@bobfrankston/msger 0.1.74 → 0.1.75

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/KNOWN-BUGS.md +121 -0
  2. package/MSGER-API-SUMMARY.md +162 -0
  3. package/MSGER-API.md +376 -0
  4. package/README.md +93 -0
  5. package/SESSION-2025-11-06.md +191 -0
  6. package/SESSION-NOTES.md +678 -0
  7. package/clihandler.d.ts.map +1 -1
  8. package/clihandler.js +62 -2
  9. package/clihandler.js.map +1 -1
  10. package/clihandler.ts +60 -2
  11. package/icon.png +0 -0
  12. package/icon1.png +0 -0
  13. package/msger-native/Cargo.toml +1 -0
  14. package/msger-native/bin/msgernative.exe +0 -0
  15. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Breadcrumbs +12 -118
  16. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/BrowserMetrics/{BrowserMetrics-690552AF-DCD4.pma → BrowserMetrics-690B9AD3-657C.pma} +0 -0
  17. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/BrowserMetrics/{BrowserMetrics-69055373-F88C.pma → BrowserMetrics-690BA05A-501C.pma} +0 -0
  18. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Crashpad/settings.dat +0 -0
  19. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/BrowsingTopicsState +1 -1
  20. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Cache/Cache_Data/data_0 +0 -0
  21. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Cache/Cache_Data/data_1 +0 -0
  22. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/{BrowserMetrics/BrowserMetrics-69055587-A65C.pma → Default/Cache/Cache_Data/data_2} +0 -0
  23. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Cache/Cache_Data/data_3 +0 -0
  24. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Cache/Cache_Data/f_000001 +383 -0
  25. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Cache/Cache_Data/f_000002 +1091 -0
  26. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Cache/Cache_Data/f_000003 +2153 -0
  27. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Cache/Cache_Data/f_000004 +0 -0
  28. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Cache/Cache_Data/f_000005 +626 -0
  29. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Cache/Cache_Data/f_000006 +393 -0
  30. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Cache/Cache_Data/index +0 -0
  31. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Code Cache/js/01241693cfdc32b9_0 +0 -0
  32. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Code Cache/js/0ba1eea781f3552c_0 +0 -0
  33. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Code Cache/js/323aa210eebefe2c_0 +0 -0
  34. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Code Cache/js/4608446ac118e77a_0 +0 -0
  35. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Code Cache/js/6938205dc2f77841_0 +0 -0
  36. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Code Cache/js/6de12299dc89e5f3_0 +0 -0
  37. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Code Cache/js/8f403c112eaa455b_0 +0 -0
  38. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Code Cache/js/9a3aceb491137f07_0 +0 -0
  39. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Code Cache/js/aedb266cbaf9c28f_0 +0 -0
  40. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Code Cache/js/ca526fdda86d0b9d_0 +0 -0
  41. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Code Cache/js/f5d11d783c9fdf69_0 +0 -0
  42. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Code Cache/js/index-dir/the-real-index +0 -0
  43. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Collections/collectionsSQLite +0 -0
  44. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Collections/collectionsSQLite-journal +0 -0
  45. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/DIPS +0 -0
  46. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/DawnGraphiteCache/data_1 +0 -0
  47. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/DawnGraphiteCache/index +0 -0
  48. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/DawnWebGPUCache/data_1 +0 -0
  49. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/DawnWebGPUCache/index +0 -0
  50. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Extension State/LOG +3 -3
  51. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Extension State/LOG.old +3 -3
  52. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Favicons +0 -0
  53. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/GPUCache/data_0 +0 -0
  54. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/GPUCache/data_1 +0 -0
  55. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/GPUCache/data_2 +0 -0
  56. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/GPUCache/index +0 -0
  57. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/History +0 -0
  58. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Local Storage/leveldb/000003.log +0 -0
  59. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Local Storage/leveldb/LOG +3 -3
  60. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Local Storage/leveldb/LOG.old +3 -3
  61. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/MediaDeviceSalts +0 -0
  62. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/MediaDeviceSalts-journal +0 -0
  63. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Network/Network Persistent State +1 -1
  64. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Network/TransportSecurity +1 -0
  65. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Preferences +1 -1
  66. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Service Worker/CacheStorage/14e849fa8522d406112ea607cf7fd6342b71b987/249ee9af-c3df-4a86-89a8-2c51f3370ee0/index +0 -0
  67. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Service Worker/CacheStorage/14e849fa8522d406112ea607cf7fd6342b71b987/249ee9af-c3df-4a86-89a8-2c51f3370ee0/index-dir/the-real-index +0 -0
  68. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Service Worker/CacheStorage/14e849fa8522d406112ea607cf7fd6342b71b987/index.txt +0 -0
  69. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Service Worker/Database/000003.log +0 -0
  70. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Service Worker/Database/CURRENT +1 -0
  71. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Service Worker/Database/LOCK +0 -0
  72. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Service Worker/Database/LOG +3 -0
  73. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Service Worker/Database/LOG.old +3 -0
  74. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Service Worker/Database/MANIFEST-000001 +0 -0
  75. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Service Worker/ScriptCache/2cc80dabc69f58b6_0 +0 -0
  76. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Service Worker/ScriptCache/2cc80dabc69f58b6_1 +0 -0
  77. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Service Worker/ScriptCache/index +0 -0
  78. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Service Worker/ScriptCache/index-dir/the-real-index +0 -0
  79. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Session Storage/000003.log +0 -0
  80. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Session Storage/LOG +3 -3
  81. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Session Storage/LOG.old +3 -3
  82. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Site Characteristics Database/000003.log +0 -0
  83. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Site Characteristics Database/LOG +3 -3
  84. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Site Characteristics Database/LOG.old +3 -3
  85. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Sync Data/LevelDB/LOG +3 -3
  86. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/Sync Data/LevelDB/LOG.old +3 -3
  87. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/WebStorage/QuotaManager +0 -0
  88. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/WebStorage/QuotaManager-journal +0 -0
  89. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/favorites_diagnostic.log +27 -0
  90. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/shared_proto_db/000003.log +0 -0
  91. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/shared_proto_db/LOG +3 -3
  92. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/shared_proto_db/LOG.old +3 -3
  93. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/shared_proto_db/metadata/000003.log +0 -0
  94. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/shared_proto_db/metadata/LOG +3 -3
  95. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Default/shared_proto_db/metadata/LOG.old +3 -3
  96. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/GrShaderCache/data_0 +0 -0
  97. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/GrShaderCache/data_1 +0 -0
  98. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/GrShaderCache/data_3 +0 -0
  99. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/GrShaderCache/f_000003 +0 -0
  100. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/GrShaderCache/f_000004 +0 -0
  101. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/GrShaderCache/index +0 -0
  102. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/GraphiteDawnCache/data_1 +0 -0
  103. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/GraphiteDawnCache/index +0 -0
  104. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/Local State +1 -1
  105. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/RevisitationBloomfilter +0 -0
  106. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/ShaderCache/data_1 +0 -0
  107. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/ShaderCache/index +0 -0
  108. package/msger-native/src/main.rs +343 -37
  109. package/msger-native/src/template.html +103 -28
  110. package/msger-storage-demo.html +290 -0
  111. package/msger.code-workspace +3 -0
  112. package/msgerdefs/README.md +122 -0
  113. package/msgerdefs/msgerdefs.d.ts +322 -0
  114. package/msgerdefs/msgerdefs.d.ts.map +1 -0
  115. package/msgerdefs/msgerdefs.js +110 -0
  116. package/msgerdefs/msgerdefs.js.map +1 -0
  117. package/msgerdefs/msgerdefs.ts +427 -0
  118. package/msgerdefs/package.json +38 -0
  119. package/msgerdefs/samples.html +431 -0
  120. package/msgerdefs/test1.cmd +1 -0
  121. package/msgerdefs/tsconfig.json +17 -0
  122. package/msgernative-linux-x64 +0 -0
  123. package/package.json +5 -1
  124. package/shower.d.ts +2 -0
  125. package/shower.d.ts.map +1 -1
  126. package/shower.js +17 -0
  127. package/shower.js.map +1 -1
  128. package/shower.ts +24 -0
  129. package/test-data-persistence.html +315 -0
  130. package/test-htmlfrom.html +29 -0
  131. package/test-ipc-reach.html +113 -0
  132. package/test-msger-api.html +120 -0
  133. package/test-msger-functions.html +325 -0
  134. package/msger-native/bin/msgernative.exe.WebView2/EBWebView/BrowserMetrics/BrowserMetrics-69055419-C8A0.pma +0 -0
