@tldraw/tlschema 4.3.0-canary.fda2775019a1 → 4.3.0-next.085293d79c32

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.
@@ -308,47 +308,51 @@ export declare const assetValidator: T.Validator<TLAsset>;
308
308
  * @public
309
309
  */
310
310
  export declare class b64Vecs {
311
+ /* Excluded from this release type: _legacyEncodePoint */
312
+ /* Excluded from this release type: _legacyEncodePoints */
313
+ /* Excluded from this release type: _legacyDecodePoints */
311
314
  /**
312
- * Encode a single point (x, y, z) to 8 base64 characters.
313
- * Each coordinate is encoded as a Float16 value, resulting in 6 bytes total.
315
+ * Encode an array of VecModels using delta encoding for improved precision.
316
+ * The first point is stored as Float32 (high precision for absolute position),
317
+ * subsequent points are stored as Float16 deltas from the previous point.
318
+ * This provides full precision for the starting position and excellent precision
319
+ * for deltas between consecutive points (which are typically small values).
314
320
  *
315
- * @param x - The x coordinate
316
- * @param y - The y coordinate
317
- * @param z - The z coordinate
318
- * @returns An 8-character base64 string representing the point
319
- */
320
- static encodePoint(x: number, y: number, z: number): string;
321
- /**
322
- * Convert an array of VecModels to a base64 string for compact storage.
323
- * Uses Float16 encoding for each coordinate (x, y, z). If a point's z value is
324
- * undefined, it defaults to 0.5.
321
+ * Format:
322
+ * - First point: 3 Float32 values = 12 bytes = 16 base64 chars
323
+ * - Delta points: 3 Float16 values each = 6 bytes = 8 base64 chars each
325
324
  *
326
325
  * @param points - An array of VecModel objects to encode
327
- * @returns A base64-encoded string containing all points
326
+ * @returns A base64-encoded string containing delta-encoded points
327
+ * @public
328
328
  */
329
329
  static encodePoints(points: VecModel[]): string;
330
330
  /**
331
- * Convert a base64 string back to an array of VecModels.
332
- * Decodes Float16-encoded coordinates (x, y, z) from the base64 string.
331
+ * Decode a delta-encoded base64 string back to an array of absolute VecModels.
332
+ * The first point is stored as Float32 (high precision), subsequent points are
333
+ * Float16 deltas that are accumulated to reconstruct absolute positions.
333
334
  *
334
- * @param base64 - The base64-encoded string containing point data
335
- * @returns An array of VecModel objects decoded from the string
335
+ * @param base64 - The base64-encoded string containing delta-encoded point data
336
+ * @returns An array of VecModel objects with absolute coordinates
337
+ * @public
336
338
  */
337
339
  static decodePoints(base64: string): VecModel[];
338
- /* Excluded from this release type: decodePointAt */
339
340
  /**
340
- * Get the first point from a base64-encoded string of points.
341
+ * Get the first point from a delta-encoded base64 string.
342
+ * The first point is stored as Float32 for full precision.
341
343
  *
342
- * @param b64Points - The base64-encoded string containing point data
344
+ * @param b64Points - The delta-encoded base64 string
343
345
  * @returns The first point as a VecModel, or null if the string is too short
344
346
  * @public
345
347
  */
346
348
  static decodeFirstPoint(b64Points: string): null | VecModel;
347
349
  /**
348
- * Get the last point from a base64-encoded string of points.
350
+ * Get the last point from a delta-encoded base64 string.
351
+ * Requires decoding all points to accumulate deltas.
349
352
  *
350
- * @param b64Points - The base64-encoded string containing point data
353
+ * @param b64Points - The delta-encoded base64 string
351
354
  * @returns The last point as a VecModel, or null if the string is too short
355
+ * @public
352
356
  */
353
357
  static decodeLastPoint(b64Points: string): null | VecModel;
354
358
  }
@@ -481,8 +485,9 @@ export declare const CameraRecordType: RecordType<TLCamera, never>;
481
485
  export declare const canvasUiColorTypeValidator: T.Validator<"accent" | "black" | "laser" | "muted-1" | "selection-fill" | "selection-stroke" | "white">;
482
486
 
483
487
  /**
484
- * Compress legacy draw shape segments by converting VecModel[] points to base64 format.
488
+ * Compress legacy draw shape segments by converting VecModel[] points to delta-encoded base64 format.
485
489
  * This function is useful for converting old draw shape data to the new compressed format.
490
+ * Uses delta encoding for improved Float16 precision.
486
491
  *
487
492
  * @public
488
493
  */
