@vtechcom/hexcore 2.0.0-beta.1

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 (173) hide show
  1. package/CHANGELOG.md +127 -0
  2. package/LICENSE +201 -0
  3. package/README.md +283 -0
  4. package/dist/app.module.js +55 -0
  5. package/dist/app.module.js.map +1 -0
  6. package/dist/auth.js +151 -0
  7. package/dist/auth.js.map +1 -0
  8. package/dist/chain/cost-models.js +81 -0
  9. package/dist/chain/cost-models.js.map +1 -0
  10. package/dist/chain/provider.js +269 -0
  11. package/dist/chain/provider.js.map +1 -0
  12. package/dist/chain/socket.js +48 -0
  13. package/dist/chain/socket.js.map +1 -0
  14. package/dist/cli/doctor.js +43 -0
  15. package/dist/cli/doctor.js.map +1 -0
  16. package/dist/cli/hexcore.js +435 -0
  17. package/dist/cli/hexcore.js.map +1 -0
  18. package/dist/common/auth.guard.js +66 -0
  19. package/dist/common/auth.guard.js.map +1 -0
  20. package/dist/common/http.js +171 -0
  21. package/dist/common/http.js.map +1 -0
  22. package/dist/common/zod-validation.pipe.js +47 -0
  23. package/dist/common/zod-validation.pipe.js.map +1 -0
  24. package/dist/config.js +354 -0
  25. package/dist/config.js.map +1 -0
  26. package/dist/config.module.js +35 -0
  27. package/dist/config.module.js.map +1 -0
  28. package/dist/controllers/cardano.controller.js +173 -0
  29. package/dist/controllers/cardano.controller.js.map +1 -0
  30. package/dist/controllers/heads.controller.js +225 -0
  31. package/dist/controllers/heads.controller.js.map +1 -0
  32. package/dist/controllers/setup.controller.js +127 -0
  33. package/dist/controllers/setup.controller.js.map +1 -0
  34. package/dist/controllers/system.controller.js +153 -0
  35. package/dist/controllers/system.controller.js.map +1 -0
  36. package/dist/db/database.module.js +73 -0
  37. package/dist/db/database.module.js.map +1 -0
  38. package/dist/db/index.js +135 -0
  39. package/dist/db/index.js.map +1 -0
  40. package/dist/db/repositories.js +220 -0
  41. package/dist/db/repositories.js.map +1 -0
  42. package/dist/docker/container-stats.js +134 -0
  43. package/dist/docker/container-stats.js.map +1 -0
  44. package/dist/docker/docker.service.js +335 -0
  45. package/dist/docker/docker.service.js.map +1 -0
  46. package/dist/hydra/argv.js +172 -0
  47. package/dist/hydra/argv.js.map +1 -0
  48. package/dist/hydra/blockfrost-keys.js +15 -0
  49. package/dist/hydra/blockfrost-keys.js.map +1 -0
  50. package/dist/hydra/boot-progress.js +165 -0
  51. package/dist/hydra/boot-progress.js.map +1 -0
  52. package/dist/hydra/capabilities.js +131 -0
  53. package/dist/hydra/capabilities.js.map +1 -0
  54. package/dist/hydra/head.service.js +1072 -0
  55. package/dist/hydra/head.service.js.map +1 -0
  56. package/dist/hydra/keys.js +301 -0
  57. package/dist/hydra/keys.js.map +1 -0
  58. package/dist/hydra/node-monitor.service.js +265 -0
  59. package/dist/hydra/node-monitor.service.js.map +1 -0
  60. package/dist/hydra/ws-client.js +177 -0
  61. package/dist/hydra/ws-client.js.map +1 -0
  62. package/dist/main.js +106 -0
  63. package/dist/main.js.map +1 -0
  64. package/dist/preflight.js +215 -0
  65. package/dist/preflight.js.map +1 -0
  66. package/dist/settings.js +243 -0
  67. package/dist/settings.js.map +1 -0
  68. package/dist/setup.service.js +257 -0
  69. package/dist/setup.service.js.map +1 -0
  70. package/dist/version.js +46 -0
  71. package/dist/version.js.map +1 -0
  72. package/node_modules/@hexcore/shared/dist/cjs/api.d.ts +730 -0
  73. package/node_modules/@hexcore/shared/dist/cjs/api.d.ts.map +1 -0
  74. package/node_modules/@hexcore/shared/dist/cjs/api.js +358 -0
  75. package/node_modules/@hexcore/shared/dist/cjs/api.js.map +1 -0
  76. package/node_modules/@hexcore/shared/dist/cjs/domain.d.ts +298 -0
  77. package/node_modules/@hexcore/shared/dist/cjs/domain.d.ts.map +1 -0
  78. package/node_modules/@hexcore/shared/dist/cjs/domain.js +49 -0
  79. package/node_modules/@hexcore/shared/dist/cjs/domain.js.map +1 -0
  80. package/node_modules/@hexcore/shared/dist/cjs/hydra-versions.d.ts +279 -0
  81. package/node_modules/@hexcore/shared/dist/cjs/hydra-versions.d.ts.map +1 -0
  82. package/node_modules/@hexcore/shared/dist/cjs/hydra-versions.js +453 -0
  83. package/node_modules/@hexcore/shared/dist/cjs/hydra-versions.js.map +1 -0
  84. package/node_modules/@hexcore/shared/dist/cjs/index.d.ts +7 -0
  85. package/node_modules/@hexcore/shared/dist/cjs/index.d.ts.map +1 -0
  86. package/node_modules/@hexcore/shared/dist/cjs/index.js +23 -0
  87. package/node_modules/@hexcore/shared/dist/cjs/index.js.map +1 -0
  88. package/node_modules/@hexcore/shared/dist/cjs/naming.d.ts +118 -0
  89. package/node_modules/@hexcore/shared/dist/cjs/naming.d.ts.map +1 -0
  90. package/node_modules/@hexcore/shared/dist/cjs/naming.js +103 -0
  91. package/node_modules/@hexcore/shared/dist/cjs/naming.js.map +1 -0
  92. package/node_modules/@hexcore/shared/dist/cjs/offline.d.ts +73 -0
  93. package/node_modules/@hexcore/shared/dist/cjs/offline.d.ts.map +1 -0
  94. package/node_modules/@hexcore/shared/dist/cjs/offline.js +80 -0
  95. package/node_modules/@hexcore/shared/dist/cjs/offline.js.map +1 -0
  96. package/node_modules/@hexcore/shared/dist/cjs/protocol-params.d.ts +79 -0
  97. package/node_modules/@hexcore/shared/dist/cjs/protocol-params.d.ts.map +1 -0
  98. package/node_modules/@hexcore/shared/dist/cjs/protocol-params.js +223 -0
  99. package/node_modules/@hexcore/shared/dist/cjs/protocol-params.js.map +1 -0
  100. package/node_modules/@hexcore/shared/dist/esm/api.js +355 -0
  101. package/node_modules/@hexcore/shared/dist/esm/api.js.map +1 -0
  102. package/node_modules/@hexcore/shared/dist/esm/domain.js +46 -0
  103. package/node_modules/@hexcore/shared/dist/esm/domain.js.map +1 -0
  104. package/node_modules/@hexcore/shared/dist/esm/hydra-versions.js +441 -0
  105. package/node_modules/@hexcore/shared/dist/esm/hydra-versions.js.map +1 -0
  106. package/node_modules/@hexcore/shared/dist/esm/index.js +7 -0
  107. package/node_modules/@hexcore/shared/dist/esm/index.js.map +1 -0
  108. package/node_modules/@hexcore/shared/dist/esm/naming.js +95 -0
  109. package/node_modules/@hexcore/shared/dist/esm/naming.js.map +1 -0
  110. package/node_modules/@hexcore/shared/dist/esm/offline.js +75 -0
  111. package/node_modules/@hexcore/shared/dist/esm/offline.js.map +1 -0
  112. package/node_modules/@hexcore/shared/dist/esm/package.json +3 -0
  113. package/node_modules/@hexcore/shared/dist/esm/protocol-params.js +217 -0
  114. package/node_modules/@hexcore/shared/dist/esm/protocol-params.js.map +1 -0
  115. package/node_modules/@hexcore/shared/package.json +15 -0
  116. package/package.json +67 -0
  117. package/web/200.html +23 -0
  118. package/web/404.html +23 -0
  119. package/web/_nuxt/2MxohCD-.js +1 -0
  120. package/web/_nuxt/4pFXjB_u.js +1 -0
  121. package/web/_nuxt/B-v0dEQX.js +1 -0
  122. package/web/_nuxt/B4yE3U25.js +1 -0
  123. package/web/_nuxt/BFh8Ai0L.js +1 -0
  124. package/web/_nuxt/BgPn4NJH.js +1 -0
  125. package/web/_nuxt/Bj1xviSh.js +1 -0
  126. package/web/_nuxt/BnotlrL7.js +1 -0
  127. package/web/_nuxt/C1YRg2ic.js +1 -0
  128. package/web/_nuxt/CGD7MYQH.js +1 -0
  129. package/web/_nuxt/CQcG7Bu4.js +1 -0
  130. package/web/_nuxt/CS3KqpH_.js +1 -0
  131. package/web/_nuxt/CT-yt694.js +1 -0
  132. package/web/_nuxt/CZK6xUH-.js +1 -0
  133. package/web/_nuxt/CcdyYRYz.js +1 -0
  134. package/web/_nuxt/CePNTU1S.js +1 -0
  135. package/web/_nuxt/CgPLsCeU.js +5 -0
  136. package/web/_nuxt/CkCrahXt.js +1 -0
  137. package/web/_nuxt/CnOqDT9k.js +3 -0
  138. package/web/_nuxt/CqsSss-D.js +1 -0
  139. package/web/_nuxt/Cr8dL64Q.js +1 -0
  140. package/web/_nuxt/D3CwzwU0.js +1 -0
  141. package/web/_nuxt/DDANn6-H.js +1 -0
  142. package/web/_nuxt/DDl9uKIA.js +1 -0
  143. package/web/_nuxt/DL9i0ayn.js +1 -0
  144. package/web/_nuxt/DLNoK9BC.js +1 -0
  145. package/web/_nuxt/DLztFeOQ.js +1 -0
  146. package/web/_nuxt/DPihKXdt.js +1 -0
  147. package/web/_nuxt/DXyr6Naa.js +1 -0
  148. package/web/_nuxt/DeDg5p0D.js +1 -0
  149. package/web/_nuxt/DgDlQiDU.js +1 -0
  150. package/web/_nuxt/DyPI7qJE.js +30 -0
  151. package/web/_nuxt/LGfPBi70.js +1 -0
  152. package/web/_nuxt/Onf26W-r.js +1 -0
  153. package/web/_nuxt/QZNQe_OX.js +1 -0
  154. package/web/_nuxt/Y8IJM-iz.js +1 -0
  155. package/web/_nuxt/YUGC0nt0.js +1 -0
  156. package/web/_nuxt/builds/latest.json +1 -0
  157. package/web/_nuxt/builds/meta/7e461629-93e2-4694-b237-6d5c6a85c97c.json +1 -0
  158. package/web/_nuxt/builds/meta/dev.json +1 -0
  159. package/web/_nuxt/entry.BxsAxZxf.css +1 -0
  160. package/web/_nuxt/error-404.XbtAw-qw.css +1 -0
  161. package/web/_nuxt/error-500.CNHVltWM.css +1 -0
  162. package/web/_nuxt/rS90pPZ_.js +1 -0
  163. package/web/_nuxt/rhEiP908.js +1 -0
  164. package/web/_nuxt/vSj9Ec0g.js +1 -0
  165. package/web/_nuxt/woNjBJMN.js +1 -0
  166. package/web/favicon.svg +28 -0
  167. package/web/heads/index.html +23 -0
  168. package/web/heads/new/index.html +23 -0
  169. package/web/index.html +23 -0
  170. package/web/login/index.html +23 -0
  171. package/web/logo.svg +56 -0
  172. package/web/settings/index.html +23 -0
  173. package/web/setup/index.html +23 -0
