quico 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/libs/utils.js ADDED
@@ -0,0 +1,404 @@
1
+
2
+ function writeVarInt(value) {
3
+ if (value < 0x40) {
4
+ // 1 byte, prefix 00
5
+ return new Uint8Array([value]); // אין צורך ב־& 0x3f
6
+ }
7
+
8
+ if (value < 0x4000) {
9
+ // 2 bytes, prefix 01
10
+ return new Uint8Array([
11
+ 0x40 | (value >> 8),
12
+ value & 0xff
13
+ ]);
14
+ }
15
+
16
+ if (value < 0x40000000) {
17
+ // 4 bytes, prefix 10
18
+ return new Uint8Array([
19
+ 0x80 | (value >> 24),
20
+ (value >> 16) & 0xff,
21
+ (value >> 8) & 0xff,
22
+ value & 0xff
23
+ ]);
24
+ }
25
+
26
+ if (value <= Number.MAX_SAFE_INTEGER) {
27
+ const hi = Math.floor(value / 2 ** 32);
28
+ const lo = value >>> 0;
29
+ return new Uint8Array([
30
+ 0xC0 | (hi >> 24),
31
+ (hi >> 16) & 0xff,
32
+ (hi >> 8) & 0xff,
33
+ hi & 0xff,
34
+ (lo >> 24) & 0xff,
35
+ (lo >> 16) & 0xff,
36
+ (lo >> 8) & 0xff,
37
+ lo & 0xff
38
+ ]);
39
+ }
40
+
41
+ throw new Error("Value too large for QUIC VarInt");
42
+ }
43
+
44
+
45
+ function writeVarInt2(value) {
46
+ if (value < 0x40) {
47
+ // 1 byte
48
+ return new Uint8Array([value & 0x3f]);
49
+ }
50
+
51
+ if (value < 0x4000) {
52
+ // 2 bytes
53
+ return new Uint8Array([
54
+ 0x40 | ((value >> 8) & 0x3f),
55
+ value & 0xff
56
+ ]);
57
+ }
58
+
59
+ if (value < 0x40000000) {
60
+ // 4 bytes
61
+ return new Uint8Array([
62
+ 0x80 | ((value >> 24) & 0x3f),
63
+ (value >> 16) & 0xff,
64
+ (value >> 8) & 0xff,
65
+ value & 0xff
66
+ ]);
67
+ }
68
+
69
+ if (value <= Number.MAX_SAFE_INTEGER) {
70
+ var hi = Math.floor(value / 2 ** 32);
71
+ var lo = value >>> 0;
72
+ return new Uint8Array([
73
+ 0xC0 | ((hi >> 24) & 0x3f),
74
+ (hi >> 16) & 0xff,
75
+ (hi >> 8) & 0xff,
76
+ hi & 0xff,
77
+ (lo >> 24) & 0xff,
78
+ (lo >> 16) & 0xff,
79
+ (lo >> 8) & 0xff,
80
+ lo & 0xff
81
+ ]);
82
+ }
83
+
84
+ throw new Error("Value too large for QUIC VarInt");
85
+ }
86
+
87
+
88
+
89
+ function readVarInt(array, offset) {
90
+ if (offset >= array.length) return null;
91
+
92
+ const first = array[offset];
93
+ const prefix = first >> 6;
94
+
95
+ if (prefix === 0b00) {
96
+ return {
97
+ value: first & 0x3f,
98
+ byteLength: 1
99
+ };
100
+ }
101
+
102
+ if (prefix === 0b01) {
103
+ if (offset + 1 >= array.length) return null;
104
+ const value = ((first & 0x3f) << 8) | array[offset + 1];
105
+ return {
106
+ value,
107
+ byteLength: 2
108
+ };
109
+ }
110
+
111
+ if (prefix === 0b10) {
112
+ if (offset + 3 >= array.length) return null;
113
+ const value = (
114
+ ((first & 0x3F) << 24) |
115
+ (array[offset + 1] << 16) |
116
+ (array[offset + 2] << 8) |
117
+ array[offset + 3]
118
+ ) >>> 0;
119
+ return {
120
+ value,
121
+ byteLength: 4
122
+ };
123
+ }
124
+
125
+ if (prefix === 0b11) {
126
+ if (offset + 7 >= array.length) return null;
127
+
128
+ const hi = (
129
+ ((first & 0x3F) << 24) |
130
+ (array[offset + 1] << 16) |
131
+ (array[offset + 2] << 8) |
132
+ array[offset + 3]
133
+ ) >>> 0;
134
+
135
+ const lo = (
136
+ (array[offset + 4] << 24) |
137
+ (array[offset + 5] << 16) |
138
+ (array[offset + 6] << 8) |
139
+ array[offset + 7]
140
+ ) >>> 0;
141
+
142
+ const full = BigInt(hi) * 4294967296n + BigInt(lo); // 2^32
143
+
144
+ if (full <= BigInt(Number.MAX_SAFE_INTEGER)) {
145
+ return {
146
+ value: Number(full),
147
+ byteLength: 8
148
+ };
149
+ } else {
150
+ return {
151
+ value: full,
152
+ byteLength: 8
153
+ };
154
+ }
155
+ }
156
+
157
+ return null;
158
+ }
159
+
160
+
161
+
162
+ function concatUint8Arrays(arrays) {
163
+ var totalLength = 0;
164
+ for (var i = 0; i < arrays.length; i++) {
165
+ totalLength += arrays[i].length;
166
+ }
167
+
168
+ var result = new Uint8Array(totalLength);
169
+ var offset = 0;
170
+
171
+ for (var i = 0; i < arrays.length; i++) {
172
+ result.set(arrays[i], offset);
173
+ offset += arrays[i].length;
174
+ }
175
+
176
+ return result;
177
+ }
178
+
179
+ function arraybufferEqual(buf1, buf2) {
180
+ //if (buf1 === buf2) {
181
+ //return true;
182
+ //}
183
+
184
+ if (buf1.byteLength !== buf2.byteLength) {
185
+ return false;
186
+ }
187
+
188
+ var view1 = new DataView(buf1);
189
+ var view2 = new DataView(buf2);
190
+
191
+ for (let i = 0; i < buf1.byteLength; i++) {
192
+ if (view1.getUint8(i) !== view2.getUint8(i)) {
193
+ return false;
194
+ }
195
+ }
196
+
197
+ return true;
198
+ }
199
+
200
+
201
+
202
+ function buildAckFrameFromPackets(packets, ecnStats, ackDelay) {
203
+ if (!packets || packets.length === 0) return null;
204
+
205
+ var sorted = packets.slice().sort((a, b) => b - a);
206
+
207
+ var ranges = [];
208
+ var rangeStart = sorted[0];
209
+ var rangeEnd = rangeStart;
210
+ var lastPn = rangeStart;
211
+
212
+ for (var i = 1; i < sorted.length; i++) {
213
+ var pn = sorted[i];
214
+ if (pn === lastPn - 1) {
215
+ lastPn = pn;
216
+ } else {
217
+ ranges.push({ start: lastPn, end: rangeEnd });
218
+ rangeEnd = pn;
219
+ lastPn = pn;
220
+ }
221
+ }
222
+ ranges.push({ start: lastPn, end: rangeEnd });
223
+
224
+ var firstRange = ranges[0].end - ranges[0].start;
225
+ var ackRanges = [];
226
+
227
+ for (var i = 1; i < ranges.length; i++) {
228
+ var gap = ranges[i - 1].start - ranges[i].end - 1;
229
+ var length = ranges[i].end - ranges[i].start;
230
+ ackRanges.push({ gap: gap, length: length });
231
+ }
232
+
233
+ var frame = {
234
+ type: 'ack',
235
+ largest: sorted[0],
236
+ delay: ackDelay || 0, // ← כאן מכניסים את ה־delay שחושב
237
+ firstRange: firstRange,
238
+ ranges: ackRanges
239
+ };
240
+
241
+ if (ecnStats) {
242
+ frame.ecn = {
243
+ ect0: ecnStats.ect0 || 0,
244
+ ect1: ecnStats.ect1 || 0,
245
+ ce: ecnStats.ce || 0
246
+ };
247
+ }
248
+
249
+ return frame;
250
+ }
251
+
252
+ function build_ack_info_from_ranges(flatRanges, ecnStats, ackDelay) {
253
+ if (!flatRanges || flatRanges.length === 0) return null;
254
+ if (flatRanges.length % 2 !== 0) throw new Error("flatRanges must be in [from, to, ...] pairs");
255
+
256
+ var ranges = [];
257
+ for (var i = 0; i < flatRanges.length; i += 2) {
258
+ var from = flatRanges[i];
259
+ var to = flatRanges[i + 1];
260
+ if (to < from) throw new Error("Range end must be >= start");
261
+ ranges.push({ start: from, end: to });
262
+ }
263
+
264
+ // Sort ranges from highest to lowest end
265
+ ranges.sort((a, b) => b.end - a.end);
266
+
267
+ // Merge overlapping or adjacent ranges
268
+ var merged = [ranges[0]];
269
+ for (var i = 1; i < ranges.length; i++) {
270
+ var last = merged[merged.length - 1];
271
+ var curr = ranges[i];
272
+ if (curr.end >= last.start - 1) {
273
+ // Merge them
274
+ last.start = Math.min(last.start, curr.start);
275
+ } else {
276
+ merged.push(curr);
277
+ }
278
+ }
279
+
280
+ var largest = merged[0].end;
281
+ var firstRange = largest - merged[0].start;
282
+ var ackRanges = [];
283
+
284
+ for (var i = 1; i < merged.length; i++) {
285
+ var gap = merged[i - 1].start - merged[i].end - 1;
286
+ var length = merged[i].end - merged[i].start;
287
+ ackRanges.push({ gap: gap, length: length });
288
+ }
289
+
290
+ return {
291
+ type: 'ack',
292
+ largest: largest,
293
+ delay: ackDelay || 0,
294
+ firstRange: firstRange,
295
+ ranges: ackRanges,
296
+ ecn: ecnStats ? {
297
+ ect0: ecnStats.ect0 || 0,
298
+ ect1: ecnStats.ect1 || 0,
299
+ ce: ecnStats.ce || 0
300
+ } : null
301
+ };
302
+ }
303
+
304
+
305
+ function build_ack_info_from_ranges2(flatRanges, ecnStats, ackDelay) {
306
+ if (!flatRanges || flatRanges.length === 0) return null;
307
+ if (flatRanges.length % 2 !== 0) throw new Error("flatRanges must be in [from, to, ...] pairs");
308
+
309
+ // בניית טווחים מלאים
310
+ var ranges = [];
311
+ for (var i = 0; i < flatRanges.length; i += 2) {
312
+ var from = flatRanges[i];
313
+ var to = flatRanges[i + 1];
314
+ if (to < from) throw new Error("Range end must be >= start");
315
+ ranges.push({ start: from, end: to });
316
+ }
317
+
318
+ // ממיינים מהגדול לקטן לפי end
319
+ ranges.sort(function (a, b) { return b.end - a.end; });
320
+
321
+ // הסרת טווחים חופפים או לא חוקיים
322
+ for (var i = 1; i < ranges.length; i++) {
323
+ if (ranges[i].end >= ranges[i - 1].start) {
324
+ throw new Error("Overlapping ranges are not allowed");
325
+ }
326
+ }
327
+
328
+ // התחלת ack מהטווח הגבוה ביותר
329
+ var largest = ranges[0].end;
330
+ var firstRange = largest - ranges[0].start;
331
+
332
+ var ackRanges = [];
333
+ var runningEnd = ranges[0].start - 1;
334
+
335
+ for (var i = 1; i < ranges.length; i++) {
336
+ var gap = runningEnd - ranges[i].end - 1;
337
+ var length = ranges[i].end - ranges[i].start;
338
+
339
+ // בדיקה אם הבלוק הבא יגלוש מתחת ל־0
340
+ var nextEnd = runningEnd - (gap + 1 + length);
341
+ if (nextEnd < 0) {
342
+ console.warn("Skipped range due to underflow risk:", ranges[i]);
343
+ continue; // לא מוסיפים את הטווח הזה
344
+ }
345
+
346
+ ackRanges.push({ gap: gap, length: length });
347
+ runningEnd = ranges[i].start - 1;
348
+ }
349
+
350
+ var frame = {
351
+ type: 'ack',
352
+ largest: largest,
353
+ delay: ackDelay || 0,
354
+ firstRange: firstRange,
355
+ ranges: ackRanges,
356
+ ecn: ecnStats ? {
357
+ ect0: ecnStats.ect0 || 0,
358
+ ect1: ecnStats.ect1 || 0,
359
+ ce: ecnStats.ce || 0
360
+ } : null
361
+ };
362
+
363
+ return frame;
364
+ }
365
+
366
+
367
+
368
+ function quic_acked_info_to_ranges(ackFrame) {
369
+ var flatRanges = [];
370
+
371
+ if (!ackFrame || ackFrame.type !== 'ack') return flatRanges;
372
+
373
+ var largest = ackFrame.largest;
374
+ var firstRange = ackFrame.firstRange;
375
+
376
+ // טווח ראשון: [largest - firstRange, largest]
377
+ var rangeEnd = largest;
378
+ var rangeStart = rangeEnd - firstRange;
379
+ flatRanges.push(rangeStart, rangeEnd);
380
+
381
+ // נתחיל לבנות את שאר הטווחים לפי gap+length
382
+ var ranges = ackFrame.ranges || [];
383
+ for (var i = 0; i < ranges.length; i++) {
384
+ var { gap, length } = ranges[i];
385
+
386
+ // מעבר אחורה לפי gap
387
+ rangeEnd = rangeStart - 1 - gap;
388
+ rangeStart = rangeEnd - length;
389
+
390
+ flatRanges.push(rangeStart, rangeEnd);
391
+ }
392
+
393
+ return flatRanges;
394
+ }
395
+
396
+
397
+ module.exports = {
398
+ concatUint8Arrays,
399
+ arraybufferEqual,
400
+ readVarInt,
401
+ writeVarInt,
402
+ quic_acked_info_to_ranges,
403
+ build_ack_info_from_ranges
404
+ };
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "quico",
3
+ "version": "0.1.0",
4
+ "description": "A pure JavaScript implementation of QUIC, HTTP/3, QPACK, and WebTransport for Node.js",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "start": "node examples/webtransport_datagram_echo/server.js"
8
+ },
9
+ "keywords": ["quic", "http3", "h3", "webtransport", "datagram", "udp", "qpack", "tls", "tls1.3", "nodejs"],
10
+ "author": "colocohen",
11
+ "license": "Apache-2.0",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/colocohen/quico.git"
15
+ },
16
+ "bugs": {
17
+ "url": "https://github.com/colocohen/quico/issues"
18
+ },
19
+ "homepage": "https://github.com/colocohen/quico",
20
+ "dependencies": {
21
+ "@noble/curves": "^1.9.6",
22
+ "@noble/hashes": "^1.8.0",
23
+ "@peculiar/x509": "^1.13.0",
24
+ "@stablelib/aes": "^2.0.1",
25
+ "@stablelib/gcm": "^2.0.1",
26
+ "flat-ranges": "^1.0.1"
27
+ }
28
+ }
package/quico.svg ADDED
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1890" height="390" stroke="#000" stroke-linecap="round" stroke-linejoin="round" fill="#fff" fill-rule="evenodd"><g fill-rule="nonzero"><path d="M1637.8 214.7l70.7-58 1 1.3-23.6 41.7-18.5 32.5c-2.2 3.7-4.4 6.8-3 11.7 1.3 5.2 4.6 5.2 8.4 5.2 1 .1 2.3-.7 3.5-.8 11.4-1 14.6 1.2 21 15.7-40 33.8-81.4 66-122.8 98.2l-1.7-1.5c1.2-2 2.4-4.2 3.7-6.3l46.4-74c1.7-2.7 3-5.5 4.5-8.3 1.8-4 .1-7-4-6.8-7.5.3-15 1.5-22.4 1.8h-23.7c-.6 0-1-.7-2-1.4l29.2-24 31.3-26c.5-.4 1.2-.6 2-1.2z" stroke="none" fill="#ffea00"/><path d="M1769.4 368l-3.3-18.7c-3.3-13.7-12.5-22.7-24.5-29.3-6-3.2-12-6.6-14.4-14.4-6.3 18-17.7 30.8-35 37.5-17.6 6.8-34.5 4.5-50.4-3.6-4.5 6.2-8.5 13-13.7 18.6-3.7 4-8.8 7-13.7 9.7-5.7 3-10.2.6-11.4-5.8-.4-2.2-.8-4.5-1-6.7 0-3.4.5-6.5 3.6-9l33.4-26.6c2.4-2 5-4 7.7-5.4 2-1 4.8-1.3 8-2 1.5-8.8 10.7-12.4 17.5-18l18.4-15 10-8c10 6.4 20.6 9.2 32 7.3 11.6-2 18.8-9.8 22-20.8a41 41 0 0 0-4.8-32.5c-1.8-3.3-4.6-4.4-8-4l-18.5 3c-2 .4-3.5 2.2-5.8 3.7l13 6c8 4.6 12 15.8 7.6 23.3-3.4 5.7-11.4 9-19 7-15.5-3.7-33.3-22-30.7-40.8 1.6-12 6.4-22.8 18-29l25.6-13.5a72 72 0 0 1-26.5-30.6c-6-13-7.2-26.6-5.4-40.7-.5-.1-1-.2-1.5-.2-1.3 5.3-3.4 10.6-4 16l-.3 23.7c-.1 1.4-1.4 3-2.5 4-13.2 11-26.5 22-39.7 32.8l-43.4 36.2-6.2 4.2 5.3-12.2c8.4-17.2 16.7-34.4 22.6-52.6 5.3-16.6 2.5-31.6-9.7-43.8-8.2-8.3-18.7-13.2-30.7-14l-17.2-1.3 2.5-12.2c2.4-11 8.2-20.7 15.5-28.8 12-13.2 26.8-21.7 45-24.2a79 79 0 0 1 57.8 13.8 103 103 0 0 1 25.9 26.8c4.6-4.3 9.2-8.4 13.7-12.6 1.7-1.6 2.7-3 1.5-6l-19.5-48c-.3-.5-.4-1-.7-2 13-.6 25 1.7 36.5 6a94 94 0 0 1 44.7 36.7c1.6 2.2 4.2 4.4 6.8 5.2a80 80 0 0 1 37.2 22.9c6 6.8 11 14.8 16 22.6 3.8 6.2 6.6 13 10.3 20.4l-22.6.7c-6.2.1-8 2.5-5.6 8.2 3 7 7.8 12.4 14.5 16l4.5 2.3c-3.7 5.8-8.2 10.4-14 13.3-11.4 5.5-22.2-.6-26.3-9.7-2.5-5.6-7.2-7-11.6-4.5-3.8 2.4-4.6 8.3-1.6 13a34 34 0 0 0 38 14c8.3-2.7 15-8 19.2-16.2 1.3-2.5 2-5.3 3.8-7.5 2-2.7 4.6-5 7.5-7.8 3.5 11.3-14 35.3-31 44.8-17 9.5-35.4 10.3-54.4 7.8 15.2 10.5 20.7 25.3 19.4 42.5-.8 11-3.8 21.6-11.2 30 4 5.4 8.8 11.2 12.5 17.5 6.4 10.8 6.6 22.5 2.7 34.2-2 6.3-5 12.5-7.3 18.7-2 5.4-1.2 6.4 4.5 7l17.6 2.4c6 1.7 12.2 3.6 15 10.2 2.2 5 1.3 7.2-4.8 8.8-20.7 0-40.6 0-60.5-.1-1.6 0-3.2-.4-4.8-.7m31.2-263c-.4-.4-.7-.8-1.4-1.8-5.7-5.8-10.5-5.4-14.7 1.7-4.3 7.3-2.5 14.4 1.3 21.3 3.3 6 9 6.6 14.3 1 4.2-6 6-12 2-19 0 0 .1 0 0-.6l-1.7-2.2s.1 0 .1-.6z" stroke-linejoin="miter" stroke-linecap="butt" fill="#f75718" stroke-width="9" stroke="#f75718"/><g stroke="none"><path d="M1703.4.3c-2.5 1.3-3.2 2-4.5 4-1.5 2.5-1.4 7.7.2 11l2.4 5.6 1.7 4 3.3 8.6 3.6 9c1.5 3.3 3 7.6 3 7.7-.1.2-1-.5-2-1.5a24 24 0 0 0-3.1-2.4c-.8-.4-1.4-1-1.4-1 0-.5-8-5.8-8.8-5.8-.4 0-.8-.3-1-.6-.3-.4-2-1.4-4-2.2l-5.2-2.5a94 94 0 0 0-13.8-4.8c-10.5-2.6-23-3.8-32.3-3L1627 29c-.7.4-1.7.7-2.2.7a77 77 0 0 0-19 7.8c-.4.4-1 .8-1.2.8-.5 0-4.5 2.4-6 3.5a62 62 0 0 0-3.6 2.6 105 105 0 0 0-18 18 93 93 0 0 0-9.2 15.4l-2.8 6c-.5 1-1 2.3-1 3s-.2 1.3-.4 1.5c-.2.1-1 2-1.5 4.2a33 33 0 0 1-1.4 4.4c-.5.6-1.7 8.4-2.4 15-.8 8 .5 11.4 4.5 12.8 1.7.5 2.4.5 6-.3l13.5-2.4c2.2-.3 4.2-.3 6.2 0l6 1a34 34 0 0 1 19.6 10.8 30 30 0 0 1 5.3 9.5c2 8-1.3 21-10.3 39.3l-2.8 6.3c0 1.6-2 1.7-32.8 1.8l-36 3c-3 3-3.4 6.7-.7 10.3 2.5 3.2 1.4 3 32.5 3l28 .6a29 29 0 0 1-3 8c-.2.4-.7 1.3-1 2l-1 2-3.8 9.2c0 .6-2 4.7-3 5.7-.3.5-8 .7-35 .7-37.3 0-36-.1-38.7 2.6-3.8 4-2.8 9.6 2 12l2.2 1h29.6 29.8a72 72 0 0 1-5.9 6.5c-6.6 6.8-8.6 9.6-9 13-.2 1.8-.1 2.4 1.3 4.5 2.4 3.6 3 3.8 13.8 4l9.2.3 2 6.3c1.2 3.5 2 6.7 2 7-.2.6-4.2.7-27 .7H1535l-2 1c-2 1-4.6 5-4.6 7.2 0 1.6 2 4.6 4 6.2l2 1.5 25.6.2 25.8 1c.1.5-1.6 3.4-3.8 6.6l-4.7 7-10.5 16.2-5.5 8.5a132 132 0 0 1-5.1 7.9c-5.5 8.3-6.3 10-6 12.8.6 5.5 5.7 8.6 11.4 7a51 51 0 0 0 7.8-4.6l6.5-4c.3 0 .5-.2.5-.4s.8-1 1.8-1.5l6.4-4.7 5.5-3.4c.5.1 1.2 1.7 2 5 2.2 8 3.2 10 6.7 13.4a16 16 0 0 0 9.9 5c4.7.7 9.5.1 14.3-1.8a75 75 0 0 0 13.7-8.7c2.6-2.3 6.7-6.6 8.7-9l3.2-3.8 1.2-1.5 2.8 1 3.6 1.3c.5.3 1.5.5 2.4.5s3 .3 4.4.7c7.3 1.8 25.2.3 32.6-2.7l3.5-1.4a80 80 0 0 0 15.3-8l3-2a164 164 0 0 0 13.6-13.3l1.5-1.8 3.6 2 4.4 2.3c2 1 5.4 4.7 7.5 8 4.4 6.8 5.5 11.7 6.4 27.5.2 3.5.6 5.6 1.3 7 1.2 2.7 4.5 5.3 7.2 5.6a1188 1188 0 0 0 40.7.2l38.7-.2 3-1.4c3-1.5 7.3-5.4 8.3-7.7l1.4-3c1-2 1-11.8.2-14.6-1.2-3.5-4-8.8-5.7-10.8a57 57 0 0 0-9.5-7.6c-.2 0-1.7-.7-3.3-1.5-1.6-.7-3.2-1.4-3.6-1.4s-2-.4-3.5-1a18 18 0 0 0-4.4-.9c-2 0-2.5-1-1.5-3 .5-1 .8-2 .8-2.2a10 10 0 0 1 .4-2c1.8-5.7 2.2-9.4 2.2-17.7 0-8.8-.1-9.4-2.5-18.2a90 90 0 0 0-6.4-14.2c-.6-1-1-2-.8-2 .1-.2 3-1 6.2-1.7a47 47 0 0 0 7.2-2.2c.7-.4 1.6-.7 2-.7 1 0 7.5-3 9.3-4.2.8-.6 1.6-1 1.8-1 .5 0 6.5-5 8-6.5a45 45 0 0 0 5.9-8.5l1.5-2.7c1-1.2 2-7 2-10.6 0-8.2-5.2-15-13.5-17.3-3-.8-12.7-1-17-.3l-10 1c-.8-.3-2.3-4.6-1.8-5.4.1-.2.8-.3 1.5-.3.8 0 2-.2 2.8-.5a21 21 0 0 1 4.2-.9c6-1 18.6-5.5 21.5-7.8a4 4 0 0 1 1.7-.9c.5 0 5.2-3.2 9-6.3a107 107 0 0 0 15.5-16.7c1.8-2.5 3.2-4.7 3.2-5 0-.1.6-1 1.3-2 2.6-3.7 5.2-10 8-19 1.4-4.5 2-12.5 1.4-17.4-.4-2.5-1-5-1.3-5.5-.4-.5-.8-1.5-.8-2 0-1.4-3.2-6.7-7-11a61 61 0 0 1-6.7-10.8c-6-12-9.8-18-15.4-25.2a140 140 0 0 0-16.4-16.4c-1-.6-2.2-1.6-2.8-2a69 69 0 0 0-8.4-5.9l-5-2.7-4.6-2.4-6.3-2.7c-4-1.5-7-3.5-8-5.2a139 139 0 0 0-16.3-18 141 141 0 0 0-14.3-11.1c-.8-.4-2.2-1.2-3-1.7-5.5-3.2-16.7-8-21-9.2l-4.6-1.2a125 125 0 0 0-31-4c-10.3-.2-11-.2-13 .7zm27.3 14.8a66 66 0 0 1 11.9 2.5 12 12 0 0 0 2.4.6 67 67 0 0 1 14.3 5.6 78 78 0 0 1 22.3 15.8c4.6 4.6 10 11.2 13.6 16.4 2.3 3.3 4.2 5 5.7 5a53 53 0 0 1 10.5 3.9c.3.2 1 .4 1.5.4.7 0 1.2.2 1.4.4.2.3 1.4 1 2.8 1.7l7.5 4.4c.4.4 1 .7 1.3.7.2 0 1 .5 1.4 1 .5.6 1.8 1.6 2.8 2.2a105 105 0 0 1 17 17.5c0 .2.5 1 1 1.4.6.6 1.2 1.6 1.6 2.3.3.6 1 2 1.8 3a119 119 0 0 1 8.1 15l3.6 7c1.6 2.6 1.7 3 1.4 3.5-.4.3-8 1-18.4 1.3l-7.2.3-1.3 1.5c-1 1.3-1.2 1.7-1 3.7.3 2.5 2.5 7 4.6 9.5a81 81 0 0 1 2.2 2.6 41 41 0 0 0 9.6 7c3.4 1.6 3.3 2.4-1.7 7.4-6 6.2-11.4 9-17.3 9a16 16 0 0 1-9.3-2.5 18 18 0 0 1-7.9-8.4c-3-5.2-6-7-9.5-6-2.2.7-5 2.7-5 3.5 0 .4-.3 1-.7 1.3-.5.4-.7 1.5-.7 3 0 4 3 8.4 8.6 13.2l3 2.3c.1 0 1.2.7 2.4 1.5 1.2.7 2.5 1.4 3 1.4s1.6.4 2.5 1a9 9 0 0 0 3.2 1c.7 0 1.4.2 1.5.5.2.3 2.7.5 5.8.5 5.2 0 8.2-.6 11.4-2 .6-.2 1.5-.6 2.2-1 6-2.6 11.8-8.2 16-15.8l2.2-4.2c0-.7 2-4 3-5.2.7-.7 1.8-1.5 2.6-2l2.5-1.4c.7-.3 1.4-.5 1.6-.4.5.3 0 3.6-.6 4.2-.2.3-.4 1-.4 1.5a6 6 0 0 1-.7 2c-.4.4-.8 1.2-.8 1.5a43 43 0 0 1-4.6 9.5c-.6.8-1 1.6-1 1.8 0 .4-3 4.7-4.4 6.3a69 69 0 0 1-17.6 15.3c-4.8 3-12 6-15.2 6.7l-2.7.8c-2 1-12 2.2-19 2.2s-18.3-1-20-2c-.6-.2-1-.3-1-.2-.4.3 1.6 2 3.3 3a42 42 0 0 1 11 10.6 37 37 0 0 1 4.7 9.9l1.4 4.6a106 106 0 0 1 .1 22.5c-.3.4-.6 1.4-.8 2.3a21 21 0 0 1-.8 3.4l-1.3 3.6a66 66 0 0 1-4.8 10.4l-.7 1.5c-.2.4-1-.1-4.5-2-1-.6-1.6-.8-1.6-.6a47 47 0 0 0 5.2 5.6c5 5.3 8.7 9.4 8.7 10 0 .2.5 1 1 1.8 1.4 2 4.3 8 5 11 1.4 5 2.3 14 1.6 15.5-.3.6-.6 2.3-.8 4a52 52 0 0 1-4.6 16.3l-1.4 3.2a93 93 0 0 1-3.3 7.6c-.8 1.2-.6 2.5.3 3.6 1 1 4 1.4 13.6 2.3 3.7.3 9.7 1.6 12.6 2.7 2.2.8 7 3.7 8.5 5 2 2 3.2 4.4 3.2 7.4 0 2.5-.1 2.7-1.8 4l-1.8 1.2H1804c-18 0-32.8-.2-33-.5-.4-.2-.8-2-1-4.4l-2-10a48 48 0 0 0-5.7-15.4c-.8-1.2-1.4-2.2-1.4-2.4 0-.3-2.6-3.4-4.6-5.6a74 74 0 0 0-9.5-7.4c-.5 0-8.4-4.8-11-6.7-3.6-2.7-6.4-6-6.4-7.5 0-.8-.2-1.7-.5-2-.3-.5-.5-.4-1 .6-.3.7-.7 1.4-1 1.6-.3.1-.5.6-.5 1 0 1.3-4.4 9.7-6.6 12.7-4.6 6.3-10.8 12.3-15.6 15.2-1 .6-2 1.4-2.3 1.8-.2.3-.7.6-1 .6-.4 0-2 .6-3.3 1.4-1.5.8-3 1.5-3.7 1.5-.4 0-1 .3-1.5.7-.3.4-1 .7-2 .7-.7 0-1.4.2-1.6.4-.1.3-1.7.6-3.5.8s-4 .6-5 1a34 34 0 0 1-14.2 0l-4.7-1-4.3-.7-11-4.2c-3.3-1.6-4.4-1.7-4.4-.4 0 1-1.8 4.4-3.2 6.3-.6.8-1 1.8-1 2 0 .3-.3.8-.7 1l-1.7 2.3c-6 8.8-17 16.6-23 16.8-2.8.1-3.6-.4-5-3.5-1.7-3.2-2-5-2.5-9-.4-5.8 1-8.5 6.2-12a33 33 0 0 0 3.1-2.5c.7-.6 1.4-1 1.6-1 .3 0 .8-.4 1.3-.8a86 86 0 0 1 4.9-4 196 196 0 0 0 10-7.7 225 225 0 0 1 7-5.5l6-4.7c5.4-4.4 9-6 10-3.8.6 1.5 1.6.5 2.6-2.7 1-3 1.4-3.6 4.5-6.6l7.8-6.3c.3 0 .7-.3 1-.6.4-.7 3-2.7 10-8l4.3-3.5c.4-.4 3.7-3 5.2-4.2.3-.2 1.4-1 2.4-2l5-4a21 21 0 0 0 3.3-2.8c.3-.8 2-.3 5.5 1.5a52 52 0 0 0 8.2 3.4c4.4 1.4 4.8 1.5 12.5 1.5 7.3 0 8.4-.1 11.2-1a28 28 0 0 0 14.7-13c3-5.6 3.7-9 3.6-17.2 0-6.4-.6-10.8-1.8-13.5l-.8-1.8c0-1-3-6.4-4.4-7.7-2.8-2.7-8.5-3.8-12.5-2.6a121 121 0 0 1-9.1 2.3c-.8.1-1.7.4-2 .7-.3.2-1.5.5-2.5.7-2.6.4-4.3 2-4 4.3 0 .2 1.2.7 2.6 1 7.3 1.8 14 6.8 16.6 12.5 2 4.5 2.5 10.5 1 13l-1.4 2.5c-.3.6-.7 1-.8 1-.3 0-1 .5-1.7 1-1.3 1.2-4 2.6-7 3.6-2 .7-6.5.7-7 .1-.2-.3-.8-.5-1.4-.5a25 25 0 0 1-6.5-2.2l-3-1.5c-1.3-.6-2.6-1.3-3-1.7a51 51 0 0 1-2.7-2.3 49 49 0 0 1-10.4-12.2c-1.4-2.2-2.4-4.4-2.4-5 0-.4-.4-1.2-.7-1.7-.4-.5-.8-1.6-.8-2.3 0-.8-.2-1.8-.4-2.3-.7-1.2-.8-10-.2-11.2.3-.5.6-2 .8-3.2.2-1.3.5-2.7.7-3 .3-.5 1-1.8 1.5-3 3-6 9-14.4 10.8-14.4.3 0 1-.6 2-1.4s1.6-1.5 1.8-1.5 1-.5 2-1a77 77 0 0 1 12.4-6c.3 0 1-.4 1.5-.7.6-.4 1.4-.8 2-.8.4 0 1.2-.2 1.7-.4.4-.2 2-1 3.8-1.6 1.7-.6 3-1.4 3-1.6.1-.2-.8-1-2-1.5a7 7 0 0 1-2.4-1.5c-.1-.2-1.6-1.3-3-2.5a68 68 0 0 1-10.3-10.5c-.6-1-1.4-1.8-1.8-2-.3-.2-.6-.6-.6-.8s-1-1.7-2-3.3c-2-3.2-6.6-12-6.6-13 0-.4-.2-.8-.4-1-1-1-2.5-7.7-3.5-15-.7-5-.3-19 .5-19.7.7-.3.5-2-.2-2-.5-.2-2.2 3-2.2 4 0 .3-.2 1.3-.6 2a74 74 0 0 0-3.7 33.1c.3 3.7.3 4-1 5-2 2-6 5.3-6.5 5.3-.2 0-1.5 1-2.8 2.2l-5.8 5-3.8 3c-.2.3-1.7 1.4-3.2 2.6-1.4 1.2-4 3.3-5.8 4.7s-3.2 2.8-3.2 3c0 .3-.4.6-.8.7-.5.2-1.6 1-2.6 1.8l-5 4.2a921 921 0 0 1-5.2 4.3l-2.4 2c-.3.2-1.5 1.2-2.7 2.2a355 355 0 0 0-10.3 8.6c-1.3 1-3 2.5-4 3.2a72 72 0 0 0-4.9 3.9c-16.5 13.8-19.8 16.4-20 16a16 16 0 0 1 1.3-3.4 58 58 0 0 0 2-4.7c.3-1 1-2 1.3-2.5.3-.3.6-1 .6-1 0-.3 1-2.6 2.4-5.2 1.2-2.7 3-6 3.5-7.7l1.8-3.6 1-2c.2-.7 1.3-3 2.4-5.3l2.5-5.5c1-2.5 2.2-5.2 3-6.6.3-.7.6-1.7.6-2 0-.4.5-1.5 1-2.5s1-2 1-2.4c0-.3.2-1 .5-1.4a36 36 0 0 0 2-6.3c.2-1.2.6-2.4.8-2.6a66 66 0 0 0 1.6-21.5c-.2-.3-.6-1.5-.8-2.6-.7-5-7-15-12.3-19.4a56 56 0 0 0-17.8-10l-4.8-1.5c-5.2-1.6-18-2-22.7-1-1.3.3-1.3.3.2-6l1-4.7c.1-1 .5-2 .8-3 .4-.8.8-2 1-3s.5-1.7.7-2 .5-1 .7-1.7c1.2-4 5.5-11.5 10.6-18 2.2-3 12.3-13 13-13 .2 0 1-.4 1.3-1 1-1 4.2-3 6.8-4.4a10 10 0 0 0 2.4-1.5c.2-.2 1.4-.8 3-1.4a82 82 0 0 0 4-1.6c3.2-1.4 4.7-2 13.2-3.7 6-1.4 19.7-1.8 24.6-.7l6 1.2c6.8 1.2 10.7 2.6 18.4 6.4a78 78 0 0 1 20.3 13.7 182 182 0 0 1 14.6 16.6c.7 1.2 1.6 2 2 2 .3 0 3.2-2.7 6.5-6l6.4-6c.3 0 1.2-.7 2-1.7 1.4-1.5 1.5-2.4.6-3.8-.5-.7-4-8.4-4-9 0-.4-1.7-4.5-3.4-7.8l-1-2.7c0-.4-.2-1-.4-1.2-.4-.4-1.5-3-3.2-7.6l-1.2-3-2.8-6.5c-.3-.5-.5-1-.5-1.4s-.4-1.4-1-2.5c-2-4.3-3-7.2-2.7-7.8.2-.6 1.2-.6 5.4-.5l9 .7zm-32.3 157c0 .4-.4 1.2-.8 1.8a22 22 0 0 0-3 5c-.5 1-1.3 2.2-1.7 2.5-.3.3-.6 1-.6 1.2 0 .4-.6 1.5-1.2 2.4a70 70 0 0 0-4.1 7.6c-4 8-5 9.6-6.4 11.5-.7 1-1.2 2-1.2 2.3s-.4 1-1 1.3c-.4.4-1 1.4-1.4 2.3s-2.4 4.5-4.6 8l-5.6 9.6-4.7 8c-3 5-3.4 6.8-2.2 8.4.4.6.7 1.5.7 2 0 2 1.6 3 6.2 2.8 2.2 0 4.7-.3 5.4-.6a14 14 0 0 1 4-.5c2.4 0 2.6.1 4.2 2 1.7 2.3 4.6 6.5 4.6 7 0 .1.7 1 1.4 2l1.5 2c0 .6-6 6.5-6.5 6.5-.4 0-1 .5-1.6 1-.4.6-1.6 1.7-2.5 2.3a39 39 0 0 0-3.3 2.7 33 33 0 0 1-7.4 5.8c-.3 0-1.3.8-2 1.7-1.5 1.7-10.4 9-12 10-.5.3-1.6 1.2-2.5 2-.8.8-2 1.5-2.3 1.5-.5 0-1 .5-1.4 1.2-.3.6-1.3 1.5-2 2-1 .5-1.8 1-2 1.5-.6 1-6.7 5.5-7.5 5.5-.5 0-1 .3-1 1a85 85 0 0 1-11.1 9.1c-.3 0-1.2 1-2.2 2s-2 2-2.5 2c-.3 0-1.3.8-2 1.7s-1.8 1.7-2.2 1.7-1.4.7-2.3 1.5a99 99 0 0 1-8.6 7.1l-8.2 6.3c-4 3.6-8.3 6.6-9.3 6.6-.5 0-1 .5-1.4 1-.5 1-2.8 2.7-2.8 2 0-.6 1.5-3 2-3 .3 0 .5-.4.5-1a85 85 0 0 1 8-13c.5-.6 1.3-2 1.8-2.8.4-1 1-1.8 1-2 .1-.1 1.3-1.7 2.5-3.6 1.3-2 2.7-3.5 3-3.7s.7-.6.7-1c0-1 2-4.7 3.3-5.8.5-.4 1-1.2 1-1.5 0-.4.6-1.5 1.4-2.5s1.4-2 1.4-2.3.4-.7.8-1c.3-.3.7-1 .7-1.5s.3-1 .7-1.2c.4-.1.8-.7 1-1.2.1-.6.8-1.8 1.4-2.6.7-.8 1.2-1.7 1.2-2 0-.2.6-1.2 1.4-2 .8-1 1.4-2 1.4-2.4 0-.5.5-1.2 1-1.7.5-.4 1-1.2 1-1.7s.1-1 .3-1 .8-.8 1.3-1.8l3-4.8c1-1.7 2-3.3 2-3.7 0-.3.3-.8.7-1.2.4-.3 1.6-2.3 2.6-4.3l1.8-3.7-1-1.5c-1.5-2.4-2.3-2.6-9.5-1.7-7.8 1-35 1.6-35.5 1-.2-.3.7-1.2 2-2 1.3-1 3-2.2 3.7-3l8-6.5c.8-.3 1.3-1 1.3-1 0-.3 1-1.2 2.3-2 1.2-.8 2.8-2 3.5-2.7 2.8-2.8 10.8-9.3 11.3-9.3.2 0 1.5-1 2.8-2.4s2.7-2.4 3.2-2.4 1-.4 1.4-1c.3-.5 1.6-2 3-3l3.8-3.3c.6-.7 1.4-1.3 1.8-1.3s1.3-.7 2-1.5l3-2.8a169 169 0 0 0 8.6-7l4-3c.8-.5 1.5-1 1.5-1.3s1-1.3 2.6-2.2c1.4-1 2.6-2 2.6-2a136 136 0 0 1 11.7-10 38 38 0 0 0 4.5-4L1687 179c.2 0 1-.7 2-1.6 5.8-5 9.6-7 9.6-5.4zm146.3 60.6c1 1 1.3 4.2.3 6l-1.8 3.4c-1 2.3-4.4 5.8-7 7.5a32 32 0 0 1-10.9 5c-.5 0-1.5.3-2.2.7-2 1-3 .5-2.7-1.7.2-1 .5-5.7.7-10.8l.3-9 4.2-.6 5-1c.5-.3 3.6-.5 7-.5 5.4 0 6 .1 7 1zm-56-128.7a19 19 0 0 0-5.5 6.7c-.8 1.5-1 2.7-1 7.4.1 5.3.1 5.6 1.6 8.4 3.8 7 9.4 9.7 13.7 6.5 2.5-1.8 3.3-2.8 5-6 1.3-2.7 1.4-3.2 1.4-8.4 0-5-.1-5.7-1.3-8-3.2-6.5-9.6-9.5-14-6.6z" fill="#000"/><path d="M1827.6 232.5l16-1c4.7.3 4 5 3 7.3a40 40 0 0 1-8 11.9 37 37 0 0 1-20.1 9.3l.4-24.4c.1-1.3 5.5-2.2 8.8-3.2z" fill="#ef7c34"/></g></g><g stroke-linejoin="miter" stroke-width="20"><path d="M314 167.6v54q0 19.6-5.2 37-5.2 17.4-14.7 31.6-9.5 14-23 24.7-13.5 10.6-30 16.7l60 47.4h-74l-49.2-39.5h-50.3q-25.3 0-47-8.8Q58.8 322 43 306.2q-15.7-15.7-24.7-37.4-9-21.6-9-47.3v-54q0-25.5 9-47.2Q27.4 98.6 43 83q15.7-15.6 37.4-24.5 21.6-8.8 47-8.8h69.2q25.4 0 47 8.8 21.5 9 37.2 24.5 15.7 15.6 24.6 37.4 8.8 21.7 8.8 47.2zm-51 54v-54q0-15-4.8-27.4-4.8-12.3-13.5-21-8.8-8.8-21-13.6-12.3-4.8-27-4.8h-69.2q-15 0-27.2 4.8-12.3 4.8-21 13.6-9 8.7-13.7 21-4.8 12.3-4.8 27.4v54q0 15 4.8 27.4 4.8 12.3 13.7 21 8.8 8.8 21 13.6 12.3 4.8 27.2 4.8h68.8q15 0 27.2-4.8 12.3-4.8 21.2-13.6 8.8-8.7 13.6-21 4.8-12.3 4.8-27.4zM651.5 73v264.5q0 5.7-2 10.5-2 5-5.7 8.5-3.7 3.5-8.6 5.5-4.8 2-10.3 2H506q-16.8 0-34-3.7-17.2-3.6-33.3-11.2-16.2-7.7-30.4-19.4-14.2-11.8-25-28-10.6-16.2-16.7-37-6-20.8-6-46.4V73h52.8v145.5q0 22.4 6.2 37.8 6.2 15.4 15.7 25.8 9.5 10.3 21 16.2 11.4 6 21.6 8.7 10.3 3 18 3.6 7.8.7 10.2.7H599V73h52.8zM766 73v291h-52.8V73H766zm322.3 238.3V364H898q-7.3 0-15.7-1.7-8.5-1.8-16.7-5.4-8.2-3.7-15.7-9.5-7.5-5.7-13.3-14-5.8-8.2-9.2-19-3.5-10.8-3.5-24.4V147q0-7.3 1.7-15.7 1.8-8.5 5.4-16.7 3.7-8.2 9.5-15.7 6-7.5 14-13.3 8.3-5.8 19-9.2Q884.3 73 898 73h190.4v52.8H898q-10.4 0-15.8 5.5-5.5 5.4-5.5 16.2V290q0 10 5.6 15.7 5.5 5.6 15.7 5.6h190.4z" fill="#c1c1c1"/><path d="M1459.5 190.7v55.6q0 26.6-9 49-9 22.4-25.4 38.6-16.2 16.2-38.4 25.3-22.3 9-48.5 9h-71.4q-26.2 0-48.5-9-22.3-9-38.6-25.3-16.2-16.2-25.5-38.6-9.2-22.3-9.2-49v-55.6q0-26.4 9.2-48.8 9.3-22.5 25.5-38.6 16.3-16 38.6-25.3 22.3-9 48.5-9h71.4q26.2 0 48.5 9 22.2 9.2 38.4 25.3 16.3 16 25.4 38.6 9 22.4 9 48.8zm-52.7 55.6v-55.6q0-15.6-5-28.3-5-12.7-14-21.7-9-9-21.7-14-12.7-5-28-5h-71.4q-15.4 0-28 5-12.7 5-21.8 14-9.2 9-14 21.7-5 12.7-5 28.3v55.6q0 15.6 5 28.3 5 12.7 14 21.7 9 9 21.8 14 12.7 5 28 5h71q15.5 0 28-5 12.7-5 22-14 9-9 14-21.7 5-12.7 5-28.3z" fill="#f75718"/></g></svg>