@kensio/colophon 2.10.0 → 2.11.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 (84) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/index.js +0 -0
  3. package/dist/config/index.d.ts.map +1 -1
  4. package/dist/config/index.js +2 -1
  5. package/dist/config/index.js.map +1 -1
  6. package/dist/encode/index.d.ts.map +1 -1
  7. package/dist/encode/index.js +10 -5
  8. package/dist/encode/index.js.map +1 -1
  9. package/dist/encode/quantise.d.ts +22 -0
  10. package/dist/encode/quantise.d.ts.map +1 -0
  11. package/dist/encode/quantise.js +29 -0
  12. package/dist/encode/quantise.js.map +1 -0
  13. package/dist/encode/sharp.d.ts +15 -0
  14. package/dist/encode/sharp.d.ts.map +1 -1
  15. package/dist/encode/sharp.js +20 -0
  16. package/dist/encode/sharp.js.map +1 -1
  17. package/dist/image/media.d.ts.map +1 -1
  18. package/dist/image/media.js.map +1 -1
  19. package/dist/image/svg.js +1 -1
  20. package/dist/platform/base64.d.ts.map +1 -1
  21. package/dist/platform/base64.js +0 -2
  22. package/dist/platform/base64.js.map +1 -1
  23. package/dist/png/carry.d.ts +27 -0
  24. package/dist/png/carry.d.ts.map +1 -0
  25. package/dist/png/carry.js +54 -0
  26. package/dist/png/carry.js.map +1 -0
  27. package/dist/png/index.d.ts +7 -5
  28. package/dist/png/index.d.ts.map +1 -1
  29. package/dist/png/index.js +1 -0
  30. package/dist/png/index.js.map +1 -1
  31. package/dist/pool.js +1 -1
  32. package/dist/stamp/config-digest.d.ts +4 -0
  33. package/dist/stamp/config-digest.d.ts.map +1 -1
  34. package/dist/stamp/config-digest.js +5 -0
  35. package/dist/stamp/config-digest.js.map +1 -1
  36. package/dist/texture/color.d.ts +10 -0
  37. package/dist/texture/color.d.ts.map +1 -0
  38. package/dist/texture/color.js +10 -0
  39. package/dist/texture/color.js.map +1 -0
  40. package/dist/texture/index.d.ts +2 -1
  41. package/dist/texture/index.d.ts.map +1 -1
  42. package/dist/texture/index.js +6 -1
  43. package/dist/texture/index.js.map +1 -1
  44. package/dist/texture/pattern.d.ts.map +1 -1
  45. package/dist/texture/pattern.js +1 -2
  46. package/dist/texture/pattern.js.map +1 -1
  47. package/dist/texture/resolve.d.ts +5 -4
  48. package/dist/texture/resolve.d.ts.map +1 -1
  49. package/dist/texture/resolve.js +5 -4
  50. package/dist/texture/resolve.js.map +1 -1
  51. package/dist/texture/waves.d.ts +18 -0
  52. package/dist/texture/waves.d.ts.map +1 -0
  53. package/dist/texture/waves.js +55 -0
  54. package/dist/texture/waves.js.map +1 -0
  55. package/dist/types.d.ts +51 -7
  56. package/dist/types.d.ts.map +1 -1
  57. package/dist/validate/keys.d.ts +4 -2
  58. package/dist/validate/keys.d.ts.map +1 -1
  59. package/dist/validate/keys.js +12 -2
  60. package/dist/validate/keys.js.map +1 -1
  61. package/dist/validate/texture.d.ts.map +1 -1
  62. package/dist/validate/texture.js +5 -1
  63. package/dist/validate/texture.js.map +1 -1
  64. package/package.json +23 -24
  65. package/dist/highlight/probe.d.ts +0 -4
  66. package/dist/highlight/probe.d.ts.map +0 -1
  67. package/dist/highlight/probe.js +0 -4
  68. package/dist/highlight/probe.js.map +0 -1
  69. package/dist/jpeg/index.d.ts +0 -10
  70. package/dist/jpeg/index.d.ts.map +0 -1
  71. package/dist/jpeg/index.js +0 -2
  72. package/dist/jpeg/index.js.map +0 -1
  73. package/dist/render/png.d.ts +0 -20
  74. package/dist/render/png.d.ts.map +0 -1
  75. package/dist/render/png.js +0 -29
  76. package/dist/render/png.js.map +0 -1
  77. package/dist/stamp/chunk.d.ts +0 -14
  78. package/dist/stamp/chunk.d.ts.map +0 -1
  79. package/dist/stamp/chunk.js +0 -38
  80. package/dist/stamp/chunk.js.map +0 -1
  81. package/dist/templates/code/ellipsis.d.ts +0 -3
  82. package/dist/templates/code/ellipsis.d.ts.map +0 -1
  83. package/dist/templates/code/ellipsis.js +0 -3
  84. package/dist/templates/code/ellipsis.js.map +0 -1
package/README.md CHANGED
@@ -251,7 +251,7 @@ theme sets and how to override part of one.
251
251
  | --------------------------------- | ---------------------------------------------------------------------------- |
252
252
  | `pnpm build` | Compile to `dist/`. |
253
253
  | `pnpm test`, `pnpm test:coverage` | Run Vitest. |
254
- | `pnpm lint` | ESLint and Prettier check. |
254
+ | `pnpm lint` | Oxlint, ESLint and oxfmt check, run together. |
255
255
  | `pnpm fmt` | Auto-fix. |
256
256
  | `pnpm samples` | Regenerate the sample images into `docs/samples/`. |
257
257
  | `pnpm baselines` | Re-record the visual regression baselines in `test/baselines/`. |
