wael-lib
Version:
Well-Known Text Arithmetic Expression Language
1,438 lines (1,384 loc) • 74.3 kB
JavaScript
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
// package.json
var require_package = __commonJS({
"package.json"(exports2, module2) {
module2.exports = {
name: "wael-lib",
version: "0.0.14",
description: "Well-Known Text Arithmetic Expression Language",
repository: {
type: "git",
url: "git+https://github.com/anthonydgj/wael.git"
},
files: [
"dist",
"examples"
],
browser: {
fs: false,
path: false,
os: false
},
type: "commonjs",
main: "dist/cjs/index.cjs",
module: "dist/esm/index.mjs",
types: "dist/cjs/index.d.ts",
exports: {
"./package.json": "./package.json",
".": {
import: {
types: "./dist/esm/index.d.mts",
default: "./dist/esm/index.mjs"
},
require: {
types: "./dist/cjs/index.d.ts",
default: "./dist/cjs/index.cjs"
}
}
},
scripts: {
build: "tsup --config ./tsup.config.ts",
"build-all": "npm run build-binary && npm run build-release-binaries",
"build-binary": 'npm run build && pkg ./dist/wael/wael.cjs -t=latest --no-bytecode --public-packages "*" --public --out-path dist/bin/',
"build-release-binaries": 'pkg ./dist/wael/wael.cjs -t=latest,latest-macos-arm64,latest-linuxstatic-x64,latest-win-x64 --no-bytecode --public-packages "*" --public --out-path dist/bin/release/',
test: "jest",
"publish-lib": "npm run build && npm test && npm publish"
},
author: "AnthonyDGJ",
license: "MIT",
devDependencies: {
"@types/geojson": "^7946.0.16",
"@types/jest": "^29.5.14",
"@types/sync-fetch": "^0.4.3",
"@types/wellknown": "^0.5.8",
jest: "^29.7.0",
pkg: "^5.8.1",
"ts-jest": "^29.3.2",
"ts-node": "^10.9.2",
tsup: "^8.4.0",
typescript: "^5.8.3"
},
dependencies: {
"@turf/turf": "^7.2.0",
chalk: "^4.1.2",
fs: "^0.0.1-security",
"ohm-js": "^17.1.0",
"sync-fetch": "^0.6.0-2",
tslib: "^2.8.1",
wellknown: "^0.5.0",
yargs: "^17.7.2"
},
keywords: [
"wkt",
"well-known text",
"ohm",
"dsl",
"domain-specific language",
"geospatial"
]
};
}
});
// scripts/wael.ts
var fs = __toESM(require("fs"));
// src/main.ts
var turf4 = __toESM(require("@turf/turf"));
var wellknown = __toESM(require("wellknown"));
// src/interpreter/interpreter.ts
var ohm = __toESM(require("ohm-js"));
var turf3 = __toESM(require("@turf/turf"));
// src/interpreter/types.ts
var GeometryType = /* @__PURE__ */ ((GeometryType2) => {
GeometryType2["Point"] = "Point";
GeometryType2["LineString"] = "LineString";
GeometryType2["Polygon"] = "Polygon";
GeometryType2["MultiPoint"] = "MultiPoint";
GeometryType2["MultiLineString"] = "MultiLineString";
GeometryType2["MultiPolygon"] = "MultiPolygon";
GeometryType2["GeometryCollection"] = "GeometryCollection";
return GeometryType2;
})(GeometryType || {});
var UNIT = null;
// src/interpreter/helpers.ts
var turf = __toESM(require("@turf/turf"));
var isAnyGeometryType = /* @__PURE__ */ __name((value) => {
const types = Object.values(GeometryType);
for (const type of types) {
if (isGeometryType(type, value)) {
return true;
}
}
return false;
}, "isAnyGeometryType");
var isGeometryType = /* @__PURE__ */ __name((type, ...values) => {
var _a2;
for (const value of values) {
const isType2 = typeof value === "object" && (value == null ? void 0 : value.type) === type || ((_a2 = value == null ? void 0 : value.geometry) == null ? void 0 : _a2.type) === type;
if (!isType2) {
return false;
}
}
return true;
}, "isGeometryType");
var getGeometryType = /* @__PURE__ */ __name((value, isForDisplay = false) => {
var _a2;
if (typeof value === "object") {
const type = ((_a2 = value == null ? void 0 : value.geometry) == null ? void 0 : _a2.type) || (value == null ? void 0 : value.type);
if (isForDisplay && type === "GeometryCollection" /* GeometryCollection */) {
return "GeometryCollection" /* GeometryCollection */;
}
return type;
}
return void 0;
}, "getGeometryType");
var getArrayLikeItems = /* @__PURE__ */ __name((value) => {
if (isGeometryType("LineString" /* LineString */, value) || isGeometryType("MultiPoint" /* MultiPoint */, value)) {
return value.coordinates;
} else if (isGeometryType("GeometryCollection" /* GeometryCollection */, value)) {
return value.geometries;
}
return void 0;
}, "getArrayLikeItems");
var isNumber = /* @__PURE__ */ __name((...values) => {
return isType("number", ...values);
}, "isNumber");
var isType = /* @__PURE__ */ __name((type, ...values) => {
for (const value of values) {
const isType2 = typeof value === type;
if (!isType2) {
return false;
}
}
return true;
}, "isType");
var arithmeticOperationExp = /* @__PURE__ */ __name((a, b, op) => {
return arithmeticOperation(a.eval(), b.eval(), op);
}, "arithmeticOperationExp");
var arithmeticOperation = /* @__PURE__ */ __name((A, B, op) => {
if (isNumber(A, B)) {
return op(A, B);
}
if (isNumber(A) && isAnyGeometryType(B)) {
return arithmeticOperation(turf.point([A, A]).geometry, B, op);
}
if (isNumber(B) && isAnyGeometryType(A)) {
return arithmeticOperation(A, turf.point([B, B]).geometry, op);
}
if (isGeometryType("Point" /* Point */, A, B)) {
return pointOperation(A, B, op);
}
if (isGeometryType("LineString" /* LineString */, A, B)) {
return lineStringOperation(A, B, op);
}
if (isGeometryType("MultiPoint" /* MultiPoint */, A, B)) {
return multiPointOperation(A, B, op);
}
if (isGeometryType("Point" /* Point */, A)) {
return transform(B, (b) => pointOperation(A, b, op));
}
if (isGeometryType("Point" /* Point */, B)) {
return transform(A, (a) => pointOperation(a, B, op));
}
return void 0;
}, "arithmeticOperation");
var pointOperation = /* @__PURE__ */ __name((A, B, computeFn) => {
return turf.point([
computeFn(A.coordinates[0], B.coordinates[0]),
computeFn(A.coordinates[1], B.coordinates[1])
]).geometry;
}, "pointOperation");
var lineStringOperation = /* @__PURE__ */ __name((A, B, computeFn) => {
return turf.lineString(A.coordinates.map((p, index) => {
return [
computeFn(p[0], B.coordinates[index][0]),
computeFn(p[1], B.coordinates[index][1])
];
})).geometry;
}, "lineStringOperation");
var multiPointOperation = /* @__PURE__ */ __name((A, B, computeFn) => {
return turf.multiPoint(A.coordinates.map((p, index) => {
return [
computeFn(p[0], B.coordinates[index][0]),
computeFn(p[1], B.coordinates[index][1])
];
})).geometry;
}, "multiPointOperation");
var _OperationNotSupported = class _OperationNotSupported extends Error {
constructor(message) {
super(`Operation not supported: ${message}`);
}
};
__name(_OperationNotSupported, "OperationNotSupported");
var OperationNotSupported = _OperationNotSupported;
function toString(value) {
try {
return `${JSON.stringify(value)}`;
} catch (err) {
return `${value}`;
}
}
__name(toString, "toString");
function transformPoints(coords, coordsMapFn) {
if (!!coords) {
if (Array.isArray(coords)) {
if (coords.length > 0) {
const firstElement = coords[0];
if (Array.isArray(firstElement)) {
return coords.map((c) => transformPoints(c, coordsMapFn));
} else {
const point4 = turf.point(coords).geometry;
return coordsMapFn(point4).coordinates;
}
}
}
}
return coords;
}
__name(transformPoints, "transformPoints");
function transform(geoJson, coordsMapFn) {
if (!!geoJson) {
if (!!geoJson.features) {
return __spreadProps(__spreadValues({}, geoJson), {
features: geoJson.features.map((feature3) => transform(feature3, coordsMapFn))
});
}
if (!!geoJson.geometries) {
return __spreadProps(__spreadValues({}, geoJson), {
geometries: geoJson.geometries.map((geometry2) => transform(geometry2, coordsMapFn))
});
}
const geometry = geoJson.geometry;
if (!!geometry) {
if (geoJson.coordinates) {
return __spreadProps(__spreadValues({}, geoJson), {
geometry: __spreadProps(__spreadValues({}, geometry), {
coordinates: transformPoints(geometry.coordinates, coordsMapFn)
})
});
}
}
const coordinates = geoJson.coordinates;
if (!!coordinates) {
return __spreadProps(__spreadValues({}, geoJson), {
coordinates: transformPoints(coordinates, coordsMapFn)
});
}
}
return geoJson;
}
__name(transform, "transform");
function convertToGeometry(json) {
if (json.type === "Feature") {
return json.geometry;
} else if (json.type === "FeatureCollection") {
return {
type: "GeometryCollection",
geometries: json.features.map((f) => convertToGeometry(f))
};
} else if (Array.isArray(json)) {
return {
type: "GeometryCollection",
geometries: json.map((f) => convertToGeometry(f))
};
}
return json;
}
__name(convertToGeometry, "convertToGeometry");
function geometryAccessor(v, p, params) {
const value = v.eval();
const property = p.sourceString;
if (!isAnyGeometryType(value)) {
throw new Error(`Expected a geometry type for value "${v.sourceString}" but got: ${toString(value)}`);
}
switch (property.toLocaleLowerCase()) {
case "type":
if ((params == null ? void 0 : params.length) > 1) {
throw new Error(`Expected no parameters for "${property}" for ${v.sourceString}`);
}
return getGeometryType(value, true);
}
if (isGeometryType("Point" /* Point */, value)) {
switch (property.toLocaleLowerCase()) {
case "x":
if ((params == null ? void 0 : params.length) > 0) {
if (params.length === 1) {
return turf.point([
params[0],
value.coordinates[1]
]).geometry;
}
throw Error(`Expected one value in "${property}" setter for "${v.sourceString}" but got: ${toString(params)}`);
}
return value.coordinates[0];
case "y":
if ((params == null ? void 0 : params.length) > 0) {
if (params.length === 1) {
return turf.point([
value.coordinates[0],
params[0]
]).geometry;
}
throw Error(`Expected one value in "${property}" setter for "${v.sourceString}" but got: ${toString(params)}`);
}
return value.coordinates[1];
}
} else if (isGeometryType("GeometryCollection" /* GeometryCollection */, value)) {
switch (property.toLocaleLowerCase()) {
case "geometryn":
if (params.length === 1) {
const index = parseInt(params[0]);
return value.geometries[index];
}
throw Error(`Expected one value in "${property}" setter for "${v.sourceString}" but got: ${toString(params)}`);
case "numgeometries":
return value.geometries.length;
}
} else if (isGeometryType("LineString" /* LineString */, value)) {
switch (property.toLocaleLowerCase()) {
case "pointn":
if (params.length === 1) {
const index = parseInt(params[0]);
return turf.point(value.coordinates[index]).geometry;
}
throw Error(`Expected one value in "${property}" setter for "${v.sourceString}" but got: ${toString(params)}`);
case "numpoints":
return value.coordinates.length;
}
}
throw new Error(`Property "${property}" not accessible on object: ${toString(value)}`);
}
__name(geometryAccessor, "geometryAccessor");
// src/interpreter/scope.ts
var _Scope = class _Scope {
constructor(parent, level = 0, defaultBindings = {}) {
this.parent = parent;
this.level = level;
this.bindings = {};
this.availableBindings = {};
this.metadata = {};
for (const identifier in defaultBindings) {
if (defaultBindings.hasOwnProperty(identifier)) {
this.store(identifier, defaultBindings[identifier]);
}
}
}
store(identifier, value, metadata, searchParentChain = true) {
let scope = this;
if (searchParentChain) {
const resolvedScope = this.resolveScope(identifier);
if (resolvedScope) {
scope = resolvedScope;
}
scope.store(identifier, value, metadata, false);
return;
}
this.bindings[identifier] = value;
if (metadata) {
this.metadata[identifier] = metadata;
}
}
resolveScope(identifier) {
if (this.bindings.hasOwnProperty(identifier)) {
return this;
}
if (this.parent) {
return this.parent.resolveScope(identifier);
}
return void 0;
}
resolve(identifier) {
var _a2;
const scope = (_a2 = this.resolveScope(identifier)) != null ? _a2 : this;
return scope.bindings[identifier];
}
push(extraBindings) {
return new _Scope(this, this.level + 1, extraBindings);
}
pop(additionalBindings) {
var _a2;
const exportedBindings = __spreadValues({}, additionalBindings);
for (const identifier in this.metadata) {
const metadata = this.metadata[identifier];
if (metadata && metadata.public) {
exportedBindings[identifier] = this.bindings[identifier];
}
}
(_a2 = this.parent) == null ? void 0 : _a2.import(exportedBindings);
return this.parent;
}
import(scopeBindings) {
this.availableBindings = __spreadValues(__spreadValues({}, this.availableBindings), scopeBindings);
}
useImports(selectedIdentifiers) {
let selectedBindings = {};
if (selectedIdentifiers) {
selectedIdentifiers.forEach((selectedIdentifier) => {
selectedBindings[selectedIdentifier] = this.availableBindings[selectedIdentifier];
});
} else {
selectedBindings = this.availableBindings;
}
this.availableBindings = {};
return selectedBindings;
}
useNamedImports(selectedIdentifiers) {
let selectedBindings = {};
if (selectedIdentifiers) {
selectedIdentifiers.forEach((selectedIdentifier) => {
selectedBindings[selectedIdentifier] = this.availableBindings[selectedIdentifier];
});
}
this.bindings = __spreadValues(__spreadValues({}, this.bindings), selectedBindings);
return selectedBindings;
}
};
__name(_Scope, "Scope");
var Scope = _Scope;
// src/interpreter/built-in-functions.ts
var turf2 = __toESM(require("@turf/turf"));
// node_modules/geojson-equality-ts/dist/esm/index.js
var __defProp2 = Object.defineProperty;
var __name2 = /* @__PURE__ */ __name((target, value) => __defProp2(target, "name", { value, configurable: true }), "__name");
var _a;
var _GeojsonEquality = (_a = class {
constructor(opts) {
this.direction = false;
this.compareProperties = true;
var _a2, _b, _c;
this.precision = 10 ** -((_a2 = opts == null ? void 0 : opts.precision) != null ? _a2 : 17);
this.direction = (_b = opts == null ? void 0 : opts.direction) != null ? _b : false;
this.compareProperties = (_c = opts == null ? void 0 : opts.compareProperties) != null ? _c : true;
}
compare(g1, g2) {
if (g1.type !== g2.type) {
return false;
}
if (!sameLength(g1, g2)) {
return false;
}
switch (g1.type) {
case "Point":
return this.compareCoord(g1.coordinates, g2.coordinates);
case "LineString":
return this.compareLine(g1.coordinates, g2.coordinates);
case "Polygon":
return this.comparePolygon(g1, g2);
case "GeometryCollection":
return this.compareGeometryCollection(g1, g2);
case "Feature":
return this.compareFeature(g1, g2);
case "FeatureCollection":
return this.compareFeatureCollection(g1, g2);
default:
if (g1.type.startsWith("Multi")) {
const g1s = explode(g1);
const g2s = explode(
g2
);
return g1s.every(
(g1part) => g2s.some((g2part) => this.compare(g1part, g2part))
);
}
}
return false;
}
compareCoord(c1, c2) {
return c1.length === c2.length && c1.every((c, i) => Math.abs(c - c2[i]) < this.precision);
}
compareLine(path1, path2, ind = 0, isPoly = false) {
if (!sameLength(path1, path2)) {
return false;
}
const p1 = path1;
let p2 = path2;
if (isPoly && !this.compareCoord(p1[0], p2[0])) {
const startIndex = this.fixStartIndex(p2, p1);
if (!startIndex) {
return false;
} else {
p2 = startIndex;
}
}
const sameDirection = this.compareCoord(p1[ind], p2[ind]);
if (this.direction || sameDirection) {
return this.comparePath(p1, p2);
} else {
if (this.compareCoord(p1[ind], p2[p2.length - (1 + ind)])) {
return this.comparePath(p1.slice().reverse(), p2);
}
return false;
}
}
fixStartIndex(sourcePath, targetPath) {
let correctPath, ind = -1;
for (let i = 0; i < sourcePath.length; i++) {
if (this.compareCoord(sourcePath[i], targetPath[0])) {
ind = i;
break;
}
}
if (ind >= 0) {
correctPath = [].concat(
sourcePath.slice(ind, sourcePath.length),
sourcePath.slice(1, ind + 1)
);
}
return correctPath;
}
comparePath(p1, p2) {
return p1.every((c, i) => this.compareCoord(c, p2[i]));
}
comparePolygon(g1, g2) {
if (this.compareLine(g1.coordinates[0], g2.coordinates[0], 1, true)) {
const holes1 = g1.coordinates.slice(1, g1.coordinates.length);
const holes2 = g2.coordinates.slice(1, g2.coordinates.length);
return holes1.every(
(h1) => holes2.some((h2) => this.compareLine(h1, h2, 1, true))
);
}
return false;
}
compareGeometryCollection(g1, g2) {
return sameLength(g1.geometries, g2.geometries) && this.compareBBox(g1, g2) && g1.geometries.every((g, i) => this.compare(g, g2.geometries[i]));
}
compareFeature(g1, g2) {
return g1.id === g2.id && (this.compareProperties ? equal(g1.properties, g2.properties) : true) && this.compareBBox(g1, g2) && this.compare(g1.geometry, g2.geometry);
}
compareFeatureCollection(g1, g2) {
return sameLength(g1.features, g2.features) && this.compareBBox(g1, g2) && g1.features.every((f, i) => this.compare(f, g2.features[i]));
}
compareBBox(g1, g2) {
return Boolean(!g1.bbox && !g2.bbox) || (g1.bbox && g2.bbox ? this.compareCoord(g1.bbox, g2.bbox) : false);
}
}, __name(_a, "_GeojsonEquality"), _a);
__name2(_GeojsonEquality, "GeojsonEquality");
var GeojsonEquality = _GeojsonEquality;
function sameLength(g1, g2) {
return g1.coordinates ? g1.coordinates.length === g2.coordinates.length : g1.length === g2.length;
}
__name(sameLength, "sameLength");
__name2(sameLength, "sameLength");
function explode(g) {
return g.coordinates.map((part) => ({
type: g.type.replace("Multi", ""),
coordinates: part
}));
}
__name(explode, "explode");
__name2(explode, "explode");
function geojsonEquality(g1, g2, opts) {
const eq = new GeojsonEquality(opts);
return eq.compare(g1, g2);
}
__name(geojsonEquality, "geojsonEquality");
__name2(geojsonEquality, "geojsonEquality");
function equal(object1, object2) {
if (object1 === null && object2 === null) {
return true;
}
if (object1 === null || object2 === null) {
return false;
}
const objKeys1 = Object.keys(object1);
const objKeys2 = Object.keys(object2);
if (objKeys1.length !== objKeys2.length) return false;
for (var key of objKeys1) {
const value1 = object1[key];
const value2 = object2[key];
const isObjects = isObject(value1) && isObject(value2);
if (isObjects && !equal(value1, value2) || !isObjects && value1 !== value2) {
return false;
}
}
return true;
}
__name(equal, "equal");
__name2(equal, "equal");
var isObject = /* @__PURE__ */ __name2((object) => {
return object != null && typeof object === "object";
}, "isObject");
// node_modules/@turf/helpers/dist/esm/index.js
var earthRadius = 63710088e-1;
var factors = {
centimeters: earthRadius * 100,
centimetres: earthRadius * 100,
degrees: 360 / (2 * Math.PI),
feet: earthRadius * 3.28084,
inches: earthRadius * 39.37,
kilometers: earthRadius / 1e3,
kilometres: earthRadius / 1e3,
meters: earthRadius,
metres: earthRadius,
miles: earthRadius / 1609.344,
millimeters: earthRadius * 1e3,
millimetres: earthRadius * 1e3,
nauticalmiles: earthRadius / 1852,
radians: 1,
yards: earthRadius * 1.0936
};
function feature(geom, properties, options2 = {}) {
const feat = { type: "Feature" };
if (options2.id === 0 || options2.id) {
feat.id = options2.id;
}
if (options2.bbox) {
feat.bbox = options2.bbox;
}
feat.properties = properties || {};
feat.geometry = geom;
return feat;
}
__name(feature, "feature");
// node_modules/@turf/invariant/dist/esm/index.js
function getCoords(coords) {
if (Array.isArray(coords)) {
return coords;
}
if (coords.type === "Feature") {
if (coords.geometry !== null) {
return coords.geometry.coordinates;
}
} else {
if (coords.coordinates) {
return coords.coordinates;
}
}
throw new Error(
"coords must be GeoJSON Feature, Geometry Object or an Array"
);
}
__name(getCoords, "getCoords");
function getGeom(geojson) {
if (geojson.type === "Feature") {
return geojson.geometry;
}
return geojson;
}
__name(getGeom, "getGeom");
function getType(geojson, _name) {
if (geojson.type === "FeatureCollection") {
return "FeatureCollection";
}
if (geojson.type === "GeometryCollection") {
return "GeometryCollection";
}
if (geojson.type === "Feature" && geojson.geometry !== null) {
return geojson.geometry.type;
}
return geojson.type;
}
__name(getType, "getType");
// node_modules/@turf/clean-coords/dist/esm/index.js
function cleanCoords(geojson, options2 = {}) {
var mutate = typeof options2 === "object" ? options2.mutate : options2;
if (!geojson) throw new Error("geojson is required");
var type = getType(geojson);
var newCoords = [];
switch (type) {
case "LineString":
newCoords = cleanLine(geojson, type);
break;
case "MultiLineString":
case "Polygon":
getCoords(geojson).forEach(function(line) {
newCoords.push(cleanLine(line, type));
});
break;
case "MultiPolygon":
getCoords(geojson).forEach(function(polygons) {
var polyPoints = [];
polygons.forEach(function(ring) {
polyPoints.push(cleanLine(ring, type));
});
newCoords.push(polyPoints);
});
break;
case "Point":
return geojson;
case "MultiPoint":
var existing = {};
getCoords(geojson).forEach(function(coord) {
var key = coord.join("-");
if (!Object.prototype.hasOwnProperty.call(existing, key)) {
newCoords.push(coord);
existing[key] = true;
}
});
break;
default:
throw new Error(type + " geometry not supported");
}
if (geojson.coordinates) {
if (mutate === true) {
geojson.coordinates = newCoords;
return geojson;
}
return { type, coordinates: newCoords };
} else {
if (mutate === true) {
geojson.geometry.coordinates = newCoords;
return geojson;
}
return feature({ type, coordinates: newCoords }, geojson.properties, {
bbox: geojson.bbox,
id: geojson.id
});
}
}
__name(cleanCoords, "cleanCoords");
function cleanLine(line, type) {
var points = getCoords(line);
if (points.length === 2 && !equals(points[0], points[1])) return points;
var newPoints = [];
var secondToLast = points.length - 1;
var newPointsLength = newPoints.length;
newPoints.push(points[0]);
for (var i = 1; i < secondToLast; i++) {
var prevAddedPoint = newPoints[newPoints.length - 1];
if (points[i][0] === prevAddedPoint[0] && points[i][1] === prevAddedPoint[1])
continue;
else {
newPoints.push(points[i]);
newPointsLength = newPoints.length;
if (newPointsLength > 2) {
if (isPointOnLineSegment(
newPoints[newPointsLength - 3],
newPoints[newPointsLength - 1],
newPoints[newPointsLength - 2]
))
newPoints.splice(newPoints.length - 2, 1);
}
}
}
newPoints.push(points[points.length - 1]);
newPointsLength = newPoints.length;
if ((type === "Polygon" || type === "MultiPolygon") && equals(points[0], points[points.length - 1]) && newPointsLength < 4) {
throw new Error("invalid polygon");
}
if (type === "LineString" && newPointsLength < 3) {
return newPoints;
}
if (isPointOnLineSegment(
newPoints[newPointsLength - 3],
newPoints[newPointsLength - 1],
newPoints[newPointsLength - 2]
))
newPoints.splice(newPoints.length - 2, 1);
return newPoints;
}
__name(cleanLine, "cleanLine");
function equals(pt1, pt2) {
return pt1[0] === pt2[0] && pt1[1] === pt2[1];
}
__name(equals, "equals");
function isPointOnLineSegment(start, end, point4) {
var x = point4[0], y = point4[1];
var startX = start[0], startY = start[1];
var endX = end[0], endY = end[1];
var dxc = x - startX;
var dyc = y - startY;
var dxl = endX - startX;
var dyl = endY - startY;
var cross = dxc * dyl - dyc * dxl;
if (cross !== 0) return false;
else if (Math.abs(dxl) >= Math.abs(dyl))
return dxl > 0 ? startX <= x && x <= endX : endX <= x && x <= startX;
else return dyl > 0 ? startY <= y && y <= endY : endY <= y && y <= startY;
}
__name(isPointOnLineSegment, "isPointOnLineSegment");
// node_modules/@turf/boolean-equal/dist/esm/index.js
function booleanEqual(feature1, feature22, options2 = {}) {
let precision = options2.precision;
precision = precision === void 0 || precision === null || isNaN(precision) ? 6 : precision;
if (typeof precision !== "number" || !(precision >= 0)) {
throw new Error("precision must be a positive number");
}
const type1 = getGeom(feature1).type;
const type2 = getGeom(feature22).type;
if (type1 !== type2) return false;
return geojsonEquality(cleanCoords(feature1), cleanCoords(feature22), {
precision
});
}
__name(booleanEqual, "booleanEqual");
var turf_boolean_equal_default = booleanEqual;
// src/interpreter/built-in-functions.ts
var BuiltInFunctions;
((BuiltInFunctions2) => {
const FlattenHelper = /* @__PURE__ */ __name((value) => {
const flattenedValues = [];
if (!!value) {
if ((value == null ? void 0 : value.type) === "GeometryCollection" /* GeometryCollection */) {
for (const item of value.geometries) {
flattenedValues.push(...FlattenHelper(item));
}
} else {
flattenedValues.push(value);
}
}
return flattenedValues;
}, "FlattenHelper");
BuiltInFunctions2.Flatten = /* @__PURE__ */ __name((value) => {
if ((value == null ? void 0 : value.type) === "GeometryCollection" /* GeometryCollection */) {
return turf2.geometryCollection(FlattenHelper(value)).geometry;
}
return value;
}, "Flatten");
BuiltInFunctions2.PointCircle = /* @__PURE__ */ __name((radius, count) => {
const circlePoints = [];
const angleIncrement = 2 * Math.PI / count;
for (let i = 0; i < count; i++) {
const angle = i * angleIncrement;
const x = radius * Math.cos(angle);
const y = radius * Math.sin(angle);
circlePoints.push(turf2.point([x, y]).geometry);
}
return turf2.geometryCollection(circlePoints).geometry;
}, "PointCircle");
BuiltInFunctions2.PointGrid = /* @__PURE__ */ __name((x, y, spacing = 1) => {
const points = [];
for (let i = 0; i < x; i++) {
for (let j = 0; j < y; j++) {
const point4 = turf2.point([i * spacing, j * spacing]).geometry;
points.push(point4);
}
}
return turf2.geometryCollection(points).geometry;
}, "PointGrid");
const getPointsList = /* @__PURE__ */ __name((value) => {
let points;
if (isGeometryType("GeometryCollection" /* GeometryCollection */, value)) {
points = value == null ? void 0 : value.geometries.map((f) => f.coordinates);
} else if (isGeometryType("LineString" /* LineString */, value) || isGeometryType("MultiPoint" /* MultiPoint */, value)) {
points = value == null ? void 0 : value.coordinates;
}
if (points) {
return points;
}
throw new Error("Expected geometry with points list");
}, "getPointsList");
BuiltInFunctions2.ToLineString = /* @__PURE__ */ __name((value) => {
const pointsList = getPointsList(value);
return turf2.lineString(pointsList).geometry;
}, "ToLineString");
BuiltInFunctions2.ToMultiPoint = /* @__PURE__ */ __name((value) => {
const pointsList = getPointsList(value);
return turf2.multiPoint(pointsList).geometry;
}, "ToMultiPoint");
BuiltInFunctions2.ToPolygon = /* @__PURE__ */ __name((value) => {
const pointsList = getPointsList(value);
if (pointsList.length > 0) {
if (!turf_boolean_equal_default(
turf2.point(pointsList[0]).geometry,
turf2.point(pointsList[pointsList.length - 1]).geometry
)) {
pointsList.push(pointsList[0]);
}
}
return turf2.polygon([pointsList]).geometry;
}, "ToPolygon");
BuiltInFunctions2.ToGeometryCollection = /* @__PURE__ */ __name((value) => {
const pointsList = getPointsList(value);
return turf2.geometryCollection(pointsList.map((p) => turf2.point(p).geometry)).geometry;
}, "ToGeometryCollection");
BuiltInFunctions2.Rotate = /* @__PURE__ */ __name((angleDegrees, origin = turf2.point([0, 0]).geometry, geometry) => {
return transform(geometry, (p) => {
const angleRadians = angleDegrees * Math.PI / -180;
const originX = origin.coordinates[0];
const originY = origin.coordinates[1];
const x = p.coordinates[0];
const y = p.coordinates[1];
const dx = x - originX;
const dy = y - originY;
const newX = originX + dx * Math.cos(angleRadians) - dy * Math.sin(angleRadians);
const newY = originY + dx * Math.sin(angleRadians) + dy * Math.cos(angleRadians);
return turf2.point([newX, newY]).geometry;
});
}, "Rotate");
BuiltInFunctions2.Round = /* @__PURE__ */ __name((precision = 0, val) => {
if (typeof val === "number") {
return +val.toFixed(precision);
}
if (isGeometryType("Point" /* Point */, val)) {
const coords = val.coordinates;
return turf2.point([
(0, BuiltInFunctions2.Round)(precision, coords[0]),
(0, BuiltInFunctions2.Round)(precision, coords[1])
]).geometry;
}
throw new OperationNotSupported(`Unable to round value: ${toString(val)}`);
}, "Round");
})(BuiltInFunctions || (BuiltInFunctions = {}));
// src/interpreter/grammar.ts
var GRAMMAR = String.raw`
WAEL {
/***************
* WAEL syntax *
***************/
// Top-level expressions
TopLevel = ScopedExpressions TopLevelEnd
TopLevelEnd = ExpressionDelimiter | end
// Comments
comment = "#" commentSpace* commentText* commentSpace* commentEnd
commentText = ~commentEnd any
commentEnd = "\n" | end
commentSpace = " "
// Expression structure
ScopedExpressions = ListOf<GeneralExpression, ExpressionDelimiter> --list
| GeneralExpression
GeneralExpression = GeneralExpression comment --rightComment
| comment GeneralExpression --leftComment
| AssignmentExp
| AssignableExpression
| comment
ExpressionDelimiter = expressionDelimiter
expressionDelimiter = ";"
// Imports
ImportExpression = AccessibleExp<ImportExpressionType>
ImportExpressionType = ImportUsingExpression | ImportAllExpression
ImportUsingExpression = ImportEitherExpression usingKeyword ImportUsingParameters
ImportUsingParameters = FunctionParameters | ImportUsingAllParams
ImportUsingAllParams = Paren<"*">
ImportAllExpression = ImportEitherExpression
ImportEitherExpression = ImportExternalExp | ImportFunctionExp
ImportExternalExp = importKeyword Paren<ImportExternalParamExp>
ImportExternalParamExp = stringLiteralExp | Identifier
ImportFunctionExp = importKeyword Paren<FunctionCallExp>
importKeyword = caseInsensitive<"import">
usingKeyword = caseInsensitive<"using">
// Exports
exportKeyword = caseInsensitive<"export">
// Variables
letKeyword = caseInsensitive<"let">
AssignmentExp = exportKeyword? letKeyword? Identifier assignmentOperator AssignableExpression
AssignableExpression =
| ImportExpression
| NonArithmeticAssignableExpression
| ArithmeticAssignableExpression
NonArithmeticAssignableExpression =
| OperationExp
| stringLiteralExp
ArithmeticAssignableExpression = Arithmetic<AssignableExpressionForArithmetic>
AssignableExpressionForArithmetic =
| BooleanResultExp
| IfThenElseExp
| ComputedExp
| FunctionTextExp
| NumberExp
| AccessibleExp<GeometryExp>
| BooleanValue
| Paren<OperationExp>
assignmentOperator = "="
ComputedValue<Type> = Type | ComputedExp
ComputedExp = AccessibleExp<ComputedPrimitive>
ComputedPrimitive = FunctionCallExp | Identifier
AccessibleExp<Type> =
| Type accessorOperator Identifier Invocation? --method
| Type
// Additional operation expressions
OperationExp = PipeExp | GenerateExp | ConcatExp
PipeExp = MappableValue anyPipeOperator Pipeable //Callable
Pipeable = FunctionCallExp | Callable
GenerateExp = generateKeyword GenerateCountExpr ComputedValue<GenerateValue>
GenerateCountExpr = ComputedValue<NumberExp> | FunctionTextExp
ConcatExp = MappableValue concatOperator MappableValue
GenerateValue = GeometryExp | FunctionTextExp
generateKeyword = caseInsensitive<"Generate">
MappableValue = AssignableExpression
// Helpers
Paren<type> = LeftParen type RightParen
OptionallyParen<type> = LeftParen type RightParen --paren
| type --noParen
OptionallyBraced<type> = LeftBrace type RightBrace --brace
| type
// Arithmetic expressions
Arithmetic<Type> = ArithmeticAdd<Type>
ArithmeticAdd<Type> =
| ArithmeticAdd<Type> plusOperator ArithmeticMul<Type> -- plus
| ArithmeticAdd<Type> minusOperator ArithmeticMul<Type> -- minus
| ArithmeticMul<Type>
ArithmeticMul<Type> =
| ArithmeticMul<Type> timesOperator ArithmeticExp<Type> -- times
| ArithmeticMul<Type> divideOperator ArithmeticExp<Type> -- divide
| ArithmeticMul<Type> modOperator ArithmeticExp<Type> -- mod
| ArithmeticExp<Type>
ArithmeticExp<Type> =
| ArithmeticPri<Type> powerOperator ArithmeticExp<Type> -- power
| ArithmeticPri<Type>
ArithmeticPri<Type> =
| Type
| leftParen Arithmetic<Type> rightParen -- paren
// Operators
operator =
| expressionDelimiter
| anyPipeOperator
| plusOperator
| minusOperator
| timesOperator
| divideOperator
| powerOperator
| modOperator
| accessorOperator
| conditionalOperator
| assignmentOperator
| notOperator
anyPipeOperator = doublePipeOperator | coordinatesPipeOperator | filterOperator | reduceOperator | pipeOperator
pipeOperator = "|"
coordinatesPipeOperator = "|*"
doublePipeOperator = "||"
filterOperator = "|~"
reduceOperator = "|>"
concatOperator = "++"
plusOperator = "+"
minusOperator = "-"
timesOperator = "*"
divideOperator = "/"
powerOperator = "^"
modOperator = "%"
accessorOperator = ":"
// Function expressions
FunctionTextExp = functionKeyword LeftParen FunctionExp RightParen --keyword
| OptionallyParen<FunctionExp>
FunctionExp = FunctionParameters "=>" OptionallyParen<FunctionBody>
FunctionParameters = LeftParen ListOf<Identifier, Comma> RightParen --multipleParams
| Identifier --single
FunctionBody = OptionallyParen<ScopedExpressions> | AssignableExpression
FunctionCallExp = FunctionCallExp Invocation | Callable Invocation
Invocation = LeftParen ListOf<GeneralExpression, Comma> RightParen
functionKeyword = caseInsensitive<"Function">
Callable =
| FunctionTextExp
| FunctionCallExp
| AccessibleExp<Callable>
| Identifier
// If-Then-Else expressions
IfThenElseExp = ifKeyword Paren<BooleanResultExp> thenKeyword
Paren<ScopedExpressions> elseKeyword
Paren<ScopedExpressions>
ifKeyword = caseInsensitive<"if">
thenKeyword = caseInsensitive<"then">
elseKeyword = caseInsensitive<"else">
// Conditional expressions
BooleanResultExp = EqualityExp | CompareExp | NotExp | booleanValue
EqualityExp = ComparePrimitive equalityOperatorPrimitive ComparePrimitive
NotExp = notOperator ComparePrimitive
ConditionalValue = CompareExp | EqualityExp | BooleanValue | NumberExp
CompareExp = ComparePrimitive compareOperatorPrimitive ComparePrimitive
ComparePrimitive = BooleanResultExp | ComputedValue<NumberExp> | AccessibleExp<GeometryExp> | geometryKeyword
conditionalOperator = compareOperatorPrimitive | equalityOperatorPrimitive
compareOperatorPrimitive = "<=" | ">=" | "<" | ">"
equalityOperatorPrimitive = "==" | "!=" | logicalOperator
logicalOperator = caseInsensitive<"And"> | caseInsensitive<"Or">
notOperator = "!"
// Identifiers
Identifier = basicIdentifier
basicIdentifier = ~nonAllowedIdentifiers id
id = firstIdCharacter idCharacter*
firstIdCharacter = simpleLatinLetter | "$" | "_"
idCharacter = simpleLatinLetter | digit | "_" | "?" | "'"
nonAllowedIdentifiers = keyword identifierEnd
identifierEnd = end | comma | leftParen | rightParen | operator | wktSpace
/*************************************
* OGC Well-Known Text (WKT) Grammar *
*************************************/
// Based on WKT Syntax: https://www.ogc.org/standard/sfa/
GeometrySyntaxExp<GeometryTypeExp, geometryKeyword> = Arithmetic<GeometryArithmetic<GeometryTypeExp, geometryKeyword>>
GeometryArithmetic<GeometryTypeExp, geometryKeyword> = GeometryPrimitive<GeometryTypeExp, geometryKeyword>
GeometryPrimitive<GeometryTypeExp, geometryKeyword> = GeometryTaggedText<GeometryTypeExp, geometryKeyword>
GeometryTaggedText<GeometryTypeExp, geometryKeyword> = geometryKeyword GeometryTypeExp
GeometryCollectionExp = GeometrySyntaxExp<GeometryCollectionText, geometryCollectionKeyword>
GeometryCollectionText = emptySet --empty
| LeftParen ListOf<GeometryExp, Comma> RightParen --present
geometryCollectionKeyword = caseInsensitive<"GEOMETRYCOLLECTION">
GeometryExp =
| PointExp
| MultiPointExp
| LineStringExp
| MultiLineStringExp
| PolygonExp
| MultiPolygonExp
| GeometryCollectionExp
// TODO -- support POLYHEDRALSURFACE geometry
//PolyhedralSurfaceExp = GeometrySyntaxExp<PolyhedralSurfaceText, polyhedralSurfaceKeyword>
//PolyhedralSurfaceText = emptySet --empty
// | LeftParen NonemptyListOf<PolygonText, Comma> RightParen --present
//polyhedralSurfaceKeyword = caseInsensitive<"PolyhedralSurface">
MultiPolygonExp = GeometrySyntaxExp<MultiPolygonText, multiPolygonKeyword>
MultiPolygonText = emptySet --empty
| LeftParen NonemptyListOf<PolygonText, Comma> RightParen --present
multiPolygonKeyword = caseInsensitive<"MULTIPOLYGON">
PolygonExp = GeometrySyntaxExp<PolygonText, polygonKeyword>
PolygonText = emptySet --empty
| LeftParen NonemptyListOf<LineStringText, Comma> RightParen --present
polygonKeyword = caseInsensitive<"POLYGON">
MultiLineStringExp = GeometrySyntaxExp<MultiLineStringText, multiLineStringKeyword>
MultiLineStringText = emptySet --empty
| LeftParen NonemptyListOf<LineStringText, Comma> RightParen --present
multiLineStringKeyword = caseInsensitive<"MULTILINESTRING">
LineStringExp = GeometrySyntaxExp<LineStringText, lineStringKeyword>
LineStringText = emptySet --empty
| LeftParen PointList RightParen --present
lineStringKeyword = caseInsensitive<"LINESTRING">
MultiPointExp = GeometrySyntaxExp<MultiPointText, multiPointKeyword>
MultiPointText = emptySet --empty
| LeftParen PointList RightParen --present
multiPointKeyword = caseInsensitive<"MULTIPOINT">
// Base point type helpers
PointList = NonemptyListOf<PointListArgument, Comma>
PointListArgument = Point | ComputedValue<PointExp>
PointExp = Arithmetic<PointArithmetic>
PointArithmetic = PointPrimitive | ComputedExp
PointPrimitive = PointTaggedText | PointText | Point
PointTaggedText = pointKeyword PointText
PointText = emptySet --empty
| LeftParen Point RightParen --present
Point = X Y
pointKeyword = caseInsensitive<"POINT">
// Keywords
keyword = geometryKeyword
| functionKeyword
| generateKeyword
| booleanValue
| ifKeyword
| thenKeyword
| elseKeyword
| importKeyword
| exportKeyword
| letKeyword
geometryKeyword = pointKeyword
| multiPointKeyword
| lineStringKeyword
| multiLineStringKeyword
| polygonKeyword
| multiPolygonKeyword
| geometryCollectionKeyword
// Coordinate values
X = PointNumberValue
Y = PointNumberValue
Z = PointNumberValue
M = PointNumberValue
// Numeric value
PointNumberValue = signedNumericLiteral
| OptionallyParen<ComputedValue<NumberExp>>
| ComputedPrimitive
NumberExp = Arithmetic<ComputedValue<signedNumericLiteral>>
// Boolean value
BooleanValue = ComputedValue<booleanValue>
booleanValue = caseInsensitive<"true"> | caseInsensitive<"false">
// String literals
stringLiteralExp = stringLiteral<"'"> | stringLiteral<"\"">
stringLiteral<quoteChar> = quoteChar stringLiteralValue<quoteChar>* quoteChar
stringLiteralValue<quoteChar> = ~quoteChar any
// OGC specification primitives
quotedName = doubleQuote name doubleQuote
name = letters
letters = wktLetter+
wktLetter = simpleLatinLetter | digit | special
simpleLatinLetter = simpleLatinUpperCaseLetter
| simpleLatinLowerCaseLetter
signedNumericLiteral = sign unsignedNumericLiteral --signPresent
| unsignedNumericLiteral --signMissing
unsignedNumericLiteral = exactNumericLiteral | approximateNumericLiteral
approximateNumericLiteral = mantissa "E" exponent // TODO -- handle this notation at higher level expressions
mantissa = exactNumericLiteral
exponent = signedInteger
exactNumericLiteral = unsignedInteger decimalPoint unsignedInteger --decimalWithWholeNumber
| decimalPoint unsignedInteger --decimalWithoutWholeNumber
| unsignedInteger --wholeNumber
signedInteger = sign unsignedInteger --signedInteger
| unsignedInteger --unsignedInteger
unsignedInteger = digit+
leftDelimiter = leftParen | leftBracket
rightDelimiter = rightParen | rightBracket
special = rightParen | leftParen | minusSign | underscore | period | quote | wktSpace
sign = plusSign | minusSign
decimalPoint = period // comma // TODO -- comma causes parsing issues
emptySet = "EMPTY"
minusSign = "-"
LeftParen = leftParen
leftParen = "("
RightParen = rightParen
rightParen = ")"
leftBracket = "["
rightBracket = "]"
LeftBrace = leftBrace
leftBrace = "{"
RightBrace = rightBrace
rightBrace = "}"
period = "."
plusSign = "+"
doubleQuote = "\""
quote = "'"
Comma = comma
comma = ","
underscore = "_"
// digit = 0|1|2|3|4|5|6|7|8|9 // provided by default
simpleLatinLowerCaseLetter = lower // a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z
simpleLatinUpperCaseLetter = upper // A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z
wktSpace = " " // unicode "U+0020" (space) // provided by default
}
`;
// src/interpreter/interpreter.ts
var import_fs = require("fs");
var import_sync_fetch = __toESM(require("sync-fetch"));
var grammarString = GRAMMAR;
var Interpreter;
((Interpreter2) => {
Interpreter2.IMPORT_DEFAULT_IDENTIFIER = "Default";
Interpreter2.IMPORT_USING_ALL = "*";
Interpreter2.STANDARD_LIBRARY = {};
const math = {};
Object.getOwnPropertyNames(Math).forEach((prop) => {
math[prop] = Math[prop];
});
Interpreter2.STANDARD_LIBRARY["Math"] = math;
Interpreter2.STANDARD_LIBRARY["Flatten"] = BuiltInFunctions.Flatten;
Interpreter2.STANDARD_LIBRARY["PointCircle"] = BuiltInFunctions.PointCircle;
Interpreter2.STANDARD_LIBRARY["PointGrid"] = BuiltInFunctions.PointGrid;
Interpreter2.STANDARD_LIBRARY["ToLineString"] = BuiltInFunctions.ToLineString;
Interpreter2.STANDARD_LIBRARY["ToMultiPoint"] = BuiltInFunctions.ToMultiPoint;
Interpreter2.STANDARD_LIBRARY["ToPolygon"] = BuiltInFunctions.ToPolygon;
Interpreter2.STANDARD_LIBRARY["ToGeometryCollection"] = BuiltInFunctions.ToGeometryCollection;
Interpreter2.STANDARD_LIBRARY["_Rotate"] = BuiltInFunctions.Rotate;
Interpreter2.STANDARD_LIBRARY["_Round"] = BuiltInFunctions.Round;
Interpreter2.createGlobalScope = /* @__PURE__ */ __name(() => new Scope(void 0, void 0, Interpreter2.STANDARD_LIBRARY), "createGlobalScope");
function evaluateInput(input, initialScope) {
const GLOBAL_SCOPE = (0, Interpreter2.createGlobalScope)();
let currentScope = initialScope || GLOBAL_SCOPE;
const grammar2 = ohm.grammar(grammarString);
const semantics = grammar2.createSemantics();
semantics.addOperation("eval", {
stringLiteral(_leftQuote, str, _rightQuote) {
return str.sourceString;
},
ImportAllExpression(exp) {
const ret = exp.eval();
if (ret) {
return ret;
}
const importObj = currentScope.useImports();
return importObj;
},
ImportUsingExpression(importAllExp, _keyword, identifierList) {
importAllExp.eval();
const identifiers = identifierList.eval();
let importObj;
if (identifiers === Interpreter2.IMPORT_USING_ALL) {
importObj = currentScope.useNamedImports(Object.keys(currentScope.availableBindings));
} else {
importObj = currentScope.useNamedImports(identifiers);
}
return importObj;
},
ImportUsingAllParams(_) {
return Interpreter2.IMPORT_USING_ALL;
},
ImportExternalExp(_keyword, importUri) {
const uri = importUri.eval();
let data;
if (uri.startsWith("http://") || uri.startsWith("https://")) {
data = (0, import_sync_fetch.default)(uri).text();
} else {
data = (0, import_fs.readFileSync)(uri, "utf8");
}
currentScope = currentScope.push();
let ret = void 0;
let bindings = void 0;
try {
ret = convertToGeometry(JSON.parse(data));
} catch (e) {
try {
const libRet = evaluateInput(data, currentScope);
bindings = {};
bindings[Interpreter2.IMPORT_DEFAULT_IDENTIFIER] = libRet;
} catch (e2) {
throw new Error(`Unable to import file: ${uri}`);
}
}
currentScope = currentScope.pop(bindings) || GLOBAL_SCOPE;
return ret;
},
ImportFunctionExp(_keyword, importFn) {
importFn.eval();
},
IfThenElseExp(_if, c, _then, exp1, _else, exp2) {
const condition = c.eval();
if (condition) {
return exp1.eval();
}
return exp2.eval();
},
booleanValue(val) {
const value = val.sourceString.toLocaleLowerCase();
if (value === "true") {
return true;
}
if (value === "false") {
return false;
}
throw new Error(`Invalid boolean value: ${val.sourceString}`);
},
EqualityExp(v1, op, v2) {
const value1 = v1.eval();
const operator = op.sourceString;
const value2 = v2.eval();
switch (operator.trim().toLocaleLowerCase()) {
case "==":
return value1 === value2;
case "!=":
return value1 !== value2;
case "and":
return value1 && value2;
case "or":
return value1 || value2;
}
throw new Error(`Operator not supported: ${operator}`);
},
NotExp(_, exp) {
return !exp.eval();
},
geometryKeyword(keyword) {
return keyword.sourceString;