@12ui/design 0.2.13 → 0.2.15
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/README.md +35 -9
- package/dist/bounded-concurrency.d.ts +13 -0
- package/dist/bounded-concurrency.d.ts.map +1 -0
- package/dist/bounded-concurrency.js +43 -0
- package/dist/bounded-concurrency.js.map +1 -0
- package/dist/branch-client.d.ts +155 -0
- package/dist/branch-client.d.ts.map +1 -0
- package/dist/branch-client.js +179 -0
- package/dist/branch-client.js.map +1 -0
- package/dist/branch-completion.d.ts +37 -0
- package/dist/branch-completion.d.ts.map +1 -0
- package/dist/branch-completion.js +137 -0
- package/dist/branch-completion.js.map +1 -0
- package/dist/branch-dispatch-loop.d.ts +84 -0
- package/dist/branch-dispatch-loop.d.ts.map +1 -0
- package/dist/branch-dispatch-loop.js +206 -0
- package/dist/branch-dispatch-loop.js.map +1 -0
- package/dist/branch-downloads.d.ts +53 -0
- package/dist/branch-downloads.d.ts.map +1 -0
- package/dist/branch-downloads.js +114 -0
- package/dist/branch-downloads.js.map +1 -0
- package/dist/branch-execution-types.d.ts +54 -0
- package/dist/branch-execution-types.d.ts.map +1 -0
- package/dist/branch-execution-types.js +2 -0
- package/dist/branch-execution-types.js.map +1 -0
- package/dist/branch-execution.d.ts +20 -0
- package/dist/branch-execution.d.ts.map +1 -0
- package/dist/branch-execution.js +380 -0
- package/dist/branch-execution.js.map +1 -0
- package/dist/branch-identity.d.ts +71 -0
- package/dist/branch-identity.d.ts.map +1 -0
- package/dist/branch-identity.js +72 -0
- package/dist/branch-identity.js.map +1 -0
- package/dist/branch-materialize.d.ts +33 -0
- package/dist/branch-materialize.d.ts.map +1 -0
- package/dist/branch-materialize.js +64 -0
- package/dist/branch-materialize.js.map +1 -0
- package/dist/branch-page-conversion.d.ts +127 -0
- package/dist/branch-page-conversion.d.ts.map +1 -0
- package/dist/branch-page-conversion.js +382 -0
- package/dist/branch-page-conversion.js.map +1 -0
- package/dist/branch-plan.d.ts +63 -0
- package/dist/branch-plan.d.ts.map +1 -0
- package/dist/branch-plan.js +95 -0
- package/dist/branch-plan.js.map +1 -0
- package/dist/branch-progress.d.ts +99 -0
- package/dist/branch-progress.d.ts.map +1 -0
- package/dist/branch-progress.js +188 -0
- package/dist/branch-progress.js.map +1 -0
- package/dist/branch-run-record.d.ts +164 -0
- package/dist/branch-run-record.d.ts.map +1 -0
- package/dist/branch-run-record.js +94 -0
- package/dist/branch-run-record.js.map +1 -0
- package/dist/branch-schedule.d.ts +74 -0
- package/dist/branch-schedule.d.ts.map +1 -0
- package/dist/branch-schedule.js +130 -0
- package/dist/branch-schedule.js.map +1 -0
- package/dist/branch-status.d.ts +11 -0
- package/dist/branch-status.d.ts.map +1 -0
- package/dist/branch-status.js +118 -0
- package/dist/branch-status.js.map +1 -0
- package/dist/branch-viewport-normalization.d.ts +74 -0
- package/dist/branch-viewport-normalization.d.ts.map +1 -0
- package/dist/branch-viewport-normalization.js +120 -0
- package/dist/branch-viewport-normalization.js.map +1 -0
- package/dist/cli-arguments.d.ts.map +1 -1
- package/dist/cli-arguments.js +5 -0
- package/dist/cli-arguments.js.map +1 -1
- package/dist/cli-branch-command.d.ts +55 -0
- package/dist/cli-branch-command.d.ts.map +1 -0
- package/dist/cli-branch-command.js +475 -0
- package/dist/cli-branch-command.js.map +1 -0
- package/dist/cli-capabilities.d.ts +51 -0
- package/dist/cli-capabilities.d.ts.map +1 -1
- package/dist/cli-capabilities.js +52 -1
- package/dist/cli-capabilities.js.map +1 -1
- package/dist/cli-create-command.d.ts +21 -0
- package/dist/cli-create-command.d.ts.map +1 -0
- package/dist/cli-create-command.js +319 -0
- package/dist/cli-create-command.js.map +1 -0
- package/dist/cli-detach.d.ts +62 -0
- package/dist/cli-detach.d.ts.map +1 -0
- package/dist/cli-detach.js +123 -0
- package/dist/cli-detach.js.map +1 -0
- package/dist/cli-draft-command.d.ts +63 -0
- package/dist/cli-draft-command.d.ts.map +1 -0
- package/dist/cli-draft-command.js +220 -0
- package/dist/cli-draft-command.js.map +1 -0
- package/dist/cli-export-command.d.ts.map +1 -1
- package/dist/cli-export-command.js +2 -3
- package/dist/cli-export-command.js.map +1 -1
- package/dist/cli-image-batch-command.d.ts +21 -0
- package/dist/cli-image-batch-command.d.ts.map +1 -1
- package/dist/cli-image-batch-command.js +65 -4
- package/dist/cli-image-batch-command.js.map +1 -1
- package/dist/cli-image-batch-resume.d.ts +7 -0
- package/dist/cli-image-batch-resume.d.ts.map +1 -1
- package/dist/cli-image-batch-resume.js +19 -2
- package/dist/cli-image-batch-resume.js.map +1 -1
- package/dist/cli-package-command.d.ts +29 -0
- package/dist/cli-package-command.d.ts.map +1 -0
- package/dist/cli-package-command.js +128 -0
- package/dist/cli-package-command.js.map +1 -0
- package/dist/cli-progress.d.ts +137 -0
- package/dist/cli-progress.d.ts.map +1 -1
- package/dist/cli-progress.js +156 -0
- package/dist/cli-progress.js.map +1 -1
- package/dist/cli-select-command.d.ts +12 -0
- package/dist/cli-select-command.d.ts.map +1 -0
- package/dist/cli-select-command.js +66 -0
- package/dist/cli-select-command.js.map +1 -0
- package/dist/cli.js +150 -7
- package/dist/cli.js.map +1 -1
- package/dist/conversion-receipt.d.ts +127 -0
- package/dist/conversion-receipt.d.ts.map +1 -0
- package/dist/conversion-receipt.js +184 -0
- package/dist/conversion-receipt.js.map +1 -0
- package/dist/create-identity.d.ts +25 -0
- package/dist/create-identity.d.ts.map +1 -0
- package/dist/create-identity.js +0 -0
- package/dist/create-identity.js.map +1 -0
- package/dist/draft-identity.d.ts +30 -0
- package/dist/draft-identity.d.ts.map +1 -0
- package/dist/draft-identity.js +0 -0
- package/dist/draft-identity.js.map +1 -0
- package/dist/draft-prompts.d.ts +35 -0
- package/dist/draft-prompts.d.ts.map +1 -0
- package/dist/draft-prompts.js +51 -0
- package/dist/draft-prompts.js.map +1 -0
- package/dist/draft-run.d.ts +32 -0
- package/dist/draft-run.d.ts.map +1 -0
- package/dist/draft-run.js +152 -0
- package/dist/draft-run.js.map +1 -0
- package/dist/draft-workspace.d.ts +90 -0
- package/dist/draft-workspace.d.ts.map +1 -0
- package/dist/draft-workspace.js +64 -0
- package/dist/draft-workspace.js.map +1 -0
- package/dist/image-batch-status.d.ts +42 -0
- package/dist/image-batch-status.d.ts.map +1 -0
- package/dist/image-batch-status.js +142 -0
- package/dist/image-batch-status.js.map +1 -0
- package/dist/image-dimensions.d.ts +12 -0
- package/dist/image-dimensions.d.ts.map +1 -0
- package/dist/image-dimensions.js +14 -0
- package/dist/image-dimensions.js.map +1 -0
- package/dist/image-generation-resume.d.ts +13 -0
- package/dist/image-generation-resume.d.ts.map +1 -1
- package/dist/image-generation-resume.js +13 -0
- package/dist/image-generation-resume.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/legacy-skill-catalog.d.ts.map +1 -1
- package/dist/legacy-skill-catalog.js +140 -0
- package/dist/legacy-skill-catalog.js.map +1 -1
- package/dist/package-client.d.ts +28 -0
- package/dist/package-client.d.ts.map +1 -1
- package/dist/package-client.js +21 -1
- package/dist/package-client.js.map +1 -1
- package/dist/package-manifest-file.d.ts +21 -0
- package/dist/package-manifest-file.d.ts.map +1 -0
- package/dist/package-manifest-file.js +119 -0
- package/dist/package-manifest-file.js.map +1 -0
- package/dist/package-manifest-template.d.ts +23 -0
- package/dist/package-manifest-template.d.ts.map +1 -0
- package/dist/package-manifest-template.js +60 -0
- package/dist/package-manifest-template.js.map +1 -0
- package/dist/package-source-refusal.d.ts +17 -0
- package/dist/package-source-refusal.d.ts.map +1 -0
- package/dist/package-source-refusal.js +61 -0
- package/dist/package-source-refusal.js.map +1 -0
- package/dist/package-submission.d.ts +134 -0
- package/dist/package-submission.d.ts.map +1 -0
- package/dist/package-submission.js +196 -0
- package/dist/package-submission.js.map +1 -0
- package/dist/selection-record.d.ts +95 -0
- package/dist/selection-record.d.ts.map +1 -0
- package/dist/selection-record.js +121 -0
- package/dist/selection-record.js.map +1 -0
- package/package.json +1 -1
- package/skills/design/SKILL.md +43 -266
- package/skills/design-branch/SKILL.md +37 -116
- package/skills/design-convert/SKILL.md +62 -148
- package/skills/design-draft/SKILL.md +71 -135
- package/skills/design-search/SKILL.md +29 -78
- package/skills/design/references/continuation-contract.md +0 -60
- package/skills/design/references/selection-contract.md +0 -112
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { TwelveUiBranchClient } from './branch-client.js';
|
|
2
|
+
import { type BranchDownloadedScreen } from './branch-downloads.js';
|
|
3
|
+
import type { BranchExecutionInputs } from './branch-execution-types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Delivery, made incremental so a page can convert as soon as ITS OWN screens
|
|
6
|
+
* land rather than waiting for screens it does not use.
|
|
7
|
+
*
|
|
8
|
+
* The durability contract is unchanged: every screen is staged first and moved
|
|
9
|
+
* into `screens/` in ONE atomic pass, so the directory still goes from empty to
|
|
10
|
+
* complete and a caller can never mistake a half-written run for a failed one.
|
|
11
|
+
* Bytes already on disk were already paid for, which is what makes a resume
|
|
12
|
+
* free, and a slot is staged exactly once however many pages ask for it.
|
|
13
|
+
*/
|
|
14
|
+
export type BranchRunMaterializer = {
|
|
15
|
+
/** Stage these slots, reusing anything already delivered or in flight. */
|
|
16
|
+
ensure: (slots: readonly string[]) => Promise<Map<string, BranchDownloadedScreen>>;
|
|
17
|
+
/**
|
|
18
|
+
* The approved design's bytes. Started once and shared: it belongs to no
|
|
19
|
+
* generated slot, so nothing else in the run gates it and it can be fetched
|
|
20
|
+
* alongside dispatch rather than after it.
|
|
21
|
+
*/
|
|
22
|
+
winner: () => Promise<BranchDownloadedScreen>;
|
|
23
|
+
/** One atomic pass: everything staged so far becomes `screens/`. */
|
|
24
|
+
finish: () => Promise<void>;
|
|
25
|
+
};
|
|
26
|
+
export declare const createRunMaterializer: (args: {
|
|
27
|
+
client: TwelveUiBranchClient;
|
|
28
|
+
runId: string;
|
|
29
|
+
inputs: BranchExecutionInputs;
|
|
30
|
+
screensDirectory: string;
|
|
31
|
+
signal?: AbortSignal;
|
|
32
|
+
}) => BranchRunMaterializer;
|
|
33
|
+
//# sourceMappingURL=branch-materialize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branch-materialize.d.ts","sourceRoot":"","sources":["../src/branch-materialize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAKL,KAAK,sBAAsB,EAC5B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAEzE;;;;;;;;;GASG;AAEH,MAAM,MAAM,qBAAqB,GAAG;IAClC,0EAA0E;IAC1E,MAAM,EAAE,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC,CAAC;IACnF;;;;OAIG;IACH,MAAM,EAAE,MAAM,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAC9C,oEAAoE;IACpE,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,MAAM;IAC1C,MAAM,EAAE,oBAAoB,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,qBAAqB,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,KAAG,qBAkEH,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { materializeBranchScreens, readMaterializedScreen, stageBranchScreen, stageBranchScreenBytes, } from './branch-downloads.js';
|
|
2
|
+
export const createRunMaterializer = (args) => {
|
|
3
|
+
const delivered = new Map();
|
|
4
|
+
const inFlight = new Map();
|
|
5
|
+
const staged = [];
|
|
6
|
+
let winner = null;
|
|
7
|
+
const stage = async (slot) => {
|
|
8
|
+
// Bytes already on disk were already paid for and already delivered.
|
|
9
|
+
const materialized = await readMaterializedScreen(args.screensDirectory, slot);
|
|
10
|
+
if (materialized)
|
|
11
|
+
return materialized;
|
|
12
|
+
const downloaded = await stageBranchScreen({
|
|
13
|
+
client: args.client,
|
|
14
|
+
runId: args.runId,
|
|
15
|
+
slot,
|
|
16
|
+
screensDirectory: args.screensDirectory,
|
|
17
|
+
...(args.signal ? { signal: args.signal } : {}),
|
|
18
|
+
});
|
|
19
|
+
staged.push(slot);
|
|
20
|
+
return downloaded;
|
|
21
|
+
};
|
|
22
|
+
const ensureSlot = async (slot) => {
|
|
23
|
+
const known = delivered.get(slot);
|
|
24
|
+
if (known)
|
|
25
|
+
return known;
|
|
26
|
+
let pending = inFlight.get(slot);
|
|
27
|
+
if (!pending) {
|
|
28
|
+
pending = stage(slot);
|
|
29
|
+
inFlight.set(slot, pending);
|
|
30
|
+
}
|
|
31
|
+
const resolved = await pending;
|
|
32
|
+
delivered.set(slot, resolved);
|
|
33
|
+
return resolved;
|
|
34
|
+
};
|
|
35
|
+
const stageWinner = async () => {
|
|
36
|
+
const materialized = await readMaterializedScreen(args.screensDirectory, 'winner');
|
|
37
|
+
if (materialized)
|
|
38
|
+
return materialized;
|
|
39
|
+
const bytes = args.inputs.winner.kind === 'image'
|
|
40
|
+
? args.inputs.winner.bytes
|
|
41
|
+
: (await args.client.downloadScreen(args.inputs.winner.runId, args.inputs.winner.slot, args.signal)).bytes;
|
|
42
|
+
const downloaded = await stageBranchScreenBytes({
|
|
43
|
+
screensDirectory: args.screensDirectory,
|
|
44
|
+
slot: 'winner',
|
|
45
|
+
bytes,
|
|
46
|
+
});
|
|
47
|
+
staged.push('winner');
|
|
48
|
+
return downloaded;
|
|
49
|
+
};
|
|
50
|
+
return {
|
|
51
|
+
ensure: async (slots) => {
|
|
52
|
+
await Promise.all(slots.map(ensureSlot));
|
|
53
|
+
return delivered;
|
|
54
|
+
},
|
|
55
|
+
winner: async () => {
|
|
56
|
+
winner ??= stageWinner();
|
|
57
|
+
return await winner;
|
|
58
|
+
},
|
|
59
|
+
finish: async () => {
|
|
60
|
+
await materializeBranchScreens(args.screensDirectory, staged.splice(0));
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=branch-materialize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branch-materialize.js","sourceRoot":"","sources":["../src/branch-materialize.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import type { ConversionModel } from './conversion-models.js';
|
|
2
|
+
import type { ResponsiveConversionQuality } from './responsive-quality.js';
|
|
3
|
+
import { type BranchDownloadedScreen } from './branch-downloads.js';
|
|
4
|
+
import type { BranchNormalizedPlan, BranchPlannedPage } from './branch-plan.js';
|
|
5
|
+
import type { BranchCompletionPage } from './branch-run-record.js';
|
|
6
|
+
import { type ConversionReceipt } from './conversion-receipt.js';
|
|
7
|
+
import type { TwelveUiConversionPackageClient } from './package-client.js';
|
|
8
|
+
import { type PackageProgressEvent } from './package-submission.js';
|
|
9
|
+
/**
|
|
10
|
+
* The terminal step: ordered viewports of ONE page become ONE package
|
|
11
|
+
* conversion. Viewport 1 of the source page is the approved winner — the
|
|
12
|
+
* server never generates it — so the package is what makes the winner and its
|
|
13
|
+
* continuations one document instead of a pile of separately converted images.
|
|
14
|
+
*
|
|
15
|
+
* Pages are independent work and run in parallel, bounded: one page per package
|
|
16
|
+
* (a page's viewports already fan out inside the package, and fusing pages into
|
|
17
|
+
* one submission would put every page's assets in one Durable Object's memory),
|
|
18
|
+
* with at most `concurrency` packages in flight so the account's admission slots
|
|
19
|
+
* are spent converting rather than queueing.
|
|
20
|
+
*
|
|
21
|
+
* A page with a hole in it is parked, not converted: stitching an incomplete
|
|
22
|
+
* page would silently ship a page that is missing a section. Its siblings still
|
|
23
|
+
* convert, because one failed screen must not cost the pages that are whole —
|
|
24
|
+
* and for the same reason no page's failure, of any kind, is allowed to abort
|
|
25
|
+
* or orphan a sibling that is already paid for and in flight.
|
|
26
|
+
*/
|
|
27
|
+
export type BranchConversionSettings = {
|
|
28
|
+
output: 'html';
|
|
29
|
+
model?: ConversionModel;
|
|
30
|
+
responsiveQuality?: ResponsiveConversionQuality;
|
|
31
|
+
/** Reuse of an existing succeeded conversion of the winner's exact bytes. */
|
|
32
|
+
sourceConversionId?: string;
|
|
33
|
+
};
|
|
34
|
+
export declare const WINNER_VIEWPORT_ID = "winner";
|
|
35
|
+
export declare const DEFAULT_PACKAGE_MODEL = "standard";
|
|
36
|
+
type PageConversion = NonNullable<BranchCompletionPage['conversion']>;
|
|
37
|
+
/** The winner's own child conversion, once the package has proved it. */
|
|
38
|
+
export type BranchWinnerConversion = {
|
|
39
|
+
sha256: string;
|
|
40
|
+
conversionId: string;
|
|
41
|
+
model: string;
|
|
42
|
+
/**
|
|
43
|
+
* The package's own expiry, which the child cannot outlive backwards: a
|
|
44
|
+
* viewport child is admitted during the drive with the same artifact TTL, so
|
|
45
|
+
* it expires at or after the package that bought it. Reporting the package's
|
|
46
|
+
* is the conservative fact, and a receipt without one would be a claim whose
|
|
47
|
+
* liveness nothing proves.
|
|
48
|
+
*/
|
|
49
|
+
expiresAt: string;
|
|
50
|
+
};
|
|
51
|
+
/** One reuse claim the server refused, and the reason it gave. */
|
|
52
|
+
export type BranchReuseDisproof = {
|
|
53
|
+
viewportId: string;
|
|
54
|
+
conversionId: string;
|
|
55
|
+
detail: string;
|
|
56
|
+
};
|
|
57
|
+
export type BranchPageConversionArgs = {
|
|
58
|
+
client: TwelveUiConversionPackageClient;
|
|
59
|
+
plan: BranchNormalizedPlan;
|
|
60
|
+
page: BranchPlannedPage;
|
|
61
|
+
screens: ReadonlyMap<string, BranchDownloadedScreen>;
|
|
62
|
+
winner?: BranchDownloadedScreen;
|
|
63
|
+
settings: BranchConversionSettings;
|
|
64
|
+
pagesDirectory: string;
|
|
65
|
+
timeoutMs?: number;
|
|
66
|
+
/** Proved conversions of the approved design, from earlier runs. */
|
|
67
|
+
winnerReceipts?: readonly ConversionReceipt[];
|
|
68
|
+
onProgress?: (event: PackageProgressEvent) => void;
|
|
69
|
+
onWinnerConversion?: (conversion: BranchWinnerConversion) => void;
|
|
70
|
+
/** A reuse the server refused, so the proof it came from can be withdrawn. */
|
|
71
|
+
onReuseDisproven?: (disproof: BranchReuseDisproof) => void;
|
|
72
|
+
signal?: AbortSignal;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* The reuse claim, gated on proof rather than on intent.
|
|
76
|
+
*
|
|
77
|
+
* A normalized winner is no longer the bytes any earlier conversion was
|
|
78
|
+
* admitted with, so a declared `--source-conversion-id` would assert a digest
|
|
79
|
+
* the server will disprove and turn a convertible page into a failed one. A
|
|
80
|
+
* receipt is keyed on the bytes actually submitted, so it survives
|
|
81
|
+
* normalization — the same approved design reconciled to the same server canvas
|
|
82
|
+
* produces the same bytes — and it is only honoured on an exact digest match.
|
|
83
|
+
*/
|
|
84
|
+
export declare const winnerReuseConversionId: (args: {
|
|
85
|
+
settings: BranchConversionSettings;
|
|
86
|
+
submittedSha256: string;
|
|
87
|
+
normalized: boolean;
|
|
88
|
+
receipts: readonly ConversionReceipt[];
|
|
89
|
+
runId: string;
|
|
90
|
+
model: string;
|
|
91
|
+
}) => string | undefined;
|
|
92
|
+
export declare const convertBranchPage: (args: BranchPageConversionArgs) => Promise<PageConversion>;
|
|
93
|
+
/** What a page needs before it can be submitted, resolved when its slot opens. */
|
|
94
|
+
export type BranchPageInputs = {
|
|
95
|
+
screens: ReadonlyMap<string, BranchDownloadedScreen>;
|
|
96
|
+
winner?: BranchDownloadedScreen;
|
|
97
|
+
};
|
|
98
|
+
export type BranchPageConversionPool = {
|
|
99
|
+
/** Enqueue a page. A page already enqueued is never submitted twice. */
|
|
100
|
+
start: (plan: BranchNormalizedPlan, page: BranchPlannedPage) => void;
|
|
101
|
+
/** Resolves once every enqueued page has settled, one way or the other. */
|
|
102
|
+
settled: () => Promise<Map<string, PageConversion>>;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* The one owner of "which pages are converting, and how many at once".
|
|
106
|
+
*
|
|
107
|
+
* Pages are handed in as they become eligible rather than all at the end, so a
|
|
108
|
+
* page whose screens landed in the first wave is already converting while the
|
|
109
|
+
* rest of the run is still generating. `prepare` runs inside the page's own
|
|
110
|
+
* slot, which is what keeps a delivery for a page that has not started from
|
|
111
|
+
* competing with the packages that are already paid for.
|
|
112
|
+
*/
|
|
113
|
+
export declare const createBranchPageConversions: (args: {
|
|
114
|
+
client: TwelveUiConversionPackageClient;
|
|
115
|
+
settings: BranchConversionSettings;
|
|
116
|
+
pagesDirectory: string;
|
|
117
|
+
prepare: (page: BranchPlannedPage, plan: BranchNormalizedPlan) => Promise<BranchPageInputs>;
|
|
118
|
+
concurrency?: number;
|
|
119
|
+
timeoutMs?: number;
|
|
120
|
+
winnerReceipts?: readonly ConversionReceipt[];
|
|
121
|
+
onProgress?: (pageId: string, event: PackageProgressEvent) => void;
|
|
122
|
+
onWinnerConversion?: (conversion: BranchWinnerConversion) => void;
|
|
123
|
+
onReuseDisproven?: (disproof: BranchReuseDisproof) => void;
|
|
124
|
+
signal?: AbortSignal;
|
|
125
|
+
}) => BranchPageConversionPool;
|
|
126
|
+
export {};
|
|
127
|
+
//# sourceMappingURL=branch-page-conversion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branch-page-conversion.d.ts","sourceRoot":"","sources":["../src/branch-page-conversion.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
import { branchPackageKey } from './branch-identity.js';
|
|
2
|
+
import { BRANCH_PAGE_CONCURRENCY_DEFAULT } from './cli-progress.js';
|
|
3
|
+
import { createConcurrencyLimiter } from './bounded-concurrency.js';
|
|
4
|
+
import { readBranchScreenBytes } from './branch-downloads.js';
|
|
5
|
+
import { reusableConversionId, } from './conversion-receipt.js';
|
|
6
|
+
import { normalizePageViewports, } from './branch-viewport-normalization.js';
|
|
7
|
+
import { isSourceConversionRefusal, sourceConversionRefusalViewportId, } from './package-source-refusal.js';
|
|
8
|
+
import { submitConversionPackage, } from './package-submission.js';
|
|
9
|
+
export const WINNER_VIEWPORT_ID = 'winner';
|
|
10
|
+
export const DEFAULT_PACKAGE_MODEL = 'standard';
|
|
11
|
+
const orderedViewports = (plan, page) => plan.screens
|
|
12
|
+
.filter((screen) => page.slots.includes(screen.slot))
|
|
13
|
+
.sort((left, right) => left.viewportOrdinal - right.viewportOrdinal)
|
|
14
|
+
.map((screen) => ({ slot: screen.slot, ordinal: screen.viewportOrdinal }));
|
|
15
|
+
/**
|
|
16
|
+
* The reuse claim, gated on proof rather than on intent.
|
|
17
|
+
*
|
|
18
|
+
* A normalized winner is no longer the bytes any earlier conversion was
|
|
19
|
+
* admitted with, so a declared `--source-conversion-id` would assert a digest
|
|
20
|
+
* the server will disprove and turn a convertible page into a failed one. A
|
|
21
|
+
* receipt is keyed on the bytes actually submitted, so it survives
|
|
22
|
+
* normalization — the same approved design reconciled to the same server canvas
|
|
23
|
+
* produces the same bytes — and it is only honoured on an exact digest match.
|
|
24
|
+
*/
|
|
25
|
+
export const winnerReuseConversionId = (args) => {
|
|
26
|
+
if (args.settings.sourceConversionId && !args.normalized)
|
|
27
|
+
return args.settings.sourceConversionId;
|
|
28
|
+
return reusableConversionId({
|
|
29
|
+
receipts: args.receipts,
|
|
30
|
+
sha256: args.submittedSha256,
|
|
31
|
+
model: args.model,
|
|
32
|
+
boughtBy: args.runId,
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* The same page, with the attachment the server just disproved dropped.
|
|
37
|
+
*
|
|
38
|
+
* A reuse claim is proved against durable evidence BEFORE the package row
|
|
39
|
+
* exists, so its refusal costs nothing and leaves nothing behind: the identical
|
|
40
|
+
* request without the attachment is a first admission, not a second one. The
|
|
41
|
+
* page's key is derived from the run, the page, and the ordered digests of the
|
|
42
|
+
* bytes being submitted (`branchPackageKey`) — never from the attachment — so
|
|
43
|
+
* the retry replays under the SAME key and the reuse stays what it always was:
|
|
44
|
+
* an optimisation over bytes the page is carrying anyway.
|
|
45
|
+
*
|
|
46
|
+
* Null when the failure is not that refusal, or names no attachment this page
|
|
47
|
+
* actually sent. Then there is nothing a retry would change, and the page
|
|
48
|
+
* settles failed exactly as it did before.
|
|
49
|
+
*/
|
|
50
|
+
const withoutRefusedAttachment = (viewports, error) => {
|
|
51
|
+
if (!isSourceConversionRefusal(error))
|
|
52
|
+
return null;
|
|
53
|
+
const attached = viewports.filter((viewport) => viewport.sourceConversionId);
|
|
54
|
+
const named = sourceConversionRefusalViewportId(error);
|
|
55
|
+
const refused = named === null
|
|
56
|
+
? attached
|
|
57
|
+
: attached.filter((viewport) => viewport.id === named);
|
|
58
|
+
// A refusal naming a viewport that carried no attachment is a contract this
|
|
59
|
+
// client does not recognise; dropping every attachment is then the only
|
|
60
|
+
// reading that can still be right.
|
|
61
|
+
const dropped = refused.length > 0 ? refused : attached;
|
|
62
|
+
if (dropped.length === 0)
|
|
63
|
+
return null;
|
|
64
|
+
const dropping = new Set(dropped.map((viewport) => viewport.id));
|
|
65
|
+
return {
|
|
66
|
+
viewports: viewports.map((viewport) => (dropping.has(viewport.id)
|
|
67
|
+
// Rebuilt without the claim, and with the bytes it was always carrying.
|
|
68
|
+
? {
|
|
69
|
+
id: viewport.id,
|
|
70
|
+
ordinal: viewport.ordinal,
|
|
71
|
+
imagePath: viewport.imagePath,
|
|
72
|
+
bytes: viewport.bytes,
|
|
73
|
+
mediaType: viewport.mediaType,
|
|
74
|
+
}
|
|
75
|
+
: viewport)),
|
|
76
|
+
disproven: dropped.map((viewport) => ({
|
|
77
|
+
viewportId: viewport.id,
|
|
78
|
+
conversionId: viewport.sourceConversionId,
|
|
79
|
+
detail: error.message,
|
|
80
|
+
})),
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
export const convertBranchPage = async (args) => {
|
|
84
|
+
const { page } = args;
|
|
85
|
+
const planned = orderedViewports(args.plan, page);
|
|
86
|
+
const missing = planned.filter((viewport) => !args.screens.has(viewport.slot));
|
|
87
|
+
if (missing.length > 0) {
|
|
88
|
+
return {
|
|
89
|
+
status: 'skipped',
|
|
90
|
+
reason: `Page ${page.id} is missing screen(s) ${missing.map((entry) => entry.slot).join(', ')},`
|
|
91
|
+
+ ' so its viewports do not stack into a whole page. The screens that did land are on'
|
|
92
|
+
+ ' disk; redraw the gap and re-run with --resume before converting this page.',
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
// Collect the page's pixels first, tagging which side declares the width.
|
|
96
|
+
const sources = [];
|
|
97
|
+
if (page.startsFromWinner) {
|
|
98
|
+
if (!args.winner) {
|
|
99
|
+
return {
|
|
100
|
+
status: 'skipped',
|
|
101
|
+
reason: `Page ${page.id} starts from the approved screen, whose bytes are not available`
|
|
102
|
+
+ ' locally, so viewport 1 of the page is missing.',
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
sources.push({
|
|
106
|
+
ordinal: 1,
|
|
107
|
+
path: args.winner.path,
|
|
108
|
+
input: {
|
|
109
|
+
id: WINNER_VIEWPORT_ID,
|
|
110
|
+
bytes: await readBranchScreenBytes(args.winner),
|
|
111
|
+
mediaType: 'image/png',
|
|
112
|
+
width: args.winner.width,
|
|
113
|
+
height: args.winner.height,
|
|
114
|
+
// The winner came from somewhere else; it is the side that moves.
|
|
115
|
+
canonical: false,
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
for (const viewport of planned) {
|
|
120
|
+
const screen = args.screens.get(viewport.slot);
|
|
121
|
+
sources.push({
|
|
122
|
+
ordinal: viewport.ordinal,
|
|
123
|
+
path: screen.path,
|
|
124
|
+
input: {
|
|
125
|
+
id: viewport.slot,
|
|
126
|
+
bytes: await readBranchScreenBytes(screen),
|
|
127
|
+
mediaType: 'image/png',
|
|
128
|
+
width: screen.width,
|
|
129
|
+
height: screen.height,
|
|
130
|
+
// Drawn by the server on the run's fixed canvas: this is the width.
|
|
131
|
+
canonical: true,
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
const model = args.settings.model ?? DEFAULT_PACKAGE_MODEL;
|
|
136
|
+
let normalization;
|
|
137
|
+
try {
|
|
138
|
+
normalization = await normalizePageViewports(sources.map((entry) => entry.input));
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
return {
|
|
142
|
+
status: 'failed',
|
|
143
|
+
output: args.settings.output,
|
|
144
|
+
error: error instanceof Error ? error.message : String(error),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
const normalizedById = new Map(normalization.viewports.map((entry) => [entry.id, entry]));
|
|
148
|
+
const viewports = sources.map((entry) => {
|
|
149
|
+
const resolved = normalizedById.get(entry.input.id);
|
|
150
|
+
const reuse = entry.input.id === WINNER_VIEWPORT_ID
|
|
151
|
+
? winnerReuseConversionId({
|
|
152
|
+
settings: args.settings,
|
|
153
|
+
submittedSha256: resolved.sha256,
|
|
154
|
+
normalized: resolved.normalized,
|
|
155
|
+
receipts: args.winnerReceipts ?? [],
|
|
156
|
+
runId: args.plan.runId,
|
|
157
|
+
model,
|
|
158
|
+
})
|
|
159
|
+
: undefined;
|
|
160
|
+
return {
|
|
161
|
+
id: entry.input.id,
|
|
162
|
+
ordinal: entry.ordinal,
|
|
163
|
+
imagePath: entry.path,
|
|
164
|
+
bytes: resolved.bytes,
|
|
165
|
+
mediaType: resolved.mediaType,
|
|
166
|
+
...(reuse ? { sourceConversionId: reuse } : {}),
|
|
167
|
+
};
|
|
168
|
+
});
|
|
169
|
+
if (viewports.length === 0) {
|
|
170
|
+
return { status: 'skipped', reason: `Page ${page.id} has no viewport to convert.` };
|
|
171
|
+
}
|
|
172
|
+
if (viewports.length === 1 && page.startsFromWinner) {
|
|
173
|
+
return {
|
|
174
|
+
status: 'skipped',
|
|
175
|
+
reason: 'The approved screen already is the whole page — the server planned no'
|
|
176
|
+
+ ' continuations for it. Convert it on its own with'
|
|
177
|
+
+ ' `12ui convert <winner> --output layerdoc --export html`.',
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
// The page's identity. Its viewports travel per submission instead, because a
|
|
181
|
+
// disproven attachment changes them and nothing else about the page.
|
|
182
|
+
const input = {
|
|
183
|
+
id: page.id,
|
|
184
|
+
ordinal: page.index,
|
|
185
|
+
kind: page.kind,
|
|
186
|
+
...(page.title ? { title: page.title } : {}),
|
|
187
|
+
...(page.purpose ? { purpose: page.purpose } : {}),
|
|
188
|
+
};
|
|
189
|
+
// Keyed on the bytes actually submitted, so a retry after normalization
|
|
190
|
+
// replays the same package instead of buying the page again.
|
|
191
|
+
const idempotencyKey = branchPackageKey({
|
|
192
|
+
runId: args.plan.runId,
|
|
193
|
+
pageIndex: page.index,
|
|
194
|
+
viewportSha256s: viewports.map((viewport) => normalizedById.get(viewport.id).sha256),
|
|
195
|
+
output: args.settings.output,
|
|
196
|
+
...(args.settings.model ? { model: args.settings.model } : {}),
|
|
197
|
+
...(args.settings.responsiveQuality
|
|
198
|
+
? { responsiveQuality: args.settings.responsiveQuality }
|
|
199
|
+
: {}),
|
|
200
|
+
});
|
|
201
|
+
const normalizedRecord = normalization.viewports
|
|
202
|
+
.filter((viewport) => viewport.normalized)
|
|
203
|
+
.map((viewport) => ({
|
|
204
|
+
id: viewport.id,
|
|
205
|
+
fromWidth: viewport.original.width,
|
|
206
|
+
fromHeight: viewport.original.height,
|
|
207
|
+
fromSha256: viewport.original.sha256,
|
|
208
|
+
toWidth: viewport.width,
|
|
209
|
+
toHeight: viewport.height,
|
|
210
|
+
toSha256: viewport.sha256,
|
|
211
|
+
}));
|
|
212
|
+
const normalizationRecord = {
|
|
213
|
+
...(normalization.canonicalWidth === null
|
|
214
|
+
? {}
|
|
215
|
+
: { canonicalWidth: normalization.canonicalWidth }),
|
|
216
|
+
...(normalizedRecord.length > 0 ? { normalizedViewports: normalizedRecord } : {}),
|
|
217
|
+
};
|
|
218
|
+
const disproven = [];
|
|
219
|
+
const disproofRecord = () => (disproven.length > 0 ? { disprovenReuse: disproven } : {});
|
|
220
|
+
// The reconciliation is a fact about what was submitted, so it belongs in
|
|
221
|
+
// the record whether or not the submission was accepted — a failed page
|
|
222
|
+
// is exactly when an operator needs to know what the bytes were.
|
|
223
|
+
const failedPage = (error) => ({
|
|
224
|
+
status: 'failed',
|
|
225
|
+
idempotencyKey,
|
|
226
|
+
output: args.settings.output,
|
|
227
|
+
...normalizationRecord,
|
|
228
|
+
...disproofRecord(),
|
|
229
|
+
error: error instanceof Error ? error.message : String(error),
|
|
230
|
+
});
|
|
231
|
+
// Whether a package row exists yet. An attachment is proved at admission,
|
|
232
|
+
// before anything durable is created, so only a failure with no admitted
|
|
233
|
+
// package can be that refusal — and only then can the same key carry a
|
|
234
|
+
// different body without being a `409 idempotency_conflict`.
|
|
235
|
+
let admitted = false;
|
|
236
|
+
const submit = async (submitted) => await submitConversionPackage({
|
|
237
|
+
client: args.client,
|
|
238
|
+
outDir: args.pagesDirectory,
|
|
239
|
+
submission: {
|
|
240
|
+
output: args.settings.output,
|
|
241
|
+
...(args.settings.model ? { model: args.settings.model } : {}),
|
|
242
|
+
...(args.settings.responsiveQuality
|
|
243
|
+
? { responsiveQuality: args.settings.responsiveQuality }
|
|
244
|
+
: {}),
|
|
245
|
+
pages: [{ ...input, viewports: [...submitted] }],
|
|
246
|
+
idempotencyKey,
|
|
247
|
+
},
|
|
248
|
+
onSubmitted: () => { admitted = true; },
|
|
249
|
+
...(args.timeoutMs === undefined ? {} : { timeoutMs: args.timeoutMs }),
|
|
250
|
+
...(args.onProgress ? { onProgress: args.onProgress } : {}),
|
|
251
|
+
...(args.signal ? { signal: args.signal } : {}),
|
|
252
|
+
});
|
|
253
|
+
let result;
|
|
254
|
+
try {
|
|
255
|
+
result = await submit(viewports);
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
// A disproven reuse costs one retry of the same page, never the page: its
|
|
259
|
+
// other screens are already paid for by the time anything could refuse it.
|
|
260
|
+
const retry = admitted ? null : withoutRefusedAttachment(viewports, error);
|
|
261
|
+
if (!retry)
|
|
262
|
+
return failedPage(error);
|
|
263
|
+
disproven.push(...retry.disproven);
|
|
264
|
+
for (const entry of retry.disproven)
|
|
265
|
+
args.onReuseDisproven?.(entry);
|
|
266
|
+
try {
|
|
267
|
+
result = await submit(retry.viewports);
|
|
268
|
+
}
|
|
269
|
+
catch (retryError) {
|
|
270
|
+
return failedPage(retryError);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
const converted = result.pages[0];
|
|
274
|
+
const winnerChild = converted?.viewports?.find((viewport) => (viewport.id === WINNER_VIEWPORT_ID
|
|
275
|
+
&& viewport.status === 'succeeded'
|
|
276
|
+
&& viewport.conversionId));
|
|
277
|
+
if (winnerChild?.conversionId && result.expiresAt) {
|
|
278
|
+
args.onWinnerConversion?.({
|
|
279
|
+
sha256: normalizedById.get(WINNER_VIEWPORT_ID).sha256,
|
|
280
|
+
conversionId: winnerChild.conversionId,
|
|
281
|
+
model,
|
|
282
|
+
expiresAt: result.expiresAt,
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
return converted?.status === 'succeeded'
|
|
286
|
+
? {
|
|
287
|
+
status: 'succeeded',
|
|
288
|
+
packageId: result.packageId,
|
|
289
|
+
idempotencyKey,
|
|
290
|
+
output: args.settings.output,
|
|
291
|
+
...normalizationRecord,
|
|
292
|
+
...disproofRecord(),
|
|
293
|
+
...(converted.conversionId ? { conversionId: converted.conversionId } : {}),
|
|
294
|
+
...(converted.outFile ? { outFile: converted.outFile } : {}),
|
|
295
|
+
...(converted.sha256 ? { sha256: converted.sha256 } : {}),
|
|
296
|
+
...(converted.bytes === undefined ? {} : { bytes: converted.bytes }),
|
|
297
|
+
}
|
|
298
|
+
: {
|
|
299
|
+
status: 'failed',
|
|
300
|
+
packageId: result.packageId,
|
|
301
|
+
idempotencyKey,
|
|
302
|
+
output: args.settings.output,
|
|
303
|
+
...normalizationRecord,
|
|
304
|
+
...disproofRecord(),
|
|
305
|
+
error: converted?.error ?? `Package ${result.packageId} produced no page.`,
|
|
306
|
+
};
|
|
307
|
+
};
|
|
308
|
+
/**
|
|
309
|
+
* Every page settles, whatever happens to any one of them. A page whose own
|
|
310
|
+
* bytes could not even be delivered is recorded as a failed conversion rather
|
|
311
|
+
* than thrown: a throw would abandon the sibling packages already running,
|
|
312
|
+
* which are paid work whose results would then never reach the sentinel.
|
|
313
|
+
*/
|
|
314
|
+
const settlePageConversion = async (args) => {
|
|
315
|
+
try {
|
|
316
|
+
return await convertBranchPage(args);
|
|
317
|
+
}
|
|
318
|
+
catch (error) {
|
|
319
|
+
return {
|
|
320
|
+
status: 'failed',
|
|
321
|
+
output: args.settings.output,
|
|
322
|
+
error: error instanceof Error ? error.message : String(error),
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
/**
|
|
327
|
+
* The one owner of "which pages are converting, and how many at once".
|
|
328
|
+
*
|
|
329
|
+
* Pages are handed in as they become eligible rather than all at the end, so a
|
|
330
|
+
* page whose screens landed in the first wave is already converting while the
|
|
331
|
+
* rest of the run is still generating. `prepare` runs inside the page's own
|
|
332
|
+
* slot, which is what keeps a delivery for a page that has not started from
|
|
333
|
+
* competing with the packages that are already paid for.
|
|
334
|
+
*/
|
|
335
|
+
export const createBranchPageConversions = (args) => {
|
|
336
|
+
const limiter = createConcurrencyLimiter(args.concurrency ?? BRANCH_PAGE_CONCURRENCY_DEFAULT);
|
|
337
|
+
const conversions = new Map();
|
|
338
|
+
const enqueued = new Map();
|
|
339
|
+
return {
|
|
340
|
+
start: (plan, page) => {
|
|
341
|
+
if (enqueued.has(page.id))
|
|
342
|
+
return;
|
|
343
|
+
enqueued.set(page.id, limiter(async () => {
|
|
344
|
+
const prepared = await args.prepare(page, plan);
|
|
345
|
+
conversions.set(page.id, await settlePageConversion({
|
|
346
|
+
client: args.client,
|
|
347
|
+
plan,
|
|
348
|
+
page,
|
|
349
|
+
screens: prepared.screens,
|
|
350
|
+
settings: args.settings,
|
|
351
|
+
pagesDirectory: args.pagesDirectory,
|
|
352
|
+
...(prepared.winner ? { winner: prepared.winner } : {}),
|
|
353
|
+
...(args.timeoutMs === undefined ? {} : { timeoutMs: args.timeoutMs }),
|
|
354
|
+
...(args.winnerReceipts ? { winnerReceipts: args.winnerReceipts } : {}),
|
|
355
|
+
...(args.onProgress
|
|
356
|
+
? { onProgress: (event) => args.onProgress(page.id, event) }
|
|
357
|
+
: {}),
|
|
358
|
+
...(args.onWinnerConversion ? { onWinnerConversion: args.onWinnerConversion } : {}),
|
|
359
|
+
...(args.onReuseDisproven ? { onReuseDisproven: args.onReuseDisproven } : {}),
|
|
360
|
+
...(args.signal ? { signal: args.signal } : {}),
|
|
361
|
+
}));
|
|
362
|
+
}).catch((error) => {
|
|
363
|
+
conversions.set(page.id, {
|
|
364
|
+
status: 'failed',
|
|
365
|
+
output: args.settings.output,
|
|
366
|
+
error: error instanceof Error ? error.message : String(error),
|
|
367
|
+
});
|
|
368
|
+
}));
|
|
369
|
+
},
|
|
370
|
+
settled: async () => {
|
|
371
|
+
// Draining can itself enqueue: a page becomes eligible while an earlier
|
|
372
|
+
// one is still in flight. Keep draining until nothing new arrived.
|
|
373
|
+
let counted = -1;
|
|
374
|
+
while (enqueued.size !== counted) {
|
|
375
|
+
counted = enqueued.size;
|
|
376
|
+
await Promise.all([...enqueued.values()]);
|
|
377
|
+
}
|
|
378
|
+
return conversions;
|
|
379
|
+
},
|
|
380
|
+
};
|
|
381
|
+
};
|
|
382
|
+
//# sourceMappingURL=branch-page-conversion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branch-page-conversion.js","sourceRoot":"","sources":["../src/branch-page-conversion.ts"],"names":[],"mappings":"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"}
|