@cardstack/boxel-cli 0.11.0-unstable.1 → 0.11.0-unstable.2

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 (82) hide show
  1. package/bundled-test-harness/assets/{app-QAuw0l8v.js → app-CtezUCip.js} +1 -1
  2. package/bundled-test-harness/assets/choreo-BEHW-NOc.js +2 -0
  3. package/bundled-test-harness/assets/{choreo-CJfBb_EY.js → choreo-C2cpCfhA.js} +164 -13
  4. package/bundled-test-harness/assets/{choreo-feature-reel-test-D2OrygZv.js → choreo-feature-reel-test-CPI_6nkT.js} +2 -2
  5. package/bundled-test-harness/assets/{choreo-gallery-w07xqtO-.js → choreo-gallery-BxA9cyzF.js} +3 -3
  6. package/bundled-test-harness/assets/{choreo-gallery-build-order-test-yQg4JER6.js → choreo-gallery-build-order-test-CLVoseAJ.js} +1 -1
  7. package/bundled-test-harness/assets/{choreo-gallery-compositor-test-C2THCXJN.js → choreo-gallery-compositor-test-BpT5Ia6B.js} +1 -1
  8. package/bundled-test-harness/assets/{choreo-gallery-cover-test-D4T_Tk4s.js → choreo-gallery-cover-test-DL_fdSsh.js} +1 -1
  9. package/bundled-test-harness/assets/{choreo-gallery-crossing-stage-test-tHUPJ-Hy.js → choreo-gallery-crossing-stage-test-BcKHhpOK.js} +2 -2
  10. package/bundled-test-harness/assets/{choreo-gallery-demos-alive-test-BOtBOnEZ.js → choreo-gallery-demos-alive-test-KufLhXG8.js} +1 -1
  11. package/bundled-test-harness/assets/{choreo-gallery-drift-test-D_6U1Z2c.js → choreo-gallery-drift-test-Cx58rYIA.js} +1 -1
  12. package/bundled-test-harness/assets/{choreo-gallery-escort-test-DDBU0n4C.js → choreo-gallery-escort-test-Wz-emmID.js} +1 -1
  13. package/bundled-test-harness/assets/{choreo-gallery-films-test-CgW1NSdr.js → choreo-gallery-films-test-BFrVs5WW.js} +2 -2
  14. package/bundled-test-harness/assets/{choreo-gallery-filter-test-DUIsNwdO.js → choreo-gallery-filter-test-DCKQkhwe.js} +1 -1
  15. package/bundled-test-harness/assets/{choreo-gallery-fold-test-Chzlxvdr.js → choreo-gallery-fold-test-UtpDgpG9.js} +1 -1
  16. package/bundled-test-harness/assets/{choreo-gallery-guide-pages-test-DOWnqALT.js → choreo-gallery-guide-pages-test-rXDU9JLM.js} +1 -1
  17. package/bundled-test-harness/assets/{choreo-gallery-guides-test-Dra2J4LJ.js → choreo-gallery-guides-test-DfVFdIuU.js} +3 -3
  18. package/bundled-test-harness/assets/{choreo-gallery-hang-test-zzn1eiB-.js → choreo-gallery-hang-test-Cj7MbkFf.js} +1 -1
  19. package/bundled-test-harness/assets/{choreo-gallery-highlight-test-CW99hncQ.js → choreo-gallery-highlight-test-D6CF3IYZ.js} +2 -2
  20. package/bundled-test-harness/assets/{choreo-gallery-inline-edit-test-CYFm1kUz.js → choreo-gallery-inline-edit-test-LfHWsbqc.js} +1 -1
  21. package/bundled-test-harness/assets/{choreo-gallery-interruption-test-CYIBrKV9.js → choreo-gallery-interruption-test-CvQQAgTp.js} +2 -2
  22. package/bundled-test-harness/assets/{choreo-gallery-lone-stack-test-DL8R3SG7.js → choreo-gallery-lone-stack-test-D7Zci7fm.js} +1 -1
  23. package/bundled-test-harness/assets/{choreo-gallery-navigation-test-Dcv04kDx.js → choreo-gallery-navigation-test-DB1EnBEW.js} +1 -1
  24. package/bundled-test-harness/assets/{choreo-gallery-playhead-transport-test-Cfz7GsXl.js → choreo-gallery-playhead-transport-test-CtBlc6AJ.js} +1 -1
  25. package/bundled-test-harness/assets/{choreo-gallery-poplayout-subtree-test-CwoklBkW.js → choreo-gallery-poplayout-subtree-test-BQbmjsvI.js} +1 -1
  26. package/bundled-test-harness/assets/{choreo-gallery-presence-modes-test-BDCIZzJ0.js → choreo-gallery-presence-modes-test-CIdXVG1K.js} +1 -1
  27. package/bundled-test-harness/assets/{choreo-gallery-presentation-test-DlyiHwFf.js → choreo-gallery-presentation-test-C_rPFp29.js} +1 -1
  28. package/bundled-test-harness/assets/{choreo-gallery-reduced-motion-test-DVz5SKNR.js → choreo-gallery-reduced-motion-test-CH5w8Lw-.js} +2 -2
  29. package/bundled-test-harness/assets/{choreo-gallery-sheet-standalone-test-CpD_-BvS.js → choreo-gallery-sheet-standalone-test-CDgI4mGX.js} +1 -1
  30. package/bundled-test-harness/assets/{choreo-gallery-sheet-test-BjvAKHDL.js → choreo-gallery-sheet-test-5lsFX7Rk.js} +1 -1
  31. package/bundled-test-harness/assets/{choreo-gallery-site-test-oq_7y_PN.js → choreo-gallery-site-test-DbMa2xeC.js} +2 -2
  32. package/bundled-test-harness/assets/{choreo-gallery-stage-Bzr4_8Xd.js → choreo-gallery-stage-b3Sk86hp.js} +2 -2
  33. package/bundled-test-harness/assets/{choreo-gallery-stage-keyboard-test-a83d2euJ.js → choreo-gallery-stage-keyboard-test-ds6fT5Eg.js} +1 -1
  34. package/bundled-test-harness/assets/{choreo-gallery-stages-test-C9Sl1kH6.js → choreo-gallery-stages-test-ahioKCct.js} +2 -2
  35. package/bundled-test-harness/assets/{choreo-gallery-subdivision-test-BVVnkOwk.js → choreo-gallery-subdivision-test-g7anTDhT.js} +1 -1
  36. package/bundled-test-harness/assets/{choreo-gallery-table-plan-test-B0YdYEA0.js → choreo-gallery-table-plan-test-Bozc4uUf.js} +1 -1
  37. package/bundled-test-harness/assets/{choreo-gallery-theater-test-BLA147xw.js → choreo-gallery-theater-test-kE535d-b.js} +3 -3
  38. package/bundled-test-harness/assets/{choreo-gallery-tuning-test-DSXiNzCh.js → choreo-gallery-tuning-test-6rHkQBnZ.js} +1 -1
  39. package/bundled-test-harness/assets/{choreo-gallery-widget-room-test-BI574PdO.js → choreo-gallery-widget-room-test-0Vq-uTo1.js} +2 -2
  40. package/bundled-test-harness/assets/{choreo-gallery-wires-test-B6Mz2WZl.js → choreo-gallery-wires-test-CdtnAWYO.js} +1 -1
  41. package/bundled-test-harness/assets/clip-BLfuHi8g.js +2 -0
  42. package/bundled-test-harness/assets/{clip-C_pXjVvY.js → clip-q1QE5f73.js} +1 -1
  43. package/bundled-test-harness/assets/{externals-6ZWftYIb.js → externals-DCnB4XSS.js} +11 -11
  44. package/bundled-test-harness/assets/film-B68PjRlr.js +2 -0
  45. package/bundled-test-harness/assets/{film-D7vtJO5q.js → film-CeUpnHN_.js} +6 -6
  46. package/bundled-test-harness/assets/{film-DN0A8JHx.js → film-DBZqyqW4.js} +6 -6
  47. package/bundled-test-harness/assets/{glimmer-motion-and-choreo-in-cards-test-BHte2t9G.js → glimmer-motion-and-choreo-in-cards-test-HA-INN3d.js} +14 -14
  48. package/bundled-test-harness/assets/{glimmer-motion-and-choreo-test-BPNVeIio.js → glimmer-motion-and-choreo-test-BZ0ZuuAw.js} +3 -3
  49. package/bundled-test-harness/assets/{index-query-engine-test-Dz7Q4Xmk.js → index-query-engine-test-CY2tAkot.js} +1 -1
  50. package/bundled-test-harness/assets/{instance-filter-matcher-test-BoLU3bVg.js → instance-filter-matcher-test-CMBTh8xn.js} +1 -1
  51. package/bundled-test-harness/assets/{main-Dlgp8c7v.js → main-BOZbZVem.js} +1 -1
  52. package/bundled-test-harness/assets/{operation-lowering-test-B0KpI1xu.js → operation-lowering-test-CHnjKSJb.js} +1 -1
  53. package/bundled-test-harness/assets/{overlays-BnOM360u.js → overlays-BOzLbVDK.js} +1 -1
  54. package/bundled-test-harness/assets/{overlays-kBVfa4i8.js → overlays-C_PuGDGh.js} +1 -1
  55. package/bundled-test-harness/assets/{plate-CFvCDv2t.js → plate-BL7UtyKE.js} +1 -1
  56. package/bundled-test-harness/assets/plate-CqG3igCJ.js +2 -0
  57. package/bundled-test-harness/assets/player-BJfsgdSI.js +2 -0
  58. package/bundled-test-harness/assets/{player-DzuYjrTU.js → player-Da_CIsp_.js} +1 -1
  59. package/bundled-test-harness/assets/{run-BMyvn_UL.js → run-D4n4LPcK.js} +96 -6
  60. package/bundled-test-harness/assets/{searchable-option-test-BBr5BPow.js → searchable-option-test-Ctf8r3HZ.js} +1 -1
  61. package/bundled-test-harness/assets/{src-Df148w_b.js → src-B_DEhPze.js} +4 -4
  62. package/bundled-test-harness/assets/{src-Cf2wv-Le.js → src-BoTgwqUA.js} +2 -2
  63. package/bundled-test-harness/assets/{test-support-rNHuieEc.js → test-support-FXDPpIl3.js} +1 -1
  64. package/bundled-test-harness/assets/{test-support-C6N_2X-l.js → test-support-VX6ukQNR.js} +1 -1
  65. package/bundled-test-harness/assets/{tests-CmsQ-Z_3.js → tests-DoTEpvcF.js} +43 -43
  66. package/bundled-test-harness/assets/{titles-B1pTaIfP.js → titles-DFJj5O0E.js} +1 -1
  67. package/bundled-test-harness/assets/titles-xGlgu7ys.js +2 -0
  68. package/bundled-test-harness/index.html +4 -4
  69. package/bundled-test-harness/tests/index.html +4 -4
  70. package/bundled-types/choreo/beacons.ts +16 -4
  71. package/bundled-types/choreo/changeset.ts +25 -5
  72. package/bundled-types/choreo/choreo.gts +245 -3
  73. package/bundled-types/choreo/far.ts +39 -0
  74. package/bundled-types/choreo/index.ts +2 -0
  75. package/bundled-types/choreo/run.ts +104 -1
  76. package/package.json +1 -1
  77. package/bundled-test-harness/assets/choreo-B3Z9QhDH.js +0 -2
  78. package/bundled-test-harness/assets/clip-BjcXuTwN.js +0 -2
  79. package/bundled-test-harness/assets/film-DMDPP7ma.js +0 -2
  80. package/bundled-test-harness/assets/plate-66qnQ-M9.js +0 -2
  81. package/bundled-test-harness/assets/player-pygg1PwA.js +0 -2
  82. package/bundled-test-harness/assets/titles-Ccpcl-jq.js +0 -2
