codeboard-studio 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +23 -0
  3. package/README.md +54 -0
  4. package/dist/src/animation/camera-plane.d.ts +8 -0
  5. package/dist/src/animation/camera-plane.d.ts.map +1 -0
  6. package/dist/src/animation/camera-plane.js +16 -0
  7. package/dist/src/animation/camera-plane.js.map +1 -0
  8. package/dist/src/animation/drawing-neighbors.d.ts +4 -0
  9. package/dist/src/animation/drawing-neighbors.d.ts.map +1 -0
  10. package/dist/src/animation/drawing-neighbors.js +38 -0
  11. package/dist/src/animation/drawing-neighbors.js.map +1 -0
  12. package/dist/src/animation/evaluate.d.ts +17 -0
  13. package/dist/src/animation/evaluate.d.ts.map +1 -0
  14. package/dist/src/animation/evaluate.js +70 -0
  15. package/dist/src/animation/evaluate.js.map +1 -0
  16. package/dist/src/animation/frame.d.ts +8 -0
  17. package/dist/src/animation/frame.d.ts.map +1 -0
  18. package/dist/src/animation/frame.js +16 -0
  19. package/dist/src/animation/frame.js.map +1 -0
  20. package/dist/src/animation/ik.d.ts +26 -0
  21. package/dist/src/animation/ik.d.ts.map +1 -0
  22. package/dist/src/animation/ik.js +47 -0
  23. package/dist/src/animation/ik.js.map +1 -0
  24. package/dist/src/animation/retime.d.ts +4 -0
  25. package/dist/src/animation/retime.d.ts.map +1 -0
  26. package/dist/src/animation/retime.js +116 -0
  27. package/dist/src/animation/retime.js.map +1 -0
  28. package/dist/src/audio/wav.d.ts +11 -0
  29. package/dist/src/audio/wav.d.ts.map +1 -0
  30. package/dist/src/audio/wav.js +58 -0
  31. package/dist/src/audio/wav.js.map +1 -0
  32. package/dist/src/authoring-runner.d.ts +2 -0
  33. package/dist/src/authoring-runner.d.ts.map +1 -0
  34. package/dist/src/authoring-runner.js +24 -0
  35. package/dist/src/authoring-runner.js.map +1 -0
  36. package/dist/src/cli.d.ts +3 -0
  37. package/dist/src/cli.d.ts.map +1 -0
  38. package/dist/src/cli.js +127 -0
  39. package/dist/src/cli.js.map +1 -0
  40. package/dist/src/core/coordinates.d.ts +16 -0
  41. package/dist/src/core/coordinates.d.ts.map +1 -0
  42. package/dist/src/core/coordinates.js +48 -0
  43. package/dist/src/core/coordinates.js.map +1 -0
  44. package/dist/src/core/handles.d.ts +93 -0
  45. package/dist/src/core/handles.d.ts.map +1 -0
  46. package/dist/src/core/handles.js +190 -0
  47. package/dist/src/core/handles.js.map +1 -0
  48. package/dist/src/core/history.d.ts +14 -0
  49. package/dist/src/core/history.d.ts.map +1 -0
  50. package/dist/src/core/history.js +80 -0
  51. package/dist/src/core/history.js.map +1 -0
  52. package/dist/src/core/inspection.d.ts +51 -0
  53. package/dist/src/core/inspection.d.ts.map +1 -0
  54. package/dist/src/core/inspection.js +72 -0
  55. package/dist/src/core/inspection.js.map +1 -0
  56. package/dist/src/core/production.d.ts +208 -0
  57. package/dist/src/core/production.d.ts.map +1 -0
  58. package/dist/src/core/production.js +894 -0
  59. package/dist/src/core/production.js.map +1 -0
  60. package/dist/src/core/project.d.ts +146 -0
  61. package/dist/src/core/project.d.ts.map +1 -0
  62. package/dist/src/core/project.js +700 -0
  63. package/dist/src/core/project.js.map +1 -0
  64. package/dist/src/drawing/brush-authoring.d.ts +6 -0
  65. package/dist/src/drawing/brush-authoring.d.ts.map +1 -0
  66. package/dist/src/drawing/brush-authoring.js +12 -0
  67. package/dist/src/drawing/brush-authoring.js.map +1 -0
  68. package/dist/src/drawing/brushes.d.ts +157 -0
  69. package/dist/src/drawing/brushes.d.ts.map +1 -0
  70. package/dist/src/drawing/brushes.js +50 -0
  71. package/dist/src/drawing/brushes.js.map +1 -0
  72. package/dist/src/drawing/color.d.ts +5 -0
  73. package/dist/src/drawing/color.d.ts.map +1 -0
  74. package/dist/src/drawing/color.js +63 -0
  75. package/dist/src/drawing/color.js.map +1 -0
  76. package/dist/src/drawing/curves.d.ts +27 -0
  77. package/dist/src/drawing/curves.d.ts.map +1 -0
  78. package/dist/src/drawing/curves.js +170 -0
  79. package/dist/src/drawing/curves.js.map +1 -0
  80. package/dist/src/drawing/math.d.ts +10 -0
  81. package/dist/src/drawing/math.d.ts.map +1 -0
  82. package/dist/src/drawing/math.js +40 -0
  83. package/dist/src/drawing/math.js.map +1 -0
  84. package/dist/src/drawing/path-geometry.d.ts +18 -0
  85. package/dist/src/drawing/path-geometry.d.ts.map +1 -0
  86. package/dist/src/drawing/path-geometry.js +115 -0
  87. package/dist/src/drawing/path-geometry.js.map +1 -0
  88. package/dist/src/drawing/path-sampling.d.ts +10 -0
  89. package/dist/src/drawing/path-sampling.d.ts.map +1 -0
  90. package/dist/src/drawing/path-sampling.js +64 -0
  91. package/dist/src/drawing/path-sampling.js.map +1 -0
  92. package/dist/src/drawing/path.d.ts +4 -0
  93. package/dist/src/drawing/path.d.ts.map +1 -0
  94. package/dist/src/drawing/path.js +27 -0
  95. package/dist/src/drawing/path.js.map +1 -0
  96. package/dist/src/drawing/pen-input.d.ts +5 -0
  97. package/dist/src/drawing/pen-input.d.ts.map +1 -0
  98. package/dist/src/drawing/pen-input.js +30 -0
  99. package/dist/src/drawing/pen-input.js.map +1 -0
  100. package/dist/src/drawing/pixel-selection.d.ts +23 -0
  101. package/dist/src/drawing/pixel-selection.d.ts.map +1 -0
  102. package/dist/src/drawing/pixel-selection.js +142 -0
  103. package/dist/src/drawing/pixel-selection.js.map +1 -0
  104. package/dist/src/drawing/pixels.d.ts +22 -0
  105. package/dist/src/drawing/pixels.d.ts.map +1 -0
  106. package/dist/src/drawing/pixels.js +79 -0
  107. package/dist/src/drawing/pixels.js.map +1 -0
  108. package/dist/src/drawing/resource-binary.d.ts +23 -0
  109. package/dist/src/drawing/resource-binary.d.ts.map +1 -0
  110. package/dist/src/drawing/resource-binary.js +135 -0
  111. package/dist/src/drawing/resource-binary.js.map +1 -0
  112. package/dist/src/drawing/resources.d.ts +51 -0
  113. package/dist/src/drawing/resources.d.ts.map +1 -0
  114. package/dist/src/drawing/resources.js +239 -0
  115. package/dist/src/drawing/resources.js.map +1 -0
  116. package/dist/src/drawing/stroke-outline.d.ts +5 -0
  117. package/dist/src/drawing/stroke-outline.d.ts.map +1 -0
  118. package/dist/src/drawing/stroke-outline.js +53 -0
  119. package/dist/src/drawing/stroke-outline.js.map +1 -0
  120. package/dist/src/drawing/swatch.d.ts +6 -0
  121. package/dist/src/drawing/swatch.d.ts.map +1 -0
  122. package/dist/src/drawing/swatch.js +15 -0
  123. package/dist/src/drawing/swatch.js.map +1 -0
  124. package/dist/src/export/animatic-export.d.ts +11 -0
  125. package/dist/src/export/animatic-export.d.ts.map +1 -0
  126. package/dist/src/export/animatic-export.js +52 -0
  127. package/dist/src/export/animatic-export.js.map +1 -0
  128. package/dist/src/export/movie-export.d.ts +16 -0
  129. package/dist/src/export/movie-export.d.ts.map +1 -0
  130. package/dist/src/export/movie-export.js +108 -0
  131. package/dist/src/export/movie-export.js.map +1 -0
  132. package/dist/src/export/sheet-layout.d.ts +27 -0
  133. package/dist/src/export/sheet-layout.d.ts.map +1 -0
  134. package/dist/src/export/sheet-layout.js +72 -0
  135. package/dist/src/export/sheet-layout.js.map +1 -0
  136. package/dist/src/export/storyboard-export.d.ts +8 -0
  137. package/dist/src/export/storyboard-export.d.ts.map +1 -0
  138. package/dist/src/export/storyboard-export.js +76 -0
  139. package/dist/src/export/storyboard-export.js.map +1 -0
  140. package/dist/src/index.d.ts +36 -0
  141. package/dist/src/index.d.ts.map +1 -0
  142. package/dist/src/index.js +27 -0
  143. package/dist/src/index.js.map +1 -0
  144. package/dist/src/model/query.d.ts +6 -0
  145. package/dist/src/model/query.d.ts.map +1 -0
  146. package/dist/src/model/query.js +7 -0
  147. package/dist/src/model/query.js.map +1 -0
  148. package/dist/src/model/schema.d.ts +754 -0
  149. package/dist/src/model/schema.d.ts.map +1 -0
  150. package/dist/src/model/schema.js +205 -0
  151. package/dist/src/model/schema.js.map +1 -0
  152. package/dist/src/model/types.d.ts +537 -0
  153. package/dist/src/model/types.d.ts.map +1 -0
  154. package/dist/src/model/types.js +8 -0
  155. package/dist/src/model/types.js.map +1 -0
  156. package/dist/src/model/validate.d.ts +12 -0
  157. package/dist/src/model/validate.d.ts.map +1 -0
  158. package/dist/src/model/validate.js +183 -0
  159. package/dist/src/model/validate.js.map +1 -0
  160. package/dist/src/preview/server.d.ts +6 -0
  161. package/dist/src/preview/server.d.ts.map +1 -0
  162. package/dist/src/preview/server.js +71 -0
  163. package/dist/src/preview/server.js.map +1 -0
  164. package/dist/src/render/annotations.d.ts +4 -0
  165. package/dist/src/render/annotations.d.ts.map +1 -0
  166. package/dist/src/render/annotations.js +27 -0
  167. package/dist/src/render/annotations.js.map +1 -0
  168. package/dist/src/render/brush-engine.d.ts +14 -0
  169. package/dist/src/render/brush-engine.d.ts.map +1 -0
  170. package/dist/src/render/brush-engine.js +230 -0
  171. package/dist/src/render/brush-engine.js.map +1 -0
  172. package/dist/src/render/layer-compositor.d.ts +33 -0
  173. package/dist/src/render/layer-compositor.d.ts.map +1 -0
  174. package/dist/src/render/layer-compositor.js +296 -0
  175. package/dist/src/render/layer-compositor.js.map +1 -0
  176. package/dist/src/render/panel-renderer.d.ts +33 -0
  177. package/dist/src/render/panel-renderer.d.ts.map +1 -0
  178. package/dist/src/render/panel-renderer.js +118 -0
  179. package/dist/src/render/panel-renderer.js.map +1 -0
  180. package/dist/src/render/png.d.ts +4 -0
  181. package/dist/src/render/png.d.ts.map +1 -0
  182. package/dist/src/render/png.js +10 -0
  183. package/dist/src/render/png.js.map +1 -0
  184. package/dist/src/render/review.d.ts +42 -0
  185. package/dist/src/render/review.d.ts.map +1 -0
  186. package/dist/src/render/review.js +192 -0
  187. package/dist/src/render/review.js.map +1 -0
  188. package/dist/src/render/vector-renderer.d.ts +5 -0
  189. package/dist/src/render/vector-renderer.d.ts.map +1 -0
  190. package/dist/src/render/vector-renderer.js +98 -0
  191. package/dist/src/render/vector-renderer.js.map +1 -0
  192. package/dist/src/starter.d.ts +2 -0
  193. package/dist/src/starter.d.ts.map +1 -0
  194. package/dist/src/starter.js +23 -0
  195. package/dist/src/starter.js.map +1 -0
  196. package/dist/src/storage/codec.d.ts +20 -0
  197. package/dist/src/storage/codec.d.ts.map +1 -0
  198. package/dist/src/storage/codec.js +203 -0
  199. package/dist/src/storage/codec.js.map +1 -0
  200. package/dist/src/storage/store.d.ts +89 -0
  201. package/dist/src/storage/store.d.ts.map +1 -0
  202. package/dist/src/storage/store.js +392 -0
  203. package/dist/src/storage/store.js.map +1 -0
  204. package/dist/src/updates.d.ts +10 -0
  205. package/dist/src/updates.d.ts.map +1 -0
  206. package/dist/src/updates.js +134 -0
  207. package/dist/src/updates.js.map +1 -0
  208. package/package.json +84 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pixel-selection.js","sourceRoot":"","sources":["../../../src/drawing/pixel-selection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { PixelBuffer, PixelRegion } from "../model/types.js";
