821821 .message-action-button : hover {
822822 background : rgba (59 , 130 , 246 , 0.2 );
823823 }
824- .visitor-counter {
825- display : flex;
826- align-items : center;
827- gap : 8px ;
828- background : linear-gradient (to bottom, # 1e293b 0% , # 0f172a 100% );
829- padding : 8px 12px ;
830- border-radius : 0.375rem ;
831- font-size : 0.875rem ;
832- color : # e2e8f0 ;
833- border : 1px solid # 3b82f6 ;
834- margin-left : 12px ;
835- }
836-
837- .visitor-icon {
838- font-size : 1rem ;
839- }
840-
841- .visitor-count {
842- font-weight : 500 ;
843- }
844-
845- @media (max-width : 768px ) {
846- .visitor-counter {
847- margin : 0.5rem 0 ;
848- }
849- }
850824 </ style >
851825 </ head >
852826 < body >
909883
910884 < div class ="menu-controls ">
911885 < select class ="model-select " title ="Select AI Model ">
912- <!-- existing options remain the same -->
886+ < optgroup label ="Custom Models ">
887+ < option value ="unity " title ="Unity with Mistral Large by Unity AI Lab | 🎭 Custom Persona " selected > Unity AI</ option >
888+ < option value ="evil " title ="Evil Mode - Experimental | 🎭 Custom Persona "> Evil Mode</ option >
889+ < option value ="midijourney " title ="Midijourney musical transformer "> Midijourney</ option >
890+ < option value ="rtist " title ="Rtist image generator by @bqrio "> Rtist</ option >
891+ < option value ="searchgpt " title ="SearchGPT with realtime news and web search "> SearchGPT</ option >
892+ < option value ="p1 " title ="Pollinations 1 (OptiLLM) "> P1</ option >
893+ </ optgroup >
894+ < optgroup label ="Base Models ">
895+ < option value ="openai " title ="OpenAI GPT-4o-mini | 🔒 Censored | 👁️ Vision "> OpenAI</ option >
896+ < option value ="openai-large " title ="OpenAI GPT-4o | 🔒 Censored | 👁️ Vision "> OpenAI Large</ option >
897+ < option value ="mistral " title ="Mistral Nemo "> Mistral</ option >
898+ < option value ="mistral-large " title ="Mistral Large | Enhanced Capabilities "> Mistral Large</ option >
899+ < option value ="qwen " title ="Qwen 2.5 72B | 🔒 Censored "> Qwen</ option >
900+ < option value ="llama " title ="Llama 3.3 70B "> Llama</ option >
901+ < option value ="deepseek " title ="DeepSeek-V3 | 🔒 Censored "> DeepSeek</ option >
902+ </ optgroup >
913903 </ select >
914- < div class ="visitor-counter "> Visitors: < span id ="visitor-count "> Loading...</ span > </ div >
915904 </ div >
916- </ div >
917- </ div >
905+
918906
919907 < script src ="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js "> </ script >
920908 < script src ="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/line-numbers/prism-line-numbers.min.js "> </ script >
928916
929917
930918 < script src ="js/nav-loader.js "> </ script >
931- < script >
932- // Visitor Tracker Logic with File System Access API
933- async function visitorTracker ( ) {
934- const fileName = "visitorCount.txt" ;
935- const visitorCountElement = document . getElementById ( "visitor-count" ) ;
936- let visitorCount = 0 ;
937919
938- try {
939- // Request permission to access a file
940- const fileHandle = await window . showSaveFilePicker ( {
941- suggestedName : fileName ,
942- types : [
943- {
944- description : "Text Files" ,
945- accept : {
946- "text/plain" : [ ".txt" ] ,
947- } ,
948- } ,
949- ] ,
950- } ) ;
951-
952- // Try to read the file if it exists
953- const file = await fileHandle . getFile ( ) ;
954- const text = await file . text ( ) ;
955- visitorCount = parseInt ( text , 10 ) || 0 ;
956-
957- // Increment visitor count
958- visitorCount += 1 ;
959-
960- // Save the updated count back to the file
961- const writable = await fileHandle . createWritable ( ) ;
962- await writable . write ( visitorCount . toString ( ) ) ;
963- await writable . close ( ) ;
964-
965- // Update the visitor count display
966- visitorCountElement . textContent = visitorCount ;
967- } catch ( error ) {
968- console . error ( "Error handling visitor count:" , error ) ;
969- visitorCountElement . textContent = "Error!" ;
970- }
971- }
972-
973- // Initialize the visitor tracker on page load
974- document . addEventListener ( "DOMContentLoaded" , ( ) => {
975- visitorTracker ( ) ;
976- } ) ;
977920
921+ < script >
978922 const DEFAULT_INSTRUCTION = "All code must be wrapped in [CODE]...[/CODE] tags." +
979923 "When using images, show them using format: https://image.pollinations.ai/prompt/your%20image-prompt-with-visual-style%20here?width=512&height=512&nologo=true&private=true&seed={random}&enhance=false&model=Unity plus your response.\n\n" +
980924 "Code format: [CODE]code here[/CODE] with your response.\n\n" +
18601804
18611805
18621806 const newImg = new Image ( ) ;
1863- newImg . onload = async function ( ) {
1807+ newImg . onload = ( ) => {
18641808 img . src = newUrl ;
18651809 img . style . opacity = "1" ;
18661810 loadingOverlay . remove ( ) ;
25212465 setTimeout ( ( ) => feedback . remove ( ) , 2000 ) ;
25222466 }
25232467 }
2524- // visitorTracker.js
2525- class VisitorTracker {
2526- constructor ( ) {
2527- this . storageKey = 'unityChat_visitorCount' ;
2528- this . userKey = 'unityChat_visitorId' ;
2529- this . count = 0 ;
2530- this . initialize ( ) ;
2531- }
2532-
2533- initialize ( ) {
2534- // Get existing count
2535- this . count = parseInt ( localStorage . getItem ( this . storageKey ) ) || 0 ;
2536-
2537- // Check if this is a new visitor
2538- if ( ! localStorage . getItem ( this . userKey ) ) {
2539- // Generate unique ID for visitor
2540- const visitorId = this . generateVisitorId ( ) ;
2541- localStorage . setItem ( this . userKey , visitorId ) ;
2542-
2543- // Increment count
2544- this . count ++ ;
2545- localStorage . setItem ( this . storageKey , this . count . toString ( ) ) ;
2546- }
2547-
2548- // Update display
2549- this . updateDisplay ( ) ;
25502468
2551- // Set up auto-refresh
2552- setInterval ( ( ) => this . updateDisplay ( ) , 30000 ) ; // Update every 30 seconds
2553- }
25542469
2555- generateVisitorId ( ) {
2556- // Create a unique ID based on timestamp and random number
2557- return Date . now ( ) . toString ( 36 ) + Math . random ( ) . toString ( 36 ) . substr ( 2 ) ;
2558- }
2559-
2560- updateDisplay ( ) {
2561- const countElement = document . querySelector ( '.visitor-count' ) ;
2562- if ( countElement ) {
2563- // Animate the number change
2564- this . animateCount ( parseInt ( countElement . textContent ) , this . count , countElement ) ;
2565- }
2566- }
2470+ async function initialize ( ) {
2471+ setupEventListeners ( ) ;
2472+ initializeVoice ( ) ;
2473+ setupImageHandling ( ) ;
2474+ fetchModels ( ) ;
2475+ await restoreState ( ) ;
25672476
2568- animateCount ( start , end , element ) {
2569- if ( start === end ) return ;
2570-
2571- const duration = 1000 ; // 1 second animation
2572- const steps = 20 ;
2573- const stepValue = ( end - start ) / steps ;
2574- const stepDuration = duration / steps ;
2575-
2576- let current = start ;
2577- const timer = setInterval ( ( ) => {
2578- current += stepValue ;
2579- if ( ( stepValue > 0 && current >= end ) || ( stepValue < 0 && current <= end ) ) {
2580- clearInterval ( timer ) ;
2581- element . textContent = end ;
2582- } else {
2583- element . textContent = Math . round ( current ) ;
2584- }
2585- } , stepDuration ) ;
2586- }
25872477
2588- // Method to manually increment count (for testing)
2589- incrementCount ( ) {
2590- this . count ++ ;
2591- localStorage . setItem ( this . storageKey , this . count . toString ( ) ) ;
2592- this . updateDisplay ( ) ;
2593- }
2478+ window . copyCode = copyCode ;
2479+ window . scrollToCode = scrollToCode ;
2480+ window . clearCodePanel = clearCodePanel ;
2481+ window . regenerateImage = regenerateImage ;
2482+ window . toggleView = toggleView ;
2483+ window . copyImageToClipboard = copyImageToClipboard ;
2484+ window . downloadImage = downloadImage ;
2485+ window . refreshImage = refreshImage ;
25942486
2595- // Method to reset count (for testing)
2596- resetCount ( ) {
2597- this . count = 0 ;
2598- localStorage . setItem ( this . storageKey , '0' ) ;
2599- this . updateDisplay ( ) ;
2600- }
2601- }
26022487
2603- async function initialize ( ) {
2604- setupEventListeners ( ) ;
2605- initializeVoice ( ) ;
2606- setupImageHandling ( ) ;
2607- fetchModels ( ) ;
2608- await restoreState ( ) ;
2609- window . visitorTracker = new VisitorTracker ( ) ;
2610-
2611- window . copyCode = copyCode ;
2612- window . scrollToCode = scrollToCode ;
2613- window . clearCodePanel = clearCodePanel ;
2614- window . regenerateImage = regenerateImage ;
2615- window . toggleView = toggleView ;
2616- window . copyImageToClipboard = copyImageToClipboard ;
2617- window . downloadImage = downloadImage ;
2618- window . refreshImage = refreshImage ;
2619-
2620- console . log ( "Chat interface initialized successfully" ) ;
2621- }
2488+ console . log ( "Chat interface initialized successfully" ) ;
2489+ }
26222490
26232491
26242492 function stopTTS ( ) {
26252493 if ( window . speechSynthesis ) {
26262494 synth . cancel ( ) ;
26272495 }
26282496 }
2629- document . addEventListener ( "DOMContentLoaded" , initialize ) ;
2497+
2498+
2499+ document . addEventListener ( "DOMContentLoaded" , initialize ) ;
26302500 </ script >
26312501 </ body >
2632- </ html >
2502+ </ html >
0 commit comments