noteconnection 1.6.8 → 1.8.0
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.
- package/LICENSE +674 -21
- package/README.md +258 -64
- package/dist/src/agent_workspace.contract.parity.test.js +475 -0
- package/dist/src/agent_workspace.frontend.test.js +9989 -0
- package/dist/src/agent_workspace.locale.contract.test.js +95 -0
- package/dist/src/agent_workspace.runtime.behavior.test.js +5072 -0
- package/dist/src/copy.assets.contract.test.js +130 -0
- package/dist/src/core/PathBridge.js +28 -3
- package/dist/src/export/WorkspaceExportBundle.js +1130 -0
- package/dist/src/export/WorkspaceExportBundle.test.js +1480 -0
- package/dist/src/export/index.js +18 -0
- package/dist/src/export/types.js +2 -0
- package/dist/src/fixrisk.issue.verifier.contract.test.js +3 -1
- package/dist/src/foundation.ann.runtime.contract.test.js +81 -0
- package/dist/src/foundation.release.evidence.contract.test.js +406 -0
- package/dist/src/foundation.sqlite.runtime.contract.test.js +82 -0
- package/dist/src/frontend/README.md +258 -64
- package/dist/src/frontend/agent_workspace.js +5353 -0
- package/dist/src/frontend/agent_workspace_runtime.js +4434 -0
- package/dist/src/frontend/analysis.js +31 -4
- package/dist/src/frontend/app.js +3597 -141
- package/dist/src/frontend/focus_mode_interactions.js +33 -0
- package/dist/src/frontend/godot_future_path_renderer.js +540 -0
- package/dist/src/frontend/godot_tree_interactions.js +178 -0
- package/dist/src/frontend/graph_state.mjs +105 -0
- package/dist/src/frontend/hosted_future_path_runtime.js +157 -0
- package/dist/src/frontend/i18n.mjs +186 -0
- package/dist/src/frontend/index.html +641 -266
- package/dist/src/frontend/layout_gpu.js +12 -4
- package/dist/src/frontend/locales/en.json +721 -5
- package/dist/src/frontend/locales/zh.json +721 -5
- package/dist/src/frontend/main.mjs +60 -0
- package/dist/src/frontend/markdown_runtime.js +827 -0
- package/dist/src/frontend/notemd.css +49 -0
- package/dist/src/frontend/notemd.html +7 -1
- package/dist/src/frontend/notemd.js +64 -0
- package/dist/src/frontend/path.html +107 -0
- package/dist/src/frontend/path_app.js +2189 -150
- package/dist/src/frontend/path_layout.mjs +143 -0
- package/dist/src/frontend/path_mermaid_utils.mjs +108 -0
- package/dist/src/frontend/path_modules_bridge.js +486 -0
- package/dist/src/frontend/path_state.mjs +118 -0
- package/dist/src/frontend/path_styles.css +146 -0
- package/dist/src/frontend/path_worker_bridge.mjs +85 -0
- package/dist/src/frontend/reader.js +522 -27
- package/dist/src/frontend/runtime_bridge.js +67 -54
- package/dist/src/frontend/runtime_bridge.mjs +279 -0
- package/dist/src/frontend/settings.js +130 -12
- package/dist/src/frontend/simulationWorker.js +241 -6
- package/dist/src/frontend/source_manager.js +190 -21
- package/dist/src/frontend/styles.css +2853 -72
- package/dist/src/frontend/workbench_state.mjs +101 -0
- package/dist/src/frontend/workspace_panes.js +10168 -0
- package/dist/src/frontend.locale.contract.test.js +62 -0
- package/dist/src/godot.sidecar.bootstrap.contract.test.js +244 -0
- package/dist/src/indexing/IndexLifecycle.js +195 -0
- package/dist/src/indexing/IndexLifecycle.test.js +49 -0
- package/dist/src/indexing/SegmentBuilder.js +64 -0
- package/dist/src/indexing/UnitBuilder.js +48 -0
- package/dist/src/indexing/types.js +2 -0
- package/dist/src/knowledge.api.contract.test.js +170 -0
- package/dist/src/learning/KnowledgeLearningPlatform.js +10386 -0
- package/dist/src/learning/KnowledgeLearningPlatform.persistence.test.js +327 -0
- package/dist/src/learning/KnowledgeLearningPlatform.program-f.test.js +99 -0
- package/dist/src/learning/KnowledgeLearningPlatform.test.js +2971 -0
- package/dist/src/learning/KnowledgeWorkspaceConversationRegression.js +2974 -0
- package/dist/src/learning/KnowledgeWorkspaceConversationRegression.test.js +3928 -0
- package/dist/src/learning/answerReleaseReview.js +4319 -0
- package/dist/src/learning/answerReleaseReview.test.js +2888 -0
- package/dist/src/learning/api.js +2 -0
- package/dist/src/learning/conversationComposer.js +1480 -0
- package/dist/src/learning/conversationComposer.test.js +1817 -0
- package/dist/src/learning/domains/ConversationManager.js +53 -0
- package/dist/src/learning/domains/KnowledgeIngestor.js +238 -0
- package/dist/src/learning/domains/KnowledgeQuerier.js +187 -0
- package/dist/src/learning/domains/MasteryEngine.js +387 -0
- package/dist/src/learning/domains/MemoryPolicyManager.js +408 -0
- package/dist/src/learning/domains/QualityEvaluator.js +307 -0
- package/dist/src/learning/domains/TutorRouter.js +313 -0
- package/dist/src/learning/domains/index.js +33 -0
- package/dist/src/learning/domains/types.js +7 -0
- package/dist/src/learning/errors.js +29 -0
- package/dist/src/learning/evidenceContextAssembler.js +1176 -0
- package/dist/src/learning/evidenceContextAssembler.test.js +6332 -0
- package/dist/src/learning/graphContextAssembler.js +870 -0
- package/dist/src/learning/graphContextAssembler.test.js +1033 -0
- package/dist/src/learning/index.js +28 -0
- package/dist/src/learning/queryBackend.js +1898 -0
- package/dist/src/learning/queryBackend.test.js +955 -0
- package/dist/src/learning/ragContextPack.js +257 -0
- package/dist/src/learning/ragContextPack.test.js +160 -0
- package/dist/src/learning/ragPublicText.js +38 -0
- package/dist/src/learning/ragSufficiencyJudge.js +161 -0
- package/dist/src/learning/ragSufficiencyJudge.test.js +177 -0
- package/dist/src/learning/ragSufficiencyProviderJudge.js +227 -0
- package/dist/src/learning/ragSufficiencyProviderJudge.test.js +156 -0
- package/dist/src/learning/requestNormalization.js +198 -0
- package/dist/src/learning/runtimeCapability.js +4677 -0
- package/dist/src/learning/runtimeCapability.test.js +3635 -0
- package/dist/src/learning/store.js +1240 -0
- package/dist/src/learning/store.test.js +1126 -0
- package/dist/src/learning/tutorAdapter.js +2 -0
- package/dist/src/learning/types.js +2 -0
- package/dist/src/learning/vectorAccelerationAdapter.js +942 -0
- package/dist/src/learning/vectorAccelerationAdapter.test.js +382 -0
- package/dist/src/lfs.asset.policy.contract.test.js +153 -0
- package/dist/src/license.policy.contract.test.js +66 -0
- package/dist/src/memory/MemoryGovernance.js +74 -0
- package/dist/src/memory/MemoryGovernance.test.js +46 -0
- package/dist/src/memory/types.js +2 -0
- package/dist/src/mermaid.frontend.guard.contract.test.js +77 -0
- package/dist/src/middleware/auth.js +17 -0
- package/dist/src/middleware/body-parser.js +45 -0
- package/dist/src/middleware/cors.js +44 -0
- package/dist/src/middleware/index.js +21 -0
- package/dist/src/middleware/request-trace.js +96 -0
- package/dist/src/notemd/AppConfigToml.js +6 -4
- package/dist/src/notemd/MermaidProcessor.js +400 -50
- package/dist/src/notemd/NotemdService.js +498 -13
- package/dist/src/notemd/PromptManager.js +15 -0
- package/dist/src/notemd/cli/commands.js +357 -0
- package/dist/src/notemd/cli/dispatcher.js +225 -0
- package/dist/src/notemd/cli/index.js +169 -0
- package/dist/src/notemd/cli/parser.js +68 -0
- package/dist/src/notemd/cli/types.js +2 -0
- package/dist/src/notemd/constants.js +43 -0
- package/dist/src/notemd/diagram/diagramGenerationService.js +78 -0
- package/dist/src/notemd/diagram/diagramSpec.js +79 -0
- package/dist/src/notemd/diagram/diagramSpecResponseParser.js +131 -0
- package/dist/src/notemd/diagram/intent.js +95 -0
- package/dist/src/notemd/diagram/planner.js +71 -0
- package/dist/src/notemd/diagram/prompts/diagramSpecPrompt.js +42 -0
- package/dist/src/notemd/diagram/types.js +18 -0
- package/dist/src/notemd/index.js +26 -0
- package/dist/src/notemd/operations/capabilityManifest.js +23 -0
- package/dist/src/notemd/operations/cliContracts.js +17 -0
- package/dist/src/notemd/operations/configProfileCommands.js +85 -0
- package/dist/src/notemd/operations/registry.contract.test.js +95 -0
- package/dist/src/notemd/operations/registry.js +991 -0
- package/dist/src/notemd/operations/types.js +2 -0
- package/dist/src/notemd/providerDiagnostics.js +220 -0
- package/dist/src/notemd/providerProfiles.js +42 -0
- package/dist/src/notemd/providerTemplates.js +231 -0
- package/dist/src/notemd/search/DuckDuckGoProvider.js +39 -0
- package/dist/src/notemd/search/SearchManager.js +13 -0
- package/dist/src/notemd/search/SearchProvider.js +2 -0
- package/dist/src/notemd/search/TavilyProvider.js +44 -0
- package/dist/src/notemd.agent.manifest.test.js +85 -0
- package/dist/src/notemd.api.contract.test.js +14 -1
- package/dist/src/notemd.app_config_toml.test.js +2 -1
- package/dist/src/notemd.batch.workflow.test.js +117 -0
- package/dist/src/notemd.cli.e2e.test.js +136 -0
- package/dist/src/notemd.core.test.js +51 -0
- package/dist/src/notemd.diagram.pipeline.test.js +233 -0
- package/dist/src/notemd.providerTemplates.test.js +34 -0
- package/dist/src/notemd.server.integration.test.js +143 -35
- package/dist/src/notemd.workflow.pipeline.test.js +162 -0
- package/dist/src/pathbridge.handshake.contract.test.js +16 -2
- package/dist/src/pathmode.background.contract.test.js +69 -0
- package/dist/src/pathmode.settings.api.contract.test.js +9 -0
- package/dist/src/pkg.sidecar.contract.test.js +9 -3
- package/dist/src/platform/ExportProfile.js +58 -0
- package/dist/src/platform/PlatformCapabilities.js +45 -0
- package/dist/src/platform/PlatformCapabilities.test.js +30 -0
- package/dist/src/platform/RenderMaterializer.js +33 -0
- package/dist/src/platform/RenderMaterializer.test.js +32 -0
- package/dist/src/query_backend.external_http.integration.test.js +410 -0
- package/dist/src/reader_renderer.js +404 -3
- package/dist/src/reader_renderer.test.js +87 -0
- package/dist/src/release.godot.mirror.contract.test.js +73 -0
- package/dist/src/resources/ResourceRegistry.js +223 -0
- package/dist/src/resources/ResourceRegistry.test.js +61 -0
- package/dist/src/resources/types.js +2 -0
- package/dist/src/routes/agentWorkspaceDiagnostics.js +173 -0
- package/dist/src/routes/data.js +267 -0
- package/dist/src/routes/diagnostics.js +51 -0
- package/dist/src/routes/index.js +23 -0
- package/dist/src/routes/knowledge.js +968 -0
- package/dist/src/routes/markdown.js +287 -0
- package/dist/src/routes/notemd.js +565 -0
- package/dist/src/routes/registry.contract.test.js +130 -0
- package/dist/src/routes/render.js +285 -0
- package/dist/src/routes/runtimeRunbookRouteOps.js +149 -0
- package/dist/src/routes/runtimeRunbookRouteOps.test.js +194 -0
- package/dist/src/routes/settings.js +6 -0
- package/dist/src/routes/staticFiles.js +94 -0
- package/dist/src/routes/types.js +2 -0
- package/dist/src/runtime.transport.adapter.contract.test.js +81 -0
- package/dist/src/server.js +11090 -1549
- package/dist/src/server.migration.test.js +193 -21
- package/dist/src/server.port.fallback.contract.test.js +63 -0
- package/dist/src/session/SessionStateStore.js +81 -0
- package/dist/src/session/SessionStateStore.test.js +58 -0
- package/dist/src/session/types.js +2 -0
- package/dist/src/settings.runtime.contract.test.js +50 -0
- package/dist/src/shared/types.contract.test.js +107 -0
- package/dist/src/shared/types.js +22 -0
- package/dist/src/sidecar.replacement.boundary.contract.test.js +128 -0
- package/dist/src/sidecar.supply.readiness.contract.test.js +144 -0
- package/dist/src/source_manager.loadflow.test.js +46 -0
- package/dist/src/startup.layout.snapshot.contract.test.js +57 -0
- package/dist/src/tauri.frontend.build.contract.test.js +60 -0
- package/dist/src/tauri.sidecar.cleanup.contract.test.js +21 -0
- package/dist/src/utils/RuntimePaths.js +4 -13
- package/dist/src/utils/platform.js +153 -0
- package/dist/src/workflows/WorkflowArtifactStore.js +96 -0
- package/dist/src/workflows/WorkflowArtifactStore.test.js +80 -0
- package/dist/src/workflows/types.js +2 -0
- package/dist/src/workspace/WorkspaceRegistry.js +122 -0
- package/dist/src/workspace/WorkspaceRegistry.test.js +29 -0
- package/dist/src/workspace/types.js +2 -0
- package/package.json +61 -10
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
(function () {
|
|
2
|
+
const CLICK_DRAG_THRESHOLD = 6;
|
|
3
|
+
const LONG_PRESS_DURATION_MS = 650;
|
|
4
|
+
|
|
5
|
+
function normalizeText(value) {
|
|
6
|
+
return String(value == null ? '' : value).replace(/\s+/g, ' ').trim();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function closestNode(target) {
|
|
10
|
+
return target && typeof target.closest === 'function'
|
|
11
|
+
? target.closest('[data-godot-tree-node-id], [data-agent-future-path-node-id]')
|
|
12
|
+
: null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function readNodeId(nodeElement) {
|
|
16
|
+
return normalizeText(
|
|
17
|
+
nodeElement
|
|
18
|
+
&& (
|
|
19
|
+
nodeElement.getAttribute('data-agent-future-path-node-id')
|
|
20
|
+
|| nodeElement.getAttribute('data-godot-tree-node-id')
|
|
21
|
+
)
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function isSpineNode(nodeElement) {
|
|
26
|
+
return nodeElement && (
|
|
27
|
+
nodeElement.getAttribute('data-agent-future-path-node-spine') === 'true'
|
|
28
|
+
|| nodeElement.getAttribute('data-godot-tree-node-spine') === 'true'
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function isExpandedNode(nodeElement) {
|
|
33
|
+
return nodeElement && (
|
|
34
|
+
nodeElement.getAttribute('data-agent-future-path-node-expanded') === 'true'
|
|
35
|
+
|| nodeElement.getAttribute('data-godot-tree-node-expanded') === 'true'
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function canTogglePrerequisites(nodeElement) {
|
|
40
|
+
return isSpineNode(nodeElement);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function emit(callbacks, name, nodeId, event) {
|
|
44
|
+
const callback = callbacks && callbacks[name];
|
|
45
|
+
if (typeof callback !== 'function') {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
callback(nodeId, event);
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function emitExpansionSignal(nodeElement, callbacks, event) {
|
|
53
|
+
if (!canTogglePrerequisites(nodeElement)) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
const nodeId = readNodeId(nodeElement);
|
|
57
|
+
if (!nodeId) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
return isExpandedNode(nodeElement)
|
|
61
|
+
? emit(callbacks, 'nodeCollapsePrereqsRequested', nodeId, event)
|
|
62
|
+
: emit(callbacks, 'nodeExpandPrereqsRequested', nodeId, event);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function bindTreeRenderer(root, callbacks) {
|
|
66
|
+
if (!root || typeof root.querySelectorAll !== 'function') {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
let longPressState = null;
|
|
70
|
+
let longPressTimer = null;
|
|
71
|
+
let suppressClickNodeId = '';
|
|
72
|
+
|
|
73
|
+
const clearLongPress = function () {
|
|
74
|
+
if (longPressTimer) {
|
|
75
|
+
clearTimeout(longPressTimer);
|
|
76
|
+
longPressTimer = null;
|
|
77
|
+
}
|
|
78
|
+
longPressState = null;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
root.querySelectorAll('[data-godot-tree-node-id], [data-agent-future-path-node-id]').forEach((nodeElement) => {
|
|
82
|
+
nodeElement.addEventListener('mousedown', function (event) {
|
|
83
|
+
if (event.button !== 0) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const nodeId = readNodeId(nodeElement);
|
|
87
|
+
if (!nodeId) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
clearLongPress();
|
|
91
|
+
longPressState = {
|
|
92
|
+
nodeId,
|
|
93
|
+
clientX: Number(event.clientX) || 0,
|
|
94
|
+
clientY: Number(event.clientY) || 0,
|
|
95
|
+
};
|
|
96
|
+
longPressTimer = setTimeout(function () {
|
|
97
|
+
if (!longPressState || longPressState.nodeId !== nodeId) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
suppressClickNodeId = nodeId;
|
|
101
|
+
emit(callbacks, 'nodeNavigateRequested', nodeId, event);
|
|
102
|
+
clearLongPress();
|
|
103
|
+
}, LONG_PRESS_DURATION_MS);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
nodeElement.addEventListener('mouseup', function (event) {
|
|
107
|
+
if (!longPressState) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const dx = (Number(event.clientX) || 0) - longPressState.clientX;
|
|
111
|
+
const dy = (Number(event.clientY) || 0) - longPressState.clientY;
|
|
112
|
+
if (Math.sqrt((dx * dx) + (dy * dy)) > CLICK_DRAG_THRESHOLD) {
|
|
113
|
+
clearLongPress();
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
clearLongPress();
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
nodeElement.addEventListener('click', function (event) {
|
|
120
|
+
const nodeId = readNodeId(nodeElement);
|
|
121
|
+
if (!nodeId || event.detail > 1) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (suppressClickNodeId === nodeId) {
|
|
125
|
+
suppressClickNodeId = '';
|
|
126
|
+
event.preventDefault();
|
|
127
|
+
event.stopPropagation();
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
emit(callbacks, 'nodeClicked', nodeId, event);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
nodeElement.addEventListener('dblclick', function (event) {
|
|
134
|
+
event.preventDefault();
|
|
135
|
+
event.stopPropagation();
|
|
136
|
+
clearLongPress();
|
|
137
|
+
if (emit(callbacks, 'nodeReaderRequested', readNodeId(nodeElement), event)) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
emitExpansionSignal(nodeElement, callbacks, event);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
nodeElement.addEventListener('contextmenu', function (event) {
|
|
144
|
+
event.preventDefault();
|
|
145
|
+
event.stopPropagation();
|
|
146
|
+
clearLongPress();
|
|
147
|
+
emitExpansionSignal(nodeElement, callbacks, event);
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
const viewport = root.querySelector('[data-godot-tree-viewport="true"]') || root;
|
|
152
|
+
viewport.addEventListener('mousedown', function (event) {
|
|
153
|
+
if (event.button !== 1) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
event.preventDefault();
|
|
157
|
+
event.stopPropagation();
|
|
158
|
+
clearLongPress();
|
|
159
|
+
const nodeElement = closestNode(event.target);
|
|
160
|
+
if (nodeElement) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
emit(callbacks, 'collapseAllRequested', '', event);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
window.NoteConnectionGodotTreeInteractions = {
|
|
168
|
+
bindTreeRenderer,
|
|
169
|
+
resolveExpansionSignal: function (nodeElement) {
|
|
170
|
+
if (!canTogglePrerequisites(nodeElement)) {
|
|
171
|
+
return '';
|
|
172
|
+
}
|
|
173
|
+
return isExpandedNode(nodeElement)
|
|
174
|
+
? 'node_collapse_prereqs_requested'
|
|
175
|
+
: 'node_expand_prereqs_requested';
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
}());
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* graph_state.mjs — Extracted graph visualization state management.
|
|
3
|
+
* Manages focus mode, layout mode, semantic accessibility, and platform detection.
|
|
4
|
+
* Formerly inline in app.js.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** Resolve the runtime platform from capabilities, navigator, and Capacitor. */
|
|
8
|
+
export function resolveRuntimePlatform(runtimeCaps) {
|
|
9
|
+
const rawPlatform = runtimeCaps && typeof runtimeCaps.platform === 'string'
|
|
10
|
+
? runtimeCaps.platform.trim().toLowerCase()
|
|
11
|
+
: '';
|
|
12
|
+
|
|
13
|
+
if (rawPlatform.includes('android')) return 'android';
|
|
14
|
+
if (rawPlatform.includes('ios')) return 'ios';
|
|
15
|
+
if (rawPlatform.includes('windows') || rawPlatform === 'win32') return 'windows';
|
|
16
|
+
if (rawPlatform.includes('macos') || rawPlatform.includes('darwin') || rawPlatform === 'mac') return 'macos';
|
|
17
|
+
if (rawPlatform.includes('linux')) return 'linux';
|
|
18
|
+
if (rawPlatform.includes('web')) return 'web';
|
|
19
|
+
|
|
20
|
+
if (typeof navigator !== 'undefined' && typeof navigator.userAgent === 'string') {
|
|
21
|
+
const ua = navigator.userAgent;
|
|
22
|
+
if (/Android/i.test(ua)) return 'android';
|
|
23
|
+
if (/iPhone|iPad|iPod/i.test(ua)) return 'ios';
|
|
24
|
+
if (/Windows/i.test(ua)) return 'windows';
|
|
25
|
+
if (/Macintosh|Mac OS X/i.test(ua)) return 'macos';
|
|
26
|
+
if (/Linux/i.test(ua)) return 'linux';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (typeof window !== 'undefined' && window.Capacitor && typeof window.Capacitor.getPlatform === 'function') {
|
|
30
|
+
try {
|
|
31
|
+
const capPlatform = String(window.Capacitor.getPlatform() || '').toLowerCase();
|
|
32
|
+
if (capPlatform === 'android') return 'android';
|
|
33
|
+
if (capPlatform === 'ios') return 'ios';
|
|
34
|
+
if (capPlatform === 'web') return 'web';
|
|
35
|
+
} catch (_err) { /* ignore */ }
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return 'web';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Create the graph semantic accessibility state. */
|
|
42
|
+
export function createGraphA11yState() {
|
|
43
|
+
return {
|
|
44
|
+
lastSummaryKey: '',
|
|
45
|
+
lastAnnouncementAt: 0,
|
|
46
|
+
pendingReason: '',
|
|
47
|
+
pendingTimer: null,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Focus mode state for the graph visualization. */
|
|
52
|
+
export function createFocusState() {
|
|
53
|
+
return {
|
|
54
|
+
nodeId: null,
|
|
55
|
+
frozen: false,
|
|
56
|
+
verticalSpacing: 120,
|
|
57
|
+
horizontalSpacing: 180,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Layout mode for the graph. */
|
|
62
|
+
export const LAYOUT_MODES = {
|
|
63
|
+
FORCE: 'force',
|
|
64
|
+
DAG: 'dag',
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/** Read the startup performance profile override from localStorage. */
|
|
68
|
+
export function readStartupPerfProfile() {
|
|
69
|
+
if (typeof localStorage === 'undefined') return '';
|
|
70
|
+
try {
|
|
71
|
+
const value = localStorage.getItem('nc.startupPerfProfile');
|
|
72
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
73
|
+
} catch (_err) {
|
|
74
|
+
return '';
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Get the rendering engine preference. */
|
|
79
|
+
export function getRenderEnginePreference(nodeCount) {
|
|
80
|
+
// Auto-switch to Canvas above 3000 nodes
|
|
81
|
+
const savedPref = typeof localStorage !== 'undefined'
|
|
82
|
+
? localStorage.getItem('nc.renderEngine')
|
|
83
|
+
: null;
|
|
84
|
+
if (savedPref === 'svg' || savedPref === 'canvas') return savedPref;
|
|
85
|
+
return nodeCount > 3000 ? 'canvas' : 'svg';
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Performance timestamp helper. */
|
|
89
|
+
export function nowMs() {
|
|
90
|
+
return (typeof performance !== 'undefined' && typeof performance.now === 'function')
|
|
91
|
+
? performance.now()
|
|
92
|
+
: Date.now();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Build a diagnostic summary of the graph state. */
|
|
96
|
+
export function getGraphDiagnostics(state) {
|
|
97
|
+
return {
|
|
98
|
+
layoutMode: state.layoutMode || 'force',
|
|
99
|
+
renderEngine: state.renderEngine || 'svg',
|
|
100
|
+
focusNodeId: state.focusNodeId || null,
|
|
101
|
+
nodeCount: state.nodes ? state.nodes.length : 0,
|
|
102
|
+
edgeCount: state.edges ? state.edges.length : 0,
|
|
103
|
+
platform: state.platform || 'unknown',
|
|
104
|
+
};
|
|
105
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
(function () {
|
|
2
|
+
function getNow() {
|
|
3
|
+
if (typeof performance !== 'undefined' && performance && typeof performance.now === 'function') {
|
|
4
|
+
return performance.now();
|
|
5
|
+
}
|
|
6
|
+
return Date.now();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function cloneDiagnostics(source) {
|
|
10
|
+
if (!source || typeof source !== 'object') {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
return JSON.parse(JSON.stringify(source));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function createRuntimeCacheManager(options) {
|
|
17
|
+
const createRuntime = options && typeof options.createRuntime === 'function'
|
|
18
|
+
? options.createRuntime
|
|
19
|
+
: null;
|
|
20
|
+
const buildSignature = options && typeof options.buildSignature === 'function'
|
|
21
|
+
? options.buildSignature
|
|
22
|
+
: null;
|
|
23
|
+
const readStats = options && typeof options.readStats === 'function'
|
|
24
|
+
? options.readStats
|
|
25
|
+
: null;
|
|
26
|
+
const label = options && typeof options.label === 'string'
|
|
27
|
+
? options.label.trim()
|
|
28
|
+
: 'hosted-future-path-runtime';
|
|
29
|
+
let cacheEntry = null;
|
|
30
|
+
let lastDiagnostics = null;
|
|
31
|
+
const aggregate = {
|
|
32
|
+
cacheHitCount: 0,
|
|
33
|
+
cacheMissCount: 0,
|
|
34
|
+
runtimeBuildCount: 0,
|
|
35
|
+
lastCacheState: 'empty',
|
|
36
|
+
lastSignature: '',
|
|
37
|
+
lastResolveMs: 0,
|
|
38
|
+
lastBuildMs: 0,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
function buildDiagnosticsBase(sourceData, signature) {
|
|
42
|
+
const stats = readStats ? readStats(sourceData) : {};
|
|
43
|
+
return {
|
|
44
|
+
cacheLabel: label,
|
|
45
|
+
signature: String(signature || ''),
|
|
46
|
+
sourceNodeCount: Number.isFinite(Number(stats && stats.nodeCount))
|
|
47
|
+
? Number(stats.nodeCount)
|
|
48
|
+
: 0,
|
|
49
|
+
sourceEdgeCount: Number.isFinite(Number(stats && stats.edgeCount))
|
|
50
|
+
? Number(stats.edgeCount)
|
|
51
|
+
: 0,
|
|
52
|
+
cacheHit: false,
|
|
53
|
+
cacheMiss: false,
|
|
54
|
+
cacheState: cacheEntry ? 'warm' : 'cold',
|
|
55
|
+
runtimeBuildCount: Number(aggregate.runtimeBuildCount || 0),
|
|
56
|
+
cacheHitCount: Number(aggregate.cacheHitCount || 0),
|
|
57
|
+
cacheMissCount: Number(aggregate.cacheMissCount || 0),
|
|
58
|
+
resolveMs: 0,
|
|
59
|
+
buildMs: 0,
|
|
60
|
+
reason: '',
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
resolve: function (sourceData) {
|
|
66
|
+
const resolveStartedAt = getNow();
|
|
67
|
+
const signature = buildSignature ? buildSignature(sourceData) : '';
|
|
68
|
+
const diagnostics = buildDiagnosticsBase(sourceData, signature);
|
|
69
|
+
if (
|
|
70
|
+
cacheEntry
|
|
71
|
+
&& cacheEntry.sourceData === sourceData
|
|
72
|
+
&& cacheEntry.signature === signature
|
|
73
|
+
) {
|
|
74
|
+
aggregate.cacheHitCount += 1;
|
|
75
|
+
aggregate.lastCacheState = 'hit';
|
|
76
|
+
diagnostics.cacheHit = true;
|
|
77
|
+
diagnostics.cacheState = 'hit';
|
|
78
|
+
diagnostics.cacheHitCount = Number(aggregate.cacheHitCount || 0);
|
|
79
|
+
diagnostics.cacheMissCount = Number(aggregate.cacheMissCount || 0);
|
|
80
|
+
diagnostics.runtimeBuildCount = Number(aggregate.runtimeBuildCount || 0);
|
|
81
|
+
diagnostics.resolveMs = Number((getNow() - resolveStartedAt).toFixed(3));
|
|
82
|
+
diagnostics.buildMs = 0;
|
|
83
|
+
diagnostics.reason = 'runtime_reused';
|
|
84
|
+
aggregate.lastResolveMs = diagnostics.resolveMs;
|
|
85
|
+
aggregate.lastBuildMs = 0;
|
|
86
|
+
aggregate.lastSignature = diagnostics.signature;
|
|
87
|
+
lastDiagnostics = diagnostics;
|
|
88
|
+
return {
|
|
89
|
+
runtime: cacheEntry.runtime,
|
|
90
|
+
diagnostics: cloneDiagnostics(diagnostics),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
aggregate.cacheMissCount += 1;
|
|
95
|
+
aggregate.lastCacheState = cacheEntry ? 'miss_rebuild' : 'miss_cold';
|
|
96
|
+
diagnostics.cacheMiss = true;
|
|
97
|
+
diagnostics.cacheState = cacheEntry ? 'miss_rebuild' : 'miss_cold';
|
|
98
|
+
diagnostics.cacheHitCount = Number(aggregate.cacheHitCount || 0);
|
|
99
|
+
diagnostics.cacheMissCount = Number(aggregate.cacheMissCount || 0);
|
|
100
|
+
|
|
101
|
+
const buildStartedAt = getNow();
|
|
102
|
+
const runtime = createRuntime ? createRuntime(sourceData) : null;
|
|
103
|
+
diagnostics.buildMs = Number((getNow() - buildStartedAt).toFixed(3));
|
|
104
|
+
diagnostics.resolveMs = Number((getNow() - resolveStartedAt).toFixed(3));
|
|
105
|
+
aggregate.lastResolveMs = diagnostics.resolveMs;
|
|
106
|
+
aggregate.lastBuildMs = diagnostics.buildMs;
|
|
107
|
+
aggregate.lastSignature = diagnostics.signature;
|
|
108
|
+
if (runtime) {
|
|
109
|
+
aggregate.runtimeBuildCount += 1;
|
|
110
|
+
diagnostics.runtimeBuildCount = Number(aggregate.runtimeBuildCount || 0);
|
|
111
|
+
cacheEntry = {
|
|
112
|
+
sourceData,
|
|
113
|
+
signature,
|
|
114
|
+
runtime,
|
|
115
|
+
};
|
|
116
|
+
diagnostics.reason = cacheEntry && cacheEntry.runtime ? 'runtime_ready' : '';
|
|
117
|
+
} else {
|
|
118
|
+
diagnostics.runtimeBuildCount = Number(aggregate.runtimeBuildCount || 0);
|
|
119
|
+
diagnostics.reason = 'runtime_unavailable';
|
|
120
|
+
cacheEntry = null;
|
|
121
|
+
}
|
|
122
|
+
lastDiagnostics = diagnostics;
|
|
123
|
+
return {
|
|
124
|
+
runtime,
|
|
125
|
+
diagnostics: cloneDiagnostics(diagnostics),
|
|
126
|
+
};
|
|
127
|
+
},
|
|
128
|
+
clear: function () {
|
|
129
|
+
cacheEntry = null;
|
|
130
|
+
aggregate.lastCacheState = 'cleared';
|
|
131
|
+
aggregate.lastSignature = '';
|
|
132
|
+
aggregate.lastResolveMs = 0;
|
|
133
|
+
aggregate.lastBuildMs = 0;
|
|
134
|
+
lastDiagnostics = null;
|
|
135
|
+
},
|
|
136
|
+
getDiagnostics: function () {
|
|
137
|
+
return cloneDiagnostics(lastDiagnostics);
|
|
138
|
+
},
|
|
139
|
+
getAggregateSnapshot: function () {
|
|
140
|
+
return cloneDiagnostics({
|
|
141
|
+
cacheLabel: label,
|
|
142
|
+
cacheHitCount: Number(aggregate.cacheHitCount || 0),
|
|
143
|
+
cacheMissCount: Number(aggregate.cacheMissCount || 0),
|
|
144
|
+
runtimeBuildCount: Number(aggregate.runtimeBuildCount || 0),
|
|
145
|
+
lastCacheState: String(aggregate.lastCacheState || ''),
|
|
146
|
+
lastSignature: String(aggregate.lastSignature || ''),
|
|
147
|
+
lastResolveMs: Number(aggregate.lastResolveMs || 0),
|
|
148
|
+
lastBuildMs: Number(aggregate.lastBuildMs || 0),
|
|
149
|
+
});
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
window.NoteConnectionHostedFuturePathRuntime = {
|
|
155
|
+
createRuntimeCacheManager,
|
|
156
|
+
};
|
|
157
|
+
}());
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* i18n.mjs - ES Module version of Internationalization Manager
|
|
3
|
+
* Replaces window.i18n global with proper module exports.
|
|
4
|
+
* A thin backward-compat shim in i18n.js re-exports through window for legacy code.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
class I18nManager {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.tauriSyncStorageKey = 'nc_tauri_lang_synced';
|
|
10
|
+
this.currentLanguage = 'en';
|
|
11
|
+
this.translations = {};
|
|
12
|
+
this.fallbackLanguage = 'en';
|
|
13
|
+
this.supportedLanguages = ['en', 'zh'];
|
|
14
|
+
this.listeners = [];
|
|
15
|
+
this.isInitialized = false;
|
|
16
|
+
this.lastSyncedLanguage = null;
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
this.lastSyncedLanguage = sessionStorage.getItem(this.tauriSyncStorageKey);
|
|
20
|
+
} catch (_e) {
|
|
21
|
+
this.lastSyncedLanguage = null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async init() {
|
|
26
|
+
const savedLang = localStorage.getItem('user_language');
|
|
27
|
+
let tauriLang = null;
|
|
28
|
+
|
|
29
|
+
if (window.__TAURI__) {
|
|
30
|
+
try {
|
|
31
|
+
tauriLang = await window.__TAURI__.core.invoke('get_user_language');
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.warn('[i18n] Failed to read language from Tauri backend:', error);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let detectedLang = savedLang || tauriLang || this.detectBrowserLanguage() || 'en';
|
|
38
|
+
|
|
39
|
+
if (!this.supportedLanguages.includes(detectedLang)) {
|
|
40
|
+
detectedLang = this.fallbackLanguage;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
await this.setLanguage(detectedLang);
|
|
44
|
+
console.log(`[i18n] Initialized with language: ${this.currentLanguage}`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
detectBrowserLanguage() {
|
|
48
|
+
const browserLang = navigator.language || navigator.userLanguage;
|
|
49
|
+
if (!browserLang) return null;
|
|
50
|
+
const langCode = browserLang.split('-')[0].toLowerCase();
|
|
51
|
+
return this.supportedLanguages.includes(langCode) ? langCode : null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async setLanguage(lang) {
|
|
55
|
+
if (!this.supportedLanguages.includes(lang)) {
|
|
56
|
+
console.warn(`[i18n] Unsupported language: ${lang}, falling back to ${this.fallbackLanguage}`);
|
|
57
|
+
lang = this.fallbackLanguage;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (this.isInitialized && this.currentLanguage === lang) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
const response = await fetch(`locales/${lang}.json`);
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
throw new Error(`Failed to load locale file: ${lang}.json`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
this.translations = await response.json();
|
|
71
|
+
this.currentLanguage = lang;
|
|
72
|
+
localStorage.setItem('user_language', lang);
|
|
73
|
+
this.isInitialized = true;
|
|
74
|
+
this.notifyListeners(lang);
|
|
75
|
+
|
|
76
|
+
if (window.__TAURI__) {
|
|
77
|
+
let syncedInSession = null;
|
|
78
|
+
try { syncedInSession = sessionStorage.getItem(this.tauriSyncStorageKey); } catch (_e) {}
|
|
79
|
+
|
|
80
|
+
if (this.lastSyncedLanguage !== lang && syncedInSession !== lang) {
|
|
81
|
+
await window.__TAURI__.core.invoke('set_user_language', { lang });
|
|
82
|
+
this.lastSyncedLanguage = lang;
|
|
83
|
+
try { sessionStorage.setItem(this.tauriSyncStorageKey, lang); } catch (_e) {}
|
|
84
|
+
} else {
|
|
85
|
+
this.lastSyncedLanguage = lang;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.error(`[i18n] Error loading language ${lang}:`, error);
|
|
90
|
+
if (lang !== this.fallbackLanguage) {
|
|
91
|
+
await this.setLanguage(this.fallbackLanguage);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
t(key, params = {}) {
|
|
97
|
+
const keys = key.split('.');
|
|
98
|
+
let value = this.translations;
|
|
99
|
+
|
|
100
|
+
for (const k of keys) {
|
|
101
|
+
if (value && typeof value === 'object' && k in value) {
|
|
102
|
+
value = value[k];
|
|
103
|
+
} else {
|
|
104
|
+
console.warn(`[i18n] Translation key not found: ${key}`);
|
|
105
|
+
return key;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (typeof value === 'string' && Object.keys(params).length > 0) {
|
|
110
|
+
return value.replace(/\{(\w+)\}/g, (match, paramKey) => {
|
|
111
|
+
return params[paramKey] !== undefined ? params[paramKey] : match;
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return value;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
getLanguage() {
|
|
119
|
+
return this.currentLanguage;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
getSupportedLanguages() {
|
|
123
|
+
return [
|
|
124
|
+
{ code: 'en', name: 'English', nativeName: 'English' },
|
|
125
|
+
{ code: 'zh', name: 'Chinese', nativeName: '中文' }
|
|
126
|
+
];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
onLanguageChange(callback) {
|
|
130
|
+
this.listeners.push(callback);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
notifyListeners(lang) {
|
|
134
|
+
this.listeners.forEach(callback => {
|
|
135
|
+
try { callback(lang); } catch (error) {
|
|
136
|
+
console.error('[i18n] Error in language change listener:', error);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
updateDOM() {
|
|
142
|
+
document.querySelectorAll('[data-i18n]').forEach(el => {
|
|
143
|
+
const key = el.getAttribute('data-i18n');
|
|
144
|
+
if (key) {
|
|
145
|
+
const translation = this.t(key);
|
|
146
|
+
if (typeof translation === 'string' && translation.includes('<')) {
|
|
147
|
+
el.innerHTML = translation;
|
|
148
|
+
} else {
|
|
149
|
+
el.textContent = typeof translation === 'string' ? translation : String(translation);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
document.querySelectorAll('[data-i18n-placeholder]').forEach(el => {
|
|
155
|
+
const key = el.getAttribute('data-i18n-placeholder');
|
|
156
|
+
if (key) el.placeholder = this.t(key);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
document.querySelectorAll('[data-i18n-title]').forEach(el => {
|
|
160
|
+
const key = el.getAttribute('data-i18n-title');
|
|
161
|
+
if (key) el.title = this.t(key);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const instance = new I18nManager();
|
|
167
|
+
|
|
168
|
+
// Backward compatibility: expose on window for legacy scripts
|
|
169
|
+
window.i18n = instance;
|
|
170
|
+
window.t = instance.t.bind(instance);
|
|
171
|
+
|
|
172
|
+
// Auto-initialize
|
|
173
|
+
if (document.readyState === 'loading') {
|
|
174
|
+
document.addEventListener('DOMContentLoaded', async () => {
|
|
175
|
+
await instance.init();
|
|
176
|
+
instance.updateDOM();
|
|
177
|
+
});
|
|
178
|
+
} else {
|
|
179
|
+
instance.init().then(() => instance.updateDOM());
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
instance.onLanguageChange(() => instance.updateDOM());
|
|
183
|
+
|
|
184
|
+
export { instance as i18n, I18nManager };
|
|
185
|
+
export const t = instance.t.bind(instance);
|
|
186
|
+
export default instance;
|