package/dist/cli/index.js CHANGED
File without changes
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EAErB,cAAc,EACf,MAAM,aAAa,CAAC;AAcrB,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,cAAc,EACd,yBAAyB,EACzB,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,aAAa,EACb,YAAY,GACb,MAAM,eAAe,CAAC;AAcvB;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAAC;AACrE;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,qBAAqB,GAC7B,qBAAqB,CAAC;AAUzB;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,GAAE,cAAmB,GAAG,cAAc,CAqCxE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EAErB,cAAc,EACf,MAAM,aAAa,CAAC;AAcrB,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,cAAc,EACd,yBAAyB,EACzB,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,aAAa,EACb,YAAY,GACb,MAAM,eAAe,CAAC;AAcvB;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAAC;AACrE;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,qBAAqB,GAC7B,qBAAqB,CAAC;AAUzB;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,GAAE,cAAmB,GAAG,cAAc,CAsCxE"}
@@ -19,7 +19,7 @@ export { DEFAULT_CODE_FONT_FAMILY, DEFAULT_CODE_STYLE, DEFAULT_COLORS, DEFAULT_C
19
19
  function warnToConsole(message) {
20
20
  // The console is the point: this is the default sink, replaced wholesale by
21
21
  // a caller-supplied `onWarning`.
22
- // eslint-disable-next-line no-console
22
+ // oxlint-disable-next-line no-console
23
23
  console.warn(`colophon: ${message}`);
24
24
  }
25
25
  /**
@@ -66,6 +66,7 @@ export function resolveConfig(input = {}) {
66
66
  // config, including one for a browser.
67
67
  rasteriser: config.rasteriser ?? defaultRasteriser,
68
68
  compressionLevel: resolveCompressionLevel(config.compressionLevel),
69
+ quantise: config.quantise ?? false,
69
70
  format: config.format ?? DEFAULT_FORMAT,
70
71
  quality: resolveQuality(config.quality),
71
72
  maxBytes: resolveMaxBytes(config.maxBytes),
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/encode/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAOlD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAyCxE;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,MAAM,CAAC,CAKjB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/encode/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAQlD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA6CxE;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,MAAM,CAAC,CAKjB"}
@@ -1,6 +1,7 @@
1
1
  import { recompressPng } from "../png/recompress.js";
2
2
  import { fitToBytes } from "./fit.js";
3
3
  import { mediaTypeFor } from "./format.js";
4
+ import { quantisePng } from "./quantise.js";
4
5
  import { openRaster } from "./sharp.js";
5
6
  import { warnIfOverCap } from "./warn.js";
6
7
  export { extensionFor, mediaTypeFor, withExtension } from "./format.js";
@@ -8,10 +9,12 @@ export { extensionFor, mediaTypeFor, withExtension } from "./format.js";
8
9
  * The rendered bytes as the configured format, before the cap is considered.
9
10
  *
10
11
  * PNG is what the rasteriser already produces, so there is nothing to convert
11
- * and the lossless recompression is the whole of the work. The other three are
12
- * encoded from whatever came back, which is a decode and an encode per image,
13
- * paid once because an image whose rebuild stamp still matches is not rendered
14
- * again.
12
+ * and the encoding is the whole of the work: the lossless recompression, or the
13
+ * palette where `quantise` asks for one, which is the same file made much
14
+ * smaller by changing the picture rather than by looking harder for matches.
15
+ * The other three formats are encoded from whatever came back, which is a
16
+ * decode and an encode per image, paid once because an image whose rebuild
17
+ * stamp still matches is not rendered again.
15
18
  *
16
19
  * Bytes that are already in the configured format are handed straight on. A
17
20
  * project whose rasteriser produces WebP and whose config asks for WebP means
@@ -20,7 +23,9 @@ export { extensionFor, mediaTypeFor, withExtension } from "./format.js";
20
23
  */
21
24
  async function toFormat(raster, config) {
22
25
  if (config.format === "png") {
23
- return recompressPng(raster, config.compressionLevel);
26
+ return config.quantise
27
+ ? quantisePng(raster, config.compressionLevel)
28
+ : recompressPng(raster, config.compressionLevel);
24
29
  }
25
30
  // Read off the config once, so the narrowing above survives into the closure
26
31
  // below, where TypeScript would otherwise have to assume the field had moved.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/encode/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAExE;;;;;;;;;;;;;GAaG;AACH,KAAK,UAAU,QAAQ,CACrB,MAAc,EACd,MAAsB;IAEtB,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAC5B,OAAO,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACxD,CAAC;IAED,6EAA6E;IAC7E,8EAA8E;IAC9E,MAAM,MAAM,GAAgB,MAAM,CAAC,MAAM,CAAC;IAC1C,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC;IAExC,IAAI,MAAM,CAAC,SAAS,KAAK,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9C,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,EAAE,OAAe,EAAmB,EAAE,CACxD,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEjC,OAAO,MAAM,CAAC,QAAQ,KAAK,SAAS;QAClC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;QACxB,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC1D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAc,EACd,MAAsB;IAEtB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAE7B,OAAO,KAAK,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/encode/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAExE;;;;;;;;;;;;;;;GAeG;AACH,KAAK,UAAU,QAAQ,CACrB,MAAc,EACd,MAAsB;IAEtB,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAC5B,OAAO,MAAM,CAAC,QAAQ;YACpB,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,gBAAgB,CAAC;YAC9C,CAAC,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACrD,CAAC;IAED,6EAA6E;IAC7E,8EAA8E;IAC9E,MAAM,MAAM,GAAgB,MAAM,CAAC,MAAM,CAAC;IAC1C,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC;IAExC,IAAI,MAAM,CAAC,SAAS,KAAK,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9C,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,EAAE,OAAe,EAAmB,EAAE,CACxD,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEjC,OAAO,MAAM,CAAC,QAAQ,KAAK,SAAS;QAClC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;QACxB,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC1D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAc,EACd,MAAsB;IAEtB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAE7B,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * The rendered PNG reduced to a palette, keeping whatever the file said about
3
+ * itself.
4
+ *
5
+ * sharp decodes the picture and writes a new file around it, so everything the
6
+ * container held is gone from what comes back, the rebuild stamp included.
7
+ * `carryAncillaryChunks` is what puts it there again, and is the reason this is
8
+ * a step of its own rather than one call.
9
+ *
10
+ * Bytes that are not a PNG are handed back as they are, which is what
11
+ * `recompressPng` does with them too. `quantise` is a PNG setting, and a
12
+ * rasteriser producing another format has already decided how its bytes are
13
+ * encoded, so converting one here would be answering a question nobody asked.
14
+ *
15
+ * There is no fallback for a palette that came out larger than the original.
16
+ * Quantising is an explicit choice, and an image that is sometimes reduced and
17
+ * sometimes not, depending on how a particular gradient happened to compress,
18
+ * is worse to reason about than one that always is. Across the sample gallery
19
+ * the smallest saving is 39%.
20
+ */
21
+ export declare function quantisePng(raster: Buffer, level: number): Promise<Buffer>;
22
+ //# sourceMappingURL=quantise.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quantise.d.ts","sourceRoot":"","sources":["../../src/encode/quantise.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,CAMjB"}
@@ -0,0 +1,29 @@
1
+ import { carryAncillaryChunks, readChunks } from "../png/index.js";
2
+ import { encodePalettePng } from "./sharp.js";
3
+ /**
4
+ * The rendered PNG reduced to a palette, keeping whatever the file said about
5
+ * itself.
6
+ *
7
+ * sharp decodes the picture and writes a new file around it, so everything the
8
+ * container held is gone from what comes back, the rebuild stamp included.
9
+ * `carryAncillaryChunks` is what puts it there again, and is the reason this is
10
+ * a step of its own rather than one call.
11
+ *
12
+ * Bytes that are not a PNG are handed back as they are, which is what
13
+ * `recompressPng` does with them too. `quantise` is a PNG setting, and a
14
+ * rasteriser producing another format has already decided how its bytes are
15
+ * encoded, so converting one here would be answering a question nobody asked.
16
+ *
17
+ * There is no fallback for a palette that came out larger than the original.
18
+ * Quantising is an explicit choice, and an image that is sometimes reduced and
19
+ * sometimes not, depending on how a particular gradient happened to compress,
20
+ * is worse to reason about than one that always is. Across the sample gallery
21
+ * the smallest saving is 39%.
22
+ */
23
+ export async function quantisePng(raster, level) {
24
+ if (readChunks(raster) === undefined) {
25
+ return raster;
26
+ }
27
+ return carryAncillaryChunks(raster, await encodePalettePng(raster, level));
28
+ }
29
+ //# sourceMappingURL=quantise.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quantise.js","sourceRoot":"","sources":["../../src/encode/quantise.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAc,EACd,KAAa;IAEb,IAAI,UAAU,CAAC,MAAM,CAAC,KAAK,SAAS,EAAE,CAAC;QACrC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,oBAAoB,CAAC,MAAM,EAAE,MAAM,gBAAgB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;AAC7E,CAAC"}
@@ -14,6 +14,21 @@ export interface OpenRaster {
14
14
  /** The same picture as `format`, at `quality`. */
15
15
  encode(format: LossyFormat, quality: number): Promise<Buffer>;
16
16
  }
17
+ /**
18
+ * The same picture as a palette PNG of at most 256 colours, compressed at
19
+ * `level`.
20
+ *
21
+ * `effort` is sharp's own dial for how long the encoder spends, and this asks
22
+ * for all of it: these are images a site commits once and then serves to
23
+ * everyone who shares a link, and the whole point of quantising is the bytes.
24
+ * It costs about 150ms on a 1200x1200 image, which is what the zlib pass it
25
+ * replaces costs anyway.
26
+ *
27
+ * What comes back is not the picture that went in, which is the setting's whole
28
+ * trade and is `config.quantise`'s to explain. What does survive is alpha,
29
+ * since a PNG palette carries its own.
30
+ */
31
+ export declare function encodePalettePng(raster: Buffer, level: number): Promise<Buffer>;
17
32
  /** Open some rendered bytes for encoding. */
18
33
  export declare function openRaster(raster: Buffer): Promise<OpenRaster>;
19
34
  //# sourceMappingURL=sharp.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sharp.d.ts","sourceRoot":"","sources":["../../src/encode/sharp.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;AAEvD;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,qEAAqE;IACrE,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,kDAAkD;IAClD,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC/D;AA6DD,6CAA6C;AAC7C,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAOpE"}
1
+ {"version":3,"file":"sharp.d.ts","sourceRoot":"","sources":["../../src/encode/sharp.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;AAEvD;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,qEAAqE;IACrE,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,kDAAkD;IAClD,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC/D;AAuCD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,CAMjB;AAwBD,6CAA6C;AAC7C,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAOpE"}
@@ -28,6 +28,26 @@ async function encodeWith(image, format, quality) {
28
28
  }
29
29
  }
30
30
  }
31
+ /**
32
+ * The same picture as a palette PNG of at most 256 colours, compressed at
33
+ * `level`.
34
+ *
35
+ * `effort` is sharp's own dial for how long the encoder spends, and this asks
36
+ * for all of it: these are images a site commits once and then serves to
37
+ * everyone who shares a link, and the whole point of quantising is the bytes.
38
+ * It costs about 150ms on a 1200x1200 image, which is what the zlib pass it
39
+ * replaces costs anyway.
40
+ *
41
+ * What comes back is not the picture that went in, which is the setting's whole
42
+ * trade and is `config.quantise`'s to explain. What does survive is alpha,
43
+ * since a PNG palette carries its own.
44
+ */
45
+ export async function encodePalettePng(raster, level) {
46
+ const image = await openSharp(raster);
47
+ return image
48
+ .png({ compressionLevel: level, effort: 10, palette: true })
49
+ .toBuffer();
50
+ }
31
51
  /**
32
52
  * What the bytes already are.
33
53
  *
@@ -1 +1 @@
1
- {"version":3,"file":"sharp.js","sourceRoot":"","sources":["../../src/encode/sharp.ts"],"names":[],"mappings":"AAqBA;;;;;;;;;;;GAWG;AACH,KAAK,UAAU,SAAS,CAAC,MAAc;IACrC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;IAEjD,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC;AACvB,CAAC;AAED,iFAAiF;AACjF,KAAK,UAAU,UAAU,CACvB,KAAY,EACZ,MAAmB,EACnB,OAAe;IAEf,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,MAAM,EAAE,CAAC;YACZ,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC5C,CAAC;QACD,KAAK,MAAM,EAAE,CAAC;YACZ,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC5C,CAAC;QACD,KAAK,MAAM,EAAE,CAAC;YACZ,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC5C,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,aAAa,CAAC,KAAY;IACvC,IAAI,CAAC;QACH,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC;QAE7C,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,sEAAsE;YACpE,sEAAsE;YACtE,oBAAoB,EACtB,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;IACJ,CAAC;AACH,CAAC;AAED,6CAA6C;AAC7C,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAc;IAC7C,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;IAEtC,OAAO;QACL,SAAS,EAAE,MAAM,aAAa,CAAC,KAAK,CAAC;QACrC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC;KACtE,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"sharp.js","sourceRoot":"","sources":["../../src/encode/sharp.ts"],"names":[],"mappings":"AAqBA;;;;;;;;;;;GAWG;AACH,KAAK,UAAU,SAAS,CAAC,MAAc;IACrC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;IAEjD,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC;AACvB,CAAC;AAED,iFAAiF;AACjF,KAAK,UAAU,UAAU,CACvB,KAAY,EACZ,MAAmB,EACnB,OAAe;IAEf,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,MAAM,EAAE,CAAC;YACZ,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC5C,CAAC;QACD,KAAK,MAAM,EAAE,CAAC;YACZ,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC5C,CAAC;QACD,KAAK,MAAM,EAAE,CAAC;YACZ,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC5C,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAc,EACd,KAAa;IAEb,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;IAEtC,OAAO,KAAK;SACT,GAAG,CAAC,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;SAC3D,QAAQ,EAAE,CAAC;AAChB,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,aAAa,CAAC,KAAY;IACvC,IAAI,CAAC;QACH,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE,CAAC;QAE7C,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,sEAAsE;YACpE,sEAAsE;YACtE,oBAAoB,EACtB,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;IACJ,CAAC;AACH,CAAC;AAED,6CAA6C;AAC7C,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAc;IAC7C,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;IAEtC,OAAO;QACL,SAAS,EAAE,MAAM,aAAa,CAAC,KAAK,CAAC;QACrC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC;KACtE,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../src/image/media.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,MAAM,MAAM,SAAS,GACnB,WAAW,GAAG,YAAY,GAAG,WAAW,GAAG,YAAY,GAAG,eAAe,CAAC;AAmB5E;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,SAAS,CAkBvE"}
1
+ {"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../src/image/media.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,MAAM,MAAM,SAAS,GACjB,WAAW,GACX,YAAY,GACZ,WAAW,GACX,YAAY,GACZ,eAAe,CAAC;AAmBpB;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,SAAS,CAkBvE"}
@@ -1 +1 @@
1
- {"version":3,"file":"media.js","sourceRoot":"","sources":["../../src/image/media.ts"],"names":[],"mappings":"AAIA,SAAS,YAAY,CACnB,KAAiB,EACjB,SAA4B;IAE5B,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;AACjE,CAAC;AAED,2DAA2D;AAC3D,SAAS,QAAQ,CAAC,KAAiB,EAAE,MAAc,EAAE,IAAY;IAC/D,OAAO,KAAK,CAAC,IAAI,CACf,IAAI,EACJ,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,KAAK,CAAU,CAClD,CAAC,KAAK,CACL,CAAC,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,KAAK,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,CAC3E,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,KAAiB;IAC9C,IAAI,YAAY,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;QAC1E,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,IAAI,YAAY,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;QAC5C,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC;QAC/B,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC;QAC7D,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC;AACpD,CAAC;AAED;;;GAGG;AACH,SAAS,KAAK,CAAC,KAAiB;IAC9B,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IAC5D,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"media.js","sourceRoot":"","sources":["../../src/image/media.ts"],"names":[],"mappings":"AAQA,SAAS,YAAY,CACnB,KAAiB,EACjB,SAA4B;IAE5B,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;AACjE,CAAC;AAED,2DAA2D;AAC3D,SAAS,QAAQ,CAAC,KAAiB,EAAE,MAAc,EAAE,IAAY;IAC/D,OAAO,KAAK,CAAC,IAAI,CACf,IAAI,EACJ,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,SAAS,EAAE,KAAK,CAAU,CAClD,CAAC,KAAK,CACL,CAAC,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,KAAK,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,CAC3E,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,KAAiB;IAC9C,IAAI,YAAY,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;QAC1E,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,IAAI,YAAY,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;QAC5C,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC;QAC/B,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC;QAC7D,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC;AACpD,CAAC;AAED;;;GAGG;AACH,SAAS,KAAK,CAAC,KAAiB;IAC9B,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IAC5D,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC"}
package/dist/image/svg.js CHANGED
@@ -25,7 +25,7 @@ function length(value) {
25
25
  }
26
26
  // Deliberately parseFloat rather than Number: a length may carry a unit,
27
27
  // and `6em` is six of something rather than not a number.
28
- // eslint-disable-next-line unicorn/prefer-number-coercion
28
+ // oxlint-disable-next-line unicorn/prefer-number-coercion
29
29
  const number = Number.parseFloat(value ?? "");
30
30
  return Number.isFinite(number) && number > 0 ? number : undefined;
31
31
  }
@@ -1 +1 @@
1
- {"version":3,"file":"base64.d.ts","sourceRoot":"","sources":["../../src/platform/base64.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,wEAAwE;AACxE,wBAAgB,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAUlD;AAED,4EAA4E;AAI5E,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,CAKhE"}
1
+ {"version":3,"file":"base64.d.ts","sourceRoot":"","sources":["../../src/platform/base64.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,wEAAwE;AACxE,wBAAgB,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CASlD;AAED,4EAA4E;AAI5E,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,CAIhE"}
@@ -20,7 +20,6 @@ export function toBase64(bytes) {
20
20
  binary += String.fromCodePoint(...bytes.subarray(at, at + chunkSize));
21
21
  }
22
22
  // `Uint8Array#toBase64` is not on the oldest Node this package supports.
23
- // eslint-disable-next-line unicorn/prefer-uint8array-base64
24
23
  return btoa(binary);
25
24
  }
26
25
  /** Decode it again, for a `data:` URI that arrived carrying its payload. */
@@ -28,7 +27,6 @@ export function toBase64(bytes) {
28
27
  // Crypto will not take a possibly-shared buffer, and a signature is decoded
29
28
  // straight into it.
30
29
  export function fromBase64(text) {
31
- // eslint-disable-next-line unicorn/prefer-uint8array-base64
32
30
  const binary = atob(text);
33
31
  return Uint8Array.from(binary, (character) => character.codePointAt(0) ?? 0);
34
32
  }
@@ -1 +1 @@
1
- {"version":3,"file":"base64.js","sourceRoot":"","sources":["../../src/platform/base64.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;GAKG;AACH,MAAM,SAAS,GAAG,OAAO,CAAC;AAE1B,wEAAwE;AACxE,MAAM,UAAU,QAAQ,CAAC,KAAiB;IACxC,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,EAAE,IAAI,SAAS,EAAE,CAAC;QACpD,MAAM,IAAI,MAAM,CAAC,aAAa,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,yEAAyE;IACzE,4DAA4D;IAC5D,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC;AAED,4EAA4E;AAC5E,2EAA2E;AAC3E,4EAA4E;AAC5E,oBAAoB;AACpB,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,4DAA4D;IAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IAE1B,OAAO,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/E,CAAC"}
1
+ {"version":3,"file":"base64.js","sourceRoot":"","sources":["../../src/platform/base64.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;GAKG;AACH,MAAM,SAAS,GAAG,OAAO,CAAC;AAE1B,wEAAwE;AACxE,MAAM,UAAU,QAAQ,CAAC,KAAiB;IACxC,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,EAAE,IAAI,SAAS,EAAE,CAAC;QACpD,MAAM,IAAI,MAAM,CAAC,aAAa,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,yEAAyE;IACzE,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC;AAED,4EAA4E;AAC5E,2EAA2E;AAC3E,4EAA4E;AAC5E,oBAAoB;AACpB,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IAE1B,OAAO,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/E,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * `encoded` with `source`'s ancillary chunks put back, straight after the
3
+ * header.
4
+ *
5
+ * An encoder that reads a picture out of a PNG and writes a new one keeps the
6
+ * pixels and drops everything said about them, which for this package means the
7
+ * rebuild stamp: `stamp/carrier/png.ts` stores it as a `tEXt` chunk, and an
8
+ * image that came back without one would be an image every later build
9
+ * re-rendered, quietly and for ever. A rasteriser's own `pHYs` or `gAMA` goes
10
+ * the same way and says how the image is meant to be shown, so this is the
11
+ * promise `recompressPng` already keeps by rebuilding a file rather than
12
+ * re-encoding it.
13
+ *
14
+ * They go after `IHDR` rather than before the image data, which is where both
15
+ * the specification and this package want them: `gAMA` and `pHYs` have to
16
+ * precede `PLTE`, and the stamp reader takes a window off the front of the file
17
+ * rather than reading all of it.
18
+ *
19
+ * Critical chunks are never carried, since the header and the palette describe
20
+ * the picture the encoder just wrote rather than the one it read. Neither is a
21
+ * type the encoder wrote for itself, which is already its answer for that
22
+ * chunk. Bytes either side that do not read as chunks mean there is nothing to
23
+ * move or nowhere to put it, and `encoded` is handed back as it is: deciding an
24
+ * image is broken is not this function's job.
25
+ */
26
+ export declare function carryAncillaryChunks(source: Buffer, encoded: Buffer): Buffer;
27
+ //# sourceMappingURL=carry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"carry.d.ts","sourceRoot":"","sources":["../../src/png/carry.ts"],"names":[],"mappings":"AAgBA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAuB5E"}
@@ -0,0 +1,54 @@
1
+ import { chunkBytes, pngSignature, readChunks } from "./chunk.js";
2
+ /**
3
+ * Whether a chunk is ancillary rather than critical, which PNG says in the case
4
+ * of the first letter of its type: `tEXt` and `pHYs` are optional information
5
+ * about the image, where `IHDR`, `PLTE`, `IDAT` and `IEND` are the image.
6
+ *
7
+ * Spec: https://www.w3.org/TR/png-3/#5Chunk-naming-conventions
8
+ */
9
+ function isAncillary({ type }) {
10
+ const first = type.codePointAt(0) ?? 0;
11
+ return first >= 0x61 && first <= 0x7a;
12
+ }
13
+ /**
14
+ * `encoded` with `source`'s ancillary chunks put back, straight after the
15
+ * header.
16
+ *
17
+ * An encoder that reads a picture out of a PNG and writes a new one keeps the
18
+ * pixels and drops everything said about them, which for this package means the
19
+ * rebuild stamp: `stamp/carrier/png.ts` stores it as a `tEXt` chunk, and an
20
+ * image that came back without one would be an image every later build
21
+ * re-rendered, quietly and for ever. A rasteriser's own `pHYs` or `gAMA` goes
22
+ * the same way and says how the image is meant to be shown, so this is the
23
+ * promise `recompressPng` already keeps by rebuilding a file rather than
24
+ * re-encoding it.
25
+ *
26
+ * They go after `IHDR` rather than before the image data, which is where both
27
+ * the specification and this package want them: `gAMA` and `pHYs` have to
28
+ * precede `PLTE`, and the stamp reader takes a window off the front of the file
29
+ * rather than reading all of it.
30
+ *
31
+ * Critical chunks are never carried, since the header and the palette describe
32
+ * the picture the encoder just wrote rather than the one it read. Neither is a
33
+ * type the encoder wrote for itself, which is already its answer for that
34
+ * chunk. Bytes either side that do not read as chunks mean there is nothing to
35
+ * move or nowhere to put it, and `encoded` is handed back as it is: deciding an
36
+ * image is broken is not this function's job.
37
+ */
38
+ export function carryAncillaryChunks(source, encoded) {
39
+ const from = readChunks(source);
40
+ const into = readChunks(encoded);
41
+ if (from === undefined || into === undefined || into[0]?.type !== "IHDR") {
42
+ return encoded;
43
+ }
44
+ const present = new Set(into.map(({ type }) => type));
45
+ const carried = from.filter((chunk) => isAncillary(chunk) && !present.has(chunk.type));
46
+ if (carried.length === 0) {
47
+ return encoded;
48
+ }
49
+ return Buffer.concat([
50
+ pngSignature,
51
+ ...[into[0], ...carried, ...into.slice(1)].map(({ type, data }) => chunkBytes(type, data)),
52
+ ]);
53
+ }
54
+ //# sourceMappingURL=carry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"carry.js","sourceRoot":"","sources":["../../src/png/carry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAElE;;;;;;GAMG;AACH,SAAS,WAAW,CAAC,EAAE,IAAI,EAAY;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAEvC,OAAO,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC;AACxC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,OAAe;IAClE,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAEjC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,KAAK,MAAM,EAAE,CAAC;QACzE,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CACzB,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAC1D,CAAC;IAEF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,YAAY;QACZ,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAChE,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CACvB;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -1,13 +1,15 @@
1
1
  /**
2
2
  * Reading and rewriting the PNG container itself, as against the picture in it.
3
3
  *
4
- * Two things in the package have to open a finished PNG: the rebuild stamp,
5
- * which puts a `tEXt` chunk in the header, and the recompressor, which replaces
6
- * the image data with a smaller encoding of the same bytes. Both need the same
7
- * chunk arithmetic, and writing a CRC in two places is how the two would come
8
- * to disagree.
4
+ * Three things in the package have to open a finished PNG: the rebuild stamp,
5
+ * which puts a `tEXt` chunk in the header, the recompressor, which replaces the
6
+ * image data with a smaller encoding of the same bytes, and the carrier that
7
+ * moves what an outside encoder dropped into what it wrote. They need the same
8
+ * chunk arithmetic, and writing a CRC in three places is how they would come to
9
+ * disagree.
9
10
  */
10
11
  export type { PngChunk } from "./chunk.js";
12
+ export { carryAncillaryChunks } from "./carry.js";
11
13
  export { chunkBytes, pngSignature, readChunks } from "./chunk.js";
12
14
  export { recompressPng } from "./recompress.js";
13
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/png/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/png/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/png/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ export { carryAncillaryChunks } from "./carry.js";
1
2
  export { chunkBytes, pngSignature, readChunks } from "./chunk.js";
2
3
  export { recompressPng } from "./recompress.js";
3
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/png/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/png/index.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/pool.js CHANGED
@@ -37,7 +37,7 @@ export async function mapConcurrent(items, limit, worker) {
37
37
  }
38
38
  // Awaiting in the loop is the whole point: a worker takes one item at a
39
39
  // time, and the parallelism comes from there being several of them.
40
- // eslint-disable-next-line no-await-in-loop
40
+ // oxlint-disable-next-line no-await-in-loop
41
41
  results[index] = await worker(item, index);
42
42
  }
43
43
  }
@@ -13,6 +13,10 @@ import type { ResolvedConfig } from "../types.js";
13
13
  * without this the setting would appear to do nothing until each post next
14
14
  * changed, which is the sort of gap that gets reported as a bug.
15
15
  *
16
+ * `quantise` is in for a stronger version of that reason again, since it does
17
+ * change the pixels, and a project turning it off wants its gradients back
18
+ * rather than only on the posts it happens to edit next.
19
+ *
16
20
  * `format`, `quality` and `maxBytes` are in for the same reason, and `emitSvg`
17
21
  * for a version of it: turning it on has to write the documents for images that
18
22
  * are already on disk, and without this it would write them only for the posts
@@ -1 +1 @@
1
- {"version":3,"file":"config-digest.d.ts","sourceRoot":"","sources":["../../src/stamp/config-digest.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAIV,cAAc,EACf,MAAM,aAAa,CAAC;AA6CrB;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA4B1E"}
1
+ {"version":3,"file":"config-digest.d.ts","sourceRoot":"","sources":["../../src/stamp/config-digest.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAIV,cAAc,EACf,MAAM,aAAa,CAAC;AA6CrB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA6B1E"}
@@ -49,6 +49,10 @@ async function backgroundDigest(background) {
49
49
  * without this the setting would appear to do nothing until each post next
50
50
  * changed, which is the sort of gap that gets reported as a bug.
51
51
  *
52
+ * `quantise` is in for a stronger version of that reason again, since it does
53
+ * change the pixels, and a project turning it off wants its gradients back
54
+ * rather than only on the posts it happens to edit next.
55
+ *
52
56
  * `format`, `quality` and `maxBytes` are in for the same reason, and `emitSvg`
53
57
  * for a version of it: turning it on has to write the documents for images that
54
58
  * are already on disk, and without this it would write them only for the posts
@@ -78,6 +82,7 @@ export async function configDigest(config) {
78
82
  code: config.code,
79
83
  rasteriser: config.rasteriser.toString(),
80
84
  compressionLevel: config.compressionLevel,
85
+ quantise: config.quantise,
81
86
  format: config.format,
82
87
  quality: config.quality,
83
88
  maxBytes: config.maxBytes,
@@ -1 +1 @@
1
- {"version":3,"file":"config-digest.js","sourceRoot":"","sources":["../../src/stamp/config-digest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAQ5C,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEtD;;;;;GAKG;AACH,KAAK,UAAU,cAAc;IAC3B,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAC7B,IAAI,GAAG,CAAC,oBAAoB,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,EAC9C,MAAM,CACP,CAAC;IACF,OAAQ,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAyB,CAAC,OAAO,CAAC;AAC/D,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,UAAU,CAAC,IAAgB;IACxC,MAAM,KAAK,GAAG,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrE,OAAO,MAAM,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;AAChF,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,WAAW,CAAC,MAAmB;IAC5C,OAAO,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,gBAAgB,CAAC,UAAsB;IACpD,OAAO,UAAU,CAAC,IAAI,KAAK,OAAO;QAChC,CAAC,CAAC,EAAE,GAAG,UAAU,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE;QACjE,CAAC,CAAC,UAAU,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAsB;IACvD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAC7B,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CACnD,CAAC;IACF,MAAM,IAAI,GACR,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAEzE,OAAO,MAAM,CACX,eAAe,CAAC;QACd,OAAO,EAAE,MAAM,cAAc,EAAE;QAC/B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,UAAU,EAAE,MAAM,gBAAgB,CAAC,MAAM,CAAC,UAAU,CAAC;QACrD,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,KAAK;QACL,IAAI;QACJ,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE;QACxC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,OAAO,EAAE,MAAM,CAAC,OAAO;KACxB,CAAC,CACH,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"config-digest.js","sourceRoot":"","sources":["../../src/stamp/config-digest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAQ5C,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEtD;;;;;GAKG;AACH,KAAK,UAAU,cAAc;IAC3B,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAC7B,IAAI,GAAG,CAAC,oBAAoB,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,EAC9C,MAAM,CACP,CAAC;IACF,OAAQ,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAyB,CAAC,OAAO,CAAC;AAC/D,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,UAAU,CAAC,IAAgB;IACxC,MAAM,KAAK,GAAG,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrE,OAAO,MAAM,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;AAChF,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,WAAW,CAAC,MAAmB;IAC5C,OAAO,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,gBAAgB,CAAC,UAAsB;IACpD,OAAO,UAAU,CAAC,IAAI,KAAK,OAAO;QAChC,CAAC,CAAC,EAAE,GAAG,UAAU,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE;QACjE,CAAC,CAAC,UAAU,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAsB;IACvD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAC7B,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CACnD,CAAC;IACF,MAAM,IAAI,GACR,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAEzE,OAAO,MAAM,CACX,eAAe,CAAC;QACd,OAAO,EAAE,MAAM,cAAc,EAAE;QAC/B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,UAAU,EAAE,MAAM,gBAAgB,CAAC,MAAM,CAAC,UAAU,CAAC;QACrD,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,KAAK;QACL,IAAI;QACJ,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE;QACxC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,OAAO,EAAE,MAAM,CAAC,OAAO;KACxB,CAAC,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * The colour a texture draws in where the palette did not supply one.
3
+ *
4
+ * `resolveTexture` fills the foreground colour in for anything that came
5
+ * through config, so this is only reached by a texture built by hand, such as
6
+ * one a test or a custom template passes to `textureSvg` directly. It is here
7
+ * rather than in either drawing module because both of them need it.
8
+ */
9
+ export declare const fallbackColor = "#ffffff";
10
+ //# sourceMappingURL=color.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color.d.ts","sourceRoot":"","sources":["../../src/texture/color.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,YAAY,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * The colour a texture draws in where the palette did not supply one.
3
+ *
4
+ * `resolveTexture` fills the foreground colour in for anything that came
5
+ * through config, so this is only reached by a texture built by hand, such as
6
+ * one a test or a custom template passes to `textureSvg` directly. It is here
7
+ * rather than in either drawing module because both of them need it.
8
+ */
9
+ export const fallbackColor = "#ffffff";
10
+ //# sourceMappingURL=color.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color.js","sourceRoot":"","sources":["../../src/texture/color.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,SAAS,CAAC"}
@@ -2,7 +2,8 @@ import type { Dimensions, Texture } from "../types.js";
2
2
  export { resolveTexture } from "./resolve.js";
3
3
  /**
4
4
  * Render the treatment laid over a background as SVG, naming whatever it needs
5
- * in `<defs>` after the given `id`.
5
+ * in `<defs>` after the given `id`. Not every treatment needs one: `waves` is
6
+ * plain elements and names nothing.
6
7
  *
7
8
  * It is drawn between the background and whatever a template draws, so a
8
9
  * texture never comes between a headline and the reader.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/texture/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAIvD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,UAAU,EACtB,EAAE,EAAE,MAAM,GACT,MAAM,CAUR"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/texture/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAKvD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,UAAU,EACtB,EAAE,EAAE,MAAM,GACT,MAAM,CAcR"}
@@ -1,9 +1,11 @@
1
1
  import { grainSvg } from "./grain.js";
2
2
  import { dotsSvg, rulesSvg } from "./pattern.js";
3
+ import { wavesSvg } from "./waves.js";
3
4
  export { resolveTexture } from "./resolve.js";
4
5
  /**
5
6
  * Render the treatment laid over a background as SVG, naming whatever it needs
6
- * in `<defs>` after the given `id`.
7
+ * in `<defs>` after the given `id`. Not every treatment needs one: `waves` is
8
+ * plain elements and names nothing.
7
9
  *
8
10
  * It is drawn between the background and whatever a template draws, so a
9
11
  * texture never comes between a headline and the reader.
@@ -15,6 +17,9 @@ export function textureSvg(texture, dimensions, id) {
15
17
  if (texture.type === "dots") {
16
18
  return dotsSvg(texture, dimensions, id);
17
19
  }
20
+ if (texture.type === "waves") {
21
+ return wavesSvg(texture, dimensions);
22
+ }
18
23
  return rulesSvg(texture, dimensions, id);
19
24
  }
20
25
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/texture/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CACxB,OAAgB,EAChB,UAAsB,EACtB,EAAU;IAEV,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC7B,OAAO,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC5B,OAAO,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;AAC3C,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/texture/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CACxB,OAAgB,EAChB,UAAsB,EACtB,EAAU;IAEV,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC7B,OAAO,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC5B,OAAO,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC7B,OAAO,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;AAC3C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"pattern.d.ts","sourceRoot":"","sources":["../../src/texture/pattern.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAiCvD,qCAAqC;AACrC,wBAAgB,OAAO,CACrB,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EACpD,UAAU,EAAE,UAAU,EACtB,EAAE,EAAE,MAAM,GACT,MAAM,CAgBR;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CACtB,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,EACrD,UAAU,EAAE,UAAU,EACtB,EAAE,EAAE,MAAM,GACT,MAAM,CAiBR"}
1
+ {"version":3,"file":"pattern.d.ts","sourceRoot":"","sources":["../../src/texture/pattern.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AA+BvD,qCAAqC;AACrC,wBAAgB,OAAO,CACrB,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EACpD,UAAU,EAAE,UAAU,EACtB,EAAE,EAAE,MAAM,GACT,MAAM,CAgBR;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CACtB,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,EACrD,UAAU,EAAE,UAAU,EACtB,EAAE,EAAE,MAAM,GACT,MAAM,CAiBR"}
@@ -1,5 +1,4 @@
1
- /** Used where the palette did not supply one, so a texture always draws. */
2
- const fallbackColor = "#ffffff";
1
+ import { fallbackColor } from "./color.js";
3
2
  const dotDefaults = { opacity: 0.08, size: 5, gap: 44 };
4
3
  const ruleDefaults = { opacity: 0.06, width: 2, gap: 28, angle: 45 };
5
4
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"pattern.js","sourceRoot":"","sources":["../../src/texture/pattern.ts"],"names":[],"mappings":"AAEA,4EAA4E;AAC5E,MAAM,aAAa,GAAG,SAAS,CAAC;AAEhC,MAAM,WAAW,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;AACxD,MAAM,YAAY,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AAErE;;;GAGG;AACH,SAAS,IAAI,CACX,EAAU,EACV,GAAW,EACX,QAAgB,EAChB,SAAiB,EACjB,UAAsB,EACtB,OAAe;IAEf,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC;IACrC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAEzB,OAAO,CACL,QAAQ;QACR,gBAAgB,EAAE,YAAY,IAAI,aAAa,IAAI,GAAG;QACtD,iCAAiC,SAAS,IAAI,QAAQ,YAAY;QAClE,SAAS;QACT,gBAAgB,MAAM,CAAC,KAAK,CAAC,aAAa,MAAM,CAAC,MAAM,CAAC,GAAG;QAC3D,eAAe,EAAE,eAAe,MAAM,CAAC,OAAO,CAAC,KAAK,CACrD,CAAC;AACJ,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,OAAO,CACrB,OAAoD,EACpD,UAAsB,EACtB,EAAU;IAEV,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,WAAW,CAAC,GAAG,CAAC;IAC3C,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAC/B,MAAM,GAAG,GACP,eAAe,MAAM,SAAS,MAAM,GAAG;QACvC,OAAO,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG;QACxD,UAAU,OAAO,CAAC,KAAK,IAAI,aAAa,KAAK,CAAC;IAEhD,OAAO,IAAI,CACT,EAAE,EACF,GAAG,EACH,GAAG,EACH,EAAE,EACF,UAAU,EACV,OAAO,CAAC,OAAO,IAAI,WAAW,CAAC,OAAO,CACvC,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ,CACtB,OAAqD,EACrD,UAAsB,EACtB,EAAU;IAEV,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC;IAC5C,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAC1B,MAAM,IAAI,GACR,aAAa,CAAC,gBAAgB,CAAC,SAAS,MAAM,CAAC,GAAG,CAAC,GAAG;QACtD,YAAY,OAAO,CAAC,KAAK,IAAI,aAAa,GAAG;QAC7C,kBAAkB,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC;IACrE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC;IAElD,OAAO,IAAI,CACT,EAAE,EACF,GAAG,EACH,IAAI,EACJ,6BAA6B,MAAM,CAAC,KAAK,CAAC,IAAI,EAC9C,UAAU,EACV,OAAO,CAAC,OAAO,IAAI,YAAY,CAAC,OAAO,CACxC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"pattern.js","sourceRoot":"","sources":["../../src/texture/pattern.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,WAAW,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;AACxD,MAAM,YAAY,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AAErE;;;GAGG;AACH,SAAS,IAAI,CACX,EAAU,EACV,GAAW,EACX,QAAgB,EAChB,SAAiB,EACjB,UAAsB,EACtB,OAAe;IAEf,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC;IACrC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAEzB,OAAO,CACL,QAAQ;QACR,gBAAgB,EAAE,YAAY,IAAI,aAAa,IAAI,GAAG;QACtD,iCAAiC,SAAS,IAAI,QAAQ,YAAY;QAClE,SAAS;QACT,gBAAgB,MAAM,CAAC,KAAK,CAAC,aAAa,MAAM,CAAC,MAAM,CAAC,GAAG;QAC3D,eAAe,EAAE,eAAe,MAAM,CAAC,OAAO,CAAC,KAAK,CACrD,CAAC;AACJ,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,OAAO,CACrB,OAAoD,EACpD,UAAsB,EACtB,EAAU;IAEV,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,WAAW,CAAC,GAAG,CAAC;IAC3C,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAC/B,MAAM,GAAG,GACP,eAAe,MAAM,SAAS,MAAM,GAAG;QACvC,OAAO,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG;QACxD,UAAU,OAAO,CAAC,KAAK,IAAI,aAAa,KAAK,CAAC;IAEhD,OAAO,IAAI,CACT,EAAE,EACF,GAAG,EACH,GAAG,EACH,EAAE,EACF,UAAU,EACV,OAAO,CAAC,OAAO,IAAI,WAAW,CAAC,OAAO,CACvC,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ,CACtB,OAAqD,EACrD,UAAsB,EACtB,EAAU;IAEV,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC;IAC5C,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAC1B,MAAM,IAAI,GACR,aAAa,CAAC,gBAAgB,CAAC,SAAS,MAAM,CAAC,GAAG,CAAC,GAAG;QACtD,YAAY,OAAO,CAAC,KAAK,IAAI,aAAa,GAAG;QAC7C,kBAAkB,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC;IACrE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC;IAElD,OAAO,IAAI,CACT,EAAE,EACF,GAAG,EACH,IAAI,EACJ,6BAA6B,MAAM,CAAC,KAAK,CAAC,IAAI,EAC9C,UAAU,EACV,OAAO,CAAC,OAAO,IAAI,YAAY,CAAC,OAAO,CACxC,CAAC;AACJ,CAAC"}
@@ -3,10 +3,11 @@ import type { BrandColors, Texture } from "../types.js";
3
3
  * Fill in the colour a texture left open, from the palette it will be drawn
4
4
  * over.
5
5
  *
6
- * A dot grid or a set of rules has to be the foreground colour by default,
7
- * because that is the one colour known to contrast with the background: a
8
- * fixed white would disappear on a light theme, which is a texture that
9
- * silently does nothing. Grain has no colour to fill in, being noise.
6
+ * A dot grid, a set of rules or a set of rings has to be the foreground colour
7
+ * by default, because that is the one colour known to contrast with the
8
+ * background: a fixed white would disappear on a light theme, which is a
9
+ * texture that silently does nothing. Grain has no colour to fill in, being
10
+ * noise.
10
11
  *
11
12
  * It happens here rather than while drawing so that the resolved config says
12
13
  * what will actually be drawn, which is also what the rebuild stamp hashes: a