diff --git a/main.js b/main.js index d8ca3d26..2e5a0568 100644 --- a/main.js +++ b/main.js @@ -14,10 +14,6 @@ function createCommonjsModule(fn) { return fn(module, module.exports), module.exports; } -function commonjsRequire (path) { - throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.'); -} - var graphology_umd_min = createCommonjsModule(function (module, exports) { !function(t,e){module.exports=e();}(commonjsGlobal,(function(){function t(e){return t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},t(e)}function e(t,e){t.prototype=Object.create(e.prototype),t.prototype.constructor=t,r(t,e);}function n(t){return n=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)},n(t)}function r(t,e){return r=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t},r(t,e)}function i(){if("undefined"==typeof Reflect||!Reflect.construct)return !1;if(Reflect.construct.sham)return !1;if("function"==typeof Proxy)return !0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return !1}}function o(t,e,n){return o=i()?Reflect.construct:function(t,e,n){var i=[null];i.push.apply(i,e);var o=new(Function.bind.apply(t,i));return n&&r(o,n.prototype),o},o.apply(null,arguments)}function a(t){var e="function"==typeof Map?new Map:void 0;return a=function(t){if(null===t||(i=t,-1===Function.toString.call(i).indexOf("[native code]")))return t;var i;if("function"!=typeof t)throw new TypeError("Super expression must either be null or a function");if(void 0!==e){if(e.has(t))return e.get(t);e.set(t,a);}function a(){return o(t,arguments,n(this).constructor)}return a.prototype=Object.create(t.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),r(a,t)},a(t)}function u(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}var c=function(){for(var t=arguments[0],e=1,n=arguments.length;e0&&a.length>i&&!a.warned){a.warned=!0;var c=new Error("Possible EventEmitter memory leak detected. "+a.length+" "+String(e)+" listeners added. Use emitter.setMaxListeners() to increase limit");c.name="MaxListenersExceededWarning",c.emitter=t,c.type=e,c.count=a.length,u=c,console&&console.warn&&console.warn(u);}return t}function S(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function A(t,e,n){var r={fired:!1,wrapFn:void 0,target:t,type:e,listener:n},i=S.bind(r);return i.listener=n,r.wrapFn=i,i}function L(t,e,n){var r=t._events;if(void 0===r)return [];var i=r[e];return void 0===i?[]:"function"==typeof i?n?[i.listener||i]:[i]:n?function(t){for(var e=new Array(t.length),n=0;n0&&(o=e[0]),o instanceof Error)throw o;var a=new Error("Unhandled error."+(o?" ("+o.message+")":""));throw a.context=o,a}var u=i[t];if(void 0===u)return !1;if("function"==typeof u)w(u,this,e);else {var c=u.length,d=N(u,c);for(n=0;n=0;o--)if(n[o]===e||n[o].listener===e){a=n[o].listener,i=o;break}if(i<0)return this;0===i?n.shift():function(t,e){for(;e+1=0;r--)this.removeListener(t,e[r]);return this},_.prototype.listeners=function(t){return L(this,t,!0)},_.prototype.rawListeners=function(t){return L(this,t,!1)},_.listenerCount=function(t,e){return "function"==typeof t.listenerCount?t.listenerCount(e):D.call(t,e)},_.prototype.listenerCount=D,_.prototype.eventNames=function(){return this._eventsCount>0?y(this._events):[]},"undefined"!=typeof Symbol&&(j.prototype[Symbol.iterator]=function(){return this}),j.of=function(){var t=arguments,e=t.length,n=0;return new j((function(){return n>=e?{done:!0}:{done:!1,value:t[n++]}}))},j.empty=function(){return new j((function(){return {done:!0}}))},j.fromSequence=function(t){var e=0,n=t.length;return new j((function(){return e>=n?{done:!0}:{done:!1,value:t[e++]}}))},j.is=function(t){return t instanceof j||"object"==typeof t&&null!==t&&"function"==typeof t.next};var O=j,C={};C.ARRAY_BUFFER_SUPPORT="undefined"!=typeof ArrayBuffer,C.SYMBOL_SUPPORT="undefined"!=typeof Symbol;var z=O,M=C,P=M.ARRAY_BUFFER_SUPPORT,T=M.SYMBOL_SUPPORT;var R=function(t){var e=function(t){return "string"==typeof t||Array.isArray(t)||P&&ArrayBuffer.isView(t)?z.fromSequence(t):"object"!=typeof t||null===t?null:T&&"function"==typeof t[Symbol.iterator]?t[Symbol.iterator]():"function"==typeof t.next?t:null}(t);if(!e)throw new Error("obliterator: target is not iterable nor a valid iterator.");return e},W=R,K=function(t,e){for(var n,r=arguments.length>1?e:1/0,i=r!==1/0?new Array(r):[],o=0,a=W(t);;){if(o===r)return i;if((n=a.next()).done)return o!==e&&(i.length=o),i;i[o++]=n.value;}},I=function(t){function n(e){var n;return (n=t.call(this)||this).name="GraphError",n.message=e,n}return e(n,t),n}(a(Error)),F=function(t){function n(e){var r;return (r=t.call(this,e)||this).name="InvalidArgumentsGraphError","function"==typeof Error.captureStackTrace&&Error.captureStackTrace(u(r),n.prototype.constructor),r}return e(n,t),n}(I),Y=function(t){function n(e){var r;return (r=t.call(this,e)||this).name="NotFoundGraphError","function"==typeof Error.captureStackTrace&&Error.captureStackTrace(u(r),n.prototype.constructor),r}return e(n,t),n}(I),B=function(t){function n(e){var r;return (r=t.call(this,e)||this).name="UsageGraphError","function"==typeof Error.captureStackTrace&&Error.captureStackTrace(u(r),n.prototype.constructor),r}return e(n,t),n}(I);function q(t,e){this.key=t,this.attributes=e,this.clear();}function J(t,e){this.key=t,this.attributes=e,this.clear();}function V(t,e){this.key=t,this.attributes=e,this.clear();}function H(t,e,n,r,i){this.key=e,this.attributes=i,this.undirected=t,this.source=n,this.target=r;}function Q(t,e,n,r,i,o,a){var u,c,d="out",s="in";if(e&&(d=s="undirected"),t.multi){if(void 0===(c=(u=o[d])[i])&&(c=new Set,u[i]=c),c.add(n),r===i&&e)return;void 0===(u=a[s])[r]&&(u[r]=c);}else {if(o[d][i]=n,r===i&&e)return;a[s][r]=n;}}function X(t,e,n){var r=t.multi,i=n.source,o=n.target,a=i.key,u=o.key,c=i[e?"undirected":"out"],d=e?"undirected":"in";if(u in c)if(r){var s=c[u];1===s.size?(delete c[u],delete o[d][a]):s.delete(n);}else delete c[u];r||delete o[d][a];}q.prototype.clear=function(){this.inDegree=0,this.outDegree=0,this.undirectedDegree=0,this.directedSelfLoops=0,this.undirectedSelfLoops=0,this.in={},this.out={},this.undirected={};},J.prototype.clear=function(){this.inDegree=0,this.outDegree=0,this.directedSelfLoops=0,this.in={},this.out={};},J.prototype.upgradeToMixed=function(){this.undirectedDegree=0,this.undirectedSelfLoops=0,this.undirected={};},V.prototype.clear=function(){this.undirectedDegree=0,this.undirectedSelfLoops=0,this.undirected={};},V.prototype.upgradeToMixed=function(){this.inDegree=0,this.outDegree=0,this.directedSelfLoops=0,this.in={},this.out={};};function Z(t,e,n,r,i,o,a){var u,c,d,s;if(r=""+r,0===n){if(!(u=t._nodes.get(r)))throw new Y("Graph.".concat(e,': could not find the "').concat(r,'" node in the graph.'));d=i,s=o;}else if(3===n){if(i=""+i,!(c=t._edges.get(i)))throw new Y("Graph.".concat(e,': could not find the "').concat(i,'" edge in the graph.'));var h=c.source.key,f=c.target.key;if(r===h)u=c.target;else {if(r!==f)throw new Y("Graph.".concat(e,': the "').concat(r,'" node is not attached to the "').concat(i,'" edge (').concat(h,", ").concat(f,")."));u=c.source;}d=o,s=a;}else {if(!(c=t._edges.get(r)))throw new Y("Graph.".concat(e,': could not find the "').concat(r,'" edge in the graph.'));u=1===n?c.source:c.target,d=i,s=o;}return [u,d,s]}var $=[{name:function(t){return "get".concat(t,"Attribute")},attacher:function(t,e,n){t.prototype[e]=function(t,r,i){var o=Z(this,e,n,t,r,i),a=o[0],u=o[1];return a.attributes[u]};}},{name:function(t){return "get".concat(t,"Attributes")},attacher:function(t,e,n){t.prototype[e]=function(t,r){return Z(this,e,n,t,r)[0].attributes};}},{name:function(t){return "has".concat(t,"Attribute")},attacher:function(t,e,n){t.prototype[e]=function(t,r,i){var o=Z(this,e,n,t,r,i),a=o[0],u=o[1];return a.attributes.hasOwnProperty(u)};}},{name:function(t){return "set".concat(t,"Attribute")},attacher:function(t,e,n){t.prototype[e]=function(t,r,i,o){var a=Z(this,e,n,t,r,i,o),u=a[0],c=a[1],d=a[2];return u.attributes[c]=d,this.emit("nodeAttributesUpdated",{key:u.key,type:"set",attributes:u.attributes,name:c}),this};}},{name:function(t){return "update".concat(t,"Attribute")},attacher:function(t,e,n){t.prototype[e]=function(t,r,i,o){var a=Z(this,e,n,t,r,i,o),u=a[0],c=a[1],d=a[2];if("function"!=typeof d)throw new F("Graph.".concat(e,": updater should be a function."));var s=u.attributes,h=d(s[c]);return s[c]=h,this.emit("nodeAttributesUpdated",{key:u.key,type:"set",attributes:u.attributes,name:c}),this};}},{name:function(t){return "remove".concat(t,"Attribute")},attacher:function(t,e,n){t.prototype[e]=function(t,r,i){var o=Z(this,e,n,t,r,i),a=o[0],u=o[1];return delete a.attributes[u],this.emit("nodeAttributesUpdated",{key:a.key,type:"remove",attributes:a.attributes,name:u}),this};}},{name:function(t){return "replace".concat(t,"Attributes")},attacher:function(t,e,n){t.prototype[e]=function(t,r,i){var o=Z(this,e,n,t,r,i),a=o[0],u=o[1];if(!h(u))throw new F("Graph.".concat(e,": provided attributes are not a plain object."));return a.attributes=u,this.emit("nodeAttributesUpdated",{key:a.key,type:"replace",attributes:a.attributes}),this};}},{name:function(t){return "merge".concat(t,"Attributes")},attacher:function(t,e,n){t.prototype[e]=function(t,r,i){var o=Z(this,e,n,t,r,i),a=o[0],u=o[1];if(!h(u))throw new F("Graph.".concat(e,": provided attributes are not a plain object."));return c(a.attributes,u),this.emit("nodeAttributesUpdated",{key:a.key,type:"merge",attributes:a.attributes,data:u}),this};}},{name:function(t){return "update".concat(t,"Attributes")},attacher:function(t,e,n){t.prototype[e]=function(t,r,i){var o=Z(this,e,n,t,r,i),a=o[0],u=o[1];if("function"!=typeof u)throw new F("Graph.".concat(e,": provided updater is not a function."));return a.attributes=u(a.attributes),this.emit("nodeAttributesUpdated",{key:a.key,type:"update",attributes:a.attributes}),this};}}];var tt=[{name:function(t){return "get".concat(t,"Attribute")},attacher:function(t,e,n){t.prototype[e]=function(t,r){var i;if("mixed"!==this.type&&"mixed"!==n&&n!==this.type)throw new B("Graph.".concat(e,": cannot find this type of edges in your ").concat(this.type," graph."));if(arguments.length>2){if(this.multi)throw new B("Graph.".concat(e,": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about."));var o=""+t,a=""+r;if(r=arguments[2],!(i=d(this,o,a,n)))throw new Y("Graph.".concat(e,': could not find an edge for the given path ("').concat(o,'" - "').concat(a,'").'))}else if(t=""+t,!(i=this._edges.get(t)))throw new Y("Graph.".concat(e,': could not find the "').concat(t,'" edge in the graph.'));if("mixed"!==n&&i.undirected!==("undirected"===n))throw new Y("Graph.".concat(e,': could not find the "').concat(t,'" ').concat(n," edge in the graph."));return i.attributes[r]};}},{name:function(t){return "get".concat(t,"Attributes")},attacher:function(t,e,n){t.prototype[e]=function(t){var r;if("mixed"!==this.type&&"mixed"!==n&&n!==this.type)throw new B("Graph.".concat(e,": cannot find this type of edges in your ").concat(this.type," graph."));if(arguments.length>1){if(this.multi)throw new B("Graph.".concat(e,": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about."));var i=""+t,o=""+arguments[1];if(!(r=d(this,i,o,n)))throw new Y("Graph.".concat(e,': could not find an edge for the given path ("').concat(i,'" - "').concat(o,'").'))}else if(t=""+t,!(r=this._edges.get(t)))throw new Y("Graph.".concat(e,': could not find the "').concat(t,'" edge in the graph.'));if("mixed"!==n&&r.undirected!==("undirected"===n))throw new Y("Graph.".concat(e,': could not find the "').concat(t,'" ').concat(n," edge in the graph."));return r.attributes};}},{name:function(t){return "has".concat(t,"Attribute")},attacher:function(t,e,n){t.prototype[e]=function(t,r){var i;if("mixed"!==this.type&&"mixed"!==n&&n!==this.type)throw new B("Graph.".concat(e,": cannot find this type of edges in your ").concat(this.type," graph."));if(arguments.length>2){if(this.multi)throw new B("Graph.".concat(e,": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about."));var o=""+t,a=""+r;if(r=arguments[2],!(i=d(this,o,a,n)))throw new Y("Graph.".concat(e,': could not find an edge for the given path ("').concat(o,'" - "').concat(a,'").'))}else if(t=""+t,!(i=this._edges.get(t)))throw new Y("Graph.".concat(e,': could not find the "').concat(t,'" edge in the graph.'));if("mixed"!==n&&i.undirected!==("undirected"===n))throw new Y("Graph.".concat(e,': could not find the "').concat(t,'" ').concat(n," edge in the graph."));return i.attributes.hasOwnProperty(r)};}},{name:function(t){return "set".concat(t,"Attribute")},attacher:function(t,e,n){t.prototype[e]=function(t,r,i){var o;if("mixed"!==this.type&&"mixed"!==n&&n!==this.type)throw new B("Graph.".concat(e,": cannot find this type of edges in your ").concat(this.type," graph."));if(arguments.length>3){if(this.multi)throw new B("Graph.".concat(e,": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about."));var a=""+t,u=""+r;if(r=arguments[2],i=arguments[3],!(o=d(this,a,u,n)))throw new Y("Graph.".concat(e,': could not find an edge for the given path ("').concat(a,'" - "').concat(u,'").'))}else if(t=""+t,!(o=this._edges.get(t)))throw new Y("Graph.".concat(e,': could not find the "').concat(t,'" edge in the graph.'));if("mixed"!==n&&o.undirected!==("undirected"===n))throw new Y("Graph.".concat(e,': could not find the "').concat(t,'" ').concat(n," edge in the graph."));return o.attributes[r]=i,this.emit("edgeAttributesUpdated",{key:o.key,type:"set",attributes:o.attributes,name:r}),this};}},{name:function(t){return "update".concat(t,"Attribute")},attacher:function(t,e,n){t.prototype[e]=function(t,r,i){var o;if("mixed"!==this.type&&"mixed"!==n&&n!==this.type)throw new B("Graph.".concat(e,": cannot find this type of edges in your ").concat(this.type," graph."));if(arguments.length>3){if(this.multi)throw new B("Graph.".concat(e,": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about."));var a=""+t,u=""+r;if(r=arguments[2],i=arguments[3],!(o=d(this,a,u,n)))throw new Y("Graph.".concat(e,': could not find an edge for the given path ("').concat(a,'" - "').concat(u,'").'))}else if(t=""+t,!(o=this._edges.get(t)))throw new Y("Graph.".concat(e,': could not find the "').concat(t,'" edge in the graph.'));if("function"!=typeof i)throw new F("Graph.".concat(e,": updater should be a function."));if("mixed"!==n&&o.undirected!==("undirected"===n))throw new Y("Graph.".concat(e,': could not find the "').concat(t,'" ').concat(n," edge in the graph."));return o.attributes[r]=i(o.attributes[r]),this.emit("edgeAttributesUpdated",{key:o.key,type:"set",attributes:o.attributes,name:r}),this};}},{name:function(t){return "remove".concat(t,"Attribute")},attacher:function(t,e,n){t.prototype[e]=function(t,r){var i;if("mixed"!==this.type&&"mixed"!==n&&n!==this.type)throw new B("Graph.".concat(e,": cannot find this type of edges in your ").concat(this.type," graph."));if(arguments.length>2){if(this.multi)throw new B("Graph.".concat(e,": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about."));var o=""+t,a=""+r;if(r=arguments[2],!(i=d(this,o,a,n)))throw new Y("Graph.".concat(e,': could not find an edge for the given path ("').concat(o,'" - "').concat(a,'").'))}else if(t=""+t,!(i=this._edges.get(t)))throw new Y("Graph.".concat(e,': could not find the "').concat(t,'" edge in the graph.'));if("mixed"!==n&&i.undirected!==("undirected"===n))throw new Y("Graph.".concat(e,': could not find the "').concat(t,'" ').concat(n," edge in the graph."));return delete i.attributes[r],this.emit("edgeAttributesUpdated",{key:i.key,type:"remove",attributes:i.attributes,name:r}),this};}},{name:function(t){return "replace".concat(t,"Attributes")},attacher:function(t,e,n){t.prototype[e]=function(t,r){var i;if("mixed"!==this.type&&"mixed"!==n&&n!==this.type)throw new B("Graph.".concat(e,": cannot find this type of edges in your ").concat(this.type," graph."));if(arguments.length>2){if(this.multi)throw new B("Graph.".concat(e,": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about."));var o=""+t,a=""+r;if(r=arguments[2],!(i=d(this,o,a,n)))throw new Y("Graph.".concat(e,': could not find an edge for the given path ("').concat(o,'" - "').concat(a,'").'))}else if(t=""+t,!(i=this._edges.get(t)))throw new Y("Graph.".concat(e,': could not find the "').concat(t,'" edge in the graph.'));if(!h(r))throw new F("Graph.".concat(e,": provided attributes are not a plain object."));if("mixed"!==n&&i.undirected!==("undirected"===n))throw new Y("Graph.".concat(e,': could not find the "').concat(t,'" ').concat(n," edge in the graph."));return i.attributes=r,this.emit("edgeAttributesUpdated",{key:i.key,type:"replace",attributes:i.attributes}),this};}},{name:function(t){return "merge".concat(t,"Attributes")},attacher:function(t,e,n){t.prototype[e]=function(t,r){var i;if("mixed"!==this.type&&"mixed"!==n&&n!==this.type)throw new B("Graph.".concat(e,": cannot find this type of edges in your ").concat(this.type," graph."));if(arguments.length>2){if(this.multi)throw new B("Graph.".concat(e,": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about."));var o=""+t,a=""+r;if(r=arguments[2],!(i=d(this,o,a,n)))throw new Y("Graph.".concat(e,': could not find an edge for the given path ("').concat(o,'" - "').concat(a,'").'))}else if(t=""+t,!(i=this._edges.get(t)))throw new Y("Graph.".concat(e,': could not find the "').concat(t,'" edge in the graph.'));if(!h(r))throw new F("Graph.".concat(e,": provided attributes are not a plain object."));if("mixed"!==n&&i.undirected!==("undirected"===n))throw new Y("Graph.".concat(e,': could not find the "').concat(t,'" ').concat(n," edge in the graph."));return c(i.attributes,r),this.emit("edgeAttributesUpdated",{key:i.key,type:"merge",attributes:i.attributes,data:r}),this};}},{name:function(t){return "update".concat(t,"Attributes")},attacher:function(t,e,n){t.prototype[e]=function(t,r){var i;if("mixed"!==this.type&&"mixed"!==n&&n!==this.type)throw new B("Graph.".concat(e,": cannot find this type of edges in your ").concat(this.type," graph."));if(arguments.length>2){if(this.multi)throw new B("Graph.".concat(e,": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about."));var o=""+t,a=""+r;if(r=arguments[2],!(i=d(this,o,a,n)))throw new Y("Graph.".concat(e,': could not find an edge for the given path ("').concat(o,'" - "').concat(a,'").'))}else if(t=""+t,!(i=this._edges.get(t)))throw new Y("Graph.".concat(e,': could not find the "').concat(t,'" edge in the graph.'));if("function"!=typeof r)throw new F("Graph.".concat(e,": provided updater is not a function."));if("mixed"!==n&&i.undirected!==("undirected"===n))throw new Y("Graph.".concat(e,': could not find the "').concat(t,'" ').concat(n," edge in the graph."));return i.attributes=r(i.attributes),this.emit("edgeAttributesUpdated",{key:i.key,type:"update",attributes:i.attributes}),this};}}];var et=O,nt=R,rt=function(){var t,e=arguments,n=-1;return new et((function r(){if(!t){if(++n>=e.length)return {done:!0};t=nt(e[n]);}var i=t.next();return i.done?(t=null,r()):i}))},it=[{name:"edges",type:"mixed"},{name:"inEdges",type:"directed",direction:"in"},{name:"outEdges",type:"directed",direction:"out"},{name:"inboundEdges",type:"mixed",direction:"in"},{name:"outboundEdges",type:"mixed",direction:"out"},{name:"directedEdges",type:"directed"},{name:"undirectedEdges",type:"undirected"}];function ot(t,e){for(var n in e)t.push(e[n].key);}function at(t,e){for(var n in e)e[n].forEach((function(e){return t.push(e.key)}));}function ut(t,e,n){for(var r in t)if(r!==n){var i=t[r];e(i.key,i.attributes,i.source.key,i.target.key,i.source.attributes,i.target.attributes,i.undirected);}}function ct(t,e,n){for(var r in t)r!==n&&t[r].forEach((function(t){return e(t.key,t.attributes,t.source.key,t.target.key,t.source.attributes,t.target.attributes,t.undirected)}));}function dt(t,e,n){for(var r in t)if(r!==n){var i=t[r];if(e(i.key,i.attributes,i.source.key,i.target.key,i.source.attributes,i.target.attributes,i.undirected))return i.key}}function st(t,e,n){var r,i,o,a,u;for(var c in t)if(c!==n)for(r=t[c].values();!0!==(i=r.next()).done;)if(a=(o=i.value).source,u=o.target,e(o.key,o.attributes,a.key,u.key,a.attributes,u.attributes,o.undirected))return o.key}function ht(t,e){var n=Object.keys(t),r=n.length,i=null,o=0;return new O((function a(){var u;if(i){var c=i.next();if(c.done)return i=null,o++,a();u=c.value;}else {if(o>=r)return {done:!0};var d=n[o];if(d===e)return o++,a();if((u=t[d])instanceof Set)return i=u.values(),a();o++;}return {done:!1,value:{edge:u.key,attributes:u.attributes,source:u.source.key,target:u.target.key,sourceAttributes:u.source.attributes,targetAttributes:u.target.attributes,undirected:u.undirected}}}))}function ft(t,e,n){var r=e[n];r&&t.push(r.key);}function pt(t,e,n){var r=e[n];r&&r.forEach((function(e){return t.push(e.key)}));}function lt(t,e,n){var r=t[e];if(r){var i=r.source,o=r.target;n(r.key,r.attributes,i.key,o.key,i.attributes,o.attributes,r.undirected);}}function gt(t,e,n){var r=t[e];r&&r.forEach((function(t){return n(t.key,t.attributes,t.source.key,t.target.key,t.source.attributes,t.target.attributes,t.undirected)}));}function yt(t,e,n){var r=t[e];if(r){var i=r.source,o=r.target;return n(r.key,r.attributes,i.key,o.key,i.attributes,o.attributes,r.undirected)?r.key:void 0}}function vt(t,e,n){var r=t[e];if(r)for(var i,o,a=r.values();!0!==(i=a.next()).done;)if(n((o=i.value).key,o.attributes,o.source.key,o.target.key,o.source.attributes,o.target.attributes,o.undirected))return o.key}function bt(t,e){var n=t[e];if(n instanceof Set){var r=n.values();return new O((function(){var t=r.next();if(t.done)return t;var e=t.value;return {done:!1,value:{edge:e.key,attributes:e.attributes,source:e.source.key,target:e.target.key,sourceAttributes:e.source.attributes,targetAttributes:e.target.attributes,undirected:e.undirected}}}))}return O.of([n.key,n.attributes,n.source.key,n.target.key,n.source.attributes,n.target.attributes])}function wt(t,e){if(0===t.size)return [];if("mixed"===e||e===t.type)return "function"==typeof Array.from?Array.from(t._edges.keys()):K(t._edges.keys(),t._edges.size);for(var n,r,i="undirected"===e?t.undirectedSize:t.directedSize,o=new Array(i),a="undirected"===e,u=t._edges.values(),c=0;!0!==(n=u.next()).done;)(r=n.value).undirected===a&&(o[c++]=r.key);return o}function mt(t,e,n){if(0!==t.size)for(var r,i,o="mixed"!==e&&e!==t.type,a="undirected"===e,u=t._edges.values();!0!==(r=u.next()).done;)if(i=r.value,!o||i.undirected===a){var c=i,d=c.key,s=c.attributes,h=c.source,f=c.target;n(d,s,h.key,f.key,h.attributes,f.attributes,i.undirected);}}function _t(t,e,n){if(0!==t.size)for(var r,i,o="mixed"!==e&&e!==t.type,a="undirected"===e,u=t._edges.values();!0!==(r=u.next()).done;)if(i=r.value,!o||i.undirected===a){var c=i,d=c.key,s=c.attributes,h=c.source,f=c.target;if(n(d,s,h.key,f.key,h.attributes,f.attributes,i.undirected))return d}}function kt(t,e){if(0===t.size)return O.empty();var n="mixed"!==e&&e!==t.type,r="undirected"===e,i=t._edges.values();return new O((function(){for(var t,e;;){if((t=i.next()).done)return t;if(e=t.value,!n||e.undirected===r)break}return {value:{edge:e.key,attributes:e.attributes,source:e.source.key,target:e.target.key,sourceAttributes:e.source.attributes,targetAttributes:e.target.attributes,undirected:e.undirected},done:!1}}))}function Gt(t,e,n,r){var i=[],o=t?at:ot;return "undirected"!==e&&("out"!==n&&o(i,r.in),"in"!==n&&o(i,r.out),!n&&r.directedSelfLoops>0&&i.splice(i.lastIndexOf(r.key),1)),"directed"!==e&&o(i,r.undirected),i}function xt(t,e,n,r,i){var o=t?ct:ut;"undirected"!==e&&("out"!==n&&o(r.in,i),"in"!==n&&o(r.out,i,n?null:r.key)),"directed"!==e&&o(r.undirected,i);}function Et(t,e,n,r,i){var o,a=t?st:dt;if("undirected"!==e){if("out"!==n&&(o=a(r.in,i)))return o;if("in"!==n&&(o=a(r.out,i,n?null:r.key)))return o}if("directed"!==e&&(o=a(r.undirected,i)))return o}function St(t,e,n){var r=O.empty();return "undirected"!==t&&("out"!==e&&void 0!==n.in&&(r=rt(r,ht(n.in))),"in"!==e&&void 0!==n.out&&(r=rt(r,ht(n.out,e?null:n.key)))),"directed"!==t&&void 0!==n.undirected&&(r=rt(r,ht(n.undirected))),r}function At(t,e,n,r,i){var o=e?pt:ft,a=[];return "undirected"!==t&&(void 0!==r.in&&"out"!==n&&o(a,r.in,i),void 0!==r.out&&"in"!==n&&o(a,r.out,i),!n&&r.directedSelfLoops>0&&a.splice(a.lastIndexOf(r.key),1)),"directed"!==t&&void 0!==r.undirected&&o(a,r.undirected,i),a}function Lt(t,e,n,r,i,o){var a=e?gt:lt;"undirected"!==t&&(void 0!==r.in&&"out"!==n&&a(r.in,i,o),r.key!==i&&void 0!==r.out&&"in"!==n&&a(r.out,i,o)),"directed"!==t&&void 0!==r.undirected&&a(r.undirected,i,o);}function Dt(t,e,n,r,i,o){var a,u=e?vt:yt;if("undirected"!==t){if(void 0!==r.in&&"out"!==n&&(a=u(r.in,i,o)))return a;if(r.key!==i&&void 0!==r.out&&"in"!==n&&(a=u(r.out,i,o,n?null:r.key)))return a}if("directed"!==t&&void 0!==r.undirected&&(a=u(r.undirected,i,o)))return a}function Nt(t,e,n,r){var i=O.empty();return "undirected"!==t&&(void 0!==n.in&&"out"!==e&&r in n.in&&(i=rt(i,bt(n.in,r))),void 0!==n.out&&"in"!==e&&r in n.out&&(i=rt(i,bt(n.out,r)))),"directed"!==t&&void 0!==n.undirected&&r in n.undirected&&(i=rt(i,bt(n.undirected,r))),i}var Ut=[{name:"neighbors",type:"mixed"},{name:"inNeighbors",type:"directed",direction:"in"},{name:"outNeighbors",type:"directed",direction:"out"},{name:"inboundNeighbors",type:"mixed",direction:"in"},{name:"outboundNeighbors",type:"mixed",direction:"out"},{name:"directedNeighbors",type:"directed"},{name:"undirectedNeighbors",type:"undirected"}];function jt(t,e){if(void 0!==e)for(var n in e)t.add(n);}function Ot(t,e,n){for(var r in e){var i=e[r];i instanceof Set&&(i=i.values().next().value);var o=i.source,a=i.target,u=o===t?a:o;n(u.key,u.attributes);}}function Ct(t,e,n,r){for(var i in n){var o=n[i];o instanceof Set&&(o=o.values().next().value);var a=o.source,u=o.target,c=a===e?u:a;t.has(c.key)||(t.add(c.key),r(c.key,c.attributes));}}function zt(t,e,n){for(var r in e){var i=e[r];i instanceof Set&&(i=i.values().next().value);var o=i.source,a=i.target,u=o===t?a:o;if(n(u.key,u.attributes))return u.key}}function Mt(t,e,n,r){for(var i in n){var o=n[i];o instanceof Set&&(o=o.values().next().value);var a=o.source,u=o.target,c=a===e?u:a;if(!t.has(c.key))if(t.add(c.key),r(c.key,c.attributes))return c.key}}function Pt(t,e){var n=Object.keys(e),r=n.length,i=0;return new O((function(){if(i>=r)return {done:!0};var o=e[n[i++]];o instanceof Set&&(o=o.values().next().value);var a=o.source,u=o.target,c=a===t?u:a;return {done:!1,value:{neighbor:c.key,attributes:c.attributes}}}))}function Tt(t,e,n){var r=Object.keys(n),i=r.length,o=0;return new O((function a(){if(o>=i)return {done:!0};var u=n[r[o++]];u instanceof Set&&(u=u.values().next().value);var c=u.source,d=u.target,s=c===e?d:c;return t.has(s.key)?a():(t.add(s.key),{done:!1,value:{neighbor:s.key,attributes:s.attributes}})}))}function Rt(t,e){var n=e.name,r=e.type,i=e.direction;t.prototype[n]=function(t){if("mixed"!==r&&"mixed"!==this.type&&r!==this.type)return [];t=""+t;var e=this._nodes.get(t);if(void 0===e)throw new Y("Graph.".concat(n,': could not find the "').concat(t,'" node in the graph.'));return function(t,e,n){if("mixed"!==t){if("undirected"===t)return Object.keys(n.undirected);if("string"==typeof e)return Object.keys(n[e])}var r=new Set;return "undirected"!==t&&("out"!==e&&jt(r,n.in),"in"!==e&&jt(r,n.out)),"directed"!==t&&jt(r,n.undirected),K(r.values(),r.size)}("mixed"===r?this.type:r,i,e)};}function Wt(t,e){var n=e.name,r=e.type,i=e.direction,o="forEach"+n[0].toUpperCase()+n.slice(1,-1);t.prototype[o]=function(t,e){if("mixed"===r||"mixed"===this.type||r===this.type){t=""+t;var n=this._nodes.get(t);if(void 0===n)throw new Y("Graph.".concat(o,': could not find the "').concat(t,'" node in the graph.'));!function(t,e,n,r){if("mixed"!==t){if("undirected"===t)return Ot(n,n.undirected,r);if("string"==typeof e)return Ot(n,n[e],r)}var i=new Set;"undirected"!==t&&("out"!==e&&Ct(i,n,n.in,r),"in"!==e&&Ct(i,n,n.out,r)),"directed"!==t&&Ct(i,n,n.undirected,r);}("mixed"===r?this.type:r,i,n,e);}};var a="map"+n[0].toUpperCase()+n.slice(1);t.prototype[a]=function(t,e){var n=[];return this[o](t,(function(t,r){n.push(e(t,r));})),n};var u="filter"+n[0].toUpperCase()+n.slice(1);t.prototype[u]=function(t,e){var n=[];return this[o](t,(function(t,r){e(t,r)&&n.push(t);})),n};var c="reduce"+n[0].toUpperCase()+n.slice(1);t.prototype[c]=function(t,e,n){if(arguments.length<3)throw new F("Graph.".concat(c,": missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array."));var r=n;return this[o](t,(function(t,n){r=e(r,t,n);})),r};}function Kt(t,e){var n=e.name,r=e.type,i=e.direction,o=n[0].toUpperCase()+n.slice(1,-1),a="find"+o;t.prototype[a]=function(t,e){if("mixed"===r||"mixed"===this.type||r===this.type){t=""+t;var n=this._nodes.get(t);if(void 0===n)throw new Y("Graph.".concat(a,': could not find the "').concat(t,'" node in the graph.'));return function(t,e,n,r){if("mixed"!==t){if("undirected"===t)return zt(n,n.undirected,r);if("string"==typeof e)return zt(n,n[e],r)}var i,o=new Set;if("undirected"!==t){if("out"!==e&&(i=Mt(o,n,n.in,r)))return i;if("in"!==e&&(i=Mt(o,n,n.out,r)))return i}if("directed"!==t&&(i=Mt(o,n,n.undirected,r)))return i}("mixed"===r?this.type:r,i,n,e)}};var u="some"+o;t.prototype[u]=function(t,e){return !!this[a](t,e)};var c="every"+o;t.prototype[c]=function(t,e){return !this[a](t,(function(t,n){return !e(t,n)}))};}function It(t,e){var n=e.name,r=e.type,i=e.direction,o=n.slice(0,-1)+"Entries";t.prototype[o]=function(t){if("mixed"!==r&&"mixed"!==this.type&&r!==this.type)return O.empty();t=""+t;var e=this._nodes.get(t);if(void 0===e)throw new Y("Graph.".concat(o,': could not find the "').concat(t,'" node in the graph.'));return function(t,e,n){if("mixed"!==t){if("undirected"===t)return Pt(n,n.undirected);if("string"==typeof e)return Pt(n,n[e])}var r=O.empty(),i=new Set;return "undirected"!==t&&("out"!==e&&(r=rt(r,Tt(i,n,n.in))),"in"!==e&&(r=rt(r,Tt(i,n,n.out)))),"directed"!==t&&(r=rt(r,Tt(i,n,n.undirected))),r}("mixed"===r?this.type:r,i,e)};}function Ft(t,e,n,r,i){for(var o,a,u,c,d,s,h,f=r._nodes.values(),p=r.type;!0!==(o=f.next()).done;){var l=!1;if(a=o.value,"undirected"!==p)for(u in c=a.out)if(s=(d=c[u]).target,l=!0,h=i(a.key,s.key,a.attributes,s.attributes,d.key,d.attributes,d.undirected),t&&h)return d;if("directed"!==p)for(u in c=a.undirected)if(!(e&&a.key>u)&&((s=(d=c[u]).target).key!==u&&(s=d.source),l=!0,h=i(a.key,s.key,a.attributes,s.attributes,d.key,d.attributes,d.undirected),t&&h))return d;if(n&&!l&&(h=i(a.key,null,a.attributes,null,null,null,null),t&&h))return null}}function Yt(t,e,n,r,i){for(var o,a,u,c,d,s,h,f,p,l=r._nodes.values(),g=r.type;!0!==(o=l.next()).done;){var y=!1;if(a=o.value,"undirected"!==g)for(u in s=a.out)for(c=s[u].values();!0!==(d=c.next()).done;)if(f=(h=d.value).target,y=!0,p=i(a.key,f.key,a.attributes,f.attributes,h.key,h.attributes,h.undirected),t&&p)return h;if("directed"!==g)for(u in s=a.undirected)if(!(e&&a.key>u))for(c=s[u].values();!0!==(d=c.next()).done;)if((f=(h=d.value).target).key!==u&&(f=h.source),y=!0,p=i(a.key,f.key,a.attributes,f.attributes,h.key,h.attributes,h.undirected),t&&p)return h;if(n&&!y&&(p=i(a.key,null,a.attributes,null,null,null,null),t&&p))return null}}function Bt(t,e){var n={key:t};return f(e.attributes)||(n.attributes=c({},e.attributes)),n}function qt(t,e){var n={key:t,source:e.source.key,target:e.target.key};return f(e.attributes)||(n.attributes=c({},e.attributes)),e.undirected&&(n.undirected=!0),n}function Jt(t){return h(t)?"key"in t?!("attributes"in t)||h(t.attributes)&&null!==t.attributes?null:"invalid-attributes":"no-key":"not-object"}function Vt(t){return h(t)?"source"in t?"target"in t?!("attributes"in t)||h(t.attributes)&&null!==t.attributes?"undirected"in t&&"boolean"!=typeof t.undirected?"invalid-undirected":null:"invalid-attributes":"no-target":"no-source":"not-object"}var Ht,Qt=(Ht=255&Math.floor(256*Math.random()),function(){return Ht++}),Xt=new Set(["directed","undirected","mixed"]),Zt=new Set(["domain","_events","_eventsCount","_maxListeners"]),$t={allowSelfLoops:!0,multi:!1,type:"mixed"};function te(t,e,n){var r=new t.NodeDataClass(e,n);return t._nodes.set(e,r),t.emit("nodeAdded",{key:e,attributes:n}),r}function ee(t,e,n,r,i,o,a,u){if(!r&&"undirected"===t.type)throw new B("Graph.".concat(e,": you cannot add a directed edge to an undirected graph. Use the #.addEdge or #.addUndirectedEdge instead."));if(r&&"directed"===t.type)throw new B("Graph.".concat(e,": you cannot add an undirected edge to a directed graph. Use the #.addEdge or #.addDirectedEdge instead."));if(u&&!h(u))throw new F("Graph.".concat(e,': invalid attributes. Expecting an object but got "').concat(u,'"'));if(o=""+o,a=""+a,u=u||{},!t.allowSelfLoops&&o===a)throw new B("Graph.".concat(e,': source & target are the same ("').concat(o,"\"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false."));var c=t._nodes.get(o),d=t._nodes.get(a);if(!c)throw new Y("Graph.".concat(e,': source node "').concat(o,'" not found.'));if(!d)throw new Y("Graph.".concat(e,': target node "').concat(a,'" not found.'));var s={key:null,undirected:r,source:o,target:a,attributes:u};if(n)i=t._edgeKeyGenerator();else if(i=""+i,t._edges.has(i))throw new B("Graph.".concat(e,': the "').concat(i,'" edge already exists in the graph.'));if(!t.multi&&(r?void 0!==c.undirected[a]:void 0!==c.out[a]))throw new B("Graph.".concat(e,': an edge linking "').concat(o,'" to "').concat(a,"\" already exists. If you really want to add multiple edges linking those nodes, you should create a multi graph by using the 'multi' option."));var f=new H(r,i,c,d,u);return t._edges.set(i,f),o===a?r?(c.undirectedSelfLoops++,t._undirectedSelfLoopCount++):(c.directedSelfLoops++,t._directedSelfLoopCount++):r?(c.undirectedDegree++,d.undirectedDegree++):(c.outDegree++,d.inDegree++),Q(t,r,f,o,a,c,d),r?t._undirectedSize++:t._directedSize++,s.key=i,t.emit("edgeAdded",s),i}function ne(t,e,n,r,i,o,a,u,d){if(!r&&"undirected"===t.type)throw new B("Graph.".concat(e,": you cannot merge/update a directed edge to an undirected graph. Use the #.mergeEdge/#.updateEdge or #.addUndirectedEdge instead."));if(r&&"directed"===t.type)throw new B("Graph.".concat(e,": you cannot merge/update an undirected edge to a directed graph. Use the #.mergeEdge/#.updateEdge or #.addDirectedEdge instead."));if(u)if(d){if("function"!=typeof u)throw new F("Graph.".concat(e,': invalid updater function. Expecting a function but got "').concat(u,'"'))}else if(!h(u))throw new F("Graph.".concat(e,': invalid attributes. Expecting an object but got "').concat(u,'"'));var s;if(o=""+o,a=""+a,d&&(s=u,u=void 0),!t.allowSelfLoops&&o===a)throw new B("Graph.".concat(e,': source & target are the same ("').concat(o,"\"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false."));var f,p,l=t._nodes.get(o),g=t._nodes.get(a);if(!n&&(f=t._edges.get(i))){if(f.source.key!==o||f.target.key!==a||r&&(f.source.key!==a||f.target.key!==o))throw new B("Graph.".concat(e,': inconsistency detected when attempting to merge the "').concat(i,'" edge with "').concat(o,'" source & "').concat(a,'" target vs. ("').concat(f.source.key,'", "').concat(f.target.key,'").'));p=f;}if(p||t.multi||!l||(p=r?l.undirected[a]:l.out[a]),p){var y=[p.key,!1,!1,!1];if(d?!s:!u)return y;if(d){var v=p.attributes;p.attributes=s(v),t.emit("edgeAttributesUpdated",{type:"replace",key:p.key,attributes:p.attributes});}else c(p.attributes,u),t.emit("edgeAttributesUpdated",{type:"merge",key:p.key,attributes:p.attributes,data:u});return y}u=u||{},d&&s&&(u=s(u));var b={key:null,undirected:r,source:o,target:a,attributes:u};if(n)i=t._edgeKeyGenerator();else if(i=""+i,t._edges.has(i))throw new B("Graph.".concat(e,': the "').concat(i,'" edge already exists in the graph.'));var w=!1,m=!1;return l||(l=te(t,o,{}),w=!0,o===a&&(g=l,m=!0)),g||(g=te(t,a,{}),m=!0),f=new H(r,i,l,g,u),t._edges.set(i,f),o===a?r?(l.undirectedSelfLoops++,t._undirectedSelfLoopCount++):(l.directedSelfLoops++,t._directedSelfLoopCount++):r?(l.undirectedDegree++,g.undirectedDegree++):(l.outDegree++,g.inDegree++),Q(t,r,f,o,a,l,g),r?t._undirectedSize++:t._directedSize++,b.key=i,t.emit("edgeAdded",b),[i,!0,w,m]}var re=function(n){function r(t){var e;if(e=n.call(this)||this,"boolean"!=typeof(t=c({},$t,t)).multi)throw new F("Graph.constructor: invalid 'multi' option. Expecting a boolean but got \"".concat(t.multi,'".'));if(!Xt.has(t.type))throw new F('Graph.constructor: invalid \'type\' option. Should be one of "mixed", "directed" or "undirected" but got "'.concat(t.type,'".'));if("boolean"!=typeof t.allowSelfLoops)throw new F("Graph.constructor: invalid 'allowSelfLoops' option. Expecting a boolean but got \"".concat(t.allowSelfLoops,'".'));var r="mixed"===t.type?q:"directed"===t.type?J:V;p(u(e),"NodeDataClass",r);var i=Qt(),o=0;return p(u(e),"_attributes",{}),p(u(e),"_nodes",new Map),p(u(e),"_edges",new Map),p(u(e),"_directedSize",0),p(u(e),"_undirectedSize",0),p(u(e),"_directedSelfLoopCount",0),p(u(e),"_undirectedSelfLoopCount",0),p(u(e),"_edgeKeyGenerator",(function(){var t;do{t="geid_"+i+"_"+o++;}while(e._edges.has(t));return t})),p(u(e),"_options",t),Zt.forEach((function(t){return p(u(e),t,e[t])})),l(u(e),"order",(function(){return e._nodes.size})),l(u(e),"size",(function(){return e._edges.size})),l(u(e),"directedSize",(function(){return e._directedSize})),l(u(e),"undirectedSize",(function(){return e._undirectedSize})),l(u(e),"selfLoopCount",(function(){return e._directedSelfLoopCount+e._undirectedSelfLoopCount})),l(u(e),"directedSelfLoopCount",(function(){return e._directedSelfLoopCount})),l(u(e),"undirectedSelfLoopCount",(function(){return e._undirectedSelfLoopCount})),l(u(e),"multi",e._options.multi),l(u(e),"type",e._options.type),l(u(e),"allowSelfLoops",e._options.allowSelfLoops),l(u(e),"implementation",(function(){return "graphology"})),e}e(r,n);var i=r.prototype;return i._resetInstanceCounters=function(){this._directedSize=0,this._undirectedSize=0,this._directedSelfLoopCount=0,this._undirectedSelfLoopCount=0;},i.hasNode=function(t){return this._nodes.has(""+t)},i.hasDirectedEdge=function(t,e){if("undirected"===this.type)return !1;if(1===arguments.length){var n=""+t,r=this._edges.get(n);return !!r&&!r.undirected}if(2===arguments.length){t=""+t,e=""+e;var i=this._nodes.get(t);if(!i)return !1;var o=i.out[e];return !!o&&(!this.multi||!!o.size)}throw new F("Graph.hasDirectedEdge: invalid arity (".concat(arguments.length,", instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target."))},i.hasUndirectedEdge=function(t,e){if("directed"===this.type)return !1;if(1===arguments.length){var n=""+t,r=this._edges.get(n);return !!r&&r.undirected}if(2===arguments.length){t=""+t,e=""+e;var i=this._nodes.get(t);if(!i)return !1;var o=i.undirected[e];return !!o&&(!this.multi||!!o.size)}throw new F("Graph.hasDirectedEdge: invalid arity (".concat(arguments.length,", instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target."))},i.hasEdge=function(t,e){if(1===arguments.length){var n=""+t;return this._edges.has(n)}if(2===arguments.length){t=""+t,e=""+e;var r=this._nodes.get(t);if(!r)return !1;var i=void 0!==r.out&&r.out[e];return i||(i=void 0!==r.undirected&&r.undirected[e]),!!i&&(!this.multi||!!i.size)}throw new F("Graph.hasEdge: invalid arity (".concat(arguments.length,", instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target."))},i.directedEdge=function(t,e){if("undirected"!==this.type){if(t=""+t,e=""+e,this.multi)throw new B("Graph.directedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.directedEdges instead.");var n=this._nodes.get(t);if(!n)throw new Y('Graph.directedEdge: could not find the "'.concat(t,'" source node in the graph.'));if(!this._nodes.has(e))throw new Y('Graph.directedEdge: could not find the "'.concat(e,'" target node in the graph.'));var r=n.out&&n.out[e]||void 0;return r?r.key:void 0}},i.undirectedEdge=function(t,e){if("directed"!==this.type){if(t=""+t,e=""+e,this.multi)throw new B("Graph.undirectedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.undirectedEdges instead.");var n=this._nodes.get(t);if(!n)throw new Y('Graph.undirectedEdge: could not find the "'.concat(t,'" source node in the graph.'));if(!this._nodes.has(e))throw new Y('Graph.undirectedEdge: could not find the "'.concat(e,'" target node in the graph.'));var r=n.undirected&&n.undirected[e]||void 0;return r?r.key:void 0}},i.edge=function(t,e){if(this.multi)throw new B("Graph.edge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.edges instead.");t=""+t,e=""+e;var n=this._nodes.get(t);if(!n)throw new Y('Graph.edge: could not find the "'.concat(t,'" source node in the graph.'));if(!this._nodes.has(e))throw new Y('Graph.edge: could not find the "'.concat(e,'" target node in the graph.'));var r=n.out&&n.out[e]||n.undirected&&n.undirected[e]||void 0;if(r)return r.key},i.areDirectedNeighbors=function(t,e){t=""+t,e=""+e;var n=this._nodes.get(t);if(!n)throw new Y('Graph.areDirectedNeighbors: could not find the "'.concat(t,'" node in the graph.'));return "undirected"!==this.type&&(e in n.in||e in n.out)},i.areOutNeighbors=function(t,e){t=""+t,e=""+e;var n=this._nodes.get(t);if(!n)throw new Y('Graph.areOutNeighbors: could not find the "'.concat(t,'" node in the graph.'));return "undirected"!==this.type&&e in n.out},i.areInNeighbors=function(t,e){t=""+t,e=""+e;var n=this._nodes.get(t);if(!n)throw new Y('Graph.areInNeighbors: could not find the "'.concat(t,'" node in the graph.'));return "undirected"!==this.type&&e in n.in},i.areUndirectedNeighbors=function(t,e){t=""+t,e=""+e;var n=this._nodes.get(t);if(!n)throw new Y('Graph.areUndirectedNeighbors: could not find the "'.concat(t,'" node in the graph.'));return "directed"!==this.type&&e in n.undirected},i.areNeighbors=function(t,e){t=""+t,e=""+e;var n=this._nodes.get(t);if(!n)throw new Y('Graph.areNeighbors: could not find the "'.concat(t,'" node in the graph.'));return "undirected"!==this.type&&(e in n.in||e in n.out)||"directed"!==this.type&&e in n.undirected},i.areInboundNeighbors=function(t,e){t=""+t,e=""+e;var n=this._nodes.get(t);if(!n)throw new Y('Graph.areInboundNeighbors: could not find the "'.concat(t,'" node in the graph.'));return "undirected"!==this.type&&e in n.in||"directed"!==this.type&&e in n.undirected},i.areOutboundNeighbors=function(t,e){t=""+t,e=""+e;var n=this._nodes.get(t);if(!n)throw new Y('Graph.areOutboundNeighbors: could not find the "'.concat(t,'" node in the graph.'));return "undirected"!==this.type&&e in n.out||"directed"!==this.type&&e in n.undirected},i.inDegree=function(t){t=""+t;var e=this._nodes.get(t);if(!e)throw new Y('Graph.inDegree: could not find the "'.concat(t,'" node in the graph.'));return "undirected"===this.type?0:e.inDegree+e.directedSelfLoops},i.outDegree=function(t){t=""+t;var e=this._nodes.get(t);if(!e)throw new Y('Graph.outDegree: could not find the "'.concat(t,'" node in the graph.'));return "undirected"===this.type?0:e.outDegree+e.directedSelfLoops},i.directedDegree=function(t){t=""+t;var e=this._nodes.get(t);if(!e)throw new Y('Graph.directedDegree: could not find the "'.concat(t,'" node in the graph.'));if("undirected"===this.type)return 0;var n=e.directedSelfLoops;return e.inDegree+n+(e.outDegree+n)},i.undirectedDegree=function(t){t=""+t;var e=this._nodes.get(t);if(!e)throw new Y('Graph.undirectedDegree: could not find the "'.concat(t,'" node in the graph.'));if("directed"===this.type)return 0;var n=e.undirectedSelfLoops;return e.undirectedDegree+2*n},i.degree=function(t){t=""+t;var e=this._nodes.get(t);if(!e)throw new Y('Graph.degree: could not find the "'.concat(t,'" node in the graph.'));var n=0;return "directed"!==this.type&&(n+=e.undirectedDegree+2*e.undirectedSelfLoops),"undirected"!==this.type&&(n+=e.inDegree+e.outDegree+2*e.directedSelfLoops),n},i.inDegreeWithoutSelfLoops=function(t){t=""+t;var e=this._nodes.get(t);if(!e)throw new Y('Graph.inDegreeWithoutSelfLoops: could not find the "'.concat(t,'" node in the graph.'));return "undirected"===this.type?0:e.inDegree},i.outDegreeWithoutSelfLoops=function(t){t=""+t;var e=this._nodes.get(t);if(!e)throw new Y('Graph.outDegreeWithoutSelfLoops: could not find the "'.concat(t,'" node in the graph.'));return "undirected"===this.type?0:e.outDegree},i.directedDegreeWithoutSelfLoops=function(t){t=""+t;var e=this._nodes.get(t);if(!e)throw new Y('Graph.directedDegreeWithoutSelfLoops: could not find the "'.concat(t,'" node in the graph.'));return "undirected"===this.type?0:e.inDegree+e.outDegree},i.undirectedDegreeWithoutSelfLoops=function(t){t=""+t;var e=this._nodes.get(t);if(!e)throw new Y('Graph.undirectedDegreeWithoutSelfLoops: could not find the "'.concat(t,'" node in the graph.'));return "directed"===this.type?0:e.undirectedDegree},i.degreeWithoutSelfLoops=function(t){t=""+t;var e=this._nodes.get(t);if(!e)throw new Y('Graph.degreeWithoutSelfLoops: could not find the "'.concat(t,'" node in the graph.'));var n=0;return "directed"!==this.type&&(n+=e.undirectedDegree),"undirected"!==this.type&&(n+=e.inDegree+e.outDegree),n},i.source=function(t){t=""+t;var e=this._edges.get(t);if(!e)throw new Y('Graph.source: could not find the "'.concat(t,'" edge in the graph.'));return e.source.key},i.target=function(t){t=""+t;var e=this._edges.get(t);if(!e)throw new Y('Graph.target: could not find the "'.concat(t,'" edge in the graph.'));return e.target.key},i.extremities=function(t){t=""+t;var e=this._edges.get(t);if(!e)throw new Y('Graph.extremities: could not find the "'.concat(t,'" edge in the graph.'));return [e.source.key,e.target.key]},i.opposite=function(t,e){t=""+t,e=""+e;var n=this._edges.get(e);if(!n)throw new Y('Graph.opposite: could not find the "'.concat(e,'" edge in the graph.'));var r=n.source.key,i=n.target.key;if(t===r)return i;if(t===i)return r;throw new Y('Graph.opposite: the "'.concat(t,'" node is not attached to the "').concat(e,'" edge (').concat(r,", ").concat(i,")."))},i.hasExtremity=function(t,e){t=""+t,e=""+e;var n=this._edges.get(t);if(!n)throw new Y('Graph.hasExtremity: could not find the "'.concat(t,'" edge in the graph.'));return n.source.key===e||n.target.key===e},i.isUndirected=function(t){t=""+t;var e=this._edges.get(t);if(!e)throw new Y('Graph.isUndirected: could not find the "'.concat(t,'" edge in the graph.'));return e.undirected},i.isDirected=function(t){t=""+t;var e=this._edges.get(t);if(!e)throw new Y('Graph.isDirected: could not find the "'.concat(t,'" edge in the graph.'));return !e.undirected},i.isSelfLoop=function(t){t=""+t;var e=this._edges.get(t);if(!e)throw new Y('Graph.isSelfLoop: could not find the "'.concat(t,'" edge in the graph.'));return e.source===e.target},i.addNode=function(t,e){var n=function(t,e,n){if(n&&!h(n))throw new F('Graph.addNode: invalid attributes. Expecting an object but got "'.concat(n,'"'));if(e=""+e,n=n||{},t._nodes.has(e))throw new B('Graph.addNode: the "'.concat(e,'" node already exist in the graph.'));var r=new t.NodeDataClass(e,n);return t._nodes.set(e,r),t.emit("nodeAdded",{key:e,attributes:n}),r}(this,t,e);return n.key},i.mergeNode=function(t,e){if(e&&!h(e))throw new F('Graph.mergeNode: invalid attributes. Expecting an object but got "'.concat(e,'"'));t=""+t,e=e||{};var n=this._nodes.get(t);return n?(e&&(c(n.attributes,e),this.emit("nodeAttributesUpdated",{type:"merge",key:t,attributes:n.attributes,data:e})),[t,!1]):(n=new this.NodeDataClass(t,e),this._nodes.set(t,n),this.emit("nodeAdded",{key:t,attributes:e}),[t,!0])},i.updateNode=function(t,e){if(e&&"function"!=typeof e)throw new F('Graph.updateNode: invalid updater function. Expecting a function but got "'.concat(e,'"'));t=""+t;var n=this._nodes.get(t);if(n){if(e){var r=n.attributes;n.attributes=e(r),this.emit("nodeAttributesUpdated",{type:"replace",key:t,attributes:n.attributes});}return [t,!1]}var i=e?e({}):{};return n=new this.NodeDataClass(t,i),this._nodes.set(t,n),this.emit("nodeAdded",{key:t,attributes:i}),[t,!0]},i.dropNode=function(t){var e=this;t=""+t;var n=this._nodes.get(t);if(!n)throw new Y('Graph.dropNode: could not find the "'.concat(t,'" node in the graph.'));this.forEachEdge(t,(function(t){e.dropEdge(t);})),this._nodes.delete(t),this.emit("nodeDropped",{key:t,attributes:n.attributes});},i.dropEdge=function(t){var e;if(arguments.length>1){var n=""+arguments[0],r=""+arguments[1];if(!(e=d(this,n,r,this.type)))throw new Y('Graph.dropEdge: could not find the "'.concat(n,'" -> "').concat(r,'" edge in the graph.'))}else if(t=""+t,!(e=this._edges.get(t)))throw new Y('Graph.dropEdge: could not find the "'.concat(t,'" edge in the graph.'));this._edges.delete(e.key);var i=e,o=i.source,a=i.target,u=i.attributes,c=e.undirected;return o===a?c?(o.undirectedSelfLoops--,this._undirectedSelfLoopCount--):(o.directedSelfLoops--,this._directedSelfLoopCount--):c?(o.undirectedDegree--,a.undirectedDegree--):(o.outDegree--,a.inDegree--),X(this,c,e),c?this._undirectedSize--:this._directedSize--,this.emit("edgeDropped",{key:t,attributes:u,source:o.key,target:a.key,undirected:c}),this},i.clear=function(){this._edges.clear(),this._nodes.clear(),this._resetInstanceCounters(),this.emit("cleared");},i.clearEdges=function(){!function(t){for(var e,n=t._nodes.values();!0!==(e=n.next()).done;)e.value.clear();}(this),this._edges.clear(),this._resetInstanceCounters(),this.emit("edgesCleared");},i.getAttribute=function(t){return this._attributes[t]},i.getAttributes=function(){return this._attributes},i.hasAttribute=function(t){return this._attributes.hasOwnProperty(t)},i.setAttribute=function(t,e){return this._attributes[t]=e,this.emit("attributesUpdated",{type:"set",attributes:this._attributes,name:t}),this},i.updateAttribute=function(t,e){if("function"!=typeof e)throw new F("Graph.updateAttribute: updater should be a function.");var n=this._attributes[t];return this._attributes[t]=e(n),this.emit("attributesUpdated",{type:"set",attributes:this._attributes,name:t}),this},i.removeAttribute=function(t){return delete this._attributes[t],this.emit("attributesUpdated",{type:"remove",attributes:this._attributes,name:t}),this},i.replaceAttributes=function(t){if(!h(t))throw new F("Graph.replaceAttributes: provided attributes are not a plain object.");return this._attributes=t,this.emit("attributesUpdated",{type:"replace",attributes:this._attributes}),this},i.mergeAttributes=function(t){if(!h(t))throw new F("Graph.mergeAttributes: provided attributes are not a plain object.");return c(this._attributes,t),this.emit("attributesUpdated",{type:"merge",attributes:this._attributes,data:t}),this},i.updateAttributes=function(t){if("function"!=typeof t)throw new F("Graph.updateAttributes: provided updater is not a function.");return this._attributes=t(this._attributes),this.emit("attributesUpdated",{type:"update",attributes:this._attributes}),this},i.updateEachNodeAttributes=function(t,e){if("function"!=typeof t)throw new F("Graph.updateEachNodeAttributes: expecting an updater function.");if(e&&!g(e))throw new F("Graph.updateEachNodeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}");for(var n,r,i=this._nodes.values();!0!==(n=i.next()).done;)(r=n.value).attributes=t(r.key,r.attributes);this.emit("eachNodeAttributesUpdated",{hints:e||null});},i.updateEachEdgeAttributes=function(t,e){if("function"!=typeof t)throw new F("Graph.updateEachEdgeAttributes: expecting an updater function.");if(e&&!g(e))throw new F("Graph.updateEachEdgeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}");for(var n,r,i,o,a=this._edges.values();!0!==(n=a.next()).done;)i=(r=n.value).source,o=r.target,r.attributes=t(r.key,r.attributes,i.key,o.key,i.attributes,o.attributes,r.undirected);this.emit("eachEdgeAttributesUpdated",{hints:e||null});},i.forEachAdjacencyEntry=function(t){if("function"!=typeof t)throw new F("Graph.forEachAdjacencyEntry: expecting a callback.");this.multi?Yt(!1,!1,!1,this,t):Ft(!1,!1,!1,this,t);},i.forEachAdjacencyEntryWithOrphans=function(t){if("function"!=typeof t)throw new F("Graph.forEachAdjacencyEntryWithOrphans: expecting a callback.");this.multi?Yt(!1,!1,!0,this,t):Ft(!1,!1,!0,this,t);},i.forEachAssymetricAdjacencyEntry=function(t){if("function"!=typeof t)throw new F("Graph.forEachAssymetricAdjacencyEntry: expecting a callback.");this.multi?Yt(!1,!0,!1,this,t):Ft(!1,!0,!1,this,t);},i.forEachAssymetricAdjacencyEntryWithOrphans=function(t){if("function"!=typeof t)throw new F("Graph.forEachAssymetricAdjacencyEntryWithOrphans: expecting a callback.");this.multi?Yt(!1,!0,!0,this,t):Ft(!1,!0,!0,this,t);},i.nodes=function(){return "function"==typeof Array.from?Array.from(this._nodes.keys()):K(this._nodes.keys(),this._nodes.size)},i.forEachNode=function(t){if("function"!=typeof t)throw new F("Graph.forEachNode: expecting a callback.");for(var e,n,r=this._nodes.values();!0!==(e=r.next()).done;)t((n=e.value).key,n.attributes);},i.findNode=function(t){if("function"!=typeof t)throw new F("Graph.findNode: expecting a callback.");for(var e,n,r=this._nodes.values();!0!==(e=r.next()).done;)if(t((n=e.value).key,n.attributes))return n.key},i.mapNodes=function(t){if("function"!=typeof t)throw new F("Graph.mapNode: expecting a callback.");for(var e,n,r=this._nodes.values(),i=new Array(this.order),o=0;!0!==(e=r.next()).done;)n=e.value,i[o++]=t(n.key,n.attributes);return i},i.someNode=function(t){if("function"!=typeof t)throw new F("Graph.someNode: expecting a callback.");for(var e,n,r=this._nodes.values();!0!==(e=r.next()).done;)if(t((n=e.value).key,n.attributes))return !0;return !1},i.everyNode=function(t){if("function"!=typeof t)throw new F("Graph.everyNode: expecting a callback.");for(var e,n,r=this._nodes.values();!0!==(e=r.next()).done;)if(!t((n=e.value).key,n.attributes))return !1;return !0},i.filterNodes=function(t){if("function"!=typeof t)throw new F("Graph.filterNodes: expecting a callback.");for(var e,n,r=this._nodes.values(),i=[];!0!==(e=r.next()).done;)t((n=e.value).key,n.attributes)&&i.push(n.key);return i},i.reduceNodes=function(t,e){if("function"!=typeof t)throw new F("Graph.reduceNodes: expecting a callback.");if(arguments.length<2)throw new F("Graph.reduceNodes: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.");for(var n,r,i=e,o=this._nodes.values();!0!==(n=o.next()).done;)i=t(i,(r=n.value).key,r.attributes);return i},i.nodeEntries=function(){var t=this._nodes.values();return new O((function(){var e=t.next();if(e.done)return e;var n=e.value;return {value:{node:n.key,attributes:n.attributes},done:!1}}))},i.exportNode=function(t){t=""+t;var e=this._nodes.get(t);if(!e)throw new Y('Graph.exportNode: could not find the "'.concat(t,'" node in the graph.'));return Bt(t,e)},i.exportEdge=function(t){t=""+t;var e=this._edges.get(t);if(!e)throw new Y('Graph.exportEdge: could not find the "'.concat(t,'" edge in the graph.'));return qt(t,e)},i.export=function(){var t=new Array(this._nodes.size),e=0;this._nodes.forEach((function(n,r){t[e++]=Bt(r,n);}));var n=new Array(this._edges.size);return e=0,this._edges.forEach((function(t,r){n[e++]=qt(r,t);})),{attributes:this.getAttributes(),nodes:t,edges:n,options:{type:this.type,multi:this.multi,allowSelfLoops:this.allowSelfLoops}}},i.importNode=function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=Jt(t);if(n){if("not-object"===n)throw new F('Graph.importNode: invalid serialized node. A serialized node should be a plain object with at least a "key" property.');if("no-key"===n)throw new F("Graph.importNode: no key provided.");if("invalid-attributes"===n)throw new F("Graph.importNode: invalid attributes. Attributes should be a plain object, null or omitted.")}var r=t.key,i=t.attributes,o=void 0===i?{}:i;return e?this.mergeNode(r,o):this.addNode(r,o),this},i.importEdge=function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=Vt(t);if(n){if("not-object"===n)throw new F('Graph.importEdge: invalid serialized edge. A serialized edge should be a plain object with at least a "source" & "target" property.');if("no-source"===n)throw new F("Graph.importEdge: missing souce.");if("no-target"===n)throw new F("Graph.importEdge: missing target.");if("invalid-attributes"===n)throw new F("Graph.importEdge: invalid attributes. Attributes should be a plain object, null or omitted.");if("invalid-undirected"===n)throw new F("Graph.importEdge: invalid undirected. Undirected should be boolean or omitted.")}var r=t.source,i=t.target,o=t.attributes,a=void 0===o?{}:o,u=t.undirected,c=void 0!==u&&u;return "key"in t?(e?c?this.mergeUndirectedEdgeWithKey:this.mergeDirectedEdgeWithKey:c?this.addUndirectedEdgeWithKey:this.addDirectedEdgeWithKey).call(this,t.key,r,i,a):(e?c?this.mergeUndirectedEdge:this.mergeDirectedEdge:c?this.addUndirectedEdge:this.addDirectedEdge).call(this,r,i,a),this},i.import=function(t){var e,n,r,i=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(s(t))return this.import(t.export(),i),this;if(!h(t))throw new F("Graph.import: invalid argument. Expecting a serialized graph or, alternatively, a Graph instance.");if(t.attributes){if(!h(t.attributes))throw new F("Graph.import: invalid attributes. Expecting a plain object.");i?this.mergeAttributes(t.attributes):this.replaceAttributes(t.attributes);}if(t.nodes){if(r=t.nodes,!Array.isArray(r))throw new F("Graph.import: invalid nodes. Expecting an array.");for(e=0,n=r.length;en)){var a=new Set;a.add(e.undirected[o]),e.undirected[o]=a,t._nodes.get(o).undirected[n]=a;}}))),this;var t;},i.toJSON=function(){return this.export()},i.toString=function(){return "[object Graph]"},i.inspect=function(){var e=this,n={};this._nodes.forEach((function(t,e){n[e]=t.attributes;}));var r={},i={};this._edges.forEach((function(t,n){var o,a=t.undirected?"--":"->",u="",c=t.source.key,d=t.target.key;t.undirected&&c>d&&(o=c,c=d,d=o);var s="(".concat(c,")").concat(a,"(").concat(d,")");n.startsWith("geid_")?e.multi&&(void 0===i[s]?i[s]=0:i[s]++,u+="".concat(i[s],". ")):u+="[".concat(n,"]: "),r[u+=s]=t.attributes;}));var o={};for(var a in this)this.hasOwnProperty(a)&&!Zt.has(a)&&"function"!=typeof this[a]&&"symbol"!==t(a)&&(o[a]=this[a]);return o.attributes=this._attributes,o.nodes=n,o.edges=r,p(o,"constructor",this.constructor),o},r}(v.exports.EventEmitter);"undefined"!=typeof Symbol&&(re.prototype[Symbol.for("nodejs.util.inspect.custom")]=re.prototype.inspect),[{name:function(t){return "".concat(t,"Edge")},generateKey:!0},{name:function(t){return "".concat(t,"DirectedEdge")},generateKey:!0,type:"directed"},{name:function(t){return "".concat(t,"UndirectedEdge")},generateKey:!0,type:"undirected"},{name:function(t){return "".concat(t,"EdgeWithKey")}},{name:function(t){return "".concat(t,"DirectedEdgeWithKey")},type:"directed"},{name:function(t){return "".concat(t,"UndirectedEdgeWithKey")},type:"undirected"}].forEach((function(t){["add","merge","update"].forEach((function(e){var n=t.name(e),r="add"===e?ee:ne;t.generateKey?re.prototype[n]=function(i,o,a){return r(this,n,!0,"undirected"===(t.type||this.type),null,i,o,a,"update"===e)}:re.prototype[n]=function(i,o,a,u){return r(this,n,!1,"undirected"===(t.type||this.type),i,o,a,u,"update"===e)};}));})),function(t){$.forEach((function(e){var n=e.name,r=e.attacher;r(t,n("Node"),0),r(t,n("Source"),1),r(t,n("Target"),2),r(t,n("Opposite"),3);}));}(re),function(t){tt.forEach((function(e){var n=e.name,r=e.attacher;r(t,n("Edge"),"mixed"),r(t,n("DirectedEdge"),"directed"),r(t,n("UndirectedEdge"),"undirected");}));}(re),function(t){it.forEach((function(e){!function(t,e){var n=e.name,r=e.type,i=e.direction;t.prototype[n]=function(t,e){if("mixed"!==r&&"mixed"!==this.type&&r!==this.type)return [];if(!arguments.length)return wt(this,r);if(1===arguments.length){t=""+t;var o=this._nodes.get(t);if(void 0===o)throw new Y("Graph.".concat(n,': could not find the "').concat(t,'" node in the graph.'));return Gt(this.multi,"mixed"===r?this.type:r,i,o)}if(2===arguments.length){t=""+t,e=""+e;var a=this._nodes.get(t);if(!a)throw new Y("Graph.".concat(n,': could not find the "').concat(t,'" source node in the graph.'));if(!this._nodes.has(e))throw new Y("Graph.".concat(n,': could not find the "').concat(e,'" target node in the graph.'));return At(r,this.multi,i,a,e)}throw new F("Graph.".concat(n,": too many arguments (expecting 0, 1 or 2 and got ").concat(arguments.length,")."))};}(t,e),function(t,e){var n=e.name,r=e.type,i=e.direction,o="forEach"+n[0].toUpperCase()+n.slice(1,-1);t.prototype[o]=function(t,e,n){if("mixed"===r||"mixed"===this.type||r===this.type){if(1===arguments.length)return mt(this,r,n=t);if(2===arguments.length){t=""+t,n=e;var a=this._nodes.get(t);if(void 0===a)throw new Y("Graph.".concat(o,': could not find the "').concat(t,'" node in the graph.'));return xt(this.multi,"mixed"===r?this.type:r,i,a,n)}if(3===arguments.length){t=""+t,e=""+e;var u=this._nodes.get(t);if(!u)throw new Y("Graph.".concat(o,': could not find the "').concat(t,'" source node in the graph.'));if(!this._nodes.has(e))throw new Y("Graph.".concat(o,': could not find the "').concat(e,'" target node in the graph.'));return Lt(r,this.multi,i,u,e,n)}throw new F("Graph.".concat(o,": too many arguments (expecting 1, 2 or 3 and got ").concat(arguments.length,")."))}};var a="map"+n[0].toUpperCase()+n.slice(1);t.prototype[a]=function(){var t,e=Array.prototype.slice.call(arguments),n=e.pop();if(0===e.length){var i=0;"directed"!==r&&(i+=this.undirectedSize),"undirected"!==r&&(i+=this.directedSize),t=new Array(i);var a=0;e.push((function(e,r,i,o,u,c,d){t[a++]=n(e,r,i,o,u,c,d);}));}else t=[],e.push((function(e,r,i,o,a,u,c){t.push(n(e,r,i,o,a,u,c));}));return this[o].apply(this,e),t};var u="filter"+n[0].toUpperCase()+n.slice(1);t.prototype[u]=function(){var t=Array.prototype.slice.call(arguments),e=t.pop(),n=[];return t.push((function(t,r,i,o,a,u,c){e(t,r,i,o,a,u,c)&&n.push(t);})),this[o].apply(this,t),n};var c="reduce"+n[0].toUpperCase()+n.slice(1);t.prototype[c]=function(){var t,e,n=Array.prototype.slice.call(arguments);if(n.length<2||n.length>4)throw new F("Graph.".concat(c,": invalid number of arguments (expecting 2, 3 or 4 and got ").concat(n.length,")."));if("function"==typeof n[n.length-1]&&"function"!=typeof n[n.length-2])throw new F("Graph.".concat(c,": missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array."));2===n.length?(t=n[0],e=n[1],n=[]):3===n.length?(t=n[1],e=n[2],n=[n[0]]):4===n.length&&(t=n[2],e=n[3],n=[n[0],n[1]]);var r=e;return n.push((function(e,n,i,o,a,u,c){r=t(r,e,n,i,o,a,u,c);})),this[o].apply(this,n),r};}(t,e),function(t,e){var n=e.name,r=e.type,i=e.direction,o="find"+n[0].toUpperCase()+n.slice(1,-1);t.prototype[o]=function(t,e,n){if("mixed"!==r&&"mixed"!==this.type&&r!==this.type)return !1;if(1===arguments.length)return _t(this,r,n=t);if(2===arguments.length){t=""+t,n=e;var a=this._nodes.get(t);if(void 0===a)throw new Y("Graph.".concat(o,': could not find the "').concat(t,'" node in the graph.'));return Et(this.multi,"mixed"===r?this.type:r,i,a,n)}if(3===arguments.length){t=""+t,e=""+e;var u=this._nodes.get(t);if(!u)throw new Y("Graph.".concat(o,': could not find the "').concat(t,'" source node in the graph.'));if(!this._nodes.has(e))throw new Y("Graph.".concat(o,': could not find the "').concat(e,'" target node in the graph.'));return Dt(r,this.multi,i,u,e,n)}throw new F("Graph.".concat(o,": too many arguments (expecting 1, 2 or 3 and got ").concat(arguments.length,")."))};var a="some"+n[0].toUpperCase()+n.slice(1,-1);t.prototype[a]=function(){var t=Array.prototype.slice.call(arguments),e=t.pop();return t.push((function(t,n,r,i,o,a,u){return e(t,n,r,i,o,a,u)})),!!this[o].apply(this,t)};var u="every"+n[0].toUpperCase()+n.slice(1,-1);t.prototype[u]=function(){var t=Array.prototype.slice.call(arguments),e=t.pop();return t.push((function(t,n,r,i,o,a,u){return !e(t,n,r,i,o,a,u)})),!this[o].apply(this,t)};}(t,e),function(t,e){var n=e.name,r=e.type,i=e.direction,o=n.slice(0,-1)+"Entries";t.prototype[o]=function(t,e){if("mixed"!==r&&"mixed"!==this.type&&r!==this.type)return O.empty();if(!arguments.length)return kt(this,r);if(1===arguments.length){t=""+t;var n=this._nodes.get(t);if(!n)throw new Y("Graph.".concat(o,': could not find the "').concat(t,'" node in the graph.'));return St(r,i,n)}if(2===arguments.length){t=""+t,e=""+e;var a=this._nodes.get(t);if(!a)throw new Y("Graph.".concat(o,': could not find the "').concat(t,'" source node in the graph.'));if(!this._nodes.has(e))throw new Y("Graph.".concat(o,': could not find the "').concat(e,'" target node in the graph.'));return Nt(r,i,a,e)}throw new F("Graph.".concat(o,": too many arguments (expecting 0, 1 or 2 and got ").concat(arguments.length,")."))};}(t,e);}));}(re),function(t){Ut.forEach((function(e){Rt(t,e),Wt(t,e),Kt(t,e),It(t,e);}));}(re);var ie=function(t){function n(e){var n=c({type:"directed"},e);if("multi"in n&&!1!==n.multi)throw new F("DirectedGraph.from: inconsistent indication that the graph should be multi in given options!");if("directed"!==n.type)throw new F('DirectedGraph.from: inconsistent "'+n.type+'" type in given options!');return t.call(this,n)||this}return e(n,t),n}(re),oe=function(t){function n(e){var n=c({type:"undirected"},e);if("multi"in n&&!1!==n.multi)throw new F("UndirectedGraph.from: inconsistent indication that the graph should be multi in given options!");if("undirected"!==n.type)throw new F('UndirectedGraph.from: inconsistent "'+n.type+'" type in given options!');return t.call(this,n)||this}return e(n,t),n}(re),ae=function(t){function n(e){var n=c({multi:!0},e);if("multi"in n&&!0!==n.multi)throw new F("MultiGraph.from: inconsistent indication that the graph should be simple in given options!");return t.call(this,n)||this}return e(n,t),n}(re),ue=function(t){function n(e){var n=c({type:"directed",multi:!0},e);if("multi"in n&&!0!==n.multi)throw new F("MultiDirectedGraph.from: inconsistent indication that the graph should be simple in given options!");if("directed"!==n.type)throw new F('MultiDirectedGraph.from: inconsistent "'+n.type+'" type in given options!');return t.call(this,n)||this}return e(n,t),n}(re),ce=function(t){function n(e){var n=c({type:"undirected",multi:!0},e);if("multi"in n&&!0!==n.multi)throw new F("MultiUndirectedGraph.from: inconsistent indication that the graph should be simple in given options!");if("undirected"!==n.type)throw new F('MultiUndirectedGraph.from: inconsistent "'+n.type+'" type in given options!');return t.call(this,n)||this}return e(n,t),n}(re);function de(t){t.from=function(e,n){var r=c({},e.options,n),i=new t(r);return i.import(e),i};}return de(re),de(ie),de(oe),de(ae),de(ue),de(ce),re.Graph=re,re.DirectedGraph=ie,re.UndirectedGraph=oe,re.MultiGraph=ae,re.MultiDirectedGraph=ue,re.MultiUndirectedGraph=ce,re.InvalidArgumentsGraphError=F,re.NotFoundGraphError=Y,re.UsageGraphError=B,re})); @@ -2477,9 +2473,17 @@ const VISTYPES = [ "Radial Tree", ]; const DIRECTIONS = ["up", "same", "down"]; +const ARROW_DIRECTIONS = { + up: "↑", + same: "→", + down: "↓", +}; const RELATIONS = ["Parent", "Sibling", "Child"]; const REAlCLOSED = ["Real", "Closed"]; const ALLUNLINKED = ["All", "No Unlinked"]; +const blankUserHier = () => { + return { up: [], same: [], down: [] }; +}; const DEFAULT_SETTINGS = { userHierarchies: [], indexNote: [""], @@ -2522,543 +2526,16 @@ const DEFAULT_SETTINGS = { superDebugMode: false, }; -const wikilinkRegex = '\\[\\[([^\\]\\r\\n]+?)\\]\\]'; -const nameRegex = '[^\\W\\d]\\w*'; -const regexEscape = function (str) { - return str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); -}; -const parseTypedLink = function (link, line, typedLinkPrefix) { - // TODO: This is something specific I use, but shouldn't keep being in this repo. - const regexPublishedIn = new RegExp(`^${regexEscape(typedLinkPrefix)} (publishedIn) (\\d\\d\\d\\d) (${wikilinkRegex},? *)+$`); - const matchPI = regexPublishedIn.exec(line); - if (!(matchPI === null)) { - return { - class: 'type-publishedIn', - isInline: false, - properties: { - year: matchPI[2], - context: '', - type: 'publishedIn', - }, - }; - } - // Intuition: Start with the typed link prefix. Then a neo4j name (nameRegex). - // Then one or more of the wikilink group: wikilink regex separated by optional comma and multiple spaces - const regex = new RegExp(`^${regexEscape(typedLinkPrefix)} (${nameRegex}) (${wikilinkRegex},? *)+$`); - const match = regex.exec(line); - const splitLink = link.original.split('|'); - let alias = null; - if (splitLink.length > 1) { - alias = splitLink.slice(1).join().slice(0, -2); - } - if (!(match === null)) { - return { - class: `type-${match[1]}`, - isInline: false, - properties: { - alias: alias, - context: '', - type: match[1], - }, - }; - } - return null; -}; +/** + * @license + * Lodash + * Copyright OpenJS Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ -function normalise(arr) { - const max = Math.max(...arr); - return arr.map((item) => item / max); -} -function debug(settings, log) { - if (settings.debugMode) { - console.log(log); - } -} -function superDebug(settings, log) { - if (settings.superDebugMode) { - console.log(log); - } -} -function debugGroupStart(settings, type, group) { - if (settings[type]) { - console.groupCollapsed(group); - } -} -function debugGroupEnd(settings, type) { - if (settings[type]) { - console.groupEnd(); - } -} -function getDVMetadataCache(app, settings, files) { - debugGroupStart(settings, "debugMode", "getDVMetadataCache"); - debug(settings, "Using Dataview"); - debugGroupStart(settings, "superDebugMode", "dvCaches"); - const fileFrontmatterArr = []; - files.forEach((file) => { - superDebug(settings, `GetDVMetadataCache: ${file.basename}`); - const dvCache = app.plugins.plugins.dataview.api.page(file.path); - superDebug(settings, { dvCache }); - fileFrontmatterArr.push(dvCache); - }); - debugGroupEnd(settings, "superDebugMode"); - debug(settings, { fileFrontmatterArr }); - debugGroupEnd(settings, "debugMode"); - return fileFrontmatterArr; -} -function getObsMetadataCache(app, settings, files) { - debugGroupStart(settings, "debugMode", "getObsMetadataCache"); - debug(settings, "Using Obsidian"); - debugGroupStart(settings, "superDebugMode", "obsCaches"); - const fileFrontmatterArr = []; - files.forEach((file) => { - var _a; - superDebug(settings, `GetObsMetadataCache: ${file.basename}`); - const obs = (_a = app.metadataCache.getFileCache(file)) === null || _a === void 0 ? void 0 : _a.frontmatter; - superDebug(settings, { obs }); - if (obs) { - fileFrontmatterArr.push(Object.assign({ file }, obs)); - } - else { - fileFrontmatterArr.push({ file }); - } - }); - debugGroupEnd(settings, "superDebugMode"); - debug(settings, { fileFrontmatterArr }); - debugGroupEnd(settings, "debugMode"); - return fileFrontmatterArr; -} -// TODO I think it'd be better to do this whole thing as an obj instead of JugglLink[] -// => {[note: string]: {type: string, linksInLine: string[]}[]} -async function getJugglLinks(app, settings) { - debugGroupStart(settings, "debugMode", "getJugglLinks"); - debug(settings, "Using Juggl"); - const files = app.vault.getMarkdownFiles(); - const { userHierarchies } = settings; - // Add Juggl links - const typedLinksArr = await Promise.all(files.map(async (file) => { - var _a, _b; - const jugglLink = { note: file.basename, links: [] }; - // Use Obs metadatacache to get the links in the current file - const links = (_b = (_a = app.metadataCache.getFileCache(file)) === null || _a === void 0 ? void 0 : _a.links) !== null && _b !== void 0 ? _b : []; - // TODO Only get cachedRead if links.length - const content = await app.vault.cachedRead(file); - links.forEach((link) => { - var _a, _b, _c, _d, _e, _f, _g; - // Get the line no. of each link - const lineNo = link.position.start.line; - // And the corresponding line content - const line = content.split("\n")[lineNo]; - // Get an array of inner text of each link - const linksInLine = (_c = (_b = (_a = line - .match(splitLinksRegex)) === null || _a === void 0 ? void 0 : _a.map((link) => link.slice(2, link.length - 2))) === null || _b === void 0 ? void 0 : _b.map((innerText) => innerText.split("|")[0])) !== null && _c !== void 0 ? _c : []; - const typedLinkPrefix = (_e = (_d = app.plugins.plugins.juggl) === null || _d === void 0 ? void 0 : _d.settings.typedLinkPrefix) !== null && _e !== void 0 ? _e : "-"; - const parsedLinks = parseTypedLink(link, line, typedLinkPrefix); - const type = (_g = (_f = parsedLinks === null || parsedLinks === void 0 ? void 0 : parsedLinks.properties) === null || _f === void 0 ? void 0 : _f.type) !== null && _g !== void 0 ? _g : ""; - let typeDir = ""; - DIRECTIONS.forEach((dir) => { - userHierarchies.forEach((hier) => { - if (hier[dir].includes(type)) { - typeDir = dir; - return; - } - }); - }); - jugglLink.links.push({ - dir: typeDir, - type, - linksInLine, - }); - }); - return jugglLink; - })); - debug(settings, { typedLinksArr }); - const allFields = settings.userHierarchies - .map((hier) => Object.values(hier)) - .flat(2) - .filter((field) => field !== ""); - typedLinksArr.forEach((jugglLink) => { - // Filter out links whose type is not in allFields - const fieldTypesOnly = jugglLink.links.filter((link) => allFields.includes(link.type)); - // // const fieldTypesOnly = []; - // jugglLink.links.forEach((link) => { - // if (allFields.includes(link.type)) { - // fieldTypesOnly.push(link); - // } - // }); - // I don't remember why I'm mutating the links instead of making a new obj - jugglLink.links = fieldTypesOnly; - }); - // Filter out the juggl links with no links - const filteredLinks = typedLinksArr.filter((jugglLink) => jugglLink.links.length); - debug(settings, { filteredLinks }); - debugGroupEnd(settings, "debugMode"); - return filteredLinks; -} -function getFieldValues(frontmatterCache, field, settings) { - var _a; - const values = []; - try { - const rawValuesPreFlat = frontmatterCache === null || frontmatterCache === void 0 ? void 0 : frontmatterCache[field]; - if (!rawValuesPreFlat) - return []; - if (typeof rawValuesPreFlat === "string") { - const splits = rawValuesPreFlat.match(splitLinksRegex); - if (splits !== null) { - const strs = splits.map((link) => link.match(dropHeaderOrAlias)[1].split("/").last()); - values.push(...strs); - } - // else { - // Dont't add anything, it's not a link - // } - } - else { - const rawValues = [rawValuesPreFlat].flat(4); - superDebug(settings, `${field} of: ${(_a = frontmatterCache === null || frontmatterCache === void 0 ? void 0 : frontmatterCache.file) === null || _a === void 0 ? void 0 : _a.path}`); - superDebug(settings, rawValues); - rawValues.forEach((rawItem) => { - if (!rawItem) - return; - let unProxied = [rawItem]; - if (util__default['default'].types.isProxy(rawItem)) { - unProxied = []; - // Definitely a proxy the first time - const first = Object.assign({}, rawItem); - first.values.forEach((firstVal) => { - if (util__default['default'].types.isProxy(firstVal)) { - const second = Object.assign({}, firstVal); - const secondValues = second.values; - if (secondValues) { - secondValues.forEach((secondVal) => { - if (util__default['default'].types.isProxy(secondVal)) { - const third = Object.assign({}, secondVal).values; - third.forEach((thirdVal) => { - unProxied.push(thirdVal); - }); - } - else { - unProxied.push(secondVal); - } - }); - } - else { - unProxied.push(second); - } - } - else { - unProxied.push(firstVal); - } - }); - } - unProxied.forEach((value) => { - console.log({ unproxiedValue: value }); - if (typeof value === "string" || typeof value === "number") { - // Obs cache converts link of form: [[\d+]] to number[][] - const rawItemAsString = value.toString(); - const splits = rawItemAsString.match(splitLinksRegex); - if (splits !== null) { - const strs = splits.map((link) => link.match(dropHeaderOrAlias)[1].split("/").last()); - values.push(...strs); - } - else { - values.push(rawItemAsString.split("/").last()); - } - } - else if (value.path !== undefined) { - const lastSplit = value.path.split("/").last(); - if (lastSplit !== undefined) { - values.push(lastSplit); - } - } - }); - }); - } - return values; - } - catch (error) { - console.log(error); - return values; - } -} -const splitAndTrim = (fields) => fields.split(",").map((str) => str.trim()); -async function getNeighbourObjArr(plugin, fileFrontmatterArr) { - const { settings } = plugin; - const { userHierarchies } = settings; - if (settings.debugMode || settings.superDebugMode) { - console.groupCollapsed("getNeighbourObjArr"); - } - let jugglLinks = []; - if (plugin.app.plugins.plugins.juggl !== undefined || - plugin.settings.parseJugglLinksWithoutJuggl) { - jugglLinks = await getJugglLinks(plugin.app, plugin.settings); - } - const neighbourObjArr = fileFrontmatterArr.map((fileFrontmatter) => { - const currFileName = fileFrontmatter.file.basename || fileFrontmatter.file.name; - const hierFields = { - current: fileFrontmatter.file, - hierarchies: [], - }; - userHierarchies.forEach((hier, i) => { - const fieldsArr = Object.values(hier); - const newHier = { up: {}, same: {}, down: {} }; - // Add regular metadata links - if (settings.useAllMetadata) { - DIRECTIONS.forEach((dir, i) => { - fieldsArr[i].forEach((field) => { - newHier[dir][field] = getFieldValues(fileFrontmatter, field, settings); - }); - }); - } - // Add Juggl Links - if (jugglLinks.length) { - const jugglLinksInFile = jugglLinks.filter((jugglLink) => { - return jugglLink.note === currFileName; - })[0]; - if (jugglLinksInFile) { - jugglLinksInFile.links.forEach((line) => { - var _a; - if (hier[line.dir].includes(line.type)) { - newHier[line.dir][line.type] = [ - ...new Set([ - ...((_a = newHier[line.dir][line.type]) !== null && _a !== void 0 ? _a : []), - ...line.linksInLine, - ]), - ]; - } - }); - } - } - hierFields.hierarchies.push(newHier); - }); - return hierFields; - }); - debug(settings, { neighbourObjArr }); - if (settings.debugMode || settings.superDebugMode) { - console.groupEnd(); - } - return neighbourObjArr; -} -// This function takes the real & implied graphs for a given relation, and returns a new graphs with both. -// It makes implied relations real -function closeImpliedLinks(real, implied) { - const closedG = real.copy(); - implied.forEachEdge((key, a, s, t) => { - closedG.mergeEdge(s, t, a); - }); - return closedG; -} -const isInVault = (app, note) => !!app.metadataCache.getFirstLinkpathDest(note, app.workspace.getActiveFile().path); -function hoverPreview(event, matrixView, to) { - const targetEl = event.target; - matrixView.app.workspace.trigger("hover-link", { - event, - source: matrixView.getViewType(), - hoverParent: matrixView, - targetEl, - linktext: to, - }); -} -async function openOrSwitch(app, dest, currFile, event) { - const { workspace } = app; - let destFile = app.metadataCache.getFirstLinkpathDest(dest, currFile.path); - // If dest doesn't exist, make it - if (!destFile) { - const newFileFolder = app.fileManager.getNewFileParent(currFile.path).path; - const newFilePath = `${newFileFolder}${newFileFolder === "/" ? "" : "/"}${dest}.md`; - await app.vault.create(newFilePath, ""); - destFile = app.metadataCache.getFirstLinkpathDest(newFilePath, currFile.path); - } - // Check if it's already open - const leavesWithDestAlreadyOpen = []; - // For all open leaves, if the leave's basename is equal to the link destination, rather activate that leaf instead of opening it in two panes - workspace.iterateAllLeaves((leaf) => { - var _a, _b; - if (((_b = (_a = leaf.view) === null || _a === void 0 ? void 0 : _a.file) === null || _b === void 0 ? void 0 : _b.basename) === dest) { - leavesWithDestAlreadyOpen.push(leaf); - } - }); - // Rather switch to it if it is open - if (leavesWithDestAlreadyOpen.length > 0) { - workspace.setActiveLeaf(leavesWithDestAlreadyOpen[0]); - } - else { - const mode = app.vault.getConfig("defaultViewMode"); - const leaf = event.ctrlKey || event.getModifierState("Meta") - ? workspace.splitActiveLeaf() - : workspace.getUnpinnedLeaf(); - await leaf.openFile(destFile, { active: true, mode }); - } -} -function padArray(arr, finalLength, filler = "") { - const copy = [...arr]; - const currLength = copy.length; - if (currLength > finalLength) { - throw new Error("Current length is greater than final length"); - } - else if (currLength === finalLength) { - return copy; - } - else { - for (let i = currLength; i < finalLength; i++) { - copy.push(filler); - } - return copy; - } -} -function transpose(A) { - const cols = A[0].length; - const AT = []; - // For each column - for (let j = 0; j < cols; j++) { - // Add a new row to AT - AT.push([]); - // And fill it with the values in the jth column of A - A.forEach((row) => AT[j].push(row[j])); - } - return AT; -} -function runs(arr) { - const runs = []; - let i = 0; - while (i < arr.length) { - const currValue = arr[i]; - runs.push({ value: currValue, first: i, last: undefined }); - while (currValue === arr[i]) { - i++; - } - runs.last().last = i - 1; - } - return runs; -} -async function copy$1(content) { - await navigator.clipboard.writeText(content).then(() => new obsidian.Notice("Copied to clipboard"), () => new obsidian.Notice("Could not copy to clipboard")); -} -function mergeGs(...graphs) { - const outG = new graphology_umd_min(); - graphs.forEach((g) => { - g.forEachNode((node, a) => { - outG.mergeNode(node, a); - }); - g.forEachEdge((key, a, s, t) => { - outG.mergeEdge(s, t, a); - }); - }); - return outG; -} -function removeUnlinkedNodes(g) { - const copy = g.copy(); - copy.forEachNode((node) => { - if (!copy.neighbors(node).length) - copy.dropNode(node); - }); - return copy; -} -function getAllGsInDir(currGraphs, dir) { - const target = {}; - const allGsInDir = Object.assign(target, ...currGraphs.map((hierGs) => hierGs[dir])); - return allGsInDir; -} -function iterateAllGs(currGraphs, cb) { - for (const hierGs of currGraphs) { - for (const dir of DIRECTIONS) { - for (const fieldName in hierGs[dir]) { - const g = hierGs[dir][fieldName]; - cb(g, dir, fieldName); - } - } - } -} -function getAllFieldGs(fields, currGraphs) { - const fieldGs = []; - iterateAllGs(currGraphs, (g, dir, fieldName) => { - if (fields.includes(fieldName)) - fieldGs.push(g); - }); - return fieldGs; -} -function hierToStr(hier) { - return `↑: ${hier.up.join(", ")} -→: ${hier.same.join(", ")} -↓: ${hier.down.join(", ")}`; -} -function removeDuplicates(arr) { - return [...new Set(arr)]; -} -/** - * Adds or updates the given yaml `key` to `value` in the given TFile - * @param {string} key - * @param {string} value - * @param {TFile} file - * @param {FrontMatterCache|undefined} frontmatter - * @param {{[fun:string]:(...args:any} api - */ -const createOrUpdateYaml = async (key, value, file, frontmatter, api) => { - let valueStr = value.toString(); - if (!frontmatter || frontmatter[key] === undefined) { - console.log(`Creating: ${key}: ${valueStr}`); - await api.createYamlProperty(key, `['${valueStr}']`, file); - } - else if ([...[frontmatter[key]]].flat(3).some((val) => val == valueStr)) { - console.log("Already Exists!"); - return; - } - else { - const oldValueFlat = [...[frontmatter[key]]].flat(4); - const newValue = [...oldValueFlat, valueStr].map((val) => `'${val}'`); - console.log(`Updating: ${key}: ${newValue}`); - await api.update(key, `[${newValue.join(", ")}]`, file); - } -}; -const getOppDir = (dir) => dir === "same" ? "same" : dir === "up" ? "down" : "up"; -const writeBCToFile = (app, plugin, currGraphs, file) => { - var _a, _b; - const frontmatter = (_a = app.metadataCache.getFileCache(file)) === null || _a === void 0 ? void 0 : _a.frontmatter; - const api = (_b = app.plugins.plugins.metaedit) === null || _b === void 0 ? void 0 : _b.api; - if (!api) { - new obsidian.Notice("Metaedit must be enabled for this function to work"); - return; - } - iterateAllGs(currGraphs.hierGs, (fieldG, dir, fieldName) => { - const oppDir = getOppDir(dir); - const succs = fieldG.inNeighbors(file.basename); - succs.forEach(async (succ) => { - const { fieldName } = fieldG.getNodeAttributes(succ); - if (!plugin.settings.limitWriteBCCheckboxStates[fieldName]) - return; - const currHier = plugin.settings.userHierarchies.find((hier) => hier[dir].includes(fieldName)); - let oppField = currHier[oppDir][0]; - if (!oppField) - oppField = `${fieldName}`; - await createOrUpdateYaml(oppField, succ, file, frontmatter, api); - }); - }); -}; -function oppFields(field, dir, userHierarchies) { - var _a, _b; - const oppDir = getOppDir(dir); - return ((_b = (_a = userHierarchies.find((hier) => hier[oppDir].includes(field))) === null || _a === void 0 ? void 0 : _a[oppDir]) !== null && _b !== void 0 ? _b : []); -} -function addNodeIfNot(g, node, attr) { - if (!g.hasNode(node)) { - g.addNode(node, attr); - } -} -function addEdgeIfNot(g, source, target, attr) { - if (!g.hasEdge(source, target)) { - g.addEdge(source, target, attr); - } -} -const getSinks = (g) => g.filterNodes((node) => !g.outNeighbors(node).length); - -/** - * @license - * Lodash - * Copyright OpenJS Foundation and other contributors - * Released under MIT license - * Based on Underscore.js 1.8.3 - * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - */ - -var lodash$1 = createCommonjsModule(function (module, exports) { +var lodash = createCommonjsModule(function (module, exports) { (function() { /** Used as a safe reference for `undefined` in pre-ES5 environments. */ @@ -20248,17468 +19725,12609 @@ var lodash$1 = createCommonjsModule(function (module, exports) { }.call(commonjsGlobal)); }); -function noop$2() { } -function run(fn) { - return fn(); -} -function blank_object() { - return Object.create(null); -} -function run_all(fns) { - fns.forEach(run); -} -function is_function(thing) { - return typeof thing === 'function'; -} -function safe_not_equal(a, b) { - return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function'); -} -function is_empty(obj) { - return Object.keys(obj).length === 0; -} -function null_to_empty(value) { - return value == null ? '' : value; -} - -function append(target, node) { - target.appendChild(node); -} -function insert(target, node, anchor) { - target.insertBefore(node, anchor || null); -} -function detach(node) { - node.parentNode.removeChild(node); -} -function destroy_each(iterations, detaching) { - for (let i = 0; i < iterations.length; i += 1) { - if (iterations[i]) - iterations[i].d(detaching); - } -} -function element(name) { - return document.createElement(name); -} -function text(data) { - return document.createTextNode(data); -} -function space() { - return text(' '); -} -function empty$1() { - return text(''); -} -function listen(node, event, handler, options) { - node.addEventListener(event, handler, options); - return () => node.removeEventListener(event, handler, options); -} -function attr(node, attribute, value) { - if (value == null) - node.removeAttribute(attribute); - else if (node.getAttribute(attribute) !== value) - node.setAttribute(attribute, value); -} -function children$1(element) { - return Array.from(element.childNodes); -} -function set_data(text, data) { - data = '' + data; - if (text.wholeText !== data) - text.data = data; -} -function set_style(node, key, value, important) { - node.style.setProperty(key, value, important ? 'important' : ''); -} -function select_option(select, value) { - for (let i = 0; i < select.options.length; i += 1) { - const option = select.options[i]; - if (option.__value === value) { - option.selected = true; - return; - } - } -} - -let current_component; -function set_current_component(component) { - current_component = component; -} - -const dirty_components = []; -const binding_callbacks = []; -const render_callbacks = []; -const flush_callbacks = []; -const resolved_promise = Promise.resolve(); -let update_scheduled = false; -function schedule_update() { - if (!update_scheduled) { - update_scheduled = true; - resolved_promise.then(flush); - } -} -function add_render_callback(fn) { - render_callbacks.push(fn); -} -let flushing = false; -const seen_callbacks = new Set(); -function flush() { - if (flushing) - return; - flushing = true; - do { - // first, call beforeUpdate functions - // and update components - for (let i = 0; i < dirty_components.length; i += 1) { - const component = dirty_components[i]; - set_current_component(component); - update(component.$$); - } - set_current_component(null); - dirty_components.length = 0; - while (binding_callbacks.length) - binding_callbacks.pop()(); - // then, once components are updated, call - // afterUpdate functions. This may cause - // subsequent updates... - for (let i = 0; i < render_callbacks.length; i += 1) { - const callback = render_callbacks[i]; - if (!seen_callbacks.has(callback)) { - // ...so guard against infinite loops - seen_callbacks.add(callback); - callback(); - } - } - render_callbacks.length = 0; - } while (dirty_components.length); - while (flush_callbacks.length) { - flush_callbacks.pop()(); - } - update_scheduled = false; - flushing = false; - seen_callbacks.clear(); -} -function update($$) { - if ($$.fragment !== null) { - $$.update(); - run_all($$.before_update); - const dirty = $$.dirty; - $$.dirty = [-1]; - $$.fragment && $$.fragment.p($$.ctx, dirty); - $$.after_update.forEach(add_render_callback); - } -} -const outroing = new Set(); -function transition_in(block, local) { - if (block && block.i) { - outroing.delete(block); - block.i(local); - } -} -function mount_component(component, target, anchor, customElement) { - const { fragment, on_mount, on_destroy, after_update } = component.$$; - fragment && fragment.m(target, anchor); - if (!customElement) { - // onMount happens before the initial afterUpdate - add_render_callback(() => { - const new_on_destroy = on_mount.map(run).filter(is_function); - if (on_destroy) { - on_destroy.push(...new_on_destroy); - } - else { - // Edge case - component was destroyed immediately, - // most likely as a result of a binding initialising - run_all(new_on_destroy); - } - component.$$.on_mount = []; - }); - } - after_update.forEach(add_render_callback); -} -function destroy_component(component, detaching) { - const $$ = component.$$; - if ($$.fragment !== null) { - run_all($$.on_destroy); - $$.fragment && $$.fragment.d(detaching); - // TODO null out other refs, including component.$$ (but need to - // preserve final state?) - $$.on_destroy = $$.fragment = null; - $$.ctx = []; - } -} -function make_dirty(component, i) { - if (component.$$.dirty[0] === -1) { - dirty_components.push(component); - schedule_update(); - component.$$.dirty.fill(0); - } - component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31)); -} -function init$1(component, options, instance, create_fragment, not_equal, props, dirty = [-1]) { - const parent_component = current_component; - set_current_component(component); - const $$ = component.$$ = { - fragment: null, - ctx: null, - // state - props, - update: noop$2, - not_equal, - bound: blank_object(), - // lifecycle - on_mount: [], - on_destroy: [], - on_disconnect: [], - before_update: [], - after_update: [], - context: new Map(parent_component ? parent_component.$$.context : []), - // everything else - callbacks: blank_object(), - dirty, - skip_bound: false - }; - let ready = false; - $$.ctx = instance - ? instance(component, options.props || {}, (i, ret, ...rest) => { - const value = rest.length ? rest[0] : ret; - if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) { - if (!$$.skip_bound && $$.bound[i]) - $$.bound[i](value); - if (ready) - make_dirty(component, i); - } - return ret; - }) - : []; - $$.update(); - ready = true; - run_all($$.before_update); - // `false` as a special case of no DOM component - $$.fragment = create_fragment ? create_fragment($$.ctx) : false; - if (options.target) { - if (options.hydrate) { - const nodes = children$1(options.target); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - $$.fragment && $$.fragment.l(nodes); - nodes.forEach(detach); - } - else { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - $$.fragment && $$.fragment.c(); - } - if (options.intro) - transition_in(component.$$.fragment); - mount_component(component, options.target, options.anchor, options.customElement); - flush(); - } - set_current_component(parent_component); -} -/** - * Base class for Svelte components. Used when dev=false. - */ -class SvelteComponent { - $destroy() { - destroy_component(this, 1); - this.$destroy = noop$2; - } - $on(type, callback) { - const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = [])); - callbacks.push(callback); - return () => { - const index = callbacks.indexOf(callback); - if (index !== -1) - callbacks.splice(index, 1); - }; - } - $set($$props) { - if (this.$$set && !is_empty($$props)) { - this.$$.skip_bound = true; - this.$$set($$props); - this.$$.skip_bound = false; - } - } -} - -/* src\Components\KoFi.svelte generated by Svelte v3.35.0 */ - -function create_fragment$6(ctx) { - let script; - let script_src_value; - let t; - let div; - let mounted; - let dispose; - - return { - c() { - script = element("script"); - t = space(); - div = element("div"); - attr(script, "type", "text/javascript"); - if (script.src !== (script_src_value = "https://ko-fi.com/widgets/widget_2.js")) attr(script, "src", script_src_value); - }, - m(target, anchor) { - append(document.head, script); - insert(target, t, anchor); - insert(target, div, anchor); - /*div_binding*/ ctx[2](div); - - if (!mounted) { - dispose = listen(script, "load", /*initializeKofi*/ ctx[1]); - mounted = true; - } - }, - p: noop$2, - i: noop$2, - o: noop$2, - d(detaching) { - detach(script); - if (detaching) detach(t); - if (detaching) detach(div); - /*div_binding*/ ctx[2](null); - mounted = false; - dispose(); - } - }; -} - -function instance$6($$self, $$props, $$invalidate) { - let button; - - var initializeKofi = () => { - kofiwidget2.init("Support Breadcrumbs development!", "#29abe0", "G2G454TZF"); - $$invalidate(0, button.innerHTML = kofiwidget2.getHTML(), button); - }; - - function div_binding($$value) { - binding_callbacks[$$value ? "unshift" : "push"](() => { - button = $$value; - $$invalidate(0, button); - }); - } - - return [button, initializeKofi, div_binding]; -} - -class KoFi extends SvelteComponent { - constructor(options) { - super(); - init$1(this, options, instance$6, create_fragment$6, safe_not_equal, {}); - } -} - -/* src\Components\Lists.svelte generated by Svelte v3.35.0 */ - -function add_css$4() { - var style = element("style"); - style.id = "svelte-fwoihq-style"; - style.textContent = "summary.hier-summary.svelte-fwoihq{color:var(--text-title-h2);font-size:larger}summary.svelte-fwoihq{color:var(--text-title-h3)}h5.breadcrumbs-header.svelte-fwoihq{color:var(--text-title-h5)}ol.markdown-preview-view.svelte-fwoihq{padding-top:3px;padding-bottom:5px}"; - append(document.head, style); -} - -function get_each_context$5(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[9] = list[i]; - return child_ctx; -} - -function get_each_context_1$5(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[12] = list[i]; - return child_ctx; -} - -function get_each_context_2$3(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[15] = list[i]; - return child_ctx; -} - -function get_each_context_3$2(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[18] = list[i]; - return child_ctx; -} - -// (21:8) {#if square.realItems.length > 0 || square.impliedItems.length > 0} -function create_if_block$3(ctx) { - let details; - let summary; - let t0_value = /*square*/ ctx[12].fieldName + ""; - let t0; - let t1; - let t2; - let if_block0 = /*square*/ ctx[12].realItems.length && create_if_block_3$1(ctx); - let if_block1 = /*square*/ ctx[12].impliedItems.length && create_if_block_1$2(ctx); - - return { - c() { - details = element("details"); - summary = element("summary"); - t0 = text(t0_value); - t1 = space(); - if (if_block0) if_block0.c(); - t2 = space(); - if (if_block1) if_block1.c(); - attr(summary, "class", "svelte-fwoihq"); - details.open = true; - attr(details, "class", "breadcrumbs-details"); - }, - m(target, anchor) { - insert(target, details, anchor); - append(details, summary); - append(summary, t0); - append(details, t1); - if (if_block0) if_block0.m(details, null); - append(details, t2); - if (if_block1) if_block1.m(details, null); - }, - p(ctx, dirty) { - if (dirty & /*filteredSquaresArr*/ 1 && t0_value !== (t0_value = /*square*/ ctx[12].fieldName + "")) set_data(t0, t0_value); - - if (/*square*/ ctx[12].realItems.length) { - if (if_block0) { - if_block0.p(ctx, dirty); - } else { - if_block0 = create_if_block_3$1(ctx); - if_block0.c(); - if_block0.m(details, t2); - } - } else if (if_block0) { - if_block0.d(1); - if_block0 = null; - } +const wikilinkRegex = '\\[\\[([^\\]\\r\\n]+?)\\]\\]'; +const nameRegex = '[^\\W\\d]\\w*'; +const regexEscape = function (str) { + return str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); +}; +const parseTypedLink = function (link, line, typedLinkPrefix) { + // TODO: This is something specific I use, but shouldn't keep being in this repo. + const regexPublishedIn = new RegExp(`^${regexEscape(typedLinkPrefix)} (publishedIn) (\\d\\d\\d\\d) (${wikilinkRegex},? *)+$`); + const matchPI = regexPublishedIn.exec(line); + if (!(matchPI === null)) { + return { + class: 'type-publishedIn', + isInline: false, + properties: { + year: matchPI[2], + context: '', + type: 'publishedIn', + }, + }; + } + // Intuition: Start with the typed link prefix. Then a neo4j name (nameRegex). + // Then one or more of the wikilink group: wikilink regex separated by optional comma and multiple spaces + const regex = new RegExp(`^${regexEscape(typedLinkPrefix)} (${nameRegex}) (${wikilinkRegex},? *)+$`); + const match = regex.exec(line); + const splitLink = link.original.split('|'); + let alias = null; + if (splitLink.length > 1) { + alias = splitLink.slice(1).join().slice(0, -2); + } + if (!(match === null)) { + return { + class: `type-${match[1]}`, + isInline: false, + properties: { + alias: alias, + context: '', + type: match[1], + }, + }; + } + return null; +}; - if (/*square*/ ctx[12].impliedItems.length) { - if (if_block1) { - if_block1.p(ctx, dirty); - } else { - if_block1 = create_if_block_1$2(ctx); - if_block1.c(); - if_block1.m(details, null); - } - } else if (if_block1) { - if_block1.d(1); - if_block1 = null; - } - }, - d(detaching) { - if (detaching) detach(details); - if (if_block0) if_block0.d(); - if (if_block1) if_block1.d(); - } - }; -} - -// (24:12) {#if square.realItems.length} -function create_if_block_3$1(ctx) { - let t; - let ol; - let if_block = /*settings*/ ctx[2].showRelationType && create_if_block_4$1(); - let each_value_3 = /*square*/ ctx[12].realItems; - let each_blocks = []; - - for (let i = 0; i < each_value_3.length; i += 1) { - each_blocks[i] = create_each_block_3$2(get_each_context_3$2(ctx, each_value_3, i)); - } - - return { - c() { - if (if_block) if_block.c(); - t = space(); - ol = element("ol"); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].c(); - } - - attr(ol, "class", "markdown-preview-view svelte-fwoihq"); - }, - m(target, anchor) { - if (if_block) if_block.m(target, anchor); - insert(target, t, anchor); - insert(target, ol, anchor); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].m(ol, null); - } - }, - p(ctx, dirty) { - if (/*settings*/ ctx[2].showRelationType) { - if (if_block) ; else { - if_block = create_if_block_4$1(); - if_block.c(); - if_block.m(t.parentNode, t); - } - } else if (if_block) { - if_block.d(1); - if_block = null; - } - - if (dirty & /*filteredSquaresArr, openOrSwitch, app, currFile, hoverPreview, matrixView*/ 27) { - each_value_3 = /*square*/ ctx[12].realItems; - let i; - - for (i = 0; i < each_value_3.length; i += 1) { - const child_ctx = get_each_context_3$2(ctx, each_value_3, i); - - if (each_blocks[i]) { - each_blocks[i].p(child_ctx, dirty); - } else { - each_blocks[i] = create_each_block_3$2(child_ctx); - each_blocks[i].c(); - each_blocks[i].m(ol, null); - } - } - - for (; i < each_blocks.length; i += 1) { - each_blocks[i].d(1); - } - - each_blocks.length = each_value_3.length; - } - }, - d(detaching) { - if (if_block) if_block.d(detaching); - if (detaching) detach(t); - if (detaching) detach(ol); - destroy_each(each_blocks, detaching); - } - }; -} - -// (25:14) {#if settings.showRelationType} -function create_if_block_4$1(ctx) { - let h5; - - return { - c() { - h5 = element("h5"); - h5.textContent = "Real"; - attr(h5, "class", "breadcrumbs-header svelte-fwoihq"); - }, - m(target, anchor) { - insert(target, h5, anchor); - }, - d(detaching) { - if (detaching) detach(h5); - } - }; -} - -// (30:16) {#each square.realItems as realItem} -function create_each_block_3$2(ctx) { - let li; - let div; - - let t0_value = (/*realItem*/ ctx[18].alt - ? /*realItem*/ ctx[18].alt - : /*realItem*/ ctx[18].to.split("/").last()) + ""; - - let t0; - let div_class_value; - let t1; - let mounted; - let dispose; - - function click_handler(...args) { - return /*click_handler*/ ctx[5](/*realItem*/ ctx[18], ...args); - } - - function mouseover_handler(...args) { - return /*mouseover_handler*/ ctx[6](/*realItem*/ ctx[18], ...args); - } - - return { - c() { - li = element("li"); - div = element("div"); - t0 = text(t0_value); - t1 = space(); - attr(div, "class", div_class_value = /*realItem*/ ctx[18].cls); - }, - m(target, anchor) { - insert(target, li, anchor); - append(li, div); - append(div, t0); - append(li, t1); - - if (!mounted) { - dispose = [ - listen(div, "click", click_handler), - listen(div, "mouseover", mouseover_handler) - ]; - - mounted = true; - } - }, - p(new_ctx, dirty) { - ctx = new_ctx; - - if (dirty & /*filteredSquaresArr*/ 1 && t0_value !== (t0_value = (/*realItem*/ ctx[18].alt - ? /*realItem*/ ctx[18].alt - : /*realItem*/ ctx[18].to.split("/").last()) + "")) set_data(t0, t0_value); - - if (dirty & /*filteredSquaresArr*/ 1 && div_class_value !== (div_class_value = /*realItem*/ ctx[18].cls)) { - attr(div, "class", div_class_value); - } - }, - d(detaching) { - if (detaching) detach(li); - mounted = false; - run_all(dispose); - } - }; -} - -// (48:12) {#if square.impliedItems.length} -function create_if_block_1$2(ctx) { - let t; - let ol; - let ol_start_value; - let if_block = /*settings*/ ctx[2].showRelationType && create_if_block_2$2(); - let each_value_2 = /*square*/ ctx[12].impliedItems; - let each_blocks = []; - - for (let i = 0; i < each_value_2.length; i += 1) { - each_blocks[i] = create_each_block_2$3(get_each_context_2$3(ctx, each_value_2, i)); - } - - return { - c() { - if (if_block) if_block.c(); - t = space(); - ol = element("ol"); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].c(); - } - - attr(ol, "class", "markdown-preview-view svelte-fwoihq"); - attr(ol, "start", ol_start_value = /*square*/ ctx[12].realItems.length + 1); - }, - m(target, anchor) { - if (if_block) if_block.m(target, anchor); - insert(target, t, anchor); - insert(target, ol, anchor); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].m(ol, null); - } - }, - p(ctx, dirty) { - if (/*settings*/ ctx[2].showRelationType) { - if (if_block) ; else { - if_block = create_if_block_2$2(); - if_block.c(); - if_block.m(t.parentNode, t); - } - } else if (if_block) { - if_block.d(1); - if_block = null; - } - - if (dirty & /*filteredSquaresArr, openOrSwitch, app, currFile, hoverPreview, matrixView*/ 27) { - each_value_2 = /*square*/ ctx[12].impliedItems; - let i; - - for (i = 0; i < each_value_2.length; i += 1) { - const child_ctx = get_each_context_2$3(ctx, each_value_2, i); - - if (each_blocks[i]) { - each_blocks[i].p(child_ctx, dirty); - } else { - each_blocks[i] = create_each_block_2$3(child_ctx); - each_blocks[i].c(); - each_blocks[i].m(ol, null); - } - } - - for (; i < each_blocks.length; i += 1) { - each_blocks[i].d(1); - } - - each_blocks.length = each_value_2.length; - } - - if (dirty & /*filteredSquaresArr*/ 1 && ol_start_value !== (ol_start_value = /*square*/ ctx[12].realItems.length + 1)) { - attr(ol, "start", ol_start_value); - } - }, - d(detaching) { - if (if_block) if_block.d(detaching); - if (detaching) detach(t); - if (detaching) detach(ol); - destroy_each(each_blocks, detaching); - } - }; -} - -// (49:14) {#if settings.showRelationType} -function create_if_block_2$2(ctx) { - let h5; - - return { - c() { - h5 = element("h5"); - h5.textContent = "Implied"; - attr(h5, "class", "breadcrumbs-header svelte-fwoihq"); - }, - m(target, anchor) { - insert(target, h5, anchor); - }, - d(detaching) { - if (detaching) detach(h5); - } - }; -} - -// (57:16) {#each square.impliedItems as impliedItem} -function create_each_block_2$3(ctx) { - let li; - let div; - - let t_value = (/*impliedItem*/ ctx[15].alt - ? /*impliedItem*/ ctx[15].alt - : /*impliedItem*/ ctx[15].to.split("/").last()) + ""; - - let t; - let div_class_value; - let mounted; - let dispose; - - function click_handler_1(...args) { - return /*click_handler_1*/ ctx[7](/*impliedItem*/ ctx[15], ...args); - } - - function mouseover_handler_1(...args) { - return /*mouseover_handler_1*/ ctx[8](/*impliedItem*/ ctx[15], ...args); - } - - return { - c() { - li = element("li"); - div = element("div"); - t = text(t_value); - attr(div, "class", div_class_value = /*impliedItem*/ ctx[15].cls); - attr(li, "class", "breadcrumbs-implied"); - }, - m(target, anchor) { - insert(target, li, anchor); - append(li, div); - append(div, t); - - if (!mounted) { - dispose = [ - listen(div, "click", click_handler_1), - listen(div, "mouseover", mouseover_handler_1) - ]; - - mounted = true; - } - }, - p(new_ctx, dirty) { - ctx = new_ctx; - - if (dirty & /*filteredSquaresArr*/ 1 && t_value !== (t_value = (/*impliedItem*/ ctx[15].alt - ? /*impliedItem*/ ctx[15].alt - : /*impliedItem*/ ctx[15].to.split("/").last()) + "")) set_data(t, t_value); - - if (dirty & /*filteredSquaresArr*/ 1 && div_class_value !== (div_class_value = /*impliedItem*/ ctx[15].cls)) { - attr(div, "class", div_class_value); - } - }, - d(detaching) { - if (detaching) detach(li); - mounted = false; - run_all(dispose); - } - }; -} - -// (20:6) {#each squares as square} -function create_each_block_1$5(ctx) { - let if_block_anchor; - let if_block = (/*square*/ ctx[12].realItems.length > 0 || /*square*/ ctx[12].impliedItems.length > 0) && create_if_block$3(ctx); - - return { - c() { - if (if_block) if_block.c(); - if_block_anchor = empty$1(); - }, - m(target, anchor) { - if (if_block) if_block.m(target, anchor); - insert(target, if_block_anchor, anchor); - }, - p(ctx, dirty) { - if (/*square*/ ctx[12].realItems.length > 0 || /*square*/ ctx[12].impliedItems.length > 0) { - if (if_block) { - if_block.p(ctx, dirty); - } else { - if_block = create_if_block$3(ctx); - if_block.c(); - if_block.m(if_block_anchor.parentNode, if_block_anchor); - } - } else if (if_block) { - if_block.d(1); - if_block = null; - } - }, - d(detaching) { - if (if_block) if_block.d(detaching); - if (detaching) detach(if_block_anchor); - } - }; -} - -// (14:2) {#each filteredSquaresArr as squares} -function create_each_block$5(ctx) { - let details; - let summary; - let t0_value = /*squares*/ ctx[9].map(func).join(", ") + ""; - let t0; - let t1; - let t2; - let each_value_1 = /*squares*/ ctx[9]; - let each_blocks = []; - - for (let i = 0; i < each_value_1.length; i += 1) { - each_blocks[i] = create_each_block_1$5(get_each_context_1$5(ctx, each_value_1, i)); - } - - return { - c() { - details = element("details"); - summary = element("summary"); - t0 = text(t0_value); - t1 = space(); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].c(); - } - - t2 = space(); - attr(summary, "class", "hier-summary svelte-fwoihq"); - details.open = true; - }, - m(target, anchor) { - insert(target, details, anchor); - append(details, summary); - append(summary, t0); - append(details, t1); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].m(details, null); - } - - append(details, t2); - }, - p(ctx, dirty) { - if (dirty & /*filteredSquaresArr*/ 1 && t0_value !== (t0_value = /*squares*/ ctx[9].map(func).join(", ") + "")) set_data(t0, t0_value); - - if (dirty & /*filteredSquaresArr, openOrSwitch, app, currFile, hoverPreview, matrixView, settings*/ 31) { - each_value_1 = /*squares*/ ctx[9]; - let i; - - for (i = 0; i < each_value_1.length; i += 1) { - const child_ctx = get_each_context_1$5(ctx, each_value_1, i); - - if (each_blocks[i]) { - each_blocks[i].p(child_ctx, dirty); - } else { - each_blocks[i] = create_each_block_1$5(child_ctx); - each_blocks[i].c(); - each_blocks[i].m(details, t2); - } - } - - for (; i < each_blocks.length; i += 1) { - each_blocks[i].d(1); - } - - each_blocks.length = each_value_1.length; - } - }, - d(detaching) { - if (detaching) detach(details); - destroy_each(each_blocks, detaching); - } - }; -} - -function create_fragment$5(ctx) { - let div; - let each_value = /*filteredSquaresArr*/ ctx[0]; - let each_blocks = []; - - for (let i = 0; i < each_value.length; i += 1) { - each_blocks[i] = create_each_block$5(get_each_context$5(ctx, each_value, i)); - } - - return { - c() { - div = element("div"); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].c(); - } - - attr(div, "class", "breadcrumbs-list"); - }, - m(target, anchor) { - insert(target, div, anchor); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].m(div, null); - } - }, - p(ctx, [dirty]) { - if (dirty & /*filteredSquaresArr, openOrSwitch, app, currFile, hoverPreview, matrixView, settings*/ 31) { - each_value = /*filteredSquaresArr*/ ctx[0]; - let i; - - for (i = 0; i < each_value.length; i += 1) { - const child_ctx = get_each_context$5(ctx, each_value, i); - - if (each_blocks[i]) { - each_blocks[i].p(child_ctx, dirty); - } else { - each_blocks[i] = create_each_block$5(child_ctx); - each_blocks[i].c(); - each_blocks[i].m(div, null); - } - } - - for (; i < each_blocks.length; i += 1) { - each_blocks[i].d(1); - } - - each_blocks.length = each_value.length; - } - }, - i: noop$2, - o: noop$2, - d(detaching) { - if (detaching) detach(div); - destroy_each(each_blocks, detaching); - } - }; -} - -const func = square => square.fieldName; - -function instance$5($$self, $$props, $$invalidate) { - - - - - let { filteredSquaresArr } = $$props; - let { currFile } = $$props; - let { settings } = $$props; - let { matrixView } = $$props; - let { app } = $$props; - const click_handler = async (realItem, e) => openOrSwitch(app, realItem.to, currFile, e); - const mouseover_handler = (realItem, e) => hoverPreview(e, matrixView, realItem.to); - const click_handler_1 = async (impliedItem, e) => openOrSwitch(app, impliedItem.to, currFile, e); - const mouseover_handler_1 = (impliedItem, e) => hoverPreview(e, matrixView, impliedItem.to); - - $$self.$$set = $$props => { - if ("filteredSquaresArr" in $$props) $$invalidate(0, filteredSquaresArr = $$props.filteredSquaresArr); - if ("currFile" in $$props) $$invalidate(1, currFile = $$props.currFile); - if ("settings" in $$props) $$invalidate(2, settings = $$props.settings); - if ("matrixView" in $$props) $$invalidate(3, matrixView = $$props.matrixView); - if ("app" in $$props) $$invalidate(4, app = $$props.app); - }; - - return [ - filteredSquaresArr, - currFile, - settings, - matrixView, - app, - click_handler, - mouseover_handler, - click_handler_1, - mouseover_handler_1 - ]; -} - -class Lists extends SvelteComponent { - constructor(options) { - super(); - if (!document.getElementById("svelte-fwoihq-style")) add_css$4(); - - init$1(this, options, instance$5, create_fragment$5, safe_not_equal, { - filteredSquaresArr: 0, - currFile: 1, - settings: 2, - matrixView: 3, - app: 4 - }); - } -} - -/* src\Components\Matrix.svelte generated by Svelte v3.35.0 */ - -function add_css$3() { - var style = element("style"); - style.id = "svelte-fq6v4k-style"; - style.textContent = "div.breadcrumbs-matrix.svelte-fq6v4k.svelte-fq6v4k{padding:5px}div.breadcrumbs-matrix.svelte-fq6v4k>div.svelte-fq6v4k{border:3px solid var(--background-modifier-border);border-radius:3px;text-align:center;margin:3px;position:relative;height:fit-content}div.breadcrumbs-matrix-square.svelte-fq6v4k.svelte-fq6v4k{border:1px solid var(--background-modifier-border)}.breadcrumbs-matrix-header.svelte-fq6v4k.svelte-fq6v4k{margin:2px}h3.breadcrumbs-matrix-header.svelte-fq6v4k.svelte-fq6v4k{color:var(--text-title-h3)}h5.breadcrumbs-matrix-header.svelte-fq6v4k.svelte-fq6v4k{color:var(--text-title-h5)}ol.svelte-fq6v4k.svelte-fq6v4k{margin:3px;padding-left:20px}"; - append(document.head, style); -} - -function get_each_context$4(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[9] = list[i]; - return child_ctx; -} - -function get_each_context_1$4(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[12] = list[i]; - return child_ctx; -} - -function get_each_context_2$2(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[15] = list[i]; - return child_ctx; -} - -function get_each_context_3$1(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[18] = list[i]; - return child_ctx; -} - -// (17:8) {#if square.realItems.length > 0 || square.impliedItems.length > 0} -function create_if_block$2(ctx) { - let div; - let h3; - let t0_value = /*square*/ ctx[12].fieldName + ""; - let t0; - let t1; - let t2; - let if_block0 = /*square*/ ctx[12].realItems.length && create_if_block_3(ctx); - let if_block1 = /*square*/ ctx[12].impliedItems.length && create_if_block_1$1(ctx); - - return { - c() { - div = element("div"); - h3 = element("h3"); - t0 = text(t0_value); - t1 = space(); - if (if_block0) if_block0.c(); - t2 = space(); - if (if_block1) if_block1.c(); - attr(h3, "class", "breadcrumbs-matrix-header svelte-fq6v4k"); - attr(div, "class", "breadcrumbs-matrix-square svelte-fq6v4k"); - }, - m(target, anchor) { - insert(target, div, anchor); - append(div, h3); - append(h3, t0); - append(div, t1); - if (if_block0) if_block0.m(div, null); - append(div, t2); - if (if_block1) if_block1.m(div, null); - }, - p(ctx, dirty) { - if (dirty & /*filteredSquaresArr*/ 1 && t0_value !== (t0_value = /*square*/ ctx[12].fieldName + "")) set_data(t0, t0_value); - - if (/*square*/ ctx[12].realItems.length) { - if (if_block0) { - if_block0.p(ctx, dirty); - } else { - if_block0 = create_if_block_3(ctx); - if_block0.c(); - if_block0.m(div, t2); - } - } else if (if_block0) { - if_block0.d(1); - if_block0 = null; - } - - if (/*square*/ ctx[12].impliedItems.length) { - if (if_block1) { - if_block1.p(ctx, dirty); - } else { - if_block1 = create_if_block_1$1(ctx); - if_block1.c(); - if_block1.m(div, null); - } - } else if (if_block1) { - if_block1.d(1); - if_block1 = null; - } - }, - d(detaching) { - if (detaching) detach(div); - if (if_block0) if_block0.d(); - if (if_block1) if_block1.d(); - } - }; -} - -// (21:12) {#if square.realItems.length} -function create_if_block_3(ctx) { - let t; - let ol; - let if_block = /*settings*/ ctx[2].showRelationType && create_if_block_4(); - let each_value_3 = /*square*/ ctx[12].realItems; - let each_blocks = []; - - for (let i = 0; i < each_value_3.length; i += 1) { - each_blocks[i] = create_each_block_3$1(get_each_context_3$1(ctx, each_value_3, i)); - } - - return { - c() { - if (if_block) if_block.c(); - t = space(); - ol = element("ol"); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].c(); - } - - attr(ol, "class", "svelte-fq6v4k"); - }, - m(target, anchor) { - if (if_block) if_block.m(target, anchor); - insert(target, t, anchor); - insert(target, ol, anchor); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].m(ol, null); - } - }, - p(ctx, dirty) { - if (/*settings*/ ctx[2].showRelationType) { - if (if_block) ; else { - if_block = create_if_block_4(); - if_block.c(); - if_block.m(t.parentNode, t); - } - } else if (if_block) { - if_block.d(1); - if_block = null; - } - - if (dirty & /*filteredSquaresArr, openOrSwitch, app, currFile, hoverPreview, matrixView*/ 27) { - each_value_3 = /*square*/ ctx[12].realItems; - let i; - - for (i = 0; i < each_value_3.length; i += 1) { - const child_ctx = get_each_context_3$1(ctx, each_value_3, i); - - if (each_blocks[i]) { - each_blocks[i].p(child_ctx, dirty); - } else { - each_blocks[i] = create_each_block_3$1(child_ctx); - each_blocks[i].c(); - each_blocks[i].m(ol, null); - } - } - - for (; i < each_blocks.length; i += 1) { - each_blocks[i].d(1); - } - - each_blocks.length = each_value_3.length; - } - }, - d(detaching) { - if (if_block) if_block.d(detaching); - if (detaching) detach(t); - if (detaching) detach(ol); - destroy_each(each_blocks, detaching); - } - }; -} - -// (22:14) {#if settings.showRelationType} -function create_if_block_4(ctx) { - let h5; - - return { - c() { - h5 = element("h5"); - h5.textContent = "Real"; - attr(h5, "class", "breadcrumbs-matrix-header svelte-fq6v4k"); - }, - m(target, anchor) { - insert(target, h5, anchor); - }, - d(detaching) { - if (detaching) detach(h5); - } - }; -} - -// (26:16) {#each square.realItems as realItem} -function create_each_block_3$1(ctx) { - let li; - let div; - - let t0_value = (/*realItem*/ ctx[18].alt - ? /*realItem*/ ctx[18].alt - : /*realItem*/ ctx[18].to.split("/").last()) + ""; - - let t0; - let div_class_value; - let t1; - let mounted; - let dispose; - - function click_handler(...args) { - return /*click_handler*/ ctx[5](/*realItem*/ ctx[18], ...args); - } - - function mouseover_handler(...args) { - return /*mouseover_handler*/ ctx[6](/*realItem*/ ctx[18], ...args); - } - - return { - c() { - li = element("li"); - div = element("div"); - t0 = text(t0_value); - t1 = space(); - attr(div, "class", div_class_value = "" + (null_to_empty(/*realItem*/ ctx[18].cls) + " svelte-fq6v4k")); - }, - m(target, anchor) { - insert(target, li, anchor); - append(li, div); - append(div, t0); - append(li, t1); - - if (!mounted) { - dispose = [ - listen(div, "click", click_handler), - listen(div, "mouseover", mouseover_handler) - ]; - - mounted = true; - } - }, - p(new_ctx, dirty) { - ctx = new_ctx; - - if (dirty & /*filteredSquaresArr*/ 1 && t0_value !== (t0_value = (/*realItem*/ ctx[18].alt - ? /*realItem*/ ctx[18].alt - : /*realItem*/ ctx[18].to.split("/").last()) + "")) set_data(t0, t0_value); - - if (dirty & /*filteredSquaresArr*/ 1 && div_class_value !== (div_class_value = "" + (null_to_empty(/*realItem*/ ctx[18].cls) + " svelte-fq6v4k"))) { - attr(div, "class", div_class_value); - } - }, - d(detaching) { - if (detaching) detach(li); - mounted = false; - run_all(dispose); - } - }; -} - -// (44:12) {#if square.impliedItems.length} -function create_if_block_1$1(ctx) { - let t; - let ol; - let ol_start_value; - let if_block = /*settings*/ ctx[2].showRelationType && create_if_block_2$1(); - let each_value_2 = /*square*/ ctx[12].impliedItems; - let each_blocks = []; - - for (let i = 0; i < each_value_2.length; i += 1) { - each_blocks[i] = create_each_block_2$2(get_each_context_2$2(ctx, each_value_2, i)); - } - - return { - c() { - if (if_block) if_block.c(); - t = space(); - ol = element("ol"); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].c(); - } - - attr(ol, "start", ol_start_value = /*square*/ ctx[12].realItems.length + 1); - attr(ol, "class", "svelte-fq6v4k"); - }, - m(target, anchor) { - if (if_block) if_block.m(target, anchor); - insert(target, t, anchor); - insert(target, ol, anchor); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].m(ol, null); - } - }, - p(ctx, dirty) { - if (/*settings*/ ctx[2].showRelationType) { - if (if_block) ; else { - if_block = create_if_block_2$1(); - if_block.c(); - if_block.m(t.parentNode, t); - } - } else if (if_block) { - if_block.d(1); - if_block = null; - } - - if (dirty & /*filteredSquaresArr, openOrSwitch, app, currFile, hoverPreview, matrixView*/ 27) { - each_value_2 = /*square*/ ctx[12].impliedItems; - let i; - - for (i = 0; i < each_value_2.length; i += 1) { - const child_ctx = get_each_context_2$2(ctx, each_value_2, i); - - if (each_blocks[i]) { - each_blocks[i].p(child_ctx, dirty); - } else { - each_blocks[i] = create_each_block_2$2(child_ctx); - each_blocks[i].c(); - each_blocks[i].m(ol, null); - } - } - - for (; i < each_blocks.length; i += 1) { - each_blocks[i].d(1); - } - - each_blocks.length = each_value_2.length; - } - - if (dirty & /*filteredSquaresArr*/ 1 && ol_start_value !== (ol_start_value = /*square*/ ctx[12].realItems.length + 1)) { - attr(ol, "start", ol_start_value); - } - }, - d(detaching) { - if (if_block) if_block.d(detaching); - if (detaching) detach(t); - if (detaching) detach(ol); - destroy_each(each_blocks, detaching); - } - }; -} - -// (45:14) {#if settings.showRelationType} -function create_if_block_2$1(ctx) { - let h5; - - return { - c() { - h5 = element("h5"); - h5.textContent = "Implied"; - attr(h5, "class", "breadcrumbs-matrix-header svelte-fq6v4k"); - }, - m(target, anchor) { - insert(target, h5, anchor); - }, - d(detaching) { - if (detaching) detach(h5); - } - }; -} - -// (49:16) {#each square.impliedItems as impliedItem} -function create_each_block_2$2(ctx) { - let li; - let div; - - let t_value = (/*impliedItem*/ ctx[15].alt - ? /*impliedItem*/ ctx[15].alt - : /*impliedItem*/ ctx[15].to.split("/").last()) + ""; - - let t; - let div_class_value; - let mounted; - let dispose; - - function click_handler_1(...args) { - return /*click_handler_1*/ ctx[7](/*impliedItem*/ ctx[15], ...args); - } - - function mouseover_handler_1(...args) { - return /*mouseover_handler_1*/ ctx[8](/*impliedItem*/ ctx[15], ...args); - } - - return { - c() { - li = element("li"); - div = element("div"); - t = text(t_value); - attr(div, "class", div_class_value = "" + (null_to_empty(/*impliedItem*/ ctx[15].cls) + " svelte-fq6v4k")); - attr(li, "class", "breadcrumbs-implied"); - }, - m(target, anchor) { - insert(target, li, anchor); - append(li, div); - append(div, t); - - if (!mounted) { - dispose = [ - listen(div, "click", click_handler_1), - listen(div, "mouseover", mouseover_handler_1) - ]; - - mounted = true; - } - }, - p(new_ctx, dirty) { - ctx = new_ctx; - - if (dirty & /*filteredSquaresArr*/ 1 && t_value !== (t_value = (/*impliedItem*/ ctx[15].alt - ? /*impliedItem*/ ctx[15].alt - : /*impliedItem*/ ctx[15].to.split("/").last()) + "")) set_data(t, t_value); - - if (dirty & /*filteredSquaresArr*/ 1 && div_class_value !== (div_class_value = "" + (null_to_empty(/*impliedItem*/ ctx[15].cls) + " svelte-fq6v4k"))) { - attr(div, "class", div_class_value); - } - }, - d(detaching) { - if (detaching) detach(li); - mounted = false; - run_all(dispose); - } - }; -} - -// (16:6) {#each squares as square} -function create_each_block_1$4(ctx) { - let if_block_anchor; - let if_block = (/*square*/ ctx[12].realItems.length > 0 || /*square*/ ctx[12].impliedItems.length > 0) && create_if_block$2(ctx); - - return { - c() { - if (if_block) if_block.c(); - if_block_anchor = empty$1(); - }, - m(target, anchor) { - if (if_block) if_block.m(target, anchor); - insert(target, if_block_anchor, anchor); - }, - p(ctx, dirty) { - if (/*square*/ ctx[12].realItems.length > 0 || /*square*/ ctx[12].impliedItems.length > 0) { - if (if_block) { - if_block.p(ctx, dirty); - } else { - if_block = create_if_block$2(ctx); - if_block.c(); - if_block.m(if_block_anchor.parentNode, if_block_anchor); - } - } else if (if_block) { - if_block.d(1); - if_block = null; - } - }, - d(detaching) { - if (if_block) if_block.d(detaching); - if (detaching) detach(if_block_anchor); - } - }; -} - -// (14:2) {#each filteredSquaresArr as squares} -function create_each_block$4(ctx) { - let div; - let t; - let each_value_1 = /*squares*/ ctx[9]; - let each_blocks = []; - - for (let i = 0; i < each_value_1.length; i += 1) { - each_blocks[i] = create_each_block_1$4(get_each_context_1$4(ctx, each_value_1, i)); - } - - return { - c() { - div = element("div"); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].c(); - } - - t = space(); - attr(div, "class", "svelte-fq6v4k"); - }, - m(target, anchor) { - insert(target, div, anchor); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].m(div, null); - } - - append(div, t); - }, - p(ctx, dirty) { - if (dirty & /*filteredSquaresArr, openOrSwitch, app, currFile, hoverPreview, matrixView, settings*/ 31) { - each_value_1 = /*squares*/ ctx[9]; - let i; - - for (i = 0; i < each_value_1.length; i += 1) { - const child_ctx = get_each_context_1$4(ctx, each_value_1, i); - - if (each_blocks[i]) { - each_blocks[i].p(child_ctx, dirty); - } else { - each_blocks[i] = create_each_block_1$4(child_ctx); - each_blocks[i].c(); - each_blocks[i].m(div, t); - } - } - - for (; i < each_blocks.length; i += 1) { - each_blocks[i].d(1); - } - - each_blocks.length = each_value_1.length; - } - }, - d(detaching) { - if (detaching) detach(div); - destroy_each(each_blocks, detaching); - } - }; -} - -function create_fragment$4(ctx) { - let div; - let each_value = /*filteredSquaresArr*/ ctx[0]; - let each_blocks = []; - - for (let i = 0; i < each_value.length; i += 1) { - each_blocks[i] = create_each_block$4(get_each_context$4(ctx, each_value, i)); - } - - return { - c() { - div = element("div"); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].c(); - } - - attr(div, "class", "breadcrumbs-matrix markdown-preview-view svelte-fq6v4k"); - }, - m(target, anchor) { - insert(target, div, anchor); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].m(div, null); - } - }, - p(ctx, [dirty]) { - if (dirty & /*filteredSquaresArr, openOrSwitch, app, currFile, hoverPreview, matrixView, settings*/ 31) { - each_value = /*filteredSquaresArr*/ ctx[0]; - let i; - - for (i = 0; i < each_value.length; i += 1) { - const child_ctx = get_each_context$4(ctx, each_value, i); - - if (each_blocks[i]) { - each_blocks[i].p(child_ctx, dirty); - } else { - each_blocks[i] = create_each_block$4(child_ctx); - each_blocks[i].c(); - each_blocks[i].m(div, null); - } - } - - for (; i < each_blocks.length; i += 1) { - each_blocks[i].d(1); - } - - each_blocks.length = each_value.length; - } - }, - i: noop$2, - o: noop$2, - d(detaching) { - if (detaching) detach(div); - destroy_each(each_blocks, detaching); - } - }; -} - -function instance$4($$self, $$props, $$invalidate) { - - - - - let { filteredSquaresArr } = $$props; - let { currFile } = $$props; - let { settings } = $$props; - let { matrixView } = $$props; - let { app } = $$props; - const click_handler = async (realItem, e) => openOrSwitch(app, realItem.to, currFile, e); - const mouseover_handler = (realItem, event) => hoverPreview(event, matrixView, realItem.to); - const click_handler_1 = async (impliedItem, e) => openOrSwitch(app, impliedItem.to, currFile, e); - const mouseover_handler_1 = (impliedItem, event) => hoverPreview(event, matrixView, impliedItem.to); - - $$self.$$set = $$props => { - if ("filteredSquaresArr" in $$props) $$invalidate(0, filteredSquaresArr = $$props.filteredSquaresArr); - if ("currFile" in $$props) $$invalidate(1, currFile = $$props.currFile); - if ("settings" in $$props) $$invalidate(2, settings = $$props.settings); - if ("matrixView" in $$props) $$invalidate(3, matrixView = $$props.matrixView); - if ("app" in $$props) $$invalidate(4, app = $$props.app); - }; - - return [ - filteredSquaresArr, - currFile, - settings, - matrixView, - app, - click_handler, - mouseover_handler, - click_handler_1, - mouseover_handler_1 - ]; -} - -class Matrix extends SvelteComponent { - constructor(options) { - super(); - if (!document.getElementById("svelte-fq6v4k-style")) add_css$3(); - - init$1(this, options, instance$4, create_fragment$4, safe_not_equal, { - filteredSquaresArr: 0, - currFile: 1, - settings: 2, - matrixView: 3, - app: 4 - }); - } -} - -class MatrixView extends obsidian.ItemView { - constructor(leaf, plugin) { - super(leaf); - this.icon = TRAIL_ICON; - this.plugin = plugin; - } - async onload() { - super.onload(); - await this.plugin.saveSettings(); - this.matrixQ = this.plugin.settings.defaultView; - this.app.workspace.onLayoutReady(async () => { - setTimeout(async () => await this.draw(), this.app.plugins.plugins.dataview - ? this.app.plugins.plugins.dataview.api - ? 1 - : this.plugin.settings.dvWaitTime - : 3000); - }); - this.plugin.addCommand({ - id: "local-index", - name: "Copy a Local Index to the clipboard", - callback: async () => { - const settings = this.plugin.settings; - const currFile = this.app.workspace.getActiveFile().basename; - const closedParents = this.plugin.currGraphs.closedGs.down; - const allPaths = this.dfsAllPaths(closedParents, currFile); - const index = this.createIndex(currFile + "\n", allPaths, settings); - debug(settings, { index }); - await copy$1(index); - }, - }); - this.plugin.addCommand({ - id: "global-index", - name: "Copy a Global Index to the clipboard", - callback: async () => { - const { up } = this.plugin.currGraphs.mergedGs; - const closedParents = this.plugin.currGraphs.closedGs.down; - const sinks = getSinks(up); - const settings = this.plugin.settings; - let globalIndex = ""; - sinks.forEach((terminal) => { - globalIndex += terminal + "\n"; - const allPaths = this.dfsAllPaths(closedParents, terminal); - globalIndex = this.createIndex(globalIndex, allPaths, settings); - }); - debug(settings, { globalIndex }); - await copy$1(globalIndex); - }, - }); - } - getViewType() { - return MATRIX_VIEW; - } - getDisplayText() { - return "Breadcrumbs Matrix"; - } - async onOpen() { - await this.plugin.saveSettings(); - // this.app.workspace.onLayoutReady(async () => { - // setTimeout(async () => await this.draw(), DATAVIEW_INDEX_DELAY); - // }); - // this.app.workspace.on("dataview:api-ready", () => - // console.log("dv ready") - // ); - } - onClose() { - if (this.view) { - this.view.$destroy(); - } - return Promise.resolve(); - } - unresolvedQ(to, from) { - const { unresolvedLinks } = this.app.metadataCache; - if (!unresolvedLinks[from]) { - return false; - } - return unresolvedLinks[from][to] > 0; - } - squareItems(g, currFile, settings, realQ = true) { - let items; - const altFieldsQ = !!settings.altLinkFields.length; - if (realQ) { - items = g.outNeighbors(currFile.basename); - } - else { - items = g.inNeighbors(currFile.basename); - } - const internalLinkObjArr = []; - // TODO I don't think I need to check the length here - /// forEach won't run if it's empty anyway - if (items.length) { - items.forEach((to) => { - let alt = null; - if (altFieldsQ) { - const toFile = this.app.metadataCache.getFirstLinkpathDest(to, currFile.path); - if (toFile) { - const metadata = this.app.metadataCache.getFileCache(toFile); - settings.altLinkFields.forEach((altLinkField) => { - var _a; - const altLink = (_a = metadata === null || metadata === void 0 ? void 0 : metadata.frontmatter) === null || _a === void 0 ? void 0 : _a[altLinkField]; - if (altLink) { - alt = altLink; - return; - } - }); - } - } - internalLinkObjArr.push({ - to, - cls: "internal-link breadcrumbs-link" + - (this.unresolvedQ(to, currFile.path) ? " is-unresolved" : "") + - (realQ ? "" : " breadcrumbs-implied"), - alt, - }); - }); - } - return internalLinkObjArr; - } - // ANCHOR Remove duplicate implied links - removeDuplicateImplied(reals, implieds) { - const realTos = reals.map((real) => real.to); - return implieds.filter((implied) => !realTos.includes(implied.to)); - } - dfsAllPaths(g, startNode) { - const queue = [ - { node: startNode, path: [] }, - ]; - const pathsArr = []; - let i = 0; - while (queue.length > 0 && i < 1000) { - i++; - const currPath = queue.shift(); - const newNodes = g.outNeighbors(currPath.node); - const extPath = [currPath.node, ...currPath.path]; - queue.unshift(...newNodes.map((n) => { - return { node: n, path: extPath }; - })); - if (newNodes.length === 0) { - pathsArr.push(extPath); - } - } - return pathsArr; - } - createIndex( - // Gotta give it a starting index. This allows it to work for the global index feat - index, allPaths, settings) { - const copy = lodash$1.cloneDeep(allPaths); - const reversed = copy.map((path) => path.reverse()); - reversed.forEach((path) => path.shift()); - const indent = " "; - const visited = {}; - const activeFile = this.app.workspace.getActiveFile(); - reversed.forEach((path) => { - var _a, _b, _c, _d; - for (let depth = 0; depth < path.length; depth++) { - const currNode = path[depth]; - // If that node has been visited before at the current depth - if (visited.hasOwnProperty(currNode) && - visited[currNode].includes(depth)) { - continue; - } - else { - index += `${indent.repeat(depth)}- `; - index += settings.wikilinkIndex ? "[[" : ""; - index += currNode; - index += settings.wikilinkIndex ? "]]" : ""; - if (settings.aliasesInIndex) { - const currFile = this.app.metadataCache.getFirstLinkpathDest(currNode, activeFile.path); - if (currFile !== null) { - const cache = this.app.metadataCache.getFileCache(currFile); - const alias = (_b = (_a = cache === null || cache === void 0 ? void 0 : cache.frontmatter) === null || _a === void 0 ? void 0 : _a.alias) !== null && _b !== void 0 ? _b : []; - const aliases = (_d = (_c = cache === null || cache === void 0 ? void 0 : cache.frontmatter) === null || _c === void 0 ? void 0 : _c.aliases) !== null && _d !== void 0 ? _d : []; - const allAliases = [ - ...[alias].flat(3), - ...[aliases].flat(3), - ]; - if (allAliases.length) { - index += ` (${allAliases.join(", ")})`; - } - } - } - index += "\n"; - if (!visited.hasOwnProperty(currNode)) { - visited[currNode] = []; - } - visited[currNode].push(depth); - } - } - }); - return index; - } - getHierSquares(userHierarchies, data, currFile, settings) { - return userHierarchies.map((hier, i) => { - const [currUpG, currSameG, currDownG] = [ - data[i].up, - data[i].same, - data[i].down, - ]; - let [rUp, rSame, rDown, iUp, iDown] = [ - this.squareItems(currUpG, currFile, settings), - this.squareItems(currSameG, currFile, settings), - this.squareItems(currDownG, currFile, settings), - this.squareItems(currDownG, currFile, settings, false), - this.squareItems(currUpG, currFile, settings, false), - ]; - // SECTION Implied Siblings - /// Notes with the same parents - const currParents = currUpG.outNeighbors(currFile.basename); - let iSameArr = []; - currParents.forEach((parent) => { - let impliedSiblings = currUpG.inNeighbors(parent); - // The current note is always it's own implied sibling, so remove it from the list - const indexCurrNote = impliedSiblings.indexOf(currFile.basename); - impliedSiblings.splice(indexCurrNote, 1); - if (settings.filterImpliedSiblingsOfDifferentTypes) { - impliedSiblings = impliedSiblings.filter((iSibling) => { - const iSiblingType = currUpG.getNodeAttribute(iSibling, "fieldName"); - const currNodeType = currUpG.getNodeAttribute(currFile.basename, "fieldName"); - console.log({ iSiblingType, currNodeType }); - return iSiblingType === currNodeType; - }); - } - // Create the implied sibling SquareProps - impliedSiblings.forEach((impliedSibling) => { - const altFieldsQ = !!settings.altLinkFields.length; - let alt = null; - if (altFieldsQ) { - const toFile = this.app.metadataCache.getFirstLinkpathDest(impliedSibling, currFile.path); - if (toFile) { - const metadata = this.app.metadataCache.getFileCache(toFile); - settings.altLinkFields.forEach((altLinkField) => { - var _a; - const altLink = (_a = metadata === null || metadata === void 0 ? void 0 : metadata.frontmatter) === null || _a === void 0 ? void 0 : _a[altLinkField]; - if (altLink) { - alt = altLink; - return; - } - }); - } - } - iSameArr.push({ - to: impliedSibling, - cls: "internal-link breadcrumbs-link breadcrumbs-implied" + - (this.unresolvedQ(impliedSibling, currFile.path) - ? " is-unresolved" - : ""), - // TODO get alt for implied siblings - alt, - }); - }); - }); - /// A real sibling implies the reverse sibling - iSameArr.push(...this.squareItems(currSameG, currFile, settings, false)); - // !SECTION - iUp = this.removeDuplicateImplied(rUp, iUp); - iSameArr = this.removeDuplicateImplied(rSame, iSameArr); - iDown = this.removeDuplicateImplied(rDown, iDown); - const iSameNoDup = []; - iSameArr.forEach((impSib) => { - if (iSameNoDup.every((noDup) => noDup.to !== impSib.to)) { - iSameNoDup.push(impSib); - } - }); - iSameArr = iSameNoDup; - debug(settings, { - rUp, - iUp, - rSame, - iSameArr, - rDown, - iDown, - }); - const upSquare = { - realItems: rUp, - impliedItems: iUp, - fieldName: hier.up[0] === "" - ? `${hier.down.join(",")}` - : hier.up.join(", "), - }; - const sameSquare = { - realItems: rSame, - impliedItems: iSameArr, - fieldName: hier.same[0] === "" - ? `${hier.up.join(",")}` - : hier.same.join(", "), - }; - const downSquare = { - realItems: rDown, - impliedItems: iDown, - fieldName: hier.down[0] === "" - ? `${hier.up.join(",")}` - : hier.down.join(", "), - }; - return [upSquare, sameSquare, downSquare]; - }); - } - async draw() { - this.contentEl.empty(); - const { settings } = this.plugin; - debugGroupStart(settings, "debugMode", "Draw Matrix/List View"); - const hierGs = this.plugin.currGraphs; - const { userHierarchies } = settings; - const currFile = this.app.workspace.getActiveFile(); - const viewToggleButton = this.contentEl.createEl("button", { - text: this.matrixQ ? "List" : "Matrix", - }); - viewToggleButton.addEventListener("click", async () => { - this.matrixQ = !this.matrixQ; - viewToggleButton.innerText = this.matrixQ ? "List" : "Matrix"; - await this.draw(); - }); - const refreshIndexButton = this.contentEl.createEl("button", { - text: "🔁", - }); - refreshIndexButton.addEventListener("click", async () => { - await this.plugin.refreshIndex(); - }); - const data = hierGs.hierGs.map((hier) => { - const hierData = { - up: undefined, - same: undefined, - down: undefined, - }; - DIRECTIONS.forEach((dir) => { - // This is merging all graphs in Dir **In a particular hierarchy**, not accross all hierarchies like mergeGs(getAllGsInDir()) does - hierData[dir] = mergeGs(...Object.values(hier[dir])); - }); - return hierData; - }); - debug(settings, { data }); - const hierSquares = this.getHierSquares(userHierarchies, data, currFile, settings); - debug(settings, { hierSquares }); - const filteredSquaresArr = hierSquares.filter((squareArr) => squareArr.some((square) => square.realItems.length + square.impliedItems.length > 0)); - const compInput = { - target: this.contentEl, - props: { - filteredSquaresArr, - currFile, - settings, - matrixView: this, - app: this.app, - }, - }; - if (this.matrixQ) { - this.view = new Matrix(compInput); - } - else { - this.view = new Lists(compInput); - } - debugGroupEnd(settings, "debugMode"); - } -} - -class BreadcrumbsSettingTab extends obsidian.PluginSettingTab { - constructor(app, plugin) { - super(app, plugin); - this.plugin = plugin; - } - display() { - const plugin = this.plugin; - const { settings } = plugin; - const { containerEl } = this; - containerEl.empty(); - containerEl.createEl("h2", { text: "Settings for Breadcrumbs plugin" }); - function hierIndex(currHiers, values) { - return currHiers.findIndex((hier) => lodash$1.isEqual(hier.up, values[0]) && - lodash$1.isEqual(hier.same, values[1]) && - lodash$1.isEqual(hier.down, values[2])); - } - const addHierarchyRow = (values = { up: [""], same: [""], down: [""] }, existing = false) => { - const row = createSpan({ cls: "hierarchy-row" }); - const hierarchyNames = row.createSpan({}); - hierarchyNames.createEl("label", { attr: { for: "up" }, text: "↑" }); - const upInput = hierarchyNames.createEl("input", { - attr: { id: "up", placeholder: "↑" }, - value: values.up.join(", "), - }); - hierarchyNames.createEl("label", { attr: { for: "same" }, text: "→" }); - const sameInput = hierarchyNames.createEl("input", { - attr: { id: "same", placeholder: "→" }, - value: values.same.join(", "), - }); - hierarchyNames.createEl("label", { attr: { for: "down" }, text: "↓" }); - const downInput = hierarchyNames.createEl("input", { - attr: { id: "down", placeholder: "↓" }, - value: values.down.join(", "), - }); - let cleanInputs = [upInput.value, sameInput.value, downInput.value].map(splitAndTrim); - [upInput, sameInput, downInput].forEach((input) => input.addEventListener("change", () => { - saveButton.toggleClass("hierarchy-unsaved", true); - saveButton.textContent = "Save"; - })); - async function resetLimitTrailCheckboxes() { - settings.limitTrailCheckboxStates = {}; - settings.userHierarchies.forEach((userHier) => { - userHier.up.forEach(async (field) => { - if (field !== "") { - settings.limitTrailCheckboxStates[field] = true; - await plugin.saveSettings(); - } - }); - }); - await plugin.saveSettings(); - drawLimitTrailCheckboxes(checkboxDiv); - } - async function resetLimitWriteBCCheckboxes() { - settings.limitWriteBCCheckboxStates = {}; - settings.userHierarchies.forEach((userHier) => { - DIRECTIONS.forEach((dir) => { - userHier.up.forEach(async (field) => { - if (field !== "") { - settings.limitWriteBCCheckboxStates[field] = true; - await plugin.saveSettings(); - } - }); - }); - }); - await plugin.saveSettings(); - drawLimitWriteBCCheckboxes(checkboxDiv); - } - row.createEl("button", { text: "X" }, (el) => { - el.addEventListener("click", async () => { - row.remove(); - const removeIndex = hierIndex(settings.userHierarchies, [upInput.value, sameInput.value, downInput.value].map(splitAndTrim)); - if (removeIndex > -1) { - settings.userHierarchies.splice(removeIndex, 1); - await plugin.saveSettings(); - } - // Refresh limitTrailFields - await resetLimitTrailCheckboxes(); - await resetLimitWriteBCCheckboxes(); - new obsidian.Notice("Hierarchy Removed."); - }); - }); - const saveButton = row.createEl("button", { - text: existing ? "Saved" : "Save", - cls: (existing ? "" : "hierarchy-unsaved ") + "save-hierarchy-button", - }, function (el) { - el.addEventListener("click", async () => { - if (hierIndex(settings.userHierarchies, [upInput.value, sameInput.value, downInput.value].map(splitAndTrim)) > -1) { - new obsidian.Notice("A hierarchy with these Up, Same, and Down values already exists."); - return; - } - if (saveButton.hasClass("hierarchy-unsaved")) { - const removeIndex = hierIndex(settings.userHierarchies, cleanInputs); - if (removeIndex > -1) { - settings.userHierarchies.splice(removeIndex, 1); - await plugin.saveSettings(); - await resetLimitTrailCheckboxes(); - await resetLimitWriteBCCheckboxes(); - } - } - cleanInputs = [upInput.value, sameInput.value, downInput.value].map(splitAndTrim); - saveButton.toggleClass("hierarchy-unsaved", false); - saveButton.textContent = "Saved"; - if (hierIndex(settings.userHierarchies, cleanInputs) > -1) { - new obsidian.Notice("A hierarchy with these Up, Same, and Down values already exists."); - } - else { - settings.userHierarchies.push({ - up: splitAndTrim(upInput.value), - same: splitAndTrim(sameInput.value), - down: splitAndTrim(downInput.value), - }); - await plugin.saveSettings(); - new obsidian.Notice("Hierarchy saved."); - await resetLimitTrailCheckboxes(); - await resetLimitWriteBCCheckboxes(); - } - }); - }); - return row; - }; - const fieldDetails = containerEl.createEl("details", { - cls: "field-details", - }); - fieldDetails.createEl("summary", { text: "Hierarchies" }); - fieldDetails.createEl("p", { - text: "Here you can set up different hierarchies you use in your vault. To add a new hierarchy, click the plus button. Then, fill in the field names of your hierachy into the 3 boxes that appear. The ↑ field is for parent relations, the → field is for siblings, and ↓ is for child relations.", - }); - fieldDetails.createEl("p", { - text: "For each direction (up, same, down), you can enter multiple field names in a comma seperated list. For example: `parent, broader, upper`", - }); - new obsidian.Setting(fieldDetails) - .setName("Add Hierarchy") - .setDesc("Add a new hierarchy.") - .addButton((button) => { - button - .setTooltip("Add Additional") - .setButtonText("+") - .onClick(async () => { - fieldDetails.append(addHierarchyRow()); - }); - }); - fieldDetails.createEl("button", { text: "Reset Hierarchies" }, async (el) => { - el.addEventListener("click", async () => { - const rows = fieldDetails.querySelectorAll(".hierarchy-row"); - rows.forEach((row) => row.remove()); - settings.userHierarchies = []; - await plugin.saveSettings(); - new obsidian.Notice("Hierarchies reset."); - }); - }); - fieldDetails.createEl("button", { text: "Show Hierarchies" }, (el) => { - el.addEventListener("click", () => { - if (settings.userHierarchies.length) { - new obsidian.Notice(settings.userHierarchies.map(hierToStr).join("\n\n")); - } - else { - new obsidian.Notice("No hierarchies currently exist."); - } - console.log({ hierarchies: settings.userHierarchies }); - }); - }); - settings.userHierarchies.forEach((userHier) => { - fieldDetails.append(addHierarchyRow(userHier, true)); - }); - const hierarchyNoteDetails = containerEl.createEl("details"); - hierarchyNoteDetails.createEl("summary", { text: "Hierarchy Notes" }); - new obsidian.Setting(hierarchyNoteDetails) - .setName("Hierarchy Note(s)") - .setDesc("A list of notes used to create external Breadcrumb structures.") - .addText((text) => { - let finalValue; - text - .setPlaceholder("Hierarchy Note(s)") - .setValue([settings.hierarchyNotes].flat().join(", ")) - .onChange(async (value) => { - finalValue = splitAndTrim(value); - }); - text.inputEl.onblur = async () => { - if (finalValue[0] === "") { - settings.hierarchyNotes = finalValue; - await plugin.saveSettings(); - } - else if (finalValue.every((note) => isInVault(this.app, note))) { - settings.hierarchyNotes = finalValue; - await plugin.saveSettings(); - } - else { - new obsidian.Notice("Atleast one of the notes is not in your vault"); - } - }; - }); - new obsidian.Setting(hierarchyNoteDetails) - .setName("Hierarchy Note Up Field Name") - .setDesc("Using the breadcrumbs generated by the hierarchy note, which ↑ type should they count as? This has to be one of the ↑ types of one of your existing hierarchies. If you want it to be something else, you can make a new hierarchy just for it.") - .addText((text) => { - let finalValue = settings.hierarchyNoteUpFieldName; - text.setPlaceholder("").setValue(settings.hierarchyNoteUpFieldName); - text.inputEl.onblur = async () => { - finalValue = text.getValue(); - if (finalValue === "") { - settings.hierarchyNoteUpFieldName = finalValue; - await plugin.saveSettings(); - } - else { - const downFieldNames = settings.userHierarchies - .map((hier) => hier.up) - .flat(3); - debug(settings, { downFieldNames, finalValue }); - if (downFieldNames.includes(finalValue)) { - settings.hierarchyNoteUpFieldName = finalValue; - await plugin.saveSettings(); - } - else { - new obsidian.Notice("The field name must be one of the exisitng ↓ fields in your hierarchies."); - } - } - }; - }); - new obsidian.Setting(hierarchyNoteDetails) - .setName("Hierarchy Note Down Field Name") - .setDesc("Using the breadcrumbs generated by the hierarchy note, which ↓ type should they count as? This has to be one of the ↓ types of one of your existing hierarchies. If you want it to be something else, you can make a new hierarchy just for it.") - .addText((text) => { - let finalValue = settings.hierarchyNoteDownFieldName; - text.setPlaceholder("").setValue(settings.hierarchyNoteDownFieldName); - text.inputEl.onblur = async () => { - finalValue = text.getValue(); - if (finalValue === "") { - settings.hierarchyNoteDownFieldName = finalValue; - await plugin.saveSettings(); - } - else { - const downFieldNames = settings.userHierarchies - .map((hier) => hier.down) - .flat(3); - debug(settings, { downFieldNames, finalValue }); - if (downFieldNames.includes(finalValue)) { - settings.hierarchyNoteDownFieldName = finalValue; - await plugin.saveSettings(); - } - else { - new obsidian.Notice("The field name must be one of the exisitng ↓ fields in your hierarchies."); - } - } - }; - }); - const generalDetails = containerEl.createEl("details"); - generalDetails.createEl("summary", { text: "General Options" }); - new obsidian.Setting(generalDetails) - .setName("CSV Breadcrumb Paths") - .setDesc("The file path of a csv files with breadcrumbs information.") - .addText((text) => { - text.setValue(settings.CSVPaths); - text.inputEl.onblur = async () => { - settings.CSVPaths = text.inputEl.value; - await plugin.saveSettings(); - }; - }); - new obsidian.Setting(generalDetails) - .setName("Refresh Index on Note Change") - .setDesc("Refresh the Breadcrumbs index data everytime you change notes. This is how Breadcrumbs used to work, making it responsive to changes immediately after changing notes. However, this can be very slow on large vaults, so it is off by default.") - .addToggle((toggle) => toggle - .setValue(settings.refreshIndexOnActiveLeafChange) - .onChange(async (value) => { - settings.refreshIndexOnActiveLeafChange = value; - await plugin.saveSettings(); - })); - new obsidian.Setting(generalDetails) - .setName("Fields used for Alternative note names (Aliases)") - .setDesc("A comma-separated list of fields you use to specify note name aliases. These fields will be checked, in order, and be used to display an alternate note title in both the list/matrix view, and trail/grid view. This field will probably be `alias` or `aliases`, but it can be anything, like `title`, for example.") - .addText((text) => { - let finalValue; - text.setValue(settings.altLinkFields.join(", ")).onChange((str) => { - finalValue = str; - }); - text.inputEl.onblur = async () => { - settings.altLinkFields = splitAndTrim(finalValue); - await plugin.saveSettings(); - }; - }); - new obsidian.Setting(generalDetails) - .setName("Use yaml or inline fields for hierarchy data") - .setDesc("If enabled, Breadcrumbs will make it's hierarchy using yaml fields, and inline fields (if you have Dataview enabled). If this is disabled, it will only use Juggl links for it's metadata (See below).") - .addToggle((toggle) => toggle.setValue(settings.useAllMetadata).onChange(async (value) => { - settings.useAllMetadata = value; - await plugin.saveSettings(); - await plugin.refreshIndex(); - })); - new obsidian.Setting(generalDetails) - .setName("Use Juggl link syntax without having Juggl installed.") - .setDesc("Should Breadcrumbs look for [Juggl links](https://juggl.io/Link+Types) even if you don't have Juggl installed? If you do have Juggl installed, it will always look for Juggl links.") - .addToggle((toggle) => toggle - .setValue(settings.parseJugglLinksWithoutJuggl) - .onChange(async (value) => { - settings.parseJugglLinksWithoutJuggl = value; - await plugin.saveSettings(); - })); - if (this.app.plugins.plugins.dataview !== undefined) { - new obsidian.Setting(generalDetails) - .setName("Dataview Wait Time") - .setDesc('Enter an integer number of seconds to wait for the Dataview Index to load. The larger your vault, the longer it will take. If you see an error in the console saying "Cannot destructure currGraphs of undefined", try making this time longer. If you don\'t get that error, you can make this time shorter to make the Breadcrumbs load faster. The default is 5 seconds.') - .addText((text) => text - .setPlaceholder("Seconds") - .setValue((settings.dvWaitTime / 1000).toString()) - .onChange(async (value) => { - const num = Number(value); - if (num > 0) { - settings.dvWaitTime = num * 1000; - await plugin.saveSettings(); - } - else { - new obsidian.Notice("The interval must be a non-negative number"); - } - })); - } - new obsidian.Setting(generalDetails) - .setName("Refresh Interval") - .setDesc("Enter an integer number of seconds to wait before Breadcrumbs auto-refreshes its data. This would update the matrix view and the trail if either are affected. (Set to 0 to disable autorefreshing)") - .addText((text) => text - .setPlaceholder("Seconds") - .setValue(settings.refreshIntervalTime.toString()) - .onChange(async (value) => { - clearInterval(plugin.refreshIntervalID); - const num = Number(value); - if (num > 0) { - settings.refreshIntervalTime = num; - await plugin.saveSettings(); - plugin.refreshIntervalID = window.setInterval(async () => { - plugin.currGraphs = await plugin.initGraphs(); - if (settings.showTrail) { - await plugin.drawTrail(); - } - if (plugin.getActiveMatrixView()) { - await plugin.getActiveMatrixView().draw(); - } - }, num * 1000); - plugin.registerInterval(plugin.refreshIntervalID); - } - else if (num === 0) { - settings.refreshIntervalTime = num; - await plugin.saveSettings(); - clearInterval(plugin.refreshIntervalID); - } - else { - new obsidian.Notice("The interval must be a non-negative number"); - } - })); - const MLViewDetails = containerEl.createEl("details"); - MLViewDetails.createEl("summary", { text: "Matrix/List View" }); - new obsidian.Setting(MLViewDetails) - .setName("Show Matrix or List view by default") - .setDesc("When Obsidian first loads, which view should it show? On = Matrix, Off = List") - .addToggle((toggle) => toggle.setValue(settings.defaultView).onChange(async (value) => { - settings.defaultView = value; - await plugin.saveSettings(); - })); - // TODO I don't think this setting works anymore. I removed it's functionality when adding multiple hierarchies - new obsidian.Setting(MLViewDetails) - .setName("Show all field names or just relation types") - .setDesc("This changes the headers in matrix/list view. You can have the headers be the list of metadata fields for each relation type (e.g. `parent, broader, upper`). Or you can have them just be the name of the relation type, i.e. 'Parent', 'Sibling', 'Child'. On = show the full list of names.") - .addToggle((toggle) => toggle.setValue(settings.showNameOrType).onChange(async (value) => { - settings.showNameOrType = value; - await plugin.saveSettings(); - await plugin.getActiveMatrixView().draw(); - })); - new obsidian.Setting(MLViewDetails) - .setName("Show Relationship Type") - .setDesc("Show whether a link is real or implied. A real link is one you explicitly put in a note. E.g. parent:: [[Note]]. An implied link is the reverse of a real link. For example, if A is the real parent of B, then B must be the implied child of A.") - .addToggle((toggle) => toggle.setValue(settings.showRelationType).onChange(async (value) => { - settings.showRelationType = value; - await plugin.saveSettings(); - await plugin.getActiveMatrixView().draw(); - })); - new obsidian.Setting(MLViewDetails) - .setName("Filter Implied Siblings") - .setDesc("Implied siblings are: 1) notes with the same parent, or 2) notes that are real siblings. This setting only applies to type 1 implied siblings. If enabled, Breadcrumbs will filter type 1 implied siblings so that they not only share the same parent, but the parent relation has the exact same type. For example, the two real relations B --parent-> A, and A --parent-> A create an implied sibling between B and C (they have the same parent, A). The two real relations B --parent-> A, and A --up-> A create an implied sibling between B and C (they also have the same parent, A). But if this setting is turned on, the second implied sibling would not show, because the parent types are differnet (parent versus up).") - .addToggle((toggle) => toggle - .setValue(settings.filterImpliedSiblingsOfDifferentTypes) - .onChange(async (value) => { - settings.filterImpliedSiblingsOfDifferentTypes = value; - await plugin.saveSettings(); - await plugin.getActiveMatrixView().draw(); - })); - new obsidian.Setting(MLViewDetails) - .setName("Open View in Right or Left side") - .setDesc("When loading the matrix view, should it open on the left or right side leaf? On = Right, Off = Left.") - .addToggle((toggle) => toggle.setValue(settings.rlLeaf).onChange(async (value) => { - var _a; - settings.rlLeaf = value; - await plugin.saveSettings(); - await ((_a = plugin.getActiveMatrixView()) === null || _a === void 0 ? void 0 : _a.onClose()); - await openView(this.app, MATRIX_VIEW, MatrixView); - })); - const trailDetails = containerEl.createEl("details"); - trailDetails.createEl("summary", { text: "Trail/Grid" }); - new obsidian.Setting(trailDetails) - .setName("Show Breadcrumbs") - .setDesc("Show a trail of notes leading from your index note down to the current note you are in (if a path exists)") - .addToggle((toggle) => toggle.setValue(settings.showTrail).onChange(async (value) => { - settings.showTrail = value; - await plugin.saveSettings(); - await plugin.drawTrail(); - })); - const limitTrailFieldsDiv = trailDetails.createDiv({ - cls: "limit-ML-fields", - }); - limitTrailFieldsDiv.createEl("strong", { - text: "Limit M/L View to only show certain fields", - }); - const checkboxDiv = limitTrailFieldsDiv.createDiv({ cls: "checkboxes" }); - function drawLimitTrailCheckboxes(div) { - checkboxDiv.empty(); - const checkboxStates = settings.limitTrailCheckboxStates; - settings.userHierarchies.forEach((userHier) => { - userHier.up.forEach(async (field) => { - if (field === "") - return; - // First sort out limitTrailCheckboxStates - if (checkboxStates[field] === undefined) { - checkboxStates[field] = true; - await plugin.saveSettings(); - } - const cbDiv = div.createDiv(); - const checkedQ = checkboxStates[field]; - const cb = cbDiv.createEl("input", { - type: "checkbox", - attr: { id: field }, - }); - cb.checked = checkedQ; - cbDiv.createEl("label", { - text: field, - attr: { for: field }, - }); - cb.addEventListener("change", async (event) => { - checkboxStates[field] = cb.checked; - await plugin.saveSettings(); - console.log(settings.limitTrailCheckboxStates); - }); - }); - }); - } - drawLimitTrailCheckboxes(checkboxDiv); - new obsidian.Setting(trailDetails) - .setName("Field name to hide trail") - .setDesc("A note-specific toggle to hide the Trail View. By default, it is `hide-trail`. So, to hide the trail on a specific note, add the field to that note's yaml, like so: `hide-trail: {{anything}}`.") - .addText((text) => { - text.setValue(settings.hideTrailFieldName); - text.inputEl.onblur = async () => { - settings.hideTrailFieldName = text.getValue(); - await plugin.saveSettings(); - }; - }); - new obsidian.Setting(trailDetails) - .setName("Trail or Table or Both") - .setDesc("Wether to show the regular breadcrumb trails, the table view, neither, or both. 1 = Only Trail, 2 = Only Grid, 3 = Both") - .addText((text) => { - text - .setValue(settings.trailOrTable.toString()) - .onChange(async (value) => { - const num = parseInt(value); - if ([1, 2, 3].includes(num)) { - settings.trailOrTable = num; - await plugin.saveSettings(); - await plugin.drawTrail(); - } - else { - new obsidian.Notice("The value has to be 1, 2, or 3"); - } - }); - }); - new obsidian.Setting(trailDetails) - .setName("Grid view dots") - .setDesc("If the grid view is visible, shows dots based on the file size of each cell.") - .addToggle((toggle) => toggle.setValue(settings.gridDots).onChange(async (value) => { - settings.gridDots = value; - await plugin.saveSettings(); - await plugin.drawTrail(); - })); - const dotsColour = trailDetails.createDiv(); - dotsColour.createEl("h4", { - text: "Dots colour", - }); - const dotsColourPicker = dotsColour.createEl("input", { - type: "color", - }); - dotsColourPicker.value = settings.dotsColour; - dotsColourPicker.addEventListener("change", async () => { - settings.dotsColour = dotsColourPicker.value; - await plugin.saveSettings(); - }); - new obsidian.Setting(trailDetails) - .setName("Grid view heatmap") - .setDesc("If the grid view is visible, change the background colour of squares based on the number of children leaving that note.") - .addToggle((toggle) => toggle.setValue(settings.gridHeatmap).onChange(async (value) => { - settings.gridHeatmap = value; - await plugin.saveSettings(); - await plugin.drawTrail(); - })); - const heatmapColour = trailDetails.createDiv(); - heatmapColour.createEl("h4", { - text: "Heat map colour", - }); - const heatmapColourPicker = heatmapColour.createEl("input", { - type: "color", - }); - heatmapColourPicker.value = settings.heatmapColour; - heatmapColourPicker.addEventListener("change", async () => { - settings.heatmapColour = heatmapColourPicker.value; - await plugin.saveSettings(); - }); - new obsidian.Setting(trailDetails) - .setName("Index/Home Note(s)") - .setDesc("The note that all of your other notes lead back to. The parent of all your parent notes. Just enter the name. So if your index note is `000 Home.md`, enter `000 Home`. You can also have multiple index notes (comma-separated list). The breadcrumb trail will show the shortest path back to any one of the index notes listed. You can now leave this field empty, meaning the trail will show a path going as far up the parent-tree as possible.") - .addText((text) => { - let finalValue; - text - .setPlaceholder("Index Note") - .setValue([settings.indexNote].flat().join(", ")) - .onChange(async (value) => { - finalValue = splitAndTrim(value); - }); - text.inputEl.onblur = async () => { - // TODO Refactor this to general purpose isInVault function - if (finalValue[0] === "") { - settings.indexNote = finalValue; - await plugin.saveSettings(); - } - else if (finalValue.every((index) => isInVault(this.app, index))) { - settings.indexNote = finalValue; - await plugin.saveSettings(); - } - else { - new obsidian.Notice(`Atleast one of the notes is not in your vault`); - } - }; - }); - new obsidian.Setting(trailDetails) - .setName("Default: All or Shortest") - .setDesc("If multiple paths are found going up the parent tree, should all of them be shown by default, or only the shortest? On = all, off = shortest") - .addToggle((toggle) => toggle.setValue(settings.showAll).onChange(async (value) => { - settings.showAll = value; - await plugin.saveSettings(); - await plugin.drawTrail(); - })); - new obsidian.Setting(trailDetails) - .setName("Breadcrumb trail seperator") - .setDesc("The character to show between crumbs in the breadcrumb trail. The default is '→'") - .addText((text) => text - .setPlaceholder("→") - .setValue(settings.trailSeperator) - .onChange(async (value) => { - settings.trailSeperator = value; - await plugin.saveSettings(); - await plugin.drawTrail(); - })); - new obsidian.Setting(trailDetails) - .setName("No path found message") - .setDesc("The text to display when no path to the index note was found, or when the current note has no parent (this happens if you haven't chosen an index note)") - .addText((text) => text - .setPlaceholder(`No path to index note was found`) - .setValue(settings.noPathMessage) - .onChange(async (value) => { - settings.noPathMessage = value; - await plugin.saveSettings(); - await plugin.drawTrail(); - })); - new obsidian.Setting(trailDetails) - .setName("Respect Readable Line Length") - .setDesc("Should the breadcrumbs trail adjust its width to the readable line length, or use as much space as possible? On = use readable line length.") - .addToggle((toggle) => toggle - .setValue(settings.respectReadableLineLength) - .onChange(async (value) => { - settings.respectReadableLineLength = value; - await plugin.saveSettings(); - await plugin.drawTrail(); - })); - const writeBCsToFileDetails = containerEl.createEl("details"); - writeBCsToFileDetails.createEl("summary", { - text: "Write Breadcrumbs to File", - }); - const limitWriteBCDiv = writeBCsToFileDetails.createDiv({ - cls: "limit-ML-fields", - }); - limitWriteBCDiv.createEl("strong", { - text: "Limit to only write certain fields to files", - }); - const limitWriteBCCheckboxDiv = limitWriteBCDiv.createDiv({ - cls: "checkboxes", - }); - function drawLimitWriteBCCheckboxes(div) { - limitWriteBCCheckboxDiv.empty(); - const checkboxStates = settings.limitWriteBCCheckboxStates; - settings.userHierarchies.forEach((userHier) => { - DIRECTIONS.forEach((dir) => { - userHier[dir].forEach(async (field) => { - if (field === "") - return; - // First sort out limitWriteBCCheckboxStates - if (checkboxStates[field] === undefined) { - checkboxStates[field] = true; - await plugin.saveSettings(); - } - const cbDiv = div.createDiv(); - const checkedQ = checkboxStates[field]; - const cb = cbDiv.createEl("input", { - type: "checkbox", - attr: { id: field }, - }); - cb.checked = checkedQ; - cbDiv.createEl("label", { - text: field, - attr: { for: field }, - }); - cb.addEventListener("change", async (event) => { - checkboxStates[field] = cb.checked; - await plugin.saveSettings(); - console.log(settings.limitWriteBCCheckboxStates); - }); - }); - }); - }); - } - drawLimitWriteBCCheckboxes(limitWriteBCCheckboxDiv); - new obsidian.Setting(writeBCsToFileDetails) - .setName("Show the `Write Breadcrumbs to ALL Files` command") - .setDesc("This command attempts to update ALL files with implied breadcrumbs pointing to them. So, it is not shown by default (even though it has 3 confirmation boxes to ensure you want to run it") - .addToggle((toggle) => toggle.setValue(settings.showWriteAllBCsCmd).onChange(async (value) => { - settings.showWriteAllBCsCmd = value; - await plugin.saveSettings(); - })); - const visModalDetails = containerEl.createEl("details"); - visModalDetails.createEl("summary", { text: "Visualisation Modal" }); - new obsidian.Setting(visModalDetails) - .setName("Default Visualisation Type") - .setDesc("Which visualisation to show by defualt") - .addDropdown((cb) => { - VISTYPES.forEach((option) => { - cb.addOption(option, option); - }); - cb.setValue(settings.visGraph); - cb.onChange(async (value) => { - settings.visGraph = value; - await plugin.saveSettings(); - }); - }); - new obsidian.Setting(visModalDetails) - .setName("Default Relation") - .setDesc("Which relation type to show first when opening the modal") - .addDropdown((cb) => { - RELATIONS.forEach((option) => { - cb.addOption(option, option); - }); - cb.setValue(settings.visRelation); - cb.onChange(async (value) => { - settings.visRelation = value; - await plugin.saveSettings(); - }); - }); - new obsidian.Setting(visModalDetails) - .setName("Default Real/Closed") - .setDesc("Show the real or closed graph by default") - .addDropdown((cb) => { - REAlCLOSED.forEach((option) => { - cb.addOption(option, option); - }); - cb.setValue(settings.visClosed); - cb.onChange(async (value) => { - settings.visClosed = value; - await plugin.saveSettings(); - }); - }); - new obsidian.Setting(visModalDetails) - .setName("Default Unlinked") - .setDesc("Show all nodes or only those which have links by default") - .addDropdown((cb) => { - ALLUNLINKED.forEach((option) => { - cb.addOption(option, option); - }); - cb.setValue(settings.visAll); - cb.onChange(async (value) => { - settings.visAll = value; - await plugin.saveSettings(); - }); - }); - const createIndexDetails = containerEl.createEl("details"); - createIndexDetails.createEl("summary", { text: "Create Index" }); - new obsidian.Setting(createIndexDetails) - .setName("Add wiklink brackets") - .setDesc("When creating an index, should it wrap the note name in wikilinks `[[]]` or not. On = yes, off = no.") - .addToggle((toggle) => toggle.setValue(settings.wikilinkIndex).onChange(async (value) => { - settings.wikilinkIndex = value; - await plugin.saveSettings(); - })); - new obsidian.Setting(createIndexDetails) - .setName("Show aliases of notes in index") - .setDesc("Show the aliases of each note in brackets. On = yes, off = no.") - .addToggle((toggle) => toggle.setValue(settings.aliasesInIndex).onChange(async (value) => { - settings.aliasesInIndex = value; - await plugin.saveSettings(); - })); - const debugDetails = containerEl.createEl("details"); - debugDetails.createEl("summary", { text: "Debugging" }); - new obsidian.Setting(debugDetails) - .setName("Debug Mode") - .setDesc("Toggling this on will enable a few console logs to appear when use the matrix/list view, or the trail.") - .addToggle((toggle) => toggle.setValue(settings.debugMode).onChange(async (value) => { - settings.debugMode = value; - await plugin.saveSettings(); - })); - new obsidian.Setting(debugDetails) - .setName("Super Debug Mode") - .setDesc("Toggling this on will enable ALOT of console logs") - .addToggle((toggle) => toggle.setValue(settings.superDebugMode).onChange(async (value) => { - settings.superDebugMode = value; - await plugin.saveSettings(); - })); - debugDetails.createEl("button", { text: "Console log `settings`" }, (el) => { - el.addEventListener("click", () => console.log(settings)); - }); - new KoFi({ target: this.containerEl }); - } -} - -/* src\Components\Stats.svelte generated by Svelte v3.35.0 */ - -function add_css$2() { - var style = element("style"); - style.id = "svelte-rb5mhu-style"; - style.textContent = "table.svelte-rb5mhu{border-collapse:collapse}td.svelte-rb5mhu:first-child{text-align:right}td.svelte-rb5mhu,th.svelte-rb5mhu{padding:3px;border:1px solid var(--background-modifier-border);white-space:pre-line}"; - append(document.head, style); -} - -function get_each_context$3(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[23] = list[i]; - return child_ctx; -} - -function get_each_context_1$3(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[23] = list[i]; - return child_ctx; -} - -function get_each_context_2$1(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[23] = list[i]; - return child_ctx; -} - -function get_each_context_3(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[30] = list[i]; - child_ctx[32] = i; - return child_ctx; -} - -function get_each_context_4(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[23] = list[i]; - return child_ctx; -} - -function get_each_context_5(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[23] = list[i]; - return child_ctx; -} - -function get_each_context_6(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[23] = list[i]; - return child_ctx; -} - -// (96:6) {#each ["up", "same", "down"] as dir} -function create_each_block_6(ctx) { - let td; - let t_value = /*data*/ ctx[1][/*i*/ ctx[32]][/*dir*/ ctx[23]].Merged.nodes.length + ""; - let t; - let td_aria_label_value; - let mounted; - let dispose; - - function click_handler() { - return /*click_handler*/ ctx[4](/*i*/ ctx[32], /*dir*/ ctx[23]); - } - - return { - c() { - td = element("td"); - t = text(t_value); - attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1][/*i*/ ctx[32]][/*dir*/ ctx[23]].Merged.nodesStr); - attr(td, "class", "svelte-rb5mhu"); - }, - m(target, anchor) { - insert(target, td, anchor); - append(td, t); - - if (!mounted) { - dispose = listen(td, "click", click_handler); - mounted = true; - } - }, - p(new_ctx, dirty) { - ctx = new_ctx; - }, - d(detaching) { - if (detaching) detach(td); - mounted = false; - dispose(); - } - }; -} - -// (128:6) {#each ["up", "same", "down"] as dir} -function create_each_block_5(ctx) { - let td; - let t_value = /*data*/ ctx[1][/*i*/ ctx[32]][/*dir*/ ctx[23]].Merged.edges.length + ""; - let t; - let td_aria_label_value; - let mounted; - let dispose; - - function click_handler_2() { - return /*click_handler_2*/ ctx[6](/*i*/ ctx[32], /*dir*/ ctx[23]); - } - - return { - c() { - td = element("td"); - t = text(t_value); - attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1][/*i*/ ctx[32]][/*dir*/ ctx[23]].Merged.edgesStr); - attr(td, "class", "svelte-rb5mhu"); - }, - m(target, anchor) { - insert(target, td, anchor); - append(td, t); - - if (!mounted) { - dispose = listen(td, "click", click_handler_2); - mounted = true; - } - }, - p(new_ctx, dirty) { - ctx = new_ctx; - }, - d(detaching) { - if (detaching) detach(td); - mounted = false; - dispose(); - } - }; -} - -// (160:6) {#each ["up", "same", "down"] as dir} -function create_each_block_4(ctx) { - let td; - let t_value = /*data*/ ctx[1][/*i*/ ctx[32]][/*dir*/ ctx[23]].Implied.edges.length + ""; - let t; - let td_aria_label_value; - let mounted; - let dispose; - - function click_handler_4() { - return /*click_handler_4*/ ctx[8](/*i*/ ctx[32], /*dir*/ ctx[23]); - } - - return { - c() { - td = element("td"); - t = text(t_value); - attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1][/*i*/ ctx[32]][/*dir*/ ctx[23]].Implied.edgesStr); - attr(td, "class", "svelte-rb5mhu"); - }, - m(target, anchor) { - insert(target, td, anchor); - append(td, t); - - if (!mounted) { - dispose = listen(td, "click", click_handler_4); - mounted = true; - } - }, - p(new_ctx, dirty) { - ctx = new_ctx; - }, - d(detaching) { - if (detaching) detach(td); - mounted = false; - dispose(); - } - }; -} - -// (90:2) {#each userHierarchies as hier, i} -function create_each_block_3(ctx) { - let tr0; - let td0; - let t0_value = /*hierStrs*/ ctx[2][/*i*/ ctx[32]] + ""; - let t0; - let t1; - let td1; - let t3; - let t4; - let td2; - - let t5_value = [ - .../*data*/ ctx[1][/*i*/ ctx[32]].up.Merged.nodes, - .../*data*/ ctx[1][/*i*/ ctx[32]].same.Merged.nodes, - .../*data*/ ctx[1][/*i*/ ctx[32]].down.Merged.nodes - ].length + ""; - - let t5; - let td2_aria_label_value; - let t6; - let tr1; - let td3; - let t8; - let t9; - let td4; - - let t10_value = [ - .../*data*/ ctx[1][/*i*/ ctx[32]].up.Merged.edges, - .../*data*/ ctx[1][/*i*/ ctx[32]].same.Merged.edges, - .../*data*/ ctx[1][/*i*/ ctx[32]].down.Merged.edges - ].length + ""; - - let t10; - let td4_aria_label_value; - let t11; - let tr2; - let td5; - let t13; - let t14; - let td6; - - let t15_value = [ - .../*data*/ ctx[1][/*i*/ ctx[32]].up.Implied.edges, - .../*data*/ ctx[1][/*i*/ ctx[32]].same.Implied.edges, - .../*data*/ ctx[1][/*i*/ ctx[32]].down.Implied.edges - ].length + ""; - - let t15; - let td6_aria_label_value; - let mounted; - let dispose; - let each_value_6 = ["up", "same", "down"]; - let each_blocks_2 = []; - - for (let i = 0; i < 3; i += 1) { - each_blocks_2[i] = create_each_block_6(get_each_context_6(ctx, each_value_6, i)); - } - - function click_handler_1() { - return /*click_handler_1*/ ctx[5](/*i*/ ctx[32]); - } - - let each_value_5 = ["up", "same", "down"]; - let each_blocks_1 = []; - - for (let i = 0; i < 3; i += 1) { - each_blocks_1[i] = create_each_block_5(get_each_context_5(ctx, each_value_5, i)); - } - - function click_handler_3() { - return /*click_handler_3*/ ctx[7](/*i*/ ctx[32]); - } - - let each_value_4 = ["up", "same", "down"]; - let each_blocks = []; - - for (let i = 0; i < 3; i += 1) { - each_blocks[i] = create_each_block_4(get_each_context_4(ctx, each_value_4, i)); - } - - function click_handler_5() { - return /*click_handler_5*/ ctx[9](/*i*/ ctx[32]); - } - - return { - c() { - tr0 = element("tr"); - td0 = element("td"); - t0 = text(t0_value); - t1 = space(); - td1 = element("td"); - td1.textContent = "Nodes"; - t3 = space(); - - for (let i = 0; i < 3; i += 1) { - each_blocks_2[i].c(); - } - - t4 = space(); - td2 = element("td"); - t5 = text(t5_value); - t6 = space(); - tr1 = element("tr"); - td3 = element("td"); - td3.textContent = "Real Edges"; - t8 = space(); - - for (let i = 0; i < 3; i += 1) { - each_blocks_1[i].c(); - } - - t9 = space(); - td4 = element("td"); - t10 = text(t10_value); - t11 = space(); - tr2 = element("tr"); - td5 = element("td"); - td5.textContent = "Implied Edges"; - t13 = space(); - - for (let i = 0; i < 3; i += 1) { - each_blocks[i].c(); - } - - t14 = space(); - td6 = element("td"); - t15 = text(t15_value); - attr(td0, "rowspan", "3"); - attr(td0, "class", "svelte-rb5mhu"); - attr(td1, "class", "svelte-rb5mhu"); - - attr(td2, "aria-label", td2_aria_label_value = [ - /*data*/ ctx[1][/*i*/ ctx[32]].up.Merged.nodesStr, - /*data*/ ctx[1][/*i*/ ctx[32]].same.Merged.nodesStr, - /*data*/ ctx[1][/*i*/ ctx[32]].down.Merged.nodesStr - ].join("\n")); - - attr(td2, "class", "svelte-rb5mhu"); - attr(td3, "class", "svelte-rb5mhu"); - - attr(td4, "aria-label", td4_aria_label_value = [ - /*data*/ ctx[1][/*i*/ ctx[32]].up.Merged.edgesStr, - /*data*/ ctx[1][/*i*/ ctx[32]].same.Merged.edgesStr, - /*data*/ ctx[1][/*i*/ ctx[32]].down.Merged.edgesStr - ].join("\n")); - - attr(td4, "class", "svelte-rb5mhu"); - attr(td5, "class", "svelte-rb5mhu"); - - attr(td6, "aria-label", td6_aria_label_value = [ - /*data*/ ctx[1][/*i*/ ctx[32]].up.Implied.edgesStr, - /*data*/ ctx[1][/*i*/ ctx[32]].same.Implied.edgesStr, - /*data*/ ctx[1][/*i*/ ctx[32]].down.Implied.edgesStr - ].join("\n")); - - attr(td6, "class", "svelte-rb5mhu"); - }, - m(target, anchor) { - insert(target, tr0, anchor); - append(tr0, td0); - append(td0, t0); - append(tr0, t1); - append(tr0, td1); - append(tr0, t3); - - for (let i = 0; i < 3; i += 1) { - each_blocks_2[i].m(tr0, null); - } - - append(tr0, t4); - append(tr0, td2); - append(td2, t5); - insert(target, t6, anchor); - insert(target, tr1, anchor); - append(tr1, td3); - append(tr1, t8); - - for (let i = 0; i < 3; i += 1) { - each_blocks_1[i].m(tr1, null); - } - - append(tr1, t9); - append(tr1, td4); - append(td4, t10); - insert(target, t11, anchor); - insert(target, tr2, anchor); - append(tr2, td5); - append(tr2, t13); - - for (let i = 0; i < 3; i += 1) { - each_blocks[i].m(tr2, null); - } - - append(tr2, t14); - append(tr2, td6); - append(td6, t15); - - if (!mounted) { - dispose = [ - listen(td2, "click", click_handler_1), - listen(td4, "click", click_handler_3), - listen(td6, "click", click_handler_5) - ]; - - mounted = true; - } - }, - p(new_ctx, dirty) { - ctx = new_ctx; - - if (dirty[0] & /*data*/ 2) { - each_value_6 = ["up", "same", "down"]; - let i; - - for (i = 0; i < 3; i += 1) { - const child_ctx = get_each_context_6(ctx, each_value_6, i); - - if (each_blocks_2[i]) { - each_blocks_2[i].p(child_ctx, dirty); - } else { - each_blocks_2[i] = create_each_block_6(child_ctx); - each_blocks_2[i].c(); - each_blocks_2[i].m(tr0, t4); - } - } - - for (; i < 3; i += 1) { - each_blocks_2[i].d(1); - } - } - - if (dirty[0] & /*data*/ 2) { - each_value_5 = ["up", "same", "down"]; - let i; - - for (i = 0; i < 3; i += 1) { - const child_ctx = get_each_context_5(ctx, each_value_5, i); - - if (each_blocks_1[i]) { - each_blocks_1[i].p(child_ctx, dirty); - } else { - each_blocks_1[i] = create_each_block_5(child_ctx); - each_blocks_1[i].c(); - each_blocks_1[i].m(tr1, t9); - } - } - - for (; i < 3; i += 1) { - each_blocks_1[i].d(1); - } - } - - if (dirty[0] & /*data*/ 2) { - each_value_4 = ["up", "same", "down"]; - let i; - - for (i = 0; i < 3; i += 1) { - const child_ctx = get_each_context_4(ctx, each_value_4, i); - - if (each_blocks[i]) { - each_blocks[i].p(child_ctx, dirty); - } else { - each_blocks[i] = create_each_block_4(child_ctx); - each_blocks[i].c(); - each_blocks[i].m(tr2, t14); - } - } - - for (; i < 3; i += 1) { - each_blocks[i].d(1); - } - } - }, - d(detaching) { - if (detaching) detach(tr0); - destroy_each(each_blocks_2, detaching); - if (detaching) detach(t6); - if (detaching) detach(tr1); - destroy_each(each_blocks_1, detaching); - if (detaching) detach(t11); - if (detaching) detach(tr2); - destroy_each(each_blocks, detaching); - mounted = false; - run_all(dispose); - } - }; -} - -// (194:4) {#each ["up", "same", "down"] as dir} -function create_each_block_2$1(ctx) { - let td; - let t0_value = lodash$1.sum(/*data*/ ctx[1].map(func)) + ""; - let t0; - let t1; - let td_aria_label_value; - let mounted; - let dispose; - - function func(...args) { - return /*func*/ ctx[10](/*dir*/ ctx[23], ...args); - } - - function func_1(...args) { - return /*func_1*/ ctx[11](/*dir*/ ctx[23], ...args); - } - - function click_handler_6() { - return /*click_handler_6*/ ctx[12](/*dir*/ ctx[23]); - } - - return { - c() { - td = element("td"); - t0 = text(t0_value); - t1 = space(); - attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1].map(func_1).join("\n")); - attr(td, "class", "svelte-rb5mhu"); - }, - m(target, anchor) { - insert(target, td, anchor); - append(td, t0); - append(td, t1); - - if (!mounted) { - dispose = listen(td, "click", click_handler_6); - mounted = true; - } - }, - p(new_ctx, dirty) { - ctx = new_ctx; - }, - d(detaching) { - if (detaching) detach(td); - mounted = false; - dispose(); - } - }; -} - -// (233:4) {#each ["up", "same", "down"] as dir} -function create_each_block_1$3(ctx) { - let td; - let t0_value = lodash$1.sum(/*data*/ ctx[1].map(func_2)) + ""; - let t0; - let t1; - let td_aria_label_value; - let mounted; - let dispose; - - function func_2(...args) { - return /*func_2*/ ctx[13](/*dir*/ ctx[23], ...args); - } - - function func_3(...args) { - return /*func_3*/ ctx[14](/*dir*/ ctx[23], ...args); - } - - function click_handler_7() { - return /*click_handler_7*/ ctx[15](/*dir*/ ctx[23]); - } - - return { - c() { - td = element("td"); - t0 = text(t0_value); - t1 = space(); - attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1].map(func_3).join("\n")); - attr(td, "class", "svelte-rb5mhu"); - }, - m(target, anchor) { - insert(target, td, anchor); - append(td, t0); - append(td, t1); - - if (!mounted) { - dispose = listen(td, "click", click_handler_7); - mounted = true; - } - }, - p(new_ctx, dirty) { - ctx = new_ctx; - }, - d(detaching) { - if (detaching) detach(td); - mounted = false; - dispose(); - } - }; -} - -// (268:4) {#each ["up", "same", "down"] as dir} -function create_each_block$3(ctx) { - let td; - let t0_value = lodash$1.sum(/*data*/ ctx[1].map(func_4)) + ""; - let t0; - let t1; - let td_aria_label_value; - let mounted; - let dispose; - - function func_4(...args) { - return /*func_4*/ ctx[16](/*dir*/ ctx[23], ...args); - } - - function func_5(...args) { - return /*func_5*/ ctx[17](/*dir*/ ctx[23], ...args); - } - - function click_handler_8() { - return /*click_handler_8*/ ctx[18](/*dir*/ ctx[23]); - } - - return { - c() { - td = element("td"); - t0 = text(t0_value); - t1 = space(); - attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1].map(func_5).join("\n")); - attr(td, "class", "svelte-rb5mhu"); - }, - m(target, anchor) { - insert(target, td, anchor); - append(td, t0); - append(td, t1); - - if (!mounted) { - dispose = listen(td, "click", click_handler_8); - mounted = true; - } - }, - p(new_ctx, dirty) { - ctx = new_ctx; - }, - d(detaching) { - if (detaching) detach(td); - mounted = false; - dispose(); - } - }; -} - -function create_fragment$3(ctx) { - let table; - let thead; - let t3; - let tr1; - let t14; - let t15; - let tr2; - let td6; - let t17; - let td7; - let t19; - let t20; - let tr3; - let td8; - let t22; - let t23; - let tr4; - let td9; - let t25; - let each_value_3 = /*userHierarchies*/ ctx[0]; - let each_blocks_3 = []; - - for (let i = 0; i < each_value_3.length; i += 1) { - each_blocks_3[i] = create_each_block_3(get_each_context_3(ctx, each_value_3, i)); - } - - let each_value_2 = ["up", "same", "down"]; - let each_blocks_2 = []; - - for (let i = 0; i < 3; i += 1) { - each_blocks_2[i] = create_each_block_2$1(get_each_context_2$1(ctx, each_value_2, i)); - } - - let each_value_1 = ["up", "same", "down"]; - let each_blocks_1 = []; - - for (let i = 0; i < 3; i += 1) { - each_blocks_1[i] = create_each_block_1$3(get_each_context_1$3(ctx, each_value_1, i)); - } - - let each_value = ["up", "same", "down"]; - let each_blocks = []; - - for (let i = 0; i < 3; i += 1) { - each_blocks[i] = create_each_block$3(get_each_context$3(ctx, each_value, i)); - } - - return { - c() { - table = element("table"); - thead = element("thead"); - - thead.innerHTML = `Hierarchy - Count`; - - t3 = space(); - tr1 = element("tr"); - - tr1.innerHTML = ` - Measure - ↑ - → - ↓ - Total`; - - t14 = space(); - - for (let i = 0; i < each_blocks_3.length; i += 1) { - each_blocks_3[i].c(); - } - - t15 = space(); - tr2 = element("tr"); - td6 = element("td"); - td6.textContent = "Totals"; - t17 = space(); - td7 = element("td"); - td7.textContent = "Nodes"; - t19 = space(); - - for (let i = 0; i < 3; i += 1) { - each_blocks_2[i].c(); - } - - t20 = space(); - tr3 = element("tr"); - td8 = element("td"); - td8.textContent = "Real Edges"; - t22 = space(); - - for (let i = 0; i < 3; i += 1) { - each_blocks_1[i].c(); - } - - t23 = space(); - tr4 = element("tr"); - td9 = element("td"); - td9.textContent = "Implied Edges"; - t25 = space(); - - for (let i = 0; i < 3; i += 1) { - each_blocks[i].c(); - } - - attr(td6, "rowspan", "3"); - attr(td6, "class", "svelte-rb5mhu"); - attr(td7, "class", "svelte-rb5mhu"); - attr(td8, "class", "svelte-rb5mhu"); - attr(td9, "class", "svelte-rb5mhu"); - attr(table, "class", "svelte-rb5mhu"); - }, - m(target, anchor) { - insert(target, table, anchor); - append(table, thead); - append(table, t3); - append(table, tr1); - append(table, t14); - - for (let i = 0; i < each_blocks_3.length; i += 1) { - each_blocks_3[i].m(table, null); - } - - append(table, t15); - append(table, tr2); - append(tr2, td6); - append(tr2, t17); - append(tr2, td7); - append(tr2, t19); - - for (let i = 0; i < 3; i += 1) { - each_blocks_2[i].m(tr2, null); - } - - append(table, t20); - append(table, tr3); - append(tr3, td8); - append(tr3, t22); - - for (let i = 0; i < 3; i += 1) { - each_blocks_1[i].m(tr3, null); - } - - append(table, t23); - append(table, tr4); - append(tr4, td9); - append(tr4, t25); - - for (let i = 0; i < 3; i += 1) { - each_blocks[i].m(tr4, null); - } - }, - p(ctx, dirty) { - if (dirty[0] & /*data, hierStrs*/ 6) { - each_value_3 = /*userHierarchies*/ ctx[0]; - let i; - - for (i = 0; i < each_value_3.length; i += 1) { - const child_ctx = get_each_context_3(ctx, each_value_3, i); - - if (each_blocks_3[i]) { - each_blocks_3[i].p(child_ctx, dirty); - } else { - each_blocks_3[i] = create_each_block_3(child_ctx); - each_blocks_3[i].c(); - each_blocks_3[i].m(table, t15); - } - } - - for (; i < each_blocks_3.length; i += 1) { - each_blocks_3[i].d(1); - } - - each_blocks_3.length = each_value_3.length; - } - - if (dirty[0] & /*data*/ 2) { - each_value_2 = ["up", "same", "down"]; - let i; - - for (i = 0; i < 3; i += 1) { - const child_ctx = get_each_context_2$1(ctx, each_value_2, i); - - if (each_blocks_2[i]) { - each_blocks_2[i].p(child_ctx, dirty); - } else { - each_blocks_2[i] = create_each_block_2$1(child_ctx); - each_blocks_2[i].c(); - each_blocks_2[i].m(tr2, null); - } - } - - for (; i < 3; i += 1) { - each_blocks_2[i].d(1); - } - } - - if (dirty[0] & /*data*/ 2) { - each_value_1 = ["up", "same", "down"]; - let i; - - for (i = 0; i < 3; i += 1) { - const child_ctx = get_each_context_1$3(ctx, each_value_1, i); - - if (each_blocks_1[i]) { - each_blocks_1[i].p(child_ctx, dirty); - } else { - each_blocks_1[i] = create_each_block_1$3(child_ctx); - each_blocks_1[i].c(); - each_blocks_1[i].m(tr3, null); - } - } - - for (; i < 3; i += 1) { - each_blocks_1[i].d(1); - } - } - - if (dirty[0] & /*data*/ 2) { - each_value = ["up", "same", "down"]; - let i; - - for (i = 0; i < 3; i += 1) { - const child_ctx = get_each_context$3(ctx, each_value, i); - - if (each_blocks[i]) { - each_blocks[i].p(child_ctx, dirty); - } else { - each_blocks[i] = create_each_block$3(child_ctx); - each_blocks[i].c(); - each_blocks[i].m(tr4, null); - } - } - - for (; i < 3; i += 1) { - each_blocks[i].d(1); - } - } - }, - i: noop$2, - o: noop$2, - d(detaching) { - if (detaching) detach(table); - destroy_each(each_blocks_3, detaching); - destroy_each(each_blocks_2, detaching); - destroy_each(each_blocks_1, detaching); - destroy_each(each_blocks, detaching); - } - }; -} - -function instance$3($$self, $$props, $$invalidate) { - - - let { plugin } = $$props; - const { settings } = plugin; - const { userHierarchies } = settings; - const separator = settings.trailSeperator; - const hierGs = plugin.currGraphs; - - function fillInInfo(dir, gType, hierData, nodesToo = true) { - const gInfo = hierData[dir][gType]; - - if (nodesToo) { - const nodes = gInfo.graph.nodes(); - gInfo.nodes = nodes; - gInfo.nodesStr = nodes.join("\n"); - } - - gInfo.edges = gInfo.graph.edges(); - const edgeStrArr = gInfo.graph.mapEdges((k, a, s, t) => `${nodesToo ? s : t} ${nodesToo || dir !== "same" ? separator : "⟷"} ${nodesToo ? t : s}`); - gInfo.edgesStr = edgeStrArr.join("\n"); - } - - const data = hierGs.hierGs.map(hier => { - const hierData = { - //@ts-ignore - up: { Merged: {}, Closed: {}, Implied: {} }, - //@ts-ignore - same: { Merged: {}, Closed: {}, Implied: {} }, - //@ts-ignore - down: { Merged: {}, Closed: {}, Implied: {} } - }; - - DIRECTIONS.forEach(dir => { - // Merged Graphs - /// Smoosh all fieldGs from one dir into a merged graph for that direction as a whole - const mergedInDir = mergeGs(...Object.values(hier[dir])); - - hierData[dir].Merged.graph = mergedInDir; - fillInInfo(dir, "Merged", hierData); - - // Closed graphs - if (dir !== "same") { - hierData[dir].Closed.graph = closeImpliedLinks(mergedInDir, mergeGs(...Object.values(hier[dir === "up" ? "down" : "up"]))); - } else { - hierData[dir].Closed.graph = closeImpliedLinks(mergedInDir, mergedInDir); - } - - fillInInfo(dir, "Closed", hierData); - - if (dir !== "same") { - hierData[dir].Implied.graph = mergeGs(...Object.values(hier[dir === "up" ? "down" : "up"])); - } else { - hierData[dir].Implied.graph = closeImpliedLinks(mergedInDir, mergedInDir); - } - - fillInInfo(dir, "Implied", hierData, false); - }); - - return hierData; - }); - - debug(settings, { data }); - let hierStrs = userHierarchies.map(hierToStr); - const click_handler = async (i, dir) => await copy$1(data[i][dir].Merged.nodesStr); - - const click_handler_1 = async i => await copy$1([ - data[i].up.Merged.nodesStr, - data[i].same.Merged.nodesStr, - data[i].down.Merged.nodesStr - ].join("\n")); - - const click_handler_2 = async (i, dir) => await copy$1(data[i][dir].Merged.edgesStr); - - const click_handler_3 = async i => await copy$1([ - data[i].up.Merged.edgesStr, - data[i].same.Merged.edgesStr, - data[i].down.Merged.edgesStr - ].join("\n")); - - const click_handler_4 = async (i, dir) => await copy$1(data[i][dir].Implied.edgesStr); - - const click_handler_5 = async i => await copy$1([ - data[i].up.Implied.edgesStr, - data[i].same.Implied.edgesStr, - data[i].down.Implied.edgesStr - ].join("\n")); - - const func = (dir, datum) => datum[dir].Merged.nodes.length; - const func_1 = (dir, datum) => datum[dir].Merged.nodesStr; - const click_handler_6 = async dir => await copy$1(data.map(datum => datum[dir].Merged.nodesStr).join("\n")); - const func_2 = (dir, datum) => datum[dir].Merged.edges.length; - const func_3 = (dir, datum) => datum[dir].Merged.edgesStr; - const click_handler_7 = async dir => await copy$1(data.map(datum => datum[dir].Merged.edgesStr).join("\n")); - const func_4 = (dir, datum) => datum[dir].Implied.edges.length; - const func_5 = (dir, datum) => datum[dir].Implied.edgesStr; - const click_handler_8 = async dir => await copy$1(data.map(datum => datum[dir].Implied.edgesStr).join("\n")); - - $$self.$$set = $$props => { - if ("plugin" in $$props) $$invalidate(3, plugin = $$props.plugin); - }; - - return [ - userHierarchies, - data, - hierStrs, - plugin, - click_handler, - click_handler_1, - click_handler_2, - click_handler_3, - click_handler_4, - click_handler_5, - func, - func_1, - click_handler_6, - func_2, - func_3, - click_handler_7, - func_4, - func_5, - click_handler_8 - ]; -} - -class Stats extends SvelteComponent { - constructor(options) { - super(); - if (!document.getElementById("svelte-rb5mhu-style")) add_css$2(); - init$1(this, options, instance$3, create_fragment$3, safe_not_equal, { plugin: 3 }, [-1, -1]); - } -} - -class StatsView extends obsidian.ItemView { - constructor(leaf, plugin) { - super(leaf); - this.icon = "info"; - this.plugin = plugin; +function normalise(arr) { + const max = Math.max(...arr); + return arr.map((item) => item / max); +} +function debug(settings, log) { + if (settings.debugMode) { + console.log(log); + } +} +function superDebug(settings, log) { + if (settings.superDebugMode) { + console.log(log); + } +} +function debugGroupStart(settings, type, group) { + if (settings[type]) { + console.groupCollapsed(group); + } +} +function debugGroupEnd(settings, type) { + if (settings[type]) { + console.groupEnd(); + } +} +function getDVMetadataCache(app, settings, files) { + debugGroupStart(settings, "debugMode", "getDVMetadataCache"); + debug(settings, "Using Dataview"); + debugGroupStart(settings, "superDebugMode", "dvCaches"); + const fileFrontmatterArr = []; + files.forEach((file) => { + superDebug(settings, `GetDVMetadataCache: ${file.basename}`); + const dvCache = app.plugins.plugins.dataview.api.page(file.path); + superDebug(settings, { dvCache }); + fileFrontmatterArr.push(dvCache); + }); + debugGroupEnd(settings, "superDebugMode"); + debug(settings, { fileFrontmatterArr }); + debugGroupEnd(settings, "debugMode"); + return fileFrontmatterArr; +} +function getObsMetadataCache(app, settings, files) { + debugGroupStart(settings, "debugMode", "getObsMetadataCache"); + debug(settings, "Using Obsidian"); + debugGroupStart(settings, "superDebugMode", "obsCaches"); + const fileFrontmatterArr = []; + files.forEach((file) => { + var _a; + superDebug(settings, `GetObsMetadataCache: ${file.basename}`); + const obs = (_a = app.metadataCache.getFileCache(file)) === null || _a === void 0 ? void 0 : _a.frontmatter; + superDebug(settings, { obs }); + if (obs) { + fileFrontmatterArr.push(Object.assign({ file }, obs)); + } + else { + fileFrontmatterArr.push({ file }); + } + }); + debugGroupEnd(settings, "superDebugMode"); + debug(settings, { fileFrontmatterArr }); + debugGroupEnd(settings, "debugMode"); + return fileFrontmatterArr; +} +// TODO I think it'd be better to do this whole thing as an obj instead of JugglLink[] +// => {[note: string]: {type: string, linksInLine: string[]}[]} +async function getJugglLinks(app, settings) { + debugGroupStart(settings, "debugMode", "getJugglLinks"); + debug(settings, "Using Juggl"); + const files = app.vault.getMarkdownFiles(); + const { userHierarchies } = settings; + // Add Juggl links + const typedLinksArr = await Promise.all(files.map(async (file) => { + var _a, _b; + const jugglLink = { note: file.basename, links: [] }; + // Use Obs metadatacache to get the links in the current file + const links = (_b = (_a = app.metadataCache.getFileCache(file)) === null || _a === void 0 ? void 0 : _a.links) !== null && _b !== void 0 ? _b : []; + // TODO Only get cachedRead if links.length + const content = await app.vault.cachedRead(file); + links.forEach((link) => { + var _a, _b, _c, _d, _e, _f, _g; + // Get the line no. of each link + const lineNo = link.position.start.line; + // And the corresponding line content + const line = content.split("\n")[lineNo]; + // Get an array of inner text of each link + const linksInLine = (_c = (_b = (_a = line + .match(splitLinksRegex)) === null || _a === void 0 ? void 0 : _a.map((link) => link.slice(2, link.length - 2))) === null || _b === void 0 ? void 0 : _b.map((innerText) => innerText.split("|")[0])) !== null && _c !== void 0 ? _c : []; + const typedLinkPrefix = (_e = (_d = app.plugins.plugins.juggl) === null || _d === void 0 ? void 0 : _d.settings.typedLinkPrefix) !== null && _e !== void 0 ? _e : "-"; + const parsedLinks = parseTypedLink(link, line, typedLinkPrefix); + const type = (_g = (_f = parsedLinks === null || parsedLinks === void 0 ? void 0 : parsedLinks.properties) === null || _f === void 0 ? void 0 : _f.type) !== null && _g !== void 0 ? _g : ""; + let typeDir = ""; + DIRECTIONS.forEach((dir) => { + userHierarchies.forEach((hier) => { + if (hier[dir].includes(type)) { + typeDir = dir; + return; + } + }); + }); + jugglLink.links.push({ + dir: typeDir, + type, + linksInLine, + }); + }); + return jugglLink; + })); + debug(settings, { typedLinksArr }); + const allFields = settings.userHierarchies + .map((hier) => Object.values(hier)) + .flat(2) + .filter((field) => field !== ""); + typedLinksArr.forEach((jugglLink) => { + // Filter out links whose type is not in allFields + const fieldTypesOnly = jugglLink.links.filter((link) => allFields.includes(link.type)); + // // const fieldTypesOnly = []; + // jugglLink.links.forEach((link) => { + // if (allFields.includes(link.type)) { + // fieldTypesOnly.push(link); + // } + // }); + // I don't remember why I'm mutating the links instead of making a new obj + jugglLink.links = fieldTypesOnly; + }); + // Filter out the juggl links with no links + const filteredLinks = typedLinksArr.filter((jugglLink) => jugglLink.links.length); + debug(settings, { filteredLinks }); + debugGroupEnd(settings, "debugMode"); + return filteredLinks; +} +function getFieldValues(frontmatterCache, field, settings) { + var _a; + const values = []; + try { + const rawValuesPreFlat = frontmatterCache === null || frontmatterCache === void 0 ? void 0 : frontmatterCache[field]; + if (!rawValuesPreFlat) + return []; + if (typeof rawValuesPreFlat === "string") { + const splits = rawValuesPreFlat.match(splitLinksRegex); + if (splits !== null) { + const strs = splits.map((link) => link.match(dropHeaderOrAlias)[1].split("/").last()); + values.push(...strs); + } + // else { + // Dont't add anything, it's not a link + // } + } + else { + const rawValues = [rawValuesPreFlat].flat(4); + superDebug(settings, `${field} of: ${(_a = frontmatterCache === null || frontmatterCache === void 0 ? void 0 : frontmatterCache.file) === null || _a === void 0 ? void 0 : _a.path}`); + superDebug(settings, rawValues); + rawValues.forEach((rawItem) => { + if (!rawItem) + return; + let unProxied = [rawItem]; + if (util__default['default'].types.isProxy(rawItem)) { + unProxied = []; + // Definitely a proxy the first time + const first = Object.assign({}, rawItem); + first.values.forEach((firstVal) => { + if (util__default['default'].types.isProxy(firstVal)) { + const second = Object.assign({}, firstVal); + const secondValues = second.values; + if (secondValues) { + secondValues.forEach((secondVal) => { + if (util__default['default'].types.isProxy(secondVal)) { + const third = Object.assign({}, secondVal).values; + third.forEach((thirdVal) => { + unProxied.push(thirdVal); + }); + } + else { + unProxied.push(secondVal); + } + }); + } + else { + unProxied.push(second); + } + } + else { + unProxied.push(firstVal); + } + }); + } + unProxied.forEach((value) => { + if (typeof value === "string" || typeof value === "number") { + // Obs cache converts link of form: [[\d+]] to number[][] + const rawItemAsString = value.toString(); + const splits = rawItemAsString.match(splitLinksRegex); + if (splits !== null) { + const strs = splits.map((link) => link.match(dropHeaderOrAlias)[1].split("/").last()); + values.push(...strs); + } + else { + values.push(rawItemAsString.split("/").last()); + } + } + else if (value.path !== undefined) { + const lastSplit = value.path.split("/").last(); + if (lastSplit !== undefined) { + values.push(lastSplit); + } + } + }); + }); + } + return values; } - async onload() { - super.onload(); - await this.plugin.saveSettings(); - this.app.workspace.onLayoutReady(async () => { - setTimeout(async () => await this.draw(), this.plugin.settings.dvWaitTime); + catch (error) { + console.log(error); + return values; + } +} +const splitAndTrim = (fields) => fields.split(",").map((str) => str.trim()); +/** + * + * @param {BreadcrumbsPlugin} plugin + * @param {dvFrontmatterCache[]} fileFrontmatterArr + * @returns HierarchyFields + */ +async function getNeighbourObjArr(plugin, fileFrontmatterArr) { + const { settings } = plugin; + const { userHierarchies } = settings; + if (settings.debugMode || settings.superDebugMode) { + console.groupCollapsed("getNeighbourObjArr"); + } + let jugglLinks = []; + if (plugin.app.plugins.plugins.juggl !== undefined || + plugin.settings.parseJugglLinksWithoutJuggl) { + jugglLinks = await getJugglLinks(plugin.app, plugin.settings); + } + const neighbourObjArr = fileFrontmatterArr.map((fileFrontmatter) => { + const currFileName = fileFrontmatter.file.basename || fileFrontmatter.file.name; + const hierFields = { + current: fileFrontmatter.file, + hierarchies: [], + }; + userHierarchies.forEach((hier, i) => { + const fieldsArr = Object.values(hier); + const newHier = { up: {}, same: {}, down: {} }; + // Add regular metadata links + if (settings.useAllMetadata) { + DIRECTIONS.forEach((dir, i) => { + fieldsArr[i].forEach((field) => { + newHier[dir][field] = getFieldValues(fileFrontmatter, field, settings); + }); + }); + } + // Add Juggl Links + if (jugglLinks.length) { + const jugglLinksInFile = jugglLinks.filter((jugglLink) => { + return jugglLink.note === currFileName; + })[0]; + if (jugglLinksInFile) { + jugglLinksInFile.links.forEach((line) => { + var _a; + if (hier[line.dir].includes(line.type)) { + newHier[line.dir][line.type] = [ + ...new Set([ + ...((_a = newHier[line.dir][line.type]) !== null && _a !== void 0 ? _a : []), + ...line.linksInLine, + ]), + ]; + } + }); + } + } + hierFields.hierarchies.push(newHier); }); + return hierFields; + }); + debug(settings, { neighbourObjArr }); + if (settings.debugMode || settings.superDebugMode) { + console.groupEnd(); } - getViewType() { - return STATS_VIEW; + return neighbourObjArr; +} +// This function takes the real & implied graphs for a given relation, and returns a new graphs with both. +// It makes implied relations real +function closeImpliedLinks(real, implied) { + const closedG = real.copy(); + implied.forEachEdge((key, a, s, t) => { + closedG.mergeEdge(t, s, a); + }); + return closedG; +} +const isInVault = (app, note) => !!app.metadataCache.getFirstLinkpathDest(note, app.workspace.getActiveFile().path); +function hoverPreview(event, matrixView, to) { + const targetEl = event.target; + matrixView.app.workspace.trigger("hover-link", { + event, + source: matrixView.getViewType(), + hoverParent: matrixView, + targetEl, + linktext: to, + }); +} +async function openOrSwitch(app, dest, currFile, event) { + const { workspace } = app; + let destFile = app.metadataCache.getFirstLinkpathDest(dest, currFile.path); + // If dest doesn't exist, make it + if (!destFile) { + const newFileFolder = app.fileManager.getNewFileParent(currFile.path).path; + const newFilePath = `${newFileFolder}${newFileFolder === "/" ? "" : "/"}${dest}.md`; + await app.vault.create(newFilePath, ""); + destFile = app.metadataCache.getFirstLinkpathDest(newFilePath, currFile.path); } - getDisplayText() { - return "Breadcrumbs Stats"; + // Check if it's already open + const leavesWithDestAlreadyOpen = []; + // For all open leaves, if the leave's basename is equal to the link destination, rather activate that leaf instead of opening it in two panes + workspace.iterateAllLeaves((leaf) => { + var _a, _b; + if (((_b = (_a = leaf.view) === null || _a === void 0 ? void 0 : _a.file) === null || _b === void 0 ? void 0 : _b.basename) === dest) { + leavesWithDestAlreadyOpen.push(leaf); + } + }); + // Rather switch to it if it is open + if (leavesWithDestAlreadyOpen.length > 0) { + workspace.setActiveLeaf(leavesWithDestAlreadyOpen[0]); } - async onOpen() { - await this.plugin.saveSettings(); + else { + const mode = app.vault.getConfig("defaultViewMode"); + const leaf = event.ctrlKey || event.getModifierState("Meta") + ? workspace.splitActiveLeaf() + : workspace.getUnpinnedLeaf(); + await leaf.openFile(destFile, { active: true, mode }); } - onClose() { - if (this.view) { - this.view.$destroy(); +} +function padArray(arr, finalLength, filler = "") { + const copy = [...arr]; + const currLength = copy.length; + if (currLength > finalLength) { + throw new Error("Current length is greater than final length"); + } + else if (currLength === finalLength) { + return copy; + } + else { + for (let i = currLength; i < finalLength; i++) { + copy.push(filler); } - return Promise.resolve(); + return copy; } - // ANCHOR Remove duplicate implied links - dfsAllPaths(g, startNode) { - const queue = [ - { node: startNode, path: [] }, - ]; - const pathsArr = []; - let i = 0; - while (queue.length > 0 && i < 1000) { +} +function transpose(A) { + const cols = A[0].length; + const AT = []; + // For each column + for (let j = 0; j < cols; j++) { + // Add a new row to AT + AT.push([]); + // And fill it with the values in the jth column of A + A.forEach((row) => AT[j].push(row[j])); + } + return AT; +} +function runs(arr) { + const runs = []; + let i = 0; + while (i < arr.length) { + const currValue = arr[i]; + runs.push({ value: currValue, first: i, last: undefined }); + while (currValue === arr[i]) { i++; - const currPath = queue.shift(); - const newNodes = g.outNeighbors(currPath.node); - const extPath = [currPath.node, ...currPath.path]; - queue.unshift(...newNodes.map((n) => { - return { node: n, path: extPath }; - })); - if (newNodes.length === 0) { - pathsArr.push(extPath); + } + runs.last().last = i - 1; + } + return runs; +} +async function copy$1(content) { + await navigator.clipboard.writeText(content).then(() => new obsidian.Notice("Copied to clipboard"), () => new obsidian.Notice("Could not copy to clipboard")); +} +function mergeGs(...graphs) { + const outG = new graphology_umd_min(); + graphs.forEach((g) => { + g.forEachNode((node, a) => { + outG.mergeNode(node, a); + }); + g.forEachEdge((key, a, s, t) => { + outG.mergeEdge(s, t, a); + }); + }); + return outG; +} +function removeUnlinkedNodes(g) { + const copy = g.copy(); + copy.forEachNode((node) => { + if (!copy.neighbors(node).length) + copy.dropNode(node); + }); + return copy; +} +function getAllGsInDir(currGraphs, dir) { + const target = {}; + const allGsInDir = Object.assign(target, ...currGraphs.map((hierGs) => hierGs[dir])); + return allGsInDir; +} +function iterateAllGs(currGraphs, cb) { + for (const hierGs of currGraphs) { + for (const dir of DIRECTIONS) { + for (const fieldName in hierGs[dir]) { + const g = hierGs[dir][fieldName]; + cb(g, dir, fieldName); } } - return pathsArr; } - async draw() { - this.contentEl.empty(); - this.view = new Stats({ - target: this.contentEl, - props: { plugin: this.plugin }, +} +function getAllFieldGs(fields, currGraphs) { + const fieldGs = []; + iterateAllGs(currGraphs, (g, dir, fieldName) => { + if (fields.includes(fieldName)) + fieldGs.push(g); + }); + return fieldGs; +} +function hierToStr(hier) { + return `↑: ${hier.up.join(", ")} +→: ${hier.same.join(", ")} +↓: ${hier.down.join(", ")}`; +} +function removeDuplicates(arr) { + return [...new Set(arr)]; +} +/** + * Adds or updates the given yaml `key` to `value` in the given TFile + * @param {string} key + * @param {string} value + * @param {TFile} file + * @param {FrontMatterCache|undefined} frontmatter + * @param {{[fun:string]:(...args:any} api + */ +const createOrUpdateYaml = async (key, value, file, frontmatter, api) => { + let valueStr = value.toString(); + if (!frontmatter || frontmatter[key] === undefined) { + console.log(`Creating: ${key}: ${valueStr}`); + await api.createYamlProperty(key, `['${valueStr}']`, file); + } + else if ([...[frontmatter[key]]].flat(3).some((val) => val == valueStr)) { + console.log("Already Exists!"); + return; + } + else { + const oldValueFlat = [...[frontmatter[key]]].flat(4); + const newValue = [...oldValueFlat, valueStr].map((val) => `'${val}'`); + console.log(`Updating: ${key}: ${newValue}`); + await api.update(key, `[${newValue.join(", ")}]`, file); + } +}; +const getOppDir = (dir) => dir === "same" ? "same" : dir === "up" ? "down" : "up"; +const writeBCToFile = (app, plugin, currGraphs, file) => { + var _a, _b; + const frontmatter = (_a = app.metadataCache.getFileCache(file)) === null || _a === void 0 ? void 0 : _a.frontmatter; + const api = (_b = app.plugins.plugins.metaedit) === null || _b === void 0 ? void 0 : _b.api; + if (!api) { + new obsidian.Notice("Metaedit must be enabled for this function to work"); + return; + } + iterateAllGs(currGraphs.hierGs, (fieldG, dir, fieldName) => { + const oppDir = getOppDir(dir); + const succs = fieldG.inNeighbors(file.basename); + succs.forEach(async (succ) => { + const { fieldName } = fieldG.getNodeAttributes(succ); + if (!plugin.settings.limitWriteBCCheckboxStates[fieldName]) + return; + const currHier = plugin.settings.userHierarchies.find((hier) => hier[dir].includes(fieldName)); + let oppField = currHier[oppDir][0]; + if (!oppField) + oppField = `${fieldName}`; + await createOrUpdateYaml(oppField, succ, file, frontmatter, api); }); + }); +}; +function oppFields(field, dir, userHierarchies) { + var _a, _b; + const oppDir = getOppDir(dir); + return ((_b = (_a = userHierarchies.find((hier) => hier[oppDir].includes(field))) === null || _a === void 0 ? void 0 : _a[oppDir]) !== null && _b !== void 0 ? _b : []); +} +function addNodeIfNot(g, node, attr) { + if (!g.hasNode(node)) { + g.addNode(node, attr); + } +} +function addEdgeIfNot(g, source, target, attr) { + if (!g.hasEdge(source, target)) { + g.addEdge(source, target, attr); } +} +const getSinks = (g) => g.filterNodes((node) => !g.outNeighbors(node).length); +function swapItems(i, j, arr) { + const max = arr.length - 1; + if (i < 0 || i > max || j < 0 || j > max) + return arr; + const tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + return arr; +} + +function noop$1() { } +function assign(tar, src) { + // @ts-ignore + for (const k in src) + tar[k] = src[k]; + return tar; } - -function ascending$1(a, b) { - return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; +function run(fn) { + return fn(); } - -function bisector(f) { - let delta = f; - let compare = f; - - if (f.length === 1) { - delta = (d, x) => f(d) - x; - compare = ascendingComparator(f); - } - - function left(a, x, lo, hi) { - if (lo == null) lo = 0; - if (hi == null) hi = a.length; - while (lo < hi) { - const mid = (lo + hi) >>> 1; - if (compare(a[mid], x) < 0) lo = mid + 1; - else hi = mid; - } - return lo; - } - - function right(a, x, lo, hi) { - if (lo == null) lo = 0; - if (hi == null) hi = a.length; - while (lo < hi) { - const mid = (lo + hi) >>> 1; - if (compare(a[mid], x) > 0) hi = mid; - else lo = mid + 1; - } - return lo; - } - - function center(a, x, lo, hi) { - if (lo == null) lo = 0; - if (hi == null) hi = a.length; - const i = left(a, x, lo, hi - 1); - return i > lo && delta(a[i - 1], x) > -delta(a[i], x) ? i - 1 : i; - } - - return {left, center, right}; +function blank_object() { + return Object.create(null); } - -function ascendingComparator(f) { - return (d, x) => ascending$1(f(d), x); +function run_all(fns) { + fns.forEach(run); } - -function number$1(x) { - return x === null ? NaN : +x; +function is_function(thing) { + return typeof thing === 'function'; } - -const ascendingBisect = bisector(ascending$1); -const bisectRight = ascendingBisect.right; -bisector(number$1).center; - -var e10 = Math.sqrt(50), - e5 = Math.sqrt(10), - e2 = Math.sqrt(2); - -function ticks(start, stop, count) { - var reverse, - i = -1, - n, - ticks, - step; - - stop = +stop, start = +start, count = +count; - if (start === stop && count > 0) return [start]; - if (reverse = stop < start) n = start, start = stop, stop = n; - if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return []; - - if (step > 0) { - let r0 = Math.round(start / step), r1 = Math.round(stop / step); - if (r0 * step < start) ++r0; - if (r1 * step > stop) --r1; - ticks = new Array(n = r1 - r0 + 1); - while (++i < n) ticks[i] = (r0 + i) * step; - } else { - step = -step; - let r0 = Math.round(start * step), r1 = Math.round(stop * step); - if (r0 / step < start) ++r0; - if (r1 / step > stop) --r1; - ticks = new Array(n = r1 - r0 + 1); - while (++i < n) ticks[i] = (r0 + i) / step; - } - - if (reverse) ticks.reverse(); - - return ticks; +function safe_not_equal(a, b) { + return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function'); +} +function is_empty(obj) { + return Object.keys(obj).length === 0; } - -function tickIncrement(start, stop, count) { - var step = (stop - start) / Math.max(0, count), - power = Math.floor(Math.log(step) / Math.LN10), - error = step / Math.pow(10, power); - return power >= 0 - ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power) - : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1); +function create_slot(definition, ctx, $$scope, fn) { + if (definition) { + const slot_ctx = get_slot_context(definition, ctx, $$scope, fn); + return definition[0](slot_ctx); + } } - -function tickStep(start, stop, count) { - var step0 = Math.abs(stop - start) / Math.max(0, count), - step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)), - error = step0 / step1; - if (error >= e10) step1 *= 10; - else if (error >= e5) step1 *= 5; - else if (error >= e2) step1 *= 2; - return stop < start ? -step1 : step1; +function get_slot_context(definition, ctx, $$scope, fn) { + return definition[1] && fn + ? assign($$scope.ctx.slice(), definition[1](fn(ctx))) + : $$scope.ctx; } - -function max$1(values, valueof) { - let max; - if (valueof === undefined) { - for (const value of values) { - if (value != null - && (max < value || (max === undefined && value >= value))) { - max = value; - } +function get_slot_changes(definition, $$scope, dirty, fn) { + if (definition[2] && fn) { + const lets = definition[2](fn(dirty)); + if ($$scope.dirty === undefined) { + return lets; + } + if (typeof lets === 'object') { + const merged = []; + const len = Math.max($$scope.dirty.length, lets.length); + for (let i = 0; i < len; i += 1) { + merged[i] = $$scope.dirty[i] | lets[i]; + } + return merged; + } + return $$scope.dirty | lets; } - } else { - let index = -1; - for (let value of values) { - if ((value = valueof(value, ++index, values)) != null - && (max < value || (max === undefined && value >= value))) { - max = value; - } + return $$scope.dirty; +} +function update_slot(slot, slot_definition, ctx, $$scope, dirty, get_slot_changes_fn, get_slot_context_fn) { + const slot_changes = get_slot_changes(slot_definition, $$scope, dirty, get_slot_changes_fn); + if (slot_changes) { + const slot_context = get_slot_context(slot_definition, ctx, $$scope, get_slot_context_fn); + slot.p(slot_context, slot_changes); } - } - return max; } - -function sequence(start, stop, step) { - start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step; - - var i = -1, - n = Math.max(0, Math.ceil((stop - start) / step)) | 0, - range = new Array(n); - - while (++i < n) { - range[i] = start + i * step; - } - - return range; +function exclude_internal_props(props) { + const result = {}; + for (const k in props) + if (k[0] !== '$') + result[k] = props[k]; + return result; } - -var noop$1 = {value: () => {}}; - -function dispatch() { - for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) { - if (!(t = arguments[i] + "") || (t in _) || /[\s.]/.test(t)) throw new Error("illegal type: " + t); - _[t] = []; - } - return new Dispatch(_); +function null_to_empty(value) { + return value == null ? '' : value; } -function Dispatch(_) { - this._ = _; +function append(target, node) { + target.appendChild(node); } - -function parseTypenames$1(typenames, types) { - return typenames.trim().split(/^|\s+/).map(function(t) { - var name = "", i = t.indexOf("."); - if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); - if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t); - return {type: t, name: name}; - }); +function insert(target, node, anchor) { + target.insertBefore(node, anchor || null); } - -Dispatch.prototype = dispatch.prototype = { - constructor: Dispatch, - on: function(typename, callback) { - var _ = this._, - T = parseTypenames$1(typename + "", _), - t, - i = -1, - n = T.length; - - // If no callback was specified, return the callback of the given type and name. - if (arguments.length < 2) { - while (++i < n) if ((t = (typename = T[i]).type) && (t = get$2(_[t], typename.name))) return t; - return; - } - - // If a type was specified, set the callback for the given type and name. - // Otherwise, if a null callback was specified, remove callbacks of the given name. - if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback); - while (++i < n) { - if (t = (typename = T[i]).type) _[t] = set$1(_[t], typename.name, callback); - else if (callback == null) for (t in _) _[t] = set$1(_[t], typename.name, null); - } - - return this; - }, - copy: function() { - var copy = {}, _ = this._; - for (var t in _) copy[t] = _[t].slice(); - return new Dispatch(copy); - }, - call: function(type, that) { - if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2]; - if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); - for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); - }, - apply: function(type, that, args) { - if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); - for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); - } -}; - -function get$2(type, name) { - for (var i = 0, n = type.length, c; i < n; ++i) { - if ((c = type[i]).name === name) { - return c.value; - } - } +function detach(node) { + node.parentNode.removeChild(node); } - -function set$1(type, name, callback) { - for (var i = 0, n = type.length; i < n; ++i) { - if (type[i].name === name) { - type[i] = noop$1, type = type.slice(0, i).concat(type.slice(i + 1)); - break; +function destroy_each(iterations, detaching) { + for (let i = 0; i < iterations.length; i += 1) { + if (iterations[i]) + iterations[i].d(detaching); } - } - if (callback != null) type.push({name: name, value: callback}); - return type; } - -var xhtml = "http://www.w3.org/1999/xhtml"; - -var namespaces = { - svg: "http://www.w3.org/2000/svg", - xhtml: xhtml, - xlink: "http://www.w3.org/1999/xlink", - xml: "http://www.w3.org/XML/1998/namespace", - xmlns: "http://www.w3.org/2000/xmlns/" -}; - -function namespace(name) { - var prefix = name += "", i = prefix.indexOf(":"); - if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1); - return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name; // eslint-disable-line no-prototype-builtins +function element(name) { + return document.createElement(name); } - -function creatorInherit(name) { - return function() { - var document = this.ownerDocument, - uri = this.namespaceURI; - return uri === xhtml && document.documentElement.namespaceURI === xhtml - ? document.createElement(name) - : document.createElementNS(uri, name); - }; +function svg_element(name) { + return document.createElementNS('http://www.w3.org/2000/svg', name); } - -function creatorFixed(fullname) { - return function() { - return this.ownerDocument.createElementNS(fullname.space, fullname.local); - }; +function text(data) { + return document.createTextNode(data); } - -function creator(name) { - var fullname = namespace(name); - return (fullname.local - ? creatorFixed - : creatorInherit)(fullname); +function space() { + return text(' '); } - -function none() {} - -function selector(selector) { - return selector == null ? none : function() { - return this.querySelector(selector); - }; +function empty$1() { + return text(''); } - -function selection_select(select) { - if (typeof select !== "function") select = selector(select); - - for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) { - if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) { - if ("__data__" in node) subnode.__data__ = node.__data__; - subgroup[i] = subnode; - } - } - } - - return new Selection$1(subgroups, this._parents); +function listen(node, event, handler, options) { + node.addEventListener(event, handler, options); + return () => node.removeEventListener(event, handler, options); } - -function array$1(x) { - return typeof x === "object" && "length" in x - ? x // Array, TypedArray, NodeList, array-like - : Array.from(x); // Map, Set, iterable, string, or anything else +function attr(node, attribute, value) { + if (value == null) + node.removeAttribute(attribute); + else if (node.getAttribute(attribute) !== value) + node.setAttribute(attribute, value); } - -function empty() { - return []; +function children$1(element) { + return Array.from(element.childNodes); } - -function selectorAll(selector) { - return selector == null ? empty : function() { - return this.querySelectorAll(selector); - }; +function set_data(text, data) { + data = '' + data; + if (text.wholeText !== data) + text.data = data; } - -function arrayAll(select) { - return function() { - var group = select.apply(this, arguments); - return group == null ? [] : array$1(group); - }; +function set_style(node, key, value, important) { + node.style.setProperty(key, value, important ? 'important' : ''); } - -function selection_selectAll(select) { - if (typeof select === "function") select = arrayAll(select); - else select = selectorAll(select); - - for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { - if (node = group[i]) { - subgroups.push(select.call(node, node.__data__, i, group)); - parents.push(node); - } +function select_option(select, value) { + for (let i = 0; i < select.options.length; i += 1) { + const option = select.options[i]; + if (option.__value === value) { + option.selected = true; + return; + } } - } - - return new Selection$1(subgroups, parents); -} - -function matcher(selector) { - return function() { - return this.matches(selector); - }; } -function childMatcher(selector) { - return function(node) { - return node.matches(selector); - }; +let current_component; +function set_current_component(component) { + current_component = component; } -var find$1 = Array.prototype.find; - -function childFind(match) { - return function() { - return find$1.call(this.children, match); - }; +const dirty_components = []; +const binding_callbacks = []; +const render_callbacks = []; +const flush_callbacks = []; +const resolved_promise = Promise.resolve(); +let update_scheduled = false; +function schedule_update() { + if (!update_scheduled) { + update_scheduled = true; + resolved_promise.then(flush); + } } - -function childFirst() { - return this.firstElementChild; +function add_render_callback(fn) { + render_callbacks.push(fn); } - -function selection_selectChild(match) { - return this.select(match == null ? childFirst - : childFind(typeof match === "function" ? match : childMatcher(match))); +let flushing = false; +const seen_callbacks = new Set(); +function flush() { + if (flushing) + return; + flushing = true; + do { + // first, call beforeUpdate functions + // and update components + for (let i = 0; i < dirty_components.length; i += 1) { + const component = dirty_components[i]; + set_current_component(component); + update(component.$$); + } + set_current_component(null); + dirty_components.length = 0; + while (binding_callbacks.length) + binding_callbacks.pop()(); + // then, once components are updated, call + // afterUpdate functions. This may cause + // subsequent updates... + for (let i = 0; i < render_callbacks.length; i += 1) { + const callback = render_callbacks[i]; + if (!seen_callbacks.has(callback)) { + // ...so guard against infinite loops + seen_callbacks.add(callback); + callback(); + } + } + render_callbacks.length = 0; + } while (dirty_components.length); + while (flush_callbacks.length) { + flush_callbacks.pop()(); + } + update_scheduled = false; + flushing = false; + seen_callbacks.clear(); } - -var filter$1 = Array.prototype.filter; - -function children() { - return this.children; +function update($$) { + if ($$.fragment !== null) { + $$.update(); + run_all($$.before_update); + const dirty = $$.dirty; + $$.dirty = [-1]; + $$.fragment && $$.fragment.p($$.ctx, dirty); + $$.after_update.forEach(add_render_callback); + } } - -function childrenFilter(match) { - return function() { - return filter$1.call(this.children, match); - }; +const outroing = new Set(); +let outros; +function transition_in(block, local) { + if (block && block.i) { + outroing.delete(block); + block.i(local); + } } - -function selection_selectChildren(match) { - return this.selectAll(match == null ? children - : childrenFilter(typeof match === "function" ? match : childMatcher(match))); +function transition_out(block, local, detach, callback) { + if (block && block.o) { + if (outroing.has(block)) + return; + outroing.add(block); + outros.c.push(() => { + outroing.delete(block); + if (callback) { + if (detach) + block.d(1); + callback(); + } + }); + block.o(local); + } } -function selection_filter(match) { - if (typeof match !== "function") match = matcher(match); - - for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) { - if ((node = group[i]) && match.call(node, node.__data__, i, group)) { - subgroup.push(node); - } +function get_spread_update(levels, updates) { + const update = {}; + const to_null_out = {}; + const accounted_for = { $$scope: 1 }; + let i = levels.length; + while (i--) { + const o = levels[i]; + const n = updates[i]; + if (n) { + for (const key in o) { + if (!(key in n)) + to_null_out[key] = 1; + } + for (const key in n) { + if (!accounted_for[key]) { + update[key] = n[key]; + accounted_for[key] = 1; + } + } + levels[i] = n; + } + else { + for (const key in o) { + accounted_for[key] = 1; + } + } } - } - - return new Selection$1(subgroups, this._parents); + for (const key in to_null_out) { + if (!(key in update)) + update[key] = undefined; + } + return update; } - -function sparse(update) { - return new Array(update.length); +function get_spread_object(spread_props) { + return typeof spread_props === 'object' && spread_props !== null ? spread_props : {}; } - -function selection_enter() { - return new Selection$1(this._enter || this._groups.map(sparse), this._parents); +function create_component(block) { + block && block.c(); } - -function EnterNode(parent, datum) { - this.ownerDocument = parent.ownerDocument; - this.namespaceURI = parent.namespaceURI; - this._next = null; - this._parent = parent; - this.__data__ = datum; +function mount_component(component, target, anchor, customElement) { + const { fragment, on_mount, on_destroy, after_update } = component.$$; + fragment && fragment.m(target, anchor); + if (!customElement) { + // onMount happens before the initial afterUpdate + add_render_callback(() => { + const new_on_destroy = on_mount.map(run).filter(is_function); + if (on_destroy) { + on_destroy.push(...new_on_destroy); + } + else { + // Edge case - component was destroyed immediately, + // most likely as a result of a binding initialising + run_all(new_on_destroy); + } + component.$$.on_mount = []; + }); + } + after_update.forEach(add_render_callback); } - -EnterNode.prototype = { - constructor: EnterNode, - appendChild: function(child) { return this._parent.insertBefore(child, this._next); }, - insertBefore: function(child, next) { return this._parent.insertBefore(child, next); }, - querySelector: function(selector) { return this._parent.querySelector(selector); }, - querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); } -}; - -function constant$7(x) { - return function() { - return x; - }; +function destroy_component(component, detaching) { + const $$ = component.$$; + if ($$.fragment !== null) { + run_all($$.on_destroy); + $$.fragment && $$.fragment.d(detaching); + // TODO null out other refs, including component.$$ (but need to + // preserve final state?) + $$.on_destroy = $$.fragment = null; + $$.ctx = []; + } } - -function bindIndex(parent, group, enter, update, exit, data) { - var i = 0, - node, - groupLength = group.length, - dataLength = data.length; - - // Put any non-null nodes that fit into update. - // Put any null nodes into enter. - // Put any remaining data into enter. - for (; i < dataLength; ++i) { - if (node = group[i]) { - node.__data__ = data[i]; - update[i] = node; - } else { - enter[i] = new EnterNode(parent, data[i]); +function make_dirty(component, i) { + if (component.$$.dirty[0] === -1) { + dirty_components.push(component); + schedule_update(); + component.$$.dirty.fill(0); } - } - - // Put any non-null nodes that don’t fit into exit. - for (; i < groupLength; ++i) { - if (node = group[i]) { - exit[i] = node; + component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31)); +} +function init$1(component, options, instance, create_fragment, not_equal, props, dirty = [-1]) { + const parent_component = current_component; + set_current_component(component); + const $$ = component.$$ = { + fragment: null, + ctx: null, + // state + props, + update: noop$1, + not_equal, + bound: blank_object(), + // lifecycle + on_mount: [], + on_destroy: [], + on_disconnect: [], + before_update: [], + after_update: [], + context: new Map(parent_component ? parent_component.$$.context : []), + // everything else + callbacks: blank_object(), + dirty, + skip_bound: false + }; + let ready = false; + $$.ctx = instance + ? instance(component, options.props || {}, (i, ret, ...rest) => { + const value = rest.length ? rest[0] : ret; + if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) { + if (!$$.skip_bound && $$.bound[i]) + $$.bound[i](value); + if (ready) + make_dirty(component, i); + } + return ret; + }) + : []; + $$.update(); + ready = true; + run_all($$.before_update); + // `false` as a special case of no DOM component + $$.fragment = create_fragment ? create_fragment($$.ctx) : false; + if (options.target) { + if (options.hydrate) { + const nodes = children$1(options.target); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + $$.fragment && $$.fragment.l(nodes); + nodes.forEach(detach); + } + else { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + $$.fragment && $$.fragment.c(); + } + if (options.intro) + transition_in(component.$$.fragment); + mount_component(component, options.target, options.anchor, options.customElement); + flush(); } - } + set_current_component(parent_component); } - -function bindKey(parent, group, enter, update, exit, data, key) { - var i, - node, - nodeByKeyValue = new Map, - groupLength = group.length, - dataLength = data.length, - keyValues = new Array(groupLength), - keyValue; - - // Compute the key for each node. - // If multiple nodes have the same key, the duplicates are added to exit. - for (i = 0; i < groupLength; ++i) { - if (node = group[i]) { - keyValues[i] = keyValue = key.call(node, node.__data__, i, group) + ""; - if (nodeByKeyValue.has(keyValue)) { - exit[i] = node; - } else { - nodeByKeyValue.set(keyValue, node); - } +/** + * Base class for Svelte components. Used when dev=false. + */ +class SvelteComponent { + $destroy() { + destroy_component(this, 1); + this.$destroy = noop$1; } - } - - // Compute the key for each datum. - // If there a node associated with this key, join and add it to update. - // If there is not (or the key is a duplicate), add it to enter. - for (i = 0; i < dataLength; ++i) { - keyValue = key.call(parent, data[i], i, data) + ""; - if (node = nodeByKeyValue.get(keyValue)) { - update[i] = node; - node.__data__ = data[i]; - nodeByKeyValue.delete(keyValue); - } else { - enter[i] = new EnterNode(parent, data[i]); + $on(type, callback) { + const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = [])); + callbacks.push(callback); + return () => { + const index = callbacks.indexOf(callback); + if (index !== -1) + callbacks.splice(index, 1); + }; } - } - - // Add any remaining nodes that were not bound to data to exit. - for (i = 0; i < groupLength; ++i) { - if ((node = group[i]) && (nodeByKeyValue.get(keyValues[i]) === node)) { - exit[i] = node; + $set($$props) { + if (this.$$set && !is_empty($$props)) { + this.$$.skip_bound = true; + this.$$set($$props); + this.$$.skip_bound = false; + } } - } -} - -function datum(node) { - return node.__data__; } -function selection_data(value, key) { - if (!arguments.length) return Array.from(this, datum); - - var bind = key ? bindKey : bindIndex, - parents = this._parents, - groups = this._groups; - - if (typeof value !== "function") value = constant$7(value); - - for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) { - var parent = parents[j], - group = groups[j], - groupLength = group.length, - data = array$1(value.call(parent, parent && parent.__data__, j, parents)), - dataLength = data.length, - enterGroup = enter[j] = new Array(dataLength), - updateGroup = update[j] = new Array(dataLength), - exitGroup = exit[j] = new Array(groupLength); +/* src\Components\Lists.svelte generated by Svelte v3.35.0 */ - bind(parent, group, enterGroup, updateGroup, exitGroup, data, key); +function add_css$6() { + var style = element("style"); + style.id = "svelte-fwoihq-style"; + style.textContent = "summary.hier-summary.svelte-fwoihq{color:var(--text-title-h2);font-size:larger}summary.svelte-fwoihq{color:var(--text-title-h3)}h5.breadcrumbs-header.svelte-fwoihq{color:var(--text-title-h5)}ol.markdown-preview-view.svelte-fwoihq{padding-top:3px;padding-bottom:5px}"; + append(document.head, style); +} - // Now connect the enter nodes to their following update node, such that - // appendChild can insert the materialized enter node before this node, - // rather than at the end of the parent node. - for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) { - if (previous = enterGroup[i0]) { - if (i0 >= i1) i1 = i0 + 1; - while (!(next = updateGroup[i1]) && ++i1 < dataLength); - previous._next = next || null; - } - } - } +function get_each_context$6(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[9] = list[i]; + return child_ctx; +} - update = new Selection$1(update, parents); - update._enter = enter; - update._exit = exit; - return update; +function get_each_context_1$6(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[12] = list[i]; + return child_ctx; } -function selection_exit() { - return new Selection$1(this._exit || this._groups.map(sparse), this._parents); +function get_each_context_2$3(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[15] = list[i]; + return child_ctx; } -function selection_join(onenter, onupdate, onexit) { - var enter = this.enter(), update = this, exit = this.exit(); - enter = typeof onenter === "function" ? onenter(enter) : enter.append(onenter + ""); - if (onupdate != null) update = onupdate(update); - if (onexit == null) exit.remove(); else onexit(exit); - return enter && update ? enter.merge(update).order() : update; +function get_each_context_3$2(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[18] = list[i]; + return child_ctx; } -function selection_merge(selection) { - if (!(selection instanceof Selection$1)) throw new Error("invalid merge"); +// (21:8) {#if square.realItems.length > 0 || square.impliedItems.length > 0} +function create_if_block$4(ctx) { + let details; + let summary; + let t0_value = /*square*/ ctx[12].fieldName + ""; + let t0; + let t1; + let t2; + let if_block0 = /*square*/ ctx[12].realItems.length && create_if_block_3$1(ctx); + let if_block1 = /*square*/ ctx[12].impliedItems.length && create_if_block_1$2(ctx); - for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { - for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) { - if (node = group0[i] || group1[i]) { - merge[i] = node; - } - } - } + return { + c() { + details = element("details"); + summary = element("summary"); + t0 = text(t0_value); + t1 = space(); + if (if_block0) if_block0.c(); + t2 = space(); + if (if_block1) if_block1.c(); + attr(summary, "class", "svelte-fwoihq"); + details.open = true; + attr(details, "class", "breadcrumbs-details"); + }, + m(target, anchor) { + insert(target, details, anchor); + append(details, summary); + append(summary, t0); + append(details, t1); + if (if_block0) if_block0.m(details, null); + append(details, t2); + if (if_block1) if_block1.m(details, null); + }, + p(ctx, dirty) { + if (dirty & /*filteredSquaresArr*/ 1 && t0_value !== (t0_value = /*square*/ ctx[12].fieldName + "")) set_data(t0, t0_value); - for (; j < m0; ++j) { - merges[j] = groups0[j]; - } + if (/*square*/ ctx[12].realItems.length) { + if (if_block0) { + if_block0.p(ctx, dirty); + } else { + if_block0 = create_if_block_3$1(ctx); + if_block0.c(); + if_block0.m(details, t2); + } + } else if (if_block0) { + if_block0.d(1); + if_block0 = null; + } - return new Selection$1(merges, this._parents); + if (/*square*/ ctx[12].impliedItems.length) { + if (if_block1) { + if_block1.p(ctx, dirty); + } else { + if_block1 = create_if_block_1$2(ctx); + if_block1.c(); + if_block1.m(details, null); + } + } else if (if_block1) { + if_block1.d(1); + if_block1 = null; + } + }, + d(detaching) { + if (detaching) detach(details); + if (if_block0) if_block0.d(); + if (if_block1) if_block1.d(); + } + }; } -function selection_order() { - - for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) { - for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) { - if (node = group[i]) { - if (next && node.compareDocumentPosition(next) ^ 4) next.parentNode.insertBefore(node, next); - next = node; - } - } - } - - return this; -} +// (24:12) {#if square.realItems.length} +function create_if_block_3$1(ctx) { + let t; + let ol; + let if_block = /*settings*/ ctx[2].showRelationType && create_if_block_4$1(); + let each_value_3 = /*square*/ ctx[12].realItems; + let each_blocks = []; -function selection_sort(compare) { - if (!compare) compare = ascending; + for (let i = 0; i < each_value_3.length; i += 1) { + each_blocks[i] = create_each_block_3$2(get_each_context_3$2(ctx, each_value_3, i)); + } - function compareNode(a, b) { - return a && b ? compare(a.__data__, b.__data__) : !a - !b; - } + return { + c() { + if (if_block) if_block.c(); + t = space(); + ol = element("ol"); - for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) { - if (node = group[i]) { - sortgroup[i] = node; - } - } - sortgroup.sort(compareNode); - } + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } - return new Selection$1(sortgroups, this._parents).order(); -} + attr(ol, "class", "markdown-preview-view svelte-fwoihq"); + }, + m(target, anchor) { + if (if_block) if_block.m(target, anchor); + insert(target, t, anchor); + insert(target, ol, anchor); -function ascending(a, b) { - return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; -} + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(ol, null); + } + }, + p(ctx, dirty) { + if (/*settings*/ ctx[2].showRelationType) { + if (if_block) ; else { + if_block = create_if_block_4$1(); + if_block.c(); + if_block.m(t.parentNode, t); + } + } else if (if_block) { + if_block.d(1); + if_block = null; + } -function selection_call() { - var callback = arguments[0]; - arguments[0] = this; - callback.apply(null, arguments); - return this; -} + if (dirty & /*filteredSquaresArr, openOrSwitch, app, currFile, hoverPreview, matrixView*/ 27) { + each_value_3 = /*square*/ ctx[12].realItems; + let i; -function selection_nodes() { - return Array.from(this); -} + for (i = 0; i < each_value_3.length; i += 1) { + const child_ctx = get_each_context_3$2(ctx, each_value_3, i); -function selection_node() { + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + } else { + each_blocks[i] = create_each_block_3$2(child_ctx); + each_blocks[i].c(); + each_blocks[i].m(ol, null); + } + } - for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { - for (var group = groups[j], i = 0, n = group.length; i < n; ++i) { - var node = group[i]; - if (node) return node; - } - } + for (; i < each_blocks.length; i += 1) { + each_blocks[i].d(1); + } - return null; + each_blocks.length = each_value_3.length; + } + }, + d(detaching) { + if (if_block) if_block.d(detaching); + if (detaching) detach(t); + if (detaching) detach(ol); + destroy_each(each_blocks, detaching); + } + }; } -function selection_size() { - let size = 0; - for (const node of this) ++size; // eslint-disable-line no-unused-vars - return size; -} +// (25:14) {#if settings.showRelationType} +function create_if_block_4$1(ctx) { + let h5; -function selection_empty() { - return !this.node(); + return { + c() { + h5 = element("h5"); + h5.textContent = "Real"; + attr(h5, "class", "breadcrumbs-header svelte-fwoihq"); + }, + m(target, anchor) { + insert(target, h5, anchor); + }, + d(detaching) { + if (detaching) detach(h5); + } + }; } -function selection_each(callback) { - - for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { - for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) { - if (node = group[i]) callback.call(node, node.__data__, i, group); - } - } - - return this; -} +// (30:16) {#each square.realItems as realItem} +function create_each_block_3$2(ctx) { + let li; + let div; -function attrRemove$1(name) { - return function() { - this.removeAttribute(name); - }; -} + let t0_value = (/*realItem*/ ctx[18].alt + ? /*realItem*/ ctx[18].alt + : /*realItem*/ ctx[18].to.split("/").last()) + ""; -function attrRemoveNS$1(fullname) { - return function() { - this.removeAttributeNS(fullname.space, fullname.local); - }; -} + let t0; + let div_class_value; + let t1; + let mounted; + let dispose; -function attrConstant$1(name, value) { - return function() { - this.setAttribute(name, value); - }; -} + function click_handler(...args) { + return /*click_handler*/ ctx[5](/*realItem*/ ctx[18], ...args); + } -function attrConstantNS$1(fullname, value) { - return function() { - this.setAttributeNS(fullname.space, fullname.local, value); - }; -} + function mouseover_handler(...args) { + return /*mouseover_handler*/ ctx[6](/*realItem*/ ctx[18], ...args); + } -function attrFunction$1(name, value) { - return function() { - var v = value.apply(this, arguments); - if (v == null) this.removeAttribute(name); - else this.setAttribute(name, v); - }; -} + return { + c() { + li = element("li"); + div = element("div"); + t0 = text(t0_value); + t1 = space(); + attr(div, "class", div_class_value = /*realItem*/ ctx[18].cls); + }, + m(target, anchor) { + insert(target, li, anchor); + append(li, div); + append(div, t0); + append(li, t1); -function attrFunctionNS$1(fullname, value) { - return function() { - var v = value.apply(this, arguments); - if (v == null) this.removeAttributeNS(fullname.space, fullname.local); - else this.setAttributeNS(fullname.space, fullname.local, v); - }; -} + if (!mounted) { + dispose = [ + listen(div, "click", click_handler), + listen(div, "mouseover", mouseover_handler) + ]; -function selection_attr(name, value) { - var fullname = namespace(name); + mounted = true; + } + }, + p(new_ctx, dirty) { + ctx = new_ctx; - if (arguments.length < 2) { - var node = this.node(); - return fullname.local - ? node.getAttributeNS(fullname.space, fullname.local) - : node.getAttribute(fullname); - } + if (dirty & /*filteredSquaresArr*/ 1 && t0_value !== (t0_value = (/*realItem*/ ctx[18].alt + ? /*realItem*/ ctx[18].alt + : /*realItem*/ ctx[18].to.split("/").last()) + "")) set_data(t0, t0_value); - return this.each((value == null - ? (fullname.local ? attrRemoveNS$1 : attrRemove$1) : (typeof value === "function" - ? (fullname.local ? attrFunctionNS$1 : attrFunction$1) - : (fullname.local ? attrConstantNS$1 : attrConstant$1)))(fullname, value)); + if (dirty & /*filteredSquaresArr*/ 1 && div_class_value !== (div_class_value = /*realItem*/ ctx[18].cls)) { + attr(div, "class", div_class_value); + } + }, + d(detaching) { + if (detaching) detach(li); + mounted = false; + run_all(dispose); + } + }; } -function defaultView(node) { - return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node - || (node.document && node) // node is a Window - || node.defaultView; // node is a Document -} +// (48:12) {#if square.impliedItems.length} +function create_if_block_1$2(ctx) { + let t; + let ol; + let ol_start_value; + let if_block = /*settings*/ ctx[2].showRelationType && create_if_block_2$2(); + let each_value_2 = /*square*/ ctx[12].impliedItems; + let each_blocks = []; -function styleRemove$1(name) { - return function() { - this.style.removeProperty(name); - }; -} + for (let i = 0; i < each_value_2.length; i += 1) { + each_blocks[i] = create_each_block_2$3(get_each_context_2$3(ctx, each_value_2, i)); + } -function styleConstant$1(name, value, priority) { - return function() { - this.style.setProperty(name, value, priority); - }; -} + return { + c() { + if (if_block) if_block.c(); + t = space(); + ol = element("ol"); -function styleFunction$1(name, value, priority) { - return function() { - var v = value.apply(this, arguments); - if (v == null) this.style.removeProperty(name); - else this.style.setProperty(name, v, priority); - }; -} + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + + attr(ol, "class", "markdown-preview-view svelte-fwoihq"); + attr(ol, "start", ol_start_value = /*square*/ ctx[12].realItems.length + 1); + }, + m(target, anchor) { + if (if_block) if_block.m(target, anchor); + insert(target, t, anchor); + insert(target, ol, anchor); -function selection_style(name, value, priority) { - return arguments.length > 1 - ? this.each((value == null - ? styleRemove$1 : typeof value === "function" - ? styleFunction$1 - : styleConstant$1)(name, value, priority == null ? "" : priority)) - : styleValue(this.node(), name); -} + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(ol, null); + } + }, + p(ctx, dirty) { + if (/*settings*/ ctx[2].showRelationType) { + if (if_block) ; else { + if_block = create_if_block_2$2(); + if_block.c(); + if_block.m(t.parentNode, t); + } + } else if (if_block) { + if_block.d(1); + if_block = null; + } -function styleValue(node, name) { - return node.style.getPropertyValue(name) - || defaultView(node).getComputedStyle(node, null).getPropertyValue(name); -} + if (dirty & /*filteredSquaresArr, openOrSwitch, app, currFile, hoverPreview, matrixView*/ 27) { + each_value_2 = /*square*/ ctx[12].impliedItems; + let i; -function propertyRemove(name) { - return function() { - delete this[name]; - }; -} + for (i = 0; i < each_value_2.length; i += 1) { + const child_ctx = get_each_context_2$3(ctx, each_value_2, i); -function propertyConstant(name, value) { - return function() { - this[name] = value; - }; -} + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + } else { + each_blocks[i] = create_each_block_2$3(child_ctx); + each_blocks[i].c(); + each_blocks[i].m(ol, null); + } + } -function propertyFunction(name, value) { - return function() { - var v = value.apply(this, arguments); - if (v == null) delete this[name]; - else this[name] = v; - }; -} + for (; i < each_blocks.length; i += 1) { + each_blocks[i].d(1); + } -function selection_property(name, value) { - return arguments.length > 1 - ? this.each((value == null - ? propertyRemove : typeof value === "function" - ? propertyFunction - : propertyConstant)(name, value)) - : this.node()[name]; -} + each_blocks.length = each_value_2.length; + } -function classArray(string) { - return string.trim().split(/^|\s+/); + if (dirty & /*filteredSquaresArr*/ 1 && ol_start_value !== (ol_start_value = /*square*/ ctx[12].realItems.length + 1)) { + attr(ol, "start", ol_start_value); + } + }, + d(detaching) { + if (if_block) if_block.d(detaching); + if (detaching) detach(t); + if (detaching) detach(ol); + destroy_each(each_blocks, detaching); + } + }; } -function classList(node) { - return node.classList || new ClassList(node); -} +// (49:14) {#if settings.showRelationType} +function create_if_block_2$2(ctx) { + let h5; -function ClassList(node) { - this._node = node; - this._names = classArray(node.getAttribute("class") || ""); + return { + c() { + h5 = element("h5"); + h5.textContent = "Implied"; + attr(h5, "class", "breadcrumbs-header svelte-fwoihq"); + }, + m(target, anchor) { + insert(target, h5, anchor); + }, + d(detaching) { + if (detaching) detach(h5); + } + }; } -ClassList.prototype = { - add: function(name) { - var i = this._names.indexOf(name); - if (i < 0) { - this._names.push(name); - this._node.setAttribute("class", this._names.join(" ")); - } - }, - remove: function(name) { - var i = this._names.indexOf(name); - if (i >= 0) { - this._names.splice(i, 1); - this._node.setAttribute("class", this._names.join(" ")); - } - }, - contains: function(name) { - return this._names.indexOf(name) >= 0; - } -}; +// (57:16) {#each square.impliedItems as impliedItem} +function create_each_block_2$3(ctx) { + let li; + let div; -function classedAdd(node, names) { - var list = classList(node), i = -1, n = names.length; - while (++i < n) list.add(names[i]); -} + let t_value = (/*impliedItem*/ ctx[15].alt + ? /*impliedItem*/ ctx[15].alt + : /*impliedItem*/ ctx[15].to.split("/").last()) + ""; -function classedRemove(node, names) { - var list = classList(node), i = -1, n = names.length; - while (++i < n) list.remove(names[i]); -} + let t; + let div_class_value; + let mounted; + let dispose; -function classedTrue(names) { - return function() { - classedAdd(this, names); - }; -} + function click_handler_1(...args) { + return /*click_handler_1*/ ctx[7](/*impliedItem*/ ctx[15], ...args); + } -function classedFalse(names) { - return function() { - classedRemove(this, names); - }; -} + function mouseover_handler_1(...args) { + return /*mouseover_handler_1*/ ctx[8](/*impliedItem*/ ctx[15], ...args); + } -function classedFunction(names, value) { - return function() { - (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names); - }; -} + return { + c() { + li = element("li"); + div = element("div"); + t = text(t_value); + attr(div, "class", div_class_value = /*impliedItem*/ ctx[15].cls); + attr(li, "class", "breadcrumbs-implied"); + }, + m(target, anchor) { + insert(target, li, anchor); + append(li, div); + append(div, t); -function selection_classed(name, value) { - var names = classArray(name + ""); + if (!mounted) { + dispose = [ + listen(div, "click", click_handler_1), + listen(div, "mouseover", mouseover_handler_1) + ]; - if (arguments.length < 2) { - var list = classList(this.node()), i = -1, n = names.length; - while (++i < n) if (!list.contains(names[i])) return false; - return true; - } + mounted = true; + } + }, + p(new_ctx, dirty) { + ctx = new_ctx; - return this.each((typeof value === "function" - ? classedFunction : value - ? classedTrue - : classedFalse)(names, value)); -} + if (dirty & /*filteredSquaresArr*/ 1 && t_value !== (t_value = (/*impliedItem*/ ctx[15].alt + ? /*impliedItem*/ ctx[15].alt + : /*impliedItem*/ ctx[15].to.split("/").last()) + "")) set_data(t, t_value); -function textRemove() { - this.textContent = ""; + if (dirty & /*filteredSquaresArr*/ 1 && div_class_value !== (div_class_value = /*impliedItem*/ ctx[15].cls)) { + attr(div, "class", div_class_value); + } + }, + d(detaching) { + if (detaching) detach(li); + mounted = false; + run_all(dispose); + } + }; } -function textConstant$1(value) { - return function() { - this.textContent = value; - }; -} +// (20:6) {#each squares as square} +function create_each_block_1$6(ctx) { + let if_block_anchor; + let if_block = (/*square*/ ctx[12].realItems.length > 0 || /*square*/ ctx[12].impliedItems.length > 0) && create_if_block$4(ctx); -function textFunction$1(value) { - return function() { - var v = value.apply(this, arguments); - this.textContent = v == null ? "" : v; - }; + return { + c() { + if (if_block) if_block.c(); + if_block_anchor = empty$1(); + }, + m(target, anchor) { + if (if_block) if_block.m(target, anchor); + insert(target, if_block_anchor, anchor); + }, + p(ctx, dirty) { + if (/*square*/ ctx[12].realItems.length > 0 || /*square*/ ctx[12].impliedItems.length > 0) { + if (if_block) { + if_block.p(ctx, dirty); + } else { + if_block = create_if_block$4(ctx); + if_block.c(); + if_block.m(if_block_anchor.parentNode, if_block_anchor); + } + } else if (if_block) { + if_block.d(1); + if_block = null; + } + }, + d(detaching) { + if (if_block) if_block.d(detaching); + if (detaching) detach(if_block_anchor); + } + }; } -function selection_text(value) { - return arguments.length - ? this.each(value == null - ? textRemove : (typeof value === "function" - ? textFunction$1 - : textConstant$1)(value)) - : this.node().textContent; -} +// (14:2) {#each filteredSquaresArr as squares} +function create_each_block$6(ctx) { + let details; + let summary; + let t0_value = /*squares*/ ctx[9].map(func).join(", ") + ""; + let t0; + let t1; + let t2; + let each_value_1 = /*squares*/ ctx[9]; + let each_blocks = []; -function htmlRemove() { - this.innerHTML = ""; -} + for (let i = 0; i < each_value_1.length; i += 1) { + each_blocks[i] = create_each_block_1$6(get_each_context_1$6(ctx, each_value_1, i)); + } -function htmlConstant(value) { - return function() { - this.innerHTML = value; - }; -} + return { + c() { + details = element("details"); + summary = element("summary"); + t0 = text(t0_value); + t1 = space(); -function htmlFunction(value) { - return function() { - var v = value.apply(this, arguments); - this.innerHTML = v == null ? "" : v; - }; -} + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } -function selection_html(value) { - return arguments.length - ? this.each(value == null - ? htmlRemove : (typeof value === "function" - ? htmlFunction - : htmlConstant)(value)) - : this.node().innerHTML; -} + t2 = space(); + attr(summary, "class", "hier-summary svelte-fwoihq"); + details.open = true; + }, + m(target, anchor) { + insert(target, details, anchor); + append(details, summary); + append(summary, t0); + append(details, t1); -function raise() { - if (this.nextSibling) this.parentNode.appendChild(this); -} + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(details, null); + } -function selection_raise() { - return this.each(raise); -} + append(details, t2); + }, + p(ctx, dirty) { + if (dirty & /*filteredSquaresArr*/ 1 && t0_value !== (t0_value = /*squares*/ ctx[9].map(func).join(", ") + "")) set_data(t0, t0_value); -function lower() { - if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild); -} + if (dirty & /*filteredSquaresArr, openOrSwitch, app, currFile, hoverPreview, matrixView, settings*/ 31) { + each_value_1 = /*squares*/ ctx[9]; + let i; -function selection_lower() { - return this.each(lower); -} + for (i = 0; i < each_value_1.length; i += 1) { + const child_ctx = get_each_context_1$6(ctx, each_value_1, i); -function selection_append(name) { - var create = typeof name === "function" ? name : creator(name); - return this.select(function() { - return this.appendChild(create.apply(this, arguments)); - }); -} + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + } else { + each_blocks[i] = create_each_block_1$6(child_ctx); + each_blocks[i].c(); + each_blocks[i].m(details, t2); + } + } -function constantNull() { - return null; -} + for (; i < each_blocks.length; i += 1) { + each_blocks[i].d(1); + } -function selection_insert(name, before) { - var create = typeof name === "function" ? name : creator(name), - select = before == null ? constantNull : typeof before === "function" ? before : selector(before); - return this.select(function() { - return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null); - }); + each_blocks.length = each_value_1.length; + } + }, + d(detaching) { + if (detaching) detach(details); + destroy_each(each_blocks, detaching); + } + }; } -function remove() { - var parent = this.parentNode; - if (parent) parent.removeChild(this); -} +function create_fragment$b(ctx) { + let div; + let each_value = /*filteredSquaresArr*/ ctx[0]; + let each_blocks = []; -function selection_remove() { - return this.each(remove); -} + for (let i = 0; i < each_value.length; i += 1) { + each_blocks[i] = create_each_block$6(get_each_context$6(ctx, each_value, i)); + } -function selection_cloneShallow() { - var clone = this.cloneNode(false), parent = this.parentNode; - return parent ? parent.insertBefore(clone, this.nextSibling) : clone; -} + return { + c() { + div = element("div"); -function selection_cloneDeep() { - var clone = this.cloneNode(true), parent = this.parentNode; - return parent ? parent.insertBefore(clone, this.nextSibling) : clone; -} + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } -function selection_clone(deep) { - return this.select(deep ? selection_cloneDeep : selection_cloneShallow); -} + attr(div, "class", "breadcrumbs-list"); + }, + m(target, anchor) { + insert(target, div, anchor); -function selection_datum(value) { - return arguments.length - ? this.property("__data__", value) - : this.node().__data__; -} + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(div, null); + } + }, + p(ctx, [dirty]) { + if (dirty & /*filteredSquaresArr, openOrSwitch, app, currFile, hoverPreview, matrixView, settings*/ 31) { + each_value = /*filteredSquaresArr*/ ctx[0]; + let i; -function contextListener(listener) { - return function(event) { - listener.call(this, event, this.__data__); - }; -} + for (i = 0; i < each_value.length; i += 1) { + const child_ctx = get_each_context$6(ctx, each_value, i); -function parseTypenames(typenames) { - return typenames.trim().split(/^|\s+/).map(function(t) { - var name = "", i = t.indexOf("."); - if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); - return {type: t, name: name}; - }); -} + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + } else { + each_blocks[i] = create_each_block$6(child_ctx); + each_blocks[i].c(); + each_blocks[i].m(div, null); + } + } -function onRemove(typename) { - return function() { - var on = this.__on; - if (!on) return; - for (var j = 0, i = -1, m = on.length, o; j < m; ++j) { - if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) { - this.removeEventListener(o.type, o.listener, o.options); - } else { - on[++i] = o; - } - } - if (++i) on.length = i; - else delete this.__on; - }; -} + for (; i < each_blocks.length; i += 1) { + each_blocks[i].d(1); + } -function onAdd(typename, value, options) { - return function() { - var on = this.__on, o, listener = contextListener(value); - if (on) for (var j = 0, m = on.length; j < m; ++j) { - if ((o = on[j]).type === typename.type && o.name === typename.name) { - this.removeEventListener(o.type, o.listener, o.options); - this.addEventListener(o.type, o.listener = listener, o.options = options); - o.value = value; - return; - } - } - this.addEventListener(typename.type, listener, options); - o = {type: typename.type, name: typename.name, value: value, listener: listener, options: options}; - if (!on) this.__on = [o]; - else on.push(o); - }; + each_blocks.length = each_value.length; + } + }, + i: noop$1, + o: noop$1, + d(detaching) { + if (detaching) detach(div); + destroy_each(each_blocks, detaching); + } + }; } -function selection_on(typename, value, options) { - var typenames = parseTypenames(typename + ""), i, n = typenames.length, t; +const func = square => square.fieldName; - if (arguments.length < 2) { - var on = this.node().__on; - if (on) for (var j = 0, m = on.length, o; j < m; ++j) { - for (i = 0, o = on[j]; i < n; ++i) { - if ((t = typenames[i]).type === o.type && t.name === o.name) { - return o.value; - } - } - } - return; - } +function instance$b($$self, $$props, $$invalidate) { + + + + + let { filteredSquaresArr } = $$props; + let { currFile } = $$props; + let { settings } = $$props; + let { matrixView } = $$props; + let { app } = $$props; + const click_handler = async (realItem, e) => openOrSwitch(app, realItem.to, currFile, e); + const mouseover_handler = (realItem, e) => hoverPreview(e, matrixView, realItem.to); + const click_handler_1 = async (impliedItem, e) => openOrSwitch(app, impliedItem.to, currFile, e); + const mouseover_handler_1 = (impliedItem, e) => hoverPreview(e, matrixView, impliedItem.to); - on = value ? onAdd : onRemove; - for (i = 0; i < n; ++i) this.each(on(typenames[i], value, options)); - return this; -} + $$self.$$set = $$props => { + if ("filteredSquaresArr" in $$props) $$invalidate(0, filteredSquaresArr = $$props.filteredSquaresArr); + if ("currFile" in $$props) $$invalidate(1, currFile = $$props.currFile); + if ("settings" in $$props) $$invalidate(2, settings = $$props.settings); + if ("matrixView" in $$props) $$invalidate(3, matrixView = $$props.matrixView); + if ("app" in $$props) $$invalidate(4, app = $$props.app); + }; -function dispatchEvent(node, type, params) { - var window = defaultView(node), - event = window.CustomEvent; + return [ + filteredSquaresArr, + currFile, + settings, + matrixView, + app, + click_handler, + mouseover_handler, + click_handler_1, + mouseover_handler_1 + ]; +} - if (typeof event === "function") { - event = new event(type, params); - } else { - event = window.document.createEvent("Event"); - if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail; - else event.initEvent(type, false, false); - } +class Lists extends SvelteComponent { + constructor(options) { + super(); + if (!document.getElementById("svelte-fwoihq-style")) add_css$6(); - node.dispatchEvent(event); + init$1(this, options, instance$b, create_fragment$b, safe_not_equal, { + filteredSquaresArr: 0, + currFile: 1, + settings: 2, + matrixView: 3, + app: 4 + }); + } } -function dispatchConstant(type, params) { - return function() { - return dispatchEvent(this, type, params); - }; -} +/* src\Components\Matrix.svelte generated by Svelte v3.35.0 */ -function dispatchFunction(type, params) { - return function() { - return dispatchEvent(this, type, params.apply(this, arguments)); - }; +function add_css$5() { + var style = element("style"); + style.id = "svelte-fq6v4k-style"; + style.textContent = "div.breadcrumbs-matrix.svelte-fq6v4k.svelte-fq6v4k{padding:5px}div.breadcrumbs-matrix.svelte-fq6v4k>div.svelte-fq6v4k{border:3px solid var(--background-modifier-border);border-radius:3px;text-align:center;margin:3px;position:relative;height:fit-content}div.breadcrumbs-matrix-square.svelte-fq6v4k.svelte-fq6v4k{border:1px solid var(--background-modifier-border)}.breadcrumbs-matrix-header.svelte-fq6v4k.svelte-fq6v4k{margin:2px}h3.breadcrumbs-matrix-header.svelte-fq6v4k.svelte-fq6v4k{color:var(--text-title-h3)}h5.breadcrumbs-matrix-header.svelte-fq6v4k.svelte-fq6v4k{color:var(--text-title-h5)}ol.svelte-fq6v4k.svelte-fq6v4k{margin:3px;padding-left:20px}"; + append(document.head, style); } -function selection_dispatch(type, params) { - return this.each((typeof params === "function" - ? dispatchFunction - : dispatchConstant)(type, params)); +function get_each_context$5(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[9] = list[i]; + return child_ctx; } -function* selection_iterator() { - for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { - for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) { - if (node = group[i]) yield node; - } - } +function get_each_context_1$5(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[12] = list[i]; + return child_ctx; } -var root$1 = [null]; - -function Selection$1(groups, parents) { - this._groups = groups; - this._parents = parents; +function get_each_context_2$2(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[15] = list[i]; + return child_ctx; } -function selection() { - return new Selection$1([[document.documentElement]], root$1); +function get_each_context_3$1(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[18] = list[i]; + return child_ctx; } -function selection_selection() { - return this; -} +// (17:8) {#if square.realItems.length > 0 || square.impliedItems.length > 0} +function create_if_block$3(ctx) { + let div; + let h3; + let t0_value = /*square*/ ctx[12].fieldName + ""; + let t0; + let t1; + let t2; + let if_block0 = /*square*/ ctx[12].realItems.length && create_if_block_3(ctx); + let if_block1 = /*square*/ ctx[12].impliedItems.length && create_if_block_1$1(ctx); -Selection$1.prototype = selection.prototype = { - constructor: Selection$1, - select: selection_select, - selectAll: selection_selectAll, - selectChild: selection_selectChild, - selectChildren: selection_selectChildren, - filter: selection_filter, - data: selection_data, - enter: selection_enter, - exit: selection_exit, - join: selection_join, - merge: selection_merge, - selection: selection_selection, - order: selection_order, - sort: selection_sort, - call: selection_call, - nodes: selection_nodes, - node: selection_node, - size: selection_size, - empty: selection_empty, - each: selection_each, - attr: selection_attr, - style: selection_style, - property: selection_property, - classed: selection_classed, - text: selection_text, - html: selection_html, - raise: selection_raise, - lower: selection_lower, - append: selection_append, - insert: selection_insert, - remove: selection_remove, - clone: selection_clone, - datum: selection_datum, - on: selection_on, - dispatch: selection_dispatch, - [Symbol.iterator]: selection_iterator -}; + return { + c() { + div = element("div"); + h3 = element("h3"); + t0 = text(t0_value); + t1 = space(); + if (if_block0) if_block0.c(); + t2 = space(); + if (if_block1) if_block1.c(); + attr(h3, "class", "breadcrumbs-matrix-header svelte-fq6v4k"); + attr(div, "class", "breadcrumbs-matrix-square svelte-fq6v4k"); + }, + m(target, anchor) { + insert(target, div, anchor); + append(div, h3); + append(h3, t0); + append(div, t1); + if (if_block0) if_block0.m(div, null); + append(div, t2); + if (if_block1) if_block1.m(div, null); + }, + p(ctx, dirty) { + if (dirty & /*filteredSquaresArr*/ 1 && t0_value !== (t0_value = /*square*/ ctx[12].fieldName + "")) set_data(t0, t0_value); -function select(selector) { - return typeof selector === "string" - ? new Selection$1([[document.querySelector(selector)]], [document.documentElement]) - : new Selection$1([[selector]], root$1); -} + if (/*square*/ ctx[12].realItems.length) { + if (if_block0) { + if_block0.p(ctx, dirty); + } else { + if_block0 = create_if_block_3(ctx); + if_block0.c(); + if_block0.m(div, t2); + } + } else if (if_block0) { + if_block0.d(1); + if_block0 = null; + } -function sourceEvent(event) { - let sourceEvent; - while (sourceEvent = event.sourceEvent) event = sourceEvent; - return event; + if (/*square*/ ctx[12].impliedItems.length) { + if (if_block1) { + if_block1.p(ctx, dirty); + } else { + if_block1 = create_if_block_1$1(ctx); + if_block1.c(); + if_block1.m(div, null); + } + } else if (if_block1) { + if_block1.d(1); + if_block1 = null; + } + }, + d(detaching) { + if (detaching) detach(div); + if (if_block0) if_block0.d(); + if (if_block1) if_block1.d(); + } + }; } -function pointer(event, node) { - event = sourceEvent(event); - if (node === undefined) node = event.currentTarget; - if (node) { - var svg = node.ownerSVGElement || node; - if (svg.createSVGPoint) { - var point = svg.createSVGPoint(); - point.x = event.clientX, point.y = event.clientY; - point = point.matrixTransform(node.getScreenCTM().inverse()); - return [point.x, point.y]; - } - if (node.getBoundingClientRect) { - var rect = node.getBoundingClientRect(); - return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop]; - } - } - return [event.pageX, event.pageY]; -} +// (21:12) {#if square.realItems.length} +function create_if_block_3(ctx) { + let t; + let ol; + let if_block = /*settings*/ ctx[2].showRelationType && create_if_block_4(); + let each_value_3 = /*square*/ ctx[12].realItems; + let each_blocks = []; -function nopropagation$1(event) { - event.stopImmediatePropagation(); -} + for (let i = 0; i < each_value_3.length; i += 1) { + each_blocks[i] = create_each_block_3$1(get_each_context_3$1(ctx, each_value_3, i)); + } -function noevent$1(event) { - event.preventDefault(); - event.stopImmediatePropagation(); -} + return { + c() { + if (if_block) if_block.c(); + t = space(); + ol = element("ol"); -function dragDisable(view) { - var root = view.document.documentElement, - selection = select(view).on("dragstart.drag", noevent$1, true); - if ("onselectstart" in root) { - selection.on("selectstart.drag", noevent$1, true); - } else { - root.__noselect = root.style.MozUserSelect; - root.style.MozUserSelect = "none"; - } -} + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } -function yesdrag(view, noclick) { - var root = view.document.documentElement, - selection = select(view).on("dragstart.drag", null); - if (noclick) { - selection.on("click.drag", noevent$1, true); - setTimeout(function() { selection.on("click.drag", null); }, 0); - } - if ("onselectstart" in root) { - selection.on("selectstart.drag", null); - } else { - root.style.MozUserSelect = root.__noselect; - delete root.__noselect; - } -} + attr(ol, "class", "svelte-fq6v4k"); + }, + m(target, anchor) { + if (if_block) if_block.m(target, anchor); + insert(target, t, anchor); + insert(target, ol, anchor); -var constant$6 = x => () => x; + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(ol, null); + } + }, + p(ctx, dirty) { + if (/*settings*/ ctx[2].showRelationType) { + if (if_block) ; else { + if_block = create_if_block_4(); + if_block.c(); + if_block.m(t.parentNode, t); + } + } else if (if_block) { + if_block.d(1); + if_block = null; + } -function DragEvent(type, { - sourceEvent, - subject, - target, - identifier, - active, - x, y, dx, dy, - dispatch -}) { - Object.defineProperties(this, { - type: {value: type, enumerable: true, configurable: true}, - sourceEvent: {value: sourceEvent, enumerable: true, configurable: true}, - subject: {value: subject, enumerable: true, configurable: true}, - target: {value: target, enumerable: true, configurable: true}, - identifier: {value: identifier, enumerable: true, configurable: true}, - active: {value: active, enumerable: true, configurable: true}, - x: {value: x, enumerable: true, configurable: true}, - y: {value: y, enumerable: true, configurable: true}, - dx: {value: dx, enumerable: true, configurable: true}, - dy: {value: dy, enumerable: true, configurable: true}, - _: {value: dispatch} - }); -} + if (dirty & /*filteredSquaresArr, openOrSwitch, app, currFile, hoverPreview, matrixView*/ 27) { + each_value_3 = /*square*/ ctx[12].realItems; + let i; -DragEvent.prototype.on = function() { - var value = this._.on.apply(this._, arguments); - return value === this._ ? this : value; -}; + for (i = 0; i < each_value_3.length; i += 1) { + const child_ctx = get_each_context_3$1(ctx, each_value_3, i); -// Ignore right-click, since that should open the context menu. -function defaultFilter$1(event) { - return !event.ctrlKey && !event.button; -} + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + } else { + each_blocks[i] = create_each_block_3$1(child_ctx); + each_blocks[i].c(); + each_blocks[i].m(ol, null); + } + } -function defaultContainer() { - return this.parentNode; -} + for (; i < each_blocks.length; i += 1) { + each_blocks[i].d(1); + } -function defaultSubject(event, d) { - return d == null ? {x: event.x, y: event.y} : d; + each_blocks.length = each_value_3.length; + } + }, + d(detaching) { + if (if_block) if_block.d(detaching); + if (detaching) detach(t); + if (detaching) detach(ol); + destroy_each(each_blocks, detaching); + } + }; } -function defaultTouchable$1() { - return navigator.maxTouchPoints || ("ontouchstart" in this); -} +// (22:14) {#if settings.showRelationType} +function create_if_block_4(ctx) { + let h5; -function drag() { - var filter = defaultFilter$1, - container = defaultContainer, - subject = defaultSubject, - touchable = defaultTouchable$1, - gestures = {}, - listeners = dispatch("start", "drag", "end"), - active = 0, - mousedownx, - mousedowny, - mousemoving, - touchending, - clickDistance2 = 0; + return { + c() { + h5 = element("h5"); + h5.textContent = "Real"; + attr(h5, "class", "breadcrumbs-matrix-header svelte-fq6v4k"); + }, + m(target, anchor) { + insert(target, h5, anchor); + }, + d(detaching) { + if (detaching) detach(h5); + } + }; +} - function drag(selection) { - selection - .on("mousedown.drag", mousedowned) - .filter(touchable) - .on("touchstart.drag", touchstarted) - .on("touchmove.drag", touchmoved) - .on("touchend.drag touchcancel.drag", touchended) - .style("touch-action", "none") - .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)"); - } +// (26:16) {#each square.realItems as realItem} +function create_each_block_3$1(ctx) { + let li; + let div; - function mousedowned(event, d) { - if (touchending || !filter.call(this, event, d)) return; - var gesture = beforestart(this, container.call(this, event, d), event, d, "mouse"); - if (!gesture) return; - select(event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true); - dragDisable(event.view); - nopropagation$1(event); - mousemoving = false; - mousedownx = event.clientX; - mousedowny = event.clientY; - gesture("start", event); - } + let t0_value = (/*realItem*/ ctx[18].alt + ? /*realItem*/ ctx[18].alt + : /*realItem*/ ctx[18].to.split("/").last()) + ""; - function mousemoved(event) { - noevent$1(event); - if (!mousemoving) { - var dx = event.clientX - mousedownx, dy = event.clientY - mousedowny; - mousemoving = dx * dx + dy * dy > clickDistance2; - } - gestures.mouse("drag", event); - } + let t0; + let div_class_value; + let t1; + let mounted; + let dispose; - function mouseupped(event) { - select(event.view).on("mousemove.drag mouseup.drag", null); - yesdrag(event.view, mousemoving); - noevent$1(event); - gestures.mouse("end", event); - } + function click_handler(...args) { + return /*click_handler*/ ctx[5](/*realItem*/ ctx[18], ...args); + } - function touchstarted(event, d) { - if (!filter.call(this, event, d)) return; - var touches = event.changedTouches, - c = container.call(this, event, d), - n = touches.length, i, gesture; + function mouseover_handler(...args) { + return /*mouseover_handler*/ ctx[6](/*realItem*/ ctx[18], ...args); + } - for (i = 0; i < n; ++i) { - if (gesture = beforestart(this, c, event, d, touches[i].identifier, touches[i])) { - nopropagation$1(event); - gesture("start", event, touches[i]); - } - } - } + return { + c() { + li = element("li"); + div = element("div"); + t0 = text(t0_value); + t1 = space(); + attr(div, "class", div_class_value = "" + (null_to_empty(/*realItem*/ ctx[18].cls) + " svelte-fq6v4k")); + }, + m(target, anchor) { + insert(target, li, anchor); + append(li, div); + append(div, t0); + append(li, t1); - function touchmoved(event) { - var touches = event.changedTouches, - n = touches.length, i, gesture; + if (!mounted) { + dispose = [ + listen(div, "click", click_handler), + listen(div, "mouseover", mouseover_handler) + ]; - for (i = 0; i < n; ++i) { - if (gesture = gestures[touches[i].identifier]) { - noevent$1(event); - gesture("drag", event, touches[i]); - } - } - } + mounted = true; + } + }, + p(new_ctx, dirty) { + ctx = new_ctx; - function touchended(event) { - var touches = event.changedTouches, - n = touches.length, i, gesture; + if (dirty & /*filteredSquaresArr*/ 1 && t0_value !== (t0_value = (/*realItem*/ ctx[18].alt + ? /*realItem*/ ctx[18].alt + : /*realItem*/ ctx[18].to.split("/").last()) + "")) set_data(t0, t0_value); - if (touchending) clearTimeout(touchending); - touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed! - for (i = 0; i < n; ++i) { - if (gesture = gestures[touches[i].identifier]) { - nopropagation$1(event); - gesture("end", event, touches[i]); - } - } - } + if (dirty & /*filteredSquaresArr*/ 1 && div_class_value !== (div_class_value = "" + (null_to_empty(/*realItem*/ ctx[18].cls) + " svelte-fq6v4k"))) { + attr(div, "class", div_class_value); + } + }, + d(detaching) { + if (detaching) detach(li); + mounted = false; + run_all(dispose); + } + }; +} - function beforestart(that, container, event, d, identifier, touch) { - var dispatch = listeners.copy(), - p = pointer(touch || event, container), dx, dy, - s; +// (44:12) {#if square.impliedItems.length} +function create_if_block_1$1(ctx) { + let t; + let ol; + let ol_start_value; + let if_block = /*settings*/ ctx[2].showRelationType && create_if_block_2$1(); + let each_value_2 = /*square*/ ctx[12].impliedItems; + let each_blocks = []; - if ((s = subject.call(that, new DragEvent("beforestart", { - sourceEvent: event, - target: drag, - identifier, - active, - x: p[0], - y: p[1], - dx: 0, - dy: 0, - dispatch - }), d)) == null) return; + for (let i = 0; i < each_value_2.length; i += 1) { + each_blocks[i] = create_each_block_2$2(get_each_context_2$2(ctx, each_value_2, i)); + } - dx = s.x - p[0] || 0; - dy = s.y - p[1] || 0; + return { + c() { + if (if_block) if_block.c(); + t = space(); + ol = element("ol"); - return function gesture(type, event, touch) { - var p0 = p, n; - switch (type) { - case "start": gestures[identifier] = gesture, n = active++; break; - case "end": delete gestures[identifier], --active; // nobreak - case "drag": p = pointer(touch || event, container), n = active; break; - } - dispatch.call( - type, - that, - new DragEvent(type, { - sourceEvent: event, - subject: s, - target: drag, - identifier, - active: n, - x: p[0] + dx, - y: p[1] + dy, - dx: p[0] - p0[0], - dy: p[1] - p0[1], - dispatch - }), - d - ); - }; - } + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } - drag.filter = function(_) { - return arguments.length ? (filter = typeof _ === "function" ? _ : constant$6(!!_), drag) : filter; - }; + attr(ol, "start", ol_start_value = /*square*/ ctx[12].realItems.length + 1); + attr(ol, "class", "svelte-fq6v4k"); + }, + m(target, anchor) { + if (if_block) if_block.m(target, anchor); + insert(target, t, anchor); + insert(target, ol, anchor); - drag.container = function(_) { - return arguments.length ? (container = typeof _ === "function" ? _ : constant$6(_), drag) : container; - }; + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(ol, null); + } + }, + p(ctx, dirty) { + if (/*settings*/ ctx[2].showRelationType) { + if (if_block) ; else { + if_block = create_if_block_2$1(); + if_block.c(); + if_block.m(t.parentNode, t); + } + } else if (if_block) { + if_block.d(1); + if_block = null; + } - drag.subject = function(_) { - return arguments.length ? (subject = typeof _ === "function" ? _ : constant$6(_), drag) : subject; - }; + if (dirty & /*filteredSquaresArr, openOrSwitch, app, currFile, hoverPreview, matrixView*/ 27) { + each_value_2 = /*square*/ ctx[12].impliedItems; + let i; - drag.touchable = function(_) { - return arguments.length ? (touchable = typeof _ === "function" ? _ : constant$6(!!_), drag) : touchable; - }; + for (i = 0; i < each_value_2.length; i += 1) { + const child_ctx = get_each_context_2$2(ctx, each_value_2, i); - drag.on = function() { - var value = listeners.on.apply(listeners, arguments); - return value === listeners ? drag : value; - }; + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + } else { + each_blocks[i] = create_each_block_2$2(child_ctx); + each_blocks[i].c(); + each_blocks[i].m(ol, null); + } + } - drag.clickDistance = function(_) { - return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2); - }; + for (; i < each_blocks.length; i += 1) { + each_blocks[i].d(1); + } - return drag; -} + each_blocks.length = each_value_2.length; + } -function define(constructor, factory, prototype) { - constructor.prototype = factory.prototype = prototype; - prototype.constructor = constructor; + if (dirty & /*filteredSquaresArr*/ 1 && ol_start_value !== (ol_start_value = /*square*/ ctx[12].realItems.length + 1)) { + attr(ol, "start", ol_start_value); + } + }, + d(detaching) { + if (if_block) if_block.d(detaching); + if (detaching) detach(t); + if (detaching) detach(ol); + destroy_each(each_blocks, detaching); + } + }; } -function extend(parent, definition) { - var prototype = Object.create(parent.prototype); - for (var key in definition) prototype[key] = definition[key]; - return prototype; +// (45:14) {#if settings.showRelationType} +function create_if_block_2$1(ctx) { + let h5; + + return { + c() { + h5 = element("h5"); + h5.textContent = "Implied"; + attr(h5, "class", "breadcrumbs-matrix-header svelte-fq6v4k"); + }, + m(target, anchor) { + insert(target, h5, anchor); + }, + d(detaching) { + if (detaching) detach(h5); + } + }; } -function Color() {} +// (49:16) {#each square.impliedItems as impliedItem} +function create_each_block_2$2(ctx) { + let li; + let div; -var darker = 0.7; -var brighter = 1 / darker; + let t_value = (/*impliedItem*/ ctx[15].alt + ? /*impliedItem*/ ctx[15].alt + : /*impliedItem*/ ctx[15].to.split("/").last()) + ""; -var reI = "\\s*([+-]?\\d+)\\s*", - reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*", - reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*", - reHex = /^#([0-9a-f]{3,8})$/, - reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$"), - reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$"), - reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$"), - reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$"), - reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$"), - reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$"); + let t; + let div_class_value; + let mounted; + let dispose; -var named = { - aliceblue: 0xf0f8ff, - antiquewhite: 0xfaebd7, - aqua: 0x00ffff, - aquamarine: 0x7fffd4, - azure: 0xf0ffff, - beige: 0xf5f5dc, - bisque: 0xffe4c4, - black: 0x000000, - blanchedalmond: 0xffebcd, - blue: 0x0000ff, - blueviolet: 0x8a2be2, - brown: 0xa52a2a, - burlywood: 0xdeb887, - cadetblue: 0x5f9ea0, - chartreuse: 0x7fff00, - chocolate: 0xd2691e, - coral: 0xff7f50, - cornflowerblue: 0x6495ed, - cornsilk: 0xfff8dc, - crimson: 0xdc143c, - cyan: 0x00ffff, - darkblue: 0x00008b, - darkcyan: 0x008b8b, - darkgoldenrod: 0xb8860b, - darkgray: 0xa9a9a9, - darkgreen: 0x006400, - darkgrey: 0xa9a9a9, - darkkhaki: 0xbdb76b, - darkmagenta: 0x8b008b, - darkolivegreen: 0x556b2f, - darkorange: 0xff8c00, - darkorchid: 0x9932cc, - darkred: 0x8b0000, - darksalmon: 0xe9967a, - darkseagreen: 0x8fbc8f, - darkslateblue: 0x483d8b, - darkslategray: 0x2f4f4f, - darkslategrey: 0x2f4f4f, - darkturquoise: 0x00ced1, - darkviolet: 0x9400d3, - deeppink: 0xff1493, - deepskyblue: 0x00bfff, - dimgray: 0x696969, - dimgrey: 0x696969, - dodgerblue: 0x1e90ff, - firebrick: 0xb22222, - floralwhite: 0xfffaf0, - forestgreen: 0x228b22, - fuchsia: 0xff00ff, - gainsboro: 0xdcdcdc, - ghostwhite: 0xf8f8ff, - gold: 0xffd700, - goldenrod: 0xdaa520, - gray: 0x808080, - green: 0x008000, - greenyellow: 0xadff2f, - grey: 0x808080, - honeydew: 0xf0fff0, - hotpink: 0xff69b4, - indianred: 0xcd5c5c, - indigo: 0x4b0082, - ivory: 0xfffff0, - khaki: 0xf0e68c, - lavender: 0xe6e6fa, - lavenderblush: 0xfff0f5, - lawngreen: 0x7cfc00, - lemonchiffon: 0xfffacd, - lightblue: 0xadd8e6, - lightcoral: 0xf08080, - lightcyan: 0xe0ffff, - lightgoldenrodyellow: 0xfafad2, - lightgray: 0xd3d3d3, - lightgreen: 0x90ee90, - lightgrey: 0xd3d3d3, - lightpink: 0xffb6c1, - lightsalmon: 0xffa07a, - lightseagreen: 0x20b2aa, - lightskyblue: 0x87cefa, - lightslategray: 0x778899, - lightslategrey: 0x778899, - lightsteelblue: 0xb0c4de, - lightyellow: 0xffffe0, - lime: 0x00ff00, - limegreen: 0x32cd32, - linen: 0xfaf0e6, - magenta: 0xff00ff, - maroon: 0x800000, - mediumaquamarine: 0x66cdaa, - mediumblue: 0x0000cd, - mediumorchid: 0xba55d3, - mediumpurple: 0x9370db, - mediumseagreen: 0x3cb371, - mediumslateblue: 0x7b68ee, - mediumspringgreen: 0x00fa9a, - mediumturquoise: 0x48d1cc, - mediumvioletred: 0xc71585, - midnightblue: 0x191970, - mintcream: 0xf5fffa, - mistyrose: 0xffe4e1, - moccasin: 0xffe4b5, - navajowhite: 0xffdead, - navy: 0x000080, - oldlace: 0xfdf5e6, - olive: 0x808000, - olivedrab: 0x6b8e23, - orange: 0xffa500, - orangered: 0xff4500, - orchid: 0xda70d6, - palegoldenrod: 0xeee8aa, - palegreen: 0x98fb98, - paleturquoise: 0xafeeee, - palevioletred: 0xdb7093, - papayawhip: 0xffefd5, - peachpuff: 0xffdab9, - peru: 0xcd853f, - pink: 0xffc0cb, - plum: 0xdda0dd, - powderblue: 0xb0e0e6, - purple: 0x800080, - rebeccapurple: 0x663399, - red: 0xff0000, - rosybrown: 0xbc8f8f, - royalblue: 0x4169e1, - saddlebrown: 0x8b4513, - salmon: 0xfa8072, - sandybrown: 0xf4a460, - seagreen: 0x2e8b57, - seashell: 0xfff5ee, - sienna: 0xa0522d, - silver: 0xc0c0c0, - skyblue: 0x87ceeb, - slateblue: 0x6a5acd, - slategray: 0x708090, - slategrey: 0x708090, - snow: 0xfffafa, - springgreen: 0x00ff7f, - steelblue: 0x4682b4, - tan: 0xd2b48c, - teal: 0x008080, - thistle: 0xd8bfd8, - tomato: 0xff6347, - turquoise: 0x40e0d0, - violet: 0xee82ee, - wheat: 0xf5deb3, - white: 0xffffff, - whitesmoke: 0xf5f5f5, - yellow: 0xffff00, - yellowgreen: 0x9acd32 -}; + function click_handler_1(...args) { + return /*click_handler_1*/ ctx[7](/*impliedItem*/ ctx[15], ...args); + } -define(Color, color, { - copy: function(channels) { - return Object.assign(new this.constructor, this, channels); - }, - displayable: function() { - return this.rgb().displayable(); - }, - hex: color_formatHex, // Deprecated! Use color.formatHex. - formatHex: color_formatHex, - formatHsl: color_formatHsl, - formatRgb: color_formatRgb, - toString: color_formatRgb -}); + function mouseover_handler_1(...args) { + return /*mouseover_handler_1*/ ctx[8](/*impliedItem*/ ctx[15], ...args); + } -function color_formatHex() { - return this.rgb().formatHex(); -} + return { + c() { + li = element("li"); + div = element("div"); + t = text(t_value); + attr(div, "class", div_class_value = "" + (null_to_empty(/*impliedItem*/ ctx[15].cls) + " svelte-fq6v4k")); + attr(li, "class", "breadcrumbs-implied"); + }, + m(target, anchor) { + insert(target, li, anchor); + append(li, div); + append(div, t); -function color_formatHsl() { - return hslConvert(this).formatHsl(); -} + if (!mounted) { + dispose = [ + listen(div, "click", click_handler_1), + listen(div, "mouseover", mouseover_handler_1) + ]; -function color_formatRgb() { - return this.rgb().formatRgb(); -} + mounted = true; + } + }, + p(new_ctx, dirty) { + ctx = new_ctx; -function color(format) { - var m, l; - format = (format + "").trim().toLowerCase(); - return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) // #ff0000 - : l === 3 ? new Rgb((m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1) // #f00 - : l === 8 ? rgba(m >> 24 & 0xff, m >> 16 & 0xff, m >> 8 & 0xff, (m & 0xff) / 0xff) // #ff000000 - : l === 4 ? rgba((m >> 12 & 0xf) | (m >> 8 & 0xf0), (m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), (((m & 0xf) << 4) | (m & 0xf)) / 0xff) // #f000 - : null) // invalid hex - : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0) - : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%) - : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1) - : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1) - : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%) - : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1) - : named.hasOwnProperty(format) ? rgbn(named[format]) // eslint-disable-line no-prototype-builtins - : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) - : null; -} + if (dirty & /*filteredSquaresArr*/ 1 && t_value !== (t_value = (/*impliedItem*/ ctx[15].alt + ? /*impliedItem*/ ctx[15].alt + : /*impliedItem*/ ctx[15].to.split("/").last()) + "")) set_data(t, t_value); -function rgbn(n) { - return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1); + if (dirty & /*filteredSquaresArr*/ 1 && div_class_value !== (div_class_value = "" + (null_to_empty(/*impliedItem*/ ctx[15].cls) + " svelte-fq6v4k"))) { + attr(div, "class", div_class_value); + } + }, + d(detaching) { + if (detaching) detach(li); + mounted = false; + run_all(dispose); + } + }; } -function rgba(r, g, b, a) { - if (a <= 0) r = g = b = NaN; - return new Rgb(r, g, b, a); -} +// (16:6) {#each squares as square} +function create_each_block_1$5(ctx) { + let if_block_anchor; + let if_block = (/*square*/ ctx[12].realItems.length > 0 || /*square*/ ctx[12].impliedItems.length > 0) && create_if_block$3(ctx); -function rgbConvert(o) { - if (!(o instanceof Color)) o = color(o); - if (!o) return new Rgb; - o = o.rgb(); - return new Rgb(o.r, o.g, o.b, o.opacity); + return { + c() { + if (if_block) if_block.c(); + if_block_anchor = empty$1(); + }, + m(target, anchor) { + if (if_block) if_block.m(target, anchor); + insert(target, if_block_anchor, anchor); + }, + p(ctx, dirty) { + if (/*square*/ ctx[12].realItems.length > 0 || /*square*/ ctx[12].impliedItems.length > 0) { + if (if_block) { + if_block.p(ctx, dirty); + } else { + if_block = create_if_block$3(ctx); + if_block.c(); + if_block.m(if_block_anchor.parentNode, if_block_anchor); + } + } else if (if_block) { + if_block.d(1); + if_block = null; + } + }, + d(detaching) { + if (if_block) if_block.d(detaching); + if (detaching) detach(if_block_anchor); + } + }; } -function rgb(r, g, b, opacity) { - return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity); -} +// (14:2) {#each filteredSquaresArr as squares} +function create_each_block$5(ctx) { + let div; + let t; + let each_value_1 = /*squares*/ ctx[9]; + let each_blocks = []; -function Rgb(r, g, b, opacity) { - this.r = +r; - this.g = +g; - this.b = +b; - this.opacity = +opacity; -} + for (let i = 0; i < each_value_1.length; i += 1) { + each_blocks[i] = create_each_block_1$5(get_each_context_1$5(ctx, each_value_1, i)); + } -define(Rgb, rgb, extend(Color, { - brighter: function(k) { - k = k == null ? brighter : Math.pow(brighter, k); - return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); - }, - darker: function(k) { - k = k == null ? darker : Math.pow(darker, k); - return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); - }, - rgb: function() { - return this; - }, - displayable: function() { - return (-0.5 <= this.r && this.r < 255.5) - && (-0.5 <= this.g && this.g < 255.5) - && (-0.5 <= this.b && this.b < 255.5) - && (0 <= this.opacity && this.opacity <= 1); - }, - hex: rgb_formatHex, // Deprecated! Use color.formatHex. - formatHex: rgb_formatHex, - formatRgb: rgb_formatRgb, - toString: rgb_formatRgb -})); + return { + c() { + div = element("div"); -function rgb_formatHex() { - return "#" + hex(this.r) + hex(this.g) + hex(this.b); -} + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } -function rgb_formatRgb() { - var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a)); - return (a === 1 ? "rgb(" : "rgba(") - + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", " - + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", " - + Math.max(0, Math.min(255, Math.round(this.b) || 0)) - + (a === 1 ? ")" : ", " + a + ")"); -} + t = space(); + attr(div, "class", "svelte-fq6v4k"); + }, + m(target, anchor) { + insert(target, div, anchor); -function hex(value) { - value = Math.max(0, Math.min(255, Math.round(value) || 0)); - return (value < 16 ? "0" : "") + value.toString(16); -} + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(div, null); + } + + append(div, t); + }, + p(ctx, dirty) { + if (dirty & /*filteredSquaresArr, openOrSwitch, app, currFile, hoverPreview, matrixView, settings*/ 31) { + each_value_1 = /*squares*/ ctx[9]; + let i; -function hsla(h, s, l, a) { - if (a <= 0) h = s = l = NaN; - else if (l <= 0 || l >= 1) h = s = NaN; - else if (s <= 0) h = NaN; - return new Hsl(h, s, l, a); -} + for (i = 0; i < each_value_1.length; i += 1) { + const child_ctx = get_each_context_1$5(ctx, each_value_1, i); -function hslConvert(o) { - if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity); - if (!(o instanceof Color)) o = color(o); - if (!o) return new Hsl; - if (o instanceof Hsl) return o; - o = o.rgb(); - var r = o.r / 255, - g = o.g / 255, - b = o.b / 255, - min = Math.min(r, g, b), - max = Math.max(r, g, b), - h = NaN, - s = max - min, - l = (max + min) / 2; - if (s) { - if (r === max) h = (g - b) / s + (g < b) * 6; - else if (g === max) h = (b - r) / s + 2; - else h = (r - g) / s + 4; - s /= l < 0.5 ? max + min : 2 - max - min; - h *= 60; - } else { - s = l > 0 && l < 1 ? 0 : h; - } - return new Hsl(h, s, l, o.opacity); -} + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + } else { + each_blocks[i] = create_each_block_1$5(child_ctx); + each_blocks[i].c(); + each_blocks[i].m(div, t); + } + } -function hsl(h, s, l, opacity) { - return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity); -} + for (; i < each_blocks.length; i += 1) { + each_blocks[i].d(1); + } -function Hsl(h, s, l, opacity) { - this.h = +h; - this.s = +s; - this.l = +l; - this.opacity = +opacity; + each_blocks.length = each_value_1.length; + } + }, + d(detaching) { + if (detaching) detach(div); + destroy_each(each_blocks, detaching); + } + }; } -define(Hsl, hsl, extend(Color, { - brighter: function(k) { - k = k == null ? brighter : Math.pow(brighter, k); - return new Hsl(this.h, this.s, this.l * k, this.opacity); - }, - darker: function(k) { - k = k == null ? darker : Math.pow(darker, k); - return new Hsl(this.h, this.s, this.l * k, this.opacity); - }, - rgb: function() { - var h = this.h % 360 + (this.h < 0) * 360, - s = isNaN(h) || isNaN(this.s) ? 0 : this.s, - l = this.l, - m2 = l + (l < 0.5 ? l : 1 - l) * s, - m1 = 2 * l - m2; - return new Rgb( - hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2), - hsl2rgb(h, m1, m2), - hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2), - this.opacity - ); - }, - displayable: function() { - return (0 <= this.s && this.s <= 1 || isNaN(this.s)) - && (0 <= this.l && this.l <= 1) - && (0 <= this.opacity && this.opacity <= 1); - }, - formatHsl: function() { - var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a)); - return (a === 1 ? "hsl(" : "hsla(") - + (this.h || 0) + ", " - + (this.s || 0) * 100 + "%, " - + (this.l || 0) * 100 + "%" - + (a === 1 ? ")" : ", " + a + ")"); - } -})); +function create_fragment$a(ctx) { + let div; + let each_value = /*filteredSquaresArr*/ ctx[0]; + let each_blocks = []; -/* From FvD 13.37, CSS Color Module Level 3 */ -function hsl2rgb(h, m1, m2) { - return (h < 60 ? m1 + (m2 - m1) * h / 60 - : h < 180 ? m2 - : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60 - : m1) * 255; -} + for (let i = 0; i < each_value.length; i += 1) { + each_blocks[i] = create_each_block$5(get_each_context$5(ctx, each_value, i)); + } -const radians = Math.PI / 180; -const degrees$1 = 180 / Math.PI; + return { + c() { + div = element("div"); -var A = -0.14861, - B = +1.78277, - C = -0.29227, - D = -0.90649, - E = +1.97294, - ED = E * D, - EB = E * B, - BC_DA = B * C - D * A; + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } -function cubehelixConvert(o) { - if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity); - if (!(o instanceof Rgb)) o = rgbConvert(o); - var r = o.r / 255, - g = o.g / 255, - b = o.b / 255, - l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB), - bl = b - l, - k = (E * (g - l) - C * bl) / D, - s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1 - h = s ? Math.atan2(k, bl) * degrees$1 - 120 : NaN; - return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity); -} + attr(div, "class", "breadcrumbs-matrix markdown-preview-view svelte-fq6v4k"); + }, + m(target, anchor) { + insert(target, div, anchor); -function cubehelix$1(h, s, l, opacity) { - return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity); -} + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(div, null); + } + }, + p(ctx, [dirty]) { + if (dirty & /*filteredSquaresArr, openOrSwitch, app, currFile, hoverPreview, matrixView, settings*/ 31) { + each_value = /*filteredSquaresArr*/ ctx[0]; + let i; -function Cubehelix(h, s, l, opacity) { - this.h = +h; - this.s = +s; - this.l = +l; - this.opacity = +opacity; -} + for (i = 0; i < each_value.length; i += 1) { + const child_ctx = get_each_context$5(ctx, each_value, i); -define(Cubehelix, cubehelix$1, extend(Color, { - brighter: function(k) { - k = k == null ? brighter : Math.pow(brighter, k); - return new Cubehelix(this.h, this.s, this.l * k, this.opacity); - }, - darker: function(k) { - k = k == null ? darker : Math.pow(darker, k); - return new Cubehelix(this.h, this.s, this.l * k, this.opacity); - }, - rgb: function() { - var h = isNaN(this.h) ? 0 : (this.h + 120) * radians, - l = +this.l, - a = isNaN(this.s) ? 0 : this.s * l * (1 - l), - cosh = Math.cos(h), - sinh = Math.sin(h); - return new Rgb( - 255 * (l + a * (A * cosh + B * sinh)), - 255 * (l + a * (C * cosh + D * sinh)), - 255 * (l + a * (E * cosh)), - this.opacity - ); - } -})); + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + } else { + each_blocks[i] = create_each_block$5(child_ctx); + each_blocks[i].c(); + each_blocks[i].m(div, null); + } + } -var constant$5 = x => () => x; + for (; i < each_blocks.length; i += 1) { + each_blocks[i].d(1); + } -function linear$1(a, d) { - return function(t) { - return a + t * d; - }; + each_blocks.length = each_value.length; + } + }, + i: noop$1, + o: noop$1, + d(detaching) { + if (detaching) detach(div); + destroy_each(each_blocks, detaching); + } + }; } -function exponential(a, b, y) { - return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) { - return Math.pow(a + t * b, y); - }; -} +function instance$a($$self, $$props, $$invalidate) { + + + + + let { filteredSquaresArr } = $$props; + let { currFile } = $$props; + let { settings } = $$props; + let { matrixView } = $$props; + let { app } = $$props; + const click_handler = async (realItem, e) => openOrSwitch(app, realItem.to, currFile, e); + const mouseover_handler = (realItem, event) => hoverPreview(event, matrixView, realItem.to); + const click_handler_1 = async (impliedItem, e) => openOrSwitch(app, impliedItem.to, currFile, e); + const mouseover_handler_1 = (impliedItem, event) => hoverPreview(event, matrixView, impliedItem.to); -function hue(a, b) { - var d = b - a; - return d ? linear$1(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant$5(isNaN(a) ? b : a); + $$self.$$set = $$props => { + if ("filteredSquaresArr" in $$props) $$invalidate(0, filteredSquaresArr = $$props.filteredSquaresArr); + if ("currFile" in $$props) $$invalidate(1, currFile = $$props.currFile); + if ("settings" in $$props) $$invalidate(2, settings = $$props.settings); + if ("matrixView" in $$props) $$invalidate(3, matrixView = $$props.matrixView); + if ("app" in $$props) $$invalidate(4, app = $$props.app); + }; + + return [ + filteredSquaresArr, + currFile, + settings, + matrixView, + app, + click_handler, + mouseover_handler, + click_handler_1, + mouseover_handler_1 + ]; } -function gamma(y) { - return (y = +y) === 1 ? nogamma : function(a, b) { - return b - a ? exponential(a, b, y) : constant$5(isNaN(a) ? b : a); - }; +class Matrix extends SvelteComponent { + constructor(options) { + super(); + if (!document.getElementById("svelte-fq6v4k-style")) add_css$5(); + + init$1(this, options, instance$a, create_fragment$a, safe_not_equal, { + filteredSquaresArr: 0, + currFile: 1, + settings: 2, + matrixView: 3, + app: 4 + }); + } } -function nogamma(a, b) { - var d = b - a; - return d ? linear$1(a, d) : constant$5(isNaN(a) ? b : a); +class MatrixView extends obsidian.ItemView { + constructor(leaf, plugin) { + super(leaf); + this.icon = TRAIL_ICON; + this.plugin = plugin; + } + async onload() { + super.onload(); + await this.plugin.saveSettings(); + this.matrixQ = this.plugin.settings.defaultView; + this.app.workspace.onLayoutReady(async () => { + setTimeout(async () => await this.draw(), this.app.plugins.plugins.dataview + ? this.app.plugins.plugins.dataview.api + ? 1 + : this.plugin.settings.dvWaitTime + : 3000); + }); + this.plugin.addCommand({ + id: "local-index", + name: "Copy a Local Index to the clipboard", + callback: async () => { + const settings = this.plugin.settings; + const currFile = this.app.workspace.getActiveFile().basename; + const closedParents = this.plugin.currGraphs.closedGs.down; + const allPaths = this.dfsAllPaths(closedParents, currFile); + const index = this.createIndex(currFile + "\n", allPaths, settings); + debug(settings, { index }); + await copy$1(index); + }, + }); + this.plugin.addCommand({ + id: "global-index", + name: "Copy a Global Index to the clipboard", + callback: async () => { + const { up } = this.plugin.currGraphs.mergedGs; + const closedParents = this.plugin.currGraphs.closedGs.down; + const sinks = getSinks(up); + const settings = this.plugin.settings; + let globalIndex = ""; + sinks.forEach((terminal) => { + globalIndex += terminal + "\n"; + const allPaths = this.dfsAllPaths(closedParents, terminal); + globalIndex = this.createIndex(globalIndex, allPaths, settings); + }); + debug(settings, { globalIndex }); + await copy$1(globalIndex); + }, + }); + } + getViewType() { + return MATRIX_VIEW; + } + getDisplayText() { + return "Breadcrumbs Matrix"; + } + async onOpen() { + await this.plugin.saveSettings(); + // this.app.workspace.onLayoutReady(async () => { + // setTimeout(async () => await this.draw(), DATAVIEW_INDEX_DELAY); + // }); + // this.app.workspace.on("dataview:api-ready", () => + // console.log("dv ready") + // ); + } + onClose() { + if (this.view) { + this.view.$destroy(); + } + return Promise.resolve(); + } + unresolvedQ(to, from) { + const { unresolvedLinks } = this.app.metadataCache; + if (!unresolvedLinks[from]) { + return false; + } + return unresolvedLinks[from][to] > 0; + } + squareItems(g, currFile, settings, realQ = true) { + let items; + const altFieldsQ = !!settings.altLinkFields.length; + if (realQ) { + items = g.outNeighbors(currFile.basename); + } + else { + items = g.inNeighbors(currFile.basename); + } + const internalLinkObjArr = []; + // TODO I don't think I need to check the length here + /// forEach won't run if it's empty anyway + if (items.length) { + items.forEach((to) => { + let alt = null; + if (altFieldsQ) { + const toFile = this.app.metadataCache.getFirstLinkpathDest(to, currFile.path); + if (toFile) { + const metadata = this.app.metadataCache.getFileCache(toFile); + settings.altLinkFields.forEach((altLinkField) => { + var _a; + const altLink = (_a = metadata === null || metadata === void 0 ? void 0 : metadata.frontmatter) === null || _a === void 0 ? void 0 : _a[altLinkField]; + if (altLink) { + alt = altLink; + return; + } + }); + } + } + internalLinkObjArr.push({ + to, + cls: "internal-link breadcrumbs-link" + + (this.unresolvedQ(to, currFile.path) ? " is-unresolved" : "") + + (realQ ? "" : " breadcrumbs-implied"), + alt, + }); + }); + } + return internalLinkObjArr; + } + // ANCHOR Remove duplicate implied links + removeDuplicateImplied(reals, implieds) { + const realTos = reals.map((real) => real.to); + return implieds.filter((implied) => !realTos.includes(implied.to)); + } + dfsAllPaths(g, startNode) { + const queue = [ + { node: startNode, path: [] }, + ]; + const pathsArr = []; + let i = 0; + while (queue.length > 0 && i < 1000) { + i++; + const currPath = queue.shift(); + const newNodes = g.outNeighbors(currPath.node); + const extPath = [currPath.node, ...currPath.path]; + queue.unshift(...newNodes.map((n) => { + return { node: n, path: extPath }; + })); + if (newNodes.length === 0) { + pathsArr.push(extPath); + } + } + return pathsArr; + } + createIndex( + // Gotta give it a starting index. This allows it to work for the global index feat + index, allPaths, settings) { + const copy = lodash.cloneDeep(allPaths); + const reversed = copy.map((path) => path.reverse()); + reversed.forEach((path) => path.shift()); + const indent = " "; + const visited = {}; + const activeFile = this.app.workspace.getActiveFile(); + reversed.forEach((path) => { + var _a, _b, _c, _d; + for (let depth = 0; depth < path.length; depth++) { + const currNode = path[depth]; + // If that node has been visited before at the current depth + if (visited.hasOwnProperty(currNode) && + visited[currNode].includes(depth)) { + continue; + } + else { + index += `${indent.repeat(depth)}- `; + index += settings.wikilinkIndex ? "[[" : ""; + index += currNode; + index += settings.wikilinkIndex ? "]]" : ""; + if (settings.aliasesInIndex) { + const currFile = this.app.metadataCache.getFirstLinkpathDest(currNode, activeFile.path); + if (currFile !== null) { + const cache = this.app.metadataCache.getFileCache(currFile); + const alias = (_b = (_a = cache === null || cache === void 0 ? void 0 : cache.frontmatter) === null || _a === void 0 ? void 0 : _a.alias) !== null && _b !== void 0 ? _b : []; + const aliases = (_d = (_c = cache === null || cache === void 0 ? void 0 : cache.frontmatter) === null || _c === void 0 ? void 0 : _c.aliases) !== null && _d !== void 0 ? _d : []; + const allAliases = [ + ...[alias].flat(3), + ...[aliases].flat(3), + ]; + if (allAliases.length) { + index += ` (${allAliases.join(", ")})`; + } + } + } + index += "\n"; + if (!visited.hasOwnProperty(currNode)) { + visited[currNode] = []; + } + visited[currNode].push(depth); + } + } + }); + return index; + } + getHierSquares(userHierarchies, data, currFile, settings) { + return userHierarchies.map((hier, i) => { + const [currUpG, currSameG, currDownG] = [ + data[i].up, + data[i].same, + data[i].down, + ]; + let [rUp, rSame, rDown, iUp, iDown] = [ + this.squareItems(currUpG, currFile, settings), + this.squareItems(currSameG, currFile, settings), + this.squareItems(currDownG, currFile, settings), + this.squareItems(currDownG, currFile, settings, false), + this.squareItems(currUpG, currFile, settings, false), + ]; + // SECTION Implied Siblings + /// Notes with the same parents + const currParents = currUpG.outNeighbors(currFile.basename); + let iSameArr = []; + currParents.forEach((parent) => { + let impliedSiblings = currUpG.inNeighbors(parent); + // The current note is always it's own implied sibling, so remove it from the list + const indexCurrNote = impliedSiblings.indexOf(currFile.basename); + impliedSiblings.splice(indexCurrNote, 1); + if (settings.filterImpliedSiblingsOfDifferentTypes) { + impliedSiblings = impliedSiblings.filter((iSibling) => { + const iSiblingType = currUpG.getNodeAttribute(iSibling, "fieldName"); + const currNodeType = currUpG.getNodeAttribute(currFile.basename, "fieldName"); + console.log({ iSiblingType, currNodeType }); + return iSiblingType === currNodeType; + }); + } + // Create the implied sibling SquareProps + impliedSiblings.forEach((impliedSibling) => { + const altFieldsQ = !!settings.altLinkFields.length; + let alt = null; + if (altFieldsQ) { + const toFile = this.app.metadataCache.getFirstLinkpathDest(impliedSibling, currFile.path); + if (toFile) { + const metadata = this.app.metadataCache.getFileCache(toFile); + settings.altLinkFields.forEach((altLinkField) => { + var _a; + const altLink = (_a = metadata === null || metadata === void 0 ? void 0 : metadata.frontmatter) === null || _a === void 0 ? void 0 : _a[altLinkField]; + if (altLink) { + alt = altLink; + return; + } + }); + } + } + iSameArr.push({ + to: impliedSibling, + cls: "internal-link breadcrumbs-link breadcrumbs-implied" + + (this.unresolvedQ(impliedSibling, currFile.path) + ? " is-unresolved" + : ""), + // TODO get alt for implied siblings + alt, + }); + }); + }); + /// A real sibling implies the reverse sibling + iSameArr.push(...this.squareItems(currSameG, currFile, settings, false)); + // !SECTION + iUp = this.removeDuplicateImplied(rUp, iUp); + iSameArr = this.removeDuplicateImplied(rSame, iSameArr); + iDown = this.removeDuplicateImplied(rDown, iDown); + const iSameNoDup = []; + iSameArr.forEach((impSib) => { + if (iSameNoDup.every((noDup) => noDup.to !== impSib.to)) { + iSameNoDup.push(impSib); + } + }); + iSameArr = iSameNoDup; + debug(settings, { + rUp, + iUp, + rSame, + iSameArr, + rDown, + iDown, + }); + const upSquare = { + realItems: rUp, + impliedItems: iUp, + fieldName: hier.up[0] === "" + ? `${hier.down.join(",")}` + : hier.up.join(", "), + }; + const sameSquare = { + realItems: rSame, + impliedItems: iSameArr, + fieldName: hier.same[0] === "" + ? `${hier.up.join(",")}` + : hier.same.join(", "), + }; + const downSquare = { + realItems: rDown, + impliedItems: iDown, + fieldName: hier.down[0] === "" + ? `${hier.up.join(",")}` + : hier.down.join(", "), + }; + return [upSquare, sameSquare, downSquare]; + }); + } + async draw() { + this.contentEl.empty(); + const { settings } = this.plugin; + debugGroupStart(settings, "debugMode", "Draw Matrix/List View"); + const hierGs = this.plugin.currGraphs; + const { userHierarchies } = settings; + const currFile = this.app.workspace.getActiveFile(); + const viewToggleButton = this.contentEl.createEl("button", { + text: this.matrixQ ? "List" : "Matrix", + }); + viewToggleButton.addEventListener("click", async () => { + this.matrixQ = !this.matrixQ; + viewToggleButton.innerText = this.matrixQ ? "List" : "Matrix"; + await this.draw(); + }); + const refreshIndexButton = this.contentEl.createEl("button", { + text: "🔁", + }); + refreshIndexButton.addEventListener("click", async () => { + await this.plugin.refreshIndex(); + }); + const data = hierGs.hierGs.map((hier) => { + const hierData = { + up: undefined, + same: undefined, + down: undefined, + }; + DIRECTIONS.forEach((dir) => { + // This is merging all graphs in Dir **In a particular hierarchy**, not accross all hierarchies like mergeGs(getAllGsInDir()) does + hierData[dir] = mergeGs(...Object.values(hier[dir])); + }); + return hierData; + }); + debug(settings, { data }); + const hierSquares = this.getHierSquares(userHierarchies, data, currFile, settings); + debug(settings, { hierSquares }); + const filteredSquaresArr = hierSquares.filter((squareArr) => squareArr.some((square) => square.realItems.length + square.impliedItems.length > 0)); + const compInput = { + target: this.contentEl, + props: { + filteredSquaresArr, + currFile, + settings, + matrixView: this, + app: this.app, + }, + }; + if (this.matrixQ) { + this.view = new Matrix(compInput); + } + else { + this.view = new Lists(compInput); + } + debugGroupEnd(settings, "debugMode"); + } } -var interpolateRgb = (function rgbGamma(y) { - var color = gamma(y); - - function rgb$1(start, end) { - var r = color((start = rgb(start)).r, (end = rgb(end)).r), - g = color(start.g, end.g), - b = color(start.b, end.b), - opacity = nogamma(start.opacity, end.opacity); - return function(t) { - start.r = r(t); - start.g = g(t); - start.b = b(t); - start.opacity = opacity(t); - return start + ""; - }; - } - - rgb$1.gamma = rgbGamma; +/* src\Components\KoFi.svelte generated by Svelte v3.35.0 */ - return rgb$1; -})(1); +function create_fragment$9(ctx) { + let script; + let script_src_value; + let t; + let div; + let mounted; + let dispose; -function numberArray(a, b) { - if (!b) b = []; - var n = a ? Math.min(b.length, a.length) : 0, - c = b.slice(), - i; - return function(t) { - for (i = 0; i < n; ++i) c[i] = a[i] * (1 - t) + b[i] * t; - return c; - }; -} + return { + c() { + script = element("script"); + t = space(); + div = element("div"); + attr(script, "type", "text/javascript"); + if (script.src !== (script_src_value = "https://ko-fi.com/widgets/widget_2.js")) attr(script, "src", script_src_value); + }, + m(target, anchor) { + append(document.head, script); + insert(target, t, anchor); + insert(target, div, anchor); + /*div_binding*/ ctx[2](div); -function isNumberArray(x) { - return ArrayBuffer.isView(x) && !(x instanceof DataView); + if (!mounted) { + dispose = listen(script, "load", /*initializeKofi*/ ctx[1]); + mounted = true; + } + }, + p: noop$1, + i: noop$1, + o: noop$1, + d(detaching) { + detach(script); + if (detaching) detach(t); + if (detaching) detach(div); + /*div_binding*/ ctx[2](null); + mounted = false; + dispose(); + } + }; } -function genericArray(a, b) { - var nb = b ? b.length : 0, - na = a ? Math.min(nb, a.length) : 0, - x = new Array(na), - c = new Array(nb), - i; +function instance$9($$self, $$props, $$invalidate) { + let button; - for (i = 0; i < na; ++i) x[i] = interpolate$1(a[i], b[i]); - for (; i < nb; ++i) c[i] = b[i]; + var initializeKofi = () => { + kofiwidget2.init("Support Breadcrumbs development!", "#29abe0", "G2G454TZF"); + $$invalidate(0, button.innerHTML = kofiwidget2.getHTML(), button); + }; - return function(t) { - for (i = 0; i < na; ++i) c[i] = x[i](t); - return c; - }; -} + function div_binding($$value) { + binding_callbacks[$$value ? "unshift" : "push"](() => { + button = $$value; + $$invalidate(0, button); + }); + } -function date(a, b) { - var d = new Date; - return a = +a, b = +b, function(t) { - return d.setTime(a * (1 - t) + b * t), d; - }; + return [button, initializeKofi, div_binding]; } -function interpolateNumber(a, b) { - return a = +a, b = +b, function(t) { - return a * (1 - t) + b * t; - }; +class KoFi extends SvelteComponent { + constructor(options) { + super(); + init$1(this, options, instance$9, create_fragment$9, safe_not_equal, {}); + } } -function object(a, b) { - var i = {}, - c = {}, - k; - - if (a === null || typeof a !== "object") a = {}; - if (b === null || typeof b !== "object") b = {}; - - for (k in b) { - if (k in a) { - i[k] = interpolate$1(a[k], b[k]); - } else { - c[k] = b[k]; - } - } +/* node_modules\svelte-icons\components\IconBase.svelte generated by Svelte v3.35.0 */ - return function(t) { - for (k in i) c[k] = i[k](t); - return c; - }; +function add_css$4() { + var style = element("style"); + style.id = "svelte-c8tyih-style"; + style.textContent = "svg.svelte-c8tyih{stroke:currentColor;fill:currentColor;stroke-width:0;width:100%;height:auto;max-height:100%}"; + append(document.head, style); } -var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g, - reB = new RegExp(reA.source, "g"); - -function zero(b) { - return function() { - return b; - }; -} +// (18:2) {#if title} +function create_if_block$2(ctx) { + let title_1; + let t; -function one(b) { - return function(t) { - return b(t) + ""; - }; + return { + c() { + title_1 = svg_element("title"); + t = text(/*title*/ ctx[0]); + }, + m(target, anchor) { + insert(target, title_1, anchor); + append(title_1, t); + }, + p(ctx, dirty) { + if (dirty & /*title*/ 1) set_data(t, /*title*/ ctx[0]); + }, + d(detaching) { + if (detaching) detach(title_1); + } + }; } -function interpolateString(a, b) { - var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b - am, // current match in a - bm, // current match in b - bs, // string preceding current number in b, if any - i = -1, // index in s - s = [], // string constants and placeholders - q = []; // number interpolators - - // Coerce inputs to strings. - a = a + "", b = b + ""; +function create_fragment$8(ctx) { + let svg; + let if_block_anchor; + let current; + let if_block = /*title*/ ctx[0] && create_if_block$2(ctx); + const default_slot_template = /*#slots*/ ctx[3].default; + const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[2], null); - // Interpolate pairs of numbers in a & b. - while ((am = reA.exec(a)) - && (bm = reB.exec(b))) { - if ((bs = bm.index) > bi) { // a string precedes the next number in b - bs = b.slice(bi, bs); - if (s[i]) s[i] += bs; // coalesce with previous string - else s[++i] = bs; - } - if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match - if (s[i]) s[i] += bm; // coalesce with previous string - else s[++i] = bm; - } else { // interpolate non-matching numbers - s[++i] = null; - q.push({i: i, x: interpolateNumber(am, bm)}); - } - bi = reB.lastIndex; - } + return { + c() { + svg = svg_element("svg"); + if (if_block) if_block.c(); + if_block_anchor = empty$1(); + if (default_slot) default_slot.c(); + attr(svg, "xmlns", "http://www.w3.org/2000/svg"); + attr(svg, "viewBox", /*viewBox*/ ctx[1]); + attr(svg, "class", "svelte-c8tyih"); + }, + m(target, anchor) { + insert(target, svg, anchor); + if (if_block) if_block.m(svg, null); + append(svg, if_block_anchor); - // Add remains of b. - if (bi < b.length) { - bs = b.slice(bi); - if (s[i]) s[i] += bs; // coalesce with previous string - else s[++i] = bs; - } + if (default_slot) { + default_slot.m(svg, null); + } - // Special optimization for only a single match. - // Otherwise, interpolate each of the numbers and rejoin the string. - return s.length < 2 ? (q[0] - ? one(q[0].x) - : zero(b)) - : (b = q.length, function(t) { - for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }); -} + current = true; + }, + p(ctx, [dirty]) { + if (/*title*/ ctx[0]) { + if (if_block) { + if_block.p(ctx, dirty); + } else { + if_block = create_if_block$2(ctx); + if_block.c(); + if_block.m(svg, if_block_anchor); + } + } else if (if_block) { + if_block.d(1); + if_block = null; + } -function interpolate$1(a, b) { - var t = typeof b, c; - return b == null || t === "boolean" ? constant$5(b) - : (t === "number" ? interpolateNumber - : t === "string" ? ((c = color(b)) ? (b = c, interpolateRgb) : interpolateString) - : b instanceof color ? interpolateRgb - : b instanceof Date ? date - : isNumberArray(b) ? numberArray - : Array.isArray(b) ? genericArray - : typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object - : interpolateNumber)(a, b); -} + if (default_slot) { + if (default_slot.p && dirty & /*$$scope*/ 4) { + update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[2], dirty, null, null); + } + } -function interpolateRound(a, b) { - return a = +a, b = +b, function(t) { - return Math.round(a * (1 - t) + b * t); - }; + if (!current || dirty & /*viewBox*/ 2) { + attr(svg, "viewBox", /*viewBox*/ ctx[1]); + } + }, + i(local) { + if (current) return; + transition_in(default_slot, local); + current = true; + }, + o(local) { + transition_out(default_slot, local); + current = false; + }, + d(detaching) { + if (detaching) detach(svg); + if (if_block) if_block.d(); + if (default_slot) default_slot.d(detaching); + } + }; } -var degrees = 180 / Math.PI; - -var identity$4 = { - translateX: 0, - translateY: 0, - rotate: 0, - skewX: 0, - scaleX: 1, - scaleY: 1 -}; - -function decompose(a, b, c, d, e, f) { - var scaleX, scaleY, skewX; - if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX; - if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX; - if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY; - if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX; - return { - translateX: e, - translateY: f, - rotate: Math.atan2(b, a) * degrees, - skewX: Math.atan(skewX) * degrees, - scaleX: scaleX, - scaleY: scaleY - }; -} +function instance$8($$self, $$props, $$invalidate) { + let { $$slots: slots = {}, $$scope } = $$props; + let { title = null } = $$props; + let { viewBox } = $$props; -var svgNode; + $$self.$$set = $$props => { + if ("title" in $$props) $$invalidate(0, title = $$props.title); + if ("viewBox" in $$props) $$invalidate(1, viewBox = $$props.viewBox); + if ("$$scope" in $$props) $$invalidate(2, $$scope = $$props.$$scope); + }; -/* eslint-disable no-undef */ -function parseCss(value) { - const m = new (typeof DOMMatrix === "function" ? DOMMatrix : WebKitCSSMatrix)(value + ""); - return m.isIdentity ? identity$4 : decompose(m.a, m.b, m.c, m.d, m.e, m.f); + return [title, viewBox, $$scope, slots]; } -function parseSvg(value) { - if (value == null) return identity$4; - if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g"); - svgNode.setAttribute("transform", value); - if (!(value = svgNode.transform.baseVal.consolidate())) return identity$4; - value = value.matrix; - return decompose(value.a, value.b, value.c, value.d, value.e, value.f); +class IconBase extends SvelteComponent { + constructor(options) { + super(); + if (!document.getElementById("svelte-c8tyih-style")) add_css$4(); + init$1(this, options, instance$8, create_fragment$8, safe_not_equal, { title: 0, viewBox: 1 }); + } } -function interpolateTransform(parse, pxComma, pxParen, degParen) { - - function pop(s) { - return s.length ? s.pop() + " " : ""; - } - - function translate(xa, ya, xb, yb, s, q) { - if (xa !== xb || ya !== yb) { - var i = s.push("translate(", null, pxComma, null, pxParen); - q.push({i: i - 4, x: interpolateNumber(xa, xb)}, {i: i - 2, x: interpolateNumber(ya, yb)}); - } else if (xb || yb) { - s.push("translate(" + xb + pxComma + yb + pxParen); - } - } - - function rotate(a, b, s, q) { - if (a !== b) { - if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path - q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: interpolateNumber(a, b)}); - } else if (b) { - s.push(pop(s) + "rotate(" + b + degParen); - } - } - - function skewX(a, b, s, q) { - if (a !== b) { - q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: interpolateNumber(a, b)}); - } else if (b) { - s.push(pop(s) + "skewX(" + b + degParen); - } - } +/* node_modules\svelte-icons\fa\FaListUl.svelte generated by Svelte v3.35.0 */ - function scale(xa, ya, xb, yb, s, q) { - if (xa !== xb || ya !== yb) { - var i = s.push(pop(s) + "scale(", null, ",", null, ")"); - q.push({i: i - 4, x: interpolateNumber(xa, xb)}, {i: i - 2, x: interpolateNumber(ya, yb)}); - } else if (xb !== 1 || yb !== 1) { - s.push(pop(s) + "scale(" + xb + "," + yb + ")"); - } - } +function create_default_slot$2(ctx) { + let path; - return function(a, b) { - var s = [], // string constants and placeholders - q = []; // number interpolators - a = parse(a), b = parse(b); - translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q); - rotate(a.rotate, b.rotate, s, q); - skewX(a.skewX, b.skewX, s, q); - scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q); - a = b = null; // gc - return function(t) { - var i = -1, n = q.length, o; - while (++i < n) s[(o = q[i]).i] = o.x(t); - return s.join(""); - }; - }; + return { + c() { + path = svg_element("path"); + attr(path, "d", "M48 48a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm448 16H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z"); + }, + m(target, anchor) { + insert(target, path, anchor); + }, + d(detaching) { + if (detaching) detach(path); + } + }; } -var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)"); -var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")"); - -var epsilon2 = 1e-12; - -function cosh(x) { - return ((x = Math.exp(x)) + 1 / x) / 2; -} +function create_fragment$7(ctx) { + let iconbase; + let current; + const iconbase_spread_levels = [{ viewBox: "0 0 512 512" }, /*$$props*/ ctx[0]]; -function sinh(x) { - return ((x = Math.exp(x)) - 1 / x) / 2; -} + let iconbase_props = { + $$slots: { default: [create_default_slot$2] }, + $$scope: { ctx } + }; -function tanh(x) { - return ((x = Math.exp(2 * x)) - 1) / (x + 1); -} + for (let i = 0; i < iconbase_spread_levels.length; i += 1) { + iconbase_props = assign(iconbase_props, iconbase_spread_levels[i]); + } -var interpolateZoom = (function zoomRho(rho, rho2, rho4) { + iconbase = new IconBase({ props: iconbase_props }); - // p0 = [ux0, uy0, w0] - // p1 = [ux1, uy1, w1] - function zoom(p0, p1) { - var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], - ux1 = p1[0], uy1 = p1[1], w1 = p1[2], - dx = ux1 - ux0, - dy = uy1 - uy0, - d2 = dx * dx + dy * dy, - i, - S; + return { + c() { + create_component(iconbase.$$.fragment); + }, + m(target, anchor) { + mount_component(iconbase, target, anchor); + current = true; + }, + p(ctx, [dirty]) { + const iconbase_changes = (dirty & /*$$props*/ 1) + ? get_spread_update(iconbase_spread_levels, [iconbase_spread_levels[0], get_spread_object(/*$$props*/ ctx[0])]) + : {}; - // Special case for u0 ≅ u1. - if (d2 < epsilon2) { - S = Math.log(w1 / w0) / rho; - i = function(t) { - return [ - ux0 + t * dx, - uy0 + t * dy, - w0 * Math.exp(rho * t * S) - ]; - }; - } + if (dirty & /*$$scope*/ 2) { + iconbase_changes.$$scope = { dirty, ctx }; + } - // General case. - else { - var d1 = Math.sqrt(d2), - b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1), - b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1), - r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), - r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1); - S = (r1 - r0) / rho; - i = function(t) { - var s = t * S, - coshr0 = cosh(r0), - u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0)); - return [ - ux0 + u * dx, - uy0 + u * dy, - w0 * coshr0 / cosh(rho * s + r0) - ]; - }; - } + iconbase.$set(iconbase_changes); + }, + i(local) { + if (current) return; + transition_in(iconbase.$$.fragment, local); + current = true; + }, + o(local) { + transition_out(iconbase.$$.fragment, local); + current = false; + }, + d(detaching) { + destroy_component(iconbase, detaching); + } + }; +} - i.duration = S * 1000 * rho / Math.SQRT2; +function instance$7($$self, $$props, $$invalidate) { + $$self.$$set = $$new_props => { + $$invalidate(0, $$props = assign(assign({}, $$props), exclude_internal_props($$new_props))); + }; - return i; - } + $$props = exclude_internal_props($$props); + return [$$props]; +} - zoom.rho = function(_) { - var _1 = Math.max(1e-3, +_), _2 = _1 * _1, _4 = _2 * _2; - return zoomRho(_1, _2, _4); - }; +class FaListUl extends SvelteComponent { + constructor(options) { + super(); + init$1(this, options, instance$7, create_fragment$7, safe_not_equal, {}); + } +} - return zoom; -})(Math.SQRT2, 2, 4); +/* node_modules\svelte-icons\fa\FaPlus.svelte generated by Svelte v3.35.0 */ -function cubehelix(hue) { - return (function cubehelixGamma(y) { - y = +y; +function create_default_slot$1(ctx) { + let path; - function cubehelix(start, end) { - var h = hue((start = cubehelix$1(start)).h, (end = cubehelix$1(end)).h), - s = nogamma(start.s, end.s), - l = nogamma(start.l, end.l), - opacity = nogamma(start.opacity, end.opacity); - return function(t) { - start.h = h(t); - start.s = s(t); - start.l = l(Math.pow(t, y)); - start.opacity = opacity(t); - return start + ""; - }; - } + return { + c() { + path = svg_element("path"); + attr(path, "d", "M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z"); + }, + m(target, anchor) { + insert(target, path, anchor); + }, + d(detaching) { + if (detaching) detach(path); + } + }; +} - cubehelix.gamma = cubehelixGamma; +function create_fragment$6(ctx) { + let iconbase; + let current; + const iconbase_spread_levels = [{ viewBox: "0 0 448 512" }, /*$$props*/ ctx[0]]; - return cubehelix; - })(1); -} + let iconbase_props = { + $$slots: { default: [create_default_slot$1] }, + $$scope: { ctx } + }; -cubehelix(hue); -var cubehelixLong = cubehelix(nogamma); + for (let i = 0; i < iconbase_spread_levels.length; i += 1) { + iconbase_props = assign(iconbase_props, iconbase_spread_levels[i]); + } -function quantize(interpolator, n) { - var samples = new Array(n); - for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1)); - return samples; -} + iconbase = new IconBase({ props: iconbase_props }); -var frame = 0, // is an animation frame pending? - timeout$1 = 0, // is a timeout pending? - interval = 0, // are any timers active? - pokeDelay = 1000, // how frequently we check for clock skew - taskHead, - taskTail, - clockLast = 0, - clockNow = 0, - clockSkew = 0, - clock = typeof performance === "object" && performance.now ? performance : Date, - setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); }; + return { + c() { + create_component(iconbase.$$.fragment); + }, + m(target, anchor) { + mount_component(iconbase, target, anchor); + current = true; + }, + p(ctx, [dirty]) { + const iconbase_changes = (dirty & /*$$props*/ 1) + ? get_spread_update(iconbase_spread_levels, [iconbase_spread_levels[0], get_spread_object(/*$$props*/ ctx[0])]) + : {}; -function now() { - return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew); + if (dirty & /*$$scope*/ 2) { + iconbase_changes.$$scope = { dirty, ctx }; + } + + iconbase.$set(iconbase_changes); + }, + i(local) { + if (current) return; + transition_in(iconbase.$$.fragment, local); + current = true; + }, + o(local) { + transition_out(iconbase.$$.fragment, local); + current = false; + }, + d(detaching) { + destroy_component(iconbase, detaching); + } + }; } -function clearNow() { - clockNow = 0; +function instance$6($$self, $$props, $$invalidate) { + $$self.$$set = $$new_props => { + $$invalidate(0, $$props = assign(assign({}, $$props), exclude_internal_props($$new_props))); + }; + + $$props = exclude_internal_props($$props); + return [$$props]; } -function Timer() { - this._call = - this._time = - this._next = null; +class FaPlus extends SvelteComponent { + constructor(options) { + super(); + init$1(this, options, instance$6, create_fragment$6, safe_not_equal, {}); + } } -Timer.prototype = timer.prototype = { - constructor: Timer, - restart: function(callback, delay, time) { - if (typeof callback !== "function") throw new TypeError("callback is not a function"); - time = (time == null ? now() : +time) + (delay == null ? 0 : +delay); - if (!this._next && taskTail !== this) { - if (taskTail) taskTail._next = this; - else taskHead = this; - taskTail = this; - } - this._call = callback; - this._time = time; - sleep(); - }, - stop: function() { - if (this._call) { - this._call = null; - this._time = Infinity; - sleep(); - } - } -}; +/* node_modules\svelte-icons\fa\FaRegTrashAlt.svelte generated by Svelte v3.35.0 */ -function timer(callback, delay, time) { - var t = new Timer; - t.restart(callback, delay, time); - return t; -} +function create_default_slot(ctx) { + let path; -function timerFlush() { - now(); // Get the current time, if not already set. - ++frame; // Pretend we’ve set an alarm, if we haven’t already. - var t = taskHead, e; - while (t) { - if ((e = clockNow - t._time) >= 0) t._call.call(null, e); - t = t._next; - } - --frame; + return { + c() { + path = svg_element("path"); + attr(path, "d", "M268 416h24a12 12 0 0 0 12-12V188a12 12 0 0 0-12-12h-24a12 12 0 0 0-12 12v216a12 12 0 0 0 12 12zM432 80h-82.41l-34-56.7A48 48 0 0 0 274.41 0H173.59a48 48 0 0 0-41.16 23.3L98.41 80H16A16 16 0 0 0 0 96v16a16 16 0 0 0 16 16h16v336a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48V128h16a16 16 0 0 0 16-16V96a16 16 0 0 0-16-16zM171.84 50.91A6 6 0 0 1 177 48h94a6 6 0 0 1 5.15 2.91L293.61 80H154.39zM368 464H80V128h288zm-212-48h24a12 12 0 0 0 12-12V188a12 12 0 0 0-12-12h-24a12 12 0 0 0-12 12v216a12 12 0 0 0 12 12z"); + }, + m(target, anchor) { + insert(target, path, anchor); + }, + d(detaching) { + if (detaching) detach(path); + } + }; } -function wake() { - clockNow = (clockLast = clock.now()) + clockSkew; - frame = timeout$1 = 0; - try { - timerFlush(); - } finally { - frame = 0; - nap(); - clockNow = 0; - } -} +function create_fragment$5(ctx) { + let iconbase; + let current; + const iconbase_spread_levels = [{ viewBox: "0 0 448 512" }, /*$$props*/ ctx[0]]; -function poke() { - var now = clock.now(), delay = now - clockLast; - if (delay > pokeDelay) clockSkew -= delay, clockLast = now; -} + let iconbase_props = { + $$slots: { default: [create_default_slot] }, + $$scope: { ctx } + }; -function nap() { - var t0, t1 = taskHead, t2, time = Infinity; - while (t1) { - if (t1._call) { - if (time > t1._time) time = t1._time; - t0 = t1, t1 = t1._next; - } else { - t2 = t1._next, t1._next = null; - t1 = t0 ? t0._next = t2 : taskHead = t2; - } - } - taskTail = t0; - sleep(time); -} + for (let i = 0; i < iconbase_spread_levels.length; i += 1) { + iconbase_props = assign(iconbase_props, iconbase_spread_levels[i]); + } -function sleep(time) { - if (frame) return; // Soonest alarm already set, or will be. - if (timeout$1) timeout$1 = clearTimeout(timeout$1); - var delay = time - clockNow; // Strictly less than if we recomputed clockNow. - if (delay > 24) { - if (time < Infinity) timeout$1 = setTimeout(wake, time - clock.now() - clockSkew); - if (interval) interval = clearInterval(interval); - } else { - if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay); - frame = 1, setFrame(wake); - } -} + iconbase = new IconBase({ props: iconbase_props }); -function timeout(callback, delay, time) { - var t = new Timer; - delay = delay == null ? 0 : +delay; - t.restart(elapsed => { - t.stop(); - callback(elapsed + delay); - }, delay, time); - return t; + return { + c() { + create_component(iconbase.$$.fragment); + }, + m(target, anchor) { + mount_component(iconbase, target, anchor); + current = true; + }, + p(ctx, [dirty]) { + const iconbase_changes = (dirty & /*$$props*/ 1) + ? get_spread_update(iconbase_spread_levels, [iconbase_spread_levels[0], get_spread_object(/*$$props*/ ctx[0])]) + : {}; + + if (dirty & /*$$scope*/ 2) { + iconbase_changes.$$scope = { dirty, ctx }; + } + + iconbase.$set(iconbase_changes); + }, + i(local) { + if (current) return; + transition_in(iconbase.$$.fragment, local); + current = true; + }, + o(local) { + transition_out(iconbase.$$.fragment, local); + current = false; + }, + d(detaching) { + destroy_component(iconbase, detaching); + } + }; } -var emptyOn = dispatch("start", "end", "cancel", "interrupt"); -var emptyTween = []; +function instance$5($$self, $$props, $$invalidate) { + $$self.$$set = $$new_props => { + $$invalidate(0, $$props = assign(assign({}, $$props), exclude_internal_props($$new_props))); + }; -var CREATED = 0; -var SCHEDULED = 1; -var STARTING = 2; -var STARTED = 3; -var RUNNING = 4; -var ENDING = 5; -var ENDED = 6; + $$props = exclude_internal_props($$props); + return [$$props]; +} -function schedule(node, name, id, index, group, timing) { - var schedules = node.__transition; - if (!schedules) node.__transition = {}; - else if (id in schedules) return; - create(node, id, { - name: name, - index: index, // For context during callback. - group: group, // For context during callback. - on: emptyOn, - tween: emptyTween, - time: timing.time, - delay: timing.delay, - duration: timing.duration, - ease: timing.ease, - timer: null, - state: CREATED - }); +class FaRegTrashAlt extends SvelteComponent { + constructor(options) { + super(); + init$1(this, options, instance$5, create_fragment$5, safe_not_equal, {}); + } } -function init(node, id) { - var schedule = get$1(node, id); - if (schedule.state > CREATED) throw new Error("too late; already scheduled"); - return schedule; +/* src\Components\UserHierarchies.svelte generated by Svelte v3.35.0 */ + +function add_css$3() { + var style = element("style"); + style.id = "svelte-cve01y-style"; + style.textContent = "div.GA-Buttons.svelte-cve01y.svelte-cve01y{padding-bottom:5px}details.BC-Hier-Details.svelte-cve01y.svelte-cve01y{padding-left:10px;margin-bottom:15px}.BC-Hier-Details.svelte-cve01y summary.svelte-cve01y::marker{font-size:10px}.BC-Hier-Details.svelte-cve01y summary button.svelte-cve01y{float:right}.icon.svelte-cve01y.svelte-cve01y{color:var(--text-normal);display:inline-block;padding-top:3px;width:17px;height:17px}"; + append(document.head, style); } -function set(node, id) { - var schedule = get$1(node, id); - if (schedule.state > STARTED) throw new Error("too late; already running"); - return schedule; +function get_each_context$4(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[10] = list[i]; + child_ctx[12] = i; + return child_ctx; } -function get$1(node, id) { - var schedule = node.__transition; - if (!schedule || !(schedule = schedule[id])) throw new Error("transition not found"); - return schedule; +function get_each_context_1$4(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[13] = list[i]; + return child_ctx; } -function create(node, id, self) { - var schedules = node.__transition, - tween; +// (76:6) {#each DIRECTIONS as dir} +function create_each_block_1$4(ctx) { + let label; + let t0_value = ARROW_DIRECTIONS[/*dir*/ ctx[13]] + ""; + let t0; + let label_for_value; + let t1; + let input; + let input_name_value; + let input_value_value; + let mounted; + let dispose; - // Initialize the self timer when the transition is created. - // Note the actual delay is not known until the first callback! - schedules[id] = self; - self.timer = timer(schedule, 0, self.time); + function change_handler(...args) { + return /*change_handler*/ ctx[9](/*i*/ ctx[12], /*dir*/ ctx[13], ...args); + } - function schedule(elapsed) { - self.state = SCHEDULED; - self.timer.restart(start, self.delay, self.time); + return { + c() { + label = element("label"); + t0 = text(t0_value); + t1 = space(); + input = element("input"); + attr(label, "for", label_for_value = /*dir*/ ctx[13]); + attr(input, "type", "text"); + attr(input, "size", "6"); + attr(input, "name", input_name_value = /*dir*/ ctx[13]); + input.value = input_value_value = /*hier*/ ctx[10][/*dir*/ ctx[13]].join(", "); + }, + m(target, anchor) { + insert(target, label, anchor); + append(label, t0); + insert(target, t1, anchor); + insert(target, input, anchor); - // If the elapsed delay is less than our first sleep, start immediately. - if (self.delay <= elapsed) start(elapsed - self.delay); - } + if (!mounted) { + dispose = listen(input, "change", change_handler); + mounted = true; + } + }, + p(new_ctx, dirty) { + ctx = new_ctx; - function start(elapsed) { - var i, j, n, o; + if (dirty & /*userHierarchies*/ 2 && input_value_value !== (input_value_value = /*hier*/ ctx[10][/*dir*/ ctx[13]].join(", ")) && input.value !== input_value_value) { + input.value = input_value_value; + } + }, + d(detaching) { + if (detaching) detach(label); + if (detaching) detach(t1); + if (detaching) detach(input); + mounted = false; + dispose(); + } + }; +} - // If the state is not SCHEDULED, then we previously errored on start. - if (self.state !== SCHEDULED) return stop(); +// (47:2) {#each userHierarchies as hier, i} +function create_each_block$4(ctx) { + let details; + let summary; + let t0_value = (DIRECTIONS.map(func).flat().join(", ") || "Empty Hierarchy") + ""; + let t0; + let t1; + let button0; + let t3; + let button1; + let t5; + let button2; + let t7; + let t8; + let mounted; + let dispose; - for (i in schedules) { - o = schedules[i]; - if (o.name !== self.name) continue; + function func(...args) { + return /*func*/ ctx[5](/*hier*/ ctx[10], ...args); + } - // While this element already has a starting transition during this frame, - // defer starting an interrupting transition until that transition has a - // chance to tick (and possibly end); see d3/d3-transition#54! - if (o.state === STARTED) return timeout(start); + function click_handler_3() { + return /*click_handler_3*/ ctx[6](/*i*/ ctx[12]); + } - // Interrupt the active transition, if any. - if (o.state === RUNNING) { - o.state = ENDED; - o.timer.stop(); - o.on.call("interrupt", node, node.__data__, o.index, o.group); - delete schedules[i]; - } + function click_handler_4() { + return /*click_handler_4*/ ctx[7](/*i*/ ctx[12]); + } - // Cancel any pre-empted transitions. - else if (+i < id) { - o.state = ENDED; - o.timer.stop(); - o.on.call("cancel", node, node.__data__, o.index, o.group); - delete schedules[i]; - } - } + function click_handler_5() { + return /*click_handler_5*/ ctx[8](/*i*/ ctx[12]); + } - // Defer the first tick to end of the current frame; see d3/d3#1576. - // Note the transition may be canceled after start and before the first tick! - // Note this must be scheduled before the start event; see d3/d3-transition#16! - // Assuming this is successful, subsequent callbacks go straight to tick. - timeout(function() { - if (self.state === STARTED) { - self.state = RUNNING; - self.timer.restart(tick, self.delay, self.time); - tick(elapsed); - } - }); + let each_value_1 = DIRECTIONS; + let each_blocks = []; - // Dispatch the start event. - // Note this must be done before the tween are initialized. - self.state = STARTING; - self.on.call("start", node, node.__data__, self.index, self.group); - if (self.state !== STARTING) return; // interrupted - self.state = STARTED; + for (let i = 0; i < each_value_1.length; i += 1) { + each_blocks[i] = create_each_block_1$4(get_each_context_1$4(ctx, each_value_1, i)); + } - // Initialize the tween, deleting null tween. - tween = new Array(n = self.tween.length); - for (i = 0, j = -1; i < n; ++i) { - if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) { - tween[++j] = o; - } - } - tween.length = j + 1; - } + return { + c() { + details = element("details"); + summary = element("summary"); + t0 = text(t0_value); + t1 = space(); + button0 = element("button"); + button0.textContent = "↑"; + t3 = space(); + button1 = element("button"); + button1.textContent = "↓"; + t5 = space(); + button2 = element("button"); + button2.textContent = "X"; + t7 = space(); - function tick(elapsed) { - var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1), - i = -1, - n = tween.length; + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } - while (++i < n) { - tween[i].call(node, t); - } + t8 = space(); + attr(button0, "aria-label", "Swap with Hierarchy Above"); + attr(button0, "class", "svelte-cve01y"); + attr(button1, "aria-label", "Swap with Hierarchy Below"); + attr(button1, "class", "svelte-cve01y"); + attr(button2, "aria-label", "Remove Hierarchy"); + attr(button2, "class", "svelte-cve01y"); + attr(summary, "class", "svelte-cve01y"); + attr(details, "class", "BC-Hier-Details svelte-cve01y"); + }, + m(target, anchor) { + insert(target, details, anchor); + append(details, summary); + append(summary, t0); + append(summary, t1); + append(summary, button0); + append(summary, t3); + append(summary, button1); + append(summary, t5); + append(summary, button2); + append(details, t7); - // Dispatch the end event. - if (self.state === ENDING) { - self.on.call("end", node, node.__data__, self.index, self.group); - stop(); - } - } + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(details, null); + } - function stop() { - self.state = ENDED; - self.timer.stop(); - delete schedules[id]; - for (var i in schedules) return; // eslint-disable-line no-unused-vars - delete node.__transition; - } -} + append(details, t8); -function interrupt(node, name) { - var schedules = node.__transition, - schedule, - active, - empty = true, - i; + if (!mounted) { + dispose = [ + listen(button0, "click", click_handler_3), + listen(button1, "click", click_handler_4), + listen(button2, "click", click_handler_5) + ]; - if (!schedules) return; + mounted = true; + } + }, + p(new_ctx, dirty) { + ctx = new_ctx; + if (dirty & /*userHierarchies*/ 2 && t0_value !== (t0_value = (DIRECTIONS.map(func).flat().join(", ") || "Empty Hierarchy") + "")) set_data(t0, t0_value); - name = name == null ? null : name + ""; + if (dirty & /*DIRECTIONS, userHierarchies, splitAndTrim, plugin, ARROW_DIRECTIONS*/ 3) { + each_value_1 = DIRECTIONS; + let i; - for (i in schedules) { - if ((schedule = schedules[i]).name !== name) { empty = false; continue; } - active = schedule.state > STARTING && schedule.state < ENDING; - schedule.state = ENDED; - schedule.timer.stop(); - schedule.on.call(active ? "interrupt" : "cancel", node, node.__data__, schedule.index, schedule.group); - delete schedules[i]; - } + for (i = 0; i < each_value_1.length; i += 1) { + const child_ctx = get_each_context_1$4(ctx, each_value_1, i); - if (empty) delete node.__transition; -} + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + } else { + each_blocks[i] = create_each_block_1$4(child_ctx); + each_blocks[i].c(); + each_blocks[i].m(details, t8); + } + } -function selection_interrupt(name) { - return this.each(function() { - interrupt(this, name); - }); + for (; i < each_blocks.length; i += 1) { + each_blocks[i].d(1); + } + + each_blocks.length = each_value_1.length; + } + }, + d(detaching) { + if (detaching) detach(details); + destroy_each(each_blocks, detaching); + mounted = false; + run_all(dispose); + } + }; } -function tweenRemove(id, name) { - var tween0, tween1; - return function() { - var schedule = set(this, id), - tween = schedule.tween; +function create_fragment$4(ctx) { + let div4; + let div3; + let button0; + let div0; + let faplus; + let t0; + let button1; + let div1; + let faregtrashalt; + let t1; + let button2; + let div2; + let falistul; + let t2; + let current; + let mounted; + let dispose; + faplus = new FaPlus({}); + faregtrashalt = new FaRegTrashAlt({}); + falistul = new FaListUl({}); + let each_value = /*userHierarchies*/ ctx[1]; + let each_blocks = []; - // If this node shared tween with the previous node, - // just assign the updated shared tween and we’re done! - // Otherwise, copy-on-write. - if (tween !== tween0) { - tween1 = tween0 = tween; - for (var i = 0, n = tween1.length; i < n; ++i) { - if (tween1[i].name === name) { - tween1 = tween1.slice(); - tween1.splice(i, 1); - break; - } - } - } + for (let i = 0; i < each_value.length; i += 1) { + each_blocks[i] = create_each_block$4(get_each_context$4(ctx, each_value, i)); + } + + return { + c() { + div4 = element("div"); + div3 = element("div"); + button0 = element("button"); + div0 = element("div"); + create_component(faplus.$$.fragment); + t0 = space(); + button1 = element("button"); + div1 = element("div"); + create_component(faregtrashalt.$$.fragment); + t1 = space(); + button2 = element("button"); + div2 = element("div"); + create_component(falistul.$$.fragment); + t2 = space(); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + + attr(div0, "class", "icon svelte-cve01y"); + attr(button0, "aria-label", "Add New Hierarchy"); + attr(div1, "class", "icon svelte-cve01y"); + attr(button1, "aria-label", "Reset All Hierarchies"); + attr(div2, "class", "icon svelte-cve01y"); + attr(button2, "aria-label", "Show Hierarchies"); + attr(div3, "class", "GA-Buttons svelte-cve01y"); + }, + m(target, anchor) { + insert(target, div4, anchor); + append(div4, div3); + append(div3, button0); + append(button0, div0); + mount_component(faplus, div0, null); + append(div3, t0); + append(div3, button1); + append(button1, div1); + mount_component(faregtrashalt, div1, null); + append(div3, t1); + append(div3, button2); + append(button2, div2); + mount_component(falistul, div2, null); + append(div4, t2); - schedule.tween = tween1; - }; -} + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(div4, null); + } -function tweenFunction(id, name, value) { - var tween0, tween1; - if (typeof value !== "function") throw new Error; - return function() { - var schedule = set(this, id), - tween = schedule.tween; + current = true; - // If this node shared tween with the previous node, - // just assign the updated shared tween and we’re done! - // Otherwise, copy-on-write. - if (tween !== tween0) { - tween1 = (tween0 = tween).slice(); - for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) { - if (tween1[i].name === name) { - tween1[i] = t; - break; - } - } - if (i === n) tween1.push(t); - } + if (!mounted) { + dispose = [ + listen(button0, "click", /*click_handler*/ ctx[2]), + listen(button1, "click", /*click_handler_1*/ ctx[3]), + listen(button2, "click", /*click_handler_2*/ ctx[4]) + ]; - schedule.tween = tween1; - }; -} + mounted = true; + } + }, + p(ctx, [dirty]) { + if (dirty & /*DIRECTIONS, userHierarchies, splitAndTrim, plugin, ARROW_DIRECTIONS, swapItems*/ 3) { + each_value = /*userHierarchies*/ ctx[1]; + let i; -function transition_tween(name, value) { - var id = this._id; + for (i = 0; i < each_value.length; i += 1) { + const child_ctx = get_each_context$4(ctx, each_value, i); - name += ""; + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + } else { + each_blocks[i] = create_each_block$4(child_ctx); + each_blocks[i].c(); + each_blocks[i].m(div4, null); + } + } - if (arguments.length < 2) { - var tween = get$1(this.node(), id).tween; - for (var i = 0, n = tween.length, t; i < n; ++i) { - if ((t = tween[i]).name === name) { - return t.value; - } - } - return null; - } + for (; i < each_blocks.length; i += 1) { + each_blocks[i].d(1); + } - return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value)); + each_blocks.length = each_value.length; + } + }, + i(local) { + if (current) return; + transition_in(faplus.$$.fragment, local); + transition_in(faregtrashalt.$$.fragment, local); + transition_in(falistul.$$.fragment, local); + current = true; + }, + o(local) { + transition_out(faplus.$$.fragment, local); + transition_out(faregtrashalt.$$.fragment, local); + transition_out(falistul.$$.fragment, local); + current = false; + }, + d(detaching) { + if (detaching) detach(div4); + destroy_component(faplus); + destroy_component(faregtrashalt); + destroy_component(falistul); + destroy_each(each_blocks, detaching); + mounted = false; + run_all(dispose); + } + }; } -function tweenValue(transition, name, value) { - var id = transition._id; +function instance$4($$self, $$props, $$invalidate) { + + let { plugin } = $$props; + let { userHierarchies } = plugin.settings; - transition.each(function() { - var schedule = set(this, id); - (schedule.value || (schedule.value = {}))[name] = value.apply(this, arguments); - }); + const click_handler = async () => { + userHierarchies.push(blankUserHier()); + $$invalidate(1, userHierarchies); + await plugin.saveSettings(); + }; - return function(node) { - return get$1(node, id).value[name]; - }; -} + const click_handler_1 = async () => { + $$invalidate(1, userHierarchies = []); + await plugin.saveSettings(); + }; -function interpolate(a, b) { - var c; - return (typeof b === "number" ? interpolateNumber - : b instanceof color ? interpolateRgb - : (c = color(b)) ? (b = c, interpolateRgb) - : interpolateString)(a, b); -} + const click_handler_2 = () => new obsidian.Notice(userHierarchies.map(hierToStr).join("\n\n")); + const func = (hier, dir) => hier[dir].map(field => field); -function attrRemove(name) { - return function() { - this.removeAttribute(name); - }; -} + const click_handler_3 = async i => { + $$invalidate(1, userHierarchies = swapItems(i, i - 1, userHierarchies)); + await plugin.saveSettings(); + }; -function attrRemoveNS(fullname) { - return function() { - this.removeAttributeNS(fullname.space, fullname.local); - }; -} + const click_handler_4 = async i => { + $$invalidate(1, userHierarchies = swapItems(i, i + 1, userHierarchies)); + await plugin.saveSettings(); + }; -function attrConstant(name, interpolate, value1) { - var string00, - string1 = value1 + "", - interpolate0; - return function() { - var string0 = this.getAttribute(name); - return string0 === string1 ? null - : string0 === string00 ? interpolate0 - : interpolate0 = interpolate(string00 = string0, value1); - }; -} + const click_handler_5 = async i => { + userHierarchies.splice(i, 1); + $$invalidate(1, userHierarchies); + await plugin.saveSettings(); + }; -function attrConstantNS(fullname, interpolate, value1) { - var string00, - string1 = value1 + "", - interpolate0; - return function() { - var string0 = this.getAttributeNS(fullname.space, fullname.local); - return string0 === string1 ? null - : string0 === string00 ? interpolate0 - : interpolate0 = interpolate(string00 = string0, value1); - }; + const change_handler = async (i, dir, e) => { + $$invalidate(1, userHierarchies[i][dir] = splitAndTrim(e.target.value), userHierarchies); + await plugin.saveSettings(); + }; + + $$self.$$set = $$props => { + if ("plugin" in $$props) $$invalidate(0, plugin = $$props.plugin); + }; + + return [ + plugin, + userHierarchies, + click_handler, + click_handler_1, + click_handler_2, + func, + click_handler_3, + click_handler_4, + click_handler_5, + change_handler + ]; } -function attrFunction(name, interpolate, value) { - var string00, - string10, - interpolate0; - return function() { - var string0, value1 = value(this), string1; - if (value1 == null) return void this.removeAttribute(name); - string0 = this.getAttribute(name); - string1 = value1 + ""; - return string0 === string1 ? null - : string0 === string00 && string1 === string10 ? interpolate0 - : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1)); - }; +class UserHierarchies extends SvelteComponent { + constructor(options) { + super(); + if (!document.getElementById("svelte-cve01y-style")) add_css$3(); + init$1(this, options, instance$4, create_fragment$4, safe_not_equal, { plugin: 0 }); + } } -function attrFunctionNS(fullname, interpolate, value) { - var string00, - string10, - interpolate0; - return function() { - var string0, value1 = value(this), string1; - if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local); - string0 = this.getAttributeNS(fullname.space, fullname.local); - string1 = value1 + ""; - return string0 === string1 ? null - : string0 === string00 && string1 === string10 ? interpolate0 - : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1)); - }; +class BreadcrumbsSettingTab extends obsidian.PluginSettingTab { + constructor(app, plugin) { + super(app, plugin); + this.plugin = plugin; + } + display() { + const plugin = this.plugin; + const { settings } = plugin; + const { containerEl } = this; + const { userHierarchies } = settings; + containerEl.empty(); + containerEl.createEl("h2", { text: "Settings for Breadcrumbs plugin" }); + const fieldDetails = containerEl.createEl("details", { + cls: "field-details", + }); + fieldDetails.createEl("summary", { text: "Hierarchies" }); + fieldDetails.createEl("p", { + text: "Here you can set up different hierarchies you use in your vault. To add a new hierarchy, click the plus button. Then, fill in the field names of your hierachy into the 3 boxes that appear. The ↑ field is for parent relations, the → field is for siblings, and ↓ is for child relations.", + }); + fieldDetails.createEl("p", { + text: "For each direction (up, same, down), you can enter multiple field names in a comma seperated list. For example: `parent, broader, upper`", + }); + new UserHierarchies({ + target: fieldDetails, + props: { plugin }, + }); + const hierarchyNoteDetails = containerEl.createEl("details"); + hierarchyNoteDetails.createEl("summary", { text: "Hierarchy Notes" }); + new obsidian.Setting(hierarchyNoteDetails) + .setName("Hierarchy Note(s)") + .setDesc("A list of notes used to create external Breadcrumb structures.") + .addText((text) => { + let finalValue; + text + .setPlaceholder("Hierarchy Note(s)") + .setValue([settings.hierarchyNotes].flat().join(", ")) + .onChange(async (value) => { + finalValue = splitAndTrim(value); + }); + text.inputEl.onblur = async () => { + if (finalValue[0] === "") { + settings.hierarchyNotes = finalValue; + await plugin.saveSettings(); + } + else if (finalValue.every((note) => isInVault(this.app, note))) { + settings.hierarchyNotes = finalValue; + await plugin.saveSettings(); + } + else { + new obsidian.Notice("Atleast one of the notes is not in your vault"); + } + }; + }); + new obsidian.Setting(hierarchyNoteDetails) + .setName("Hierarchy Note Up Field Name") + .setDesc("Using the breadcrumbs generated by the hierarchy note, which ↑ type should they count as? This has to be one of the ↑ types of one of your existing hierarchies. If you want it to be something else, you can make a new hierarchy just for it.") + .addText((text) => { + let finalValue = settings.hierarchyNoteUpFieldName; + text.setPlaceholder("").setValue(settings.hierarchyNoteUpFieldName); + text.inputEl.onblur = async () => { + finalValue = text.getValue(); + if (finalValue === "") { + settings.hierarchyNoteUpFieldName = finalValue; + await plugin.saveSettings(); + } + else { + const downFieldNames = userHierarchies + .map((hier) => hier.up) + .flat(3); + debug(settings, { downFieldNames, finalValue }); + if (downFieldNames.includes(finalValue)) { + settings.hierarchyNoteUpFieldName = finalValue; + await plugin.saveSettings(); + } + else { + new obsidian.Notice("The field name must be one of the exisitng ↓ fields in your hierarchies."); + } + } + }; + }); + new obsidian.Setting(hierarchyNoteDetails) + .setName("Hierarchy Note Down Field Name") + .setDesc("Using the breadcrumbs generated by the hierarchy note, which ↓ type should they count as? This has to be one of the ↓ types of one of your existing hierarchies. If you want it to be something else, you can make a new hierarchy just for it.") + .addText((text) => { + let finalValue = settings.hierarchyNoteDownFieldName; + text.setPlaceholder("").setValue(settings.hierarchyNoteDownFieldName); + text.inputEl.onblur = async () => { + finalValue = text.getValue(); + if (finalValue === "") { + settings.hierarchyNoteDownFieldName = finalValue; + await plugin.saveSettings(); + } + else { + const downFieldNames = userHierarchies + .map((hier) => hier.down) + .flat(3); + debug(settings, { downFieldNames, finalValue }); + if (downFieldNames.includes(finalValue)) { + settings.hierarchyNoteDownFieldName = finalValue; + await plugin.saveSettings(); + } + else { + new obsidian.Notice("The field name must be one of the exisitng ↓ fields in your hierarchies."); + } + } + }; + }); + const generalDetails = containerEl.createEl("details"); + generalDetails.createEl("summary", { text: "General Options" }); + new obsidian.Setting(generalDetails) + .setName("CSV Breadcrumb Paths") + .setDesc("The file path of a csv files with breadcrumbs information.") + .addText((text) => { + text.setValue(settings.CSVPaths); + text.inputEl.onblur = async () => { + settings.CSVPaths = text.inputEl.value; + await plugin.saveSettings(); + }; + }); + new obsidian.Setting(generalDetails) + .setName("Refresh Index on Note Change") + .setDesc("Refresh the Breadcrumbs index data everytime you change notes. This is how Breadcrumbs used to work, making it responsive to changes immediately after changing notes. However, this can be very slow on large vaults, so it is off by default.") + .addToggle((toggle) => toggle + .setValue(settings.refreshIndexOnActiveLeafChange) + .onChange(async (value) => { + settings.refreshIndexOnActiveLeafChange = value; + await plugin.saveSettings(); + })); + new obsidian.Setting(generalDetails) + .setName("Fields used for Alternative note names (Aliases)") + .setDesc("A comma-separated list of fields you use to specify note name aliases. These fields will be checked, in order, and be used to display an alternate note title in both the list/matrix view, and trail/grid view. This field will probably be `alias` or `aliases`, but it can be anything, like `title`, for example.") + .addText((text) => { + let finalValue; + text.setValue(settings.altLinkFields.join(", ")).onChange((str) => { + finalValue = str; + }); + text.inputEl.onblur = async () => { + settings.altLinkFields = splitAndTrim(finalValue); + await plugin.saveSettings(); + }; + }); + new obsidian.Setting(generalDetails) + .setName("Use yaml or inline fields for hierarchy data") + .setDesc("If enabled, Breadcrumbs will make it's hierarchy using yaml fields, and inline fields (if you have Dataview enabled). If this is disabled, it will only use Juggl links for it's metadata (See below).") + .addToggle((toggle) => toggle.setValue(settings.useAllMetadata).onChange(async (value) => { + settings.useAllMetadata = value; + await plugin.saveSettings(); + await plugin.refreshIndex(); + })); + new obsidian.Setting(generalDetails) + .setName("Use Juggl link syntax without having Juggl installed.") + .setDesc("Should Breadcrumbs look for [Juggl links](https://juggl.io/Link+Types) even if you don't have Juggl installed? If you do have Juggl installed, it will always look for Juggl links.") + .addToggle((toggle) => toggle + .setValue(settings.parseJugglLinksWithoutJuggl) + .onChange(async (value) => { + settings.parseJugglLinksWithoutJuggl = value; + await plugin.saveSettings(); + })); + if (this.app.plugins.plugins.dataview !== undefined) { + new obsidian.Setting(generalDetails) + .setName("Dataview Wait Time") + .setDesc('Enter an integer number of seconds to wait for the Dataview Index to load. The larger your vault, the longer it will take. If you see an error in the console saying "Cannot destructure currGraphs of undefined", try making this time longer. If you don\'t get that error, you can make this time shorter to make the Breadcrumbs load faster. The default is 5 seconds.') + .addText((text) => text + .setPlaceholder("Seconds") + .setValue((settings.dvWaitTime / 1000).toString()) + .onChange(async (value) => { + const num = Number(value); + if (num > 0) { + settings.dvWaitTime = num * 1000; + await plugin.saveSettings(); + } + else { + new obsidian.Notice("The interval must be a non-negative number"); + } + })); + } + new obsidian.Setting(generalDetails) + .setName("Refresh Interval") + .setDesc("Enter an integer number of seconds to wait before Breadcrumbs auto-refreshes its data. This would update the matrix view and the trail if either are affected. (Set to 0 to disable autorefreshing)") + .addText((text) => text + .setPlaceholder("Seconds") + .setValue(settings.refreshIntervalTime.toString()) + .onChange(async (value) => { + clearInterval(plugin.refreshIntervalID); + const num = Number(value); + if (num > 0) { + settings.refreshIntervalTime = num; + await plugin.saveSettings(); + plugin.refreshIntervalID = window.setInterval(async () => { + plugin.currGraphs = await plugin.initGraphs(); + if (settings.showTrail) { + await plugin.drawTrail(); + } + if (plugin.getActiveMatrixView()) { + await plugin.getActiveMatrixView().draw(); + } + }, num * 1000); + plugin.registerInterval(plugin.refreshIntervalID); + } + else if (num === 0) { + settings.refreshIntervalTime = num; + await plugin.saveSettings(); + clearInterval(plugin.refreshIntervalID); + } + else { + new obsidian.Notice("The interval must be a non-negative number"); + } + })); + const MLViewDetails = containerEl.createEl("details"); + MLViewDetails.createEl("summary", { text: "Matrix/List View" }); + new obsidian.Setting(MLViewDetails) + .setName("Show Matrix or List view by default") + .setDesc("When Obsidian first loads, which view should it show? On = Matrix, Off = List") + .addToggle((toggle) => toggle.setValue(settings.defaultView).onChange(async (value) => { + settings.defaultView = value; + await plugin.saveSettings(); + })); + // TODO I don't think this setting works anymore. I removed it's functionality when adding multiple hierarchies + new obsidian.Setting(MLViewDetails) + .setName("Show all field names or just relation types") + .setDesc("This changes the headers in matrix/list view. You can have the headers be the list of metadata fields for each relation type (e.g. `parent, broader, upper`). Or you can have them just be the name of the relation type, i.e. 'Parent', 'Sibling', 'Child'. On = show the full list of names.") + .addToggle((toggle) => toggle.setValue(settings.showNameOrType).onChange(async (value) => { + settings.showNameOrType = value; + await plugin.saveSettings(); + await plugin.getActiveMatrixView().draw(); + })); + new obsidian.Setting(MLViewDetails) + .setName("Show Relationship Type") + .setDesc("Show whether a link is real or implied. A real link is one you explicitly put in a note. E.g. parent:: [[Note]]. An implied link is the reverse of a real link. For example, if A is the real parent of B, then B must be the implied child of A.") + .addToggle((toggle) => toggle.setValue(settings.showRelationType).onChange(async (value) => { + settings.showRelationType = value; + await plugin.saveSettings(); + await plugin.getActiveMatrixView().draw(); + })); + new obsidian.Setting(MLViewDetails) + .setName("Filter Implied Siblings") + .setDesc("Implied siblings are: 1) notes with the same parent, or 2) notes that are real siblings. This setting only applies to type 1 implied siblings. If enabled, Breadcrumbs will filter type 1 implied siblings so that they not only share the same parent, but the parent relation has the exact same type. For example, the two real relations B --parent-> A, and A --parent-> A create an implied sibling between B and C (they have the same parent, A). The two real relations B --parent-> A, and A --up-> A create an implied sibling between B and C (they also have the same parent, A). But if this setting is turned on, the second implied sibling would not show, because the parent types are differnet (parent versus up).") + .addToggle((toggle) => toggle + .setValue(settings.filterImpliedSiblingsOfDifferentTypes) + .onChange(async (value) => { + settings.filterImpliedSiblingsOfDifferentTypes = value; + await plugin.saveSettings(); + await plugin.getActiveMatrixView().draw(); + })); + new obsidian.Setting(MLViewDetails) + .setName("Open View in Right or Left side") + .setDesc("When loading the matrix view, should it open on the left or right side leaf? On = Right, Off = Left.") + .addToggle((toggle) => toggle.setValue(settings.rlLeaf).onChange(async (value) => { + var _a; + settings.rlLeaf = value; + await plugin.saveSettings(); + await ((_a = plugin.getActiveMatrixView()) === null || _a === void 0 ? void 0 : _a.onClose()); + await openView(this.app, MATRIX_VIEW, MatrixView); + })); + const trailDetails = containerEl.createEl("details"); + trailDetails.createEl("summary", { text: "Trail/Grid" }); + new obsidian.Setting(trailDetails) + .setName("Show Breadcrumbs") + .setDesc("Show a trail of notes leading from your index note down to the current note you are in (if a path exists)") + .addToggle((toggle) => toggle.setValue(settings.showTrail).onChange(async (value) => { + settings.showTrail = value; + await plugin.saveSettings(); + await plugin.drawTrail(); + })); + const limitTrailFieldsDiv = trailDetails.createDiv({ + cls: "limit-ML-fields", + }); + limitTrailFieldsDiv.createEl("strong", { + text: "Limit M/L View to only show certain fields", + }); + const checkboxDiv = limitTrailFieldsDiv.createDiv({ cls: "checkboxes" }); + function drawLimitTrailCheckboxes(div) { + checkboxDiv.empty(); + const checkboxStates = settings.limitTrailCheckboxStates; + settings.userHierarchies.forEach((userHier) => { + userHier.up.forEach(async (field) => { + if (field === "") + return; + // First sort out limitTrailCheckboxStates + if (checkboxStates[field] === undefined) { + checkboxStates[field] = true; + await plugin.saveSettings(); + } + const cbDiv = div.createDiv(); + const checkedQ = checkboxStates[field]; + const cb = cbDiv.createEl("input", { + type: "checkbox", + attr: { id: field }, + }); + cb.checked = checkedQ; + cbDiv.createEl("label", { + text: field, + attr: { for: field }, + }); + cb.addEventListener("change", async (event) => { + checkboxStates[field] = cb.checked; + await plugin.saveSettings(); + console.log(settings.limitTrailCheckboxStates); + }); + }); + }); + } + drawLimitTrailCheckboxes(checkboxDiv); + new obsidian.Setting(trailDetails) + .setName("Field name to hide trail") + .setDesc("A note-specific toggle to hide the Trail View. By default, it is `hide-trail`. So, to hide the trail on a specific note, add the field to that note's yaml, like so: `hide-trail: {{anything}}`.") + .addText((text) => { + text.setValue(settings.hideTrailFieldName); + text.inputEl.onblur = async () => { + settings.hideTrailFieldName = text.getValue(); + await plugin.saveSettings(); + }; + }); + new obsidian.Setting(trailDetails) + .setName("Trail or Table or Both") + .setDesc("Wether to show the regular breadcrumb trails, the table view, neither, or both. 1 = Only Trail, 2 = Only Grid, 3 = Both") + .addText((text) => { + text + .setValue(settings.trailOrTable.toString()) + .onChange(async (value) => { + const num = parseInt(value); + if ([1, 2, 3].includes(num)) { + settings.trailOrTable = num; + await plugin.saveSettings(); + await plugin.drawTrail(); + } + else { + new obsidian.Notice("The value has to be 1, 2, or 3"); + } + }); + }); + new obsidian.Setting(trailDetails) + .setName("Grid view dots") + .setDesc("If the grid view is visible, shows dots based on the file size of each cell.") + .addToggle((toggle) => toggle.setValue(settings.gridDots).onChange(async (value) => { + settings.gridDots = value; + await plugin.saveSettings(); + await plugin.drawTrail(); + })); + const dotsColour = trailDetails.createDiv(); + dotsColour.createEl("h4", { + text: "Dots colour", + }); + const dotsColourPicker = dotsColour.createEl("input", { + type: "color", + }); + dotsColourPicker.value = settings.dotsColour; + dotsColourPicker.addEventListener("change", async () => { + settings.dotsColour = dotsColourPicker.value; + await plugin.saveSettings(); + }); + new obsidian.Setting(trailDetails) + .setName("Grid view heatmap") + .setDesc("If the grid view is visible, change the background colour of squares based on the number of children leaving that note.") + .addToggle((toggle) => toggle.setValue(settings.gridHeatmap).onChange(async (value) => { + settings.gridHeatmap = value; + await plugin.saveSettings(); + await plugin.drawTrail(); + })); + const heatmapColour = trailDetails.createDiv(); + heatmapColour.createEl("h4", { + text: "Heat map colour", + }); + const heatmapColourPicker = heatmapColour.createEl("input", { + type: "color", + }); + heatmapColourPicker.value = settings.heatmapColour; + heatmapColourPicker.addEventListener("change", async () => { + settings.heatmapColour = heatmapColourPicker.value; + await plugin.saveSettings(); + }); + new obsidian.Setting(trailDetails) + .setName("Index/Home Note(s)") + .setDesc("The note that all of your other notes lead back to. The parent of all your parent notes. Just enter the name. So if your index note is `000 Home.md`, enter `000 Home`. You can also have multiple index notes (comma-separated list). The breadcrumb trail will show the shortest path back to any one of the index notes listed. You can now leave this field empty, meaning the trail will show a path going as far up the parent-tree as possible.") + .addText((text) => { + let finalValue; + text + .setPlaceholder("Index Note") + .setValue([settings.indexNote].flat().join(", ")) + .onChange(async (value) => { + finalValue = splitAndTrim(value); + }); + text.inputEl.onblur = async () => { + // TODO Refactor this to general purpose isInVault function + if (finalValue[0] === "") { + settings.indexNote = finalValue; + await plugin.saveSettings(); + } + else if (finalValue.every((index) => isInVault(this.app, index))) { + settings.indexNote = finalValue; + await plugin.saveSettings(); + } + else { + new obsidian.Notice(`Atleast one of the notes is not in your vault`); + } + }; + }); + new obsidian.Setting(trailDetails) + .setName("Default: All or Shortest") + .setDesc("If multiple paths are found going up the parent tree, should all of them be shown by default, or only the shortest? On = all, off = shortest") + .addToggle((toggle) => toggle.setValue(settings.showAll).onChange(async (value) => { + settings.showAll = value; + await plugin.saveSettings(); + await plugin.drawTrail(); + })); + new obsidian.Setting(trailDetails) + .setName("Breadcrumb trail seperator") + .setDesc("The character to show between crumbs in the breadcrumb trail. The default is '→'") + .addText((text) => text + .setPlaceholder("→") + .setValue(settings.trailSeperator) + .onChange(async (value) => { + settings.trailSeperator = value; + await plugin.saveSettings(); + await plugin.drawTrail(); + })); + new obsidian.Setting(trailDetails) + .setName("No path found message") + .setDesc("The text to display when no path to the index note was found, or when the current note has no parent (this happens if you haven't chosen an index note)") + .addText((text) => text + .setPlaceholder(`No path to index note was found`) + .setValue(settings.noPathMessage) + .onChange(async (value) => { + settings.noPathMessage = value; + await plugin.saveSettings(); + await plugin.drawTrail(); + })); + new obsidian.Setting(trailDetails) + .setName("Respect Readable Line Length") + .setDesc("Should the breadcrumbs trail adjust its width to the readable line length, or use as much space as possible? On = use readable line length.") + .addToggle((toggle) => toggle + .setValue(settings.respectReadableLineLength) + .onChange(async (value) => { + settings.respectReadableLineLength = value; + await plugin.saveSettings(); + await plugin.drawTrail(); + })); + const writeBCsToFileDetails = containerEl.createEl("details"); + writeBCsToFileDetails.createEl("summary", { + text: "Write Breadcrumbs to File", + }); + const limitWriteBCDiv = writeBCsToFileDetails.createDiv({ + cls: "limit-ML-fields", + }); + limitWriteBCDiv.createEl("strong", { + text: "Limit to only write certain fields to files", + }); + const limitWriteBCCheckboxDiv = limitWriteBCDiv.createDiv({ + cls: "checkboxes", + }); + function drawLimitWriteBCCheckboxes(div) { + limitWriteBCCheckboxDiv.empty(); + const checkboxStates = settings.limitWriteBCCheckboxStates; + settings.userHierarchies.forEach((userHier) => { + DIRECTIONS.forEach((dir) => { + userHier[dir].forEach(async (field) => { + if (field === "") + return; + // First sort out limitWriteBCCheckboxStates + if (checkboxStates[field] === undefined) { + checkboxStates[field] = true; + await plugin.saveSettings(); + } + const cbDiv = div.createDiv(); + const checkedQ = checkboxStates[field]; + const cb = cbDiv.createEl("input", { + type: "checkbox", + attr: { id: field }, + }); + cb.checked = checkedQ; + cbDiv.createEl("label", { + text: field, + attr: { for: field }, + }); + cb.addEventListener("change", async (event) => { + checkboxStates[field] = cb.checked; + await plugin.saveSettings(); + console.log(settings.limitWriteBCCheckboxStates); + }); + }); + }); + }); + } + drawLimitWriteBCCheckboxes(limitWriteBCCheckboxDiv); + new obsidian.Setting(writeBCsToFileDetails) + .setName("Show the `Write Breadcrumbs to ALL Files` command") + .setDesc("This command attempts to update ALL files with implied breadcrumbs pointing to them. So, it is not shown by default (even though it has 3 confirmation boxes to ensure you want to run it") + .addToggle((toggle) => toggle.setValue(settings.showWriteAllBCsCmd).onChange(async (value) => { + settings.showWriteAllBCsCmd = value; + await plugin.saveSettings(); + })); + const visModalDetails = containerEl.createEl("details"); + visModalDetails.createEl("summary", { text: "Visualisation Modal" }); + new obsidian.Setting(visModalDetails) + .setName("Default Visualisation Type") + .setDesc("Which visualisation to show by defualt") + .addDropdown((cb) => { + VISTYPES.forEach((option) => { + cb.addOption(option, option); + }); + cb.setValue(settings.visGraph); + cb.onChange(async (value) => { + settings.visGraph = value; + await plugin.saveSettings(); + }); + }); + new obsidian.Setting(visModalDetails) + .setName("Default Relation") + .setDesc("Which relation type to show first when opening the modal") + .addDropdown((cb) => { + RELATIONS.forEach((option) => { + cb.addOption(option, option); + }); + cb.setValue(settings.visRelation); + cb.onChange(async (value) => { + settings.visRelation = value; + await plugin.saveSettings(); + }); + }); + new obsidian.Setting(visModalDetails) + .setName("Default Real/Closed") + .setDesc("Show the real or closed graph by default") + .addDropdown((cb) => { + REAlCLOSED.forEach((option) => { + cb.addOption(option, option); + }); + cb.setValue(settings.visClosed); + cb.onChange(async (value) => { + settings.visClosed = value; + await plugin.saveSettings(); + }); + }); + new obsidian.Setting(visModalDetails) + .setName("Default Unlinked") + .setDesc("Show all nodes or only those which have links by default") + .addDropdown((cb) => { + ALLUNLINKED.forEach((option) => { + cb.addOption(option, option); + }); + cb.setValue(settings.visAll); + cb.onChange(async (value) => { + settings.visAll = value; + await plugin.saveSettings(); + }); + }); + const createIndexDetails = containerEl.createEl("details"); + createIndexDetails.createEl("summary", { text: "Create Index" }); + new obsidian.Setting(createIndexDetails) + .setName("Add wiklink brackets") + .setDesc("When creating an index, should it wrap the note name in wikilinks `[[]]` or not. On = yes, off = no.") + .addToggle((toggle) => toggle.setValue(settings.wikilinkIndex).onChange(async (value) => { + settings.wikilinkIndex = value; + await plugin.saveSettings(); + })); + new obsidian.Setting(createIndexDetails) + .setName("Show aliases of notes in index") + .setDesc("Show the aliases of each note in brackets. On = yes, off = no.") + .addToggle((toggle) => toggle.setValue(settings.aliasesInIndex).onChange(async (value) => { + settings.aliasesInIndex = value; + await plugin.saveSettings(); + })); + const debugDetails = containerEl.createEl("details"); + debugDetails.createEl("summary", { text: "Debugging" }); + new obsidian.Setting(debugDetails) + .setName("Debug Mode") + .setDesc("Toggling this on will enable a few console logs to appear when use the matrix/list view, or the trail.") + .addToggle((toggle) => toggle.setValue(settings.debugMode).onChange(async (value) => { + settings.debugMode = value; + await plugin.saveSettings(); + })); + new obsidian.Setting(debugDetails) + .setName("Super Debug Mode") + .setDesc("Toggling this on will enable ALOT of console logs") + .addToggle((toggle) => toggle.setValue(settings.superDebugMode).onChange(async (value) => { + settings.superDebugMode = value; + await plugin.saveSettings(); + })); + debugDetails.createEl("button", { text: "Console log `settings`" }, (el) => { + el.addEventListener("click", () => console.log(settings)); + }); + new KoFi({ target: this.containerEl }); + } } -function transition_attr(name, value) { - var fullname = namespace(name), i = fullname === "transform" ? interpolateTransformSvg : interpolate; - return this.attrTween(name, typeof value === "function" - ? (fullname.local ? attrFunctionNS : attrFunction)(fullname, i, tweenValue(this, "attr." + name, value)) - : value == null ? (fullname.local ? attrRemoveNS : attrRemove)(fullname) - : (fullname.local ? attrConstantNS : attrConstant)(fullname, i, value)); -} +/* src\Components\Stats.svelte generated by Svelte v3.35.0 */ -function attrInterpolate(name, i) { - return function(t) { - this.setAttribute(name, i.call(this, t)); - }; +function add_css$2() { + var style = element("style"); + style.id = "svelte-rb5mhu-style"; + style.textContent = "table.svelte-rb5mhu{border-collapse:collapse}td.svelte-rb5mhu:first-child{text-align:right}td.svelte-rb5mhu,th.svelte-rb5mhu{padding:3px;border:1px solid var(--background-modifier-border);white-space:pre-line}"; + append(document.head, style); } -function attrInterpolateNS(fullname, i) { - return function(t) { - this.setAttributeNS(fullname.space, fullname.local, i.call(this, t)); - }; +function get_each_context$3(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[23] = list[i]; + return child_ctx; } -function attrTweenNS(fullname, value) { - var t0, i0; - function tween() { - var i = value.apply(this, arguments); - if (i !== i0) t0 = (i0 = i) && attrInterpolateNS(fullname, i); - return t0; - } - tween._value = value; - return tween; +function get_each_context_1$3(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[23] = list[i]; + return child_ctx; } -function attrTween(name, value) { - var t0, i0; - function tween() { - var i = value.apply(this, arguments); - if (i !== i0) t0 = (i0 = i) && attrInterpolate(name, i); - return t0; - } - tween._value = value; - return tween; +function get_each_context_2$1(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[23] = list[i]; + return child_ctx; } -function transition_attrTween(name, value) { - var key = "attr." + name; - if (arguments.length < 2) return (key = this.tween(key)) && key._value; - if (value == null) return this.tween(key, null); - if (typeof value !== "function") throw new Error; - var fullname = namespace(name); - return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value)); +function get_each_context_3(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[30] = list[i]; + child_ctx[32] = i; + return child_ctx; } -function delayFunction(id, value) { - return function() { - init(this, id).delay = +value.apply(this, arguments); - }; +function get_each_context_4(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[23] = list[i]; + return child_ctx; } -function delayConstant(id, value) { - return value = +value, function() { - init(this, id).delay = value; - }; +function get_each_context_5(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[23] = list[i]; + return child_ctx; } -function transition_delay(value) { - var id = this._id; - - return arguments.length - ? this.each((typeof value === "function" - ? delayFunction - : delayConstant)(id, value)) - : get$1(this.node(), id).delay; +function get_each_context_6(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[23] = list[i]; + return child_ctx; } -function durationFunction(id, value) { - return function() { - set(this, id).duration = +value.apply(this, arguments); - }; -} +// (96:6) {#each ["up", "same", "down"] as dir} +function create_each_block_6(ctx) { + let td; + let t_value = /*data*/ ctx[1][/*i*/ ctx[32]][/*dir*/ ctx[23]].Merged.nodes.length + ""; + let t; + let td_aria_label_value; + let mounted; + let dispose; -function durationConstant(id, value) { - return value = +value, function() { - set(this, id).duration = value; - }; -} + function click_handler() { + return /*click_handler*/ ctx[4](/*i*/ ctx[32], /*dir*/ ctx[23]); + } -function transition_duration(value) { - var id = this._id; + return { + c() { + td = element("td"); + t = text(t_value); + attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1][/*i*/ ctx[32]][/*dir*/ ctx[23]].Merged.nodesStr); + attr(td, "class", "svelte-rb5mhu"); + }, + m(target, anchor) { + insert(target, td, anchor); + append(td, t); - return arguments.length - ? this.each((typeof value === "function" - ? durationFunction - : durationConstant)(id, value)) - : get$1(this.node(), id).duration; + if (!mounted) { + dispose = listen(td, "click", click_handler); + mounted = true; + } + }, + p(new_ctx, dirty) { + ctx = new_ctx; + }, + d(detaching) { + if (detaching) detach(td); + mounted = false; + dispose(); + } + }; } -function easeConstant(id, value) { - if (typeof value !== "function") throw new Error; - return function() { - set(this, id).ease = value; - }; -} +// (128:6) {#each ["up", "same", "down"] as dir} +function create_each_block_5(ctx) { + let td; + let t_value = /*data*/ ctx[1][/*i*/ ctx[32]][/*dir*/ ctx[23]].Merged.edges.length + ""; + let t; + let td_aria_label_value; + let mounted; + let dispose; -function transition_ease(value) { - var id = this._id; + function click_handler_2() { + return /*click_handler_2*/ ctx[6](/*i*/ ctx[32], /*dir*/ ctx[23]); + } - return arguments.length - ? this.each(easeConstant(id, value)) - : get$1(this.node(), id).ease; -} + return { + c() { + td = element("td"); + t = text(t_value); + attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1][/*i*/ ctx[32]][/*dir*/ ctx[23]].Merged.edgesStr); + attr(td, "class", "svelte-rb5mhu"); + }, + m(target, anchor) { + insert(target, td, anchor); + append(td, t); -function easeVarying(id, value) { - return function() { - var v = value.apply(this, arguments); - if (typeof v !== "function") throw new Error; - set(this, id).ease = v; - }; + if (!mounted) { + dispose = listen(td, "click", click_handler_2); + mounted = true; + } + }, + p(new_ctx, dirty) { + ctx = new_ctx; + }, + d(detaching) { + if (detaching) detach(td); + mounted = false; + dispose(); + } + }; } -function transition_easeVarying(value) { - if (typeof value !== "function") throw new Error; - return this.each(easeVarying(this._id, value)); -} +// (160:6) {#each ["up", "same", "down"] as dir} +function create_each_block_4(ctx) { + let td; + let t_value = /*data*/ ctx[1][/*i*/ ctx[32]][/*dir*/ ctx[23]].Implied.edges.length + ""; + let t; + let td_aria_label_value; + let mounted; + let dispose; -function transition_filter(match) { - if (typeof match !== "function") match = matcher(match); + function click_handler_4() { + return /*click_handler_4*/ ctx[8](/*i*/ ctx[32], /*dir*/ ctx[23]); + } - for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) { - if ((node = group[i]) && match.call(node, node.__data__, i, group)) { - subgroup.push(node); - } - } - } + return { + c() { + td = element("td"); + t = text(t_value); + attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1][/*i*/ ctx[32]][/*dir*/ ctx[23]].Implied.edgesStr); + attr(td, "class", "svelte-rb5mhu"); + }, + m(target, anchor) { + insert(target, td, anchor); + append(td, t); - return new Transition(subgroups, this._parents, this._name, this._id); + if (!mounted) { + dispose = listen(td, "click", click_handler_4); + mounted = true; + } + }, + p(new_ctx, dirty) { + ctx = new_ctx; + }, + d(detaching) { + if (detaching) detach(td); + mounted = false; + dispose(); + } + }; } -function transition_merge(transition) { - if (transition._id !== this._id) throw new Error; - - for (var groups0 = this._groups, groups1 = transition._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { - for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) { - if (node = group0[i] || group1[i]) { - merge[i] = node; - } - } - } +// (90:2) {#each userHierarchies as hier, i} +function create_each_block_3(ctx) { + let tr0; + let td0; + let t0_value = /*hierStrs*/ ctx[2][/*i*/ ctx[32]] + ""; + let t0; + let t1; + let td1; + let t3; + let t4; + let td2; - for (; j < m0; ++j) { - merges[j] = groups0[j]; - } + let t5_value = [ + .../*data*/ ctx[1][/*i*/ ctx[32]].up.Merged.nodes, + .../*data*/ ctx[1][/*i*/ ctx[32]].same.Merged.nodes, + .../*data*/ ctx[1][/*i*/ ctx[32]].down.Merged.nodes + ].length + ""; - return new Transition(merges, this._parents, this._name, this._id); -} + let t5; + let td2_aria_label_value; + let t6; + let tr1; + let td3; + let t8; + let t9; + let td4; -function start(name) { - return (name + "").trim().split(/^|\s+/).every(function(t) { - var i = t.indexOf("."); - if (i >= 0) t = t.slice(0, i); - return !t || t === "start"; - }); -} + let t10_value = [ + .../*data*/ ctx[1][/*i*/ ctx[32]].up.Merged.edges, + .../*data*/ ctx[1][/*i*/ ctx[32]].same.Merged.edges, + .../*data*/ ctx[1][/*i*/ ctx[32]].down.Merged.edges + ].length + ""; -function onFunction(id, name, listener) { - var on0, on1, sit = start(name) ? init : set; - return function() { - var schedule = sit(this, id), - on = schedule.on; + let t10; + let td4_aria_label_value; + let t11; + let tr2; + let td5; + let t13; + let t14; + let td6; - // If this node shared a dispatch with the previous node, - // just assign the updated shared dispatch and we’re done! - // Otherwise, copy-on-write. - if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener); + let t15_value = [ + .../*data*/ ctx[1][/*i*/ ctx[32]].up.Implied.edges, + .../*data*/ ctx[1][/*i*/ ctx[32]].same.Implied.edges, + .../*data*/ ctx[1][/*i*/ ctx[32]].down.Implied.edges + ].length + ""; - schedule.on = on1; - }; -} + let t15; + let td6_aria_label_value; + let mounted; + let dispose; + let each_value_6 = ["up", "same", "down"]; + let each_blocks_2 = []; -function transition_on(name, listener) { - var id = this._id; + for (let i = 0; i < 3; i += 1) { + each_blocks_2[i] = create_each_block_6(get_each_context_6(ctx, each_value_6, i)); + } - return arguments.length < 2 - ? get$1(this.node(), id).on.on(name) - : this.each(onFunction(id, name, listener)); -} + function click_handler_1() { + return /*click_handler_1*/ ctx[5](/*i*/ ctx[32]); + } -function removeFunction(id) { - return function() { - var parent = this.parentNode; - for (var i in this.__transition) if (+i !== id) return; - if (parent) parent.removeChild(this); - }; -} + let each_value_5 = ["up", "same", "down"]; + let each_blocks_1 = []; -function transition_remove() { - return this.on("end.remove", removeFunction(this._id)); -} + for (let i = 0; i < 3; i += 1) { + each_blocks_1[i] = create_each_block_5(get_each_context_5(ctx, each_value_5, i)); + } -function transition_select(select) { - var name = this._name, - id = this._id; + function click_handler_3() { + return /*click_handler_3*/ ctx[7](/*i*/ ctx[32]); + } - if (typeof select !== "function") select = selector(select); + let each_value_4 = ["up", "same", "down"]; + let each_blocks = []; - for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) { - if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) { - if ("__data__" in node) subnode.__data__ = node.__data__; - subgroup[i] = subnode; - schedule(subgroup[i], name, id, i, subgroup, get$1(node, id)); - } - } - } + for (let i = 0; i < 3; i += 1) { + each_blocks[i] = create_each_block_4(get_each_context_4(ctx, each_value_4, i)); + } - return new Transition(subgroups, this._parents, name, id); -} + function click_handler_5() { + return /*click_handler_5*/ ctx[9](/*i*/ ctx[32]); + } -function transition_selectAll(select) { - var name = this._name, - id = this._id; + return { + c() { + tr0 = element("tr"); + td0 = element("td"); + t0 = text(t0_value); + t1 = space(); + td1 = element("td"); + td1.textContent = "Nodes"; + t3 = space(); - if (typeof select !== "function") select = selectorAll(select); + for (let i = 0; i < 3; i += 1) { + each_blocks_2[i].c(); + } - for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { - if (node = group[i]) { - for (var children = select.call(node, node.__data__, i, group), child, inherit = get$1(node, id), k = 0, l = children.length; k < l; ++k) { - if (child = children[k]) { - schedule(child, name, id, k, children, inherit); - } - } - subgroups.push(children); - parents.push(node); - } - } - } + t4 = space(); + td2 = element("td"); + t5 = text(t5_value); + t6 = space(); + tr1 = element("tr"); + td3 = element("td"); + td3.textContent = "Real Edges"; + t8 = space(); - return new Transition(subgroups, parents, name, id); -} + for (let i = 0; i < 3; i += 1) { + each_blocks_1[i].c(); + } -var Selection = selection.prototype.constructor; + t9 = space(); + td4 = element("td"); + t10 = text(t10_value); + t11 = space(); + tr2 = element("tr"); + td5 = element("td"); + td5.textContent = "Implied Edges"; + t13 = space(); -function transition_selection() { - return new Selection(this._groups, this._parents); -} + for (let i = 0; i < 3; i += 1) { + each_blocks[i].c(); + } -function styleNull(name, interpolate) { - var string00, - string10, - interpolate0; - return function() { - var string0 = styleValue(this, name), - string1 = (this.style.removeProperty(name), styleValue(this, name)); - return string0 === string1 ? null - : string0 === string00 && string1 === string10 ? interpolate0 - : interpolate0 = interpolate(string00 = string0, string10 = string1); - }; -} + t14 = space(); + td6 = element("td"); + t15 = text(t15_value); + attr(td0, "rowspan", "3"); + attr(td0, "class", "svelte-rb5mhu"); + attr(td1, "class", "svelte-rb5mhu"); -function styleRemove(name) { - return function() { - this.style.removeProperty(name); - }; -} + attr(td2, "aria-label", td2_aria_label_value = [ + /*data*/ ctx[1][/*i*/ ctx[32]].up.Merged.nodesStr, + /*data*/ ctx[1][/*i*/ ctx[32]].same.Merged.nodesStr, + /*data*/ ctx[1][/*i*/ ctx[32]].down.Merged.nodesStr + ].join("\n")); -function styleConstant(name, interpolate, value1) { - var string00, - string1 = value1 + "", - interpolate0; - return function() { - var string0 = styleValue(this, name); - return string0 === string1 ? null - : string0 === string00 ? interpolate0 - : interpolate0 = interpolate(string00 = string0, value1); - }; -} + attr(td2, "class", "svelte-rb5mhu"); + attr(td3, "class", "svelte-rb5mhu"); -function styleFunction(name, interpolate, value) { - var string00, - string10, - interpolate0; - return function() { - var string0 = styleValue(this, name), - value1 = value(this), - string1 = value1 + ""; - if (value1 == null) string1 = value1 = (this.style.removeProperty(name), styleValue(this, name)); - return string0 === string1 ? null - : string0 === string00 && string1 === string10 ? interpolate0 - : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1)); - }; -} + attr(td4, "aria-label", td4_aria_label_value = [ + /*data*/ ctx[1][/*i*/ ctx[32]].up.Merged.edgesStr, + /*data*/ ctx[1][/*i*/ ctx[32]].same.Merged.edgesStr, + /*data*/ ctx[1][/*i*/ ctx[32]].down.Merged.edgesStr + ].join("\n")); -function styleMaybeRemove(id, name) { - var on0, on1, listener0, key = "style." + name, event = "end." + key, remove; - return function() { - var schedule = set(this, id), - on = schedule.on, - listener = schedule.value[key] == null ? remove || (remove = styleRemove(name)) : undefined; + attr(td4, "class", "svelte-rb5mhu"); + attr(td5, "class", "svelte-rb5mhu"); - // If this node shared a dispatch with the previous node, - // just assign the updated shared dispatch and we’re done! - // Otherwise, copy-on-write. - if (on !== on0 || listener0 !== listener) (on1 = (on0 = on).copy()).on(event, listener0 = listener); + attr(td6, "aria-label", td6_aria_label_value = [ + /*data*/ ctx[1][/*i*/ ctx[32]].up.Implied.edgesStr, + /*data*/ ctx[1][/*i*/ ctx[32]].same.Implied.edgesStr, + /*data*/ ctx[1][/*i*/ ctx[32]].down.Implied.edgesStr + ].join("\n")); - schedule.on = on1; - }; -} + attr(td6, "class", "svelte-rb5mhu"); + }, + m(target, anchor) { + insert(target, tr0, anchor); + append(tr0, td0); + append(td0, t0); + append(tr0, t1); + append(tr0, td1); + append(tr0, t3); -function transition_style(name, value, priority) { - var i = (name += "") === "transform" ? interpolateTransformCss : interpolate; - return value == null ? this - .styleTween(name, styleNull(name, i)) - .on("end.style." + name, styleRemove(name)) - : typeof value === "function" ? this - .styleTween(name, styleFunction(name, i, tweenValue(this, "style." + name, value))) - .each(styleMaybeRemove(this._id, name)) - : this - .styleTween(name, styleConstant(name, i, value), priority) - .on("end.style." + name, null); -} + for (let i = 0; i < 3; i += 1) { + each_blocks_2[i].m(tr0, null); + } -function styleInterpolate(name, i, priority) { - return function(t) { - this.style.setProperty(name, i.call(this, t), priority); - }; -} + append(tr0, t4); + append(tr0, td2); + append(td2, t5); + insert(target, t6, anchor); + insert(target, tr1, anchor); + append(tr1, td3); + append(tr1, t8); -function styleTween(name, value, priority) { - var t, i0; - function tween() { - var i = value.apply(this, arguments); - if (i !== i0) t = (i0 = i) && styleInterpolate(name, i, priority); - return t; - } - tween._value = value; - return tween; -} + for (let i = 0; i < 3; i += 1) { + each_blocks_1[i].m(tr1, null); + } -function transition_styleTween(name, value, priority) { - var key = "style." + (name += ""); - if (arguments.length < 2) return (key = this.tween(key)) && key._value; - if (value == null) return this.tween(key, null); - if (typeof value !== "function") throw new Error; - return this.tween(key, styleTween(name, value, priority == null ? "" : priority)); -} + append(tr1, t9); + append(tr1, td4); + append(td4, t10); + insert(target, t11, anchor); + insert(target, tr2, anchor); + append(tr2, td5); + append(tr2, t13); -function textConstant(value) { - return function() { - this.textContent = value; - }; -} + for (let i = 0; i < 3; i += 1) { + each_blocks[i].m(tr2, null); + } -function textFunction(value) { - return function() { - var value1 = value(this); - this.textContent = value1 == null ? "" : value1; - }; -} + append(tr2, t14); + append(tr2, td6); + append(td6, t15); -function transition_text(value) { - return this.tween("text", typeof value === "function" - ? textFunction(tweenValue(this, "text", value)) - : textConstant(value == null ? "" : value + "")); -} + if (!mounted) { + dispose = [ + listen(td2, "click", click_handler_1), + listen(td4, "click", click_handler_3), + listen(td6, "click", click_handler_5) + ]; -function textInterpolate(i) { - return function(t) { - this.textContent = i.call(this, t); - }; -} + mounted = true; + } + }, + p(new_ctx, dirty) { + ctx = new_ctx; -function textTween(value) { - var t0, i0; - function tween() { - var i = value.apply(this, arguments); - if (i !== i0) t0 = (i0 = i) && textInterpolate(i); - return t0; - } - tween._value = value; - return tween; -} + if (dirty[0] & /*data*/ 2) { + each_value_6 = ["up", "same", "down"]; + let i; -function transition_textTween(value) { - var key = "text"; - if (arguments.length < 1) return (key = this.tween(key)) && key._value; - if (value == null) return this.tween(key, null); - if (typeof value !== "function") throw new Error; - return this.tween(key, textTween(value)); -} + for (i = 0; i < 3; i += 1) { + const child_ctx = get_each_context_6(ctx, each_value_6, i); -function transition_transition() { - var name = this._name, - id0 = this._id, - id1 = newId(); + if (each_blocks_2[i]) { + each_blocks_2[i].p(child_ctx, dirty); + } else { + each_blocks_2[i] = create_each_block_6(child_ctx); + each_blocks_2[i].c(); + each_blocks_2[i].m(tr0, t4); + } + } - for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { - if (node = group[i]) { - var inherit = get$1(node, id0); - schedule(node, name, id1, i, group, { - time: inherit.time + inherit.delay + inherit.duration, - delay: 0, - duration: inherit.duration, - ease: inherit.ease - }); - } - } - } + for (; i < 3; i += 1) { + each_blocks_2[i].d(1); + } + } - return new Transition(groups, this._parents, name, id1); -} + if (dirty[0] & /*data*/ 2) { + each_value_5 = ["up", "same", "down"]; + let i; -function transition_end() { - var on0, on1, that = this, id = that._id, size = that.size(); - return new Promise(function(resolve, reject) { - var cancel = {value: reject}, - end = {value: function() { if (--size === 0) resolve(); }}; + for (i = 0; i < 3; i += 1) { + const child_ctx = get_each_context_5(ctx, each_value_5, i); - that.each(function() { - var schedule = set(this, id), - on = schedule.on; + if (each_blocks_1[i]) { + each_blocks_1[i].p(child_ctx, dirty); + } else { + each_blocks_1[i] = create_each_block_5(child_ctx); + each_blocks_1[i].c(); + each_blocks_1[i].m(tr1, t9); + } + } - // If this node shared a dispatch with the previous node, - // just assign the updated shared dispatch and we’re done! - // Otherwise, copy-on-write. - if (on !== on0) { - on1 = (on0 = on).copy(); - on1._.cancel.push(cancel); - on1._.interrupt.push(cancel); - on1._.end.push(end); - } + for (; i < 3; i += 1) { + each_blocks_1[i].d(1); + } + } - schedule.on = on1; - }); + if (dirty[0] & /*data*/ 2) { + each_value_4 = ["up", "same", "down"]; + let i; - // The selection was empty, resolve end immediately - if (size === 0) resolve(); - }); -} + for (i = 0; i < 3; i += 1) { + const child_ctx = get_each_context_4(ctx, each_value_4, i); -var id = 0; + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + } else { + each_blocks[i] = create_each_block_4(child_ctx); + each_blocks[i].c(); + each_blocks[i].m(tr2, t14); + } + } -function Transition(groups, parents, name, id) { - this._groups = groups; - this._parents = parents; - this._name = name; - this._id = id; + for (; i < 3; i += 1) { + each_blocks[i].d(1); + } + } + }, + d(detaching) { + if (detaching) detach(tr0); + destroy_each(each_blocks_2, detaching); + if (detaching) detach(t6); + if (detaching) detach(tr1); + destroy_each(each_blocks_1, detaching); + if (detaching) detach(t11); + if (detaching) detach(tr2); + destroy_each(each_blocks, detaching); + mounted = false; + run_all(dispose); + } + }; } -function newId() { - return ++id; -} +// (194:4) {#each ["up", "same", "down"] as dir} +function create_each_block_2$1(ctx) { + let td; + let t0_value = lodash.sum(/*data*/ ctx[1].map(func)) + ""; + let t0; + let t1; + let td_aria_label_value; + let mounted; + let dispose; -var selection_prototype = selection.prototype; + function func(...args) { + return /*func*/ ctx[10](/*dir*/ ctx[23], ...args); + } -Transition.prototype = { - constructor: Transition, - select: transition_select, - selectAll: transition_selectAll, - filter: transition_filter, - merge: transition_merge, - selection: transition_selection, - transition: transition_transition, - call: selection_prototype.call, - nodes: selection_prototype.nodes, - node: selection_prototype.node, - size: selection_prototype.size, - empty: selection_prototype.empty, - each: selection_prototype.each, - on: transition_on, - attr: transition_attr, - attrTween: transition_attrTween, - style: transition_style, - styleTween: transition_styleTween, - text: transition_text, - textTween: transition_textTween, - remove: transition_remove, - tween: transition_tween, - delay: transition_delay, - duration: transition_duration, - ease: transition_ease, - easeVarying: transition_easeVarying, - end: transition_end, - [Symbol.iterator]: selection_prototype[Symbol.iterator] -}; + function func_1(...args) { + return /*func_1*/ ctx[11](/*dir*/ ctx[23], ...args); + } -function cubicInOut(t) { - return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2; -} + function click_handler_6() { + return /*click_handler_6*/ ctx[12](/*dir*/ ctx[23]); + } -var defaultTiming = { - time: null, // Set on use. - delay: 0, - duration: 250, - ease: cubicInOut -}; + return { + c() { + td = element("td"); + t0 = text(t0_value); + t1 = space(); + attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1].map(func_1).join("\n")); + attr(td, "class", "svelte-rb5mhu"); + }, + m(target, anchor) { + insert(target, td, anchor); + append(td, t0); + append(td, t1); -function inherit(node, id) { - var timing; - while (!(timing = node.__transition) || !(timing = timing[id])) { - if (!(node = node.parentNode)) { - throw new Error(`transition ${id} not found`); - } - } - return timing; + if (!mounted) { + dispose = listen(td, "click", click_handler_6); + mounted = true; + } + }, + p(new_ctx, dirty) { + ctx = new_ctx; + }, + d(detaching) { + if (detaching) detach(td); + mounted = false; + dispose(); + } + }; } -function selection_transition(name) { - var id, - timing; +// (233:4) {#each ["up", "same", "down"] as dir} +function create_each_block_1$3(ctx) { + let td; + let t0_value = lodash.sum(/*data*/ ctx[1].map(func_2)) + ""; + let t0; + let t1; + let td_aria_label_value; + let mounted; + let dispose; - if (name instanceof Transition) { - id = name._id, name = name._name; - } else { - id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + ""; - } + function func_2(...args) { + return /*func_2*/ ctx[13](/*dir*/ ctx[23], ...args); + } - for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) { - for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { - if (node = group[i]) { - schedule(node, name, id, i, group, timing || inherit(node, id)); - } - } - } + function func_3(...args) { + return /*func_3*/ ctx[14](/*dir*/ ctx[23], ...args); + } - return new Transition(groups, this._parents, name, id); + function click_handler_7() { + return /*click_handler_7*/ ctx[15](/*dir*/ ctx[23]); + } + + return { + c() { + td = element("td"); + t0 = text(t0_value); + t1 = space(); + attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1].map(func_3).join("\n")); + attr(td, "class", "svelte-rb5mhu"); + }, + m(target, anchor) { + insert(target, td, anchor); + append(td, t0); + append(td, t1); + + if (!mounted) { + dispose = listen(td, "click", click_handler_7); + mounted = true; + } + }, + p(new_ctx, dirty) { + ctx = new_ctx; + }, + d(detaching) { + if (detaching) detach(td); + mounted = false; + dispose(); + } + }; } -selection.prototype.interrupt = selection_interrupt; -selection.prototype.transition = selection_transition; +// (268:4) {#each ["up", "same", "down"] as dir} +function create_each_block$3(ctx) { + let td; + let t0_value = lodash.sum(/*data*/ ctx[1].map(func_4)) + ""; + let t0; + let t1; + let td_aria_label_value; + let mounted; + let dispose; -const pi$1 = Math.PI, - tau$1 = 2 * pi$1, - epsilon$1 = 1e-6, - tauEpsilon = tau$1 - epsilon$1; + function func_4(...args) { + return /*func_4*/ ctx[16](/*dir*/ ctx[23], ...args); + } -function Path() { - this._x0 = this._y0 = // start of current subpath - this._x1 = this._y1 = null; // end of current subpath - this._ = ""; -} + function func_5(...args) { + return /*func_5*/ ctx[17](/*dir*/ ctx[23], ...args); + } -function path() { - return new Path; -} + function click_handler_8() { + return /*click_handler_8*/ ctx[18](/*dir*/ ctx[23]); + } -Path.prototype = path.prototype = { - constructor: Path, - moveTo: function(x, y) { - this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y); - }, - closePath: function() { - if (this._x1 !== null) { - this._x1 = this._x0, this._y1 = this._y0; - this._ += "Z"; - } - }, - lineTo: function(x, y) { - this._ += "L" + (this._x1 = +x) + "," + (this._y1 = +y); - }, - quadraticCurveTo: function(x1, y1, x, y) { - this._ += "Q" + (+x1) + "," + (+y1) + "," + (this._x1 = +x) + "," + (this._y1 = +y); - }, - bezierCurveTo: function(x1, y1, x2, y2, x, y) { - this._ += "C" + (+x1) + "," + (+y1) + "," + (+x2) + "," + (+y2) + "," + (this._x1 = +x) + "," + (this._y1 = +y); - }, - arcTo: function(x1, y1, x2, y2, r) { - x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r; - var x0 = this._x1, - y0 = this._y1, - x21 = x2 - x1, - y21 = y2 - y1, - x01 = x0 - x1, - y01 = y0 - y1, - l01_2 = x01 * x01 + y01 * y01; + return { + c() { + td = element("td"); + t0 = text(t0_value); + t1 = space(); + attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1].map(func_5).join("\n")); + attr(td, "class", "svelte-rb5mhu"); + }, + m(target, anchor) { + insert(target, td, anchor); + append(td, t0); + append(td, t1); - // Is the radius negative? Error. - if (r < 0) throw new Error("negative radius: " + r); + if (!mounted) { + dispose = listen(td, "click", click_handler_8); + mounted = true; + } + }, + p(new_ctx, dirty) { + ctx = new_ctx; + }, + d(detaching) { + if (detaching) detach(td); + mounted = false; + dispose(); + } + }; +} - // Is this path empty? Move to (x1,y1). - if (this._x1 === null) { - this._ += "M" + (this._x1 = x1) + "," + (this._y1 = y1); - } +function create_fragment$3(ctx) { + let table; + let thead; + let t3; + let tr1; + let t14; + let t15; + let tr2; + let td6; + let t17; + let td7; + let t19; + let t20; + let tr3; + let td8; + let t22; + let t23; + let tr4; + let td9; + let t25; + let each_value_3 = /*userHierarchies*/ ctx[0]; + let each_blocks_3 = []; - // Or, is (x1,y1) coincident with (x0,y0)? Do nothing. - else if (!(l01_2 > epsilon$1)); + for (let i = 0; i < each_value_3.length; i += 1) { + each_blocks_3[i] = create_each_block_3(get_each_context_3(ctx, each_value_3, i)); + } - // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear? - // Equivalently, is (x1,y1) coincident with (x2,y2)? - // Or, is the radius zero? Line to (x1,y1). - else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon$1) || !r) { - this._ += "L" + (this._x1 = x1) + "," + (this._y1 = y1); - } + let each_value_2 = ["up", "same", "down"]; + let each_blocks_2 = []; - // Otherwise, draw an arc! - else { - var x20 = x2 - x0, - y20 = y2 - y0, - l21_2 = x21 * x21 + y21 * y21, - l20_2 = x20 * x20 + y20 * y20, - l21 = Math.sqrt(l21_2), - l01 = Math.sqrt(l01_2), - l = r * Math.tan((pi$1 - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2), - t01 = l / l01, - t21 = l / l21; + for (let i = 0; i < 3; i += 1) { + each_blocks_2[i] = create_each_block_2$1(get_each_context_2$1(ctx, each_value_2, i)); + } - // If the start tangent is not coincident with (x0,y0), line to. - if (Math.abs(t01 - 1) > epsilon$1) { - this._ += "L" + (x1 + t01 * x01) + "," + (y1 + t01 * y01); - } + let each_value_1 = ["up", "same", "down"]; + let each_blocks_1 = []; - this._ += "A" + r + "," + r + ",0,0," + (+(y01 * x20 > x01 * y20)) + "," + (this._x1 = x1 + t21 * x21) + "," + (this._y1 = y1 + t21 * y21); - } - }, - arc: function(x, y, r, a0, a1, ccw) { - x = +x, y = +y, r = +r, ccw = !!ccw; - var dx = r * Math.cos(a0), - dy = r * Math.sin(a0), - x0 = x + dx, - y0 = y + dy, - cw = 1 ^ ccw, - da = ccw ? a0 - a1 : a1 - a0; + for (let i = 0; i < 3; i += 1) { + each_blocks_1[i] = create_each_block_1$3(get_each_context_1$3(ctx, each_value_1, i)); + } - // Is the radius negative? Error. - if (r < 0) throw new Error("negative radius: " + r); + let each_value = ["up", "same", "down"]; + let each_blocks = []; - // Is this path empty? Move to (x0,y0). - if (this._x1 === null) { - this._ += "M" + x0 + "," + y0; - } + for (let i = 0; i < 3; i += 1) { + each_blocks[i] = create_each_block$3(get_each_context$3(ctx, each_value, i)); + } - // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0). - else if (Math.abs(this._x1 - x0) > epsilon$1 || Math.abs(this._y1 - y0) > epsilon$1) { - this._ += "L" + x0 + "," + y0; - } + return { + c() { + table = element("table"); + thead = element("thead"); - // Is this arc empty? We’re done. - if (!r) return; + thead.innerHTML = `Hierarchy + Count`; - // Does the angle go the wrong way? Flip the direction. - if (da < 0) da = da % tau$1 + tau$1; + t3 = space(); + tr1 = element("tr"); - // Is this a complete circle? Draw two arcs to complete the circle. - if (da > tauEpsilon) { - this._ += "A" + r + "," + r + ",0,1," + cw + "," + (x - dx) + "," + (y - dy) + "A" + r + "," + r + ",0,1," + cw + "," + (this._x1 = x0) + "," + (this._y1 = y0); - } + tr1.innerHTML = ` + Measure + ↑ + → + ↓ + Total`; - // Is this arc non-empty? Draw an arc! - else if (da > epsilon$1) { - this._ += "A" + r + "," + r + ",0," + (+(da >= pi$1)) + "," + cw + "," + (this._x1 = x + r * Math.cos(a1)) + "," + (this._y1 = y + r * Math.sin(a1)); - } - }, - rect: function(x, y, w, h) { - this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y) + "h" + (+w) + "v" + (+h) + "h" + (-w) + "Z"; - }, - toString: function() { - return this._; - } -}; + t14 = space(); -function center(x, y) { - var nodes, strength = 1; + for (let i = 0; i < each_blocks_3.length; i += 1) { + each_blocks_3[i].c(); + } - if (x == null) x = 0; - if (y == null) y = 0; + t15 = space(); + tr2 = element("tr"); + td6 = element("td"); + td6.textContent = "Totals"; + t17 = space(); + td7 = element("td"); + td7.textContent = "Nodes"; + t19 = space(); - function force() { - var i, - n = nodes.length, - node, - sx = 0, - sy = 0; + for (let i = 0; i < 3; i += 1) { + each_blocks_2[i].c(); + } - for (i = 0; i < n; ++i) { - node = nodes[i], sx += node.x, sy += node.y; - } + t20 = space(); + tr3 = element("tr"); + td8 = element("td"); + td8.textContent = "Real Edges"; + t22 = space(); - for (sx = (sx / n - x) * strength, sy = (sy / n - y) * strength, i = 0; i < n; ++i) { - node = nodes[i], node.x -= sx, node.y -= sy; - } - } + for (let i = 0; i < 3; i += 1) { + each_blocks_1[i].c(); + } - force.initialize = function(_) { - nodes = _; - }; + t23 = space(); + tr4 = element("tr"); + td9 = element("td"); + td9.textContent = "Implied Edges"; + t25 = space(); - force.x = function(_) { - return arguments.length ? (x = +_, force) : x; - }; + for (let i = 0; i < 3; i += 1) { + each_blocks[i].c(); + } - force.y = function(_) { - return arguments.length ? (y = +_, force) : y; - }; + attr(td6, "rowspan", "3"); + attr(td6, "class", "svelte-rb5mhu"); + attr(td7, "class", "svelte-rb5mhu"); + attr(td8, "class", "svelte-rb5mhu"); + attr(td9, "class", "svelte-rb5mhu"); + attr(table, "class", "svelte-rb5mhu"); + }, + m(target, anchor) { + insert(target, table, anchor); + append(table, thead); + append(table, t3); + append(table, tr1); + append(table, t14); - force.strength = function(_) { - return arguments.length ? (strength = +_, force) : strength; - }; + for (let i = 0; i < each_blocks_3.length; i += 1) { + each_blocks_3[i].m(table, null); + } - return force; -} + append(table, t15); + append(table, tr2); + append(tr2, td6); + append(tr2, t17); + append(tr2, td7); + append(tr2, t19); -function tree_add(d) { - const x = +this._x.call(null, d), - y = +this._y.call(null, d); - return add(this.cover(x, y), x, y, d); -} + for (let i = 0; i < 3; i += 1) { + each_blocks_2[i].m(tr2, null); + } -function add(tree, x, y, d) { - if (isNaN(x) || isNaN(y)) return tree; // ignore invalid points + append(table, t20); + append(table, tr3); + append(tr3, td8); + append(tr3, t22); - var parent, - node = tree._root, - leaf = {data: d}, - x0 = tree._x0, - y0 = tree._y0, - x1 = tree._x1, - y1 = tree._y1, - xm, - ym, - xp, - yp, - right, - bottom, - i, - j; + for (let i = 0; i < 3; i += 1) { + each_blocks_1[i].m(tr3, null); + } - // If the tree is empty, initialize the root as a leaf. - if (!node) return tree._root = leaf, tree; + append(table, t23); + append(table, tr4); + append(tr4, td9); + append(tr4, t25); - // Find the existing leaf for the new point, or add it. - while (node.length) { - if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; - if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; - if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree; - } + for (let i = 0; i < 3; i += 1) { + each_blocks[i].m(tr4, null); + } + }, + p(ctx, dirty) { + if (dirty[0] & /*data, hierStrs*/ 6) { + each_value_3 = /*userHierarchies*/ ctx[0]; + let i; - // Is the new point is exactly coincident with the existing point? - xp = +tree._x.call(null, node.data); - yp = +tree._y.call(null, node.data); - if (x === xp && y === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree; + for (i = 0; i < each_value_3.length; i += 1) { + const child_ctx = get_each_context_3(ctx, each_value_3, i); - // Otherwise, split the leaf node until the old and new point are separated. - do { - parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4); - if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; - if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; - } while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | (xp >= xm))); - return parent[j] = node, parent[i] = leaf, tree; -} + if (each_blocks_3[i]) { + each_blocks_3[i].p(child_ctx, dirty); + } else { + each_blocks_3[i] = create_each_block_3(child_ctx); + each_blocks_3[i].c(); + each_blocks_3[i].m(table, t15); + } + } -function addAll(data) { - var d, i, n = data.length, - x, - y, - xz = new Array(n), - yz = new Array(n), - x0 = Infinity, - y0 = Infinity, - x1 = -Infinity, - y1 = -Infinity; + for (; i < each_blocks_3.length; i += 1) { + each_blocks_3[i].d(1); + } - // Compute the points and their extent. - for (i = 0; i < n; ++i) { - if (isNaN(x = +this._x.call(null, d = data[i])) || isNaN(y = +this._y.call(null, d))) continue; - xz[i] = x; - yz[i] = y; - if (x < x0) x0 = x; - if (x > x1) x1 = x; - if (y < y0) y0 = y; - if (y > y1) y1 = y; - } + each_blocks_3.length = each_value_3.length; + } - // If there were no (valid) points, abort. - if (x0 > x1 || y0 > y1) return this; + if (dirty[0] & /*data*/ 2) { + each_value_2 = ["up", "same", "down"]; + let i; - // Expand the tree to cover the new points. - this.cover(x0, y0).cover(x1, y1); + for (i = 0; i < 3; i += 1) { + const child_ctx = get_each_context_2$1(ctx, each_value_2, i); - // Add the new points. - for (i = 0; i < n; ++i) { - add(this, xz[i], yz[i], data[i]); - } + if (each_blocks_2[i]) { + each_blocks_2[i].p(child_ctx, dirty); + } else { + each_blocks_2[i] = create_each_block_2$1(child_ctx); + each_blocks_2[i].c(); + each_blocks_2[i].m(tr2, null); + } + } - return this; -} + for (; i < 3; i += 1) { + each_blocks_2[i].d(1); + } + } -function tree_cover(x, y) { - if (isNaN(x = +x) || isNaN(y = +y)) return this; // ignore invalid points + if (dirty[0] & /*data*/ 2) { + each_value_1 = ["up", "same", "down"]; + let i; - var x0 = this._x0, - y0 = this._y0, - x1 = this._x1, - y1 = this._y1; + for (i = 0; i < 3; i += 1) { + const child_ctx = get_each_context_1$3(ctx, each_value_1, i); - // If the quadtree has no extent, initialize them. - // Integer extent are necessary so that if we later double the extent, - // the existing quadrant boundaries don’t change due to floating point error! - if (isNaN(x0)) { - x1 = (x0 = Math.floor(x)) + 1; - y1 = (y0 = Math.floor(y)) + 1; - } + if (each_blocks_1[i]) { + each_blocks_1[i].p(child_ctx, dirty); + } else { + each_blocks_1[i] = create_each_block_1$3(child_ctx); + each_blocks_1[i].c(); + each_blocks_1[i].m(tr3, null); + } + } - // Otherwise, double repeatedly to cover. - else { - var z = x1 - x0 || 1, - node = this._root, - parent, - i; + for (; i < 3; i += 1) { + each_blocks_1[i].d(1); + } + } - while (x0 > x || x >= x1 || y0 > y || y >= y1) { - i = (y < y0) << 1 | (x < x0); - parent = new Array(4), parent[i] = node, node = parent, z *= 2; - switch (i) { - case 0: x1 = x0 + z, y1 = y0 + z; break; - case 1: x0 = x1 - z, y1 = y0 + z; break; - case 2: x1 = x0 + z, y0 = y1 - z; break; - case 3: x0 = x1 - z, y0 = y1 - z; break; - } - } + if (dirty[0] & /*data*/ 2) { + each_value = ["up", "same", "down"]; + let i; - if (this._root && this._root.length) this._root = node; - } + for (i = 0; i < 3; i += 1) { + const child_ctx = get_each_context$3(ctx, each_value, i); - this._x0 = x0; - this._y0 = y0; - this._x1 = x1; - this._y1 = y1; - return this; -} + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + } else { + each_blocks[i] = create_each_block$3(child_ctx); + each_blocks[i].c(); + each_blocks[i].m(tr4, null); + } + } -function tree_data() { - var data = []; - this.visit(function(node) { - if (!node.length) do data.push(node.data); while (node = node.next) - }); - return data; + for (; i < 3; i += 1) { + each_blocks[i].d(1); + } + } + }, + i: noop$1, + o: noop$1, + d(detaching) { + if (detaching) detach(table); + destroy_each(each_blocks_3, detaching); + destroy_each(each_blocks_2, detaching); + destroy_each(each_blocks_1, detaching); + destroy_each(each_blocks, detaching); + } + }; } -function tree_extent(_) { - return arguments.length - ? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1]) - : isNaN(this._x0) ? undefined : [[this._x0, this._y0], [this._x1, this._y1]]; -} +function instance$3($$self, $$props, $$invalidate) { + + + let { plugin } = $$props; + const { settings } = plugin; + const { userHierarchies } = settings; + const separator = settings.trailSeperator; + const hierGs = plugin.currGraphs; -function Quad(node, x0, y0, x1, y1) { - this.node = node; - this.x0 = x0; - this.y0 = y0; - this.x1 = x1; - this.y1 = y1; -} + function fillInInfo(dir, gType, hierData, nodesToo = true) { + const gInfo = hierData[dir][gType]; -function tree_find(x, y, radius) { - var data, - x0 = this._x0, - y0 = this._y0, - x1, - y1, - x2, - y2, - x3 = this._x1, - y3 = this._y1, - quads = [], - node = this._root, - q, - i; + if (nodesToo) { + const nodes = gInfo.graph.nodes(); + gInfo.nodes = nodes; + gInfo.nodesStr = nodes.join("\n"); + } - if (node) quads.push(new Quad(node, x0, y0, x3, y3)); - if (radius == null) radius = Infinity; - else { - x0 = x - radius, y0 = y - radius; - x3 = x + radius, y3 = y + radius; - radius *= radius; - } + gInfo.edges = gInfo.graph.edges(); + const edgeStrArr = gInfo.graph.mapEdges((k, a, s, t) => `${nodesToo ? s : t} ${nodesToo || dir !== "same" ? separator : "⟷"} ${nodesToo ? t : s}`); + gInfo.edgesStr = edgeStrArr.join("\n"); + } - while (q = quads.pop()) { + const data = hierGs.hierGs.map(hier => { + const hierData = { + //@ts-ignore + up: { Merged: {}, Closed: {}, Implied: {} }, + //@ts-ignore + same: { Merged: {}, Closed: {}, Implied: {} }, + //@ts-ignore + down: { Merged: {}, Closed: {}, Implied: {} } + }; - // Stop searching if this quadrant can’t contain a closer node. - if (!(node = q.node) - || (x1 = q.x0) > x3 - || (y1 = q.y0) > y3 - || (x2 = q.x1) < x0 - || (y2 = q.y1) < y0) continue; + DIRECTIONS.forEach(dir => { + // Merged Graphs + /// Smoosh all fieldGs from one dir into a merged graph for that direction as a whole + const mergedInDir = mergeGs(...Object.values(hier[dir])); - // Bisect the current quadrant. - if (node.length) { - var xm = (x1 + x2) / 2, - ym = (y1 + y2) / 2; + hierData[dir].Merged.graph = mergedInDir; + fillInInfo(dir, "Merged", hierData); - quads.push( - new Quad(node[3], xm, ym, x2, y2), - new Quad(node[2], x1, ym, xm, y2), - new Quad(node[1], xm, y1, x2, ym), - new Quad(node[0], x1, y1, xm, ym) - ); + // Closed graphs + if (dir !== "same") { + hierData[dir].Closed.graph = closeImpliedLinks(mergedInDir, mergeGs(...Object.values(hier[dir === "up" ? "down" : "up"]))); + } else { + hierData[dir].Closed.graph = closeImpliedLinks(mergedInDir, mergedInDir); + } - // Visit the closest quadrant first. - if (i = (y >= ym) << 1 | (x >= xm)) { - q = quads[quads.length - 1]; - quads[quads.length - 1] = quads[quads.length - 1 - i]; - quads[quads.length - 1 - i] = q; - } - } + fillInInfo(dir, "Closed", hierData); - // Visit this point. (Visiting coincident points isn’t necessary!) - else { - var dx = x - +this._x.call(null, node.data), - dy = y - +this._y.call(null, node.data), - d2 = dx * dx + dy * dy; - if (d2 < radius) { - var d = Math.sqrt(radius = d2); - x0 = x - d, y0 = y - d; - x3 = x + d, y3 = y + d; - data = node.data; - } - } - } + if (dir !== "same") { + hierData[dir].Implied.graph = mergeGs(...Object.values(hier[dir === "up" ? "down" : "up"])); + } else { + hierData[dir].Implied.graph = closeImpliedLinks(mergedInDir, mergedInDir); + } - return data; -} + fillInInfo(dir, "Implied", hierData, false); + }); -function tree_remove(d) { - if (isNaN(x = +this._x.call(null, d)) || isNaN(y = +this._y.call(null, d))) return this; // ignore invalid points + return hierData; + }); - var parent, - node = this._root, - retainer, - previous, - next, - x0 = this._x0, - y0 = this._y0, - x1 = this._x1, - y1 = this._y1, - x, - y, - xm, - ym, - right, - bottom, - i, - j; + debug(settings, { data }); + let hierStrs = userHierarchies.map(hierToStr); + const click_handler = async (i, dir) => await copy$1(data[i][dir].Merged.nodesStr); - // If the tree is empty, initialize the root as a leaf. - if (!node) return this; + const click_handler_1 = async i => await copy$1([ + data[i].up.Merged.nodesStr, + data[i].same.Merged.nodesStr, + data[i].down.Merged.nodesStr + ].join("\n")); - // Find the leaf node for the point. - // While descending, also retain the deepest parent with a non-removed sibling. - if (node.length) while (true) { - if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; - if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; - if (!(parent = node, node = node[i = bottom << 1 | right])) return this; - if (!node.length) break; - if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) retainer = parent, j = i; - } + const click_handler_2 = async (i, dir) => await copy$1(data[i][dir].Merged.edgesStr); - // Find the point to remove. - while (node.data !== d) if (!(previous = node, node = node.next)) return this; - if (next = node.next) delete node.next; + const click_handler_3 = async i => await copy$1([ + data[i].up.Merged.edgesStr, + data[i].same.Merged.edgesStr, + data[i].down.Merged.edgesStr + ].join("\n")); - // If there are multiple coincident points, remove just the point. - if (previous) return (next ? previous.next = next : delete previous.next), this; + const click_handler_4 = async (i, dir) => await copy$1(data[i][dir].Implied.edgesStr); - // If this is the root point, remove it. - if (!parent) return this._root = next, this; + const click_handler_5 = async i => await copy$1([ + data[i].up.Implied.edgesStr, + data[i].same.Implied.edgesStr, + data[i].down.Implied.edgesStr + ].join("\n")); - // Remove this leaf. - next ? parent[i] = next : delete parent[i]; + const func = (dir, datum) => datum[dir].Merged.nodes.length; + const func_1 = (dir, datum) => datum[dir].Merged.nodesStr; + const click_handler_6 = async dir => await copy$1(data.map(datum => datum[dir].Merged.nodesStr).join("\n")); + const func_2 = (dir, datum) => datum[dir].Merged.edges.length; + const func_3 = (dir, datum) => datum[dir].Merged.edgesStr; + const click_handler_7 = async dir => await copy$1(data.map(datum => datum[dir].Merged.edgesStr).join("\n")); + const func_4 = (dir, datum) => datum[dir].Implied.edges.length; + const func_5 = (dir, datum) => datum[dir].Implied.edgesStr; + const click_handler_8 = async dir => await copy$1(data.map(datum => datum[dir].Implied.edgesStr).join("\n")); - // If the parent now contains exactly one leaf, collapse superfluous parents. - if ((node = parent[0] || parent[1] || parent[2] || parent[3]) - && node === (parent[3] || parent[2] || parent[1] || parent[0]) - && !node.length) { - if (retainer) retainer[j] = node; - else this._root = node; - } + $$self.$$set = $$props => { + if ("plugin" in $$props) $$invalidate(3, plugin = $$props.plugin); + }; - return this; + return [ + userHierarchies, + data, + hierStrs, + plugin, + click_handler, + click_handler_1, + click_handler_2, + click_handler_3, + click_handler_4, + click_handler_5, + func, + func_1, + click_handler_6, + func_2, + func_3, + click_handler_7, + func_4, + func_5, + click_handler_8 + ]; } -function removeAll(data) { - for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]); - return this; +class Stats extends SvelteComponent { + constructor(options) { + super(); + if (!document.getElementById("svelte-rb5mhu-style")) add_css$2(); + init$1(this, options, instance$3, create_fragment$3, safe_not_equal, { plugin: 3 }, [-1, -1]); + } } -function tree_root() { - return this._root; +class StatsView extends obsidian.ItemView { + constructor(leaf, plugin) { + super(leaf); + this.icon = "info"; + this.plugin = plugin; + } + async onload() { + super.onload(); + await this.plugin.saveSettings(); + this.app.workspace.onLayoutReady(async () => { + setTimeout(async () => await this.draw(), this.plugin.settings.dvWaitTime); + }); + } + getViewType() { + return STATS_VIEW; + } + getDisplayText() { + return "Breadcrumbs Stats"; + } + async onOpen() { + await this.plugin.saveSettings(); + } + onClose() { + if (this.view) { + this.view.$destroy(); + } + return Promise.resolve(); + } + // ANCHOR Remove duplicate implied links + dfsAllPaths(g, startNode) { + const queue = [ + { node: startNode, path: [] }, + ]; + const pathsArr = []; + let i = 0; + while (queue.length > 0 && i < 1000) { + i++; + const currPath = queue.shift(); + const newNodes = g.outNeighbors(currPath.node); + const extPath = [currPath.node, ...currPath.path]; + queue.unshift(...newNodes.map((n) => { + return { node: n, path: extPath }; + })); + if (newNodes.length === 0) { + pathsArr.push(extPath); + } + } + return pathsArr; + } + async draw() { + this.contentEl.empty(); + this.view = new Stats({ + target: this.contentEl, + props: { plugin: this.plugin }, + }); + } } -function tree_size() { - var size = 0; - this.visit(function(node) { - if (!node.length) do ++size; while (node = node.next) - }); - return size; +function ascending$1(a, b) { + return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; } -function tree_visit(callback) { - var quads = [], q, node = this._root, child, x0, y0, x1, y1; - if (node) quads.push(new Quad(node, this._x0, this._y0, this._x1, this._y1)); - while (q = quads.pop()) { - if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) { - var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2; - if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1)); - if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1)); - if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym)); - if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym)); +function bisector(f) { + let delta = f; + let compare = f; + + if (f.length === 1) { + delta = (d, x) => f(d) - x; + compare = ascendingComparator(f); + } + + function left(a, x, lo, hi) { + if (lo == null) lo = 0; + if (hi == null) hi = a.length; + while (lo < hi) { + const mid = (lo + hi) >>> 1; + if (compare(a[mid], x) < 0) lo = mid + 1; + else hi = mid; } + return lo; } - return this; -} -function tree_visitAfter(callback) { - var quads = [], next = [], q; - if (this._root) quads.push(new Quad(this._root, this._x0, this._y0, this._x1, this._y1)); - while (q = quads.pop()) { - var node = q.node; - if (node.length) { - var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2; - if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym)); - if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym)); - if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1)); - if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1)); + function right(a, x, lo, hi) { + if (lo == null) lo = 0; + if (hi == null) hi = a.length; + while (lo < hi) { + const mid = (lo + hi) >>> 1; + if (compare(a[mid], x) > 0) hi = mid; + else lo = mid + 1; } - next.push(q); + return lo; } - while (q = next.pop()) { - callback(q.node, q.x0, q.y0, q.x1, q.y1); + + function center(a, x, lo, hi) { + if (lo == null) lo = 0; + if (hi == null) hi = a.length; + const i = left(a, x, lo, hi - 1); + return i > lo && delta(a[i - 1], x) > -delta(a[i], x) ? i - 1 : i; } - return this; -} -function defaultX(d) { - return d[0]; + return {left, center, right}; } -function tree_x(_) { - return arguments.length ? (this._x = _, this) : this._x; +function ascendingComparator(f) { + return (d, x) => ascending$1(f(d), x); } -function defaultY(d) { - return d[1]; +function number$1(x) { + return x === null ? NaN : +x; } -function tree_y(_) { - return arguments.length ? (this._y = _, this) : this._y; -} +const ascendingBisect = bisector(ascending$1); +const bisectRight = ascendingBisect.right; +bisector(number$1).center; -function quadtree(nodes, x, y) { - var tree = new Quadtree(x == null ? defaultX : x, y == null ? defaultY : y, NaN, NaN, NaN, NaN); - return nodes == null ? tree : tree.addAll(nodes); -} +var e10 = Math.sqrt(50), + e5 = Math.sqrt(10), + e2 = Math.sqrt(2); + +function ticks(start, stop, count) { + var reverse, + i = -1, + n, + ticks, + step; + + stop = +stop, start = +start, count = +count; + if (start === stop && count > 0) return [start]; + if (reverse = stop < start) n = start, start = stop, stop = n; + if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return []; + + if (step > 0) { + let r0 = Math.round(start / step), r1 = Math.round(stop / step); + if (r0 * step < start) ++r0; + if (r1 * step > stop) --r1; + ticks = new Array(n = r1 - r0 + 1); + while (++i < n) ticks[i] = (r0 + i) * step; + } else { + step = -step; + let r0 = Math.round(start * step), r1 = Math.round(stop * step); + if (r0 / step < start) ++r0; + if (r1 / step > stop) --r1; + ticks = new Array(n = r1 - r0 + 1); + while (++i < n) ticks[i] = (r0 + i) / step; + } + + if (reverse) ticks.reverse(); -function Quadtree(x, y, x0, y0, x1, y1) { - this._x = x; - this._y = y; - this._x0 = x0; - this._y0 = y0; - this._x1 = x1; - this._y1 = y1; - this._root = undefined; + return ticks; } -function leaf_copy(leaf) { - var copy = {data: leaf.data}, next = copy; - while (leaf = leaf.next) next = next.next = {data: leaf.data}; - return copy; +function tickIncrement(start, stop, count) { + var step = (stop - start) / Math.max(0, count), + power = Math.floor(Math.log(step) / Math.LN10), + error = step / Math.pow(10, power); + return power >= 0 + ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power) + : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1); } -var treeProto = quadtree.prototype = Quadtree.prototype; - -treeProto.copy = function() { - var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1), - node = this._root, - nodes, - child; - - if (!node) return copy; - - if (!node.length) return copy._root = leaf_copy(node), copy; +function tickStep(start, stop, count) { + var step0 = Math.abs(stop - start) / Math.max(0, count), + step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)), + error = step0 / step1; + if (error >= e10) step1 *= 10; + else if (error >= e5) step1 *= 5; + else if (error >= e2) step1 *= 2; + return stop < start ? -step1 : step1; +} - nodes = [{source: node, target: copy._root = new Array(4)}]; - while (node = nodes.pop()) { - for (var i = 0; i < 4; ++i) { - if (child = node.source[i]) { - if (child.length) nodes.push({source: child, target: node.target[i] = new Array(4)}); - else node.target[i] = leaf_copy(child); +function max$1(values, valueof) { + let max; + if (valueof === undefined) { + for (const value of values) { + if (value != null + && (max < value || (max === undefined && value >= value))) { + max = value; + } + } + } else { + let index = -1; + for (let value of values) { + if ((value = valueof(value, ++index, values)) != null + && (max < value || (max === undefined && value >= value))) { + max = value; } } } + return max; +} - return copy; -}; +function sequence(start, stop, step) { + start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step; -treeProto.add = tree_add; -treeProto.addAll = addAll; -treeProto.cover = tree_cover; -treeProto.data = tree_data; -treeProto.extent = tree_extent; -treeProto.find = tree_find; -treeProto.remove = tree_remove; -treeProto.removeAll = removeAll; -treeProto.root = tree_root; -treeProto.size = tree_size; -treeProto.visit = tree_visit; -treeProto.visitAfter = tree_visitAfter; -treeProto.x = tree_x; -treeProto.y = tree_y; + var i = -1, + n = Math.max(0, Math.ceil((stop - start) / step)) | 0, + range = new Array(n); -function constant$4(x) { - return function() { - return x; - }; -} + while (++i < n) { + range[i] = start + i * step; + } -function jiggle(random) { - return (random() - 0.5) * 1e-6; + return range; } -function x$2(d) { - return d.x + d.vx; -} +var noop = {value: () => {}}; -function y$2(d) { - return d.y + d.vy; +function dispatch() { + for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) { + if (!(t = arguments[i] + "") || (t in _) || /[\s.]/.test(t)) throw new Error("illegal type: " + t); + _[t] = []; + } + return new Dispatch(_); } -function collide(radius) { - var nodes, - radii, - random, - strength = 1, - iterations = 1; +function Dispatch(_) { + this._ = _; +} - if (typeof radius !== "function") radius = constant$4(radius == null ? 1 : +radius); +function parseTypenames$1(typenames, types) { + return typenames.trim().split(/^|\s+/).map(function(t) { + var name = "", i = t.indexOf("."); + if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); + if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t); + return {type: t, name: name}; + }); +} - function force() { - var i, n = nodes.length, - tree, - node, - xi, - yi, - ri, - ri2; +Dispatch.prototype = dispatch.prototype = { + constructor: Dispatch, + on: function(typename, callback) { + var _ = this._, + T = parseTypenames$1(typename + "", _), + t, + i = -1, + n = T.length; - for (var k = 0; k < iterations; ++k) { - tree = quadtree(nodes, x$2, y$2).visitAfter(prepare); - for (i = 0; i < n; ++i) { - node = nodes[i]; - ri = radii[node.index], ri2 = ri * ri; - xi = node.x + node.vx; - yi = node.y + node.vy; - tree.visit(apply); - } + // If no callback was specified, return the callback of the given type and name. + if (arguments.length < 2) { + while (++i < n) if ((t = (typename = T[i]).type) && (t = get$1(_[t], typename.name))) return t; + return; } - function apply(quad, x0, y0, x1, y1) { - var data = quad.data, rj = quad.r, r = ri + rj; - if (data) { - if (data.index > node.index) { - var x = xi - data.x - data.vx, - y = yi - data.y - data.vy, - l = x * x + y * y; - if (l < r * r) { - if (x === 0) x = jiggle(random), l += x * x; - if (y === 0) y = jiggle(random), l += y * y; - l = (r - (l = Math.sqrt(l))) / l * strength; - node.vx += (x *= l) * (r = (rj *= rj) / (ri2 + rj)); - node.vy += (y *= l) * r; - data.vx -= x * (r = 1 - r); - data.vy -= y * r; - } - } - return; - } - return x0 > xi + r || x1 < xi - r || y0 > yi + r || y1 < yi - r; + // If a type was specified, set the callback for the given type and name. + // Otherwise, if a null callback was specified, remove callbacks of the given name. + if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback); + while (++i < n) { + if (t = (typename = T[i]).type) _[t] = set$1(_[t], typename.name, callback); + else if (callback == null) for (t in _) _[t] = set$1(_[t], typename.name, null); } + + return this; + }, + copy: function() { + var copy = {}, _ = this._; + for (var t in _) copy[t] = _[t].slice(); + return new Dispatch(copy); + }, + call: function(type, that) { + if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2]; + if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); + for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); + }, + apply: function(type, that, args) { + if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); + for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); } +}; - function prepare(quad) { - if (quad.data) return quad.r = radii[quad.data.index]; - for (var i = quad.r = 0; i < 4; ++i) { - if (quad[i] && quad[i].r > quad.r) { - quad.r = quad[i].r; - } +function get$1(type, name) { + for (var i = 0, n = type.length, c; i < n; ++i) { + if ((c = type[i]).name === name) { + return c.value; } } +} - function initialize() { - if (!nodes) return; - var i, n = nodes.length, node; - radii = new Array(n); - for (i = 0; i < n; ++i) node = nodes[i], radii[node.index] = +radius(node, i, nodes); +function set$1(type, name, callback) { + for (var i = 0, n = type.length; i < n; ++i) { + if (type[i].name === name) { + type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1)); + break; + } } + if (callback != null) type.push({name: name, value: callback}); + return type; +} - force.initialize = function(_nodes, _random) { - nodes = _nodes; - random = _random; - initialize(); - }; +var xhtml = "http://www.w3.org/1999/xhtml"; - force.iterations = function(_) { - return arguments.length ? (iterations = +_, force) : iterations; - }; +var namespaces = { + svg: "http://www.w3.org/2000/svg", + xhtml: xhtml, + xlink: "http://www.w3.org/1999/xlink", + xml: "http://www.w3.org/XML/1998/namespace", + xmlns: "http://www.w3.org/2000/xmlns/" +}; - force.strength = function(_) { - return arguments.length ? (strength = +_, force) : strength; - }; +function namespace(name) { + var prefix = name += "", i = prefix.indexOf(":"); + if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1); + return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name; // eslint-disable-line no-prototype-builtins +} - force.radius = function(_) { - return arguments.length ? (radius = typeof _ === "function" ? _ : constant$4(+_), initialize(), force) : radius; +function creatorInherit(name) { + return function() { + var document = this.ownerDocument, + uri = this.namespaceURI; + return uri === xhtml && document.documentElement.namespaceURI === xhtml + ? document.createElement(name) + : document.createElementNS(uri, name); }; - - return force; } -function index$1(d) { - return d.index; +function creatorFixed(fullname) { + return function() { + return this.ownerDocument.createElementNS(fullname.space, fullname.local); + }; } -function find(nodeById, nodeId) { - var node = nodeById.get(nodeId); - if (!node) throw new Error("node not found: " + nodeId); - return node; +function creator(name) { + var fullname = namespace(name); + return (fullname.local + ? creatorFixed + : creatorInherit)(fullname); } -function link$1(links) { - var id = index$1, - strength = defaultStrength, - strengths, - distance = constant$4(30), - distances, - nodes, - count, - bias, - random, - iterations = 1; +function none() {} - if (links == null) links = []; +function selector(selector) { + return selector == null ? none : function() { + return this.querySelector(selector); + }; +} - function defaultStrength(link) { - return 1 / Math.min(count[link.source.index], count[link.target.index]); - } +function selection_select(select) { + if (typeof select !== "function") select = selector(select); - function force(alpha) { - for (var k = 0, n = links.length; k < iterations; ++k) { - for (var i = 0, link, source, target, x, y, l, b; i < n; ++i) { - link = links[i], source = link.source, target = link.target; - x = target.x + target.vx - source.x - source.vx || jiggle(random); - y = target.y + target.vy - source.y - source.vy || jiggle(random); - l = Math.sqrt(x * x + y * y); - l = (l - distances[i]) / l * alpha * strengths[i]; - x *= l, y *= l; - target.vx -= x * (b = bias[i]); - target.vy -= y * b; - source.vx += x * (b = 1 - b); - source.vy += y * b; + for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) { + if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) { + if ("__data__" in node) subnode.__data__ = node.__data__; + subgroup[i] = subnode; } } } - function initialize() { - if (!nodes) return; - - var i, - n = nodes.length, - m = links.length, - nodeById = new Map(nodes.map((d, i) => [id(d, i, nodes), d])), - link; - - for (i = 0, count = new Array(n); i < m; ++i) { - link = links[i], link.index = i; - if (typeof link.source !== "object") link.source = find(nodeById, link.source); - if (typeof link.target !== "object") link.target = find(nodeById, link.target); - count[link.source.index] = (count[link.source.index] || 0) + 1; - count[link.target.index] = (count[link.target.index] || 0) + 1; - } + return new Selection$1(subgroups, this._parents); +} - for (i = 0, bias = new Array(m); i < m; ++i) { - link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]); - } +function array$1(x) { + return typeof x === "object" && "length" in x + ? x // Array, TypedArray, NodeList, array-like + : Array.from(x); // Map, Set, iterable, string, or anything else +} - strengths = new Array(m), initializeStrength(); - distances = new Array(m), initializeDistance(); - } +function empty() { + return []; +} - function initializeStrength() { - if (!nodes) return; +function selectorAll(selector) { + return selector == null ? empty : function() { + return this.querySelectorAll(selector); + }; +} - for (var i = 0, n = links.length; i < n; ++i) { - strengths[i] = +strength(links[i], i, links); - } - } +function arrayAll(select) { + return function() { + var group = select.apply(this, arguments); + return group == null ? [] : array$1(group); + }; +} - function initializeDistance() { - if (!nodes) return; +function selection_selectAll(select) { + if (typeof select === "function") select = arrayAll(select); + else select = selectorAll(select); - for (var i = 0, n = links.length; i < n; ++i) { - distances[i] = +distance(links[i], i, links); + for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { + if (node = group[i]) { + subgroups.push(select.call(node, node.__data__, i, group)); + parents.push(node); + } } } - force.initialize = function(_nodes, _random) { - nodes = _nodes; - random = _random; - initialize(); - }; + return new Selection$1(subgroups, parents); +} - force.links = function(_) { - return arguments.length ? (links = _, initialize(), force) : links; +function matcher(selector) { + return function() { + return this.matches(selector); }; +} - force.id = function(_) { - return arguments.length ? (id = _, force) : id; +function childMatcher(selector) { + return function(node) { + return node.matches(selector); }; +} - force.iterations = function(_) { - return arguments.length ? (iterations = +_, force) : iterations; - }; +var find$1 = Array.prototype.find; - force.strength = function(_) { - return arguments.length ? (strength = typeof _ === "function" ? _ : constant$4(+_), initializeStrength(), force) : strength; +function childFind(match) { + return function() { + return find$1.call(this.children, match); }; +} - force.distance = function(_) { - return arguments.length ? (distance = typeof _ === "function" ? _ : constant$4(+_), initializeDistance(), force) : distance; - }; +function childFirst() { + return this.firstElementChild; +} - return force; +function selection_selectChild(match) { + return this.select(match == null ? childFirst + : childFind(typeof match === "function" ? match : childMatcher(match))); } -// https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use -const a = 1664525; -const c$1 = 1013904223; -const m = 4294967296; // 2^32 +var filter = Array.prototype.filter; -function lcg() { - let s = 1; - return () => (s = (a * s + c$1) % m) / m; +function children() { + return this.children; } -function x$1(d) { - return d.x; +function childrenFilter(match) { + return function() { + return filter.call(this.children, match); + }; } -function y$1(d) { - return d.y; +function selection_selectChildren(match) { + return this.selectAll(match == null ? children + : childrenFilter(typeof match === "function" ? match : childMatcher(match))); } -var initialRadius = 10, - initialAngle = Math.PI * (3 - Math.sqrt(5)); - -function simulation(nodes) { - var simulation, - alpha = 1, - alphaMin = 0.001, - alphaDecay = 1 - Math.pow(alphaMin, 1 / 300), - alphaTarget = 0, - velocityDecay = 0.6, - forces = new Map(), - stepper = timer(step), - event = dispatch("tick", "end"), - random = lcg(); - - if (nodes == null) nodes = []; +function selection_filter(match) { + if (typeof match !== "function") match = matcher(match); - function step() { - tick(); - event.call("tick", simulation); - if (alpha < alphaMin) { - stepper.stop(); - event.call("end", simulation); + for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) { + if ((node = group[i]) && match.call(node, node.__data__, i, group)) { + subgroup.push(node); + } } } - function tick(iterations) { - var i, n = nodes.length, node; + return new Selection$1(subgroups, this._parents); +} - if (iterations === undefined) iterations = 1; +function sparse(update) { + return new Array(update.length); +} - for (var k = 0; k < iterations; ++k) { - alpha += (alphaTarget - alpha) * alphaDecay; +function selection_enter() { + return new Selection$1(this._enter || this._groups.map(sparse), this._parents); +} - forces.forEach(function(force) { - force(alpha); - }); +function EnterNode(parent, datum) { + this.ownerDocument = parent.ownerDocument; + this.namespaceURI = parent.namespaceURI; + this._next = null; + this._parent = parent; + this.__data__ = datum; +} - for (i = 0; i < n; ++i) { - node = nodes[i]; - if (node.fx == null) node.x += node.vx *= velocityDecay; - else node.x = node.fx, node.vx = 0; - if (node.fy == null) node.y += node.vy *= velocityDecay; - else node.y = node.fy, node.vy = 0; - } +EnterNode.prototype = { + constructor: EnterNode, + appendChild: function(child) { return this._parent.insertBefore(child, this._next); }, + insertBefore: function(child, next) { return this._parent.insertBefore(child, next); }, + querySelector: function(selector) { return this._parent.querySelector(selector); }, + querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); } +}; + +function constant$6(x) { + return function() { + return x; + }; +} + +function bindIndex(parent, group, enter, update, exit, data) { + var i = 0, + node, + groupLength = group.length, + dataLength = data.length; + + // Put any non-null nodes that fit into update. + // Put any null nodes into enter. + // Put any remaining data into enter. + for (; i < dataLength; ++i) { + if (node = group[i]) { + node.__data__ = data[i]; + update[i] = node; + } else { + enter[i] = new EnterNode(parent, data[i]); } + } - return simulation; + // Put any non-null nodes that don’t fit into exit. + for (; i < groupLength; ++i) { + if (node = group[i]) { + exit[i] = node; + } } +} - function initializeNodes() { - for (var i = 0, n = nodes.length, node; i < n; ++i) { - node = nodes[i], node.index = i; - if (node.fx != null) node.x = node.fx; - if (node.fy != null) node.y = node.fy; - if (isNaN(node.x) || isNaN(node.y)) { - var radius = initialRadius * Math.sqrt(0.5 + i), angle = i * initialAngle; - node.x = radius * Math.cos(angle); - node.y = radius * Math.sin(angle); - } - if (isNaN(node.vx) || isNaN(node.vy)) { - node.vx = node.vy = 0; +function bindKey(parent, group, enter, update, exit, data, key) { + var i, + node, + nodeByKeyValue = new Map, + groupLength = group.length, + dataLength = data.length, + keyValues = new Array(groupLength), + keyValue; + + // Compute the key for each node. + // If multiple nodes have the same key, the duplicates are added to exit. + for (i = 0; i < groupLength; ++i) { + if (node = group[i]) { + keyValues[i] = keyValue = key.call(node, node.__data__, i, group) + ""; + if (nodeByKeyValue.has(keyValue)) { + exit[i] = node; + } else { + nodeByKeyValue.set(keyValue, node); } } } - function initializeForce(force) { - if (force.initialize) force.initialize(nodes, random); - return force; + // Compute the key for each datum. + // If there a node associated with this key, join and add it to update. + // If there is not (or the key is a duplicate), add it to enter. + for (i = 0; i < dataLength; ++i) { + keyValue = key.call(parent, data[i], i, data) + ""; + if (node = nodeByKeyValue.get(keyValue)) { + update[i] = node; + node.__data__ = data[i]; + nodeByKeyValue.delete(keyValue); + } else { + enter[i] = new EnterNode(parent, data[i]); + } } - initializeNodes(); - - return simulation = { - tick: tick, - - restart: function() { - return stepper.restart(step), simulation; - }, + // Add any remaining nodes that were not bound to data to exit. + for (i = 0; i < groupLength; ++i) { + if ((node = group[i]) && (nodeByKeyValue.get(keyValues[i]) === node)) { + exit[i] = node; + } + } +} - stop: function() { - return stepper.stop(), simulation; - }, +function datum(node) { + return node.__data__; +} - nodes: function(_) { - return arguments.length ? (nodes = _, initializeNodes(), forces.forEach(initializeForce), simulation) : nodes; - }, +function selection_data(value, key) { + if (!arguments.length) return Array.from(this, datum); - alpha: function(_) { - return arguments.length ? (alpha = +_, simulation) : alpha; - }, + var bind = key ? bindKey : bindIndex, + parents = this._parents, + groups = this._groups; - alphaMin: function(_) { - return arguments.length ? (alphaMin = +_, simulation) : alphaMin; - }, + if (typeof value !== "function") value = constant$6(value); - alphaDecay: function(_) { - return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay; - }, + for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) { + var parent = parents[j], + group = groups[j], + groupLength = group.length, + data = array$1(value.call(parent, parent && parent.__data__, j, parents)), + dataLength = data.length, + enterGroup = enter[j] = new Array(dataLength), + updateGroup = update[j] = new Array(dataLength), + exitGroup = exit[j] = new Array(groupLength); - alphaTarget: function(_) { - return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget; - }, + bind(parent, group, enterGroup, updateGroup, exitGroup, data, key); - velocityDecay: function(_) { - return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay; - }, + // Now connect the enter nodes to their following update node, such that + // appendChild can insert the materialized enter node before this node, + // rather than at the end of the parent node. + for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) { + if (previous = enterGroup[i0]) { + if (i0 >= i1) i1 = i0 + 1; + while (!(next = updateGroup[i1]) && ++i1 < dataLength); + previous._next = next || null; + } + } + } - randomSource: function(_) { - return arguments.length ? (random = _, forces.forEach(initializeForce), simulation) : random; - }, + update = new Selection$1(update, parents); + update._enter = enter; + update._exit = exit; + return update; +} - force: function(name, _) { - return arguments.length > 1 ? ((_ == null ? forces.delete(name) : forces.set(name, initializeForce(_))), simulation) : forces.get(name); - }, +function selection_exit() { + return new Selection$1(this._exit || this._groups.map(sparse), this._parents); +} - find: function(x, y, radius) { - var i = 0, - n = nodes.length, - dx, - dy, - d2, - node, - closest; +function selection_join(onenter, onupdate, onexit) { + var enter = this.enter(), update = this, exit = this.exit(); + enter = typeof onenter === "function" ? onenter(enter) : enter.append(onenter + ""); + if (onupdate != null) update = onupdate(update); + if (onexit == null) exit.remove(); else onexit(exit); + return enter && update ? enter.merge(update).order() : update; +} - if (radius == null) radius = Infinity; - else radius *= radius; +function selection_merge(selection) { + if (!(selection instanceof Selection$1)) throw new Error("invalid merge"); - for (i = 0; i < n; ++i) { - node = nodes[i]; - dx = x - node.x; - dy = y - node.y; - d2 = dx * dx + dy * dy; - if (d2 < radius) closest = node, radius = d2; + for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { + for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) { + if (node = group0[i] || group1[i]) { + merge[i] = node; } - - return closest; - }, - - on: function(name, _) { - return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name); } - }; -} - -function manyBody() { - var nodes, - node, - random, - alpha, - strength = constant$4(-30), - strengths, - distanceMin2 = 1, - distanceMax2 = Infinity, - theta2 = 0.81; - - function force(_) { - var i, n = nodes.length, tree = quadtree(nodes, x$1, y$1).visitAfter(accumulate); - for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply); } - function initialize() { - if (!nodes) return; - var i, n = nodes.length, node; - strengths = new Array(n); - for (i = 0; i < n; ++i) node = nodes[i], strengths[node.index] = +strength(node, i, nodes); + for (; j < m0; ++j) { + merges[j] = groups0[j]; } - function accumulate(quad) { - var strength = 0, q, c, weight = 0, x, y, i; + return new Selection$1(merges, this._parents); +} - // For internal nodes, accumulate forces from child quadrants. - if (quad.length) { - for (x = y = i = 0; i < 4; ++i) { - if ((q = quad[i]) && (c = Math.abs(q.value))) { - strength += q.value, weight += c, x += c * q.x, y += c * q.y; - } - } - quad.x = x / weight; - quad.y = y / weight; - } +function selection_order() { - // For leaf nodes, accumulate forces from coincident quadrants. - else { - q = quad; - q.x = q.data.x; - q.y = q.data.y; - do strength += strengths[q.data.index]; - while (q = q.next); + for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) { + for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) { + if (node = group[i]) { + if (next && node.compareDocumentPosition(next) ^ 4) next.parentNode.insertBefore(node, next); + next = node; + } } - - quad.value = strength; } - function apply(quad, x1, _, x2) { - if (!quad.value) return true; - - var x = quad.x - node.x, - y = quad.y - node.y, - w = x2 - x1, - l = x * x + y * y; + return this; +} - // Apply the Barnes-Hut approximation if possible. - // Limit forces for very close nodes; randomize direction if coincident. - if (w * w / theta2 < l) { - if (l < distanceMax2) { - if (x === 0) x = jiggle(random), l += x * x; - if (y === 0) y = jiggle(random), l += y * y; - if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l); - node.vx += x * quad.value * alpha / l; - node.vy += y * quad.value * alpha / l; - } - return true; - } +function selection_sort(compare) { + if (!compare) compare = ascending; - // Otherwise, process points directly. - else if (quad.length || l >= distanceMax2) return; + function compareNode(a, b) { + return a && b ? compare(a.__data__, b.__data__) : !a - !b; + } - // Limit forces for very close nodes; randomize direction if coincident. - if (quad.data !== node || quad.next) { - if (x === 0) x = jiggle(random), l += x * x; - if (y === 0) y = jiggle(random), l += y * y; - if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l); + for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) { + if (node = group[i]) { + sortgroup[i] = node; + } } - - do if (quad.data !== node) { - w = strengths[quad.data.index] * alpha / l; - node.vx += x * w; - node.vy += y * w; - } while (quad = quad.next); + sortgroup.sort(compareNode); } - force.initialize = function(_nodes, _random) { - nodes = _nodes; - random = _random; - initialize(); - }; + return new Selection$1(sortgroups, this._parents).order(); +} - force.strength = function(_) { - return arguments.length ? (strength = typeof _ === "function" ? _ : constant$4(+_), initialize(), force) : strength; - }; +function ascending(a, b) { + return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; +} - force.distanceMin = function(_) { - return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2); - }; +function selection_call() { + var callback = arguments[0]; + arguments[0] = this; + callback.apply(null, arguments); + return this; +} - force.distanceMax = function(_) { - return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2); - }; +function selection_nodes() { + return Array.from(this); +} - force.theta = function(_) { - return arguments.length ? (theta2 = _ * _, force) : Math.sqrt(theta2); - }; +function selection_node() { - return force; -} + for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { + for (var group = groups[j], i = 0, n = group.length; i < n; ++i) { + var node = group[i]; + if (node) return node; + } + } -function formatDecimal(x) { - return Math.abs(x = Math.round(x)) >= 1e21 - ? x.toLocaleString("en").replace(/,/g, "") - : x.toString(10); + return null; } -// Computes the decimal coefficient and exponent of the specified number x with -// significant digits p, where x is positive and p is in [1, 21] or undefined. -// For example, formatDecimalParts(1.23) returns ["123", 0]. -function formatDecimalParts(x, p) { - if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity - var i, coefficient = x.slice(0, i); - - // The string returned by toExponential either has the form \d\.\d+e[-+]\d+ - // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3). - return [ - coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient, - +x.slice(i + 1) - ]; +function selection_size() { + let size = 0; + for (const node of this) ++size; // eslint-disable-line no-unused-vars + return size; } -function exponent(x) { - return x = formatDecimalParts(Math.abs(x)), x ? x[1] : NaN; +function selection_empty() { + return !this.node(); } -function formatGroup(grouping, thousands) { - return function(value, width) { - var i = value.length, - t = [], - j = 0, - g = grouping[0], - length = 0; +function selection_each(callback) { - while (i > 0 && g > 0) { - if (length + g + 1 > width) g = Math.max(1, width - length); - t.push(value.substring(i -= g, i + g)); - if ((length += g + 1) > width) break; - g = grouping[j = (j + 1) % grouping.length]; + for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { + for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) { + if (node = group[i]) callback.call(node, node.__data__, i, group); } + } - return t.reverse().join(thousands); + return this; +} + +function attrRemove$1(name) { + return function() { + this.removeAttribute(name); }; } -function formatNumerals(numerals) { - return function(value) { - return value.replace(/[0-9]/g, function(i) { - return numerals[+i]; - }); +function attrRemoveNS$1(fullname) { + return function() { + this.removeAttributeNS(fullname.space, fullname.local); }; } -// [[fill]align][sign][symbol][0][width][,][.precision][~][type] -var re = /^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i; +function attrConstant$1(name, value) { + return function() { + this.setAttribute(name, value); + }; +} -function formatSpecifier(specifier) { - if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier); - var match; - return new FormatSpecifier({ - fill: match[1], - align: match[2], - sign: match[3], - symbol: match[4], - zero: match[5], - width: match[6], - comma: match[7], - precision: match[8] && match[8].slice(1), - trim: match[9], - type: match[10] - }); +function attrConstantNS$1(fullname, value) { + return function() { + this.setAttributeNS(fullname.space, fullname.local, value); + }; } -formatSpecifier.prototype = FormatSpecifier.prototype; // instanceof +function attrFunction$1(name, value) { + return function() { + var v = value.apply(this, arguments); + if (v == null) this.removeAttribute(name); + else this.setAttribute(name, v); + }; +} -function FormatSpecifier(specifier) { - this.fill = specifier.fill === undefined ? " " : specifier.fill + ""; - this.align = specifier.align === undefined ? ">" : specifier.align + ""; - this.sign = specifier.sign === undefined ? "-" : specifier.sign + ""; - this.symbol = specifier.symbol === undefined ? "" : specifier.symbol + ""; - this.zero = !!specifier.zero; - this.width = specifier.width === undefined ? undefined : +specifier.width; - this.comma = !!specifier.comma; - this.precision = specifier.precision === undefined ? undefined : +specifier.precision; - this.trim = !!specifier.trim; - this.type = specifier.type === undefined ? "" : specifier.type + ""; +function attrFunctionNS$1(fullname, value) { + return function() { + var v = value.apply(this, arguments); + if (v == null) this.removeAttributeNS(fullname.space, fullname.local); + else this.setAttributeNS(fullname.space, fullname.local, v); + }; } -FormatSpecifier.prototype.toString = function() { - return this.fill - + this.align - + this.sign - + this.symbol - + (this.zero ? "0" : "") - + (this.width === undefined ? "" : Math.max(1, this.width | 0)) - + (this.comma ? "," : "") - + (this.precision === undefined ? "" : "." + Math.max(0, this.precision | 0)) - + (this.trim ? "~" : "") - + this.type; -}; +function selection_attr(name, value) { + var fullname = namespace(name); -// Trims insignificant zeros, e.g., replaces 1.2000k with 1.2k. -function formatTrim(s) { - out: for (var n = s.length, i = 1, i0 = -1, i1; i < n; ++i) { - switch (s[i]) { - case ".": i0 = i1 = i; break; - case "0": if (i0 === 0) i0 = i; i1 = i; break; - default: if (!+s[i]) break out; if (i0 > 0) i0 = 0; break; - } + if (arguments.length < 2) { + var node = this.node(); + return fullname.local + ? node.getAttributeNS(fullname.space, fullname.local) + : node.getAttribute(fullname); } - return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s; + + return this.each((value == null + ? (fullname.local ? attrRemoveNS$1 : attrRemove$1) : (typeof value === "function" + ? (fullname.local ? attrFunctionNS$1 : attrFunction$1) + : (fullname.local ? attrConstantNS$1 : attrConstant$1)))(fullname, value)); } -var prefixExponent; +function defaultView(node) { + return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node + || (node.document && node) // node is a Window + || node.defaultView; // node is a Document +} -function formatPrefixAuto(x, p) { - var d = formatDecimalParts(x, p); - if (!d) return x + ""; - var coefficient = d[0], - exponent = d[1], - i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1, - n = coefficient.length; - return i === n ? coefficient - : i > n ? coefficient + new Array(i - n + 1).join("0") - : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i) - : "0." + new Array(1 - i).join("0") + formatDecimalParts(x, Math.max(0, p + i - 1))[0]; // less than 1y! +function styleRemove$1(name) { + return function() { + this.style.removeProperty(name); + }; } -function formatRounded(x, p) { - var d = formatDecimalParts(x, p); - if (!d) return x + ""; - var coefficient = d[0], - exponent = d[1]; - return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient - : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1) - : coefficient + new Array(exponent - coefficient.length + 2).join("0"); +function styleConstant$1(name, value, priority) { + return function() { + this.style.setProperty(name, value, priority); + }; } -var formatTypes = { - "%": (x, p) => (x * 100).toFixed(p), - "b": (x) => Math.round(x).toString(2), - "c": (x) => x + "", - "d": formatDecimal, - "e": (x, p) => x.toExponential(p), - "f": (x, p) => x.toFixed(p), - "g": (x, p) => x.toPrecision(p), - "o": (x) => Math.round(x).toString(8), - "p": (x, p) => formatRounded(x * 100, p), - "r": formatRounded, - "s": formatPrefixAuto, - "X": (x) => Math.round(x).toString(16).toUpperCase(), - "x": (x) => Math.round(x).toString(16) -}; +function styleFunction$1(name, value, priority) { + return function() { + var v = value.apply(this, arguments); + if (v == null) this.style.removeProperty(name); + else this.style.setProperty(name, v, priority); + }; +} -function identity$3(x) { - return x; +function selection_style(name, value, priority) { + return arguments.length > 1 + ? this.each((value == null + ? styleRemove$1 : typeof value === "function" + ? styleFunction$1 + : styleConstant$1)(name, value, priority == null ? "" : priority)) + : styleValue(this.node(), name); +} + +function styleValue(node, name) { + return node.style.getPropertyValue(name) + || defaultView(node).getComputedStyle(node, null).getPropertyValue(name); } -var map$1 = Array.prototype.map, - prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"]; +function propertyRemove(name) { + return function() { + delete this[name]; + }; +} -function formatLocale(locale) { - var group = locale.grouping === undefined || locale.thousands === undefined ? identity$3 : formatGroup(map$1.call(locale.grouping, Number), locale.thousands + ""), - currencyPrefix = locale.currency === undefined ? "" : locale.currency[0] + "", - currencySuffix = locale.currency === undefined ? "" : locale.currency[1] + "", - decimal = locale.decimal === undefined ? "." : locale.decimal + "", - numerals = locale.numerals === undefined ? identity$3 : formatNumerals(map$1.call(locale.numerals, String)), - percent = locale.percent === undefined ? "%" : locale.percent + "", - minus = locale.minus === undefined ? "−" : locale.minus + "", - nan = locale.nan === undefined ? "NaN" : locale.nan + ""; +function propertyConstant(name, value) { + return function() { + this[name] = value; + }; +} - function newFormat(specifier) { - specifier = formatSpecifier(specifier); +function propertyFunction(name, value) { + return function() { + var v = value.apply(this, arguments); + if (v == null) delete this[name]; + else this[name] = v; + }; +} - var fill = specifier.fill, - align = specifier.align, - sign = specifier.sign, - symbol = specifier.symbol, - zero = specifier.zero, - width = specifier.width, - comma = specifier.comma, - precision = specifier.precision, - trim = specifier.trim, - type = specifier.type; +function selection_property(name, value) { + return arguments.length > 1 + ? this.each((value == null + ? propertyRemove : typeof value === "function" + ? propertyFunction + : propertyConstant)(name, value)) + : this.node()[name]; +} - // The "n" type is an alias for ",g". - if (type === "n") comma = true, type = "g"; +function classArray(string) { + return string.trim().split(/^|\s+/); +} - // The "" type, and any invalid type, is an alias for ".12~g". - else if (!formatTypes[type]) precision === undefined && (precision = 12), trim = true, type = "g"; +function classList(node) { + return node.classList || new ClassList(node); +} - // If zero fill is specified, padding goes after sign and before digits. - if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "="; +function ClassList(node) { + this._node = node; + this._names = classArray(node.getAttribute("class") || ""); +} - // Compute the prefix and suffix. - // For SI-prefix, the suffix is lazily computed. - var prefix = symbol === "$" ? currencyPrefix : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "", - suffix = symbol === "$" ? currencySuffix : /[%p]/.test(type) ? percent : ""; +ClassList.prototype = { + add: function(name) { + var i = this._names.indexOf(name); + if (i < 0) { + this._names.push(name); + this._node.setAttribute("class", this._names.join(" ")); + } + }, + remove: function(name) { + var i = this._names.indexOf(name); + if (i >= 0) { + this._names.splice(i, 1); + this._node.setAttribute("class", this._names.join(" ")); + } + }, + contains: function(name) { + return this._names.indexOf(name) >= 0; + } +}; - // What format function should we use? - // Is this an integer type? - // Can this type generate exponential notation? - var formatType = formatTypes[type], - maybeSuffix = /[defgprs%]/.test(type); +function classedAdd(node, names) { + var list = classList(node), i = -1, n = names.length; + while (++i < n) list.add(names[i]); +} - // Set the default precision if not specified, - // or clamp the specified precision to the supported range. - // For significant precision, it must be in [1, 21]. - // For fixed precision, it must be in [0, 20]. - precision = precision === undefined ? 6 - : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision)) - : Math.max(0, Math.min(20, precision)); +function classedRemove(node, names) { + var list = classList(node), i = -1, n = names.length; + while (++i < n) list.remove(names[i]); +} - function format(value) { - var valuePrefix = prefix, - valueSuffix = suffix, - i, n, c; +function classedTrue(names) { + return function() { + classedAdd(this, names); + }; +} - if (type === "c") { - valueSuffix = formatType(value) + valueSuffix; - value = ""; - } else { - value = +value; +function classedFalse(names) { + return function() { + classedRemove(this, names); + }; +} - // Determine the sign. -0 is not less than 0, but 1 / -0 is! - var valueNegative = value < 0 || 1 / value < 0; +function classedFunction(names, value) { + return function() { + (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names); + }; +} - // Perform the initial formatting. - value = isNaN(value) ? nan : formatType(Math.abs(value), precision); +function selection_classed(name, value) { + var names = classArray(name + ""); - // Trim insignificant zeros. - if (trim) value = formatTrim(value); + if (arguments.length < 2) { + var list = classList(this.node()), i = -1, n = names.length; + while (++i < n) if (!list.contains(names[i])) return false; + return true; + } - // If a negative value rounds to zero after formatting, and no explicit positive sign is requested, hide the sign. - if (valueNegative && +value === 0 && sign !== "+") valueNegative = false; + return this.each((typeof value === "function" + ? classedFunction : value + ? classedTrue + : classedFalse)(names, value)); +} - // Compute the prefix and suffix. - valuePrefix = (valueNegative ? (sign === "(" ? sign : minus) : sign === "-" || sign === "(" ? "" : sign) + valuePrefix; - valueSuffix = (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + valueSuffix + (valueNegative && sign === "(" ? ")" : ""); +function textRemove() { + this.textContent = ""; +} - // Break the formatted value into the integer “value” part that can be - // grouped, and fractional or exponential “suffix” part that is not. - if (maybeSuffix) { - i = -1, n = value.length; - while (++i < n) { - if (c = value.charCodeAt(i), 48 > c || c > 57) { - valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix; - value = value.slice(0, i); - break; - } - } - } - } +function textConstant$1(value) { + return function() { + this.textContent = value; + }; +} - // If the fill character is not "0", grouping is applied before padding. - if (comma && !zero) value = group(value, Infinity); +function textFunction$1(value) { + return function() { + var v = value.apply(this, arguments); + this.textContent = v == null ? "" : v; + }; +} - // Compute the padding. - var length = valuePrefix.length + value.length + valueSuffix.length, - padding = length < width ? new Array(width - length + 1).join(fill) : ""; +function selection_text(value) { + return arguments.length + ? this.each(value == null + ? textRemove : (typeof value === "function" + ? textFunction$1 + : textConstant$1)(value)) + : this.node().textContent; +} - // If the fill character is "0", grouping is applied after padding. - if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = ""; +function htmlRemove() { + this.innerHTML = ""; +} - // Reconstruct the final output based on the desired alignment. - switch (align) { - case "<": value = valuePrefix + value + valueSuffix + padding; break; - case "=": value = valuePrefix + padding + value + valueSuffix; break; - case "^": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break; - default: value = padding + valuePrefix + value + valueSuffix; break; - } +function htmlConstant(value) { + return function() { + this.innerHTML = value; + }; +} - return numerals(value); - } +function htmlFunction(value) { + return function() { + var v = value.apply(this, arguments); + this.innerHTML = v == null ? "" : v; + }; +} - format.toString = function() { - return specifier + ""; - }; +function selection_html(value) { + return arguments.length + ? this.each(value == null + ? htmlRemove : (typeof value === "function" + ? htmlFunction + : htmlConstant)(value)) + : this.node().innerHTML; +} - return format; - } +function raise() { + if (this.nextSibling) this.parentNode.appendChild(this); +} - function formatPrefix(specifier, value) { - var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)), - e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3, - k = Math.pow(10, -e), - prefix = prefixes[8 + e / 3]; - return function(value) { - return f(k * value) + prefix; - }; - } +function selection_raise() { + return this.each(raise); +} - return { - format: newFormat, - formatPrefix: formatPrefix - }; +function lower() { + if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild); } -var locale; -var format; -var formatPrefix; +function selection_lower() { + return this.each(lower); +} -defaultLocale({ - thousands: ",", - grouping: [3], - currency: ["$", ""] -}); +function selection_append(name) { + var create = typeof name === "function" ? name : creator(name); + return this.select(function() { + return this.appendChild(create.apply(this, arguments)); + }); +} -function defaultLocale(definition) { - locale = formatLocale(definition); - format = locale.format; - formatPrefix = locale.formatPrefix; - return locale; +function constantNull() { + return null; } -function precisionFixed(step) { - return Math.max(0, -exponent(Math.abs(step))); +function selection_insert(name, before) { + var create = typeof name === "function" ? name : creator(name), + select = before == null ? constantNull : typeof before === "function" ? before : selector(before); + return this.select(function() { + return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null); + }); } -function precisionPrefix(step, value) { - return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step))); +function remove() { + var parent = this.parentNode; + if (parent) parent.removeChild(this); } -function precisionRound(step, max) { - step = Math.abs(step), max = Math.abs(max) - step; - return Math.max(0, exponent(max) - exponent(step)) + 1; +function selection_remove() { + return this.each(remove); } -function defaultSeparation$1(a, b) { - return a.parent === b.parent ? 1 : 2; +function selection_cloneShallow() { + var clone = this.cloneNode(false), parent = this.parentNode; + return parent ? parent.insertBefore(clone, this.nextSibling) : clone; } -function meanX(children) { - return children.reduce(meanXReduce, 0) / children.length; +function selection_cloneDeep() { + var clone = this.cloneNode(true), parent = this.parentNode; + return parent ? parent.insertBefore(clone, this.nextSibling) : clone; } -function meanXReduce(x, c) { - return x + c.x; +function selection_clone(deep) { + return this.select(deep ? selection_cloneDeep : selection_cloneShallow); } -function maxY(children) { - return 1 + children.reduce(maxYReduce, 0); +function selection_datum(value) { + return arguments.length + ? this.property("__data__", value) + : this.node().__data__; } -function maxYReduce(y, c) { - return Math.max(y, c.y); +function contextListener(listener) { + return function(event) { + listener.call(this, event, this.__data__); + }; } -function leafLeft(node) { - var children; - while (children = node.children) node = children[0]; - return node; +function parseTypenames(typenames) { + return typenames.trim().split(/^|\s+/).map(function(t) { + var name = "", i = t.indexOf("."); + if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); + return {type: t, name: name}; + }); } -function leafRight(node) { - var children; - while (children = node.children) node = children[children.length - 1]; - return node; +function onRemove(typename) { + return function() { + var on = this.__on; + if (!on) return; + for (var j = 0, i = -1, m = on.length, o; j < m; ++j) { + if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) { + this.removeEventListener(o.type, o.listener, o.options); + } else { + on[++i] = o; + } + } + if (++i) on.length = i; + else delete this.__on; + }; } -function cluster() { - var separation = defaultSeparation$1, - dx = 1, - dy = 1, - nodeSize = false; +function onAdd(typename, value, options) { + return function() { + var on = this.__on, o, listener = contextListener(value); + if (on) for (var j = 0, m = on.length; j < m; ++j) { + if ((o = on[j]).type === typename.type && o.name === typename.name) { + this.removeEventListener(o.type, o.listener, o.options); + this.addEventListener(o.type, o.listener = listener, o.options = options); + o.value = value; + return; + } + } + this.addEventListener(typename.type, listener, options); + o = {type: typename.type, name: typename.name, value: value, listener: listener, options: options}; + if (!on) this.__on = [o]; + else on.push(o); + }; +} - function cluster(root) { - var previousNode, - x = 0; +function selection_on(typename, value, options) { + var typenames = parseTypenames(typename + ""), i, n = typenames.length, t; - // First walk, computing the initial x & y values. - root.eachAfter(function(node) { - var children = node.children; - if (children) { - node.x = meanX(children); - node.y = maxY(children); - } else { - node.x = previousNode ? x += separation(node, previousNode) : 0; - node.y = 0; - previousNode = node; + if (arguments.length < 2) { + var on = this.node().__on; + if (on) for (var j = 0, m = on.length, o; j < m; ++j) { + for (i = 0, o = on[j]; i < n; ++i) { + if ((t = typenames[i]).type === o.type && t.name === o.name) { + return o.value; + } } - }); + } + return; + } - var left = leafLeft(root), - right = leafRight(root), - x0 = left.x - separation(left, right) / 2, - x1 = right.x + separation(right, left) / 2; + on = value ? onAdd : onRemove; + for (i = 0; i < n; ++i) this.each(on(typenames[i], value, options)); + return this; +} - // Second walk, normalizing x & y to the desired size. - return root.eachAfter(nodeSize ? function(node) { - node.x = (node.x - root.x) * dx; - node.y = (root.y - node.y) * dy; - } : function(node) { - node.x = (node.x - x0) / (x1 - x0) * dx; - node.y = (1 - (root.y ? node.y / root.y : 1)) * dy; - }); +function dispatchEvent(node, type, params) { + var window = defaultView(node), + event = window.CustomEvent; + + if (typeof event === "function") { + event = new event(type, params); + } else { + event = window.document.createEvent("Event"); + if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail; + else event.initEvent(type, false, false); } - cluster.separation = function(x) { - return arguments.length ? (separation = x, cluster) : separation; - }; + node.dispatchEvent(event); +} - cluster.size = function(x) { - return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? null : [dx, dy]); +function dispatchConstant(type, params) { + return function() { + return dispatchEvent(this, type, params); }; +} - cluster.nodeSize = function(x) { - return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? [dx, dy] : null); +function dispatchFunction(type, params) { + return function() { + return dispatchEvent(this, type, params.apply(this, arguments)); }; +} - return cluster; +function selection_dispatch(type, params) { + return this.each((typeof params === "function" + ? dispatchFunction + : dispatchConstant)(type, params)); +} + +function* selection_iterator() { + for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { + for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) { + if (node = group[i]) yield node; + } + } +} + +var root = [null]; + +function Selection$1(groups, parents) { + this._groups = groups; + this._parents = parents; +} + +function selection() { + return new Selection$1([[document.documentElement]], root); +} + +function selection_selection() { + return this; +} + +Selection$1.prototype = selection.prototype = { + constructor: Selection$1, + select: selection_select, + selectAll: selection_selectAll, + selectChild: selection_selectChild, + selectChildren: selection_selectChildren, + filter: selection_filter, + data: selection_data, + enter: selection_enter, + exit: selection_exit, + join: selection_join, + merge: selection_merge, + selection: selection_selection, + order: selection_order, + sort: selection_sort, + call: selection_call, + nodes: selection_nodes, + node: selection_node, + size: selection_size, + empty: selection_empty, + each: selection_each, + attr: selection_attr, + style: selection_style, + property: selection_property, + classed: selection_classed, + text: selection_text, + html: selection_html, + raise: selection_raise, + lower: selection_lower, + append: selection_append, + insert: selection_insert, + remove: selection_remove, + clone: selection_clone, + datum: selection_datum, + on: selection_on, + dispatch: selection_dispatch, + [Symbol.iterator]: selection_iterator +}; + +function select(selector) { + return typeof selector === "string" + ? new Selection$1([[document.querySelector(selector)]], [document.documentElement]) + : new Selection$1([[selector]], root); +} + +function sourceEvent(event) { + let sourceEvent; + while (sourceEvent = event.sourceEvent) event = sourceEvent; + return event; } -function count(node) { - var sum = 0, - children = node.children, - i = children && children.length; - if (!i) sum = 1; - else while (--i >= 0) sum += children[i].value; - node.value = sum; +function pointer(event, node) { + event = sourceEvent(event); + if (node === undefined) node = event.currentTarget; + if (node) { + var svg = node.ownerSVGElement || node; + if (svg.createSVGPoint) { + var point = svg.createSVGPoint(); + point.x = event.clientX, point.y = event.clientY; + point = point.matrixTransform(node.getScreenCTM().inverse()); + return [point.x, point.y]; + } + if (node.getBoundingClientRect) { + var rect = node.getBoundingClientRect(); + return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop]; + } + } + return [event.pageX, event.pageY]; } -function node_count() { - return this.eachAfter(count); +function nopropagation$1(event) { + event.stopImmediatePropagation(); } -function node_each(callback, that) { - let index = -1; - for (const node of this) { - callback.call(that, node, ++index, this); - } - return this; +function noevent$1(event) { + event.preventDefault(); + event.stopImmediatePropagation(); } -function node_eachBefore(callback, that) { - var node = this, nodes = [node], children, i, index = -1; - while (node = nodes.pop()) { - callback.call(that, node, ++index, this); - if (children = node.children) { - for (i = children.length - 1; i >= 0; --i) { - nodes.push(children[i]); - } - } +function dragDisable(view) { + var root = view.document.documentElement, + selection = select(view).on("dragstart.drag", noevent$1, true); + if ("onselectstart" in root) { + selection.on("selectstart.drag", noevent$1, true); + } else { + root.__noselect = root.style.MozUserSelect; + root.style.MozUserSelect = "none"; } - return this; } -function node_eachAfter(callback, that) { - var node = this, nodes = [node], next = [], children, i, n, index = -1; - while (node = nodes.pop()) { - next.push(node); - if (children = node.children) { - for (i = 0, n = children.length; i < n; ++i) { - nodes.push(children[i]); - } - } +function yesdrag(view, noclick) { + var root = view.document.documentElement, + selection = select(view).on("dragstart.drag", null); + if (noclick) { + selection.on("click.drag", noevent$1, true); + setTimeout(function() { selection.on("click.drag", null); }, 0); } - while (node = next.pop()) { - callback.call(that, node, ++index, this); + if ("onselectstart" in root) { + selection.on("selectstart.drag", null); + } else { + root.style.MozUserSelect = root.__noselect; + delete root.__noselect; } - return this; } -function node_find(callback, that) { - let index = -1; - for (const node of this) { - if (callback.call(that, node, ++index, this)) { - return node; - } - } -} +var constant$5 = x => () => x; -function node_sum(value) { - return this.eachAfter(function(node) { - var sum = +value(node.data) || 0, - children = node.children, - i = children && children.length; - while (--i >= 0) sum += children[i].value; - node.value = sum; +function DragEvent(type, { + sourceEvent, + subject, + target, + identifier, + active, + x, y, dx, dy, + dispatch +}) { + Object.defineProperties(this, { + type: {value: type, enumerable: true, configurable: true}, + sourceEvent: {value: sourceEvent, enumerable: true, configurable: true}, + subject: {value: subject, enumerable: true, configurable: true}, + target: {value: target, enumerable: true, configurable: true}, + identifier: {value: identifier, enumerable: true, configurable: true}, + active: {value: active, enumerable: true, configurable: true}, + x: {value: x, enumerable: true, configurable: true}, + y: {value: y, enumerable: true, configurable: true}, + dx: {value: dx, enumerable: true, configurable: true}, + dy: {value: dy, enumerable: true, configurable: true}, + _: {value: dispatch} }); } -function node_sort(compare) { - return this.eachBefore(function(node) { - if (node.children) { - node.children.sort(compare); - } - }); -} +DragEvent.prototype.on = function() { + var value = this._.on.apply(this._, arguments); + return value === this._ ? this : value; +}; -function node_path(end) { - var start = this, - ancestor = leastCommonAncestor(start, end), - nodes = [start]; - while (start !== ancestor) { - start = start.parent; - nodes.push(start); - } - var k = nodes.length; - while (end !== ancestor) { - nodes.splice(k, 0, end); - end = end.parent; - } - return nodes; +// Ignore right-click, since that should open the context menu. +function defaultFilter$1(event) { + return !event.ctrlKey && !event.button; } -function leastCommonAncestor(a, b) { - if (a === b) return a; - var aNodes = a.ancestors(), - bNodes = b.ancestors(), - c = null; - a = aNodes.pop(); - b = bNodes.pop(); - while (a === b) { - c = a; - a = aNodes.pop(); - b = bNodes.pop(); - } - return c; +function defaultContainer() { + return this.parentNode; } -function node_ancestors() { - var node = this, nodes = [node]; - while (node = node.parent) { - nodes.push(node); - } - return nodes; +function defaultSubject(event, d) { + return d == null ? {x: event.x, y: event.y} : d; } -function node_descendants() { - return Array.from(this); +function defaultTouchable$1() { + return navigator.maxTouchPoints || ("ontouchstart" in this); } -function node_leaves() { - var leaves = []; - this.eachBefore(function(node) { - if (!node.children) { - leaves.push(node); - } - }); - return leaves; -} +function drag() { + var filter = defaultFilter$1, + container = defaultContainer, + subject = defaultSubject, + touchable = defaultTouchable$1, + gestures = {}, + listeners = dispatch("start", "drag", "end"), + active = 0, + mousedownx, + mousedowny, + mousemoving, + touchending, + clickDistance2 = 0; -function node_links() { - var root = this, links = []; - root.each(function(node) { - if (node !== root) { // Don’t include the root’s parent, if any. - links.push({source: node.parent, target: node}); + function drag(selection) { + selection + .on("mousedown.drag", mousedowned) + .filter(touchable) + .on("touchstart.drag", touchstarted) + .on("touchmove.drag", touchmoved) + .on("touchend.drag touchcancel.drag", touchended) + .style("touch-action", "none") + .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)"); + } + + function mousedowned(event, d) { + if (touchending || !filter.call(this, event, d)) return; + var gesture = beforestart(this, container.call(this, event, d), event, d, "mouse"); + if (!gesture) return; + select(event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true); + dragDisable(event.view); + nopropagation$1(event); + mousemoving = false; + mousedownx = event.clientX; + mousedowny = event.clientY; + gesture("start", event); + } + + function mousemoved(event) { + noevent$1(event); + if (!mousemoving) { + var dx = event.clientX - mousedownx, dy = event.clientY - mousedowny; + mousemoving = dx * dx + dy * dy > clickDistance2; } - }); - return links; -} + gestures.mouse("drag", event); + } -function* node_iterator() { - var node = this, current, next = [node], children, i, n; - do { - current = next.reverse(), next = []; - while (node = current.pop()) { - yield node; - if (children = node.children) { - for (i = 0, n = children.length; i < n; ++i) { - next.push(children[i]); - } + function mouseupped(event) { + select(event.view).on("mousemove.drag mouseup.drag", null); + yesdrag(event.view, mousemoving); + noevent$1(event); + gestures.mouse("end", event); + } + + function touchstarted(event, d) { + if (!filter.call(this, event, d)) return; + var touches = event.changedTouches, + c = container.call(this, event, d), + n = touches.length, i, gesture; + + for (i = 0; i < n; ++i) { + if (gesture = beforestart(this, c, event, d, touches[i].identifier, touches[i])) { + nopropagation$1(event); + gesture("start", event, touches[i]); } } - } while (next.length); -} + } -function hierarchy(data, children) { - if (data instanceof Map) { - data = [undefined, data]; - if (children === undefined) children = mapChildren; - } else if (children === undefined) { - children = objectChildren; + function touchmoved(event) { + var touches = event.changedTouches, + n = touches.length, i, gesture; + + for (i = 0; i < n; ++i) { + if (gesture = gestures[touches[i].identifier]) { + noevent$1(event); + gesture("drag", event, touches[i]); + } + } } - var root = new Node(data), - node, - nodes = [root], - child, - childs, - i, - n; + function touchended(event) { + var touches = event.changedTouches, + n = touches.length, i, gesture; - while (node = nodes.pop()) { - if ((childs = children(node.data)) && (n = (childs = Array.from(childs)).length)) { - node.children = childs; - for (i = n - 1; i >= 0; --i) { - nodes.push(child = childs[i] = new Node(childs[i])); - child.parent = node; - child.depth = node.depth + 1; + if (touchending) clearTimeout(touchending); + touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed! + for (i = 0; i < n; ++i) { + if (gesture = gestures[touches[i].identifier]) { + nopropagation$1(event); + gesture("end", event, touches[i]); } } } - return root.eachBefore(computeHeight); -} + function beforestart(that, container, event, d, identifier, touch) { + var dispatch = listeners.copy(), + p = pointer(touch || event, container), dx, dy, + s; -function node_copy() { - return hierarchy(this).eachBefore(copyData); -} + if ((s = subject.call(that, new DragEvent("beforestart", { + sourceEvent: event, + target: drag, + identifier, + active, + x: p[0], + y: p[1], + dx: 0, + dy: 0, + dispatch + }), d)) == null) return; -function objectChildren(d) { - return d.children; + dx = s.x - p[0] || 0; + dy = s.y - p[1] || 0; + + return function gesture(type, event, touch) { + var p0 = p, n; + switch (type) { + case "start": gestures[identifier] = gesture, n = active++; break; + case "end": delete gestures[identifier], --active; // nobreak + case "drag": p = pointer(touch || event, container), n = active; break; + } + dispatch.call( + type, + that, + new DragEvent(type, { + sourceEvent: event, + subject: s, + target: drag, + identifier, + active: n, + x: p[0] + dx, + y: p[1] + dy, + dx: p[0] - p0[0], + dy: p[1] - p0[1], + dispatch + }), + d + ); + }; + } + + drag.filter = function(_) { + return arguments.length ? (filter = typeof _ === "function" ? _ : constant$5(!!_), drag) : filter; + }; + + drag.container = function(_) { + return arguments.length ? (container = typeof _ === "function" ? _ : constant$5(_), drag) : container; + }; + + drag.subject = function(_) { + return arguments.length ? (subject = typeof _ === "function" ? _ : constant$5(_), drag) : subject; + }; + + drag.touchable = function(_) { + return arguments.length ? (touchable = typeof _ === "function" ? _ : constant$5(!!_), drag) : touchable; + }; + + drag.on = function() { + var value = listeners.on.apply(listeners, arguments); + return value === listeners ? drag : value; + }; + + drag.clickDistance = function(_) { + return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2); + }; + + return drag; } -function mapChildren(d) { - return Array.isArray(d) ? d[1] : null; +function define(constructor, factory, prototype) { + constructor.prototype = factory.prototype = prototype; + prototype.constructor = constructor; } -function copyData(node) { - if (node.data.value !== undefined) node.value = node.data.value; - node.data = node.data.data; +function extend(parent, definition) { + var prototype = Object.create(parent.prototype); + for (var key in definition) prototype[key] = definition[key]; + return prototype; } -function computeHeight(node) { - var height = 0; - do node.height = height; - while ((node = node.parent) && (node.height < ++height)); -} +function Color() {} + +var darker = 0.7; +var brighter = 1 / darker; + +var reI = "\\s*([+-]?\\d+)\\s*", + reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*", + reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*", + reHex = /^#([0-9a-f]{3,8})$/, + reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$"), + reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$"), + reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$"), + reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$"), + reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$"), + reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$"); + +var named = { + aliceblue: 0xf0f8ff, + antiquewhite: 0xfaebd7, + aqua: 0x00ffff, + aquamarine: 0x7fffd4, + azure: 0xf0ffff, + beige: 0xf5f5dc, + bisque: 0xffe4c4, + black: 0x000000, + blanchedalmond: 0xffebcd, + blue: 0x0000ff, + blueviolet: 0x8a2be2, + brown: 0xa52a2a, + burlywood: 0xdeb887, + cadetblue: 0x5f9ea0, + chartreuse: 0x7fff00, + chocolate: 0xd2691e, + coral: 0xff7f50, + cornflowerblue: 0x6495ed, + cornsilk: 0xfff8dc, + crimson: 0xdc143c, + cyan: 0x00ffff, + darkblue: 0x00008b, + darkcyan: 0x008b8b, + darkgoldenrod: 0xb8860b, + darkgray: 0xa9a9a9, + darkgreen: 0x006400, + darkgrey: 0xa9a9a9, + darkkhaki: 0xbdb76b, + darkmagenta: 0x8b008b, + darkolivegreen: 0x556b2f, + darkorange: 0xff8c00, + darkorchid: 0x9932cc, + darkred: 0x8b0000, + darksalmon: 0xe9967a, + darkseagreen: 0x8fbc8f, + darkslateblue: 0x483d8b, + darkslategray: 0x2f4f4f, + darkslategrey: 0x2f4f4f, + darkturquoise: 0x00ced1, + darkviolet: 0x9400d3, + deeppink: 0xff1493, + deepskyblue: 0x00bfff, + dimgray: 0x696969, + dimgrey: 0x696969, + dodgerblue: 0x1e90ff, + firebrick: 0xb22222, + floralwhite: 0xfffaf0, + forestgreen: 0x228b22, + fuchsia: 0xff00ff, + gainsboro: 0xdcdcdc, + ghostwhite: 0xf8f8ff, + gold: 0xffd700, + goldenrod: 0xdaa520, + gray: 0x808080, + green: 0x008000, + greenyellow: 0xadff2f, + grey: 0x808080, + honeydew: 0xf0fff0, + hotpink: 0xff69b4, + indianred: 0xcd5c5c, + indigo: 0x4b0082, + ivory: 0xfffff0, + khaki: 0xf0e68c, + lavender: 0xe6e6fa, + lavenderblush: 0xfff0f5, + lawngreen: 0x7cfc00, + lemonchiffon: 0xfffacd, + lightblue: 0xadd8e6, + lightcoral: 0xf08080, + lightcyan: 0xe0ffff, + lightgoldenrodyellow: 0xfafad2, + lightgray: 0xd3d3d3, + lightgreen: 0x90ee90, + lightgrey: 0xd3d3d3, + lightpink: 0xffb6c1, + lightsalmon: 0xffa07a, + lightseagreen: 0x20b2aa, + lightskyblue: 0x87cefa, + lightslategray: 0x778899, + lightslategrey: 0x778899, + lightsteelblue: 0xb0c4de, + lightyellow: 0xffffe0, + lime: 0x00ff00, + limegreen: 0x32cd32, + linen: 0xfaf0e6, + magenta: 0xff00ff, + maroon: 0x800000, + mediumaquamarine: 0x66cdaa, + mediumblue: 0x0000cd, + mediumorchid: 0xba55d3, + mediumpurple: 0x9370db, + mediumseagreen: 0x3cb371, + mediumslateblue: 0x7b68ee, + mediumspringgreen: 0x00fa9a, + mediumturquoise: 0x48d1cc, + mediumvioletred: 0xc71585, + midnightblue: 0x191970, + mintcream: 0xf5fffa, + mistyrose: 0xffe4e1, + moccasin: 0xffe4b5, + navajowhite: 0xffdead, + navy: 0x000080, + oldlace: 0xfdf5e6, + olive: 0x808000, + olivedrab: 0x6b8e23, + orange: 0xffa500, + orangered: 0xff4500, + orchid: 0xda70d6, + palegoldenrod: 0xeee8aa, + palegreen: 0x98fb98, + paleturquoise: 0xafeeee, + palevioletred: 0xdb7093, + papayawhip: 0xffefd5, + peachpuff: 0xffdab9, + peru: 0xcd853f, + pink: 0xffc0cb, + plum: 0xdda0dd, + powderblue: 0xb0e0e6, + purple: 0x800080, + rebeccapurple: 0x663399, + red: 0xff0000, + rosybrown: 0xbc8f8f, + royalblue: 0x4169e1, + saddlebrown: 0x8b4513, + salmon: 0xfa8072, + sandybrown: 0xf4a460, + seagreen: 0x2e8b57, + seashell: 0xfff5ee, + sienna: 0xa0522d, + silver: 0xc0c0c0, + skyblue: 0x87ceeb, + slateblue: 0x6a5acd, + slategray: 0x708090, + slategrey: 0x708090, + snow: 0xfffafa, + springgreen: 0x00ff7f, + steelblue: 0x4682b4, + tan: 0xd2b48c, + teal: 0x008080, + thistle: 0xd8bfd8, + tomato: 0xff6347, + turquoise: 0x40e0d0, + violet: 0xee82ee, + wheat: 0xf5deb3, + white: 0xffffff, + whitesmoke: 0xf5f5f5, + yellow: 0xffff00, + yellowgreen: 0x9acd32 +}; + +define(Color, color, { + copy: function(channels) { + return Object.assign(new this.constructor, this, channels); + }, + displayable: function() { + return this.rgb().displayable(); + }, + hex: color_formatHex, // Deprecated! Use color.formatHex. + formatHex: color_formatHex, + formatHsl: color_formatHsl, + formatRgb: color_formatRgb, + toString: color_formatRgb +}); -function Node(data) { - this.data = data; - this.depth = - this.height = 0; - this.parent = null; +function color_formatHex() { + return this.rgb().formatHex(); } -Node.prototype = hierarchy.prototype = { - constructor: Node, - count: node_count, - each: node_each, - eachAfter: node_eachAfter, - eachBefore: node_eachBefore, - find: node_find, - sum: node_sum, - sort: node_sort, - path: node_path, - ancestors: node_ancestors, - descendants: node_descendants, - leaves: node_leaves, - links: node_links, - copy: node_copy, - [Symbol.iterator]: node_iterator -}; - -function required(f) { - if (typeof f !== "function") throw new Error; - return f; +function color_formatHsl() { + return hslConvert(this).formatHsl(); } -function constantZero() { - return 0; +function color_formatRgb() { + return this.rgb().formatRgb(); } -function constant$3(x) { - return function() { - return x; - }; +function color(format) { + var m, l; + format = (format + "").trim().toLowerCase(); + return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) // #ff0000 + : l === 3 ? new Rgb((m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1) // #f00 + : l === 8 ? rgba(m >> 24 & 0xff, m >> 16 & 0xff, m >> 8 & 0xff, (m & 0xff) / 0xff) // #ff000000 + : l === 4 ? rgba((m >> 12 & 0xf) | (m >> 8 & 0xf0), (m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), (((m & 0xf) << 4) | (m & 0xf)) / 0xff) // #f000 + : null) // invalid hex + : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0) + : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%) + : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1) + : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1) + : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%) + : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1) + : named.hasOwnProperty(format) ? rgbn(named[format]) // eslint-disable-line no-prototype-builtins + : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) + : null; } -function roundNode(node) { - node.x0 = Math.round(node.x0); - node.y0 = Math.round(node.y0); - node.x1 = Math.round(node.x1); - node.y1 = Math.round(node.y1); +function rgbn(n) { + return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1); } -function treemapDice(parent, x0, y0, x1, y1) { - var nodes = parent.children, - node, - i = -1, - n = nodes.length, - k = parent.value && (x1 - x0) / parent.value; - - while (++i < n) { - node = nodes[i], node.y0 = y0, node.y1 = y1; - node.x0 = x0, node.x1 = x0 += node.value * k; - } +function rgba(r, g, b, a) { + if (a <= 0) r = g = b = NaN; + return new Rgb(r, g, b, a); } -function partition() { - var dx = 1, - dy = 1, - padding = 0, - round = false; - - function partition(root) { - var n = root.height + 1; - root.x0 = - root.y0 = padding; - root.x1 = dx; - root.y1 = dy / n; - root.eachBefore(positionNode(dy, n)); - if (round) root.eachBefore(roundNode); - return root; - } - - function positionNode(dy, n) { - return function(node) { - if (node.children) { - treemapDice(node, node.x0, dy * (node.depth + 1) / n, node.x1, dy * (node.depth + 2) / n); - } - var x0 = node.x0, - y0 = node.y0, - x1 = node.x1 - padding, - y1 = node.y1 - padding; - if (x1 < x0) x0 = x1 = (x0 + x1) / 2; - if (y1 < y0) y0 = y1 = (y0 + y1) / 2; - node.x0 = x0; - node.y0 = y0; - node.x1 = x1; - node.y1 = y1; - }; - } - - partition.round = function(x) { - return arguments.length ? (round = !!x, partition) : round; - }; - - partition.size = function(x) { - return arguments.length ? (dx = +x[0], dy = +x[1], partition) : [dx, dy]; - }; - - partition.padding = function(x) { - return arguments.length ? (padding = +x, partition) : padding; - }; - - return partition; +function rgbConvert(o) { + if (!(o instanceof Color)) o = color(o); + if (!o) return new Rgb; + o = o.rgb(); + return new Rgb(o.r, o.g, o.b, o.opacity); } -var preroot = {depth: -1}, - ambiguous = {}; - -function defaultId(d) { - return d.id; +function rgb(r, g, b, opacity) { + return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity); } -function defaultParentId(d) { - return d.parentId; +function Rgb(r, g, b, opacity) { + this.r = +r; + this.g = +g; + this.b = +b; + this.opacity = +opacity; } -function stratify() { - var id = defaultId, - parentId = defaultParentId; - - function stratify(data) { - var nodes = Array.from(data), - n = nodes.length, - d, - i, - root, - parent, - node, - nodeId, - nodeKey, - nodeByKey = new Map; - - for (i = 0; i < n; ++i) { - d = nodes[i], node = nodes[i] = new Node(d); - if ((nodeId = id(d, i, data)) != null && (nodeId += "")) { - nodeKey = node.id = nodeId; - nodeByKey.set(nodeKey, nodeByKey.has(nodeKey) ? ambiguous : node); - } - if ((nodeId = parentId(d, i, data)) != null && (nodeId += "")) { - node.parent = nodeId; - } - } - - for (i = 0; i < n; ++i) { - node = nodes[i]; - if (nodeId = node.parent) { - parent = nodeByKey.get(nodeId); - if (!parent) throw new Error("missing: " + nodeId); - if (parent === ambiguous) throw new Error("ambiguous: " + nodeId); - if (parent.children) parent.children.push(node); - else parent.children = [node]; - node.parent = parent; - } else { - if (root) throw new Error("multiple roots"); - root = node; - } - } - - if (!root) throw new Error("no root"); - root.parent = preroot; - root.eachBefore(function(node) { node.depth = node.parent.depth + 1; --n; }).eachBefore(computeHeight); - root.parent = null; - if (n > 0) throw new Error("cycle"); - - return root; - } - - stratify.id = function(x) { - return arguments.length ? (id = required(x), stratify) : id; - }; - - stratify.parentId = function(x) { - return arguments.length ? (parentId = required(x), stratify) : parentId; - }; - - return stratify; -} +define(Rgb, rgb, extend(Color, { + brighter: function(k) { + k = k == null ? brighter : Math.pow(brighter, k); + return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); + }, + darker: function(k) { + k = k == null ? darker : Math.pow(darker, k); + return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); + }, + rgb: function() { + return this; + }, + displayable: function() { + return (-0.5 <= this.r && this.r < 255.5) + && (-0.5 <= this.g && this.g < 255.5) + && (-0.5 <= this.b && this.b < 255.5) + && (0 <= this.opacity && this.opacity <= 1); + }, + hex: rgb_formatHex, // Deprecated! Use color.formatHex. + formatHex: rgb_formatHex, + formatRgb: rgb_formatRgb, + toString: rgb_formatRgb +})); -function defaultSeparation(a, b) { - return a.parent === b.parent ? 1 : 2; +function rgb_formatHex() { + return "#" + hex(this.r) + hex(this.g) + hex(this.b); } -// function radialSeparation(a, b) { -// return (a.parent === b.parent ? 1 : 2) / a.depth; -// } - -// This function is used to traverse the left contour of a subtree (or -// subforest). It returns the successor of v on this contour. This successor is -// either given by the leftmost child of v or by the thread of v. The function -// returns null if and only if v is on the highest level of its subtree. -function nextLeft(v) { - var children = v.children; - return children ? children[0] : v.t; +function rgb_formatRgb() { + var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a)); + return (a === 1 ? "rgb(" : "rgba(") + + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", " + + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", " + + Math.max(0, Math.min(255, Math.round(this.b) || 0)) + + (a === 1 ? ")" : ", " + a + ")"); } -// This function works analogously to nextLeft. -function nextRight(v) { - var children = v.children; - return children ? children[children.length - 1] : v.t; +function hex(value) { + value = Math.max(0, Math.min(255, Math.round(value) || 0)); + return (value < 16 ? "0" : "") + value.toString(16); } -// Shifts the current subtree rooted at w+. This is done by increasing -// prelim(w+) and mod(w+) by shift. -function moveSubtree(wm, wp, shift) { - var change = shift / (wp.i - wm.i); - wp.c -= change; - wp.s += shift; - wm.c += change; - wp.z += shift; - wp.m += shift; +function hsla(h, s, l, a) { + if (a <= 0) h = s = l = NaN; + else if (l <= 0 || l >= 1) h = s = NaN; + else if (s <= 0) h = NaN; + return new Hsl(h, s, l, a); } -// All other shifts, applied to the smaller subtrees between w- and w+, are -// performed by this function. To prepare the shifts, we have to adjust -// change(w+), shift(w+), and change(w-). -function executeShifts(v) { - var shift = 0, - change = 0, - children = v.children, - i = children.length, - w; - while (--i >= 0) { - w = children[i]; - w.z += shift; - w.m += shift; - shift += w.s + (change += w.c); +function hslConvert(o) { + if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity); + if (!(o instanceof Color)) o = color(o); + if (!o) return new Hsl; + if (o instanceof Hsl) return o; + o = o.rgb(); + var r = o.r / 255, + g = o.g / 255, + b = o.b / 255, + min = Math.min(r, g, b), + max = Math.max(r, g, b), + h = NaN, + s = max - min, + l = (max + min) / 2; + if (s) { + if (r === max) h = (g - b) / s + (g < b) * 6; + else if (g === max) h = (b - r) / s + 2; + else h = (r - g) / s + 4; + s /= l < 0.5 ? max + min : 2 - max - min; + h *= 60; + } else { + s = l > 0 && l < 1 ? 0 : h; } + return new Hsl(h, s, l, o.opacity); } -// If vi-’s ancestor is a sibling of v, returns vi-’s ancestor. Otherwise, -// returns the specified (default) ancestor. -function nextAncestor(vim, v, ancestor) { - return vim.a.parent === v.parent ? vim.a : ancestor; +function hsl(h, s, l, opacity) { + return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity); } -function TreeNode(node, i) { - this._ = node; - this.parent = null; - this.children = null; - this.A = null; // default ancestor - this.a = this; // ancestor - this.z = 0; // prelim - this.m = 0; // mod - this.c = 0; // change - this.s = 0; // shift - this.t = null; // thread - this.i = i; // number +function Hsl(h, s, l, opacity) { + this.h = +h; + this.s = +s; + this.l = +l; + this.opacity = +opacity; } -TreeNode.prototype = Object.create(Node.prototype); - -function treeRoot(root) { - var tree = new TreeNode(root, 0), - node, - nodes = [tree], - child, - children, - i, - n; - - while (node = nodes.pop()) { - if (children = node._.children) { - node.children = new Array(n = children.length); - for (i = n - 1; i >= 0; --i) { - nodes.push(child = node.children[i] = new TreeNode(children[i], i)); - child.parent = node; - } - } +define(Hsl, hsl, extend(Color, { + brighter: function(k) { + k = k == null ? brighter : Math.pow(brighter, k); + return new Hsl(this.h, this.s, this.l * k, this.opacity); + }, + darker: function(k) { + k = k == null ? darker : Math.pow(darker, k); + return new Hsl(this.h, this.s, this.l * k, this.opacity); + }, + rgb: function() { + var h = this.h % 360 + (this.h < 0) * 360, + s = isNaN(h) || isNaN(this.s) ? 0 : this.s, + l = this.l, + m2 = l + (l < 0.5 ? l : 1 - l) * s, + m1 = 2 * l - m2; + return new Rgb( + hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2), + hsl2rgb(h, m1, m2), + hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2), + this.opacity + ); + }, + displayable: function() { + return (0 <= this.s && this.s <= 1 || isNaN(this.s)) + && (0 <= this.l && this.l <= 1) + && (0 <= this.opacity && this.opacity <= 1); + }, + formatHsl: function() { + var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a)); + return (a === 1 ? "hsl(" : "hsla(") + + (this.h || 0) + ", " + + (this.s || 0) * 100 + "%, " + + (this.l || 0) * 100 + "%" + + (a === 1 ? ")" : ", " + a + ")"); } +})); - (tree.parent = new TreeNode(null, 0)).children = [tree]; - return tree; +/* From FvD 13.37, CSS Color Module Level 3 */ +function hsl2rgb(h, m1, m2) { + return (h < 60 ? m1 + (m2 - m1) * h / 60 + : h < 180 ? m2 + : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60 + : m1) * 255; } -// Node-link tree diagram using the Reingold-Tilford "tidy" algorithm -function tree() { - var separation = defaultSeparation, - dx = 1, - dy = 1, - nodeSize = null; - - function tree(root) { - var t = treeRoot(root); - - // Compute the layout using Buchheim et al.’s algorithm. - t.eachAfter(firstWalk), t.parent.m = -t.z; - t.eachBefore(secondWalk); - - // If a fixed node size is specified, scale x and y. - if (nodeSize) root.eachBefore(sizeNode); +const radians = Math.PI / 180; +const degrees$1 = 180 / Math.PI; - // If a fixed tree size is specified, scale x and y based on the extent. - // Compute the left-most, right-most, and depth-most nodes for extents. - else { - var left = root, - right = root, - bottom = root; - root.eachBefore(function(node) { - if (node.x < left.x) left = node; - if (node.x > right.x) right = node; - if (node.depth > bottom.depth) bottom = node; - }); - var s = left === right ? 1 : separation(left, right) / 2, - tx = s - left.x, - kx = dx / (right.x + s + tx), - ky = dy / (bottom.depth || 1); - root.eachBefore(function(node) { - node.x = (node.x + tx) * kx; - node.y = node.depth * ky; - }); - } +var A = -0.14861, + B = +1.78277, + C = -0.29227, + D = -0.90649, + E = +1.97294, + ED = E * D, + EB = E * B, + BC_DA = B * C - D * A; - return root; - } +function cubehelixConvert(o) { + if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity); + if (!(o instanceof Rgb)) o = rgbConvert(o); + var r = o.r / 255, + g = o.g / 255, + b = o.b / 255, + l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB), + bl = b - l, + k = (E * (g - l) - C * bl) / D, + s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1 + h = s ? Math.atan2(k, bl) * degrees$1 - 120 : NaN; + return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity); +} - // Computes a preliminary x-coordinate for v. Before that, FIRST WALK is - // applied recursively to the children of v, as well as the function - // APPORTION. After spacing out the children by calling EXECUTE SHIFTS, the - // node v is placed to the midpoint of its outermost children. - function firstWalk(v) { - var children = v.children, - siblings = v.parent.children, - w = v.i ? siblings[v.i - 1] : null; - if (children) { - executeShifts(v); - var midpoint = (children[0].z + children[children.length - 1].z) / 2; - if (w) { - v.z = w.z + separation(v._, w._); - v.m = v.z - midpoint; - } else { - v.z = midpoint; - } - } else if (w) { - v.z = w.z + separation(v._, w._); - } - v.parent.A = apportion(v, w, v.parent.A || siblings[0]); - } +function cubehelix$1(h, s, l, opacity) { + return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity); +} - // Computes all real x-coordinates by summing up the modifiers recursively. - function secondWalk(v) { - v._.x = v.z + v.parent.m; - v.m += v.parent.m; - } +function Cubehelix(h, s, l, opacity) { + this.h = +h; + this.s = +s; + this.l = +l; + this.opacity = +opacity; +} - // The core of the algorithm. Here, a new subtree is combined with the - // previous subtrees. Threads are used to traverse the inside and outside - // contours of the left and right subtree up to the highest common level. The - // vertices used for the traversals are vi+, vi-, vo-, and vo+, where the - // superscript o means outside and i means inside, the subscript - means left - // subtree and + means right subtree. For summing up the modifiers along the - // contour, we use respective variables si+, si-, so-, and so+. Whenever two - // nodes of the inside contours conflict, we compute the left one of the - // greatest uncommon ancestors using the function ANCESTOR and call MOVE - // SUBTREE to shift the subtree and prepare the shifts of smaller subtrees. - // Finally, we add a new thread (if necessary). - function apportion(v, w, ancestor) { - if (w) { - var vip = v, - vop = v, - vim = w, - vom = vip.parent.children[0], - sip = vip.m, - sop = vop.m, - sim = vim.m, - som = vom.m, - shift; - while (vim = nextRight(vim), vip = nextLeft(vip), vim && vip) { - vom = nextLeft(vom); - vop = nextRight(vop); - vop.a = v; - shift = vim.z + sim - vip.z - sip + separation(vim._, vip._); - if (shift > 0) { - moveSubtree(nextAncestor(vim, v, ancestor), v, shift); - sip += shift; - sop += shift; - } - sim += vim.m; - sip += vip.m; - som += vom.m; - sop += vop.m; - } - if (vim && !nextRight(vop)) { - vop.t = vim; - vop.m += sim - sop; - } - if (vip && !nextLeft(vom)) { - vom.t = vip; - vom.m += sip - som; - ancestor = v; - } - } - return ancestor; +define(Cubehelix, cubehelix$1, extend(Color, { + brighter: function(k) { + k = k == null ? brighter : Math.pow(brighter, k); + return new Cubehelix(this.h, this.s, this.l * k, this.opacity); + }, + darker: function(k) { + k = k == null ? darker : Math.pow(darker, k); + return new Cubehelix(this.h, this.s, this.l * k, this.opacity); + }, + rgb: function() { + var h = isNaN(this.h) ? 0 : (this.h + 120) * radians, + l = +this.l, + a = isNaN(this.s) ? 0 : this.s * l * (1 - l), + cosh = Math.cos(h), + sinh = Math.sin(h); + return new Rgb( + 255 * (l + a * (A * cosh + B * sinh)), + 255 * (l + a * (C * cosh + D * sinh)), + 255 * (l + a * (E * cosh)), + this.opacity + ); } +})); - function sizeNode(node) { - node.x *= dx; - node.y = node.depth * dy; - } +var constant$4 = x => () => x; - tree.separation = function(x) { - return arguments.length ? (separation = x, tree) : separation; +function linear$1(a, d) { + return function(t) { + return a + t * d; }; +} - tree.size = function(x) { - return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], tree) : (nodeSize ? null : [dx, dy]); +function exponential(a, b, y) { + return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) { + return Math.pow(a + t * b, y); }; +} - tree.nodeSize = function(x) { - return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], tree) : (nodeSize ? [dx, dy] : null); +function hue(a, b) { + var d = b - a; + return d ? linear$1(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant$4(isNaN(a) ? b : a); +} + +function gamma(y) { + return (y = +y) === 1 ? nogamma : function(a, b) { + return b - a ? exponential(a, b, y) : constant$4(isNaN(a) ? b : a); }; +} - return tree; +function nogamma(a, b) { + var d = b - a; + return d ? linear$1(a, d) : constant$4(isNaN(a) ? b : a); } -function treemapSlice(parent, x0, y0, x1, y1) { - var nodes = parent.children, - node, - i = -1, - n = nodes.length, - k = parent.value && (y1 - y0) / parent.value; +var interpolateRgb = (function rgbGamma(y) { + var color = gamma(y); - while (++i < n) { - node = nodes[i], node.x0 = x0, node.x1 = x1; - node.y0 = y0, node.y1 = y0 += node.value * k; + function rgb$1(start, end) { + var r = color((start = rgb(start)).r, (end = rgb(end)).r), + g = color(start.g, end.g), + b = color(start.b, end.b), + opacity = nogamma(start.opacity, end.opacity); + return function(t) { + start.r = r(t); + start.g = g(t); + start.b = b(t); + start.opacity = opacity(t); + return start + ""; + }; } -} -var phi = (1 + Math.sqrt(5)) / 2; + rgb$1.gamma = rgbGamma; -function squarifyRatio(ratio, parent, x0, y0, x1, y1) { - var rows = [], - nodes = parent.children, - row, - nodeValue, - i0 = 0, - i1 = 0, - n = nodes.length, - dx, dy, - value = parent.value, - sumValue, - minValue, - maxValue, - newRatio, - minRatio, - alpha, - beta; + return rgb$1; +})(1); - while (i0 < n) { - dx = x1 - x0, dy = y1 - y0; +function numberArray(a, b) { + if (!b) b = []; + var n = a ? Math.min(b.length, a.length) : 0, + c = b.slice(), + i; + return function(t) { + for (i = 0; i < n; ++i) c[i] = a[i] * (1 - t) + b[i] * t; + return c; + }; +} - // Find the next non-empty node. - do sumValue = nodes[i1++].value; while (!sumValue && i1 < n); - minValue = maxValue = sumValue; - alpha = Math.max(dy / dx, dx / dy) / (value * ratio); - beta = sumValue * sumValue * alpha; - minRatio = Math.max(maxValue / beta, beta / minValue); +function isNumberArray(x) { + return ArrayBuffer.isView(x) && !(x instanceof DataView); +} - // Keep adding nodes while the aspect ratio maintains or improves. - for (; i1 < n; ++i1) { - sumValue += nodeValue = nodes[i1].value; - if (nodeValue < minValue) minValue = nodeValue; - if (nodeValue > maxValue) maxValue = nodeValue; - beta = sumValue * sumValue * alpha; - newRatio = Math.max(maxValue / beta, beta / minValue); - if (newRatio > minRatio) { sumValue -= nodeValue; break; } - minRatio = newRatio; - } +function genericArray(a, b) { + var nb = b ? b.length : 0, + na = a ? Math.min(nb, a.length) : 0, + x = new Array(na), + c = new Array(nb), + i; - // Position and record the row orientation. - rows.push(row = {value: sumValue, dice: dx < dy, children: nodes.slice(i0, i1)}); - if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += dy * sumValue / value : y1); - else treemapSlice(row, x0, y0, value ? x0 += dx * sumValue / value : x1, y1); - value -= sumValue, i0 = i1; - } + for (i = 0; i < na; ++i) x[i] = interpolate$1(a[i], b[i]); + for (; i < nb; ++i) c[i] = b[i]; - return rows; + return function(t) { + for (i = 0; i < na; ++i) c[i] = x[i](t); + return c; + }; } -var squarify = (function custom(ratio) { - - function squarify(parent, x0, y0, x1, y1) { - squarifyRatio(ratio, parent, x0, y0, x1, y1); - } - - squarify.ratio = function(x) { - return custom((x = +x) > 1 ? x : 1); +function date(a, b) { + var d = new Date; + return a = +a, b = +b, function(t) { + return d.setTime(a * (1 - t) + b * t), d; }; +} - return squarify; -})(phi); +function interpolateNumber(a, b) { + return a = +a, b = +b, function(t) { + return a * (1 - t) + b * t; + }; +} -function index() { - var tile = squarify, - round = false, - dx = 1, - dy = 1, - paddingStack = [0], - paddingInner = constantZero, - paddingTop = constantZero, - paddingRight = constantZero, - paddingBottom = constantZero, - paddingLeft = constantZero; +function object(a, b) { + var i = {}, + c = {}, + k; - function treemap(root) { - root.x0 = - root.y0 = 0; - root.x1 = dx; - root.y1 = dy; - root.eachBefore(positionNode); - paddingStack = [0]; - if (round) root.eachBefore(roundNode); - return root; - } + if (a === null || typeof a !== "object") a = {}; + if (b === null || typeof b !== "object") b = {}; - function positionNode(node) { - var p = paddingStack[node.depth], - x0 = node.x0 + p, - y0 = node.y0 + p, - x1 = node.x1 - p, - y1 = node.y1 - p; - if (x1 < x0) x0 = x1 = (x0 + x1) / 2; - if (y1 < y0) y0 = y1 = (y0 + y1) / 2; - node.x0 = x0; - node.y0 = y0; - node.x1 = x1; - node.y1 = y1; - if (node.children) { - p = paddingStack[node.depth + 1] = paddingInner(node) / 2; - x0 += paddingLeft(node) - p; - y0 += paddingTop(node) - p; - x1 -= paddingRight(node) - p; - y1 -= paddingBottom(node) - p; - if (x1 < x0) x0 = x1 = (x0 + x1) / 2; - if (y1 < y0) y0 = y1 = (y0 + y1) / 2; - tile(node, x0, y0, x1, y1); + for (k in b) { + if (k in a) { + i[k] = interpolate$1(a[k], b[k]); + } else { + c[k] = b[k]; } } - treemap.round = function(x) { - return arguments.length ? (round = !!x, treemap) : round; + return function(t) { + for (k in i) c[k] = i[k](t); + return c; }; +} - treemap.size = function(x) { - return arguments.length ? (dx = +x[0], dy = +x[1], treemap) : [dx, dy]; - }; +var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g, + reB = new RegExp(reA.source, "g"); - treemap.tile = function(x) { - return arguments.length ? (tile = required(x), treemap) : tile; +function zero(b) { + return function() { + return b; }; +} - treemap.padding = function(x) { - return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : treemap.paddingInner(); +function one(b) { + return function(t) { + return b(t) + ""; }; +} - treemap.paddingInner = function(x) { - return arguments.length ? (paddingInner = typeof x === "function" ? x : constant$3(+x), treemap) : paddingInner; - }; +function interpolateString(a, b) { + var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b + am, // current match in a + bm, // current match in b + bs, // string preceding current number in b, if any + i = -1, // index in s + s = [], // string constants and placeholders + q = []; // number interpolators - treemap.paddingOuter = function(x) { - return arguments.length ? treemap.paddingTop(x).paddingRight(x).paddingBottom(x).paddingLeft(x) : treemap.paddingTop(); - }; + // Coerce inputs to strings. + a = a + "", b = b + ""; - treemap.paddingTop = function(x) { - return arguments.length ? (paddingTop = typeof x === "function" ? x : constant$3(+x), treemap) : paddingTop; - }; + // Interpolate pairs of numbers in a & b. + while ((am = reA.exec(a)) + && (bm = reB.exec(b))) { + if ((bs = bm.index) > bi) { // a string precedes the next number in b + bs = b.slice(bi, bs); + if (s[i]) s[i] += bs; // coalesce with previous string + else s[++i] = bs; + } + if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match + if (s[i]) s[i] += bm; // coalesce with previous string + else s[++i] = bm; + } else { // interpolate non-matching numbers + s[++i] = null; + q.push({i: i, x: interpolateNumber(am, bm)}); + } + bi = reB.lastIndex; + } - treemap.paddingRight = function(x) { - return arguments.length ? (paddingRight = typeof x === "function" ? x : constant$3(+x), treemap) : paddingRight; - }; + // Add remains of b. + if (bi < b.length) { + bs = b.slice(bi); + if (s[i]) s[i] += bs; // coalesce with previous string + else s[++i] = bs; + } - treemap.paddingBottom = function(x) { - return arguments.length ? (paddingBottom = typeof x === "function" ? x : constant$3(+x), treemap) : paddingBottom; - }; + // Special optimization for only a single match. + // Otherwise, interpolate each of the numbers and rejoin the string. + return s.length < 2 ? (q[0] + ? one(q[0].x) + : zero(b)) + : (b = q.length, function(t) { + for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t); + return s.join(""); + }); +} - treemap.paddingLeft = function(x) { - return arguments.length ? (paddingLeft = typeof x === "function" ? x : constant$3(+x), treemap) : paddingLeft; - }; +function interpolate$1(a, b) { + var t = typeof b, c; + return b == null || t === "boolean" ? constant$4(b) + : (t === "number" ? interpolateNumber + : t === "string" ? ((c = color(b)) ? (b = c, interpolateRgb) : interpolateString) + : b instanceof color ? interpolateRgb + : b instanceof Date ? date + : isNumberArray(b) ? numberArray + : Array.isArray(b) ? genericArray + : typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object + : interpolateNumber)(a, b); +} - return treemap; +function interpolateRound(a, b) { + return a = +a, b = +b, function(t) { + return Math.round(a * (1 - t) + b * t); + }; } -function binary(parent, x0, y0, x1, y1) { - var nodes = parent.children, - i, n = nodes.length, - sum, sums = new Array(n + 1); +var degrees = 180 / Math.PI; - for (sums[0] = sum = i = 0; i < n; ++i) { - sums[i + 1] = sum += nodes[i].value; - } +var identity$3 = { + translateX: 0, + translateY: 0, + rotate: 0, + skewX: 0, + scaleX: 1, + scaleY: 1 +}; - partition(0, n, parent.value, x0, y0, x1, y1); +function decompose(a, b, c, d, e, f) { + var scaleX, scaleY, skewX; + if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX; + if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX; + if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY; + if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX; + return { + translateX: e, + translateY: f, + rotate: Math.atan2(b, a) * degrees, + skewX: Math.atan(skewX) * degrees, + scaleX: scaleX, + scaleY: scaleY + }; +} - function partition(i, j, value, x0, y0, x1, y1) { - if (i >= j - 1) { - var node = nodes[i]; - node.x0 = x0, node.y0 = y0; - node.x1 = x1, node.y1 = y1; - return; - } +var svgNode; - var valueOffset = sums[i], - valueTarget = (value / 2) + valueOffset, - k = i + 1, - hi = j - 1; +/* eslint-disable no-undef */ +function parseCss(value) { + const m = new (typeof DOMMatrix === "function" ? DOMMatrix : WebKitCSSMatrix)(value + ""); + return m.isIdentity ? identity$3 : decompose(m.a, m.b, m.c, m.d, m.e, m.f); +} - while (k < hi) { - var mid = k + hi >>> 1; - if (sums[mid] < valueTarget) k = mid + 1; - else hi = mid; - } +function parseSvg(value) { + if (value == null) return identity$3; + if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g"); + svgNode.setAttribute("transform", value); + if (!(value = svgNode.transform.baseVal.consolidate())) return identity$3; + value = value.matrix; + return decompose(value.a, value.b, value.c, value.d, value.e, value.f); +} - if ((valueTarget - sums[k - 1]) < (sums[k] - valueTarget) && i + 1 < k) --k; +function interpolateTransform(parse, pxComma, pxParen, degParen) { - var valueLeft = sums[k] - valueOffset, - valueRight = value - valueLeft; + function pop(s) { + return s.length ? s.pop() + " " : ""; + } - if ((x1 - x0) > (y1 - y0)) { - var xk = value ? (x0 * valueRight + x1 * valueLeft) / value : x1; - partition(i, k, valueLeft, x0, y0, xk, y1); - partition(k, j, valueRight, xk, y0, x1, y1); - } else { - var yk = value ? (y0 * valueRight + y1 * valueLeft) / value : y1; - partition(i, k, valueLeft, x0, y0, x1, yk); - partition(k, j, valueRight, x0, yk, x1, y1); + function translate(xa, ya, xb, yb, s, q) { + if (xa !== xb || ya !== yb) { + var i = s.push("translate(", null, pxComma, null, pxParen); + q.push({i: i - 4, x: interpolateNumber(xa, xb)}, {i: i - 2, x: interpolateNumber(ya, yb)}); + } else if (xb || yb) { + s.push("translate(" + xb + pxComma + yb + pxParen); } } -} -function initRange(domain, range) { - switch (arguments.length) { - case 0: break; - case 1: this.range(domain); break; - default: this.range(range).domain(domain); break; + function rotate(a, b, s, q) { + if (a !== b) { + if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path + q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: interpolateNumber(a, b)}); + } else if (b) { + s.push(pop(s) + "rotate(" + b + degParen); + } } - return this; -} - -const implicit = Symbol("implicit"); - -function ordinal() { - var index = new Map(), - domain = [], - range = [], - unknown = implicit; - function scale(d) { - var key = d + "", i = index.get(key); - if (!i) { - if (unknown !== implicit) return unknown; - index.set(key, i = domain.push(d)); + function skewX(a, b, s, q) { + if (a !== b) { + q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: interpolateNumber(a, b)}); + } else if (b) { + s.push(pop(s) + "skewX(" + b + degParen); } - return range[(i - 1) % range.length]; } - scale.domain = function(_) { - if (!arguments.length) return domain.slice(); - domain = [], index = new Map(); - for (const value of _) { - const key = value + ""; - if (index.has(key)) continue; - index.set(key, domain.push(value)); + function scale(xa, ya, xb, yb, s, q) { + if (xa !== xb || ya !== yb) { + var i = s.push(pop(s) + "scale(", null, ",", null, ")"); + q.push({i: i - 4, x: interpolateNumber(xa, xb)}, {i: i - 2, x: interpolateNumber(ya, yb)}); + } else if (xb !== 1 || yb !== 1) { + s.push(pop(s) + "scale(" + xb + "," + yb + ")"); } - return scale; - }; - - scale.range = function(_) { - return arguments.length ? (range = Array.from(_), scale) : range.slice(); - }; + } - scale.unknown = function(_) { - return arguments.length ? (unknown = _, scale) : unknown; + return function(a, b) { + var s = [], // string constants and placeholders + q = []; // number interpolators + a = parse(a), b = parse(b); + translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q); + rotate(a.rotate, b.rotate, s, q); + skewX(a.skewX, b.skewX, s, q); + scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q); + a = b = null; // gc + return function(t) { + var i = -1, n = q.length, o; + while (++i < n) s[(o = q[i]).i] = o.x(t); + return s.join(""); + }; }; +} - scale.copy = function() { - return ordinal(domain, range).unknown(unknown); - }; +var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)"); +var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")"); - initRange.apply(scale, arguments); +var epsilon2 = 1e-12; - return scale; +function cosh(x) { + return ((x = Math.exp(x)) + 1 / x) / 2; } -function band() { - var scale = ordinal().unknown(undefined), - domain = scale.domain, - ordinalRange = scale.range, - r0 = 0, - r1 = 1, - step, - bandwidth, - round = false, - paddingInner = 0, - paddingOuter = 0, - align = 0.5; - - delete scale.unknown; +function sinh(x) { + return ((x = Math.exp(x)) - 1 / x) / 2; +} - function rescale() { - var n = domain().length, - reverse = r1 < r0, - start = reverse ? r1 : r0, - stop = reverse ? r0 : r1; - step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2); - if (round) step = Math.floor(step); - start += (stop - start - step * (n - paddingInner)) * align; - bandwidth = step * (1 - paddingInner); - if (round) start = Math.round(start), bandwidth = Math.round(bandwidth); - var values = sequence(n).map(function(i) { return start + step * i; }); - return ordinalRange(reverse ? values.reverse() : values); - } +function tanh(x) { + return ((x = Math.exp(2 * x)) - 1) / (x + 1); +} - scale.domain = function(_) { - return arguments.length ? (domain(_), rescale()) : domain(); - }; +var interpolateZoom = (function zoomRho(rho, rho2, rho4) { - scale.range = function(_) { - return arguments.length ? ([r0, r1] = _, r0 = +r0, r1 = +r1, rescale()) : [r0, r1]; - }; + // p0 = [ux0, uy0, w0] + // p1 = [ux1, uy1, w1] + function zoom(p0, p1) { + var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], + ux1 = p1[0], uy1 = p1[1], w1 = p1[2], + dx = ux1 - ux0, + dy = uy1 - uy0, + d2 = dx * dx + dy * dy, + i, + S; - scale.rangeRound = function(_) { - return [r0, r1] = _, r0 = +r0, r1 = +r1, round = true, rescale(); - }; + // Special case for u0 ≅ u1. + if (d2 < epsilon2) { + S = Math.log(w1 / w0) / rho; + i = function(t) { + return [ + ux0 + t * dx, + uy0 + t * dy, + w0 * Math.exp(rho * t * S) + ]; + }; + } - scale.bandwidth = function() { - return bandwidth; - }; + // General case. + else { + var d1 = Math.sqrt(d2), + b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1), + b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1), + r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), + r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1); + S = (r1 - r0) / rho; + i = function(t) { + var s = t * S, + coshr0 = cosh(r0), + u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0)); + return [ + ux0 + u * dx, + uy0 + u * dy, + w0 * coshr0 / cosh(rho * s + r0) + ]; + }; + } - scale.step = function() { - return step; - }; + i.duration = S * 1000 * rho / Math.SQRT2; - scale.round = function(_) { - return arguments.length ? (round = !!_, rescale()) : round; - }; + return i; + } - scale.padding = function(_) { - return arguments.length ? (paddingInner = Math.min(1, paddingOuter = +_), rescale()) : paddingInner; + zoom.rho = function(_) { + var _1 = Math.max(1e-3, +_), _2 = _1 * _1, _4 = _2 * _2; + return zoomRho(_1, _2, _4); }; - scale.paddingInner = function(_) { - return arguments.length ? (paddingInner = Math.min(1, _), rescale()) : paddingInner; - }; + return zoom; +})(Math.SQRT2, 2, 4); - scale.paddingOuter = function(_) { - return arguments.length ? (paddingOuter = +_, rescale()) : paddingOuter; - }; +function cubehelix(hue) { + return (function cubehelixGamma(y) { + y = +y; - scale.align = function(_) { - return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align; - }; + function cubehelix(start, end) { + var h = hue((start = cubehelix$1(start)).h, (end = cubehelix$1(end)).h), + s = nogamma(start.s, end.s), + l = nogamma(start.l, end.l), + opacity = nogamma(start.opacity, end.opacity); + return function(t) { + start.h = h(t); + start.s = s(t); + start.l = l(Math.pow(t, y)); + start.opacity = opacity(t); + return start + ""; + }; + } - scale.copy = function() { - return band(domain(), [r0, r1]) - .round(round) - .paddingInner(paddingInner) - .paddingOuter(paddingOuter) - .align(align); - }; + cubehelix.gamma = cubehelixGamma; - return initRange.apply(rescale(), arguments); + return cubehelix; + })(1); } -function pointish(scale) { - var copy = scale.copy; - - scale.padding = scale.paddingOuter; - delete scale.paddingInner; - delete scale.paddingOuter; - - scale.copy = function() { - return pointish(copy()); - }; - - return scale; -} +cubehelix(hue); +var cubehelixLong = cubehelix(nogamma); -function point$1() { - return pointish(band.apply(null, arguments).paddingInner(1)); +function quantize(interpolator, n) { + var samples = new Array(n); + for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1)); + return samples; } -function constants(x) { - return function() { - return x; - }; -} +var frame = 0, // is an animation frame pending? + timeout$1 = 0, // is a timeout pending? + interval = 0, // are any timers active? + pokeDelay = 1000, // how frequently we check for clock skew + taskHead, + taskTail, + clockLast = 0, + clockNow = 0, + clockSkew = 0, + clock = typeof performance === "object" && performance.now ? performance : Date, + setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); }; -function number(x) { - return +x; +function now() { + return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew); } -var unit = [0, 1]; - -function identity$2(x) { - return x; +function clearNow() { + clockNow = 0; } -function normalize(a, b) { - return (b -= (a = +a)) - ? function(x) { return (x - a) / b; } - : constants(isNaN(b) ? NaN : 0.5); +function Timer() { + this._call = + this._time = + this._next = null; } -function clamper(a, b) { - var t; - if (a > b) t = a, a = b, b = t; - return function(x) { return Math.max(a, Math.min(b, x)); }; -} +Timer.prototype = timer.prototype = { + constructor: Timer, + restart: function(callback, delay, time) { + if (typeof callback !== "function") throw new TypeError("callback is not a function"); + time = (time == null ? now() : +time) + (delay == null ? 0 : +delay); + if (!this._next && taskTail !== this) { + if (taskTail) taskTail._next = this; + else taskHead = this; + taskTail = this; + } + this._call = callback; + this._time = time; + sleep(); + }, + stop: function() { + if (this._call) { + this._call = null; + this._time = Infinity; + sleep(); + } + } +}; -// normalize(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1]. -// interpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding range value x in [a,b]. -function bimap(domain, range, interpolate) { - var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1]; - if (d1 < d0) d0 = normalize(d1, d0), r0 = interpolate(r1, r0); - else d0 = normalize(d0, d1), r0 = interpolate(r0, r1); - return function(x) { return r0(d0(x)); }; +function timer(callback, delay, time) { + var t = new Timer; + t.restart(callback, delay, time); + return t; } -function polymap(domain, range, interpolate) { - var j = Math.min(domain.length, range.length) - 1, - d = new Array(j), - r = new Array(j), - i = -1; - - // Reverse descending domains. - if (domain[j] < domain[0]) { - domain = domain.slice().reverse(); - range = range.slice().reverse(); +function timerFlush() { + now(); // Get the current time, if not already set. + ++frame; // Pretend we’ve set an alarm, if we haven’t already. + var t = taskHead, e; + while (t) { + if ((e = clockNow - t._time) >= 0) t._call.call(null, e); + t = t._next; } + --frame; +} - while (++i < j) { - d[i] = normalize(domain[i], domain[i + 1]); - r[i] = interpolate(range[i], range[i + 1]); +function wake() { + clockNow = (clockLast = clock.now()) + clockSkew; + frame = timeout$1 = 0; + try { + timerFlush(); + } finally { + frame = 0; + nap(); + clockNow = 0; } - - return function(x) { - var i = bisectRight(domain, x, 1, j) - 1; - return r[i](d[i](x)); - }; } -function copy(source, target) { - return target - .domain(source.domain()) - .range(source.range()) - .interpolate(source.interpolate()) - .clamp(source.clamp()) - .unknown(source.unknown()); +function poke() { + var now = clock.now(), delay = now - clockLast; + if (delay > pokeDelay) clockSkew -= delay, clockLast = now; } -function transformer() { - var domain = unit, - range = unit, - interpolate = interpolate$1, - transform, - untransform, - unknown, - clamp = identity$2, - piecewise, - output, - input; - - function rescale() { - var n = Math.min(domain.length, range.length); - if (clamp !== identity$2) clamp = clamper(domain[0], domain[n - 1]); - piecewise = n > 2 ? polymap : bimap; - output = input = null; - return scale; +function nap() { + var t0, t1 = taskHead, t2, time = Infinity; + while (t1) { + if (t1._call) { + if (time > t1._time) time = t1._time; + t0 = t1, t1 = t1._next; + } else { + t2 = t1._next, t1._next = null; + t1 = t0 ? t0._next = t2 : taskHead = t2; + } } + taskTail = t0; + sleep(time); +} - function scale(x) { - return x == null || isNaN(x = +x) ? unknown : (output || (output = piecewise(domain.map(transform), range, interpolate)))(transform(clamp(x))); +function sleep(time) { + if (frame) return; // Soonest alarm already set, or will be. + if (timeout$1) timeout$1 = clearTimeout(timeout$1); + var delay = time - clockNow; // Strictly less than if we recomputed clockNow. + if (delay > 24) { + if (time < Infinity) timeout$1 = setTimeout(wake, time - clock.now() - clockSkew); + if (interval) interval = clearInterval(interval); + } else { + if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay); + frame = 1, setFrame(wake); } +} - scale.invert = function(y) { - return clamp(untransform((input || (input = piecewise(range, domain.map(transform), interpolateNumber)))(y))); - }; - - scale.domain = function(_) { - return arguments.length ? (domain = Array.from(_, number), rescale()) : domain.slice(); - }; - - scale.range = function(_) { - return arguments.length ? (range = Array.from(_), rescale()) : range.slice(); - }; - - scale.rangeRound = function(_) { - return range = Array.from(_), interpolate = interpolateRound, rescale(); - }; - - scale.clamp = function(_) { - return arguments.length ? (clamp = _ ? true : identity$2, rescale()) : clamp !== identity$2; - }; +function timeout(callback, delay, time) { + var t = new Timer; + delay = delay == null ? 0 : +delay; + t.restart(elapsed => { + t.stop(); + callback(elapsed + delay); + }, delay, time); + return t; +} - scale.interpolate = function(_) { - return arguments.length ? (interpolate = _, rescale()) : interpolate; - }; +var emptyOn = dispatch("start", "end", "cancel", "interrupt"); +var emptyTween = []; - scale.unknown = function(_) { - return arguments.length ? (unknown = _, scale) : unknown; - }; +var CREATED = 0; +var SCHEDULED = 1; +var STARTING = 2; +var STARTED = 3; +var RUNNING = 4; +var ENDING = 5; +var ENDED = 6; - return function(t, u) { - transform = t, untransform = u; - return rescale(); - }; +function schedule(node, name, id, index, group, timing) { + var schedules = node.__transition; + if (!schedules) node.__transition = {}; + else if (id in schedules) return; + create(node, id, { + name: name, + index: index, // For context during callback. + group: group, // For context during callback. + on: emptyOn, + tween: emptyTween, + time: timing.time, + delay: timing.delay, + duration: timing.duration, + ease: timing.ease, + timer: null, + state: CREATED + }); } -function continuous() { - return transformer()(identity$2, identity$2); +function init(node, id) { + var schedule = get(node, id); + if (schedule.state > CREATED) throw new Error("too late; already scheduled"); + return schedule; } -function tickFormat(start, stop, count, specifier) { - var step = tickStep(start, stop, count), - precision; - specifier = formatSpecifier(specifier == null ? ",f" : specifier); - switch (specifier.type) { - case "s": { - var value = Math.max(Math.abs(start), Math.abs(stop)); - if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision; - return formatPrefix(specifier, value); - } - case "": - case "e": - case "g": - case "p": - case "r": { - if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e"); - break; - } - case "f": - case "%": { - if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2; - break; - } - } - return format(specifier); +function set(node, id) { + var schedule = get(node, id); + if (schedule.state > STARTED) throw new Error("too late; already running"); + return schedule; } -function linearish(scale) { - var domain = scale.domain; - - scale.ticks = function(count) { - var d = domain(); - return ticks(d[0], d[d.length - 1], count == null ? 10 : count); - }; - - scale.tickFormat = function(count, specifier) { - var d = domain(); - return tickFormat(d[0], d[d.length - 1], count == null ? 10 : count, specifier); - }; - - scale.nice = function(count) { - if (count == null) count = 10; - - var d = domain(); - var i0 = 0; - var i1 = d.length - 1; - var start = d[i0]; - var stop = d[i1]; - var prestep; - var step; - var maxIter = 10; - - if (stop < start) { - step = start, start = stop, stop = step; - step = i0, i0 = i1, i1 = step; - } - - while (maxIter-- > 0) { - step = tickIncrement(start, stop, count); - if (step === prestep) { - d[i0] = start; - d[i1] = stop; - return domain(d); - } else if (step > 0) { - start = Math.floor(start / step) * step; - stop = Math.ceil(stop / step) * step; - } else if (step < 0) { - start = Math.ceil(start * step) / step; - stop = Math.floor(stop * step) / step; - } else { - break; - } - prestep = step; - } +function get(node, id) { + var schedule = node.__transition; + if (!schedule || !(schedule = schedule[id])) throw new Error("transition not found"); + return schedule; +} - return scale; - }; +function create(node, id, self) { + var schedules = node.__transition, + tween; - return scale; -} + // Initialize the self timer when the transition is created. + // Note the actual delay is not known until the first callback! + schedules[id] = self; + self.timer = timer(schedule, 0, self.time); -function linear() { - var scale = continuous(); + function schedule(elapsed) { + self.state = SCHEDULED; + self.timer.restart(start, self.delay, self.time); - scale.copy = function() { - return copy(scale, linear()); - }; + // If the elapsed delay is less than our first sleep, start immediately. + if (self.delay <= elapsed) start(elapsed - self.delay); + } - initRange.apply(scale, arguments); + function start(elapsed) { + var i, j, n, o; - return linearish(scale); -} + // If the state is not SCHEDULED, then we previously errored on start. + if (self.state !== SCHEDULED) return stop(); -function colors(specifier) { - var n = specifier.length / 6 | 0, colors = new Array(n), i = 0; - while (i < n) colors[i] = "#" + specifier.slice(i * 6, ++i * 6); - return colors; -} + for (i in schedules) { + o = schedules[i]; + if (o.name !== self.name) continue; -var category10 = colors("1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf"); + // While this element already has a starting transition during this frame, + // defer starting an interrupting transition until that transition has a + // chance to tick (and possibly end); see d3/d3-transition#54! + if (o.state === STARTED) return timeout(start); -cubehelixLong(cubehelix$1(-100, 0.75, 0.35), cubehelix$1(80, 1.50, 0.8)); + // Interrupt the active transition, if any. + if (o.state === RUNNING) { + o.state = ENDED; + o.timer.stop(); + o.on.call("interrupt", node, node.__data__, o.index, o.group); + delete schedules[i]; + } -cubehelixLong(cubehelix$1(260, 0.75, 0.35), cubehelix$1(80, 1.50, 0.8)); + // Cancel any pre-empted transitions. + else if (+i < id) { + o.state = ENDED; + o.timer.stop(); + o.on.call("cancel", node, node.__data__, o.index, o.group); + delete schedules[i]; + } + } -var c = cubehelix$1(); + // Defer the first tick to end of the current frame; see d3/d3#1576. + // Note the transition may be canceled after start and before the first tick! + // Note this must be scheduled before the start event; see d3/d3-transition#16! + // Assuming this is successful, subsequent callbacks go straight to tick. + timeout(function() { + if (self.state === STARTED) { + self.state = RUNNING; + self.timer.restart(tick, self.delay, self.time); + tick(elapsed); + } + }); -function rainbow(t) { - if (t < 0 || t > 1) t -= Math.floor(t); - var ts = Math.abs(t - 0.5); - c.h = 360 * t - 100; - c.s = 1.5 - 1.5 * ts; - c.l = 0.8 - 0.9 * ts; - return c + ""; -} + // Dispatch the start event. + // Note this must be done before the tween are initialized. + self.state = STARTING; + self.on.call("start", node, node.__data__, self.index, self.group); + if (self.state !== STARTING) return; // interrupted + self.state = STARTED; -function constant$2(x) { - return function constant() { - return x; - }; -} + // Initialize the tween, deleting null tween. + tween = new Array(n = self.tween.length); + for (i = 0, j = -1; i < n; ++i) { + if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) { + tween[++j] = o; + } + } + tween.length = j + 1; + } -var abs = Math.abs; -var atan2 = Math.atan2; -var cos = Math.cos; -var max = Math.max; -var min = Math.min; -var sin = Math.sin; -var sqrt = Math.sqrt; + function tick(elapsed) { + var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1), + i = -1, + n = tween.length; -var epsilon = 1e-12; -var pi = Math.PI; -var halfPi = pi / 2; -var tau = 2 * pi; + while (++i < n) { + tween[i].call(node, t); + } -function acos(x) { - return x > 1 ? 0 : x < -1 ? pi : Math.acos(x); -} + // Dispatch the end event. + if (self.state === ENDING) { + self.on.call("end", node, node.__data__, self.index, self.group); + stop(); + } + } -function asin(x) { - return x >= 1 ? halfPi : x <= -1 ? -halfPi : Math.asin(x); + function stop() { + self.state = ENDED; + self.timer.stop(); + delete schedules[id]; + for (var i in schedules) return; // eslint-disable-line no-unused-vars + delete node.__transition; + } } -function arcInnerRadius(d) { - return d.innerRadius; -} +function interrupt(node, name) { + var schedules = node.__transition, + schedule, + active, + empty = true, + i; -function arcOuterRadius(d) { - return d.outerRadius; -} + if (!schedules) return; -function arcStartAngle(d) { - return d.startAngle; -} + name = name == null ? null : name + ""; -function arcEndAngle(d) { - return d.endAngle; -} + for (i in schedules) { + if ((schedule = schedules[i]).name !== name) { empty = false; continue; } + active = schedule.state > STARTING && schedule.state < ENDING; + schedule.state = ENDED; + schedule.timer.stop(); + schedule.on.call(active ? "interrupt" : "cancel", node, node.__data__, schedule.index, schedule.group); + delete schedules[i]; + } -function arcPadAngle(d) { - return d && d.padAngle; // Note: optional! + if (empty) delete node.__transition; } -function intersect(x0, y0, x1, y1, x2, y2, x3, y3) { - var x10 = x1 - x0, y10 = y1 - y0, - x32 = x3 - x2, y32 = y3 - y2, - t = y32 * x10 - x32 * y10; - if (t * t < epsilon) return; - t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / t; - return [x0 + t * x10, y0 + t * y10]; +function selection_interrupt(name) { + return this.each(function() { + interrupt(this, name); + }); } -// Compute perpendicular offset line of length rc. -// http://mathworld.wolfram.com/Circle-LineIntersection.html -function cornerTangents(x0, y0, x1, y1, r1, rc, cw) { - var x01 = x0 - x1, - y01 = y0 - y1, - lo = (cw ? rc : -rc) / sqrt(x01 * x01 + y01 * y01), - ox = lo * y01, - oy = -lo * x01, - x11 = x0 + ox, - y11 = y0 + oy, - x10 = x1 + ox, - y10 = y1 + oy, - x00 = (x11 + x10) / 2, - y00 = (y11 + y10) / 2, - dx = x10 - x11, - dy = y10 - y11, - d2 = dx * dx + dy * dy, - r = r1 - rc, - D = x11 * y10 - x10 * y11, - d = (dy < 0 ? -1 : 1) * sqrt(max(0, r * r * d2 - D * D)), - cx0 = (D * dy - dx * d) / d2, - cy0 = (-D * dx - dy * d) / d2, - cx1 = (D * dy + dx * d) / d2, - cy1 = (-D * dx + dy * d) / d2, - dx0 = cx0 - x00, - dy0 = cy0 - y00, - dx1 = cx1 - x00, - dy1 = cy1 - y00; +function tweenRemove(id, name) { + var tween0, tween1; + return function() { + var schedule = set(this, id), + tween = schedule.tween; - // Pick the closer of the two intersection points. - // TODO Is there a faster way to determine which intersection to use? - if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1; + // If this node shared tween with the previous node, + // just assign the updated shared tween and we’re done! + // Otherwise, copy-on-write. + if (tween !== tween0) { + tween1 = tween0 = tween; + for (var i = 0, n = tween1.length; i < n; ++i) { + if (tween1[i].name === name) { + tween1 = tween1.slice(); + tween1.splice(i, 1); + break; + } + } + } - return { - cx: cx0, - cy: cy0, - x01: -ox, - y01: -oy, - x11: cx0 * (r1 / r - 1), - y11: cy0 * (r1 / r - 1) + schedule.tween = tween1; }; } -function arc() { - var innerRadius = arcInnerRadius, - outerRadius = arcOuterRadius, - cornerRadius = constant$2(0), - padRadius = null, - startAngle = arcStartAngle, - endAngle = arcEndAngle, - padAngle = arcPadAngle, - context = null; +function tweenFunction(id, name, value) { + var tween0, tween1; + if (typeof value !== "function") throw new Error; + return function() { + var schedule = set(this, id), + tween = schedule.tween; - function arc() { - var buffer, - r, - r0 = +innerRadius.apply(this, arguments), - r1 = +outerRadius.apply(this, arguments), - a0 = startAngle.apply(this, arguments) - halfPi, - a1 = endAngle.apply(this, arguments) - halfPi, - da = abs(a1 - a0), - cw = a1 > a0; + // If this node shared tween with the previous node, + // just assign the updated shared tween and we’re done! + // Otherwise, copy-on-write. + if (tween !== tween0) { + tween1 = (tween0 = tween).slice(); + for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) { + if (tween1[i].name === name) { + tween1[i] = t; + break; + } + } + if (i === n) tween1.push(t); + } - if (!context) context = buffer = path(); + schedule.tween = tween1; + }; +} - // Ensure that the outer radius is always larger than the inner radius. - if (r1 < r0) r = r1, r1 = r0, r0 = r; +function transition_tween(name, value) { + var id = this._id; - // Is it a point? - if (!(r1 > epsilon)) context.moveTo(0, 0); + name += ""; - // Or is it a circle or annulus? - else if (da > tau - epsilon) { - context.moveTo(r1 * cos(a0), r1 * sin(a0)); - context.arc(0, 0, r1, a0, a1, !cw); - if (r0 > epsilon) { - context.moveTo(r0 * cos(a1), r0 * sin(a1)); - context.arc(0, 0, r0, a1, a0, cw); + if (arguments.length < 2) { + var tween = get(this.node(), id).tween; + for (var i = 0, n = tween.length, t; i < n; ++i) { + if ((t = tween[i]).name === name) { + return t.value; } } + return null; + } - // Or is it a circular or annular sector? - else { - var a01 = a0, - a11 = a1, - a00 = a0, - a10 = a1, - da0 = da, - da1 = da, - ap = padAngle.apply(this, arguments) / 2, - rp = (ap > epsilon) && (padRadius ? +padRadius.apply(this, arguments) : sqrt(r0 * r0 + r1 * r1)), - rc = min(abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)), - rc0 = rc, - rc1 = rc, - t0, - t1; - - // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0. - if (rp > epsilon) { - var p0 = asin(rp / r0 * sin(ap)), - p1 = asin(rp / r1 * sin(ap)); - if ((da0 -= p0 * 2) > epsilon) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0; - else da0 = 0, a00 = a10 = (a0 + a1) / 2; - if ((da1 -= p1 * 2) > epsilon) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1; - else da1 = 0, a01 = a11 = (a0 + a1) / 2; - } - - var x01 = r1 * cos(a01), - y01 = r1 * sin(a01), - x10 = r0 * cos(a10), - y10 = r0 * sin(a10); - - // Apply rounded corners? - if (rc > epsilon) { - var x11 = r1 * cos(a11), - y11 = r1 * sin(a11), - x00 = r0 * cos(a00), - y00 = r0 * sin(a00), - oc; + return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value)); +} - // Restrict the corner radius according to the sector angle. - if (da < pi && (oc = intersect(x01, y01, x00, y00, x11, y11, x10, y10))) { - var ax = x01 - oc[0], - ay = y01 - oc[1], - bx = x11 - oc[0], - by = y11 - oc[1], - kc = 1 / sin(acos((ax * bx + ay * by) / (sqrt(ax * ax + ay * ay) * sqrt(bx * bx + by * by))) / 2), - lc = sqrt(oc[0] * oc[0] + oc[1] * oc[1]); - rc0 = min(rc, (r0 - lc) / (kc - 1)); - rc1 = min(rc, (r1 - lc) / (kc + 1)); - } - } +function tweenValue(transition, name, value) { + var id = transition._id; - // Is the sector collapsed to a line? - if (!(da1 > epsilon)) context.moveTo(x01, y01); + transition.each(function() { + var schedule = set(this, id); + (schedule.value || (schedule.value = {}))[name] = value.apply(this, arguments); + }); - // Does the sector’s outer ring have rounded corners? - else if (rc1 > epsilon) { - t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw); - t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw); + return function(node) { + return get(node, id).value[name]; + }; +} - context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01); +function interpolate(a, b) { + var c; + return (typeof b === "number" ? interpolateNumber + : b instanceof color ? interpolateRgb + : (c = color(b)) ? (b = c, interpolateRgb) + : interpolateString)(a, b); +} - // Have the corners merged? - if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw); +function attrRemove(name) { + return function() { + this.removeAttribute(name); + }; +} - // Otherwise, draw the two corners and the ring. - else { - context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw); - context.arc(0, 0, r1, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw); - context.arc(t1.cx, t1.cy, rc1, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw); - } - } +function attrRemoveNS(fullname) { + return function() { + this.removeAttributeNS(fullname.space, fullname.local); + }; +} - // Or is the outer ring just a circular arc? - else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw); +function attrConstant(name, interpolate, value1) { + var string00, + string1 = value1 + "", + interpolate0; + return function() { + var string0 = this.getAttribute(name); + return string0 === string1 ? null + : string0 === string00 ? interpolate0 + : interpolate0 = interpolate(string00 = string0, value1); + }; +} - // Is there no inner ring, and it’s a circular sector? - // Or perhaps it’s an annular sector collapsed due to padding? - if (!(r0 > epsilon) || !(da0 > epsilon)) context.lineTo(x10, y10); +function attrConstantNS(fullname, interpolate, value1) { + var string00, + string1 = value1 + "", + interpolate0; + return function() { + var string0 = this.getAttributeNS(fullname.space, fullname.local); + return string0 === string1 ? null + : string0 === string00 ? interpolate0 + : interpolate0 = interpolate(string00 = string0, value1); + }; +} - // Does the sector’s inner ring (or point) have rounded corners? - else if (rc0 > epsilon) { - t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw); - t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw); +function attrFunction(name, interpolate, value) { + var string00, + string10, + interpolate0; + return function() { + var string0, value1 = value(this), string1; + if (value1 == null) return void this.removeAttribute(name); + string0 = this.getAttribute(name); + string1 = value1 + ""; + return string0 === string1 ? null + : string0 === string00 && string1 === string10 ? interpolate0 + : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1)); + }; +} - context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01); +function attrFunctionNS(fullname, interpolate, value) { + var string00, + string10, + interpolate0; + return function() { + var string0, value1 = value(this), string1; + if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local); + string0 = this.getAttributeNS(fullname.space, fullname.local); + string1 = value1 + ""; + return string0 === string1 ? null + : string0 === string00 && string1 === string10 ? interpolate0 + : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1)); + }; +} - // Have the corners merged? - if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw); +function transition_attr(name, value) { + var fullname = namespace(name), i = fullname === "transform" ? interpolateTransformSvg : interpolate; + return this.attrTween(name, typeof value === "function" + ? (fullname.local ? attrFunctionNS : attrFunction)(fullname, i, tweenValue(this, "attr." + name, value)) + : value == null ? (fullname.local ? attrRemoveNS : attrRemove)(fullname) + : (fullname.local ? attrConstantNS : attrConstant)(fullname, i, value)); +} - // Otherwise, draw the two corners and the ring. - else { - context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw); - context.arc(0, 0, r0, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), cw); - context.arc(t1.cx, t1.cy, rc0, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw); - } - } +function attrInterpolate(name, i) { + return function(t) { + this.setAttribute(name, i.call(this, t)); + }; +} - // Or is the inner ring just a circular arc? - else context.arc(0, 0, r0, a10, a00, cw); - } +function attrInterpolateNS(fullname, i) { + return function(t) { + this.setAttributeNS(fullname.space, fullname.local, i.call(this, t)); + }; +} - context.closePath(); +function attrTweenNS(fullname, value) { + var t0, i0; + function tween() { + var i = value.apply(this, arguments); + if (i !== i0) t0 = (i0 = i) && attrInterpolateNS(fullname, i); + return t0; + } + tween._value = value; + return tween; +} - if (buffer) return context = null, buffer + "" || null; +function attrTween(name, value) { + var t0, i0; + function tween() { + var i = value.apply(this, arguments); + if (i !== i0) t0 = (i0 = i) && attrInterpolate(name, i); + return t0; } + tween._value = value; + return tween; +} - arc.centroid = function() { - var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2, - a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi / 2; - return [cos(a) * r, sin(a) * r]; +function transition_attrTween(name, value) { + var key = "attr." + name; + if (arguments.length < 2) return (key = this.tween(key)) && key._value; + if (value == null) return this.tween(key, null); + if (typeof value !== "function") throw new Error; + var fullname = namespace(name); + return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value)); +} + +function delayFunction(id, value) { + return function() { + init(this, id).delay = +value.apply(this, arguments); }; +} - arc.innerRadius = function(_) { - return arguments.length ? (innerRadius = typeof _ === "function" ? _ : constant$2(+_), arc) : innerRadius; +function delayConstant(id, value) { + return value = +value, function() { + init(this, id).delay = value; }; +} - arc.outerRadius = function(_) { - return arguments.length ? (outerRadius = typeof _ === "function" ? _ : constant$2(+_), arc) : outerRadius; - }; +function transition_delay(value) { + var id = this._id; - arc.cornerRadius = function(_) { - return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : constant$2(+_), arc) : cornerRadius; - }; + return arguments.length + ? this.each((typeof value === "function" + ? delayFunction + : delayConstant)(id, value)) + : get(this.node(), id).delay; +} - arc.padRadius = function(_) { - return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : constant$2(+_), arc) : padRadius; +function durationFunction(id, value) { + return function() { + set(this, id).duration = +value.apply(this, arguments); }; +} - arc.startAngle = function(_) { - return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$2(+_), arc) : startAngle; +function durationConstant(id, value) { + return value = +value, function() { + set(this, id).duration = value; }; +} - arc.endAngle = function(_) { - return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$2(+_), arc) : endAngle; - }; +function transition_duration(value) { + var id = this._id; - arc.padAngle = function(_) { - return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$2(+_), arc) : padAngle; - }; + return arguments.length + ? this.each((typeof value === "function" + ? durationFunction + : durationConstant)(id, value)) + : get(this.node(), id).duration; +} - arc.context = function(_) { - return arguments.length ? ((context = _ == null ? null : _), arc) : context; +function easeConstant(id, value) { + if (typeof value !== "function") throw new Error; + return function() { + set(this, id).ease = value; }; +} - return arc; +function transition_ease(value) { + var id = this._id; + + return arguments.length + ? this.each(easeConstant(id, value)) + : get(this.node(), id).ease; } -var slice = Array.prototype.slice; +function easeVarying(id, value) { + return function() { + var v = value.apply(this, arguments); + if (typeof v !== "function") throw new Error; + set(this, id).ease = v; + }; +} -function array(x) { - return typeof x === "object" && "length" in x - ? x // Array, TypedArray, NodeList, array-like - : Array.from(x); // Map, Set, iterable, string, or anything else +function transition_easeVarying(value) { + if (typeof value !== "function") throw new Error; + return this.each(easeVarying(this._id, value)); } -function Linear(context) { - this._context = context; +function transition_filter(match) { + if (typeof match !== "function") match = matcher(match); + + for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) { + if ((node = group[i]) && match.call(node, node.__data__, i, group)) { + subgroup.push(node); + } + } + } + + return new Transition(subgroups, this._parents, this._name, this._id); } -Linear.prototype = { - areaStart: function() { - this._line = 0; - }, - areaEnd: function() { - this._line = NaN; - }, - lineStart: function() { - this._point = 0; - }, - lineEnd: function() { - if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); - this._line = 1 - this._line; - }, - point: function(x, y) { - x = +x, y = +y; - switch (this._point) { - case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; - case 1: this._point = 2; // proceed - default: this._context.lineTo(x, y); break; +function transition_merge(transition) { + if (transition._id !== this._id) throw new Error; + + for (var groups0 = this._groups, groups1 = transition._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { + for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) { + if (node = group0[i] || group1[i]) { + merge[i] = node; + } } } -}; -function curveLinear(context) { - return new Linear(context); + for (; j < m0; ++j) { + merges[j] = groups0[j]; + } + + return new Transition(merges, this._parents, this._name, this._id); } -function x(p) { - return p[0]; +function start(name) { + return (name + "").trim().split(/^|\s+/).every(function(t) { + var i = t.indexOf("."); + if (i >= 0) t = t.slice(0, i); + return !t || t === "start"; + }); } -function y(p) { - return p[1]; +function onFunction(id, name, listener) { + var on0, on1, sit = start(name) ? init : set; + return function() { + var schedule = sit(this, id), + on = schedule.on; + + // If this node shared a dispatch with the previous node, + // just assign the updated shared dispatch and we’re done! + // Otherwise, copy-on-write. + if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener); + + schedule.on = on1; + }; } -function line(x$1, y$1) { - var defined = constant$2(true), - context = null, - curve = curveLinear, - output = null; +function transition_on(name, listener) { + var id = this._id; - x$1 = typeof x$1 === "function" ? x$1 : (x$1 === undefined) ? x : constant$2(x$1); - y$1 = typeof y$1 === "function" ? y$1 : (y$1 === undefined) ? y : constant$2(y$1); + return arguments.length < 2 + ? get(this.node(), id).on.on(name) + : this.each(onFunction(id, name, listener)); +} - function line(data) { - var i, - n = (data = array(data)).length, - d, - defined0 = false, - buffer; +function removeFunction(id) { + return function() { + var parent = this.parentNode; + for (var i in this.__transition) if (+i !== id) return; + if (parent) parent.removeChild(this); + }; +} - if (context == null) output = curve(buffer = path()); +function transition_remove() { + return this.on("end.remove", removeFunction(this._id)); +} - for (i = 0; i <= n; ++i) { - if (!(i < n && defined(d = data[i], i, data)) === defined0) { - if (defined0 = !defined0) output.lineStart(); - else output.lineEnd(); +function transition_select(select) { + var name = this._name, + id = this._id; + + if (typeof select !== "function") select = selector(select); + + for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) { + if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) { + if ("__data__" in node) subnode.__data__ = node.__data__; + subgroup[i] = subnode; + schedule(subgroup[i], name, id, i, subgroup, get(node, id)); } - if (defined0) output.point(+x$1(d, i, data), +y$1(d, i, data)); } + } - if (buffer) return output = null, buffer + "" || null; + return new Transition(subgroups, this._parents, name, id); +} + +function transition_selectAll(select) { + var name = this._name, + id = this._id; + + if (typeof select !== "function") select = selectorAll(select); + + for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { + if (node = group[i]) { + for (var children = select.call(node, node.__data__, i, group), child, inherit = get(node, id), k = 0, l = children.length; k < l; ++k) { + if (child = children[k]) { + schedule(child, name, id, k, children, inherit); + } + } + subgroups.push(children); + parents.push(node); + } + } } - line.x = function(_) { - return arguments.length ? (x$1 = typeof _ === "function" ? _ : constant$2(+_), line) : x$1; - }; + return new Transition(subgroups, parents, name, id); +} - line.y = function(_) { - return arguments.length ? (y$1 = typeof _ === "function" ? _ : constant$2(+_), line) : y$1; - }; +var Selection = selection.prototype.constructor; - line.defined = function(_) { - return arguments.length ? (defined = typeof _ === "function" ? _ : constant$2(!!_), line) : defined; +function transition_selection() { + return new Selection(this._groups, this._parents); +} + +function styleNull(name, interpolate) { + var string00, + string10, + interpolate0; + return function() { + var string0 = styleValue(this, name), + string1 = (this.style.removeProperty(name), styleValue(this, name)); + return string0 === string1 ? null + : string0 === string00 && string1 === string10 ? interpolate0 + : interpolate0 = interpolate(string00 = string0, string10 = string1); }; +} - line.curve = function(_) { - return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve; +function styleRemove(name) { + return function() { + this.style.removeProperty(name); }; +} - line.context = function(_) { - return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context; +function styleConstant(name, interpolate, value1) { + var string00, + string1 = value1 + "", + interpolate0; + return function() { + var string0 = styleValue(this, name); + return string0 === string1 ? null + : string0 === string00 ? interpolate0 + : interpolate0 = interpolate(string00 = string0, value1); }; +} - return line; +function styleFunction(name, interpolate, value) { + var string00, + string10, + interpolate0; + return function() { + var string0 = styleValue(this, name), + value1 = value(this), + string1 = value1 + ""; + if (value1 == null) string1 = value1 = (this.style.removeProperty(name), styleValue(this, name)); + return string0 === string1 ? null + : string0 === string00 && string1 === string10 ? interpolate0 + : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1)); + }; } -var curveRadialLinear = curveRadial(curveLinear); +function styleMaybeRemove(id, name) { + var on0, on1, listener0, key = "style." + name, event = "end." + key, remove; + return function() { + var schedule = set(this, id), + on = schedule.on, + listener = schedule.value[key] == null ? remove || (remove = styleRemove(name)) : undefined; -function Radial(curve) { - this._curve = curve; + // If this node shared a dispatch with the previous node, + // just assign the updated shared dispatch and we’re done! + // Otherwise, copy-on-write. + if (on !== on0 || listener0 !== listener) (on1 = (on0 = on).copy()).on(event, listener0 = listener); + + schedule.on = on1; + }; } -Radial.prototype = { - areaStart: function() { - this._curve.areaStart(); - }, - areaEnd: function() { - this._curve.areaEnd(); - }, - lineStart: function() { - this._curve.lineStart(); - }, - lineEnd: function() { - this._curve.lineEnd(); - }, - point: function(a, r) { - this._curve.point(r * Math.sin(a), r * -Math.cos(a)); - } -}; +function transition_style(name, value, priority) { + var i = (name += "") === "transform" ? interpolateTransformCss : interpolate; + return value == null ? this + .styleTween(name, styleNull(name, i)) + .on("end.style." + name, styleRemove(name)) + : typeof value === "function" ? this + .styleTween(name, styleFunction(name, i, tweenValue(this, "style." + name, value))) + .each(styleMaybeRemove(this._id, name)) + : this + .styleTween(name, styleConstant(name, i, value), priority) + .on("end.style." + name, null); +} -function curveRadial(curve) { +function styleInterpolate(name, i, priority) { + return function(t) { + this.style.setProperty(name, i.call(this, t), priority); + }; +} - function radial(context) { - return new Radial(curve(context)); +function styleTween(name, value, priority) { + var t, i0; + function tween() { + var i = value.apply(this, arguments); + if (i !== i0) t = (i0 = i) && styleInterpolate(name, i, priority); + return t; } - - radial._curve = curve; - - return radial; + tween._value = value; + return tween; } -function lineRadial(l) { - var c = l.curve; +function transition_styleTween(name, value, priority) { + var key = "style." + (name += ""); + if (arguments.length < 2) return (key = this.tween(key)) && key._value; + if (value == null) return this.tween(key, null); + if (typeof value !== "function") throw new Error; + return this.tween(key, styleTween(name, value, priority == null ? "" : priority)); +} - l.angle = l.x, delete l.x; - l.radius = l.y, delete l.y; +function textConstant(value) { + return function() { + this.textContent = value; + }; +} - l.curve = function(_) { - return arguments.length ? c(curveRadial(_)) : c()._curve; +function textFunction(value) { + return function() { + var value1 = value(this); + this.textContent = value1 == null ? "" : value1; }; +} - return l; +function transition_text(value) { + return this.tween("text", typeof value === "function" + ? textFunction(tweenValue(this, "text", value)) + : textConstant(value == null ? "" : value + "")); } -function lineRadial$1() { - return lineRadial(line().curve(curveRadialLinear)); +function textInterpolate(i) { + return function(t) { + this.textContent = i.call(this, t); + }; } -function linkSource(d) { - return d.source; +function textTween(value) { + var t0, i0; + function tween() { + var i = value.apply(this, arguments); + if (i !== i0) t0 = (i0 = i) && textInterpolate(i); + return t0; + } + tween._value = value; + return tween; } -function linkTarget(d) { - return d.target; +function transition_textTween(value) { + var key = "text"; + if (arguments.length < 1) return (key = this.tween(key)) && key._value; + if (value == null) return this.tween(key, null); + if (typeof value !== "function") throw new Error; + return this.tween(key, textTween(value)); } -function link(curve) { - var source = linkSource, - target = linkTarget, - x$1 = x, - y$1 = y, - context = null; +function transition_transition() { + var name = this._name, + id0 = this._id, + id1 = newId(); - function link() { - var buffer, argv = slice.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv); - if (!context) context = buffer = path(); - curve(context, +x$1.apply(this, (argv[0] = s, argv)), +y$1.apply(this, argv), +x$1.apply(this, (argv[0] = t, argv)), +y$1.apply(this, argv)); - if (buffer) return context = null, buffer + "" || null; + for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { + if (node = group[i]) { + var inherit = get(node, id0); + schedule(node, name, id1, i, group, { + time: inherit.time + inherit.delay + inherit.duration, + delay: 0, + duration: inherit.duration, + ease: inherit.ease + }); + } + } } - link.source = function(_) { - return arguments.length ? (source = _, link) : source; - }; + return new Transition(groups, this._parents, name, id1); +} - link.target = function(_) { - return arguments.length ? (target = _, link) : target; - }; +function transition_end() { + var on0, on1, that = this, id = that._id, size = that.size(); + return new Promise(function(resolve, reject) { + var cancel = {value: reject}, + end = {value: function() { if (--size === 0) resolve(); }}; - link.x = function(_) { - return arguments.length ? (x$1 = typeof _ === "function" ? _ : constant$2(+_), link) : x$1; - }; + that.each(function() { + var schedule = set(this, id), + on = schedule.on; - link.y = function(_) { - return arguments.length ? (y$1 = typeof _ === "function" ? _ : constant$2(+_), link) : y$1; - }; + // If this node shared a dispatch with the previous node, + // just assign the updated shared dispatch and we’re done! + // Otherwise, copy-on-write. + if (on !== on0) { + on1 = (on0 = on).copy(); + on1._.cancel.push(cancel); + on1._.interrupt.push(cancel); + on1._.end.push(end); + } - link.context = function(_) { - return arguments.length ? ((context = _ == null ? null : _), link) : context; - }; + schedule.on = on1; + }); - return link; + // The selection was empty, resolve end immediately + if (size === 0) resolve(); + }); } -function curveHorizontal(context, x0, y0, x1, y1) { - context.moveTo(x0, y0); - context.bezierCurveTo(x0 = (x0 + x1) / 2, y0, x0, y1, x1, y1); -} +var id = 0; -function linkHorizontal() { - return link(curveHorizontal); +function Transition(groups, parents, name, id) { + this._groups = groups; + this._parents = parents; + this._name = name; + this._id = id; } -function point(that, x, y) { - that._context.bezierCurveTo( - (2 * that._x0 + that._x1) / 3, - (2 * that._y0 + that._y1) / 3, - (that._x0 + 2 * that._x1) / 3, - (that._y0 + 2 * that._y1) / 3, - (that._x0 + 4 * that._x1 + x) / 6, - (that._y0 + 4 * that._y1 + y) / 6 - ); +function newId() { + return ++id; } -function Basis(context) { - this._context = context; -} +var selection_prototype = selection.prototype; -Basis.prototype = { - areaStart: function() { - this._line = 0; - }, - areaEnd: function() { - this._line = NaN; - }, - lineStart: function() { - this._x0 = this._x1 = - this._y0 = this._y1 = NaN; - this._point = 0; - }, - lineEnd: function() { - switch (this._point) { - case 3: point(this, this._x1, this._y1); // proceed - case 2: this._context.lineTo(this._x1, this._y1); break; - } - if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); - this._line = 1 - this._line; - }, - point: function(x, y) { - x = +x, y = +y; - switch (this._point) { - case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; - case 1: this._point = 2; break; - case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed - default: point(this, x, y); break; - } - this._x0 = this._x1, this._x1 = x; - this._y0 = this._y1, this._y1 = y; - } +Transition.prototype = { + constructor: Transition, + select: transition_select, + selectAll: transition_selectAll, + filter: transition_filter, + merge: transition_merge, + selection: transition_selection, + transition: transition_transition, + call: selection_prototype.call, + nodes: selection_prototype.nodes, + node: selection_prototype.node, + size: selection_prototype.size, + empty: selection_prototype.empty, + each: selection_prototype.each, + on: transition_on, + attr: transition_attr, + attrTween: transition_attrTween, + style: transition_style, + styleTween: transition_styleTween, + text: transition_text, + textTween: transition_textTween, + remove: transition_remove, + tween: transition_tween, + delay: transition_delay, + duration: transition_duration, + ease: transition_ease, + easeVarying: transition_easeVarying, + end: transition_end, + [Symbol.iterator]: selection_prototype[Symbol.iterator] }; -function Bundle(context, beta) { - this._basis = new Basis(context); - this._beta = beta; +function cubicInOut(t) { + return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2; } -Bundle.prototype = { - lineStart: function() { - this._x = []; - this._y = []; - this._basis.lineStart(); - }, - lineEnd: function() { - var x = this._x, - y = this._y, - j = x.length - 1; - - if (j > 0) { - var x0 = x[0], - y0 = y[0], - dx = x[j] - x0, - dy = y[j] - y0, - i = -1, - t; +var defaultTiming = { + time: null, // Set on use. + delay: 0, + duration: 250, + ease: cubicInOut +}; - while (++i <= j) { - t = i / j; - this._basis.point( - this._beta * x[i] + (1 - this._beta) * (x0 + t * dx), - this._beta * y[i] + (1 - this._beta) * (y0 + t * dy) - ); - } +function inherit(node, id) { + var timing; + while (!(timing = node.__transition) || !(timing = timing[id])) { + if (!(node = node.parentNode)) { + throw new Error(`transition ${id} not found`); } - - this._x = this._y = null; - this._basis.lineEnd(); - }, - point: function(x, y) { - this._x.push(+x); - this._y.push(+y); } -}; + return timing; +} -var bundle = (function custom(beta) { +function selection_transition(name) { + var id, + timing; - function bundle(context) { - return beta === 1 ? new Basis(context) : new Bundle(context, beta); + if (name instanceof Transition) { + id = name._id, name = name._name; + } else { + id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + ""; } - bundle.beta = function(beta) { - return custom(+beta); - }; + for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { + if (node = group[i]) { + schedule(node, name, id, i, group, timing || inherit(node, id)); + } + } + } - return bundle; -})(0.85); + return new Transition(groups, this._parents, name, id); +} -var constant$1 = x => () => x; +selection.prototype.interrupt = selection_interrupt; +selection.prototype.transition = selection_transition; -function ZoomEvent(type, { - sourceEvent, - target, - transform, - dispatch -}) { - Object.defineProperties(this, { - type: {value: type, enumerable: true, configurable: true}, - sourceEvent: {value: sourceEvent, enumerable: true, configurable: true}, - target: {value: target, enumerable: true, configurable: true}, - transform: {value: transform, enumerable: true, configurable: true}, - _: {value: dispatch} - }); +const pi$1 = Math.PI, + tau$1 = 2 * pi$1, + epsilon$1 = 1e-6, + tauEpsilon = tau$1 - epsilon$1; + +function Path() { + this._x0 = this._y0 = // start of current subpath + this._x1 = this._y1 = null; // end of current subpath + this._ = ""; } -function Transform(k, x, y) { - this.k = k; - this.x = x; - this.y = y; +function path() { + return new Path; } -Transform.prototype = { - constructor: Transform, - scale: function(k) { - return k === 1 ? this : new Transform(this.k * k, this.x, this.y); - }, - translate: function(x, y) { - return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y); - }, - apply: function(point) { - return [point[0] * this.k + this.x, point[1] * this.k + this.y]; - }, - applyX: function(x) { - return x * this.k + this.x; - }, - applyY: function(y) { - return y * this.k + this.y; - }, - invert: function(location) { - return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k]; +Path.prototype = path.prototype = { + constructor: Path, + moveTo: function(x, y) { + this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y); }, - invertX: function(x) { - return (x - this.x) / this.k; + closePath: function() { + if (this._x1 !== null) { + this._x1 = this._x0, this._y1 = this._y0; + this._ += "Z"; + } }, - invertY: function(y) { - return (y - this.y) / this.k; + lineTo: function(x, y) { + this._ += "L" + (this._x1 = +x) + "," + (this._y1 = +y); }, - rescaleX: function(x) { - return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x)); + quadraticCurveTo: function(x1, y1, x, y) { + this._ += "Q" + (+x1) + "," + (+y1) + "," + (this._x1 = +x) + "," + (this._y1 = +y); }, - rescaleY: function(y) { - return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y)); + bezierCurveTo: function(x1, y1, x2, y2, x, y) { + this._ += "C" + (+x1) + "," + (+y1) + "," + (+x2) + "," + (+y2) + "," + (this._x1 = +x) + "," + (this._y1 = +y); }, - toString: function() { - return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")"; - } -}; - -var identity$1 = new Transform(1, 0, 0); - -function nopropagation(event) { - event.stopImmediatePropagation(); -} - -function noevent(event) { - event.preventDefault(); - event.stopImmediatePropagation(); -} + arcTo: function(x1, y1, x2, y2, r) { + x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r; + var x0 = this._x1, + y0 = this._y1, + x21 = x2 - x1, + y21 = y2 - y1, + x01 = x0 - x1, + y01 = y0 - y1, + l01_2 = x01 * x01 + y01 * y01; -// Ignore right-click, since that should open the context menu. -// except for pinch-to-zoom, which is sent as a wheel+ctrlKey event -function defaultFilter(event) { - return (!event.ctrlKey || event.type === 'wheel') && !event.button; -} + // Is the radius negative? Error. + if (r < 0) throw new Error("negative radius: " + r); -function defaultExtent() { - var e = this; - if (e instanceof SVGElement) { - e = e.ownerSVGElement || e; - if (e.hasAttribute("viewBox")) { - e = e.viewBox.baseVal; - return [[e.x, e.y], [e.x + e.width, e.y + e.height]]; + // Is this path empty? Move to (x1,y1). + if (this._x1 === null) { + this._ += "M" + (this._x1 = x1) + "," + (this._y1 = y1); } - return [[0, 0], [e.width.baseVal.value, e.height.baseVal.value]]; - } - return [[0, 0], [e.clientWidth, e.clientHeight]]; -} -function defaultTransform() { - return this.__zoom || identity$1; -} + // Or, is (x1,y1) coincident with (x0,y0)? Do nothing. + else if (!(l01_2 > epsilon$1)); -function defaultWheelDelta(event) { - return -event.deltaY * (event.deltaMode === 1 ? 0.05 : event.deltaMode ? 1 : 0.002) * (event.ctrlKey ? 10 : 1); -} + // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear? + // Equivalently, is (x1,y1) coincident with (x2,y2)? + // Or, is the radius zero? Line to (x1,y1). + else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon$1) || !r) { + this._ += "L" + (this._x1 = x1) + "," + (this._y1 = y1); + } -function defaultTouchable() { - return navigator.maxTouchPoints || ("ontouchstart" in this); -} + // Otherwise, draw an arc! + else { + var x20 = x2 - x0, + y20 = y2 - y0, + l21_2 = x21 * x21 + y21 * y21, + l20_2 = x20 * x20 + y20 * y20, + l21 = Math.sqrt(l21_2), + l01 = Math.sqrt(l01_2), + l = r * Math.tan((pi$1 - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2), + t01 = l / l01, + t21 = l / l21; -function defaultConstrain(transform, extent, translateExtent) { - var dx0 = transform.invertX(extent[0][0]) - translateExtent[0][0], - dx1 = transform.invertX(extent[1][0]) - translateExtent[1][0], - dy0 = transform.invertY(extent[0][1]) - translateExtent[0][1], - dy1 = transform.invertY(extent[1][1]) - translateExtent[1][1]; - return transform.translate( - dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1), - dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1) - ); -} + // If the start tangent is not coincident with (x0,y0), line to. + if (Math.abs(t01 - 1) > epsilon$1) { + this._ += "L" + (x1 + t01 * x01) + "," + (y1 + t01 * y01); + } -function zoom() { - var filter = defaultFilter, - extent = defaultExtent, - constrain = defaultConstrain, - wheelDelta = defaultWheelDelta, - touchable = defaultTouchable, - scaleExtent = [0, Infinity], - translateExtent = [[-Infinity, -Infinity], [Infinity, Infinity]], - duration = 250, - interpolate = interpolateZoom, - listeners = dispatch("start", "zoom", "end"), - touchstarting, - touchfirst, - touchending, - touchDelay = 500, - wheelDelay = 150, - clickDistance2 = 0, - tapDistance = 10; + this._ += "A" + r + "," + r + ",0,0," + (+(y01 * x20 > x01 * y20)) + "," + (this._x1 = x1 + t21 * x21) + "," + (this._y1 = y1 + t21 * y21); + } + }, + arc: function(x, y, r, a0, a1, ccw) { + x = +x, y = +y, r = +r, ccw = !!ccw; + var dx = r * Math.cos(a0), + dy = r * Math.sin(a0), + x0 = x + dx, + y0 = y + dy, + cw = 1 ^ ccw, + da = ccw ? a0 - a1 : a1 - a0; - function zoom(selection) { - selection - .property("__zoom", defaultTransform) - .on("wheel.zoom", wheeled) - .on("mousedown.zoom", mousedowned) - .on("dblclick.zoom", dblclicked) - .filter(touchable) - .on("touchstart.zoom", touchstarted) - .on("touchmove.zoom", touchmoved) - .on("touchend.zoom touchcancel.zoom", touchended) - .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)"); - } + // Is the radius negative? Error. + if (r < 0) throw new Error("negative radius: " + r); - zoom.transform = function(collection, transform, point, event) { - var selection = collection.selection ? collection.selection() : collection; - selection.property("__zoom", defaultTransform); - if (collection !== selection) { - schedule(collection, transform, point, event); - } else { - selection.interrupt().each(function() { - gesture(this, arguments) - .event(event) - .start() - .zoom(null, typeof transform === "function" ? transform.apply(this, arguments) : transform) - .end(); - }); + // Is this path empty? Move to (x0,y0). + if (this._x1 === null) { + this._ += "M" + x0 + "," + y0; } - }; - zoom.scaleBy = function(selection, k, p, event) { - zoom.scaleTo(selection, function() { - var k0 = this.__zoom.k, - k1 = typeof k === "function" ? k.apply(this, arguments) : k; - return k0 * k1; - }, p, event); - }; + // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0). + else if (Math.abs(this._x1 - x0) > epsilon$1 || Math.abs(this._y1 - y0) > epsilon$1) { + this._ += "L" + x0 + "," + y0; + } - zoom.scaleTo = function(selection, k, p, event) { - zoom.transform(selection, function() { - var e = extent.apply(this, arguments), - t0 = this.__zoom, - p0 = p == null ? centroid(e) : typeof p === "function" ? p.apply(this, arguments) : p, - p1 = t0.invert(p0), - k1 = typeof k === "function" ? k.apply(this, arguments) : k; - return constrain(translate(scale(t0, k1), p0, p1), e, translateExtent); - }, p, event); - }; + // Is this arc empty? We’re done. + if (!r) return; - zoom.translateBy = function(selection, x, y, event) { - zoom.transform(selection, function() { - return constrain(this.__zoom.translate( - typeof x === "function" ? x.apply(this, arguments) : x, - typeof y === "function" ? y.apply(this, arguments) : y - ), extent.apply(this, arguments), translateExtent); - }, null, event); - }; + // Does the angle go the wrong way? Flip the direction. + if (da < 0) da = da % tau$1 + tau$1; - zoom.translateTo = function(selection, x, y, p, event) { - zoom.transform(selection, function() { - var e = extent.apply(this, arguments), - t = this.__zoom, - p0 = p == null ? centroid(e) : typeof p === "function" ? p.apply(this, arguments) : p; - return constrain(identity$1.translate(p0[0], p0[1]).scale(t.k).translate( - typeof x === "function" ? -x.apply(this, arguments) : -x, - typeof y === "function" ? -y.apply(this, arguments) : -y - ), e, translateExtent); - }, p, event); - }; + // Is this a complete circle? Draw two arcs to complete the circle. + if (da > tauEpsilon) { + this._ += "A" + r + "," + r + ",0,1," + cw + "," + (x - dx) + "," + (y - dy) + "A" + r + "," + r + ",0,1," + cw + "," + (this._x1 = x0) + "," + (this._y1 = y0); + } - function scale(transform, k) { - k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], k)); - return k === transform.k ? transform : new Transform(k, transform.x, transform.y); + // Is this arc non-empty? Draw an arc! + else if (da > epsilon$1) { + this._ += "A" + r + "," + r + ",0," + (+(da >= pi$1)) + "," + cw + "," + (this._x1 = x + r * Math.cos(a1)) + "," + (this._y1 = y + r * Math.sin(a1)); + } + }, + rect: function(x, y, w, h) { + this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y) + "h" + (+w) + "v" + (+h) + "h" + (-w) + "Z"; + }, + toString: function() { + return this._; } +}; - function translate(transform, p0, p1) { - var x = p0[0] - p1[0] * transform.k, y = p0[1] - p1[1] * transform.k; - return x === transform.x && y === transform.y ? transform : new Transform(transform.k, x, y); - } +function center(x, y) { + var nodes, strength = 1; - function centroid(extent) { - return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1][1]) / 2]; - } + if (x == null) x = 0; + if (y == null) y = 0; - function schedule(transition, transform, point, event) { - transition - .on("start.zoom", function() { gesture(this, arguments).event(event).start(); }) - .on("interrupt.zoom end.zoom", function() { gesture(this, arguments).event(event).end(); }) - .tween("zoom", function() { - var that = this, - args = arguments, - g = gesture(that, args).event(event), - e = extent.apply(that, args), - p = point == null ? centroid(e) : typeof point === "function" ? point.apply(that, args) : point, - w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]), - a = that.__zoom, - b = typeof transform === "function" ? transform.apply(that, args) : transform, - i = interpolate(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k)); - return function(t) { - if (t === 1) t = b; // Avoid rounding error on end. - else { var l = i(t), k = w / l[2]; t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k); } - g.zoom(null, t); - }; - }); - } + function force() { + var i, + n = nodes.length, + node, + sx = 0, + sy = 0; - function gesture(that, args, clean) { - return (!clean && that.__zooming) || new Gesture(that, args); - } + for (i = 0; i < n; ++i) { + node = nodes[i], sx += node.x, sy += node.y; + } - function Gesture(that, args) { - this.that = that; - this.args = args; - this.active = 0; - this.sourceEvent = null; - this.extent = extent.apply(that, args); - this.taps = 0; + for (sx = (sx / n - x) * strength, sy = (sy / n - y) * strength, i = 0; i < n; ++i) { + node = nodes[i], node.x -= sx, node.y -= sy; + } } - Gesture.prototype = { - event: function(event) { - if (event) this.sourceEvent = event; - return this; - }, - start: function() { - if (++this.active === 1) { - this.that.__zooming = this; - this.emit("start"); - } - return this; - }, - zoom: function(key, transform) { - if (this.mouse && key !== "mouse") this.mouse[1] = transform.invert(this.mouse[0]); - if (this.touch0 && key !== "touch") this.touch0[1] = transform.invert(this.touch0[0]); - if (this.touch1 && key !== "touch") this.touch1[1] = transform.invert(this.touch1[0]); - this.that.__zoom = transform; - this.emit("zoom"); - return this; - }, - end: function() { - if (--this.active === 0) { - delete this.that.__zooming; - this.emit("end"); - } - return this; - }, - emit: function(type) { - var d = select(this.that).datum(); - listeners.call( - type, - this.that, - new ZoomEvent(type, { - sourceEvent: this.sourceEvent, - target: zoom, - type, - transform: this.that.__zoom, - dispatch: listeners - }), - d - ); - } + force.initialize = function(_) { + nodes = _; }; - function wheeled(event, ...args) { - if (!filter.apply(this, arguments)) return; - var g = gesture(this, args).event(event), - t = this.__zoom, - k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], t.k * Math.pow(2, wheelDelta.apply(this, arguments)))), - p = pointer(event); + force.x = function(_) { + return arguments.length ? (x = +_, force) : x; + }; - // If the mouse is in the same location as before, reuse it. - // If there were recent wheel events, reset the wheel idle timeout. - if (g.wheel) { - if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) { - g.mouse[1] = t.invert(g.mouse[0] = p); - } - clearTimeout(g.wheel); - } + force.y = function(_) { + return arguments.length ? (y = +_, force) : y; + }; - // If this wheel event won’t trigger a transform change, ignore it. - else if (t.k === k) return; + force.strength = function(_) { + return arguments.length ? (strength = +_, force) : strength; + }; - // Otherwise, capture the mouse point and location at the start. - else { - g.mouse = [p, t.invert(p)]; - interrupt(this); - g.start(); - } + return force; +} + +function tree_add(d) { + const x = +this._x.call(null, d), + y = +this._y.call(null, d); + return add(this.cover(x, y), x, y, d); +} + +function add(tree, x, y, d) { + if (isNaN(x) || isNaN(y)) return tree; // ignore invalid points + + var parent, + node = tree._root, + leaf = {data: d}, + x0 = tree._x0, + y0 = tree._y0, + x1 = tree._x1, + y1 = tree._y1, + xm, + ym, + xp, + yp, + right, + bottom, + i, + j; - noevent(event); - g.wheel = setTimeout(wheelidled, wheelDelay); - g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent, translateExtent)); + // If the tree is empty, initialize the root as a leaf. + if (!node) return tree._root = leaf, tree; - function wheelidled() { - g.wheel = null; - g.end(); - } + // Find the existing leaf for the new point, or add it. + while (node.length) { + if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; + if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; + if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree; } - function mousedowned(event, ...args) { - if (touchending || !filter.apply(this, arguments)) return; - var g = gesture(this, args, true).event(event), - v = select(event.view).on("mousemove.zoom", mousemoved, true).on("mouseup.zoom", mouseupped, true), - p = pointer(event, currentTarget), - currentTarget = event.currentTarget, - x0 = event.clientX, - y0 = event.clientY; + // Is the new point is exactly coincident with the existing point? + xp = +tree._x.call(null, node.data); + yp = +tree._y.call(null, node.data); + if (x === xp && y === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree; - dragDisable(event.view); - nopropagation(event); - g.mouse = [p, this.__zoom.invert(p)]; - interrupt(this); - g.start(); + // Otherwise, split the leaf node until the old and new point are separated. + do { + parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4); + if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; + if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; + } while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | (xp >= xm))); + return parent[j] = node, parent[i] = leaf, tree; +} - function mousemoved(event) { - noevent(event); - if (!g.moved) { - var dx = event.clientX - x0, dy = event.clientY - y0; - g.moved = dx * dx + dy * dy > clickDistance2; - } - g.event(event) - .zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] = pointer(event, currentTarget), g.mouse[1]), g.extent, translateExtent)); - } +function addAll(data) { + var d, i, n = data.length, + x, + y, + xz = new Array(n), + yz = new Array(n), + x0 = Infinity, + y0 = Infinity, + x1 = -Infinity, + y1 = -Infinity; - function mouseupped(event) { - v.on("mousemove.zoom mouseup.zoom", null); - yesdrag(event.view, g.moved); - noevent(event); - g.event(event).end(); - } + // Compute the points and their extent. + for (i = 0; i < n; ++i) { + if (isNaN(x = +this._x.call(null, d = data[i])) || isNaN(y = +this._y.call(null, d))) continue; + xz[i] = x; + yz[i] = y; + if (x < x0) x0 = x; + if (x > x1) x1 = x; + if (y < y0) y0 = y; + if (y > y1) y1 = y; } - function dblclicked(event, ...args) { - if (!filter.apply(this, arguments)) return; - var t0 = this.__zoom, - p0 = pointer(event.changedTouches ? event.changedTouches[0] : event, this), - p1 = t0.invert(p0), - k1 = t0.k * (event.shiftKey ? 0.5 : 2), - t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, args), translateExtent); + // If there were no (valid) points, abort. + if (x0 > x1 || y0 > y1) return this; - noevent(event); - if (duration > 0) select(this).transition().duration(duration).call(schedule, t1, p0, event); - else select(this).call(zoom.transform, t1, p0, event); + // Expand the tree to cover the new points. + this.cover(x0, y0).cover(x1, y1); + + // Add the new points. + for (i = 0; i < n; ++i) { + add(this, xz[i], yz[i], data[i]); } - function touchstarted(event, ...args) { - if (!filter.apply(this, arguments)) return; - var touches = event.touches, - n = touches.length, - g = gesture(this, args, event.changedTouches.length === n).event(event), - started, i, t, p; + return this; +} - nopropagation(event); - for (i = 0; i < n; ++i) { - t = touches[i], p = pointer(t, this); - p = [p, this.__zoom.invert(p), t.identifier]; - if (!g.touch0) g.touch0 = p, started = true, g.taps = 1 + !!touchstarting; - else if (!g.touch1 && g.touch0[2] !== p[2]) g.touch1 = p, g.taps = 0; - } +function tree_cover(x, y) { + if (isNaN(x = +x) || isNaN(y = +y)) return this; // ignore invalid points - if (touchstarting) touchstarting = clearTimeout(touchstarting); + var x0 = this._x0, + y0 = this._y0, + x1 = this._x1, + y1 = this._y1; - if (started) { - if (g.taps < 2) touchfirst = p[0], touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay); - interrupt(this); - g.start(); - } + // If the quadtree has no extent, initialize them. + // Integer extent are necessary so that if we later double the extent, + // the existing quadrant boundaries don’t change due to floating point error! + if (isNaN(x0)) { + x1 = (x0 = Math.floor(x)) + 1; + y1 = (y0 = Math.floor(y)) + 1; } - function touchmoved(event, ...args) { - if (!this.__zooming) return; - var g = gesture(this, args).event(event), - touches = event.changedTouches, - n = touches.length, i, t, p, l; + // Otherwise, double repeatedly to cover. + else { + var z = x1 - x0 || 1, + node = this._root, + parent, + i; - noevent(event); - for (i = 0; i < n; ++i) { - t = touches[i], p = pointer(t, this); - if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p; - else if (g.touch1 && g.touch1[2] === t.identifier) g.touch1[0] = p; - } - t = g.that.__zoom; - if (g.touch1) { - var p0 = g.touch0[0], l0 = g.touch0[1], - p1 = g.touch1[0], l1 = g.touch1[1], - dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp, - dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl; - t = scale(t, Math.sqrt(dp / dl)); - p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2]; - l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2]; + while (x0 > x || x >= x1 || y0 > y || y >= y1) { + i = (y < y0) << 1 | (x < x0); + parent = new Array(4), parent[i] = node, node = parent, z *= 2; + switch (i) { + case 0: x1 = x0 + z, y1 = y0 + z; break; + case 1: x0 = x1 - z, y1 = y0 + z; break; + case 2: x1 = x0 + z, y0 = y1 - z; break; + case 3: x0 = x1 - z, y0 = y1 - z; break; + } } - else if (g.touch0) p = g.touch0[0], l = g.touch0[1]; - else return; - g.zoom("touch", constrain(translate(t, p, l), g.extent, translateExtent)); + if (this._root && this._root.length) this._root = node; } - function touchended(event, ...args) { - if (!this.__zooming) return; - var g = gesture(this, args).event(event), - touches = event.changedTouches, - n = touches.length, i, t; + this._x0 = x0; + this._y0 = y0; + this._x1 = x1; + this._y1 = y1; + return this; +} - nopropagation(event); - if (touchending) clearTimeout(touchending); - touchending = setTimeout(function() { touchending = null; }, touchDelay); - for (i = 0; i < n; ++i) { - t = touches[i]; - if (g.touch0 && g.touch0[2] === t.identifier) delete g.touch0; - else if (g.touch1 && g.touch1[2] === t.identifier) delete g.touch1; - } - if (g.touch1 && !g.touch0) g.touch0 = g.touch1, delete g.touch1; - if (g.touch0) g.touch0[1] = this.__zoom.invert(g.touch0[0]); - else { - g.end(); - // If this was a dbltap, reroute to the (optional) dblclick.zoom handler. - if (g.taps === 2) { - t = pointer(t, this); - if (Math.hypot(touchfirst[0] - t[0], touchfirst[1] - t[1]) < tapDistance) { - var p = select(this).on("dblclick.zoom"); - if (p) p.apply(this, arguments); - } - } - } - } +function tree_data() { + var data = []; + this.visit(function(node) { + if (!node.length) do data.push(node.data); while (node = node.next) + }); + return data; +} - zoom.wheelDelta = function(_) { - return arguments.length ? (wheelDelta = typeof _ === "function" ? _ : constant$1(+_), zoom) : wheelDelta; - }; +function tree_extent(_) { + return arguments.length + ? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1]) + : isNaN(this._x0) ? undefined : [[this._x0, this._y0], [this._x1, this._y1]]; +} - zoom.filter = function(_) { - return arguments.length ? (filter = typeof _ === "function" ? _ : constant$1(!!_), zoom) : filter; - }; +function Quad(node, x0, y0, x1, y1) { + this.node = node; + this.x0 = x0; + this.y0 = y0; + this.x1 = x1; + this.y1 = y1; +} - zoom.touchable = function(_) { - return arguments.length ? (touchable = typeof _ === "function" ? _ : constant$1(!!_), zoom) : touchable; - }; +function tree_find(x, y, radius) { + var data, + x0 = this._x0, + y0 = this._y0, + x1, + y1, + x2, + y2, + x3 = this._x1, + y3 = this._y1, + quads = [], + node = this._root, + q, + i; - zoom.extent = function(_) { - return arguments.length ? (extent = typeof _ === "function" ? _ : constant$1([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent; - }; + if (node) quads.push(new Quad(node, x0, y0, x3, y3)); + if (radius == null) radius = Infinity; + else { + x0 = x - radius, y0 = y - radius; + x3 = x + radius, y3 = y + radius; + radius *= radius; + } - zoom.scaleExtent = function(_) { - return arguments.length ? (scaleExtent[0] = +_[0], scaleExtent[1] = +_[1], zoom) : [scaleExtent[0], scaleExtent[1]]; - }; + while (q = quads.pop()) { - zoom.translateExtent = function(_) { - return arguments.length ? (translateExtent[0][0] = +_[0][0], translateExtent[1][0] = +_[1][0], translateExtent[0][1] = +_[0][1], translateExtent[1][1] = +_[1][1], zoom) : [[translateExtent[0][0], translateExtent[0][1]], [translateExtent[1][0], translateExtent[1][1]]]; - }; + // Stop searching if this quadrant can’t contain a closer node. + if (!(node = q.node) + || (x1 = q.x0) > x3 + || (y1 = q.y0) > y3 + || (x2 = q.x1) < x0 + || (y2 = q.y1) < y0) continue; - zoom.constrain = function(_) { - return arguments.length ? (constrain = _, zoom) : constrain; - }; + // Bisect the current quadrant. + if (node.length) { + var xm = (x1 + x2) / 2, + ym = (y1 + y2) / 2; - zoom.duration = function(_) { - return arguments.length ? (duration = +_, zoom) : duration; - }; + quads.push( + new Quad(node[3], xm, ym, x2, y2), + new Quad(node[2], x1, ym, xm, y2), + new Quad(node[1], xm, y1, x2, ym), + new Quad(node[0], x1, y1, xm, ym) + ); - zoom.interpolate = function(_) { - return arguments.length ? (interpolate = _, zoom) : interpolate; - }; + // Visit the closest quadrant first. + if (i = (y >= ym) << 1 | (x >= xm)) { + q = quads[quads.length - 1]; + quads[quads.length - 1] = quads[quads.length - 1 - i]; + quads[quads.length - 1 - i] = q; + } + } - zoom.on = function() { - var value = listeners.on.apply(listeners, arguments); - return value === listeners ? zoom : value; - }; + // Visit this point. (Visiting coincident points isn’t necessary!) + else { + var dx = x - +this._x.call(null, node.data), + dy = y - +this._y.call(null, node.data), + d2 = dx * dx + dy * dy; + if (d2 < radius) { + var d = Math.sqrt(radius = d2); + x0 = x - d, y0 = y - d; + x3 = x + d, y3 = y + d; + data = node.data; + } + } + } - zoom.clickDistance = function(_) { - return arguments.length ? (clickDistance2 = (_ = +_) * _, zoom) : Math.sqrt(clickDistance2); - }; + return data; +} - zoom.tapDistance = function(_) { - return arguments.length ? (tapDistance = +_, zoom) : tapDistance; - }; +function tree_remove(d) { + if (isNaN(x = +this._x.call(null, d)) || isNaN(y = +this._y.call(null, d))) return this; // ignore invalid points - return zoom; -} + var parent, + node = this._root, + retainer, + previous, + next, + x0 = this._x0, + y0 = this._y0, + x1 = this._x1, + y1 = this._y1, + x, + y, + xm, + ym, + right, + bottom, + i, + j; -const arcDiagram = (graph, app, currFile, modal, width, height) => { - const data = graphlibToD3(graph); - const margin = { top: 20, right: 20, bottom: 20, left: 150 }; - const svg = select(".d3-graph") - .append("svg") - .attr("height", height) - .attr("width", width); - const nodes = data.nodes.map(({ id, name }) => ({ - id, - name, - sourceLinks: [], - targetLinks: [], - })); - const nodeById = new Map(nodes.map((d) => [d.id, d])); - const links = data.links.map(({ source, target }) => ({ - source: nodeById.get(source), - target: nodeById.get(target), - })); - for (const link of links) { - const { source, target } = link; - source.sourceLinks.push(link); - target.targetLinks.push(link); - } - svg.append("style").text(` - -path { - stroke: #808080; - opacity: 0.8; -} - -text { - stroke: var(--text-a); - opacity: 0.8; -} - - -.hover g.primary text { - fill: black; -} - -.hover g.secondary text { - fill: #333; -} - -.hover .secondary { - color: red; -} - -.hover path.primary { - stroke: #333; - stroke-opacity: 1; -} - -.hover rect { - opacity: 1; - cursor: pointer; -} - -`); - const y = point$1(nodes.map((d) => d.name).sort(ascending$1), [ - margin.top, - height - margin.bottom, - ]); - const label = svg - .append("g") - .attr("font-family", "sans-serif") - .attr("font-size", 10) - .attr("text-anchor", "end") - .selectAll("g") - .data(nodes) - .join("g") - .attr("transform", (d) => `translate(${margin.left},${(d.y = y(d.name))})`) - .call((g) => g - .append("text") - .attr("x", -6) - .attr("dy", "0.35em") - // .attr("fill", (d) => d3.lab(color(d.group)).darker(2)) - .text((d) => d.name)) - .call((g) => g.append("circle").attr("r", 3) - // .attr("fill", (d) => color(d.group)) - ); - const path = svg - .insert("g", "*") - .attr("fill", "none") - .attr("stroke-opacity", 0.6) - .attr("stroke-width", 1.5) - .selectAll("path") - .data(links) - .join("path") - // .attr("stroke", (d) => - // d.source.group === d.target.group ? color(d.source.group) : "#aaa" - // ) - .attr("d", arc); - const step = 104; - const nodeClick = (event, dest) => { - const currFile = app.workspace.getActiveFile(); - openOrSwitch(app, dest, currFile, event); - modal.close(); - }; - svg - .append("g") - .attr("fill", "none") - .attr("pointer-events", "all") - .selectAll("rect") - .data(nodes) - .join("rect") - .attr("width", margin.left + 40) - .attr("height", step) - .attr("y", (d) => y(d.name) - step / 2) - .on("mouseover", (d) => { - svg.classed("hover", true); - label.classed("primary", (n) => n === d); - label.classed("secondary", (n) => n.sourceLinks.some((l) => l.target === d) || - n.targetLinks.some((l) => l.source === d)); - path - .classed("primary", (l) => l.source === d || l.target === d) - .filter(".primary") - .raise(); - }) - .on("mouseout", (d) => { - svg.classed("hover", false); - label.classed("primary", false); - label.classed("secondary", false); - path.classed("primary", false).order(); - }) - .on("click", (event, d) => { - nodeClick(event, d.name); - }); - // function update() { - // y.domain(nodes.sort(viewof order.value).map(d => d.id)); - // const t = svg.transition() - // .duration(750); - // label.transition(t) - // .delay((d, i) => i * 20) - // .attrTween("transform", d => { - // const i = d3.interpolateNumber(d.y, y(d.id)); - // return t => `translate(${margin.left},${d.y = i(t)})`; - // }); - // path.transition(t) - // .duration(750 + nodes.length * 20) - // .attrTween("d", d => () => arc(d)); - // overlay.transition(t) - // .delay((d, i) => i * 20) - // .attr("y", d => y(d.id) - step / 2); - // } - // viewof order.addEventListener("input", update); - // invalidation.then(() => viewof order.removeEventListener("input", update)); - function arc(d) { - const y1 = d.source.y; - const y2 = d.target.y; - const r = Math.abs(y2 - y1) / 2; - return `M${margin.left},${y1}A${r},${r} 0,0,${y1 < y2 ? 1 : 0} ${margin.left},${y2}`; - } - function zoomed({ transform }) { - svg.attr("transform", transform); - } - svg.call(zoom() - .extent([ - [0, 0], - [width, height], - ]) - .scaleExtent([0.5, 8]) - .on("zoom", zoomed)); -}; + // If the tree is empty, initialize the root as a leaf. + if (!node) return this; + + // Find the leaf node for the point. + // While descending, also retain the deepest parent with a non-removed sibling. + if (node.length) while (true) { + if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; + if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; + if (!(parent = node, node = node[i = bottom << 1 | right])) return this; + if (!node.length) break; + if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) retainer = parent, j = i; + } -const circlePacking = (graph, app, currFile, modal, width, height) => { - const flatAdj = dfsFlatAdjList(graph, currFile.basename); - console.log({ flatAdj }); - const hierarchy = stratify()(flatAdj); - console.log({ hierarchy }); - const adjList = bfsAdjList(graph, currFile.basename); - console.log({ adjList }); - const noDoubles = [...adjList]; - noDoubles.forEach((a, i) => { - if (noDoubles.some((b, j) => i !== j && a.name === b.name)) { - const index = noDoubles.findIndex((b, j) => i !== j && a.name === b.name); - noDoubles.splice(index, 1); - } - }); - // const noDoubles = adjList.filter((a) => { - // !adjList.some((b) => { - // console.log({ a, b }); - // return a.name !== b.name && a.parentId === b.parentId; - // }); - // }); - console.log({ noDoubles }); - // const root = stratify(noDoubles); - // console.log(root); - // const hierarchy: d3Tree = createTreeHierarchy(noDoubles, { - // id: "name", - // excludeParent: true, - // }); - // console.log({ hierarchy }); - const linkArr = noDoubles.map((d) => { - return { source: d.name, target: d.parentId }; - }); - const links = linkArr.map((d) => Object.create(d)); - const svg = select(".d3-graph") - .append("svg") - .attr("height", height) - .attr("width", width); - const nodeColour = getComputedStyle(document.body).getPropertyValue("--text-accent"); - // Initialize the circle: all located at the center of the svg area - const node = svg - .append("g") - .selectAll("circle") - .data(noDoubles) - .join("circle") - .attr("r", (d) => Math.round(d.height / 10) + 10) - .attr("cx", width / 2) - .attr("cy", height / 2) - .style("fill", nodeColour) - .style("fill-opacity", 0.6) - .attr("stroke", nodeColour) - .style("stroke-width", 4); - node.attr("aria-label", (d) => d.name); - const nodeClick = (event, dest) => { - const currFile = app.workspace.getActiveFile(); - openOrSwitch(app, dest, currFile, event); - modal.close(); - }; - node.on("click", (event, d) => { - nodeClick(event, d.name); - }); - svg - .append("g") - .attr("stroke", "#868282") - .attr("stroke-opacity", 0.6) - .selectAll("line") - .data(links) - .join("line") - .attr("stroke-width", 0.8); - // Features of the forces applied to the nodes: - const simulation$1 = simulation() - .force("center", center() - .x(width / 2) - .y(height / 2)) // Attraction to the center of the svg area - .force("charge", manyBody().strength(0.5)) // Nodes are attracted one each other of value is > 0 - .force("collide", collide().strength(0.025).radius(30).iterations(1)); // Force that avoids circle overlapping - // Apply these forces to the nodes and update their positions. - // Once the force algorithm is happy with positions ('alpha' value is low enough), simulations will stop. - simulation$1.nodes(noDoubles).on("tick", function (d) { - node.attr("cx", (d) => d.x).attr("cy", (d) => d.y); - }); - function zoomed({ transform }) { - node.attr("transform", transform); - } - svg.call(zoom() - .extent([ - [0, 0], - [width, height], - ]) - .scaleExtent([0.5, 8]) - .on("zoom", zoomed)); - const drag$1 = (simulation) => { - function dragstarted(event, d) { - if (!event.active) - simulation.alphaTarget(0.3).restart(); - d.fx = d.x; - d.fy = d.y; - } - function dragged(event, d) { - d.fx = event.x; - d.fy = event.y; - } - function dragended(event, d) { - if (!event.active) - simulation.alphaTarget(0); - d.fx = null; - d.fy = null; - } - return drag() - .on("start", dragstarted) - .on("drag", dragged) - .on("end", dragended); - }; - node.call(drag$1(simulation$1)); - // const pack = (data) => - // d3.pack().size([width, height]).padding(3)( - // d3 - // .hierarchy(data) - // .sum((d) => d.value) - // .sort((a, b) => b.value - a.value) - // ); - // const root = pack(hierarchy); - // const svg = d3 - // .select(".d3-graph") - // .append("svg") - // .attr("height", height) - // .attr("width", width) - // .style("font", "10px sans-serif") - // .style("overflow", "visible") - // .attr("text-anchor", "middle"); - // const node = svg - // .append("g") - // .attr("pointer-events", "all") - // .selectAll("g") - // .data(root.descendants()) - // .join("g") - // .attr("transform", (d) => `translate(${d.x},${d.y})`); - // node - // .append("circle") - // .attr("r", (d) => d.r) - // .attr("stroke", (d) => (d.children ? "#bbb" : "none")) - // .attr("fill", (d) => (d.children ? "none" : "#ddd")); - // const leaf = node.filter((d) => !d.children); - // leaf.select("circle"); - // // leaf - // // .append("clipPath") - // // .attr("id", (d) => (d.clipUid = DOM.uid("clip")).id) - // // .append("use") - // // .attr("xlink:href", (d) => d.leafUid.href); - // // leaf - // // .append("text") - // // .attr("clip-path", (d) => d.clipUid) - // // .selectAll("tspan") - // // .data((d) => d.data.name.split(/(?=[A-Z][^A-Z])/g)) - // // .join("tspan") - // // .attr("x", 0) - // // .attr("y", (d, i, nodes) => `${i - nodes.length / 2 + 0.8}em`) - // // .text((d) => d); - // node.append("title").text( - // (d) => `${d - // .ancestors() - // .map((d) => d.data.data.name) - // .reverse() - // .join("/")} - // ${d.value.toLocaleString()}` - // ); -}; + // Find the point to remove. + while (node.data !== d) if (!(previous = node, node = node.next)) return this; + if (next = node.next) delete node.next; -const edgeBundling = (graph, app, currFile, modal, width, height) => { - const flatAdj = dfsFlatAdjList(graph, currFile.basename); - console.log({ flatAdj }); - const hier = stratify()(flatAdj); - console.log({ hier }); - const PADDING_BUBBLE = 15; // distance between edge end and bubble - const PADDING_LABEL = 30; // distance between edge end and engineer name - const BUBBLE_SIZE_MIN = 4; - const BUBBLE_SIZE_MAX = 20; - var diameter = 560, radius = diameter / 2, innerRadius = radius - 170; // between center and edge end - // The 'cluster' function takes 1 argument as input. It also has methods (??) like cluster.separation(), cluster.size() and cluster.nodeSize() - var cluster$1 = cluster().size([360, innerRadius]); - var line = lineRadial$1() - .curve(bundle.beta(0.85)) - .radius(function (d) { - return d[1]; - }) - .angle(function (d) { - return (d[0] / 180) * Math.PI; - }); - const svg = select(".d3-graph") - .append("svg") - .attr("height", height) - .attr("width", width) - .append("g") - .attr("transform", "translate(" + radius + "," + radius + ")"); - var link = svg.append("g").selectAll(".link"), label = svg.append("g").selectAll(".label"), bubble = svg.append("g").selectAll(".bubble"); - // Add a scale for bubble size - var bubbleSizeScale = linear() - .domain([0, 100]) - .range([BUBBLE_SIZE_MIN, BUBBLE_SIZE_MAX]); - // Scale for the bubble size - // If wanna see your data - // console.log(hierarchicalData) - // Reformat the data - var root = packageHierarchy(hier) - //debugger; - .sum(function (d) { - console.log(d); - return d.height; - }); - // console.log(root) - // Build an object that gives feature of each leaves - cluster$1(root); - const leaves = root.leaves(); - // Leaves is an array of Objects. 1 item = one leaf. Provides x and y for leaf position in the svg. Also gives details about its parent. - link - .data(packageImports(leaves)) - .enter() - .append("path") - .each(function (d) { - (d.source = d[0]), (d.target = d[d.length - 1]); - }) - .attr("class", "link") - .attr("d", line) - .attr("fill", "none") - .attr("stroke", "black"); - label - .data(leaves) - .enter() - .append("text") - .attr("class", "label") - .attr("dy", "0.31em") - .attr("transform", function (d) { - return ("rotate(" + - (d.x - 90) + - ")translate(" + - (d.y + PADDING_LABEL) + - ",0)" + - (d.x < 180 ? "" : "rotate(180)")); - }) - .attr("text-anchor", function (d) { - return d.x < 180 ? "start" : "end"; - }) - .text(function (d) { - return d.data.key; - }); - bubble - .data(leaves) - .enter() - .append("circle") - .attr("class", "bubble") - .attr("transform", function (d) { - return ("rotate(" + (d.x - 90) + ")translate(" + (d.y + PADDING_BUBBLE) + ",0)"); - }) - .attr("r", (d) => bubbleSizeScale(d.value)) - .attr("stroke", "black") - .attr("fill", "#69a3b2") - .style("opacity", 0.2); - // Lazily construct the package hierarchy from class names. - function packageHierarchy(classes) { - var map = {}; - function find(name, data) { - var node = map[name], i; - if (!node) { - node = map[name] = data || { name: name, children: [] }; - if (name.length) { - node.parent = find(name.substring(0, (i = name.lastIndexOf(".")))); - node.parent.children.push(node); - node.key = name.substring(i + 1); - } - } - return node; - } - classes.forEach(function (d) { - find(d.name, d); - }); - return hierarchy(map[""]); - } - // Return a list of imports for the given array of nodes. - function packageImports(nodes) { - var map = {}, imports = []; - // Compute a map from name to node. - nodes.forEach(function (d) { - map[d.data.name] = d; - }); - // For each import, construct a link from the source to target node. - nodes.forEach(function (d) { - if (d.data.imports) - d.data.imports.forEach(function (i) { - imports.push(map[d.data.name].path(map[i])); - }); - }); - return imports; - } + // If there are multiple coincident points, remove just the point. + if (previous) return (next ? previous.next = next : delete previous.next), this; + + // If this is the root point, remove it. + if (!parent) return this._root = next, this; + + // Remove this leaf. + next ? parent[i] = next : delete parent[i]; + + // If the parent now contains exactly one leaf, collapse superfluous parents. + if ((node = parent[0] || parent[1] || parent[2] || parent[3]) + && node === (parent[3] || parent[2] || parent[1] || parent[0]) + && !node.length) { + if (retainer) retainer[j] = node; + else this._root = node; + } + + return this; +} + +function removeAll(data) { + for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]); + return this; +} + +function tree_root() { + return this._root; +} + +function tree_size() { + var size = 0; + this.visit(function(node) { + if (!node.length) do ++size; while (node = node.next) + }); + return size; +} + +function tree_visit(callback) { + var quads = [], q, node = this._root, child, x0, y0, x1, y1; + if (node) quads.push(new Quad(node, this._x0, this._y0, this._x1, this._y1)); + while (q = quads.pop()) { + if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) { + var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2; + if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1)); + if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1)); + if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym)); + if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym)); + } + } + return this; +} + +function tree_visitAfter(callback) { + var quads = [], next = [], q; + if (this._root) quads.push(new Quad(this._root, this._x0, this._y0, this._x1, this._y1)); + while (q = quads.pop()) { + var node = q.node; + if (node.length) { + var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2; + if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym)); + if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym)); + if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1)); + if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1)); + } + next.push(q); + } + while (q = next.pop()) { + callback(q.node, q.x0, q.y0, q.x1, q.y1); + } + return this; +} + +function defaultX(d) { + return d[0]; +} + +function tree_x(_) { + return arguments.length ? (this._x = _, this) : this._x; +} + +function defaultY(d) { + return d[1]; +} + +function tree_y(_) { + return arguments.length ? (this._y = _, this) : this._y; +} + +function quadtree(nodes, x, y) { + var tree = new Quadtree(x == null ? defaultX : x, y == null ? defaultY : y, NaN, NaN, NaN, NaN); + return nodes == null ? tree : tree.addAll(nodes); +} + +function Quadtree(x, y, x0, y0, x1, y1) { + this._x = x; + this._y = y; + this._x0 = x0; + this._y0 = y0; + this._x1 = x1; + this._y1 = y1; + this._root = undefined; +} + +function leaf_copy(leaf) { + var copy = {data: leaf.data}, next = copy; + while (leaf = leaf.next) next = next.next = {data: leaf.data}; + return copy; +} + +var treeProto = quadtree.prototype = Quadtree.prototype; + +treeProto.copy = function() { + var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1), + node = this._root, + nodes, + child; + + if (!node) return copy; + + if (!node.length) return copy._root = leaf_copy(node), copy; + + nodes = [{source: node, target: copy._root = new Array(4)}]; + while (node = nodes.pop()) { + for (var i = 0; i < 4; ++i) { + if (child = node.source[i]) { + if (child.length) nodes.push({source: child, target: node.target[i] = new Array(4)}); + else node.target[i] = leaf_copy(child); + } + } + } + + return copy; }; -/** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ -function listCacheClear() { - this.__data__ = []; - this.size = 0; +treeProto.add = tree_add; +treeProto.addAll = addAll; +treeProto.cover = tree_cover; +treeProto.data = tree_data; +treeProto.extent = tree_extent; +treeProto.find = tree_find; +treeProto.remove = tree_remove; +treeProto.removeAll = removeAll; +treeProto.root = tree_root; +treeProto.size = tree_size; +treeProto.visit = tree_visit; +treeProto.visitAfter = tree_visitAfter; +treeProto.x = tree_x; +treeProto.y = tree_y; + +function constant$3(x) { + return function() { + return x; + }; } -var _listCacheClear = listCacheClear; +function jiggle(random) { + return (random() - 0.5) * 1e-6; +} -/** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ -function eq(value, other) { - return value === other || (value !== value && other !== other); +function x$2(d) { + return d.x + d.vx; } -var eq_1 = eq; +function y$2(d) { + return d.y + d.vy; +} -/** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq_1(array[length][0], key)) { - return length; +function collide(radius) { + var nodes, + radii, + random, + strength = 1, + iterations = 1; + + if (typeof radius !== "function") radius = constant$3(radius == null ? 1 : +radius); + + function force() { + var i, n = nodes.length, + tree, + node, + xi, + yi, + ri, + ri2; + + for (var k = 0; k < iterations; ++k) { + tree = quadtree(nodes, x$2, y$2).visitAfter(prepare); + for (i = 0; i < n; ++i) { + node = nodes[i]; + ri = radii[node.index], ri2 = ri * ri; + xi = node.x + node.vx; + yi = node.y + node.vy; + tree.visit(apply); + } + } + + function apply(quad, x0, y0, x1, y1) { + var data = quad.data, rj = quad.r, r = ri + rj; + if (data) { + if (data.index > node.index) { + var x = xi - data.x - data.vx, + y = yi - data.y - data.vy, + l = x * x + y * y; + if (l < r * r) { + if (x === 0) x = jiggle(random), l += x * x; + if (y === 0) y = jiggle(random), l += y * y; + l = (r - (l = Math.sqrt(l))) / l * strength; + node.vx += (x *= l) * (r = (rj *= rj) / (ri2 + rj)); + node.vy += (y *= l) * r; + data.vx -= x * (r = 1 - r); + data.vy -= y * r; + } + } + return; + } + return x0 > xi + r || x1 < xi - r || y0 > yi + r || y1 < yi - r; } } - return -1; -} - -var _assocIndexOf = assocIndexOf; - -/** Used for built-in method references. */ -var arrayProto = Array.prototype; - -/** Built-in value references. */ -var splice = arrayProto.splice; - -/** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function listCacheDelete(key) { - var data = this.__data__, - index = _assocIndexOf(data, key); - - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - --this.size; - return true; -} - -var _listCacheDelete = listCacheDelete; - -/** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function listCacheGet(key) { - var data = this.__data__, - index = _assocIndexOf(data, key); - - return index < 0 ? undefined : data[index][1]; -} - -var _listCacheGet = listCacheGet; - -/** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function listCacheHas(key) { - return _assocIndexOf(this.__data__, key) > -1; -} - -var _listCacheHas = listCacheHas; - -/** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ -function listCacheSet(key, value) { - var data = this.__data__, - index = _assocIndexOf(data, key); - if (index < 0) { - ++this.size; - data.push([key, value]); - } else { - data[index][1] = value; + function prepare(quad) { + if (quad.data) return quad.r = radii[quad.data.index]; + for (var i = quad.r = 0; i < 4; ++i) { + if (quad[i] && quad[i].r > quad.r) { + quad.r = quad[i].r; + } + } } - return this; -} - -var _listCacheSet = listCacheSet; -/** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function ListCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); + function initialize() { + if (!nodes) return; + var i, n = nodes.length, node; + radii = new Array(n); + for (i = 0; i < n; ++i) node = nodes[i], radii[node.index] = +radius(node, i, nodes); } -} -// Add methods to `ListCache`. -ListCache.prototype.clear = _listCacheClear; -ListCache.prototype['delete'] = _listCacheDelete; -ListCache.prototype.get = _listCacheGet; -ListCache.prototype.has = _listCacheHas; -ListCache.prototype.set = _listCacheSet; - -var _ListCache = ListCache; + force.initialize = function(_nodes, _random) { + nodes = _nodes; + random = _random; + initialize(); + }; -/** - * Removes all key-value entries from the stack. - * - * @private - * @name clear - * @memberOf Stack - */ -function stackClear() { - this.__data__ = new _ListCache; - this.size = 0; -} + force.iterations = function(_) { + return arguments.length ? (iterations = +_, force) : iterations; + }; -var _stackClear = stackClear; + force.strength = function(_) { + return arguments.length ? (strength = +_, force) : strength; + }; -/** - * Removes `key` and its value from the stack. - * - * @private - * @name delete - * @memberOf Stack - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function stackDelete(key) { - var data = this.__data__, - result = data['delete'](key); + force.radius = function(_) { + return arguments.length ? (radius = typeof _ === "function" ? _ : constant$3(+_), initialize(), force) : radius; + }; - this.size = data.size; - return result; + return force; } -var _stackDelete = stackDelete; - -/** - * Gets the stack value for `key`. - * - * @private - * @name get - * @memberOf Stack - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function stackGet(key) { - return this.__data__.get(key); +function index$1(d) { + return d.index; } -var _stackGet = stackGet; - -/** - * Checks if a stack value for `key` exists. - * - * @private - * @name has - * @memberOf Stack - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function stackHas(key) { - return this.__data__.has(key); +function find(nodeById, nodeId) { + var node = nodeById.get(nodeId); + if (!node) throw new Error("node not found: " + nodeId); + return node; } -var _stackHas = stackHas; - -/** Detect free variable `global` from Node.js. */ - -var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; +function link$1(links) { + var id = index$1, + strength = defaultStrength, + strengths, + distance = constant$3(30), + distances, + nodes, + count, + bias, + random, + iterations = 1; -var _freeGlobal = freeGlobal; + if (links == null) links = []; -/** Detect free variable `self`. */ -var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + function defaultStrength(link) { + return 1 / Math.min(count[link.source.index], count[link.target.index]); + } -/** Used as a reference to the global object. */ -var root = _freeGlobal || freeSelf || Function('return this')(); + function force(alpha) { + for (var k = 0, n = links.length; k < iterations; ++k) { + for (var i = 0, link, source, target, x, y, l, b; i < n; ++i) { + link = links[i], source = link.source, target = link.target; + x = target.x + target.vx - source.x - source.vx || jiggle(random); + y = target.y + target.vy - source.y - source.vy || jiggle(random); + l = Math.sqrt(x * x + y * y); + l = (l - distances[i]) / l * alpha * strengths[i]; + x *= l, y *= l; + target.vx -= x * (b = bias[i]); + target.vy -= y * b; + source.vx += x * (b = 1 - b); + source.vy += y * b; + } + } + } -var _root = root; + function initialize() { + if (!nodes) return; -/** Built-in value references. */ -var Symbol$1 = _root.Symbol; + var i, + n = nodes.length, + m = links.length, + nodeById = new Map(nodes.map((d, i) => [id(d, i, nodes), d])), + link; -var _Symbol = Symbol$1; + for (i = 0, count = new Array(n); i < m; ++i) { + link = links[i], link.index = i; + if (typeof link.source !== "object") link.source = find(nodeById, link.source); + if (typeof link.target !== "object") link.target = find(nodeById, link.target); + count[link.source.index] = (count[link.source.index] || 0) + 1; + count[link.target.index] = (count[link.target.index] || 0) + 1; + } -/** Used for built-in method references. */ -var objectProto$g = Object.prototype; + for (i = 0, bias = new Array(m); i < m; ++i) { + link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]); + } -/** Used to check objects for own properties. */ -var hasOwnProperty$d = objectProto$g.hasOwnProperty; + strengths = new Array(m), initializeStrength(); + distances = new Array(m), initializeDistance(); + } -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString$1 = objectProto$g.toString; + function initializeStrength() { + if (!nodes) return; -/** Built-in value references. */ -var symToStringTag$1 = _Symbol ? _Symbol.toStringTag : undefined; + for (var i = 0, n = links.length; i < n; ++i) { + strengths[i] = +strength(links[i], i, links); + } + } -/** - * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the raw `toStringTag`. - */ -function getRawTag(value) { - var isOwn = hasOwnProperty$d.call(value, symToStringTag$1), - tag = value[symToStringTag$1]; + function initializeDistance() { + if (!nodes) return; - try { - value[symToStringTag$1] = undefined; - var unmasked = true; - } catch (e) {} - - var result = nativeObjectToString$1.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag$1] = tag; - } else { - delete value[symToStringTag$1]; + for (var i = 0, n = links.length; i < n; ++i) { + distances[i] = +distance(links[i], i, links); } } - return result; -} - -var _getRawTag = getRawTag; -/** Used for built-in method references. */ -var objectProto$f = Object.prototype; + force.initialize = function(_nodes, _random) { + nodes = _nodes; + random = _random; + initialize(); + }; -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var nativeObjectToString = objectProto$f.toString; + force.links = function(_) { + return arguments.length ? (links = _, initialize(), force) : links; + }; -/** - * Converts `value` to a string using `Object.prototype.toString`. - * - * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - */ -function objectToString(value) { - return nativeObjectToString.call(value); -} + force.id = function(_) { + return arguments.length ? (id = _, force) : id; + }; -var _objectToString = objectToString; + force.iterations = function(_) { + return arguments.length ? (iterations = +_, force) : iterations; + }; -/** `Object#toString` result references. */ -var nullTag = '[object Null]', - undefinedTag = '[object Undefined]'; + force.strength = function(_) { + return arguments.length ? (strength = typeof _ === "function" ? _ : constant$3(+_), initializeStrength(), force) : strength; + }; -/** Built-in value references. */ -var symToStringTag = _Symbol ? _Symbol.toStringTag : undefined; + force.distance = function(_) { + return arguments.length ? (distance = typeof _ === "function" ? _ : constant$3(+_), initializeDistance(), force) : distance; + }; -/** - * The base implementation of `getTag` without fallbacks for buggy environments. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ -function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; - } - return (symToStringTag && symToStringTag in Object(value)) - ? _getRawTag(value) - : _objectToString(value); + return force; } -var _baseGetTag = baseGetTag; +// https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use +const a = 1664525; +const c$1 = 1013904223; +const m = 4294967296; // 2^32 -/** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ -function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); +function lcg() { + let s = 1; + return () => (s = (a * s + c$1) % m) / m; } -var isObject_1 = isObject; - -/** `Object#toString` result references. */ -var asyncTag = '[object AsyncFunction]', - funcTag$2 = '[object Function]', - genTag$1 = '[object GeneratorFunction]', - proxyTag = '[object Proxy]'; - -/** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ -function isFunction(value) { - if (!isObject_1(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = _baseGetTag(value); - return tag == funcTag$2 || tag == genTag$1 || tag == asyncTag || tag == proxyTag; +function x$1(d) { + return d.x; } -var isFunction_1 = isFunction; - -/** Used to detect overreaching core-js shims. */ -var coreJsData = _root['__core-js_shared__']; - -var _coreJsData = coreJsData; - -/** Used to detect methods masquerading as native. */ -var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(_coreJsData && _coreJsData.keys && _coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; -}()); - -/** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ -function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); +function y$1(d) { + return d.y; } -var _isMasked = isMasked; +var initialRadius = 10, + initialAngle = Math.PI * (3 - Math.sqrt(5)); -/** Used for built-in method references. */ -var funcProto$1 = Function.prototype; +function simulation(nodes) { + var simulation, + alpha = 1, + alphaMin = 0.001, + alphaDecay = 1 - Math.pow(alphaMin, 1 / 300), + alphaTarget = 0, + velocityDecay = 0.6, + forces = new Map(), + stepper = timer(step), + event = dispatch("tick", "end"), + random = lcg(); -/** Used to resolve the decompiled source of functions. */ -var funcToString$1 = funcProto$1.toString; + if (nodes == null) nodes = []; -/** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to convert. - * @returns {string} Returns the source code. - */ -function toSource(func) { - if (func != null) { - try { - return funcToString$1.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} + function step() { + tick(); + event.call("tick", simulation); + if (alpha < alphaMin) { + stepper.stop(); + event.call("end", simulation); + } } - return ''; -} - -var _toSource = toSource; - -/** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; + function tick(iterations) { + var i, n = nodes.length, node; -/** Used for built-in method references. */ -var funcProto = Function.prototype, - objectProto$e = Object.prototype; + if (iterations === undefined) iterations = 1; -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; + for (var k = 0; k < iterations; ++k) { + alpha += (alphaTarget - alpha) * alphaDecay; -/** Used to check objects for own properties. */ -var hasOwnProperty$c = objectProto$e.hasOwnProperty; + forces.forEach(function(force) { + force(alpha); + }); -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty$c).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); + for (i = 0; i < n; ++i) { + node = nodes[i]; + if (node.fx == null) node.x += node.vx *= velocityDecay; + else node.x = node.fx, node.vx = 0; + if (node.fy == null) node.y += node.vy *= velocityDecay; + else node.y = node.fy, node.vy = 0; + } + } -/** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ -function baseIsNative(value) { - if (!isObject_1(value) || _isMasked(value)) { - return false; + return simulation; } - var pattern = isFunction_1(value) ? reIsNative : reIsHostCtor; - return pattern.test(_toSource(value)); -} - -var _baseIsNative = baseIsNative; - -/** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ -function getValue(object, key) { - return object == null ? undefined : object[key]; -} - -var _getValue = getValue; - -/** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ -function getNative(object, key) { - var value = _getValue(object, key); - return _baseIsNative(value) ? value : undefined; -} - -var _getNative = getNative; - -/* Built-in method references that are verified to be native. */ -var Map$1 = _getNative(_root, 'Map'); - -var _Map = Map$1; - -/* Built-in method references that are verified to be native. */ -var nativeCreate = _getNative(Object, 'create'); -var _nativeCreate = nativeCreate; - -/** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ -function hashClear() { - this.__data__ = _nativeCreate ? _nativeCreate(null) : {}; - this.size = 0; -} - -var _hashClear = hashClear; + function initializeNodes() { + for (var i = 0, n = nodes.length, node; i < n; ++i) { + node = nodes[i], node.index = i; + if (node.fx != null) node.x = node.fx; + if (node.fy != null) node.y = node.fy; + if (isNaN(node.x) || isNaN(node.y)) { + var radius = initialRadius * Math.sqrt(0.5 + i), angle = i * initialAngle; + node.x = radius * Math.cos(angle); + node.y = radius * Math.sin(angle); + } + if (isNaN(node.vx) || isNaN(node.vy)) { + node.vx = node.vy = 0; + } + } + } -/** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function hashDelete(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; -} + function initializeForce(force) { + if (force.initialize) force.initialize(nodes, random); + return force; + } -var _hashDelete = hashDelete; + initializeNodes(); -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED$2 = '__lodash_hash_undefined__'; + return simulation = { + tick: tick, -/** Used for built-in method references. */ -var objectProto$d = Object.prototype; + restart: function() { + return stepper.restart(step), simulation; + }, -/** Used to check objects for own properties. */ -var hasOwnProperty$b = objectProto$d.hasOwnProperty; + stop: function() { + return stepper.stop(), simulation; + }, -/** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function hashGet(key) { - var data = this.__data__; - if (_nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED$2 ? undefined : result; - } - return hasOwnProperty$b.call(data, key) ? data[key] : undefined; -} + nodes: function(_) { + return arguments.length ? (nodes = _, initializeNodes(), forces.forEach(initializeForce), simulation) : nodes; + }, -var _hashGet = hashGet; + alpha: function(_) { + return arguments.length ? (alpha = +_, simulation) : alpha; + }, -/** Used for built-in method references. */ -var objectProto$c = Object.prototype; + alphaMin: function(_) { + return arguments.length ? (alphaMin = +_, simulation) : alphaMin; + }, -/** Used to check objects for own properties. */ -var hasOwnProperty$a = objectProto$c.hasOwnProperty; + alphaDecay: function(_) { + return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay; + }, -/** - * Checks if a hash value for `key` exists. - * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function hashHas(key) { - var data = this.__data__; - return _nativeCreate ? (data[key] !== undefined) : hasOwnProperty$a.call(data, key); -} + alphaTarget: function(_) { + return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget; + }, -var _hashHas = hashHas; + velocityDecay: function(_) { + return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay; + }, -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED$1 = '__lodash_hash_undefined__'; + randomSource: function(_) { + return arguments.length ? (random = _, forces.forEach(initializeForce), simulation) : random; + }, -/** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ -function hashSet(key, value) { - var data = this.__data__; - this.size += this.has(key) ? 0 : 1; - data[key] = (_nativeCreate && value === undefined) ? HASH_UNDEFINED$1 : value; - return this; -} + force: function(name, _) { + return arguments.length > 1 ? ((_ == null ? forces.delete(name) : forces.set(name, initializeForce(_))), simulation) : forces.get(name); + }, -var _hashSet = hashSet; + find: function(x, y, radius) { + var i = 0, + n = nodes.length, + dx, + dy, + d2, + node, + closest; -/** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Hash(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} + if (radius == null) radius = Infinity; + else radius *= radius; -// Add methods to `Hash`. -Hash.prototype.clear = _hashClear; -Hash.prototype['delete'] = _hashDelete; -Hash.prototype.get = _hashGet; -Hash.prototype.has = _hashHas; -Hash.prototype.set = _hashSet; + for (i = 0; i < n; ++i) { + node = nodes[i]; + dx = x - node.x; + dy = y - node.y; + d2 = dx * dx + dy * dy; + if (d2 < radius) closest = node, radius = d2; + } -var _Hash = Hash; + return closest; + }, -/** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ -function mapCacheClear() { - this.size = 0; - this.__data__ = { - 'hash': new _Hash, - 'map': new (_Map || _ListCache), - 'string': new _Hash + on: function(name, _) { + return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name); + } }; } -var _mapCacheClear = mapCacheClear; - -/** - * Checks if `value` is suitable for use as unique object key. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ -function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); -} - -var _isKeyable = isKeyable; +function manyBody() { + var nodes, + node, + random, + alpha, + strength = constant$3(-30), + strengths, + distanceMin2 = 1, + distanceMax2 = Infinity, + theta2 = 0.81; -/** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ -function getMapData(map, key) { - var data = map.__data__; - return _isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; -} + function force(_) { + var i, n = nodes.length, tree = quadtree(nodes, x$1, y$1).visitAfter(accumulate); + for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply); + } -var _getMapData = getMapData; + function initialize() { + if (!nodes) return; + var i, n = nodes.length, node; + strengths = new Array(n); + for (i = 0; i < n; ++i) node = nodes[i], strengths[node.index] = +strength(node, i, nodes); + } -/** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function mapCacheDelete(key) { - var result = _getMapData(this, key)['delete'](key); - this.size -= result ? 1 : 0; - return result; -} + function accumulate(quad) { + var strength = 0, q, c, weight = 0, x, y, i; -var _mapCacheDelete = mapCacheDelete; + // For internal nodes, accumulate forces from child quadrants. + if (quad.length) { + for (x = y = i = 0; i < 4; ++i) { + if ((q = quad[i]) && (c = Math.abs(q.value))) { + strength += q.value, weight += c, x += c * q.x, y += c * q.y; + } + } + quad.x = x / weight; + quad.y = y / weight; + } -/** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function mapCacheGet(key) { - return _getMapData(this, key).get(key); -} + // For leaf nodes, accumulate forces from coincident quadrants. + else { + q = quad; + q.x = q.data.x; + q.y = q.data.y; + do strength += strengths[q.data.index]; + while (q = q.next); + } -var _mapCacheGet = mapCacheGet; + quad.value = strength; + } -/** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function mapCacheHas(key) { - return _getMapData(this, key).has(key); -} + function apply(quad, x1, _, x2) { + if (!quad.value) return true; -var _mapCacheHas = mapCacheHas; + var x = quad.x - node.x, + y = quad.y - node.y, + w = x2 - x1, + l = x * x + y * y; -/** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ -function mapCacheSet(key, value) { - var data = _getMapData(this, key), - size = data.size; + // Apply the Barnes-Hut approximation if possible. + // Limit forces for very close nodes; randomize direction if coincident. + if (w * w / theta2 < l) { + if (l < distanceMax2) { + if (x === 0) x = jiggle(random), l += x * x; + if (y === 0) y = jiggle(random), l += y * y; + if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l); + node.vx += x * quad.value * alpha / l; + node.vy += y * quad.value * alpha / l; + } + return true; + } - data.set(key, value); - this.size += data.size == size ? 0 : 1; - return this; -} + // Otherwise, process points directly. + else if (quad.length || l >= distanceMax2) return; -var _mapCacheSet = mapCacheSet; + // Limit forces for very close nodes; randomize direction if coincident. + if (quad.data !== node || quad.next) { + if (x === 0) x = jiggle(random), l += x * x; + if (y === 0) y = jiggle(random), l += y * y; + if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l); + } -/** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function MapCache(entries) { - var index = -1, - length = entries == null ? 0 : entries.length; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); + do if (quad.data !== node) { + w = strengths[quad.data.index] * alpha / l; + node.vx += x * w; + node.vy += y * w; + } while (quad = quad.next); } -} -// Add methods to `MapCache`. -MapCache.prototype.clear = _mapCacheClear; -MapCache.prototype['delete'] = _mapCacheDelete; -MapCache.prototype.get = _mapCacheGet; -MapCache.prototype.has = _mapCacheHas; -MapCache.prototype.set = _mapCacheSet; + force.initialize = function(_nodes, _random) { + nodes = _nodes; + random = _random; + initialize(); + }; -var _MapCache = MapCache; + force.strength = function(_) { + return arguments.length ? (strength = typeof _ === "function" ? _ : constant$3(+_), initialize(), force) : strength; + }; -/** Used as the size to enable large array optimizations. */ -var LARGE_ARRAY_SIZE$1 = 200; + force.distanceMin = function(_) { + return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2); + }; -/** - * Sets the stack `key` to `value`. - * - * @private - * @name set - * @memberOf Stack - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the stack cache instance. - */ -function stackSet(key, value) { - var data = this.__data__; - if (data instanceof _ListCache) { - var pairs = data.__data__; - if (!_Map || (pairs.length < LARGE_ARRAY_SIZE$1 - 1)) { - pairs.push([key, value]); - this.size = ++data.size; - return this; - } - data = this.__data__ = new _MapCache(pairs); - } - data.set(key, value); - this.size = data.size; - return this; -} + force.distanceMax = function(_) { + return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2); + }; -var _stackSet = stackSet; + force.theta = function(_) { + return arguments.length ? (theta2 = _ * _, force) : Math.sqrt(theta2); + }; -/** - * Creates a stack cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Stack(entries) { - var data = this.__data__ = new _ListCache(entries); - this.size = data.size; + return force; } -// Add methods to `Stack`. -Stack.prototype.clear = _stackClear; -Stack.prototype['delete'] = _stackDelete; -Stack.prototype.get = _stackGet; -Stack.prototype.has = _stackHas; -Stack.prototype.set = _stackSet; +function formatDecimal(x) { + return Math.abs(x = Math.round(x)) >= 1e21 + ? x.toLocaleString("en").replace(/,/g, "") + : x.toString(10); +} -var _Stack = Stack; +// Computes the decimal coefficient and exponent of the specified number x with +// significant digits p, where x is positive and p is in [1, 21] or undefined. +// For example, formatDecimalParts(1.23) returns ["123", 0]. +function formatDecimalParts(x, p) { + if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity + var i, coefficient = x.slice(0, i); -/** - * A specialized version of `_.forEach` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. - */ -function arrayEach(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length; + // The string returned by toExponential either has the form \d\.\d+e[-+]\d+ + // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3). + return [ + coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient, + +x.slice(i + 1) + ]; +} - while (++index < length) { - if (iteratee(array[index], index, array) === false) { - break; - } - } - return array; +function exponent(x) { + return x = formatDecimalParts(Math.abs(x)), x ? x[1] : NaN; } -var _arrayEach = arrayEach; +function formatGroup(grouping, thousands) { + return function(value, width) { + var i = value.length, + t = [], + j = 0, + g = grouping[0], + length = 0; -var defineProperty = (function() { - try { - var func = _getNative(Object, 'defineProperty'); - func({}, '', {}); - return func; - } catch (e) {} -}()); + while (i > 0 && g > 0) { + if (length + g + 1 > width) g = Math.max(1, width - length); + t.push(value.substring(i -= g, i + g)); + if ((length += g + 1) > width) break; + g = grouping[j = (j + 1) % grouping.length]; + } -var _defineProperty = defineProperty; + return t.reverse().join(thousands); + }; +} -/** - * The base implementation of `assignValue` and `assignMergeValue` without - * value checks. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ -function baseAssignValue(object, key, value) { - if (key == '__proto__' && _defineProperty) { - _defineProperty(object, key, { - 'configurable': true, - 'enumerable': true, - 'value': value, - 'writable': true +function formatNumerals(numerals) { + return function(value) { + return value.replace(/[0-9]/g, function(i) { + return numerals[+i]; }); - } else { - object[key] = value; - } + }; } -var _baseAssignValue = baseAssignValue; - -/** Used for built-in method references. */ -var objectProto$b = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty$9 = objectProto$b.hasOwnProperty; +// [[fill]align][sign][symbol][0][width][,][.precision][~][type] +var re = /^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i; -/** - * Assigns `value` to `key` of `object` if the existing value is not equivalent - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ -function assignValue(object, key, value) { - var objValue = object[key]; - if (!(hasOwnProperty$9.call(object, key) && eq_1(objValue, value)) || - (value === undefined && !(key in object))) { - _baseAssignValue(object, key, value); - } +function formatSpecifier(specifier) { + if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier); + var match; + return new FormatSpecifier({ + fill: match[1], + align: match[2], + sign: match[3], + symbol: match[4], + zero: match[5], + width: match[6], + comma: match[7], + precision: match[8] && match[8].slice(1), + trim: match[9], + type: match[10] + }); } -var _assignValue = assignValue; - -/** - * Copies properties of `source` to `object`. - * - * @private - * @param {Object} source The object to copy properties from. - * @param {Array} props The property identifiers to copy. - * @param {Object} [object={}] The object to copy properties to. - * @param {Function} [customizer] The function to customize copied values. - * @returns {Object} Returns `object`. - */ -function copyObject(source, props, object, customizer) { - var isNew = !object; - object || (object = {}); - - var index = -1, - length = props.length; +formatSpecifier.prototype = FormatSpecifier.prototype; // instanceof - while (++index < length) { - var key = props[index]; +function FormatSpecifier(specifier) { + this.fill = specifier.fill === undefined ? " " : specifier.fill + ""; + this.align = specifier.align === undefined ? ">" : specifier.align + ""; + this.sign = specifier.sign === undefined ? "-" : specifier.sign + ""; + this.symbol = specifier.symbol === undefined ? "" : specifier.symbol + ""; + this.zero = !!specifier.zero; + this.width = specifier.width === undefined ? undefined : +specifier.width; + this.comma = !!specifier.comma; + this.precision = specifier.precision === undefined ? undefined : +specifier.precision; + this.trim = !!specifier.trim; + this.type = specifier.type === undefined ? "" : specifier.type + ""; +} - var newValue = customizer - ? customizer(object[key], source[key], key, object, source) - : undefined; +FormatSpecifier.prototype.toString = function() { + return this.fill + + this.align + + this.sign + + this.symbol + + (this.zero ? "0" : "") + + (this.width === undefined ? "" : Math.max(1, this.width | 0)) + + (this.comma ? "," : "") + + (this.precision === undefined ? "" : "." + Math.max(0, this.precision | 0)) + + (this.trim ? "~" : "") + + this.type; +}; - if (newValue === undefined) { - newValue = source[key]; - } - if (isNew) { - _baseAssignValue(object, key, newValue); - } else { - _assignValue(object, key, newValue); +// Trims insignificant zeros, e.g., replaces 1.2000k with 1.2k. +function formatTrim(s) { + out: for (var n = s.length, i = 1, i0 = -1, i1; i < n; ++i) { + switch (s[i]) { + case ".": i0 = i1 = i; break; + case "0": if (i0 === 0) i0 = i; i1 = i; break; + default: if (!+s[i]) break out; if (i0 > 0) i0 = 0; break; } } - return object; + return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s; } -var _copyObject = copyObject; - -/** - * The base implementation of `_.times` without support for iteratee shorthands - * or max array length checks. - * - * @private - * @param {number} n The number of times to invoke `iteratee`. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the array of results. - */ -function baseTimes(n, iteratee) { - var index = -1, - result = Array(n); +var prefixExponent; - while (++index < n) { - result[index] = iteratee(index); - } - return result; +function formatPrefixAuto(x, p) { + var d = formatDecimalParts(x, p); + if (!d) return x + ""; + var coefficient = d[0], + exponent = d[1], + i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1, + n = coefficient.length; + return i === n ? coefficient + : i > n ? coefficient + new Array(i - n + 1).join("0") + : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i) + : "0." + new Array(1 - i).join("0") + formatDecimalParts(x, Math.max(0, p + i - 1))[0]; // less than 1y! } -var _baseTimes = baseTimes; - -/** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ -function isObjectLike(value) { - return value != null && typeof value == 'object'; +function formatRounded(x, p) { + var d = formatDecimalParts(x, p); + if (!d) return x + ""; + var coefficient = d[0], + exponent = d[1]; + return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient + : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1) + : coefficient + new Array(exponent - coefficient.length + 2).join("0"); } -var isObjectLike_1 = isObjectLike; - -/** `Object#toString` result references. */ -var argsTag$3 = '[object Arguments]'; +var formatTypes = { + "%": (x, p) => (x * 100).toFixed(p), + "b": (x) => Math.round(x).toString(2), + "c": (x) => x + "", + "d": formatDecimal, + "e": (x, p) => x.toExponential(p), + "f": (x, p) => x.toFixed(p), + "g": (x, p) => x.toPrecision(p), + "o": (x) => Math.round(x).toString(8), + "p": (x, p) => formatRounded(x * 100, p), + "r": formatRounded, + "s": formatPrefixAuto, + "X": (x) => Math.round(x).toString(16).toUpperCase(), + "x": (x) => Math.round(x).toString(16) +}; -/** - * The base implementation of `_.isArguments`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - */ -function baseIsArguments(value) { - return isObjectLike_1(value) && _baseGetTag(value) == argsTag$3; +function identity$2(x) { + return x; } -var _baseIsArguments = baseIsArguments; +var map = Array.prototype.map, + prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"]; -/** Used for built-in method references. */ -var objectProto$a = Object.prototype; +function formatLocale(locale) { + var group = locale.grouping === undefined || locale.thousands === undefined ? identity$2 : formatGroup(map.call(locale.grouping, Number), locale.thousands + ""), + currencyPrefix = locale.currency === undefined ? "" : locale.currency[0] + "", + currencySuffix = locale.currency === undefined ? "" : locale.currency[1] + "", + decimal = locale.decimal === undefined ? "." : locale.decimal + "", + numerals = locale.numerals === undefined ? identity$2 : formatNumerals(map.call(locale.numerals, String)), + percent = locale.percent === undefined ? "%" : locale.percent + "", + minus = locale.minus === undefined ? "−" : locale.minus + "", + nan = locale.nan === undefined ? "NaN" : locale.nan + ""; -/** Used to check objects for own properties. */ -var hasOwnProperty$8 = objectProto$a.hasOwnProperty; + function newFormat(specifier) { + specifier = formatSpecifier(specifier); -/** Built-in value references. */ -var propertyIsEnumerable$1 = objectProto$a.propertyIsEnumerable; + var fill = specifier.fill, + align = specifier.align, + sign = specifier.sign, + symbol = specifier.symbol, + zero = specifier.zero, + width = specifier.width, + comma = specifier.comma, + precision = specifier.precision, + trim = specifier.trim, + type = specifier.type; -/** - * Checks if `value` is likely an `arguments` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - * else `false`. - * @example - * - * _.isArguments(function() { return arguments; }()); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ -var isArguments = _baseIsArguments(function() { return arguments; }()) ? _baseIsArguments : function(value) { - return isObjectLike_1(value) && hasOwnProperty$8.call(value, 'callee') && - !propertyIsEnumerable$1.call(value, 'callee'); -}; + // The "n" type is an alias for ",g". + if (type === "n") comma = true, type = "g"; -var isArguments_1 = isArguments; + // The "" type, and any invalid type, is an alias for ".12~g". + else if (!formatTypes[type]) precision === undefined && (precision = 12), trim = true, type = "g"; -/** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ -var isArray = Array.isArray; + // If zero fill is specified, padding goes after sign and before digits. + if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "="; -var isArray_1 = isArray; + // Compute the prefix and suffix. + // For SI-prefix, the suffix is lazily computed. + var prefix = symbol === "$" ? currencyPrefix : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "", + suffix = symbol === "$" ? currencySuffix : /[%p]/.test(type) ? percent : ""; -/** - * This method returns `false`. - * - * @static - * @memberOf _ - * @since 4.13.0 - * @category Util - * @returns {boolean} Returns `false`. - * @example - * - * _.times(2, _.stubFalse); - * // => [false, false] - */ -function stubFalse() { - return false; -} + // What format function should we use? + // Is this an integer type? + // Can this type generate exponential notation? + var formatType = formatTypes[type], + maybeSuffix = /[defgprs%]/.test(type); -var stubFalse_1 = stubFalse; + // Set the default precision if not specified, + // or clamp the specified precision to the supported range. + // For significant precision, it must be in [1, 21]. + // For fixed precision, it must be in [0, 20]. + precision = precision === undefined ? 6 + : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision)) + : Math.max(0, Math.min(20, precision)); -var isBuffer_1 = createCommonjsModule(function (module, exports) { -/** Detect free variable `exports`. */ -var freeExports = exports && !exports.nodeType && exports; + function format(value) { + var valuePrefix = prefix, + valueSuffix = suffix, + i, n, c; -/** Detect free variable `module`. */ -var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; + if (type === "c") { + valueSuffix = formatType(value) + valueSuffix; + value = ""; + } else { + value = +value; -/** Detect the popular CommonJS extension `module.exports`. */ -var moduleExports = freeModule && freeModule.exports === freeExports; + // Determine the sign. -0 is not less than 0, but 1 / -0 is! + var valueNegative = value < 0 || 1 / value < 0; -/** Built-in value references. */ -var Buffer = moduleExports ? _root.Buffer : undefined; + // Perform the initial formatting. + value = isNaN(value) ? nan : formatType(Math.abs(value), precision); -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined; + // Trim insignificant zeros. + if (trim) value = formatTrim(value); -/** - * Checks if `value` is a buffer. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. - * @example - * - * _.isBuffer(new Buffer(2)); - * // => true - * - * _.isBuffer(new Uint8Array(2)); - * // => false - */ -var isBuffer = nativeIsBuffer || stubFalse_1; + // If a negative value rounds to zero after formatting, and no explicit positive sign is requested, hide the sign. + if (valueNegative && +value === 0 && sign !== "+") valueNegative = false; -module.exports = isBuffer; -}); + // Compute the prefix and suffix. + valuePrefix = (valueNegative ? (sign === "(" ? sign : minus) : sign === "-" || sign === "(" ? "" : sign) + valuePrefix; + valueSuffix = (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + valueSuffix + (valueNegative && sign === "(" ? ")" : ""); -/** Used as references for various `Number` constants. */ -var MAX_SAFE_INTEGER$1 = 9007199254740991; + // Break the formatted value into the integer “value” part that can be + // grouped, and fractional or exponential “suffix” part that is not. + if (maybeSuffix) { + i = -1, n = value.length; + while (++i < n) { + if (c = value.charCodeAt(i), 48 > c || c > 57) { + valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix; + value = value.slice(0, i); + break; + } + } + } + } -/** Used to detect unsigned integer values. */ -var reIsUint = /^(?:0|[1-9]\d*)$/; + // If the fill character is not "0", grouping is applied before padding. + if (comma && !zero) value = group(value, Infinity); -/** - * Checks if `value` is a valid array-like index. - * - * @private - * @param {*} value The value to check. - * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. - * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. - */ -function isIndex(value, length) { - var type = typeof value; - length = length == null ? MAX_SAFE_INTEGER$1 : length; + // Compute the padding. + var length = valuePrefix.length + value.length + valueSuffix.length, + padding = length < width ? new Array(width - length + 1).join(fill) : ""; - return !!length && - (type == 'number' || - (type != 'symbol' && reIsUint.test(value))) && - (value > -1 && value % 1 == 0 && value < length); -} + // If the fill character is "0", grouping is applied after padding. + if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = ""; -var _isIndex = isIndex; + // Reconstruct the final output based on the desired alignment. + switch (align) { + case "<": value = valuePrefix + value + valueSuffix + padding; break; + case "=": value = valuePrefix + padding + value + valueSuffix; break; + case "^": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break; + default: value = padding + valuePrefix + value + valueSuffix; break; + } -/** Used as references for various `Number` constants. */ -var MAX_SAFE_INTEGER = 9007199254740991; + return numerals(value); + } -/** - * Checks if `value` is a valid array-like length. - * - * **Note:** This method is loosely based on - * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. - * @example - * - * _.isLength(3); - * // => true - * - * _.isLength(Number.MIN_VALUE); - * // => false - * - * _.isLength(Infinity); - * // => false - * - * _.isLength('3'); - * // => false - */ -function isLength(value) { - return typeof value == 'number' && - value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; -} - -var isLength_1 = isLength; - -/** `Object#toString` result references. */ -var argsTag$2 = '[object Arguments]', - arrayTag$2 = '[object Array]', - boolTag$3 = '[object Boolean]', - dateTag$3 = '[object Date]', - errorTag$2 = '[object Error]', - funcTag$1 = '[object Function]', - mapTag$7 = '[object Map]', - numberTag$3 = '[object Number]', - objectTag$3 = '[object Object]', - regexpTag$3 = '[object RegExp]', - setTag$7 = '[object Set]', - stringTag$4 = '[object String]', - weakMapTag$2 = '[object WeakMap]'; - -var arrayBufferTag$3 = '[object ArrayBuffer]', - dataViewTag$4 = '[object DataView]', - float32Tag$2 = '[object Float32Array]', - float64Tag$2 = '[object Float64Array]', - int8Tag$2 = '[object Int8Array]', - int16Tag$2 = '[object Int16Array]', - int32Tag$2 = '[object Int32Array]', - uint8Tag$2 = '[object Uint8Array]', - uint8ClampedTag$2 = '[object Uint8ClampedArray]', - uint16Tag$2 = '[object Uint16Array]', - uint32Tag$2 = '[object Uint32Array]'; - -/** Used to identify `toStringTag` values of typed arrays. */ -var typedArrayTags = {}; -typedArrayTags[float32Tag$2] = typedArrayTags[float64Tag$2] = -typedArrayTags[int8Tag$2] = typedArrayTags[int16Tag$2] = -typedArrayTags[int32Tag$2] = typedArrayTags[uint8Tag$2] = -typedArrayTags[uint8ClampedTag$2] = typedArrayTags[uint16Tag$2] = -typedArrayTags[uint32Tag$2] = true; -typedArrayTags[argsTag$2] = typedArrayTags[arrayTag$2] = -typedArrayTags[arrayBufferTag$3] = typedArrayTags[boolTag$3] = -typedArrayTags[dataViewTag$4] = typedArrayTags[dateTag$3] = -typedArrayTags[errorTag$2] = typedArrayTags[funcTag$1] = -typedArrayTags[mapTag$7] = typedArrayTags[numberTag$3] = -typedArrayTags[objectTag$3] = typedArrayTags[regexpTag$3] = -typedArrayTags[setTag$7] = typedArrayTags[stringTag$4] = -typedArrayTags[weakMapTag$2] = false; + format.toString = function() { + return specifier + ""; + }; -/** - * The base implementation of `_.isTypedArray` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - */ -function baseIsTypedArray(value) { - return isObjectLike_1(value) && - isLength_1(value.length) && !!typedArrayTags[_baseGetTag(value)]; -} + return format; + } -var _baseIsTypedArray = baseIsTypedArray; + function formatPrefix(specifier, value) { + var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)), + e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3, + k = Math.pow(10, -e), + prefix = prefixes[8 + e / 3]; + return function(value) { + return f(k * value) + prefix; + }; + } -/** - * The base implementation of `_.unary` without support for storing metadata. - * - * @private - * @param {Function} func The function to cap arguments for. - * @returns {Function} Returns the new capped function. - */ -function baseUnary(func) { - return function(value) { - return func(value); + return { + format: newFormat, + formatPrefix: formatPrefix }; } -var _baseUnary = baseUnary; - -var _nodeUtil = createCommonjsModule(function (module, exports) { -/** Detect free variable `exports`. */ -var freeExports = exports && !exports.nodeType && exports; - -/** Detect free variable `module`. */ -var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; - -/** Detect the popular CommonJS extension `module.exports`. */ -var moduleExports = freeModule && freeModule.exports === freeExports; - -/** Detect free variable `process` from Node.js. */ -var freeProcess = moduleExports && _freeGlobal.process; - -/** Used to access faster Node.js helpers. */ -var nodeUtil = (function() { - try { - // Use `util.types` for Node.js 10+. - var types = freeModule && freeModule.require && freeModule.require('util').types; - - if (types) { - return types; - } - - // Legacy `process.binding('util')` for Node.js < 10. - return freeProcess && freeProcess.binding && freeProcess.binding('util'); - } catch (e) {} -}()); +var locale; +var format; +var formatPrefix; -module.exports = nodeUtil; +defaultLocale({ + thousands: ",", + grouping: [3], + currency: ["$", ""] }); -/* Node.js helper references. */ -var nodeIsTypedArray = _nodeUtil && _nodeUtil.isTypedArray; - -/** - * Checks if `value` is classified as a typed array. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - * @example - * - * _.isTypedArray(new Uint8Array); - * // => true - * - * _.isTypedArray([]); - * // => false - */ -var isTypedArray = nodeIsTypedArray ? _baseUnary(nodeIsTypedArray) : _baseIsTypedArray; - -var isTypedArray_1 = isTypedArray; - -/** Used for built-in method references. */ -var objectProto$9 = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty$7 = objectProto$9.hasOwnProperty; - -/** - * Creates an array of the enumerable property names of the array-like `value`. - * - * @private - * @param {*} value The value to query. - * @param {boolean} inherited Specify returning inherited property names. - * @returns {Array} Returns the array of property names. - */ -function arrayLikeKeys(value, inherited) { - var isArr = isArray_1(value), - isArg = !isArr && isArguments_1(value), - isBuff = !isArr && !isArg && isBuffer_1(value), - isType = !isArr && !isArg && !isBuff && isTypedArray_1(value), - skipIndexes = isArr || isArg || isBuff || isType, - result = skipIndexes ? _baseTimes(value.length, String) : [], - length = result.length; - - for (var key in value) { - if ((inherited || hasOwnProperty$7.call(value, key)) && - !(skipIndexes && ( - // Safari 9 has enumerable `arguments.length` in strict mode. - key == 'length' || - // Node.js 0.10 has enumerable non-index properties on buffers. - (isBuff && (key == 'offset' || key == 'parent')) || - // PhantomJS 2 has enumerable non-index properties on typed arrays. - (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || - // Skip index properties. - _isIndex(key, length) - ))) { - result.push(key); - } - } - return result; +function defaultLocale(definition) { + locale = formatLocale(definition); + format = locale.format; + formatPrefix = locale.formatPrefix; + return locale; } -var _arrayLikeKeys = arrayLikeKeys; - -/** Used for built-in method references. */ -var objectProto$8 = Object.prototype; - -/** - * Checks if `value` is likely a prototype object. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. - */ -function isPrototype(value) { - var Ctor = value && value.constructor, - proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$8; - - return value === proto; +function precisionFixed(step) { + return Math.max(0, -exponent(Math.abs(step))); } -var _isPrototype = isPrototype; - -/** - * Creates a unary function that invokes `func` with its argument transformed. - * - * @private - * @param {Function} func The function to wrap. - * @param {Function} transform The argument transform. - * @returns {Function} Returns the new function. - */ -function overArg(func, transform) { - return function(arg) { - return func(transform(arg)); - }; +function precisionPrefix(step, value) { + return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step))); } -var _overArg = overArg; - -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeKeys = _overArg(Object.keys, Object); - -var _nativeKeys = nativeKeys; - -/** Used for built-in method references. */ -var objectProto$7 = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty$6 = objectProto$7.hasOwnProperty; - -/** - * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ -function baseKeys(object) { - if (!_isPrototype(object)) { - return _nativeKeys(object); - } - var result = []; - for (var key in Object(object)) { - if (hasOwnProperty$6.call(object, key) && key != 'constructor') { - result.push(key); - } - } - return result; +function precisionRound(step, max) { + step = Math.abs(step), max = Math.abs(max) - step; + return Math.max(0, exponent(max) - exponent(step)) + 1; } -var _baseKeys = baseKeys; - -/** - * Checks if `value` is array-like. A value is considered array-like if it's - * not a function and has a `value.length` that's an integer greater than or - * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - * @example - * - * _.isArrayLike([1, 2, 3]); - * // => true - * - * _.isArrayLike(document.body.children); - * // => true - * - * _.isArrayLike('abc'); - * // => true - * - * _.isArrayLike(_.noop); - * // => false - */ -function isArrayLike(value) { - return value != null && isLength_1(value.length) && !isFunction_1(value); +function defaultSeparation$1(a, b) { + return a.parent === b.parent ? 1 : 2; } -var isArrayLike_1 = isArrayLike; +function meanX(children) { + return children.reduce(meanXReduce, 0) / children.length; +} -/** - * Creates an array of the own enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. See the - * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * for more details. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keys(new Foo); - * // => ['a', 'b'] (iteration order is not guaranteed) - * - * _.keys('hi'); - * // => ['0', '1'] - */ -function keys(object) { - return isArrayLike_1(object) ? _arrayLikeKeys(object) : _baseKeys(object); +function meanXReduce(x, c) { + return x + c.x; } -var keys_1 = keys; +function maxY(children) { + return 1 + children.reduce(maxYReduce, 0); +} -/** - * The base implementation of `_.assign` without support for multiple sources - * or `customizer` functions. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @returns {Object} Returns `object`. - */ -function baseAssign(object, source) { - return object && _copyObject(source, keys_1(source), object); +function maxYReduce(y, c) { + return Math.max(y, c.y); } -var _baseAssign = baseAssign; +function leafLeft(node) { + var children; + while (children = node.children) node = children[0]; + return node; +} -/** - * This function is like - * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * except that it includes inherited enumerable properties. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ -function nativeKeysIn(object) { - var result = []; - if (object != null) { - for (var key in Object(object)) { - result.push(key); - } - } - return result; +function leafRight(node) { + var children; + while (children = node.children) node = children[children.length - 1]; + return node; } -var _nativeKeysIn = nativeKeysIn; +function cluster() { + var separation = defaultSeparation$1, + dx = 1, + dy = 1, + nodeSize = false; -/** Used for built-in method references. */ -var objectProto$6 = Object.prototype; + function cluster(root) { + var previousNode, + x = 0; -/** Used to check objects for own properties. */ -var hasOwnProperty$5 = objectProto$6.hasOwnProperty; + // First walk, computing the initial x & y values. + root.eachAfter(function(node) { + var children = node.children; + if (children) { + node.x = meanX(children); + node.y = maxY(children); + } else { + node.x = previousNode ? x += separation(node, previousNode) : 0; + node.y = 0; + previousNode = node; + } + }); -/** - * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ -function baseKeysIn(object) { - if (!isObject_1(object)) { - return _nativeKeysIn(object); - } - var isProto = _isPrototype(object), - result = []; + var left = leafLeft(root), + right = leafRight(root), + x0 = left.x - separation(left, right) / 2, + x1 = right.x + separation(right, left) / 2; - for (var key in object) { - if (!(key == 'constructor' && (isProto || !hasOwnProperty$5.call(object, key)))) { - result.push(key); - } + // Second walk, normalizing x & y to the desired size. + return root.eachAfter(nodeSize ? function(node) { + node.x = (node.x - root.x) * dx; + node.y = (root.y - node.y) * dy; + } : function(node) { + node.x = (node.x - x0) / (x1 - x0) * dx; + node.y = (1 - (root.y ? node.y / root.y : 1)) * dy; + }); } - return result; -} -var _baseKeysIn = baseKeysIn; + cluster.separation = function(x) { + return arguments.length ? (separation = x, cluster) : separation; + }; -/** - * Creates an array of the own and inherited enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keysIn(new Foo); - * // => ['a', 'b', 'c'] (iteration order is not guaranteed) - */ -function keysIn(object) { - return isArrayLike_1(object) ? _arrayLikeKeys(object, true) : _baseKeysIn(object); -} + cluster.size = function(x) { + return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? null : [dx, dy]); + }; -var keysIn_1 = keysIn; + cluster.nodeSize = function(x) { + return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? [dx, dy] : null); + }; -/** - * The base implementation of `_.assignIn` without support for multiple sources - * or `customizer` functions. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @returns {Object} Returns `object`. - */ -function baseAssignIn(object, source) { - return object && _copyObject(source, keysIn_1(source), object); + return cluster; } -var _baseAssignIn = baseAssignIn; - -var _cloneBuffer = createCommonjsModule(function (module, exports) { -/** Detect free variable `exports`. */ -var freeExports = exports && !exports.nodeType && exports; - -/** Detect free variable `module`. */ -var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; - -/** Detect the popular CommonJS extension `module.exports`. */ -var moduleExports = freeModule && freeModule.exports === freeExports; +function count(node) { + var sum = 0, + children = node.children, + i = children && children.length; + if (!i) sum = 1; + else while (--i >= 0) sum += children[i].value; + node.value = sum; +} -/** Built-in value references. */ -var Buffer = moduleExports ? _root.Buffer : undefined, - allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined; +function node_count() { + return this.eachAfter(count); +} -/** - * Creates a clone of `buffer`. - * - * @private - * @param {Buffer} buffer The buffer to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Buffer} Returns the cloned buffer. - */ -function cloneBuffer(buffer, isDeep) { - if (isDeep) { - return buffer.slice(); +function node_each(callback, that) { + let index = -1; + for (const node of this) { + callback.call(that, node, ++index, this); } - var length = buffer.length, - result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); - - buffer.copy(result); - return result; + return this; } -module.exports = cloneBuffer; -}); - -/** - * Copies the values of `source` to `array`. - * - * @private - * @param {Array} source The array to copy values from. - * @param {Array} [array=[]] The array to copy values to. - * @returns {Array} Returns `array`. - */ -function copyArray(source, array) { - var index = -1, - length = source.length; - - array || (array = Array(length)); - while (++index < length) { - array[index] = source[index]; +function node_eachBefore(callback, that) { + var node = this, nodes = [node], children, i, index = -1; + while (node = nodes.pop()) { + callback.call(that, node, ++index, this); + if (children = node.children) { + for (i = children.length - 1; i >= 0; --i) { + nodes.push(children[i]); + } + } } - return array; + return this; } -var _copyArray = copyArray; - -/** - * A specialized version of `_.filter` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ -function arrayFilter(array, predicate) { - var index = -1, - length = array == null ? 0 : array.length, - resIndex = 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result[resIndex++] = value; +function node_eachAfter(callback, that) { + var node = this, nodes = [node], next = [], children, i, n, index = -1; + while (node = nodes.pop()) { + next.push(node); + if (children = node.children) { + for (i = 0, n = children.length; i < n; ++i) { + nodes.push(children[i]); + } } } - return result; + while (node = next.pop()) { + callback.call(that, node, ++index, this); + } + return this; } -var _arrayFilter = arrayFilter; - -/** - * This method returns a new empty array. - * - * @static - * @memberOf _ - * @since 4.13.0 - * @category Util - * @returns {Array} Returns the new empty array. - * @example - * - * var arrays = _.times(2, _.stubArray); - * - * console.log(arrays); - * // => [[], []] - * - * console.log(arrays[0] === arrays[1]); - * // => false - */ -function stubArray() { - return []; +function node_find(callback, that) { + let index = -1; + for (const node of this) { + if (callback.call(that, node, ++index, this)) { + return node; + } + } } -var stubArray_1 = stubArray; - -/** Used for built-in method references. */ -var objectProto$5 = Object.prototype; - -/** Built-in value references. */ -var propertyIsEnumerable = objectProto$5.propertyIsEnumerable; - -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeGetSymbols$1 = Object.getOwnPropertySymbols; - -/** - * Creates an array of the own enumerable symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. - */ -var getSymbols = !nativeGetSymbols$1 ? stubArray_1 : function(object) { - if (object == null) { - return []; - } - object = Object(object); - return _arrayFilter(nativeGetSymbols$1(object), function(symbol) { - return propertyIsEnumerable.call(object, symbol); +function node_sum(value) { + return this.eachAfter(function(node) { + var sum = +value(node.data) || 0, + children = node.children, + i = children && children.length; + while (--i >= 0) sum += children[i].value; + node.value = sum; }); -}; - -var _getSymbols = getSymbols; +} -/** - * Copies own symbols of `source` to `object`. - * - * @private - * @param {Object} source The object to copy symbols from. - * @param {Object} [object={}] The object to copy symbols to. - * @returns {Object} Returns `object`. - */ -function copySymbols(source, object) { - return _copyObject(source, _getSymbols(source), object); +function node_sort(compare) { + return this.eachBefore(function(node) { + if (node.children) { + node.children.sort(compare); + } + }); } -var _copySymbols = copySymbols; - -/** - * Appends the elements of `values` to `array`. - * - * @private - * @param {Array} array The array to modify. - * @param {Array} values The values to append. - * @returns {Array} Returns `array`. - */ -function arrayPush(array, values) { - var index = -1, - length = values.length, - offset = array.length; - - while (++index < length) { - array[offset + index] = values[index]; +function node_path(end) { + var start = this, + ancestor = leastCommonAncestor(start, end), + nodes = [start]; + while (start !== ancestor) { + start = start.parent; + nodes.push(start); + } + var k = nodes.length; + while (end !== ancestor) { + nodes.splice(k, 0, end); + end = end.parent; } - return array; + return nodes; } -var _arrayPush = arrayPush; - -/** Built-in value references. */ -var getPrototype = _overArg(Object.getPrototypeOf, Object); - -var _getPrototype = getPrototype; - -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeGetSymbols = Object.getOwnPropertySymbols; - -/** - * Creates an array of the own and inherited enumerable symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. - */ -var getSymbolsIn = !nativeGetSymbols ? stubArray_1 : function(object) { - var result = []; - while (object) { - _arrayPush(result, _getSymbols(object)); - object = _getPrototype(object); +function leastCommonAncestor(a, b) { + if (a === b) return a; + var aNodes = a.ancestors(), + bNodes = b.ancestors(), + c = null; + a = aNodes.pop(); + b = bNodes.pop(); + while (a === b) { + c = a; + a = aNodes.pop(); + b = bNodes.pop(); } - return result; -}; - -var _getSymbolsIn = getSymbolsIn; - -/** - * Copies own and inherited symbols of `source` to `object`. - * - * @private - * @param {Object} source The object to copy symbols from. - * @param {Object} [object={}] The object to copy symbols to. - * @returns {Object} Returns `object`. - */ -function copySymbolsIn(source, object) { - return _copyObject(source, _getSymbolsIn(source), object); + return c; } -var _copySymbolsIn = copySymbolsIn; - -/** - * The base implementation of `getAllKeys` and `getAllKeysIn` which uses - * `keysFunc` and `symbolsFunc` to get the enumerable property names and - * symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Function} keysFunc The function to get the keys of `object`. - * @param {Function} symbolsFunc The function to get the symbols of `object`. - * @returns {Array} Returns the array of property names and symbols. - */ -function baseGetAllKeys(object, keysFunc, symbolsFunc) { - var result = keysFunc(object); - return isArray_1(object) ? result : _arrayPush(result, symbolsFunc(object)); +function node_ancestors() { + var node = this, nodes = [node]; + while (node = node.parent) { + nodes.push(node); + } + return nodes; } -var _baseGetAllKeys = baseGetAllKeys; - -/** - * Creates an array of own enumerable property names and symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names and symbols. - */ -function getAllKeys(object) { - return _baseGetAllKeys(object, keys_1, _getSymbols); +function node_descendants() { + return Array.from(this); } -var _getAllKeys = getAllKeys; - -/** - * Creates an array of own and inherited enumerable property names and - * symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names and symbols. - */ -function getAllKeysIn(object) { - return _baseGetAllKeys(object, keysIn_1, _getSymbolsIn); +function node_leaves() { + var leaves = []; + this.eachBefore(function(node) { + if (!node.children) { + leaves.push(node); + } + }); + return leaves; } -var _getAllKeysIn = getAllKeysIn; - -/* Built-in method references that are verified to be native. */ -var DataView$1 = _getNative(_root, 'DataView'); - -var _DataView = DataView$1; - -/* Built-in method references that are verified to be native. */ -var Promise$1 = _getNative(_root, 'Promise'); - -var _Promise = Promise$1; - -/* Built-in method references that are verified to be native. */ -var Set$1 = _getNative(_root, 'Set'); - -var _Set = Set$1; - -/* Built-in method references that are verified to be native. */ -var WeakMap = _getNative(_root, 'WeakMap'); - -var _WeakMap = WeakMap; - -/** `Object#toString` result references. */ -var mapTag$6 = '[object Map]', - objectTag$2 = '[object Object]', - promiseTag = '[object Promise]', - setTag$6 = '[object Set]', - weakMapTag$1 = '[object WeakMap]'; - -var dataViewTag$3 = '[object DataView]'; - -/** Used to detect maps, sets, and weakmaps. */ -var dataViewCtorString = _toSource(_DataView), - mapCtorString = _toSource(_Map), - promiseCtorString = _toSource(_Promise), - setCtorString = _toSource(_Set), - weakMapCtorString = _toSource(_WeakMap); +function node_links() { + var root = this, links = []; + root.each(function(node) { + if (node !== root) { // Don’t include the root’s parent, if any. + links.push({source: node.parent, target: node}); + } + }); + return links; +} -/** - * Gets the `toStringTag` of `value`. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ -var getTag = _baseGetTag; - -// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. -if ((_DataView && getTag(new _DataView(new ArrayBuffer(1))) != dataViewTag$3) || - (_Map && getTag(new _Map) != mapTag$6) || - (_Promise && getTag(_Promise.resolve()) != promiseTag) || - (_Set && getTag(new _Set) != setTag$6) || - (_WeakMap && getTag(new _WeakMap) != weakMapTag$1)) { - getTag = function(value) { - var result = _baseGetTag(value), - Ctor = result == objectTag$2 ? value.constructor : undefined, - ctorString = Ctor ? _toSource(Ctor) : ''; - - if (ctorString) { - switch (ctorString) { - case dataViewCtorString: return dataViewTag$3; - case mapCtorString: return mapTag$6; - case promiseCtorString: return promiseTag; - case setCtorString: return setTag$6; - case weakMapCtorString: return weakMapTag$1; +function* node_iterator() { + var node = this, current, next = [node], children, i, n; + do { + current = next.reverse(), next = []; + while (node = current.pop()) { + yield node; + if (children = node.children) { + for (i = 0, n = children.length; i < n; ++i) { + next.push(children[i]); + } } } - return result; - }; + } while (next.length); } -var _getTag = getTag; - -/** Used for built-in method references. */ -var objectProto$4 = Object.prototype; - -/** Used to check objects for own properties. */ -var hasOwnProperty$4 = objectProto$4.hasOwnProperty; - -/** - * Initializes an array clone. - * - * @private - * @param {Array} array The array to clone. - * @returns {Array} Returns the initialized clone. - */ -function initCloneArray(array) { - var length = array.length, - result = new array.constructor(length); - - // Add properties assigned by `RegExp#exec`. - if (length && typeof array[0] == 'string' && hasOwnProperty$4.call(array, 'index')) { - result.index = array.index; - result.input = array.input; +function hierarchy(data, children) { + if (data instanceof Map) { + data = [undefined, data]; + if (children === undefined) children = mapChildren; + } else if (children === undefined) { + children = objectChildren; } - return result; -} -var _initCloneArray = initCloneArray; - -/** Built-in value references. */ -var Uint8Array = _root.Uint8Array; + var root = new Node(data), + node, + nodes = [root], + child, + childs, + i, + n; -var _Uint8Array = Uint8Array; + while (node = nodes.pop()) { + if ((childs = children(node.data)) && (n = (childs = Array.from(childs)).length)) { + node.children = childs; + for (i = n - 1; i >= 0; --i) { + nodes.push(child = childs[i] = new Node(childs[i])); + child.parent = node; + child.depth = node.depth + 1; + } + } + } -/** - * Creates a clone of `arrayBuffer`. - * - * @private - * @param {ArrayBuffer} arrayBuffer The array buffer to clone. - * @returns {ArrayBuffer} Returns the cloned array buffer. - */ -function cloneArrayBuffer(arrayBuffer) { - var result = new arrayBuffer.constructor(arrayBuffer.byteLength); - new _Uint8Array(result).set(new _Uint8Array(arrayBuffer)); - return result; + return root.eachBefore(computeHeight); } -var _cloneArrayBuffer = cloneArrayBuffer; - -/** - * Creates a clone of `dataView`. - * - * @private - * @param {Object} dataView The data view to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned data view. - */ -function cloneDataView(dataView, isDeep) { - var buffer = isDeep ? _cloneArrayBuffer(dataView.buffer) : dataView.buffer; - return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +function node_copy() { + return hierarchy(this).eachBefore(copyData); } -var _cloneDataView = cloneDataView; - -/** Used to match `RegExp` flags from their coerced string values. */ -var reFlags = /\w*$/; - -/** - * Creates a clone of `regexp`. - * - * @private - * @param {Object} regexp The regexp to clone. - * @returns {Object} Returns the cloned regexp. - */ -function cloneRegExp(regexp) { - var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); - result.lastIndex = regexp.lastIndex; - return result; +function objectChildren(d) { + return d.children; } -var _cloneRegExp = cloneRegExp; - -/** Used to convert symbols to primitives and strings. */ -var symbolProto$2 = _Symbol ? _Symbol.prototype : undefined, - symbolValueOf$1 = symbolProto$2 ? symbolProto$2.valueOf : undefined; - -/** - * Creates a clone of the `symbol` object. - * - * @private - * @param {Object} symbol The symbol object to clone. - * @returns {Object} Returns the cloned symbol object. - */ -function cloneSymbol(symbol) { - return symbolValueOf$1 ? Object(symbolValueOf$1.call(symbol)) : {}; +function mapChildren(d) { + return Array.isArray(d) ? d[1] : null; } -var _cloneSymbol = cloneSymbol; - -/** - * Creates a clone of `typedArray`. - * - * @private - * @param {Object} typedArray The typed array to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned typed array. - */ -function cloneTypedArray(typedArray, isDeep) { - var buffer = isDeep ? _cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; - return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); -} - -var _cloneTypedArray = cloneTypedArray; - -/** `Object#toString` result references. */ -var boolTag$2 = '[object Boolean]', - dateTag$2 = '[object Date]', - mapTag$5 = '[object Map]', - numberTag$2 = '[object Number]', - regexpTag$2 = '[object RegExp]', - setTag$5 = '[object Set]', - stringTag$3 = '[object String]', - symbolTag$3 = '[object Symbol]'; - -var arrayBufferTag$2 = '[object ArrayBuffer]', - dataViewTag$2 = '[object DataView]', - float32Tag$1 = '[object Float32Array]', - float64Tag$1 = '[object Float64Array]', - int8Tag$1 = '[object Int8Array]', - int16Tag$1 = '[object Int16Array]', - int32Tag$1 = '[object Int32Array]', - uint8Tag$1 = '[object Uint8Array]', - uint8ClampedTag$1 = '[object Uint8ClampedArray]', - uint16Tag$1 = '[object Uint16Array]', - uint32Tag$1 = '[object Uint32Array]'; - -/** - * Initializes an object clone based on its `toStringTag`. - * - * **Note:** This function only supports cloning values with tags of - * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. - * - * @private - * @param {Object} object The object to clone. - * @param {string} tag The `toStringTag` of the object to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the initialized clone. - */ -function initCloneByTag(object, tag, isDeep) { - var Ctor = object.constructor; - switch (tag) { - case arrayBufferTag$2: - return _cloneArrayBuffer(object); - - case boolTag$2: - case dateTag$2: - return new Ctor(+object); - - case dataViewTag$2: - return _cloneDataView(object, isDeep); - - case float32Tag$1: case float64Tag$1: - case int8Tag$1: case int16Tag$1: case int32Tag$1: - case uint8Tag$1: case uint8ClampedTag$1: case uint16Tag$1: case uint32Tag$1: - return _cloneTypedArray(object, isDeep); - - case mapTag$5: - return new Ctor; +function copyData(node) { + if (node.data.value !== undefined) node.value = node.data.value; + node.data = node.data.data; +} - case numberTag$2: - case stringTag$3: - return new Ctor(object); +function computeHeight(node) { + var height = 0; + do node.height = height; + while ((node = node.parent) && (node.height < ++height)); +} - case regexpTag$2: - return _cloneRegExp(object); +function Node(data) { + this.data = data; + this.depth = + this.height = 0; + this.parent = null; +} - case setTag$5: - return new Ctor; +Node.prototype = hierarchy.prototype = { + constructor: Node, + count: node_count, + each: node_each, + eachAfter: node_eachAfter, + eachBefore: node_eachBefore, + find: node_find, + sum: node_sum, + sort: node_sort, + path: node_path, + ancestors: node_ancestors, + descendants: node_descendants, + leaves: node_leaves, + links: node_links, + copy: node_copy, + [Symbol.iterator]: node_iterator +}; - case symbolTag$3: - return _cloneSymbol(object); - } +function required(f) { + if (typeof f !== "function") throw new Error; + return f; } -var _initCloneByTag = initCloneByTag; - -/** Built-in value references. */ -var objectCreate = Object.create; +function constantZero() { + return 0; +} -/** - * The base implementation of `_.create` without support for assigning - * properties to the created object. - * - * @private - * @param {Object} proto The object to inherit from. - * @returns {Object} Returns the new object. - */ -var baseCreate = (function() { - function object() {} - return function(proto) { - if (!isObject_1(proto)) { - return {}; - } - if (objectCreate) { - return objectCreate(proto); - } - object.prototype = proto; - var result = new object; - object.prototype = undefined; - return result; +function constant$2(x) { + return function() { + return x; }; -}()); - -var _baseCreate = baseCreate; - -/** - * Initializes an object clone. - * - * @private - * @param {Object} object The object to clone. - * @returns {Object} Returns the initialized clone. - */ -function initCloneObject(object) { - return (typeof object.constructor == 'function' && !_isPrototype(object)) - ? _baseCreate(_getPrototype(object)) - : {}; } -var _initCloneObject = initCloneObject; - -/** `Object#toString` result references. */ -var mapTag$4 = '[object Map]'; - -/** - * The base implementation of `_.isMap` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a map, else `false`. - */ -function baseIsMap(value) { - return isObjectLike_1(value) && _getTag(value) == mapTag$4; +function roundNode(node) { + node.x0 = Math.round(node.x0); + node.y0 = Math.round(node.y0); + node.x1 = Math.round(node.x1); + node.y1 = Math.round(node.y1); } -var _baseIsMap = baseIsMap; - -/* Node.js helper references. */ -var nodeIsMap = _nodeUtil && _nodeUtil.isMap; - -/** - * Checks if `value` is classified as a `Map` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a map, else `false`. - * @example - * - * _.isMap(new Map); - * // => true - * - * _.isMap(new WeakMap); - * // => false - */ -var isMap = nodeIsMap ? _baseUnary(nodeIsMap) : _baseIsMap; - -var isMap_1 = isMap; - -/** `Object#toString` result references. */ -var setTag$4 = '[object Set]'; +function treemapDice(parent, x0, y0, x1, y1) { + var nodes = parent.children, + node, + i = -1, + n = nodes.length, + k = parent.value && (x1 - x0) / parent.value; -/** - * The base implementation of `_.isSet` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a set, else `false`. - */ -function baseIsSet(value) { - return isObjectLike_1(value) && _getTag(value) == setTag$4; + while (++i < n) { + node = nodes[i], node.y0 = y0, node.y1 = y1; + node.x0 = x0, node.x1 = x0 += node.value * k; + } } -var _baseIsSet = baseIsSet; - -/* Node.js helper references. */ -var nodeIsSet = _nodeUtil && _nodeUtil.isSet; - -/** - * Checks if `value` is classified as a `Set` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a set, else `false`. - * @example - * - * _.isSet(new Set); - * // => true - * - * _.isSet(new WeakSet); - * // => false - */ -var isSet = nodeIsSet ? _baseUnary(nodeIsSet) : _baseIsSet; - -var isSet_1 = isSet; - -/** Used to compose bitmasks for cloning. */ -var CLONE_DEEP_FLAG = 1, - CLONE_FLAT_FLAG = 2, - CLONE_SYMBOLS_FLAG$1 = 4; - -/** `Object#toString` result references. */ -var argsTag$1 = '[object Arguments]', - arrayTag$1 = '[object Array]', - boolTag$1 = '[object Boolean]', - dateTag$1 = '[object Date]', - errorTag$1 = '[object Error]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - mapTag$3 = '[object Map]', - numberTag$1 = '[object Number]', - objectTag$1 = '[object Object]', - regexpTag$1 = '[object RegExp]', - setTag$3 = '[object Set]', - stringTag$2 = '[object String]', - symbolTag$2 = '[object Symbol]', - weakMapTag = '[object WeakMap]'; - -var arrayBufferTag$1 = '[object ArrayBuffer]', - dataViewTag$1 = '[object DataView]', - float32Tag = '[object Float32Array]', - float64Tag = '[object Float64Array]', - int8Tag = '[object Int8Array]', - int16Tag = '[object Int16Array]', - int32Tag = '[object Int32Array]', - uint8Tag = '[object Uint8Array]', - uint8ClampedTag = '[object Uint8ClampedArray]', - uint16Tag = '[object Uint16Array]', - uint32Tag = '[object Uint32Array]'; - -/** Used to identify `toStringTag` values supported by `_.clone`. */ -var cloneableTags = {}; -cloneableTags[argsTag$1] = cloneableTags[arrayTag$1] = -cloneableTags[arrayBufferTag$1] = cloneableTags[dataViewTag$1] = -cloneableTags[boolTag$1] = cloneableTags[dateTag$1] = -cloneableTags[float32Tag] = cloneableTags[float64Tag] = -cloneableTags[int8Tag] = cloneableTags[int16Tag] = -cloneableTags[int32Tag] = cloneableTags[mapTag$3] = -cloneableTags[numberTag$1] = cloneableTags[objectTag$1] = -cloneableTags[regexpTag$1] = cloneableTags[setTag$3] = -cloneableTags[stringTag$2] = cloneableTags[symbolTag$2] = -cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = -cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; -cloneableTags[errorTag$1] = cloneableTags[funcTag] = -cloneableTags[weakMapTag] = false; +function partition() { + var dx = 1, + dy = 1, + padding = 0, + round = false; -/** - * The base implementation of `_.clone` and `_.cloneDeep` which tracks - * traversed objects. - * - * @private - * @param {*} value The value to clone. - * @param {boolean} bitmask The bitmask flags. - * 1 - Deep clone - * 2 - Flatten inherited properties - * 4 - Clone symbols - * @param {Function} [customizer] The function to customize cloning. - * @param {string} [key] The key of `value`. - * @param {Object} [object] The parent object of `value`. - * @param {Object} [stack] Tracks traversed objects and their clone counterparts. - * @returns {*} Returns the cloned value. - */ -function baseClone(value, bitmask, customizer, key, object, stack) { - var result, - isDeep = bitmask & CLONE_DEEP_FLAG, - isFlat = bitmask & CLONE_FLAT_FLAG, - isFull = bitmask & CLONE_SYMBOLS_FLAG$1; - - if (customizer) { - result = object ? customizer(value, key, object, stack) : customizer(value); - } - if (result !== undefined) { - return result; - } - if (!isObject_1(value)) { - return value; + function partition(root) { + var n = root.height + 1; + root.x0 = + root.y0 = padding; + root.x1 = dx; + root.y1 = dy / n; + root.eachBefore(positionNode(dy, n)); + if (round) root.eachBefore(roundNode); + return root; } - var isArr = isArray_1(value); - if (isArr) { - result = _initCloneArray(value); - if (!isDeep) { - return _copyArray(value, result); - } - } else { - var tag = _getTag(value), - isFunc = tag == funcTag || tag == genTag; - if (isBuffer_1(value)) { - return _cloneBuffer(value, isDeep); - } - if (tag == objectTag$1 || tag == argsTag$1 || (isFunc && !object)) { - result = (isFlat || isFunc) ? {} : _initCloneObject(value); - if (!isDeep) { - return isFlat - ? _copySymbolsIn(value, _baseAssignIn(result, value)) - : _copySymbols(value, _baseAssign(result, value)); - } - } else { - if (!cloneableTags[tag]) { - return object ? value : {}; + function positionNode(dy, n) { + return function(node) { + if (node.children) { + treemapDice(node, node.x0, dy * (node.depth + 1) / n, node.x1, dy * (node.depth + 2) / n); } - result = _initCloneByTag(value, tag, isDeep); - } - } - // Check for circular references and return its corresponding clone. - stack || (stack = new _Stack); - var stacked = stack.get(value); - if (stacked) { - return stacked; - } - stack.set(value, result); - - if (isSet_1(value)) { - value.forEach(function(subValue) { - result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); - }); - } else if (isMap_1(value)) { - value.forEach(function(subValue, key) { - result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); - }); + var x0 = node.x0, + y0 = node.y0, + x1 = node.x1 - padding, + y1 = node.y1 - padding; + if (x1 < x0) x0 = x1 = (x0 + x1) / 2; + if (y1 < y0) y0 = y1 = (y0 + y1) / 2; + node.x0 = x0; + node.y0 = y0; + node.x1 = x1; + node.y1 = y1; + }; } - var keysFunc = isFull - ? (isFlat ? _getAllKeysIn : _getAllKeys) - : (isFlat ? keysIn_1 : keys_1); - - var props = isArr ? undefined : keysFunc(value); - _arrayEach(props || value, function(subValue, key) { - if (props) { - key = subValue; - subValue = value[key]; - } - // Recursively populate clone (susceptible to call stack limits). - _assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); - }); - return result; -} + partition.round = function(x) { + return arguments.length ? (round = !!x, partition) : round; + }; -var _baseClone = baseClone; + partition.size = function(x) { + return arguments.length ? (dx = +x[0], dy = +x[1], partition) : [dx, dy]; + }; -/** Used to compose bitmasks for cloning. */ -var CLONE_SYMBOLS_FLAG = 4; + partition.padding = function(x) { + return arguments.length ? (padding = +x, partition) : padding; + }; -/** - * Creates a shallow clone of `value`. - * - * **Note:** This method is loosely based on the - * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) - * and supports cloning arrays, array buffers, booleans, date objects, maps, - * numbers, `Object` objects, regexes, sets, strings, symbols, and typed - * arrays. The own enumerable properties of `arguments` objects are cloned - * as plain objects. An empty object is returned for uncloneable values such - * as error objects, functions, DOM nodes, and WeakMaps. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to clone. - * @returns {*} Returns the cloned value. - * @see _.cloneDeep - * @example - * - * var objects = [{ 'a': 1 }, { 'b': 2 }]; - * - * var shallow = _.clone(objects); - * console.log(shallow[0] === objects[0]); - * // => true - */ -function clone(value) { - return _baseClone(value, CLONE_SYMBOLS_FLAG); + return partition; } -var clone_1 = clone; +var preroot = {depth: -1}, + ambiguous = {}; -/** - * Creates a function that returns `value`. - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Util - * @param {*} value The value to return from the new function. - * @returns {Function} Returns the new constant function. - * @example - * - * var objects = _.times(2, _.constant({ 'a': 1 })); - * - * console.log(objects); - * // => [{ 'a': 1 }, { 'a': 1 }] - * - * console.log(objects[0] === objects[1]); - * // => true - */ -function constant(value) { - return function() { - return value; - }; +function defaultId(d) { + return d.id; } -var constant_1 = constant; - -/** - * Creates a base function for methods like `_.forIn` and `_.forOwn`. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. - */ -function createBaseFor(fromRight) { - return function(object, iteratee, keysFunc) { - var index = -1, - iterable = Object(object), - props = keysFunc(object), - length = props.length; - - while (length--) { - var key = props[fromRight ? length : ++index]; - if (iteratee(iterable[key], key, iterable) === false) { - break; - } - } - return object; - }; +function defaultParentId(d) { + return d.parentId; } -var _createBaseFor = createBaseFor; - -/** - * The base implementation of `baseForOwn` which iterates over `object` - * properties returned by `keysFunc` and invokes `iteratee` for each property. - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} keysFunc The function to get the keys of `object`. - * @returns {Object} Returns `object`. - */ -var baseFor = _createBaseFor(); - -var _baseFor = baseFor; - -/** - * The base implementation of `_.forOwn` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. - */ -function baseForOwn(object, iteratee) { - return object && _baseFor(object, iteratee, keys_1); -} +function stratify() { + var id = defaultId, + parentId = defaultParentId; -var _baseForOwn = baseForOwn; + function stratify(data) { + var nodes = Array.from(data), + n = nodes.length, + d, + i, + root, + parent, + node, + nodeId, + nodeKey, + nodeByKey = new Map; -/** - * Creates a `baseEach` or `baseEachRight` function. - * - * @private - * @param {Function} eachFunc The function to iterate over a collection. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. - */ -function createBaseEach(eachFunc, fromRight) { - return function(collection, iteratee) { - if (collection == null) { - return collection; - } - if (!isArrayLike_1(collection)) { - return eachFunc(collection, iteratee); + for (i = 0; i < n; ++i) { + d = nodes[i], node = nodes[i] = new Node(d); + if ((nodeId = id(d, i, data)) != null && (nodeId += "")) { + nodeKey = node.id = nodeId; + nodeByKey.set(nodeKey, nodeByKey.has(nodeKey) ? ambiguous : node); + } + if ((nodeId = parentId(d, i, data)) != null && (nodeId += "")) { + node.parent = nodeId; + } } - var length = collection.length, - index = fromRight ? length : -1, - iterable = Object(collection); - while ((fromRight ? index-- : ++index < length)) { - if (iteratee(iterable[index], index, iterable) === false) { - break; + for (i = 0; i < n; ++i) { + node = nodes[i]; + if (nodeId = node.parent) { + parent = nodeByKey.get(nodeId); + if (!parent) throw new Error("missing: " + nodeId); + if (parent === ambiguous) throw new Error("ambiguous: " + nodeId); + if (parent.children) parent.children.push(node); + else parent.children = [node]; + node.parent = parent; + } else { + if (root) throw new Error("multiple roots"); + root = node; } } - return collection; - }; -} - -var _createBaseEach = createBaseEach; -/** - * The base implementation of `_.forEach` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array|Object} Returns `collection`. - */ -var baseEach = _createBaseEach(_baseForOwn); + if (!root) throw new Error("no root"); + root.parent = preroot; + root.eachBefore(function(node) { node.depth = node.parent.depth + 1; --n; }).eachBefore(computeHeight); + root.parent = null; + if (n > 0) throw new Error("cycle"); -var _baseEach = baseEach; + return root; + } -/** - * This method returns the first argument it receives. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Util - * @param {*} value Any value. - * @returns {*} Returns `value`. - * @example - * - * var object = { 'a': 1 }; - * - * console.log(_.identity(object) === object); - * // => true - */ -function identity(value) { - return value; -} + stratify.id = function(x) { + return arguments.length ? (id = required(x), stratify) : id; + }; -var identity_1 = identity; + stratify.parentId = function(x) { + return arguments.length ? (parentId = required(x), stratify) : parentId; + }; -/** - * Casts `value` to `identity` if it's not a function. - * - * @private - * @param {*} value The value to inspect. - * @returns {Function} Returns cast function. - */ -function castFunction(value) { - return typeof value == 'function' ? value : identity_1; + return stratify; } -var _castFunction = castFunction; - -/** - * Iterates over elements of `collection` and invokes `iteratee` for each element. - * The iteratee is invoked with three arguments: (value, index|key, collection). - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * **Note:** As with other "Collections" methods, objects with a "length" - * property are iterated like arrays. To avoid this behavior use `_.forIn` - * or `_.forOwn` for object iteration. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @alias each - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Array|Object} Returns `collection`. - * @see _.forEachRight - * @example - * - * _.forEach([1, 2], function(value) { - * console.log(value); - * }); - * // => Logs `1` then `2`. - * - * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { - * console.log(key); - * }); - * // => Logs 'a' then 'b' (iteration order is not guaranteed). - */ -function forEach(collection, iteratee) { - var func = isArray_1(collection) ? _arrayEach : _baseEach; - return func(collection, _castFunction(iteratee)); +function defaultSeparation(a, b) { + return a.parent === b.parent ? 1 : 2; } -var forEach_1 = forEach; - -var each = forEach_1; +// function radialSeparation(a, b) { +// return (a.parent === b.parent ? 1 : 2) / a.depth; +// } -/** - * The base implementation of `_.filter` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ -function baseFilter(collection, predicate) { - var result = []; - _baseEach(collection, function(value, index, collection) { - if (predicate(value, index, collection)) { - result.push(value); - } - }); - return result; +// This function is used to traverse the left contour of a subtree (or +// subforest). It returns the successor of v on this contour. This successor is +// either given by the leftmost child of v or by the thread of v. The function +// returns null if and only if v is on the highest level of its subtree. +function nextLeft(v) { + var children = v.children; + return children ? children[0] : v.t; } -var _baseFilter = baseFilter; - -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; - -/** - * Adds `value` to the array cache. - * - * @private - * @name add - * @memberOf SetCache - * @alias push - * @param {*} value The value to cache. - * @returns {Object} Returns the cache instance. - */ -function setCacheAdd(value) { - this.__data__.set(value, HASH_UNDEFINED); - return this; +// This function works analogously to nextLeft. +function nextRight(v) { + var children = v.children; + return children ? children[children.length - 1] : v.t; } -var _setCacheAdd = setCacheAdd; - -/** - * Checks if `value` is in the array cache. - * - * @private - * @name has - * @memberOf SetCache - * @param {*} value The value to search for. - * @returns {number} Returns `true` if `value` is found, else `false`. - */ -function setCacheHas(value) { - return this.__data__.has(value); +// Shifts the current subtree rooted at w+. This is done by increasing +// prelim(w+) and mod(w+) by shift. +function moveSubtree(wm, wp, shift) { + var change = shift / (wp.i - wm.i); + wp.c -= change; + wp.s += shift; + wm.c += change; + wp.z += shift; + wp.m += shift; } -var _setCacheHas = setCacheHas; - -/** - * - * Creates an array cache object to store unique values. - * - * @private - * @constructor - * @param {Array} [values] The values to cache. - */ -function SetCache(values) { - var index = -1, - length = values == null ? 0 : values.length; - - this.__data__ = new _MapCache; - while (++index < length) { - this.add(values[index]); +// All other shifts, applied to the smaller subtrees between w- and w+, are +// performed by this function. To prepare the shifts, we have to adjust +// change(w+), shift(w+), and change(w-). +function executeShifts(v) { + var shift = 0, + change = 0, + children = v.children, + i = children.length, + w; + while (--i >= 0) { + w = children[i]; + w.z += shift; + w.m += shift; + shift += w.s + (change += w.c); } } -// Add methods to `SetCache`. -SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd; -SetCache.prototype.has = _setCacheHas; +// If vi-’s ancestor is a sibling of v, returns vi-’s ancestor. Otherwise, +// returns the specified (default) ancestor. +function nextAncestor(vim, v, ancestor) { + return vim.a.parent === v.parent ? vim.a : ancestor; +} + +function TreeNode(node, i) { + this._ = node; + this.parent = null; + this.children = null; + this.A = null; // default ancestor + this.a = this; // ancestor + this.z = 0; // prelim + this.m = 0; // mod + this.c = 0; // change + this.s = 0; // shift + this.t = null; // thread + this.i = i; // number +} -var _SetCache = SetCache; +TreeNode.prototype = Object.create(Node.prototype); -/** - * A specialized version of `_.some` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - */ -function arraySome(array, predicate) { - var index = -1, - length = array == null ? 0 : array.length; +function treeRoot(root) { + var tree = new TreeNode(root, 0), + node, + nodes = [tree], + child, + children, + i, + n; - while (++index < length) { - if (predicate(array[index], index, array)) { - return true; + while (node = nodes.pop()) { + if (children = node._.children) { + node.children = new Array(n = children.length); + for (i = n - 1; i >= 0; --i) { + nodes.push(child = node.children[i] = new TreeNode(children[i], i)); + child.parent = node; + } } } - return false; -} - -var _arraySome = arraySome; -/** - * Checks if a `cache` value for `key` exists. - * - * @private - * @param {Object} cache The cache to query. - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function cacheHas(cache, key) { - return cache.has(key); + (tree.parent = new TreeNode(null, 0)).children = [tree]; + return tree; } -var _cacheHas = cacheHas; +// Node-link tree diagram using the Reingold-Tilford "tidy" algorithm +function tree() { + var separation = defaultSeparation, + dx = 1, + dy = 1, + nodeSize = null; -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG$5 = 1, - COMPARE_UNORDERED_FLAG$3 = 2; + function tree(root) { + var t = treeRoot(root); -/** - * A specialized version of `baseIsEqualDeep` for arrays with support for - * partial deep comparisons. - * - * @private - * @param {Array} array The array to compare. - * @param {Array} other The other array to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `array` and `other` objects. - * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. - */ -function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG$5, - arrLength = array.length, - othLength = other.length; + // Compute the layout using Buchheim et al.’s algorithm. + t.eachAfter(firstWalk), t.parent.m = -t.z; + t.eachBefore(secondWalk); - if (arrLength != othLength && !(isPartial && othLength > arrLength)) { - return false; - } - // Check that cyclic values are equal. - var arrStacked = stack.get(array); - var othStacked = stack.get(other); - if (arrStacked && othStacked) { - return arrStacked == other && othStacked == array; - } - var index = -1, - result = true, - seen = (bitmask & COMPARE_UNORDERED_FLAG$3) ? new _SetCache : undefined; + // If a fixed node size is specified, scale x and y. + if (nodeSize) root.eachBefore(sizeNode); - stack.set(array, other); - stack.set(other, array); + // If a fixed tree size is specified, scale x and y based on the extent. + // Compute the left-most, right-most, and depth-most nodes for extents. + else { + var left = root, + right = root, + bottom = root; + root.eachBefore(function(node) { + if (node.x < left.x) left = node; + if (node.x > right.x) right = node; + if (node.depth > bottom.depth) bottom = node; + }); + var s = left === right ? 1 : separation(left, right) / 2, + tx = s - left.x, + kx = dx / (right.x + s + tx), + ky = dy / (bottom.depth || 1); + root.eachBefore(function(node) { + node.x = (node.x + tx) * kx; + node.y = node.depth * ky; + }); + } - // Ignore non-index properties. - while (++index < arrLength) { - var arrValue = array[index], - othValue = other[index]; + return root; + } - if (customizer) { - var compared = isPartial - ? customizer(othValue, arrValue, index, other, array, stack) - : customizer(arrValue, othValue, index, array, other, stack); - } - if (compared !== undefined) { - if (compared) { - continue; + // Computes a preliminary x-coordinate for v. Before that, FIRST WALK is + // applied recursively to the children of v, as well as the function + // APPORTION. After spacing out the children by calling EXECUTE SHIFTS, the + // node v is placed to the midpoint of its outermost children. + function firstWalk(v) { + var children = v.children, + siblings = v.parent.children, + w = v.i ? siblings[v.i - 1] : null; + if (children) { + executeShifts(v); + var midpoint = (children[0].z + children[children.length - 1].z) / 2; + if (w) { + v.z = w.z + separation(v._, w._); + v.m = v.z - midpoint; + } else { + v.z = midpoint; } - result = false; - break; + } else if (w) { + v.z = w.z + separation(v._, w._); } - // Recursively compare arrays (susceptible to call stack limits). - if (seen) { - if (!_arraySome(other, function(othValue, othIndex) { - if (!_cacheHas(seen, othIndex) && - (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { - return seen.push(othIndex); - } - })) { - result = false; - break; + v.parent.A = apportion(v, w, v.parent.A || siblings[0]); + } + + // Computes all real x-coordinates by summing up the modifiers recursively. + function secondWalk(v) { + v._.x = v.z + v.parent.m; + v.m += v.parent.m; + } + + // The core of the algorithm. Here, a new subtree is combined with the + // previous subtrees. Threads are used to traverse the inside and outside + // contours of the left and right subtree up to the highest common level. The + // vertices used for the traversals are vi+, vi-, vo-, and vo+, where the + // superscript o means outside and i means inside, the subscript - means left + // subtree and + means right subtree. For summing up the modifiers along the + // contour, we use respective variables si+, si-, so-, and so+. Whenever two + // nodes of the inside contours conflict, we compute the left one of the + // greatest uncommon ancestors using the function ANCESTOR and call MOVE + // SUBTREE to shift the subtree and prepare the shifts of smaller subtrees. + // Finally, we add a new thread (if necessary). + function apportion(v, w, ancestor) { + if (w) { + var vip = v, + vop = v, + vim = w, + vom = vip.parent.children[0], + sip = vip.m, + sop = vop.m, + sim = vim.m, + som = vom.m, + shift; + while (vim = nextRight(vim), vip = nextLeft(vip), vim && vip) { + vom = nextLeft(vom); + vop = nextRight(vop); + vop.a = v; + shift = vim.z + sim - vip.z - sip + separation(vim._, vip._); + if (shift > 0) { + moveSubtree(nextAncestor(vim, v, ancestor), v, shift); + sip += shift; + sop += shift; + } + sim += vim.m; + sip += vip.m; + som += vom.m; + sop += vop.m; + } + if (vim && !nextRight(vop)) { + vop.t = vim; + vop.m += sim - sop; + } + if (vip && !nextLeft(vom)) { + vom.t = vip; + vom.m += sip - som; + ancestor = v; } - } else if (!( - arrValue === othValue || - equalFunc(arrValue, othValue, bitmask, customizer, stack) - )) { - result = false; - break; } + return ancestor; } - stack['delete'](array); - stack['delete'](other); - return result; -} -var _equalArrays = equalArrays; - -/** - * Converts `map` to its key-value pairs. - * - * @private - * @param {Object} map The map to convert. - * @returns {Array} Returns the key-value pairs. - */ -function mapToArray(map) { - var index = -1, - result = Array(map.size); + function sizeNode(node) { + node.x *= dx; + node.y = node.depth * dy; + } - map.forEach(function(value, key) { - result[++index] = [key, value]; - }); - return result; -} + tree.separation = function(x) { + return arguments.length ? (separation = x, tree) : separation; + }; -var _mapToArray = mapToArray; + tree.size = function(x) { + return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], tree) : (nodeSize ? null : [dx, dy]); + }; -/** - * Converts `set` to an array of its values. - * - * @private - * @param {Object} set The set to convert. - * @returns {Array} Returns the values. - */ -function setToArray(set) { - var index = -1, - result = Array(set.size); + tree.nodeSize = function(x) { + return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], tree) : (nodeSize ? [dx, dy] : null); + }; - set.forEach(function(value) { - result[++index] = value; - }); - return result; + return tree; } -var _setToArray = setToArray; - -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG$4 = 1, - COMPARE_UNORDERED_FLAG$2 = 2; - -/** `Object#toString` result references. */ -var boolTag = '[object Boolean]', - dateTag = '[object Date]', - errorTag = '[object Error]', - mapTag$2 = '[object Map]', - numberTag = '[object Number]', - regexpTag = '[object RegExp]', - setTag$2 = '[object Set]', - stringTag$1 = '[object String]', - symbolTag$1 = '[object Symbol]'; - -var arrayBufferTag = '[object ArrayBuffer]', - dataViewTag = '[object DataView]'; - -/** Used to convert symbols to primitives and strings. */ -var symbolProto$1 = _Symbol ? _Symbol.prototype : undefined, - symbolValueOf = symbolProto$1 ? symbolProto$1.valueOf : undefined; +function treemapSlice(parent, x0, y0, x1, y1) { + var nodes = parent.children, + node, + i = -1, + n = nodes.length, + k = parent.value && (y1 - y0) / parent.value; -/** - * A specialized version of `baseIsEqualDeep` for comparing objects of - * the same `toStringTag`. - * - * **Note:** This function only supports comparing values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {string} tag The `toStringTag` of the objects to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ -function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { - switch (tag) { - case dataViewTag: - if ((object.byteLength != other.byteLength) || - (object.byteOffset != other.byteOffset)) { - return false; - } - object = object.buffer; - other = other.buffer; + while (++i < n) { + node = nodes[i], node.x0 = x0, node.x1 = x1; + node.y0 = y0, node.y1 = y0 += node.value * k; + } +} - case arrayBufferTag: - if ((object.byteLength != other.byteLength) || - !equalFunc(new _Uint8Array(object), new _Uint8Array(other))) { - return false; - } - return true; +var phi = (1 + Math.sqrt(5)) / 2; - case boolTag: - case dateTag: - case numberTag: - // Coerce booleans to `1` or `0` and dates to milliseconds. - // Invalid dates are coerced to `NaN`. - return eq_1(+object, +other); +function squarifyRatio(ratio, parent, x0, y0, x1, y1) { + var rows = [], + nodes = parent.children, + row, + nodeValue, + i0 = 0, + i1 = 0, + n = nodes.length, + dx, dy, + value = parent.value, + sumValue, + minValue, + maxValue, + newRatio, + minRatio, + alpha, + beta; - case errorTag: - return object.name == other.name && object.message == other.message; + while (i0 < n) { + dx = x1 - x0, dy = y1 - y0; - case regexpTag: - case stringTag$1: - // Coerce regexes to strings and treat strings, primitives and objects, - // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring - // for more details. - return object == (other + ''); + // Find the next non-empty node. + do sumValue = nodes[i1++].value; while (!sumValue && i1 < n); + minValue = maxValue = sumValue; + alpha = Math.max(dy / dx, dx / dy) / (value * ratio); + beta = sumValue * sumValue * alpha; + minRatio = Math.max(maxValue / beta, beta / minValue); - case mapTag$2: - var convert = _mapToArray; + // Keep adding nodes while the aspect ratio maintains or improves. + for (; i1 < n; ++i1) { + sumValue += nodeValue = nodes[i1].value; + if (nodeValue < minValue) minValue = nodeValue; + if (nodeValue > maxValue) maxValue = nodeValue; + beta = sumValue * sumValue * alpha; + newRatio = Math.max(maxValue / beta, beta / minValue); + if (newRatio > minRatio) { sumValue -= nodeValue; break; } + minRatio = newRatio; + } - case setTag$2: - var isPartial = bitmask & COMPARE_PARTIAL_FLAG$4; - convert || (convert = _setToArray); + // Position and record the row orientation. + rows.push(row = {value: sumValue, dice: dx < dy, children: nodes.slice(i0, i1)}); + if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += dy * sumValue / value : y1); + else treemapSlice(row, x0, y0, value ? x0 += dx * sumValue / value : x1, y1); + value -= sumValue, i0 = i1; + } - if (object.size != other.size && !isPartial) { - return false; - } - // Assume cyclic values are equal. - var stacked = stack.get(object); - if (stacked) { - return stacked == other; - } - bitmask |= COMPARE_UNORDERED_FLAG$2; + return rows; +} - // Recursively compare objects (susceptible to call stack limits). - stack.set(object, other); - var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); - stack['delete'](object); - return result; +var squarify = (function custom(ratio) { - case symbolTag$1: - if (symbolValueOf) { - return symbolValueOf.call(object) == symbolValueOf.call(other); - } + function squarify(parent, x0, y0, x1, y1) { + squarifyRatio(ratio, parent, x0, y0, x1, y1); } - return false; -} - -var _equalByTag = equalByTag; -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG$3 = 1; + squarify.ratio = function(x) { + return custom((x = +x) > 1 ? x : 1); + }; -/** Used for built-in method references. */ -var objectProto$3 = Object.prototype; + return squarify; +})(phi); -/** Used to check objects for own properties. */ -var hasOwnProperty$3 = objectProto$3.hasOwnProperty; +function index() { + var tile = squarify, + round = false, + dx = 1, + dy = 1, + paddingStack = [0], + paddingInner = constantZero, + paddingTop = constantZero, + paddingRight = constantZero, + paddingBottom = constantZero, + paddingLeft = constantZero; -/** - * A specialized version of `baseIsEqualDeep` for objects with support for - * partial deep comparisons. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ -function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG$3, - objProps = _getAllKeys(object), - objLength = objProps.length, - othProps = _getAllKeys(other), - othLength = othProps.length; - - if (objLength != othLength && !isPartial) { - return false; - } - var index = objLength; - while (index--) { - var key = objProps[index]; - if (!(isPartial ? key in other : hasOwnProperty$3.call(other, key))) { - return false; - } - } - // Check that cyclic values are equal. - var objStacked = stack.get(object); - var othStacked = stack.get(other); - if (objStacked && othStacked) { - return objStacked == other && othStacked == object; - } - var result = true; - stack.set(object, other); - stack.set(other, object); - - var skipCtor = isPartial; - while (++index < objLength) { - key = objProps[index]; - var objValue = object[key], - othValue = other[key]; - - if (customizer) { - var compared = isPartial - ? customizer(othValue, objValue, key, other, object, stack) - : customizer(objValue, othValue, key, object, other, stack); - } - // Recursively compare objects (susceptible to call stack limits). - if (!(compared === undefined - ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) - : compared - )) { - result = false; - break; - } - skipCtor || (skipCtor = key == 'constructor'); + function treemap(root) { + root.x0 = + root.y0 = 0; + root.x1 = dx; + root.y1 = dy; + root.eachBefore(positionNode); + paddingStack = [0]; + if (round) root.eachBefore(roundNode); + return root; } - if (result && !skipCtor) { - var objCtor = object.constructor, - othCtor = other.constructor; - // Non `Object` object instances with different constructors are not equal. - if (objCtor != othCtor && - ('constructor' in object && 'constructor' in other) && - !(typeof objCtor == 'function' && objCtor instanceof objCtor && - typeof othCtor == 'function' && othCtor instanceof othCtor)) { - result = false; + function positionNode(node) { + var p = paddingStack[node.depth], + x0 = node.x0 + p, + y0 = node.y0 + p, + x1 = node.x1 - p, + y1 = node.y1 - p; + if (x1 < x0) x0 = x1 = (x0 + x1) / 2; + if (y1 < y0) y0 = y1 = (y0 + y1) / 2; + node.x0 = x0; + node.y0 = y0; + node.x1 = x1; + node.y1 = y1; + if (node.children) { + p = paddingStack[node.depth + 1] = paddingInner(node) / 2; + x0 += paddingLeft(node) - p; + y0 += paddingTop(node) - p; + x1 -= paddingRight(node) - p; + y1 -= paddingBottom(node) - p; + if (x1 < x0) x0 = x1 = (x0 + x1) / 2; + if (y1 < y0) y0 = y1 = (y0 + y1) / 2; + tile(node, x0, y0, x1, y1); } } - stack['delete'](object); - stack['delete'](other); - return result; -} -var _equalObjects = equalObjects; + treemap.round = function(x) { + return arguments.length ? (round = !!x, treemap) : round; + }; -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG$2 = 1; + treemap.size = function(x) { + return arguments.length ? (dx = +x[0], dy = +x[1], treemap) : [dx, dy]; + }; -/** `Object#toString` result references. */ -var argsTag = '[object Arguments]', - arrayTag = '[object Array]', - objectTag = '[object Object]'; + treemap.tile = function(x) { + return arguments.length ? (tile = required(x), treemap) : tile; + }; -/** Used for built-in method references. */ -var objectProto$2 = Object.prototype; + treemap.padding = function(x) { + return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : treemap.paddingInner(); + }; -/** Used to check objects for own properties. */ -var hasOwnProperty$2 = objectProto$2.hasOwnProperty; + treemap.paddingInner = function(x) { + return arguments.length ? (paddingInner = typeof x === "function" ? x : constant$2(+x), treemap) : paddingInner; + }; -/** - * A specialized version of `baseIsEqual` for arrays and objects which performs - * deep comparisons and tracks traversed objects enabling objects with circular - * references to be compared. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. - * @param {Function} customizer The function to customize comparisons. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Object} [stack] Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ -function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { - var objIsArr = isArray_1(object), - othIsArr = isArray_1(other), - objTag = objIsArr ? arrayTag : _getTag(object), - othTag = othIsArr ? arrayTag : _getTag(other); + treemap.paddingOuter = function(x) { + return arguments.length ? treemap.paddingTop(x).paddingRight(x).paddingBottom(x).paddingLeft(x) : treemap.paddingTop(); + }; - objTag = objTag == argsTag ? objectTag : objTag; - othTag = othTag == argsTag ? objectTag : othTag; + treemap.paddingTop = function(x) { + return arguments.length ? (paddingTop = typeof x === "function" ? x : constant$2(+x), treemap) : paddingTop; + }; - var objIsObj = objTag == objectTag, - othIsObj = othTag == objectTag, - isSameTag = objTag == othTag; + treemap.paddingRight = function(x) { + return arguments.length ? (paddingRight = typeof x === "function" ? x : constant$2(+x), treemap) : paddingRight; + }; - if (isSameTag && isBuffer_1(object)) { - if (!isBuffer_1(other)) { - return false; - } - objIsArr = true; - objIsObj = false; - } - if (isSameTag && !objIsObj) { - stack || (stack = new _Stack); - return (objIsArr || isTypedArray_1(object)) - ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack) - : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); - } - if (!(bitmask & COMPARE_PARTIAL_FLAG$2)) { - var objIsWrapped = objIsObj && hasOwnProperty$2.call(object, '__wrapped__'), - othIsWrapped = othIsObj && hasOwnProperty$2.call(other, '__wrapped__'); + treemap.paddingBottom = function(x) { + return arguments.length ? (paddingBottom = typeof x === "function" ? x : constant$2(+x), treemap) : paddingBottom; + }; - if (objIsWrapped || othIsWrapped) { - var objUnwrapped = objIsWrapped ? object.value() : object, - othUnwrapped = othIsWrapped ? other.value() : other; + treemap.paddingLeft = function(x) { + return arguments.length ? (paddingLeft = typeof x === "function" ? x : constant$2(+x), treemap) : paddingLeft; + }; - stack || (stack = new _Stack); - return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); - } - } - if (!isSameTag) { - return false; - } - stack || (stack = new _Stack); - return _equalObjects(object, other, bitmask, customizer, equalFunc, stack); + return treemap; } -var _baseIsEqualDeep = baseIsEqualDeep; +function binary(parent, x0, y0, x1, y1) { + var nodes = parent.children, + i, n = nodes.length, + sum, sums = new Array(n + 1); -/** - * The base implementation of `_.isEqual` which supports partial comparisons - * and tracks traversed objects. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {boolean} bitmask The bitmask flags. - * 1 - Unordered comparison - * 2 - Partial comparison - * @param {Function} [customizer] The function to customize comparisons. - * @param {Object} [stack] Tracks traversed `value` and `other` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - */ -function baseIsEqual(value, other, bitmask, customizer, stack) { - if (value === other) { - return true; - } - if (value == null || other == null || (!isObjectLike_1(value) && !isObjectLike_1(other))) { - return value !== value && other !== other; + for (sums[0] = sum = i = 0; i < n; ++i) { + sums[i + 1] = sum += nodes[i].value; } - return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); -} -var _baseIsEqual = baseIsEqual; + partition(0, n, parent.value, x0, y0, x1, y1); -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG$1 = 1, - COMPARE_UNORDERED_FLAG$1 = 2; + function partition(i, j, value, x0, y0, x1, y1) { + if (i >= j - 1) { + var node = nodes[i]; + node.x0 = x0, node.y0 = y0; + node.x1 = x1, node.y1 = y1; + return; + } -/** - * The base implementation of `_.isMatch` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to inspect. - * @param {Object} source The object of property values to match. - * @param {Array} matchData The property names, values, and compare flags to match. - * @param {Function} [customizer] The function to customize comparisons. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - */ -function baseIsMatch(object, source, matchData, customizer) { - var index = matchData.length, - length = index, - noCustomizer = !customizer; + var valueOffset = sums[i], + valueTarget = (value / 2) + valueOffset, + k = i + 1, + hi = j - 1; - if (object == null) { - return !length; - } - object = Object(object); - while (index--) { - var data = matchData[index]; - if ((noCustomizer && data[2]) - ? data[1] !== object[data[0]] - : !(data[0] in object) - ) { - return false; + while (k < hi) { + var mid = k + hi >>> 1; + if (sums[mid] < valueTarget) k = mid + 1; + else hi = mid; } - } - while (++index < length) { - data = matchData[index]; - var key = data[0], - objValue = object[key], - srcValue = data[1]; - - if (noCustomizer && data[2]) { - if (objValue === undefined && !(key in object)) { - return false; - } + + if ((valueTarget - sums[k - 1]) < (sums[k] - valueTarget) && i + 1 < k) --k; + + var valueLeft = sums[k] - valueOffset, + valueRight = value - valueLeft; + + if ((x1 - x0) > (y1 - y0)) { + var xk = value ? (x0 * valueRight + x1 * valueLeft) / value : x1; + partition(i, k, valueLeft, x0, y0, xk, y1); + partition(k, j, valueRight, xk, y0, x1, y1); } else { - var stack = new _Stack; - if (customizer) { - var result = customizer(objValue, srcValue, key, object, source, stack); - } - if (!(result === undefined - ? _baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$1 | COMPARE_UNORDERED_FLAG$1, customizer, stack) - : result - )) { - return false; - } + var yk = value ? (y0 * valueRight + y1 * valueLeft) / value : y1; + partition(i, k, valueLeft, x0, y0, x1, yk); + partition(k, j, valueRight, x0, yk, x1, y1); } } - return true; } -var _baseIsMatch = baseIsMatch; - -/** - * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` if suitable for strict - * equality comparisons, else `false`. - */ -function isStrictComparable(value) { - return value === value && !isObject_1(value); +function initRange(domain, range) { + switch (arguments.length) { + case 0: break; + case 1: this.range(domain); break; + default: this.range(range).domain(domain); break; + } + return this; } -var _isStrictComparable = isStrictComparable; - -/** - * Gets the property names, values, and compare flags of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the match data of `object`. - */ -function getMatchData(object) { - var result = keys_1(object), - length = result.length; +const implicit = Symbol("implicit"); - while (length--) { - var key = result[length], - value = object[key]; +function ordinal() { + var index = new Map(), + domain = [], + range = [], + unknown = implicit; - result[length] = [key, value, _isStrictComparable(value)]; + function scale(d) { + var key = d + "", i = index.get(key); + if (!i) { + if (unknown !== implicit) return unknown; + index.set(key, i = domain.push(d)); + } + return range[(i - 1) % range.length]; } - return result; -} -var _getMatchData = getMatchData; - -/** - * A specialized version of `matchesProperty` for source values suitable - * for strict equality comparisons, i.e. `===`. - * - * @private - * @param {string} key The key of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - */ -function matchesStrictComparable(key, srcValue) { - return function(object) { - if (object == null) { - return false; + scale.domain = function(_) { + if (!arguments.length) return domain.slice(); + domain = [], index = new Map(); + for (const value of _) { + const key = value + ""; + if (index.has(key)) continue; + index.set(key, domain.push(value)); } - return object[key] === srcValue && - (srcValue !== undefined || (key in Object(object))); + return scale; }; -} - -var _matchesStrictComparable = matchesStrictComparable; -/** - * The base implementation of `_.matches` which doesn't clone `source`. - * - * @private - * @param {Object} source The object of property values to match. - * @returns {Function} Returns the new spec function. - */ -function baseMatches(source) { - var matchData = _getMatchData(source); - if (matchData.length == 1 && matchData[0][2]) { - return _matchesStrictComparable(matchData[0][0], matchData[0][1]); - } - return function(object) { - return object === source || _baseIsMatch(object, source, matchData); + scale.range = function(_) { + return arguments.length ? (range = Array.from(_), scale) : range.slice(); }; -} - -var _baseMatches = baseMatches; - -/** `Object#toString` result references. */ -var symbolTag = '[object Symbol]'; -/** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ -function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike_1(value) && _baseGetTag(value) == symbolTag); -} + scale.unknown = function(_) { + return arguments.length ? (unknown = _, scale) : unknown; + }; -var isSymbol_1 = isSymbol; + scale.copy = function() { + return ordinal(domain, range).unknown(unknown); + }; -/** Used to match property names within property paths. */ -var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/; + initRange.apply(scale, arguments); -/** - * Checks if `value` is a property name and not a property path. - * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. - */ -function isKey(value, object) { - if (isArray_1(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol_1(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); + return scale; } -var _isKey = isKey; +function band() { + var scale = ordinal().unknown(undefined), + domain = scale.domain, + ordinalRange = scale.range, + r0 = 0, + r1 = 1, + step, + bandwidth, + round = false, + paddingInner = 0, + paddingOuter = 0, + align = 0.5; -/** Error message constants. */ -var FUNC_ERROR_TEXT = 'Expected a function'; + delete scale.unknown; -/** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) - * method interface of `clear`, `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] - * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; - */ -function memoize(func, resolver) { - if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); + function rescale() { + var n = domain().length, + reverse = r1 < r0, + start = reverse ? r1 : r0, + stop = reverse ? r0 : r1; + step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2); + if (round) step = Math.floor(step); + start += (stop - start - step * (n - paddingInner)) * align; + bandwidth = step * (1 - paddingInner); + if (round) start = Math.round(start), bandwidth = Math.round(bandwidth); + var values = sequence(n).map(function(i) { return start + step * i; }); + return ordinalRange(reverse ? values.reverse() : values); } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result) || cache; - return result; + scale.domain = function(_) { + return arguments.length ? (domain(_), rescale()) : domain(); }; - memoized.cache = new (memoize.Cache || _MapCache); - return memoized; -} - -// Expose `MapCache`. -memoize.Cache = _MapCache; -var memoize_1 = memoize; + scale.range = function(_) { + return arguments.length ? ([r0, r1] = _, r0 = +r0, r1 = +r1, rescale()) : [r0, r1]; + }; -/** Used as the maximum memoize cache size. */ -var MAX_MEMOIZE_SIZE = 500; + scale.rangeRound = function(_) { + return [r0, r1] = _, r0 = +r0, r1 = +r1, round = true, rescale(); + }; -/** - * A specialized version of `_.memoize` which clears the memoized function's - * cache when it exceeds `MAX_MEMOIZE_SIZE`. - * - * @private - * @param {Function} func The function to have its output memoized. - * @returns {Function} Returns the new memoized function. - */ -function memoizeCapped(func) { - var result = memoize_1(func, function(key) { - if (cache.size === MAX_MEMOIZE_SIZE) { - cache.clear(); - } - return key; - }); + scale.bandwidth = function() { + return bandwidth; + }; - var cache = result.cache; - return result; -} + scale.step = function() { + return step; + }; -var _memoizeCapped = memoizeCapped; + scale.round = function(_) { + return arguments.length ? (round = !!_, rescale()) : round; + }; -/** Used to match property names within property paths. */ -var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + scale.padding = function(_) { + return arguments.length ? (paddingInner = Math.min(1, paddingOuter = +_), rescale()) : paddingInner; + }; -/** Used to match backslashes in property paths. */ -var reEscapeChar = /\\(\\)?/g; + scale.paddingInner = function(_) { + return arguments.length ? (paddingInner = Math.min(1, _), rescale()) : paddingInner; + }; -/** - * Converts `string` to a property path array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. - */ -var stringToPath = _memoizeCapped(function(string) { - var result = []; - if (string.charCodeAt(0) === 46 /* . */) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, subString) { - result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; -}); + scale.paddingOuter = function(_) { + return arguments.length ? (paddingOuter = +_, rescale()) : paddingOuter; + }; -var _stringToPath = stringToPath; + scale.align = function(_) { + return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align; + }; -/** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ -function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); + scale.copy = function() { + return band(domain(), [r0, r1]) + .round(round) + .paddingInner(paddingInner) + .paddingOuter(paddingOuter) + .align(align); + }; - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; + return initRange.apply(rescale(), arguments); } -var _arrayMap = arrayMap; +function pointish(scale) { + var copy = scale.copy; -/** Used as references for various `Number` constants. */ -var INFINITY$2 = 1 / 0; + scale.padding = scale.paddingOuter; + delete scale.paddingInner; + delete scale.paddingOuter; -/** Used to convert symbols to primitives and strings. */ -var symbolProto = _Symbol ? _Symbol.prototype : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; + scale.copy = function() { + return pointish(copy()); + }; -/** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ -function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; - } - if (isArray_1(value)) { - // Recursively convert values (susceptible to call stack limits). - return _arrayMap(value, baseToString) + ''; - } - if (isSymbol_1(value)) { - return symbolToString ? symbolToString.call(value) : ''; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY$2) ? '-0' : result; + return scale; } -var _baseToString = baseToString; - -/** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ -function toString(value) { - return value == null ? '' : _baseToString(value); +function point$1() { + return pointish(band.apply(null, arguments).paddingInner(1)); } -var toString_1 = toString; +function constants(x) { + return function() { + return x; + }; +} -/** - * Casts `value` to a path array if it's not one. - * - * @private - * @param {*} value The value to inspect. - * @param {Object} [object] The object to query keys on. - * @returns {Array} Returns the cast property path array. - */ -function castPath(value, object) { - if (isArray_1(value)) { - return value; - } - return _isKey(value, object) ? [value] : _stringToPath(toString_1(value)); +function number(x) { + return +x; } -var _castPath = castPath; +var unit = [0, 1]; -/** Used as references for various `Number` constants. */ -var INFINITY$1 = 1 / 0; +function identity$1(x) { + return x; +} -/** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ -function toKey(value) { - if (typeof value == 'string' || isSymbol_1(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result; +function normalize(a, b) { + return (b -= (a = +a)) + ? function(x) { return (x - a) / b; } + : constants(isNaN(b) ? NaN : 0.5); } -var _toKey = toKey; +function clamper(a, b) { + var t; + if (a > b) t = a, a = b, b = t; + return function(x) { return Math.max(a, Math.min(b, x)); }; +} -/** - * The base implementation of `_.get` without support for default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. - */ -function baseGet(object, path) { - path = _castPath(path, object); +// normalize(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1]. +// interpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding range value x in [a,b]. +function bimap(domain, range, interpolate) { + var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1]; + if (d1 < d0) d0 = normalize(d1, d0), r0 = interpolate(r1, r0); + else d0 = normalize(d0, d1), r0 = interpolate(r0, r1); + return function(x) { return r0(d0(x)); }; +} - var index = 0, - length = path.length; +function polymap(domain, range, interpolate) { + var j = Math.min(domain.length, range.length) - 1, + d = new Array(j), + r = new Array(j), + i = -1; - while (object != null && index < length) { - object = object[_toKey(path[index++])]; + // Reverse descending domains. + if (domain[j] < domain[0]) { + domain = domain.slice().reverse(); + range = range.slice().reverse(); } - return (index && index == length) ? object : undefined; -} -var _baseGet = baseGet; + while (++i < j) { + d[i] = normalize(domain[i], domain[i + 1]); + r[i] = interpolate(range[i], range[i + 1]); + } -/** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 - * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' - */ -function get(object, path, defaultValue) { - var result = object == null ? undefined : _baseGet(object, path); - return result === undefined ? defaultValue : result; + return function(x) { + var i = bisectRight(domain, x, 1, j) - 1; + return r[i](d[i](x)); + }; } -var get_1 = get; - -/** - * The base implementation of `_.hasIn` without support for deep paths. - * - * @private - * @param {Object} [object] The object to query. - * @param {Array|string} key The key to check. - * @returns {boolean} Returns `true` if `key` exists, else `false`. - */ -function baseHasIn(object, key) { - return object != null && key in Object(object); +function copy(source, target) { + return target + .domain(source.domain()) + .range(source.range()) + .interpolate(source.interpolate()) + .clamp(source.clamp()) + .unknown(source.unknown()); } -var _baseHasIn = baseHasIn; - -/** - * Checks if `path` exists on `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @param {Function} hasFunc The function to check properties. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - */ -function hasPath(object, path, hasFunc) { - path = _castPath(path, object); - - var index = -1, - length = path.length, - result = false; +function transformer() { + var domain = unit, + range = unit, + interpolate = interpolate$1, + transform, + untransform, + unknown, + clamp = identity$1, + piecewise, + output, + input; - while (++index < length) { - var key = _toKey(path[index]); - if (!(result = object != null && hasFunc(object, key))) { - break; - } - object = object[key]; - } - if (result || ++index != length) { - return result; + function rescale() { + var n = Math.min(domain.length, range.length); + if (clamp !== identity$1) clamp = clamper(domain[0], domain[n - 1]); + piecewise = n > 2 ? polymap : bimap; + output = input = null; + return scale; } - length = object == null ? 0 : object.length; - return !!length && isLength_1(length) && _isIndex(key, length) && - (isArray_1(object) || isArguments_1(object)); -} -var _hasPath = hasPath; + function scale(x) { + return x == null || isNaN(x = +x) ? unknown : (output || (output = piecewise(domain.map(transform), range, interpolate)))(transform(clamp(x))); + } -/** - * Checks if `path` is a direct or inherited property of `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - * @example - * - * var object = _.create({ 'a': _.create({ 'b': 2 }) }); - * - * _.hasIn(object, 'a'); - * // => true - * - * _.hasIn(object, 'a.b'); - * // => true - * - * _.hasIn(object, ['a', 'b']); - * // => true - * - * _.hasIn(object, 'b'); - * // => false - */ -function hasIn(object, path) { - return object != null && _hasPath(object, path, _baseHasIn); -} + scale.invert = function(y) { + return clamp(untransform((input || (input = piecewise(range, domain.map(transform), interpolateNumber)))(y))); + }; -var hasIn_1 = hasIn; + scale.domain = function(_) { + return arguments.length ? (domain = Array.from(_, number), rescale()) : domain.slice(); + }; -/** Used to compose bitmasks for value comparisons. */ -var COMPARE_PARTIAL_FLAG = 1, - COMPARE_UNORDERED_FLAG = 2; + scale.range = function(_) { + return arguments.length ? (range = Array.from(_), rescale()) : range.slice(); + }; -/** - * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. - * - * @private - * @param {string} path The path of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - */ -function baseMatchesProperty(path, srcValue) { - if (_isKey(path) && _isStrictComparable(srcValue)) { - return _matchesStrictComparable(_toKey(path), srcValue); - } - return function(object) { - var objValue = get_1(object, path); - return (objValue === undefined && objValue === srcValue) - ? hasIn_1(object, path) - : _baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG); + scale.rangeRound = function(_) { + return range = Array.from(_), interpolate = interpolateRound, rescale(); }; -} -var _baseMatchesProperty = baseMatchesProperty; + scale.clamp = function(_) { + return arguments.length ? (clamp = _ ? true : identity$1, rescale()) : clamp !== identity$1; + }; -/** - * The base implementation of `_.property` without support for deep paths. - * - * @private - * @param {string} key The key of the property to get. - * @returns {Function} Returns the new accessor function. - */ -function baseProperty(key) { - return function(object) { - return object == null ? undefined : object[key]; + scale.interpolate = function(_) { + return arguments.length ? (interpolate = _, rescale()) : interpolate; }; -} -var _baseProperty = baseProperty; + scale.unknown = function(_) { + return arguments.length ? (unknown = _, scale) : unknown; + }; -/** - * A specialized version of `baseProperty` which supports deep paths. - * - * @private - * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new accessor function. - */ -function basePropertyDeep(path) { - return function(object) { - return _baseGet(object, path); + return function(t, u) { + transform = t, untransform = u; + return rescale(); }; } -var _basePropertyDeep = basePropertyDeep; - -/** - * Creates a function that returns the value at `path` of a given object. - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Util - * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new accessor function. - * @example - * - * var objects = [ - * { 'a': { 'b': 2 } }, - * { 'a': { 'b': 1 } } - * ]; - * - * _.map(objects, _.property('a.b')); - * // => [2, 1] - * - * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); - * // => [1, 2] - */ -function property(path) { - return _isKey(path) ? _baseProperty(_toKey(path)) : _basePropertyDeep(path); +function continuous() { + return transformer()(identity$1, identity$1); } -var property_1 = property; - -/** - * The base implementation of `_.iteratee`. - * - * @private - * @param {*} [value=_.identity] The value to convert to an iteratee. - * @returns {Function} Returns the iteratee. - */ -function baseIteratee(value) { - // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. - // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. - if (typeof value == 'function') { - return value; - } - if (value == null) { - return identity_1; - } - if (typeof value == 'object') { - return isArray_1(value) - ? _baseMatchesProperty(value[0], value[1]) - : _baseMatches(value); +function tickFormat(start, stop, count, specifier) { + var step = tickStep(start, stop, count), + precision; + specifier = formatSpecifier(specifier == null ? ",f" : specifier); + switch (specifier.type) { + case "s": { + var value = Math.max(Math.abs(start), Math.abs(stop)); + if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision; + return formatPrefix(specifier, value); + } + case "": + case "e": + case "g": + case "p": + case "r": { + if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e"); + break; + } + case "f": + case "%": { + if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2; + break; + } } - return property_1(value); + return format(specifier); } -var _baseIteratee = baseIteratee; +function linearish(scale) { + var domain = scale.domain; -/** - * Iterates over elements of `collection`, returning an array of all elements - * `predicate` returns truthy for. The predicate is invoked with three - * arguments: (value, index|key, collection). - * - * **Note:** Unlike `_.remove`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - * @see _.reject - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false } - * ]; - * - * _.filter(users, function(o) { return !o.active; }); - * // => objects for ['fred'] - * - * // The `_.matches` iteratee shorthand. - * _.filter(users, { 'age': 36, 'active': true }); - * // => objects for ['barney'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.filter(users, ['active', false]); - * // => objects for ['fred'] - * - * // The `_.property` iteratee shorthand. - * _.filter(users, 'active'); - * // => objects for ['barney'] - * - * // Combining several predicates using `_.overEvery` or `_.overSome`. - * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); - * // => objects for ['fred', 'barney'] - */ -function filter(collection, predicate) { - var func = isArray_1(collection) ? _arrayFilter : _baseFilter; - return func(collection, _baseIteratee(predicate)); -} + scale.ticks = function(count) { + var d = domain(); + return ticks(d[0], d[d.length - 1], count == null ? 10 : count); + }; -var filter_1 = filter; + scale.tickFormat = function(count, specifier) { + var d = domain(); + return tickFormat(d[0], d[d.length - 1], count == null ? 10 : count, specifier); + }; -/** Used for built-in method references. */ -var objectProto$1 = Object.prototype; + scale.nice = function(count) { + if (count == null) count = 10; -/** Used to check objects for own properties. */ -var hasOwnProperty$1 = objectProto$1.hasOwnProperty; + var d = domain(); + var i0 = 0; + var i1 = d.length - 1; + var start = d[i0]; + var stop = d[i1]; + var prestep; + var step; + var maxIter = 10; -/** - * The base implementation of `_.has` without support for deep paths. - * - * @private - * @param {Object} [object] The object to query. - * @param {Array|string} key The key to check. - * @returns {boolean} Returns `true` if `key` exists, else `false`. - */ -function baseHas(object, key) { - return object != null && hasOwnProperty$1.call(object, key); -} + if (stop < start) { + step = start, start = stop, stop = step; + step = i0, i0 = i1, i1 = step; + } + + while (maxIter-- > 0) { + step = tickIncrement(start, stop, count); + if (step === prestep) { + d[i0] = start; + d[i1] = stop; + return domain(d); + } else if (step > 0) { + start = Math.floor(start / step) * step; + stop = Math.ceil(stop / step) * step; + } else if (step < 0) { + start = Math.ceil(start * step) / step; + stop = Math.floor(stop * step) / step; + } else { + break; + } + prestep = step; + } -var _baseHas = baseHas; + return scale; + }; -/** - * Checks if `path` is a direct property of `object`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - * @example - * - * var object = { 'a': { 'b': 2 } }; - * var other = _.create({ 'a': _.create({ 'b': 2 }) }); - * - * _.has(object, 'a'); - * // => true - * - * _.has(object, 'a.b'); - * // => true - * - * _.has(object, ['a', 'b']); - * // => true - * - * _.has(other, 'a'); - * // => false - */ -function has(object, path) { - return object != null && _hasPath(object, path, _baseHas); + return scale; } -var has_1 = has; +function linear() { + var scale = continuous(); -/** `Object#toString` result references. */ -var mapTag$1 = '[object Map]', - setTag$1 = '[object Set]'; + scale.copy = function() { + return copy(scale, linear()); + }; -/** Used for built-in method references. */ -var objectProto = Object.prototype; + initRange.apply(scale, arguments); -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + return linearish(scale); +} -/** - * Checks if `value` is an empty object, collection, map, or set. - * - * Objects are considered empty if they have no own enumerable string keyed - * properties. - * - * Array-like values such as `arguments` objects, arrays, buffers, strings, or - * jQuery-like collections are considered empty if they have a `length` of `0`. - * Similarly, maps and sets are considered empty if they have a `size` of `0`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is empty, else `false`. - * @example - * - * _.isEmpty(null); - * // => true - * - * _.isEmpty(true); - * // => true - * - * _.isEmpty(1); - * // => true - * - * _.isEmpty([1, 2, 3]); - * // => false - * - * _.isEmpty({ 'a': 1 }); - * // => false - */ -function isEmpty(value) { - if (value == null) { - return true; - } - if (isArrayLike_1(value) && - (isArray_1(value) || typeof value == 'string' || typeof value.splice == 'function' || - isBuffer_1(value) || isTypedArray_1(value) || isArguments_1(value))) { - return !value.length; - } - var tag = _getTag(value); - if (tag == mapTag$1 || tag == setTag$1) { - return !value.size; - } - if (_isPrototype(value)) { - return !_baseKeys(value).length; - } - for (var key in value) { - if (hasOwnProperty.call(value, key)) { - return false; - } - } - return true; +function colors(specifier) { + var n = specifier.length / 6 | 0, colors = new Array(n), i = 0; + while (i < n) colors[i] = "#" + specifier.slice(i * 6, ++i * 6); + return colors; } -var isEmpty_1 = isEmpty; +var category10 = colors("1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf"); -/** - * Checks if `value` is `undefined`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. - * @example - * - * _.isUndefined(void 0); - * // => true - * - * _.isUndefined(null); - * // => false - */ -function isUndefined(value) { - return value === undefined; -} +cubehelixLong(cubehelix$1(-100, 0.75, 0.35), cubehelix$1(80, 1.50, 0.8)); -var isUndefined_1 = isUndefined; +cubehelixLong(cubehelix$1(260, 0.75, 0.35), cubehelix$1(80, 1.50, 0.8)); -/** - * The base implementation of `_.map` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ -function baseMap(collection, iteratee) { - var index = -1, - result = isArrayLike_1(collection) ? Array(collection.length) : []; +var c = cubehelix$1(); - _baseEach(collection, function(value, key, collection) { - result[++index] = iteratee(value, key, collection); - }); - return result; +function rainbow(t) { + if (t < 0 || t > 1) t -= Math.floor(t); + var ts = Math.abs(t - 0.5); + c.h = 360 * t - 100; + c.s = 1.5 - 1.5 * ts; + c.l = 0.8 - 0.9 * ts; + return c + ""; } -var _baseMap = baseMap; - -/** - * Creates an array of values by running each element in `collection` thru - * `iteratee`. The iteratee is invoked with three arguments: - * (value, index|key, collection). - * - * Many lodash methods are guarded to work as iteratees for methods like - * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. - * - * The guarded methods are: - * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, - * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, - * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, - * `template`, `trim`, `trimEnd`, `trimStart`, and `words` - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - * @example - * - * function square(n) { - * return n * n; - * } - * - * _.map([4, 8], square); - * // => [16, 64] - * - * _.map({ 'a': 4, 'b': 8 }, square); - * // => [16, 64] (iteration order is not guaranteed) - * - * var users = [ - * { 'user': 'barney' }, - * { 'user': 'fred' } - * ]; - * - * // The `_.property` iteratee shorthand. - * _.map(users, 'user'); - * // => ['barney', 'fred'] - */ -function map(collection, iteratee) { - var func = isArray_1(collection) ? _arrayMap : _baseMap; - return func(collection, _baseIteratee(iteratee)); +function constant$1(x) { + return function constant() { + return x; + }; } -var map_1 = map; +var abs = Math.abs; +var atan2 = Math.atan2; +var cos = Math.cos; +var max = Math.max; +var min = Math.min; +var sin = Math.sin; +var sqrt = Math.sqrt; -/** - * A specialized version of `_.reduce` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {boolean} [initAccum] Specify using the first element of `array` as - * the initial value. - * @returns {*} Returns the accumulated value. - */ -function arrayReduce(array, iteratee, accumulator, initAccum) { - var index = -1, - length = array == null ? 0 : array.length; +var epsilon = 1e-12; +var pi = Math.PI; +var halfPi = pi / 2; +var tau = 2 * pi; - if (initAccum && length) { - accumulator = array[++index]; - } - while (++index < length) { - accumulator = iteratee(accumulator, array[index], index, array); - } - return accumulator; +function acos(x) { + return x > 1 ? 0 : x < -1 ? pi : Math.acos(x); } -var _arrayReduce = arrayReduce; - -/** - * The base implementation of `_.reduce` and `_.reduceRight`, without support - * for iteratee shorthands, which iterates over `collection` using `eachFunc`. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} accumulator The initial value. - * @param {boolean} initAccum Specify using the first or last element of - * `collection` as the initial value. - * @param {Function} eachFunc The function to iterate over `collection`. - * @returns {*} Returns the accumulated value. - */ -function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { - eachFunc(collection, function(value, index, collection) { - accumulator = initAccum - ? (initAccum = false, value) - : iteratee(accumulator, value, index, collection); - }); - return accumulator; +function asin(x) { + return x >= 1 ? halfPi : x <= -1 ? -halfPi : Math.asin(x); } -var _baseReduce = baseReduce; - -/** - * Reduces `collection` to a value which is the accumulated result of running - * each element in `collection` thru `iteratee`, where each successive - * invocation is supplied the return value of the previous. If `accumulator` - * is not given, the first element of `collection` is used as the initial - * value. The iteratee is invoked with four arguments: - * (accumulator, value, index|key, collection). - * - * Many lodash methods are guarded to work as iteratees for methods like - * `_.reduce`, `_.reduceRight`, and `_.transform`. - * - * The guarded methods are: - * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, - * and `sortBy` - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @returns {*} Returns the accumulated value. - * @see _.reduceRight - * @example - * - * _.reduce([1, 2], function(sum, n) { - * return sum + n; - * }, 0); - * // => 3 - * - * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { - * (result[value] || (result[value] = [])).push(key); - * return result; - * }, {}); - * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) - */ -function reduce(collection, iteratee, accumulator) { - var func = isArray_1(collection) ? _arrayReduce : _baseReduce, - initAccum = arguments.length < 3; - - return func(collection, _baseIteratee(iteratee), accumulator, initAccum, _baseEach); +function arcInnerRadius(d) { + return d.innerRadius; } -var reduce_1 = reduce; - -/** `Object#toString` result references. */ -var stringTag = '[object String]'; - -/** - * Checks if `value` is classified as a `String` primitive or object. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a string, else `false`. - * @example - * - * _.isString('abc'); - * // => true - * - * _.isString(1); - * // => false - */ -function isString(value) { - return typeof value == 'string' || - (!isArray_1(value) && isObjectLike_1(value) && _baseGetTag(value) == stringTag); +function arcOuterRadius(d) { + return d.outerRadius; } -var isString_1 = isString; - -/** - * Gets the size of an ASCII `string`. - * - * @private - * @param {string} string The string inspect. - * @returns {number} Returns the string size. - */ -var asciiSize = _baseProperty('length'); - -var _asciiSize = asciiSize; - -/** Used to compose unicode character classes. */ -var rsAstralRange$1 = '\\ud800-\\udfff', - rsComboMarksRange$1 = '\\u0300-\\u036f', - reComboHalfMarksRange$1 = '\\ufe20-\\ufe2f', - rsComboSymbolsRange$1 = '\\u20d0-\\u20ff', - rsComboRange$1 = rsComboMarksRange$1 + reComboHalfMarksRange$1 + rsComboSymbolsRange$1, - rsVarRange$1 = '\\ufe0e\\ufe0f'; - -/** Used to compose unicode capture groups. */ -var rsZWJ$1 = '\\u200d'; - -/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ -var reHasUnicode = RegExp('[' + rsZWJ$1 + rsAstralRange$1 + rsComboRange$1 + rsVarRange$1 + ']'); - -/** - * Checks if `string` contains Unicode symbols. - * - * @private - * @param {string} string The string to inspect. - * @returns {boolean} Returns `true` if a symbol is found, else `false`. - */ -function hasUnicode(string) { - return reHasUnicode.test(string); -} - -var _hasUnicode = hasUnicode; - -/** Used to compose unicode character classes. */ -var rsAstralRange = '\\ud800-\\udfff', - rsComboMarksRange = '\\u0300-\\u036f', - reComboHalfMarksRange = '\\ufe20-\\ufe2f', - rsComboSymbolsRange = '\\u20d0-\\u20ff', - rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, - rsVarRange = '\\ufe0e\\ufe0f'; - -/** Used to compose unicode capture groups. */ -var rsAstral = '[' + rsAstralRange + ']', - rsCombo = '[' + rsComboRange + ']', - rsFitz = '\\ud83c[\\udffb-\\udfff]', - rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', - rsNonAstral = '[^' + rsAstralRange + ']', - rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', - rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', - rsZWJ = '\\u200d'; - -/** Used to compose unicode regexes. */ -var reOptMod = rsModifier + '?', - rsOptVar = '[' + rsVarRange + ']?', - rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', - rsSeq = rsOptVar + reOptMod + rsOptJoin, - rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; - -/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ -var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); +function arcStartAngle(d) { + return d.startAngle; +} -/** - * Gets the size of a Unicode `string`. - * - * @private - * @param {string} string The string inspect. - * @returns {number} Returns the string size. - */ -function unicodeSize(string) { - var result = reUnicode.lastIndex = 0; - while (reUnicode.test(string)) { - ++result; - } - return result; +function arcEndAngle(d) { + return d.endAngle; } -var _unicodeSize = unicodeSize; +function arcPadAngle(d) { + return d && d.padAngle; // Note: optional! +} -/** - * Gets the number of symbols in `string`. - * - * @private - * @param {string} string The string to inspect. - * @returns {number} Returns the string size. - */ -function stringSize(string) { - return _hasUnicode(string) - ? _unicodeSize(string) - : _asciiSize(string); +function intersect(x0, y0, x1, y1, x2, y2, x3, y3) { + var x10 = x1 - x0, y10 = y1 - y0, + x32 = x3 - x2, y32 = y3 - y2, + t = y32 * x10 - x32 * y10; + if (t * t < epsilon) return; + t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / t; + return [x0 + t * x10, y0 + t * y10]; } -var _stringSize = stringSize; +// Compute perpendicular offset line of length rc. +// http://mathworld.wolfram.com/Circle-LineIntersection.html +function cornerTangents(x0, y0, x1, y1, r1, rc, cw) { + var x01 = x0 - x1, + y01 = y0 - y1, + lo = (cw ? rc : -rc) / sqrt(x01 * x01 + y01 * y01), + ox = lo * y01, + oy = -lo * x01, + x11 = x0 + ox, + y11 = y0 + oy, + x10 = x1 + ox, + y10 = y1 + oy, + x00 = (x11 + x10) / 2, + y00 = (y11 + y10) / 2, + dx = x10 - x11, + dy = y10 - y11, + d2 = dx * dx + dy * dy, + r = r1 - rc, + D = x11 * y10 - x10 * y11, + d = (dy < 0 ? -1 : 1) * sqrt(max(0, r * r * d2 - D * D)), + cx0 = (D * dy - dx * d) / d2, + cy0 = (-D * dx - dy * d) / d2, + cx1 = (D * dy + dx * d) / d2, + cy1 = (-D * dx + dy * d) / d2, + dx0 = cx0 - x00, + dy0 = cy0 - y00, + dx1 = cx1 - x00, + dy1 = cy1 - y00; -/** `Object#toString` result references. */ -var mapTag = '[object Map]', - setTag = '[object Set]'; + // Pick the closer of the two intersection points. + // TODO Is there a faster way to determine which intersection to use? + if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1; -/** - * Gets the size of `collection` by returning its length for array-like - * values or the number of own enumerable string keyed properties for objects. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object|string} collection The collection to inspect. - * @returns {number} Returns the collection size. - * @example - * - * _.size([1, 2, 3]); - * // => 3 - * - * _.size({ 'a': 1, 'b': 2 }); - * // => 2 - * - * _.size('pebbles'); - * // => 7 - */ -function size(collection) { - if (collection == null) { - return 0; - } - if (isArrayLike_1(collection)) { - return isString_1(collection) ? _stringSize(collection) : collection.length; - } - var tag = _getTag(collection); - if (tag == mapTag || tag == setTag) { - return collection.size; - } - return _baseKeys(collection).length; + return { + cx: cx0, + cy: cy0, + x01: -ox, + y01: -oy, + x11: cx0 * (r1 / r - 1), + y11: cy0 * (r1 / r - 1) + }; } -var size_1 = size; +function arc() { + var innerRadius = arcInnerRadius, + outerRadius = arcOuterRadius, + cornerRadius = constant$1(0), + padRadius = null, + startAngle = arcStartAngle, + endAngle = arcEndAngle, + padAngle = arcPadAngle, + context = null; -/** - * An alternative to `_.reduce`; this method transforms `object` to a new - * `accumulator` object which is the result of running each of its own - * enumerable string keyed properties thru `iteratee`, with each invocation - * potentially mutating the `accumulator` object. If `accumulator` is not - * provided, a new object with the same `[[Prototype]]` will be used. The - * iteratee is invoked with four arguments: (accumulator, value, key, object). - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @since 1.3.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The custom accumulator value. - * @returns {*} Returns the accumulated value. - * @example - * - * _.transform([2, 3, 4], function(result, n) { - * result.push(n *= n); - * return n % 2 == 0; - * }, []); - * // => [4, 9] - * - * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { - * (result[value] || (result[value] = [])).push(key); - * }, {}); - * // => { '1': ['a', 'c'], '2': ['b'] } - */ -function transform(object, iteratee, accumulator) { - var isArr = isArray_1(object), - isArrLike = isArr || isBuffer_1(object) || isTypedArray_1(object); + function arc() { + var buffer, + r, + r0 = +innerRadius.apply(this, arguments), + r1 = +outerRadius.apply(this, arguments), + a0 = startAngle.apply(this, arguments) - halfPi, + a1 = endAngle.apply(this, arguments) - halfPi, + da = abs(a1 - a0), + cw = a1 > a0; - iteratee = _baseIteratee(iteratee); - if (accumulator == null) { - var Ctor = object && object.constructor; - if (isArrLike) { - accumulator = isArr ? new Ctor : []; - } - else if (isObject_1(object)) { - accumulator = isFunction_1(Ctor) ? _baseCreate(_getPrototype(object)) : {}; - } - else { - accumulator = {}; - } - } - (isArrLike ? _arrayEach : _baseForOwn)(object, function(value, index, object) { - return iteratee(accumulator, value, index, object); - }); - return accumulator; -} + if (!context) context = buffer = path(); -var transform_1 = transform; + // Ensure that the outer radius is always larger than the inner radius. + if (r1 < r0) r = r1, r1 = r0, r0 = r; -/** Built-in value references. */ -var spreadableSymbol = _Symbol ? _Symbol.isConcatSpreadable : undefined; + // Is it a point? + if (!(r1 > epsilon)) context.moveTo(0, 0); -/** - * Checks if `value` is a flattenable `arguments` object or array. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. - */ -function isFlattenable(value) { - return isArray_1(value) || isArguments_1(value) || - !!(spreadableSymbol && value && value[spreadableSymbol]); -} + // Or is it a circle or annulus? + else if (da > tau - epsilon) { + context.moveTo(r1 * cos(a0), r1 * sin(a0)); + context.arc(0, 0, r1, a0, a1, !cw); + if (r0 > epsilon) { + context.moveTo(r0 * cos(a1), r0 * sin(a1)); + context.arc(0, 0, r0, a1, a0, cw); + } + } -var _isFlattenable = isFlattenable; + // Or is it a circular or annular sector? + else { + var a01 = a0, + a11 = a1, + a00 = a0, + a10 = a1, + da0 = da, + da1 = da, + ap = padAngle.apply(this, arguments) / 2, + rp = (ap > epsilon) && (padRadius ? +padRadius.apply(this, arguments) : sqrt(r0 * r0 + r1 * r1)), + rc = min(abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)), + rc0 = rc, + rc1 = rc, + t0, + t1; -/** - * The base implementation of `_.flatten` with support for restricting flattening. - * - * @private - * @param {Array} array The array to flatten. - * @param {number} depth The maximum recursion depth. - * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. - * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. - * @param {Array} [result=[]] The initial result value. - * @returns {Array} Returns the new flattened array. - */ -function baseFlatten(array, depth, predicate, isStrict, result) { - var index = -1, - length = array.length; - - predicate || (predicate = _isFlattenable); - result || (result = []); - - while (++index < length) { - var value = array[index]; - if (depth > 0 && predicate(value)) { - if (depth > 1) { - // Recursively flatten arrays (susceptible to call stack limits). - baseFlatten(value, depth - 1, predicate, isStrict, result); - } else { - _arrayPush(result, value); + // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0. + if (rp > epsilon) { + var p0 = asin(rp / r0 * sin(ap)), + p1 = asin(rp / r1 * sin(ap)); + if ((da0 -= p0 * 2) > epsilon) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0; + else da0 = 0, a00 = a10 = (a0 + a1) / 2; + if ((da1 -= p1 * 2) > epsilon) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1; + else da1 = 0, a01 = a11 = (a0 + a1) / 2; } - } else if (!isStrict) { - result[result.length] = value; - } - } - return result; -} -var _baseFlatten = baseFlatten; + var x01 = r1 * cos(a01), + y01 = r1 * sin(a01), + x10 = r0 * cos(a10), + y10 = r0 * sin(a10); -/** - * A faster alternative to `Function#apply`, this function invokes `func` - * with the `this` binding of `thisArg` and the arguments of `args`. - * - * @private - * @param {Function} func The function to invoke. - * @param {*} thisArg The `this` binding of `func`. - * @param {Array} args The arguments to invoke `func` with. - * @returns {*} Returns the result of `func`. - */ -function apply(func, thisArg, args) { - switch (args.length) { - case 0: return func.call(thisArg); - case 1: return func.call(thisArg, args[0]); - case 2: return func.call(thisArg, args[0], args[1]); - case 3: return func.call(thisArg, args[0], args[1], args[2]); - } - return func.apply(thisArg, args); -} + // Apply rounded corners? + if (rc > epsilon) { + var x11 = r1 * cos(a11), + y11 = r1 * sin(a11), + x00 = r0 * cos(a00), + y00 = r0 * sin(a00), + oc; -var _apply = apply; + // Restrict the corner radius according to the sector angle. + if (da < pi && (oc = intersect(x01, y01, x00, y00, x11, y11, x10, y10))) { + var ax = x01 - oc[0], + ay = y01 - oc[1], + bx = x11 - oc[0], + by = y11 - oc[1], + kc = 1 / sin(acos((ax * bx + ay * by) / (sqrt(ax * ax + ay * ay) * sqrt(bx * bx + by * by))) / 2), + lc = sqrt(oc[0] * oc[0] + oc[1] * oc[1]); + rc0 = min(rc, (r0 - lc) / (kc - 1)); + rc1 = min(rc, (r1 - lc) / (kc + 1)); + } + } -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeMax = Math.max; + // Is the sector collapsed to a line? + if (!(da1 > epsilon)) context.moveTo(x01, y01); -/** - * A specialized version of `baseRest` which transforms the rest array. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @param {Function} transform The rest array transform. - * @returns {Function} Returns the new function. - */ -function overRest(func, start, transform) { - start = nativeMax(start === undefined ? (func.length - 1) : start, 0); - return function() { - var args = arguments, - index = -1, - length = nativeMax(args.length - start, 0), - array = Array(length); + // Does the sector’s outer ring have rounded corners? + else if (rc1 > epsilon) { + t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw); + t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw); - while (++index < length) { - array[index] = args[start + index]; - } - index = -1; - var otherArgs = Array(start + 1); - while (++index < start) { - otherArgs[index] = args[index]; - } - otherArgs[start] = transform(array); - return _apply(func, this, otherArgs); - }; -} + context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01); -var _overRest = overRest; + // Have the corners merged? + if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw); -/** - * The base implementation of `setToString` without support for hot loop shorting. - * - * @private - * @param {Function} func The function to modify. - * @param {Function} string The `toString` result. - * @returns {Function} Returns `func`. - */ -var baseSetToString = !_defineProperty ? identity_1 : function(func, string) { - return _defineProperty(func, 'toString', { - 'configurable': true, - 'enumerable': false, - 'value': constant_1(string), - 'writable': true - }); -}; + // Otherwise, draw the two corners and the ring. + else { + context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw); + context.arc(0, 0, r1, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw); + context.arc(t1.cx, t1.cy, rc1, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw); + } + } -var _baseSetToString = baseSetToString; + // Or is the outer ring just a circular arc? + else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw); -/** Used to detect hot functions by number of calls within a span of milliseconds. */ -var HOT_COUNT = 800, - HOT_SPAN = 16; + // Is there no inner ring, and it’s a circular sector? + // Or perhaps it’s an annular sector collapsed due to padding? + if (!(r0 > epsilon) || !(da0 > epsilon)) context.lineTo(x10, y10); -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeNow = Date.now; + // Does the sector’s inner ring (or point) have rounded corners? + else if (rc0 > epsilon) { + t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw); + t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw); -/** - * Creates a function that'll short out and invoke `identity` instead - * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` - * milliseconds. - * - * @private - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new shortable function. - */ -function shortOut(func) { - var count = 0, - lastCalled = 0; + context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01); - return function() { - var stamp = nativeNow(), - remaining = HOT_SPAN - (stamp - lastCalled); + // Have the corners merged? + if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw); - lastCalled = stamp; - if (remaining > 0) { - if (++count >= HOT_COUNT) { - return arguments[0]; + // Otherwise, draw the two corners and the ring. + else { + context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw); + context.arc(0, 0, r0, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), cw); + context.arc(t1.cx, t1.cy, rc0, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw); + } } - } else { - count = 0; + + // Or is the inner ring just a circular arc? + else context.arc(0, 0, r0, a10, a00, cw); } - return func.apply(undefined, arguments); - }; -} -var _shortOut = shortOut; + context.closePath(); -/** - * Sets the `toString` method of `func` to return `string`. - * - * @private - * @param {Function} func The function to modify. - * @param {Function} string The `toString` result. - * @returns {Function} Returns `func`. - */ -var setToString = _shortOut(_baseSetToString); + if (buffer) return context = null, buffer + "" || null; + } -var _setToString = setToString; + arc.centroid = function() { + var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2, + a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi / 2; + return [cos(a) * r, sin(a) * r]; + }; -/** - * The base implementation of `_.rest` which doesn't validate or coerce arguments. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @returns {Function} Returns the new function. - */ -function baseRest(func, start) { - return _setToString(_overRest(func, start, identity_1), func + ''); -} + arc.innerRadius = function(_) { + return arguments.length ? (innerRadius = typeof _ === "function" ? _ : constant$1(+_), arc) : innerRadius; + }; -var _baseRest = baseRest; + arc.outerRadius = function(_) { + return arguments.length ? (outerRadius = typeof _ === "function" ? _ : constant$1(+_), arc) : outerRadius; + }; -/** - * The base implementation of `_.findIndex` and `_.findLastIndex` without - * support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} predicate The function invoked per iteration. - * @param {number} fromIndex The index to search from. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function baseFindIndex(array, predicate, fromIndex, fromRight) { - var length = array.length, - index = fromIndex + (fromRight ? 1 : -1); + arc.cornerRadius = function(_) { + return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : constant$1(+_), arc) : cornerRadius; + }; - while ((fromRight ? index-- : ++index < length)) { - if (predicate(array[index], index, array)) { - return index; - } - } - return -1; -} + arc.padRadius = function(_) { + return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : constant$1(+_), arc) : padRadius; + }; -var _baseFindIndex = baseFindIndex; + arc.startAngle = function(_) { + return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$1(+_), arc) : startAngle; + }; -/** - * The base implementation of `_.isNaN` without support for number objects. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. - */ -function baseIsNaN(value) { - return value !== value; -} + arc.endAngle = function(_) { + return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$1(+_), arc) : endAngle; + }; -var _baseIsNaN = baseIsNaN; + arc.padAngle = function(_) { + return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$1(+_), arc) : padAngle; + }; -/** - * A specialized version of `_.indexOf` which performs strict equality - * comparisons of values, i.e. `===`. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function strictIndexOf(array, value, fromIndex) { - var index = fromIndex - 1, - length = array.length; + arc.context = function(_) { + return arguments.length ? ((context = _ == null ? null : _), arc) : context; + }; - while (++index < length) { - if (array[index] === value) { - return index; - } - } - return -1; + return arc; } -var _strictIndexOf = strictIndexOf; +var slice = Array.prototype.slice; -/** - * The base implementation of `_.indexOf` without `fromIndex` bounds checks. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function baseIndexOf(array, value, fromIndex) { - return value === value - ? _strictIndexOf(array, value, fromIndex) - : _baseFindIndex(array, _baseIsNaN, fromIndex); +function array(x) { + return typeof x === "object" && "length" in x + ? x // Array, TypedArray, NodeList, array-like + : Array.from(x); // Map, Set, iterable, string, or anything else } -var _baseIndexOf = baseIndexOf; - -/** - * A specialized version of `_.includes` for arrays without support for - * specifying an index to search from. - * - * @private - * @param {Array} [array] The array to inspect. - * @param {*} target The value to search for. - * @returns {boolean} Returns `true` if `target` is found, else `false`. - */ -function arrayIncludes(array, value) { - var length = array == null ? 0 : array.length; - return !!length && _baseIndexOf(array, value, 0) > -1; +function Linear(context) { + this._context = context; } -var _arrayIncludes = arrayIncludes; - -/** - * This function is like `arrayIncludes` except that it accepts a comparator. - * - * @private - * @param {Array} [array] The array to inspect. - * @param {*} target The value to search for. - * @param {Function} comparator The comparator invoked per element. - * @returns {boolean} Returns `true` if `target` is found, else `false`. - */ -function arrayIncludesWith(array, value, comparator) { - var index = -1, - length = array == null ? 0 : array.length; - - while (++index < length) { - if (comparator(value, array[index])) { - return true; +Linear.prototype = { + areaStart: function() { + this._line = 0; + }, + areaEnd: function() { + this._line = NaN; + }, + lineStart: function() { + this._point = 0; + }, + lineEnd: function() { + if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); + this._line = 1 - this._line; + }, + point: function(x, y) { + x = +x, y = +y; + switch (this._point) { + case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; + case 1: this._point = 2; // proceed + default: this._context.lineTo(x, y); break; } } - return false; -} +}; -var _arrayIncludesWith = arrayIncludesWith; +function curveLinear(context) { + return new Linear(context); +} -/** - * This method returns `undefined`. - * - * @static - * @memberOf _ - * @since 2.3.0 - * @category Util - * @example - * - * _.times(2, _.noop); - * // => [undefined, undefined] - */ -function noop() { - // No operation performed. +function x(p) { + return p[0]; } -var noop_1 = noop; +function y(p) { + return p[1]; +} -/** Used as references for various `Number` constants. */ -var INFINITY = 1 / 0; +function line(x$1, y$1) { + var defined = constant$1(true), + context = null, + curve = curveLinear, + output = null; -/** - * Creates a set object of `values`. - * - * @private - * @param {Array} values The values to add to the set. - * @returns {Object} Returns the new set. - */ -var createSet = !(_Set && (1 / _setToArray(new _Set([,-0]))[1]) == INFINITY) ? noop_1 : function(values) { - return new _Set(values); -}; + x$1 = typeof x$1 === "function" ? x$1 : (x$1 === undefined) ? x : constant$1(x$1); + y$1 = typeof y$1 === "function" ? y$1 : (y$1 === undefined) ? y : constant$1(y$1); -var _createSet = createSet; + function line(data) { + var i, + n = (data = array(data)).length, + d, + defined0 = false, + buffer; -/** Used as the size to enable large array optimizations. */ -var LARGE_ARRAY_SIZE = 200; + if (context == null) output = curve(buffer = path()); -/** - * The base implementation of `_.uniqBy` without support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new duplicate free array. - */ -function baseUniq(array, iteratee, comparator) { - var index = -1, - includes = _arrayIncludes, - length = array.length, - isCommon = true, - result = [], - seen = result; - - if (comparator) { - isCommon = false; - includes = _arrayIncludesWith; - } - else if (length >= LARGE_ARRAY_SIZE) { - var set = iteratee ? null : _createSet(array); - if (set) { - return _setToArray(set); - } - isCommon = false; - includes = _cacheHas; - seen = new _SetCache; - } - else { - seen = iteratee ? [] : result; - } - outer: - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value) : value; - - value = (comparator || value !== 0) ? value : 0; - if (isCommon && computed === computed) { - var seenIndex = seen.length; - while (seenIndex--) { - if (seen[seenIndex] === computed) { - continue outer; - } - } - if (iteratee) { - seen.push(computed); - } - result.push(value); - } - else if (!includes(seen, computed, comparator)) { - if (seen !== result) { - seen.push(computed); + for (i = 0; i <= n; ++i) { + if (!(i < n && defined(d = data[i], i, data)) === defined0) { + if (defined0 = !defined0) output.lineStart(); + else output.lineEnd(); } - result.push(value); + if (defined0) output.point(+x$1(d, i, data), +y$1(d, i, data)); } + + if (buffer) return output = null, buffer + "" || null; } - return result; -} -var _baseUniq = baseUniq; + line.x = function(_) { + return arguments.length ? (x$1 = typeof _ === "function" ? _ : constant$1(+_), line) : x$1; + }; -/** - * This method is like `_.isArrayLike` except that it also checks if `value` - * is an object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array-like object, - * else `false`. - * @example - * - * _.isArrayLikeObject([1, 2, 3]); - * // => true - * - * _.isArrayLikeObject(document.body.children); - * // => true - * - * _.isArrayLikeObject('abc'); - * // => false - * - * _.isArrayLikeObject(_.noop); - * // => false - */ -function isArrayLikeObject(value) { - return isObjectLike_1(value) && isArrayLike_1(value); -} + line.y = function(_) { + return arguments.length ? (y$1 = typeof _ === "function" ? _ : constant$1(+_), line) : y$1; + }; -var isArrayLikeObject_1 = isArrayLikeObject; + line.defined = function(_) { + return arguments.length ? (defined = typeof _ === "function" ? _ : constant$1(!!_), line) : defined; + }; -/** - * Creates an array of unique values, in order, from all given arrays using - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of combined values. - * @example - * - * _.union([2], [1, 2]); - * // => [2, 1] - */ -var union = _baseRest(function(arrays) { - return _baseUniq(_baseFlatten(arrays, 1, isArrayLikeObject_1, true)); -}); + line.curve = function(_) { + return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve; + }; -var union_1 = union; + line.context = function(_) { + return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context; + }; -/** - * The base implementation of `_.values` and `_.valuesIn` which creates an - * array of `object` property values corresponding to the property names - * of `props`. - * - * @private - * @param {Object} object The object to query. - * @param {Array} props The property names to get values for. - * @returns {Object} Returns the array of property values. - */ -function baseValues(object, props) { - return _arrayMap(props, function(key) { - return object[key]; - }); + return line; } -var _baseValues = baseValues; +var curveRadialLinear = curveRadial(curveLinear); -/** - * Creates an array of the own enumerable string keyed property values of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property values. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.values(new Foo); - * // => [1, 2] (iteration order is not guaranteed) - * - * _.values('hi'); - * // => ['h', 'i'] - */ -function values(object) { - return object == null ? [] : _baseValues(object, keys_1(object)); +function Radial(curve) { + this._curve = curve; } -var values_1 = values; - -/* global window */ - -var lodash; - -if (typeof commonjsRequire === "function") { - try { - lodash = { - clone: clone_1, - constant: constant_1, - each: each, - filter: filter_1, - has: has_1, - isArray: isArray_1, - isEmpty: isEmpty_1, - isFunction: isFunction_1, - isUndefined: isUndefined_1, - keys: keys_1, - map: map_1, - reduce: reduce_1, - size: size_1, - transform: transform_1, - union: union_1, - values: values_1 - }; - } catch (e) { - // continue regardless of error +Radial.prototype = { + areaStart: function() { + this._curve.areaStart(); + }, + areaEnd: function() { + this._curve.areaEnd(); + }, + lineStart: function() { + this._curve.lineStart(); + }, + lineEnd: function() { + this._curve.lineEnd(); + }, + point: function(a, r) { + this._curve.point(r * Math.sin(a), r * -Math.cos(a)); } -} - -if (!lodash) { - lodash = window._; -} - -var lodash_1 = lodash; - -var graph = Graph; - -var DEFAULT_EDGE_NAME = "\x00"; -var GRAPH_NODE = "\x00"; -var EDGE_KEY_DELIM = "\x01"; - -// Implementation notes: -// -// * Node id query functions should return string ids for the nodes -// * Edge id query functions should return an "edgeObj", edge object, that is -// composed of enough information to uniquely identify an edge: {v, w, name}. -// * Internally we use an "edgeId", a stringified form of the edgeObj, to -// reference edges. This is because we need a performant way to look these -// edges up and, object properties, which have string keys, are the closest -// we're going to get to a performant hashtable in JavaScript. - -function Graph(opts) { - this._isDirected = lodash_1.has(opts, "directed") ? opts.directed : true; - this._isMultigraph = lodash_1.has(opts, "multigraph") ? opts.multigraph : false; - this._isCompound = lodash_1.has(opts, "compound") ? opts.compound : false; - - // Label for the graph itself - this._label = undefined; - - // Defaults to be set when creating a new node - this._defaultNodeLabelFn = lodash_1.constant(undefined); - - // Defaults to be set when creating a new edge - this._defaultEdgeLabelFn = lodash_1.constant(undefined); - - // v -> label - this._nodes = {}; +}; - if (this._isCompound) { - // v -> parent - this._parent = {}; +function curveRadial(curve) { - // v -> children - this._children = {}; - this._children[GRAPH_NODE] = {}; + function radial(context) { + return new Radial(curve(context)); } - // v -> edgeObj - this._in = {}; + radial._curve = curve; - // u -> v -> Number - this._preds = {}; + return radial; +} - // v -> edgeObj - this._out = {}; +function lineRadial(l) { + var c = l.curve; - // v -> w -> Number - this._sucs = {}; + l.angle = l.x, delete l.x; + l.radius = l.y, delete l.y; - // e -> edgeObj - this._edgeObjs = {}; + l.curve = function(_) { + return arguments.length ? c(curveRadial(_)) : c()._curve; + }; - // e -> label - this._edgeLabels = {}; + return l; } -/* Number of nodes in the graph. Should only be changed by the implementation. */ -Graph.prototype._nodeCount = 0; - -/* Number of edges in the graph. Should only be changed by the implementation. */ -Graph.prototype._edgeCount = 0; +function lineRadial$1() { + return lineRadial(line().curve(curveRadialLinear)); +} +function linkSource(d) { + return d.source; +} -/* === Graph functions ========= */ +function linkTarget(d) { + return d.target; +} -Graph.prototype.isDirected = function() { - return this._isDirected; -}; +function link(curve) { + var source = linkSource, + target = linkTarget, + x$1 = x, + y$1 = y, + context = null; -Graph.prototype.isMultigraph = function() { - return this._isMultigraph; -}; + function link() { + var buffer, argv = slice.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv); + if (!context) context = buffer = path(); + curve(context, +x$1.apply(this, (argv[0] = s, argv)), +y$1.apply(this, argv), +x$1.apply(this, (argv[0] = t, argv)), +y$1.apply(this, argv)); + if (buffer) return context = null, buffer + "" || null; + } -Graph.prototype.isCompound = function() { - return this._isCompound; -}; + link.source = function(_) { + return arguments.length ? (source = _, link) : source; + }; -Graph.prototype.setGraph = function(label) { - this._label = label; - return this; -}; + link.target = function(_) { + return arguments.length ? (target = _, link) : target; + }; -Graph.prototype.graph = function() { - return this._label; -}; + link.x = function(_) { + return arguments.length ? (x$1 = typeof _ === "function" ? _ : constant$1(+_), link) : x$1; + }; + link.y = function(_) { + return arguments.length ? (y$1 = typeof _ === "function" ? _ : constant$1(+_), link) : y$1; + }; -/* === Node functions ========== */ + link.context = function(_) { + return arguments.length ? ((context = _ == null ? null : _), link) : context; + }; -Graph.prototype.setDefaultNodeLabel = function(newDefault) { - if (!lodash_1.isFunction(newDefault)) { - newDefault = lodash_1.constant(newDefault); - } - this._defaultNodeLabelFn = newDefault; - return this; -}; + return link; +} -Graph.prototype.nodeCount = function() { - return this._nodeCount; -}; +function curveHorizontal(context, x0, y0, x1, y1) { + context.moveTo(x0, y0); + context.bezierCurveTo(x0 = (x0 + x1) / 2, y0, x0, y1, x1, y1); +} -Graph.prototype.nodes = function() { - return lodash_1.keys(this._nodes); -}; +function linkHorizontal() { + return link(curveHorizontal); +} -Graph.prototype.sources = function() { - var self = this; - return lodash_1.filter(this.nodes(), function(v) { - return lodash_1.isEmpty(self._in[v]); - }); -}; +function point(that, x, y) { + that._context.bezierCurveTo( + (2 * that._x0 + that._x1) / 3, + (2 * that._y0 + that._y1) / 3, + (that._x0 + 2 * that._x1) / 3, + (that._y0 + 2 * that._y1) / 3, + (that._x0 + 4 * that._x1 + x) / 6, + (that._y0 + 4 * that._y1 + y) / 6 + ); +} -Graph.prototype.sinks = function() { - var self = this; - return lodash_1.filter(this.nodes(), function(v) { - return lodash_1.isEmpty(self._out[v]); - }); -}; +function Basis(context) { + this._context = context; +} -Graph.prototype.setNodes = function(vs, value) { - var args = arguments; - var self = this; - lodash_1.each(vs, function(v) { - if (args.length > 1) { - self.setNode(v, value); - } else { - self.setNode(v); +Basis.prototype = { + areaStart: function() { + this._line = 0; + }, + areaEnd: function() { + this._line = NaN; + }, + lineStart: function() { + this._x0 = this._x1 = + this._y0 = this._y1 = NaN; + this._point = 0; + }, + lineEnd: function() { + switch (this._point) { + case 3: point(this, this._x1, this._y1); // proceed + case 2: this._context.lineTo(this._x1, this._y1); break; } - }); - return this; -}; - -Graph.prototype.setNode = function(v, value) { - if (lodash_1.has(this._nodes, v)) { - if (arguments.length > 1) { - this._nodes[v] = value; + if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); + this._line = 1 - this._line; + }, + point: function(x, y) { + x = +x, y = +y; + switch (this._point) { + case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; + case 1: this._point = 2; break; + case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed + default: point(this, x, y); break; } - return this; - } - - this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v); - if (this._isCompound) { - this._parent[v] = GRAPH_NODE; - this._children[v] = {}; - this._children[GRAPH_NODE][v] = true; + this._x0 = this._x1, this._x1 = x; + this._y0 = this._y1, this._y1 = y; } - this._in[v] = {}; - this._preds[v] = {}; - this._out[v] = {}; - this._sucs[v] = {}; - ++this._nodeCount; - return this; -}; - -Graph.prototype.node = function(v) { - return this._nodes[v]; }; -Graph.prototype.hasNode = function(v) { - return lodash_1.has(this._nodes, v); -}; +function Bundle(context, beta) { + this._basis = new Basis(context); + this._beta = beta; +} -Graph.prototype.removeNode = function(v) { - var self = this; - if (lodash_1.has(this._nodes, v)) { - var removeEdge = function(e) { self.removeEdge(self._edgeObjs[e]); }; - delete this._nodes[v]; - if (this._isCompound) { - this._removeFromParentsChildList(v); - delete this._parent[v]; - lodash_1.each(this.children(v), function(child) { - self.setParent(child); - }); - delete this._children[v]; - } - lodash_1.each(lodash_1.keys(this._in[v]), removeEdge); - delete this._in[v]; - delete this._preds[v]; - lodash_1.each(lodash_1.keys(this._out[v]), removeEdge); - delete this._out[v]; - delete this._sucs[v]; - --this._nodeCount; - } - return this; -}; +Bundle.prototype = { + lineStart: function() { + this._x = []; + this._y = []; + this._basis.lineStart(); + }, + lineEnd: function() { + var x = this._x, + y = this._y, + j = x.length - 1; -Graph.prototype.setParent = function(v, parent) { - if (!this._isCompound) { - throw new Error("Cannot set parent in a non-compound graph"); - } + if (j > 0) { + var x0 = x[0], + y0 = y[0], + dx = x[j] - x0, + dy = y[j] - y0, + i = -1, + t; - if (lodash_1.isUndefined(parent)) { - parent = GRAPH_NODE; - } else { - // Coerce parent to string - parent += ""; - for (var ancestor = parent; - !lodash_1.isUndefined(ancestor); - ancestor = this.parent(ancestor)) { - if (ancestor === v) { - throw new Error("Setting " + parent+ " as parent of " + v + - " would create a cycle"); + while (++i <= j) { + t = i / j; + this._basis.point( + this._beta * x[i] + (1 - this._beta) * (x0 + t * dx), + this._beta * y[i] + (1 - this._beta) * (y0 + t * dy) + ); } } - this.setNode(parent); - } - - this.setNode(v); - this._removeFromParentsChildList(v); - this._parent[v] = parent; - this._children[parent][v] = true; - return this; -}; - -Graph.prototype._removeFromParentsChildList = function(v) { - delete this._children[this._parent[v]][v]; -}; - -Graph.prototype.parent = function(v) { - if (this._isCompound) { - var parent = this._parent[v]; - if (parent !== GRAPH_NODE) { - return parent; - } - } -}; - -Graph.prototype.children = function(v) { - if (lodash_1.isUndefined(v)) { - v = GRAPH_NODE; - } - - if (this._isCompound) { - var children = this._children[v]; - if (children) { - return lodash_1.keys(children); - } - } else if (v === GRAPH_NODE) { - return this.nodes(); - } else if (this.hasNode(v)) { - return []; - } -}; - -Graph.prototype.predecessors = function(v) { - var predsV = this._preds[v]; - if (predsV) { - return lodash_1.keys(predsV); - } -}; - -Graph.prototype.successors = function(v) { - var sucsV = this._sucs[v]; - if (sucsV) { - return lodash_1.keys(sucsV); - } -}; - -Graph.prototype.neighbors = function(v) { - var preds = this.predecessors(v); - if (preds) { - return lodash_1.union(preds, this.successors(v)); - } -}; - -Graph.prototype.isLeaf = function (v) { - var neighbors; - if (this.isDirected()) { - neighbors = this.successors(v); - } else { - neighbors = this.neighbors(v); + this._x = this._y = null; + this._basis.lineEnd(); + }, + point: function(x, y) { + this._x.push(+x); + this._y.push(+y); } - return neighbors.length === 0; }; -Graph.prototype.filterNodes = function(filter) { - var copy = new this.constructor({ - directed: this._isDirected, - multigraph: this._isMultigraph, - compound: this._isCompound - }); - - copy.setGraph(this.graph()); - - var self = this; - lodash_1.each(this._nodes, function(value, v) { - if (filter(v)) { - copy.setNode(v, value); - } - }); - - lodash_1.each(this._edgeObjs, function(e) { - if (copy.hasNode(e.v) && copy.hasNode(e.w)) { - copy.setEdge(e, self.edge(e)); - } - }); - - var parents = {}; - function findParent(v) { - var parent = self.parent(v); - if (parent === undefined || copy.hasNode(parent)) { - parents[v] = parent; - return parent; - } else if (parent in parents) { - return parents[parent]; - } else { - return findParent(parent); - } - } +var bundle = (function custom(beta) { - if (this._isCompound) { - lodash_1.each(copy.nodes(), function(v) { - copy.setParent(v, findParent(v)); - }); + function bundle(context) { + return beta === 1 ? new Basis(context) : new Bundle(context, beta); } - return copy; -}; - -/* === Edge functions ========== */ - -Graph.prototype.setDefaultEdgeLabel = function(newDefault) { - if (!lodash_1.isFunction(newDefault)) { - newDefault = lodash_1.constant(newDefault); - } - this._defaultEdgeLabelFn = newDefault; - return this; -}; + bundle.beta = function(beta) { + return custom(+beta); + }; -Graph.prototype.edgeCount = function() { - return this._edgeCount; -}; + return bundle; +})(0.85); -Graph.prototype.edges = function() { - return lodash_1.values(this._edgeObjs); -}; +var constant = x => () => x; -Graph.prototype.setPath = function(vs, value) { - var self = this; - var args = arguments; - lodash_1.reduce(vs, function(v, w) { - if (args.length > 1) { - self.setEdge(v, w, value); - } else { - self.setEdge(v, w); - } - return w; +function ZoomEvent(type, { + sourceEvent, + target, + transform, + dispatch +}) { + Object.defineProperties(this, { + type: {value: type, enumerable: true, configurable: true}, + sourceEvent: {value: sourceEvent, enumerable: true, configurable: true}, + target: {value: target, enumerable: true, configurable: true}, + transform: {value: transform, enumerable: true, configurable: true}, + _: {value: dispatch} }); - return this; -}; - -/* - * setEdge(v, w, [value, [name]]) - * setEdge({ v, w, [name] }, [value]) - */ -Graph.prototype.setEdge = function() { - var v, w, name, value; - var valueSpecified = false; - var arg0 = arguments[0]; - - if (typeof arg0 === "object" && arg0 !== null && "v" in arg0) { - v = arg0.v; - w = arg0.w; - name = arg0.name; - if (arguments.length === 2) { - value = arguments[1]; - valueSpecified = true; - } - } else { - v = arg0; - w = arguments[1]; - name = arguments[3]; - if (arguments.length > 2) { - value = arguments[2]; - valueSpecified = true; - } - } - - v = "" + v; - w = "" + w; - if (!lodash_1.isUndefined(name)) { - name = "" + name; - } - - var e = edgeArgsToId(this._isDirected, v, w, name); - if (lodash_1.has(this._edgeLabels, e)) { - if (valueSpecified) { - this._edgeLabels[e] = value; - } - return this; - } - - if (!lodash_1.isUndefined(name) && !this._isMultigraph) { - throw new Error("Cannot set a named edge when isMultigraph = false"); - } - - // It didn't exist, so we need to create it. - // First ensure the nodes exist. - this.setNode(v); - this.setNode(w); - - this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name); - - var edgeObj = edgeArgsToObj(this._isDirected, v, w, name); - // Ensure we add undirected edges in a consistent way. - v = edgeObj.v; - w = edgeObj.w; - - Object.freeze(edgeObj); - this._edgeObjs[e] = edgeObj; - incrementOrInitEntry(this._preds[w], v); - incrementOrInitEntry(this._sucs[v], w); - this._in[w][e] = edgeObj; - this._out[v][e] = edgeObj; - this._edgeCount++; - return this; -}; - -Graph.prototype.edge = function(v, w, name) { - var e = (arguments.length === 1 - ? edgeObjToId(this._isDirected, arguments[0]) - : edgeArgsToId(this._isDirected, v, w, name)); - return this._edgeLabels[e]; -}; - -Graph.prototype.hasEdge = function(v, w, name) { - var e = (arguments.length === 1 - ? edgeObjToId(this._isDirected, arguments[0]) - : edgeArgsToId(this._isDirected, v, w, name)); - return lodash_1.has(this._edgeLabels, e); -}; - -Graph.prototype.removeEdge = function(v, w, name) { - var e = (arguments.length === 1 - ? edgeObjToId(this._isDirected, arguments[0]) - : edgeArgsToId(this._isDirected, v, w, name)); - var edge = this._edgeObjs[e]; - if (edge) { - v = edge.v; - w = edge.w; - delete this._edgeLabels[e]; - delete this._edgeObjs[e]; - decrementOrRemoveEntry(this._preds[w], v); - decrementOrRemoveEntry(this._sucs[v], w); - delete this._in[w][e]; - delete this._out[v][e]; - this._edgeCount--; - } - return this; -}; +} -Graph.prototype.inEdges = function(v, u) { - var inV = this._in[v]; - if (inV) { - var edges = lodash_1.values(inV); - if (!u) { - return edges; - } - return lodash_1.filter(edges, function(edge) { return edge.v === u; }); - } -}; +function Transform(k, x, y) { + this.k = k; + this.x = x; + this.y = y; +} -Graph.prototype.outEdges = function(v, w) { - var outV = this._out[v]; - if (outV) { - var edges = lodash_1.values(outV); - if (!w) { - return edges; - } - return lodash_1.filter(edges, function(edge) { return edge.w === w; }); +Transform.prototype = { + constructor: Transform, + scale: function(k) { + return k === 1 ? this : new Transform(this.k * k, this.x, this.y); + }, + translate: function(x, y) { + return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y); + }, + apply: function(point) { + return [point[0] * this.k + this.x, point[1] * this.k + this.y]; + }, + applyX: function(x) { + return x * this.k + this.x; + }, + applyY: function(y) { + return y * this.k + this.y; + }, + invert: function(location) { + return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k]; + }, + invertX: function(x) { + return (x - this.x) / this.k; + }, + invertY: function(y) { + return (y - this.y) / this.k; + }, + rescaleX: function(x) { + return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x)); + }, + rescaleY: function(y) { + return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y)); + }, + toString: function() { + return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")"; } }; -Graph.prototype.nodeEdges = function(v, w) { - var inEdges = this.inEdges(v, w); - if (inEdges) { - return inEdges.concat(this.outEdges(v, w)); - } -}; +var identity = new Transform(1, 0, 0); -function incrementOrInitEntry(map, k) { - if (map[k]) { - map[k]++; - } else { - map[k] = 1; - } +function nopropagation(event) { + event.stopImmediatePropagation(); } -function decrementOrRemoveEntry(map, k) { - if (!--map[k]) { delete map[k]; } +function noevent(event) { + event.preventDefault(); + event.stopImmediatePropagation(); } -function edgeArgsToId(isDirected, v_, w_, name) { - var v = "" + v_; - var w = "" + w_; - if (!isDirected && v > w) { - var tmp = v; - v = w; - w = tmp; - } - return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM + - (lodash_1.isUndefined(name) ? DEFAULT_EDGE_NAME : name); +// Ignore right-click, since that should open the context menu. +// except for pinch-to-zoom, which is sent as a wheel+ctrlKey event +function defaultFilter(event) { + return (!event.ctrlKey || event.type === 'wheel') && !event.button; } -function edgeArgsToObj(isDirected, v_, w_, name) { - var v = "" + v_; - var w = "" + w_; - if (!isDirected && v > w) { - var tmp = v; - v = w; - w = tmp; - } - var edgeObj = { v: v, w: w }; - if (name) { - edgeObj.name = name; +function defaultExtent() { + var e = this; + if (e instanceof SVGElement) { + e = e.ownerSVGElement || e; + if (e.hasAttribute("viewBox")) { + e = e.viewBox.baseVal; + return [[e.x, e.y], [e.x + e.width, e.y + e.height]]; + } + return [[0, 0], [e.width.baseVal.value, e.height.baseVal.value]]; } - return edgeObj; -} - -function edgeObjToId(isDirected, edgeObj) { - return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name); + return [[0, 0], [e.clientWidth, e.clientHeight]]; } -var version = '2.1.8'; - -// Includes only the "core" of graphlib -var lib = { - Graph: graph, - version: version -}; - -var json = { - write: write, - read: read -}; - -function write(g) { - var json = { - options: { - directed: g.isDirected(), - multigraph: g.isMultigraph(), - compound: g.isCompound() - }, - nodes: writeNodes(g), - edges: writeEdges(g) - }; - if (!lodash_1.isUndefined(g.graph())) { - json.value = lodash_1.clone(g.graph()); - } - return json; +function defaultTransform() { + return this.__zoom || identity; } -function writeNodes(g) { - return lodash_1.map(g.nodes(), function(v) { - var nodeValue = g.node(v); - var parent = g.parent(v); - var node = { v: v }; - if (!lodash_1.isUndefined(nodeValue)) { - node.value = nodeValue; - } - if (!lodash_1.isUndefined(parent)) { - node.parent = parent; - } - return node; - }); +function defaultWheelDelta(event) { + return -event.deltaY * (event.deltaMode === 1 ? 0.05 : event.deltaMode ? 1 : 0.002) * (event.ctrlKey ? 10 : 1); } -function writeEdges(g) { - return lodash_1.map(g.edges(), function(e) { - var edgeValue = g.edge(e); - var edge = { v: e.v, w: e.w }; - if (!lodash_1.isUndefined(e.name)) { - edge.name = e.name; - } - if (!lodash_1.isUndefined(edgeValue)) { - edge.value = edgeValue; - } - return edge; - }); +function defaultTouchable() { + return navigator.maxTouchPoints || ("ontouchstart" in this); } -function read(json) { - var g = new graph(json.options).setGraph(json.value); - lodash_1.each(json.nodes, function(entry) { - g.setNode(entry.v, entry.value); - if (entry.parent) { - g.setParent(entry.v, entry.parent); - } - }); - lodash_1.each(json.edges, function(entry) { - g.setEdge({ v: entry.v, w: entry.w, name: entry.name }, entry.value); - }); - return g; +function defaultConstrain(transform, extent, translateExtent) { + var dx0 = transform.invertX(extent[0][0]) - translateExtent[0][0], + dx1 = transform.invertX(extent[1][0]) - translateExtent[1][0], + dy0 = transform.invertY(extent[0][1]) - translateExtent[0][1], + dy1 = transform.invertY(extent[1][1]) - translateExtent[1][1]; + return transform.translate( + dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1), + dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1) + ); } -var components_1 = components; - -function components(g) { - var visited = {}; - var cmpts = []; - var cmpt; +function zoom() { + var filter = defaultFilter, + extent = defaultExtent, + constrain = defaultConstrain, + wheelDelta = defaultWheelDelta, + touchable = defaultTouchable, + scaleExtent = [0, Infinity], + translateExtent = [[-Infinity, -Infinity], [Infinity, Infinity]], + duration = 250, + interpolate = interpolateZoom, + listeners = dispatch("start", "zoom", "end"), + touchstarting, + touchfirst, + touchending, + touchDelay = 500, + wheelDelay = 150, + clickDistance2 = 0, + tapDistance = 10; - function dfs(v) { - if (lodash_1.has(visited, v)) return; - visited[v] = true; - cmpt.push(v); - lodash_1.each(g.successors(v), dfs); - lodash_1.each(g.predecessors(v), dfs); + function zoom(selection) { + selection + .property("__zoom", defaultTransform) + .on("wheel.zoom", wheeled) + .on("mousedown.zoom", mousedowned) + .on("dblclick.zoom", dblclicked) + .filter(touchable) + .on("touchstart.zoom", touchstarted) + .on("touchmove.zoom", touchmoved) + .on("touchend.zoom touchcancel.zoom", touchended) + .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)"); } - lodash_1.each(g.nodes(), function(v) { - cmpt = []; - dfs(v); - if (cmpt.length) { - cmpts.push(cmpt); + zoom.transform = function(collection, transform, point, event) { + var selection = collection.selection ? collection.selection() : collection; + selection.property("__zoom", defaultTransform); + if (collection !== selection) { + schedule(collection, transform, point, event); + } else { + selection.interrupt().each(function() { + gesture(this, arguments) + .event(event) + .start() + .zoom(null, typeof transform === "function" ? transform.apply(this, arguments) : transform) + .end(); + }); } - }); - - return cmpts; -} - -var priorityQueue = PriorityQueue; + }; -/** - * A min-priority queue data structure. This algorithm is derived from Cormen, - * et al., "Introduction to Algorithms". The basic idea of a min-priority - * queue is that you can efficiently (in O(1) time) get the smallest key in - * the queue. Adding and removing elements takes O(log n) time. A key can - * have its priority decreased in O(log n) time. - */ -function PriorityQueue() { - this._arr = []; - this._keyIndices = {}; -} + zoom.scaleBy = function(selection, k, p, event) { + zoom.scaleTo(selection, function() { + var k0 = this.__zoom.k, + k1 = typeof k === "function" ? k.apply(this, arguments) : k; + return k0 * k1; + }, p, event); + }; -/** - * Returns the number of elements in the queue. Takes `O(1)` time. - */ -PriorityQueue.prototype.size = function() { - return this._arr.length; -}; + zoom.scaleTo = function(selection, k, p, event) { + zoom.transform(selection, function() { + var e = extent.apply(this, arguments), + t0 = this.__zoom, + p0 = p == null ? centroid(e) : typeof p === "function" ? p.apply(this, arguments) : p, + p1 = t0.invert(p0), + k1 = typeof k === "function" ? k.apply(this, arguments) : k; + return constrain(translate(scale(t0, k1), p0, p1), e, translateExtent); + }, p, event); + }; -/** - * Returns the keys that are in the queue. Takes `O(n)` time. - */ -PriorityQueue.prototype.keys = function() { - return this._arr.map(function(x) { return x.key; }); -}; + zoom.translateBy = function(selection, x, y, event) { + zoom.transform(selection, function() { + return constrain(this.__zoom.translate( + typeof x === "function" ? x.apply(this, arguments) : x, + typeof y === "function" ? y.apply(this, arguments) : y + ), extent.apply(this, arguments), translateExtent); + }, null, event); + }; -/** - * Returns `true` if **key** is in the queue and `false` if not. - */ -PriorityQueue.prototype.has = function(key) { - return lodash_1.has(this._keyIndices, key); -}; + zoom.translateTo = function(selection, x, y, p, event) { + zoom.transform(selection, function() { + var e = extent.apply(this, arguments), + t = this.__zoom, + p0 = p == null ? centroid(e) : typeof p === "function" ? p.apply(this, arguments) : p; + return constrain(identity.translate(p0[0], p0[1]).scale(t.k).translate( + typeof x === "function" ? -x.apply(this, arguments) : -x, + typeof y === "function" ? -y.apply(this, arguments) : -y + ), e, translateExtent); + }, p, event); + }; -/** - * Returns the priority for **key**. If **key** is not present in the queue - * then this function returns `undefined`. Takes `O(1)` time. - * - * @param {Object} key - */ -PriorityQueue.prototype.priority = function(key) { - var index = this._keyIndices[key]; - if (index !== undefined) { - return this._arr[index].priority; + function scale(transform, k) { + k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], k)); + return k === transform.k ? transform : new Transform(k, transform.x, transform.y); } -}; -/** - * Returns the key for the minimum element in this queue. If the queue is - * empty this function throws an Error. Takes `O(1)` time. - */ -PriorityQueue.prototype.min = function() { - if (this.size() === 0) { - throw new Error("Queue underflow"); + function translate(transform, p0, p1) { + var x = p0[0] - p1[0] * transform.k, y = p0[1] - p1[1] * transform.k; + return x === transform.x && y === transform.y ? transform : new Transform(transform.k, x, y); } - return this._arr[0].key; -}; -/** - * Inserts a new key into the priority queue. If the key already exists in - * the queue this function returns `false`; otherwise it will return `true`. - * Takes `O(n)` time. - * - * @param {Object} key the key to add - * @param {Number} priority the initial priority for the key - */ -PriorityQueue.prototype.add = function(key, priority) { - var keyIndices = this._keyIndices; - key = String(key); - if (!lodash_1.has(keyIndices, key)) { - var arr = this._arr; - var index = arr.length; - keyIndices[key] = index; - arr.push({key: key, priority: priority}); - this._decrease(index); - return true; + function centroid(extent) { + return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1][1]) / 2]; } - return false; -}; - -/** - * Removes and returns the smallest key in the queue. Takes `O(log n)` time. - */ -PriorityQueue.prototype.removeMin = function() { - this._swap(0, this._arr.length - 1); - var min = this._arr.pop(); - delete this._keyIndices[min.key]; - this._heapify(0); - return min.key; -}; -/** - * Decreases the priority for **key** to **priority**. If the new priority is - * greater than the previous priority, this function will throw an Error. - * - * @param {Object} key the key for which to raise priority - * @param {Number} priority the new priority for the key - */ -PriorityQueue.prototype.decrease = function(key, priority) { - var index = this._keyIndices[key]; - if (priority > this._arr[index].priority) { - throw new Error("New priority is greater than current priority. " + - "Key: " + key + " Old: " + this._arr[index].priority + " New: " + priority); + function schedule(transition, transform, point, event) { + transition + .on("start.zoom", function() { gesture(this, arguments).event(event).start(); }) + .on("interrupt.zoom end.zoom", function() { gesture(this, arguments).event(event).end(); }) + .tween("zoom", function() { + var that = this, + args = arguments, + g = gesture(that, args).event(event), + e = extent.apply(that, args), + p = point == null ? centroid(e) : typeof point === "function" ? point.apply(that, args) : point, + w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]), + a = that.__zoom, + b = typeof transform === "function" ? transform.apply(that, args) : transform, + i = interpolate(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k)); + return function(t) { + if (t === 1) t = b; // Avoid rounding error on end. + else { var l = i(t), k = w / l[2]; t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k); } + g.zoom(null, t); + }; + }); } - this._arr[index].priority = priority; - this._decrease(index); -}; -PriorityQueue.prototype._heapify = function(i) { - var arr = this._arr; - var l = 2 * i; - var r = l + 1; - var largest = i; - if (l < arr.length) { - largest = arr[l].priority < arr[largest].priority ? l : largest; - if (r < arr.length) { - largest = arr[r].priority < arr[largest].priority ? r : largest; - } - if (largest !== i) { - this._swap(i, largest); - this._heapify(largest); - } + function gesture(that, args, clean) { + return (!clean && that.__zooming) || new Gesture(that, args); } -}; -PriorityQueue.prototype._decrease = function(index) { - var arr = this._arr; - var priority = arr[index].priority; - var parent; - while (index !== 0) { - parent = index >> 1; - if (arr[parent].priority < priority) { - break; - } - this._swap(index, parent); - index = parent; + function Gesture(that, args) { + this.that = that; + this.args = args; + this.active = 0; + this.sourceEvent = null; + this.extent = extent.apply(that, args); + this.taps = 0; } -}; - -PriorityQueue.prototype._swap = function(i, j) { - var arr = this._arr; - var keyIndices = this._keyIndices; - var origArrI = arr[i]; - var origArrJ = arr[j]; - arr[i] = origArrJ; - arr[j] = origArrI; - keyIndices[origArrJ.key] = i; - keyIndices[origArrI.key] = j; -}; - -var dijkstra_1 = dijkstra; -var DEFAULT_WEIGHT_FUNC$1 = lodash_1.constant(1); - -function dijkstra(g, source, weightFn, edgeFn) { - return runDijkstra(g, String(source), - weightFn || DEFAULT_WEIGHT_FUNC$1, - edgeFn || function(v) { return g.outEdges(v); }); -} - -function runDijkstra(g, source, weightFn, edgeFn) { - var results = {}; - var pq = new priorityQueue(); - var v, vEntry; - - var updateNeighbors = function(edge) { - var w = edge.v !== v ? edge.v : edge.w; - var wEntry = results[w]; - var weight = weightFn(edge); - var distance = vEntry.distance + weight; - - if (weight < 0) { - throw new Error("dijkstra does not allow negative edge weights. " + - "Bad edge: " + edge + " Weight: " + weight); - } - - if (distance < wEntry.distance) { - wEntry.distance = distance; - wEntry.predecessor = v; - pq.decrease(w, distance); + Gesture.prototype = { + event: function(event) { + if (event) this.sourceEvent = event; + return this; + }, + start: function() { + if (++this.active === 1) { + this.that.__zooming = this; + this.emit("start"); + } + return this; + }, + zoom: function(key, transform) { + if (this.mouse && key !== "mouse") this.mouse[1] = transform.invert(this.mouse[0]); + if (this.touch0 && key !== "touch") this.touch0[1] = transform.invert(this.touch0[0]); + if (this.touch1 && key !== "touch") this.touch1[1] = transform.invert(this.touch1[0]); + this.that.__zoom = transform; + this.emit("zoom"); + return this; + }, + end: function() { + if (--this.active === 0) { + delete this.that.__zooming; + this.emit("end"); + } + return this; + }, + emit: function(type) { + var d = select(this.that).datum(); + listeners.call( + type, + this.that, + new ZoomEvent(type, { + sourceEvent: this.sourceEvent, + target: zoom, + type, + transform: this.that.__zoom, + dispatch: listeners + }), + d + ); } }; - g.nodes().forEach(function(v) { - var distance = v === source ? 0 : Number.POSITIVE_INFINITY; - results[v] = { distance: distance }; - pq.add(v, distance); - }); + function wheeled(event, ...args) { + if (!filter.apply(this, arguments)) return; + var g = gesture(this, args).event(event), + t = this.__zoom, + k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], t.k * Math.pow(2, wheelDelta.apply(this, arguments)))), + p = pointer(event); - while (pq.size() > 0) { - v = pq.removeMin(); - vEntry = results[v]; - if (vEntry.distance === Number.POSITIVE_INFINITY) { - break; + // If the mouse is in the same location as before, reuse it. + // If there were recent wheel events, reset the wheel idle timeout. + if (g.wheel) { + if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) { + g.mouse[1] = t.invert(g.mouse[0] = p); + } + clearTimeout(g.wheel); } - edgeFn(v).forEach(updateNeighbors); - } - - return results; -} - -var dijkstraAll_1 = dijkstraAll; - -function dijkstraAll(g, weightFunc, edgeFunc) { - return lodash_1.transform(g.nodes(), function(acc, v) { - acc[v] = dijkstra_1(g, v, weightFunc, edgeFunc); - }, {}); -} - -var tarjan_1 = tarjan; + // If this wheel event won’t trigger a transform change, ignore it. + else if (t.k === k) return; -function tarjan(g) { - var index = 0; - var stack = []; - var visited = {}; // node id -> { onStack, lowlink, index } - var results = []; - - function dfs(v) { - var entry = visited[v] = { - onStack: true, - lowlink: index, - index: index++ - }; - stack.push(v); + // Otherwise, capture the mouse point and location at the start. + else { + g.mouse = [p, t.invert(p)]; + interrupt(this); + g.start(); + } - g.successors(v).forEach(function(w) { - if (!lodash_1.has(visited, w)) { - dfs(w); - entry.lowlink = Math.min(entry.lowlink, visited[w].lowlink); - } else if (visited[w].onStack) { - entry.lowlink = Math.min(entry.lowlink, visited[w].index); - } - }); + noevent(event); + g.wheel = setTimeout(wheelidled, wheelDelay); + g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent, translateExtent)); - if (entry.lowlink === entry.index) { - var cmpt = []; - var w; - do { - w = stack.pop(); - visited[w].onStack = false; - cmpt.push(w); - } while (v !== w); - results.push(cmpt); + function wheelidled() { + g.wheel = null; + g.end(); } } - g.nodes().forEach(function(v) { - if (!lodash_1.has(visited, v)) { - dfs(v); - } - }); - - return results; -} - -var findCycles_1 = findCycles; - -function findCycles(g) { - return lodash_1.filter(tarjan_1(g), function(cmpt) { - return cmpt.length > 1 || (cmpt.length === 1 && g.hasEdge(cmpt[0], cmpt[0])); - }); -} - -var floydWarshall_1 = floydWarshall; - -var DEFAULT_WEIGHT_FUNC = lodash_1.constant(1); - -function floydWarshall(g, weightFn, edgeFn) { - return runFloydWarshall(g, - weightFn || DEFAULT_WEIGHT_FUNC, - edgeFn || function(v) { return g.outEdges(v); }); -} + function mousedowned(event, ...args) { + if (touchending || !filter.apply(this, arguments)) return; + var g = gesture(this, args, true).event(event), + v = select(event.view).on("mousemove.zoom", mousemoved, true).on("mouseup.zoom", mouseupped, true), + p = pointer(event, currentTarget), + currentTarget = event.currentTarget, + x0 = event.clientX, + y0 = event.clientY; -function runFloydWarshall(g, weightFn, edgeFn) { - var results = {}; - var nodes = g.nodes(); + dragDisable(event.view); + nopropagation(event); + g.mouse = [p, this.__zoom.invert(p)]; + interrupt(this); + g.start(); - nodes.forEach(function(v) { - results[v] = {}; - results[v][v] = { distance: 0 }; - nodes.forEach(function(w) { - if (v !== w) { - results[v][w] = { distance: Number.POSITIVE_INFINITY }; + function mousemoved(event) { + noevent(event); + if (!g.moved) { + var dx = event.clientX - x0, dy = event.clientY - y0; + g.moved = dx * dx + dy * dy > clickDistance2; } - }); - edgeFn(v).forEach(function(edge) { - var w = edge.v === v ? edge.w : edge.v; - var d = weightFn(edge); - results[v][w] = { distance: d, predecessor: v }; - }); - }); - - nodes.forEach(function(k) { - var rowK = results[k]; - nodes.forEach(function(i) { - var rowI = results[i]; - nodes.forEach(function(j) { - var ik = rowI[k]; - var kj = rowK[j]; - var ij = rowI[j]; - var altDistance = ik.distance + kj.distance; - if (altDistance < ij.distance) { - ij.distance = altDistance; - ij.predecessor = kj.predecessor; - } - }); - }); - }); - - return results; -} - -var topsort_1 = topsort; -topsort.CycleException = CycleException; - -function topsort(g) { - var visited = {}; - var stack = {}; - var results = []; - - function visit(node) { - if (lodash_1.has(stack, node)) { - throw new CycleException(); + g.event(event) + .zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] = pointer(event, currentTarget), g.mouse[1]), g.extent, translateExtent)); } - if (!lodash_1.has(visited, node)) { - stack[node] = true; - visited[node] = true; - lodash_1.each(g.predecessors(node), visit); - delete stack[node]; - results.push(node); + function mouseupped(event) { + v.on("mousemove.zoom mouseup.zoom", null); + yesdrag(event.view, g.moved); + noevent(event); + g.event(event).end(); } } - lodash_1.each(g.sinks(), visit); + function dblclicked(event, ...args) { + if (!filter.apply(this, arguments)) return; + var t0 = this.__zoom, + p0 = pointer(event.changedTouches ? event.changedTouches[0] : event, this), + p1 = t0.invert(p0), + k1 = t0.k * (event.shiftKey ? 0.5 : 2), + t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, args), translateExtent); - if (lodash_1.size(visited) !== g.nodeCount()) { - throw new CycleException(); + noevent(event); + if (duration > 0) select(this).transition().duration(duration).call(schedule, t1, p0, event); + else select(this).call(zoom.transform, t1, p0, event); } - return results; -} - -function CycleException() {} -CycleException.prototype = new Error(); // must be an instance of Error to pass testing - -var isAcyclic_1 = isAcyclic; + function touchstarted(event, ...args) { + if (!filter.apply(this, arguments)) return; + var touches = event.touches, + n = touches.length, + g = gesture(this, args, event.changedTouches.length === n).event(event), + started, i, t, p; -function isAcyclic(g) { - try { - topsort_1(g); - } catch (e) { - if (e instanceof topsort_1.CycleException) { - return false; + nopropagation(event); + for (i = 0; i < n; ++i) { + t = touches[i], p = pointer(t, this); + p = [p, this.__zoom.invert(p), t.identifier]; + if (!g.touch0) g.touch0 = p, started = true, g.taps = 1 + !!touchstarting; + else if (!g.touch1 && g.touch0[2] !== p[2]) g.touch1 = p, g.taps = 0; } - throw e; - } - return true; -} -var dfs_1 = dfs; + if (touchstarting) touchstarting = clearTimeout(touchstarting); -/* - * A helper that preforms a pre- or post-order traversal on the input graph - * and returns the nodes in the order they were visited. If the graph is - * undirected then this algorithm will navigate using neighbors. If the graph - * is directed then this algorithm will navigate using successors. - * - * Order must be one of "pre" or "post". - */ -function dfs(g, vs, order) { - if (!lodash_1.isArray(vs)) { - vs = [vs]; + if (started) { + if (g.taps < 2) touchfirst = p[0], touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay); + interrupt(this); + g.start(); + } } - var navigation = (g.isDirected() ? g.successors : g.neighbors).bind(g); + function touchmoved(event, ...args) { + if (!this.__zooming) return; + var g = gesture(this, args).event(event), + touches = event.changedTouches, + n = touches.length, i, t, p, l; - var acc = []; - var visited = {}; - lodash_1.each(vs, function(v) { - if (!g.hasNode(v)) { - throw new Error("Graph does not have node: " + v); + noevent(event); + for (i = 0; i < n; ++i) { + t = touches[i], p = pointer(t, this); + if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p; + else if (g.touch1 && g.touch1[2] === t.identifier) g.touch1[0] = p; + } + t = g.that.__zoom; + if (g.touch1) { + var p0 = g.touch0[0], l0 = g.touch0[1], + p1 = g.touch1[0], l1 = g.touch1[1], + dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp, + dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl; + t = scale(t, Math.sqrt(dp / dl)); + p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2]; + l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2]; } + else if (g.touch0) p = g.touch0[0], l = g.touch0[1]; + else return; - doDfs(g, v, order === "post", visited, navigation, acc); - }); - return acc; -} + g.zoom("touch", constrain(translate(t, p, l), g.extent, translateExtent)); + } -function doDfs(g, v, postorder, visited, navigation, acc) { - if (!lodash_1.has(visited, v)) { - visited[v] = true; + function touchended(event, ...args) { + if (!this.__zooming) return; + var g = gesture(this, args).event(event), + touches = event.changedTouches, + n = touches.length, i, t; - if (!postorder) { acc.push(v); } - lodash_1.each(navigation(v), function(w) { - doDfs(g, w, postorder, visited, navigation, acc); - }); - if (postorder) { acc.push(v); } + nopropagation(event); + if (touchending) clearTimeout(touchending); + touchending = setTimeout(function() { touchending = null; }, touchDelay); + for (i = 0; i < n; ++i) { + t = touches[i]; + if (g.touch0 && g.touch0[2] === t.identifier) delete g.touch0; + else if (g.touch1 && g.touch1[2] === t.identifier) delete g.touch1; + } + if (g.touch1 && !g.touch0) g.touch0 = g.touch1, delete g.touch1; + if (g.touch0) g.touch0[1] = this.__zoom.invert(g.touch0[0]); + else { + g.end(); + // If this was a dbltap, reroute to the (optional) dblclick.zoom handler. + if (g.taps === 2) { + t = pointer(t, this); + if (Math.hypot(touchfirst[0] - t[0], touchfirst[1] - t[1]) < tapDistance) { + var p = select(this).on("dblclick.zoom"); + if (p) p.apply(this, arguments); + } + } + } } -} -var postorder_1 = postorder; + zoom.wheelDelta = function(_) { + return arguments.length ? (wheelDelta = typeof _ === "function" ? _ : constant(+_), zoom) : wheelDelta; + }; -function postorder(g, vs) { - return dfs_1(g, vs, "post"); -} + zoom.filter = function(_) { + return arguments.length ? (filter = typeof _ === "function" ? _ : constant(!!_), zoom) : filter; + }; -var preorder_1 = preorder; + zoom.touchable = function(_) { + return arguments.length ? (touchable = typeof _ === "function" ? _ : constant(!!_), zoom) : touchable; + }; -function preorder(g, vs) { - return dfs_1(g, vs, "pre"); -} + zoom.extent = function(_) { + return arguments.length ? (extent = typeof _ === "function" ? _ : constant([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent; + }; -var prim_1 = prim; + zoom.scaleExtent = function(_) { + return arguments.length ? (scaleExtent[0] = +_[0], scaleExtent[1] = +_[1], zoom) : [scaleExtent[0], scaleExtent[1]]; + }; -function prim(g, weightFunc) { - var result = new graph(); - var parents = {}; - var pq = new priorityQueue(); - var v; + zoom.translateExtent = function(_) { + return arguments.length ? (translateExtent[0][0] = +_[0][0], translateExtent[1][0] = +_[1][0], translateExtent[0][1] = +_[0][1], translateExtent[1][1] = +_[1][1], zoom) : [[translateExtent[0][0], translateExtent[0][1]], [translateExtent[1][0], translateExtent[1][1]]]; + }; - function updateNeighbors(edge) { - var w = edge.v === v ? edge.w : edge.v; - var pri = pq.priority(w); - if (pri !== undefined) { - var edgeWeight = weightFunc(edge); - if (edgeWeight < pri) { - parents[w] = v; - pq.decrease(w, edgeWeight); - } - } - } + zoom.constrain = function(_) { + return arguments.length ? (constrain = _, zoom) : constrain; + }; - if (g.nodeCount() === 0) { - return result; - } + zoom.duration = function(_) { + return arguments.length ? (duration = +_, zoom) : duration; + }; - lodash_1.each(g.nodes(), function(v) { - pq.add(v, Number.POSITIVE_INFINITY); - result.setNode(v); - }); + zoom.interpolate = function(_) { + return arguments.length ? (interpolate = _, zoom) : interpolate; + }; - // Start from an arbitrary node - pq.decrease(g.nodes()[0], 0); + zoom.on = function() { + var value = listeners.on.apply(listeners, arguments); + return value === listeners ? zoom : value; + }; - var init = false; - while (pq.size() > 0) { - v = pq.removeMin(); - if (lodash_1.has(parents, v)) { - result.setEdge(v, parents[v]); - } else if (init) { - throw new Error("Input graph is not connected: " + g); - } else { - init = true; - } + zoom.clickDistance = function(_) { + return arguments.length ? (clickDistance2 = (_ = +_) * _, zoom) : Math.sqrt(clickDistance2); + }; - g.nodeEdges(v).forEach(updateNeighbors); - } + zoom.tapDistance = function(_) { + return arguments.length ? (tapDistance = +_, zoom) : tapDistance; + }; - return result; + return zoom; } -var alg = { - components: components_1, - dijkstra: dijkstra_1, - dijkstraAll: dijkstraAll_1, - findCycles: findCycles_1, - floydWarshall: floydWarshall_1, - isAcyclic: isAcyclic_1, - postorder: postorder_1, - preorder: preorder_1, - prim: prim_1, - tarjan: tarjan_1, - topsort: topsort_1 +const arcDiagram = (graph, app, currFile, modal, width, height) => { + const data = graphlibToD3(graph); + const margin = { top: 20, right: 20, bottom: 20, left: 150 }; + const svg = select(".d3-graph") + .append("svg") + .attr("height", height) + .attr("width", width); + const nodes = data.nodes.map(({ id, name }) => ({ + id, + name, + sourceLinks: [], + targetLinks: [], + })); + const nodeById = new Map(nodes.map((d) => [d.id, d])); + const links = data.links.map(({ source, target }) => ({ + source: nodeById.get(source), + target: nodeById.get(target), + })); + for (const link of links) { + const { source, target } = link; + source.sourceLinks.push(link); + target.targetLinks.push(link); + } + svg.append("style").text(` + +path { + stroke: #808080; + opacity: 0.8; +} + +text { + stroke: var(--text-a); + opacity: 0.8; +} + + +.hover g.primary text { + fill: black; +} + +.hover g.secondary text { + fill: #333; +} + +.hover .secondary { + color: red; +} + +.hover path.primary { + stroke: #333; + stroke-opacity: 1; +} + +.hover rect { + opacity: 1; + cursor: pointer; +} + +`); + const y = point$1(nodes.map((d) => d.name).sort(ascending$1), [ + margin.top, + height - margin.bottom, + ]); + const label = svg + .append("g") + .attr("font-family", "sans-serif") + .attr("font-size", 10) + .attr("text-anchor", "end") + .selectAll("g") + .data(nodes) + .join("g") + .attr("transform", (d) => `translate(${margin.left},${(d.y = y(d.name))})`) + .call((g) => g + .append("text") + .attr("x", -6) + .attr("dy", "0.35em") + // .attr("fill", (d) => d3.lab(color(d.group)).darker(2)) + .text((d) => d.name)) + .call((g) => g.append("circle").attr("r", 3) + // .attr("fill", (d) => color(d.group)) + ); + const path = svg + .insert("g", "*") + .attr("fill", "none") + .attr("stroke-opacity", 0.6) + .attr("stroke-width", 1.5) + .selectAll("path") + .data(links) + .join("path") + // .attr("stroke", (d) => + // d.source.group === d.target.group ? color(d.source.group) : "#aaa" + // ) + .attr("d", arc); + const step = 104; + const nodeClick = (event, dest) => { + const currFile = app.workspace.getActiveFile(); + openOrSwitch(app, dest, currFile, event); + modal.close(); + }; + svg + .append("g") + .attr("fill", "none") + .attr("pointer-events", "all") + .selectAll("rect") + .data(nodes) + .join("rect") + .attr("width", margin.left + 40) + .attr("height", step) + .attr("y", (d) => y(d.name) - step / 2) + .on("mouseover", (d) => { + svg.classed("hover", true); + label.classed("primary", (n) => n === d); + label.classed("secondary", (n) => n.sourceLinks.some((l) => l.target === d) || + n.targetLinks.some((l) => l.source === d)); + path + .classed("primary", (l) => l.source === d || l.target === d) + .filter(".primary") + .raise(); + }) + .on("mouseout", (d) => { + svg.classed("hover", false); + label.classed("primary", false); + label.classed("secondary", false); + path.classed("primary", false).order(); + }) + .on("click", (event, d) => { + nodeClick(event, d.name); + }); + // function update() { + // y.domain(nodes.sort(viewof order.value).map(d => d.id)); + // const t = svg.transition() + // .duration(750); + // label.transition(t) + // .delay((d, i) => i * 20) + // .attrTween("transform", d => { + // const i = d3.interpolateNumber(d.y, y(d.id)); + // return t => `translate(${margin.left},${d.y = i(t)})`; + // }); + // path.transition(t) + // .duration(750 + nodes.length * 20) + // .attrTween("d", d => () => arc(d)); + // overlay.transition(t) + // .delay((d, i) => i * 20) + // .attr("y", d => y(d.id) - step / 2); + // } + // viewof order.addEventListener("input", update); + // invalidation.then(() => viewof order.removeEventListener("input", update)); + function arc(d) { + const y1 = d.source.y; + const y2 = d.target.y; + const r = Math.abs(y2 - y1) / 2; + return `M${margin.left},${y1}A${r},${r} 0,0,${y1 < y2 ? 1 : 0} ${margin.left},${y2}`; + } + function zoomed({ transform }) { + svg.attr("transform", transform); + } + svg.call(zoom() + .extent([ + [0, 0], + [width, height], + ]) + .scaleExtent([0.5, 8]) + .on("zoom", zoomed)); }; -/** - * Copyright (c) 2014, Chris Pettitt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ +const circlePacking = (graph, app, currFile, modal, width, height) => { + const flatAdj = dfsFlatAdjList(graph, currFile.basename); + console.log({ flatAdj }); + const hierarchy = stratify()(flatAdj); + console.log({ hierarchy }); + const adjList = bfsAdjList(graph, currFile.basename); + console.log({ adjList }); + const noDoubles = [...adjList]; + noDoubles.forEach((a, i) => { + if (noDoubles.some((b, j) => i !== j && a.name === b.name)) { + const index = noDoubles.findIndex((b, j) => i !== j && a.name === b.name); + noDoubles.splice(index, 1); + } + }); + // const noDoubles = adjList.filter((a) => { + // !adjList.some((b) => { + // console.log({ a, b }); + // return a.name !== b.name && a.parentId === b.parentId; + // }); + // }); + console.log({ noDoubles }); + // const root = stratify(noDoubles); + // console.log(root); + // const hierarchy: d3Tree = createTreeHierarchy(noDoubles, { + // id: "name", + // excludeParent: true, + // }); + // console.log({ hierarchy }); + const linkArr = noDoubles.map((d) => { + return { source: d.name, target: d.parentId }; + }); + const links = linkArr.map((d) => Object.create(d)); + const svg = select(".d3-graph") + .append("svg") + .attr("height", height) + .attr("width", width); + const nodeColour = getComputedStyle(document.body).getPropertyValue("--text-accent"); + // Initialize the circle: all located at the center of the svg area + const node = svg + .append("g") + .selectAll("circle") + .data(noDoubles) + .join("circle") + .attr("r", (d) => Math.round(d.height / 10) + 10) + .attr("cx", width / 2) + .attr("cy", height / 2) + .style("fill", nodeColour) + .style("fill-opacity", 0.6) + .attr("stroke", nodeColour) + .style("stroke-width", 4); + node.attr("aria-label", (d) => d.name); + const nodeClick = (event, dest) => { + const currFile = app.workspace.getActiveFile(); + openOrSwitch(app, dest, currFile, event); + modal.close(); + }; + node.on("click", (event, d) => { + nodeClick(event, d.name); + }); + svg + .append("g") + .attr("stroke", "#868282") + .attr("stroke-opacity", 0.6) + .selectAll("line") + .data(links) + .join("line") + .attr("stroke-width", 0.8); + // Features of the forces applied to the nodes: + const simulation$1 = simulation() + .force("center", center() + .x(width / 2) + .y(height / 2)) // Attraction to the center of the svg area + .force("charge", manyBody().strength(0.5)) // Nodes are attracted one each other of value is > 0 + .force("collide", collide().strength(0.025).radius(30).iterations(1)); // Force that avoids circle overlapping + // Apply these forces to the nodes and update their positions. + // Once the force algorithm is happy with positions ('alpha' value is low enough), simulations will stop. + simulation$1.nodes(noDoubles).on("tick", function (d) { + node.attr("cx", (d) => d.x).attr("cy", (d) => d.y); + }); + function zoomed({ transform }) { + node.attr("transform", transform); + } + svg.call(zoom() + .extent([ + [0, 0], + [width, height], + ]) + .scaleExtent([0.5, 8]) + .on("zoom", zoomed)); + const drag$1 = (simulation) => { + function dragstarted(event, d) { + if (!event.active) + simulation.alphaTarget(0.3).restart(); + d.fx = d.x; + d.fy = d.y; + } + function dragged(event, d) { + d.fx = event.x; + d.fy = event.y; + } + function dragended(event, d) { + if (!event.active) + simulation.alphaTarget(0); + d.fx = null; + d.fy = null; + } + return drag() + .on("start", dragstarted) + .on("drag", dragged) + .on("end", dragended); + }; + node.call(drag$1(simulation$1)); + // const pack = (data) => + // d3.pack().size([width, height]).padding(3)( + // d3 + // .hierarchy(data) + // .sum((d) => d.value) + // .sort((a, b) => b.value - a.value) + // ); + // const root = pack(hierarchy); + // const svg = d3 + // .select(".d3-graph") + // .append("svg") + // .attr("height", height) + // .attr("width", width) + // .style("font", "10px sans-serif") + // .style("overflow", "visible") + // .attr("text-anchor", "middle"); + // const node = svg + // .append("g") + // .attr("pointer-events", "all") + // .selectAll("g") + // .data(root.descendants()) + // .join("g") + // .attr("transform", (d) => `translate(${d.x},${d.y})`); + // node + // .append("circle") + // .attr("r", (d) => d.r) + // .attr("stroke", (d) => (d.children ? "#bbb" : "none")) + // .attr("fill", (d) => (d.children ? "none" : "#ddd")); + // const leaf = node.filter((d) => !d.children); + // leaf.select("circle"); + // // leaf + // // .append("clipPath") + // // .attr("id", (d) => (d.clipUid = DOM.uid("clip")).id) + // // .append("use") + // // .attr("xlink:href", (d) => d.leafUid.href); + // // leaf + // // .append("text") + // // .attr("clip-path", (d) => d.clipUid) + // // .selectAll("tspan") + // // .data((d) => d.data.name.split(/(?=[A-Z][^A-Z])/g)) + // // .join("tspan") + // // .attr("x", 0) + // // .attr("y", (d, i, nodes) => `${i - nodes.length / 2 + 0.8}em`) + // // .text((d) => d); + // node.append("title").text( + // (d) => `${d + // .ancestors() + // .map((d) => d.data.data.name) + // .reverse() + // .join("/")} + // ${d.value.toLocaleString()}` + // ); +}; -var graphlib = { - Graph: lib.Graph, - json: json, - alg: alg, - version: lib.version +const edgeBundling = (graph, app, currFile, modal, width, height) => { + const flatAdj = dfsFlatAdjList(graph, currFile.basename); + console.log({ flatAdj }); + const hier = stratify()(flatAdj); + console.log({ hier }); + const PADDING_BUBBLE = 15; // distance between edge end and bubble + const PADDING_LABEL = 30; // distance between edge end and engineer name + const BUBBLE_SIZE_MIN = 4; + const BUBBLE_SIZE_MAX = 20; + var diameter = 560, radius = diameter / 2, innerRadius = radius - 170; // between center and edge end + // The 'cluster' function takes 1 argument as input. It also has methods (??) like cluster.separation(), cluster.size() and cluster.nodeSize() + var cluster$1 = cluster().size([360, innerRadius]); + var line = lineRadial$1() + .curve(bundle.beta(0.85)) + .radius(function (d) { + return d[1]; + }) + .angle(function (d) { + return (d[0] / 180) * Math.PI; + }); + const svg = select(".d3-graph") + .append("svg") + .attr("height", height) + .attr("width", width) + .append("g") + .attr("transform", "translate(" + radius + "," + radius + ")"); + var link = svg.append("g").selectAll(".link"), label = svg.append("g").selectAll(".label"), bubble = svg.append("g").selectAll(".bubble"); + // Add a scale for bubble size + var bubbleSizeScale = linear() + .domain([0, 100]) + .range([BUBBLE_SIZE_MIN, BUBBLE_SIZE_MAX]); + // Scale for the bubble size + // If wanna see your data + // console.log(hierarchicalData) + // Reformat the data + var root = packageHierarchy(hier) + //debugger; + .sum(function (d) { + console.log(d); + return d.height; + }); + // console.log(root) + // Build an object that gives feature of each leaves + cluster$1(root); + const leaves = root.leaves(); + // Leaves is an array of Objects. 1 item = one leaf. Provides x and y for leaf position in the svg. Also gives details about its parent. + link + .data(packageImports(leaves)) + .enter() + .append("path") + .each(function (d) { + (d.source = d[0]), (d.target = d[d.length - 1]); + }) + .attr("class", "link") + .attr("d", line) + .attr("fill", "none") + .attr("stroke", "black"); + label + .data(leaves) + .enter() + .append("text") + .attr("class", "label") + .attr("dy", "0.31em") + .attr("transform", function (d) { + return ("rotate(" + + (d.x - 90) + + ")translate(" + + (d.y + PADDING_LABEL) + + ",0)" + + (d.x < 180 ? "" : "rotate(180)")); + }) + .attr("text-anchor", function (d) { + return d.x < 180 ? "start" : "end"; + }) + .text(function (d) { + return d.data.key; + }); + bubble + .data(leaves) + .enter() + .append("circle") + .attr("class", "bubble") + .attr("transform", function (d) { + return ("rotate(" + (d.x - 90) + ")translate(" + (d.y + PADDING_BUBBLE) + ",0)"); + }) + .attr("r", (d) => bubbleSizeScale(d.value)) + .attr("stroke", "black") + .attr("fill", "#69a3b2") + .style("opacity", 0.2); + // Lazily construct the package hierarchy from class names. + function packageHierarchy(classes) { + var map = {}; + function find(name, data) { + var node = map[name], i; + if (!node) { + node = map[name] = data || { name: name, children: [] }; + if (name.length) { + node.parent = find(name.substring(0, (i = name.lastIndexOf(".")))); + node.parent.children.push(node); + node.key = name.substring(i + 1); + } + } + return node; + } + classes.forEach(function (d) { + find(d.name, d); + }); + return hierarchy(map[""]); + } + // Return a list of imports for the given array of nodes. + function packageImports(nodes) { + var map = {}, imports = []; + // Compute a map from name to node. + nodes.forEach(function (d) { + map[d.data.name] = d; + }); + // For each import, construct a link from the source to target node. + nodes.forEach(function (d) { + if (d.data.imports) + d.data.imports.forEach(function (i) { + imports.push(map[d.data.name].path(map[i])); + }); + }); + return imports; + } }; const forceDirectedG = (graph, app, currFile, modal, width, height) => { @@ -37717,7 +32335,7 @@ const forceDirectedG = (graph, app, currFile, modal, width, height) => { let nodeToGetTo = currFile.basename; console.log({ nodeToGetTo }); console.time("Find all paths"); - let pathsFromNodeToGetTo = graphlib.alg.dijkstra(graph, nodeToGetTo); + // let pathsFromNodeToGetTo = graphlib.alg.dijkstra(graph, nodeToGetTo); console.timeEnd("Find all paths"); const defaultNodeColour = getComputedStyle(document.body).getPropertyValue("--text-accent"); let currNodeColour = defaultNodeColour; @@ -37851,7 +32469,7 @@ const forceDirectedG = (graph, app, currFile, modal, width, height) => { else return currNodeColour; }); - pathsFromNodeToGetTo = graphlib.alg.dijkstra(graph, nodeToGetTo); + // pathsFromNodeToGetTo = graphlib.alg.dijkstra(graph, nodeToGetTo); } }); function linked(a, b) { @@ -37861,23 +32479,25 @@ const forceDirectedG = (graph, app, currFile, modal, width, height) => { (link.target.index === a && link.source.index === b)); return !!linkedArr; } - function walkDijkstraPaths(paths, startNode) { - if (startNode === nodeToGetTo || paths[startNode].distance === Infinity) - return []; - let step = startNode; - const path = [startNode]; - let i = 0; - const MAX = 300; - while (paths[step].predecessor !== nodeToGetTo && i < MAX) { - i++; - step = paths[step].predecessor; - path.push(step); - } - if (i >= MAX) - return []; - path.push(nodeToGetTo); - return path; - } + // function walkDijkstraPaths( + // paths: { [node: string]: graphlib.Path }, + // startNode: string + // ) { + // if (startNode === nodeToGetTo || paths[startNode].distance === Infinity) + // return []; + // let step = startNode; + // const path: string[] = [startNode]; + // let i = 0; + // const MAX = 300; + // while (paths[step].predecessor !== nodeToGetTo && i < MAX) { + // i++; + // step = paths[step].predecessor; + // path.push(step); + // } + // if (i >= MAX) return []; + // path.push(nodeToGetTo); + // return path; + // } node .on("mouseover", (event, d) => { node @@ -37895,23 +32515,27 @@ const forceDirectedG = (graph, app, currFile, modal, width, height) => { : 0.2; }); // Highlight path from hovered node to currNode - const hoveredNode = nameFromIndex(d); - const path = walkDijkstraPaths(pathsFromNodeToGetTo, hoveredNode); - if (path.length) { - link - .transition() - .duration(150) - .style("stroke", function (link) { - if (path.includes(nameFromIndex(link.source)) && - path.includes(nameFromIndex(link.target))) - return currNodeColour; - }) - .style("opacity", function (link) { - if (path.includes(nameFromIndex(link.source)) && - path.includes(nameFromIndex(link.target))) - return 1; - }); - } + nameFromIndex(d); + // const path = walkDijkstraPaths(pathsFromNodeToGetTo, hoveredNode); + // if (path.length) { + // link + // .transition() + // .duration(150) + // .style("stroke", function (link) { + // if ( + // path.includes(nameFromIndex(link.source)) && + // path.includes(nameFromIndex(link.target)) + // ) + // return currNodeColour; + // }) + // .style("opacity", function (link) { + // if ( + // path.includes(nameFromIndex(link.source)) && + // path.includes(nameFromIndex(link.target)) + // ) + // return 1; + // }); + // } }) .on("mouseout", unfocus); function unfocus() { @@ -38632,8 +33256,8 @@ function create_fragment$2(ctx) { each_blocks.length = each_value.length; } }, - i: noop$2, - o: noop$2, + i: noop$1, + o: noop$1, d(detaching) { if (detaching) detach(div0); destroy_each(each_blocks, detaching); @@ -38961,7 +33585,7 @@ function get_each_context_2(ctx, list, i) { // (87:8) {#if step.value && settings.gridDots} function create_if_block$1(ctx) { let div; - let each_value_2 = lodash$1.range(Math.floor(/*wordCounts*/ ctx[2][/*step*/ ctx[24].value] / 1000)); + let each_value_2 = lodash.range(Math.floor(/*wordCounts*/ ctx[2][/*step*/ ctx[24].value] / 1000)); let each_blocks = []; for (let i = 0; i < each_value_2.length; i += 1) { @@ -38987,7 +33611,7 @@ function create_if_block$1(ctx) { }, p(ctx, dirty) { if (dirty & /*settings, wordCounts*/ 20) { - each_value_2 = lodash$1.range(Math.floor(/*wordCounts*/ ctx[2][/*step*/ ctx[24].value] / 1000)); + each_value_2 = lodash.range(Math.floor(/*wordCounts*/ ctx[2][/*step*/ ctx[24].value] / 1000)); let i; for (i = 0; i < each_value_2.length; i += 1) { @@ -39029,7 +33653,7 @@ function create_each_block_2(ctx) { m(target, anchor) { insert(target, span, anchor); }, - p: noop$2, + p: noop$1, d(detaching) { if (detaching) detach(span); } @@ -39225,8 +33849,8 @@ function create_fragment$1(ctx) { set_style(div, "grid-template-rows", ("1fr ").repeat(/*sortedTrails*/ ctx[0].length)); } }, - i: noop$2, - o: noop$2, + i: noop$1, + o: noop$1, d(detaching) { if (detaching) detach(div); destroy_each(each_blocks, detaching); @@ -39348,21 +33972,21 @@ function add_css() { function get_each_context(ctx, list, i) { const child_ctx = ctx.slice(); - child_ctx[11] = list[i]; + child_ctx[10] = list[i]; return child_ctx; } function get_each_context_1(ctx, list, i) { const child_ctx = ctx.slice(); - child_ctx[14] = list[i]; - child_ctx[16] = i; + child_ctx[13] = list[i]; + child_ctx[15] = i; return child_ctx; } -// (21:8) {:else} +// (20:8) {:else} function create_else_block(ctx) { let each_1_anchor; - let each_value_1 = /*trail*/ ctx[11]; + let each_value_1 = /*trail*/ ctx[10]; let each_blocks = []; for (let i = 0; i < each_value_1.length; i += 1) { @@ -39385,8 +34009,8 @@ function create_else_block(ctx) { insert(target, each_1_anchor, anchor); }, p(ctx, dirty) { - if (dirty & /*settings, trailsToShow, openOrSwitch, app, currFile, hoverPreview, activeLeafView*/ 206) { - each_value_1 = /*trail*/ ctx[11]; + if (dirty & /*settings, trailsToShow, openOrSwitch, app, currFile, hoverPreview, activeLeafView*/ 110) { + each_value_1 = /*trail*/ ctx[10]; let i; for (i = 0; i < each_value_1.length; i += 1) { @@ -39415,7 +34039,7 @@ function create_else_block(ctx) { }; } -// (19:8) {#if trail.length === 0} +// (18:8) {#if trail.length === 0} function create_if_block_1(ctx) { let span; let t_value = /*settings*/ ctx[2].noPathMessage + ""; @@ -39439,7 +34063,7 @@ function create_if_block_1(ctx) { }; } -// (31:12) {#if i < trail.length - 1} +// (30:12) {#if i < trail.length - 1} function create_if_block_2(ctx) { let span; let t_value = " " + /*settings*/ ctx[2].trailSeperator + " " + ""; @@ -39463,10 +34087,10 @@ function create_if_block_2(ctx) { }; } -// (22:10) {#each trail as crumb, i} +// (21:10) {#each trail as crumb, i} function create_each_block_1(ctx) { let span; - let t0_value = /*crumb*/ ctx[14] + ""; + let t0_value = /*crumb*/ ctx[13] + ""; let t0; let t1; let if_block_anchor; @@ -39474,14 +34098,14 @@ function create_each_block_1(ctx) { let dispose; function click_handler(...args) { - return /*click_handler*/ ctx[8](/*crumb*/ ctx[14], ...args); + return /*click_handler*/ ctx[7](/*crumb*/ ctx[13], ...args); } function mouseover_handler(...args) { - return /*mouseover_handler*/ ctx[9](/*crumb*/ ctx[14], ...args); + return /*mouseover_handler*/ ctx[8](/*crumb*/ ctx[13], ...args); } - let if_block = /*i*/ ctx[16] < /*trail*/ ctx[11].length - 1 && create_if_block_2(ctx); + let if_block = /*i*/ ctx[15] < /*trail*/ ctx[10].length - 1 && create_if_block_2(ctx); return { c() { @@ -39510,9 +34134,9 @@ function create_each_block_1(ctx) { }, p(new_ctx, dirty) { ctx = new_ctx; - if (dirty & /*trailsToShow*/ 64 && t0_value !== (t0_value = /*crumb*/ ctx[14] + "")) set_data(t0, t0_value); + if (dirty & /*trailsToShow*/ 32 && t0_value !== (t0_value = /*crumb*/ ctx[13] + "")) set_data(t0, t0_value); - if (/*i*/ ctx[16] < /*trail*/ ctx[11].length - 1) { + if (/*i*/ ctx[15] < /*trail*/ ctx[10].length - 1) { if (if_block) { if_block.p(ctx, dirty); } else { @@ -39536,13 +34160,13 @@ function create_each_block_1(ctx) { }; } -// (17:4) {#each trailsToShow as trail} +// (16:4) {#each trailsToShow as trail} function create_each_block(ctx) { let div; let t; function select_block_type(ctx, dirty) { - if (/*trail*/ ctx[11].length === 0) return create_if_block_1; + if (/*trail*/ ctx[10].length === 0) return create_if_block_1; return create_else_block; } @@ -39580,10 +34204,11 @@ function create_each_block(ctx) { }; } -// (40:2) {#if sortedTrails.length > 1} +// (39:2) {#if sortedTrails.length > 1} function create_if_block(ctx) { let div; let button; + let t_value = (/*showAll*/ ctx[4] ? "Shortest" : "All") + ""; let t; let mounted; let dispose; @@ -39592,7 +34217,7 @@ function create_if_block(ctx) { c() { div = element("div"); button = element("button"); - t = text(/*buttonText*/ ctx[5]); + t = text(t_value); attr(button, "class", "button-div"); }, m(target, anchor) { @@ -39601,12 +34226,12 @@ function create_if_block(ctx) { append(button, t); if (!mounted) { - dispose = listen(button, "click", /*click_handler_1*/ ctx[10]); + dispose = listen(button, "click", /*click_handler_1*/ ctx[9]); mounted = true; } }, p(ctx, dirty) { - if (dirty & /*buttonText*/ 32) set_data(t, /*buttonText*/ ctx[5]); + if (dirty & /*showAll*/ 16 && t_value !== (t_value = (/*showAll*/ ctx[4] ? "Shortest" : "All") + "")) set_data(t, t_value); }, d(detaching) { if (detaching) detach(div); @@ -39620,7 +34245,7 @@ function create_fragment(ctx) { let span; let div; let t; - let each_value = /*trailsToShow*/ ctx[6]; + let each_value = /*trailsToShow*/ ctx[5]; let each_blocks = []; for (let i = 0; i < each_value.length; i += 1) { @@ -39655,8 +34280,8 @@ function create_fragment(ctx) { if (if_block) if_block.m(span, null); }, p(ctx, [dirty]) { - if (dirty & /*settings, trailsToShow, openOrSwitch, app, currFile, hoverPreview, activeLeafView*/ 206) { - each_value = /*trailsToShow*/ ctx[6]; + if (dirty & /*settings, trailsToShow, openOrSwitch, app, currFile, hoverPreview, activeLeafView*/ 110) { + each_value = /*trailsToShow*/ ctx[5]; let i; for (i = 0; i < each_value.length; i += 1) { @@ -39691,8 +34316,8 @@ function create_fragment(ctx) { if_block = null; } }, - i: noop$2, - o: noop$2, + i: noop$1, + o: noop$1, d(detaching) { if (detaching) detach(span); destroy_each(each_blocks, detaching); @@ -39702,7 +34327,6 @@ function create_fragment(ctx) { } function instance($$self, $$props, $$invalidate) { - let buttonText; let trailsToShow; @@ -39724,12 +34348,8 @@ function instance($$self, $$props, $$invalidate) { }; $$self.$$.update = () => { - if ($$self.$$.dirty & /*showAll*/ 16) { - $$invalidate(5, buttonText = showAll ? "Shortest" : "All"); - } - if ($$self.$$.dirty & /*showAll, sortedTrails*/ 17) { - $$invalidate(6, trailsToShow = showAll ? sortedTrails : [sortedTrails[0]]); + $$invalidate(5, trailsToShow = showAll ? sortedTrails : [sortedTrails[0]]); } }; @@ -39739,7 +34359,6 @@ function instance($$self, $$props, $$invalidate) { settings, currFile, showAll, - buttonText, trailsToShow, activeLeafView, click_handler, @@ -39909,13 +34528,15 @@ class BreadcrumbsPlugin extends obsidian.Plugin { var _a; if (this.app.plugins.enabledPlugins.has("dataview")) { const api = (_a = this.app.plugins.plugins.dataview) === null || _a === void 0 ? void 0 : _a.api; - if (api) + if (api) { await initEverything(); - else + } + else { this.registerEvent(this.app.metadataCache.on("dataview:api-ready", async () => { console.log("dv ready"); await initEverything(); })); + } } }); obsidian.addIcon(TRAIL_ICON, TRAIL_ICON_SVG); @@ -39993,21 +34614,20 @@ class BreadcrumbsPlugin extends obsidian.Plugin { return null; } // SECTION OneSource - populateGraph(g, currFileName, fields, dir, fieldName) { + populateGraph(g, currFileName, fieldValues, dir, fieldName) { addNodeIfNot(g, currFileName, { dir, fieldName }); if (fieldName === "") return; - fields.forEach((field) => { - addNodeIfNot(g, field, { dir, fieldName }); - addEdgeIfNot(g, currFileName, field, { dir, fieldName }); + fieldValues.forEach((value) => { + addNodeIfNot(g, value, { dir, fieldName }); + addEdgeIfNot(g, currFileName, value, { dir, fieldName }); }); } - async getCSVRows(basePath) { + async getCSVRows() { const { CSVPaths } = this.settings; const CSVRows = []; - if (CSVPaths[0] === "") { + if (CSVPaths[0] === "") return CSVRows; - } const fullPath = obsidian.normalizePath(CSVPaths[0]); const content = await this.app.vault.adapter.read(fullPath); const lines = content.split("\n"); @@ -40035,11 +34655,10 @@ class BreadcrumbsPlugin extends obsidian.Plugin { }); } async initGraphs() { - var _a; - const settings = this.settings; + const { settings } = this; debugGroupStart(settings, "debugMode", "Initialise Graphs"); const files = this.app.vault.getMarkdownFiles(); - const dvQ = !!((_a = this.app.plugins.plugins.dataview) === null || _a === void 0 ? void 0 : _a.api); + const dvQ = !!this.app.plugins.enabledPlugins.has("dataview"); const fileFrontmatterArr = dvQ ? getDVMetadataCache(this.app, settings, files) : getObsMetadataCache(this.app, settings, files); @@ -40047,10 +34666,9 @@ class BreadcrumbsPlugin extends obsidian.Plugin { debugGroupStart(settings, "debugMode", "Hierarchy Note Adjacency List"); let hierarchyNotesArr = []; if (settings.hierarchyNotes[0] !== "") { - const currPath = this.app.workspace.getActiveFile().path; const contentArr = []; settings.hierarchyNotes.forEach(async (note) => { - const file = this.app.metadataCache.getFirstLinkpathDest(note, currPath); + const file = this.app.metadataCache.getFirstLinkpathDest(note, ""); if (file) { const content = await this.app.vault.cachedRead(file); contentArr.push(content); @@ -40073,7 +34691,7 @@ class BreadcrumbsPlugin extends obsidian.Plugin { }; userHierarchies.forEach((hier, i) => { const newGraphs = { up: {}, same: {}, down: {} }; - Object.keys(hier).forEach((dir) => { + DIRECTIONS.forEach((dir) => { hier[dir].forEach((dirField) => { newGraphs[dir][dirField] = new graphology_umd_min(); }); @@ -40081,24 +34699,18 @@ class BreadcrumbsPlugin extends obsidian.Plugin { graphs.hierGs.push(newGraphs); }); const useCSV = settings.CSVPaths !== ""; - let basePath; - let CSVRows; - if (useCSV) { - basePath = this.app.vault.adapter.basePath; - CSVRows = await this.getCSVRows(basePath); - } + let CSVRows = useCSV ? await this.getCSVRows() : []; relObjArr.forEach((relObj) => { const currFileName = relObj.current.basename || relObj.current.name; relObj.hierarchies.forEach((hier, i) => { DIRECTIONS.forEach((dir) => { - Object.keys(hier[dir]).forEach((fieldName) => { + for (const fieldName in hier[dir]) { const g = graphs.hierGs[i][dir][fieldName]; const fieldValues = hier[dir][fieldName]; this.populateGraph(g, currFileName, fieldValues, dir, fieldName); - if (useCSV) { + if (useCSV) this.addCSVCrumbs(g, CSVRows, dir, fieldName); - } - }); + } }); }); }); @@ -40135,8 +34747,7 @@ class BreadcrumbsPlugin extends obsidian.Plugin { graphs.mergedGs[dir] = dirMerged; }); DIRECTIONS.forEach((dir) => { - const oppDir = getOppDir(dir); - graphs.closedGs[dir] = closeImpliedLinks(graphs.mergedGs[dir], graphs.mergedGs[oppDir]); + graphs.closedGs[dir] = closeImpliedLinks(graphs.mergedGs[dir], graphs.mergedGs[getOppDir(dir)]); }); // LimitTrailG if (Object.values(settings.limitTrailCheckboxStates).every((val) => val)) { @@ -40174,57 +34785,34 @@ class BreadcrumbsPlugin extends obsidian.Plugin { : "internal-link breadcrumbs-link"; } bfsAllPaths(g, startNode) { + const pathsArr = []; const queue = [ { node: startNode, path: [] }, ]; - const pathsArr = []; let i = 0; while (queue.length !== 0 && i < 1000) { i++; - const currPath = queue.shift(); - const newNodes = g.outNeighbors(currPath.node); - const extPath = [currPath.node, ...currPath.path]; - queue.push(...newNodes.map((n) => { + const { node, path } = queue.shift(); + const extPath = [node, ...path]; + queue.push(...g.outNeighbors(node).map((n) => { return { node: n, path: extPath }; })); // terminal node - if (newNodes.length === 0) { + if (!g.outDegree(node)) { pathsArr.push(extPath); } } // Splice off the current note from the path pathsArr.forEach((path) => { - if (path.length) { + if (path.length) path.splice(path.length - 1, 1); - } }); debug(this.settings, { pathsArr }); return pathsArr; } - dfsAllPaths(g, startNode) { - const queue = [ - { node: startNode, path: [] }, - ]; - const pathsArr = []; - let i = 0; - while (queue.length > 0 && i < 1000) { - i++; - const currPath = queue.shift(); - const newNodes = g.outNeighbors(currPath.node); - const extPath = [currPath.node, ...currPath.path]; - queue.unshift(...newNodes.map((n) => { - return { node: n, path: extPath }; - })); - if (newNodes.length === 0) { - pathsArr.push(extPath); - } - } - return pathsArr; - } getBreadcrumbs(g, currFile) { - if (currFile.extension !== "md") { + if (currFile.extension !== "md") return null; - } const from = currFile.basename; const indexNotes = [this.settings.indexNote].flat(); let allTrails = this.bfsAllPaths(g, from); @@ -40240,7 +34828,7 @@ class BreadcrumbsPlugin extends obsidian.Plugin { } async drawTrail() { var _a, _b, _c, _d, _e; - const settings = this.settings; + const { settings } = this; debugGroupStart(settings, "debugMode", "Draw Trail"); if (!settings.showTrail) { debugGroupEnd(settings, "debugMode"); diff --git a/package.json b/package.json index e11158a5..10983062 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "juggl-api": "git+https://github.com/HEmile/juggl-api.git", "nodejs": "^0.0.0", "obsidian-community-lib": "^1.2.0", - "svelte": "3.35.0" + "svelte": "3.35.0", + "svelte-icons": "^2.1.0" } } diff --git a/src/BreadcrumbsSettingTab.ts b/src/BreadcrumbsSettingTab.ts index 85b759a4..ee31ab60 100644 --- a/src/BreadcrumbsSettingTab.ts +++ b/src/BreadcrumbsSettingTab.ts @@ -1,26 +1,25 @@ import { App, - ButtonComponent, DropdownComponent, Notice, PluginSettingTab, Setting, } from "obsidian"; +import { openView } from "obsidian-community-lib"; import { ALLUNLINKED, DIRECTIONS, + MATRIX_VIEW, REAlCLOSED, RELATIONS, - MATRIX_VIEW, VISTYPES, } from "src/constants"; -import type { Relations, userHierarchy, visTypes } from "src/interfaces"; +import type { Relations, visTypes } from "src/interfaces"; import type BreadcrumbsPlugin from "src/main"; -import { debug, hierToStr, isInVault, splitAndTrim } from "src/sharedFunctions"; -import { isEqual } from "lodash"; -import KoFi from "./Components/KoFi.svelte"; -import { openView } from "obsidian-community-lib"; import MatrixView from "src/MatrixView"; +import { debug, isInVault, splitAndTrim } from "src/sharedFunctions"; +import KoFi from "./Components/KoFi.svelte"; +import UserHierarchies from "./Components/UserHierarchies.svelte"; export class BreadcrumbsSettingTab extends PluginSettingTab { plugin: BreadcrumbsPlugin; @@ -34,172 +33,10 @@ export class BreadcrumbsSettingTab extends PluginSettingTab { const plugin = this.plugin; const { settings } = plugin; const { containerEl } = this; + const { userHierarchies } = settings; containerEl.empty(); containerEl.createEl("h2", { text: "Settings for Breadcrumbs plugin" }); - function hierIndex( - currHiers: userHierarchy[], - values: [string[], string[], string[]] - ) { - return currHiers.findIndex( - (hier) => - isEqual(hier.up, values[0]) && - isEqual(hier.same, values[1]) && - isEqual(hier.down, values[2]) - ); - } - - const addHierarchyRow = ( - values: userHierarchy = { up: [""], same: [""], down: [""] }, - existing = false - ) => { - const row = createSpan({ cls: "hierarchy-row" }); - - const hierarchyNames = row.createSpan({}); - - hierarchyNames.createEl("label", { attr: { for: "up" }, text: "↑" }); - const upInput = hierarchyNames.createEl("input", { - attr: { id: "up", placeholder: "↑" }, - value: values.up.join(", "), - }); - hierarchyNames.createEl("label", { attr: { for: "same" }, text: "→" }); - const sameInput = hierarchyNames.createEl("input", { - attr: { id: "same", placeholder: "→" }, - value: values.same.join(", "), - }); - hierarchyNames.createEl("label", { attr: { for: "down" }, text: "↓" }); - const downInput = hierarchyNames.createEl("input", { - attr: { id: "down", placeholder: "↓" }, - value: values.down.join(", "), - }); - let cleanInputs = [upInput.value, sameInput.value, downInput.value].map( - splitAndTrim - ) as [string[], string[], string[]]; - - [upInput, sameInput, downInput].forEach((input) => - input.addEventListener("change", () => { - saveButton.toggleClass("hierarchy-unsaved", true); - saveButton.textContent = "Save"; - }) - ); - - async function resetLimitTrailCheckboxes() { - settings.limitTrailCheckboxStates = {}; - settings.userHierarchies.forEach((userHier) => { - userHier.up.forEach(async (field) => { - if (field !== "") { - settings.limitTrailCheckboxStates[field] = true; - await plugin.saveSettings(); - } - }); - }); - await plugin.saveSettings(); - drawLimitTrailCheckboxes(checkboxDiv); - } - - async function resetLimitWriteBCCheckboxes() { - settings.limitWriteBCCheckboxStates = {}; - settings.userHierarchies.forEach((userHier) => { - DIRECTIONS.forEach((dir) => { - userHier.up.forEach(async (field) => { - if (field !== "") { - settings.limitWriteBCCheckboxStates[field] = true; - await plugin.saveSettings(); - } - }); - }); - }); - await plugin.saveSettings(); - drawLimitWriteBCCheckboxes(checkboxDiv); - } - - const deleteButton = row.createEl("button", { text: "X" }, (el) => { - el.addEventListener("click", async () => { - row.remove(); - const removeIndex = hierIndex( - settings.userHierarchies, - [upInput.value, sameInput.value, downInput.value].map( - splitAndTrim - ) as [string[], string[], string[]] - ); - - if (removeIndex > -1) { - settings.userHierarchies.splice(removeIndex, 1); - await plugin.saveSettings(); - } - - // Refresh limitTrailFields - await resetLimitTrailCheckboxes(); - await resetLimitWriteBCCheckboxes(); - - new Notice("Hierarchy Removed."); - }); - }); - - const saveButton = row.createEl( - "button", - { - text: existing ? "Saved" : "Save", - cls: (existing ? "" : "hierarchy-unsaved ") + "save-hierarchy-button", - }, - function (el) { - el.addEventListener("click", async () => { - if ( - hierIndex( - settings.userHierarchies, - [upInput.value, sameInput.value, downInput.value].map( - splitAndTrim - ) as [string[], string[], string[]] - ) > -1 - ) { - new Notice( - "A hierarchy with these Up, Same, and Down values already exists." - ); - return; - } - if (saveButton.hasClass("hierarchy-unsaved")) { - const removeIndex = hierIndex( - settings.userHierarchies, - cleanInputs - ); - - if (removeIndex > -1) { - settings.userHierarchies.splice(removeIndex, 1); - await plugin.saveSettings(); - await resetLimitTrailCheckboxes(); - await resetLimitWriteBCCheckboxes(); - } - } - cleanInputs = [upInput.value, sameInput.value, downInput.value].map( - splitAndTrim - ) as [string[], string[], string[]]; - - saveButton.toggleClass("hierarchy-unsaved", false); - saveButton.textContent = "Saved"; - - if (hierIndex(settings.userHierarchies, cleanInputs) > -1) { - new Notice( - "A hierarchy with these Up, Same, and Down values already exists." - ); - } else { - settings.userHierarchies.push({ - up: splitAndTrim(upInput.value), - same: splitAndTrim(sameInput.value), - down: splitAndTrim(downInput.value), - }); - await plugin.saveSettings(); - new Notice("Hierarchy saved."); - - await resetLimitTrailCheckboxes(); - await resetLimitWriteBCCheckboxes(); - } - }); - } - ); - - return row; - }; - const fieldDetails: HTMLDetailsElement = containerEl.createEl("details", { cls: "field-details", }); @@ -212,45 +49,9 @@ export class BreadcrumbsSettingTab extends PluginSettingTab { text: "For each direction (up, same, down), you can enter multiple field names in a comma seperated list. For example: `parent, broader, upper`", }); - new Setting(fieldDetails) - .setName("Add Hierarchy") - .setDesc("Add a new hierarchy.") - .addButton((button: ButtonComponent) => { - let b = button - .setTooltip("Add Additional") - .setButtonText("+") - .onClick(async () => { - fieldDetails.append(addHierarchyRow()); - }); - }); - - fieldDetails.createEl( - "button", - { text: "Reset Hierarchies" }, - async (el) => { - el.addEventListener("click", async () => { - const rows = fieldDetails.querySelectorAll(".hierarchy-row"); - rows.forEach((row) => row.remove()); - settings.userHierarchies = []; - await plugin.saveSettings(); - new Notice("Hierarchies reset."); - }); - } - ); - - fieldDetails.createEl("button", { text: "Show Hierarchies" }, (el) => { - el.addEventListener("click", () => { - if (settings.userHierarchies.length) { - new Notice(settings.userHierarchies.map(hierToStr).join("\n\n")); - } else { - new Notice("No hierarchies currently exist."); - } - console.log({ hierarchies: settings.userHierarchies }); - }); - }); - - settings.userHierarchies.forEach((userHier) => { - fieldDetails.append(addHierarchyRow(userHier, true)); + new UserHierarchies({ + target: fieldDetails, + props: { plugin }, }); const hierarchyNoteDetails: HTMLDetailsElement = @@ -297,7 +98,7 @@ export class BreadcrumbsSettingTab extends PluginSettingTab { settings.hierarchyNoteUpFieldName = finalValue; await plugin.saveSettings(); } else { - const downFieldNames = settings.userHierarchies + const downFieldNames = userHierarchies .map((hier) => hier.up) .flat(3); @@ -330,7 +131,7 @@ export class BreadcrumbsSettingTab extends PluginSettingTab { settings.hierarchyNoteDownFieldName = finalValue; await plugin.saveSettings(); } else { - const downFieldNames = settings.userHierarchies + const downFieldNames = userHierarchies .map((hier) => hier.down) .flat(3); diff --git a/src/Components/UserHierarchies.svelte b/src/Components/UserHierarchies.svelte new file mode 100644 index 00000000..dd5547b6 --- /dev/null +++ b/src/Components/UserHierarchies.svelte @@ -0,0 +1,119 @@ + + +
+
+ + + +
+ + {#each userHierarchies as hier, i} +
+ + {DIRECTIONS.map((dir) => hier[dir].map((field) => field)) + .flat() + .join(", ") || "Empty Hierarchy"} + + + + + {#each DIRECTIONS as dir} + + { + userHierarchies[i][dir] = splitAndTrim(e.target.value); + await plugin.saveSettings(); + }} + /> + {/each} +
+ {/each} +
+ + diff --git a/src/constants.ts b/src/constants.ts index dde215ca..7aee0652 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -2,6 +2,7 @@ import type { BreadcrumbsSettings, Directions, Relations, + userHierarchy, visTypes, } from "src/interfaces"; @@ -28,10 +29,19 @@ export const VISTYPES: visTypes[] = [ ]; export const DIRECTIONS: Directions[] = ["up", "same", "down"]; +export const ARROW_DIRECTIONS = { + up: "↑", + same: "→", + down: "↓", +}; export const RELATIONS: Relations[] = ["Parent", "Sibling", "Child"]; export const REAlCLOSED = ["Real", "Closed"]; export const ALLUNLINKED = ["All", "No Unlinked"]; +export const blankUserHier = (): userHierarchy => { + return { up: [], same: [], down: [] }; +}; + export const DEFAULT_SETTINGS: BreadcrumbsSettings = { userHierarchies: [], indexNote: [""], diff --git a/src/main.ts b/src/main.ts index 00d69889..e2fc5210 100644 --- a/src/main.ts +++ b/src/main.ts @@ -14,10 +14,10 @@ import { BreadcrumbsSettingTab } from "src/BreadcrumbsSettingTab"; import { DEFAULT_SETTINGS, DIRECTIONS, - TRAIL_ICON, - TRAIL_ICON_SVG, MATRIX_VIEW, STATS_VIEW, + TRAIL_ICON, + TRAIL_ICON_SVG, } from "src/constants"; import type { BCIndex, @@ -144,14 +144,16 @@ export default class BreadcrumbsPlugin extends Plugin { this.app.workspace.onLayoutReady(async () => { if (this.app.plugins.enabledPlugins.has("dataview")) { const api = this.app.plugins.plugins.dataview?.api; - if (api) await initEverything(); - else + if (api) { + await initEverything(); + } else { this.registerEvent( this.app.metadataCache.on("dataview:api-ready", async () => { console.log("dv ready"); await initEverything(); }) ); + } } }); @@ -347,25 +349,24 @@ export default class BreadcrumbsPlugin extends Plugin { populateGraph( g: Graph, currFileName: string, - fields: string[], + fieldValues: string[], dir: Directions, fieldName: string ): void { addNodeIfNot(g, currFileName, { dir, fieldName }); if (fieldName === "") return; - fields.forEach((field) => { - addNodeIfNot(g, field, { dir, fieldName }); - addEdgeIfNot(g, currFileName, field, { dir, fieldName }); + fieldValues.forEach((value) => { + addNodeIfNot(g, value, { dir, fieldName }); + addEdgeIfNot(g, currFileName, value, { dir, fieldName }); }); } - async getCSVRows(basePath: string) { + async getCSVRows() { const { CSVPaths } = this.settings; const CSVRows: { [key: string]: string }[] = []; - if (CSVPaths[0] === "") { - return CSVRows; - } + if (CSVPaths[0] === "") return CSVRows; + const fullPath = normalizePath(CSVPaths[0]); const content = await this.app.vault.adapter.read(fullPath); @@ -403,11 +404,11 @@ export default class BreadcrumbsPlugin extends Plugin { } async initGraphs(): Promise { - const settings = this.settings; + const { settings } = this; debugGroupStart(settings, "debugMode", "Initialise Graphs"); const files = this.app.vault.getMarkdownFiles(); - const dvQ = !!this.app.plugins.plugins.dataview?.api; + const dvQ = !!this.app.plugins.enabledPlugins.has("dataview"); const fileFrontmatterArr: dvFrontmatterCache[] = dvQ ? getDVMetadataCache(this.app, settings, files) @@ -422,14 +423,10 @@ export default class BreadcrumbsPlugin extends Plugin { children: string[]; }[] = []; if (settings.hierarchyNotes[0] !== "") { - const currPath = this.app.workspace.getActiveFile().path; const contentArr: string[] = []; settings.hierarchyNotes.forEach(async (note) => { - const file = this.app.metadataCache.getFirstLinkpathDest( - note, - currPath - ); + const file = this.app.metadataCache.getFirstLinkpathDest(note, ""); if (file) { const content = await this.app.vault.cachedRead(file); contentArr.push(content); @@ -459,38 +456,30 @@ export default class BreadcrumbsPlugin extends Plugin { userHierarchies.forEach((hier, i) => { const newGraphs: HierarchyGraphs = { up: {}, same: {}, down: {} }; - Object.keys(hier).forEach((dir: Directions) => { + DIRECTIONS.forEach((dir: Directions) => { hier[dir].forEach((dirField) => { newGraphs[dir][dirField] = new Graph(); }); }); - graphs.hierGs.push(newGraphs); }); const useCSV = settings.CSVPaths !== ""; - let basePath: string; - let CSVRows: { [key: string]: string }[]; - if (useCSV) { - basePath = this.app.vault.adapter.basePath; - CSVRows = await this.getCSVRows(basePath); - } + let CSVRows = useCSV ? await this.getCSVRows() : []; relObjArr.forEach((relObj) => { const currFileName = relObj.current.basename || relObj.current.name; relObj.hierarchies.forEach((hier, i) => { - DIRECTIONS.forEach((dir: Directions) => { - Object.keys(hier[dir]).forEach((fieldName) => { + DIRECTIONS.forEach((dir) => { + for (const fieldName in hier[dir]) { const g = graphs.hierGs[i][dir][fieldName]; const fieldValues = hier[dir][fieldName]; this.populateGraph(g, currFileName, fieldValues, dir, fieldName); - if (useCSV) { - this.addCSVCrumbs(g, CSVRows, dir, fieldName); - } - }); + if (useCSV) this.addCSVCrumbs(g, CSVRows, dir, fieldName); + } }); }); }); @@ -537,10 +526,9 @@ export default class BreadcrumbsPlugin extends Plugin { }); DIRECTIONS.forEach((dir) => { - const oppDir = getOppDir(dir); graphs.closedGs[dir] = closeImpliedLinks( graphs.mergedGs[dir], - graphs.mergedGs[oppDir] + graphs.mergedGs[getOppDir(dir)] ); }); @@ -597,68 +585,36 @@ export default class BreadcrumbsPlugin extends Plugin { } bfsAllPaths(g: Graph, startNode: string): string[][] { + const pathsArr: string[][] = []; const queue: { node: string; path: string[] }[] = [ { node: startNode, path: [] }, ]; - const pathsArr: string[][] = []; let i = 0; while (queue.length !== 0 && i < 1000) { i++; - const currPath = queue.shift(); - - const newNodes = g.outNeighbors(currPath.node); - const extPath = [currPath.node, ...currPath.path]; + const { node, path } = queue.shift(); + const extPath = [node, ...path]; queue.push( - ...newNodes.map((n: string) => { + ...g.outNeighbors(node).map((n) => { return { node: n, path: extPath }; }) ); // terminal node - if (newNodes.length === 0) { + if (!g.outDegree(node)) { pathsArr.push(extPath); } } // Splice off the current note from the path pathsArr.forEach((path) => { - if (path.length) { - path.splice(path.length - 1, 1); - } + if (path.length) path.splice(path.length - 1, 1); }); debug(this.settings, { pathsArr }); return pathsArr; } - dfsAllPaths(g: Graph, startNode: string): string[][] { - const queue: { node: string; path: string[] }[] = [ - { node: startNode, path: [] }, - ]; - const pathsArr: string[][] = []; - - let i = 0; - while (queue.length > 0 && i < 1000) { - i++; - const currPath = queue.shift(); - - const newNodes = g.outNeighbors(currPath.node); - const extPath = [currPath.node, ...currPath.path]; - queue.unshift( - ...newNodes.map((n: string) => { - return { node: n, path: extPath }; - }) - ); - - if (newNodes.length === 0) { - pathsArr.push(extPath); - } - } - return pathsArr; - } - getBreadcrumbs(g: Graph, currFile: TFile): string[][] | null { - if (currFile.extension !== "md") { - return null; - } + if (currFile.extension !== "md") return null; const from = currFile.basename; const indexNotes: string[] = [this.settings.indexNote].flat(); @@ -678,7 +634,7 @@ export default class BreadcrumbsPlugin extends Plugin { } async drawTrail(): Promise { - const settings = this.settings; + const { settings } = this; debugGroupStart(settings, "debugMode", "Draw Trail"); if (!settings.showTrail) { debugGroupEnd(settings, "debugMode"); diff --git a/src/sharedFunctions.ts b/src/sharedFunctions.ts index e385a858..9dd2b1f9 100644 --- a/src/sharedFunctions.ts +++ b/src/sharedFunctions.ts @@ -314,6 +314,12 @@ export function getFieldValues( export const splitAndTrim = (fields: string): string[] => fields.split(",").map((str: string) => str.trim()); +/** + * + * @param {BreadcrumbsPlugin} plugin + * @param {dvFrontmatterCache[]} fileFrontmatterArr + * @returns HierarchyFields + */ export async function getNeighbourObjArr( plugin: BreadcrumbsPlugin, fileFrontmatterArr: dvFrontmatterCache[] @@ -739,3 +745,12 @@ export const getSinks = (g: Graph) => export const getSources = (g: Graph) => g.filterNodes((node) => !g.inNeighbors(node).length); + +export function swapItems(i: number, j: number, arr: T[]) { + const max = arr.length - 1; + if (i < 0 || i > max || j < 0 || j > max) return arr; + const tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + return arr; +}