diff --git a/demo/index.html b/demo/index.html index 4ff3b047..09d36118 100644 --- a/demo/index.html +++ b/demo/index.html @@ -4,7 +4,7 @@ Pts.js Demos - + diff --git a/dist/es2015/Op.js b/dist/es2015/Op.js index bf01cc14..0bf53cb4 100644 --- a/dist/es2015/Op.js +++ b/dist/es2015/Op.js @@ -284,6 +284,14 @@ export class Circle { } return new Group(Rectangle.center(pts), new Pt(r, r)); } + static fromTriangle(pts, enclose = false) { + if (enclose) { + return Triangle.circumcircle(pts); + } + else { + return Triangle.incircle(pts); + } + } static fromCenter(pt, radius) { return new Group(new Pt(pt), new Pt(radius, radius)); } diff --git a/dist/es2015/Space.js b/dist/es2015/Space.js index a319efa5..21ef19a9 100644 --- a/dist/es2015/Space.js +++ b/dist/es2015/Space.js @@ -209,7 +209,7 @@ export class MultiTouchSpace extends Space { _mouseUp(evt) { this._mouseAction(UIA.up, evt); if (this._dragged) - this._mouseAction(UIA.down, evt); + this._mouseAction(UIA.drop, evt); this._pressed = false; this._dragged = false; return false; diff --git a/dist/es2015/UI.js b/dist/es2015/UI.js index 4dd81ce8..1757c38f 100644 --- a/dist/es2015/UI.js +++ b/dist/es2015/UI.js @@ -1,78 +1,234 @@ -import { Rectangle, Circle } from "./Op"; -export var UIShape; -(function (UIShape) { - UIShape[UIShape["Rectangle"] = 0] = "Rectangle"; - UIShape[UIShape["Circle"] = 1] = "Circle"; - UIShape[UIShape["Polygon"] = 2] = "Polygon"; - UIShape[UIShape["Polyline"] = 3] = "Polyline"; - UIShape[UIShape["Line"] = 4] = "Line"; -})(UIShape || (UIShape = {})); +import { Pt, Group } from "./Pt"; +import { Rectangle, Circle, Polygon } from "./Op"; +export const UIShape = { + rectangle: "rectangle", circle: "circle", polygon: "polygon", polyline: "polyline", line: "line" +}; export const UIPointerActions = { - up: "up", down: "down", move: "move", drag: "drag", drop: "drop", over: "over", out: "out" + up: "up", down: "down", move: "move", drag: "drag", uidrag: "uidrag", drop: "drop", over: "over", out: "out", enter: "enter", leave: "leave", all: "all" }; export class UI { - constructor(group, shape, states, id) { - this.group = group; - this.shape = shape; - this._id = id; + constructor(group, shape, states = {}, id) { + this._holds = []; + this._group = Group.fromArray(group); + this._shape = shape; + this._id = id === undefined ? `ui_${(UI._counter++)}` : id; this._states = states; this._actions = {}; } + static fromRectangle(group, states, id) { + return new this(group, UIShape.rectangle, states, id); + } + static fromCircle(group, states, id) { + return new this(group, UIShape.circle, states, id); + } + static fromPolygon(group, states, id) { + return new this(group, UIShape.polygon, states, id); + } + static fromUI(ui, states, id) { + return new this(ui.group, ui.shape, states || ui._states, id); + } get id() { return this._id; } set id(d) { this._id = d; } - state(key) { - return this._states[key] || false; + get group() { return this._group; } + set group(d) { this._group = d; } + get shape() { return this._shape; } + set shape(d) { this._shape = d; } + state(key, value) { + if (!key) + return null; + if (value !== undefined) { + this._states[key] = value; + return this; + } + return this._states[key] || null; } on(key, fn) { - this._actions[key] = fn; - return this; + if (!this._actions[key]) + this._actions[key] = []; + return UI._addHandler(this._actions[key], fn); } - off(key) { - delete this._actions[key]; - return this; + off(key, which) { + if (!this._actions[key]) + return false; + if (which === undefined) { + delete this._actions[key]; + return true; + } + else { + return UI._removeHandler(this._actions[key], which); + } } listen(key, p) { if (this._actions[key] !== undefined) { - if (this._trigger(p)) { - this._actions[key](p, this, key); + if (this._within(p) || this._holds.indexOf(key) >= 0) { + UI._trigger(this._actions[key], this, p, key); + return true; + } + else if (this._actions['all']) { + UI._trigger(this._actions['all'], this, p, key); return true; } } return false; } + hold(key) { + this._holds.push(key); + return this._holds.length - 1; + } + unhold(id) { + if (id !== undefined) { + this._holds = this._holds.splice(id, 1); + } + else { + this._holds = []; + } + } + static track(uis, key, p) { + for (let i = 0, len = uis.length; i < len; i++) { + uis[i].listen(key, p); + } + } render(fn) { - fn(this.group, this._states); + fn(this._group, this._states); + } + toString() { + return `UI ${this.group.toString}`; } - _trigger(p) { + _within(p) { let fn = null; - if (this.shape === UIShape.Rectangle) { + if (this._shape === UIShape.rectangle) { fn = Rectangle.withinBound; } - else if (this.shape === UIShape.Circle) { + else if (this._shape === UIShape.circle) { fn = Circle.withinBound; } - else if (this.shape === UIShape.Polygon) { - fn = Rectangle.withinBound; + else if (this._shape === UIShape.polygon) { + fn = Polygon.hasIntersectPoint; + } + else { + return false; + } + return fn(this._group, p); + } + static _trigger(fns, target, pt, type) { + if (fns) { + for (let i = 0, len = fns.length; i < len; i++) { + if (fns[i]) + fns[i](target, pt, type); + } + } + } + static _addHandler(fns, fn) { + if (fn) { + fns.push(fn); + return fns.length - 1; + } + else { + return -1; + } + } + static _removeHandler(fns, index) { + if (index >= 0 && index < fns.length) { + let temp = fns.length; + fns.splice(index, 1); + return (temp > fns.length); } else { return false; } - return fn(this.group, p); } } +UI._counter = 0; export class UIButton extends UI { - constructor(group, shape, states, id) { + constructor(group, shape, states = {}, id) { super(group, shape, states, id); - this._clicks = 0; + this._hoverID = -1; + if (!states.hover) + states.hover = false; + if (!states.clicks) + states.hover = 0; + const UA = UIPointerActions; + this.on(UA.up, (target, pt, type) => { + this.state('clicks', this._states.clicks + 1); + }); + this.on(UA.move, (target, pt, type) => { + let hover = this._within(pt); + if (hover && !this._states.hover) { + this.state('hover', true); + UI._trigger(this._actions[UA.enter], this, pt, UA.enter); + var _capID = this.hold(UA.move); + this._hoverID = this.on(UA.move, (t, p) => { + if (!this._within(p) && !this.state('dragging')) { + this.state('hover', false); + UI._trigger(this._actions[UA.leave], this, pt, UA.leave); + this.off(UA.move, this._hoverID); + this.unhold(_capID); + } + }); + } + }); } - get clicks() { return this._clicks; } onClick(fn) { - this._clicks++; - this.on(UIPointerActions.up, fn); + return this.on(UIPointerActions.up, fn); + } + offClick(id) { + return this.off(UIPointerActions.up, id); + } + onHover(enter, leave) { + var ids = [undefined, undefined]; + if (enter) + ids[0] = this.on(UIPointerActions.enter, enter); + if (leave) + ids[1] = this.on(UIPointerActions.leave, leave); + return ids; + } + offHover(enterID, leaveID) { + var s = [false, false]; + if (enterID === undefined || enterID >= 0) + s[0] = this.off(UIPointerActions.enter, enterID); + if (leaveID === undefined || leaveID >= 0) + s[1] = this.off(UIPointerActions.leave, leaveID); + return s; + } +} +export class UIDragger extends UIButton { + constructor(group, shape, states = {}, id) { + super(group, shape, states, id); + this._draggingID = -1; + this._moveHoldID = -1; + if (!states.dragging) + states.dragging = false; + if (!states.offset) + states.offset = new Pt(group[0]); + const UA = UIPointerActions; + this.on(UA.down, (target, pt, type) => { + this.state('dragging', true); + this.state('offset', new Pt(pt).subtract(target.group[0])); + this._moveHoldID = this.hold(UA.move); + this._draggingID = this.on(UA.move, (t, p) => { + if (this.state('dragging')) { + UI._trigger(this._actions[UA.uidrag], t, p, UA.uidrag); + } + }); + }); + this.on(UA.up, (target, pt, type) => { + this.state('dragging', false); + this.off(UA.move, this._draggingID); + this.unhold(this._moveHoldID); + UI._trigger(this._actions[UA.drop], target, pt, type); + }); + } + onDrag(fn) { + return this.on(UIPointerActions.uidrag, fn); + } + offDrag(id) { + return this.off(UIPointerActions.uidrag, id); + } + onDrop(fn) { + return this.on(UIPointerActions.drop, fn); } - onHover(over, out) { - this.on(UIPointerActions.over, over); - this.on(UIPointerActions.out, out); + offDrop(id) { + return this.off(UIPointerActions.drop, id); } } //# sourceMappingURL=UI.js.map \ No newline at end of file diff --git a/dist/es2015/_lib.js b/dist/es2015/_lib.js index 76c39fc8..cb71f3c6 100644 --- a/dist/es2015/_lib.js +++ b/dist/es2015/_lib.js @@ -12,6 +12,7 @@ export * from "./Dom"; export * from "./Svg"; export * from "./Typography"; export * from "./Physics"; +export * from "./UI"; import * as _Canvas from './Canvas'; export let namespace = (scope) => { let lib = module.exports; diff --git a/dist/es2015/_module.js b/dist/es2015/_module.js index 835409b8..8f31661d 100644 --- a/dist/es2015/_module.js +++ b/dist/es2015/_module.js @@ -12,4 +12,5 @@ export * from "./Dom"; export * from "./Svg"; export * from "./Typography"; export * from "./Physics"; +export * from "./UI"; //# sourceMappingURL=_module.js.map \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index 96379dbf..66966348 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,5 +1,5 @@ /*! - * pts.js 0.5.1 - Copyright © 2017-2018 William Ngan and contributors. + * pts.js 0.6.0 - Copyright © 2017-2018 William Ngan and contributors. * Licensed under Apache 2.0 License. * See https://github.com/williamngan/pts for details. */ @@ -75,7 +75,7 @@ return /******/ (function(modules) { // webpackBootstrap /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 9); +/******/ return __webpack_require__(__webpack_require__.s = 10); /******/ }) /************************************************************************/ /******/ ([ @@ -984,6 +984,14 @@ class Circle { } return new Pt_1.Group(Rectangle.center(pts), new Pt_1.Pt(r, r)); } + static fromTriangle(pts, enclose = false) { + if (enclose) { + return Triangle.circumcircle(pts); + } + else { + return Triangle.incircle(pts); + } + } static fromCenter(pt, radius) { return new Pt_1.Group(new Pt_1.Pt(pt), new Pt_1.Pt(radius, radius)); } @@ -2391,7 +2399,7 @@ exports.Font = Font; Object.defineProperty(exports, "__esModule", { value: true }); const Pt_1 = __webpack_require__(0); -const UI_1 = __webpack_require__(11); +const UI_1 = __webpack_require__(7); class Space { constructor() { this.id = "space"; @@ -2602,7 +2610,7 @@ class MultiTouchSpace extends Space { _mouseUp(evt) { this._mouseAction(UI_1.UIPointerActions.up, evt); if (this._dragged) - this._mouseAction(UI_1.UIPointerActions.down, evt); + this._mouseAction(UI_1.UIPointerActions.drop, evt); this._pressed = false; this._dragged = false; return false; @@ -2641,6 +2649,251 @@ exports.MultiTouchSpace = MultiTouchSpace; "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const Pt_1 = __webpack_require__(0); +const Op_1 = __webpack_require__(2); +exports.UIShape = { + rectangle: "rectangle", circle: "circle", polygon: "polygon", polyline: "polyline", line: "line" +}; +exports.UIPointerActions = { + up: "up", down: "down", move: "move", drag: "drag", uidrag: "uidrag", drop: "drop", over: "over", out: "out", enter: "enter", leave: "leave", all: "all" +}; +class UI { + constructor(group, shape, states = {}, id) { + this._holds = []; + this._group = Pt_1.Group.fromArray(group); + this._shape = shape; + this._id = id === undefined ? `ui_${(UI._counter++)}` : id; + this._states = states; + this._actions = {}; + } + static fromRectangle(group, states, id) { + return new this(group, exports.UIShape.rectangle, states, id); + } + static fromCircle(group, states, id) { + return new this(group, exports.UIShape.circle, states, id); + } + static fromPolygon(group, states, id) { + return new this(group, exports.UIShape.polygon, states, id); + } + static fromUI(ui, states, id) { + return new this(ui.group, ui.shape, states || ui._states, id); + } + get id() { return this._id; } + set id(d) { this._id = d; } + get group() { return this._group; } + set group(d) { this._group = d; } + get shape() { return this._shape; } + set shape(d) { this._shape = d; } + state(key, value) { + if (!key) + return null; + if (value !== undefined) { + this._states[key] = value; + return this; + } + return this._states[key] || null; + } + on(key, fn) { + if (!this._actions[key]) + this._actions[key] = []; + return UI._addHandler(this._actions[key], fn); + } + off(key, which) { + if (!this._actions[key]) + return false; + if (which === undefined) { + delete this._actions[key]; + return true; + } + else { + return UI._removeHandler(this._actions[key], which); + } + } + listen(key, p) { + if (this._actions[key] !== undefined) { + if (this._within(p) || this._holds.indexOf(key) >= 0) { + UI._trigger(this._actions[key], this, p, key); + return true; + } + else if (this._actions['all']) { + UI._trigger(this._actions['all'], this, p, key); + return true; + } + } + return false; + } + hold(key) { + this._holds.push(key); + return this._holds.length - 1; + } + unhold(id) { + if (id !== undefined) { + this._holds = this._holds.splice(id, 1); + } + else { + this._holds = []; + } + } + static track(uis, key, p) { + for (let i = 0, len = uis.length; i < len; i++) { + uis[i].listen(key, p); + } + } + render(fn) { + fn(this._group, this._states); + } + toString() { + return `UI ${this.group.toString}`; + } + _within(p) { + let fn = null; + if (this._shape === exports.UIShape.rectangle) { + fn = Op_1.Rectangle.withinBound; + } + else if (this._shape === exports.UIShape.circle) { + fn = Op_1.Circle.withinBound; + } + else if (this._shape === exports.UIShape.polygon) { + fn = Op_1.Polygon.hasIntersectPoint; + } + else { + return false; + } + return fn(this._group, p); + } + static _trigger(fns, target, pt, type) { + if (fns) { + for (let i = 0, len = fns.length; i < len; i++) { + if (fns[i]) + fns[i](target, pt, type); + } + } + } + static _addHandler(fns, fn) { + if (fn) { + fns.push(fn); + return fns.length - 1; + } + else { + return -1; + } + } + static _removeHandler(fns, index) { + if (index >= 0 && index < fns.length) { + let temp = fns.length; + fns.splice(index, 1); + return (temp > fns.length); + } + else { + return false; + } + } +} +UI._counter = 0; +exports.UI = UI; +class UIButton extends UI { + constructor(group, shape, states = {}, id) { + super(group, shape, states, id); + this._hoverID = -1; + if (!states.hover) + states.hover = false; + if (!states.clicks) + states.hover = 0; + const UA = exports.UIPointerActions; + this.on(UA.up, (target, pt, type) => { + this.state('clicks', this._states.clicks + 1); + }); + this.on(UA.move, (target, pt, type) => { + let hover = this._within(pt); + if (hover && !this._states.hover) { + this.state('hover', true); + UI._trigger(this._actions[UA.enter], this, pt, UA.enter); + var _capID = this.hold(UA.move); + this._hoverID = this.on(UA.move, (t, p) => { + if (!this._within(p) && !this.state('dragging')) { + this.state('hover', false); + UI._trigger(this._actions[UA.leave], this, pt, UA.leave); + this.off(UA.move, this._hoverID); + this.unhold(_capID); + } + }); + } + }); + } + onClick(fn) { + return this.on(exports.UIPointerActions.up, fn); + } + offClick(id) { + return this.off(exports.UIPointerActions.up, id); + } + onHover(enter, leave) { + var ids = [undefined, undefined]; + if (enter) + ids[0] = this.on(exports.UIPointerActions.enter, enter); + if (leave) + ids[1] = this.on(exports.UIPointerActions.leave, leave); + return ids; + } + offHover(enterID, leaveID) { + var s = [false, false]; + if (enterID === undefined || enterID >= 0) + s[0] = this.off(exports.UIPointerActions.enter, enterID); + if (leaveID === undefined || leaveID >= 0) + s[1] = this.off(exports.UIPointerActions.leave, leaveID); + return s; + } +} +exports.UIButton = UIButton; +class UIDragger extends UIButton { + constructor(group, shape, states = {}, id) { + super(group, shape, states, id); + this._draggingID = -1; + this._moveHoldID = -1; + if (!states.dragging) + states.dragging = false; + if (!states.offset) + states.offset = new Pt_1.Pt(group[0]); + const UA = exports.UIPointerActions; + this.on(UA.down, (target, pt, type) => { + this.state('dragging', true); + this.state('offset', new Pt_1.Pt(pt).subtract(target.group[0])); + this._moveHoldID = this.hold(UA.move); + this._draggingID = this.on(UA.move, (t, p) => { + if (this.state('dragging')) { + UI._trigger(this._actions[UA.uidrag], t, p, UA.uidrag); + } + }); + }); + this.on(UA.up, (target, pt, type) => { + this.state('dragging', false); + this.off(UA.move, this._draggingID); + this.unhold(this._moveHoldID); + UI._trigger(this._actions[UA.drop], target, pt, type); + }); + } + onDrag(fn) { + return this.on(exports.UIPointerActions.uidrag, fn); + } + offDrag(id) { + return this.off(exports.UIPointerActions.uidrag, id); + } + onDrop(fn) { + return this.on(exports.UIPointerActions.drop, fn); + } + offDrop(id) { + return this.off(exports.UIPointerActions.drop, id); + } +} +exports.UIDragger = UIDragger; + + +/***/ }), +/* 8 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); const Pt_1 = __webpack_require__(0); class Typography { @@ -2683,7 +2936,7 @@ exports.Typography = Typography; /***/ }), -/* 8 */ +/* 9 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -3133,7 +3386,7 @@ exports.HTMLForm = HTMLForm; /***/ }), -/* 9 */ +/* 10 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -3142,7 +3395,7 @@ function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, "__esModule", { value: true }); -__export(__webpack_require__(10)); +__export(__webpack_require__(11)); __export(__webpack_require__(12)); __export(__webpack_require__(5)); __export(__webpack_require__(4)); @@ -3152,14 +3405,15 @@ __export(__webpack_require__(0)); __export(__webpack_require__(6)); __export(__webpack_require__(13)); __export(__webpack_require__(1)); -__export(__webpack_require__(8)); +__export(__webpack_require__(9)); __export(__webpack_require__(14)); -__export(__webpack_require__(7)); +__export(__webpack_require__(8)); __export(__webpack_require__(15)); +__export(__webpack_require__(7)); /***/ }), -/* 10 */ +/* 11 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -3169,7 +3423,7 @@ const Space_1 = __webpack_require__(6); const Form_1 = __webpack_require__(5); const Pt_1 = __webpack_require__(0); const Util_1 = __webpack_require__(1); -const Typography_1 = __webpack_require__(7); +const Typography_1 = __webpack_require__(8); const Op_1 = __webpack_require__(2); class CanvasSpace extends Space_1.MultiTouchSpace { constructor(elem, callback) { @@ -3689,94 +3943,6 @@ class CanvasForm extends Form_1.VisualForm { exports.CanvasForm = CanvasForm; -/***/ }), -/* 11 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const Op_1 = __webpack_require__(2); -var UIShape; -(function (UIShape) { - UIShape[UIShape["Rectangle"] = 0] = "Rectangle"; - UIShape[UIShape["Circle"] = 1] = "Circle"; - UIShape[UIShape["Polygon"] = 2] = "Polygon"; - UIShape[UIShape["Polyline"] = 3] = "Polyline"; - UIShape[UIShape["Line"] = 4] = "Line"; -})(UIShape = exports.UIShape || (exports.UIShape = {})); -exports.UIPointerActions = { - up: "up", down: "down", move: "move", drag: "drag", drop: "drop", over: "over", out: "out" -}; -class UI { - constructor(group, shape, states, id) { - this.group = group; - this.shape = shape; - this._id = id; - this._states = states; - this._actions = {}; - } - get id() { return this._id; } - set id(d) { this._id = d; } - state(key) { - return this._states[key] || false; - } - on(key, fn) { - this._actions[key] = fn; - return this; - } - off(key) { - delete this._actions[key]; - return this; - } - listen(key, p) { - if (this._actions[key] !== undefined) { - if (this._trigger(p)) { - this._actions[key](p, this, key); - return true; - } - } - return false; - } - render(fn) { - fn(this.group, this._states); - } - _trigger(p) { - let fn = null; - if (this.shape === UIShape.Rectangle) { - fn = Op_1.Rectangle.withinBound; - } - else if (this.shape === UIShape.Circle) { - fn = Op_1.Circle.withinBound; - } - else if (this.shape === UIShape.Polygon) { - fn = Op_1.Rectangle.withinBound; - } - else { - return false; - } - return fn(this.group, p); - } -} -exports.UI = UI; -class UIButton extends UI { - constructor(group, shape, states, id) { - super(group, shape, states, id); - this._clicks = 0; - } - get clicks() { return this._clicks; } - onClick(fn) { - this._clicks++; - this.on(exports.UIPointerActions.up, fn); - } - onHover(over, out) { - this.on(exports.UIPointerActions.over, over); - this.on(exports.UIPointerActions.out, out); - } -} -exports.UIButton = UIButton; - - /***/ }), /* 12 */ /***/ (function(module, exports, __webpack_require__) { @@ -4409,7 +4575,7 @@ const Num_1 = __webpack_require__(3); const Util_1 = __webpack_require__(1); const Pt_1 = __webpack_require__(0); const Op_1 = __webpack_require__(2); -const Dom_1 = __webpack_require__(8); +const Dom_1 = __webpack_require__(9); class SVGSpace extends Dom_1.DOMSpace { constructor(elem, callback) { super(elem, callback); diff --git a/dist/pts.js b/dist/pts.js index 1ec1f190..08ac7552 100644 --- a/dist/pts.js +++ b/dist/pts.js @@ -1,5 +1,5 @@ /*! - * pts.js 0.5.1 - Copyright © 2017-2018 William Ngan and contributors. + * pts.js 0.6.0 - Copyright © 2017-2018 William Ngan and contributors. * Licensed under Apache 2.0 License. * See https://github.com/williamngan/pts for details. */ @@ -75,7 +75,7 @@ return /******/ (function(modules) { // webpackBootstrap /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 10); +/******/ return __webpack_require__(__webpack_require__.s = 11); /******/ }) /************************************************************************/ /******/ ([ @@ -984,6 +984,14 @@ class Circle { } return new Pt_1.Group(Rectangle.center(pts), new Pt_1.Pt(r, r)); } + static fromTriangle(pts, enclose = false) { + if (enclose) { + return Triangle.circumcircle(pts); + } + else { + return Triangle.incircle(pts); + } + } static fromCenter(pt, radius) { return new Pt_1.Group(new Pt_1.Pt(pt), new Pt_1.Pt(radius, radius)); } @@ -2391,7 +2399,7 @@ exports.Font = Font; Object.defineProperty(exports, "__esModule", { value: true }); const Pt_1 = __webpack_require__(0); -const UI_1 = __webpack_require__(11); +const UI_1 = __webpack_require__(8); class Space { constructor() { this.id = "space"; @@ -2602,7 +2610,7 @@ class MultiTouchSpace extends Space { _mouseUp(evt) { this._mouseAction(UI_1.UIPointerActions.up, evt); if (this._dragged) - this._mouseAction(UI_1.UIPointerActions.down, evt); + this._mouseAction(UI_1.UIPointerActions.drop, evt); this._pressed = false; this._dragged = false; return false; @@ -2646,7 +2654,7 @@ const Space_1 = __webpack_require__(6); const Form_1 = __webpack_require__(5); const Pt_1 = __webpack_require__(0); const Util_1 = __webpack_require__(1); -const Typography_1 = __webpack_require__(8); +const Typography_1 = __webpack_require__(9); const Op_1 = __webpack_require__(2); class CanvasSpace extends Space_1.MultiTouchSpace { constructor(elem, callback) { @@ -3172,6 +3180,251 @@ exports.CanvasForm = CanvasForm; "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const Pt_1 = __webpack_require__(0); +const Op_1 = __webpack_require__(2); +exports.UIShape = { + rectangle: "rectangle", circle: "circle", polygon: "polygon", polyline: "polyline", line: "line" +}; +exports.UIPointerActions = { + up: "up", down: "down", move: "move", drag: "drag", uidrag: "uidrag", drop: "drop", over: "over", out: "out", enter: "enter", leave: "leave", all: "all" +}; +class UI { + constructor(group, shape, states = {}, id) { + this._holds = []; + this._group = Pt_1.Group.fromArray(group); + this._shape = shape; + this._id = id === undefined ? `ui_${(UI._counter++)}` : id; + this._states = states; + this._actions = {}; + } + static fromRectangle(group, states, id) { + return new this(group, exports.UIShape.rectangle, states, id); + } + static fromCircle(group, states, id) { + return new this(group, exports.UIShape.circle, states, id); + } + static fromPolygon(group, states, id) { + return new this(group, exports.UIShape.polygon, states, id); + } + static fromUI(ui, states, id) { + return new this(ui.group, ui.shape, states || ui._states, id); + } + get id() { return this._id; } + set id(d) { this._id = d; } + get group() { return this._group; } + set group(d) { this._group = d; } + get shape() { return this._shape; } + set shape(d) { this._shape = d; } + state(key, value) { + if (!key) + return null; + if (value !== undefined) { + this._states[key] = value; + return this; + } + return this._states[key] || null; + } + on(key, fn) { + if (!this._actions[key]) + this._actions[key] = []; + return UI._addHandler(this._actions[key], fn); + } + off(key, which) { + if (!this._actions[key]) + return false; + if (which === undefined) { + delete this._actions[key]; + return true; + } + else { + return UI._removeHandler(this._actions[key], which); + } + } + listen(key, p) { + if (this._actions[key] !== undefined) { + if (this._within(p) || this._holds.indexOf(key) >= 0) { + UI._trigger(this._actions[key], this, p, key); + return true; + } + else if (this._actions['all']) { + UI._trigger(this._actions['all'], this, p, key); + return true; + } + } + return false; + } + hold(key) { + this._holds.push(key); + return this._holds.length - 1; + } + unhold(id) { + if (id !== undefined) { + this._holds = this._holds.splice(id, 1); + } + else { + this._holds = []; + } + } + static track(uis, key, p) { + for (let i = 0, len = uis.length; i < len; i++) { + uis[i].listen(key, p); + } + } + render(fn) { + fn(this._group, this._states); + } + toString() { + return `UI ${this.group.toString}`; + } + _within(p) { + let fn = null; + if (this._shape === exports.UIShape.rectangle) { + fn = Op_1.Rectangle.withinBound; + } + else if (this._shape === exports.UIShape.circle) { + fn = Op_1.Circle.withinBound; + } + else if (this._shape === exports.UIShape.polygon) { + fn = Op_1.Polygon.hasIntersectPoint; + } + else { + return false; + } + return fn(this._group, p); + } + static _trigger(fns, target, pt, type) { + if (fns) { + for (let i = 0, len = fns.length; i < len; i++) { + if (fns[i]) + fns[i](target, pt, type); + } + } + } + static _addHandler(fns, fn) { + if (fn) { + fns.push(fn); + return fns.length - 1; + } + else { + return -1; + } + } + static _removeHandler(fns, index) { + if (index >= 0 && index < fns.length) { + let temp = fns.length; + fns.splice(index, 1); + return (temp > fns.length); + } + else { + return false; + } + } +} +UI._counter = 0; +exports.UI = UI; +class UIButton extends UI { + constructor(group, shape, states = {}, id) { + super(group, shape, states, id); + this._hoverID = -1; + if (!states.hover) + states.hover = false; + if (!states.clicks) + states.hover = 0; + const UA = exports.UIPointerActions; + this.on(UA.up, (target, pt, type) => { + this.state('clicks', this._states.clicks + 1); + }); + this.on(UA.move, (target, pt, type) => { + let hover = this._within(pt); + if (hover && !this._states.hover) { + this.state('hover', true); + UI._trigger(this._actions[UA.enter], this, pt, UA.enter); + var _capID = this.hold(UA.move); + this._hoverID = this.on(UA.move, (t, p) => { + if (!this._within(p) && !this.state('dragging')) { + this.state('hover', false); + UI._trigger(this._actions[UA.leave], this, pt, UA.leave); + this.off(UA.move, this._hoverID); + this.unhold(_capID); + } + }); + } + }); + } + onClick(fn) { + return this.on(exports.UIPointerActions.up, fn); + } + offClick(id) { + return this.off(exports.UIPointerActions.up, id); + } + onHover(enter, leave) { + var ids = [undefined, undefined]; + if (enter) + ids[0] = this.on(exports.UIPointerActions.enter, enter); + if (leave) + ids[1] = this.on(exports.UIPointerActions.leave, leave); + return ids; + } + offHover(enterID, leaveID) { + var s = [false, false]; + if (enterID === undefined || enterID >= 0) + s[0] = this.off(exports.UIPointerActions.enter, enterID); + if (leaveID === undefined || leaveID >= 0) + s[1] = this.off(exports.UIPointerActions.leave, leaveID); + return s; + } +} +exports.UIButton = UIButton; +class UIDragger extends UIButton { + constructor(group, shape, states = {}, id) { + super(group, shape, states, id); + this._draggingID = -1; + this._moveHoldID = -1; + if (!states.dragging) + states.dragging = false; + if (!states.offset) + states.offset = new Pt_1.Pt(group[0]); + const UA = exports.UIPointerActions; + this.on(UA.down, (target, pt, type) => { + this.state('dragging', true); + this.state('offset', new Pt_1.Pt(pt).subtract(target.group[0])); + this._moveHoldID = this.hold(UA.move); + this._draggingID = this.on(UA.move, (t, p) => { + if (this.state('dragging')) { + UI._trigger(this._actions[UA.uidrag], t, p, UA.uidrag); + } + }); + }); + this.on(UA.up, (target, pt, type) => { + this.state('dragging', false); + this.off(UA.move, this._draggingID); + this.unhold(this._moveHoldID); + UI._trigger(this._actions[UA.drop], target, pt, type); + }); + } + onDrag(fn) { + return this.on(exports.UIPointerActions.uidrag, fn); + } + offDrag(id) { + return this.off(exports.UIPointerActions.uidrag, id); + } + onDrop(fn) { + return this.on(exports.UIPointerActions.drop, fn); + } + offDrop(id) { + return this.off(exports.UIPointerActions.drop, id); + } +} +exports.UIDragger = UIDragger; + + +/***/ }), +/* 9 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); const Pt_1 = __webpack_require__(0); class Typography { @@ -3214,7 +3467,7 @@ exports.Typography = Typography; /***/ }), -/* 9 */ +/* 10 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -3664,7 +3917,7 @@ exports.HTMLForm = HTMLForm; /***/ }), -/* 10 */ +/* 11 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -3683,10 +3936,11 @@ __export(__webpack_require__(0)); __export(__webpack_require__(6)); __export(__webpack_require__(13)); __export(__webpack_require__(1)); -__export(__webpack_require__(9)); +__export(__webpack_require__(10)); __export(__webpack_require__(14)); -__export(__webpack_require__(8)); +__export(__webpack_require__(9)); __export(__webpack_require__(15)); +__export(__webpack_require__(8)); const _Canvas = __webpack_require__(7); exports.namespace = (scope) => { let lib = module.exports; @@ -3713,94 +3967,6 @@ exports.quickStart = (id, bg = "#9ab") => { }; -/***/ }), -/* 11 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const Op_1 = __webpack_require__(2); -var UIShape; -(function (UIShape) { - UIShape[UIShape["Rectangle"] = 0] = "Rectangle"; - UIShape[UIShape["Circle"] = 1] = "Circle"; - UIShape[UIShape["Polygon"] = 2] = "Polygon"; - UIShape[UIShape["Polyline"] = 3] = "Polyline"; - UIShape[UIShape["Line"] = 4] = "Line"; -})(UIShape = exports.UIShape || (exports.UIShape = {})); -exports.UIPointerActions = { - up: "up", down: "down", move: "move", drag: "drag", drop: "drop", over: "over", out: "out" -}; -class UI { - constructor(group, shape, states, id) { - this.group = group; - this.shape = shape; - this._id = id; - this._states = states; - this._actions = {}; - } - get id() { return this._id; } - set id(d) { this._id = d; } - state(key) { - return this._states[key] || false; - } - on(key, fn) { - this._actions[key] = fn; - return this; - } - off(key) { - delete this._actions[key]; - return this; - } - listen(key, p) { - if (this._actions[key] !== undefined) { - if (this._trigger(p)) { - this._actions[key](p, this, key); - return true; - } - } - return false; - } - render(fn) { - fn(this.group, this._states); - } - _trigger(p) { - let fn = null; - if (this.shape === UIShape.Rectangle) { - fn = Op_1.Rectangle.withinBound; - } - else if (this.shape === UIShape.Circle) { - fn = Op_1.Circle.withinBound; - } - else if (this.shape === UIShape.Polygon) { - fn = Op_1.Rectangle.withinBound; - } - else { - return false; - } - return fn(this.group, p); - } -} -exports.UI = UI; -class UIButton extends UI { - constructor(group, shape, states, id) { - super(group, shape, states, id); - this._clicks = 0; - } - get clicks() { return this._clicks; } - onClick(fn) { - this._clicks++; - this.on(exports.UIPointerActions.up, fn); - } - onHover(over, out) { - this.on(exports.UIPointerActions.over, over); - this.on(exports.UIPointerActions.out, out); - } -} -exports.UIButton = UIButton; - - /***/ }), /* 12 */ /***/ (function(module, exports, __webpack_require__) { @@ -4433,7 +4599,7 @@ const Num_1 = __webpack_require__(3); const Util_1 = __webpack_require__(1); const Pt_1 = __webpack_require__(0); const Op_1 = __webpack_require__(2); -const Dom_1 = __webpack_require__(9); +const Dom_1 = __webpack_require__(10); class SVGSpace extends Dom_1.DOMSpace { constructor(elem, callback) { super(elem, callback); diff --git a/dist/pts.min.js b/dist/pts.min.js index b8f23e35..73c52bde 100644 --- a/dist/pts.min.js +++ b/dist/pts.min.js @@ -1,7 +1,7 @@ /*! - * pts.js 0.5.1 (minified es6) - Copyright © 2017-2018 William Ngan and contributors. + * pts.js 0.6.0 (minified es6) - Copyright © 2017-2018 William Ngan and contributors. * Licensed under Apache 2.0 License. * See https://github.com/williamngan/pts for details. */ -(function(e,t){'object'==typeof exports&&'object'==typeof module?module.exports=t():'function'==typeof define&&define.amd?define([],t):'object'==typeof exports?exports.Pts=t():e.Pts=t()})('undefined'==typeof self?this:self,function(){return function(e){function t(i){if(n[i])return n[i].exports;var o=n[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,i){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:i})},t.n=function(e){var n=e&&e.__esModule?function(){return e['default']}:function(){return e};return t.d(n,'a',n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p='',t(t.s=0)}([function(e,t){(function(t,n){e.exports=n()})('undefined'==typeof self?this:self,function(){var e=Math.pow,n=Math.sqrt,o=Math.PI,t=Number.MIN_VALUE,i=Number.MAX_VALUE,a=Math.floor,r=Math.atan2,u=Math.max,l=Math.sin,s=Math.cos,_=Math.min,d=Math.abs;return function(e){function t(i){if(n[i])return n[i].exports;var o=n[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,i){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:i})},t.n=function(e){var n=e&&e.__esModule?function(){return e['default']}:function(){return e};return t.d(n,'a',n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p='',t(t.s=10)}([function(e,t,n){'use strict';Object.defineProperty(t,'__esModule',{value:!0});const i=n(1),o=n(3),c=n(4);t.PtBaseArray=Float32Array;class h extends t.PtBaseArray{constructor(...e){1===e.length&&'number'==typeof e[0]?super(e[0]):super(0t)return!1;return!0}to(...e){let t=i.Util.getArgs(e);for(let n=0,i=_(this.length,t.length);ne(t,...n)}ops(e){let t=[];for(let n=0,i=e.length;ne?[-1*e-1,t]:[e,t];return p.prototype.splice.apply(this,n)}segments(e=2,t=1,n=!1){return this.split(e,t,n)}lines(){return this.segments(2,1)}centroid(){return o.Geom.centroid(this)}boundingBox(){return o.Geom.boundingBox(this)}anchorTo(e=0){o.Geom.anchor(this,e,'to')}anchorFrom(e=0){o.Geom.anchor(this,e,'from')}op(e){let t=this;return(...n)=>e(t,...n)}ops(e){let t=[];for(let n=0,i=e.length;nt?i[e]-n[e]:n[e]-i[e])}forEachPt(e,...t){if(!this[0][e])return i.Util.warn(`${e} is not a function of Pt`),this;for(let n=0,i=this.length;ne+t.toString()+' ','')+' ]'}}t.Group=p;class m extends p{constructor(...e){super(...e),this._center=new h,this._size=new h,this._topLeft=new h,this._bottomRight=new h,this._inited=!1,this.init()}static fromBoundingRect(e){let t=new m(new h(e.left||0,e.top||0),new h(e.right||0,e.bottom||0));return e.width&&e.height&&(t.size=new h(e.width,e.height)),t}static fromGroup(e){if(2>e.length)throw new Error('Cannot create a Bound from a group that has less than 2 Pt');return new m(e[0],e[e.length-1])}init(){if(this.p1&&(this._size=this.p1.clone(),this._inited=!0),this.p1&&this.p2){let e=this.p1,t=this.p2;this.topLeft=e.$min(t),this._bottomRight=e.$max(t),this._updateSize(),this._inited=!0}}clone(){return new m(this._topLeft.clone(),this._bottomRight.clone())}_updateSize(){this._size=this._bottomRight.$subtract(this._topLeft).abs(),this._updateCenter()}_updateCenter(){this._center=this._size.$multiply(.5).add(this._topLeft)}_updatePosFromTop(){this._bottomRight=this._topLeft.$add(this._size),this._updateCenter()}_updatePosFromBottom(){this._topLeft=this._bottomRight.$subtract(this._size),this._updateCenter()}_updatePosFromCenter(){let e=this._size.$multiply(.5);this._topLeft=this._center.$subtract(e),this._bottomRight=this._center.$add(e)}get size(){return new h(this._size)}set size(e){this._size=new h(e),this._updatePosFromTop()}get center(){return new h(this._center)}set center(e){this._center=new h(e),this._updatePosFromCenter()}get topLeft(){return new h(this._topLeft)}set topLeft(e){this._topLeft=new h(e),this[0]=this._topLeft,this._updateSize()}get bottomRight(){return new h(this._bottomRight)}set bottomRight(e){this._bottomRight=new h(e),this[1]=this._bottomRight,this._updateSize()}get width(){return 0e.length)return[];let t=[],n=Array.isArray(e[0])||ArrayBuffer.isView(e[0]);if('number'==typeof e[0])t=Array.prototype.slice.call(e);else if('object'==typeof e[0]&&!n){let n=['x','y','z','w'],o=e[0];for(let e=0;e=o.length||!(n[e]in o));e++)t.push(o[n[e]])}else n&&(t=[].slice.call(e[0]));return t}static warn(e='error',t=void 0){if('error'==l.warnLevel())throw new Error(e);else'warn'==l.warnLevel()&&console.warn(e);return t}static randomInt(e,t=0){return a(Math.random()*e)+t}static split(e,t,n,o=!1){let r=n||t,a=[];for(let s=0;se.length))a.push(e.slice(s*r,s*r+t));else if(o){let n=e.slice(s*r);n=n.concat(e.slice(0,(s*r+t)%t)),a.push(n)}else break;return a}static flatten(e,t=!0){let n=t?new s.Group:[];return n.concat.apply(n,e)}static combine(e,t,n){let o=[];for(let r=0,i=e.length;r=e&&(o=t+(o-e)),i&&i(o),o}}static forRange(e,t,n=0,o=1){let r=[];for(let a=n;ac.Util.warn('Group\'s length is less than '+t,e),m=(e,t='')=>c.Util.warn(`Index ${t} is out of bound in Group`,e);class f{static fromAngle(e,t,n){let i=new P.Group(new P.Pt(e),new P.Pt(e));return i[1].toAngle(t,n,!0),i}static slope(e,t){return 0==t[0]-e[0]?void 0:(t[1]-e[1])/(t[0]-e[0])}static intercept(e,t){if(0==t[0]-e[0])return;else{let n=(t[1]-e[1])/(t[0]-e[0]),i=e[1]-n*e[0];return{slope:n,yi:i,xi:0==n?void 0:-i/n}}}static sideOfPt2D(e,t){return(e[1][0]-e[0][0])*(t[1]-e[0][1])-(t[0]-e[0][0])*(e[1][1]-e[0][1])}static collinear(e,t,n,i=.01){let o=new P.Pt(0,0,0).to(e).$subtract(t),r=new P.Pt(0,0,0).to(e).$subtract(n);return o.$cross(r).divide(1e3).equals(new P.Pt(0,0,0),i)}static magnitude(e){return 2<=e.length?e[1].$subtract(e[0]).magnitude():0}static magnitudeSq(e){return 2<=e.length?e[1].$subtract(e[0]).magnitudeSq():0}static perpendicularFromPt(e,t,n=!1){if(!e[0].equals(e[1])){let i=e[0].$subtract(e[1]),o=e[1].$subtract(t),r=o.$subtract(i.$project(o));return n?r:r.$add(t)}}static distanceFromPt(e,t){return f.perpendicularFromPt(e,t,!0).magnitude()}static intersectRay2D(e,t){let n=f.intercept(e[0],e[1]),i=f.intercept(t[0],t[1]),o=e[0],r=t[0];if(n==void 0){if(i==void 0)return;let e=-i.slope*(r[0]-o[0])+r[1];return new P.Pt(o[0],e)}if(void 0==i){let e=-n.slope*(o[0]-r[0])+o[1];return new P.Pt(r[0],e)}if(i.slope!=n.slope){let e=(n.slope*o[0]-i.slope*r[0]+r[1]-o[1])/(n.slope-i.slope),t=n.slope*(e-o[0])+o[1];return new P.Pt(e,t)}return n.yi==i.yi?new P.Pt(o[0],o[1]):void 0}static intersectLine2D(e,t){let n=f.intersectRay2D(e,t);return n&&p.Geom.withinBound(n,e[0],e[1])&&p.Geom.withinBound(n,t[0],t[1])?n:void 0}static intersectLineWithRay2D(e,t){let n=f.intersectRay2D(e,t);return n&&p.Geom.withinBound(n,e[0],e[1])?n:void 0}static intersectPolygon2D(e,t,n=!1){let o=n?f.intersectLineWithRay2D:f.intersectLine2D,r=new P.Group;for(let a=0,i=t.length;ad(t[1]/t[0])?0>r[1]?0:2:0>r[0]?3:1,f.intersectRay2D(o[a],e)}}static marker(e,n,i='arrow',o=!0){let r=o?0:1,a=o?1:0,t=e[r].$subtract(e[a]);if(0===t.magnitudeSq())return new P.Group;t.unit();let s=p.Geom.perpendicular(t).multiply(n[0]).add(e[a]);return'arrow'==i?(s.add(t.$multiply(n[1])),new P.Group(e[a],s[0],s[1])):new P.Group(s[0],s[1])}static toRect(e){return new P.Group(e[0].$min(e[1]),e[0].$max(e[1]))}}t.Line=f;class y{static from(e,t,n){return y.fromTopLeft(e,t,n)}static fromTopLeft(e,t,n){let i='number'==typeof t?[t,n||t]:t;return new P.Group(new P.Pt(e),new P.Pt(e).add(i))}static fromCenter(e,t,n){let i='number'==typeof t?[t/2,(n||t)/2]:new P.Pt(t).divide(2);return new P.Group(new P.Pt(e).subtract(i),new P.Pt(e).add(i))}static toCircle(e,t=!0){return b.fromRect(e,t)}static toSquare(e,t=!1){let n=y.size(e),i=t?n.maxValue().value:n.minValue().value;return y.fromCenter(y.center(e),i,i)}static size(e){return e[0].$max(e[1]).subtract(e[0].$min(e[1]))}static center(e){let t=e[0].$min(e[1]),n=e[0].$max(e[1]);return t.add(n.$subtract(t).divide(2))}static corners(e){let t=e[0].$min(e[1]),n=e[0].$max(e[1]);return new P.Group(t,new P.Pt(n.x,t.y),n,new P.Pt(t.x,n.y))}static sides(e){let[t,n,i,o]=y.corners(e);return[new P.Group(t,n),new P.Group(n,i),new P.Group(i,o),new P.Group(o,t)]}static boundingBox(e){let t=c.Util.flatten(e,!1),n=P.Pt.make(2,Number.MAX_VALUE),o=P.Pt.make(2,Number.MIN_VALUE);for(let r=0,i=t.length;re;e++)n[e]=_(n[e],t[r][e]),o[e]=u(o[e],t[r][e]);return new P.Group(n,o)}static polygon(e){return y.corners(e)}static quadrants(e,t){let n=y.corners(e),i=t==void 0?y.center(e):new P.Pt(t);return n.map((e)=>new P.Group(e,i).boundingBox())}static halves(e,t=.5,n=!1){let i=e[0].$min(e[1]),o=e[0].$max(e[1]),r=n?p.Num.lerp(i[1],o[1],t):p.Num.lerp(i[0],o[0],t);return n?[new P.Group(i,new P.Pt(o[0],r)),new P.Group(new P.Pt(i[0],r),o)]:[new P.Group(i,new P.Pt(r,o[1])),new P.Group(new P.Pt(r,i[1]),o)]}static withinBound(e,t){return p.Geom.withinBound(t,e[0],e[1])}static hasIntersectRect2D(e,t,n=!1){return n&&(e=p.Geom.boundingBox(e),t=p.Geom.boundingBox(t)),!(e[0][0]>t[1][0]||t[0][0]>e[1][0])&&!(e[0][1]>t[1][1]||t[0][1]>e[1][1])}static intersectRect2D(e,t){return y.hasIntersectRect2D(e,t)?f.intersectLines2D(y.sides(e),y.sides(t)):new P.Group}}t.Rectangle=y;class b{static fromRect(e,t=!1){let i=0,o=i=y.size(e).minValue().value/2;if(t){let t=y.size(e).maxValue().value/2;i=n(o*o+t*t)}else i=o;return new P.Group(y.center(e),new P.Pt(i,i))}static fromCenter(e,t){return new P.Group(new P.Pt(e),new P.Pt(t,t))}static withinBound(e,t,n=0){let i=e[0].$subtract(t);return i.dot(i)+nd)return new P.Group;else{let e=n(d),o=t[0].$subtract(i.$multiply(-l+e));if(0==d)return new P.Group(o);let r=t[0].$subtract(i.$multiply(-l-e));return new P.Group(o,r)}}static intersectLine2D(e,t){let n=b.intersectRay2D(e,t),o=new P.Group;if(0a+s)return new P.Group;if(rr;r++)n.push(e[0].clone().toAngle(t,e[1][0],!0)),t+=2*o/3;return n}return x.fromCenter(e[0],e[1][0])}}t.Circle=b;class x{static fromRect(e){let t=e[0].$add(e[1]).divide(2);t.y=e[0][1];let n=e[1].clone();return n.x=e[0][0],new P.Group(t,e[1].clone(),n)}static fromCircle(e){return b.toTriangle(e,!0)}static fromCenter(e,t){return x.fromCircle(b.fromCenter(e,t))}static medial(e){return 3>e.length?h(new P.Group,3):v.midpoints(e,!0)}static oppositeSide(e,t){return 3>e.length?h(new P.Group,3):0===t?P.Group.fromPtArray([e[1],e[2]]):1===t?P.Group.fromPtArray([e[0],e[2]]):P.Group.fromPtArray([e[0],e[1]])}static altitude(e,t){let n=x.oppositeSide(e,t);return 1e.length)return h(void 0,3);let t=x.altitude(e,0),n=x.altitude(e,1);return f.intersectRay2D(t,n)}static incenter(e){if(3>e.length)return h(void 0,3);let t=v.bisector(e,0).add(e[0]),n=v.bisector(e,1).add(e[1]);return f.intersectRay2D(new P.Group(e[0],t),new P.Group(e[1],n))}static incircle(e,t){let n=t?t:x.incenter(e),i=v.area(e),o=v.perimeter(e,!0),a=2*i/o.total;return b.fromCenter(n,a)}static circumcenter(e){let t=x.medial(e),n=[t[0],p.Geom.perpendicular(e[0].$subtract(t[0])).p1.$add(t[0])],i=[t[1],p.Geom.perpendicular(e[1].$subtract(t[1])).p1.$add(t[1])];return f.intersectRay2D(n,i)}static circumcircle(e,t){let n=t?t:x.circumcenter(e),i=e[0].$subtract(n).magnitude();return b.fromCenter(n,i)}}t.Triangle=x;class v{static centroid(e){return p.Geom.centroid(e)}static rectangle(e,t,n){return y.corners(y.fromCenter(e,t,n))}static fromCenter(e,t,n){let r=new P.Group;for(let a,d=0;dt||t>=e.length)throw new Error('index out of the Polygon\'s range');return new P.Group(e[t],t===e.length-1?e[0]:e[t+1])}static lines(e,t=!0){if(2>e.length)return h(new P.Group,2);let n=c.Util.split(e,2,1);return t&&n.push(new P.Group(e[e.length-1],e[0])),n.map((e)=>e)}static midpoints(e,n=!1,i=.5){if(2>e.length)return h(new P.Group,2);let t=v.lines(e,n),o=t.map((e)=>p.Geom.interpolate(e[0],e[1],i));return o}static adjacentSides(e,t,n=!1){if(2>e.length)return h(new P.Group,2);if(0>t||t>=e.length)return m(new P.Group,t);let i=[],o=t-1;n&&0>o&&(o=e.length-1),0<=o&&i.push(new P.Group(e[t],e[o]));let r=t+1;return n&&r>e.length-1&&(r=0),r<=e.length-1&&i.push(new P.Group(e[t],e[r])),i}static bisector(e,t){let n=v.adjacentSides(e,t,!0);if(2<=n.length){let e=n[0][1].$subtract(n[0][0]).unit(),t=n[1][1].$subtract(n[1][0]).unit();return e.add(t).divide(2)}}static perimeter(e,t=!1){if(2>e.length)return h(new P.Group,2);let n=v.lines(e,t),o=0,r=P.Pt.make(n.length,0);for(let a,s=0,i=n.length;se.length)return h(new P.Group,3);let t=(e,t)=>e[0]*t[1]-e[1]*t[0],n=0;for(let o=0,i=e.length;oe.length)return h(new P.Group,3);t||(e=e.slice(),e.sort((e,t)=>e[0]-t[0]));let n=(e,t,n)=>0<(t[0]-e[0])*(n[1]-e[1])-(n[0]-e[0])*(t[1]-e[1]),o=[],r=e.length-2,a=r+3;o[r]=e[2],o[a]=e[2],n(e[0],e[1],e[2])?(o[r+1]=e[0],o[r+2]=e[1]):(o[r+1]=e[1],o[r+2]=e[0]);for(let s,l=3,i=e.length;lt[1]!=o[1][1]>t[1]&&t[0]<(o[1][0]-o[0][0])*(t[1]-o[0][1])/(o[1][1]-o[0][1])+o[0][0]&&(n=!n);return n}static hasIntersectCircle(e,t){let n={which:-1,dist:0,normal:null,edge:null,vertex:null},o=t[0],s=t[1][0],r=a;for(let a=0,i=e.length;ai&&n.normal.multiply(-1),n.dist=r,n.vertex=o,n}static hasIntersectPolygon(e,t){let n={which:-1,dist:0,normal:new P.Pt,edge:new P.Group,vertex:new P.Pt},o=a;for(let r=0,i=e.length+t.length;rc&&n.normal.multiply(-1);let u=a;for(let o,a=0,i=r.length;ap.Geom.boundingBox(e)),n=c.Util.flatten(t,!1);return t.unshift(p.Geom.boundingBox(n)),t}}t.Polygon=v;class G{static getSteps(e){let n=new P.Group;for(let o,t=0;t<=e;t++)o=t/e,n.push(new P.Pt(o*o*o,o*o,o,1));return n}static controlPoints(e,t=0,n=!1){if(t>e.length-1)return new P.Group;let i=(t)=>te+n.x*t[o],0),i=e.reduce((e,n,o)=>e+n.y*t[o],0);if(2e+n.z*t[o],0);return new P.Pt(n,i,o)}return new P.Pt(n,i)}static catmullRom(e,t=10){if(2>e.length)return new P.Group;let n=new P.Group,o=G.getSteps(t),r=G.controlPoints(e,0,!0);for(let a=0;a<=t;a++)n.push(G.catmullRomStep(o[a],r));for(let i=0;ie.length)return new P.Group;let o=new P.Group,r=G.getSteps(t),a=G.controlPoints(e,0,!0);for(let s=0;s<=t;s++)o.push(G.cardinalStep(r[s],a,n));for(let i=0;ie.length)return new P.Group;let n=new P.Group,o=G.getSteps(t),i=0;for(;ie.length)return new P.Group;let o=new P.Group,r=G.getSteps(t),i=0;for(;in?o-=i:o=_(t,n)&&e<=u(t,n)}static randomRange(e,t=0){let n=e>t?e-t:t-e;return e+Math.random()*n}static normalizeValue(e,t,n){let i=_(t,n),o=u(t,n);return(e-i)/(o-i)}static sum(e){let t=new m.Pt(e[0]);for(let n=1,i=e.length;ne.$min(t)),n=e.reduce((e,t)=>e.$max(t));return new m.Group(t,n)}static centroid(e){return c.average(e)}static anchor(e,t=0,n='to'){let o='to'==n?'subtract':'add';for(let r=0,i=e.length;r{if(2>e.length||2>t.length)throw new Error('Pt dimension cannot be less than 2');let i=e.$subtract(n),o=t.$subtract(n);if(0<=i[0]&&0>o[0])return 1;if(0>i[0]&&0<=o[0])return-1;if(0==i[0]&&0==o[0])return 0<=i[1]||0<=o[1]?i[1]>o[1]?1:-1:o[1]>i[1]?1:-1;let r=i.$cross2D(o);return 0>r?1:0o[0]*o[0]+o[1]*o[1]?1:-1})}static scale(e,t,n){let o=Array.isArray(e)?e:[e],i='number'==typeof t?m.Pt.make(o[0].length,t):t;n||(n=m.Pt.make(o[0].length,0));for(let r,a=0,s=o.length;at;t++)e[t]=s(t*o/180);return{table:e,cos:(t)=>e[a(y.boundAngle(y.toDegree(t)))]}}static sinTable(){let e=new Float64Array(360);for(let t=0;360>t;t++)e[t]=l(t*o/180);return{table:e,sin:(t)=>e[a(y.boundAngle(y.toDegree(t)))]}}}i.Geom=y;class b{static linear(e,t=1){return t*e}static quadraticIn(e,t=1){return t*e*e}static quadraticOut(e,t=1){return-t*e*(e-2)}static quadraticInOut(e,t=1){let n=2*e;return .5>e?4*(t/2*e*e):-t/2*((n-1)*(n-3)-1)}static cubicIn(e,t=1){return t*e*e*e}static cubicOut(e,t=1){let n=e-1;return t*(n*n*n+1)}static cubicInOut(e,t=1){let n=2*e;return .5>e?t/2*n*n*n:t/2*((n-2)*(n-2)*(n-2)+2)}static exponentialIn(n,t=1,i=.25){return t*e(n,1/i)}static exponentialOut(n,t=1,i=.25){return t*e(n,i)}static sineIn(e,t=1){return-t*s(e*g.Const.half_pi)+t}static sineOut(e,t=1){return t*l(e*g.Const.half_pi)}static sineInOut(e,t=1){return-t/2*(s(o*e)-1)}static cosineApprox(e,t=1){let n=e*e,i=n*n;return t*(4*(i*n)/9-17*i/9+22*n/9)}static circularIn(e,t=1){return-t*(n(1-e*e)-1)}static circularOut(e,t=1){let i=e-1;return t*n(1-i*i)}static circularInOut(e,t=1){let i=2*e;return .5>e?-t/2*(n(1-i*i)-1):t/2*(n(1-(i-2)*(i-2))+1)}static elasticIn(n,t=1,i=.7){let o=n-1,r=1.5707963267948966*(i/g.Const.two_pi);return t*(-e(2,10*o)*l((o-r)*g.Const.two_pi/i))}static elasticOut(n,t=1,i=.7){let o=1.5707963267948966*(i/g.Const.two_pi);return t*(e(2,-10*n)*l((n-o)*g.Const.two_pi/i))+t}static elasticInOut(n,t=1,i=.6){let o=2*n,r=1.5707963267948966*(i/g.Const.two_pi);return .5>n?(o-=1,t*(-.5*(e(2,10*o)*l((o-r)*g.Const.two_pi/i)))):(o-=1,t*(.5*(e(2,-10*o)*l((o-r)*g.Const.two_pi/i)))+t)}static bounceIn(e,t=1){return t-b.bounceOut(1-e,t)}static bounceOut(e,t=1){return e<1/2.75?t*(7.5625*e*e):e<2/2.75?(e-=1.5/2.75,t*(7.5625*e*e+.75)):e<2.5/2.75?(e-=2.25/2.75,t*(7.5625*e*e+.9375)):(e-=2.625/2.75,t*(7.5625*e*e+.984375))}static bounceInOut(e,t=1){return .5>e?b.bounceIn(2*e,t)/2:b.bounceOut(2*e-1,t)/2+t/2}static sigmoid(e,t=1,n=10){return t/(1+h(-(n*(e-.5))))}static logSigmoid(e,t=1,n=.7){n=u(g.Const.epsilon,_(1-g.Const.epsilon,n)),n=1/(1-n);let i=1/(1+h(-2*((e-.5)*n))),o=1/(1+h(n)),r=1/(1+h(-n));return t*(i-o)/(r-o)}static seat(n,t=1,i=.5){return .5>n?t*e(2*n,1-i)/2:t*(1-e(2*(1-n),1-i)/2)}static quadraticBezier(e,t=1,i=[.05,.95]){let o='number'==typeof i?i:i[0],r='number'==typeof i?.5:i[1],a=1-2*o;0===a&&(a=g.Const.epsilon);let s=(n(o*o+a*e)-o)/a;return t*((1-2*r)*(s*s)+2*r*s)}static cubicBezier(e,t=1,n=[.1,.7],i=[.9,.2]){let o=new m.Group(new m.Pt(0,0),new m.Pt(n),new m.Pt(i),new m.Pt(1,1));return t*p.Curve.bezierStep(new m.Pt(e*e*e,e*e,e,1),p.Curve.controlPoints(o)).y}static quadraticTarget(e,t=1,n=[.2,.35]){let i=_(1-g.Const.epsilon,u(g.Const.epsilon,n[0])),o=_(1,u(0,n[1])),r=(1-o)/(1-i)-o/i;return t*_(1,u(0,r*(e*e)-(r*(i*i)-o)/i*e))}static cliff(e,t=1,n=.5){return e>n?t:0}static step(e,n,i,t,...o){let r=1/n,s=a(i/r)*r;return e(s,t,...o)}}i.Shaping=b;class x{constructor(e){this._dims=0,this._source=m.Group.fromPtArray(e),this.calc()}get max(){return this._max.clone()}get min(){return this._min.clone()}get magnitude(){return this._mag.clone()}calc(){if(this._source){let e=this._source[0].length;this._dims=e;let t=new m.Pt(e),n=new m.Pt(e),o=new m.Pt(e);for(let r=0;ru(e,t.length),0):e[0].length;for(let a=0;athis._time.end&&(cancelAnimationFrame(this._animID),this._playing=!1)}pause(e=!1){return this._pause=!e||!this._pause,this}resume(){return this._pause=!1,this}stop(e=0){return this._time.end=e,this}playOnce(e=5e3){return this.play(),this.stop(e),this}render(e){return this._renderFunc&&this._renderFunc(e,this),this}set customRendering(e){this._renderFunc=e}get customRendering(){return this._renderFunc}get isPlaying(){return this._playing}get outerBound(){return this.bound.clone()}get innerBound(){return new o.Bound(o.Pt.make(this.size.length,0),this.size.clone())}get size(){return this.bound.size.clone()}get center(){return this.size.divide(2)}get width(){return this.bound.width}get height(){return this.bound.height}}t.Space=r;class a extends r{constructor(){super(...arguments),this._pressed=!1,this._dragged=!1,this._hasMouse=!1,this._hasTouch=!1}get pointer(){let e=this._pointer.clone();return e.id=this._pointer.id,e}bindCanvas(e,t){this._canvas.addEventListener(e,t)}unbindCanvas(e,t){this._canvas.removeEventListener(e,t)}bindMouse(e=!0){return e?(this.bindCanvas('mousedown',this._mouseDown.bind(this)),this.bindCanvas('mouseup',this._mouseUp.bind(this)),this.bindCanvas('mouseover',this._mouseOver.bind(this)),this.bindCanvas('mouseout',this._mouseOut.bind(this)),this.bindCanvas('mousemove',this._mouseMove.bind(this)),this._hasMouse=!0):(this.unbindCanvas('mousedown',this._mouseDown.bind(this)),this.unbindCanvas('mouseup',this._mouseUp.bind(this)),this.unbindCanvas('mouseover',this._mouseOver.bind(this)),this.unbindCanvas('mouseout',this._mouseOut.bind(this)),this.unbindCanvas('mousemove',this._mouseMove.bind(this)),this._hasMouse=!1),this}bindTouch(e=!0){return e?(this.bindCanvas('touchstart',this._mouseDown.bind(this)),this.bindCanvas('touchend',this._mouseUp.bind(this)),this.bindCanvas('touchmove',this._touchMove.bind(this)),this.bindCanvas('touchcancel',this._mouseOut.bind(this)),this._hasTouch=!0):(this.unbindCanvas('touchstart',this._mouseDown.bind(this)),this.unbindCanvas('touchend',this._mouseUp.bind(this)),this.unbindCanvas('touchmove',this._touchMove.bind(this)),this.unbindCanvas('touchcancel',this._mouseOut.bind(this)),this._hasTouch=!1),this}touchesToPoints(e,n='touches'){if(!e||!e[n])return[];let r=[];for(var a=0;a{this._ctx=this._space.ctx,this._ctx.fillStyle=this._style.fillStyle,this._ctx.strokeStyle=this._style.strokeStyle,this._ctx.lineJoin='bevel',this._ctx.font=this._font.value,this._ready=!0}})}get space(){return this._space}useOffscreen(e=!0,t=!1){return t&&this._space.clearOffscreen('string'==typeof t?t:null),this._ctx=this._space.hasOffscreen&&e?this._space.offscreenCtx:this._space.ctx,this}renderOffscreen(e=[0,0]){this._space.hasOffscreen&&this._space.ctx.drawImage(this._space.offscreenCanvas,e[0],e[1],this._space.width,this._space.height)}fill(e){return'boolean'==typeof e?this.filled=e:(this.filled=!0,this._style.fillStyle=e,this._ctx.fillStyle=e),this}stroke(e,t,n,i){return'boolean'==typeof e?this.stroked=e:(this.stroked=!0,this._style.strokeStyle=e,this._ctx.strokeStyle=e,t&&(this._ctx.lineWidth=t,this._style.lineWidth=t),n&&(this._ctx.lineJoin=n,this._style.lineJoin=n),i&&(this._ctx.lineCap=i,this._style.lineCap=i)),this}font(e,t,n,i,o){return'number'==typeof e?(this._font.size=e,o&&(this._font.face=o),t&&(this._font.weight=t),n&&(this._font.style=n),i&&(this._font.lineHeight=i),this._ctx.font=this._font.value):this._font=e,this._estimateTextWidth&&this.fontWidthEstimate(!0),this}fontWidthEstimate(e=!0){return this._estimateTextWidth=e?l.Typography.textWidthEstimator((e)=>this._ctx.measureText(e).width):void 0,this}getTextWidth(e){return this._estimateTextWidth?this._estimateTextWidth(e):this._ctx.measureText(e+' .').width}_textTruncate(e,t,n=''){return l.Typography.truncate(this.getTextWidth.bind(this),e,t,n)}_textAlign(e,t,n,i){i||(i=d.Rectangle.center(e));var o=e[0][0];'end'==this._ctx.textAlign||'right'==this._ctx.textAlign?o=e[1][0]:('center'==this._ctx.textAlign||'middle'==this._ctx.textAlign)&&(o=i[0]);var a=i[1];return'top'==t||'start'==t?a=e[0][1]:('end'==t||'bottom'==t)&&(a=e[1][1]),n?new r.Pt(o+n[0],a+n[1]):new r.Pt(o,a)}reset(){for(let e in this._style)this._style.hasOwnProperty(e)&&(this._ctx[e]=this._style[e]);return this._font=new o.Font,this._ctx.font=this._font.value,this}_paint(){this._filled&&this._ctx.fill(),this._stroked&&this._ctx.stroke()}point(e,t=5,n='square'){if(e){if(!_[n])throw new Error(`${n} is not a static function of CanvasForm`);return _[n](this._ctx,e,t),this._paint(),this}}static circle(e,t,n=10){t&&(e.beginPath(),e.arc(t[0],t[1],n,0,s.Const.two_pi,!1),e.closePath())}circle(e){return _.circle(this._ctx,e[0],e[1][0]),this._paint(),this}static arc(e,t,n,i,o,r){t&&(e.beginPath(),e.arc(t[0],t[1],n,i,o,r))}arc(e,t,n,i,o){return _.arc(this._ctx,e,t,n,i,o),this._paint(),this}static square(e,t,n){if(t){let i=t[0]-n,o=t[1]-n,r=t[0]+n,a=t[1]+n;e.beginPath(),e.moveTo(i,o),e.lineTo(i,a),e.lineTo(r,a),e.lineTo(r,o),e.closePath()}}square(e,t){return _.square(this._ctx,e,t),this._paint(),this}static line(e,t){if(!(2>t.length)){e.beginPath(),e.moveTo(t[0][0],t[0][1]);for(let n=1,i=t.length;nt.length)){e.beginPath(),e.moveTo(t[0][0],t[0][1]);for(let n=1,i=t.length;nt.length||(e.beginPath(),e.moveTo(t[0][0],t[0][1]),e.lineTo(t[0][0],t[1][1]),e.lineTo(t[1][0],t[1][1]),e.lineTo(t[1][0],t[0][1]),e.closePath())}rect(e){return _.rect(this._ctx,e),this._paint(),this}static image(e,n,i=new r.Pt,o){if('number'==typeof i[0])e.drawImage(n,i[0],i[1]);else{let r=i;o?e.drawImage(n,o[0][0],o[0][1],o[1][0]-o[0][0],o[1][1]-o[0][1],r[0][0],r[0][1],r[1][0]-r[0][0],r[1][1]-r[0][1]):e.drawImage(n,r[0][0],r[0][1],r[1][0]-r[0][0],r[1][1]-r[0][1])}}image(e,t,n){return _.image(this._ctx,e,t,n),this}static text(e,t,n,i){t&&e.fillText(n,t[0],t[1],i)}text(e,t,n){return _.text(this._ctx,e,t,n),this}textBox(e,n,i='middle',o='',r=!0){r&&(this._ctx.textBaseline=i);let a=d.Rectangle.size(e),s=this._textTruncate(n,a[0],o);return this.text(this._textAlign(e,i),s[0]),this}paragraphBox(e,t,n=1.2,i='top',o=!0){let a=d.Rectangle.size(e);this._ctx.textBaseline='top';let s=this._font.size*n,l=(e,n=[],i=0)=>{if(!e)return n;if(o&&i*s>a[1]-2*s)return n;if(1e4=d||r[1]===e.length)&&(d=void 0);let c=r[0].substr(0,d);return n.push(c),0>=r[1]||r[1]===e.length?n:l(e.substr(d||r[1]),n,i+1)},c=l(t),p=c.length*s,_=e;if('middle'==i||'center'==i){let t=(a[1]-p)/2;o&&(t=u(0,t)),_=new r.Group(e[0].$add(0,t),e[1].$subtract(0,t))}else _='bottom'==i?new r.Group(e[0].$add(0,a[1]-p),e[1]):new r.Group(e[0],e[0].$add(a[0],p));let h=d.Rectangle.center(_);for(let r=0,a=c.length;re.length*r}static truncate(e,t,n,i=''){let o=a(t.length*_(1,n/e(t)));return ot?_(o,n):0{e.parentNode.removeChild(e)}),super.remove(e)}removeAll(){return this._container.innerHTML='',super.removeAll()}}t.HTMLSpace=l;class d extends o.VisualForm{constructor(e){super(),this._ctx={group:null,groupID:'pts',groupCount:0,currentID:'pts0',currentClass:'',style:{filled:!0,stroked:!0,background:'#f03',"border-color":'#fff',color:'#000',"border-width":'1px',"border-radius":'0',"border-style":'solid',position:'absolute',top:0,left:0,width:0,height:0},font:'11px sans-serif',fontSize:11,fontFamily:'sans-serif'},this._ready=!1,this._space=e,this._space.add({start:()=>{this._ctx.group=this._space.element,this._ctx.groupID='pts_dom_'+d.groupID++,this._ready=!0}})}get space(){return this._space}styleTo(e,t,n=''){if(this._ctx.style[e]===void 0)throw new Error(`${e} style property doesn't exist`);this._ctx.style[e]=`${t}${n}`}fill(e){return'boolean'==typeof e?(this.styleTo('filled',e),!e&&this.styleTo('background','transparent')):(this.styleTo('filled',!0),this.styleTo('background',e)),this}stroke(e,t){return'boolean'==typeof e?(this.styleTo('stroked',e),!e&&this.styleTo('border-width',0)):(this.styleTo('stroked',!0),this.styleTo('border-color',e),this.styleTo('border-width',(t||1)+'px')),this}fillText(e){return this.styleTo('color',e),this}cls(e){return this._ctx.currentClass='boolean'==typeof e?'':e,this}font(e,t,n,i,o){return'number'==typeof e?(this._font.size=e,o&&(this._font.face=o),t&&(this._font.weight=t),n&&(this._font.style=n),i&&(this._font.lineHeight=i),this._ctx.font=this._font.value):this._font=e,this}reset(){return this._ctx.style={filled:!0,stroked:!0,background:'#f03',"border-color":'#fff',"border-width":'1px'},this._font=new o.Font(14,'sans-serif'),this._ctx.font=this._font.value,this}updateScope(e,t){return this._ctx.group=t,this._ctx.groupID=e,this._ctx.groupCount=0,this.nextID(),this._ctx}scope(e){if(!e||null==e.animateID)throw new Error('item not defined or not yet added to Space');return this.updateScope(d.scopeID(e),this.space.element)}nextID(){return this._ctx.groupCount++,this._ctx.currentID=`${this._ctx.groupID}-${this._ctx.groupCount}`,this._ctx.currentID}static getID(e){return e.currentID||`p-${d.domID++}`}static scopeID(e){return`item-${e.animateID}`}static style(e,t){let n=[];for(let i in t.filled||n.push('background: none'),t.stroked||n.push('border: none'),t)if(t.hasOwnProperty(i)&&'filled'!=i&&'stroked'!=i){let e=t[i];if(e)if(!t.filled&&0===i.indexOf('background'))continue;else if(!t.stroked&&0===i.indexOf('border-width'))continue;else n.push(`${i}: ${e}`)}return l.setAttr(e,{style:n.join(';')})}static rectStyle(e,t,n){return e.style.left=t[0]+'px',e.style.top=t[1]+'px',e.style.width=n[0]+'px',e.style.height=n[1]+'px',e}static point(e,t,n=5,i='square'){return'circle'===i?d.circle(e,t,n):d.square(e,t,n)}point(e,t=5,n='square'){return this.nextID(),'circle'==n&&this.styleTo('border-radius','100%'),d.point(this._ctx,e,t,n),this}static circle(e,t,n=10){let i=l.htmlElement(e.group,'div',d.getID(e));return l.setAttr(i,{class:`pts-form pts-circle ${e.currentClass}`}),d.rectStyle(e,new a.Pt(t).$subtract(n),new a.Pt(2*n,2*n)),d.style(i,e.style),i}circle(e){return this.nextID(),this.styleTo('border-radius','100%'),d.circle(this._ctx,e[0],e[1][0]),this}static square(e,t,n){let i=l.htmlElement(e.group,'div',d.getID(e));return l.setAttr(i,{class:`pts-form pts-square ${e.currentClass}`}),d.rectStyle(e,new a.Pt(t).$subtract(n),new a.Pt(2*n,2*n)),d.style(i,e.style),i}square(e,t){return this.nextID(),d.square(this._ctx,e,t),this}static rect(e,t){if(this._checkSize(t)){let n=l.htmlElement(e.group,'div',d.getID(e));return l.setAttr(n,{class:`pts-form pts-rect ${e.currentClass}`}),d.rectStyle(e,t[0],t[1]),d.style(n,e.style),n}}rect(e){return this.nextID(),this.styleTo('border-radius','0'),d.rect(this._ctx,e),this}static text(e,t,n){let i=l.htmlElement(e.group,'div',d.getID(e));return l.setAttr(i,{position:'absolute',class:`pts-form pts-text ${e.currentClass}`,left:t[0],top:t[1]}),i.textContent=n,d.style(i,e.style),i}text(e,t){return this.nextID(),d.text(this._ctx,e,t),this}log(e){return this.fill('#000').stroke('#fff',.5).text([10,14],e),this}arc(){return r.Util.warn('arc is not implemented in HTMLForm'),this}line(){return r.Util.warn('line is not implemented in HTMLForm'),this}polygon(){return r.Util.warn('polygon is not implemented in HTMLForm'),this}}d.groupID=0,d.domID=0,t.HTMLForm=d},function(e,t,n){'use strict';function i(e){for(var n in e)t.hasOwnProperty(n)||(t[n]=e[n])}Object.defineProperty(t,'__esModule',{value:!0}),i(n(7)),i(n(12)),i(n(5)),i(n(4)),i(n(3)),i(n(2)),i(n(0)),i(n(6)),i(n(13)),i(n(1)),i(n(9)),i(n(14)),i(n(8)),i(n(15));const o=n(7);t.namespace=(t)=>{let n=e.exports;for(let e in n)'namespace'!=e&&(t[e]=n[e])},t.quickStart=(e,n='#9ab')=>{let i=window;return t.namespace(i),i.space=new o.CanvasSpace(e).setup({bgcolor:n,resize:!0,retina:!0}),i.form=i.space.getForm(),function(e=null,t=null,n=null,o=null){i.space.add({start:t,animate:e,resize:o,action:n}),i.space.bindMouse().bindTouch().play()}}},function(e,t,n){'use strict';Object.defineProperty(t,'__esModule',{value:!0});const i=n(2);var o;(function(e){e[e.Rectangle=0]='Rectangle',e[e.Circle=1]='Circle',e[e.Polygon=2]='Polygon',e[e.Polyline=3]='Polyline',e[e.Line=4]='Line'})(o=t.UIShape||(t.UIShape={})),t.UIPointerActions={up:'up',down:'down',move:'move',drag:'drag',drop:'drop',over:'over',out:'out'};class r{constructor(e,t,n,i){this.group=e,this.shape=t,this._id=i,this._states=n,this._actions={}}get id(){return this._id}set id(e){this._id=e}state(e){return this._states[e]||!1}on(e,t){return this._actions[e]=t,this}off(e){return delete this._actions[e],this}listen(e,t){return!!(void 0!==this._actions[e]&&this._trigger(t))&&(this._actions[e](t,this,e),!0)}render(e){e(this.group,this._states)}_trigger(e){let t=null;if(this.shape===o.Rectangle)t=i.Rectangle.withinBound;else if(this.shape===o.Circle)t=i.Circle.withinBound;else if(this.shape===o.Polygon)t=i.Rectangle.withinBound;else return!1;return t(this.group,e)}}t.UI=r;class a extends r{constructor(e,t,n,i){super(e,t,n,i),this._clicks=0}get clicks(){return this._clicks}onClick(e){this._clicks++,this.on(t.UIPointerActions.up,e)}onHover(e,n){this.on(t.UIPointerActions.over,e),this.on(t.UIPointerActions.out,n)}}t.UIButton=a},function(e,t,n){'use strict';Object.defineProperty(t,'__esModule',{value:!0});const o=n(0),r=n(2),s=n(1),l=n(3),d=n(4);t.Create=class{static distributeRandom(e,t,n=2){let r=new o.Group;for(let a,s=0;se&&(e*=65536),e=a(e),256>e&&(e|=e<<8);for(let t,n=0;255>n;n++)t=1&n?p[n]^255&e:p[n]^255&e>>8,this.perm[n]=this.perm[n+256]=t}noise2D(){let e=u(0,a(this._n[0]))%255,t=u(0,a(this._n[1]))%255,n=this._n[0]%255-e,i=this._n[1]%255-t,o=d.Vec.dot(c[(e+this.perm[t])%12],[n,i,0]),r=d.Vec.dot(c[(e+this.perm[t+1])%12],[n,i-1,0]),s=d.Vec.dot(c[(e+1+this.perm[t])%12],[n-1,i,0]),p=d.Vec.dot(c[(e+1+this.perm[t+1])%12],[n-1,i-1,0]),_=(e)=>e*e*e*(e*(6*e-15)+10),h=_(n);return l.Num.lerp(l.Num.lerp(o,s,h),l.Num.lerp(r,p,h),_(i))}}t.Noise=h;class i extends o.Group{constructor(){super(...arguments),this._mesh=[]}delaunay(e=!0){if(3>this.length)return[];this._mesh=[];let t=this.length,n=[];for(let o=0;othis[t][0]-this[e][0]);let o=this.slice(),r=this._superTriangle();o=o.concat(r);let a=[this._circum(t,t+1,t+2,r)],l=[],d=[];for(let t=0,r=n.length;tn*n){l.push(t),d.push(t.triangle),a.splice(c,1);continue}i[0]*i[0]+i[1]*i[1]-n*n>s.Const.epsilon||(r.push(t.i,t.j,t.j,t.k,t.k,t.i),a.splice(c,1))}for(i._dedupe(r),c=r.length;1=e.length){let t=(t)=>e[t]||'F';e=`${t(0)}${t(0)}${t(1)}${t(1)}${t(2)}${t(2)}`}let t=1;8===e.length&&(t=e.substr(6)&&1,e=e.substring(0,6));let n=parseInt(e,16);return new m(n>>16,255&n>>8,255&n,t)}static rgb(...e){return m.from(...e).toMode('rgb')}static hsl(...e){return m.from(...e).toMode('hsl')}static hsb(...e){return m.from(...e).toMode('hsb')}static lab(...e){return m.from(...e).toMode('lab')}static lch(...e){return m.from(...e).toMode('lch')}static luv(...e){return m.from(...e).toMode('luv')}static xyz(...e){return m.from(...e).toMode('xyz')}static maxValues(e){return m.ranges[e].zipSlice(1).$take([0,1,2])}get hex(){return this.toString('hex')}get rgb(){return this.toString('rgb')}get rgba(){return this.toString('rgba')}clone(){let e=new m(this);return e.toMode(this._mode),e}toMode(e,t=!1){if(t){let t=this._mode.toUpperCase()+'to'+e.toUpperCase();if(m[t])this.to(m[t](this,this._isNorm,this._isNorm));else throw new Error('Cannot convert color with '+t)}return this._mode=e,this}get mode(){return this._mode}get r(){return this[0]}set r(e){this[0]=e}get g(){return this[1]}set g(e){this[1]=e}get b(){return this[2]}set b(e){this[2]=e}get h(){return'lch'==this._mode?this[2]:this[0]}set h(e){let t='lch'==this._mode?2:0;this[t]=e}get s(){return this[1]}set s(e){this[1]=e}get l(){return'hsl'==this._mode?this[2]:this[0]}set l(e){let t='hsl'==this._mode?2:0;this[t]=e}get a(){return this[1]}set a(e){this[1]=e}get c(){return this[1]}set c(e){this[1]=e}get u(){return this[1]}set u(e){this[1]=e}get v(){return this[2]}set v(e){this[2]=e}get alpha(){return 3n;n++)this[n]=e?p.Num.mapToRange(this[n],t[n][0],t[n][1],0,1):p.Num.mapToRange(this[n],0,1,t[n][0],t[n][1]);return this._isNorm=e,this}$normalize(e=!0){return this.clone().normalize(e)}toString(e='mode'){if('hex'==e){let e=(e)=>{let t=a(e).toString(16);return 2>t.length?'0'+t:t};return`#${e(this[0])}${e(this[1])}${e(this[2])}`}return'rgba'==e?`rgba(${a(this[0])},${a(this[1])},${a(this[2])},${this.alpha}`:'rgb'==e?`rgb(${a(this[0])},${a(this[1])},${a(this[2])}`:`${this._mode}(${this[0]},${this[1]},${this[2]},${this.alpha})`}static RGBtoHSL(e,t=!1,n=!1){let[i,o,r]=t?e:e.$normalize(),a=u(i,o,r),c=_(i,o,r),p=(a+c)/2,h=p,s=p;if(a==c)p=0,h=0;else{let e=a-c;h=.5=r?r*(1+o):r+o-r*o,s=2*r-a,l=(e)=>(e=0>e?e+1:16*e?s+6*((a-s)*e):1>2*e?a:2>3*e?s+6*((a-s)*(2/3-e)):s),d=n?1:255;return m.rgb(d*l(i+1/3),d*l(i),d*l(i-1/3),e.alpha)}static RGBtoHSB(e,t=!1,n=!1){let[i,o,r]=t?e:e.$normalize(),a=u(i,o,r),l=_(i,o,r),c=a-l,d=0,p=0===a?0:c/a;return a!=l&&(a===i?d=(o-r)/c+(oa;a++)r[a]=.04045r;r++)s[r]=0>s[r]?0:.0031308.008856{let t=e*e*e;return .008856{e.parentNode.removeChild(e)}),super.remove(e)}removeAll(){return this._container.innerHTML='',super.removeAll()}}t.SVGSpace=c;class u extends i.VisualForm{constructor(e){super(),this._ctx={group:null,groupID:'pts',groupCount:0,currentID:'pts0',currentClass:'',style:{filled:!0,stroked:!0,fill:'#f03',stroke:'#fff',"stroke-width":1,"stroke-linejoin":'bevel',"stroke-linecap":'sqaure'},font:'11px sans-serif',fontSize:11,fontFamily:'sans-serif'},this._ready=!1,this._space=e,this._space.add({start:()=>{this._ctx.group=this._space.element,this._ctx.groupID='pts_svg_'+u.groupID++,this._ready=!0}})}get space(){return this._space}styleTo(e,t){if(this._ctx.style[e]===void 0)throw new Error(`${e} style property doesn't exist`);this._ctx.style[e]=t}fill(e){return'boolean'==typeof e?this.styleTo('filled',e):(this.styleTo('filled',!0),this.styleTo('fill',e)),this}stroke(e,t,n,i){return'boolean'==typeof e?this.styleTo('stroked',e):(this.styleTo('stroked',!0),this.styleTo('stroke',e),t&&this.styleTo('stroke-width',t),n&&this.styleTo('stroke-linejoin',n),i&&this.styleTo('stroke-linecap',i)),this}cls(e){return this._ctx.currentClass='boolean'==typeof e?'':e,this}font(e,t,n,i,o){return'number'==typeof e?(this._font.size=e,o&&(this._font.face=o),t&&(this._font.weight=t),n&&(this._font.style=n),i&&(this._font.lineHeight=i),this._ctx.font=this._font.value):this._font=e,this}reset(){return this._ctx.style={filled:!0,stroked:!0,fill:'#f03',stroke:'#fff',"stroke-width":1,"stroke-linejoin":'bevel',"stroke-linecap":'sqaure'},this._font=new i.Font(14,'sans-serif'),this._ctx.font=this._font.value,this}updateScope(e,t){return this._ctx.group=t,this._ctx.groupID=e,this._ctx.groupCount=0,this.nextID(),this._ctx}scope(e){if(!e||null==e.animateID)throw new Error('item not defined or not yet added to Space');return this.updateScope(u.scopeID(e),this.space.element)}nextID(){return this._ctx.groupCount++,this._ctx.currentID=`${this._ctx.groupID}-${this._ctx.groupCount}`,this._ctx.currentID}static getID(e){return e.currentID||`p-${u.domID++}`}static scopeID(e){return`item-${e.animateID}`}static style(e,t){let n=[];for(let i in t.filled||n.push('fill: none'),t.stroked||n.push('stroke: none'),t)if(t.hasOwnProperty(i)&&'filled'!=i&&'stroked'!=i){let e=t[i];if(e)if(!t.filled&&0===i.indexOf('fill'))continue;else if(!t.stroked&&0===i.indexOf('stroke'))continue;else n.push(`${i}: ${e}`)}return l.DOMSpace.setAttr(e,{style:n.join(';')})}static point(e,t,n=5,i='square'){return'circle'===i?u.circle(e,t,n):u.square(e,t,n)}point(e,t=5,n='square'){return this.nextID(),u.point(this._ctx,e,t,n),this}static circle(e,t,n=10){let i=c.svgElement(e.group,'circle',u.getID(e));return l.DOMSpace.setAttr(i,{cx:t[0],cy:t[1],r:n,class:`pts-svgform pts-circle ${e.currentClass}`}),u.style(i,e.style),i}circle(e){return this.nextID(),u.circle(this._ctx,e[0],e[1][0]),this}static arc(e,t,n,i,s,p){let _=c.svgElement(e.group,'path',u.getID(e));const h=new a.Pt(t).toAngle(i,n,!0),g=new a.Pt(t).toAngle(s,n,!0),m=o.Geom.boundAngle(s)-o.Geom.boundAngle(i);let f=!!(m>r.Const.pi);p&&(f=!f);const y=p?'0':'1',b=`M ${h[0]} ${h[1]} A ${n} ${n} 0 ${f?'1':'0'} ${y} ${g[0]} ${g[1]}`;return l.DOMSpace.setAttr(_,{d:b,class:`pts-svgform pts-arc ${e.currentClass}`}),u.style(_,e.style),_}arc(e,t,n,i,o){return this.nextID(),u.arc(this._ctx,e,t,n,i,o),this}static square(e,t,n){let i=c.svgElement(e.group,'rect',u.getID(e));return l.DOMSpace.setAttr(i,{x:t[0]-n,y:t[1]-n,width:2*n,height:2*n,class:`pts-svgform pts-square ${e.currentClass}`}),u.style(i,e.style),i}square(e,t){return this.nextID(),u.square(this._ctx,e,t),this}static line(e,t){if(this._checkSize(t)){if(2e+`${t[0]},${t[1]} `,'');return l.DOMSpace.setAttr(i,{points:o,class:`pts-svgform pts-polygon ${e.currentClass}`}),u.style(i,e.style),i}}static polygon(e,t){return u._poly(e,t,!0)}polygon(e){return this.nextID(),u.polygon(this._ctx,e),this}static rect(e,t){if(this._checkSize(t)){let n=c.svgElement(e.group,'rect',u.getID(e)),i=a.Group.fromArray(t).boundingBox(),o=s.Rectangle.size(i);return l.DOMSpace.setAttr(n,{x:i[0][0],y:i[0][1],width:o[0],height:o[1],class:`pts-svgform pts-rect ${e.currentClass}`}),u.style(n,e.style),n}}rect(e){return this.nextID(),u.rect(this._ctx,e),this}static text(e,t,n){let i=c.svgElement(e.group,'text',u.getID(e));return l.DOMSpace.setAttr(i,{"pointer-events":'none',x:t[0],y:t[1],dx:0,dy:0,class:`pts-svgform pts-text ${e.currentClass}`}),i.textContent=n,u.style(i,e.style),i}text(e,t){return this.nextID(),u.text(this._ctx,e,t),this}log(e){return this.fill('#000').stroke('#fff',.5).text([10,14],e),this}}u.groupID=0,u.domID=0,t.SVGForm=u},function(e,t,i){'use strict';Object.defineProperty(t,'__esModule',{value:!0});const o=i(0),r=i(2);class l{constructor(e,t=1,n=0){return this._lastTime=null,this._gravity=new o.Pt,this._friction=1,this._damping=.75,this._particles=[],this._bodies=[],this._names={p:{},b:{}},this._bound=o.Bound.fromGroup(e),this._friction=t,this._gravity='number'==typeof n?new o.Pt(0,n):new o.Pt(n),this}get gravity(){return this._gravity}set gravity(e){this._gravity=e}get friction(){return this._friction}set friction(e){this._friction=e}get damping(){return this._damping}set damping(e){this._damping=e}get bodyCount(){return this._bodies.length}get particleCount(){return this._particles.length}body(e){return this._bodies['string'==typeof e?this._names.b[e]:e]}particle(e){return this._particles['string'==typeof e?this._names.p[e]:e]}update(e){let t=e/1e3;this._updateParticles(t),this._updateBodies(t)}drawParticles(e){this._drawParticles=e}drawBodies(e){this._drawBodies=e}add(e,t){return e instanceof c?(this._bodies.push(e),t&&(this._names.b[t]=this._bodies.length-1)):(this._particles.push(e),t&&(this._names.p[t]=this._particles.length-1)),this}remove(e,t,n=1){let i=0>t?[-1*t-1,n]:[t,n];return'body'==e?this._bodies.splice(i[0],i[1]):this._particles.splice(i[0],i[1]),this}static edgeConstraint(e,t,n,i=1,o=!1){const r=1/(e.mass||1),a=1/(t.mass||1),s=r+a;let l=t.$subtract(e),c=n*n,u=o?n/l.magnitude()-1:c/(l.dot(l)+c)-.5,d=l.$multiply(u*i);return e.subtract(d.$multiply(r/s)),t.add(d.$multiply(a/s)),e}static boundConstraint(e,t,n=.75){let i=t.boundingBox(),r=e.$min(i[1].subtract(e.radius)).$max(i[0].add(e.radius));if(r[0]===i[0][0]||r[0]===i[1][0]){let t=e.changed.$multiply(n);e.previous=r.$subtract(new o.Pt(-t[0],t[1]))}else if(r[1]===i[0][1]||r[1]===i[1][1]){let t=e.changed.$multiply(n);e.previous=r.$subtract(new o.Pt(t[0],-t[1]))}e.to(r)}integrate(e,t,n){return e.addForce(this._gravity),e.verlet(t,this._friction,n),e}_updateParticles(e){for(let t,n=0,i=this._particles.length;ne||e>=this.length)throw new Error('index1 is not in the Group\'s indices');if(0>t||t>=this.length)throw new Error('index1 is not in the Group\'s indices');let i=this[e].$subtract(this[t]).magnitude();return this._cs.push([e,t,i,n||this._stiff]),this}linkAll(e){let t=this.length/2;for(let o,n=0,i=this.length;n=i-1?0:n+1,this.link(n,o,e),4=i-o?n%i:n+o;this.link(n,r,e)}n<=t-1&&this.link(n,_(this.length-1,n+a(t)))}}linksToLines(){let e=[];for(let t,n=0,i=this._cs.length;nd(i[0][1]-i[1][1])?(n.vertex[0]-t[0]-i[0][0])/(i[1][0]-i[0][0]):(n.vertex[1]-t[1]-i[0][1])/(i[1][1]-i[0][1]);let o=1/(e*e+(1-e)*(1-e)),r=n.vertex.body.mass||1,a=n.edge[0].body.mass||1,s=r/(r+a);i[0].subtract(t.$multiply(s*(1-e)*o/2)),i[1].subtract(t.$multiply(s*e*o/2)),n.vertex.add(t.$multiply(a/(r+a)))}}processParticle(e){let t=this,n=r.Polygon.hasIntersectCircle(t,r.Circle.fromCenter(e,e.radius));if(n){let i,t=n.normal.$multiply(n.dist),o=n.edge;i=d(o[0][0]-o[1][0])>d(o[0][1]-o[1][1])?(n.vertex[0]-t[0]-o[0][0])/(o[1][0]-o[0][0]):(n.vertex[1]-t[1]-o[0][1])/(o[1][1]-o[0][1]);let r=1/(i*i+(1-i)*(1-i)),a=n.vertex.mass||e.mass||1,s=n.edge[0].body.mass||1,l=a/(a+s);o[0].subtract(t.$multiply(l*(1-i)*r/2)),o[1].subtract(t.$multiply(l*i*r/2));let c=e.changed.add(t.$multiply(s/(a+s)));e.previous=e.$subtract(c)}}}t.Body=c}])})}])}); +(function(e,t){'object'==typeof exports&&'object'==typeof module?module.exports=t():'function'==typeof define&&define.amd?define([],t):'object'==typeof exports?exports.Pts=t():e.Pts=t()})('undefined'==typeof self?this:self,function(){return function(e){function t(i){if(n[i])return n[i].exports;var o=n[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,i){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:i})},t.n=function(e){var n=e&&e.__esModule?function(){return e['default']}:function(){return e};return t.d(n,'a',n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p='',t(t.s=0)}([function(e,t){(function(t,n){e.exports=n()})('undefined'==typeof self?this:self,function(){var e=Math.pow,n=Math.sqrt,o=Math.PI,t=Number.MIN_VALUE,i=Number.MAX_VALUE,a=Math.floor,r=Math.atan2,u=Math.max,l=Math.sin,s=Math.cos,_=Math.min,d=Math.abs;return function(e){function t(i){if(n[i])return n[i].exports;var o=n[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,i){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:i})},t.n=function(e){var n=e&&e.__esModule?function(){return e['default']}:function(){return e};return t.d(n,'a',n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p='',t(t.s=11)}([function(e,t,n){'use strict';Object.defineProperty(t,'__esModule',{value:!0});const i=n(1),o=n(3),c=n(4);t.PtBaseArray=Float32Array;class h extends t.PtBaseArray{constructor(...e){1===e.length&&'number'==typeof e[0]?super(e[0]):super(0t)return!1;return!0}to(...e){let t=i.Util.getArgs(e);for(let n=0,i=_(this.length,t.length);ne(t,...n)}ops(e){let t=[];for(let n=0,i=e.length;ne?[-1*e-1,t]:[e,t];return p.prototype.splice.apply(this,n)}segments(e=2,t=1,n=!1){return this.split(e,t,n)}lines(){return this.segments(2,1)}centroid(){return o.Geom.centroid(this)}boundingBox(){return o.Geom.boundingBox(this)}anchorTo(e=0){o.Geom.anchor(this,e,'to')}anchorFrom(e=0){o.Geom.anchor(this,e,'from')}op(e){let t=this;return(...n)=>e(t,...n)}ops(e){let t=[];for(let n=0,i=e.length;nt?i[e]-n[e]:n[e]-i[e])}forEachPt(e,...t){if(!this[0][e])return i.Util.warn(`${e} is not a function of Pt`),this;for(let n=0,i=this.length;ne+t.toString()+' ','')+' ]'}}t.Group=p;class m extends p{constructor(...e){super(...e),this._center=new h,this._size=new h,this._topLeft=new h,this._bottomRight=new h,this._inited=!1,this.init()}static fromBoundingRect(e){let t=new m(new h(e.left||0,e.top||0),new h(e.right||0,e.bottom||0));return e.width&&e.height&&(t.size=new h(e.width,e.height)),t}static fromGroup(e){if(2>e.length)throw new Error('Cannot create a Bound from a group that has less than 2 Pt');return new m(e[0],e[e.length-1])}init(){if(this.p1&&(this._size=this.p1.clone(),this._inited=!0),this.p1&&this.p2){let e=this.p1,t=this.p2;this.topLeft=e.$min(t),this._bottomRight=e.$max(t),this._updateSize(),this._inited=!0}}clone(){return new m(this._topLeft.clone(),this._bottomRight.clone())}_updateSize(){this._size=this._bottomRight.$subtract(this._topLeft).abs(),this._updateCenter()}_updateCenter(){this._center=this._size.$multiply(.5).add(this._topLeft)}_updatePosFromTop(){this._bottomRight=this._topLeft.$add(this._size),this._updateCenter()}_updatePosFromBottom(){this._topLeft=this._bottomRight.$subtract(this._size),this._updateCenter()}_updatePosFromCenter(){let e=this._size.$multiply(.5);this._topLeft=this._center.$subtract(e),this._bottomRight=this._center.$add(e)}get size(){return new h(this._size)}set size(e){this._size=new h(e),this._updatePosFromTop()}get center(){return new h(this._center)}set center(e){this._center=new h(e),this._updatePosFromCenter()}get topLeft(){return new h(this._topLeft)}set topLeft(e){this._topLeft=new h(e),this[0]=this._topLeft,this._updateSize()}get bottomRight(){return new h(this._bottomRight)}set bottomRight(e){this._bottomRight=new h(e),this[1]=this._bottomRight,this._updateSize()}get width(){return 0e.length)return[];let t=[],n=Array.isArray(e[0])||ArrayBuffer.isView(e[0]);if('number'==typeof e[0])t=Array.prototype.slice.call(e);else if('object'==typeof e[0]&&!n){let n=['x','y','z','w'],o=e[0];for(let e=0;e=o.length||!(n[e]in o));e++)t.push(o[n[e]])}else n&&(t=[].slice.call(e[0]));return t}static warn(e='error',t=void 0){if('error'==l.warnLevel())throw new Error(e);else'warn'==l.warnLevel()&&console.warn(e);return t}static randomInt(e,t=0){return a(Math.random()*e)+t}static split(e,t,n,o=!1){let r=n||t,a=[];for(let s=0;se.length))a.push(e.slice(s*r,s*r+t));else if(o){let n=e.slice(s*r);n=n.concat(e.slice(0,(s*r+t)%t)),a.push(n)}else break;return a}static flatten(e,t=!0){let n=t?new s.Group:[];return n.concat.apply(n,e)}static combine(e,t,n){let o=[];for(let r=0,i=e.length;r=e&&(o=t+(o-e)),i&&i(o),o}}static forRange(e,t,n=0,o=1){let r=[];for(let a=n;ac.Util.warn('Group\'s length is less than '+t,e),m=(e,t='')=>c.Util.warn(`Index ${t} is out of bound in Group`,e);class f{static fromAngle(e,t,n){let i=new P.Group(new P.Pt(e),new P.Pt(e));return i[1].toAngle(t,n,!0),i}static slope(e,t){return 0==t[0]-e[0]?void 0:(t[1]-e[1])/(t[0]-e[0])}static intercept(e,t){if(0==t[0]-e[0])return;else{let n=(t[1]-e[1])/(t[0]-e[0]),i=e[1]-n*e[0];return{slope:n,yi:i,xi:0==n?void 0:-i/n}}}static sideOfPt2D(e,t){return(e[1][0]-e[0][0])*(t[1]-e[0][1])-(t[0]-e[0][0])*(e[1][1]-e[0][1])}static collinear(e,t,n,i=.01){let o=new P.Pt(0,0,0).to(e).$subtract(t),r=new P.Pt(0,0,0).to(e).$subtract(n);return o.$cross(r).divide(1e3).equals(new P.Pt(0,0,0),i)}static magnitude(e){return 2<=e.length?e[1].$subtract(e[0]).magnitude():0}static magnitudeSq(e){return 2<=e.length?e[1].$subtract(e[0]).magnitudeSq():0}static perpendicularFromPt(e,t,n=!1){if(!e[0].equals(e[1])){let i=e[0].$subtract(e[1]),o=e[1].$subtract(t),r=o.$subtract(i.$project(o));return n?r:r.$add(t)}}static distanceFromPt(e,t){return f.perpendicularFromPt(e,t,!0).magnitude()}static intersectRay2D(e,t){let n=f.intercept(e[0],e[1]),i=f.intercept(t[0],t[1]),o=e[0],r=t[0];if(n==void 0){if(i==void 0)return;let e=-i.slope*(r[0]-o[0])+r[1];return new P.Pt(o[0],e)}if(void 0==i){let e=-n.slope*(o[0]-r[0])+o[1];return new P.Pt(r[0],e)}if(i.slope!=n.slope){let e=(n.slope*o[0]-i.slope*r[0]+r[1]-o[1])/(n.slope-i.slope),t=n.slope*(e-o[0])+o[1];return new P.Pt(e,t)}return n.yi==i.yi?new P.Pt(o[0],o[1]):void 0}static intersectLine2D(e,t){let n=f.intersectRay2D(e,t);return n&&p.Geom.withinBound(n,e[0],e[1])&&p.Geom.withinBound(n,t[0],t[1])?n:void 0}static intersectLineWithRay2D(e,t){let n=f.intersectRay2D(e,t);return n&&p.Geom.withinBound(n,e[0],e[1])?n:void 0}static intersectPolygon2D(e,t,n=!1){let o=n?f.intersectLineWithRay2D:f.intersectLine2D,r=new P.Group;for(let a=0,i=t.length;ad(t[1]/t[0])?0>r[1]?0:2:0>r[0]?3:1,f.intersectRay2D(o[a],e)}}static marker(e,n,i='arrow',o=!0){let r=o?0:1,a=o?1:0,t=e[r].$subtract(e[a]);if(0===t.magnitudeSq())return new P.Group;t.unit();let s=p.Geom.perpendicular(t).multiply(n[0]).add(e[a]);return'arrow'==i?(s.add(t.$multiply(n[1])),new P.Group(e[a],s[0],s[1])):new P.Group(s[0],s[1])}static toRect(e){return new P.Group(e[0].$min(e[1]),e[0].$max(e[1]))}}t.Line=f;class y{static from(e,t,n){return y.fromTopLeft(e,t,n)}static fromTopLeft(e,t,n){let i='number'==typeof t?[t,n||t]:t;return new P.Group(new P.Pt(e),new P.Pt(e).add(i))}static fromCenter(e,t,n){let i='number'==typeof t?[t/2,(n||t)/2]:new P.Pt(t).divide(2);return new P.Group(new P.Pt(e).subtract(i),new P.Pt(e).add(i))}static toCircle(e,t=!0){return b.fromRect(e,t)}static toSquare(e,t=!1){let n=y.size(e),i=t?n.maxValue().value:n.minValue().value;return y.fromCenter(y.center(e),i,i)}static size(e){return e[0].$max(e[1]).subtract(e[0].$min(e[1]))}static center(e){let t=e[0].$min(e[1]),n=e[0].$max(e[1]);return t.add(n.$subtract(t).divide(2))}static corners(e){let t=e[0].$min(e[1]),n=e[0].$max(e[1]);return new P.Group(t,new P.Pt(n.x,t.y),n,new P.Pt(t.x,n.y))}static sides(e){let[t,n,i,o]=y.corners(e);return[new P.Group(t,n),new P.Group(n,i),new P.Group(i,o),new P.Group(o,t)]}static boundingBox(e){let t=c.Util.flatten(e,!1),n=P.Pt.make(2,Number.MAX_VALUE),o=P.Pt.make(2,Number.MIN_VALUE);for(let r=0,i=t.length;re;e++)n[e]=_(n[e],t[r][e]),o[e]=u(o[e],t[r][e]);return new P.Group(n,o)}static polygon(e){return y.corners(e)}static quadrants(e,t){let n=y.corners(e),i=t==void 0?y.center(e):new P.Pt(t);return n.map((e)=>new P.Group(e,i).boundingBox())}static halves(e,t=.5,n=!1){let i=e[0].$min(e[1]),o=e[0].$max(e[1]),r=n?p.Num.lerp(i[1],o[1],t):p.Num.lerp(i[0],o[0],t);return n?[new P.Group(i,new P.Pt(o[0],r)),new P.Group(new P.Pt(i[0],r),o)]:[new P.Group(i,new P.Pt(r,o[1])),new P.Group(new P.Pt(r,i[1]),o)]}static withinBound(e,t){return p.Geom.withinBound(t,e[0],e[1])}static hasIntersectRect2D(e,t,n=!1){return n&&(e=p.Geom.boundingBox(e),t=p.Geom.boundingBox(t)),!(e[0][0]>t[1][0]||t[0][0]>e[1][0])&&!(e[0][1]>t[1][1]||t[0][1]>e[1][1])}static intersectRect2D(e,t){return y.hasIntersectRect2D(e,t)?f.intersectLines2D(y.sides(e),y.sides(t)):new P.Group}}t.Rectangle=y;class b{static fromRect(e,t=!1){let i=0,o=i=y.size(e).minValue().value/2;if(t){let t=y.size(e).maxValue().value/2;i=n(o*o+t*t)}else i=o;return new P.Group(y.center(e),new P.Pt(i,i))}static fromTriangle(e,t=!1){return t?x.circumcircle(e):x.incircle(e)}static fromCenter(e,t){return new P.Group(new P.Pt(e),new P.Pt(t,t))}static withinBound(e,t,n=0){let i=e[0].$subtract(t);return i.dot(i)+nd)return new P.Group;else{let e=n(d),o=t[0].$subtract(i.$multiply(-l+e));if(0==d)return new P.Group(o);let r=t[0].$subtract(i.$multiply(-l-e));return new P.Group(o,r)}}static intersectLine2D(e,t){let n=b.intersectRay2D(e,t),o=new P.Group;if(0a+s)return new P.Group;if(rr;r++)n.push(e[0].clone().toAngle(t,e[1][0],!0)),t+=2*o/3;return n}return x.fromCenter(e[0],e[1][0])}}t.Circle=b;class x{static fromRect(e){let t=e[0].$add(e[1]).divide(2);t.y=e[0][1];let n=e[1].clone();return n.x=e[0][0],new P.Group(t,e[1].clone(),n)}static fromCircle(e){return b.toTriangle(e,!0)}static fromCenter(e,t){return x.fromCircle(b.fromCenter(e,t))}static medial(e){return 3>e.length?h(new P.Group,3):v.midpoints(e,!0)}static oppositeSide(e,t){return 3>e.length?h(new P.Group,3):0===t?P.Group.fromPtArray([e[1],e[2]]):1===t?P.Group.fromPtArray([e[0],e[2]]):P.Group.fromPtArray([e[0],e[1]])}static altitude(e,t){let n=x.oppositeSide(e,t);return 1e.length)return h(void 0,3);let t=x.altitude(e,0),n=x.altitude(e,1);return f.intersectRay2D(t,n)}static incenter(e){if(3>e.length)return h(void 0,3);let t=v.bisector(e,0).add(e[0]),n=v.bisector(e,1).add(e[1]);return f.intersectRay2D(new P.Group(e[0],t),new P.Group(e[1],n))}static incircle(e,t){let n=t?t:x.incenter(e),i=v.area(e),o=v.perimeter(e,!0),a=2*i/o.total;return b.fromCenter(n,a)}static circumcenter(e){let t=x.medial(e),n=[t[0],p.Geom.perpendicular(e[0].$subtract(t[0])).p1.$add(t[0])],i=[t[1],p.Geom.perpendicular(e[1].$subtract(t[1])).p1.$add(t[1])];return f.intersectRay2D(n,i)}static circumcircle(e,t){let n=t?t:x.circumcenter(e),i=e[0].$subtract(n).magnitude();return b.fromCenter(n,i)}}t.Triangle=x;class v{static centroid(e){return p.Geom.centroid(e)}static rectangle(e,t,n){return y.corners(y.fromCenter(e,t,n))}static fromCenter(e,t,n){let r=new P.Group;for(let a,d=0;dt||t>=e.length)throw new Error('index out of the Polygon\'s range');return new P.Group(e[t],t===e.length-1?e[0]:e[t+1])}static lines(e,t=!0){if(2>e.length)return h(new P.Group,2);let n=c.Util.split(e,2,1);return t&&n.push(new P.Group(e[e.length-1],e[0])),n.map((e)=>e)}static midpoints(e,n=!1,i=.5){if(2>e.length)return h(new P.Group,2);let t=v.lines(e,n),o=t.map((e)=>p.Geom.interpolate(e[0],e[1],i));return o}static adjacentSides(e,t,n=!1){if(2>e.length)return h(new P.Group,2);if(0>t||t>=e.length)return m(new P.Group,t);let i=[],o=t-1;n&&0>o&&(o=e.length-1),0<=o&&i.push(new P.Group(e[t],e[o]));let r=t+1;return n&&r>e.length-1&&(r=0),r<=e.length-1&&i.push(new P.Group(e[t],e[r])),i}static bisector(e,t){let n=v.adjacentSides(e,t,!0);if(2<=n.length){let e=n[0][1].$subtract(n[0][0]).unit(),t=n[1][1].$subtract(n[1][0]).unit();return e.add(t).divide(2)}}static perimeter(e,t=!1){if(2>e.length)return h(new P.Group,2);let n=v.lines(e,t),o=0,r=P.Pt.make(n.length,0);for(let a,s=0,i=n.length;se.length)return h(new P.Group,3);let t=(e,t)=>e[0]*t[1]-e[1]*t[0],n=0;for(let o=0,i=e.length;oe.length)return h(new P.Group,3);t||(e=e.slice(),e.sort((e,t)=>e[0]-t[0]));let n=(e,t,n)=>0<(t[0]-e[0])*(n[1]-e[1])-(n[0]-e[0])*(t[1]-e[1]),o=[],r=e.length-2,a=r+3;o[r]=e[2],o[a]=e[2],n(e[0],e[1],e[2])?(o[r+1]=e[0],o[r+2]=e[1]):(o[r+1]=e[1],o[r+2]=e[0]);for(let s,l=3,i=e.length;lt[1]!=o[1][1]>t[1]&&t[0]<(o[1][0]-o[0][0])*(t[1]-o[0][1])/(o[1][1]-o[0][1])+o[0][0]&&(n=!n);return n}static hasIntersectCircle(e,t){let n={which:-1,dist:0,normal:null,edge:null,vertex:null},o=t[0],s=t[1][0],r=a;for(let a=0,i=e.length;ai&&n.normal.multiply(-1),n.dist=r,n.vertex=o,n}static hasIntersectPolygon(e,t){let n={which:-1,dist:0,normal:new P.Pt,edge:new P.Group,vertex:new P.Pt},o=a;for(let r=0,i=e.length+t.length;rc&&n.normal.multiply(-1);let u=a;for(let o,a=0,i=r.length;ap.Geom.boundingBox(e)),n=c.Util.flatten(t,!1);return t.unshift(p.Geom.boundingBox(n)),t}}t.Polygon=v;class G{static getSteps(e){let n=new P.Group;for(let o,t=0;t<=e;t++)o=t/e,n.push(new P.Pt(o*o*o,o*o,o,1));return n}static controlPoints(e,t=0,n=!1){if(t>e.length-1)return new P.Group;let i=(t)=>te+n.x*t[o],0),i=e.reduce((e,n,o)=>e+n.y*t[o],0);if(2e+n.z*t[o],0);return new P.Pt(n,i,o)}return new P.Pt(n,i)}static catmullRom(e,t=10){if(2>e.length)return new P.Group;let n=new P.Group,o=G.getSteps(t),r=G.controlPoints(e,0,!0);for(let a=0;a<=t;a++)n.push(G.catmullRomStep(o[a],r));for(let i=0;ie.length)return new P.Group;let o=new P.Group,r=G.getSteps(t),a=G.controlPoints(e,0,!0);for(let s=0;s<=t;s++)o.push(G.cardinalStep(r[s],a,n));for(let i=0;ie.length)return new P.Group;let n=new P.Group,o=G.getSteps(t),i=0;for(;ie.length)return new P.Group;let o=new P.Group,r=G.getSteps(t),i=0;for(;in?o-=i:o=_(t,n)&&e<=u(t,n)}static randomRange(e,t=0){let n=e>t?e-t:t-e;return e+Math.random()*n}static normalizeValue(e,t,n){let i=_(t,n),o=u(t,n);return(e-i)/(o-i)}static sum(e){let t=new m.Pt(e[0]);for(let n=1,i=e.length;ne.$min(t)),n=e.reduce((e,t)=>e.$max(t));return new m.Group(t,n)}static centroid(e){return c.average(e)}static anchor(e,t=0,n='to'){let o='to'==n?'subtract':'add';for(let r=0,i=e.length;r{if(2>e.length||2>t.length)throw new Error('Pt dimension cannot be less than 2');let i=e.$subtract(n),o=t.$subtract(n);if(0<=i[0]&&0>o[0])return 1;if(0>i[0]&&0<=o[0])return-1;if(0==i[0]&&0==o[0])return 0<=i[1]||0<=o[1]?i[1]>o[1]?1:-1:o[1]>i[1]?1:-1;let r=i.$cross2D(o);return 0>r?1:0o[0]*o[0]+o[1]*o[1]?1:-1})}static scale(e,t,n){let o=Array.isArray(e)?e:[e],i='number'==typeof t?m.Pt.make(o[0].length,t):t;n||(n=m.Pt.make(o[0].length,0));for(let r,a=0,s=o.length;at;t++)e[t]=s(t*o/180);return{table:e,cos:(t)=>e[a(y.boundAngle(y.toDegree(t)))]}}static sinTable(){let e=new Float64Array(360);for(let t=0;360>t;t++)e[t]=l(t*o/180);return{table:e,sin:(t)=>e[a(y.boundAngle(y.toDegree(t)))]}}}i.Geom=y;class b{static linear(e,t=1){return t*e}static quadraticIn(e,t=1){return t*e*e}static quadraticOut(e,t=1){return-t*e*(e-2)}static quadraticInOut(e,t=1){let n=2*e;return .5>e?4*(t/2*e*e):-t/2*((n-1)*(n-3)-1)}static cubicIn(e,t=1){return t*e*e*e}static cubicOut(e,t=1){let n=e-1;return t*(n*n*n+1)}static cubicInOut(e,t=1){let n=2*e;return .5>e?t/2*n*n*n:t/2*((n-2)*(n-2)*(n-2)+2)}static exponentialIn(n,t=1,i=.25){return t*e(n,1/i)}static exponentialOut(n,t=1,i=.25){return t*e(n,i)}static sineIn(e,t=1){return-t*s(e*h.Const.half_pi)+t}static sineOut(e,t=1){return t*l(e*h.Const.half_pi)}static sineInOut(e,t=1){return-t/2*(s(o*e)-1)}static cosineApprox(e,t=1){let n=e*e,i=n*n;return t*(4*(i*n)/9-17*i/9+22*n/9)}static circularIn(e,t=1){return-t*(n(1-e*e)-1)}static circularOut(e,t=1){let i=e-1;return t*n(1-i*i)}static circularInOut(e,t=1){let i=2*e;return .5>e?-t/2*(n(1-i*i)-1):t/2*(n(1-(i-2)*(i-2))+1)}static elasticIn(n,t=1,i=.7){let o=n-1,r=1.5707963267948966*(i/h.Const.two_pi);return t*(-e(2,10*o)*l((o-r)*h.Const.two_pi/i))}static elasticOut(n,t=1,i=.7){let o=1.5707963267948966*(i/h.Const.two_pi);return t*(e(2,-10*n)*l((n-o)*h.Const.two_pi/i))+t}static elasticInOut(n,t=1,i=.6){let o=2*n,r=1.5707963267948966*(i/h.Const.two_pi);return .5>n?(o-=1,t*(-.5*(e(2,10*o)*l((o-r)*h.Const.two_pi/i)))):(o-=1,t*(.5*(e(2,-10*o)*l((o-r)*h.Const.two_pi/i)))+t)}static bounceIn(e,t=1){return t-b.bounceOut(1-e,t)}static bounceOut(e,t=1){return e<1/2.75?t*(7.5625*e*e):e<2/2.75?(e-=1.5/2.75,t*(7.5625*e*e+.75)):e<2.5/2.75?(e-=2.25/2.75,t*(7.5625*e*e+.9375)):(e-=2.625/2.75,t*(7.5625*e*e+.984375))}static bounceInOut(e,t=1){return .5>e?b.bounceIn(2*e,t)/2:b.bounceOut(2*e-1,t)/2+t/2}static sigmoid(e,t=1,n=10){return t/(1+g(-(n*(e-.5))))}static logSigmoid(e,t=1,n=.7){n=u(h.Const.epsilon,_(1-h.Const.epsilon,n)),n=1/(1-n);let i=1/(1+g(-2*((e-.5)*n))),o=1/(1+g(n)),r=1/(1+g(-n));return t*(i-o)/(r-o)}static seat(n,t=1,i=.5){return .5>n?t*e(2*n,1-i)/2:t*(1-e(2*(1-n),1-i)/2)}static quadraticBezier(e,t=1,i=[.05,.95]){let o='number'==typeof i?i:i[0],r='number'==typeof i?.5:i[1],a=1-2*o;0===a&&(a=h.Const.epsilon);let s=(n(o*o+a*e)-o)/a;return t*((1-2*r)*(s*s)+2*r*s)}static cubicBezier(e,t=1,n=[.1,.7],i=[.9,.2]){let o=new m.Group(new m.Pt(0,0),new m.Pt(n),new m.Pt(i),new m.Pt(1,1));return t*p.Curve.bezierStep(new m.Pt(e*e*e,e*e,e,1),p.Curve.controlPoints(o)).y}static quadraticTarget(e,t=1,n=[.2,.35]){let i=_(1-h.Const.epsilon,u(h.Const.epsilon,n[0])),o=_(1,u(0,n[1])),r=(1-o)/(1-i)-o/i;return t*_(1,u(0,r*(e*e)-(r*(i*i)-o)/i*e))}static cliff(e,t=1,n=.5){return e>n?t:0}static step(e,n,i,t,...o){let r=1/n,s=a(i/r)*r;return e(s,t,...o)}}i.Shaping=b;class x{constructor(e){this._dims=0,this._source=m.Group.fromPtArray(e),this.calc()}get max(){return this._max.clone()}get min(){return this._min.clone()}get magnitude(){return this._mag.clone()}calc(){if(this._source){let e=this._source[0].length;this._dims=e;let t=new m.Pt(e),n=new m.Pt(e),o=new m.Pt(e);for(let r=0;ru(e,t.length),0):e[0].length;for(let a=0;athis._time.end&&(cancelAnimationFrame(this._animID),this._playing=!1)}pause(e=!1){return this._pause=!e||!this._pause,this}resume(){return this._pause=!1,this}stop(e=0){return this._time.end=e,this}playOnce(e=5e3){return this.play(),this.stop(e),this}render(e){return this._renderFunc&&this._renderFunc(e,this),this}set customRendering(e){this._renderFunc=e}get customRendering(){return this._renderFunc}get isPlaying(){return this._playing}get outerBound(){return this.bound.clone()}get innerBound(){return new o.Bound(o.Pt.make(this.size.length,0),this.size.clone())}get size(){return this.bound.size.clone()}get center(){return this.size.divide(2)}get width(){return this.bound.width}get height(){return this.bound.height}}t.Space=r;class a extends r{constructor(){super(...arguments),this._pressed=!1,this._dragged=!1,this._hasMouse=!1,this._hasTouch=!1}get pointer(){let e=this._pointer.clone();return e.id=this._pointer.id,e}bindCanvas(e,t){this._canvas.addEventListener(e,t)}unbindCanvas(e,t){this._canvas.removeEventListener(e,t)}bindMouse(e=!0){return e?(this.bindCanvas('mousedown',this._mouseDown.bind(this)),this.bindCanvas('mouseup',this._mouseUp.bind(this)),this.bindCanvas('mouseover',this._mouseOver.bind(this)),this.bindCanvas('mouseout',this._mouseOut.bind(this)),this.bindCanvas('mousemove',this._mouseMove.bind(this)),this._hasMouse=!0):(this.unbindCanvas('mousedown',this._mouseDown.bind(this)),this.unbindCanvas('mouseup',this._mouseUp.bind(this)),this.unbindCanvas('mouseover',this._mouseOver.bind(this)),this.unbindCanvas('mouseout',this._mouseOut.bind(this)),this.unbindCanvas('mousemove',this._mouseMove.bind(this)),this._hasMouse=!1),this}bindTouch(e=!0){return e?(this.bindCanvas('touchstart',this._mouseDown.bind(this)),this.bindCanvas('touchend',this._mouseUp.bind(this)),this.bindCanvas('touchmove',this._touchMove.bind(this)),this.bindCanvas('touchcancel',this._mouseOut.bind(this)),this._hasTouch=!0):(this.unbindCanvas('touchstart',this._mouseDown.bind(this)),this.unbindCanvas('touchend',this._mouseUp.bind(this)),this.unbindCanvas('touchmove',this._touchMove.bind(this)),this.unbindCanvas('touchcancel',this._mouseOut.bind(this)),this._hasTouch=!1),this}touchesToPoints(e,n='touches'){if(!e||!e[n])return[];let r=[];for(var a=0;a{this._ctx=this._space.ctx,this._ctx.fillStyle=this._style.fillStyle,this._ctx.strokeStyle=this._style.strokeStyle,this._ctx.lineJoin='bevel',this._ctx.font=this._font.value,this._ready=!0}})}get space(){return this._space}useOffscreen(e=!0,t=!1){return t&&this._space.clearOffscreen('string'==typeof t?t:null),this._ctx=this._space.hasOffscreen&&e?this._space.offscreenCtx:this._space.ctx,this}renderOffscreen(e=[0,0]){this._space.hasOffscreen&&this._space.ctx.drawImage(this._space.offscreenCanvas,e[0],e[1],this._space.width,this._space.height)}fill(e){return'boolean'==typeof e?this.filled=e:(this.filled=!0,this._style.fillStyle=e,this._ctx.fillStyle=e),this}stroke(e,t,n,i){return'boolean'==typeof e?this.stroked=e:(this.stroked=!0,this._style.strokeStyle=e,this._ctx.strokeStyle=e,t&&(this._ctx.lineWidth=t,this._style.lineWidth=t),n&&(this._ctx.lineJoin=n,this._style.lineJoin=n),i&&(this._ctx.lineCap=i,this._style.lineCap=i)),this}font(e,t,n,i,o){return'number'==typeof e?(this._font.size=e,o&&(this._font.face=o),t&&(this._font.weight=t),n&&(this._font.style=n),i&&(this._font.lineHeight=i),this._ctx.font=this._font.value):this._font=e,this._estimateTextWidth&&this.fontWidthEstimate(!0),this}fontWidthEstimate(e=!0){return this._estimateTextWidth=e?l.Typography.textWidthEstimator((e)=>this._ctx.measureText(e).width):void 0,this}getTextWidth(e){return this._estimateTextWidth?this._estimateTextWidth(e):this._ctx.measureText(e+' .').width}_textTruncate(e,t,n=''){return l.Typography.truncate(this.getTextWidth.bind(this),e,t,n)}_textAlign(e,t,n,i){i||(i=d.Rectangle.center(e));var o=e[0][0];'end'==this._ctx.textAlign||'right'==this._ctx.textAlign?o=e[1][0]:('center'==this._ctx.textAlign||'middle'==this._ctx.textAlign)&&(o=i[0]);var a=i[1];return'top'==t||'start'==t?a=e[0][1]:('end'==t||'bottom'==t)&&(a=e[1][1]),n?new r.Pt(o+n[0],a+n[1]):new r.Pt(o,a)}reset(){for(let e in this._style)this._style.hasOwnProperty(e)&&(this._ctx[e]=this._style[e]);return this._font=new o.Font,this._ctx.font=this._font.value,this}_paint(){this._filled&&this._ctx.fill(),this._stroked&&this._ctx.stroke()}point(e,t=5,n='square'){if(e){if(!_[n])throw new Error(`${n} is not a static function of CanvasForm`);return _[n](this._ctx,e,t),this._paint(),this}}static circle(e,t,n=10){t&&(e.beginPath(),e.arc(t[0],t[1],n,0,s.Const.two_pi,!1),e.closePath())}circle(e){return _.circle(this._ctx,e[0],e[1][0]),this._paint(),this}static arc(e,t,n,i,o,r){t&&(e.beginPath(),e.arc(t[0],t[1],n,i,o,r))}arc(e,t,n,i,o){return _.arc(this._ctx,e,t,n,i,o),this._paint(),this}static square(e,t,n){if(t){let i=t[0]-n,o=t[1]-n,r=t[0]+n,a=t[1]+n;e.beginPath(),e.moveTo(i,o),e.lineTo(i,a),e.lineTo(r,a),e.lineTo(r,o),e.closePath()}}square(e,t){return _.square(this._ctx,e,t),this._paint(),this}static line(e,t){if(!(2>t.length)){e.beginPath(),e.moveTo(t[0][0],t[0][1]);for(let n=1,i=t.length;nt.length)){e.beginPath(),e.moveTo(t[0][0],t[0][1]);for(let n=1,i=t.length;nt.length||(e.beginPath(),e.moveTo(t[0][0],t[0][1]),e.lineTo(t[0][0],t[1][1]),e.lineTo(t[1][0],t[1][1]),e.lineTo(t[1][0],t[0][1]),e.closePath())}rect(e){return _.rect(this._ctx,e),this._paint(),this}static image(e,n,i=new r.Pt,o){if('number'==typeof i[0])e.drawImage(n,i[0],i[1]);else{let r=i;o?e.drawImage(n,o[0][0],o[0][1],o[1][0]-o[0][0],o[1][1]-o[0][1],r[0][0],r[0][1],r[1][0]-r[0][0],r[1][1]-r[0][1]):e.drawImage(n,r[0][0],r[0][1],r[1][0]-r[0][0],r[1][1]-r[0][1])}}image(e,t,n){return _.image(this._ctx,e,t,n),this}static text(e,t,n,i){t&&e.fillText(n,t[0],t[1],i)}text(e,t,n){return _.text(this._ctx,e,t,n),this}textBox(e,n,i='middle',o='',r=!0){r&&(this._ctx.textBaseline=i);let a=d.Rectangle.size(e),s=this._textTruncate(n,a[0],o);return this.text(this._textAlign(e,i),s[0]),this}paragraphBox(e,t,n=1.2,i='top',o=!0){let a=d.Rectangle.size(e);this._ctx.textBaseline='top';let s=this._font.size*n,l=(e,n=[],i=0)=>{if(!e)return n;if(o&&i*s>a[1]-2*s)return n;if(1e4=d||r[1]===e.length)&&(d=void 0);let c=r[0].substr(0,d);return n.push(c),0>=r[1]||r[1]===e.length?n:l(e.substr(d||r[1]),n,i+1)},c=l(t),p=c.length*s,_=e;if('middle'==i||'center'==i){let t=(a[1]-p)/2;o&&(t=u(0,t)),_=new r.Group(e[0].$add(0,t),e[1].$subtract(0,t))}else _='bottom'==i?new r.Group(e[0].$add(0,a[1]-p),e[1]):new r.Group(e[0],e[0].$add(a[0],p));let g=d.Rectangle.center(_);for(let r=0,a=c.length;re.length}return!1}}r._counter=0,t.UI=r;class a extends r{constructor(e,n,i={},o){super(e,n,i,o),this._hoverID=-1,i.hover||(i.hover=!1),i.clicks||(i.hover=0);const a=t.UIPointerActions;this.on(a.up,()=>{this.state('clicks',this._states.clicks+1)}),this.on(a.move,(e,n)=>{let t=this._within(n);if(t&&!this._states.hover){this.state('hover',!0),r._trigger(this._actions[a.enter],this,n,a.enter);var i=this.hold(a.move);this._hoverID=this.on(a.move,(e,t)=>{this._within(t)||this.state('dragging')||(this.state('hover',!1),r._trigger(this._actions[a.leave],this,n,a.leave),this.off(a.move,this._hoverID),this.unhold(i))})}})}onClick(e){return this.on(t.UIPointerActions.up,e)}offClick(e){return this.off(t.UIPointerActions.up,e)}onHover(e,n){var i=[void 0,void 0];return e&&(i[0]=this.on(t.UIPointerActions.enter,e)),n&&(i[1]=this.on(t.UIPointerActions.leave,n)),i}offHover(e,n){var i=[!1,!1];return(void 0===e||0<=e)&&(i[0]=this.off(t.UIPointerActions.enter,e)),(void 0===n||0<=n)&&(i[1]=this.off(t.UIPointerActions.leave,n)),i}}t.UIButton=a;t.UIDragger=class extends a{constructor(e,n,o={},a){super(e,n,o,a),this._draggingID=-1,this._moveHoldID=-1,o.dragging||(o.dragging=!1),o.offset||(o.offset=new i.Pt(e[0]));const s=t.UIPointerActions;this.on(s.down,(e,t)=>{this.state('dragging',!0),this.state('offset',new i.Pt(t).subtract(e.group[0])),this._moveHoldID=this.hold(s.move),this._draggingID=this.on(s.move,(e,t)=>{this.state('dragging')&&r._trigger(this._actions[s.uidrag],e,t,s.uidrag)})}),this.on(s.up,(e,t,n)=>{this.state('dragging',!1),this.off(s.move,this._draggingID),this.unhold(this._moveHoldID),r._trigger(this._actions[s.drop],e,t,n)})}onDrag(e){return this.on(t.UIPointerActions.uidrag,e)}offDrag(e){return this.off(t.UIPointerActions.uidrag,e)}onDrop(e){return this.on(t.UIPointerActions.drop,e)}offDrop(e){return this.off(t.UIPointerActions.drop,e)}}},function(e,t,n){'use strict';Object.defineProperty(t,'__esModule',{value:!0});const i=n(0);t.Typography=class{static textWidthEstimator(e,t=['M','n','.'],n=[.06,.8,.14]){let o=t.map(e),r=new i.Pt(n).dot(o);return(e)=>e.length*r}static truncate(e,t,n,i=''){let o=a(t.length*_(1,n/e(t)));return ot?_(o,n):0{e.parentNode.removeChild(e)}),super.remove(e)}removeAll(){return this._container.innerHTML='',super.removeAll()}}t.HTMLSpace=l;class d extends o.VisualForm{constructor(e){super(),this._ctx={group:null,groupID:'pts',groupCount:0,currentID:'pts0',currentClass:'',style:{filled:!0,stroked:!0,background:'#f03',"border-color":'#fff',color:'#000',"border-width":'1px',"border-radius":'0',"border-style":'solid',position:'absolute',top:0,left:0,width:0,height:0},font:'11px sans-serif',fontSize:11,fontFamily:'sans-serif'},this._ready=!1,this._space=e,this._space.add({start:()=>{this._ctx.group=this._space.element,this._ctx.groupID='pts_dom_'+d.groupID++,this._ready=!0}})}get space(){return this._space}styleTo(e,t,n=''){if(this._ctx.style[e]===void 0)throw new Error(`${e} style property doesn't exist`);this._ctx.style[e]=`${t}${n}`}fill(e){return'boolean'==typeof e?(this.styleTo('filled',e),!e&&this.styleTo('background','transparent')):(this.styleTo('filled',!0),this.styleTo('background',e)),this}stroke(e,t){return'boolean'==typeof e?(this.styleTo('stroked',e),!e&&this.styleTo('border-width',0)):(this.styleTo('stroked',!0),this.styleTo('border-color',e),this.styleTo('border-width',(t||1)+'px')),this}fillText(e){return this.styleTo('color',e),this}cls(e){return this._ctx.currentClass='boolean'==typeof e?'':e,this}font(e,t,n,i,o){return'number'==typeof e?(this._font.size=e,o&&(this._font.face=o),t&&(this._font.weight=t),n&&(this._font.style=n),i&&(this._font.lineHeight=i),this._ctx.font=this._font.value):this._font=e,this}reset(){return this._ctx.style={filled:!0,stroked:!0,background:'#f03',"border-color":'#fff',"border-width":'1px'},this._font=new o.Font(14,'sans-serif'),this._ctx.font=this._font.value,this}updateScope(e,t){return this._ctx.group=t,this._ctx.groupID=e,this._ctx.groupCount=0,this.nextID(),this._ctx}scope(e){if(!e||null==e.animateID)throw new Error('item not defined or not yet added to Space');return this.updateScope(d.scopeID(e),this.space.element)}nextID(){return this._ctx.groupCount++,this._ctx.currentID=`${this._ctx.groupID}-${this._ctx.groupCount}`,this._ctx.currentID}static getID(e){return e.currentID||`p-${d.domID++}`}static scopeID(e){return`item-${e.animateID}`}static style(e,t){let n=[];for(let i in t.filled||n.push('background: none'),t.stroked||n.push('border: none'),t)if(t.hasOwnProperty(i)&&'filled'!=i&&'stroked'!=i){let e=t[i];if(e)if(!t.filled&&0===i.indexOf('background'))continue;else if(!t.stroked&&0===i.indexOf('border-width'))continue;else n.push(`${i}: ${e}`)}return l.setAttr(e,{style:n.join(';')})}static rectStyle(e,t,n){return e.style.left=t[0]+'px',e.style.top=t[1]+'px',e.style.width=n[0]+'px',e.style.height=n[1]+'px',e}static point(e,t,n=5,i='square'){return'circle'===i?d.circle(e,t,n):d.square(e,t,n)}point(e,t=5,n='square'){return this.nextID(),'circle'==n&&this.styleTo('border-radius','100%'),d.point(this._ctx,e,t,n),this}static circle(e,t,n=10){let i=l.htmlElement(e.group,'div',d.getID(e));return l.setAttr(i,{class:`pts-form pts-circle ${e.currentClass}`}),d.rectStyle(e,new a.Pt(t).$subtract(n),new a.Pt(2*n,2*n)),d.style(i,e.style),i}circle(e){return this.nextID(),this.styleTo('border-radius','100%'),d.circle(this._ctx,e[0],e[1][0]),this}static square(e,t,n){let i=l.htmlElement(e.group,'div',d.getID(e));return l.setAttr(i,{class:`pts-form pts-square ${e.currentClass}`}),d.rectStyle(e,new a.Pt(t).$subtract(n),new a.Pt(2*n,2*n)),d.style(i,e.style),i}square(e,t){return this.nextID(),d.square(this._ctx,e,t),this}static rect(e,t){if(this._checkSize(t)){let n=l.htmlElement(e.group,'div',d.getID(e));return l.setAttr(n,{class:`pts-form pts-rect ${e.currentClass}`}),d.rectStyle(e,t[0],t[1]),d.style(n,e.style),n}}rect(e){return this.nextID(),this.styleTo('border-radius','0'),d.rect(this._ctx,e),this}static text(e,t,n){let i=l.htmlElement(e.group,'div',d.getID(e));return l.setAttr(i,{position:'absolute',class:`pts-form pts-text ${e.currentClass}`,left:t[0],top:t[1]}),i.textContent=n,d.style(i,e.style),i}text(e,t){return this.nextID(),d.text(this._ctx,e,t),this}log(e){return this.fill('#000').stroke('#fff',.5).text([10,14],e),this}arc(){return r.Util.warn('arc is not implemented in HTMLForm'),this}line(){return r.Util.warn('line is not implemented in HTMLForm'),this}polygon(){return r.Util.warn('polygon is not implemented in HTMLForm'),this}}d.groupID=0,d.domID=0,t.HTMLForm=d},function(e,t,n){'use strict';function i(e){for(var n in e)t.hasOwnProperty(n)||(t[n]=e[n])}Object.defineProperty(t,'__esModule',{value:!0}),i(n(7)),i(n(12)),i(n(5)),i(n(4)),i(n(3)),i(n(2)),i(n(0)),i(n(6)),i(n(13)),i(n(1)),i(n(10)),i(n(14)),i(n(9)),i(n(15)),i(n(8));const o=n(7);t.namespace=(t)=>{let n=e.exports;for(let e in n)'namespace'!=e&&(t[e]=n[e])},t.quickStart=(e,n='#9ab')=>{let i=window;return t.namespace(i),i.space=new o.CanvasSpace(e).setup({bgcolor:n,resize:!0,retina:!0}),i.form=i.space.getForm(),function(e=null,t=null,n=null,o=null){i.space.add({start:t,animate:e,resize:o,action:n}),i.space.bindMouse().bindTouch().play()}}},function(e,t,n){'use strict';Object.defineProperty(t,'__esModule',{value:!0});const o=n(0),r=n(2),s=n(1),l=n(3),d=n(4);t.Create=class{static distributeRandom(e,t,n=2){let r=new o.Group;for(let a,s=0;se&&(e*=65536),e=a(e),256>e&&(e|=e<<8);for(let t,n=0;255>n;n++)t=1&n?p[n]^255&e:p[n]^255&e>>8,this.perm[n]=this.perm[n+256]=t}noise2D(){let e=u(0,a(this._n[0]))%255,t=u(0,a(this._n[1]))%255,n=this._n[0]%255-e,i=this._n[1]%255-t,o=d.Vec.dot(c[(e+this.perm[t])%12],[n,i,0]),r=d.Vec.dot(c[(e+this.perm[t+1])%12],[n,i-1,0]),s=d.Vec.dot(c[(e+1+this.perm[t])%12],[n-1,i,0]),p=d.Vec.dot(c[(e+1+this.perm[t+1])%12],[n-1,i-1,0]),_=(e)=>e*e*e*(e*(6*e-15)+10),g=_(n);return l.Num.lerp(l.Num.lerp(o,s,g),l.Num.lerp(r,p,g),_(i))}}t.Noise=h;class i extends o.Group{constructor(){super(...arguments),this._mesh=[]}delaunay(e=!0){if(3>this.length)return[];this._mesh=[];let t=this.length,n=[];for(let o=0;othis[t][0]-this[e][0]);let o=this.slice(),r=this._superTriangle();o=o.concat(r);let a=[this._circum(t,t+1,t+2,r)],l=[],d=[];for(let t=0,r=n.length;tn*n){l.push(t),d.push(t.triangle),a.splice(c,1);continue}i[0]*i[0]+i[1]*i[1]-n*n>s.Const.epsilon||(r.push(t.i,t.j,t.j,t.k,t.k,t.i),a.splice(c,1))}for(i._dedupe(r),c=r.length;1=e.length){let t=(t)=>e[t]||'F';e=`${t(0)}${t(0)}${t(1)}${t(1)}${t(2)}${t(2)}`}let t=1;8===e.length&&(t=e.substr(6)&&1,e=e.substring(0,6));let n=parseInt(e,16);return new m(n>>16,255&n>>8,255&n,t)}static rgb(...e){return m.from(...e).toMode('rgb')}static hsl(...e){return m.from(...e).toMode('hsl')}static hsb(...e){return m.from(...e).toMode('hsb')}static lab(...e){return m.from(...e).toMode('lab')}static lch(...e){return m.from(...e).toMode('lch')}static luv(...e){return m.from(...e).toMode('luv')}static xyz(...e){return m.from(...e).toMode('xyz')}static maxValues(e){return m.ranges[e].zipSlice(1).$take([0,1,2])}get hex(){return this.toString('hex')}get rgb(){return this.toString('rgb')}get rgba(){return this.toString('rgba')}clone(){let e=new m(this);return e.toMode(this._mode),e}toMode(e,t=!1){if(t){let t=this._mode.toUpperCase()+'to'+e.toUpperCase();if(m[t])this.to(m[t](this,this._isNorm,this._isNorm));else throw new Error('Cannot convert color with '+t)}return this._mode=e,this}get mode(){return this._mode}get r(){return this[0]}set r(e){this[0]=e}get g(){return this[1]}set g(e){this[1]=e}get b(){return this[2]}set b(e){this[2]=e}get h(){return'lch'==this._mode?this[2]:this[0]}set h(e){let t='lch'==this._mode?2:0;this[t]=e}get s(){return this[1]}set s(e){this[1]=e}get l(){return'hsl'==this._mode?this[2]:this[0]}set l(e){let t='hsl'==this._mode?2:0;this[t]=e}get a(){return this[1]}set a(e){this[1]=e}get c(){return this[1]}set c(e){this[1]=e}get u(){return this[1]}set u(e){this[1]=e}get v(){return this[2]}set v(e){this[2]=e}get alpha(){return 3n;n++)this[n]=e?p.Num.mapToRange(this[n],t[n][0],t[n][1],0,1):p.Num.mapToRange(this[n],0,1,t[n][0],t[n][1]);return this._isNorm=e,this}$normalize(e=!0){return this.clone().normalize(e)}toString(e='mode'){if('hex'==e){let e=(e)=>{let t=a(e).toString(16);return 2>t.length?'0'+t:t};return`#${e(this[0])}${e(this[1])}${e(this[2])}`}return'rgba'==e?`rgba(${a(this[0])},${a(this[1])},${a(this[2])},${this.alpha}`:'rgb'==e?`rgb(${a(this[0])},${a(this[1])},${a(this[2])}`:`${this._mode}(${this[0]},${this[1]},${this[2]},${this.alpha})`}static RGBtoHSL(e,t=!1,n=!1){let[i,o,r]=t?e:e.$normalize(),a=u(i,o,r),c=_(i,o,r),p=(a+c)/2,g=p,s=p;if(a==c)p=0,g=0;else{let e=a-c;g=.5=r?r*(1+o):r+o-r*o,s=2*r-a,l=(e)=>(e=0>e?e+1:16*e?s+6*((a-s)*e):1>2*e?a:2>3*e?s+6*((a-s)*(2/3-e)):s),d=n?1:255;return m.rgb(d*l(i+1/3),d*l(i),d*l(i-1/3),e.alpha)}static RGBtoHSB(e,t=!1,n=!1){let[i,o,r]=t?e:e.$normalize(),a=u(i,o,r),l=_(i,o,r),c=a-l,d=0,p=0===a?0:c/a;return a!=l&&(a===i?d=(o-r)/c+(oa;a++)r[a]=.04045r;r++)s[r]=0>s[r]?0:.0031308.008856{let t=e*e*e;return .008856{e.parentNode.removeChild(e)}),super.remove(e)}removeAll(){return this._container.innerHTML='',super.removeAll()}}t.SVGSpace=c;class u extends i.VisualForm{constructor(e){super(),this._ctx={group:null,groupID:'pts',groupCount:0,currentID:'pts0',currentClass:'',style:{filled:!0,stroked:!0,fill:'#f03',stroke:'#fff',"stroke-width":1,"stroke-linejoin":'bevel',"stroke-linecap":'sqaure'},font:'11px sans-serif',fontSize:11,fontFamily:'sans-serif'},this._ready=!1,this._space=e,this._space.add({start:()=>{this._ctx.group=this._space.element,this._ctx.groupID='pts_svg_'+u.groupID++,this._ready=!0}})}get space(){return this._space}styleTo(e,t){if(this._ctx.style[e]===void 0)throw new Error(`${e} style property doesn't exist`);this._ctx.style[e]=t}fill(e){return'boolean'==typeof e?this.styleTo('filled',e):(this.styleTo('filled',!0),this.styleTo('fill',e)),this}stroke(e,t,n,i){return'boolean'==typeof e?this.styleTo('stroked',e):(this.styleTo('stroked',!0),this.styleTo('stroke',e),t&&this.styleTo('stroke-width',t),n&&this.styleTo('stroke-linejoin',n),i&&this.styleTo('stroke-linecap',i)),this}cls(e){return this._ctx.currentClass='boolean'==typeof e?'':e,this}font(e,t,n,i,o){return'number'==typeof e?(this._font.size=e,o&&(this._font.face=o),t&&(this._font.weight=t),n&&(this._font.style=n),i&&(this._font.lineHeight=i),this._ctx.font=this._font.value):this._font=e,this}reset(){return this._ctx.style={filled:!0,stroked:!0,fill:'#f03',stroke:'#fff',"stroke-width":1,"stroke-linejoin":'bevel',"stroke-linecap":'sqaure'},this._font=new i.Font(14,'sans-serif'),this._ctx.font=this._font.value,this}updateScope(e,t){return this._ctx.group=t,this._ctx.groupID=e,this._ctx.groupCount=0,this.nextID(),this._ctx}scope(e){if(!e||null==e.animateID)throw new Error('item not defined or not yet added to Space');return this.updateScope(u.scopeID(e),this.space.element)}nextID(){return this._ctx.groupCount++,this._ctx.currentID=`${this._ctx.groupID}-${this._ctx.groupCount}`,this._ctx.currentID}static getID(e){return e.currentID||`p-${u.domID++}`}static scopeID(e){return`item-${e.animateID}`}static style(e,t){let n=[];for(let i in t.filled||n.push('fill: none'),t.stroked||n.push('stroke: none'),t)if(t.hasOwnProperty(i)&&'filled'!=i&&'stroked'!=i){let e=t[i];if(e)if(!t.filled&&0===i.indexOf('fill'))continue;else if(!t.stroked&&0===i.indexOf('stroke'))continue;else n.push(`${i}: ${e}`)}return l.DOMSpace.setAttr(e,{style:n.join(';')})}static point(e,t,n=5,i='square'){return'circle'===i?u.circle(e,t,n):u.square(e,t,n)}point(e,t=5,n='square'){return this.nextID(),u.point(this._ctx,e,t,n),this}static circle(e,t,n=10){let i=c.svgElement(e.group,'circle',u.getID(e));return l.DOMSpace.setAttr(i,{cx:t[0],cy:t[1],r:n,class:`pts-svgform pts-circle ${e.currentClass}`}),u.style(i,e.style),i}circle(e){return this.nextID(),u.circle(this._ctx,e[0],e[1][0]),this}static arc(e,t,n,i,s,p){let _=c.svgElement(e.group,'path',u.getID(e));const g=new a.Pt(t).toAngle(i,n,!0),h=new a.Pt(t).toAngle(s,n,!0),m=o.Geom.boundAngle(s)-o.Geom.boundAngle(i);let f=!!(m>r.Const.pi);p&&(f=!f);const y=p?'0':'1',b=`M ${g[0]} ${g[1]} A ${n} ${n} 0 ${f?'1':'0'} ${y} ${h[0]} ${h[1]}`;return l.DOMSpace.setAttr(_,{d:b,class:`pts-svgform pts-arc ${e.currentClass}`}),u.style(_,e.style),_}arc(e,t,n,i,o){return this.nextID(),u.arc(this._ctx,e,t,n,i,o),this}static square(e,t,n){let i=c.svgElement(e.group,'rect',u.getID(e));return l.DOMSpace.setAttr(i,{x:t[0]-n,y:t[1]-n,width:2*n,height:2*n,class:`pts-svgform pts-square ${e.currentClass}`}),u.style(i,e.style),i}square(e,t){return this.nextID(),u.square(this._ctx,e,t),this}static line(e,t){if(this._checkSize(t)){if(2e+`${t[0]},${t[1]} `,'');return l.DOMSpace.setAttr(i,{points:o,class:`pts-svgform pts-polygon ${e.currentClass}`}),u.style(i,e.style),i}}static polygon(e,t){return u._poly(e,t,!0)}polygon(e){return this.nextID(),u.polygon(this._ctx,e),this}static rect(e,t){if(this._checkSize(t)){let n=c.svgElement(e.group,'rect',u.getID(e)),i=a.Group.fromArray(t).boundingBox(),o=s.Rectangle.size(i);return l.DOMSpace.setAttr(n,{x:i[0][0],y:i[0][1],width:o[0],height:o[1],class:`pts-svgform pts-rect ${e.currentClass}`}),u.style(n,e.style),n}}rect(e){return this.nextID(),u.rect(this._ctx,e),this}static text(e,t,n){let i=c.svgElement(e.group,'text',u.getID(e));return l.DOMSpace.setAttr(i,{"pointer-events":'none',x:t[0],y:t[1],dx:0,dy:0,class:`pts-svgform pts-text ${e.currentClass}`}),i.textContent=n,u.style(i,e.style),i}text(e,t){return this.nextID(),u.text(this._ctx,e,t),this}log(e){return this.fill('#000').stroke('#fff',.5).text([10,14],e),this}}u.groupID=0,u.domID=0,t.SVGForm=u},function(e,t,i){'use strict';Object.defineProperty(t,'__esModule',{value:!0});const o=i(0),r=i(2);class l{constructor(e,t=1,n=0){return this._lastTime=null,this._gravity=new o.Pt,this._friction=1,this._damping=.75,this._particles=[],this._bodies=[],this._names={p:{},b:{}},this._bound=o.Bound.fromGroup(e),this._friction=t,this._gravity='number'==typeof n?new o.Pt(0,n):new o.Pt(n),this}get gravity(){return this._gravity}set gravity(e){this._gravity=e}get friction(){return this._friction}set friction(e){this._friction=e}get damping(){return this._damping}set damping(e){this._damping=e}get bodyCount(){return this._bodies.length}get particleCount(){return this._particles.length}body(e){return this._bodies['string'==typeof e?this._names.b[e]:e]}particle(e){return this._particles['string'==typeof e?this._names.p[e]:e]}update(e){let t=e/1e3;this._updateParticles(t),this._updateBodies(t)}drawParticles(e){this._drawParticles=e}drawBodies(e){this._drawBodies=e}add(e,t){return e instanceof c?(this._bodies.push(e),t&&(this._names.b[t]=this._bodies.length-1)):(this._particles.push(e),t&&(this._names.p[t]=this._particles.length-1)),this}remove(e,t,n=1){let i=0>t?[-1*t-1,n]:[t,n];return'body'==e?this._bodies.splice(i[0],i[1]):this._particles.splice(i[0],i[1]),this}static edgeConstraint(e,t,n,i=1,o=!1){const r=1/(e.mass||1),a=1/(t.mass||1),s=r+a;let l=t.$subtract(e),c=n*n,u=o?n/l.magnitude()-1:c/(l.dot(l)+c)-.5,d=l.$multiply(u*i);return e.subtract(d.$multiply(r/s)),t.add(d.$multiply(a/s)),e}static boundConstraint(e,t,n=.75){let i=t.boundingBox(),r=e.$min(i[1].subtract(e.radius)).$max(i[0].add(e.radius));if(r[0]===i[0][0]||r[0]===i[1][0]){let t=e.changed.$multiply(n);e.previous=r.$subtract(new o.Pt(-t[0],t[1]))}else if(r[1]===i[0][1]||r[1]===i[1][1]){let t=e.changed.$multiply(n);e.previous=r.$subtract(new o.Pt(t[0],-t[1]))}e.to(r)}integrate(e,t,n){return e.addForce(this._gravity),e.verlet(t,this._friction,n),e}_updateParticles(e){for(let t,n=0,i=this._particles.length;ne||e>=this.length)throw new Error('index1 is not in the Group\'s indices');if(0>t||t>=this.length)throw new Error('index1 is not in the Group\'s indices');let i=this[e].$subtract(this[t]).magnitude();return this._cs.push([e,t,i,n||this._stiff]),this}linkAll(e){let t=this.length/2;for(let o,n=0,i=this.length;n=i-1?0:n+1,this.link(n,o,e),4=i-o?n%i:n+o;this.link(n,r,e)}n<=t-1&&this.link(n,_(this.length-1,n+a(t)))}}linksToLines(){let e=[];for(let t,n=0,i=this._cs.length;nd(i[0][1]-i[1][1])?(n.vertex[0]-t[0]-i[0][0])/(i[1][0]-i[0][0]):(n.vertex[1]-t[1]-i[0][1])/(i[1][1]-i[0][1]);let o=1/(e*e+(1-e)*(1-e)),r=n.vertex.body.mass||1,a=n.edge[0].body.mass||1,s=r/(r+a);i[0].subtract(t.$multiply(s*(1-e)*o/2)),i[1].subtract(t.$multiply(s*e*o/2)),n.vertex.add(t.$multiply(a/(r+a)))}}processParticle(e){let t=this,n=r.Polygon.hasIntersectCircle(t,r.Circle.fromCenter(e,e.radius));if(n){let i,t=n.normal.$multiply(n.dist),o=n.edge;i=d(o[0][0]-o[1][0])>d(o[0][1]-o[1][1])?(n.vertex[0]-t[0]-o[0][0])/(o[1][0]-o[0][0]):(n.vertex[1]-t[1]-o[0][1])/(o[1][1]-o[0][1]);let r=1/(i*i+(1-i)*(1-i)),a=n.vertex.mass||e.mass||1,s=n.edge[0].body.mass||1,l=a/(a+s);o[0].subtract(t.$multiply(l*(1-i)*r/2)),o[1].subtract(t.$multiply(l*i*r/2));let c=e.changed.add(t.$multiply(s/(a+s)));e.previous=e.$subtract(c)}}}t.Body=c}])})}])}); //# sourceMappingURL=pts.min.js.map \ No newline at end of file