@xgent-ai/skills 0.1.0 → 0.4.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.
Files changed (1043) hide show
  1. package/README.md +124 -4
  2. package/bin/xgent-skills.js +561 -4
  3. package/package.json +7 -3
  4. package/skills/agi-mode/SKILL.md +225 -0
  5. package/skills/agi-mode/evals/baseline-coverage.md +96 -0
  6. package/skills/agi-mode/evals/scenarios.md +331 -0
  7. package/skills/agi-mode/evals/test_check_evidence.py +141 -0
  8. package/skills/agi-mode/playbooks/arena.md +47 -0
  9. package/skills/agi-mode/playbooks/authoring-a-skill.md +26 -0
  10. package/skills/agi-mode/playbooks/autonomous-run.md +39 -0
  11. package/skills/agi-mode/playbooks/bug-fix.md +27 -0
  12. package/skills/agi-mode/playbooks/design-prototype.md +41 -0
  13. package/skills/agi-mode/playbooks/eval.md +72 -0
  14. package/skills/agi-mode/playbooks/feature.md +26 -0
  15. package/skills/agi-mode/playbooks/forensics.md +31 -0
  16. package/skills/agi-mode/playbooks/hillclimb.md +73 -0
  17. package/skills/agi-mode/playbooks/investigation.md +29 -0
  18. package/skills/agi-mode/playbooks/migration-refactoring.md +27 -0
  19. package/skills/agi-mode/playbooks/optimization.md +27 -0
  20. package/skills/agi-mode/playbooks/pr-lifecycle.md +38 -0
  21. package/skills/agi-mode/playbooks/program.md +57 -0
  22. package/skills/agi-mode/playbooks/reflection.md +41 -0
  23. package/skills/agi-mode/playbooks/resource-cleanup.md +24 -0
  24. package/skills/agi-mode/playbooks/review.md +27 -0
  25. package/skills/agi-mode/playbooks/session-handoff.md +37 -0
  26. package/skills/agi-mode/playbooks/shipping.md +35 -0
  27. package/skills/agi-mode/playbooks/ui-delivery.md +34 -0
  28. package/skills/agi-mode/playbooks/unblock.md +54 -0
  29. package/skills/agi-mode/principles/autonomous-decisions.md +21 -0
  30. package/skills/agi-mode/principles/behavioral-tests.md +21 -0
  31. package/skills/agi-mode/principles/boundary-discipline.md +21 -0
  32. package/skills/agi-mode/principles/bounded-convergence.md +21 -0
  33. package/skills/agi-mode/principles/build-leverage.md +21 -0
  34. package/skills/agi-mode/principles/challenge-premises.md +21 -0
  35. package/skills/agi-mode/principles/complete-migrations.md +21 -0
  36. package/skills/agi-mode/principles/context-as-state.md +21 -0
  37. package/skills/agi-mode/principles/critical-path-throughput.md +21 -0
  38. package/skills/agi-mode/principles/domain-models-and-types.md +23 -0
  39. package/skills/agi-mode/principles/evidence-lifetime.md +21 -0
  40. package/skills/agi-mode/principles/experience-first.md +21 -0
  41. package/skills/agi-mode/principles/explore-alternatives.md +21 -0
  42. package/skills/agi-mode/principles/falsifiable-verification.md +21 -0
  43. package/skills/agi-mode/principles/foundations-first.md +21 -0
  44. package/skills/agi-mode/principles/idempotent-effects.md +21 -0
  45. package/skills/agi-mode/principles/information-first.md +21 -0
  46. package/skills/agi-mode/principles/minimize-complexity.md +21 -0
  47. package/skills/agi-mode/principles/outcome-ownership.md +21 -0
  48. package/skills/agi-mode/principles/prove-real-outcomes.md +21 -0
  49. package/skills/agi-mode/principles/redesign-from-constraints.md +21 -0
  50. package/skills/agi-mode/principles/root-cause.md +21 -0
  51. package/skills/agi-mode/principles/state-ownership.md +21 -0
  52. package/skills/agi-mode/principles/structural-learning.md +21 -0
  53. package/skills/agi-mode/principles/verifiable-units.md +21 -0
  54. package/skills/agi-mode/references/continuity.md +75 -0
  55. package/skills/agi-mode/references/eval-protocol.md +71 -0
  56. package/skills/agi-mode/references/evidence-contract.md +57 -0
  57. package/skills/agi-mode/references/evolution-evidence.md +71 -0
  58. package/skills/agi-mode/references/experiments.md +82 -0
  59. package/skills/agi-mode/references/reflection/divergent-reviewer.md +45 -0
  60. package/skills/agi-mode/references/reflection/judgment-reviewer.md +44 -0
  61. package/skills/agi-mode/references/reflection/synthesizer.md +39 -0
  62. package/skills/agi-mode/references/reflection/tooling-reviewer.md +57 -0
  63. package/skills/agi-mode/references/skill-evolution.md +50 -0
  64. package/skills/agi-mode/scripts/check_evidence.py +147 -0
  65. package/skills/apply-code-review/SKILL.md +53 -0
  66. package/skills/apply-code-review/agents/openai.yaml +4 -0
  67. package/skills/apply-code-review/references/record-contract.md +77 -0
  68. package/skills/apply-doc-review/SKILL.md +79 -0
  69. package/skills/apply-doc-review/agents/openai.yaml +4 -0
  70. package/skills/apply-doc-review/references/disposition-contract.md +57 -0
  71. package/skills/archify/LICENSE +22 -0
  72. package/skills/archify/SKILL.md +137 -0
  73. package/skills/archify/THIRD_PARTY_NOTICES.md +69 -0
  74. package/skills/archify/assets/JetBrainsMono-OFL.txt +93 -0
  75. package/skills/archify/assets/template.html +14937 -0
  76. package/skills/archify/bin/archify.mjs +2139 -0
  77. package/skills/archify/bin/open-artifact.mjs +86 -0
  78. package/skills/archify/bin/preview.mjs +653 -0
  79. package/skills/archify/bin/visual-check.mjs +829 -0
  80. package/skills/archify/brand-marks/README.md +31 -0
  81. package/skills/archify/brand-marks/catalog.json +131 -0
  82. package/skills/archify/delta/architecture-delta.mjs +1232 -0
  83. package/skills/archify/examples/agent-run.lifecycle.json +60 -0
  84. package/skills/archify/examples/agent-tool-call.workflow.json +94 -0
  85. package/skills/archify/examples/async-job-roundtrip.sequence.json +61 -0
  86. package/skills/archify/examples/brand-aware-delivery.architecture.json +47 -0
  87. package/skills/archify/examples/cache-miss-request.sequence.json +82 -0
  88. package/skills/archify/examples/checkout-platform.base.architecture.json +31 -0
  89. package/skills/archify/examples/checkout-platform.head.architecture.json +31 -0
  90. package/skills/archify/examples/dataflow-product-analytics.html +15048 -0
  91. package/skills/archify/examples/deployment-release.lifecycle.json +49 -0
  92. package/skills/archify/examples/event-stream.dataflow.json +57 -0
  93. package/skills/archify/examples/incident-response.workflow.json +64 -0
  94. package/skills/archify/examples/lifecycle-agent-run.html +14983 -0
  95. package/skills/archify/examples/product-analytics.dataflow.json +76 -0
  96. package/skills/archify/examples/production-deployment.architecture.json +71 -0
  97. package/skills/archify/examples/release-delivery.workflow.json +62 -0
  98. package/skills/archify/examples/sequence-cache-miss-request.html +15063 -0
  99. package/skills/archify/examples/web-app-rendered.html +15012 -0
  100. package/skills/archify/examples/web-app.architecture.json +46 -0
  101. package/skills/archify/examples/workflow-agent-tool-call-rendered.html +15054 -0
  102. package/skills/archify/migrations/workflow-v2.mjs +279 -0
  103. package/skills/archify/package-lock.json +149 -0
  104. package/skills/archify/package.json +39 -0
  105. package/skills/archify/recipes/scenarios.mjs +391 -0
  106. package/skills/archify/references/authoring-contract.md +247 -0
  107. package/skills/archify/references/brand-marks.md +65 -0
  108. package/skills/archify/references/delivery-contract.md +138 -0
  109. package/skills/archify/references/viewer-runtime.md +45 -0
  110. package/skills/archify/renderers/architecture/grid.mjs +62 -0
  111. package/skills/archify/renderers/architecture/render-architecture.mjs +1078 -0
  112. package/skills/archify/renderers/dataflow/README.md +104 -0
  113. package/skills/archify/renderers/dataflow/render-dataflow.mjs +483 -0
  114. package/skills/archify/renderers/lifecycle/README.md +115 -0
  115. package/skills/archify/renderers/lifecycle/render-lifecycle.mjs +561 -0
  116. package/skills/archify/renderers/sequence/README.md +114 -0
  117. package/skills/archify/renderers/sequence/render-sequence.mjs +464 -0
  118. package/skills/archify/renderers/shared/brand-marks.mjs +563 -0
  119. package/skills/archify/renderers/shared/cli.mjs +218 -0
  120. package/skills/archify/renderers/shared/desktop-readability.mjs +26 -0
  121. package/skills/archify/renderers/shared/diagnostics.mjs +160 -0
  122. package/skills/archify/renderers/shared/engineering-profiles.mjs +157 -0
  123. package/skills/archify/renderers/shared/generated-brand-marks.mjs +2003 -0
  124. package/skills/archify/renderers/shared/generated-validators.mjs +13 -0
  125. package/skills/archify/renderers/shared/geometry.mjs +1423 -0
  126. package/skills/archify/renderers/shared/i18n.mjs +595 -0
  127. package/skills/archify/renderers/shared/layout-report.mjs +40 -0
  128. package/skills/archify/renderers/shared/legend.mjs +217 -0
  129. package/skills/archify/renderers/shared/output-path.mjs +340 -0
  130. package/skills/archify/renderers/shared/repository-evidence.mjs +239 -0
  131. package/skills/archify/renderers/shared/repository-location.mjs +58 -0
  132. package/skills/archify/renderers/shared/text-fit.mjs +49 -0
  133. package/skills/archify/renderers/shared/utils.mjs +232 -0
  134. package/skills/archify/renderers/shared/validator.mjs +86 -0
  135. package/skills/archify/renderers/workflow/README.md +223 -0
  136. package/skills/archify/renderers/workflow/render-workflow.mjs +35 -0
  137. package/skills/archify/renderers/workflow/workflow-compiler.mjs +4400 -0
  138. package/skills/archify/renderers/workflow/workflow-migration-geometry.mjs +144 -0
  139. package/skills/archify/schemas/README.md +211 -0
  140. package/skills/archify/schemas/architecture.schema.json +178 -0
  141. package/skills/archify/schemas/common.schema.json +115 -0
  142. package/skills/archify/schemas/dataflow.schema.json +243 -0
  143. package/skills/archify/schemas/lifecycle.schema.json +266 -0
  144. package/skills/archify/schemas/sequence.schema.json +223 -0
  145. package/skills/archify/schemas/workflow.schema.json +428 -0
  146. package/skills/archify/scripts/check-render-output.mjs +916 -0
  147. package/skills/archify/scripts/check-update.mjs +1667 -0
  148. package/skills/archify/scripts/generate-brand-marks.mjs +141 -0
  149. package/skills/archify/scripts/generate-validators.mjs +66 -0
  150. package/skills/archify/scripts/render-examples.mjs +26 -0
  151. package/skills/archify/scripts/update-contract.mjs +182 -0
  152. package/skills/archify/skill-release.json +10 -0
  153. package/skills/archify/test/adaptive-reader-layout.test.mjs +86 -0
  154. package/skills/archify/test/animation.test.mjs +179 -0
  155. package/skills/archify/test/architecture-compare-recovery.test.mjs +157 -0
  156. package/skills/archify/test/architecture-delta-markers.test.mjs +137 -0
  157. package/skills/archify/test/architecture-delta.test.mjs +705 -0
  158. package/skills/archify/test/artifact-receipt-flush.test.mjs +126 -0
  159. package/skills/archify/test/authored-reachability.test.mjs +95 -0
  160. package/skills/archify/test/authoring-safety-contract.test.mjs +54 -0
  161. package/skills/archify/test/automatic-port-spread.test.mjs +376 -0
  162. package/skills/archify/test/base-input-compatibility.test.mjs +42 -0
  163. package/skills/archify/test/brand-marks.test.mjs +678 -0
  164. package/skills/archify/test/chapter-delta-preview.test.mjs +157 -0
  165. package/skills/archify/test/chapter-handoff.test.mjs +97 -0
  166. package/skills/archify/test/chapter-rail.test.mjs +86 -0
  167. package/skills/archify/test/checkout-line-endings.test.mjs +72 -0
  168. package/skills/archify/test/ci-scope.test.mjs +59 -0
  169. package/skills/archify/test/clean-skill-staging.test.mjs +440 -0
  170. package/skills/archify/test/cli-output-types.test.mjs +201 -0
  171. package/skills/archify/test/cli.test.mjs +986 -0
  172. package/skills/archify/test/community-proof-intake.test.mjs +125 -0
  173. package/skills/archify/test/cursor-onboarding.test.mjs +74 -0
  174. package/skills/archify/test/degraded.test.mjs +161 -0
  175. package/skills/archify/test/delivery-contract.test.mjs +52 -0
  176. package/skills/archify/test/desktop-reader-browser.test.mjs +80 -0
  177. package/skills/archify/test/diagram-guide.test.mjs +92 -0
  178. package/skills/archify/test/engineering-profile.test.mjs +209 -0
  179. package/skills/archify/test/export-browser.test.mjs +305 -0
  180. package/skills/archify/test/export-cleanup-browser.test.mjs +294 -0
  181. package/skills/archify/test/finder-browser.test.mjs +274 -0
  182. package/skills/archify/test/finder.test.mjs +104 -0
  183. package/skills/archify/test/fixtures/automatic-routing-node-border-clearance.workflow.json +40 -0
  184. package/skills/archify/test/fixtures/fail-migration-cleanup.mjs +17 -0
  185. package/skills/archify/test/fixtures/issue-126/custom-widths.workflow.json +18 -0
  186. package/skills/archify/test/fixtures/issue-126/explicit-route.workflow.json +28 -0
  187. package/skills/archify/test/fixtures/issue-126/explicit-viewbox.workflow.json +19 -0
  188. package/skills/archify/test/fixtures/issue-126/labels.workflow.json +18 -0
  189. package/skills/archify/test/fixtures/v1-baseline/agent-run.lifecycle.json +64 -0
  190. package/skills/archify/test/fixtures/v1-baseline/agent-tool-call.workflow.json +88 -0
  191. package/skills/archify/test/fixtures/v1-baseline/cache-miss-request.sequence.json +75 -0
  192. package/skills/archify/test/fixtures/v1-baseline/event-stream.dataflow.json +57 -0
  193. package/skills/archify/test/fixtures/v1-baseline/product-analytics.dataflow.json +70 -0
  194. package/skills/archify/test/fixtures/v1-baseline/production-deployment.architecture.json +71 -0
  195. package/skills/archify/test/fixtures/v1-baseline/web-app.architecture.json +41 -0
  196. package/skills/archify/test/fixtures/v1-workflow-700x400.workflow.json +22 -0
  197. package/skills/archify/test/fixtures/v1-workflow-explicit-coordinates.workflow.json +47 -0
  198. package/skills/archify/test/focus-browser.test.mjs +226 -0
  199. package/skills/archify/test/gallery.test.mjs +130 -0
  200. package/skills/archify/test/generate-validators.test.mjs +59 -0
  201. package/skills/archify/test/generate-viewer.test.mjs +165 -0
  202. package/skills/archify/test/generated-artifact-xml.test.mjs +88 -0
  203. package/skills/archify/test/geometry.test.mjs +739 -0
  204. package/skills/archify/test/golden.mjs +207 -0
  205. package/skills/archify/test/grid.test.mjs +47 -0
  206. package/skills/archify/test/guide-page.test.mjs +85 -0
  207. package/skills/archify/test/guide.test.mjs +81 -0
  208. package/skills/archify/test/guided-views-browser.test.mjs +460 -0
  209. package/skills/archify/test/guided-views.test.mjs +144 -0
  210. package/skills/archify/test/helpers/desktop-browser.mjs +48 -0
  211. package/skills/archify/test/helpers/offline-fonts.mjs +76 -0
  212. package/skills/archify/test/helpers/viewer-click.mjs +72 -0
  213. package/skills/archify/test/helpers/xml.mjs +37 -0
  214. package/skills/archify/test/i18n.test.mjs +422 -0
  215. package/skills/archify/test/intent-trace-browser.test.mjs +284 -0
  216. package/skills/archify/test/intent-trace.test.mjs +111 -0
  217. package/skills/archify/test/landing.test.mjs +97 -0
  218. package/skills/archify/test/layout-rules.test.mjs +1498 -0
  219. package/skills/archify/test/legend-contract.test.mjs +404 -0
  220. package/skills/archify/test/motion-governor-browser.test.mjs +342 -0
  221. package/skills/archify/test/motion-governor.test.mjs +111 -0
  222. package/skills/archify/test/offline-font-browser.test.mjs +210 -0
  223. package/skills/archify/test/offline-self-containment.test.mjs +80 -0
  224. package/skills/archify/test/open-artifact.test.mjs +118 -0
  225. package/skills/archify/test/ordinary-model-floor.test.mjs +1052 -0
  226. package/skills/archify/test/output-path.test.mjs +587 -0
  227. package/skills/archify/test/presentation.test.mjs +71 -0
  228. package/skills/archify/test/preset-tryon.test.mjs +113 -0
  229. package/skills/archify/test/preview-contract.test.mjs +40 -0
  230. package/skills/archify/test/preview.test.mjs +530 -0
  231. package/skills/archify/test/proof-aperture.test.mjs +78 -0
  232. package/skills/archify/test/reach-share-card.test.mjs +149 -0
  233. package/skills/archify/test/reader-layout-browser.test.mjs +320 -0
  234. package/skills/archify/test/readme-showcase.test.mjs +319 -0
  235. package/skills/archify/test/real-repository-proof.test.mjs +209 -0
  236. package/skills/archify/test/relationship-direct-explorer.test.mjs +115 -0
  237. package/skills/archify/test/relationship-lens.test.mjs +128 -0
  238. package/skills/archify/test/relationship-permalink.test.mjs +130 -0
  239. package/skills/archify/test/relationship-pulse.test.mjs +122 -0
  240. package/skills/archify/test/release-identity.test.mjs +476 -0
  241. package/skills/archify/test/release-package-gates.test.mjs +750 -0
  242. package/skills/archify/test/render-output-checks.test.mjs +588 -0
  243. package/skills/archify/test/renderer-diagnostic-boundary.test.mjs +107 -0
  244. package/skills/archify/test/repair-receipt.test.mjs +181 -0
  245. package/skills/archify/test/repository-evidence-replacement.test.mjs +136 -0
  246. package/skills/archify/test/repository-evidence.test.mjs +605 -0
  247. package/skills/archify/test/repository-language-metadata.test.mjs +67 -0
  248. package/skills/archify/test/route-journey.test.mjs +125 -0
  249. package/skills/archify/test/route-probe-browser.test.mjs +363 -0
  250. package/skills/archify/test/route-probe.test.mjs +114 -0
  251. package/skills/archify/test/route-share-card.test.mjs +163 -0
  252. package/skills/archify/test/semantic-camera.test.mjs +88 -0
  253. package/skills/archify/test/semantic-flow.test.mjs +90 -0
  254. package/skills/archify/test/semantic-legend-gateway.test.mjs +156 -0
  255. package/skills/archify/test/semantic-lens-browser.test.mjs +372 -0
  256. package/skills/archify/test/semantic-lens.test.mjs +103 -0
  257. package/skills/archify/test/semantic-passport.test.mjs +99 -0
  258. package/skills/archify/test/semantic-radar.test.mjs +735 -0
  259. package/skills/archify/test/semantic-zoom.test.mjs +86 -0
  260. package/skills/archify/test/sequence-column-fit.test.mjs +137 -0
  261. package/skills/archify/test/settled-flow.test.mjs +97 -0
  262. package/skills/archify/test/share-card-export.test.mjs +132 -0
  263. package/skills/archify/test/site-language-continuity.test.mjs +569 -0
  264. package/skills/archify/test/site-language-integration.mjs +9 -0
  265. package/skills/archify/test/skill-metadata.test.mjs +84 -0
  266. package/skills/archify/test/stable-update-manifest.test.mjs +167 -0
  267. package/skills/archify/test/start-page.test.mjs +312 -0
  268. package/skills/archify/test/story-beat-navigator.test.mjs +103 -0
  269. package/skills/archify/test/story-carrier.test.mjs +90 -0
  270. package/skills/archify/test/story-director-strip.test.mjs +91 -0
  271. package/skills/archify/test/story-follow-camera.test.mjs +103 -0
  272. package/skills/archify/test/story-horizon.test.mjs +91 -0
  273. package/skills/archify/test/story-moment-link.test.mjs +93 -0
  274. package/skills/archify/test/story-shelf.test.mjs +84 -0
  275. package/skills/archify/test/story-trail.test.mjs +81 -0
  276. package/skills/archify/test/toolbar-polish.test.mjs +57 -0
  277. package/skills/archify/test/update-contract.test.mjs +133 -0
  278. package/skills/archify/test/update-notifier.test.mjs +3317 -0
  279. package/skills/archify/test/v1-compatibility.test.mjs +329 -0
  280. package/skills/archify/test/vertical-edge.test.mjs +68 -0
  281. package/skills/archify/test/viewer-camera-browser.test.mjs +395 -0
  282. package/skills/archify/test/viewer-chrome-layout.test.mjs +1104 -0
  283. package/skills/archify/test/viewer-identifiers-browser.test.mjs +135 -0
  284. package/skills/archify/test/visual-check.test.mjs +400 -0
  285. package/skills/archify/test/webm-artifact.smoke.mjs +1855 -0
  286. package/skills/archify/test/workflow-compiler-hard-contract.test.mjs +2136 -0
  287. package/skills/archify/test/workflow-compiler.test.mjs +1163 -0
  288. package/skills/archify/test/workflow-migration.test.mjs +620 -0
  289. package/skills/archify/test/workflow-semantic-contract.test.mjs +131 -0
  290. package/skills/architect/SKILL.md +83 -0
  291. package/skills/architect/references/design-red-flags.md +33 -0
  292. package/skills/architect/references/rationale-template.md +35 -0
  293. package/skills/architect/references/runner-prompt.md +20 -0
  294. package/skills/arena/SKILL.md +13 -0
  295. package/skills/automate-me/SKILL.md +104 -0
  296. package/skills/autoresearch/SKILL.md +14 -0
  297. package/skills/debugging/SKILL.md +279 -0
  298. package/skills/dev-plan/SKILL.md +117 -92
  299. package/skills/dev-plan/references/architecture-quality.md +141 -0
  300. package/skills/dev-plan/references/execution-workflow.md +25 -0
  301. package/skills/dev-plan/references/plan-skeleton.md +252 -77
  302. package/skills/dev-plan/scripts/check_progress.sh +162 -0
  303. package/skills/documentation-writer/SKILL.md +204 -0
  304. package/skills/documentation-writer/assets/templates/ARCHITECTURE.md +49 -0
  305. package/skills/documentation-writer/assets/templates/CONCERNS.md +56 -0
  306. package/skills/documentation-writer/assets/templates/CONVENTIONS.md +52 -0
  307. package/skills/documentation-writer/assets/templates/FEATURES.md +43 -0
  308. package/skills/documentation-writer/assets/templates/INTEGRATIONS.md +48 -0
  309. package/skills/documentation-writer/assets/templates/STACK.md +56 -0
  310. package/skills/documentation-writer/assets/templates/STRUCTURE.md +44 -0
  311. package/skills/documentation-writer/assets/templates/TESTING.md +57 -0
  312. package/skills/documentation-writer/references/api-docs.md +185 -0
  313. package/skills/documentation-writer/references/architecture.md +134 -0
  314. package/skills/documentation-writer/references/codebase-map.md +113 -0
  315. package/skills/documentation-writer/references/inquiry-checkpoints.md +78 -0
  316. package/skills/documentation-writer/references/readme.md +89 -0
  317. package/skills/documentation-writer/references/stack-detection.md +134 -0
  318. package/skills/documentation-writer/references/user-manual.md +103 -0
  319. package/skills/documentation-writer/references/writing-style.md +220 -0
  320. package/skills/documentation-writer/scripts/check_doc.py +273 -0
  321. package/skills/documentation-writer/scripts/scan.py +712 -0
  322. package/skills/elintp/SKILL.md +155 -0
  323. package/skills/figure-it-out/SKILL.md +53 -0
  324. package/skills/gdpr-compliant/SKILL.md +283 -0
  325. package/skills/gdpr-compliant/references/Security.md +266 -0
  326. package/skills/gdpr-compliant/references/data-rights.md +177 -0
  327. package/skills/how/SKILL.md +58 -0
  328. package/skills/how/references/explainer-prompt.md +55 -0
  329. package/skills/how/references/explorer-prompt.md +52 -0
  330. package/skills/humanize-writing/SKILL.md +417 -0
  331. package/skills/humanize-writing/references/ai-tells.md +291 -0
  332. package/skills/kpi-dashboard-design/SKILL.md +103 -0
  333. package/skills/landing-page-conversion-audit/SKILL.md +122 -0
  334. package/skills/meeting-minutes/SKILL.md +235 -0
  335. package/skills/pardon/SKILL.md +30 -0
  336. package/skills/portal-app-exchange/SKILL.md +97 -0
  337. package/skills/portal-dev-setup/SKILL.md +610 -0
  338. package/skills/portal-dev-setup/puller.env.example +75 -0
  339. package/skills/portal-dev-setup/references/kafka.md +140 -0
  340. package/skills/portal-dev-setup/references/troubleshooting.md +163 -0
  341. package/skills/portal-dev-setup/scripts/onebox.sh +1420 -0
  342. package/skills/portal-external-app/SKILL.md +309 -0
  343. package/skills/portal-external-app/references/contract-doc-template.md +96 -0
  344. package/skills/portal-external-app/references/health-contract.md +80 -0
  345. package/skills/portal-external-app/references/integration-contract.md +130 -0
  346. package/skills/portal-external-app/references/public-entrypoints.md +100 -0
  347. package/skills/portal-external-app/references/quota-and-seats.md +194 -0
  348. package/skills/portal-external-app/references/registration-and-onebox.md +315 -0
  349. package/skills/portal-external-app/scripts/health-verdict.ts +22 -0
  350. package/skills/portal-external-app/scripts/verify-health.ts +27 -0
  351. package/skills/portal-logging/SKILL.md +139 -0
  352. package/skills/portal-logging/references/collectors.md +285 -0
  353. package/skills/portal-logging/references/contract.md +95 -0
  354. package/skills/portal-logging/scripts/smoke-ingest.sh +72 -0
  355. package/skills/portal-micro-app/SKILL.md +73 -0
  356. package/skills/portal-micro-app/references/manifest-and-acl.md +97 -0
  357. package/skills/portal-micro-app/references/open-api-and-extensions.md +86 -0
  358. package/skills/portal-micro-app/references/sdk-reference.md +208 -0
  359. package/skills/prd/SKILL.md +230 -0
  360. package/skills/prd/references/prd-skeleton.md +282 -0
  361. package/skills/prd/references/product-quality.md +89 -0
  362. package/skills/prd/references/spms-mapping.md +150 -0
  363. package/skills/react/SKILL.md +125 -0
  364. package/skills/react/references/actions.md +251 -0
  365. package/skills/react/references/component-patterns.md +275 -0
  366. package/skills/react/references/data-fetching.md +279 -0
  367. package/skills/react/references/effect-patterns.md +407 -0
  368. package/skills/react/references/js-performance.md +432 -0
  369. package/skills/react/references/react19-migration.md +407 -0
  370. package/skills/react/references/rendering-performance.md +351 -0
  371. package/skills/react/references/rerender-optimization.md +578 -0
  372. package/skills/reflect/SKILL.md +13 -0
  373. package/skills/review-code/SKILL.md +63 -0
  374. package/skills/review-code/agents/openai.yaml +4 -0
  375. package/skills/review-code/references/git-scopes.md +38 -0
  376. package/skills/review-code/references/report-contract.md +56 -0
  377. package/skills/review-code/references/review-lenses.md +33 -0
  378. package/skills/review-dev-plan/SKILL.md +88 -0
  379. package/skills/review-dev-plan/agents/openai.yaml +4 -0
  380. package/skills/review-dev-plan/references/report-contract.md +59 -0
  381. package/skills/review-dev-plan/references/review-lenses.md +82 -0
  382. package/skills/review-prd/SKILL.md +84 -0
  383. package/skills/review-prd/agents/openai.yaml +4 -0
  384. package/skills/review-prd/references/report-contract.md +64 -0
  385. package/skills/review-prd/references/review-lenses.md +82 -0
  386. package/skills/review-prd-dev-gaps/SKILL.md +84 -0
  387. package/skills/review-prd-dev-gaps/agents/openai.yaml +4 -0
  388. package/skills/review-prd-dev-gaps/references/report-contract.md +72 -0
  389. package/skills/rust/SKILL.md +103 -0
  390. package/skills/rust/references/chapter_01.md +564 -0
  391. package/skills/rust/references/chapter_02.md +117 -0
  392. package/skills/rust/references/chapter_03.md +209 -0
  393. package/skills/rust/references/chapter_04.md +183 -0
  394. package/skills/rust/references/chapter_05.md +390 -0
  395. package/skills/rust/references/chapter_06.md +142 -0
  396. package/skills/rust/references/chapter_07.md +226 -0
  397. package/skills/rust/references/chapter_08.md +257 -0
  398. package/skills/rust/references/chapter_09.md +261 -0
  399. package/skills/rust/references/chapter_10.md +554 -0
  400. package/skills/security-audit/SKILL.md +191 -0
  401. package/skills/security-audit/references/language-patterns.md +221 -0
  402. package/skills/security-audit/references/report-format.md +194 -0
  403. package/skills/security-audit/references/secret-patterns.md +178 -0
  404. package/skills/security-audit/references/vuln-categories.md +288 -0
  405. package/skills/security-audit/references/vulnerable-packages.md +111 -0
  406. package/skills/sql-optimization/SKILL.md +296 -0
  407. package/skills/story-points/SKILL.md +219 -0
  408. package/skills/story-points/references/factors.md +367 -0
  409. package/skills/summarize/SKILL.md +80 -0
  410. package/skills/swarm/SKILL.md +263 -0
  411. package/skills/swarm/evals/evals.json +55 -0
  412. package/skills/swarm/references/agent-types.md +260 -0
  413. package/skills/swarm/references/teams/code-audit.md +81 -0
  414. package/skills/swarm/references/teams/debug-race.md +70 -0
  415. package/skills/swarm/references/teams/feature-dev.md +71 -0
  416. package/skills/swarm/references/teams/product.md +114 -0
  417. package/skills/swarm/references/teams/refactor-migration.md +73 -0
  418. package/skills/swarm/references/teams/research-debate.md +73 -0
  419. package/skills/tdd/SKILL.md +42 -0
  420. package/skills/teach/SKILL.md +21 -0
  421. package/skills/test-plan/SKILL.md +137 -0
  422. package/skills/test-plan/references/case-taxonomy.md +142 -0
  423. package/skills/why/SKILL.md +158 -0
  424. package/skills/why/references/epistemics.md +144 -0
  425. package/skills/why/references/investigator-prompt.md +103 -0
  426. package/skills/why/references/source-playbook.md +17 -0
  427. package/skills/why/references/sources/code-archaeology.md +88 -0
  428. package/skills/why/references/sources/databricks.md +70 -0
  429. package/skills/why/references/sources/datadog.md +99 -0
  430. package/skills/why/references/sources/incident-postmortem.md +15 -0
  431. package/skills/why/references/sources/linear.md +48 -0
  432. package/skills/why/references/sources/notion.md +55 -0
  433. package/skills/why/references/sources/sentry.md +100 -0
  434. package/skills/why/references/sources/slack.md +54 -0
  435. package/skills/why/references/synthesizer-prompt.md +135 -0
  436. package/skills/working-with-mbx/SKILL.md +343 -0
  437. package/skills/working-with-mbx/references/acknowledgements.md +37 -0
  438. package/skills/working-with-mbx/references/benchmarks.md +140 -0
  439. package/skills/working-with-mbx/references/cache-results.md +153 -0
  440. package/skills/working-with-mbx/references/cache-server.md +151 -0
  441. package/skills/working-with-mbx/references/cli/adopt.md +29 -0
  442. package/skills/working-with-mbx/references/cli/cache/dir.md +24 -0
  443. package/skills/working-with-mbx/references/cli/cache/export.md +31 -0
  444. package/skills/working-with-mbx/references/cli/cache/import.md +27 -0
  445. package/skills/working-with-mbx/references/cli/cache/largest.md +26 -0
  446. package/skills/working-with-mbx/references/cli/cache/projects.md +23 -0
  447. package/skills/working-with-mbx/references/cli/cache/remove.md +30 -0
  448. package/skills/working-with-mbx/references/cli/cache/stats.md +24 -0
  449. package/skills/working-with-mbx/references/cli/cache/trace.md +27 -0
  450. package/skills/working-with-mbx/references/cli/cache/verify.md +23 -0
  451. package/skills/working-with-mbx/references/cli/cache.md +35 -0
  452. package/skills/working-with-mbx/references/cli/clean.md +27 -0
  453. package/skills/working-with-mbx/references/cli/completion.md +27 -0
  454. package/skills/working-with-mbx/references/cli/doctor.md +24 -0
  455. package/skills/working-with-mbx/references/cli/exec.md +28 -0
  456. package/skills/working-with-mbx/references/cli/explain.md +29 -0
  457. package/skills/working-with-mbx/references/cli/gc.md +28 -0
  458. package/skills/working-with-mbx/references/cli/prefetch.md +27 -0
  459. package/skills/working-with-mbx/references/cli/setup.md +28 -0
  460. package/skills/working-with-mbx/references/cli/stats.md +24 -0
  461. package/skills/working-with-mbx/references/cli/tui.md +24 -0
  462. package/skills/working-with-mbx/references/cli.md +58 -0
  463. package/skills/working-with-mbx/references/compared.md +67 -0
  464. package/skills/working-with-mbx/references/configuration.md +724 -0
  465. package/skills/working-with-mbx/references/cookbook/fork-prs.md +82 -0
  466. package/skills/working-with-mbx/references/cookbook/local-development.md +127 -0
  467. package/skills/working-with-mbx/references/cookbook/migrate.md +67 -0
  468. package/skills/working-with-mbx/references/dashboard.md +89 -0
  469. package/skills/working-with-mbx/references/faq.md +75 -0
  470. package/skills/working-with-mbx/references/getting-started.md +147 -0
  471. package/skills/working-with-mbx/references/github-action.md +254 -0
  472. package/skills/working-with-mbx/references/guide.md +59 -0
  473. package/skills/working-with-mbx/references/how-it-works.md +86 -0
  474. package/skills/working-with-mbx/references/incremental.md +78 -0
  475. package/skills/working-with-mbx/references/index.md +57 -0
  476. package/skills/working-with-mbx/references/installation.md +101 -0
  477. package/skills/working-with-mbx/references/limits.md +182 -0
  478. package/skills/working-with-mbx/references/linkers.md +75 -0
  479. package/skills/working-with-mbx/references/managed-targets.md +197 -0
  480. package/skills/working-with-mbx/references/protocol-compatibility.md +103 -0
  481. package/skills/working-with-mbx/references/remote-cache.md +190 -0
  482. package/skills/working-with-mbx/references/scheduling.md +65 -0
  483. package/skills/working-with-mbx/references/setup.md +157 -0
  484. package/skills/working-with-mbx/references/stability.md +43 -0
  485. package/skills/working-with-mbx/references/standalone-builds.md +102 -0
  486. package/skills/working-with-mbx/references/stats.md +49 -0
  487. package/skills/working-with-mbx/references/troubleshooting.md +136 -0
  488. package/skills/working-with-mbx/references/tui.md +163 -0
  489. package/skills/working-with-mbx/update-docs.sh +49 -0
  490. package/skills/working-with-mise/SKILL.md +297 -0
  491. package/skills/working-with-mise/references/cli/activate-html.md +90 -0
  492. package/skills/working-with-mise/references/cli/alias-html.md +30 -0
  493. package/skills/working-with-mise/references/cli/backends-html.md +40 -0
  494. package/skills/working-with-mise/references/cli/bin-paths-html.md +37 -0
  495. package/skills/working-with-mise/references/cli/bootstrap-html.md +109 -0
  496. package/skills/working-with-mise/references/cli/cache-html.md +40 -0
  497. package/skills/working-with-mise/references/cli/completion-html.md +76 -0
  498. package/skills/working-with-mise/references/cli/config-html.md +44 -0
  499. package/skills/working-with-mise/references/cli/daemons-html.md +48 -0
  500. package/skills/working-with-mise/references/cli/deactivate-html.md +47 -0
  501. package/skills/working-with-mise/references/cli/deps-html.md +89 -0
  502. package/skills/working-with-mise/references/cli/doctor-html.md +46 -0
  503. package/skills/working-with-mise/references/cli/dotfiles-html.md +57 -0
  504. package/skills/working-with-mise/references/cli/edit-html.md +48 -0
  505. package/skills/working-with-mise/references/cli/en-html.md +62 -0
  506. package/skills/working-with-mise/references/cli/env-html.md +57 -0
  507. package/skills/working-with-mise/references/cli/exec-html.md +79 -0
  508. package/skills/working-with-mise/references/cli/exec.md +79 -0
  509. package/skills/working-with-mise/references/cli/fmt-html.md +44 -0
  510. package/skills/working-with-mise/references/cli/generate-html.md +43 -0
  511. package/skills/working-with-mise/references/cli/implode-html.md +35 -0
  512. package/skills/working-with-mise/references/cli/install-html.md +83 -0
  513. package/skills/working-with-mise/references/cli/install-into-html.md +47 -0
  514. package/skills/working-with-mise/references/cli/latest-html.md +62 -0
  515. package/skills/working-with-mise/references/cli/link-html.md +57 -0
  516. package/skills/working-with-mise/references/cli/lock-html.md +114 -0
  517. package/skills/working-with-mise/references/cli/ls-html.md +95 -0
  518. package/skills/working-with-mise/references/cli/ls-remote-html.md +61 -0
  519. package/skills/working-with-mise/references/cli/mcp-html.md +57 -0
  520. package/skills/working-with-mise/references/cli/oci-html.md +41 -0
  521. package/skills/working-with-mise/references/cli/outdated-html.md +79 -0
  522. package/skills/working-with-mise/references/cli/packslip-html.md +38 -0
  523. package/skills/working-with-mise/references/cli/patrons-html.md +45 -0
  524. package/skills/working-with-mise/references/cli/plugins-html.md +46 -0
  525. package/skills/working-with-mise/references/cli/prune-html.md +56 -0
  526. package/skills/working-with-mise/references/cli/registry-html.md +59 -0
  527. package/skills/working-with-mise/references/cli/reshim-html.md +46 -0
  528. package/skills/working-with-mise/references/cli/run-html.md +152 -0
  529. package/skills/working-with-mise/references/cli/search-html.md +69 -0
  530. package/skills/working-with-mise/references/cli/self-update-html.md +42 -0
  531. package/skills/working-with-mise/references/cli/set-html.md +116 -0
  532. package/skills/working-with-mise/references/cli/settings-html.md +78 -0
  533. package/skills/working-with-mise/references/cli/shell-alias-html.md +39 -0
  534. package/skills/working-with-mise/references/cli/shell-html.md +53 -0
  535. package/skills/working-with-mise/references/cli/skills-html.md +39 -0
  536. package/skills/working-with-mise/references/cli/sponsors-html.md +31 -0
  537. package/skills/working-with-mise/references/cli/ssh-html.md +45 -0
  538. package/skills/working-with-mise/references/cli/sync-html.md +37 -0
  539. package/skills/working-with-mise/references/cli/tasks-html.md +61 -0
  540. package/skills/working-with-mise/references/cli/test-tool-html.md +49 -0
  541. package/skills/working-with-mise/references/cli/token-html.md +37 -0
  542. package/skills/working-with-mise/references/cli/tool-alias-html.md +41 -0
  543. package/skills/working-with-mise/references/cli/tool-html.md +55 -0
  544. package/skills/working-with-mise/references/cli/tool-stub-html.md +60 -0
  545. package/skills/working-with-mise/references/cli/trust-html.md +63 -0
  546. package/skills/working-with-mise/references/cli/uninstall-html.md +62 -0
  547. package/skills/working-with-mise/references/cli/unset-html.md +59 -0
  548. package/skills/working-with-mise/references/cli/untrust-html.md +35 -0
  549. package/skills/working-with-mise/references/cli/unuse-html.md +74 -0
  550. package/skills/working-with-mise/references/cli/upgrade-html.md +133 -0
  551. package/skills/working-with-mise/references/cli/use-html.md +130 -0
  552. package/skills/working-with-mise/references/cli/use.md +130 -0
  553. package/skills/working-with-mise/references/cli/version-html.md +46 -0
  554. package/skills/working-with-mise/references/cli/watch-html.md +465 -0
  555. package/skills/working-with-mise/references/cli/where-html.md +53 -0
  556. package/skills/working-with-mise/references/cli/which-html.md +55 -0
  557. package/skills/working-with-mise/references/configuration/environments-html.md +171 -0
  558. package/skills/working-with-mise/references/configuration/project-diagnostics-html.md +93 -0
  559. package/skills/working-with-mise/references/configuration/settings-html.md +3062 -0
  560. package/skills/working-with-mise/references/configuration/vars-html.md +167 -0
  561. package/skills/working-with-mise/references/dev-tools/aliases-html.md +97 -0
  562. package/skills/working-with-mise/references/dev-tools/backend_architecture-html.md +198 -0
  563. package/skills/working-with-mise/references/dev-tools/backends/aqua-html.md +274 -0
  564. package/skills/working-with-mise/references/dev-tools/backends/aqua.md +274 -0
  565. package/skills/working-with-mise/references/dev-tools/backends/asdf-html.md +98 -0
  566. package/skills/working-with-mise/references/dev-tools/backends/asdf.md +98 -0
  567. package/skills/working-with-mise/references/dev-tools/backends/cargo-html.md +240 -0
  568. package/skills/working-with-mise/references/dev-tools/backends/cargo.md +240 -0
  569. package/skills/working-with-mise/references/dev-tools/backends/conda-html.md +125 -0
  570. package/skills/working-with-mise/references/dev-tools/backends/dotnet-html.md +142 -0
  571. package/skills/working-with-mise/references/dev-tools/backends/forgejo-html.md +533 -0
  572. package/skills/working-with-mise/references/dev-tools/backends/gem-html.md +77 -0
  573. package/skills/working-with-mise/references/dev-tools/backends/gem.md +77 -0
  574. package/skills/working-with-mise/references/dev-tools/backends/github-html.md +622 -0
  575. package/skills/working-with-mise/references/dev-tools/backends/github.md +622 -0
  576. package/skills/working-with-mise/references/dev-tools/backends/gitlab-html.md +546 -0
  577. package/skills/working-with-mise/references/dev-tools/backends/go-html.md +115 -0
  578. package/skills/working-with-mise/references/dev-tools/backends/go.md +115 -0
  579. package/skills/working-with-mise/references/dev-tools/backends/http-html.md +644 -0
  580. package/skills/working-with-mise/references/dev-tools/backends/http.md +644 -0
  581. package/skills/working-with-mise/references/dev-tools/backends/npm-html.md +436 -0
  582. package/skills/working-with-mise/references/dev-tools/backends/npm.md +436 -0
  583. package/skills/working-with-mise/references/dev-tools/backends/packslip-html.md +310 -0
  584. package/skills/working-with-mise/references/dev-tools/backends/pipx-html.md +329 -0
  585. package/skills/working-with-mise/references/dev-tools/backends/pipx.md +329 -0
  586. package/skills/working-with-mise/references/dev-tools/backends/pkgx-html.md +73 -0
  587. package/skills/working-with-mise/references/dev-tools/backends/pypi-html.md +331 -0
  588. package/skills/working-with-mise/references/dev-tools/backends/s3-html.md +346 -0
  589. package/skills/working-with-mise/references/dev-tools/backends/spm-html.md +201 -0
  590. package/skills/working-with-mise/references/dev-tools/backends/ubi-html.md +232 -0
  591. package/skills/working-with-mise/references/dev-tools/backends/vfox-html.md +173 -0
  592. package/skills/working-with-mise/references/dev-tools/backends/vfox.md +173 -0
  593. package/skills/working-with-mise/references/dev-tools/backends.md +32 -0
  594. package/skills/working-with-mise/references/dev-tools/comparison-to-asdf-html.md +112 -0
  595. package/skills/working-with-mise/references/dev-tools/deps-html.md +390 -0
  596. package/skills/working-with-mise/references/dev-tools/github-tokens-html.md +390 -0
  597. package/skills/working-with-mise/references/dev-tools/index-html.md +420 -0
  598. package/skills/working-with-mise/references/dev-tools/mise-lock-html.md +660 -0
  599. package/skills/working-with-mise/references/dev-tools/mise-oci-html.md +418 -0
  600. package/skills/working-with-mise/references/dev-tools/packslip-resources-html.md +203 -0
  601. package/skills/working-with-mise/references/dev-tools/packslip-verification-html.md +178 -0
  602. package/skills/working-with-mise/references/dev-tools/shims-html.md +397 -0
  603. package/skills/working-with-mise/references/dev-tools/tool-stubs-html.md +416 -0
  604. package/skills/working-with-mise/references/guides/getting-started.md +268 -0
  605. package/skills/working-with-mise/references/index.md +37 -0
  606. package/skills/working-with-mise/update-docs.sh +111 -0
  607. package/skills/xgent-app-release/SKILL.md +507 -0
  608. package/skills/xgent-app-release/references/build-and-package.md +70 -0
  609. package/skills/xgent-app-release/references/embed-csp.mjs +126 -0
  610. package/skills/xgent-app-release/references/frontend-archive.md +67 -0
  611. package/skills/xgent-app-release/references/public-delivery.md +75 -0
  612. package/skills/xgent-app-release/references/publish-api.md +321 -0
  613. package/skills/xgent-app-release/references/troubleshooting.md +124 -0
  614. package/skills/xgent-app-release/references/verify-preflight.mjs +50 -0
  615. package/skills/xgent-app-release/scripts/npm-token.mjs +99 -0
  616. package/skills/xgent-app-release/scripts/preflight.mjs +351 -0
  617. package/skills/xgent-app-release/scripts/registry-config.mjs +88 -0
  618. package/skills/xgent-image-push/SKILL.md +239 -0
  619. package/skills/xgent-image-push/registry.env.example +51 -0
  620. package/skills/xgent-image-push/scripts/push-image.sh +576 -0
  621. package/skills/xgent-init/SKILL.md +37 -0
  622. package/skills/xgent-init/references/external-app-AGENTS.template.md +149 -0
  623. package/skills/xgent-init/references/external-app-DESIGN.template.md +317 -0
  624. package/skills/xgent-init/references/external-app-PRODUCT.template.md +87 -0
  625. package/skills/xgent-init/references/fill-guide.md +66 -0
  626. package/skills/xgent-init/scripts/check-docs.mjs +232 -0
  627. package/vendor/impeccable/LICENSE +191 -0
  628. package/vendor/impeccable/NOTICE.md +11 -0
  629. package/vendor/impeccable/VERSION.json +22 -0
  630. package/vendor/impeccable/bundle/blobs/00c067253d37cd20a41dbe9c806d6a72cbff983ad1418b3c3e447998f577b9c2 +152 -0
  631. package/vendor/impeccable/bundle/blobs/00d167d9183c8d0c6c0682055107382e6672bacf7a712de0abc8f157c2cb2210 +86 -0
  632. package/vendor/impeccable/bundle/blobs/00f053b877a92a9847d69eec2403e40c757152f30a5ca807c5033c58d7c297f1 +33 -0
  633. package/vendor/impeccable/bundle/blobs/012f548547fae48ebdd22a3c3af8a01032641fddd530e3783bd73b7358ab2c49 +80 -0
  634. package/vendor/impeccable/bundle/blobs/016c082dcd2aa8f3c080a757c8ed335c6070a904bd2f39668bb9d3e6f95929c1 +24 -0
  635. package/vendor/impeccable/bundle/blobs/0221a193d111a9de33a785706a603e55dd974a115f549dbdf74e0f9ec72bde7d +101 -0
  636. package/vendor/impeccable/bundle/blobs/03b30331c176a248a3b3bd17abdff1a1fd658f09ffb2a412b36ae9627dd3f33b +105 -0
  637. package/vendor/impeccable/bundle/blobs/055c571f2960b8f929d6a8d3806a4d32dfcb9750b3ef8b60adc8930fff34b559 +101 -0
  638. package/vendor/impeccable/bundle/blobs/058f81f256134841875fd3183e06b37a023de0c877fd2b9eecd97011640791fe +46 -0
  639. package/vendor/impeccable/bundle/blobs/05aa836a190f4ff62e5d4619738bdb891d83d85e35d81c2e6e322d1dc084d802 +80 -0
  640. package/vendor/impeccable/bundle/blobs/05e86f37d7fa381c5e8a04b6212490a27904d3be3e9384862a0764d3daba6d78 +54 -0
  641. package/vendor/impeccable/bundle/blobs/0605c8729dc638a46798e90ab12486fe3ae3372a869757cfb387a08e23b3c84a +152 -0
  642. package/vendor/impeccable/bundle/blobs/0617b37a905f0486c1ab4e91a287c8ef8292e253095c340f452d591206272f73 +104 -0
  643. package/vendor/impeccable/bundle/blobs/0648e4e06d01cabc91fa7dc19256ceedeeeea213b9265e9d36b0918370e16fb2 +318 -0
  644. package/vendor/impeccable/bundle/blobs/06b20bd42e5682a42c5d6fbfaad4c55e66ff9b9d99a604bd31d3545af120fc2d +101 -0
  645. package/vendor/impeccable/bundle/blobs/076a31941acbaa81013c8c511e146ed4138128eb5e9895dae3e9a27a25ac4f04 +13 -0
  646. package/vendor/impeccable/bundle/blobs/08346755b13f1a3f7c6fb4e512387884b80467aaeff109fd41f5521d2a95635a +113 -0
  647. package/vendor/impeccable/bundle/blobs/08398fa2d8e2b06b849f1c0f032e1e93b832e9294aed35c1c7f62b938d62ee80 +43 -0
  648. package/vendor/impeccable/bundle/blobs/087f6715114e901c2ce00b438e75b82fd48978c020a782f3dc361d39eb7198a6 +26 -0
  649. package/vendor/impeccable/bundle/blobs/08812a8618de7bd2f63a51298e9c2558031237e8efba280062ccb636101e25e1 +80 -0
  650. package/vendor/impeccable/bundle/blobs/08a2980eae0bfea1f00229899defc28ec92c7ecb875bf5fb02e4ba80dad6c394 +806 -0
  651. package/vendor/impeccable/bundle/blobs/08d78eb31c561256f83baa0afa742a660f1467aa2c81be2f60c2b7f9c770d66e +54 -0
  652. package/vendor/impeccable/bundle/blobs/09310582ed23393b171eb99ad4a288cc422ac53c26d76311586ce54c6df77b22 +113 -0
  653. package/vendor/impeccable/bundle/blobs/098a891028ce59c212b747d3c70468dd750aff7053a703d1336045ed31e0da7c +70 -0
  654. package/vendor/impeccable/bundle/blobs/0a151a54959a15eb32fa338890d5d64ac48a9d54d2d5442c3c7708a4c27c1858 +104 -0
  655. package/vendor/impeccable/bundle/blobs/0bb4085f6dda702846e0e56bd4f797aa1b046ab48eca02644448e368f3820f88 +104 -0
  656. package/vendor/impeccable/bundle/blobs/0bc2bc36ca6e74f9f610392f1a4fb8f57b2676238ba1f9c65cd8714f5d27e8a2 +42 -0
  657. package/vendor/impeccable/bundle/blobs/0bc7d7971b3edf2acd0580e847458dc6d84129d90715b452799ace3bed815c7c +84 -0
  658. package/vendor/impeccable/bundle/blobs/0bf6f08bf34d24cd88a78d544add9e4d71478bcf939926cde32f4e164882c775 +105 -0
  659. package/vendor/impeccable/bundle/blobs/0c064c9975f25f6eb5cf7911c2eeafd3e695d729f8c86a49a24ff2d76cb3cd94 +63 -0
  660. package/vendor/impeccable/bundle/blobs/0ccf57f758eb0d53bc32c5c77156f016e528d20fe2c2740662bf19964dfbb00b +152 -0
  661. package/vendor/impeccable/bundle/blobs/0dd1e6ccf053cb80e057caf7bf2fef30fd0197a41d907a1a8d2d2d02f6978674 +63 -0
  662. package/vendor/impeccable/bundle/blobs/0e081d496eba4bd77aca81723d59120c10177a71c9551a60ab923c356fb3cf38 +104 -0
  663. package/vendor/impeccable/bundle/blobs/0e18ac33b7e6a247b658fcaf926d9eac028399597dbaba366f1d2f2b884a383b +325 -0
  664. package/vendor/impeccable/bundle/blobs/0ed5986d1503399f48c11104df5e523a63be2d6558770ebfbbeb2323ca3f2ad3 +46 -0
  665. package/vendor/impeccable/bundle/blobs/11f75834c26ecd8a5b0afdf696e838953b235dc4835b7293bbc6b1bc27dd3106 +84 -0
  666. package/vendor/impeccable/bundle/blobs/14c9c9a7816026dd77494d06b8d1777c8d64785126b0c9ac8db5ebd996dfd6b6 +101 -0
  667. package/vendor/impeccable/bundle/blobs/14ef0ab84c10331f8af6b4124387a3f80b493175a04a3f89200719b4b5aea221 +152 -0
  668. package/vendor/impeccable/bundle/blobs/1547005438784032de3254cb35bff393e8187d7a459d0c20a693d9bfb0b5c1a4 +42 -0
  669. package/vendor/impeccable/bundle/blobs/162b814ddd1133923b9584bb95f85959e64844c94341d6bf10a81c06ab7cc02c +101 -0
  670. package/vendor/impeccable/bundle/blobs/1640c70b984a43e729d72d046109f87243ae84ecd64d2600a007d140558123cc +80 -0
  671. package/vendor/impeccable/bundle/blobs/16498466a97a5b19a593d5b3f245468c71784bea069d7fc8aa9690db5ac1d968 +29 -0
  672. package/vendor/impeccable/bundle/blobs/1652d639d91889a08bda7f351456c43ee30e5677aa4866a90f375e1e4be15deb +80 -0
  673. package/vendor/impeccable/bundle/blobs/16ba7fca1973c5faf53dd2ca523559129c0fe9e5f8d50b645f527afa78186cd2 +345 -0
  674. package/vendor/impeccable/bundle/blobs/16d99e9fe8e75d69042bc4fda12e93daa7e10f9fa6c00b12b0f0580b119a4cfd +105 -0
  675. package/vendor/impeccable/bundle/blobs/171777f8a8596d2ffdb43f4b935a7c6c12859ace233967f868a566390a59708e +325 -0
  676. package/vendor/impeccable/bundle/blobs/1725ca4aa546a34770f29191b58bf8dc14957d4258fb9e7d02f7b1c59c412ea4 +63 -0
  677. package/vendor/impeccable/bundle/blobs/173dd66abe65633910dcb04a51f40d6ff2a793f87088f022a02fc4cad24dd133 +94 -0
  678. package/vendor/impeccable/bundle/blobs/17c583cf8ad41266ea1e787b666b9d91fe13469d3d0f6af57c08e0146f9b17ac +58 -0
  679. package/vendor/impeccable/bundle/blobs/1898529e994bf0a31ee9ff3f87c343caea3d8a7e0986f404e129fbf89078ade0 +90 -0
  680. package/vendor/impeccable/bundle/blobs/190a4e642ca362d7499f3c3ab123e21f18f75457d11f072b545a183f296e6495 +99 -0
  681. package/vendor/impeccable/bundle/blobs/1971edc3784273bd8da7b1980779c6159471e857992faa6637178109cb130503 +806 -0
  682. package/vendor/impeccable/bundle/blobs/199d5d3db1197e053a2eb9c3cb927d44cbaaaeb57745c1ada3fd775ba50d9291 +104 -0
  683. package/vendor/impeccable/bundle/blobs/19b439d7d16e139357459d3874f739ea94dbdffeb2a0e201df1620ed1e40574d +24 -0
  684. package/vendor/impeccable/bundle/blobs/19c5bfce570a0e2bddd4d9c788936ff9070c90299363c4853ba77bfd37306e20 +416 -0
  685. package/vendor/impeccable/bundle/blobs/1b289c8c09de9d4442109ada91b1fa3a190e113a310cab7aa26a3633c5df0bb0 +24 -0
  686. package/vendor/impeccable/bundle/blobs/1bb3bdce54386e96e21b5956713a80583e6b3b9d1170f3bb8dec3819fa341bc3 +46 -0
  687. package/vendor/impeccable/bundle/blobs/1c11cb8ea42536c7a51e197f1aa32198960bb89262da2eaf32e0feb03c70792c +152 -0
  688. package/vendor/impeccable/bundle/blobs/1c6258015ed02c522948f8f1a3b6457395a8f7954497b87c1cd83f1791f9f819 +24 -0
  689. package/vendor/impeccable/bundle/blobs/1d7145fd5bf65282b2e05cf42faf41766d68e83e2b75f460b3b62d81ada5e5d7 +152 -0
  690. package/vendor/impeccable/bundle/blobs/1d72b494f46a60e6c9c06e89bab79789dd85e11f62fb4286a03abf26d352dc1f +80 -0
  691. package/vendor/impeccable/bundle/blobs/1e2f696760ee55fb154bdcc302c7d7b0fbb807e0308130594bd892dae14dc9ea +42 -0
  692. package/vendor/impeccable/bundle/blobs/1f6c3a1d7344f44eaa88b6f38334ad7d7b60201709589039a58cee73de486f5d +24 -0
  693. package/vendor/impeccable/bundle/blobs/207d443cabe4e6fe1351f91785748957f757bf1e7aeca405433c0329dad46a15 +63 -0
  694. package/vendor/impeccable/bundle/blobs/20e2111b3e065e8e8054f715ea3902e64b77886b30d2bddee723558f22942620 +90 -0
  695. package/vendor/impeccable/bundle/blobs/21e78c8a77badb3f83290cd4577ed3b24bd4dd3b57136d7da75733d4f3ee9ac0 +19 -0
  696. package/vendor/impeccable/bundle/blobs/223f08673b267f81d7586f686afe05d7cd7529a8e11ac37d979f95c2ceaae8ce +24 -0
  697. package/vendor/impeccable/bundle/blobs/238e1967d933ca5739db708f7ad9f72ca8b34bc4c9b9e1c07b0a06dcf9d00681 +806 -0
  698. package/vendor/impeccable/bundle/blobs/244e5b7bca6d22a51b4e22104a52a36e477056b03d257b56d1d4e319cd6167a8 +80 -0
  699. package/vendor/impeccable/bundle/blobs/2499b18f26639694344ca95682f47c65494f730cfff88aa9bd2aa83a22e5926d +101 -0
  700. package/vendor/impeccable/bundle/blobs/26cd88d10f8a14ed0ddb6e6b21e5e2c981f410eac93afa179202c354d7d1c0d5 +113 -0
  701. package/vendor/impeccable/bundle/blobs/275dd1b6e63bbd30d2713227c4f79b880a8bc4e01cc48d392068bb86939d3afa +38 -0
  702. package/vendor/impeccable/bundle/blobs/28f65b42c1ce9aaea35dc37a51257d7c703bb7f6553ebe3b8ca238a1007251e0 +113 -0
  703. package/vendor/impeccable/bundle/blobs/29f741b71e75fd39c65ca6df4b01b5f6c4f3c4c7adf23b47a3220ce2c0251f24 +104 -0
  704. package/vendor/impeccable/bundle/blobs/2ac1624b1253f3b6fcf2da54d54293624176539b2e9609a49245e7e46c65ca5f +42 -0
  705. package/vendor/impeccable/bundle/blobs/2b58041cd82d819d12762b10becb95f8253c661bf6a9de40f61fc01c1204b743 +806 -0
  706. package/vendor/impeccable/bundle/blobs/2b5b2fbf5f658f34ea1997fb1aeebe01604d05187f75c6a4f1f55a5bc78520a4 +104 -0
  707. package/vendor/impeccable/bundle/blobs/2b9379cdb329890eebe2384fbaa23f771745f30d8cfc43e180ebd092e69bcd2f +87 -0
  708. package/vendor/impeccable/bundle/blobs/2bc5d62463cc83d6417df7b8f4a02b4135e2b1bb654aa7727890662496f86e3d +42 -0
  709. package/vendor/impeccable/bundle/blobs/2c2ed6286bd74adef4f24ef442e2e1bc0780d44bc060aa2a4c03a03988dbafd5 +325 -0
  710. package/vendor/impeccable/bundle/blobs/2ce1722bd1a9f366182d9357d629796b1448f7a0126a854df507eb044d891cab +26 -0
  711. package/vendor/impeccable/bundle/blobs/2e4846117a2fcdc1e4bc9570a5333da839649cb8ccdac6a30a87591ca05b4bb0 +54 -0
  712. package/vendor/impeccable/bundle/blobs/2f02f96f889e0c8e0e90806af1ef17e0c162a6cc402068f434d3f7608d9deda3 +54 -0
  713. package/vendor/impeccable/bundle/blobs/2feb3768125ba6469c92a50d516727e6d42f44579165ddfd33409948e2a3803d +27 -0
  714. package/vendor/impeccable/bundle/blobs/3149a87bbed84bffe3558d5eaf1dc596b2e84d3c1be290fc7b1c13e481ae0803 +90 -0
  715. package/vendor/impeccable/bundle/blobs/31b90048c0b540daec46762a10c2b6b6434737a89af005054d8b848d829d003b +69 -0
  716. package/vendor/impeccable/bundle/blobs/3253eab02b62efa80abc74a5c85da08f3e2c6c20dff8dec38f4d236cbbfa0f3c +63 -0
  717. package/vendor/impeccable/bundle/blobs/3565d038a2eeab88a8b18ff52e6630008ab30f867f9df922a38ce8980440b2e3 +80 -0
  718. package/vendor/impeccable/bundle/blobs/3673248740bcdd1122ccc610093ba2fe52f3943a61ce0b7170b74dc49e5b6098 +416 -0
  719. package/vendor/impeccable/bundle/blobs/3753448bca49da76dd8b12d5a8b4264414673f26e49028d37616faa8beb210b7 +127 -0
  720. package/vendor/impeccable/bundle/blobs/37565671b09d983ea1ad83a9e9190bc37255d93c68445958c6facecc7e0f7c4f +33 -0
  721. package/vendor/impeccable/bundle/blobs/37680abf9a8e446619fcd33862718f483d197bf2652f966adca8dc54d2909b9d +85 -0
  722. package/vendor/impeccable/bundle/blobs/37aeddc0f2031fa89d72519ae2e7542c267872f81786fb8288fca0a49118be11 +27 -0
  723. package/vendor/impeccable/bundle/blobs/37c9a2122efa64dc8789eb47d196150b0bc635e0ba95042fd381ff157002ed50 +111 -0
  724. package/vendor/impeccable/bundle/blobs/385a0efe833bd4afe4a257e7159590de0cf1b7fd8f7b213b732f1e537c62dab7 +21 -0
  725. package/vendor/impeccable/bundle/blobs/3898bd9b56a042e860a0db4fb4dd81ac81126fa218b604702e2ac0c2287ae09b +345 -0
  726. package/vendor/impeccable/bundle/blobs/3970c8e24615610b0246585e49146f6762d5082b3c8fddc08a00940d6e72d394 +80 -0
  727. package/vendor/impeccable/bundle/blobs/39ac044f2e45a9e7eed8eb68fe91d32938160eb7f8fa93d2afc42fc80a0c3c10 +54 -0
  728. package/vendor/impeccable/bundle/blobs/39d9600489073e227e4f4d55c451ce4252a6632ed7ae37923efbbcbc91f16d07 +206 -0
  729. package/vendor/impeccable/bundle/blobs/3af7c46309f748ff3845f16455a431ec0e9e807e5e3a965e96e9ee75a1198eb8 +95 -0
  730. package/vendor/impeccable/bundle/blobs/3b2b60f23fa8ed9d73e721e17142c3933dc5318fa9a251742a76fee890ac81a8 +26 -0
  731. package/vendor/impeccable/bundle/blobs/3bcf81b938a0f0309e9ed6616f4bd18d82f07e2801411ee4cce51220d417eb95 +80 -0
  732. package/vendor/impeccable/bundle/blobs/3bd55b35c253f7841ca4e6e1a855a4b477d59aa2daf6e61e93fd685caaaff131 +63 -0
  733. package/vendor/impeccable/bundle/blobs/3bed76a0d528e2d73da8acae4dc63702bdb5baca5ab11600d70e75fc9f2ba90b +42 -0
  734. package/vendor/impeccable/bundle/blobs/3e3b6fdc6afbc2c2a734d08d6a18b393b7139c56f28f91f82e13e5555b98018a +84 -0
  735. package/vendor/impeccable/bundle/blobs/3ef9a43006bc68d83bc958fc8401e59f9beb6379048f5ced047747fdad05b895 +46 -0
  736. package/vendor/impeccable/bundle/blobs/3f2c351303b74e217907006fb9c55ada2ef596e9710c13d631e20506d17b9ee8 +325 -0
  737. package/vendor/impeccable/bundle/blobs/400419aaa20f710e1a7e5ca1fce9e8bc995c4db84053f40cf778d987619e0210 +24 -0
  738. package/vendor/impeccable/bundle/blobs/402373ef95962ecb81dd3d7cf70ecb3bd3e22a2bd2aabb4c0d76f7f4f9447870 +105 -0
  739. package/vendor/impeccable/bundle/blobs/40c87038b5f75147a5952a96237acf312a327bf70c1bcd8e0a5f064625ae9668 +51 -0
  740. package/vendor/impeccable/bundle/blobs/40cd6024312a1339aa66801df533afa543e60c36e708f0f9659dd8d558f83dce +63 -0
  741. package/vendor/impeccable/bundle/blobs/412dd9a5238aee223397591fe49b3bd27b6b53d649a0e67ed8570f3e199cebb9 +24 -0
  742. package/vendor/impeccable/bundle/blobs/41ef23c048ab739f48afdce26a2678d36ee40bcced34ef4b969d1d8ffafca64c +113 -0
  743. package/vendor/impeccable/bundle/blobs/420d82fe41884b7aa8c28750520146d8160c91396ac332a96b2d82a90b017fb2 +80 -0
  744. package/vendor/impeccable/bundle/blobs/424ff273e7ab283d6695d127bb502675627193f5b752d7b43b7524bcfc42f43f +84 -0
  745. package/vendor/impeccable/bundle/blobs/42831c3cd874346d8e7f120808d91e6ed3cda5c3eca6eefd76b126659536bc87 +148 -0
  746. package/vendor/impeccable/bundle/blobs/42a71df98075f66e6eb396b69ef3d6b1c3db46d1c1d24b4edc9d15f53d193ecb +111 -0
  747. package/vendor/impeccable/bundle/blobs/43dbfcb7c2e54c9cca9fce66024f17c06a2f2be645547b718b75c8828a463de2 +24 -0
  748. package/vendor/impeccable/bundle/blobs/442749aed338f51c1a3ccfb182c6ade9b74b90590b67984062ac94a5b100e914 +80 -0
  749. package/vendor/impeccable/bundle/blobs/4435529820c3fc2eceae8b1ee35c906a34c7612fb860117e896152b45aee0770 +26 -0
  750. package/vendor/impeccable/bundle/blobs/44a60aedcc350c2d7d501d0f830a31a586a6511a9ff9b4e361cb328bb747339d +101 -0
  751. package/vendor/impeccable/bundle/blobs/45dcea8da47cc21f447041daa942cf5d92cddde9a5a02c196cedbd159c829304 +47 -0
  752. package/vendor/impeccable/bundle/blobs/464c0c2b33d278375aec66caf95518f5e7ccd0aad1bea3f9dd553ed47815daa1 +325 -0
  753. package/vendor/impeccable/bundle/blobs/4700adf4542874f204c680ebad8317a97bf7169dbc04147082618ab59ce70c7d +85 -0
  754. package/vendor/impeccable/bundle/blobs/4777bbeaff2efcd6a2a66b07aacaaf57cd32f3fab1c1da5a0513937fafb48bd1 +63 -0
  755. package/vendor/impeccable/bundle/blobs/47b3461f6f76db80fdc49fc7542552d65fed24edc8d30d903cb76aefbad0ed05 +84 -0
  756. package/vendor/impeccable/bundle/blobs/47edbdfaf27073c47033d1ac7dfee881be49e2dcbda7671d1157300481dde6da +1 -0
  757. package/vendor/impeccable/bundle/blobs/484ea165f6d49ecc15b7a5c5623e377f2e203f4dad366df23eae99255ecf4572 +152 -0
  758. package/vendor/impeccable/bundle/blobs/485774d58dfd5796956024cdd9c12f05e692a3703f70b12a02ab43918885c3fd +101 -0
  759. package/vendor/impeccable/bundle/blobs/4879f38b23d0a251a63cbb0327e660296194cd2e71eb4da3236c6ebfe5807746 +33 -0
  760. package/vendor/impeccable/bundle/blobs/488da2e7406c6b4b5c92d7bc8cbd370cdaafc82a5f3ab5adbcffb21d1d1c4df4 +113 -0
  761. package/vendor/impeccable/bundle/blobs/48bb7c3b738f57fa4f3f714d7e3e919879036f3e751135a9acc1c5ede1850ea6 +54 -0
  762. package/vendor/impeccable/bundle/blobs/492a8030d11e2f4908d934bd817bd6d16a3164056c74a7172f60e2cec5ff3055 +42 -0
  763. package/vendor/impeccable/bundle/blobs/494d6fcb4701c437597c2ed16a9595af92f3d9ad53c944c96a2fb563bd766af5 +99 -0
  764. package/vendor/impeccable/bundle/blobs/4972f28d96897c8dec891f0de7a0d9d51f36030ff780ed9d960241c75413da2b +46 -0
  765. package/vendor/impeccable/bundle/blobs/49a7b37b98fb6e3ef68154174677ff4b9f1715efcffdbf6b30c3535b3e4e302c +54 -0
  766. package/vendor/impeccable/bundle/blobs/4a6f0386bff78bb42efa285df2919e75209ec336672cf5fff91ba66ffb352eaa +63 -0
  767. package/vendor/impeccable/bundle/blobs/4a8a45a46b79948a64b484edf389aa0b00fc80de855470cbabe3c7c71268f345 +828 -0
  768. package/vendor/impeccable/bundle/blobs/4ad7c5d5821f85c2311ff91746d9b9cf272dbe0a9a5b61687f77681f5a13f812 +69 -0
  769. package/vendor/impeccable/bundle/blobs/4b0e2eea17f297daa06b17578131775be099ef43addf91007f4b7e295454f64f +105 -0
  770. package/vendor/impeccable/bundle/blobs/4bceaf3346b6f5100b5a54deaae49a38b975dd134df2836675848f06ff1e7e11 +806 -0
  771. package/vendor/impeccable/bundle/blobs/4df48b7a86d525ad12e7889a1fd16b06ed4b25a9470c359c7193a6d82649262f +54 -0
  772. package/vendor/impeccable/bundle/blobs/4e3cc4d0e229ca96dd2e28fb2da0478a7f0bb64e447d07a652c425d8fbc57573 +113 -0
  773. package/vendor/impeccable/bundle/blobs/4ea8e05d0f88d24f182ad554da84317f90b9730e29fad262143ddf423a1f8645 +26 -0
  774. package/vendor/impeccable/bundle/blobs/4fb6d2fcc8afaf827a7377ddd604725264fd83be871e2d35062e9d1939144404 +25 -0
  775. package/vendor/impeccable/bundle/blobs/50d4b14134fc06daeac0aab6960800f171ef85250d3bcce6f246cf81e824463f +88 -0
  776. package/vendor/impeccable/bundle/blobs/50f3b5714ca3e2c1bcf070003733407935ee050609d3123c2c065489fbc9950b +43 -0
  777. package/vendor/impeccable/bundle/blobs/51032bb883137007127d30189b44b516d0e6140271bf5881da7eca76f8bd282c +113 -0
  778. package/vendor/impeccable/bundle/blobs/511ecde67e6bd976c9bdfa8d92f0dba359621344f8135c2a5ce5a66b385a4cb5 +42 -0
  779. package/vendor/impeccable/bundle/blobs/514a27fc9830455828d337cfc2fa95fa86be8e5464501bbabb9aca09a66b40ad +63 -0
  780. package/vendor/impeccable/bundle/blobs/521391d55814fdef6cd648ed62154a14d77b324004a0fc2d06c0a4e97857eab2 +806 -0
  781. package/vendor/impeccable/bundle/blobs/529cb2ace696ec11a86f4b010c9b137acf282072e483932181be1871df2aa690 +152 -0
  782. package/vendor/impeccable/bundle/blobs/52e861ac390a62c4473ae0cf87ff18dd6d721afa6557910492dd8ed28bd9970d +84 -0
  783. package/vendor/impeccable/bundle/blobs/532d6387db6f5da1a59dc7d29ce4d8ba6ca044626c367dc16e1cb8b981eb2d9a +104 -0
  784. package/vendor/impeccable/bundle/blobs/53628d05b7eff0d4f48b95e48fad40266452fe1b42f398bd88dd9328353e0dd8 +101 -0
  785. package/vendor/impeccable/bundle/blobs/53de37260c4f1c37e467557e9b038faa0f285b056bb2b95f435e0a7d1b69b0de +89 -0
  786. package/vendor/impeccable/bundle/blobs/5415103ca4422ea1422e23bfe9f9bae181f5d6d6407442f7fba31856ada58d12 +113 -0
  787. package/vendor/impeccable/bundle/blobs/54e71283cbd5646021fcd8eaa28d85852ec5288109c306aca9db9e2e4832338e +69 -0
  788. package/vendor/impeccable/bundle/blobs/5515d5210fbe2ef64e611ef2827a7204b7cea2f9df059f3ea499931f45065d93 +104 -0
  789. package/vendor/impeccable/bundle/blobs/56285b28b0ffe471761c2ad062d3f933ed2346ca1b617f1323a30fed99a1a852 +24 -0
  790. package/vendor/impeccable/bundle/blobs/56500b1f9d2fcec8324d7f448d813048b5831a46d3feeb1055bd3eb17ec3660f +70 -0
  791. package/vendor/impeccable/bundle/blobs/56cc1bba51e6805de370160ce4a9399fef3740571204f13c3c751725870305e5 +113 -0
  792. package/vendor/impeccable/bundle/blobs/571526fd5c60a586ff65bdb3f8333f26c36ae227f5f5ece826f4a43b4d4aee0f +325 -0
  793. package/vendor/impeccable/bundle/blobs/571f5c3bcf01c9b1bd02ab853a54db3f88375c4b8f39dd67d53e983a33e08bb7 +26 -0
  794. package/vendor/impeccable/bundle/blobs/57e28934208e3eac653ab59c5c6a5e4eace44906d8ac86472988242d777ca5a1 +54 -0
  795. package/vendor/impeccable/bundle/blobs/5855d7595b0212bb8d521e0265378d437df8d2343d5f8a30408c3edde0a14d96 +85 -0
  796. package/vendor/impeccable/bundle/blobs/599afc25c1d6d083e4d4e60e1617ab05f6c5ecd52be75473f3788063219aa174 +31 -0
  797. package/vendor/impeccable/bundle/blobs/5a07d4769a741cd00fdf8c95b943ef072eb12cd0c9e2c2d2622d5fe0a4fa3894 +46 -0
  798. package/vendor/impeccable/bundle/blobs/5a9626fb8c1e9051155c68626fe7c765a55be325113245d44b4991fc3d3b014e +44 -0
  799. package/vendor/impeccable/bundle/blobs/5b5dcf7029376ee6fbcf13e5975eb828dd1dbf41736c1bd5017dcda8173b1ebc +325 -0
  800. package/vendor/impeccable/bundle/blobs/5be952da521a2d5fb799c834d14ce5388284374bc23c5efcec737a05aa65d878 +84 -0
  801. package/vendor/impeccable/bundle/blobs/5c036648951d555e73be63161e5c9edcba146d8e9f64b1604ffdea765cde5d9d +131 -0
  802. package/vendor/impeccable/bundle/blobs/5c4cd151c97dae824a039211d7ccfba4c572b76d8f079c6186ba1dd5dae7732b +54 -0
  803. package/vendor/impeccable/bundle/blobs/5ce0631eacaae6d9fbb23ade26a774a20142cb40d3a8d5608a3fb9dbc4116b60 +806 -0
  804. package/vendor/impeccable/bundle/blobs/5db17cd013c10dca0012bc18aee7276280941579aa50757682e9ce60c4f7a006 +104 -0
  805. package/vendor/impeccable/bundle/blobs/5e354ae11913d5846faa3681a9ed98b68d1881fbbb1ecebf0769e3010bb0a426 +42 -0
  806. package/vendor/impeccable/bundle/blobs/5e6eea05456108b8766cf354dda998e90b6a5ecca7f15d807e28659ee78c306f +42 -0
  807. package/vendor/impeccable/bundle/blobs/5fae7f8a2fc3ddd49ad0a413446dc44daedef5b6b7de5eb935bd2fbfad646d58 +92 -0
  808. package/vendor/impeccable/bundle/blobs/634257e766b1fecacd25e27dbfc7e21ef3b440b01e94e92b8b17711018d8a661 +152 -0
  809. package/vendor/impeccable/bundle/blobs/6428239079f98fd6500e9fd032dd289b52052da7a4364ff357b0a5341b6444db +63 -0
  810. package/vendor/impeccable/bundle/blobs/647bab2f5cf6279d58d808f4df05d1ac63c1c86c6df9d13406ae776458653995 +42 -0
  811. package/vendor/impeccable/bundle/blobs/64802d14087fc96b38ef3881fef8098b36068d07f3b942031637b18eef3dd2af +84 -0
  812. package/vendor/impeccable/bundle/blobs/64807d8f43267f4ed879e997834bbf793bd4605ba1dc65f4b545324b660a7063 +80 -0
  813. package/vendor/impeccable/bundle/blobs/6528f2aebe4a425b724de293c8f6dc8a42ca80c7f1ed3039b8b9a813b004956a +87 -0
  814. package/vendor/impeccable/bundle/blobs/6575a657642ccdab42d0743ceaee06621c77811b4dc4f21c616e28aabf5e28ef +42 -0
  815. package/vendor/impeccable/bundle/blobs/66d60356172ccafdd334fca9bf33243c8409216a733dcde0d66a24fd70ee8132 +1 -0
  816. package/vendor/impeccable/bundle/blobs/68c5636a7858dd0b5137a9229c15e25fdc2ee40a0f8a4e9d809f78e809256262 +327 -0
  817. package/vendor/impeccable/bundle/blobs/696c15f96d49a03091b71a408151a3297521f7a8231b98ca9b1103667a0b5f89 +80 -0
  818. package/vendor/impeccable/bundle/blobs/69be9bb887f4d8ba4ead24928f9b97d122c796e731652fc0c08f195ab8ec2815 +105 -0
  819. package/vendor/impeccable/bundle/blobs/69cad1ae7355825ef320ac9638a1c9675ba9fda01c9a0fa12244cc4a1973e550 +214 -0
  820. package/vendor/impeccable/bundle/blobs/6acc0bf221a4ddc6e5c6438348920b2ca2393b29c4314dbde2cdc23f2b1a9639 +58 -0
  821. package/vendor/impeccable/bundle/blobs/6bc62a59f6fef0b749927c8d10e9849ab2411199d86d70772a86f8e83ac309f5 +29 -0
  822. package/vendor/impeccable/bundle/blobs/6c382f8283756e8a693d832b750f7e4cbff1ca5bdcc3825b2b4ef4da9f21876a +94 -0
  823. package/vendor/impeccable/bundle/blobs/6c9ce3e27ec4520ead001da3aad2a2ebba481c4e5cd22873db8890259ee579fe +95 -0
  824. package/vendor/impeccable/bundle/blobs/6d21d8e2729effaecc5b6239dadbcffb1ec8d51e8bdadeb47a39827266a61c5e +26 -0
  825. package/vendor/impeccable/bundle/blobs/6d368b679a0ed1815812815de65863b5840d419589dfbda06224c01149240287 +258 -0
  826. package/vendor/impeccable/bundle/blobs/6d9258a49c0b0583ec255eeb1092554298d5eea676fb9391f5a5a1377c3fd770 +87 -0
  827. package/vendor/impeccable/bundle/blobs/6e7e3b7c4cf331cdb43f4546c164acd6c45a267ce3289dcfa87e13202d98c747 +104 -0
  828. package/vendor/impeccable/bundle/blobs/6f4dfe968f47302ea64dca0e02f8c6d81497d93e4f436d09236e305456cbcc02 +87 -0
  829. package/vendor/impeccable/bundle/blobs/6f7f1639a933ed88e116aa8ab0cfb951096930d14f413349ae22ed04e28d2358 +46 -0
  830. package/vendor/impeccable/bundle/blobs/706c68612a7c6b899a0abf0b407eca7cabcd371deae60f830aa38aa86947694e +84 -0
  831. package/vendor/impeccable/bundle/blobs/713a942482531ef8ef103adf48d9decd7327697450e444289aa0479458e4ee1f +101 -0
  832. package/vendor/impeccable/bundle/blobs/713cac92a71ef45e8b700180d881f830096cfe2b0615e79b276ccc4a12c051e0 +80 -0
  833. package/vendor/impeccable/bundle/blobs/7212014fb2477d1d54aedaa79cdb861071a58afb2ae6d4dc5a495fa4810c6f8a +46 -0
  834. package/vendor/impeccable/bundle/blobs/73549b5536699c915156339976192fb38534bb43158cf9262ff5b89090388c64 +806 -0
  835. package/vendor/impeccable/bundle/blobs/73bd60faec1d8360753595f1ee9e970b44933448202767d7b0e87c275d399396 +6 -0
  836. package/vendor/impeccable/bundle/blobs/73f8bdec7d9a97476fd7d7e0b4114b5c3e9c7b84c22cbb876cd18c3e64a9b8c5 +42 -0
  837. package/vendor/impeccable/bundle/blobs/745b1f74877f6b3445da48af65dc45c66c3daa7738cb9a928aaa900889c2a204 +104 -0
  838. package/vendor/impeccable/bundle/blobs/74e20b26c29242bbebf79760315f7f0788e001566695618cfc70805484c6f92a +111 -0
  839. package/vendor/impeccable/bundle/blobs/754e9f0aa2101245a83cb17d8cc5bc49cf87997b29a83dedbfff283dbd0a8c4f +44 -0
  840. package/vendor/impeccable/bundle/blobs/765d3e890cd7f58ca94b6834181052166e9c4f9ef06278dc241da4d64da2d595 +113 -0
  841. package/vendor/impeccable/bundle/blobs/778cedc9199b407d3e23fa1041e38d548b00b1101a33517aa2a2eb299f9d0edc +26 -0
  842. package/vendor/impeccable/bundle/blobs/77ae09542fbc10aa4e8b119d6fd19359908a47c13c30068d6a150bfdb50e3e10 +24 -0
  843. package/vendor/impeccable/bundle/blobs/7848f40e224cf520bd8554943c9816a1ff8c97b1db57af0844e3b1ebb223d91f +416 -0
  844. package/vendor/impeccable/bundle/blobs/78c236dadb7e70337dc9dfa67e65fc15b7abed137ad320c16410ddfa7aec34f9 +131 -0
  845. package/vendor/impeccable/bundle/blobs/79114c6bf78b5a1838fe19bf033f3be85b232560eebf190ff8586aaec34ea170 +105 -0
  846. package/vendor/impeccable/bundle/blobs/796bbd8231413fcbf22eb7e6f40c402842aa4b10b1894545a7b05d9201ca7c4a +152 -0
  847. package/vendor/impeccable/bundle/blobs/79f85e381d1d6fdc8d39f54e1c8753fccf19b4ba3abb9827b6a7cc61eb376d1f +416 -0
  848. package/vendor/impeccable/bundle/blobs/7ad26830c7399a118cdbd4465a5426bc1919015aba99fd15959dc6deb8edc8d6 +80 -0
  849. package/vendor/impeccable/bundle/blobs/7af7fcc09c6b14f26ba78734460a2f9dddd2dcd2e2fa0c47c682f539e2f4cad5 +24 -0
  850. package/vendor/impeccable/bundle/blobs/7b1a4cc5ce94837c8309962a204c47361927e442b7a1c3cc472f90276eca8b8c +63 -0
  851. package/vendor/impeccable/bundle/blobs/7c417abe75f0ce4341b6f5acbadcafbbeabcc32cdb13c930aecc5cabda9f9242 +26 -0
  852. package/vendor/impeccable/bundle/blobs/7e36403ed58e0e82c0e42bf2fbea1c066b8e63276978647a6f1e44bf1edb23fb +63 -0
  853. package/vendor/impeccable/bundle/blobs/7fd1617d5a86b7a1a0bf9d6e291b334ac41a3efce31031eeaef11de7cd7e75b4 +325 -0
  854. package/vendor/impeccable/bundle/blobs/80191b3580a996a2045105976f728e0f46de22c412fc7640741add9767b2d8f4 +101 -0
  855. package/vendor/impeccable/bundle/blobs/808291e15746c9a64d9ede3ad3f06664b0a72970aa95052e064a96f1bfbed361 +54 -0
  856. package/vendor/impeccable/bundle/blobs/814610dee1081abc4213476ff0c4ae3e8f457909550d250ea0f89953687c85c6 +63 -0
  857. package/vendor/impeccable/bundle/blobs/8157b5a376e46980117f1ad6d08b24ee7be966f5de64b041bd213d486ea8c077 +26 -0
  858. package/vendor/impeccable/bundle/blobs/81666fc7f783b4e3514db6554e713dc0479bd9cdedb06e93d15f8b579aae869a +105 -0
  859. package/vendor/impeccable/bundle/blobs/835f19a0a3812f3652dd6979a2ce5597f654fd01f26e1b420b92d5f42b997ce4 +121 -0
  860. package/vendor/impeccable/bundle/blobs/8373668da1aa37c39888809ed9e834a7edfcb884af12f74934c270d004fba626 +85 -0
  861. package/vendor/impeccable/bundle/blobs/83d614fec61078175383012a088f49a9c0bb08b9ebd2b651c77cb94a323474ab +42 -0
  862. package/vendor/impeccable/bundle/blobs/8449781319a33d4a10a7fab9bfa4812241c303b95f33703b300b097dba51089a +152 -0
  863. package/vendor/impeccable/bundle/blobs/84a06415956986cb215139b3efda7b3c7a5bb6f502a3b3d9300f0744a970e620 +99 -0
  864. package/vendor/impeccable/bundle/blobs/857c4a0db5859f1fa91152db684528299dfc552525f50f416d1625a270e12671 +46 -0
  865. package/vendor/impeccable/bundle/blobs/86d10faab62da852aa1f4304157871545c853da708b6fe61c80aefb552c1f300 +84 -0
  866. package/vendor/impeccable/bundle/blobs/871a8e4d749b807c693ebabd83defbd6c76e1bd2a0f53a28a460cb1308ba8634 +318 -0
  867. package/vendor/impeccable/bundle/blobs/87b3db688c7963898bda8096f7868fed05ec5a0a80d14298e8b906b70cdf9c42 +416 -0
  868. package/vendor/impeccable/bundle/blobs/881a58aadf300bcc8f4947243e82192ae8dd7f14822a70fabc84fc74a5f9199c +46 -0
  869. package/vendor/impeccable/bundle/blobs/88549c11ea55d5dfc9f551db9a9c270d7362a9d42aa83db7747c9a7f020e1255 +46 -0
  870. package/vendor/impeccable/bundle/blobs/88749ebbe9bc87250765a07c2b959508262bd0e276ad60baa53e6e48c3579143 +806 -0
  871. package/vendor/impeccable/bundle/blobs/8a2d316593a631579bbb2f3fcb90d4488f85e97f69698dd2dd4fb50766f537d3 +325 -0
  872. package/vendor/impeccable/bundle/blobs/8c06daf096984cf71cf4133ea284dd6eaf503208da828816836ea41dfb69a234 +80 -0
  873. package/vendor/impeccable/bundle/blobs/8c34f78d71ac02c99303c7e0ca9ef30341aa9ecdeb75804dcba7e36a127914c1 +84 -0
  874. package/vendor/impeccable/bundle/blobs/8eb39a13e3d3650d4261f8fb06e91d6c0b888ca12ddbd3a5610cd8f0b05ad176 +69 -0
  875. package/vendor/impeccable/bundle/blobs/8ff60b8b5369d364f732f8de10479a39294e65341b3e0b6497b21de5c8e34b2d +806 -0
  876. package/vendor/impeccable/bundle/blobs/904859c8160b02330b04db23a8eeeb4ef55bcaa10f5208b8d73a1718334633e7 +84 -0
  877. package/vendor/impeccable/bundle/blobs/9205e222bc6565b37fb504ceec93233c2d2a456802b69d16e6b1c44723907c4c +5 -0
  878. package/vendor/impeccable/bundle/blobs/9287af96048c58ed0e72493cf7eb90c3957d4ba8b19e70ecf5d1f54264e9e597 +101 -0
  879. package/vendor/impeccable/bundle/blobs/92b7ab84c828fa888f4882c417c3d7f8fde2e5445b40f96f4fc8181a3e058afc +101 -0
  880. package/vendor/impeccable/bundle/blobs/93c53421c3376f695fe9dad5c82102f74bb5dd15e4ced81bb4ad50a71e5f1027 +24 -0
  881. package/vendor/impeccable/bundle/blobs/93eda27117930692a20f668f1cb0a80b7e14ab865998faba567cd721116081d4 +84 -0
  882. package/vendor/impeccable/bundle/blobs/94b4ce6299fea93d9f256b2d25705961a76bc5ea940c56db4145686ebc99df1b +89 -0
  883. package/vendor/impeccable/bundle/blobs/95b07450ad1ea0b7adc369587b06e52404945bbaa5d87f7491fac7ffd0e6e2ae +11 -0
  884. package/vendor/impeccable/bundle/blobs/95f0c7935a6d0375e09ae67ae0066c0ce7b583bf1d445d268cc4d2f4f900b1bb +113 -0
  885. package/vendor/impeccable/bundle/blobs/960cb922bc934adbf9192e9428ff6bec1f382038166f02a785939c93b7391067 +139 -0
  886. package/vendor/impeccable/bundle/blobs/96e2e6bd4fcf9a2c6da65fb029f96d9176308fae2efd9d8653d3b8d838960e07 +44 -0
  887. package/vendor/impeccable/bundle/blobs/96e508039c719c0815701c36b8418b18baee1967f915fa29b23b84861ae8ea94 +127 -0
  888. package/vendor/impeccable/bundle/blobs/98384b78af087855dbb526ec1e870a676ecd87f57237643dfea815317dad8a07 +26 -0
  889. package/vendor/impeccable/bundle/blobs/98afc4c6da252e90c6b783079b6f157bf94a13dd4351392e881edd2a100edf6a +105 -0
  890. package/vendor/impeccable/bundle/blobs/99e4a6facdb07986aa721bda8a4e35466b30091f32e38d7a71d9fcbe3591f65a +45 -0
  891. package/vendor/impeccable/bundle/blobs/9a2c08ee2516d2ee87129e7ebe6a0895f9990c9852d1f6fa7e70be9a6a88a659 +234 -0
  892. package/vendor/impeccable/bundle/blobs/9a4aa0d4903eabee987fdc92053466ff7f6eb0604797aee0efe67d67999b3eae +46 -0
  893. package/vendor/impeccable/bundle/blobs/9d45e5f6c082de6df4a2cfff11deb969715c49b5d9891d100dd1b2252c5bdcdd +152 -0
  894. package/vendor/impeccable/bundle/blobs/9db3c0857f4c2c8877b1fe24a47a229fee0de76ec9057bd8ee95f0677fb58d74 +26 -0
  895. package/vendor/impeccable/bundle/blobs/9e161532dc6731581d7a5f35bda5a2865e5248df7aff90e6dfc9221409893e35 +54 -0
  896. package/vendor/impeccable/bundle/blobs/9e82126a2e08aa365f9c430d383cf6e1921e04d1e0a1b5777716ff97828cfad8 +46 -0
  897. package/vendor/impeccable/bundle/blobs/9eb03b319ce7a2b281bc85ed1b0a437eb05ab2f765fc267354f9f9e6cbfadc25 +806 -0
  898. package/vendor/impeccable/bundle/blobs/9f1151faffbaadba0ddf5c09a4b2a82c9a12c900a2c1a9dac9863ba9ba0f420e +54 -0
  899. package/vendor/impeccable/bundle/blobs/9f2993499adadfdef4065a9a7fb69c75f888d892d4ee6bdbe62619bc772f495c +24 -0
  900. package/vendor/impeccable/bundle/blobs/a1a56df5fd51be403ca85a2f8054bb6f2bfeee443556c7798c2482e412fb6a09 +54 -0
  901. package/vendor/impeccable/bundle/blobs/a1af8b8a97665a3692eb39872c235796684a387a0b83785872f81aebd9dab046 +152 -0
  902. package/vendor/impeccable/bundle/blobs/a27399e3056c77a28ddd310fb5b4dee6e8e440dfa1737f7e38815097bec4c3a9 +46 -0
  903. package/vendor/impeccable/bundle/blobs/a423108e7e31a54564e2e0794186394f842625fd9f7d7ce6e6615362511503a2 +93 -0
  904. package/vendor/impeccable/bundle/blobs/a4cfd2330c8cca94b62986679b3f9e3bb9ada0cb30c2c63c5d19c6039f5a45ae +104 -0
  905. package/vendor/impeccable/bundle/blobs/a55f016c046cb6a27c55bd7f346375aeb506a755c4fbca19a5f92dbd42309c23 +59 -0
  906. package/vendor/impeccable/bundle/blobs/a569989e6a3d6453b4c45e9474e162a15cc54e11732ac6baa7990a6e7cccc0b5 +21 -0
  907. package/vendor/impeccable/bundle/blobs/a7045711a1f0dd2cd5bd98e57ff615f638d7e29738bdd618cf15e83fea5993b9 +325 -0
  908. package/vendor/impeccable/bundle/blobs/a75b892696469e3ccd2af33c9eef793e635efc3c5ac45336b0c1373d90c856b0 +63 -0
  909. package/vendor/impeccable/bundle/blobs/a7e8e60df83c6f47590467094ab2a13f1fe28ce45959a4e69dd89575a4208646 +47 -0
  910. package/vendor/impeccable/bundle/blobs/a7f036f4217933db8a96cf2f0ba251b15f388839d62bcf95720ce0b7152dd185 +806 -0
  911. package/vendor/impeccable/bundle/blobs/a892e337eee548d53252abb72ba5aa85cbcf556ffd8dc74e05534652c010d574 +24 -0
  912. package/vendor/impeccable/bundle/blobs/a93397adc906e245c69b42d4b25931fc92dc75baa60ca9a3749ba23b52ba01a0 +88 -0
  913. package/vendor/impeccable/bundle/blobs/a9856cb40da6519b1334bcfc75a4fbe83bef39ca86ee6f3effcb2a96794c627c +127 -0
  914. package/vendor/impeccable/bundle/blobs/a98b397cedeeaa1da57f3395b3d9b6c1fc477f4247fb9dc13e4da3da588283ff +54 -0
  915. package/vendor/impeccable/bundle/blobs/a9d2203acd45ca33a13d5c68b02b23ed512425ac15f0e8438318ed124b43729d +61 -0
  916. package/vendor/impeccable/bundle/blobs/a9e63b2df611805e845e0bb1cca1a0c27e83640a78185c9fd9de90d53a539cdc +42 -0
  917. package/vendor/impeccable/bundle/blobs/ab80e6a971baa66342548a846ce3fb69824ef9ef4e0f26c6f02685f225d00bbd +26 -0
  918. package/vendor/impeccable/bundle/blobs/ac695dd89d5f1261004cfa966526f5d5e913c92fa0640d4d71cb42493effad08 +131 -0
  919. package/vendor/impeccable/bundle/blobs/add1bee76f897f989166a5b9ad1b38d9173248e29d668d5c885ae9a0eff73861 +105 -0
  920. package/vendor/impeccable/bundle/blobs/af35b5fb6e45acb6483a5fbb864c3eaa9c57bacc43857f48183c836041c670ae +101 -0
  921. package/vendor/impeccable/bundle/blobs/af5842c4844b692b817319d5375611d4211dc7f459fb12da358baefc3a6cd373 +63 -0
  922. package/vendor/impeccable/bundle/blobs/b0e1a0721a1e47675a8750cfb608138743dd9fa9c047146e5cc8f82b9041be7a +806 -0
  923. package/vendor/impeccable/bundle/blobs/b14dc725606717be881a058bb691c0af1860cc8ad98d48e5a4789fe1a7de5458 +806 -0
  924. package/vendor/impeccable/bundle/blobs/b2732083f8f1d1924d38f84f179491430aebda8e0fd1f1d0785e3f883bcf3a40 +63 -0
  925. package/vendor/impeccable/bundle/blobs/b29e10f4506af2277739ad2373bc91c9fff41dbe76c9907f45152b4178cc6b6c +105 -0
  926. package/vendor/impeccable/bundle/blobs/b2d71ff0df7ed49e06dfc4acfce3d3f7eb48afa68be04763ee8c08354df50a07 +97 -0
  927. package/vendor/impeccable/bundle/blobs/b2f60e0154bf0e687badc46d8c8420e2118a9a6e21162050722be779dc02cb6d +111 -0
  928. package/vendor/impeccable/bundle/blobs/b314a0c5bd844f6471ea3031aeb9299674d972fbdd1615d99d16478de437d26d +84 -0
  929. package/vendor/impeccable/bundle/blobs/b3b1d5a4c80ce279d88896601deee9ccfeacdae0d0cd433600985a5f7ac93c72 +26 -0
  930. package/vendor/impeccable/bundle/blobs/b4be5499f404a926cdd2c55d8fb7409ba74a56b3d0c7d865594cc0254d3e499a +42 -0
  931. package/vendor/impeccable/bundle/blobs/b4def5b57733b6ba233570bd5691a536901f8b15479fc0111a2cde56224d0e1a +325 -0
  932. package/vendor/impeccable/bundle/blobs/b5f4fbb4a044c3f5ec14adc847222488f00fccabbf79ecd0b21084c8d319d616 +105 -0
  933. package/vendor/impeccable/bundle/blobs/b626e0677288a1660e9ce80c4f0454b527010239681f6b8dcc0f36b4a4d6bcb2 +113 -0
  934. package/vendor/impeccable/bundle/blobs/b6a2ef031313d3848ab2928875298550836f0f9ff7bdf5772e918c5c610ea448 +806 -0
  935. package/vendor/impeccable/bundle/blobs/b6dfd3df9a371e7d179d365cc1d72c11d4ed91b6507c0e1dbec0843419542f66 +84 -0
  936. package/vendor/impeccable/bundle/blobs/b719be9c5d4ced5d649ec6c0c90630196e7ee513d0da482aef13c705fdc23ab6 +113 -0
  937. package/vendor/impeccable/bundle/blobs/b7fcd2b03539d1029c8774fa806e6f4c677448e9e97e15f69b066022536c5491 +80 -0
  938. package/vendor/impeccable/bundle/blobs/b824bb76a657d3edd65e89807dcb21a3679eab39292423066e11368b35afba79 +325 -0
  939. package/vendor/impeccable/bundle/blobs/b8938fea3399aa639b4c873248035c219658069eef7be62672254e2f72c056f4 +42 -0
  940. package/vendor/impeccable/bundle/blobs/b8d49a3cab3428d9f351502e9c2c5802cef187e0d2af626ef3e1cd1837fd06bf +105 -0
  941. package/vendor/impeccable/bundle/blobs/ba0d96d88ab40fad1cb522e60b11affc568cfe9d340110ac5e71f834ac3d0f4a +42 -0
  942. package/vendor/impeccable/bundle/blobs/bb069b43c09109d7031b0374e31955749fec657b252d39782f11e8985aca2b51 +131 -0
  943. package/vendor/impeccable/bundle/blobs/bb36665889124a0b6e15f16045265737449c3bdcf2712cdb08af3cfa01563e2b +14 -0
  944. package/vendor/impeccable/bundle/blobs/bb59a1f78f3d2aa78e4b024fe203117155f50946a9e4bbe65c1b3b3abdcee356 +104 -0
  945. package/vendor/impeccable/bundle/blobs/bb9d4bb369216e892eea25adeaefc5a3e09bb4abd31e3475b79e47b3aee2a6af +806 -0
  946. package/vendor/impeccable/bundle/blobs/bc48bca63dff44e1f0205bafb64e16b2d6fb294ace405dbc9ae06a3bc6107154 +113 -0
  947. package/vendor/impeccable/bundle/blobs/bc5f71f1129d0f2c310d913d07c8dc609a1d25644121bd78c308f42d52a0b9e9 +86 -0
  948. package/vendor/impeccable/bundle/blobs/bcc05ea92faebb5c74037a9d4263a5ce9a56f5ab07c8ab3c59ee704d8cade745 +24 -0
  949. package/vendor/impeccable/bundle/blobs/bdd676c8f29295addfdbceaab285bb1184ec3ef7ff60501908b97ea8269580c4 +85 -0
  950. package/vendor/impeccable/bundle/blobs/bdf9a59beea111ac6f98f5624854feb5a5a1d60b1989edbbfabf3dc6f357a7e6 +105 -0
  951. package/vendor/impeccable/bundle/blobs/bdfd2a879ca65e437481eac5309f2283da225121630935d89ed902cfdf470c8e +105 -0
  952. package/vendor/impeccable/bundle/blobs/bea6ebfda78c51b9cf372097a1d77431d0f6bcd96eadec13a2ac95afbb87fb6d +104 -0
  953. package/vendor/impeccable/bundle/blobs/bf3b8883f8550744e08754af82a78939ab8b1237e5fad6f38d819e2f17e8a389 +104 -0
  954. package/vendor/impeccable/bundle/blobs/bf92a4a51b29de9661c5fa82f3d79244718a67d385ef661990f0c4a5b367e843 +104 -0
  955. package/vendor/impeccable/bundle/blobs/bfc51972fbf387566dc9e29c8b1af479a66ab401fdbce659fae9e6a5a9d85316 +69 -0
  956. package/vendor/impeccable/bundle/blobs/c06effcdc60859157208d3b7ee23d56160f2386f6a2dfa2514ba82fe21828ae0 +24 -0
  957. package/vendor/impeccable/bundle/blobs/c100b67a4ae248ad564182b181acb1ee2fe64c00049aeef62d4e7a3213726f37 +26 -0
  958. package/vendor/impeccable/bundle/blobs/c1cb6877ca99a0c1b38ba0c7d59f32702d3022f6821d8045f7133f7c40b6362f +242 -0
  959. package/vendor/impeccable/bundle/blobs/c1f3766091019b6f9183bc1d11b1e0fe03d44c168dc05a682c55df32f904dcfd +33 -0
  960. package/vendor/impeccable/bundle/blobs/c2dfc965319745c403b99e00e9e97de15f1300ea721bd3f708f0ac47aadc537b +101 -0
  961. package/vendor/impeccable/bundle/blobs/c327bf17f2af186f87164dee5fb5468746a9b137f0b604365d531ac9387f3712 +325 -0
  962. package/vendor/impeccable/bundle/blobs/c6b3bc811eb23d90ff9add1e0e5b40999a0bbbab364f5e6d08061f36d30429a5 +39 -0
  963. package/vendor/impeccable/bundle/blobs/c6f15d20d8d8748c4c475ff70cdb0ee426f2e6c9e7eab6169311f4dffd279ea1 +54 -0
  964. package/vendor/impeccable/bundle/blobs/c83d6a13fdfb58835c845f61aed3fc6dca17b5569d33387ced840bc13424f354 +84 -0
  965. package/vendor/impeccable/bundle/blobs/c9284892cb1f21aaeaf93fdf2e9e7a679d05e0baa8ddf309a79a9790d262ad38 +806 -0
  966. package/vendor/impeccable/bundle/blobs/cb8caddbb3919e5bf7f252143b519fb16db28a244642d937b186cb89962d9201 +828 -0
  967. package/vendor/impeccable/bundle/blobs/cbd8bd68fa00935dd0f179adb169252629cf7ee443ea9dc7db77e7ef2cf77446 +4 -0
  968. package/vendor/impeccable/bundle/blobs/cdf8a88b9865599c58fe285041d2d46eea7d9bd2d4075d82de358191742b20ad +46 -0
  969. package/vendor/impeccable/bundle/blobs/cf3d3a296890ac1ee363fee930f252e20d0935cd575367ad017b3cdc2dc5a50d +26 -0
  970. package/vendor/impeccable/bundle/blobs/d1366aa4802b364893c2a14b16fe95c3b7fab79f9f69eb272fd1538f7cb1ce2c +105 -0
  971. package/vendor/impeccable/bundle/blobs/d1fbd55074abb2251bdaa03749d34acc42c38e46e47549f18f5848df57d43c42 +86 -0
  972. package/vendor/impeccable/bundle/blobs/d2455359baf5f9e75360c7094e28a16937c8674619e07d58f30d2b5abfd31e53 +105 -0
  973. package/vendor/impeccable/bundle/blobs/d2e16da9bb6b33c931378d1bf57dcfff5dc426a71434bc352cec6aece715a66f +152 -0
  974. package/vendor/impeccable/bundle/blobs/d4a9e18a879bbb92aa0a56e16b45481090dffa4470efdecf52fb0da8c900be5d +46 -0
  975. package/vendor/impeccable/bundle/blobs/d57c3e0453f601ad688911fca4471057c7b46b561fcd42a1e12a581101c5186c +41 -0
  976. package/vendor/impeccable/bundle/blobs/d5f83912eda93d42f93522bb74aeff0ea04d9c559577ec52fcccc130dd03166d +137 -0
  977. package/vendor/impeccable/bundle/blobs/d6489d7f3e607ce3f8514a7a7d3a0eb5e8f1ac55859eaf7d5c31b53de8fab9f3 +152 -0
  978. package/vendor/impeccable/bundle/blobs/d658c48ffbe0031e8e3b318996cad6ceafe29e40aa50d5bb25e4bf1d6839dc7c +89 -0
  979. package/vendor/impeccable/bundle/blobs/d6a1fa1689642a6db9027493747d7ed54f9e0cae660472022c0a0a8dfdead3f4 +54 -0
  980. package/vendor/impeccable/bundle/blobs/d6a51f4df6d76f16b95ab81268a689f4c5936d505c5bb25c80ad7423f927bbc6 +47 -0
  981. package/vendor/impeccable/bundle/blobs/d7211a816aa8ca1111701930f7cdab82b4c8caa94c9a37522c1d7945209b01c2 +84 -0
  982. package/vendor/impeccable/bundle/blobs/d7b99a57652cb8741d57a15ba7e06de4707fac02a97e5e001179da007272f2b8 +113 -0
  983. package/vendor/impeccable/bundle/blobs/d87879329982d608866e4babd31c61438ec34c68483e529761fbf420203eeebd +104 -0
  984. package/vendor/impeccable/bundle/blobs/d9963fd73bf6129fe0c8ec25c5148f50617ec85683b8eeae7e411c9a42e2db33 +137 -0
  985. package/vendor/impeccable/bundle/blobs/da3b2399814db89d67959268c646601957d3e8c641b09a5bdbce84217c1c2cfe +46 -0
  986. package/vendor/impeccable/bundle/blobs/dc3aeccbea3e997704ce8b170f56b0eaf343a14ad4fedb22a6dbee0f205aa37f +47 -0
  987. package/vendor/impeccable/bundle/blobs/dcc1572e739cdabcbf084f276b447cb686aa18459896e6d8fe29f4d7d807bd1d +46 -0
  988. package/vendor/impeccable/bundle/blobs/dcf7340da023e64144af5768b8bf44ecf45b1bfdec12d3b1c9e6618f17f8c60a +131 -0
  989. package/vendor/impeccable/bundle/blobs/dd66761b291c7dbca6e9efd22023e38f8c53ad310f3a6cdab5dc7ecd7ae8f31f +84 -0
  990. package/vendor/impeccable/bundle/blobs/dd953992625c240fd1842aaf533a865aabd09487cbc16fa01fe8bb4b4365b843 +101 -0
  991. package/vendor/impeccable/bundle/blobs/de1b7404f4cdfd7b515196afb17b74b1980f0bc88cb8681ae93a76ca48ec7bdb +167 -0
  992. package/vendor/impeccable/bundle/blobs/de70398719140e4951aa111e9625de5ed916ad1ef0877e4ab6f6b4a7e3cc5f8f +154 -0
  993. package/vendor/impeccable/bundle/blobs/deaaa533475b6a9f7dd52e01a1f1997aa3af146694334981650f8c846f939559 +113 -0
  994. package/vendor/impeccable/bundle/blobs/df23e9ee5b689a05ed88f42e9a36aaffa2e6e28b1d56e2832acaa1d3603fd363 +105 -0
  995. package/vendor/impeccable/bundle/blobs/dfd6f341b156bc604e7556b27cba437d5870fbc82d4c673d0127cf18151b2226 +99 -0
  996. package/vendor/impeccable/bundle/blobs/e02ba7f4417e84b3bd5ec65287c4a14cf163ca3ac6f8ee37d8f709d0c8b0b6d2 +84 -0
  997. package/vendor/impeccable/bundle/blobs/e07176229b8a330970ca3c9c5e3dd68c2aaeb726285e30f471e91053d7f8e798 +24 -0
  998. package/vendor/impeccable/bundle/blobs/e1075ea5b34ac9c60f7c5bda97356eeaf1b683b599592d324fd3704f0852ad7a +152 -0
  999. package/vendor/impeccable/bundle/blobs/e26ddd48211aae08fe6debf2a7a4308aa081ed224668cde528e451888db0e3e3 +325 -0
  1000. package/vendor/impeccable/bundle/blobs/e2e275495354eeccb7e59af7d74e2ff1f371839bd6aaec1266428760995fb24c +104 -0
  1001. package/vendor/impeccable/bundle/blobs/e3af212117e0c552b0976687200fe8f95846a01725a482e8e4dbfd75e40dbfa6 +26 -0
  1002. package/vendor/impeccable/bundle/blobs/e3c2031978cd670d7150ff3140f12cf8b6882ef638ea9a9985caffa9a80c8713 +63 -0
  1003. package/vendor/impeccable/bundle/blobs/e44ca51f24c4736f9aee6024182b0409aa12ec94812b7ec94745e0999ed06a70 +29 -0
  1004. package/vendor/impeccable/bundle/blobs/e68467ba99684d8c975a8a2725145d29db41d70659c7544ea54cc6632660cea3 +127 -0
  1005. package/vendor/impeccable/bundle/blobs/e6e18e7c23cfe82961d90b9714cb466c20bd83f222ac63e9339b6b2c304e1787 +26 -0
  1006. package/vendor/impeccable/bundle/blobs/e71524578eb2bda3b8d2da3d8b8371239a2179c5fa866f9f7e48bcac45a8cd6f +84 -0
  1007. package/vendor/impeccable/bundle/blobs/e7af7ad18b307a3171fcf49421df2a557f93289d27af2430f10ee74e2a2fc2d3 +101 -0
  1008. package/vendor/impeccable/bundle/blobs/e7dd10af2c3c18c60dc20734d55ff870c323a10dadd337600f7bb980fc6b53c8 +327 -0
  1009. package/vendor/impeccable/bundle/blobs/e802e4f7bdc89050a9c0f2ca506e1d493a2316e6e810c0336c57aa073717ef3e +50 -0
  1010. package/vendor/impeccable/bundle/blobs/e85da3098368807689009184eca2bb09a91bdb6cb1be3e7a61f91f1ae31cd69b +152 -0
  1011. package/vendor/impeccable/bundle/blobs/e8720f3aa41135211cc58cc299a39eeda86c75651f4279cc1ede8db10dcc0584 +98 -0
  1012. package/vendor/impeccable/bundle/blobs/e8ee6c08e94b80324173d89d6f4cdc5b4829ea6858b3a11fc186588a490cada4 +46 -0
  1013. package/vendor/impeccable/bundle/blobs/e9861052457cc1ddc42c687bb8c33a877834ced94fed74af2a4f00f6bae50795 +101 -0
  1014. package/vendor/impeccable/bundle/blobs/ea8432c90c30ecb0426662a681ead5c0941113079704e1a766cda09e85b15b4f +111 -0
  1015. package/vendor/impeccable/bundle/blobs/eaa50e8cd95e00a94a257db2bff4eafd820696ba75a08a384a00517c3402924e +325 -0
  1016. package/vendor/impeccable/bundle/blobs/eb3e86876c20f1cfc443dcbe48d8f41fea6e815082a304610be432272429a06d +42 -0
  1017. package/vendor/impeccable/bundle/blobs/eba472f6190541c28e2e647ed019f43564ba5b92d629963f34c899175b25b31e +46 -0
  1018. package/vendor/impeccable/bundle/blobs/eba609589a5a051643a7bae60b7cceef7cfe44d0f8bd9229e61473ac75910fb3 +24 -0
  1019. package/vendor/impeccable/bundle/blobs/ec6338b20047099601e4bac8b2efcd597f800d5e437259f6c15d23090400621b +325 -0
  1020. package/vendor/impeccable/bundle/blobs/ec81b008d2641402e3352b09b1a90562ef7a24598d7c5aded475038cce63aca0 +24 -0
  1021. package/vendor/impeccable/bundle/blobs/ec86b8633fbeb14ef2272f220fdd98089972b03b99da83e49eeb6a8b73b00617 +113 -0
  1022. package/vendor/impeccable/bundle/blobs/ee6d6d127c1c2ab3526d529a8e3698be2185b5e346ac617f37501de2c0698b97 +99 -0
  1023. package/vendor/impeccable/bundle/blobs/ef2dde00030580ed2765cbf7be9b2ea4a6f64cb915b804fd6f6abcf38051c7b9 +234 -0
  1024. package/vendor/impeccable/bundle/blobs/ef2e97cd690baf6fe5c895dd2d8844aff9fcc4a8bc04973402678a739c81d712 +90 -0
  1025. package/vendor/impeccable/bundle/blobs/f0fbe529f63961a027bada2e6a3cbe86f4af0dba4b8e1010da22b007f9002f66 +63 -0
  1026. package/vendor/impeccable/bundle/blobs/f1601095679d7d8cf6fef6845598c70d8734190709c1404fa0026e28fef2faaa +325 -0
  1027. package/vendor/impeccable/bundle/blobs/f254d59ff973e907cacdc2c34b8b4de075437d292de31dac30e10a9d7035086c +85 -0
  1028. package/vendor/impeccable/bundle/blobs/f5efb1b1dd4cd18e1d4789d7c8e0188f4342b25fffd53af6088ba8b67774fb99 +26 -0
  1029. package/vendor/impeccable/bundle/blobs/f672ef8251a3ed4051a053d30819664951b17540b2899acd27d20e500c234abc +258 -0
  1030. package/vendor/impeccable/bundle/blobs/f68a3d68ac92606e91aa8878e003d9432ddd09aa97ca01c6b3ce46c937dca316 +13510 -0
  1031. package/vendor/impeccable/bundle/blobs/f7a9e3f30fe07b0d98351730e9895d50bba96dd42fe91c0d9b9a76ef62e53322 +80 -0
  1032. package/vendor/impeccable/bundle/blobs/f7b854effc55c8f07e40a415e0d6b5c333f4042fbc849fac73d52619c8d053a1 +54 -0
  1033. package/vendor/impeccable/bundle/blobs/f84b653ede0804d21e6210c6d21fd5352023914fedceae6ff14e20f1e93b06e7 +46 -0
  1034. package/vendor/impeccable/bundle/blobs/f964506c0fae87b3c2c1db7016ddc9be9ef970bbcf5548d684b997b5d5991586 +33 -0
  1035. package/vendor/impeccable/bundle/blobs/f9cbbad0cc08fb9bd69d4d3046067c6cf820b89cdaf7af8c81c671fb0a62b6ae +54 -0
  1036. package/vendor/impeccable/bundle/blobs/fb32d99751c5fc24493ff4460be1767bd5236dc820fd337775067c0620d1a7a6 +113 -0
  1037. package/vendor/impeccable/bundle/blobs/fb5fec24adafa48df43eece6907c1c986a4772cbdc64142c881f00c3b312e9ca +152 -0
  1038. package/vendor/impeccable/bundle/blobs/fc149b5bc7a8d0cc9b9bf86e5013793f3857c1c302212e9aaf101cb95427386b +101 -0
  1039. package/vendor/impeccable/bundle/blobs/fce6688138d2ceb1e3d2cde5231f54b1d8dc8748b4c95a7919aa83b6f924cf96 +127 -0
  1040. package/vendor/impeccable/bundle/blobs/fe91fcf28638f95577af481a50edaf339d6c9a3ad3b9fa477bc81c116b8bc392 +139 -0
  1041. package/vendor/impeccable/bundle/blobs/ff0ab1361f52d70d3ff0d23090d78794a75afdfa2f8c1cee5491dee69215faaa +105 -0
  1042. package/vendor/impeccable/bundle/manifest.json +1254 -0
  1043. package/skills/dev-plan/evals/evals.json +0 -72
