zattera-js 0.1.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.
- package/LICENSE +21 -0
- package/README.md +694 -0
- package/dist/browser/index.js +2466 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/node/auth/index.js +188 -0
- package/dist/node/auth/index.js.map +1 -0
- package/dist/node/auth/keys.js +264 -0
- package/dist/node/auth/keys.js.map +1 -0
- package/dist/node/auth/memo.js +79 -0
- package/dist/node/auth/memo.js.map +1 -0
- package/dist/node/auth/serializer.js +162 -0
- package/dist/node/auth/serializer.js.map +1 -0
- package/dist/node/client/index.js +838 -0
- package/dist/node/client/index.js.map +1 -0
- package/dist/node/index.js +30 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/node_modules/@noble/ciphers/aes.js +254 -0
- package/dist/node/node_modules/@noble/ciphers/aes.js.map +1 -0
- package/dist/node/node_modules/@noble/ciphers/utils.js +113 -0
- package/dist/node/node_modules/@noble/ciphers/utils.js.map +1 -0
- package/dist/node/node_modules/@noble/hashes/esm/_md.js +146 -0
- package/dist/node/node_modules/@noble/hashes/esm/_md.js.map +1 -0
- package/dist/node/node_modules/@noble/hashes/esm/_u64.js +51 -0
- package/dist/node/node_modules/@noble/hashes/esm/_u64.js.map +1 -0
- package/dist/node/node_modules/@noble/hashes/esm/legacy.js +123 -0
- package/dist/node/node_modules/@noble/hashes/esm/legacy.js.map +1 -0
- package/dist/node/node_modules/@noble/hashes/esm/sha2.js +346 -0
- package/dist/node/node_modules/@noble/hashes/esm/sha2.js.map +1 -0
- package/dist/node/node_modules/@noble/hashes/esm/utils.js +73 -0
- package/dist/node/node_modules/@noble/hashes/esm/utils.js.map +1 -0
- package/dist/node/node_modules/@noble/secp256k1/index.js +578 -0
- package/dist/node/node_modules/@noble/secp256k1/index.js.map +1 -0
- package/dist/node/node_modules/bs58/node_modules/base-x/src/esm/index.js +132 -0
- package/dist/node/node_modules/bs58/node_modules/base-x/src/esm/index.js.map +1 -0
- package/dist/node/node_modules/bs58/src/esm/index.js +7 -0
- package/dist/node/node_modules/bs58/src/esm/index.js.map +1 -0
- package/dist/node/types/index.js +48 -0
- package/dist/node/types/index.js.map +1 -0
- package/dist/node/utils/chain-id.js +9 -0
- package/dist/node/utils/chain-id.js.map +1 -0
- package/dist/types/auth/index.d.ts +134 -0
- package/dist/types/auth/index.d.ts.map +1 -0
- package/dist/types/auth/keys.d.ts +112 -0
- package/dist/types/auth/keys.d.ts.map +1 -0
- package/dist/types/auth/memo.d.ts +51 -0
- package/dist/types/auth/memo.d.ts.map +1 -0
- package/dist/types/auth/serializer.d.ts +57 -0
- package/dist/types/auth/serializer.d.ts.map +1 -0
- package/dist/types/client/index.d.ts +360 -0
- package/dist/types/client/index.d.ts.map +1 -0
- package/dist/types/index.d.ts +16 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +593 -0
- package/dist/types/types/index.d.ts.map +1 -0
- package/dist/types/utils/chain-id.d.ts +10 -0
- package/dist/types/utils/chain-id.d.ts.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
class TransactionSerializer {
|
|
2
|
+
buffer = [];
|
|
3
|
+
/**
|
|
4
|
+
* Write a uint8 (1 byte)
|
|
5
|
+
*/
|
|
6
|
+
writeUInt8(value) {
|
|
7
|
+
this.buffer.push(value & 255);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Write a uint16 (2 bytes, little-endian)
|
|
11
|
+
*/
|
|
12
|
+
writeUInt16(value) {
|
|
13
|
+
this.buffer.push(value & 255);
|
|
14
|
+
this.buffer.push(value >> 8 & 255);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Write a uint32 (4 bytes, little-endian)
|
|
18
|
+
*/
|
|
19
|
+
writeUInt32(value) {
|
|
20
|
+
this.buffer.push(value & 255);
|
|
21
|
+
this.buffer.push(value >> 8 & 255);
|
|
22
|
+
this.buffer.push(value >> 16 & 255);
|
|
23
|
+
this.buffer.push(value >> 24 & 255);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Write a uint64 (8 bytes, little-endian)
|
|
27
|
+
*/
|
|
28
|
+
writeUInt64(value) {
|
|
29
|
+
const bigValue = typeof value === "number" ? BigInt(value) : value;
|
|
30
|
+
for (let i = 0; i < 8; i++) {
|
|
31
|
+
this.buffer.push(Number(bigValue >> BigInt(i * 8) & BigInt(255)));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Write variable-length integer
|
|
36
|
+
*/
|
|
37
|
+
writeVarint32(value) {
|
|
38
|
+
while (value >= 128) {
|
|
39
|
+
this.buffer.push(value & 127 | 128);
|
|
40
|
+
value >>= 7;
|
|
41
|
+
}
|
|
42
|
+
this.buffer.push(value & 127);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Write a string
|
|
46
|
+
*/
|
|
47
|
+
writeString(value) {
|
|
48
|
+
const bytes = new TextEncoder().encode(value);
|
|
49
|
+
this.writeVarint32(bytes.length);
|
|
50
|
+
for (const byte of bytes) {
|
|
51
|
+
this.buffer.push(byte);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Write bytes
|
|
56
|
+
*/
|
|
57
|
+
writeBytes(bytes) {
|
|
58
|
+
for (const byte of bytes) {
|
|
59
|
+
this.buffer.push(byte);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Write array with length prefix
|
|
64
|
+
*/
|
|
65
|
+
writeArray(arr, writeItem) {
|
|
66
|
+
this.writeVarint32(arr.length);
|
|
67
|
+
for (const item of arr) {
|
|
68
|
+
writeItem(item);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Get the serialized buffer
|
|
73
|
+
*/
|
|
74
|
+
toBuffer() {
|
|
75
|
+
return new Uint8Array(this.buffer);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function serializeTransaction(tx) {
|
|
79
|
+
const serializer = new TransactionSerializer();
|
|
80
|
+
serializer.writeUInt16(tx.ref_block_num);
|
|
81
|
+
serializer.writeUInt32(tx.ref_block_prefix);
|
|
82
|
+
const expirationDate = new Date(tx.expiration);
|
|
83
|
+
const expirationSeconds = Math.floor(expirationDate.getTime() / 1e3);
|
|
84
|
+
serializer.writeUInt32(expirationSeconds);
|
|
85
|
+
serializer.writeArray(tx.operations, (op) => {
|
|
86
|
+
serializeOperation(serializer, op);
|
|
87
|
+
});
|
|
88
|
+
serializer.writeArray(tx.extensions, (ext) => {
|
|
89
|
+
if (typeof ext === "object" && ext !== null) {
|
|
90
|
+
serializer.writeString(JSON.stringify(ext));
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
return serializer.toBuffer();
|
|
94
|
+
}
|
|
95
|
+
function serializeOperation(serializer, operation) {
|
|
96
|
+
if (!Array.isArray(operation) || operation.length !== 2) {
|
|
97
|
+
throw new Error("Invalid operation format");
|
|
98
|
+
}
|
|
99
|
+
const [opType, opData] = operation;
|
|
100
|
+
if (typeof opType === "number") {
|
|
101
|
+
serializer.writeVarint32(opType);
|
|
102
|
+
} else if (typeof opType === "string") {
|
|
103
|
+
const opId = getOperationId(opType);
|
|
104
|
+
serializer.writeVarint32(opId);
|
|
105
|
+
}
|
|
106
|
+
serializeOperationData(serializer, opData);
|
|
107
|
+
}
|
|
108
|
+
function getOperationId(opName) {
|
|
109
|
+
const operationIds = {
|
|
110
|
+
vote: 0,
|
|
111
|
+
comment: 1,
|
|
112
|
+
transfer: 2,
|
|
113
|
+
transfer_to_vesting: 3,
|
|
114
|
+
withdraw_vesting: 4,
|
|
115
|
+
limit_order_create: 5,
|
|
116
|
+
limit_order_cancel: 6,
|
|
117
|
+
feed_publish: 7,
|
|
118
|
+
convert: 8,
|
|
119
|
+
account_create: 9,
|
|
120
|
+
account_update: 10,
|
|
121
|
+
witness_update: 11,
|
|
122
|
+
account_witness_vote: 12,
|
|
123
|
+
account_witness_proxy: 13
|
|
124
|
+
// ... more operations
|
|
125
|
+
};
|
|
126
|
+
return operationIds[opName] ?? -1;
|
|
127
|
+
}
|
|
128
|
+
function serializeOperationData(serializer, data) {
|
|
129
|
+
if (data === null || data === void 0) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (typeof data === "string") {
|
|
133
|
+
serializer.writeString(data);
|
|
134
|
+
} else if (typeof data === "number") {
|
|
135
|
+
serializer.writeUInt32(data);
|
|
136
|
+
} else if (typeof data === "boolean") {
|
|
137
|
+
serializer.writeUInt8(data ? 1 : 0);
|
|
138
|
+
} else if (typeof data === "object") {
|
|
139
|
+
for (const value of Object.values(data)) {
|
|
140
|
+
serializeOperationData(serializer, value);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function serializeSignedTransaction(tx) {
|
|
145
|
+
const serializer = new TransactionSerializer();
|
|
146
|
+
const txBytes = serializeTransaction(tx);
|
|
147
|
+
serializer.writeBytes(txBytes);
|
|
148
|
+
if (tx.signatures) {
|
|
149
|
+
serializer.writeArray(tx.signatures, (sig) => {
|
|
150
|
+
serializer.writeBytes(sig);
|
|
151
|
+
});
|
|
152
|
+
} else {
|
|
153
|
+
serializer.writeVarint32(0);
|
|
154
|
+
}
|
|
155
|
+
return serializer.toBuffer();
|
|
156
|
+
}
|
|
157
|
+
export {
|
|
158
|
+
TransactionSerializer,
|
|
159
|
+
serializeSignedTransaction,
|
|
160
|
+
serializeTransaction
|
|
161
|
+
};
|
|
162
|
+
//# sourceMappingURL=serializer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serializer.js","sources":["../../../src/auth/serializer.ts"],"sourcesContent":["/**\n * Transaction serialization for Zattera blockchain\n */\n\nimport type { Transaction, Operation } from '../types/index.js';\n\n/**\n * Simple binary serializer for transactions\n */\nexport class TransactionSerializer {\n private buffer: number[] = [];\n\n /**\n * Write a uint8 (1 byte)\n */\n writeUInt8(value: number): void {\n this.buffer.push(value & 0xff);\n }\n\n /**\n * Write a uint16 (2 bytes, little-endian)\n */\n writeUInt16(value: number): void {\n this.buffer.push(value & 0xff);\n this.buffer.push((value >> 8) & 0xff);\n }\n\n /**\n * Write a uint32 (4 bytes, little-endian)\n */\n writeUInt32(value: number): void {\n this.buffer.push(value & 0xff);\n this.buffer.push((value >> 8) & 0xff);\n this.buffer.push((value >> 16) & 0xff);\n this.buffer.push((value >> 24) & 0xff);\n }\n\n /**\n * Write a uint64 (8 bytes, little-endian)\n */\n writeUInt64(value: number | bigint): void {\n const bigValue = typeof value === 'number' ? BigInt(value) : value;\n for (let i = 0; i < 8; i++) {\n this.buffer.push(Number((bigValue >> BigInt(i * 8)) & BigInt(0xff)));\n }\n }\n\n /**\n * Write variable-length integer\n */\n writeVarint32(value: number): void {\n while (value >= 0x80) {\n this.buffer.push((value & 0x7f) | 0x80);\n value >>= 7;\n }\n this.buffer.push(value & 0x7f);\n }\n\n /**\n * Write a string\n */\n writeString(value: string): void {\n const bytes = new TextEncoder().encode(value);\n this.writeVarint32(bytes.length);\n for (const byte of bytes) {\n this.buffer.push(byte);\n }\n }\n\n /**\n * Write bytes\n */\n writeBytes(bytes: Uint8Array): void {\n for (const byte of bytes) {\n this.buffer.push(byte);\n }\n }\n\n /**\n * Write array with length prefix\n */\n writeArray<T>(arr: T[], writeItem: (item: T) => void): void {\n this.writeVarint32(arr.length);\n for (const item of arr) {\n writeItem(item);\n }\n }\n\n /**\n * Get the serialized buffer\n */\n toBuffer(): Uint8Array {\n return new Uint8Array(this.buffer);\n }\n}\n\n/**\n * Serialize a transaction (without signatures)\n */\nexport function serializeTransaction(tx: Transaction): Uint8Array {\n const serializer = new TransactionSerializer();\n\n // ref_block_num (uint16)\n serializer.writeUInt16(tx.ref_block_num);\n\n // ref_block_prefix (uint32)\n serializer.writeUInt32(tx.ref_block_prefix);\n\n // expiration (uint32 - seconds since epoch)\n const expirationDate = new Date(tx.expiration);\n const expirationSeconds = Math.floor(expirationDate.getTime() / 1000);\n serializer.writeUInt32(expirationSeconds);\n\n // operations array\n serializer.writeArray(tx.operations, (op: Operation) => {\n serializeOperation(serializer, op);\n });\n\n // extensions array (usually empty)\n serializer.writeArray(tx.extensions, (ext: unknown) => {\n // For now, we'll serialize extensions as opaque data\n // In practice, this is usually an empty array\n if (typeof ext === 'object' && ext !== null) {\n serializer.writeString(JSON.stringify(ext));\n }\n });\n\n return serializer.toBuffer();\n}\n\n/**\n * Serialize an operation\n * Operations are in format: [operation_type_id, operation_data]\n */\nfunction serializeOperation(serializer: TransactionSerializer, operation: Operation): void {\n if (!Array.isArray(operation) || operation.length !== 2) {\n throw new Error('Invalid operation format');\n }\n\n const [opType, opData] = operation;\n\n // Write operation type (assuming it's a string or number)\n if (typeof opType === 'number') {\n serializer.writeVarint32(opType);\n } else if (typeof opType === 'string') {\n // Map operation names to IDs (this would need to be complete)\n const opId = getOperationId(opType);\n serializer.writeVarint32(opId);\n }\n\n // Serialize operation data\n // This is a simplified version - full implementation would need\n // specific serialization logic for each operation type\n serializeOperationData(serializer, opData);\n}\n\n/**\n * Get operation ID from operation name\n * This is a simplified mapping - would need to be complete\n */\nfunction getOperationId(opName: string): number {\n const operationIds: Record<string, number> = {\n vote: 0,\n comment: 1,\n transfer: 2,\n transfer_to_vesting: 3,\n withdraw_vesting: 4,\n limit_order_create: 5,\n limit_order_cancel: 6,\n feed_publish: 7,\n convert: 8,\n account_create: 9,\n account_update: 10,\n witness_update: 11,\n account_witness_vote: 12,\n account_witness_proxy: 13,\n // ... more operations\n };\n\n return operationIds[opName] ?? -1;\n}\n\n/**\n * Serialize operation data\n * This is a simplified version that handles basic types\n */\nfunction serializeOperationData(serializer: TransactionSerializer, data: unknown): void {\n if (data === null || data === undefined) {\n return;\n }\n\n if (typeof data === 'string') {\n serializer.writeString(data);\n } else if (typeof data === 'number') {\n serializer.writeUInt32(data);\n } else if (typeof data === 'boolean') {\n serializer.writeUInt8(data ? 1 : 0);\n } else if (typeof data === 'object') {\n // For objects, serialize each field\n // This would need proper field ordering based on operation type\n for (const value of Object.values(data)) {\n serializeOperationData(serializer, value);\n }\n }\n}\n\n/**\n * Serialize a signed transaction (with signatures)\n */\nexport function serializeSignedTransaction(tx: Transaction & { signatures?: Uint8Array[] }): Uint8Array {\n const serializer = new TransactionSerializer();\n\n // Serialize the transaction part\n const txBytes = serializeTransaction(tx);\n serializer.writeBytes(txBytes);\n\n // Serialize signatures\n if (tx.signatures) {\n serializer.writeArray(tx.signatures, (sig: Uint8Array) => {\n serializer.writeBytes(sig);\n });\n } else {\n serializer.writeVarint32(0); // Empty signatures array\n }\n\n return serializer.toBuffer();\n}\n"],"names":[],"mappings":"AASO,MAAM,sBAAsB;AAAA,EACzB,SAAmB,CAAA;AAAA;AAAA;AAAA;AAAA,EAK3B,WAAW,OAAqB;AAC9B,SAAK,OAAO,KAAK,QAAQ,GAAI;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,OAAqB;AAC/B,SAAK,OAAO,KAAK,QAAQ,GAAI;AAC7B,SAAK,OAAO,KAAM,SAAS,IAAK,GAAI;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,OAAqB;AAC/B,SAAK,OAAO,KAAK,QAAQ,GAAI;AAC7B,SAAK,OAAO,KAAM,SAAS,IAAK,GAAI;AACpC,SAAK,OAAO,KAAM,SAAS,KAAM,GAAI;AACrC,SAAK,OAAO,KAAM,SAAS,KAAM,GAAI;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,OAA8B;AACxC,UAAM,WAAW,OAAO,UAAU,WAAW,OAAO,KAAK,IAAI;AAC7D,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,WAAK,OAAO,KAAK,OAAQ,YAAY,OAAO,IAAI,CAAC,IAAK,OAAO,GAAI,CAAC,CAAC;AAAA,IACrE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,OAAqB;AACjC,WAAO,SAAS,KAAM;AACpB,WAAK,OAAO,KAAM,QAAQ,MAAQ,GAAI;AACtC,gBAAU;AAAA,IACZ;AACA,SAAK,OAAO,KAAK,QAAQ,GAAI;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,OAAqB;AAC/B,UAAM,QAAQ,IAAI,cAAc,OAAO,KAAK;AAC5C,SAAK,cAAc,MAAM,MAAM;AAC/B,eAAW,QAAQ,OAAO;AACxB,WAAK,OAAO,KAAK,IAAI;AAAA,IACvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,OAAyB;AAClC,eAAW,QAAQ,OAAO;AACxB,WAAK,OAAO,KAAK,IAAI;AAAA,IACvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,WAAc,KAAU,WAAoC;AAC1D,SAAK,cAAc,IAAI,MAAM;AAC7B,eAAW,QAAQ,KAAK;AACtB,gBAAU,IAAI;AAAA,IAChB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,WAAuB;AACrB,WAAO,IAAI,WAAW,KAAK,MAAM;AAAA,EACnC;AACF;AAKO,SAAS,qBAAqB,IAA6B;AAChE,QAAM,aAAa,IAAI,sBAAA;AAGvB,aAAW,YAAY,GAAG,aAAa;AAGvC,aAAW,YAAY,GAAG,gBAAgB;AAG1C,QAAM,iBAAiB,IAAI,KAAK,GAAG,UAAU;AAC7C,QAAM,oBAAoB,KAAK,MAAM,eAAe,QAAA,IAAY,GAAI;AACpE,aAAW,YAAY,iBAAiB;AAGxC,aAAW,WAAW,GAAG,YAAY,CAAC,OAAkB;AACtD,uBAAmB,YAAY,EAAE;AAAA,EACnC,CAAC;AAGD,aAAW,WAAW,GAAG,YAAY,CAAC,QAAiB;AAGrD,QAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAC3C,iBAAW,YAAY,KAAK,UAAU,GAAG,CAAC;AAAA,IAC5C;AAAA,EACF,CAAC;AAED,SAAO,WAAW,SAAA;AACpB;AAMA,SAAS,mBAAmB,YAAmC,WAA4B;AACzF,MAAI,CAAC,MAAM,QAAQ,SAAS,KAAK,UAAU,WAAW,GAAG;AACvD,UAAM,IAAI,MAAM,0BAA0B;AAAA,EAC5C;AAEA,QAAM,CAAC,QAAQ,MAAM,IAAI;AAGzB,MAAI,OAAO,WAAW,UAAU;AAC9B,eAAW,cAAc,MAAM;AAAA,EACjC,WAAW,OAAO,WAAW,UAAU;AAErC,UAAM,OAAO,eAAe,MAAM;AAClC,eAAW,cAAc,IAAI;AAAA,EAC/B;AAKA,yBAAuB,YAAY,MAAM;AAC3C;AAMA,SAAS,eAAe,QAAwB;AAC9C,QAAM,eAAuC;AAAA,IAC3C,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA,IACV,qBAAqB;AAAA,IACrB,kBAAkB;AAAA,IAClB,oBAAoB;AAAA,IACpB,oBAAoB;AAAA,IACpB,cAAc;AAAA,IACd,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,sBAAsB;AAAA,IACtB,uBAAuB;AAAA;AAAA,EAAA;AAIzB,SAAO,aAAa,MAAM,KAAK;AACjC;AAMA,SAAS,uBAAuB,YAAmC,MAAqB;AACtF,MAAI,SAAS,QAAQ,SAAS,QAAW;AACvC;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,UAAU;AAC5B,eAAW,YAAY,IAAI;AAAA,EAC7B,WAAW,OAAO,SAAS,UAAU;AACnC,eAAW,YAAY,IAAI;AAAA,EAC7B,WAAW,OAAO,SAAS,WAAW;AACpC,eAAW,WAAW,OAAO,IAAI,CAAC;AAAA,EACpC,WAAW,OAAO,SAAS,UAAU;AAGnC,eAAW,SAAS,OAAO,OAAO,IAAI,GAAG;AACvC,6BAAuB,YAAY,KAAK;AAAA,IAC1C;AAAA,EACF;AACF;AAKO,SAAS,2BAA2B,IAA6D;AACtG,QAAM,aAAa,IAAI,sBAAA;AAGvB,QAAM,UAAU,qBAAqB,EAAE;AACvC,aAAW,WAAW,OAAO;AAG7B,MAAI,GAAG,YAAY;AACjB,eAAW,WAAW,GAAG,YAAY,CAAC,QAAoB;AACxD,iBAAW,WAAW,GAAG;AAAA,IAC3B,CAAC;AAAA,EACH,OAAO;AACL,eAAW,cAAc,CAAC;AAAA,EAC5B;AAEA,SAAO,WAAW,SAAA;AACpB;"}
|