@@ -4215,8 +4220,11 @@ export declare interface TLDrawShapeProps {
4215
4220
  export declare interface TLDrawShapeSegment {
4216
4221
  /** Type of drawing segment - 'free' for freehand curves, 'straight' for line segments */
4217
4222
  type: 'free' | 'straight';
4218
- /** Base64-encoded points (x, y, z triplets stored as Float16) */
4219
- points: string;
4223
+ /**
4224
+ * Delta-encoded base64 path data.
4225
+ * First point stored as Float32 (12 bytes) for precision, subsequent points as Float16 deltas (6 bytes each).
4226
+ */
4227
+ path: string;
4220
4228
  }
4221
4229
 
4222
4230
  /**
package/dist-cjs/index.js CHANGED
@@ -181,7 +181,7 @@ var import_translations = require("./translations/translations");
181
181
  var import_b64Vecs = require("./misc/b64Vecs");
182
182
  (0, import_utils.registerTldrawLibraryVersion)(
183
183
  "@tldraw/tlschema",
184
- "4.3.0-canary.fda2775019a1",
184
+ "4.3.0-next.085293d79c32",
185
185
  "cjs"
186
186
  );
187
187
  //# sourceMappingURL=index.js.map
@@ -18,10 +18,16 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var b64Vecs_exports = {};
20
20
  __export(b64Vecs_exports, {
21
- b64Vecs: () => b64Vecs
21
+ b64Vecs: () => b64Vecs,
22
+ fallbackBase64ToUint8Array: () => fallbackBase64ToUint8Array,
23
+ fallbackUint8ArrayToBase64: () => fallbackUint8ArrayToBase64,
24
+ float16BitsToNumber: () => float16BitsToNumber,
25
+ numberToFloat16Bits: () => numberToFloat16Bits
22
26
  });
23
27
  module.exports = __toCommonJS(b64Vecs_exports);
24
- const POINT_B64_LENGTH = 8;
28
+ var import_utils = require("@tldraw/utils");
29
+ const _POINT_B64_LENGTH = 8;
30
+ const FIRST_POINT_B64_LENGTH = 16;
25
31
  const BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
26
32
  const B64_LOOKUP = new Uint8Array(128);
27
33
  for (let i = 0; i < 64; i++) {
@@ -36,23 +42,25 @@ const MANTISSA = new Float64Array(1024);
36
42
  for (let i = 0; i < 1024; i++) {
37
43
  MANTISSA[i] = 1 + i / 1024;
38
44
  }
39
- function uint16ArrayToBase64(uint16Array) {
40
- const uint8Array = new Uint8Array(
41
- uint16Array.buffer,
42
- uint16Array.byteOffset,
43
- uint16Array.byteLength
44
- );
45
- let result = "";
46
- for (let i = 0; i < uint8Array.length; i += 3) {
47
- const byte1 = uint8Array[i];
48
- const byte2 = uint8Array[i + 1];
49
- const byte3 = uint8Array[i + 2];
50
- const bitmap = byte1 << 16 | byte2 << 8 | byte3;
51
- result += BASE64_CHARS[bitmap >> 18 & 63] + BASE64_CHARS[bitmap >> 12 & 63] + BASE64_CHARS[bitmap >> 6 & 63] + BASE64_CHARS[bitmap & 63];
52
- }
53
- return result;
45
+ function nativeGetFloat16(dataView, offset) {
46
+ return dataView.getFloat16(offset, true);
47
+ }
48
+ function fallbackGetFloat16(dataView, offset) {
49
+ return float16BitsToNumber(dataView.getUint16(offset, true));
50
+ }
51
+ const getFloat16 = typeof DataView.prototype.getFloat16 === "function" ? nativeGetFloat16 : fallbackGetFloat16;
52
+ function nativeSetFloat16(dataView, offset, value) {
53
+ ;
54
+ dataView.setFloat16(offset, value, true);
55
+ }
56
+ function fallbackSetFloat16(dataView, offset, value) {
57
+ dataView.setUint16(offset, numberToFloat16Bits(value), true);
58
+ }
59
+ const setFloat16 = typeof DataView.prototype.setFloat16 === "function" ? nativeSetFloat16 : fallbackSetFloat16;
60
+ function nativeBase64ToUint8Array(base64) {
61
+ return Uint8Array.fromBase64(base64);
54
62
  }
55
- function base64ToUint16Array(base64) {
63
+ function fallbackBase64ToUint8Array(base64) {
56
64
  const numBytes = Math.floor(base64.length * 3 / 4);
57
65
  const bytes = new Uint8Array(numBytes);
58
66
  let byteIndex = 0;
@@ -66,8 +74,25 @@ function base64ToUint16Array(base64) {
66
74
  bytes[byteIndex++] = bitmap >> 8 & 255;
67
75
  bytes[byteIndex++] = bitmap & 255;
68
76
  }
69
- return new Uint16Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 2);
77
+ return bytes;
70
78
  }
79
+ function nativeUint8ArrayToBase64(uint8Array) {
80
+ return uint8Array.toBase64();
81
+ }
82
+ function fallbackUint8ArrayToBase64(uint8Array) {
83
+ (0, import_utils.assert)(uint8Array.length % 3 === 0, "Uint8Array length must be a multiple of 3");
84
+ let result = "";
85
+ for (let i = 0; i < uint8Array.length; i += 3) {
86
+ const byte1 = uint8Array[i];
87
+ const byte2 = uint8Array[i + 1];
88
+ const byte3 = uint8Array[i + 2];
89
+ const bitmap = byte1 << 16 | byte2 << 8 | byte3;
90
+ result += BASE64_CHARS[bitmap >> 18 & 63] + BASE64_CHARS[bitmap >> 12 & 63] + BASE64_CHARS[bitmap >> 6 & 63] + BASE64_CHARS[bitmap & 63];
91
+ }
92
+ return result;
93
+ }
94
+ const uint8ArrayToBase64 = typeof Uint8Array.prototype.toBase64 === "function" ? nativeUint8ArrayToBase64 : fallbackUint8ArrayToBase64;
95
+ const base64ToUint8Array = typeof Uint8Array.fromBase64 === "function" ? nativeBase64ToUint8Array : fallbackBase64ToUint8Array;
71
96
  function float16BitsToNumber(bits) {
72
97
  const sign = bits >> 15;
73
98
  const exp = bits >> 10 & 31;
@@ -111,114 +136,175 @@ function numberToFloat16Bits(value) {
111
136
  }
112
137
  class b64Vecs {
113
138
  /**
114
- * Encode a single point (x, y, z) to 8 base64 characters.
139
+ * Encode a single point (x, y, z) to 8 base64 characters using legacy Float16 encoding.
115
140
  * Each coordinate is encoded as a Float16 value, resulting in 6 bytes total.
116
141
  *
117
142
  * @param x - The x coordinate
118
143
  * @param y - The y coordinate
119
144
  * @param z - The z coordinate
120
145
  * @returns An 8-character base64 string representing the point
146
+ * @internal
121
147
  */
122
- static encodePoint(x, y, z) {
123
- const xBits = numberToFloat16Bits(x);
124
- const yBits = numberToFloat16Bits(y);
125
- const zBits = numberToFloat16Bits(z);
126
- const b0 = xBits & 255;
127
- const b1 = xBits >> 8 & 255;
128
- const b2 = yBits & 255;
129
- const b3 = yBits >> 8 & 255;
130
- const b4 = zBits & 255;
131
- const b5 = zBits >> 8 & 255;
132
- const bitmap1 = b0 << 16 | b1 << 8 | b2;
133
- const bitmap2 = b3 << 16 | b4 << 8 | b5;
134
- return BASE64_CHARS[bitmap1 >> 18 & 63] + BASE64_CHARS[bitmap1 >> 12 & 63] + BASE64_CHARS[bitmap1 >> 6 & 63] + BASE64_CHARS[bitmap1 & 63] + BASE64_CHARS[bitmap2 >> 18 & 63] + BASE64_CHARS[bitmap2 >> 12 & 63] + BASE64_CHARS[bitmap2 >> 6 & 63] + BASE64_CHARS[bitmap2 & 63];
148
+ static _legacyEncodePoint(x, y, z) {
149
+ const buffer = new Uint8Array(6);
150
+ const dataView = new DataView(buffer.buffer);
151
+ setFloat16(dataView, 0, x);
152
+ setFloat16(dataView, 2, y);
153
+ setFloat16(dataView, 4, z);
154
+ return uint8ArrayToBase64(buffer);
135
155
  }
136
156
  /**
137
- * Convert an array of VecModels to a base64 string for compact storage.
157
+ * Convert an array of VecModels to a base64 string using legacy Float16 encoding.
138
158
  * Uses Float16 encoding for each coordinate (x, y, z). If a point's z value is
139
159
  * undefined, it defaults to 0.5.
140
160
  *
141
161
  * @param points - An array of VecModel objects to encode
142
162
  * @returns A base64-encoded string containing all points
163
+ * @internal Used only for migrations from legacy format
143
164
  */
144
- static encodePoints(points) {
145
- const uint16s = new Uint16Array(points.length * 3);
165
+ static _legacyEncodePoints(points) {
166
+ if (points.length === 0) return "";
167
+ const buffer = new Uint8Array(points.length * 6);
168
+ const dataView = new DataView(buffer.buffer);
146
169
  for (let i = 0; i < points.length; i++) {
147
170
  const p = points[i];
148
- uint16s[i * 3] = numberToFloat16Bits(p.x);
149
- uint16s[i * 3 + 1] = numberToFloat16Bits(p.y);
150
- uint16s[i * 3 + 2] = numberToFloat16Bits(p.z ?? 0.5);
171
+ const offset = i * 6;
172
+ setFloat16(dataView, offset, p.x);
173
+ setFloat16(dataView, offset + 2, p.y);
174
+ setFloat16(dataView, offset + 4, p.z ?? 0.5);
151
175
  }
152
- return uint16ArrayToBase64(uint16s);
176
+ return uint8ArrayToBase64(buffer);
153
177
  }
154
178
  /**
155
- * Convert a base64 string back to an array of VecModels.
179
+ * Convert a legacy base64 string back to an array of VecModels.
156
180
  * Decodes Float16-encoded coordinates (x, y, z) from the base64 string.
157
181
  *
158
182
  * @param base64 - The base64-encoded string containing point data
159
183
  * @returns An array of VecModel objects decoded from the string
184
+ * @internal Used only for migrations from legacy format
160
185
  */
161
- static decodePoints(base64) {
162
- const uint16s = base64ToUint16Array(base64);
186
+ static _legacyDecodePoints(base64) {
187
+ const bytes = base64ToUint8Array(base64);
188
+ const dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
163
189
  const result = [];
164
- for (let i = 0; i < uint16s.length; i += 3) {
190
+ for (let offset = 0; offset < bytes.length; offset += 6) {
165
191
  result.push({
166
- x: float16BitsToNumber(uint16s[i]),
167
- y: float16BitsToNumber(uint16s[i + 1]),
168
- z: float16BitsToNumber(uint16s[i + 2])
192
+ x: getFloat16(dataView, offset),
193
+ y: getFloat16(dataView, offset + 2),
194
+ z: getFloat16(dataView, offset + 4)
169
195
  });
170
196
  }
171
197
  return result;
172
198
  }
173
199
  /**
174
- * Decode a single point (8 base64 chars) starting at the given offset.
175
- * Each point is encoded as 3 Float16 values (x, y, z) in 8 base64 characters.
200
+ * Encode an array of VecModels using delta encoding for improved precision.
201
+ * The first point is stored as Float32 (high precision for absolute position),
202
+ * subsequent points are stored as Float16 deltas from the previous point.
203
+ * This provides full precision for the starting position and excellent precision
204
+ * for deltas between consecutive points (which are typically small values).
176
205
  *
177
- * @param b64Points - The base64-encoded string containing point data
178
- * @param charOffset - The character offset where the point starts (must be a multiple of 8)
179
- * @returns A VecModel object with x, y, and z coordinates
180
- * @internal
206
+ * Format:
207
+ * - First point: 3 Float32 values = 12 bytes = 16 base64 chars
208
+ * - Delta points: 3 Float16 values each = 6 bytes = 8 base64 chars each
209
+ *
210
+ * @param points - An array of VecModel objects to encode
211
+ * @returns A base64-encoded string containing delta-encoded points
212
+ * @public
181
213
  */
182
- static decodePointAt(b64Points, charOffset) {
183
- const c0 = B64_LOOKUP[b64Points.charCodeAt(charOffset)];
184
- const c1 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 1)];
185
- const c2 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 2)];
186
- const c3 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 3)];
187
- const c4 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 4)];
188
- const c5 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 5)];
189
- const c6 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 6)];
190
- const c7 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 7)];
191
- const bitmap1 = c0 << 18 | c1 << 12 | c2 << 6 | c3;
192
- const bitmap2 = c4 << 18 | c5 << 12 | c6 << 6 | c7;
193
- const xBits = bitmap1 >> 16 & 255 | bitmap1 & 65280;
194
- const yBits = bitmap1 & 255 | bitmap2 >> 8 & 65280;
195
- const zBits = bitmap2 >> 8 & 255 | bitmap2 << 8 & 65280;
196
- return {
197
- x: float16BitsToNumber(xBits),
198
- y: float16BitsToNumber(yBits),
199
- z: float16BitsToNumber(zBits)
200
- };
214
+ static encodePoints(points) {
215
+ if (points.length === 0) return "";
216
+ const firstPointBytes = 12;
217
+ const deltaBytes = (points.length - 1) * 6;
218
+ const totalBytes = firstPointBytes + deltaBytes;
219
+ const buffer = new Uint8Array(totalBytes);
220
+ const dataView = new DataView(buffer.buffer);
221
+ const first = points[0];
222
+ dataView.setFloat32(0, first.x, true);
223
+ dataView.setFloat32(4, first.y, true);
224
+ dataView.setFloat32(8, first.z ?? 0.5, true);
225
+ let prevX = first.x;
226
+ let prevY = first.y;
227
+ let prevZ = first.z ?? 0.5;
228
+ for (let i = 1; i < points.length; i++) {
229
+ const p = points[i];
230
+ const z = p.z ?? 0.5;
231
+ const offset = firstPointBytes + (i - 1) * 6;
232
+ setFloat16(dataView, offset, p.x - prevX);
233
+ setFloat16(dataView, offset + 2, p.y - prevY);
234
+ setFloat16(dataView, offset + 4, z - prevZ);
235
+ prevX = p.x;
236
+ prevY = p.y;
237
+ prevZ = z;
238
+ }
239
+ return uint8ArrayToBase64(buffer);
240
+ }
241
+ /**
242
+ * Decode a delta-encoded base64 string back to an array of absolute VecModels.
243
+ * The first point is stored as Float32 (high precision), subsequent points are
244
+ * Float16 deltas that are accumulated to reconstruct absolute positions.
245
+ *
246
+ * @param base64 - The base64-encoded string containing delta-encoded point data
247
+ * @returns An array of VecModel objects with absolute coordinates
248
+ * @public
249
+ */
250
+ static decodePoints(base64) {
251
+ if (base64.length === 0) return [];
252
+ const bytes = base64ToUint8Array(base64);
253
+ const dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
254
+ const result = [];
255
+ let x = dataView.getFloat32(0, true);
256
+ let y = dataView.getFloat32(4, true);
257
+ let z = dataView.getFloat32(8, true);
258
+ result.push({ x, y, z });
259
+ const firstPointBytes = 12;
260
+ for (let offset = firstPointBytes; offset < bytes.length; offset += 6) {
261
+ x += getFloat16(dataView, offset);
262
+ y += getFloat16(dataView, offset + 2);
263
+ z += getFloat16(dataView, offset + 4);
264
+ result.push({ x, y, z });
265
+ }
266
+ return result;
201
267
  }
