obsidian-integration-testing 10.1.0 → 10.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Lazily loads `sharp`, the OPTIONAL peer dependency the image helpers need, and
5
+ * describes the slice of its surface they use.
6
+ *
7
+ * The load is deferred because a static import would drag `sharp`'s
8
+ * platform-specific native binaries into every consumer of this package's index,
9
+ * when only screenshot post-processing needs them. The type is structural for
10
+ * the same reason: this module type-checks without `sharp`'s own types being
11
+ * resolvable.
12
+ */
13
+ /**
14
+ * A layer passed to `sharp`'s `composite`.
15
+ */
16
+ export interface SharpCompositeLayer {
17
+ readonly input: Buffer;
18
+ readonly left: number;
19
+ readonly top: number;
20
+ }
21
+ /**
22
+ * The `sharp` entry point the image helpers use.
23
+ */
24
+ export type SharpFactory = (input: Uint8Array) => SharpInstance;
25
+ /**
26
+ * One `sharp` pipeline.
27
+ */
28
+ export interface SharpInstance {
29
+ blur(this: void, sigma: number): SharpInstance;
30
+ composite(this: void, layers: SharpCompositeLayer[]): SharpInstance;
31
+ metadata(this: void): Promise<SharpMetadata>;
32
+ png(this: void): SharpInstance;
33
+ resize(this: void, width: number, height: number, options?: SharpResizeOptions): SharpInstance;
34
+ toBuffer(this: void): Promise<Buffer>;
35
+ }
36
+ /**
37
+ * The subset of `sharp`'s metadata the image helpers read.
38
+ */
39
+ export interface SharpMetadata {
40
+ readonly height?: number | undefined;
41
+ readonly width?: number | undefined;
42
+ }
43
+ /**
44
+ * The subset of `sharp`'s resize options the image helpers set.
45
+ */
46
+ export interface SharpResizeOptions {
47
+ readonly fit: 'cover' | 'fill';
48
+ }
49
+ /**
50
+ * Loads `sharp` on demand.
51
+ *
52
+ * @param caller - Name of the calling helper, so the error says which one needs it.
53
+ * @returns A {@link Promise} that resolves to the `sharp` factory.
54
+ * @throws Error naming the missing optional peer dependency.
55
+ */
56
+ export declare function importSharp(caller: string): Promise<SharpFactory>;
@@ -0,0 +1,117 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Fits a screenshot onto a canvas of a different aspect ratio without cropping
5
+ * it or distorting it, filling the leftover margins with a blurred, enlarged
6
+ * copy of the same image (the "pillarbox" treatment used by store listings).
7
+ *
8
+ * The motivating case is a mobile store screenshot. The Android emulator's
9
+ * framebuffer is whatever the AVD's screen is — a Pixel 10 Pro XL is 1344x2992,
10
+ * roughly 9:20 — while the community store asks for 900x1600 (9:16). Cropping
11
+ * to 9:16 throws away a fifth of the frame, and stretching distorts the UI, so
12
+ * the image is scaled to fit the HEIGHT and the two side margins are filled.
13
+ *
14
+ * The geometry is a pure function so it can be unit-tested; the pixel work needs
15
+ * `sharp`, which is an OPTIONAL peer dependency — declared rather than bundled
16
+ * because only screenshot capture needs it, and it ships platform-specific
17
+ * native binaries that every other consumer would pay for.
18
+ */
19
+ /**
20
+ * Parameters for {@link computeFitToCanvas}.
21
+ */
22
+ export interface ComputeFitToCanvasParams {
23
+ /**
24
+ * Height of the target canvas, in pixels.
25
+ */
26
+ readonly canvasHeightInPixels: number;
27
+ /**
28
+ * Width of the target canvas, in pixels.
29
+ */
30
+ readonly canvasWidthInPixels: number;
31
+ /**
32
+ * Height of the source image, in pixels.
33
+ */
34
+ readonly sourceHeightInPixels: number;
35
+ /**
36
+ * Width of the source image, in pixels.
37
+ */
38
+ readonly sourceWidthInPixels: number;
39
+ }
40
+ /**
41
+ * Options for {@link fitScreenshotToCanvas}.
42
+ */
43
+ export interface FitScreenshotToCanvasOptions {
44
+ /**
45
+ * Gaussian blur strength applied to the margin fill.
46
+ *
47
+ * @default `24`
48
+ */
49
+ readonly blurSigma?: number;
50
+ /**
51
+ * Height of the target canvas, in pixels.
52
+ */
53
+ readonly canvasHeightInPixels: number;
54
+ /**
55
+ * Width of the target canvas, in pixels.
56
+ */
57
+ readonly canvasWidthInPixels: number;
58
+ }
59
+ /**
60
+ * Where the scaled source image sits on the canvas.
61
+ */
62
+ export interface FitToCanvasGeometry {
63
+ /**
64
+ * Width of each side margin, in pixels. Both sides are equal by construction.
65
+ */
66
+ readonly marginInPixels: number;
67
+ /**
68
+ * Left offset of the scaled image on the canvas, in pixels.
69
+ */
70
+ readonly offsetXInPixels: number;
71
+ /**
72
+ * Top offset of the scaled image on the canvas, in pixels.
73
+ */
74
+ readonly offsetYInPixels: number;
75
+ /**
76
+ * Height the source is scaled to, in pixels.
77
+ */
78
+ readonly scaledHeightInPixels: number;
79
+ /**
80
+ * Width the source is scaled to, in pixels.
81
+ */
82
+ readonly scaledWidthInPixels: number;
83
+ }
84
+ /**
85
+ * Computes how a source image is scaled and placed to fill a canvas's height,
86
+ * with equal margins on the left and right.
87
+ *
88
+ * The scaled width is rounded to the nearest integer that leaves an EVEN
89
+ * remainder, so the two margins are exactly equal — an asymmetric pillarbox is
90
+ * visible at a glance and looks like a mistake. Where both neighbors qualify,
91
+ * the one closer to the true scaled width wins, so the aspect error stays below
92
+ * one part in a thousand.
93
+ *
94
+ * Worked example, the mobile store case: a 1344x2992 frame onto a 900x1600
95
+ * canvas scales by `1600/2992` to 718.72 wide. 719 would leave a 181px
96
+ * remainder, which cannot split evenly, so 718 is chosen (margin 91) over 720
97
+ * (margin 90) because 718 is nearer 718.72.
98
+ *
99
+ * @param params - The source and canvas dimensions.
100
+ * @returns The scaled size, the offsets, and the side margin.
101
+ * @throws Error if any dimension is not a positive number.
102
+ */
103
+ export declare function computeFitToCanvas(params: ComputeFitToCanvasParams): FitToCanvasGeometry;
104
+ /**
105
+ * Scales a screenshot to fill a canvas's height and fills the side margins with
106
+ * a blurred, enlarged copy of the same image.
107
+ *
108
+ * Nothing is cropped and nothing is stretched: the visible screenshot keeps its
109
+ * aspect ratio to within a rounding pixel, and the margins are made of the
110
+ * image itself rather than a flat color, so the result reads as one frame.
111
+ *
112
+ * @param bytes - The source PNG.
113
+ * @param options - The target canvas size and blur strength.
114
+ * @returns A {@link Promise} that resolves to the composed PNG, exactly the canvas size.
115
+ * @throws Error if `sharp` is not installed, or the source dimensions cannot be read.
116
+ */
117
+ export declare function fitScreenshotToCanvas(bytes: Uint8Array, options: FitScreenshotToCanvasOptions): Promise<Uint8Array>;
@@ -0,0 +1,78 @@
1
+ import { importSharp } from "./sharp-loader.mjs";
2
+ const DEFAULT_BLUR_SIGMA = 24;
3
+ const MARGIN_SIDES = 2;
4
+ function computeFitToCanvas(params) {
5
+ const {
6
+ canvasHeightInPixels,
7
+ canvasWidthInPixels,
8
+ sourceHeightInPixels,
9
+ sourceWidthInPixels
10
+ } = params;
11
+ const namedDimensions = [
12
+ ["canvasHeightInPixels", canvasHeightInPixels],
13
+ ["canvasWidthInPixels", canvasWidthInPixels],
14
+ ["sourceHeightInPixels", sourceHeightInPixels],
15
+ ["sourceWidthInPixels", sourceWidthInPixels]
16
+ ];
17
+ for (const [name, value] of namedDimensions) {
18
+ if (!Number.isFinite(value) || value <= 0) {
19
+ throw new Error(`computeFitToCanvas: ${name} must be a positive number, got ${String(value)}.`);
20
+ }
21
+ }
22
+ const scaledHeightInPixels = canvasHeightInPixels;
23
+ const exactScaledWidth = sourceWidthInPixels * (canvasHeightInPixels / sourceHeightInPixels);
24
+ const scaledWidthInPixels = roundToMatchingParity(exactScaledWidth, canvasWidthInPixels);
25
+ if (scaledWidthInPixels > canvasWidthInPixels) {
26
+ throw new Error(
27
+ `computeFitToCanvas: the source is wider than the canvas once scaled to its height (${String(scaledWidthInPixels)} > ${String(canvasWidthInPixels)}); this fits by height and cannot letterbox.`
28
+ );
29
+ }
30
+ const marginInPixels = (canvasWidthInPixels - scaledWidthInPixels) / MARGIN_SIDES;
31
+ return {
32
+ marginInPixels,
33
+ offsetXInPixels: marginInPixels,
34
+ offsetYInPixels: 0,
35
+ scaledHeightInPixels,
36
+ scaledWidthInPixels
37
+ };
38
+ }
39
+ async function fitScreenshotToCanvas(bytes, options) {
40
+ const {
41
+ blurSigma = DEFAULT_BLUR_SIGMA,
42
+ canvasHeightInPixels,
43
+ canvasWidthInPixels
44
+ } = options;
45
+ const sharp = await importSharp("fitScreenshotToCanvas");
46
+ const metadata = await sharp(bytes).metadata();
47
+ const sourceWidthInPixels = metadata.width;
48
+ const sourceHeightInPixels = metadata.height;
49
+ if (sourceWidthInPixels === void 0 || sourceHeightInPixels === void 0) {
50
+ throw new Error("fitScreenshotToCanvas: could not read the source image dimensions.");
51
+ }
52
+ const geometry = computeFitToCanvas({
53
+ canvasHeightInPixels,
54
+ canvasWidthInPixels,
55
+ sourceHeightInPixels,
56
+ sourceWidthInPixels
57
+ });
58
+ const background = await sharp(bytes).resize(canvasWidthInPixels, canvasHeightInPixels, { fit: "cover" }).blur(blurSigma).toBuffer();
59
+ const foreground = await sharp(bytes).resize(geometry.scaledWidthInPixels, geometry.scaledHeightInPixels, { fit: "fill" }).toBuffer();
60
+ const composed = await sharp(background).composite([{
61
+ input: foreground,
62
+ left: geometry.offsetXInPixels,
63
+ top: geometry.offsetYInPixels
64
+ }]).png().toBuffer();
65
+ return new Uint8Array(composed);
66
+ }
67
+ function roundToMatchingParity(value, target) {
68
+ const rounded = Math.round(value);
69
+ if ((target - rounded) % MARGIN_SIDES === 0) {
70
+ return rounded;
71
+ }
72
+ return value >= rounded ? rounded + 1 : rounded - 1;
73
+ }
74
+ export {
75
+ computeFitToCanvas,
76
+ fitScreenshotToCanvas
77
+ };
78
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2ZpdC1zY3JlZW5zaG90LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogRml0cyBhIHNjcmVlbnNob3Qgb250byBhIGNhbnZhcyBvZiBhIGRpZmZlcmVudCBhc3BlY3QgcmF0aW8gd2l0aG91dCBjcm9wcGluZ1xuICogaXQgb3IgZGlzdG9ydGluZyBpdCwgZmlsbGluZyB0aGUgbGVmdG92ZXIgbWFyZ2lucyB3aXRoIGEgYmx1cnJlZCwgZW5sYXJnZWRcbiAqIGNvcHkgb2YgdGhlIHNhbWUgaW1hZ2UgKHRoZSBcInBpbGxhcmJveFwiIHRyZWF0bWVudCB1c2VkIGJ5IHN0b3JlIGxpc3RpbmdzKS5cbiAqXG4gKiBUaGUgbW90aXZhdGluZyBjYXNlIGlzIGEgbW9iaWxlIHN0b3JlIHNjcmVlbnNob3QuIFRoZSBBbmRyb2lkIGVtdWxhdG9yJ3NcbiAqIGZyYW1lYnVmZmVyIGlzIHdoYXRldmVyIHRoZSBBVkQncyBzY3JlZW4gaXMgXHUyMDE0IGEgUGl4ZWwgMTAgUHJvIFhMIGlzIDEzNDR4Mjk5MixcbiAqIHJvdWdobHkgOToyMCBcdTIwMTQgd2hpbGUgdGhlIGNvbW11bml0eSBzdG9yZSBhc2tzIGZvciA5MDB4MTYwMCAoOToxNikuIENyb3BwaW5nXG4gKiB0byA5OjE2IHRocm93cyBhd2F5IGEgZmlmdGggb2YgdGhlIGZyYW1lLCBhbmQgc3RyZXRjaGluZyBkaXN0b3J0cyB0aGUgVUksIHNvXG4gKiB0aGUgaW1hZ2UgaXMgc2NhbGVkIHRvIGZpdCB0aGUgSEVJR0hUIGFuZCB0aGUgdHdvIHNpZGUgbWFyZ2lucyBhcmUgZmlsbGVkLlxuICpcbiAqIFRoZSBnZW9tZXRyeSBpcyBhIHB1cmUgZnVuY3Rpb24gc28gaXQgY2FuIGJlIHVuaXQtdGVzdGVkOyB0aGUgcGl4ZWwgd29yayBuZWVkc1xuICogYHNoYXJwYCwgd2hpY2ggaXMgYW4gT1BUSU9OQUwgcGVlciBkZXBlbmRlbmN5IFx1MjAxNCBkZWNsYXJlZCByYXRoZXIgdGhhbiBidW5kbGVkXG4gKiBiZWNhdXNlIG9ubHkgc2NyZWVuc2hvdCBjYXB0dXJlIG5lZWRzIGl0LCBhbmQgaXQgc2hpcHMgcGxhdGZvcm0tc3BlY2lmaWNcbiAqIG5hdGl2ZSBiaW5hcmllcyB0aGF0IGV2ZXJ5IG90aGVyIGNvbnN1bWVyIHdvdWxkIHBheSBmb3IuXG4gKi9cblxuaW1wb3J0IHsgaW1wb3J0U2hhcnAgfSBmcm9tICcuL3NoYXJwLWxvYWRlci5tanMnO1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBjb21wdXRlRml0VG9DYW52YXN9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbXB1dGVGaXRUb0NhbnZhc1BhcmFtcyB7XG4gIC8qKlxuICAgKiBIZWlnaHQgb2YgdGhlIHRhcmdldCBjYW52YXMsIGluIHBpeGVscy5cbiAgICovXG4gIHJlYWRvbmx5IGNhbnZhc0hlaWdodEluUGl4ZWxzOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFdpZHRoIG9mIHRoZSB0YXJnZXQgY2FudmFzLCBpbiBwaXhlbHMuXG4gICAqL1xuICByZWFkb25seSBjYW52YXNXaWR0aEluUGl4ZWxzOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEhlaWdodCBvZiB0aGUgc291cmNlIGltYWdlLCBpbiBwaXhlbHMuXG4gICAqL1xuICByZWFkb25seSBzb3VyY2VIZWlnaHRJblBpeGVsczogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBXaWR0aCBvZiB0aGUgc291cmNlIGltYWdlLCBpbiBwaXhlbHMuXG4gICAqL1xuICByZWFkb25seSBzb3VyY2VXaWR0aEluUGl4ZWxzOiBudW1iZXI7XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3Ige0BsaW5rIGZpdFNjcmVlbnNob3RUb0NhbnZhc30uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRml0U2NyZWVuc2hvdFRvQ2FudmFzT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBHYXVzc2lhbiBibHVyIHN0cmVuZ3RoIGFwcGxpZWQgdG8gdGhlIG1hcmdpbiBmaWxsLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgMjRgXG4gICAqL1xuICByZWFkb25seSBibHVyU2lnbWE/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEhlaWdodCBvZiB0aGUgdGFyZ2V0IGNhbnZhcywgaW4gcGl4ZWxzLlxuICAgKi9cbiAgcmVhZG9ubHkgY2FudmFzSGVpZ2h0SW5QaXhlbHM6IG51bWJlcjtcblxuICAvKipcbiAgICogV2lkdGggb2YgdGhlIHRhcmdldCBjYW52YXMsIGluIHBpeGVscy5cbiAgICovXG4gIHJlYWRvbmx5IGNhbnZhc1dpZHRoSW5QaXhlbHM6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBXaGVyZSB0aGUgc2NhbGVkIHNvdXJjZSBpbWFnZSBzaXRzIG9uIHRoZSBjYW52YXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRml0VG9DYW52YXNHZW9tZXRyeSB7XG4gIC8qKlxuICAgKiBXaWR0aCBvZiBlYWNoIHNpZGUgbWFyZ2luLCBpbiBwaXhlbHMuIEJvdGggc2lkZXMgYXJlIGVxdWFsIGJ5IGNvbnN0cnVjdGlvbi5cbiAgICovXG4gIHJlYWRvbmx5IG1hcmdpbkluUGl4ZWxzOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIExlZnQgb2Zmc2V0IG9mIHRoZSBzY2FsZWQgaW1hZ2Ugb24gdGhlIGNhbnZhcywgaW4gcGl4ZWxzLlxuICAgKi9cbiAgcmVhZG9ubHkgb2Zmc2V0WEluUGl4ZWxzOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRvcCBvZmZzZXQgb2YgdGhlIHNjYWxlZCBpbWFnZSBvbiB0aGUgY2FudmFzLCBpbiBwaXhlbHMuXG4gICAqL1xuICByZWFkb25seSBvZmZzZXRZSW5QaXhlbHM6IG51bWJlcjtcblxuICAvKipcbiAgICogSGVpZ2h0IHRoZSBzb3VyY2UgaXMgc2NhbGVkIHRvLCBpbiBwaXhlbHMuXG4gICAqL1xuICByZWFkb25seSBzY2FsZWRIZWlnaHRJblBpeGVsczogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBXaWR0aCB0aGUgc291cmNlIGlzIHNjYWxlZCB0bywgaW4gcGl4ZWxzLlxuICAgKi9cbiAgcmVhZG9ubHkgc2NhbGVkV2lkdGhJblBpeGVsczogbnVtYmVyO1xufVxuXG4vKipcbiAqIERlZmF1bHQgR2F1c3NpYW4gYmx1ciBzdHJlbmd0aCBmb3IgdGhlIG1hcmdpbiBmaWxsOiBzb2Z0IGVub3VnaCB0aGF0IG5vXG4gKiBkZXRhaWwgcmVhZHMgYXMgY29udGVudCwgZ2VudGxlIGVub3VnaCB0byBrZWVwIHRoZSBmcmFtZSdzIGNvbG9ycy5cbiAqL1xuY29uc3QgREVGQVVMVF9CTFVSX1NJR01BID0gMjQ7XG5cbi8qKlxuICogVGhlIG51bWJlciBvZiBzaWRlIG1hcmdpbnMgdGhlIGxlZnRvdmVyIHdpZHRoIGlzIHNwbGl0IGJldHdlZW4uXG4gKi9cbmNvbnN0IE1BUkdJTl9TSURFUyA9IDI7XG5cbi8qKlxuICogQ29tcHV0ZXMgaG93IGEgc291cmNlIGltYWdlIGlzIHNjYWxlZCBhbmQgcGxhY2VkIHRvIGZpbGwgYSBjYW52YXMncyBoZWlnaHQsXG4gKiB3aXRoIGVxdWFsIG1hcmdpbnMgb24gdGhlIGxlZnQgYW5kIHJpZ2h0LlxuICpcbiAqIFRoZSBzY2FsZWQgd2lkdGggaXMgcm91bmRlZCB0byB0aGUgbmVhcmVzdCBpbnRlZ2VyIHRoYXQgbGVhdmVzIGFuIEVWRU5cbiAqIHJlbWFpbmRlciwgc28gdGhlIHR3byBtYXJnaW5zIGFyZSBleGFjdGx5IGVxdWFsIFx1MjAxNCBhbiBhc3ltbWV0cmljIHBpbGxhcmJveCBpc1xuICogdmlzaWJsZSBhdCBhIGdsYW5jZSBhbmQgbG9va3MgbGlrZSBhIG1pc3Rha2UuIFdoZXJlIGJvdGggbmVpZ2hib3JzIHF1YWxpZnksXG4gKiB0aGUgb25lIGNsb3NlciB0byB0aGUgdHJ1ZSBzY2FsZWQgd2lkdGggd2lucywgc28gdGhlIGFzcGVjdCBlcnJvciBzdGF5cyBiZWxvd1xuICogb25lIHBhcnQgaW4gYSB0aG91c2FuZC5cbiAqXG4gKiBXb3JrZWQgZXhhbXBsZSwgdGhlIG1vYmlsZSBzdG9yZSBjYXNlOiBhIDEzNDR4Mjk5MiBmcmFtZSBvbnRvIGEgOTAweDE2MDBcbiAqIGNhbnZhcyBzY2FsZXMgYnkgYDE2MDAvMjk5MmAgdG8gNzE4LjcyIHdpZGUuIDcxOSB3b3VsZCBsZWF2ZSBhIDE4MXB4XG4gKiByZW1haW5kZXIsIHdoaWNoIGNhbm5vdCBzcGxpdCBldmVubHksIHNvIDcxOCBpcyBjaG9zZW4gKG1hcmdpbiA5MSkgb3ZlciA3MjBcbiAqIChtYXJnaW4gOTApIGJlY2F1c2UgNzE4IGlzIG5lYXJlciA3MTguNzIuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSBzb3VyY2UgYW5kIGNhbnZhcyBkaW1lbnNpb25zLlxuICogQHJldHVybnMgVGhlIHNjYWxlZCBzaXplLCB0aGUgb2Zmc2V0cywgYW5kIHRoZSBzaWRlIG1hcmdpbi5cbiAqIEB0aHJvd3MgRXJyb3IgaWYgYW55IGRpbWVuc2lvbiBpcyBub3QgYSBwb3NpdGl2ZSBudW1iZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlRml0VG9DYW52YXMocGFyYW1zOiBDb21wdXRlRml0VG9DYW52YXNQYXJhbXMpOiBGaXRUb0NhbnZhc0dlb21ldHJ5IHtcbiAgY29uc3Qge1xuICAgIGNhbnZhc0hlaWdodEluUGl4ZWxzLFxuICAgIGNhbnZhc1dpZHRoSW5QaXhlbHMsXG4gICAgc291cmNlSGVpZ2h0SW5QaXhlbHMsXG4gICAgc291cmNlV2lkdGhJblBpeGVsc1xuICB9ID0gcGFyYW1zO1xuXG4gIGNvbnN0IG5hbWVkRGltZW5zaW9uczogW3N0cmluZywgbnVtYmVyXVtdID0gW1xuICAgIFsnY2FudmFzSGVpZ2h0SW5QaXhlbHMnLCBjYW52YXNIZWlnaHRJblBpeGVsc10sXG4gICAgWydjYW52YXNXaWR0aEluUGl4ZWxzJywgY2FudmFzV2lkdGhJblBpeGVsc10sXG4gICAgWydzb3VyY2VIZWlnaHRJblBpeGVscycsIHNvdXJjZUhlaWdodEluUGl4ZWxzXSxcbiAgICBbJ3NvdXJjZVdpZHRoSW5QaXhlbHMnLCBzb3VyY2VXaWR0aEluUGl4ZWxzXVxuICBdO1xuXG4gIGZvciAoY29uc3QgW25hbWUsIHZhbHVlXSBvZiBuYW1lZERpbWVuc2lvbnMpIHtcbiAgICBpZiAoIU51bWJlci5pc0Zpbml0ZSh2YWx1ZSkgfHwgdmFsdWUgPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBjb21wdXRlRml0VG9DYW52YXM6ICR7bmFtZX0gbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlciwgZ290ICR7U3RyaW5nKHZhbHVlKX0uYCk7XG4gICAgfVxuICB9XG5cbiAgY29uc3Qgc2NhbGVkSGVpZ2h0SW5QaXhlbHMgPSBjYW52YXNIZWlnaHRJblBpeGVscztcbiAgY29uc3QgZXhhY3RTY2FsZWRXaWR0aCA9IHNvdXJjZVdpZHRoSW5QaXhlbHMgKiAoY2FudmFzSGVpZ2h0SW5QaXhlbHMgLyBzb3VyY2VIZWlnaHRJblBpeGVscyk7XG4gIGNvbnN0IHNjYWxlZFdpZHRoSW5QaXhlbHMgPSByb3VuZFRvTWF0Y2hpbmdQYXJpdHkoZXhhY3RTY2FsZWRXaWR0aCwgY2FudmFzV2lkdGhJblBpeGVscyk7XG5cbiAgaWYgKHNjYWxlZFdpZHRoSW5QaXhlbHMgPiBjYW52YXNXaWR0aEluUGl4ZWxzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ2NvbXB1dGVGaXRUb0NhbnZhczogdGhlIHNvdXJjZSBpcyB3aWRlciB0aGFuIHRoZSBjYW52YXMgb25jZSBzY2FsZWQgdG8gaXRzIGhlaWdodCAnXG4gICAgICAgICsgYCgke1N0cmluZyhzY2FsZWRXaWR0aEluUGl4ZWxzKX0gPiAke1N0cmluZyhjYW52YXNXaWR0aEluUGl4ZWxzKX0pOyB0aGlzIGZpdHMgYnkgaGVpZ2h0IGFuZCBjYW5ub3QgbGV0dGVyYm94LmBcbiAgICApO1xuICB9XG5cbiAgY29uc3QgbWFyZ2luSW5QaXhlbHMgPSAoY2FudmFzV2lkdGhJblBpeGVscyAtIHNjYWxlZFdpZHRoSW5QaXhlbHMpIC8gTUFSR0lOX1NJREVTO1xuXG4gIHJldHVybiB7XG4gICAgbWFyZ2luSW5QaXhlbHMsXG4gICAgb2Zmc2V0WEluUGl4ZWxzOiBtYXJnaW5JblBpeGVscyxcbiAgICBvZmZzZXRZSW5QaXhlbHM6IDAsXG4gICAgc2NhbGVkSGVpZ2h0SW5QaXhlbHMsXG4gICAgc2NhbGVkV2lkdGhJblBpeGVsc1xuICB9O1xufVxuXG4vKipcbiAqIFNjYWxlcyBhIHNjcmVlbnNob3QgdG8gZmlsbCBhIGNhbnZhcydzIGhlaWdodCBhbmQgZmlsbHMgdGhlIHNpZGUgbWFyZ2lucyB3aXRoXG4gKiBhIGJsdXJyZWQsIGVubGFyZ2VkIGNvcHkgb2YgdGhlIHNhbWUgaW1hZ2UuXG4gKlxuICogTm90aGluZyBpcyBjcm9wcGVkIGFuZCBub3RoaW5nIGlzIHN0cmV0Y2hlZDogdGhlIHZpc2libGUgc2NyZWVuc2hvdCBrZWVwcyBpdHNcbiAqIGFzcGVjdCByYXRpbyB0byB3aXRoaW4gYSByb3VuZGluZyBwaXhlbCwgYW5kIHRoZSBtYXJnaW5zIGFyZSBtYWRlIG9mIHRoZVxuICogaW1hZ2UgaXRzZWxmIHJhdGhlciB0aGFuIGEgZmxhdCBjb2xvciwgc28gdGhlIHJlc3VsdCByZWFkcyBhcyBvbmUgZnJhbWUuXG4gKlxuICogQHBhcmFtIGJ5dGVzIC0gVGhlIHNvdXJjZSBQTkcuXG4gKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSB0YXJnZXQgY2FudmFzIHNpemUgYW5kIGJsdXIgc3RyZW5ndGguXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHRvIHRoZSBjb21wb3NlZCBQTkcsIGV4YWN0bHkgdGhlIGNhbnZhcyBzaXplLlxuICogQHRocm93cyBFcnJvciBpZiBgc2hhcnBgIGlzIG5vdCBpbnN0YWxsZWQsIG9yIHRoZSBzb3VyY2UgZGltZW5zaW9ucyBjYW5ub3QgYmUgcmVhZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZpdFNjcmVlbnNob3RUb0NhbnZhcyhieXRlczogVWludDhBcnJheSwgb3B0aW9uczogRml0U2NyZWVuc2hvdFRvQ2FudmFzT3B0aW9ucyk6IFByb21pc2U8VWludDhBcnJheT4ge1xuICBjb25zdCB7XG4gICAgYmx1clNpZ21hID0gREVGQVVMVF9CTFVSX1NJR01BLFxuICAgIGNhbnZhc0hlaWdodEluUGl4ZWxzLFxuICAgIGNhbnZhc1dpZHRoSW5QaXhlbHNcbiAgfSA9IG9wdGlvbnM7XG5cbiAgY29uc3Qgc2hhcnAgPSBhd2FpdCBpbXBvcnRTaGFycCgnZml0U2NyZWVuc2hvdFRvQ2FudmFzJyk7XG4gIGNvbnN0IG1ldGFkYXRhID0gYXdhaXQgc2hhcnAoYnl0ZXMpLm1ldGFkYXRhKCk7XG4gIGNvbnN0IHNvdXJjZVdpZHRoSW5QaXhlbHMgPSBtZXRhZGF0YS53aWR0aDtcbiAgY29uc3Qgc291cmNlSGVpZ2h0SW5QaXhlbHMgPSBtZXRhZGF0YS5oZWlnaHQ7XG5cbiAgLyogdjggaWdub3JlIG5leHQgMyAtLSBEZWZlbnNpdmU6IGBzaGFycGAgcmVqZWN0cyBhIG5vbi1pbWFnZSBiZWZvcmUgaXQgY2FuIHJlcG9ydCBtZXRhZGF0YSB3aXRob3V0IGRpbWVuc2lvbnMsIHNvIHRoaXMgYnJhbmNoIGlzIHVucmVhY2hhYmxlIGZyb20gYSB0ZXN0LiAqL1xuICBpZiAoc291cmNlV2lkdGhJblBpeGVscyA9PT0gdW5kZWZpbmVkIHx8IHNvdXJjZUhlaWdodEluUGl4ZWxzID09PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ZpdFNjcmVlbnNob3RUb0NhbnZhczogY291bGQgbm90IHJlYWQgdGhlIHNvdXJjZSBpbWFnZSBkaW1lbnNpb25zLicpO1xuICB9XG5cbiAgY29uc3QgZ2VvbWV0cnkgPSBjb21wdXRlRml0VG9DYW52YXMoe1xuICAgIGNhbnZhc0hlaWdodEluUGl4ZWxzLFxuICAgIGNhbnZhc1dpZHRoSW5QaXhlbHMsXG4gICAgc291cmNlSGVpZ2h0SW5QaXhlbHMsXG4gICAgc291cmNlV2lkdGhJblBpeGVsc1xuICB9KTtcblxuICAvLyBUaGUgYmFja2dyb3VuZCBpcyB0aGUgc2FtZSBmcmFtZSBibG93biB1cCB0byBDT1ZFUiB0aGUgY2FudmFzIGFuZCBibHVycmVkLFxuICAvLyBTbyB0aGUgbWFyZ2lucyBjYXJyeSB0aGUgc2NyZWVuc2hvdCdzIG93biBjb2xvcnMgaW5zdGVhZCBvZiBhIGZsYXQgYmFyLlxuICBjb25zdCBiYWNrZ3JvdW5kID0gYXdhaXQgc2hhcnAoYnl0ZXMpXG4gICAgLnJlc2l6ZShjYW52YXNXaWR0aEluUGl4ZWxzLCBjYW52YXNIZWlnaHRJblBpeGVscywgeyBmaXQ6ICdjb3ZlcicgfSlcbiAgICAuYmx1cihibHVyU2lnbWEpXG4gICAgLnRvQnVmZmVyKCk7XG5cbiAgY29uc3QgZm9yZWdyb3VuZCA9IGF3YWl0IHNoYXJwKGJ5dGVzKVxuICAgIC5yZXNpemUoZ2VvbWV0cnkuc2NhbGVkV2lkdGhJblBpeGVscywgZ2VvbWV0cnkuc2NhbGVkSGVpZ2h0SW5QaXhlbHMsIHsgZml0OiAnZmlsbCcgfSlcbiAgICAudG9CdWZmZXIoKTtcblxuICBjb25zdCBjb21wb3NlZCA9IGF3YWl0IHNoYXJwKGJhY2tncm91bmQpXG4gICAgLmNvbXBvc2l0ZShbe1xuICAgICAgaW5wdXQ6IGZvcmVncm91bmQsXG4gICAgICBsZWZ0OiBnZW9tZXRyeS5vZmZzZXRYSW5QaXhlbHMsXG4gICAgICB0b3A6IGdlb21ldHJ5Lm9mZnNldFlJblBpeGVsc1xuICAgIH1dKVxuICAgIC5wbmcoKVxuICAgIC50b0J1ZmZlcigpO1xuXG4gIHJldHVybiBuZXcgVWludDhBcnJheShjb21wb3NlZCk7XG59XG5cbi8qKlxuICogUm91bmRzIGEgd2lkdGggdG8gdGhlIG5lYXJlc3QgaW50ZWdlciBzaGFyaW5nIGB0YXJnZXRgJ3MgcGFyaXR5LCBzb1xuICogYHRhcmdldCAtIHJlc3VsdGAgaXMgZXZlbiBhbmQgc3BsaXRzIGludG8gdHdvIGVxdWFsIG1hcmdpbnMuXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIGV4YWN0IHNjYWxlZCB3aWR0aC5cbiAqIEBwYXJhbSB0YXJnZXQgLSBUaGUgY2FudmFzIHdpZHRoIHdob3NlIHBhcml0eSBtdXN0IGJlIG1hdGNoZWQuXG4gKiBAcmV0dXJucyBUaGUgbmVhcmVzdCBpbnRlZ2VyIG9mIHRoZSBzYW1lIHBhcml0eSBhcyBgdGFyZ2V0YC5cbiAqL1xuZnVuY3Rpb24gcm91bmRUb01hdGNoaW5nUGFyaXR5KHZhbHVlOiBudW1iZXIsIHRhcmdldDogbnVtYmVyKTogbnVtYmVyIHtcbiAgY29uc3Qgcm91bmRlZCA9IE1hdGgucm91bmQodmFsdWUpO1xuICBpZiAoKHRhcmdldCAtIHJvdW5kZWQpICUgTUFSR0lOX1NJREVTID09PSAwKSB7XG4gICAgcmV0dXJuIHJvdW5kZWQ7XG4gIH1cblxuICAvLyBgcm91bmRlZGAgbGVhdmVzIGFuIG9kZCByZW1haW5kZXIsIHNvIHN0ZXAgdG8gd2hpY2hldmVyIG5laWdoYm9yIGlzIGNsb3NlclxuICAvLyBUbyB0aGUgdHJ1ZSB2YWx1ZTsgYm90aCBoYXZlIHRoZSBwYXJpdHkgYHJvdW5kZWRgIGxhY2tzLlxuICByZXR1cm4gdmFsdWUgPj0gcm91bmRlZCA/IHJvdW5kZWQgKyAxIDogcm91bmRlZCAtIDE7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiQUFtQkEsU0FBUyxtQkFBbUI7QUFtRjVCLE1BQU0scUJBQXFCO0FBSzNCLE1BQU0sZUFBZTtBQXFCZCxTQUFTLG1CQUFtQixRQUF1RDtBQUN4RixRQUFNO0FBQUEsSUFDSjtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLEVBQ0YsSUFBSTtBQUVKLFFBQU0sa0JBQXNDO0FBQUEsSUFDMUMsQ0FBQyx3QkFBd0Isb0JBQW9CO0FBQUEsSUFDN0MsQ0FBQyx1QkFBdUIsbUJBQW1CO0FBQUEsSUFDM0MsQ0FBQyx3QkFBd0Isb0JBQW9CO0FBQUEsSUFDN0MsQ0FBQyx1QkFBdUIsbUJBQW1CO0FBQUEsRUFDN0M7QUFFQSxhQUFXLENBQUMsTUFBTSxLQUFLLEtBQUssaUJBQWlCO0FBQzNDLFFBQUksQ0FBQyxPQUFPLFNBQVMsS0FBSyxLQUFLLFNBQVMsR0FBRztBQUN6QyxZQUFNLElBQUksTUFBTSx1QkFBdUIsSUFBSSxtQ0FBbUMsT0FBTyxLQUFLLENBQUMsR0FBRztBQUFBLElBQ2hHO0FBQUEsRUFDRjtBQUVBLFFBQU0sdUJBQXVCO0FBQzdCLFFBQU0sbUJBQW1CLHVCQUF1Qix1QkFBdUI7QUFDdkUsUUFBTSxzQkFBc0Isc0JBQXNCLGtCQUFrQixtQkFBbUI7QUFFdkYsTUFBSSxzQkFBc0IscUJBQXFCO0FBQzdDLFVBQU0sSUFBSTtBQUFBLE1BQ1Isc0ZBQ1EsT0FBTyxtQkFBbUIsQ0FBQyxNQUFNLE9BQU8sbUJBQW1CLENBQUM7QUFBQSxJQUN0RTtBQUFBLEVBQ0Y7QUFFQSxRQUFNLGtCQUFrQixzQkFBc0IsdUJBQXVCO0FBRXJFLFNBQU87QUFBQSxJQUNMO0FBQUEsSUFDQSxpQkFBaUI7QUFBQSxJQUNqQixpQkFBaUI7QUFBQSxJQUNqQjtBQUFBLElBQ0E7QUFBQSxFQUNGO0FBQ0Y7QUFlQSxlQUFzQixzQkFBc0IsT0FBbUIsU0FBNEQ7QUFDekgsUUFBTTtBQUFBLElBQ0osWUFBWTtBQUFBLElBQ1o7QUFBQSxJQUNBO0FBQUEsRUFDRixJQUFJO0FBRUosUUFBTSxRQUFRLE1BQU0sWUFBWSx1QkFBdUI7QUFDdkQsUUFBTSxXQUFXLE1BQU0sTUFBTSxLQUFLLEVBQUUsU0FBUztBQUM3QyxRQUFNLHNCQUFzQixTQUFTO0FBQ3JDLFFBQU0sdUJBQXVCLFNBQVM7QUFHdEMsTUFBSSx3QkFBd0IsVUFBYSx5QkFBeUIsUUFBVztBQUMzRSxVQUFNLElBQUksTUFBTSxvRUFBb0U7QUFBQSxFQUN0RjtBQUVBLFFBQU0sV0FBVyxtQkFBbUI7QUFBQSxJQUNsQztBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLEVBQ0YsQ0FBQztBQUlELFFBQU0sYUFBYSxNQUFNLE1BQU0sS0FBSyxFQUNqQyxPQUFPLHFCQUFxQixzQkFBc0IsRUFBRSxLQUFLLFFBQVEsQ0FBQyxFQUNsRSxLQUFLLFNBQVMsRUFDZCxTQUFTO0FBRVosUUFBTSxhQUFhLE1BQU0sTUFBTSxLQUFLLEVBQ2pDLE9BQU8sU0FBUyxxQkFBcUIsU0FBUyxzQkFBc0IsRUFBRSxLQUFLLE9BQU8sQ0FBQyxFQUNuRixTQUFTO0FBRVosUUFBTSxXQUFXLE1BQU0sTUFBTSxVQUFVLEVBQ3BDLFVBQVUsQ0FBQztBQUFBLElBQ1YsT0FBTztBQUFBLElBQ1AsTUFBTSxTQUFTO0FBQUEsSUFDZixLQUFLLFNBQVM7QUFBQSxFQUNoQixDQUFDLENBQUMsRUFDRCxJQUFJLEVBQ0osU0FBUztBQUVaLFNBQU8sSUFBSSxXQUFXLFFBQVE7QUFDaEM7QUFVQSxTQUFTLHNCQUFzQixPQUFlLFFBQXdCO0FBQ3BFLFFBQU0sVUFBVSxLQUFLLE1BQU0sS0FBSztBQUNoQyxPQUFLLFNBQVMsV0FBVyxpQkFBaUIsR0FBRztBQUMzQyxXQUFPO0FBQUEsRUFDVDtBQUlBLFNBQU8sU0FBUyxVQUFVLFVBQVUsSUFBSSxVQUFVO0FBQ3BEOyIsCiAgIm5hbWVzIjogW10KfQo=
@@ -22,10 +22,14 @@ export type { ElectronCompatibility, ElectronCompatibilityTier, ResolveElectronC
22
22
  export { resolveElectronCompatibility } from './electron-compatibility.mjs';
23
23
  export type { EvalInObsidianParams, HoverElementParams, Lib, MoveMouseParams, PressKeyParams, TypeIntoEditorParams, UnhoverElementParams, WaitUntilParams } from './eval-in-obsidian.mjs';
24
24
  export { evalInObsidian } from './eval-in-obsidian.mjs';
25
+ export type { ComputeFitToCanvasParams, FitScreenshotToCanvasOptions, FitToCanvasGeometry } from './fit-screenshot.mjs';
26
+ export { computeFitToCanvas, fitScreenshotToCanvas } from './fit-screenshot.mjs';
25
27
  export type { IncompatibleInstallerVersionErrorConstructorParams } from './incompatible-installer-version-error.mjs';
26
28
  export { IncompatibleInstallerVersionError } from './incompatible-installer-version-error.mjs';
27
29
  export type { InstallerCompatibility, InstallerCompatibilityTier, ResolveInstallerCompatibilityParams } from './installer-compatibility.mjs';
28
30
  export { resolveInstallerCompatibility } from './installer-compatibility.mjs';
31
+ export type { ComputeLabelBandParams, LabelBandGeometry, LabelScreenshotOptions } from './label-screenshot.mjs';
32
+ export { buildLabelSvg, computeLabelBand, escapeSvgText, labelScreenshot } from './label-screenshot.mjs';
29
33
  export type { LibResolver } from './lib-registry.mjs';
30
34
  export { registerLibResolver } from './lib-registry.mjs';
31
35
  export type { ObsidianRuntimeVersions, ObsidianVersionDownloads, ObsidianVersionMetadata } from './obsidian-metadata.mjs';
@@ -16,8 +16,18 @@ import { buildDemoVaultPopulate } from "./demo-vault-populate.mjs";
16
16
  import { readDemoVaultTree } from "./demo-vault-tree.mjs";
17
17
  import { resolveElectronCompatibility } from "./electron-compatibility.mjs";
18
18
  import { evalInObsidian } from "./eval-in-obsidian.mjs";
19
+ import {
20
+ computeFitToCanvas,
21
+ fitScreenshotToCanvas
22
+ } from "./fit-screenshot.mjs";
19
23
  import { IncompatibleInstallerVersionError } from "./incompatible-installer-version-error.mjs";
20
24
  import { resolveInstallerCompatibility } from "./installer-compatibility.mjs";
25
+ import {
26
+ buildLabelSvg,
27
+ computeLabelBand,
28
+ escapeSvgText,
29
+ labelScreenshot
30
+ } from "./label-screenshot.mjs";
21
31
  import { registerLibResolver } from "./lib-registry.mjs";
22
32
  import { getVersionMetadata } from "./obsidian-metadata.mjs";
23
33
  import {
@@ -50,13 +60,19 @@ export {
50
60
  TemporaryVault,
51
61
  buildDemoVaultPopulate,
52
62
  buildDeviceMetricsOverride,
63
+ buildLabelSvg,
53
64
  captureObsidianScreenshot,
65
+ computeFitToCanvas,
66
+ computeLabelBand,
54
67
  connectToCdp,
55
68
  createTransportFromOptions,
56
69
  decodeBase64Png,
70
+ escapeSvgText,
57
71
  evalInObsidian,
72
+ fitScreenshotToCanvas,
58
73
  getVersionMetadata,
59
74
  isPng,
75
+ labelScreenshot,
60
76
  pollInObsidian,
61
77
  readDemoVaultTree,
62
78
  readPngDimensions,
@@ -70,4 +86,4 @@ export {
70
86
  setVaultPathResolver,
71
87
  unregisterVault
72
88
  };
73
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2luZGV4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogQ29udGFpbnMgdGhlIGVudHJ5IHBvaW50IGZvciB0aGUgaW50ZWdyYXRpb24gdGVzdGluZyBtb2R1bGUuXG4gKi9cblxuZXhwb3J0IHR5cGUge1xuICBBc2FyRmFsbGJhY2ssXG4gIEFzYXJGYWxsYmFja1RpZXIsXG4gIFJlc29sdmVBc2FyRmFsbGJhY2tQYXJhbXNcbn0gZnJvbSAnLi9hc2FyLWZhbGxiYWNrLWRldGVjdGlvbi5tanMnO1xuZXhwb3J0IHsgcmVzb2x2ZUFzYXJGYWxsYmFjayB9IGZyb20gJy4vYXNhci1mYWxsYmFjay1kZXRlY3Rpb24ubWpzJztcbmV4cG9ydCB0eXBlIHsgQ2FwdHVyZU9ic2lkaWFuU2NyZWVuc2hvdE9wdGlvbnMgfSBmcm9tICcuL2NhcHR1cmUtb2JzaWRpYW4tc2NyZWVuc2hvdC5tanMnO1xuZXhwb3J0IHsgY2FwdHVyZU9ic2lkaWFuU2NyZWVuc2hvdCB9IGZyb20gJy4vY2FwdHVyZS1vYnNpZGlhbi1zY3JlZW5zaG90Lm1qcyc7XG5leHBvcnQgdHlwZSB7XG4gIENhcHR1cmVTY3JlZW5zaG90UGFyYW1zLFxuICBQbmdEaW1lbnNpb25zXG59IGZyb20gJy4vY2FwdHVyZS1zY3JlZW5zaG90Lm1qcyc7XG5leHBvcnQge1xuICBidWlsZERldmljZU1ldHJpY3NPdmVycmlkZSxcbiAgZGVjb2RlQmFzZTY0UG5nLFxuICBpc1BuZyxcbiAgcmVhZFBuZ0RpbWVuc2lvbnNcbn0gZnJvbSAnLi9jYXB0dXJlLXNjcmVlbnNob3QubWpzJztcbmV4cG9ydCB0eXBlIHtcbiAgQ2RwQ29ubmVjdGlvbixcbiAgQ29ubmVjdFRvQ2RwT3B0aW9uc1xufSBmcm9tICcuL2Nvbm5lY3QtdG8tY2RwLm1qcyc7XG5leHBvcnQgeyBjb25uZWN0VG9DZHAgfSBmcm9tICcuL2Nvbm5lY3QtdG8tY2RwLm1qcyc7XG5leHBvcnQgeyBDb250ZXh0SWQgfSBmcm9tICcuL2NvbnRleHQtaWQubWpzJztcbmV4cG9ydCB0eXBlIHtcbiAgVHJhbnNwb3J0T3B0aW9uc1Jlc29sdmVyLFxuICBWYXVsdFBhdGhSZXNvbHZlclxufSBmcm9tICcuL2NvbnRleHQtcHJvdmlkZXIubWpzJztcbmV4cG9ydCB7XG4gIHNldFRyYW5zcG9ydE9wdGlvbnNSZXNvbHZlcixcbiAgc2V0VmF1bHRQYXRoUmVzb2x2ZXJcbn0gZnJvbSAnLi9jb250ZXh0LXByb3ZpZGVyLm1qcyc7XG5leHBvcnQgdHlwZSB7XG4gIEJ1aWxkRGVtb1ZhdWx0UG9wdWxhdGVQYXJhbXMsXG4gIEluamVjdFBsdWdpblBhcmFtc1xufSBmcm9tICcuL2RlbW8tdmF1bHQtcG9wdWxhdGUubWpzJztcbmV4cG9ydCB7IGJ1aWxkRGVtb1ZhdWx0UG9wdWxhdGUgfSBmcm9tICcuL2RlbW8tdmF1bHQtcG9wdWxhdGUubWpzJztcbmV4cG9ydCB0eXBlIHsgUmVhZERlbW9WYXVsdFRyZWVQYXJhbXMgfSBmcm9tICcuL2RlbW8tdmF1bHQtdHJlZS5tanMnO1xuZXhwb3J0IHsgcmVhZERlbW9WYXVsdFRyZWUgfSBmcm9tICcuL2RlbW8tdmF1bHQtdHJlZS5tanMnO1xuZXhwb3J0IHR5cGUge1xuICBFbGVjdHJvbkNvbXBhdGliaWxpdHksXG4gIEVsZWN0cm9uQ29tcGF0aWJpbGl0eVRpZXIsXG4gIFJlc29sdmVFbGVjdHJvbkNvbXBhdGliaWxpdHlQYXJhbXNcbn0gZnJvbSAnLi9lbGVjdHJvbi1jb21wYXRpYmlsaXR5Lm1qcyc7XG5leHBvcnQgeyByZXNvbHZlRWxlY3Ryb25Db21wYXRpYmlsaXR5IH0gZnJvbSAnLi9lbGVjdHJvbi1jb21wYXRpYmlsaXR5Lm1qcyc7XG5leHBvcnQgdHlwZSB7XG4gIEV2YWxJbk9ic2lkaWFuUGFyYW1zLFxuICBIb3ZlckVsZW1lbnRQYXJhbXMsXG4gIExpYixcbiAgTW92ZU1vdXNlUGFyYW1zLFxuICBQcmVzc0tleVBhcmFtcyxcbiAgVHlwZUludG9FZGl0b3JQYXJhbXMsXG4gIFVuaG92ZXJFbGVtZW50UGFyYW1zLFxuICBXYWl0VW50aWxQYXJhbXNcbn0gZnJvbSAnLi9ldmFsLWluLW9ic2lkaWFuLm1qcyc7XG5leHBvcnQgeyBldmFsSW5PYnNpZGlhbiB9IGZyb20gJy4vZXZhbC1pbi1vYnNpZGlhbi5tanMnO1xuZXhwb3J0IHR5cGUgeyBJbmNvbXBhdGlibGVJbnN0YWxsZXJWZXJzaW9uRXJyb3JDb25zdHJ1Y3RvclBhcmFtcyB9IGZyb20gJy4vaW5jb21wYXRpYmxlLWluc3RhbGxlci12ZXJzaW9uLWVycm9yLm1qcyc7XG5leHBvcnQgeyBJbmNvbXBhdGlibGVJbnN0YWxsZXJWZXJzaW9uRXJyb3IgfSBmcm9tICcuL2luY29tcGF0aWJsZS1pbnN0YWxsZXItdmVyc2lvbi1lcnJvci5tanMnO1xuZXhwb3J0IHR5cGUge1xuICBJbnN0YWxsZXJDb21wYXRpYmlsaXR5LFxuICBJbnN0YWxsZXJDb21wYXRpYmlsaXR5VGllcixcbiAgUmVzb2x2ZUluc3RhbGxlckNvbXBhdGliaWxpdHlQYXJhbXNcbn0gZnJvbSAnLi9pbnN0YWxsZXItY29tcGF0aWJpbGl0eS5tanMnO1xuZXhwb3J0IHsgcmVzb2x2ZUluc3RhbGxlckNvbXBhdGliaWxpdHkgfSBmcm9tICcuL2luc3RhbGxlci1jb21wYXRpYmlsaXR5Lm1qcyc7XG5leHBvcnQgdHlwZSB7IExpYlJlc29sdmVyIH0gZnJvbSAnLi9saWItcmVnaXN0cnkubWpzJztcbmV4cG9ydCB7IHJlZ2lzdGVyTGliUmVzb2x2ZXIgfSBmcm9tICcuL2xpYi1yZWdpc3RyeS5tanMnO1xuZXhwb3J0IHR5cGUge1xuICBPYnNpZGlhblJ1bnRpbWVWZXJzaW9ucyxcbiAgT2JzaWRpYW5WZXJzaW9uRG93bmxvYWRzLFxuICBPYnNpZGlhblZlcnNpb25NZXRhZGF0YVxufSBmcm9tICcuL29ic2lkaWFuLW1ldGFkYXRhLm1qcyc7XG5leHBvcnQgeyBnZXRWZXJzaW9uTWV0YWRhdGEgfSBmcm9tICcuL29ic2lkaWFuLW1ldGFkYXRhLm1qcyc7XG5leHBvcnQge1xuICBDQVRBTFlTVF9MQVRFU1QsXG4gIFBVQkxJQ19MQVRFU1Rcbn0gZnJvbSAnLi9vYnNpZGlhbi12ZXJzaW9uLm1qcyc7XG5leHBvcnQgdHlwZSB7IFBvbGxJbk9ic2lkaWFuUGFyYW1zIH0gZnJvbSAnLi9wb2xsLWluLW9ic2lkaWFuLm1qcyc7XG5leHBvcnQgeyBwb2xsSW5PYnNpZGlhbiB9IGZyb20gJy4vcG9sbC1pbi1vYnNpZGlhbi5tanMnO1xuZXhwb3J0IHsgUmVuZGVyZXJGYWlsZWRUb0luaXRpYWxpemVFcnJvciB9IGZyb20gJy4vcmVuZGVyZXItZmFpbGVkLXRvLWluaXRpYWxpemUtZXJyb3IubWpzJztcbmV4cG9ydCB0eXBlIHsgUnVuT2JzaWRpYW5WZXJzaW9uTWF0cml4UGFyYW1zIH0gZnJvbSAnLi9ydW4tdmVyc2lvbi1tYXRyaXgubWpzJztcbmV4cG9ydCB7IHJ1bk9ic2lkaWFuVmVyc2lvbk1hdHJpeCB9IGZyb20gJy4vcnVuLXZlcnNpb24tbWF0cml4Lm1qcyc7XG5leHBvcnQgdHlwZSB7IFNpbGVudEFzYXJGYWxsYmFja0Vycm9yQ29uc3RydWN0b3JQYXJhbXMgfSBmcm9tICcuL3NpbGVudC1hc2FyLWZhbGxiYWNrLWVycm9yLm1qcyc7XG5leHBvcnQgeyBTaWxlbnRBc2FyRmFsbGJhY2tFcnJvciB9IGZyb20gJy4vc2lsZW50LWFzYXItZmFsbGJhY2stZXJyb3IubWpzJztcbmV4cG9ydCB0eXBlIHtcbiAgUG9wdWxhdGVGaWxlQ29udGVudCxcbiAgUG9wdWxhdGVGaWxlc1BhcmFtc1xufSBmcm9tICcuL3RlbXBvcmFyeS12YXVsdC5tanMnO1xuZXhwb3J0IHsgVGVtcG9yYXJ5VmF1bHQgfSBmcm9tICcuL3RlbXBvcmFyeS12YXVsdC5tanMnO1xuZXhwb3J0IHR5cGUge1xuICBBcHBpdW1TZXNzaW9uSW5mbyxcbiAgQXBwaXVtVHJhbnNwb3J0Q29uZmlnXG59IGZyb20gJy4vdHJhbnNwb3J0LWFwcGl1bS5tanMnO1xuZXhwb3J0IHsgQXBwaXVtVHJhbnNwb3J0IH0gZnJvbSAnLi90cmFuc3BvcnQtYXBwaXVtLm1qcyc7XG5leHBvcnQgdHlwZSB7XG4gIERlc2t0b3BDZHBUcmFuc3BvcnRDb25maWcsXG4gIE93bmVkSW5zdGFuY2VBc2FyLFxuICBPd25lZEluc3RhbmNlQ29uZmlnXG59IGZyb20gJy4vdHJhbnNwb3J0LWRlc2t0b3AtY2RwLm1qcyc7XG5leHBvcnQgeyBEZXNrdG9wQ2RwVHJhbnNwb3J0IH0gZnJvbSAnLi90cmFuc3BvcnQtZGVza3RvcC1jZHAubWpzJztcbmV4cG9ydCB7IGNyZWF0ZVRyYW5zcG9ydEZyb21PcHRpb25zIH0gZnJvbSAnLi90cmFuc3BvcnQtZmFjdG9yeS5tanMnO1xuZXhwb3J0IHR5cGUge1xuICBPYnNpZGlhbkFuZHJvaWRBcHBpdW1UcmFuc3BvcnRPcHRpb25zLFxuICBPYnNpZGlhbkNkcFRyYW5zcG9ydE9wdGlvbnMsXG4gIE9ic2lkaWFuVHJhbnNwb3J0T3B0aW9uc1xufSBmcm9tICcuL3RyYW5zcG9ydC1vcHRpb25zLm1qcyc7XG5leHBvcnQgdHlwZSB7XG4gIE9ic2lkaWFuVHJhbnNwb3J0LFxuICBUcmFuc3BvcnRFdmFsT3B0aW9uc1xufSBmcm9tICcuL3RyYW5zcG9ydC5tanMnO1xuZXhwb3J0IHtcbiAgcmVnaXN0ZXJWYXVsdCxcbiAgdW5yZWdpc3RlclZhdWx0XG59IGZyb20gJy4vdmF1bHQtcmVnaXN0cnkubWpzJztcbmV4cG9ydCB0eXBlIHsgT2JzaWRpYW5WZXJzaW9uTWF0cml4RW50cnkgfSBmcm9tICcuL3ZlcnNpb24tbWF0cml4Lm1qcyc7XG5leHBvcnQgeyBERUZBVUxUX09CU0lESUFOX1ZFUlNJT05fU1BFQ1MgfSBmcm9tICcuL3ZlcnNpb24tbWF0cml4Lm1qcyc7XG4iXSwKICAibWFwcGluZ3MiOiAiQUFXQSxTQUFTLDJCQUEyQjtBQUVwQyxTQUFTLGlDQUFpQztBQUsxQztBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBS1AsU0FBUyxvQkFBb0I7QUFDN0IsU0FBUyxpQkFBaUI7QUFLMUI7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFLUCxTQUFTLDhCQUE4QjtBQUV2QyxTQUFTLHlCQUF5QjtBQU1sQyxTQUFTLG9DQUFvQztBQVc3QyxTQUFTLHNCQUFzQjtBQUUvQixTQUFTLHlDQUF5QztBQU1sRCxTQUFTLHFDQUFxQztBQUU5QyxTQUFTLDJCQUEyQjtBQU1wQyxTQUFTLDBCQUEwQjtBQUNuQztBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUVQLFNBQVMsc0JBQXNCO0FBQy9CLFNBQVMsdUNBQXVDO0FBRWhELFNBQVMsZ0NBQWdDO0FBRXpDLFNBQVMsK0JBQStCO0FBS3hDLFNBQVMsc0JBQXNCO0FBSy9CLFNBQVMsdUJBQXVCO0FBTWhDLFNBQVMsMkJBQTJCO0FBQ3BDLFNBQVMsa0NBQWtDO0FBVTNDO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBRVAsU0FBUyxzQ0FBc0M7IiwKICAibmFtZXMiOiBbXQp9Cg==
89
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2luZGV4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogQ29udGFpbnMgdGhlIGVudHJ5IHBvaW50IGZvciB0aGUgaW50ZWdyYXRpb24gdGVzdGluZyBtb2R1bGUuXG4gKi9cblxuZXhwb3J0IHR5cGUge1xuICBBc2FyRmFsbGJhY2ssXG4gIEFzYXJGYWxsYmFja1RpZXIsXG4gIFJlc29sdmVBc2FyRmFsbGJhY2tQYXJhbXNcbn0gZnJvbSAnLi9hc2FyLWZhbGxiYWNrLWRldGVjdGlvbi5tanMnO1xuZXhwb3J0IHsgcmVzb2x2ZUFzYXJGYWxsYmFjayB9IGZyb20gJy4vYXNhci1mYWxsYmFjay1kZXRlY3Rpb24ubWpzJztcbmV4cG9ydCB0eXBlIHsgQ2FwdHVyZU9ic2lkaWFuU2NyZWVuc2hvdE9wdGlvbnMgfSBmcm9tICcuL2NhcHR1cmUtb2JzaWRpYW4tc2NyZWVuc2hvdC5tanMnO1xuZXhwb3J0IHsgY2FwdHVyZU9ic2lkaWFuU2NyZWVuc2hvdCB9IGZyb20gJy4vY2FwdHVyZS1vYnNpZGlhbi1zY3JlZW5zaG90Lm1qcyc7XG5leHBvcnQgdHlwZSB7XG4gIENhcHR1cmVTY3JlZW5zaG90UGFyYW1zLFxuICBQbmdEaW1lbnNpb25zXG59IGZyb20gJy4vY2FwdHVyZS1zY3JlZW5zaG90Lm1qcyc7XG5leHBvcnQge1xuICBidWlsZERldmljZU1ldHJpY3NPdmVycmlkZSxcbiAgZGVjb2RlQmFzZTY0UG5nLFxuICBpc1BuZyxcbiAgcmVhZFBuZ0RpbWVuc2lvbnNcbn0gZnJvbSAnLi9jYXB0dXJlLXNjcmVlbnNob3QubWpzJztcbmV4cG9ydCB0eXBlIHtcbiAgQ2RwQ29ubmVjdGlvbixcbiAgQ29ubmVjdFRvQ2RwT3B0aW9uc1xufSBmcm9tICcuL2Nvbm5lY3QtdG8tY2RwLm1qcyc7XG5leHBvcnQgeyBjb25uZWN0VG9DZHAgfSBmcm9tICcuL2Nvbm5lY3QtdG8tY2RwLm1qcyc7XG5leHBvcnQgeyBDb250ZXh0SWQgfSBmcm9tICcuL2NvbnRleHQtaWQubWpzJztcbmV4cG9ydCB0eXBlIHtcbiAgVHJhbnNwb3J0T3B0aW9uc1Jlc29sdmVyLFxuICBWYXVsdFBhdGhSZXNvbHZlclxufSBmcm9tICcuL2NvbnRleHQtcHJvdmlkZXIubWpzJztcbmV4cG9ydCB7XG4gIHNldFRyYW5zcG9ydE9wdGlvbnNSZXNvbHZlcixcbiAgc2V0VmF1bHRQYXRoUmVzb2x2ZXJcbn0gZnJvbSAnLi9jb250ZXh0LXByb3ZpZGVyLm1qcyc7XG5leHBvcnQgdHlwZSB7XG4gIEJ1aWxkRGVtb1ZhdWx0UG9wdWxhdGVQYXJhbXMsXG4gIEluamVjdFBsdWdpblBhcmFtc1xufSBmcm9tICcuL2RlbW8tdmF1bHQtcG9wdWxhdGUubWpzJztcbmV4cG9ydCB7IGJ1aWxkRGVtb1ZhdWx0UG9wdWxhdGUgfSBmcm9tICcuL2RlbW8tdmF1bHQtcG9wdWxhdGUubWpzJztcbmV4cG9ydCB0eXBlIHsgUmVhZERlbW9WYXVsdFRyZWVQYXJhbXMgfSBmcm9tICcuL2RlbW8tdmF1bHQtdHJlZS5tanMnO1xuZXhwb3J0IHsgcmVhZERlbW9WYXVsdFRyZWUgfSBmcm9tICcuL2RlbW8tdmF1bHQtdHJlZS5tanMnO1xuZXhwb3J0IHR5cGUge1xuICBFbGVjdHJvbkNvbXBhdGliaWxpdHksXG4gIEVsZWN0cm9uQ29tcGF0aWJpbGl0eVRpZXIsXG4gIFJlc29sdmVFbGVjdHJvbkNvbXBhdGliaWxpdHlQYXJhbXNcbn0gZnJvbSAnLi9lbGVjdHJvbi1jb21wYXRpYmlsaXR5Lm1qcyc7XG5leHBvcnQgeyByZXNvbHZlRWxlY3Ryb25Db21wYXRpYmlsaXR5IH0gZnJvbSAnLi9lbGVjdHJvbi1jb21wYXRpYmlsaXR5Lm1qcyc7XG5leHBvcnQgdHlwZSB7XG4gIEV2YWxJbk9ic2lkaWFuUGFyYW1zLFxuICBIb3ZlckVsZW1lbnRQYXJhbXMsXG4gIExpYixcbiAgTW92ZU1vdXNlUGFyYW1zLFxuICBQcmVzc0tleVBhcmFtcyxcbiAgVHlwZUludG9FZGl0b3JQYXJhbXMsXG4gIFVuaG92ZXJFbGVtZW50UGFyYW1zLFxuICBXYWl0VW50aWxQYXJhbXNcbn0gZnJvbSAnLi9ldmFsLWluLW9ic2lkaWFuLm1qcyc7XG5leHBvcnQgeyBldmFsSW5PYnNpZGlhbiB9IGZyb20gJy4vZXZhbC1pbi1vYnNpZGlhbi5tanMnO1xuZXhwb3J0IHR5cGUge1xuICBDb21wdXRlRml0VG9DYW52YXNQYXJhbXMsXG4gIEZpdFNjcmVlbnNob3RUb0NhbnZhc09wdGlvbnMsXG4gIEZpdFRvQ2FudmFzR2VvbWV0cnlcbn0gZnJvbSAnLi9maXQtc2NyZWVuc2hvdC5tanMnO1xuZXhwb3J0IHtcbiAgY29tcHV0ZUZpdFRvQ2FudmFzLFxuICBmaXRTY3JlZW5zaG90VG9DYW52YXNcbn0gZnJvbSAnLi9maXQtc2NyZWVuc2hvdC5tanMnO1xuZXhwb3J0IHR5cGUgeyBJbmNvbXBhdGlibGVJbnN0YWxsZXJWZXJzaW9uRXJyb3JDb25zdHJ1Y3RvclBhcmFtcyB9IGZyb20gJy4vaW5jb21wYXRpYmxlLWluc3RhbGxlci12ZXJzaW9uLWVycm9yLm1qcyc7XG5leHBvcnQgeyBJbmNvbXBhdGlibGVJbnN0YWxsZXJWZXJzaW9uRXJyb3IgfSBmcm9tICcuL2luY29tcGF0aWJsZS1pbnN0YWxsZXItdmVyc2lvbi1lcnJvci5tanMnO1xuZXhwb3J0IHR5cGUge1xuICBJbnN0YWxsZXJDb21wYXRpYmlsaXR5LFxuICBJbnN0YWxsZXJDb21wYXRpYmlsaXR5VGllcixcbiAgUmVzb2x2ZUluc3RhbGxlckNvbXBhdGliaWxpdHlQYXJhbXNcbn0gZnJvbSAnLi9pbnN0YWxsZXItY29tcGF0aWJpbGl0eS5tanMnO1xuZXhwb3J0IHsgcmVzb2x2ZUluc3RhbGxlckNvbXBhdGliaWxpdHkgfSBmcm9tICcuL2luc3RhbGxlci1jb21wYXRpYmlsaXR5Lm1qcyc7XG5leHBvcnQgdHlwZSB7XG4gIENvbXB1dGVMYWJlbEJhbmRQYXJhbXMsXG4gIExhYmVsQmFuZEdlb21ldHJ5LFxuICBMYWJlbFNjcmVlbnNob3RPcHRpb25zXG59IGZyb20gJy4vbGFiZWwtc2NyZWVuc2hvdC5tanMnO1xuZXhwb3J0IHtcbiAgYnVpbGRMYWJlbFN2ZyxcbiAgY29tcHV0ZUxhYmVsQmFuZCxcbiAgZXNjYXBlU3ZnVGV4dCxcbiAgbGFiZWxTY3JlZW5zaG90XG59IGZyb20gJy4vbGFiZWwtc2NyZWVuc2hvdC5tanMnO1xuZXhwb3J0IHR5cGUgeyBMaWJSZXNvbHZlciB9IGZyb20gJy4vbGliLXJlZ2lzdHJ5Lm1qcyc7XG5leHBvcnQgeyByZWdpc3RlckxpYlJlc29sdmVyIH0gZnJvbSAnLi9saWItcmVnaXN0cnkubWpzJztcbmV4cG9ydCB0eXBlIHtcbiAgT2JzaWRpYW5SdW50aW1lVmVyc2lvbnMsXG4gIE9ic2lkaWFuVmVyc2lvbkRvd25sb2FkcyxcbiAgT2JzaWRpYW5WZXJzaW9uTWV0YWRhdGFcbn0gZnJvbSAnLi9vYnNpZGlhbi1tZXRhZGF0YS5tanMnO1xuZXhwb3J0IHsgZ2V0VmVyc2lvbk1ldGFkYXRhIH0gZnJvbSAnLi9vYnNpZGlhbi1tZXRhZGF0YS5tanMnO1xuZXhwb3J0IHtcbiAgQ0FUQUxZU1RfTEFURVNULFxuICBQVUJMSUNfTEFURVNUXG59IGZyb20gJy4vb2JzaWRpYW4tdmVyc2lvbi5tanMnO1xuZXhwb3J0IHR5cGUgeyBQb2xsSW5PYnNpZGlhblBhcmFtcyB9IGZyb20gJy4vcG9sbC1pbi1vYnNpZGlhbi5tanMnO1xuZXhwb3J0IHsgcG9sbEluT2JzaWRpYW4gfSBmcm9tICcuL3BvbGwtaW4tb2JzaWRpYW4ubWpzJztcbmV4cG9ydCB7IFJlbmRlcmVyRmFpbGVkVG9Jbml0aWFsaXplRXJyb3IgfSBmcm9tICcuL3JlbmRlcmVyLWZhaWxlZC10by1pbml0aWFsaXplLWVycm9yLm1qcyc7XG5leHBvcnQgdHlwZSB7IFJ1bk9ic2lkaWFuVmVyc2lvbk1hdHJpeFBhcmFtcyB9IGZyb20gJy4vcnVuLXZlcnNpb24tbWF0cml4Lm1qcyc7XG5leHBvcnQgeyBydW5PYnNpZGlhblZlcnNpb25NYXRyaXggfSBmcm9tICcuL3J1bi12ZXJzaW9uLW1hdHJpeC5tanMnO1xuZXhwb3J0IHR5cGUgeyBTaWxlbnRBc2FyRmFsbGJhY2tFcnJvckNvbnN0cnVjdG9yUGFyYW1zIH0gZnJvbSAnLi9zaWxlbnQtYXNhci1mYWxsYmFjay1lcnJvci5tanMnO1xuZXhwb3J0IHsgU2lsZW50QXNhckZhbGxiYWNrRXJyb3IgfSBmcm9tICcuL3NpbGVudC1hc2FyLWZhbGxiYWNrLWVycm9yLm1qcyc7XG5leHBvcnQgdHlwZSB7XG4gIFBvcHVsYXRlRmlsZUNvbnRlbnQsXG4gIFBvcHVsYXRlRmlsZXNQYXJhbXNcbn0gZnJvbSAnLi90ZW1wb3JhcnktdmF1bHQubWpzJztcbmV4cG9ydCB7IFRlbXBvcmFyeVZhdWx0IH0gZnJvbSAnLi90ZW1wb3JhcnktdmF1bHQubWpzJztcbmV4cG9ydCB0eXBlIHtcbiAgQXBwaXVtU2Vzc2lvbkluZm8sXG4gIEFwcGl1bVRyYW5zcG9ydENvbmZpZ1xufSBmcm9tICcuL3RyYW5zcG9ydC1hcHBpdW0ubWpzJztcbmV4cG9ydCB7IEFwcGl1bVRyYW5zcG9ydCB9IGZyb20gJy4vdHJhbnNwb3J0LWFwcGl1bS5tanMnO1xuZXhwb3J0IHR5cGUge1xuICBEZXNrdG9wQ2RwVHJhbnNwb3J0Q29uZmlnLFxuICBPd25lZEluc3RhbmNlQXNhcixcbiAgT3duZWRJbnN0YW5jZUNvbmZpZ1xufSBmcm9tICcuL3RyYW5zcG9ydC1kZXNrdG9wLWNkcC5tanMnO1xuZXhwb3J0IHsgRGVza3RvcENkcFRyYW5zcG9ydCB9IGZyb20gJy4vdHJhbnNwb3J0LWRlc2t0b3AtY2RwLm1qcyc7XG5leHBvcnQgeyBjcmVhdGVUcmFuc3BvcnRGcm9tT3B0aW9ucyB9IGZyb20gJy4vdHJhbnNwb3J0LWZhY3RvcnkubWpzJztcbmV4cG9ydCB0eXBlIHtcbiAgT2JzaWRpYW5BbmRyb2lkQXBwaXVtVHJhbnNwb3J0T3B0aW9ucyxcbiAgT2JzaWRpYW5DZHBUcmFuc3BvcnRPcHRpb25zLFxuICBPYnNpZGlhblRyYW5zcG9ydE9wdGlvbnNcbn0gZnJvbSAnLi90cmFuc3BvcnQtb3B0aW9ucy5tanMnO1xuZXhwb3J0IHR5cGUge1xuICBPYnNpZGlhblRyYW5zcG9ydCxcbiAgVHJhbnNwb3J0RXZhbE9wdGlvbnNcbn0gZnJvbSAnLi90cmFuc3BvcnQubWpzJztcbmV4cG9ydCB7XG4gIHJlZ2lzdGVyVmF1bHQsXG4gIHVucmVnaXN0ZXJWYXVsdFxufSBmcm9tICcuL3ZhdWx0LXJlZ2lzdHJ5Lm1qcyc7XG5leHBvcnQgdHlwZSB7IE9ic2lkaWFuVmVyc2lvbk1hdHJpeEVudHJ5IH0gZnJvbSAnLi92ZXJzaW9uLW1hdHJpeC5tanMnO1xuZXhwb3J0IHsgREVGQVVMVF9PQlNJRElBTl9WRVJTSU9OX1NQRUNTIH0gZnJvbSAnLi92ZXJzaW9uLW1hdHJpeC5tanMnO1xuIl0sCiAgIm1hcHBpbmdzIjogIkFBV0EsU0FBUywyQkFBMkI7QUFFcEMsU0FBUyxpQ0FBaUM7QUFLMUM7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUtQLFNBQVMsb0JBQW9CO0FBQzdCLFNBQVMsaUJBQWlCO0FBSzFCO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBS1AsU0FBUyw4QkFBOEI7QUFFdkMsU0FBUyx5QkFBeUI7QUFNbEMsU0FBUyxvQ0FBb0M7QUFXN0MsU0FBUyxzQkFBc0I7QUFNL0I7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFFUCxTQUFTLHlDQUF5QztBQU1sRCxTQUFTLHFDQUFxQztBQU05QztBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBRVAsU0FBUywyQkFBMkI7QUFNcEMsU0FBUywwQkFBMEI7QUFDbkM7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFFUCxTQUFTLHNCQUFzQjtBQUMvQixTQUFTLHVDQUF1QztBQUVoRCxTQUFTLGdDQUFnQztBQUV6QyxTQUFTLCtCQUErQjtBQUt4QyxTQUFTLHNCQUFzQjtBQUsvQixTQUFTLHVCQUF1QjtBQU1oQyxTQUFTLDJCQUEyQjtBQUNwQyxTQUFTLGtDQUFrQztBQVUzQztBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUVQLFNBQVMsc0NBQXNDOyIsCiAgIm5hbWVzIjogW10KfQo=
@@ -0,0 +1,98 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Adds a caption band to an already-captured screenshot.
5
+ *
6
+ * A store listing shows screenshots ONE AT A TIME, in a carousel, with no
7
+ * caption of its own — so an image has to say what it is showing. Without that,
8
+ * a shot of the state a plugin removes reads as a shot of the state the plugin
9
+ * causes, which is the opposite of the message.
10
+ *
11
+ * The band is drawn over the BOTTOM of the frame, for two reasons: the top is
12
+ * where the content being demonstrated usually starts, and the bottom of an
13
+ * Obsidian frame is chrome — status bar, word count, sync indicator — which the
14
+ * band then covers rather than competing with.
15
+ *
16
+ * This is post-processing, deliberately. The capture stays an untouched device
17
+ * frame, and rewording a label needs no re-shoot.
18
+ */
19
+ /**
20
+ * Parameters for {@link computeLabelBand}.
21
+ */
22
+ export interface ComputeLabelBandParams {
23
+ /**
24
+ * Height of the image being labeled, in pixels.
25
+ */
26
+ readonly imageHeightInPixels: number;
27
+ /**
28
+ * Width of the image being labeled, in pixels.
29
+ */
30
+ readonly imageWidthInPixels: number;
31
+ }
32
+ /**
33
+ * The geometry of the caption band.
34
+ */
35
+ export interface LabelBandGeometry {
36
+ /**
37
+ * Font size for the caption, in pixels.
38
+ */
39
+ readonly fontSizeInPixels: number;
40
+ /**
41
+ * Height of the band, in pixels.
42
+ */
43
+ readonly heightInPixels: number;
44
+ /**
45
+ * Distance from the top of the image to the top of the band, in pixels.
46
+ */
47
+ readonly topInPixels: number;
48
+ }
49
+ /**
50
+ * Options for {@link labelScreenshot}.
51
+ */
52
+ export interface LabelScreenshotOptions {
53
+ /**
54
+ * The caption. Keep it to a handful of words: it is read at listing-thumbnail
55
+ * size, and it is clipped rather than wrapped.
56
+ */
57
+ readonly text: string;
58
+ }
59
+ /**
60
+ * Builds the SVG for the caption band.
61
+ *
62
+ * @param text - The caption.
63
+ * @param geometry - The band geometry.
64
+ * @param imageWidthInPixels - Width of the image, so the band spans it.
65
+ * @returns The SVG markup.
66
+ */
67
+ export declare function buildLabelSvg(text: string, geometry: LabelBandGeometry, imageWidthInPixels: number): string;
68
+ /**
69
+ * Computes the caption band's size and position for a given image.
70
+ *
71
+ * @param params - The image dimensions.
72
+ * @returns The band geometry.
73
+ * @throws Error if either dimension is not a positive number.
74
+ */
75
+ export declare function computeLabelBand(params: ComputeLabelBandParams): LabelBandGeometry;
76
+ /**
77
+ * Escapes text for inclusion in SVG character data.
78
+ *
79
+ * A caption is authored per screenshot and can legitimately contain `&` or the
80
+ * angle brackets Obsidian uses in link syntax; unescaped, those make the SVG
81
+ * impossible to parse and `sharp` fails on a caption rather than on an image.
82
+ *
83
+ * @param text - The raw caption.
84
+ * @returns The caption, safe to embed in SVG.
85
+ */
86
+ export declare function escapeSvgText(text: string): string;
87
+ /**
88
+ * Draws a caption band across the bottom of a screenshot.
89
+ *
90
+ * The image keeps its dimensions exactly: the band is composited OVER the
91
+ * frame, never appended to it, because the store expects a specific size.
92
+ *
93
+ * @param bytes - The captured PNG.
94
+ * @param options - The caption.
95
+ * @returns A {@link Promise} that resolves to the labeled PNG, the same size as the input.
96
+ * @throws Error if `sharp` is not installed, or the image dimensions cannot be read.
97
+ */
98
+ export declare function labelScreenshot(bytes: Uint8Array, options: LabelScreenshotOptions): Promise<Uint8Array>;
@@ -0,0 +1,54 @@
1
+ import { importSharp } from "./sharp-loader.mjs";
2
+ const FONT_SIZE_RATIO = 0.034;
3
+ const BAND_HEIGHT_RATIO = 2.2;
4
+ const BAND_OPACITY = 0.82;
5
+ const MINIMUM_FONT_SIZE_IN_PIXELS = 18;
6
+ const CENTER_DIVISOR = 2;
7
+ function buildLabelSvg(text, geometry, imageWidthInPixels) {
8
+ const { fontSizeInPixels, heightInPixels } = geometry;
9
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="${String(imageWidthInPixels)}" height="${String(heightInPixels)}"><rect x="0" y="0" width="${String(imageWidthInPixels)}" height="${String(heightInPixels)}" fill="#000000" fill-opacity="${String(BAND_OPACITY)}"/><text x="${String(imageWidthInPixels / CENTER_DIVISOR)}" y="${String(heightInPixels / CENTER_DIVISOR)}" font-family="Segoe UI, Helvetica, Arial, sans-serif" font-size="${String(fontSizeInPixels)}" font-weight="600" fill="#ffffff" text-anchor="middle" dominant-baseline="central">${escapeSvgText(text)}</text></svg>`;
10
+ }
11
+ function computeLabelBand(params) {
12
+ const { imageHeightInPixels, imageWidthInPixels } = params;
13
+ if (!Number.isFinite(imageWidthInPixels) || imageWidthInPixels <= 0) {
14
+ throw new Error(`computeLabelBand: imageWidthInPixels must be a positive number, got ${String(imageWidthInPixels)}.`);
15
+ }
16
+ if (!Number.isFinite(imageHeightInPixels) || imageHeightInPixels <= 0) {
17
+ throw new Error(`computeLabelBand: imageHeightInPixels must be a positive number, got ${String(imageHeightInPixels)}.`);
18
+ }
19
+ const fontSizeInPixels = Math.max(MINIMUM_FONT_SIZE_IN_PIXELS, Math.round(imageWidthInPixels * FONT_SIZE_RATIO));
20
+ const heightInPixels = Math.min(imageHeightInPixels, Math.round(fontSizeInPixels * BAND_HEIGHT_RATIO));
21
+ return {
22
+ fontSizeInPixels,
23
+ heightInPixels,
24
+ topInPixels: imageHeightInPixels - heightInPixels
25
+ };
26
+ }
27
+ function escapeSvgText(text) {
28
+ return text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&apos;");
29
+ }
30
+ async function labelScreenshot(bytes, options) {
31
+ const sharp = await importSharp("labelScreenshot");
32
+ const metadata = await sharp(bytes).metadata();
33
+ const imageWidthInPixels = metadata.width;
34
+ const imageHeightInPixels = metadata.height;
35
+ if (imageWidthInPixels === void 0 || imageHeightInPixels === void 0) {
36
+ throw new Error("labelScreenshot: could not read the source image dimensions.");
37
+ }
38
+ const geometry = computeLabelBand({ imageHeightInPixels, imageWidthInPixels });
39
+ const svg = buildLabelSvg(options.text, geometry, imageWidthInPixels);
40
+ const layer = {
41
+ input: Buffer.from(svg),
42
+ left: 0,
43
+ top: geometry.topInPixels
44
+ };
45
+ const labeled = await sharp(bytes).composite([layer]).png().toBuffer();
46
+ return new Uint8Array(labeled);
47
+ }
48
+ export {
49
+ buildLabelSvg,
50
+ computeLabelBand,
51
+ escapeSvgText,
52
+ labelScreenshot
53
+ };
54
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2xhYmVsLXNjcmVlbnNob3QudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBBZGRzIGEgY2FwdGlvbiBiYW5kIHRvIGFuIGFscmVhZHktY2FwdHVyZWQgc2NyZWVuc2hvdC5cbiAqXG4gKiBBIHN0b3JlIGxpc3Rpbmcgc2hvd3Mgc2NyZWVuc2hvdHMgT05FIEFUIEEgVElNRSwgaW4gYSBjYXJvdXNlbCwgd2l0aCBub1xuICogY2FwdGlvbiBvZiBpdHMgb3duIFx1MjAxNCBzbyBhbiBpbWFnZSBoYXMgdG8gc2F5IHdoYXQgaXQgaXMgc2hvd2luZy4gV2l0aG91dCB0aGF0LFxuICogYSBzaG90IG9mIHRoZSBzdGF0ZSBhIHBsdWdpbiByZW1vdmVzIHJlYWRzIGFzIGEgc2hvdCBvZiB0aGUgc3RhdGUgdGhlIHBsdWdpblxuICogY2F1c2VzLCB3aGljaCBpcyB0aGUgb3Bwb3NpdGUgb2YgdGhlIG1lc3NhZ2UuXG4gKlxuICogVGhlIGJhbmQgaXMgZHJhd24gb3ZlciB0aGUgQk9UVE9NIG9mIHRoZSBmcmFtZSwgZm9yIHR3byByZWFzb25zOiB0aGUgdG9wIGlzXG4gKiB3aGVyZSB0aGUgY29udGVudCBiZWluZyBkZW1vbnN0cmF0ZWQgdXN1YWxseSBzdGFydHMsIGFuZCB0aGUgYm90dG9tIG9mIGFuXG4gKiBPYnNpZGlhbiBmcmFtZSBpcyBjaHJvbWUgXHUyMDE0IHN0YXR1cyBiYXIsIHdvcmQgY291bnQsIHN5bmMgaW5kaWNhdG9yIFx1MjAxNCB3aGljaCB0aGVcbiAqIGJhbmQgdGhlbiBjb3ZlcnMgcmF0aGVyIHRoYW4gY29tcGV0aW5nIHdpdGguXG4gKlxuICogVGhpcyBpcyBwb3N0LXByb2Nlc3NpbmcsIGRlbGliZXJhdGVseS4gVGhlIGNhcHR1cmUgc3RheXMgYW4gdW50b3VjaGVkIGRldmljZVxuICogZnJhbWUsIGFuZCByZXdvcmRpbmcgYSBsYWJlbCBuZWVkcyBubyByZS1zaG9vdC5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IFNoYXJwQ29tcG9zaXRlTGF5ZXIgfSBmcm9tICcuL3NoYXJwLWxvYWRlci5tanMnO1xuXG5pbXBvcnQgeyBpbXBvcnRTaGFycCB9IGZyb20gJy4vc2hhcnAtbG9hZGVyLm1qcyc7XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGNvbXB1dGVMYWJlbEJhbmR9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbXB1dGVMYWJlbEJhbmRQYXJhbXMge1xuICAvKipcbiAgICogSGVpZ2h0IG9mIHRoZSBpbWFnZSBiZWluZyBsYWJlbGVkLCBpbiBwaXhlbHMuXG4gICAqL1xuICByZWFkb25seSBpbWFnZUhlaWdodEluUGl4ZWxzOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFdpZHRoIG9mIHRoZSBpbWFnZSBiZWluZyBsYWJlbGVkLCBpbiBwaXhlbHMuXG4gICAqL1xuICByZWFkb25seSBpbWFnZVdpZHRoSW5QaXhlbHM6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBUaGUgZ2VvbWV0cnkgb2YgdGhlIGNhcHRpb24gYmFuZC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBMYWJlbEJhbmRHZW9tZXRyeSB7XG4gIC8qKlxuICAgKiBGb250IHNpemUgZm9yIHRoZSBjYXB0aW9uLCBpbiBwaXhlbHMuXG4gICAqL1xuICByZWFkb25seSBmb250U2l6ZUluUGl4ZWxzOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEhlaWdodCBvZiB0aGUgYmFuZCwgaW4gcGl4ZWxzLlxuICAgKi9cbiAgcmVhZG9ubHkgaGVpZ2h0SW5QaXhlbHM6IG51bWJlcjtcblxuICAvKipcbiAgICogRGlzdGFuY2UgZnJvbSB0aGUgdG9wIG9mIHRoZSBpbWFnZSB0byB0aGUgdG9wIG9mIHRoZSBiYW5kLCBpbiBwaXhlbHMuXG4gICAqL1xuICByZWFkb25seSB0b3BJblBpeGVsczogbnVtYmVyO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayBsYWJlbFNjcmVlbnNob3R9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIExhYmVsU2NyZWVuc2hvdE9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIGNhcHRpb24uIEtlZXAgaXQgdG8gYSBoYW5kZnVsIG9mIHdvcmRzOiBpdCBpcyByZWFkIGF0IGxpc3RpbmctdGh1bWJuYWlsXG4gICAqIHNpemUsIGFuZCBpdCBpcyBjbGlwcGVkIHJhdGhlciB0aGFuIHdyYXBwZWQuXG4gICAqL1xuICByZWFkb25seSB0ZXh0OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQ2FwdGlvbiBzaXplIGFzIGEgZnJhY3Rpb24gb2YgaW1hZ2UgV0lEVEgsIG5vdCBoZWlnaHQuXG4gKlxuICogV2lkdGggaXMgd2hhdCBnb3Zlcm5zIGxlZ2liaWxpdHkgaGVyZTogYSA5MDB4MTYwMCBwaG9uZSBmcmFtZSBhbmQgYSAxMjAweDgwMFxuICogZGVza3RvcCBmcmFtZSBhcmUgcmVhZCBhdCBzaW1pbGFyIG9uLXNjcmVlbiB3aWR0aHMgaW4gYSBsaXN0aW5nLCBzbyBzaXppbmcgYnlcbiAqIHdpZHRoIGtlZXBzIHRoZSBjYXB0aW9uIHZpc3VhbGx5IGNvbnNpc3RlbnQgYWNyb3NzIHRoZSB0d28uXG4gKi9cbmNvbnN0IEZPTlRfU0laRV9SQVRJTyA9IDAuMDM0O1xuXG4vKipcbiAqIEJhbmQgaGVpZ2h0IGFzIGEgbXVsdGlwbGUgb2YgdGhlIGZvbnQgc2l6ZSBcdTIwMTQgZW5vdWdoIHRvIHNpdCB0aGUgdGV4dCBvbiB3aXRoXG4gKiBjbGVhciBzcGFjZSBhYm92ZSBhbmQgYmVsb3cuXG4gKi9cbmNvbnN0IEJBTkRfSEVJR0hUX1JBVElPID0gMi4yO1xuXG4vKipcbiAqIE9wYWNpdHkgb2YgdGhlIGJhbmQsIGRhcmsgZW5vdWdoIHRvIGNhcnJ5IGxpZ2h0IHRleHQgb3ZlciBhbnkgT2JzaWRpYW4gdGhlbWVcbiAqIHdoaWxlIHRoZSBmcmFtZSBiZW5lYXRoIHN0YXlzIGZhaW50bHkgdmlzaWJsZSByYXRoZXIgdGhhbiBsb29raW5nIGN1dCBvZmYuXG4gKi9cbmNvbnN0IEJBTkRfT1BBQ0lUWSA9IDAuODI7XG5cbmNvbnN0IE1JTklNVU1fRk9OVF9TSVpFX0lOX1BJWEVMUyA9IDE4O1xuXG4vKipcbiAqIERpdmlzb3IgdGhhdCB0dXJucyBhIHNwYW4gaW50byBpdHMgbWlkcG9pbnQsIGZvciBjZW50ZXJpbmcgdGhlIGNhcHRpb24uXG4gKi9cbmNvbnN0IENFTlRFUl9ESVZJU09SID0gMjtcblxuLyoqXG4gKiBCdWlsZHMgdGhlIFNWRyBmb3IgdGhlIGNhcHRpb24gYmFuZC5cbiAqXG4gKiBAcGFyYW0gdGV4dCAtIFRoZSBjYXB0aW9uLlxuICogQHBhcmFtIGdlb21ldHJ5IC0gVGhlIGJhbmQgZ2VvbWV0cnkuXG4gKiBAcGFyYW0gaW1hZ2VXaWR0aEluUGl4ZWxzIC0gV2lkdGggb2YgdGhlIGltYWdlLCBzbyB0aGUgYmFuZCBzcGFucyBpdC5cbiAqIEByZXR1cm5zIFRoZSBTVkcgbWFya3VwLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRMYWJlbFN2Zyh0ZXh0OiBzdHJpbmcsIGdlb21ldHJ5OiBMYWJlbEJhbmRHZW9tZXRyeSwgaW1hZ2VXaWR0aEluUGl4ZWxzOiBudW1iZXIpOiBzdHJpbmcge1xuICBjb25zdCB7IGZvbnRTaXplSW5QaXhlbHMsIGhlaWdodEluUGl4ZWxzIH0gPSBnZW9tZXRyeTtcblxuICByZXR1cm4gYDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiJHtTdHJpbmcoaW1hZ2VXaWR0aEluUGl4ZWxzKX1cIiBoZWlnaHQ9XCIke1N0cmluZyhoZWlnaHRJblBpeGVscyl9XCI+YFxuICAgICsgYDxyZWN0IHg9XCIwXCIgeT1cIjBcIiB3aWR0aD1cIiR7U3RyaW5nKGltYWdlV2lkdGhJblBpeGVscyl9XCIgaGVpZ2h0PVwiJHtTdHJpbmcoaGVpZ2h0SW5QaXhlbHMpfVwiIGBcbiAgICArIGBmaWxsPVwiIzAwMDAwMFwiIGZpbGwtb3BhY2l0eT1cIiR7U3RyaW5nKEJBTkRfT1BBQ0lUWSl9XCIvPmBcbiAgICArIGA8dGV4dCB4PVwiJHtTdHJpbmcoaW1hZ2VXaWR0aEluUGl4ZWxzIC8gQ0VOVEVSX0RJVklTT1IpfVwiIHk9XCIke1N0cmluZyhoZWlnaHRJblBpeGVscyAvIENFTlRFUl9ESVZJU09SKX1cIiBgXG4gICAgKyBgZm9udC1mYW1pbHk9XCJTZWdvZSBVSSwgSGVsdmV0aWNhLCBBcmlhbCwgc2Fucy1zZXJpZlwiIGZvbnQtc2l6ZT1cIiR7U3RyaW5nKGZvbnRTaXplSW5QaXhlbHMpfVwiIGBcbiAgICArICdmb250LXdlaWdodD1cIjYwMFwiIGZpbGw9XCIjZmZmZmZmXCIgdGV4dC1hbmNob3I9XCJtaWRkbGVcIiBkb21pbmFudC1iYXNlbGluZT1cImNlbnRyYWxcIj4nXG4gICAgKyBgJHtlc2NhcGVTdmdUZXh0KHRleHQpfTwvdGV4dD48L3N2Zz5gO1xufVxuXG4vKipcbiAqIENvbXB1dGVzIHRoZSBjYXB0aW9uIGJhbmQncyBzaXplIGFuZCBwb3NpdGlvbiBmb3IgYSBnaXZlbiBpbWFnZS5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGltYWdlIGRpbWVuc2lvbnMuXG4gKiBAcmV0dXJucyBUaGUgYmFuZCBnZW9tZXRyeS5cbiAqIEB0aHJvd3MgRXJyb3IgaWYgZWl0aGVyIGRpbWVuc2lvbiBpcyBub3QgYSBwb3NpdGl2ZSBudW1iZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlTGFiZWxCYW5kKHBhcmFtczogQ29tcHV0ZUxhYmVsQmFuZFBhcmFtcyk6IExhYmVsQmFuZEdlb21ldHJ5IHtcbiAgY29uc3QgeyBpbWFnZUhlaWdodEluUGl4ZWxzLCBpbWFnZVdpZHRoSW5QaXhlbHMgfSA9IHBhcmFtcztcblxuICBpZiAoIU51bWJlci5pc0Zpbml0ZShpbWFnZVdpZHRoSW5QaXhlbHMpIHx8IGltYWdlV2lkdGhJblBpeGVscyA8PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBjb21wdXRlTGFiZWxCYW5kOiBpbWFnZVdpZHRoSW5QaXhlbHMgbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlciwgZ290ICR7U3RyaW5nKGltYWdlV2lkdGhJblBpeGVscyl9LmApO1xuICB9XG5cbiAgaWYgKCFOdW1iZXIuaXNGaW5pdGUoaW1hZ2VIZWlnaHRJblBpeGVscykgfHwgaW1hZ2VIZWlnaHRJblBpeGVscyA8PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBjb21wdXRlTGFiZWxCYW5kOiBpbWFnZUhlaWdodEluUGl4ZWxzIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXIsIGdvdCAke1N0cmluZyhpbWFnZUhlaWdodEluUGl4ZWxzKX0uYCk7XG4gIH1cblxuICBjb25zdCBmb250U2l6ZUluUGl4ZWxzID0gTWF0aC5tYXgoTUlOSU1VTV9GT05UX1NJWkVfSU5fUElYRUxTLCBNYXRoLnJvdW5kKGltYWdlV2lkdGhJblBpeGVscyAqIEZPTlRfU0laRV9SQVRJTykpO1xuICBjb25zdCBoZWlnaHRJblBpeGVscyA9IE1hdGgubWluKGltYWdlSGVpZ2h0SW5QaXhlbHMsIE1hdGgucm91bmQoZm9udFNpemVJblBpeGVscyAqIEJBTkRfSEVJR0hUX1JBVElPKSk7XG5cbiAgcmV0dXJuIHtcbiAgICBmb250U2l6ZUluUGl4ZWxzLFxuICAgIGhlaWdodEluUGl4ZWxzLFxuICAgIHRvcEluUGl4ZWxzOiBpbWFnZUhlaWdodEluUGl4ZWxzIC0gaGVpZ2h0SW5QaXhlbHNcbiAgfTtcbn1cblxuLyoqXG4gKiBFc2NhcGVzIHRleHQgZm9yIGluY2x1c2lvbiBpbiBTVkcgY2hhcmFjdGVyIGRhdGEuXG4gKlxuICogQSBjYXB0aW9uIGlzIGF1dGhvcmVkIHBlciBzY3JlZW5zaG90IGFuZCBjYW4gbGVnaXRpbWF0ZWx5IGNvbnRhaW4gYCZgIG9yIHRoZVxuICogYW5nbGUgYnJhY2tldHMgT2JzaWRpYW4gdXNlcyBpbiBsaW5rIHN5bnRheDsgdW5lc2NhcGVkLCB0aG9zZSBtYWtlIHRoZSBTVkdcbiAqIGltcG9zc2libGUgdG8gcGFyc2UgYW5kIGBzaGFycGAgZmFpbHMgb24gYSBjYXB0aW9uIHJhdGhlciB0aGFuIG9uIGFuIGltYWdlLlxuICpcbiAqIEBwYXJhbSB0ZXh0IC0gVGhlIHJhdyBjYXB0aW9uLlxuICogQHJldHVybnMgVGhlIGNhcHRpb24sIHNhZmUgdG8gZW1iZWQgaW4gU1ZHLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZXNjYXBlU3ZnVGV4dCh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdGV4dFxuICAgIC5yZXBsYWNlQWxsKCcmJywgJyZhbXA7JylcbiAgICAucmVwbGFjZUFsbCgnPCcsICcmbHQ7JylcbiAgICAucmVwbGFjZUFsbCgnPicsICcmZ3Q7JylcbiAgICAucmVwbGFjZUFsbCgnXCInLCAnJnF1b3Q7JylcbiAgICAucmVwbGFjZUFsbCgnXFwnJywgJyZhcG9zOycpO1xufVxuXG4vKipcbiAqIERyYXdzIGEgY2FwdGlvbiBiYW5kIGFjcm9zcyB0aGUgYm90dG9tIG9mIGEgc2NyZWVuc2hvdC5cbiAqXG4gKiBUaGUgaW1hZ2Uga2VlcHMgaXRzIGRpbWVuc2lvbnMgZXhhY3RseTogdGhlIGJhbmQgaXMgY29tcG9zaXRlZCBPVkVSIHRoZVxuICogZnJhbWUsIG5ldmVyIGFwcGVuZGVkIHRvIGl0LCBiZWNhdXNlIHRoZSBzdG9yZSBleHBlY3RzIGEgc3BlY2lmaWMgc2l6ZS5cbiAqXG4gKiBAcGFyYW0gYnl0ZXMgLSBUaGUgY2FwdHVyZWQgUE5HLlxuICogQHBhcmFtIG9wdGlvbnMgLSBUaGUgY2FwdGlvbi5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGxhYmVsZWQgUE5HLCB0aGUgc2FtZSBzaXplIGFzIHRoZSBpbnB1dC5cbiAqIEB0aHJvd3MgRXJyb3IgaWYgYHNoYXJwYCBpcyBub3QgaW5zdGFsbGVkLCBvciB0aGUgaW1hZ2UgZGltZW5zaW9ucyBjYW5ub3QgYmUgcmVhZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxhYmVsU2NyZWVuc2hvdChieXRlczogVWludDhBcnJheSwgb3B0aW9uczogTGFiZWxTY3JlZW5zaG90T3B0aW9ucyk6IFByb21pc2U8VWludDhBcnJheT4ge1xuICBjb25zdCBzaGFycCA9IGF3YWl0IGltcG9ydFNoYXJwKCdsYWJlbFNjcmVlbnNob3QnKTtcbiAgY29uc3QgbWV0YWRhdGEgPSBhd2FpdCBzaGFycChieXRlcykubWV0YWRhdGEoKTtcbiAgY29uc3QgaW1hZ2VXaWR0aEluUGl4ZWxzID0gbWV0YWRhdGEud2lkdGg7XG4gIGNvbnN0IGltYWdlSGVpZ2h0SW5QaXhlbHMgPSBtZXRhZGF0YS5oZWlnaHQ7XG5cbiAgLyogdjggaWdub3JlIG5leHQgMyAtLSBEZWZlbnNpdmU6IGBzaGFycGAgcmVqZWN0cyBhIG5vbi1pbWFnZSBiZWZvcmUgaXQgY2FuIHJlcG9ydCBtZXRhZGF0YSB3aXRob3V0IGRpbWVuc2lvbnMsIHNvIHRoaXMgYnJhbmNoIGlzIHVucmVhY2hhYmxlIGZyb20gYSB0ZXN0LiAqL1xuICBpZiAoaW1hZ2VXaWR0aEluUGl4ZWxzID09PSB1bmRlZmluZWQgfHwgaW1hZ2VIZWlnaHRJblBpeGVscyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdsYWJlbFNjcmVlbnNob3Q6IGNvdWxkIG5vdCByZWFkIHRoZSBzb3VyY2UgaW1hZ2UgZGltZW5zaW9ucy4nKTtcbiAgfVxuXG4gIGNvbnN0IGdlb21ldHJ5ID0gY29tcHV0ZUxhYmVsQmFuZCh7IGltYWdlSGVpZ2h0SW5QaXhlbHMsIGltYWdlV2lkdGhJblBpeGVscyB9KTtcbiAgY29uc3Qgc3ZnID0gYnVpbGRMYWJlbFN2ZyhvcHRpb25zLnRleHQsIGdlb21ldHJ5LCBpbWFnZVdpZHRoSW5QaXhlbHMpO1xuICBjb25zdCBsYXllcjogU2hhcnBDb21wb3NpdGVMYXllciA9IHtcbiAgICBpbnB1dDogQnVmZmVyLmZyb20oc3ZnKSxcbiAgICBsZWZ0OiAwLFxuICAgIHRvcDogZ2VvbWV0cnkudG9wSW5QaXhlbHNcbiAgfTtcblxuICBjb25zdCBsYWJlbGVkID0gYXdhaXQgc2hhcnAoYnl0ZXMpXG4gICAgLmNvbXBvc2l0ZShbbGF5ZXJdKVxuICAgIC5wbmcoKVxuICAgIC50b0J1ZmZlcigpO1xuXG4gIHJldHVybiBuZXcgVWludDhBcnJheShsYWJlbGVkKTtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICJBQXFCQSxTQUFTLG1CQUFtQjtBQXVENUIsTUFBTSxrQkFBa0I7QUFNeEIsTUFBTSxvQkFBb0I7QUFNMUIsTUFBTSxlQUFlO0FBRXJCLE1BQU0sOEJBQThCO0FBS3BDLE1BQU0saUJBQWlCO0FBVWhCLFNBQVMsY0FBYyxNQUFjLFVBQTZCLG9CQUFvQztBQUMzRyxRQUFNLEVBQUUsa0JBQWtCLGVBQWUsSUFBSTtBQUU3QyxTQUFPLGtEQUFrRCxPQUFPLGtCQUFrQixDQUFDLGFBQWEsT0FBTyxjQUFjLENBQUMsOEJBQ3RGLE9BQU8sa0JBQWtCLENBQUMsYUFBYSxPQUFPLGNBQWMsQ0FBQyxrQ0FDekQsT0FBTyxZQUFZLENBQUMsZUFDeEMsT0FBTyxxQkFBcUIsY0FBYyxDQUFDLFFBQVEsT0FBTyxpQkFBaUIsY0FBYyxDQUFDLHFFQUNuQyxPQUFPLGdCQUFnQixDQUFDLHVGQUV4RixjQUFjLElBQUksQ0FBQztBQUM1QjtBQVNPLFNBQVMsaUJBQWlCLFFBQW1EO0FBQ2xGLFFBQU0sRUFBRSxxQkFBcUIsbUJBQW1CLElBQUk7QUFFcEQsTUFBSSxDQUFDLE9BQU8sU0FBUyxrQkFBa0IsS0FBSyxzQkFBc0IsR0FBRztBQUNuRSxVQUFNLElBQUksTUFBTSx1RUFBdUUsT0FBTyxrQkFBa0IsQ0FBQyxHQUFHO0FBQUEsRUFDdEg7QUFFQSxNQUFJLENBQUMsT0FBTyxTQUFTLG1CQUFtQixLQUFLLHVCQUF1QixHQUFHO0FBQ3JFLFVBQU0sSUFBSSxNQUFNLHdFQUF3RSxPQUFPLG1CQUFtQixDQUFDLEdBQUc7QUFBQSxFQUN4SDtBQUVBLFFBQU0sbUJBQW1CLEtBQUssSUFBSSw2QkFBNkIsS0FBSyxNQUFNLHFCQUFxQixlQUFlLENBQUM7QUFDL0csUUFBTSxpQkFBaUIsS0FBSyxJQUFJLHFCQUFxQixLQUFLLE1BQU0sbUJBQW1CLGlCQUFpQixDQUFDO0FBRXJHLFNBQU87QUFBQSxJQUNMO0FBQUEsSUFDQTtBQUFBLElBQ0EsYUFBYSxzQkFBc0I7QUFBQSxFQUNyQztBQUNGO0FBWU8sU0FBUyxjQUFjLE1BQXNCO0FBQ2xELFNBQU8sS0FDSixXQUFXLEtBQUssT0FBTyxFQUN2QixXQUFXLEtBQUssTUFBTSxFQUN0QixXQUFXLEtBQUssTUFBTSxFQUN0QixXQUFXLEtBQUssUUFBUSxFQUN4QixXQUFXLEtBQU0sUUFBUTtBQUM5QjtBQWFBLGVBQXNCLGdCQUFnQixPQUFtQixTQUFzRDtBQUM3RyxRQUFNLFFBQVEsTUFBTSxZQUFZLGlCQUFpQjtBQUNqRCxRQUFNLFdBQVcsTUFBTSxNQUFNLEtBQUssRUFBRSxTQUFTO0FBQzdDLFFBQU0scUJBQXFCLFNBQVM7QUFDcEMsUUFBTSxzQkFBc0IsU0FBUztBQUdyQyxNQUFJLHVCQUF1QixVQUFhLHdCQUF3QixRQUFXO0FBQ3pFLFVBQU0sSUFBSSxNQUFNLDhEQUE4RDtBQUFBLEVBQ2hGO0FBRUEsUUFBTSxXQUFXLGlCQUFpQixFQUFFLHFCQUFxQixtQkFBbUIsQ0FBQztBQUM3RSxRQUFNLE1BQU0sY0FBYyxRQUFRLE1BQU0sVUFBVSxrQkFBa0I7QUFDcEUsUUFBTSxRQUE2QjtBQUFBLElBQ2pDLE9BQU8sT0FBTyxLQUFLLEdBQUc7QUFBQSxJQUN0QixNQUFNO0FBQUEsSUFDTixLQUFLLFNBQVM7QUFBQSxFQUNoQjtBQUVBLFFBQU0sVUFBVSxNQUFNLE1BQU0sS0FBSyxFQUM5QixVQUFVLENBQUMsS0FBSyxDQUFDLEVBQ2pCLElBQUksRUFDSixTQUFTO0FBRVosU0FBTyxJQUFJLFdBQVcsT0FBTztBQUMvQjsiLAogICJuYW1lcyI6IFtdCn0K
@@ -1,4 +1,4 @@
1
- const LIBRARY_VERSION = false ? "dev" : "10.0.0";
1
+ const LIBRARY_VERSION = false ? "dev" : "10.2.0";
2
2
  export {
3
3
  LIBRARY_VERSION
4
4
  };
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @file
3
+ *
4
+ * Lazily loads `sharp`, the OPTIONAL peer dependency the image helpers need, and
5
+ * describes the slice of its surface they use.
6
+ *
7
+ * The load is deferred because a static import would drag `sharp`'s
8
+ * platform-specific native binaries into every consumer of this package's index,
9
+ * when only screenshot post-processing needs them. The type is structural for
10
+ * the same reason: this module type-checks without `sharp`'s own types being
11
+ * resolvable.
12
+ */
13
+ /**
14
+ * A layer passed to `sharp`'s `composite`.
15
+ */
16
+ export interface SharpCompositeLayer {
17
+ readonly input: Buffer;
18
+ readonly left: number;
19
+ readonly top: number;
20
+ }
21
+ /**
22
+ * The `sharp` entry point the image helpers use.
23
+ */
24
+ export type SharpFactory = (input: Uint8Array) => SharpInstance;
25
+ /**
26
+ * One `sharp` pipeline.
27
+ */
28
+ export interface SharpInstance {
29
+ blur(this: void, sigma: number): SharpInstance;
30
+ composite(this: void, layers: SharpCompositeLayer[]): SharpInstance;
31
+ metadata(this: void): Promise<SharpMetadata>;
32
+ png(this: void): SharpInstance;
33
+ resize(this: void, width: number, height: number, options?: SharpResizeOptions): SharpInstance;
34
+ toBuffer(this: void): Promise<Buffer>;
35
+ }
36
+ /**
37
+ * The subset of `sharp`'s metadata the image helpers read.
38
+ */
39
+ export interface SharpMetadata {
40
+ readonly height?: number | undefined;
41
+ readonly width?: number | undefined;
42
+ }
43
+ /**
44
+ * The subset of `sharp`'s resize options the image helpers set.
45
+ */
46
+ export interface SharpResizeOptions {
47
+ readonly fit: 'cover' | 'fill';
48
+ }
49
+ /**
50
+ * Loads `sharp` on demand.
51
+ *
52
+ * @param caller - Name of the calling helper, so the error says which one needs it.
53
+ * @returns A {@link Promise} that resolves to the `sharp` factory.
54
+ * @throws Error naming the missing optional peer dependency.
55
+ */
56
+ export declare function importSharp(caller: string): Promise<SharpFactory>;
@@ -0,0 +1,16 @@
1
+ async function importSharp(caller) {
2
+ try {
3
+ const sharpModule = await import("sharp");
4
+ const factory = sharpModule.default;
5
+ return factory;
6
+ } catch (error) {
7
+ throw new Error(
8
+ `${caller} needs the optional peer dependency "sharp". Install it in the consuming project (npm i -D sharp).`,
9
+ { cause: error }
10
+ );
11
+ }
12
+ }
13
+ export {
14
+ importSharp
15
+ };
16
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL3NoYXJwLWxvYWRlci50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIExhemlseSBsb2FkcyBgc2hhcnBgLCB0aGUgT1BUSU9OQUwgcGVlciBkZXBlbmRlbmN5IHRoZSBpbWFnZSBoZWxwZXJzIG5lZWQsIGFuZFxuICogZGVzY3JpYmVzIHRoZSBzbGljZSBvZiBpdHMgc3VyZmFjZSB0aGV5IHVzZS5cbiAqXG4gKiBUaGUgbG9hZCBpcyBkZWZlcnJlZCBiZWNhdXNlIGEgc3RhdGljIGltcG9ydCB3b3VsZCBkcmFnIGBzaGFycGAnc1xuICogcGxhdGZvcm0tc3BlY2lmaWMgbmF0aXZlIGJpbmFyaWVzIGludG8gZXZlcnkgY29uc3VtZXIgb2YgdGhpcyBwYWNrYWdlJ3MgaW5kZXgsXG4gKiB3aGVuIG9ubHkgc2NyZWVuc2hvdCBwb3N0LXByb2Nlc3NpbmcgbmVlZHMgdGhlbS4gVGhlIHR5cGUgaXMgc3RydWN0dXJhbCBmb3JcbiAqIHRoZSBzYW1lIHJlYXNvbjogdGhpcyBtb2R1bGUgdHlwZS1jaGVja3Mgd2l0aG91dCBgc2hhcnBgJ3Mgb3duIHR5cGVzIGJlaW5nXG4gKiByZXNvbHZhYmxlLlxuICovXG5cbi8qKlxuICogQSBsYXllciBwYXNzZWQgdG8gYHNoYXJwYCdzIGBjb21wb3NpdGVgLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNoYXJwQ29tcG9zaXRlTGF5ZXIge1xuICByZWFkb25seSBpbnB1dDogQnVmZmVyO1xuICByZWFkb25seSBsZWZ0OiBudW1iZXI7XG4gIHJlYWRvbmx5IHRvcDogbnVtYmVyO1xufVxuXG4vKipcbiAqIFRoZSBgc2hhcnBgIGVudHJ5IHBvaW50IHRoZSBpbWFnZSBoZWxwZXJzIHVzZS5cbiAqL1xuZXhwb3J0IHR5cGUgU2hhcnBGYWN0b3J5ID0gKGlucHV0OiBVaW50OEFycmF5KSA9PiBTaGFycEluc3RhbmNlO1xuXG4vKipcbiAqIE9uZSBgc2hhcnBgIHBpcGVsaW5lLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNoYXJwSW5zdGFuY2Uge1xuICBibHVyKHRoaXM6IHZvaWQsIHNpZ21hOiBudW1iZXIpOiBTaGFycEluc3RhbmNlO1xuICBjb21wb3NpdGUodGhpczogdm9pZCwgbGF5ZXJzOiBTaGFycENvbXBvc2l0ZUxheWVyW10pOiBTaGFycEluc3RhbmNlO1xuICBtZXRhZGF0YSh0aGlzOiB2b2lkKTogUHJvbWlzZTxTaGFycE1ldGFkYXRhPjtcbiAgcG5nKHRoaXM6IHZvaWQpOiBTaGFycEluc3RhbmNlO1xuICByZXNpemUodGhpczogdm9pZCwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIsIG9wdGlvbnM/OiBTaGFycFJlc2l6ZU9wdGlvbnMpOiBTaGFycEluc3RhbmNlO1xuICB0b0J1ZmZlcih0aGlzOiB2b2lkKTogUHJvbWlzZTxCdWZmZXI+O1xufVxuXG4vKipcbiAqIFRoZSBzdWJzZXQgb2YgYHNoYXJwYCdzIG1ldGFkYXRhIHRoZSBpbWFnZSBoZWxwZXJzIHJlYWQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2hhcnBNZXRhZGF0YSB7XG4gIHJlYWRvbmx5IGhlaWdodD86IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgcmVhZG9ubHkgd2lkdGg/OiBudW1iZXIgfCB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogVGhlIHN1YnNldCBvZiBgc2hhcnBgJ3MgcmVzaXplIG9wdGlvbnMgdGhlIGltYWdlIGhlbHBlcnMgc2V0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNoYXJwUmVzaXplT3B0aW9ucyB7XG4gIHJlYWRvbmx5IGZpdDogJ2NvdmVyJyB8ICdmaWxsJztcbn1cblxuLyoqXG4gKiBMb2FkcyBgc2hhcnBgIG9uIGRlbWFuZC5cbiAqXG4gKiBAcGFyYW0gY2FsbGVyIC0gTmFtZSBvZiB0aGUgY2FsbGluZyBoZWxwZXIsIHNvIHRoZSBlcnJvciBzYXlzIHdoaWNoIG9uZSBuZWVkcyBpdC5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGBzaGFycGAgZmFjdG9yeS5cbiAqIEB0aHJvd3MgRXJyb3IgbmFtaW5nIHRoZSBtaXNzaW5nIG9wdGlvbmFsIHBlZXIgZGVwZW5kZW5jeS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGltcG9ydFNoYXJwKGNhbGxlcjogc3RyaW5nKTogUHJvbWlzZTxTaGFycEZhY3Rvcnk+IHtcbiAgdHJ5IHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXggLS0gYHNoYXJwYCBpcyBhbiBPUFRJT05BTCBwZWVyLCBzbyBpdCBtdXN0IGJlIGxvYWRlZCBsYXppbHk6IGEgc3RhdGljIGltcG9ydCB3b3VsZCBkcmFnIGl0cyBuYXRpdmUgYmluYXJpZXMgaW50byBldmVyeSBjb25zdW1lciBvZiB0aGlzIHBhY2thZ2UncyBpbmRleC5cbiAgICBjb25zdCBzaGFycE1vZHVsZSA9IGF3YWl0IGltcG9ydCgnc2hhcnAnKTtcbiAgICBjb25zdCBmYWN0b3J5OiB1bmtub3duID0gc2hhcnBNb2R1bGUuZGVmYXVsdDtcbiAgICByZXR1cm4gZmFjdG9yeSBhcyBTaGFycEZhY3Rvcnk7XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgLyogdjggaWdub3JlIHN0YXJ0IC0tIFJlYWNoZWQgb25seSB3aGVuIHRoZSBvcHRpb25hbCBwZWVyIGlzIGFic2VudCwgd2hpY2ggaXQgbmV2ZXIgaXMgaW4gdGhpcyBwYWNrYWdlJ3Mgb3duIHRlc3QgcnVuLiAqL1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGAke2NhbGxlcn0gbmVlZHMgdGhlIG9wdGlvbmFsIHBlZXIgZGVwZW5kZW5jeSBcInNoYXJwXCIuIGBcbiAgICAgICAgKyAnSW5zdGFsbCBpdCBpbiB0aGUgY29uc3VtaW5nIHByb2plY3QgKG5wbSBpIC1EIHNoYXJwKS4nLFxuICAgICAgeyBjYXVzZTogZXJyb3IgfVxuICAgICk7XG4gICAgLyogdjggaWdub3JlIHN0b3AgKi9cbiAgfVxufVxuIl0sCiAgIm1hcHBpbmdzIjogIkFBNkRBLGVBQXNCLFlBQVksUUFBdUM7QUFDdkUsTUFBSTtBQUVGLFVBQU0sY0FBYyxNQUFNLE9BQU8sT0FBTztBQUN4QyxVQUFNLFVBQW1CLFlBQVk7QUFDckMsV0FBTztBQUFBLEVBQ1QsU0FBUyxPQUFnQjtBQUV2QixVQUFNLElBQUk7QUFBQSxNQUNSLEdBQUcsTUFBTTtBQUFBLE1BRVQsRUFBRSxPQUFPLE1BQU07QUFBQSxJQUNqQjtBQUFBLEVBRUY7QUFDRjsiLAogICJuYW1lcyI6IFtdCn0K