@@ -0,0 +1,383 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>WallClock</title>
8
+ <link rel="stylesheet" href="styles.css">
9
+ <link rel="manifest" href="manifest.webmanifest">
10
+ <link rel="icon" href="clock-icon.svg" type="image/svg+xml">
11
+ <meta name="theme-color" content="#ffffff">
12
+ <link rel="apple-touch-icon" href="apple-touch-icon.png">
13
+ </head>
14
+
15
+ <body>
16
+
17
+ <!-- Banner container with state-based banners -->
18
+ <div id="banner-container" class="fader">
19
+ <div id="banner-content">
20
+ <div id="banner-unavailable">🚫 Microphone permission denied</div>
21
+ <div id="banner-disabled">🚫 Voice control disabled</div>
22
+ <div id="banner-waiting">🎤 Say "hey timer" or "go timer"</div>
23
+ <div id="banner-listening">🎤 Listening • Say "help" or click for commands</div>
24
+ <div id="banner-speech-blocked">🔇 Speech unavailable - Silent mode or no speech synthesis</div>
25
+ <div id="banner-network-error">⚠️ Network error - Speech recognition temporarily unavailable</div>
26
+ </div>
27
+
28
+ <!-- Single shared progress bar container -->
29
+ <div id="progress-container" class="hidden">
30
+ <div class="timeout-progress-bar"></div>
31
+ </div>
32
+ </div>
33
+
34
+ <!-- Main content area for clock -->
35
+ <div id="main-content">
36
+ <div id="clock-container">
37
+ <svg id="analog-clock" viewBox="0 0 400 400">
38
+ <!-- Clock face -->
39
+ <circle cx="200" cy="200" r="190" fill="var(--clock-bg)" stroke="var(--clock-numbers)"
40
+ stroke-width="4" />
41
+
42
+ <!-- Hour markers and numbers -->
43
+ <g id="hour-markers"></g>
44
+
45
+ <!-- Digital time display -->
46
+ <text id="digital-time" x="200" y="250" text-anchor="middle" dominant-baseline="middle" font-size="64"
47
+ font-family="var(--clock-font)" fill="none" stroke="var(--digital-time-color)"
48
+ stroke-width="1"></text>
49
+
50
+ <!-- Clock hands (after digital time so they appear in front) -->
51
+ <line id="hour-hand" x1="200" y1="200" x2="200" y2="90" stroke-width="6" stroke-linecap="round"
52
+ class="hour-hand" />
53
+ <line id="minute-hand" x1="200" y1="200" x2="200" y2="50" stroke-width="4" stroke-linecap="round"
54
+ class="minute-hand" />
55
+ <line id="second-hand" x1="200" y1="200" x2="200" y2="40" stroke-width="2" stroke-linecap="round"
56
+ class="second-hand" />
57
+
58
+ <!-- Timer countdown display -->
59
+ <text id="timer-countdown" x="200" y="160" text-anchor="middle" dominant-baseline="middle"
60
+ font-size="64" font-family="var(--clock-font)" fill="var(--timer-seconds-color)"
61
+ font-weight="bold"></text>
62
+
63
+
64
+ <!-- Timer countdown circles - 60 dots at second positions -->
65
+ <g id="countdown-dots">
66
+ <!-- Generated 60 dots positioned at second marks (every 6 degrees) -->
67
+ <circle class="countdown-dot" data-second="0" cx="250" cy="30" r="8"
68
+ transform="rotate(0 250 250)" />
69
+ <circle class="countdown-dot" data-second="1" cx="250" cy="30" r="8"
70
+ transform="rotate(6 250 250)" />
71
+ <circle class="countdown-dot" data-second="2" cx="250" cy="30" r="8"
72
+ transform="rotate(12 250 250)" />
73
+ <circle class="countdown-dot" data-second="3" cx="250" cy="30" r="8"
74
+ transform="rotate(18 250 250)" />
75
+ <circle class="countdown-dot" data-second="4" cx="250" cy="30" r="8"
76
+ transform="rotate(24 250 250)" />
77
+ <circle class="countdown-dot" data-second="5" cx="250" cy="30" r="8"
78
+ transform="rotate(30 250 250)" />
79
+ <circle class="countdown-dot" data-second="6" cx="250" cy="30" r="8"
80
+ transform="rotate(36 250 250)" />
81
+ <circle class="countdown-dot" data-second="7" cx="250" cy="30" r="8"
82
+ transform="rotate(42 250 250)" />
83
+ <circle class="countdown-dot" data-second="8" cx="250" cy="30" r="8"
84
+ transform="rotate(48 250 250)" />
85
+ <circle class="countdown-dot" data-second="9" cx="250" cy="30" r="8"
86
+ transform="rotate(54 250 250)" />
87
+ <circle class="countdown-dot" data-second="10" cx="250" cy="30" r="8"
88
+ transform="rotate(60 250 250)" />
89
+ <circle class="countdown-dot" data-second="11" cx="250" cy="30" r="8"
90
+ transform="rotate(66 250 250)" />
91
+ <circle class="countdown-dot" data-second="12" cx="250" cy="30" r="8"
92
+ transform="rotate(72 250 250)" />
93
+ <circle class="countdown-dot" data-second="13" cx="250" cy="30" r="8"
94
+ transform="rotate(78 250 250)" />
95
+ <circle class="countdown-dot" data-second="14" cx="250" cy="30" r="8"
96
+ transform="rotate(84 250 250)" />
97
+ <circle class="countdown-dot" data-second="15" cx="250" cy="30" r="8"
98
+ transform="rotate(90 250 250)" />
99
+ <circle class="countdown-dot" data-second="16" cx="250" cy="30" r="8"
100
+ transform="rotate(96 250 250)" />
101
+ <circle class="countdown-dot" data-second="17" cx="250" cy="30" r="8"
102
+ transform="rotate(102 250 250)" />
103
+ <circle class="countdown-dot" data-second="18" cx="250" cy="30" r="8"
104
+ transform="rotate(108 250 250)" />
105
+ <circle class="countdown-dot" data-second="19" cx="250" cy="30" r="8"
106
+ transform="rotate(114 250 250)" />
107
+ <circle class="countdown-dot" data-second="20" cx="250" cy="30" r="8"
108
+ transform="rotate(120 250 250)" />
109
+ <circle class="countdown-dot" data-second="21" cx="250" cy="30" r="8"
110
+ transform="rotate(126 250 250)" />
111
+ <circle class="countdown-dot" data-second="22" cx="250" cy="30" r="8"
112
+ transform="rotate(132 250 250)" />
113
+ <circle class="countdown-dot" data-second="23" cx="250" cy="30" r="8"
114
+ transform="rotate(138 250 250)" />
115
+ <circle class="countdown-dot" data-second="24" cx="250" cy="30" r="8"
116
+ transform="rotate(144 250 250)" />
117
+ <circle class="countdown-dot" data-second="25" cx="250" cy="30" r="8"
118
+ transform="rotate(150 250 250)" />
119
+ <circle class="countdown-dot" data-second="26" cx="250" cy="30" r="8"
120
+ transform="rotate(156 250 250)" />
121
+ <circle class="countdown-dot" data-second="27" cx="250" cy="30" r="8"
122
+ transform="rotate(162 250 250)" />
123
+ <circle class="countdown-dot" data-second="28" cx="250" cy="30" r="8"
124
+ transform="rotate(168 250 250)" />
125
+ <circle class="countdown-dot" data-second="29" cx="250" cy="30" r="8"
126
+ transform="rotate(174 250 250)" />
127
+ <circle class="countdown-dot" data-second="30" cx="250" cy="30" r="8"
128
+ transform="rotate(180 250 250)" />
129
+ <circle class="countdown-dot" data-second="31" cx="250" cy="30" r="8"
130
+ transform="rotate(186 250 250)" />
131
+ <circle class="countdown-dot" data-second="32" cx="250" cy="30" r="8"
132
+ transform="rotate(192 250 250)" />
133
+ <circle class="countdown-dot" data-second="33" cx="250" cy="30" r="8"
134
+ transform="rotate(198 250 250)" />
135
+ <circle class="countdown-dot" data-second="34" cx="250" cy="30" r="8"
136
+ transform="rotate(204 250 250)" />
137
+ <circle class="countdown-dot" data-second="35" cx="250" cy="30" r="8"
138
+ transform="rotate(210 250 250)" />
139
+ <circle class="countdown-dot" data-second="36" cx="250" cy="30" r="8"
140
+ transform="rotate(216 250 250)" />
141
+ <circle class="countdown-dot" data-second="37" cx="250" cy="30" r="8"
142
+ transform="rotate(222 250 250)" />
143
+ <circle class="countdown-dot" data-second="38" cx="250" cy="30" r="8"
144
+ transform="rotate(228 250 250)" />
145
+ <circle class="countdown-dot" data-second="39" cx="250" cy="30" r="8"
146
+ transform="rotate(234 250 250)" />
147
+ <circle class="countdown-dot" data-second="40" cx="250" cy="30" r="8"
148
+ transform="rotate(240 250 250)" />
149
+ <circle class="countdown-dot" data-second="41" cx="250" cy="30" r="8"
150
+ transform="rotate(246 250 250)" />
151
+ <circle class="countdown-dot" data-second="42" cx="250" cy="30" r="8"
152
+ transform="rotate(252 250 250)" />
153
+ <circle class="countdown-dot" data-second="43" cx="250" cy="30" r="8"
154
+ transform="rotate(258 250 250)" />
155
+ <circle class="countdown-dot" data-second="44" cx="250" cy="30" r="8"
156
+ transform="rotate(264 250 250)" />
157
+ <circle class="countdown-dot" data-second="45" cx="250" cy="30" r="8"
158
+ transform="rotate(270 250 250)" />
159
+ <circle class="countdown-dot" data-second="46" cx="250" cy="30" r="8"
160
+ transform="rotate(276 250 250)" />
161
+ <circle class="countdown-dot" data-second="47" cx="250" cy="30" r="8"
162
+ transform="rotate(282 250 250)" />
163
+ <circle class="countdown-dot" data-second="48" cx="250" cy="30" r="8"
164
+ transform="rotate(288 250 250)" />
165
+ <circle class="countdown-dot" data-second="49" cx="250" cy="30" r="8"
166
+ transform="rotate(294 250 250)" />
167
+ <circle class="countdown-dot" data-second="50" cx="250" cy="30" r="8"
168
+ transform="rotate(300 250 250)" />
169
+ <circle class="countdown-dot" data-second="51" cx="250" cy="30" r="8"
170
+ transform="rotate(306 250 250)" />
171
+ <circle class="countdown-dot" data-second="52" cx="250" cy="30" r="8"
172
+ transform="rotate(312 250 250)" />
173
+ <circle class="countdown-dot" data-second="53" cx="250" cy="30" r="8"
174
+ transform="rotate(318 250 250)" />
175
+ <circle class="countdown-dot" data-second="54" cx="250" cy="30" r="8"
176
+ transform="rotate(324 250 250)" />
177
+ <circle class="countdown-dot" data-second="55" cx="250" cy="30" r="8"
178
+ transform="rotate(330 250 250)" />
179
+ <circle class="countdown-dot" data-second="56" cx="250" cy="30" r="8"
180
+ transform="rotate(336 250 250)" />
181
+ <circle class="countdown-dot" data-second="57" cx="250" cy="30" r="8"
182
+ transform="rotate(342 250 250)" />
183
+ <circle class="countdown-dot" data-second="58" cx="250" cy="30" r="8"
184
+ transform="rotate(348 250 250)" />
185
+ <circle class="countdown-dot" data-second="59" cx="250" cy="30" r="8"
186
+ transform="rotate(354 250 250)" />
187
+ </g>
188
+ </svg>
189
+
190
+ <!-- Digital time overlay (outside SVG for better positioning) -->
191
+ <div id="digital-time-overlay"></div>
192
+
193
+ <!-- AM/PM indicator in lower left -->
194
+ <div id="ampm-indicator"></div>
195
+
196
+ <!-- Battery indicator -->
197
+ <div id="battery-indicator" class="hidden">
198
+ <span id="battery-percentage"></span>%
199
+ </div>
200
+
201
+ <!-- Always-active timer cancel button -->
202
+ <button id="timer-cancel-floating" class="hidden">Cancel Timer</button>
203
+
204
+ <!-- Log overlay -->
205
+ <div id="log-overlay" class="collapsed">
206
+ <div id="log-content">
207
+ <h3>Debug Log</h3>
208
+ <div id="log-messages"></div>
209
+ <p><small>Touch anywhere to close</small></p>
210
+ </div>
211
+ </div>
212
+
213
+ <!-- Settings panel -->
214
+ <div id="settings-panel" class="collapsed">
215
+ <div id="settings-content">
216
+ <h3>Timer Settings</h3>
217
+ <div>
218
+ <label for="timer-minutes">Minutes:</label>
219
+ <input type="number" id="timer-minutes" min="0" max="59" value="0">
220
+ </div>
221
+ <div>
222
+ <label for="timer-seconds">Seconds:</label>
223
+ <input type="number" id="timer-seconds" min="0" max="59" value="0">
224
+ </div>
225
+ <button id="start-timer">Start Timer</button>
226
+ <button id="cancel-timer" disabled>Cancel Timer</button>
227
+
228
+ <h3>Display Options</h3>
229
+ <div>
230
+ <label for="show-digital">
231
+ <input type="checkbox" id="show-digital"> Show 24-hour digital time
232
+ </label>
233
+ </div>
234
+ <div>
235
+ <label for="silent-mode">
236
+ <input type="checkbox" id="silent-mode"> Silent mode (audio only for timer alerts)
237
+ </label>
238
+ </div>
239
+ <div>
240
+ <label for="theme-select">Theme:</label>
241
+ <select id="theme-select">
242
+ <option value="system">System</option>
243
+ <option value="light">Light</option>
244
+ <option value="dark">Dark</option>
245
+ </select>
246
+ </div>
247
+
248
+ <h3>Voice Control</h3>
249
+ <button id="voice-toggle">Enable Voice Control</button>
250
+ <div>
251
+ <label for="microphone-select">Microphone:</label>
252
+ <select id="microphone-select">
253
+ <option value="">Default</option>
254
+ </select>
255
+ <button id="refresh-microphones" type="button">Refresh</button>
256
+ </div>
257
+ <div>
258
+ <label for="listening-timeout">Listening timeout (seconds):</label>
259
+ <input type="number" id="listening-timeout" min="5" max="60" value="15">
260
+ </div>
261
+ <div>
262
+ <label for="ai-parsing">
263
+ <input type="checkbox" id="ai-parsing"> Enhanced AI parsing (for complex commands)
264
+ </label>
265
+ </div>
266
+ <div id="ai-config" class="hidden">
267
+ <label for="ai-service">AI Service:</label>
268
+ <select id="ai-service">
269
+ <option value="openai">OpenAI GPT</option>
270
+ <option value="claude">Anthropic Claude</option>
271
+ <option value="gemini">Google Gemini</option>
272
+ </select>
273
+ <div>
274
+ <label for="ai-api-key">API Key:</label>
275
+ <input type="password" id="ai-api-key" placeholder="Enter your API key">
276
+ </div>
277
+ </div>
278
+ <div id="voice-status"></div>
279
+ <div class="settings-actions">
280
+ <button id="reset-settings" type="button" class="danger-button">Reset All Settings</button>
281
+ </div>
282
+ </div>
283
+ </div>
284
+ </div>
285
+ </div>
286
+
287
+ <!-- Fixed controls as z-plane overlay -->
288
+ <div id="fixed-controls" class="fader">
289
+ <button id="settings-toggle" title="Settings">⚙️</button>
290
+ <button id="log-toggle" title="Show Debug Log (Ctrl+L)">^L 📋</button>
291
+ <button id="install-button" title="Install App" class="hidden">📱 Install</button>
292
+ <div id="version-box">loading...</div>
293
+ <div id="inactivity-countdown">30s</div>
294
+ <div id="memory-display"></div>
295
+ </div>
296
+
297
+ <!-- Debug log panel as z-plane overlay -->
298
+ <div id="debug-log" class="hidden">
299
+ <div id="debug-log-content"></div>
300
+ <div id="debug-log-controls">
301
+ <button id="clear-log">Clear Log</button>
302
+ <div id="debug-log-legend">^C: Copy | ^F: Save to File | ESC: Close</div>
303
+ </div>
304
+ </div>
305
+
306
+ <!-- Help dialog -->
307
+ <div id="help-dialog" class="hidden">
308
+ <div id="help-dialog-content">
309
+ <button id="help-close">✕</button>
310
+ <h2>Voice Commands</h2>
311
+ <div class="help-section">
312
+ <h3>Timer Commands</h3>
313
+ <ul>
314
+ <li>"timer 5 minutes" - Set a 5 minute timer</li>
315
+ <li>"timer 30 seconds" - Set a 30 second timer</li>
316
+ <li>"timer 1 and a half hours" - Set a 90 minute timer</li>
317
+ <li>"cancel timer" - Cancel the current timer</li>
318
+ </ul>
319
+ </div>
320
+ <div class="help-section">
321
+ <h3>Display Commands</h3>
322
+ <ul>
323
+ <li>"show digital time" - Show digital clock overlay</li>
324
+ <li>"hide digital time" - Hide digital clock overlay</li>
325
+ <li>"fullscreen" - Enter fullscreen mode</li>
326
+ <li>"exit fullscreen" - Exit fullscreen mode</li>
327
+ </ul>
328
+ </div>
329
+ <div class="help-section">
330
+ <h3>Theme Commands</h3>
331
+ <ul>
332
+ <li>"light mode" - Switch to light theme</li>
333
+ <li>"dark mode" - Switch to dark theme</li>
334
+ <li>"system theme" - Use system theme preference</li>
335
+ </ul>
336
+ </div>
337
+ <div class="help-section">
338
+ <h3>Other Commands</h3>
339
+ <ul>
340
+ <li>"silent" - Toggle silent mode</li>
341
+ <li>"stop voice" - Disable voice control</li>
342
+ <li>"what time is it" - Announce the current time</li>
343
+ <li>"stop" - Stop speaking help</li>
344
+ </ul>
345
+ </div>
346
+ </div>
347
+ </div>
348
+
349
+ <!-- Timer complete audio -->
350
+ <audio id="timer-sound" preload="auto">
351
+ <source
352
+ src="data:audio/wav;base64,UklGRnoGAABXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YQoGAACBhYqFbF1fdJivrJBhNjVgodDbq2EcBj+a2/LDciUFLIHO8tiJNwgZaLvt559NEAxQp+PwtmMcBjiR1/LMeSwFJHfH8N2QQAoUXrTp66hVFApGn+DyvmwhBTGH0fPTgjMGHm7A7+OZURE"
353
+ type="audio/wav">
354
+ </audio>
355
+
356
+ <!-- TensorFlow.js and Speech Commands Model -->
357
+ <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@4.22.0/dist/tf.min.js"></script>
358
+ <script
359
+ src="https://cdn.jsdelivr.net/npm/@tensorflow-models/speech-commands@0.5.4/dist/speech-commands.min.js"></script>
360
+
361
+ <!-- Porcupine model loaded dynamically when needed -->
362
+ <!-- <script src="porcupine-model-base64.js"></script> -->
363
+ <script src="clock.js" type="module" defer></script>
364
+ <script>
365
+ // Register service worker for PWA functionality when served from server
366
+ if ('serviceWorker' in navigator && window.location.protocol !== 'file:') {
367
+ window.addEventListener('load', () => {
368
+ navigator.serviceWorker.register('./sw.js')
369
+ .then(reg => {
370
+ // Service worker registered successfully - no console logging to avoid violations
371
+ })
372
+ .catch(err => {
373
+ // Service worker registration failed - only log actual errors
374
+ if (err.name !== 'SecurityError') {
375
+ console.error('Service Worker registration failed:', err);
376
+ }
377
+ });
378
+ });
379
+ }
380
+ </script>
381
+ </body>
382
+
383
+ </html>