202
268
  /**
203
- * Get the first point from a base64-encoded string of points.
269
+ * Get the first point from a delta-encoded base64 string.
270
+ * The first point is stored as Float32 for full precision.
204
271
  *
205
- * @param b64Points - The base64-encoded string containing point data
272
+ * @param b64Points - The delta-encoded base64 string
206
273
  * @returns The first point as a VecModel, or null if the string is too short
207
274
  * @public
208
275
  */
209
276
  static decodeFirstPoint(b64Points) {
210
- if (b64Points.length < POINT_B64_LENGTH) return null;
211
- return b64Vecs.decodePointAt(b64Points, 0);
277
+ if (b64Points.length < FIRST_POINT_B64_LENGTH) return null;
278
+ const bytes = base64ToUint8Array(b64Points.slice(0, FIRST_POINT_B64_LENGTH));
279
+ const dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
280
+ return {
281
+ x: dataView.getFloat32(0, true),
282
+ y: dataView.getFloat32(4, true),
283
+ z: dataView.getFloat32(8, true)
284
+ };
212
285
  }
213
286
  /**
214
- * Get the last point from a base64-encoded string of points.
287
+ * Get the last point from a delta-encoded base64 string.
288
+ * Requires decoding all points to accumulate deltas.
215
289
  *
216
- * @param b64Points - The base64-encoded string containing point data
290
+ * @param b64Points - The delta-encoded base64 string
217
291
  * @returns The last point as a VecModel, or null if the string is too short
292
+ * @public
218
293
  */
