From ef951c971db0e8ad87cc747eade69ac8c1af80d1 Mon Sep 17 00:00:00 2001
From: Margaret <62753112+meg-1@users.noreply.github.com>
Date: Sat, 25 Mar 2023 15:46:59 +0200
Subject: [PATCH 1/3] adding a contacts web application example
---
.../contacts_web_application/contacts.js | 57 +
.../contacts_web_application/contacts.py | 42 +
.../contacts_web_application/index.html | 136 +
.../contacts_web_application/index.md | 10 +
.../contacts_web_application/py_config.toml | 4 +
.../contacts_web_application/pyscript.js | 27253 ++++++++++++++++
.../contacts_web_application/styles.css | 147 +
7 files changed, 27649 insertions(+)
create mode 100644 src/psc/gallery/examples/contacts_web_application/contacts.js
create mode 100644 src/psc/gallery/examples/contacts_web_application/contacts.py
create mode 100644 src/psc/gallery/examples/contacts_web_application/index.html
create mode 100644 src/psc/gallery/examples/contacts_web_application/index.md
create mode 100644 src/psc/gallery/examples/contacts_web_application/py_config.toml
create mode 100644 src/psc/gallery/examples/contacts_web_application/pyscript.js
create mode 100644 src/psc/gallery/examples/contacts_web_application/styles.css
diff --git a/src/psc/gallery/examples/contacts_web_application/contacts.js b/src/psc/gallery/examples/contacts_web_application/contacts.js
new file mode 100644
index 0000000..4442cbe
--- /dev/null
+++ b/src/psc/gallery/examples/contacts_web_application/contacts.js
@@ -0,0 +1,57 @@
+document.getElementById("search_area").addEventListener("input", function (user_input) {
+ const contacts_match_name_list = pyscript.runtime.globals.get('search_by_value') || "empty";
+ if (user_input.target.value != "") {
+ const search_result = contacts_match_name_list(user_input.target.value);
+ } else {
+ clear_search_area();
+ }
+
+ return user_input.target.value;
+});
+
+function clear_search_area() {
+ const output_grid = document.getElementById("found_contacts_list");
+ /* this function is for the search OUTPUT */
+ output_grid.innerHTML = "";
+}
+
+function add_found_contact(contact_name, contact_number) {
+ const output_grid = document.getElementById("found_contacts_list");
+ const contact_card = document.getElementById("contact_card_template").cloneNode(true);
+ contact_card.childNodes.forEach(function (child, number) {
+ if (child.className != undefined &&
+ child.className.includes("name_template")) {
+ child.innerText = contact_name;
+ }
+
+ if (child.className != undefined &&
+ child.className.includes("number_template")) {
+ child.innerText = contact_number;
+ }
+ });
+
+ contact_card.style = "visibility: visible;";
+ output_grid.appendChild(contact_card);
+ }
+
+ function add_to_list(contact_number, contact_name) {
+ let grid = document.getElementById("contacts_list_grid");
+ let contacts_card = document.createElement("div");
+ contacts_card.className = "d-flex justify-content-center w-100 row contact_card";
+ let name = document.createElement("span");
+ name.className = "d-flex justify-content-center w-50 m-auto";
+ contacts_card.style = "border: 1px solid black";
+ //vertical-align: middle;
+ //align-middle
+ let num = document.createElement("span");
+ num.className = "d-flex justify-content-center m-auto";
+ num.innerHTML = contact_number;
+ name.innerHTML = contact_name;
+ //contacts_card.style = "background-color: green; width: 100%; height: 100px;";
+ //contacts_card.id = "contacts_list_grid"
+ //contacts_card.innerHTML = contact_number + " " + contact_name;
+ contacts_card.appendChild(name);
+ contacts_card.appendChild(num);
+ grid.appendChild(contacts_card);
+ }
+//# sourceMappingURL=pyscript.js.map
\ No newline at end of file
diff --git a/src/psc/gallery/examples/contacts_web_application/contacts.py b/src/psc/gallery/examples/contacts_web_application/contacts.py
new file mode 100644
index 0000000..9971296
--- /dev/null
+++ b/src/psc/gallery/examples/contacts_web_application/contacts.py
@@ -0,0 +1,42 @@
+""" Contacts Web Application """
+from js import add_to_list, clear_search_area, add_found_contact
+import re
+contacts_list = {}
+output = Element("output")
+
+search_res = []
+
+def search_by_value(query):
+ global search_res
+ search_res = []
+ clear_search_area()
+ for number, name in contacts_list.items():
+ temp = re.findall(query, name)
+ if temp:
+ contact = {"contact_name": name, "contact_number": number}
+ add_found_contact(name, number)
+ search_res.append(contact)
+ return search_res
+
+def contact_book(*args, **kwargs):
+ """Contact book function."""
+ # Signal that PyScript is alive by setting the ``Save Contact``
+ # disabled attribute
+ save_button = Element("save")
+ # Now get the various inputs
+ contact_name = Element("contact_name").value
+ phone_number = Element("phone_number").value
+
+ if phone_number not in contacts_list.keys():
+ contacts_list[phone_number] = contact_name
+ last_val = list(contacts_list.keys())[-1]
+ add_to_list(str(last_val), str(contacts_list[last_val]))
+
+
+def setup():
+ """When Pyodide starts up, enable the Save button."""
+ save_button = Element("save") # noqa
+ save_button.element.removeAttribute("disabled")
+ output = Element("output")
+
+setup()
\ No newline at end of file
diff --git a/src/psc/gallery/examples/contacts_web_application/index.html b/src/psc/gallery/examples/contacts_web_application/index.html
new file mode 100644
index 0000000..5e3928c
--- /dev/null
+++ b/src/psc/gallery/examples/contacts_web_application/index.html
@@ -0,0 +1,136 @@
+
+
+
+
+
+ Contact Book
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Welcome to the "PyScript Contacts Web Application"
+ "how does it work?"
+
+
enter a contact name and number in the form area
+
click the "save contact" button
+
you will see the contact appear in the "name" and "number" area
+
enter as many contacts as you wish
+
+ after adding one or more contacts, you can enter a query in the "enter your query"
+ area. this area is used as a search box. you can enter contact names, and easily find
+ the contacts name and number combined!
+
+
Have fun!
+
+
+
+
+
+
+
+
Add Your Contacts
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Search Box
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Contacts List
+
+
name
+
number
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/psc/gallery/examples/contacts_web_application/index.md b/src/psc/gallery/examples/contacts_web_application/index.md
new file mode 100644
index 0000000..78039d5
--- /dev/null
+++ b/src/psc/gallery/examples/contacts_web_application/index.md
@@ -0,0 +1,10 @@
+---
+title: PyScript Contacts Web Application
+subtitle: Enter some contacts, get some contacts.
+author: meg-1
+linked_files:
+ - contacts.py
+ - styles.css
+---
+The *body* description.
+this project is intended to show interaction between Pyscript and JavaScript
\ No newline at end of file
diff --git a/src/psc/gallery/examples/contacts_web_application/py_config.toml b/src/psc/gallery/examples/contacts_web_application/py_config.toml
new file mode 100644
index 0000000..c83c741
--- /dev/null
+++ b/src/psc/gallery/examples/contacts_web_application/py_config.toml
@@ -0,0 +1,4 @@
+autoclose_loader = true
+
+[[runtimes]]
+src = "https://cdn.jsdelivr.net/pyodide/v0.21.3/full/pyodide.js"
\ No newline at end of file
diff --git a/src/psc/gallery/examples/contacts_web_application/pyscript.js b/src/psc/gallery/examples/contacts_web_application/pyscript.js
new file mode 100644
index 0000000..f5ea08b
--- /dev/null
+++ b/src/psc/gallery/examples/contacts_web_application/pyscript.js
@@ -0,0 +1,27253 @@
+var pyscript = (function (exports) {
+ 'use strict';
+
+ /* eslint-disable */
+ !(function (r) {
+ if ('object' == typeof exports && 'undefined' != typeof module) module.exports = r();
+ else if ('function' == typeof define && define.amd) define([], r);
+ else {
+ ('undefined' != typeof window
+ ? window
+ : 'undefined' != typeof global
+ ? global
+ : 'undefined' != typeof self
+ ? self
+ : this
+ ).toml = r();
+ }
+ })(function () {
+ return (function r(t, e, n) {
+ function u(i, a) {
+ if (!e[i]) {
+ if (!t[i]) {
+ var c = 'function' == typeof require && require;
+ if (!a && c) return c(i, !0);
+ if (o) return o(i, !0);
+ var f = new Error("Cannot find module '" + i + "'");
+ throw ((f.code = 'MODULE_NOT_FOUND'), f);
+ }
+ var s = (e[i] = {
+ exports: {},
+ });
+ t[i][0].call(
+ s.exports,
+ function (r) {
+ var e = t[i][1][r];
+ return u(e || r);
+ },
+ s,
+ s.exports,
+ r,
+ t,
+ e,
+ n,
+ );
+ }
+ return e[i].exports;
+ }
+ for (var o = 'function' == typeof require && require, i = 0; i < n.length; i++) u(n[i]);
+ return u;
+ })(
+ {
+ 1: [
+ function (r, t, e) {
+ t.exports = (function () {
+
+ function r(t, e, n, u) {
+ (this.message = t),
+ (this.expected = e),
+ (this.found = n),
+ (this.location = u),
+ (this.name = 'SyntaxError'),
+ 'function' == typeof Error.captureStackTrace && Error.captureStackTrace(this, r);
+ }
+ return (
+ (function (r, t) {
+ function e() {
+ this.constructor = r;
+ }
+ (e.prototype = t.prototype), (r.prototype = new e());
+ })(r, Error),
+ (r.buildMessage = function (r, t) {
+ function e(r) {
+ return r.charCodeAt(0).toString(16).toUpperCase();
+ }
+
+ function n(r) {
+ return r
+ .replace(/\\/g, '\\\\')
+ .replace(/"/g, '\\"')
+ .replace(/\0/g, '\\0')
+ .replace(/\t/g, '\\t')
+ .replace(/\n/g, '\\n')
+ .replace(/\r/g, '\\r')
+ .replace(/[\x00-\x0F]/g, function (r) {
+ return '\\x0' + e(r);
+ })
+ .replace(/[\x10-\x1F\x7F-\x9F]/g, function (r) {
+ return '\\x' + e(r);
+ });
+ }
+
+ function u(r) {
+ return r
+ .replace(/\\/g, '\\\\')
+ .replace(/\]/g, '\\]')
+ .replace(/\^/g, '\\^')
+ .replace(/-/g, '\\-')
+ .replace(/\0/g, '\\0')
+ .replace(/\t/g, '\\t')
+ .replace(/\n/g, '\\n')
+ .replace(/\r/g, '\\r')
+ .replace(/[\x00-\x0F]/g, function (r) {
+ return '\\x0' + e(r);
+ })
+ .replace(/[\x10-\x1F\x7F-\x9F]/g, function (r) {
+ return '\\x' + e(r);
+ });
+ }
+
+ function o(r) {
+ return i[r.type](r);
+ }
+ var i = {
+ literal: function (r) {
+ return '"' + n(r.text) + '"';
+ },
+ class: function (r) {
+ var t,
+ e = '';
+ for (t = 0; t < r.parts.length; t++)
+ e +=
+ r.parts[t] instanceof Array
+ ? u(r.parts[t][0]) + '-' + u(r.parts[t][1])
+ : u(r.parts[t]);
+ return '[' + (r.inverted ? '^' : '') + e + ']';
+ },
+ any: function (r) {
+ return 'any character';
+ },
+ end: function (r) {
+ return 'end of input';
+ },
+ other: function (r) {
+ return r.description;
+ },
+ };
+ return (
+ 'Expected ' +
+ (function (r) {
+ var t,
+ e,
+ n = new Array(r.length);
+ for (t = 0; t < r.length; t++) n[t] = o(r[t]);
+ if ((n.sort(), n.length > 0)) {
+ for (t = 1, e = 1; t < n.length; t++)
+ n[t - 1] !== n[t] && ((n[e] = n[t]), e++);
+ n.length = e;
+ }
+ switch (n.length) {
+ case 1:
+ return n[0];
+ case 2:
+ return n[0] + ' or ' + n[1];
+ default:
+ return n.slice(0, -1).join(', ') + ', or ' + n[n.length - 1];
+ }
+ })(r) +
+ ' but ' +
+ (function (r) {
+ return r ? '"' + n(r) + '"' : 'end of input';
+ })(t) +
+ ' found.'
+ );
+ }),
+ {
+ SyntaxError: r,
+ parse: function (t, e) {
+ function n() {
+ return t.substring(Me, _e);
+ }
+
+ function u(r, t) {
+ throw ((t = void 0 !== t ? t : f(Me, _e)), l(r, t));
+ }
+
+ function o(r, t) {
+ return {
+ type: 'literal',
+ text: r,
+ ignoreCase: t,
+ };
+ }
+
+ function i(r, t, e) {
+ return {
+ type: 'class',
+ parts: r,
+ inverted: t,
+ ignoreCase: e,
+ };
+ }
+
+ function a(r) {
+ return {
+ type: 'other',
+ description: r,
+ };
+ }
+
+ function c(r) {
+ var e,
+ n = Ne[r];
+ if (n) return n;
+ for (e = r - 1; !Ne[e]; ) e--;
+ for (
+ n = {
+ line: (n = Ne[e]).line,
+ column: n.column,
+ };
+ e < r;
+
+ )
+ 10 === t.charCodeAt(e) ? (n.line++, (n.column = 1)) : n.column++, e++;
+ return (Ne[r] = n), n;
+ }
+
+ function f(r, t) {
+ var e = c(r),
+ n = c(t);
+ return {
+ start: {
+ offset: r,
+ line: e.line,
+ column: e.column,
+ },
+ end: {
+ offset: t,
+ line: n.line,
+ column: n.column,
+ },
+ };
+ }
+
+ function s(r) {
+ _e < He || (_e > He && ((He = _e), (Ue = [])), Ue.push(r));
+ }
+
+ function l(t, e) {
+ return new r(t, null, null, e);
+ }
+
+ function h(t, e, n) {
+ return new r(r.buildMessage(t, e), t, e, n);
+ }
+
+ function p() {
+ var r, t, e, n, u, o, i, a;
+ for (
+ r = _e, t = [], (e = g()) === mr && (e = d()) === mr && (e = A());
+ e !== mr;
+
+ )
+ t.push(e), (e = g()) === mr && (e = d()) === mr && (e = A());
+ if (t !== mr) {
+ if (((e = _e), (n = v()) !== mr)) {
+ for (u = [], (o = g()) === mr && (o = A()); o !== mr; )
+ u.push(o), (o = g()) === mr && (o = A());
+ u !== mr
+ ? ((o = _e),
+ (i = d()) !== mr && (a = p()) !== mr
+ ? (o = i = [i, a])
+ : ((_e = o), (o = mr)),
+ o === mr && (o = null),
+ o !== mr ? (e = n = [n, u, o]) : ((_e = e), (e = mr)))
+ : ((_e = e), (e = mr));
+ } else (_e = e), (e = mr);
+ e === mr && (e = null),
+ e !== mr ? ((Me = r), (r = t = wr())) : ((_e = r), (r = mr));
+ } else (_e = r), (r = mr);
+ return r;
+ }
+
+ function v() {
+ var r, t;
+ return (
+ (r = _e),
+ (t = Cr()) !== mr && ((Me = r), (t = Fr(t))),
+ (r = t) === mr &&
+ ((r = _e),
+ (t = yr()) !== mr && ((Me = r), (t = Er(t))),
+ (r = t) === mr &&
+ ((r = _e), (t = C()) !== mr && ((Me = r), (t = Tr(t))), (r = t))),
+ r
+ );
+ }
+
+ function d() {
+ var r;
+ return (
+ Ze++,
+ 10 === t.charCodeAt(_e) ? ((r = Or), _e++) : ((r = mr), 0 === Ze && s(jr)),
+ r === mr &&
+ (t.substr(_e, 2) === _r
+ ? ((r = _r), (_e += 2))
+ : ((r = mr), 0 === Ze && s(Mr))),
+ Ze--,
+ r === mr && 0 === Ze && s(Dr),
+ r
+ );
+ }
+
+ function g() {
+ var r;
+ return (
+ Ze++,
+ Hr.test(t.charAt(_e))
+ ? ((r = t.charAt(_e)), _e++)
+ : ((r = mr), 0 === Ze && s(Ur)),
+ Ze--,
+ r === mr && 0 === Ze && s(Nr),
+ r
+ );
+ }
+
+ function A() {
+ var r, e, n, u, o, i;
+ if (
+ (Ze++,
+ (r = _e),
+ 35 === t.charCodeAt(_e) ? ((e = Ir), _e++) : ((e = mr), 0 === Ze && s(Rr)),
+ e !== mr)
+ ) {
+ for (
+ n = [],
+ u = _e,
+ o = _e,
+ Ze++,
+ i = d(),
+ Ze--,
+ i === mr ? (o = void 0) : ((_e = o), (o = mr)),
+ o !== mr
+ ? (t.length > _e
+ ? ((i = t.charAt(_e)), _e++)
+ : ((i = mr), 0 === Ze && s(qr)),
+ i !== mr ? (u = o = [o, i]) : ((_e = u), (u = mr)))
+ : ((_e = u), (u = mr));
+ u !== mr;
+
+ )
+ n.push(u),
+ (u = _e),
+ (o = _e),
+ Ze++,
+ (i = d()),
+ Ze--,
+ i === mr ? (o = void 0) : ((_e = o), (o = mr)),
+ o !== mr
+ ? (t.length > _e
+ ? ((i = t.charAt(_e)), _e++)
+ : ((i = mr), 0 === Ze && s(qr)),
+ i !== mr ? (u = o = [o, i]) : ((_e = u), (u = mr)))
+ : ((_e = u), (u = mr));
+ n !== mr ? (r = e = [e, n]) : ((_e = r), (r = mr));
+ } else (_e = r), (r = mr);
+ return Ze--, r === mr && ((e = mr), 0 === Ze && s(Zr)), r;
+ }
+
+ function C() {
+ var r, e, n, u, o, i;
+ if (((r = _e), (e = y()) !== mr)) {
+ for (n = [], u = g(); u !== mr; ) n.push(u), (u = g());
+ if (n !== mr)
+ if (
+ (61 === t.charCodeAt(_e)
+ ? ((u = Qr), _e++)
+ : ((u = mr), 0 === Ze && s(Yr)),
+ u !== mr)
+ ) {
+ for (o = [], i = g(); i !== mr; ) o.push(i), (i = g());
+ o !== mr && (i = T()) !== mr
+ ? ((Me = r), (r = e = kr(e, i)))
+ : ((_e = r), (r = mr));
+ } else (_e = r), (r = mr);
+ else (_e = r), (r = mr);
+ } else (_e = r), (r = mr);
+ return r;
+ }
+
+ function y() {
+ var r;
+ return (r = b()) === mr && (r = x()), r;
+ }
+
+ function b() {
+ var r, t, e;
+ if (((r = _e), (t = []), (e = m()) !== mr))
+ for (; e !== mr; ) t.push(e), (e = m());
+ else t = mr;
+ return t !== mr && ((Me = r), (t = zr())), (r = t);
+ }
+
+ function m() {
+ var r;
+ return (
+ Ze++,
+ Jr.test(t.charAt(_e))
+ ? ((r = t.charAt(_e)), _e++)
+ : ((r = mr), 0 === Ze && s(Pr)),
+ Ze--,
+ r === mr && 0 === Ze && s(Br),
+ r
+ );
+ }
+
+ function x() {
+ var r, t, e;
+ if (((r = _e), S() !== mr)) {
+ if (((t = []), (e = j()) !== mr)) for (; e !== mr; ) t.push(e), (e = j());
+ else t = mr;
+ t !== mr && (e = S()) !== mr
+ ? ((Me = r), (r = Lr(t)))
+ : ((_e = r), (r = mr));
+ } else (_e = r), (r = mr);
+ return r;
+ }
+
+ function S() {
+ var r;
+ return (
+ Ze++,
+ 34 === t.charCodeAt(_e) ? ((r = Wr), _e++) : ((r = mr), 0 === Ze && s(Gr)),
+ Ze--,
+ r === mr && 0 === Ze && s(Vr),
+ r
+ );
+ }
+
+ function w() {
+ var r;
+ return (
+ Ze++,
+ 39 === t.charCodeAt(_e) ? ((r = Xr), _e++) : ((r = mr), 0 === Ze && s($r)),
+ Ze--,
+ r === mr && 0 === Ze && s(Kr),
+ r
+ );
+ }
+
+ function F() {
+ var r;
+ return (
+ Ze++,
+ t.substr(_e, 3) === tt
+ ? ((r = tt), (_e += 3))
+ : ((r = mr), 0 === Ze && s(et)),
+ Ze--,
+ r === mr && 0 === Ze && s(rt),
+ r
+ );
+ }
+
+ function E() {
+ var r;
+ return (
+ Ze++,
+ t.substr(_e, 3) === ut
+ ? ((r = ut), (_e += 3))
+ : ((r = mr), 0 === Ze && s(ot)),
+ Ze--,
+ r === mr && 0 === Ze && s(nt),
+ r
+ );
+ }
+
+ function T() {
+ var r;
+ return (
+ (r = D()) === mr &&
+ (r = L()) === mr &&
+ (r = er()) === mr &&
+ (r = V()) === mr &&
+ (r = K()) === mr &&
+ (r = vr()) === mr &&
+ (r = Ar()),
+ r
+ );
+ }
+
+ function D() {
+ var r;
+ return (r = Q()) === mr && (r = O()) === mr && (r = B()) === mr && (r = R()), r;
+ }
+
+ function O() {
+ var r, t, e;
+ if (((r = _e), S() !== mr)) {
+ for (t = [], e = j(); e !== mr; ) t.push(e), (e = j());
+ t !== mr && (e = S()) !== mr
+ ? ((Me = r), (r = it(t)))
+ : ((_e = r), (r = mr));
+ } else (_e = r), (r = mr);
+ return r;
+ }
+
+ function j() {
+ var r;
+ return (r = _()) === mr && (r = M()), r;
+ }
+
+ function _() {
+ var r, e, n;
+ return (
+ Ze++,
+ (r = _e),
+ (e = _e),
+ Ze++,
+ (n = d()),
+ Ze--,
+ n === mr ? (e = void 0) : ((_e = e), (e = mr)),
+ e !== mr
+ ? (ct.test(t.charAt(_e))
+ ? ((n = t.charAt(_e)), _e++)
+ : ((n = mr), 0 === Ze && s(ft)),
+ n !== mr ? ((Me = r), (r = e = zr())) : ((_e = r), (r = mr)))
+ : ((_e = r), (r = mr)),
+ Ze--,
+ r === mr && ((e = mr), 0 === Ze && s(at)),
+ r
+ );
+ }
+
+ function M() {
+ var r, e, n, u;
+ return (
+ (r = _e),
+ H() !== mr
+ ? ((e = N()) === mr &&
+ (e = S()) === mr &&
+ (e = H()) === mr &&
+ ((e = _e),
+ 117 === t.charCodeAt(_e)
+ ? ((n = st), _e++)
+ : ((n = mr), 0 === Ze && s(lt)),
+ n !== mr && (u = U()) !== mr
+ ? (e = n = [n, u])
+ : ((_e = e), (e = mr)),
+ e === mr &&
+ ((e = _e),
+ 85 === t.charCodeAt(_e)
+ ? ((n = ht), _e++)
+ : ((n = mr), 0 === Ze && s(pt)),
+ n !== mr && (u = Z()) !== mr
+ ? (e = n = [n, u])
+ : ((_e = e), (e = mr)))),
+ e !== mr ? ((Me = r), (r = vt())) : ((_e = r), (r = mr)))
+ : ((_e = r), (r = mr)),
+ r
+ );
+ }
+
+ function N() {
+ var r;
+ return (
+ Ze++,
+ gt.test(t.charAt(_e))
+ ? ((r = t.charAt(_e)), _e++)
+ : ((r = mr), 0 === Ze && s(At)),
+ Ze--,
+ r === mr && 0 === Ze && s(dt),
+ r
+ );
+ }
+
+ function H() {
+ var r;
+ return (
+ Ze++,
+ 92 === t.charCodeAt(_e) ? ((r = yt), _e++) : ((r = mr), 0 === Ze && s(bt)),
+ Ze--,
+ r === mr && 0 === Ze && s(Ct),
+ r
+ );
+ }
+
+ function U() {
+ var r, t, e, n, u;
+ return (
+ Ze++,
+ (r = _e),
+ (t = I()) !== mr && (e = I()) !== mr && (n = I()) !== mr && (u = I()) !== mr
+ ? (r = t = [t, e, n, u])
+ : ((_e = r), (r = mr)),
+ Ze--,
+ r === mr && ((t = mr), 0 === Ze && s(mt)),
+ r
+ );
+ }
+
+ function Z() {
+ var r, t, e, n, u, o, i, a, c;
+ return (
+ Ze++,
+ (r = _e),
+ (t = I()) !== mr &&
+ (e = I()) !== mr &&
+ (n = I()) !== mr &&
+ (u = I()) !== mr &&
+ (o = I()) !== mr &&
+ (i = I()) !== mr &&
+ (a = I()) !== mr &&
+ (c = I()) !== mr
+ ? (r = t = [t, e, n, u, o, i, a, c])
+ : ((_e = r), (r = mr)),
+ Ze--,
+ r === mr && ((t = mr), 0 === Ze && s(xt)),
+ r
+ );
+ }
+
+ function I() {
+ var r;
+ return (
+ St.test(t.charAt(_e))
+ ? ((r = t.charAt(_e)), _e++)
+ : ((r = mr), 0 === Ze && s(wt)),
+ r
+ );
+ }
+
+ function R() {
+ var r, t, e;
+ if (((r = _e), w() !== mr)) {
+ for (t = [], e = q(); e !== mr; ) t.push(e), (e = q());
+ t !== mr && (e = w()) !== mr
+ ? ((Me = r), (r = Ft()))
+ : ((_e = r), (r = mr));
+ } else (_e = r), (r = mr);
+ return r;
+ }
+
+ function q() {
+ var r, e, n;
+ return (
+ Ze++,
+ (r = _e),
+ (e = _e),
+ Ze++,
+ (n = d()),
+ Ze--,
+ n === mr ? (e = void 0) : ((_e = e), (e = mr)),
+ e !== mr
+ ? (Et.test(t.charAt(_e))
+ ? ((n = t.charAt(_e)), _e++)
+ : ((n = mr), 0 === Ze && s(Tt)),
+ n !== mr ? (r = e = [e, n]) : ((_e = r), (r = mr)))
+ : ((_e = r), (r = mr)),
+ Ze--,
+ r === mr && ((e = mr), 0 === Ze && s(at)),
+ r
+ );
+ }
+
+ function Q() {
+ var r, t, e, n;
+ if (((r = _e), F() !== mr))
+ if (((t = d()) === mr && (t = null), t !== mr)) {
+ for (e = [], n = Y(); n !== mr; ) e.push(n), (n = Y());
+ e !== mr && (n = F()) !== mr
+ ? ((Me = r), (r = Dt(e)))
+ : ((_e = r), (r = mr));
+ } else (_e = r), (r = mr);
+ else (_e = r), (r = mr);
+ return r;
+ }
+
+ function Y() {
+ var r;
+ return (
+ (r = k()) === mr &&
+ ((r = _e),
+ H() !== mr && d() !== mr
+ ? ((Me = r), (r = zr()))
+ : ((_e = r), (r = mr)),
+ r === mr && (r = d())),
+ r
+ );
+ }
+
+ function k() {
+ var r, t, e;
+ return (
+ (r = _e),
+ (t = _e),
+ Ze++,
+ (e = F()),
+ Ze--,
+ e === mr ? (t = void 0) : ((_e = t), (t = mr)),
+ t !== mr && (e = z()) !== mr
+ ? ((Me = r), (r = t = zr()))
+ : ((_e = r), (r = mr)),
+ r === mr && (r = M()),
+ r
+ );
+ }
+
+ function z() {
+ var r, e, n;
+ return (
+ Ze++,
+ (r = _e),
+ (e = _e),
+ Ze++,
+ (n = d()),
+ Ze--,
+ n === mr ? (e = void 0) : ((_e = e), (e = mr)),
+ e !== mr
+ ? (Ot.test(t.charAt(_e))
+ ? ((n = t.charAt(_e)), _e++)
+ : ((n = mr), 0 === Ze && s(jt)),
+ n !== mr ? (r = e = [e, n]) : ((_e = r), (r = mr)))
+ : ((_e = r), (r = mr)),
+ Ze--,
+ r === mr && ((e = mr), 0 === Ze && s(at)),
+ r
+ );
+ }
+
+ function B() {
+ var r, t, e, n;
+ if (((r = _e), E() !== mr))
+ if (((t = d()) === mr && (t = null), t !== mr)) {
+ for (e = [], n = J(); n !== mr; ) e.push(n), (n = J());
+ e !== mr && (n = E()) !== mr
+ ? ((Me = r), (r = it(e)))
+ : ((_e = r), (r = mr));
+ } else (_e = r), (r = mr);
+ else (_e = r), (r = mr);
+ return r;
+ }
+
+ function J() {
+ var r, e, n;
+ return (
+ (r = _e),
+ (e = _e),
+ Ze++,
+ t.substr(_e, 3) === ut
+ ? ((n = ut), (_e += 3))
+ : ((n = mr), 0 === Ze && s(ot)),
+ Ze--,
+ n === mr ? (e = void 0) : ((_e = e), (e = mr)),
+ e !== mr && (n = P()) !== mr
+ ? ((Me = r), (r = e = zr()))
+ : ((_e = r), (r = mr)),
+ r === mr && (r = d()),
+ r
+ );
+ }
+
+ function P() {
+ var r, e, n;
+ return (
+ Ze++,
+ (r = _e),
+ (e = _e),
+ Ze++,
+ (n = d()),
+ Ze--,
+ n === mr ? (e = void 0) : ((_e = e), (e = mr)),
+ e !== mr
+ ? (Mt.test(t.charAt(_e))
+ ? ((n = t.charAt(_e)), _e++)
+ : ((n = mr), 0 === Ze && s(Nt)),
+ n !== mr ? (r = e = [e, n]) : ((_e = r), (r = mr)))
+ : ((_e = r), (r = mr)),
+ Ze--,
+ r === mr && ((e = mr), 0 === Ze && s(_t)),
+ r
+ );
+ }
+
+ function L() {
+ var r, e;
+ return (
+ (r = _e),
+ t.substr(_e, 4) === Ht
+ ? ((e = Ht), (_e += 4))
+ : ((e = mr), 0 === Ze && s(Ut)),
+ e !== mr && ((Me = r), (e = Zt())),
+ (r = e) === mr &&
+ ((r = _e),
+ t.substr(_e, 5) === It
+ ? ((e = It), (_e += 5))
+ : ((e = mr), 0 === Ze && s(Rt)),
+ e !== mr && ((Me = r), (e = qt())),
+ (r = e)),
+ r
+ );
+ }
+
+ function V() {
+ var r, t, e, n;
+ return (
+ (r = _e),
+ K() !== mr
+ ? ((t = _e),
+ (e = W()) !== mr
+ ? ((n = G()) === mr && (n = null),
+ n !== mr ? (t = e = [e, n]) : ((_e = t), (t = mr)))
+ : ((_e = t), (t = mr)),
+ t === mr && (t = G()),
+ t !== mr ? ((Me = r), (r = Qt())) : ((_e = r), (r = mr)))
+ : ((_e = r), (r = mr)),
+ r
+ );
+ }
+
+ function W() {
+ var r, e, n, u, o, i, a;
+ if (
+ ((r = _e),
+ 46 === t.charCodeAt(_e) ? ((e = Yt), _e++) : ((e = mr), 0 === Ze && s(kt)),
+ e !== mr)
+ )
+ if ((n = tr()) !== mr) {
+ for (
+ u = [],
+ o = _e,
+ 95 === t.charCodeAt(_e)
+ ? ((i = zt), _e++)
+ : ((i = mr), 0 === Ze && s(Bt)),
+ i === mr && (i = null),
+ i !== mr && (a = tr()) !== mr
+ ? (o = i = [i, a])
+ : ((_e = o), (o = mr));
+ o !== mr;
+
+ )
+ u.push(o),
+ (o = _e),
+ 95 === t.charCodeAt(_e)
+ ? ((i = zt), _e++)
+ : ((i = mr), 0 === Ze && s(Bt)),
+ i === mr && (i = null),
+ i !== mr && (a = tr()) !== mr
+ ? (o = i = [i, a])
+ : ((_e = o), (o = mr));
+ u !== mr ? (r = e = [e, n, u]) : ((_e = r), (r = mr));
+ } else (_e = r), (r = mr);
+ else (_e = r), (r = mr);
+ return r;
+ }
+
+ function G() {
+ var r, e, n;
+ return (
+ (r = _e),
+ 101 === t.charCodeAt(_e) ? ((e = Jt), _e++) : ((e = mr), 0 === Ze && s(Pt)),
+ e === mr &&
+ (69 === t.charCodeAt(_e)
+ ? ((e = Lt), _e++)
+ : ((e = mr), 0 === Ze && s(Vt))),
+ e !== mr && (n = K()) !== mr ? (r = e = [e, n]) : ((_e = r), (r = mr)),
+ r
+ );
+ }
+
+ function K() {
+ var r, t;
+ return (
+ (r = _e),
+ (t = X()) === mr && (t = null),
+ t !== mr && $() !== mr ? ((Me = r), (r = t = Wt())) : ((_e = r), (r = mr)),
+ r
+ );
+ }
+
+ function X() {
+ var r;
+ return (
+ 43 === t.charCodeAt(_e) ? ((r = Gt), _e++) : ((r = mr), 0 === Ze && s(Kt)),
+ r === mr &&
+ (45 === t.charCodeAt(_e)
+ ? ((r = Xt), _e++)
+ : ((r = mr), 0 === Ze && s($t))),
+ r
+ );
+ }
+
+ function $() {
+ var r, e, n, u, o, i;
+ if (((r = _e), (e = rr()) !== mr)) {
+ if (
+ ((n = []),
+ (u = _e),
+ 95 === t.charCodeAt(_e)
+ ? ((o = zt), _e++)
+ : ((o = mr), 0 === Ze && s(Bt)),
+ o === mr && (o = null),
+ o !== mr && (i = tr()) !== mr ? (u = o = [o, i]) : ((_e = u), (u = mr)),
+ u !== mr)
+ )
+ for (; u !== mr; )
+ n.push(u),
+ (u = _e),
+ 95 === t.charCodeAt(_e)
+ ? ((o = zt), _e++)
+ : ((o = mr), 0 === Ze && s(Bt)),
+ o === mr && (o = null),
+ o !== mr && (i = tr()) !== mr
+ ? (u = o = [o, i])
+ : ((_e = u), (u = mr));
+ else n = mr;
+ n !== mr ? (r = e = [e, n]) : ((_e = r), (r = mr));
+ } else (_e = r), (r = mr);
+ return r === mr && (r = tr()), r;
+ }
+
+ function rr() {
+ var r;
+ return (
+ re.test(t.charAt(_e))
+ ? ((r = t.charAt(_e)), _e++)
+ : ((r = mr), 0 === Ze && s(te)),
+ r
+ );
+ }
+
+ function tr() {
+ var r;
+ return (
+ ee.test(t.charAt(_e))
+ ? ((r = t.charAt(_e)), _e++)
+ : ((r = mr), 0 === Ze && s(ne)),
+ r
+ );
+ }
+
+ function er() {
+ var r, e;
+ return (
+ (r = _e),
+ nr() !== mr
+ ? (84 === t.charCodeAt(_e)
+ ? ((e = ue), _e++)
+ : ((e = mr), 0 === Ze && s(oe)),
+ e !== mr && ar() !== mr
+ ? ((Me = r), (r = ie()))
+ : ((_e = r), (r = mr)))
+ : ((_e = r), (r = mr)),
+ r
+ );
+ }
+
+ function nr() {
+ var r, e, n, u, o, i;
+ return (
+ Ze++,
+ (r = _e),
+ (e = ur()) !== mr
+ ? (45 === t.charCodeAt(_e)
+ ? ((n = Xt), _e++)
+ : ((n = mr), 0 === Ze && s($t)),
+ n !== mr && (u = or()) !== mr
+ ? (45 === t.charCodeAt(_e)
+ ? ((o = Xt), _e++)
+ : ((o = mr), 0 === Ze && s($t)),
+ o !== mr && (i = ir()) !== mr
+ ? (r = e = [e, n, u, o, i])
+ : ((_e = r), (r = mr)))
+ : ((_e = r), (r = mr)))
+ : ((_e = r), (r = mr)),
+ Ze--,
+ r === mr && ((e = mr), 0 === Ze && s(ae)),
+ r
+ );
+ }
+
+ function ur() {
+ var r, t, e, n, u;
+ return (
+ (r = _e),
+ (t = tr()) !== mr &&
+ (e = tr()) !== mr &&
+ (n = tr()) !== mr &&
+ (u = tr()) !== mr
+ ? (r = t = [t, e, n, u])
+ : ((_e = r), (r = mr)),
+ r
+ );
+ }
+
+ function or() {
+ var r, t, e;
+ return (
+ (r = _e),
+ (t = tr()) !== mr && (e = tr()) !== mr
+ ? (r = t = [t, e])
+ : ((_e = r), (r = mr)),
+ r
+ );
+ }
+
+ function ir() {
+ var r, t, e;
+ return (
+ (r = _e),
+ (t = tr()) !== mr && (e = tr()) !== mr
+ ? (r = t = [t, e])
+ : ((_e = r), (r = mr)),
+ r
+ );
+ }
+
+ function ar() {
+ var r, t, e;
+ return (
+ (r = _e),
+ (t = cr()) !== mr && (e = pr()) !== mr
+ ? (r = t = [t, e])
+ : ((_e = r), (r = mr)),
+ r
+ );
+ }
+
+ function cr() {
+ var r, e, n, u, o, i, a;
+ return (
+ (r = _e),
+ (e = fr()) !== mr
+ ? (58 === t.charCodeAt(_e)
+ ? ((n = ce), _e++)
+ : ((n = mr), 0 === Ze && s(fe)),
+ n !== mr && (u = sr()) !== mr
+ ? (58 === t.charCodeAt(_e)
+ ? ((o = ce), _e++)
+ : ((o = mr), 0 === Ze && s(fe)),
+ o !== mr && (i = lr()) !== mr
+ ? ((a = hr()) === mr && (a = null),
+ a !== mr
+ ? (r = e = [e, n, u, o, i, a])
+ : ((_e = r), (r = mr)))
+ : ((_e = r), (r = mr)))
+ : ((_e = r), (r = mr)))
+ : ((_e = r), (r = mr)),
+ r
+ );
+ }
+
+ function fr() {
+ var r, t, e;
+ return (
+ Ze++,
+ (r = _e),
+ (t = tr()) !== mr && (e = tr()) !== mr
+ ? (r = t = [t, e])
+ : ((_e = r), (r = mr)),
+ Ze--,
+ r === mr && ((t = mr), 0 === Ze && s(se)),
+ r
+ );
+ }
+
+ function sr() {
+ var r, t, e;
+ return (
+ Ze++,
+ (r = _e),
+ (t = tr()) !== mr && (e = tr()) !== mr
+ ? (r = t = [t, e])
+ : ((_e = r), (r = mr)),
+ Ze--,
+ r === mr && ((t = mr), 0 === Ze && s(le)),
+ r
+ );
+ }
+
+ function lr() {
+ var r, t, e;
+ return (
+ Ze++,
+ (r = _e),
+ (t = tr()) !== mr && (e = tr()) !== mr
+ ? (r = t = [t, e])
+ : ((_e = r), (r = mr)),
+ Ze--,
+ r === mr && ((t = mr), 0 === Ze && s(he)),
+ r
+ );
+ }
+
+ function hr() {
+ var r, e, n, u;
+ if (
+ ((r = _e),
+ 46 === t.charCodeAt(_e) ? ((e = Yt), _e++) : ((e = mr), 0 === Ze && s(kt)),
+ e !== mr)
+ ) {
+ if (((n = []), (u = tr()) !== mr)) for (; u !== mr; ) n.push(u), (u = tr());
+ else n = mr;
+ n !== mr ? (r = e = [e, n]) : ((_e = r), (r = mr));
+ } else (_e = r), (r = mr);
+ return r;
+ }
+
+ function pr() {
+ var r, e, n, u, o;
+ return (
+ Ze++,
+ 90 === t.charCodeAt(_e) ? ((r = ve), _e++) : ((r = mr), 0 === Ze && s(de)),
+ r === mr &&
+ ((r = _e),
+ (e = X()) !== mr && (n = fr()) !== mr
+ ? (58 === t.charCodeAt(_e)
+ ? ((u = ce), _e++)
+ : ((u = mr), 0 === Ze && s(fe)),
+ u !== mr && (o = sr()) !== mr
+ ? (r = e = [e, n, u, o])
+ : ((_e = r), (r = mr)))
+ : ((_e = r), (r = mr))),
+ Ze--,
+ r === mr && ((e = mr), 0 === Ze && s(pe)),
+ r
+ );
+ }
+
+ function vr() {
+ var r, e, n, u, o, i, a, c, f, l;
+ if (
+ ((r = _e),
+ 91 === t.charCodeAt(_e) ? ((e = ge), _e++) : ((e = mr), 0 === Ze && s(Ae)),
+ e !== mr)
+ ) {
+ for (n = [], u = gr(); u !== mr; ) n.push(u), (u = gr());
+ if (n !== mr) {
+ if (((u = _e), (o = dr()) !== mr)) {
+ for (i = [], a = gr(); a !== mr; ) i.push(a), (a = gr());
+ if (i !== mr) {
+ if (
+ ((a = _e),
+ 44 === t.charCodeAt(_e)
+ ? ((c = Ce), _e++)
+ : ((c = mr), 0 === Ze && s(ye)),
+ c !== mr)
+ ) {
+ for (f = [], l = gr(); l !== mr; ) f.push(l), (l = gr());
+ f !== mr ? (a = c = [c, f]) : ((_e = a), (a = mr));
+ } else (_e = a), (a = mr);
+ a === mr && (a = null),
+ a !== mr ? (u = o = [o, i, a]) : ((_e = u), (u = mr));
+ } else (_e = u), (u = mr);
+ } else (_e = u), (u = mr);
+ u === mr && (u = null),
+ u !== mr
+ ? (93 === t.charCodeAt(_e)
+ ? ((o = be), _e++)
+ : ((o = mr), 0 === Ze && s(me)),
+ o !== mr ? ((Me = r), (r = e = xe(u))) : ((_e = r), (r = mr)))
+ : ((_e = r), (r = mr));
+ } else (_e = r), (r = mr);
+ } else (_e = r), (r = mr);
+ return r;
+ }
+
+ function dr() {
+ var r, e, n, u, o, i, a;
+ if (((r = _e), (e = T()) !== mr)) {
+ for (n = _e, u = [], o = gr(); o !== mr; ) u.push(o), (o = gr());
+ if (u !== mr)
+ if (
+ (44 === t.charCodeAt(_e)
+ ? ((o = Ce), _e++)
+ : ((o = mr), 0 === Ze && s(ye)),
+ o !== mr)
+ ) {
+ for (i = [], a = gr(); a !== mr; ) i.push(a), (a = gr());
+ i !== mr && (a = dr()) !== mr
+ ? (n = u = [u, o, i, a])
+ : ((_e = n), (n = mr));
+ } else (_e = n), (n = mr);
+ else (_e = n), (n = mr);
+ n === mr && (n = null),
+ n !== mr ? ((Me = r), (r = e = Se(e, n))) : ((_e = r), (r = mr));
+ } else (_e = r), (r = mr);
+ return r;
+ }
+
+ function gr() {
+ var r;
+ return (r = g()) === mr && (r = d()) === mr && (r = A()), r;
+ }
+
+ function Ar() {
+ var r, e, n, u, o, i, a, c, f, l, h;
+ if (
+ ((r = _e),
+ 123 === t.charCodeAt(_e) ? ((e = we), _e++) : ((e = mr), 0 === Ze && s(Fe)),
+ e !== mr)
+ ) {
+ for (n = [], u = g(); u !== mr; ) n.push(u), (u = g());
+ if (n !== mr) {
+ if (((u = _e), (o = C()) !== mr)) {
+ for (i = [], a = _e, c = [], f = g(); f !== mr; )
+ c.push(f), (f = g());
+ if (c !== mr)
+ if (
+ (44 === t.charCodeAt(_e)
+ ? ((f = Ce), _e++)
+ : ((f = mr), 0 === Ze && s(ye)),
+ f !== mr)
+ ) {
+ for (l = [], h = g(); h !== mr; ) l.push(h), (h = g());
+ l !== mr && (h = C()) !== mr
+ ? (a = c = [c, f, l, h])
+ : ((_e = a), (a = mr));
+ } else (_e = a), (a = mr);
+ else (_e = a), (a = mr);
+ for (; a !== mr; ) {
+ for (i.push(a), a = _e, c = [], f = g(); f !== mr; )
+ c.push(f), (f = g());
+ if (c !== mr)
+ if (
+ (44 === t.charCodeAt(_e)
+ ? ((f = Ce), _e++)
+ : ((f = mr), 0 === Ze && s(ye)),
+ f !== mr)
+ ) {
+ for (l = [], h = g(); h !== mr; ) l.push(h), (h = g());
+ l !== mr && (h = C()) !== mr
+ ? (a = c = [c, f, l, h])
+ : ((_e = a), (a = mr));
+ } else (_e = a), (a = mr);
+ else (_e = a), (a = mr);
+ }
+ if (i !== mr) {
+ for (a = [], c = g(); c !== mr; ) a.push(c), (c = g());
+ a !== mr ? (u = o = [o, i, a]) : ((_e = u), (u = mr));
+ } else (_e = u), (u = mr);
+ } else (_e = u), (u = mr);
+ u === mr && (u = null),
+ u !== mr
+ ? (125 === t.charCodeAt(_e)
+ ? ((o = Ee), _e++)
+ : ((o = mr), 0 === Ze && s(Te)),
+ o !== mr ? ((Me = r), (r = e = De(u))) : ((_e = r), (r = mr)))
+ : ((_e = r), (r = mr));
+ } else (_e = r), (r = mr);
+ } else (_e = r), (r = mr);
+ return r;
+ }
+
+ function Cr() {
+ var r, e, n, u;
+ return (
+ (r = _e),
+ 91 === t.charCodeAt(_e) ? ((e = ge), _e++) : ((e = mr), 0 === Ze && s(Ae)),
+ e !== mr && (n = yr()) !== mr
+ ? (93 === t.charCodeAt(_e)
+ ? ((u = be), _e++)
+ : ((u = mr), 0 === Ze && s(me)),
+ u !== mr ? ((Me = r), (r = e = Oe(n))) : ((_e = r), (r = mr)))
+ : ((_e = r), (r = mr)),
+ r
+ );
+ }
+
+ function yr() {
+ var r, e, n, u, o, i, a, c, f, l;
+ if (
+ ((r = _e),
+ 91 === t.charCodeAt(_e) ? ((e = ge), _e++) : ((e = mr), 0 === Ze && s(Ae)),
+ e !== mr)
+ ) {
+ for (n = [], u = g(); u !== mr; ) n.push(u), (u = g());
+ if (n !== mr)
+ if ((u = y()) !== mr) {
+ for (o = [], i = _e, a = [], c = g(); c !== mr; )
+ a.push(c), (c = g());
+ if (a !== mr)
+ if (
+ (46 === t.charCodeAt(_e)
+ ? ((c = Yt), _e++)
+ : ((c = mr), 0 === Ze && s(kt)),
+ c !== mr)
+ ) {
+ for (f = [], l = g(); l !== mr; ) f.push(l), (l = g());
+ f !== mr && (l = y()) !== mr
+ ? (i = a = [a, c, f, l])
+ : ((_e = i), (i = mr));
+ } else (_e = i), (i = mr);
+ else (_e = i), (i = mr);
+ for (; i !== mr; ) {
+ for (o.push(i), i = _e, a = [], c = g(); c !== mr; )
+ a.push(c), (c = g());
+ if (a !== mr)
+ if (
+ (46 === t.charCodeAt(_e)
+ ? ((c = Yt), _e++)
+ : ((c = mr), 0 === Ze && s(kt)),
+ c !== mr)
+ ) {
+ for (f = [], l = g(); l !== mr; ) f.push(l), (l = g());
+ f !== mr && (l = y()) !== mr
+ ? (i = a = [a, c, f, l])
+ : ((_e = i), (i = mr));
+ } else (_e = i), (i = mr);
+ else (_e = i), (i = mr);
+ }
+ if (o !== mr) {
+ for (i = [], a = g(); a !== mr; ) i.push(a), (a = g());
+ i !== mr
+ ? (93 === t.charCodeAt(_e)
+ ? ((a = be), _e++)
+ : ((a = mr), 0 === Ze && s(me)),
+ a !== mr
+ ? ((Me = r), (r = e = je(u, o)))
+ : ((_e = r), (r = mr)))
+ : ((_e = r), (r = mr));
+ } else (_e = r), (r = mr);
+ } else (_e = r), (r = mr);
+ else (_e = r), (r = mr);
+ } else (_e = r), (r = mr);
+ return r;
+ }
+ e = void 0 !== e ? e : {};
+ var br,
+ mr = {},
+ xr = {
+ Expressions: p,
+ },
+ Sr = p,
+ wr = function () {
+ return Pe;
+ },
+ Fr = function (r) {
+ Le = Je(Pe, !0, r);
+ },
+ Er = function (r) {
+ Le = Je(Pe, !1, r);
+ },
+ Tr = function (r) {
+ Be(Le.table, r[0]), (Le.table[r[0]] = r[1]);
+ },
+ Dr = a('Newline'),
+ Or = '\n',
+ jr = o('\n', !1),
+ _r = '\r\n',
+ Mr = o('\r\n', !1),
+ Nr = a('Whitespace'),
+ Hr = /^[ \t]/,
+ Ur = i([' ', '\t'], !1, !1),
+ Zr = a('Comment'),
+ Ir = '#',
+ Rr = o('#', !1),
+ qr = {
+ type: 'any',
+ },
+ Qr = '=',
+ Yr = o('=', !1),
+ kr = function (r, t) {
+ return [r, t.value];
+ },
+ zr = function () {
+ return n();
+ },
+ Br = a('[a-z], [A-Z], [0-9], "-", "_"'),
+ Jr = /^[a-zA-Z0-9\-_]/,
+ Pr = i([['a', 'z'], ['A', 'Z'], ['0', '9'], '-', '_'], !1, !1),
+ Lr = function (r) {
+ return r.join('');
+ },
+ Vr = a('DoubleQuote'),
+ Wr = '"',
+ Gr = o('"', !1),
+ Kr = a('SingleQuote'),
+ Xr = "'",
+ $r = o("'", !1),
+ rt = a('ThreeDoubleQuotes'),
+ tt = '"""',
+ et = o('"""', !1),
+ nt = a('ThreeSingleQuotes'),
+ ut = "'''",
+ ot = o("'''", !1),
+ it = function (r) {
+ return {
+ type: 'String',
+ value: r.join(''),
+ };
+ },
+ at = a('NormalCharacter'),
+ ct = /^[^\0-\x1F"\\]/,
+ ft = i([['\0', ''], '"', '\\'], !0, !1),
+ st = 'u',
+ lt = o('u', !1),
+ ht = 'U',
+ pt = o('U', !1),
+ vt = function () {
+ var r = n();
+ return r.length <= 2 ? ke(r[1]) : ze(parseInt(r.substr(2), 16));
+ },
+ dt = a('"b", "f", "n", "r", "t"'),
+ gt = /^[bfnrt]/,
+ At = i(['b', 'f', 'n', 'r', 't'], !1, !1),
+ Ct = a('Backslash'),
+ yt = '\\',
+ bt = o('\\', !1),
+ mt = a('FourHexadecimalDigits'),
+ xt = a('EightHexadecimalDigits'),
+ St = /^[0-9A-Fa-f]/,
+ wt = i(
+ [
+ ['0', '9'],
+ ['A', 'F'],
+ ['a', 'f'],
+ ],
+ !1,
+ !1,
+ ),
+ Ft = function () {
+ var r = n();
+ return {
+ type: 'String',
+ value: r.substr(1, r.length - 2),
+ };
+ },
+ Et = /^[^\0-\x08\n-\x1F']/,
+ Tt = i([['\0', '\b'], ['\n', ''], "'"], !0, !1),
+ Dt = function (r) {
+ return {
+ type: 'String',
+ value: r.join('').replace(/\\\r?\n(?:\r?\n|[ \t])*/g, ''),
+ };
+ },
+ Ot = /^[^\0-\x1F\\]/,
+ jt = i([['\0', ''], '\\'], !0, !1),
+ _t = a('AnyCharacter'),
+ Mt = /^[^\0-\x08\n-\x1F]/,
+ Nt = i(
+ [
+ ['\0', '\b'],
+ ['\n', ''],
+ ],
+ !0,
+ !1,
+ ),
+ Ht = 'true',
+ Ut = o('true', !1),
+ Zt = function () {
+ return {
+ type: 'Boolean',
+ value: !0,
+ };
+ },
+ It = 'false',
+ Rt = o('false', !1),
+ qt = function () {
+ return {
+ type: 'Boolean',
+ value: !1,
+ };
+ },
+ Qt = function () {
+ var r = n(),
+ t = parseFloat(r.replace(/_/g, ''));
+ return (
+ Re(t) || u(r + 'is not a 64-bit floating-point number.'),
+ {
+ type: 'Float',
+ value: t,
+ }
+ );
+ },
+ Yt = '.',
+ kt = o('.', !1),
+ zt = '_',
+ Bt = o('_', !1),
+ Jt = 'e',
+ Pt = o('e', !1),
+ Lt = 'E',
+ Vt = o('E', !1),
+ Wt = function () {
+ var r = n(),
+ t = r.replace(/_/g, ''),
+ e = !1;
+ if ('-' === t[0]) {
+ var o = '-9223372036854775808';
+ (t.length > o.length || (t.length === o.length && t > o)) && (e = !0);
+ } else {
+ '+' === t[0] && (t = t.substr(1));
+ var i = '9223372036854775807';
+ (t.length > i.length || (t.length === i.length && t > i)) && (e = !0);
+ }
+ return (
+ e && u(r + ' is not a 64-bit signed integer.'),
+ (t = parseInt(t, 10)),
+ Re(t) || u(r + ' is not a 64-bit signed integer.'),
+ {
+ type: 'Integer',
+ value: t,
+ }
+ );
+ },
+ Gt = '+',
+ Kt = o('+', !1),
+ Xt = '-',
+ $t = o('-', !1),
+ re = /^[1-9]/,
+ te = i([['1', '9']], !1, !1),
+ ee = /^[0-9]/,
+ ne = i([['0', '9']], !1, !1),
+ ue = 'T',
+ oe = o('T', !1),
+ ie = function () {
+ var r = n(),
+ t = new Date(r);
+ return (
+ Re(t.getTime()) ||
+ u(
+ 'Date-time ' +
+ r +
+ ' is invalid. It does not conform to RFC 3339 or this is a browser-specific problem.',
+ ),
+ {
+ type: 'DateTime',
+ value: t,
+ }
+ );
+ },
+ ae = a('FullDate (YYYY-mm-dd)'),
+ ce = ':',
+ fe = o(':', !1),
+ se = a('Hour (HH)'),
+ le = a('Minute (MM)'),
+ he = a('Second (SS)'),
+ pe = a('TimeOffset (Z or +/-HH:MM)'),
+ ve = 'Z',
+ de = o('Z', !1),
+ ge = '[',
+ Ae = o('[', !1),
+ Ce = ',',
+ ye = o(',', !1),
+ be = ']',
+ me = o(']', !1),
+ xe = function (r) {
+ for (
+ var t = {
+ type: 'Array',
+ value: r ? r[0] : [],
+ },
+ e = 0,
+ n = t.value,
+ u = n.length;
+ e < u;
+ e++
+ )
+ n[e] = n[e].value;
+ return t;
+ },
+ Se = function (r, t) {
+ var e = [r];
+ if (t)
+ for (var n = r.type, o = 0, i = t[3], a = i.length; o < a; o++)
+ n !== i[o].type &&
+ u(Ye(i[o].value) + ' should be of type "' + n + '".'),
+ e.push(i[o]);
+ return e;
+ },
+ we = '{',
+ Fe = o('{', !1),
+ Ee = '}',
+ Te = o('}', !1),
+ De = function (r) {
+ var t = {};
+ if (r) {
+ t[r[0][0]] = r[0][1];
+ for (var e = 0, n = r[1], u = n.length; e < u; e++) {
+ var o = n[e][3];
+ Be(t, o[0]), (t[o[0]] = o[1]);
+ }
+ }
+ return {
+ type: 'InlineTable',
+ value: t,
+ };
+ },
+ Oe = function (r) {
+ return r;
+ },
+ je = function (r, t) {
+ for (var e = [r], n = 0, u = t.length; n < u; n++) e.push(t[n][3]);
+ return e;
+ },
+ _e = 0,
+ Me = 0,
+ Ne = [
+ {
+ line: 1,
+ column: 1,
+ },
+ ],
+ He = 0,
+ Ue = [],
+ Ze = 0;
+ if ('startRule' in e) {
+ if (!(e.startRule in xr))
+ throw new Error('Can\'t start parsing from rule "' + e.startRule + '".');
+ Sr = xr[e.startRule];
+ }
+ var Ie, Re, qe, Qe, Ye, ke, ze, Be, Je;
+ (Ie = function (r) {
+ return 'Value for ' + r + ' should not be redefined in the same table.';
+ }),
+ (Re =
+ Number.isFinite ||
+ function (r) {
+ return 'number' == typeof r && isFinite(r);
+ }),
+ (qe =
+ Array.isArray ||
+ function (r) {
+ return '[object Array]' === Object.prototype.toString.call(r);
+ }),
+ (Qe = function (r, t) {
+ return Object.prototype.hasOwnProperty.call(r, t);
+ }),
+ (Ye =
+ 'object' == typeof JSON && JSON
+ ? JSON.stringify
+ : function (r) {
+ return (
+ '"' +
+ String(r).replace(/[\x00-\x1F"\\]/g, function (r) {
+ switch (r) {
+ case '"':
+ case '\\':
+ return '\\' + r;
+ case '\t':
+ return '\\t';
+ case '\n':
+ return '\\n';
+ case '\r':
+ return '\\r';
+ case '\b':
+ return '\\b';
+ case '\f':
+ return '\\f';
+ default:
+ var t = r.charCodeAt(0).toString(16);
+ return '\\u' + '0000'.substr(t.length) + t;
+ }
+ }) +
+ '"'
+ );
+ }),
+ (ke = function (r) {
+ switch (r) {
+ case '"':
+ case '\\':
+ return r;
+ case 't':
+ return '\t';
+ case 'n':
+ return '\n';
+ case 'r':
+ return '\r';
+ case 'b':
+ return '\b';
+ case 'f':
+ return '\f';
+ default:
+ u(Ye(r) + ' cannot be escaped.');
+ }
+ }),
+ (ze = function (r) {
+ if (
+ ((!Re(r) || r < 0 || r > 1114111) &&
+ u('U+' + r.toString(16) + ' is not a valid Unicode code point.'),
+ String.fromCodePoint)
+ )
+ return String.fromCodePoint(r);
+ var t = '';
+ return (
+ r > 65535 &&
+ ((r -= 65536),
+ (t += String.fromCharCode(((r >>> 10) & 1023) | 55296)),
+ (r = 56320 | (1023 & r))),
+ (t += String.fromCharCode(r))
+ );
+ }),
+ (Be = function (r, t) {
+ Qe(r, t) && u(Ie(Ye(t)));
+ }),
+ (Je = function (r, t, e) {
+ for (var n = '', o = 0, i = e.length; o < i; o++) {
+ var a = e[o];
+ if (((n += (n ? '.' : '') + Ye(a)), Qe(r, a)))
+ t
+ ? qe(r[a])
+ ? (Ge[n] || u(Ie(n)),
+ o + 1 === i
+ ? ((c = {}), r[a].push(c), (r = c))
+ : ((n += '.' + Ye(r[a].length - 1)),
+ (r = r[a][r[a].length - 1])))
+ : (Ve[n] || u(Ie(n)), (r = r[a]))
+ : qe(r[a])
+ ? ((Ge[n] && o + 1 !== i) || u(Ie(n)),
+ (n += '.' + Ye(r[a].length - 1)),
+ (r = r[a][r[a].length - 1]))
+ : (Ve[n] || u(Ie(n)), (r = r[a]));
+ else if (t && o + 1 === i) {
+ var c = {};
+ (r[a] = [c]), (r = c), (Ge[n] = !0);
+ } else (r = r[a] = {}), (Ve[n] = !0);
+ }
+ return (
+ t ? Ge[n] || u(Ie(n)) : ((We[n] || Ge[n]) && u(Ie(n)), (We[n] = !0)),
+ {
+ table: r,
+ path: e,
+ }
+ );
+ });
+ var Pe = {},
+ Le = {
+ table: Pe,
+ path: [],
+ },
+ Ve = {},
+ We = {},
+ Ge = {};
+ if ((br = Sr()) !== mr && _e === t.length) return br;
+ throw (
+ (br !== mr &&
+ _e < t.length &&
+ s({
+ type: 'end',
+ }),
+ h(
+ Ue,
+ He < t.length ? t.charAt(He) : null,
+ He < t.length ? f(He, He + 1) : f(He, He),
+ ))
+ );
+ },
+ }
+ );
+ })();
+ },
+ {},
+ ],
+ 2: [
+ function (r, t, e) {
+
+ function n(r, t, e, n) {
+ (this.message = r), (this.offset = t), (this.line = e), (this.column = n);
+ }
+ !(function (r, t) {
+ function e() {
+ this.constructor = r;
+ }
+ (e.prototype = t.prototype), (r.prototype = new e());
+ })(n, SyntaxError);
+ var u = r('./lib/parser'),
+ o = {
+ parse: function (r) {
+ try {
+ return u.parse(r);
+ } catch (r) {
+ throw r instanceof u.SyntaxError
+ ? ((r.line = r.location.start.line),
+ (r.column = r.location.start.column),
+ (r.offset = r.location.start.offset),
+ new n(
+ r.message,
+ r.location.start.offset,
+ r.location.start.line,
+ r.location.start.column,
+ ))
+ : r;
+ }
+ },
+ SyntaxError: n,
+ };
+ t.exports = o;
+ },
+ {
+ './lib/parser': 1,
+ },
+ ],
+ },
+ {},
+ [2],
+ )(2);
+ });
+
+ var toml$1 = toml;
+
+ /* Very simple logger interface.
+
+ Each module is expected to create its own logger by doing e.g.:
+
+ const logger = getLogger('my-prefix');
+
+ and then use it instead of console:
+
+ logger.info('hello', 'world');
+ logger.warn('...');
+ logger.error('...');
+
+ The logger automatically adds the prefix "[my-prefix]" to all logs; so e.g., the
+ above call would print:
+
+ [my-prefix] hello world
+
+ logger.log is intentionally omitted. The idea is that PyScript should not
+ write anything to console.log, to leave it free for the user.
+
+ Currently, the logger does not to anything more than that. In the future,
+ we might want to add additional features such as the ability to
+ enable/disable logs on a global or per-module basis.
+ */
+ const _cache = new Map();
+ function getLogger(prefix) {
+ let logger = _cache.get(prefix);
+ if (logger === undefined) {
+ logger = _makeLogger(prefix);
+ _cache.set(prefix, logger);
+ }
+ return logger;
+ }
+ function _makeLogger(prefix) {
+ prefix = '[' + prefix + '] ';
+ function make(level) {
+ const out_fn = console[level].bind(console);
+ function fn(fmt, ...args) {
+ out_fn(prefix + fmt, ...args);
+ }
+ return fn;
+ }
+ // 'log' is intentionally omitted
+ const debug = make('debug');
+ const info = make('info');
+ const warn = make('warn');
+ const error = make('error');
+ return { debug, info, warn, error };
+ }
+
+ const logger$e = getLogger('pyscript/runtime');
+ // VERSION
+ // Version number of release
+ const version = '2022.12.1.dev';
+ /*
+ Runtime class is a super class that all different runtimes must respect
+ and adhere to.
+
+ Currently, the only runtime available is Pyodide as indicated by the
+ `RuntimeInterpreter` type above. This serves as a Union of types of
+ different runtimes/interpreters which will be added in near future.
+
+ The class has abstract methods available which each runtime is supposed
+ to implement.
+
+ Methods available handle loading of the interpreter, initialization,
+ running code, loading and installation of packages, loading from files etc.
+
+ For an example implementation, refer to the `PyodideRuntime` class
+ in `pyodide.ts`
+ */
+ class Runtime extends Object {
+ constructor(config) {
+ super();
+ this.config = config;
+ }
+ /**
+ * Same as run, but Python exceptions are not propagated: instead, they
+ * are logged to the console.
+ *
+ * This is a bad API and should be killed/refactored/changed eventually,
+ * but for now we have code which relies on it.
+ * */
+ runButDontRaise(code) {
+ let result;
+ try {
+ result = this.run(code);
+ }
+ catch (error) {
+ logger$e.error('Error:', error);
+ }
+ return result;
+ }
+ }
+
+ const CLOSEBUTTON = ``;
+ /*
+ These error codes are used to identify the type of error that occurred.
+ The convention is:
+ * PY0 - errors that occur when fetching
+ * PY1 - errors that occur in config
+ * PY9 - Deprecation errors
+ */
+ var ErrorCode;
+ (function (ErrorCode) {
+ ErrorCode["GENERIC"] = "PY0000";
+ ErrorCode["FETCH_ERROR"] = "PY0001";
+ ErrorCode["FETCH_NAME_ERROR"] = "PY0002";
+ // Currently these are created depending on error code received from fetching
+ ErrorCode["FETCH_UNAUTHORIZED_ERROR"] = "PY0401";
+ ErrorCode["FETCH_FORBIDDEN_ERROR"] = "PY0403";
+ ErrorCode["FETCH_NOT_FOUND_ERROR"] = "PY0404";
+ ErrorCode["FETCH_SERVER_ERROR"] = "PY0500";
+ ErrorCode["FETCH_UNAVAILABLE_ERROR"] = "PY0503";
+ ErrorCode["BAD_CONFIG"] = "PY1000";
+ ErrorCode["MICROPIP_INSTALL_ERROR"] = "PY1001";
+ ErrorCode["TOP_LEVEL_AWAIT"] = "PY9000";
+ })(ErrorCode || (ErrorCode = {}));
+ class UserError extends Error {
+ constructor(errorCode, message, t = "text") {
+ super(message);
+ this.errorCode = errorCode;
+ this.name = "UserError";
+ this.messageType = t;
+ this.message = `(${errorCode}): ${message}`;
+ }
+ }
+ class FetchError extends Error {
+ constructor(errorCode, message) {
+ super(message);
+ this.name = "FetchError";
+ this.errorCode = errorCode;
+ this.message = `(${errorCode}): ${message}`;
+ }
+ }
+ class InstallError extends UserError {
+ constructor(errorCode, message) {
+ super(errorCode, message);
+ this.name = "InstallError";
+ }
+ }
+ function _createAlertBanner(message, level = 'error', messageType = 'text', logMessage = true) {
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+ switch (`log-${level}-${logMessage}`) {
+ case 'log-error-true':
+ console.error(message);
+ break;
+ case 'log-warning-true':
+ console.warn(message);
+ break;
+ }
+ const banner = document.createElement('div');
+ banner.className = `alert-banner py-${level}`;
+ if (messageType === 'html') {
+ banner.innerHTML = message;
+ }
+ else {
+ banner.textContent = message;
+ }
+ if (level === 'warning') {
+ const closeButton = document.createElement('button');
+ closeButton.id = 'alert-close-button';
+ closeButton.addEventListener('click', () => {
+ banner.remove();
+ });
+ closeButton.innerHTML = CLOSEBUTTON;
+ banner.appendChild(closeButton);
+ }
+ document.body.prepend(banner);
+ }
+
+ function addClasses(element, classes) {
+ for (const entry of classes) {
+ element.classList.add(entry);
+ }
+ }
+ function escape(str) {
+ return str.replace(//g, '>');
+ }
+ function htmlDecode(input) {
+ const doc = new DOMParser().parseFromString(ltrim(escape(input)), 'text/html');
+ return doc.documentElement.textContent;
+ }
+ function ltrim(code) {
+ const lines = code.split('\n');
+ if (lines.length == 0)
+ return code;
+ const lengths = lines
+ .filter(line => line.trim().length != 0)
+ .map(line => {
+ return line.match(/^\s*/)?.pop()?.length;
+ });
+ const k = Math.min(...lengths);
+ return k != 0 ? lines.map(line => line.substring(k)).join('\n') : code;
+ }
+ let _uniqueIdCounter = 0;
+ function ensureUniqueId(el) {
+ if (el.id === '')
+ el.id = `py-internal-${_uniqueIdCounter++}`;
+ }
+ function showWarning(msg, messageType = 'text') {
+ _createAlertBanner(msg, 'warning', messageType);
+ }
+ function handleFetchError(e, singleFile) {
+ // XXX: inspecting the error message to understand what happened is very
+ // fragile. We need a better solution.
+ let errorContent;
+ if (e.message.includes('Failed to fetch')) {
+ errorContent = `PyScript: Access to local files
+ (using "Paths:" in <py-config>)
+ is not available when directly opening a HTML file;
+ you must use a webserver to serve the additional files.
+ See this reference
+ on starting a simple webserver with Python.`;
+ }
+ else if (e.message.includes('404')) {
+ errorContent =
+ `PyScript: Loading from file ` +
+ singleFile +
+ ` failed with error 404 (File not Found). Are your filename and path are correct?`;
+ }
+ else {
+ errorContent = `PyScript encountered an error while loading from file: ${e.message}`;
+ }
+ throw new UserError(ErrorCode.FETCH_ERROR, errorContent, 'html');
+ }
+ function readTextFromPath(path) {
+ const request = new XMLHttpRequest();
+ request.open('GET', path, false);
+ request.send();
+ const returnValue = request.responseText;
+ return returnValue;
+ }
+ function globalExport(name, obj) {
+ // attach the given object to the global object, so that it is globally
+ // visible everywhere. Should be used very sparingly!
+ globalThis[name] = obj;
+ }
+ function getAttribute(el, attr) {
+ if (el.hasAttribute(attr)) {
+ const value = el.getAttribute(attr);
+ if (value) {
+ return value;
+ }
+ }
+ return null;
+ }
+ function joinPaths(parts, separator = '/') {
+ const res = parts
+ .map(function (part) {
+ return part.trim().replace(/(^[/]*|[/]*$)/g, '');
+ })
+ .filter(p => p !== '')
+ .join(separator || '/');
+ if (parts[0].startsWith('/')) {
+ return '/' + res;
+ }
+ return res;
+ }
+ function createDeprecationWarning(msg, elementName) {
+ const banners = document.getElementsByClassName('alert-banner py-warning');
+ let bannerCount = 0;
+ for (const banner of banners) {
+ if (banner.innerHTML.includes(elementName)) {
+ bannerCount++;
+ }
+ }
+ if (bannerCount == 0) {
+ _createAlertBanner(msg, 'warning');
+ }
+ }
+
+ const logger$d = getLogger('py-config');
+ const allKeys = {
+ string: ['name', 'description', 'version', 'type', 'author_name', 'author_email', 'license'],
+ number: ['schema_version'],
+ array: ['runtimes', 'packages', 'fetch', 'plugins'],
+ };
+ const defaultConfig$1 = {
+ schema_version: 1,
+ type: 'app',
+ runtimes: [
+ {
+ src: 'https://cdn.jsdelivr.net/pyodide/v0.21.3/full/pyodide.js',
+ name: 'pyodide-0.21.3',
+ lang: 'python',
+ },
+ ],
+ packages: [],
+ fetch: [],
+ plugins: [],
+ };
+ function loadConfigFromElement(el) {
+ let srcConfig;
+ let inlineConfig;
+ if (el === null) {
+ srcConfig = {};
+ inlineConfig = {};
+ }
+ else {
+ const configType = getAttribute(el, 'type') || 'toml';
+ srcConfig = extractFromSrc(el, configType);
+ inlineConfig = extractFromInline(el, configType);
+ }
+ srcConfig = mergeConfig(srcConfig, defaultConfig$1);
+ const result = mergeConfig(inlineConfig, srcConfig);
+ result.pyscript = {
+ version: version,
+ time: new Date().toISOString(),
+ };
+ return result;
+ }
+ function extractFromSrc(el, configType) {
+ const src = getAttribute(el, 'src');
+ if (src) {
+ logger$d.info('loading ', src);
+ return validateConfig(readTextFromPath(src), configType);
+ }
+ return {};
+ }
+ function extractFromInline(el, configType) {
+ if (el.innerHTML !== '') {
+ logger$d.info('loading content');
+ return validateConfig(htmlDecode(el.innerHTML), configType);
+ }
+ return {};
+ }
+ function fillUserData(inputConfig, resultConfig) {
+ for (const key in inputConfig) {
+ // fill in all extra keys ignored by the validator
+ if (!(key in defaultConfig$1)) {
+ resultConfig[key] = inputConfig[key];
+ }
+ }
+ return resultConfig;
+ }
+ function mergeConfig(inlineConfig, externalConfig) {
+ if (Object.keys(inlineConfig).length === 0 && Object.keys(externalConfig).length === 0) {
+ return defaultConfig$1;
+ }
+ else if (Object.keys(inlineConfig).length === 0) {
+ return externalConfig;
+ }
+ else if (Object.keys(externalConfig).length === 0) {
+ return inlineConfig;
+ }
+ else {
+ let merged = {};
+ for (const keyType in allKeys) {
+ const keys = allKeys[keyType];
+ keys.forEach(function (item) {
+ if (keyType === 'boolean') {
+ merged[item] =
+ typeof inlineConfig[item] !== 'undefined' ? inlineConfig[item] : externalConfig[item];
+ }
+ else {
+ merged[item] = inlineConfig[item] || externalConfig[item];
+ }
+ });
+ }
+ // fill extra keys from external first
+ // they will be overridden by inline if extra keys also clash
+ merged = fillUserData(externalConfig, merged);
+ merged = fillUserData(inlineConfig, merged);
+ return merged;
+ }
+ }
+ function parseConfig(configText, configType = 'toml') {
+ let config;
+ if (configType === 'toml') {
+ try {
+ // TOML parser is soft and can parse even JSON strings, this additional check prevents it.
+ if (configText.trim()[0] === '{') {
+ throw new UserError(ErrorCode.BAD_CONFIG, `The config supplied: ${configText} is an invalid TOML and cannot be parsed`);
+ }
+ config = toml$1.parse(configText);
+ }
+ catch (err) {
+ const errMessage = err.toString();
+ throw new UserError(ErrorCode.BAD_CONFIG, `The config supplied: ${configText} is an invalid TOML and cannot be parsed: ${errMessage}`);
+ }
+ }
+ else if (configType === 'json') {
+ try {
+ config = JSON.parse(configText);
+ }
+ catch (err) {
+ const errMessage = err.toString();
+ throw new UserError(ErrorCode.BAD_CONFIG, `The config supplied: ${configText} is an invalid JSON and cannot be parsed: ${errMessage}`);
+ }
+ }
+ else {
+ throw new UserError(ErrorCode.BAD_CONFIG, `The type of config supplied '${configType}' is not supported, supported values are ["toml", "json"]`);
+ }
+ return config;
+ }
+ function validateConfig(configText, configType = 'toml') {
+ const config = parseConfig(configText, configType);
+ const finalConfig = {};
+ for (const keyType in allKeys) {
+ const keys = allKeys[keyType];
+ keys.forEach(function (item) {
+ if (validateParamInConfig(item, keyType, config)) {
+ if (item === 'runtimes') {
+ finalConfig[item] = [];
+ const runtimes = config[item];
+ runtimes.forEach(function (eachRuntime) {
+ const runtimeConfig = {};
+ for (const eachRuntimeParam in eachRuntime) {
+ if (validateParamInConfig(eachRuntimeParam, 'string', eachRuntime)) {
+ runtimeConfig[eachRuntimeParam] = eachRuntime[eachRuntimeParam];
+ }
+ }
+ finalConfig[item].push(runtimeConfig);
+ });
+ }
+ else if (item === 'fetch') {
+ finalConfig[item] = [];
+ const fetchList = config[item];
+ fetchList.forEach(function (eachFetch) {
+ const eachFetchConfig = {};
+ for (const eachFetchConfigParam in eachFetch) {
+ const targetType = eachFetchConfigParam === 'files' ? 'array' : 'string';
+ if (validateParamInConfig(eachFetchConfigParam, targetType, eachFetch)) {
+ eachFetchConfig[eachFetchConfigParam] = eachFetch[eachFetchConfigParam];
+ }
+ }
+ finalConfig[item].push(eachFetchConfig);
+ });
+ }
+ else {
+ finalConfig[item] = config[item];
+ }
+ }
+ });
+ }
+ return fillUserData(config, finalConfig);
+ }
+ function validateParamInConfig(paramName, paramType, config) {
+ if (paramName in config) {
+ return paramType === 'array' ? Array.isArray(config[paramName]) : typeof config[paramName] === paramType;
+ }
+ return false;
+ }
+
+ const logger$c = getLogger('plugin');
+ class Plugin {
+ /** Validate the configuration of the plugin and handle default values.
+ *
+ * Individual plugins are expected to check that the config keys/sections
+ * which are relevant to them contains valid values, and to raise an error
+ * if they contains unknown keys.
+ *
+ * This is also a good place where set default values for those keys which
+ * are not specified by the user.
+ *
+ * This hook should **NOT** contain expensive operations, else it delays
+ * the download of the python interpreter which is initiated later.
+ */
+ configure(config) { }
+ /** The preliminary initialization phase is complete and we are about to
+ * download and launch the Python interpreter.
+ *
+ * We can assume that the page is already shown to the user and that the
+ * DOM content has been loaded. This is a good place where to add tags to
+ * the DOM, if needed.
+ *
+ * This hook should **NOT** contain expensive operations, else it delays
+ * the download of the python interpreter which is initiated later.
+ */
+ beforeLaunch(config) { }
+ /** The Python interpreter has been launched, the virtualenv has been
+ * installed and we are ready to execute user code.
+ *
+ * The tags will be executed after this hook.
+ */
+ afterSetup(runtime) { }
+ /** Startup complete. The interpreter is initialized and ready, user
+ * scripts have been executed: the main initialization logic ends here and
+ * the page is ready to accept user interactions.
+ */
+ afterStartup(runtime) { }
+ /** Called when an UserError is raised
+ */
+ onUserError(error) { }
+ }
+ class PluginManager {
+ constructor() {
+ this._plugins = [];
+ this._pythonPlugins = [];
+ }
+ add(...plugins) {
+ for (const p of plugins)
+ this._plugins.push(p);
+ }
+ addPythonPlugin(plugin) {
+ this._pythonPlugins.push(plugin);
+ }
+ configure(config) {
+ for (const p of this._plugins)
+ p.configure(config);
+ for (const p of this._pythonPlugins)
+ p.configure?.(config);
+ }
+ beforeLaunch(config) {
+ for (const p of this._plugins)
+ p.beforeLaunch(config);
+ }
+ afterSetup(runtime) {
+ for (const p of this._plugins)
+ p.afterSetup(runtime);
+ for (const p of this._pythonPlugins)
+ p.afterSetup?.(runtime);
+ }
+ afterStartup(runtime) {
+ for (const p of this._plugins)
+ p.afterStartup(runtime);
+ for (const p of this._pythonPlugins)
+ p.afterStartup?.(runtime);
+ }
+ onUserError(error) {
+ for (const p of this._plugins)
+ p.onUserError(error);
+ for (const p of this._pythonPlugins)
+ p.onUserError?.(error);
+ }
+ }
+ /**
+ * Defines a new CustomElement (via customElement.defines) with `tag`,
+ * where the new CustomElement is a proxy that delegates the logic to
+ * pyPluginClass.
+ *
+ * @param tag - tag that will be used to define the new CustomElement (i.e: "py-script")
+ * @param pyPluginClass - class that will be used to create instance to be
+ * used as CustomElement logic handler. Any DOM event
+ * received by the newly created CustomElement will be
+ * delegated to that instance.
+ */
+ function define_custom_element(tag, pyPluginClass) {
+ logger$c.info(`creating plugin: ${tag}`);
+ class ProxyCustomElement extends HTMLElement {
+ constructor() {
+ logger$c.debug(`creating ${tag} plugin instance`);
+ super();
+ this.shadow = this.attachShadow({ mode: 'open' });
+ this.wrapper = document.createElement('slot');
+ this.shadow.appendChild(this.wrapper);
+ this.originalInnerHTML = this.innerHTML;
+ this.pyPluginInstance = pyPluginClass(this);
+ }
+ connectedCallback() {
+ const innerHTML = this.pyPluginInstance.connect();
+ if (typeof innerHTML === 'string')
+ this.innerHTML = innerHTML;
+ }
+ }
+ customElements.define(tag, ProxyCustomElement);
+ }
+
+ const logger$b = getLogger('pyexec');
+ function pyExec(runtime, pysrc, outElem) {
+ //This is pyscript.py
+ const pyscript_py = runtime.interpreter.pyimport('pyscript');
+ ensureUniqueId(outElem);
+ pyscript_py.set_current_display_target(outElem.id);
+ try {
+ try {
+ if (pyscript_py.uses_top_level_await(pysrc)) {
+ throw new UserError(ErrorCode.TOP_LEVEL_AWAIT, 'The use of top-level "await", "async for", and ' +
+ '"async with" is deprecated.' +
+ '\nPlease write a coroutine containing ' +
+ 'your code and schedule it using asyncio.ensure_future() or similar.' +
+ '\nSee https://docs.pyscript.net/latest/guides/asyncio.html for more information.');
+ }
+ return runtime.run(pysrc);
+ }
+ catch (err) {
+ // XXX: currently we display exceptions in the same position as
+ // the output. But we probably need a better way to do that,
+ // e.g. allowing plugins to intercept exceptions and display them
+ // in a configurable way.
+ displayPyException(err, outElem);
+ }
+ }
+ finally {
+ pyscript_py.set_current_display_target(undefined);
+ pyscript_py.destroy();
+ }
+ }
+ /**
+ * Javascript API to call the python display() function
+ *
+ * Expected usage:
+ * pyDisplay(runtime, obj);
+ * pyDisplay(runtime, obj, { target: targetID });
+ */
+ function pyDisplay(runtime, obj, kwargs) {
+ const display = runtime.globals.get('display');
+ if (kwargs === undefined)
+ display(obj);
+ else {
+ display.callKwargs(obj, kwargs);
+ }
+ }
+ function displayPyException(err, errElem) {
+ //addClasses(errElem, ['py-error'])
+ const pre = document.createElement('pre');
+ pre.className = 'py-error';
+ if (err.name === 'PythonError') {
+ // err.message contains the python-level traceback (i.e. a string
+ // starting with: "Traceback (most recent call last) ..."
+ logger$b.error('Python exception:\n' + err.message);
+ pre.innerText = err.message;
+ }
+ else {
+ // this is very likely a normal JS exception. The best we can do is to
+ // display it as is.
+ logger$b.error('Non-python exception:\n' + err);
+ pre.innerText = err;
+ }
+ errElem.appendChild(pre);
+ }
+
+ /*
+ This is a fetch wrapper that handles any non 200 response and throws a FetchError
+ with the right ErrorCode.
+ TODO: Should we only throw on 4xx and 5xx responses?
+ */
+ async function robustFetch(url, options) {
+ const response = await fetch(url, options);
+ // Note that response.ok is true for 200-299 responses
+ if (!response.ok) {
+ const errorMsg = `Fetching from URL ${url} failed with error ${response.status} (${response.statusText}).`;
+ switch (response.status) {
+ case 404:
+ throw new FetchError(ErrorCode.FETCH_NOT_FOUND_ERROR, errorMsg);
+ case 401:
+ throw new FetchError(ErrorCode.FETCH_UNAUTHORIZED_ERROR, errorMsg);
+ case 403:
+ throw new FetchError(ErrorCode.FETCH_FORBIDDEN_ERROR, errorMsg);
+ case 500:
+ throw new FetchError(ErrorCode.FETCH_SERVER_ERROR, errorMsg);
+ case 503:
+ throw new FetchError(ErrorCode.FETCH_UNAVAILABLE_ERROR, errorMsg);
+ default:
+ throw new FetchError(ErrorCode.FETCH_ERROR, errorMsg);
+ }
+ }
+ return response;
+ }
+
+ const logger$a = getLogger('py-script');
+ function make_PyScript(runtime) {
+ class PyScript extends HTMLElement {
+ async connectedCallback() {
+ if (this.hasAttribute('output')) {
+ const deprecationMessage = ("The 'output' attribute is deprecated and ignored. You should use " +
+ "'display()' to output the content to a specific element. " +
+ 'For example display(myElement, target="divID").');
+ showWarning(deprecationMessage);
+ }
+ ensureUniqueId(this);
+ // Save innerHTML information in srcCode so we can access it later
+ // once we clean innerHTML (which is required since we don't want
+ // source code to be rendered on the screen)
+ this.srcCode = this.innerHTML;
+ const pySrc = await this.getPySrc();
+ this.innerHTML = '';
+ pyExec(runtime, pySrc, this);
+ }
+ async getPySrc() {
+ if (this.hasAttribute('src')) {
+ const url = this.getAttribute('src');
+ try {
+ const response = await robustFetch(url);
+ return await response.text();
+ }
+ catch (e) {
+ _createAlertBanner(e.message);
+ this.innerHTML = '';
+ throw e;
+ }
+ }
+ else {
+ return htmlDecode(this.srcCode);
+ }
+ }
+ }
+ return PyScript;
+ }
+ /** Defines all possible py-on* and their corresponding event types */
+ const pyAttributeToEvent = new Map([
+ // Leaving pys-onClick and pys-onKeyDown for backward compatibility
+ ['pys-onClick', 'click'],
+ ['pys-onKeyDown', 'keydown'],
+ ['py-onClick', 'click'],
+ ['py-onKeyDown', 'keydown'],
+ // Window Events
+ ['py-afterprint', 'afterprint'],
+ ['py-beforeprint', 'beforeprint'],
+ ['py-beforeunload', 'beforeunload'],
+ ['py-error', 'error'],
+ ['py-hashchange', 'hashchange'],
+ ['py-load', 'load'],
+ ['py-message', 'message'],
+ ['py-offline', 'offline'],
+ ['py-online', 'online'],
+ ['py-pagehide', 'pagehide'],
+ ['py-pageshow', 'pageshow'],
+ ['py-popstate', 'popstate'],
+ ['py-resize', 'resize'],
+ ['py-storage', 'storage'],
+ ['py-unload', 'unload'],
+ // Form Events
+ ['py-blur', 'blur'],
+ ['py-change', 'change'],
+ ['py-contextmenu', 'contextmenu'],
+ ['py-focus', 'focus'],
+ ['py-input', 'input'],
+ ['py-invalid', 'invalid'],
+ ['py-reset', 'reset'],
+ ['py-search', 'search'],
+ ['py-select', 'select'],
+ ['py-submit', 'submit'],
+ // Keyboard Events
+ ['py-keydown', 'keydown'],
+ ['py-keypress', 'keypress'],
+ ['py-keyup', 'keyup'],
+ // Mouse Events
+ ['py-click', 'click'],
+ ['py-dblclick', 'dblclick'],
+ ['py-mousedown', 'mousedown'],
+ ['py-mousemove', 'mousemove'],
+ ['py-mouseout', 'mouseout'],
+ ['py-mouseover', 'mouseover'],
+ ['py-mouseup', 'mouseup'],
+ ['py-mousewheel', 'mousewheel'],
+ ['py-wheel', 'wheel'],
+ // Drag Events
+ ['py-drag', 'drag'],
+ ['py-dragend', 'dragend'],
+ ['py-dragenter', 'dragenter'],
+ ['py-dragleave', 'dragleave'],
+ ['py-dragover', 'dragover'],
+ ['py-dragstart', 'dragstart'],
+ ['py-drop', 'drop'],
+ ['py-scroll', 'scroll'],
+ // Clipboard Events
+ ['py-copy', 'copy'],
+ ['py-cut', 'cut'],
+ ['py-paste', 'paste'],
+ // Media Events
+ ['py-abort', 'abort'],
+ ['py-canplay', 'canplay'],
+ ['py-canplaythrough', 'canplaythrough'],
+ ['py-cuechange', 'cuechange'],
+ ['py-durationchange', 'durationchange'],
+ ['py-emptied', 'emptied'],
+ ['py-ended', 'ended'],
+ ['py-loadeddata', 'loadeddata'],
+ ['py-loadedmetadata', 'loadedmetadata'],
+ ['py-loadstart', 'loadstart'],
+ ['py-pause', 'pause'],
+ ['py-play', 'play'],
+ ['py-playing', 'playing'],
+ ['py-progress', 'progress'],
+ ['py-ratechange', 'ratechange'],
+ ['py-seeked', 'seeked'],
+ ['py-seeking', 'seeking'],
+ ['py-stalled', 'stalled'],
+ ['py-suspend', 'suspend'],
+ ['py-timeupdate', 'timeupdate'],
+ ['py-volumechange', 'volumechange'],
+ ['py-waiting', 'waiting'],
+ // Misc Events
+ ['py-toggle', 'toggle'],
+ ]);
+ /** Initialize all elements with py-* handlers attributes */
+ function initHandlers(runtime) {
+ logger$a.debug('Initializing py-* event handlers...');
+ for (const pyAttribute of pyAttributeToEvent.keys()) {
+ createElementsWithEventListeners(runtime, pyAttribute);
+ }
+ }
+ /** Initializes an element with the given py-on* attribute and its handler */
+ function createElementsWithEventListeners(runtime, pyAttribute) {
+ const matches = document.querySelectorAll(`[${pyAttribute}]`);
+ for (const el of matches) {
+ if (el.id.length === 0) {
+ throw new TypeError(`<${el.tagName.toLowerCase()}> must have an id attribute, when using the ${pyAttribute} attribute`);
+ }
+ const handlerCode = el.getAttribute(pyAttribute);
+ const event = pyAttributeToEvent.get(pyAttribute);
+ if (pyAttribute === 'pys-onClick' || pyAttribute === 'pys-onKeyDown') {
+ console.warn('Use of pys-onClick and pys-onKeyDown attributes is deprecated in favor of py-onClick() and py-onKeyDown(). pys-on* attributes will be deprecated in a future version of PyScript.');
+ const source = `
+ from pyodide.ffi import create_proxy
+ Element("${el.id}").element.addEventListener("${event}", create_proxy(${handlerCode}))
+ `;
+ runtime.run(source);
+ }
+ else {
+ el.addEventListener(event, () => {
+ runtime.run(handlerCode);
+ });
+ }
+ // TODO: Should we actually map handlers in JS instead of Python?
+ // el.onclick = (evt: any) => {
+ // console.log("click");
+ // new Promise((resolve, reject) => {
+ // setTimeout(() => {
+ // console.log('Inside')
+ // }, 300);
+ // }).then(() => {
+ // console.log("resolved")
+ // });
+ // // let handlerCode = el.getAttribute('py-onClick');
+ // // pyodide.runPython(handlerCode);
+ // }
+ }
+ }
+ /** Mount all elements with attribute py-mount into the Python namespace */
+ function mountElements(runtime) {
+ const matches = document.querySelectorAll('[py-mount]');
+ logger$a.info(`py-mount: found ${matches.length} elements`);
+ let source = '';
+ for (const el of matches) {
+ const mountName = el.getAttribute('py-mount') || el.id.split('-').join('_');
+ source += `\n${mountName} = Element("${el.id}")`;
+ }
+ runtime.run(source);
+ }
+
+ const logger$9 = getLogger('pyscript/pyodide');
+ class PyodideRuntime extends Runtime {
+ constructor(config, stdio, src = 'https://cdn.jsdelivr.net/pyodide/v0.21.3/full/pyodide.js', name = 'pyodide-default', lang = 'python') {
+ logger$9.info('Runtime config:', { name, lang, src });
+ super(config);
+ this.stdio = stdio;
+ this.src = src;
+ this.name = name;
+ this.lang = lang;
+ }
+ /**
+ * Although `loadPyodide` is used below,
+ * notice that it is not imported i.e.
+ * import { loadPyodide } from 'pyodide';
+ * is not used at the top of this file.
+ *
+ * This is because, if it's used, loadPyodide
+ * behaves mischievously i.e. it tries to load
+ * `pyodide.asm.js` and `pyodide_py.tar` but
+ * with paths that are wrong such as:
+ *
+ * http://127.0.0.1:8080/build/pyodide_py.tar
+ * which results in a 404 since `build` doesn't
+ * contain these files and is clearly the wrong
+ * path.
+ */
+ async loadInterpreter() {
+ logger$9.info('Loading pyodide');
+ this.interpreter = await loadPyodide({
+ stdout: (msg) => {
+ this.stdio.stdout_writeline(msg);
+ },
+ stderr: (msg) => {
+ this.stdio.stderr_writeline(msg);
+ },
+ fullStdLib: false,
+ });
+ this.globals = this.interpreter.globals;
+ if (this.config.packages) {
+ logger$9.info("Found packages in configuration to install. Loading micropip...");
+ await this.loadPackage('micropip');
+ }
+ logger$9.info('pyodide loaded and initialized');
+ }
+ run(code) {
+ return this.interpreter.runPython(code);
+ }
+ registerJsModule(name, module) {
+ this.interpreter.registerJsModule(name, module);
+ }
+ async loadPackage(names) {
+ logger$9.info(`pyodide.loadPackage: ${names.toString()}`);
+ await this.interpreter.loadPackage(names, logger$9.info.bind(logger$9), logger$9.info.bind(logger$9));
+ }
+ async installPackage(package_name) {
+ if (package_name.length > 0) {
+ logger$9.info(`micropip install ${package_name.toString()}`);
+ const micropip = this.interpreter.pyimport('micropip');
+ try {
+ await micropip.install(package_name);
+ micropip.destroy();
+ }
+ catch (e) {
+ let exceptionMessage = `Unable to install package(s) '` + package_name + `'.`;
+ // If we can't fetch `package_name` micropip.install throws a huge
+ // Python traceback in `e.message` this logic is to handle the
+ // error and throw a more sensible error message instead of the
+ // huge traceback.
+ if (e.message.includes("Can't find a pure Python 3 wheel")) {
+ exceptionMessage += (` Reason: Can't find a pure Python 3 Wheel for package(s) '` + package_name +
+ `'. See: https://pyodide.org/en/stable/usage/faq.html#micropip-can-t-find-a-pure-python-wheel ` +
+ `for more information.`);
+ }
+ else if (e.message.includes("Can't fetch metadata")) {
+ exceptionMessage += (" Unable to find package in PyPI. " +
+ "Please make sure you have entered a correct package name.");
+ }
+ else {
+ exceptionMessage += (` Reason: ${e.message}. Please open an issue at ` +
+ `https://github.com/pyscript/pyscript/issues/new if you require help or ` +
+ `you think it's a bug.`);
+ }
+ logger$9.error(e);
+ throw new InstallError(ErrorCode.MICROPIP_INSTALL_ERROR, exceptionMessage);
+ }
+ }
+ }
+ /**
+ *
+ * @param path : the path in the filesystem
+ * @param fetch_path : the path to be fetched
+ *
+ * Given a file available at `fetch_path` URL (eg: `http://dummy.com/hi.py`),
+ * the function downloads the file and saves it to the `path` (eg: `a/b/c/foo.py`)
+ * on the FS.
+ *
+ * Example usage:
+ * await loadFromFile(`a/b/c/foo.py`, `http://dummy.com/hi.py`)
+ *
+ * Nested paths are iteratively analysed and each part is created
+ * if it doesn't exist.
+ *
+ * The analysis returns if the part exists and if it's parent directory exists
+ * Due to the manner in which we proceed, the parent will ALWAYS exist.
+ *
+ * The iteration proceeds in the following manner for `a/b/c/foo.py`:
+ *
+ * - `a` doesn't exist but it's parent i.e. `root` exists --> create `a`
+ * - `a/b` doesn't exist but it's parent i.e. `a` exists --> create `a/b`
+ * - `a/b/c` doesn't exist but it's parent i.e. `a/b` exists --> create `a/b/c`
+ *
+ * Finally, write content of `http://dummy.com/hi.py` to `a/b/c/foo.py`
+ *
+ * NOTE: The `path` parameter expects to have the `filename` in it i.e.
+ * `a/b/c/foo.py` is valid while `a/b/c` (i.e. only the folders) are incorrect.
+ */
+ async loadFromFile(path, fetch_path) {
+ const pathArr = path.split('/');
+ const filename = pathArr.pop();
+ for (let i = 0; i < pathArr.length; i++) {
+ // iteratively calculates parts of the path i.e. `a`, `a/b`, `a/b/c` for `a/b/c/foo.py`
+ const eachPath = pathArr.slice(0, i + 1).join('/');
+ // analyses `eachPath` and returns if it exists along with if its parent directory exists or not
+ const { exists, parentExists } = this.interpreter.FS.analyzePath(eachPath);
+ // due to the iterative manner in which we proceed, the parent directory should ALWAYS exist
+ if (!parentExists) {
+ throw new Error(`'INTERNAL ERROR! cannot create ${path}, this should never happen'`);
+ }
+ // creates `eachPath` if it doesn't exist
+ if (!exists) {
+ this.interpreter.FS.mkdir(eachPath);
+ }
+ }
+ // `robustFetch` checks for failures in getting a response
+ const response = await robustFetch(fetch_path);
+ const buffer = await response.arrayBuffer();
+ const data = new Uint8Array(buffer);
+ pathArr.push(filename);
+ // opens a file descriptor for the file at `path`
+ const stream = this.interpreter.FS.open(pathArr.join('/'), 'w');
+ this.interpreter.FS.write(stream, data, 0, data.length, 0);
+ this.interpreter.FS.close(stream);
+ }
+ invalidate_module_path_cache() {
+ const importlib = this.interpreter.pyimport("importlib");
+ importlib.invalidate_caches();
+ }
+ }
+
+ function calculatePaths(fetch_cfg) {
+ const fetchPaths = [];
+ const paths = [];
+ fetch_cfg.forEach(function (each_fetch_cfg) {
+ const from = each_fetch_cfg.from || '';
+ const to_folder = each_fetch_cfg.to_folder || '.';
+ const to_file = each_fetch_cfg.to_file;
+ const files = each_fetch_cfg.files;
+ if (files !== undefined) {
+ if (to_file !== undefined) {
+ throw new UserError(ErrorCode.BAD_CONFIG, `Cannot use 'to_file' and 'files' parameters together!`);
+ }
+ for (const each_f of files) {
+ const each_fetch_path = joinPaths([from, each_f]);
+ fetchPaths.push(each_fetch_path);
+ const each_path = joinPaths([to_folder, each_f]);
+ paths.push(each_path);
+ }
+ }
+ else {
+ fetchPaths.push(from);
+ const filename = to_file || from.split('/').pop();
+ if (filename === '') {
+ throw new UserError(ErrorCode.BAD_CONFIG, `Couldn't determine the filename from the path ${from}, please supply 'to_file' parameter.`);
+ }
+ else {
+ paths.push(joinPaths([to_folder, filename]));
+ }
+ }
+ });
+ return [paths, fetchPaths];
+ }
+
+ /**
+ The data structure for documents. @nonabstract
+ */
+ class Text {
+ /**
+ @internal
+ */
+ constructor() { }
+ /**
+ Get the line description around the given position.
+ */
+ lineAt(pos) {
+ if (pos < 0 || pos > this.length)
+ throw new RangeError(`Invalid position ${pos} in document of length ${this.length}`);
+ return this.lineInner(pos, false, 1, 0);
+ }
+ /**
+ Get the description for the given (1-based) line number.
+ */
+ line(n) {
+ if (n < 1 || n > this.lines)
+ throw new RangeError(`Invalid line number ${n} in ${this.lines}-line document`);
+ return this.lineInner(n, true, 1, 0);
+ }
+ /**
+ Replace a range of the text with the given content.
+ */
+ replace(from, to, text) {
+ let parts = [];
+ this.decompose(0, from, parts, 2 /* Open.To */);
+ if (text.length)
+ text.decompose(0, text.length, parts, 1 /* Open.From */ | 2 /* Open.To */);
+ this.decompose(to, this.length, parts, 1 /* Open.From */);
+ return TextNode.from(parts, this.length - (to - from) + text.length);
+ }
+ /**
+ Append another document to this one.
+ */
+ append(other) {
+ return this.replace(this.length, this.length, other);
+ }
+ /**
+ Retrieve the text between the given points.
+ */
+ slice(from, to = this.length) {
+ let parts = [];
+ this.decompose(from, to, parts, 0);
+ return TextNode.from(parts, to - from);
+ }
+ /**
+ Test whether this text is equal to another instance.
+ */
+ eq(other) {
+ if (other == this)
+ return true;
+ if (other.length != this.length || other.lines != this.lines)
+ return false;
+ let start = this.scanIdentical(other, 1), end = this.length - this.scanIdentical(other, -1);
+ let a = new RawTextCursor(this), b = new RawTextCursor(other);
+ for (let skip = start, pos = start;;) {
+ a.next(skip);
+ b.next(skip);
+ skip = 0;
+ if (a.lineBreak != b.lineBreak || a.done != b.done || a.value != b.value)
+ return false;
+ pos += a.value.length;
+ if (a.done || pos >= end)
+ return true;
+ }
+ }
+ /**
+ Iterate over the text. When `dir` is `-1`, iteration happens
+ from end to start. This will return lines and the breaks between
+ them as separate strings.
+ */
+ iter(dir = 1) { return new RawTextCursor(this, dir); }
+ /**
+ Iterate over a range of the text. When `from` > `to`, the
+ iterator will run in reverse.
+ */
+ iterRange(from, to = this.length) { return new PartialTextCursor(this, from, to); }
+ /**
+ Return a cursor that iterates over the given range of lines,
+ _without_ returning the line breaks between, and yielding empty
+ strings for empty lines.
+
+ When `from` and `to` are given, they should be 1-based line numbers.
+ */
+ iterLines(from, to) {
+ let inner;
+ if (from == null) {
+ inner = this.iter();
+ }
+ else {
+ if (to == null)
+ to = this.lines + 1;
+ let start = this.line(from).from;
+ inner = this.iterRange(start, Math.max(start, to == this.lines + 1 ? this.length : to <= 1 ? 0 : this.line(to - 1).to));
+ }
+ return new LineCursor(inner);
+ }
+ /**
+ @internal
+ */
+ toString() { return this.sliceString(0); }
+ /**
+ Convert the document to an array of lines (which can be
+ deserialized again via [`Text.of`](https://codemirror.net/6/docs/ref/#state.Text^of)).
+ */
+ toJSON() {
+ let lines = [];
+ this.flatten(lines);
+ return lines;
+ }
+ /**
+ Create a `Text` instance for the given array of lines.
+ */
+ static of(text) {
+ if (text.length == 0)
+ throw new RangeError("A document must have at least one line");
+ if (text.length == 1 && !text[0])
+ return Text.empty;
+ return text.length <= 32 /* Tree.Branch */ ? new TextLeaf(text) : TextNode.from(TextLeaf.split(text, []));
+ }
+ }
+ // Leaves store an array of line strings. There are always line breaks
+ // between these strings. Leaves are limited in size and have to be
+ // contained in TextNode instances for bigger documents.
+ class TextLeaf extends Text {
+ constructor(text, length = textLength(text)) {
+ super();
+ this.text = text;
+ this.length = length;
+ }
+ get lines() { return this.text.length; }
+ get children() { return null; }
+ lineInner(target, isLine, line, offset) {
+ for (let i = 0;; i++) {
+ let string = this.text[i], end = offset + string.length;
+ if ((isLine ? line : end) >= target)
+ return new Line(offset, end, line, string);
+ offset = end + 1;
+ line++;
+ }
+ }
+ decompose(from, to, target, open) {
+ let text = from <= 0 && to >= this.length ? this
+ : new TextLeaf(sliceText(this.text, from, to), Math.min(to, this.length) - Math.max(0, from));
+ if (open & 1 /* Open.From */) {
+ let prev = target.pop();
+ let joined = appendText(text.text, prev.text.slice(), 0, text.length);
+ if (joined.length <= 32 /* Tree.Branch */) {
+ target.push(new TextLeaf(joined, prev.length + text.length));
+ }
+ else {
+ let mid = joined.length >> 1;
+ target.push(new TextLeaf(joined.slice(0, mid)), new TextLeaf(joined.slice(mid)));
+ }
+ }
+ else {
+ target.push(text);
+ }
+ }
+ replace(from, to, text) {
+ if (!(text instanceof TextLeaf))
+ return super.replace(from, to, text);
+ let lines = appendText(this.text, appendText(text.text, sliceText(this.text, 0, from)), to);
+ let newLen = this.length + text.length - (to - from);
+ if (lines.length <= 32 /* Tree.Branch */)
+ return new TextLeaf(lines, newLen);
+ return TextNode.from(TextLeaf.split(lines, []), newLen);
+ }
+ sliceString(from, to = this.length, lineSep = "\n") {
+ let result = "";
+ for (let pos = 0, i = 0; pos <= to && i < this.text.length; i++) {
+ let line = this.text[i], end = pos + line.length;
+ if (pos > from && i)
+ result += lineSep;
+ if (from < end && to > pos)
+ result += line.slice(Math.max(0, from - pos), to - pos);
+ pos = end + 1;
+ }
+ return result;
+ }
+ flatten(target) {
+ for (let line of this.text)
+ target.push(line);
+ }
+ scanIdentical() { return 0; }
+ static split(text, target) {
+ let part = [], len = -1;
+ for (let line of text) {
+ part.push(line);
+ len += line.length + 1;
+ if (part.length == 32 /* Tree.Branch */) {
+ target.push(new TextLeaf(part, len));
+ part = [];
+ len = -1;
+ }
+ }
+ if (len > -1)
+ target.push(new TextLeaf(part, len));
+ return target;
+ }
+ }
+ // Nodes provide the tree structure of the `Text` type. They store a
+ // number of other nodes or leaves, taking care to balance themselves
+ // on changes. There are implied line breaks _between_ the children of
+ // a node (but not before the first or after the last child).
+ class TextNode extends Text {
+ constructor(children, length) {
+ super();
+ this.children = children;
+ this.length = length;
+ this.lines = 0;
+ for (let child of children)
+ this.lines += child.lines;
+ }
+ lineInner(target, isLine, line, offset) {
+ for (let i = 0;; i++) {
+ let child = this.children[i], end = offset + child.length, endLine = line + child.lines - 1;
+ if ((isLine ? endLine : end) >= target)
+ return child.lineInner(target, isLine, line, offset);
+ offset = end + 1;
+ line = endLine + 1;
+ }
+ }
+ decompose(from, to, target, open) {
+ for (let i = 0, pos = 0; pos <= to && i < this.children.length; i++) {
+ let child = this.children[i], end = pos + child.length;
+ if (from <= end && to >= pos) {
+ let childOpen = open & ((pos <= from ? 1 /* Open.From */ : 0) | (end >= to ? 2 /* Open.To */ : 0));
+ if (pos >= from && end <= to && !childOpen)
+ target.push(child);
+ else
+ child.decompose(from - pos, to - pos, target, childOpen);
+ }
+ pos = end + 1;
+ }
+ }
+ replace(from, to, text) {
+ if (text.lines < this.lines)
+ for (let i = 0, pos = 0; i < this.children.length; i++) {
+ let child = this.children[i], end = pos + child.length;
+ // Fast path: if the change only affects one child and the
+ // child's size remains in the acceptable range, only update
+ // that child
+ if (from >= pos && to <= end) {
+ let updated = child.replace(from - pos, to - pos, text);
+ let totalLines = this.lines - child.lines + updated.lines;
+ if (updated.lines < (totalLines >> (5 /* Tree.BranchShift */ - 1)) &&
+ updated.lines > (totalLines >> (5 /* Tree.BranchShift */ + 1))) {
+ let copy = this.children.slice();
+ copy[i] = updated;
+ return new TextNode(copy, this.length - (to - from) + text.length);
+ }
+ return super.replace(pos, end, updated);
+ }
+ pos = end + 1;
+ }
+ return super.replace(from, to, text);
+ }
+ sliceString(from, to = this.length, lineSep = "\n") {
+ let result = "";
+ for (let i = 0, pos = 0; i < this.children.length && pos <= to; i++) {
+ let child = this.children[i], end = pos + child.length;
+ if (pos > from && i)
+ result += lineSep;
+ if (from < end && to > pos)
+ result += child.sliceString(from - pos, to - pos, lineSep);
+ pos = end + 1;
+ }
+ return result;
+ }
+ flatten(target) {
+ for (let child of this.children)
+ child.flatten(target);
+ }
+ scanIdentical(other, dir) {
+ if (!(other instanceof TextNode))
+ return 0;
+ let length = 0;
+ let [iA, iB, eA, eB] = dir > 0 ? [0, 0, this.children.length, other.children.length]
+ : [this.children.length - 1, other.children.length - 1, -1, -1];
+ for (;; iA += dir, iB += dir) {
+ if (iA == eA || iB == eB)
+ return length;
+ let chA = this.children[iA], chB = other.children[iB];
+ if (chA != chB)
+ return length + chA.scanIdentical(chB, dir);
+ length += chA.length + 1;
+ }
+ }
+ static from(children, length = children.reduce((l, ch) => l + ch.length + 1, -1)) {
+ let lines = 0;
+ for (let ch of children)
+ lines += ch.lines;
+ if (lines < 32 /* Tree.Branch */) {
+ let flat = [];
+ for (let ch of children)
+ ch.flatten(flat);
+ return new TextLeaf(flat, length);
+ }
+ let chunk = Math.max(32 /* Tree.Branch */, lines >> 5 /* Tree.BranchShift */), maxChunk = chunk << 1, minChunk = chunk >> 1;
+ let chunked = [], currentLines = 0, currentLen = -1, currentChunk = [];
+ function add(child) {
+ let last;
+ if (child.lines > maxChunk && child instanceof TextNode) {
+ for (let node of child.children)
+ add(node);
+ }
+ else if (child.lines > minChunk && (currentLines > minChunk || !currentLines)) {
+ flush();
+ chunked.push(child);
+ }
+ else if (child instanceof TextLeaf && currentLines &&
+ (last = currentChunk[currentChunk.length - 1]) instanceof TextLeaf &&
+ child.lines + last.lines <= 32 /* Tree.Branch */) {
+ currentLines += child.lines;
+ currentLen += child.length + 1;
+ currentChunk[currentChunk.length - 1] = new TextLeaf(last.text.concat(child.text), last.length + 1 + child.length);
+ }
+ else {
+ if (currentLines + child.lines > chunk)
+ flush();
+ currentLines += child.lines;
+ currentLen += child.length + 1;
+ currentChunk.push(child);
+ }
+ }
+ function flush() {
+ if (currentLines == 0)
+ return;
+ chunked.push(currentChunk.length == 1 ? currentChunk[0] : TextNode.from(currentChunk, currentLen));
+ currentLen = -1;
+ currentLines = currentChunk.length = 0;
+ }
+ for (let child of children)
+ add(child);
+ flush();
+ return chunked.length == 1 ? chunked[0] : new TextNode(chunked, length);
+ }
+ }
+ Text.empty = /*@__PURE__*/new TextLeaf([""], 0);
+ function textLength(text) {
+ let length = -1;
+ for (let line of text)
+ length += line.length + 1;
+ return length;
+ }
+ function appendText(text, target, from = 0, to = 1e9) {
+ for (let pos = 0, i = 0, first = true; i < text.length && pos <= to; i++) {
+ let line = text[i], end = pos + line.length;
+ if (end >= from) {
+ if (end > to)
+ line = line.slice(0, to - pos);
+ if (pos < from)
+ line = line.slice(from - pos);
+ if (first) {
+ target[target.length - 1] += line;
+ first = false;
+ }
+ else
+ target.push(line);
+ }
+ pos = end + 1;
+ }
+ return target;
+ }
+ function sliceText(text, from, to) {
+ return appendText(text, [""], from, to);
+ }
+ class RawTextCursor {
+ constructor(text, dir = 1) {
+ this.dir = dir;
+ this.done = false;
+ this.lineBreak = false;
+ this.value = "";
+ this.nodes = [text];
+ this.offsets = [dir > 0 ? 1 : (text instanceof TextLeaf ? text.text.length : text.children.length) << 1];
+ }
+ nextInner(skip, dir) {
+ this.done = this.lineBreak = false;
+ for (;;) {
+ let last = this.nodes.length - 1;
+ let top = this.nodes[last], offsetValue = this.offsets[last], offset = offsetValue >> 1;
+ let size = top instanceof TextLeaf ? top.text.length : top.children.length;
+ if (offset == (dir > 0 ? size : 0)) {
+ if (last == 0) {
+ this.done = true;
+ this.value = "";
+ return this;
+ }
+ if (dir > 0)
+ this.offsets[last - 1]++;
+ this.nodes.pop();
+ this.offsets.pop();
+ }
+ else if ((offsetValue & 1) == (dir > 0 ? 0 : 1)) {
+ this.offsets[last] += dir;
+ if (skip == 0) {
+ this.lineBreak = true;
+ this.value = "\n";
+ return this;
+ }
+ skip--;
+ }
+ else if (top instanceof TextLeaf) {
+ // Move to the next string
+ let next = top.text[offset + (dir < 0 ? -1 : 0)];
+ this.offsets[last] += dir;
+ if (next.length > Math.max(0, skip)) {
+ this.value = skip == 0 ? next : dir > 0 ? next.slice(skip) : next.slice(0, next.length - skip);
+ return this;
+ }
+ skip -= next.length;
+ }
+ else {
+ let next = top.children[offset + (dir < 0 ? -1 : 0)];
+ if (skip > next.length) {
+ skip -= next.length;
+ this.offsets[last] += dir;
+ }
+ else {
+ if (dir < 0)
+ this.offsets[last]--;
+ this.nodes.push(next);
+ this.offsets.push(dir > 0 ? 1 : (next instanceof TextLeaf ? next.text.length : next.children.length) << 1);
+ }
+ }
+ }
+ }
+ next(skip = 0) {
+ if (skip < 0) {
+ this.nextInner(-skip, (-this.dir));
+ skip = this.value.length;
+ }
+ return this.nextInner(skip, this.dir);
+ }
+ }
+ class PartialTextCursor {
+ constructor(text, start, end) {
+ this.value = "";
+ this.done = false;
+ this.cursor = new RawTextCursor(text, start > end ? -1 : 1);
+ this.pos = start > end ? text.length : 0;
+ this.from = Math.min(start, end);
+ this.to = Math.max(start, end);
+ }
+ nextInner(skip, dir) {
+ if (dir < 0 ? this.pos <= this.from : this.pos >= this.to) {
+ this.value = "";
+ this.done = true;
+ return this;
+ }
+ skip += Math.max(0, dir < 0 ? this.pos - this.to : this.from - this.pos);
+ let limit = dir < 0 ? this.pos - this.from : this.to - this.pos;
+ if (skip > limit)
+ skip = limit;
+ limit -= skip;
+ let { value } = this.cursor.next(skip);
+ this.pos += (value.length + skip) * dir;
+ this.value = value.length <= limit ? value : dir < 0 ? value.slice(value.length - limit) : value.slice(0, limit);
+ this.done = !this.value;
+ return this;
+ }
+ next(skip = 0) {
+ if (skip < 0)
+ skip = Math.max(skip, this.from - this.pos);
+ else if (skip > 0)
+ skip = Math.min(skip, this.to - this.pos);
+ return this.nextInner(skip, this.cursor.dir);
+ }
+ get lineBreak() { return this.cursor.lineBreak && this.value != ""; }
+ }
+ class LineCursor {
+ constructor(inner) {
+ this.inner = inner;
+ this.afterBreak = true;
+ this.value = "";
+ this.done = false;
+ }
+ next(skip = 0) {
+ let { done, lineBreak, value } = this.inner.next(skip);
+ if (done) {
+ this.done = true;
+ this.value = "";
+ }
+ else if (lineBreak) {
+ if (this.afterBreak) {
+ this.value = "";
+ }
+ else {
+ this.afterBreak = true;
+ this.next();
+ }
+ }
+ else {
+ this.value = value;
+ this.afterBreak = false;
+ }
+ return this;
+ }
+ get lineBreak() { return false; }
+ }
+ if (typeof Symbol != "undefined") {
+ Text.prototype[Symbol.iterator] = function () { return this.iter(); };
+ RawTextCursor.prototype[Symbol.iterator] = PartialTextCursor.prototype[Symbol.iterator] =
+ LineCursor.prototype[Symbol.iterator] = function () { return this; };
+ }
+ /**
+ This type describes a line in the document. It is created
+ on-demand when lines are [queried](https://codemirror.net/6/docs/ref/#state.Text.lineAt).
+ */
+ class Line {
+ /**
+ @internal
+ */
+ constructor(
+ /**
+ The position of the start of the line.
+ */
+ from,
+ /**
+ The position at the end of the line (_before_ the line break,
+ or at the end of document for the last line).
+ */
+ to,
+ /**
+ This line's line number (1-based).
+ */
+ number,
+ /**
+ The line's content.
+ */
+ text) {
+ this.from = from;
+ this.to = to;
+ this.number = number;
+ this.text = text;
+ }
+ /**
+ The length of the line (not including any line break after it).
+ */
+ get length() { return this.to - this.from; }
+ }
+
+ // Compressed representation of the Grapheme_Cluster_Break=Extend
+ // information from
+ // http://www.unicode.org/Public/13.0.0/ucd/auxiliary/GraphemeBreakProperty.txt.
+ // Each pair of elements represents a range, as an offet from the
+ // previous range and a length. Numbers are in base-36, with the empty
+ // string being a shorthand for 1.
+ let extend = /*@__PURE__*/"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(s => s ? parseInt(s, 36) : 1);
+ // Convert offsets into absolute values
+ for (let i = 1; i < extend.length; i++)
+ extend[i] += extend[i - 1];
+ function isExtendingChar(code) {
+ for (let i = 1; i < extend.length; i += 2)
+ if (extend[i] > code)
+ return extend[i - 1] <= code;
+ return false;
+ }
+ function isRegionalIndicator(code) {
+ return code >= 0x1F1E6 && code <= 0x1F1FF;
+ }
+ const ZWJ = 0x200d;
+ /**
+ Returns a next grapheme cluster break _after_ (not equal to)
+ `pos`, if `forward` is true, or before otherwise. Returns `pos`
+ itself if no further cluster break is available in the string.
+ Moves across surrogate pairs, extending characters (when
+ `includeExtending` is true), characters joined with zero-width
+ joiners, and flag emoji.
+ */
+ function findClusterBreak(str, pos, forward = true, includeExtending = true) {
+ return (forward ? nextClusterBreak : prevClusterBreak)(str, pos, includeExtending);
+ }
+ function nextClusterBreak(str, pos, includeExtending) {
+ if (pos == str.length)
+ return pos;
+ // If pos is in the middle of a surrogate pair, move to its start
+ if (pos && surrogateLow(str.charCodeAt(pos)) && surrogateHigh(str.charCodeAt(pos - 1)))
+ pos--;
+ let prev = codePointAt(str, pos);
+ pos += codePointSize(prev);
+ while (pos < str.length) {
+ let next = codePointAt(str, pos);
+ if (prev == ZWJ || next == ZWJ || includeExtending && isExtendingChar(next)) {
+ pos += codePointSize(next);
+ prev = next;
+ }
+ else if (isRegionalIndicator(next)) {
+ let countBefore = 0, i = pos - 2;
+ while (i >= 0 && isRegionalIndicator(codePointAt(str, i))) {
+ countBefore++;
+ i -= 2;
+ }
+ if (countBefore % 2 == 0)
+ break;
+ else
+ pos += 2;
+ }
+ else {
+ break;
+ }
+ }
+ return pos;
+ }
+ function prevClusterBreak(str, pos, includeExtending) {
+ while (pos > 0) {
+ let found = nextClusterBreak(str, pos - 2, includeExtending);
+ if (found < pos)
+ return found;
+ pos--;
+ }
+ return 0;
+ }
+ function surrogateLow(ch) { return ch >= 0xDC00 && ch < 0xE000; }
+ function surrogateHigh(ch) { return ch >= 0xD800 && ch < 0xDC00; }
+ /**
+ Find the code point at the given position in a string (like the
+ [`codePointAt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt)
+ string method).
+ */
+ function codePointAt(str, pos) {
+ let code0 = str.charCodeAt(pos);
+ if (!surrogateHigh(code0) || pos + 1 == str.length)
+ return code0;
+ let code1 = str.charCodeAt(pos + 1);
+ if (!surrogateLow(code1))
+ return code0;
+ return ((code0 - 0xd800) << 10) + (code1 - 0xdc00) + 0x10000;
+ }
+ /**
+ Given a Unicode codepoint, return the JavaScript string that
+ respresents it (like
+ [`String.fromCodePoint`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint)).
+ */
+ function fromCodePoint(code) {
+ if (code <= 0xffff)
+ return String.fromCharCode(code);
+ code -= 0x10000;
+ return String.fromCharCode((code >> 10) + 0xd800, (code & 1023) + 0xdc00);
+ }
+ /**
+ The amount of positions a character takes up a JavaScript string.
+ */
+ function codePointSize(code) { return code < 0x10000 ? 1 : 2; }
+
+ const DefaultSplit = /\r\n?|\n/;
+ /**
+ Distinguishes different ways in which positions can be mapped.
+ */
+ var MapMode = /*@__PURE__*/(function (MapMode) {
+ /**
+ Map a position to a valid new position, even when its context
+ was deleted.
+ */
+ MapMode[MapMode["Simple"] = 0] = "Simple";
+ /**
+ Return null if deletion happens across the position.
+ */
+ MapMode[MapMode["TrackDel"] = 1] = "TrackDel";
+ /**
+ Return null if the character _before_ the position is deleted.
+ */
+ MapMode[MapMode["TrackBefore"] = 2] = "TrackBefore";
+ /**
+ Return null if the character _after_ the position is deleted.
+ */
+ MapMode[MapMode["TrackAfter"] = 3] = "TrackAfter";
+ return MapMode})(MapMode || (MapMode = {}));
+ /**
+ A change description is a variant of [change set](https://codemirror.net/6/docs/ref/#state.ChangeSet)
+ that doesn't store the inserted text. As such, it can't be
+ applied, but is cheaper to store and manipulate.
+ */
+ class ChangeDesc {
+ // Sections are encoded as pairs of integers. The first is the
+ // length in the current document, and the second is -1 for
+ // unaffected sections, and the length of the replacement content
+ // otherwise. So an insertion would be (0, n>0), a deletion (n>0,
+ // 0), and a replacement two positive numbers.
+ /**
+ @internal
+ */
+ constructor(
+ /**
+ @internal
+ */
+ sections) {
+ this.sections = sections;
+ }
+ /**
+ The length of the document before the change.
+ */
+ get length() {
+ let result = 0;
+ for (let i = 0; i < this.sections.length; i += 2)
+ result += this.sections[i];
+ return result;
+ }
+ /**
+ The length of the document after the change.
+ */
+ get newLength() {
+ let result = 0;
+ for (let i = 0; i < this.sections.length; i += 2) {
+ let ins = this.sections[i + 1];
+ result += ins < 0 ? this.sections[i] : ins;
+ }
+ return result;
+ }
+ /**
+ False when there are actual changes in this set.
+ */
+ get empty() { return this.sections.length == 0 || this.sections.length == 2 && this.sections[1] < 0; }
+ /**
+ Iterate over the unchanged parts left by these changes. `posA`
+ provides the position of the range in the old document, `posB`
+ the new position in the changed document.
+ */
+ iterGaps(f) {
+ for (let i = 0, posA = 0, posB = 0; i < this.sections.length;) {
+ let len = this.sections[i++], ins = this.sections[i++];
+ if (ins < 0) {
+ f(posA, posB, len);
+ posB += len;
+ }
+ else {
+ posB += ins;
+ }
+ posA += len;
+ }
+ }
+ /**
+ Iterate over the ranges changed by these changes. (See
+ [`ChangeSet.iterChanges`](https://codemirror.net/6/docs/ref/#state.ChangeSet.iterChanges) for a
+ variant that also provides you with the inserted text.)
+ `fromA`/`toA` provides the extent of the change in the starting
+ document, `fromB`/`toB` the extent of the replacement in the
+ changed document.
+
+ When `individual` is true, adjacent changes (which are kept
+ separate for [position mapping](https://codemirror.net/6/docs/ref/#state.ChangeDesc.mapPos)) are
+ reported separately.
+ */
+ iterChangedRanges(f, individual = false) {
+ iterChanges(this, f, individual);
+ }
+ /**
+ Get a description of the inverted form of these changes.
+ */
+ get invertedDesc() {
+ let sections = [];
+ for (let i = 0; i < this.sections.length;) {
+ let len = this.sections[i++], ins = this.sections[i++];
+ if (ins < 0)
+ sections.push(len, ins);
+ else
+ sections.push(ins, len);
+ }
+ return new ChangeDesc(sections);
+ }
+ /**
+ Compute the combined effect of applying another set of changes
+ after this one. The length of the document after this set should
+ match the length before `other`.
+ */
+ composeDesc(other) { return this.empty ? other : other.empty ? this : composeSets(this, other); }
+ /**
+ Map this description, which should start with the same document
+ as `other`, over another set of changes, so that it can be
+ applied after it. When `before` is true, map as if the changes
+ in `other` happened before the ones in `this`.
+ */
+ mapDesc(other, before = false) { return other.empty ? this : mapSet(this, other, before); }
+ mapPos(pos, assoc = -1, mode = MapMode.Simple) {
+ let posA = 0, posB = 0;
+ for (let i = 0; i < this.sections.length;) {
+ let len = this.sections[i++], ins = this.sections[i++], endA = posA + len;
+ if (ins < 0) {
+ if (endA > pos)
+ return posB + (pos - posA);
+ posB += len;
+ }
+ else {
+ if (mode != MapMode.Simple && endA >= pos &&
+ (mode == MapMode.TrackDel && posA < pos && endA > pos ||
+ mode == MapMode.TrackBefore && posA < pos ||
+ mode == MapMode.TrackAfter && endA > pos))
+ return null;
+ if (endA > pos || endA == pos && assoc < 0 && !len)
+ return pos == posA || assoc < 0 ? posB : posB + ins;
+ posB += ins;
+ }
+ posA = endA;
+ }
+ if (pos > posA)
+ throw new RangeError(`Position ${pos} is out of range for changeset of length ${posA}`);
+ return posB;
+ }
+ /**
+ Check whether these changes touch a given range. When one of the
+ changes entirely covers the range, the string `"cover"` is
+ returned.
+ */
+ touchesRange(from, to = from) {
+ for (let i = 0, pos = 0; i < this.sections.length && pos <= to;) {
+ let len = this.sections[i++], ins = this.sections[i++], end = pos + len;
+ if (ins >= 0 && pos <= to && end >= from)
+ return pos < from && end > to ? "cover" : true;
+ pos = end;
+ }
+ return false;
+ }
+ /**
+ @internal
+ */
+ toString() {
+ let result = "";
+ for (let i = 0; i < this.sections.length;) {
+ let len = this.sections[i++], ins = this.sections[i++];
+ result += (result ? " " : "") + len + (ins >= 0 ? ":" + ins : "");
+ }
+ return result;
+ }
+ /**
+ Serialize this change desc to a JSON-representable value.
+ */
+ toJSON() { return this.sections; }
+ /**
+ Create a change desc from its JSON representation (as produced
+ by [`toJSON`](https://codemirror.net/6/docs/ref/#state.ChangeDesc.toJSON).
+ */
+ static fromJSON(json) {
+ if (!Array.isArray(json) || json.length % 2 || json.some(a => typeof a != "number"))
+ throw new RangeError("Invalid JSON representation of ChangeDesc");
+ return new ChangeDesc(json);
+ }
+ /**
+ @internal
+ */
+ static create(sections) { return new ChangeDesc(sections); }
+ }
+ /**
+ A change set represents a group of modifications to a document. It
+ stores the document length, and can only be applied to documents
+ with exactly that length.
+ */
+ class ChangeSet extends ChangeDesc {
+ constructor(sections,
+ /**
+ @internal
+ */
+ inserted) {
+ super(sections);
+ this.inserted = inserted;
+ }
+ /**
+ Apply the changes to a document, returning the modified
+ document.
+ */
+ apply(doc) {
+ if (this.length != doc.length)
+ throw new RangeError("Applying change set to a document with the wrong length");
+ iterChanges(this, (fromA, toA, fromB, _toB, text) => doc = doc.replace(fromB, fromB + (toA - fromA), text), false);
+ return doc;
+ }
+ mapDesc(other, before = false) { return mapSet(this, other, before, true); }
+ /**
+ Given the document as it existed _before_ the changes, return a
+ change set that represents the inverse of this set, which could
+ be used to go from the document created by the changes back to
+ the document as it existed before the changes.
+ */
+ invert(doc) {
+ let sections = this.sections.slice(), inserted = [];
+ for (let i = 0, pos = 0; i < sections.length; i += 2) {
+ let len = sections[i], ins = sections[i + 1];
+ if (ins >= 0) {
+ sections[i] = ins;
+ sections[i + 1] = len;
+ let index = i >> 1;
+ while (inserted.length < index)
+ inserted.push(Text.empty);
+ inserted.push(len ? doc.slice(pos, pos + len) : Text.empty);
+ }
+ pos += len;
+ }
+ return new ChangeSet(sections, inserted);
+ }
+ /**
+ Combine two subsequent change sets into a single set. `other`
+ must start in the document produced by `this`. If `this` goes
+ `docA` → `docB` and `other` represents `docB` → `docC`, the
+ returned value will represent the change `docA` → `docC`.
+ */
+ compose(other) { return this.empty ? other : other.empty ? this : composeSets(this, other, true); }
+ /**
+ Given another change set starting in the same document, maps this
+ change set over the other, producing a new change set that can be
+ applied to the document produced by applying `other`. When
+ `before` is `true`, order changes as if `this` comes before
+ `other`, otherwise (the default) treat `other` as coming first.
+
+ Given two changes `A` and `B`, `A.compose(B.map(A))` and
+ `B.compose(A.map(B, true))` will produce the same document. This
+ provides a basic form of [operational
+ transformation](https://en.wikipedia.org/wiki/Operational_transformation),
+ and can be used for collaborative editing.
+ */
+ map(other, before = false) { return other.empty ? this : mapSet(this, other, before, true); }
+ /**
+ Iterate over the changed ranges in the document, calling `f` for
+ each, with the range in the original document (`fromA`-`toA`)
+ and the range that replaces it in the new document
+ (`fromB`-`toB`).
+
+ When `individual` is true, adjacent changes are reported
+ separately.
+ */
+ iterChanges(f, individual = false) {
+ iterChanges(this, f, individual);
+ }
+ /**
+ Get a [change description](https://codemirror.net/6/docs/ref/#state.ChangeDesc) for this change
+ set.
+ */
+ get desc() { return ChangeDesc.create(this.sections); }
+ /**
+ @internal
+ */
+ filter(ranges) {
+ let resultSections = [], resultInserted = [], filteredSections = [];
+ let iter = new SectionIter(this);
+ done: for (let i = 0, pos = 0;;) {
+ let next = i == ranges.length ? 1e9 : ranges[i++];
+ while (pos < next || pos == next && iter.len == 0) {
+ if (iter.done)
+ break done;
+ let len = Math.min(iter.len, next - pos);
+ addSection(filteredSections, len, -1);
+ let ins = iter.ins == -1 ? -1 : iter.off == 0 ? iter.ins : 0;
+ addSection(resultSections, len, ins);
+ if (ins > 0)
+ addInsert(resultInserted, resultSections, iter.text);
+ iter.forward(len);
+ pos += len;
+ }
+ let end = ranges[i++];
+ while (pos < end) {
+ if (iter.done)
+ break done;
+ let len = Math.min(iter.len, end - pos);
+ addSection(resultSections, len, -1);
+ addSection(filteredSections, len, iter.ins == -1 ? -1 : iter.off == 0 ? iter.ins : 0);
+ iter.forward(len);
+ pos += len;
+ }
+ }
+ return { changes: new ChangeSet(resultSections, resultInserted),
+ filtered: ChangeDesc.create(filteredSections) };
+ }
+ /**
+ Serialize this change set to a JSON-representable value.
+ */
+ toJSON() {
+ let parts = [];
+ for (let i = 0; i < this.sections.length; i += 2) {
+ let len = this.sections[i], ins = this.sections[i + 1];
+ if (ins < 0)
+ parts.push(len);
+ else if (ins == 0)
+ parts.push([len]);
+ else
+ parts.push([len].concat(this.inserted[i >> 1].toJSON()));
+ }
+ return parts;
+ }
+ /**
+ Create a change set for the given changes, for a document of the
+ given length, using `lineSep` as line separator.
+ */
+ static of(changes, length, lineSep) {
+ let sections = [], inserted = [], pos = 0;
+ let total = null;
+ function flush(force = false) {
+ if (!force && !sections.length)
+ return;
+ if (pos < length)
+ addSection(sections, length - pos, -1);
+ let set = new ChangeSet(sections, inserted);
+ total = total ? total.compose(set.map(total)) : set;
+ sections = [];
+ inserted = [];
+ pos = 0;
+ }
+ function process(spec) {
+ if (Array.isArray(spec)) {
+ for (let sub of spec)
+ process(sub);
+ }
+ else if (spec instanceof ChangeSet) {
+ if (spec.length != length)
+ throw new RangeError(`Mismatched change set length (got ${spec.length}, expected ${length})`);
+ flush();
+ total = total ? total.compose(spec.map(total)) : spec;
+ }
+ else {
+ let { from, to = from, insert } = spec;
+ if (from > to || from < 0 || to > length)
+ throw new RangeError(`Invalid change range ${from} to ${to} (in doc of length ${length})`);
+ let insText = !insert ? Text.empty : typeof insert == "string" ? Text.of(insert.split(lineSep || DefaultSplit)) : insert;
+ let insLen = insText.length;
+ if (from == to && insLen == 0)
+ return;
+ if (from < pos)
+ flush();
+ if (from > pos)
+ addSection(sections, from - pos, -1);
+ addSection(sections, to - from, insLen);
+ addInsert(inserted, sections, insText);
+ pos = to;
+ }
+ }
+ process(changes);
+ flush(!total);
+ return total;
+ }
+ /**
+ Create an empty changeset of the given length.
+ */
+ static empty(length) {
+ return new ChangeSet(length ? [length, -1] : [], []);
+ }
+ /**
+ Create a changeset from its JSON representation (as produced by
+ [`toJSON`](https://codemirror.net/6/docs/ref/#state.ChangeSet.toJSON).
+ */
+ static fromJSON(json) {
+ if (!Array.isArray(json))
+ throw new RangeError("Invalid JSON representation of ChangeSet");
+ let sections = [], inserted = [];
+ for (let i = 0; i < json.length; i++) {
+ let part = json[i];
+ if (typeof part == "number") {
+ sections.push(part, -1);
+ }
+ else if (!Array.isArray(part) || typeof part[0] != "number" || part.some((e, i) => i && typeof e != "string")) {
+ throw new RangeError("Invalid JSON representation of ChangeSet");
+ }
+ else if (part.length == 1) {
+ sections.push(part[0], 0);
+ }
+ else {
+ while (inserted.length < i)
+ inserted.push(Text.empty);
+ inserted[i] = Text.of(part.slice(1));
+ sections.push(part[0], inserted[i].length);
+ }
+ }
+ return new ChangeSet(sections, inserted);
+ }
+ /**
+ @internal
+ */
+ static createSet(sections, inserted) {
+ return new ChangeSet(sections, inserted);
+ }
+ }
+ function addSection(sections, len, ins, forceJoin = false) {
+ if (len == 0 && ins <= 0)
+ return;
+ let last = sections.length - 2;
+ if (last >= 0 && ins <= 0 && ins == sections[last + 1])
+ sections[last] += len;
+ else if (len == 0 && sections[last] == 0)
+ sections[last + 1] += ins;
+ else if (forceJoin) {
+ sections[last] += len;
+ sections[last + 1] += ins;
+ }
+ else
+ sections.push(len, ins);
+ }
+ function addInsert(values, sections, value) {
+ if (value.length == 0)
+ return;
+ let index = (sections.length - 2) >> 1;
+ if (index < values.length) {
+ values[values.length - 1] = values[values.length - 1].append(value);
+ }
+ else {
+ while (values.length < index)
+ values.push(Text.empty);
+ values.push(value);
+ }
+ }
+ function iterChanges(desc, f, individual) {
+ let inserted = desc.inserted;
+ for (let posA = 0, posB = 0, i = 0; i < desc.sections.length;) {
+ let len = desc.sections[i++], ins = desc.sections[i++];
+ if (ins < 0) {
+ posA += len;
+ posB += len;
+ }
+ else {
+ let endA = posA, endB = posB, text = Text.empty;
+ for (;;) {
+ endA += len;
+ endB += ins;
+ if (ins && inserted)
+ text = text.append(inserted[(i - 2) >> 1]);
+ if (individual || i == desc.sections.length || desc.sections[i + 1] < 0)
+ break;
+ len = desc.sections[i++];
+ ins = desc.sections[i++];
+ }
+ f(posA, endA, posB, endB, text);
+ posA = endA;
+ posB = endB;
+ }
+ }
+ }
+ function mapSet(setA, setB, before, mkSet = false) {
+ // Produce a copy of setA that applies to the document after setB
+ // has been applied (assuming both start at the same document).
+ let sections = [], insert = mkSet ? [] : null;
+ let a = new SectionIter(setA), b = new SectionIter(setB);
+ // Iterate over both sets in parallel. inserted tracks, for changes
+ // in A that have to be processed piece-by-piece, whether their
+ // content has been inserted already, and refers to the section
+ // index.
+ for (let inserted = -1;;) {
+ if (a.ins == -1 && b.ins == -1) {
+ // Move across ranges skipped by both sets.
+ let len = Math.min(a.len, b.len);
+ addSection(sections, len, -1);
+ a.forward(len);
+ b.forward(len);
+ }
+ else if (b.ins >= 0 && (a.ins < 0 || inserted == a.i || a.off == 0 && (b.len < a.len || b.len == a.len && !before))) {
+ // If there's a change in B that comes before the next change in
+ // A (ordered by start pos, then len, then before flag), skip
+ // that (and process any changes in A it covers).
+ let len = b.len;
+ addSection(sections, b.ins, -1);
+ while (len) {
+ let piece = Math.min(a.len, len);
+ if (a.ins >= 0 && inserted < a.i && a.len <= piece) {
+ addSection(sections, 0, a.ins);
+ if (insert)
+ addInsert(insert, sections, a.text);
+ inserted = a.i;
+ }
+ a.forward(piece);
+ len -= piece;
+ }
+ b.next();
+ }
+ else if (a.ins >= 0) {
+ // Process the part of a change in A up to the start of the next
+ // non-deletion change in B (if overlapping).
+ let len = 0, left = a.len;
+ while (left) {
+ if (b.ins == -1) {
+ let piece = Math.min(left, b.len);
+ len += piece;
+ left -= piece;
+ b.forward(piece);
+ }
+ else if (b.ins == 0 && b.len < left) {
+ left -= b.len;
+ b.next();
+ }
+ else {
+ break;
+ }
+ }
+ addSection(sections, len, inserted < a.i ? a.ins : 0);
+ if (insert && inserted < a.i)
+ addInsert(insert, sections, a.text);
+ inserted = a.i;
+ a.forward(a.len - left);
+ }
+ else if (a.done && b.done) {
+ return insert ? ChangeSet.createSet(sections, insert) : ChangeDesc.create(sections);
+ }
+ else {
+ throw new Error("Mismatched change set lengths");
+ }
+ }
+ }
+ function composeSets(setA, setB, mkSet = false) {
+ let sections = [];
+ let insert = mkSet ? [] : null;
+ let a = new SectionIter(setA), b = new SectionIter(setB);
+ for (let open = false;;) {
+ if (a.done && b.done) {
+ return insert ? ChangeSet.createSet(sections, insert) : ChangeDesc.create(sections);
+ }
+ else if (a.ins == 0) { // Deletion in A
+ addSection(sections, a.len, 0, open);
+ a.next();
+ }
+ else if (b.len == 0 && !b.done) { // Insertion in B
+ addSection(sections, 0, b.ins, open);
+ if (insert)
+ addInsert(insert, sections, b.text);
+ b.next();
+ }
+ else if (a.done || b.done) {
+ throw new Error("Mismatched change set lengths");
+ }
+ else {
+ let len = Math.min(a.len2, b.len), sectionLen = sections.length;
+ if (a.ins == -1) {
+ let insB = b.ins == -1 ? -1 : b.off ? 0 : b.ins;
+ addSection(sections, len, insB, open);
+ if (insert && insB)
+ addInsert(insert, sections, b.text);
+ }
+ else if (b.ins == -1) {
+ addSection(sections, a.off ? 0 : a.len, len, open);
+ if (insert)
+ addInsert(insert, sections, a.textBit(len));
+ }
+ else {
+ addSection(sections, a.off ? 0 : a.len, b.off ? 0 : b.ins, open);
+ if (insert && !b.off)
+ addInsert(insert, sections, b.text);
+ }
+ open = (a.ins > len || b.ins >= 0 && b.len > len) && (open || sections.length > sectionLen);
+ a.forward2(len);
+ b.forward(len);
+ }
+ }
+ }
+ class SectionIter {
+ constructor(set) {
+ this.set = set;
+ this.i = 0;
+ this.next();
+ }
+ next() {
+ let { sections } = this.set;
+ if (this.i < sections.length) {
+ this.len = sections[this.i++];
+ this.ins = sections[this.i++];
+ }
+ else {
+ 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 } = this.set, index = (this.i - 2) >> 1;
+ return index >= inserted.length ? Text.empty : inserted[index];
+ }
+ textBit(len) {
+ let { inserted } = this.set, index = (this.i - 2) >> 1;
+ return index >= inserted.length && !len ? Text.empty
+ : inserted[index].slice(this.off, len == null ? undefined : this.off + len);
+ }
+ forward(len) {
+ if (len == this.len)
+ this.next();
+ else {
+ this.len -= len;
+ this.off += len;
+ }
+ }
+ forward2(len) {
+ if (this.ins == -1)
+ this.forward(len);
+ else if (len == this.ins)
+ this.next();
+ else {
+ this.ins -= len;
+ this.off += len;
+ }
+ }
+ }
+
+ /**
+ A single selection range. When
+ [`allowMultipleSelections`](https://codemirror.net/6/docs/ref/#state.EditorState^allowMultipleSelections)
+ is enabled, a [selection](https://codemirror.net/6/docs/ref/#state.EditorSelection) may hold
+ multiple ranges. By default, selections hold exactly one range.
+ */
+ class SelectionRange {
+ constructor(
+ /**
+ The lower boundary of the range.
+ */
+ from,
+ /**
+ The upper boundary of the range.
+ */
+ to, flags) {
+ this.from = from;
+ this.to = to;
+ this.flags = flags;
+ }
+ /**
+ The anchor of the range—the side that doesn't move when you
+ extend it.
+ */
+ get anchor() { return this.flags & 16 /* RangeFlag.Inverted */ ? this.to : this.from; }
+ /**
+ The head of the range, which is moved when the range is
+ [extended](https://codemirror.net/6/docs/ref/#state.SelectionRange.extend).
+ */
+ get head() { return this.flags & 16 /* RangeFlag.Inverted */ ? this.from : this.to; }
+ /**
+ True when `anchor` and `head` are at the same position.
+ */
+ get empty() { return this.from == this.to; }
+ /**
+ If this is a cursor that is explicitly associated with the
+ character on one of its sides, this returns the side. -1 means
+ the character before its position, 1 the character after, and 0
+ means no association.
+ */
+ get assoc() { return this.flags & 4 /* RangeFlag.AssocBefore */ ? -1 : this.flags & 8 /* RangeFlag.AssocAfter */ ? 1 : 0; }
+ /**
+ The bidirectional text level associated with this cursor, if
+ any.
+ */
+ get bidiLevel() {
+ let level = this.flags & 3 /* RangeFlag.BidiLevelMask */;
+ return level == 3 ? null : level;
+ }
+ /**
+ The goal column (stored vertical offset) associated with a
+ cursor. This is used to preserve the vertical position when
+ [moving](https://codemirror.net/6/docs/ref/#view.EditorView.moveVertically) across
+ lines of different length.
+ */
+ get goalColumn() {
+ let value = this.flags >> 5 /* RangeFlag.GoalColumnOffset */;
+ return value == 33554431 /* RangeFlag.NoGoalColumn */ ? undefined : value;
+ }
+ /**
+ Map this range through a change, producing a valid range in the
+ updated document.
+ */
+ map(change, assoc = -1) {
+ let from, to;
+ if (this.empty) {
+ from = to = change.mapPos(this.from, assoc);
+ }
+ else {
+ from = change.mapPos(this.from, 1);
+ to = change.mapPos(this.to, -1);
+ }
+ return from == this.from && to == this.to ? this : new SelectionRange(from, to, this.flags);
+ }
+ /**
+ Extend this range to cover at least `from` to `to`.
+ */
+ extend(from, to = from) {
+ if (from <= this.anchor && to >= this.anchor)
+ return EditorSelection.range(from, to);
+ let head = Math.abs(from - this.anchor) > Math.abs(to - this.anchor) ? from : to;
+ return EditorSelection.range(this.anchor, head);
+ }
+ /**
+ Compare this range to another range.
+ */
+ eq(other) {
+ return this.anchor == other.anchor && this.head == other.head;
+ }
+ /**
+ Return a JSON-serializable object representing the range.
+ */
+ toJSON() { return { anchor: this.anchor, head: this.head }; }
+ /**
+ Convert a JSON representation of a range to a `SelectionRange`
+ instance.
+ */
+ static fromJSON(json) {
+ if (!json || typeof json.anchor != "number" || typeof json.head != "number")
+ throw new RangeError("Invalid JSON representation for SelectionRange");
+ return EditorSelection.range(json.anchor, json.head);
+ }
+ /**
+ @internal
+ */
+ static create(from, to, flags) {
+ return new SelectionRange(from, to, flags);
+ }
+ }
+ /**
+ An editor selection holds one or more selection ranges.
+ */
+ class EditorSelection {
+ constructor(
+ /**
+ The ranges in the selection, sorted by position. Ranges cannot
+ overlap (but they may touch, if they aren't empty).
+ */
+ ranges,
+ /**
+ The index of the _main_ range in the selection (which is
+ usually the range that was added last).
+ */
+ mainIndex) {
+ this.ranges = ranges;
+ this.mainIndex = mainIndex;
+ }
+ /**
+ Map a selection through a change. Used to adjust the selection
+ position for changes.
+ */
+ map(change, assoc = -1) {
+ if (change.empty)
+ return this;
+ return EditorSelection.create(this.ranges.map(r => r.map(change, assoc)), this.mainIndex);
+ }
+ /**
+ Compare this selection to another selection.
+ */
+ eq(other) {
+ if (this.ranges.length != other.ranges.length ||
+ this.mainIndex != other.mainIndex)
+ return false;
+ for (let i = 0; i < this.ranges.length; i++)
+ if (!this.ranges[i].eq(other.ranges[i]))
+ return false;
+ return true;
+ }
+ /**
+ Get the primary selection range. Usually, you should make sure
+ your code applies to _all_ ranges, by using methods like
+ [`changeByRange`](https://codemirror.net/6/docs/ref/#state.EditorState.changeByRange).
+ */
+ get main() { return this.ranges[this.mainIndex]; }
+ /**
+ Make sure the selection only has one range. Returns a selection
+ holding only the main range from this selection.
+ */
+ asSingle() {
+ return this.ranges.length == 1 ? this : new EditorSelection([this.main], 0);
+ }
+ /**
+ Extend this selection with an extra range.
+ */
+ addRange(range, main = true) {
+ return EditorSelection.create([range].concat(this.ranges), main ? 0 : this.mainIndex + 1);
+ }
+ /**
+ Replace a given range with another range, and then normalize the
+ selection to merge and sort ranges if necessary.
+ */
+ replaceRange(range, which = this.mainIndex) {
+ let ranges = this.ranges.slice();
+ ranges[which] = range;
+ return EditorSelection.create(ranges, this.mainIndex);
+ }
+ /**
+ Convert this selection to an object that can be serialized to
+ JSON.
+ */
+ toJSON() {
+ return { ranges: this.ranges.map(r => r.toJSON()), main: this.mainIndex };
+ }
+ /**
+ Create a selection from a JSON representation.
+ */
+ static fromJSON(json) {
+ if (!json || !Array.isArray(json.ranges) || typeof json.main != "number" || json.main >= json.ranges.length)
+ throw new RangeError("Invalid JSON representation for EditorSelection");
+ return new EditorSelection(json.ranges.map((r) => SelectionRange.fromJSON(r)), json.main);
+ }
+ /**
+ Create a selection holding a single range.
+ */
+ static single(anchor, head = anchor) {
+ return new EditorSelection([EditorSelection.range(anchor, head)], 0);
+ }
+ /**
+ Sort and merge the given set of ranges, creating a valid
+ selection.
+ */
+ static create(ranges, mainIndex = 0) {
+ if (ranges.length == 0)
+ throw new RangeError("A selection needs at least one range");
+ for (let pos = 0, i = 0; i < ranges.length; i++) {
+ let range = ranges[i];
+ if (range.empty ? range.from <= pos : range.from < pos)
+ return EditorSelection.normalized(ranges.slice(), mainIndex);
+ pos = range.to;
+ }
+ return new EditorSelection(ranges, mainIndex);
+ }
+ /**
+ Create a cursor selection range at the given position. You can
+ safely ignore the optional arguments in most situations.
+ */
+ static cursor(pos, assoc = 0, bidiLevel, goalColumn) {
+ return SelectionRange.create(pos, pos, (assoc == 0 ? 0 : assoc < 0 ? 4 /* RangeFlag.AssocBefore */ : 8 /* RangeFlag.AssocAfter */) |
+ (bidiLevel == null ? 3 : Math.min(2, bidiLevel)) |
+ ((goalColumn !== null && goalColumn !== void 0 ? goalColumn : 33554431 /* RangeFlag.NoGoalColumn */) << 5 /* RangeFlag.GoalColumnOffset */));
+ }
+ /**
+ Create a selection range.
+ */
+ static range(anchor, head, goalColumn) {
+ let goal = (goalColumn !== null && goalColumn !== void 0 ? goalColumn : 33554431 /* RangeFlag.NoGoalColumn */) << 5 /* RangeFlag.GoalColumnOffset */;
+ return head < anchor ? SelectionRange.create(head, anchor, 16 /* RangeFlag.Inverted */ | goal | 8 /* RangeFlag.AssocAfter */)
+ : SelectionRange.create(anchor, head, goal | (head > anchor ? 4 /* RangeFlag.AssocBefore */ : 0));
+ }
+ /**
+ @internal
+ */
+ static normalized(ranges, mainIndex = 0) {
+ let main = ranges[mainIndex];
+ ranges.sort((a, b) => a.from - b.from);
+ mainIndex = ranges.indexOf(main);
+ for (let i = 1; i < ranges.length; i++) {
+ let range = ranges[i], prev = ranges[i - 1];
+ if (range.empty ? range.from <= prev.to : range.from < prev.to) {
+ let from = prev.from, to = Math.max(range.to, prev.to);
+ if (i <= mainIndex)
+ mainIndex--;
+ ranges.splice(--i, 2, range.anchor > range.head ? EditorSelection.range(to, from) : EditorSelection.range(from, to));
+ }
+ }
+ return new EditorSelection(ranges, mainIndex);
+ }
+ }
+ function checkSelection(selection, docLength) {
+ for (let range of selection.ranges)
+ if (range.to > docLength)
+ throw new RangeError("Selection points outside of document");
+ }
+
+ let nextID = 0;
+ /**
+ A facet is a labeled value that is associated with an editor
+ state. It takes inputs from any number of extensions, and combines
+ those into a single output value.
+
+ Examples of uses of facets are the [tab
+ size](https://codemirror.net/6/docs/ref/#state.EditorState^tabSize), [editor
+ attributes](https://codemirror.net/6/docs/ref/#view.EditorView^editorAttributes), and [update
+ listeners](https://codemirror.net/6/docs/ref/#view.EditorView^updateListener).
+ */
+ class Facet {
+ constructor(
+ /**
+ @internal
+ */
+ combine,
+ /**
+ @internal
+ */
+ compareInput,
+ /**
+ @internal
+ */
+ compare, isStatic, enables) {
+ this.combine = combine;
+ this.compareInput = compareInput;
+ this.compare = compare;
+ this.isStatic = isStatic;
+ /**
+ @internal
+ */
+ this.id = nextID++;
+ this.default = combine([]);
+ this.extensions = typeof enables == "function" ? enables(this) : enables;
+ }
+ /**
+ Define a new facet.
+ */
+ static define(config = {}) {
+ return new Facet(config.combine || ((a) => a), config.compareInput || ((a, b) => a === b), config.compare || (!config.combine ? sameArray$1 : (a, b) => a === b), !!config.static, config.enables);
+ }
+ /**
+ Returns an extension that adds the given value to this facet.
+ */
+ of(value) {
+ return new FacetProvider([], this, 0 /* Provider.Static */, value);
+ }
+ /**
+ Create an extension that computes a value for the facet from a
+ state. You must take care to declare the parts of the state that
+ this value depends on, since your function is only called again
+ for a new state when one of those parts changed.
+
+ In cases where your value depends only on a single field, you'll
+ want to use the [`from`](https://codemirror.net/6/docs/ref/#state.Facet.from) method instead.
+ */
+ compute(deps, get) {
+ if (this.isStatic)
+ throw new Error("Can't compute a static facet");
+ return new FacetProvider(deps, this, 1 /* Provider.Single */, get);
+ }
+ /**
+ Create an extension that computes zero or more values for this
+ facet from a state.
+ */
+ computeN(deps, get) {
+ if (this.isStatic)
+ throw new Error("Can't compute a static facet");
+ return new FacetProvider(deps, this, 2 /* Provider.Multi */, get);
+ }
+ from(field, get) {
+ if (!get)
+ get = x => x;
+ return this.compute([field], state => get(state.field(field)));
+ }
+ }
+ function sameArray$1(a, b) {
+ return a == b || a.length == b.length && a.every((e, i) => e === b[i]);
+ }
+ class FacetProvider {
+ constructor(dependencies, facet, type, value) {
+ this.dependencies = dependencies;
+ this.facet = facet;
+ this.type = type;
+ this.value = value;
+ this.id = nextID++;
+ }
+ dynamicSlot(addresses) {
+ var _a;
+ let getter = this.value;
+ let compare = this.facet.compareInput;
+ let id = this.id, idx = addresses[id] >> 1, multi = this.type == 2 /* Provider.Multi */;
+ let depDoc = false, depSel = false, depAddrs = [];
+ for (let dep of this.dependencies) {
+ if (dep == "doc")
+ depDoc = true;
+ else if (dep == "selection")
+ depSel = true;
+ else if ((((_a = addresses[dep.id]) !== null && _a !== void 0 ? _a : 1) & 1) == 0)
+ depAddrs.push(addresses[dep.id]);
+ }
+ return {
+ create(state) {
+ state.values[idx] = getter(state);
+ return 1 /* SlotStatus.Changed */;
+ },
+ update(state, tr) {
+ if ((depDoc && tr.docChanged) || (depSel && (tr.docChanged || tr.selection)) || ensureAll(state, depAddrs)) {
+ let newVal = getter(state);
+ if (multi ? !compareArray(newVal, state.values[idx], compare) : !compare(newVal, state.values[idx])) {
+ state.values[idx] = newVal;
+ return 1 /* SlotStatus.Changed */;
+ }
+ }
+ return 0;
+ },
+ reconfigure: (state, oldState) => {
+ let newVal = getter(state);
+ let oldAddr = oldState.config.address[id];
+ if (oldAddr != null) {
+ let oldVal = getAddr(oldState, oldAddr);
+ if (this.dependencies.every(dep => {
+ return dep instanceof Facet ? oldState.facet(dep) === state.facet(dep) :
+ dep instanceof StateField ? oldState.field(dep, false) == state.field(dep, false) : true;
+ }) || (multi ? compareArray(newVal, oldVal, compare) : compare(newVal, oldVal))) {
+ state.values[idx] = oldVal;
+ return 0;
+ }
+ }
+ state.values[idx] = newVal;
+ return 1 /* SlotStatus.Changed */;
+ }
+ };
+ }
+ }
+ function compareArray(a, b, compare) {
+ if (a.length != b.length)
+ return false;
+ for (let i = 0; i < a.length; i++)
+ if (!compare(a[i], b[i]))
+ return false;
+ return true;
+ }
+ function ensureAll(state, addrs) {
+ let changed = false;
+ for (let addr of addrs)
+ if (ensureAddr(state, addr) & 1 /* SlotStatus.Changed */)
+ changed = true;
+ return changed;
+ }
+ function dynamicFacetSlot(addresses, facet, providers) {
+ let providerAddrs = providers.map(p => addresses[p.id]);
+ let providerTypes = providers.map(p => p.type);
+ let dynamic = providerAddrs.filter(p => !(p & 1));
+ let idx = addresses[facet.id] >> 1;
+ function get(state) {
+ let values = [];
+ for (let i = 0; i < providerAddrs.length; i++) {
+ let value = getAddr(state, providerAddrs[i]);
+ if (providerTypes[i] == 2 /* Provider.Multi */)
+ for (let val of value)
+ values.push(val);
+ else
+ values.push(value);
+ }
+ return facet.combine(values);
+ }
+ return {
+ create(state) {
+ for (let addr of providerAddrs)
+ ensureAddr(state, addr);
+ state.values[idx] = get(state);
+ return 1 /* SlotStatus.Changed */;
+ },
+ update(state, tr) {
+ if (!ensureAll(state, dynamic))
+ return 0;
+ let value = get(state);
+ if (facet.compare(value, state.values[idx]))
+ return 0;
+ state.values[idx] = value;
+ return 1 /* SlotStatus.Changed */;
+ },
+ reconfigure(state, oldState) {
+ let depChanged = ensureAll(state, providerAddrs);
+ let oldProviders = oldState.config.facets[facet.id], oldValue = oldState.facet(facet);
+ if (oldProviders && !depChanged && sameArray$1(providers, oldProviders)) {
+ state.values[idx] = oldValue;
+ return 0;
+ }
+ let value = get(state);
+ if (facet.compare(value, oldValue)) {
+ state.values[idx] = oldValue;
+ return 0;
+ }
+ state.values[idx] = value;
+ return 1 /* SlotStatus.Changed */;
+ }
+ };
+ }
+ const initField = /*@__PURE__*/Facet.define({ static: true });
+ /**
+ Fields can store additional information in an editor state, and
+ keep it in sync with the rest of the state.
+ */
+ class StateField {
+ constructor(
+ /**
+ @internal
+ */
+ id, createF, updateF, compareF,
+ /**
+ @internal
+ */
+ spec) {
+ this.id = id;
+ this.createF = createF;
+ this.updateF = updateF;
+ this.compareF = compareF;
+ this.spec = spec;
+ /**
+ @internal
+ */
+ this.provides = undefined;
+ }
+ /**
+ Define a state field.
+ */
+ static define(config) {
+ let field = new StateField(nextID++, config.create, config.update, config.compare || ((a, b) => a === b), config);
+ if (config.provide)
+ field.provides = config.provide(field);
+ return field;
+ }
+ create(state) {
+ let init = state.facet(initField).find(i => i.field == this);
+ return ((init === null || init === void 0 ? void 0 : init.create) || this.createF)(state);
+ }
+ /**
+ @internal
+ */
+ slot(addresses) {
+ let idx = addresses[this.id] >> 1;
+ return {
+ create: (state) => {
+ state.values[idx] = this.create(state);
+ return 1 /* SlotStatus.Changed */;
+ },
+ update: (state, tr) => {
+ let oldVal = state.values[idx];
+ let value = this.updateF(oldVal, tr);
+ if (this.compareF(oldVal, value))
+ return 0;
+ state.values[idx] = value;
+ return 1 /* SlotStatus.Changed */;
+ },
+ reconfigure: (state, oldState) => {
+ if (oldState.config.address[this.id] != null) {
+ state.values[idx] = oldState.field(this);
+ return 0;
+ }
+ state.values[idx] = this.create(state);
+ return 1 /* SlotStatus.Changed */;
+ }
+ };
+ }
+ /**
+ Returns an extension that enables this field and overrides the
+ way it is initialized. Can be useful when you need to provide a
+ non-default starting value for the field.
+ */
+ init(create) {
+ return [this, initField.of({ field: this, create })];
+ }
+ /**
+ State field instances can be used as
+ [`Extension`](https://codemirror.net/6/docs/ref/#state.Extension) values to enable the field in a
+ given state.
+ */
+ get extension() { return this; }
+ }
+ const Prec_ = { lowest: 4, low: 3, default: 2, high: 1, highest: 0 };
+ function prec(value) {
+ return (ext) => new PrecExtension(ext, value);
+ }
+ /**
+ By default extensions are registered in the order they are found
+ in the flattened form of nested array that was provided.
+ Individual extension values can be assigned a precedence to
+ override this. Extensions that do not have a precedence set get
+ the precedence of the nearest parent with a precedence, or
+ [`default`](https://codemirror.net/6/docs/ref/#state.Prec.default) if there is no such parent. The
+ final ordering of extensions is determined by first sorting by
+ precedence and then by order within each precedence.
+ */
+ const Prec = {
+ /**
+ The highest precedence level, for extensions that should end up
+ near the start of the precedence ordering.
+ */
+ highest: /*@__PURE__*/prec(Prec_.highest),
+ /**
+ A higher-than-default precedence, for extensions that should
+ come before those with default precedence.
+ */
+ high: /*@__PURE__*/prec(Prec_.high),
+ /**
+ The default precedence, which is also used for extensions
+ without an explicit precedence.
+ */
+ default: /*@__PURE__*/prec(Prec_.default),
+ /**
+ A lower-than-default precedence.
+ */
+ low: /*@__PURE__*/prec(Prec_.low),
+ /**
+ The lowest precedence level. Meant for things that should end up
+ near the end of the extension order.
+ */
+ lowest: /*@__PURE__*/prec(Prec_.lowest)
+ };
+ class PrecExtension {
+ constructor(inner, prec) {
+ this.inner = inner;
+ this.prec = prec;
+ }
+ }
+ /**
+ Extension compartments can be used to make a configuration
+ dynamic. By [wrapping](https://codemirror.net/6/docs/ref/#state.Compartment.of) part of your
+ configuration in a compartment, you can later
+ [replace](https://codemirror.net/6/docs/ref/#state.Compartment.reconfigure) that part through a
+ transaction.
+ */
+ class Compartment {
+ /**
+ Create an instance of this compartment to add to your [state
+ configuration](https://codemirror.net/6/docs/ref/#state.EditorStateConfig.extensions).
+ */
+ of(ext) { return new CompartmentInstance(this, ext); }
+ /**
+ Create an [effect](https://codemirror.net/6/docs/ref/#state.TransactionSpec.effects) that
+ reconfigures this compartment.
+ */
+ reconfigure(content) {
+ return Compartment.reconfigure.of({ compartment: this, extension: content });
+ }
+ /**
+ Get the current content of the compartment in the state, or
+ `undefined` if it isn't present.
+ */
+ get(state) {
+ return state.config.compartments.get(this);
+ }
+ }
+ class CompartmentInstance {
+ constructor(compartment, inner) {
+ this.compartment = compartment;
+ this.inner = inner;
+ }
+ }
+ class Configuration {
+ constructor(base, compartments, dynamicSlots, address, staticValues, facets) {
+ this.base = base;
+ this.compartments = compartments;
+ this.dynamicSlots = dynamicSlots;
+ this.address = address;
+ this.staticValues = staticValues;
+ this.facets = facets;
+ this.statusTemplate = [];
+ while (this.statusTemplate.length < dynamicSlots.length)
+ this.statusTemplate.push(0 /* SlotStatus.Unresolved */);
+ }
+ staticFacet(facet) {
+ let addr = this.address[facet.id];
+ return addr == null ? facet.default : this.staticValues[addr >> 1];
+ }
+ static resolve(base, compartments, oldState) {
+ let fields = [];
+ let facets = Object.create(null);
+ let newCompartments = new Map();
+ for (let ext of flatten(base, compartments, newCompartments)) {
+ if (ext instanceof StateField)
+ fields.push(ext);
+ else
+ (facets[ext.facet.id] || (facets[ext.facet.id] = [])).push(ext);
+ }
+ let address = Object.create(null);
+ let staticValues = [];
+ let dynamicSlots = [];
+ for (let field of fields) {
+ address[field.id] = dynamicSlots.length << 1;
+ dynamicSlots.push(a => field.slot(a));
+ }
+ let oldFacets = oldState === null || oldState === void 0 ? void 0 : oldState.config.facets;
+ for (let id in facets) {
+ let providers = facets[id], facet = providers[0].facet;
+ let oldProviders = oldFacets && oldFacets[id] || [];
+ if (providers.every(p => p.type == 0 /* Provider.Static */)) {
+ address[facet.id] = (staticValues.length << 1) | 1;
+ if (sameArray$1(oldProviders, providers)) {
+ staticValues.push(oldState.facet(facet));
+ }
+ else {
+ let value = facet.combine(providers.map(p => p.value));
+ staticValues.push(oldState && facet.compare(value, oldState.facet(facet)) ? oldState.facet(facet) : value);
+ }
+ }
+ else {
+ for (let p of providers) {
+ if (p.type == 0 /* Provider.Static */) {
+ address[p.id] = (staticValues.length << 1) | 1;
+ staticValues.push(p.value);
+ }
+ else {
+ address[p.id] = dynamicSlots.length << 1;
+ dynamicSlots.push(a => p.dynamicSlot(a));
+ }
+ }
+ address[facet.id] = dynamicSlots.length << 1;
+ dynamicSlots.push(a => dynamicFacetSlot(a, facet, providers));
+ }
+ }
+ let dynamic = dynamicSlots.map(f => f(address));
+ return new Configuration(base, newCompartments, dynamic, address, staticValues, facets);
+ }
+ }
+ function flatten(extension, compartments, newCompartments) {
+ let result = [[], [], [], [], []];
+ let seen = new Map();
+ function inner(ext, prec) {
+ let known = seen.get(ext);
+ if (known != null) {
+ if (known <= prec)
+ return;
+ let found = result[known].indexOf(ext);
+ if (found > -1)
+ result[known].splice(found, 1);
+ if (ext instanceof CompartmentInstance)
+ newCompartments.delete(ext.compartment);
+ }
+ seen.set(ext, prec);
+ if (Array.isArray(ext)) {
+ for (let e of ext)
+ inner(e, prec);
+ }
+ else if (ext instanceof CompartmentInstance) {
+ if (newCompartments.has(ext.compartment))
+ throw new RangeError(`Duplicate use of compartment in extensions`);
+ let content = compartments.get(ext.compartment) || ext.inner;
+ newCompartments.set(ext.compartment, content);
+ inner(content, prec);
+ }
+ else if (ext instanceof PrecExtension) {
+ inner(ext.inner, ext.prec);
+ }
+ else if (ext instanceof StateField) {
+ result[prec].push(ext);
+ if (ext.provides)
+ inner(ext.provides, prec);
+ }
+ else if (ext instanceof FacetProvider) {
+ result[prec].push(ext);
+ if (ext.facet.extensions)
+ inner(ext.facet.extensions, Prec_.default);
+ }
+ else {
+ let content = ext.extension;
+ if (!content)
+ throw new Error(`Unrecognized extension value in extension set (${ext}). This sometimes happens because multiple instances of @codemirror/state are loaded, breaking instanceof checks.`);
+ inner(content, prec);
+ }
+ }
+ inner(extension, Prec_.default);
+ return result.reduce((a, b) => a.concat(b));
+ }
+ function ensureAddr(state, addr) {
+ if (addr & 1)
+ return 2 /* SlotStatus.Computed */;
+ let idx = addr >> 1;
+ let status = state.status[idx];
+ if (status == 4 /* SlotStatus.Computing */)
+ throw new Error("Cyclic dependency between fields and/or facets");
+ if (status & 2 /* SlotStatus.Computed */)
+ return status;
+ state.status[idx] = 4 /* SlotStatus.Computing */;
+ let changed = state.computeSlot(state, state.config.dynamicSlots[idx]);
+ return state.status[idx] = 2 /* SlotStatus.Computed */ | changed;
+ }
+ function getAddr(state, addr) {
+ return addr & 1 ? state.config.staticValues[addr >> 1] : state.values[addr >> 1];
+ }
+
+ const languageData = /*@__PURE__*/Facet.define();
+ const allowMultipleSelections = /*@__PURE__*/Facet.define({
+ combine: values => values.some(v => v),
+ static: true
+ });
+ const lineSeparator = /*@__PURE__*/Facet.define({
+ combine: values => values.length ? values[0] : undefined,
+ static: true
+ });
+ const changeFilter = /*@__PURE__*/Facet.define();
+ const transactionFilter = /*@__PURE__*/Facet.define();
+ const transactionExtender = /*@__PURE__*/Facet.define();
+ const readOnly = /*@__PURE__*/Facet.define({
+ combine: values => values.length ? values[0] : false
+ });
+
+ /**
+ Annotations are tagged values that are used to add metadata to
+ transactions in an extensible way. They should be used to model
+ things that effect the entire transaction (such as its [time
+ stamp](https://codemirror.net/6/docs/ref/#state.Transaction^time) or information about its
+ [origin](https://codemirror.net/6/docs/ref/#state.Transaction^userEvent)). For effects that happen
+ _alongside_ the other changes made by the transaction, [state
+ effects](https://codemirror.net/6/docs/ref/#state.StateEffect) are more appropriate.
+ */
+ class Annotation {
+ /**
+ @internal
+ */
+ constructor(
+ /**
+ The annotation type.
+ */
+ type,
+ /**
+ The value of this annotation.
+ */
+ value) {
+ this.type = type;
+ this.value = value;
+ }
+ /**
+ Define a new type of annotation.
+ */
+ static define() { return new AnnotationType(); }
+ }
+ /**
+ Marker that identifies a type of [annotation](https://codemirror.net/6/docs/ref/#state.Annotation).
+ */
+ class AnnotationType {
+ /**
+ Create an instance of this annotation.
+ */
+ of(value) { return new Annotation(this, value); }
+ }
+ /**
+ Representation of a type of state effect. Defined with
+ [`StateEffect.define`](https://codemirror.net/6/docs/ref/#state.StateEffect^define).
+ */
+ class StateEffectType {
+ /**
+ @internal
+ */
+ constructor(
+ // The `any` types in these function types are there to work
+ // around TypeScript issue #37631, where the type guard on
+ // `StateEffect.is` mysteriously stops working when these properly
+ // have type `Value`.
+ /**
+ @internal
+ */
+ map) {
+ this.map = map;
+ }
+ /**
+ Create a [state effect](https://codemirror.net/6/docs/ref/#state.StateEffect) instance of this
+ type.
+ */
+ of(value) { return new StateEffect(this, value); }
+ }
+ /**
+ State effects can be used to represent additional effects
+ associated with a [transaction](https://codemirror.net/6/docs/ref/#state.Transaction.effects). They
+ are often useful to model changes to custom [state
+ fields](https://codemirror.net/6/docs/ref/#state.StateField), when those changes aren't implicit in
+ document or selection changes.
+ */
+ class StateEffect {
+ /**
+ @internal
+ */
+ constructor(
+ /**
+ @internal
+ */
+ type,
+ /**
+ The value of this effect.
+ */
+ value) {
+ this.type = type;
+ this.value = value;
+ }
+ /**
+ Map this effect through a position mapping. Will return
+ `undefined` when that ends up deleting the effect.
+ */
+ map(mapping) {
+ let mapped = this.type.map(this.value, mapping);
+ return mapped === undefined ? undefined : mapped == this.value ? this : new StateEffect(this.type, mapped);
+ }
+ /**
+ Tells you whether this effect object is of a given
+ [type](https://codemirror.net/6/docs/ref/#state.StateEffectType).
+ */
+ is(type) { return this.type == type; }
+ /**
+ Define a new effect type. The type parameter indicates the type
+ of values that his effect holds.
+ */
+ static define(spec = {}) {
+ return new StateEffectType(spec.map || (v => v));
+ }
+ /**
+ Map an array of effects through a change set.
+ */
+ static mapEffects(effects, mapping) {
+ if (!effects.length)
+ return effects;
+ let result = [];
+ for (let effect of effects) {
+ let mapped = effect.map(mapping);
+ if (mapped)
+ result.push(mapped);
+ }
+ return result;
+ }
+ }
+ /**
+ This effect can be used to reconfigure the root extensions of
+ the editor. Doing this will discard any extensions
+ [appended](https://codemirror.net/6/docs/ref/#state.StateEffect^appendConfig), but does not reset
+ the content of [reconfigured](https://codemirror.net/6/docs/ref/#state.Compartment.reconfigure)
+ compartments.
+ */
+ StateEffect.reconfigure = /*@__PURE__*/StateEffect.define();
+ /**
+ Append extensions to the top-level configuration of the editor.
+ */
+ StateEffect.appendConfig = /*@__PURE__*/StateEffect.define();
+ /**
+ Changes to the editor state are grouped into transactions.
+ Typically, a user action creates a single transaction, which may
+ contain any number of document changes, may change the selection,
+ or have other effects. Create a transaction by calling
+ [`EditorState.update`](https://codemirror.net/6/docs/ref/#state.EditorState.update), or immediately
+ dispatch one by calling
+ [`EditorView.dispatch`](https://codemirror.net/6/docs/ref/#view.EditorView.dispatch).
+ */
+ class Transaction {
+ constructor(
+ /**
+ The state from which the transaction starts.
+ */
+ startState,
+ /**
+ The document changes made by this transaction.
+ */
+ changes,
+ /**
+ The selection set by this transaction, or undefined if it
+ doesn't explicitly set a selection.
+ */
+ selection,
+ /**
+ The effects added to the transaction.
+ */
+ effects,
+ /**
+ @internal
+ */
+ annotations,
+ /**
+ Whether the selection should be scrolled into view after this
+ transaction is dispatched.
+ */
+ scrollIntoView) {
+ this.startState = startState;
+ this.changes = changes;
+ this.selection = selection;
+ this.effects = effects;
+ this.annotations = annotations;
+ this.scrollIntoView = scrollIntoView;
+ /**
+ @internal
+ */
+ this._doc = null;
+ /**
+ @internal
+ */
+ this._state = null;
+ if (selection)
+ checkSelection(selection, changes.newLength);
+ if (!annotations.some((a) => a.type == Transaction.time))
+ this.annotations = annotations.concat(Transaction.time.of(Date.now()));
+ }
+ /**
+ @internal
+ */
+ static create(startState, changes, selection, effects, annotations, scrollIntoView) {
+ return new Transaction(startState, changes, selection, effects, annotations, scrollIntoView);
+ }
+ /**
+ The new document produced by the transaction. Contrary to
+ [`.state`](https://codemirror.net/6/docs/ref/#state.Transaction.state)`.doc`, accessing this won't
+ force the entire new state to be computed right away, so it is
+ recommended that [transaction
+ filters](https://codemirror.net/6/docs/ref/#state.EditorState^transactionFilter) use this getter
+ when they need to look at the new document.
+ */
+ get newDoc() {
+ return this._doc || (this._doc = this.changes.apply(this.startState.doc));
+ }
+ /**
+ The new selection produced by the transaction. If
+ [`this.selection`](https://codemirror.net/6/docs/ref/#state.Transaction.selection) is undefined,
+ this will [map](https://codemirror.net/6/docs/ref/#state.EditorSelection.map) the start state's
+ current selection through the changes made by the transaction.
+ */
+ get newSelection() {
+ return this.selection || this.startState.selection.map(this.changes);
+ }
+ /**
+ The new state created by the transaction. Computed on demand
+ (but retained for subsequent access), so it is recommended not to
+ access it in [transaction
+ filters](https://codemirror.net/6/docs/ref/#state.EditorState^transactionFilter) when possible.
+ */
+ get state() {
+ if (!this._state)
+ this.startState.applyTransaction(this);
+ return this._state;
+ }
+ /**
+ Get the value of the given annotation type, if any.
+ */
+ annotation(type) {
+ for (let ann of this.annotations)
+ if (ann.type == type)
+ return ann.value;
+ return undefined;
+ }
+ /**
+ Indicates whether the transaction changed the document.
+ */
+ get docChanged() { return !this.changes.empty; }
+ /**
+ Indicates whether this transaction reconfigures the state
+ (through a [configuration compartment](https://codemirror.net/6/docs/ref/#state.Compartment) or
+ with a top-level configuration
+ [effect](https://codemirror.net/6/docs/ref/#state.StateEffect^reconfigure).
+ */
+ get reconfigured() { return this.startState.config != this.state.config; }
+ /**
+ Returns true if the transaction has a [user
+ event](https://codemirror.net/6/docs/ref/#state.Transaction^userEvent) annotation that is equal to
+ or more specific than `event`. For example, if the transaction
+ has `"select.pointer"` as user event, `"select"` and
+ `"select.pointer"` will match it.
+ */
+ isUserEvent(event) {
+ let e = this.annotation(Transaction.userEvent);
+ return !!(e && (e == event || e.length > event.length && e.slice(0, event.length) == event && e[event.length] == "."));
+ }
+ }
+ /**
+ Annotation used to store transaction timestamps. Automatically
+ added to every transaction, holding `Date.now()`.
+ */
+ Transaction.time = /*@__PURE__*/Annotation.define();
+ /**
+ Annotation used to associate a transaction with a user interface
+ event. Holds a string identifying the event, using a
+ dot-separated format to support attaching more specific
+ information. The events used by the core libraries are:
+
+ - `"input"` when content is entered
+ - `"input.type"` for typed input
+ - `"input.type.compose"` for composition
+ - `"input.paste"` for pasted input
+ - `"input.drop"` when adding content with drag-and-drop
+ - `"input.complete"` when autocompleting
+ - `"delete"` when the user deletes content
+ - `"delete.selection"` when deleting the selection
+ - `"delete.forward"` when deleting forward from the selection
+ - `"delete.backward"` when deleting backward from the selection
+ - `"delete.cut"` when cutting to the clipboard
+ - `"move"` when content is moved
+ - `"move.drop"` when content is moved within the editor through drag-and-drop
+ - `"select"` when explicitly changing the selection
+ - `"select.pointer"` when selecting with a mouse or other pointing device
+ - `"undo"` and `"redo"` for history actions
+
+ Use [`isUserEvent`](https://codemirror.net/6/docs/ref/#state.Transaction.isUserEvent) to check
+ whether the annotation matches a given event.
+ */
+ Transaction.userEvent = /*@__PURE__*/Annotation.define();
+ /**
+ Annotation indicating whether a transaction should be added to
+ the undo history or not.
+ */
+ Transaction.addToHistory = /*@__PURE__*/Annotation.define();
+ /**
+ Annotation indicating (when present and true) that a transaction
+ represents a change made by some other actor, not the user. This
+ is used, for example, to tag other people's changes in
+ collaborative editing.
+ */
+ Transaction.remote = /*@__PURE__*/Annotation.define();
+ function joinRanges(a, b) {
+ let result = [];
+ for (let iA = 0, iB = 0;;) {
+ let from, to;
+ if (iA < a.length && (iB == b.length || b[iB] >= a[iA])) {
+ from = a[iA++];
+ to = a[iA++];
+ }
+ else if (iB < b.length) {
+ from = b[iB++];
+ to = b[iB++];
+ }
+ else
+ return result;
+ if (!result.length || result[result.length - 1] < from)
+ result.push(from, to);
+ else if (result[result.length - 1] < to)
+ result[result.length - 1] = to;
+ }
+ }
+ function mergeTransaction(a, b, sequential) {
+ var _a;
+ let mapForA, mapForB, changes;
+ if (sequential) {
+ mapForA = b.changes;
+ mapForB = ChangeSet.empty(b.changes.length);
+ changes = a.changes.compose(b.changes);
+ }
+ else {
+ mapForA = b.changes.map(a.changes);
+ mapForB = a.changes.mapDesc(b.changes, true);
+ changes = a.changes.compose(mapForA);
+ }
+ return {
+ changes,
+ selection: b.selection ? b.selection.map(mapForB) : (_a = a.selection) === null || _a === void 0 ? void 0 : _a.map(mapForA),
+ effects: StateEffect.mapEffects(a.effects, mapForA).concat(StateEffect.mapEffects(b.effects, mapForB)),
+ annotations: a.annotations.length ? a.annotations.concat(b.annotations) : b.annotations,
+ scrollIntoView: a.scrollIntoView || b.scrollIntoView
+ };
+ }
+ function resolveTransactionInner(state, spec, docSize) {
+ let sel = spec.selection, annotations = asArray$1(spec.annotations);
+ if (spec.userEvent)
+ annotations = annotations.concat(Transaction.userEvent.of(spec.userEvent));
+ return {
+ changes: spec.changes instanceof ChangeSet ? spec.changes
+ : ChangeSet.of(spec.changes || [], docSize, state.facet(lineSeparator)),
+ selection: sel && (sel instanceof EditorSelection ? sel : EditorSelection.single(sel.anchor, sel.head)),
+ effects: asArray$1(spec.effects),
+ annotations,
+ scrollIntoView: !!spec.scrollIntoView
+ };
+ }
+ function resolveTransaction(state, specs, filter) {
+ let s = resolveTransactionInner(state, specs.length ? specs[0] : {}, state.doc.length);
+ if (specs.length && specs[0].filter === false)
+ filter = false;
+ for (let i = 1; i < specs.length; i++) {
+ if (specs[i].filter === false)
+ filter = false;
+ let seq = !!specs[i].sequential;
+ s = mergeTransaction(s, resolveTransactionInner(state, specs[i], seq ? s.changes.newLength : state.doc.length), seq);
+ }
+ let tr = Transaction.create(state, s.changes, s.selection, s.effects, s.annotations, s.scrollIntoView);
+ return extendTransaction(filter ? filterTransaction(tr) : tr);
+ }
+ // Finish a transaction by applying filters if necessary.
+ function filterTransaction(tr) {
+ let state = tr.startState;
+ // Change filters
+ let result = true;
+ for (let filter of state.facet(changeFilter)) {
+ let value = filter(tr);
+ if (value === false) {
+ result = false;
+ break;
+ }
+ if (Array.isArray(value))
+ result = result === true ? value : joinRanges(result, value);
+ }
+ if (result !== true) {
+ let changes, back;
+ if (result === false) {
+ back = tr.changes.invertedDesc;
+ changes = ChangeSet.empty(state.doc.length);
+ }
+ else {
+ let filtered = tr.changes.filter(result);
+ changes = filtered.changes;
+ back = filtered.filtered.mapDesc(filtered.changes).invertedDesc;
+ }
+ tr = Transaction.create(state, changes, tr.selection && tr.selection.map(back), StateEffect.mapEffects(tr.effects, back), tr.annotations, tr.scrollIntoView);
+ }
+ // Transaction filters
+ let filters = state.facet(transactionFilter);
+ for (let i = filters.length - 1; i >= 0; i--) {
+ let filtered = filters[i](tr);
+ if (filtered instanceof Transaction)
+ tr = filtered;
+ else if (Array.isArray(filtered) && filtered.length == 1 && filtered[0] instanceof Transaction)
+ tr = filtered[0];
+ else
+ tr = resolveTransaction(state, asArray$1(filtered), false);
+ }
+ return tr;
+ }
+ function extendTransaction(tr) {
+ let state = tr.startState, extenders = state.facet(transactionExtender), spec = tr;
+ for (let i = extenders.length - 1; i >= 0; i--) {
+ let extension = extenders[i](tr);
+ if (extension && Object.keys(extension).length)
+ spec = mergeTransaction(spec, resolveTransactionInner(state, extension, tr.changes.newLength), true);
+ }
+ return spec == tr ? tr : Transaction.create(state, tr.changes, tr.selection, spec.effects, spec.annotations, spec.scrollIntoView);
+ }
+ const none$2 = [];
+ function asArray$1(value) {
+ return value == null ? none$2 : Array.isArray(value) ? value : [value];
+ }
+
+ /**
+ The categories produced by a [character
+ categorizer](https://codemirror.net/6/docs/ref/#state.EditorState.charCategorizer). These are used
+ do things like selecting by word.
+ */
+ var CharCategory = /*@__PURE__*/(function (CharCategory) {
+ /**
+ Word characters.
+ */
+ CharCategory[CharCategory["Word"] = 0] = "Word";
+ /**
+ Whitespace.
+ */
+ CharCategory[CharCategory["Space"] = 1] = "Space";
+ /**
+ Anything else.
+ */
+ CharCategory[CharCategory["Other"] = 2] = "Other";
+ return CharCategory})(CharCategory || (CharCategory = {}));
+ const nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
+ let wordChar;
+ try {
+ wordChar = /*@__PURE__*/new RegExp("[\\p{Alphabetic}\\p{Number}_]", "u");
+ }
+ catch (_) { }
+ function hasWordChar(str) {
+ if (wordChar)
+ return wordChar.test(str);
+ for (let i = 0; i < str.length; i++) {
+ let ch = str[i];
+ if (/\w/.test(ch) || ch > "\x80" && (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch)))
+ return true;
+ }
+ return false;
+ }
+ function makeCategorizer(wordChars) {
+ return (char) => {
+ if (!/\S/.test(char))
+ return CharCategory.Space;
+ if (hasWordChar(char))
+ return CharCategory.Word;
+ for (let i = 0; i < wordChars.length; i++)
+ if (char.indexOf(wordChars[i]) > -1)
+ return CharCategory.Word;
+ return CharCategory.Other;
+ };
+ }
+
+ /**
+ The editor state class is a persistent (immutable) data structure.
+ To update a state, you [create](https://codemirror.net/6/docs/ref/#state.EditorState.update) a
+ [transaction](https://codemirror.net/6/docs/ref/#state.Transaction), which produces a _new_ state
+ instance, without modifying the original object.
+
+ As such, _never_ mutate properties of a state directly. That'll
+ just break things.
+ */
+ class EditorState {
+ constructor(
+ /**
+ @internal
+ */
+ config,
+ /**
+ The current document.
+ */
+ doc,
+ /**
+ The current selection.
+ */
+ selection,
+ /**
+ @internal
+ */
+ values, computeSlot, tr) {
+ this.config = config;
+ this.doc = doc;
+ this.selection = selection;
+ this.values = values;
+ this.status = config.statusTemplate.slice();
+ this.computeSlot = computeSlot;
+ // Fill in the computed state immediately, so that further queries
+ // for it made during the update return this state
+ if (tr)
+ tr._state = this;
+ for (let i = 0; i < this.config.dynamicSlots.length; i++)
+ ensureAddr(this, i << 1);
+ this.computeSlot = null;
+ }
+ field(field, require = true) {
+ let addr = this.config.address[field.id];
+ if (addr == null) {
+ if (require)
+ throw new RangeError("Field is not present in this state");
+ return undefined;
+ }
+ ensureAddr(this, addr);
+ return getAddr(this, addr);
+ }
+ /**
+ Create a [transaction](https://codemirror.net/6/docs/ref/#state.Transaction) that updates this
+ state. Any number of [transaction specs](https://codemirror.net/6/docs/ref/#state.TransactionSpec)
+ can be passed. Unless
+ [`sequential`](https://codemirror.net/6/docs/ref/#state.TransactionSpec.sequential) is set, the
+ [changes](https://codemirror.net/6/docs/ref/#state.TransactionSpec.changes) (if any) of each spec
+ are assumed to start in the _current_ document (not the document
+ produced by previous specs), and its
+ [selection](https://codemirror.net/6/docs/ref/#state.TransactionSpec.selection) and
+ [effects](https://codemirror.net/6/docs/ref/#state.TransactionSpec.effects) are assumed to refer
+ to the document created by its _own_ changes. The resulting
+ transaction contains the combined effect of all the different
+ specs. For [selection](https://codemirror.net/6/docs/ref/#state.TransactionSpec.selection), later
+ specs take precedence over earlier ones.
+ */
+ update(...specs) {
+ return resolveTransaction(this, specs, true);
+ }
+ /**
+ @internal
+ */
+ applyTransaction(tr) {
+ let conf = this.config, { base, compartments } = conf;
+ for (let effect of tr.effects) {
+ if (effect.is(Compartment.reconfigure)) {
+ if (conf) {
+ compartments = new Map;
+ conf.compartments.forEach((val, key) => compartments.set(key, val));
+ conf = null;
+ }
+ compartments.set(effect.value.compartment, effect.value.extension);
+ }
+ else if (effect.is(StateEffect.reconfigure)) {
+ conf = null;
+ base = effect.value;
+ }
+ else if (effect.is(StateEffect.appendConfig)) {
+ conf = null;
+ base = asArray$1(base).concat(effect.value);
+ }
+ }
+ let startValues;
+ if (!conf) {
+ conf = Configuration.resolve(base, compartments, this);
+ let intermediateState = new EditorState(conf, this.doc, this.selection, conf.dynamicSlots.map(() => null), (state, slot) => slot.reconfigure(state, this), null);
+ startValues = intermediateState.values;
+ }
+ else {
+ startValues = tr.startState.values.slice();
+ }
+ new EditorState(conf, tr.newDoc, tr.newSelection, startValues, (state, slot) => slot.update(state, tr), tr);
+ }
+ /**
+ Create a [transaction spec](https://codemirror.net/6/docs/ref/#state.TransactionSpec) that
+ replaces every selection range with the given content.
+ */
+ replaceSelection(text) {
+ if (typeof text == "string")
+ text = this.toText(text);
+ return this.changeByRange(range => ({ changes: { from: range.from, to: range.to, insert: text },
+ range: EditorSelection.cursor(range.from + text.length) }));
+ }
+ /**
+ Create a set of changes and a new selection by running the given
+ function for each range in the active selection. The function
+ can return an optional set of changes (in the coordinate space
+ of the start document), plus an updated range (in the coordinate
+ space of the document produced by the call's own changes). This
+ method will merge all the changes and ranges into a single
+ changeset and selection, and return it as a [transaction
+ spec](https://codemirror.net/6/docs/ref/#state.TransactionSpec), which can be passed to
+ [`update`](https://codemirror.net/6/docs/ref/#state.EditorState.update).
+ */
+ changeByRange(f) {
+ let sel = this.selection;
+ let result1 = f(sel.ranges[0]);
+ let changes = this.changes(result1.changes), ranges = [result1.range];
+ let effects = asArray$1(result1.effects);
+ for (let i = 1; i < sel.ranges.length; i++) {
+ let result = f(sel.ranges[i]);
+ let newChanges = this.changes(result.changes), newMapped = newChanges.map(changes);
+ for (let j = 0; j < i; j++)
+ ranges[j] = ranges[j].map(newMapped);
+ let mapBy = changes.mapDesc(newChanges, true);
+ ranges.push(result.range.map(mapBy));
+ changes = changes.compose(newMapped);
+ effects = StateEffect.mapEffects(effects, newMapped).concat(StateEffect.mapEffects(asArray$1(result.effects), mapBy));
+ }
+ return {
+ changes,
+ selection: EditorSelection.create(ranges, sel.mainIndex),
+ effects
+ };
+ }
+ /**
+ Create a [change set](https://codemirror.net/6/docs/ref/#state.ChangeSet) from the given change
+ description, taking the state's document length and line
+ separator into account.
+ */
+ changes(spec = []) {
+ if (spec instanceof ChangeSet)
+ return spec;
+ return ChangeSet.of(spec, this.doc.length, this.facet(EditorState.lineSeparator));
+ }
+ /**
+ Using the state's [line
+ separator](https://codemirror.net/6/docs/ref/#state.EditorState^lineSeparator), create a
+ [`Text`](https://codemirror.net/6/docs/ref/#state.Text) instance from the given string.
+ */
+ toText(string) {
+ return Text.of(string.split(this.facet(EditorState.lineSeparator) || DefaultSplit));
+ }
+ /**
+ Return the given range of the document as a string.
+ */
+ sliceDoc(from = 0, to = this.doc.length) {
+ return this.doc.sliceString(from, to, this.lineBreak);
+ }
+ /**
+ Get the value of a state [facet](https://codemirror.net/6/docs/ref/#state.Facet).
+ */
+ facet(facet) {
+ let addr = this.config.address[facet.id];
+ if (addr == null)
+ return facet.default;
+ ensureAddr(this, addr);
+ return getAddr(this, addr);
+ }
+ /**
+ Convert this state to a JSON-serializable object. When custom
+ fields should be serialized, you can pass them in as an object
+ mapping property names (in the resulting object, which should
+ not use `doc` or `selection`) to fields.
+ */
+ toJSON(fields) {
+ let result = {
+ doc: this.sliceDoc(),
+ selection: this.selection.toJSON()
+ };
+ if (fields)
+ for (let prop in fields) {
+ let value = fields[prop];
+ if (value instanceof StateField && this.config.address[value.id] != null)
+ result[prop] = value.spec.toJSON(this.field(fields[prop]), this);
+ }
+ return result;
+ }
+ /**
+ Deserialize a state from its JSON representation. When custom
+ fields should be deserialized, pass the same object you passed
+ to [`toJSON`](https://codemirror.net/6/docs/ref/#state.EditorState.toJSON) when serializing as
+ third argument.
+ */
+ static fromJSON(json, config = {}, fields) {
+ if (!json || typeof json.doc != "string")
+ throw new RangeError("Invalid JSON representation for EditorState");
+ let fieldInit = [];
+ if (fields)
+ for (let prop in fields) {
+ if (Object.prototype.hasOwnProperty.call(json, prop)) {
+ let field = fields[prop], value = json[prop];
+ fieldInit.push(field.init(state => field.spec.fromJSON(value, state)));
+ }
+ }
+ return EditorState.create({
+ doc: json.doc,
+ selection: EditorSelection.fromJSON(json.selection),
+ extensions: config.extensions ? fieldInit.concat([config.extensions]) : fieldInit
+ });
+ }
+ /**
+ Create a new state. You'll usually only need this when
+ initializing an editor—updated states are created by applying
+ transactions.
+ */
+ static create(config = {}) {
+ let configuration = Configuration.resolve(config.extensions || [], new Map);
+ let doc = config.doc instanceof Text ? config.doc
+ : Text.of((config.doc || "").split(configuration.staticFacet(EditorState.lineSeparator) || DefaultSplit));
+ let selection = !config.selection ? EditorSelection.single(0)
+ : config.selection instanceof EditorSelection ? config.selection
+ : EditorSelection.single(config.selection.anchor, config.selection.head);
+ checkSelection(selection, doc.length);
+ if (!configuration.staticFacet(allowMultipleSelections))
+ selection = selection.asSingle();
+ return new EditorState(configuration, doc, selection, configuration.dynamicSlots.map(() => null), (state, slot) => slot.create(state), null);
+ }
+ /**
+ The size (in columns) of a tab in the document, determined by
+ the [`tabSize`](https://codemirror.net/6/docs/ref/#state.EditorState^tabSize) facet.
+ */
+ get tabSize() { return this.facet(EditorState.tabSize); }
+ /**
+ Get the proper [line-break](https://codemirror.net/6/docs/ref/#state.EditorState^lineSeparator)
+ string for this state.
+ */
+ get lineBreak() { return this.facet(EditorState.lineSeparator) || "\n"; }
+ /**
+ Returns true when the editor is
+ [configured](https://codemirror.net/6/docs/ref/#state.EditorState^readOnly) to be read-only.
+ */
+ get readOnly() { return this.facet(readOnly); }
+ /**
+ Look up a translation for the given phrase (via the
+ [`phrases`](https://codemirror.net/6/docs/ref/#state.EditorState^phrases) facet), or return the
+ original string if no translation is found.
+
+ If additional arguments are passed, they will be inserted in
+ place of markers like `$1` (for the first value) and `$2`, etc.
+ A single `$` is equivalent to `$1`, and `$$` will produce a
+ literal dollar sign.
+ */
+ phrase(phrase, ...insert) {
+ for (let map of this.facet(EditorState.phrases))
+ if (Object.prototype.hasOwnProperty.call(map, phrase)) {
+ phrase = map[phrase];
+ break;
+ }
+ if (insert.length)
+ phrase = phrase.replace(/\$(\$|\d*)/g, (m, i) => {
+ if (i == "$")
+ return "$";
+ let n = +(i || 1);
+ return !n || n > insert.length ? m : insert[n - 1];
+ });
+ return phrase;
+ }
+ /**
+ Find the values for a given language data field, provided by the
+ the [`languageData`](https://codemirror.net/6/docs/ref/#state.EditorState^languageData) facet.
+ */
+ languageDataAt(name, pos, side = -1) {
+ let values = [];
+ for (let provider of this.facet(languageData)) {
+ for (let result of provider(this, pos, side)) {
+ if (Object.prototype.hasOwnProperty.call(result, name))
+ values.push(result[name]);
+ }
+ }
+ return values;
+ }
+ /**
+ Return a function that can categorize strings (expected to
+ represent a single [grapheme cluster](https://codemirror.net/6/docs/ref/#state.findClusterBreak))
+ into one of:
+
+ - Word (contains an alphanumeric character or a character
+ explicitly listed in the local language's `"wordChars"`
+ language data, which should be a string)
+ - Space (contains only whitespace)
+ - Other (anything else)
+ */
+ charCategorizer(at) {
+ return makeCategorizer(this.languageDataAt("wordChars", at).join(""));
+ }
+ /**
+ Find the word at the given position, meaning the range
+ containing all [word](https://codemirror.net/6/docs/ref/#state.CharCategory.Word) characters
+ around it. If no word characters are adjacent to the position,
+ this returns null.
+ */
+ wordAt(pos) {
+ let { text, from, length } = this.doc.lineAt(pos);
+ let cat = this.charCategorizer(pos);
+ let start = pos - from, end = pos - from;
+ while (start > 0) {
+ let prev = findClusterBreak(text, start, false);
+ if (cat(text.slice(prev, start)) != CharCategory.Word)
+ break;
+ start = prev;
+ }
+ while (end < length) {
+ let next = findClusterBreak(text, end);
+ if (cat(text.slice(end, next)) != CharCategory.Word)
+ break;
+ end = next;
+ }
+ return start == end ? null : EditorSelection.range(start + from, end + from);
+ }
+ }
+ /**
+ A facet that, when enabled, causes the editor to allow multiple
+ ranges to be selected. Be careful though, because by default the
+ editor relies on the native DOM selection, which cannot handle
+ multiple selections. An extension like
+ [`drawSelection`](https://codemirror.net/6/docs/ref/#view.drawSelection) can be used to make
+ secondary selections visible to the user.
+ */
+ EditorState.allowMultipleSelections = allowMultipleSelections;
+ /**
+ Configures the tab size to use in this state. The first
+ (highest-precedence) value of the facet is used. If no value is
+ given, this defaults to 4.
+ */
+ EditorState.tabSize = /*@__PURE__*/Facet.define({
+ combine: values => values.length ? values[0] : 4
+ });
+ /**
+ The line separator to use. By default, any of `"\n"`, `"\r\n"`
+ and `"\r"` is treated as a separator when splitting lines, and
+ lines are joined with `"\n"`.
+
+ When you configure a value here, only that precise separator
+ will be used, allowing you to round-trip documents through the
+ editor without normalizing line separators.
+ */
+ EditorState.lineSeparator = lineSeparator;
+ /**
+ This facet controls the value of the
+ [`readOnly`](https://codemirror.net/6/docs/ref/#state.EditorState.readOnly) getter, which is
+ consulted by commands and extensions that implement editing
+ functionality to determine whether they should apply. It
+ defaults to false, but when its highest-precedence value is
+ `true`, such functionality disables itself.
+
+ Not to be confused with
+ [`EditorView.editable`](https://codemirror.net/6/docs/ref/#view.EditorView^editable), which
+ controls whether the editor's DOM is set to be editable (and
+ thus focusable).
+ */
+ EditorState.readOnly = readOnly;
+ /**
+ Registers translation phrases. The
+ [`phrase`](https://codemirror.net/6/docs/ref/#state.EditorState.phrase) method will look through
+ all objects registered with this facet to find translations for
+ its argument.
+ */
+ EditorState.phrases = /*@__PURE__*/Facet.define({
+ compare(a, b) {
+ let kA = Object.keys(a), kB = Object.keys(b);
+ return kA.length == kB.length && kA.every(k => a[k] == b[k]);
+ }
+ });
+ /**
+ A facet used to register [language
+ data](https://codemirror.net/6/docs/ref/#state.EditorState.languageDataAt) providers.
+ */
+ EditorState.languageData = languageData;
+ /**
+ Facet used to register change filters, which are called for each
+ transaction (unless explicitly
+ [disabled](https://codemirror.net/6/docs/ref/#state.TransactionSpec.filter)), and can suppress
+ part of the transaction's changes.
+
+ Such a function can return `true` to indicate that it doesn't
+ want to do anything, `false` to completely stop the changes in
+ the transaction, or a set of ranges in which changes should be
+ suppressed. Such ranges are represented as an array of numbers,
+ with each pair of two numbers indicating the start and end of a
+ range. So for example `[10, 20, 100, 110]` suppresses changes
+ between 10 and 20, and between 100 and 110.
+ */
+ EditorState.changeFilter = changeFilter;
+ /**
+ Facet used to register a hook that gets a chance to update or
+ replace transaction specs before they are applied. This will
+ only be applied for transactions that don't have
+ [`filter`](https://codemirror.net/6/docs/ref/#state.TransactionSpec.filter) set to `false`. You
+ can either return a single transaction spec (possibly the input
+ transaction), or an array of specs (which will be combined in
+ the same way as the arguments to
+ [`EditorState.update`](https://codemirror.net/6/docs/ref/#state.EditorState.update)).
+
+ When possible, it is recommended to avoid accessing
+ [`Transaction.state`](https://codemirror.net/6/docs/ref/#state.Transaction.state) in a filter,
+ since it will force creation of a state that will then be
+ discarded again, if the transaction is actually filtered.
+
+ (This functionality should be used with care. Indiscriminately
+ modifying transaction is likely to break something or degrade
+ the user experience.)
+ */
+ EditorState.transactionFilter = transactionFilter;
+ /**
+ This is a more limited form of
+ [`transactionFilter`](https://codemirror.net/6/docs/ref/#state.EditorState^transactionFilter),
+ which can only add
+ [annotations](https://codemirror.net/6/docs/ref/#state.TransactionSpec.annotations) and
+ [effects](https://codemirror.net/6/docs/ref/#state.TransactionSpec.effects). _But_, this type
+ of filter runs even if the transaction has disabled regular
+ [filtering](https://codemirror.net/6/docs/ref/#state.TransactionSpec.filter), making it suitable
+ for effects that don't need to touch the changes or selection,
+ but do want to process every transaction.
+
+ Extenders run _after_ filters, when both are present.
+ */
+ EditorState.transactionExtender = transactionExtender;
+ Compartment.reconfigure = /*@__PURE__*/StateEffect.define();
+
+ /**
+ Utility function for combining behaviors to fill in a config
+ object from an array of provided configs. `defaults` should hold
+ default values for all optional fields in `Config`.
+
+ The function will, by default, error
+ when a field gets two values that aren't `===`-equal, but you can
+ provide combine functions per field to do something else.
+ */
+ function combineConfig(configs, defaults, // Should hold only the optional properties of Config, but I haven't managed to express that
+ combine = {}) {
+ let result = {};
+ for (let config of configs)
+ for (let key of Object.keys(config)) {
+ let value = config[key], current = result[key];
+ if (current === undefined)
+ result[key] = value;
+ else if (current === value || value === undefined) ; // No conflict
+ else if (Object.hasOwnProperty.call(combine, key))
+ result[key] = combine[key](current, value);
+ else
+ throw new Error("Config merge conflict for field " + key);
+ }
+ for (let key in defaults)
+ if (result[key] === undefined)
+ result[key] = defaults[key];
+ return result;
+ }
+
+ /**
+ Each range is associated with a value, which must inherit from
+ this class.
+ */
+ class RangeValue {
+ /**
+ Compare this value with another value. Used when comparing
+ rangesets. The default implementation compares by identity.
+ Unless you are only creating a fixed number of unique instances
+ of your value type, it is a good idea to implement this
+ properly.
+ */
+ eq(other) { return this == other; }
+ /**
+ Create a [range](https://codemirror.net/6/docs/ref/#state.Range) with this value.
+ */
+ range(from, to = from) { return Range$1.create(from, to, this); }
+ }
+ RangeValue.prototype.startSide = RangeValue.prototype.endSide = 0;
+ RangeValue.prototype.point = false;
+ RangeValue.prototype.mapMode = MapMode.TrackDel;
+ /**
+ A range associates a value with a range of positions.
+ */
+ class Range$1 {
+ constructor(
+ /**
+ The range's start position.
+ */
+ from,
+ /**
+ Its end position.
+ */
+ to,
+ /**
+ The value associated with this range.
+ */
+ value) {
+ this.from = from;
+ this.to = to;
+ this.value = value;
+ }
+ /**
+ @internal
+ */
+ static create(from, to, value) {
+ return new Range$1(from, to, value);
+ }
+ }
+ function cmpRange(a, b) {
+ return a.from - b.from || a.value.startSide - b.value.startSide;
+ }
+ class Chunk {
+ constructor(from, to, value,
+ // Chunks are marked with the largest point that occurs
+ // in them (or -1 for no points), so that scans that are
+ // only interested in points (such as the
+ // heightmap-related logic) can skip range-only chunks.
+ maxPoint) {
+ this.from = from;
+ this.to = to;
+ this.value = value;
+ this.maxPoint = maxPoint;
+ }
+ get length() { return this.to[this.to.length - 1]; }
+ // Find the index of the given position and side. Use the ranges'
+ // `from` pos when `end == false`, `to` when `end == true`.
+ findIndex(pos, side, end, startAt = 0) {
+ let arr = end ? this.to : this.from;
+ for (let lo = startAt, hi = arr.length;;) {
+ if (lo == hi)
+ return lo;
+ let mid = (lo + hi) >> 1;
+ let diff = arr[mid] - pos || (end ? this.value[mid].endSide : this.value[mid].startSide) - side;
+ if (mid == lo)
+ return diff >= 0 ? lo : hi;
+ if (diff >= 0)
+ hi = mid;
+ else
+ lo = mid + 1;
+ }
+ }
+ between(offset, from, to, f) {
+ for (let i = this.findIndex(from, -1000000000 /* C.Far */, true), e = this.findIndex(to, 1000000000 /* C.Far */, false, i); i < e; i++)
+ if (f(this.from[i] + offset, this.to[i] + offset, this.value[i]) === false)
+ return false;
+ }
+ map(offset, changes) {
+ let value = [], from = [], to = [], newPos = -1, maxPoint = -1;
+ for (let i = 0; i < this.value.length; i++) {
+ let val = this.value[i], curFrom = this.from[i] + offset, curTo = this.to[i] + offset, newFrom, newTo;
+ if (curFrom == curTo) {
+ let mapped = changes.mapPos(curFrom, val.startSide, val.mapMode);
+ if (mapped == null)
+ continue;
+ newFrom = newTo = mapped;
+ if (val.startSide != val.endSide) {
+ newTo = changes.mapPos(curFrom, val.endSide);
+ if (newTo < newFrom)
+ continue;
+ }
+ }
+ else {
+ newFrom = changes.mapPos(curFrom, val.startSide);
+ newTo = changes.mapPos(curTo, val.endSide);
+ if (newFrom > newTo || newFrom == newTo && val.startSide > 0 && val.endSide <= 0)
+ continue;
+ }
+ if ((newTo - newFrom || val.endSide - val.startSide) < 0)
+ continue;
+ if (newPos < 0)
+ newPos = newFrom;
+ if (val.point)
+ maxPoint = Math.max(maxPoint, newTo - newFrom);
+ value.push(val);
+ from.push(newFrom - newPos);
+ to.push(newTo - newPos);
+ }
+ return { mapped: value.length ? new Chunk(from, to, value, maxPoint) : null, pos: newPos };
+ }
+ }
+ /**
+ A range set stores a collection of [ranges](https://codemirror.net/6/docs/ref/#state.Range) in a
+ way that makes them efficient to [map](https://codemirror.net/6/docs/ref/#state.RangeSet.map) and
+ [update](https://codemirror.net/6/docs/ref/#state.RangeSet.update). This is an immutable data
+ structure.
+ */
+ class RangeSet {
+ constructor(
+ /**
+ @internal
+ */
+ chunkPos,
+ /**
+ @internal
+ */
+ chunk,
+ /**
+ @internal
+ */
+ nextLayer,
+ /**
+ @internal
+ */
+ maxPoint) {
+ this.chunkPos = chunkPos;
+ this.chunk = chunk;
+ this.nextLayer = nextLayer;
+ this.maxPoint = maxPoint;
+ }
+ /**
+ @internal
+ */
+ static create(chunkPos, chunk, nextLayer, maxPoint) {
+ return new RangeSet(chunkPos, chunk, nextLayer, maxPoint);
+ }
+ /**
+ @internal
+ */
+ get length() {
+ let last = this.chunk.length - 1;
+ return last < 0 ? 0 : Math.max(this.chunkEnd(last), this.nextLayer.length);
+ }
+ /**
+ The number of ranges in the set.
+ */
+ get size() {
+ if (this.isEmpty)
+ return 0;
+ let size = this.nextLayer.size;
+ for (let chunk of this.chunk)
+ size += chunk.value.length;
+ return size;
+ }
+ /**
+ @internal
+ */
+ chunkEnd(index) {
+ return this.chunkPos[index] + this.chunk[index].length;
+ }
+ /**
+ Update the range set, optionally adding new ranges or filtering
+ out existing ones.
+
+ (Note: The type parameter is just there as a kludge to work
+ around TypeScript variance issues that prevented `RangeSet`
+ from being a subtype of `RangeSet` when `X` is a subtype of
+ `Y`.)
+ */
+ update(updateSpec) {
+ let { add = [], sort = false, filterFrom = 0, filterTo = this.length } = updateSpec;
+ let filter = updateSpec.filter;
+ if (add.length == 0 && !filter)
+ return this;
+ if (sort)
+ add = add.slice().sort(cmpRange);
+ if (this.isEmpty)
+ return add.length ? RangeSet.of(add) : this;
+ let cur = new LayerCursor(this, null, -1).goto(0), i = 0, spill = [];
+ let builder = new RangeSetBuilder();
+ while (cur.value || i < add.length) {
+ if (i < add.length && (cur.from - add[i].from || cur.startSide - add[i].value.startSide) >= 0) {
+ let range = add[i++];
+ if (!builder.addInner(range.from, range.to, range.value))
+ spill.push(range);
+ }
+ else if (cur.rangeIndex == 1 && cur.chunkIndex < this.chunk.length &&
+ (i == add.length || this.chunkEnd(cur.chunkIndex) < add[i].from) &&
+ (!filter || filterFrom > this.chunkEnd(cur.chunkIndex) || filterTo < this.chunkPos[cur.chunkIndex]) &&
+ builder.addChunk(this.chunkPos[cur.chunkIndex], this.chunk[cur.chunkIndex])) {
+ cur.nextChunk();
+ }
+ else {
+ if (!filter || filterFrom > cur.to || filterTo < cur.from || filter(cur.from, cur.to, cur.value)) {
+ if (!builder.addInner(cur.from, cur.to, cur.value))
+ spill.push(Range$1.create(cur.from, cur.to, cur.value));
+ }
+ cur.next();
+ }
+ }
+ return builder.finishInner(this.nextLayer.isEmpty && !spill.length ? RangeSet.empty
+ : this.nextLayer.update({ add: spill, filter, filterFrom, filterTo }));
+ }
+ /**
+ Map this range set through a set of changes, return the new set.
+ */
+ map(changes) {
+ if (changes.empty || this.isEmpty)
+ return this;
+ let chunks = [], chunkPos = [], maxPoint = -1;
+ for (let i = 0; i < this.chunk.length; i++) {
+ let start = this.chunkPos[i], chunk = this.chunk[i];
+ let touch = changes.touchesRange(start, start + chunk.length);
+ if (touch === false) {
+ maxPoint = Math.max(maxPoint, chunk.maxPoint);
+ chunks.push(chunk);
+ chunkPos.push(changes.mapPos(start));
+ }
+ else if (touch === true) {
+ let { mapped, pos } = chunk.map(start, changes);
+ if (mapped) {
+ maxPoint = Math.max(maxPoint, mapped.maxPoint);
+ chunks.push(mapped);
+ chunkPos.push(pos);
+ }
+ }
+ }
+ let next = this.nextLayer.map(changes);
+ return chunks.length == 0 ? next : new RangeSet(chunkPos, chunks, next || RangeSet.empty, maxPoint);
+ }
+ /**
+ Iterate over the ranges that touch the region `from` to `to`,
+ calling `f` for each. There is no guarantee that the ranges will
+ be reported in any specific order. When the callback returns
+ `false`, iteration stops.
+ */
+ between(from, to, f) {
+ if (this.isEmpty)
+ return;
+ for (let i = 0; i < this.chunk.length; i++) {
+ let start = this.chunkPos[i], chunk = this.chunk[i];
+ if (to >= start && from <= start + chunk.length &&
+ chunk.between(start, from - start, to - start, f) === false)
+ return;
+ }
+ this.nextLayer.between(from, to, f);
+ }
+ /**
+ Iterate over the ranges in this set, in order, including all
+ ranges that end at or after `from`.
+ */
+ iter(from = 0) {
+ return HeapCursor.from([this]).goto(from);
+ }
+ /**
+ @internal
+ */
+ get isEmpty() { return this.nextLayer == this; }
+ /**
+ Iterate over the ranges in a collection of sets, in order,
+ starting from `from`.
+ */
+ static iter(sets, from = 0) {
+ return HeapCursor.from(sets).goto(from);
+ }
+ /**
+ Iterate over two groups of sets, calling methods on `comparator`
+ to notify it of possible differences.
+ */
+ static compare(oldSets, newSets,
+ /**
+ This indicates how the underlying data changed between these
+ ranges, and is needed to synchronize the iteration. `from` and
+ `to` are coordinates in the _new_ space, after these changes.
+ */
+ textDiff, comparator,
+ /**
+ Can be used to ignore all non-point ranges, and points below
+ the given size. When -1, all ranges are compared.
+ */
+ minPointSize = -1) {
+ let a = oldSets.filter(set => set.maxPoint > 0 || !set.isEmpty && set.maxPoint >= minPointSize);
+ let b = newSets.filter(set => set.maxPoint > 0 || !set.isEmpty && set.maxPoint >= minPointSize);
+ let sharedChunks = findSharedChunks(a, b, textDiff);
+ let sideA = new SpanCursor(a, sharedChunks, minPointSize);
+ let sideB = new SpanCursor(b, sharedChunks, minPointSize);
+ textDiff.iterGaps((fromA, fromB, length) => compare(sideA, fromA, sideB, fromB, length, comparator));
+ if (textDiff.empty && textDiff.length == 0)
+ compare(sideA, 0, sideB, 0, 0, comparator);
+ }
+ /**
+ Compare the contents of two groups of range sets, returning true
+ if they are equivalent in the given range.
+ */
+ static eq(oldSets, newSets, from = 0, to) {
+ if (to == null)
+ to = 1000000000 /* C.Far */;
+ let a = oldSets.filter(set => !set.isEmpty && newSets.indexOf(set) < 0);
+ let b = newSets.filter(set => !set.isEmpty && oldSets.indexOf(set) < 0);
+ if (a.length != b.length)
+ return false;
+ if (!a.length)
+ return true;
+ let sharedChunks = findSharedChunks(a, b);
+ let sideA = new SpanCursor(a, sharedChunks, 0).goto(from), sideB = new SpanCursor(b, sharedChunks, 0).goto(from);
+ for (;;) {
+ if (sideA.to != sideB.to ||
+ !sameValues(sideA.active, sideB.active) ||
+ sideA.point && (!sideB.point || !sideA.point.eq(sideB.point)))
+ return false;
+ if (sideA.to > to)
+ return true;
+ sideA.next();
+ sideB.next();
+ }
+ }
+ /**
+ Iterate over a group of range sets at the same time, notifying
+ the iterator about the ranges covering every given piece of
+ content. Returns the open count (see
+ [`SpanIterator.span`](https://codemirror.net/6/docs/ref/#state.SpanIterator.span)) at the end
+ of the iteration.
+ */
+ static spans(sets, from, to, iterator,
+ /**
+ When given and greater than -1, only points of at least this
+ size are taken into account.
+ */
+ minPointSize = -1) {
+ let cursor = new SpanCursor(sets, null, minPointSize).goto(from), pos = from;
+ let open = cursor.openStart;
+ for (;;) {
+ let curTo = Math.min(cursor.to, to);
+ if (cursor.point) {
+ iterator.point(pos, curTo, cursor.point, cursor.activeForPoint(cursor.to), open, cursor.pointRank);
+ open = cursor.openEnd(curTo) + (cursor.to > curTo ? 1 : 0);
+ }
+ else if (curTo > pos) {
+ iterator.span(pos, curTo, cursor.active, open);
+ open = cursor.openEnd(curTo);
+ }
+ if (cursor.to > to)
+ break;
+ pos = cursor.to;
+ cursor.next();
+ }
+ return open;
+ }
+ /**
+ Create a range set for the given range or array of ranges. By
+ default, this expects the ranges to be _sorted_ (by start
+ position and, if two start at the same position,
+ `value.startSide`). You can pass `true` as second argument to
+ cause the method to sort them.
+ */
+ static of(ranges, sort = false) {
+ let build = new RangeSetBuilder();
+ for (let range of ranges instanceof Range$1 ? [ranges] : sort ? lazySort(ranges) : ranges)
+ build.add(range.from, range.to, range.value);
+ return build.finish();
+ }
+ }
+ /**
+ The empty set of ranges.
+ */
+ RangeSet.empty = /*@__PURE__*/new RangeSet([], [], null, -1);
+ function lazySort(ranges) {
+ if (ranges.length > 1)
+ for (let prev = ranges[0], i = 1; i < ranges.length; i++) {
+ let cur = ranges[i];
+ if (cmpRange(prev, cur) > 0)
+ return ranges.slice().sort(cmpRange);
+ prev = cur;
+ }
+ return ranges;
+ }
+ RangeSet.empty.nextLayer = RangeSet.empty;
+ /**
+ A range set builder is a data structure that helps build up a
+ [range set](https://codemirror.net/6/docs/ref/#state.RangeSet) directly, without first allocating
+ an array of [`Range`](https://codemirror.net/6/docs/ref/#state.Range) objects.
+ */
+ class RangeSetBuilder {
+ /**
+ Create an empty builder.
+ */
+ constructor() {
+ this.chunks = [];
+ this.chunkPos = [];
+ this.chunkStart = -1;
+ this.last = null;
+ this.lastFrom = -1000000000 /* C.Far */;
+ this.lastTo = -1000000000 /* C.Far */;
+ this.from = [];
+ this.to = [];
+ this.value = [];
+ this.maxPoint = -1;
+ this.setMaxPoint = -1;
+ this.nextLayer = null;
+ }
+ finishChunk(newArrays) {
+ this.chunks.push(new Chunk(this.from, this.to, this.value, this.maxPoint));
+ this.chunkPos.push(this.chunkStart);
+ this.chunkStart = -1;
+ this.setMaxPoint = Math.max(this.setMaxPoint, this.maxPoint);
+ this.maxPoint = -1;
+ if (newArrays) {
+ this.from = [];
+ this.to = [];
+ this.value = [];
+ }
+ }
+ /**
+ Add a range. Ranges should be added in sorted (by `from` and
+ `value.startSide`) order.
+ */
+ add(from, to, value) {
+ if (!this.addInner(from, to, value))
+ (this.nextLayer || (this.nextLayer = new RangeSetBuilder)).add(from, to, value);
+ }
+ /**
+ @internal
+ */
+ addInner(from, to, value) {
+ let diff = from - this.lastTo || value.startSide - this.last.endSide;
+ if (diff <= 0 && (from - this.lastFrom || value.startSide - this.last.startSide) < 0)
+ throw new Error("Ranges must be added sorted by `from` position and `startSide`");
+ if (diff < 0)
+ return false;
+ if (this.from.length == 250 /* C.ChunkSize */)
+ this.finishChunk(true);
+ if (this.chunkStart < 0)
+ this.chunkStart = from;
+ this.from.push(from - this.chunkStart);
+ this.to.push(to - this.chunkStart);
+ this.last = value;
+ this.lastFrom = from;
+ this.lastTo = to;
+ this.value.push(value);
+ if (value.point)
+ this.maxPoint = Math.max(this.maxPoint, to - from);
+ return true;
+ }
+ /**
+ @internal
+ */
+ addChunk(from, chunk) {
+ if ((from - this.lastTo || chunk.value[0].startSide - this.last.endSide) < 0)
+ return false;
+ if (this.from.length)
+ this.finishChunk(true);
+ this.setMaxPoint = Math.max(this.setMaxPoint, chunk.maxPoint);
+ this.chunks.push(chunk);
+ this.chunkPos.push(from);
+ let last = chunk.value.length - 1;
+ this.last = chunk.value[last];
+ this.lastFrom = chunk.from[last] + from;
+ this.lastTo = chunk.to[last] + from;
+ return true;
+ }
+ /**
+ Finish the range set. Returns the new set. The builder can't be
+ used anymore after this has been called.
+ */
+ finish() { return this.finishInner(RangeSet.empty); }
+ /**
+ @internal
+ */
+ finishInner(next) {
+ if (this.from.length)
+ this.finishChunk(false);
+ if (this.chunks.length == 0)
+ return next;
+ let result = RangeSet.create(this.chunkPos, this.chunks, this.nextLayer ? this.nextLayer.finishInner(next) : next, this.setMaxPoint);
+ this.from = null; // Make sure further `add` calls produce errors
+ return result;
+ }
+ }
+ function findSharedChunks(a, b, textDiff) {
+ let inA = new Map();
+ for (let set of a)
+ for (let i = 0; i < set.chunk.length; i++)
+ if (set.chunk[i].maxPoint <= 0)
+ inA.set(set.chunk[i], set.chunkPos[i]);
+ let shared = new Set();
+ for (let set of b)
+ for (let i = 0; i < set.chunk.length; i++) {
+ let known = inA.get(set.chunk[i]);
+ if (known != null && (textDiff ? textDiff.mapPos(known) : known) == set.chunkPos[i] &&
+ !(textDiff === null || textDiff === void 0 ? void 0 : textDiff.touchesRange(known, known + set.chunk[i].length)))
+ shared.add(set.chunk[i]);
+ }
+ return shared;
+ }
+ class LayerCursor {
+ constructor(layer, skip, minPoint, rank = 0) {
+ this.layer = layer;
+ this.skip = skip;
+ this.minPoint = minPoint;
+ this.rank = rank;
+ }
+ get startSide() { return this.value ? this.value.startSide : 0; }
+ get endSide() { return this.value ? this.value.endSide : 0; }
+ goto(pos, side = -1000000000 /* C.Far */) {
+ this.chunkIndex = this.rangeIndex = 0;
+ this.gotoInner(pos, side, false);
+ return this;
+ }
+ gotoInner(pos, side, forward) {
+ while (this.chunkIndex < this.layer.chunk.length) {
+ let next = this.layer.chunk[this.chunkIndex];
+ if (!(this.skip && this.skip.has(next) ||
+ this.layer.chunkEnd(this.chunkIndex) < pos ||
+ next.maxPoint < this.minPoint))
+ break;
+ this.chunkIndex++;
+ forward = false;
+ }
+ if (this.chunkIndex < this.layer.chunk.length) {
+ let rangeIndex = this.layer.chunk[this.chunkIndex].findIndex(pos - this.layer.chunkPos[this.chunkIndex], side, true);
+ if (!forward || this.rangeIndex < rangeIndex)
+ this.setRangeIndex(rangeIndex);
+ }
+ this.next();
+ }
+ forward(pos, side) {
+ if ((this.to - pos || this.endSide - side) < 0)
+ this.gotoInner(pos, side, true);
+ }
+ next() {
+ for (;;) {
+ if (this.chunkIndex == this.layer.chunk.length) {
+ this.from = this.to = 1000000000 /* C.Far */;
+ this.value = null;
+ break;
+ }
+ else {
+ let chunkPos = this.layer.chunkPos[this.chunkIndex], chunk = this.layer.chunk[this.chunkIndex];
+ let from = chunkPos + chunk.from[this.rangeIndex];
+ this.from = from;
+ this.to = chunkPos + chunk.to[this.rangeIndex];
+ this.value = chunk.value[this.rangeIndex];
+ this.setRangeIndex(this.rangeIndex + 1);
+ if (this.minPoint < 0 || this.value.point && this.to - this.from >= this.minPoint)
+ break;
+ }
+ }
+ }
+ setRangeIndex(index) {
+ if (index == this.layer.chunk[this.chunkIndex].value.length) {
+ this.chunkIndex++;
+ if (this.skip) {
+ while (this.chunkIndex < this.layer.chunk.length && this.skip.has(this.layer.chunk[this.chunkIndex]))
+ this.chunkIndex++;
+ }
+ this.rangeIndex = 0;
+ }
+ else {
+ this.rangeIndex = index;
+ }
+ }
+ nextChunk() {
+ this.chunkIndex++;
+ this.rangeIndex = 0;
+ this.next();
+ }
+ compare(other) {
+ return this.from - other.from || this.startSide - other.startSide || this.rank - other.rank ||
+ this.to - other.to || this.endSide - other.endSide;
+ }
+ }
+ class HeapCursor {
+ constructor(heap) {
+ this.heap = heap;
+ }
+ static from(sets, skip = null, minPoint = -1) {
+ let heap = [];
+ for (let i = 0; i < sets.length; i++) {
+ for (let cur = sets[i]; !cur.isEmpty; cur = cur.nextLayer) {
+ if (cur.maxPoint >= minPoint)
+ heap.push(new LayerCursor(cur, skip, minPoint, i));
+ }
+ }
+ return heap.length == 1 ? heap[0] : new HeapCursor(heap);
+ }
+ get startSide() { return this.value ? this.value.startSide : 0; }
+ goto(pos, side = -1000000000 /* C.Far */) {
+ for (let cur of this.heap)
+ cur.goto(pos, side);
+ for (let i = this.heap.length >> 1; i >= 0; i--)
+ heapBubble(this.heap, i);
+ this.next();
+ return this;
+ }
+ forward(pos, side) {
+ for (let cur of this.heap)
+ cur.forward(pos, side);
+ for (let i = this.heap.length >> 1; i >= 0; i--)
+ heapBubble(this.heap, i);
+ if ((this.to - pos || this.value.endSide - side) < 0)
+ this.next();
+ }
+ next() {
+ if (this.heap.length == 0) {
+ this.from = this.to = 1000000000 /* C.Far */;
+ this.value = null;
+ this.rank = -1;
+ }
+ else {
+ let top = this.heap[0];
+ this.from = top.from;
+ this.to = top.to;
+ this.value = top.value;
+ this.rank = top.rank;
+ if (top.value)
+ top.next();
+ heapBubble(this.heap, 0);
+ }
+ }
+ }
+ function heapBubble(heap, index) {
+ for (let cur = heap[index];;) {
+ let childIndex = (index << 1) + 1;
+ if (childIndex >= heap.length)
+ break;
+ let child = heap[childIndex];
+ if (childIndex + 1 < heap.length && child.compare(heap[childIndex + 1]) >= 0) {
+ child = heap[childIndex + 1];
+ childIndex++;
+ }
+ if (cur.compare(child) < 0)
+ break;
+ heap[childIndex] = cur;
+ heap[index] = child;
+ index = childIndex;
+ }
+ }
+ class SpanCursor {
+ constructor(sets, skip, minPoint) {
+ this.minPoint = minPoint;
+ this.active = [];
+ this.activeTo = [];
+ this.activeRank = [];
+ this.minActive = -1;
+ // A currently active point range, if any
+ this.point = null;
+ this.pointFrom = 0;
+ this.pointRank = 0;
+ this.to = -1000000000 /* C.Far */;
+ this.endSide = 0;
+ this.openStart = -1;
+ this.cursor = HeapCursor.from(sets, skip, minPoint);
+ }
+ goto(pos, side = -1000000000 /* C.Far */) {
+ this.cursor.goto(pos, side);
+ this.active.length = this.activeTo.length = this.activeRank.length = 0;
+ this.minActive = -1;
+ this.to = pos;
+ this.endSide = side;
+ this.openStart = -1;
+ this.next();
+ return this;
+ }
+ forward(pos, side) {
+ while (this.minActive > -1 && (this.activeTo[this.minActive] - pos || this.active[this.minActive].endSide - side) < 0)
+ this.removeActive(this.minActive);
+ this.cursor.forward(pos, side);
+ }
+ removeActive(index) {
+ remove(this.active, index);
+ remove(this.activeTo, index);
+ remove(this.activeRank, index);
+ this.minActive = findMinIndex(this.active, this.activeTo);
+ }
+ addActive(trackOpen) {
+ let i = 0, { value, to, rank } = this.cursor;
+ while (i < this.activeRank.length && this.activeRank[i] <= rank)
+ i++;
+ insert(this.active, i, value);
+ insert(this.activeTo, i, to);
+ insert(this.activeRank, i, rank);
+ if (trackOpen)
+ insert(trackOpen, i, this.cursor.from);
+ this.minActive = findMinIndex(this.active, this.activeTo);
+ }
+ // After calling this, if `this.point` != null, the next range is a
+ // point. Otherwise, it's a regular range, covered by `this.active`.
+ next() {
+ let from = this.to, wasPoint = this.point;
+ this.point = null;
+ let trackOpen = this.openStart < 0 ? [] : null, trackExtra = 0;
+ for (;;) {
+ let a = this.minActive;
+ if (a > -1 && (this.activeTo[a] - this.cursor.from || this.active[a].endSide - this.cursor.startSide) < 0) {
+ if (this.activeTo[a] > from) {
+ this.to = this.activeTo[a];
+ this.endSide = this.active[a].endSide;
+ break;
+ }
+ this.removeActive(a);
+ if (trackOpen)
+ remove(trackOpen, a);
+ }
+ else if (!this.cursor.value) {
+ this.to = this.endSide = 1000000000 /* C.Far */;
+ break;
+ }
+ else if (this.cursor.from > from) {
+ this.to = this.cursor.from;
+ this.endSide = this.cursor.startSide;
+ break;
+ }
+ else {
+ let nextVal = this.cursor.value;
+ if (!nextVal.point) { // Opening a range
+ this.addActive(trackOpen);
+ if (this.cursor.from < from && this.cursor.to > from)
+ trackExtra++;
+ this.cursor.next();
+ }
+ else if (wasPoint && this.cursor.to == this.to && this.cursor.from < this.cursor.to) {
+ // Ignore any non-empty points that end precisely at the end of the prev point
+ this.cursor.next();
+ }
+ else { // New point
+ this.point = nextVal;
+ this.pointFrom = this.cursor.from;
+ this.pointRank = this.cursor.rank;
+ this.to = this.cursor.to;
+ this.endSide = nextVal.endSide;
+ if (this.cursor.from < from)
+ trackExtra = 1;
+ this.cursor.next();
+ this.forward(this.to, this.endSide);
+ break;
+ }
+ }
+ }
+ if (trackOpen) {
+ let openStart = 0;
+ while (openStart < trackOpen.length && trackOpen[openStart] < from)
+ openStart++;
+ this.openStart = openStart + trackExtra;
+ }
+ }
+ activeForPoint(to) {
+ if (!this.active.length)
+ return this.active;
+ let active = [];
+ for (let i = this.active.length - 1; i >= 0; i--) {
+ if (this.activeRank[i] < this.pointRank)
+ break;
+ if (this.activeTo[i] > to || this.activeTo[i] == to && this.active[i].endSide >= this.point.endSide)
+ active.push(this.active[i]);
+ }
+ return active.reverse();
+ }
+ openEnd(to) {
+ let open = 0;
+ for (let i = this.activeTo.length - 1; i >= 0 && this.activeTo[i] > to; i--)
+ open++;
+ return open;
+ }
+ }
+ function compare(a, startA, b, startB, length, comparator) {
+ a.goto(startA);
+ b.goto(startB);
+ let endB = startB + length;
+ let pos = startB, dPos = startB - startA;
+ for (;;) {
+ let diff = (a.to + dPos) - b.to || a.endSide - b.endSide;
+ let end = diff < 0 ? a.to + dPos : b.to, clipEnd = Math.min(end, endB);
+ if (a.point || b.point) {
+ if (!(a.point && b.point && (a.point == b.point || a.point.eq(b.point)) &&
+ sameValues(a.activeForPoint(a.to + dPos), b.activeForPoint(b.to))))
+ comparator.comparePoint(pos, clipEnd, a.point, b.point);
+ }
+ else {
+ if (clipEnd > pos && !sameValues(a.active, b.active))
+ comparator.compareRange(pos, clipEnd, a.active, b.active);
+ }
+ if (end > endB)
+ break;
+ pos = end;
+ if (diff <= 0)
+ a.next();
+ if (diff >= 0)
+ b.next();
+ }
+ }
+ function sameValues(a, b) {
+ if (a.length != b.length)
+ return false;
+ for (let i = 0; i < a.length; i++)
+ if (a[i] != b[i] && !a[i].eq(b[i]))
+ return false;
+ return true;
+ }
+ function remove(array, index) {
+ for (let i = index, e = array.length - 1; i < e; i++)
+ array[i] = array[i + 1];
+ array.pop();
+ }
+ function insert(array, index, value) {
+ for (let i = array.length - 1; i >= index; i--)
+ array[i + 1] = array[i];
+ array[index] = value;
+ }
+ function findMinIndex(value, array) {
+ let found = -1, foundPos = 1000000000 /* C.Far */;
+ for (let i = 0; i < array.length; i++)
+ if ((array[i] - foundPos || value[i].endSide - value[found].endSide) < 0) {
+ found = i;
+ foundPos = array[i];
+ }
+ return found;
+ }
+
+ /**
+ Count the column position at the given offset into the string,
+ taking extending characters and tab size into account.
+ */
+ function countColumn(string, tabSize, to = string.length) {
+ let n = 0;
+ for (let i = 0; i < to;) {
+ if (string.charCodeAt(i) == 9) {
+ n += tabSize - (n % tabSize);
+ i++;
+ }
+ else {
+ n++;
+ i = findClusterBreak(string, i);
+ }
+ }
+ return n;
+ }
+ /**
+ Find the offset that corresponds to the given column position in a
+ string, taking extending characters and tab size into account. By
+ default, the string length is returned when it is too short to
+ reach the column. Pass `strict` true to make it return -1 in that
+ situation.
+ */
+ function findColumn(string, col, tabSize, strict) {
+ for (let i = 0, n = 0;;) {
+ if (n >= col)
+ return i;
+ if (i == string.length)
+ break;
+ n += string.charCodeAt(i) == 9 ? tabSize - (n % tabSize) : 1;
+ i = findClusterBreak(string, i);
+ }
+ return strict === true ? -1 : string.length;
+ }
+
+ const C = "\u037c";
+ const COUNT = typeof Symbol == "undefined" ? "__" + C : Symbol.for(C);
+ const SET = typeof Symbol == "undefined" ? "__styleSet" + Math.floor(Math.random() * 1e8) : Symbol("styleSet");
+ const top = typeof globalThis != "undefined" ? globalThis : typeof window != "undefined" ? window : {};
+
+ // :: - Style modules encapsulate a set of CSS rules defined from
+ // JavaScript. Their definitions are only available in a given DOM
+ // root after it has been _mounted_ there with `StyleModule.mount`.
+ //
+ // Style modules should be created once and stored somewhere, as
+ // opposed to re-creating them every time you need them. The amount of
+ // CSS rules generated for a given DOM root is bounded by the amount
+ // of style modules that were used. So to avoid leaking rules, don't
+ // create these dynamically, but treat them as one-time allocations.
+ class StyleModule {
+ // :: (Object