@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,678 @@
1
+ # msger Development Session Notes
2
+ **Date:** 2025-11-04
3
+ **Status:** In Progress - Ready to Continue
4
+
5
+ ## What Was Completed Today ✅
6
+
7
+ ### 1. Fixed Fullscreen Feature (F11 and Esc Keys)
8
+ - **Problem:** Fullscreen wasn't working with F11 or Esc keys
9
+ - **Root Cause:** Was mixing native window fullscreen (Rust/tao) with HTML5 fullscreen (JavaScript)
10
+ - **Solution:**
11
+ - Implemented keyboard event handling at Rust/window level
12
+ - F11 toggles fullscreen (works everywhere, including `-url` mode)
13
+ - Esc exits fullscreen first, then dismisses window on second press
14
+ - Fixed monitor detection bug by using `current_monitor()` instead of `None`
15
+ - **Files Modified:**
16
+ - `msger-native/src/main.rs` - Added KeyboardInput event handling, monitor detection
17
+ - `msger-native/src/template.html` - Updated F11/Esc handlers
18
+ - **Binary Rebuilt:** ✅ Latest binary includes all fixes
19
+
20
+ ### 2. Implemented msger JavaScript API
21
+ Full window control and data persistence API now available!
22
+
23
+ #### Window Control Functions
24
+ ```javascript
25
+ msger.toggleFullscreen()
26
+ msger.setFullscreen(enabled)
27
+ msger.minimize()
28
+ msger.maximize()
29
+ msger.setSize(width, height)
30
+ msger.setPosition(x, y)
31
+ msger.setAlwaysOnTop(enabled)
32
+ msger.setTitle(title)
33
+ msger.close(result?)
34
+ ```
35
+
36
+ #### Data Persistence Functions
37
+ ```javascript
38
+ msger.saveData(key, value) // localStorage with msger_ prefix
39
+ msger.loadData(key, defaultValue?)
40
+ msger.removeData(key)
41
+ msger.clearData() // Clear all msger_* keys
42
+ ```
43
+
44
+ **Implementation:**
45
+ - JavaScript API injected into both template.html and URL mode
46
+ - IPC message passing from JS → Rust
47
+ - Event loop processes actions in `MainEventsCleared`
48
+ - **Works in both `-message` and `-url` modes!**
49
+
50
+ **Files Modified:**
51
+ - `msger-native/src/main.rs` - Added IPC action handling, window control logic
52
+ - `msger-native/src/template.html` - Added window.msger API
53
+
54
+ ### 3. Created @bobfrankston/msgerdefs Package
55
+ Separate TypeScript definitions package for the msger API!
56
+
57
+ **Files Created:**
58
+ - `msgerdefs/package.json` - NPM package configuration
59
+ - `msgerdefs/msgerdefs.ts` - Full TypeScript definitions
60
+ - `msgerdefs/msgerdefs.d.ts` - Compiled type definitions
61
+ - `msgerdefs/msgerdefs.js` - Compiled JavaScript
62
+ - `msgerdefs/README.md` - Package documentation
63
+ - `msgerdefs/tsconfig.json` - TypeScript compiler config
64
+ - `msgerdefs/samples.html` - Interactive examples & test page
65
+ - `msgerdefs/.gitignore` - Git ignore file
66
+
67
+ **Features:**
68
+ - Full TypeScript type definitions for all API methods
69
+ - Browser-compatible `getMsgerAPI()` function
70
+ - `isMsger()` detection function
71
+ - Ready for separate Git repository
72
+ - Ready to publish to NPM as `@bobfrankston/msgerdefs`
73
+
74
+ ### 4. Created Comprehensive Documentation
75
+ - **MSGER-API.md** - Complete API reference with examples
76
+ - **msgerdefs/README.md** - Package usage guide
77
+ - **msgerdefs/samples.html** - Interactive examples for all features
78
+
79
+ ## Known Issues 🐛
80
+
81
+ ### Fullscreen Toggle Bug (FIXED ✅)
82
+ - **Issue:** Window disappeared after clicking "Toggle Fullscreen" button
83
+ - **Fix Applied:** Now uses `current_monitor()` to ensure fullscreen on correct monitor
84
+ - **Rebuild Status:** Fixed in latest binary
85
+ - **Test:** Try `msger -url msgerdefs/samples.html` (now supports relative paths!)
86
+
87
+ ### Relative Path URLs Not Working (FIXED ✅)
88
+ - **Issue:** `node cli.js -url msgerdefs/samples.html` failed with WebView2Error
89
+ - **Root Cause:** WebView2 requires absolute `file://` URLs, not relative paths
90
+ - **Fix Applied:** Added path normalization in `shower.ts` - automatically converts file paths to `file://` URLs
91
+ - **Now Supports:**
92
+ - Relative paths: `msgerdefs/samples.html`
93
+ - Absolute paths: `Y:/dev/utils/msger/file.html`
94
+ - File URLs: `file:///Y:/dev/utils/msger/file.html`
95
+ - HTTP URLs: `http://example.com` and `https://example.com`
96
+ - **Files Modified:** `shower.ts` - Added pathToFileURL conversion
97
+
98
+ ### Toggle Fullscreen Crashes in URL Mode (CRITICAL BUG 🔴)
99
+ - **Issue:** Clicking "Toggle Fullscreen" button in samples.html causes panic/crash
100
+ - **Error:** `wry-0.47.2\src\webview2\mod.rs:812:58: http::Error(InvalidUri(InvalidFormat))`
101
+ - **Root Cause:** Bug in wry library - calling window fullscreen operations while webview is active causes wry to parse something as URI and fail
102
+ - **Workaround:** F11 key works fine! Only the JavaScript `msger.toggleFullscreen()` button crashes
103
+ - **Status:** Need to either:
104
+ 1. Update wry to newer version (check if fixed)
105
+ 2. Disable JS fullscreen button for URL mode
106
+ 3. Find different approach to fullscreen that doesn't trigger wry bug
107
+ - **Note:** This is a wry library bug, not our code bug
108
+ - **Reproducible:**
109
+ ```bash
110
+ node cli.js -url msgerdefs/samples.html
111
+ # Click "Toggle Fullscreen" button → CRASH
112
+ # Press F11 key → Works fine
113
+ ```
114
+
115
+ ## Next Steps - File System API 📁
116
+
117
+ ### Agreed Approach: Option A - Hybrid
118
+ File system access with two modes:
119
+
120
+ #### 1. File Dialogs (Always Safe - No Flag Required)
121
+ ```javascript
122
+ // Select files
123
+ const file = await msger.fs.selectFile(options)
124
+ const files = await msger.fs.selectFiles(options)
125
+ const path = await msger.fs.saveFileAs(content, filename, options)
126
+ const folder = await msger.fs.selectFolder(options)
127
+ ```
128
+ - User chooses files via native dialogs
129
+ - Always returns content + path
130
+ - No security concerns (user explicitly selects)
131
+
132
+ #### 2. Direct File Access (Requires `--allowFs` Flag)
133
+ ```javascript
134
+ // Read/write/list files directly by path
135
+ const content = await msger.fs.read(path)
136
+ await msger.fs.write(path, content)
137
+ const files = await msger.fs.list(path)
138
+ const exists = await msger.fs.exists(path)
139
+ await msger.fs.delete(path)
140
+ ```
141
+ - Requires launching with: `msger -url "..." --allowFs`
142
+ - Security conscious - disabled by default
143
+ - Useful for trusted local apps
144
+
145
+ ### Implementation Plan
146
+
147
+ #### Step 1: Add Dependencies to Cargo.toml
148
+ ```toml
149
+ [dependencies]
150
+ # File dialog library
151
+ rfd = "0.14" # Native file dialogs (cross-platform)
152
+ ```
153
+
154
+ #### Step 2: Extend IPC Message Types
155
+ Add new action types for file operations:
156
+ - `selectFile`, `selectFiles`, `saveFileAs`, `selectFolder`
157
+ - `fs.read`, `fs.write`, `fs.list`, `fs.exists`, `fs.delete`
158
+
159
+ #### Step 3: Implement in Rust (main.rs)
160
+ - Handle file dialog actions → return results to JS via IPC
161
+ - Handle direct file access (check `allowFs` flag first!)
162
+ - Return results/errors as JSON
163
+
164
+ #### Step 4: Extend JavaScript API
165
+ - Add `msger.fs.*` methods
166
+ - Make async (return Promises)
167
+ - Update both template.html and injected script
168
+
169
+ #### Step 5: Update TypeScript Definitions
170
+ - Add file system types to msgerdefs.ts
171
+ - Mark `fs` as optional (only available when `allowFs` enabled)
172
+
173
+ #### Step 6: Test & Document
174
+ - Create file system examples in samples.html
175
+ - Update MSGER-API.md with file system docs
176
+ - Test on Windows (primary), Linux (if possible)
177
+
178
+ ## Important Notes for Tomorrow
179
+
180
+ ### CLI Options Status
181
+ - **Case Sensitivity:** CLI options are NOT case sensitive (user confirmed)
182
+ - `-url` and `-URL` and `--url` all work
183
+ - `-fullscreen` and `--fullscreen` both work
184
+
185
+ ### PWA Support
186
+ - PWAs loaded with `-url` work! (Service Workers, IndexedDB, Manifest)
187
+ - Service Workers: ✅ Work
188
+ - Offline mode: ✅ Works
189
+ - "Install" UI: ❌ Not applicable (already native window)
190
+ - Push notifications: ⚠️ Platform-dependent
191
+
192
+ ### Git Repository Plan
193
+ - `msgerdefs/` should have its own Git repository
194
+ - Keep copy in parent msger repo for convenience
195
+ - Publish to NPM as `@bobfrankston/msgerdefs`
196
+
197
+ ## File Locations
198
+
199
+ ### Source Code
200
+ - `msger-native/src/main.rs` - Rust backend (window, IPC, events)
201
+ - `msger-native/src/template.html` - HTML template with msger API
202
+ - `clihandler.ts` - CLI argument parsing
203
+ - `shower.ts` - TypeScript wrapper for Rust binary
204
+
205
+ ### TypeScript Definitions
206
+ - `msgerdefs/msgerdefs.ts` - TypeScript source
207
+ - `msgerdefs/package.json` - NPM package config
208
+ - `msgerdefs/samples.html` - Interactive examples
209
+
210
+ ### Documentation
211
+ - `README.md` - Main project readme
212
+ - `MSGER-API.md` - Complete API reference
213
+ - `FULLSCREEN-FEATURE.md` - Fullscreen implementation details
214
+ - `msgerdefs/README.md` - TypeScript package readme
215
+ - `SESSION-NOTES.md` - This file!
216
+
217
+ ### Built Files
218
+ - `msger-native/bin/msgernative.exe` - Windows binary (latest)
219
+ - `msgernative-linux-x64` - Linux x64 binary
220
+ - `msgerdefs/msgerdefs.js` - Compiled JavaScript
221
+ - `msgerdefs/msgerdefs.d.ts` - Compiled TypeScript definitions
222
+
223
+ ## Build Commands
224
+
225
+ ### Rebuild Rust Binary (Windows)
226
+ ```powershell
227
+ powershell.exe -Command "& {Import-Module 'C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\Microsoft.VisualStudio.DevShell.dll'; Enter-VsDevShell -VsInstallPath 'C:\Program Files\Microsoft Visual Studio\2022\Community' -SkipAutomaticLocation; cd Y:\dev\utils\msger\msger-native; cargo build --release; Copy-Item target\release\msgernative.exe bin\ -Force}"
228
+ ```
229
+
230
+ ### Compile TypeScript
231
+ ```bash
232
+ # Main project
233
+ tsc
234
+
235
+ # msgerdefs package
236
+ cd msgerdefs && tsc
237
+ ```
238
+
239
+ ### Test Commands
240
+ ```bash
241
+ # Test basic window
242
+ node cli.js -message "Test" -timeout 5
243
+
244
+ # Test fullscreen
245
+ node cli.js --fullscreen -message "Press F11 or Esc" -timeout 10
246
+
247
+ # Test samples page
248
+ node cli.js -url "file:///Y:/dev/utils/msger/msgerdefs/samples.html" -size 900,700
249
+
250
+ # Test with URL
251
+ node cli.js -url "https://example.com" -size 1024,768
252
+ ```
253
+
254
+ ## Questions to Address Tomorrow
255
+
256
+ 1. **Window Closing Bug:** Why does window abort after some operations?
257
+ 2. **File Dialog Library:** Confirm `rfd` crate is the best choice for cross-platform file dialogs
258
+ 3. **allowFs Flag:** How to pass/validate the `--allowFs` flag securely?
259
+ 4. **Async Responses:** How to handle async file operations and return results to JavaScript?
260
+ 5. **Error Handling:** How to return errors to JavaScript (reject promises)?
261
+
262
+ ## Remember
263
+
264
+ - Always use VS Developer Command Prompt for Rust builds on Windows
265
+ - Test in both template mode (`-message`) and URL mode (`-url`)
266
+ - Update both Rust code AND JavaScript API in template.html
267
+ - Keep msgerdefs types in sync with implementation
268
+ - Fullscreen fix: Always use `current_monitor()` not `None`
269
+
270
+ ---
271
+
272
+ **Session End Time:** Ready to continue tomorrow!
273
+ **Next Priority:** Implement file system API (Option A - Hybrid approach)
274
+
275
+ ** One Additional note
276
+
277
+ According to
278
+ https://www.perplexity.ai/search/can-the-rust-tool-chain-compil-kTNtAElGREq2YIU8qCpx_Q#1
279
+ rust should be able to cross compile to the pi on Windows.
280
+
281
+ ---
282
+
283
+ # Session 2025-11-05: Critical Bug Discovery
284
+
285
+ ## CRITICAL: Window Manipulation API Completely Broken ❌
286
+
287
+ ### What We Discovered
288
+ Testing revealed that **ALL window manipulation functions** cause crashes when called via JavaScript IPC, not just fullscreen. This is a fundamental bug in wry 0.47.2.
289
+
290
+ ### The Bug
291
+ **Error:** `http::Error(InvalidUri(InvalidFormat))` at `wry-0.47.2/src/webview2/mod.rs:812:58`
292
+
293
+ When JavaScript calls any window manipulation function through IPC (`window.ipc.postMessage`), the wry library tries to parse something as an HTTP URI internally and crashes. The panic occurs in FFI code that "cannot unwind", so even Rust's `catch_unwind` can't prevent the crash.
294
+
295
+ ### Affected Functions (ALL DISABLED)
296
+ - ❌ `msger.toggleFullscreen()`
297
+ - ❌ `msger.setFullscreen(enabled)`
298
+ - ❌ `msger.minimize()`
299
+ - ❌ `msger.maximize()`
300
+ - ❌ `msger.setSize(width, height)`
301
+ - ❌ `msger.setPosition(x, y)`
302
+ - ❌ `msger.setAlwaysOnTop(enabled)`
303
+ - ❌ `msger.setTitle(title)`
304
+
305
+ ### Still Working ✅
306
+ - ✅ `msger.saveData()` / `msger.loadData()` / `msger.removeData()` / `msger.clearData()` - localStorage only
307
+ - ✅ `msger.isAvailable()` - Pure JavaScript
308
+ - ✅ `msger.testHello()` - Pure JavaScript test function
309
+ - ⚠️ `msger.close(result)` - May work (exits immediately)
310
+
311
+ ### Changes Made
312
+
313
+ #### 1. Disabled All Broken Functions
314
+ Updated both `main.rs` (MSGER_JS_API) and `template.html`:
315
+ - All window manipulation functions now return `false`
316
+ - Log descriptive error messages to console
317
+ - Provide alternative solutions (CLI flags, F11 key)
318
+ - No more crashes!
319
+
320
+ #### 2. Added Error Handling
321
+ - IPC availability check before sending messages
322
+ - Try/catch blocks around all IPC operations
323
+ - `safePostMessage()` helper function
324
+ - Graceful degradation with helpful error messages
325
+
326
+ #### 3. Created Test Suite
327
+ - `test-msger-functions.html` - Comprehensive test page
328
+ - Tests basic functionality (testHello, testIPC)
329
+ - Tests each API function individually
330
+ - Auto-runs basic tests on load
331
+
332
+ #### 4. Documentation
333
+ - **KNOWN-BUGS.md** - Complete documentation of the wry bug
334
+ - Detailed technical explanation
335
+ - Workarounds for each function
336
+ - Testing instructions
337
+ - Potential solutions
338
+
339
+ ### Workarounds
340
+
341
+ Since JavaScript API is broken, use **CLI arguments** instead:
342
+
343
+ ```bash
344
+ # Configure everything at startup
345
+ node cli.js -url page.html \
346
+ -fullscreen \
347
+ -size 1920,1080 \
348
+ -pos 0,0 \
349
+ -alwaysOnTop \
350
+ -title "My App"
351
+ ```
352
+
353
+ For fullscreen toggle during runtime:
354
+ - **F11 key** - Works at native window level (bypasses IPC)
355
+ - **Esc key** - Exits fullscreen
356
+
357
+ ### Next Steps
358
+
359
+ 1. **Test CLI workarounds** - Verify all CLI flags work correctly
360
+ 2. **Update msgerdefs package** - Mark window functions as deprecated/broken
361
+ 3. **Research wry updates** - Check if newer versions fix this
362
+ 4. **Consider alternatives:**
363
+ - Full Tauri framework (better WebView2 integration)
364
+ - Different WebView library
365
+ - Native UI for controls instead of HTML/JS
366
+
367
+ ### Files Modified
368
+ - `msger-native/src/main.rs` - Disabled window manipulation API
369
+ - `msger-native/src/template.html` - Disabled window manipulation API
370
+ - `test-msger-functions.html` - Created test suite
371
+ - `KNOWN-BUGS.md` - Created documentation
372
+
373
+ ### Binary Status
374
+ - ✅ Rebuilt with all fixes (v0.1.57)
375
+ - ✅ No more crashes from window manipulation
376
+ - ✅ Helpful error messages in console
377
+ - ✅ localStorage functions still work perfectly
378
+
379
+ ### DEFINITIVE TEST RESULTS
380
+
381
+ #### IPC Crash Test
382
+ Created `test-ipc-reach.html` to test if messages reach Rust handlers:
383
+ - **Result:** CRASH on `window.ipc.postMessage()`
384
+ - **Location:** wry-0.47.2/src/webview2/mod.rs:812:58
385
+ - **Error:** `http::Error(InvalidUri(InvalidFormat))`
386
+
387
+ **Critical Finding:**
388
+ - Crash happens **INSIDE wry library**, not in our code
389
+ - Message never reaches Rust handlers (no DEBUG output)
390
+ - `catch_unwind` is **useless** (panic in FFI/COM code)
391
+ - **ALL IPC is broken at the library level**
392
+
393
+ #### What Actually Works
394
+ - ✅ `msger.saveData()` - localStorage only
395
+ - ✅ `msger.loadData()` - localStorage only
396
+ - ✅ `msger.removeData()` - localStorage only
397
+ - ✅ `msger.clearData()` - localStorage only
398
+ - ✅ Browser APIs (File API, Download API)
399
+ - ❌ **Everything else is broken**
400
+
401
+ #### Why F11 Doesn't Work
402
+ - WebView2 captures keyboard events before window handler
403
+ - Rust window handler never receives F11/Esc keys
404
+ - HTML5 fullscreen API (document.requestFullscreen) might work but not native window fullscreen
405
+
406
+ ### Clean Demo Created
407
+ **`msgerdefs/samples.html`** - Updated to show only working features:
408
+ - Basic storage with timestamps
409
+ - Structured data (objects, arrays)
410
+ - List/clear all data
411
+ - Download with custom filename (not "virtual files")
412
+ - Storage location information
413
+ - PWA support documentation
414
+ - No broken window control buttons
415
+ - Clear warnings about limitations
416
+
417
+ ### Storage Questions Answered
418
+
419
+ **Q: Where are settings saved?**
420
+ - **Location:** `%LOCALAPPDATA%\Microsoft\Edge\User Data\WebView2\Default\Local Storage\leveldb\`
421
+ - Each URL origin has its own storage partition
422
+ - Data persists across restarts
423
+ - Can be viewed with `showStorageInfo()` function in samples.html
424
+
425
+ **Q: Do PWAs work?**
426
+ - ✅ **YES!** PWAs loaded with `-url` work great:
427
+ - Service Workers ✅
428
+ - IndexedDB ✅ (can store GBs of data)
429
+ - Cache API ✅ (offline assets)
430
+ - localStorage/sessionStorage ✅
431
+ - Web Manifest ✅
432
+ - Push Notifications ⚠️ (platform dependent)
433
+ - "Install" UI ❌ (not applicable - already native window)
434
+ - Example: `node cli.js -url https://your-pwa.app -detach`
435
+
436
+ **Q: Why "virtual files"?**
437
+ - Bad naming! Changed to "Download with custom filename"
438
+ - It's just localStorage + browser download API
439
+ - No real file system involved
440
+
441
+ ---
442
+
443
+ # Session 2025-11-05 (Continued): F11 Fullscreen Fixed ✅
444
+
445
+ ## F11 Fullscreen Now Works!
446
+
447
+ **Problem:** F11 key was not working because WebView2 captures keyboard events before the Rust window handler receives them.
448
+
449
+ **Solution:** Implemented HTML5 Fullscreen API handler in JavaScript
450
+ - Added `keydown` event listener that intercepts F11
451
+ - Uses `document.documentElement.requestFullscreen()` for fullscreen
452
+ - Uses `document.exitFullscreen()` to exit
453
+ - **No IPC required** - pure browser API, so no crash!
454
+
455
+ **How it Works:**
456
+ - Press **F11** → Toggle fullscreen (enter if not fullscreen, exit if fullscreen)
457
+ - Press **Esc** → Exit fullscreen (if in fullscreen mode)
458
+
459
+ **Files Modified:**
460
+ - `msgerdefs/samples.html` - Added F11 keyboard handler, updated info boxes
461
+
462
+ **Note:** This is HTML5 fullscreen (webpage fullscreen), not native window fullscreen, but it provides the same user experience.
463
+
464
+ ## Isolated Storage with Custom WebContext ✅
465
+
466
+ **Problem:** msger was using the default WebView2 data folder, which meant all WebView2 applications shared the same localStorage!
467
+
468
+ **Solution:** Implemented custom `WebContext` with dedicated data directory
469
+ - Created `WebContext::new(Some(PathBuf))` with custom path
470
+ - Used `WebViewBuilder::with_web_context()` to apply it
471
+ - **New storage location:** `%LOCALAPPDATA%\msger\webview2\` (isolated from other apps)
472
+
473
+ **Benefits:**
474
+ - Each app using msger gets its own isolated storage
475
+ - No conflicts with other WebView2 applications
476
+ - Data is still persistent across restarts
477
+ - Each URL origin still gets its own partition within msger's storage
478
+
479
+ **Files Modified:**
480
+ - `msger-native/src/main.rs` - Added WebContext import and configuration
481
+ - Binary rebuilt successfully
482
+
483
+ ## OK/Cancel Buttons Added to Samples ✅
484
+
485
+ **Added:** Window control demonstration buttons to show broken IPC
486
+ - Three red buttons: "Try OK", "Try Cancel", "Try Close"
487
+ - Safely call `msger.close()` methods without crashing
488
+ - Display helpful error messages explaining the wry bug
489
+ - List workarounds (X button, Alt+F4, CLI flags)
490
+
491
+ **Files Modified:**
492
+ - `msgerdefs/samples.html` - Added window controls section with demo buttons
493
+
494
+ ## Critical JavaScript Bug Fixed ✅
495
+
496
+ **Problem:** Template.html had a "Temporal Dead Zone" error
497
+ - **Line 312**: Used `zoomLevel` variable before declaration
498
+ - **Line 317**: Declared `let zoomLevel = 1.0` (too late!)
499
+ - **Error:** `Uncaught ReferenceError: Cannot access 'zoomLevel' before initialization`
500
+ - **Impact:** Entire script stopped executing, preventing ALL JavaScript from running (including F11 handler in URL mode)
501
+
502
+ **Solution:** Moved `let zoomLevel = 1.0` declaration before usage
503
+ - Zoom features now work correctly
504
+ - F11 handler in samples.html can now execute
505
+ - No more JavaScript errors blocking initialization
506
+
507
+ **Files Modified:**
508
+ - `msger-native/src/template.html` - Fixed zoomLevel declaration order
509
+ - Binary rebuilt (v0.1.57)
510
+
511
+ **This explains why F11 wasn't working!** The JavaScript error was stopping script execution.
512
+
513
+ ## IPC Works in Template Mode, Crashes in URL Mode ✅
514
+
515
+ **Critical Discovery:**
516
+ - **IPC WORKS** in template mode (`-message`, `-html`, `-htmlfrom`)
517
+ - **IPC CRASHES** in URL mode (`-url` with injected script)
518
+ - Root cause: wry 0.47.2 bug only affects injected scripts in URL mode
519
+
520
+ **Working:**
521
+ - ✅ OK/Cancel buttons work in message mode
522
+ - ✅ `msger.saveData()` etc. work everywhere (no IPC needed)
523
+ - ✅ `msger.close()` works in template mode via IPC
524
+
525
+ **Broken:**
526
+ - ❌ All IPC operations crash in URL mode (injected script context)
527
+ - ❌ F11 for native fullscreen (HTML5 fullscreen works but only makes content fullscreen, not window)
528
+
529
+ **Files Verified:**
530
+ - `msger-native/src/template.html` - Restored working IPC in sendResult()
531
+ - Binary tested and confirmed working
532
+
533
+ ## Added -htmlfrom Option ✅
534
+
535
+ **Purpose:** Load HTML from file or URL and embed in template (unlike -url which loads directly)
536
+
537
+ **Implementation:**
538
+ - Added `-htmlfrom <file|url>` CLI option
539
+ - Fetches HTML content (file or URL) and embeds in template.html
540
+ - Has OK/Cancel buttons (unlike -url)
541
+ - msger API available (IPC works since it's template mode)
542
+ - No CORS restrictions (fetched server-side)
543
+
544
+ **Files Modified:**
545
+ - `clihandler.ts` - Added htmlfrom parsing, URL/file loading
546
+ - `shower.ts` - TypeScript interface
547
+ - Compiled successfully
548
+
549
+ **Known Limitation:**
550
+ - ⚠️ External resources (CSS, JS, images) may be blocked by CSP when embedding HTML
551
+ - Works best for self-contained HTML or local files
552
+ - For full web pages with external resources, use `-url` instead
553
+
554
+ ## Added -dev Flag (Partial) ⚠️
555
+
556
+ **Status:** Parses flag but can't auto-open DevTools
557
+ - wry 0.47.2 doesn't have `open_devtools()` method available
558
+ - Flag accepted but prints message to press F12 manually
559
+ - DevTools enabled by default, just can't auto-open
560
+
561
+ **Files Modified:**
562
+ - `clihandler.ts` - Added -dev parsing
563
+ - `shower.ts` - Added dev field
564
+ - `main.rs` - Added dev field, commented out open_devtools()
565
+
566
+ ## Security Note Added ✅
567
+
568
+ Added security warning to help text:
569
+ > msger is designed for displaying trusted, friendly content (local apps, your own HTML).
570
+ > It is NOT a secure sandbox for untrusted/hostile web content.
571
+ > Use -htmlfrom and -url with trusted sources only.
572
+
573
+ ## Session Summary - 2025-11-05 (Continued) - Updated 2025-11-06
574
+
575
+ ### What Works ✅
576
+ 1. **Native browser APIs** - localStorage, window.close(), all standard web APIs work perfectly
577
+ 2. **Template mode** - Message, HTML, htmlfrom all work with OK/Cancel buttons
578
+ 3. **Button results via IPC** - Parent process gets user's button choice (template mode only)
579
+ 4. **F11 fullscreen** - HTML5 fullscreen (content only, not native window)
580
+ 5. **Isolated storage** - Custom WebContext at %LOCALAPPDATA%\msger\webview2\
581
+ 6. **CLI fullscreen** - `-fullscreen` flag for native window fullscreen
582
+ 7. **-htmlfrom** - Load HTML from file/URL with buttons
583
+
584
+ ### msger JavaScript API - Minimal & Optional
585
+ **The msger API is almost empty** - native browser APIs are preferred:
586
+ - `msger.isAvailable()` - Feature detection (returns true in msger)
587
+ - `msger.close()` - Same as native `window.close()` (no added value)
588
+ - Storage functions - Optional wrappers around native localStorage (not needed)
589
+
590
+ **Recommendation:** Use native browser APIs (`localStorage`, `window.close()`) for compatibility. Your code will work in any browser context, not just msger.
591
+
592
+ ### The Real Value of msger
593
+ **msger = Fast CLI tool that creates native windows with HTML and returns button results**
594
+ - Not a JavaScript API library
595
+ - It's a CLI wrapper around native webview
596
+ - Button results flow back to parent process (template mode)
597
+ - Everything else uses standard browser APIs
598
+
599
+ ### What's Broken ❌
600
+ 1. **URL mode IPC** - All window controls crash in `-url` mode (wry 0.47.2 bug)
601
+ 2. **Native F11** - Can't toggle native window fullscreen (WebView2 captures key)
602
+ 3. **-dev auto-open** - Can't programmatically open DevTools (method not available)
603
+ 4. **External resources in -htmlfrom** - CSP blocks external CSS/JS/images
604
+
605
+ ### Recently Fixed ✅
606
+ 1. **Multi-monitor positioning** (Fixed 2025-11-06)
607
+ - Was: Assumed monitors arranged left-to-right, added widths (wrong!)
608
+ - Now: Gets specific monitor's actual OS position and adds user offset
609
+ - Fix in main.rs: Use `monitor.position()` instead of adding widths
610
+ - Test with: `msger -message "Test" -pos 10,10,1` (screen 1 = second monitor)
611
+
612
+ ### Workarounds 🔧
613
+ 1. **Use template mode** (`-message`, `-html`, `-htmlfrom`) instead of `-url` when you need buttons
614
+ 2. **Use `-fullscreen` CLI flag** for native fullscreen instead of F11
615
+ 3. **Press F12** manually to open DevTools
616
+ 4. **Use `-url`** for pages with external resources instead of `-htmlfrom`
617
+ 5. **Press Esc or Alt+F4** to close window in URL mode
618
+
619
+ ### Next Session Priorities
620
+
621
+ #### 1. File System API - IMPLEMENT WHEN TIME FOR DEBUGGING (Week of 2025-11-11+)
622
+ **Goal:** Make msger feasible for writing platform apps with file access
623
+
624
+ **Why it's possible:**
625
+ - IPC works perfectly in template mode (proven by button clicks)
626
+ - Just need bidirectional IPC pattern (JavaScript → Rust → JavaScript)
627
+ - Use `rfd` crate for native file dialogs
628
+
629
+ **Two modes to implement:**
630
+
631
+ **A) File Dialogs (Always Safe - No Flag Required):**
632
+ ```javascript
633
+ // User chooses files via native dialogs
634
+ await msger.selectFile(options) // Pick single file → {path, content}
635
+ await msger.selectFiles(options) // Pick multiple files → [{path, content}...]
636
+ await msger.saveFileAs(content, name, options) // Save dialog → path
637
+ await msger.selectFolder(options) // Folder picker → path
638
+ ```
639
+
640
+ **B) Direct File Access (Requires --allowFs Flag):**
641
+ ```javascript
642
+ // Direct file operations by path - requires: msger -htmlfrom app.html --allowFs
643
+ await msger.fs.read(path) // Read file content
644
+ await msger.fs.write(path, content) // Write file
645
+ await msger.fs.list(path) // List directory
646
+ await msger.fs.exists(path) // Check if exists
647
+ await msger.fs.delete(path) // Delete file
648
+ await msger.fs.mkdir(path) // Create directory
649
+ ```
650
+
651
+ **Implementation approach:**
652
+ - Add `rfd = "0.14"` to Cargo.toml for dialogs
653
+ - Add `allowFs` flag to MessageBoxOptions
654
+ - Extend IPC handler to recognize file actions
655
+ - Check `allowFs` flag before allowing direct path operations
656
+ - Send results back via `webview.evaluate_script()`
657
+ - JavaScript polls for result in `window.__msger_file_result`
658
+ - Much better than native `<input type="file">` - returns actual paths!
659
+
660
+ #### 2. Window Manipulation APIs - ALSO POSSIBLE IN TEMPLATE MODE
661
+ **Discovery:** IPC only crashes in URL mode. Window manipulation should work in template mode!
662
+
663
+ **What could work:**
664
+ ```javascript
665
+ await msger.setSize(width, height)
666
+ await msger.setPosition(x, y)
667
+ await msger.setTitle(title)
668
+ await msger.setAlwaysOnTop(enabled)
669
+ await msger.minimize()
670
+ await msger.maximize()
671
+ ```
672
+
673
+ These were disabled thinking ALL IPC was broken, but template mode IPC works fine. Could re-enable with same bidirectional pattern as file API.
674
+
675
+ #### 3. Periodic wry Update Check
676
+ Check every few months if wry has fixed the URL mode IPC crash bug. Update to newer wry version if fixed. This would enable window/file APIs in URL mode too.
677
+
678
+ #### 4. Test PWA functionality with sample app
@@ -1 +1 @@
1
- {"version":3,"file":"clihandler.d.ts","sourceRoot":"","sources":["clihandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AA8EhD;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG;IAAE,OAAO,EAAE,iBAAiB,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,CAgLpH;AAED,wBAAgB,QAAQ,IAAI,IAAI,CAE/B;AAED,wBAAgB,WAAW,IAAI,IAAI,CAElC"}
1
+ {"version":3,"file":"clihandler.d.ts","sourceRoot":"","sources":["clihandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AA8FhD;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG;IAAE,OAAO,EAAE,iBAAiB,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,CA0NpH;AAED,wBAAgB,QAAQ,IAAI,IAAI,CAE/B;AAED,wBAAgB,WAAW,IAAI,IAAI,CAElC"}