219
294
  static decodeLastPoint(b64Points) {
220
- if (b64Points.length < POINT_B64_LENGTH) return null;
221
- return b64Vecs.decodePointAt(b64Points, b64Points.length - POINT_B64_LENGTH);
295
+ if (b64Points.length < FIRST_POINT_B64_LENGTH) return null;
296
+ const bytes = base64ToUint8Array(b64Points);
297
+ const dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
298
+ let x = dataView.getFloat32(0, true);
299
+ let y = dataView.getFloat32(4, true);
300
+ let z = dataView.getFloat32(8, true);
301
+ const firstPointBytes = 12;
302
+ for (let offset = firstPointBytes; offset < bytes.length; offset += 6) {
303
+ x += getFloat16(dataView, offset);
304
+ y += getFloat16(dataView, offset + 2);
305
+ z += getFloat16(dataView, offset + 4);
306
+ }
307
+ return { x, y, z };
222
308
  }
223
309
  }
224
310
  //# sourceMappingURL=b64Vecs.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/misc/b64Vecs.ts"],
4
- "sourcesContent": ["import { VecModel } from './geometry-types'\n\n// Each point = 3 Float16s = 6 bytes = 8 base64 chars\nconst POINT_B64_LENGTH = 8\n\n// O(1) lookup table for base64 decoding (maps char code -> 6-bit value)\nconst BASE64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nconst B64_LOOKUP = new Uint8Array(128)\nfor (let i = 0; i < 64; i++) {\n\tB64_LOOKUP[BASE64_CHARS.charCodeAt(i)] = i\n}\n\n// Precomputed powers of 2 for Float16 exponents (exp - 15, so indices 0-30 map to 2^-15 to 2^15)\nconst POW2 = new Float64Array(31)\nfor (let i = 0; i < 31; i++) {\n\tPOW2[i] = Math.pow(2, i - 15)\n}\nconst POW2_SUBNORMAL = Math.pow(2, -14) / 1024 // For subnormal numbers\n\n// Precomputed mantissa values: 1 + frac/1024 for all 1024 possible frac values\n// Avoids division in hot path\nconst MANTISSA = new Float64Array(1024)\nfor (let i = 0; i < 1024; i++) {\n\tMANTISSA[i] = 1 + i / 1024\n}\n\n/**\n * Convert a Uint16Array (containing Float16 bits) to base64.\n * Processes bytes in groups of 3 to produce 4 base64 characters.\n *\n * @internal\n */\nfunction uint16ArrayToBase64(uint16Array: Uint16Array): string {\n\tconst uint8Array = new Uint8Array(\n\t\tuint16Array.buffer,\n\t\tuint16Array.byteOffset,\n\t\tuint16Array.byteLength\n\t)\n\tlet result = ''\n\n\t// Process bytes in groups of 3 -> 4 base64 chars\n\tfor (let i = 0; i < uint8Array.length; i += 3) {\n\t\tconst byte1 = uint8Array[i]\n\t\tconst byte2 = uint8Array[i + 1] // Always exists for our use case (multiple of 6 bytes)\n\t\tconst byte3 = uint8Array[i + 2]\n\n\t\tconst bitmap = (byte1 << 16) | (byte2 << 8) | byte3\n\t\tresult +=\n\t\t\tBASE64_CHARS[(bitmap >> 18) & 63] +\n\t\t\tBASE64_CHARS[(bitmap >> 12) & 63] +\n\t\t\tBASE64_CHARS[(bitmap >> 6) & 63] +\n\t\t\tBASE64_CHARS[bitmap & 63]\n\t}\n\n\treturn result\n}\n\n/**\n * Convert a base64 string to Uint16Array containing Float16 bits.\n * The base64 string must have a length that is a multiple of 4.\n *\n * @param base64 - The base64-encoded string to decode\n * @returns A Uint16Array containing the decoded Float16 bit values\n * @public\n */\nfunction base64ToUint16Array(base64: string): Uint16Array {\n\t// Calculate exact number of bytes (4 base64 chars = 3 bytes)\n\tconst numBytes = Math.floor((base64.length * 3) / 4)\n\tconst bytes = new Uint8Array(numBytes)\n\tlet byteIndex = 0\n\n\t// Process in groups of 4 base64 characters\n\tfor (let i = 0; i < base64.length; i += 4) {\n\t\tconst c0 = B64_LOOKUP[base64.charCodeAt(i)]\n\t\tconst c1 = B64_LOOKUP[base64.charCodeAt(i + 1)]\n\t\tconst c2 = B64_LOOKUP[base64.charCodeAt(i + 2)]\n\t\tconst c3 = B64_LOOKUP[base64.charCodeAt(i + 3)]\n\n\t\tconst bitmap = (c0 << 18) | (c1 << 12) | (c2 << 6) | c3\n\n\t\tbytes[byteIndex++] = (bitmap >> 16) & 255\n\t\tbytes[byteIndex++] = (bitmap >> 8) & 255\n\t\tbytes[byteIndex++] = bitmap & 255\n\t}\n\n\treturn new Uint16Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 2)\n}\n\n/**\n * Convert Float16 bits to a number using optimized lookup tables.\n * Handles normal numbers, subnormal numbers, zero, infinity, and NaN.\n *\n * @param bits - The 16-bit Float16 value to decode\n * @returns The decoded number value\n */\nfunction float16BitsToNumber(bits: number): number {\n\tconst sign = bits >> 15\n\tconst exp = (bits >> 10) & 0x1f\n\tconst frac = bits & 0x3ff\n\n\tif (exp === 0) {\n\t\t// Subnormal or zero - rare case\n\t\treturn sign ? -frac * POW2_SUBNORMAL : frac * POW2_SUBNORMAL\n\t}\n\tif (exp === 31) {\n\t\t// Infinity or NaN - very rare\n\t\treturn frac ? NaN : sign ? -Infinity : Infinity\n\t}\n\t// Normal case - two table lookups, one multiply, no division\n\tconst magnitude = POW2[exp] * MANTISSA[frac]\n\treturn sign ? -magnitude : magnitude\n}\n\n/**\n * Convert a number to Float16 bits.\n * Handles normal numbers, subnormal numbers, zero, infinity, and NaN.\n *\n * @param value - The number to encode as Float16\n * @returns The 16-bit Float16 representation of the number\n * @internal\n */\nfunction numberToFloat16Bits(value: number): number {\n\tif (value === 0) return Object.is(value, -0) ? 0x8000 : 0\n\tif (!Number.isFinite(value)) {\n\t\tif (Number.isNaN(value)) return 0x7e00\n\t\treturn value > 0 ? 0x7c00 : 0xfc00\n\t}\n\n\tconst sign = value < 0 ? 1 : 0\n\tvalue = Math.abs(value)\n\n\t// Find exponent and mantissa\n\tconst exp = Math.floor(Math.log2(value))\n\tlet expBiased = exp + 15\n\n\tif (expBiased >= 31) {\n\t\t// Overflow to infinity\n\t\treturn (sign << 15) | 0x7c00\n\t}\n\tif (expBiased <= 0) {\n\t\t// Subnormal or underflow\n\t\tconst frac = Math.round(value * Math.pow(2, 14) * 1024)\n\t\treturn (sign << 15) | (frac & 0x3ff)\n\t}\n\n\t// Normal number\n\tconst mantissa = value / Math.pow(2, exp) - 1\n\tlet frac = Math.round(mantissa * 1024)\n\n\t// Handle rounding overflow: if frac rounds to 1024, increment exponent\n\tif (frac >= 1024) {\n\t\tfrac = 0\n\t\texpBiased++\n\t\tif (expBiased >= 31) {\n\t\t\t// Overflow to infinity\n\t\t\treturn (sign << 15) | 0x7c00\n\t\t}\n\t}\n\n\treturn (sign << 15) | (expBiased << 10) | frac\n}\n\n/**\n * Utilities for encoding and decoding points using base64 and Float16 encoding.\n * Provides functions for converting between VecModel arrays and compact base64 strings,\n * as well as individual point encoding/decoding operations.\n *\n * @public\n */\nexport class b64Vecs {\n\t/**\n\t * Encode a single point (x, y, z) to 8 base64 characters.\n\t * Each coordinate is encoded as a Float16 value, resulting in 6 bytes total.\n\t *\n\t * @param x - The x coordinate\n\t * @param y - The y coordinate\n\t * @param z - The z coordinate\n\t * @returns An 8-character base64 string representing the point\n\t */\n\tstatic encodePoint(x: number, y: number, z: number): string {\n\t\tconst xBits = numberToFloat16Bits(x)\n\t\tconst yBits = numberToFloat16Bits(y)\n\t\tconst zBits = numberToFloat16Bits(z)\n\n\t\t// Convert Float16 bits to 6 bytes (little-endian)\n\t\tconst b0 = xBits & 0xff\n\t\tconst b1 = (xBits >> 8) & 0xff\n\t\tconst b2 = yBits & 0xff\n\t\tconst b3 = (yBits >> 8) & 0xff\n\t\tconst b4 = zBits & 0xff\n\t\tconst b5 = (zBits >> 8) & 0xff\n\n\t\t// Convert 6 bytes to 8 base64 chars\n\t\tconst bitmap1 = (b0 << 16) | (b1 << 8) | b2\n\t\tconst bitmap2 = (b3 << 16) | (b4 << 8) | b5\n\n\t\treturn (\n\t\t\tBASE64_CHARS[(bitmap1 >> 18) & 0x3f] +\n\t\t\tBASE64_CHARS[(bitmap1 >> 12) & 0x3f] +\n\t\t\tBASE64_CHARS[(bitmap1 >> 6) & 0x3f] +\n\t\t\tBASE64_CHARS[bitmap1 & 0x3f] +\n\t\t\tBASE64_CHARS[(bitmap2 >> 18) & 0x3f] +\n\t\t\tBASE64_CHARS[(bitmap2 >> 12) & 0x3f] +\n\t\t\tBASE64_CHARS[(bitmap2 >> 6) & 0x3f] +\n\t\t\tBASE64_CHARS[bitmap2 & 0x3f]\n\t\t)\n\t}\n\n\t/**\n\t * Convert an array of VecModels to a base64 string for compact storage.\n\t * Uses Float16 encoding for each coordinate (x, y, z). If a point's z value is\n\t * undefined, it defaults to 0.5.\n\t *\n\t * @param points - An array of VecModel objects to encode\n\t * @returns A base64-encoded string containing all points\n\t */\n\tstatic encodePoints(points: VecModel[]): string {\n\t\tconst uint16s = new Uint16Array(points.length * 3)\n\t\tfor (let i = 0; i < points.length; i++) {\n\t\t\tconst p = points[i]\n\t\t\tuint16s[i * 3] = numberToFloat16Bits(p.x)\n\t\t\tuint16s[i * 3 + 1] = numberToFloat16Bits(p.y)\n\t\t\tuint16s[i * 3 + 2] = numberToFloat16Bits(p.z ?? 0.5)\n\t\t}\n\t\treturn uint16ArrayToBase64(uint16s)\n\t}\n\n\t/**\n\t * Convert a base64 string back to an array of VecModels.\n\t * Decodes Float16-encoded coordinates (x, y, z) from the base64 string.\n\t *\n\t * @param base64 - The base64-encoded string containing point data\n\t * @returns An array of VecModel objects decoded from the string\n\t */\n\tstatic decodePoints(base64: string): VecModel[] {\n\t\tconst uint16s = base64ToUint16Array(base64)\n\t\tconst result: VecModel[] = []\n\t\tfor (let i = 0; i < uint16s.length; i += 3) {\n\t\t\tresult.push({\n\t\t\t\tx: float16BitsToNumber(uint16s[i]),\n\t\t\t\ty: float16BitsToNumber(uint16s[i + 1]),\n\t\t\t\tz: float16BitsToNumber(uint16s[i + 2]),\n\t\t\t})\n\t\t}\n\t\treturn result\n\t}\n\n\t/**\n\t * Decode a single point (8 base64 chars) starting at the given offset.\n\t * Each point is encoded as 3 Float16 values (x, y, z) in 8 base64 characters.\n\t *\n\t * @param b64Points - The base64-encoded string containing point data\n\t * @param charOffset - The character offset where the point starts (must be a multiple of 8)\n\t * @returns A VecModel object with x, y, and z coordinates\n\t * @internal\n\t */\n\tstatic decodePointAt(b64Points: string, charOffset: number): VecModel {\n\t\t// Decode 8 base64 chars -> 6 bytes -> 3 Float16s using O(1) lookup\n\t\tconst c0 = B64_LOOKUP[b64Points.charCodeAt(charOffset)]\n\t\tconst c1 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 1)]\n\t\tconst c2 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 2)]\n\t\tconst c3 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 3)]\n\t\tconst c4 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 4)]\n\t\tconst c5 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 5)]\n\t\tconst c6 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 6)]\n\t\tconst c7 = B64_LOOKUP[b64Points.charCodeAt(charOffset + 7)]\n\n\t\t// 4 base64 chars -> 24 bits -> 3 bytes\n\t\tconst bitmap1 = (c0 << 18) | (c1 << 12) | (c2 << 6) | c3\n\t\tconst bitmap2 = (c4 << 18) | (c5 << 12) | (c6 << 6) | c7\n\n\t\t// Extract Float16 bits directly (little-endian byte order)\n\t\t// bitmap1 = [byte0:8][byte1:8][byte2:8], bitmap2 = [byte3:8][byte4:8][byte5:8]\n\t\t// xBits = byte0 | (byte1 << 8), yBits = byte2 | (byte3 << 8), zBits = byte4 | (byte5 << 8)\n\t\tconst xBits = ((bitmap1 >> 16) & 0xff) | (bitmap1 & 0xff00)\n\t\tconst yBits = (bitmap1 & 0xff) | ((bitmap2 >> 8) & 0xff00)\n\t\tconst zBits = ((bitmap2 >> 8) & 0xff) | ((bitmap2 << 8) & 0xff00)\n\n\t\treturn {\n\t\t\tx: float16BitsToNumber(xBits),\n\t\t\ty: float16BitsToNumber(yBits),\n\t\t\tz: float16BitsToNumber(zBits),\n\t\t}\n\t}\n\n\t/**\n\t * Get the first point from a base64-encoded string of points.\n\t *\n\t * @param b64Points - The base64-encoded string containing point data\n\t * @returns The first point as a VecModel, or null if the string is too short\n\t * @public\n\t */\n\tstatic decodeFirstPoint(b64Points: string): VecModel | null {\n\t\tif (b64Points.length < POINT_B64_LENGTH) return null\n\t\treturn b64Vecs.decodePointAt(b64Points, 0)\n\t}\n\n\t/**\n\t * Get the last point from a base64-encoded string of points.\n\t *\n\t * @param b64Points - The base64-encoded string containing point data\n\t * @returns The last point as a VecModel, or null if the string is too short\n\t */\n\tstatic decodeLastPoint(b64Points: string): VecModel | null {\n\t\tif (b64Points.length < POINT_B64_LENGTH) return null\n\t\treturn b64Vecs.decodePointAt(b64Points, b64Points.length - POINT_B64_LENGTH)\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { assert } from '@tldraw/utils'\nimport { VecModel } from './geometry-types'\n\n// Each point = 3 Float16s = 6 bytes = 8 base64 chars (legacy format)\nconst _POINT_B64_LENGTH = 8\n\n// First point in delta encoding = 3 Float32s = 12 bytes = 16 base64 chars\nconst FIRST_POINT_B64_LENGTH = 16\n\n// O(1) lookup table for base64 decoding (maps char code -> 6-bit value)\nconst BASE64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nconst B64_LOOKUP = new Uint8Array(128)\nfor (let i = 0; i < 64; i++) {\n\tB64_LOOKUP[BASE64_CHARS.charCodeAt(i)] = i\n}\n\n// Precomputed powers of 2 for Float16 exponents (exp - 15, so indices 0-30 map to 2^-15 to 2^15)\nconst POW2 = new Float64Array(31)\nfor (let i = 0; i < 31; i++) {\n\tPOW2[i] = Math.pow(2, i - 15)\n}\nconst POW2_SUBNORMAL = Math.pow(2, -14) / 1024 // For subnormal numbers\n\n// Precomputed mantissa values: 1 + frac/1024 for all 1024 possible frac values\n// Avoids division in hot path\nconst MANTISSA = new Float64Array(1024)\nfor (let i = 0; i < 1024; i++) {\n\tMANTISSA[i] = 1 + i / 1024\n}\n\ndeclare global {\n\tinterface Uint8Array {\n\t\ttoBase64?(): string\n\t}\n\tinterface Uint8ArrayConstructor {\n\t\tfromBase64?(base64: string): Uint8Array\n\t}\n}\n\nfunction nativeGetFloat16(dataView: DataView, offset: number): number {\n\treturn (dataView as any).getFloat16(offset, true)\n}\nfunction fallbackGetFloat16(dataView: DataView, offset: number): number {\n\treturn float16BitsToNumber(dataView.getUint16(offset, true))\n}\n\nconst getFloat16 =\n\ttypeof (DataView.prototype as any).getFloat16 === 'function'\n\t\t? nativeGetFloat16\n\t\t: fallbackGetFloat16\n\nfunction nativeSetFloat16(dataView: DataView, offset: number, value: number): void {\n\t;(dataView as any).setFloat16(offset, value, true)\n}\nfunction fallbackSetFloat16(dataView: DataView, offset: number, value: number): void {\n\tdataView.setUint16(offset, numberToFloat16Bits(value), true)\n}\n\nconst setFloat16 =\n\ttypeof (DataView.prototype as any).setFloat16 === 'function'\n\t\t? nativeSetFloat16\n\t\t: fallbackSetFloat16\n\nfunction nativeBase64ToUint8Array(base64: string): Uint8Array {\n\treturn Uint8Array.fromBase64!(base64)\n}\n\n/** @internal */\nexport function fallbackBase64ToUint8Array(base64: string): Uint8Array {\n\tconst numBytes = Math.floor((base64.length * 3) / 4)\n\tconst bytes = new Uint8Array(numBytes)\n\tlet byteIndex = 0\n\n\tfor (let i = 0; i < base64.length; i += 4) {\n\t\tconst c0 = B64_LOOKUP[base64.charCodeAt(i)]\n\t\tconst c1 = B64_LOOKUP[base64.charCodeAt(i + 1)]\n\t\tconst c2 = B64_LOOKUP[base64.charCodeAt(i + 2)]\n\t\tconst c3 = B64_LOOKUP[base64.charCodeAt(i + 3)]\n\n\t\tconst bitmap = (c0 << 18) | (c1 << 12) | (c2 << 6) | c3\n\n\t\tbytes[byteIndex++] = (bitmap >> 16) & 255\n\t\tbytes[byteIndex++] = (bitmap >> 8) & 255\n\t\tbytes[byteIndex++] = bitmap & 255\n\t}\n\n\treturn bytes\n}\n\nfunction nativeUint8ArrayToBase64(uint8Array: Uint8Array): string {\n\treturn uint8Array.toBase64!()\n}\n\n/** @internal */\nexport function fallbackUint8ArrayToBase64(uint8Array: Uint8Array): string {\n\tassert(uint8Array.length % 3 === 0, 'Uint8Array length must be a multiple of 3')\n\tlet result = ''\n\n\t// Process bytes in groups of 3 -> 4 base64 chars\n\tfor (let i = 0; i < uint8Array.length; i += 3) {\n\t\tconst byte1 = uint8Array[i]\n\t\tconst byte2 = uint8Array[i + 1]\n\t\tconst byte3 = uint8Array[i + 2]\n\n\t\tconst bitmap = (byte1 << 16) | (byte2 << 8) | byte3\n\t\tresult +=\n\t\t\tBASE64_CHARS[(bitmap >> 18) & 63] +\n\t\t\tBASE64_CHARS[(bitmap >> 12) & 63] +\n\t\t\tBASE64_CHARS[(bitmap >> 6) & 63] +\n\t\t\tBASE64_CHARS[bitmap & 63]\n\t}\n\n\treturn result\n}\n\n/**\n * Convert a Uint8Array to base64.\n * Processes bytes in groups of 3 to produce 4 base64 characters.\n *\n * @internal\n */\nconst uint8ArrayToBase64 =\n\ttypeof Uint8Array.prototype.toBase64 === 'function'\n\t\t? nativeUint8ArrayToBase64\n\t\t: fallbackUint8ArrayToBase64\n\n/**\n * Convert a base64 string to Uint8Array.\n *\n * @internal\n */\nconst base64ToUint8Array =\n\ttypeof Uint8Array.fromBase64 === 'function'\n\t\t? nativeBase64ToUint8Array\n\t\t: fallbackBase64ToUint8Array\n\n/**\n * Convert Float16 bits to a number using optimized lookup tables.\n * Handles normal numbers, subnormal numbers, zero, infinity, and NaN.\n *\n * @param bits - The 16-bit Float16 value to decode\n * @returns The decoded number value\n * @internal\n */\nexport function float16BitsToNumber(bits: number): number {\n\tconst sign = bits >> 15\n\tconst exp = (bits >> 10) & 0x1f\n\tconst frac = bits & 0x3ff\n\n\tif (exp === 0) {\n\t\t// Subnormal or zero - rare case\n\t\treturn sign ? -frac * POW2_SUBNORMAL : frac * POW2_SUBNORMAL\n\t}\n\tif (exp === 31) {\n\t\t// Infinity or NaN - very rare\n\t\treturn frac ? NaN : sign ? -Infinity : Infinity\n\t}\n\t// Normal case - two table lookups, one multiply, no division\n\tconst magnitude = POW2[exp] * MANTISSA[frac]\n\treturn sign ? -magnitude : magnitude\n}\n\n/**\n * Convert a number to Float16 bits.\n * Handles normal numbers, subnormal numbers, zero, infinity, and NaN.\n *\n * @param value - The number to encode as Float16\n * @returns The 16-bit Float16 representation of the number\n * @internal\n */\nexport function numberToFloat16Bits(value: number): number {\n\tif (value === 0) return Object.is(value, -0) ? 0x8000 : 0\n\tif (!Number.isFinite(value)) {\n\t\tif (Number.isNaN(value)) return 0x7e00\n\t\treturn value > 0 ? 0x7c00 : 0xfc00\n\t}\n\n\tconst sign = value < 0 ? 1 : 0\n\tvalue = Math.abs(value)\n\n\t// Find exponent and mantissa\n\tconst exp = Math.floor(Math.log2(value))\n\tlet expBiased = exp + 15\n\n\tif (expBiased >= 31) {\n\t\t// Overflow to infinity\n\t\treturn (sign << 15) | 0x7c00\n\t}\n\tif (expBiased <= 0) {\n\t\t// Subnormal or underflow\n\t\tconst frac = Math.round(value * Math.pow(2, 14) * 1024)\n\t\treturn (sign << 15) | (frac & 0x3ff)\n\t}\n\n\t// Normal number\n\tconst mantissa = value / Math.pow(2, exp) - 1\n\tlet frac = Math.round(mantissa * 1024)\n\n\t// Handle rounding overflow: if frac rounds to 1024, increment exponent\n\tif (frac >= 1024) {\n\t\tfrac = 0\n\t\texpBiased++\n\t\tif (expBiased >= 31) {\n\t\t\t// Overflow to infinity\n\t\t\treturn (sign << 15) | 0x7c00\n\t\t}\n\t}\n\n\treturn (sign << 15) | (expBiased << 10) | frac\n}\n\n/**\n * Utilities for encoding and decoding points using base64 and Float16 encoding.\n * Provides functions for converting between VecModel arrays and compact base64 strings,\n * as well as individual point encoding/decoding operations.\n *\n * @public\n */\nexport class b64Vecs {\n\t/**\n\t * Encode a single point (x, y, z) to 8 base64 characters using legacy Float16 encoding.\n\t * Each coordinate is encoded as a Float16 value, resulting in 6 bytes total.\n\t *\n\t * @param x - The x coordinate\n\t * @param y - The y coordinate\n\t * @param z - The z coordinate\n\t * @returns An 8-character base64 string representing the point\n\t * @internal\n\t */\n\tstatic _legacyEncodePoint(x: number, y: number, z: number): string {\n\t\tconst buffer = new Uint8Array(6)\n\t\tconst dataView = new DataView(buffer.buffer)\n\n\t\tsetFloat16(dataView, 0, x)\n\t\tsetFloat16(dataView, 2, y)\n\t\tsetFloat16(dataView, 4, z)\n\n\t\treturn uint8ArrayToBase64(buffer)\n\t}\n\n\t/**\n\t * Convert an array of VecModels to a base64 string using legacy Float16 encoding.\n\t * Uses Float16 encoding for each coordinate (x, y, z). If a point's z value is\n\t * undefined, it defaults to 0.5.\n\t *\n\t * @param points - An array of VecModel objects to encode\n\t * @returns A base64-encoded string containing all points\n\t * @internal Used only for migrations from legacy format\n\t */\n\tstatic _legacyEncodePoints(points: VecModel[]): string {\n\t\tif (points.length === 0) return ''\n\n\t\t// 3 Float16s per point = 6 bytes per point\n\t\tconst buffer = new Uint8Array(points.length * 6)\n\t\tconst dataView = new DataView(buffer.buffer)\n\n\t\tfor (let i = 0; i < points.length; i++) {\n\t\t\tconst p = points[i]\n\t\t\tconst offset = i * 6\n\t\t\tsetFloat16(dataView, offset, p.x)\n\t\t\tsetFloat16(dataView, offset + 2, p.y)\n\t\t\tsetFloat16(dataView, offset + 4, p.z ?? 0.5)\n\t\t}\n\n\t\treturn uint8ArrayToBase64(buffer)\n\t}\n\n\t/**\n\t * Convert a legacy base64 string back to an array of VecModels.\n\t * Decodes Float16-encoded coordinates (x, y, z) from the base64 string.\n\t *\n\t * @param base64 - The base64-encoded string containing point data\n\t * @returns An array of VecModel objects decoded from the string\n\t * @internal Used only for migrations from legacy format\n\t */\n\tstatic _legacyDecodePoints(base64: string): VecModel[] {\n\t\tconst bytes = base64ToUint8Array(base64)\n\t\tconst dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)\n\t\tconst result: VecModel[] = []\n\t\tfor (let offset = 0; offset < bytes.length; offset += 6) {\n\t\t\tresult.push({\n\t\t\t\tx: getFloat16(dataView, offset),\n\t\t\t\ty: getFloat16(dataView, offset + 2),\n\t\t\t\tz: getFloat16(dataView, offset + 4),\n\t\t\t})\n\t\t}\n\t\treturn result\n\t}\n\n\t/**\n\t * Encode an array of VecModels using delta encoding for improved precision.\n\t * The first point is stored as Float32 (high precision for absolute position),\n\t * subsequent points are stored as Float16 deltas from the previous point.\n\t * This provides full precision for the starting position and excellent precision\n\t * for deltas between consecutive points (which are typically small values).\n\t *\n\t * Format:\n\t * - First point: 3 Float32 values = 12 bytes = 16 base64 chars\n\t * - Delta points: 3 Float16 values each = 6 bytes = 8 base64 chars each\n\t *\n\t * @param points - An array of VecModel objects to encode\n\t * @returns A base64-encoded string containing delta-encoded points\n\t * @public\n\t */\n\tstatic encodePoints(points: VecModel[]): string {\n\t\tif (points.length === 0) return ''\n\n\t\t// First point: 3 Float32s = 12 bytes\n\t\t// Remaining points: 3 Float16s each = 6 bytes each\n\t\tconst firstPointBytes = 12\n\t\tconst deltaBytes = (points.length - 1) * 6\n\t\tconst totalBytes = firstPointBytes + deltaBytes\n\n\t\tconst buffer = new Uint8Array(totalBytes)\n\t\tconst dataView = new DataView(buffer.buffer)\n\n\t\t// First point is stored as Float32 for full precision\n\t\tconst first = points[0]\n\t\tdataView.setFloat32(0, first.x, true) // little-endian\n\t\tdataView.setFloat32(4, first.y, true)\n\t\tdataView.setFloat32(8, first.z ?? 0.5, true)\n\n\t\t// Subsequent points are Float16 deltas from the previous point\n\t\tlet prevX = first.x\n\t\tlet prevY = first.y\n\t\tlet prevZ = first.z ?? 0.5\n\n\t\tfor (let i = 1; i < points.length; i++) {\n\t\t\tconst p = points[i]\n\t\t\tconst z = p.z ?? 0.5\n\n\t\t\tconst offset = firstPointBytes + (i - 1) * 6\n\t\t\tsetFloat16(dataView, offset, p.x - prevX)\n\t\t\tsetFloat16(dataView, offset + 2, p.y - prevY)\n\t\t\tsetFloat16(dataView, offset + 4, z - prevZ)\n\n\t\t\tprevX = p.x\n\t\t\tprevY = p.y\n\t\t\tprevZ = z\n\t\t}\n\n\t\treturn uint8ArrayToBase64(buffer)\n\t}\n\n\t/**\n\t * Decode a delta-encoded base64 string back to an array of absolute VecModels.\n\t * The first point is stored as Float32 (high precision), subsequent points are\n\t * Float16 deltas that are accumulated to reconstruct absolute positions.\n\t *\n\t * @param base64 - The base64-encoded string containing delta-encoded point data\n\t * @returns An array of VecModel objects with absolute coordinates\n\t * @public\n\t */\n\tstatic decodePoints(base64: string): VecModel[] {\n\t\tif (base64.length === 0) return []\n\n\t\tconst bytes = base64ToUint8Array(base64)\n\t\tconst dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)\n\t\tconst result: VecModel[] = []\n\n\t\t// First point is Float32 (12 bytes)\n\t\tlet x = dataView.getFloat32(0, true)\n\t\tlet y = dataView.getFloat32(4, true)\n\t\tlet z = dataView.getFloat32(8, true)\n\t\tresult.push({ x, y, z })\n\n\t\t// Subsequent points are Float16 deltas - accumulate to get absolute positions\n\t\tconst firstPointBytes = 12\n\t\tfor (let offset = firstPointBytes; offset < bytes.length; offset += 6) {\n\t\t\tx += getFloat16(dataView, offset)\n\t\t\ty += getFloat16(dataView, offset + 2)\n\t\t\tz += getFloat16(dataView, offset + 4)\n\t\t\tresult.push({ x, y, z })\n\t\t}\n\n\t\treturn result\n\t}\n\n\t/**\n\t * Get the first point from a delta-encoded base64 string.\n\t * The first point is stored as Float32 for full precision.\n\t *\n\t * @param b64Points - The delta-encoded base64 string\n\t * @returns The first point as a VecModel, or null if the string is too short\n\t * @public\n\t */\n\tstatic decodeFirstPoint(b64Points: string): VecModel | null {\n\t\t// First point needs 16 base64 chars (12 bytes as Float32)\n\t\tif (b64Points.length < FIRST_POINT_B64_LENGTH) return null\n\n\t\tconst bytes = base64ToUint8Array(b64Points.slice(0, FIRST_POINT_B64_LENGTH))\n\t\tconst dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)\n\n\t\treturn {\n\t\t\tx: dataView.getFloat32(0, true),\n\t\t\ty: dataView.getFloat32(4, true),\n\t\t\tz: dataView.getFloat32(8, true),\n\t\t}\n\t}\n\n\t/**\n\t * Get the last point from a delta-encoded base64 string.\n\t * Requires decoding all points to accumulate deltas.\n\t *\n\t * @param b64Points - The delta-encoded base64 string\n\t * @returns The last point as a VecModel, or null if the string is too short\n\t * @public\n\t */\n\tstatic decodeLastPoint(b64Points: string): VecModel | null {\n\t\tif (b64Points.length < FIRST_POINT_B64_LENGTH) return null\n\n\t\tconst bytes = base64ToUint8Array(b64Points)\n\t\tconst dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)\n\n\t\t// Start with first point (Float32)\n\t\tlet x = dataView.getFloat32(0, true)\n\t\tlet y = dataView.getFloat32(4, true)\n\t\tlet z = dataView.getFloat32(8, true)\n\n\t\t// Accumulate all Float16 deltas to get the last point\n\t\tconst firstPointBytes = 12\n\t\tfor (let offset = firstPointBytes; offset < bytes.length; offset += 6) {\n\t\t\tx += getFloat16(dataView, offset)\n\t\t\ty += getFloat16(dataView, offset + 2)\n\t\t\tz += getFloat16(dataView, offset + 4)\n\t\t}\n\n\t\treturn { x, y, z }\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["frac"]
7
7
  }
