rapier-markdown-kit 1.2.45 → 1.2.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +12 -5
- package/README.md +134 -11
- package/dist/agent/vendor/BROWSER-ENTITIES.json +36 -0
- package/dist/agent/vendor/MARKDOWN-RUNTIME.json +136 -0
- package/dist/agent/vendor/MARKDOWNIT.json +582 -0
- package/dist/agent/vendor/NOTICE.txt +60 -0
- package/dist/agent/vendor/markdown-licenses/entities-LICENSE.txt +11 -0
- package/dist/agent/vendor/markdown-licenses/linkify-it-LICENSE.txt +22 -0
- package/dist/agent/vendor/markdown-licenses/markdown-it-LICENSE.txt +22 -0
- package/dist/agent/vendor/markdown-licenses/mdurl-LICENSE.txt +45 -0
- package/dist/agent/vendor/markdown-licenses/punycode.js-LICENSE-MIT.txt +20 -0
- package/dist/agent/vendor/markdown-licenses/uc.micro-LICENSE.txt +20 -0
- package/dist/agent/vendor/markdown-plugins.json +46 -0
- package/dist/agent/vendor/markdown-plugins.mjs +27 -0
- package/dist/agent/vendor/markdown-runtime.mjs +13 -0
- package/dist/kit/artifact-modules.mjs +19 -0
- package/dist/kit/assets.d.mts +106 -0
- package/dist/kit/export-fonts.mjs +28 -19
- package/dist/kit/index.d.mts +151 -0
- package/dist/kit/layout.d.mts +61 -0
- package/dist/kit/ledger/carried.d.mts +12 -6
- package/dist/kit/ledger/carried.mjs +17 -8
- package/dist/kit/ledger/format.mjs +5 -3
- package/dist/kit/ledger/source.mjs +31 -2
- package/dist/kit/ledger/text-merge.mjs +33 -0
- package/dist/kit/ledger/transport.mjs +61 -2
- package/dist/kit/ledger.d.mts +137 -31
- package/dist/kit/markdown-it.d.mts +2 -2
- package/dist/kit/marks.d.mts +241 -0
- package/dist/kit/marks.mjs +39 -1
- package/dist/kit/model.d.mts +191 -0
- package/dist/kit/pdf-source-digest.mjs +10 -0
- package/dist/kit/pdf-source.mjs +4 -1
- package/dist/kit/pdf-vectors.mjs +3 -2
- package/dist/kit/render-entry.d.mts +654 -0
- package/dist/kit/render-markdown.mjs +14 -8
- package/dist/kit/render-print.mjs +36 -7
- package/dist/kit/render.mjs +16 -14
- package/dist/kit/typography.d.mts +42 -0
- package/dist/kit/will.d.mts +26 -3
- package/dist/layout/initial-range.mjs +18 -0
- package/dist/layout/typography.mjs +2 -18
- package/dist/math/delimiters.mjs +38 -0
- package/dist/math/markdown-rules.mjs +103 -0
- package/dist/packages/rapier-diff/concerns.mjs +2 -2
- package/dist/spec/document-fonts.mjs +62 -16
- package/dist/spec/md-assets.mjs +1 -0
- package/dist/spec/md-comments.mjs +384 -0
- package/dist/spec/md-marks.mjs +9 -0
- package/dist/spec/md-parser-config.mjs +463 -0
- package/dist/spec/md-parser-runtime.mjs +23 -0
- package/package.json +30 -8
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
import type {Layout} from './layout.mjs';
|
|
3
|
+
export {};
|
|
4
|
+
|
|
5
|
+
export interface RichTextItem {
|
|
6
|
+
text: string;
|
|
7
|
+
font: string;
|
|
8
|
+
letterSpacing?: number;
|
|
9
|
+
extraWidth?: number;
|
|
10
|
+
break?: 'normal' | 'never';
|
|
11
|
+
hyphenate?: boolean;
|
|
12
|
+
width?: never;
|
|
13
|
+
}
|
|
14
|
+
export interface RichBoxItem {width: number; text?: never}
|
|
15
|
+
export type RichItem = RichTextItem | RichBoxItem;
|
|
16
|
+
export interface PreparationOptions {
|
|
17
|
+
whiteSpace?: 'normal' | 'pre-wrap';
|
|
18
|
+
wordBreak?: 'normal' | 'keep-all';
|
|
19
|
+
language?: string;
|
|
20
|
+
policy?: 'wrap' | 'paragraph';
|
|
21
|
+
hanging?: boolean;
|
|
22
|
+
paragraphBreaks?: readonly number[] | null;
|
|
23
|
+
}
|
|
24
|
+
declare const preparedInline: unique symbol;
|
|
25
|
+
declare const preparedParagraph: unique symbol;
|
|
26
|
+
/** Opaque measured source. Retain the handle rather than cloning or serializing it. */
|
|
27
|
+
export interface PreparedRichParagraph {readonly [preparedInline]: true}
|
|
28
|
+
/** Paragraph-fit geometry is distinct from the inline engine's handle. */
|
|
29
|
+
export interface ParagraphGeometry {readonly [preparedParagraph]: true}
|
|
30
|
+
export type PreparedHandle = PreparedRichParagraph | ParagraphGeometry;
|
|
31
|
+
type WrapPreparation = PreparationOptions & {policy?: 'wrap'};
|
|
32
|
+
type ParagraphPreparation = PreparationOptions & {policy: 'paragraph'};
|
|
33
|
+
/** Cancellation with return() publishes no handle or plan. */
|
|
34
|
+
export interface PreparationWork<T> extends IterableIterator<void, T | null | undefined, void> {
|
|
35
|
+
return(value?: T | null): IteratorReturnResult<T | null | undefined>;
|
|
36
|
+
}
|
|
37
|
+
export type PreparationSteps = PreparationWork<PreparedHandle>;
|
|
38
|
+
export interface FitWidthRequest {segment: number; word: number; from: number; to: number}
|
|
39
|
+
export type ReadKnownWidth = (request: FitWidthRequest) => number | undefined;
|
|
40
|
+
export type FitWork<P> = Generator<FitWidthRequest | null, P | null, number | undefined>;
|
|
41
|
+
export type FrozenFitPlan<P extends {lines: object[]}> = Readonly<Omit<P, 'lines'>> & {
|
|
42
|
+
readonly lines: readonly Readonly<P['lines'][number]>[];
|
|
43
|
+
};
|
|
44
|
+
export interface PreparationScope {
|
|
45
|
+
prepare(owner: object, items: readonly RichItem[], options: ParagraphPreparation): ParagraphGeometry | null;
|
|
46
|
+
prepare(owner: object, items: readonly RichItem[], options?: WrapPreparation): PreparedRichParagraph | null;
|
|
47
|
+
prepare(owner: object, items: readonly RichItem[], options: PreparationOptions): PreparedHandle | null;
|
|
48
|
+
prepareSteps(owner: object, items: readonly RichItem[], options: ParagraphPreparation): PreparationWork<ParagraphGeometry>;
|
|
49
|
+
prepareSteps(owner: object, items: readonly RichItem[], options?: WrapPreparation): PreparationWork<PreparedRichParagraph>;
|
|
50
|
+
prepareSteps(owner: object, items: readonly RichItem[], options: PreparationOptions): PreparationSteps;
|
|
51
|
+
fit<P extends {lines: object[]}>(owner: object, handle: ParagraphGeometry,
|
|
52
|
+
createWork: (readKnown: ReadKnownWidth) => FitWork<P>): FrozenFitPlan<P> | null;
|
|
53
|
+
fitSteps<P extends {lines: object[]}>(owner: object, handle: ParagraphGeometry,
|
|
54
|
+
createWork: (readKnown: ReadKnownWidth) => FitWork<P>): PreparationWork<FrozenFitPlan<P>>;
|
|
55
|
+
current(handle: PreparedHandle | null | undefined): boolean;
|
|
56
|
+
invalidateFonts(): number;
|
|
57
|
+
forget(owner: object): void;
|
|
58
|
+
retire(options?: {documentChanged?: boolean}): void;
|
|
59
|
+
}
|
|
60
|
+
export function createPreparationScope(document?: Document | null): PreparationScope;
|
|
61
|
+
export function prepareRichParagraph(items: readonly RichItem[], options: ParagraphPreparation): ParagraphGeometry | null;
|
|
62
|
+
export function prepareRichParagraph(items: readonly RichItem[], options?: WrapPreparation): PreparedRichParagraph | null;
|
|
63
|
+
export function prepareRichParagraph(items: readonly RichItem[], options: PreparationOptions): PreparedHandle | null;
|
|
64
|
+
export function captureFontAuthority(document?: Document | null): number;
|
|
65
|
+
export function invalidateRichMetrics(document?: Document | null): number;
|
|
66
|
+
/** Unsupported properties are accepted as input and return false, without changing the source. */
|
|
67
|
+
export interface RichStyle {
|
|
68
|
+
writingMode?: string; direction?: string; unicodeBidi?: string; textTransform?: string;
|
|
69
|
+
fontKerning?: string; fontOpticalSizing?: string; fontStretch?: string; fontSizeAdjust?: string;
|
|
70
|
+
textRendering?: string; verticalAlign?: string; whiteSpace?: string; wordBreak?: string;
|
|
71
|
+
hyphens?: string; lineBreak?: string; hangingPunctuation?: string; tabSize?: string;
|
|
72
|
+
textWrapStyle?: string; fontFeatureSettings?: string; fontVariationSettings?: string;
|
|
73
|
+
fontVariant?: string; fontVariantLigatures?: string; fontVariantCaps?: string;
|
|
74
|
+
fontVariantNumeric?: string; fontVariantEastAsian?: string; fontVariantPosition?: string;
|
|
75
|
+
fontVariantAlternates?: string; fontSynthesis?: string; fontSynthesisWeight?: string;
|
|
76
|
+
fontSynthesisStyle?: string; fontSynthesisSmallCaps?: string; letterSpacing?: string; wordSpacing?: string;
|
|
77
|
+
}
|
|
78
|
+
export function supportsRichStyle(style: RichStyle | null | undefined, contentLanguage?: string): boolean;
|
|
79
|
+
|
|
80
|
+
declare const richCursor: unique symbol;
|
|
81
|
+
declare const fragmentCursor: unique symbol;
|
|
82
|
+
export interface RichInlineCursor {readonly [richCursor]: true}
|
|
83
|
+
export interface RichFragmentCursor {readonly [fragmentCursor]: true}
|
|
84
|
+
export interface RichInlineFragmentRange {
|
|
85
|
+
itemIndex: number;
|
|
86
|
+
gapBefore: number;
|
|
87
|
+
gapItemIndex: number;
|
|
88
|
+
occupiedWidth: number;
|
|
89
|
+
start: RichFragmentCursor;
|
|
90
|
+
end: RichFragmentCursor;
|
|
91
|
+
}
|
|
92
|
+
export interface RichInlineLineRange {
|
|
93
|
+
fragments: RichInlineFragmentRange[];
|
|
94
|
+
width: number;
|
|
95
|
+
end: RichInlineCursor;
|
|
96
|
+
}
|
|
97
|
+
export interface FlowFragment {
|
|
98
|
+
itemIndex: number;
|
|
99
|
+
sourceStart: number;
|
|
100
|
+
sourceEnd: number;
|
|
101
|
+
gapBefore: number;
|
|
102
|
+
gapItemIndex: number;
|
|
103
|
+
occupiedWidth: number;
|
|
104
|
+
}
|
|
105
|
+
export interface MaterializedFragment extends FlowFragment {
|
|
106
|
+
text: string;
|
|
107
|
+
}
|
|
108
|
+
export interface MaterializedLine {
|
|
109
|
+
fragments: MaterializedFragment[];
|
|
110
|
+
width: number;
|
|
111
|
+
end: RichInlineCursor;
|
|
112
|
+
}
|
|
113
|
+
export function layoutNextRichInlineLineRange(prepared: PreparedRichParagraph, maxWidth: number,
|
|
114
|
+
start?: RichInlineCursor): RichInlineLineRange | null;
|
|
115
|
+
export function materializeRichInlineLineRange(prepared: PreparedRichParagraph, line: RichInlineLineRange): MaterializedLine;
|
|
116
|
+
export interface MappedFragment {text: string; offsets: number[]; start: number; end: number}
|
|
117
|
+
export type MappableFragment = {sourceStart: number; sourceEnd: number} & (
|
|
118
|
+
{text: string; derive?: false} | {derive: true; glyph?: string}
|
|
119
|
+
);
|
|
120
|
+
export function mapFragment(run: string | {raw: string; break?: 'normal' | 'never'}, fragment: MappableFragment,
|
|
121
|
+
options?: {whiteSpace?: 'normal' | 'pre-wrap'}): MappedFragment | null;
|
|
122
|
+
|
|
123
|
+
export interface LineMetrics {line: number; cap: number; capTop: number}
|
|
124
|
+
export interface FontMeasurementAuthority {
|
|
125
|
+
captureFontAuthority(document: Document): number;
|
|
126
|
+
fontReady(document: Document, font: string, text: string): boolean;
|
|
127
|
+
}
|
|
128
|
+
export function createLineMeasurer(authority?: FontMeasurementAuthority | null): (element: Element | null | undefined) => LineMetrics | null;
|
|
129
|
+
export function lineMetrics(element: Element | null | undefined): LineMetrics | null;
|
|
130
|
+
export function linesHeight(lines: number, metrics: Pick<LineMetrics, 'line' | 'cap'> | null | undefined): number | null;
|
|
131
|
+
export interface PictureBox {x: number; width: number; height: number}
|
|
132
|
+
export interface Rect extends PictureBox {y: number}
|
|
133
|
+
export function linesSlices<T extends Rect>(slices: readonly T[], layout: Layout | null | undefined,
|
|
134
|
+
metrics: LineMetrics | null | undefined, y: number, height: number): T[] | readonly T[];
|
|
135
|
+
export function linesTop(layout: Layout | null | undefined, metrics: LineMetrics | null | undefined): number;
|
|
136
|
+
export function imageBox(columnWidth: number, naturalWidth: number, naturalHeight: number, layout?: Layout,
|
|
137
|
+
defaultWidth?: number, metrics?: LineMetrics | null): PictureBox | null;
|
|
138
|
+
export interface ReservedRaster {
|
|
139
|
+
fit: PictureBox;
|
|
140
|
+
reserved: PictureBox;
|
|
141
|
+
visualDeltaX: number;
|
|
142
|
+
visualDeltaY: number;
|
|
143
|
+
}
|
|
144
|
+
export function rasterReserved(columnWidth: number, unrotated: PictureBox | null, rad: number): ReservedRaster | null;
|
|
145
|
+
export type ProfileSpan = readonly [number, number];
|
|
146
|
+
export interface SpanProfile {
|
|
147
|
+
spanAt(t: number): ProfileSpan | null;
|
|
148
|
+
runsAt?(t: number): readonly ProfileSpan[] | null;
|
|
149
|
+
}
|
|
150
|
+
export type ShapeProfile = SpanProfile | {runsAt(t: number): readonly ProfileSpan[] | null; spanAt?(t: number): ProfileSpan | null};
|
|
151
|
+
export interface RunProfile extends SpanProfile {runsAt(t: number): readonly ProfileSpan[]}
|
|
152
|
+
export function alphaProfile(image: HTMLImageElement): RunProfile | null;
|
|
153
|
+
export function polygonProfile(corners: readonly ProfileSpan[]): SpanProfile;
|
|
154
|
+
export function rotatedBoundsRad(width: number, height: number, rad: number): {width: number; height: number};
|
|
155
|
+
export function rasterTiltProfile(width: number, height: number, rad: number): SpanProfile;
|
|
156
|
+
export function rotatedRasterAlpha(baseAlpha: RunProfile | null, width: number, height: number, rad: number): RunProfile | null;
|
|
157
|
+
export function bandsProfile(bands: readonly (readonly ProfileSpan[])[]): RunProfile | null;
|
|
158
|
+
export function serializeProfile(profile: ShapeProfile | null | undefined, count?: number): string;
|
|
159
|
+
export function parseProfile(text: string): RunProfile | null;
|
|
160
|
+
export function frameScale(element: Element | null | undefined): number;
|
|
161
|
+
export function pictureSlices(profile: ShapeProfile | null, x: number, y: number, width: number, height: number, scale?: number): Rect[];
|
|
162
|
+
export function besideSlices<T extends Rect>(slices: readonly T[], columnLeft: number, columnRight: number,
|
|
163
|
+
pictureLeft: number, pictureWidth: number): readonly T[];
|
|
164
|
+
export interface BandSlot {x: number; width: number}
|
|
165
|
+
export interface FlowSlot extends BandSlot {y: number; block?: number; channel?: number}
|
|
166
|
+
export type SlotsForBand = (width: number, obstacles: readonly Rect[], top: number, height: number, minWidth?: number) => BandSlot[] | null;
|
|
167
|
+
export const slotsForBand: SlotsForBand;
|
|
168
|
+
export interface SlotSequenceResult {slots: FlowSlot[]; end: number; multiple: boolean}
|
|
169
|
+
export type SlotSequence = (width: number, top: number, obstacles: readonly Rect[], lineHeight: number,
|
|
170
|
+
minWidth: number, slotsForBand: SlotsForBand, direction?: 'ltr' | 'rtl', order?: 'columns' | 'rows') => SlotSequenceResult | null;
|
|
171
|
+
export const slotSequence: SlotSequence;
|
|
172
|
+
export function columnsFilled(slots: readonly FlowSlot[], placed: readonly FlowSlot[]): boolean;
|
|
173
|
+
export type FlowLine<F extends FlowFragment = MaterializedFragment> = FlowSlot & {fragments: F[]} &
|
|
174
|
+
(F extends MaterializedFragment ? {end: RichInlineCursor} : {wordSpacing: number});
|
|
175
|
+
export interface FlowPlan<F extends FlowFragment = MaterializedFragment> {lines: FlowLine<F>[]; height: number}
|
|
176
|
+
export function flowLines(flow: PreparedRichParagraph, width: number, top: number, obstacles: readonly Rect[],
|
|
177
|
+
lineHeight: number, minWidth: number, direction?: 'ltr' | 'rtl', balance?: number,
|
|
178
|
+
align?: 'start' | 'end' | 'left' | 'right' | 'center' | 'justify'): FlowPlan | null;
|
|
179
|
+
export interface WrapShape {boxWidth: number; boxHeight: number; startY: number; points: [number, number][]}
|
|
180
|
+
export function wrapShape(side: 'left' | 'right', obstacles: readonly Rect[], width: number, top: number): WrapShape | null;
|
|
181
|
+
export function boxClearance(obstacles: readonly Rect[], width: number, top: number, height: number,
|
|
182
|
+
floor: number): {left: number; right: number; fits: boolean} | null;
|
|
183
|
+
export interface EdgeLine {block: Element; top: number; bottom: number; start: number; content: number}
|
|
184
|
+
export function edgeLines(root: Element, skip?: (text: Text) => boolean): EdgeLine[];
|
|
185
|
+
export interface EdgeMarks {
|
|
186
|
+
markers: {item: Element; shift: number}[];
|
|
187
|
+
bars: {quote: Element; runs: {shift: number; top: number; bottom: number}[]}[];
|
|
188
|
+
steps: Element[];
|
|
189
|
+
}
|
|
190
|
+
export function edgeMarks(root: Element, before: readonly EdgeLine[], skip?: (text: Text) => boolean): EdgeMarks;
|
|
191
|
+
export function imageOnly(paragraph: Node, image: Node): boolean;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
export const PDF_SOURCE_DIGEST = '/RapierSourceDigest <' + '0'.repeat(64) + '>';
|
|
3
|
+
|
|
4
|
+
export async function pdfSourceDigest(bytes, start, end) {
|
|
5
|
+
if (!Number.isSafeInteger(start) || !Number.isSafeInteger(end) || start < 0 || start + 64 > end || end > bytes.length)
|
|
6
|
+
throw new Error('Invalid PDF source digest range.');
|
|
7
|
+
const bound = bytes.slice(0, end);
|
|
8
|
+
bound.fill(48, start, start + 64);
|
|
9
|
+
return Array.from(new Uint8Array(await crypto.subtle.digest('SHA-256', bound)), byte => byte.toString(16).padStart(2, '0')).join('');
|
|
10
|
+
}
|
package/dist/kit/pdf-source.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
+
import {PDF_SOURCE_DIGEST, pdfSourceDigest} from './pdf-source-digest.mjs';
|
|
2
3
|
function pdfStructure(input) {
|
|
3
4
|
const bytes = input instanceof Uint8Array ? input : new Uint8Array(input);
|
|
4
5
|
const fail = () => { throw Object.assign(new Error('The PDF source could not be attached.'), {code: 'pdf_source_invalid'}); };
|
|
@@ -116,10 +117,12 @@ export async function attachPdfSource(input, {source, filename, maxBytes = Infin
|
|
|
116
117
|
table += place ? String(place.at).padStart(10, '0') + ' ' + String(place.generation).padStart(5, '0') + ' n \n' : '0000000000 00000 f \n';
|
|
117
118
|
}
|
|
118
119
|
const identity = trailer.fields.get('ID');
|
|
119
|
-
table += 'trailer\n<< /Size ' + totalSize + ' /Root ' + rootId + ' ' + generation + ' R /Info ' + infoId + ' 0 R' + (identity ? ' /ID ' + identity.value : '') + ' >>\nstartxref\n' + length + '\n%%EOF\n';
|
|
120
|
+
table += 'trailer\n<< /Size ' + totalSize + ' /Root ' + rootId + ' ' + generation + ' R /Info ' + infoId + ' 0 R' + (identity ? ' /ID ' + identity.value : '') + ' ' + PDF_SOURCE_DIGEST + ' >>\nstartxref\n' + length + '\n%%EOF\n';
|
|
121
|
+
const digestAt = length + table.indexOf(PDF_SOURCE_DIGEST) + PDF_SOURCE_DIGEST.indexOf('<') + 1;
|
|
120
122
|
parts.push(ascii(table)); length += table.length;
|
|
121
123
|
if (length > maxBytes) throw Object.assign(new Error('The exported file exceeds the file limit.'), {code: 'export_too_large'});
|
|
122
124
|
const result = new Uint8Array(length); let at = 0;
|
|
123
125
|
for (const chunk of parts) { result.set(chunk, at); at += chunk.length; }
|
|
126
|
+
result.set(encode.encode(await pdfSourceDigest(result, digestAt, result.length - 1)), digestAt);
|
|
124
127
|
check(); return result;
|
|
125
128
|
}
|
package/dist/kit/pdf-vectors.mjs
CHANGED
|
@@ -157,14 +157,15 @@ export async function collectPdfVectors(main, {width, height, count, capture, si
|
|
|
157
157
|
const wrap = document.createElement('div');
|
|
158
158
|
wrap.style.cssText = `position:fixed;left:0;top:0;width:${box.width}px;height:${box.height}px;pointer-events:none;background:transparent`;
|
|
159
159
|
clone.style.setProperty('width', box.width + 'px', 'important'); clone.style.setProperty('height', box.height + 'px', 'important');
|
|
160
|
-
|
|
160
|
+
const surface = document.createElement('div'); surface.style.cssText = 'width:100%;height:100%';
|
|
161
|
+
surface.append(clone); wrap.attachShadow({mode: 'open'}).append(surface); document.body.append(wrap);
|
|
161
162
|
try {
|
|
162
163
|
const plainText = node.localName === 'text' && window.getComputedStyle(node).filter === 'none' && window.getComputedStyle(node).textShadow === 'none';
|
|
163
164
|
const bounds = plainText ? node.getBoundingClientRect() : box;
|
|
164
165
|
const left = Math.max(0, bounds.left - box.left - 2), top = Math.max(0, bounds.top - box.top - 2);
|
|
165
166
|
const right = Math.min(box.width, bounds.right - box.left + 2), bottom = Math.min(box.height, bounds.bottom - box.top + 2);
|
|
166
167
|
if (!(right > left && bottom > top)) return;
|
|
167
|
-
const result = await capture({root:
|
|
168
|
+
const result = await capture({root: surface, clip: {x: left, y: top, width: right - left, height: bottom - top}, transparent: true, scale: 2, signal, current, pixels: true}); check();
|
|
168
169
|
if (result?.rgb instanceof Uint8Array && result?.alpha instanceof Uint8Array) {
|
|
169
170
|
return {image: {rgb: await compress(result.rgb), alpha: await compress(result.alpha), width: result.width, height: result.height}, x: box.left - origin.left + left, y: box.top - origin.top + top, width: right - left, height: bottom - top};
|
|
170
171
|
}
|