(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.G = {})); }(this, (function (exports) { 'use strict'; var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; function createCommonjsModule(fn, basedir, module) { return module = { path: basedir, exports: {}, require: function (path, base) { return commonjsRequire(path, (base === undefined || base === null) ? module.path : base); } }, fn(module, module.exports), module.exports; } function commonjsRequire () { throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs'); } var rbush = createCommonjsModule(function (module, exports) { (function (global, factory) { module.exports = factory() ; }(commonjsGlobal, function () { function quickselect(arr, k, left, right, compare) { quickselectStep(arr, k, left || 0, right || (arr.length - 1), compare || defaultCompare); } function quickselectStep(arr, k, left, right, compare) { while (right > left) { if (right - left > 600) { var n = right - left + 1; var m = k - left + 1; var z = Math.log(n); var s = 0.5 * Math.exp(2 * z / 3); var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1); var newLeft = Math.max(left, Math.floor(k - m * s / n + sd)); var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd)); quickselectStep(arr, k, newLeft, newRight, compare); } var t = arr[k]; var i = left; var j = right; swap(arr, left, k); if (compare(arr[right], t) > 0) { swap(arr, left, right); } while (i < j) { swap(arr, i, j); i++; j--; while (compare(arr[i], t) < 0) { i++; } while (compare(arr[j], t) > 0) { j--; } } if (compare(arr[left], t) === 0) { swap(arr, left, j); } else { j++; swap(arr, j, right); } if (j <= k) { left = j + 1; } if (k <= j) { right = j - 1; } } } function swap(arr, i, j) { var tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } function defaultCompare(a, b) { return a < b ? -1 : a > b ? 1 : 0; } var RBush = function RBush(maxEntries) { if ( maxEntries === void 0 ) maxEntries = 9; // max entries in a node is 9 by default; min node fill is 40% for best performance this._maxEntries = Math.max(4, maxEntries); this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4)); this.clear(); }; RBush.prototype.all = function all () { return this._all(this.data, []); }; RBush.prototype.search = function search (bbox) { var node = this.data; var result = []; if (!intersects(bbox, node)) { return result; } var toBBox = this.toBBox; var nodesToSearch = []; while (node) { for (var i = 0; i < node.children.length; i++) { var child = node.children[i]; var childBBox = node.leaf ? toBBox(child) : child; if (intersects(bbox, childBBox)) { if (node.leaf) { result.push(child); } else if (contains(bbox, childBBox)) { this._all(child, result); } else { nodesToSearch.push(child); } } } node = nodesToSearch.pop(); } return result; }; RBush.prototype.collides = function collides (bbox) { var node = this.data; if (!intersects(bbox, node)) { return false; } var nodesToSearch = []; while (node) { for (var i = 0; i < node.children.length; i++) { var child = node.children[i]; var childBBox = node.leaf ? this.toBBox(child) : child; if (intersects(bbox, childBBox)) { if (node.leaf || contains(bbox, childBBox)) { return true; } nodesToSearch.push(child); } } node = nodesToSearch.pop(); } return false; }; RBush.prototype.load = function load (data) { if (!(data && data.length)) { return this; } if (data.length < this._minEntries) { for (var i = 0; i < data.length; i++) { this.insert(data[i]); } return this; } // recursively build the tree with the given data from scratch using OMT algorithm var node = this._build(data.slice(), 0, data.length - 1, 0); if (!this.data.children.length) { // save as is if tree is empty this.data = node; } else if (this.data.height === node.height) { // split root if trees have the same height this._splitRoot(this.data, node); } else { if (this.data.height < node.height) { // swap trees if inserted one is bigger var tmpNode = this.data; this.data = node; node = tmpNode; } // insert the small tree into the large tree at appropriate level this._insert(node, this.data.height - node.height - 1, true); } return this; }; RBush.prototype.insert = function insert (item) { if (item) { this._insert(item, this.data.height - 1); } return this; }; RBush.prototype.clear = function clear () { this.data = createNode([]); return this; }; RBush.prototype.remove = function remove (item, equalsFn) { if (!item) { return this; } var node = this.data; var bbox = this.toBBox(item); var path = []; var indexes = []; var i, parent, goingUp; // depth-first iterative tree traversal while (node || path.length) { if (!node) { // go up node = path.pop(); parent = path[path.length - 1]; i = indexes.pop(); goingUp = true; } if (node.leaf) { // check current node var index = findItem(item, node.children, equalsFn); if (index !== -1) { // item found, remove the item and condense tree upwards node.children.splice(index, 1); path.push(node); this._condense(path); return this; } } if (!goingUp && !node.leaf && contains(node, bbox)) { // go down path.push(node); indexes.push(i); i = 0; parent = node; node = node.children[0]; } else if (parent) { // go right i++; node = parent.children[i]; goingUp = false; } else { node = null; } // nothing found } return this; }; RBush.prototype.toBBox = function toBBox (item) { return item; }; RBush.prototype.compareMinX = function compareMinX (a, b) { return a.minX - b.minX; }; RBush.prototype.compareMinY = function compareMinY (a, b) { return a.minY - b.minY; }; RBush.prototype.toJSON = function toJSON () { return this.data; }; RBush.prototype.fromJSON = function fromJSON (data) { this.data = data; return this; }; RBush.prototype._all = function _all (node, result) { var nodesToSearch = []; while (node) { if (node.leaf) { result.push.apply(result, node.children); } else { nodesToSearch.push.apply(nodesToSearch, node.children); } node = nodesToSearch.pop(); } return result; }; RBush.prototype._build = function _build (items, left, right, height) { var N = right - left + 1; var M = this._maxEntries; var node; if (N <= M) { // reached leaf level; return leaf node = createNode(items.slice(left, right + 1)); calcBBox(node, this.toBBox); return node; } if (!height) { // target height of the bulk-loaded tree height = Math.ceil(Math.log(N) / Math.log(M)); // target number of root entries to maximize storage utilization M = Math.ceil(N / Math.pow(M, height - 1)); } node = createNode([]); node.leaf = false; node.height = height; // split the items into M mostly square tiles var N2 = Math.ceil(N / M); var N1 = N2 * Math.ceil(Math.sqrt(M)); multiSelect(items, left, right, N1, this.compareMinX); for (var i = left; i <= right; i += N1) { var right2 = Math.min(i + N1 - 1, right); multiSelect(items, i, right2, N2, this.compareMinY); for (var j = i; j <= right2; j += N2) { var right3 = Math.min(j + N2 - 1, right2); // pack each entry recursively node.children.push(this._build(items, j, right3, height - 1)); } } calcBBox(node, this.toBBox); return node; }; RBush.prototype._chooseSubtree = function _chooseSubtree (bbox, node, level, path) { while (true) { path.push(node); if (node.leaf || path.length - 1 === level) { break; } var minArea = Infinity; var minEnlargement = Infinity; var targetNode = (void 0); for (var i = 0; i < node.children.length; i++) { var child = node.children[i]; var area = bboxArea(child); var enlargement = enlargedArea(bbox, child) - area; // choose entry with the least area enlargement if (enlargement < minEnlargement) { minEnlargement = enlargement; minArea = area < minArea ? area : minArea; targetNode = child; } else if (enlargement === minEnlargement) { // otherwise choose one with the smallest area if (area < minArea) { minArea = area; targetNode = child; } } } node = targetNode || node.children[0]; } return node; }; RBush.prototype._insert = function _insert (item, level, isNode) { var bbox = isNode ? item : this.toBBox(item); var insertPath = []; // find the best node for accommodating the item, saving all nodes along the path too var node = this._chooseSubtree(bbox, this.data, level, insertPath); // put the item into the node node.children.push(item); extend(node, bbox); // split on node overflow; propagate upwards if necessary while (level >= 0) { if (insertPath[level].children.length > this._maxEntries) { this._split(insertPath, level); level--; } else { break; } } // adjust bboxes along the insertion path this._adjustParentBBoxes(bbox, insertPath, level); }; // split overflowed node into two RBush.prototype._split = function _split (insertPath, level) { var node = insertPath[level]; var M = node.children.length; var m = this._minEntries; this._chooseSplitAxis(node, m, M); var splitIndex = this._chooseSplitIndex(node, m, M); var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex)); newNode.height = node.height; newNode.leaf = node.leaf; calcBBox(node, this.toBBox); calcBBox(newNode, this.toBBox); if (level) { insertPath[level - 1].children.push(newNode); } else { this._splitRoot(node, newNode); } }; RBush.prototype._splitRoot = function _splitRoot (node, newNode) { // split root node this.data = createNode([node, newNode]); this.data.height = node.height + 1; this.data.leaf = false; calcBBox(this.data, this.toBBox); }; RBush.prototype._chooseSplitIndex = function _chooseSplitIndex (node, m, M) { var index; var minOverlap = Infinity; var minArea = Infinity; for (var i = m; i <= M - m; i++) { var bbox1 = distBBox(node, 0, i, this.toBBox); var bbox2 = distBBox(node, i, M, this.toBBox); var overlap = intersectionArea(bbox1, bbox2); var area = bboxArea(bbox1) + bboxArea(bbox2); // choose distribution with minimum overlap if (overlap < minOverlap) { minOverlap = overlap; index = i; minArea = area < minArea ? area : minArea; } else if (overlap === minOverlap) { // otherwise choose distribution with minimum area if (area < minArea) { minArea = area; index = i; } } } return index || M - m; }; // sorts node children by the best axis for split RBush.prototype._chooseSplitAxis = function _chooseSplitAxis (node, m, M) { var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX; var compareMinY = node.leaf ? this.compareMinY : compareNodeMinY; var xMargin = this._allDistMargin(node, m, M, compareMinX); var yMargin = this._allDistMargin(node, m, M, compareMinY); // if total distributions margin value is minimal for x, sort by minX, // otherwise it's already sorted by minY if (xMargin < yMargin) { node.children.sort(compareMinX); } }; // total margin of all possible split distributions where each node is at least m full RBush.prototype._allDistMargin = function _allDistMargin (node, m, M, compare) { node.children.sort(compare); var toBBox = this.toBBox; var leftBBox = distBBox(node, 0, m, toBBox); var rightBBox = distBBox(node, M - m, M, toBBox); var margin = bboxMargin(leftBBox) + bboxMargin(rightBBox); for (var i = m; i < M - m; i++) { var child = node.children[i]; extend(leftBBox, node.leaf ? toBBox(child) : child); margin += bboxMargin(leftBBox); } for (var i$1 = M - m - 1; i$1 >= m; i$1--) { var child$1 = node.children[i$1]; extend(rightBBox, node.leaf ? toBBox(child$1) : child$1); margin += bboxMargin(rightBBox); } return margin; }; RBush.prototype._adjustParentBBoxes = function _adjustParentBBoxes (bbox, path, level) { // adjust bboxes along the given tree path for (var i = level; i >= 0; i--) { extend(path[i], bbox); } }; RBush.prototype._condense = function _condense (path) { // go through the path, removing empty nodes and updating bboxes for (var i = path.length - 1, siblings = (void 0); i >= 0; i--) { if (path[i].children.length === 0) { if (i > 0) { siblings = path[i - 1].children; siblings.splice(siblings.indexOf(path[i]), 1); } else { this.clear(); } } else { calcBBox(path[i], this.toBBox); } } }; function findItem(item, items, equalsFn) { if (!equalsFn) { return items.indexOf(item); } for (var i = 0; i < items.length; i++) { if (equalsFn(item, items[i])) { return i; } } return -1; } // calculate node's bbox from bboxes of its children function calcBBox(node, toBBox) { distBBox(node, 0, node.children.length, toBBox, node); } // min bounding rectangle of node children from k to p-1 function distBBox(node, k, p, toBBox, destNode) { if (!destNode) { destNode = createNode(null); } destNode.minX = Infinity; destNode.minY = Infinity; destNode.maxX = -Infinity; destNode.maxY = -Infinity; for (var i = k; i < p; i++) { var child = node.children[i]; extend(destNode, node.leaf ? toBBox(child) : child); } return destNode; } function extend(a, b) { a.minX = Math.min(a.minX, b.minX); a.minY = Math.min(a.minY, b.minY); a.maxX = Math.max(a.maxX, b.maxX); a.maxY = Math.max(a.maxY, b.maxY); return a; } function compareNodeMinX(a, b) { return a.minX - b.minX; } function compareNodeMinY(a, b) { return a.minY - b.minY; } function bboxArea(a) { return (a.maxX - a.minX) * (a.maxY - a.minY); } function bboxMargin(a) { return (a.maxX - a.minX) + (a.maxY - a.minY); } function enlargedArea(a, b) { return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) * (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY)); } function intersectionArea(a, b) { var minX = Math.max(a.minX, b.minX); var minY = Math.max(a.minY, b.minY); var maxX = Math.min(a.maxX, b.maxX); var maxY = Math.min(a.maxY, b.maxY); return Math.max(0, maxX - minX) * Math.max(0, maxY - minY); } function contains(a, b) { return a.minX <= b.minX && a.minY <= b.minY && b.maxX <= a.maxX && b.maxY <= a.maxY; } function intersects(a, b) { return b.minX <= a.maxX && b.minY <= a.maxY && b.maxX >= a.minX && b.maxY >= a.minY; } function createNode(children) { return { children: children, height: 1, leaf: true, minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity }; } // sort an array so that items come in groups of n unsorted items, with groups sorted between each other; // combines selection algorithm with binary divide & conquer approach function multiSelect(arr, left, right, n, compare) { var stack = [left, right]; while (stack.length) { right = stack.pop(); left = stack.pop(); if (right - left <= n) { continue; } var mid = left + Math.ceil((right - left) / n / 2) * n; quickselect(arr, mid, left, right, compare); stack.push(left, mid, mid, right); } } return RBush; })); }); /** * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type */ (function (PropertySyntax) { /** * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#coordinate */ PropertySyntax["COORDINATE"] = ""; /** * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#color */ PropertySyntax["COLOR"] = ""; /** * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#paint */ PropertySyntax["PAINT"] = ""; /** * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#number */ PropertySyntax["NUMBER"] = ""; /** * @see https://developer.mozilla.org/zh-CN/docs/Web/CSS/angle */ PropertySyntax["ANGLE"] = ""; /** * with range 0..1 * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#opacity_value */ PropertySyntax["OPACITY_VALUE"] = ""; /** * with range 0..Infinity */ PropertySyntax["SHADOW_BLUR"] = ""; /** * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#length */ PropertySyntax["LENGTH"] = ""; /** * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#percentage */ PropertySyntax["PERCENTAGE"] = ""; PropertySyntax["LENGTH_PERCENTAGE"] = " | "; PropertySyntax["LENGTH_PERCENTAGE_12"] = "[ | ]{1,2}"; /** * @see https://developer.mozilla.org/en-US/docs/Web/CSS/margin#formal_syntax */ PropertySyntax["LENGTH_PERCENTAGE_14"] = "[ | ]{1,4}"; /** * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#list-of-ts */ PropertySyntax["LIST_OF_POINTS"] = ""; PropertySyntax["PATH"] = ""; /** * @see https://developer.mozilla.org/en-US/docs/Web/CSS/filter#formal_syntax */ PropertySyntax["FILTER"] = ""; PropertySyntax["Z_INDEX"] = ""; PropertySyntax["OFFSET_DISTANCE"] = ""; PropertySyntax["DEFINED_PATH"] = ""; PropertySyntax["MARKER"] = ""; PropertySyntax["TRANSFORM"] = ""; PropertySyntax["TRANSFORM_ORIGIN"] = ""; PropertySyntax["TEXT"] = ""; PropertySyntax["TEXT_TRANSFORM"] = ""; })(exports.PropertySyntax || (exports.PropertySyntax = {})); function _regeneratorRuntime() { _regeneratorRuntime = function () { return exports; }; var exports = {}, Op = Object.prototype, hasOwn = Op.hasOwnProperty, defineProperty = Object.defineProperty || function (obj, key, desc) { obj[key] = desc.value; }, $Symbol = "function" == typeof Symbol ? Symbol : {}, iteratorSymbol = $Symbol.iterator || "@@iterator", asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; function define(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }), obj[key]; } try { define({}, ""); } catch (err) { define = function (obj, key, value) { return obj[key] = value; }; } function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator, generator = Object.create(protoGenerator.prototype), context = new Context(tryLocsList || []); return defineProperty(generator, "_invoke", { value: makeInvokeMethod(innerFn, self, context) }), generator; } function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } exports.wrap = wrap; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; define(IteratorPrototype, iteratorSymbol, function () { return this; }); var getProto = Object.getPrototypeOf, NativeIteratorPrototype = getProto && getProto(getProto(values([]))); NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { define(prototype, method, function (arg) { return this._invoke(method, arg); }); }); } function AsyncIterator(generator, PromiseImpl) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if ("throw" !== record.type) { var result = record.arg, value = result.value; return value && "object" == typeof value && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }) : PromiseImpl.resolve(value).then(function (unwrapped) { result.value = unwrapped, resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } reject(record.arg); } var previousPromise; defineProperty(this, "_invoke", { value: function (method, arg) { function callInvokeWithMethodAndArg() { return new PromiseImpl(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(innerFn, self, context) { var state = "suspendedStart"; return function (method, arg) { if ("executing" === state) throw new Error("Generator is already running"); if ("completed" === state) { if ("throw" === method) throw arg; return doneResult(); } for (context.method = method, context.arg = arg;;) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { if ("suspendedStart" === state) throw state = "completed", context.arg; context.dispatchException(context.arg); } else "return" === context.method && context.abrupt("return", context.arg); state = "executing"; var record = tryCatch(innerFn, self, context); if ("normal" === record.type) { if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; return { value: record.arg, done: context.done }; } "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); } }; } function maybeInvokeDelegate(delegate, context) { var methodName = context.method, method = delegate.iterator[methodName]; if (undefined === method) return context.delegate = null, "throw" === methodName && delegate.iterator.return && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method) || "return" !== methodName && (context.method = "throw", context.arg = new TypeError("The iterator does not provide a '" + methodName + "' method")), ContinueSentinel; var record = tryCatch(method, delegate.iterator, context.arg); if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; var info = record.arg; return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); } function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal", delete record.arg, entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); } function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) return iteratorMethod.call(iterable); if ("function" == typeof iterable.next) return iterable; if (!isNaN(iterable.length)) { var i = -1, next = function next() { for (; ++i < iterable.length;) if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; return next.value = undefined, next.done = !0, next; }; return next.next = next; } } return { next: doneResult }; } function doneResult() { return { value: undefined, done: !0 }; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, defineProperty(Gp, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), defineProperty(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { var ctor = "function" == typeof genFun && genFun.constructor; return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); }, exports.mark = function (genFun) { return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; }, exports.awrap = function (arg) { return { __await: arg }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { return this; }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { void 0 === PromiseImpl && (PromiseImpl = Promise); var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { return this; }), define(Gp, "toString", function () { return "[object Generator]"; }), exports.keys = function (val) { var object = Object(val), keys = []; for (var key in object) keys.push(key); return keys.reverse(), function next() { for (; keys.length;) { var key = keys.pop(); if (key in object) return next.value = key, next.done = !1, next; } return next.done = !0, next; }; }, exports.values = values, Context.prototype = { constructor: Context, reset: function (skipTempReset) { if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); }, stop: function () { this.done = !0; var rootRecord = this.tryEntries[0].completion; if ("throw" === rootRecord.type) throw rootRecord.arg; return this.rval; }, dispatchException: function (exception) { if (this.done) throw exception; var context = this; function handle(loc, caught) { return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i], record = entry.completion; if ("root" === entry.tryLoc) return handle("end"); if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"), hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } else if (hasCatch) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); } else { if (!hasFinally) throw new Error("try statement without catch or finally"); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } } } }, abrupt: function (type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); var record = finallyEntry ? finallyEntry.completion : {}; return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); }, complete: function (record, afterLoc) { if ("throw" === record.type) throw record.arg; return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; }, finish: function (finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; } }, catch: function (tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if ("throw" === record.type) { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function (iterable, resultName, nextLoc) { return this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }, "next" === this.method && (this.arg = undefined), ContinueSentinel; } }, exports; } function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); } /** * Common utilities * @module glMatrix */ // Configuration Constants var EPSILON = 0.000001; var ARRAY_TYPE = typeof Float32Array !== 'undefined' ? Float32Array : Array; if (!Math.hypot) Math.hypot = function () { var y = 0, i = arguments.length; while (i--) { y += arguments[i] * arguments[i]; } return Math.sqrt(y); }; /** * 3x3 Matrix * @module mat3 */ /** * Creates a new identity mat3 * * @returns {mat3} a new 3x3 matrix */ function create() { var out = new ARRAY_TYPE(9); if (ARRAY_TYPE != Float32Array) { out[1] = 0; out[2] = 0; out[3] = 0; out[5] = 0; out[6] = 0; out[7] = 0; } out[0] = 1; out[4] = 1; out[8] = 1; return out; } /** * Copies the upper-left 3x3 values into the given mat3. * * @param {mat3} out the receiving 3x3 matrix * @param {ReadonlyMat4} a the source 4x4 matrix * @returns {mat3} out */ function fromMat4(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[4]; out[4] = a[5]; out[5] = a[6]; out[6] = a[8]; out[7] = a[9]; out[8] = a[10]; return out; } /** * Create a new mat3 with the given values * * @param {Number} m00 Component in column 0, row 0 position (index 0) * @param {Number} m01 Component in column 0, row 1 position (index 1) * @param {Number} m02 Component in column 0, row 2 position (index 2) * @param {Number} m10 Component in column 1, row 0 position (index 3) * @param {Number} m11 Component in column 1, row 1 position (index 4) * @param {Number} m12 Component in column 1, row 2 position (index 5) * @param {Number} m20 Component in column 2, row 0 position (index 6) * @param {Number} m21 Component in column 2, row 1 position (index 7) * @param {Number} m22 Component in column 2, row 2 position (index 8) * @returns {mat3} A new mat3 */ function fromValues(m00, m01, m02, m10, m11, m12, m20, m21, m22) { var out = new ARRAY_TYPE(9); out[0] = m00; out[1] = m01; out[2] = m02; out[3] = m10; out[4] = m11; out[5] = m12; out[6] = m20; out[7] = m21; out[8] = m22; return out; } /** * 4x4 Matrix
Format: column-major, when typed out it looks like row-major
The matrices are being post multiplied. * @module mat4 */ /** * Creates a new identity mat4 * * @returns {mat4} a new 4x4 matrix */ function create$1() { var out = new ARRAY_TYPE(16); if (ARRAY_TYPE != Float32Array) { out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; } out[0] = 1; out[5] = 1; out[10] = 1; out[15] = 1; return out; } /** * Creates a new mat4 initialized with values from an existing matrix * * @param {ReadonlyMat4} a matrix to clone * @returns {mat4} a new 4x4 matrix */ function clone(a) { var out = new ARRAY_TYPE(16); out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; out[4] = a[4]; out[5] = a[5]; out[6] = a[6]; out[7] = a[7]; out[8] = a[8]; out[9] = a[9]; out[10] = a[10]; out[11] = a[11]; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; return out; } /** * Copy the values from one mat4 to another * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the source matrix * @returns {mat4} out */ function copy(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; out[4] = a[4]; out[5] = a[5]; out[6] = a[6]; out[7] = a[7]; out[8] = a[8]; out[9] = a[9]; out[10] = a[10]; out[11] = a[11]; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; return out; } /** * Create a new mat4 with the given values * * @param {Number} m00 Component in column 0, row 0 position (index 0) * @param {Number} m01 Component in column 0, row 1 position (index 1) * @param {Number} m02 Component in column 0, row 2 position (index 2) * @param {Number} m03 Component in column 0, row 3 position (index 3) * @param {Number} m10 Component in column 1, row 0 position (index 4) * @param {Number} m11 Component in column 1, row 1 position (index 5) * @param {Number} m12 Component in column 1, row 2 position (index 6) * @param {Number} m13 Component in column 1, row 3 position (index 7) * @param {Number} m20 Component in column 2, row 0 position (index 8) * @param {Number} m21 Component in column 2, row 1 position (index 9) * @param {Number} m22 Component in column 2, row 2 position (index 10) * @param {Number} m23 Component in column 2, row 3 position (index 11) * @param {Number} m30 Component in column 3, row 0 position (index 12) * @param {Number} m31 Component in column 3, row 1 position (index 13) * @param {Number} m32 Component in column 3, row 2 position (index 14) * @param {Number} m33 Component in column 3, row 3 position (index 15) * @returns {mat4} A new mat4 */ function fromValues$1(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) { var out = new ARRAY_TYPE(16); out[0] = m00; out[1] = m01; out[2] = m02; out[3] = m03; out[4] = m10; out[5] = m11; out[6] = m12; out[7] = m13; out[8] = m20; out[9] = m21; out[10] = m22; out[11] = m23; out[12] = m30; out[13] = m31; out[14] = m32; out[15] = m33; return out; } /** * Set the components of a mat4 to the given values * * @param {mat4} out the receiving matrix * @param {Number} m00 Component in column 0, row 0 position (index 0) * @param {Number} m01 Component in column 0, row 1 position (index 1) * @param {Number} m02 Component in column 0, row 2 position (index 2) * @param {Number} m03 Component in column 0, row 3 position (index 3) * @param {Number} m10 Component in column 1, row 0 position (index 4) * @param {Number} m11 Component in column 1, row 1 position (index 5) * @param {Number} m12 Component in column 1, row 2 position (index 6) * @param {Number} m13 Component in column 1, row 3 position (index 7) * @param {Number} m20 Component in column 2, row 0 position (index 8) * @param {Number} m21 Component in column 2, row 1 position (index 9) * @param {Number} m22 Component in column 2, row 2 position (index 10) * @param {Number} m23 Component in column 2, row 3 position (index 11) * @param {Number} m30 Component in column 3, row 0 position (index 12) * @param {Number} m31 Component in column 3, row 1 position (index 13) * @param {Number} m32 Component in column 3, row 2 position (index 14) * @param {Number} m33 Component in column 3, row 3 position (index 15) * @returns {mat4} out */ function set(out, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) { out[0] = m00; out[1] = m01; out[2] = m02; out[3] = m03; out[4] = m10; out[5] = m11; out[6] = m12; out[7] = m13; out[8] = m20; out[9] = m21; out[10] = m22; out[11] = m23; out[12] = m30; out[13] = m31; out[14] = m32; out[15] = m33; return out; } /** * Set a mat4 to the identity matrix * * @param {mat4} out the receiving matrix * @returns {mat4} out */ function identity(out) { out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = 1; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = 1; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; } /** * Transpose the values of a mat4 * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the source matrix * @returns {mat4} out */ function transpose(out, a) { // If we are transposing ourselves we can skip a few steps but have to cache some values if (out === a) { var a01 = a[1], a02 = a[2], a03 = a[3]; var a12 = a[6], a13 = a[7]; var a23 = a[11]; out[1] = a[4]; out[2] = a[8]; out[3] = a[12]; out[4] = a01; out[6] = a[9]; out[7] = a[13]; out[8] = a02; out[9] = a12; out[11] = a[14]; out[12] = a03; out[13] = a13; out[14] = a23; } else { out[0] = a[0]; out[1] = a[4]; out[2] = a[8]; out[3] = a[12]; out[4] = a[1]; out[5] = a[5]; out[6] = a[9]; out[7] = a[13]; out[8] = a[2]; out[9] = a[6]; out[10] = a[10]; out[11] = a[14]; out[12] = a[3]; out[13] = a[7]; out[14] = a[11]; out[15] = a[15]; } return out; } /** * Inverts a mat4 * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the source matrix * @returns {mat4} out */ function invert(out, a) { var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]; var a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]; var a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]; var a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]; var b00 = a00 * a11 - a01 * a10; var b01 = a00 * a12 - a02 * a10; var b02 = a00 * a13 - a03 * a10; var b03 = a01 * a12 - a02 * a11; var b04 = a01 * a13 - a03 * a11; var b05 = a02 * a13 - a03 * a12; var b06 = a20 * a31 - a21 * a30; var b07 = a20 * a32 - a22 * a30; var b08 = a20 * a33 - a23 * a30; var b09 = a21 * a32 - a22 * a31; var b10 = a21 * a33 - a23 * a31; var b11 = a22 * a33 - a23 * a32; // Calculate the determinant var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; if (!det) { return null; } det = 1.0 / det; out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det; out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det; out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det; out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det; out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det; out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det; out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det; out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det; out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det; out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det; out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det; out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det; out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det; out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det; out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det; return out; } /** * Calculates the adjugate of a mat4 * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the source matrix * @returns {mat4} out */ function adjoint(out, a) { var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]; var a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]; var a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]; var a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]; out[0] = a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22); out[1] = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22)); out[2] = a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12); out[3] = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12)); out[4] = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22)); out[5] = a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22); out[6] = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12)); out[7] = a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12); out[8] = a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21); out[9] = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21)); out[10] = a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11); out[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11)); out[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21)); out[13] = a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21); out[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11)); out[15] = a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11); return out; } /** * Calculates the determinant of a mat4 * * @param {ReadonlyMat4} a the source matrix * @returns {Number} determinant of a */ function determinant(a) { var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]; var a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]; var a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]; var a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]; var b00 = a00 * a11 - a01 * a10; var b01 = a00 * a12 - a02 * a10; var b02 = a00 * a13 - a03 * a10; var b03 = a01 * a12 - a02 * a11; var b04 = a01 * a13 - a03 * a11; var b05 = a02 * a13 - a03 * a12; var b06 = a20 * a31 - a21 * a30; var b07 = a20 * a32 - a22 * a30; var b08 = a20 * a33 - a23 * a30; var b09 = a21 * a32 - a22 * a31; var b10 = a21 * a33 - a23 * a31; var b11 = a22 * a33 - a23 * a32; // Calculate the determinant return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; } /** * Multiplies two mat4s * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the first operand * @param {ReadonlyMat4} b the second operand * @returns {mat4} out */ function multiply(out, a, b) { var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]; var a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]; var a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]; var a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]; // Cache only the current line of the second matrix var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3]; out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; b0 = b[4]; b1 = b[5]; b2 = b[6]; b3 = b[7]; out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; b0 = b[8]; b1 = b[9]; b2 = b[10]; b3 = b[11]; out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; b0 = b[12]; b1 = b[13]; b2 = b[14]; b3 = b[15]; out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; return out; } /** * Translate a mat4 by the given vector * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the matrix to translate * @param {ReadonlyVec3} v vector to translate by * @returns {mat4} out */ function translate(out, a, v) { var x = v[0], y = v[1], z = v[2]; var a00, a01, a02, a03; var a10, a11, a12, a13; var a20, a21, a22, a23; if (a === out) { out[12] = a[0] * x + a[4] * y + a[8] * z + a[12]; out[13] = a[1] * x + a[5] * y + a[9] * z + a[13]; out[14] = a[2] * x + a[6] * y + a[10] * z + a[14]; out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]; } else { a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3]; a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7]; a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11]; out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03; out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13; out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23; out[12] = a00 * x + a10 * y + a20 * z + a[12]; out[13] = a01 * x + a11 * y + a21 * z + a[13]; out[14] = a02 * x + a12 * y + a22 * z + a[14]; out[15] = a03 * x + a13 * y + a23 * z + a[15]; } return out; } /** * Scales the mat4 by the dimensions in the given vec3 not using vectorization * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the matrix to scale * @param {ReadonlyVec3} v the vec3 to scale the matrix by * @returns {mat4} out **/ function scale(out, a, v) { var x = v[0], y = v[1], z = v[2]; out[0] = a[0] * x; out[1] = a[1] * x; out[2] = a[2] * x; out[3] = a[3] * x; out[4] = a[4] * y; out[5] = a[5] * y; out[6] = a[6] * y; out[7] = a[7] * y; out[8] = a[8] * z; out[9] = a[9] * z; out[10] = a[10] * z; out[11] = a[11] * z; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; return out; } /** * Rotates a mat4 by the given angle around the given axis * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by * @param {ReadonlyVec3} axis the axis to rotate around * @returns {mat4} out */ function rotate(out, a, rad, axis) { var x = axis[0], y = axis[1], z = axis[2]; var len = Math.hypot(x, y, z); var s, c, t; var a00, a01, a02, a03; var a10, a11, a12, a13; var a20, a21, a22, a23; var b00, b01, b02; var b10, b11, b12; var b20, b21, b22; if (len < EPSILON) { return null; } len = 1 / len; x *= len; y *= len; z *= len; s = Math.sin(rad); c = Math.cos(rad); t = 1 - c; a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3]; a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7]; a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11]; // Construct the elements of the rotation matrix b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s; b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s; b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c; // Perform rotation-specific matrix multiplication out[0] = a00 * b00 + a10 * b01 + a20 * b02; out[1] = a01 * b00 + a11 * b01 + a21 * b02; out[2] = a02 * b00 + a12 * b01 + a22 * b02; out[3] = a03 * b00 + a13 * b01 + a23 * b02; out[4] = a00 * b10 + a10 * b11 + a20 * b12; out[5] = a01 * b10 + a11 * b11 + a21 * b12; out[6] = a02 * b10 + a12 * b11 + a22 * b12; out[7] = a03 * b10 + a13 * b11 + a23 * b12; out[8] = a00 * b20 + a10 * b21 + a20 * b22; out[9] = a01 * b20 + a11 * b21 + a21 * b22; out[10] = a02 * b20 + a12 * b21 + a22 * b22; out[11] = a03 * b20 + a13 * b21 + a23 * b22; if (a !== out) { // If the source and destination differ, copy the unchanged last row out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; } return out; } /** * Rotates a matrix by the given angle around the X axis * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by * @returns {mat4} out */ function rotateX(out, a, rad) { var s = Math.sin(rad); var c = Math.cos(rad); var a10 = a[4]; var a11 = a[5]; var a12 = a[6]; var a13 = a[7]; var a20 = a[8]; var a21 = a[9]; var a22 = a[10]; var a23 = a[11]; if (a !== out) { // If the source and destination differ, copy the unchanged rows out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; } // Perform axis-specific matrix multiplication out[4] = a10 * c + a20 * s; out[5] = a11 * c + a21 * s; out[6] = a12 * c + a22 * s; out[7] = a13 * c + a23 * s; out[8] = a20 * c - a10 * s; out[9] = a21 * c - a11 * s; out[10] = a22 * c - a12 * s; out[11] = a23 * c - a13 * s; return out; } /** * Rotates a matrix by the given angle around the Y axis * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by * @returns {mat4} out */ function rotateY(out, a, rad) { var s = Math.sin(rad); var c = Math.cos(rad); var a00 = a[0]; var a01 = a[1]; var a02 = a[2]; var a03 = a[3]; var a20 = a[8]; var a21 = a[9]; var a22 = a[10]; var a23 = a[11]; if (a !== out) { // If the source and destination differ, copy the unchanged rows out[4] = a[4]; out[5] = a[5]; out[6] = a[6]; out[7] = a[7]; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; } // Perform axis-specific matrix multiplication out[0] = a00 * c - a20 * s; out[1] = a01 * c - a21 * s; out[2] = a02 * c - a22 * s; out[3] = a03 * c - a23 * s; out[8] = a00 * s + a20 * c; out[9] = a01 * s + a21 * c; out[10] = a02 * s + a22 * c; out[11] = a03 * s + a23 * c; return out; } /** * Rotates a matrix by the given angle around the Z axis * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the matrix to rotate * @param {Number} rad the angle to rotate the matrix by * @returns {mat4} out */ function rotateZ(out, a, rad) { var s = Math.sin(rad); var c = Math.cos(rad); var a00 = a[0]; var a01 = a[1]; var a02 = a[2]; var a03 = a[3]; var a10 = a[4]; var a11 = a[5]; var a12 = a[6]; var a13 = a[7]; if (a !== out) { // If the source and destination differ, copy the unchanged last row out[8] = a[8]; out[9] = a[9]; out[10] = a[10]; out[11] = a[11]; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; } // Perform axis-specific matrix multiplication out[0] = a00 * c + a10 * s; out[1] = a01 * c + a11 * s; out[2] = a02 * c + a12 * s; out[3] = a03 * c + a13 * s; out[4] = a10 * c - a00 * s; out[5] = a11 * c - a01 * s; out[6] = a12 * c - a02 * s; out[7] = a13 * c - a03 * s; return out; } /** * Creates a matrix from a vector translation * This is equivalent to (but much faster than): * * mat4.identity(dest); * mat4.translate(dest, dest, vec); * * @param {mat4} out mat4 receiving operation result * @param {ReadonlyVec3} v Translation vector * @returns {mat4} out */ function fromTranslation(out, v) { out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = 1; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = 1; out[11] = 0; out[12] = v[0]; out[13] = v[1]; out[14] = v[2]; out[15] = 1; return out; } /** * Creates a matrix from a vector scaling * This is equivalent to (but much faster than): * * mat4.identity(dest); * mat4.scale(dest, dest, vec); * * @param {mat4} out mat4 receiving operation result * @param {ReadonlyVec3} v Scaling vector * @returns {mat4} out */ function fromScaling(out, v) { out[0] = v[0]; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = v[1]; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = v[2]; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; } /** * Creates a matrix from a given angle around a given axis * This is equivalent to (but much faster than): * * mat4.identity(dest); * mat4.rotate(dest, dest, rad, axis); * * @param {mat4} out mat4 receiving operation result * @param {Number} rad the angle to rotate the matrix by * @param {ReadonlyVec3} axis the axis to rotate around * @returns {mat4} out */ function fromRotation(out, rad, axis) { var x = axis[0], y = axis[1], z = axis[2]; var len = Math.hypot(x, y, z); var s, c, t; if (len < EPSILON) { return null; } len = 1 / len; x *= len; y *= len; z *= len; s = Math.sin(rad); c = Math.cos(rad); t = 1 - c; // Perform rotation-specific matrix multiplication out[0] = x * x * t + c; out[1] = y * x * t + z * s; out[2] = z * x * t - y * s; out[3] = 0; out[4] = x * y * t - z * s; out[5] = y * y * t + c; out[6] = z * y * t + x * s; out[7] = 0; out[8] = x * z * t + y * s; out[9] = y * z * t - x * s; out[10] = z * z * t + c; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; } /** * Creates a matrix from the given angle around the X axis * This is equivalent to (but much faster than): * * mat4.identity(dest); * mat4.rotateX(dest, dest, rad); * * @param {mat4} out mat4 receiving operation result * @param {Number} rad the angle to rotate the matrix by * @returns {mat4} out */ function fromXRotation(out, rad) { var s = Math.sin(rad); var c = Math.cos(rad); // Perform axis-specific matrix multiplication out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = c; out[6] = s; out[7] = 0; out[8] = 0; out[9] = -s; out[10] = c; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; } /** * Creates a matrix from the given angle around the Y axis * This is equivalent to (but much faster than): * * mat4.identity(dest); * mat4.rotateY(dest, dest, rad); * * @param {mat4} out mat4 receiving operation result * @param {Number} rad the angle to rotate the matrix by * @returns {mat4} out */ function fromYRotation(out, rad) { var s = Math.sin(rad); var c = Math.cos(rad); // Perform axis-specific matrix multiplication out[0] = c; out[1] = 0; out[2] = -s; out[3] = 0; out[4] = 0; out[5] = 1; out[6] = 0; out[7] = 0; out[8] = s; out[9] = 0; out[10] = c; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; } /** * Creates a matrix from the given angle around the Z axis * This is equivalent to (but much faster than): * * mat4.identity(dest); * mat4.rotateZ(dest, dest, rad); * * @param {mat4} out mat4 receiving operation result * @param {Number} rad the angle to rotate the matrix by * @returns {mat4} out */ function fromZRotation(out, rad) { var s = Math.sin(rad); var c = Math.cos(rad); // Perform axis-specific matrix multiplication out[0] = c; out[1] = s; out[2] = 0; out[3] = 0; out[4] = -s; out[5] = c; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = 1; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; } /** * Creates a matrix from a quaternion rotation and vector translation * This is equivalent to (but much faster than): * * mat4.identity(dest); * mat4.translate(dest, vec); * let quatMat = mat4.create(); * quat4.toMat4(quat, quatMat); * mat4.multiply(dest, quatMat); * * @param {mat4} out mat4 receiving operation result * @param {quat4} q Rotation quaternion * @param {ReadonlyVec3} v Translation vector * @returns {mat4} out */ function fromRotationTranslation(out, q, v) { // Quaternion math var x = q[0], y = q[1], z = q[2], w = q[3]; var x2 = x + x; var y2 = y + y; var z2 = z + z; var xx = x * x2; var xy = x * y2; var xz = x * z2; var yy = y * y2; var yz = y * z2; var zz = z * z2; var wx = w * x2; var wy = w * y2; var wz = w * z2; out[0] = 1 - (yy + zz); out[1] = xy + wz; out[2] = xz - wy; out[3] = 0; out[4] = xy - wz; out[5] = 1 - (xx + zz); out[6] = yz + wx; out[7] = 0; out[8] = xz + wy; out[9] = yz - wx; out[10] = 1 - (xx + yy); out[11] = 0; out[12] = v[0]; out[13] = v[1]; out[14] = v[2]; out[15] = 1; return out; } /** * Creates a new mat4 from a dual quat. * * @param {mat4} out Matrix * @param {ReadonlyQuat2} a Dual Quaternion * @returns {mat4} mat4 receiving operation result */ function fromQuat2(out, a) { var translation = new ARRAY_TYPE(3); var bx = -a[0], by = -a[1], bz = -a[2], bw = a[3], ax = a[4], ay = a[5], az = a[6], aw = a[7]; var magnitude = bx * bx + by * by + bz * bz + bw * bw; //Only scale if it makes sense if (magnitude > 0) { translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2 / magnitude; translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2 / magnitude; translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2 / magnitude; } else { translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2; translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2; translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2; } fromRotationTranslation(out, a, translation); return out; } /** * Returns the translation vector component of a transformation * matrix. If a matrix is built with fromRotationTranslation, * the returned vector will be the same as the translation vector * originally supplied. * @param {vec3} out Vector to receive translation component * @param {ReadonlyMat4} mat Matrix to be decomposed (input) * @return {vec3} out */ function getTranslation(out, mat) { out[0] = mat[12]; out[1] = mat[13]; out[2] = mat[14]; return out; } /** * Returns the scaling factor component of a transformation * matrix. If a matrix is built with fromRotationTranslationScale * with a normalized Quaternion paramter, the returned vector will be * the same as the scaling vector * originally supplied. * @param {vec3} out Vector to receive scaling factor component * @param {ReadonlyMat4} mat Matrix to be decomposed (input) * @return {vec3} out */ function getScaling(out, mat) { var m11 = mat[0]; var m12 = mat[1]; var m13 = mat[2]; var m21 = mat[4]; var m22 = mat[5]; var m23 = mat[6]; var m31 = mat[8]; var m32 = mat[9]; var m33 = mat[10]; out[0] = Math.hypot(m11, m12, m13); out[1] = Math.hypot(m21, m22, m23); out[2] = Math.hypot(m31, m32, m33); return out; } /** * Returns a quaternion representing the rotational component * of a transformation matrix. If a matrix is built with * fromRotationTranslation, the returned quaternion will be the * same as the quaternion originally supplied. * @param {quat} out Quaternion to receive the rotation component * @param {ReadonlyMat4} mat Matrix to be decomposed (input) * @return {quat} out */ function getRotation(out, mat) { var scaling = new ARRAY_TYPE(3); getScaling(scaling, mat); var is1 = 1 / scaling[0]; var is2 = 1 / scaling[1]; var is3 = 1 / scaling[2]; var sm11 = mat[0] * is1; var sm12 = mat[1] * is2; var sm13 = mat[2] * is3; var sm21 = mat[4] * is1; var sm22 = mat[5] * is2; var sm23 = mat[6] * is3; var sm31 = mat[8] * is1; var sm32 = mat[9] * is2; var sm33 = mat[10] * is3; var trace = sm11 + sm22 + sm33; var S = 0; if (trace > 0) { S = Math.sqrt(trace + 1.0) * 2; out[3] = 0.25 * S; out[0] = (sm23 - sm32) / S; out[1] = (sm31 - sm13) / S; out[2] = (sm12 - sm21) / S; } else if (sm11 > sm22 && sm11 > sm33) { S = Math.sqrt(1.0 + sm11 - sm22 - sm33) * 2; out[3] = (sm23 - sm32) / S; out[0] = 0.25 * S; out[1] = (sm12 + sm21) / S; out[2] = (sm31 + sm13) / S; } else if (sm22 > sm33) { S = Math.sqrt(1.0 + sm22 - sm11 - sm33) * 2; out[3] = (sm31 - sm13) / S; out[0] = (sm12 + sm21) / S; out[1] = 0.25 * S; out[2] = (sm23 + sm32) / S; } else { S = Math.sqrt(1.0 + sm33 - sm11 - sm22) * 2; out[3] = (sm12 - sm21) / S; out[0] = (sm31 + sm13) / S; out[1] = (sm23 + sm32) / S; out[2] = 0.25 * S; } return out; } /** * Creates a matrix from a quaternion rotation, vector translation and vector scale * This is equivalent to (but much faster than): * * mat4.identity(dest); * mat4.translate(dest, vec); * let quatMat = mat4.create(); * quat4.toMat4(quat, quatMat); * mat4.multiply(dest, quatMat); * mat4.scale(dest, scale) * * @param {mat4} out mat4 receiving operation result * @param {quat4} q Rotation quaternion * @param {ReadonlyVec3} v Translation vector * @param {ReadonlyVec3} s Scaling vector * @returns {mat4} out */ function fromRotationTranslationScale(out, q, v, s) { // Quaternion math var x = q[0], y = q[1], z = q[2], w = q[3]; var x2 = x + x; var y2 = y + y; var z2 = z + z; var xx = x * x2; var xy = x * y2; var xz = x * z2; var yy = y * y2; var yz = y * z2; var zz = z * z2; var wx = w * x2; var wy = w * y2; var wz = w * z2; var sx = s[0]; var sy = s[1]; var sz = s[2]; out[0] = (1 - (yy + zz)) * sx; out[1] = (xy + wz) * sx; out[2] = (xz - wy) * sx; out[3] = 0; out[4] = (xy - wz) * sy; out[5] = (1 - (xx + zz)) * sy; out[6] = (yz + wx) * sy; out[7] = 0; out[8] = (xz + wy) * sz; out[9] = (yz - wx) * sz; out[10] = (1 - (xx + yy)) * sz; out[11] = 0; out[12] = v[0]; out[13] = v[1]; out[14] = v[2]; out[15] = 1; return out; } /** * Creates a matrix from a quaternion rotation, vector translation and vector scale, rotating and scaling around the given origin * This is equivalent to (but much faster than): * * mat4.identity(dest); * mat4.translate(dest, vec); * mat4.translate(dest, origin); * let quatMat = mat4.create(); * quat4.toMat4(quat, quatMat); * mat4.multiply(dest, quatMat); * mat4.scale(dest, scale) * mat4.translate(dest, negativeOrigin); * * @param {mat4} out mat4 receiving operation result * @param {quat4} q Rotation quaternion * @param {ReadonlyVec3} v Translation vector * @param {ReadonlyVec3} s Scaling vector * @param {ReadonlyVec3} o The origin vector around which to scale and rotate * @returns {mat4} out */ function fromRotationTranslationScaleOrigin(out, q, v, s, o) { // Quaternion math var x = q[0], y = q[1], z = q[2], w = q[3]; var x2 = x + x; var y2 = y + y; var z2 = z + z; var xx = x * x2; var xy = x * y2; var xz = x * z2; var yy = y * y2; var yz = y * z2; var zz = z * z2; var wx = w * x2; var wy = w * y2; var wz = w * z2; var sx = s[0]; var sy = s[1]; var sz = s[2]; var ox = o[0]; var oy = o[1]; var oz = o[2]; var out0 = (1 - (yy + zz)) * sx; var out1 = (xy + wz) * sx; var out2 = (xz - wy) * sx; var out4 = (xy - wz) * sy; var out5 = (1 - (xx + zz)) * sy; var out6 = (yz + wx) * sy; var out8 = (xz + wy) * sz; var out9 = (yz - wx) * sz; var out10 = (1 - (xx + yy)) * sz; out[0] = out0; out[1] = out1; out[2] = out2; out[3] = 0; out[4] = out4; out[5] = out5; out[6] = out6; out[7] = 0; out[8] = out8; out[9] = out9; out[10] = out10; out[11] = 0; out[12] = v[0] + ox - (out0 * ox + out4 * oy + out8 * oz); out[13] = v[1] + oy - (out1 * ox + out5 * oy + out9 * oz); out[14] = v[2] + oz - (out2 * ox + out6 * oy + out10 * oz); out[15] = 1; return out; } /** * Calculates a 4x4 matrix from the given quaternion * * @param {mat4} out mat4 receiving operation result * @param {ReadonlyQuat} q Quaternion to create matrix from * * @returns {mat4} out */ function fromQuat(out, q) { var x = q[0], y = q[1], z = q[2], w = q[3]; var x2 = x + x; var y2 = y + y; var z2 = z + z; var xx = x * x2; var yx = y * x2; var yy = y * y2; var zx = z * x2; var zy = z * y2; var zz = z * z2; var wx = w * x2; var wy = w * y2; var wz = w * z2; out[0] = 1 - yy - zz; out[1] = yx + wz; out[2] = zx - wy; out[3] = 0; out[4] = yx - wz; out[5] = 1 - xx - zz; out[6] = zy + wx; out[7] = 0; out[8] = zx + wy; out[9] = zy - wx; out[10] = 1 - xx - yy; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; } /** * Generates a frustum matrix with the given bounds * * @param {mat4} out mat4 frustum matrix will be written into * @param {Number} left Left bound of the frustum * @param {Number} right Right bound of the frustum * @param {Number} bottom Bottom bound of the frustum * @param {Number} top Top bound of the frustum * @param {Number} near Near bound of the frustum * @param {Number} far Far bound of the frustum * @returns {mat4} out */ function frustum(out, left, right, bottom, top, near, far) { var rl = 1 / (right - left); var tb = 1 / (top - bottom); var nf = 1 / (near - far); out[0] = near * 2 * rl; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = near * 2 * tb; out[6] = 0; out[7] = 0; out[8] = (right + left) * rl; out[9] = (top + bottom) * tb; out[10] = (far + near) * nf; out[11] = -1; out[12] = 0; out[13] = 0; out[14] = far * near * 2 * nf; out[15] = 0; return out; } /** * Generates a perspective projection matrix with the given bounds. * The near/far clip planes correspond to a normalized device coordinate Z range of [-1, 1], * which matches WebGL/OpenGL's clip volume. * Passing null/undefined/no value for far will generate infinite projection matrix. * * @param {mat4} out mat4 frustum matrix will be written into * @param {number} fovy Vertical field of view in radians * @param {number} aspect Aspect ratio. typically viewport width/height * @param {number} near Near bound of the frustum * @param {number} far Far bound of the frustum, can be null or Infinity * @returns {mat4} out */ function perspectiveNO(out, fovy, aspect, near, far) { var f = 1.0 / Math.tan(fovy / 2), nf; out[0] = f / aspect; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = f; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[11] = -1; out[12] = 0; out[13] = 0; out[15] = 0; if (far != null && far !== Infinity) { nf = 1 / (near - far); out[10] = (far + near) * nf; out[14] = 2 * far * near * nf; } else { out[10] = -1; out[14] = -2 * near; } return out; } /** * Alias for {@link mat4.perspectiveNO} * @function */ var perspective = perspectiveNO; /** * Generates a perspective projection matrix suitable for WebGPU with the given bounds. * The near/far clip planes correspond to a normalized device coordinate Z range of [0, 1], * which matches WebGPU/Vulkan/DirectX/Metal's clip volume. * Passing null/undefined/no value for far will generate infinite projection matrix. * * @param {mat4} out mat4 frustum matrix will be written into * @param {number} fovy Vertical field of view in radians * @param {number} aspect Aspect ratio. typically viewport width/height * @param {number} near Near bound of the frustum * @param {number} far Far bound of the frustum, can be null or Infinity * @returns {mat4} out */ function perspectiveZO(out, fovy, aspect, near, far) { var f = 1.0 / Math.tan(fovy / 2), nf; out[0] = f / aspect; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = f; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[11] = -1; out[12] = 0; out[13] = 0; out[15] = 0; if (far != null && far !== Infinity) { nf = 1 / (near - far); out[10] = far * nf; out[14] = far * near * nf; } else { out[10] = -1; out[14] = -near; } return out; } /** * Generates a perspective projection matrix with the given field of view. * This is primarily useful for generating projection matrices to be used * with the still experiemental WebVR API. * * @param {mat4} out mat4 frustum matrix will be written into * @param {Object} fov Object containing the following values: upDegrees, downDegrees, leftDegrees, rightDegrees * @param {number} near Near bound of the frustum * @param {number} far Far bound of the frustum * @returns {mat4} out */ function perspectiveFromFieldOfView(out, fov, near, far) { var upTan = Math.tan(fov.upDegrees * Math.PI / 180.0); var downTan = Math.tan(fov.downDegrees * Math.PI / 180.0); var leftTan = Math.tan(fov.leftDegrees * Math.PI / 180.0); var rightTan = Math.tan(fov.rightDegrees * Math.PI / 180.0); var xScale = 2.0 / (leftTan + rightTan); var yScale = 2.0 / (upTan + downTan); out[0] = xScale; out[1] = 0.0; out[2] = 0.0; out[3] = 0.0; out[4] = 0.0; out[5] = yScale; out[6] = 0.0; out[7] = 0.0; out[8] = -((leftTan - rightTan) * xScale * 0.5); out[9] = (upTan - downTan) * yScale * 0.5; out[10] = far / (near - far); out[11] = -1.0; out[12] = 0.0; out[13] = 0.0; out[14] = far * near / (near - far); out[15] = 0.0; return out; } /** * Generates a orthogonal projection matrix with the given bounds. * The near/far clip planes correspond to a normalized device coordinate Z range of [-1, 1], * which matches WebGL/OpenGL's clip volume. * * @param {mat4} out mat4 frustum matrix will be written into * @param {number} left Left bound of the frustum * @param {number} right Right bound of the frustum * @param {number} bottom Bottom bound of the frustum * @param {number} top Top bound of the frustum * @param {number} near Near bound of the frustum * @param {number} far Far bound of the frustum * @returns {mat4} out */ function orthoNO(out, left, right, bottom, top, near, far) { var lr = 1 / (left - right); var bt = 1 / (bottom - top); var nf = 1 / (near - far); out[0] = -2 * lr; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = -2 * bt; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = 2 * nf; out[11] = 0; out[12] = (left + right) * lr; out[13] = (top + bottom) * bt; out[14] = (far + near) * nf; out[15] = 1; return out; } /** * Alias for {@link mat4.orthoNO} * @function */ var ortho = orthoNO; /** * Generates a orthogonal projection matrix with the given bounds. * The near/far clip planes correspond to a normalized device coordinate Z range of [0, 1], * which matches WebGPU/Vulkan/DirectX/Metal's clip volume. * * @param {mat4} out mat4 frustum matrix will be written into * @param {number} left Left bound of the frustum * @param {number} right Right bound of the frustum * @param {number} bottom Bottom bound of the frustum * @param {number} top Top bound of the frustum * @param {number} near Near bound of the frustum * @param {number} far Far bound of the frustum * @returns {mat4} out */ function orthoZO(out, left, right, bottom, top, near, far) { var lr = 1 / (left - right); var bt = 1 / (bottom - top); var nf = 1 / (near - far); out[0] = -2 * lr; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = -2 * bt; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = nf; out[11] = 0; out[12] = (left + right) * lr; out[13] = (top + bottom) * bt; out[14] = near * nf; out[15] = 1; return out; } /** * Generates a look-at matrix with the given eye position, focal point, and up axis. * If you want a matrix that actually makes an object look at another object, you should use targetTo instead. * * @param {mat4} out mat4 frustum matrix will be written into * @param {ReadonlyVec3} eye Position of the viewer * @param {ReadonlyVec3} center Point the viewer is looking at * @param {ReadonlyVec3} up vec3 pointing up * @returns {mat4} out */ function lookAt(out, eye, center, up) { var x0, x1, x2, y0, y1, y2, z0, z1, z2, len; var eyex = eye[0]; var eyey = eye[1]; var eyez = eye[2]; var upx = up[0]; var upy = up[1]; var upz = up[2]; var centerx = center[0]; var centery = center[1]; var centerz = center[2]; if (Math.abs(eyex - centerx) < EPSILON && Math.abs(eyey - centery) < EPSILON && Math.abs(eyez - centerz) < EPSILON) { return identity(out); } z0 = eyex - centerx; z1 = eyey - centery; z2 = eyez - centerz; len = 1 / Math.hypot(z0, z1, z2); z0 *= len; z1 *= len; z2 *= len; x0 = upy * z2 - upz * z1; x1 = upz * z0 - upx * z2; x2 = upx * z1 - upy * z0; len = Math.hypot(x0, x1, x2); if (!len) { x0 = 0; x1 = 0; x2 = 0; } else { len = 1 / len; x0 *= len; x1 *= len; x2 *= len; } y0 = z1 * x2 - z2 * x1; y1 = z2 * x0 - z0 * x2; y2 = z0 * x1 - z1 * x0; len = Math.hypot(y0, y1, y2); if (!len) { y0 = 0; y1 = 0; y2 = 0; } else { len = 1 / len; y0 *= len; y1 *= len; y2 *= len; } out[0] = x0; out[1] = y0; out[2] = z0; out[3] = 0; out[4] = x1; out[5] = y1; out[6] = z1; out[7] = 0; out[8] = x2; out[9] = y2; out[10] = z2; out[11] = 0; out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez); out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez); out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez); out[15] = 1; return out; } /** * Generates a matrix that makes something look at something else. * * @param {mat4} out mat4 frustum matrix will be written into * @param {ReadonlyVec3} eye Position of the viewer * @param {ReadonlyVec3} center Point the viewer is looking at * @param {ReadonlyVec3} up vec3 pointing up * @returns {mat4} out */ function targetTo(out, eye, target, up) { var eyex = eye[0], eyey = eye[1], eyez = eye[2], upx = up[0], upy = up[1], upz = up[2]; var z0 = eyex - target[0], z1 = eyey - target[1], z2 = eyez - target[2]; var len = z0 * z0 + z1 * z1 + z2 * z2; if (len > 0) { len = 1 / Math.sqrt(len); z0 *= len; z1 *= len; z2 *= len; } var x0 = upy * z2 - upz * z1, x1 = upz * z0 - upx * z2, x2 = upx * z1 - upy * z0; len = x0 * x0 + x1 * x1 + x2 * x2; if (len > 0) { len = 1 / Math.sqrt(len); x0 *= len; x1 *= len; x2 *= len; } out[0] = x0; out[1] = x1; out[2] = x2; out[3] = 0; out[4] = z1 * x2 - z2 * x1; out[5] = z2 * x0 - z0 * x2; out[6] = z0 * x1 - z1 * x0; out[7] = 0; out[8] = z0; out[9] = z1; out[10] = z2; out[11] = 0; out[12] = eyex; out[13] = eyey; out[14] = eyez; out[15] = 1; return out; } /** * Returns a string representation of a mat4 * * @param {ReadonlyMat4} a matrix to represent as a string * @returns {String} string representation of the matrix */ function str(a) { return "mat4(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + ", " + a[9] + ", " + a[10] + ", " + a[11] + ", " + a[12] + ", " + a[13] + ", " + a[14] + ", " + a[15] + ")"; } /** * Returns Frobenius norm of a mat4 * * @param {ReadonlyMat4} a the matrix to calculate Frobenius norm of * @returns {Number} Frobenius norm */ function frob(a) { return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); } /** * Adds two mat4's * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the first operand * @param {ReadonlyMat4} b the second operand * @returns {mat4} out */ function add(out, a, b) { out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; out[2] = a[2] + b[2]; out[3] = a[3] + b[3]; out[4] = a[4] + b[4]; out[5] = a[5] + b[5]; out[6] = a[6] + b[6]; out[7] = a[7] + b[7]; out[8] = a[8] + b[8]; out[9] = a[9] + b[9]; out[10] = a[10] + b[10]; out[11] = a[11] + b[11]; out[12] = a[12] + b[12]; out[13] = a[13] + b[13]; out[14] = a[14] + b[14]; out[15] = a[15] + b[15]; return out; } /** * Subtracts matrix b from matrix a * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the first operand * @param {ReadonlyMat4} b the second operand * @returns {mat4} out */ function subtract(out, a, b) { out[0] = a[0] - b[0]; out[1] = a[1] - b[1]; out[2] = a[2] - b[2]; out[3] = a[3] - b[3]; out[4] = a[4] - b[4]; out[5] = a[5] - b[5]; out[6] = a[6] - b[6]; out[7] = a[7] - b[7]; out[8] = a[8] - b[8]; out[9] = a[9] - b[9]; out[10] = a[10] - b[10]; out[11] = a[11] - b[11]; out[12] = a[12] - b[12]; out[13] = a[13] - b[13]; out[14] = a[14] - b[14]; out[15] = a[15] - b[15]; return out; } /** * Multiply each element of the matrix by a scalar. * * @param {mat4} out the receiving matrix * @param {ReadonlyMat4} a the matrix to scale * @param {Number} b amount to scale the matrix's elements by * @returns {mat4} out */ function multiplyScalar(out, a, b) { out[0] = a[0] * b; out[1] = a[1] * b; out[2] = a[2] * b; out[3] = a[3] * b; out[4] = a[4] * b; out[5] = a[5] * b; out[6] = a[6] * b; out[7] = a[7] * b; out[8] = a[8] * b; out[9] = a[9] * b; out[10] = a[10] * b; out[11] = a[11] * b; out[12] = a[12] * b; out[13] = a[13] * b; out[14] = a[14] * b; out[15] = a[15] * b; return out; } /** * Adds two mat4's after multiplying each element of the second operand by a scalar value. * * @param {mat4} out the receiving vector * @param {ReadonlyMat4} a the first operand * @param {ReadonlyMat4} b the second operand * @param {Number} scale the amount to scale b's elements by before adding * @returns {mat4} out */ function multiplyScalarAndAdd(out, a, b, scale) { out[0] = a[0] + b[0] * scale; out[1] = a[1] + b[1] * scale; out[2] = a[2] + b[2] * scale; out[3] = a[3] + b[3] * scale; out[4] = a[4] + b[4] * scale; out[5] = a[5] + b[5] * scale; out[6] = a[6] + b[6] * scale; out[7] = a[7] + b[7] * scale; out[8] = a[8] + b[8] * scale; out[9] = a[9] + b[9] * scale; out[10] = a[10] + b[10] * scale; out[11] = a[11] + b[11] * scale; out[12] = a[12] + b[12] * scale; out[13] = a[13] + b[13] * scale; out[14] = a[14] + b[14] * scale; out[15] = a[15] + b[15] * scale; return out; } /** * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) * * @param {ReadonlyMat4} a The first matrix. * @param {ReadonlyMat4} b The second matrix. * @returns {Boolean} True if the matrices are equal, false otherwise. */ function exactEquals(a, b) { return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8] && a[9] === b[9] && a[10] === b[10] && a[11] === b[11] && a[12] === b[12] && a[13] === b[13] && a[14] === b[14] && a[15] === b[15]; } /** * Returns whether or not the matrices have approximately the same elements in the same position. * * @param {ReadonlyMat4} a The first matrix. * @param {ReadonlyMat4} b The second matrix. * @returns {Boolean} True if the matrices are equal, false otherwise. */ function equals(a, b) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3]; var a4 = a[4], a5 = a[5], a6 = a[6], a7 = a[7]; var a8 = a[8], a9 = a[9], a10 = a[10], a11 = a[11]; var a12 = a[12], a13 = a[13], a14 = a[14], a15 = a[15]; var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3]; var b4 = b[4], b5 = b[5], b6 = b[6], b7 = b[7]; var b8 = b[8], b9 = b[9], b10 = b[10], b11 = b[11]; var b12 = b[12], b13 = b[13], b14 = b[14], b15 = b[15]; return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= EPSILON * Math.max(1.0, Math.abs(a8), Math.abs(b8)) && Math.abs(a9 - b9) <= EPSILON * Math.max(1.0, Math.abs(a9), Math.abs(b9)) && Math.abs(a10 - b10) <= EPSILON * Math.max(1.0, Math.abs(a10), Math.abs(b10)) && Math.abs(a11 - b11) <= EPSILON * Math.max(1.0, Math.abs(a11), Math.abs(b11)) && Math.abs(a12 - b12) <= EPSILON * Math.max(1.0, Math.abs(a12), Math.abs(b12)) && Math.abs(a13 - b13) <= EPSILON * Math.max(1.0, Math.abs(a13), Math.abs(b13)) && Math.abs(a14 - b14) <= EPSILON * Math.max(1.0, Math.abs(a14), Math.abs(b14)) && Math.abs(a15 - b15) <= EPSILON * Math.max(1.0, Math.abs(a15), Math.abs(b15)); } /** * Alias for {@link mat4.multiply} * @function */ var mul = multiply; /** * Alias for {@link mat4.subtract} * @function */ var sub = subtract; var mat4 = /*#__PURE__*/Object.freeze({ __proto__: null, create: create$1, clone: clone, copy: copy, fromValues: fromValues$1, set: set, identity: identity, transpose: transpose, invert: invert, adjoint: adjoint, determinant: determinant, multiply: multiply, translate: translate, scale: scale, rotate: rotate, rotateX: rotateX, rotateY: rotateY, rotateZ: rotateZ, fromTranslation: fromTranslation, fromScaling: fromScaling, fromRotation: fromRotation, fromXRotation: fromXRotation, fromYRotation: fromYRotation, fromZRotation: fromZRotation, fromRotationTranslation: fromRotationTranslation, fromQuat2: fromQuat2, getTranslation: getTranslation, getScaling: getScaling, getRotation: getRotation, fromRotationTranslationScale: fromRotationTranslationScale, fromRotationTranslationScaleOrigin: fromRotationTranslationScaleOrigin, fromQuat: fromQuat, frustum: frustum, perspectiveNO: perspectiveNO, perspective: perspective, perspectiveZO: perspectiveZO, perspectiveFromFieldOfView: perspectiveFromFieldOfView, orthoNO: orthoNO, ortho: ortho, orthoZO: orthoZO, lookAt: lookAt, targetTo: targetTo, str: str, frob: frob, add: add, subtract: subtract, multiplyScalar: multiplyScalar, multiplyScalarAndAdd: multiplyScalarAndAdd, exactEquals: exactEquals, equals: equals, mul: mul, sub: sub }); /** * 3 Dimensional Vector * @module vec3 */ /** * Creates a new, empty vec3 * * @returns {vec3} a new 3D vector */ function create$2() { var out = new ARRAY_TYPE(3); if (ARRAY_TYPE != Float32Array) { out[0] = 0; out[1] = 0; out[2] = 0; } return out; } /** * Creates a new vec3 initialized with values from an existing vector * * @param {ReadonlyVec3} a vector to clone * @returns {vec3} a new 3D vector */ function clone$1(a) { var out = new ARRAY_TYPE(3); out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; return out; } /** * Calculates the length of a vec3 * * @param {ReadonlyVec3} a vector to calculate length of * @returns {Number} length of a */ function length(a) { var x = a[0]; var y = a[1]; var z = a[2]; return Math.hypot(x, y, z); } /** * Creates a new vec3 initialized with the given values * * @param {Number} x X component * @param {Number} y Y component * @param {Number} z Z component * @returns {vec3} a new 3D vector */ function fromValues$2(x, y, z) { var out = new ARRAY_TYPE(3); out[0] = x; out[1] = y; out[2] = z; return out; } /** * Copy the values from one vec3 to another * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the source vector * @returns {vec3} out */ function copy$1(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; return out; } /** * Set the components of a vec3 to the given values * * @param {vec3} out the receiving vector * @param {Number} x X component * @param {Number} y Y component * @param {Number} z Z component * @returns {vec3} out */ function set$1(out, x, y, z) { out[0] = x; out[1] = y; out[2] = z; return out; } /** * Adds two vec3's * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the first operand * @param {ReadonlyVec3} b the second operand * @returns {vec3} out */ function add$1(out, a, b) { out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; out[2] = a[2] + b[2]; return out; } /** * Subtracts vector b from vector a * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the first operand * @param {ReadonlyVec3} b the second operand * @returns {vec3} out */ function subtract$1(out, a, b) { out[0] = a[0] - b[0]; out[1] = a[1] - b[1]; out[2] = a[2] - b[2]; return out; } /** * Multiplies two vec3's * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the first operand * @param {ReadonlyVec3} b the second operand * @returns {vec3} out */ function multiply$1(out, a, b) { out[0] = a[0] * b[0]; out[1] = a[1] * b[1]; out[2] = a[2] * b[2]; return out; } /** * Scales a vec3 by a scalar number * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the vector to scale * @param {Number} b amount to scale the vector by * @returns {vec3} out */ function scale$1(out, a, b) { out[0] = a[0] * b; out[1] = a[1] * b; out[2] = a[2] * b; return out; } /** * Normalize a vec3 * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a vector to normalize * @returns {vec3} out */ function normalize(out, a) { var x = a[0]; var y = a[1]; var z = a[2]; var len = x * x + y * y + z * z; if (len > 0) { //TODO: evaluate use of glm_invsqrt here? len = 1 / Math.sqrt(len); } out[0] = a[0] * len; out[1] = a[1] * len; out[2] = a[2] * len; return out; } /** * Calculates the dot product of two vec3's * * @param {ReadonlyVec3} a the first operand * @param {ReadonlyVec3} b the second operand * @returns {Number} dot product of a and b */ function dot(a, b) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; } /** * Computes the cross product of two vec3's * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the first operand * @param {ReadonlyVec3} b the second operand * @returns {vec3} out */ function cross(out, a, b) { var ax = a[0], ay = a[1], az = a[2]; var bx = b[0], by = b[1], bz = b[2]; out[0] = ay * bz - az * by; out[1] = az * bx - ax * bz; out[2] = ax * by - ay * bx; return out; } /** * Performs a linear interpolation between two vec3's * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the first operand * @param {ReadonlyVec3} b the second operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {vec3} out */ function lerp(out, a, b, t) { var ax = a[0]; var ay = a[1]; var az = a[2]; out[0] = ax + t * (b[0] - ax); out[1] = ay + t * (b[1] - ay); out[2] = az + t * (b[2] - az); return out; } /** * Transforms the vec3 with a mat4. * 4th vector component is implicitly '1' * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the vector to transform * @param {ReadonlyMat4} m matrix to transform with * @returns {vec3} out */ function transformMat4(out, a, m) { var x = a[0], y = a[1], z = a[2]; var w = m[3] * x + m[7] * y + m[11] * z + m[15]; w = w || 1.0; out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w; out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w; out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w; return out; } /** * Transforms the vec3 with a mat3. * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the vector to transform * @param {ReadonlyMat3} m the 3x3 matrix to transform with * @returns {vec3} out */ function transformMat3(out, a, m) { var x = a[0], y = a[1], z = a[2]; out[0] = x * m[0] + y * m[3] + z * m[6]; out[1] = x * m[1] + y * m[4] + z * m[7]; out[2] = x * m[2] + y * m[5] + z * m[8]; return out; } /** * Transforms the vec3 with a quat * Can also be used for dual quaternions. (Multiply it with the real part) * * @param {vec3} out the receiving vector * @param {ReadonlyVec3} a the vector to transform * @param {ReadonlyQuat} q quaternion to transform with * @returns {vec3} out */ function transformQuat(out, a, q) { // benchmarks: https://jsperf.com/quaternion-transform-vec3-implementations-fixed var qx = q[0], qy = q[1], qz = q[2], qw = q[3]; var x = a[0], y = a[1], z = a[2]; // var qvec = [qx, qy, qz]; // var uv = vec3.cross([], qvec, a); var uvx = qy * z - qz * y, uvy = qz * x - qx * z, uvz = qx * y - qy * x; // var uuv = vec3.cross([], qvec, uv); var uuvx = qy * uvz - qz * uvy, uuvy = qz * uvx - qx * uvz, uuvz = qx * uvy - qy * uvx; // vec3.scale(uv, uv, 2 * w); var w2 = qw * 2; uvx *= w2; uvy *= w2; uvz *= w2; // vec3.scale(uuv, uuv, 2); uuvx *= 2; uuvy *= 2; uuvz *= 2; // return vec3.add(out, a, vec3.add(out, uv, uuv)); out[0] = x + uvx + uuvx; out[1] = y + uvy + uuvy; out[2] = z + uvz + uuvz; return out; } /** * Returns whether or not the vectors have approximately the same elements in the same position. * * @param {ReadonlyVec3} a The first vector. * @param {ReadonlyVec3} b The second vector. * @returns {Boolean} True if the vectors are equal, false otherwise. */ function equals$1(a, b) { var a0 = a[0], a1 = a[1], a2 = a[2]; var b0 = b[0], b1 = b[1], b2 = b[2]; return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)); } /** * Alias for {@link vec3.length} * @function */ var len = length; /** * Perform some operation over an array of vec3s. * * @param {Array} a the array of vectors to iterate over * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed * @param {Number} offset Number of elements to skip at the beginning of the array * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array * @param {Function} fn Function to call for each vector in the array * @param {Object} [arg] additional argument to pass to fn * @returns {Array} a * @function */ var forEach = function () { var vec = create$2(); return function (a, stride, offset, count, fn, arg) { var i, l; if (!stride) { stride = 3; } if (!offset) { offset = 0; } if (count) { l = Math.min(count * stride + offset, a.length); } else { l = a.length; } for (i = offset; i < l; i += stride) { vec[0] = a[i]; vec[1] = a[i + 1]; vec[2] = a[i + 2]; fn(vec, vec, arg); a[i] = vec[0]; a[i + 1] = vec[1]; a[i + 2] = vec[2]; } return a; }; }(); /** * 4 Dimensional Vector * @module vec4 */ /** * Creates a new, empty vec4 * * @returns {vec4} a new 4D vector */ function create$3() { var out = new ARRAY_TYPE(4); if (ARRAY_TYPE != Float32Array) { out[0] = 0; out[1] = 0; out[2] = 0; out[3] = 0; } return out; } /** * Creates a new vec4 initialized with the given values * * @param {Number} x X component * @param {Number} y Y component * @param {Number} z Z component * @param {Number} w W component * @returns {vec4} a new 4D vector */ function fromValues$3(x, y, z, w) { var out = new ARRAY_TYPE(4); out[0] = x; out[1] = y; out[2] = z; out[3] = w; return out; } /** * Copy the values from one vec4 to another * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a the source vector * @returns {vec4} out */ function copy$2(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; return out; } /** * Normalize a vec4 * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a vector to normalize * @returns {vec4} out */ function normalize$1(out, a) { var x = a[0]; var y = a[1]; var z = a[2]; var w = a[3]; var len = x * x + y * y + z * z + w * w; if (len > 0) { len = 1 / Math.sqrt(len); } out[0] = x * len; out[1] = y * len; out[2] = z * len; out[3] = w * len; return out; } /** * Transforms the vec4 with a mat4. * * @param {vec4} out the receiving vector * @param {ReadonlyVec4} a the vector to transform * @param {ReadonlyMat4} m matrix to transform with * @returns {vec4} out */ function transformMat4$1(out, a, m) { var x = a[0], y = a[1], z = a[2], w = a[3]; out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w; out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w; out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w; out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w; return out; } /** * Perform some operation over an array of vec4s. * * @param {Array} a the array of vectors to iterate over * @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed * @param {Number} offset Number of elements to skip at the beginning of the array * @param {Number} count Number of vec4s to iterate over. If 0 iterates over entire array * @param {Function} fn Function to call for each vector in the array * @param {Object} [arg] additional argument to pass to fn * @returns {Array} a * @function */ var forEach$1 = function () { var vec = create$3(); return function (a, stride, offset, count, fn, arg) { var i, l; if (!stride) { stride = 4; } if (!offset) { offset = 0; } if (count) { l = Math.min(count * stride + offset, a.length); } else { l = a.length; } for (i = offset; i < l; i += stride) { vec[0] = a[i]; vec[1] = a[i + 1]; vec[2] = a[i + 2]; vec[3] = a[i + 3]; fn(vec, vec, arg); a[i] = vec[0]; a[i + 1] = vec[1]; a[i + 2] = vec[2]; a[i + 3] = vec[3]; } return a; }; }(); /** * Quaternion * @module quat */ /** * Creates a new identity quat * * @returns {quat} a new quaternion */ function create$4() { var out = new ARRAY_TYPE(4); if (ARRAY_TYPE != Float32Array) { out[0] = 0; out[1] = 0; out[2] = 0; } out[3] = 1; return out; } /** * Sets a quat from the given angle and rotation axis, * then returns it. * * @param {quat} out the receiving quaternion * @param {ReadonlyVec3} axis the axis around which to rotate * @param {Number} rad the angle in radians * @returns {quat} out **/ function setAxisAngle(out, axis, rad) { rad = rad * 0.5; var s = Math.sin(rad); out[0] = s * axis[0]; out[1] = s * axis[1]; out[2] = s * axis[2]; out[3] = Math.cos(rad); return out; } /** * Multiplies two quat's * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a the first operand * @param {ReadonlyQuat} b the second operand * @returns {quat} out */ function multiply$2(out, a, b) { var ax = a[0], ay = a[1], az = a[2], aw = a[3]; var bx = b[0], by = b[1], bz = b[2], bw = b[3]; out[0] = ax * bw + aw * bx + ay * bz - az * by; out[1] = ay * bw + aw * by + az * bx - ax * bz; out[2] = az * bw + aw * bz + ax * by - ay * bx; out[3] = aw * bw - ax * bx - ay * by - az * bz; return out; } /** * Performs a spherical linear interpolation between two quat * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a the first operand * @param {ReadonlyQuat} b the second operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {quat} out */ function slerp(out, a, b, t) { // benchmarks: // http://jsperf.com/quaternion-slerp-implementations var ax = a[0], ay = a[1], az = a[2], aw = a[3]; var bx = b[0], by = b[1], bz = b[2], bw = b[3]; var omega, cosom, sinom, scale0, scale1; // calc cosine cosom = ax * bx + ay * by + az * bz + aw * bw; // adjust signs (if necessary) if (cosom < 0.0) { cosom = -cosom; bx = -bx; by = -by; bz = -bz; bw = -bw; } // calculate coefficients if (1.0 - cosom > EPSILON) { // standard case (slerp) omega = Math.acos(cosom); sinom = Math.sin(omega); scale0 = Math.sin((1.0 - t) * omega) / sinom; scale1 = Math.sin(t * omega) / sinom; } else { // "from" and "to" quaternions are very close // ... so we can do a linear interpolation scale0 = 1.0 - t; scale1 = t; } // calculate final values out[0] = scale0 * ax + scale1 * bx; out[1] = scale0 * ay + scale1 * by; out[2] = scale0 * az + scale1 * bz; out[3] = scale0 * aw + scale1 * bw; return out; } /** * Calculates the inverse of a quat * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a quat to calculate inverse of * @returns {quat} out */ function invert$1(out, a) { var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3]; var dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3; var invDot = dot ? 1.0 / dot : 0; // TODO: Would be faster to return [0,0,0,0] immediately if dot == 0 out[0] = -a0 * invDot; out[1] = -a1 * invDot; out[2] = -a2 * invDot; out[3] = a3 * invDot; return out; } /** * Creates a quaternion from the given 3x3 rotation matrix. * * NOTE: The resultant quaternion is not normalized, so you should be sure * to renormalize the quaternion yourself where necessary. * * @param {quat} out the receiving quaternion * @param {ReadonlyMat3} m rotation matrix * @returns {quat} out * @function */ function fromMat3(out, m) { // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes // article "Quaternion Calculus and Fast Animation". var fTrace = m[0] + m[4] + m[8]; var fRoot; if (fTrace > 0.0) { // |w| > 1/2, may as well choose w > 1/2 fRoot = Math.sqrt(fTrace + 1.0); // 2w out[3] = 0.5 * fRoot; fRoot = 0.5 / fRoot; // 1/(4w) out[0] = (m[5] - m[7]) * fRoot; out[1] = (m[6] - m[2]) * fRoot; out[2] = (m[1] - m[3]) * fRoot; } else { // |w| <= 1/2 var i = 0; if (m[4] > m[0]) i = 1; if (m[8] > m[i * 3 + i]) i = 2; var j = (i + 1) % 3; var k = (i + 2) % 3; fRoot = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1.0); out[i] = 0.5 * fRoot; fRoot = 0.5 / fRoot; out[3] = (m[j * 3 + k] - m[k * 3 + j]) * fRoot; out[j] = (m[j * 3 + i] + m[i * 3 + j]) * fRoot; out[k] = (m[k * 3 + i] + m[i * 3 + k]) * fRoot; } return out; } /** * Creates a quaternion from the given euler angle x, y, z. * * @param {quat} out the receiving quaternion * @param {x} Angle to rotate around X axis in degrees. * @param {y} Angle to rotate around Y axis in degrees. * @param {z} Angle to rotate around Z axis in degrees. * @returns {quat} out * @function */ function fromEuler(out, x, y, z) { var halfToRad = 0.5 * Math.PI / 180.0; x *= halfToRad; y *= halfToRad; z *= halfToRad; var sx = Math.sin(x); var cx = Math.cos(x); var sy = Math.sin(y); var cy = Math.cos(y); var sz = Math.sin(z); var cz = Math.cos(z); out[0] = sx * cy * cz - cx * sy * sz; out[1] = cx * sy * cz + sx * cy * sz; out[2] = cx * cy * sz - sx * sy * cz; out[3] = cx * cy * cz + sx * sy * sz; return out; } /** * Creates a new quat initialized with the given values * * @param {Number} x X component * @param {Number} y Y component * @param {Number} z Z component * @param {Number} w W component * @returns {quat} a new quaternion * @function */ var fromValues$4 = fromValues$3; /** * Copy the values from one quat to another * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a the source quaternion * @returns {quat} out * @function */ var copy$3 = copy$2; /** * Alias for {@link quat.multiply} * @function */ var mul$1 = multiply$2; /** * Normalize a quat * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a quaternion to normalize * @returns {quat} out * @function */ var normalize$2 = normalize$1; /** * Sets a quaternion to represent the shortest rotation from one * vector to another. * * Both vectors are assumed to be unit length. * * @param {quat} out the receiving quaternion. * @param {ReadonlyVec3} a the initial vector * @param {ReadonlyVec3} b the destination vector * @returns {quat} out */ var rotationTo = function () { var tmpvec3 = create$2(); var xUnitVec3 = fromValues$2(1, 0, 0); var yUnitVec3 = fromValues$2(0, 1, 0); return function (out, a, b) { var dot$1 = dot(a, b); if (dot$1 < -0.999999) { cross(tmpvec3, xUnitVec3, a); if (len(tmpvec3) < 0.000001) cross(tmpvec3, yUnitVec3, a); normalize(tmpvec3, tmpvec3); setAxisAngle(out, tmpvec3, Math.PI); return out; } else if (dot$1 > 0.999999) { out[0] = 0; out[1] = 0; out[2] = 0; out[3] = 1; return out; } else { cross(tmpvec3, a, b); out[0] = tmpvec3[0]; out[1] = tmpvec3[1]; out[2] = tmpvec3[2]; out[3] = 1 + dot$1; return normalize$2(out, out); } }; }(); /** * Performs a spherical linear interpolation with two control points * * @param {quat} out the receiving quaternion * @param {ReadonlyQuat} a the first operand * @param {ReadonlyQuat} b the second operand * @param {ReadonlyQuat} c the third operand * @param {ReadonlyQuat} d the fourth operand * @param {Number} t interpolation amount, in the range [0-1], between the two inputs * @returns {quat} out */ var sqlerp = function () { var temp1 = create$4(); var temp2 = create$4(); return function (out, a, b, c, d, t) { slerp(temp1, a, d, t); slerp(temp2, b, c, t); slerp(out, temp1, temp2, 2 * t * (1 - t)); return out; }; }(); /** * Sets the specified quaternion with values corresponding to the given * axes. Each axis is a vec3 and is expected to be unit length and * perpendicular to all other specified axes. * * @param {ReadonlyVec3} view the vector representing the viewing direction * @param {ReadonlyVec3} right the vector representing the local "right" direction * @param {ReadonlyVec3} up the vector representing the local "up" direction * @returns {quat} out */ var setAxes = function () { var matr = create(); return function (out, view, right, up) { matr[0] = right[0]; matr[3] = right[1]; matr[6] = right[2]; matr[1] = up[0]; matr[4] = up[1]; matr[7] = up[2]; matr[2] = -view[0]; matr[5] = -view[1]; matr[8] = -view[2]; return normalize$2(out, fromMat3(out, matr)); }; }(); /** * 2 Dimensional Vector * @module vec2 */ /** * Creates a new, empty vec2 * * @returns {vec2} a new 2D vector */ function create$5() { var out = new ARRAY_TYPE(2); if (ARRAY_TYPE != Float32Array) { out[0] = 0; out[1] = 0; } return out; } /** * Creates a new vec2 initialized with the given values * * @param {Number} x X component * @param {Number} y Y component * @returns {vec2} a new 2D vector */ function fromValues$5(x, y) { var out = new ARRAY_TYPE(2); out[0] = x; out[1] = y; return out; } /** * Copy the values from one vec2 to another * * @param {vec2} out the receiving vector * @param {ReadonlyVec2} a the source vector * @returns {vec2} out */ function copy$4(out, a) { out[0] = a[0]; out[1] = a[1]; return out; } /** * Normalize a vec2 * * @param {vec2} out the receiving vector * @param {ReadonlyVec2} a vector to normalize * @returns {vec2} out */ function normalize$3(out, a) { var x = a[0], y = a[1]; var len = x * x + y * y; if (len > 0) { //TODO: evaluate use of glm_invsqrt here? len = 1 / Math.sqrt(len); } out[0] = a[0] * len; out[1] = a[1] * len; return out; } /** * Calculates the dot product of two vec2's * * @param {ReadonlyVec2} a the first operand * @param {ReadonlyVec2} b the second operand * @returns {Number} dot product of a and b */ function dot$1(a, b) { return a[0] * b[0] + a[1] * b[1]; } /** * Returns whether or not the vectors exactly have the same elements in the same position (when compared with ===) * * @param {ReadonlyVec2} a The first vector. * @param {ReadonlyVec2} b The second vector. * @returns {Boolean} True if the vectors are equal, false otherwise. */ function exactEquals$1(a, b) { return a[0] === b[0] && a[1] === b[1]; } /** * Perform some operation over an array of vec2s. * * @param {Array} a the array of vectors to iterate over * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed * @param {Number} offset Number of elements to skip at the beginning of the array * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array * @param {Function} fn Function to call for each vector in the array * @param {Object} [arg] additional argument to pass to fn * @returns {Array} a * @function */ var forEach$2 = function () { var vec = create$5(); return function (a, stride, offset, count, fn, arg) { var i, l; if (!stride) { stride = 2; } if (!offset) { offset = 0; } if (count) { l = Math.min(count * stride + offset, a.length); } else { l = a.length; } for (i = offset; i < l; i += stride) { vec[0] = a[i]; vec[1] = a[i + 1]; fn(vec, vec, arg); a[i] = vec[0]; a[i + 1] = vec[1]; } return a; }; }(); function clonePath(path) { return path.map(function (x) { return (Array.isArray(x) ? [].concat(x) : x); }); } /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var paramsParser = { x1: 0, y1: 0, x2: 0, y2: 0, x: 0, y: 0, qx: null, qy: null, }; function fixArc(pathArray, allPathCommands, i) { if (pathArray[i].length > 7) { pathArray[i].shift(); var pi = pathArray[i]; // const ni = i + 1; var ni = i; while (pi.length) { // if created multiple C:s, their original seg is saved allPathCommands[i] = 'A'; // @ts-ignore pathArray.splice((ni += 1), 0, ['C'].concat(pi.splice(0, 6))); } pathArray.splice(i, 1); } } var paramsCount = { a: 7, c: 6, h: 1, l: 2, m: 2, r: 4, q: 4, s: 4, t: 2, v: 1, z: 0, }; /** * Iterates an array to check if it's an actual `PathArray`. */ function isPathArray(path) { return (Array.isArray(path) && path.every(function (seg) { var lk = seg[0].toLowerCase(); return paramsCount[lk] === seg.length - 1 && 'achlmqstvz'.includes(lk); })); } /** * Iterates an array to check if it's a `PathArray` * with all absolute values. */ function isAbsoluteArray(path) { return (isPathArray(path) && // @ts-ignore -- `isPathArray` also checks if it's `Array` path.every(function (_a) { var x = _a[0]; return x === x.toUpperCase(); })); } /** * Iterates an array to check if it's a `PathArray` * with all segments are in non-shorthand notation * with absolute values. */ function isNormalizedArray(path) { return isAbsoluteArray(path) && path.every(function (_a) { var pc = _a[0]; return 'ACLMQZ'.includes(pc); }); } /** * Breaks the parsing of a pathString once a segment is finalized. */ function finalizeSegment(path) { var pathCommand = path.pathValue[path.segmentStart]; var LK = pathCommand.toLowerCase(); var data = path.data; while (data.length >= paramsCount[LK]) { // overloaded `moveTo` // https://github.com/rveciana/svg-path-properties/blob/master/src/parse.ts if (LK === 'm' && data.length > 2) { // @ts-ignore path.segments.push([pathCommand].concat(data.splice(0, 2))); LK = 'l'; pathCommand = pathCommand === 'm' ? 'l' : 'L'; } else { // @ts-ignore path.segments.push([pathCommand].concat(data.splice(0, paramsCount[LK]))); } if (!paramsCount[LK]) { break; } } } /** * Validates an A (arc-to) specific path command value. * Usually a `large-arc-flag` or `sweep-flag`. */ function scanFlag(path) { var index = path.index, pathValue = path.pathValue; var code = pathValue.charCodeAt(index); if (code === 0x30 /* 0 */) { path.param = 0; path.index += 1; return; } if (code === 0x31 /* 1 */) { path.param = 1; path.index += 1; return; } path.err = "[path-util]: invalid Arc flag \"" + pathValue[index] + "\", expecting 0 or 1 at index " + index; } /** * Checks if the character is or belongs to a number. * [0-9]|+|-|. */ function isDigitStart(code) { return ((code >= 48 && code <= 57) /* 0..9 */ || code === 0x2b /* + */ || code === 0x2d /* - */ || code === 0x2e); /* . */ } function isDigit(code) { return code >= 48 && code <= 57; // 0..9 } /** * Validates every character of the path string, * every path command, negative numbers or floating point numbers. */ function scanParam(path) { var max = path.max, pathValue = path.pathValue, start = path.index; var index = start; var zeroFirst = false; var hasCeiling = false; var hasDecimal = false; var hasDot = false; var ch; if (index >= max) { // path.err = 'SvgPath: missed param (at pos ' + index + ')'; path.err = "[path-util]: Invalid path value at index " + index + ", \"pathValue\" is missing param"; return; } ch = pathValue.charCodeAt(index); if (ch === 0x2b /* + */ || ch === 0x2d /* - */) { index += 1; // ch = (index < max) ? pathValue.charCodeAt(index) : 0; ch = pathValue.charCodeAt(index); } // This logic is shamelessly borrowed from Esprima // https://github.com/ariya/esprimas if (!isDigit(ch) && ch !== 0x2e /* . */) { // path.err = 'SvgPath: param should start with 0..9 or `.` (at pos ' + index + ')'; path.err = "[path-util]: Invalid path value at index " + index + ", \"" + pathValue[index] + "\" is not a number"; return; } if (ch !== 0x2e /* . */) { zeroFirst = ch === 0x30 /* 0 */; index += 1; ch = pathValue.charCodeAt(index); if (zeroFirst && index < max) { // decimal number starts with '0' such as '09' is illegal. if (ch && isDigit(ch)) { // path.err = 'SvgPath: numbers started with `0` such as `09` // are illegal (at pos ' + start + ')'; path.err = "[path-util]: Invalid path value at index " + start + ", \"" + pathValue[start] + "\" illegal number"; return; } } while (index < max && isDigit(pathValue.charCodeAt(index))) { index += 1; hasCeiling = true; } ch = pathValue.charCodeAt(index); } if (ch === 0x2e /* . */) { hasDot = true; index += 1; while (isDigit(pathValue.charCodeAt(index))) { index += 1; hasDecimal = true; } ch = pathValue.charCodeAt(index); } if (ch === 0x65 /* e */ || ch === 0x45 /* E */) { if (hasDot && !hasCeiling && !hasDecimal) { path.err = "[path-util]: Invalid path value at index " + index + ", \"" + pathValue[index] + "\" invalid float exponent"; return; } index += 1; ch = pathValue.charCodeAt(index); if (ch === 0x2b /* + */ || ch === 0x2d /* - */) { index += 1; } if (index < max && isDigit(pathValue.charCodeAt(index))) { while (index < max && isDigit(pathValue.charCodeAt(index))) { index += 1; } } else { path.err = "[path-util]: Invalid path value at index " + index + ", \"" + pathValue[index] + "\" invalid integer exponent"; return; } } path.index = index; path.param = +path.pathValue.slice(start, index); } /** * Checks if the character is a space. */ function isSpace(ch) { var specialSpaces = [ 0x1680, 0x180e, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200a, 0x202f, 0x205f, 0x3000, 0xfeff, ]; /* istanbul ignore next */ return (ch === 0x0a || ch === 0x0d || ch === 0x2028 || ch === 0x2029 || // Line terminators // White spaces ch === 0x20 || ch === 0x09 || ch === 0x0b || ch === 0x0c || ch === 0xa0 || (ch >= 0x1680 && specialSpaces.includes(ch))); } /** * Points the parser to the next character in the * path string every time it encounters any kind of * space character. */ function skipSpaces(path) { var pathValue = path.pathValue, max = path.max; while (path.index < max && isSpace(pathValue.charCodeAt(path.index))) { path.index += 1; } } /** * Checks if the character is a path command. */ function isPathCommand(code) { // eslint-disable-next-line no-bitwise -- Impossible to satisfy switch (code | 0x20) { case 0x6d /* m */: case 0x7a /* z */: case 0x6c /* l */: case 0x68 /* h */: case 0x76 /* v */: case 0x63 /* c */: case 0x73 /* s */: case 0x71 /* q */: case 0x74 /* t */: case 0x61 /* a */: // case 0x72/* r */: return true; default: return false; } } /** * Checks if the character is an A (arc-to) path command. */ function isArcCommand(code) { return (code | 0x20) === 0x61; } /** * Scans every character in the path string to determine * where a segment starts and where it ends. */ function scanSegment(path) { var max = path.max, pathValue = path.pathValue, index = path.index; var cmdCode = pathValue.charCodeAt(index); var reqParams = paramsCount[pathValue[index].toLowerCase()]; path.segmentStart = index; if (!isPathCommand(cmdCode)) { path.err = "[path-util]: Invalid path value \"" + pathValue[index] + "\" is not a path command"; return; } path.index += 1; skipSpaces(path); path.data = []; if (!reqParams) { // Z finalizeSegment(path); return; } for (;;) { for (var i = reqParams; i > 0; i -= 1) { if (isArcCommand(cmdCode) && (i === 3 || i === 4)) scanFlag(path); else scanParam(path); if (path.err.length) { return; } path.data.push(path.param); skipSpaces(path); // after ',' param is mandatory if (path.index < max && pathValue.charCodeAt(path.index) === 0x2c /* , */) { path.index += 1; skipSpaces(path); } } if (path.index >= path.max) { break; } // Stop on next segment if (!isDigitStart(pathValue.charCodeAt(path.index))) { break; } } finalizeSegment(path); } /** * The `PathParser` is used by the `parsePathString` static method * to generate a `pathArray`. */ var PathParser = /** @class */ (function () { function PathParser(pathString) { this.pathValue = pathString; // @ts-ignore this.segments = []; this.max = pathString.length; this.index = 0; this.param = 0.0; this.segmentStart = 0; this.data = []; this.err = ''; } return PathParser; }()); /** * Parses a path string value and returns an array * of segments we like to call `pathArray`. */ function parsePathString(pathInput) { if (isPathArray(pathInput)) { return clonePath(pathInput); } var path = new PathParser(pathInput); skipSpaces(path); while (path.index < path.max && !path.err.length) { scanSegment(path); } return path.err ? path.err : path.segments; } function path2Absolute(pathInput) { if (isAbsoluteArray(pathInput)) { return clonePath(pathInput); } var path = parsePathString(pathInput); // if (!path || !path.length) { // return [['M', 0, 0]]; // } var x = 0; var y = 0; var mx = 0; var my = 0; // @ts-ignore return path.map(function (segment) { var values = segment.slice(1).map(Number); var pathCommand = segment[0]; var absCommand = pathCommand.toUpperCase(); if (pathCommand === 'M') { x = values[0], y = values[1]; mx = x; my = y; return ['M', x, y]; } var absoluteSegment; if (pathCommand !== absCommand) { switch (absCommand) { case 'A': absoluteSegment = [ absCommand, values[0], values[1], values[2], values[3], values[4], values[5] + x, values[6] + y, ]; break; case 'V': absoluteSegment = [absCommand, values[0] + y]; break; case 'H': absoluteSegment = [absCommand, values[0] + x]; break; default: { // use brakets for `eslint: no-case-declaration` // https://stackoverflow.com/a/50753272/803358 var absValues = values.map(function (n, j) { return n + (j % 2 ? y : x); }); // for n, l, c, s, q, t // @ts-ignore absoluteSegment = [absCommand].concat(absValues); } } } else { // @ts-ignore absoluteSegment = [absCommand].concat(values); } var segLength = absoluteSegment.length; switch (absCommand) { case 'Z': x = mx; y = my; break; case 'H': x = absoluteSegment[1]; break; case 'V': y = absoluteSegment[1]; break; default: x = absoluteSegment[segLength - 2]; y = absoluteSegment[segLength - 1]; if (absCommand === 'M') { mx = x; my = y; } } return absoluteSegment; }); } /** * Normalizes a single segment of a `PathArray` object. * eg. H/V -> L, T -> Q */ function normalizeSegment(segment, params) { var pathCommand = segment[0]; var px1 = params.x1, py1 = params.y1, px2 = params.x2, py2 = params.y2; var values = segment.slice(1).map(Number); var result = segment; if (!'TQ'.includes(pathCommand)) { // optional but good to be cautious params.qx = null; params.qy = null; } if (pathCommand === 'H') { result = ['L', segment[1], py1]; } else if (pathCommand === 'V') { result = ['L', px1, segment[1]]; } else if (pathCommand === 'S') { var x1 = px1 * 2 - px2; var y1 = py1 * 2 - py2; params.x1 = x1; params.y1 = y1; result = ['C', x1, y1].concat(values); } else if (pathCommand === 'T') { var qx = px1 * 2 - params.qx; var qy = py1 * 2 - params.qy; params.qx = qx; params.qy = qy; result = ['Q', qx, qy].concat(values); } else if (pathCommand === 'Q') { var nqx = values[0], nqy = values[1]; params.qx = nqx; params.qy = nqy; } return result; } /** * @example * const path = 'M0 0 H50'; * const normalizedPath = SVGPathCommander.normalizePath(path); * // result => [['M', 0, 0], ['L', 50, 0]] */ function normalizePath(pathInput) { if (isNormalizedArray(pathInput)) { return clonePath(pathInput); } var path = path2Absolute(pathInput); var params = __assign({}, paramsParser); for (var i = 0; i < path.length; i += 1) { // Save current path command path[i] = normalizeSegment(path[i], params); var segment = path[i]; var seglen = segment.length; params.x1 = +segment[seglen - 2]; params.y1 = +segment[seglen - 1]; params.x2 = +segment[seglen - 4] || params.x1; params.y2 = +segment[seglen - 3] || params.y1; } return path; } /** * Iterates an array to check if it's a `PathArray` * with all C (cubic bezier) segments. * * @param {string | PathArray} path the `Array` to be checked * @returns {boolean} iteration result */ function isCurveArray(path) { return isNormalizedArray(path) && path.every(function (_a) { var pc = _a[0]; return 'MC'.includes(pc); }); } function rotateVector(x, y, rad) { var X = x * Math.cos(rad) - y * Math.sin(rad); var Y = x * Math.sin(rad) + y * Math.cos(rad); return { x: X, y: Y }; } /** * Converts A (arc-to) segments to C (cubic-bezier-to). * * For more information of where this math came from visit: * http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes */ function arcToCubic(X1, Y1, RX, RY, angle, LAF, SF, X2, Y2, recursive) { var x1 = X1; var y1 = Y1; var rx = RX; var ry = RY; var x2 = X2; var y2 = Y2; // for more information of where this Math came from visit: // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes var d120 = (Math.PI * 120) / 180; var rad = (Math.PI / 180) * (+angle || 0); /** @type {number[]} */ var res = []; var xy; var f1; var f2; var cx; var cy; if (!recursive) { xy = rotateVector(x1, y1, -rad); x1 = xy.x; y1 = xy.y; xy = rotateVector(x2, y2, -rad); x2 = xy.x; y2 = xy.y; var x = (x1 - x2) / 2; var y = (y1 - y2) / 2; var h = (x * x) / (rx * rx) + (y * y) / (ry * ry); if (h > 1) { h = Math.sqrt(h); rx *= h; ry *= h; } var rx2 = rx * rx; var ry2 = ry * ry; var k = (LAF === SF ? -1 : 1) * Math.sqrt(Math.abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))); cx = (k * rx * y) / ry + (x1 + x2) / 2; cy = (k * -ry * x) / rx + (y1 + y2) / 2; // eslint-disable-next-line no-bitwise -- Impossible to satisfy no-bitwise f1 = Math.asin(((((y1 - cy) / ry) * Math.pow(10, 9)) >> 0) / Math.pow(10, 9)); // eslint-disable-next-line no-bitwise -- Impossible to satisfy no-bitwise f2 = Math.asin(((((y2 - cy) / ry) * Math.pow(10, 9)) >> 0) / Math.pow(10, 9)); f1 = x1 < cx ? Math.PI - f1 : f1; f2 = x2 < cx ? Math.PI - f2 : f2; if (f1 < 0) f1 = Math.PI * 2 + f1; if (f2 < 0) f2 = Math.PI * 2 + f2; if (SF && f1 > f2) { f1 -= Math.PI * 2; } if (!SF && f2 > f1) { f2 -= Math.PI * 2; } } else { f1 = recursive[0], f2 = recursive[1], cx = recursive[2], cy = recursive[3]; } var df = f2 - f1; if (Math.abs(df) > d120) { var f2old = f2; var x2old = x2; var y2old = y2; f2 = f1 + d120 * (SF && f2 > f1 ? 1 : -1); x2 = cx + rx * Math.cos(f2); y2 = cy + ry * Math.sin(f2); res = arcToCubic(x2, y2, rx, ry, angle, 0, SF, x2old, y2old, [f2, f2old, cx, cy]); } df = f2 - f1; var c1 = Math.cos(f1); var s1 = Math.sin(f1); var c2 = Math.cos(f2); var s2 = Math.sin(f2); var t = Math.tan(df / 4); var hx = (4 / 3) * rx * t; var hy = (4 / 3) * ry * t; var m1 = [x1, y1]; var m2 = [x1 + hx * s1, y1 - hy * c1]; var m3 = [x2 + hx * s2, y2 - hy * c2]; var m4 = [x2, y2]; m2[0] = 2 * m1[0] - m2[0]; m2[1] = 2 * m1[1] - m2[1]; if (recursive) { return m2.concat(m3, m4, res); // return [...m2, ...m3, ...m4, ...res]; } res = m2.concat(m3, m4, res); // res = [...m2, ...m3, ...m4, ...res]; var newres = []; for (var i = 0, ii = res.length; i < ii; i += 1) { newres[i] = i % 2 ? rotateVector(res[i - 1], res[i], rad).y : rotateVector(res[i], res[i + 1], rad).x; } return newres; } // const TAU = Math.PI * 2; // const mapToEllipse = ( // { x, y }: { x: number; y: number }, // rx: number, // ry: number, // cosphi: number, // sinphi: number, // centerx: number, // centery: number, // ) => { // x *= rx; // y *= ry; // const xp = cosphi * x - sinphi * y; // const yp = sinphi * x + cosphi * y; // return { // x: xp + centerx, // y: yp + centery, // }; // }; // const approxUnitArc = (ang1: number, ang2: number) => { // // If 90 degree circular arc, use a constant // // as derived from http://spencermortensen.com/articles/bezier-circle // const a = // ang2 === 1.5707963267948966 // ? 0.551915024494 // : ang2 === -1.5707963267948966 // ? -0.551915024494 // : (4 / 3) * Math.tan(ang2 / 4); // const x1 = Math.cos(ang1); // const y1 = Math.sin(ang1); // const x2 = Math.cos(ang1 + ang2); // const y2 = Math.sin(ang1 + ang2); // return [ // { // x: x1 - y1 * a, // y: y1 + x1 * a, // }, // { // x: x2 + y2 * a, // y: y2 - x2 * a, // }, // { // x: x2, // y: y2, // }, // ]; // }; // const vectorAngle = (ux: number, uy: number, vx: number, vy: number) => { // const sign = ux * vy - uy * vx < 0 ? -1 : 1; // let dot = ux * vx + uy * vy; // if (dot > 1) { // dot = 1; // } // if (dot < -1) { // dot = -1; // } // return sign * Math.acos(dot); // }; // const getArcCenter = ( // px: any, // py: any, // cx: any, // cy: any, // rx: number, // ry: number, // largeArcFlag: number, // sweepFlag: number, // sinphi: number, // cosphi: number, // pxp: number, // pyp: number, // ) => { // const rxsq = Math.pow(rx, 2); // const rysq = Math.pow(ry, 2); // const pxpsq = Math.pow(pxp, 2); // const pypsq = Math.pow(pyp, 2); // let radicant = rxsq * rysq - rxsq * pypsq - rysq * pxpsq; // if (radicant < 0) { // radicant = 0; // } // radicant /= rxsq * pypsq + rysq * pxpsq; // radicant = Math.sqrt(radicant) * (largeArcFlag === sweepFlag ? -1 : 1); // const centerxp = ((radicant * rx) / ry) * pyp; // const centeryp = ((radicant * -ry) / rx) * pxp; // const centerx = cosphi * centerxp - sinphi * centeryp + (px + cx) / 2; // const centery = sinphi * centerxp + cosphi * centeryp + (py + cy) / 2; // const vx1 = (pxp - centerxp) / rx; // const vy1 = (pyp - centeryp) / ry; // const vx2 = (-pxp - centerxp) / rx; // const vy2 = (-pyp - centeryp) / ry; // const ang1 = vectorAngle(1, 0, vx1, vy1); // let ang2 = vectorAngle(vx1, vy1, vx2, vy2); // if (sweepFlag === 0 && ang2 > 0) { // ang2 -= TAU; // } // if (sweepFlag === 1 && ang2 < 0) { // ang2 += TAU; // } // return [centerx, centery, ang1, ang2]; // }; // const arcToBezier = ({ px, py, cx, cy, rx, ry, xAxisRotation = 0, largeArcFlag = 0, sweepFlag = 0 }) => { // const curves = []; // if (rx === 0 || ry === 0) { // return [{ x1: 0, y1: 0, x2: 0, y2: 0, x: cx, y: cy }]; // } // const sinphi = Math.sin((xAxisRotation * TAU) / 360); // const cosphi = Math.cos((xAxisRotation * TAU) / 360); // const pxp = (cosphi * (px - cx)) / 2 + (sinphi * (py - cy)) / 2; // const pyp = (-sinphi * (px - cx)) / 2 + (cosphi * (py - cy)) / 2; // if (pxp === 0 && pyp === 0) { // return [{ x1: 0, y1: 0, x2: 0, y2: 0, x: cx, y: cy }]; // } // rx = Math.abs(rx); // ry = Math.abs(ry); // const lambda = Math.pow(pxp, 2) / Math.pow(rx, 2) + Math.pow(pyp, 2) / Math.pow(ry, 2); // if (lambda > 1) { // rx *= Math.sqrt(lambda); // ry *= Math.sqrt(lambda); // } // let [centerx, centery, ang1, ang2] = getArcCenter( // px, // py, // cx, // cy, // rx, // ry, // largeArcFlag, // sweepFlag, // sinphi, // cosphi, // pxp, // pyp, // ); // // If 'ang2' == 90.0000000001, then `ratio` will evaluate to // // 1.0000000001. This causes `segments` to be greater than one, which is an // // unecessary split, and adds extra points to the bezier curve. To alleviate // // this issue, we round to 1.0 when the ratio is close to 1.0. // let ratio = Math.abs(ang2) / (TAU / 4); // if (Math.abs(1.0 - ratio) < 0.0000001) { // ratio = 1.0; // } // const segments = Math.max(Math.ceil(ratio), 1); // ang2 /= segments; // for (let i = 0; i < segments; i++) { // curves.push(approxUnitArc(ang1, ang2)); // ang1 += ang2; // } // return curves.map((curve) => { // const { x: x1, y: y1 } = mapToEllipse(curve[0], rx, ry, cosphi, sinphi, centerx, centery); // const { x: x2, y: y2 } = mapToEllipse(curve[1], rx, ry, cosphi, sinphi, centerx, centery); // const { x, y } = mapToEllipse(curve[2], rx, ry, cosphi, sinphi, centerx, centery); // return { x1, y1, x2, y2, x, y }; // }); // }; // export function arcToCubic( // x1: number, // y1: number, // rx: number, // ry: number, // angle: number, // LAF: number, // SF: number, // x2: number, // y2: number, // ) { // const curves = arcToBezier({ // px: x1, // py: y1, // cx: x2, // cy: y2, // rx, // ry, // xAxisRotation: angle, // largeArcFlag: LAF, // sweepFlag: SF, // }); // return curves.reduce((prev, cur) => { // const { x1, y1, x2, y2, x, y } = cur; // prev.push(x1, y1, x2, y2, x, y); // return prev; // }, [] as number[]); // } function quadToCubic(x1, y1, qx, qy, x2, y2) { var r13 = 1 / 3; var r23 = 2 / 3; return [ r13 * x1 + r23 * qx, r13 * y1 + r23 * qy, r13 * x2 + r23 * qx, r13 * y2 + r23 * qy, x2, y2, // x,y ]; } function midPoint(a, b, t) { var ax = a[0]; var ay = a[1]; var bx = b[0]; var by = b[1]; return [ax + (bx - ax) * t, ay + (by - ay) * t]; } function distanceSquareRoot(a, b) { return Math.sqrt((a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1])); } /** * Returns a {x,y} point at a given length, the total length and * the minimum and maximum {x,y} coordinates of a line (L,V,H,Z) segment. */ function segmentLineFactory(x1, y1, x2, y2, distance) { var length = distanceSquareRoot([x1, y1], [x2, y2]); var point = { x: 0, y: 0 }; if (typeof distance === 'number') { if (distance <= 0) { point = { x: x1, y: y1 }; } else if (distance >= length) { point = { x: x2, y: y2 }; } else { var _a = midPoint([x1, y1], [x2, y2], distance / length), x = _a[0], y = _a[1]; point = { x: x, y: y }; } } return { length: length, point: point, min: { x: Math.min(x1, x2), y: Math.min(y1, y2), }, max: { x: Math.max(x1, x2), y: Math.max(y1, y2), }, }; } function lineToCubic(x1, y1, x2, y2) { var t = 0.5; var p0 = [x1, y1]; var p1 = [x2, y2]; var p2 = midPoint(p0, p1, t); var p3 = midPoint(p1, p2, t); var p4 = midPoint(p2, p3, t); var p5 = midPoint(p3, p4, t); var p6 = midPoint(p4, p5, t); // const seg1 = [...p0, ...p2, ...p4, ...p6, t]; // @ts-ignore var cp1 = segmentLineFactory(p0[0], p0[1], p2[0], p2[1], p4[0]).point; // const seg2 = [...p6, ...p5, ...p3, ...p1, 0]; // @ts-ignore var cp2 = segmentLineFactory(p6[0], p6[1], p5[0], p5[1], p3[0]).point; return [cp1.x, cp1.y, cp2.x, cp2.y, x2, y2]; } function segmentToCubic(segment, params) { var pathCommand = segment[0]; var values = segment.slice(1).map(Number); var x = values[0], y = values[1]; var args; var px1 = params.x1, py1 = params.y1, px = params.x, py = params.y; if (!'TQ'.includes(pathCommand)) { params.qx = null; params.qy = null; } switch (pathCommand) { case 'M': params.x = x; params.y = y; return segment; case 'A': args = [px1, py1].concat(values); // @ts-ignore return ['C'].concat(arcToCubic(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9])); case 'Q': params.qx = x; params.qy = y; args = [px1, py1].concat(values); // @ts-ignore return ['C'].concat(quadToCubic(args[0], args[1], args[2], args[3], args[4], args[5])); case 'L': // @ts-ignore return ['C'].concat(lineToCubic(px1, py1, x, y)); case 'Z': // prevent NaN from divide 0 if (px1 === px && py1 === py) { return ['C', px1, py1, px, py, px, py]; } // @ts-ignore return ['C'].concat(lineToCubic(px1, py1, px, py)); } return segment; } // import { fixPath } from '../process/fix-path'; function path2Curve(pathInput, needZCommandIndexes) { if (needZCommandIndexes === void 0) { needZCommandIndexes = false; } if (isCurveArray(pathInput)) { var cloned = clonePath(pathInput); if (needZCommandIndexes) { return [cloned, []]; } else { return cloned; } } // fixPath will remove 'Z' command // const path = fixPath(normalizePath(pathInput)); var path = normalizePath(pathInput); var params = __assign({}, paramsParser); var allPathCommands = []; var pathCommand = ''; var ii = path.length; var segment; var seglen; var zCommandIndexes = []; for (var i = 0; i < ii; i += 1) { if (path[i]) pathCommand = path[i][0]; allPathCommands[i] = pathCommand; var curveSegment = segmentToCubic(path[i], params); path[i] = curveSegment; fixArc(path, allPathCommands, i); ii = path.length; // solves curveArrays ending in Z // keep Z command account for lineJoin // @see https://github.com/antvis/util/issues/68 if (pathCommand === 'Z') { zCommandIndexes.push(i); } segment = path[i]; seglen = segment.length; params.x1 = +segment[seglen - 2]; params.y1 = +segment[seglen - 1]; params.x2 = +segment[seglen - 4] || params.x1; params.y2 = +segment[seglen - 3] || params.y1; } // validate if (needZCommandIndexes) { return [path, zCommandIndexes]; } else { return path; } } // reverse CURVE based pathArray segments only function reverseCurve(pathArray) { var rotatedCurve = pathArray .slice(1) .map(function (x, i, curveOnly) { // @ts-ignore return !i ? pathArray[0].slice(1).concat(x.slice(1)) : curveOnly[i - 1].slice(-2).concat(x.slice(1)); }) // @ts-ignore .map(function (x) { return x.map(function (y, i) { return x[x.length - i - 2 * (1 - (i % 2))]; }); }) .reverse(); return [['M'].concat(rotatedCurve[0].slice(0, 2))].concat(rotatedCurve.map(function (x) { return ['C'].concat(x.slice(2)); })); } function angleBetween(v0, v1) { var v0x = v0.x, v0y = v0.y; var v1x = v1.x, v1y = v1.y; var p = v0x * v1x + v0y * v1y; var n = Math.sqrt((Math.pow(v0x, 2) + Math.pow(v0y, 2)) * (Math.pow(v1x, 2) + Math.pow(v1y, 2))); var sign = v0x * v1y - v0y * v1x < 0 ? -1 : 1; var angle = sign * Math.acos(p / n); return angle; } /** * Returns a {x,y} point at a given length, the total length and * the minimum and maximum {x,y} coordinates of a C (cubic-bezier) segment. * @see https://github.com/MadLittleMods/svg-curve-lib/blob/master/src/js/svg-curve-lib.js */ function getPointAtArcSegmentLength(x1, y1, RX, RY, angle, LAF, SF, x, y, t) { var abs = Math.abs, sin = Math.sin, cos = Math.cos, sqrt = Math.sqrt, PI = Math.PI; var rx = abs(RX); var ry = abs(RY); var xRot = ((angle % 360) + 360) % 360; var xRotRad = xRot * (PI / 180); if (x1 === x && y1 === y) { return { x: x1, y: y1 }; } if (rx === 0 || ry === 0) { return segmentLineFactory(x1, y1, x, y, t).point; } var dx = (x1 - x) / 2; var dy = (y1 - y) / 2; var transformedPoint = { x: cos(xRotRad) * dx + sin(xRotRad) * dy, y: -sin(xRotRad) * dx + cos(xRotRad) * dy, }; var radiiCheck = Math.pow(transformedPoint.x, 2) / Math.pow(rx, 2) + Math.pow(transformedPoint.y, 2) / Math.pow(ry, 2); if (radiiCheck > 1) { rx *= sqrt(radiiCheck); ry *= sqrt(radiiCheck); } var cSquareNumerator = Math.pow(rx, 2) * Math.pow(ry, 2) - Math.pow(rx, 2) * Math.pow(transformedPoint.y, 2) - Math.pow(ry, 2) * Math.pow(transformedPoint.x, 2); var cSquareRootDenom = Math.pow(rx, 2) * Math.pow(transformedPoint.y, 2) + Math.pow(ry, 2) * Math.pow(transformedPoint.x, 2); var cRadicand = cSquareNumerator / cSquareRootDenom; cRadicand = cRadicand < 0 ? 0 : cRadicand; var cCoef = (LAF !== SF ? 1 : -1) * sqrt(cRadicand); var transformedCenter = { x: cCoef * ((rx * transformedPoint.y) / ry), y: cCoef * (-(ry * transformedPoint.x) / rx), }; var center = { x: cos(xRotRad) * transformedCenter.x - sin(xRotRad) * transformedCenter.y + (x1 + x) / 2, y: sin(xRotRad) * transformedCenter.x + cos(xRotRad) * transformedCenter.y + (y1 + y) / 2, }; var startVector = { x: (transformedPoint.x - transformedCenter.x) / rx, y: (transformedPoint.y - transformedCenter.y) / ry, }; var startAngle = angleBetween({ x: 1, y: 0 }, startVector); var endVector = { x: (-transformedPoint.x - transformedCenter.x) / rx, y: (-transformedPoint.y - transformedCenter.y) / ry, }; var sweepAngle = angleBetween(startVector, endVector); if (!SF && sweepAngle > 0) { sweepAngle -= 2 * PI; } else if (SF && sweepAngle < 0) { sweepAngle += 2 * PI; } sweepAngle %= 2 * PI; var alpha = startAngle + sweepAngle * t; var ellipseComponentX = rx * cos(alpha); var ellipseComponentY = ry * sin(alpha); var point = { x: cos(xRotRad) * ellipseComponentX - sin(xRotRad) * ellipseComponentY + center.x, y: sin(xRotRad) * ellipseComponentX + cos(xRotRad) * ellipseComponentY + center.y, }; // to be used later // point.ellipticalArcStartAngle = startAngle; // point.ellipticalArcEndAngle = startAngle + sweepAngle; // point.ellipticalArcAngle = alpha; // point.ellipticalArcCenter = center; // point.resultantRx = rx; // point.resultantRy = ry; return point; } /** * Returns a {x,y} point at a given length, the total length and * the shape minimum and maximum {x,y} coordinates of an A (arc-to) segment. * * For better performance, it can skip calculate bbox or length in some scenario. */ function segmentArcFactory(X1, Y1, RX, RY, angle, LAF, SF, X2, Y2, distance, options) { var _a; var _b = options.bbox, bbox = _b === void 0 ? true : _b, _c = options.length, length = _c === void 0 ? true : _c, _d = options.sampleSize, sampleSize = _d === void 0 ? 30 : _d; var distanceIsNumber = typeof distance === 'number'; var x = X1; var y = Y1; var LENGTH = 0; var prev = [x, y, LENGTH]; var cur = [x, y]; var t = 0; var POINT = { x: 0, y: 0 }; var POINTS = [{ x: x, y: y }]; if (distanceIsNumber && distance <= 0) { POINT = { x: x, y: y }; } // bad perf when size > 100 for (var j = 0; j <= sampleSize; j += 1) { t = j / sampleSize; (_a = getPointAtArcSegmentLength(X1, Y1, RX, RY, angle, LAF, SF, X2, Y2, t), x = _a.x, y = _a.y); if (bbox) { POINTS.push({ x: x, y: y }); } if (length) { LENGTH += distanceSquareRoot(cur, [x, y]); } cur = [x, y]; if (distanceIsNumber && LENGTH >= distance && distance > prev[2]) { var dv = (LENGTH - distance) / (LENGTH - prev[2]); POINT = { x: cur[0] * (1 - dv) + prev[0] * dv, y: cur[1] * (1 - dv) + prev[1] * dv, }; } prev = [x, y, LENGTH]; } if (distanceIsNumber && distance >= LENGTH) { POINT = { x: X2, y: Y2 }; } return { length: LENGTH, point: POINT, min: { x: Math.min.apply(null, POINTS.map(function (n) { return n.x; })), y: Math.min.apply(null, POINTS.map(function (n) { return n.y; })), }, max: { x: Math.max.apply(null, POINTS.map(function (n) { return n.x; })), y: Math.max.apply(null, POINTS.map(function (n) { return n.y; })), }, }; } /** * Returns a {x,y} point at a given length, the total length and * the minimum and maximum {x,y} coordinates of a C (cubic-bezier) segment. */ function getPointAtCubicSegmentLength(x1, y1, c1x, c1y, c2x, c2y, x2, y2, t) { var t1 = 1 - t; return { x: Math.pow(t1, 3) * x1 + 3 * Math.pow(t1, 2) * t * c1x + 3 * t1 * Math.pow(t, 2) * c2x + Math.pow(t, 3) * x2, y: Math.pow(t1, 3) * y1 + 3 * Math.pow(t1, 2) * t * c1y + 3 * t1 * Math.pow(t, 2) * c2y + Math.pow(t, 3) * y2, }; } /** * Returns the length of a C (cubic-bezier) segment * or an {x,y} point at a given length. */ function segmentCubicFactory(x1, y1, c1x, c1y, c2x, c2y, x2, y2, distance, options) { var _a; var _b = options.bbox, bbox = _b === void 0 ? true : _b, _c = options.length, length = _c === void 0 ? true : _c, _d = options.sampleSize, sampleSize = _d === void 0 ? 10 : _d; var distanceIsNumber = typeof distance === 'number'; var x = x1; var y = y1; var LENGTH = 0; var prev = [x, y, LENGTH]; var cur = [x, y]; var t = 0; var POINT = { x: 0, y: 0 }; var POINTS = [{ x: x, y: y }]; if (distanceIsNumber && distance <= 0) { POINT = { x: x, y: y }; } // bad perf when size = 300 for (var j = 0; j <= sampleSize; j += 1) { t = j / sampleSize; (_a = getPointAtCubicSegmentLength(x1, y1, c1x, c1y, c2x, c2y, x2, y2, t), x = _a.x, y = _a.y); if (bbox) { POINTS.push({ x: x, y: y }); } if (length) { LENGTH += distanceSquareRoot(cur, [x, y]); } cur = [x, y]; if (distanceIsNumber && LENGTH >= distance && distance > prev[2]) { var dv = (LENGTH - distance) / (LENGTH - prev[2]); POINT = { x: cur[0] * (1 - dv) + prev[0] * dv, y: cur[1] * (1 - dv) + prev[1] * dv, }; } prev = [x, y, LENGTH]; } if (distanceIsNumber && distance >= LENGTH) { POINT = { x: x2, y: y2 }; } return { length: LENGTH, point: POINT, min: { x: Math.min.apply(null, POINTS.map(function (n) { return n.x; })), y: Math.min.apply(null, POINTS.map(function (n) { return n.y; })), }, max: { x: Math.max.apply(null, POINTS.map(function (n) { return n.x; })), y: Math.max.apply(null, POINTS.map(function (n) { return n.y; })), }, }; } /** * Returns the {x,y} coordinates of a point at a * given length of a quadratic-bezier segment. * * @see https://github.com/substack/point-at-length */ function getPointAtQuadSegmentLength(x1, y1, cx, cy, x2, y2, t) { var t1 = 1 - t; return { x: Math.pow(t1, 2) * x1 + 2 * t1 * t * cx + Math.pow(t, 2) * x2, y: Math.pow(t1, 2) * y1 + 2 * t1 * t * cy + Math.pow(t, 2) * y2, }; } /** * Returns a {x,y} point at a given length, the total length and * the minimum and maximum {x,y} coordinates of a Q (quadratic-bezier) segment. */ function segmentQuadFactory(x1, y1, qx, qy, x2, y2, distance, options) { var _a; var _b = options.bbox, bbox = _b === void 0 ? true : _b, _c = options.length, length = _c === void 0 ? true : _c, _d = options.sampleSize, sampleSize = _d === void 0 ? 10 : _d; var distanceIsNumber = typeof distance === 'number'; var x = x1; var y = y1; var LENGTH = 0; var prev = [x, y, LENGTH]; var cur = [x, y]; var t = 0; var POINT = { x: 0, y: 0 }; var POINTS = [{ x: x, y: y }]; if (distanceIsNumber && distance <= 0) { POINT = { x: x, y: y }; } for (var j = 0; j <= sampleSize; j += 1) { t = j / sampleSize; (_a = getPointAtQuadSegmentLength(x1, y1, qx, qy, x2, y2, t), x = _a.x, y = _a.y); if (bbox) { POINTS.push({ x: x, y: y }); } if (length) { LENGTH += distanceSquareRoot(cur, [x, y]); } cur = [x, y]; if (distanceIsNumber && LENGTH >= distance && distance > prev[2]) { var dv = (LENGTH - distance) / (LENGTH - prev[2]); POINT = { x: cur[0] * (1 - dv) + prev[0] * dv, y: cur[1] * (1 - dv) + prev[1] * dv, }; } prev = [x, y, LENGTH]; } /* istanbul ignore else */ if (distanceIsNumber && distance >= LENGTH) { POINT = { x: x2, y: y2 }; } return { length: LENGTH, point: POINT, min: { x: Math.min.apply(null, POINTS.map(function (n) { return n.x; })), y: Math.min.apply(null, POINTS.map(function (n) { return n.y; })), }, max: { x: Math.max.apply(null, POINTS.map(function (n) { return n.x; })), y: Math.max.apply(null, POINTS.map(function (n) { return n.y; })), }, }; } /** * Returns a {x,y} point at a given length * of a shape, the shape total length and * the shape minimum and maximum {x,y} coordinates. */ function pathLengthFactory(pathInput, distance, options) { var _a, _b, _c, _d, _e, _f; var path = normalizePath(pathInput); var distanceIsNumber = typeof distance === 'number'; var isM; var data = []; var pathCommand; var x = 0; var y = 0; var mx = 0; var my = 0; var seg; var MIN = []; var MAX = []; var length = 0; var min = { x: 0, y: 0 }; var max = min; var point = min; var POINT = min; var LENGTH = 0; for (var i = 0, ll = path.length; i < ll; i += 1) { seg = path[i]; pathCommand = seg[0]; isM = pathCommand === 'M'; data = !isM ? [x, y].concat(seg.slice(1)) : data; // this segment is always ZERO /* istanbul ignore else */ if (isM) { // remember mx, my for Z mx = seg[1], my = seg[2]; min = { x: mx, y: my }; max = min; length = 0; if (distanceIsNumber && distance < 0.001) { POINT = min; } } else if (pathCommand === 'L') { (_a = segmentLineFactory(data[0], data[1], data[2], data[3], (distance || 0) - LENGTH), length = _a.length, min = _a.min, max = _a.max, point = _a.point); } else if (pathCommand === 'A') { (_b = segmentArcFactory(data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], (distance || 0) - LENGTH, options || {}), length = _b.length, min = _b.min, max = _b.max, point = _b.point); } else if (pathCommand === 'C') { (_c = segmentCubicFactory(data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], (distance || 0) - LENGTH, options || {}), length = _c.length, min = _c.min, max = _c.max, point = _c.point); } else if (pathCommand === 'Q') { (_d = segmentQuadFactory(data[0], data[1], data[2], data[3], data[4], data[5], (distance || 0) - LENGTH, options || {}), length = _d.length, min = _d.min, max = _d.max, point = _d.point); } else if (pathCommand === 'Z') { data = [x, y, mx, my]; (_e = segmentLineFactory(data[0], data[1], data[2], data[3], (distance || 0) - LENGTH), length = _e.length, min = _e.min, max = _e.max, point = _e.point); } if (distanceIsNumber && LENGTH < distance && LENGTH + length >= distance) { POINT = point; } MAX.push(max); MIN.push(min); LENGTH += length; _f = pathCommand !== 'Z' ? seg.slice(-2) : [mx, my], x = _f[0], y = _f[1]; } // native `getPointAtLength` behavior when the given distance // is higher than total length if (distanceIsNumber && distance >= LENGTH) { POINT = { x: x, y: y }; } return { length: LENGTH, point: POINT, min: { x: Math.min.apply(null, MIN.map(function (n) { return n.x; })), y: Math.min.apply(null, MIN.map(function (n) { return n.y; })), }, max: { x: Math.max.apply(null, MAX.map(function (n) { return n.x; })), y: Math.max.apply(null, MAX.map(function (n) { return n.y; })), }, }; } /** * Returns the shape total length, or the equivalent to `shape.getTotalLength()`. * * The `normalizePath` version is lighter, faster, more efficient and more accurate * with paths that are not `curveArray`. */ function getTotalLength(pathInput, options) { return pathLengthFactory(pathInput, undefined, __assign(__assign({}, options), { bbox: false, length: true })).length; } function getRotations(a) { var segCount = a.length; var pointCount = segCount - 1; return a.map(function (f, idx) { return a.map(function (p, i) { var oldSegIdx = idx + i; var seg; if (i === 0 || (a[oldSegIdx] && a[oldSegIdx][0] === 'M')) { seg = a[oldSegIdx]; return ['M'].concat(seg.slice(-2)); } if (oldSegIdx >= segCount) oldSegIdx -= pointCount; return a[oldSegIdx]; }); }); } function getRotatedCurve(a, b) { var segCount = a.length - 1; var lineLengths = []; var computedIndex = 0; var sumLensSqrd = 0; var rotations = getRotations(a); rotations.forEach(function (r, i) { a.slice(1).forEach(function (s, j) { // @ts-ignore sumLensSqrd += distanceSquareRoot(a[(i + j) % segCount].slice(-2), b[j % segCount].slice(-2)); }); lineLengths[i] = sumLensSqrd; sumLensSqrd = 0; }); computedIndex = lineLengths.indexOf(Math.min.apply(null, lineLengths)); return rotations[computedIndex]; } /** * Returns the area of a single cubic-bezier segment. * * http://objectmix.com/graphics/133553-area-closed-bezier-curve.html */ function getCubicSegArea(x1, y1, c1x, c1y, c2x, c2y, x2, y2) { // https://stackoverflow.com/a/15845996 return ((3 * ((y2 - y1) * (c1x + c2x) - (x2 - x1) * (c1y + c2y) + c1y * (x1 - c2x) - c1x * (y1 - c2y) + y2 * (c2x + x1 / 3) - x2 * (c2y + y1 / 3))) / 20); } /** * Returns the area of a shape. * @author Jürg Lehni & Jonathan Puckey * * @see https://github.com/paperjs/paper.js/blob/develop/src/path/Path.js */ function getPathArea(path) { var x = 0; var y = 0; var len = 0; return path2Curve(path) .map(function (seg) { var _a; switch (seg[0]) { case 'M': x = seg[1], y = seg[2]; return 0; default: // @ts-ignore var _b = seg.slice(1), c1x = _b[0], c1y = _b[1], c2x = _b[2], c2y = _b[3], x2 = _b[4], y2 = _b[5]; len = getCubicSegArea(x, y, c1x, c1y, c2x, c2y, x2, y2); _a = seg.slice(-2), x = _a[0], y = _a[1]; return len; } }) .reduce(function (a, b) { return a + b; }, 0); } // export function getPathArea(pathArray: AbsoluteArray) { // let x = 0; // let y = 0; // let mx = 0; // let my = 0; // let len = 0; // return pathArray // .map((seg) => { // switch (seg[0]) { // case 'M': // case 'Z': // mx = seg[0] === 'M' ? seg[1] : mx; // my = seg[0] === 'M' ? seg[2] : my; // x = mx; // y = my; // return 0; // default: // // @ts-ignore // len = getCubicSegArea.apply(0, [x, y].concat(seg.slice(1))); // [x, y] = seg.slice(-2) as [number, number]; // return len; // } // }) // .reduce((a, b) => a + b, 0); // } function getDrawDirection(pathArray) { return getPathArea(pathArray) >= 0; } /** * Returns [x,y] coordinates of a point at a given length of a shape. */ function getPointAtLength(pathInput, distance, options) { return pathLengthFactory(pathInput, distance, __assign(__assign({}, options), { bbox: false, length: true })).point; } function splitCubic(pts, t) { if (t === void 0) { t = 0.5; } var p0 = pts.slice(0, 2); var p1 = pts.slice(2, 4); var p2 = pts.slice(4, 6); var p3 = pts.slice(6, 8); var p4 = midPoint(p0, p1, t); var p5 = midPoint(p1, p2, t); var p6 = midPoint(p2, p3, t); var p7 = midPoint(p4, p5, t); var p8 = midPoint(p5, p6, t); var p9 = midPoint(p7, p8, t); return [ // @ts-ignore ['C'].concat(p4, p7, p9), // @ts-ignore ['C'].concat(p8, p6, p3), ]; } function getCurveArray(segments) { return segments.map(function (segment, i, pathArray) { // @ts-ignore var segmentData = i && pathArray[i - 1].slice(-2).concat(segment.slice(1)); // @ts-ignore var curveLength = i ? segmentCubicFactory(segmentData[0], segmentData[1], segmentData[2], segmentData[3], segmentData[4], segmentData[5], segmentData[6], segmentData[7], segmentData[8], { bbox: false }).length : 0; var subsegs; if (i) { // must be [segment,segment] subsegs = curveLength ? splitCubic(segmentData) : [segment, segment]; } else { subsegs = [segment]; } return { s: segment, ss: subsegs, l: curveLength, }; }); } function equalizeSegments(path1, path2, TL) { var c1 = getCurveArray(path1); var c2 = getCurveArray(path2); var L1 = c1.length; var L2 = c2.length; var l1 = c1.filter(function (x) { return x.l; }).length; var l2 = c2.filter(function (x) { return x.l; }).length; var m1 = c1.filter(function (x) { return x.l; }).reduce(function (a, _a) { var l = _a.l; return a + l; }, 0) / l1 || 0; var m2 = c2.filter(function (x) { return x.l; }).reduce(function (a, _a) { var l = _a.l; return a + l; }, 0) / l2 || 0; var tl = TL || Math.max(L1, L2); var mm = [m1, m2]; var dif = [tl - L1, tl - L2]; var canSplit = 0; var result = [c1, c2].map(function (x, i) { // @ts-ignore return x.l === tl ? x.map(function (y) { return y.s; }) : x .map(function (y, j) { canSplit = j && dif[i] && y.l >= mm[i]; dif[i] -= canSplit ? 1 : 0; return canSplit ? y.ss : [y.s]; }) .flat(); }); return result[0].length === result[1].length ? result : equalizeSegments(result[0], result[1], tl); } // isFinite, var isNil = function (value) { /** * isNil(null) => true * isNil() => true */ return value === null || value === undefined; }; var toString = {}.toString; var isType = function (value, type) { return toString.call(value) === '[object ' + type + ']'; }; var isArray = (function (value) { return Array.isArray ? Array.isArray(value) : isType(value, 'Array'); }); var isObject = (function (value) { /** * isObject({}) => true * isObject([1, 2, 3]) => true * isObject(Function) => true * isObject(null) => false */ var type = typeof value; return (value !== null && type === 'object') || type === 'function'; }); /** * @param {Array} arr The array to iterate over. * @return {*} Returns the maximum value. * @example * * max([1, 2]); * // => 2 * * max([]); * // => undefined * * const data = new Array(1250010).fill(1).map((d,idx) => idx); * * max(data); * // => 1250010 * // Math.max(...data) will encounter "Maximum call stack size exceeded" error */ var max = (function (arr) { if (!isArray(arr)) { return undefined; } return arr.reduce(function (prev, curr) { return Math.max(prev, curr); }, arr[0]); }); /** * @param {Array} arr The array to iterate over. * @return {*} Returns the minimum value. * @example * * min([1, 2]); * // => 1 * * min([]); * // => undefined * * const data = new Array(1250010).fill(1).map((d,idx) => idx); * * min(data); * // => 1250010 * // Math.min(...data) will encounter "Maximum call stack size exceeded" error */ var min = (function (arr) { if (!isArray(arr)) { return undefined; } return arr.reduce(function (prev, curr) { return Math.min(prev, curr); }, arr[0]); }); var isString = (function (str) { return isType(str, 'String'); }); var clamp = function (a, min, max) { if (a < min) { return min; } else if (a > max) { return max; } return a; }; /** * 判断是否数字 * @return {Boolean} 是否数字 */ var isNumber = function (value) { return isType(value, 'Number'); }; var PRECISION = 0.00001; // numbers less than this is considered as 0 function isNumberEqual(a, b, precision) { if (precision === void 0) { precision = PRECISION; } return Math.abs(a - b) < precision; } var mod = function (n, m) { return ((n % m) + m) % m; }; /** * 是否是布尔类型 * * @param {Object} value 测试的值 * @return {Boolean} */ var isBoolean = function (value) { return isType(value, 'Boolean'); }; var isUndefined = function (value) { return value === undefined; }; // These units are iterated through, so be careful when adding or changing the (function (UnitType) { UnitType[UnitType["kUnknown"] = 0] = "kUnknown"; UnitType[UnitType["kNumber"] = 1] = "kNumber"; UnitType[UnitType["kPercentage"] = 2] = "kPercentage"; // Length units UnitType[UnitType["kEms"] = 3] = "kEms"; // kExs, UnitType[UnitType["kPixels"] = 4] = "kPixels"; // kCentimeters, // kMillimeters, // kInches, // kPoints, // kPicas, // kQuarterMillimeters, // https://drafts.csswg.org/css-values-4/#viewport-relative-lengths // // See also IsViewportPercentageLength. // kViewportWidth, // kViewportHeight, // kViewportInlineSize, // kViewportBlockSize, // kViewportMin, // kViewportMax, // kSmallViewportWidth, // kSmallViewportHeight, // kSmallViewportInlineSize, // kSmallViewportBlockSize, // kSmallViewportMin, // kSmallViewportMax, // kLargeViewportWidth, // kLargeViewportHeight, // kLargeViewportInlineSize, // kLargeViewportBlockSize, // kLargeViewportMin, // kLargeViewportMax, // kDynamicViewportWidth, // kDynamicViewportHeight, // kDynamicViewportInlineSize, // kDynamicViewportBlockSize, // kDynamicViewportMin, // kDynamicViewportMax, // https://drafts.csswg.org/css-contain-3/#container-lengths // // See also IsContainerPercentageLength. // kContainerWidth, // kContainerHeight, // kContainerInlineSize, // kContainerBlockSize, // kContainerMin, // kContainerMax, UnitType[UnitType["kRems"] = 5] = "kRems"; // kChs, // kUserUnits, // The SVG term for unitless lengths // Angle units UnitType[UnitType["kDegrees"] = 6] = "kDegrees"; UnitType[UnitType["kRadians"] = 7] = "kRadians"; UnitType[UnitType["kGradians"] = 8] = "kGradians"; UnitType[UnitType["kTurns"] = 9] = "kTurns"; // Time units UnitType[UnitType["kMilliseconds"] = 10] = "kMilliseconds"; UnitType[UnitType["kSeconds"] = 11] = "kSeconds"; // kHertz, // kKilohertz, // Resolution // kDotsPerPixel, // kDotsPerInch, // kDotsPerCentimeter, // Other units // kFraction, UnitType[UnitType["kInteger"] = 12] = "kInteger"; // This value is used to handle quirky margins in reflow roots (body, td, // and th) like WinIE. The basic idea is that a stylesheet can use the value // __qem (for quirky em) instead of em. When the quirky value is used, if // you're in quirks mode, the margin will collapse away inside a table cell. // This quirk is specified in the HTML spec but our impl is different. // TODO: Remove this. crbug.com/443952 // kQuirkyEms, })(exports.UnitType || (exports.UnitType = {})); var UnitCategory; (function (UnitCategory) { UnitCategory[UnitCategory["kUNumber"] = 0] = "kUNumber"; UnitCategory[UnitCategory["kUPercent"] = 1] = "kUPercent"; UnitCategory[UnitCategory["kULength"] = 2] = "kULength"; UnitCategory[UnitCategory["kUAngle"] = 3] = "kUAngle"; UnitCategory[UnitCategory["kUTime"] = 4] = "kUTime"; // kUFrequency, // kUResolution, UnitCategory[UnitCategory["kUOther"] = 5] = "kUOther"; })(UnitCategory || (UnitCategory = {})); var ValueRange; (function (ValueRange) { ValueRange[ValueRange["kAll"] = 0] = "kAll"; ValueRange[ValueRange["kNonNegative"] = 1] = "kNonNegative"; ValueRange[ValueRange["kInteger"] = 2] = "kInteger"; ValueRange[ValueRange["kNonNegativeInteger"] = 3] = "kNonNegativeInteger"; ValueRange[ValueRange["kPositiveInteger"] = 4] = "kPositiveInteger"; })(ValueRange || (ValueRange = {})); var Nested; (function (Nested) { Nested[Nested["kYes"] = 0] = "kYes"; Nested[Nested["kNo"] = 1] = "kNo"; })(Nested || (Nested = {})); var ParenLess; (function (ParenLess) { ParenLess[ParenLess["kYes"] = 0] = "kYes"; ParenLess[ParenLess["kNo"] = 1] = "kNo"; })(ParenLess || (ParenLess = {})); // This file specifies the unit strings used in CSSPrimitiveValues. var data = [{ name: 'em', unit_type: exports.UnitType.kEms }, // { // name: 'ex', // unit_type: UnitType.kExs, // }, { name: 'px', unit_type: exports.UnitType.kPixels }, // { // name: "cm", // unit_type: UnitType.kCentimeters, // }, // { // name: "mm", // unit_type: UnitType.kMillimeters, // }, // { // name: "q", // unit_type: UnitType.kQuarterMillimeters, // }, // { // name: "in", // unit_type: UnitType.kInches, // }, // { // name: "pt", // unit_type: UnitType.kPoints, // }, // { // name: "pc", // unit_type: UnitType.kPicas, // }, { name: 'deg', unit_type: exports.UnitType.kDegrees }, { name: 'rad', unit_type: exports.UnitType.kRadians }, { name: 'grad', unit_type: exports.UnitType.kGradians }, { name: 'ms', unit_type: exports.UnitType.kMilliseconds }, { name: 's', unit_type: exports.UnitType.kSeconds }, // { // name: "hz", // unit_type: UnitType.kHertz, // }, // { // name: "khz", // unit_type: UnitType.kKilohertz, // }, // { // name: "dpi", // unit_type: "kDotsPerInch", // }, // { // name: "dpcm", // unit_type: "kDotsPerCentimeter", // }, // { // name: "dppx", // unit_type: "kDotsPerPixel", // }, // { // name: "x", // unit_type: "kDotsPerPixel", // }, // { // name: "vw", // unit_type: "kViewportWidth", // }, // { // name: "vh", // unit_type: "kViewportHeight", // }, // { // name: "vi", // unit_type: "kViewportInlineSize", // }, // { // name: "vb", // unit_type: "kViewportBlockSize", // }, // { // name: "vmin", // unit_type: UnitType.kViewportMin, // }, // { // name: "vmax", // unit_type: UnitType.kViewportMax, // }, // { // name: "svw", // unit_type: "kSmallViewportWidth", // }, // { // name: "svh", // unit_type: "kSmallViewportHeight", // }, // { // name: "svi", // unit_type: "kSmallViewportInlineSize", // }, // { // name: "svb", // unit_type: "kSmallViewportBlockSize", // }, // { // name: "svmin", // unit_type: "kSmallViewportMin", // }, // { // name: "svmax", // unit_type: "kSmallViewportMax", // }, // { // name: "lvw", // unit_type: "kLargeViewportWidth", // }, // { // name: "lvh", // unit_type: "kLargeViewportHeight", // }, // { // name: "lvi", // unit_type: "kLargeViewportInlineSize", // }, // { // name: "lvb", // unit_type: "kLargeViewportBlockSize", // }, // { // name: "lvmin", // unit_type: UnitType.kLargeViewportMin, // }, // { // name: "lvmax", // unit_type: UnitType.kLargeViewportMax, // }, // { // name: "dvw", // unit_type: UnitType.kDynamicViewportWidth, // }, // { // name: "dvh", // unit_type: UnitType.kDynamicViewportHeight, // }, // { // name: "dvi", // unit_type: UnitType.kDynamicViewportInlineSize, // }, // { // name: "dvb", // unit_type: UnitType.kDynamicViewportBlockSize, // }, // { // name: "dvmin", // unit_type: UnitType.kDynamicViewportMin, // }, // { // name: "dvmax", // unit_type: UnitType.kDynamicViewportMax, // }, // { // name: "cqw", // unit_type: UnitType.kContainerWidth, // }, // { // name: "cqh", // unit_type: UnitType.kContainerHeight, // }, // { // name: "cqi", // unit_type: UnitType.kContainerInlineSize, // }, // { // name: "cqb", // unit_type: UnitType.kContainerBlockSize, // }, // { // name: "cqmin", // unit_type: UnitType.kContainerMin, // }, // { // name: "cqmax", // unit_type: UnitType.kContainerMax, // }, { name: 'rem', unit_type: exports.UnitType.kRems }, // { // name: 'fr', // unit_type: UnitType.kFraction, // }, { name: 'turn', unit_type: exports.UnitType.kTurns } // { // name: 'ch', // unit_type: UnitType.kChs, // }, // { // name: '__qem', // unit_type: UnitType.kQuirkyEms, // }, ]; var CSSStyleValueType; (function (CSSStyleValueType) { CSSStyleValueType[CSSStyleValueType["kUnknownType"] = 0] = "kUnknownType"; CSSStyleValueType[CSSStyleValueType["kUnparsedType"] = 1] = "kUnparsedType"; CSSStyleValueType[CSSStyleValueType["kKeywordType"] = 2] = "kKeywordType"; // Start of CSSNumericValue subclasses CSSStyleValueType[CSSStyleValueType["kUnitType"] = 3] = "kUnitType"; CSSStyleValueType[CSSStyleValueType["kSumType"] = 4] = "kSumType"; CSSStyleValueType[CSSStyleValueType["kProductType"] = 5] = "kProductType"; CSSStyleValueType[CSSStyleValueType["kNegateType"] = 6] = "kNegateType"; CSSStyleValueType[CSSStyleValueType["kInvertType"] = 7] = "kInvertType"; CSSStyleValueType[CSSStyleValueType["kMinType"] = 8] = "kMinType"; CSSStyleValueType[CSSStyleValueType["kMaxType"] = 9] = "kMaxType"; CSSStyleValueType[CSSStyleValueType["kClampType"] = 10] = "kClampType"; // End of CSSNumericValue subclasses CSSStyleValueType[CSSStyleValueType["kTransformType"] = 11] = "kTransformType"; CSSStyleValueType[CSSStyleValueType["kPositionType"] = 12] = "kPositionType"; CSSStyleValueType[CSSStyleValueType["kURLImageType"] = 13] = "kURLImageType"; CSSStyleValueType[CSSStyleValueType["kColorType"] = 14] = "kColorType"; CSSStyleValueType[CSSStyleValueType["kUnsupportedColorType"] = 15] = "kUnsupportedColorType"; })(CSSStyleValueType || (CSSStyleValueType = {})); // function parseCSSStyleValue(propertyName: string, value: string): CSSStyleValue[] { // // const propertyId = cssPropertyID(propertyName); // // if (propertyId === CSSPropertyID.kInvalid) { // // return []; // // } // // const customPropertyName = propertyId === CSSPropertyID.kVariable ? propertyName : null; // // return fromString(propertyId, customPropertyName, value); // return []; // } var stringToUnitType = function stringToUnitType(name) { return data.find(function (item) { return item.name === name; }).unit_type; }; var unitFromName = function unitFromName(name) { if (!name) { return exports.UnitType.kUnknown; } if (name === 'number') { return exports.UnitType.kNumber; } if (name === 'percent' || name === '%') { return exports.UnitType.kPercentage; } return stringToUnitType(name); }; var unitTypeToUnitCategory = function unitTypeToUnitCategory(type) { switch (type) { case exports.UnitType.kNumber: case exports.UnitType.kInteger: return UnitCategory.kUNumber; case exports.UnitType.kPercentage: return UnitCategory.kUPercent; case exports.UnitType.kPixels: // case UnitType.kCentimeters: // case UnitType.kMillimeters: // case UnitType.kQuarterMillimeters: // case UnitType.kInches: // case UnitType.kPoints: // case UnitType.kPicas: // case UnitType.kUserUnits: return UnitCategory.kULength; case exports.UnitType.kMilliseconds: case exports.UnitType.kSeconds: return UnitCategory.kUTime; case exports.UnitType.kDegrees: case exports.UnitType.kRadians: case exports.UnitType.kGradians: case exports.UnitType.kTurns: return UnitCategory.kUAngle; // case UnitType.kHertz: // case UnitType.kKilohertz: // return UnitCategory.kUFrequency; // case UnitType.kDotsPerPixel: // case UnitType.kDotsPerInch: // case UnitType.kDotsPerCentimeter: // return UnitCategory.kUResolution; default: return UnitCategory.kUOther; } }; var canonicalUnitTypeForCategory = function canonicalUnitTypeForCategory(category) { // The canonical unit type is chosen according to the way // CSSPropertyParser.ValidUnit() chooses the default unit in each category // (based on unitflags). switch (category) { case UnitCategory.kUNumber: return exports.UnitType.kNumber; case UnitCategory.kULength: return exports.UnitType.kPixels; case UnitCategory.kUPercent: return exports.UnitType.kPercentage; // return UnitType.kUnknown; // Cannot convert between numbers and percent. case UnitCategory.kUTime: return exports.UnitType.kSeconds; case UnitCategory.kUAngle: return exports.UnitType.kDegrees; // case UnitCategory.kUFrequency: // return UnitType.kHertz; // case UnitCategory.kUResolution: // return UnitType.kDotsPerPixel; default: return exports.UnitType.kUnknown; } }; /** * @see https://chromium.googlesource.com/chromium/src/+/refs/heads/main/third_party/blink/renderer/core/css/css_primitive_value.cc#353 */ var conversionToCanonicalUnitsScaleFactor = function conversionToCanonicalUnitsScaleFactor(unit_type) { var factor = 1.0; // FIXME: the switch can be replaced by an array of scale factors. switch (unit_type) { // These are "canonical" units in their respective categories. case exports.UnitType.kPixels: // case UnitType.kUserUnits: case exports.UnitType.kDegrees: case exports.UnitType.kSeconds: // case UnitType.kHertz: break; case exports.UnitType.kMilliseconds: factor = 0.001; break; // case UnitType.kCentimeters: // // factor = kCssPixelsPerCentimeter; // break; // case UnitType.kDotsPerCentimeter: // // factor = 1 / kCssPixelsPerCentimeter; // break; // case UnitType.kMillimeters: // // factor = kCssPixelsPerMillimeter; // break; // case UnitType.kQuarterMillimeters: // // factor = kCssPixelsPerQuarterMillimeter; // break; // case UnitType.kInches: // // factor = kCssPixelsPerInch; // break; // case UnitType.kDotsPerInch: // // factor = 1 / kCssPixelsPerInch; // break; // case UnitType.kPoints: // // factor = kCssPixelsPerPoint; // break; // case UnitType.kPicas: // // factor = kCssPixelsPerPica; // break; case exports.UnitType.kRadians: factor = 180 / Math.PI; break; case exports.UnitType.kGradians: factor = 0.9; break; case exports.UnitType.kTurns: factor = 360; break; } return factor; }; var unitTypeToString = function unitTypeToString(type) { switch (type) { case exports.UnitType.kNumber: case exports.UnitType.kInteger: // case UnitType.kUserUnits: return ''; case exports.UnitType.kPercentage: return '%'; case exports.UnitType.kEms: // case UnitType.kQuirkyEms: return 'em'; // case UnitType.kExs: // return 'ex'; case exports.UnitType.kRems: return 'rem'; // case UnitType.kChs: // return 'ch'; case exports.UnitType.kPixels: return 'px'; // case UnitType.kCentimeters: // return 'cm'; // case UnitType.kDotsPerPixel: // return 'dppx'; // case UnitType.kDotsPerInch: // return 'dpi'; // case UnitType.kDotsPerCentimeter: // return 'dpcm'; // case UnitType.kMillimeters: // return 'mm'; // case UnitType.kQuarterMillimeters: // return 'q'; // case UnitType.kInches: // return 'in'; // case UnitType.kPoints: // return 'pt'; // case UnitType.kPicas: // return 'pc'; case exports.UnitType.kDegrees: return 'deg'; case exports.UnitType.kRadians: return 'rad'; case exports.UnitType.kGradians: return 'grad'; case exports.UnitType.kMilliseconds: return 'ms'; case exports.UnitType.kSeconds: return 's'; // case UnitType.kHertz: // return 'hz'; // case UnitType.kKilohertz: // return 'khz'; case exports.UnitType.kTurns: return 'turn'; } return ''; }; /** * CSSStyleValue is the base class for all CSS values accessible from Typed OM. * Values that are not yet supported as specific types are also returned as base CSSStyleValues. * * Spec @see https://drafts.css-houdini.org/css-typed-om/#stylevalue-objects * Docs @see https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleValue */ var CSSStyleValue = /*#__PURE__*/function () { function CSSStyleValue() {} // static parse(propertyName: string, value: string): CSSStyleValue { // return parseCSSStyleValue(propertyName, value)[0]; // } // static parseAll(propertyName: string, value: string): CSSStyleValue[] { // return parseCSSStyleValue(propertyName, value); // } CSSStyleValue.isAngle = function isAngle(unit) { return unit === exports.UnitType.kDegrees || unit === exports.UnitType.kRadians || unit === exports.UnitType.kGradians || unit === exports.UnitType.kTurns; } // static isViewportPercentageLength(type: UnitType) { // return type >= UnitType.kViewportWidth && type <= UnitType.kDynamicViewportMax; // } // static isContainerPercentageLength(type: UnitType) { // return type >= UnitType.kContainerWidth && type <= UnitType.kContainerMax; // } ; CSSStyleValue.isLength = function isLength(type) { // return (type >= UnitType.kEms && type <= UnitType.kUserUnits) || type == UnitType.kQuirkyEms; return type >= exports.UnitType.kEms && type < exports.UnitType.kDegrees; }; CSSStyleValue.isRelativeUnit = function isRelativeUnit(type) { return type === exports.UnitType.kPercentage || type === exports.UnitType.kEms || // type === UnitType.kExs || type === exports.UnitType.kRems // type === UnitType.kChs || // this.isViewportPercentageLength(type) || // this.isContainerPercentageLength(type) ; }; CSSStyleValue.isTime = function isTime(unit) { return unit === exports.UnitType.kSeconds || unit === exports.UnitType.kMilliseconds; } // protected abstract toCSSValue(): CSSValue; ; var _proto = CSSStyleValue.prototype; _proto.toString = function toString() { return this.buildCSSText(Nested.kNo, ParenLess.kNo, ''); }; _proto.isNumericValue = function isNumericValue() { return this.getType() >= CSSStyleValueType.kUnitType && this.getType() <= CSSStyleValueType.kClampType; }; return CSSStyleValue; }(); /** * CSSColorValue is the base class used for the various CSS color interfaces. * * @see https://drafts.css-houdini.org/css-typed-om-1/#colorvalue-objects */ var CSSColorValue = /*#__PURE__*/function (_CSSStyleValue) { _inheritsLoose(CSSColorValue, _CSSStyleValue); function CSSColorValue(colorSpace) { var _this; _this = _CSSStyleValue.call(this) || this; _this.colorSpace = void 0; _this.colorSpace = colorSpace; return _this; } var _proto = CSSColorValue.prototype; _proto.getType = function getType() { return CSSStyleValueType.kColorType; } // buildCSSText(n: Nested, p: ParenLess, result: string): string { // let text = ''; // if (this.colorSpace === 'rgb') { // text = `rgba(${this.channels.join(',')},${this.alpha})`; // } // return (result += text); // } /** * @see https://drafts.css-houdini.org/css-typed-om-1/#dom-csscolorvalue-to */; _proto.to = function to(colorSpace) { return this; }; return CSSColorValue; }(CSSStyleValue); (function (GradientType) { GradientType[GradientType["Constant"] = 0] = "Constant"; GradientType[GradientType["LinearGradient"] = 1] = "LinearGradient"; GradientType[GradientType["RadialGradient"] = 2] = "RadialGradient"; })(exports.GradientType || (exports.GradientType = {})); var CSSGradientValue = /*#__PURE__*/function (_CSSStyleValue) { _inheritsLoose(CSSGradientValue, _CSSStyleValue); function CSSGradientValue(type, value) { var _this; _this = _CSSStyleValue.call(this) || this; _this.type = void 0; _this.value = void 0; _this.type = type; _this.value = value; return _this; } var _proto = CSSGradientValue.prototype; _proto.clone = function clone() { return new CSSGradientValue(this.type, this.value); }; _proto.buildCSSText = function buildCSSText(n, p, result) { return result; }; _proto.getType = function getType() { return CSSStyleValueType.kColorType; }; return CSSGradientValue; }(CSSStyleValue); /** * CSSKeywordValue represents CSS Values that are specified as keywords * eg. 'initial' * @see https://developer.mozilla.org/en-US/docs/Web/API/CSSKeywordValue * @see https://chromium.googlesource.com/chromium/src/+/refs/heads/main/third_party/blink/renderer/core/css/cssom/css_keyword_value.idl */ var CSSKeywordValue = /*#__PURE__*/function (_CSSStyleValue) { _inheritsLoose(CSSKeywordValue, _CSSStyleValue); function CSSKeywordValue(value) { var _this; _this = _CSSStyleValue.call(this) || this; _this.value = void 0; _this.value = value; return _this; } var _proto = CSSKeywordValue.prototype; _proto.clone = function clone() { return new CSSKeywordValue(this.value); }; _proto.getType = function getType() { return CSSStyleValueType.kKeywordType; }; _proto.buildCSSText = function buildCSSText(n, p, result) { return result + this.value; }; return CSSKeywordValue; }(CSSStyleValue); function memoize(func, resolver) { if (typeof func !== 'function' || resolver != null && typeof resolver !== 'function') { throw new TypeError('Expected a function'); } var memoized = function memoized() { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } var key = resolver ? resolver.apply(this, args) : args[0]; var cache = memoized.cache; if (cache.has(key)) { return cache.get(key); } var result = func.apply(this, args); memoized.cache = cache.set(key, result) || cache; return result; }; memoized.cache = new (memoize.Cache || Map)(); return memoized; } memoize.Cache = Map; var camelCase = memoize(function (str) { if (str === void 0) { str = ''; } return str.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); }); }); var kebabize = function kebabize(str) { return str.split('').map(function (letter, idx) { return letter.toUpperCase() === letter ? "" + (idx !== 0 ? '-' : '') + letter.toLowerCase() : letter; }).join(''); }; function DCHECK(bool) { if (!bool) { throw new Error(); } } function isFunction(func) { return typeof func === 'function'; } function isSymbol(value) { // @see https://github.com/lodash/lodash/blob/master/isSymbol.js return typeof value === 'symbol'; } var definedProps = function definedProps(obj) { return Object.fromEntries(Object.entries(obj).filter(function (_ref) { var v = _ref[1]; return v !== undefined; })); }; var FORMAT_ATTR_MAP = { d: { alias: 'path' }, strokeDasharray: { alias: 'lineDash' }, strokeWidth: { alias: 'lineWidth' }, textAnchor: { alias: 'textAlign' }, src: { alias: 'img' } }; var formatAttributeName = memoize(function (name) { var attributeName = camelCase(name); var map = FORMAT_ATTR_MAP[attributeName]; attributeName = (map === null || map === void 0 ? void 0 : map.alias) || attributeName; return attributeName; }); // type CSSNumericBaseType = // | 'length' // | 'angle' // | 'time' // | 'frequency' // | 'resolution' // | 'flex' // | 'percent'; // https://drafts.css-houdini.org/css-typed-om/#dictdef-cssnumerictype // interface CSSNumericType { // length: number; // angle: number; // time: number; // frequency: number; // resolution: number; // flex: number; // percent: number; // percentHint: CSSNumericBaseType; // } var formatInfinityOrNaN = function formatInfinityOrNaN(number, suffix) { if (suffix === void 0) { suffix = ''; } var result = ''; if (!Number.isFinite(number)) { if (number > 0) result = 'infinity';else result = '-infinity'; } else { DCHECK(Number.isNaN(number)); result = 'NaN'; } return result += suffix; }; var toCanonicalUnit = function toCanonicalUnit(unit) { return canonicalUnitTypeForCategory(unitTypeToUnitCategory(unit)); }; /** * CSSNumericValue is the base class for numeric and length typed CSS Values. * @see https://drafts.css-houdini.org/css-typed-om/#numeric-objects * @see https://developer.mozilla.org/en-US/docs/Web/API/CSSNumericValue * @see https://chromium.googlesource.com/chromium/src/+/refs/heads/main/third_party/blink/renderer/core/css/cssom/css_numeric_value.idl */ /** * Represents numeric values that can be expressed as a single number plus a * unit (or a naked number or percentage). * @see https://drafts.css-houdini.org/css-typed-om/#cssunitvalue */ var CSSUnitValue = /*#__PURE__*/function (_CSSStyleValue) { _inheritsLoose(CSSUnitValue, _CSSStyleValue); function CSSUnitValue(value, unitOrName) { var _this; if (unitOrName === void 0) { unitOrName = exports.UnitType.kNumber; } _this = _CSSStyleValue.call(this) || this; _this.unit = void 0; _this.value = void 0; var unit; if (typeof unitOrName === 'string') { unit = unitFromName(unitOrName); } else { unit = unitOrName; } _this.unit = unit; _this.value = value; return _this; } var _proto = CSSUnitValue.prototype; _proto.clone = function clone() { return new CSSUnitValue(this.value, this.unit); }; _proto.equals = function equals(other) { var other_unit_value = other; return this.value === other_unit_value.value && this.unit === other_unit_value.unit; }; _proto.getType = function getType() { return CSSStyleValueType.kUnitType; }; _proto.convertTo = function convertTo(target_unit) { if (this.unit === target_unit) { return new CSSUnitValue(this.value, this.unit); } // Instead of defining the scale factors for every unit to every other unit, // we simply convert to the canonical unit and back since we already have // the scale factors for canonical units. var canonical_unit = toCanonicalUnit(this.unit); if (canonical_unit !== toCanonicalUnit(target_unit) || canonical_unit === exports.UnitType.kUnknown) { return null; } var scale_factor = conversionToCanonicalUnitsScaleFactor(this.unit) / conversionToCanonicalUnitsScaleFactor(target_unit); return new CSSUnitValue(this.value * scale_factor, target_unit); }; _proto.buildCSSText = function buildCSSText(n, p, result) { var text; switch (this.unit) { case exports.UnitType.kUnknown: // FIXME break; case exports.UnitType.kInteger: text = Number(this.value).toFixed(0); break; case exports.UnitType.kNumber: case exports.UnitType.kPercentage: case exports.UnitType.kEms: // case UnitType.kQuirkyEms: // case UnitType.kExs: case exports.UnitType.kRems: // case UnitType.kChs: case exports.UnitType.kPixels: // case UnitType.kCentimeters: // case UnitType.kDotsPerPixel: // case UnitType.kDotsPerInch: // case UnitType.kDotsPerCentimeter: // case UnitType.kMillimeters: // case UnitType.kQuarterMillimeters: // case UnitType.kInches: // case UnitType.kPoints: // case UnitType.kPicas: // case UnitType.kUserUnits: case exports.UnitType.kDegrees: case exports.UnitType.kRadians: case exports.UnitType.kGradians: case exports.UnitType.kMilliseconds: case exports.UnitType.kSeconds: // case UnitType.kHertz: // case UnitType.kKilohertz: case exports.UnitType.kTurns: // case UnitType.kContainerMax: { // case UnitType.kContainerMin: // case UnitType.kContainerBlockSize: // case UnitType.kContainerInlineSize: // case UnitType.kContainerHeight: // case UnitType.kContainerWidth: // case UnitType.kDynamicViewportMax: // case UnitType.kDynamicViewportMin: // case UnitType.kDynamicViewportBlockSize: // case UnitType.kDynamicViewportInlineSize: // case UnitType.kDynamicViewportHeight: // case UnitType.kDynamicViewportWidth: // case UnitType.kLargeViewportMax: // case UnitType.kLargeViewportMin: // case UnitType.kLargeViewportBlockSize: // case UnitType.kLargeViewportInlineSize: // case UnitType.kLargeViewportHeight: // case UnitType.kLargeViewportWidth: // case UnitType.kSmallViewportMax: // case UnitType.kSmallViewportMin: // case UnitType.kSmallViewportBlockSize: // case UnitType.kSmallViewportInlineSize: // case UnitType.kSmallViewportHeight: // case UnitType.kSmallViewportWidth: // case UnitType.kViewportMax: // case UnitType.kViewportMin: // case UnitType.kViewportBlockSize: // case UnitType.kViewportInlineSize: // case UnitType.kViewportHeight: // case UnitType.kViewportWidth: // case UnitType.kFraction: { var kMinInteger = -999999; var kMaxInteger = 999999; var value = this.value; var unit = unitTypeToString(this.unit); if (value < kMinInteger || value > kMaxInteger) { var _unit = unitTypeToString(this.unit); if (!Number.isFinite(value) || Number.isNaN(value)) { text = formatInfinityOrNaN(value, _unit); } else { text = value + (_unit || ''); } } else { text = "" + value + unit; } } } result += text; return result; }; return CSSUnitValue; }(CSSStyleValue); var Opx = new CSSUnitValue(0, 'px'); var Lpx = new CSSUnitValue(1, 'px'); var Odeg = new CSSUnitValue(0, 'deg'); /** * The CSSRGB class represents the CSS rgb()/rgba() functions. * * @see https://drafts.css-houdini.org/css-typed-om-1/#cssrgb */ var CSSRGB = /*#__PURE__*/function (_CSSColorValue) { _inheritsLoose(CSSRGB, _CSSColorValue); function CSSRGB(r, g, b, alpha, /** * 'transparent' & 'none' has the same rgba data */ isNone) { var _this; if (alpha === void 0) { alpha = 1; } if (isNone === void 0) { isNone = false; } _this = _CSSColorValue.call(this, 'rgb') || this; _this.r = void 0; _this.g = void 0; _this.b = void 0; _this.alpha = void 0; _this.isNone = void 0; _this.r = r; _this.g = g; _this.b = b; _this.alpha = alpha; _this.isNone = isNone; return _this; } var _proto = CSSRGB.prototype; _proto.clone = function clone() { return new CSSRGB(this.r, this.g, this.b, this.alpha); }; _proto.buildCSSText = function buildCSSText(n, p, result) { return result + ("rgba(" + this.r + "," + this.g + "," + this.b + "," + this.alpha + ")"); }; return CSSRGB; }(CSSColorValue); /** * holds useful CSS-related methods. * @see https://developer.mozilla.org/en-US/docs/Web/API/CSS * * * CSS Typed OM @see https://developer.mozilla.org/en-US/docs/Web/API/CSS/factory_functions * * register property @see https://developer.mozilla.org/en-US/docs/Web/API/CSS/RegisterProperty * * CSS Layout API */ var CSS = { /** * * @see https://drafts.csswg.org/css-values-4/#number-value */ number: function number(n) { return new CSSUnitValue(n); }, /** * * @see https://drafts.csswg.org/css-values-4/#percentage-value */ percent: function percent(n) { return new CSSUnitValue(n, '%'); }, /** * */ px: function px(n) { return new CSSUnitValue(n, 'px'); }, /** * */ em: function em(n) { return new CSSUnitValue(n, 'em'); }, rem: function rem(n) { return new CSSUnitValue(n, 'rem'); }, /** * */ deg: function deg(n) { return new CSSUnitValue(n, 'deg'); }, /** * */ grad: function grad(n) { return new CSSUnitValue(n, 'grad'); }, /** * */ rad: function rad(n) { return new CSSUnitValue(n, 'rad'); }, /** * */ turn: function turn(n) { return new CSSUnitValue(n, 'turn'); }, /** *