@inflexa-ai/harness 0.17.0 → 0.19.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/dist/agents/report-builder.d.ts +2 -0
- package/dist/agents/report-builder.js +2 -0
- package/dist/agents/report-session-agent.d.ts +56 -0
- package/dist/agents/report-session-agent.js +72 -0
- package/dist/app/report-session-runtime.d.ts +72 -0
- package/dist/app/report-session-runtime.js +157 -0
- package/dist/app/spawn-report-session.d.ts +85 -0
- package/dist/app/spawn-report-session.js +83 -0
- package/dist/contracts/chat-events.d.ts +9 -0
- package/dist/contracts/index.d.ts +6 -2
- package/dist/contracts/index.js +3 -1
- package/dist/contracts/organ-system.d.ts +49 -0
- package/dist/contracts/organ-system.js +67 -0
- package/dist/contracts/report-blocks.d.ts +564 -0
- package/dist/contracts/report-blocks.js +117 -0
- package/dist/contracts/report-reference.d.ts +459 -0
- package/dist/contracts/report-reference.js +256 -0
- package/dist/contracts/schemas/chat-events.d.ts +2 -0
- package/dist/contracts/schemas/chat-events.js +2 -0
- package/dist/contracts/severity.d.ts +15 -0
- package/dist/contracts/severity.js +10 -0
- package/dist/contracts/target-dossier.d.ts +8675 -12972
- package/dist/contracts/target-dossier.js +534 -591
- package/dist/data/safety-panel-schema.d.ts +18 -5
- package/dist/data/safety-panel-schema.js +4 -4
- package/dist/execution/artifact-metadata.js +1 -0
- package/dist/execution/report-runner.js +1 -3
- package/dist/execution/run-synthesis.js +2 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +19 -0
- package/dist/lib/async-utils.d.ts +16 -4
- package/dist/lib/async-utils.js +20 -15
- package/dist/lib/host-concurrency.js +1 -0
- package/dist/loop/__fixtures__/scripted-provider.js +23 -2
- package/dist/loop/run-agent.js +58 -10
- package/dist/loop/tool-detail.d.ts +40 -0
- package/dist/loop/tool-detail.js +35 -3
- package/dist/loop/types.d.ts +13 -0
- package/dist/memory/thread-history.d.ts +10 -0
- package/dist/memory/thread-history.js +12 -1
- package/dist/memory/thread-store.d.ts +4 -4
- package/dist/memory/thread-store.js +18 -9
- package/dist/prompts/report-session.d.ts +1 -0
- package/dist/prompts/report-session.js +89 -0
- package/dist/prompts/target-assessment/briefs/executive-recommendation.d.ts +1 -1
- package/dist/prompts/target-assessment/briefs/executive-recommendation.js +5 -5
- package/dist/prompts/target-assessment/briefs/liability-bullets.d.ts +1 -1
- package/dist/prompts/target-assessment/briefs/liability-bullets.js +1 -1
- package/dist/prompts/target-assessment/briefs/target-organ-liabilities.d.ts +1 -1
- package/dist/prompts/target-assessment/briefs/target-organ-liabilities.js +11 -3
- package/dist/prompts/target-assessment/investigation/adversarial-critique.d.ts +1 -0
- package/dist/prompts/target-assessment/investigation/adversarial-critique.js +67 -0
- package/dist/prompts/target-assessment/investigation/claim-reverification.d.ts +1 -0
- package/dist/prompts/target-assessment/investigation/claim-reverification.js +49 -0
- package/dist/prompts/target-assessment/investigation/index.d.ts +3 -0
- package/dist/prompts/target-assessment/investigation/index.js +3 -0
- package/dist/prompts/target-assessment/investigation/mechanism-proposal.d.ts +1 -0
- package/dist/prompts/target-assessment/investigation/mechanism-proposal.js +49 -0
- package/dist/prompts/target-assessment/tox-voice/index.d.ts +1 -1
- package/dist/prompts/target-assessment/tox-voice/vocabulary.d.ts +8 -5
- package/dist/prompts/target-assessment/tox-voice/vocabulary.js +9 -20
- package/dist/providers/__fixtures__/session.d.ts +5 -4
- package/dist/providers/__fixtures__/session.js +4 -4
- package/dist/providers/ai-sdk.d.ts +77 -0
- package/dist/providers/ai-sdk.js +149 -19
- package/dist/providers/errors.d.ts +14 -0
- package/dist/providers/errors.js +103 -18
- package/dist/providers/types.d.ts +16 -0
- package/dist/providers/types.js +10 -1
- package/dist/report-model/block-walk.d.ts +56 -0
- package/dist/report-model/block-walk.js +89 -0
- package/dist/report-model/draft-finish.d.ts +60 -0
- package/dist/report-model/draft-finish.js +56 -0
- package/dist/report-model/draft-operations.d.ts +125 -0
- package/dist/report-model/draft-operations.js +341 -0
- package/dist/report-model/draft-read.d.ts +59 -0
- package/dist/report-model/draft-read.js +109 -0
- package/dist/report-model/draft.d.ts +51 -0
- package/dist/report-model/draft.js +32 -0
- package/dist/report-model/fixture-resolver.d.ts +8 -0
- package/dist/report-model/fixture-resolver.js +252 -0
- package/dist/report-model/pin-snapshot.d.ts +30 -0
- package/dist/report-model/pin-snapshot.js +40 -0
- package/dist/report-model/reference-resolver.d.ts +113 -0
- package/dist/report-model/reference-resolver.js +60 -0
- package/dist/report-model/structural-validation.d.ts +22 -0
- package/dist/report-model/structural-validation.js +68 -0
- package/dist/report-model/validate.d.ts +72 -0
- package/dist/report-model/validate.js +95 -0
- package/dist/report-render/chart.d.ts +33 -0
- package/dist/report-render/chart.js +538 -0
- package/dist/report-render/page.d.ts +127 -0
- package/dist/report-render/page.js +307 -0
- package/dist/report-render/references.d.ts +32 -0
- package/dist/report-render/references.js +44 -0
- package/dist/report-render/render.d.ts +25 -0
- package/dist/report-render/render.js +125 -0
- package/dist/report-render/script-json.d.ts +13 -0
- package/dist/report-render/script-json.js +15 -0
- package/dist/report-render/types.d.ts +39 -0
- package/dist/report-render/types.js +10 -0
- package/dist/report-render/value-bridge.d.ts +62 -0
- package/dist/report-render/value-bridge.js +82 -0
- package/dist/report-render/views/chart-view.d.ts +11 -0
- package/dist/report-render/views/chart-view.js +23 -0
- package/dist/report-render/views/page-view.d.ts +20 -0
- package/dist/report-render/views/page-view.js +49 -0
- package/dist/report-render/views/prose.d.ts +28 -0
- package/dist/report-render/views/prose.js +75 -0
- package/dist/report-render/views/references-view.d.ts +20 -0
- package/dist/report-render/views/references-view.js +64 -0
- package/dist/report-render/views/values.d.ts +42 -0
- package/dist/report-render/views/values.js +43 -0
- package/dist/runtime/assemble.d.ts +15 -0
- package/dist/runtime/assemble.js +28 -6
- package/dist/runtime/boot.d.ts +3 -3
- package/dist/runtime/boot.js +15 -4
- package/dist/runtime/dbos.d.ts +4 -4
- package/dist/state/artifacts.d.ts +16 -0
- package/dist/state/artifacts.js +18 -0
- package/dist/state/init.js +54 -0
- package/dist/state/purge-analysis.js +2 -0
- package/dist/state/report-session-state.d.ts +112 -0
- package/dist/state/report-session-state.js +150 -0
- package/dist/state/report-versions.d.ts +129 -0
- package/dist/state/report-versions.js +167 -0
- package/dist/state/snapshot-parse.d.ts +34 -0
- package/dist/state/snapshot-parse.js +82 -0
- package/dist/tasks/data-profile.js +1 -0
- package/dist/tools/ad-hoc-router.d.ts +7 -2
- package/dist/tools/ad-hoc-router.js +2 -1
- package/dist/tools/bio/chembl.js +1 -0
- package/dist/tools/bio/comptox.js +1 -0
- package/dist/tools/bio/drug-gene-interactions.js +1 -0
- package/dist/tools/bio/gene-disease-evidence.js +1 -0
- package/dist/tools/bio/gene-preclinical-profile.js +1 -0
- package/dist/tools/bio/keys.d.ts +3 -2
- package/dist/tools/bio/keys.js +3 -2
- package/dist/tools/bio/lookup-annotation.js +1 -0
- package/dist/tools/bio/opentargets.d.ts +3 -3
- package/dist/tools/bio/opentargets.js +4 -3
- package/dist/tools/bio/pubchem.js +1 -0
- package/dist/tools/bio/search-clinical-trials.js +1 -0
- package/dist/tools/bio/search-faers.js +1 -0
- package/dist/tools/bio/search-geo-datasets.js +1 -0
- package/dist/tools/bio/search-interactions.js +1 -0
- package/dist/tools/bio/target-safety.d.ts +4 -6
- package/dist/tools/bio/target-safety.js +7 -6
- package/dist/tools/define-tool.d.ts +19 -12
- package/dist/tools/define-tool.js +4 -2
- package/dist/tools/display/show-user.js +1 -0
- package/dist/tools/iterate-report.js +2 -0
- package/dist/tools/lib/chembl-client.d.ts +2 -0
- package/dist/tools/lib/chembl-client.js +1 -0
- package/dist/tools/lib/monarch-client.d.ts +42 -0
- package/dist/tools/lib/monarch-client.js +100 -0
- package/dist/tools/report/build-report.js +1 -0
- package/dist/tools/report/mint-preview-url.js +1 -0
- package/dist/tools/report/preview-snapshot.js +1 -0
- package/dist/tools/report/submit-report.js +1 -0
- package/dist/tools/report/version-fs.js +4 -0
- package/dist/tools/report-authoring/authoring-tools.d.ts +241 -0
- package/dist/tools/report-authoring/authoring-tools.js +460 -0
- package/dist/tools/report-session/index.d.ts +8 -0
- package/dist/tools/report-session/index.js +8 -0
- package/dist/tools/report-session/preview-report.d.ts +90 -0
- package/dist/tools/report-session/preview-report.js +245 -0
- package/dist/tools/research/context7-docs.js +2 -0
- package/dist/tools/research/generate-analogy-report.js +1 -0
- package/dist/tools/research/generate-plan.js +7 -2
- package/dist/tools/research/inspect-data-profile.js +4 -0
- package/dist/tools/research/literature-reviewer.js +1 -0
- package/dist/tools/research/search-arxiv.js +1 -0
- package/dist/tools/research/search-github-repos.js +1 -0
- package/dist/tools/research/search-semantic-scholar.js +1 -0
- package/dist/tools/sandbox/list-available-packages.js +23 -0
- package/dist/tools/sandbox/list-available-refs.js +36 -0
- package/dist/tools/sandbox/report-blocker.js +1 -0
- package/dist/tools/sandbox/skills.js +2 -0
- package/dist/tools/workspace/file-stat.js +1 -0
- package/dist/tools/workspace/show-file.js +2 -0
- package/dist/tools/workspace/show-plan.js +1 -0
- package/dist/workflows/execute-analysis.d.ts +5 -1
- package/dist/workflows/execute-analysis.js +5 -5
- package/dist/workflows/execute-target-assessment.d.ts +13 -2
- package/dist/workflows/execute-target-assessment.js +78 -16
- package/dist/workflows/target-assessment/assemblers/index.d.ts +1 -1
- package/dist/workflows/target-assessment/assemblers/index.js +1 -1
- package/dist/workflows/target-assessment/assemblers/literature.d.ts +9 -27
- package/dist/workflows/target-assessment/assemblers/literature.js +32 -48
- package/dist/workflows/target-assessment/assemblers/orchestrator.d.ts +17 -9
- package/dist/workflows/target-assessment/assemblers/orchestrator.js +195 -85
- package/dist/workflows/target-assessment/assemblers/safety.d.ts +70 -48
- package/dist/workflows/target-assessment/assemblers/safety.js +125 -42
- package/dist/workflows/target-assessment/collectors/index.d.ts +5 -2
- package/dist/workflows/target-assessment/collectors/index.js +48 -5
- package/dist/workflows/target-assessment/coverage.d.ts +43 -27
- package/dist/workflows/target-assessment/coverage.js +33 -29
- package/dist/workflows/target-assessment/fanout/index.js +1 -0
- package/dist/workflows/target-assessment/investigation/index.d.ts +97 -0
- package/dist/workflows/target-assessment/investigation/index.js +419 -0
- package/dist/workflows/target-assessment/lib/approval-precedents.d.ts +26 -5
- package/dist/workflows/target-assessment/lib/approval-precedents.js +95 -29
- package/dist/workflows/target-assessment/lib/citation-validator.js +1 -1
- package/dist/workflows/target-assessment/lib/clinical-consequence-annotator.d.ts +2 -2
- package/dist/workflows/target-assessment/lib/clinical-evidence-attribution.d.ts +2 -3
- package/dist/workflows/target-assessment/lib/clinical-evidence-attribution.js +0 -4
- package/dist/workflows/target-assessment/lib/compute-derived.d.ts +6 -5
- package/dist/workflows/target-assessment/lib/compute-derived.js +14 -5
- package/dist/workflows/target-assessment/lib/family-complex-supplement.d.ts +5 -6
- package/dist/workflows/target-assessment/lib/family-complex-supplement.js +2 -3
- package/dist/workflows/target-assessment/lib/fda-label-safety.d.ts +72 -0
- package/dist/workflows/target-assessment/lib/fda-label-safety.js +166 -0
- package/dist/workflows/target-assessment/lib/heterodimer-filter.d.ts +0 -9
- package/dist/workflows/target-assessment/lib/heterodimer-filter.js +0 -10
- package/dist/workflows/target-assessment/lib/hpo-organ-map.d.ts +34 -0
- package/dist/workflows/target-assessment/lib/hpo-organ-map.js +63 -0
- package/dist/workflows/target-assessment/lib/impc-organ-map.d.ts +19 -0
- package/dist/workflows/target-assessment/lib/impc-organ-map.js +39 -0
- package/dist/workflows/target-assessment/lib/meddra-organ-map.d.ts +24 -14
- package/dist/workflows/target-assessment/lib/meddra-organ-map.js +59 -47
- package/dist/workflows/target-assessment/lib/recommendation-sanitizer.js +1 -1
- package/dist/workflows/target-assessment/lib/regulatory-actions.d.ts +2 -3
- package/dist/workflows/target-assessment/lib/regulatory-actions.js +33 -4
- package/dist/workflows/target-assessment/lib/safety-corroboration.d.ts +44 -0
- package/dist/workflows/target-assessment/lib/safety-corroboration.js +273 -0
- package/dist/workflows/target-assessment/lib/target-identity-filter.d.ts +5 -7
- package/dist/workflows/target-assessment/lib/target-identity-filter.js +5 -7
- package/dist/workflows/target-assessment/metrics.d.ts +1 -6
- package/dist/workflows/target-assessment/metrics.js +1 -13
- package/dist/workflows/target-assessment/phase4-assemble.d.ts +2147 -807
- package/dist/workflows/target-assessment/phase4-assemble.js +19 -19
- package/dist/workflows/target-assessment/phase5-persist.d.ts +20 -21
- package/dist/workflows/target-assessment/phase5-persist.js +56 -173
- package/dist/workflows/target-assessment/schemas.d.ts +46 -1
- package/dist/workflows/target-assessment/schemas.js +19 -0
- package/dist/workflows/target-assessment/steps/fanout/polypharm-for-one-modulator-step.d.ts +1 -0
- package/dist/workflows/target-assessment/steps/fanout/polypharm-for-one-modulator-step.js +2 -0
- package/dist/workflows/target-assessment/steps/phase2-aggregate.d.ts +26 -62
- package/dist/workflows/target-assessment/steps/phase2-aggregate.js +0 -4
- package/dist/workflows/target-assessment/steps/phase3-aggregate.d.ts +27 -154
- package/dist/workflows/target-assessment/steps/phase3-aggregate.js +0 -6
- package/dist/workflows/target-assessment/steps/synthesis/diagnostics.d.ts +0 -6
- package/dist/workflows/target-assessment/steps/synthesis/diagnostics.js +0 -18
- package/dist/workflows/target-assessment/sub-workflows/per-modulator-polypharm.d.ts +1 -0
- package/dist/workflows/target-assessment/synthesis/index.d.ts +52 -5
- package/dist/workflows/target-assessment/synthesis/index.js +4 -1
- package/dist/workflows/target-assessment/synthesis-probes.d.ts +3 -3
- package/package.json +4 -1
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The page constants: the CDN pins, the inline style, the ECharts theme, and the chart bootstrap.
|
|
3
|
+
*
|
|
4
|
+
* These constants are copies. The old template pack at `templates/report-html` holds the source, and the
|
|
5
|
+
* old render path owns that directory. The renderer never reads that directory at run time, thus the
|
|
6
|
+
* output stays a pure function of its inputs. A copy that drifts is a maintenance cost, and it is the
|
|
7
|
+
* price of a page with no local asset and no template engine.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* The head references: the Tailwind runtime, the ECharts runtime, the two fonts, and the preconnect. Each
|
|
11
|
+
* tag carries the pinned version and, where the source pins one, the integrity hash. The bytes are exact
|
|
12
|
+
* copies, thus the page stays deterministic and the hashes stay valid.
|
|
13
|
+
*/
|
|
14
|
+
export declare const CDN_HEAD = "<script src=\"https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.3.2/dist/index.global.min.js\" integrity=\"sha384-shaHAtPgz0ulP7R/YmFe0nZtC8FxdhJPi73vwJQcADVttxvHLJBJt/pjzkLSbIvL\" crossorigin=\"anonymous\"></script>\n<script src=\"https://cdn.jsdelivr.net/npm/echarts@5.5.1/dist/echarts.min.js\" integrity=\"sha384-Mx5lkUEQPM1pOJCwFtUICyX45KNojXbkWdYhkKUKsbv391mavbfoAmONbzkgYPzR\" crossorigin=\"anonymous\"></script>\n<link rel=\"preconnect\" href=\"https://cdn.jsdelivr.net\" crossorigin>\n<link href=\"https://cdn.jsdelivr.net/npm/@fontsource-variable/space-grotesk@5.1.1/index.css\" rel=\"stylesheet\" integrity=\"sha384-b3Dtcpab/ltw+oDnVHstCCa9ENEb2hKouCSRAfb8o0ROkWOb2uNWYG6+l7HGrHmG\" crossorigin=\"anonymous\">\n<link href=\"https://cdn.jsdelivr.net/npm/@fontsource-variable/ibm-plex-mono@5.1.1/index.css\" rel=\"stylesheet\">";
|
|
15
|
+
/**
|
|
16
|
+
* The style rules of the page. The renderer inlines them in one `<style>` block, thus the page holds the
|
|
17
|
+
* whole design token set and every component rule with no external stylesheet.
|
|
18
|
+
*/
|
|
19
|
+
export declare const PAGE_CSS = "/* \u2500\u2500 Color Palette \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n:root {\n /* Primary Scale */\n --color-primary-50: #f0f1fe; /* Tag bg, CTA section bg */\n --color-primary-100: #dde0fc;\n --color-primary-200: #bcc2f9; /* Badge borders, corner accent default */\n --color-primary-300: #9ba5f5; /* Corner button accent default */\n --color-primary-400: #7987f0; /* Section illustration icons */\n --color-primary-500: #576dea; /* Primary action, section labels, links */\n --color-primary-600: #4458d4; /* Button hover */\n --color-primary-700: #3545b0; /* Tag text on primary-50 bg */\n\n /* Text */\n --color-heading: #0f172a; /* slate-900 \u2014 all headings */\n --color-text: #475569; /* slate-600 \u2014 body text */\n --color-text-secondary: #64748b; /* slate-500 \u2014 captions, metadata */\n --color-text-muted: #94a3b8; /* slate-400 \u2014 timestamps, footnotes */\n\n /* Surface */\n --color-bg: #ffffff; /* Page background (white) */\n --color-bg-alt: #f8fafc; /* Alternating section bg (slate-50) */\n --color-card: #ffffff; /* Cards (white) */\n --color-border: #e2e8f0; /* slate-200 \u2014 card borders, dividers */\n --color-border-hover: #cbd5e1; /* slate-300 \u2014 hover borders */\n\n /* Data Visualization */\n --color-up: #ef4444; /* Red 500 \u2014 upregulated, positive */\n --color-down: #576dea; /* Primary 500 \u2014 downregulated, negative */\n --color-ns: #94a3b8; /* Slate 400 \u2014 not significant */\n\n /* Semantic (Tags \u2014 solid bg + colored text) */\n --color-high-bg: #f0fdf4; /* green-50 */\n --color-high-text: #15803d; /* green-700 */\n --color-medium-bg: #fffbeb; /* amber-50 */\n --color-medium-text:#b45309; /* amber-700 */\n --color-low-bg: #fef2f2; /* red-50 */\n --color-low-text: #b91c1c; /* red-700 */\n\n /* Stat card accent colors */\n --color-stat-primary: #576dea;\n --color-stat-green: #22c55e;\n --color-stat-red: #ef4444;\n --color-stat-purple: #a78bfa;\n --color-stat-amber: #f59e0b;\n}\n\n/* \u2500\u2500 Typography \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nbody {\n font-family: 'Space Grotesk Variable', system-ui, sans-serif;\n font-size: 16px;\n line-height: 1.6;\n color: var(--color-text);\n}\n\n.font-mono, code, .gene {\n font-family: 'IBM Plex Mono Variable', ui-monospace, monospace;\n}\n\n/* Rule: Headings use font-sans (Space Grotesk), never font-mono.\n Labels, tags, badges, data, product names always use font-mono (IBM Plex Mono). */\n\n/* \u2500\u2500 Corner Accent Cards \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.corner-accents {\n position: relative;\n border: 1px solid var(--color-border);\n background: var(--color-card);\n /* No border-radius \u2014 square corners */\n}\n.corner-accents::before,\n.corner-accents::after {\n content: '';\n position: absolute;\n width: 20px;\n height: 20px;\n transition: all 0.3s ease;\n pointer-events: none;\n}\n.corner-accents::before {\n top: -1px; left: -1px;\n border-top: 2px solid var(--color-primary-200);\n border-left: 2px solid var(--color-primary-200);\n}\n.corner-accents::after {\n bottom: -1px; right: -1px;\n border-bottom: 2px solid var(--color-primary-200);\n border-right: 2px solid var(--color-primary-200);\n}\n.corner-accents:hover::before,\n.corner-accents:hover::after {\n width: 28px;\n height: 28px;\n border-color: var(--color-primary-500);\n}\n.corner-accents:hover {\n box-shadow: 0 4px 12px -4px rgba(15, 23, 42, 0.08);\n}\n\n/* \u2500\u2500 Window Chrome Panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* Exception: uses rounded-xl (only rounded component) */\n.window-chrome {\n border-radius: 12px;\n border: 1px solid var(--color-border);\n background: var(--color-card);\n box-shadow: 0 8px 30px -8px rgba(15,23,42,0.08), 0 4px 12px -4px rgba(15,23,42,0.04);\n transition: all 0.5s ease;\n}\n.window-chrome:hover {\n transform: translateY(-4px);\n box-shadow: 0 25px 50px -12px rgba(15,23,42,0.18), 0 12px 24px -8px rgba(15,23,42,0.1);\n border-color: var(--color-border-hover);\n}\n.window-chrome .chrome-dots span { transition: background-color 0.3s ease; }\n.window-chrome:hover .chrome-dots .dot-1 { background-color: #fb7185; }\n.window-chrome:hover .chrome-dots .dot-2 { background-color: #fbbf24; }\n.window-chrome:hover .chrome-dots .dot-3 { background-color: #4ade80; }\n\n/* \u2500\u2500 Terminal Card \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.terminal-card {\n position: relative;\n overflow: hidden;\n}\n.terminal-card .terminal-header {\n background: #1e293b; /* slate-800 */\n}\n.terminal-card .terminal-body-dark {\n background: #0f172a; /* slate-900 */\n color: #e2e8f0;\n}\n.terminal-card::after {\n content: '';\n position: absolute;\n inset: 0;\n pointer-events: none;\n opacity: 0;\n background: repeating-linear-gradient(\n 0deg, transparent, transparent 2px,\n rgba(148, 163, 184, 0.03) 2px, rgba(148, 163, 184, 0.03) 4px\n );\n transition: opacity 0.3s ease;\n}\n.terminal-card:hover::after { opacity: 1; }\n\n/* \u2500\u2500 Block Progress Bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* Usage: <span class=\"block-progress\"><span class=\"filled-high\">\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588</span><span class=\"empty\">\u2591\u2591</span> <span class=\"score\">0.82</span></span> */\n.block-progress {\n font-family: 'IBM Plex Mono Variable', ui-monospace, monospace;\n font-size: 14px;\n}\n.block-progress .filled-high { color: var(--color-primary-500); } /* \u2265 0.8 */\n.block-progress .filled-mid { color: #f59e0b; } /* \u2265 0.6 */\n.block-progress .filled-low { color: #f43f5e; } /* < 0.6 */\n.block-progress .empty { color: #e2e8f0; }\n.block-progress .score { font-size: 12px; color: #94a3b8; margin-left: 8px; }\n\n/* \u2500\u2500 Sidebar Navigation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* When a sidebar is rendered (#report-sidebar), the body shifts right on lg+\n to make room. Styling matches the corner-accent / mono-label language. */\n@media (min-width: 1024px) {\n body:has(#report-sidebar) { padding-left: 15rem; }\n}\n.sidebar-link {\n border-left: 2px solid transparent;\n}\n.sidebar-link.active {\n color: var(--color-primary-500);\n background-color: var(--color-primary-50);\n border-left-color: var(--color-primary-500);\n font-weight: 600;\n}\n\n/* \u2500\u2500 Insight Box \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.insight-box {\n background: var(--color-card);\n border: 1px solid var(--color-border);\n /* No border-radius \u2014 uses corner-accents class */\n}\n\n/* \u2500\u2500 Section Textures \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* Apply to <section>: combine one pattern + noise, e.g. class=\"texture-dots texture-noise\" */\n/* Textures should be felt, not seen \u2014 low opacity, faded edges */\n\n/* \u2500\u2500 Fade-In \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.fade-in {\n opacity: 0;\n transform: translateY(20px);\n transition: opacity 0.7s ease-out, transform 0.7s ease-out;\n}\n.fade-in-visible {\n opacity: 1;\n transform: translateY(0);\n}\n/* Stagger with data-delay attribute: <div class=\"fade-in\" data-delay=\"100\"> */";
|
|
20
|
+
/**
|
|
21
|
+
* The registered name of the ECharts theme. The skeleton registers the theme under this name, and the
|
|
22
|
+
* bootstrap reads the same name. One source prevents a silent mismatch between the two sites.
|
|
23
|
+
*/
|
|
24
|
+
export declare const ECHARTS_THEME_NAME = "inflexa";
|
|
25
|
+
/**
|
|
26
|
+
* The ECharts theme as a plain object. The renderer serializes this object and registers it, thus the
|
|
27
|
+
* theme never rides a JSON file and no run-time read is necessary. The palette and the axis styles mirror
|
|
28
|
+
* the light design tokens of the page.
|
|
29
|
+
*/
|
|
30
|
+
export declare const ECHARTS_THEME: {
|
|
31
|
+
color: string[];
|
|
32
|
+
backgroundColor: string;
|
|
33
|
+
textStyle: {
|
|
34
|
+
fontFamily: string;
|
|
35
|
+
fontSize: number;
|
|
36
|
+
color: string;
|
|
37
|
+
};
|
|
38
|
+
title: {
|
|
39
|
+
show: boolean;
|
|
40
|
+
};
|
|
41
|
+
legend: {
|
|
42
|
+
bottom: number;
|
|
43
|
+
textStyle: {
|
|
44
|
+
fontSize: number;
|
|
45
|
+
color: string;
|
|
46
|
+
};
|
|
47
|
+
itemGap: number;
|
|
48
|
+
itemWidth: number;
|
|
49
|
+
itemHeight: number;
|
|
50
|
+
};
|
|
51
|
+
grid: {
|
|
52
|
+
left: number;
|
|
53
|
+
right: number;
|
|
54
|
+
top: number;
|
|
55
|
+
bottom: number;
|
|
56
|
+
containLabel: boolean;
|
|
57
|
+
};
|
|
58
|
+
tooltip: {
|
|
59
|
+
backgroundColor: string;
|
|
60
|
+
borderColor: string;
|
|
61
|
+
textStyle: {
|
|
62
|
+
color: string;
|
|
63
|
+
fontSize: number;
|
|
64
|
+
};
|
|
65
|
+
extraCssText: string;
|
|
66
|
+
};
|
|
67
|
+
toolbox: {
|
|
68
|
+
feature: {
|
|
69
|
+
saveAsImage: {
|
|
70
|
+
title: string;
|
|
71
|
+
pixelRatio: number;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
iconStyle: {
|
|
75
|
+
borderColor: string;
|
|
76
|
+
};
|
|
77
|
+
right: number;
|
|
78
|
+
top: number;
|
|
79
|
+
};
|
|
80
|
+
xAxis: {
|
|
81
|
+
axisLine: {
|
|
82
|
+
lineStyle: {
|
|
83
|
+
color: string;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
axisTick: {
|
|
87
|
+
lineStyle: {
|
|
88
|
+
color: string;
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
axisLabel: {
|
|
92
|
+
color: string;
|
|
93
|
+
fontSize: number;
|
|
94
|
+
};
|
|
95
|
+
splitLine: {
|
|
96
|
+
lineStyle: {
|
|
97
|
+
color: string;
|
|
98
|
+
type: string;
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
yAxis: {
|
|
103
|
+
axisLine: {
|
|
104
|
+
show: boolean;
|
|
105
|
+
};
|
|
106
|
+
axisTick: {
|
|
107
|
+
show: boolean;
|
|
108
|
+
};
|
|
109
|
+
axisLabel: {
|
|
110
|
+
color: string;
|
|
111
|
+
fontSize: number;
|
|
112
|
+
};
|
|
113
|
+
splitLine: {
|
|
114
|
+
lineStyle: {
|
|
115
|
+
color: string;
|
|
116
|
+
type: string;
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* The page-side script that wires each chart. It finds every chart container, reads the option JSON from
|
|
123
|
+
* the sibling `<script type="application/json">` element, and initializes ECharts with the registered
|
|
124
|
+
* theme. The skeleton registers the theme before this script runs. A resize handler keeps each chart
|
|
125
|
+
* fit to the window.
|
|
126
|
+
*/
|
|
127
|
+
export declare const CHART_BOOTSTRAP: string;
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The page constants: the CDN pins, the inline style, the ECharts theme, and the chart bootstrap.
|
|
3
|
+
*
|
|
4
|
+
* These constants are copies. The old template pack at `templates/report-html` holds the source, and the
|
|
5
|
+
* old render path owns that directory. The renderer never reads that directory at run time, thus the
|
|
6
|
+
* output stays a pure function of its inputs. A copy that drifts is a maintenance cost, and it is the
|
|
7
|
+
* price of a page with no local asset and no template engine.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* The head references: the Tailwind runtime, the ECharts runtime, the two fonts, and the preconnect. Each
|
|
11
|
+
* tag carries the pinned version and, where the source pins one, the integrity hash. The bytes are exact
|
|
12
|
+
* copies, thus the page stays deterministic and the hashes stay valid.
|
|
13
|
+
*/
|
|
14
|
+
export const CDN_HEAD = `<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.3.2/dist/index.global.min.js" integrity="sha384-shaHAtPgz0ulP7R/YmFe0nZtC8FxdhJPi73vwJQcADVttxvHLJBJt/pjzkLSbIvL" crossorigin="anonymous"></script>
|
|
15
|
+
<script src="https://cdn.jsdelivr.net/npm/echarts@5.5.1/dist/echarts.min.js" integrity="sha384-Mx5lkUEQPM1pOJCwFtUICyX45KNojXbkWdYhkKUKsbv391mavbfoAmONbzkgYPzR" crossorigin="anonymous"></script>
|
|
16
|
+
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin>
|
|
17
|
+
<link href="https://cdn.jsdelivr.net/npm/@fontsource-variable/space-grotesk@5.1.1/index.css" rel="stylesheet" integrity="sha384-b3Dtcpab/ltw+oDnVHstCCa9ENEb2hKouCSRAfb8o0ROkWOb2uNWYG6+l7HGrHmG" crossorigin="anonymous">
|
|
18
|
+
<link href="https://cdn.jsdelivr.net/npm/@fontsource-variable/ibm-plex-mono@5.1.1/index.css" rel="stylesheet">`;
|
|
19
|
+
/**
|
|
20
|
+
* The style rules of the page. The renderer inlines them in one `<style>` block, thus the page holds the
|
|
21
|
+
* whole design token set and every component rule with no external stylesheet.
|
|
22
|
+
*/
|
|
23
|
+
export const PAGE_CSS = `/* ── Color Palette ────────────────────────────────────── */
|
|
24
|
+
:root {
|
|
25
|
+
/* Primary Scale */
|
|
26
|
+
--color-primary-50: #f0f1fe; /* Tag bg, CTA section bg */
|
|
27
|
+
--color-primary-100: #dde0fc;
|
|
28
|
+
--color-primary-200: #bcc2f9; /* Badge borders, corner accent default */
|
|
29
|
+
--color-primary-300: #9ba5f5; /* Corner button accent default */
|
|
30
|
+
--color-primary-400: #7987f0; /* Section illustration icons */
|
|
31
|
+
--color-primary-500: #576dea; /* Primary action, section labels, links */
|
|
32
|
+
--color-primary-600: #4458d4; /* Button hover */
|
|
33
|
+
--color-primary-700: #3545b0; /* Tag text on primary-50 bg */
|
|
34
|
+
|
|
35
|
+
/* Text */
|
|
36
|
+
--color-heading: #0f172a; /* slate-900 — all headings */
|
|
37
|
+
--color-text: #475569; /* slate-600 — body text */
|
|
38
|
+
--color-text-secondary: #64748b; /* slate-500 — captions, metadata */
|
|
39
|
+
--color-text-muted: #94a3b8; /* slate-400 — timestamps, footnotes */
|
|
40
|
+
|
|
41
|
+
/* Surface */
|
|
42
|
+
--color-bg: #ffffff; /* Page background (white) */
|
|
43
|
+
--color-bg-alt: #f8fafc; /* Alternating section bg (slate-50) */
|
|
44
|
+
--color-card: #ffffff; /* Cards (white) */
|
|
45
|
+
--color-border: #e2e8f0; /* slate-200 — card borders, dividers */
|
|
46
|
+
--color-border-hover: #cbd5e1; /* slate-300 — hover borders */
|
|
47
|
+
|
|
48
|
+
/* Data Visualization */
|
|
49
|
+
--color-up: #ef4444; /* Red 500 — upregulated, positive */
|
|
50
|
+
--color-down: #576dea; /* Primary 500 — downregulated, negative */
|
|
51
|
+
--color-ns: #94a3b8; /* Slate 400 — not significant */
|
|
52
|
+
|
|
53
|
+
/* Semantic (Tags — solid bg + colored text) */
|
|
54
|
+
--color-high-bg: #f0fdf4; /* green-50 */
|
|
55
|
+
--color-high-text: #15803d; /* green-700 */
|
|
56
|
+
--color-medium-bg: #fffbeb; /* amber-50 */
|
|
57
|
+
--color-medium-text:#b45309; /* amber-700 */
|
|
58
|
+
--color-low-bg: #fef2f2; /* red-50 */
|
|
59
|
+
--color-low-text: #b91c1c; /* red-700 */
|
|
60
|
+
|
|
61
|
+
/* Stat card accent colors */
|
|
62
|
+
--color-stat-primary: #576dea;
|
|
63
|
+
--color-stat-green: #22c55e;
|
|
64
|
+
--color-stat-red: #ef4444;
|
|
65
|
+
--color-stat-purple: #a78bfa;
|
|
66
|
+
--color-stat-amber: #f59e0b;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/* ── Typography ───────────────────────────────────────── */
|
|
70
|
+
body {
|
|
71
|
+
font-family: 'Space Grotesk Variable', system-ui, sans-serif;
|
|
72
|
+
font-size: 16px;
|
|
73
|
+
line-height: 1.6;
|
|
74
|
+
color: var(--color-text);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.font-mono, code, .gene {
|
|
78
|
+
font-family: 'IBM Plex Mono Variable', ui-monospace, monospace;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/* Rule: Headings use font-sans (Space Grotesk), never font-mono.
|
|
82
|
+
Labels, tags, badges, data, product names always use font-mono (IBM Plex Mono). */
|
|
83
|
+
|
|
84
|
+
/* ── Corner Accent Cards ─────────────────────────────── */
|
|
85
|
+
.corner-accents {
|
|
86
|
+
position: relative;
|
|
87
|
+
border: 1px solid var(--color-border);
|
|
88
|
+
background: var(--color-card);
|
|
89
|
+
/* No border-radius — square corners */
|
|
90
|
+
}
|
|
91
|
+
.corner-accents::before,
|
|
92
|
+
.corner-accents::after {
|
|
93
|
+
content: '';
|
|
94
|
+
position: absolute;
|
|
95
|
+
width: 20px;
|
|
96
|
+
height: 20px;
|
|
97
|
+
transition: all 0.3s ease;
|
|
98
|
+
pointer-events: none;
|
|
99
|
+
}
|
|
100
|
+
.corner-accents::before {
|
|
101
|
+
top: -1px; left: -1px;
|
|
102
|
+
border-top: 2px solid var(--color-primary-200);
|
|
103
|
+
border-left: 2px solid var(--color-primary-200);
|
|
104
|
+
}
|
|
105
|
+
.corner-accents::after {
|
|
106
|
+
bottom: -1px; right: -1px;
|
|
107
|
+
border-bottom: 2px solid var(--color-primary-200);
|
|
108
|
+
border-right: 2px solid var(--color-primary-200);
|
|
109
|
+
}
|
|
110
|
+
.corner-accents:hover::before,
|
|
111
|
+
.corner-accents:hover::after {
|
|
112
|
+
width: 28px;
|
|
113
|
+
height: 28px;
|
|
114
|
+
border-color: var(--color-primary-500);
|
|
115
|
+
}
|
|
116
|
+
.corner-accents:hover {
|
|
117
|
+
box-shadow: 0 4px 12px -4px rgba(15, 23, 42, 0.08);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/* ── Window Chrome Panel ─────────────────────────────── */
|
|
121
|
+
/* Exception: uses rounded-xl (only rounded component) */
|
|
122
|
+
.window-chrome {
|
|
123
|
+
border-radius: 12px;
|
|
124
|
+
border: 1px solid var(--color-border);
|
|
125
|
+
background: var(--color-card);
|
|
126
|
+
box-shadow: 0 8px 30px -8px rgba(15,23,42,0.08), 0 4px 12px -4px rgba(15,23,42,0.04);
|
|
127
|
+
transition: all 0.5s ease;
|
|
128
|
+
}
|
|
129
|
+
.window-chrome:hover {
|
|
130
|
+
transform: translateY(-4px);
|
|
131
|
+
box-shadow: 0 25px 50px -12px rgba(15,23,42,0.18), 0 12px 24px -8px rgba(15,23,42,0.1);
|
|
132
|
+
border-color: var(--color-border-hover);
|
|
133
|
+
}
|
|
134
|
+
.window-chrome .chrome-dots span { transition: background-color 0.3s ease; }
|
|
135
|
+
.window-chrome:hover .chrome-dots .dot-1 { background-color: #fb7185; }
|
|
136
|
+
.window-chrome:hover .chrome-dots .dot-2 { background-color: #fbbf24; }
|
|
137
|
+
.window-chrome:hover .chrome-dots .dot-3 { background-color: #4ade80; }
|
|
138
|
+
|
|
139
|
+
/* ── Terminal Card ───────────────────────────────────── */
|
|
140
|
+
.terminal-card {
|
|
141
|
+
position: relative;
|
|
142
|
+
overflow: hidden;
|
|
143
|
+
}
|
|
144
|
+
.terminal-card .terminal-header {
|
|
145
|
+
background: #1e293b; /* slate-800 */
|
|
146
|
+
}
|
|
147
|
+
.terminal-card .terminal-body-dark {
|
|
148
|
+
background: #0f172a; /* slate-900 */
|
|
149
|
+
color: #e2e8f0;
|
|
150
|
+
}
|
|
151
|
+
.terminal-card::after {
|
|
152
|
+
content: '';
|
|
153
|
+
position: absolute;
|
|
154
|
+
inset: 0;
|
|
155
|
+
pointer-events: none;
|
|
156
|
+
opacity: 0;
|
|
157
|
+
background: repeating-linear-gradient(
|
|
158
|
+
0deg, transparent, transparent 2px,
|
|
159
|
+
rgba(148, 163, 184, 0.03) 2px, rgba(148, 163, 184, 0.03) 4px
|
|
160
|
+
);
|
|
161
|
+
transition: opacity 0.3s ease;
|
|
162
|
+
}
|
|
163
|
+
.terminal-card:hover::after { opacity: 1; }
|
|
164
|
+
|
|
165
|
+
/* ── Block Progress Bar ──────────────────────────────── */
|
|
166
|
+
/* Usage: <span class="block-progress"><span class="filled-high">████████</span><span class="empty">░░</span> <span class="score">0.82</span></span> */
|
|
167
|
+
.block-progress {
|
|
168
|
+
font-family: 'IBM Plex Mono Variable', ui-monospace, monospace;
|
|
169
|
+
font-size: 14px;
|
|
170
|
+
}
|
|
171
|
+
.block-progress .filled-high { color: var(--color-primary-500); } /* ≥ 0.8 */
|
|
172
|
+
.block-progress .filled-mid { color: #f59e0b; } /* ≥ 0.6 */
|
|
173
|
+
.block-progress .filled-low { color: #f43f5e; } /* < 0.6 */
|
|
174
|
+
.block-progress .empty { color: #e2e8f0; }
|
|
175
|
+
.block-progress .score { font-size: 12px; color: #94a3b8; margin-left: 8px; }
|
|
176
|
+
|
|
177
|
+
/* ── Sidebar Navigation ──────────────────────────────── */
|
|
178
|
+
/* When a sidebar is rendered (#report-sidebar), the body shifts right on lg+
|
|
179
|
+
to make room. Styling matches the corner-accent / mono-label language. */
|
|
180
|
+
@media (min-width: 1024px) {
|
|
181
|
+
body:has(#report-sidebar) { padding-left: 15rem; }
|
|
182
|
+
}
|
|
183
|
+
.sidebar-link {
|
|
184
|
+
border-left: 2px solid transparent;
|
|
185
|
+
}
|
|
186
|
+
.sidebar-link.active {
|
|
187
|
+
color: var(--color-primary-500);
|
|
188
|
+
background-color: var(--color-primary-50);
|
|
189
|
+
border-left-color: var(--color-primary-500);
|
|
190
|
+
font-weight: 600;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/* ── Insight Box ─────────────────────────────────────── */
|
|
194
|
+
.insight-box {
|
|
195
|
+
background: var(--color-card);
|
|
196
|
+
border: 1px solid var(--color-border);
|
|
197
|
+
/* No border-radius — uses corner-accents class */
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/* ── Section Textures ────────────────────────────────── */
|
|
201
|
+
/* Apply to <section>: combine one pattern + noise, e.g. class="texture-dots texture-noise" */
|
|
202
|
+
/* Textures should be felt, not seen — low opacity, faded edges */
|
|
203
|
+
|
|
204
|
+
/* ── Fade-In ─────────────────────────────────────────── */
|
|
205
|
+
.fade-in {
|
|
206
|
+
opacity: 0;
|
|
207
|
+
transform: translateY(20px);
|
|
208
|
+
transition: opacity 0.7s ease-out, transform 0.7s ease-out;
|
|
209
|
+
}
|
|
210
|
+
.fade-in-visible {
|
|
211
|
+
opacity: 1;
|
|
212
|
+
transform: translateY(0);
|
|
213
|
+
}
|
|
214
|
+
/* Stagger with data-delay attribute: <div class="fade-in" data-delay="100"> */`;
|
|
215
|
+
/**
|
|
216
|
+
* The registered name of the ECharts theme. The skeleton registers the theme under this name, and the
|
|
217
|
+
* bootstrap reads the same name. One source prevents a silent mismatch between the two sites.
|
|
218
|
+
*/
|
|
219
|
+
export const ECHARTS_THEME_NAME = "inflexa";
|
|
220
|
+
/**
|
|
221
|
+
* The ECharts theme as a plain object. The renderer serializes this object and registers it, thus the
|
|
222
|
+
* theme never rides a JSON file and no run-time read is necessary. The palette and the axis styles mirror
|
|
223
|
+
* the light design tokens of the page.
|
|
224
|
+
*/
|
|
225
|
+
export const ECHARTS_THEME = {
|
|
226
|
+
color: ["#576dea", "#ef4444", "#22c55e", "#a78bfa", "#f59e0b", "#ec4899", "#06b6d4", "#f97316", "#8b5cf6", "#14b8a6"],
|
|
227
|
+
backgroundColor: "transparent",
|
|
228
|
+
textStyle: {
|
|
229
|
+
fontFamily: "'Space Grotesk Variable', system-ui, sans-serif",
|
|
230
|
+
fontSize: 12,
|
|
231
|
+
color: "#64748b",
|
|
232
|
+
},
|
|
233
|
+
title: {
|
|
234
|
+
show: false,
|
|
235
|
+
},
|
|
236
|
+
legend: {
|
|
237
|
+
bottom: 0,
|
|
238
|
+
textStyle: { fontSize: 11, color: "#64748b" },
|
|
239
|
+
itemGap: 16,
|
|
240
|
+
itemWidth: 12,
|
|
241
|
+
itemHeight: 12,
|
|
242
|
+
},
|
|
243
|
+
grid: {
|
|
244
|
+
left: 60,
|
|
245
|
+
right: 24,
|
|
246
|
+
top: 24,
|
|
247
|
+
bottom: 48,
|
|
248
|
+
containLabel: false,
|
|
249
|
+
},
|
|
250
|
+
tooltip: {
|
|
251
|
+
backgroundColor: "#ffffff",
|
|
252
|
+
borderColor: "#e2e8f0",
|
|
253
|
+
textStyle: { color: "#334155", fontSize: 12 },
|
|
254
|
+
extraCssText: "border-radius: 4px; box-shadow: 0 4px 12px rgba(15,23,42,0.1);",
|
|
255
|
+
},
|
|
256
|
+
toolbox: {
|
|
257
|
+
feature: {
|
|
258
|
+
saveAsImage: { title: "Save", pixelRatio: 2 },
|
|
259
|
+
},
|
|
260
|
+
iconStyle: { borderColor: "#94a3b8" },
|
|
261
|
+
right: 16,
|
|
262
|
+
top: 0,
|
|
263
|
+
},
|
|
264
|
+
xAxis: {
|
|
265
|
+
axisLine: { lineStyle: { color: "#e2e8f0" } },
|
|
266
|
+
axisTick: { lineStyle: { color: "#e2e8f0" } },
|
|
267
|
+
axisLabel: { color: "#64748b", fontSize: 11 },
|
|
268
|
+
splitLine: { lineStyle: { color: "#f1f5f9", type: "dashed" } },
|
|
269
|
+
},
|
|
270
|
+
yAxis: {
|
|
271
|
+
axisLine: { show: false },
|
|
272
|
+
axisTick: { show: false },
|
|
273
|
+
axisLabel: { color: "#64748b", fontSize: 11 },
|
|
274
|
+
splitLine: { lineStyle: { color: "#f1f5f9", type: "dashed" } },
|
|
275
|
+
},
|
|
276
|
+
};
|
|
277
|
+
/**
|
|
278
|
+
* The page-side script that wires each chart. It finds every chart container, reads the option JSON from
|
|
279
|
+
* the sibling `<script type="application/json">` element, and initializes ECharts with the registered
|
|
280
|
+
* theme. The skeleton registers the theme before this script runs. A resize handler keeps each chart
|
|
281
|
+
* fit to the window.
|
|
282
|
+
*/
|
|
283
|
+
export const CHART_BOOTSTRAP = `(function () {
|
|
284
|
+
if (typeof echarts === "undefined") {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
var containers = document.querySelectorAll("[data-echarts-id]");
|
|
288
|
+
for (var i = 0; i < containers.length; i++) {
|
|
289
|
+
var container = containers[i];
|
|
290
|
+
var optionScript = container.nextElementSibling;
|
|
291
|
+
if (!optionScript || optionScript.getAttribute("type") !== "application/json") {
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
var option = JSON.parse(optionScript.textContent || "{}");
|
|
295
|
+
var chart = echarts.init(container, ${JSON.stringify(ECHARTS_THEME_NAME)});
|
|
296
|
+
chart.setOption(option);
|
|
297
|
+
}
|
|
298
|
+
window.addEventListener("resize", function () {
|
|
299
|
+
var nodes = document.querySelectorAll("[data-echarts-id]");
|
|
300
|
+
for (var j = 0; j < nodes.length; j++) {
|
|
301
|
+
var instance = echarts.getInstanceByDom(nodes[j]);
|
|
302
|
+
if (instance) {
|
|
303
|
+
instance.resize();
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
})();`;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The reference ledger state.
|
|
3
|
+
*
|
|
4
|
+
* A claim binds to evidence, and a citation block points at an external source. The ledger collects each
|
|
5
|
+
* reference in first-appearance order, and it gives one marker number to each distinct reference. A claim
|
|
6
|
+
* marker and a citation marker read from the same ledger, thus one reference that two blocks share gets
|
|
7
|
+
* one number and one list entry.
|
|
8
|
+
*
|
|
9
|
+
* Identity is the canonical serialization of the reference. `serializeReference` sorts the keys at every
|
|
10
|
+
* depth, thus two references match only when every field matches. The key order of the source object does
|
|
11
|
+
* not change the identity.
|
|
12
|
+
*/
|
|
13
|
+
import { type Reference } from "../contracts/report-reference.js";
|
|
14
|
+
/**
|
|
15
|
+
* The mutable ledger of references.
|
|
16
|
+
*
|
|
17
|
+
* The page walk makes one ledger, and it threads the ledger through each claim and each citation. The
|
|
18
|
+
* order of the entries is the order of the first mark, thus the marker numbers count up by first
|
|
19
|
+
* appearance.
|
|
20
|
+
*/
|
|
21
|
+
export declare class ReferenceLedger {
|
|
22
|
+
private readonly order;
|
|
23
|
+
private readonly markers;
|
|
24
|
+
/**
|
|
25
|
+
* Give the marker number of a reference. A new reference gets the next number, and it joins the
|
|
26
|
+
* order. A reference that matches an earlier one gives the earlier number, thus the list holds it one
|
|
27
|
+
* time.
|
|
28
|
+
*/
|
|
29
|
+
mark(reference: Reference): number;
|
|
30
|
+
/** The references in first-appearance order. The marker of an entry is its position plus one. */
|
|
31
|
+
entries(): readonly Reference[];
|
|
32
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The reference ledger state.
|
|
3
|
+
*
|
|
4
|
+
* A claim binds to evidence, and a citation block points at an external source. The ledger collects each
|
|
5
|
+
* reference in first-appearance order, and it gives one marker number to each distinct reference. A claim
|
|
6
|
+
* marker and a citation marker read from the same ledger, thus one reference that two blocks share gets
|
|
7
|
+
* one number and one list entry.
|
|
8
|
+
*
|
|
9
|
+
* Identity is the canonical serialization of the reference. `serializeReference` sorts the keys at every
|
|
10
|
+
* depth, thus two references match only when every field matches. The key order of the source object does
|
|
11
|
+
* not change the identity.
|
|
12
|
+
*/
|
|
13
|
+
import { serializeReference } from "../contracts/report-reference.js";
|
|
14
|
+
/**
|
|
15
|
+
* The mutable ledger of references.
|
|
16
|
+
*
|
|
17
|
+
* The page walk makes one ledger, and it threads the ledger through each claim and each citation. The
|
|
18
|
+
* order of the entries is the order of the first mark, thus the marker numbers count up by first
|
|
19
|
+
* appearance.
|
|
20
|
+
*/
|
|
21
|
+
export class ReferenceLedger {
|
|
22
|
+
order = [];
|
|
23
|
+
markers = new Map();
|
|
24
|
+
/**
|
|
25
|
+
* Give the marker number of a reference. A new reference gets the next number, and it joins the
|
|
26
|
+
* order. A reference that matches an earlier one gives the earlier number, thus the list holds it one
|
|
27
|
+
* time.
|
|
28
|
+
*/
|
|
29
|
+
mark(reference) {
|
|
30
|
+
const key = serializeReference(reference);
|
|
31
|
+
const seen = this.markers.get(key);
|
|
32
|
+
if (seen !== undefined) {
|
|
33
|
+
return seen;
|
|
34
|
+
}
|
|
35
|
+
const marker = this.order.length + 1;
|
|
36
|
+
this.markers.set(key, marker);
|
|
37
|
+
this.order.push(reference);
|
|
38
|
+
return marker;
|
|
39
|
+
}
|
|
40
|
+
/** The references in first-appearance order. The marker of an entry is its position plus one. */
|
|
41
|
+
entries() {
|
|
42
|
+
return this.order;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The page walk: the document walk, the value-map validation, and the problem collection.
|
|
3
|
+
*
|
|
4
|
+
* `renderReportPage` walks the sections in document order. It dispatches each block to its kind renderer,
|
|
5
|
+
* and it validates the bound value against the shape that the block needs. A missing entry, or an entry of
|
|
6
|
+
* the wrong shape, becomes one typed problem. The walk collects every problem, thus one render reports each
|
|
7
|
+
* fault at one time. A page with no problem assembles to one HTML string.
|
|
8
|
+
*
|
|
9
|
+
* One shared `ReferenceLedger` threads through the whole walk. Thus a claim marker and a citation marker
|
|
10
|
+
* count by first appearance across the page, and a reference that two blocks share keeps one number and one
|
|
11
|
+
* list entry.
|
|
12
|
+
*
|
|
13
|
+
* The output is a pure function of the two inputs. The renderer reads no clock, no random value, and no
|
|
14
|
+
* locale. Thus the same document and the same values give the same bytes.
|
|
15
|
+
*/
|
|
16
|
+
import { type Result } from "neverthrow";
|
|
17
|
+
import type { ReportDocument } from "../contracts/report-blocks.js";
|
|
18
|
+
import type { RenderProblem, RenderValues } from "./types.js";
|
|
19
|
+
/**
|
|
20
|
+
* Render a report document and its value map to one HTML string.
|
|
21
|
+
*
|
|
22
|
+
* The walk collects every value problem. When any problem exists, the render returns the problems and no
|
|
23
|
+
* HTML. When no problem exists, the render assembles the page and returns the string.
|
|
24
|
+
*/
|
|
25
|
+
export declare function renderReportPage(document: ReportDocument, values: RenderValues): Result<string, RenderProblem[]>;
|