laneyard 0.6.1 → 0.8.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.
- package/README.md +13 -497
- package/dist/src/cli/adopt.js +24 -8
- package/dist/src/cli/remove.js +52 -34
- package/dist/src/cli/reset.js +2 -2
- package/dist/src/cli/setup.js +85 -40
- package/dist/src/cli/uninstall.js +5 -21
- package/dist/src/config/env-file-setting.js +57 -0
- package/dist/src/config/resolve.js +8 -5
- package/dist/src/config/schema.js +29 -0
- package/dist/src/db/credentials.js +18 -54
- package/dist/src/db/migrate-global-scope.js +75 -0
- package/dist/src/db/open.js +21 -0
- package/dist/src/db/schema.sql +10 -5
- package/dist/src/db/secrets.js +44 -65
- package/dist/src/fastfile/adoption.js +19 -4
- package/dist/src/git/workspace.js +28 -0
- package/dist/src/heuristics/readiness.js +80 -135
- package/dist/src/main.js +31 -2
- package/dist/src/runner/env-file.js +144 -0
- package/dist/src/runner/orchestrate.js +39 -5
- package/dist/src/secrets/vault.js +75 -40
- package/dist/src/server/app.js +4 -0
- package/dist/src/server/routes/credentials.js +0 -13
- package/dist/src/server/routes/fastfile.js +1 -1
- package/dist/src/server/routes/projects.js +59 -16
- package/dist/src/server/routes/readiness.js +2 -3
- package/dist/src/server/routes/secrets.js +111 -39
- package/dist/src/sidecar/fastlane-dir.js +18 -8
- package/dist/src/sidecar/lanes.js +1 -1
- package/dist/src/sidecar/uses.js +1 -1
- package/dist/web/assets/{Editor-CMa4-4N3.js → Editor-BK-ZRKlI.js} +1 -1
- package/dist/web/assets/index-DnUdqjT4.js +62 -0
- package/dist/web/assets/{index-DsjxZtsO.css → index-r3IyRuO4.css} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/web/assets/index-B8lAQPEM.js +0 -62
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { MIN_LENGTH as MIN_REDACTABLE } from "../../logs/redact.js";
|
|
2
2
|
import { exportedVarNames } from "../../credentials/kinds.js";
|
|
3
3
|
import { requiredSecrets } from "../required-secrets.js";
|
|
4
|
+
import { dotenvLine } from "../../runner/env-file.js";
|
|
5
|
+
import { envFileProblem, setEnvFileSetting } from "../../config/env-file-setting.js";
|
|
4
6
|
/** POSIX environment variable names. Anything else would never reach fastlane. */
|
|
5
7
|
const VALID_KEY = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
6
8
|
export async function registerSecretRoutes(app, ctx) {
|
|
7
|
-
const listRoute = (slug) => slug === null ? ctx.vault.listGlobal() : ctx.vault.list(slug);
|
|
8
|
-
app.get("/api/secrets", async () => listRoute(null));
|
|
9
9
|
app.get("/api/projects/:slug/secrets", async (req, reply) => {
|
|
10
10
|
const { slug } = req.params;
|
|
11
11
|
if (!ctx.config.project(slug))
|
|
12
12
|
return reply.code(404).send({ error: "Unknown project" });
|
|
13
|
-
return
|
|
13
|
+
return ctx.vault.listWithValues(slug);
|
|
14
14
|
});
|
|
15
15
|
const put = async (slug, key, body, reply) => {
|
|
16
|
-
const { value, masked } = (body ?? {});
|
|
16
|
+
const { value, masked, inEnvFile } = (body ?? {});
|
|
17
17
|
if (!VALID_KEY.test(key)) {
|
|
18
18
|
return reply.code(400).send({
|
|
19
19
|
error: `"${key}" is not a valid environment variable name: letters, digits and underscore, not starting with a digit.`,
|
|
@@ -31,10 +31,11 @@ export async function registerSecretRoutes(app, ctx) {
|
|
|
31
31
|
"Store it unmasked if you accept it appearing in the output.",
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
// Defaults to false: a variable goes in the file because someone said so,
|
|
35
|
+
// never because a field was left out of a request.
|
|
36
|
+
await ctx.vault.set(slug, key, value, masked !== false, inEnvFile === true);
|
|
35
37
|
return reply.code(204).send();
|
|
36
38
|
};
|
|
37
|
-
app.put("/api/secrets/:key", async (req, reply) => put(null, req.params.key, req.body, reply));
|
|
38
39
|
app.put("/api/projects/:slug/secrets/:key", async (req, reply) => {
|
|
39
40
|
const { slug, key } = req.params;
|
|
40
41
|
if (!ctx.config.project(slug))
|
|
@@ -42,55 +43,60 @@ export async function registerSecretRoutes(app, ctx) {
|
|
|
42
43
|
return put(slug, key, req.body, reply);
|
|
43
44
|
});
|
|
44
45
|
/**
|
|
45
|
-
* One value, in the clear —
|
|
46
|
+
* One value, in the clear — including a masked one, on request.
|
|
46
47
|
*
|
|
47
|
-
* A separate route rather than a field on the listing,
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
48
|
+
* A separate route rather than a field on the listing, and that is the whole
|
|
49
|
+
* of what keeps a secret a secret here: reading one is a deliberate request
|
|
50
|
+
* for one named key, by an admin, one at a time. The listing carries the
|
|
51
|
+
* unmasked values and never a masked one, so opening the tab reveals nothing
|
|
52
|
+
* — pressing `show` on a line does.
|
|
53
|
+
*
|
|
54
|
+
* It used to refuse a masked value outright, and `vault.ts` says at length why
|
|
55
|
+
* that was worth less than it looked. The short version: `masked` is about
|
|
56
|
+
* what a run prints, and refusing to ever show it again meant a passphrase
|
|
57
|
+
* suspected of a typo could be replaced but never checked.
|
|
51
58
|
*/
|
|
52
59
|
app.get("/api/projects/:slug/secrets/:key/value", async (req, reply) => {
|
|
53
60
|
const { slug, key } = req.params;
|
|
54
61
|
if (!ctx.config.project(slug))
|
|
55
62
|
return reply.code(404).send({ error: "Unknown project" });
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
return { key, value };
|
|
61
|
-
}
|
|
62
|
-
catch (cause) {
|
|
63
|
-
// The vault refuses a masked value whoever asks. 409 rather than 403: the
|
|
64
|
-
// request is not forbidden to this account, it is refused for this secret.
|
|
65
|
-
return reply.code(409).send({ error: cause.message });
|
|
66
|
-
}
|
|
63
|
+
const value = ctx.vault.reveal(slug, key);
|
|
64
|
+
if (value === null)
|
|
65
|
+
return reply.code(404).send({ error: "Unknown secret" });
|
|
66
|
+
return { key, value };
|
|
67
67
|
});
|
|
68
68
|
/**
|
|
69
|
-
* Turns
|
|
69
|
+
* Turns a flag on or off, leaving the value alone.
|
|
70
70
|
*
|
|
71
71
|
* Needed because of a circle: to read a value you must first declare it not
|
|
72
72
|
* secret, and declaring that by storing it again would mean typing the value
|
|
73
73
|
* you were trying to read.
|
|
74
|
+
*
|
|
75
|
+
* Two independent flags, and either may be sent alone: `masked` is about what
|
|
76
|
+
* a run prints, `inEnvFile` about whether the variable is also written into
|
|
77
|
+
* the file the build reads. Sending one must not disturb the other — they
|
|
78
|
+
* answer different questions about the same row.
|
|
74
79
|
*/
|
|
75
80
|
app.patch("/api/projects/:slug/secrets/:key", async (req, reply) => {
|
|
76
81
|
const { slug, key } = req.params;
|
|
77
82
|
if (!ctx.config.project(slug))
|
|
78
83
|
return reply.code(404).send({ error: "Unknown project" });
|
|
79
|
-
const { masked } = (req.body ?? {});
|
|
80
|
-
if (typeof masked !== "boolean") {
|
|
84
|
+
const { masked, inEnvFile } = (req.body ?? {});
|
|
85
|
+
if (masked !== undefined && typeof masked !== "boolean") {
|
|
81
86
|
return reply.code(400).send({ error: "`masked` is true or false." });
|
|
82
87
|
}
|
|
88
|
+
if (inEnvFile !== undefined && typeof inEnvFile !== "boolean") {
|
|
89
|
+
return reply.code(400).send({ error: "`inEnvFile` is true or false." });
|
|
90
|
+
}
|
|
91
|
+
if (masked === undefined && inEnvFile === undefined) {
|
|
92
|
+
return reply.code(400).send({ error: "Send `masked`, `inEnvFile`, or both." });
|
|
93
|
+
}
|
|
83
94
|
const existing = ctx.vault.list(slug).find((s) => s.key === key);
|
|
84
95
|
if (!existing)
|
|
85
96
|
return reply.code(404).send({ error: "Unknown secret" });
|
|
86
|
-
if (existing.scope === "global") {
|
|
87
|
-
// The same rule the interface draws: a global secret belongs to every
|
|
88
|
-
// project, so changing it from inside one would hide that from the rest.
|
|
89
|
-
return reply.code(409).send({ error: "That is a global secret. Change it with `laneyard secret set`." });
|
|
90
|
-
}
|
|
91
97
|
// A value too short to redact cannot be masked, the same refusal as on the
|
|
92
98
|
// way in — accepting it would leave someone believing they are protected.
|
|
93
|
-
if (masked) {
|
|
99
|
+
if (masked === true) {
|
|
94
100
|
const value = ctx.vault.reveal(slug, key);
|
|
95
101
|
if (value !== null && value.length < MIN_REDACTABLE) {
|
|
96
102
|
return reply.code(400).send({
|
|
@@ -98,7 +104,80 @@ export async function registerSecretRoutes(app, ctx) {
|
|
|
98
104
|
});
|
|
99
105
|
}
|
|
100
106
|
}
|
|
101
|
-
|
|
107
|
+
if (masked !== undefined)
|
|
108
|
+
ctx.vault.setMasked(slug, key, masked);
|
|
109
|
+
if (inEnvFile !== undefined)
|
|
110
|
+
ctx.vault.setInEnvFile(slug, key, inEnvFile);
|
|
111
|
+
return reply.code(204).send();
|
|
112
|
+
});
|
|
113
|
+
/**
|
|
114
|
+
* The environment file this project will write, before it writes it.
|
|
115
|
+
*
|
|
116
|
+
* The whole reason the flag lives on the variable rather than in a picker: a
|
|
117
|
+
* list of tick boxes cannot tell you that one is missing, and this can. What
|
|
118
|
+
* comes back is the file, rendered exactly as the run will render it, with
|
|
119
|
+
* every masked value replaced by dots.
|
|
120
|
+
*
|
|
121
|
+
* **The masking happens before the render, never after.** Rendering the real
|
|
122
|
+
* values and then trying to blank them would put every secret this project
|
|
123
|
+
* holds into a browser and hope the second pass caught them all. The values
|
|
124
|
+
* that leave this process are dots and the names beside them.
|
|
125
|
+
*/
|
|
126
|
+
app.get("/api/projects/:slug/env-file", async (req, reply) => {
|
|
127
|
+
const { slug } = req.params;
|
|
128
|
+
if (!ctx.config.project(slug))
|
|
129
|
+
return reply.code(404).send({ error: "Unknown project" });
|
|
130
|
+
const resolved = await ctx.config.resolve(slug, ctx.workspacePath(slug));
|
|
131
|
+
const path = resolved?.settings.env_file ?? null;
|
|
132
|
+
const provenance = path === null ? null : (resolved?.provenance.env_file ?? null);
|
|
133
|
+
const masked = new Set(ctx.vault
|
|
134
|
+
.list(slug)
|
|
135
|
+
.filter((s) => s.masked)
|
|
136
|
+
.map((s) => s.key));
|
|
137
|
+
const values = ctx.vault.envFileValues(slug);
|
|
138
|
+
const body = Object.keys(values)
|
|
139
|
+
.sort()
|
|
140
|
+
.map((key) => (masked.has(key) ? `${key}=••••\n` : dotenvLine(key, values[key])))
|
|
141
|
+
.join("");
|
|
142
|
+
return { path, provenance, body };
|
|
143
|
+
});
|
|
144
|
+
/**
|
|
145
|
+
* Turns the environment file on, moves it, or turns it off.
|
|
146
|
+
*
|
|
147
|
+
* Writes `config.yml`, because that is where configuration lives — and it is
|
|
148
|
+
* written from here because a setting reachable only by editing YAML by hand
|
|
149
|
+
* is a feature nobody finds. The accounts screen already writes that file for
|
|
150
|
+
* the same reason.
|
|
151
|
+
*
|
|
152
|
+
* Refused where the repository's own `laneyard.yml` names the path: that file
|
|
153
|
+
* wins for every setting, and a screen that appeared to change it while the
|
|
154
|
+
* next run ignored what it wrote would be worse than one that says who decides.
|
|
155
|
+
*/
|
|
156
|
+
app.put("/api/projects/:slug/env-file", async (req, reply) => {
|
|
157
|
+
const { slug } = req.params;
|
|
158
|
+
if (!ctx.config.project(slug))
|
|
159
|
+
return reply.code(404).send({ error: "Unknown project" });
|
|
160
|
+
const { path } = (req.body ?? {});
|
|
161
|
+
if (path !== null && typeof path !== "string") {
|
|
162
|
+
return reply.code(400).send({ error: "`path` is a path, or null to write no file." });
|
|
163
|
+
}
|
|
164
|
+
const resolved = await ctx.config.resolve(slug, ctx.workspacePath(slug));
|
|
165
|
+
if (resolved?.provenance.env_file === "repo") {
|
|
166
|
+
return reply.code(409).send({
|
|
167
|
+
error: "The repository's laneyard.yml sets env_file. Change it there, and commit it.",
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
if (typeof path === "string") {
|
|
171
|
+
const problem = envFileProblem(path.trim());
|
|
172
|
+
if (problem)
|
|
173
|
+
return reply.code(400).send({ error: problem });
|
|
174
|
+
}
|
|
175
|
+
const found = await setEnvFileSetting(ctx.config.configPath(), slug, typeof path === "string" ? path.trim() : null);
|
|
176
|
+
if (!found)
|
|
177
|
+
return reply.code(404).send({ error: "Unknown project" });
|
|
178
|
+
// The file is watched, but on a debounce: reloading here is what makes the
|
|
179
|
+
// very next request — the one this screen is about to send — truthful.
|
|
180
|
+
await ctx.config.load();
|
|
102
181
|
return reply.code(204).send();
|
|
103
182
|
});
|
|
104
183
|
/**
|
|
@@ -133,17 +212,10 @@ export async function registerSecretRoutes(app, ctx) {
|
|
|
133
212
|
workspacePath,
|
|
134
213
|
fastlaneDir,
|
|
135
214
|
vaultKeys: ctx.vault.list(slug).map((s) => s.key),
|
|
136
|
-
// Resolved the way a run resolves them, a project's own block shadowing a
|
|
137
|
-
// global one, so the form and the checklist cannot disagree about what is
|
|
138
|
-
// already supplied.
|
|
139
215
|
blockNames: exportedVarNames(ctx.vault.listCredentials(slug)),
|
|
140
216
|
serverEnv: Object.keys(process.env),
|
|
141
217
|
});
|
|
142
218
|
});
|
|
143
|
-
app.delete("/api/secrets/:key", async (req, reply) => {
|
|
144
|
-
const removed = ctx.vault.remove(null, req.params.key);
|
|
145
|
-
return removed ? reply.code(204).send() : reply.code(404).send({ error: "Unknown secret" });
|
|
146
|
-
});
|
|
147
219
|
app.delete("/api/projects/:slug/secrets/:key", async (req, reply) => {
|
|
148
220
|
const { slug, key } = req.params;
|
|
149
221
|
const removed = ctx.vault.remove(slug, key);
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { stat } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
const isDirectory = async (path) => stat(path).then((s) => s.isDirectory(), () => false);
|
|
2
4
|
/**
|
|
3
5
|
* Refuses a missing fastlane directory with a sentence instead of an ENOENT.
|
|
4
6
|
*
|
|
@@ -6,16 +8,24 @@ import { stat } from "node:fs/promises";
|
|
|
6
8
|
* '…/workspaces/popotheque-app/fastlane'` — technically accurate and no help at
|
|
7
9
|
* all, because the interesting part is *why* it was looking there.
|
|
8
10
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* Two stories, and they need different sentences. **The workspace may not exist
|
|
12
|
+
* at all**: nothing has been cloned yet, which is the ordinary state of a project
|
|
13
|
+
* between `laneyard setup` and its first run. Telling that one it forgot to push
|
|
14
|
+
* sent people through their git history looking for a problem they did not have.
|
|
15
|
+
*
|
|
16
|
+
* Otherwise the clone is there without the folder, and it is nearly always the
|
|
17
|
+
* same story: the configured fastlane folder is in the working copy setup ran
|
|
18
|
+
* against, but not in the clone Laneyard builds from — never committed, not yet
|
|
19
|
+
* pushed, or gitignored.
|
|
14
20
|
*/
|
|
15
|
-
export async function assertFastlaneDir(
|
|
16
|
-
|
|
17
|
-
if (found)
|
|
21
|
+
export async function assertFastlaneDir(workspacePath, configured) {
|
|
22
|
+
if (await isDirectory(join(workspacePath, configured)))
|
|
18
23
|
return;
|
|
24
|
+
if (!(await isDirectory(workspacePath))) {
|
|
25
|
+
throw new Error(`${configured}/ cannot be read yet: this project has not been cloned. ` +
|
|
26
|
+
"Laneyard clones the repository on the project's first run — start one, " +
|
|
27
|
+
"and the Fastfile is readable from then on.");
|
|
28
|
+
}
|
|
19
29
|
throw new Error(`No ${configured}/ in the clone. Laneyard builds from a clone of the remote, ` +
|
|
20
30
|
"so a fastlane folder that exists only in your working copy — uncommitted, " +
|
|
21
31
|
"unpushed, or gitignored — never reaches it. Commit and push it, or set " +
|
|
@@ -9,7 +9,7 @@ import { assertFastlaneDir } from "./fastlane-dir.js";
|
|
|
9
9
|
*/
|
|
10
10
|
async function hashFastlaneDir(root, fastlaneDir) {
|
|
11
11
|
const dir = join(root, fastlaneDir);
|
|
12
|
-
await assertFastlaneDir(
|
|
12
|
+
await assertFastlaneDir(root, fastlaneDir);
|
|
13
13
|
const hash = createHash("sha256");
|
|
14
14
|
// Same reason as in `uses.ts`: the reader is part of the key, so improving the
|
|
15
15
|
// sidecar cannot leave an install served by what the old one concluded.
|
package/dist/src/sidecar/uses.js
CHANGED
|
@@ -9,7 +9,7 @@ import { assertFastlaneDir } from "./fastlane-dir.js";
|
|
|
9
9
|
*/
|
|
10
10
|
async function hashFastlaneDir(root, fastlaneDir) {
|
|
11
11
|
const dir = join(root, fastlaneDir);
|
|
12
|
-
await assertFastlaneDir(
|
|
12
|
+
await assertFastlaneDir(root, fastlaneDir);
|
|
13
13
|
const hash = createHash("sha256");
|
|
14
14
|
// The sidecar is part of the question, not just the answer: a parser that
|
|
15
15
|
// learns to read more finds more in a Fastfile that never changed, and a key
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as Fn,j as Eh}from"./index-
|
|
1
|
+
import{r as Fn,j as Eh}from"./index-DnUdqjT4.js";let hs=[],tl=[];(()=>{let n="lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,3b,f,,w,1j,,,,4,8,4,,3,7,a,2,t,,1m,,,,2,4,8,,9,,a,2,q,,2,2,1l,,4,2,4,2,2,3,3,,u,2,3,,b,2,1l,,4,5,,2,4,,k,2,m,6,,,1m,,,2,,4,8,,7,3,a,2,u,,1n,,,,c,,9,,14,,3,,1l,3,5,3,,4,7,2,b,2,t,,1m,,2,,2,,3,,5,2,7,2,b,2,s,2,1l,2,,,2,4,8,,9,,a,2,t,,20,,4,,2,3,,,8,,29,,2,7,c,8,2q,,2,9,b,6,22,2,r,,,,,,1j,e,,5,,2,5,b,,10,9,,2u,4,,6,,2,2,2,p,2,4,3,g,4,d,,2,2,6,,f,,jj,3,qa,3,t,3,t,2,u,2,1s,2,,7,8,,2,b,9,,19,3,3b,2,y,,3a,3,4,2,9,,6,3,63,2,2,,1m,,,7,,,,,2,8,6,a,2,,1c,h,1r,4,1c,7,,,5,,14,9,c,2,w,4,2,2,,3,1k,,,2,3,,,3,1m,8,2,2,48,3,,d,,7,4,,6,,3,2,5i,1m,,5,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,p,2,5,,47,2,q,i,d,,12,8,p,b,1a,3,1c,,2,4,2,2,13,,1v,6,2,2,2,2,c,,8,,1b,,1f,,,3,2,2,5,2,,,16,2,8,,6m,,2,,4,,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,ar,2,49,b,4w,,1i,f,1k,3,1d,4,2,2,1x,3,10,5,,8,1q,,c,2,1g,9,a,4,2,,2n,3,2,,,2,6,,4g,,3,8,l,2,1l,2,,,,,m,,e,7,3,5,5f,8,2,3,,,n,,29,,2,6,,,2,,,2,,2,6j,,2,4,6,2,,2,r,2,2d,8,2,,,2,2y,,,,2,6,,,2t,3,2,4,,5,77,9,,2,6t,,a,2,,,4,,40,4,2,2,4,,w,a,14,6,2,4,8,,9,6,2,3,1a,d,,2,ba,7,,6,,,2a,m,2,7,,2,,2,3e,6,3,,,2,,7,,,20,2,3,,,,9n,2,f0b,5,1n,7,t4,,1r,4,29,,f5k,2,43q,,,3,4,5,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,79,7,c5,4,15s,7,31,7,240,5,gx7k,2o,3k,6o".split(",").map(e=>e?parseInt(e,36):1);for(let e=0,t=0;e<n.length;e++)(e%2?tl:hs).push(t=t+n[e])})();function Rh(n){if(n<768)return!1;for(let e=0,t=hs.length;;){let i=e+t>>1;if(n<hs[i])t=i;else if(n>=tl[i])e=i+1;else return!0;if(e==t)return!1}}function Pr(n){return n>=127462&&n<=127487}const Ir=8205;function Ph(n,e,t=!0,i=!0){return(t?il:Ih)(n,e,i)}function il(n,e,t){if(e==n.length)return e;e&&nl(n.charCodeAt(e))&&sl(n.charCodeAt(e-1))&&e--;let i=Hn(n,e);for(e+=Nr(i);e<n.length;){let s=Hn(n,e);if(i==Ir||s==Ir||t&&Rh(s))e+=Nr(s),i=s;else if(Pr(s)){let r=0,o=e-2;for(;o>=0&&Pr(Hn(n,o));)r++,o-=2;if(r%2==0)break;e+=2}else break}return e}function Ih(n,e,t){for(;e>1;){let i=il(n,e-2,t);if(i<e)return i;e--}return 0}function Hn(n,e){let t=n.charCodeAt(e);if(!sl(t)||e+1==n.length)return t;let i=n.charCodeAt(e+1);return nl(i)?(t-55296<<10)+(i-56320)+65536:t}function nl(n){return n>=56320&&n<57344}function sl(n){return n>=55296&&n<56320}function Nr(n){return n<65536?1:2}class W{lineAt(e){if(e<0||e>this.length)throw new RangeError(`Invalid position ${e} in document of length ${this.length}`);return this.lineInner(e,!1,1,0)}line(e){if(e<1||e>this.lines)throw new RangeError(`Invalid line number ${e} in ${this.lines}-line document`);return this.lineInner(e,!0,1,0)}replace(e,t,i){[e,t]=Ht(this,e,t);let s=[];return this.decompose(0,e,s,2),i.length&&i.decompose(0,i.length,s,3),this.decompose(t,this.length,s,1),Ve.from(s,this.length-(t-e)+i.length)}append(e){return this.replace(this.length,this.length,e)}slice(e,t=this.length){[e,t]=Ht(this,e,t);let i=[];return this.decompose(e,t,i,0),Ve.from(i,t-e)}eq(e){if(e==this)return!0;if(e.length!=this.length||e.lines!=this.lines)return!1;let t=this.scanIdentical(e,1),i=this.length-this.scanIdentical(e,-1),s=new ri(this),r=new ri(e);for(let o=t,l=t;;){if(s.next(o),r.next(o),o=0,s.lineBreak!=r.lineBreak||s.done!=r.done||s.value!=r.value)return!1;if(l+=s.value.length,s.done||l>=i)return!0}}iter(e=1){return new ri(this,e)}iterRange(e,t=this.length){return new rl(this,e,t)}iterLines(e,t){let i;if(e==null)i=this.iter();else{t==null&&(t=this.lines+1);let s=this.line(e).from;i=this.iterRange(s,Math.max(s,t==this.lines+1?this.length:t<=1?0:this.line(t-1).to))}return new ol(i)}toString(){return this.sliceString(0)}toJSON(){let e=[];return this.flatten(e),e}constructor(){}static of(e){if(e.length==0)throw new RangeError("A document must have at least one line");return e.length==1&&!e[0]?W.empty:e.length<=32?new J(e):Ve.from(J.split(e,[]))}}class J extends W{constructor(e,t=Nh(e)){super(),this.text=e,this.length=t}get lines(){return this.text.length}get children(){return null}lineInner(e,t,i,s){for(let r=0;;r++){let o=this.text[r],l=s+o.length;if((t?i:l)>=e)return new Wh(s,l,i,o);s=l+1,i++}}decompose(e,t,i,s){let r=e<=0&&t>=this.length?this:new J(Wr(this.text,e,t),Math.min(t,this.length)-Math.max(0,e));if(s&1){let o=i.pop(),l=Yi(r.text,o.text.slice(),0,r.length);if(l.length<=32)i.push(new J(l,o.length+r.length));else{let a=l.length>>1;i.push(new J(l.slice(0,a)),new J(l.slice(a)))}}else i.push(r)}replace(e,t,i){if(!(i instanceof J))return super.replace(e,t,i);[e,t]=Ht(this,e,t);let s=Yi(this.text,Yi(i.text,Wr(this.text,0,e)),t),r=this.length+i.length-(t-e);return s.length<=32?new J(s,r):Ve.from(J.split(s,[]),r)}sliceString(e,t=this.length,i=`
|
|
2
2
|
`){[e,t]=Ht(this,e,t);let s="";for(let r=0,o=0;r<=t&&o<this.text.length;o++){let l=this.text[o],a=r+l.length;r>e&&o&&(s+=i),e<a&&t>r&&(s+=l.slice(Math.max(0,e-r),t-r)),r=a+1}return s}flatten(e){for(let t of this.text)e.push(t)}scanIdentical(){return 0}static split(e,t){let i=[],s=-1;for(let r of e)i.push(r),s+=r.length+1,i.length==32&&(t.push(new J(i,s)),i=[],s=-1);return s>-1&&t.push(new J(i,s)),t}}class Ve extends W{constructor(e,t){super(),this.children=e,this.length=t,this.lines=0;for(let i of e)this.lines+=i.lines}lineInner(e,t,i,s){for(let r=0;;r++){let o=this.children[r],l=s+o.length,a=i+o.lines-1;if((t?a:l)>=e)return o.lineInner(e,t,i,s);s=l+1,i=a+1}}decompose(e,t,i,s){for(let r=0,o=0;o<=t&&r<this.children.length;r++){let l=this.children[r],a=o+l.length;if(e<=a&&t>=o){let h=s&((o<=e?1:0)|(a>=t?2:0));o>=e&&a<=t&&!h?i.push(l):l.decompose(e-o,t-o,i,h)}o=a+1}}replace(e,t,i){if([e,t]=Ht(this,e,t),i.lines<this.lines)for(let s=0,r=0;s<this.children.length;s++){let o=this.children[s],l=r+o.length;if(e>=r&&t<=l){let a=o.replace(e-r,t-r,i),h=this.lines-o.lines+a.lines;if(a.lines<h>>4&&a.lines>h>>6){let c=this.children.slice();return c[s]=a,new Ve(c,this.length-(t-e)+i.length)}return super.replace(r,l,a)}r=l+1}return super.replace(e,t,i)}sliceString(e,t=this.length,i=`
|
|
3
3
|
`){[e,t]=Ht(this,e,t);let s="";for(let r=0,o=0;r<this.children.length&&o<=t;r++){let l=this.children[r],a=o+l.length;o>e&&r&&(s+=i),e<a&&t>o&&(s+=l.sliceString(e-o,t-o,i)),o=a+1}return s}flatten(e){for(let t of this.children)t.flatten(e)}scanIdentical(e,t){if(!(e instanceof Ve))return 0;let i=0,[s,r,o,l]=t>0?[0,0,this.children.length,e.children.length]:[this.children.length-1,e.children.length-1,-1,-1];for(;;s+=t,r+=t){if(s==o||r==l)return i;let a=this.children[s],h=e.children[r];if(a!=h)return i+a.scanIdentical(h,t);i+=a.length+1}}static from(e,t=e.reduce((i,s)=>i+s.length+1,-1)){let i=0;for(let d of e)i+=d.lines;if(i<32){let d=[];for(let p of e)p.flatten(d);return new J(d,t)}let s=Math.max(32,i>>5),r=s<<1,o=s>>1,l=[],a=0,h=-1,c=[];function f(d){let p;if(d.lines>r&&d instanceof Ve)for(let g of d.children)f(g);else d.lines>o&&(a>o||!a)?(u(),l.push(d)):d instanceof J&&a&&(p=c[c.length-1])instanceof J&&d.lines+p.lines<=32?(a+=d.lines,h+=d.length+1,c[c.length-1]=new J(p.text.concat(d.text),p.length+1+d.length)):(a+d.lines>s&&u(),a+=d.lines,h+=d.length+1,c.push(d))}function u(){a!=0&&(l.push(c.length==1?c[0]:Ve.from(c,h)),h=-1,a=c.length=0)}for(let d of e)f(d);return u(),l.length==1?l[0]:new Ve(l,t)}}W.empty=new J([""],0);function Nh(n){let e=-1;for(let t of n)e+=t.length+1;return e}function Yi(n,e,t=0,i=1e9){for(let s=0,r=0,o=!0;r<n.length&&s<=i;r++){let l=n[r],a=s+l.length;a>=t&&(a>i&&(l=l.slice(0,i-s)),s<t&&(l=l.slice(t-s)),o?(e[e.length-1]+=l,o=!1):e.push(l)),s=a+1}return e}function Wr(n,e,t){return Yi(n,[""],e,t)}class ri{constructor(e,t=1){this.dir=t,this.done=!1,this.lineBreak=!1,this.value="",this.nodes=[e],this.offsets=[t>0?1:(e instanceof J?e.text.length:e.children.length)<<1]}nextInner(e,t){for(this.done=this.lineBreak=!1;;){let i=this.nodes.length-1,s=this.nodes[i],r=this.offsets[i],o=r>>1,l=s instanceof J?s.text.length:s.children.length;if(o==(t>0?l:0)){if(i==0)return this.done=!0,this.value="",this;t>0&&this.offsets[i-1]++,this.nodes.pop(),this.offsets.pop()}else if((r&1)==(t>0?0:1)){if(this.offsets[i]+=t,e==0)return this.lineBreak=!0,this.value=`
|
|
4
4
|
`,this;e--}else if(s instanceof J){let a=s.text[o+(t<0?-1:0)];if(this.offsets[i]+=t,a.length>Math.max(0,e))return this.value=e==0?a:t>0?a.slice(e):a.slice(0,a.length-e),this;e-=a.length}else{let a=s.children[o+(t<0?-1:0)];e>a.length?(e-=a.length,this.offsets[i]+=t):(t<0&&this.offsets[i]--,this.nodes.push(a),this.offsets.push(t>0?1:(a instanceof J?a.text.length:a.children.length)<<1))}}}next(e=0){return e<0&&(this.nextInner(-e,-this.dir),e=this.value.length),this.nextInner(e,this.dir)}}class rl{constructor(e,t,i){this.value="",this.done=!1,this.cursor=new ri(e,t>i?-1:1),this.pos=t>i?e.length:0,this.from=Math.min(t,i),this.to=Math.max(t,i)}nextInner(e,t){if(t<0?this.pos<=this.from:this.pos>=this.to)return this.value="",this.done=!0,this;e+=Math.max(0,t<0?this.pos-this.to:this.from-this.pos);let i=t<0?this.pos-this.from:this.to-this.pos;e>i&&(e=i),i-=e;let{value:s}=this.cursor.next(e);return this.pos+=(s.length+e)*t,this.value=s.length<=i?s:t<0?s.slice(s.length-i):s.slice(0,i),this.done=!this.value,this}next(e=0){return e<0?e=Math.max(e,this.from-this.pos):e>0&&(e=Math.min(e,this.to-this.pos)),this.nextInner(e,this.cursor.dir)}get lineBreak(){return this.cursor.lineBreak&&this.value!=""}}class ol{constructor(e){this.inner=e,this.afterBreak=!0,this.value="",this.done=!1}next(e=0){let{done:t,lineBreak:i,value:s}=this.inner.next(e);return t&&this.afterBreak?(this.value="",this.afterBreak=!1):t?(this.done=!0,this.value=""):i?this.afterBreak?this.value="":(this.afterBreak=!0,this.next()):(this.value=s,this.afterBreak=!1),this}get lineBreak(){return!1}}typeof Symbol<"u"&&(W.prototype[Symbol.iterator]=function(){return this.iter()},ri.prototype[Symbol.iterator]=rl.prototype[Symbol.iterator]=ol.prototype[Symbol.iterator]=function(){return this});class Wh{constructor(e,t,i,s){this.from=e,this.to=t,this.number=i,this.text=s}get length(){return this.to-this.from}}function Ht(n,e,t){return e=Math.max(0,Math.min(n.length,e)),[e,Math.max(e,Math.min(n.length,t))]}function ee(n,e,t=!0,i=!0){return Ph(n,e,t,i)}function Fh(n){return n>=56320&&n<57344}function Hh(n){return n>=55296&&n<56320}function er(n,e){let t=n.charCodeAt(e);if(!Hh(t)||e+1==n.length)return t;let i=n.charCodeAt(e+1);return Fh(i)?(t-55296<<10)+(i-56320)+65536:t}function Vh(n){return n<=65535?String.fromCharCode(n):(n-=65536,String.fromCharCode((n>>10)+55296,(n&1023)+56320))}function ll(n){return n<65536?1:2}const cs=/\r\n?|\n/;var xe=function(n){return n[n.Simple=0]="Simple",n[n.TrackDel=1]="TrackDel",n[n.TrackBefore=2]="TrackBefore",n[n.TrackAfter=3]="TrackAfter",n}(xe||(xe={}));class Ue{constructor(e){this.sections=e}get length(){let e=0;for(let t=0;t<this.sections.length;t+=2)e+=this.sections[t];return e}get newLength(){let e=0;for(let t=0;t<this.sections.length;t+=2){let i=this.sections[t+1];e+=i<0?this.sections[t]:i}return e}get empty(){return this.sections.length==0||this.sections.length==2&&this.sections[1]<0}iterGaps(e){for(let t=0,i=0,s=0;t<this.sections.length;){let r=this.sections[t++],o=this.sections[t++];o<0?(e(i,s,r),s+=r):s+=o,i+=r}}iterChangedRanges(e,t=!1){fs(this,e,t)}get invertedDesc(){let e=[];for(let t=0;t<this.sections.length;){let i=this.sections[t++],s=this.sections[t++];s<0?e.push(i,s):e.push(s,i)}return new Ue(e)}composeDesc(e){return this.empty?e:e.empty?this:al(this,e)}mapDesc(e,t=!1){return e.empty?this:us(this,e,t)}mapPos(e,t=-1,i=xe.Simple){let s=0,r=0;for(let o=0;o<this.sections.length;){let l=this.sections[o++],a=this.sections[o++],h=s+l;if(a<0){if(h>e)return r+(e-s);r+=l}else{if(i!=xe.Simple&&h>=e&&(i==xe.TrackDel&&s<e&&h>e||i==xe.TrackBefore&&s<e||i==xe.TrackAfter&&h>e))return null;if(h>e||h==e&&t<0&&!l)return e==s||t<0?r:r+a;r+=a}s=h}if(e>s)throw new RangeError(`Position ${e} is out of range for changeset of length ${s}`);return r}touchesRange(e,t=e){for(let i=0,s=0;i<this.sections.length&&s<=t;){let r=this.sections[i++],o=this.sections[i++],l=s+r;if(o>=0&&s<=t&&l>=e)return s<e&&l>t?"cover":!0;s=l}return!1}toString(){let e="";for(let t=0;t<this.sections.length;){let i=this.sections[t++],s=this.sections[t++];e+=(e?" ":"")+i+(s>=0?":"+s:"")}return e}toJSON(){return this.sections}static fromJSON(e){if(!Array.isArray(e)||e.length%2||e.some(t=>typeof t!="number"))throw new RangeError("Invalid JSON representation of ChangeDesc");return new Ue(e)}static create(e){return new Ue(e)}}class X extends Ue{constructor(e,t){super(e),this.inserted=t}apply(e){if(this.length!=e.length)throw new RangeError("Applying change set to a document with the wrong length");return fs(this,(t,i,s,r,o)=>e=e.replace(s,s+(i-t),o),!1),e}mapDesc(e,t=!1){return us(this,e,t,!0)}invert(e){let t=this.sections.slice(),i=[];for(let s=0,r=0;s<t.length;s+=2){let o=t[s],l=t[s+1];if(l>=0){t[s]=l,t[s+1]=o;let a=s>>1;for(;i.length<a;)i.push(W.empty);i.push(o?e.slice(r,r+o):W.empty)}r+=o}return new X(t,i)}compose(e){return this.empty?e:e.empty?this:al(this,e,!0)}map(e,t=!1){return e.empty?this:us(this,e,t,!0)}iterChanges(e,t=!1){fs(this,e,t)}get desc(){return Ue.create(this.sections)}filter(e){let t=[],i=[],s=[],r=new fi(this);e:for(let o=0,l=0;;){let a=o==e.length?1e9:e[o++];for(;l<a||l==a&&r.len==0;){if(r.done)break e;let c=Math.min(r.len,a-l);oe(s,c,-1);let f=r.ins==-1?-1:r.off==0?r.ins:0;oe(t,c,f),f>0&&nt(i,t,r.text),r.forward(c),l+=c}let h=e[o++];for(;l<h;){if(r.done)break e;let c=Math.min(r.len,h-l);oe(t,c,-1),oe(s,c,r.ins==-1?-1:r.off==0?r.ins:0),r.forward(c),l+=c}}return{changes:new X(t,i),filtered:Ue.create(s)}}toJSON(){let e=[];for(let t=0;t<this.sections.length;t+=2){let i=this.sections[t],s=this.sections[t+1];s<0?e.push(i):s==0?e.push([i]):e.push([i].concat(this.inserted[t>>1].toJSON()))}return e}static of(e,t,i){let s=[],r=[],o=0,l=null;function a(c=!1){if(!c&&!s.length)return;o<t&&oe(s,t-o,-1);let f=new X(s,r);l=l?l.compose(f.map(l)):f,s=[],r=[],o=0}function h(c){if(Array.isArray(c))for(let f of c)h(f);else if(c instanceof X){if(c.length!=t)throw new RangeError(`Mismatched change set length (got ${c.length}, expected ${t})`);a(),l=l?l.compose(c.map(l)):c}else{let{from:f,to:u=f,insert:d}=c;if(f>u||f<0||u>t)throw new RangeError(`Invalid change range ${f} to ${u} (in doc of length ${t})`);let p=d?typeof d=="string"?W.of(d.split(i||cs)):d:W.empty,g=p.length;if(f==u&&g==0)return;f<o&&a(),f>o&&oe(s,f-o,-1),oe(s,u-f,g),nt(r,s,p),o=u}}return h(e),a(!l),l}static empty(e){return new X(e?[e,-1]:[],[])}static fromJSON(e){if(!Array.isArray(e))throw new RangeError("Invalid JSON representation of ChangeSet");let t=[],i=[];for(let s=0;s<e.length;s++){let r=e[s];if(typeof r=="number")t.push(r,-1);else{if(!Array.isArray(r)||typeof r[0]!="number"||r.some((o,l)=>l&&typeof o!="string"))throw new RangeError("Invalid JSON representation of ChangeSet");if(r.length==1)t.push(r[0],0);else{for(;i.length<s;)i.push(W.empty);i[s]=W.of(r.slice(1)),t.push(r[0],i[s].length)}}}return new X(t,i)}static createSet(e,t){return new X(e,t)}}function oe(n,e,t,i=!1){if(e==0&&t<=0)return;let s=n.length-2;s>=0&&t<=0&&t==n[s+1]?n[s]+=e:s>=0&&e==0&&n[s]==0?n[s+1]+=t:i?(n[s]+=e,n[s+1]+=t):n.push(e,t)}function nt(n,e,t){if(t.length==0)return;let i=e.length-2>>1;if(i<n.length)n[n.length-1]=n[n.length-1].append(t);else{for(;n.length<i;)n.push(W.empty);n.push(t)}}function fs(n,e,t){let i=n.inserted;for(let s=0,r=0,o=0;o<n.sections.length;){let l=n.sections[o++],a=n.sections[o++];if(a<0)s+=l,r+=l;else{let h=s,c=r,f=W.empty;for(;h+=l,c+=a,a&&i&&(f=f.append(i[o-2>>1])),!(t||o==n.sections.length||n.sections[o+1]<0);)l=n.sections[o++],a=n.sections[o++];e(s,h,r,c,f),s=h,r=c}}}function us(n,e,t,i=!1){let s=[],r=i?[]:null,o=new fi(n),l=new fi(e);for(let a=-1;;){if(o.done&&l.len||l.done&&o.len)throw new Error("Mismatched change set lengths");if(o.ins==-1&&l.ins==-1){let h=Math.min(o.len,l.len);oe(s,h,-1),o.forward(h),l.forward(h)}else if(l.ins>=0&&(o.ins<0||a==o.i||o.off==0&&(l.len<o.len||l.len==o.len&&!t))){let h=l.len;for(oe(s,l.ins,-1);h;){let c=Math.min(o.len,h);o.ins>=0&&a<o.i&&o.len<=c&&(oe(s,0,o.ins),r&&nt(r,s,o.text),a=o.i),o.forward(c),h-=c}l.next()}else if(o.ins>=0){let h=0,c=o.len;for(;c;)if(l.ins==-1){let f=Math.min(c,l.len);h+=f,c-=f,l.forward(f)}else if(l.ins==0&&l.len<c)c-=l.len,l.next();else break;oe(s,h,a<o.i?o.ins:0),r&&a<o.i&&nt(r,s,o.text),a=o.i,o.forward(o.len-c)}else{if(o.done&&l.done)return r?X.createSet(s,r):Ue.create(s);throw new Error("Mismatched change set lengths")}}}function al(n,e,t=!1){let i=[],s=t?[]:null,r=new fi(n),o=new fi(e);for(let l=!1;;){if(r.done&&o.done)return s?X.createSet(i,s):Ue.create(i);if(r.ins==0)oe(i,r.len,0,l),r.next();else if(o.len==0&&!o.done)oe(i,0,o.ins,l),s&&nt(s,i,o.text),o.next();else{if(r.done||o.done)throw new Error("Mismatched change set lengths");{let a=Math.min(r.len2,o.len),h=i.length;if(r.ins==-1){let c=o.ins==-1?-1:o.off?0:o.ins;oe(i,a,c,l),s&&c&&nt(s,i,o.text)}else o.ins==-1?(oe(i,r.off?0:r.len,a,l),s&&nt(s,i,r.textBit(a))):(oe(i,r.off?0:r.len,o.off?0:o.ins,l),s&&!o.off&&nt(s,i,o.text));l=(r.ins>a||o.ins>=0&&o.len>a)&&(l||i.length>h),r.forward2(a),o.forward(a)}}}}class fi{constructor(e){this.set=e,this.i=0,this.next()}next(){let{sections:e}=this.set;this.i<e.length?(this.len=e[this.i++],this.ins=e[this.i++]):(this.len=0,this.ins=-2),this.off=0}get done(){return this.ins==-2}get len2(){return this.ins<0?this.len:this.ins}get text(){let{inserted:e}=this.set,t=this.i-2>>1;return t>=e.length?W.empty:e[t]}textBit(e){let{inserted:t}=this.set,i=this.i-2>>1;return i>=t.length&&!e?W.empty:t[i].slice(this.off,e==null?void 0:this.off+e)}forward(e){e==this.len?this.next():(this.len-=e,this.off+=e)}forward2(e){this.ins==-1?this.forward(e):e==this.ins?this.next():(this.ins-=e,this.off+=e)}}class tt{constructor(e,t,i,s){this.from=e,this.to=t,this.flags=i,this.goalColumn=s}get anchor(){return this.flags&32?this.to:this.from}get head(){return this.flags&32?this.from:this.to}get empty(){return this.from==this.to}get assoc(){return this.flags&8?-1:this.flags&16?1:0}get undirectional(){return(this.flags&64)>0}get bidiLevel(){let e=this.flags&7;return e==7?null:e}map(e,t=-1){let i,s;return this.empty?i=s=e.mapPos(this.from,t):(i=e.mapPos(this.from,1),s=e.mapPos(this.to,-1)),i==this.from&&s==this.to?this:new tt(i,s,this.flags,this.goalColumn)}extend(e,t=e,i=0){if(e<=this.anchor&&t>=this.anchor)return b.range(e,t,void 0,void 0,i);let s=Math.abs(e-this.anchor)>Math.abs(t-this.anchor)?e:t;return b.range(this.anchor,s,void 0,void 0,i)}eq(e,t=!1){return this.anchor==e.anchor&&this.head==e.head&&this.goalColumn==e.goalColumn&&(!t||!this.empty||this.assoc==e.assoc)}toJSON(){return{anchor:this.anchor,head:this.head}}static fromJSON(e){if(!e||typeof e.anchor!="number"||typeof e.head!="number")throw new RangeError("Invalid JSON representation for SelectionRange");return b.range(e.anchor,e.head)}static create(e,t,i,s){return new tt(e,t,i,s)}}class b{constructor(e,t){this.ranges=e,this.mainIndex=t}map(e,t=-1){return e.empty?this:b.create(this.ranges.map(i=>i.map(e,t)),this.mainIndex)}eq(e,t=!1){if(this.ranges.length!=e.ranges.length||this.mainIndex!=e.mainIndex)return!1;for(let i=0;i<this.ranges.length;i++)if(!this.ranges[i].eq(e.ranges[i],t))return!1;return!0}get main(){return this.ranges[this.mainIndex]}asSingle(){return this.ranges.length==1?this:new b([this.main],0)}addRange(e,t=!0){return b.create([e].concat(this.ranges),t?0:this.mainIndex+1)}replaceRange(e,t=this.mainIndex){let i=this.ranges.slice();return i[t]=e,b.create(i,this.mainIndex)}toJSON(){return{ranges:this.ranges.map(e=>e.toJSON()),main:this.mainIndex}}static fromJSON(e){if(!e||!Array.isArray(e.ranges)||typeof e.main!="number"||e.main>=e.ranges.length)throw new RangeError("Invalid JSON representation for EditorSelection");return new b(e.ranges.map(t=>tt.fromJSON(t)),e.main)}static single(e,t=e){return new b([b.range(e,t)],0)}static create(e,t=0){if(e.length==0)throw new RangeError("A selection needs at least one range");for(let i=0,s=0;s<e.length;s++){let r=e[s];if(r.empty?r.from<=i:r.from<i)return b.normalized(e.slice(),t);i=r.to}return new b(e,t)}static cursor(e,t=0,i,s){return tt.create(e,e,(t==0?0:t<0?8:16)|(i==null?7:Math.min(6,i)),s)}static range(e,t,i,s,r){let o=s==null?7:Math.min(6,s);return!r&&e!=t&&(r=t<e?1:-1),r&&(o|=r<0?8:16),t<e?tt.create(t,e,o|32,i):tt.create(e,t,o,i)}static undirectionalRange(e,t){return tt.create(e,t,64,void 0)}static normalized(e,t=0){let i=e[t];e.sort((s,r)=>s.from-r.from),t=e.indexOf(i);for(let s=1;s<e.length;s++){let r=e[s],o=e[s-1];if(r.empty?r.from<=o.to:r.from<o.to){let l=o.from,a=Math.max(r.to,o.to);s<=t&&t--,e.splice(--s,2,r.anchor>r.head?b.range(a,l):b.range(l,a))}}return new b(e,t)}}function hl(n,e){for(let t of n.ranges)if(t.to>e)throw new RangeError("Selection points outside of document")}let tr=0;class A{constructor(e,t,i,s,r){this.combine=e,this.compareInput=t,this.compare=i,this.isStatic=s,this.id=tr++,this.default=e([]),this.extensions=typeof r=="function"?r(this):r}get reader(){return this}static define(e={}){return new A(e.combine||(t=>t),e.compareInput||((t,i)=>t===i),e.compare||(e.combine?(t,i)=>t===i:ir),!!e.static,e.enables)}of(e){return new Xi([],this,0,e)}compute(e,t){if(this.isStatic)throw new Error("Can't compute a static facet");return new Xi(e,this,1,t)}computeN(e,t){if(this.isStatic)throw new Error("Can't compute a static facet");return new Xi(e,this,2,t)}from(e,t){return t||(t=i=>i),this.compute([e],i=>t(i.field(e)))}}function ir(n,e){return n==e||n.length==e.length&&n.every((t,i)=>t===e[i])}class Xi{constructor(e,t,i,s){this.dependencies=e,this.facet=t,this.type=i,this.value=s,this.id=tr++}dynamicSlot(e){var t;let i=this.value,s=this.facet.compareInput,r=this.id,o=e[r]>>1,l=this.type==2,a=!1,h=!1,c=[];for(let f of this.dependencies)f=="doc"?a=!0:f=="selection"?h=!0:((t=e[f.id])!==null&&t!==void 0?t:1)&1||c.push(e[f.id]);return{create(f){return f.values[o]=i(f),1},update(f,u){if(a&&u.docChanged||h&&(u.docChanged||u.selection)||ds(f,c)){let d=i(f);if(l?!Fr(d,f.values[o],s):!s(d,f.values[o]))return f.values[o]=d,1}return 0},reconfigure:(f,u)=>{let d,p=u.config.address[r];if(p!=null){let g=ln(u,p);if(this.dependencies.every(m=>m instanceof A?u.facet(m)===f.facet(m):m instanceof Ge?u.field(m,!1)==f.field(m,!1):!0)||(l?Fr(d=i(f),g,s):s(d=i(f),g)))return f.values[o]=g,0}else d=i(f);return f.values[o]=d,1}}}get extension(){return this}}function Fr(n,e,t){if(n.length!=e.length)return!1;for(let i=0;i<n.length;i++)if(!t(n[i],e[i]))return!1;return!0}function ds(n,e){let t=!1;for(let i of e)oi(n,i)&1&&(t=!0);return t}function zh(n,e,t){let i=t.map(a=>n[a.id]),s=t.map(a=>a.type),r=i.filter(a=>!(a&1)),o=n[e.id]>>1;function l(a){let h=[];for(let c=0;c<i.length;c++){let f=ln(a,i[c]);if(s[c]==2)for(let u of f)h.push(u);else h.push(f)}return e.combine(h)}return{create(a){for(let h of i)oi(a,h);return a.values[o]=l(a),1},update(a,h){if(!ds(a,r))return 0;let c=l(a);return e.compare(c,a.values[o])?0:(a.values[o]=c,1)},reconfigure(a,h){let c=ds(a,i),f=h.config.facets[e.id],u=h.facet(e);if(f&&!c&&ir(t,f))return a.values[o]=u,0;let d=l(a);return e.compare(d,u)?(a.values[o]=u,0):(a.values[o]=d,1)}}}const Li=A.define({static:!0});class Ge{constructor(e,t,i,s,r){this.id=e,this.createF=t,this.updateF=i,this.compareF=s,this.spec=r,this.provides=void 0}static define(e){let t=new Ge(tr++,e.create,e.update,e.compare||((i,s)=>i===s),e);return e.provide&&(t.provides=e.provide(t)),t}create(e){let t=e.facet(Li).find(i=>i.field==this);return((t==null?void 0:t.create)||this.createF)(e)}slot(e){let t=e[this.id]>>1;return{create:i=>(i.values[t]=this.create(i),1),update:(i,s)=>{let r=i.values[t],o=this.updateF(r,s);return this.compareF(r,o)?0:(i.values[t]=o,1)},reconfigure:(i,s)=>{let r=i.facet(Li),o=s.facet(Li),l;return(l=r.find(a=>a.field==this))&&l!=o.find(a=>a.field==this)?(i.values[t]=l.create(i),1):s.config.address[this.id]!=null?(i.values[t]=s.field(this),0):(i.values[t]=this.create(i),1)}}}init(e){return[this,Li.of({field:this,create:e})]}get extension(){return this}}const mt={lowest:4,low:3,default:2,high:1,highest:0};function Xt(n){return e=>new cl(e,n)}const vi={highest:Xt(mt.highest),high:Xt(mt.high),default:Xt(mt.default),low:Xt(mt.low),lowest:Xt(mt.lowest)};class cl{constructor(e,t){this.inner=e,this.prec=t}get extension(){return this}}class Mn{of(e){return new ps(this,e)}reconfigure(e){return Mn.reconfigure.of({compartment:this,extension:e})}get(e){return e.config.compartments.get(this)}}class ps{constructor(e,t){this.compartment=e,this.inner=t}get extension(){return this}}class on{constructor(e,t,i,s,r,o){for(this.base=e,this.compartments=t,this.dynamicSlots=i,this.address=s,this.staticValues=r,this.facets=o,this.statusTemplate=[];this.statusTemplate.length<i.length;)this.statusTemplate.push(0)}staticFacet(e){let t=this.address[e.id];return t==null?e.default:this.staticValues[t>>1]}static resolve(e,t,i){let s=[],r=Object.create(null),o=new Map;for(let u of qh(e,t,o))u instanceof Ge?s.push(u):(r[u.facet.id]||(r[u.facet.id]=[])).push(u);let l=Object.create(null),a=[],h=[];for(let u of s)l[u.id]=h.length<<1,h.push(d=>u.slot(d));let c=i==null?void 0:i.config.facets;for(let u in r){let d=r[u],p=d[0].facet,g=c&&c[u]||[];if(d.every(m=>m.type==0))if(l[p.id]=a.length<<1|1,ir(g,d))a.push(i.facet(p));else{let m=p.combine(d.map(y=>y.value));a.push(i&&p.compare(m,i.facet(p))?i.facet(p):m)}else{for(let m of d)m.type==0?(l[m.id]=a.length<<1|1,a.push(m.value)):(l[m.id]=h.length<<1,h.push(y=>m.dynamicSlot(y)));l[p.id]=h.length<<1,h.push(m=>zh(m,p,d))}}let f=h.map(u=>u(l));return new on(e,o,f,l,a,r)}}function qh(n,e,t){let i=[[],[],[],[],[]],s=new Map;function r(o,l){let a=s.get(o);if(a!=null){if(a<=l)return;let h=i[a].indexOf(o);h>-1&&i[a].splice(h,1),o instanceof ps&&t.delete(o.compartment)}if(s.set(o,l),Array.isArray(o))for(let h of o)r(h,l);else if(o instanceof ps){if(t.has(o.compartment))throw new RangeError("Duplicate use of compartment in extensions");let h=e.get(o.compartment)||o.inner;t.set(o.compartment,h),r(h,l)}else if(o instanceof cl)r(o.inner,o.prec);else if(o instanceof Ge)i[l].push(o),o.provides&&r(o.provides,l);else if(o instanceof Xi)i[l].push(o),o.facet.extensions&&r(o.facet.extensions,mt.default);else{let h=o.extension;if(!h)throw new Error(`Unrecognized extension value in extension set (${o}).`);if(h==o)throw new Error(`Unrecognized extension value in extension set (${o}). This sometimes happens because multiple instances of @codemirror/state are loaded, breaking instanceof checks.`);r(h,l)}}return r(n,mt.default),i.reduce((o,l)=>o.concat(l))}function oi(n,e){if(e&1)return 2;let t=e>>1,i=n.status[t];if(i==4)throw new Error("Cyclic dependency between fields and/or facets");if(i&2)return i;n.status[t]=4;let s=n.computeSlot(n,n.config.dynamicSlots[t]);return n.status[t]=2|s}function ln(n,e){return e&1?n.config.staticValues[e>>1]:n.values[e>>1]}const fl=A.define(),gs=A.define({combine:n=>n.some(e=>e),static:!0}),ul=A.define({combine:n=>n.length?n[0]:void 0,static:!0}),dl=A.define(),pl=A.define(),gl=A.define(),ml=A.define({combine:n=>n.length?n[0]:!1});class ft{constructor(e,t){this.type=e,this.value=t}static define(){return new Kh}}class Kh{of(e){return new ft(this,e)}}class $h{constructor(e){this.map=e}of(e){return new K(this,e)}}class K{constructor(e,t){this.type=e,this.value=t}map(e){let t=this.type.map(this.value,e);return t===void 0?void 0:t==this.value?this:new K(this.type,t)}is(e){return this.type==e}static define(e={}){return new $h(e.map||(t=>t))}static mapEffects(e,t){if(!e.length)return e;let i=[];for(let s of e){let r=s.map(t);r&&i.push(r)}return i}}K.reconfigure=K.define();K.appendConfig=K.define();class Q{constructor(e,t,i,s,r,o){this.startState=e,this.changes=t,this.selection=i,this.effects=s,this.annotations=r,this.scrollIntoView=o,this._doc=null,this._state=null,i&&hl(i,t.newLength),r.some(l=>l.type==Q.time)||(this.annotations=r.concat(Q.time.of(Date.now())))}static create(e,t,i,s,r,o){return new Q(e,t,i,s,r,o)}get newDoc(){return this._doc||(this._doc=this.changes.apply(this.startState.doc))}get newSelection(){return this.selection||this.startState.selection.map(this.changes)}get state(){return this._state||this.startState.applyTransaction(this),this._state}annotation(e){for(let t of this.annotations)if(t.type==e)return t.value}get docChanged(){return!this.changes.empty}get reconfigured(){return this.startState.config!=this.state.config}isUserEvent(e){let t=this.annotation(Q.userEvent);return!!(t&&(t==e||t.length>e.length&&t.slice(0,e.length)==e&&t[e.length]=="."))}}Q.time=ft.define();Q.userEvent=ft.define();Q.addToHistory=ft.define();Q.remote=ft.define();function jh(n,e){let t=[];for(let i=0,s=0;;){let r,o;if(i<n.length&&(s==e.length||e[s]>=n[i]))r=n[i++],o=n[i++];else if(s<e.length)r=e[s++],o=e[s++];else return t;!t.length||t[t.length-1]<r?t.push(r,o):t[t.length-1]<o&&(t[t.length-1]=o)}}function yl(n,e,t){var i;let s,r,o;return t?(s=e.changes,r=X.empty(e.changes.length),o=n.changes.compose(e.changes)):(s=e.changes.map(n.changes),r=n.changes.mapDesc(e.changes,!0),o=n.changes.compose(s)),{changes:o,selection:e.selection?e.selection.map(r):(i=n.selection)===null||i===void 0?void 0:i.map(s),effects:K.mapEffects(n.effects,s).concat(K.mapEffects(e.effects,r)),annotations:n.annotations.length?n.annotations.concat(e.annotations):e.annotations,scrollIntoView:n.scrollIntoView||e.scrollIntoView}}function ms(n,e,t){let i=e.selection,s=Pt(e.annotations);return e.userEvent&&(s=s.concat(Q.userEvent.of(e.userEvent))),{changes:e.changes instanceof X?e.changes:X.of(e.changes||[],t,n.facet(ul)),selection:i&&(i instanceof b?i:b.single(i.anchor,i.head)),effects:Pt(e.effects),annotations:s,scrollIntoView:!!e.scrollIntoView}}function bl(n,e,t){let i=ms(n,e.length?e[0]:{},n.doc.length);e.length&&e[0].filter===!1&&(t=!1);for(let r=1;r<e.length;r++){e[r].filter===!1&&(t=!1);let o=!!e[r].sequential;i=yl(i,ms(n,e[r],o?i.changes.newLength:n.doc.length),o)}let s=Q.create(n,i.changes,i.selection,i.effects,i.annotations,i.scrollIntoView);return _h(t?Uh(s):s)}function Uh(n){let e=n.startState,t=!0;for(let s of e.facet(dl)){let r=s(n);if(r===!1){t=!1;break}Array.isArray(r)&&(t=t===!0?r:jh(t,r))}if(t!==!0){let s,r;if(t===!1)r=n.changes.invertedDesc,s=X.empty(e.doc.length);else{let o=n.changes.filter(t);s=o.changes,r=o.filtered.mapDesc(o.changes).invertedDesc}n=Q.create(e,s,n.selection&&n.selection.map(r),K.mapEffects(n.effects,r),n.annotations,n.scrollIntoView)}let i=e.facet(pl);for(let s=i.length-1;s>=0;s--){let r=i[s](n);r instanceof Q?n=r:Array.isArray(r)&&r.length==1&&r[0]instanceof Q?n=r[0]:n=bl(e,Pt(r),!1)}return n}function _h(n){let e=n.startState,t=e.facet(gl),i=n;for(let s=t.length-1;s>=0;s--){let r=t[s](n);r&&Object.keys(r).length&&(i=yl(i,ms(e,r,n.changes.newLength),!0))}return i==n?n:Q.create(e,n.changes,n.selection,i.effects,i.annotations,i.scrollIntoView)}const Gh=[];function Pt(n){return n==null?Gh:Array.isArray(n)?n:[n]}var se=function(n){return n[n.Word=0]="Word",n[n.Space=1]="Space",n[n.Other=2]="Other",n}(se||(se={}));const Jh=/[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;let ys;try{ys=new RegExp("[\\p{Alphabetic}\\p{Number}_]","u")}catch{}function Yh(n){if(ys)return ys.test(n);for(let e=0;e<n.length;e++){let t=n[e];if(/\w/.test(t)||t>""&&(t.toUpperCase()!=t.toLowerCase()||Jh.test(t)))return!0}return!1}function Xh(n){return e=>{if(!/\S/.test(e))return se.Space;if(Yh(e))return se.Word;for(let t=0;t<n.length;t++)if(e.indexOf(n[t])>-1)return se.Word;return se.Other}}class N{constructor(e,t,i,s,r,o){this.config=e,this.doc=t,this.selection=i,this.values=s,this.status=e.statusTemplate.slice(),this.computeSlot=r,o&&(o._state=this);for(let l=0;l<this.config.dynamicSlots.length;l++)oi(this,l<<1);this.computeSlot=null}field(e,t=!0){let i=this.config.address[e.id];if(i==null){if(t)throw new RangeError("Field is not present in this state");return}return oi(this,i),ln(this,i)}update(...e){return bl(this,e,!0)}applyTransaction(e){let t=this.config,{base:i,compartments:s}=t;for(let l of e.effects)l.is(Mn.reconfigure)?(t&&(s=new Map,t.compartments.forEach((a,h)=>s.set(h,a)),t=null),s.set(l.value.compartment,l.value.extension)):l.is(K.reconfigure)?(t=null,i=l.value):l.is(K.appendConfig)&&(t=null,i=Pt(i).concat(l.value));let r;t?r=e.startState.values.slice():(t=on.resolve(i,s,this),r=new N(t,this.doc,this.selection,t.dynamicSlots.map(()=>null),(a,h)=>h.reconfigure(a,this),null).values);let o=e.startState.facet(gs)?e.newSelection:e.newSelection.asSingle();new N(t,e.newDoc,o,r,(l,a)=>a.update(l,e),e)}replaceSelection(e){return typeof e=="string"&&(e=this.toText(e)),this.changeByRange(t=>({changes:{from:t.from,to:t.to,insert:e},range:b.cursor(t.from+e.length)}))}changeByRange(e){let t=this.selection,i=e(t.ranges[0]),s=this.changes(i.changes),r=[i.range],o=Pt(i.effects);for(let l=1;l<t.ranges.length;l++){let a=e(t.ranges[l]),h=this.changes(a.changes),c=h.map(s);for(let u=0;u<l;u++)r[u]=r[u].map(c);let f=s.mapDesc(h,!0);r.push(a.range.map(f)),s=s.compose(c),o=K.mapEffects(o,c).concat(K.mapEffects(Pt(a.effects),f))}return{changes:s,selection:b.create(r,t.mainIndex),effects:o}}changes(e=[]){return e instanceof X?e:X.of(e,this.doc.length,this.facet(N.lineSeparator))}toText(e){return W.of(e.split(this.facet(N.lineSeparator)||cs))}sliceDoc(e=0,t=this.doc.length){return this.doc.sliceString(e,t,this.lineBreak)}facet(e){let t=this.config.address[e.id];return t==null?e.default:(oi(this,t),ln(this,t))}toJSON(e){let t={doc:this.sliceDoc(),selection:this.selection.toJSON()};if(e)for(let i in e){let s=e[i];s instanceof Ge&&this.config.address[s.id]!=null&&(t[i]=s.spec.toJSON(this.field(e[i]),this))}return t}static fromJSON(e,t={},i){if(!e||typeof e.doc!="string")throw new RangeError("Invalid JSON representation for EditorState");let s=[];if(i){for(let r in i)if(Object.prototype.hasOwnProperty.call(e,r)){let o=i[r],l=e[r];s.push(o.init(a=>o.spec.fromJSON(l,a)))}}return N.create({doc:e.doc,selection:b.fromJSON(e.selection),extensions:t.extensions?s.concat([t.extensions]):s})}static create(e={}){let t=on.resolve(e.extensions||[],new Map),i=e.doc instanceof W?e.doc:W.of((e.doc||"").split(t.staticFacet(N.lineSeparator)||cs)),s=e.selection?e.selection instanceof b?e.selection:b.single(e.selection.anchor,e.selection.head):b.single(0);return hl(s,i.length),t.staticFacet(gs)||(s=s.asSingle()),new N(t,i,s,t.dynamicSlots.map(()=>null),(r,o)=>o.create(r),null)}get tabSize(){return this.facet(N.tabSize)}get lineBreak(){return this.facet(N.lineSeparator)||`
|