@@ -6,7 +6,7 @@ import { t as Component } from "./dist-CkA1rgqO.js";
6
6
  import "./template-factory-ds9s0u8l.js";
7
7
  import "./src-Ds_gxjJo.js";
8
8
  import { t as MotionModifier } from "./motion-BNbXVpox.js";
9
- import { t as Choreo } from "./choreo-CJfBb_EY.js";
9
+ import { t as Choreo } from "./choreo-C2cpCfhA.js";
10
10
  //#region ../choreo/src/film/titles.gts
11
11
  /**
12
12
  * THE GATE — the front door. The film is narrated, so the door asks; and
@@ -0,0 +1,2 @@
1
+ import { n as Gate, t as EndCard } from "./titles-DFJj5O0E.js";
2
+ export { EndCard, Gate };
@@ -12,7 +12,7 @@
12
12
  boxelComponentL3, boxelComponentL4;
13
13
  </style>
14
14
 
15
- <meta name="@cardstack/host/config/environment" content="%7B%22modulePrefix%22%3A%22%40cardstack%2Fhost%22%2C%22environment%22%3A%22development%22%2C%22hostedEnvironment%22%3A%22local%22%2C%22rootURL%22%3A%22%2F%22%2C%22locationType%22%3A%22history%22%2C%22EmberENV%22%3A%7B%22EXTEND_PROTOTYPES%22%3Afalse%2C%22FEATURES%22%3A%7B%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_DEFAULT_ASYNC_OBSERVERS%22%3Atrue%2C%22_JQUERY_INTEGRATION%22%3Afalse%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%220.0.0%2Bb968411e%22%7D%2C%22ember-cli-mirage%22%3A%7B%22enabled%22%3Afalse%7D%2C%22logLevels%22%3A%22*%3Dinfo%2Cmatrix%3Dinfo%2Crealm%3Aevents%3Ddebug%22%2C%22matrixURL%22%3A%22http%3A%2F%2Flocalhost%3A8008%22%2C%22matrixServerName%22%3A%22localhost%22%2C%22autoSaveDelayMs%22%3A500%2C%22autoSaveQuietPeriodMs%22%3A1500%2C%22autoSaveMaxWaitMs%22%3A10000%2C%22monacoDebounceMs%22%3A500%2C%22monacoCursorDebounceMs%22%3A200%2C%22loginMessageTimeoutMs%22%3A1000%2C%22minSaveTaskDurationMs%22%3A1000%2C%22cardRenderTimeout%22%3A30000%2C%22cardSizeLimitBytes%22%3A524288%2C%22fileSizeLimitBytes%22%3A5242880%2C%22audioSizeLimitBytes%22%3A20971520%2C%22videoSizeLimitBytes%22%3A52428800%2C%22iconsURL%22%3A%22http%3A%2F%2Flocalhost%3A4206%22%2C%22secureOriginURL%22%3A%22https%3A%2F%2Flocalhost%3A4208%2Fsecure%22%2C%22signInOnSecureOrigin%22%3Afalse%2C%22publishedRealmBoxelSpaceDomain%22%3A%22localhost%3A4201%22%2C%22publishedRealmBoxelSiteDomain%22%3A%22localhost%3A4201%22%2C%22hostsOwnAssets%22%3Atrue%2C%22hostRoutingMap%22%3A%5B%5D%2C%22realmServerURL%22%3A%22https%3A%2F%2Flocalhost%3A4201%2F%22%2C%22resolvedBaseRealmURL%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fbase%2F%22%2C%22resolvedCatalogRealmURL%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fcatalog%2F%22%2C%22resolvedSkillsRealmURL%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fskills%2F%22%2C%22resolvedOpenRouterRealmURL%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fopenrouter%2F%22%2C%22resolvedPretuiRealmURL%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fpretui%2F%22%2C%22resolvedTestRealmURL%22%3A%22https%3A%2F%2Flocalhost%3A4202%2Ftest%2F%22%2C%22featureFlags%22%3A%7B%22DASHBOARD_V2%22%3Afalse%7D%2C%22prefixRealmURLs%22%3A%7B%22%40cardstack%2Fbase%2F%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fbase%2F%22%2C%22%40cardstack%2Fcatalog%2F%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fcatalog%2F%22%2C%22%40cardstack%2Fskills%2F%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fskills%2F%22%2C%22%40cardstack%2Fopenrouter%2F%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fopenrouter%2F%22%2C%22%40cardstack%2Fpretui%2F%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fpretui%2F%22%7D%2C%22defaultSystemCardId%22%3A%22%40cardstack%2Fcatalog%2FSystemCard%2Fdefault%22%2C%22defaultFieldSpecId%22%3A%22%40cardstack%2Fcatalog%2FSpec%2Ffields%2Ffield%22%7D">
15
+ <meta name="@cardstack/host/config/environment" content="%7B%22modulePrefix%22%3A%22%40cardstack%2Fhost%22%2C%22environment%22%3A%22development%22%2C%22hostedEnvironment%22%3A%22local%22%2C%22rootURL%22%3A%22%2F%22%2C%22locationType%22%3A%22history%22%2C%22EmberENV%22%3A%7B%22EXTEND_PROTOTYPES%22%3Afalse%2C%22FEATURES%22%3A%7B%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_DEFAULT_ASYNC_OBSERVERS%22%3Atrue%2C%22_JQUERY_INTEGRATION%22%3Afalse%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%220.0.0%2B5ac6897d%22%7D%2C%22ember-cli-mirage%22%3A%7B%22enabled%22%3Afalse%7D%2C%22logLevels%22%3A%22*%3Dinfo%2Cmatrix%3Dinfo%2Crealm%3Aevents%3Ddebug%22%2C%22matrixURL%22%3A%22http%3A%2F%2Flocalhost%3A8008%22%2C%22matrixServerName%22%3A%22localhost%22%2C%22autoSaveDelayMs%22%3A500%2C%22autoSaveQuietPeriodMs%22%3A1500%2C%22autoSaveMaxWaitMs%22%3A10000%2C%22monacoDebounceMs%22%3A500%2C%22monacoCursorDebounceMs%22%3A200%2C%22loginMessageTimeoutMs%22%3A1000%2C%22minSaveTaskDurationMs%22%3A1000%2C%22cardRenderTimeout%22%3A30000%2C%22cardSizeLimitBytes%22%3A524288%2C%22fileSizeLimitBytes%22%3A5242880%2C%22audioSizeLimitBytes%22%3A20971520%2C%22videoSizeLimitBytes%22%3A52428800%2C%22iconsURL%22%3A%22http%3A%2F%2Flocalhost%3A4206%22%2C%22secureOriginURL%22%3A%22https%3A%2F%2Flocalhost%3A4208%2Fsecure%22%2C%22signInOnSecureOrigin%22%3Afalse%2C%22publishedRealmBoxelSpaceDomain%22%3A%22localhost%3A4201%22%2C%22publishedRealmBoxelSiteDomain%22%3A%22localhost%3A4201%22%2C%22hostsOwnAssets%22%3Atrue%2C%22hostRoutingMap%22%3A%5B%5D%2C%22realmServerURL%22%3A%22https%3A%2F%2Flocalhost%3A4201%2F%22%2C%22resolvedBaseRealmURL%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fbase%2F%22%2C%22resolvedCatalogRealmURL%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fcatalog%2F%22%2C%22resolvedSkillsRealmURL%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fskills%2F%22%2C%22resolvedOpenRouterRealmURL%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fopenrouter%2F%22%2C%22resolvedPretuiRealmURL%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fpretui%2F%22%2C%22resolvedTestRealmURL%22%3A%22https%3A%2F%2Flocalhost%3A4202%2Ftest%2F%22%2C%22featureFlags%22%3A%7B%22DASHBOARD_V2%22%3Afalse%7D%2C%22prefixRealmURLs%22%3A%7B%22%40cardstack%2Fbase%2F%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fbase%2F%22%2C%22%40cardstack%2Fcatalog%2F%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fcatalog%2F%22%2C%22%40cardstack%2Fskills%2F%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fskills%2F%22%2C%22%40cardstack%2Fopenrouter%2F%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fopenrouter%2F%22%2C%22%40cardstack%2Fpretui%2F%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fpretui%2F%22%7D%2C%22defaultSystemCardId%22%3A%22%40cardstack%2Fcatalog%2FSystemCard%2Fdefault%22%2C%22defaultFieldSpecId%22%3A%22%40cardstack%2Fcatalog%2FSpec%2Ffields%2Ffield%22%7D">
16
16
 
17
17
  <script>
18
18
  // Resolve dynamic-import chunk URLs against the host's distURL rather
@@ -121,7 +121,7 @@
121
121
  <meta data-boxel-head-start="">
122
122
  <title>Boxel</title>
123
123
  <meta data-boxel-head-end="">
124
- <script type="module" crossorigin="" src="/assets/main-Dlgp8c7v.js"></script>
124
+ <script type="module" crossorigin="" src="/assets/main-BOZbZVem.js"></script>
125
125
  <link rel="modulepreload" crossorigin="" href="/assets/chunk-Rp0pCe6z.js">
126
126
  <link rel="modulepreload" crossorigin="" href="/assets/preload-helper-CKDH5-7N.js">
127
127
  <link rel="modulepreload" crossorigin="" href="/assets/index-esm-CUymiD6S.js">
@@ -322,7 +322,7 @@
322
322
  <link rel="modulepreload" crossorigin="" href="/assets/validate-realm-DFzizApj.js">
323
323
  <link rel="modulepreload" crossorigin="" href="/assets/view-visually-C3PpJSI2.js">
324
324
  <link rel="modulepreload" crossorigin="" href="/assets/tools-DU8Rc15s.js">
325
- <link rel="modulepreload" crossorigin="" href="/assets/externals-6ZWftYIb.js">
325
+ <link rel="modulepreload" crossorigin="" href="/assets/externals-DCnB4XSS.js">
326
326
  <link rel="modulepreload" crossorigin="" href="/assets/render-service-DeDLQrOD.js">
327
327
  <link rel="modulepreload" crossorigin="" href="/assets/buffer-DQZcL7h7.js">
328
328
  <link rel="modulepreload" crossorigin="" href="/assets/perform-g9ba6YNZ.js">
@@ -440,7 +440,7 @@
440
440
  <link rel="modulepreload" crossorigin="" href="/assets/card-service-BZPDxaaw.js">
441
441
  <link rel="modulepreload" crossorigin="" href="/assets/host-mode-service-CV8pBhBq.js">
442
442
  <link rel="modulepreload" crossorigin="" href="/assets/render-diagnostics-CztktD_I.js">
443
- <link rel="modulepreload" crossorigin="" href="/assets/app-QAuw0l8v.js">
443
+ <link rel="modulepreload" crossorigin="" href="/assets/app-CtezUCip.js">
444
444
  <link rel="stylesheet" crossorigin="" href="/assets/components-xAPF0vFU.css">
445
445
  <link rel="stylesheet" crossorigin="" href="/assets/signed-capture-BzA7ETjL.css">
446
446
  <link rel="stylesheet" crossorigin="" href="/assets/submode-switcher-eD-kKcpB.css">
@@ -13,12 +13,12 @@
13
13
  boxelComponentL3, boxelComponentL4;
14
14
  </style>
15
15
 
16
- <meta name="@cardstack/host/config/environment" content="%7B%22modulePrefix%22%3A%22%40cardstack%2Fhost%22%2C%22environment%22%3A%22test%22%2C%22hostedEnvironment%22%3A%22local%22%2C%22rootURL%22%3A%22%2F%22%2C%22locationType%22%3A%22none%22%2C%22EmberENV%22%3A%7B%22EXTEND_PROTOTYPES%22%3Afalse%2C%22FEATURES%22%3A%7B%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_DEFAULT_ASYNC_OBSERVERS%22%3Atrue%2C%22_JQUERY_INTEGRATION%22%3Afalse%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%220.0.0%2Bb968411e%22%2C%22LOG_ACTIVE_GENERATION%22%3Afalse%2C%22LOG_VIEW_LOOKUPS%22%3Afalse%2C%22rootElement%22%3A%22%23ember-testing%22%2C%22autoboot%22%3Afalse%7D%2C%22ember-cli-mirage%22%3A%7B%22enabled%22%3Afalse%7D%2C%22logLevels%22%3A%22*%3Dinfo%2Cmatrix%3Dinfo%2Crealm%3Aevents%3Ddebug%22%2C%22matrixURL%22%3A%22http%3A%2F%2Flocalhost%3A8008%22%2C%22matrixServerName%22%3A%22localhost%22%2C%22autoSaveDelayMs%22%3A0%2C%22autoSaveQuietPeriodMs%22%3A0%2C%22autoSaveMaxWaitMs%22%3A10000%2C%22monacoDebounceMs%22%3A0%2C%22monacoCursorDebounceMs%22%3A0%2C%22loginMessageTimeoutMs%22%3A0%2C%22minSaveTaskDurationMs%22%3A0%2C%22cardRenderTimeout%22%3A30000%2C%22cardSizeLimitBytes%22%3A524288%2C%22fileSizeLimitBytes%22%3A5242880%2C%22audioSizeLimitBytes%22%3A20971520%2C%22videoSizeLimitBytes%22%3A52428800%2C%22iconsURL%22%3A%22http%3A%2F%2Flocalhost%3A4206%22%2C%22secureOriginURL%22%3A%22https%3A%2F%2Flocalhost%3A4208%2Fsecure%22%2C%22signInOnSecureOrigin%22%3Afalse%2C%22publishedRealmBoxelSpaceDomain%22%3A%22localhost%3A4201%22%2C%22publishedRealmBoxelSiteDomain%22%3A%22localhost%3A4201%22%2C%22hostsOwnAssets%22%3Atrue%2C%22hostRoutingMap%22%3A%5B%5D%2C%22realmServerURL%22%3A%22http%3A%2F%2Ftest-realm%22%2C%22resolvedBaseRealmURL%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fbase%2F%22%2C%22resolvedSkillsRealmURL%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fskills%2F%22%2C%22resolvedPretuiRealmURL%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fpretui%2F%22%2C%22resolvedTestRealmURL%22%3A%22https%3A%2F%2Flocalhost%3A4202%2Ftest%2F%22%2C%22featureFlags%22%3A%7B%7D%2C%22prefixRealmURLs%22%3A%7B%22%40cardstack%2Fbase%2F%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fbase%2F%22%2C%22%40cardstack%2Fcatalog%2F%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fcatalog%2F%22%2C%22%40cardstack%2Fskills%2F%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fskills%2F%22%2C%22%40cardstack%2Fopenrouter%2F%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fopenrouter%2F%22%2C%22%40cardstack%2Fpretui%2F%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fpretui%2F%22%7D%2C%22sqlSchema%22%3A%22--%20This%20is%20auto-generated%20by%20packages%2Frealm-server%2Fscripts%2Fconvert-to-sqlite.ts%5Cn--%20Please%20don't%20directly%20modify%20this%20file%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20anonymous_grant_rate_limits%20(%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20grant_id%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20client_ip%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20window_start%20NOT%20NULL%2C%5Cn%20%20%20window_seconds%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20count%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20expires_at%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%2C%20grant_id%2C%20client_ip%2C%20window_start%2C%20window_seconds%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20bot_commands%20(%5Cn%20%20%20id%20NOT%20NULL%2C%5Cn%20%20%20bot_id%20NOT%20NULL%2C%5Cn%20%20%20command%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20command_filter%20BLOB%20NOT%20NULL%2C%5Cn%20%20%20created_at%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20id%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20bot_registrations%20(%5Cn%20%20%20id%20NOT%20NULL%2C%5Cn%20%20%20username%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20created_at%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20id%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20boxel_index%20(%5Cn%20%20%20url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20file_alias%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20type%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20generation%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20pristine_doc%20BLOB%2C%5Cn%20%20%20search_doc%20BLOB%2C%5Cn%20%20%20error_doc%20BLOB%2C%5Cn%20%20%20deps%20BLOB%20DEFAULT%20'%5B%5D'%2C%5Cn%20%20%20types%20BLOB%2C%5Cn%20%20%20indexed_at%2C%5Cn%20%20%20is_deleted%20BOOLEAN%2C%5Cn%20%20%20last_modified%2C%5Cn%20%20%20display_names%20BLOB%2C%5Cn%20%20%20resource_created_at%2C%5Cn%20%20%20icon_html%20TEXT%2C%5Cn%20%20%20has_error%20BOOLEAN%20DEFAULT%20false%20NOT%20NULL%2C%5Cn%20%20%20last_known_good_deps%20BLOB%2C%5Cn%20%20%20diagnostics%20BLOB%2C%5Cn%20%20%20host_shell_generation%20INTEGER%2C%5Cn%20%20%20source_content_hash%20TEXT%2C%5Cn%20%20%20relationship_deps%20BLOB%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20url%2C%20realm_url%2C%20type%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20boxel_index_pending%20(%5Cn%20%20%20url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20file_alias%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20type%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20generation%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20pristine_doc%20BLOB%2C%5Cn%20%20%20search_doc%20BLOB%2C%5Cn%20%20%20error_doc%20BLOB%2C%5Cn%20%20%20deps%20BLOB%20DEFAULT%20'%5B%5D'%2C%5Cn%20%20%20types%20BLOB%2C%5Cn%20%20%20indexed_at%2C%5Cn%20%20%20is_deleted%20BOOLEAN%2C%5Cn%20%20%20last_modified%2C%5Cn%20%20%20display_names%20BLOB%2C%5Cn%20%20%20resource_created_at%2C%5Cn%20%20%20icon_html%20TEXT%2C%5Cn%20%20%20has_error%20BOOLEAN%20DEFAULT%20false%20NOT%20NULL%2C%5Cn%20%20%20last_known_good_deps%20BLOB%2C%5Cn%20%20%20diagnostics%20BLOB%2C%5Cn%20%20%20host_shell_generation%20INTEGER%2C%5Cn%20%20%20source_content_hash%20TEXT%2C%5Cn%20%20%20job_id%20INTEGER%2C%5Cn%20%20%20staging_id%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20relationship_deps%20BLOB%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%2C%20staging_id%2C%20url%2C%20type%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20incoming_webhooks%20(%5Cn%20%20%20id%20NOT%20NULL%2C%5Cn%20%20%20username%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20webhook_path%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20verification_type%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20verification_config%20BLOB%20NOT%20NULL%2C%5Cn%20%20%20created_at%20NOT%20NULL%2C%5Cn%20%20%20updated_at%20NOT%20NULL%2C%5Cn%20%20%20signing_secret_ciphertext%2C%5Cn%20%20%20signing_secret_nonce%2C%5Cn%20%20%20signing_secret_tag%2C%5Cn%20%20%20signing_secret_key_id%20TEXT%2C%5Cn%20%20%20signing_secret_created_at%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20id%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20media_cache_ledger%20(%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20source_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20capture_spec_hash%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20source_generation%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20object_key%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20source_content_hash%20TEXT%2C%5Cn%20%20%20lane%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20content_type%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20size_bytes%20NOT%20NULL%2C%5Cn%20%20%20created_at%20NOT%20NULL%2C%5Cn%20%20%20last_accessed_at%20NOT%20NULL%2C%5Cn%20%20%20width%20INTEGER%2C%5Cn%20%20%20height%20INTEGER%2C%5Cn%20%20%20diagnostics%20BLOB%2C%5Cn%20%20%20rendered_as%20TEXT%20DEFAULT%20''%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%2C%20source_url%2C%20capture_spec_hash%2C%20source_generation%2C%20rendered_as%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20module_transpile_cache%20(%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20canonical_path%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20body%20TEXT%2C%5Cn%20%20%20headers%20BLOB%2C%5Cn%20%20%20dependency_keys%20BLOB%2C%5Cn%20%20%20generation%20DEFAULT%200%20NOT%20NULL%2C%5Cn%20%20%20created_at%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%2C%20canonical_path%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20modules%20(%5Cn%20%20%20url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20cache_scope%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20auth_user_id%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20resolved_realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20definitions%20BLOB%2C%5Cn%20%20%20deps%20BLOB%2C%5Cn%20%20%20error_doc%20BLOB%2C%5Cn%20%20%20created_at%2C%5Cn%20%20%20file_alias%20TEXT%2C%5Cn%20%20%20url_hash%20TEXT%20GENERATED%20ALWAYS%20AS%20(url)%20STORED%20NOT%20NULL%2C%5Cn%20%20%20diagnostics%20BLOB%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20url%2C%20cache_scope%2C%20auth_user_id%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20prerendered_html%20(%5Cn%20%20%20url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20file_alias%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20type%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20fitted_html%20BLOB%2C%5Cn%20%20%20embedded_html%20BLOB%2C%5Cn%20%20%20atom_html%20TEXT%2C%5Cn%20%20%20head_html%20TEXT%2C%5Cn%20%20%20isolated_html%20TEXT%2C%5Cn%20%20%20markdown%20TEXT%2C%5Cn%20%20%20deps%20BLOB%2C%5Cn%20%20%20last_known_good_deps%20BLOB%2C%5Cn%20%20%20generation%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20is_deleted%20BOOLEAN%2C%5Cn%20%20%20error_doc%20BLOB%2C%5Cn%20%20%20rendered_at%2C%5Cn%20%20%20diagnostics%20BLOB%2C%5Cn%20%20%20captures%20BLOB%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20url%2C%20realm_url%2C%20type%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20prerendered_html_pending%20(%5Cn%20%20%20url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20file_alias%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20type%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20fitted_html%20BLOB%2C%5Cn%20%20%20embedded_html%20BLOB%2C%5Cn%20%20%20atom_html%20TEXT%2C%5Cn%20%20%20head_html%20TEXT%2C%5Cn%20%20%20isolated_html%20TEXT%2C%5Cn%20%20%20markdown%20TEXT%2C%5Cn%20%20%20deps%20BLOB%2C%5Cn%20%20%20last_known_good_deps%20BLOB%2C%5Cn%20%20%20generation%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20is_deleted%20BOOLEAN%2C%5Cn%20%20%20error_doc%20BLOB%2C%5Cn%20%20%20rendered_at%2C%5Cn%20%20%20diagnostics%20BLOB%2C%5Cn%20%20%20captures%20BLOB%2C%5Cn%20%20%20job_id%20INTEGER%2C%5Cn%20%20%20staging_id%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%2C%20staging_id%2C%20url%2C%20type%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20rate_limit_buckets%20(%5Cn%20%20%20bucket_key%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20tokens%20NOT%20NULL%2C%5Cn%20%20%20refilled_at%20NOT%20NULL%2C%5Cn%20%20%20expires_at%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20bucket_key%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20rate_limit_budgets%20(%5Cn%20%20%20budget_key%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20period%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20period_start%20NOT%20NULL%2C%5Cn%20%20%20count%20NOT%20NULL%2C%5Cn%20%20%20expires_at%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20budget_key%2C%20period%2C%20period_start%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20realm_file_meta%20(%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20file_path%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20created_at%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20content_hash%20TEXT%2C%5Cn%20%20%20content_size%20INTEGER%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%2C%20file_path%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20realm_generations%20(%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20current_generation%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20loader_epoch%20TEXT%20DEFAULT%20'0'%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20realm_index_commits%20(%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20generation%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20base_generation%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20pass_id%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20job_id%20INTEGER%2C%5Cn%20%20%20urls%20BLOB%2C%5Cn%20%20%20render_only_urls%20BLOB%2C%5Cn%20%20%20full_realm%20BOOLEAN%20DEFAULT%20false%20NOT%20NULL%2C%5Cn%20%20%20committed_at%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%2C%20generation%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20realm_meta%20(%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20generation%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20value%20BLOB%20NOT%20NULL%2C%5Cn%20%20%20indexed_at%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%2C%20generation%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20realm_metadata%20(%5Cn%20%20%20url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20show_as_catalog%20BOOLEAN%2C%5Cn%20%20%20publishable%20BOOLEAN%2C%5Cn%20%20%20created_at%20DEFAULT%20CURRENT_TIMESTAMP%20NOT%20NULL%2C%5Cn%20%20%20updated_at%20DEFAULT%20CURRENT_TIMESTAMP%20NOT%20NULL%2C%5Cn%20%20%20archived_at%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20url%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20realm_registry%20(%5Cn%20%20%20id%20DEFAULT%20(hex(randomblob(16)))%20NOT%20NULL%2C%5Cn%20%20%20url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20kind%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20disk_id%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20owner_username%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20source_url%20TEXT%2C%5Cn%20%20%20last_published_at%2C%5Cn%20%20%20pinned%20BOOLEAN%20DEFAULT%20false%20NOT%20NULL%2C%5Cn%20%20%20created_at%20DEFAULT%20CURRENT_TIMESTAMP%20NOT%20NULL%2C%5Cn%20%20%20updated_at%20DEFAULT%20CURRENT_TIMESTAMP%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20id%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20realm_type_generations%20(%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20type_key%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20index_generation%20INTEGER%20DEFAULT%200%20NOT%20NULL%2C%5Cn%20%20%20html_generation%20INTEGER%20DEFAULT%200%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%2C%20type_key%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20realm_user_permissions%20(%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20username%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20read%20BOOLEAN%20NOT%20NULL%2C%5Cn%20%20%20write%20BOOLEAN%20NOT%20NULL%2C%5Cn%20%20%20realm_owner%20BOOLEAN%20DEFAULT%20false%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%2C%20username%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20scoped_css%20(%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20hash%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20css%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20last_interned_at%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%2C%20hash%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20unlisted_realm_paths%20(%5Cn%20%20%20id%20DEFAULT%20(hex(randomblob(16)))%20NOT%20NULL%2C%5Cn%20%20%20source_realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20slug%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20owner_user_id%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20created_at%20DEFAULT%20CURRENT_TIMESTAMP%20NOT%20NULL%2C%5Cn%20%20%20updated_at%20DEFAULT%20CURRENT_TIMESTAMP%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20id%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20webhook_commands%20(%5Cn%20%20%20id%20NOT%20NULL%2C%5Cn%20%20%20incoming_webhook_id%20NOT%20NULL%2C%5Cn%20%20%20command%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20command_filter%20BLOB%2C%5Cn%20%20%20created_at%20NOT%20NULL%2C%5Cn%20%20%20updated_at%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20id%20)%20%5Cn)%3B%22%2C%22defaultSystemCardId%22%3A%22http%3A%2F%2Ftest-realm%2Ftest%2FSystemCard%2Fdefault%22%2C%22defaultFieldSpecId%22%3A%22http%3A%2F%2Ftest-realm%2Ftest%2Ffields%2Ffield%22%7D">
16
+ <meta name="@cardstack/host/config/environment" content="%7B%22modulePrefix%22%3A%22%40cardstack%2Fhost%22%2C%22environment%22%3A%22test%22%2C%22hostedEnvironment%22%3A%22local%22%2C%22rootURL%22%3A%22%2F%22%2C%22locationType%22%3A%22none%22%2C%22EmberENV%22%3A%7B%22EXTEND_PROTOTYPES%22%3Afalse%2C%22FEATURES%22%3A%7B%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_DEFAULT_ASYNC_OBSERVERS%22%3Atrue%2C%22_JQUERY_INTEGRATION%22%3Afalse%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%220.0.0%2B5ac6897d%22%2C%22LOG_ACTIVE_GENERATION%22%3Afalse%2C%22LOG_VIEW_LOOKUPS%22%3Afalse%2C%22rootElement%22%3A%22%23ember-testing%22%2C%22autoboot%22%3Afalse%7D%2C%22ember-cli-mirage%22%3A%7B%22enabled%22%3Afalse%7D%2C%22logLevels%22%3A%22*%3Dinfo%2Cmatrix%3Dinfo%2Crealm%3Aevents%3Ddebug%22%2C%22matrixURL%22%3A%22http%3A%2F%2Flocalhost%3A8008%22%2C%22matrixServerName%22%3A%22localhost%22%2C%22autoSaveDelayMs%22%3A0%2C%22autoSaveQuietPeriodMs%22%3A0%2C%22autoSaveMaxWaitMs%22%3A10000%2C%22monacoDebounceMs%22%3A0%2C%22monacoCursorDebounceMs%22%3A0%2C%22loginMessageTimeoutMs%22%3A0%2C%22minSaveTaskDurationMs%22%3A0%2C%22cardRenderTimeout%22%3A30000%2C%22cardSizeLimitBytes%22%3A524288%2C%22fileSizeLimitBytes%22%3A5242880%2C%22audioSizeLimitBytes%22%3A20971520%2C%22videoSizeLimitBytes%22%3A52428800%2C%22iconsURL%22%3A%22http%3A%2F%2Flocalhost%3A4206%22%2C%22secureOriginURL%22%3A%22https%3A%2F%2Flocalhost%3A4208%2Fsecure%22%2C%22signInOnSecureOrigin%22%3Afalse%2C%22publishedRealmBoxelSpaceDomain%22%3A%22localhost%3A4201%22%2C%22publishedRealmBoxelSiteDomain%22%3A%22localhost%3A4201%22%2C%22hostsOwnAssets%22%3Atrue%2C%22hostRoutingMap%22%3A%5B%5D%2C%22realmServerURL%22%3A%22http%3A%2F%2Ftest-realm%22%2C%22resolvedBaseRealmURL%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fbase%2F%22%2C%22resolvedSkillsRealmURL%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fskills%2F%22%2C%22resolvedPretuiRealmURL%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fpretui%2F%22%2C%22resolvedTestRealmURL%22%3A%22https%3A%2F%2Flocalhost%3A4202%2Ftest%2F%22%2C%22featureFlags%22%3A%7B%7D%2C%22prefixRealmURLs%22%3A%7B%22%40cardstack%2Fbase%2F%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fbase%2F%22%2C%22%40cardstack%2Fcatalog%2F%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fcatalog%2F%22%2C%22%40cardstack%2Fskills%2F%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fskills%2F%22%2C%22%40cardstack%2Fopenrouter%2F%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fopenrouter%2F%22%2C%22%40cardstack%2Fpretui%2F%22%3A%22https%3A%2F%2Flocalhost%3A4201%2Fpretui%2F%22%7D%2C%22sqlSchema%22%3A%22--%20This%20is%20auto-generated%20by%20packages%2Frealm-server%2Fscripts%2Fconvert-to-sqlite.ts%5Cn--%20Please%20don't%20directly%20modify%20this%20file%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20anonymous_grant_rate_limits%20(%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20grant_id%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20client_ip%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20window_start%20NOT%20NULL%2C%5Cn%20%20%20window_seconds%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20count%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20expires_at%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%2C%20grant_id%2C%20client_ip%2C%20window_start%2C%20window_seconds%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20bot_commands%20(%5Cn%20%20%20id%20NOT%20NULL%2C%5Cn%20%20%20bot_id%20NOT%20NULL%2C%5Cn%20%20%20command%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20command_filter%20BLOB%20NOT%20NULL%2C%5Cn%20%20%20created_at%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20id%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20bot_registrations%20(%5Cn%20%20%20id%20NOT%20NULL%2C%5Cn%20%20%20username%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20created_at%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20id%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20boxel_index%20(%5Cn%20%20%20url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20file_alias%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20type%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20generation%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20pristine_doc%20BLOB%2C%5Cn%20%20%20search_doc%20BLOB%2C%5Cn%20%20%20error_doc%20BLOB%2C%5Cn%20%20%20deps%20BLOB%20DEFAULT%20'%5B%5D'%2C%5Cn%20%20%20types%20BLOB%2C%5Cn%20%20%20indexed_at%2C%5Cn%20%20%20is_deleted%20BOOLEAN%2C%5Cn%20%20%20last_modified%2C%5Cn%20%20%20display_names%20BLOB%2C%5Cn%20%20%20resource_created_at%2C%5Cn%20%20%20icon_html%20TEXT%2C%5Cn%20%20%20has_error%20BOOLEAN%20DEFAULT%20false%20NOT%20NULL%2C%5Cn%20%20%20last_known_good_deps%20BLOB%2C%5Cn%20%20%20diagnostics%20BLOB%2C%5Cn%20%20%20host_shell_generation%20INTEGER%2C%5Cn%20%20%20source_content_hash%20TEXT%2C%5Cn%20%20%20relationship_deps%20BLOB%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20url%2C%20realm_url%2C%20type%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20boxel_index_pending%20(%5Cn%20%20%20url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20file_alias%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20type%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20generation%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20pristine_doc%20BLOB%2C%5Cn%20%20%20search_doc%20BLOB%2C%5Cn%20%20%20error_doc%20BLOB%2C%5Cn%20%20%20deps%20BLOB%20DEFAULT%20'%5B%5D'%2C%5Cn%20%20%20types%20BLOB%2C%5Cn%20%20%20indexed_at%2C%5Cn%20%20%20is_deleted%20BOOLEAN%2C%5Cn%20%20%20last_modified%2C%5Cn%20%20%20display_names%20BLOB%2C%5Cn%20%20%20resource_created_at%2C%5Cn%20%20%20icon_html%20TEXT%2C%5Cn%20%20%20has_error%20BOOLEAN%20DEFAULT%20false%20NOT%20NULL%2C%5Cn%20%20%20last_known_good_deps%20BLOB%2C%5Cn%20%20%20diagnostics%20BLOB%2C%5Cn%20%20%20host_shell_generation%20INTEGER%2C%5Cn%20%20%20source_content_hash%20TEXT%2C%5Cn%20%20%20job_id%20INTEGER%2C%5Cn%20%20%20staging_id%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20relationship_deps%20BLOB%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%2C%20staging_id%2C%20url%2C%20type%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20incoming_webhooks%20(%5Cn%20%20%20id%20NOT%20NULL%2C%5Cn%20%20%20username%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20webhook_path%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20verification_type%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20verification_config%20BLOB%20NOT%20NULL%2C%5Cn%20%20%20created_at%20NOT%20NULL%2C%5Cn%20%20%20updated_at%20NOT%20NULL%2C%5Cn%20%20%20signing_secret_ciphertext%2C%5Cn%20%20%20signing_secret_nonce%2C%5Cn%20%20%20signing_secret_tag%2C%5Cn%20%20%20signing_secret_key_id%20TEXT%2C%5Cn%20%20%20signing_secret_created_at%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20id%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20media_cache_ledger%20(%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20source_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20capture_spec_hash%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20source_generation%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20object_key%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20source_content_hash%20TEXT%2C%5Cn%20%20%20lane%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20content_type%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20size_bytes%20NOT%20NULL%2C%5Cn%20%20%20created_at%20NOT%20NULL%2C%5Cn%20%20%20last_accessed_at%20NOT%20NULL%2C%5Cn%20%20%20width%20INTEGER%2C%5Cn%20%20%20height%20INTEGER%2C%5Cn%20%20%20diagnostics%20BLOB%2C%5Cn%20%20%20rendered_as%20TEXT%20DEFAULT%20''%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%2C%20source_url%2C%20capture_spec_hash%2C%20source_generation%2C%20rendered_as%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20module_transpile_cache%20(%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20canonical_path%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20body%20TEXT%2C%5Cn%20%20%20headers%20BLOB%2C%5Cn%20%20%20dependency_keys%20BLOB%2C%5Cn%20%20%20generation%20DEFAULT%200%20NOT%20NULL%2C%5Cn%20%20%20created_at%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%2C%20canonical_path%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20modules%20(%5Cn%20%20%20url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20cache_scope%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20auth_user_id%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20resolved_realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20definitions%20BLOB%2C%5Cn%20%20%20deps%20BLOB%2C%5Cn%20%20%20error_doc%20BLOB%2C%5Cn%20%20%20created_at%2C%5Cn%20%20%20file_alias%20TEXT%2C%5Cn%20%20%20url_hash%20TEXT%20GENERATED%20ALWAYS%20AS%20(url)%20STORED%20NOT%20NULL%2C%5Cn%20%20%20diagnostics%20BLOB%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20url%2C%20cache_scope%2C%20auth_user_id%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20prerendered_html%20(%5Cn%20%20%20url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20file_alias%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20type%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20fitted_html%20BLOB%2C%5Cn%20%20%20embedded_html%20BLOB%2C%5Cn%20%20%20atom_html%20TEXT%2C%5Cn%20%20%20head_html%20TEXT%2C%5Cn%20%20%20isolated_html%20TEXT%2C%5Cn%20%20%20markdown%20TEXT%2C%5Cn%20%20%20deps%20BLOB%2C%5Cn%20%20%20last_known_good_deps%20BLOB%2C%5Cn%20%20%20generation%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20is_deleted%20BOOLEAN%2C%5Cn%20%20%20error_doc%20BLOB%2C%5Cn%20%20%20rendered_at%2C%5Cn%20%20%20diagnostics%20BLOB%2C%5Cn%20%20%20captures%20BLOB%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20url%2C%20realm_url%2C%20type%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20prerendered_html_pending%20(%5Cn%20%20%20url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20file_alias%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20type%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20fitted_html%20BLOB%2C%5Cn%20%20%20embedded_html%20BLOB%2C%5Cn%20%20%20atom_html%20TEXT%2C%5Cn%20%20%20head_html%20TEXT%2C%5Cn%20%20%20isolated_html%20TEXT%2C%5Cn%20%20%20markdown%20TEXT%2C%5Cn%20%20%20deps%20BLOB%2C%5Cn%20%20%20last_known_good_deps%20BLOB%2C%5Cn%20%20%20generation%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20is_deleted%20BOOLEAN%2C%5Cn%20%20%20error_doc%20BLOB%2C%5Cn%20%20%20rendered_at%2C%5Cn%20%20%20diagnostics%20BLOB%2C%5Cn%20%20%20captures%20BLOB%2C%5Cn%20%20%20job_id%20INTEGER%2C%5Cn%20%20%20staging_id%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%2C%20staging_id%2C%20url%2C%20type%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20rate_limit_buckets%20(%5Cn%20%20%20bucket_key%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20tokens%20NOT%20NULL%2C%5Cn%20%20%20refilled_at%20NOT%20NULL%2C%5Cn%20%20%20expires_at%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20bucket_key%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20rate_limit_budgets%20(%5Cn%20%20%20budget_key%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20period%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20period_start%20NOT%20NULL%2C%5Cn%20%20%20count%20NOT%20NULL%2C%5Cn%20%20%20expires_at%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20budget_key%2C%20period%2C%20period_start%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20realm_file_meta%20(%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20file_path%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20created_at%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20content_hash%20TEXT%2C%5Cn%20%20%20content_size%20INTEGER%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%2C%20file_path%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20realm_generations%20(%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20current_generation%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20loader_epoch%20TEXT%20DEFAULT%20'0'%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20realm_index_commits%20(%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20generation%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20base_generation%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20pass_id%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20job_id%20INTEGER%2C%5Cn%20%20%20urls%20BLOB%2C%5Cn%20%20%20render_only_urls%20BLOB%2C%5Cn%20%20%20full_realm%20BOOLEAN%20DEFAULT%20false%20NOT%20NULL%2C%5Cn%20%20%20committed_at%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%2C%20generation%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20realm_meta%20(%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20generation%20INTEGER%20NOT%20NULL%2C%5Cn%20%20%20value%20BLOB%20NOT%20NULL%2C%5Cn%20%20%20indexed_at%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%2C%20generation%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20realm_metadata%20(%5Cn%20%20%20url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20show_as_catalog%20BOOLEAN%2C%5Cn%20%20%20publishable%20BOOLEAN%2C%5Cn%20%20%20created_at%20DEFAULT%20CURRENT_TIMESTAMP%20NOT%20NULL%2C%5Cn%20%20%20updated_at%20DEFAULT%20CURRENT_TIMESTAMP%20NOT%20NULL%2C%5Cn%20%20%20archived_at%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20url%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20realm_registry%20(%5Cn%20%20%20id%20DEFAULT%20(hex(randomblob(16)))%20NOT%20NULL%2C%5Cn%20%20%20url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20kind%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20disk_id%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20owner_username%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20source_url%20TEXT%2C%5Cn%20%20%20last_published_at%2C%5Cn%20%20%20pinned%20BOOLEAN%20DEFAULT%20false%20NOT%20NULL%2C%5Cn%20%20%20created_at%20DEFAULT%20CURRENT_TIMESTAMP%20NOT%20NULL%2C%5Cn%20%20%20updated_at%20DEFAULT%20CURRENT_TIMESTAMP%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20id%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20realm_type_generations%20(%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20type_key%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20index_generation%20INTEGER%20DEFAULT%200%20NOT%20NULL%2C%5Cn%20%20%20html_generation%20INTEGER%20DEFAULT%200%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%2C%20type_key%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20realm_user_permissions%20(%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20username%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20read%20BOOLEAN%20NOT%20NULL%2C%5Cn%20%20%20write%20BOOLEAN%20NOT%20NULL%2C%5Cn%20%20%20realm_owner%20BOOLEAN%20DEFAULT%20false%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%2C%20username%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20scoped_css%20(%5Cn%20%20%20realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20hash%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20css%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20last_interned_at%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20realm_url%2C%20hash%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20unlisted_realm_paths%20(%5Cn%20%20%20id%20DEFAULT%20(hex(randomblob(16)))%20NOT%20NULL%2C%5Cn%20%20%20source_realm_url%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20slug%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20owner_user_id%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20created_at%20DEFAULT%20CURRENT_TIMESTAMP%20NOT%20NULL%2C%5Cn%20%20%20updated_at%20DEFAULT%20CURRENT_TIMESTAMP%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20id%20)%20%5Cn)%3B%5Cn%5Cn%20CREATE%20TABLE%20IF%20NOT%20EXISTS%20webhook_commands%20(%5Cn%20%20%20id%20NOT%20NULL%2C%5Cn%20%20%20incoming_webhook_id%20NOT%20NULL%2C%5Cn%20%20%20command%20TEXT%20NOT%20NULL%2C%5Cn%20%20%20command_filter%20BLOB%2C%5Cn%20%20%20created_at%20NOT%20NULL%2C%5Cn%20%20%20updated_at%20NOT%20NULL%2C%5Cn%20%20%20PRIMARY%20KEY%20(%20id%20)%20%5Cn)%3B%22%2C%22defaultSystemCardId%22%3A%22http%3A%2F%2Ftest-realm%2Ftest%2FSystemCard%2Fdefault%22%2C%22defaultFieldSpecId%22%3A%22http%3A%2F%2Ftest-realm%2Ftest%2Ffields%2Ffield%22%7D">
17
17
 
18
18
  <link rel="stylesheet" href="/@embroider/virtual/app.css">
19
19
 
20
20
 
21
- <script type="module" crossorigin="" src="/assets/tests-CmsQ-Z_3.js"></script>
21
+ <script type="module" crossorigin="" src="/assets/tests-DoTEpvcF.js"></script>
22
22
  <link rel="modulepreload" crossorigin="" href="/assets/chunk-Rp0pCe6z.js">
23
23
  <link rel="modulepreload" crossorigin="" href="/assets/preload-helper-CKDH5-7N.js">
24
24
  <link rel="modulepreload" crossorigin="" href="/assets/index-esm-CUymiD6S.js">
@@ -219,7 +219,7 @@
219
219
  <link rel="modulepreload" crossorigin="" href="/assets/validate-realm-DFzizApj.js">
220
220
  <link rel="modulepreload" crossorigin="" href="/assets/view-visually-C3PpJSI2.js">
221
221
  <link rel="modulepreload" crossorigin="" href="/assets/tools-DU8Rc15s.js">
222
- <link rel="modulepreload" crossorigin="" href="/assets/externals-6ZWftYIb.js">
222
+ <link rel="modulepreload" crossorigin="" href="/assets/externals-DCnB4XSS.js">
223
223
  <link rel="modulepreload" crossorigin="" href="/assets/render-service-DeDLQrOD.js">
224
224
  <link rel="modulepreload" crossorigin="" href="/assets/buffer-DQZcL7h7.js">
225
225
  <link rel="modulepreload" crossorigin="" href="/assets/perform-g9ba6YNZ.js">
@@ -337,7 +337,7 @@
337
337
  <link rel="modulepreload" crossorigin="" href="/assets/card-service-BZPDxaaw.js">
338
338
  <link rel="modulepreload" crossorigin="" href="/assets/host-mode-service-CV8pBhBq.js">
339
339
  <link rel="modulepreload" crossorigin="" href="/assets/render-diagnostics-CztktD_I.js">
340
- <link rel="modulepreload" crossorigin="" href="/assets/app-QAuw0l8v.js">
340
+ <link rel="modulepreload" crossorigin="" href="/assets/app-CtezUCip.js">
341
341
  <link rel="modulepreload" crossorigin="" href="/assets/qunit-C-Foo4Nd.js">
342
342
  <link rel="modulepreload" crossorigin="" href="/assets/dist-CPfIHBla.js">
343
343
  <link rel="modulepreload" crossorigin="" href="/assets/dist-Ds4JDBNZ.js">
@@ -44,15 +44,27 @@ export function registerBeacon(name: string, element: Element): () => void {
44
44
  }
45
45
 
46
46
  /**
47
- * Measure every live beacon, in the same window the region measures `final`.
47
+ * Measure the live beacons, in the same window the region measures `final`.
48
48
  *
49
49
  * Re-measured every pass, never cached: the trash can move without the list
50
50
  * rendering at all — a header that hides, a column that resizes, a scroll.
51
+ *
52
+ * A region passes the names its score asked for, so a pass measures only
53
+ * those: a page can claim hundreds of beacons (every chip a sheet may open
54
+ * from), and each region measuring every one on every pass would cost a
55
+ * layout read per beacon per region. Without `names`, every claimed beacon
56
+ * is measured.
51
57
  */
