@geohar/un-bien 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +726 -0
  3. package/dist/actions/handlers.d.ts +77 -0
  4. package/dist/actions/handlers.js +26 -0
  5. package/dist/actions/handlers.js.map +1 -0
  6. package/dist/actions/registry.d.ts +39 -0
  7. package/dist/actions/registry.js +62 -0
  8. package/dist/actions/registry.js.map +1 -0
  9. package/dist/bin/supervisord.d.ts +2 -0
  10. package/dist/bin/supervisord.js +86 -0
  11. package/dist/bin/supervisord.js.map +1 -0
  12. package/dist/config.d.ts +84 -0
  13. package/dist/config.js +115 -0
  14. package/dist/config.js.map +1 -0
  15. package/dist/daemon/client.d.ts +20 -0
  16. package/dist/daemon/client.js +131 -0
  17. package/dist/daemon/client.js.map +1 -0
  18. package/dist/daemon/control_protocol.d.ts +176 -0
  19. package/dist/daemon/control_protocol.js +63 -0
  20. package/dist/daemon/control_protocol.js.map +1 -0
  21. package/dist/daemon/cron_log.d.ts +45 -0
  22. package/dist/daemon/cron_log.js +71 -0
  23. package/dist/daemon/cron_log.js.map +1 -0
  24. package/dist/daemon/cron_registry.d.ts +80 -0
  25. package/dist/daemon/cron_registry.js +198 -0
  26. package/dist/daemon/cron_registry.js.map +1 -0
  27. package/dist/daemon/id.d.ts +24 -0
  28. package/dist/daemon/id.js +36 -0
  29. package/dist/daemon/id.js.map +1 -0
  30. package/dist/daemon/install.d.ts +170 -0
  31. package/dist/daemon/install.js +603 -0
  32. package/dist/daemon/install.js.map +1 -0
  33. package/dist/daemon/registry.d.ts +63 -0
  34. package/dist/daemon/registry.js +153 -0
  35. package/dist/daemon/registry.js.map +1 -0
  36. package/dist/daemon/rpc_child.d.ts +194 -0
  37. package/dist/daemon/rpc_child.js +419 -0
  38. package/dist/daemon/rpc_child.js.map +1 -0
  39. package/dist/daemon/supervisor.d.ts +93 -0
  40. package/dist/daemon/supervisor.js +666 -0
  41. package/dist/daemon/supervisor.js.map +1 -0
  42. package/dist/extension_ui_bridge.d.ts +26 -0
  43. package/dist/extension_ui_bridge.js +341 -0
  44. package/dist/extension_ui_bridge.js.map +1 -0
  45. package/dist/index.d.ts +197 -0
  46. package/dist/index.js +5750 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/mcp/mesh_result.d.ts +10 -0
  49. package/dist/mcp/mesh_result.js +42 -0
  50. package/dist/mcp/mesh_result.js.map +1 -0
  51. package/dist/mcp/mesh_server.d.ts +16 -0
  52. package/dist/mcp/mesh_server.js +373 -0
  53. package/dist/mcp/mesh_server.js.map +1 -0
  54. package/dist/mesh/canonical.d.ts +30 -0
  55. package/dist/mesh/canonical.js +63 -0
  56. package/dist/mesh/canonical.js.map +1 -0
  57. package/dist/mesh/client.d.ts +18 -0
  58. package/dist/mesh/client.js +127 -0
  59. package/dist/mesh/client.js.map +1 -0
  60. package/dist/mesh/encoding.d.ts +38 -0
  61. package/dist/mesh/encoding.js +217 -0
  62. package/dist/mesh/encoding.js.map +1 -0
  63. package/dist/mesh/self_revoke.d.ts +73 -0
  64. package/dist/mesh/self_revoke.js +407 -0
  65. package/dist/mesh/self_revoke.js.map +1 -0
  66. package/dist/mesh/siblings.d.ts +49 -0
  67. package/dist/mesh/siblings.js +159 -0
  68. package/dist/mesh/siblings.js.map +1 -0
  69. package/dist/mesh/types.d.ts +34 -0
  70. package/dist/mesh/types.js +11 -0
  71. package/dist/mesh/types.js.map +1 -0
  72. package/dist/mesh/verify.d.ts +17 -0
  73. package/dist/mesh/verify.js +86 -0
  74. package/dist/mesh/verify.js.map +1 -0
  75. package/dist/pairing/crypto.d.ts +8 -0
  76. package/dist/pairing/crypto.js +22 -0
  77. package/dist/pairing/crypto.js.map +1 -0
  78. package/dist/pairing/qr.d.ts +59 -0
  79. package/dist/pairing/qr.js +127 -0
  80. package/dist/pairing/qr.js.map +1 -0
  81. package/dist/pairing/storage.d.ts +120 -0
  82. package/dist/pairing/storage.js +614 -0
  83. package/dist/pairing/storage.js.map +1 -0
  84. package/dist/panel_bridge.d.ts +15 -0
  85. package/dist/panel_bridge.js +409 -0
  86. package/dist/panel_bridge.js.map +1 -0
  87. package/dist/paths.d.ts +39 -0
  88. package/dist/paths.js +51 -0
  89. package/dist/paths.js.map +1 -0
  90. package/dist/protocol/codec.d.ts +7 -0
  91. package/dist/protocol/codec.js +48 -0
  92. package/dist/protocol/codec.js.map +1 -0
  93. package/dist/protocol/types.d.ts +404 -0
  94. package/dist/protocol/types.js +2 -0
  95. package/dist/protocol/types.js.map +1 -0
  96. package/dist/rooms.d.ts +42 -0
  97. package/dist/rooms.js +78 -0
  98. package/dist/rooms.js.map +1 -0
  99. package/dist/session/bridge.d.ts +37 -0
  100. package/dist/session/bridge.js +134 -0
  101. package/dist/session/bridge.js.map +1 -0
  102. package/dist/session/broker.d.ts +189 -0
  103. package/dist/session/broker.js +527 -0
  104. package/dist/session/broker.js.map +1 -0
  105. package/dist/session/broker_remote.d.ts +74 -0
  106. package/dist/session/broker_remote.js +581 -0
  107. package/dist/session/broker_remote.js.map +1 -0
  108. package/dist/session/cwd_lock.d.ts +33 -0
  109. package/dist/session/cwd_lock.js +127 -0
  110. package/dist/session/cwd_lock.js.map +1 -0
  111. package/dist/session/debug_log.d.ts +3 -0
  112. package/dist/session/debug_log.js +32 -0
  113. package/dist/session/debug_log.js.map +1 -0
  114. package/dist/session/envelope.d.ts +33 -0
  115. package/dist/session/envelope.js +117 -0
  116. package/dist/session/envelope.js.map +1 -0
  117. package/dist/session/global_config.d.ts +33 -0
  118. package/dist/session/global_config.js +73 -0
  119. package/dist/session/global_config.js.map +1 -0
  120. package/dist/session/ipc.d.ts +27 -0
  121. package/dist/session/ipc.js +22 -0
  122. package/dist/session/ipc.js.map +1 -0
  123. package/dist/session/leader_election.d.ts +32 -0
  124. package/dist/session/leader_election.js +108 -0
  125. package/dist/session/leader_election.js.map +1 -0
  126. package/dist/session/local_config.d.ts +67 -0
  127. package/dist/session/local_config.js +193 -0
  128. package/dist/session/local_config.js.map +1 -0
  129. package/dist/session/mesh_node.d.ts +116 -0
  130. package/dist/session/mesh_node.js +596 -0
  131. package/dist/session/mesh_node.js.map +1 -0
  132. package/dist/session/peer.d.ts +139 -0
  133. package/dist/session/peer.js +474 -0
  134. package/dist/session/peer.js.map +1 -0
  135. package/dist/session/peer_inventory.d.ts +13 -0
  136. package/dist/session/peer_inventory.js +48 -0
  137. package/dist/session/peer_inventory.js.map +1 -0
  138. package/dist/session/peer_limits.d.ts +9 -0
  139. package/dist/session/peer_limits.js +24 -0
  140. package/dist/session/peer_limits.js.map +1 -0
  141. package/dist/session/rpc_envelope.d.ts +108 -0
  142. package/dist/session/rpc_envelope.js +221 -0
  143. package/dist/session/rpc_envelope.js.map +1 -0
  144. package/dist/session/rpc_inbound.d.ts +55 -0
  145. package/dist/session/rpc_inbound.js +136 -0
  146. package/dist/session/rpc_inbound.js.map +1 -0
  147. package/dist/session/setup_wizard.d.ts +39 -0
  148. package/dist/session/setup_wizard.js +63 -0
  149. package/dist/session/setup_wizard.js.map +1 -0
  150. package/dist/session/tools.d.ts +24 -0
  151. package/dist/session/tools.js +272 -0
  152. package/dist/session/tools.js.map +1 -0
  153. package/dist/session/wizard.d.ts +13 -0
  154. package/dist/session/wizard.js +20 -0
  155. package/dist/session/wizard.js.map +1 -0
  156. package/dist/transport/peer_channel.d.ts +52 -0
  157. package/dist/transport/peer_channel.js +145 -0
  158. package/dist/transport/peer_channel.js.map +1 -0
  159. package/dist/transport/pi_forward_client.d.ts +29 -0
  160. package/dist/transport/pi_forward_client.js +68 -0
  161. package/dist/transport/pi_forward_client.js.map +1 -0
  162. package/dist/transport/relay_client.d.ts +96 -0
  163. package/dist/transport/relay_client.js +210 -0
  164. package/dist/transport/relay_client.js.map +1 -0
  165. package/dist/ui/footer.d.ts +32 -0
  166. package/dist/ui/footer.js +34 -0
  167. package/dist/ui/footer.js.map +1 -0
  168. package/docs/daemon.md +289 -0
  169. package/package.json +92 -0
  170. package/service-templates/launchd.plist.template +35 -0
  171. package/service-templates/systemd.service.template +19 -0
  172. package/service-templates/task-launcher.vbs.template +10 -0
  173. package/service-templates/task-scheduler.xml.template +38 -0
  174. package/skills/agent-network/SKILL.md +310 -0
