@citeark/agent 0.3.20
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 +202 -0
- package/README.md +128 -0
- package/data/dataset-source-registry.v1.json +300 -0
- package/dist/arkgraph/boot.js +6 -0
- package/dist/arkgraph/index.html +1 -0
- package/dist/arkgraph/viewer.css +1 -0
- package/dist/arkgraph/viewer.en.css +1 -0
- package/dist/arkgraph/viewer.en.js +49 -0
- package/dist/arkgraph/viewer.en.js.LEGAL.txt +56 -0
- package/dist/arkgraph/viewer.js +49 -0
- package/dist/arkgraph/viewer.js.LEGAL.txt +56 -0
- package/docker/claude-code/Dockerfile +97 -0
- package/docker/claude-code/codex-pro-relay.mjs +466 -0
- package/docker/claude-code/runtime-contract-check.mjs +79 -0
- package/docs/arkgraph-reading.md +79 -0
- package/docs/configuration.md +100 -0
- package/docs/integration.md +92 -0
- package/docs/maturity-plan.md +27 -0
- package/docs/npm-release.md +44 -0
- package/docs/paper-reading.md +40 -0
- package/docs/research-plan-granularity.md +27 -0
- package/docs/terminal.md +49 -0
- package/examples/toy-evaluation/compile-task.json +27 -0
- package/examples/toy-evaluation/paper.md +5 -0
- package/examples/toy-evaluation/repository/README.md +9 -0
- package/examples/toy-evaluation/repository/checkpoint.json +4 -0
- package/examples/toy-evaluation/repository/evaluate.py +17 -0
- package/examples/toy-evaluation/task.json +81 -0
- package/package.json +59 -0
- package/prompts/compile-research.md +58 -0
- package/prompts/execute-contract.md +72 -0
- package/prompts/execute-workspace-simple.md +51 -0
- package/prompts/execute-workspace.md +34 -0
- package/prompts/prepare-reproduction.md +82 -0
- package/prompts/repair-research.md +45 -0
- package/protocol/CAP.md +129 -0
- package/protocol/LICENSE +12 -0
- package/protocol/MAPPINGS.md +72 -0
- package/protocol/README.md +38 -0
- package/protocol/conformance-v2.0-alpha.1.json +36 -0
- package/protocol/examples/arkgraph/checkpoint-evaluation.json +309 -0
- package/protocol/examples/arkgraph/fixtures.mjs +49 -0
- package/protocol/examples/arkgraph/paper-free.json +291 -0
- package/protocol/examples/arkgraph/partial-failure.json +344 -0
- package/protocol/examples/arkgraph/training-evaluation.json +443 -0
- package/protocol/profiles/agent-trace.md +16 -0
- package/protocol/profiles/computational-run.md +16 -0
- package/protocol/profiles/core.md +15 -0
- package/protocol/profiles/public-bundle.md +18 -0
- package/protocol/profiles/reproduction.md +29 -0
- package/protocol/profiles/research-compilation.md +44 -0
- package/protocol/profiles/research-plan.md +39 -0
- package/protocol/profiles/restricted-evidence.md +15 -0
- package/runtime/bootstrap-autodl-runtime.sh +314 -0
- package/runtime/create-runtime-venv.sh +41 -0
- package/runtime/install-local-cpu-runtime.sh +23 -0
- package/runtime/install-scientific-runtime.sh +153 -0
- package/runtime/mineru/parse.py +62 -0
- package/runtime/mineru/requirements.txt +4 -0
- package/runtime/requirements-baseline.txt +38 -0
- package/schemas/cap/v2/activity.schema.json +47 -0
- package/schemas/cap/v2/agent.schema.json +32 -0
- package/schemas/cap/v2/assertion.schema.json +110 -0
- package/schemas/cap/v2/descriptor.schema.json +243 -0
- package/schemas/cap/v2/entity.schema.json +64 -0
- package/schemas/cap/v2/manifest.schema.json +67 -0
- package/schemas/cap/v2/relation.schema.json +82 -0
- package/schemas/compute-catalog.schema.json +63 -0
- package/schemas/compute-decision.schema.json +27 -0
- package/schemas/execution-contract.schema.json +1024 -0
- package/schemas/research-card.schema.json +30 -0
- package/schemas/research-inventory-draft.schema.json +366 -0
- package/schemas/research.schema.json +1044 -0
- package/schemas/result.schema.json +173 -0
- package/schemas/verification-policy.schema.json +47 -0
- package/schemas/verified-conclusion.schema.json +58 -0
- package/schemas/workspace-summary.schema.json +24 -0
- package/scripts/build-arkgraph-view.mjs +12 -0
- package/scripts/check-execution-feasibility.mjs +24 -0
- package/scripts/check-syntax.mjs +15 -0
- package/scripts/deterministic-asset-preparation.py +438 -0
- package/scripts/package-cap.mjs +23 -0
- package/scripts/package-local-agent.mjs +23 -0
- package/scripts/preview-arkgraph.mjs +25 -0
- package/scripts/replay-research-compiler-candidate.mjs +134 -0
- package/scripts/review-compiler-sources.mjs +44 -0
- package/scripts/run-asset-preparation.sh +17 -0
- package/scripts/run-research-plan.mjs +98 -0
- package/scripts/validate-asset-preparation.py +290 -0
- package/scripts/verify-local-runtime.mjs +57 -0
- package/scripts/verify-npm-package.mjs +57 -0
- package/src/adapters/paper2agent.mjs +107 -0
- package/src/assets/cache.mjs +159 -0
- package/src/assets/compute.mjs +98 -0
- package/src/assets/executor.mjs +145 -0
- package/src/assets/lifecycle.mjs +213 -0
- package/src/assets/manifest.mjs +242 -0
- package/src/assets/opportunistic-preparation.mjs +81 -0
- package/src/assets/plan.mjs +411 -0
- package/src/assets/prompts.mjs +29 -0
- package/src/assets/public-asset-probe.mjs +525 -0
- package/src/assets/qualification.mjs +119 -0
- package/src/assets/readiness.mjs +130 -0
- package/src/assets/reproduction-admission.mjs +355 -0
- package/src/assets/requirements.mjs +152 -0
- package/src/assets/source-grounding.mjs +341 -0
- package/src/assets/source-policy.mjs +118 -0
- package/src/autodl/client.mjs +260 -0
- package/src/autodl/ssh.mjs +380 -0
- package/src/autodl/tools.mjs +129 -0
- package/src/cap/redaction.mjs +38 -0
- package/src/cap/v2/archive.mjs +152 -0
- package/src/cap/v2/attestation.mjs +204 -0
- package/src/cap/v2/canonical-json.mjs +114 -0
- package/src/cap/v2/compilation-artifact.mjs +240 -0
- package/src/cap/v2/core.mjs +282 -0
- package/src/cap/v2/measurement-assessment-records.mjs +23 -0
- package/src/cap/v2/pipeline-artifact.mjs +922 -0
- package/src/cap/v2/read.mjs +41 -0
- package/src/cap/v2/reassessment-artifact.mjs +383 -0
- package/src/cap/v2/research-artifact.mjs +231 -0
- package/src/cap/v2/research-map-records.mjs +46 -0
- package/src/cap/v2/research-object-records.mjs +163 -0
- package/src/cap/v2/research-records.mjs +187 -0
- package/src/cap/v2/verify.mjs +642 -0
- package/src/cli.mjs +1146 -0
- package/src/compute/autodl-pro-compiler.mjs +347 -0
- package/src/compute/autodl-pro-executor.mjs +459 -0
- package/src/compute/autodl-pro-job.mjs +843 -0
- package/src/compute/autodl-pro-network.mjs +295 -0
- package/src/compute/autodl-pro-remote.mjs +810 -0
- package/src/compute/autodl-pro-staging.mjs +117 -0
- package/src/compute/campaign.mjs +110 -0
- package/src/compute/catalog.mjs +123 -0
- package/src/compute/checkpoint-protocol.mjs +154 -0
- package/src/compute/codex-account-lock.mjs +111 -0
- package/src/compute/codex-account-session.mjs +107 -0
- package/src/compute/compiler-profile.mjs +38 -0
- package/src/compute/compiler-router.mjs +23 -0
- package/src/compute/coordinator-recovery.mjs +210 -0
- package/src/compute/executor-router.mjs +29 -0
- package/src/compute/gcp-batch-compiler.mjs +685 -0
- package/src/compute/gcp-batch-executor.mjs +1215 -0
- package/src/compute/gcp-batch-failure.mjs +92 -0
- package/src/compute/gcp-batch-job.mjs +527 -0
- package/src/compute/gcp-batch-lifecycle.mjs +81 -0
- package/src/compute/gcp-checkpoint-worker.mjs +1633 -0
- package/src/compute/local-codex-compiler.mjs +52 -0
- package/src/compute/measurement-hardware.mjs +128 -0
- package/src/compute/remote-attempt.mjs +226 -0
- package/src/compute/requirements.mjs +124 -0
- package/src/compute/research-phases.mjs +48 -0
- package/src/compute/scheduler.mjs +452 -0
- package/src/compute/shared-workloads.mjs +26 -0
- package/src/compute/stage-archive.mjs +79 -0
- package/src/contracts/campaign-contract.mjs +52 -0
- package/src/contracts/execution-contract.mjs +819 -0
- package/src/contracts/execution-mode.mjs +19 -0
- package/src/contracts/execution-timeouts.mjs +45 -0
- package/src/contracts/execution-workload.mjs +68 -0
- package/src/contracts/preflight-schema.mjs +25 -0
- package/src/contracts/public-contract.mjs +63 -0
- package/src/contracts/subject-tags.mjs +31 -0
- package/src/dashboard/data.mjs +898 -0
- package/src/dashboard/server.mjs +79 -0
- package/src/dashboard/static/dashboard.css +366 -0
- package/src/dashboard/static/dashboard.js +560 -0
- package/src/dashboard/static/index.html +85 -0
- package/src/deployment/community-policy.mjs +9 -0
- package/src/deployment/environment.mjs +112 -0
- package/src/deployment/guided.mjs +98 -0
- package/src/deployment/handoff.mjs +102 -0
- package/src/deployment/local-contract.mjs +31 -0
- package/src/deployment/local.mjs +100 -0
- package/src/deployment/prepare.mjs +46 -0
- package/src/deployment/recipe.mjs +108 -0
- package/src/deployment/supplement.mjs +51 -0
- package/src/deployment/terminal.mjs +43 -0
- package/src/diagnosis/renderer.mjs +75 -0
- package/src/diagnosis/target-failure.mjs +46 -0
- package/src/evidence/parser-registry.mjs +54 -0
- package/src/evidence/parsers/fasttext-classification.mjs +82 -0
- package/src/evidence/parsers/json-scalar.mjs +96 -0
- package/src/evidence/parsers/simcse-senteval.mjs +104 -0
- package/src/evidence/parsers/starspace-classification.mjs +78 -0
- package/src/evidence/registry.mjs +147 -0
- package/src/execution/runner-audit.mjs +473 -0
- package/src/gcp/auth.mjs +106 -0
- package/src/gcp/batch-client.mjs +120 -0
- package/src/gcp/resource-discovery.mjs +177 -0
- package/src/gcp/rest.mjs +82 -0
- package/src/gcp/secret-manager.mjs +34 -0
- package/src/gcp/signed-url.mjs +133 -0
- package/src/gcp/storage.mjs +220 -0
- package/src/graph/command.mjs +41 -0
- package/src/graph/execution.mjs +97 -0
- package/src/graph/model.mjs +37 -0
- package/src/graph/presentation.mjs +110 -0
- package/src/graph/query.mjs +159 -0
- package/src/graph/research-relations.mjs +69 -0
- package/src/graph/source-page.mjs +12 -0
- package/src/graph/source-preview.mjs +34 -0
- package/src/graph/validate.mjs +76 -0
- package/src/job.mjs +496 -0
- package/src/network/autodl-routing-proxy.mjs +462 -0
- package/src/network/egress-proxy.mjs +158 -0
- package/src/observability/event-contract.mjs +230 -0
- package/src/observability/pipeline-monitor.mjs +166 -0
- package/src/pipeline/orchestrator.mjs +1281 -0
- package/src/pipeline/recovery-error.mjs +11 -0
- package/src/pipeline/replay.mjs +304 -0
- package/src/pipeline/shared-execution.mjs +115 -0
- package/src/pipeline/stage-checkpoint.mjs +86 -0
- package/src/pipeline/stage-recovery.mjs +101 -0
- package/src/pipeline/targets.mjs +110 -0
- package/src/process.mjs +143 -0
- package/src/protocol.mjs +312 -0
- package/src/provider/codex-account.mjs +44 -0
- package/src/provider/codex-completion.mjs +49 -0
- package/src/provider/completion.mjs +292 -0
- package/src/provider/model-client.mjs +44 -0
- package/src/provider/model-route.mjs +29 -0
- package/src/provider/openrouter-readiness.mjs +189 -0
- package/src/provider/reader-bridge.mjs +35 -0
- package/src/provider/relay.mjs +263 -0
- package/src/provider/runtime-auth.mjs +40 -0
- package/src/public/cap.d.mts +90 -0
- package/src/public/cap.mjs +12 -0
- package/src/public/contracts.d.mts +2 -0
- package/src/public/host.mjs +171 -0
- package/src/public/operations.d.mts +11 -0
- package/src/public/presentation.d.mts +4 -0
- package/src/records/views.mjs +26 -0
- package/src/remote/command.mjs +178 -0
- package/src/remote/ssh.mjs +59 -0
- package/src/repository-origin.mjs +81 -0
- package/src/reproduction/evidence-feedback.mjs +96 -0
- package/src/reproduction/incomplete-initialization.mjs +25 -0
- package/src/reproduction/lifecycle.mjs +253 -0
- package/src/reproduction/plan.mjs +132 -0
- package/src/reproduction/prompts.mjs +70 -0
- package/src/reproduction/runner.mjs +188 -0
- package/src/reproduction/summary.mjs +130 -0
- package/src/reproduction/workspace-mode.mjs +7 -0
- package/src/research/automatic-admission.mjs +156 -0
- package/src/research/compiler-coverage.mjs +85 -0
- package/src/research/compiler-failure.mjs +24 -0
- package/src/research/compiler-normalization-guards.mjs +112 -0
- package/src/research/compiler-repair.mjs +3 -0
- package/src/research/compiler.mjs +853 -0
- package/src/research/continuation-selection.mjs +26 -0
- package/src/research/execution-graph-context.mjs +43 -0
- package/src/research/experiment-importance.mjs +15 -0
- package/src/research/inventory-handoff.mjs +104 -0
- package/src/research/inventory-revisions.mjs +32 -0
- package/src/research/mineru-local.mjs +73 -0
- package/src/research/paper-command.mjs +19 -0
- package/src/research/paper-markdown.mjs +180 -0
- package/src/research/paper-source-map.mjs +69 -0
- package/src/research/planning-policy.mjs +88 -0
- package/src/research/reference-materials.mjs +11 -0
- package/src/research/reproduction-scope.mjs +30 -0
- package/src/research/research-map.mjs +94 -0
- package/src/research/research-objects.mjs +88 -0
- package/src/research/source-discovery.mjs +646 -0
- package/src/research/source-observations.mjs +75 -0
- package/src/research/source-review-cli-mcp.mjs +26 -0
- package/src/research/source-review-input.mjs +209 -0
- package/src/research/source-review-local-codex.mjs +36 -0
- package/src/research/source-review-model.mjs +70 -0
- package/src/research/source-review.mjs +173 -0
- package/src/research/structure.mjs +3163 -0
- package/src/research-card/renderer.mjs +277 -0
- package/src/research-card/verified-conclusion.mjs +143 -0
- package/src/results/output-registry.mjs +183 -0
- package/src/runtime/claude-code.mjs +52 -0
- package/src/runtime/codex-capacity-retry.mjs +87 -0
- package/src/runtime/codex.mjs +64 -0
- package/src/runtime/config.mjs +157 -0
- package/src/runtime/final-output.mjs +40 -0
- package/src/runtime/index.mjs +21 -0
- package/src/runtime/local-codex.mjs +74 -0
- package/src/runtime/opencode.mjs +95 -0
- package/src/runtime/prompt.mjs +13 -0
- package/src/sandbox/docker.mjs +363 -0
- package/src/settings/command.mjs +297 -0
- package/src/settings/store.mjs +119 -0
- package/src/telemetry/pricing.mjs +68 -0
- package/src/telemetry/usage.mjs +265 -0
- package/src/terminal/events.mjs +97 -0
- package/src/terminal/input.mjs +40 -0
- package/src/terminal/plain.mjs +40 -0
- package/src/terminal/remote-stream.mjs +22 -0
- package/src/terminal/screen.mjs +214 -0
- package/src/terminal/transcript.mjs +69 -0
- package/src/util.mjs +107 -0
- package/src/verification/ai-assessor.mjs +534 -0
- package/src/verification/claim-evaluator.mjs +242 -0
- package/src/verification/evidence-context.mjs +165 -0
- package/src/verification/evidence-reader.mjs +95 -0
- package/src/verification/integrity.mjs +570 -0
- package/src/verification/tolerance.mjs +32 -0
- package/src/workloads/cpu-research-preparation.mjs +56 -0
- package/src/workloads/definition.mjs +74 -0
- package/src/workloads/phase-aware-reproduction.mjs +46 -0
- package/src/workloads/reproduction.mjs +85 -0
- package/src/workspace/command.mjs +242 -0
- package/src/workspace/control.mjs +49 -0
- package/src/workspace/entry.mjs +28 -0
- package/src/workspace/input.mjs +93 -0
- package/src/workspace/interactive.mjs +94 -0
- package/src/workspace/jobs.mjs +418 -0
- package/src/workspace/session.mjs +97 -0
- package/src/workspace/worker.mjs +137 -0
- package/ui/arkgraph/ambient-motion.mjs +10 -0
- package/ui/arkgraph/app.jsx +153 -0
- package/ui/arkgraph/boot.js +6 -0
- package/ui/arkgraph/camera-motion.mjs +20 -0
- package/ui/arkgraph/context-reveal.mjs +39 -0
- package/ui/arkgraph/details.css +3 -0
- package/ui/arkgraph/entry.jsx +28 -0
- package/ui/arkgraph/experiment-curves.mjs +17 -0
- package/ui/arkgraph/experiment-selection.mjs +15 -0
- package/ui/arkgraph/experiment-style.css +26 -0
- package/ui/arkgraph/experiment-ui.jsx +32 -0
- package/ui/arkgraph/frame.html +1 -0
- package/ui/arkgraph/graph-gestures.mjs +62 -0
- package/ui/arkgraph/label-layout.mjs +57 -0
- package/ui/arkgraph/locales/en.json +229 -0
- package/ui/arkgraph/locales/source-types.json +15 -0
- package/ui/arkgraph/localization-build.mjs +27 -0
- package/ui/arkgraph/material-build.mjs +23 -0
- package/ui/arkgraph/material-colors.mjs +39 -0
- package/ui/arkgraph/material-style.css +15 -0
- package/ui/arkgraph/open-graph.jsx +326 -0
- package/ui/arkgraph/outline.jsx +49 -0
- package/ui/arkgraph/package-lock.json +888 -0
- package/ui/arkgraph/package.json +17 -0
- package/ui/arkgraph/reading-layout.mjs +130 -0
- package/ui/arkgraph/reading-presentation.mjs +73 -0
- package/ui/arkgraph/record-detail.css +51 -0
- package/ui/arkgraph/record-details.jsx +29 -0
- package/ui/arkgraph/research-types.mjs +31 -0
- package/ui/arkgraph/selection-mark.jsx +6 -0
- package/ui/arkgraph/soft-spine.mjs +26 -0
- package/ui/arkgraph/steering-style.css +187 -0
- package/ui/arkgraph/style.css +272 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Camera and node dragging share one pointer owner and the same bounded follow model.
|
|
2
|
+
export function createGraphGestures({element,graph,findNode,reduced,onStart,onActivity,onRelease,onTap,onNodeStart,onNodeEnd}){
|
|
3
|
+
let gesture=null,frame=0,lastTime=0,target=null,node=null,nodeStarted=false,disposed=false;
|
|
4
|
+
const state=(name,lag=0)=>{const prefix=node?'nodeDrag':'pan';element.dataset[prefix]=name;element.dataset[prefix+'Lag']=lag.toFixed(2);};
|
|
5
|
+
const active=()=>!!gesture||!!frame;
|
|
6
|
+
const finish=()=>{
|
|
7
|
+
state('idle');target=null;lastTime=0;
|
|
8
|
+
if(nodeStarted){const released=node;nodeStarted=false;delete released.fx;delete released.fy;onNodeEnd(released);}
|
|
9
|
+
node=null;
|
|
10
|
+
};
|
|
11
|
+
const render=now=>{
|
|
12
|
+
frame=0;if(disposed||!target)return;
|
|
13
|
+
const position=node||graph.centerAt(),k=graph.zoom(),dx=target.x-position.x,dy=target.y-position.y,lag=Math.hypot(dx,dy)*k;
|
|
14
|
+
const dt=lastTime?Math.min(40,now-lastTime):16;lastTime=now;
|
|
15
|
+
const amount=reduced()?1:1-Math.exp(-dt/(node?85:65));
|
|
16
|
+
const remaining=Math.min(node?26:24,lag*(1-amount)),ratio=lag?remaining/lag:0;
|
|
17
|
+
const x=target.x-dx*ratio,y=target.y-dy*ratio;
|
|
18
|
+
if(node){node.x=node.fx=x;node.y=node.fy=y;}else graph.centerAt(x,y);
|
|
19
|
+
onActivity();state(gesture?'dragging':'settling',remaining);
|
|
20
|
+
const peak=node?'nodeDragPeakLag':'panPeakLag';element.dataset[peak]=Math.max(Number(element.dataset[peak]||0),remaining).toFixed(2);
|
|
21
|
+
if(remaining>.12)frame=requestAnimationFrame(render);
|
|
22
|
+
else if(!gesture)finish();
|
|
23
|
+
};
|
|
24
|
+
const schedule=()=>{if(!frame)frame=requestAnimationFrame(render);};
|
|
25
|
+
const cancel=()=>{
|
|
26
|
+
cancelAnimationFrame(frame);frame=0;
|
|
27
|
+
if(gesture){try{element.releasePointerCapture(gesture.id);}catch{}gesture=null;onRelease();}
|
|
28
|
+
finish();
|
|
29
|
+
};
|
|
30
|
+
const down=event=>{
|
|
31
|
+
if(event.button!==0||event.isPrimary===false||event.target.tagName!=='CANVAS')return;
|
|
32
|
+
cancel();const rect=element.getBoundingClientRect();node=findNode(event.clientX-rect.left,event.clientY-rect.top)||null;
|
|
33
|
+
const center=node?{x:node.x,y:node.y}:graph.centerAt();
|
|
34
|
+
gesture={id:event.pointerId,x:event.clientX,y:event.clientY,center,zoom:graph.zoom(),moved:false};
|
|
35
|
+
target={...center};element.dataset[node?'nodeDragPeakLag':'panPeakLag']='0';onStart(node);
|
|
36
|
+
element.setPointerCapture(event.pointerId);event.preventDefault();event.stopImmediatePropagation();state('dragging');
|
|
37
|
+
};
|
|
38
|
+
const move=event=>{
|
|
39
|
+
if(!gesture||event.pointerId!==gesture.id)return;
|
|
40
|
+
const dx=event.clientX-gesture.x,dy=event.clientY-gesture.y;
|
|
41
|
+
gesture.moved ||= Math.hypot(dx,dy)>3;
|
|
42
|
+
if(gesture.moved){
|
|
43
|
+
if(node&&!nodeStarted){nodeStarted=true;node.fx=node.x;node.fy=node.y;onNodeStart(node);}
|
|
44
|
+
const sign=node?1:-1;target={x:gesture.center.x+sign*dx/gesture.zoom,y:gesture.center.y+sign*dy/gesture.zoom};schedule();
|
|
45
|
+
}
|
|
46
|
+
event.preventDefault();event.stopImmediatePropagation();
|
|
47
|
+
};
|
|
48
|
+
const up=event=>{
|
|
49
|
+
if(!gesture||event.pointerId!==gesture.id)return;
|
|
50
|
+
const moved=gesture.moved,tapped=node;gesture=null;
|
|
51
|
+
try{element.releasePointerCapture(event.pointerId);}catch{}
|
|
52
|
+
event.preventDefault();event.stopImmediatePropagation();onRelease();
|
|
53
|
+
if(moved)schedule();else{cancel();onTap(tapped,{x:event.clientX,y:event.clientY});}
|
|
54
|
+
};
|
|
55
|
+
const mouseDown=event=>{if(gesture){event.preventDefault();event.stopImmediatePropagation();}};
|
|
56
|
+
const aborted=event=>{if(gesture&&event.pointerId===gesture.id)cancel();};
|
|
57
|
+
const wheel=()=>{if(active())cancel();};
|
|
58
|
+
element.addEventListener('pointerdown',down,true);element.addEventListener('mousedown',mouseDown,true);element.addEventListener('wheel',wheel,{capture:true,passive:true});
|
|
59
|
+
window.addEventListener('pointermove',move,{capture:true,passive:false});window.addEventListener('pointerup',up,true);window.addEventListener('pointercancel',aborted,true);
|
|
60
|
+
element.dataset.pan='idle';element.dataset.nodeDrag='idle';
|
|
61
|
+
return {get active(){return active();},cancel,dispose(){disposed=true;cancel();element.removeEventListener('pointerdown',down,true);element.removeEventListener('mousedown',mouseDown,true);element.removeEventListener('wheel',wheel,true);window.removeEventListener('pointermove',move,true);window.removeEventListener('pointerup',up,true);window.removeEventListener('pointercancel',aborted,true);}};
|
|
62
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// Fixed graph geometry only: camera position, zoom and viewport never enter the solver.
|
|
2
|
+
const overlap=(a,b,pad=4)=>a.x<b.x+b.w+pad&&a.x+a.w+pad>b.x&&a.y<b.y+b.h+pad&&a.y+a.h+pad>b.y;
|
|
3
|
+
const swept=(box,n)=>{const {x=0,y=0}=n?.motion||{};return {...box,x:box.x-x,y:box.y-y,w:box.w+2*x,h:box.h+2*y};};
|
|
4
|
+
const near=(n,b)=>({x:Math.max(b.x,Math.min(b.x+b.w,n.x)),y:Math.max(b.y,Math.min(b.y+b.h,n.y))});
|
|
5
|
+
const cross=(a,b,c)=>(b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
|
|
6
|
+
const intersects=(a,b,c,d)=>cross(a,b,c)*cross(a,b,d)<-1e-6&&cross(c,d,a)*cross(c,d,b)<-1e-6;
|
|
7
|
+
function lineHits(a,b,box){
|
|
8
|
+
const p={x:box.x,y:box.y},q={x:box.x+box.w,y:box.y},r={x:q.x,y:box.y+box.h},s={x:p.x,y:r.y};
|
|
9
|
+
return intersects(a,b,p,q)||intersects(a,b,q,r)||intersects(a,b,r,s)||intersects(a,b,s,p);
|
|
10
|
+
}
|
|
11
|
+
export function layoutLabels(items,previous=new Map(),reserved=[]){
|
|
12
|
+
const boxes=new Map(),result=new Map(),byId=new Map(items.map(n=>[n.id,n]));
|
|
13
|
+
const obstacles=[...items.map(n=>({id:n.id,x:n.x-n.r,y:n.y-n.r,w:2*n.r,h:2*n.r})),...reserved];
|
|
14
|
+
const ordered=[...items].sort((a,b)=>Number(b.main)-Number(a.main)||(a.main?a.step-b.step:a.y-b.y)||a.id.localeCompare(b.id));
|
|
15
|
+
function choose(n,retain=true){
|
|
16
|
+
const others=[...boxes.entries()].filter(([id])=>id!==n.id),old=previous.get(n.id);
|
|
17
|
+
const free=b=>{
|
|
18
|
+
const envelope=swept(b,n);
|
|
19
|
+
// A label shares its owner's motion. Other nodes/labels can move independently.
|
|
20
|
+
return !obstacles.some(o=>o.id===n.id?overlap(b,o,4):overlap(envelope,swept(o,byId.get(o.id)),4))
|
|
21
|
+
&&!others.some(([id,o])=>overlap(envelope,swept(o,byId.get(id)),5));
|
|
22
|
+
};
|
|
23
|
+
const score=b=>{
|
|
24
|
+
const p=near(n,b),length=Math.hypot(p.x-n.x,p.y-n.y),gap=Math.max(0,length-n.r),vx=b.x+b.w/2-n.x,vy=b.y+b.h/2-n.y;
|
|
25
|
+
let cost=gap*2+Math.abs(vy)*(n.main?.65:.12);
|
|
26
|
+
// Place branch labels outward from their parent, preserving the local fan order.
|
|
27
|
+
if(n.outward){const v=Math.hypot(vx,vy)||1;cost+=(1-(vx*n.outward.x+vy*n.outward.y)/v)*16;}
|
|
28
|
+
else if(b.side!==n.side)cost+=n.main?7:3;
|
|
29
|
+
for(const [id,o] of others){const owner=byId.get(id),end=near(owner,o);if(intersects(n,p,owner,end))cost+=160;if(lineHits(n,p,o)||lineHits(owner,end,b))cost+=100;}
|
|
30
|
+
for(const other of items)if(other.id!==n.id){const q=near(other,b);if(Math.hypot(q.x-other.x,q.y-other.y)<length-2)cost+=45;}
|
|
31
|
+
for(const o of obstacles)if(o.id!==n.id&&lineHits(n,p,o))cost+=160;
|
|
32
|
+
return cost;
|
|
33
|
+
};
|
|
34
|
+
const retained=old&&{x:n.x+old.dx,y:n.y+old.dy,w:n.w,h:n.h,side:old.side};
|
|
35
|
+
const preferred=n.preferred&&{x:n.x+n.preferred.dx,y:n.y+n.preferred.dy,w:n.w,h:n.h,side:n.preferred.side};
|
|
36
|
+
// The physical layout already reserves this nearby attachment. Camera movement
|
|
37
|
+
// never participates in this choice or in the collision geometry.
|
|
38
|
+
if(preferred&&free(preferred))return preferred;
|
|
39
|
+
// At rest a good attachment stays put, including through pan/zoom and gentle drift.
|
|
40
|
+
if(retain&&retained&&free(retained)&&score(retained)<48)return retained;
|
|
41
|
+
let best=null,bestScore=Infinity;
|
|
42
|
+
for(let ring=0;ring<5||!best;ring++){
|
|
43
|
+
const r=n.r+8+ring*10,candidates=[];
|
|
44
|
+
for(const side of ['left','right'])for(const shift of [0,-.5,.5,-1,1])candidates.push({x:side==='left'?n.x-r-n.w:n.x+r,y:n.y-n.h/2+shift*n.h,w:n.w,h:n.h,side});
|
|
45
|
+
for(const side of ['above','below'])for(const shift of [0,-.25,.25,-.5,.5])candidates.push({x:n.x-n.w/2+shift*n.w,y:side==='above'?n.y-r-n.h:n.y+r,w:n.w,h:n.h,side});
|
|
46
|
+
for(const b of candidates)if(free(b)){const value=score(b)+(retained?Math.hypot(b.x-retained.x,b.y-retained.y)*.06:0);if(value<bestScore){best=b;bestScore=value;}}
|
|
47
|
+
if(best&&ring>1&&(ring*10+8)*2>bestScore+20)break;
|
|
48
|
+
}
|
|
49
|
+
if(retain&&retained&&free(retained)&&score(retained)<=bestScore+14)return retained;
|
|
50
|
+
return best;
|
|
51
|
+
}
|
|
52
|
+
for(const n of ordered)boxes.set(n.id,choose(n));
|
|
53
|
+
// A final local pass can shorten leaders after all neighboring labels are known.
|
|
54
|
+
if(!previous.size)for(const n of ordered)boxes.set(n.id,choose(n,false));
|
|
55
|
+
for(const n of items){const b=boxes.get(n.id);result.set(n.id,{dx:b.x-n.x,dy:b.y-n.y,side:b.side});}
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
{
|
|
2
|
+
" · 全文 ": " · Total ",
|
|
3
|
+
" · 正在检索完整记录…": " · Searching complete records…",
|
|
4
|
+
" 个": " objects",
|
|
5
|
+
" 个主节点": " main nodes",
|
|
6
|
+
" 个假说": " hypotheses",
|
|
7
|
+
" 个对象 ": " objects ",
|
|
8
|
+
" 个对象 · 全文 ": " visible · Total ",
|
|
9
|
+
" 个必要步骤": " required steps",
|
|
10
|
+
" 个科研步骤。": " research steps.",
|
|
11
|
+
" 个补充对象": " additional objects",
|
|
12
|
+
" 条": " relations",
|
|
13
|
+
" 条 ": " relations ",
|
|
14
|
+
" 条关系": " relations",
|
|
15
|
+
" 项": " items",
|
|
16
|
+
" 项 · 点击弱化或恢复": " items · Click to dim or restore",
|
|
17
|
+
" 项主张 ": " claims ",
|
|
18
|
+
" 项匹配": " matches",
|
|
19
|
+
" 项实验": " experiments",
|
|
20
|
+
" 项实验共用": " experiments share this step",
|
|
21
|
+
" 项实验已选 ": " experiments selected ",
|
|
22
|
+
" 项实验,共用 ": " experiments sharing ",
|
|
23
|
+
" 项数值": " values",
|
|
24
|
+
"上一个主线节点": "Previous mainline node",
|
|
25
|
+
"下一个主线节点": "Next mainline node",
|
|
26
|
+
"主体": "Agent",
|
|
27
|
+
"主张": "Claim",
|
|
28
|
+
"主张、假说与评估": "Claims, hypotheses and assessments",
|
|
29
|
+
"主线以外的概念、前提、观点和解释": "Additional concepts, premises, claims and explanations",
|
|
30
|
+
"主线导航": "Mainline navigation",
|
|
31
|
+
"人、组织、智能体与运行节点": "People, organizations, agents and execution nodes",
|
|
32
|
+
"从主线开始": "Start with the mainline",
|
|
33
|
+
"代码": "Code",
|
|
34
|
+
"作者提出的发现、解释、定理或结论": "Findings, explanations, theorems or conclusions proposed by the authors",
|
|
35
|
+
"使用": "Uses",
|
|
36
|
+
"使用方法": "Uses method",
|
|
37
|
+
"依据": "Based on",
|
|
38
|
+
"保存实验范围": "Save experiment scope",
|
|
39
|
+
"保存选择后,正式执行前仍需确认资源与费用。": "Confirm resources and costs before starting the selected experiments.",
|
|
40
|
+
"修订": "Revises",
|
|
41
|
+
"候选实验": "Candidate experiment",
|
|
42
|
+
"假说": "Hypothesis",
|
|
43
|
+
"假说与前提": "Hypotheses and premises",
|
|
44
|
+
"先看问题,再选择实验": "Read the question, then select experiments",
|
|
45
|
+
"全部 ": "All ",
|
|
46
|
+
"全部关联 · ": "All connections · ",
|
|
47
|
+
"全部数据 ↓": "Complete data ↓",
|
|
48
|
+
"全部研究对象": "All research objects",
|
|
49
|
+
"关系": "Relations",
|
|
50
|
+
"关联实验计划": "Related experiment plans",
|
|
51
|
+
"关闭大纲": "Close outline",
|
|
52
|
+
"关闭放大图表": "Close enlarged figure",
|
|
53
|
+
"关闭详情": "Close details",
|
|
54
|
+
"具体研究的安排或尚未执行的后续研究意向": "Research arrangements and proposed future work",
|
|
55
|
+
"内容": "Content",
|
|
56
|
+
"内容分类": "Content categories",
|
|
57
|
+
"再显示 ": "Show more ",
|
|
58
|
+
"包含 ": "Includes ",
|
|
59
|
+
"包含步骤": "Has step",
|
|
60
|
+
"包含的必要步骤": "Required steps",
|
|
61
|
+
"原文": "Source",
|
|
62
|
+
"原文依据与目标": "Source evidence and targets",
|
|
63
|
+
"原文图表": "Source figures and tables",
|
|
64
|
+
"原文图表与评述": "Source evidence and commentary",
|
|
65
|
+
"原文报告": "Reported in the paper",
|
|
66
|
+
"参与": "Associated with",
|
|
67
|
+
"参与者": "Participant",
|
|
68
|
+
"发表于": "Asserted in",
|
|
69
|
+
"取消选择": "Deselect",
|
|
70
|
+
"可复用的操作方法、算法、分析或测量方法": "Reusable procedures, algorithms, analysis and measurement methods",
|
|
71
|
+
"后续研究与实验计划": "Future research and experiment plans",
|
|
72
|
+
"后续研究意向、待执行方案及预期材料与产出": "Proposed research, pending plans and expected inputs and outputs",
|
|
73
|
+
"回到研究概览": "Return to the overview",
|
|
74
|
+
"图上实验关系": "Experiment connections",
|
|
75
|
+
"图中 ": "Visible: ",
|
|
76
|
+
"大纲": "Outline",
|
|
77
|
+
"大纲视图": "Outline view",
|
|
78
|
+
"完成选择": "Finish selection",
|
|
79
|
+
"完整整理关系": "Complete relation record",
|
|
80
|
+
"实体": "Entity",
|
|
81
|
+
"实际发生的执行、采集、测量与分析": "Recorded execution, collection, measurement and analysis",
|
|
82
|
+
"实际发生的采集、实验、训练、访谈或分析": "Recorded collection, experiments, training, interviews and analysis",
|
|
83
|
+
"实际获得或计算得到的数据、图像及分析结果": "Observed or computed data, images and analysis results",
|
|
84
|
+
"实验依赖不可用": "Experiment dependency unavailable",
|
|
85
|
+
"实验依赖存在循环": "Cyclic experiment dependencies",
|
|
86
|
+
"实验材料 ": "Experiment materials ",
|
|
87
|
+
"实验范围": "Experiment scope",
|
|
88
|
+
"实验计划": "Experiment plan",
|
|
89
|
+
"对象与资源": "Objects and resources",
|
|
90
|
+
"对象之间的关联 ": "Connections between objects ",
|
|
91
|
+
"对象分类": "Object categories",
|
|
92
|
+
"对象类型筛选": "Filter object types",
|
|
93
|
+
"展开论文说明": "Expand paper description",
|
|
94
|
+
"展开详情": "Expand details",
|
|
95
|
+
"属于": "Part of",
|
|
96
|
+
"已保存到此浏览器": "Saved in this browser",
|
|
97
|
+
"已选 ": "Selected: ",
|
|
98
|
+
"已选择 · 移出范围": "Selected · Remove from scope",
|
|
99
|
+
"归属于": "Attributed to",
|
|
100
|
+
"待明确的输入": "Unresolved inputs",
|
|
101
|
+
"待核对条件": "Conditions to verify",
|
|
102
|
+
"待检验假说与条件前提;通过子类型区分": "Hypotheses to test and conditional premises, distinguished by subtype",
|
|
103
|
+
"报告数值 ": "Reported values ",
|
|
104
|
+
"拟检验": "Planned for",
|
|
105
|
+
"指标": "Metric",
|
|
106
|
+
"按需查阅 ": "Reference sections ",
|
|
107
|
+
"描述": "Describes",
|
|
108
|
+
"提出、执行、提供或评估研究内容的人、组织或软件代理": "People, organizations or software agents proposing, executing, providing or assessing research",
|
|
109
|
+
"搜索内容、数值或来源": "Search content, values or sources",
|
|
110
|
+
"搜索大纲": "Search outline",
|
|
111
|
+
"收起数值": "Show fewer values",
|
|
112
|
+
"收起论文说明": "Collapse paper description",
|
|
113
|
+
"放大": "Enlarge ",
|
|
114
|
+
"数值": "Value",
|
|
115
|
+
"数值的完整条件与来源": "Complete measurement conditions and sources",
|
|
116
|
+
"数据与提示": "Data and prompts",
|
|
117
|
+
"数据集": "Dataset",
|
|
118
|
+
"整理关系": "Research relation",
|
|
119
|
+
"断言": "Assertion",
|
|
120
|
+
"方案": "Plan",
|
|
121
|
+
"方法": "Method",
|
|
122
|
+
"方法、计划、数据、模型、材料、观测": "Methods, plans, data, models, materials and observations",
|
|
123
|
+
"方法与活动细节": "Method and activity details",
|
|
124
|
+
"方法与过程": "Methods and processes",
|
|
125
|
+
"方法图示": "Method illustrations",
|
|
126
|
+
"暂未识别基础对象类型": "Unrecognized object type",
|
|
127
|
+
"替代": "Supersedes",
|
|
128
|
+
"有归属与依据的验证、评价或局限性分析": "Attributed, evidence-based verification, evaluation and limitation analysis",
|
|
129
|
+
"未分类": "Unclassified",
|
|
130
|
+
"未解析的外部引用": "Unresolved external reference",
|
|
131
|
+
"本次选择的实验": "Selected experiments",
|
|
132
|
+
"本篇尚未建立此类独立对象。": "This paper has no independent objects in this category.",
|
|
133
|
+
"材料": "Material",
|
|
134
|
+
"材料与工具": "Materials and tools",
|
|
135
|
+
"材料与来源": "Materials and sources",
|
|
136
|
+
"条件": "Condition",
|
|
137
|
+
"来源理解": "Source interpretation",
|
|
138
|
+
"来源论文以及内容提供者、作者或整理者": "Source papers, content providers, authors and compilers",
|
|
139
|
+
"来源资料": "Source material",
|
|
140
|
+
"查看": "View ",
|
|
141
|
+
"查看全图": "Fit graph",
|
|
142
|
+
"查看全部 ": "Show all ",
|
|
143
|
+
"查看原论文 ↗": "View source paper ↗",
|
|
144
|
+
"查看实验:": "View experiment: ",
|
|
145
|
+
"查看范围 →": "Review scope →",
|
|
146
|
+
"样本": "Sample",
|
|
147
|
+
"检查点": "Checkpoint",
|
|
148
|
+
"概念": "Concept",
|
|
149
|
+
"概念、定义、理论框架,以及变量和指标的定义": "Concepts, definitions, theoretical frameworks, variables and metrics",
|
|
150
|
+
"概念与定义": "Concepts and definitions",
|
|
151
|
+
"模型": "Model",
|
|
152
|
+
"模型、数据与材料": "Models, data and materials",
|
|
153
|
+
"模型与检查点": "Models and checkpoints",
|
|
154
|
+
"正在加载完整记录…": "Loading complete records…",
|
|
155
|
+
"此浏览器无法保存草案。": "This browser cannot save the draft.",
|
|
156
|
+
"没有匹配内容,试试其他关键词。": "No matches. Try another search term.",
|
|
157
|
+
"没有匹配的关系": "No matching relations",
|
|
158
|
+
"活动": "Activity",
|
|
159
|
+
"派生自": "Derived from",
|
|
160
|
+
"涉及": "About",
|
|
161
|
+
"清空": "Clear",
|
|
162
|
+
"清空搜索": "Clear search",
|
|
163
|
+
"点问题看比较方式 · + 加入范围": "Click a question to inspect its comparison · + Add to scope",
|
|
164
|
+
"生成": "Generated",
|
|
165
|
+
"生成自": "Generated by",
|
|
166
|
+
"相关方法 ": "Related methods ",
|
|
167
|
+
"相关证据": "Related evidence",
|
|
168
|
+
"研究使用的模型、数据、提示、材料和工具": "Models, data, prompts, materials and tools used in the research",
|
|
169
|
+
"研究对象、材料、数据集、模型、仪器、代码和来源文献": "Research objects, materials, datasets, models, instruments, code and source literature",
|
|
170
|
+
"研究方案": "Research plan",
|
|
171
|
+
"研究概览": "Research overview",
|
|
172
|
+
"研究活动": "Research activity",
|
|
173
|
+
"研究脉络 ": "Research mainline ",
|
|
174
|
+
"研究计划 · 尚未执行": "Research plan · Not executed",
|
|
175
|
+
"研究评估": "Research assessment",
|
|
176
|
+
"研究试图回答的问题或目标": "The question or objective addressed by the research",
|
|
177
|
+
"研究问题": "Research question",
|
|
178
|
+
"终点": "Target",
|
|
179
|
+
"结果": "Result",
|
|
180
|
+
"结果与评价": "Results and assessments",
|
|
181
|
+
"缩小详情,显示图谱": "Shrink details to show graph",
|
|
182
|
+
"缺少输入:": "Missing input: ",
|
|
183
|
+
"节点图未能打开:": "Unable to open graph: ",
|
|
184
|
+
"范围与限制": "Scope and limitations",
|
|
185
|
+
"补充概念与解释": "Additional concepts and explanations",
|
|
186
|
+
"观察与判断": "Observations and criteria",
|
|
187
|
+
"观测": "Observation",
|
|
188
|
+
"观测与结果": "Observations and results",
|
|
189
|
+
"观点与解释": "Claims and explanations",
|
|
190
|
+
"视图控制": "View controls",
|
|
191
|
+
"解释假说": "Explains hypothesis",
|
|
192
|
+
"计划步骤": "Planned step",
|
|
193
|
+
"论文使用的方法及报告的研究活动": "Methods and research activities reported in the paper",
|
|
194
|
+
"论文原文": "Source paper",
|
|
195
|
+
"论文大纲": "Paper outline",
|
|
196
|
+
"论文报告的图表、观测和补充评价": "Figures, tables, observations and supplementary assessments reported in the paper",
|
|
197
|
+
"论文来源": "Source paper",
|
|
198
|
+
"论文来源与参与者": "Source papers and participants",
|
|
199
|
+
"论文节点图": "Paper graph",
|
|
200
|
+
"论文阅读地图": "Paper reading map",
|
|
201
|
+
"论证": "Argument",
|
|
202
|
+
"论证与证明": "Arguments and proofs",
|
|
203
|
+
"证据关联": "Evidence for",
|
|
204
|
+
"证据关联来自原文阅读,不表示已完成独立验证。": "This evidence connection comes from reading the source and does not indicate independent verification.",
|
|
205
|
+
"评估": "Assessment",
|
|
206
|
+
"详情 ": " details ",
|
|
207
|
+
"责任主体": "Responsible agent",
|
|
208
|
+
"资源": "Resource",
|
|
209
|
+
"起点": "Source",
|
|
210
|
+
"运行观测": "Execution observation",
|
|
211
|
+
"返回实验详情": "Return to experiment details",
|
|
212
|
+
"连接依据与主张的推导、证明或解释性论证": "Derivations, proofs or explanatory arguments connecting evidence and claims",
|
|
213
|
+
"适用条件与方法": "Applicable conditions and methods",
|
|
214
|
+
"选择": "Select",
|
|
215
|
+
"选择实验": "Select experiments",
|
|
216
|
+
"选择这项实验": "Select this experiment",
|
|
217
|
+
"遵循": "Follows",
|
|
218
|
+
"重新加载": "Reload",
|
|
219
|
+
"重试": "Retry",
|
|
220
|
+
"问题": "Question",
|
|
221
|
+
"问题与概念": "Questions and concepts",
|
|
222
|
+
"阅读分析": "Reading analysis",
|
|
223
|
+
"阅读核对": "Reading assessment",
|
|
224
|
+
"阅读脉络": "Reading mainline",
|
|
225
|
+
"需要": "Requires",
|
|
226
|
+
"预期产出": "Expected output",
|
|
227
|
+
"预期材料与产出": "Expected materials and outputs",
|
|
228
|
+
"Agent 生成 · 来源声明": "Agent-generated · Source declarations"
|
|
229
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"question": "研究问题",
|
|
3
|
+
"concept": "概念与定义",
|
|
4
|
+
"hypothesis": "假说与前提",
|
|
5
|
+
"claim": "主张",
|
|
6
|
+
"method": "方法",
|
|
7
|
+
"plan": "研究方案",
|
|
8
|
+
"activity": "研究活动",
|
|
9
|
+
"result": "观测与结果",
|
|
10
|
+
"argument": "论证与证明",
|
|
11
|
+
"assessment": "评估",
|
|
12
|
+
"resource": "对象与资源",
|
|
13
|
+
"agent": "责任主体",
|
|
14
|
+
"provenance": "Agent 生成 · 来源声明"
|
|
15
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import ts from './node_modules/typescript/lib/typescript.js';
|
|
3
|
+
const english=JSON.parse(await fs.readFile(new URL('./locales/en.json',import.meta.url),'utf8'));
|
|
4
|
+
const translate=text=>{
|
|
5
|
+
if(!/[\u4e00-\u9fff]/.test(text))return text;
|
|
6
|
+
if(!(text in english))throw Error(`Missing ArkGraph UI translation: ${JSON.stringify(text)}`);
|
|
7
|
+
return english[text];
|
|
8
|
+
};
|
|
9
|
+
// Translate only UI source literals, after JSX lowering. Scientific records stay unchanged.
|
|
10
|
+
export const localizationPlugin={name:'arkgraph-english',setup(build){
|
|
11
|
+
build.onLoad({filter:/ui\/arkgraph\/[^/]+\.(jsx|mjs)$/},async({path})=>{
|
|
12
|
+
const source=await fs.readFile(path,'utf8');
|
|
13
|
+
const result=ts.transpileModule(source,{fileName:path,compilerOptions:{target:ts.ScriptTarget.ESNext,module:ts.ModuleKind.ESNext,jsx:ts.JsxEmit.React},transformers:{after:[context=>root=>{
|
|
14
|
+
const f=context.factory;
|
|
15
|
+
function visit(node){
|
|
16
|
+
if(ts.isStringLiteral(node))return f.createStringLiteral(translate(node.text));
|
|
17
|
+
if(ts.isNoSubstitutionTemplateLiteral(node))return f.createNoSubstitutionTemplateLiteral(translate(node.text));
|
|
18
|
+
if(ts.isTemplateHead(node))return f.createTemplateHead(translate(node.text));
|
|
19
|
+
if(ts.isTemplateMiddle(node))return f.createTemplateMiddle(translate(node.text));
|
|
20
|
+
if(ts.isTemplateTail(node))return f.createTemplateTail(translate(node.text));
|
|
21
|
+
return ts.visitEachChild(node,visit,context);
|
|
22
|
+
}
|
|
23
|
+
return ts.visitNode(root,visit);
|
|
24
|
+
}]}});
|
|
25
|
+
return {contents:result.outputText,loader:'js'};
|
|
26
|
+
});
|
|
27
|
+
}};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import {MD} from './material-colors.mjs';
|
|
3
|
+
const swatches=Object.values(MD),neutrals=new Set(Object.entries(MD).filter(([k])=>k.startsWith('grey')).map(([,v])=>v));
|
|
4
|
+
const rgb=hex=>[1,3,5].map(i=>parseInt(hex.slice(i,i+2),16));
|
|
5
|
+
function closestColor(hex){
|
|
6
|
+
const values=rgb(hex);return swatches.reduce((best,next)=>{
|
|
7
|
+
const distance=c=>rgb(c).reduce((sum,v,i)=>sum+(v-values[i])**2,0);
|
|
8
|
+
return distance(next)<distance(best)?next:best;
|
|
9
|
+
},swatches[0]);
|
|
10
|
+
}
|
|
11
|
+
export function materialCss(source){
|
|
12
|
+
let css=source.replace(/#([\da-f]{8}|[\da-f]{6}|[\da-f]{4}|[\da-f]{3})\b/gi,(_,value)=>{
|
|
13
|
+
const expanded=value.length<=4?[...value].map(c=>c+c).join(''):value;
|
|
14
|
+
return closestColor('#'+expanded.slice(0,6))+(expanded.length===8?expanded.slice(6).toUpperCase():'');
|
|
15
|
+
});
|
|
16
|
+
// Keep small secondary text readable on the light surfaces.
|
|
17
|
+
css=css.replace(/(?<![-\w])color:\s*(#[\dA-F]{6})([\dA-F]{2})?\b/g,(_,value,opacity)=>{
|
|
18
|
+
if(neutrals.has(value)&&parseInt(value.slice(1,3),16)>parseInt(MD.grey700.slice(1,3),16))return 'color: '+MD.grey700;
|
|
19
|
+
return 'color: '+value+(opacity||'');
|
|
20
|
+
});
|
|
21
|
+
return css;
|
|
22
|
+
}
|
|
23
|
+
export const materialCssPlugin={name:'material-palette',setup(build){build.onLoad({filter:/\.css$/},async args=>({contents:materialCss(await fs.readFile(args.path,'utf8')),loader:'css'}));}};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Material Design 2014 palette, verified against Google MDC Web v14.0.0.
|
|
2
|
+
// https://github.com/material-components/material-components-web/blob/v14.0.0/packages/mdc-theme/_color-palette.scss
|
|
3
|
+
export const MATERIAL_SOURCE='https://github.com/material-components/material-components-web/blob/v14.0.0/packages/mdc-theme/_color-palette.scss';
|
|
4
|
+
export const MD=Object.freeze({
|
|
5
|
+
white:'#FFFFFF',black:'#000000',
|
|
6
|
+
grey50:'#FAFAFA',grey100:'#F5F5F5',grey200:'#EEEEEE',grey300:'#E0E0E0',grey400:'#BDBDBD',
|
|
7
|
+
grey500:'#9E9E9E',grey600:'#757575',grey700:'#616161',grey800:'#424242',grey900:'#212121',
|
|
8
|
+
blue50:'#E3F2FD',blue600:'#1E88E5',blue700:'#1976D2',
|
|
9
|
+
indigo50:'#E8EAF6',indigo500:'#3F51B5',
|
|
10
|
+
deepOrange50:'#FBE9E7',deepOrange700:'#E64A19',
|
|
11
|
+
teal50:'#E0F2F1',teal600:'#00897B',red50:'#FFEBEE',red700:'#D32F2F',
|
|
12
|
+
amber700:'#FFA000',lightGreen700:'#689F38',green600:'#43A047',purple500:'#9C27B0'
|
|
13
|
+
});
|
|
14
|
+
export const typeColors=Object.freeze({entity:MD.blue600,activity:MD.deepOrange700,assertion:MD.indigo500,agent:MD.teal600,unknown:MD.grey600});
|
|
15
|
+
export const coreLabels=Object.freeze({entity:'实体',activity:'活动',assertion:'断言',agent:'参与者',unknown:'未分类'});
|
|
16
|
+
export const coreHints=Object.freeze({entity:'方法、计划、数据、模型、材料、观测',activity:'实际发生的执行、采集、测量与分析',assertion:'主张、假说与评估',agent:'人、组织、智能体与运行节点',unknown:'暂未识别基础对象类型'});
|
|
17
|
+
const assertionRoles=new Set(['claim','hypothesis','assessment','evaluation','assertion']);
|
|
18
|
+
const activityRoles=new Set(['activity','execution','run','measurement-activity','analysis-activity']);
|
|
19
|
+
const agentRoles=new Set(['agent','participant','person','organization']);
|
|
20
|
+
const entityRoles=new Set(['entity','method','procedure','procedure-step','plan','model','checkpoint','dataset','sample','observation','material','code','source-work','file','instrument']);
|
|
21
|
+
export function coreTypeOf(record){
|
|
22
|
+
const explicit=record.recordType||record.type||record.raw?.type;
|
|
23
|
+
if(explicit){const value=String(explicit).toLowerCase(),type=value.match(/record-types\/(entity|activity|assertion|agent)\//)?.[1]||value;if(type in typeColors)return type;}
|
|
24
|
+
if(assertionRoles.has(record.role))return 'assertion';
|
|
25
|
+
if(activityRoles.has(record.role))return 'activity';
|
|
26
|
+
if(agentRoles.has(record.role))return 'agent';
|
|
27
|
+
if(entityRoles.has(record.role))return 'entity';
|
|
28
|
+
return 'unknown';
|
|
29
|
+
}
|
|
30
|
+
export const colorOf=record=>typeColors[coreTypeOf(record)];
|
|
31
|
+
export const alpha=(hex,opacity)=>hex+Math.round(Math.max(0,Math.min(1,opacity))*255).toString(16).padStart(2,'0');
|
|
32
|
+
export function shapeOf(record){
|
|
33
|
+
if(record.role==='hypothesis')return 'hypothesis';
|
|
34
|
+
if(['assessment','evaluation'].includes(record.role))return 'assessment';
|
|
35
|
+
if(['procedure','procedure-step','plan'].includes(record.role)||record.prospective)return 'plan';
|
|
36
|
+
if(record.role==='method')return 'method';
|
|
37
|
+
if(record.role==='observation')return 'observation';
|
|
38
|
+
return coreTypeOf(record)==='activity'?'activity':'circle';
|
|
39
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/* All authored colors come from the Material Design palette. */
|
|
2
|
+
:root { --paper:#FAFAFA; --ink:#212121; --muted:#757575; --border:#E0E0E0; --accent:#1976D2; --soft-accent:#E3F2FD; }
|
|
3
|
+
.graph-region { background-image:none; }
|
|
4
|
+
.graph-region:before { background:none; }
|
|
5
|
+
.brand-mark { color:#1976D2; background:#E3F2FD; }
|
|
6
|
+
.legend { align-items:center; }
|
|
7
|
+
.legend-title { font-size:10px; color:#616161; margin:0 7px; }
|
|
8
|
+
.legend i { width:9px; height:9px; }
|
|
9
|
+
.legend button { color:#424242; }
|
|
10
|
+
.legend small { color:#616161; }
|
|
11
|
+
.detail-eyebrow:before { background:var(--record-color,#757575); width:7px; height:7px; }
|
|
12
|
+
.expanded-controls button { color:#616161; }
|
|
13
|
+
.expanded-controls i { background:#9E9E9E !important; }
|
|
14
|
+
.graph-error { color:#D32F2F; background:#FFEBEE; border-color:#D32F2F; }
|
|
15
|
+
@media (max-width:530px) { .legend-title { font-size:9px; margin:0 4px; } }
|