clearotron 0.2.1 → 0.2.3
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/.env.example +82 -1
- package/.nvmrc +1 -1
- package/CONTRIBUTING.md +3 -3
- package/INSTALL.md +64 -58
- package/README.md +11 -16
- package/THIRD-PARTY-NOTICES.md +1 -1
- package/bin/brandowner.mjs +1 -1
- package/bin/clearotron.mjs +26 -4
- package/bin/connect.mjs +2 -2
- package/bin/example.mjs +31 -11
- package/bin/grant.mjs +3 -3
- package/bin/key.mjs +1 -1
- package/bin/onboard.mjs +252 -136
- package/bin/start.mjs +176 -33
- package/bin/stop.mjs +65 -3
- package/bin/update.mjs +7 -7
- package/bin/uspto-sync.mjs +1 -1
- package/build-info.json +2 -2
- package/demo/full-country-search/run/_driver/framework.json +1 -1
- package/demo/global-preliminary-search/run/_driver/framework.json +1 -1
- package/demo/knockout-search/run/_driver/framework.json +1 -1
- package/demo/multi-country-focus-search/run/_driver/framework.json +1 -1
- package/docs/DELIVERY.md +6 -2
- package/docs/E2E.md +5 -5
- package/docs/PORTAL.md +2 -2
- package/docs/README.md +5 -4
- package/docs/SECURITY.md +17 -0
- package/docs/architecture/01-product-overview.md +2 -2
- package/docs/architecture/02-architecture.md +2 -2
- package/docs/architecture/04-configuration-reference.md +8 -3
- package/docs/architecture/05-config-governance.md +52 -5
- package/docs/architecture/05-customer-profiles.md +2 -2
- package/docs/architecture/06-operations-runbook.md +13 -1
- package/docs/architecture/09-security-and-data.md +1 -1
- package/docs/configuration.md +4 -3
- package/docs/decisions/0004-documentation-structure.md +1 -1
- package/driver/CHANGELOG.md +121 -1
- package/driver/README.md +2 -2
- package/driver/ask-ledger.mjs +3 -3
- package/driver/authority-trees.mjs +1 -1
- package/driver/call-capture.mjs +1 -1
- package/driver/card-frame.mjs +1 -1
- package/driver/case-law-ledger.mjs +1 -1
- package/driver/claim-liveness.mjs +1 -1
- package/driver/common-law-receipts.mjs +2 -2
- package/driver/commonlaw-carry.mjs +1 -1
- package/driver/config-inventory.mjs +1 -1
- package/driver/config-staleness.mjs +1 -1
- package/driver/connotation-search.mjs +12 -12
- package/driver/contract-audit.mjs +5 -5
- package/driver/contract-dictation-registry.mjs +4 -4
- package/driver/contract-dictation.mjs +2 -2
- package/driver/contract-e3-backlog.mjs +6 -6
- package/driver/contract-vocabulary.mjs +3 -3
- package/driver/corrections-feedforward.mjs +1 -1
- package/driver/coverage-form-io.mjs +2 -2
- package/driver/coverage-form.mjs +4 -4
- package/driver/coverage-ledger.mjs +3 -3
- package/driver/coverage-union.mjs +1 -1
- package/driver/declination-call.mjs +35 -3
- package/driver/declination-duty.mjs +1 -1
- package/driver/deliver-trigger.sh +3 -3
- package/driver/deploy-live-run-guard.mjs +6 -2
- package/driver/dev-portal.mjs +3 -3
- package/driver/disposition-call.mjs +4 -4
- package/driver/disposition-tool.mjs +4 -4
- package/driver/disposition-union.mjs +2 -2
- package/driver/doc-constants.mjs +1 -1
- package/driver/door-gates.mjs +2 -2
- package/driver/doubt-selection.mjs +2 -2
- package/driver/drainer-identity.mjs +1 -1
- package/driver/driver.config.mjs +64 -12
- package/driver/e2e-rounds.mjs +2 -2
- package/driver/effort-model.mjs +2 -2
- package/driver/engine/anthropic-agent.mjs +24 -24
- package/driver/engine/auth.mjs +1 -1
- package/driver/engine/cli-version.mjs +103 -0
- package/driver/engine/common.mjs +1 -1
- package/driver/engine/deny-authority-write.mjs +1 -1
- package/driver/engine/jx-turn.mjs +1 -1
- package/driver/engine/mcp/clarivate-server.mjs +1 -1
- package/driver/engine/mcp/corsearch-server.mjs +1 -1
- package/driver/engine/mcp/declination-server.mjs +1 -1
- package/driver/engine/mcp/dispositions-server.mjs +1 -1
- package/driver/engine/mcp/euipo-server.mjs +1 -1
- package/driver/engine/mcp/fetch-server.mjs +1 -1
- package/driver/engine/mcp/free-tier-server.mjs +2 -2
- package/driver/engine/mcp/gather-config.mjs +11 -11
- package/driver/engine/mcp/perplexity-server.mjs +1 -1
- package/driver/engine/mcp/recording-server.mjs +8 -4
- package/driver/engine/mcp/signa-server.mjs +1 -1
- package/driver/engine/mcp/uspto-local-server.mjs +1 -1
- package/driver/engine/openai-agent.mjs +2 -2
- package/driver/engine-build.mjs +2 -2
- package/driver/enqueue-schema.mjs +10 -10
- package/driver/enqueue.mjs +1 -1
- package/driver/envelope-settle.mjs +1 -1
- package/driver/evidence-claim-invariant.mjs +2 -2
- package/driver/feedback-store.mjs +1 -1
- package/driver/findings-model.mjs +60 -10
- package/driver/flag-snapshot.mjs +20 -0
- package/driver/floor-duty.mjs +1 -1
- package/driver/form-neighbourhood.mjs +1 -1
- package/driver/framework.mjs +2 -2
- package/driver/gateway.mjs +45 -23
- package/driver/grounds-grammar.mjs +1 -1
- package/driver/hit-list.mjs +1 -1
- package/driver/jurisdiction-systems.mjs +1 -1
- package/driver/jx-lanes.mjs +1 -1
- package/driver/jx-units.mjs +1 -1
- package/driver/jx.mjs +3 -3
- package/driver/knockout-assess-record.mjs +5 -1
- package/driver/narrative-refutation-record.mjs +3 -3
- package/driver/numeric-setting.mjs +1 -1
- package/driver/owner-use-check.mjs +184 -0
- package/driver/package.json +4 -4
- package/driver/party-facts.mjs +2 -2
- package/driver/phase0.mjs +2 -2
- package/driver/pipeline-knockout.mjs +52 -4
- package/driver/pipeline.mjs +180 -67
- package/driver/placement-diff.mjs +2 -2
- package/driver/placement-form.mjs +4 -4
- package/driver/placement-union.mjs +1 -1
- package/driver/plain-register.mjs +120 -0
- package/driver/portal-access.mjs +1 -1
- package/driver/portal-acks.mjs +1 -1
- package/driver/portal-config-view.mjs +42 -3
- package/driver/portal-families.mjs +1 -1
- package/driver/portal-local-auth.mjs +1 -1
- package/driver/portal-report.mjs +7 -7
- package/driver/portal-service.mjs +41 -22
- package/driver/portal-upstream.mjs +2 -2
- package/driver/predelivery-lint.mjs +149 -11
- package/driver/prelim-variants-record.mjs +2 -2
- package/driver/profile-page.html +11 -3
- package/driver/profile-selection.mjs +1 -1
- package/driver/profile-service.mjs +6 -6
- package/driver/profiles/README.md +3 -3
- package/driver/profiles.mjs +145 -13
- package/driver/progress.mjs +6 -6
- package/driver/provider-usage.mjs +1 -1
- package/driver/publish/demo-marking.mjs +1 -1
- package/driver/publish/index.mjs +49 -8
- package/driver/publish/knockout.mjs +42 -14
- package/driver/publish/parse.mjs +4 -4
- package/driver/publish/publish-inputs.mjs +2 -2
- package/driver/publish/register-presence.mjs +1 -1
- package/driver/publish/render-knockout.mjs +646 -144
- package/driver/publish/render.mjs +2 -2
- package/driver/publish/report-data.mjs +13 -3
- package/driver/queue-watch-probe.mjs +1 -1
- package/driver/queue-watch-verdict.mjs +1 -1
- package/driver/recall-reconciliation.mjs +1 -1
- package/driver/recipe-service.mjs +1 -1
- package/driver/record-carry.mjs +5 -5
- package/driver/recording-agreement.mjs +3 -3
- package/driver/reference-score.mjs +7 -7
- package/driver/reference-strip-signatures.mjs +20 -0
- package/driver/refusal-bound.mjs +3 -3
- package/driver/register-availability.mjs +2 -2
- package/driver/register-count.mjs +1 -1
- package/driver/register-grant-vocabulary.mjs +2 -2
- package/driver/register-plan.mjs +8 -8
- package/driver/register-records.mjs +2 -2
- package/driver/registry-fidelity.mjs +3 -3
- package/driver/remedy-accounting.mjs +1 -1
- package/driver/repair-composers.mjs +2 -2
- package/driver/repair-digest.mjs +3 -3
- package/driver/repairs.mjs +6 -6
- package/driver/replay-archive.mjs +2 -0
- package/driver/report-card-record.mjs +2 -2
- package/driver/result-noun-fields.mjs +10 -3
- package/driver/run-economics.mjs +2 -2
- package/driver/run-integrity.mjs +1 -1
- package/driver/runner.mjs +22 -22
- package/driver/scope-rules.mjs +1 -1
- package/driver/search-policy.mjs +5 -5
- package/driver/skeptic-search.mjs +1 -1
- package/driver/skills/blind-frame/SKILL.md +2 -2
- package/driver/skills/case-law-citation/SKILL.md +2 -2
- package/driver/skills/knockout-assess/SKILL.md +94 -4
- package/driver/skills/matter-frame/SKILL.md +6 -6
- package/driver/skills/matter-frame/watchlist-reference.md +2 -2
- package/driver/skills/prelim-common-law/SKILL.md +1 -1
- package/driver/skills/prelim-search/SKILL.md +3 -3
- package/driver/skills/prelim-search/report-prose.md +82 -0
- package/driver/skills/prelim-search/risk-framework-demo.manifest.json +1 -1
- package/driver/skills/prelim-search/risk-framework-triage.manifest.json +1 -1
- package/driver/skills/prelim-search/risk-framework.manifest.json +1 -1
- package/driver/skills/prelim-search/synthesis-rules.md +1 -1
- package/driver/skills/prelim-search/template-formatting.md +1 -1
- package/driver/skills/prelim-search/templates/email/generic.md +1 -1
- package/driver/skills/prelim-search/worked-examples.md +1 -1
- package/driver/skills/prelim-variants/SKILL.md +5 -5
- package/driver/stage-context.mjs +1 -1
- package/driver/stages-knockout.mjs +55 -4
- package/driver/stages.mjs +101 -44
- package/driver/stray-artifacts.mjs +2 -2
- package/driver/suite-census.json +275 -65
- package/driver/synthesis-record.mjs +1 -1
- package/driver/systemd/clearotron-client-mcp.service +1 -1
- package/driver/systemd/clearotron-portal.service +1 -1
- package/driver/systemd/render-units.mjs +1 -1
- package/driver/tokens.mjs +1 -1
- package/driver/tool-calls.mjs +1 -1
- package/driver/turnaround-bands.mjs +1 -1
- package/driver/unit-file-drift.mjs +1 -1
- package/driver/unit-inventory.mjs +297 -80
- package/driver/unit-state-verdict.mjs +20 -12
- package/driver/verify-knockout.mjs +10 -2
- package/driver/verify.mjs +13 -13
- package/driver/whatif-memo-run.mjs +72 -9
- package/driver/whatif-memo.mjs +19 -1
- package/driver/whatif-queue.mjs +1 -1
- package/driver/whatif-worker.mjs +1 -1
- package/examples/README.md +2 -2
- package/examples/grants.example.json +6 -7
- package/mcp-server/CHANGELOG.md +6 -0
- package/mcp-server/README.md +3 -3
- package/mcp-server/http-server.mjs +44 -1
- package/mcp-server/key-socket.mjs +184 -0
- package/mcp-server/lib/audit-view.mjs +69 -2
- package/mcp-server/lib/brief.mjs +15 -0
- package/mcp-server/lib/driver.mjs +7 -1
- package/mcp-server/lib/events.mjs +1 -1
- package/mcp-server/lib/http-handler.mjs +1 -1
- package/mcp-server/lib/knockout.mjs +435 -0
- package/mcp-server/lib/ops.mjs +4 -4
- package/mcp-server/lib/options.mjs +1 -1
- package/mcp-server/lib/plan.mjs +1 -1
- package/mcp-server/lib/runs.mjs +1 -1
- package/mcp-server/lib/scrub.mjs +2 -2
- package/mcp-server/lib/whatif.mjs +5 -5
- package/mcp-server/mint-token.mjs +1 -1
- package/mcp-server/package.json +2 -2
- package/mcp-server/packs/ops/EXAMPLES.md +2 -2
- package/mcp-server/server.mjs +77 -12
- package/package.json +30 -12
- package/portal-ui/dist/assets/{index-Ct3iQtZ2.css → index-1ziUJX1E.css} +43 -2
- package/portal-ui/dist/assets/{index-BUGgiYtF.js → index-CEYvXdqH.js} +226 -49
- package/portal-ui/dist/index.html +2 -2
- package/portal-ui/package.json +1 -1
- package/providers/_shared/enumerate.mjs +1 -1
- package/providers/_shared/ledger-path.mjs +3 -3
- package/providers/_shared/ledger.mjs +1 -1
- package/providers/_shared/result-shape.mjs +3 -3
- package/providers/_shared/term-shape.mjs +2 -2
- package/providers/corsearch/src/core.js +1 -1
- package/providers/jx-subclass/BUILDING.md +1 -1
- package/providers/oauth-mcp-bridge/CHANGELOG.md +6 -0
- package/providers/oauth-mcp-bridge/package.json +1 -1
- package/providers/oauth-mcp-bridge/stdin-guard.mjs +2 -2
- package/providers/uspto-local/src/index-store.js +2 -2
- package/scripts/README.md +1 -1
- package/scripts/added-reference-check.mjs +29 -1
- package/scripts/authority-boundary-probe.mjs +1 -1
- package/scripts/backfill-started-at.mjs +1 -1
- package/scripts/citation-line-check.mjs +124 -5
- package/scripts/compare.mjs +2 -2
- package/scripts/contract-dictation-scan.mjs +2 -2
- package/scripts/dead-names.mjs +1 -1
- package/scripts/drain-preflight.mjs +5 -5
- package/scripts/e2e-unread-terminals.mjs +1 -1
- package/scripts/e2e.mjs +8 -8
- package/scripts/env-audit.mjs +7 -7
- package/scripts/env-classify.mjs +206 -18
- package/scripts/freeze-example-run.mjs +3 -3
- package/scripts/head-arrived-gated.mjs +1 -1
- package/scripts/headless-page.mjs +51 -2
- package/scripts/live-surface-check.mjs +129 -19
- package/scripts/main-health.mjs +1 -1
- package/scripts/merge-presence-check.mjs +3 -3
- package/scripts/mint-suite-census.mjs +6 -6
- package/scripts/nightly-notice.mjs +1 -3
- package/scripts/preinstall-node-check.mjs +24 -0
- package/scripts/reconcile-runs.mjs +1 -1
- package/scripts/release-await-cut.mjs +6 -4
- package/scripts/release-version-pr-checks.mjs +1 -1
- package/scripts/release-version.mjs +2 -2
- package/scripts/render-check.mjs +66 -7
- package/scripts/report-frame-check.mjs +1 -1
- package/scripts/report-screenshot.mjs +1 -1
- package/scripts/revisit-render-check.mjs +1 -1
- package/scripts/score.mjs +4 -4
- package/scripts/strip-tracker-citations.mjs +139 -0
- package/scripts/test-run.mjs +19 -3
- package/scripts/third-party-notices.mjs +3 -3
- package/scripts/travelling-predicates.mjs +3 -3
- package/scripts/unexecuted-asserts.mjs +2 -2
- package/scripts/verify-publishable.mjs +2 -2
- package/scripts/write-up-form-census.mjs +1 -1
- package/shared/access-audience.mjs +1 -1
- package/shared/anon-overlay.mjs +3 -3
- package/shared/brand.mjs +13 -13
- package/shared/citation-scan.mjs +1 -1
- package/shared/client-door.mjs +7 -7
- package/shared/customer-store.mjs +1 -1
- package/shared/driver-dir.mjs +1 -1
- package/shared/env-aliases.mjs +0 -48
- package/shared/env-local.mjs +1 -1
- package/shared/identifier-scan.mjs +3 -3
- package/shared/invocation.mjs +29 -1
- package/shared/names-in-force.mjs +4 -0
- package/shared/node-floor.mjs +97 -0
- package/shared/product-owned-names.mjs +1 -1
- package/shared/register-selection.mjs +1 -1
- package/shared/scope.mjs +5 -5
- package/shared/server-units.mjs +4 -4
- package/shared/staff-domain.mjs +154 -0
- package/shared/store-in-repo.mjs +25 -4
- package/shared/suite-census.mjs +4 -4
- package/shared/tty-style.mjs +1 -1
- package/shared/uspto-index-size.mjs +1 -1
- package/shared/vacuous-pass.mjs +1 -1
- package/skills/clearotron-account/SKILL.md +42 -13
- package/skills/clearotron-ops/SKILL.md +1 -1
- package/driver/recipes/README.md +0 -49
- package/driver/skills/prelim-search/risk-framework-aurora.manifest.json +0 -19
- package/driver/skills/prelim-search/risk-framework-aurora.md +0 -77
- package/driver/skills/prelim-search/risk-framework-zephyr.manifest.json +0 -14
- package/driver/skills/prelim-search/risk-framework-zephyr.md +0 -33
- package/driver/skills/prelim-search/worked-examples-aurora.md +0 -10
- package/driver/skills/prelim-search/worked-examples-zephyr.md +0 -10
- package/driver/systemd/prelim-driver.path +0 -69
- package/driver/systemd/prelim-driver.service +0 -86
- package/driver/systemd/prelim-driver.timer +0 -14
- package/driver/systemd/prelim-outbox.path +0 -27
- package/driver/systemd/prelim-outbox.service +0 -37
- package/driver/systemd/prelim-outbox.timer +0 -21
- package/node_modules/exceljs/README_zh.md +0 -2878
- package/node_modules/exceljs/dist/LICENSE +0 -22
- package/node_modules/exceljs/dist/es5/csv/csv.js +0 -182
- package/node_modules/exceljs/dist/es5/csv/csv.js.map +0 -1
- package/node_modules/exceljs/dist/es5/csv/line-buffer.js +0 -68
- package/node_modules/exceljs/dist/es5/csv/line-buffer.js.map +0 -1
- package/node_modules/exceljs/dist/es5/csv/stream-converter.js +0 -110
- package/node_modules/exceljs/dist/es5/csv/stream-converter.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/anchor.js +0 -73
- package/node_modules/exceljs/dist/es5/doc/anchor.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/cell.js +0 -961
- package/node_modules/exceljs/dist/es5/doc/cell.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/column.js +0 -274
- package/node_modules/exceljs/dist/es5/doc/column.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/data-validations.js +0 -18
- package/node_modules/exceljs/dist/es5/doc/data-validations.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/defined-names.js +0 -173
- package/node_modules/exceljs/dist/es5/doc/defined-names.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/enums.js +0 -49
- package/node_modules/exceljs/dist/es5/doc/enums.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/image.js +0 -69
- package/node_modules/exceljs/dist/es5/doc/image.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/modelcontainer.js +0 -16
- package/node_modules/exceljs/dist/es5/doc/modelcontainer.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/note.js +0 -64
- package/node_modules/exceljs/dist/es5/doc/note.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/range.js +0 -229
- package/node_modules/exceljs/dist/es5/doc/range.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/row.js +0 -382
- package/node_modules/exceljs/dist/es5/doc/row.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/table.js +0 -443
- package/node_modules/exceljs/dist/es5/doc/table.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/workbook.js +0 -202
- package/node_modules/exceljs/dist/es5/doc/workbook.js.map +0 -1
- package/node_modules/exceljs/dist/es5/doc/worksheet.js +0 -900
- package/node_modules/exceljs/dist/es5/doc/worksheet.js.map +0 -1
- package/node_modules/exceljs/dist/es5/exceljs.bare.js +0 -14
- package/node_modules/exceljs/dist/es5/exceljs.bare.js.map +0 -1
- package/node_modules/exceljs/dist/es5/exceljs.browser.js +0 -36
- package/node_modules/exceljs/dist/es5/exceljs.browser.js.map +0 -1
- package/node_modules/exceljs/dist/es5/exceljs.nodejs.js +0 -15
- package/node_modules/exceljs/dist/es5/exceljs.nodejs.js.map +0 -1
- package/node_modules/exceljs/dist/es5/index.js +0 -15
- package/node_modules/exceljs/dist/es5/stream/xlsx/hyperlink-reader.js +0 -90
- package/node_modules/exceljs/dist/es5/stream/xlsx/hyperlink-reader.js.map +0 -1
- package/node_modules/exceljs/dist/es5/stream/xlsx/sheet-comments-writer.js +0 -94
- package/node_modules/exceljs/dist/es5/stream/xlsx/sheet-comments-writer.js.map +0 -1
- package/node_modules/exceljs/dist/es5/stream/xlsx/sheet-rels-writer.js +0 -94
- package/node_modules/exceljs/dist/es5/stream/xlsx/sheet-rels-writer.js.map +0 -1
- package/node_modules/exceljs/dist/es5/stream/xlsx/workbook-reader.js +0 -362
- package/node_modules/exceljs/dist/es5/stream/xlsx/workbook-reader.js.map +0 -1
- package/node_modules/exceljs/dist/es5/stream/xlsx/workbook-writer.js +0 -347
- package/node_modules/exceljs/dist/es5/stream/xlsx/workbook-writer.js.map +0 -1
- package/node_modules/exceljs/dist/es5/stream/xlsx/worksheet-reader.js +0 -392
- package/node_modules/exceljs/dist/es5/stream/xlsx/worksheet-reader.js.map +0 -1
- package/node_modules/exceljs/dist/es5/stream/xlsx/worksheet-writer.js +0 -652
- package/node_modules/exceljs/dist/es5/stream/xlsx/worksheet-writer.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/auto-drain.js +0 -18
- package/node_modules/exceljs/dist/es5/utils/auto-drain.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/browser-buffer-decode.js +0 -15
- package/node_modules/exceljs/dist/es5/utils/browser-buffer-decode.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/browser-buffer-encode.js +0 -18
- package/node_modules/exceljs/dist/es5/utils/browser-buffer-encode.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/cell-matrix.js +0 -149
- package/node_modules/exceljs/dist/es5/utils/cell-matrix.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/col-cache.js +0 -258
- package/node_modules/exceljs/dist/es5/utils/col-cache.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/copy-style.js +0 -43
- package/node_modules/exceljs/dist/es5/utils/copy-style.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/encryptor.js +0 -58
- package/node_modules/exceljs/dist/es5/utils/encryptor.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/iterate-stream.js +0 -46
- package/node_modules/exceljs/dist/es5/utils/iterate-stream.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/parse-sax.js +0 -47
- package/node_modules/exceljs/dist/es5/utils/parse-sax.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/shared-formula.js +0 -42
- package/node_modules/exceljs/dist/es5/utils/shared-formula.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/shared-strings.js +0 -32
- package/node_modules/exceljs/dist/es5/utils/shared-strings.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/stream-base64.js +0 -66
- package/node_modules/exceljs/dist/es5/utils/stream-base64.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/stream-buf.js +0 -343
- package/node_modules/exceljs/dist/es5/utils/stream-buf.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/string-buf.js +0 -73
- package/node_modules/exceljs/dist/es5/utils/string-buf.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/string-builder.js +0 -32
- package/node_modules/exceljs/dist/es5/utils/string-builder.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/stuttered-pipe.js +0 -61
- package/node_modules/exceljs/dist/es5/utils/stuttered-pipe.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/typed-stack.js +0 -23
- package/node_modules/exceljs/dist/es5/utils/typed-stack.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/under-dash.js +0 -168
- package/node_modules/exceljs/dist/es5/utils/under-dash.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/utils.js +0 -171
- package/node_modules/exceljs/dist/es5/utils/utils.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/xml-stream.js +0 -151
- package/node_modules/exceljs/dist/es5/utils/xml-stream.js.map +0 -1
- package/node_modules/exceljs/dist/es5/utils/zip-stream.js +0 -79
- package/node_modules/exceljs/dist/es5/utils/zip-stream.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/defaultnumformats.js +0 -230
- package/node_modules/exceljs/dist/es5/xlsx/defaultnumformats.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/rel-type.js +0 -18
- package/node_modules/exceljs/dist/es5/xlsx/rel-type.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/base-xform.js +0 -139
- package/node_modules/exceljs/dist/es5/xlsx/xform/base-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/defined-name-xform.js +0 -85
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/defined-name-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/sheet-xform.js +0 -32
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/sheet-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-calc-properties-xform.js +0 -24
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-calc-properties-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-properties-xform.js +0 -27
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-properties-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-view-xform.js +0 -51
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-view-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-xform.js +0 -234
- package/node_modules/exceljs/dist/es5/xlsx/xform/book/workbook-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/comment-xform.js +0 -103
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/comment-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/comments-xform.js +0 -76
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/comments-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/style/vml-position-xform.js +0 -35
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/style/vml-position-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/style/vml-protection-xform.js +0 -32
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/style/vml-protection-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-anchor-xform.js +0 -53
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-anchor-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-client-data-xform.js +0 -97
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-client-data-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-notes-xform.js +0 -107
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-notes-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-shape-xform.js +0 -92
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-shape-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-textbox-xform.js +0 -61
- package/node_modules/exceljs/dist/es5/xlsx/xform/comment/vml-textbox-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/composite-xform.js +0 -51
- package/node_modules/exceljs/dist/es5/xlsx/xform/composite-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-heading-pairs-xform.js +0 -30
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-heading-pairs-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-titles-of-parts-xform.js +0 -27
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-titles-of-parts-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-xform.js +0 -93
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/app-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/content-types-xform.js +0 -112
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/content-types-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/core-xform.js +0 -158
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/core-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/relationship-xform.js +0 -23
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/relationship-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/relationships-xform.js +0 -65
- package/node_modules/exceljs/dist/es5/xlsx/xform/core/relationships-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/base-cell-anchor-xform.js +0 -47
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/base-cell-anchor-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/blip-fill-xform.js +0 -61
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/blip-fill-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/blip-xform.js +0 -40
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/blip-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/c-nv-pic-pr-xform.js +0 -35
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/c-nv-pic-pr-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/c-nv-pr-xform.js +0 -62
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/c-nv-pr-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/cell-position-xform.js +0 -82
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/cell-position-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/drawing-xform.js +0 -98
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/drawing-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/ext-lst-xform.js +0 -40
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/ext-lst-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/ext-xform.js +0 -38
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/ext-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/hlink-click-xform.js +0 -38
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/hlink-click-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/nv-pic-pr-xform.js +0 -59
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/nv-pic-pr-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/one-cell-anchor-xform.js +0 -63
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/one-cell-anchor-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/pic-xform.js +0 -67
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/pic-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/sp-pr.js +0 -30
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/sp-pr.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/two-cell-anchor-xform.js +0 -62
- package/node_modules/exceljs/dist/es5/xlsx/xform/drawing/two-cell-anchor-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/list-xform.js +0 -91
- package/node_modules/exceljs/dist/es5/xlsx/xform/list-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/auto-filter-xform.js +0 -40
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/auto-filter-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cell-xform.js +0 -451
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cell-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/cf-rule-xform.js +0 -275
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/cf-rule-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/cfvo-xform.js +0 -25
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/cfvo-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/color-scale-xform.js +0 -38
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/color-scale-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/conditional-formatting-xform.js +0 -45
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/conditional-formatting-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/conditional-formattings-xform.js +0 -77
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/conditional-formattings-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/databar-xform.js +0 -42
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/databar-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/ext-lst-ref-xform.js +0 -71
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/ext-lst-ref-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/formula-xform.js +0 -22
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/formula-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/icon-set-xform.js +0 -43
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf/icon-set-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cf-icon-ext-xform.js +0 -28
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cf-icon-ext-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js +0 -88
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cfvo-ext-xform.js +0 -38
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/cfvo-ext-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formatting-ext-xform.js +0 -52
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formatting-ext-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formattings-ext-xform.js +0 -43
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/conditional-formattings-ext-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/databar-ext-xform.js +0 -75
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/databar-ext-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/f-ext-xform.js +0 -22
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/f-ext-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/icon-set-ext-xform.js +0 -66
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/icon-set-ext-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/sqref-ext-xform.js +0 -22
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/cf-ext/sqref-ext-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/col-xform.js +0 -78
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/col-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/data-validations-xform.js +0 -247
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/data-validations-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/dimension-xform.js +0 -28
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/dimension-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/drawing-xform.js +0 -32
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/drawing-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/ext-lst-xform.js +0 -69
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/ext-lst-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/header-footer-xform.js +0 -126
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/header-footer-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/hyperlink-xform.js +0 -50
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/hyperlink-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/merge-cell-xform.js +0 -26
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/merge-cell-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/merges.js +0 -52
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/merges.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/outline-properties-xform.js +0 -35
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/outline-properties-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-breaks-xform.js +0 -24
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-breaks-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-margins-xform.js +0 -46
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-margins-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-setup-properties-xform.js +0 -32
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-setup-properties-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-setup-xform.js +0 -99
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/page-setup-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/picture-xform.js +0 -32
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/picture-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/print-options-xform.js +0 -45
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/print-options-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/row-breaks-xform.js +0 -37
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/row-breaks-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/row-xform.js +0 -128
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/row-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-format-properties-xform.js +0 -51
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-format-properties-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-properties-xform.js +0 -83
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-properties-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-protection-xform.js +0 -84
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-protection-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-view-xform.js +0 -190
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/sheet-view-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/table-part-xform.js +0 -32
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/table-part-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/worksheet-xform.js +0 -513
- package/node_modules/exceljs/dist/es5/xlsx/xform/sheet/worksheet-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/simple/boolean-xform.js +0 -27
- package/node_modules/exceljs/dist/es5/xlsx/xform/simple/boolean-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/simple/date-xform.js +0 -58
- package/node_modules/exceljs/dist/es5/xlsx/xform/simple/date-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/simple/float-xform.js +0 -47
- package/node_modules/exceljs/dist/es5/xlsx/xform/simple/float-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/simple/integer-xform.js +0 -53
- package/node_modules/exceljs/dist/es5/xlsx/xform/simple/integer-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/simple/string-xform.js +0 -47
- package/node_modules/exceljs/dist/es5/xlsx/xform/simple/string-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/static-xform.js +0 -61
- package/node_modules/exceljs/dist/es5/xlsx/xform/static-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/strings/phonetic-text-xform.js +0 -98
- package/node_modules/exceljs/dist/es5/xlsx/xform/strings/phonetic-text-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/strings/rich-text-xform.js +0 -92
- package/node_modules/exceljs/dist/es5/xlsx/xform/strings/rich-text-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/strings/shared-string-xform.js +0 -99
- package/node_modules/exceljs/dist/es5/xlsx/xform/strings/shared-string-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/strings/shared-strings-xform.js +0 -114
- package/node_modules/exceljs/dist/es5/xlsx/xform/strings/shared-strings-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/strings/text-xform.js +0 -39
- package/node_modules/exceljs/dist/es5/xlsx/xform/strings/text-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/alignment-xform.js +0 -139
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/alignment-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/border-xform.js +0 -185
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/border-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/color-xform.js +0 -66
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/color-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/dxf-xform.js +0 -106
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/dxf-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/fill-xform.js +0 -308
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/fill-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/font-xform.js +0 -175
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/font-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/numfmt-xform.js +0 -59
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/numfmt-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/protection-xform.js +0 -53
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/protection-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/style-xform.js +0 -118
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/style-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/styles-xform.js +0 -612
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/styles-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/underline-xform.js +0 -46
- package/node_modules/exceljs/dist/es5/xlsx/xform/style/underline-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/auto-filter-xform.js +0 -75
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/auto-filter-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/custom-filter-xform.js +0 -30
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/custom-filter-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/filter-column-xform.js +0 -89
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/filter-column-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/filter-xform.js +0 -28
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/filter-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-column-xform.js +0 -42
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-column-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-style-info-xform.js +0 -40
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-style-info-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-xform.js +0 -123
- package/node_modules/exceljs/dist/es5/xlsx/xform/table/table-xform.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xlsx.js +0 -697
- package/node_modules/exceljs/dist/es5/xlsx/xlsx.js.map +0 -1
- package/node_modules/exceljs/dist/es5/xlsx/xml/theme1.js +0 -5
- package/node_modules/exceljs/dist/es5/xlsx/xml/theme1.js.map +0 -1
- package/node_modules/exceljs/dist/exceljs.bare.js +0 -55253
- package/node_modules/exceljs/dist/exceljs.bare.js.map +0 -761
- package/node_modules/exceljs/dist/exceljs.bare.min.js +0 -45
- package/node_modules/exceljs/dist/exceljs.bare.min.js.map +0 -1
- package/node_modules/exceljs/dist/exceljs.js +0 -59900
- package/node_modules/exceljs/dist/exceljs.js.map +0 -1083
- package/node_modules/exceljs/dist/exceljs.min.js +0 -45
- package/node_modules/exceljs/dist/exceljs.min.js.map +0 -1
- package/scripts/ai-page-render-check.mjs +0 -532
- package/scripts/clearances-render-check.mjs +0 -480
- package/scripts/composer-render-check.mjs +0 -1027
- package/scripts/deploy-test.sh +0 -309
- package/scripts/home-render-check.mjs +0 -526
- package/scripts/portal-lifecycle-check.mjs +0 -639
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright 2026 Cordillera Sàrl. Additional terms under section 7 of the AGPL-3.0 apply — see ADDITIONAL-TERMS.md
|
|
3
|
+
// lib/knockout.mjs — the KNOCKOUT lane, projected into the audit tools' own shapes (tracker issue 275).
|
|
4
|
+
//
|
|
5
|
+
// THE DEFECT THIS CLOSES, and it is worth stating plainly because the failure mode was a confident wrong
|
|
6
|
+
// answer rather than an error. Every read-only tool whose job is to show HOW a search reached its answer
|
|
7
|
+
// returned empty on a delivered Knockout search: `get_run` listed eleven clearance documents and reported
|
|
8
|
+
// each missing, `list_searches` returned zero, `read_artifact report` said the report did not exist while
|
|
9
|
+
// it sat on disk in the pool. An assistant session asked those tools whether a delivered knockout had
|
|
10
|
+
// checked a particular use, was shown a wall of empties, correctly applied "an absence is a finding", and
|
|
11
|
+
// told the account owner the report was ungrounded prose. Every part of that was false, and it was the
|
|
12
|
+
// only conclusion the tools supported.
|
|
13
|
+
//
|
|
14
|
+
// TWO CAUSES, BOTH MECHANICAL:
|
|
15
|
+
// 1. WRONG DIRECTORY. A knockout writes report.md/report.html/report-data.json to the POOL, never into
|
|
16
|
+
// the run dir. `resolveRun` has returned `poolDir` beside `P` for exactly this reason since brief.mjs
|
|
17
|
+
// needed it — and brief was the only reader that used it, which is precisely why brief was the only
|
|
18
|
+
// tool that worked.
|
|
19
|
+
// 2. WRONG SCHEMA. The projections read clearance artifacts (findings.json, audit.md, the coverage
|
|
20
|
+
// ledger) that this product never writes. The data they want is in `knockout-findings.json`.
|
|
21
|
+
//
|
|
22
|
+
// THE RULE THIS MODULE FOLLOWS, from the issue: the reader adapts to the product, never the product to the
|
|
23
|
+
// reader. Nothing here asks the knockout lane to emit a clearance-shaped artifact it has no use for.
|
|
24
|
+
//
|
|
25
|
+
// AND THE RULE THAT MATTERS MOST: a projection with no knockout equivalent returns a STATED refusal, never
|
|
26
|
+
// an empty list. `[]` reads as "we looked and found nothing" — that reading is the whole incident above.
|
|
27
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
28
|
+
import { basename, join } from "node:path";
|
|
29
|
+
|
|
30
|
+
import { koPaths } from "./driver.mjs";
|
|
31
|
+
import { driverDir } from "../../shared/driver-dir.mjs";
|
|
32
|
+
|
|
33
|
+
const readJson = (p) => { try { return JSON.parse(readFileSync(p, "utf8")); } catch { return null; } };
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Is this run a knockout? Answered from DISK, never from a stored lane string.
|
|
37
|
+
*
|
|
38
|
+
* `knockout-plan.json` is the frame stage's output and lands before any assessment exists, so a run that
|
|
39
|
+
* failed mid-flight is still recognised as the product it is — which is the case where an audit tool being
|
|
40
|
+
* wrong about the lane is least recoverable and most likely to be asked about.
|
|
41
|
+
*/
|
|
42
|
+
export function isKnockoutRun(run) {
|
|
43
|
+
if (!run?.runDir) return false;
|
|
44
|
+
const K = koPaths(run.runDir);
|
|
45
|
+
return existsSync(K.findings) || existsSync(K.plan) || existsSync(K.frame);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** The assessment artifact, parsed. `null` when the run has not reached the assess stage (or it failed). */
|
|
49
|
+
export function knockoutDoc(run) {
|
|
50
|
+
return run?.runDir ? readJson(koPaths(run.runDir).findings) : null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const marksOf = (doc) => (Array.isArray(doc?.marks) ? doc.marks : []);
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* A stated non-answer. The shape carries `available: false` AND a sentence, so a caller that reads only
|
|
57
|
+
* the flag and a caller that reads only the prose both get the same fact — and neither can mistake it for
|
|
58
|
+
* a search that came back empty.
|
|
59
|
+
*/
|
|
60
|
+
export function notProducedOnThisProduct(what, insteadSee) {
|
|
61
|
+
return {
|
|
62
|
+
available: false,
|
|
63
|
+
product: "knockout",
|
|
64
|
+
note: `A Knockout search does not produce ${what}. This is a statement about the product, not a result: `
|
|
65
|
+
+ `nothing was searched and found empty here.${insteadSee ? ` ${insteadSee}` : ""}`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ── artifacts ────────────────────────────────────────────────────────────────────────────────────────
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* What this lane ACTUALLY writes, with its real presence — run directory and pool together.
|
|
73
|
+
*
|
|
74
|
+
* The old list was `artifactStatus(P)` plus every REGISTER_AXES entry appended unconditionally: eleven
|
|
75
|
+
* clearance documents, every one reported `exists: false` on a product that never writes them. That is not
|
|
76
|
+
* an empty result, it is eleven false negatives, and it is what a reader was shown before concluding the
|
|
77
|
+
* pipeline had a data-integrity gap.
|
|
78
|
+
*/
|
|
79
|
+
export function knockoutArtifacts(run) {
|
|
80
|
+
const K = koPaths(run.runDir);
|
|
81
|
+
const out = [
|
|
82
|
+
{ name: "frame", file: basename(K.frame), path: K.frame },
|
|
83
|
+
{ name: "plan", file: basename(K.plan), path: K.plan },
|
|
84
|
+
{ name: "findings", file: basename(K.findings), path: K.findings },
|
|
85
|
+
{ name: "assessment", file: basename(K.assessment), path: K.assessment },
|
|
86
|
+
{ name: "registerCounts", file: basename(K.registerCounts), path: K.registerCounts },
|
|
87
|
+
{ name: "registerRecords", file: basename(K.registerRecords), path: K.registerRecords },
|
|
88
|
+
{ name: "sweepLedger", file: basename(K.sweepLedger), path: K.sweepLedger },
|
|
89
|
+
{ name: "runLog", file: "run.jsonl", path: driverDir(run.runDir, "run.jsonl") },
|
|
90
|
+
].map((a) => ({ name: a.name, file: a.file, exists: existsSync(a.path) }));
|
|
91
|
+
|
|
92
|
+
// The published half. A knockout's report lives in the pool and NOWHERE in the run dir, so a list built
|
|
93
|
+
// from the run dir alone reports a delivered report as missing — the exact reading that made
|
|
94
|
+
// `read_artifact report` say `exists: false` about a file on disk.
|
|
95
|
+
for (const [name, file] of publishedFiles(run)) out.push({ name, file, exists: true });
|
|
96
|
+
|
|
97
|
+
// The research payloads, one per mark, named so a reader can ask for one by name.
|
|
98
|
+
for (const f of listDir(join(run.runDir, "research"))) {
|
|
99
|
+
if (f.endsWith(".md")) out.push({ name: `research:${f.replace(/\.md$/, "")}`, file: f, exists: true });
|
|
100
|
+
}
|
|
101
|
+
return out;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const listDir = (d) => { try { return readdirSync(d); } catch { return []; } };
|
|
105
|
+
|
|
106
|
+
/** The pool-side documents this run actually published, as [name, file] pairs. Empty before delivery. */
|
|
107
|
+
function publishedFiles(run) {
|
|
108
|
+
const out = [];
|
|
109
|
+
if (!run?.poolDir) return out;
|
|
110
|
+
for (const f of listDir(run.poolDir)) {
|
|
111
|
+
if (f === "report.md") out.push(["report", f]);
|
|
112
|
+
else if (f === "report.html") out.push(["reportHtml", f]);
|
|
113
|
+
else if (/^report-data(-.+)?\.json$/.test(f)) out.push([f === "report-data.json" ? "reportData" : `reportData:${f.slice(12, -5)}`, f]);
|
|
114
|
+
else if (/^report-.+\.html$/.test(f)) out.push([`reportHtml:${f.slice(7, -5)}`, f]);
|
|
115
|
+
else if (/^knockout-audit-.+\.xlsx$/.test(f)) out.push(["auditWorkbook", f]);
|
|
116
|
+
}
|
|
117
|
+
return out;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Resolve a knockout artifact name to a path. Pool first for the published names, because those are the
|
|
122
|
+
* ones a reader asks for by name and the ones that are NOT in the run dir.
|
|
123
|
+
*/
|
|
124
|
+
export function knockoutArtifactPath(run, name) {
|
|
125
|
+
const K = koPaths(run.runDir);
|
|
126
|
+
const direct = {
|
|
127
|
+
frame: K.frame, plan: K.plan, findings: K.findings, assessment: K.assessment,
|
|
128
|
+
registerCounts: K.registerCounts, registerRecords: K.registerRecords,
|
|
129
|
+
sweepLedger: K.sweepLedger, "run.jsonl": driverDir(run.runDir, "run.jsonl"),
|
|
130
|
+
}[name];
|
|
131
|
+
if (direct) return direct;
|
|
132
|
+
if (name?.startsWith("research:")) return K.research(name.slice("research:".length));
|
|
133
|
+
const published = publishedFiles(run).find(([n]) => n === name);
|
|
134
|
+
if (published && run.poolDir) return join(run.poolDir, published[1]);
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// ── findings ─────────────────────────────────────────────────────────────────────────────────────────
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* The run's findings, in `filterFindings`' shape ({ source, kind, items }).
|
|
142
|
+
*
|
|
143
|
+
* `kind: "audit"` has NO knockout equivalent and says so. The clearance lane's audit trail is a per-finding
|
|
144
|
+
* rationale spine; this lane's deeper record is the audit workbook, which is a spreadsheet and not a thing
|
|
145
|
+
* this tool can hand back as rows. Returning `[]` there would report "the audit trail is empty" about a
|
|
146
|
+
* product that keeps its audit trail somewhere else.
|
|
147
|
+
*/
|
|
148
|
+
export function knockoutFindings(run, { kind, sourceLayer } = {}) {
|
|
149
|
+
const doc = knockoutDoc(run);
|
|
150
|
+
if (!doc) return { ...notProducedOnThisProduct("an assessment artifact yet", "This run has not completed its assess stage."), kind: kind ?? "findings", items: [] };
|
|
151
|
+
|
|
152
|
+
if (kind === "audit") {
|
|
153
|
+
return {
|
|
154
|
+
...notProducedOnThisProduct("a per-finding audit-trail spine",
|
|
155
|
+
"Its deeper record is the audit workbook published beside the report (read_artifact auditWorkbook names the file); the reasoning behind each band is on the finding itself, in `basis`."),
|
|
156
|
+
kind: "audit", items: [],
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
if (kind === "negatives") return { source: "knockout-findings.json", kind: "negatives", items: knockoutNegatives(doc) };
|
|
160
|
+
|
|
161
|
+
const items = [];
|
|
162
|
+
for (const m of marksOf(doc)) {
|
|
163
|
+
for (const f of (Array.isArray(m.findings) ? m.findings : [])) {
|
|
164
|
+
items.push({
|
|
165
|
+
id: `${m.name} #${f.ordinal}`, mark: m.name, ordinal: f.ordinal,
|
|
166
|
+
name: f.name, owner: f.owner ?? null, band: f.band ?? null, type: f.type ?? null,
|
|
167
|
+
net: f.net ?? null, basis: f.basis ?? null, evidence: f.evidence ?? [],
|
|
168
|
+
source_layer: sourceLayerOf(f),
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
// The promoted register filings the rater READ. They are findings a reader asks about by name, and
|
|
172
|
+
// omitting them here would make this tool disagree with the report, which prints them as cards.
|
|
173
|
+
for (const r of (Array.isArray(m.registerReads) ? m.registerReads : [])) {
|
|
174
|
+
items.push({
|
|
175
|
+
id: `${m.name} ${r.recordId}`, mark: m.name, ordinal: null,
|
|
176
|
+
name: null, owner: null, band: r.band ?? null, type: "Register filing",
|
|
177
|
+
net: r.read ?? null, basis: r.read ?? null, evidence: [], recordId: r.recordId ?? null,
|
|
178
|
+
source_layer: "Register",
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
const filtered = sourceLayer
|
|
183
|
+
? items.filter((f) => String(f.source_layer ?? "").toLowerCase() === String(sourceLayer).toLowerCase())
|
|
184
|
+
: items;
|
|
185
|
+
return { source: "knockout-findings.json", kind: kind ?? "findings", items: filtered };
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// A finding that reasoned from a fetched filing carries `weighedFilings`; everything else on this lane
|
|
189
|
+
// came off the marketplace/common-law sweep. Derived from the record, never from a word the seat typed.
|
|
190
|
+
const sourceLayerOf = (f) =>
|
|
191
|
+
(Array.isArray(f?.weighedFilings) && f.weighedFilings.length) ? "Register" : "Common-law";
|
|
192
|
+
|
|
193
|
+
const knockoutNegatives = (doc) => marksOf(doc).flatMap((m) =>
|
|
194
|
+
(Array.isArray(m.negatives) ? m.negatives : []).map((n, i) => ({
|
|
195
|
+
id: `${m.name} NR#${i + 1}`, mark: m.name,
|
|
196
|
+
term: n?.term ?? null, source: n?.source ?? null, note: n?.note ?? null,
|
|
197
|
+
})));
|
|
198
|
+
|
|
199
|
+
// ── evidence ─────────────────────────────────────────────────────────────────────────────────────────
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* The records this search considered, in `evidenceRecords`' shape ({ source, records }).
|
|
203
|
+
*
|
|
204
|
+
* Two layers, from two stores: the register filings the run FETCHED (`_driver/register-records.json` — the
|
|
205
|
+
* driver's own measurement, not a model's) and the common-law uses the assessment cited.
|
|
206
|
+
*/
|
|
207
|
+
export function knockoutEvidence(run) {
|
|
208
|
+
const doc = knockoutDoc(run);
|
|
209
|
+
const recordsDoc = readJson(koPaths(run.runDir).registerRecords);
|
|
210
|
+
const out = [];
|
|
211
|
+
|
|
212
|
+
for (const entry of (Array.isArray(recordsDoc?.marks) ? recordsDoc.marks : [])) {
|
|
213
|
+
for (const r of (Array.isArray(entry.records) ? entry.records : [])) {
|
|
214
|
+
out.push({
|
|
215
|
+
layer: "register", mark: r.mark ?? entry.name ?? null, owner: r.owner ?? null,
|
|
216
|
+
country: r.territory ?? null, classes: r.classes ?? [], status: r.status ?? null,
|
|
217
|
+
url: r.url ?? null, recordId: r.recordId ?? null,
|
|
218
|
+
matchedForm: r.matchedForm ?? null, matchedBasis: r.matchedBasis ?? null,
|
|
219
|
+
// `retrieved` is what the provider actually returned for this row, and it is a FACT about the
|
|
220
|
+
// fetch rather than about the filing. A reader deciding how much weight to give a row needs it.
|
|
221
|
+
retrieved: true, superseded: false, source: "register-records.json",
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
for (const m of marksOf(doc)) {
|
|
226
|
+
for (const f of (Array.isArray(m.findings) ? m.findings : [])) {
|
|
227
|
+
for (const u of (Array.isArray(f.evidence) ? f.evidence : [])) {
|
|
228
|
+
out.push({
|
|
229
|
+
layer: "common-law", mark: m.name, owner: f.owner ?? null, country: null, classes: [],
|
|
230
|
+
status: null, url: u, name: f.name ?? null,
|
|
231
|
+
retrieved: true, superseded: false, source: "knockout-findings.json",
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const source = [recordsDoc ? "register-records.json" : null, doc ? "knockout-findings.json" : null]
|
|
237
|
+
.filter(Boolean).join(" + ") || "none";
|
|
238
|
+
return { source, records: out };
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// ── the search log ───────────────────────────────────────────────────────────────────────────────────
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* The defensibility record, in `searchLog`'s shape ({ count, searches }).
|
|
245
|
+
*
|
|
246
|
+
* `list_searches` is documented as "proof of where the search looked and found nothing", and on every
|
|
247
|
+
* knockout we sell it returned zero — while the proof sat in `negatives` inside knockout-findings.json.
|
|
248
|
+
* That is the single most quotable line of this issue: if a client challenged a knockout result, the
|
|
249
|
+
* product could not produce its own proof of search.
|
|
250
|
+
*/
|
|
251
|
+
export function knockoutSearches(run) {
|
|
252
|
+
const doc = knockoutDoc(run);
|
|
253
|
+
const searches = [];
|
|
254
|
+
|
|
255
|
+
for (const m of marksOf(doc)) {
|
|
256
|
+
// The term the sweep actually ran for this mark. One row per mark, always — a mark that was swept and
|
|
257
|
+
// surfaced nothing is the row a defensibility question is ABOUT.
|
|
258
|
+
searches.push({
|
|
259
|
+
id: `${m.name} S#1`, term: m.name, mark: m.name,
|
|
260
|
+
classes: m.classesSearched ?? [], jurisdictions: [], office: null,
|
|
261
|
+
matchShapes: ["exact"],
|
|
262
|
+
outcome: (Array.isArray(m.findings) && m.findings.length) ? "found" : "no-hit",
|
|
263
|
+
note: m.degraded ? "Research payload unavailable for this mark — rated as degraded." : null,
|
|
264
|
+
source: "knockout-findings.json",
|
|
265
|
+
});
|
|
266
|
+
for (const [i, n] of (Array.isArray(m.negatives) ? m.negatives : []).entries()) {
|
|
267
|
+
searches.push({
|
|
268
|
+
id: `${m.name} NR#${i + 1}`, term: n?.term ?? null, mark: m.name,
|
|
269
|
+
classes: m.classesSearched ?? [], jurisdictions: [], office: null, matchShapes: ["exact"],
|
|
270
|
+
outcome: "no-hit", note: n?.note ?? null, source: n?.source ?? "knockout-findings.json",
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
// The register lane's own asked-and-unanswered terms, when it ran. `terms[].ok === false` is a search
|
|
275
|
+
// that did NOT answer — reporting it as a clean no-hit would be the un-run check dressed as a negative.
|
|
276
|
+
const recordsDoc = readJson(koPaths(run.runDir).registerRecords);
|
|
277
|
+
for (const entry of (Array.isArray(recordsDoc?.marks) ? recordsDoc.marks : [])) {
|
|
278
|
+
for (const t of (Array.isArray(entry.terms) ? entry.terms : [])) {
|
|
279
|
+
searches.push({
|
|
280
|
+
id: `${entry.name} REG:${t.term}`, term: t.term, mark: entry.name,
|
|
281
|
+
classes: entry.classes ?? [], jurisdictions: [], office: recordsDoc.providerLabel ?? recordsDoc.provider ?? null,
|
|
282
|
+
matchShapes: [t.basis ?? "exact"],
|
|
283
|
+
outcome: t.ok === false ? "recorded" : "found",
|
|
284
|
+
note: t.ok === false ? `This search did not answer: ${t.reason ?? "no reason recorded"}` : null,
|
|
285
|
+
source: "register-records.json",
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return { count: searches.length, searches, source: doc ? "knockout-findings.json" : "none" };
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// ── coverage ─────────────────────────────────────────────────────────────────────────────────────────
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* What the search covered, in `coverageStatement`'s shape ({ areas, note }).
|
|
296
|
+
*
|
|
297
|
+
* A knockout keeps no coverage LEDGER — that artifact is the clearance lane's, and saying "this run
|
|
298
|
+
* records no coverage ledger" was true and useless. What it does hold is a per-mark record of what was
|
|
299
|
+
* swept and what the register lane did, and that is what an area is here.
|
|
300
|
+
*/
|
|
301
|
+
export function knockoutCoverage(run) {
|
|
302
|
+
const doc = knockoutDoc(run);
|
|
303
|
+
if (!doc) {
|
|
304
|
+
return {
|
|
305
|
+
...notProducedOnThisProduct("a coverage statement before its assess stage completes"),
|
|
306
|
+
areas: [],
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
const areas = marksOf(doc).map((m) => ({
|
|
310
|
+
area: `${m.name} — common-law and marketplace sweep`,
|
|
311
|
+
state: m.degraded ? "Partially covered" : "Searched",
|
|
312
|
+
// NEVER "clean". This lane's own doctrine: a mark this screen did not knock out is not knocked out at
|
|
313
|
+
// the configured depth — a result about the SCREEN, not about the mark.
|
|
314
|
+
detail: m.degraded
|
|
315
|
+
? "Research could not be completed for this name; the rating reflects an analytical assessment pending fuller data."
|
|
316
|
+
: `Screened at the configured depth${(m.classesSearched ?? []).length ? ` in classes ${m.classesSearched.join(", ")}` : ""}. `
|
|
317
|
+
+ `${(m.findings ?? []).length} conflict(s) recorded, ${(m.negatives ?? []).length} search(es) recorded as returning nothing.`,
|
|
318
|
+
}));
|
|
319
|
+
|
|
320
|
+
const recordsDoc = readJson(koPaths(run.runDir).registerRecords);
|
|
321
|
+
const countsDoc = readJson(koPaths(run.runDir).registerCounts);
|
|
322
|
+
if (recordsDoc || countsDoc) {
|
|
323
|
+
areas.push({
|
|
324
|
+
area: "Register",
|
|
325
|
+
state: recordsDoc?.unavailable ? "Open item" : "Searched",
|
|
326
|
+
detail: recordsDoc?.unavailable
|
|
327
|
+
? String(recordsDoc.unavailable)
|
|
328
|
+
: "Filings were fetched and counted for the searched names; the filings themselves are in list_evidence.",
|
|
329
|
+
});
|
|
330
|
+
} else {
|
|
331
|
+
areas.push({
|
|
332
|
+
area: "Register",
|
|
333
|
+
state: "Not run this run",
|
|
334
|
+
detail: "This run has no register component — the assessment rests on the common-law and marketplace sweep.",
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
return {
|
|
338
|
+
areas,
|
|
339
|
+
note: "A Knockout search screens; it does not enumerate. An area marked Searched means it was screened "
|
|
340
|
+
+ "at the configured depth and nothing blocking surfaced there — never that the name is clear.",
|
|
341
|
+
source: "knockout-findings.json",
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// ── trace ────────────────────────────────────────────────────────────────────────────────────────────
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* The stages this lane runs, in pipeline order. `trace`'s table is the clearance STAGE_ORDER, so its error
|
|
349
|
+
* enumerated fifteen stages and none of them was a knockout stage — the tool could resolve nothing on this
|
|
350
|
+
* product, including the word "verdict".
|
|
351
|
+
*
|
|
352
|
+
* `knockout-assess` is chunked (`knockout-assess#N`), so a caller may name the bare stage or one chunk.
|
|
353
|
+
*/
|
|
354
|
+
export const KNOCKOUT_STAGES = ["knockout-frame", "knockout-sweep", "knockout-register", "knockout-assess"];
|
|
355
|
+
|
|
356
|
+
export function knockoutStageFor(target) {
|
|
357
|
+
const t = String(target ?? "").trim();
|
|
358
|
+
const bare = t.split("#")[0];
|
|
359
|
+
return KNOCKOUT_STAGES.includes(bare) ? t : null;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* `trace` for this lane — HOW the run reached its answer, from the run's own event log.
|
|
364
|
+
*
|
|
365
|
+
* Deliberately NOT threaded through the clearance trace's walk. That walk is built on `paths()`, the
|
|
366
|
+
* register axes and the clearance findings spine; teaching it a second lane would put a knockout branch in
|
|
367
|
+
* every one of its enrichments, and the clearance trace is the surface that currently works. This answers
|
|
368
|
+
* the same question off the artifacts this product actually writes.
|
|
369
|
+
*
|
|
370
|
+
* `events` is the caller's already-read run log, passed in so this module never re-reads it.
|
|
371
|
+
*/
|
|
372
|
+
export function traceKnockout(run, target, events = []) {
|
|
373
|
+
const t = String(target ?? "").trim();
|
|
374
|
+
const doc = knockoutDoc(run);
|
|
375
|
+
const verdict = () => ({
|
|
376
|
+
kind: "verdict",
|
|
377
|
+
verdict: doc?.batch?.overall ?? runVerdictFromEvents(events) ?? null,
|
|
378
|
+
marks: marksOf(doc).map((m) => ({ mark: m.name, band: m.rating ?? null, basis: m.basis ?? null })),
|
|
379
|
+
note: "A Knockout verdict is the batch's worst band across its marks; each mark's own band and the "
|
|
380
|
+
+ "one-sentence ground for it are listed here.",
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
if (!t || /^verdict$/i.test(t)) return { runId: run.runId, target: t || "verdict", ...verdict() };
|
|
384
|
+
|
|
385
|
+
const stage = knockoutStageFor(t);
|
|
386
|
+
if (stage) {
|
|
387
|
+
const bare = stage.split("#")[0];
|
|
388
|
+
const rows = events.filter((e) => String(e.stage ?? "").split("#")[0] === bare
|
|
389
|
+
|| String(e.event ?? "").startsWith(bare));
|
|
390
|
+
return {
|
|
391
|
+
runId: run.runId, target: t, kind: "stage", stage,
|
|
392
|
+
events: rows,
|
|
393
|
+
// What the stage wrote, by presence — the honest answer to "did this stage produce anything".
|
|
394
|
+
produced: knockoutArtifacts(run).filter((a) => a.exists && STAGE_OUTPUTS[bare]?.includes(a.name)),
|
|
395
|
+
note: STAGE_NOTES[bare] ?? null,
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// A mark or an owner named directly — the fuzzy target the clearance trace also supports.
|
|
400
|
+
const hit = marksOf(doc).find((m) => String(m.name ?? "").toLowerCase().includes(t.toLowerCase()));
|
|
401
|
+
if (hit) {
|
|
402
|
+
return {
|
|
403
|
+
runId: run.runId, target: t, kind: "mark", mark: hit.name, band: hit.rating ?? null,
|
|
404
|
+
basis: hit.basis ?? null, factors: hit.factors ?? [], counterFactors: hit.counterFactors ?? [],
|
|
405
|
+
findings: (hit.findings ?? []).map((f) => ({ ordinal: f.ordinal, name: f.name, band: f.band, evidence: f.evidence ?? [] })),
|
|
406
|
+
registerReads: hit.registerReads ?? [],
|
|
407
|
+
note: "The band, the one-sentence ground for it, and the observations it rests on.",
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
return {
|
|
412
|
+
runId: run.runId, target: t,
|
|
413
|
+
error: `Could not resolve target "${t}" on this Knockout search. Try a stage (${KNOCKOUT_STAGES.join(", ")}), `
|
|
414
|
+
+ `a mark name, an artifact (${knockoutArtifacts(run).filter((a) => a.exists).map((a) => a.name).join(", ")}), or "verdict".`,
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// Which artifacts each stage is responsible for — used to answer "did it produce anything" by presence
|
|
419
|
+
// rather than by trusting a completion event, which is written before the file is fsynced.
|
|
420
|
+
const STAGE_OUTPUTS = {
|
|
421
|
+
"knockout-frame": ["frame", "plan"],
|
|
422
|
+
"knockout-sweep": ["sweepLedger"],
|
|
423
|
+
"knockout-register": ["registerCounts", "registerRecords"],
|
|
424
|
+
"knockout-assess": ["findings", "assessment"],
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
const STAGE_NOTES = {
|
|
428
|
+
"knockout-frame": "Reads the order and writes the plan: which names, which classes, at what depth.",
|
|
429
|
+
"knockout-sweep": "One research call per mark against the marketplace/common-law provider; the payloads land in research/.",
|
|
430
|
+
"knockout-register": "Fetches and counts register filings for the searched names. Absent on a run with no register component.",
|
|
431
|
+
"knockout-assess": "Rates each mark from its own payload and the fetched filings, and writes knockout-findings.json.",
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
const runVerdictFromEvents = (events) =>
|
|
435
|
+
[...events].reverse().find((e) => e.event === "verdict")?.verdict ?? null;
|
package/mcp-server/lib/ops.mjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// lib/ops.mjs — the OPS write-face for the MCP server: start_run / stop_run / feed_context.
|
|
4
4
|
//
|
|
5
5
|
// ops-token-only (enforced centrally in scope.authorize — these are never reachable by a user/internal
|
|
6
|
-
// session). Writes ONLY within an agent's own
|
|
6
|
+
// session). Writes ONLY within an agent's own clearotron queue + run dirs (the same surface the runner already
|
|
7
7
|
// drains); shells nothing, spawns nothing. start_run enqueues a job the live runner picks up; stop_run
|
|
8
8
|
// dequeues a not-yet-claimed job (a real cancel) or files a cancel request for a running one; feed_context
|
|
9
9
|
// writes the late-bind applicant binding (customer-bind.json) the pipeline's pre-start bind already reads.
|
|
@@ -211,7 +211,7 @@ export const START_RUN_JOB_FIELDS = Object.freeze({
|
|
|
211
211
|
+ "which writes the field directly rather than asking this tool for it (tracker issue 2038).",
|
|
212
212
|
promptParts: "the requester's declaration that the prose rides as SIDECAR files. This door assembles from "
|
|
213
213
|
+ "structured tool input and writes no sidecars, so a job it built cannot be in that shape. Carrying it "
|
|
214
|
-
+ "would make the manifest claim an intake it did not use, and
|
|
214
|
+
+ "would make the manifest claim an intake it did not use, and the manifest check would then report sidecars "
|
|
215
215
|
+ "missing on a job that never had any.",
|
|
216
216
|
name: "the pre-markName spelling of the search subject. The schema offers markName/marks[]; a second "
|
|
217
217
|
+ "name field would give one door two answers to 'what is being cleared'.",
|
|
@@ -229,7 +229,7 @@ export function assertScopedProfileKey(args, scope, verb) {
|
|
|
229
229
|
throw new Error(`${verb}: an accounts-scoped session must set profileKey explicitly (domain-based customer resolution is not available to scoped tokens)`);
|
|
230
230
|
}
|
|
231
231
|
|
|
232
|
-
// start_run — enqueue a
|
|
232
|
+
// start_run — enqueue a clearotron job the runner will drain. Returns the queue id + slug; the runId/codename is
|
|
233
233
|
// assigned by the runner on claim, so the caller polls list_runs(slug) / run_changes for it.
|
|
234
234
|
export function startRun(args = {}, { scope } = {}) {
|
|
235
235
|
const agent = args.agent ? String(args.agent) : "";
|
|
@@ -596,7 +596,7 @@ export function markSent(args = {}) {
|
|
|
596
596
|
// forever — the alreadySent early-return then suppressed every retry of this cleanup. Making the
|
|
597
597
|
// removal idempotent lets a retried mark_sent finish the cleanup a killed first call left undone.
|
|
598
598
|
//
|
|
599
|
-
// EVERY FORM THE RUN WAS EVER KNOWN BY, not just one (post-merge audit 2). A pre- packet carries the
|
|
599
|
+
// EVERY FORM THE RUN WAS EVER KNOWN BY, not just one (post-merge audit 2). A pre-change packet carries the
|
|
600
600
|
// legacy dateless `<slug>-<codename>` runId while the resolved run's own id is the dated canonical
|
|
601
601
|
// `<slug>-<date>-<codename>` — a run delivered on 2026-07-29 still has exactly that pair on disk, its
|
|
602
602
|
// _driver/delivery.json naming the dateless form and its status.json the dated one. That is also why
|
|
@@ -62,7 +62,7 @@ const HEADLINE = {
|
|
|
62
62
|
};
|
|
63
63
|
|
|
64
64
|
// THE BUNDLES ARE GONE, and their deletion is the change rather than a tidy-up. They were three
|
|
65
|
-
// hand-written shortcuts — `knockout` / `global-
|
|
65
|
+
// hand-written shortcuts — `knockout` / `global-clearotron` / `deep-dive` — each carrying a `searchLevel`
|
|
66
66
|
// plus a `caseLaw` flag, and each naming a product ("Full deep dive") that appeared in no registry, on
|
|
67
67
|
// no report and on no wire. That is what a bundle IS when the wire does not carry the product: a second
|
|
68
68
|
// menu, invented to say the thing the first menu could not. The wire carries the product now, so the
|
package/mcp-server/lib/plan.mjs
CHANGED
|
@@ -42,7 +42,7 @@ import { BRAND } from "../../shared/brand.mjs"; // — the operator name in th
|
|
|
42
42
|
// whether to buy it.
|
|
43
43
|
export const PLAN_CAVEAT = "Ratings reflect our common law assessment. Register analysis may adjust ratings in either direction.";
|
|
44
44
|
|
|
45
|
-
// THE INVERTED CAVEAT WENT WITH THE LEVEL (
|
|
45
|
+
// THE INVERTED CAVEAT WENT WITH THE LEVEL (2026-08-06). A second caveat existed for one reason:
|
|
46
46
|
// register-only ran the halves the other way round, so "ratings reflect our common law assessment" would
|
|
47
47
|
// have described an assessment that never ran. That level is retired and no resolution reaches this file
|
|
48
48
|
// without one — a plan describes a run that WOULD start, and none of them can be register-only — so
|
package/mcp-server/lib/runs.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
2
|
// Copyright 2026 Cordillera Sàrl. Additional terms under section 7 of the AGPL-3.0 apply — see ADDITIONAL-TERMS.md
|
|
3
|
-
// lib/runs.mjs — discover + resolve
|
|
3
|
+
// lib/runs.mjs — discover + resolve clearotron run-dirs (in-flight AND archived) across every agent workspace.
|
|
4
4
|
//
|
|
5
5
|
// Read-only. We MIRROR the driver's own status walk (progress.mjs `findStatusFiles`) here rather than
|
|
6
6
|
// importing it, so the MCP stays a pure additive consumer (no edit to the shared driver file the parallel
|
package/mcp-server/lib/scrub.mjs
CHANGED
|
@@ -54,7 +54,7 @@ export const CLIENT_FRONT_MATTER = new Set([
|
|
|
54
54
|
// `Generic default (generic) · Generic default framework · profile d37721cda899` → drop the profile segment.
|
|
55
55
|
// The framework title is client-facing (report footer: "Rated under <title>"); the profile hash is the
|
|
56
56
|
// internal identity of the config that rated the matter and is not. A custom framework carries its source
|
|
57
|
-
// FILENAME too (`custom framework:
|
|
57
|
+
// FILENAME too (`custom framework: Foxglade Interactive ACP risk framework (risk-framework-foxglade.md)`) — the
|
|
58
58
|
// human title stays, the file is config identity and goes.
|
|
59
59
|
function ratedUnderForClient(v) {
|
|
60
60
|
return String(v ?? "").split("·").map((s) => s.trim())
|
|
@@ -158,7 +158,7 @@ export function scrubMarkdown(text) {
|
|
|
158
158
|
// at least announced itself as internal.
|
|
159
159
|
//
|
|
160
160
|
// The ruling needed no new product decision, because the product had already made it:
|
|
161
|
-
// `publish/report-data.mjs:
|
|
161
|
+
// `publish/report-data.mjs:74` (`const live`) filters to live findings, "a withdrawn finding renders nowhere — it does
|
|
162
162
|
// not exist here either". Two client surfaces, one question, two answers. So the block is DROPPED, and
|
|
163
163
|
// the two agree by construction rather than key by key — which is the thing asked not to repeat.
|
|
164
164
|
//
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
import { STAGES, STAGE_ORDER, stageOrdinal, REGISTER_AXES, axisTier, resolveModel, config, deriveSlug } from "./driver.mjs";
|
|
24
24
|
import { readCapped } from "./util.mjs";
|
|
25
25
|
import { join, basename } from "node:path";
|
|
26
|
-
import { readFileSync } from "node:fs"; //
|
|
26
|
+
import { readFileSync } from "node:fs"; // the canonical run's frozen profile
|
|
27
27
|
import { driverDir } from "../../shared/driver-dir.mjs"; //
|
|
28
28
|
// — the SHARED eligibility composer. A leaf module (fs/path/crypto only), so a
|
|
29
29
|
// static import here costs the read-only surface nothing and buys the one thing three copies of this
|
|
@@ -252,7 +252,7 @@ export async function whatIfRun({ confirmationToken } = {}, deps = {}) {
|
|
|
252
252
|
// askArchivedRun answers {ok:true, memoPath, memoId, parentRunId, assumption, ratedUnder,
|
|
253
253
|
// statedLimits} or {ok:false, fail, detail} — a stable MEMO_FAILS code, never a throw, because the
|
|
254
254
|
// worker records what it is handed and a throw there becomes a string nobody can branch on.
|
|
255
|
-
// THE RESOLVER IS HANDED OVER, and this line is the whole of
|
|
255
|
+
// THE RESOLVER IS HANDED OVER, and this line is the whole of the first defect.
|
|
256
256
|
// `askArchivedRun` takes its resolver from `deps` and has no default for it — `reason` was given one
|
|
257
257
|
// and `resolveRun` was not — so calling it bare returned `memo_run_unresolved` for every memo on
|
|
258
258
|
// every run, while `resolveRun(runId)` eight lines above had already resolved that same run fine.
|
|
@@ -278,8 +278,8 @@ export async function whatIfRun({ confirmationToken } = {}, deps = {}) {
|
|
|
278
278
|
// The reconstruction above carries six fields and resolveProfile keys on none of them. It reads
|
|
279
279
|
// `job.profileKey` first, then falls back to `job.forwarderDomain`; the job has `forwarder` but not
|
|
280
280
|
// `forwarderDomain`, and no profileKey at all. So BOTH resolution routes were dead here and every
|
|
281
|
-
// what-if silently resolved to the house `generic` profile. Measured on a
|
|
282
|
-
// {"event":"profile-mismatch","sidecar":"
|
|
281
|
+
// what-if silently resolved to the house `generic` profile. Measured on a test-account run:
|
|
282
|
+
// {"event":"profile-mismatch","sidecar":"burrowell","resolved":"generic"} — while the client-facing
|
|
283
283
|
// result reported ok:true and "Sandboxed re-run complete" and said nothing.
|
|
284
284
|
//
|
|
285
285
|
// WHY THAT IS WORSE THAN A WRONG LABEL. A what-if changes ONE thing and reads the difference. This
|
|
@@ -324,7 +324,7 @@ export async function whatIfRun({ confirmationToken } = {}, deps = {}) {
|
|
|
324
324
|
shadowDir: basename(r.shadowDir), output: r.output ? basename(r.output) : null,
|
|
325
325
|
completeness: comp.level, honestyNote: comp.note,
|
|
326
326
|
diff, telemetryDelta,
|
|
327
|
-
//
|
|
327
|
+
// the rating authority this diff was produced under, on the client-facing
|
|
328
328
|
// result. The engine KNEW (it wrote a profile-mismatch row) and the surface said nothing, which is
|
|
329
329
|
// the one case where the evidence exists on disk and the reader cannot reach it. Null means the
|
|
330
330
|
// canonical run froze no profile — a pre-profile run, where `generic` is the right answer rather
|
|
@@ -91,7 +91,7 @@ export function mintFromOptions({ scope, sub = null, runId = null, ttlDays, verb
|
|
|
91
91
|
: scope === "account" ? "(n/a — the fixed account tool set)"
|
|
92
92
|
: "(n/a — read-only, one run)";
|
|
93
93
|
const acctEcho = t.accounts ? t.accounts.join(",") : scope === "account" ? "(whatever the grants file grants this identity)" : "(all)";
|
|
94
|
-
// THE LEVERS, IN THE ORDER THAT WORKS (
|
|
94
|
+
// THE LEVERS, IN THE ORDER THAT WORKS (found in review).
|
|
95
95
|
//
|
|
96
96
|
// The denylist was named FIRST and named without a path — "the TRADEMARK_MCP_TOKEN_DENYLIST file",
|
|
97
97
|
// a variable an operator never set and a file that, on a default install, did not exist. Since
|
package/mcp-server/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "trademark-artifacts-mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"license": "AGPL-3.0-only",
|
|
5
5
|
"private": true,
|
|
6
|
-
"description": "MCP server to interrogate
|
|
6
|
+
"description": "MCP server to interrogate clearotron trademark-clearance runs — list/read artifacts, trace the full decision flow, telemetry/cost, coverage, single-run search, and a gated single-step what-if. Imports the clearotron-driver read-only; touches no driver/template/deploy files.",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "server.mjs",
|
|
9
9
|
"scripts": {
|
|
@@ -29,8 +29,8 @@ original message. It does not guess.
|
|
|
29
29
|
|
|
30
30
|
## Late applicant binding
|
|
31
31
|
|
|
32
|
-
Requester (mid-run): *"the applicant will be
|
|
33
|
-
customer: "
|
|
32
|
+
Requester (mid-run): *"the applicant will be Coastline Drinks Ltd"* → `feed_context { runId,
|
|
33
|
+
customer: "Coastline Drinks Ltd" }` → the outbox later carries a `late-bind-ack` to relay.
|
|
34
34
|
|
|
35
35
|
## Courier wake
|
|
36
36
|
|