2
+ export declare function validateDimensions(width: number, height: number): void;
3
+ export declare function validatePixels(image: PixelBuffer): void;
4
+ export declare function createPixels(width: number, height: number): PixelBuffer;
5
+ export declare function validatePixelRegion(image: PixelBuffer, region: PixelRegion): void;
6
+ export declare function readPixelRegion(image: PixelBuffer, region: PixelRegion): PixelBuffer;
7
+ export declare function writePixelRegion(image: PixelBuffer, x: number, y: number, patch: PixelBuffer): void;
8
+ export declare function decodePixels(bytes: Uint8Array): Promise<PixelBuffer>;
9
+ export declare function encodePixels(image: PixelBuffer): Promise<Buffer>;
10
+ export interface PixelComparison {
11
+ width: number;
12
+ height: number;
13
+ changedPixels: number;
14
+ maxChannelDelta: number;
15
+ meanAbsoluteDelta: number;
16
+ bounds: PixelRegion | null;
17
+ }
18
+ /** Compare visible premultiplied RGBA, ignoring hidden RGB under zero alpha. */
19
+ export declare function comparePixels(before: PixelBuffer, after: PixelBuffer, options?: {
20
+ threshold?: number;
21
+ }): PixelComparison;
22
+ //# sourceMappingURL=pixels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pixels.d.ts","sourceRoot":"","sources":["../../../src/drawing/pixels.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAElE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAGtE;AACD,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAIvD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAIvE;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI,CAIjF;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,GAAG,WAAW,CAQpF;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CAKnG;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAI1E;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAGtE;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAC,MAAM,CAAC;IAAA,MAAM,EAAC,MAAM,CAAC;IAAA,aAAa,EAAC,MAAM,CAAC;IAAA,eAAe,EAAC,MAAM,CAAC;IAAA,iBAAiB,EAAC,MAAM,CAAC;IAAA,MAAM,EAAC,WAAW,GAAC,IAAI,CAAC;CACzH;AAED,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,MAAM,EAAC,WAAW,EAAC,KAAK,EAAC,WAAW,EAAC,OAAO,GAAC;IAAC,SAAS,CAAC,EAAC,MAAM,CAAA;CAAI,GAAE,eAAe,CAejH"}
@@ -0,0 +1,79 @@
1
+ import sharp from "sharp";
2
+ export function validateDimensions(width, height) {
3
+ if (!Number.isSafeInteger(width) || !Number.isSafeInteger(height) || width < 1 || height < 1 || width * height > 32 * 1024 * 1024)
4
+ throw new Error("Pixel surface dimensions must be positive integers within the 32 megapixel render budget");
5
+ }
6
+ export function validatePixels(image) {
7
+ validateDimensions(image.width, image.height);
8
+ if (!(image.pixels instanceof Uint8Array) || image.pixels.length !== image.width * image.height * 4)
9
+ throw new Error("Pixel surface requires exactly width × height × 4 RGBA8 bytes");
10
+ }
11
+ export function createPixels(width, height) {
12
+ // Validate dimensions before allocating user-controlled memory.
13
+ validateDimensions(width, height);
14
+ return { width, height, pixels: new Uint8Array(width * height * 4) };
15
+ }
16
+ export function validatePixelRegion(image, region) {
17
+ validatePixels(image);
18
+ if (![region.x, region.y, region.width, region.height].every(Number.isSafeInteger) || region.x < 0 || region.y < 0 || region.width < 1 || region.height < 1 || region.x + region.width > image.width || region.y + region.height > image.height)
19
+ throw new Error("Pixel region must be an integer rectangle inside the source surface");
20
+ }
21
+ export function readPixelRegion(image, region) {
22
+ validatePixelRegion(image, region);
23
+ const result = createPixels(region.width, region.height);
24
+ for (let row = 0; row < region.height; row++) {
25
+ const start = ((region.y + row) * image.width + region.x) * 4;
26
+ result.pixels.set(image.pixels.subarray(start, start + region.width * 4), row * region.width * 4);
27
+ }
28
+ return result;
29
+ }
30
+ export function writePixelRegion(image, x, y, patch) {
31
+ validatePixels(patch);
32
+ validatePixelRegion(image, { x, y, width: patch.width, height: patch.height });
33
+ const bytes = patch.pixels.slice();
34
+ for (let row = 0; row < patch.height; row++)
35
+ image.pixels.set(bytes.subarray(row * patch.width * 4, (row + 1) * patch.width * 4), ((y + row) * image.width + x) * 4);
36
+ }
37
+ export async function decodePixels(bytes) {
38
+ const { data, info } = await sharp(bytes, { limitInputPixels: 32 * 1024 * 1024 }).toColourspace("srgb").ensureAlpha().raw().toBuffer({ resolveWithObject: true });
39
+ const result = { width: info.width, height: info.height, pixels: new Uint8Array(data) };
40
+ validatePixels(result);
41
+ return result;
42
+ }
43
+ export async function encodePixels(image) {
44
+ validatePixels(image);
45
+ return sharp(image.pixels, { raw: { width: image.width, height: image.height, channels: 4 } }).png().toBuffer();
46
+ }
47
+ /** Compare visible premultiplied RGBA, ignoring hidden RGB under zero alpha. */
48
+ export function comparePixels(before, after, options = {}) {
49
+ validatePixels(before);
50
+ validatePixels(after);
51
+ if (before.width !== after.width || before.height !== after.height)
52
+ throw new Error("Pixel comparison requires matching dimensions");
53
+ const threshold = options.threshold ?? 0;
54
+ if (!Number.isFinite(threshold) || threshold < 0 || threshold > 255)
55
+ throw new Error("Comparison threshold must be between 0 and 255");
56
+ const { width, height } = before;
57
+ let changedPixels = 0, maxChannelDelta = 0, total = 0, left = width, top = height, right = -1, bottom = -1;
58
+ for (let i = 0; i < width * height; i++) {
59
+ const at = i * 4, aa = before.pixels[at + 3], ba = after.pixels[at + 3];
60
+ let difference = Math.abs(aa - ba);
61
+ total += difference;
62
+ for (let c = 0; c < 3; c++) {
63
+ const delta = Math.abs(before.pixels[at + c] * aa / 255 - after.pixels[at + c] * ba / 255);
64
+ total += delta;
65
+ difference = Math.max(difference, delta);
66
+ }
67
+ maxChannelDelta = Math.max(maxChannelDelta, difference);
68
+ if (difference > threshold) {
69
+ const x = i % width, y = Math.floor(i / width);
70
+ changedPixels++;
71
+ left = Math.min(left, x);
72
+ right = Math.max(right, x);
73
+ top = Math.min(top, y);
74
+ bottom = Math.max(bottom, y);
75
+ }
76
+ }
77
+ return { width, height, changedPixels, maxChannelDelta, meanAbsoluteDelta: total / (width * height * 4), bounds: changedPixels ? { x: left, y: top, width: right - left + 1, height: bottom - top + 1 } : null };
78
+ }
79
+ //# sourceMappingURL=pixels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pixels.js","sourceRoot":"","sources":["../../../src/drawing/pixels.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ export interface Sample {
2
+ name: string;
3
+ width: number;
4
+ height: number;
5
+ alpha: Uint8Array;
6
+ spacing?: number;
7
+ }
8
+ export declare class Reader {
9
+ readonly data: Buffer;
10
+ offset: number;
11
+ constructor(data: Buffer);
12
+ take(n: number): Buffer;
13
+ u8(): number;
14
+ u16(): number;
15
+ u32(): number;
16
+ i32(): number;
17
+ }
18
+ export declare function readGBR(r: Reader): Sample;
19
+ export declare function readABR(data: Buffer): {
20
+ samples: Sample[];
21
+ unsupported: string[];
22
+ };
23
+ //# sourceMappingURL=resource-binary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-binary.d.ts","sourceRoot":"","sources":["../../../src/drawing/resource-binary.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,MAAM;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE;AAE5G,qBAAa,MAAM;IAEL,QAAQ,CAAC,IAAI,EAAE,MAAM;IADjC,MAAM,SAAK;gBACU,IAAI,EAAE,MAAM;IACjC,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;IAIvB,EAAE;IACF,GAAG;IACH,GAAG;IACH,GAAG;CACJ;AAMD,wBAAgB,OAAO,CAAC,CAAC,EAAC,MAAM,GAAG,MAAM,CAWxC;AA4BD,wBAAgB,OAAO,CAAC,IAAI,EAAC,MAAM,GAAE;IAAC,OAAO,EAAC,MAAM,EAAE,CAAC;IAAA,WAAW,EAAC,MAAM,EAAE,CAAA;CAAC,CA6B3E"}
@@ -0,0 +1,135 @@
1
+ export class Reader {
2
+ data;
3
+ offset = 0;
4
+ constructor(data) {
5
+ this.data = data;
6
+ }
7
+ take(n) {
8
+ if (!Number.isInteger(n) || n < 0 || this.offset + n > this.data.length)
9
+ throw new Error(`Truncated brush resource at byte ${this.offset} (requested ${n})`);
10
+ const out = this.data.subarray(this.offset, this.offset + n);
11
+ this.offset += n;
12
+ return out;
13
+ }
14
+ u8() { return this.take(1).readUInt8(); }
15
+ u16() { return this.take(2).readUInt16BE(); }
16
+ u32() { return this.take(4).readUInt32BE(); }
17
+ i32() { return this.take(4).readInt32BE(); }
18
+ }
19
+ function dimensions(w, h) {
20
+ if (w < 1 || h < 1 || w > 8192 || h > 8192 || w * h > 16 * 1024 * 1024)
21
+ throw new Error(`Brush dimensions exceed 16 megapixel decode limit: ${w} x ${h}`);
22
+ }
23
+ export function readGBR(r) {
24
+ const start = r.offset, header = r.u32(), version = r.u32(), width = r.u32(), height = r.u32(), channels = r.u32();
25
+ if (version !== 1 && version !== 2)
26
+ throw new Error(`GBR version ${version} is unsupported (only 1 and 2)`);
27
+ dimensions(width, height);
28
+ if (channels !== 1 && channels !== 4)
29
+ throw new Error(`GBR ${channels}-byte color format unsupported`);
30
+ let spacing = .25;
31
+ if (version === 2) {
32
+ if (r.take(4).toString() !== "GIMP")
33
+ throw new Error("Invalid GBR magic");
34
+ spacing = r.u32() / 100;
35
+ }
36
+ const name = r.take(header - (r.offset - start)).toString("utf8").replace(/\0+$/, "");
37
+ const pixels = r.take(width * height * channels);
38
+ const alpha = channels === 1 ? new Uint8Array(pixels) : Uint8Array.from({ length: width * height }, (_, i) => pixels[i * 4 + 3]);
39
+ return { name, width, height, alpha, spacing };
40
+ }
41
+ function sampled(r, name) {
42
+ const top = r.i32(), left = r.i32(), bottom = r.i32(), right = r.i32();
43
+ const width = right - left, height = bottom - top;
44
+ dimensions(width, height);
45
+ const depth = r.u16(), compression = r.u8();
46
+ if (depth !== 8)
47
+ throw new Error(`ABR ${depth}-bit samples are unsupported`);
48
+ let alpha;
49
+ if (compression === 0)
50
+ alpha = new Uint8Array(r.take(width * height));
51
+ else if (compression === 1) {
52
+ const lengths = Array.from({ length: height }, () => r.u16());
53
+ alpha = new Uint8Array(width * height);
54
+ for (let row = 0; row < height; row++) {
55
+ const scan = new Reader(r.take(lengths[row]));
56
+ let column = 0;
57
+ while (scan.offset < scan.data.length) {
58
+ const code = scan.u8();
59
+ if (code === 128)
60
+ continue;
61
+ const count = code < 128 ? code + 1 : 257 - code;
62
+ if (column + count > width)
63
+ throw new Error("ABR RLE row overflow");
64
+ if (code < 128)
65
+ alpha.set(scan.take(count), row * width + column);
66
+ else
67
+ alpha.fill(scan.u8(), row * width + column, row * width + column + count);
68
+ column += count;
69
+ }
70
+ if (column !== width)
71
+ throw new Error("ABR RLE row is incomplete");
72
+ }
73
+ }
74
+ else
75
+ throw new Error(`ABR compression ${compression} is unsupported`);
76
+ return { name, width, height, alpha };
77
+ }
78
+ export function readABR(data) {
79
+ const r = new Reader(data), version = r.u16(), second = r.u16(), samples = [], unsupported = [];
80
+ if (version === 1 || version === 2) {
81
+ if (second > 4096)
82
+ throw new Error("ABR sample count exceeds 4096");
83
+ for (let i = 0; i < second; i++) {
84
+ const type = r.u16(), record = new Reader(r.take(r.u32()));
85
+ if (type !== 2) {
86
+ unsupported.push(`ABR entry ${i}: computed/unknown brush type ${type}`);
87
+ continue;
88
+ }
89
+ try {
90
+ record.take(4);
91
+ const spacing = record.u16() / 100;
92
+ let name = `Sample ${i + 1}`;
93
+ if (version === 2) {
94
+ const length = record.u32();
95
+ const text = Buffer.from(record.take(length * 2));
96
+ name = text.swap16().toString("utf16le").replace(/\0+$/, "");
97
+ }
98
+ record.take(9);
99
+ samples.push({ ...sampled(record, name), spacing });
100
+ }
101
+ catch (e) {
102
+ unsupported.push(`ABR entry ${i}: ${e.message}`);
103
+ }
104
+ }
105
+ }
106
+ else if (version === 6 && (second === 1 || second === 2)) {
107
+ while (r.offset < data.length) {
108
+ if (r.take(4).toString() !== "8BIM")
109
+ throw new Error("Invalid ABR section signature");
110
+ const kind = r.take(4).toString(), section = new Reader(r.take(r.u32()));
111
+ if (kind !== "samp") {
112
+ unsupported.push(`ABR ${kind} section not mapped to stroke behavior`);
113
+ continue;
114
+ }
115
+ while (section.offset < section.data.length) {
116
+ const size = section.u32(), record = new Reader(section.take(size));
117
+ section.take((4 - size % 4) % 4);
118
+ try {
119
+ record.take(37 + (second === 1 ? 10 : 264));
120
+ samples.push(sampled(record, `Sample ${samples.length + 1}`));
121
+ }
122
+ catch (e) {
123
+ unsupported.push(`ABR sample: ${e.message}`);
124
+ }
125
+ if (samples.length > 4096)
126
+ throw new Error("ABR sample limit exceeded");
127
+ }
128
+ }
129
+ }
130
+ else
131
+ unsupported.push(`ABR version ${version}.${second} is unsupported; supported sampled formats: 1, 2, 6.1, 6.2`);
132
+ unsupported.push("Photoshop brush dynamics, dual brush, wet mixing and texture behavior are not emulated");
133
+ return { samples, unsupported };
134
+ }
135
+ //# sourceMappingURL=resource-binary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-binary.js","sourceRoot":"","sources":["../../../src/drawing/resource-binary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import type { BrushPreset, BrushTip } from "../model/types.js";
2
+ export interface ResourceOrigin {
3
+ source: string;
4
+ author?: string;
5
+ license: string;
6
+ redistribution: "allowed" | "unknown" | "forbidden";
7
+ }
8
+ export interface BrushResource {
9
+ id: string;
10
+ name: string;
11
+ role: "tip" | "texture";
12
+ tip: Extract<BrushTip, {
13
+ kind: "bitmap";
14
+ }>;
15
+ originalWidth: number;
16
+ originalHeight: number;
17
+ checksum: string;
18
+ origin: ResourceOrigin;
19
+ }
20
+ export interface ImportedPreset {
21
+ name: string;
22
+ engine: string;
23
+ parameters: Record<string, string>;
24
+ resourceIds: string[];
25
+ mapped: Partial<Pick<BrushPreset, "spacing" | "opacity" | "flow">>;
26
+ missingDependencies: string[];
27
+ unsupported: string[];
28
+ }
29
+ export interface BrushImportReport {
30
+ format: string;
31
+ source: ResourceOrigin;
32
+ checksum: string;
33
+ resources: BrushResource[];
34
+ presets: ImportedPreset[];
35
+ mapped: string[];
36
+ missingDependencies: string[];
37
+ unsupported: string[];
38
+ warnings: string[];
39
+ }
40
+ export interface ImportOptions {
41
+ origin: ResourceOrigin;
42
+ maxTipSize?: number;
43
+ maskMode?: "alpha" | "luminance" | "inverse-luminance";
44
+ dependencies?: Record<string, Buffer>;
45
+ role?: "tip" | "texture";
46
+ }
47
+ export declare function importBrushResource(path: string, options: ImportOptions): Promise<BrushImportReport>;
48
+ export declare function importBrushResourceBuffer(data: Buffer, name: string, options: ImportOptions): Promise<BrushImportReport>;
49
+ /** Explicitly reauthor a resource for this engine; never promises source-application parity. */
50
+ export declare function brushFromResource(resource: BrushResource, settings: Omit<BrushPreset, "tip">): BrushPreset;
51
+ //# sourceMappingURL=resources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../../../src/drawing/resources.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAG/D,MAAM,WAAW,cAAc;IAAG,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,SAAS,GAAC,SAAS,GAAC,WAAW,CAAA;CAAE;AACrI,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,KAAK,GAAC,SAAS,CAAC;IAAC,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAC;QAAC,IAAI,EAAC,QAAQ,CAAA;KAAC,CAAC,CAAC;IACxF,aAAa,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,cAAc,CAAC;CACzF;AACD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAC,MAAM,CAAC,CAAC;IAAC,WAAW,EAAE,MAAM,EAAE,CAAC;IACvF,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,WAAW,EAAC,SAAS,GAAC,SAAS,GAAC,MAAM,CAAC,CAAC,CAAC;IAC9D,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,EAAE,CAAC;CACtD;AACD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,cAAc,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,aAAa,EAAE,CAAC;IACrF,OAAO,EAAE,cAAc,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACvH;AACD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,cAAc,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,GAAC,WAAW,GAAC,mBAAmB,CAAC;IACnD,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAC,MAAM,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE,KAAK,GAAC,SAAS,CAAC;CACxB;AA+BD,wBAAsB,mBAAmB,CAAC,IAAI,EAAC,MAAM,EAAE,OAAO,EAAC,aAAa,GAAE,OAAO,CAAC,iBAAiB,CAAC,CAEvG;AAED,wBAAsB,yBAAyB,CAAC,IAAI,EAAC,MAAM,EAAC,IAAI,EAAC,MAAM,EAAC,OAAO,EAAC,aAAa,GAAE,OAAO,CAAC,iBAAiB,CAAC,CAgHxH;AAED,gGAAgG;AAChG,wBAAgB,iBAAiB,CAAC,QAAQ,EAAC,aAAa,EAAC,QAAQ,EAAC,IAAI,CAAC,WAAW,EAAC,KAAK,CAAC,GAAE,WAAW,CAGrG"}
@@ -0,0 +1,239 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { basename, extname } from "node:path";
3
+ import { createHash } from "node:crypto";
4
+ import { inflateSync } from "node:zlib";
5
+ import { unzipSync } from "fflate";
6
+ import { XMLParser, XMLValidator } from "fast-xml-parser";
7
+ import sharp from "sharp";
8
+ import { Reader, readGBR, readABR } from "./resource-binary.js";
9
+ const sha = (b) => createHash("sha256").update(b).digest("hex");
10
+ const list = (x) => x === undefined ? [] : Array.isArray(x) ? x : [x];
11
+ const xml = (text) => {
12
+ text = text.replace(/<!DOCTYPE\s+[A-Za-z_:][\w:.-]*\s*>/g, "");
13
+ if (text.length > 8 * 1024 * 1024 || /<!DOCTYPE|<!ENTITY/i.test(text))
14
+ throw new Error("XML entities/DOCTYPE or oversized XML are not allowed");
15
+ const valid = XMLValidator.validate(text);
16
+ if (valid !== true)
17
+ throw new Error(`Invalid preset XML: ${valid.err.msg}`);
18
+ return new XMLParser({ ignoreAttributes: false, parseTagValue: false, attributeNamePrefix: "@" }).parse(text);
19
+ };
20
+ function pngText(data) {
21
+ if (data.subarray(0, 8).toString("hex") !== "89504e470d0a1a0a")
22
+ throw new Error("KPP must be a PNG container");
23
+ const r = new Reader(data);
24
+ r.take(8);
25
+ const fields = {};
26
+ while (r.offset < data.length) {
27
+ const length = r.u32(), type = r.take(4).toString(), chunk = r.take(length);
28
+ r.take(4);
29
+ if (!["tEXt", "zTXt", "iTXt"].includes(type))
30
+ continue;
31
+ const zero = chunk.indexOf(0);
32
+ if (zero < 1)
33
+ throw new Error("Invalid PNG text keyword");
34
+ const key = chunk.subarray(0, zero).toString();
35
+ let value;
36
+ if (type === "tEXt")
37
+ value = chunk.subarray(zero + 1);
38
+ else if (type === "zTXt") {
39
+ if (chunk[zero + 1] !== 0)
40
+ throw new Error("Unknown PNG text compression");
41
+ value = inflateSync(chunk.subarray(zero + 2), { maxOutputLength: 8 * 1024 * 1024 });
42
+ }
43
+ else {
44
+ const compressed = chunk[zero + 1], method = chunk[zero + 2];
45
+ let offset = zero + 3;
46
+ for (let i = 0; i < 2; i++) {
47
+ const end = chunk.indexOf(0, offset);
48
+ if (end < 0)
49
+ throw new Error("Invalid international PNG text");
50
+ offset = end + 1;
51
+ }
52
+ if (method !== 0 || !(compressed === 0 || compressed === 1))
53
+ throw new Error("Unknown international PNG text compression");
54
+ value = compressed ? inflateSync(chunk.subarray(offset), { maxOutputLength: 8 * 1024 * 1024 }) : chunk.subarray(offset);
55
+ }
56
+ fields[key] = value.toString("utf8");
57
+ }
58
+ return fields;
59
+ }
60
+ export async function importBrushResource(path, options) {
61
+ return importBrushResourceBuffer(await readFile(path), basename(path), options);
62
+ }
63
+ export async function importBrushResourceBuffer(data, name, options) {
64
+ if (data.length > 64 * 1024 * 1024)
65
+ throw new Error("Brush resource exceeds 64 MB input limit");
66
+ const max = options.maxTipSize ?? 128;
67
+ if (!Number.isInteger(max) || max < 1 || max > 512)
68
+ throw new Error("maxTipSize must be 1..512");
69
+ const format = extname(name).toLowerCase().slice(1);
70
+ const report = { format, source: options.origin, checksum: sha(data), resources: [], presets: [], mapped: [], missingDependencies: [], unsupported: [], warnings: [] };
71
+ const addSample = async (sample, originName, role = "tip") => {
72
+ const { data: pixels, info } = await sharp(sample.alpha, { raw: { width: sample.width, height: sample.height, channels: 1 } }).resize({ width: max, height: max, fit: "inside", withoutEnlargement: true }).greyscale().raw().toBuffer({ resolveWithObject: true });
73
+ const checksum = createHash("sha256").update(`mask:${sample.width}x${sample.height}:`).update(sample.alpha).digest("hex");
74
+ const importedChecksum = createHash("sha256").update(`${checksum}:${info.width}x${info.height}:`).update(pixels).digest("hex");
75
+ const id = `resource:${importedChecksum}:${role}`;
76
+ const tip = { kind: "bitmap", width: info.width, height: info.height, alpha: Array.from(pixels, v => v / 255), angle: 0, rotationMode: "stroke", sourceAssetId: id };
77
+ if (!report.resources.some(r => r.id === id))
78
+ report.resources.push({ id, name: originName, role, tip, originalWidth: sample.width, originalHeight: sample.height, checksum, origin: options.origin });
79
+ if (info.width !== sample.width || info.height !== sample.height)
80
+ report.warnings.push(`${originName}: resampled ${sample.width}x${sample.height} to ${info.width}x${info.height}`);
81
+ return id;
82
+ };
83
+ const image = async (bytes, entry, role = "tip") => {
84
+ const { data: pixels, info } = await sharp(bytes, { limitInputPixels: 16 * 1024 * 1024 }).toColourspace("srgb").ensureAlpha().raw().toBuffer({ resolveWithObject: true });
85
+ const mode = role === "texture" ? "luminance" : options.maskMode ?? "alpha";
86
+ const alpha = Uint8Array.from({ length: info.width * info.height }, (_, i) => {
87
+ const a = pixels[i * 4 + 3] / 255, l = .2126 * pixels[i * 4] + .7152 * pixels[i * 4 + 1] + .0722 * pixels[i * 4 + 2];
88
+ return Math.round(mode === "alpha" ? a * 255 : (mode === "luminance" ? l : 255 - l) * a);
89
+ });
90
+ if (mode === "alpha" && alpha.every(v => v === 255))
91
+ report.warnings.push(`${entry}: alpha is fully opaque; choose inverse-luminance for black-on-white tips`);
92
+ return addSample({ name: entry, width: info.width, height: info.height, alpha }, entry, role);
93
+ };
94
+ const load = async (bytes, entry, role = "tip") => {
95
+ const extension = extname(entry).toLowerCase();
96
+ if (extension === ".png")
97
+ return [await image(bytes, entry, role)];
98
+ if (extension === ".gbr") {
99
+ const s = readGBR(new Reader(bytes));
100
+ const id = await addSample(s, entry, role);
101
+ report.mapped.push(`${entry}: bitmap alpha; native spacing ${s.spacing}`);
102
+ return [id];
103
+ }
104
+ if (extension === ".gih") {
105
+ const r = new Reader(bytes), line = () => { const end = bytes.indexOf(10, r.offset); if (end < 0 || end - r.offset > 4096)
106
+ throw new Error("Invalid GIH header"); return r.take(end - r.offset + 1).toString().trim(); };
107
+ line();
108
+ const header = line(), count = Number(header.split(/\s/)[0]);
109
+ if (!Number.isInteger(count) || count < 1 || count > 4096)
110
+ throw new Error("Invalid GIH brush count");
111
+ const ids = [];
112
+ for (let i = 0; i < count; i++)
113
+ ids.push(await addSample(readGBR(r), `${entry}#${i}`, role));
114
+ report.unsupported.push(`${entry}: image-pipe selection dynamics are not emulated (${header}); cells are separate tips`);
115
+ return ids;
116
+ }
117
+ if (extension === ".abr") {
118
+ const result = readABR(bytes);
119
+ report.unsupported.push(...result.unsupported);
120
+ const ids = [];
121
+ for (const s of result.samples)
122
+ ids.push(await addSample(s, `${entry}/${s.name}`, role));
123
+ return ids;
124
+ }
125
+ report.unsupported.push(`${entry}: resource encoding ${extension} is not decoded`);
126
+ return [];
127
+ };
128
+ const preset = async (bytes, entry, dependencies) => {
129
+ const fields = pngText(bytes);
130
+ if (!fields.preset)
131
+ throw new Error(`${entry}: missing preset metadata; preview is never used as a tip`);
132
+ const root = xml(fields.preset).Preset;
133
+ if (!root)
134
+ throw new Error(`${entry}: missing Preset XML root`);
135
+ const parameters = {};
136
+ for (const param of list(root.param))
137
+ parameters[String(param["@name"])] = String(param["#text"] ?? "");
138
+ const result = { name: root["@name"] ?? entry, engine: root["@paintopid"] ?? "unknown", parameters, resourceIds: [], mapped: {}, missingDependencies: [], unsupported: [] };
139
+ const deps = { ...dependencies };
140
+ for (const resource of list(root.resources?.resource)) {
141
+ const file = String(resource["@filename"] ?? "");
142
+ if (!file)
143
+ continue;
144
+ const decoded = Buffer.from(String(resource["#text"] ?? ""), "base64");
145
+ if (decoded.length > 16 * 1024 * 1024)
146
+ throw new Error("Embedded resource exceeds 16 MB");
147
+ const expected = resource["@md5sum"];
148
+ if (expected && createHash("md5").update(decoded).digest("hex") !== expected)
149
+ throw new Error(`Embedded resource checksum mismatch: ${file}`);
150
+ deps[file] = decoded;
151
+ }
152
+ const refs = [];
153
+ let brushDefinition;
154
+ if (parameters.brush_definition) {
155
+ brushDefinition = xml(parameters.brush_definition).Brush;
156
+ const walk = (node) => {
157
+ if (!node || typeof node !== "object")
158
+ return;
159
+ for (const [key, value] of Object.entries(node)) {
160
+ if (key === "@filename")
161
+ refs.push({ name: String(value), role: "tip" });
162
+ else if (typeof value === "object")
163
+ walk(value);
164
+ }
165
+ };
166
+ walk(brushDefinition);
167
+ const rawSpacing = brushDefinition?.["@spacing"], spacing = Number(rawSpacing);
168
+ if (rawSpacing !== undefined) {
169
+ if (String(rawSpacing).trim() && Number.isFinite(spacing) && spacing >= .02 && spacing <= 4)
170
+ result.mapped.spacing = spacing;
171
+ else
172
+ result.unsupported.push(`Unmapped brush spacing: ${rawSpacing} (supported range 0.02..4)`);
173
+ }
174
+ }
175
+ for (const [key, value] of Object.entries(parameters)) {
176
+ if (/Texture\/Pattern\/.*(?:FileName|Filename)$/i.test(key) && value)
177
+ refs.push({ name: value, role: "texture" });
178
+ if (key === "OpacityValue" || key === "FlowValue") {
179
+ const v = Number(value);
180
+ if (value.trim() && Number.isFinite(v) && v >= 0 && v <= 1)
181
+ result.mapped[key === "OpacityValue" ? "opacity" : "flow"] = v;
182
+ else
183
+ result.unsupported.push(`Unmapped parameter: ${key} = ${value} (supported range 0..1)`);
184
+ }
185
+ }
186
+ let resolvedTip = false;
187
+ for (const ref of refs) {
188
+ const matches = Object.hasOwn(deps, ref.name) ? [ref.name] : Object.keys(deps).filter(k => basename(k) === basename(ref.name));
189
+ if (matches.length !== 1) {
190
+ result.missingDependencies.push(`${ref.name}${matches.length > 1 ? " (ambiguous)" : ""}`);
191
+ continue;
192
+ }
193
+ const ids = await load(deps[matches[0]], ref.name, ref.role);
194
+ result.resourceIds.push(...ids);
195
+ if (ref.role === 'tip' && ids.length)
196
+ resolvedTip = true;
197
+ }
198
+ if (!resolvedTip)
199
+ result.unsupported.push("No explicit bitmap tip reference resolved; auto/procedural/masked brush definitions are not translated");
200
+ result.unsupported.push(`Krita engine '${result.engine}' is not emulated; sensors, mixing, masked brush and texture mode require explicit reauthoring`);
201
+ result.unsupported.push(...Object.keys(parameters).filter(k => !["brush_definition", "OpacityValue", "FlowValue", "paintop"].includes(k)).map(k => `Unmapped parameter: ${k}`));
202
+ report.presets.push(result);
203
+ report.missingDependencies.push(...result.missingDependencies);
204
+ report.unsupported.push(...result.unsupported);
205
+ report.mapped.push(...Object.entries(result.mapped).map(([k, v]) => `${entry}: ${k} = ${v}`));
206
+ };
207
+ if (format === "bundle") {
208
+ let expanded = 0, count = 0;
209
+ const entries = unzipSync(data, { filter: entry => {
210
+ if (++count > 4096 || entry.originalSize > 16 * 1024 * 1024 || (expanded += entry.originalSize) > 64 * 1024 * 1024)
211
+ throw new Error("Bundle exceeds entry/decompression limits");
212
+ if (entry.name.includes("..") || entry.name.startsWith("/") || entry.name.includes("\\"))
213
+ throw new Error("Unsafe bundle entry path");
214
+ return true;
215
+ } });
216
+ const deps = Object.fromEntries(Object.entries(entries).map(([k, v]) => [k, Buffer.from(v)]));
217
+ for (const [entry, bytes] of Object.entries(deps)) {
218
+ if (entry.endsWith(".kpp"))
219
+ await preset(bytes, entry, deps);
220
+ else if (/^(brushes|kis_brushes)\//.test(entry))
221
+ await load(bytes, entry);
222
+ else if (/^(patterns|kis_patterns)\//.test(entry))
223
+ await load(bytes, entry, "texture");
224
+ }
225
+ report.warnings.push("Bundle metadata does not establish redistribution permission; origin/license is caller-supplied");
226
+ }
227
+ else if (format === "kpp")
228
+ await preset(data, name, options.dependencies ?? {});
229
+ else
230
+ await load(data, name, options.role ?? "tip");
231
+ return report;
232
+ }
233
+ /** Explicitly reauthor a resource for this engine; never promises source-application parity. */
234
+ export function brushFromResource(resource, settings) {
235
+ if (resource.role !== "tip")
236
+ throw new Error("A texture resource is not a brush tip; select a tip explicitly");
237
+ return { ...structuredClone(settings), tip: structuredClone(resource.tip), provenance: { ...resource.origin, resourceChecksum: resource.checksum } };
238
+ }
239
+ //# sourceMappingURL=resources.js.map