52
- export function measureBeacons(root: DOMRect): Map<string, Bounds> {
58
+ export function measureBeacons(
59
+ root: DOMRect,
60
+ names?: Iterable<string>,
61
+ ): Map<string, Bounds> {
53
62
  const out = new Map<string, Bounds>();
54
- for (const [name, el] of registry) {
55
- if (!el.isConnected) {
63
+ const wanted = names
64
+ ? [...names].map((name) => [name, registry.get(name)] as const)
65
+ : [...registry];
66
+ for (const [name, el] of wanted) {
67
+ if (!el?.isConnected) {
56
68
  continue;
57
69
  }
58
70
  out.set(name, measureBounds(el, root));
@@ -61,8 +61,16 @@ export class Changeset implements ChangesetLike {
61
61
  /** the frame's own size in local pixels, from the same final layout */
62
62
  readonly frame?: { height: number; width: number };
63
63
 
64
- /** what the page shows behind this region — see ChangesetLike.ground */
65
- readonly ground?: string;
64
+ /** what the page shows behind this region — see ChangesetLike.ground.
65
+ * Read on first use: finding it walks the region's ancestors' computed
66
+ * styles, and most passes never crossfade a skin that needs it. */
67
+ get ground(): string | undefined {
68
+ if (typeof this.groundSource === 'function') {
69
+ this.groundSource = this.groundSource();
70
+ }
71
+ return this.groundSource;
72
+ }
73
+ private groundSource: string | undefined | (() => string | undefined);
66
74
 
67
75
  constructor(
68
76
  inserted: Sprite[],
@@ -71,15 +79,27 @@ export class Changeset implements ChangesetLike {
71
79
  beacons: Map<string, Bounds> = new Map(),
72
80
  measureZoom = 1,
73
81
  frame?: { height: number; width: number },
74
- ground?: string,
82
+ ground?: string | (() => string | undefined),
83
+ // measures a beacon `beacons` does not hold, for a name the score has
84
+ // not asked for before
85
+ measureBeacon?: (name: string) => Bounds | null,
75
86
  ) {
76
87
  this.inserted = inserted;
77
88
  this.removed = removed;
78
89
  this.kept = kept;
79
- this.beacon = (name) => beacons.get(name) ?? null;
90
+ this.beacon = (name) => {
91
+ if (!beacons.has(name) && measureBeacon) {
92
+ const bounds = measureBeacon(name);
93
+ if (bounds) {
94
+ beacons.set(name, bounds);
95
+ }
96
+ return bounds;
97
+ }
98
+ return beacons.get(name) ?? null;
99
+ };
80
100
  this.measureZoom = measureZoom;
81
101
  this.frame = frame;
82
- this.ground = ground;
102
+ this.groundSource = ground;
83
103
  }
84
104
 
85
105
  get all(): Sprite[] {
@@ -206,6 +206,35 @@ interface Signature {
206
206
  /** outline the region and its participants; console.table each run */
207
207
  debug?: boolean;
208
208
  id?: string;
209
+ /**
210
+ * Sit this region out of render passes: while true it takes no snapshot
211
+ * and joins no barrier, so it plays nothing and costs nothing, and its
212
+ * participants stay registered and its block stays rendered. A page with
213
+ * many regions of which few can change at once (a message per region in
214
+ * a long transcript) keeps the rest idle; the pass that sets it back to
215
+ * false is the first one the region watches again.
216
+ */
217
+ idle?: boolean;
218
+ /**
219
+ * Wire only what can be seen: the region measures and animates only the
220
+ * participants inside its scroller's view, or close enough to it
221
+ * (`@inViewMargin` views beyond each edge, default 1) that a move may
222
+ * bring them on screen. The rest are left to layout: no snapshot, no
223
+ * measuring, no motion. A participant coming within the margin is wired
224
+ * and one leaving it unwired, and neither counts as an arrival or a
225
+ * removal. A pass that moves something farther than the margin is a
226
+ * jump, not a change, and lands as layout puts it: animating it would
227
+ * fly blocks past ones that were never wired.
228
+ */
229
+ inView?: boolean;
230
+ inViewMargin?: number;
231
+ /**
232
+ * The most animation time, in ms, one painted frame may advance: a run
233
+ * behind a long frame slows down instead of skipping ahead, so nothing
234
+ * jumps on a busy page. Unset, a frame advances by the time since the
235
+ * last one (up to 40 ms).
236
+ */
237
+ maxFrameStep?: number;
209
238
  /**
210
239
  * A `c.Camera3D` cue moved the shot. Called every frame it changes —
211
240
  * scrubs included, since the pose is sampled from the score — with a
@@ -353,6 +382,29 @@ function reducesMotion(root: Element): boolean {
353
382
  );
354
383
  }
355
384
 
385
+ /** whether an element scrolls its content on either axis */
386
+ function scrolls(el: Element): boolean {
387
+ const { overflowX, overflowY } = getComputedStyle(el);
388
+ return [overflowX, overflowY].some(
389
+ (o) => o === 'auto' || o === 'scroll' || o === 'overlay',
390
+ );
391
+ }
392
+
393
+ /** the nearest ancestor that scrolls vertically: what `@inView` calls the view */
394
+ function scrollerOf(el: Element): HTMLElement | null {
395
+ for (let p = el.parentElement; p; p = p.parentElement) {
396
+ const overflow = getComputedStyle(p).overflowY;
397
+ if (
398
+ overflow === 'auto' ||
399
+ overflow === 'scroll' ||
400
+ overflow === 'overlay'
401
+ ) {
402
+ return p;
403
+ }
404
+ }
405
+ return null;
406
+ }
407
+
356
408
  /**
357
409
  * The barrier books one post-render callback for every region taking part in a
358
410
  * pass. `joinPass(this)` is where the region's PassHost contract (measurePass /
@@ -392,6 +444,9 @@ export class Choreo extends Component<Signature> implements ChoreoHost {
392
444
  private arrived = new Set<ChoreoNode>();
393
445
  /** destroyed before the pass that removed them has been processed */
394
446
  private claimed = new Set<ChoreoNode>();
447
+ /** every beacon name this region's score has read, so a pass measures
448
+ * those beacons and not the whole page's */
449
+ readonly beaconNames = new Set<string>();
395
450
  /** removed participants this region is keeping alive in its orphan layer */
396
451
  private orphans = new Set<ChoreoNode>();
397
452
  /** participants whose Presence is letting them go: removed once, not on every pass while they leave */
@@ -443,6 +498,7 @@ export class Choreo extends Component<Signature> implements ChoreoHost {
443
498
  this.run = undefined;
444
499
  // a quiet region must not take its pause to the grave
445
500
  this.unquiet();
501
+ this.viewObserver?.disconnect();
446
502
  for (const node of [...this.orphans, ...this.claimed]) {
447
503
  this.drop(node);
448
504
  }
@@ -474,6 +530,7 @@ export class Choreo extends Component<Signature> implements ChoreoHost {
474
530
  register(node: ChoreoNode) {
475
531
  this.participants.add(node);
476
532
  this.arrived.add(node);
533
+ this.watchView(node);
477
534
  if (this.args.debug && node.element) {
478
535
  (node.element as HTMLElement).style.outline = '1px dotted #16a34a';
479
536
  // the seam lints (§5.3): inside a region the timeline is the only
@@ -495,9 +552,120 @@ export class Choreo extends Component<Signature> implements ChoreoHost {
495
552
  // a destroyed participant may still be claimed (below); the sets that decide that survive until drop()
496
553
  this.participants.delete(node);
497
554
  this.arrived.delete(node);
555
+ this.unwatchView(node);
498
556
  };
499
557
  }
500
558
 
559
+ /** sat out a pass since the last one it watched (`@idle`) */
560
+ private slept = false;
561
+
562
+ /* ---- @inView: what is wired ---- */
563
+
564
+ /** participants inside the view or its margin, as the observer last saw them */
565
+ private nearView = new Set<ChoreoNode>();
566
+ /** what the last pass animated: kept wired until a pass lets it go, so a
567
+ * block that leaves the margin mid-flight is not cut loose halfway */
568
+ private flying = new Set<ChoreoNode>();
569
+ private viewNodes = new WeakMap<Element, ChoreoNode>();
570
+ private viewObserver?: IntersectionObserver;
571
+ private viewRoot: HTMLElement | null = null;
572
+ /** the `@inViewMargin` the current observer was made with */
573
+ private viewMarginUsed?: number;
574
+
575
+ private get viewMargin() {
576
+ return this.args.inViewMargin ?? 1;
577
+ }
578
+
579
+ private watchView(node: ChoreoNode) {
580
+ const el = node.element;
581
+ if (!this.args.inView || !el) {
582
+ return;
583
+ }
584
+ if (!this.viewObserver) {
585
+ this.viewRoot = this.element ? scrollerOf(this.element) : null;
586
+ this.viewMarginUsed = this.viewMargin;
587
+ this.viewObserver = new IntersectionObserver(
588
+ (entries) => {
589
+ for (const entry of entries) {
590
+ const seen = this.viewNodes.get(entry.target);
591
+ if (!seen) {
592
+ continue;
593
+ }
594
+ if (entry.isIntersecting) {
595
+ this.nearView.add(seen);
596
+ } else {
597
+ this.nearView.delete(seen);
598
+ }
599
+ }
600
+ },
601
+ {
602
+ root: this.viewRoot,
603
+ rootMargin: `${this.viewMargin * 100}% 0px`,
604
+ },
605
+ );
606
+ }
607
+ this.viewNodes.set(el, node);
608
+ this.viewObserver.observe(el);
609
+ }
610
+
611
+ /**
612
+ * `@inView` and `@inViewMargin` can change after participants registered:
613
+ * switched on (or given a new margin), the region observes every current
614
+ * participant and wires the ones already near the view now (the observer
615
+ * reports only after the next frame); switched off, it lets the observer
616
+ * go and wires everything again.
617
+ */
618
+ private syncViewWatch() {
619
+ if (
620
+ this.args.inView &&
621
+ this.viewObserver &&
622
+ this.viewMarginUsed !== this.viewMargin
623
+ ) {
624
+ // the observer's margin is fixed when it is made: a new margin makes a
625
+ // new observer
626
+ this.viewObserver.disconnect();
627
+ this.viewObserver = undefined;
628
+ this.nearView.clear();
629
+ }
630
+ if (this.args.inView && !this.viewObserver) {
631
+ for (const node of this.participants) {
632
+ this.watchView(node);
633
+ }
634
+ if (this.viewObserver) {
635
+ const near = this.nearViewBand();
636
+ for (const node of this.participants) {
637
+ const r = node.element?.getBoundingClientRect();
638
+ if (r && r.bottom >= near.top && r.top <= near.bottom) {
639
+ this.nearView.add(node);
640
+ }
641
+ }
642
+ }
643
+ } else if (!this.args.inView && this.viewObserver) {
644
+ this.viewObserver.disconnect();
645
+ this.viewObserver = undefined;
646
+ this.viewRoot = null;
647
+ this.nearView.clear();
648
+ this.flying.clear();
649
+ }
650
+ }
651
+
652
+ private unwatchView(node: ChoreoNode) {
653
+ this.nearView.delete(node);
654
+ if (node.element) {
655
+ this.viewObserver?.unobserve(node.element);
656
+ }
657
+ }
658
+
659
+ /** the view and its margin, in viewport px; read once per pass */
660
+ private nearViewBand() {
661
+ const r = this.viewRoot
662
+ ? this.viewRoot.getBoundingClientRect()
663
+ : { bottom: window.innerHeight, top: 0 };
664
+ const height = r.bottom - r.top;
665
+ const margin = height * this.viewMargin;
666
+ return { bottom: r.bottom + margin, margin, top: r.top - margin };
667
+ }
668
+
501
669
  claim(node: ChoreoNode) {
502
670
  if (this.orphans.has(node)) {
503
671
  return true;
@@ -520,8 +688,20 @@ export class Choreo extends Component<Signature> implements ChoreoHost {
520
688
  // (`layout` / `layoutId`) snapshot here too, so `{{motion layout=true}}`
521
689
  // works inside a <Choreo> without a <LayoutGroup> wrapped around it.
522
690
  snapshotOnRender();
691
+ if (this.args.idle) {
692
+ this.slept = true;
693
+ return undefined;
694
+ }
695
+ if (this.slept) {
696
+ // what arrived while the region sat out was never watched arriving:
697
+ // waking must not replay it. This pass's own arrivals register after
698
+ // this, as its modifiers install.
699
+ this.slept = false;
700
+ this.arrived.clear();
701
+ }
523
702
  if (!this.passPending) {
524
703
  this.passPending = true;
704
+ this.syncViewWatch();
525
705
  this.snapshot();
526
706
  // every region announces here, while Glimmer is still rendering, so the
527
707
  // barrier knows the whole cast before anybody measures
@@ -534,9 +714,14 @@ export class Choreo extends Component<Signature> implements ChoreoHost {
534
714
  private snapshot() {
535
715
  this.snapshots.clear();
536
716
  this.rootSnapshot = this.element?.getBoundingClientRect();
717
+ const wired = this.args.inView ? this.nearView : undefined;
537
718
  for (const node of this.participants) {
538
719
  const el = node.element;
539
- if (el?.isConnected && !this.orphans.has(node)) {
720
+ if (
721
+ el?.isConnected &&
722
+ !this.orphans.has(node) &&
723
+ (!wired || wired.has(node) || this.flying.has(node))
724
+ ) {
540
725
  this.snapshots.set(node, measure(el));
541
726
  }
542
727
  }
@@ -601,6 +786,7 @@ export class Choreo extends Component<Signature> implements ChoreoHost {
601
786
  role: node.role,
602
787
  type,
603
788
  });
789
+ const near = this.args.inView ? this.nearViewBand() : undefined;
604
790
  const candidates = new Set([
605
791
  ...this.participants,
606
792
  ...this.claimed,
@@ -617,6 +803,15 @@ export class Choreo extends Component<Signature> implements ChoreoHost {
617
803
  const prior = this.orphanBounds.get(node);
618
804
  removed.push(sprite(node, 'removed', prior));
619
805
  } else if (this.arrived.has(node)) {
806
+ if (near) {
807
+ const r = el.getBoundingClientRect();
808
+ if (r.bottom < near.top || r.top > near.bottom) {
809
+ // it lands out of reach of the view: layout places it
810
+ continue;
811
+ }
812
+ // wired now: the observer reports only after the next frame
813
+ this.nearView.add(node);
814
+ }
620
815
  inserted.push(
621
816
  sprite(node, 'inserted', undefined, bounds(measure(el), after)),
622
817
  );
@@ -667,6 +862,24 @@ export class Choreo extends Component<Signature> implements ChoreoHost {
667
862
  };
668
863
  }
669
864
  }
865
+ // a jump: something moved farther than the margin, past blocks that
866
+ // were never wired. It lands as layout puts it; what was leaving goes now.
867
+ if (near && kept.some((s) => Math.abs(s.delta?.y ?? 0) > near.margin)) {
868
+ for (const s of removed) {
869
+ this.drop(s.node);
870
+ }
871
+ inserted.length = 0;
872
+ kept.length = 0;
873
+ removed.length = 0;
874
+ }
875
+ if (near) {
876
+ this.flying = new Set(
877
+ [
878
+ ...inserted,
879
+ ...kept.filter((s) => s.delta && (s.delta.x || s.delta.y)),
880
+ ].map((s) => s.node),
881
+ );
882
+ }
670
883
  this.arrived.clear();
671
884
  this.snapshots.clear();
672
885
  const claimed = [...this.claimed];
@@ -725,7 +938,10 @@ export class Choreo extends Component<Signature> implements ChoreoHost {
725
938
  [...kept, ...inserted.filter((s) => s.type === 'kept')],
726
939
  // measured in the same window as `final`, and re-measured every pass: a
727
940
  // beacon can move without this region rendering at all
728
- measureBeacons(after),
941
+ // the beacons this score has asked for before, measured now; a name it
942
+ // asks for the first time is measured when the step reads it (Glimmer
943
+ // reads a step's args as it compiles, after this)
944
+ measureBeacons(after, this.beaconNames),
729
945
  measureZoom,
730
946
  // the frame's own size in the same final layout, local pixels — the
731
947
  // camera's centre reference, so aim terms are internally consistent
@@ -733,7 +949,11 @@ export class Choreo extends Component<Signature> implements ChoreoHost {
733
949
  height: after.height / measureZoom,
734
950
  width: after.width / measureZoom,
735
951
  },
736
- groundOf(root),
952
+ () => groundOf(root),
953
+ (name) => {
954
+ this.beaconNames.add(name);
955
+ return measureBeacons(after, [name]).get(name) ?? null;
956
+ },
737
957
  );
738
958
  this.changeset = changeset;
739
959
 
@@ -860,6 +1080,9 @@ export class Choreo extends Component<Signature> implements ChoreoHost {
860
1080
  // aloft, kept-motion cannot justify a recompile either: the score it
861
1081
  // would produce is the degraded one above.
862
1082
  (this.orphans.size > 0 || !changeset.sprites({ type: 'moved' }).length) &&
1083
+ // …and only while the layout it compiled in still stands: a reflow or
1084
+ // a scroll under a leaver still aloft is a real move, not noise
1085
+ this.layoutOf() === this.layoutPrint &&
863
1086
  // …but an EDITED timeline is never noise: a changed tree replays,
864
1087
  // exactly as it would with no orphans aloft (the build-order
865
1088
  // transport's delay nudge, made while a leaver is frozen mid-park)
@@ -1010,6 +1233,7 @@ export class Choreo extends Component<Signature> implements ChoreoHost {
1010
1233
  // arriving, and every one it can see on its way out. A region in that
1011
1234
  // state is not watching a departure, it is inside one — see `park`.
1012
1235
  doomed: !kept.length && !inserted.length && removed.length > 0,
1236
+ maxFrameStep: this.args.maxFrameStep,
1013
1237
  });
1014
1238
 
1015
1239
  if (this.args.quiet) {
@@ -1082,6 +1306,24 @@ export class Choreo extends Component<Signature> implements ChoreoHost {
1082
1306
  `${el.offsetWidth},${el.offsetHeight}`,
1083
1307
  );
1084
1308
  }
1309
+ // A scroll moves every participant in page space and none of them in
1310
+ // the offsets above, so the scroll offset of the scroller the region
1311
+ // sits in is part of where its participants stand: a follow settled into
1312
+ // a pass mid-run is a real move, and the run is recompiled to carry it.
1313
+ // The walk stops at that scroller (the document's own scroll counts only
1314
+ // when no element scroller holds the region), so scrolling an outer
1315
+ // scroller or the page around it does not cancel the region's runs, for
1316
+ // the same reason the offset walk above stops at the region's edge.
1317
+ let sx = 0;
1318
+ let sy = 0;
1319
+ for (let a = root?.parentElement; a; a = a.parentElement) {
1320
+ sx += a.scrollLeft;
1321
+ sy += a.scrollTop;
1322
+ if (a !== document.documentElement && scrolls(a)) {
1323
+ break;
1324
+ }
1325
+ }
1326
+ parts.push(`scroll@${Math.round(sx)},${Math.round(sy)}`);
1085
1327
  return parts.join('|');
1086
1328
  }
1087
1329
 
@@ -103,11 +103,50 @@ export function setBeforeMeasure(fn: () => void) {
103
103
  beforeMeasure = fn;
104
104
  }
105
105
 
106
+ /**
107
+ * SETTLE: state that the pass implies but that is not markup, settled after
108
+ * this pass's mounts and before any region measures. A scroll owner (a list
109
+ * that keeps its scroll at the newest content, or holds a row in place while
110
+ * rows above it change) holds its anchor here: a scroll position is state,
111
+ * so it lands in the same pass as the change that moved it, and every region
112
+ * measures the page as the reader will see it. An element the scroll kept
113
+ * still then reads as not moved and gets no motion; only what really moved
114
+ * on screen does.
115
+ *
116
+ * A settler only runs inside a barrier, and a barrier runs only when a
117
+ * region joins a pass: with no region mounted, every region idle, or motion
118
+ * off, no settler runs. So the owner sets its scroll through its own path as
119
+ * well (on render or on resize, as it would with no Choreo on the page), and
120
+ * the settler only makes that happen before regions measure. State never
121
+ * depends on a settler (ADR 007 §1.1).
122
+ *
123
+ * Settlers run in registration order; one that throws is reported and the
124
+ * pass goes on. Returns the unregister function.
125
+ */
126
+ const settlers = new Set<() => void>();
127
+ export function registerSettle(fn: () => void): () => void {
128
+ settlers.add(fn);
129
+ return () => {
130
+ settlers.delete(fn);
131
+ };
132
+ }
133
+
106
134
  function runBarrier() {
107
135
  booked = false;
108
136
  const hosts = [...intents];
109
137
  intents.clear();
110
138
  beforeMeasure();
139
+ for (const settle of [...settlers]) {
140
+ // a settler is app code: one that throws must not keep the regions that
141
+ // joined this pass from measuring, or they would stay pending for good
142
+ try {
143
+ settle();
144
+ } catch (e) {
145
+ queueMicrotask(() => {
146
+ throw e;
147
+ });
148
+ }
149
+ }
111
150
  const passes: Pass[] = [];
112
151
  for (const host of hosts) {
113
152
  const pass = host.measurePass();