@hashgraphonline/standards-sdk 0.0.157-canary.2 → 0.0.157-canary.4

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 (178) hide show
  1. package/dist/cjs/hcs-10/base-client.d.ts +1 -1
  2. package/dist/cjs/hcs-10/base-client.d.ts.map +1 -1
  3. package/dist/cjs/hcs-10/sdk.d.ts +1 -1
  4. package/dist/cjs/hcs-10/sdk.d.ts.map +1 -1
  5. package/dist/cjs/hcs-11/agent-builder.d.ts +2 -0
  6. package/dist/cjs/hcs-11/agent-builder.d.ts.map +1 -1
  7. package/dist/cjs/hcs-11/client.d.ts +2 -0
  8. package/dist/cjs/hcs-11/client.d.ts.map +1 -1
  9. package/dist/cjs/hcs-11/types.d.ts +4 -2
  10. package/dist/cjs/hcs-11/types.d.ts.map +1 -1
  11. package/dist/cjs/hcs-15/index.d.ts +3 -0
  12. package/dist/cjs/hcs-15/index.d.ts.map +1 -0
  13. package/dist/cjs/hcs-15/petal-manager.d.ts +27 -0
  14. package/dist/cjs/hcs-15/petal-manager.d.ts.map +1 -0
  15. package/dist/cjs/hcs-15/types.d.ts +41 -0
  16. package/dist/cjs/hcs-15/types.d.ts.map +1 -0
  17. package/dist/cjs/hcs-16/flora-account-manager.d.ts.map +1 -1
  18. package/dist/cjs/hcs-16/types.d.ts +3 -5
  19. package/dist/cjs/hcs-16/types.d.ts.map +1 -1
  20. package/dist/cjs/hcs-18/discovery.d.ts +1 -0
  21. package/dist/cjs/hcs-18/discovery.d.ts.map +1 -1
  22. package/dist/cjs/hcs-18/types.d.ts +1 -0
  23. package/dist/cjs/hcs-18/types.d.ts.map +1 -1
  24. package/dist/cjs/hcs-20/sdk.d.ts.map +1 -1
  25. package/dist/cjs/hcs-7/evm-bridge.d.ts.map +1 -1
  26. package/dist/cjs/hcs-7/redis-cache.d.ts.map +1 -1
  27. package/dist/cjs/hcs-7/wasm-bridge.d.ts.map +1 -1
  28. package/dist/cjs/{index-xZmk-HBD.cjs → index-CJsmyij2.cjs} +12 -12
  29. package/dist/cjs/index-CJsmyij2.cjs.map +1 -0
  30. package/dist/cjs/{index-CyAbgH2f-Cv8mxAhS.cjs → index-CyAbgH2f-Dn5WQtPx.cjs} +2 -2
  31. package/dist/cjs/{index-CyAbgH2f-Cv8mxAhS.cjs.map → index-CyAbgH2f-Dn5WQtPx.cjs.map} +1 -1
  32. package/dist/cjs/index.d.ts +1 -1
  33. package/dist/cjs/services/types.d.ts +1 -1
  34. package/dist/cjs/services/types.d.ts.map +1 -1
  35. package/dist/cjs/standards-sdk.cjs +1 -1
  36. package/dist/cjs/{standards-sdk.es45-BxAtDqsy-ELd4REyl.cjs → standards-sdk.es45-BxAtDqsy-CiMtsDbD.cjs} +2 -2
  37. package/dist/cjs/{standards-sdk.es45-BxAtDqsy-ELd4REyl.cjs.map → standards-sdk.es45-BxAtDqsy-CiMtsDbD.cjs.map} +1 -1
  38. package/dist/cjs/{standards-sdk.es46-BI8ACeLM-DRmcgoN0.cjs → standards-sdk.es46-BI8ACeLM-DFYgO-fP.cjs} +2 -2
  39. package/dist/cjs/{standards-sdk.es46-BI8ACeLM-DRmcgoN0.cjs.map → standards-sdk.es46-BI8ACeLM-DFYgO-fP.cjs.map} +1 -1
  40. package/dist/cjs/{standards-sdk.es47-DbkY3FlD-DfMpZygD.cjs → standards-sdk.es47-DbkY3FlD-2qTWs2BD.cjs} +2 -2
  41. package/dist/cjs/{standards-sdk.es47-DbkY3FlD-DfMpZygD.cjs.map → standards-sdk.es47-DbkY3FlD-2qTWs2BD.cjs.map} +1 -1
  42. package/dist/cjs/{standards-sdk.es48-DzT9Qc3F-CmCkJl3x.cjs → standards-sdk.es48-DzT9Qc3F-Byz0fQnW.cjs} +2 -2
  43. package/dist/cjs/{standards-sdk.es48-DzT9Qc3F-CmCkJl3x.cjs.map → standards-sdk.es48-DzT9Qc3F-Byz0fQnW.cjs.map} +1 -1
  44. package/dist/cjs/utils/logger.d.ts.map +1 -1
  45. package/dist/es/hcs-10/base-client.d.ts +1 -1
  46. package/dist/es/hcs-10/base-client.d.ts.map +1 -1
  47. package/dist/es/hcs-10/sdk.d.ts +1 -1
  48. package/dist/es/hcs-10/sdk.d.ts.map +1 -1
  49. package/dist/es/hcs-11/agent-builder.d.ts +2 -0
  50. package/dist/es/hcs-11/agent-builder.d.ts.map +1 -1
  51. package/dist/es/hcs-11/client.d.ts +2 -0
  52. package/dist/es/hcs-11/client.d.ts.map +1 -1
  53. package/dist/es/hcs-11/types.d.ts +4 -2
  54. package/dist/es/hcs-11/types.d.ts.map +1 -1
  55. package/dist/es/hcs-15/index.d.ts +3 -0
  56. package/dist/es/hcs-15/index.d.ts.map +1 -0
  57. package/dist/es/hcs-15/petal-manager.d.ts +27 -0
  58. package/dist/es/hcs-15/petal-manager.d.ts.map +1 -0
  59. package/dist/es/hcs-15/types.d.ts +41 -0
  60. package/dist/es/hcs-15/types.d.ts.map +1 -0
  61. package/dist/es/hcs-16/flora-account-manager.d.ts.map +1 -1
  62. package/dist/es/hcs-16/types.d.ts +3 -5
  63. package/dist/es/hcs-16/types.d.ts.map +1 -1
  64. package/dist/es/hcs-18/discovery.d.ts +1 -0
  65. package/dist/es/hcs-18/discovery.d.ts.map +1 -1
  66. package/dist/es/hcs-18/types.d.ts +1 -0
  67. package/dist/es/hcs-18/types.d.ts.map +1 -1
  68. package/dist/es/hcs-20/sdk.d.ts.map +1 -1
  69. package/dist/es/hcs-7/evm-bridge.d.ts.map +1 -1
  70. package/dist/es/hcs-7/redis-cache.d.ts.map +1 -1
  71. package/dist/es/hcs-7/wasm-bridge.d.ts.map +1 -1
  72. package/dist/es/index.d.ts +1 -1
  73. package/dist/es/services/types.d.ts +1 -1
  74. package/dist/es/services/types.d.ts.map +1 -1
  75. package/dist/es/standards-sdk.es.js +19 -22
  76. package/dist/es/standards-sdk.es.js.map +1 -1
  77. package/dist/es/standards-sdk.es10.js +1 -1
  78. package/dist/es/standards-sdk.es11.js +10 -2
  79. package/dist/es/standards-sdk.es11.js.map +1 -1
  80. package/dist/es/standards-sdk.es12.js +1 -1
  81. package/dist/es/standards-sdk.es13.js +1 -1
  82. package/dist/es/standards-sdk.es13.js.map +1 -1
  83. package/dist/es/standards-sdk.es14.js +1 -1
  84. package/dist/es/standards-sdk.es15.js +39 -9
  85. package/dist/es/standards-sdk.es15.js.map +1 -1
  86. package/dist/es/standards-sdk.es16.js +1 -0
  87. package/dist/es/standards-sdk.es16.js.map +1 -1
  88. package/dist/es/standards-sdk.es18.js +1 -1
  89. package/dist/es/standards-sdk.es19.js +1 -1
  90. package/dist/es/standards-sdk.es2.js +1 -1
  91. package/dist/es/standards-sdk.es20.js +2 -2
  92. package/dist/es/standards-sdk.es23.js +2 -2
  93. package/dist/es/standards-sdk.es25.js +4 -2
  94. package/dist/es/standards-sdk.es25.js.map +1 -1
  95. package/dist/es/standards-sdk.es26.js +2 -2
  96. package/dist/es/standards-sdk.es27.js +152 -6
  97. package/dist/es/standards-sdk.es27.js.map +1 -1
  98. package/dist/es/standards-sdk.es28.js +26 -189
  99. package/dist/es/standards-sdk.es28.js.map +1 -1
  100. package/dist/es/standards-sdk.es29.js +446 -26
  101. package/dist/es/standards-sdk.es29.js.map +1 -1
  102. package/dist/es/standards-sdk.es3.js +1 -1
  103. package/dist/es/standards-sdk.es3.js.map +1 -1
  104. package/dist/es/standards-sdk.es30.js +6 -342
  105. package/dist/es/standards-sdk.es30.js.map +1 -1
  106. package/dist/es/standards-sdk.es31.js +202 -6
  107. package/dist/es/standards-sdk.es31.js.map +1 -1
  108. package/dist/es/standards-sdk.es32.js +34 -202
  109. package/dist/es/standards-sdk.es32.js.map +1 -1
  110. package/dist/es/standards-sdk.es33.js +529 -34
  111. package/dist/es/standards-sdk.es33.js.map +1 -1
  112. package/dist/es/standards-sdk.es34.js +87 -501
  113. package/dist/es/standards-sdk.es34.js.map +1 -1
  114. package/dist/es/standards-sdk.es35.js +19 -98
  115. package/dist/es/standards-sdk.es35.js.map +1 -1
  116. package/dist/es/standards-sdk.es36.js +156 -18
  117. package/dist/es/standards-sdk.es36.js.map +1 -1
  118. package/dist/es/standards-sdk.es37.js +146 -150
  119. package/dist/es/standards-sdk.es37.js.map +1 -1
  120. package/dist/es/standards-sdk.es38.js +561 -134
  121. package/dist/es/standards-sdk.es38.js.map +1 -1
  122. package/dist/es/standards-sdk.es39.js +562 -543
  123. package/dist/es/standards-sdk.es39.js.map +1 -1
  124. package/dist/es/standards-sdk.es4.js +6 -4
  125. package/dist/es/standards-sdk.es4.js.map +1 -1
  126. package/dist/es/standards-sdk.es40.js +4 -601
  127. package/dist/es/standards-sdk.es40.js.map +1 -1
  128. package/dist/es/standards-sdk.es41.js +415 -4
  129. package/dist/es/standards-sdk.es41.js.map +1 -1
  130. package/dist/es/standards-sdk.es42.js +1536 -389
  131. package/dist/es/standards-sdk.es42.js.map +1 -1
  132. package/dist/es/standards-sdk.es43.js +133 -1541
  133. package/dist/es/standards-sdk.es43.js.map +1 -1
  134. package/dist/es/standards-sdk.es44.js +7 -155
  135. package/dist/es/standards-sdk.es44.js.map +1 -1
  136. package/dist/es/standards-sdk.es45.js +2 -7
  137. package/dist/es/standards-sdk.es45.js.map +1 -1
  138. package/dist/es/standards-sdk.es46.js +5 -5
  139. package/dist/es/standards-sdk.es48.js +1 -1
  140. package/dist/es/standards-sdk.es49.js +1 -1
  141. package/dist/es/standards-sdk.es5.js +4 -6
  142. package/dist/es/standards-sdk.es5.js.map +1 -1
  143. package/dist/es/standards-sdk.es50.js +1 -1
  144. package/dist/es/standards-sdk.es51.js +1 -1
  145. package/dist/es/standards-sdk.es52.js +1 -1
  146. package/dist/es/standards-sdk.es54.js +7135 -2
  147. package/dist/es/standards-sdk.es54.js.map +1 -1
  148. package/dist/es/standards-sdk.es55.js +7134 -41
  149. package/dist/es/standards-sdk.es55.js.map +1 -1
  150. package/dist/es/standards-sdk.es56.js +37 -37
  151. package/dist/es/standards-sdk.es56.js.map +1 -1
  152. package/dist/es/standards-sdk.es57.js +37 -37
  153. package/dist/es/standards-sdk.es57.js.map +1 -1
  154. package/dist/es/standards-sdk.es58.js +78 -72
  155. package/dist/es/standards-sdk.es58.js.map +1 -1
  156. package/dist/es/standards-sdk.es59.js +41 -7134
  157. package/dist/es/standards-sdk.es59.js.map +1 -1
  158. package/dist/es/standards-sdk.es6.js.map +1 -1
  159. package/dist/es/standards-sdk.es7.js +28 -22
  160. package/dist/es/standards-sdk.es7.js.map +1 -1
  161. package/dist/es/standards-sdk.es8.js +5 -5
  162. package/dist/es/utils/logger.d.ts.map +1 -1
  163. package/package.json +37 -35
  164. package/dist/cjs/hcs-21/index.d.ts +0 -4
  165. package/dist/cjs/hcs-21/index.d.ts.map +0 -1
  166. package/dist/cjs/hcs-21/petal-account-manager.d.ts +0 -52
  167. package/dist/cjs/hcs-21/petal-account-manager.d.ts.map +0 -1
  168. package/dist/cjs/hcs-21/types.d.ts +0 -44
  169. package/dist/cjs/hcs-21/types.d.ts.map +0 -1
  170. package/dist/cjs/index-xZmk-HBD.cjs.map +0 -1
  171. package/dist/es/hcs-21/index.d.ts +0 -4
  172. package/dist/es/hcs-21/index.d.ts.map +0 -1
  173. package/dist/es/hcs-21/petal-account-manager.d.ts +0 -52
  174. package/dist/es/hcs-21/petal-account-manager.d.ts.map +0 -1
  175. package/dist/es/hcs-21/types.d.ts +0 -44
  176. package/dist/es/hcs-21/types.d.ts.map +0 -1
  177. package/dist/es/standards-sdk.es60.js +0 -7144
  178. package/dist/es/standards-sdk.es60.js.map +0 -1
