arcane-os 0.1.0-dev.5

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 (248) hide show
  1. package/CHANGELOG.md +154 -0
  2. package/COMMERCIAL-LICENSE.md +13 -0
  3. package/LICENSE +661 -0
  4. package/NOTICE +70 -0
  5. package/README.md +448 -0
  6. package/bin/arcane-test.mjs +741 -0
  7. package/bin/arcane.mjs +5 -0
  8. package/docs/architecture.md +234 -0
  9. package/docs/compatibility.md +36 -0
  10. package/docs/event-manager.md +166 -0
  11. package/docs/platform-targets.md +108 -0
  12. package/docs/publishing.md +203 -0
  13. package/docs/reference/README.md +117 -0
  14. package/docs/reference/arcane-ollama.md +288 -0
  15. package/docs/reference/availability-and-normalization.md +123 -0
  16. package/docs/reference/behavioral-testing.md +86 -0
  17. package/docs/reference/cli.md +569 -0
  18. package/docs/reference/core/README.md +62 -0
  19. package/docs/reference/core/arcane-ai-contracts.md +873 -0
  20. package/docs/reference/core/arcane-api.md +601 -0
  21. package/docs/reference/core/arcane-entities.md +65 -0
  22. package/docs/reference/core/arcane-events.md +134 -0
  23. package/docs/reference/core/ollama-module.md +181 -0
  24. package/docs/reference/core/reference/arcane-api/ai-and-ollama.md +1909 -0
  25. package/docs/reference/core/reference/arcane-api/applications-terminal-capabilities.md +1057 -0
  26. package/docs/reference/core/reference/arcane-api/core-and-events.md +320 -0
  27. package/docs/reference/core/reference/arcane-api/filesystem-storage-preferences-appearance.md +610 -0
  28. package/docs/reference/core/reference/arcane-api/namespaces.md +1157 -0
  29. package/docs/reference/core/reference/arcane-api/platform-installation-users-system.md +1423 -0
  30. package/docs/reference/core/reference/arcane-api/session-provisioning-diagnostics-development.md +315 -0
  31. package/docs/reference/event-manager.md +957 -0
  32. package/docs/reference/inventory/package-api.json +2632 -0
  33. package/docs/reference/inventory/runtime-components.json +934 -0
  34. package/docs/reference/inventory/runtime-entities.json +26 -0
  35. package/docs/reference/inventory/runtime-modules.json +1249 -0
  36. package/docs/reference/protocols.md +242 -0
  37. package/docs/reference/runtime-components.md +1098 -0
  38. package/docs/reference/runtime-entities.md +303 -0
  39. package/docs/reference/runtime-modules.md +2010 -0
  40. package/docs/reference/sdk-api.md +4901 -0
  41. package/docs/roadmap.md +79 -0
  42. package/docs/work-amplification.md +124 -0
  43. package/node_modules/event-pubsub/CHANGELOG.md +55 -0
  44. package/node_modules/event-pubsub/MIGRATION.md +70 -0
  45. package/node_modules/event-pubsub/README.md +363 -0
  46. package/node_modules/event-pubsub/SECURITY.md +37 -0
  47. package/node_modules/event-pubsub/index.js +141 -0
  48. package/node_modules/event-pubsub/licence +21 -0
  49. package/node_modules/event-pubsub/package.json +59 -0
  50. package/node_modules/strong-type/README.md +408 -0
  51. package/node_modules/strong-type/assets/strong-type-header.png +0 -0
  52. package/node_modules/strong-type/index.js +1151 -0
  53. package/node_modules/strong-type/licence +21 -0
  54. package/node_modules/strong-type/node.js +125 -0
  55. package/node_modules/strong-type/package.json +61 -0
  56. package/package.json +95 -0
  57. package/runtime/ARCANE_RUNTIME_RELEASE.json +791 -0
  58. package/runtime/arcane/components/app-bar.html +468 -0
  59. package/runtime/arcane/components/assistant-panel.html +715 -0
  60. package/runtime/arcane/components/calculator.html +8 -0
  61. package/runtime/arcane/components/chart.html +655 -0
  62. package/runtime/arcane/components/chat.html +1225 -0
  63. package/runtime/arcane/components/conversation-view.html +13 -0
  64. package/runtime/arcane/components/dashboard-config.html +341 -0
  65. package/runtime/arcane/components/data-maintenance.html +112 -0
  66. package/runtime/arcane/components/data-view.html +92 -0
  67. package/runtime/arcane/components/directory-picker.html +197 -0
  68. package/runtime/arcane/components/document-inspector.html +252 -0
  69. package/runtime/arcane/components/file-drop.html +264 -0
  70. package/runtime/arcane/components/file-inspector.html +293 -0
  71. package/runtime/arcane/components/file-manager.html +1715 -0
  72. package/runtime/arcane/components/header.html +142 -0
  73. package/runtime/arcane/components/integration-settings.html +14 -0
  74. package/runtime/arcane/components/local-ai-status.html +360 -0
  75. package/runtime/arcane/components/markdown-document.html +1048 -0
  76. package/runtime/arcane/components/markdown-editor.html +360 -0
  77. package/runtime/arcane/components/media-embed.html +8 -0
  78. package/runtime/arcane/components/modal.html +402 -0
  79. package/runtime/arcane/components/output-panel.html +259 -0
  80. package/runtime/arcane/components/preferences-form.html +135 -0
  81. package/runtime/arcane/components/record-timeline.html +105 -0
  82. package/runtime/arcane/components/relationship-board.html +116 -0
  83. package/runtime/arcane/components/screen-capture.html +8 -0
  84. package/runtime/arcane/components/source-code-viewer.html +441 -0
  85. package/runtime/arcane/components/source-explanation.html +124 -0
  86. package/runtime/arcane/components/speech.html +365 -0
  87. package/runtime/arcane/components/summary-strip.html +177 -0
  88. package/runtime/arcane/components/table.html +77 -0
  89. package/runtime/arcane/components/task-progress.html +282 -0
  90. package/runtime/arcane/components/terminal-workspace.html +65 -0
  91. package/runtime/arcane/components/theme-editor.html +41 -0
  92. package/runtime/arcane/components/theme-switcher.html +46 -0
  93. package/runtime/arcane/components/unified-inbox.html +20 -0
  94. package/runtime/arcane/components/voice-transcription.html +476 -0
  95. package/runtime/arcane/components/weather-widget.html +8 -0
  96. package/runtime/arcane/components/web-navigator.html +239 -0
  97. package/runtime/arcane/css/communications.css +1 -0
  98. package/runtime/arcane/css/dashboard-config.css +45 -0
  99. package/runtime/arcane/css/document-site.css +981 -0
  100. package/runtime/arcane/css/layout.css +438 -0
  101. package/runtime/arcane/css/primitives.css +321 -0
  102. package/runtime/arcane/css/theme.css +112 -0
  103. package/runtime/arcane/css/utility-workspace.css +1 -0
  104. package/runtime/arcane/entities/ApiModelRecord.js +20 -0
  105. package/runtime/arcane/entities/Calculation.js +13 -0
  106. package/runtime/arcane/entities/Chat.js +581 -0
  107. package/runtime/arcane/entities/CommunicationMessage.js +29 -0
  108. package/runtime/arcane/entities/CommunicationThread.js +21 -0
  109. package/runtime/arcane/entities/Document.js +10 -0
  110. package/runtime/arcane/entities/File.js +143 -0
  111. package/runtime/arcane/entities/Image.js +135 -0
  112. package/runtime/arcane/entities/IntentEnvelope.js +834 -0
  113. package/runtime/arcane/entities/Preference.js +83 -0
  114. package/runtime/arcane/entities/TWiNPolicyDecision.js +1092 -0
  115. package/runtime/arcane/entities/TerminalSession.js +46 -0
  116. package/runtime/arcane/entities/Theme.js +107 -0
  117. package/runtime/arcane/entities/User.js +1046 -0
  118. package/runtime/arcane/entities/Weather.js +23 -0
  119. package/runtime/arcane/img/arcane-os-everywhere.png +0 -0
  120. package/runtime/arcane/img/arrow-left.png +0 -0
  121. package/runtime/arcane/img/arrow-right.png +0 -0
  122. package/runtime/arcane/img/doc.svg +5 -0
  123. package/runtime/arcane/img/folder.svg +4 -0
  124. package/runtime/arcane/img/image.svg +5 -0
  125. package/runtime/arcane/img/refresh.png +0 -0
  126. package/runtime/arcane/img/send.svg +9 -0
  127. package/runtime/arcane/img/trash.svg +5 -0
  128. package/runtime/arcane/img/upload.svg +5 -0
  129. package/runtime/arcane/modules/AI.js +2048 -0
  130. package/runtime/arcane/modules/AIPreferenceRuntime.js +32 -0
  131. package/runtime/arcane/modules/AIPreferenceTuple.js +92 -0
  132. package/runtime/arcane/modules/AIResponseLength.js +42 -0
  133. package/runtime/arcane/modules/AIResponseURLPolicy.js +626 -0
  134. package/runtime/arcane/modules/AnsiText.js +53 -0
  135. package/runtime/arcane/modules/ApiModelDatabase.js +25 -0
  136. package/runtime/arcane/modules/AppDataScope.js +245 -0
  137. package/runtime/arcane/modules/AppearancePreferences.js +28 -0
  138. package/runtime/arcane/modules/ArcaneCommunicationBridge.js +22 -0
  139. package/runtime/arcane/modules/ArcaneNavigationPolicy.js +135 -0
  140. package/runtime/arcane/modules/ArcaneNetworkPolicy.js +255 -0
  141. package/runtime/arcane/modules/AsyncBoundary.js +161 -0
  142. package/runtime/arcane/modules/BrowserTestSuite.js +326 -0
  143. package/runtime/arcane/modules/CalculatorEngine.js +20 -0
  144. package/runtime/arcane/modules/CaseEvidenceIndexer.js +134 -0
  145. package/runtime/arcane/modules/ChartLibrary.js +35 -0
  146. package/runtime/arcane/modules/ChatRecords.js +13 -0
  147. package/runtime/arcane/modules/CommunicationAppController.js +43 -0
  148. package/runtime/arcane/modules/CommunicationHub.js +16 -0
  149. package/runtime/arcane/modules/CommunicationPreferences.js +13 -0
  150. package/runtime/arcane/modules/CommunicationProviderRegistry.js +16 -0
  151. package/runtime/arcane/modules/ComponentContracts.js +586 -0
  152. package/runtime/arcane/modules/ConfiguredAIChatSession.js +288 -0
  153. package/runtime/arcane/modules/ConversationActionItems.js +488 -0
  154. package/runtime/arcane/modules/ConversationClosingReport.js +274 -0
  155. package/runtime/arcane/modules/ConversationTimebox.js +527 -0
  156. package/runtime/arcane/modules/CoreLocalModelCatalog.js +255 -0
  157. package/runtime/arcane/modules/DBLS.js +171 -0
  158. package/runtime/arcane/modules/DBOPFS.js +1154 -0
  159. package/runtime/arcane/modules/DBOPFSWorker.js +116 -0
  160. package/runtime/arcane/modules/DataMaintenance.js +91 -0
  161. package/runtime/arcane/modules/DevelopmentWorkspace.js +74 -0
  162. package/runtime/arcane/modules/DirectoryPicker.js +109 -0
  163. package/runtime/arcane/modules/DocumentNavigation.js +223 -0
  164. package/runtime/arcane/modules/Errors.js +1025 -0
  165. package/runtime/arcane/modules/GifEncoder.js +29 -0
  166. package/runtime/arcane/modules/HTMLImport.js +114 -0
  167. package/runtime/arcane/modules/InMemoryCommunicationProvider.js +14 -0
  168. package/runtime/arcane/modules/IsolatedModelQuestionRunner.js +275 -0
  169. package/runtime/arcane/modules/LocalAIReadiness.js +870 -0
  170. package/runtime/arcane/modules/LocalAIReadinessController.js +156 -0
  171. package/runtime/arcane/modules/MD.js +111 -0
  172. package/runtime/arcane/modules/Mail.js +352 -0
  173. package/runtime/arcane/modules/MailTransport.mjs +180 -0
  174. package/runtime/arcane/modules/Marked.min.js +71 -0
  175. package/runtime/arcane/modules/MemoryRecords.js +44 -0
  176. package/runtime/arcane/modules/MessageAdvisory.js +38 -0
  177. package/runtime/arcane/modules/ModelDefinition.js +189 -0
  178. package/runtime/arcane/modules/Ollama.js +74 -0
  179. package/runtime/arcane/modules/OllamaModelIdentifier.js +21 -0
  180. package/runtime/arcane/modules/OllamaSettings.js +24 -0
  181. package/runtime/arcane/modules/OpenMeteoWeatherProvider.js +14 -0
  182. package/runtime/arcane/modules/PreferenceStore.js +109 -0
  183. package/runtime/arcane/modules/QRCode.min.js +1 -0
  184. package/runtime/arcane/modules/Questionnaire.js +61 -0
  185. package/runtime/arcane/modules/RecordLinkIndex.js +24 -0
  186. package/runtime/arcane/modules/RecordPassageIndex.js +222 -0
  187. package/runtime/arcane/modules/RecordReviewStore.js +94 -0
  188. package/runtime/arcane/modules/RevocableProjectionLedger.js +1623 -0
  189. package/runtime/arcane/modules/RiskSignalAnalyzer.js +37 -0
  190. package/runtime/arcane/modules/ScamRiskPolicy.js +62 -0
  191. package/runtime/arcane/modules/ScopedOPFSCache.js +183 -0
  192. package/runtime/arcane/modules/ScreenCapture.js +20 -0
  193. package/runtime/arcane/modules/SpeechPlayback.js +581 -0
  194. package/runtime/arcane/modules/StaticDocumentCatalog.js +1248 -0
  195. package/runtime/arcane/modules/SystemAppearance.js +20 -0
  196. package/runtime/arcane/modules/SystemPlatformPresentation.js +51 -0
  197. package/runtime/arcane/modules/SystemToolRegistry.js +28 -0
  198. package/runtime/arcane/modules/TerminalClient.js +52 -0
  199. package/runtime/arcane/modules/TerminalCommandRegistry.js +50 -0
  200. package/runtime/arcane/modules/ThemeBootstrap.js +26 -0
  201. package/runtime/arcane/modules/ThemeManager.js +131 -0
  202. package/runtime/arcane/modules/TimeGuard.js +149 -0
  203. package/runtime/arcane/modules/ToolCallRouter.js +83 -0
  204. package/runtime/arcane/modules/WaitForComponent.js +102 -0
  205. package/runtime/arcane/modules/YouTubeMedia.js +16 -0
  206. package/runtime/arcane/modules/uPlot.LICENSE.txt +21 -0
  207. package/runtime/arcane/modules/uPlot.iife.min.js +2 -0
  208. package/runtime/arcane/modules/uPlot.min.css +1 -0
  209. package/runtime/arcane/security/arcane-network-policy.json +6 -0
  210. package/runtime/strong-type/index.js +352 -0
  211. package/runtime/strong-type/licence +21 -0
  212. package/runtime/strong-type/package.json +45 -0
  213. package/schemas/arcane-app-bundle.schema.json +125 -0
  214. package/schemas/arcane-app.schema.json +329 -0
  215. package/schemas/arcane-lock.schema.json +86 -0
  216. package/schemas/arcane-package.schema.json +224 -0
  217. package/schemas/cli-event.schema.json +122 -0
  218. package/schemas/event-stack.schema.json +152 -0
  219. package/schemas/native-build-plan.schema.json +176 -0
  220. package/schemas/target-adapter.schema.json +117 -0
  221. package/src/app-descriptor.mjs +500 -0
  222. package/src/cli/main.mjs +561 -0
  223. package/src/constants.mjs +31 -0
  224. package/src/dev-server.mjs +718 -0
  225. package/src/doctor.mjs +315 -0
  226. package/src/dom-event-instrumentation.mjs +594 -0
  227. package/src/errors.mjs +75 -0
  228. package/src/event-manager.mjs +1342 -0
  229. package/src/event-queue.mjs +138 -0
  230. package/src/events.mjs +219 -0
  231. package/src/index.mjs +177 -0
  232. package/src/integrated-provider-loader.mjs +432 -0
  233. package/src/native-plan.mjs +698 -0
  234. package/src/native-provider-loader.mjs +1126 -0
  235. package/src/packager/core.mjs +2691 -0
  236. package/src/process.mjs +353 -0
  237. package/src/release-bundle.mjs +2523 -0
  238. package/src/repository.mjs +90 -0
  239. package/src/runtime.mjs +452 -0
  240. package/src/scaffold.mjs +380 -0
  241. package/src/targets/index.mjs +436 -0
  242. package/src/templates/assets/app-icon.png +0 -0
  243. package/src/templates/workspace-template.mjs +388 -0
  244. package/src/testing-loader.mjs +9 -0
  245. package/src/testing.mjs +427 -0
  246. package/src/toolchain.mjs +1335 -0
  247. package/src/update-check.mjs +307 -0
  248. package/src/workspace.mjs +449 -0
