1 | import { common, createSerializeWire, crypto, InvalidFormatError, IOHelper, } from '@neo-one/client-common-esnext-esm';
|
2 | import { BinaryReader, Block, ConsensusPayload, deserializeTransactionWire, } from '@neo-one/node-core-esnext-esm';
|
3 | import { makeErrorWithCode, utils } from '@neo-one/utils-esnext-esm';
|
4 | import { Transform } from 'stream';
|
5 | import { assertCommand, Command } from './Command';
|
6 | import { AddrPayload, FilterAddPayload, FilterLoadPayload, GetBlocksPayload, HeadersPayload, InvPayload, MerkleBlockPayload, VersionPayload, } from './payload';
|
7 | export const COMMAND_LENGTH = 12;
|
8 | export const PAYLOAD_MAX_SIZE = 0x02000000;
|
9 | const calculateChecksum = (buffer) => common.toUInt32LE(crypto.hash256(buffer));
|
10 | const deserializeMessageHeader = ({ context, reader, }) => {
|
11 | if (reader.readUInt32LE() !== context.messageMagic) {
|
12 | throw new InvalidFormatError();
|
13 | }
|
14 | const command = assertCommand(reader.readFixedString(COMMAND_LENGTH));
|
15 | const length = reader.readUInt32LE();
|
16 | if (length > PAYLOAD_MAX_SIZE) {
|
17 | throw new InvalidFormatError();
|
18 | }
|
19 | const checksum = reader.readUInt32LE();
|
20 | return { command, length, checksum };
|
21 | };
|
22 | export class Message {
|
23 | constructor({ magic, value }) {
|
24 | this.serializeWire = createSerializeWire(this.serializeWireBase.bind(this));
|
25 | this.magic = magic;
|
26 | this.value = value;
|
27 | }
|
28 | static deserializeWireBase(options) {
|
29 | const { reader, context } = options;
|
30 | const { command, length, checksum } = deserializeMessageHeader(options);
|
31 | const payloadBuffer = reader.readBytes(length);
|
32 | if (calculateChecksum(payloadBuffer) !== checksum) {
|
33 | throw new InvalidFormatError();
|
34 | }
|
35 | const payloadOptions = {
|
36 | context: options.context,
|
37 | buffer: payloadBuffer,
|
38 | };
|
39 | let value;
|
40 | switch (command) {
|
41 | case Command.addr:
|
42 | value = {
|
43 | command: Command.addr,
|
44 | payload: AddrPayload.deserializeWire(payloadOptions),
|
45 | };
|
46 | break;
|
47 | case Command.block:
|
48 | value = {
|
49 | command: Command.block,
|
50 | payload: Block.deserializeWire(payloadOptions),
|
51 | };
|
52 | break;
|
53 | case Command.consensus:
|
54 | value = {
|
55 | command: Command.consensus,
|
56 | payload: ConsensusPayload.deserializeWire(payloadOptions),
|
57 | };
|
58 | break;
|
59 | case Command.filteradd:
|
60 | value = {
|
61 | command: Command.filteradd,
|
62 | payload: FilterAddPayload.deserializeWire(payloadOptions),
|
63 | };
|
64 | break;
|
65 | case Command.filterclear:
|
66 | value = { command: Command.filterclear };
|
67 | break;
|
68 | case Command.filterload:
|
69 | value = {
|
70 | command: Command.filterload,
|
71 | payload: FilterLoadPayload.deserializeWire(payloadOptions),
|
72 | };
|
73 | break;
|
74 | case Command.getaddr:
|
75 | value = { command: Command.getaddr };
|
76 | break;
|
77 | case Command.getblocks:
|
78 | value = {
|
79 | command: Command.getblocks,
|
80 | payload: GetBlocksPayload.deserializeWire(payloadOptions),
|
81 | };
|
82 | break;
|
83 | case Command.getdata:
|
84 | value = {
|
85 | command: Command.getdata,
|
86 | payload: InvPayload.deserializeWire(payloadOptions),
|
87 | };
|
88 | break;
|
89 | case Command.getheaders:
|
90 | value = {
|
91 | command: Command.getheaders,
|
92 | payload: GetBlocksPayload.deserializeWire(payloadOptions),
|
93 | };
|
94 | break;
|
95 | case Command.headers:
|
96 | value = {
|
97 | command: Command.headers,
|
98 | payload: HeadersPayload.deserializeWire(payloadOptions),
|
99 | };
|
100 | break;
|
101 | case Command.inv:
|
102 | value = {
|
103 | command: Command.inv,
|
104 | payload: InvPayload.deserializeWire(payloadOptions),
|
105 | };
|
106 | break;
|
107 | case Command.mempool:
|
108 | value = { command: Command.mempool };
|
109 | break;
|
110 | case Command.tx:
|
111 | value = {
|
112 | command: Command.tx,
|
113 | payload: deserializeTransactionWire(payloadOptions),
|
114 | };
|
115 | break;
|
116 | case Command.verack:
|
117 | value = { command: Command.verack };
|
118 | break;
|
119 | case Command.version:
|
120 | value = {
|
121 | command: Command.version,
|
122 | payload: VersionPayload.deserializeWire(payloadOptions),
|
123 | };
|
124 | break;
|
125 | case Command.alert:
|
126 | value = { command: Command.alert };
|
127 | break;
|
128 | case Command.merkleblock:
|
129 | value = {
|
130 | command: Command.merkleblock,
|
131 | payload: MerkleBlockPayload.deserializeWire(payloadOptions),
|
132 | };
|
133 | break;
|
134 | case Command.notfound:
|
135 | value = { command: Command.notfound };
|
136 | break;
|
137 | case Command.ping:
|
138 | value = { command: Command.ping };
|
139 | break;
|
140 | case Command.pong:
|
141 | value = { command: Command.pong };
|
142 | break;
|
143 | case Command.reject:
|
144 | value = { command: Command.reject };
|
145 | break;
|
146 | default:
|
147 | utils.assertNever(command);
|
148 | throw new InvalidFormatError();
|
149 | }
|
150 | return new this({ magic: context.messageMagic, value });
|
151 | }
|
152 | static deserializeWire(options) {
|
153 | return this.deserializeWireBase({
|
154 | context: options.context,
|
155 | reader: new BinaryReader(options.buffer),
|
156 | });
|
157 | }
|
158 | serializeWireBase(writer) {
|
159 | const { value } = this;
|
160 | writer.writeUInt32LE(this.magic);
|
161 | writer.writeFixedString(value.command, COMMAND_LENGTH);
|
162 | let payload = Buffer.alloc(0);
|
163 | switch (value.command) {
|
164 | case Command.addr:
|
165 | payload = value.payload.serializeWire();
|
166 | break;
|
167 | case Command.block:
|
168 | payload = value.payload.serializeWire();
|
169 | break;
|
170 | case Command.consensus:
|
171 | payload = value.payload.serializeWire();
|
172 | break;
|
173 | case Command.filteradd:
|
174 | payload = value.payload.serializeWire();
|
175 | break;
|
176 | case Command.filterclear:
|
177 | break;
|
178 | case Command.filterload:
|
179 | payload = value.payload.serializeWire();
|
180 | break;
|
181 | case Command.getaddr:
|
182 | break;
|
183 | case Command.getblocks:
|
184 | payload = value.payload.serializeWire();
|
185 | break;
|
186 | case Command.getdata:
|
187 | payload = value.payload.serializeWire();
|
188 | break;
|
189 | case Command.getheaders:
|
190 | payload = value.payload.serializeWire();
|
191 | break;
|
192 | case Command.headers:
|
193 | payload = value.payload.serializeWire();
|
194 | break;
|
195 | case Command.inv:
|
196 | payload = value.payload.serializeWire();
|
197 | break;
|
198 | case Command.mempool:
|
199 | break;
|
200 | case Command.tx:
|
201 | payload = value.payload.serializeWire();
|
202 | break;
|
203 | case Command.verack:
|
204 | break;
|
205 | case Command.version:
|
206 | payload = value.payload.serializeWire();
|
207 | break;
|
208 | case Command.alert:
|
209 | break;
|
210 | case Command.merkleblock:
|
211 | payload = value.payload.serializeWire();
|
212 | break;
|
213 | case Command.notfound:
|
214 | break;
|
215 | case Command.ping:
|
216 | break;
|
217 | case Command.pong:
|
218 | break;
|
219 | case Command.reject:
|
220 | break;
|
221 | default:
|
222 | utils.assertNever(value);
|
223 | throw new InvalidFormatError();
|
224 | }
|
225 | writer.writeUInt32LE(payload.length);
|
226 | writer.writeUInt32LE(calculateChecksum(payload));
|
227 | writer.writeBytes(payload);
|
228 | }
|
229 | }
|
230 | export const InvalidMessageTransformEncodingError = makeErrorWithCode('INVALID_MESSAGE_TRANSFORM_ENCODING', (message) => message);
|
231 | const SIZE_OF_MESSAGE_HEADER = IOHelper.sizeOfUInt32LE +
|
232 | IOHelper.sizeOfFixedString(COMMAND_LENGTH) +
|
233 | IOHelper.sizeOfUInt32LE +
|
234 | IOHelper.sizeOfUInt32LE;
|
235 | export class MessageTransform extends Transform {
|
236 | constructor(context) {
|
237 | super({ readableObjectMode: true });
|
238 | this.context = context;
|
239 | this.mutableBuffer = Buffer.from([]);
|
240 | }
|
241 | _transform(chunk, encoding, callback) {
|
242 | if (typeof chunk === 'string') {
|
243 | throw new InvalidMessageTransformEncodingError(`Invalid Message Transform Chunk Type. Expected chunk type to be 'string', found: ${typeof chunk}`);
|
244 | }
|
245 | if (encoding !== 'buffer') {
|
246 | throw new InvalidMessageTransformEncodingError(`Invalid Message Transform Encoding. Expected: 'buffer', found: ${encoding}`);
|
247 | }
|
248 | this.mutableBuffer = Buffer.concat([this.mutableBuffer, chunk]);
|
249 | try {
|
250 | const { remainingBuffer, mutableMessages } = this.processBuffer(new BinaryReader(this.mutableBuffer));
|
251 | this.mutableBuffer = remainingBuffer;
|
252 | mutableMessages.forEach((message) => this.push(message));
|
253 | callback(undefined);
|
254 | }
|
255 | catch (error) {
|
256 | callback(error);
|
257 | }
|
258 | }
|
259 | processBuffer(reader) {
|
260 | if (reader.remaining < SIZE_OF_MESSAGE_HEADER) {
|
261 | return { remainingBuffer: reader.remainingBuffer, mutableMessages: [] };
|
262 | }
|
263 | const { length } = deserializeMessageHeader({
|
264 | context: this.context,
|
265 | reader: reader.clone(),
|
266 | });
|
267 | if (reader.remaining < SIZE_OF_MESSAGE_HEADER + length) {
|
268 | return { remainingBuffer: reader.remainingBuffer, mutableMessages: [] };
|
269 | }
|
270 | const message = Message.deserializeWireBase({
|
271 | context: this.context,
|
272 | reader,
|
273 | });
|
274 | const { remainingBuffer, mutableMessages } = this.processBuffer(reader);
|
275 | mutableMessages.push(message);
|
276 | return { remainingBuffer, mutableMessages };
|
277 | }
|
278 | }
|
279 |
|
280 | //# sourceMappingURL=data:application/json;charset=utf8;base64,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LENBQUM7U0FDekU7UUFFRCxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsd0JBQXdCLENBQUM7WUFDMUMsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO1lBQ3JCLE1BQU0sRUFBRSxNQUFNLENBQUMsS0FBSyxFQUFFO1NBQ3ZCLENBQUMsQ0FBQztRQUVILElBQUksTUFBTSxDQUFDLFNBQVMsR0FBRyxzQkFBc0IsR0FBRyxNQUFNLEVBQUU7WUFDdEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLENBQUMsZUFBZSxFQUFFLGVBQWUsRUFBRSxFQUFFLEVBQUUsQ0FBQztTQUN6RTtRQUVELE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQztZQUMxQyxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87WUFDckIsTUFBTTtTQUNQLENBQUMsQ0FBQztRQUVILE1BQU0sRUFBRSxlQUFlLEVBQUUsZUFBZSxFQUFFLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN4RSxlQUFlLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRTlCLE9BQU8sRUFBRSxlQUFlLEVBQUUsZUFBZSxFQUFFLENBQUM7SUFDOUMsQ0FBQztDQUNGIiwiZmlsZSI6Im5lby1vbmUtbm9kZS1wcm90b2NvbC9zcmMvTWVzc2FnZS5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEJpbmFyeVdyaXRlcixcbiAgY29tbW9uLFxuICBjcmVhdGVTZXJpYWxpemVXaXJlLFxuICBjcnlwdG8sXG4gIEludmFsaWRGb3JtYXRFcnJvcixcbiAgSU9IZWxwZXIsXG4gIFNlcmlhbGl6YWJsZVdpcmUsXG4gIFNlcmlhbGl6ZVdpcmUsXG59IGZyb20gJ0BuZW8tb25lL2NsaWVudC1jb21tb24tZXNuZXh0LWVzbSc7XG5pbXBvcnQge1xuICBCaW5hcnlSZWFkZXIsXG4gIEJsb2NrLFxuICBDb25zZW5zdXNQYXlsb2FkLFxuICBkZXNlcmlhbGl6ZVRyYW5zYWN0aW9uV2lyZSxcbiAgRGVzZXJpYWxpemVXaXJlQmFzZU9wdGlvbnMsXG4gIERlc2VyaWFsaXplV2lyZUNvbnRleHQsXG4gIERlc2VyaWFsaXplV2lyZU9wdGlvbnMsXG4gIFRyYW5zYWN0aW9uLFxufSBmcm9tICdAbmVvLW9uZS9ub2RlLWNvcmUtZXNuZXh0LWVzbSc7XG5pbXBvcnQgeyBtYWtlRXJyb3JXaXRoQ29kZSwgdXRpbHMgfSBmcm9tICdAbmVvLW9uZS91dGlscy1lc25leHQtZXNtJztcbmltcG9ydCB7IFRyYW5zZm9ybSB9IGZyb20gJ3N0cmVhbSc7XG5pbXBvcnQgeyBhc3NlcnRDb21tYW5kLCBDb21tYW5kIH0gZnJvbSAnLi9Db21tYW5kJztcbmltcG9ydCB7XG4gIEFkZHJQYXlsb2FkLFxuICBGaWx0ZXJBZGRQYXlsb2FkLFxuICBGaWx0ZXJMb2FkUGF5bG9hZCxcbiAgR2V0QmxvY2tzUGF5bG9hZCxcbiAgSGVhZGVyc1BheWxvYWQsXG4gIEludlBheWxvYWQsXG4gIE1lcmtsZUJsb2NrUGF5bG9hZCxcbiAgVmVyc2lvblBheWxvYWQsXG59IGZyb20gJy4vcGF5bG9hZCc7XG5leHBvcnQgdHlwZSBNZXNzYWdlVmFsdWUgPVxuICB8IHsgcmVhZG9ubHkgY29tbWFuZDogQ29tbWFuZC5hZGRyOyByZWFkb25seSBwYXlsb2FkOiBBZGRyUGF5bG9hZCB9XG4gIHwgeyByZWFkb25seSBjb21tYW5kOiBDb21tYW5kLmJsb2NrOyByZWFkb25seSBwYXlsb2FkOiBCbG9jayB9XG4gIHwgeyByZWFkb25seSBjb21tYW5kOiBDb21tYW5kLmNvbnNlbnN1czsgcmVhZG9ubHkgcGF5bG9hZDogQ29uc2Vuc3VzUGF5bG9hZCB9XG4gIHwgeyByZWFkb25seSBjb21tYW5kOiBDb21tYW5kLmZpbHRlcmFkZDsgcmVhZG9ubHkgcGF5bG9hZDogRmlsdGVyQWRkUGF5bG9hZCB9XG4gIHwgeyByZWFkb25seSBjb21tYW5kOiBDb21tYW5kLmZpbHRlcmNsZWFyIH1cbiAgfCB7IHJlYWRvbmx5IGNvbW1hbmQ6IENvbW1hbmQuZmlsdGVybG9hZDsgcmVhZG9ubHkgcGF5bG9hZDogRmlsdGVyTG9hZFBheWxvYWQgfVxuICB8IHsgcmVhZG9ubHkgY29tbWFuZDogQ29tbWFuZC5nZXRhZGRyIH1cbiAgfCB7IHJlYWRvbmx5IGNvbW1hbmQ6IENvbW1hbmQuZ2V0YmxvY2tzOyByZWFkb25seSBwYXlsb2FkOiBHZXRCbG9ja3NQYXlsb2FkIH1cbiAgfCB7IHJlYWRvbmx5IGNvbW1hbmQ6IENvbW1hbmQuZ2V0ZGF0YTsgcmVhZG9ubHkgcGF5bG9hZDogSW52UGF5bG9hZCB9XG4gIHwgeyByZWFkb25seSBjb21tYW5kOiBDb21tYW5kLmdldGhlYWRlcnM7IHJlYWRvbmx5IHBheWxvYWQ6IEdldEJsb2Nrc1BheWxvYWQgfVxuICB8IHsgcmVhZG9ubHkgY29tbWFuZDogQ29tbWFuZC5oZWFkZXJzOyByZWFkb25seSBwYXlsb2FkOiBIZWFkZXJzUGF5bG9hZCB9XG4gIHwgeyByZWFkb25seSBjb21tYW5kOiBDb21tYW5kLmludjsgcmVhZG9ubHkgcGF5bG9hZDogSW52UGF5bG9hZCB9XG4gIHwgeyByZWFkb25seSBjb21tYW5kOiBDb21tYW5kLm1lbXBvb2wgfVxuICB8IHsgcmVhZG9ubHkgY29tbWFuZDogQ29tbWFuZC50eDsgcmVhZG9ubHkgcGF5bG9hZDogVHJhbnNhY3Rpb24gfVxuICB8IHsgcmVhZG9ubHkgY29tbWFuZDogQ29tbWFuZC52ZXJhY2sgfVxuICB8IHsgcmVhZG9ubHkgY29tbWFuZDogQ29tbWFuZC52ZXJzaW9uOyByZWFkb25seSBwYXlsb2FkOiBWZXJzaW9uUGF5bG9hZCB9XG4gIHwgeyByZWFkb25seSBjb21tYW5kOiBDb21tYW5kLmFsZXJ0IH1cbiAgfCB7IHJlYWRvbmx5IGNvbW1hbmQ6IENvbW1hbmQubWVya2xlYmxvY2s7IHJlYWRvbmx5IHBheWxvYWQ6IE1lcmtsZUJsb2NrUGF5bG9hZCB9XG4gIHwgeyByZWFkb25seSBjb21tYW5kOiBDb21tYW5kLm5vdGZvdW5kIH1cbiAgfCB7IHJlYWRvbmx5IGNvbW1hbmQ6IENvbW1hbmQucGluZyB9XG4gIHwgeyByZWFkb25seSBjb21tYW5kOiBDb21tYW5kLnBvbmcgfVxuICB8IHsgcmVhZG9ubHkgY29tbWFuZDogQ29tbWFuZC5yZWplY3QgfTtcbmV4cG9ydCBpbnRlcmZhY2UgTWVzc2FnZUFkZCB7XG4gIHJlYWRvbmx5IG1hZ2ljOiBudW1iZXI7XG4gIHJlYWRvbmx5IHZhbHVlOiBNZXNzYWdlVmFsdWU7XG59XG5cbmV4cG9ydCBjb25zdCBDT01NQU5EX0xFTkdUSCA9IDEyO1xuZXhwb3J0IGNvbnN0IFBBWUxPQURfTUFYX1NJWkUgPSAweDAyMDAwMDAwO1xuXG5jb25zdCBjYWxjdWxhdGVDaGVja3N1bSA9IChidWZmZXI6IEJ1ZmZlcikgPT4gY29tbW9uLnRvVUludDMyTEUoY3J5cHRvLmhhc2gyNTYoYnVmZmVyKSk7XG5cbmNvbnN0IGRlc2VyaWFsaXplTWVzc2FnZUhlYWRlciA9ICh7XG4gIGNvbnRleHQsXG4gIHJlYWRlcixcbn06IERlc2VyaWFsaXplV2lyZUJhc2VPcHRpb25zKToge1xuICByZWFkb25seSBjb21tYW5kOiBDb21tYW5kO1xuICByZWFkb25seSBsZW5ndGg6IG51bWJlcjtcbiAgcmVhZG9ubHkgY2hlY2tzdW06IG51bWJlcjtcbn0gPT4ge1xuICBpZiAocmVhZGVyLnJlYWRVSW50MzJMRSgpICE9PSBjb250ZXh0Lm1lc3NhZ2VNYWdpYykge1xuICAgIHRocm93IG5ldyBJbnZhbGlkRm9ybWF0RXJyb3IoKTtcbiAgfVxuICBjb25zdCBjb21tYW5kID0gYXNzZXJ0Q29tbWFuZChyZWFkZXIucmVhZEZpeGVkU3RyaW5nKENPTU1BTkRfTEVOR1RIKSk7XG4gIGNvbnN0IGxlbmd0aCA9IHJlYWRlci5yZWFkVUludDMyTEUoKTtcbiAgaWYgKGxlbmd0aCA+IFBBWUxPQURfTUFYX1NJWkUpIHtcbiAgICB0aHJvdyBuZXcgSW52YWxpZEZvcm1hdEVycm9yKCk7XG4gIH1cbiAgY29uc3QgY2hlY2tzdW0gPSByZWFkZXIucmVhZFVJbnQzMkxFKCk7XG5cbiAgcmV0dXJuIHsgY29tbWFuZCwgbGVuZ3RoLCBjaGVja3N1bSB9O1xufTtcblxuZXhwb3J0IGNsYXNzIE1lc3NhZ2UgaW1wbGVtZW50cyBTZXJpYWxpemFibGVXaXJlPE1lc3NhZ2U+IHtcbiAgcHVibGljIHN0YXRpYyBkZXNlcmlhbGl6ZVdpcmVCYXNlKG9wdGlvbnM6IERlc2VyaWFsaXplV2lyZUJhc2VPcHRpb25zKTogTWVzc2FnZSB7XG4gICAgY29uc3QgeyByZWFkZXIsIGNvbnRleHQgfSA9IG9wdGlvbnM7XG4gICAgY29uc3QgeyBjb21tYW5kLCBsZW5ndGgsIGNoZWNrc3VtIH0gPSBkZXNlcmlhbGl6ZU1lc3NhZ2VIZWFkZXIob3B0aW9ucyk7XG4gICAgY29uc3QgcGF5bG9hZEJ1ZmZlciA9IHJlYWRlci5yZWFkQnl0ZXMobGVuZ3RoKTtcbiAgICBpZiAoY2FsY3VsYXRlQ2hlY2tzdW0ocGF5bG9hZEJ1ZmZlcikgIT09IGNoZWNrc3VtKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEZvcm1hdEVycm9yKCk7XG4gICAgfVxuXG4gICAgY29uc3QgcGF5bG9hZE9wdGlvbnMgPSB7XG4gICAgICBjb250ZXh0OiBvcHRpb25zLmNvbnRleHQsXG4gICAgICBidWZmZXI6IHBheWxvYWRCdWZmZXIsXG4gICAgfTtcblxuICAgIGxldCB2YWx1ZTogTWVzc2FnZVZhbHVlO1xuICAgIHN3aXRjaCAoY29tbWFuZCkge1xuICAgICAgY2FzZSBDb21tYW5kLmFkZHI6XG4gICAgICAgIHZhbHVlID0ge1xuICAgICAgICAgIGNvbW1hbmQ6IENvbW1hbmQuYWRkcixcbiAgICAgICAgICBwYXlsb2FkOiBBZGRyUGF5bG9hZC5kZXNlcmlhbGl6ZVdpcmUocGF5bG9hZE9wdGlvbnMpLFxuICAgICAgICB9O1xuXG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBDb21tYW5kLmJsb2NrOlxuICAgICAgICB2YWx1ZSA9IHtcbiAgICAgICAgICBjb21tYW5kOiBDb21tYW5kLmJsb2NrLFxuICAgICAgICAgIHBheWxvYWQ6IEJsb2NrLmRlc2VyaWFsaXplV2lyZShwYXlsb2FkT3B0aW9ucyksXG4gICAgICAgIH07XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIENvbW1hbmQuY29uc2Vuc3VzOlxuICAgICAgICB2YWx1ZSA9IHtcbiAgICAgICAgICBjb21tYW5kOiBDb21tYW5kLmNvbnNlbnN1cyxcbiAgICAgICAgICBwYXlsb2FkOiBDb25zZW5zdXNQYXlsb2FkLmRlc2VyaWFsaXplV2lyZShwYXlsb2FkT3B0aW9ucyksXG4gICAgICAgIH07XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIENvbW1hbmQuZmlsdGVyYWRkOlxuICAgICAgICB2YWx1ZSA9IHtcbiAgICAgICAgICBjb21tYW5kOiBDb21tYW5kLmZpbHRlcmFkZCxcbiAgICAgICAgICBwYXlsb2FkOiBGaWx0ZXJBZGRQYXlsb2FkLmRlc2VyaWFsaXplV2lyZShwYXlsb2FkT3B0aW9ucyksXG4gICAgICAgIH07XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIENvbW1hbmQuZmlsdGVyY2xlYXI6XG4gICAgICAgIHZhbHVlID0geyBjb21tYW5kOiBDb21tYW5kLmZpbHRlcmNsZWFyIH07XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBDb21tYW5kLmZpbHRlcmxvYWQ6XG4gICAgICAgIHZhbHVlID0ge1xuICAgICAgICAgIGNvbW1hbmQ6IENvbW1hbmQuZmlsdGVybG9hZCxcbiAgICAgICAgICBwYXlsb2FkOiBGaWx0ZXJMb2FkUGF5bG9hZC5kZXNlcmlhbGl6ZVdpcmUocGF5bG9hZE9wdGlvbnMpLFxuICAgICAgICB9O1xuXG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBDb21tYW5kLmdldGFkZHI6XG4gICAgICAgIHZhbHVlID0geyBjb21tYW5kOiBDb21tYW5kLmdldGFkZHIgfTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIENvbW1hbmQuZ2V0YmxvY2tzOlxuICAgICAgICB2YWx1ZSA9IHtcbiAgICAgICAgICBjb21tYW5kOiBDb21tYW5kLmdldGJsb2NrcyxcbiAgICAgICAgICBwYXlsb2FkOiBHZXRCbG9ja3NQYXlsb2FkLmRlc2VyaWFsaXplV2lyZShwYXlsb2FkT3B0aW9ucyksXG4gICAgICAgIH07XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIENvbW1hbmQuZ2V0ZGF0YTpcbiAgICAgICAgdmFsdWUgPSB7XG4gICAgICAgICAgY29tbWFuZDogQ29tbWFuZC5nZXRkYXRhLFxuICAgICAgICAgIHBheWxvYWQ6IEludlBheWxvYWQuZGVzZXJpYWxpemVXaXJlKHBheWxvYWRPcHRpb25zKSxcbiAgICAgICAgfTtcblxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQ29tbWFuZC5nZXRoZWFkZXJzOlxuICAgICAgICB2YWx1ZSA9IHtcbiAgICAgICAgICBjb21tYW5kOiBDb21tYW5kLmdldGhlYWRlcnMsXG4gICAgICAgICAgcGF5bG9hZDogR2V0QmxvY2tzUGF5bG9hZC5kZXNlcmlhbGl6ZVdpcmUocGF5bG9hZE9wdGlvbnMpLFxuICAgICAgICB9O1xuXG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBDb21tYW5kLmhlYWRlcnM6XG4gICAgICAgIHZhbHVlID0ge1xuICAgICAgICAgIGNvbW1hbmQ6IENvbW1hbmQuaGVhZGVycyxcbiAgICAgICAgICBwYXlsb2FkOiBIZWFkZXJzUGF5bG9hZC5kZXNlcmlhbGl6ZVdpcmUocGF5bG9hZE9wdGlvbnMpLFxuICAgICAgICB9O1xuXG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBDb21tYW5kLmludjpcbiAgICAgICAgdmFsdWUgPSB7XG4gICAgICAgICAgY29tbWFuZDogQ29tbWFuZC5pbnYsXG4gICAgICAgICAgcGF5bG9hZDogSW52UGF5bG9hZC5kZXNlcmlhbGl6ZVdpcmUocGF5bG9hZE9wdGlvbnMpLFxuICAgICAgICB9O1xuXG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBDb21tYW5kLm1lbXBvb2w6XG4gICAgICAgIHZhbHVlID0geyBjb21tYW5kOiBDb21tYW5kLm1lbXBvb2wgfTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIENvbW1hbmQudHg6XG4gICAgICAgIHZhbHVlID0ge1xuICAgICAgICAgIGNvbW1hbmQ6IENvbW1hbmQudHgsXG4gICAgICAgICAgcGF5bG9hZDogZGVzZXJpYWxpemVUcmFuc2FjdGlvbldpcmUocGF5bG9hZE9wdGlvbnMpLFxuICAgICAgICB9O1xuXG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBDb21tYW5kLnZlcmFjazpcbiAgICAgICAgdmFsdWUgPSB7IGNvbW1hbmQ6IENvbW1hbmQudmVyYWNrIH07XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBDb21tYW5kLnZlcnNpb246XG4gICAgICAgIHZhbHVlID0ge1xuICAgICAgICAgIGNvbW1hbmQ6IENvbW1hbmQudmVyc2lvbixcbiAgICAgICAgICBwYXlsb2FkOiBWZXJzaW9uUGF5bG9hZC5kZXNlcmlhbGl6ZVdpcmUocGF5bG9hZE9wdGlvbnMpLFxuICAgICAgICB9O1xuXG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBDb21tYW5kLmFsZXJ0OlxuICAgICAgICB2YWx1ZSA9IHsgY29tbWFuZDogQ29tbWFuZC5hbGVydCB9O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQ29tbWFuZC5tZXJrbGVibG9jazpcbiAgICAgICAgdmFsdWUgPSB7XG4gICAgICAgICAgY29tbWFuZDogQ29tbWFuZC5tZXJrbGVibG9jayxcbiAgICAgICAgICBwYXlsb2FkOiBNZXJrbGVCbG9ja1BheWxvYWQuZGVzZXJpYWxpemVXaXJlKHBheWxvYWRPcHRpb25zKSxcbiAgICAgICAgfTtcblxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQ29tbWFuZC5ub3Rmb3VuZDpcbiAgICAgICAgdmFsdWUgPSB7IGNvbW1hbmQ6IENvbW1hbmQubm90Zm91bmQgfTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIENvbW1hbmQucGluZzpcbiAgICAgICAgdmFsdWUgPSB7IGNvbW1hbmQ6IENvbW1hbmQucGluZyB9O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQ29tbWFuZC5wb25nOlxuICAgICAgICB2YWx1ZSA9IHsgY29tbWFuZDogQ29tbWFuZC5wb25nIH07XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBDb21tYW5kLnJlamVjdDpcbiAgICAgICAgdmFsdWUgPSB7IGNvbW1hbmQ6IENvbW1hbmQucmVqZWN0IH07XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdXRpbHMuYXNzZXJ0TmV2ZXIoY29tbWFuZCk7XG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkRm9ybWF0RXJyb3IoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IHRoaXMoeyBtYWdpYzogY29udGV4dC5tZXNzYWdlTWFnaWMsIHZhbHVlIH0pO1xuICB9XG5cbiAgcHVibGljIHN0YXRpYyBkZXNlcmlhbGl6ZVdpcmUob3B0aW9uczogRGVzZXJpYWxpemVXaXJlT3B0aW9ucyk6IE1lc3NhZ2Uge1xuICAgIHJldHVybiB0aGlzLmRlc2VyaWFsaXplV2lyZUJhc2Uoe1xuICAgICAgY29udGV4dDogb3B0aW9ucy5jb250ZXh0LFxuICAgICAgcmVhZGVyOiBuZXcgQmluYXJ5UmVhZGVyKG9wdGlvbnMuYnVmZmVyKSxcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyByZWFkb25seSBtYWdpYzogbnVtYmVyO1xuICBwdWJsaWMgcmVhZG9ubHkgdmFsdWU6IE1lc3NhZ2VWYWx1ZTtcbiAgcHVibGljIHJlYWRvbmx5IHNlcmlhbGl6ZVdpcmU6IFNlcmlhbGl6ZVdpcmUgPSBjcmVhdGVTZXJpYWxpemVXaXJlKHRoaXMuc2VyaWFsaXplV2lyZUJhc2UuYmluZCh0aGlzKSk7XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKHsgbWFnaWMsIHZhbHVlIH06IE1lc3NhZ2VBZGQpIHtcbiAgICB0aGlzLm1hZ2ljID0gbWFnaWM7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICB9XG5cbiAgcHVibGljIHNlcmlhbGl6ZVdpcmVCYXNlKHdyaXRlcjogQmluYXJ5V3JpdGVyKTogdm9pZCB7XG4gICAgY29uc3QgeyB2YWx1ZSB9ID0gdGhpcztcblxuICAgIHdyaXRlci53cml0ZVVJbnQzMkxFKHRoaXMubWFnaWMpO1xuICAgIHdyaXRlci53cml0ZUZpeGVkU3RyaW5nKHZhbHVlLmNvbW1hbmQsIENPTU1BTkRfTEVOR1RIKTtcblxuICAgIGxldCBwYXlsb2FkID0gQnVmZmVyLmFsbG9jKDApO1xuICAgIHN3aXRjaCAodmFsdWUuY29tbWFuZCkge1xuICAgICAgY2FzZSBDb21tYW5kLmFkZHI6XG4gICAgICAgIHBheWxvYWQgPSB2YWx1ZS5wYXlsb2FkLnNlcmlhbGl6ZVdpcmUoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIENvbW1hbmQuYmxvY2s6XG4gICAgICAgIHBheWxvYWQgPSB2YWx1ZS5wYXlsb2FkLnNlcmlhbGl6ZVdpcmUoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIENvbW1hbmQuY29uc2Vuc3VzOlxuICAgICAgICBwYXlsb2FkID0gdmFsdWUucGF5bG9hZC5zZXJpYWxpemVXaXJlKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBDb21tYW5kLmZpbHRlcmFkZDpcbiAgICAgICAgcGF5bG9hZCA9IHZhbHVlLnBheWxvYWQuc2VyaWFsaXplV2lyZSgpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQ29tbWFuZC5maWx0ZXJjbGVhcjpcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIENvbW1hbmQuZmlsdGVybG9hZDpcbiAgICAgICAgcGF5bG9hZCA9IHZhbHVlLnBheWxvYWQuc2VyaWFsaXplV2lyZSgpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQ29tbWFuZC5nZXRhZGRyOlxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQ29tbWFuZC5nZXRibG9ja3M6XG4gICAgICAgIHBheWxvYWQgPSB2YWx1ZS5wYXlsb2FkLnNlcmlhbGl6ZVdpcmUoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIENvbW1hbmQuZ2V0ZGF0YTpcbiAgICAgICAgcGF5bG9hZCA9IHZhbHVlLnBheWxvYWQuc2VyaWFsaXplV2lyZSgpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQ29tbWFuZC5nZXRoZWFkZXJzOlxuICAgICAgICBwYXlsb2FkID0gdmFsdWUucGF5bG9hZC5zZXJpYWxpemVXaXJlKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBDb21tYW5kLmhlYWRlcnM6XG4gICAgICAgIHBheWxvYWQgPSB2YWx1ZS5wYXlsb2FkLnNlcmlhbGl6ZVdpcmUoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIENvbW1hbmQuaW52OlxuICAgICAgICBwYXlsb2FkID0gdmFsdWUucGF5bG9hZC5zZXJpYWxpemVXaXJlKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBDb21tYW5kLm1lbXBvb2w6XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBDb21tYW5kLnR4OlxuICAgICAgICBwYXlsb2FkID0gdmFsdWUucGF5bG9hZC5zZXJpYWxpemVXaXJlKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBDb21tYW5kLnZlcmFjazpcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIENvbW1hbmQudmVyc2lvbjpcbiAgICAgICAgcGF5bG9hZCA9IHZhbHVlLnBheWxvYWQuc2VyaWFsaXplV2lyZSgpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQ29tbWFuZC5hbGVydDpcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIENvbW1hbmQubWVya2xlYmxvY2s6XG4gICAgICAgIHBheWxvYWQgPSB2YWx1ZS5wYXlsb2FkLnNlcmlhbGl6ZVdpcmUoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIENvbW1hbmQubm90Zm91bmQ6XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBDb21tYW5kLnBpbmc6XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBDb21tYW5kLnBvbmc6XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBDb21tYW5kLnJlamVjdDpcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB1dGlscy5hc3NlcnROZXZlcih2YWx1ZSk7XG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkRm9ybWF0RXJyb3IoKTtcbiAgICB9XG5cbiAgICB3cml0ZXIud3JpdGVVSW50MzJMRShwYXlsb2FkLmxlbmd0aCk7XG4gICAgd3JpdGVyLndyaXRlVUludDMyTEUoY2FsY3VsYXRlQ2hlY2tzdW0ocGF5bG9hZCkpO1xuICAgIHdyaXRlci53cml0ZUJ5dGVzKHBheWxvYWQpO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBJbnZhbGlkTWVzc2FnZVRyYW5zZm9ybUVuY29kaW5nRXJyb3IgPSBtYWtlRXJyb3JXaXRoQ29kZShcbiAgJ0lOVkFMSURfTUVTU0FHRV9UUkFOU0ZPUk1fRU5DT0RJTkcnLFxuICAobWVzc2FnZTogc3RyaW5nKSA9PiBtZXNzYWdlLFxuKTtcblxuY29uc3QgU0laRV9PRl9NRVNTQUdFX0hFQURFUiA9XG4gIElPSGVscGVyLnNpemVPZlVJbnQzMkxFICtcbiAgSU9IZWxwZXIuc2l6ZU9mRml4ZWRTdHJpbmcoQ09NTUFORF9MRU5HVEgpICtcbiAgSU9IZWxwZXIuc2l6ZU9mVUludDMyTEUgK1xuICBJT0hlbHBlci5zaXplT2ZVSW50MzJMRTtcblxuZXhwb3J0IGNsYXNzIE1lc3NhZ2VUcmFuc2Zvcm0gZXh0ZW5kcyBUcmFuc2Zvcm0ge1xuICBwdWJsaWMgcmVhZG9ubHkgY29udGV4dDogRGVzZXJpYWxpemVXaXJlQ29udGV4dDtcbiAgcHVibGljIG11dGFibGVCdWZmZXI6IEJ1ZmZlcjtcblxuICBwdWJsaWMgY29uc3RydWN0b3IoY29udGV4dDogRGVzZXJpYWxpemVXaXJlQ29udGV4dCkge1xuICAgIHN1cGVyKHsgcmVhZGFibGVPYmplY3RNb2RlOiB0cnVlIH0pO1xuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gICAgdGhpcy5tdXRhYmxlQnVmZmVyID0gQnVmZmVyLmZyb20oW10pO1xuICB9XG5cbiAgcHVibGljIF90cmFuc2Zvcm0oXG4gICAgY2h1bms6IEJ1ZmZlciB8IHN0cmluZyxcbiAgICBlbmNvZGluZzogc3RyaW5nLFxuICAgIGNhbGxiYWNrOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkLCBkYXRhPzogQnVmZmVyIHwgc3RyaW5nKSA9PiB2b2lkLFxuICApOiB2b2lkIHtcbiAgICBpZiAodHlwZW9mIGNodW5rID09PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRNZXNzYWdlVHJhbnNmb3JtRW5jb2RpbmdFcnJvcihcbiAgICAgICAgYEludmFsaWQgTWVzc2FnZSBUcmFuc2Zvcm0gQ2h1bmsgVHlwZS4gRXhwZWN0ZWQgY2h1bmsgdHlwZSB0byBiZSAnc3RyaW5nJywgZm91bmQ6ICR7dHlwZW9mIGNodW5rfWAsXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoZW5jb2RpbmcgIT09ICdidWZmZXInKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZE1lc3NhZ2VUcmFuc2Zvcm1FbmNvZGluZ0Vycm9yKFxuICAgICAgICBgSW52YWxpZCBNZXNzYWdlIFRyYW5zZm9ybSBFbmNvZGluZy4gRXhwZWN0ZWQ6ICdidWZmZXInLCBmb3VuZDogJHtlbmNvZGluZ31gLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLm11dGFibGVCdWZmZXIgPSBCdWZmZXIuY29uY2F0KFt0aGlzLm11dGFibGVCdWZmZXIsIGNodW5rXSk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgcmVtYWluaW5nQnVmZmVyLCBtdXRhYmxlTWVzc2FnZXMgfSA9IHRoaXMucHJvY2Vzc0J1ZmZlcihuZXcgQmluYXJ5UmVhZGVyKHRoaXMubXV0YWJsZUJ1ZmZlcikpO1xuXG4gICAgICB0aGlzLm11dGFibGVCdWZmZXIgPSByZW1haW5pbmdCdWZmZXI7XG4gICAgICBtdXRhYmxlTWVzc2FnZXMuZm9yRWFjaCgobWVzc2FnZSkgPT4gdGhpcy5wdXNoKG1lc3NhZ2UpKTtcbiAgICAgIGNhbGxiYWNrKHVuZGVmaW5lZCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNhbGxiYWNrKGVycm9yKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHByb2Nlc3NCdWZmZXIoXG4gICAgcmVhZGVyOiBCaW5hcnlSZWFkZXIsXG4gICk6IHtcbiAgICByZWFkb25seSByZW1haW5pbmdCdWZmZXI6IEJ1ZmZlcjtcbiAgICByZWFkb25seSBtdXRhYmxlTWVzc2FnZXM6IE1lc3NhZ2VbXTtcbiAgfSB7XG4gICAgaWYgKHJlYWRlci5yZW1haW5pbmcgPCBTSVpFX09GX01FU1NBR0VfSEVBREVSKSB7XG4gICAgICByZXR1cm4geyByZW1haW5pbmdCdWZmZXI6IHJlYWRlci5yZW1haW5pbmdCdWZmZXIsIG11dGFibGVNZXNzYWdlczogW10gfTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGxlbmd0aCB9ID0gZGVzZXJpYWxpemVNZXNzYWdlSGVhZGVyKHtcbiAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgIHJlYWRlcjogcmVhZGVyLmNsb25lKCksXG4gICAgfSk7XG5cbiAgICBpZiAocmVhZGVyLnJlbWFpbmluZyA8IFNJWkVfT0ZfTUVTU0FHRV9IRUFERVIgKyBsZW5ndGgpIHtcbiAgICAgIHJldHVybiB7IHJlbWFpbmluZ0J1ZmZlcjogcmVhZGVyLnJlbWFpbmluZ0J1ZmZlciwgbXV0YWJsZU1lc3NhZ2VzOiBbXSB9O1xuICAgIH1cblxuICAgIGNvbnN0IG1lc3NhZ2UgPSBNZXNzYWdlLmRlc2VyaWFsaXplV2lyZUJhc2Uoe1xuICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgcmVhZGVyLFxuICAgIH0pO1xuXG4gICAgY29uc3QgeyByZW1haW5pbmdCdWZmZXIsIG11dGFibGVNZXNzYWdlcyB9ID0gdGhpcy5wcm9jZXNzQnVmZmVyKHJlYWRlcik7XG4gICAgbXV0YWJsZU1lc3NhZ2VzLnB1c2gobWVzc2FnZSk7XG5cbiAgICByZXR1cm4geyByZW1haW5pbmdCdWZmZXIsIG11dGFibGVNZXNzYWdlcyB9O1xuICB9XG59XG4iXX0=
|