@@ -0,0 +1,441 @@
1
+ /**
2
+ * Per-version hydra-node argv profiles.
3
+ *
4
+ * hydra-node's flag set moves between releases: 0.22.x has `--blockfrost` and
5
+ * `--network` but neither `--unsynced-period` nor the Blockfrost timeout knobs,
6
+ * which arrived in the 2.x line. An unknown flag aborts hydra-node during
7
+ * option parsing, so the container dies instantly and the head reports a
8
+ * generic "node never became ready" that points nowhere near the real cause.
9
+ *
10
+ * This table is the declared answer for the versions we ship support for: which
11
+ * flags exist, and what values to pass when the operator has not overridden
12
+ * them. Adding a hydra-node release is deliberately a code change — a new entry
13
+ * here plus a bump of HYDRA_NODE_IMAGE — so a version's argv is reviewed and
14
+ * tested rather than guessed at runtime.
15
+ *
16
+ * Images that match no entry (a fork, a `master` tag, a release newer than this
17
+ * build) are not rejected: the control-plane falls back to probing
18
+ * `hydra-node --help`. See capabilities.ts.
19
+ *
20
+ * Lives in shared because the UI lists the same versions in the create form
21
+ * that the control-plane accepts.
22
+ */
23
+ /** Every platform this table distinguishes, for entries that apply to all. */
24
+ export const HOST_PLATFORMS = [
25
+ 'darwin-arm64',
26
+ 'darwin-x64',
27
+ 'linux-arm64',
28
+ 'linux-x64',
29
+ 'unknown',
30
+ ];
31
+ /** True on a platform whose Docker cannot run an amd64 image natively. */
32
+ export function isArm64(platform) {
33
+ return platform === 'darwin-arm64' || platform === 'linux-arm64';
34
+ }
35
+ /**
36
+ * Defects worth warning about, newest first.
37
+ *
38
+ * Add an entry when upstream confirms one that changes whether a version is
39
+ * safe to pin — with the issue link, so the claim is checkable and can be
40
+ * retired when it is fixed.
41
+ */
42
+ export const HYDRA_KNOWN_ISSUES = [
43
+ {
44
+ // No upstream issue: this is how the images are built, not a bug in the
45
+ // node. Our own record carries the source references and the timings.
46
+ url: 'https://github.com/Vtechcom/hexcore-v2/issues/7',
47
+ title: 'The official image is amd64-only and will not run on an arm64 host',
48
+ impact: 'Every image cardano-scaling publishes is built for amd64 alone. On Apple Silicon it ' +
49
+ 'runs under Rosetta, and from 2.2.0 the node forces the whole KZG trusted setup into ' +
50
+ 'memory before it installs a tracer or opens its API socket — under Rosetta blst loses ' +
51
+ 'the CPU paths that make that fast, so the node stalls there printing nothing at all ' +
52
+ 'and the head fails as a plain readiness timeout with no clue in the log. On arm64 ' +
53
+ 'Linux the daemon simply refuses the image unless qemu is installed. Measured: the ' +
54
+ 'warm-up takes 0.47s on an arm64 rebuild of the same source and was never observed to ' +
55
+ 'finish under Rosetta. Use hydra-node 2.3.x (arm64) instead — same code, architecture ' +
56
+ 'fixed — or 2.1.x, which predates the warm-up but carries a double-spend defect.',
57
+ severity: 'blocker',
58
+ /**
59
+ * Keyed on the image and the host, not on the version range, and both
60
+ * halves matter. `aniadev9/hydra-node:2.3.0-arm64` parses as 2.3.0, so a
61
+ * version-range entry would put a blocker on the one image that fixes
62
+ * this; and on an amd64 host there is nothing wrong at all.
63
+ *
64
+ * Both arm64 platforms, even though only one of them fails silently —
65
+ * an image that cannot run is worth saying before someone pins it for
66
+ * the life of a head.
67
+ */
68
+ imagePattern: /(^|\/)cardano-scaling\/hydra-node(:|$)/,
69
+ hostPlatforms: ['darwin-arm64', 'linux-arm64'],
70
+ // The warm-up landed in 8ded45de4 / 016ec6ee2 (2026-05-27), tagged into
71
+ // 2.2.0. 2.1.0 predates it and boots under Rosetta.
72
+ affectedFrom: '2.2.0',
73
+ },
74
+ {
75
+ id: 2629,
76
+ url: 'https://github.com/cardano-scaling/hydra/issues/2629',
77
+ title: 'The same UTxO can end up spendable on both L1 and L2',
78
+ impact: 'After recovering an incremental-commit deposit and side-loading a snapshot, the recovered ' +
79
+ 'UTxO reappears in the L2 ledger while it is also back on L1 — spendable twice. Reported ' +
80
+ 'against 2.1.0 on preprod. Only reachable through incremental commit plus recover, but the ' +
81
+ 'consequence is a double spend, so treat a head that has done both as suspect.',
82
+ severity: 'blocker',
83
+ // Reported against 2.1.0. Incremental commit plus side-load has a
84
+ // different shape before 2.0, so the 0.22 line is not claimed here.
85
+ affectedFrom: '2.0.0',
86
+ fixedIn: '2.2.0',
87
+ },
88
+ {
89
+ id: 2642,
90
+ url: 'https://github.com/cardano-scaling/hydra/issues/2642',
91
+ title: 'Log rotation silently drops pending deposits',
92
+ impact: 'Rotation writes a checkpoint and discards the events behind it, but the replay path drops ' +
93
+ '`pendingDeposits` — so a deposit recorded before a rotation is unrecoverable after a restart ' +
94
+ 'except by hand. This one bites here in particular: every head hexcore creates sets ' +
95
+ '--persistence-rotate-after, so rotation is not a rare event.',
96
+ severity: 'blocker',
97
+ // The `Checkpoint` event and `aggregateNodeState` the issue points at
98
+ // are 2.x head logic.
99
+ affectedFrom: '2.0.0',
100
+ fixedIn: '2.3.0',
101
+ },
102
+ {
103
+ id: 2477,
104
+ url: 'https://github.com/cardano-scaling/hydra/issues/2477',
105
+ title: 'hydra-node crashes when Blockfrost rate-limits or resets the connection',
106
+ impact: 'A 403 from Blockfrost — which is what its rate limit returns — or a dropped connection ' +
107
+ 'kills the node outright. It does not retry and does not come back, so the head stays down ' +
108
+ 'until someone restarts it. Nodes sharing one project id hit the rate limit soonest.',
109
+ severity: 'blocker',
110
+ // Fixed by PR #2729, merged 2026-07-07; 2.3.0 was cut on 2026-07-15 and
111
+ // is the first release carrying it.
112
+ fixedIn: '2.3.0',
113
+ backends: ['blockfrost'],
114
+ },
115
+ {
116
+ id: 2697,
117
+ url: 'https://github.com/cardano-scaling/hydra/issues/2697',
118
+ title: 'Increment and Decrement validators omit `mustNotMintOrBurn`',
119
+ impact: 'Every other head transition guards against minting or burning; these two did not. Upstream ' +
120
+ 'found no exploit — a burn should still fail indirectly through the value check — but called ' +
121
+ 'that chain of reasoning fragile. Defence in depth rather than a known hole.',
122
+ severity: 'warning',
123
+ // Hydra.Contract.Head as it stands in the 2.x scripts; 0.22 ships
124
+ // different validators entirely.
125
+ affectedFrom: '2.0.0',
126
+ fixedIn: '2.2.0',
127
+ },
128
+ ];
129
+ /**
130
+ * Numeric version from an image tag, or null when it is not a release tag
131
+ * (`master`, a fork, a digest). Pre-release suffixes are ignored: `2.3.0-rc1`
132
+ * is treated as 2.3.0, which is the right call for "does this carry the fix".
133
+ */
134
+ export function parseVersionTag(tag) {
135
+ const match = /^v?(\d+)\.(\d+)(?:\.(\d+))?/.exec(tag);
136
+ if (!match)
137
+ return null;
138
+ return [Number(match[1]), Number(match[2]), Number(match[3] ?? 0)];
139
+ }
140
+ /** True when `tag` names a release strictly older than `other`. */
141
+ export function isVersionBefore(tag, other) {
142
+ const a = parseVersionTag(tag);
143
+ const b = parseVersionTag(other);
144
+ if (!a || !b)
145
+ return false;
146
+ for (let i = 0; i < 3; i++) {
147
+ if (a[i] !== b[i])
148
+ return a[i] < b[i];
149
+ }
150
+ return false;
151
+ }
152
+ /**
153
+ * Known issues that apply to an image, optionally narrowed to one backend.
154
+ *
155
+ * An unparseable tag yields nothing rather than everything: we genuinely do not
156
+ * know what a `master` build contains, and warning about every open issue on a
157
+ * version that may well have the fix is noise that trains people to ignore it.
158
+ */
159
+ export function knownIssuesFor(image, backend, platform = 'unknown') {
160
+ const tag = imageTag(image);
161
+ if (!tag || !parseVersionTag(tag))
162
+ return [];
163
+ return HYDRA_KNOWN_ISSUES.filter(issue => {
164
+ if (issue.fixedIn && !isVersionBefore(tag, issue.fixedIn))
165
+ return false;
166
+ if (issue.affectedFrom && isVersionBefore(tag, issue.affectedFrom))
167
+ return false;
168
+ if (backend && issue.backends && !issue.backends.includes(backend))
169
+ return false;
170
+ if (issue.imagePattern && !issue.imagePattern.test(image))
171
+ return false;
172
+ /**
173
+ * A platform-specific issue is hidden only when the host is known to be
174
+ * one it does not affect. `unknown` still shows it: a warning someone
175
+ * does not need is a smaller failure than a head that never boots and
176
+ * says nothing about why.
177
+ */
178
+ if (issue.hostPlatforms && platform !== 'unknown' && !issue.hostPlatforms.includes(platform))
179
+ return false;
180
+ return true;
181
+ });
182
+ }
183
+ /**
184
+ * Newest first — `findVersionProfile` returns the first match, so a more
185
+ * specific pattern must come before a broader one.
186
+ */
187
+ export const HYDRA_VERSION_PROFILES = [
188
+ /**
189
+ * 2.3.0 rebuilt for arm64 — the same source, the architecture fixed.
190
+ *
191
+ * First in the list because `findVersionProfile` takes the first match and
192
+ * `2.3.0-arm64` also satisfies the 2.3 pattern below.
193
+ *
194
+ * It exists because upstream publishes amd64 only, and from 2.2.0 the node
195
+ * forces the KZG trusted setup into memory before it installs a tracer —
196
+ * under Rosetta that never finishes and prints nothing while failing. Native
197
+ * on arm64 the same warm-up takes 0.47s. See Vtechcom/hexcore-v2#7 for the
198
+ * measurements and docs/FIELD_NOTES.md for how they were taken.
199
+ *
200
+ * The flags are 2.3.0's because the code IS 2.3.0; nothing here was probed
201
+ * separately, and nothing needs to be.
202
+ *
203
+ * **This is a personal Docker Hub account, not one this project controls**,
204
+ * and recommending it makes that a supply-chain dependency for whoever takes
205
+ * the recommendation. It is offered anyway because the alternative on Apple
206
+ * Silicon is a version with a known double spend, and because it is
207
+ * reproducible: `tagPattern` matches the TAG, so anyone who rebuilds 2.3.0
208
+ * themselves and pushes `you/hydra-node:2.3.0-arm64` lands on this exact
209
+ * profile. Replace it the moment an image we own, or a multi-arch upstream
210
+ * one, exists.
211
+ */
212
+ {
213
+ id: '2.3-arm64',
214
+ label: 'hydra-node 2.3.x (arm64)',
215
+ image: 'aniadev9/hydra-node:2.3.0-arm64',
216
+ tagPattern: /^2\.3(\.\d+)?-arm64$/,
217
+ flags: {
218
+ unsyncedPeriod: true,
219
+ blockfrostTimeouts: true,
220
+ network: true,
221
+ blockfrost: true,
222
+ offline: true,
223
+ },
224
+ args: {
225
+ unsyncedPeriod: 180,
226
+ blockfrostQueryTimeout: 30,
227
+ blockfrostRetryTimeout: 300,
228
+ extraArgs: [],
229
+ },
230
+ summary: '2.3.0 rebuilt for arm64. Identical code and flags, but it boots natively on Apple ' +
231
+ 'Silicon instead of stalling under Rosetta. Community-built image.',
232
+ /**
233
+ * macOS on Apple Silicon only, and not arm64 Linux — which the image
234
+ * would also run on.
235
+ *
236
+ * The narrowing is about what happens when we say nothing. On Docker
237
+ * Desktop the amd64 image *starts* and then stalls in silence, so an
238
+ * operator with no recommendation is left with a head that failed for
239
+ * no visible reason: that is worth spending a third-party image on. On
240
+ * arm64 Linux the daemon rejects the image immediately and says exactly
241
+ * why, so the operator can see the problem and choose — including by
242
+ * rebuilding it themselves, which the known-issue text points at.
243
+ *
244
+ * Pointing people at an account this project does not own is a cost.
245
+ * It is paid where it buys the most and nowhere else.
246
+ */
247
+ recommendedOn: ['darwin-arm64'],
248
+ },
249
+ {
250
+ id: '2.3',
251
+ label: 'hydra-node 2.3.x',
252
+ image: 'ghcr.io/cardano-scaling/hydra-node:2.3.0',
253
+ tagPattern: /^2\.3(\.|-|$)/,
254
+ flags: {
255
+ unsyncedPeriod: true,
256
+ blockfrostTimeouts: true,
257
+ network: true,
258
+ blockfrost: true,
259
+ offline: true,
260
+ },
261
+ args: {
262
+ // 180s is upstream's tested value: it clears Blockfrost's 50-80s tip
263
+ // drift while still catching a genuinely stalled node. See argv.ts
264
+ // for why the node's own default (half the contestation period) is
265
+ // too tight on this backend.
266
+ unsyncedPeriod: 180,
267
+ blockfrostQueryTimeout: 30,
268
+ blockfrostRetryTimeout: 300,
269
+ extraArgs: [],
270
+ },
271
+ summary: 'Full Blockfrost drift tolerance. No commit phase (ADR-33), SQLite event store.',
272
+ /**
273
+ * Upstream's own build, and the default everywhere except macOS on
274
+ * Apple Silicon. `unknown` gets it too: when we cannot tell what the
275
+ * machine is, the image published by the project is more defensible
276
+ * than one rebuilt by an individual.
277
+ *
278
+ * `linux-arm64` is in this list knowingly. The image will not run there
279
+ * either — but the daemon says so immediately and by name, and that is
280
+ * a better place to leave someone than pointed at a personal registry.
281
+ * The known-issue entry still fires and names the alternative.
282
+ */
283
+ recommendedOn: ['darwin-x64', 'linux-x64', 'linux-arm64', 'unknown'],
284
+ },
285
+ /**
286
+ * 2.1 is the one concession to machines that cannot run 2.3.0's image.
287
+ *
288
+ * Every hydra-node image is amd64-only, and from 2.2.0 on the node forces
289
+ * the entire KZG trusted setup into memory before it opens a socket or
290
+ * installs a tracer — under Rosetta that outlasts the readiness budget
291
+ * without printing a single line, so the node simply never greets. 2.1.0
292
+ * predates the warm-up and is the only version measured to boot on Apple
293
+ * Silicon. See docs/FIELD_NOTES.md for how that was established.
294
+ *
295
+ * 2.2 is deliberately NOT offered. It carries the same warm-up, so it
296
+ * solves nothing 2.3 does not, while still carrying two blockers 2.3 fixed
297
+ * — an option whose only distinguishing feature is being worse. Pinning it
298
+ * by hand still works, and HYDRA_KNOWN_ISSUES still warns, because that
299
+ * matches by version range rather than by profile.
300
+ *
301
+ * The real answer for arm64 is a rebuilt 2.3 image, which the create form
302
+ * takes as a custom reference. `tagPattern` matches the TAG, so a private
303
+ * `you/hydra-node:2.3.0` resolves to the 2.3 profile with no probe needed.
304
+ *
305
+ * Flags below were read from `hydra-node --help` on the actual image, not
306
+ * inferred from the version line: 2.1.0 accepts everything 2.3.0 does,
307
+ * including the offline branch and the Blockfrost timeouts.
308
+ */
309
+ {
310
+ id: '2.1',
311
+ label: 'hydra-node 2.1.x',
312
+ image: 'ghcr.io/cardano-scaling/hydra-node:2.1.0',
313
+ tagPattern: /^2\.1(\.|-|$)/,
314
+ flags: {
315
+ unsyncedPeriod: true,
316
+ blockfrostTimeouts: true,
317
+ network: true,
318
+ blockfrost: true,
319
+ offline: true,
320
+ },
321
+ args: {
322
+ unsyncedPeriod: 180,
323
+ blockfrostQueryTimeout: 30,
324
+ blockfrostRetryTimeout: 300,
325
+ extraArgs: [],
326
+ },
327
+ summary: 'Oldest 2.x with the full flag set. Carries a double-spend defect fixed in 2.2.0 — use it ' +
328
+ 'for testing where 2.3.0 will not run, not for a head holding anything real.',
329
+ },
330
+ {
331
+ id: '0.22',
332
+ label: 'hydra-node 0.22.x',
333
+ image: 'ghcr.io/cardano-scaling/hydra-node:0.22.3',
334
+ tagPattern: /^0\.22(\.|-|$)/,
335
+ flags: {
336
+ // Neither the unsynced period nor the Blockfrost timeouts exist on
337
+ // this line; passing them kills the container at startup.
338
+ unsyncedPeriod: false,
339
+ blockfrostTimeouts: false,
340
+ network: true,
341
+ blockfrost: true,
342
+ // Offline mode predates both lines, so it is the one advanced
343
+ // capability 0.22.x shares with 2.x.
344
+ offline: true,
345
+ },
346
+ args: {
347
+ // Carried for completeness — the flags above gate them out of argv.
348
+ unsyncedPeriod: 180,
349
+ blockfrostQueryTimeout: 30,
350
+ blockfrostRetryTimeout: 300,
351
+ extraArgs: [],
352
+ },
353
+ summary: 'Legacy protocol (commit phase, older scripts). Runs with a 60s unsynced budget ' +
354
+ 'inside Blockfrost’s 50-80s drift band — prefer 2.3.x on Blockfrost.',
355
+ },
356
+ ];
357
+ /**
358
+ * Values used when an image matches no profile, so an unrecognised image still
359
+ * boots with the same tuning the 2.x line gets. Whether the flags are actually
360
+ * passed is decided separately, by probing the image.
361
+ */
362
+ export const FALLBACK_HYDRA_ARGS = {
363
+ unsyncedPeriod: 180,
364
+ blockfrostQueryTimeout: 30,
365
+ blockfrostRetryTimeout: 300,
366
+ extraArgs: [],
367
+ };
368
+ /**
369
+ * The tag part of an image reference.
370
+ *
371
+ * Written by hand rather than with a split(':') because both `localhost:5000/x`
372
+ * (registry port, no tag) and `x@sha256:…` (digest, no tag) would otherwise
373
+ * report a tag that does not exist and match the wrong profile.
374
+ */
375
+ export function imageTag(image) {
376
+ const at = image.indexOf('@');
377
+ const ref = at === -1 ? image : image.slice(0, at);
378
+ const colon = ref.indexOf(':', ref.lastIndexOf('/') + 1);
379
+ return colon === -1 ? '' : ref.slice(colon + 1);
380
+ }
381
+ /** The profile claiming this image, or undefined when it must be probed. */
382
+ export function findVersionProfile(image) {
383
+ const tag = imageTag(image);
384
+ if (!tag)
385
+ return undefined;
386
+ return HYDRA_VERSION_PROFILES.find(p => p.tagPattern.test(tag));
387
+ }
388
+ /**
389
+ * Merge, in order: explicit operator override, then the version's own default,
390
+ * then the fallback. An override is deliberately allowed to win over the
391
+ * profile — someone who set HYDRA_UNSYNCED_PERIOD for a reason should not have
392
+ * it silently reverted by a version bump.
393
+ */
394
+ export function resolveHydraArgs(profile, overrides = {}) {
395
+ const base = profile?.args ?? FALLBACK_HYDRA_ARGS;
396
+ return {
397
+ unsyncedPeriod: overrides.unsyncedPeriod ?? base.unsyncedPeriod,
398
+ blockfrostQueryTimeout: overrides.blockfrostQueryTimeout ?? base.blockfrostQueryTimeout,
399
+ blockfrostRetryTimeout: overrides.blockfrostRetryTimeout ?? base.blockfrostRetryTimeout,
400
+ extraArgs: [...base.extraArgs],
401
+ };
402
+ }
403
+ export function toVersionInfo(profile, platform = 'unknown') {
404
+ return {
405
+ id: profile.id,
406
+ label: profile.label,
407
+ image: profile.image,
408
+ summary: profile.summary,
409
+ recommended: profile.recommendedOn?.includes(platform) ?? false,
410
+ flags: { ...profile.flags },
411
+ args: { ...profile.args, extraArgs: [...profile.args.extraArgs] },
412
+ // `imagePattern` is a RegExp and would cross the wire as `{}` — the same
413
+ // trap `tagPattern` sets on the profile. It has done its job by the time
414
+ // an issue is in this list, so it is dropped rather than shipped broken.
415
+ knownIssues: knownIssuesFor(profile.image, undefined, platform).map(stripPatterns),
416
+ };
417
+ }
418
+ function stripPatterns(issue) {
419
+ const { imagePattern: _dropped, ...rest } = issue;
420
+ return rest;
421
+ }
422
+ /**
423
+ * Map Node's `process.platform` and `process.arch` onto the platforms this
424
+ * table distinguishes.
425
+ *
426
+ * Anything outside the four becomes `unknown` rather than being carried
427
+ * through: the table only holds evidence about those, and a claim about a
428
+ * FreeBSD s390x host is one nobody has checked.
429
+ */
430
+ export function toHostPlatform(os, arch) {
431
+ if (os === 'darwin' && arch === 'arm64')
432
+ return 'darwin-arm64';
433
+ if (os === 'darwin' && arch === 'x64')
434
+ return 'darwin-x64';
435
+ if (os === 'linux' && arch === 'arm64')
436
+ return 'linux-arm64';
437
+ if (os === 'linux' && arch === 'x64')
438
+ return 'linux-x64';
439
+ return 'unknown';
440
+ }
441
+ //# sourceMappingURL=hydra-versions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hydra-versions.js","sourceRoot":"","sources":["../../src/hydra-versions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export * from './domain.js';
2
+ export * from './api.js';
3
+ export * from './naming.js';
4
+ export * from './hydra-versions.js';
5
+ export * from './offline.js';
6
+ export * from './protocol-params.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Deterministic naming + path conventions.
3
+ *
4
+ * v1 derived container names from the DB primary key of the node, which meant
5
+ * you could not tell which head a container belonged to without a DB lookup,
6
+ * and recreating a head produced unpredictable names. v2 names everything from
7
+ * (headId, nodeIndex) so the whole layout is reproducible and greppable.
8
+ */
9
+ export const CONTAINER_PREFIX = 'hexcore';
10
+ export const DOCKER_NETWORK = 'hexcore-net';
11
+ export const LABEL_MANAGED = 'io.hexcore.managed';
12
+ export const LABEL_HEAD_ID = 'io.hexcore.head-id';
13
+ export const LABEL_NODE_ID = 'io.hexcore.node-id';
14
+ export const LABEL_NODE_INDEX = 'io.hexcore.node-index';
15
+ /**
16
+ * Which Hexcore installation owns this container.
17
+ *
18
+ * `LABEL_MANAGED` says "Hexcore made this" and nothing more, so it cannot tell
19
+ * two installations apart — and more than one is normal: a developer running
20
+ * the repo has one state dir, an `npm i -g hexcore` on the same machine has
21
+ * another, and both talk to the same Docker daemon. A bulk operation matched on
22
+ * `LABEL_MANAGED` alone therefore reaches across installations, which is how
23
+ * `hexcore clean` destroyed the containers of a head it had never heard of.
24
+ *
25
+ * The value is a random id kept in the state dir, so it identifies the state
26
+ * dir rather than the machine, the user or the checkout.
27
+ */
28
+ export const LABEL_INSTALL = 'io.hexcore.install';
29
+ /** e.g. head 3, index 0 -> `hexcore-h3-n0` (also the Hydra --node-id and DNS name). */
30
+ export function nodeContainerName(headId, nodeIndex) {
31
+ return `${CONTAINER_PREFIX}-h${headId}-n${nodeIndex}`;
32
+ }
33
+ export function headDirName(headId) {
34
+ return `head-${headId}`;
35
+ }
36
+ /** Layout under the state dir: heads/head-1/{keys,persistence,...} */
37
+ export const headPaths = (stateDir, headId) => {
38
+ const root = `${trimSlash(stateDir)}/heads/${headDirName(headId)}`;
39
+ return {
40
+ root,
41
+ keys: `${root}/keys`,
42
+ persistence: `${root}/persistence`,
43
+ protocolParameters: `${root}/protocol-parameters.json`,
44
+ /**
45
+ * Offline mode only. `--initial-utxo` is the L2 ledger's entire
46
+ * starting state and `--ledger-genesis` the simulated L1's block-time
47
+ * parameters; both are written at start, next to everything else the
48
+ * head owns, so deleting the head takes them with it.
49
+ */
50
+ initialUtxo: `${root}/initial-utxo.json`,
51
+ ledgerGenesis: `${root}/shelley-genesis.json`,
52
+ /**
53
+ * Written by v2 up to the per-node keys change, and still removed on
54
+ * every start so a stale project id does not sit on disk unused.
55
+ */
56
+ legacyBlockfrostToken: `${root}/blockfrost.txt`,
57
+ /**
58
+ * One token file per node: hydra-node takes `--blockfrost FILE`, so a
59
+ * per-node key can only be expressed as a per-node file. Nodes sharing
60
+ * a key simply get the same contents written to each of theirs.
61
+ */
62
+ nodeBlockfrostToken: (nodeIndex) => `${root}/blockfrost-n${nodeIndex}.txt`,
63
+ nodePersistence: (nodeIndex) => `${root}/persistence/n${nodeIndex}`,
64
+ nodeKeys: (nodeIndex) => ({
65
+ hydraSk: `${root}/keys/n${nodeIndex}.hydra.sk`,
66
+ hydraVk: `${root}/keys/n${nodeIndex}.hydra.vk`,
67
+ cardanoSk: `${root}/keys/n${nodeIndex}.cardano.sk`,
68
+ cardanoVk: `${root}/keys/n${nodeIndex}.cardano.vk`,
69
+ }),
70
+ };
71
+ };
72
+ /**
73
+ * Same layout as seen from inside the container, where the state dir is always
74
+ * bind-mounted at /data. Keeping the two in lockstep avoids the class of bug
75
+ * where a host path leaks into a container argument.
76
+ */
77
+ export const CONTAINER_DATA_DIR = '/data';
78
+ export const containerHeadPaths = (headId) => headPaths(CONTAINER_DATA_DIR, headId);
79
+ function trimSlash(p) {
80
+ return p.replace(/\/+$/, '');
81
+ }
82
+ /**
83
+ * Port allocation. Each node gets a contiguous triple so a head of N nodes
84
+ * occupies a predictable, non-overlapping range:
85
+ * api = base + slot*10
86
+ * p2p = base + slot*10 + 1
87
+ * monitoring = base + slot*10 + 2
88
+ */
89
+ export const PORT_BASE = 14000;
90
+ export const PORTS_PER_NODE = 10;
91
+ export function portsForSlot(slot, base = PORT_BASE) {
92
+ const start = base + slot * PORTS_PER_NODE;
93
+ return { api: start, p2p: start + 1, monitoring: start + 2 };
94
+ }
95
+ //# sourceMappingURL=naming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.js","sourceRoot":"","sources":["../../src/naming.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,SAAS,CAAC;AAC1C,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAAC;AAE5C,MAAM,CAAC,MAAM,aAAa,GAAG,oBAAoB,CAAC;AAClD,MAAM,CAAC,MAAM,aAAa,GAAG,oBAAoB,CAAC;AAClD,MAAM,CAAC,MAAM,aAAa,GAAG,oBAAoB,CAAC;AAClD,MAAM,CAAC,MAAM,gBAAgB,GAAG,uBAAuB,CAAC;AACxD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,oBAAoB,CAAC;AAElD,uFAAuF;AACvF,MAAM,UAAU,iBAAiB,CAAC,MAAc,EAAE,SAAiB;IAC/D,OAAO,GAAG,gBAAgB,KAAK,MAAM,KAAK,SAAS,EAAE,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAc;IACtC,OAAO,QAAQ,MAAM,EAAE,CAAC;AAC5B,CAAC;AAED,sEAAsE;AACtE,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,QAAgB,EAAE,MAAc,EAAE,EAAE;IAC1D,MAAM,IAAI,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,UAAU,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;IACnE,OAAO;QACH,IAAI;QACJ,IAAI,EAAE,GAAG,IAAI,OAAO;QACpB,WAAW,EAAE,GAAG,IAAI,cAAc;QAClC,kBAAkB,EAAE,GAAG,IAAI,2BAA2B;QACtD;;;;;WAKG;QACH,WAAW,EAAE,GAAG,IAAI,oBAAoB;QACxC,aAAa,EAAE,GAAG,IAAI,uBAAuB;QAC7C;;;WAGG;QACH,qBAAqB,EAAE,GAAG,IAAI,iBAAiB;QAC/C;;;;WAIG;QACH,mBAAmB,EAAE,CAAC,SAAiB,EAAE,EAAE,CAAC,GAAG,IAAI,gBAAgB,SAAS,MAAM;QAClF,eAAe,EAAE,CAAC,SAAiB,EAAE,EAAE,CAAC,GAAG,IAAI,iBAAiB,SAAS,EAAE;QAC3E,QAAQ,EAAE,CAAC,SAAiB,EAAE,EAAE,CAAC,CAAC;YAC9B,OAAO,EAAE,GAAG,IAAI,UAAU,SAAS,WAAW;YAC9C,OAAO,EAAE,GAAG,IAAI,UAAU,SAAS,WAAW;YAC9C,SAAS,EAAE,GAAG,IAAI,UAAU,SAAS,aAAa;YAClD,SAAS,EAAE,GAAG,IAAI,UAAU,SAAS,aAAa;SACrD,CAAC;KACL,CAAC;AACN,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAC1C,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAAc,EAAE,EAAE,CAAC,SAAS,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;AAE5F,SAAS,SAAS,CAAC,CAAS;IACxB,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACjC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,CAAC;AAC/B,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AAQjC,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,IAAI,GAAG,SAAS;IACvD,MAAM,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,cAAc,CAAC;IAC3C,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC,EAAE,UAAU,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC;AACjE,CAAC"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Offline mode.
3
+ *
4
+ * hydra-node can run with its layer-1 interface disabled entirely: no chain to
5
+ * observe, no scripts to publish, no funds to commit. The head opens
6
+ * immediately with a UTxO set handed to it on disk, which makes it the fastest
7
+ * way to develop against the Hydra API — and the only way to run one without a
8
+ * Blockfrost key or a cardano-node socket.
9
+ *
10
+ * The flags are mutually exclusive with the online ones (`--offline-head-seed`
11
+ * is a different branch of hydra-node's option parser than
12
+ * `--mainnet`/`--node-socket`/`--blockfrost`), so an offline head is a distinct
13
+ * chain backend here rather than a checkbox on an online one. Passing an online
14
+ * flag alongside `--offline-head-seed` aborts option parsing and the container
15
+ * dies before it logs anything useful.
16
+ *
17
+ * Reference layout this mirrors: infra/preprod-offline in the graveyard repo —
18
+ * `--offline-head-seed` + `--initial-utxo` + `--ledger-genesis`, no
19
+ * contestation or deposit period, single node.
20
+ */
21
+ /** `--offline-head-seed` takes 32 bytes as hex. */
22
+ export const OFFLINE_HEAD_SEED_BYTES = 32;
23
+ /**
24
+ * How many nodes an offline head may run.
25
+ *
26
+ * Offline mode is multi-party: `--peer` and `--hydra-verification-key` sit
27
+ * outside hydra-node's chain-config group, so the nodes form a Head over the
28
+ * same network layer an online head uses. Only the Cardano key options are
29
+ * online-only, and offline peers authorise nothing on chain, so they are simply
30
+ * not passed.
31
+ *
32
+ * The cap is lower than an online head's ten because every node runs on this
33
+ * one machine with no L1 to spread the load over, and each brings an embedded
34
+ * etcd. Five is enough for the multi-party flows worth rehearsing offline
35
+ * without turning a laptop into the bottleneck under test.
36
+ */
37
+ export const MAX_OFFLINE_NODES = 5;
38
+ /** Lovelace seeded to each node's own address when no UTxO file is supplied. */
39
+ export const DEFAULT_OFFLINE_SEED_LOVELACE = 20_000_000_000;
40
+ /** A hex seed is exactly 32 bytes, lowercase or upper. */
41
+ export const offlineHeadSeedPattern = /^[0-9a-fA-F]{64}$/;
42
+ /**
43
+ * Seed derived from the head id when the operator names none.
44
+ *
45
+ * It only has to be stable and unique per head: hydra-node derives the offline
46
+ * head id from it, and every node of the same head must agree. Deriving it from
47
+ * the row id gives both properties for free and keeps two offline heads on one
48
+ * machine from colliding — which they would if everyone kept the `…0001` from
49
+ * the reference config.
50
+ */
51
+ export function defaultOfflineHeadSeed(headId) {
52
+ return headId.toString(16).padStart(OFFLINE_HEAD_SEED_BYTES * 2, '0');
53
+ }
54
+ /**
55
+ * The `--initial-utxo` file: the L2 ledger's entire starting state.
56
+ *
57
+ * Keys are TxIn references that no L1 transaction produced — offline mode never
58
+ * checks them against a chain. A zero tx id with one output index per node is
59
+ * what the reference config uses, and it keeps the file readable.
60
+ *
61
+ * Addresses are the nodes' own generated (or imported) Cardano addresses, so
62
+ * the operator already holds the signing keys for everything in the head.
63
+ */
64
+ export function buildInitialUtxo(entries) {
65
+ const txId = '0'.repeat(64);
66
+ const utxo = {};
67
+ entries.forEach((entry, index) => {
68
+ utxo[`${txId}#${index}`] = {
69
+ address: entry.address,
70
+ value: { lovelace: entry.lovelace },
71
+ };
72
+ });
73
+ return utxo;
74
+ }
75
+ //# sourceMappingURL=offline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offline.js","sourceRoot":"","sources":["../../src/offline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,mDAAmD;AACnD,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAE1C;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAEnC,gFAAgF;AAChF,MAAM,CAAC,MAAM,6BAA6B,GAAG,cAAc,CAAC;AAE5D,0DAA0D;AAC1D,MAAM,CAAC,MAAM,sBAAsB,GAAG,mBAAmB,CAAC;AAE1D;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAc;IACjD,OAAO,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,uBAAuB,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;AAC1E,CAAC;AAaD;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAA2B;IACxD,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC5B,MAAM,IAAI,GAA4B,EAAE,CAAC;IACzC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QAC7B,IAAI,CAAC,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC,GAAG;YACvB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE;SACtC,CAAC;IACN,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,CAAC;AAChB,CAAC"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }