+ function loadGroupGroups(feature22) {
+ const props = feature22.properties;
+ if (feature22.geometry || !props.members)
+ return;
+ const featureLevelIndex = levels.indexOf(props.level);
+ let sharedGroups = [];
+ props.members.forEach((memberID, index) => {
+ const member = _featuresByCode[memberID];
+ const memberGroups = member.properties.groups.filter((groupID) => {
+ return groupID !== feature22.properties.id && featureLevelIndex < levels.indexOf(_featuresByCode[groupID].properties.level);
+ });
+ if (index === 0) {
+ sharedGroups = memberGroups;
+ } else {
+ sharedGroups = sharedGroups.filter((groupID) => memberGroups.indexOf(groupID) !== -1);
+ }
+ });
+ props.groups = props.groups.concat(
+ sharedGroups.filter((groupID) => props.groups.indexOf(groupID) === -1)
+ );
+ for (const groupID of sharedGroups) {
+ const groupFeature = _featuresByCode[groupID];
+ if (groupFeature.properties.members.indexOf(props.id) === -1) {
+ groupFeature.properties.members.push(props.id);
+ }
+ }
+ }
+ function loadRoadSpeedUnit(feature22) {
+ const props = feature22.properties;
+ if (feature22.geometry) {
+ if (!props.roadSpeedUnit)
+ props.roadSpeedUnit = "km/h";
+ } else if (props.members) {
+ const vals = Array.from(
+ new Set(
+ props.members.map((id2) => {
+ const member = _featuresByCode[id2];
+ if (member.geometry)
+ return member.properties.roadSpeedUnit || "km/h";
+ }).filter(Boolean)
+ )
+ );
+ if (vals.length === 1)
+ props.roadSpeedUnit = vals[0];
+ }
+ }
+ function loadRoadHeightUnit(feature22) {
+ const props = feature22.properties;
+ if (feature22.geometry) {
+ if (!props.roadHeightUnit)
+ props.roadHeightUnit = "m";
+ } else if (props.members) {
+ const vals = Array.from(
+ new Set(
+ props.members.map((id2) => {
+ const member = _featuresByCode[id2];
+ if (member.geometry)
+ return member.properties.roadHeightUnit || "m";
+ }).filter(Boolean)
+ )
+ );
+ if (vals.length === 1)
+ props.roadHeightUnit = vals[0];
+ }
+ }
+ function loadDriveSide(feature22) {
+ const props = feature22.properties;
+ if (feature22.geometry) {
+ if (!props.driveSide)
+ props.driveSide = "right";
+ } else if (props.members) {
+ const vals = Array.from(
+ new Set(
+ props.members.map((id2) => {
+ const member = _featuresByCode[id2];
+ if (member.geometry)
+ return member.properties.driveSide || "right";
+ }).filter(Boolean)
+ )
+ );
+ if (vals.length === 1)
+ props.driveSide = vals[0];
+ }
+ }
+ function loadCallingCodes(feature22) {
+ const props = feature22.properties;
+ if (!feature22.geometry && props.members) {
+ props.callingCodes = Array.from(
+ new Set(
+ props.members.reduce((array2, id2) => {
+ const member = _featuresByCode[id2];
+ if (member.geometry && member.properties.callingCodes) {
+ return array2.concat(member.properties.callingCodes);
+ }
+ return array2;
+ }, [])
+ )
+ );
+ }
+ }
+ function loadFlag(feature22) {
+ if (!feature22.properties.iso1A2)
+ return;
+ const flag = feature22.properties.iso1A2.replace(/./g, function(char) {
+ return String.fromCodePoint(char.charCodeAt(0) + 127397);
+ });
+ feature22.properties.emojiFlag = flag;
+ }
+ function loadMembersForGroupsOf(feature22) {
+ for (const groupID of feature22.properties.groups) {
+ const groupFeature = _featuresByCode[groupID];
+ if (!groupFeature.properties.members) {
+ groupFeature.properties.members = [];
+ }
+ groupFeature.properties.members.push(feature22.properties.id);
+ }
+ }
+ function cacheFeatureByIDs(feature22) {
+ let ids = [];
+ for (const prop of identifierProps) {
+ const id2 = feature22.properties[prop];
+ if (id2) {
+ ids.push(id2);
+ }
+ }
+ for (const alias of feature22.properties.aliases || []) {
+ ids.push(alias);
+ }
+ for (const id2 of ids) {
+ const cid = canonicalID(id2);
+ _featuresByCode[cid] = feature22;
+ }
+ }
+ }
+ function locArray(loc) {
+ if (Array.isArray(loc)) {
+ return loc;
+ } else if (loc.coordinates) {
+ return loc.coordinates;
+ }
+ return loc.geometry.coordinates;
+ }
+ function smallestFeature(loc) {
+ const query = locArray(loc);
+ const featureProperties = _whichPolygon(query);
+ if (!featureProperties)
+ return null;
+ return _featuresByCode[featureProperties.id];
+ }
+ function countryFeature(loc) {
+ const feature22 = smallestFeature(loc);
+ if (!feature22)
+ return null;
+ const countryCode = feature22.properties.country || feature22.properties.iso1A2;
+ return _featuresByCode[countryCode] || null;
+ }
+ var defaultOpts = {
+ level: void 0,
+ maxLevel: void 0,
+ withProp: void 0
+ };
+ function featureForLoc(loc, opts) {
+ const targetLevel = opts.level || "country";
+ const maxLevel = opts.maxLevel || "world";
+ const withProp = opts.withProp;
+ const targetLevelIndex = levels.indexOf(targetLevel);
+ if (targetLevelIndex === -1)
+ return null;
+ const maxLevelIndex = levels.indexOf(maxLevel);
+ if (maxLevelIndex === -1)
+ return null;
+ if (maxLevelIndex < targetLevelIndex)
+ return null;
+ if (targetLevel === "country") {
+ const fastFeature = countryFeature(loc);
+ if (fastFeature) {
+ if (!withProp || fastFeature.properties[withProp]) {
+ return fastFeature;
+ }
+ }
+ }
+ const features = featuresContaining(loc);
+ const match = features.find((feature22) => {
+ let levelIndex = levels.indexOf(feature22.properties.level);
+ if (feature22.properties.level === targetLevel || // if no feature exists at the target level, return the first feature at the next level up
+ levelIndex > targetLevelIndex && levelIndex <= maxLevelIndex) {
+ if (!withProp || feature22.properties[withProp]) {
+ return feature22;
+ }
+ }
+ return false;
+ });
+ return match || null;
+ }
+ function featureForID(id2) {
+ let stringID;
+ if (typeof id2 === "number") {
+ stringID = id2.toString();
+ if (stringID.length === 1) {
+ stringID = "00" + stringID;
+ } else if (stringID.length === 2) {
+ stringID = "0" + stringID;
+ }
+ } else {
+ stringID = canonicalID(id2);
+ }
+ return _featuresByCode[stringID] || null;
+ }
+ function smallestFeaturesForBbox(bbox2) {
+ return _whichPolygon.bbox(bbox2).map((props) => _featuresByCode[props.id]);
+ }
+ function smallestOrMatchingFeature(query) {
+ if (typeof query === "object") {
+ return smallestFeature(query);
+ }
+ return featureForID(query);
+ }
+ function feature(query, opts = defaultOpts) {
+ if (typeof query === "object") {
+ return featureForLoc(query, opts);
+ }
+ return featureForID(query);
+ }
+ function iso1A2Code(query, opts = defaultOpts) {
+ opts.withProp = "iso1A2";
+ const match = feature(query, opts);
+ if (!match)
+ return null;
+ return match.properties.iso1A2 || null;
+ }
+ function propertiesForQuery(query, property) {
+ const features = featuresContaining(query, false);
+ return features.map((feature22) => feature22.properties[property]).filter(Boolean);
+ }
+ function iso1A2Codes(query) {
+ return propertiesForQuery(query, "iso1A2");
+ }
+ function featuresContaining(query, strict) {
+ let matchingFeatures;
+ if (Array.isArray(query) && query.length === 4) {
+ matchingFeatures = smallestFeaturesForBbox(query);
+ } else {
+ const smallestOrMatching = smallestOrMatchingFeature(query);
+ matchingFeatures = smallestOrMatching ? [smallestOrMatching] : [];
+ }
+ if (!matchingFeatures.length)
+ return [];
+ let returnFeatures;
+ if (!strict || typeof query === "object") {
+ returnFeatures = matchingFeatures.slice();
+ } else {
+ returnFeatures = [];
+ }
+ for (const feature22 of matchingFeatures) {
+ const properties = feature22.properties;
+ for (const groupID of properties.groups) {
+ const groupFeature = _featuresByCode[groupID];
+ if (returnFeatures.indexOf(groupFeature) === -1) {
+ returnFeatures.push(groupFeature);
+ }
+ }
+ }
+ return returnFeatures;
+ }
+ function featuresIn(id2, strict) {
+ const feature22 = featureForID(id2);
+ if (!feature22)
+ return [];
+ let features = [];
+ if (!strict) {
+ features.push(feature22);
+ }
+ const properties = feature22.properties;
+ for (const memberID of properties.members || []) {
+ features.push(_featuresByCode[memberID]);
+ }
+ return features;
+ }
+ function aggregateFeature(id2) {
+ var _a2;
+ const features = featuresIn(id2, false);
+ if (features.length === 0)
+ return null;
+ let aggregateCoordinates = [];
+ for (const feature22 of features) {
+ if (((_a2 = feature22.geometry) == null ? void 0 : _a2.type) === "MultiPolygon" && feature22.geometry.coordinates) {
+ aggregateCoordinates = aggregateCoordinates.concat(feature22.geometry.coordinates);
+ }
+ }
+ return {
+ type: "Feature",
+ properties: features[0].properties,
+ geometry: {
+ type: "MultiPolygon",
+ coordinates: aggregateCoordinates
+ }
+ };
+ }
+ function roadSpeedUnit(query) {
+ const feature22 = smallestOrMatchingFeature(query);
+ return feature22 && feature22.properties.roadSpeedUnit || null;
+ }
+ function roadHeightUnit(query) {
+ const feature22 = smallestOrMatchingFeature(query);
+ return feature22 && feature22.properties.roadHeightUnit || null;
+ }
+
+ // node_modules/polyclip-ts/dist/constant.js
+ var constant_default5 = (x2) => {
+ return () => {
+ return x2;
+ };
+ };
+
+ // node_modules/polyclip-ts/dist/compare.js
+ var compare_default = (eps) => {
+ const almostEqual = eps ? (a2, b2) => b2.minus(a2).abs().isLessThanOrEqualTo(eps) : constant_default5(false);
+ return (a2, b2) => {
+ if (almostEqual(a2, b2))
+ return 0;
+ return a2.comparedTo(b2);
+ };
+ };
+
+ // node_modules/polyclip-ts/dist/orient.js
+ function orient_default(eps) {
+ const almostCollinear = eps ? (area2, ax, ay, cx, cy) => area2.exponentiatedBy(2).isLessThanOrEqualTo(cx.minus(ax).exponentiatedBy(2).plus(cy.minus(ay).exponentiatedBy(2)).times(eps)) : constant_default5(false);
+ return (a2, b2, c2) => {
+ const ax = a2.x, ay = a2.y, cx = c2.x, cy = c2.y;
+ const area2 = ay.minus(cy).times(b2.x.minus(cx)).minus(ax.minus(cx).times(b2.y.minus(cy)));
+ if (almostCollinear(area2, ax, ay, cx, cy))
+ return 0;
+ return area2.comparedTo(0);
+ };
+ }
+
+ // node_modules/bignumber.js/bignumber.mjs
+ var isNumeric = /^-?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i;
+ var mathceil = Math.ceil;
+ var mathfloor = Math.floor;
+ var bignumberError = "[BigNumber Error] ";
+ var tooManyDigits = bignumberError + "Number primitive has more than 15 significant digits: ";
+ var BASE = 1e14;
+ var LOG_BASE = 14;
+ var MAX_SAFE_INTEGER = 9007199254740991;
+ var POWS_TEN = [1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13];
+ var SQRT_BASE = 1e7;
+ var MAX = 1e9;
+ function clone(configObject) {
+ var div, convertBase, parseNumeric2, P2 = BigNumber2.prototype = { constructor: BigNumber2, toString: null, valueOf: null }, ONE = new BigNumber2(1), DECIMAL_PLACES = 20, ROUNDING_MODE = 4, TO_EXP_NEG = -7, TO_EXP_POS = 21, MIN_EXP = -1e7, MAX_EXP = 1e7, CRYPTO = false, MODULO_MODE = 1, POW_PRECISION = 0, FORMAT = {
+ prefix: "",
+ groupSize: 3,
+ secondaryGroupSize: 0,
+ groupSeparator: ",",
+ decimalSeparator: ".",
+ fractionGroupSize: 0,
+ fractionGroupSeparator: "\xA0",
+ // non-breaking space
+ suffix: ""
+ }, ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz", alphabetHasNormalDecimalDigits = true;
+ function BigNumber2(v2, b2) {
+ var alphabet, c2, caseChanged, e3, i3, isNum, len, str, x2 = this;
+ if (!(x2 instanceof BigNumber2))
+ return new BigNumber2(v2, b2);
+ if (b2 == null) {
+ if (v2 && v2._isBigNumber === true) {
+ x2.s = v2.s;
+ if (!v2.c || v2.e > MAX_EXP) {
+ x2.c = x2.e = null;
+ } else if (v2.e < MIN_EXP) {
+ x2.c = [x2.e = 0];
+ } else {
+ x2.e = v2.e;
+ x2.c = v2.c.slice();
+ }
+ return;
+ }
+ if ((isNum = typeof v2 == "number") && v2 * 0 == 0) {
+ x2.s = 1 / v2 < 0 ? (v2 = -v2, -1) : 1;
+ if (v2 === ~~v2) {
+ for (e3 = 0, i3 = v2; i3 >= 10; i3 /= 10, e3++)
+ ;
+ if (e3 > MAX_EXP) {
+ x2.c = x2.e = null;
+ } else {
+ x2.e = e3;
+ x2.c = [v2];
+ }
+ return;
+ }
+ str = String(v2);
+ } else {
+ if (!isNumeric.test(str = String(v2)))
+ return parseNumeric2(x2, str, isNum);
+ x2.s = str.charCodeAt(0) == 45 ? (str = str.slice(1), -1) : 1;
+ }
+ if ((e3 = str.indexOf(".")) > -1)
+ str = str.replace(".", "");
+ if ((i3 = str.search(/e/i)) > 0) {
+ if (e3 < 0)
+ e3 = i3;
+ e3 += +str.slice(i3 + 1);
+ str = str.substring(0, i3);
+ } else if (e3 < 0) {
+ e3 = str.length;
+ }
+ } else {
+ intCheck(b2, 2, ALPHABET.length, "Base");
+ if (b2 == 10 && alphabetHasNormalDecimalDigits) {
+ x2 = new BigNumber2(v2);
+ return round(x2, DECIMAL_PLACES + x2.e + 1, ROUNDING_MODE);
+ }
+ str = String(v2);
+ if (isNum = typeof v2 == "number") {
+ if (v2 * 0 != 0)
+ return parseNumeric2(x2, str, isNum, b2);
+ x2.s = 1 / v2 < 0 ? (str = str.slice(1), -1) : 1;
+ if (BigNumber2.DEBUG && str.replace(/^0\.0*|\./, "").length > 15) {
+ throw Error(tooManyDigits + v2);
+ }
+ } else {
+ x2.s = str.charCodeAt(0) === 45 ? (str = str.slice(1), -1) : 1;
+ }
+ alphabet = ALPHABET.slice(0, b2);
+ e3 = i3 = 0;
+ for (len = str.length; i3 < len; i3++) {
+ if (alphabet.indexOf(c2 = str.charAt(i3)) < 0) {
+ if (c2 == ".") {
+ if (i3 > e3) {
+ e3 = len;
+ continue;
+ }
+ } else if (!caseChanged) {
+ if (str == str.toUpperCase() && (str = str.toLowerCase()) || str == str.toLowerCase() && (str = str.toUpperCase())) {
+ caseChanged = true;
+ i3 = -1;
+ e3 = 0;
+ continue;
+ }
+ }
+ return parseNumeric2(x2, String(v2), isNum, b2);
+ }
+ }
+ isNum = false;
+ str = convertBase(str, b2, 10, x2.s);
+ if ((e3 = str.indexOf(".")) > -1)
+ str = str.replace(".", "");
+ else
+ e3 = str.length;
+ }
+ for (i3 = 0; str.charCodeAt(i3) === 48; i3++)
+ ;
+ for (len = str.length; str.charCodeAt(--len) === 48; )
+ ;
+ if (str = str.slice(i3, ++len)) {
+ len -= i3;
+ if (isNum && BigNumber2.DEBUG && len > 15 && (v2 > MAX_SAFE_INTEGER || v2 !== mathfloor(v2))) {
+ throw Error(tooManyDigits + x2.s * v2);
+ }
+ if ((e3 = e3 - i3 - 1) > MAX_EXP) {
+ x2.c = x2.e = null;
+ } else if (e3 < MIN_EXP) {
+ x2.c = [x2.e = 0];
+ } else {
+ x2.e = e3;
+ x2.c = [];
+ i3 = (e3 + 1) % LOG_BASE;
+ if (e3 < 0)
+ i3 += LOG_BASE;
+ if (i3 < len) {
+ if (i3)
+ x2.c.push(+str.slice(0, i3));
+ for (len -= LOG_BASE; i3 < len; ) {
+ x2.c.push(+str.slice(i3, i3 += LOG_BASE));
+ }
+ i3 = LOG_BASE - (str = str.slice(i3)).length;
+ } else {
+ i3 -= len;
+ }
+ for (; i3--; str += "0")
+ ;
+ x2.c.push(+str);
+ }
+ } else {
+ x2.c = [x2.e = 0];
+ }
+ }
+ BigNumber2.clone = clone;
+ BigNumber2.ROUND_UP = 0;
+ BigNumber2.ROUND_DOWN = 1;
+ BigNumber2.ROUND_CEIL = 2;
+ BigNumber2.ROUND_FLOOR = 3;
+ BigNumber2.ROUND_HALF_UP = 4;
+ BigNumber2.ROUND_HALF_DOWN = 5;
+ BigNumber2.ROUND_HALF_EVEN = 6;
+ BigNumber2.ROUND_HALF_CEIL = 7;
+ BigNumber2.ROUND_HALF_FLOOR = 8;
+ BigNumber2.EUCLID = 9;
+ BigNumber2.config = BigNumber2.set = function(obj) {
+ var p2, v2;
+ if (obj != null) {
+ if (typeof obj == "object") {
+ if (obj.hasOwnProperty(p2 = "DECIMAL_PLACES")) {
+ v2 = obj[p2];
+ intCheck(v2, 0, MAX, p2);
+ DECIMAL_PLACES = v2;
+ }
+ if (obj.hasOwnProperty(p2 = "ROUNDING_MODE")) {
+ v2 = obj[p2];
+ intCheck(v2, 0, 8, p2);
+ ROUNDING_MODE = v2;
+ }
+ if (obj.hasOwnProperty(p2 = "EXPONENTIAL_AT")) {
+ v2 = obj[p2];
+ if (v2 && v2.pop) {
+ intCheck(v2[0], -MAX, 0, p2);
+ intCheck(v2[1], 0, MAX, p2);
+ TO_EXP_NEG = v2[0];
+ TO_EXP_POS = v2[1];
+ } else {
+ intCheck(v2, -MAX, MAX, p2);
+ TO_EXP_NEG = -(TO_EXP_POS = v2 < 0 ? -v2 : v2);
+ }
+ }
+ if (obj.hasOwnProperty(p2 = "RANGE")) {
+ v2 = obj[p2];
+ if (v2 && v2.pop) {
+ intCheck(v2[0], -MAX, -1, p2);
+ intCheck(v2[1], 1, MAX, p2);
+ MIN_EXP = v2[0];
+ MAX_EXP = v2[1];
+ } else {
+ intCheck(v2, -MAX, MAX, p2);
+ if (v2) {
+ MIN_EXP = -(MAX_EXP = v2 < 0 ? -v2 : v2);
+ } else {
+ throw Error(bignumberError + p2 + " cannot be zero: " + v2);
+ }
+ }
+ }
+ if (obj.hasOwnProperty(p2 = "CRYPTO")) {
+ v2 = obj[p2];
+ if (v2 === !!v2) {
+ if (v2) {
+ if (typeof crypto != "undefined" && crypto && (crypto.getRandomValues || crypto.randomBytes)) {
+ CRYPTO = v2;
+ } else {
+ CRYPTO = !v2;
+ throw Error(bignumberError + "crypto unavailable");
+ }
+ } else {
+ CRYPTO = v2;
+ }
+ } else {
+ throw Error(bignumberError + p2 + " not true or false: " + v2);
+ }
+ }
+ if (obj.hasOwnProperty(p2 = "MODULO_MODE")) {
+ v2 = obj[p2];
+ intCheck(v2, 0, 9, p2);
+ MODULO_MODE = v2;
+ }
+ if (obj.hasOwnProperty(p2 = "POW_PRECISION")) {
+ v2 = obj[p2];
+ intCheck(v2, 0, MAX, p2);
+ POW_PRECISION = v2;
+ }
+ if (obj.hasOwnProperty(p2 = "FORMAT")) {
+ v2 = obj[p2];
+ if (typeof v2 == "object")
+ FORMAT = v2;
+ else
+ throw Error(bignumberError + p2 + " not an object: " + v2);
+ }
+ if (obj.hasOwnProperty(p2 = "ALPHABET")) {
+ v2 = obj[p2];
+ if (typeof v2 == "string" && !/^.?$|[+\-.\s]|(.).*\1/.test(v2)) {
+ alphabetHasNormalDecimalDigits = v2.slice(0, 10) == "0123456789";
+ ALPHABET = v2;
+ } else {
+ throw Error(bignumberError + p2 + " invalid: " + v2);
+ }
+ }
+ } else {
+ throw Error(bignumberError + "Object expected: " + obj);
+ }
+ }
+ return {
+ DECIMAL_PLACES,
+ ROUNDING_MODE,
+ EXPONENTIAL_AT: [TO_EXP_NEG, TO_EXP_POS],
+ RANGE: [MIN_EXP, MAX_EXP],
+ CRYPTO,
+ MODULO_MODE,
+ POW_PRECISION,
+ FORMAT,
+ ALPHABET
+ };
+ };
+ BigNumber2.isBigNumber = function(v2) {
+ if (!v2 || v2._isBigNumber !== true)
+ return false;
+ if (!BigNumber2.DEBUG)
+ return true;
+ var i3, n3, c2 = v2.c, e3 = v2.e, s2 = v2.s;
+ out:
+ if ({}.toString.call(c2) == "[object Array]") {
+ if ((s2 === 1 || s2 === -1) && e3 >= -MAX && e3 <= MAX && e3 === mathfloor(e3)) {
+ if (c2[0] === 0) {
+ if (e3 === 0 && c2.length === 1)
+ return true;
+ break out;
+ }
+ i3 = (e3 + 1) % LOG_BASE;
+ if (i3 < 1)
+ i3 += LOG_BASE;
+ if (String(c2[0]).length == i3) {
+ for (i3 = 0; i3 < c2.length; i3++) {
+ n3 = c2[i3];
+ if (n3 < 0 || n3 >= BASE || n3 !== mathfloor(n3))
+ break out;
+ }
+ if (n3 !== 0)
+ return true;
+ }
+ }
+ } else if (c2 === null && e3 === null && (s2 === null || s2 === 1 || s2 === -1)) {
+ return true;
+ }
+ throw Error(bignumberError + "Invalid BigNumber: " + v2);
+ };
+ BigNumber2.maximum = BigNumber2.max = function() {
+ return maxOrMin(arguments, -1);
+ };
+ BigNumber2.minimum = BigNumber2.min = function() {
+ return maxOrMin(arguments, 1);
+ };
+ BigNumber2.random = function() {
+ var pow2_53 = 9007199254740992;
+ var random53bitInt = Math.random() * pow2_53 & 2097151 ? function() {
+ return mathfloor(Math.random() * pow2_53);
+ } : function() {
+ return (Math.random() * 1073741824 | 0) * 8388608 + (Math.random() * 8388608 | 0);
+ };
+ return function(dp) {
+ var a2, b2, e3, k2, v2, i3 = 0, c2 = [], rand = new BigNumber2(ONE);
+ if (dp == null)
+ dp = DECIMAL_PLACES;
+ else
+ intCheck(dp, 0, MAX);
+ k2 = mathceil(dp / LOG_BASE);
+ if (CRYPTO) {
+ if (crypto.getRandomValues) {
+ a2 = crypto.getRandomValues(new Uint32Array(k2 *= 2));
+ for (; i3 < k2; ) {
+ v2 = a2[i3] * 131072 + (a2[i3 + 1] >>> 11);
+ if (v2 >= 9e15) {
+ b2 = crypto.getRandomValues(new Uint32Array(2));
+ a2[i3] = b2[0];
+ a2[i3 + 1] = b2[1];
+ } else {
+ c2.push(v2 % 1e14);
+ i3 += 2;
+ }
+ }
+ i3 = k2 / 2;
+ } else if (crypto.randomBytes) {
+ a2 = crypto.randomBytes(k2 *= 7);
+ for (; i3 < k2; ) {
+ v2 = (a2[i3] & 31) * 281474976710656 + a2[i3 + 1] * 1099511627776 + a2[i3 + 2] * 4294967296 + a2[i3 + 3] * 16777216 + (a2[i3 + 4] << 16) + (a2[i3 + 5] << 8) + a2[i3 + 6];
+ if (v2 >= 9e15) {
+ crypto.randomBytes(7).copy(a2, i3);
+ } else {
+ c2.push(v2 % 1e14);
+ i3 += 7;
+ }
+ }
+ i3 = k2 / 7;
+ } else {
+ CRYPTO = false;
+ throw Error(bignumberError + "crypto unavailable");
+ }
+ }
+ if (!CRYPTO) {
+ for (; i3 < k2; ) {
+ v2 = random53bitInt();
+ if (v2 < 9e15)
+ c2[i3++] = v2 % 1e14;
+ }
+ }
+ k2 = c2[--i3];
+ dp %= LOG_BASE;
+ if (k2 && dp) {
+ v2 = POWS_TEN[LOG_BASE - dp];
+ c2[i3] = mathfloor(k2 / v2) * v2;
+ }
+ for (; c2[i3] === 0; c2.pop(), i3--)
+ ;
+ if (i3 < 0) {
+ c2 = [e3 = 0];
+ } else {
+ for (e3 = -1; c2[0] === 0; c2.splice(0, 1), e3 -= LOG_BASE)
+ ;
+ for (i3 = 1, v2 = c2[0]; v2 >= 10; v2 /= 10, i3++)
+ ;
+ if (i3 < LOG_BASE)
+ e3 -= LOG_BASE - i3;
+ }
+ rand.e = e3;
+ rand.c = c2;
+ return rand;
+ };
+ }();
+ BigNumber2.sum = function() {
+ var i3 = 1, args = arguments, sum = new BigNumber2(args[0]);
+ for (; i3 < args.length; )
+ sum = sum.plus(args[i3++]);
+ return sum;
+ };
+ convertBase = /* @__PURE__ */ function() {
+ var decimal = "0123456789";
+ function toBaseOut(str, baseIn, baseOut, alphabet) {
+ var j2, arr = [0], arrL, i3 = 0, len = str.length;
+ for (; i3 < len; ) {
+ for (arrL = arr.length; arrL--; arr[arrL] *= baseIn)
+ ;
+ arr[0] += alphabet.indexOf(str.charAt(i3++));
+ for (j2 = 0; j2 < arr.length; j2++) {
+ if (arr[j2] > baseOut - 1) {
+ if (arr[j2 + 1] == null)
+ arr[j2 + 1] = 0;
+ arr[j2 + 1] += arr[j2] / baseOut | 0;
+ arr[j2] %= baseOut;
+ }
+ }
+ }
+ return arr.reverse();
+ }
+ return function(str, baseIn, baseOut, sign2, callerIsToString) {
+ var alphabet, d2, e3, k2, r2, x2, xc, y2, i3 = str.indexOf("."), dp = DECIMAL_PLACES, rm = ROUNDING_MODE;
+ if (i3 >= 0) {
+ k2 = POW_PRECISION;
+ POW_PRECISION = 0;
+ str = str.replace(".", "");
+ y2 = new BigNumber2(baseIn);
+ x2 = y2.pow(str.length - i3);
+ POW_PRECISION = k2;
+ y2.c = toBaseOut(
+ toFixedPoint(coeffToString(x2.c), x2.e, "0"),
+ 10,
+ baseOut,
+ decimal
+ );
+ y2.e = y2.c.length;
+ }
+ xc = toBaseOut(str, baseIn, baseOut, callerIsToString ? (alphabet = ALPHABET, decimal) : (alphabet = decimal, ALPHABET));
+ e3 = k2 = xc.length;
+ for (; xc[--k2] == 0; xc.pop())
+ ;
+ if (!xc[0])
+ return alphabet.charAt(0);
+ if (i3 < 0) {
+ --e3;
+ } else {
+ x2.c = xc;
+ x2.e = e3;
+ x2.s = sign2;
+ x2 = div(x2, y2, dp, rm, baseOut);
+ xc = x2.c;
+ r2 = x2.r;
+ e3 = x2.e;
+ }
+ d2 = e3 + dp + 1;
+ i3 = xc[d2];
+ k2 = baseOut / 2;
+ r2 = r2 || d2 < 0 || xc[d2 + 1] != null;
+ r2 = rm < 4 ? (i3 != null || r2) && (rm == 0 || rm == (x2.s < 0 ? 3 : 2)) : i3 > k2 || i3 == k2 && (rm == 4 || r2 || rm == 6 && xc[d2 - 1] & 1 || rm == (x2.s < 0 ? 8 : 7));
+ if (d2 < 1 || !xc[0]) {
+ str = r2 ? toFixedPoint(alphabet.charAt(1), -dp, alphabet.charAt(0)) : alphabet.charAt(0);
+ } else {
+ xc.length = d2;
+ if (r2) {
+ for (--baseOut; ++xc[--d2] > baseOut; ) {
+ xc[d2] = 0;
+ if (!d2) {
+ ++e3;
+ xc = [1].concat(xc);
+ }
+ }
+ }
+ for (k2 = xc.length; !xc[--k2]; )
+ ;
+ for (i3 = 0, str = ""; i3 <= k2; str += alphabet.charAt(xc[i3++]))
+ ;
+ str = toFixedPoint(str, e3, alphabet.charAt(0));
+ }
+ return str;
+ };
+ }();
+ div = /* @__PURE__ */ function() {
+ function multiply(x2, k2, base) {
+ var m2, temp, xlo, xhi, carry = 0, i3 = x2.length, klo = k2 % SQRT_BASE, khi = k2 / SQRT_BASE | 0;
+ for (x2 = x2.slice(); i3--; ) {
+ xlo = x2[i3] % SQRT_BASE;
+ xhi = x2[i3] / SQRT_BASE | 0;
+ m2 = khi * xlo + xhi * klo;
+ temp = klo * xlo + m2 % SQRT_BASE * SQRT_BASE + carry;
+ carry = (temp / base | 0) + (m2 / SQRT_BASE | 0) + khi * xhi;
+ x2[i3] = temp % base;
+ }
+ if (carry)
+ x2 = [carry].concat(x2);
+ return x2;
+ }
+ function compare2(a2, b2, aL, bL) {
+ var i3, cmp;
+ if (aL != bL) {
+ cmp = aL > bL ? 1 : -1;
+ } else {
+ for (i3 = cmp = 0; i3 < aL; i3++) {
+ if (a2[i3] != b2[i3]) {
+ cmp = a2[i3] > b2[i3] ? 1 : -1;
+ break;
+ }
+ }
+ }
+ return cmp;
+ }
+ function subtract(a2, b2, aL, base) {
+ var i3 = 0;
+ for (; aL--; ) {
+ a2[aL] -= i3;
+ i3 = a2[aL] < b2[aL] ? 1 : 0;
+ a2[aL] = i3 * base + a2[aL] - b2[aL];
+ }
+ for (; !a2[0] && a2.length > 1; a2.splice(0, 1))
+ ;
+ }
+ return function(x2, y2, dp, rm, base) {
+ var cmp, e3, i3, more, n3, prod, prodL, q2, qc, rem, remL, rem0, xi, xL, yc0, yL, yz, s2 = x2.s == y2.s ? 1 : -1, xc = x2.c, yc = y2.c;
+ if (!xc || !xc[0] || !yc || !yc[0]) {
+ return new BigNumber2(
+ // Return NaN if either NaN, or both Infinity or 0.
+ !x2.s || !y2.s || (xc ? yc && xc[0] == yc[0] : !yc) ? NaN : (
+ // Return ±0 if x is ±0 or y is ±Infinity, or return ±Infinity as y is ±0.
+ xc && xc[0] == 0 || !yc ? s2 * 0 : s2 / 0
+ )
+ );
+ }
+ q2 = new BigNumber2(s2);
+ qc = q2.c = [];
+ e3 = x2.e - y2.e;
+ s2 = dp + e3 + 1;
+ if (!base) {
+ base = BASE;
+ e3 = bitFloor(x2.e / LOG_BASE) - bitFloor(y2.e / LOG_BASE);
+ s2 = s2 / LOG_BASE | 0;
+ }
+ for (i3 = 0; yc[i3] == (xc[i3] || 0); i3++)
+ ;
+ if (yc[i3] > (xc[i3] || 0))
+ e3--;
+ if (s2 < 0) {
+ qc.push(1);
+ more = true;
+ } else {
+ xL = xc.length;
+ yL = yc.length;
+ i3 = 0;
+ s2 += 2;
+ n3 = mathfloor(base / (yc[0] + 1));
+ if (n3 > 1) {
+ yc = multiply(yc, n3, base);
+ xc = multiply(xc, n3, base);
+ yL = yc.length;
+ xL = xc.length;
+ }
+ xi = yL;
+ rem = xc.slice(0, yL);
+ remL = rem.length;
+ for (; remL < yL; rem[remL++] = 0)
+ ;
+ yz = yc.slice();
+ yz = [0].concat(yz);
+ yc0 = yc[0];
+ if (yc[1] >= base / 2)
+ yc0++;
+ do {
+ n3 = 0;
+ cmp = compare2(yc, rem, yL, remL);
+ if (cmp < 0) {
+ rem0 = rem[0];
+ if (yL != remL)
+ rem0 = rem0 * base + (rem[1] || 0);
+ n3 = mathfloor(rem0 / yc0);
+ if (n3 > 1) {
+ if (n3 >= base)
+ n3 = base - 1;
+ prod = multiply(yc, n3, base);
+ prodL = prod.length;
+ remL = rem.length;
+ while (compare2(prod, rem, prodL, remL) == 1) {
+ n3--;
+ subtract(prod, yL < prodL ? yz : yc, prodL, base);
+ prodL = prod.length;
+ cmp = 1;
+ }
+ } else {
+ if (n3 == 0) {
+ cmp = n3 = 1;
+ }
+ prod = yc.slice();
+ prodL = prod.length;
+ }
+ if (prodL < remL)
+ prod = [0].concat(prod);
+ subtract(rem, prod, remL, base);
+ remL = rem.length;
+ if (cmp == -1) {
+ while (compare2(yc, rem, yL, remL) < 1) {
+ n3++;
+ subtract(rem, yL < remL ? yz : yc, remL, base);
+ remL = rem.length;
+ }
+ }
+ } else if (cmp === 0) {
+ n3++;
+ rem = [0];
+ }
+ qc[i3++] = n3;
+ if (rem[0]) {
+ rem[remL++] = xc[xi] || 0;
+ } else {
+ rem = [xc[xi]];
+ remL = 1;
+ }
+ } while ((xi++ < xL || rem[0] != null) && s2--);
+ more = rem[0] != null;
+ if (!qc[0])
+ qc.splice(0, 1);
+ }
+ if (base == BASE) {
+ for (i3 = 1, s2 = qc[0]; s2 >= 10; s2 /= 10, i3++)
+ ;
+ round(q2, dp + (q2.e = i3 + e3 * LOG_BASE - 1) + 1, rm, more);
+ } else {
+ q2.e = e3;
+ q2.r = +more;
+ }
+ return q2;
+ };
+ }();
+ function format2(n3, i3, rm, id2) {
+ var c0, e3, ne2, len, str;
+ if (rm == null)
+ rm = ROUNDING_MODE;
+ else
+ intCheck(rm, 0, 8);
+ if (!n3.c)
+ return n3.toString();
+ c0 = n3.c[0];
+ ne2 = n3.e;
+ if (i3 == null) {
+ str = coeffToString(n3.c);
+ str = id2 == 1 || id2 == 2 && (ne2 <= TO_EXP_NEG || ne2 >= TO_EXP_POS) ? toExponential(str, ne2) : toFixedPoint(str, ne2, "0");
+ } else {
+ n3 = round(new BigNumber2(n3), i3, rm);
+ e3 = n3.e;
+ str = coeffToString(n3.c);
+ len = str.length;
+ if (id2 == 1 || id2 == 2 && (i3 <= e3 || e3 <= TO_EXP_NEG)) {
+ for (; len < i3; str += "0", len++)
+ ;
+ str = toExponential(str, e3);
+ } else {
+ i3 -= ne2;
+ str = toFixedPoint(str, e3, "0");
+ if (e3 + 1 > len) {
+ if (--i3 > 0)
+ for (str += "."; i3--; str += "0")
+ ;
+ } else {
+ i3 += e3 - len;
+ if (i3 > 0) {
+ if (e3 + 1 == len)
+ str += ".";
+ for (; i3--; str += "0")
+ ;
+ }
+ }
+ }
+ }
+ return n3.s < 0 && c0 ? "-" + str : str;
+ }
+ function maxOrMin(args, n3) {
+ var k2, y2, i3 = 1, x2 = new BigNumber2(args[0]);
+ for (; i3 < args.length; i3++) {
+ y2 = new BigNumber2(args[i3]);
+ if (!y2.s || (k2 = compare(x2, y2)) === n3 || k2 === 0 && x2.s === n3) {
+ x2 = y2;
+ }
+ }
+ return x2;
+ }
+ function normalise(n3, c2, e3) {
+ var i3 = 1, j2 = c2.length;
+ for (; !c2[--j2]; c2.pop())
+ ;
+ for (j2 = c2[0]; j2 >= 10; j2 /= 10, i3++)
+ ;
+ if ((e3 = i3 + e3 * LOG_BASE - 1) > MAX_EXP) {
+ n3.c = n3.e = null;
+ } else if (e3 < MIN_EXP) {
+ n3.c = [n3.e = 0];
+ } else {
+ n3.e = e3;
+ n3.c = c2;
+ }
+ return n3;
+ }
+ parseNumeric2 = /* @__PURE__ */ function() {
+ var basePrefix = /^(-?)0([xbo])(?=\w[\w.]*$)/i, dotAfter = /^([^.]+)\.$/, dotBefore = /^\.([^.]+)$/, isInfinityOrNaN = /^-?(Infinity|NaN)$/, whitespaceOrPlus = /^\s*\+(?=[\w.])|^\s+|\s+$/g;
+ return function(x2, str, isNum, b2) {
+ var base, s2 = isNum ? str : str.replace(whitespaceOrPlus, "");
+ if (isInfinityOrNaN.test(s2)) {
+ x2.s = isNaN(s2) ? null : s2 < 0 ? -1 : 1;
+ } else {
+ if (!isNum) {
+ s2 = s2.replace(basePrefix, function(m2, p1, p2) {
+ base = (p2 = p2.toLowerCase()) == "x" ? 16 : p2 == "b" ? 2 : 8;
+ return !b2 || b2 == base ? p1 : m2;
+ });
+ if (b2) {
+ base = b2;
+ s2 = s2.replace(dotAfter, "$1").replace(dotBefore, "0.$1");
+ }
+ if (str != s2)
+ return new BigNumber2(s2, base);
+ }
+ if (BigNumber2.DEBUG) {
+ throw Error(bignumberError + "Not a" + (b2 ? " base " + b2 : "") + " number: " + str);
+ }
+ x2.s = null;
+ }
+ x2.c = x2.e = null;
+ };
+ }();
+ function round(x2, sd, rm, r2) {
+ var d2, i3, j2, k2, n3, ni, rd, xc = x2.c, pows10 = POWS_TEN;
+ if (xc) {
+ out: {
+ for (d2 = 1, k2 = xc[0]; k2 >= 10; k2 /= 10, d2++)
+ ;
+ i3 = sd - d2;
+ if (i3 < 0) {
+ i3 += LOG_BASE;
+ j2 = sd;
+ n3 = xc[ni = 0];
+ rd = mathfloor(n3 / pows10[d2 - j2 - 1] % 10);
+ } else {
+ ni = mathceil((i3 + 1) / LOG_BASE);
+ if (ni >= xc.length) {
+ if (r2) {
+ for (; xc.length <= ni; xc.push(0))
+ ;
+ n3 = rd = 0;
+ d2 = 1;
+ i3 %= LOG_BASE;
+ j2 = i3 - LOG_BASE + 1;
+ } else {
+ break out;
+ }
+ } else {
+ n3 = k2 = xc[ni];
+ for (d2 = 1; k2 >= 10; k2 /= 10, d2++)
+ ;
+ i3 %= LOG_BASE;
+ j2 = i3 - LOG_BASE + d2;
+ rd = j2 < 0 ? 0 : mathfloor(n3 / pows10[d2 - j2 - 1] % 10);
+ }
+ }
+ r2 = r2 || sd < 0 || // Are there any non-zero digits after the rounding digit?
+ // The expression n % pows10[d - j - 1] returns all digits of n to the right
+ // of the digit at j, e.g. if n is 908714 and j is 2, the expression gives 714.
+ xc[ni + 1] != null || (j2 < 0 ? n3 : n3 % pows10[d2 - j2 - 1]);
+ r2 = rm < 4 ? (rd || r2) && (rm == 0 || rm == (x2.s < 0 ? 3 : 2)) : rd > 5 || rd == 5 && (rm == 4 || r2 || rm == 6 && // Check whether the digit to the left of the rounding digit is odd.
+ (i3 > 0 ? j2 > 0 ? n3 / pows10[d2 - j2] : 0 : xc[ni - 1]) % 10 & 1 || rm == (x2.s < 0 ? 8 : 7));
+ if (sd < 1 || !xc[0]) {
+ xc.length = 0;
+ if (r2) {
+ sd -= x2.e + 1;
+ xc[0] = pows10[(LOG_BASE - sd % LOG_BASE) % LOG_BASE];
+ x2.e = -sd || 0;
+ } else {
+ xc[0] = x2.e = 0;
+ }
+ return x2;
+ }
+ if (i3 == 0) {
+ xc.length = ni;
+ k2 = 1;
+ ni--;
+ } else {
+ xc.length = ni + 1;
+ k2 = pows10[LOG_BASE - i3];
+ xc[ni] = j2 > 0 ? mathfloor(n3 / pows10[d2 - j2] % pows10[j2]) * k2 : 0;
+ }
+ if (r2) {
+ for (; ; ) {
+ if (ni == 0) {
+ for (i3 = 1, j2 = xc[0]; j2 >= 10; j2 /= 10, i3++)
+ ;
+ j2 = xc[0] += k2;
+ for (k2 = 1; j2 >= 10; j2 /= 10, k2++)
+ ;
+ if (i3 != k2) {
+ x2.e++;
+ if (xc[0] == BASE)
+ xc[0] = 1;
+ }
+ break;
+ } else {
+ xc[ni] += k2;
+ if (xc[ni] != BASE)
+ break;
+ xc[ni--] = 0;
+ k2 = 1;
+ }
+ }
+ }
+ for (i3 = xc.length; xc[--i3] === 0; xc.pop())
+ ;
+ }
+ if (x2.e > MAX_EXP) {
+ x2.c = x2.e = null;
+ } else if (x2.e < MIN_EXP) {
+ x2.c = [x2.e = 0];
+ }
+ }
+ return x2;
+ }
+ function valueOf(n3) {
+ var str, e3 = n3.e;
+ if (e3 === null)
+ return n3.toString();
+ str = coeffToString(n3.c);
+ str = e3 <= TO_EXP_NEG || e3 >= TO_EXP_POS ? toExponential(str, e3) : toFixedPoint(str, e3, "0");
+ return n3.s < 0 ? "-" + str : str;
+ }
+ P2.absoluteValue = P2.abs = function() {
+ var x2 = new BigNumber2(this);
+ if (x2.s < 0)
+ x2.s = 1;
+ return x2;
+ };
+ P2.comparedTo = function(y2, b2) {
+ return compare(this, new BigNumber2(y2, b2));
+ };
+ P2.decimalPlaces = P2.dp = function(dp, rm) {
+ var c2, n3, v2, x2 = this;
+ if (dp != null) {
+ intCheck(dp, 0, MAX);
+ if (rm == null)
+ rm = ROUNDING_MODE;
+ else
+ intCheck(rm, 0, 8);
+ return round(new BigNumber2(x2), dp + x2.e + 1, rm);
+ }
+ if (!(c2 = x2.c))
+ return null;
+ n3 = ((v2 = c2.length - 1) - bitFloor(this.e / LOG_BASE)) * LOG_BASE;
+ if (v2 = c2[v2])
+ for (; v2 % 10 == 0; v2 /= 10, n3--)
+ ;
+ if (n3 < 0)
+ n3 = 0;
+ return n3;
+ };
+ P2.dividedBy = P2.div = function(y2, b2) {
+ return div(this, new BigNumber2(y2, b2), DECIMAL_PLACES, ROUNDING_MODE);
+ };
+ P2.dividedToIntegerBy = P2.idiv = function(y2, b2) {
+ return div(this, new BigNumber2(y2, b2), 0, 1);
+ };
+ P2.exponentiatedBy = P2.pow = function(n3, m2) {
+ var half, isModExp, i3, k2, more, nIsBig, nIsNeg, nIsOdd, y2, x2 = this;
+ n3 = new BigNumber2(n3);
+ if (n3.c && !n3.isInteger()) {
+ throw Error(bignumberError + "Exponent not an integer: " + valueOf(n3));
+ }
+ if (m2 != null)
+ m2 = new BigNumber2(m2);
+ nIsBig = n3.e > 14;
+ if (!x2.c || !x2.c[0] || x2.c[0] == 1 && !x2.e && x2.c.length == 1 || !n3.c || !n3.c[0]) {
+ y2 = new BigNumber2(Math.pow(+valueOf(x2), nIsBig ? n3.s * (2 - isOdd(n3)) : +valueOf(n3)));
+ return m2 ? y2.mod(m2) : y2;
+ }
+ nIsNeg = n3.s < 0;
+ if (m2) {
+ if (m2.c ? !m2.c[0] : !m2.s)
+ return new BigNumber2(NaN);
+ isModExp = !nIsNeg && x2.isInteger() && m2.isInteger();
+ if (isModExp)
+ x2 = x2.mod(m2);
+ } else if (n3.e > 9 && (x2.e > 0 || x2.e < -1 || (x2.e == 0 ? x2.c[0] > 1 || nIsBig && x2.c[1] >= 24e7 : x2.c[0] < 8e13 || nIsBig && x2.c[0] <= 9999975e7))) {
+ k2 = x2.s < 0 && isOdd(n3) ? -0 : 0;
+ if (x2.e > -1)
+ k2 = 1 / k2;
+ return new BigNumber2(nIsNeg ? 1 / k2 : k2);
+ } else if (POW_PRECISION) {
+ k2 = mathceil(POW_PRECISION / LOG_BASE + 2);
+ }
+ if (nIsBig) {
+ half = new BigNumber2(0.5);
+ if (nIsNeg)
+ n3.s = 1;
+ nIsOdd = isOdd(n3);
+ } else {
+ i3 = Math.abs(+valueOf(n3));
+ nIsOdd = i3 % 2;
+ }
+ y2 = new BigNumber2(ONE);
+ for (; ; ) {
+ if (nIsOdd) {
+ y2 = y2.times(x2);
+ if (!y2.c)
+ break;
+ if (k2) {
+ if (y2.c.length > k2)
+ y2.c.length = k2;
+ } else if (isModExp) {
+ y2 = y2.mod(m2);
+ }
+ }
+ if (i3) {
+ i3 = mathfloor(i3 / 2);
+ if (i3 === 0)
+ break;
+ nIsOdd = i3 % 2;
+ } else {
+ n3 = n3.times(half);
+ round(n3, n3.e + 1, 1);
+ if (n3.e > 14) {
+ nIsOdd = isOdd(n3);
+ } else {
+ i3 = +valueOf(n3);
+ if (i3 === 0)
+ break;
+ nIsOdd = i3 % 2;
+ }
+ }
+ x2 = x2.times(x2);
+ if (k2) {
+ if (x2.c && x2.c.length > k2)
+ x2.c.length = k2;
+ } else if (isModExp) {
+ x2 = x2.mod(m2);
+ }
+ }
+ if (isModExp)
+ return y2;
+ if (nIsNeg)
+ y2 = ONE.div(y2);
+ return m2 ? y2.mod(m2) : k2 ? round(y2, POW_PRECISION, ROUNDING_MODE, more) : y2;
+ };
+ P2.integerValue = function(rm) {
+ var n3 = new BigNumber2(this);
+ if (rm == null)
+ rm = ROUNDING_MODE;
+ else
+ intCheck(rm, 0, 8);
+ return round(n3, n3.e + 1, rm);
+ };
+ P2.isEqualTo = P2.eq = function(y2, b2) {
+ return compare(this, new BigNumber2(y2, b2)) === 0;
+ };
+ P2.isFinite = function() {
+ return !!this.c;
+ };
+ P2.isGreaterThan = P2.gt = function(y2, b2) {
+ return compare(this, new BigNumber2(y2, b2)) > 0;
+ };
+ P2.isGreaterThanOrEqualTo = P2.gte = function(y2, b2) {
+ return (b2 = compare(this, new BigNumber2(y2, b2))) === 1 || b2 === 0;
+ };
+ P2.isInteger = function() {
+ return !!this.c && bitFloor(this.e / LOG_BASE) > this.c.length - 2;
+ };
+ P2.isLessThan = P2.lt = function(y2, b2) {
+ return compare(this, new BigNumber2(y2, b2)) < 0;
+ };
+ P2.isLessThanOrEqualTo = P2.lte = function(y2, b2) {
+ return (b2 = compare(this, new BigNumber2(y2, b2))) === -1 || b2 === 0;
+ };
+ P2.isNaN = function() {
+ return !this.s;
+ };
+ P2.isNegative = function() {
+ return this.s < 0;
+ };
+ P2.isPositive = function() {
+ return this.s > 0;
+ };
+ P2.isZero = function() {
+ return !!this.c && this.c[0] == 0;
+ };
+ P2.minus = function(y2, b2) {
+ var i3, j2, t2, xLTy, x2 = this, a2 = x2.s;
+ y2 = new BigNumber2(y2, b2);
+ b2 = y2.s;
+ if (!a2 || !b2)
+ return new BigNumber2(NaN);
+ if (a2 != b2) {
+ y2.s = -b2;
+ return x2.plus(y2);
+ }
+ var xe2 = x2.e / LOG_BASE, ye2 = y2.e / LOG_BASE, xc = x2.c, yc = y2.c;
+ if (!xe2 || !ye2) {
+ if (!xc || !yc)
+ return xc ? (y2.s = -b2, y2) : new BigNumber2(yc ? x2 : NaN);
+ if (!xc[0] || !yc[0]) {
+ return yc[0] ? (y2.s = -b2, y2) : new BigNumber2(xc[0] ? x2 : (
+ // IEEE 754 (2008) 6.3: n - n = -0 when rounding to -Infinity
+ ROUNDING_MODE == 3 ? -0 : 0
+ ));
+ }
+ }
+ xe2 = bitFloor(xe2);
+ ye2 = bitFloor(ye2);
+ xc = xc.slice();
+ if (a2 = xe2 - ye2) {
+ if (xLTy = a2 < 0) {
+ a2 = -a2;
+ t2 = xc;
+ } else {
+ ye2 = xe2;
+ t2 = yc;
+ }
+ t2.reverse();
+ for (b2 = a2; b2--; t2.push(0))
+ ;
+ t2.reverse();
+ } else {
+ j2 = (xLTy = (a2 = xc.length) < (b2 = yc.length)) ? a2 : b2;
+ for (a2 = b2 = 0; b2 < j2; b2++) {
+ if (xc[b2] != yc[b2]) {
+ xLTy = xc[b2] < yc[b2];
+ break;
+ }
+ }
+ }
+ if (xLTy) {
+ t2 = xc;
+ xc = yc;
+ yc = t2;
+ y2.s = -y2.s;
+ }
+ b2 = (j2 = yc.length) - (i3 = xc.length);
+ if (b2 > 0)
+ for (; b2--; xc[i3++] = 0)
+ ;
+ b2 = BASE - 1;
+ for (; j2 > a2; ) {
+ if (xc[--j2] < yc[j2]) {
+ for (i3 = j2; i3 && !xc[--i3]; xc[i3] = b2)
+ ;
+ --xc[i3];
+ xc[j2] += BASE;
+ }
+ xc[j2] -= yc[j2];
+ }
+ for (; xc[0] == 0; xc.splice(0, 1), --ye2)
+ ;
+ if (!xc[0]) {
+ y2.s = ROUNDING_MODE == 3 ? -1 : 1;
+ y2.c = [y2.e = 0];
+ return y2;
+ }
+ return normalise(y2, xc, ye2);
+ };
+ P2.modulo = P2.mod = function(y2, b2) {
+ var q2, s2, x2 = this;
+ y2 = new BigNumber2(y2, b2);
+ if (!x2.c || !y2.s || y2.c && !y2.c[0]) {
+ return new BigNumber2(NaN);
+ } else if (!y2.c || x2.c && !x2.c[0]) {
+ return new BigNumber2(x2);
+ }
+ if (MODULO_MODE == 9) {
+ s2 = y2.s;
+ y2.s = 1;
+ q2 = div(x2, y2, 0, 3);
+ y2.s = s2;
+ q2.s *= s2;
+ } else {
+ q2 = div(x2, y2, 0, MODULO_MODE);
+ }
+ y2 = x2.minus(q2.times(y2));
+ if (!y2.c[0] && MODULO_MODE == 1)
+ y2.s = x2.s;
+ return y2;
+ };
+ P2.multipliedBy = P2.times = function(y2, b2) {
+ var c2, e3, i3, j2, k2, m2, xcL, xlo, xhi, ycL, ylo, yhi, zc, base, sqrtBase, x2 = this, xc = x2.c, yc = (y2 = new BigNumber2(y2, b2)).c;
+ if (!xc || !yc || !xc[0] || !yc[0]) {
+ if (!x2.s || !y2.s || xc && !xc[0] && !yc || yc && !yc[0] && !xc) {
+ y2.c = y2.e = y2.s = null;
+ } else {
+ y2.s *= x2.s;
+ if (!xc || !yc) {
+ y2.c = y2.e = null;
+ } else {
+ y2.c = [0];
+ y2.e = 0;
+ }
+ }
+ return y2;
+ }
+ e3 = bitFloor(x2.e / LOG_BASE) + bitFloor(y2.e / LOG_BASE);
+ y2.s *= x2.s;
+ xcL = xc.length;
+ ycL = yc.length;
+ if (xcL < ycL) {
+ zc = xc;
+ xc = yc;
+ yc = zc;
+ i3 = xcL;
+ xcL = ycL;
+ ycL = i3;
+ }
+ for (i3 = xcL + ycL, zc = []; i3--; zc.push(0))
+ ;
+ base = BASE;
+ sqrtBase = SQRT_BASE;
+ for (i3 = ycL; --i3 >= 0; ) {
+ c2 = 0;
+ ylo = yc[i3] % sqrtBase;
+ yhi = yc[i3] / sqrtBase | 0;
+ for (k2 = xcL, j2 = i3 + k2; j2 > i3; ) {
+ xlo = xc[--k2] % sqrtBase;
+ xhi = xc[k2] / sqrtBase | 0;
+ m2 = yhi * xlo + xhi * ylo;
+ xlo = ylo * xlo + m2 % sqrtBase * sqrtBase + zc[j2] + c2;
+ c2 = (xlo / base | 0) + (m2 / sqrtBase | 0) + yhi * xhi;
+ zc[j2--] = xlo % base;
+ }
+ zc[j2] = c2;
+ }
+ if (c2) {
+ ++e3;
+ } else {
+ zc.splice(0, 1);
+ }
+ return normalise(y2, zc, e3);
+ };
+ P2.negated = function() {
+ var x2 = new BigNumber2(this);
+ x2.s = -x2.s || null;
+ return x2;
+ };
+ P2.plus = function(y2, b2) {
+ var t2, x2 = this, a2 = x2.s;
+ y2 = new BigNumber2(y2, b2);
+ b2 = y2.s;
+ if (!a2 || !b2)
+ return new BigNumber2(NaN);
+ if (a2 != b2) {
+ y2.s = -b2;
+ return x2.minus(y2);
+ }
+ var xe2 = x2.e / LOG_BASE, ye2 = y2.e / LOG_BASE, xc = x2.c, yc = y2.c;
+ if (!xe2 || !ye2) {
+ if (!xc || !yc)
+ return new BigNumber2(a2 / 0);
+ if (!xc[0] || !yc[0])
+ return yc[0] ? y2 : new BigNumber2(xc[0] ? x2 : a2 * 0);
+ }
+ xe2 = bitFloor(xe2);
+ ye2 = bitFloor(ye2);
+ xc = xc.slice();
+ if (a2 = xe2 - ye2) {
+ if (a2 > 0) {
+ ye2 = xe2;
+ t2 = yc;
+ } else {
+ a2 = -a2;
+ t2 = xc;
+ }
+ t2.reverse();
+ for (; a2--; t2.push(0))
+ ;
+ t2.reverse();
+ }
+ a2 = xc.length;
+ b2 = yc.length;
+ if (a2 - b2 < 0) {
+ t2 = yc;
+ yc = xc;
+ xc = t2;
+ b2 = a2;
+ }
+ for (a2 = 0; b2; ) {
+ a2 = (xc[--b2] = xc[b2] + yc[b2] + a2) / BASE | 0;
+ xc[b2] = BASE === xc[b2] ? 0 : xc[b2] % BASE;
+ }
+ if (a2) {
+ xc = [a2].concat(xc);
+ ++ye2;
+ }
+ return normalise(y2, xc, ye2);
+ };
+ P2.precision = P2.sd = function(sd, rm) {
+ var c2, n3, v2, x2 = this;
+ if (sd != null && sd !== !!sd) {
+ intCheck(sd, 1, MAX);
+ if (rm == null)
+ rm = ROUNDING_MODE;
+ else
+ intCheck(rm, 0, 8);
+ return round(new BigNumber2(x2), sd, rm);
+ }
+ if (!(c2 = x2.c))
+ return null;
+ v2 = c2.length - 1;
+ n3 = v2 * LOG_BASE + 1;
+ if (v2 = c2[v2]) {
+ for (; v2 % 10 == 0; v2 /= 10, n3--)
+ ;
+ for (v2 = c2[0]; v2 >= 10; v2 /= 10, n3++)
+ ;
+ }
+ if (sd && x2.e + 1 > n3)
+ n3 = x2.e + 1;
+ return n3;
+ };
+ P2.shiftedBy = function(k2) {
+ intCheck(k2, -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
+ return this.times("1e" + k2);
+ };
+ P2.squareRoot = P2.sqrt = function() {
+ var m2, n3, r2, rep, t2, x2 = this, c2 = x2.c, s2 = x2.s, e3 = x2.e, dp = DECIMAL_PLACES + 4, half = new BigNumber2("0.5");
+ if (s2 !== 1 || !c2 || !c2[0]) {
+ return new BigNumber2(!s2 || s2 < 0 && (!c2 || c2[0]) ? NaN : c2 ? x2 : 1 / 0);
+ }
+ s2 = Math.sqrt(+valueOf(x2));
+ if (s2 == 0 || s2 == 1 / 0) {
+ n3 = coeffToString(c2);
+ if ((n3.length + e3) % 2 == 0)
+ n3 += "0";
+ s2 = Math.sqrt(+n3);
+ e3 = bitFloor((e3 + 1) / 2) - (e3 < 0 || e3 % 2);
+ if (s2 == 1 / 0) {
+ n3 = "5e" + e3;
+ } else {
+ n3 = s2.toExponential();
+ n3 = n3.slice(0, n3.indexOf("e") + 1) + e3;
+ }
+ r2 = new BigNumber2(n3);
+ } else {
+ r2 = new BigNumber2(s2 + "");
+ }
+ if (r2.c[0]) {
+ e3 = r2.e;
+ s2 = e3 + dp;
+ if (s2 < 3)
+ s2 = 0;
+ for (; ; ) {
+ t2 = r2;
+ r2 = half.times(t2.plus(div(x2, t2, dp, 1)));
+ if (coeffToString(t2.c).slice(0, s2) === (n3 = coeffToString(r2.c)).slice(0, s2)) {
+ if (r2.e < e3)
+ --s2;
+ n3 = n3.slice(s2 - 3, s2 + 1);
+ if (n3 == "9999" || !rep && n3 == "4999") {
+ if (!rep) {
+ round(t2, t2.e + DECIMAL_PLACES + 2, 0);
+ if (t2.times(t2).eq(x2)) {
+ r2 = t2;
+ break;
+ }
+ }
+ dp += 4;
+ s2 += 4;
+ rep = 1;
+ } else {
+ if (!+n3 || !+n3.slice(1) && n3.charAt(0) == "5") {
+ round(r2, r2.e + DECIMAL_PLACES + 2, 1);
+ m2 = !r2.times(r2).eq(x2);
+ }
+ break;
+ }
+ }
+ }
+ }
+ return round(r2, r2.e + DECIMAL_PLACES + 1, ROUNDING_MODE, m2);
+ };
+ P2.toExponential = function(dp, rm) {
+ if (dp != null) {
+ intCheck(dp, 0, MAX);
+ dp++;
+ }
+ return format2(this, dp, rm, 1);
+ };
+ P2.toFixed = function(dp, rm) {
+ if (dp != null) {
+ intCheck(dp, 0, MAX);
+ dp = dp + this.e + 1;
+ }
+ return format2(this, dp, rm);
+ };
+ P2.toFormat = function(dp, rm, format3) {
+ var str, x2 = this;
+ if (format3 == null) {
+ if (dp != null && rm && typeof rm == "object") {
+ format3 = rm;
+ rm = null;
+ } else if (dp && typeof dp == "object") {
+ format3 = dp;
+ dp = rm = null;
+ } else {
+ format3 = FORMAT;
+ }
+ } else if (typeof format3 != "object") {
+ throw Error(bignumberError + "Argument not an object: " + format3);
+ }
+ str = x2.toFixed(dp, rm);
+ if (x2.c) {
+ var i3, arr = str.split("."), g1 = +format3.groupSize, g22 = +format3.secondaryGroupSize, groupSeparator = format3.groupSeparator || "", intPart = arr[0], fractionPart = arr[1], isNeg = x2.s < 0, intDigits = isNeg ? intPart.slice(1) : intPart, len = intDigits.length;
+ if (g22) {
+ i3 = g1;
+ g1 = g22;
+ g22 = i3;
+ len -= i3;
+ }
+ if (g1 > 0 && len > 0) {
+ i3 = len % g1 || g1;
+ intPart = intDigits.substr(0, i3);
+ for (; i3 < len; i3 += g1)
+ intPart += groupSeparator + intDigits.substr(i3, g1);
+ if (g22 > 0)
+ intPart += groupSeparator + intDigits.slice(i3);
+ if (isNeg)
+ intPart = "-" + intPart;
+ }
+ str = fractionPart ? intPart + (format3.decimalSeparator || "") + ((g22 = +format3.fractionGroupSize) ? fractionPart.replace(
+ new RegExp("\\d{" + g22 + "}\\B", "g"),
+ "$&" + (format3.fractionGroupSeparator || "")
+ ) : fractionPart) : intPart;
+ }
+ return (format3.prefix || "") + str + (format3.suffix || "");
+ };
+ P2.toFraction = function(md) {
+ var d2, d0, d1, d22, e3, exp2, n3, n0, n1, q2, r2, s2, x2 = this, xc = x2.c;
+ if (md != null) {
+ n3 = new BigNumber2(md);
+ if (!n3.isInteger() && (n3.c || n3.s !== 1) || n3.lt(ONE)) {
+ throw Error(bignumberError + "Argument " + (n3.isInteger() ? "out of range: " : "not an integer: ") + valueOf(n3));
+ }
+ }
+ if (!xc)
+ return new BigNumber2(x2);
+ d2 = new BigNumber2(ONE);
+ n1 = d0 = new BigNumber2(ONE);
+ d1 = n0 = new BigNumber2(ONE);
+ s2 = coeffToString(xc);
+ e3 = d2.e = s2.length - x2.e - 1;
+ d2.c[0] = POWS_TEN[(exp2 = e3 % LOG_BASE) < 0 ? LOG_BASE + exp2 : exp2];
+ md = !md || n3.comparedTo(d2) > 0 ? e3 > 0 ? d2 : n1 : n3;
+ exp2 = MAX_EXP;
+ MAX_EXP = 1 / 0;
+ n3 = new BigNumber2(s2);
+ n0.c[0] = 0;
+ for (; ; ) {
+ q2 = div(n3, d2, 0, 1);
+ d22 = d0.plus(q2.times(d1));
+ if (d22.comparedTo(md) == 1)
+ break;
+ d0 = d1;
+ d1 = d22;
+ n1 = n0.plus(q2.times(d22 = n1));
+ n0 = d22;
+ d2 = n3.minus(q2.times(d22 = d2));
+ n3 = d22;
+ }
+ d22 = div(md.minus(d0), d1, 0, 1);
+ n0 = n0.plus(d22.times(n1));
+ d0 = d0.plus(d22.times(d1));
+ n0.s = n1.s = x2.s;
+ e3 = e3 * 2;
+ r2 = div(n1, d1, e3, ROUNDING_MODE).minus(x2).abs().comparedTo(
+ div(n0, d0, e3, ROUNDING_MODE).minus(x2).abs()
+ ) < 1 ? [n1, d1] : [n0, d0];
+ MAX_EXP = exp2;
+ return r2;
+ };
+ P2.toNumber = function() {
+ return +valueOf(this);
+ };
+ P2.toPrecision = function(sd, rm) {
+ if (sd != null)
+ intCheck(sd, 1, MAX);
+ return format2(this, sd, rm, 2);
+ };
+ P2.toString = function(b2) {
+ var str, n3 = this, s2 = n3.s, e3 = n3.e;
+ if (e3 === null) {
+ if (s2) {
+ str = "Infinity";
+ if (s2 < 0)
+ str = "-" + str;
+ } else {
+ str = "NaN";
+ }
+ } else {
+ if (b2 == null) {
+ str = e3 <= TO_EXP_NEG || e3 >= TO_EXP_POS ? toExponential(coeffToString(n3.c), e3) : toFixedPoint(coeffToString(n3.c), e3, "0");
+ } else if (b2 === 10 && alphabetHasNormalDecimalDigits) {
+ n3 = round(new BigNumber2(n3), DECIMAL_PLACES + e3 + 1, ROUNDING_MODE);
+ str = toFixedPoint(coeffToString(n3.c), n3.e, "0");
+ } else {
+ intCheck(b2, 2, ALPHABET.length, "Base");
+ str = convertBase(toFixedPoint(coeffToString(n3.c), e3, "0"), 10, b2, s2, true);
+ }
+ if (s2 < 0 && n3.c[0])
+ str = "-" + str;
+ }
+ return str;
+ };
+ P2.valueOf = P2.toJSON = function() {
+ return valueOf(this);
+ };
+ P2._isBigNumber = true;
+ P2[Symbol.toStringTag] = "BigNumber";
+ P2[Symbol.for("nodejs.util.inspect.custom")] = P2.valueOf;
+ if (configObject != null)
+ BigNumber2.set(configObject);
+ return BigNumber2;
+ }
+ function bitFloor(n3) {
+ var i3 = n3 | 0;
+ return n3 > 0 || n3 === i3 ? i3 : i3 - 1;
+ }
+ function coeffToString(a2) {
+ var s2, z2, i3 = 1, j2 = a2.length, r2 = a2[0] + "";
+ for (; i3 < j2; ) {
+ s2 = a2[i3++] + "";
+ z2 = LOG_BASE - s2.length;
+ for (; z2--; s2 = "0" + s2)
+ ;
+ r2 += s2;
+ }
+ for (j2 = r2.length; r2.charCodeAt(--j2) === 48; )
+ ;
+ return r2.slice(0, j2 + 1 || 1);
+ }
+ function compare(x2, y2) {
+ var a2, b2, xc = x2.c, yc = y2.c, i3 = x2.s, j2 = y2.s, k2 = x2.e, l2 = y2.e;
+ if (!i3 || !j2)
+ return null;
+ a2 = xc && !xc[0];
+ b2 = yc && !yc[0];
+ if (a2 || b2)
+ return a2 ? b2 ? 0 : -j2 : i3;
+ if (i3 != j2)
+ return i3;
+ a2 = i3 < 0;
+ b2 = k2 == l2;
+ if (!xc || !yc)
+ return b2 ? 0 : !xc ^ a2 ? 1 : -1;
+ if (!b2)
+ return k2 > l2 ^ a2 ? 1 : -1;
+ j2 = (k2 = xc.length) < (l2 = yc.length) ? k2 : l2;
+ for (i3 = 0; i3 < j2; i3++)
+ if (xc[i3] != yc[i3])
+ return xc[i3] > yc[i3] ^ a2 ? 1 : -1;
+ return k2 == l2 ? 0 : k2 > l2 ^ a2 ? 1 : -1;
+ }
+ function intCheck(n3, min3, max3, name) {
+ if (n3 < min3 || n3 > max3 || n3 !== mathfloor(n3)) {
+ throw Error(bignumberError + (name || "Argument") + (typeof n3 == "number" ? n3 < min3 || n3 > max3 ? " out of range: " : " not an integer: " : " not a primitive number: ") + String(n3));
+ }
+ }
+ function isOdd(n3) {
+ var k2 = n3.c.length - 1;
+ return bitFloor(n3.e / LOG_BASE) == k2 && n3.c[k2] % 2 != 0;
+ }
+ function toExponential(str, e3) {
+ return (str.length > 1 ? str.charAt(0) + "." + str.slice(1) : str) + (e3 < 0 ? "e" : "e+") + e3;
+ }
+ function toFixedPoint(str, e3, z2) {
+ var len, zs;
+ if (e3 < 0) {
+ for (zs = z2 + "."; ++e3; zs += z2)
+ ;
+ str = zs + str;
+ } else {
+ len = str.length;
+ if (++e3 > len) {
+ for (zs = z2, e3 -= len; --e3; zs += z2)
+ ;
+ str += zs;
+ } else if (e3 < len) {
+ str = str.slice(0, e3) + "." + str.slice(e3);
+ }
+ }
+ return str;
+ }
+ var BigNumber = clone();
+ var bignumber_default = BigNumber;
+
+ // node_modules/splaytree-ts/dist/index.js
+ var SplayTreeNode = class {
+ constructor(key) {
+ __publicField(this, "key");
+ __publicField(this, "left", null);
+ __publicField(this, "right", null);
+ this.key = key;
+ }
+ };
+ var SplayTreeSetNode = class extends SplayTreeNode {
+ constructor(key) {
+ super(key);
+ }
+ };
+ var SplayTree = class {
+ constructor() {
+ __publicField(this, "size", 0);
+ __publicField(this, "modificationCount", 0);
+ __publicField(this, "splayCount", 0);
+ }
+ splay(key) {
+ const root3 = this.root;
+ if (root3 == null) {
+ this.compare(key, key);
+ return -1;
+ }
+ let right = null;
+ let newTreeRight = null;
+ let left = null;
+ let newTreeLeft = null;
+ let current = root3;
+ const compare2 = this.compare;
+ let comp;
+ while (true) {
+ comp = compare2(current.key, key);
+ if (comp > 0) {
+ let currentLeft = current.left;
+ if (currentLeft == null)
+ break;
+ comp = compare2(currentLeft.key, key);
+ if (comp > 0) {
+ current.left = currentLeft.right;
+ currentLeft.right = current;
+ current = currentLeft;
+ currentLeft = current.left;
+ if (currentLeft == null)
+ break;
+ }
+ if (right == null) {
+ newTreeRight = current;
+ } else {
+ right.left = current;
+ }
+ right = current;
+ current = currentLeft;
+ } else if (comp < 0) {
+ let currentRight = current.right;
+ if (currentRight == null)
+ break;
+ comp = compare2(currentRight.key, key);
+ if (comp < 0) {
+ current.right = currentRight.left;
+ currentRight.left = current;
+ current = currentRight;
+ currentRight = current.right;
+ if (currentRight == null)
+ break;
+ }
+ if (left == null) {
+ newTreeLeft = current;
+ } else {
+ left.right = current;
+ }
+ left = current;
+ current = currentRight;
+ } else {
+ break;
+ }
+ }
+ if (left != null) {
+ left.right = current.left;
+ current.left = newTreeLeft;
+ }
+ if (right != null) {
+ right.left = current.right;
+ current.right = newTreeRight;
+ }
+ if (this.root !== current) {
+ this.root = current;
+ this.splayCount++;
+ }
+ return comp;
+ }
+ splayMin(node) {
+ let current = node;
+ let nextLeft = current.left;
+ while (nextLeft != null) {
+ const left = nextLeft;
+ current.left = left.right;
+ left.right = current;
+ current = left;
+ nextLeft = current.left;
+ }
+ return current;
+ }
+ splayMax(node) {
+ let current = node;
+ let nextRight = current.right;
+ while (nextRight != null) {
+ const right = nextRight;
+ current.right = right.left;
+ right.left = current;
+ current = right;
+ nextRight = current.right;
+ }
+ return current;
+ }
+ _delete(key) {
+ if (this.root == null)
+ return null;
+ const comp = this.splay(key);
+ if (comp != 0)
+ return null;
+ let root3 = this.root;
+ const result = root3;
+ const left = root3.left;
+ this.size--;
+ if (left == null) {
+ this.root = root3.right;
+ } else {
+ const right = root3.right;
+ root3 = this.splayMax(left);
+ root3.right = right;
+ this.root = root3;
+ }
+ this.modificationCount++;
+ return result;
+ }
+ addNewRoot(node, comp) {
+ this.size++;
+ this.modificationCount++;
+ const root3 = this.root;
+ if (root3 == null) {
+ this.root = node;
+ return;
+ }
+ if (comp < 0) {
+ node.left = root3;
+ node.right = root3.right;
+ root3.right = null;
+ } else {
+ node.right = root3;
+ node.left = root3.left;
+ root3.left = null;
+ }
+ this.root = node;
+ }
+ _first() {
+ const root3 = this.root;
+ if (root3 == null)
+ return null;
+ this.root = this.splayMin(root3);
+ return this.root;
+ }
+ _last() {
+ const root3 = this.root;
+ if (root3 == null)
+ return null;
+ this.root = this.splayMax(root3);
+ return this.root;
+ }
+ clear() {
+ this.root = null;
+ this.size = 0;
+ this.modificationCount++;
+ }
+ has(key) {
+ return this.validKey(key) && this.splay(key) == 0;
+ }
+ defaultCompare() {
+ return (a2, b2) => a2 < b2 ? -1 : a2 > b2 ? 1 : 0;
+ }
+ wrap() {
+ return {
+ getRoot: () => {
+ return this.root;
+ },
+ setRoot: (root3) => {
+ this.root = root3;
+ },
+ getSize: () => {
+ return this.size;
+ },
+ getModificationCount: () => {
+ return this.modificationCount;
+ },
+ getSplayCount: () => {
+ return this.splayCount;
+ },
+ setSplayCount: (count) => {
+ this.splayCount = count;
+ },
+ splay: (key) => {
+ return this.splay(key);
+ },
+ has: (key) => {
+ return this.has(key);
+ }
+ };
+ }
+ };
+ var _a;
+ var _SplayTreeSet = class _SplayTreeSet extends SplayTree {
+ constructor(compare2, isValidKey) {
+ super();
+ __publicField(this, "root", null);
+ __publicField(this, "compare");
+ __publicField(this, "validKey");
+ __publicField(this, _a, "[object Set]");
+ this.compare = compare2 != null ? compare2 : this.defaultCompare();
+ this.validKey = isValidKey != null ? isValidKey : (v2) => v2 != null && v2 != void 0;
+ }
+ delete(element) {
+ if (!this.validKey(element))
+ return false;
+ return this._delete(element) != null;
+ }
+ deleteAll(elements) {
+ for (const element of elements) {
+ this.delete(element);
+ }
+ }
+ forEach(f2) {
+ const nodes = this[Symbol.iterator]();
+ let result;
+ while (result = nodes.next(), !result.done) {
+ f2(result.value, result.value, this);
+ }
+ }
+ add(element) {
+ const compare2 = this.splay(element);
+ if (compare2 != 0)
+ this.addNewRoot(new SplayTreeSetNode(element), compare2);
+ return this;
+ }
+ addAndReturn(element) {
+ const compare2 = this.splay(element);
+ if (compare2 != 0)
+ this.addNewRoot(new SplayTreeSetNode(element), compare2);
+ return this.root.key;
+ }
+ addAll(elements) {
+ for (const element of elements) {
+ this.add(element);
+ }
+ }
+ isEmpty() {
+ return this.root == null;
+ }
+ isNotEmpty() {
+ return this.root != null;
+ }
+ single() {
+ if (this.size == 0)
+ throw "Bad state: No element";
+ if (this.size > 1)
+ throw "Bad state: Too many element";
+ return this.root.key;
+ }
+ first() {
+ if (this.size == 0)
+ throw "Bad state: No element";
+ return this._first().key;
+ }
+ last() {
+ if (this.size == 0)
+ throw "Bad state: No element";
+ return this._last().key;
+ }
+ lastBefore(element) {
+ if (element == null)
+ throw "Invalid arguments(s)";
+ if (this.root == null)
+ return null;
+ const comp = this.splay(element);
+ if (comp < 0)
+ return this.root.key;
+ let node = this.root.left;
+ if (node == null)
+ return null;
+ let nodeRight = node.right;
+ while (nodeRight != null) {
+ node = nodeRight;
+ nodeRight = node.right;
+ }
+ return node.key;
+ }
+ firstAfter(element) {
+ if (element == null)
+ throw "Invalid arguments(s)";
+ if (this.root == null)
+ return null;
+ const comp = this.splay(element);
+ if (comp > 0)
+ return this.root.key;
+ let node = this.root.right;
+ if (node == null)
+ return null;
+ let nodeLeft = node.left;
+ while (nodeLeft != null) {
+ node = nodeLeft;
+ nodeLeft = node.left;
+ }
+ return node.key;
+ }
+ retainAll(elements) {
+ const retainSet = new _SplayTreeSet(this.compare, this.validKey);
+ const modificationCount = this.modificationCount;
+ for (const object of elements) {
+ if (modificationCount != this.modificationCount) {
+ throw "Concurrent modification during iteration.";
+ }
+ if (this.validKey(object) && this.splay(object) == 0) {
+ retainSet.add(this.root.key);
+ }
+ }
+ if (retainSet.size != this.size) {
+ this.root = retainSet.root;
+ this.size = retainSet.size;
+ this.modificationCount++;
+ }
+ }
+ lookup(object) {
+ if (!this.validKey(object))
+ return null;
+ const comp = this.splay(object);
+ if (comp != 0)
+ return null;
+ return this.root.key;
+ }
+ intersection(other) {
+ const result = new _SplayTreeSet(this.compare, this.validKey);
+ for (const element of this) {
+ if (other.has(element))
+ result.add(element);
+ }
+ return result;
+ }
+ difference(other) {
+ const result = new _SplayTreeSet(this.compare, this.validKey);
+ for (const element of this) {
+ if (!other.has(element))
+ result.add(element);
+ }
+ return result;
+ }
+ union(other) {
+ const u2 = this.clone();
+ u2.addAll(other);
+ return u2;
+ }
+ clone() {
+ const set4 = new _SplayTreeSet(this.compare, this.validKey);
+ set4.size = this.size;
+ set4.root = this.copyNode(this.root);
+ return set4;
+ }
+ copyNode(node) {
+ if (node == null)
+ return null;
+ function copyChildren(node2, dest) {
+ let left;
+ let right;
+ do {
+ left = node2.left;
+ right = node2.right;
+ if (left != null) {
+ const newLeft = new SplayTreeSetNode(left.key);
+ dest.left = newLeft;
+ copyChildren(left, newLeft);
+ }
+ if (right != null) {
+ const newRight = new SplayTreeSetNode(right.key);
+ dest.right = newRight;
+ node2 = right;
+ dest = newRight;
+ }
+ } while (right != null);
+ }
+ const result = new SplayTreeSetNode(node.key);
+ copyChildren(node, result);
+ return result;
+ }
+ toSet() {
+ return this.clone();
+ }
+ entries() {
+ return new SplayTreeSetEntryIterableIterator(this.wrap());
+ }
+ keys() {
+ return this[Symbol.iterator]();
+ }
+ values() {
+ return this[Symbol.iterator]();
+ }
+ [Symbol.iterator]() {
+ return new SplayTreeKeyIterableIterator(this.wrap());
+ }
+ };
+ _a = Symbol.toStringTag;
+ var SplayTreeSet = _SplayTreeSet;
+ var SplayTreeIterableIterator = class {
+ constructor(tree) {
+ __publicField(this, "tree");
+ __publicField(this, "path", new Array());
+ __publicField(this, "modificationCount", null);
+ __publicField(this, "splayCount");
+ this.tree = tree;
+ this.splayCount = tree.getSplayCount();
+ }
+ [Symbol.iterator]() {
+ return this;
+ }
+ next() {
+ if (this.moveNext())
+ return { done: false, value: this.current() };
+ return { done: true, value: null };
+ }
+ current() {
+ if (!this.path.length)
+ return null;
+ const node = this.path[this.path.length - 1];
+ return this.getValue(node);
+ }
+ rebuildPath(key) {
+ this.path.splice(0, this.path.length);
+ this.tree.splay(key);
+ this.path.push(this.tree.getRoot());
+ this.splayCount = this.tree.getSplayCount();
+ }
+ findLeftMostDescendent(node) {
+ while (node != null) {
+ this.path.push(node);
+ node = node.left;
+ }
+ }
+ moveNext() {
+ if (this.modificationCount != this.tree.getModificationCount()) {
+ if (this.modificationCount == null) {
+ this.modificationCount = this.tree.getModificationCount();
+ let node2 = this.tree.getRoot();
+ while (node2 != null) {
+ this.path.push(node2);
+ node2 = node2.left;
+ }
+ return this.path.length > 0;
+ }
+ throw "Concurrent modification during iteration.";
+ }
+ if (!this.path.length)
+ return false;
+ if (this.splayCount != this.tree.getSplayCount()) {
+ this.rebuildPath(this.path[this.path.length - 1].key);
+ }
+ let node = this.path[this.path.length - 1];
+ let next = node.right;
+ if (next != null) {
+ while (next != null) {
+ this.path.push(next);
+ next = next.left;
+ }
+ return true;
+ }
+ this.path.pop();
+ while (this.path.length && this.path[this.path.length - 1].right === node) {
+ node = this.path.pop();
+ }
+ return this.path.length > 0;
+ }
+ };
+ var SplayTreeKeyIterableIterator = class extends SplayTreeIterableIterator {
+ getValue(node) {
+ return node.key;
+ }
+ };
+ var SplayTreeSetEntryIterableIterator = class extends SplayTreeIterableIterator {
+ getValue(node) {
+ return [node.key, node.key];
+ }
+ };
+
+ // node_modules/polyclip-ts/dist/identity.js
+ var identity_default3 = (x2) => {
+ return x2;
+ };
+
+ // node_modules/polyclip-ts/dist/snap.js
+ var snap_default = (eps) => {
+ if (eps) {
+ const xTree = new SplayTreeSet(compare_default(eps));
+ const yTree = new SplayTreeSet(compare_default(eps));
+ const snapCoord = (coord2, tree) => {
+ return tree.addAndReturn(coord2);
+ };
+ const snap = (v2) => {
+ return {
+ x: snapCoord(v2.x, xTree),
+ y: snapCoord(v2.y, yTree)
+ };
+ };
+ snap({ x: new bignumber_default(0), y: new bignumber_default(0) });
+ return snap;
+ }
+ return identity_default3;
+ };
+
+ // node_modules/polyclip-ts/dist/precision.js
+ var set3 = (eps) => {
+ return {
+ set: (eps2) => {
+ precision = set3(eps2);
+ },
+ reset: () => set3(eps),
+ compare: compare_default(eps),
+ snap: snap_default(eps),
+ orient: orient_default(eps)
+ };
+ };
+ var precision = set3();
+
+ // node_modules/polyclip-ts/dist/bbox.js
+ var isInBbox = (bbox2, point2) => {
+ return bbox2.ll.x.isLessThanOrEqualTo(point2.x) && point2.x.isLessThanOrEqualTo(bbox2.ur.x) && bbox2.ll.y.isLessThanOrEqualTo(point2.y) && point2.y.isLessThanOrEqualTo(bbox2.ur.y);
+ };
+ var getBboxOverlap = (b1, b2) => {
+ if (b2.ur.x.isLessThan(b1.ll.x) || b1.ur.x.isLessThan(b2.ll.x) || b2.ur.y.isLessThan(b1.ll.y) || b1.ur.y.isLessThan(b2.ll.y))
+ return null;
+ const lowerX = b1.ll.x.isLessThan(b2.ll.x) ? b2.ll.x : b1.ll.x;
+ const upperX = b1.ur.x.isLessThan(b2.ur.x) ? b1.ur.x : b2.ur.x;
+ const lowerY = b1.ll.y.isLessThan(b2.ll.y) ? b2.ll.y : b1.ll.y;
+ const upperY = b1.ur.y.isLessThan(b2.ur.y) ? b1.ur.y : b2.ur.y;
+ return { ll: { x: lowerX, y: lowerY }, ur: { x: upperX, y: upperY } };
+ };
+
+ // node_modules/polyclip-ts/dist/vector.js
+ var crossProduct = (a2, b2) => a2.x.times(b2.y).minus(a2.y.times(b2.x));
+ var dotProduct = (a2, b2) => a2.x.times(b2.x).plus(a2.y.times(b2.y));
+ var length = (v2) => dotProduct(v2, v2).sqrt();
+ var sineOfAngle = (pShared, pBase, pAngle) => {
+ const vBase = { x: pBase.x.minus(pShared.x), y: pBase.y.minus(pShared.y) };
+ const vAngle = { x: pAngle.x.minus(pShared.x), y: pAngle.y.minus(pShared.y) };
+ return crossProduct(vAngle, vBase).div(length(vAngle)).div(length(vBase));
+ };
+ var cosineOfAngle = (pShared, pBase, pAngle) => {
+ const vBase = { x: pBase.x.minus(pShared.x), y: pBase.y.minus(pShared.y) };
+ const vAngle = { x: pAngle.x.minus(pShared.x), y: pAngle.y.minus(pShared.y) };
+ return dotProduct(vAngle, vBase).div(length(vAngle)).div(length(vBase));
+ };
+ var horizontalIntersection = (pt2, v2, y2) => {
+ if (v2.y.isZero())
+ return null;
+ return { x: pt2.x.plus(v2.x.div(v2.y).times(y2.minus(pt2.y))), y: y2 };
+ };
+ var verticalIntersection = (pt2, v2, x2) => {
+ if (v2.x.isZero())
+ return null;
+ return { x: x2, y: pt2.y.plus(v2.y.div(v2.x).times(x2.minus(pt2.x))) };
+ };
+ var intersection = (pt1, v1, pt2, v2) => {
+ if (v1.x.isZero())
+ return verticalIntersection(pt2, v2, pt1.x);
+ if (v2.x.isZero())
+ return verticalIntersection(pt1, v1, pt2.x);
+ if (v1.y.isZero())
+ return horizontalIntersection(pt2, v2, pt1.y);
+ if (v2.y.isZero())
+ return horizontalIntersection(pt1, v1, pt2.y);
+ const kross = crossProduct(v1, v2);
+ if (kross.isZero())
+ return null;
+ const ve2 = { x: pt2.x.minus(pt1.x), y: pt2.y.minus(pt1.y) };
+ const d1 = crossProduct(ve2, v1).div(kross);
+ const d2 = crossProduct(ve2, v2).div(kross);
+ const x12 = pt1.x.plus(d2.times(v1.x)), x2 = pt2.x.plus(d1.times(v2.x));
+ const y12 = pt1.y.plus(d2.times(v1.y)), y2 = pt2.y.plus(d1.times(v2.y));
+ const x3 = x12.plus(x2).div(2);
+ const y3 = y12.plus(y2).div(2);
+ return { x: x3, y: y3 };
+ };
+
+ // node_modules/polyclip-ts/dist/sweep-event.js
+ var SweepEvent = class _SweepEvent {
+ // Warning: 'point' input will be modified and re-used (for performance)
+ constructor(point2, isLeft) {
+ __publicField(this, "point");
+ __publicField(this, "isLeft");
+ __publicField(this, "segment");
+ __publicField(this, "otherSE");
+ __publicField(this, "consumedBy");
+ if (point2.events === void 0)
+ point2.events = [this];
+ else
+ point2.events.push(this);
+ this.point = point2;
+ this.isLeft = isLeft;
+ }
+ // for ordering sweep events in the sweep event queue
+ static compare(a2, b2) {
+ const ptCmp = _SweepEvent.comparePoints(a2.point, b2.point);
+ if (ptCmp !== 0)
+ return ptCmp;
+ if (a2.point !== b2.point)
+ a2.link(b2);
+ if (a2.isLeft !== b2.isLeft)
+ return a2.isLeft ? 1 : -1;
+ return Segment.compare(a2.segment, b2.segment);
+ }
+ // for ordering points in sweep line order
+ static comparePoints(aPt, bPt) {
+ if (aPt.x.isLessThan(bPt.x))
+ return -1;
+ if (aPt.x.isGreaterThan(bPt.x))
+ return 1;
+ if (aPt.y.isLessThan(bPt.y))
+ return -1;
+ if (aPt.y.isGreaterThan(bPt.y))
+ return 1;
+ return 0;
+ }
+ link(other) {
+ if (other.point === this.point) {
+ throw new Error("Tried to link already linked events");
+ }
+ const otherEvents = other.point.events;
+ for (let i3 = 0, iMax = otherEvents.length; i3 < iMax; i3++) {
+ const evt = otherEvents[i3];
+ this.point.events.push(evt);
+ evt.point = this.point;
+ }
+ this.checkForConsuming();
+ }
+ /* Do a pass over our linked events and check to see if any pair
+ * of segments match, and should be consumed. */
+ checkForConsuming() {
+ const numEvents = this.point.events.length;
+ for (let i3 = 0; i3 < numEvents; i3++) {
+ const evt1 = this.point.events[i3];
+ if (evt1.segment.consumedBy !== void 0)
+ continue;
+ for (let j2 = i3 + 1; j2 < numEvents; j2++) {
+ const evt2 = this.point.events[j2];
+ if (evt2.consumedBy !== void 0)
+ continue;
+ if (evt1.otherSE.point.events !== evt2.otherSE.point.events)
+ continue;
+ evt1.segment.consume(evt2.segment);
+ }
+ }
+ }
+ getAvailableLinkedEvents() {
+ const events = [];
+ for (let i3 = 0, iMax = this.point.events.length; i3 < iMax; i3++) {
+ const evt = this.point.events[i3];
+ if (evt !== this && !evt.segment.ringOut && evt.segment.isInResult()) {
+ events.push(evt);
+ }
+ }
+ return events;
+ }
+ /**
+ * Returns a comparator function for sorting linked events that will
+ * favor the event that will give us the smallest left-side angle.
+ * All ring construction starts as low as possible heading to the right,
+ * so by always turning left as sharp as possible we'll get polygons
+ * without uncessary loops & holes.
+ *
+ * The comparator function has a compute cache such that it avoids
+ * re-computing already-computed values.
+ */
+ getLeftmostComparator(baseEvent) {
+ const cache = /* @__PURE__ */ new Map();
+ const fillCache = (linkedEvent) => {
+ const nextEvent = linkedEvent.otherSE;
+ cache.set(linkedEvent, {
+ sine: sineOfAngle(this.point, baseEvent.point, nextEvent.point),
+ cosine: cosineOfAngle(this.point, baseEvent.point, nextEvent.point)
+ });
+ };
+ return (a2, b2) => {
+ if (!cache.has(a2))
+ fillCache(a2);
+ if (!cache.has(b2))
+ fillCache(b2);
+ const { sine: asine, cosine: acosine } = cache.get(a2);
+ const { sine: bsine, cosine: bcosine } = cache.get(b2);
+ if (asine.isGreaterThanOrEqualTo(0) && bsine.isGreaterThanOrEqualTo(0)) {
+ if (acosine.isLessThan(bcosine))
+ return 1;
+ if (acosine.isGreaterThan(bcosine))
+ return -1;
+ return 0;
+ }
+ if (asine.isLessThan(0) && bsine.isLessThan(0)) {
+ if (acosine.isLessThan(bcosine))
+ return -1;
+ if (acosine.isGreaterThan(bcosine))
+ return 1;
+ return 0;
+ }
+ if (bsine.isLessThan(asine))
+ return -1;
+ if (bsine.isGreaterThan(asine))
+ return 1;
+ return 0;
+ };
+ }
+ };
+
+ // node_modules/polyclip-ts/dist/segment.js
+ var segmentId = 0;
+ var Segment = class _Segment {
+ /* Warning: a reference to ringWindings input will be stored,
+ * and possibly will be later modified */
+ constructor(leftSE, rightSE, rings, windings) {
+ __publicField(this, "id");
+ __publicField(this, "leftSE");
+ __publicField(this, "rightSE");
+ __publicField(this, "rings");
+ __publicField(this, "windings");
+ __publicField(this, "ringOut");
+ __publicField(this, "consumedBy");
+ __publicField(this, "prev");
+ __publicField(this, "_prevInResult");
+ __publicField(this, "_beforeState");
+ __publicField(this, "_afterState");
+ __publicField(this, "_isInResult");
+ this.id = ++segmentId;
+ this.leftSE = leftSE;
+ leftSE.segment = this;
+ leftSE.otherSE = rightSE;
+ this.rightSE = rightSE;
+ rightSE.segment = this;
+ rightSE.otherSE = leftSE;
+ this.rings = rings;
+ this.windings = windings;
+ }
+ /* This compare() function is for ordering segments in the sweep
+ * line tree, and does so according to the following criteria:
+ *
+ * Consider the vertical line that lies an infinestimal step to the
+ * right of the right-more of the two left endpoints of the input
+ * segments. Imagine slowly moving a point up from negative infinity
+ * in the increasing y direction. Which of the two segments will that
+ * point intersect first? That segment comes 'before' the other one.
+ *
+ * If neither segment would be intersected by such a line, (if one
+ * or more of the segments are vertical) then the line to be considered
+ * is directly on the right-more of the two left inputs.
+ */
+ static compare(a2, b2) {
+ const alx = a2.leftSE.point.x;
+ const blx = b2.leftSE.point.x;
+ const arx = a2.rightSE.point.x;
+ const brx = b2.rightSE.point.x;
+ if (brx.isLessThan(alx))
+ return 1;
+ if (arx.isLessThan(blx))
+ return -1;
+ const aly = a2.leftSE.point.y;
+ const bly = b2.leftSE.point.y;
+ const ary = a2.rightSE.point.y;
+ const bry = b2.rightSE.point.y;
+ if (alx.isLessThan(blx)) {
+ if (bly.isLessThan(aly) && bly.isLessThan(ary))
+ return 1;
+ if (bly.isGreaterThan(aly) && bly.isGreaterThan(ary))
+ return -1;
+ const aCmpBLeft = a2.comparePoint(b2.leftSE.point);
+ if (aCmpBLeft < 0)
+ return 1;
+ if (aCmpBLeft > 0)
+ return -1;
+ const bCmpARight = b2.comparePoint(a2.rightSE.point);
+ if (bCmpARight !== 0)
+ return bCmpARight;
+ return -1;
+ }
+ if (alx.isGreaterThan(blx)) {
+ if (aly.isLessThan(bly) && aly.isLessThan(bry))
+ return -1;
+ if (aly.isGreaterThan(bly) && aly.isGreaterThan(bry))
+ return 1;
+ const bCmpALeft = b2.comparePoint(a2.leftSE.point);
+ if (bCmpALeft !== 0)
+ return bCmpALeft;
+ const aCmpBRight = a2.comparePoint(b2.rightSE.point);
+ if (aCmpBRight < 0)
+ return 1;
+ if (aCmpBRight > 0)
+ return -1;
+ return 1;
+ }
+ if (aly.isLessThan(bly))
+ return -1;
+ if (aly.isGreaterThan(bly))
+ return 1;
+ if (arx.isLessThan(brx)) {
+ const bCmpARight = b2.comparePoint(a2.rightSE.point);
+ if (bCmpARight !== 0)
+ return bCmpARight;
+ }
+ if (arx.isGreaterThan(brx)) {
+ const aCmpBRight = a2.comparePoint(b2.rightSE.point);
+ if (aCmpBRight < 0)
+ return 1;
+ if (aCmpBRight > 0)
+ return -1;
+ }
+ if (!arx.eq(brx)) {
+ const ay = ary.minus(aly);
+ const ax = arx.minus(alx);
+ const by = bry.minus(bly);
+ const bx = brx.minus(blx);
+ if (ay.isGreaterThan(ax) && by.isLessThan(bx))
+ return 1;
+ if (ay.isLessThan(ax) && by.isGreaterThan(bx))
+ return -1;
+ }
+ if (arx.isGreaterThan(brx))
+ return 1;
+ if (arx.isLessThan(brx))
+ return -1;
+ if (ary.isLessThan(bry))
+ return -1;
+ if (ary.isGreaterThan(bry))
+ return 1;
+ if (a2.id < b2.id)
+ return -1;
+ if (a2.id > b2.id)
+ return 1;
+ return 0;
+ }
+ static fromRing(pt1, pt2, ring) {
+ let leftPt, rightPt, winding;
+ const cmpPts = SweepEvent.comparePoints(pt1, pt2);
+ if (cmpPts < 0) {
+ leftPt = pt1;
+ rightPt = pt2;
+ winding = 1;
+ } else if (cmpPts > 0) {
+ leftPt = pt2;
+ rightPt = pt1;
+ winding = -1;
+ } else
+ throw new Error("Tried to create degenerate segment at [".concat(pt1.x, ", ").concat(pt1.y, "]"));
+ const leftSE = new SweepEvent(leftPt, true);
+ const rightSE = new SweepEvent(rightPt, false);
+ return new _Segment(leftSE, rightSE, [ring], [winding]);
+ }
+ /* When a segment is split, the rightSE is replaced with a new sweep event */
+ replaceRightSE(newRightSE) {
+ this.rightSE = newRightSE;
+ this.rightSE.segment = this;
+ this.rightSE.otherSE = this.leftSE;
+ this.leftSE.otherSE = this.rightSE;
+ }
+ bbox() {
+ const y12 = this.leftSE.point.y;
+ const y2 = this.rightSE.point.y;
+ return {
+ ll: { x: this.leftSE.point.x, y: y12.isLessThan(y2) ? y12 : y2 },
+ ur: { x: this.rightSE.point.x, y: y12.isGreaterThan(y2) ? y12 : y2 }
+ };
+ }
+ /* A vector from the left point to the right */
+ vector() {
+ return {
+ x: this.rightSE.point.x.minus(this.leftSE.point.x),
+ y: this.rightSE.point.y.minus(this.leftSE.point.y)
+ };
+ }
+ isAnEndpoint(pt2) {
+ return pt2.x.eq(this.leftSE.point.x) && pt2.y.eq(this.leftSE.point.y) || pt2.x.eq(this.rightSE.point.x) && pt2.y.eq(this.rightSE.point.y);
+ }
+ /* Compare this segment with a point.
+ *
+ * A point P is considered to be colinear to a segment if there
+ * exists a distance D such that if we travel along the segment
+ * from one * endpoint towards the other a distance D, we find
+ * ourselves at point P.
+ *
+ * Return value indicates:
+ *
+ * 1: point lies above the segment (to the left of vertical)
+ * 0: point is colinear to segment
+ * -1: point lies below the segment (to the right of vertical)
+ */
+ comparePoint(point2) {
+ return precision.orient(this.leftSE.point, point2, this.rightSE.point);
+ }
+ /**
+ * Given another segment, returns the first non-trivial intersection
+ * between the two segments (in terms of sweep line ordering), if it exists.
+ *
+ * A 'non-trivial' intersection is one that will cause one or both of the
+ * segments to be split(). As such, 'trivial' vs. 'non-trivial' intersection:
+ *
+ * * endpoint of segA with endpoint of segB --> trivial
+ * * endpoint of segA with point along segB --> non-trivial
+ * * endpoint of segB with point along segA --> non-trivial
+ * * point along segA with point along segB --> non-trivial
+ *
+ * If no non-trivial intersection exists, return null
+ * Else, return null.
+ */
+ getIntersection(other) {
+ const tBbox = this.bbox();
+ const oBbox = other.bbox();
+ const bboxOverlap = getBboxOverlap(tBbox, oBbox);
+ if (bboxOverlap === null)
+ return null;
+ const tlp = this.leftSE.point;
+ const trp = this.rightSE.point;
+ const olp = other.leftSE.point;
+ const orp = other.rightSE.point;
+ const touchesOtherLSE = isInBbox(tBbox, olp) && this.comparePoint(olp) === 0;
+ const touchesThisLSE = isInBbox(oBbox, tlp) && other.comparePoint(tlp) === 0;
+ const touchesOtherRSE = isInBbox(tBbox, orp) && this.comparePoint(orp) === 0;
+ const touchesThisRSE = isInBbox(oBbox, trp) && other.comparePoint(trp) === 0;
+ if (touchesThisLSE && touchesOtherLSE) {
+ if (touchesThisRSE && !touchesOtherRSE)
+ return trp;
+ if (!touchesThisRSE && touchesOtherRSE)
+ return orp;
+ return null;
+ }
+ if (touchesThisLSE) {
+ if (touchesOtherRSE) {
+ if (tlp.x.eq(orp.x) && tlp.y.eq(orp.y))
+ return null;
+ }
+ return tlp;
+ }
+ if (touchesOtherLSE) {
+ if (touchesThisRSE) {
+ if (trp.x.eq(olp.x) && trp.y.eq(olp.y))
+ return null;
+ }
+ return olp;
+ }
+ if (touchesThisRSE && touchesOtherRSE)
+ return null;
+ if (touchesThisRSE)
+ return trp;
+ if (touchesOtherRSE)
+ return orp;
+ const pt2 = intersection(tlp, this.vector(), olp, other.vector());
+ if (pt2 === null)
+ return null;
+ if (!isInBbox(bboxOverlap, pt2))
+ return null;
+ return precision.snap(pt2);
+ }
+ /**
+ * Split the given segment into multiple segments on the given points.
+ * * Each existing segment will retain its leftSE and a new rightSE will be
+ * generated for it.
+ * * A new segment will be generated which will adopt the original segment's
+ * rightSE, and a new leftSE will be generated for it.
+ * * If there are more than two points given to split on, new segments
+ * in the middle will be generated with new leftSE and rightSE's.
+ * * An array of the newly generated SweepEvents will be returned.
+ *
+ * Warning: input array of points is modified
+ */
+ split(point2) {
+ const newEvents = [];
+ const alreadyLinked = point2.events !== void 0;
+ const newLeftSE = new SweepEvent(point2, true);
+ const newRightSE = new SweepEvent(point2, false);
+ const oldRightSE = this.rightSE;
+ this.replaceRightSE(newRightSE);
+ newEvents.push(newRightSE);
+ newEvents.push(newLeftSE);
+ const newSeg = new _Segment(newLeftSE, oldRightSE, this.rings.slice(), this.windings.slice());
+ if (SweepEvent.comparePoints(newSeg.leftSE.point, newSeg.rightSE.point) > 0) {
+ newSeg.swapEvents();
+ }
+ if (SweepEvent.comparePoints(this.leftSE.point, this.rightSE.point) > 0) {
+ this.swapEvents();
+ }
+ if (alreadyLinked) {
+ newLeftSE.checkForConsuming();
+ newRightSE.checkForConsuming();
+ }
+ return newEvents;
+ }
+ /* Swap which event is left and right */
+ swapEvents() {
+ const tmpEvt = this.rightSE;
+ this.rightSE = this.leftSE;
+ this.leftSE = tmpEvt;
+ this.leftSE.isLeft = true;
+ this.rightSE.isLeft = false;
+ for (let i3 = 0, iMax = this.windings.length; i3 < iMax; i3++) {
+ this.windings[i3] *= -1;
+ }
+ }
+ /* Consume another segment. We take their rings under our wing
+ * and mark them as consumed. Use for perfectly overlapping segments */
+ consume(other) {
+ let consumer = this;
+ let consumee = other;
+ while (consumer.consumedBy)
+ consumer = consumer.consumedBy;
+ while (consumee.consumedBy)
+ consumee = consumee.consumedBy;
+ const cmp = _Segment.compare(consumer, consumee);
+ if (cmp === 0)
+ return;
+ if (cmp > 0) {
+ const tmp = consumer;
+ consumer = consumee;
+ consumee = tmp;
+ }
+ if (consumer.prev === consumee) {
+ const tmp = consumer;
+ consumer = consumee;
+ consumee = tmp;
+ }
+ for (let i3 = 0, iMax = consumee.rings.length; i3 < iMax; i3++) {
+ const ring = consumee.rings[i3];
+ const winding = consumee.windings[i3];
+ const index = consumer.rings.indexOf(ring);
+ if (index === -1) {
+ consumer.rings.push(ring);
+ consumer.windings.push(winding);
+ } else
+ consumer.windings[index] += winding;
+ }
+ consumee.rings = null;
+ consumee.windings = null;
+ consumee.consumedBy = consumer;
+ consumee.leftSE.consumedBy = consumer.leftSE;
+ consumee.rightSE.consumedBy = consumer.rightSE;
+ }
+ /* The first segment previous segment chain that is in the result */
+ prevInResult() {
+ if (this._prevInResult !== void 0)
+ return this._prevInResult;
+ if (!this.prev)
+ this._prevInResult = null;
+ else if (this.prev.isInResult())
+ this._prevInResult = this.prev;
+ else
+ this._prevInResult = this.prev.prevInResult();
+ return this._prevInResult;
+ }
+ beforeState() {
+ if (this._beforeState !== void 0)
+ return this._beforeState;
+ if (!this.prev)
+ this._beforeState = {
+ rings: [],
+ windings: [],
+ multiPolys: []
+ };
+ else {
+ const seg = this.prev.consumedBy || this.prev;
+ this._beforeState = seg.afterState();
+ }
+ return this._beforeState;
+ }
+ afterState() {
+ if (this._afterState !== void 0)
+ return this._afterState;
+ const beforeState = this.beforeState();
+ this._afterState = {
+ rings: beforeState.rings.slice(0),
+ windings: beforeState.windings.slice(0),
+ multiPolys: []
+ };
+ const ringsAfter = this._afterState.rings;
+ const windingsAfter = this._afterState.windings;
+ const mpsAfter = this._afterState.multiPolys;
+ for (let i3 = 0, iMax = this.rings.length; i3 < iMax; i3++) {
+ const ring = this.rings[i3];
+ const winding = this.windings[i3];
+ const index = ringsAfter.indexOf(ring);
+ if (index === -1) {
+ ringsAfter.push(ring);
+ windingsAfter.push(winding);
+ } else
+ windingsAfter[index] += winding;
+ }
+ const polysAfter = [];
+ const polysExclude = [];
+ for (let i3 = 0, iMax = ringsAfter.length; i3 < iMax; i3++) {
+ if (windingsAfter[i3] === 0)
+ continue;
+ const ring = ringsAfter[i3];
+ const poly = ring.poly;
+ if (polysExclude.indexOf(poly) !== -1)
+ continue;
+ if (ring.isExterior)
+ polysAfter.push(poly);
+ else {
+ if (polysExclude.indexOf(poly) === -1)
+ polysExclude.push(poly);
+ const index = polysAfter.indexOf(ring.poly);
+ if (index !== -1)
+ polysAfter.splice(index, 1);
+ }
+ }
+ for (let i3 = 0, iMax = polysAfter.length; i3 < iMax; i3++) {
+ const mp = polysAfter[i3].multiPoly;
+ if (mpsAfter.indexOf(mp) === -1)
+ mpsAfter.push(mp);
+ }
+ return this._afterState;
+ }
+ /* Is this segment part of the final result? */
+ isInResult() {
+ if (this.consumedBy)
+ return false;
+ if (this._isInResult !== void 0)
+ return this._isInResult;
+ const mpsBefore = this.beforeState().multiPolys;
+ const mpsAfter = this.afterState().multiPolys;
+ switch (operation_default.type) {
+ case "union": {
+ const noBefores = mpsBefore.length === 0;
+ const noAfters = mpsAfter.length === 0;
+ this._isInResult = noBefores !== noAfters;
+ break;
+ }
+ case "intersection": {
+ let least;
+ let most;
+ if (mpsBefore.length < mpsAfter.length) {
+ least = mpsBefore.length;
+ most = mpsAfter.length;
+ } else {
+ least = mpsAfter.length;
+ most = mpsBefore.length;
+ }
+ this._isInResult = most === operation_default.numMultiPolys && least < most;
+ break;
+ }
+ case "xor": {
+ const diff = Math.abs(mpsBefore.length - mpsAfter.length);
+ this._isInResult = diff % 2 === 1;
+ break;
+ }
+ case "difference": {
+ const isJustSubject = (mps) => mps.length === 1 && mps[0].isSubject;
+ this._isInResult = isJustSubject(mpsBefore) !== isJustSubject(mpsAfter);
+ break;
+ }
+ }
+ return this._isInResult;
+ }
+ };
+
+ // node_modules/polyclip-ts/dist/geom-in.js
+ var RingIn = class {
+ constructor(geomRing, poly, isExterior) {
+ __publicField(this, "poly");
+ __publicField(this, "isExterior");
+ __publicField(this, "segments");
+ __publicField(this, "bbox");
+ if (!Array.isArray(geomRing) || geomRing.length === 0) {
+ throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
+ }
+ this.poly = poly;
+ this.isExterior = isExterior;
+ this.segments = [];
+ if (typeof geomRing[0][0] !== "number" || typeof geomRing[0][1] !== "number") {
+ throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
+ }
+ const firstPoint = precision.snap({ x: new bignumber_default(geomRing[0][0]), y: new bignumber_default(geomRing[0][1]) });
+ this.bbox = {
+ ll: { x: firstPoint.x, y: firstPoint.y },
+ ur: { x: firstPoint.x, y: firstPoint.y }
+ };
+ let prevPoint = firstPoint;
+ for (let i3 = 1, iMax = geomRing.length; i3 < iMax; i3++) {
+ if (typeof geomRing[i3][0] !== "number" || typeof geomRing[i3][1] !== "number") {
+ throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
+ }
+ const point2 = precision.snap({ x: new bignumber_default(geomRing[i3][0]), y: new bignumber_default(geomRing[i3][1]) });
+ if (point2.x.eq(prevPoint.x) && point2.y.eq(prevPoint.y))
+ continue;
+ this.segments.push(Segment.fromRing(prevPoint, point2, this));
+ if (point2.x.isLessThan(this.bbox.ll.x))
+ this.bbox.ll.x = point2.x;
+ if (point2.y.isLessThan(this.bbox.ll.y))
+ this.bbox.ll.y = point2.y;
+ if (point2.x.isGreaterThan(this.bbox.ur.x))
+ this.bbox.ur.x = point2.x;
+ if (point2.y.isGreaterThan(this.bbox.ur.y))
+ this.bbox.ur.y = point2.y;
+ prevPoint = point2;
+ }
+ if (!firstPoint.x.eq(prevPoint.x) || !firstPoint.y.eq(prevPoint.y)) {
+ this.segments.push(Segment.fromRing(prevPoint, firstPoint, this));
+ }
+ }
+ getSweepEvents() {
+ const sweepEvents = [];
+ for (let i3 = 0, iMax = this.segments.length; i3 < iMax; i3++) {
+ const segment = this.segments[i3];
+ sweepEvents.push(segment.leftSE);
+ sweepEvents.push(segment.rightSE);
+ }
+ return sweepEvents;
+ }
+ };
+ var PolyIn = class {
+ constructor(geomPoly, multiPoly) {
+ __publicField(this, "multiPoly");
+ __publicField(this, "exteriorRing");
+ __publicField(this, "interiorRings");
+ __publicField(this, "bbox");
+ if (!Array.isArray(geomPoly)) {
+ throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
+ }
+ this.exteriorRing = new RingIn(geomPoly[0], this, true);
+ this.bbox = {
+ ll: { x: this.exteriorRing.bbox.ll.x, y: this.exteriorRing.bbox.ll.y },
+ ur: { x: this.exteriorRing.bbox.ur.x, y: this.exteriorRing.bbox.ur.y }
+ };
+ this.interiorRings = [];
+ for (let i3 = 1, iMax = geomPoly.length; i3 < iMax; i3++) {
+ const ring = new RingIn(geomPoly[i3], this, false);
+ if (ring.bbox.ll.x.isLessThan(this.bbox.ll.x))
+ this.bbox.ll.x = ring.bbox.ll.x;
+ if (ring.bbox.ll.y.isLessThan(this.bbox.ll.y))
+ this.bbox.ll.y = ring.bbox.ll.y;
+ if (ring.bbox.ur.x.isGreaterThan(this.bbox.ur.x))
+ this.bbox.ur.x = ring.bbox.ur.x;
+ if (ring.bbox.ur.y.isGreaterThan(this.bbox.ur.y))
+ this.bbox.ur.y = ring.bbox.ur.y;
+ this.interiorRings.push(ring);
+ }
+ this.multiPoly = multiPoly;
+ }
+ getSweepEvents() {
+ const sweepEvents = this.exteriorRing.getSweepEvents();
+ for (let i3 = 0, iMax = this.interiorRings.length; i3 < iMax; i3++) {
+ const ringSweepEvents = this.interiorRings[i3].getSweepEvents();
+ for (let j2 = 0, jMax = ringSweepEvents.length; j2 < jMax; j2++) {
+ sweepEvents.push(ringSweepEvents[j2]);
+ }
+ }
+ return sweepEvents;
+ }
+ };
+ var MultiPolyIn = class {
+ constructor(geom, isSubject) {
+ __publicField(this, "isSubject");
+ __publicField(this, "polys");
+ __publicField(this, "bbox");
+ if (!Array.isArray(geom)) {
+ throw new Error("Input geometry is not a valid Polygon or MultiPolygon");
+ }
+ try {
+ if (typeof geom[0][0][0] === "number")
+ geom = [geom];
+ } catch (ex) {
+ }
+ this.polys = [];
+ this.bbox = {
+ ll: { x: new bignumber_default(Number.POSITIVE_INFINITY), y: new bignumber_default(Number.POSITIVE_INFINITY) },
+ ur: { x: new bignumber_default(Number.NEGATIVE_INFINITY), y: new bignumber_default(Number.NEGATIVE_INFINITY) }
+ };
+ for (let i3 = 0, iMax = geom.length; i3 < iMax; i3++) {
+ const poly = new PolyIn(geom[i3], this);
+ if (poly.bbox.ll.x.isLessThan(this.bbox.ll.x))
+ this.bbox.ll.x = poly.bbox.ll.x;
+ if (poly.bbox.ll.y.isLessThan(this.bbox.ll.y))
+ this.bbox.ll.y = poly.bbox.ll.y;
+ if (poly.bbox.ur.x.isGreaterThan(this.bbox.ur.x))
+ this.bbox.ur.x = poly.bbox.ur.x;
+ if (poly.bbox.ur.y.isGreaterThan(this.bbox.ur.y))
+ this.bbox.ur.y = poly.bbox.ur.y;
+ this.polys.push(poly);
+ }
+ this.isSubject = isSubject;
+ }
+ getSweepEvents() {
+ const sweepEvents = [];
+ for (let i3 = 0, iMax = this.polys.length; i3 < iMax; i3++) {
+ const polySweepEvents = this.polys[i3].getSweepEvents();
+ for (let j2 = 0, jMax = polySweepEvents.length; j2 < jMax; j2++) {
+ sweepEvents.push(polySweepEvents[j2]);
+ }
+ }
+ return sweepEvents;
+ }
+ };
+
+ // node_modules/polyclip-ts/dist/geom-out.js
+ var RingOut = class _RingOut {
+ constructor(events) {
+ __publicField(this, "events");
+ __publicField(this, "poly");
+ __publicField(this, "_isExteriorRing");
+ __publicField(this, "_enclosingRing");
+ this.events = events;
+ for (let i3 = 0, iMax = events.length; i3 < iMax; i3++) {
+ events[i3].segment.ringOut = this;
+ }
+ this.poly = null;
+ }
+ /* Given the segments from the sweep line pass, compute & return a series
+ * of closed rings from all the segments marked to be part of the result */
+ static factory(allSegments) {
+ const ringsOut = [];
+ for (let i3 = 0, iMax = allSegments.length; i3 < iMax; i3++) {
+ const segment = allSegments[i3];
+ if (!segment.isInResult() || segment.ringOut)
+ continue;
+ let prevEvent = null;
+ let event = segment.leftSE;
+ let nextEvent = segment.rightSE;
+ const events = [event];
+ const startingPoint = event.point;
+ const intersectionLEs = [];
+ while (true) {
+ prevEvent = event;
+ event = nextEvent;
+ events.push(event);
+ if (event.point === startingPoint)
+ break;
+ while (true) {
+ const availableLEs = event.getAvailableLinkedEvents();
+ if (availableLEs.length === 0) {
+ const firstPt = events[0].point;
+ const lastPt = events[events.length - 1].point;
+ throw new Error("Unable to complete output ring starting at [".concat(firstPt.x, ",") + " ".concat(firstPt.y, "]. Last matching segment found ends at") + " [".concat(lastPt.x, ", ").concat(lastPt.y, "]."));
+ }
+ if (availableLEs.length === 1) {
+ nextEvent = availableLEs[0].otherSE;
+ break;
+ }
+ let indexLE = null;
+ for (let j2 = 0, jMax = intersectionLEs.length; j2 < jMax; j2++) {
+ if (intersectionLEs[j2].point === event.point) {
+ indexLE = j2;
+ break;
+ }
+ }
+ if (indexLE !== null) {
+ const intersectionLE = intersectionLEs.splice(indexLE)[0];
+ const ringEvents = events.splice(intersectionLE.index);
+ ringEvents.unshift(ringEvents[0].otherSE);
+ ringsOut.push(new _RingOut(ringEvents.reverse()));
+ continue;
+ }
+ intersectionLEs.push({
+ index: events.length,
+ point: event.point
+ });
+ const comparator = event.getLeftmostComparator(prevEvent);
+ nextEvent = availableLEs.sort(comparator)[0].otherSE;
+ break;
+ }
+ }
+ ringsOut.push(new _RingOut(events));
+ }
+ return ringsOut;
+ }
+ getGeom() {
+ let prevPt = this.events[0].point;
+ const points = [prevPt];
+ for (let i3 = 1, iMax = this.events.length - 1; i3 < iMax; i3++) {
+ const pt3 = this.events[i3].point;
+ const nextPt2 = this.events[i3 + 1].point;
+ if (precision.orient(pt3, prevPt, nextPt2) === 0)
+ continue;
+ points.push(pt3);
+ prevPt = pt3;
+ }
+ if (points.length === 1)
+ return null;
+ const pt2 = points[0];
+ const nextPt = points[1];
+ if (precision.orient(pt2, prevPt, nextPt) === 0)
+ points.shift();
+ points.push(points[0]);
+ const step = this.isExteriorRing() ? 1 : -1;
+ const iStart = this.isExteriorRing() ? 0 : points.length - 1;
+ const iEnd = this.isExteriorRing() ? points.length : -1;
+ const orderedPoints = [];
+ for (let i3 = iStart; i3 != iEnd; i3 += step)
+ orderedPoints.push([points[i3].x.toNumber(), points[i3].y.toNumber()]);
+ return orderedPoints;
+ }
+ isExteriorRing() {
+ if (this._isExteriorRing === void 0) {
+ const enclosing = this.enclosingRing();
+ this._isExteriorRing = enclosing ? !enclosing.isExteriorRing() : true;
+ }
+ return this._isExteriorRing;
+ }
+ enclosingRing() {
+ if (this._enclosingRing === void 0) {
+ this._enclosingRing = this._calcEnclosingRing();
+ }
+ return this._enclosingRing;
+ }
+ /* Returns the ring that encloses this one, if any */
+ _calcEnclosingRing() {
+ var _a2, _b;
+ let leftMostEvt = this.events[0];
+ for (let i3 = 1, iMax = this.events.length; i3 < iMax; i3++) {
+ const evt = this.events[i3];
+ if (SweepEvent.compare(leftMostEvt, evt) > 0)
+ leftMostEvt = evt;
+ }
+ let prevSeg = leftMostEvt.segment.prevInResult();
+ let prevPrevSeg = prevSeg ? prevSeg.prevInResult() : null;
+ while (true) {
+ if (!prevSeg)
+ return null;
+ if (!prevPrevSeg)
+ return prevSeg.ringOut;
+ if (prevPrevSeg.ringOut !== prevSeg.ringOut) {
+ if (((_a2 = prevPrevSeg.ringOut) == null ? void 0 : _a2.enclosingRing()) !== prevSeg.ringOut) {
+ return prevSeg.ringOut;
+ } else
+ return (_b = prevSeg.ringOut) == null ? void 0 : _b.enclosingRing();
+ }
+ prevSeg = prevPrevSeg.prevInResult();
+ prevPrevSeg = prevSeg ? prevSeg.prevInResult() : null;
+ }
+ }
+ };
+ var PolyOut = class {
+ constructor(exteriorRing) {
+ __publicField(this, "exteriorRing");
+ __publicField(this, "interiorRings");
+ this.exteriorRing = exteriorRing;
+ exteriorRing.poly = this;
+ this.interiorRings = [];
+ }
+ addInterior(ring) {
+ this.interiorRings.push(ring);
+ ring.poly = this;
+ }
+ getGeom() {
+ const geom = [this.exteriorRing.getGeom()];
+ if (geom[0] === null)
+ return null;
+ for (let i3 = 0, iMax = this.interiorRings.length; i3 < iMax; i3++) {
+ const ringGeom = this.interiorRings[i3].getGeom();
+ if (ringGeom === null)
+ continue;
+ geom.push(ringGeom);
+ }
+ return geom;
+ }
+ };
+ var MultiPolyOut = class {
+ constructor(rings) {
+ __publicField(this, "rings");
+ __publicField(this, "polys");
+ this.rings = rings;
+ this.polys = this._composePolys(rings);
+ }
+ getGeom() {
+ const geom = [];
+ for (let i3 = 0, iMax = this.polys.length; i3 < iMax; i3++) {
+ const polyGeom = this.polys[i3].getGeom();
+ if (polyGeom === null)
+ continue;
+ geom.push(polyGeom);
+ }
+ return geom;
+ }
+ _composePolys(rings) {
+ var _a2;
+ const polys = [];
+ for (let i3 = 0, iMax = rings.length; i3 < iMax; i3++) {
+ const ring = rings[i3];
+ if (ring.poly)
+ continue;
+ if (ring.isExteriorRing())
+ polys.push(new PolyOut(ring));
+ else {
+ const enclosingRing = ring.enclosingRing();
+ if (!(enclosingRing == null ? void 0 : enclosingRing.poly))
+ polys.push(new PolyOut(enclosingRing));
+ (_a2 = enclosingRing == null ? void 0 : enclosingRing.poly) == null ? void 0 : _a2.addInterior(ring);
+ }
+ }
+ return polys;
+ }
+ };
+
+ // node_modules/polyclip-ts/dist/sweep-line.js
+ var SweepLine = class {
+ constructor(queue, comparator = Segment.compare) {
+ __publicField(this, "queue");
+ __publicField(this, "tree");
+ __publicField(this, "segments");
+ this.queue = queue;
+ this.tree = new SplayTreeSet(comparator);
+ this.segments = [];
+ }
+ process(event) {
+ const segment = event.segment;
+ const newEvents = [];
+ if (event.consumedBy) {
+ if (event.isLeft)
+ this.queue.delete(event.otherSE);
+ else
+ this.tree.delete(segment);
+ return newEvents;
+ }
+ if (event.isLeft)
+ this.tree.add(segment);
+ let prevSeg = segment;
+ let nextSeg = segment;
+ do {
+ prevSeg = this.tree.lastBefore(prevSeg);
+ } while (prevSeg != null && prevSeg.consumedBy != void 0);
+ do {
+ nextSeg = this.tree.firstAfter(nextSeg);
+ } while (nextSeg != null && nextSeg.consumedBy != void 0);
+ if (event.isLeft) {
+ let prevMySplitter = null;
+ if (prevSeg) {
+ const prevInter = prevSeg.getIntersection(segment);
+ if (prevInter !== null) {
+ if (!segment.isAnEndpoint(prevInter))
+ prevMySplitter = prevInter;
+ if (!prevSeg.isAnEndpoint(prevInter)) {
+ const newEventsFromSplit = this._splitSafely(prevSeg, prevInter);
+ for (let i3 = 0, iMax = newEventsFromSplit.length; i3 < iMax; i3++) {
+ newEvents.push(newEventsFromSplit[i3]);
+ }
+ }
+ }
+ }
+ let nextMySplitter = null;
+ if (nextSeg) {
+ const nextInter = nextSeg.getIntersection(segment);
+ if (nextInter !== null) {
+ if (!segment.isAnEndpoint(nextInter))
+ nextMySplitter = nextInter;
+ if (!nextSeg.isAnEndpoint(nextInter)) {
+ const newEventsFromSplit = this._splitSafely(nextSeg, nextInter);
+ for (let i3 = 0, iMax = newEventsFromSplit.length; i3 < iMax; i3++) {
+ newEvents.push(newEventsFromSplit[i3]);
+ }
+ }
+ }
+ }
+ if (prevMySplitter !== null || nextMySplitter !== null) {
+ let mySplitter = null;
+ if (prevMySplitter === null)
+ mySplitter = nextMySplitter;
+ else if (nextMySplitter === null)
+ mySplitter = prevMySplitter;
+ else {
+ const cmpSplitters = SweepEvent.comparePoints(prevMySplitter, nextMySplitter);
+ mySplitter = cmpSplitters <= 0 ? prevMySplitter : nextMySplitter;
+ }
+ this.queue.delete(segment.rightSE);
+ newEvents.push(segment.rightSE);
+ const newEventsFromSplit = segment.split(mySplitter);
+ for (let i3 = 0, iMax = newEventsFromSplit.length; i3 < iMax; i3++) {
+ newEvents.push(newEventsFromSplit[i3]);
+ }
+ }
+ if (newEvents.length > 0) {
+ this.tree.delete(segment);
+ newEvents.push(event);
+ } else {
+ this.segments.push(segment);
+ segment.prev = prevSeg;
+ }
+ } else {
+ if (prevSeg && nextSeg) {
+ const inter = prevSeg.getIntersection(nextSeg);
+ if (inter !== null) {
+ if (!prevSeg.isAnEndpoint(inter)) {
+ const newEventsFromSplit = this._splitSafely(prevSeg, inter);
+ for (let i3 = 0, iMax = newEventsFromSplit.length; i3 < iMax; i3++) {
+ newEvents.push(newEventsFromSplit[i3]);
+ }
+ }
+ if (!nextSeg.isAnEndpoint(inter)) {
+ const newEventsFromSplit = this._splitSafely(nextSeg, inter);
+ for (let i3 = 0, iMax = newEventsFromSplit.length; i3 < iMax; i3++) {
+ newEvents.push(newEventsFromSplit[i3]);
+ }
+ }
+ }
+ }
+ this.tree.delete(segment);
+ }
+ return newEvents;
+ }
+ /* Safely split a segment that is currently in the datastructures
+ * IE - a segment other than the one that is currently being processed. */
+ _splitSafely(seg, pt2) {
+ this.tree.delete(seg);
+ const rightSE = seg.rightSE;
+ this.queue.delete(rightSE);
+ const newEvents = seg.split(pt2);
+ newEvents.push(rightSE);
+ if (seg.consumedBy === void 0)
+ this.tree.add(seg);
+ return newEvents;
+ }
+ };
+
+ // node_modules/polyclip-ts/dist/operation.js
+ var Operation = class {
+ constructor() {
+ __publicField(this, "type");
+ __publicField(this, "numMultiPolys");
+ }
+ run(type2, geom, moreGeoms) {
+ operation.type = type2;
+ const multipolys = [new MultiPolyIn(geom, true)];
+ for (let i3 = 0, iMax = moreGeoms.length; i3 < iMax; i3++) {
+ multipolys.push(new MultiPolyIn(moreGeoms[i3], false));
+ }
+ operation.numMultiPolys = multipolys.length;
+ if (operation.type === "difference") {
+ const subject = multipolys[0];
+ let i3 = 1;
+ while (i3 < multipolys.length) {
+ if (getBboxOverlap(multipolys[i3].bbox, subject.bbox) !== null)
+ i3++;
+ else
+ multipolys.splice(i3, 1);
+ }
+ }
+ if (operation.type === "intersection") {
+ for (let i3 = 0, iMax = multipolys.length; i3 < iMax; i3++) {
+ const mpA = multipolys[i3];
+ for (let j2 = i3 + 1, jMax = multipolys.length; j2 < jMax; j2++) {
+ if (getBboxOverlap(mpA.bbox, multipolys[j2].bbox) === null)
+ return [];
+ }
+ }
+ }
+ const queue = new SplayTreeSet(SweepEvent.compare);
+ for (let i3 = 0, iMax = multipolys.length; i3 < iMax; i3++) {
+ const sweepEvents = multipolys[i3].getSweepEvents();
+ for (let j2 = 0, jMax = sweepEvents.length; j2 < jMax; j2++) {
+ queue.add(sweepEvents[j2]);
+ }
+ }
+ const sweepLine = new SweepLine(queue);
+ let evt = null;
+ if (queue.size != 0) {
+ evt = queue.first();
+ queue.delete(evt);
+ }
+ while (evt) {
+ const newEvents = sweepLine.process(evt);
+ for (let i3 = 0, iMax = newEvents.length; i3 < iMax; i3++) {
+ const evt2 = newEvents[i3];
+ if (evt2.consumedBy === void 0)
+ queue.add(evt2);
+ }
+ if (queue.size != 0) {
+ evt = queue.first();
+ queue.delete(evt);
+ } else {
+ evt = null;
+ }
+ }
+ precision.reset();
+ const ringsOut = RingOut.factory(sweepLine.segments);
+ const result = new MultiPolyOut(ringsOut);
+ return result.getGeom();
+ }
+ };
+ var operation = new Operation();
+ var operation_default = operation;
+
+ // node_modules/polyclip-ts/dist/index.js
+ var union = (geom, ...moreGeoms) => operation_default.run("union", geom, moreGeoms);
+ var difference = (geom, ...moreGeoms) => operation_default.run("difference", geom, moreGeoms);
+ var setPrecision = precision.set;
+
+ // node_modules/@rapideditor/location-conflation/index.mjs
+ var import_geojson_area = __toESM(require_geojson_area(), 1);
+ var import_circle_to_polygon = __toESM(require_circle_to_polygon(), 1);
+ var import_geojson_precision = __toESM(require_geojson_precision(), 1);
+ var import_json_stringify_pretty_compact = __toESM(require_json_stringify_pretty_compact(), 1);
+ var LocationConflation = class {
+ // constructor
+ //
+ // `fc` Optional FeatureCollection of known features
+ //
+ // Optionally pass a GeoJSON FeatureCollection of known features which we can refer to later.
+ // Each feature must have a filename-like `id`, for example: `something.geojson`
+ //
+ // {
+ // "type": "FeatureCollection"
+ // "features": [
+ // {
+ // "type": "Feature",
+ // "id": "philly_metro.geojson",
+ // "properties": { … },
+ // "geometry": { … }
+ // }
+ // ]
+ // }
+ constructor(fc) {
+ this._cache = {};
+ this.strict = true;
+ if (fc && fc.type === "FeatureCollection" && Array.isArray(fc.features)) {
+ fc.features.forEach((feature3) => {
+ feature3.properties = feature3.properties || {};
+ let props = feature3.properties;
+ let id2 = feature3.id || props.id;
+ if (!id2 || !/^\S+\.geojson$/i.test(id2))
+ return;
+ id2 = id2.toLowerCase();
+ feature3.id = id2;
+ props.id = id2;
+ if (!props.area) {
+ const area = import_geojson_area.default.geometry(feature3.geometry) / 1e6;
+ props.area = Number(area.toFixed(2));
+ }
+ this._cache[id2] = feature3;
+ });
+ }
+ let world = _cloneDeep(feature("Q2"));
+ world.geometry = {
+ type: "Polygon",
+ coordinates: [[[-180, -90], [180, -90], [180, 90], [-180, 90], [-180, -90]]]
+ };
+ world.id = "Q2";
+ world.properties.id = "Q2";
+ world.properties.area = import_geojson_area.default.geometry(world.geometry) / 1e6;
+ this._cache.Q2 = world;
+ }
+ // validateLocation
+ // `location` The location to validate
+ //
+ // Pass a `location` value to validate
+ //
+ // Returns a result like:
+ // {
+ // type: 'point', 'geojson', or 'countrycoder'
+ // location: the queried location
+ // id: the stable identifier for the feature
+ // }
+ // or `null` if the location is invalid
+ //
+ validateLocation(location) {
+ if (Array.isArray(location) && (location.length === 2 || location.length === 3)) {
+ const lon = location[0];
+ const lat = location[1];
+ const radius = location[2];
+ if (Number.isFinite(lon) && lon >= -180 && lon <= 180 && Number.isFinite(lat) && lat >= -90 && lat <= 90 && (location.length === 2 || Number.isFinite(radius) && radius > 0)) {
+ const id2 = "[" + location.toString() + "]";
+ return { type: "point", location, id: id2 };
+ }
+ } else if (typeof location === "string" && /^\S+\.geojson$/i.test(location)) {
+ const id2 = location.toLowerCase();
+ if (this._cache[id2]) {
+ return { type: "geojson", location, id: id2 };
+ }
+ } else if (typeof location === "string" || typeof location === "number") {
+ const feature3 = feature(location);
+ if (feature3) {
+ const id2 = feature3.properties.wikidata;
+ return { type: "countrycoder", location, id: id2 };
+ }
+ }
+ if (this.strict) {
+ throw new Error('validateLocation: Invalid location: "'.concat(location, '".'));
+ } else {
+ return null;
+ }
+ }
+ // resolveLocation
+ // `location` The location to resolve
+ //
+ // Pass a `location` value to resolve
+ //
+ // Returns a result like:
+ // {
+ // type: 'point', 'geojson', or 'countrycoder'
+ // location: the queried location
+ // id: a stable identifier for the feature
+ // feature: the resolved GeoJSON feature
+ // }
+ // or `null` if the location is invalid
+ //
+ resolveLocation(location) {
+ const valid = this.validateLocation(location);
+ if (!valid)
+ return null;
+ const id2 = valid.id;
+ if (this._cache[id2]) {
+ return Object.assign(valid, { feature: this._cache[id2] });
+ }
+ if (valid.type === "point") {
+ const lon = location[0];
+ const lat = location[1];
+ const radius = location[2] || 25;
+ const EDGES = 10;
+ const PRECISION = 3;
+ const area = Math.PI * radius * radius;
+ const feature3 = this._cache[id2] = (0, import_geojson_precision.default)({
+ type: "Feature",
+ id: id2,
+ properties: { id: id2, area: Number(area.toFixed(2)) },
+ geometry: (0, import_circle_to_polygon.default)([lon, lat], radius * 1e3, EDGES)
+ // km to m
+ }, PRECISION);
+ return Object.assign(valid, { feature: feature3 });
+ } else if (valid.type === "geojson") {
+ } else if (valid.type === "countrycoder") {
+ let feature3 = _cloneDeep(feature(id2));
+ let props = feature3.properties;
+ if (Array.isArray(props.members)) {
+ let aggregate = aggregateFeature(id2);
+ aggregate.geometry.coordinates = _clip([aggregate], "UNION").geometry.coordinates;
+ feature3.geometry = aggregate.geometry;
+ }
+ if (!props.area) {
+ const area = import_geojson_area.default.geometry(feature3.geometry) / 1e6;
+ props.area = Number(area.toFixed(2));
+ }
+ feature3.id = id2;
+ props.id = id2;
+ this._cache[id2] = feature3;
+ return Object.assign(valid, { feature: feature3 });
+ }
+ if (this.strict) {
+ throw new Error("resolveLocation: Couldn't resolve location \"".concat(location, '".'));
+ } else {
+ return null;
+ }
+ }
+ // validateLocationSet
+ // `locationSet` the locationSet to validate
+ //
+ // Pass a locationSet Object to validate like:
+ // {
+ // include: [ Array of locations ],
+ // exclude: [ Array of locations ]
+ // }
+ //
+ // Returns a result like:
+ // {
+ // type: 'locationset'
+ // locationSet: the queried locationSet
+ // id: the stable identifier for the feature
+ // }
+ // or `null` if the locationSet is invalid
+ //
+ validateLocationSet(locationSet) {
+ locationSet = locationSet || {};
+ const validator = this.validateLocation.bind(this);
+ let include = (locationSet.include || []).map(validator).filter(Boolean);
+ let exclude = (locationSet.exclude || []).map(validator).filter(Boolean);
+ if (!include.length) {
+ if (this.strict) {
+ throw new Error("validateLocationSet: LocationSet includes nothing.");
+ } else {
+ locationSet.include = ["Q2"];
+ include = [{ type: "countrycoder", location: "Q2", id: "Q2" }];
+ }
+ }
+ include.sort(_sortLocations);
+ let id2 = "+[" + include.map((d2) => d2.id).join(",") + "]";
+ if (exclude.length) {
+ exclude.sort(_sortLocations);
+ id2 += "-[" + exclude.map((d2) => d2.id).join(",") + "]";
+ }
+ return { type: "locationset", locationSet, id: id2 };
+ }
+ // resolveLocationSet
+ // `locationSet` the locationSet to resolve
+ //
+ // Pass a locationSet Object to validate like:
+ // {
+ // include: [ Array of locations ],
+ // exclude: [ Array of locations ]
+ // }
+ //
+ // Returns a result like:
+ // {
+ // type: 'locationset'
+ // locationSet: the queried locationSet
+ // id: the stable identifier for the feature
+ // feature: the resolved GeoJSON feature
+ // }
+ // or `null` if the locationSet is invalid
+ //
+ resolveLocationSet(locationSet) {
+ locationSet = locationSet || {};
+ const valid = this.validateLocationSet(locationSet);
+ if (!valid)
+ return null;
+ const id2 = valid.id;
+ if (this._cache[id2]) {
+ return Object.assign(valid, { feature: this._cache[id2] });
+ }
+ const resolver = this.resolveLocation.bind(this);
+ const includes = (locationSet.include || []).map(resolver).filter(Boolean);
+ const excludes = (locationSet.exclude || []).map(resolver).filter(Boolean);
+ if (includes.length === 1 && excludes.length === 0) {
+ return Object.assign(valid, { feature: includes[0].feature });
+ }
+ const includeGeoJSON = _clip(includes.map((d2) => d2.feature), "UNION");
+ const excludeGeoJSON = _clip(excludes.map((d2) => d2.feature), "UNION");
+ let resultGeoJSON = excludeGeoJSON ? _clip([includeGeoJSON, excludeGeoJSON], "DIFFERENCE") : includeGeoJSON;
+ const area = import_geojson_area.default.geometry(resultGeoJSON.geometry) / 1e6;
+ resultGeoJSON.id = id2;
+ resultGeoJSON.properties = { id: id2, area: Number(area.toFixed(2)) };
+ this._cache[id2] = resultGeoJSON;
+ return Object.assign(valid, { feature: resultGeoJSON });
+ }
+ // stringify
+ // convenience method to prettyStringify the given object
+ stringify(obj, options2) {
+ return (0, import_json_stringify_pretty_compact.default)(obj, options2);
+ }
+ };
+ function _clip(features, which) {
+ if (!Array.isArray(features) || !features.length)
+ return null;
+ const fn = { UNION: union, DIFFERENCE: difference }[which];
+ const args = features.map((feature3) => feature3.geometry.coordinates);
+ const coords = fn.apply(null, args);
+ return {
+ type: "Feature",
+ properties: {},
+ geometry: {
+ type: whichType(coords),
+ coordinates: coords
+ }
+ };
+ function whichType(coords2) {
+ const a2 = Array.isArray(coords2);
+ const b2 = a2 && Array.isArray(coords2[0]);
+ const c2 = b2 && Array.isArray(coords2[0][0]);
+ const d2 = c2 && Array.isArray(coords2[0][0][0]);
+ return d2 ? "MultiPolygon" : "Polygon";
+ }
+ }
+ function _cloneDeep(obj) {
+ return JSON.parse(JSON.stringify(obj));
+ }
+ function _sortLocations(a2, b2) {
+ const rank = { countrycoder: 1, geojson: 2, point: 3 };
+ const aRank = rank[a2.type];
+ const bRank = rank[b2.type];
+ return aRank > bRank ? 1 : aRank < bRank ? -1 : a2.id.localeCompare(b2.id);
+ }
+
+ // modules/core/LocationManager.js
+ var import_which_polygon2 = __toESM(require_which_polygon());
+ var import_geojson_area2 = __toESM(require_geojson_area());
+ var _loco = new LocationConflation();
+ var LocationManager = class {
+ /**
+ * @constructor
+ */
+ constructor() {
+ this._wp = null;
+ this._resolved = /* @__PURE__ */ new Map();
+ this._knownLocationSets = /* @__PURE__ */ new Map();
+ this._locationIncludedIn = /* @__PURE__ */ new Map();
+ this._locationExcludedIn = /* @__PURE__ */ new Map();
+ const world = { locationSet: { include: ["Q2"] } };
+ this._resolveLocationSet(world);
+ this._rebuildIndex();
+ }
+ /**
+ * _validateLocationSet
+ * Pass an Object with a `locationSet` property.
+ * Validates the `locationSet` and sets a `locationSetID` property on the object.
+ * To avoid so much computation we only resolve the include and exclude regions, but not the locationSet itself.
+ *
+ * Use `_resolveLocationSet()` instead if you need to resolve geojson of locationSet, for example to render it.
+ * Note: You need to call `_rebuildIndex()` after you're all finished validating the locationSets.
+ *
+ * @param `obj` Object to check, it should have `locationSet` property
+ */
+ _validateLocationSet(obj) {
+ if (obj.locationSetID)
+ return;
+ try {
+ let locationSet = obj.locationSet;
+ if (!locationSet) {
+ throw new Error("object missing locationSet property");
+ }
+ if (!locationSet.include) {
+ locationSet.include = ["Q2"];
+ }
+ const locationSetID = _loco.validateLocationSet(locationSet).id;
+ obj.locationSetID = locationSetID;
+ if (this._knownLocationSets.has(locationSetID))
+ return;
+ let area = 0;
+ (locationSet.include || []).forEach((location) => {
+ const locationID = _loco.validateLocation(location).id;
+ let geojson = this._resolved.get(locationID);
+ if (!geojson) {
+ geojson = _loco.resolveLocation(location).feature;
+ this._resolved.set(locationID, geojson);
+ }
+ area += geojson.properties.area;
+ let s2 = this._locationIncludedIn.get(locationID);
+ if (!s2) {
+ s2 = /* @__PURE__ */ new Set();
+ this._locationIncludedIn.set(locationID, s2);
+ }
+ s2.add(locationSetID);
+ });
+ (locationSet.exclude || []).forEach((location) => {
+ const locationID = _loco.validateLocation(location).id;
+ let geojson = this._resolved.get(locationID);
+ if (!geojson) {
+ geojson = _loco.resolveLocation(location).feature;
+ this._resolved.set(locationID, geojson);
+ }
+ area -= geojson.properties.area;
+ let s2 = this._locationExcludedIn.get(locationID);
+ if (!s2) {
+ s2 = /* @__PURE__ */ new Set();
+ this._locationExcludedIn.set(locationID, s2);
+ }
+ s2.add(locationSetID);
+ });
+ this._knownLocationSets.set(locationSetID, area);
+ } catch {
+ obj.locationSet = { include: ["Q2"] };
+ obj.locationSetID = "+[Q2]";
+ }
+ }
+ /**
+ * _resolveLocationSet
+ * Does everything that `_validateLocationSet()` does, but then "resolves" the locationSet into GeoJSON.
+ * This step is a bit more computationally expensive, so really only needed if you intend to render the shape.
+ *
+ * Note: You need to call `_rebuildIndex()` after you're all finished validating the locationSets.
+ *
+ * @param `obj` Object to check, it should have `locationSet` property
+ */
+ _resolveLocationSet(obj) {
+ this._validateLocationSet(obj);
+ if (this._resolved.has(obj.locationSetID))
+ return;
+ try {
+ const result = _loco.resolveLocationSet(obj.locationSet);
+ const locationSetID = result.id;
+ obj.locationSetID = locationSetID;
+ if (!result.feature.geometry.coordinates.length || !result.feature.properties.area) {
+ throw new Error("locationSet ".concat(locationSetID, " resolves to an empty feature."));
+ }
+ let geojson = JSON.parse(JSON.stringify(result.feature));
+ geojson.id = locationSetID;
+ geojson.properties.id = locationSetID;
+ this._resolved.set(locationSetID, geojson);
+ } catch {
+ obj.locationSet = { include: ["Q2"] };
+ obj.locationSetID = "+[Q2]";
+ }
+ }
+ /**
+ * _rebuildIndex
+ * Rebuilds the whichPolygon index with whatever features have been resolved into GeoJSON.
+ */
+ _rebuildIndex() {
+ this._wp = (0, import_which_polygon2.default)({ features: [...this._resolved.values()] });
+ }
+ /**
+ * mergeCustomGeoJSON
+ * Accepts a FeatureCollection-like object containing custom locations
+ * Each feature must have a filename-like `id`, for example: `something.geojson`
+ * {
+ * "type": "FeatureCollection"
+ * "features": [
+ * {
+ * "type": "Feature",
+ * "id": "philly_metro.geojson",
+ * "properties": { … },
+ * "geometry": { … }
+ * }
+ * ]
+ * }
+ *
+ * @param `fc` FeatureCollection-like Object containing custom locations
+ */
+ mergeCustomGeoJSON(fc) {
+ if (!fc || fc.type !== "FeatureCollection" || !Array.isArray(fc.features))
+ return;
+ fc.features.forEach((feature3) => {
+ feature3.properties = feature3.properties || {};
+ let props = feature3.properties;
+ let id2 = feature3.id || props.id;
+ if (!id2 || !/^\S+\.geojson$/i.test(id2))
+ return;
+ id2 = id2.toLowerCase();
+ feature3.id = id2;
+ props.id = id2;
+ if (!props.area) {
+ const area = import_geojson_area2.default.geometry(feature3.geometry) / 1e6;
+ props.area = Number(area.toFixed(2));
+ }
+ _loco._cache[id2] = feature3;
+ });
+ }
+ /**
+ * mergeLocationSets
+ * Accepts an Array of Objects containing `locationSet` properties:
+ * [
+ * { id: 'preset1', locationSet: {…} },
+ * { id: 'preset2', locationSet: {…} },
+ * …
+ * ]
+ * After validating, the Objects will be decorated with a `locationSetID` property:
+ * [
+ * { id: 'preset1', locationSet: {…}, locationSetID: '+[Q2]' },
+ * { id: 'preset2', locationSet: {…}, locationSetID: '+[Q30]' },
+ * …
+ * ]
+ *
+ * @param `objects` Objects to check - they should have `locationSet` property
+ * @return Promise resolved true (this function used to be slow/async, now it's faster and sync)
+ */
+ mergeLocationSets(objects) {
+ if (!Array.isArray(objects))
+ return Promise.reject("nothing to do");
+ objects.forEach((obj) => this._validateLocationSet(obj));
+ this._rebuildIndex();
+ return Promise.resolve(objects);
+ }
+ /**
+ * locationSetID
+ * Returns a locationSetID for a given locationSet (fallback to `+[Q2]`, world)
+ * (The locationSet doesn't necessarily need to be resolved to compute its `id`)
+ *
+ * @param `locationSet` A locationSet Object, e.g. `{ include: ['us'] }`
+ * @return String locationSetID, e.g. `+[Q30]`
+ */
+ locationSetID(locationSet) {
+ let locationSetID;
+ try {
+ locationSetID = _loco.validateLocationSet(locationSet).id;
+ } catch {
+ locationSetID = "+[Q2]";
+ }
+ return locationSetID;
+ }
+ /**
+ * feature
+ * Returns the resolved GeoJSON feature for a given locationSetID (fallback to 'world')
+ * A GeoJSON feature:
+ * {
+ * type: 'Feature',
+ * id: '+[Q30]',
+ * properties: { id: '+[Q30]', area: 21817019.17, … },
+ * geometry: { … }
+ * }
+ *
+ * @param `locationSetID` String identifier, e.g. `+[Q30]`
+ * @return GeoJSON object (fallback to world)
+ */
+ feature(locationSetID = "+[Q2]") {
+ const feature3 = this._resolved.get(locationSetID);
+ return feature3 || this._resolved.get("+[Q2]");
+ }
+ /**
+ * locationSetsAt
+ * Find all the locationSets valid at the given location.
+ * Results include the area (in km²) to facilitate sorting.
+ *
+ * Object of locationSetIDs to areas (in km²)
+ * {
+ * "+[Q2]": 511207893.3958111,
+ * "+[Q30]": 21817019.17,
+ * "+[new_jersey.geojson]": 22390.77,
+ * …
+ * }
+ *
+ * @param `loc` `[lon,lat]` location to query, e.g. `[-74.4813, 40.7967]`
+ * @return Object of locationSetIDs valid at given location
+ */
+ locationSetsAt(loc) {
+ let result = {};
+ const hits = this._wp(loc, true) || [];
+ const thiz = this;
+ hits.forEach((prop) => {
+ if (prop.id[0] !== "+")
+ return;
+ const locationSetID = prop.id;
+ const area = thiz._knownLocationSets.get(locationSetID);
+ if (area) {
+ result[locationSetID] = area;