@@ -0,0 +1,1855 @@
1
+ import assert from 'node:assert/strict';
2
+ import { execFileSync, spawn } from 'node:child_process';
3
+ import { once } from 'node:events';
4
+ import fs from 'node:fs';
5
+ import net from 'node:net';
6
+ import os from 'node:os';
7
+ import path from 'node:path';
8
+ import { pathToFileURL, fileURLToPath } from 'node:url';
9
+
10
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
11
+ const skillRoot = path.resolve(__dirname, '..');
12
+ const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'archify-webm-artifact-'));
13
+ const externalReachSource = process.env.ARCHIFY_REACH_CARD_SOURCE
14
+ ? path.resolve(process.env.ARCHIFY_REACH_CARD_SOURCE)
15
+ : '';
16
+ const externalReachOutput = process.env.ARCHIFY_REACH_CARD_OUTPUT
17
+ ? path.resolve(process.env.ARCHIFY_REACH_CARD_OUTPUT)
18
+ : '';
19
+ assert.equal(Boolean(externalReachSource), Boolean(externalReachOutput), 'ARCHIFY_REACH_CARD_SOURCE and ARCHIFY_REACH_CARD_OUTPUT must be set together');
20
+
21
+ function executable(candidates) {
22
+ for (const candidate of candidates) {
23
+ if (!candidate) continue;
24
+ if (candidate.includes(path.sep)) {
25
+ if (fs.existsSync(candidate)) return candidate;
26
+ continue;
27
+ }
28
+ try {
29
+ return execFileSync('sh', ['-c', `command -v "$1"`, 'archify-which', candidate], { encoding: 'utf8' }).trim();
30
+ } catch (_) {
31
+ // Try the next platform-specific name.
32
+ }
33
+ }
34
+ return '';
35
+ }
36
+
37
+ const chrome = executable([
38
+ process.env.ARCHIFY_CHROME,
39
+ 'google-chrome',
40
+ 'google-chrome-stable',
41
+ 'chromium',
42
+ 'chromium-browser',
43
+ '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
44
+ ]);
45
+ const ffmpeg = executable([process.env.ARCHIFY_FFMPEG, 'ffmpeg']);
46
+
47
+ assert.ok(chrome, 'Chrome/Chromium is required for the WebM artifact smoke test (or set ARCHIFY_CHROME)');
48
+ assert.ok(ffmpeg, 'ffmpeg is required for the WebM artifact smoke test (or set ARCHIFY_FFMPEG)');
49
+
50
+ const source = JSON.parse(fs.readFileSync(path.join(skillRoot, 'examples/web-app.architecture.json'), 'utf8'));
51
+ source.meta.animation = 'trace';
52
+ source.meta.visual_preset = 'signal-flow';
53
+
54
+ const input = path.join(tmp, 'motion.architecture.json');
55
+ const output = path.join(tmp, 'motion.html');
56
+ fs.writeFileSync(input, JSON.stringify(source));
57
+ execFileSync(process.execPath, [
58
+ path.join(skillRoot, 'renderers/architecture/render-architecture.mjs'),
59
+ input,
60
+ output,
61
+ ], { stdio: ['ignore', 'ignore', 'pipe'] });
62
+
63
+ const sequenceOutput = path.join(tmp, 'sequence.html');
64
+ execFileSync(process.execPath, [
65
+ path.join(skillRoot, 'renderers/sequence/render-sequence.mjs'),
66
+ path.join(skillRoot, 'examples/cache-miss-request.sequence.json'),
67
+ sequenceOutput,
68
+ ], { stdio: ['ignore', 'ignore', 'pipe'] });
69
+
70
+ const routeOutputs = {
71
+ architecture: output,
72
+ sequence: sequenceOutput,
73
+ };
74
+ for (const [mode, example] of Object.entries({
75
+ workflow: 'agent-tool-call.workflow.json',
76
+ dataflow: 'product-analytics.dataflow.json',
77
+ lifecycle: 'agent-run.lifecycle.json',
78
+ })) {
79
+ const rendered = path.join(tmp, `${mode}.html`);
80
+ execFileSync(process.execPath, [
81
+ path.join(skillRoot, `renderers/${mode}/render-${mode}.mjs`),
82
+ path.join(skillRoot, 'examples', example),
83
+ rendered,
84
+ ], { stdio: ['ignore', 'ignore', 'pipe'] });
85
+ routeOutputs[mode] = rendered;
86
+ }
87
+
88
+ function renderLegendFixture(mode, name, document) {
89
+ const inputPath = path.join(tmp, `${name}.${mode}.json`);
90
+ const outputPath = path.join(tmp, `${name}.${mode}.html`);
91
+ fs.writeFileSync(inputPath, JSON.stringify(document));
92
+ execFileSync(process.execPath, [
93
+ path.join(skillRoot, `renderers/${mode}/render-${mode}.mjs`),
94
+ inputPath,
95
+ outputPath,
96
+ ], { stdio: ['ignore', 'ignore', 'pipe'] });
97
+ return outputPath;
98
+ }
99
+
100
+ const legendOutputs = {
101
+ dataflow: renderLegendFixture('dataflow', 'issue-52-default-flow', {
102
+ schema_version: 1,
103
+ diagram_type: 'dataflow',
104
+ meta: { title: 'Default Flow With Store' },
105
+ stages: [{ label: 'Input' }, { label: 'Output' }],
106
+ nodes: [
107
+ { id: 'input', type: 'backend', label: 'Input', stage: 0, row: 0 },
108
+ { id: 'output', type: 'database', label: 'Output Store', stage: 1, row: 0 },
109
+ ],
110
+ flows: [{ from: 'input', to: 'output', label: 'request', route: 'straight' }],
111
+ }),
112
+ lifecycle: renderLegendFixture('lifecycle', 'issue-52-no-waiting', {
113
+ schema_version: 1,
114
+ diagram_type: 'lifecycle',
115
+ meta: { title: 'No Waiting or Failure', viewBox: [720, 566] },
116
+ lanes: [{ id: 'main', label: 'Lifecycle' }],
117
+ states: [
118
+ { id: 'started', type: 'start', label: 'Started', lane: 'main', col: 0 },
119
+ { id: 'running', type: 'active', label: 'Running', lane: 'main', col: 1 },
120
+ { id: 'completed', type: 'success', label: 'Completed', lane: 'main', col: 2 },
121
+ ],
122
+ transitions: [{ from: 'started', to: 'running' }, { from: 'running', to: 'completed' }],
123
+ }),
124
+ custom: renderLegendFixture('architecture', 'issue-52-custom-label', {
125
+ schema_version: 1,
126
+ diagram_type: 'architecture',
127
+ meta: {
128
+ title: 'Custom Legend Label',
129
+ viewBox: [720, 420],
130
+ legend: {
131
+ entries: {
132
+ frontend: { label: 'Reader <UI> & ops' },
133
+ external: { label: 'Future integration', visible: true },
134
+ },
135
+ },
136
+ views: [{ id: 'main', label: 'Main', focus: ['ui', 'store'] }],
137
+ },
138
+ components: [
139
+ { id: 'ui', type: 'frontend', label: 'UI', pos: [60, 90] },
140
+ { id: 'store', type: 'database', label: 'Store', pos: [300, 90] },
141
+ ],
142
+ connections: [],
143
+ }),
144
+ hidden: renderLegendFixture('dataflow', 'issue-52-hidden', {
145
+ schema_version: 1,
146
+ diagram_type: 'dataflow',
147
+ meta: { title: 'Hidden Legend', legend: { mode: 'hidden', entries: { database: { visible: true } } } },
148
+ stages: [{ label: 'Input' }, { label: 'Output' }],
149
+ nodes: [
150
+ { id: 'input', type: 'backend', label: 'Input', stage: 0, row: 0 },
151
+ { id: 'output', type: 'backend', label: 'Output', stage: 1, row: 0 },
152
+ ],
153
+ flows: [{ from: 'input', to: 'output', label: 'request', route: 'straight' }],
154
+ }),
155
+ };
156
+
157
+ const parallelSource = JSON.parse(JSON.stringify(source));
158
+ parallelSource.meta.title = 'Parallel Route Identity';
159
+ parallelSource.connections[0].label = '';
160
+ parallelSource.connections.splice(1, 0, {
161
+ id: 'users-to-cdn-alternate',
162
+ from: 'users',
163
+ to: 'cdn',
164
+ label: '',
165
+ });
166
+ const parallelInput = path.join(tmp, 'parallel.architecture.json');
167
+ const parallelOutput = path.join(tmp, 'parallel.html');
168
+ fs.writeFileSync(parallelInput, JSON.stringify(parallelSource));
169
+ execFileSync(process.execPath, [
170
+ path.join(skillRoot, 'renderers/architecture/render-architecture.mjs'),
171
+ parallelInput,
172
+ parallelOutput,
173
+ ], { stdio: ['ignore', 'ignore', 'pipe'] });
174
+
175
+ const specialSourceLabel = '入口 <script>window.__routeLabelExecuted = true</script> 汉字 🚀 with an intentionally very long endpoint label';
176
+ const specialTargetLabel = '终点服务 ✅ emoji + CJK + a second deliberately long endpoint label for header fitting';
177
+ const specialComponents = Array.from({ length: 11 }, (_, index) => ({
178
+ id: index === 0 ? 'Route_Source-01' : index === 10 ? 'Route_Target-10' : `route_step-${index}`,
179
+ type: index === 0 ? 'external' : index === 10 ? 'database' : 'backend',
180
+ label: index === 0 ? specialSourceLabel : index === 10 ? specialTargetLabel : `步骤 ${index} · service_${index} ⚙️`,
181
+ sublabel: `hop ${index}`,
182
+ pos: [40 + index * 820, 280],
183
+ size: [index === 0 || index === 10 ? 780 : 220, 72],
184
+ }));
185
+ const specialRouteSource = {
186
+ schema_version: 1,
187
+ diagram_type: 'architecture',
188
+ meta: {
189
+ title: '多语言 Route Share Card 🚀 with a deliberately long original diagram title that must fit safely',
190
+ subtitle: 'Ten exact authored hops',
191
+ animation: 'trace',
192
+ },
193
+ components: specialComponents,
194
+ boundaries: [],
195
+ connections: specialComponents.slice(0, -1).map((component, index) => ({
196
+ id: `route_edge-${index + 1}`,
197
+ from: component.id,
198
+ to: specialComponents[index + 1].id,
199
+ label: '',
200
+ })),
201
+ cards: [],
202
+ };
203
+ const specialRouteInput = path.join(tmp, 'special-route.architecture.json');
204
+ const specialRouteOutput = path.join(tmp, 'special-route.html');
205
+ fs.writeFileSync(specialRouteInput, JSON.stringify(specialRouteSource));
206
+ execFileSync(process.execPath, [
207
+ path.join(skillRoot, 'renderers/architecture/render-architecture.mjs'),
208
+ specialRouteInput,
209
+ specialRouteOutput,
210
+ ], { stdio: ['ignore', 'ignore', 'pipe'] });
211
+
212
+ assert.equal(typeof WebSocket, 'function', 'Node.js 22+ is required for the Chrome DevTools smoke harness');
213
+
214
+ function delay(ms) {
215
+ return new Promise((resolve) => setTimeout(resolve, ms));
216
+ }
217
+
218
+ async function waitForExit(child, timeoutMs) {
219
+ if (child.exitCode !== null || child.signalCode !== null) return true;
220
+ return Promise.race([
221
+ once(child, 'exit').then(() => true),
222
+ delay(timeoutMs).then(() => false),
223
+ ]);
224
+ }
225
+
226
+ async function removeTempTree(directory) {
227
+ const transientCodes = new Set(['EBUSY', 'ENOTEMPTY', 'EPERM']);
228
+ let lastError;
229
+ for (let attempt = 0; attempt < 8; attempt += 1) {
230
+ try {
231
+ fs.rmSync(directory, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 });
232
+ return;
233
+ } catch (error) {
234
+ if (!transientCodes.has(error?.code)) throw error;
235
+ lastError = error;
236
+ await delay(100 * (attempt + 1));
237
+ }
238
+ }
239
+ console.warn(`warning: temporary Chrome profile cleanup deferred (${lastError?.code || 'unknown'}): ${directory}`);
240
+ }
241
+
242
+ async function withTimeout(promise, ms, label) {
243
+ let timer;
244
+ try {
245
+ return await Promise.race([
246
+ promise,
247
+ new Promise((_, reject) => {
248
+ timer = setTimeout(() => reject(new Error(`${label} timed out after ${ms}ms`)), ms);
249
+ }),
250
+ ]);
251
+ } finally {
252
+ clearTimeout(timer);
253
+ }
254
+ }
255
+
256
+ async function freePort() {
257
+ const server = net.createServer();
258
+ await new Promise((resolve, reject) => {
259
+ server.once('error', reject);
260
+ server.listen(0, '127.0.0.1', resolve);
261
+ });
262
+ const port = server.address().port;
263
+ await new Promise((resolve) => server.close(resolve));
264
+ return port;
265
+ }
266
+
267
+ async function devtoolsEndpoint(port, chromeProcess, diagnostics) {
268
+ for (let attempt = 0; attempt < 100; attempt += 1) {
269
+ try {
270
+ const response = await fetch(`http://127.0.0.1:${port}/json/version`);
271
+ if (response.ok) return (await response.json()).webSocketDebuggerUrl;
272
+ } catch (_) {
273
+ // Chrome may need a moment to bind the debugging port.
274
+ }
275
+ if (chromeProcess.exitCode !== null) break;
276
+ await delay(50);
277
+ }
278
+ const stderr = diagnostics().trim();
279
+ const exit = chromeProcess.exitCode === null ? 'still running' : `exited with code ${chromeProcess.exitCode}`;
280
+ throw new Error(`Chrome did not expose a DevTools endpoint (${exit})${stderr ? `:\n${stderr}` : ''}`);
281
+ }
282
+
283
+ async function connectCdp(webSocketUrl) {
284
+ const socket = new WebSocket(webSocketUrl);
285
+ await new Promise((resolve, reject) => {
286
+ socket.addEventListener('open', resolve, { once: true });
287
+ socket.addEventListener('error', reject, { once: true });
288
+ });
289
+ let nextId = 0;
290
+ const pending = new Map();
291
+ socket.addEventListener('message', (event) => {
292
+ const message = JSON.parse(String(event.data));
293
+ if (!message.id || !pending.has(message.id)) return;
294
+ const request = pending.get(message.id);
295
+ pending.delete(message.id);
296
+ if (message.error) request.reject(new Error(message.error.message));
297
+ else request.resolve(message.result);
298
+ });
299
+ socket.addEventListener('close', () => {
300
+ for (const request of pending.values()) request.reject(new Error('Chrome DevTools connection closed'));
301
+ pending.clear();
302
+ });
303
+ return {
304
+ socket,
305
+ send(method, params = {}, sessionId) {
306
+ const id = ++nextId;
307
+ return new Promise((resolve, reject) => {
308
+ pending.set(id, { resolve, reject });
309
+ socket.send(JSON.stringify({ id, method, params, ...(sessionId ? { sessionId } : {}) }));
310
+ });
311
+ },
312
+ };
313
+ }
314
+
315
+ async function evaluate(cdp, sessionId, expression, awaitPromise = false) {
316
+ const response = await cdp.send('Runtime.evaluate', {
317
+ expression,
318
+ awaitPromise,
319
+ returnByValue: true,
320
+ }, sessionId);
321
+ if (response.exceptionDetails) {
322
+ throw new Error(response.exceptionDetails.exception?.description || response.exceptionDetails.text || 'browser evaluation failed');
323
+ }
324
+ return response.result?.value;
325
+ }
326
+
327
+ const port = await freePort();
328
+ let chromeStderr = '';
329
+ const chromeProcess = spawn(chrome, [
330
+ '--headless=new',
331
+ '--disable-gpu',
332
+ '--disable-dev-shm-usage',
333
+ '--no-sandbox',
334
+ '--allow-file-access-from-files',
335
+ '--autoplay-policy=no-user-gesture-required',
336
+ '--log-level=3',
337
+ `--user-data-dir=${path.join(tmp, 'chrome-profile')}`,
338
+ '--remote-debugging-address=127.0.0.1',
339
+ `--remote-debugging-port=${port}`,
340
+ 'about:blank',
341
+ ], { stdio: ['ignore', 'ignore', 'pipe'] });
342
+ chromeProcess.stderr.setEncoding('utf8');
343
+ chromeProcess.stderr.on('data', (chunk) => {
344
+ chromeStderr = `${chromeStderr}${chunk}`.slice(-64 * 1024);
345
+ });
346
+
347
+ let cdp;
348
+ let targetId;
349
+
350
+ try {
351
+ cdp = await connectCdp(await devtoolsEndpoint(port, chromeProcess, () => chromeStderr));
352
+ ({ targetId } = await cdp.send('Target.createTarget', { url: 'about:blank' }));
353
+ await cdp.send('Target.activateTarget', { targetId });
354
+ const { sessionId } = await cdp.send('Target.attachToTarget', { targetId, flatten: true });
355
+ await cdp.send('Page.enable', {}, sessionId);
356
+ await cdp.send('Runtime.enable', {}, sessionId);
357
+
358
+ async function navigateReady(file, condition, label) {
359
+ const url = file instanceof URL ? file.href : pathToFileURL(file).href;
360
+ await cdp.send('Page.navigate', { url }, sessionId);
361
+ await cdp.send('Page.bringToFront', {}, sessionId);
362
+ await cdp.send('Emulation.setFocusEmulationEnabled', { enabled: true }, sessionId);
363
+ let ready = false;
364
+ for (let attempt = 0; attempt < 100 && !ready; attempt += 1) {
365
+ ready = await evaluate(cdp, sessionId, `document.readyState === "complete" && (${condition})`);
366
+ if (!ready) await delay(50);
367
+ }
368
+ assert.equal(ready, true, `${label} did not expose its browser export surface`);
369
+ }
370
+
371
+ async function verifyResolvedLegendContract(outputs) {
372
+ async function inspectKinds(file, expectedKinds, theme) {
373
+ const url = new URL(pathToFileURL(file).href);
374
+ url.searchParams.set('theme', theme);
375
+ await navigateReady(url, '!!(window.Archify && Archify.semanticLens)', `legend ${theme}`);
376
+ const result = await evaluate(cdp, sessionId, `(() => {
377
+ var svg = document.querySelector('.diagram-container > svg');
378
+ var entries = Array.from(svg.querySelectorAll('[data-legend-semantic-kind]'));
379
+ var vb = svg.viewBox.baseVal;
380
+ return {
381
+ theme: document.documentElement.getAttribute('data-theme'),
382
+ kinds: entries.map(function (entry) { return entry.getAttribute('data-legend-semantic-kind'); }),
383
+ bridge: !!svg.querySelector('[data-legend-bridge]'),
384
+ roles: entries.map(function (entry) { return entry.getAttribute('role'); }),
385
+ aria: entries.map(function (entry) { return entry.getAttribute('aria-label'); }),
386
+ counts: entries.map(function (entry) { return entry.getAttribute('data-legend-count'); }),
387
+ tabStops: entries.filter(function (entry) { return entry.getAttribute('tabindex') === '0'; }).length,
388
+ inside: entries.every(function (entry) {
389
+ var box = entry.getBBox();
390
+ return box.x >= vb.x && box.y >= vb.y && box.x + box.width <= vb.x + vb.width && box.y + box.height <= vb.y + vb.height;
391
+ })
392
+ };
393
+ })()`);
394
+ assert.equal(result.theme, theme);
395
+ assert.deepEqual(result.kinds, expectedKinds);
396
+ assert.equal(result.inside, true);
397
+ return result;
398
+ }
399
+
400
+ for (const theme of ['dark', 'light']) {
401
+ const dataflow = await inspectKinds(outputs.dataflow, ['database', 'default'], theme);
402
+ assert.equal(dataflow.bridge, true);
403
+ assert.deepEqual(dataflow.roles, ['button', null]);
404
+ assert.deepEqual(dataflow.aria, ['Inspect data store, 1 node', null]);
405
+ assert.deepEqual(dataflow.counts, ['1', null]);
406
+ assert.equal(dataflow.tabStops, 1);
407
+ const lifecycle = await inspectKinds(outputs.lifecycle, ['start', 'active', 'success'], theme);
408
+ assert.equal(lifecycle.bridge, true);
409
+ }
410
+
411
+ await navigateReady(outputs.dataflow, '!!(window.Archify && Archify.semanticLens && Archify.exportMenu)', 'Dataflow database legend runtime');
412
+ const databaseRuntime = await evaluate(cdp, sessionId, String.raw`(async function () {
413
+ var entry = document.querySelector('[data-legend-kind="database"]');
414
+ entry.focus();
415
+ entry.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));
416
+ var originalCreateObjectURL = URL.createObjectURL;
417
+ var originalAnchorClick = HTMLAnchorElement.prototype.click;
418
+ var captured;
419
+ URL.createObjectURL = function (blob) {
420
+ captured = blob.text();
421
+ return 'blob:archify-dataflow-legend-smoke';
422
+ };
423
+ HTMLAnchorElement.prototype.click = function () {};
424
+ try {
425
+ await Archify.exportMenu.run('svg');
426
+ var exportedText = await captured;
427
+ var exported = new DOMParser().parseFromString(exportedText, 'image/svg+xml').documentElement;
428
+ return {
429
+ selected: Archify.semanticLens.active(),
430
+ lensOpen: Archify.semanticLens.isOpen(),
431
+ exportedKinds: Array.from(exported.querySelectorAll('[data-legend-semantic-kind]')).map(function (item) { return item.getAttribute('data-legend-semantic-kind'); }),
432
+ exportedBridgeResidue: exported.querySelectorAll('[data-legend-bridge], [data-legend-kind], [data-legend-label], [data-legend-count], [data-legend-bridge-runtime]').length
433
+ };
434
+ } finally {
435
+ URL.createObjectURL = originalCreateObjectURL;
436
+ HTMLAnchorElement.prototype.click = originalAnchorClick;
437
+ }
438
+ })()`, true);
439
+ assert.deepEqual(databaseRuntime.selected, ['database']);
440
+ assert.equal(databaseRuntime.lensOpen, true);
441
+ assert.deepEqual(databaseRuntime.exportedKinds, ['database', 'default']);
442
+ assert.equal(databaseRuntime.exportedBridgeResidue, 0);
443
+
444
+ await navigateReady(outputs.custom, '!!(window.Archify && Archify.semanticLens && Archify.exportMenu)', 'custom legend runtime');
445
+ const runtime = await evaluate(cdp, sessionId, String.raw`(async function () {
446
+ var svg = document.querySelector('.diagram-container > svg');
447
+ var entries = Array.from(svg.querySelectorAll('[data-legend-semantic-kind]'));
448
+ var interactive = entries.filter(function (entry) { return entry.hasAttribute('data-legend-kind'); });
449
+ var first = interactive[0];
450
+ var second = interactive[1];
451
+ first.focus();
452
+ first.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowRight', bubbles: true }));
453
+ var arrowMoved = document.activeElement === second;
454
+ second.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));
455
+ var selected = Archify.semanticLens.active();
456
+ var guidedActivated = Archify.guidedViews.activate('main', { updateUrl: false });
457
+ var guidedActive = Archify.guidedViews.active();
458
+ var visualMatrix = [];
459
+ for (var preset of ['classic', 'signal-flow', 'blueprint', 'editorial']) {
460
+ if (!Archify.preset.apply(preset)) throw new Error('could not apply preset ' + preset);
461
+ for (var theme of ['dark', 'light']) {
462
+ document.documentElement.setAttribute('data-theme', theme);
463
+ visualMatrix.push({
464
+ preset: preset,
465
+ theme: theme,
466
+ kinds: entries.map(function (entry) { return entry.getAttribute('data-legend-semantic-kind'); }),
467
+ labels: entries.map(function (entry) { return entry.querySelector('text').textContent; })
468
+ });
469
+ }
470
+ }
471
+
472
+ var originalCreateObjectURL = URL.createObjectURL;
473
+ var originalAnchorClick = HTMLAnchorElement.prototype.click;
474
+ var captured;
475
+ URL.createObjectURL = function (blob) {
476
+ captured = blob.text();
477
+ return 'blob:archify-legend-smoke';
478
+ };
479
+ HTMLAnchorElement.prototype.click = function () {};
480
+ try {
481
+ await Archify.exportMenu.run('svg');
482
+ var exportedText = await captured;
483
+ var exported = new DOMParser().parseFromString(exportedText, 'image/svg+xml').documentElement;
484
+ return {
485
+ labels: interactive.map(function (entry) { return entry.getAttribute('aria-label'); }),
486
+ roles: entries.map(function (entry) { return entry.getAttribute('role'); }),
487
+ counts: interactive.map(function (entry) { return entry.getAttribute('data-legend-count'); }),
488
+ tabStops: interactive.filter(function (entry) { return entry.getAttribute('tabindex') === '0'; }).length,
489
+ arrowMoved: arrowMoved,
490
+ selected: selected,
491
+ lensOpen: Archify.semanticLens.isOpen(),
492
+ guidedActivated: guidedActivated,
493
+ guidedActive: guidedActive,
494
+ visualMatrix: visualMatrix,
495
+ forcedUnusedInteractive: entries.at(-1).hasAttribute('data-legend-kind'),
496
+ exportedKinds: Array.from(exported.querySelectorAll('[data-legend-semantic-kind]')).map(function (entry) { return entry.getAttribute('data-legend-semantic-kind'); }),
497
+ exportedBridgeResidue: exported.querySelectorAll('[data-legend-bridge], [data-legend-kind], [data-legend-label], [data-legend-count], [data-legend-bridge-runtime]').length,
498
+ exportedLabels: Array.from(exported.querySelectorAll('[data-legend-semantic-kind] text')).map(function (text) { return text.textContent; })
499
+ };
500
+ } finally {
501
+ URL.createObjectURL = originalCreateObjectURL;
502
+ HTMLAnchorElement.prototype.click = originalAnchorClick;
503
+ }
504
+ })()`, true);
505
+ assert.deepEqual(runtime.labels, ['Inspect Reader <UI> & ops, 1 node', 'Inspect Database, 1 node']);
506
+ assert.deepEqual(runtime.roles, ['button', 'button', null]);
507
+ assert.deepEqual(runtime.counts, ['1', '1']);
508
+ assert.equal(runtime.tabStops, 1);
509
+ assert.equal(runtime.arrowMoved, true);
510
+ assert.deepEqual(runtime.selected, ['database']);
511
+ assert.equal(runtime.lensOpen, false);
512
+ assert.equal(runtime.guidedActivated, true);
513
+ assert.equal(runtime.guidedActive, 'main');
514
+ assert.equal(runtime.visualMatrix.length, 8);
515
+ for (const entry of runtime.visualMatrix) {
516
+ assert.deepEqual(entry.kinds, ['frontend', 'database', 'external']);
517
+ assert.deepEqual(entry.labels, ['Reader <UI> & ops', 'Database', 'Future integration']);
518
+ }
519
+ assert.equal(runtime.forcedUnusedInteractive, false);
520
+ assert.deepEqual(runtime.exportedKinds, ['frontend', 'database', 'external']);
521
+ assert.equal(runtime.exportedBridgeResidue, 0);
522
+ assert.deepEqual(runtime.exportedLabels, ['Reader <UI> & ops', 'Database', 'Future integration']);
523
+
524
+ await cdp.send('Emulation.setEmulatedMedia', { media: 'print' }, sessionId);
525
+ const printState = await evaluate(cdp, sessionId, `(() => ({
526
+ legendDisplay: getComputedStyle(document.querySelector('[data-legend]')).display,
527
+ runtimeBadgesHidden: Array.from(document.querySelectorAll('[data-legend-bridge-runtime]')).every(function (entry) { return getComputedStyle(entry).display === 'none'; })
528
+ }))()`);
529
+ assert.notEqual(printState.legendDisplay, 'none');
530
+ assert.equal(printState.runtimeBadgesHidden, true);
531
+ await cdp.send('Emulation.setEmulatedMedia', { media: '' }, sessionId);
532
+
533
+ const embedUrl = new URL(pathToFileURL(outputs.custom).href);
534
+ embedUrl.searchParams.set('embed', '1');
535
+ await navigateReady(embedUrl, '!!(window.Archify && Archify.semanticLens)', 'embedded legend');
536
+ const embed = await evaluate(cdp, sessionId, `(() => ({
537
+ roles: document.querySelectorAll('[data-legend-kind][role]').length,
538
+ runtime: document.querySelectorAll('[data-legend-bridge-runtime]').length,
539
+ kinds: Array.from(document.querySelectorAll('[data-legend-semantic-kind]')).map(function (entry) { return entry.getAttribute('data-legend-semantic-kind'); })
540
+ }))()`);
541
+ assert.deepEqual(embed, { roles: 0, runtime: 0, kinds: ['frontend', 'database', 'external'] });
542
+
543
+ await navigateReady(outputs.hidden, '!!(window.Archify && Archify.semanticLens)', 'hidden legend');
544
+ const hidden = await evaluate(cdp, sessionId, `(() => ({
545
+ root: !!document.querySelector('[data-legend]'),
546
+ bridge: !!document.querySelector('[data-legend-bridge]'),
547
+ title: Array.from(document.querySelectorAll('.diagram-container svg text')).some(function (text) { return text.textContent.trim() === 'Legend'; })
548
+ }))()`);
549
+ assert.deepEqual(hidden, { root: false, bridge: false, title: false });
550
+ console.log('ok legend runtime: labels, counts, keyboard, export, print, embed, hidden, and dual themes');
551
+ }
552
+
553
+ async function verifySemanticPassportDismissal(file) {
554
+ await navigateReady(file, '!!(window.Archify && Archify.focus && document.querySelector("#btn-focus-clear"))', 'Semantic Passport dismissal');
555
+ const result = await evaluate(cdp, sessionId, `(() => {
556
+ var chip = document.querySelector('#focus-chip');
557
+ var close = document.querySelector('#btn-focus-clear');
558
+ var container = document.querySelector('.diagram-container');
559
+ var svg = container.querySelector(':scope > svg');
560
+ var origin = svg.querySelector('[data-node-id="clients"]');
561
+ var neighbor = svg.querySelector('[data-node-id]:not([data-node-id="clients"])');
562
+ if (!origin || !neighbor) return { ok: false, error: 'missing smoke-test nodes' };
563
+ function state() {
564
+ return { hidden: chip.hidden, active: Archify.focus.active() };
565
+ }
566
+
567
+ Archify.focus.set('clients', { toggle: false, updateUrl: false });
568
+ var cardRect = chip.getBoundingClientRect();
569
+ var closeRect = close.getBoundingClientRect();
570
+ var layout = {
571
+ topGap: Math.round(closeRect.top - cardRect.top),
572
+ rightGap: Math.round(cardRect.right - closeRect.right),
573
+ label: close.getAttribute('aria-label'),
574
+ title: close.getAttribute('title'),
575
+ text: close.textContent.trim()
576
+ };
577
+ close.click();
578
+ var afterClose = state();
579
+ var restoredFocus = document.activeElement && document.activeElement.getAttribute('data-node-id');
580
+
581
+ Archify.focus.set('clients', { toggle: false, updateUrl: false });
582
+ chip.querySelector('.relationship-lens-head').dispatchEvent(new MouseEvent('click', { bubbles: true }));
583
+ var afterInside = state();
584
+ container.dispatchEvent(new MouseEvent('click', { bubbles: true }));
585
+ var afterOutside = state();
586
+
587
+ Archify.focus.set('clients', { toggle: false, updateUrl: false });
588
+ neighbor.dispatchEvent(new MouseEvent('click', { bubbles: true }));
589
+ var afterNode = state();
590
+ return {
591
+ ok: true,
592
+ layout: layout,
593
+ afterClose: afterClose,
594
+ restoredFocus: restoredFocus,
595
+ afterInside: afterInside,
596
+ afterOutside: afterOutside,
597
+ afterNode: afterNode,
598
+ neighborId: neighbor.getAttribute('data-node-id')
599
+ };
600
+ })()`);
601
+ assert.equal(result?.ok, true, result?.error || 'Semantic Passport smoke failed');
602
+ assert.equal(result.layout.label, 'Close semantic passport');
603
+ assert.equal(result.layout.title, 'Close');
604
+ assert.equal(result.layout.text, '×');
605
+ assert.ok(result.layout.topGap >= 0 && result.layout.topGap <= 16, `Semantic Passport close top gap ${result.layout.topGap}px`);
606
+ assert.ok(result.layout.rightGap >= 0 && result.layout.rightGap <= 16, `Semantic Passport close right gap ${result.layout.rightGap}px`);
607
+ assert.deepEqual(result.afterClose, { hidden: true, active: null });
608
+ assert.equal(result.restoredFocus, 'clients');
609
+ assert.deepEqual(result.afterInside, { hidden: false, active: 'clients' });
610
+ assert.deepEqual(result.afterOutside, { hidden: true, active: null });
611
+ assert.deepEqual(result.afterNode, { hidden: false, active: result.neighborId });
612
+ console.log('ok Semantic Passport: close control, focus return, inside preservation, and outside dismissal');
613
+ }
614
+
615
+ async function verifyArchitectureDeltaNavigator(file) {
616
+ await cdp.send('Emulation.setEmulatedMedia', {
617
+ media: 'screen',
618
+ features: [{ name: 'prefers-reduced-motion', value: 'no-preference' }],
619
+ }, sessionId);
620
+ const readyCondition = '!!document.querySelector("#review-play") && !document.querySelector("#review-play").disabled';
621
+ async function waitForSelected(changeKey, label) {
622
+ for (let attempt = 0; attempt < 80; attempt += 1) {
623
+ if (await evaluate(cdp, sessionId, `document.querySelector('.change-row[aria-current="step"]')?.dataset.changeKey === ${JSON.stringify(changeKey)}`)) return;
624
+ await delay(50);
625
+ }
626
+ const observed = await evaluate(cdp, sessionId, `({
627
+ selected: document.querySelector('.change-row[aria-current="step"]')?.dataset.changeKey || null,
628
+ pressed: document.querySelector('#review-play')?.getAttribute('aria-pressed'),
629
+ label: document.querySelector('#review-play')?.textContent,
630
+ status: document.querySelector('#review-status')?.textContent,
631
+ reducedMotion: matchMedia('(prefers-reduced-motion: reduce)').matches,
632
+ hidden: document.hidden
633
+ })`);
634
+ assert.fail(`${label} did not select ${changeKey} within the bounded wait: ${JSON.stringify(observed)}`);
635
+ }
636
+ async function waitForReviewFinished(label) {
637
+ for (let attempt = 0; attempt < 400; attempt += 1) {
638
+ const done = await evaluate(cdp, sessionId, `document.querySelector('#review-play').getAttribute('aria-pressed') === 'false' && document.querySelector('#review-play').textContent === 'Replay'`);
639
+ if (done) return;
640
+ await delay(50);
641
+ }
642
+ assert.fail(`${label} did not finish within the bounded wait`);
643
+ }
644
+ await navigateReady(file, readyCondition, 'architecture-delta navigator');
645
+ const initial = await evaluate(cdp, sessionId, `({
646
+ status: document.querySelector('#review-status').textContent,
647
+ selected: document.querySelectorAll('.change-row[aria-current="step"]').length,
648
+ current: document.querySelectorAll('[data-delta-review-current]').length,
649
+ rows: document.querySelectorAll('.change-row').length
650
+ })`);
651
+ assert.deepEqual(initial, { status: 'Overview · 11 authored changes', selected: 0, current: 0, rows: 11 });
652
+
653
+ await evaluate(cdp, sessionId, `document.querySelector('#review-play').click()`);
654
+ await waitForSelected('relationship:fraud-check', 'architecture-delta initial playback');
655
+ const advanced = await evaluate(cdp, sessionId, `({
656
+ selected: document.querySelector('.change-row[aria-current="step"]')?.dataset.changeKey,
657
+ pressed: document.querySelector('#review-play').getAttribute('aria-pressed')
658
+ })`);
659
+ assert.deepEqual(advanced, { selected: 'relationship:fraud-check', pressed: 'true' });
660
+
661
+ await evaluate(cdp, sessionId, `document.querySelector('[role="tab"][data-target="base"]').click()`);
662
+ const pausedKey = await evaluate(cdp, sessionId, `document.querySelector('.change-row[aria-current="step"]')?.dataset.changeKey`);
663
+ await delay(1550);
664
+ assert.equal(await evaluate(cdp, sessionId, `document.querySelector('.change-row[aria-current="step"]')?.dataset.changeKey`), pausedKey);
665
+ assert.equal(await evaluate(cdp, sessionId, `document.querySelector('#review-play').getAttribute('aria-pressed')`), 'false');
666
+
667
+ const overview = await evaluate(cdp, sessionId, `(() => {
668
+ document.querySelector('[role="tab"][data-target="delta"]').click();
669
+ document.querySelector('#review-overview').click();
670
+ return {
671
+ active: document.querySelector('[data-view="delta"]').hasAttribute('data-delta-review-active'),
672
+ current: document.querySelectorAll('[data-delta-review-current]').length,
673
+ selected: document.querySelectorAll('.change-row[aria-current="step"]').length
674
+ };
675
+ })()`);
676
+ assert.deepEqual(overview, { active: false, current: 0, selected: 0 });
677
+
678
+ await navigateReady(file, readyCondition, 'architecture-delta manual lifecycle navigator');
679
+ await evaluate(cdp, sessionId, `document.querySelector('#review-play').click()`);
680
+ await waitForSelected('relationship:fraud-check', 'architecture-delta previous control');
681
+ const previousPause = await evaluate(cdp, sessionId, `(() => {
682
+ document.querySelector('#review-previous').click();
683
+ return {
684
+ selected: document.querySelector('.change-row[aria-current="step"]')?.dataset.changeKey,
685
+ pressed: document.querySelector('#review-play').getAttribute('aria-pressed')
686
+ };
687
+ })()`);
688
+ assert.deepEqual(previousPause, { selected: 'component:fraud', pressed: 'false' });
689
+ await delay(1450);
690
+ assert.equal(await evaluate(cdp, sessionId, `document.querySelector('.change-row[aria-current="step"]')?.dataset.changeKey`), 'component:fraud');
691
+
692
+ await evaluate(cdp, sessionId, `document.querySelector('#review-play').click()`);
693
+ const nextPause = await evaluate(cdp, sessionId, `(() => {
694
+ document.querySelector('#review-next').click();
695
+ return {
696
+ selected: document.querySelector('.change-row[aria-current="step"]')?.dataset.changeKey,
697
+ pressed: document.querySelector('#review-play').getAttribute('aria-pressed')
698
+ };
699
+ })()`);
700
+ assert.deepEqual(nextPause, { selected: 'relationship:fraud-check', pressed: 'false' });
701
+
702
+ await evaluate(cdp, sessionId, `document.querySelector('#review-play').click()`);
703
+ const rowPause = await evaluate(cdp, sessionId, `(() => {
704
+ document.querySelector('.change-row[data-change-key="component:queue"]').click();
705
+ return {
706
+ selected: document.querySelector('.change-row[aria-current="step"]')?.dataset.changeKey,
707
+ pressed: document.querySelector('#review-play').getAttribute('aria-pressed')
708
+ };
709
+ })()`);
710
+ assert.deepEqual(rowPause, { selected: 'component:queue', pressed: 'false' });
711
+
712
+ await navigateReady(file, readyCondition, 'architecture-delta focus lifecycle navigator');
713
+ const focusedPause = await evaluate(cdp, sessionId, `(() => {
714
+ document.querySelector('#review-play').click();
715
+ document.querySelector('#review-next').focus();
716
+ return {
717
+ selected: document.querySelector('.change-row[aria-current="step"]')?.dataset.changeKey,
718
+ pressed: document.querySelector('#review-play').getAttribute('aria-pressed')
719
+ };
720
+ })()`);
721
+ assert.deepEqual(focusedPause, { selected: 'component:fraud', pressed: 'false' });
722
+ await delay(1450);
723
+ assert.equal(await evaluate(cdp, sessionId, `document.querySelector('.change-row[aria-current="step"]')?.dataset.changeKey`), 'component:fraud');
724
+
725
+ await navigateReady(file, readyCondition, 'architecture-delta hidden lifecycle navigator');
726
+ const hiddenPause = await evaluate(cdp, sessionId, `(() => {
727
+ document.querySelector('#review-play').click();
728
+ Object.defineProperty(document, 'hidden', { configurable: true, get: function () { return true; } });
729
+ document.dispatchEvent(new Event('visibilitychange'));
730
+ return {
731
+ hidden: document.hidden,
732
+ selected: document.querySelector('.change-row[aria-current="step"]')?.dataset.changeKey,
733
+ pressed: document.querySelector('#review-play').getAttribute('aria-pressed')
734
+ };
735
+ })()`);
736
+ assert.deepEqual(hiddenPause, { hidden: true, selected: 'component:fraud', pressed: 'false' });
737
+ await delay(1450);
738
+ assert.equal(await evaluate(cdp, sessionId, `document.querySelector('.change-row[aria-current="step"]')?.dataset.changeKey`), 'component:fraud');
739
+
740
+ await navigateReady(file, readyCondition, 'architecture-delta print lifecycle navigator');
741
+ const printPause = await evaluate(cdp, sessionId, `(() => {
742
+ document.querySelector('#review-play').click();
743
+ window.dispatchEvent(new Event('beforeprint'));
744
+ return {
745
+ status: document.querySelector('#review-status').textContent,
746
+ selected: document.querySelectorAll('.change-row[aria-current="step"]').length,
747
+ pressed: document.querySelector('#review-play').getAttribute('aria-pressed')
748
+ };
749
+ })()`);
750
+ assert.deepEqual(printPause, { status: 'Overview · 11 authored changes', selected: 0, pressed: 'false' });
751
+ await delay(1450);
752
+ assert.equal(await evaluate(cdp, sessionId, `document.querySelectorAll('.change-row[aria-current="step"]').length`), 0);
753
+
754
+ const keyboard = await evaluate(cdp, sessionId, `(() => {
755
+ document.querySelector('details').open = true;
756
+ var first = document.querySelector('.change-row');
757
+ first.click();
758
+ first.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true }));
759
+ var focused = document.activeElement.dataset.changeKey;
760
+ document.activeElement.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));
761
+ return { focused: focused, selected: document.querySelector('.change-row[aria-current="step"]').dataset.changeKey };
762
+ })()`);
763
+ assert.deepEqual(keyboard, { focused: 'relationship:fraud-check', selected: 'relationship:fraud-check' });
764
+
765
+ await cdp.send('Emulation.setEmulatedMedia', { features: [{ name: 'prefers-reduced-motion', value: 'reduce' }] }, sessionId);
766
+ await navigateReady(file, readyCondition, 'architecture-delta reduced-motion navigator');
767
+ await evaluate(cdp, sessionId, `document.querySelector('#review-play').click()`);
768
+ await delay(1550);
769
+ const reduced = await evaluate(cdp, sessionId, `({
770
+ selected: document.querySelector('.change-row[aria-current="step"]')?.dataset.changeKey,
771
+ pressed: document.querySelector('#review-play').getAttribute('aria-pressed'),
772
+ nextDisabled: document.querySelector('#review-next').disabled
773
+ })`);
774
+ assert.deepEqual(reduced, { selected: 'component:fraud', pressed: 'false', nextDisabled: false });
775
+ await evaluate(cdp, sessionId, `document.querySelector('#review-next').click()`);
776
+
777
+ await evaluate(cdp, sessionId, `document.querySelector('.change-row').click()`);
778
+ await cdp.send('Emulation.setEmulatedMedia', { media: 'print' }, sessionId);
779
+ await delay(200);
780
+ const printState = await evaluate(cdp, sessionId, `({
781
+ strip: getComputedStyle(document.querySelector('.review-strip')).display,
782
+ base: getComputedStyle(document.querySelector('[data-view="base"]')).display,
783
+ delta: getComputedStyle(document.querySelector('[data-view="delta"]')).display,
784
+ head: getComputedStyle(document.querySelector('[data-view="head"]')).display,
785
+ current: getComputedStyle(document.querySelector('[data-delta-review-current]')).opacity,
786
+ same: getComputedStyle(document.querySelector('[data-view="delta"] [data-delta-state="same"]')).opacity
787
+ })`);
788
+ assert.deepEqual(printState, { strip: 'none', base: 'none', delta: 'block', head: 'none', current: '1', same: '1' });
789
+ await cdp.send('Emulation.setEmulatedMedia', {
790
+ media: 'screen',
791
+ features: [{ name: 'prefers-reduced-motion', value: 'no-preference' }],
792
+ }, sessionId);
793
+
794
+ await navigateReady(file, readyCondition, 'architecture-delta tamper navigator');
795
+ const tampered = await evaluate(cdp, sessionId, `(() => {
796
+ var companion = document.querySelector('[data-view="delta"] g[data-edge-id="fraud-check"]');
797
+ companion.parentNode.insertBefore(companion.cloneNode(true), companion.nextSibling);
798
+ document.querySelector('.change-row[data-change-key="relationship:fraud-check"]').click();
799
+ return {
800
+ status: document.querySelector('#review-status').textContent,
801
+ disabled: Array.from(document.querySelectorAll('.review-step,.change-row')).every(function (button) { return button.disabled; }),
802
+ canvases: document.querySelectorAll('[data-view]').length
803
+ };
804
+ })()`);
805
+ assert.deepEqual(tampered, { status: 'Review unavailable · compare identity mismatch', disabled: true, canvases: 3 });
806
+
807
+ await navigateReady(file, readyCondition, 'architecture-delta finite navigator');
808
+ await evaluate(cdp, sessionId, `document.querySelector('#review-play').click()`);
809
+ await waitForReviewFinished('architecture-delta finite playback');
810
+ const finished = await evaluate(cdp, sessionId, `({
811
+ selected: document.querySelector('.change-row[aria-current="step"]')?.dataset.changeKey,
812
+ label: document.querySelector('#review-play').textContent,
813
+ pressed: document.querySelector('#review-play').getAttribute('aria-pressed')
814
+ })`);
815
+ assert.deepEqual(finished, { selected: 'relationship:publish-order', label: 'Replay', pressed: 'false' });
816
+ await evaluate(cdp, sessionId, `document.querySelector('#review-play').click()`);
817
+ const replayStarted = await evaluate(cdp, sessionId, `({
818
+ selected: document.querySelector('.change-row[aria-current="step"]')?.dataset.changeKey,
819
+ label: document.querySelector('#review-play').textContent,
820
+ pressed: document.querySelector('#review-play').getAttribute('aria-pressed')
821
+ })`);
822
+ assert.deepEqual(replayStarted, { selected: 'component:fraud', label: 'Pause', pressed: 'true' });
823
+ await waitForReviewFinished('architecture-delta replay playback');
824
+ const replayFinished = await evaluate(cdp, sessionId, `({
825
+ selected: document.querySelector('.change-row[aria-current="step"]')?.dataset.changeKey,
826
+ label: document.querySelector('#review-play').textContent,
827
+ pressed: document.querySelector('#review-play').getAttribute('aria-pressed')
828
+ })`);
829
+ assert.deepEqual(replayFinished, { selected: 'relationship:publish-order', label: 'Replay', pressed: 'false' });
830
+
831
+ const exportProof = await withTimeout(evaluate(cdp, sessionId, String.raw`(async function () {
832
+ var frames = Array.from(document.querySelectorAll('.snapshot-frame'));
833
+ var explorers = frames.map(function (frame) {
834
+ var child = frame.contentWindow;
835
+ return Boolean(child && child.Archify && child.Archify.focus && child.Archify.routeProbe && child.document.querySelector('#btn-node-finder') && child.document.querySelector('#guided-view-play'));
836
+ });
837
+ var svgA = Archify.deltaExport.canonicalSvg();
838
+ document.querySelector('#theme').click();
839
+ document.querySelector('#preset').click();
840
+ document.querySelector('.change-row').click();
841
+ var svgB = Archify.deltaExport.canonicalSvg();
842
+ var parsed = new DOMParser().parseFromString(svgB, 'image/svg+xml');
843
+ var baselineMarkers = Array.from(parsed.querySelectorAll('path[data-edge-id][data-delta-state="removed"], path[data-edge-id][data-delta-state="moved-from"]')).map(function (edge) {
844
+ var markerId = (edge.getAttribute('marker-end') || '').match(/^url\(#([^)]+)\)$/)?.[1];
845
+ var marker = markerId ? parsed.getElementById(markerId) : null;
846
+ return {
847
+ edge: edge.getAttribute('data-edge-id'),
848
+ resolved: marker?.localName === 'marker',
849
+ tone: marker?.querySelector('polygon')?.getAttribute('class') || null
850
+ };
851
+ }).sort(function (a, b) { return a.edge.localeCompare(b.edge); });
852
+ var exportStyle = parsed.querySelector('style')?.textContent || '';
853
+ var blob = await Archify.deltaExport.shareCard();
854
+ var bytes = new Uint8Array(await blob.arrayBuffer());
855
+ return {
856
+ explorers: explorers,
857
+ stable: svgA === svgB,
858
+ baselineMarkers: baselineMarkers,
859
+ reviewResidue: parsed.querySelectorAll('[data-delta-review-current]').length,
860
+ boundaryStyle: exportStyle.includes('text[data-delta-boundary-state="added"]{fill:#34d399!important}'),
861
+ markerStyle: exportStyle.includes('.delta-edge-marker[data-delta-state],.delta-boundary-marker[data-delta-state]{color:var(--delta)}'),
862
+ frameStyle: exportStyle.includes('rect[data-graph-role="structural-frame"]'),
863
+ boundaryMarkers: Array.from(parsed.querySelectorAll('.delta-boundary-marker')).map(function (marker) { return marker.textContent; }),
864
+ type: blob.type,
865
+ size: blob.size,
866
+ signature: Array.from(bytes.slice(0, 8)).map(function (byte) { return byte.toString(16).padStart(2, '0'); }).join('')
867
+ };
868
+ })()`, true), 15_000, 'Architecture Delta export');
869
+ assert.deepEqual(exportProof.explorers, [true, true]);
870
+ assert.equal(exportProof.stable, true);
871
+ assert.deepEqual(exportProof.baselineMarkers, [
872
+ { edge: 'authorize-payment', resolved: true, tone: 'm-security' },
873
+ { edge: 'publish-order', resolved: true, tone: 'm-dashed' },
874
+ { edge: 'session-read', resolved: true, tone: 'm-default' },
875
+ ]);
876
+ assert.equal(exportProof.reviewResidue, 0);
877
+ assert.equal(exportProof.boundaryStyle, true);
878
+ assert.equal(exportProof.markerStyle, true);
879
+ assert.equal(exportProof.frameStyle, true);
880
+ assert.deepEqual(exportProof.boundaryMarkers, ['~', '~']);
881
+ assert.equal(exportProof.type, 'image/png');
882
+ assert.ok(exportProof.size > 20_000, `Architecture Delta Share Card is unexpectedly small (${exportProof.size} bytes)`);
883
+ assert.equal(exportProof.signature, '89504e470d0a1a0a');
884
+ console.log(`ok Architecture Delta navigator + export: exact identity, complete explorers, static SVG, and ${exportProof.size}-byte Share Card`);
885
+ }
886
+
887
+ async function captureShareCard(file, label) {
888
+ await navigateReady(file, '!!(window.Archify && Archify.exportMenu && Archify.exportMenu.shareCard)', label);
889
+ const sharePayload = await withTimeout(evaluate(cdp, sessionId, String.raw`(async function () {
890
+ try {
891
+ var blob = await Archify.exportMenu.shareCard();
892
+ var bytes = new Uint8Array(await blob.arrayBuffer());
893
+ var binary = '';
894
+ for (var offset = 0; offset < bytes.length; offset += 32768) {
895
+ binary += String.fromCharCode.apply(null, bytes.subarray(offset, offset + 32768));
896
+ }
897
+ return { ok: true, type: blob.type, size: blob.size, base64: btoa(binary) };
898
+ } catch (error) {
899
+ return { ok: false, error: String(error && error.message || error) };
900
+ }
901
+ })()`, true), 10_000, `${label} Share Card export`);
902
+
903
+ assert.equal(sharePayload?.ok, true, sharePayload?.error || `${label} Share Card export failed`);
904
+ assert.equal(sharePayload.type, 'image/png');
905
+ assert.ok(sharePayload.size > 20_000, `${label} Share Card is unexpectedly small (${sharePayload.size} bytes)`);
906
+
907
+ const png = Buffer.from(sharePayload.base64, 'base64');
908
+ assert.equal(png.subarray(0, 8).toString('hex'), '89504e470d0a1a0a', `${label} output is not a PNG`);
909
+ assert.equal(png.readUInt32BE(16), 1200, `${label} Share Card width`);
910
+ assert.equal(png.readUInt32BE(20), 630, `${label} Share Card height`);
911
+
912
+ const pngPath = path.join(tmp, `${label}.share-card.png`);
913
+ fs.writeFileSync(pngPath, png);
914
+ const pixels = execFileSync(ffmpeg, [
915
+ '-v', 'error',
916
+ '-i', pngPath,
917
+ '-vf', 'scale=120:63',
918
+ '-frames:v', '1',
919
+ '-f', 'rawvideo',
920
+ '-pix_fmt', 'rgb24',
921
+ '-',
922
+ ], { maxBuffer: 4 * 1024 * 1024 });
923
+ const colors = new Set();
924
+ const counts = new Map();
925
+ for (let offset = 0; offset < pixels.length; offset += 3) {
926
+ const color = pixels.subarray(offset, offset + 3).toString('hex');
927
+ colors.add(color);
928
+ counts.set(color, (counts.get(color) || 0) + 1);
929
+ }
930
+ const largestColorShare = Math.max(...counts.values()) / (pixels.length / 3);
931
+ assert.ok(colors.size >= 24, `${label} Share Card has only ${colors.size} sampled colors`);
932
+ assert.ok(largestColorShare < 0.96, `${label} Share Card is visually near-blank (${Math.round(largestColorShare * 100)}% one color)`);
933
+ console.log(`ok ${label} Share Card: ${sharePayload.size} bytes, 1200x630, ${colors.size} sampled colors`);
934
+ }
935
+
936
+ async function captureCopiedShareCard(file, label) {
937
+ await navigateReady(file, '!!(window.Archify && Archify.exportMenu && Archify.exportMenu.copyShareCard)', label);
938
+ const copiedPayload = await withTimeout(evaluate(cdp, sessionId, String.raw`(async function () {
939
+ try {
940
+ Object.defineProperty(window, 'ClipboardItem', {
941
+ configurable: true,
942
+ value: function ClipboardItem(items) { this.items = items; }
943
+ });
944
+ Object.defineProperty(navigator, 'clipboard', {
945
+ configurable: true,
946
+ value: {
947
+ write: async function (items) {
948
+ window.__archifyCopiedShareCard = await Promise.resolve(items[0].items['image/png']);
949
+ }
950
+ }
951
+ });
952
+ window.alert = function (message) { window.__archifyCopyAlert = message; };
953
+ await Archify.exportMenu.copyShareCard();
954
+ var blob = window.__archifyCopiedShareCard;
955
+ if (!blob) throw new Error(window.__archifyCopyAlert || 'clipboard received no blob');
956
+ var bytes = new Uint8Array(await blob.arrayBuffer());
957
+ var binary = '';
958
+ for (var offset = 0; offset < bytes.length; offset += 32768) {
959
+ binary += String.fromCharCode.apply(null, bytes.subarray(offset, offset + 32768));
960
+ }
961
+ return {
962
+ ok: true,
963
+ type: blob.type,
964
+ size: blob.size,
965
+ base64: btoa(binary),
966
+ receipt: {
967
+ format: document.documentElement.getAttribute('data-last-export-format'),
968
+ width: document.documentElement.getAttribute('data-last-export-width'),
969
+ height: document.documentElement.getAttribute('data-last-export-height'),
970
+ canonical: document.documentElement.getAttribute('data-last-export-canonical'),
971
+ error: document.documentElement.getAttribute('data-last-export-error')
972
+ }
973
+ };
974
+ } catch (error) {
975
+ return { ok: false, error: String(error && error.message || error) };
976
+ }
977
+ })()`, true), 10_000, `${label} Copy Share Card`);
978
+
979
+ assert.equal(copiedPayload?.ok, true, copiedPayload?.error || `${label} Copy Share Card failed`);
980
+ assert.equal(copiedPayload.type, 'image/png');
981
+ assert.ok(copiedPayload.size > 20_000, `${label} copied Share Card is unexpectedly small`);
982
+ const png = Buffer.from(copiedPayload.base64, 'base64');
983
+ assert.equal(png.subarray(0, 8).toString('hex'), '89504e470d0a1a0a', `${label} copied output is not a PNG`);
984
+ assert.equal(png.readUInt32BE(16), 1200, `${label} copied Share Card width`);
985
+ assert.equal(png.readUInt32BE(20), 630, `${label} copied Share Card height`);
986
+ assert.deepEqual(copiedPayload.receipt, {
987
+ format: 'share-card',
988
+ width: '1200',
989
+ height: '630',
990
+ canonical: 'true',
991
+ error: null,
992
+ });
993
+ console.log(`ok ${label} Copy Share Card: ${copiedPayload.size} bytes, image/png, truthful receipt`);
994
+ }
995
+
996
+ async function captureRouteShareCard(file, label, sourceId, targetId, options = {}) {
997
+ await navigateReady(file, '!!(window.Archify && Archify.routeProbe && Archify.exportMenu && Archify.exportMenu.downloadRouteShareCard)', label);
998
+ const routePayload = await withTimeout(evaluate(cdp, sessionId, String.raw`(async function () {
999
+ try {
1000
+ window.alert = function (message) { window.__archifyRouteAlert = message; };
1001
+ Archify.routeProbe.begin({ source: ${JSON.stringify(sourceId)}, focusNode: false });
1002
+ if (!Archify.routeProbe.choose(${JSON.stringify(targetId)}, { updateUrl: false })) {
1003
+ throw new Error('route did not resolve');
1004
+ }
1005
+ var snapshot = Archify.routeProbe.exportSnapshot();
1006
+ if (!snapshot) throw new Error('resolved route exposed no export snapshot');
1007
+ Archify.exportMenu.syncRouteShare();
1008
+ var routeMenuItem = document.querySelector('[data-action="route-share-card"]');
1009
+ var menuResolved = !!routeMenuItem && !routeMenuItem.hidden && !routeMenuItem.disabled;
1010
+ var svg = document.querySelector('.diagram-container svg');
1011
+ var firstEdgeKey = snapshot.edges[0].key;
1012
+ var primaryCarrier = Array.from(svg.querySelectorAll('[data-edge-key]')).find(function (element) {
1013
+ return element.getAttribute('data-edge-key') === firstEdgeKey && hasDrawableGeometry(element);
1014
+ });
1015
+ if (!primaryCarrier) throw new Error('route exposed no primary geometry carrier');
1016
+ var duplicateCarrier = primaryCarrier.cloneNode(true);
1017
+ var duplicateGeometry = /^(path|line|polyline)$/i.test(duplicateCarrier.tagName)
1018
+ ? duplicateCarrier
1019
+ : duplicateCarrier.querySelector('path, line, polyline');
1020
+ if (duplicateGeometry.tagName.toLowerCase() === 'path') {
1021
+ duplicateGeometry.setAttribute('d', duplicateGeometry.getAttribute('d') + ' M 0 0 L 1 1');
1022
+ }
1023
+ svg.appendChild(duplicateCarrier);
1024
+ var duplicateGeometryRejected = Archify.routeProbe.exportSnapshot() === null;
1025
+ var duplicateExportError = '';
1026
+ try { await Archify.exportMenu.shareCard({ variant: 'route' }); }
1027
+ catch (error) { duplicateExportError = String(error && error.message || error); }
1028
+ duplicateCarrier.remove();
1029
+ var primaryGeometry = /^(path|line|polyline)$/i.test(primaryCarrier.tagName)
1030
+ ? primaryCarrier
1031
+ : primaryCarrier.querySelector('path, line, polyline');
1032
+ var geometryAttribute = primaryGeometry.tagName.toLowerCase() === 'path' ? 'd' :
1033
+ primaryGeometry.tagName.toLowerCase() === 'polyline' ? 'points' : 'x2';
1034
+ var originalGeometry = primaryGeometry.getAttribute(geometryAttribute);
1035
+ primaryGeometry.setAttribute(geometryAttribute, '');
1036
+ var emptyGeometryRejected = Archify.routeProbe.exportSnapshot() === null;
1037
+ var emptyGeometryExportError = '';
1038
+ try { await Archify.exportMenu.shareCard({ variant: 'route' }); }
1039
+ catch (error) { emptyGeometryExportError = String(error && error.message || error); }
1040
+ primaryGeometry.setAttribute(geometryAttribute, originalGeometry);
1041
+ await new Promise(function (resolve) {
1042
+ requestAnimationFrame(function () { requestAnimationFrame(resolve); });
1043
+ });
1044
+ function stableLiveSnapshot() {
1045
+ var clone = svg.cloneNode(true);
1046
+ clone.style.removeProperty('transform');
1047
+ clone.style.removeProperty('clip-path');
1048
+ clone.removeAttribute('data-view-scale');
1049
+ Array.from(clone.querySelectorAll('[data-legend-bridge-runtime]')).forEach(function (element) { element.remove(); });
1050
+ return clone.outerHTML;
1051
+ }
1052
+ var liveBefore = stableLiveSnapshot();
1053
+ var captured = [];
1054
+ var downloads = [];
1055
+ var originalCreateObjectURL = URL.createObjectURL.bind(URL);
1056
+ var originalAnchorClick = HTMLAnchorElement.prototype.click;
1057
+ var originalFillText = CanvasRenderingContext2D.prototype.fillText;
1058
+ var headerMetrics = [];
1059
+ URL.createObjectURL = function (blob) {
1060
+ if (blob && blob.type && blob.type.indexOf('image/svg+xml') === 0) {
1061
+ captured.push(blob.text());
1062
+ }
1063
+ return originalCreateObjectURL(blob);
1064
+ };
1065
+ HTMLAnchorElement.prototype.click = function () { downloads.push(this.download); };
1066
+ CanvasRenderingContext2D.prototype.fillText = function (text, x, y) {
1067
+ if (headerMetrics.length < 2 && (y === 62 || y === 87)) {
1068
+ headerMetrics.push({
1069
+ y: y,
1070
+ text: String(text),
1071
+ width: this.measureText(String(text)).width,
1072
+ maxWidth: y === 62 ? 798 : 848
1073
+ });
1074
+ }
1075
+ return originalFillText.apply(this, arguments);
1076
+ };
1077
+
1078
+ var blob;
1079
+ var canonicalBlob;
1080
+ var routeReceipt;
1081
+ var ordinaryReceipt;
1082
+ var routeFingerprints = [];
1083
+ try {
1084
+ blob = await Archify.exportMenu.downloadRouteShareCard();
1085
+ routeReceipt = {
1086
+ format: document.documentElement.getAttribute('data-last-export-format'),
1087
+ variant: document.documentElement.getAttribute('data-last-export-variant'),
1088
+ width: document.documentElement.getAttribute('data-last-export-width'),
1089
+ height: document.documentElement.getAttribute('data-last-export-height'),
1090
+ canonical: document.documentElement.getAttribute('data-last-export-canonical'),
1091
+ routeStateClean: document.documentElement.getAttribute('data-last-export-route-state-clean'),
1092
+ error: document.documentElement.getAttribute('data-last-export-error')
1093
+ };
1094
+ var routeSvgText = captured[0] ? await captured[0] : '';
1095
+ function fingerprint(text) {
1096
+ var hash = 2166136261;
1097
+ for (var index = 0; index < text.length; index++) {
1098
+ hash ^= text.charCodeAt(index);
1099
+ hash = Math.imul(hash, 16777619);
1100
+ }
1101
+ return (hash >>> 0).toString(16);
1102
+ }
1103
+ routeFingerprints.push(fingerprint(routeSvgText));
1104
+
1105
+ if (${JSON.stringify(options.journeyInvariance === true)}) {
1106
+ async function captureJourneySource(action) {
1107
+ action();
1108
+ var captureIndex = captured.length;
1109
+ await Archify.exportMenu.shareCard({ variant: 'route' });
1110
+ routeFingerprints.push(fingerprint(await captured[captureIndex]));
1111
+ }
1112
+ await captureJourneySource(function () { Archify.routeProbe.selectJourneyIndex(0); });
1113
+ await captureJourneySource(function () { Archify.routeProbe.selectJourneyIndex(Math.floor(snapshot.nodeIds.length / 2)); });
1114
+ await captureJourneySource(function () { Archify.routeProbe.selectJourneyIndex(snapshot.nodeIds.length - 1); });
1115
+ Archify.routeProbe.showOverview({ reveal: false });
1116
+ var started = Archify.routeProbe.playJourney();
1117
+ if (!started) throw new Error('Route Journey could not enter playing state for invariance check');
1118
+ await captureJourneySource(function () {});
1119
+ Archify.routeProbe.pauseJourney({ preserveElapsed: false });
1120
+ await captureJourneySource(function () {});
1121
+ document.documentElement.setAttribute('data-motion', 'still');
1122
+ await captureJourneySource(function () {});
1123
+ document.documentElement.setAttribute('data-motion', 'live');
1124
+ Archify.routeProbe.showOverview({ reveal: false });
1125
+ }
1126
+
1127
+ var toBlobError = '';
1128
+ var originalToBlob = HTMLCanvasElement.prototype.toBlob;
1129
+ HTMLCanvasElement.prototype.toBlob = function (callback) { callback(null); };
1130
+ try { await Archify.exportMenu.shareCard({ variant: 'route' }); }
1131
+ catch (error) { toBlobError = String(error && error.message || error); }
1132
+ finally { HTMLCanvasElement.prototype.toBlob = originalToBlob; }
1133
+
1134
+ var missingToBlobError = '';
1135
+ HTMLCanvasElement.prototype.toBlob = undefined;
1136
+ try { await Archify.exportMenu.shareCard({ variant: 'route' }); }
1137
+ catch (error) { missingToBlobError = String(error && error.message || error); }
1138
+ finally { HTMLCanvasElement.prototype.toBlob = originalToBlob; }
1139
+
1140
+ var missingContextError = '';
1141
+ var originalGetContext = HTMLCanvasElement.prototype.getContext;
1142
+ HTMLCanvasElement.prototype.getContext = function () { return null; };
1143
+ try { await Archify.exportMenu.shareCard({ variant: 'route' }); }
1144
+ catch (error) { missingContextError = String(error && error.message || error); }
1145
+ finally { HTMLCanvasElement.prototype.getContext = originalGetContext; }
1146
+
1147
+ var imageDecodeError = '';
1148
+ var OriginalImage = window.Image;
1149
+ function FailingImage() {}
1150
+ Object.defineProperty(FailingImage.prototype, 'src', {
1151
+ set: function () {
1152
+ var instance = this;
1153
+ queueMicrotask(function () {
1154
+ if (typeof instance.onerror === 'function') instance.onerror(new Event('error'));
1155
+ });
1156
+ }
1157
+ });
1158
+ window.Image = FailingImage;
1159
+ try { await Archify.exportMenu.shareCard({ variant: 'route' }); }
1160
+ catch (error) { imageDecodeError = String(error && error.message || error); }
1161
+ finally { window.Image = OriginalImage; }
1162
+
1163
+ var unknownVariantError = '';
1164
+ try { await Archify.exportMenu.shareCard({ variant: 'unknown' }); }
1165
+ catch (error) { unknownVariantError = String(error && error.message || error); }
1166
+
1167
+ var canonicalIndex = captured.length;
1168
+ canonicalBlob = await Archify.exportMenu.shareCard();
1169
+ var canonicalSvgText = captured[canonicalIndex] ? await captured[canonicalIndex] : '';
1170
+ await Archify.exportMenu.run('share-card');
1171
+ ordinaryReceipt = {
1172
+ format: document.documentElement.getAttribute('data-last-export-format'),
1173
+ variant: document.documentElement.getAttribute('data-last-export-variant'),
1174
+ width: document.documentElement.getAttribute('data-last-export-width'),
1175
+ height: document.documentElement.getAttribute('data-last-export-height'),
1176
+ canonical: document.documentElement.getAttribute('data-last-export-canonical'),
1177
+ routeStateClean: document.documentElement.getAttribute('data-last-export-route-state-clean'),
1178
+ error: document.documentElement.getAttribute('data-last-export-error')
1179
+ };
1180
+ var svgDownloadIndex = captured.length;
1181
+ await Archify.exportMenu.run('svg');
1182
+ var exportedSvgText = captured[svgDownloadIndex] ? await captured[svgDownloadIndex] : '';
1183
+ var svgReceipt = {
1184
+ format: document.documentElement.getAttribute('data-last-export-format'),
1185
+ variant: document.documentElement.getAttribute('data-last-export-variant'),
1186
+ canonical: document.documentElement.getAttribute('data-last-export-canonical')
1187
+ };
1188
+ await Archify.exportMenu.run('png');
1189
+ var pngReceipt = {
1190
+ format: document.documentElement.getAttribute('data-last-export-format'),
1191
+ variant: document.documentElement.getAttribute('data-last-export-variant'),
1192
+ canonical: document.documentElement.getAttribute('data-last-export-canonical')
1193
+ };
1194
+
1195
+ var parser = new DOMParser();
1196
+ var routeSvg = parser.parseFromString(routeSvgText, 'image/svg+xml').documentElement;
1197
+ var canonicalSvg = parser.parseFromString(canonicalSvgText, 'image/svg+xml').documentElement;
1198
+ var exportedSvg = parser.parseFromString(exportedSvgText, 'image/svg+xml').documentElement;
1199
+ var matchedNodeIds = Array.from(routeSvg.querySelectorAll('[data-node-id][data-share-route-match]')).map(function (node) {
1200
+ return { id: node.getAttribute('data-node-id'), step: Number(node.getAttribute('data-share-route-step')) };
1201
+ }).sort(function (a, b) { return a.step - b.step; }).map(function (item) { return item.id; });
1202
+ var edgeSteps = new Map();
1203
+ Array.from(routeSvg.querySelectorAll('[data-edge-key][data-share-route-match]')).forEach(function (edge) {
1204
+ edgeSteps.set(edge.getAttribute('data-edge-key'), Number(edge.getAttribute('data-share-route-step')));
1205
+ });
1206
+ var matchedEdgeKeys = Array.from(edgeSteps).sort(function (a, b) { return a[1] - b[1]; }).map(function (entry) { return entry[0]; });
1207
+ var expectedEdgeKeys = snapshot.edges.map(function (edge) { return edge.key; });
1208
+ var routeNodeIds = Array.from(routeSvg.querySelectorAll('[data-node-id]')).map(function (node) { return node.getAttribute('data-node-id'); }).sort();
1209
+ var liveNodeIds = Array.from(svg.querySelectorAll('[data-node-id]')).map(function (node) { return node.getAttribute('data-node-id'); }).sort();
1210
+ var routeEdgeKeys = Array.from(new Set(Array.from(routeSvg.querySelectorAll('[data-edge-key]')).map(function (edge) { return edge.getAttribute('data-edge-key'); }))).sort();
1211
+ var liveEdgeKeys = Array.from(new Set(Array.from(svg.querySelectorAll('[data-edge-key]')).map(function (edge) { return edge.getAttribute('data-edge-key'); }))).sort();
1212
+
1213
+ var bytes = new Uint8Array(await blob.arrayBuffer());
1214
+ var binary = '';
1215
+ for (var offset = 0; offset < bytes.length; offset += 32768) {
1216
+ binary += String.fromCharCode.apply(null, bytes.subarray(offset, offset + 32768));
1217
+ }
1218
+
1219
+ await new Promise(function (resolve) {
1220
+ requestAnimationFrame(function () { requestAnimationFrame(resolve); });
1221
+ });
1222
+ var liveAfter = stableLiveSnapshot();
1223
+ var liveUnchanged = liveBefore === liveAfter;
1224
+ var liveDiff = '';
1225
+ if (!liveUnchanged) {
1226
+ var diffIndex = 0;
1227
+ while (diffIndex < liveBefore.length && diffIndex < liveAfter.length && liveBefore[diffIndex] === liveAfter[diffIndex]) diffIndex++;
1228
+ liveDiff = 'at ' + diffIndex + ': before=' + liveBefore.slice(Math.max(0, diffIndex - 80), diffIndex + 160) +
1229
+ ' after=' + liveAfter.slice(Math.max(0, diffIndex - 80), diffIndex + 160);
1230
+ }
1231
+
1232
+ var asyncClearIndex = captured.length;
1233
+ var asyncClearPromise = Archify.exportMenu.shareCard({ variant: 'route' });
1234
+ Archify.routeProbe.clear({ updateUrl: false, preserveView: true });
1235
+ var asyncClearBlob = await asyncClearPromise;
1236
+ var asyncClearFingerprint = fingerprint(await captured[asyncClearIndex]);
1237
+ var hiddenAfterClear = routeMenuItem.hidden && routeMenuItem.disabled &&
1238
+ getComputedStyle(routeMenuItem).display === 'none';
1239
+ var staleError = '';
1240
+ try { await Archify.exportMenu.shareCard({ variant: 'route' }); }
1241
+ catch (error) { staleError = String(error && error.message || error); }
1242
+ await Archify.exportMenu.downloadRouteShareCard();
1243
+ var failedReceipt = {
1244
+ format: document.documentElement.getAttribute('data-last-export-format'),
1245
+ variant: document.documentElement.getAttribute('data-last-export-variant'),
1246
+ errorFormat: document.documentElement.getAttribute('data-last-export-error-format'),
1247
+ error: document.documentElement.getAttribute('data-last-export-error')
1248
+ };
1249
+
1250
+ return {
1251
+ ok: true,
1252
+ type: blob.type,
1253
+ size: blob.size,
1254
+ base64: btoa(binary),
1255
+ snapshot: snapshot,
1256
+ matchedNodeIds: matchedNodeIds,
1257
+ matchedEdgeKeys: matchedEdgeKeys,
1258
+ expectedEdgeKeys: expectedEdgeKeys,
1259
+ routeShare: routeSvg.hasAttribute('data-share-route'),
1260
+ routeLiveResidue: routeSvg.querySelectorAll('[data-route-match], [data-route-step], [data-route-start], [data-route-end], [data-route-journey-state], [data-route-journey-current], [data-route-journey-overlay]').length,
1261
+ routeMotionResidue: (routeSvg.hasAttribute('data-animation') ? 1 : 0) + routeSvg.querySelectorAll('[data-animate]').length,
1262
+ routeNodeIds: routeNodeIds,
1263
+ liveNodeIds: liveNodeIds,
1264
+ routeEdgeKeys: routeEdgeKeys,
1265
+ liveEdgeKeys: liveEdgeKeys,
1266
+ canonicalRouteResidue: canonicalSvg.querySelectorAll('[data-route-match], [data-route-step], [data-route-start], [data-route-end], [data-share-route-match], [data-share-route-step], [data-share-route-start], [data-share-route-end], [data-share-route-middle]').length,
1267
+ canonicalRouteActive: canonicalSvg.hasAttribute('data-route-active') || canonicalSvg.hasAttribute('data-share-route'),
1268
+ canonicalSize: canonicalBlob.size,
1269
+ liveUnchanged: liveUnchanged,
1270
+ liveDiff: liveDiff,
1271
+ menuResolved: menuResolved,
1272
+ duplicateGeometryRejected: duplicateGeometryRejected,
1273
+ duplicateExportError: duplicateExportError,
1274
+ emptyGeometryRejected: emptyGeometryRejected,
1275
+ emptyGeometryExportError: emptyGeometryExportError,
1276
+ toBlobError: toBlobError,
1277
+ missingToBlobError: missingToBlobError,
1278
+ missingContextError: missingContextError,
1279
+ imageDecodeError: imageDecodeError,
1280
+ unknownVariantError: unknownVariantError,
1281
+ headerMetrics: headerMetrics,
1282
+ routeLabelExecuted: !!window.__routeLabelExecuted,
1283
+ svgReceipt: svgReceipt,
1284
+ pngReceipt: pngReceipt,
1285
+ exportedSvgRouteResidue: exportedSvg.hasAttribute('data-route-active') ||
1286
+ exportedSvg.hasAttribute('data-share-route') ||
1287
+ exportedSvg.querySelectorAll('[data-route-match], [data-route-step], [data-route-start], [data-route-end], [data-share-route-match], [data-share-route-step], [data-share-route-start], [data-share-route-end], [data-share-route-middle]').length > 0,
1288
+ exportedSvgDualTheme: /prefers-color-scheme:\s*light/.test(Array.from(exportedSvg.querySelectorAll('style')).map(function (style) { return style.textContent; }).join('\n')),
1289
+ asyncClearStable: asyncClearBlob && asyncClearBlob.type === 'image/png' && asyncClearFingerprint === routeFingerprints[0],
1290
+ hiddenAfterClear: hiddenAfterClear,
1291
+ staleSnapshot: Archify.routeProbe.exportSnapshot(),
1292
+ staleError: staleError,
1293
+ routeFingerprints: routeFingerprints,
1294
+ downloads: downloads,
1295
+ routeReceipt: routeReceipt,
1296
+ ordinaryReceipt: ordinaryReceipt,
1297
+ failedReceipt: failedReceipt
1298
+ };
1299
+ } finally {
1300
+ URL.createObjectURL = originalCreateObjectURL;
1301
+ HTMLAnchorElement.prototype.click = originalAnchorClick;
1302
+ CanvasRenderingContext2D.prototype.fillText = originalFillText;
1303
+ }
1304
+ } catch (error) {
1305
+ return { ok: false, error: String(error && error.message || error) };
1306
+ }
1307
+ })()`, true), 25_000, `${label} Route Card export`);
1308
+
1309
+ assert.equal(routePayload?.ok, true, routePayload?.error || `${label} Route Card export failed`);
1310
+ assert.equal(routePayload.type, 'image/png');
1311
+ assert.ok(routePayload.size > 20_000, `${label} Route Card is unexpectedly small (${routePayload.size} bytes)`);
1312
+ const png = Buffer.from(routePayload.base64, 'base64');
1313
+ assert.equal(png.subarray(0, 8).toString('hex'), '89504e470d0a1a0a', `${label} Route Card is not a PNG`);
1314
+ assert.equal(png.readUInt32BE(16), 1200, `${label} Route Card width`);
1315
+ assert.equal(png.readUInt32BE(20), 630, `${label} Route Card height`);
1316
+ const pngPath = path.join(tmp, `${label}.route-share-card.png`);
1317
+ fs.writeFileSync(pngPath, png);
1318
+ const sampledPixels = execFileSync(ffmpeg, [
1319
+ '-v', 'error',
1320
+ '-i', pngPath,
1321
+ '-vf', 'scale=120:63',
1322
+ '-frames:v', '1',
1323
+ '-f', 'rawvideo',
1324
+ '-pix_fmt', 'rgb24',
1325
+ '-',
1326
+ ], { maxBuffer: 4 * 1024 * 1024 });
1327
+ const sampledColors = new Set();
1328
+ for (let offset = 0; offset < sampledPixels.length; offset += 3) {
1329
+ sampledColors.add(sampledPixels.subarray(offset, offset + 3).toString('hex'));
1330
+ }
1331
+ assert.ok(sampledColors.size >= 20, `${label} Route Card has only ${sampledColors.size} sampled colors`);
1332
+ assert.equal(routePayload.routeShare, true);
1333
+ assert.deepEqual(routePayload.matchedNodeIds, routePayload.snapshot.nodeIds);
1334
+ assert.deepEqual(routePayload.matchedEdgeKeys, routePayload.expectedEdgeKeys);
1335
+ assert.equal(routePayload.routeLiveResidue, 0);
1336
+ assert.equal(routePayload.routeMotionResidue, 0);
1337
+ assert.deepEqual(routePayload.routeNodeIds, routePayload.liveNodeIds);
1338
+ assert.deepEqual(routePayload.routeEdgeKeys, routePayload.liveEdgeKeys);
1339
+ assert.equal(routePayload.canonicalRouteResidue, 0);
1340
+ assert.equal(routePayload.canonicalRouteActive, false);
1341
+ assert.equal(routePayload.liveUnchanged, true, routePayload.liveDiff);
1342
+ assert.equal(routePayload.menuResolved, true);
1343
+ assert.equal(routePayload.duplicateGeometryRejected, true);
1344
+ assert.match(routePayload.duplicateExportError, /Trace a route before exporting a Route Share Card/);
1345
+ assert.equal(routePayload.emptyGeometryRejected, true);
1346
+ assert.match(routePayload.emptyGeometryExportError, /Trace a route before exporting a Route Share Card/);
1347
+ assert.match(routePayload.toBlobError, /canvas\.toBlob returned no data for Share Card/);
1348
+ assert.match(routePayload.missingToBlobError, /canvas\.toBlob unavailable for Share Card/);
1349
+ assert.match(routePayload.missingContextError, /2D canvas context unavailable for Share Card/);
1350
+ assert.ok(routePayload.imageDecodeError);
1351
+ assert.match(routePayload.unknownVariantError, /Unknown Share Card variant: unknown/);
1352
+ assert.equal(routePayload.routeLabelExecuted, false);
1353
+ assert.deepEqual(routePayload.headerMetrics.map((metric) => metric.y), [62, 87]);
1354
+ assert.ok(routePayload.headerMetrics.every((metric) => metric.width <= metric.maxWidth + 0.5), `${label} title/subtitle overflowed the Share Card header`);
1355
+ assert.deepEqual(routePayload.svgReceipt, { format: 'svg', variant: null, canonical: 'true' });
1356
+ assert.deepEqual(routePayload.pngReceipt, { format: 'png', variant: null, canonical: 'true' });
1357
+ assert.equal(routePayload.exportedSvgRouteResidue, false);
1358
+ assert.equal(routePayload.exportedSvgDualTheme, true);
1359
+ assert.equal(routePayload.asyncClearStable, true);
1360
+ assert.equal(routePayload.hiddenAfterClear, true);
1361
+ assert.equal(routePayload.staleSnapshot, null);
1362
+ assert.match(routePayload.staleError, /Trace a route before exporting a Route Share Card/);
1363
+ assert.ok(routePayload.routeFingerprints.every((fingerprint) => fingerprint === routePayload.routeFingerprints[0]), `${label} Route source changed across Journey state`);
1364
+ assert.match(routePayload.downloads[0], /-route-share-card\.png$/);
1365
+ assert.doesNotMatch(routePayload.downloads[0], /-route-.+-to-.+\.png$/);
1366
+ assert.deepEqual(routePayload.routeReceipt, {
1367
+ format: 'share-card',
1368
+ variant: 'route',
1369
+ width: '1200',
1370
+ height: '630',
1371
+ canonical: 'false',
1372
+ routeStateClean: 'true',
1373
+ error: null,
1374
+ });
1375
+ assert.deepEqual(routePayload.ordinaryReceipt, {
1376
+ format: 'share-card',
1377
+ variant: null,
1378
+ width: '1200',
1379
+ height: '630',
1380
+ canonical: 'true',
1381
+ routeStateClean: null,
1382
+ error: null,
1383
+ });
1384
+ assert.equal(routePayload.failedReceipt.format, null);
1385
+ assert.equal(routePayload.failedReceipt.variant, null);
1386
+ assert.equal(routePayload.failedReceipt.errorFormat, 'share-card');
1387
+ assert.match(routePayload.failedReceipt.error, /Trace a route before exporting a Route Share Card/);
1388
+ if (options.expectedHops !== undefined) assert.equal(routePayload.snapshot.hops, options.expectedHops);
1389
+ if (options.expectedSourceLabel !== undefined) assert.equal(routePayload.snapshot.source.label, options.expectedSourceLabel);
1390
+ if (options.expectedTargetLabel !== undefined) assert.equal(routePayload.snapshot.target.label, options.expectedTargetLabel);
1391
+ console.log(`ok ${label} Route Card: ${routePayload.size} bytes, ${routePayload.snapshot.nodeIds.length} nodes, ${routePayload.snapshot.edges.length} exact hops`);
1392
+ }
1393
+
1394
+ async function verifyDynamicReducedMotionRoute(file, label, sourceId, targetId) {
1395
+ await cdp.send('Emulation.setEmulatedMedia', {
1396
+ features: [{ name: 'prefers-reduced-motion', value: 'no-preference' }],
1397
+ }, sessionId);
1398
+ await navigateReady(file, '!!(window.Archify && Archify.routeProbe && Archify.exportMenu && Archify.motionGovernor)', label);
1399
+
1400
+ async function sourceFingerprint() {
1401
+ return withTimeout(evaluate(cdp, sessionId, String.raw`(async function () {
1402
+ var originalCreateObjectURL = URL.createObjectURL.bind(URL);
1403
+ var sourcePromise = null;
1404
+ URL.createObjectURL = function (blob) {
1405
+ if (!sourcePromise && blob && blob.type && blob.type.indexOf('image/svg+xml') === 0) sourcePromise = blob.text();
1406
+ return originalCreateObjectURL(blob);
1407
+ };
1408
+ try {
1409
+ await Archify.exportMenu.shareCard({ variant: 'route' });
1410
+ var source = await sourcePromise;
1411
+ var hash = 2166136261;
1412
+ for (var index = 0; index < source.length; index++) {
1413
+ hash ^= source.charCodeAt(index);
1414
+ hash = Math.imul(hash, 16777619);
1415
+ }
1416
+ return (hash >>> 0).toString(16);
1417
+ } finally {
1418
+ URL.createObjectURL = originalCreateObjectURL;
1419
+ }
1420
+ })()`, true), 10_000, `${label} source fingerprint`);
1421
+ }
1422
+
1423
+ const setup = await evaluate(cdp, sessionId, `(function () {
1424
+ Archify.routeProbe.begin({ source: ${JSON.stringify(sourceId)}, focusNode: false });
1425
+ if (!Archify.routeProbe.choose(${JSON.stringify(targetId)}, { updateUrl: false })) return { resolved: false };
1426
+ Archify.routeProbe.showOverview({ reveal: false });
1427
+ return {
1428
+ resolved: true,
1429
+ started: Archify.routeProbe.playJourney(),
1430
+ playing: Archify.routeProbe.isJourneyPlaying(),
1431
+ motion: document.documentElement.getAttribute('data-motion')
1432
+ };
1433
+ })()`);
1434
+ assert.deepEqual(setup, { resolved: true, started: true, playing: true, motion: 'live' });
1435
+ const before = await sourceFingerprint();
1436
+
1437
+ await cdp.send('Emulation.setEmulatedMedia', {
1438
+ features: [{ name: 'prefers-reduced-motion', value: 'reduce' }],
1439
+ }, sessionId);
1440
+ let reduced = null;
1441
+ for (let attempt = 0; attempt < 50; attempt += 1) {
1442
+ reduced = await evaluate(cdp, sessionId, `({
1443
+ matches: matchMedia('(prefers-reduced-motion: reduce)').matches,
1444
+ motion: document.documentElement.getAttribute('data-motion'),
1445
+ playing: Archify.routeProbe.isJourneyPlaying()
1446
+ })`);
1447
+ if (reduced.matches && reduced.motion === 'still' && !reduced.playing) break;
1448
+ await delay(20);
1449
+ }
1450
+ assert.deepEqual(reduced, { matches: true, motion: 'still', playing: false });
1451
+ const after = await sourceFingerprint();
1452
+ assert.equal(after, before, `${label} source changed after dynamic reduced-motion paused Journey`);
1453
+
1454
+ await cdp.send('Emulation.setEmulatedMedia', {
1455
+ features: [{ name: 'prefers-reduced-motion', value: 'no-preference' }],
1456
+ }, sessionId);
1457
+ console.log(`ok ${label}: dynamic reduced-motion paused Journey without changing Route Card source`);
1458
+ }
1459
+
1460
+ async function captureRouteVisualMatrix(file, label, sourceId, targetId) {
1461
+ await navigateReady(file, '!!(window.Archify && Archify.preset && Archify.routeProbe && Archify.exportMenu)', label);
1462
+ const matrix = await withTimeout(evaluate(cdp, sessionId, String.raw`(async function () {
1463
+ Archify.routeProbe.begin({ source: ${JSON.stringify(sourceId)}, focusNode: false });
1464
+ if (!Archify.routeProbe.choose(${JSON.stringify(targetId)}, { updateUrl: false })) {
1465
+ throw new Error('route did not resolve');
1466
+ }
1467
+ var identity = JSON.stringify(Archify.routeProbe.exportSnapshot());
1468
+ var results = [];
1469
+ for (var preset of ['classic', 'signal-flow', 'blueprint', 'editorial']) {
1470
+ if (!Archify.preset.apply(preset)) throw new Error('could not apply preset ' + preset);
1471
+ for (var theme of ['dark', 'light']) {
1472
+ document.documentElement.setAttribute('data-theme', theme);
1473
+ var blob = await Archify.exportMenu.shareCard({ variant: 'route' });
1474
+ var bytes = new Uint8Array(await blob.arrayBuffer());
1475
+ var hash = 2166136261;
1476
+ for (var index = 0; index < bytes.length; index++) {
1477
+ hash ^= bytes[index];
1478
+ hash = Math.imul(hash, 16777619);
1479
+ }
1480
+ var view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
1481
+ results.push({
1482
+ preset: preset,
1483
+ theme: theme,
1484
+ type: blob.type,
1485
+ size: blob.size,
1486
+ width: view.getUint32(16),
1487
+ height: view.getUint32(20),
1488
+ hash: (hash >>> 0).toString(16),
1489
+ identity: JSON.stringify(Archify.routeProbe.exportSnapshot())
1490
+ });
1491
+ }
1492
+ }
1493
+ return { identity: identity, results: results };
1494
+ })()`, true), 20_000, `${label} Route visual matrix`);
1495
+
1496
+ assert.equal(matrix.results.length, 8);
1497
+ for (const result of matrix.results) {
1498
+ assert.equal(result.type, 'image/png', `${label} ${result.preset}/${result.theme} MIME`);
1499
+ assert.equal(result.width, 1200, `${label} ${result.preset}/${result.theme} width`);
1500
+ assert.equal(result.height, 630, `${label} ${result.preset}/${result.theme} height`);
1501
+ assert.ok(result.size > 20_000, `${label} ${result.preset}/${result.theme} is unexpectedly small`);
1502
+ assert.equal(result.identity, matrix.identity, `${label} ${result.preset}/${result.theme} changed route identity`);
1503
+ }
1504
+ assert.equal(new Set(matrix.results.map((result) => result.hash)).size, 8, `${label} presets/themes should produce eight distinct PNGs`);
1505
+ console.log(`ok ${label} Route visual matrix: Classic/Flow/Blueprint/Editorial x dark/light`);
1506
+ }
1507
+
1508
+ async function captureReachShareCard(file, label, originId, direction, options = {}) {
1509
+ await navigateReady(file, '!!(window.Archify && Archify.focus && Archify.focus.reachabilitySnapshot && Archify.exportMenu && Archify.exportMenu.downloadReachShareCard)', label);
1510
+ const reachPayload = await withTimeout(evaluate(cdp, sessionId, String.raw`(async function () {
1511
+ try {
1512
+ window.alert = function (message) { window.__archifyReachAlert = String(message); };
1513
+ if (!Archify.focus.set(${JSON.stringify(originId)}, { toggle: false, updateUrl: false })) {
1514
+ throw new Error('focus origin did not resolve');
1515
+ }
1516
+ if (!Archify.focus.reach(${JSON.stringify(direction)}, { toggle: false, updateUrl: false, reveal: false })) {
1517
+ throw new Error('authored reach did not resolve');
1518
+ }
1519
+ var snapshot = Archify.focus.reachabilitySnapshot();
1520
+ if (!snapshot) throw new Error('active authored reach exposed no export snapshot');
1521
+ Archify.exportMenu.syncReachShare();
1522
+ var reachMenuItem = document.querySelector('[data-action="reach-share-card"]');
1523
+ var menuResolved = !!reachMenuItem && !reachMenuItem.hidden && !reachMenuItem.disabled &&
1524
+ getComputedStyle(reachMenuItem).display !== 'none';
1525
+ var svg = document.querySelector('.diagram-container svg');
1526
+
1527
+ var firstEdge = snapshot.edges[0];
1528
+ var primaryCarrier = Array.from(svg.querySelectorAll('[data-edge-key]')).find(function (element) {
1529
+ return element.getAttribute('data-edge-key') === firstEdge.key && hasDrawableGeometry(element);
1530
+ });
1531
+ if (!primaryCarrier) throw new Error('reach exposed no primary geometry carrier');
1532
+ var duplicateCarrier = primaryCarrier.cloneNode(true);
1533
+ var duplicateGeometry = /^(path|line|polyline)$/i.test(duplicateCarrier.tagName)
1534
+ ? duplicateCarrier
1535
+ : duplicateCarrier.querySelector('path, line, polyline');
1536
+ if (duplicateGeometry.tagName.toLowerCase() === 'path') {
1537
+ duplicateGeometry.setAttribute('d', duplicateGeometry.getAttribute('d') + ' M 0 0 L 1 1');
1538
+ }
1539
+ svg.appendChild(duplicateCarrier);
1540
+ var duplicateGeometryRejected = Archify.focus.reachabilitySnapshot() === null;
1541
+ var duplicateExportError = '';
1542
+ try { await Archify.exportMenu.shareCard({ variant: 'reach' }); }
1543
+ catch (error) { duplicateExportError = String(error && error.message || error); }
1544
+ duplicateCarrier.remove();
1545
+ snapshot = Archify.focus.reachabilitySnapshot();
1546
+ if (!snapshot) throw new Error('reach snapshot did not recover after geometry restoration');
1547
+
1548
+ function stableLiveSnapshot() {
1549
+ var clone = svg.cloneNode(true);
1550
+ clone.style.removeProperty('transform');
1551
+ clone.style.removeProperty('clip-path');
1552
+ clone.removeAttribute('data-view-scale');
1553
+ Array.from(clone.querySelectorAll('[data-legend-bridge-runtime]')).forEach(function (element) { element.remove(); });
1554
+ return clone.outerHTML;
1555
+ }
1556
+ function fingerprintBytes(bytes) {
1557
+ var hash = 2166136261;
1558
+ for (var index = 0; index < bytes.length; index++) {
1559
+ hash ^= bytes[index];
1560
+ hash = Math.imul(hash, 16777619);
1561
+ }
1562
+ return (hash >>> 0).toString(16);
1563
+ }
1564
+ var liveBefore = stableLiveSnapshot();
1565
+ var captured = [];
1566
+ var downloads = [];
1567
+ var originalCreateObjectURL = URL.createObjectURL.bind(URL);
1568
+ var originalAnchorClick = HTMLAnchorElement.prototype.click;
1569
+ URL.createObjectURL = function (blob) {
1570
+ if (blob && blob.type && blob.type.indexOf('image/svg+xml') === 0) captured.push(blob.text());
1571
+ return originalCreateObjectURL(blob);
1572
+ };
1573
+ HTMLAnchorElement.prototype.click = function () { downloads.push(this.download); };
1574
+
1575
+ try {
1576
+ var blob = await Archify.exportMenu.shareCard({ variant: 'reach' });
1577
+ var reachSvgText = captured[0] ? await captured[0] : '';
1578
+ var downloadedBlob = await Archify.exportMenu.downloadReachShareCard();
1579
+ var reachReceipt = {
1580
+ format: document.documentElement.getAttribute('data-last-export-format'),
1581
+ variant: document.documentElement.getAttribute('data-last-export-variant'),
1582
+ width: document.documentElement.getAttribute('data-last-export-width'),
1583
+ height: document.documentElement.getAttribute('data-last-export-height'),
1584
+ canonical: document.documentElement.getAttribute('data-last-export-canonical'),
1585
+ routeStateClean: document.documentElement.getAttribute('data-last-export-route-state-clean'),
1586
+ reachStateClean: document.documentElement.getAttribute('data-last-export-reach-state-clean'),
1587
+ error: document.documentElement.getAttribute('data-last-export-error')
1588
+ };
1589
+
1590
+ var parser = new DOMParser();
1591
+ var reachSvg = parser.parseFromString(reachSvgText, 'image/svg+xml').documentElement;
1592
+ var matchedNodeIds = Array.from(reachSvg.querySelectorAll('[data-node-id][data-share-reach-match]')).map(function (node) {
1593
+ return node.getAttribute('data-node-id');
1594
+ });
1595
+ var matchedEdgeKeys = Array.from(new Set(Array.from(reachSvg.querySelectorAll('[data-edge-key][data-share-reach-match]')).map(function (edge) {
1596
+ return edge.getAttribute('data-edge-key');
1597
+ })));
1598
+ var reachNodeIds = Array.from(reachSvg.querySelectorAll('[data-node-id]')).map(function (node) {
1599
+ return node.getAttribute('data-node-id');
1600
+ }).sort();
1601
+ var liveNodeIds = Array.from(svg.querySelectorAll('[data-node-id]')).map(function (node) {
1602
+ return node.getAttribute('data-node-id');
1603
+ }).sort();
1604
+ var reachEdgeKeys = Array.from(new Set(Array.from(reachSvg.querySelectorAll('[data-edge-key]')).map(function (edge) {
1605
+ return edge.getAttribute('data-edge-key');
1606
+ }))).sort();
1607
+ var liveEdgeKeys = Array.from(new Set(Array.from(svg.querySelectorAll('[data-edge-key]')).map(function (edge) {
1608
+ return edge.getAttribute('data-edge-key');
1609
+ }))).sort();
1610
+ var reachStyles = Array.from(reachSvg.querySelectorAll('style')).map(function (style) { return style.textContent; }).join('\n');
1611
+
1612
+ await new Promise(function (resolve) {
1613
+ requestAnimationFrame(function () { requestAnimationFrame(resolve); });
1614
+ });
1615
+ var liveAfter = stableLiveSnapshot();
1616
+
1617
+ var matrix = [];
1618
+ if (${JSON.stringify(options.matrix === true)}) {
1619
+ var identity = JSON.stringify(snapshot);
1620
+ for (var preset of ['classic', 'signal-flow', 'blueprint', 'editorial']) {
1621
+ if (!Archify.preset.apply(preset)) throw new Error('could not apply preset ' + preset);
1622
+ for (var theme of ['dark', 'light']) {
1623
+ document.documentElement.setAttribute('data-theme', theme);
1624
+ var matrixBlob = await Archify.exportMenu.shareCard({ variant: 'reach' });
1625
+ var matrixBytes = new Uint8Array(await matrixBlob.arrayBuffer());
1626
+ var matrixView = new DataView(matrixBytes.buffer, matrixBytes.byteOffset, matrixBytes.byteLength);
1627
+ matrix.push({
1628
+ preset: preset,
1629
+ theme: theme,
1630
+ type: matrixBlob.type,
1631
+ size: matrixBlob.size,
1632
+ width: matrixView.getUint32(16),
1633
+ height: matrixView.getUint32(20),
1634
+ hash: fingerprintBytes(matrixBytes),
1635
+ identity: JSON.stringify(Archify.focus.reachabilitySnapshot())
1636
+ });
1637
+ }
1638
+ }
1639
+ if (matrix.some(function (entry) { return entry.identity !== identity; })) {
1640
+ throw new Error('visual matrix changed authored reach identity');
1641
+ }
1642
+ }
1643
+
1644
+ Archify.focus.clearReach({ updateUrl: false });
1645
+ Archify.exportMenu.syncReachShare();
1646
+ var hiddenAfterClear = reachMenuItem.hidden && reachMenuItem.disabled &&
1647
+ getComputedStyle(reachMenuItem).display === 'none';
1648
+ var staleError = '';
1649
+ try { await Archify.exportMenu.shareCard({ variant: 'reach' }); }
1650
+ catch (error) { staleError = String(error && error.message || error); }
1651
+ await Archify.exportMenu.downloadReachShareCard();
1652
+ var failedReceipt = {
1653
+ format: document.documentElement.getAttribute('data-last-export-format'),
1654
+ variant: document.documentElement.getAttribute('data-last-export-variant'),
1655
+ errorFormat: document.documentElement.getAttribute('data-last-export-error-format'),
1656
+ error: document.documentElement.getAttribute('data-last-export-error')
1657
+ };
1658
+ var canonicalIndex = captured.length;
1659
+ var canonicalBlob = await Archify.exportMenu.shareCard();
1660
+ var canonicalSvgText = captured[canonicalIndex] ? await captured[canonicalIndex] : '';
1661
+ var canonicalSvg = parser.parseFromString(canonicalSvgText, 'image/svg+xml').documentElement;
1662
+ var canonicalReachResidue = canonicalSvg.hasAttribute('data-share-reach') ||
1663
+ canonicalSvg.hasAttribute('data-reach-active') ||
1664
+ canonicalSvg.querySelectorAll('[data-share-reach-match], [data-share-reach-origin], [data-share-reach-depth], [data-reach-match], [data-reach-origin], [data-reach-depth]').length > 0;
1665
+
1666
+ var bytes = new Uint8Array(await blob.arrayBuffer());
1667
+ var binary = '';
1668
+ for (var offset = 0; offset < bytes.length; offset += 32768) {
1669
+ binary += String.fromCharCode.apply(null, bytes.subarray(offset, offset + 32768));
1670
+ }
1671
+ return {
1672
+ ok: true,
1673
+ type: blob.type,
1674
+ size: blob.size,
1675
+ base64: btoa(binary),
1676
+ snapshot: snapshot,
1677
+ matchedNodeIds: matchedNodeIds,
1678
+ matchedEdgeKeys: matchedEdgeKeys,
1679
+ expectedEdgeKeys: snapshot.edges.map(function (edge) { return edge.key; }),
1680
+ reachDirection: reachSvg.getAttribute('data-share-reach'),
1681
+ originCount: reachSvg.querySelectorAll('[data-node-id][data-share-reach-origin]').length,
1682
+ reachLiveResidue: reachSvg.hasAttribute('data-reach-active') || reachSvg.querySelectorAll('[data-reach-match], [data-reach-origin], [data-reach-depth]').length > 0,
1683
+ routeResidue: reachSvg.hasAttribute('data-share-route') || reachSvg.querySelectorAll('[data-share-route-match], [data-share-route-step], [data-route-match], [data-route-step]').length > 0,
1684
+ motionResidue: reachSvg.hasAttribute('data-animation') || reachSvg.querySelectorAll('[data-animate]').length > 0,
1685
+ blueprintStaticRule: /data-preset=\"blueprint\"\]\[data-share-reach\][^}]*filter:\s*none/.test(reachStyles),
1686
+ reachNodeIds: reachNodeIds,
1687
+ liveNodeIds: liveNodeIds,
1688
+ reachEdgeKeys: reachEdgeKeys,
1689
+ liveEdgeKeys: liveEdgeKeys,
1690
+ liveUnchanged: liveBefore === liveAfter,
1691
+ menuResolved: menuResolved,
1692
+ duplicateGeometryRejected: duplicateGeometryRejected,
1693
+ duplicateExportError: duplicateExportError,
1694
+ downloadStable: downloadedBlob && downloadedBlob.type === 'image/png',
1695
+ downloads: downloads,
1696
+ reachReceipt: reachReceipt,
1697
+ hiddenAfterClear: hiddenAfterClear,
1698
+ staleSnapshot: Archify.focus.reachabilitySnapshot(),
1699
+ staleError: staleError,
1700
+ failedReceipt: failedReceipt,
1701
+ canonicalSize: canonicalBlob.size,
1702
+ canonicalReachResidue: canonicalReachResidue,
1703
+ matrix: matrix
1704
+ };
1705
+ } finally {
1706
+ URL.createObjectURL = originalCreateObjectURL;
1707
+ HTMLAnchorElement.prototype.click = originalAnchorClick;
1708
+ }
1709
+ } catch (error) {
1710
+ return { ok: false, error: String(error && error.message || error) };
1711
+ }
1712
+ })()`, true), options.matrix ? 35_000 : 15_000, `${label} Reach Card export`);
1713
+
1714
+ assert.equal(reachPayload?.ok, true, reachPayload?.error || `${label} Reach Card export failed`);
1715
+ assert.equal(reachPayload.type, 'image/png');
1716
+ assert.ok(reachPayload.size > 20_000, `${label} Reach Card is unexpectedly small (${reachPayload.size} bytes)`);
1717
+ const png = Buffer.from(reachPayload.base64, 'base64');
1718
+ assert.equal(png.subarray(0, 8).toString('hex'), '89504e470d0a1a0a', `${label} Reach Card is not a PNG`);
1719
+ assert.equal(png.readUInt32BE(16), 1200, `${label} Reach Card width`);
1720
+ assert.equal(png.readUInt32BE(20), 630, `${label} Reach Card height`);
1721
+ if (options.outputPath) {
1722
+ fs.mkdirSync(path.dirname(options.outputPath), { recursive: true });
1723
+ fs.writeFileSync(options.outputPath, png);
1724
+ }
1725
+ assert.equal(reachPayload.reachDirection, direction);
1726
+ assert.deepEqual(reachPayload.matchedNodeIds.slice().sort(), reachPayload.snapshot.nodeIds.slice().sort());
1727
+ assert.deepEqual(reachPayload.matchedEdgeKeys.slice().sort(), reachPayload.expectedEdgeKeys.slice().sort());
1728
+ assert.equal(reachPayload.originCount, 1);
1729
+ assert.equal(reachPayload.reachLiveResidue, false);
1730
+ assert.equal(reachPayload.routeResidue, false);
1731
+ assert.equal(reachPayload.motionResidue, false);
1732
+ assert.equal(reachPayload.blueprintStaticRule, true);
1733
+ assert.deepEqual(reachPayload.reachNodeIds, reachPayload.liveNodeIds);
1734
+ assert.deepEqual(reachPayload.reachEdgeKeys, reachPayload.liveEdgeKeys);
1735
+ assert.equal(reachPayload.liveUnchanged, true);
1736
+ assert.equal(reachPayload.menuResolved, true);
1737
+ assert.equal(reachPayload.duplicateGeometryRejected, true);
1738
+ assert.match(reachPayload.duplicateExportError, /Trace authored reach before exporting a Reach Share Card/);
1739
+ assert.equal(reachPayload.downloadStable, true);
1740
+ assert.match(reachPayload.downloads[0], new RegExp(`-${direction}-reach-share-card\\.png$`));
1741
+ assert.deepEqual(reachPayload.reachReceipt, {
1742
+ format: 'share-card',
1743
+ variant: 'reach',
1744
+ width: '1200',
1745
+ height: '630',
1746
+ canonical: 'false',
1747
+ routeStateClean: null,
1748
+ reachStateClean: 'true',
1749
+ error: null,
1750
+ });
1751
+ assert.equal(reachPayload.hiddenAfterClear, true);
1752
+ assert.equal(reachPayload.staleSnapshot, null);
1753
+ assert.match(reachPayload.staleError, /Trace authored reach before exporting a Reach Share Card/);
1754
+ assert.equal(reachPayload.failedReceipt.format, null);
1755
+ assert.equal(reachPayload.failedReceipt.variant, null);
1756
+ assert.equal(reachPayload.failedReceipt.errorFormat, 'share-card');
1757
+ assert.match(reachPayload.failedReceipt.error, /Trace authored reach before exporting a Reach Share Card/);
1758
+ assert.ok(reachPayload.canonicalSize > 20_000);
1759
+ assert.equal(reachPayload.canonicalReachResidue, false);
1760
+ if (options.matrix) {
1761
+ assert.equal(reachPayload.matrix.length, 8);
1762
+ assert.equal(new Set(reachPayload.matrix.map((entry) => entry.hash)).size, 8, `${label} Reach presets/themes should produce eight distinct PNGs`);
1763
+ for (const entry of reachPayload.matrix) {
1764
+ assert.equal(entry.type, 'image/png');
1765
+ assert.equal(entry.width, 1200);
1766
+ assert.equal(entry.height, 630);
1767
+ assert.ok(entry.size > 20_000);
1768
+ }
1769
+ }
1770
+ console.log(`ok ${label} Reach Card: ${reachPayload.size} bytes, ${reachPayload.snapshot.nodeIds.length} nodes, ${reachPayload.snapshot.edges.length} authored links`);
1771
+ }
1772
+
1773
+ await verifyResolvedLegendContract(legendOutputs);
1774
+ await verifySemanticPassportDismissal(path.resolve(skillRoot, '../docs/gallery/artifacts/production-deployment.architecture.html'));
1775
+ await verifyArchitectureDeltaNavigator(path.resolve(skillRoot, '../examples/checkout-platform-delta.html'));
1776
+ await captureShareCard(output, 'architecture-wide');
1777
+ await captureShareCard(sequenceOutput, 'sequence-tall');
1778
+ await captureCopiedShareCard(output, 'architecture-wide');
1779
+ await captureRouteShareCard(routeOutputs.architecture, 'architecture-route', 'users', 'api', { journeyInvariance: true });
1780
+ await captureRouteShareCard(routeOutputs.workflow, 'workflow-route', 'user', 'approval');
1781
+ await captureRouteShareCard(routeOutputs.sequence, 'sequence-route', 'web', 'db');
1782
+ await captureRouteShareCard(routeOutputs.dataflow, 'dataflow-route', 'web', 'dashboard');
1783
+ await captureRouteShareCard(routeOutputs.lifecycle, 'lifecycle-route', 'executing', 'cancelled');
1784
+ await captureRouteShareCard(parallelOutput, 'parallel-route', 'users', 'cdn');
1785
+ await captureRouteShareCard(specialRouteOutput, 'special-10-hop-route', 'Route_Source-01', 'Route_Target-10', {
1786
+ expectedHops: 10,
1787
+ expectedSourceLabel: specialSourceLabel,
1788
+ expectedTargetLabel: specialTargetLabel,
1789
+ });
1790
+ await captureRouteVisualMatrix(routeOutputs.architecture, 'architecture-route', 'users', 'api');
1791
+ await captureRouteVisualMatrix(routeOutputs.sequence, 'sequence-route', 'web', 'db');
1792
+ await captureReachShareCard(routeOutputs.architecture, 'architecture-reach', 'users', 'downstream', { matrix: true });
1793
+ await captureReachShareCard(routeOutputs.workflow, 'workflow-reach', 'user', 'downstream');
1794
+ await captureReachShareCard(routeOutputs.sequence, 'sequence-reach', 'web', 'downstream');
1795
+ await captureReachShareCard(routeOutputs.dataflow, 'dataflow-reach', 'web', 'downstream');
1796
+ await captureReachShareCard(routeOutputs.lifecycle, 'lifecycle-reach', 'executing', 'downstream');
1797
+ if (externalReachSource) {
1798
+ assert.ok(fs.existsSync(externalReachSource), `external Reach Card source does not exist: ${externalReachSource}`);
1799
+ await captureReachShareCard(
1800
+ externalReachSource,
1801
+ 'external-reach',
1802
+ process.env.ARCHIFY_REACH_CARD_ORIGIN || 'router',
1803
+ process.env.ARCHIFY_REACH_CARD_DIRECTION || 'downstream',
1804
+ { outputPath: externalReachOutput },
1805
+ );
1806
+ console.log(`ok external Reach Card artifact: ${externalReachOutput}`);
1807
+ }
1808
+ await verifyDynamicReducedMotionRoute(routeOutputs.architecture, 'architecture-route reduced motion', 'users', 'api');
1809
+ await navigateReady(output, '!!(window.Archify && Archify.motion && Archify.motion.canRecord())', 'motion artifact');
1810
+
1811
+ const payload = await withTimeout(evaluate(cdp, sessionId, String.raw`(async function () {
1812
+ try {
1813
+ var blob = await Archify.motion.recordWebm({ duration: 1400, fps: 12 });
1814
+ var bytes = new Uint8Array(await blob.arrayBuffer());
1815
+ var binary = '';
1816
+ for (var offset = 0; offset < bytes.length; offset += 32768) {
1817
+ binary += String.fromCharCode.apply(null, bytes.subarray(offset, offset + 32768));
1818
+ }
1819
+ return { ok: true, type: blob.type, size: blob.size, base64: btoa(binary) };
1820
+ } catch (error) {
1821
+ return { ok: false, error: String(error && error.message || error) };
1822
+ }
1823
+ })()`, true), 20_000, 'WebM recording');
1824
+ assert.equal(payload?.ok, true, payload?.error || 'WebM recording failed');
1825
+ assert.match(payload.type, /^video\/webm/);
1826
+ assert.ok(payload.size > 10_000, `WebM is unexpectedly small (${payload.size} bytes)`);
1827
+
1828
+ const webm = path.join(tmp, 'motion.webm');
1829
+ fs.writeFileSync(webm, Buffer.from(payload.base64, 'base64'));
1830
+ const frameMd5 = execFileSync(ffmpeg, [
1831
+ '-v', 'error',
1832
+ '-i', webm,
1833
+ '-vf', 'fps=6,scale=320:-2',
1834
+ '-f', 'framemd5',
1835
+ '-',
1836
+ ], { encoding: 'utf8', maxBuffer: 4 * 1024 * 1024 });
1837
+ const hashes = frameMd5
1838
+ .split('\n')
1839
+ .filter((line) => line && !line.startsWith('#'))
1840
+ .map((line) => line.split(',').at(-1).trim());
1841
+ const uniqueFrames = new Set(hashes);
1842
+
1843
+ assert.ok(hashes.length >= 4, `decoded only ${hashes.length} WebM frames`);
1844
+ assert.ok(uniqueFrames.size >= 2, 'decoded WebM frames are static');
1845
+ console.log(`ok WebM artifact: ${payload.size} bytes, ${hashes.length} sampled frames, ${uniqueFrames.size} unique`);
1846
+ } finally {
1847
+ if (cdp && targetId) await withTimeout(cdp.send('Target.closeTarget', { targetId }), 500, 'target close').catch(() => {});
1848
+ if (cdp) cdp.socket.close();
1849
+ chromeProcess.kill('SIGTERM');
1850
+ if (!(await waitForExit(chromeProcess, 1000))) {
1851
+ chromeProcess.kill('SIGKILL');
1852
+ await waitForExit(chromeProcess, 1000);
1853
+ }
1854
+ await removeTempTree(tmp);
1855
+ }