char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
e21152dc9
char/aliceai-t5-moe
1/** 2* Centralized PWA constants to avoid magic strings, regexes, and duplicated 3* definitions across the codebase. 4*/ 5 6import { APP_NAME } from './app.constants' ; 7 8export const MEDIA_QUERIES = { 9DISPLAY_MODE_STANDALONE :'(display-mode: standalone)' , 10PREFERS_DARK :'(prefers-color-scheme: dark)' , 11PREFERS_LIGHT :'(prefers-color-scheme: light)' 12} as const ; 13 14export const THEME_COLORS = { 15ACCENT_BLUE :'#2563eb' , 16ACCENT_BLUE_HOVER :'#1d4ed8' , 17BACKGROUND_DARK :'#111111' , 18BACKGROUND_LIGHT :'white' , 19DARK :'#0d0d0d' , 20LIGHT :'#ffffff' , 21TITLE_UPDATE_ALERT :{ 22BG_DARK :'zinc-800' , 23BG_LIGHT :'white' , 24BORDER_DARK :'zinc-700' , 25BORDER_LIGHT :'zinc-200' , 26TEXT_DARK :'zinc-400' , 27TEXT_LIGHT :'zinc-500' 28} 29} as const ; 30 31export const FAVICON_PATHS = { 32ICO_DARK :'favicon-dark.ico' , 33ICO_LIGHT :'favicon.ico' , 34SVG_DARK :'favicon-dark.svg' , 35SVG_LIGHT :'favicon.svg' 36} as const ; 37 38// Substituted for `currentColor` in src/lib/assets/logo.svg when generating 39// the light/dark static sources consumed by the PWA asset generator. 40export const FAVICON_COLORS = { 41DARK :'#fafafa' , 42LIGHT :'#111111' 43} as const ; 44 45export const FAVICON_SELECTORS = { 46ICO_48X48 :'link[rel="icon"][sizes="48x48"]' , 47SVG_ANY :'link[rel="icon"][type="image/svg+xml"]' 48} as const ; 49 50export const APPLE_ASSETS = { 51TOUCH_ICON :'apple-touch-icon-180x180.png' 52} as const ; 53 54export const PWA_MANIFEST = { 55background_color :THEME_COLORS . BACKGROUND_LIGHT , 56description :'Local AI chat interface powered by llama.cpp' , 57display :'standalone' as const , 58icons :[ 59{ sizes :'64x64' , src :'pwa-64x64.png' , type :'image/png' }, 60{ sizes :'192x192' , src :'pwa-192x192.png' , type :'image/png' }, 61{ purpose :'any' as const , sizes :'512x512' , src :'pwa-512x512.png' , type :'image/png' }, 62{ 63purpose :'maskable' as const , 64sizes :'512x512' , 65src :'maskable-icon-512x512.png' , 66type :'image/png' 67} 68], 69name :APP_NAME , 70short_name :APP_NAME , 71start_url :'./' , 72theme_color :THEME_COLORS . BACKGROUND_LIGHT 73}; 74 75export const PWA_ICON_PATHS = { 76MASKABLE_512 :'/maskable-icon-512x512.png' , 77PWA_64 :'/pwa-64x64.png' , 78PWA_192 :'/pwa-192x192.png' , 79PWA_512 :'/pwa-512x512.png' 80} as const ; 81 82/** Apple device dimensions (logical points) and DPR, from Apple HIG. */ 83export const APPLE_DEVICES = { 84'640x1136' :{ dpr :2 , height :568 , width :320 }, // iPhone 6/7/8 Plus 85'744x1133' :{ dpr :2 , height :573 , width :376 }, // iPad mini 8.3" 86'750x1334' :{ dpr :2 , height :667 , width :375 }, // iPhone 6/7/8, 14 87'1032x1376' :{ dpr :2 , height :1376 , width :1032 }, // iPad Air 13" 88// iPhones (DPR 3) 89'1170x2532' :{ dpr :3 , height :844 , width :390 }, // iPhone 13, 15 90'1179x2556' :{ dpr :3 , height :852 , width :393 }, // iPhone 14, 15 Pro, 16 91'1206x2622' :{ dpr :3 , height :874 , width :402 }, // iPhone 16 Plus, 16e 92'1284x2778' :{ dpr :3 , height :926 , width :428 }, // iPhone 15 Plus 93'1290x2796' :{ dpr :3 , height :932 , width :430 }, // iPhone 15 Pro Max, 16 Pro 94'1320x2868' :{ dpr :3 , height :956 , width :440 }, // iPhone 16 Pro Max 95'1640x2360' :{ dpr :2 , height :1180 , width :820 }, // iPad Air 10.9" 96// iPads (DPR 2) 97'1668x2388' :{ dpr :2 , height :1194 , width :834 }, // iPad Air 11", iPad 11" 98'2048x2732' :{ dpr :2 , height :1366 , width :1024 } // iPad Pro 12.9" 99} as const ; 100 101export type AppleDeviceKey = keyof typeof APPLE_DEVICES ; 102 103export const PWA_FILE_PATHS = { 104MANIFEST :'/manifest.webmanifest' , 105SERVICE_WORKER :'/sw.js' , 106VERSION :'/version.json' , 107WORKBOX :'/workbox-<hash>.js' 108} as const ; 109 110// Used by the server middleware to skip API key validation. 111// Keep in sync with tools/server/server-http.cpp public_endpoints list. 112 113export const PUBLIC_ENDPOINTS = [ 114'/health' , 115'/v1/health' , 116'/models' , 117'/v1/models' , 118'/props' , 119'/metrics' , 120'/' , 121'/index.html' , 122 123'/favicon.ico' , 124'/favicon-dark.ico' , 125'/favicon.svg' , 126'/favicon-dark.svg' , 127'/pwa-64x64.png' , 128'/pwa-192x192.png' , 129'/pwa-512x512.png' , 130'/maskable-icon-512x512.png' , 131'/apple-touch-icon-180x180.png' , 132'/apple-splash-portrait-640x1136.png' , 133'/apple-splash-landscape-640x1136.png' , 134'/apple-splash-portrait-750x1334.png' , 135'/apple-splash-landscape-750x1334.png' , 136'/apple-splash-portrait-1170x2532.png' , 137'/apple-splash-landscape-1170x2532.png' , 138'/apple-splash-portrait-1179x2556.png' , 139'/apple-splash-landscape-1179x2556.png' , 140'/apple-splash-portrait-1206x2622.png' , 141'/apple-splash-landscape-1206x2622.png' , 142'/apple-splash-portrait-1284x2778.png' , 143'/apple-splash-landscape-1284x2778.png' , 144'/apple-splash-portrait-1290x2796.png' , 145'/apple-splash-landscape-1290x2796.png' , 146'/apple-splash-portrait-1320x2868.png' , 147'/apple-splash-landscape-1320x2868.png' , 148'/apple-splash-portrait-1488x2266.png' , 149'/apple-splash-landscape-1488x2266.png' , 150'/apple-splash-portrait-1640x2360.png' , 151'/apple-splash-landscape-1640x2360.png' , 152'/apple-splash-portrait-1668x2388.png' , 153'/apple-splash-landscape-1668x2388.png' , 154'/apple-splash-portrait-2048x2732.png' , 155'/apple-splash-landscape-2048x2732.png' , 156'/apple-splash-portrait-dark-640x1136.png' , 157'/apple-splash-landscape-dark-640x1136.png' , 158'/apple-splash-portrait-dark-750x1334.png' , 159'/apple-splash-landscape-dark-750x1334.png' , 160'/apple-splash-portrait-dark-1170x2532.png' , 161'/apple-splash-landscape-dark-1170x2532.png' , 162'/apple-splash-portrait-dark-1179x2556.png' , 163'/apple-splash-landscape-dark-1179x2556.png' , 164'/apple-splash-portrait-dark-1206x2622.png' , 165'/apple-splash-landscape-dark-1206x2622.png' , 166'/apple-splash-portrait-dark-1284x2778.png' , 167'/apple-splash-landscape-dark-1284x2778.png' , 168'/apple-splash-portrait-dark-1290x2796.png' , 169'/apple-splash-landscape-dark-1290x2796.png' , 170'/apple-splash-portrait-dark-1320x2868.png' , 171'/apple-splash-landscape-dark-1320x2868.png' , 172'/apple-splash-portrait-dark-1488x2266.png' , 173'/apple-splash-landscape-dark-1488x2266.png' , 174'/apple-splash-portrait-dark-1640x2360.png' , 175'/apple-splash-landscape-dark-1640x2360.png' , 176'/apple-splash-portrait-dark-1668x2388.png' , 177'/apple-splash-landscape-dark-1668x2388.png' , 178'/apple-splash-portrait-dark-2048x2732.png' , 179'/apple-splash-landscape-dark-2048x2732.png' , 180'/manifest.webmanifest' , 181'/sw.js' , 182'/version.json' , 183'/workbox-<hash>.js' 184] as const ; 185export const BUILD_CONFIG = { 186GUIDE_COMMENT :` 187<!-- 188This is a static build of the frontend. 189It is automatically generated by the build process. 190Do not edit this file directly. 191To make changes, refer to the "Web UI" section in the README. 192--> 193` . trim (), 194OUTPUT_DIR :'./dist' 195} as const ; 196 197export const REGEX_PATTERNS = { 198HEAD_CLOSE :/ \t*<\/head> / , 199SPLASH_FILE :/ ^apple-splash-(portrait|landscape)-(dark-)?(\d+)x(\d+)\.png$ / 200} as const ; 201 202// Device names used by @vite-pwa/assets-generator for splash screen generation. 203// Keep in sync with pwa-assets.config.ts. 204export const PWA_GENERATOR_DEVICES = [ 205'iPhone 13' , 206'iPhone 13 Pro' , 207'iPhone 13 Pro Max' , 208'iPhone 14' , 209'iPhone 14 Plus' , 210'iPhone 14 Pro' , 211'iPhone 14 Pro Max' , 212'iPhone 15' , 213'iPhone 15 Plus' , 214'iPhone 15 Pro' , 215'iPhone 15 Pro Max' , 216'iPhone 16' , 217'iPhone 16 Plus' , 218'iPhone 16 Pro' , 219'iPhone 16 Pro Max' , 220'iPhone 16e' , 221'iPhone SE 4"' , 222'iPhone SE 4.7"' , 223'iPad 11"' , 224'iPad Air 10.9"' , 225'iPad Air 11"' , 226'iPad Air 13"' , 227'iPad Pro 11"' , 228'iPad Pro 12.9"' , 229'iPad mini 8.3"' 230] as const ; 231 232// PWA assets generator configuration — used by pwa-assets.config.ts 233// FAVICON_PADDING: fraction (0..1) of the icon reserved as equal margin on 234// each side. Applied to icon PNG/ICO outputs by @vite-pwa/assets-generator and 235// post-processed into the static favicon.svg so the in-app logo (which reads 236// src/lib/assets/logo.svg directly) is unaffected. 237export const PWA_ASSET_GENERATOR = { 238ADD_MEDIA_SCREEN :true , 239BASE_PATH :'./' , 240DARK_PREFIX :'dark-' , 241FAVICON_PADDING :0.04 , 242FIT_MODE :'contain' , 243LINK_PRESET :'2023' , 244PNG_COMPRESSION_LEVEL :9 , 245PNG_QUALITY :60 , 246SPLASH_PADDING :0.75 , 247XHTML :false 248} as const ; 249 250export const CACHE_SETTINGS = { 251API_CACHE_MAX_AGE_SECONDS :60 * 60 * 24 , 252API_CACHE_MAX_ENTRIES :50 , 253IMMUTABLE_MAX_AGE_SECONDS :31536000 , 254MAX_FILE_SIZE_BYTES :10 * 1024 * 1024 255} as const ; 256 257export const GLOB_PATTERNS :string [] = [ 258'**/*.{js,css,html,ico,svg,png,webp,woff,woff2,json,webmanifest}' 259]; 260 261export const SW_CONFIG = { 262CHECK_INTERVAL_MS :60000 , 263UPDATE_FETCH_OPTIONS :{ 264CACHE :'no-store' , 265HEADERS :{ 266CACHE :'no-store' , 267CACHE_CONTROL :'no-cache' 268} 269} 270} as const ; 271 272// Runtime caching configuration for Workbox 273export const RUNTIME_CACHING = { 274CACHE_NAME :'api-cache' , 275HANDLER :'NetworkFirst' 276} as const ; 277 278// Workbox runtime caching patterns 279export const API_CACHING_PATTERNS = { 280STATIC_API :/ ^\/(health|props|models|tools|slots|cors-proxy).* / , 281V1_API :/ ^\/v1\/.* / 282} as const ; 283 284// SvelteKit PWA plugin options 285export const PWA_KIT_OPTIONS = {} as const ; 286 287export const APPLE_META_TAGS = { 288MOBILE_WEB_APP_CAPABLE :{ content :'yes' , name :'apple-mobile-web-app-capable' }, 289MOBILE_WEB_APP_TITLE :{ name :'apple-mobile-web-app-title' }, 290STATUS_BAR_STYLE :{ content :'black-translucent' , name :'apple-mobile-web-app-status-bar-style' } 291} as const ; 292 293// Splash screen HTML link tag prefix used by generateSplashScreenLinks 294export const SPLASH_LINK = { 295DARK_MEDIA_SUFFIX :' and (prefers-color-scheme: dark)' , 296HTML :'<link rel="apple-touch-startup-image"' 297} as const ; 298 299// SvelteKit PWA plugin configuration — used by @vite.config.ts 300import type { SvelteKitPWAOptions } from '@vite-pwa/sveltekit' ; 301 302export const SVELTEKIT_PWA_OPTIONS :SvelteKitPWAOptions = { 303devOptions :{ 304enabled :true , 305suppressWarnings :true 306}, 307 308// SvelteKit-specific options 309kit :{ 310// Include version file for proper cache invalidation 311includeVersionFile :true 312}, 313 314// Strategy: generateSW - the plugin generates a service worker automatically 315// using Workbox. For a custom SW, use 'injectManifest' instead. 316// Manifest configuration 317manifest :PWA_MANIFEST , 318 319// Workbox configuration for generateSW strategy 320workbox :{ 321// Match all static assets in the build output. 322// Uses '**/' because SvelteKit outputs files under _app/immutable/ 323// subdirectories. 324globPatterns :GLOB_PATTERNS , 325maximumFileSizeToCacheInBytes :CACHE_SETTINGS . MAX_FILE_SIZE_BYTES , 326 327// Prevent @vite-pwa/sveltekit from auto-adding a NavigationRoute by 328// setting navigateFallback to empty string. This keeps the service 329// worker from intercepting direct browser navigation to server API 330// endpoints (e.g. /slots, /models, /v1/models) which should return 331// JSON, not the SPA HTML shell. The server's own static-file fallback 332// handles non-API navigation to index.html for the SPA router. 333navigateFallback :'' , 334 335// Runtime caching for API calls - use NetworkFirst so APIs are always fresh 336runtimeCaching :[ 337{ 338handler :RUNTIME_CACHING . HANDLER , 339options :{ 340cacheName :RUNTIME_CACHING . CACHE_NAME , 341expiration :{ 342maxAgeSeconds :CACHE_SETTINGS . API_CACHE_MAX_AGE_SECONDS , 343maxEntries :CACHE_SETTINGS . API_CACHE_MAX_ENTRIES 344} 345}, 346urlPattern :API_CACHING_PATTERNS . V1_API 347}, 348{ 349handler :RUNTIME_CACHING . HANDLER , 350options :{ 351cacheName :RUNTIME_CACHING . CACHE_NAME , 352expiration :{ 353maxAgeSeconds :CACHE_SETTINGS . API_CACHE_MAX_AGE_SECONDS , 354maxEntries :CACHE_SETTINGS . API_CACHE_MAX_ENTRIES 355} 356}, 357urlPattern :API_CACHING_PATTERNS . STATIC_API 358} 359] 360} 361};