@@ -0,0 +1,239 @@
1
+ <link rel="stylesheet" href="./arcane/css/theme.css?v=1">
2
+ <link rel="stylesheet" href="./arcane/css/primitives.css?v=1">
3
+ <style>
4
+ :host{display:block;height:100%;min-height:30rem}
5
+ .navigator{display:grid;grid-template-rows:auto 1fr auto;height:100%;min-height:30rem}
6
+ .toolbar{align-items:center;border-bottom:1px solid var(--arcane-border);display:grid;gap:var(--arcane-space-2);grid-template-columns:auto minmax(0,1fr) auto;padding:var(--arcane-space-3)}
7
+ .history,.actions{display:flex;gap:var(--arcane-space-1)}
8
+ button{min-width:2.5rem}
9
+ .address{display:flex;gap:var(--arcane-space-2)}
10
+ .address input{min-width:0;width:100%}
11
+ .viewport{display:grid;min-height:24rem}
12
+ .viewport>iframe,.viewport>.blocked{grid-area:1/1;height:100%;min-height:24rem;width:100%}
13
+ .viewport>iframe{background:var(--arcane-surface-raised);border:0}
14
+ .blocked{align-content:center;background:var(--arcane-surface-raised);box-sizing:border-box;display:grid;gap:var(--arcane-space-3);justify-items:start;overflow:auto;padding:clamp(var(--arcane-space-5),7vw,var(--arcane-space-8))}
15
+ .blocked[hidden]{display:none}
16
+ .blocked__eyebrow{color:var(--arcane-danger);font-weight:700;letter-spacing:.08em;margin:0;text-transform:uppercase}
17
+ .blocked h2,.blocked p{margin:0}
18
+ .blocked code{max-width:100%;overflow-wrap:anywhere}
19
+ .blocked dl{display:grid;gap:var(--arcane-space-2);margin:0}
20
+ .blocked dl div{display:grid;gap:var(--arcane-space-1)}
21
+ .blocked dt{color:var(--arcane-muted);font-size:.8rem;font-weight:700;text-transform:uppercase}
22
+ .blocked dd{margin:0}
23
+ .blocked__boundary{border-left:.25rem solid var(--arcane-danger);padding-left:var(--arcane-space-3)}
24
+ .status{border-top:1px solid var(--arcane-border);color:var(--arcane-muted);font-size:.85rem;margin:0;padding:var(--arcane-space-2) var(--arcane-space-3)}
25
+ @media(max-width:42rem){.toolbar{grid-template-columns:1fr}.history,.actions{justify-content:center}}
26
+ </style>
27
+ <section class="navigator arcane-card">
28
+ <div class="toolbar">
29
+ <div class="history">
30
+ <button id="back" class="arcane-button arcane-button--tertiary" type="button" aria-label="Back">←</button>
31
+ <button id="forward" class="arcane-button arcane-button--tertiary" type="button" aria-label="Forward">→</button>
32
+ <button id="home" class="arcane-button arcane-button--tertiary" type="button" aria-label="Home">⌂</button>
33
+ </div>
34
+ <form id="addressForm" class="address">
35
+ <label class="visually-hidden" for="address">Web address</label>
36
+ <input id="address" type="text" inputmode="url" autocomplete="off" spellcheck="false" placeholder="https://example.com">
37
+ <button class="arcane-button" type="submit">Go</button>
38
+ </form>
39
+ <div class="actions">
40
+ <button id="reload" class="arcane-button arcane-button--tertiary" type="button" aria-label="Reload">↻</button>
41
+ <button id="external" class="arcane-button arcane-button--secondary" type="button">Open externally</button>
42
+ </div>
43
+ </div>
44
+ <div class="viewport">
45
+ <iframe id="frame" title="Web content" referrerpolicy="strict-origin-when-cross-origin" sandbox="allow-forms allow-scripts"></iframe>
46
+ <section id="blocked" class="blocked" hidden tabindex="-1" aria-labelledby="blockedTitle">
47
+ <p class="blocked__eyebrow">Arcane global deny</p>
48
+ <h2 id="blockedTitle">Connection blocked</h2>
49
+ <p>Arcane stopped this outbound navigation before it sent a request.</p>
50
+ <code id="blockedTarget"></code>
51
+ <dl>
52
+ <div><dt>Reason</dt><dd id="blockedReason"></dd></div>
53
+ <div><dt>Source</dt><dd id="blockedSource"></dd></div>
54
+ <div><dt>Rule and decision</dt><dd id="blockedEvidence"></dd></div>
55
+ </dl>
56
+ <p class="blocked__boundary">Global deny rules override every app capability and cannot be bypassed here.</p>
57
+ </section>
58
+ </div>
59
+ <p id="status" class="status" role="status" aria-live="polite">Enter an address. Some sites block embedded viewing; use Open externally when needed.</p>
60
+ </section>
61
+ <script type="module">
62
+ const host=this;
63
+ const root=host.shadowRoot;
64
+ const address=root.querySelector('#address');
65
+ const frame=root.querySelector('#frame');
66
+ const blocked=root.querySelector('#blocked');
67
+ const status=root.querySelector('#status');
68
+ const back=root.querySelector('#back');
69
+ const forward=root.querySelector('#forward');
70
+ let homeUrl='https://example.com/';
71
+ let history=[];
72
+ let position=-1;
73
+ let navigationGuard=null;
74
+ let navigationSequence=0;
75
+
76
+ function normalize(value){
77
+ let text=String(value||'').trim();
78
+ if(!/^[a-z][a-z0-9+.-]*:/i.test(text))text=`https://${text}`;
79
+ const url=new URL(text);
80
+ if(!['http:','https:'].includes(url.protocol))throw new TypeError('Web addresses must use HTTP or HTTPS.');
81
+ return url.href;
82
+ }
83
+
84
+ function currentUrl(){return history[position]||'';}
85
+
86
+ function unavailableDecision(url,error){
87
+ return {
88
+ blocked:true,
89
+ decisionId:'policy-unavailable',
90
+ decidedAt:new Date().toISOString(),
91
+ policyGeneration:null,
92
+ ruleId:'policy-unavailable',
93
+ ruleType:'policy',
94
+ target:url,
95
+ matchedValue:new URL(url).hostname,
96
+ reason:{
97
+ title:'Navigation paused because policy is unavailable',
98
+ description:'Arcane could not verify the global deny policy, so it did not send this request.'
99
+ },
100
+ source:{
101
+ label:'Arcane policy safety boundary',
102
+ reference:error?.code||null
103
+ }
104
+ };
105
+ }
106
+
107
+ async function evaluate(url,intent){
108
+ if(!navigationGuard){
109
+ const error=new Error('Arcane navigation guard is unavailable.');
110
+ error.code='ARCANE_NAVIGATION_GUARD_UNAVAILABLE';
111
+ return unavailableDecision(url,error);
112
+ }
113
+ try{
114
+ const decision=await navigationGuard(url,{intent});
115
+ if(!decision||typeof decision!=='object'||typeof decision.blocked!=='boolean'){
116
+ throw new TypeError('Navigation policy returned an invalid decision.');
117
+ }
118
+ return decision;
119
+ }catch(error){
120
+ return unavailableDecision(url,error);
121
+ }
122
+ }
123
+
124
+ function updateButtons(){
125
+ back.disabled=position<=0;
126
+ forward.disabled=position<0||position>=history.length-1;
127
+ }
128
+
129
+ function recordHistory(url,record){
130
+ if(!record)return;
131
+ history=history.slice(0,position+1);
132
+ history.push(url);
133
+ position=history.length-1;
134
+ }
135
+
136
+ function showBlocked(url,decision){
137
+ frame.hidden=true;
138
+ frame.removeAttribute('src');
139
+ blocked.hidden=false;
140
+ root.querySelector('#blockedTarget').textContent=url;
141
+ root.querySelector('#blockedReason').textContent=`${decision.reason?.title||'Blocked by policy'} — ${decision.reason?.description||'No additional reason was provided.'}`;
142
+ root.querySelector('#blockedSource').textContent=[decision.source?.label,decision.source?.reference].filter(Boolean).join(' · ')||'Arcane global policy';
143
+ root.querySelector('#blockedEvidence').textContent=[decision.ruleId&&`Rule ${decision.ruleId}`,decision.policyGeneration&&`Policy generation ${decision.policyGeneration}`,decision.decisionId&&`Decision ${decision.decisionId}`,decision.decidedAt].filter(Boolean).join(' · ');
144
+ status.textContent='Blocked by the Arcane global deny policy.';
145
+ blocked.focus();
146
+ host.dispatchEvent(new CustomEvent('web-navigation-blocked',{bubbles:true,composed:true,detail:{url,decision}}));
147
+ }
148
+
149
+ function showFrame(url){
150
+ blocked.hidden=true;
151
+ frame.hidden=false;
152
+ frame.src=url;
153
+ status.textContent='Loading…';
154
+ host.dispatchEvent(new CustomEvent('web-navigate',{bubbles:true,composed:true,detail:{url}}));
155
+ }
156
+
157
+ async function navigate(value,{record=true}={}){
158
+ const sequence=++navigationSequence;
159
+ try{
160
+ const url=normalize(value);
161
+ address.value=url;
162
+ status.textContent='Checking the global deny policy…';
163
+ const decision=await evaluate(url,'embedded');
164
+ if(sequence!==navigationSequence)return'';
165
+ recordHistory(url,record);
166
+ updateButtons();
167
+ if(decision.blocked){
168
+ showBlocked(url,decision);
169
+ return'';
170
+ }
171
+ showFrame(url);
172
+ return url;
173
+ }catch(error){
174
+ if(sequence===navigationSequence)status.textContent=error.message;
175
+ return'';
176
+ }
177
+ }
178
+
179
+ async function openExternal(){
180
+ const sequence=++navigationSequence;
181
+ try{
182
+ const url=normalize(currentUrl()||address.value||homeUrl);
183
+ status.textContent='Checking the global deny policy…';
184
+ const decision=await evaluate(url,'external');
185
+ if(sequence!==navigationSequence)return;
186
+ if(decision.blocked){
187
+ showBlocked(url,decision);
188
+ return;
189
+ }
190
+ status.textContent='Handing the allowed address to the system browser…';
191
+ host.dispatchEvent(new CustomEvent('web-open-external',{bubbles:true,composed:true,detail:{url}}));
192
+ }catch(error){
193
+ if(sequence===navigationSequence)status.textContent=error.message;
194
+ }
195
+ }
196
+
197
+ function ownNavigation(operation){
198
+ operation.catch(function reportUnexpectedNavigationFailure(error){
199
+ status.textContent=error.message;
200
+ });
201
+ }
202
+
203
+ function move(amount){
204
+ const next=position+amount;
205
+ if(next<0||next>=history.length)return;
206
+ position=next;
207
+ ownNavigation(navigate(history[position],{record:false}));
208
+ }
209
+
210
+ function configure(options){
211
+ if(options?.homeUrl)homeUrl=normalize(options.homeUrl);
212
+ navigationGuard=typeof options?.navigationGuard==='function'?options.navigationGuard:null;
213
+ if(options?.initialUrl)ownNavigation(navigate(options.initialUrl));
214
+ else updateButtons();
215
+ return host;
216
+ }
217
+
218
+ function handleAddressSubmit(event){event.preventDefault();ownNavigation(navigate(address.value));}
219
+ function handleHomeClick(){ownNavigation(navigate(homeUrl));}
220
+ function handleReloadClick(){const current=currentUrl();if(current)ownNavigation(navigate(current,{record:false}));}
221
+ function handleExternalClick(){ownNavigation(openExternal());}
222
+ function handleBackClick(){move(-1);}
223
+ function handleForwardClick(){move(1);}
224
+ function handleFrameLoad(){if(blocked.hidden)status.textContent='Loaded. If the page is blank, its site does not permit embedded viewing.';}
225
+
226
+ host.configure=configure;
227
+ host.navigate=navigate;
228
+ host.currentUrl=currentUrl;
229
+ root.querySelector('#addressForm').addEventListener('submit',handleAddressSubmit);
230
+ root.querySelector('#home').addEventListener('click',handleHomeClick);
231
+ root.querySelector('#reload').addEventListener('click',handleReloadClick);
232
+ root.querySelector('#external').addEventListener('click',handleExternalClick);
233
+ back.addEventListener('click',handleBackClick);
234
+ forward.addEventListener('click',handleForwardClick);
235
+ frame.addEventListener('load',handleFrameLoad);
236
+ updateButtons();
237
+ host.ready=true;
238
+ host.dispatchEvent(new CustomEvent('web-navigator-ready',{bubbles:true,composed:true}));
239
+ </script>
@@ -0,0 +1 @@
1
+ :root{color-scheme:light dark;--background:#f4f6fb;--text-color:#172238;--primary-color:#172238;--secondary-color:#e5e9f3;--button-text-color:#fff;--border-color:#cbd3e2;--muted-text-color:#647084;--modal-background:#fff;--shadow-color:rgba(23,34,56,.15);--focus-color:#7657d5;--success-color:#26744d;--danger-color:#a53838;font:16px/1.5 system-ui,sans-serif;background:var(--background);color:var(--text-color)}@media(prefers-color-scheme:dark){:root:not([data-color-scheme="light"]){--background:#0e1420;--text-color:#eef2fb;--primary-color:#202c46;--secondary-color:#1a2437;--border-color:#394760;--muted-text-color:#aab4c8;--modal-background:#141d2c;--shadow-color:rgba(0,0,0,.4);--focus-color:#a98dff}}:root[data-color-scheme="dark"]{--background:#0e1420;--text-color:#eef2fb;--primary-color:#202c46;--secondary-color:#1a2437;--border-color:#394760;--muted-text-color:#aab4c8;--modal-background:#141d2c;--shadow-color:rgba(0,0,0,.4);--focus-color:#a98dff}*{box-sizing:border-box}body{margin:0;min-height:100vh;background:var(--background);color:var(--text-color)}body.modal-open{overflow:hidden}main{display:grid;gap:1rem;margin:auto;max-width:100rem;padding:clamp(.75rem,2vw,1.5rem)}.page-heading{align-items:end;display:flex;gap:1rem;justify-content:space-between}.page-heading h1{font-size:clamp(2rem,5vw,3.2rem);line-height:1;margin:0}.page-heading p{color:var(--muted-text-color);margin:.45rem 0 0}.heading-actions{align-items:center;display:flex;gap:.75rem}.app-status{white-space:nowrap}.app-status[data-tone="warning"]{color:#a46800}.app-status[data-tone="error"]{color:var(--danger-color)}.workspace{display:grid;grid-template-columns:minmax(18rem,24rem) minmax(0,1fr);min-height:34rem;overflow:hidden}.workspace>html-import{display:block;min-width:0}.workspace>html-import:first-child{border-right:1px solid var(--border-color)}.settings-panel{position:fixed;inset:0;z-index:20;overflow:auto;padding:clamp(1rem,5vw,4rem);background:rgba(5,10,18,.72);backdrop-filter:blur(.3rem)}.settings-panel>html-import{display:block;margin:auto;max-width:56rem}.settings-panel[hidden]{display:none}:root[data-density="compact"] main{padding:.75rem}:root[data-reduce-motion="true"] *{animation:none!important;scroll-behavior:auto!important;transition:none!important}@media(max-width:48rem){.workspace{grid-template-columns:1fr}.workspace>html-import:first-child{border-right:0;border-bottom:1px solid var(--border-color)}.page-heading{align-items:flex-start;flex-direction:column}.heading-actions{width:100%;justify-content:space-between}}
@@ -0,0 +1,45 @@
1
+ .chart-options{
2
+ display:grid;
3
+ gap:.75em;
4
+ grid-template-columns:repeat(auto-fit,minmax(16em,1fr));
5
+ }
6
+
7
+ .chart-option-group{
8
+ font-size:1em;
9
+ grid-column:1 / -1;
10
+ margin:.5em 0 0;
11
+ }
12
+
13
+ .chart-option{
14
+ align-items:flex-start;
15
+ border:1px solid var(--border-color);
16
+ border-radius:.5em;
17
+ display:grid;
18
+ gap:.25em .65em;
19
+ grid-template-columns:auto 1fr;
20
+ padding:.75em;
21
+ }
22
+
23
+ .chart-option input{
24
+ margin:.25em 0 0;
25
+ width:auto;
26
+ }
27
+
28
+ .chart-option h3,
29
+ .chart-option p{
30
+ grid-column:2;
31
+ margin:0;
32
+ }
33
+
34
+ .chart-option p{
35
+ font-size:.9em;
36
+ opacity:.75;
37
+ }
38
+
39
+ .chart-option.disabled{
40
+ opacity:.55;
41
+ }
42
+
43
+ .dashboard-config-empty{
44
+ opacity:.7;
45
+ }