@@ -34,7 +34,7 @@ var import_TLFillStyle = require("../styles/TLFillStyle");
34
34
  var import_TLSizeStyle = require("../styles/TLSizeStyle");
35
35
  const DrawShapeSegment = import_validate.T.object({
36
36
  type: import_validate.T.literalEnum("free", "straight"),
37
- points: import_validate.T.string
37
+ path: import_validate.T.string
38
38
  });
39
39
  const drawShapeProps = {
40
40
  color: import_TLColorStyle.DefaultColorStyle,
@@ -52,7 +52,8 @@ const drawShapeProps = {
52
52
  const Versions = (0, import_TLShape.createShapePropsMigrationIds)("draw", {
53
53
  AddInPen: 1,
54
54
  AddScale: 2,
55
- Base64: 3
55
+ Base64: 3,
56
+ LegacyPointsConversion: 4
56
57
  });
57
58
  const drawShapeMigrations = (0, import_TLShape.createShapePropsMigrationSequence)({
58
59
  sequence: [
@@ -85,31 +86,51 @@ const drawShapeMigrations = (0, import_TLShape.createShapePropsMigrationSequence
85
86
  id: Versions.Base64,
86
87
  up: (props) => {
87
88
  props.segments = props.segments.map((segment) => {
89
+ if (segment.path !== void 0) return segment;
90
+ const { points, ...rest } = segment;
91
+ const vecModels = Array.isArray(points) ? points : import_b64Vecs.b64Vecs._legacyDecodePoints(points);
88
92
  return {
89
- ...segment,
90
- // Only encode if points is an array (not already base64 string)
91
- points: typeof segment.points === "string" ? segment.points : import_b64Vecs.b64Vecs.encodePoints(segment.points)
93
+ ...rest,
94
+ path: import_b64Vecs.b64Vecs.encodePoints(vecModels)
92
95
  };
93
96
  });
94
97
  props.scaleX = props.scaleX ?? 1;
95
98
  props.scaleY = props.scaleY ?? 1;
96
99
  },
97
100
  down: (props) => {
98
- props.segments = props.segments.map((segment) => ({
99
- ...segment,
100
- // Only decode if points is a string (not already VecModel[])
101
- points: Array.isArray(segment.points) ? segment.points : import_b64Vecs.b64Vecs.decodePoints(segment.points)
102
- }));
101
+ props.segments = props.segments.map((segment) => {
102
+ const { path, ...rest } = segment;
103
+ return {
104
+ ...rest,
105
+ points: import_b64Vecs.b64Vecs.decodePoints(path)
106
+ };
107
+ });
103
108
  delete props.scaleX;
104
109
  delete props.scaleY;
105
110
  }
111
+ },
112
+ {
113
+ id: Versions.LegacyPointsConversion,
114
+ up: (props) => {
115
+ props.segments = props.segments.map((segment) => {
116
+ if (segment.path !== void 0) return segment;
117
+ const { points, ...rest } = segment;
118
+ const vecModels = Array.isArray(points) ? points : import_b64Vecs.b64Vecs._legacyDecodePoints(points);
119
+ return {
120
+ ...rest,
121
+ path: import_b64Vecs.b64Vecs.encodePoints(vecModels)
122
+ };
123
+ });
124
+ },
125
+ down: (_props) => {
126
+ }
106
127
  }
107
128
  ]
108
129
  });
109
130
  function compressLegacySegments(segments) {
110
131
  return segments.map((segment) => ({
111
- ...segment,
112
- points: import_b64Vecs.b64Vecs.encodePoints(segment.points)
132
+ type: segment.type,
133
+ path: import_b64Vecs.b64Vecs.encodePoints(segment.points)
113
134
  }));
114
135
  }
115
136
  //# sourceMappingURL=TLDrawShape.js.map