@@ -1,39 +1,534 @@
1
- var DiscoveryOperation = /* @__PURE__ */ ((DiscoveryOperation2) => {
2
- DiscoveryOperation2["ANNOUNCE"] = "announce";
3
- DiscoveryOperation2["PROPOSE"] = "propose";
4
- DiscoveryOperation2["RESPOND"] = "respond";
5
- DiscoveryOperation2["COMPLETE"] = "complete";
6
- DiscoveryOperation2["WITHDRAW"] = "withdraw";
7
- return DiscoveryOperation2;
8
- })(DiscoveryOperation || {});
9
- var DiscoveryState = /* @__PURE__ */ ((DiscoveryState2) => {
10
- DiscoveryState2["IDLE"] = "idle";
11
- DiscoveryState2["ANNOUNCED"] = "announced";
12
- DiscoveryState2["PROPOSING"] = "proposing";
13
- DiscoveryState2["FORMING"] = "forming";
14
- DiscoveryState2["ACTIVE"] = "active";
15
- DiscoveryState2["WITHDRAWN"] = "withdrawn";
16
- return DiscoveryState2;
17
- })(DiscoveryState || {});
18
- class DiscoveryError extends Error {
19
- constructor(message, code) {
20
- super(message);
21
- this.code = code;
22
- this.name = "DiscoveryError";
1
+ import { PublicKey, TopicMessageSubmitTransaction } from "@hashgraph/sdk";
2
+ import { Logger } from "./standards-sdk.es34.js";
3
+ import { DiscoveryState, DiscoveryError, DiscoveryErrorCodes, DiscoveryOperation } from "./standards-sdk.es32.js";
4
+ import { FloraAccountManager } from "./standards-sdk.es29.js";
5
+ class FloraDiscovery {
6
+ // Track proposals being processed
7
+ constructor(config, baseClient, client, logger) {
8
+ this.state = DiscoveryState.IDLE;
9
+ this.lastSequenceNumber = 0;
10
+ this.announcements = /* @__PURE__ */ new Map();
11
+ this.proposals = /* @__PURE__ */ new Map();
12
+ this.formations = /* @__PURE__ */ new Map();
13
+ this.floraCreationInProgress = /* @__PURE__ */ new Set();
14
+ this.config = config;
15
+ this.mirrorNode = baseClient.mirrorNode;
16
+ this.logger = logger || new Logger({ module: "FloraDiscovery" });
17
+ this.client = client;
18
+ this.eventEmitter = config.onDiscoveryEvent;
19
+ if (client) {
20
+ this.floraClient = new FloraAccountManager(
21
+ client,
22
+ baseClient.network,
23
+ this.logger
24
+ );
25
+ }
26
+ }
27
+ /**
28
+ * Start discovery service
29
+ */
30
+ async startDiscovery() {
31
+ if (this.state !== DiscoveryState.IDLE) {
32
+ throw new DiscoveryError(
33
+ "Discovery already started",
34
+ DiscoveryErrorCodes.ALREADY_IN_DISCOVERY
35
+ );
36
+ }
37
+ this.logger.info("Starting Flora discovery");
38
+ await this.syncDiscoveryTopic();
39
+ this.state = DiscoveryState.ANNOUNCED;
40
+ }
41
+ /**
42
+ * Announce Petal availability
43
+ */
44
+ async announceAvailability(validFor = 1e4) {
45
+ if (!this.client) {
46
+ throw new DiscoveryError(
47
+ "Client required for announcements",
48
+ DiscoveryErrorCodes.INVALID_STATE
49
+ );
50
+ }
51
+ const message = {
52
+ p: "hcs-18",
53
+ op: DiscoveryOperation.ANNOUNCE,
54
+ data: {
55
+ account: this.config.accountId,
56
+ petal: {
57
+ name: this.config.petalName,
58
+ priority: this.config.priority
59
+ },
60
+ capabilities: this.config.capabilities,
61
+ valid_for: validFor
62
+ }
63
+ };
64
+ const sequenceNumber = await this.sendDiscoveryMessage(message);
65
+ this.myAnnouncementSeq = sequenceNumber;
66
+ this.state = DiscoveryState.ANNOUNCED;
67
+ this.emitEvent({
68
+ type: "announcement_received",
69
+ sequenceNumber,
70
+ timestamp: /* @__PURE__ */ new Date(),
71
+ data: message.data
72
+ });
73
+ return sequenceNumber;
74
+ }
75
+ /**
76
+ * Propose Flora formation
77
+ */
78
+ async proposeFloraFormation(memberAccounts, config) {
79
+ if (!this.client) {
80
+ throw new DiscoveryError(
81
+ "Client required for proposals",
82
+ DiscoveryErrorCodes.INVALID_STATE
83
+ );
84
+ }
85
+ const members = memberAccounts.map((account) => {
86
+ const announcement = Array.from(this.announcements.values()).find(
87
+ (a) => a.account === account
88
+ );
89
+ return {
90
+ account,
91
+ announce_seq: announcement?.sequenceNumber,
92
+ priority: announcement?.data.petal.priority || 500
93
+ };
94
+ });
95
+ const proposeData = {
96
+ proposer: this.config.accountId,
97
+ members,
98
+ config
99
+ };
100
+ const message = {
101
+ p: "hcs-18",
102
+ op: DiscoveryOperation.PROPOSE,
103
+ data: proposeData
104
+ };
105
+ const sequenceNumber = await this.sendDiscoveryMessage(message);
106
+ this.state = DiscoveryState.PROPOSING;
107
+ this.emitEvent({
108
+ type: "proposal_received",
109
+ sequenceNumber,
110
+ timestamp: /* @__PURE__ */ new Date(),
111
+ data: proposeData
112
+ });
113
+ return sequenceNumber;
114
+ }
115
+ /**
116
+ * Respond to Flora proposal
117
+ */
118
+ async respondToProposal(proposalSeq, decision, reason) {
119
+ if (!this.client) {
120
+ throw new DiscoveryError(
121
+ "Client required for responses",
122
+ DiscoveryErrorCodes.INVALID_STATE
123
+ );
124
+ }
125
+ await this.syncDiscoveryTopic();
126
+ const proposal = this.proposals.get(proposalSeq);
127
+ if (!proposal) {
128
+ throw new DiscoveryError(
129
+ `Proposal ${proposalSeq} not found`,
130
+ DiscoveryErrorCodes.INVALID_MESSAGE
131
+ );
132
+ }
133
+ const responseData = {
134
+ responder: this.config.accountId,
135
+ proposal_seq: proposalSeq,
136
+ decision,
137
+ reason
138
+ };
139
+ const message = {
140
+ p: "hcs-18",
141
+ op: DiscoveryOperation.RESPOND,
142
+ data: responseData
143
+ };
144
+ await this.sendDiscoveryMessage(message);
145
+ this.emitEvent({
146
+ type: "response_received",
147
+ sequenceNumber: proposalSeq,
148
+ timestamp: /* @__PURE__ */ new Date(),
149
+ data: responseData
150
+ });
151
+ if (decision === "accept") {
152
+ this.state = DiscoveryState.FORMING;
153
+ }
154
+ }
155
+ /**
156
+ * Find compatible Petals for Flora formation
157
+ */
158
+ findCompatiblePetals(filters = {}) {
159
+ const candidates = Array.from(this.announcements.values()).filter((announcement) => {
160
+ if (announcement.account === this.config.accountId) {
161
+ return false;
162
+ }
163
+ if (filters.protocols?.length) {
164
+ const hasCompatibleProtocol = filters.protocols.some(
165
+ (protocol) => announcement.data.capabilities.protocols.includes(protocol)
166
+ );
167
+ if (!hasCompatibleProtocol) return false;
168
+ }
169
+ if (filters.minPriority && announcement.data.petal.priority < filters.minPriority) {
170
+ return false;
171
+ }
172
+ return true;
173
+ }).sort((a, b) => b.data.petal.priority - a.data.petal.priority);
174
+ return filters.maxMembers ? candidates.slice(0, filters.maxMembers) : candidates;
175
+ }
176
+ /**
177
+ * Get current discovery state
178
+ */
179
+ getState() {
180
+ return this.state;
181
+ }
182
+ /**
183
+ * Get tracked announcements
184
+ */
185
+ getAnnouncements() {
186
+ return new Map(this.announcements);
187
+ }
188
+ /**
189
+ * Get tracked proposals
190
+ */
191
+ getProposals() {
192
+ return new Map(this.proposals);
193
+ }
194
+ /**
195
+ * Get Flora formations
196
+ */
197
+ getFormations() {
198
+ return new Map(this.formations);
199
+ }
200
+ /**
201
+ * Complete Flora formation (called by proposer)
202
+ */
203
+ async completeFloraFormation(proposalSeq, floraAccountId, topics) {
204
+ if (!this.client) {
205
+ throw new DiscoveryError(
206
+ "Client required for completion",
207
+ DiscoveryErrorCodes.INVALID_STATE
208
+ );
209
+ }
210
+ const proposal = this.proposals.get(proposalSeq);
211
+ if (!proposal) {
212
+ throw new DiscoveryError(
213
+ `Proposal ${proposalSeq} not found`,
214
+ DiscoveryErrorCodes.INVALID_MESSAGE
215
+ );
216
+ }
217
+ const message = {
218
+ p: "hcs-18",
219
+ op: DiscoveryOperation.COMPLETE,
220
+ data: {
221
+ proposer: this.config.accountId,
222
+ proposal_seq: proposalSeq,
223
+ flora_account: floraAccountId,
224
+ topics
225
+ }
226
+ };
227
+ await this.sendDiscoveryMessage(message);
228
+ const formation = {
229
+ proposalSeq,
230
+ floraAccountId,
231
+ topics,
232
+ members: proposal.data.members.map((m) => ({
233
+ account: m.account,
234
+ priority: m.priority
235
+ })),
236
+ threshold: proposal.data.config.threshold,
237
+ createdAt: /* @__PURE__ */ new Date()
238
+ };
239
+ this.formations.set(proposalSeq, formation);
240
+ this.state = DiscoveryState.ACTIVE;
241
+ this.emitEvent({
242
+ type: "formation_complete",
243
+ sequenceNumber: proposalSeq,
244
+ timestamp: /* @__PURE__ */ new Date(),
245
+ data: formation
246
+ });
247
+ }
248
+ /**
249
+ * Withdraw from discovery
250
+ */
251
+ async withdraw(reason) {
252
+ if (!this.client || !this.myAnnouncementSeq) {
253
+ throw new DiscoveryError(
254
+ "No active announcement to withdraw",
255
+ DiscoveryErrorCodes.INVALID_STATE
256
+ );
257
+ }
258
+ const message = {
259
+ p: "hcs-18",
260
+ op: DiscoveryOperation.WITHDRAW,
261
+ data: {
262
+ account: this.config.accountId,
263
+ announce_seq: this.myAnnouncementSeq,
264
+ reason
265
+ }
266
+ };
267
+ await this.sendDiscoveryMessage(message);
268
+ this.state = DiscoveryState.WITHDRAWN;
269
+ this.emitEvent({
270
+ type: "withdrawal_received",
271
+ timestamp: /* @__PURE__ */ new Date(),
272
+ data: message.data
273
+ });
274
+ }
275
+ /**
276
+ * Sync discovery topic and process messages
277
+ */
278
+ async syncDiscoveryTopic() {
279
+ try {
280
+ const messages = await this.mirrorNode.getTopicMessages(
281
+ this.config.discoveryTopicId.toString(),
282
+ {
283
+ sequenceNumber: this.lastSequenceNumber + 1
284
+ }
285
+ );
286
+ for (const message of messages) {
287
+ try {
288
+ if (message.p !== "hcs-18") {
289
+ continue;
290
+ }
291
+ const discoveryMessage = message;
292
+ await this.processDiscoveryMessage(
293
+ discoveryMessage,
294
+ message.sequence_number
295
+ );
296
+ this.lastSequenceNumber = message.sequence_number;
297
+ } catch (error) {
298
+ if (error instanceof DiscoveryError && error.code === DiscoveryErrorCodes.FLORA_CREATION_FAILED) {
299
+ return;
300
+ }
301
+ }
302
+ }
303
+ } catch (error) {
304
+ this.logger.error("Failed to sync discovery topic", error);
305
+ }
306
+ }
307
+ /**
308
+ * Process discovered messages
309
+ */
310
+ async processDiscoveryMessage(message, sequenceNumber) {
311
+ switch (message.op) {
312
+ case DiscoveryOperation.ANNOUNCE:
313
+ await this.handleAnnouncement(
314
+ message,
315
+ sequenceNumber
316
+ );
317
+ break;
318
+ case DiscoveryOperation.PROPOSE:
319
+ await this.handleProposal(message, sequenceNumber);
320
+ break;
321
+ case DiscoveryOperation.RESPOND:
322
+ await this.handleResponse(message, sequenceNumber);
323
+ break;
324
+ case DiscoveryOperation.COMPLETE:
325
+ await this.handleCompletion(message, sequenceNumber);
326
+ break;
327
+ case DiscoveryOperation.WITHDRAW:
328
+ await this.handleWithdrawal(message, sequenceNumber);
329
+ break;
330
+ }
331
+ }
332
+ /**
333
+ * Handle announcement message
334
+ */
335
+ async handleAnnouncement(message, sequenceNumber) {
336
+ const announcement = {
337
+ account: message.data.account,
338
+ sequenceNumber,
339
+ consensusTimestamp: (/* @__PURE__ */ new Date()).toISOString(),
340
+ data: message.data
341
+ };
342
+ this.announcements.set(sequenceNumber, announcement);
343
+ if (message.data.account === this.config.accountId) {
344
+ return;
345
+ }
346
+ this.emitEvent({
347
+ type: "announcement_received",
348
+ sequenceNumber,
349
+ timestamp: /* @__PURE__ */ new Date(),
350
+ data: message.data
351
+ });
352
+ }
353
+ /**
354
+ * Handle proposal message
355
+ */
356
+ async handleProposal(message, sequenceNumber) {
357
+ const proposal = {
358
+ sequenceNumber,
359
+ consensusTimestamp: (/* @__PURE__ */ new Date()).toISOString(),
360
+ proposer: message.data.proposer,
361
+ data: message.data,
362
+ responses: /* @__PURE__ */ new Map()
363
+ };
364
+ this.proposals.set(sequenceNumber, proposal);
365
+ if (this.config.autoAcceptFilter?.(proposal)) {
366
+ await this.respondToProposal(sequenceNumber, "accept");
367
+ }
368
+ const isIncluded = message.data.members.some(
369
+ (m) => m.account === this.config.accountId
370
+ );
371
+ if (isIncluded) {
372
+ this.emitEvent({
373
+ type: "proposal_received",
374
+ sequenceNumber,
375
+ timestamp: /* @__PURE__ */ new Date(),
376
+ data: message.data
377
+ });
378
+ }
379
+ }
380
+ /**
381
+ * Handle response message
382
+ */
383
+ async handleResponse(message, sequenceNumber) {
384
+ const proposal = this.proposals.get(message.data.proposal_seq);
385
+ if (proposal) {
386
+ proposal.responses.set(message.data.responder, message.data);
387
+ if (this.isProposalReady(proposal)) {
388
+ if (proposal.data.proposer === this.config.accountId && this.floraClient && !this.floraCreationInProgress.has(message.data.proposal_seq)) {
389
+ this.floraCreationInProgress.add(message.data.proposal_seq);
390
+ try {
391
+ await this.createFloraFromProposal(proposal);
392
+ } finally {
393
+ this.floraCreationInProgress.delete(message.data.proposal_seq);
394
+ }
395
+ }
396
+ }
397
+ }
398
+ this.emitEvent({
399
+ type: "response_received",
400
+ sequenceNumber,
401
+ timestamp: /* @__PURE__ */ new Date(),
402
+ data: message.data
403
+ });
404
+ }
405
+ /**
406
+ * Handle completion message
407
+ */
408
+ async handleCompletion(message, sequenceNumber) {
409
+ const formation = {
410
+ proposalSeq: message.data.proposal_seq,
411
+ floraAccountId: message.data.flora_account,
412
+ topics: message.data.topics,
413
+ members: [],
414
+ threshold: 0,
415
+ createdAt: /* @__PURE__ */ new Date()
416
+ };
417
+ if (this.isPartOfFormation(formation)) {
418
+ this.state = DiscoveryState.ACTIVE;
419
+ }
420
+ this.formations.set(message.data.proposal_seq, formation);
421
+ this.emitEvent({
422
+ type: "formation_complete",
423
+ sequenceNumber,
424
+ timestamp: /* @__PURE__ */ new Date(),
425
+ data: formation
426
+ });
427
+ }
428
+ /**
429
+ * Handle withdrawal message
430
+ */
431
+ async handleWithdrawal(message, sequenceNumber) {
432
+ this.announcements.delete(message.data.announce_seq);
433
+ this.emitEvent({
434
+ type: "withdrawal_received",
435
+ sequenceNumber,
436
+ timestamp: /* @__PURE__ */ new Date(),
437
+ data: message.data
438
+ });
439
+ }
440
+ /**
441
+ * Check if proposal has enough responses
442
+ */
443
+ isProposalReady(proposal) {
444
+ const acceptances = Array.from(proposal.responses.values()).filter(
445
+ (r) => r.decision === "accept"
446
+ );
447
+ const requiredResponses = proposal.data.members.length - 1;
448
+ return acceptances.length >= requiredResponses;
449
+ }
450
+ /**
451
+ * Check if we're part of a Flora formation
452
+ */
453
+ isPartOfFormation(formation) {
454
+ return formation.members.some((m) => m.account === this.config.accountId);
455
+ }
456
+ /**
457
+ * Create Flora from accepted proposal
458
+ */
459
+ async createFloraFromProposal(proposal) {
460
+ if (!this.floraClient) {
461
+ throw new DiscoveryError(
462
+ "Flora client not available",
463
+ DiscoveryErrorCodes.FLORA_CREATION_FAILED
464
+ );
465
+ }
466
+ try {
467
+ const memberPubKeys = await Promise.all(
468
+ proposal.data.members.map(async (m) => {
469
+ const accountInfo = await this.mirrorNode.requestAccount(m.account);
470
+ const privateKey = this.config.memberPrivateKeys?.get(m.account);
471
+ return {
472
+ accountId: m.account,
473
+ publicKey: PublicKey.fromString(accountInfo.key.key),
474
+ privateKey
475
+ // Include private key if available
476
+ };
477
+ })
478
+ );
479
+ if (!memberPubKeys[0].privateKey) {
480
+ throw new DiscoveryError(
481
+ "First member must have private key for Flora profile creation",
482
+ DiscoveryErrorCodes.FLORA_CREATION_FAILED
483
+ );
484
+ }
485
+ const floraResult = await this.floraClient.createFlora({
486
+ members: memberPubKeys,
487
+ threshold: proposal.data.config.threshold,
488
+ initialBalance: 10,
489
+ displayName: proposal.data.config.name
490
+ });
491
+ await this.completeFloraFormation(
492
+ proposal.sequenceNumber,
493
+ floraResult.floraAccountId.toString(),
494
+ {
495
+ communication: floraResult.topics.communication.toString(),
496
+ transaction: floraResult.topics.transaction.toString(),
497
+ state: floraResult.topics.state.toString()
498
+ }
499
+ );
500
+ } catch (error) {
501
+ this.logger.error("Failed to create Flora", { error: error instanceof Error ? error.message : error });
502
+ return;
503
+ }
504
+ }
505
+ /**
506
+ * Send message to discovery topic
507
+ */
508
+ async sendDiscoveryMessage(message) {
509
+ if (!this.client) {
510
+ throw new DiscoveryError(
511
+ "Client required for sending messages",
512
+ DiscoveryErrorCodes.INVALID_STATE
513
+ );
514
+ }
515
+ const payload = JSON.stringify(message);
516
+ const transaction = new TopicMessageSubmitTransaction().setTopicId(this.config.discoveryTopicId).setMessage(payload);
517
+ const response = await transaction.execute(this.client);
518
+ const receipt = await response.getReceipt(this.client);
519
+ return receipt.topicSequenceNumber.toNumber();
520
+ }
521
+ /**
522
+ * Emit discovery event
523
+ */
524
+ emitEvent(event) {
525
+ if (this.eventEmitter) {
526
+ this.eventEmitter(event);
527
+ }
23
528
  }
24
529
  }
25
- const DiscoveryErrorCodes = {
26
- INVALID_MESSAGE: "INVALID_MESSAGE",
27
- TIMEOUT: "TIMEOUT",
28
- INSUFFICIENT_PETALS: "INSUFFICIENT_PETALS",
29
- FLORA_CREATION_FAILED: "FLORA_CREATION_FAILED",
30
- ALREADY_IN_DISCOVERY: "ALREADY_IN_DISCOVERY",
31
- INVALID_STATE: "INVALID_STATE"
32
- };
33
530
  export {
34
- DiscoveryError,
35
- DiscoveryErrorCodes,
36
- DiscoveryOperation,
37
- DiscoveryState
531
+ FloraDiscovery,
532
+ FloraDiscovery as HCS18Discovery
38
533
  };
39
534
  //# sourceMappingURL=standards-sdk.es33.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"standards-sdk.es33.js","sources":["../../src/hcs-18/types.ts"],"sourcesContent":["/**\n * HCS-18 Flora Discovery Protocol Types\n * Standard for Flora discovery and formation\n */\n\nimport { AccountId, TopicId, PublicKey } from '@hashgraph/sdk';\n\n/**\n * HCS-18 Operation types\n */\nexport enum DiscoveryOperation {\n ANNOUNCE = 'announce',\n PROPOSE = 'propose',\n RESPOND = 'respond',\n COMPLETE = 'complete',\n WITHDRAW = 'withdraw',\n}\n\n/**\n * Base HCS-18 message structure\n */\nexport interface DiscoveryMessage {\n p: 'hcs-18';\n op: DiscoveryOperation;\n data: any;\n}\n\n/**\n * Announce operation data\n */\nexport interface AnnounceData {\n account: string;\n petal: {\n name: string;\n priority: number;\n };\n capabilities: {\n protocols: string[];\n resources?: {\n compute?: 'high' | 'medium' | 'low';\n storage?: 'high' | 'medium' | 'low';\n bandwidth?: 'high' | 'medium' | 'low';\n };\n group_preferences?: {\n sizes?: number[];\n threshold_ratios?: number[];\n };\n };\n valid_for?: number;\n}\n\n/**\n * Propose operation data\n */\nexport interface ProposeData {\n proposer: string;\n members: Array<{\n account: string;\n announce_seq?: number;\n priority: number;\n status?: 'existing' | 'proposed';\n }>;\n config: {\n name: string;\n threshold: number;\n purpose?: string;\n reason?: string;\n };\n existing_flora?: string;\n}\n\n/**\n * Respond operation data\n */\nexport interface RespondData {\n responder: string;\n proposal_seq: number;\n decision: 'accept' | 'reject';\n reason?: string;\n accepted_seq?: number;\n}\n\n/**\n * Complete operation data\n */\nexport interface CompleteData {\n proposer: string;\n proposal_seq: number;\n flora_account: string;\n topics: {\n communication: string;\n transaction: string;\n state: string;\n };\n}\n\n/**\n * Withdraw operation data\n */\nexport interface WithdrawData {\n account: string;\n announce_seq: number;\n reason?: string;\n}\n\n/**\n * Typed message operations\n */\nexport interface AnnounceMessage extends DiscoveryMessage {\n op: DiscoveryOperation.ANNOUNCE;\n data: AnnounceData;\n}\n\nexport interface ProposeMessage extends DiscoveryMessage {\n op: DiscoveryOperation.PROPOSE;\n data: ProposeData;\n}\n\nexport interface RespondMessage extends DiscoveryMessage {\n op: DiscoveryOperation.RESPOND;\n data: RespondData;\n}\n\nexport interface CompleteMessage extends DiscoveryMessage {\n op: DiscoveryOperation.COMPLETE;\n data: CompleteData;\n}\n\nexport interface WithdrawMessage extends DiscoveryMessage {\n op: DiscoveryOperation.WITHDRAW;\n data: WithdrawData;\n}\n\n/**\n * Discovery phase states\n */\nexport enum DiscoveryState {\n IDLE = 'idle',\n ANNOUNCED = 'announced',\n PROPOSING = 'proposing',\n FORMING = 'forming',\n ACTIVE = 'active',\n WITHDRAWN = 'withdrawn',\n}\n\n/**\n * Tracked announcement with HCS metadata\n */\nexport interface TrackedAnnouncement {\n account: string;\n sequenceNumber: number;\n consensusTimestamp: string;\n data: AnnounceData;\n}\n\n/**\n * Tracked proposal with HCS metadata\n */\nexport interface TrackedProposal {\n sequenceNumber: number;\n consensusTimestamp: string;\n proposer: string;\n data: ProposeData;\n responses: Map<string, RespondData>;\n}\n\n/**\n * Flora formation result\n */\nexport interface FloraFormation {\n proposalSeq: number;\n floraAccountId: string;\n topics: {\n communication: string;\n transaction: string;\n state: string;\n };\n members: Array<{\n account: string;\n priority: number;\n }>;\n threshold: number;\n createdAt: Date;\n}\n\n/**\n * Discovery event types for monitoring\n */\nexport interface DiscoveryEvent {\n type:\n | 'announcement_received'\n | 'proposal_received'\n | 'response_received'\n | 'formation_complete'\n | 'withdrawal_received'\n | 'discovery_timeout';\n sequenceNumber?: number;\n timestamp: Date;\n data: any;\n}\n\n/**\n * Discovery configuration\n */\nexport interface DiscoveryConfig {\n discoveryTopicId: string | TopicId;\n accountId: string;\n petalName: string;\n priority: number;\n capabilities: {\n protocols: string[];\n resources?: AnnounceData['capabilities']['resources'];\n group_preferences?: AnnounceData['capabilities']['group_preferences'];\n };\n autoAcceptFilter?: (proposal: TrackedProposal) => boolean;\n onDiscoveryEvent?: (event: DiscoveryEvent) => void;\n}\n\n/**\n * HCS-18 Errors\n */\nexport class DiscoveryError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n ) {\n super(message);\n this.name = 'DiscoveryError';\n }\n}\n\nexport const DiscoveryErrorCodes = {\n INVALID_MESSAGE: 'INVALID_MESSAGE',\n TIMEOUT: 'TIMEOUT',\n INSUFFICIENT_PETALS: 'INSUFFICIENT_PETALS',\n FLORA_CREATION_FAILED: 'FLORA_CREATION_FAILED',\n ALREADY_IN_DISCOVERY: 'ALREADY_IN_DISCOVERY',\n INVALID_STATE: 'INVALID_STATE',\n} as const;\n"],"names":["DiscoveryOperation","DiscoveryState"],"mappings":"AAUO,IAAK,uCAAAA,wBAAL;AACLA,sBAAA,UAAA,IAAW;AACXA,sBAAA,SAAA,IAAU;AACVA,sBAAA,SAAA,IAAU;AACVA,sBAAA,UAAA,IAAW;AACXA,sBAAA,UAAA,IAAW;AALD,SAAAA;AAAA,GAAA,sBAAA,CAAA,CAAA;AA8HL,IAAK,mCAAAC,oBAAL;AACLA,kBAAA,MAAA,IAAO;AACPA,kBAAA,WAAA,IAAY;AACZA,kBAAA,WAAA,IAAY;AACZA,kBAAA,SAAA,IAAU;AACVA,kBAAA,QAAA,IAAS;AACTA,kBAAA,WAAA,IAAY;AANF,SAAAA;AAAA,GAAA,kBAAA,CAAA,CAAA;AAqFL,MAAM,uBAAuB,MAAM;AAAA,EACxC,YACE,SACgB,MAChB;AACA,UAAM,OAAO;AAFG,SAAA,OAAA;AAGhB,SAAK,OAAO;AAAA,EACd;AACF;AAEO,MAAM,sBAAsB;AAAA,EACjC,iBAAiB;AAAA,EACjB,SAAS;AAAA,EACT,qBAAqB;AAAA,EACrB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,eAAe;AACjB;"}
1
+ {"version":3,"file":"standards-sdk.es33.js","sources":["../../src/hcs-18/discovery.ts"],"sourcesContent":["import {\n TopicId,\n AccountId,\n Client,\n TopicMessageSubmitTransaction,\n} from '@hashgraph/sdk';\nimport { HCS10BaseClient } from '../hcs-10/base-client';\nimport { HederaMirrorNode } from '../services/mirror-node';\nimport { Logger } from '../utils/logger';\nimport type { NetworkType } from '../utils/types';\nimport {\n DiscoveryConfig,\n DiscoveryState,\n DiscoveryMessage,\n DiscoveryOperation,\n AnnounceMessage,\n ProposeMessage,\n RespondMessage,\n CompleteMessage,\n WithdrawMessage,\n TrackedAnnouncement,\n TrackedProposal,\n FloraFormation,\n DiscoveryEvent,\n DiscoveryError,\n DiscoveryErrorCodes,\n AnnounceData,\n ProposeData,\n RespondData,\n} from './types';\nimport { FloraAccountManager } from '../hcs-16/flora-account-manager';\nimport { PublicKey } from '@hashgraph/sdk';\n\n/**\n * HCS-18 Flora Discovery Service\n */\nexport class FloraDiscovery {\n private state: DiscoveryState = DiscoveryState.IDLE;\n private config: DiscoveryConfig;\n private mirrorNode: HederaMirrorNode;\n private logger: Logger;\n private client?: Client;\n private floraClient?: FloraAccountManager;\n\n private lastSequenceNumber = 0;\n private announcements = new Map<number, TrackedAnnouncement>();\n private proposals = new Map<number, TrackedProposal>();\n private formations = new Map<number, FloraFormation>();\n private myAnnouncementSeq?: number;\n private eventEmitter?: (event: DiscoveryEvent) => void;\n private floraCreationInProgress = new Set<number>(); // Track proposals being processed\n\n constructor(\n config: DiscoveryConfig,\n baseClient: HCS10BaseClient,\n client?: Client,\n logger?: Logger,\n ) {\n this.config = config;\n this.mirrorNode = baseClient.mirrorNode;\n this.logger = logger || new Logger({ module: 'FloraDiscovery' });\n this.client = client;\n this.eventEmitter = config.onDiscoveryEvent;\n\n if (client) {\n this.floraClient = new FloraAccountManager(\n client,\n baseClient.network as NetworkType,\n this.logger,\n );\n }\n }\n\n /**\n * Start discovery service\n */\n async startDiscovery(): Promise<void> {\n if (this.state !== DiscoveryState.IDLE) {\n throw new DiscoveryError(\n 'Discovery already started',\n DiscoveryErrorCodes.ALREADY_IN_DISCOVERY,\n );\n }\n\n this.logger.info('Starting Flora discovery');\n await this.syncDiscoveryTopic();\n this.state = DiscoveryState.ANNOUNCED;\n }\n\n /**\n * Announce Petal availability\n */\n async announceAvailability(validFor = 10000): Promise<number> {\n if (!this.client) {\n throw new DiscoveryError(\n 'Client required for announcements',\n DiscoveryErrorCodes.INVALID_STATE,\n );\n }\n\n const message: AnnounceMessage = {\n p: 'hcs-18',\n op: DiscoveryOperation.ANNOUNCE,\n data: {\n account: this.config.accountId,\n petal: {\n name: this.config.petalName,\n priority: this.config.priority,\n },\n capabilities: this.config.capabilities,\n valid_for: validFor,\n },\n };\n\n const sequenceNumber = await this.sendDiscoveryMessage(message);\n this.myAnnouncementSeq = sequenceNumber;\n this.state = DiscoveryState.ANNOUNCED;\n\n this.emitEvent({\n type: 'announcement_received',\n sequenceNumber,\n timestamp: new Date(),\n data: message.data,\n });\n\n return sequenceNumber;\n }\n\n /**\n * Propose Flora formation\n */\n async proposeFloraFormation(\n memberAccounts: string[],\n config: {\n name: string;\n threshold: number;\n purpose?: string;\n },\n ): Promise<number> {\n if (!this.client) {\n throw new DiscoveryError(\n 'Client required for proposals',\n DiscoveryErrorCodes.INVALID_STATE,\n );\n }\n\n const members = memberAccounts.map(account => {\n const announcement = Array.from(this.announcements.values()).find(\n a => a.account === account,\n );\n return {\n account,\n announce_seq: announcement?.sequenceNumber,\n priority: announcement?.data.petal.priority || 500,\n };\n });\n\n const proposeData: ProposeData = {\n proposer: this.config.accountId,\n members,\n config,\n };\n\n const message: ProposeMessage = {\n p: 'hcs-18',\n op: DiscoveryOperation.PROPOSE,\n data: proposeData,\n };\n\n const sequenceNumber = await this.sendDiscoveryMessage(message);\n this.state = DiscoveryState.PROPOSING;\n\n this.emitEvent({\n type: 'proposal_received',\n sequenceNumber,\n timestamp: new Date(),\n data: proposeData,\n });\n\n return sequenceNumber;\n }\n\n /**\n * Respond to Flora proposal\n */\n async respondToProposal(\n proposalSeq: number,\n decision: 'accept' | 'reject',\n reason?: string,\n ): Promise<void> {\n if (!this.client) {\n throw new DiscoveryError(\n 'Client required for responses',\n DiscoveryErrorCodes.INVALID_STATE,\n );\n }\n\n await this.syncDiscoveryTopic();\n\n const proposal = this.proposals.get(proposalSeq);\n if (!proposal) {\n throw new DiscoveryError(\n `Proposal ${proposalSeq} not found`,\n DiscoveryErrorCodes.INVALID_MESSAGE,\n );\n }\n\n const responseData: RespondData = {\n responder: this.config.accountId,\n proposal_seq: proposalSeq,\n decision,\n reason,\n };\n\n const message: RespondMessage = {\n p: 'hcs-18',\n op: DiscoveryOperation.RESPOND,\n data: responseData,\n };\n\n await this.sendDiscoveryMessage(message);\n\n this.emitEvent({\n type: 'response_received',\n sequenceNumber: proposalSeq,\n timestamp: new Date(),\n data: responseData,\n });\n\n if (decision === 'accept') {\n this.state = DiscoveryState.FORMING;\n }\n }\n\n /**\n * Find compatible Petals for Flora formation\n */\n findCompatiblePetals(\n filters: {\n protocols?: string[];\n minPriority?: number;\n maxMembers?: number;\n resourceRequirements?: {\n compute?: 'high' | 'medium' | 'low';\n storage?: 'high' | 'medium' | 'low';\n bandwidth?: 'high' | 'medium' | 'low';\n };\n } = {},\n ): TrackedAnnouncement[] {\n const candidates = Array.from(this.announcements.values())\n .filter(announcement => {\n if (announcement.account === this.config.accountId) {\n return false;\n }\n\n if (filters.protocols?.length) {\n const hasCompatibleProtocol = filters.protocols.some(protocol =>\n announcement.data.capabilities.protocols.includes(protocol),\n );\n if (!hasCompatibleProtocol) return false;\n }\n\n if (\n filters.minPriority &&\n announcement.data.petal.priority < filters.minPriority\n ) {\n return false;\n }\n\n return true;\n })\n .sort((a, b) => b.data.petal.priority - a.data.petal.priority);\n\n return filters.maxMembers\n ? candidates.slice(0, filters.maxMembers)\n : candidates;\n }\n\n /**\n * Get current discovery state\n */\n getState(): DiscoveryState {\n return this.state;\n }\n\n /**\n * Get tracked announcements\n */\n getAnnouncements(): Map<number, TrackedAnnouncement> {\n return new Map(this.announcements);\n }\n\n /**\n * Get tracked proposals\n */\n getProposals(): Map<number, TrackedProposal> {\n return new Map(this.proposals);\n }\n\n /**\n * Get Flora formations\n */\n getFormations(): Map<number, FloraFormation> {\n return new Map(this.formations);\n }\n\n /**\n * Complete Flora formation (called by proposer)\n */\n async completeFloraFormation(\n proposalSeq: number,\n floraAccountId: string,\n topics: {\n communication: string;\n transaction: string;\n state: string;\n },\n ): Promise<void> {\n if (!this.client) {\n throw new DiscoveryError(\n 'Client required for completion',\n DiscoveryErrorCodes.INVALID_STATE,\n );\n }\n\n const proposal = this.proposals.get(proposalSeq);\n if (!proposal) {\n throw new DiscoveryError(\n `Proposal ${proposalSeq} not found`,\n DiscoveryErrorCodes.INVALID_MESSAGE,\n );\n }\n\n const message: CompleteMessage = {\n p: 'hcs-18',\n op: DiscoveryOperation.COMPLETE,\n data: {\n proposer: this.config.accountId,\n proposal_seq: proposalSeq,\n flora_account: floraAccountId,\n topics,\n },\n };\n\n await this.sendDiscoveryMessage(message);\n\n const formation: FloraFormation = {\n proposalSeq,\n floraAccountId,\n topics,\n members: proposal.data.members.map(m => ({\n account: m.account,\n priority: m.priority,\n })),\n threshold: proposal.data.config.threshold,\n createdAt: new Date(),\n };\n\n this.formations.set(proposalSeq, formation);\n this.state = DiscoveryState.ACTIVE;\n\n this.emitEvent({\n type: 'formation_complete',\n sequenceNumber: proposalSeq,\n timestamp: new Date(),\n data: formation,\n });\n }\n\n /**\n * Withdraw from discovery\n */\n async withdraw(reason?: string): Promise<void> {\n if (!this.client || !this.myAnnouncementSeq) {\n throw new DiscoveryError(\n 'No active announcement to withdraw',\n DiscoveryErrorCodes.INVALID_STATE,\n );\n }\n\n const message: WithdrawMessage = {\n p: 'hcs-18',\n op: DiscoveryOperation.WITHDRAW,\n data: {\n account: this.config.accountId,\n announce_seq: this.myAnnouncementSeq,\n reason,\n },\n };\n\n await this.sendDiscoveryMessage(message);\n this.state = DiscoveryState.WITHDRAWN;\n\n this.emitEvent({\n type: 'withdrawal_received',\n timestamp: new Date(),\n data: message.data,\n });\n }\n\n /**\n * Sync discovery topic and process messages\n */\n private async syncDiscoveryTopic(): Promise<void> {\n try {\n const messages = await this.mirrorNode.getTopicMessages(\n this.config.discoveryTopicId.toString(),\n {\n sequenceNumber: this.lastSequenceNumber + 1,\n },\n );\n\n for (const message of messages) {\n try {\n if (message.p !== 'hcs-18') {\n continue;\n }\n\n const discoveryMessage = message as unknown as DiscoveryMessage;\n await this.processDiscoveryMessage(\n discoveryMessage,\n message.sequence_number!,\n );\n this.lastSequenceNumber = message.sequence_number!;\n } catch (error) {\n if (error instanceof DiscoveryError && error.code === DiscoveryErrorCodes.FLORA_CREATION_FAILED) {\n return;\n }\n }\n }\n\n } catch (error) {\n this.logger.error('Failed to sync discovery topic', error);\n }\n }\n\n /**\n * Process discovered messages\n */\n private async processDiscoveryMessage(\n message: DiscoveryMessage,\n sequenceNumber: number,\n ): Promise<void> {\n switch (message.op) {\n case DiscoveryOperation.ANNOUNCE:\n await this.handleAnnouncement(\n message as AnnounceMessage,\n sequenceNumber,\n );\n break;\n case DiscoveryOperation.PROPOSE:\n await this.handleProposal(message as ProposeMessage, sequenceNumber);\n break;\n case DiscoveryOperation.RESPOND:\n await this.handleResponse(message as RespondMessage, sequenceNumber);\n break;\n case DiscoveryOperation.COMPLETE:\n await this.handleCompletion(message as CompleteMessage, sequenceNumber);\n break;\n case DiscoveryOperation.WITHDRAW:\n await this.handleWithdrawal(message as WithdrawMessage, sequenceNumber);\n break;\n }\n }\n\n /**\n * Handle announcement message\n */\n private async handleAnnouncement(\n message: AnnounceMessage,\n sequenceNumber: number,\n ): Promise<void> {\n const announcement: TrackedAnnouncement = {\n account: message.data.account,\n sequenceNumber,\n consensusTimestamp: new Date().toISOString(),\n data: message.data,\n };\n\n this.announcements.set(sequenceNumber, announcement);\n\n if (message.data.account === this.config.accountId) {\n return;\n }\n\n this.emitEvent({\n type: 'announcement_received',\n sequenceNumber,\n timestamp: new Date(),\n data: message.data,\n });\n }\n\n /**\n * Handle proposal message\n */\n private async handleProposal(\n message: ProposeMessage,\n sequenceNumber: number,\n ): Promise<void> {\n const proposal: TrackedProposal = {\n sequenceNumber,\n consensusTimestamp: new Date().toISOString(),\n proposer: message.data.proposer,\n data: message.data,\n responses: new Map(),\n };\n\n this.proposals.set(sequenceNumber, proposal);\n\n if (this.config.autoAcceptFilter?.(proposal)) {\n await this.respondToProposal(sequenceNumber, 'accept');\n }\n\n const isIncluded = message.data.members.some(\n m => m.account === this.config.accountId,\n );\n\n if (isIncluded) {\n this.emitEvent({\n type: 'proposal_received',\n sequenceNumber,\n timestamp: new Date(),\n data: message.data,\n });\n }\n }\n\n /**\n * Handle response message\n */\n private async handleResponse(\n message: RespondMessage,\n sequenceNumber: number,\n ): Promise<void> {\n const proposal = this.proposals.get(message.data.proposal_seq);\n if (proposal) {\n proposal.responses.set(message.data.responder, message.data);\n\n if (this.isProposalReady(proposal)) {\n if (\n proposal.data.proposer === this.config.accountId &&\n this.floraClient &&\n !this.floraCreationInProgress.has(message.data.proposal_seq)\n ) {\n this.floraCreationInProgress.add(message.data.proposal_seq);\n try {\n await this.createFloraFromProposal(proposal);\n } finally {\n this.floraCreationInProgress.delete(message.data.proposal_seq);\n }\n }\n }\n }\n\n this.emitEvent({\n type: 'response_received',\n sequenceNumber,\n timestamp: new Date(),\n data: message.data,\n });\n }\n\n /**\n * Handle completion message\n */\n private async handleCompletion(\n message: CompleteMessage,\n sequenceNumber: number,\n ): Promise<void> {\n const formation: FloraFormation = {\n proposalSeq: message.data.proposal_seq,\n floraAccountId: message.data.flora_account,\n topics: message.data.topics,\n members: [],\n threshold: 0,\n createdAt: new Date(),\n };\n\n if (this.isPartOfFormation(formation)) {\n this.state = DiscoveryState.ACTIVE;\n }\n\n this.formations.set(message.data.proposal_seq, formation);\n\n this.emitEvent({\n type: 'formation_complete',\n sequenceNumber,\n timestamp: new Date(),\n data: formation,\n });\n }\n\n /**\n * Handle withdrawal message\n */\n private async handleWithdrawal(\n message: WithdrawMessage,\n sequenceNumber: number,\n ): Promise<void> {\n this.announcements.delete(message.data.announce_seq);\n\n this.emitEvent({\n type: 'withdrawal_received',\n sequenceNumber,\n timestamp: new Date(),\n data: message.data,\n });\n }\n\n /**\n * Check if proposal has enough responses\n */\n private isProposalReady(proposal: TrackedProposal): boolean {\n const acceptances = Array.from(proposal.responses.values()).filter(\n r => r.decision === 'accept',\n );\n\n const requiredResponses = proposal.data.members.length - 1;\n return acceptances.length >= requiredResponses;\n }\n\n /**\n * Check if we're part of a Flora formation\n */\n private isPartOfFormation(formation: FloraFormation): boolean {\n return formation.members.some(m => m.account === this.config.accountId);\n }\n\n /**\n * Create Flora from accepted proposal\n */\n private async createFloraFromProposal(\n proposal: TrackedProposal,\n ): Promise<void> {\n if (!this.floraClient) {\n throw new DiscoveryError(\n 'Flora client not available',\n DiscoveryErrorCodes.FLORA_CREATION_FAILED,\n );\n }\n\n try {\n const memberPubKeys = await Promise.all(\n proposal.data.members.map(async m => {\n const accountInfo = await this.mirrorNode.requestAccount(m.account);\n const privateKey = this.config.memberPrivateKeys?.get(m.account);\n return {\n accountId: m.account,\n publicKey: PublicKey.fromString(accountInfo.key.key),\n privateKey, // Include private key if available\n };\n }),\n );\n\n // Ensure at least the first member has a private key for profile creation\n if (!memberPubKeys[0].privateKey) {\n throw new DiscoveryError(\n 'First member must have private key for Flora profile creation',\n DiscoveryErrorCodes.FLORA_CREATION_FAILED,\n );\n }\n\n const floraResult = await this.floraClient.createFlora({\n members: memberPubKeys,\n threshold: proposal.data.config.threshold,\n initialBalance: 10,\n displayName: proposal.data.config.name,\n });\n\n await this.completeFloraFormation(\n proposal.sequenceNumber,\n floraResult.floraAccountId.toString(),\n {\n communication: floraResult.topics.communication.toString(),\n transaction: floraResult.topics.transaction.toString(),\n state: floraResult.topics.state.toString(),\n },\n );\n } catch (error) {\n this.logger.error('Failed to create Flora', { error: error instanceof Error ? error.message : error });\n return;\n }\n }\n\n /**\n * Send message to discovery topic\n */\n private async sendDiscoveryMessage(\n message: DiscoveryMessage,\n ): Promise<number> {\n if (!this.client) {\n throw new DiscoveryError(\n 'Client required for sending messages',\n DiscoveryErrorCodes.INVALID_STATE,\n );\n }\n\n const payload = JSON.stringify(message);\n\n const transaction = new TopicMessageSubmitTransaction()\n .setTopicId(this.config.discoveryTopicId)\n .setMessage(payload);\n\n const response = await transaction.execute(this.client);\n const receipt = await response.getReceipt(this.client);\n\n return receipt.topicSequenceNumber.toNumber();\n }\n\n /**\n * Emit discovery event\n */\n private emitEvent(event: DiscoveryEvent): void {\n if (this.eventEmitter) {\n this.eventEmitter(event);\n }\n }\n}\n\nexport { FloraDiscovery as HCS18Discovery };\n"],"names":[],"mappings":";;;;AAoCO,MAAM,eAAe;AAAA;AAAA,EAgB1B,YACE,QACA,YACA,QACA,QACA;AApBF,SAAQ,QAAwB,eAAe;AAO/C,SAAQ,qBAAqB;AAC7B,SAAQ,oCAAoB,IAAA;AAC5B,SAAQ,gCAAgB,IAAA;AACxB,SAAQ,iCAAiB,IAAA;AAGzB,SAAQ,8CAA8B,IAAA;AAQpC,SAAK,SAAS;AACd,SAAK,aAAa,WAAW;AAC7B,SAAK,SAAS,UAAU,IAAI,OAAO,EAAE,QAAQ,kBAAkB;AAC/D,SAAK,SAAS;AACd,SAAK,eAAe,OAAO;AAE3B,QAAI,QAAQ;AACV,WAAK,cAAc,IAAI;AAAA,QACrB;AAAA,QACA,WAAW;AAAA,QACX,KAAK;AAAA,MAAA;AAAA,IAET;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,iBAAgC;AACpC,QAAI,KAAK,UAAU,eAAe,MAAM;AACtC,YAAM,IAAI;AAAA,QACR;AAAA,QACA,oBAAoB;AAAA,MAAA;AAAA,IAExB;AAEA,SAAK,OAAO,KAAK,0BAA0B;AAC3C,UAAM,KAAK,mBAAA;AACX,SAAK,QAAQ,eAAe;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,qBAAqB,WAAW,KAAwB;AAC5D,QAAI,CAAC,KAAK,QAAQ;AAChB,YAAM,IAAI;AAAA,QACR;AAAA,QACA,oBAAoB;AAAA,MAAA;AAAA,IAExB;AAEA,UAAM,UAA2B;AAAA,MAC/B,GAAG;AAAA,MACH,IAAI,mBAAmB;AAAA,MACvB,MAAM;AAAA,QACJ,SAAS,KAAK,OAAO;AAAA,QACrB,OAAO;AAAA,UACL,MAAM,KAAK,OAAO;AAAA,UAClB,UAAU,KAAK,OAAO;AAAA,QAAA;AAAA,QAExB,cAAc,KAAK,OAAO;AAAA,QAC1B,WAAW;AAAA,MAAA;AAAA,IACb;AAGF,UAAM,iBAAiB,MAAM,KAAK,qBAAqB,OAAO;AAC9D,SAAK,oBAAoB;AACzB,SAAK,QAAQ,eAAe;AAE5B,SAAK,UAAU;AAAA,MACb,MAAM;AAAA,MACN;AAAA,MACA,+BAAe,KAAA;AAAA,MACf,MAAM,QAAQ;AAAA,IAAA,CACf;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,sBACJ,gBACA,QAKiB;AACjB,QAAI,CAAC,KAAK,QAAQ;AAChB,YAAM,IAAI;AAAA,QACR;AAAA,QACA,oBAAoB;AAAA,MAAA;AAAA,IAExB;AAEA,UAAM,UAAU,eAAe,IAAI,CAAA,YAAW;AAC5C,YAAM,eAAe,MAAM,KAAK,KAAK,cAAc,OAAA,CAAQ,EAAE;AAAA,QAC3D,CAAA,MAAK,EAAE,YAAY;AAAA,MAAA;AAErB,aAAO;AAAA,QACL;AAAA,QACA,cAAc,cAAc;AAAA,QAC5B,UAAU,cAAc,KAAK,MAAM,YAAY;AAAA,MAAA;AAAA,IAEnD,CAAC;AAED,UAAM,cAA2B;AAAA,MAC/B,UAAU,KAAK,OAAO;AAAA,MACtB;AAAA,MACA;AAAA,IAAA;AAGF,UAAM,UAA0B;AAAA,MAC9B,GAAG;AAAA,MACH,IAAI,mBAAmB;AAAA,MACvB,MAAM;AAAA,IAAA;AAGR,UAAM,iBAAiB,MAAM,KAAK,qBAAqB,OAAO;AAC9D,SAAK,QAAQ,eAAe;AAE5B,SAAK,UAAU;AAAA,MACb,MAAM;AAAA,MACN;AAAA,MACA,+BAAe,KAAA;AAAA,MACf,MAAM;AAAA,IAAA,CACP;AAED,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,kBACJ,aACA,UACA,QACe;AACf,QAAI,CAAC,KAAK,QAAQ;AAChB,YAAM,IAAI;AAAA,QACR;AAAA,QACA,oBAAoB;AAAA,MAAA;AAAA,IAExB;AAEA,UAAM,KAAK,mBAAA;AAEX,UAAM,WAAW,KAAK,UAAU,IAAI,WAAW;AAC/C,QAAI,CAAC,UAAU;AACb,YAAM,IAAI;AAAA,QACR,YAAY,WAAW;AAAA,QACvB,oBAAoB;AAAA,MAAA;AAAA,IAExB;AAEA,UAAM,eAA4B;AAAA,MAChC,WAAW,KAAK,OAAO;AAAA,MACvB,cAAc;AAAA,MACd;AAAA,MACA;AAAA,IAAA;AAGF,UAAM,UAA0B;AAAA,MAC9B,GAAG;AAAA,MACH,IAAI,mBAAmB;AAAA,MACvB,MAAM;AAAA,IAAA;AAGR,UAAM,KAAK,qBAAqB,OAAO;AAEvC,SAAK,UAAU;AAAA,MACb,MAAM;AAAA,MACN,gBAAgB;AAAA,MAChB,+BAAe,KAAA;AAAA,MACf,MAAM;AAAA,IAAA,CACP;AAED,QAAI,aAAa,UAAU;AACzB,WAAK,QAAQ,eAAe;AAAA,IAC9B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,qBACE,UASI,IACmB;AACvB,UAAM,aAAa,MAAM,KAAK,KAAK,cAAc,QAAQ,EACtD,OAAO,CAAA,iBAAgB;AACtB,UAAI,aAAa,YAAY,KAAK,OAAO,WAAW;AAClD,eAAO;AAAA,MACT;AAEA,UAAI,QAAQ,WAAW,QAAQ;AAC7B,cAAM,wBAAwB,QAAQ,UAAU;AAAA,UAAK,cACnD,aAAa,KAAK,aAAa,UAAU,SAAS,QAAQ;AAAA,QAAA;AAE5D,YAAI,CAAC,sBAAuB,QAAO;AAAA,MACrC;AAEA,UACE,QAAQ,eACR,aAAa,KAAK,MAAM,WAAW,QAAQ,aAC3C;AACA,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,IACT,CAAC,EACA,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,MAAM,WAAW,EAAE,KAAK,MAAM,QAAQ;AAE/D,WAAO,QAAQ,aACX,WAAW,MAAM,GAAG,QAAQ,UAAU,IACtC;AAAA,EACN;AAAA;AAAA;AAAA;AAAA,EAKA,WAA2B;AACzB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,mBAAqD;AACnD,WAAO,IAAI,IAAI,KAAK,aAAa;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,eAA6C;AAC3C,WAAO,IAAI,IAAI,KAAK,SAAS;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,gBAA6C;AAC3C,WAAO,IAAI,IAAI,KAAK,UAAU;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,uBACJ,aACA,gBACA,QAKe;AACf,QAAI,CAAC,KAAK,QAAQ;AAChB,YAAM,IAAI;AAAA,QACR;AAAA,QACA,oBAAoB;AAAA,MAAA;AAAA,IAExB;AAEA,UAAM,WAAW,KAAK,UAAU,IAAI,WAAW;AAC/C,QAAI,CAAC,UAAU;AACb,YAAM,IAAI;AAAA,QACR,YAAY,WAAW;AAAA,QACvB,oBAAoB;AAAA,MAAA;AAAA,IAExB;AAEA,UAAM,UAA2B;AAAA,MAC/B,GAAG;AAAA,MACH,IAAI,mBAAmB;AAAA,MACvB,MAAM;AAAA,QACJ,UAAU,KAAK,OAAO;AAAA,QACtB,cAAc;AAAA,QACd,eAAe;AAAA,QACf;AAAA,MAAA;AAAA,IACF;AAGF,UAAM,KAAK,qBAAqB,OAAO;AAEvC,UAAM,YAA4B;AAAA,MAChC;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS,SAAS,KAAK,QAAQ,IAAI,CAAA,OAAM;AAAA,QACvC,SAAS,EAAE;AAAA,QACX,UAAU,EAAE;AAAA,MAAA,EACZ;AAAA,MACF,WAAW,SAAS,KAAK,OAAO;AAAA,MAChC,+BAAe,KAAA;AAAA,IAAK;AAGtB,SAAK,WAAW,IAAI,aAAa,SAAS;AAC1C,SAAK,QAAQ,eAAe;AAE5B,SAAK,UAAU;AAAA,MACb,MAAM;AAAA,MACN,gBAAgB;AAAA,MAChB,+BAAe,KAAA;AAAA,MACf,MAAM;AAAA,IAAA,CACP;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,QAAgC;AAC7C,QAAI,CAAC,KAAK,UAAU,CAAC,KAAK,mBAAmB;AAC3C,YAAM,IAAI;AAAA,QACR;AAAA,QACA,oBAAoB;AAAA,MAAA;AAAA,IAExB;AAEA,UAAM,UAA2B;AAAA,MAC/B,GAAG;AAAA,MACH,IAAI,mBAAmB;AAAA,MACvB,MAAM;AAAA,QACJ,SAAS,KAAK,OAAO;AAAA,QACrB,cAAc,KAAK;AAAA,QACnB;AAAA,MAAA;AAAA,IACF;AAGF,UAAM,KAAK,qBAAqB,OAAO;AACvC,SAAK,QAAQ,eAAe;AAE5B,SAAK,UAAU;AAAA,MACb,MAAM;AAAA,MACN,+BAAe,KAAA;AAAA,MACf,MAAM,QAAQ;AAAA,IAAA,CACf;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,qBAAoC;AAChD,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,WAAW;AAAA,QACrC,KAAK,OAAO,iBAAiB,SAAA;AAAA,QAC7B;AAAA,UACE,gBAAgB,KAAK,qBAAqB;AAAA,QAAA;AAAA,MAC5C;AAGF,iBAAW,WAAW,UAAU;AAC9B,YAAI;AACF,cAAI,QAAQ,MAAM,UAAU;AAC1B;AAAA,UACF;AAEA,gBAAM,mBAAmB;AACzB,gBAAM,KAAK;AAAA,YACT;AAAA,YACA,QAAQ;AAAA,UAAA;AAEV,eAAK,qBAAqB,QAAQ;AAAA,QACpC,SAAS,OAAO;AACd,cAAI,iBAAiB,kBAAkB,MAAM,SAAS,oBAAoB,uBAAuB;AAC/F;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IAEF,SAAS,OAAO;AACd,WAAK,OAAO,MAAM,kCAAkC,KAAK;AAAA,IAC3D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,wBACZ,SACA,gBACe;AACf,YAAQ,QAAQ,IAAA;AAAA,MACd,KAAK,mBAAmB;AACtB,cAAM,KAAK;AAAA,UACT;AAAA,UACA;AAAA,QAAA;AAEF;AAAA,MACF,KAAK,mBAAmB;AACtB,cAAM,KAAK,eAAe,SAA2B,cAAc;AACnE;AAAA,MACF,KAAK,mBAAmB;AACtB,cAAM,KAAK,eAAe,SAA2B,cAAc;AACnE;AAAA,MACF,KAAK,mBAAmB;AACtB,cAAM,KAAK,iBAAiB,SAA4B,cAAc;AACtE;AAAA,MACF,KAAK,mBAAmB;AACtB,cAAM,KAAK,iBAAiB,SAA4B,cAAc;AACtE;AAAA,IAAA;AAAA,EAEN;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,mBACZ,SACA,gBACe;AACf,UAAM,eAAoC;AAAA,MACxC,SAAS,QAAQ,KAAK;AAAA,MACtB;AAAA,MACA,qBAAoB,oBAAI,KAAA,GAAO,YAAA;AAAA,MAC/B,MAAM,QAAQ;AAAA,IAAA;AAGhB,SAAK,cAAc,IAAI,gBAAgB,YAAY;AAEnD,QAAI,QAAQ,KAAK,YAAY,KAAK,OAAO,WAAW;AAClD;AAAA,IACF;AAEA,SAAK,UAAU;AAAA,MACb,MAAM;AAAA,MACN;AAAA,MACA,+BAAe,KAAA;AAAA,MACf,MAAM,QAAQ;AAAA,IAAA,CACf;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eACZ,SACA,gBACe;AACf,UAAM,WAA4B;AAAA,MAChC;AAAA,MACA,qBAAoB,oBAAI,KAAA,GAAO,YAAA;AAAA,MAC/B,UAAU,QAAQ,KAAK;AAAA,MACvB,MAAM,QAAQ;AAAA,MACd,+BAAe,IAAA;AAAA,IAAI;AAGrB,SAAK,UAAU,IAAI,gBAAgB,QAAQ;AAE3C,QAAI,KAAK,OAAO,mBAAmB,QAAQ,GAAG;AAC5C,YAAM,KAAK,kBAAkB,gBAAgB,QAAQ;AAAA,IACvD;AAEA,UAAM,aAAa,QAAQ,KAAK,QAAQ;AAAA,MACtC,CAAA,MAAK,EAAE,YAAY,KAAK,OAAO;AAAA,IAAA;AAGjC,QAAI,YAAY;AACd,WAAK,UAAU;AAAA,QACb,MAAM;AAAA,QACN;AAAA,QACA,+BAAe,KAAA;AAAA,QACf,MAAM,QAAQ;AAAA,MAAA,CACf;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eACZ,SACA,gBACe;AACf,UAAM,WAAW,KAAK,UAAU,IAAI,QAAQ,KAAK,YAAY;AAC7D,QAAI,UAAU;AACZ,eAAS,UAAU,IAAI,QAAQ,KAAK,WAAW,QAAQ,IAAI;AAE3D,UAAI,KAAK,gBAAgB,QAAQ,GAAG;AAClC,YACE,SAAS,KAAK,aAAa,KAAK,OAAO,aACvC,KAAK,eACL,CAAC,KAAK,wBAAwB,IAAI,QAAQ,KAAK,YAAY,GAC3D;AACA,eAAK,wBAAwB,IAAI,QAAQ,KAAK,YAAY;AAC1D,cAAI;AACF,kBAAM,KAAK,wBAAwB,QAAQ;AAAA,UAC7C,UAAA;AACE,iBAAK,wBAAwB,OAAO,QAAQ,KAAK,YAAY;AAAA,UAC/D;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,SAAK,UAAU;AAAA,MACb,MAAM;AAAA,MACN;AAAA,MACA,+BAAe,KAAA;AAAA,MACf,MAAM,QAAQ;AAAA,IAAA,CACf;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,iBACZ,SACA,gBACe;AACf,UAAM,YAA4B;AAAA,MAChC,aAAa,QAAQ,KAAK;AAAA,MAC1B,gBAAgB,QAAQ,KAAK;AAAA,MAC7B,QAAQ,QAAQ,KAAK;AAAA,MACrB,SAAS,CAAA;AAAA,MACT,WAAW;AAAA,MACX,+BAAe,KAAA;AAAA,IAAK;AAGtB,QAAI,KAAK,kBAAkB,SAAS,GAAG;AACrC,WAAK,QAAQ,eAAe;AAAA,IAC9B;AAEA,SAAK,WAAW,IAAI,QAAQ,KAAK,cAAc,SAAS;AAExD,SAAK,UAAU;AAAA,MACb,MAAM;AAAA,MACN;AAAA,MACA,+BAAe,KAAA;AAAA,MACf,MAAM;AAAA,IAAA,CACP;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,iBACZ,SACA,gBACe;AACf,SAAK,cAAc,OAAO,QAAQ,KAAK,YAAY;AAEnD,SAAK,UAAU;AAAA,MACb,MAAM;AAAA,MACN;AAAA,MACA,+BAAe,KAAA;AAAA,MACf,MAAM,QAAQ;AAAA,IAAA,CACf;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAgB,UAAoC;AAC1D,UAAM,cAAc,MAAM,KAAK,SAAS,UAAU,OAAA,CAAQ,EAAE;AAAA,MAC1D,CAAA,MAAK,EAAE,aAAa;AAAA,IAAA;AAGtB,UAAM,oBAAoB,SAAS,KAAK,QAAQ,SAAS;AACzD,WAAO,YAAY,UAAU;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAkB,WAAoC;AAC5D,WAAO,UAAU,QAAQ,KAAK,CAAA,MAAK,EAAE,YAAY,KAAK,OAAO,SAAS;AAAA,EACxE;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,wBACZ,UACe;AACf,QAAI,CAAC,KAAK,aAAa;AACrB,YAAM,IAAI;AAAA,QACR;AAAA,QACA,oBAAoB;AAAA,MAAA;AAAA,IAExB;AAEA,QAAI;AACF,YAAM,gBAAgB,MAAM,QAAQ;AAAA,QAClC,SAAS,KAAK,QAAQ,IAAI,OAAM,MAAK;AACnC,gBAAM,cAAc,MAAM,KAAK,WAAW,eAAe,EAAE,OAAO;AAClE,gBAAM,aAAa,KAAK,OAAO,mBAAmB,IAAI,EAAE,OAAO;AAC/D,iBAAO;AAAA,YACL,WAAW,EAAE;AAAA,YACb,WAAW,UAAU,WAAW,YAAY,IAAI,GAAG;AAAA,YACnD;AAAA;AAAA,UAAA;AAAA,QAEJ,CAAC;AAAA,MAAA;AAIH,UAAI,CAAC,cAAc,CAAC,EAAE,YAAY;AAChC,cAAM,IAAI;AAAA,UACR;AAAA,UACA,oBAAoB;AAAA,QAAA;AAAA,MAExB;AAEA,YAAM,cAAc,MAAM,KAAK,YAAY,YAAY;AAAA,QACrD,SAAS;AAAA,QACT,WAAW,SAAS,KAAK,OAAO;AAAA,QAChC,gBAAgB;AAAA,QAChB,aAAa,SAAS,KAAK,OAAO;AAAA,MAAA,CACnC;AAED,YAAM,KAAK;AAAA,QACT,SAAS;AAAA,QACT,YAAY,eAAe,SAAA;AAAA,QAC3B;AAAA,UACE,eAAe,YAAY,OAAO,cAAc,SAAA;AAAA,UAChD,aAAa,YAAY,OAAO,YAAY,SAAA;AAAA,UAC5C,OAAO,YAAY,OAAO,MAAM,SAAA;AAAA,QAAS;AAAA,MAC3C;AAAA,IAEJ,SAAS,OAAO;AACd,WAAK,OAAO,MAAM,0BAA0B,EAAE,OAAO,iBAAiB,QAAQ,MAAM,UAAU,MAAA,CAAO;AACrG;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,qBACZ,SACiB;AACjB,QAAI,CAAC,KAAK,QAAQ;AAChB,YAAM,IAAI;AAAA,QACR;AAAA,QACA,oBAAoB;AAAA,MAAA;AAAA,IAExB;AAEA,UAAM,UAAU,KAAK,UAAU,OAAO;AAEtC,UAAM,cAAc,IAAI,8BAAA,EACrB,WAAW,KAAK,OAAO,gBAAgB,EACvC,WAAW,OAAO;AAErB,UAAM,WAAW,MAAM,YAAY,QAAQ,KAAK,MAAM;AACtD,UAAM,UAAU,MAAM,SAAS,WAAW,KAAK,MAAM;AAErD,WAAO,QAAQ,oBAAoB,SAAA;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKQ,UAAU,OAA6B;AAC7C,QAAI,KAAK,cAAc;AACrB,WAAK,aAAa,KAAK;AAAA,IACzB;AAAA,EACF;AACF;"}