@@ -0,0 +1,407 @@
1
+ import { createHash } from "node:crypto";
2
+ import { MeshFetchInvalidResponseError, MeshFetchUnavailableError, } from "./client.js";
3
+ import { bytesEqual, decodeEd25519PublicKey, encodeEd25519PublicKey, publicKeyFingerprint, } from "./encoding.js";
4
+ import { buildTopologySnapshot, } from "./siblings.js";
5
+ import { verifyEnvelope } from "./verify.js";
6
+ const DEFAULT_INTERVAL_MS = 60_000;
7
+ function compareAscii(left, right) {
8
+ return left < right ? -1 : left > right ? 1 : 0;
9
+ }
10
+ function rawOwnerFingerprint(rawOwner) {
11
+ let fingerprintInput;
12
+ if (typeof rawOwner === "string") {
13
+ fingerprintInput = rawOwner;
14
+ }
15
+ else {
16
+ try {
17
+ const serialized = JSON.stringify(rawOwner);
18
+ const type = rawOwner === null ? "null" : typeof rawOwner;
19
+ fingerprintInput = `${type}:${serialized ?? ""}`;
20
+ }
21
+ catch {
22
+ fingerprintInput = `${typeof rawOwner}:unserializable`;
23
+ }
24
+ }
25
+ return createHash("sha256")
26
+ .update(fingerprintInput, "utf8")
27
+ .digest("hex")
28
+ .slice(0, 8);
29
+ }
30
+ function topologyEquals(left, right) {
31
+ if (!left)
32
+ return false;
33
+ if (left.self.pcPubkey !== right.self.pcPubkey ||
34
+ left.self.pcLabel !== right.self.pcLabel ||
35
+ left.self.legacyPcLabel !== right.self.legacyPcLabel ||
36
+ left.siblings.length !== right.siblings.length)
37
+ return false;
38
+ return left.siblings.every((identity, index) => {
39
+ const other = right.siblings[index];
40
+ return (other !== undefined &&
41
+ identity.pcPubkey === other.pcPubkey &&
42
+ identity.pcLabel === other.pcLabel &&
43
+ identity.legacyPcLabel === other.legacyPcLabel);
44
+ });
45
+ }
46
+ export class SelfRevoke {
47
+ client;
48
+ storage;
49
+ myPubkey;
50
+ intervalMs;
51
+ onRevoke;
52
+ onAuthoritativeOwners;
53
+ onTopologyChanged;
54
+ log;
55
+ /**
56
+ * Accepted anti-rollback floor, deliberately independent from pending I/O.
57
+ * https://github.com/jacobaraujo7/remote_pi/issues/73: this in-memory floor
58
+ * resets on process restart, allowing pre-revocation membership replay.
59
+ */
60
+ lastSeenVersion = new Map();
61
+ pendingRevocations = new Map();
62
+ membershipByOwner = new Map();
63
+ previousTopology = null;
64
+ sweepInFlight = null;
65
+ timer = null;
66
+ /** Invalidates authority held by an async sweep when this producer stops/re-pairs. */
67
+ lifecycleGeneration = 0;
68
+ constructor(opts) {
69
+ this.client = opts.client;
70
+ this.storage = opts.storage;
71
+ this.myPubkey = new Uint8Array(opts.myPubkey);
72
+ encodeEd25519PublicKey(this.myPubkey, "self public key");
73
+ this.intervalMs = opts.intervalMs ?? DEFAULT_INTERVAL_MS;
74
+ this.onRevoke = opts.onRevoke;
75
+ this.onAuthoritativeOwners = opts.onAuthoritativeOwners;
76
+ this.onTopologyChanged = opts.onTopologyChanged;
77
+ this.log = opts.log ?? {
78
+ info: (message) => console.info(message),
79
+ warn: (message) => console.warn(message),
80
+ error: (message) => console.error(message),
81
+ };
82
+ }
83
+ start() {
84
+ if (this.timer !== null)
85
+ return;
86
+ void this.checkOnce().catch(() => this.log.error("[mesh] event=self_revoke_sweep_failed"));
87
+ this.timer = setInterval(() => {
88
+ void this.checkOnce().catch(() => this.log.error("[mesh] event=self_revoke_sweep_failed"));
89
+ }, this.intervalMs);
90
+ }
91
+ stop() {
92
+ this.invalidateStorageAuthority();
93
+ if (this.timer !== null) {
94
+ clearInterval(this.timer);
95
+ this.timer = null;
96
+ }
97
+ }
98
+ /** Called before a same-process pairing mutation enters the storage lane. */
99
+ invalidateStorageAuthority() {
100
+ this.lifecycleGeneration += 1;
101
+ }
102
+ /** Schedules one post-mutation authoritative sweep after any stale sweep exits. */
103
+ requestFreshCheck() {
104
+ const prior = this.sweepInFlight;
105
+ if (!prior)
106
+ return this.checkOnce();
107
+ return prior.catch(() => undefined).then(() => this.checkOnce());
108
+ }
109
+ checkOnce() {
110
+ if (this.sweepInFlight)
111
+ return this.sweepInFlight;
112
+ const generation = this.lifecycleGeneration;
113
+ const sweep = this._runSweep(generation).finally(() => {
114
+ if (this.sweepInFlight === sweep)
115
+ this.sweepInFlight = null;
116
+ });
117
+ this.sweepInFlight = sweep;
118
+ return sweep;
119
+ }
120
+ async _runSweep(generation) {
121
+ let snapshot;
122
+ try {
123
+ snapshot = await this.storage.snapshotOwnerPubkeys();
124
+ }
125
+ catch {
126
+ if (!this._hasAuthority(generation))
127
+ return;
128
+ this.log.error("[mesh] event=owner_list_unavailable");
129
+ await this._publishTopology(buildTopologySnapshot(this.myPubkey, this.membershipByOwner.values()), generation);
130
+ return;
131
+ }
132
+ if (!this._hasAuthority(generation))
133
+ return;
134
+ const slots = this._canonicalOwnerSlots(snapshot);
135
+ if (this.onAuthoritativeOwners) {
136
+ if (!this._hasAuthority(generation))
137
+ return;
138
+ try {
139
+ await this.onAuthoritativeOwners(slots.map((slot) => slot.canonicalOwnerPubkey));
140
+ }
141
+ catch {
142
+ if (this._hasAuthority(generation)) {
143
+ this.log.error("[mesh] event=authoritative_owners_callback_failed");
144
+ }
145
+ }
146
+ if (!this._hasAuthority(generation))
147
+ return;
148
+ }
149
+ await this._pruneStateNotIn(slots, generation);
150
+ if (!this._hasAuthority(generation))
151
+ return;
152
+ for (const slot of slots) {
153
+ const staleResponse = await this._checkOwnerSlot(slot, generation);
154
+ if (!this._hasAuthority(generation) || staleResponse)
155
+ return;
156
+ }
157
+ await this._publishTopology(buildTopologySnapshot(this.myPubkey, this.membershipByOwner.values()), generation);
158
+ }
159
+ _hasAuthority(generation) {
160
+ return generation === this.lifecycleGeneration;
161
+ }
162
+ _canonicalOwnerSlots(snapshot) {
163
+ const rawHandlesByCanonical = new Map();
164
+ const bytesByCanonical = new Map();
165
+ for (const record of snapshot) {
166
+ const rawOwner = record.rawOwnerPubkey;
167
+ if (typeof rawOwner !== "string") {
168
+ this.log.warn(`[mesh] event=invalid_owner_record owner_fp=${rawOwnerFingerprint(rawOwner)}`);
169
+ continue;
170
+ }
171
+ try {
172
+ const ownerPk = decodeEd25519PublicKey(rawOwner, "Owner record");
173
+ const canonical = encodeEd25519PublicKey(ownerPk);
174
+ const handles = rawHandlesByCanonical.get(canonical) ?? new Map();
175
+ handles.set(rawOwner, record.token);
176
+ rawHandlesByCanonical.set(canonical, handles);
177
+ if (!bytesByCanonical.has(canonical))
178
+ bytesByCanonical.set(canonical, ownerPk);
179
+ }
180
+ catch {
181
+ this.log.warn(`[mesh] event=invalid_owner_record owner_fp=${rawOwnerFingerprint(rawOwner)}`);
182
+ }
183
+ }
184
+ return [...rawHandlesByCanonical.entries()]
185
+ .sort(([left], [right]) => compareAscii(left, right))
186
+ .map(([canonicalOwnerPubkey, handles]) => {
187
+ const ownerPk = bytesByCanonical.get(canonicalOwnerPubkey);
188
+ return {
189
+ canonicalOwnerPubkey,
190
+ rawOwnerPubkeys: [...handles.entries()]
191
+ .sort(([left], [right]) => compareAscii(left, right))
192
+ .map(([rawOwnerPubkey, token]) => ({ rawOwnerPubkey, token })),
193
+ ownerPk,
194
+ fingerprint: publicKeyFingerprint(ownerPk),
195
+ };
196
+ });
197
+ }
198
+ async _pruneStateNotIn(slots, generation) {
199
+ const currentOwners = new Set(slots.map((slot) => slot.canonicalOwnerPubkey));
200
+ for (const [owner, pending] of [...this.pendingRevocations]) {
201
+ if (currentOwners.has(owner))
202
+ continue;
203
+ for (const rawOwnerPubkey of [...pending.rawOwnerTokens.keys()]) {
204
+ if (!this._hasAuthority(generation))
205
+ return;
206
+ pending.rawOwnerTokens.delete(rawOwnerPubkey);
207
+ await this._invokeRevokeCallback(rawOwnerPubkey, owner, pending.fingerprint, generation);
208
+ if (!this._hasAuthority(generation))
209
+ return;
210
+ }
211
+ if (pending.rawOwnerTokens.size === 0) {
212
+ this.pendingRevocations.delete(owner);
213
+ }
214
+ }
215
+ for (const owner of this.membershipByOwner.keys()) {
216
+ if (!currentOwners.has(owner) && !this.pendingRevocations.has(owner)) {
217
+ this.membershipByOwner.delete(owner);
218
+ }
219
+ }
220
+ for (const owner of this.lastSeenVersion.keys()) {
221
+ if (!currentOwners.has(owner) && !this.pendingRevocations.has(owner)) {
222
+ this.lastSeenVersion.delete(owner);
223
+ }
224
+ }
225
+ }
226
+ async _checkOwnerSlot(slot, generation) {
227
+ const since = this.lastSeenVersion.get(slot.canonicalOwnerPubkey);
228
+ const hash = createHash("sha256").update(slot.ownerPk).digest("hex");
229
+ let envelope;
230
+ try {
231
+ envelope = await this.client.get(hash, since);
232
+ }
233
+ catch (error) {
234
+ if (!this._hasAuthority(generation))
235
+ return false;
236
+ const stale = await this._retryPending(slot, generation);
237
+ if (stale || !this._hasAuthority(generation))
238
+ return stale;
239
+ if (error instanceof MeshFetchUnavailableError) {
240
+ this.log.warn(`[mesh] event=owner_fetch_unavailable owner_fp=${slot.fingerprint}`);
241
+ return false;
242
+ }
243
+ this.membershipByOwner.delete(slot.canonicalOwnerPubkey);
244
+ const event = error instanceof MeshFetchInvalidResponseError
245
+ ? "owner_fetch_invalid"
246
+ : "owner_fetch_failed";
247
+ this.log.warn(`[mesh] event=${event} owner_fp=${slot.fingerprint}`);
248
+ return false;
249
+ }
250
+ if (!this._hasAuthority(generation))
251
+ return false;
252
+ if (!envelope)
253
+ return this._retryPending(slot, generation);
254
+ let header;
255
+ try {
256
+ header = await verifyEnvelope(envelope);
257
+ }
258
+ catch {
259
+ if (!this._hasAuthority(generation))
260
+ return false;
261
+ this.membershipByOwner.delete(slot.canonicalOwnerPubkey);
262
+ this.log.warn(`[mesh] event=owner_envelope_invalid owner_fp=${slot.fingerprint}`);
263
+ return this._retryPending(slot, generation);
264
+ }
265
+ if (!this._hasAuthority(generation))
266
+ return false;
267
+ if (!bytesEqual(header.ownerPk, slot.ownerPk)) {
268
+ this.membershipByOwner.delete(slot.canonicalOwnerPubkey);
269
+ this.log.warn(`[mesh] event=owner_slot_mismatch owner_fp=${slot.fingerprint}`);
270
+ return this._retryPending(slot, generation);
271
+ }
272
+ const lastSeen = this.lastSeenVersion.get(slot.canonicalOwnerPubkey);
273
+ if (lastSeen !== undefined && header.version <= lastSeen) {
274
+ this.log.warn(`[mesh] event=owner_rollback owner_fp=${slot.fingerprint} received_version=${header.version} retained_version=${lastSeen}`);
275
+ return this._retryPending(slot, generation);
276
+ }
277
+ const membership = {
278
+ ownerPubkey: encodeEd25519PublicKey(header.ownerPk),
279
+ members: header.members.map((member) => ({
280
+ pcPubkey: member.remoteEpk,
281
+ ...(member.nickname === undefined ? {} : { nickname: member.nickname }),
282
+ })),
283
+ };
284
+ const selfPubkey = encodeEd25519PublicKey(this.myPubkey);
285
+ const stillMember = membership.members.some((member) => member.pcPubkey === selfPubkey);
286
+ if (!this._hasAuthority(generation))
287
+ return false;
288
+ if (stillMember) {
289
+ // A newer self-including envelope supersedes any older pending revoke.
290
+ this.pendingRevocations.delete(slot.canonicalOwnerPubkey);
291
+ this.lastSeenVersion.set(slot.canonicalOwnerPubkey, header.version);
292
+ this.membershipByOwner.set(slot.canonicalOwnerPubkey, membership);
293
+ return false;
294
+ }
295
+ const previousVersion = this.lastSeenVersion.get(slot.canonicalOwnerPubkey);
296
+ this.lastSeenVersion.set(slot.canonicalOwnerPubkey, header.version);
297
+ this.membershipByOwner.delete(slot.canonicalOwnerPubkey);
298
+ this.pendingRevocations.set(slot.canonicalOwnerPubkey, {
299
+ version: header.version,
300
+ previousVersion,
301
+ fingerprint: slot.fingerprint,
302
+ rawOwnerTokens: new Map(slot.rawOwnerPubkeys.map(({ rawOwnerPubkey, token }) => [
303
+ rawOwnerPubkey,
304
+ token,
305
+ ])),
306
+ });
307
+ this.log.info(`[mesh] event=self_revoked owner_fp=${slot.fingerprint} received_version=${header.version} since=${since ?? "none"} member_count=${header.members.length}`);
308
+ const stale = await this._retryPending(slot, generation);
309
+ if (stale) {
310
+ // This signed response authorized the old pairing snapshot only. Do not
311
+ // retain its floor, pending work, or topology contribution for a re-pair.
312
+ this.pendingRevocations.delete(slot.canonicalOwnerPubkey);
313
+ if (previousVersion === undefined)
314
+ this.lastSeenVersion.delete(slot.canonicalOwnerPubkey);
315
+ else
316
+ this.lastSeenVersion.set(slot.canonicalOwnerPubkey, previousVersion);
317
+ return true;
318
+ }
319
+ return false;
320
+ }
321
+ /** Returns true only when storage proves the pending snapshot was re-paired. */
322
+ async _retryPending(slot, generation) {
323
+ const pending = this.pendingRevocations.get(slot.canonicalOwnerPubkey);
324
+ if (!pending)
325
+ return false;
326
+ for (const rawOwnerPubkey of [...pending.rawOwnerTokens.keys()]) {
327
+ if (!this._hasAuthority(generation))
328
+ return false;
329
+ let result;
330
+ try {
331
+ const expectedToken = pending.rawOwnerTokens.get(rawOwnerPubkey);
332
+ result = await this.storage.conditionalRemovePeer(rawOwnerPubkey, expectedToken, () => this._hasAuthority(generation));
333
+ }
334
+ catch {
335
+ if (this._hasAuthority(generation)) {
336
+ this.log.error(`[mesh] event=owner_storage_remove_failed owner_fp=${slot.fingerprint}`);
337
+ }
338
+ return false;
339
+ }
340
+ if (!this._hasAuthority(generation))
341
+ return false;
342
+ if (result.outcome === "stale") {
343
+ // The accepted revocation belonged to an old pairing snapshot. Its
344
+ // floor must not suppress a current replacement envelope, but the
345
+ // already-pruned topology stays fail-closed until that envelope wins.
346
+ this.pendingRevocations.delete(slot.canonicalOwnerPubkey);
347
+ if (pending.previousVersion === undefined) {
348
+ this.lastSeenVersion.delete(slot.canonicalOwnerPubkey);
349
+ }
350
+ else {
351
+ this.lastSeenVersion.set(slot.canonicalOwnerPubkey, pending.previousVersion);
352
+ }
353
+ return true;
354
+ }
355
+ if (result.outcome === "no_authority")
356
+ return false;
357
+ // The remaining terminal outcomes are exact local removal or an
358
+ // authoritative strict-read absence, applied fail-closed to this runtime.
359
+ // This intentionally does not claim durable cross-process re-pair provenance.
360
+ pending.rawOwnerTokens.delete(rawOwnerPubkey);
361
+ if (result.outcome === "removed") {
362
+ for (const remainingRawOwner of pending.rawOwnerTokens.keys()) {
363
+ pending.rawOwnerTokens.set(remainingRawOwner, result.nextToken);
364
+ }
365
+ }
366
+ await this._invokeRevokeCallback(rawOwnerPubkey, slot.canonicalOwnerPubkey, pending.fingerprint, generation);
367
+ if (!this._hasAuthority(generation))
368
+ return false;
369
+ }
370
+ if (pending.rawOwnerTokens.size === 0) {
371
+ this.pendingRevocations.delete(slot.canonicalOwnerPubkey);
372
+ }
373
+ return false;
374
+ }
375
+ async _invokeRevokeCallback(rawOwnerPubkey, canonicalOwnerPubkey, fingerprint, generation) {
376
+ if (!this._hasAuthority(generation) || !this.onRevoke)
377
+ return;
378
+ try {
379
+ await this.onRevoke(rawOwnerPubkey, canonicalOwnerPubkey);
380
+ }
381
+ catch {
382
+ if (this._hasAuthority(generation)) {
383
+ this.log.error(`[mesh] event=owner_revoke_callback_failed owner_fp=${fingerprint}`);
384
+ }
385
+ }
386
+ }
387
+ async _publishTopology(next, generation) {
388
+ if (!this._hasAuthority(generation) ||
389
+ topologyEquals(this.previousTopology, next))
390
+ return;
391
+ try {
392
+ if (this.onTopologyChanged) {
393
+ if (!this._hasAuthority(generation))
394
+ return;
395
+ await this.onTopologyChanged(next);
396
+ }
397
+ }
398
+ catch {
399
+ if (this._hasAuthority(generation))
400
+ this.log.error("[mesh] event=topology_callback_failed");
401
+ return;
402
+ }
403
+ if (this._hasAuthority(generation))
404
+ this.previousTopology = next;
405
+ }
406
+ }
407
+ //# sourceMappingURL=self_revoke.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"self_revoke.js","sourceRoot":"","sources":["../../src/mesh/self_revoke.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import type { MeshClient } from "./client.js";
2
+ export interface PiRoutingIdentity {
3
+ readonly pcPubkey: string;
4
+ /** Receiver-local display and routing alias. */
5
+ readonly pcLabel: string;
6
+ /** Raw legacy cross-PC wire prefix; distinct from the receiver-local alias. */
7
+ readonly legacyPcLabel: string;
8
+ }
9
+ export interface MeshTopologySnapshot {
10
+ readonly self: PiRoutingIdentity;
11
+ readonly siblings: readonly PiRoutingIdentity[];
12
+ }
13
+ export interface BoundOwnerMembership {
14
+ /** Canonical standard-padded string derived from MeshHeader.ownerPk bytes. */
15
+ readonly ownerPubkey: string;
16
+ readonly members: readonly {
17
+ readonly pcPubkey: string;
18
+ readonly nickname?: string;
19
+ }[];
20
+ }
21
+ /** Legacy mutable shape retained through the Task 4 compatibility window. */
22
+ export interface SiblingPi {
23
+ pcLabel: string;
24
+ pcPubkey: string;
25
+ }
26
+ export interface DiscoverSelfLabelResult {
27
+ selfPcLabel: string;
28
+ }
29
+ export interface DiscoverOptions {
30
+ client: MeshClient;
31
+ ownerEpks: readonly unknown[];
32
+ myPubkey: Uint8Array;
33
+ log?: {
34
+ warn(msg: string): void;
35
+ };
36
+ }
37
+ /**
38
+ * Builds one deterministic direct-co-membership topology for self and siblings.
39
+ * Memberships that do not themselves contain self contribute nothing.
40
+ */
41
+ export declare function buildTopologySnapshot(myPubkey: Uint8Array, memberships: Iterable<BoundOwnerMembership>): MeshTopologySnapshot;
42
+ /** Discovers one bound, direct, canonical topology from raw Owner records. */
43
+ export declare function discoverTopology(opts: DiscoverOptions): Promise<MeshTopologySnapshot>;
44
+ /** Compatibility fallback now follows the routing-alias grammar. */
45
+ export declare function fallbackLabel(pcPubkey: string): string;
46
+ /** Compatibility wrapper over the atomic topology producer. */
47
+ export declare function discoverSelfLabel(opts: DiscoverOptions): Promise<DiscoverSelfLabelResult>;
48
+ /** Compatibility wrapper over the atomic topology producer. */
49
+ export declare function discoverSiblings(opts: DiscoverOptions): Promise<SiblingPi[]>;
@@ -0,0 +1,159 @@
1
+ import { createHash } from "node:crypto";
2
+ import { allocateRoutingAliases, bytesEqual, canonicalizeEd25519PublicKey, decodeEd25519PublicKey, encodeEd25519PublicKey, publicKeyFingerprint, selectRoutingNickname, toBase64UrlNoPad, } from "./encoding.js";
3
+ import { verifyEnvelope } from "./verify.js";
4
+ function compareAscii(left, right) {
5
+ return left < right ? -1 : left > right ? 1 : 0;
6
+ }
7
+ function freezeIdentity(pcPubkey, pcLabel, legacyPcLabel) {
8
+ return Object.freeze({ pcPubkey, pcLabel, legacyPcLabel });
9
+ }
10
+ /**
11
+ * Builds one deterministic direct-co-membership topology for self and siblings.
12
+ * Memberships that do not themselves contain self contribute nothing.
13
+ */
14
+ export function buildTopologySnapshot(myPubkey, memberships) {
15
+ const selfPubkey = encodeEd25519PublicKey(myPubkey, "self public key");
16
+ const nicknamesByKey = new Map([[selfPubkey, []]]);
17
+ for (const membership of memberships) {
18
+ canonicalizeEd25519PublicKey(membership.ownerPubkey, "membership.ownerPubkey");
19
+ const normalizedMembers = membership.members.map((member, index) => {
20
+ if (member.nickname !== undefined &&
21
+ typeof member.nickname !== "string") {
22
+ throw new Error(`mesh: membership.members[${index}].nickname invalid`);
23
+ }
24
+ return {
25
+ pcPubkey: canonicalizeEd25519PublicKey(member.pcPubkey, `membership.members[${index}].pcPubkey`),
26
+ nickname: member.nickname,
27
+ };
28
+ });
29
+ if (!normalizedMembers.some((member) => member.pcPubkey === selfPubkey)) {
30
+ continue;
31
+ }
32
+ for (const member of normalizedMembers) {
33
+ const candidates = nicknamesByKey.get(member.pcPubkey) ?? [];
34
+ if (!nicknamesByKey.has(member.pcPubkey)) {
35
+ nicknamesByKey.set(member.pcPubkey, candidates);
36
+ }
37
+ if (member.nickname)
38
+ candidates.push(member.nickname);
39
+ }
40
+ }
41
+ const selectedNicknames = new Map([...nicknamesByKey.entries()].map(([pcPubkey, candidates]) => [
42
+ pcPubkey,
43
+ selectRoutingNickname(candidates),
44
+ ]));
45
+ const aliases = allocateRoutingAliases([...selectedNicknames.entries()].map(([pcPubkey, nickname]) => ({
46
+ pcPubkey,
47
+ ...(nickname === undefined ? {} : { nickname }),
48
+ })));
49
+ const selfLabel = aliases.get(selfPubkey);
50
+ if (!selfLabel) {
51
+ throw new Error("mesh: topology self alias invariant failed");
52
+ }
53
+ const siblings = [...aliases.entries()]
54
+ .filter(([pcPubkey]) => pcPubkey !== selfPubkey)
55
+ .sort(([left], [right]) => compareAscii(left, right))
56
+ .map(([pcPubkey, pcLabel]) => freezeIdentity(pcPubkey, pcLabel, selectedNicknames.get(pcPubkey) ?? pcPubkey.slice(0, 8)));
57
+ return Object.freeze({
58
+ self: freezeIdentity(selfPubkey, selfLabel, selectedNicknames.get(selfPubkey) ?? selfPubkey.slice(0, 8)),
59
+ siblings: Object.freeze(siblings),
60
+ });
61
+ }
62
+ function rawOwnerFingerprint(rawOwner) {
63
+ let fingerprintInput;
64
+ if (typeof rawOwner === "string") {
65
+ fingerprintInput = rawOwner;
66
+ }
67
+ else {
68
+ try {
69
+ const serialized = JSON.stringify(rawOwner);
70
+ const type = rawOwner === null ? "null" : typeof rawOwner;
71
+ fingerprintInput = `${type}:${serialized ?? ""}`;
72
+ }
73
+ catch {
74
+ fingerprintInput = `${typeof rawOwner}:unserializable`;
75
+ }
76
+ }
77
+ return createHash("sha256")
78
+ .update(fingerprintInput, "utf8")
79
+ .digest("hex")
80
+ .slice(0, 8);
81
+ }
82
+ function canonicalOwnerSlots(rawOwners, log) {
83
+ const slots = new Map();
84
+ for (const rawOwner of rawOwners) {
85
+ if (typeof rawOwner !== "string") {
86
+ log.warn(`[mesh] event=invalid_owner_record owner_fp=${rawOwnerFingerprint(rawOwner)}`);
87
+ continue;
88
+ }
89
+ try {
90
+ const ownerPk = decodeEd25519PublicKey(rawOwner, "Owner record");
91
+ const canonicalOwnerPubkey = encodeEd25519PublicKey(ownerPk);
92
+ if (!slots.has(canonicalOwnerPubkey)) {
93
+ slots.set(canonicalOwnerPubkey, {
94
+ canonicalOwnerPubkey,
95
+ ownerPk,
96
+ fingerprint: publicKeyFingerprint(ownerPk),
97
+ });
98
+ }
99
+ }
100
+ catch {
101
+ log.warn(`[mesh] event=invalid_owner_record owner_fp=${rawOwnerFingerprint(rawOwner)}`);
102
+ }
103
+ }
104
+ return [...slots.values()].sort((left, right) => compareAscii(left.canonicalOwnerPubkey, right.canonicalOwnerPubkey));
105
+ }
106
+ /** Discovers one bound, direct, canonical topology from raw Owner records. */
107
+ export async function discoverTopology(opts) {
108
+ const log = opts.log ?? { warn: (message) => console.warn(message) };
109
+ const selfPubkey = encodeEd25519PublicKey(opts.myPubkey, "self public key");
110
+ const memberships = [];
111
+ for (const slot of canonicalOwnerSlots(opts.ownerEpks, log)) {
112
+ try {
113
+ const hash = createHash("sha256").update(slot.ownerPk).digest("hex");
114
+ const envelope = await opts.client.get(hash);
115
+ if (!envelope)
116
+ continue;
117
+ const header = await verifyEnvelope(envelope);
118
+ if (!bytesEqual(header.ownerPk, slot.ownerPk)) {
119
+ log.warn(`[mesh] event=owner_slot_mismatch owner_fp=${slot.fingerprint}`);
120
+ continue;
121
+ }
122
+ if (!header.members.some((member) => member.remoteEpk === selfPubkey)) {
123
+ continue;
124
+ }
125
+ memberships.push({
126
+ ownerPubkey: encodeEd25519PublicKey(header.ownerPk),
127
+ members: header.members.map((member) => ({
128
+ pcPubkey: member.remoteEpk,
129
+ ...(member.nickname === undefined
130
+ ? {}
131
+ : { nickname: member.nickname }),
132
+ })),
133
+ });
134
+ }
135
+ catch {
136
+ log.warn(`[mesh] event=owner_discovery_failed owner_fp=${slot.fingerprint}`);
137
+ }
138
+ }
139
+ return buildTopologySnapshot(opts.myPubkey, memberships);
140
+ }
141
+ /** Compatibility fallback now follows the routing-alias grammar. */
142
+ export function fallbackLabel(pcPubkey) {
143
+ const bytes = decodeEd25519PublicKey(pcPubkey, "pcPubkey");
144
+ return `pc-${toBase64UrlNoPad(bytes).slice(0, 8)}`;
145
+ }
146
+ /** Compatibility wrapper over the atomic topology producer. */
147
+ export async function discoverSelfLabel(opts) {
148
+ const topology = await discoverTopology(opts);
149
+ return { selfPcLabel: topology.self.pcLabel };
150
+ }
151
+ /** Compatibility wrapper over the atomic topology producer. */
152
+ export async function discoverSiblings(opts) {
153
+ const topology = await discoverTopology(opts);
154
+ return topology.siblings.map(({ pcLabel, pcPubkey }) => ({
155
+ pcLabel,
156
+ pcPubkey,
157
+ }));
158
+ }
159
+ //# sourceMappingURL=siblings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"siblings.js","sourceRoot":"","sources":["../../src/mesh/siblings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EACL,sBAAsB,EACtB,UAAU,EACV,4BAA4B,EAC5B,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AA+C7C,SAAS,YAAY,CAAC,IAAY,EAAE,KAAa;IAC/C,OAAO,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,cAAc,CACrB,QAAgB,EAChB,OAAe,EACf,aAAqB;IAErB,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAAoB,EACpB,WAA2C;IAE3C,MAAM,UAAU,GAAG,sBAAsB,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;IACvE,MAAM,cAAc,GAAG,IAAI,GAAG,CAAmB,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAErE,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,4BAA4B,CAC1B,UAAU,CAAC,WAAW,EACtB,wBAAwB,CACzB,CAAC;QACF,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;YACjE,IACE,MAAM,CAAC,QAAQ,KAAK,SAAS;gBAC7B,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EACnC,CAAC;gBACD,MAAM,IAAI,KAAK,CAAC,4BAA4B,KAAK,oBAAoB,CAAC,CAAC;YACzE,CAAC;YACD,OAAO;gBACL,QAAQ,EAAE,4BAA4B,CACpC,MAAM,CAAC,QAAQ,EACf,sBAAsB,KAAK,YAAY,CACxC;gBACD,QAAQ,EAAE,MAAM,CAAC,QAAQ;aAC1B,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,KAAK,UAAU,CAAC,EAAE,CAAC;YACxE,SAAS;QACX,CAAC;QAED,KAAK,MAAM,MAAM,IAAI,iBAAiB,EAAE,CAAC;YACvC,MAAM,UAAU,GAAG,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC7D,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACzC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YAClD,CAAC;YACD,IAAI,MAAM,CAAC,QAAQ;gBAAE,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAC/B,CAAC,GAAG,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC;QAC5D,QAAQ;QACR,qBAAqB,CAAC,UAAU,CAAC;KAClC,CAAC,CACH,CAAC;IACF,MAAM,OAAO,GAAG,sBAAsB,CACpC,CAAC,GAAG,iBAAiB,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9D,QAAQ;QACR,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC;KAChD,CAAC,CAAC,CACJ,CAAC;IACF,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC1C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,QAAQ,GAAG,CAAC,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;SACpC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,QAAQ,KAAK,UAAU,CAAC;SAC/C,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;SACpD,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,EAAE,CAC3B,cAAc,CACZ,QAAQ,EACR,OAAO,EACP,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CACxD,CACF,CAAC;IAEJ,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,IAAI,EAAE,cAAc,CAClB,UAAU,EACV,SAAS,EACT,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAC5D;QACD,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;KAClC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,mBAAmB,CAAC,QAAiB;IAC5C,IAAI,gBAAwB,CAAC;IAC7B,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,gBAAgB,GAAG,QAAQ,CAAC;IAC9B,CAAC;SAAM,CAAC;QACN,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,IAAI,GAAG,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,QAAQ,CAAC;YAC1D,gBAAgB,GAAG,GAAG,IAAI,IAAI,UAAU,IAAI,EAAE,EAAE,CAAC;QACnD,CAAC;QAAC,MAAM,CAAC;YACP,gBAAgB,GAAG,GAAG,OAAO,QAAQ,iBAAiB,CAAC;QACzD,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAC,QAAQ,CAAC;SACxB,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC;SAChC,MAAM,CAAC,KAAK,CAAC;SACb,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACjB,CAAC;AAED,SAAS,mBAAmB,CAC1B,SAA6B,EAC7B,GAAgC;IAEhC,MAAM,KAAK,GAAG,IAAI,GAAG,EAA8B,CAAC;IACpD,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,GAAG,CAAC,IAAI,CACN,8CAA8C,mBAAmB,CAAC,QAAQ,CAAC,EAAE,CAC9E,CAAC;YACF,SAAS;QACX,CAAC;QACD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,sBAAsB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;YACjE,MAAM,oBAAoB,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;YAC7D,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,CAAC;gBACrC,KAAK,CAAC,GAAG,CAAC,oBAAoB,EAAE;oBAC9B,oBAAoB;oBACpB,OAAO;oBACP,WAAW,EAAE,oBAAoB,CAAC,OAAO,CAAC;iBAC3C,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,CAAC,IAAI,CACN,8CAA8C,mBAAmB,CAAC,QAAQ,CAAC,EAAE,CAC9E,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAC9C,YAAY,CAAC,IAAI,CAAC,oBAAoB,EAAE,KAAK,CAAC,oBAAoB,CAAC,CACpE,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAqB;IAErB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,EAAE,IAAI,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;IAC7E,MAAM,UAAU,GAAG,sBAAsB,CAAC,IAAI,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;IAC5E,MAAM,WAAW,GAA2B,EAAE,CAAC;IAE/C,KAAK,MAAM,IAAI,IAAI,mBAAmB,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,CAAC;QAC5D,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACrE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC7C,IAAI,CAAC,QAAQ;gBAAE,SAAS;YACxB,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAC;YAC9C,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC9C,GAAG,CAAC,IAAI,CACN,6CAA6C,IAAI,CAAC,WAAW,EAAE,CAChE,CAAC;gBACF,SAAS;YACX,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,KAAK,UAAU,CAAC,EAAE,CAAC;gBACtE,SAAS;YACX,CAAC;YACD,WAAW,CAAC,IAAI,CAAC;gBACf,WAAW,EAAE,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC;gBACnD,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;oBACvC,QAAQ,EAAE,MAAM,CAAC,SAAS;oBAC1B,GAAG,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS;wBAC/B,CAAC,CAAC,EAAE;wBACJ,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;iBACnC,CAAC,CAAC;aACJ,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,CAAC,IAAI,CACN,gDAAgD,IAAI,CAAC,WAAW,EAAE,CACnE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,qBAAqB,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AAC3D,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,MAAM,KAAK,GAAG,sBAAsB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC3D,OAAO,MAAM,gBAAgB,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AACrD,CAAC;AAED,+DAA+D;AAC/D,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAAqB;IAErB,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC9C,OAAO,EAAE,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;AAChD,CAAC;AAED,+DAA+D;AAC/D,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAqB;IAErB,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC9C,OAAO,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;QACvD,OAAO;QACP,QAAQ;KACT,CAAC,CAAC,CAAC;AACN,CAAC"}