looply-cli 0.5.12 → 0.5.13
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/dist/.src-hash +1 -1
- package/dist/bin.d.ts.map +1 -1
- package/dist/bin.js +7 -0
- package/dist/bin.js.map +1 -1
- package/dist/branch-delivery-wiring.d.ts +3 -1
- package/dist/branch-delivery-wiring.d.ts.map +1 -1
- package/dist/branch-delivery-wiring.js +47 -2
- package/dist/branch-delivery-wiring.js.map +1 -1
- package/dist/delivery-rules.d.ts +11 -0
- package/dist/delivery-rules.d.ts.map +1 -1
- package/dist/delivery-rules.js +34 -1
- package/dist/delivery-rules.js.map +1 -1
- package/dist/github-api.d.ts +2 -0
- package/dist/github-api.d.ts.map +1 -1
- package/dist/github-api.js +3 -0
- package/dist/github-api.js.map +1 -1
- package/dist/goal-gap.d.ts +9 -0
- package/dist/goal-gap.d.ts.map +1 -1
- package/dist/goal-gap.js +9 -0
- package/dist/goal-gap.js.map +1 -1
- package/dist/mcp-main.js +3 -0
- package/dist/mcp-main.js.map +1 -1
- package/dist/mcp-server.d.ts +5 -0
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +14 -1
- package/dist/mcp-server.js.map +1 -1
- package/dist/model-transport.d.ts.map +1 -1
- package/dist/model-transport.js +4 -0
- package/dist/model-transport.js.map +1 -1
- package/dist/run-cmd.d.ts.map +1 -1
- package/dist/run-cmd.js +18 -1
- package/dist/run-cmd.js.map +1 -1
- package/dist/screenshot-tool.d.ts +45 -0
- package/dist/screenshot-tool.d.ts.map +1 -0
- package/dist/screenshot-tool.js +49 -0
- package/dist/screenshot-tool.js.map +1 -0
- package/dist/server-client.d.ts +15 -0
- package/dist/server-client.d.ts.map +1 -1
- package/dist/server-client.js +10 -0
- package/dist/server-client.js.map +1 -1
- package/dist/visual-proof-browser.d.ts +184 -0
- package/dist/visual-proof-browser.d.ts.map +1 -0
- package/dist/visual-proof-browser.js +267 -0
- package/dist/visual-proof-browser.js.map +1 -0
- package/dist/visual-proof-cmd.d.ts +24 -0
- package/dist/visual-proof-cmd.d.ts.map +1 -0
- package/dist/visual-proof-cmd.js +144 -0
- package/dist/visual-proof-cmd.js.map +1 -0
- package/dist/visual-proof-config.d.ts +151 -0
- package/dist/visual-proof-config.d.ts.map +1 -0
- package/dist/visual-proof-config.js +381 -0
- package/dist/visual-proof-config.js.map +1 -0
- package/dist/visual-proof-publish.d.ts +77 -0
- package/dist/visual-proof-publish.d.ts.map +1 -0
- package/dist/visual-proof-publish.js +211 -0
- package/dist/visual-proof-publish.js.map +1 -0
- package/dist/visual-proof-run.d.ts +73 -0
- package/dist/visual-proof-run.d.ts.map +1 -0
- package/dist/visual-proof-run.js +153 -0
- package/dist/visual-proof-run.js.map +1 -0
- package/dist/visual-proof-scope.d.ts +41 -0
- package/dist/visual-proof-scope.d.ts.map +1 -0
- package/dist/visual-proof-scope.js +205 -0
- package/dist/visual-proof-scope.js.map +1 -0
- package/dist/visual-proof-serve.d.ts +11 -0
- package/dist/visual-proof-serve.d.ts.map +1 -0
- package/dist/visual-proof-serve.js +100 -0
- package/dist/visual-proof-serve.js.map +1 -0
- package/dist/visual-proof-store.d.ts +76 -0
- package/dist/visual-proof-store.d.ts.map +1 -0
- package/dist/visual-proof-store.js +117 -0
- package/dist/visual-proof-store.js.map +1 -0
- package/dist/visual-proof.d.ts +87 -0
- package/dist/visual-proof.d.ts.map +1 -0
- package/dist/visual-proof.js +343 -0
- package/dist/visual-proof.js.map +1 -0
- package/package.json +5 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visual-proof-cmd.d.ts","sourceRoot":"","sources":["../src/visual-proof-cmd.ts"],"names":[],"mappings":"AAMA,OAAO,EAAsC,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAKvF;;;;;;;GAOG;AAEH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;CACf;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,eAAe,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAqBjG;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,EAAE,CAazD;AAED,sFAAsF;AACtF,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAa7C;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CA0D3H"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseVisualProofArgs = parseVisualProofArgs;
|
|
4
|
+
exports.describeOutcome = describeOutcome;
|
|
5
|
+
exports.carryOf = carryOf;
|
|
6
|
+
exports.visualProofCommand = visualProofCommand;
|
|
7
|
+
const node_fs_1 = require("node:fs");
|
|
8
|
+
const node_path_1 = require("node:path");
|
|
9
|
+
const config_1 = require("./config");
|
|
10
|
+
const git_driver_1 = require("./git-driver");
|
|
11
|
+
const run_base_1 = require("./run-base");
|
|
12
|
+
const untrusted_gate_1 = require("./untrusted-gate");
|
|
13
|
+
const visual_proof_1 = require("./visual-proof");
|
|
14
|
+
const visual_proof_config_1 = require("./visual-proof-config");
|
|
15
|
+
const workspace_1 = require("./workspace");
|
|
16
|
+
const yaml_1 = require("yaml");
|
|
17
|
+
function parseVisualProofArgs(argv) {
|
|
18
|
+
const out = { base: null, head: 'HEAD', goalId: null, text: '', json: false };
|
|
19
|
+
for (let i = 0; i < argv.length; i++) {
|
|
20
|
+
const a = argv[i];
|
|
21
|
+
const next = () => {
|
|
22
|
+
const v = argv[i + 1];
|
|
23
|
+
if (v === undefined || v.startsWith('--'))
|
|
24
|
+
return null;
|
|
25
|
+
i++;
|
|
26
|
+
return v;
|
|
27
|
+
};
|
|
28
|
+
if (a === '--json')
|
|
29
|
+
out.json = true;
|
|
30
|
+
else if (a === '--base' || a === '--head' || a === '--goal' || a === '--text') {
|
|
31
|
+
const v = next();
|
|
32
|
+
if (v === null)
|
|
33
|
+
return { error: `${a} needs a value` };
|
|
34
|
+
if (a === '--base')
|
|
35
|
+
out.base = v;
|
|
36
|
+
else if (a === '--head')
|
|
37
|
+
out.head = v;
|
|
38
|
+
else if (a === '--goal')
|
|
39
|
+
out.goalId = v;
|
|
40
|
+
else
|
|
41
|
+
out.text = v;
|
|
42
|
+
}
|
|
43
|
+
else
|
|
44
|
+
return { error: `unknown argument ${a}` };
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
function describeOutcome(o) {
|
|
49
|
+
if (o.kind === 'not-ui')
|
|
50
|
+
return [`no screenshots: ${o.because}`];
|
|
51
|
+
if (o.kind === 'failed')
|
|
52
|
+
return [`screenshots failed: ${o.because}`];
|
|
53
|
+
const m = o.manifest;
|
|
54
|
+
const ok = m.shots.filter((s) => s.ok).length;
|
|
55
|
+
return [
|
|
56
|
+
`screenshots: ${ok} of ${m.shots.length} taken, ${m.sheets.length} before/after sheet(s)`,
|
|
57
|
+
` before ${m.baseSha.slice(0, 12)} → after ${m.headSha.slice(0, 12)}`,
|
|
58
|
+
` folder ${o.dir}`,
|
|
59
|
+
...m.apps.flatMap((a) => [` ${a.name}: ${a.routes.map((r) => r.name || r.path || 'home').join(', ')}`, ...a.why.map((w) => ` · ${w}`)]),
|
|
60
|
+
...m.sheets.map((s) => ` sheet ${(0, node_path_1.join)(o.dir, s.file)}`),
|
|
61
|
+
...m.notes.map((n) => ` note: ${n}`),
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
/** `run.carry_into_checkouts`, or what the gates imply when the file does not say. */
|
|
65
|
+
function carryOf(cwd) {
|
|
66
|
+
const file = (0, node_path_1.join)(cwd, '.looply', 'config.yaml');
|
|
67
|
+
if (!(0, node_fs_1.existsSync)(file))
|
|
68
|
+
return ['node_modules'];
|
|
69
|
+
const text = (0, node_fs_1.readFileSync)(file, 'utf8');
|
|
70
|
+
try {
|
|
71
|
+
const cfg = (0, config_1.parseConfig)(text);
|
|
72
|
+
const carry = cfg.run.carryIntoCheckouts ?? [];
|
|
73
|
+
if (carry.length > 0)
|
|
74
|
+
return [...carry];
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
/* fall through to what the gates imply */
|
|
78
|
+
}
|
|
79
|
+
const raw = (0, yaml_1.parse)(text);
|
|
80
|
+
return (0, config_1.defaultCarry)(raw?.gates);
|
|
81
|
+
}
|
|
82
|
+
async function visualProofCommand(argv, cwd, out) {
|
|
83
|
+
const args = parseVisualProofArgs(argv);
|
|
84
|
+
if ('error' in args) {
|
|
85
|
+
out(`looply visual-proof: ${args.error}`);
|
|
86
|
+
return 64;
|
|
87
|
+
}
|
|
88
|
+
let config;
|
|
89
|
+
try {
|
|
90
|
+
config = (0, visual_proof_config_1.readVisualProofConfig)(cwd);
|
|
91
|
+
}
|
|
92
|
+
catch (e) {
|
|
93
|
+
out(e instanceof visual_proof_config_1.VisualProofConfigError ? e.message : `config: ${e.message}`);
|
|
94
|
+
return 1;
|
|
95
|
+
}
|
|
96
|
+
if (!config.enabled) {
|
|
97
|
+
out('visual_proof is not configured in .looply/config.yaml (see `visual-proof-config.ts` for the section)');
|
|
98
|
+
return 1;
|
|
99
|
+
}
|
|
100
|
+
const exec = (0, git_driver_1.nodeGitExec)(cwd);
|
|
101
|
+
let base = args.base;
|
|
102
|
+
if (base === null) {
|
|
103
|
+
let configured;
|
|
104
|
+
try {
|
|
105
|
+
configured = (0, config_1.parseConfig)((0, node_fs_1.readFileSync)((0, node_path_1.join)(cwd, '.looply', 'config.yaml'), 'utf8')).run.baseBranch;
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
configured = undefined;
|
|
109
|
+
}
|
|
110
|
+
base = (await (0, run_base_1.resolveBaseBranch)(new git_driver_1.GitDriver(exec), configured))?.ref ?? null;
|
|
111
|
+
if (base === null) {
|
|
112
|
+
out('looply visual-proof: the base branch could not be found; pass --base');
|
|
113
|
+
return 1;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const deps = {
|
|
117
|
+
git: exec,
|
|
118
|
+
buildRunner: (tree) => (0, untrusted_gate_1.makeUntrustedGateRunner)(tree),
|
|
119
|
+
now: () => Date.now(),
|
|
120
|
+
log: (line) => {
|
|
121
|
+
if (!args.json)
|
|
122
|
+
out(line);
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
const outcome = await (0, visual_proof_1.captureVisualProof)({
|
|
126
|
+
checkout: cwd,
|
|
127
|
+
projectDir: cwd,
|
|
128
|
+
projectName: cwd.split(/[\\/]/).pop() ?? 'project',
|
|
129
|
+
goalId: args.goalId,
|
|
130
|
+
goalText: args.text,
|
|
131
|
+
base,
|
|
132
|
+
head: args.head,
|
|
133
|
+
config,
|
|
134
|
+
carry: carryOf(cwd),
|
|
135
|
+
storeBase: (0, workspace_1.workspacesBase)(),
|
|
136
|
+
}, deps);
|
|
137
|
+
if (args.json)
|
|
138
|
+
out(JSON.stringify(outcome.kind === 'captured' ? { kind: outcome.kind, dir: outcome.dir, manifest: outcome.manifest } : outcome, null, 2));
|
|
139
|
+
else
|
|
140
|
+
for (const line of describeOutcome(outcome))
|
|
141
|
+
out(line);
|
|
142
|
+
return outcome.kind === 'failed' ? 1 : 0;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=visual-proof-cmd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visual-proof-cmd.js","sourceRoot":"","sources":["../src/visual-proof-cmd.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `visual_proof:` IN `.looply/config.yaml` — HOW LOOPLY SHOWS A UI CHANGE.
|
|
3
|
+
*
|
|
4
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
5
|
+
* A ticket that changes what a screen looks like was judged by its unit tests
|
|
6
|
+
* alone (TAB-B-61, the cramped sidebar). This section tells Looply how to build
|
|
7
|
+
* the app, serve it, sign in with the project's OWN test data and which screens
|
|
8
|
+
* to capture, so a finished UI change carries before/after screenshots.
|
|
9
|
+
*
|
|
10
|
+
* visual_proof:
|
|
11
|
+
* enabled: true
|
|
12
|
+
* max_routes: 4 # screens per goal (default 4)
|
|
13
|
+
* max_mb: 2048 # all screenshots kept on this machine (default 2048)
|
|
14
|
+
* apps:
|
|
15
|
+
* - name: admin
|
|
16
|
+
* when: ["admin/**"] # changed files that make this app's proof run
|
|
17
|
+
* build: "cd admin && node node_modules/vite/bin/vite.js build" # in the sandbox, offline
|
|
18
|
+
* static: admin/dist # Looply serves this folder itself
|
|
19
|
+
* mount: /admin/ # the URL path the app expects (Vite `base`)
|
|
20
|
+
* storage: { tabsy.activeCompanyId: cmp_demo } # set before every page
|
|
21
|
+
* dark: { storage: { tabsy.theme: dark } } # else prefers-color-scheme
|
|
22
|
+
* rtl: { storage: { tabsy.lang: ar } } # absent: no RTL capture
|
|
23
|
+
* login:
|
|
24
|
+
* storage:
|
|
25
|
+
* tabsy.access: { from: admin/src/test/fixtures.ts, match: "access: '([^']+)'" }
|
|
26
|
+
* api:
|
|
27
|
+
* fallback: { status: 200, json: [] }
|
|
28
|
+
* routes:
|
|
29
|
+
* - { path: /api/v1/companies/selectable, file: admin/src/test/companies.json }
|
|
30
|
+
* router: admin/src/App.tsx # to infer screens from changed pages
|
|
31
|
+
* routes:
|
|
32
|
+
* - { path: dashboard, name: Dashboard }
|
|
33
|
+
*
|
|
34
|
+
* 🔴 NO PROJECT CODE RUNS OUTSIDE THE SANDBOX. `build` runs where every gate runs
|
|
35
|
+
* (the AppContainer, no network). Looply serves the built files with its own
|
|
36
|
+
* static server; the app's code then runs only inside the browser, and every
|
|
37
|
+
* request that is not to that server is answered from `api` or refused — the
|
|
38
|
+
* page is offline by construction. A dev-server command (`vite dev`, `next
|
|
39
|
+
* start`) is NOT supported: a contained process cannot be reached on loopback.
|
|
40
|
+
*
|
|
41
|
+
* 🔴 SIGN-IN USES THE PROJECT'S OWN TEST DATA, NEVER A REAL ACCOUNT. Every value
|
|
42
|
+
* under `login` is READ from a file in the repository whose path says it is a
|
|
43
|
+
* seed, fixture, mock or test file; a literal written here is refused, so a real
|
|
44
|
+
* password can never be typed into this file and work.
|
|
45
|
+
*/
|
|
46
|
+
export declare class VisualProofConfigError extends Error {
|
|
47
|
+
readonly key: string;
|
|
48
|
+
constructor(key: string, message: string);
|
|
49
|
+
}
|
|
50
|
+
/** A value read from a file in the repository: the whole file, a JSON key, or a regex's first group. */
|
|
51
|
+
export interface FixtureRef {
|
|
52
|
+
readonly from: string;
|
|
53
|
+
/** Dotted path into a JSON file (`users.0.password`). */
|
|
54
|
+
readonly key?: string;
|
|
55
|
+
/** A regular expression whose FIRST capture group is the value. */
|
|
56
|
+
readonly match?: string;
|
|
57
|
+
}
|
|
58
|
+
export type StorageValue = string | FixtureRef;
|
|
59
|
+
export interface ApiRoute {
|
|
60
|
+
/** A URL path on the served origin; a trailing `*` matches any rest. */
|
|
61
|
+
readonly path: string;
|
|
62
|
+
readonly method?: string;
|
|
63
|
+
readonly status: number;
|
|
64
|
+
/** A JSON body given inline. */
|
|
65
|
+
readonly json?: unknown;
|
|
66
|
+
/** A JSON body read from a file in the repository. */
|
|
67
|
+
readonly file?: string;
|
|
68
|
+
}
|
|
69
|
+
export interface FormLogin {
|
|
70
|
+
/** Path on the served origin, under the mount (`/admin/login`). */
|
|
71
|
+
readonly path: string;
|
|
72
|
+
/** CSS selector → the value to type there. */
|
|
73
|
+
readonly fields: Readonly<Record<string, FixtureRef>>;
|
|
74
|
+
readonly submit: string;
|
|
75
|
+
/** A selector that is on screen once signed in. */
|
|
76
|
+
readonly waitFor?: string;
|
|
77
|
+
}
|
|
78
|
+
export interface VariantSetup {
|
|
79
|
+
readonly storage: Readonly<Record<string, string>>;
|
|
80
|
+
}
|
|
81
|
+
export interface ProofRoute {
|
|
82
|
+
/** Relative to the mount: `dashboard`, `orders/123`. Empty is the app's root. */
|
|
83
|
+
readonly path: string;
|
|
84
|
+
readonly name: string;
|
|
85
|
+
/** Changed files that make this route relevant. Empty: always a candidate. */
|
|
86
|
+
readonly when: readonly string[];
|
|
87
|
+
}
|
|
88
|
+
export interface ProofApp {
|
|
89
|
+
readonly name: string;
|
|
90
|
+
readonly when: readonly string[];
|
|
91
|
+
readonly build: string | null;
|
|
92
|
+
/** Folders carried into the throwaway checkout this app is built in; null: inferred from `build`. */
|
|
93
|
+
readonly carry: readonly string[] | null;
|
|
94
|
+
readonly timeoutS: number;
|
|
95
|
+
readonly static: string;
|
|
96
|
+
readonly mount: string;
|
|
97
|
+
readonly spa: boolean;
|
|
98
|
+
readonly storage: Readonly<Record<string, string>>;
|
|
99
|
+
readonly light: VariantSetup | null;
|
|
100
|
+
readonly dark: VariantSetup | null;
|
|
101
|
+
readonly rtl: VariantSetup | null;
|
|
102
|
+
readonly login: {
|
|
103
|
+
readonly storage: Readonly<Record<string, FixtureRef>>;
|
|
104
|
+
readonly form: FormLogin | null;
|
|
105
|
+
};
|
|
106
|
+
readonly api: {
|
|
107
|
+
readonly routes: readonly ApiRoute[];
|
|
108
|
+
readonly fallback: {
|
|
109
|
+
status: number;
|
|
110
|
+
json?: unknown;
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
readonly router: string | null;
|
|
114
|
+
readonly routes: readonly ProofRoute[];
|
|
115
|
+
readonly waitFor: string | null;
|
|
116
|
+
}
|
|
117
|
+
export interface Viewport {
|
|
118
|
+
readonly name: string;
|
|
119
|
+
readonly width: number;
|
|
120
|
+
readonly height: number;
|
|
121
|
+
}
|
|
122
|
+
export interface VisualProofConfig {
|
|
123
|
+
readonly enabled: boolean;
|
|
124
|
+
readonly maxRoutes: number;
|
|
125
|
+
readonly maxMb: number;
|
|
126
|
+
readonly viewports: readonly Viewport[];
|
|
127
|
+
readonly themes: readonly ('light' | 'dark')[];
|
|
128
|
+
readonly apps: readonly ProofApp[];
|
|
129
|
+
}
|
|
130
|
+
export declare const DEFAULT_VIEWPORTS: readonly Viewport[];
|
|
131
|
+
export declare const DEFAULT_MAX_ROUTES = 4;
|
|
132
|
+
export declare const DEFAULT_MAX_MB = 2048;
|
|
133
|
+
export declare const DISABLED: VisualProofConfig;
|
|
134
|
+
/** A repository-relative path that stays inside the repository. */
|
|
135
|
+
export declare function repoPath(p: string, path: string): string;
|
|
136
|
+
/**
|
|
137
|
+
* 🔴 A SIGN-IN VALUE IS A POINTER INTO A TEST FILE, NEVER THE VALUE ITSELF.
|
|
138
|
+
*/
|
|
139
|
+
export declare function fixtureRef(raw: unknown, path: string): FixtureRef;
|
|
140
|
+
/** The `visual_proof:` section as written, or DISABLED when absent. Throws on anything malformed. */
|
|
141
|
+
export declare function parseVisualProof(raw: unknown): VisualProofConfig;
|
|
142
|
+
/** Read `visual_proof:` from the project's `.looply/config.yaml`; DISABLED when the file or section is absent. */
|
|
143
|
+
export declare function readVisualProofConfig(projectDir: string): VisualProofConfig;
|
|
144
|
+
/**
|
|
145
|
+
* Resolve a fixture pointer to its value, reading the file from the first root that has it
|
|
146
|
+
* (the checkout, then the project's main folder — a machine checkout may not carry it).
|
|
147
|
+
*/
|
|
148
|
+
export declare function readFixture(ref: FixtureRef, roots: readonly string[]): string;
|
|
149
|
+
/** A JSON body file from the repository (checkout first, then the project folder). */
|
|
150
|
+
export declare function readJsonFile(path: string, roots: readonly string[]): unknown;
|
|
151
|
+
//# sourceMappingURL=visual-proof-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visual-proof-config.d.ts","sourceRoot":"","sources":["../src/visual-proof-config.ts"],"names":[],"mappings":"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"}
|