From cfb0ce0f007e1691dd5fe4e924d8c7c541e699d2 Mon Sep 17 00:00:00 2001 From: Ross Keenan Date: Fri, 19 Nov 2021 14:00:20 +0200 Subject: [PATCH] refactor: :recycle: Organise different views better --- .vscode/settings.json | 3 +- main.js | 6010 ++++++++++++++++++---------------- src/BreadcrumbsSettingTab.ts | 15 +- src/constants.ts | 28 + 4 files changed, 3166 insertions(+), 2890 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 55de5e6c..6e0f3770 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,6 +12,7 @@ "WriteBCToFile", "LimitTrailFields", "CSV Crumbs", - "nextPrev" + "nextPrev", + "DucksView" ] } \ No newline at end of file diff --git a/main.js b/main.js index 7035f1fc..8fa818c0 100644 --- a/main.js +++ b/main.js @@ -19,7 +19,7 @@ var graphology_umd_min = createCommonjsModule(function (module, exports) { }); -createCommonjsModule(function (module, exports) { +var feather = createCommonjsModule(function (module, exports) { (function webpackUniversalModuleDefinition(root, factory) { module.exports = factory(); })(typeof self !== 'undefined' ? self : commonjsGlobal, function() { @@ -2415,6 +2415,23 @@ module.exports = __webpack_require__(/*! /home/travis/build/feathericons/feather async function wait(delay) { return new Promise((resolve) => setTimeout(resolve, delay)); } +/** + * Adds a specific Feather Icon to Obsidian. + * + * @param name official Name of the Icon (https://feathericons.com/) + * @param attr SVG Attributes for the Icon. The default should work for most usecases. + * @returns {string} Icon name + */ +function addFeatherIcon(name, attr = { viewBox: "0 0 24 24", width: "100", height: "100" }) { + if (feather.icons[name]) { + const iconName = `feather-${name}`; + obsidian.addIcon(iconName, feather.icons[name].toSvg(attr)); + return iconName; + } + else { + throw Error(`This Icon (${name}) doesn't exist in the Feather Library.`); + } +} /** * When hovering a link going to `to`, show the Obsidian hover-preview of that note. * @@ -2543,124 +2560,610 @@ async function openView(app, viewType, viewClass, side = "right") { return leaf.view; } -const MATRIX_VIEW = "BC-matrix"; -const STATS_VIEW = "BC-stats"; -const TRAIL_ICON = "BC-trail-icon"; -const TRAIL_ICON_SVG = ''; -const splitLinksRegex = new RegExp(/\[\[(.+?)\]\]/g); -const dropHeaderOrAlias = new RegExp(/\[\[([^#|]+)\]\]/); -const VISTYPES = [ - "Force Directed Graph", - "Tidy Tree", - "Circle Packing", - "Edge Bundling", - "Arc Diagram", - "Sunburst", - "Tree Map", - "Icicle", - "Radial Tree", -]; -const DIRECTIONS = ["up", "same", "down", "next", "prev"]; -const ARROW_DIRECTIONS = { - up: "↑", - same: "↔", - down: "↓", - next: "→", - prev: "←", -}; -const RELATIONS = ["Parent", "Sibling", "Child"]; -const REAlCLOSED = ["Real", "Closed"]; -const ALLUNLINKED = ["All", "No Unlinked"]; -const blankUserHier = () => { - return { up: [], same: [], down: [], next: [], prev: [] }; -}; -const blankDirObjs = () => { - return { - up: {}, - same: {}, - down: {}, - next: {}, - prev: {}, - }; -}; -const blankDirUndef = () => { - return { - up: undefined, - same: undefined, - down: undefined, - next: undefined, - prev: undefined, - }; -}; -const DEFAULT_SETTINGS = { - userHierarchies: [], - indexNote: [""], - CSVPaths: "", - hierarchyNotes: [""], - hierarchyNoteDownFieldName: "", - hierarchyNoteUpFieldName: "", - refreshIndexOnActiveLeafChange: false, - altLinkFields: [], - useAllMetadata: true, - parseJugglLinksWithoutJuggl: false, - dvWaitTime: 5000, - refreshIntervalTime: 0, - defaultView: true, - orderField: "order", - showNameOrType: true, - showRelationType: true, - filterImpliedSiblingsOfDifferentTypes: false, - rlLeaf: true, - showBCs: true, - showTrail: true, - showGrid: true, - showPrevNext: true, - limitTrailCheckboxStates: {}, - hideTrailFieldName: "hide-trail", - gridDots: false, - dotsColour: "#000000", - gridHeatmap: false, - heatmapColour: getComputedStyle(document.body).getPropertyValue("--text-accent"), - showAll: false, - noPathMessage: `This note has no real or implied parents`, - trailSeperator: "→", - respectReadableLineLength: true, - limitWriteBCCheckboxStates: {}, - writeBCsInline: false, - showWriteAllBCsCmd: false, - visGraph: "Force Directed Graph", - visRelation: "Parent", - visClosed: "Real", - visAll: "All", - wikilinkIndex: true, - aliasesInIndex: false, - debugMode: false, - superDebugMode: false, -}; +function noop$1() { } +function assign(tar, src) { + // @ts-ignore + for (const k in src) + tar[k] = src[k]; + return tar; +} +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 create_slot(definition, ctx, $$scope, fn) { + if (definition) { + const slot_ctx = get_slot_context(definition, ctx, $$scope, fn); + return definition[0](slot_ctx); + } +} +function get_slot_context(definition, ctx, $$scope, fn) { + return definition[1] && fn + ? assign($$scope.ctx.slice(), definition[1](fn(ctx))) + : $$scope.ctx; +} +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; + } + 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); + } +} +function exclude_internal_props(props) { + const result = {}; + for (const k in props) + if (k[0] !== '$') + result[k] = props[k]; + return result; +} +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 svg_element(name) { + return document.createElementNS('http://www.w3.org/2000/svg', 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(); +let outros; +function transition_in(block, local) { + if (block && block.i) { + outroing.delete(block); + block.i(local); + } +} +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 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; + } + } + } + for (const key in to_null_out) { + if (!(key in update)) + update[key] = undefined; + } + return update; +} +function get_spread_object(spread_props) { + return typeof spread_props === 'object' && spread_props !== null ? spread_props : {}; +} +function create_component(block) { + block && block.c(); +} +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$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); +} /** - * @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 + * Base class for Svelte components. Used when dev=false. */ +class SvelteComponent { + $destroy() { + destroy_component(this, 1); + this.$destroy = noop$1; + } + $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; + } + } +} -var lodash = createCommonjsModule(function (module, exports) { -(function() { +/* src\Components\Ducks.svelte generated by Svelte v3.35.0 */ - /** Used as a safe reference for `undefined` in pre-ES5 environments. */ - var undefined$1; +function get_each_context$8(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[9] = list[i]; + return child_ctx; +} - /** Used as the semantic version number. */ - var VERSION = '4.17.21'; +// (16:2) {#each ducks as duck} +function create_each_block$8(ctx) { + let div; + let a; + let t0_value = /*duck*/ ctx[9] + ""; + let t0; + let t1; + let mounted; + let dispose; - /** Used as the size to enable large array optimizations. */ - var LARGE_ARRAY_SIZE = 200; + function click_handler(...args) { + return /*click_handler*/ ctx[4](/*duck*/ ctx[9], ...args); + } - /** Error message constants. */ - var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.', + function mouseover_handler(...args) { + return /*mouseover_handler*/ ctx[5](/*duck*/ ctx[9], ...args); + } + + return { + c() { + div = element("div"); + a = element("a"); + t0 = text(t0_value); + t1 = space(); + attr(a, "class", "internal-link"); + }, + m(target, anchor) { + insert(target, div, anchor); + append(div, a); + append(a, t0); + append(div, t1); + + if (!mounted) { + dispose = [ + listen(div, "click", click_handler), + listen(div, "mouseover", mouseover_handler) + ]; + + mounted = true; + } + }, + p(new_ctx, dirty) { + ctx = new_ctx; + }, + d(detaching) { + if (detaching) detach(div); + mounted = false; + run_all(dispose); + } + }; +} + +function create_fragment$d(ctx) { + let div; + let h6; + let t1; + let each_value = /*ducks*/ ctx[2]; + let each_blocks = []; + + for (let i = 0; i < each_value.length; i += 1) { + each_blocks[i] = create_each_block$8(get_each_context$8(ctx, each_value, i)); + } + + return { + c() { + div = element("div"); + h6 = element("h6"); + h6.textContent = "Notes without Breadcrumbs"; + t1 = space(); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + + attr(div, "class", "BC-Ducks markdown-preview-view"); + }, + m(target, anchor) { + insert(target, div, anchor); + append(div, h6); + append(div, t1); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(div, null); + } + }, + p(ctx, [dirty]) { + if (dirty & /*openOrSwitch, app, ducks, hoverPreview, ducksView*/ 7) { + each_value = /*ducks*/ ctx[2]; + let i; + + for (i = 0; i < each_value.length; i += 1) { + const child_ctx = get_each_context$8(ctx, each_value, i); + + if (each_blocks[i]) { + each_blocks[i].p(child_ctx, dirty); + } else { + each_blocks[i] = create_each_block$8(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$1, + o: noop$1, + d(detaching) { + if (detaching) detach(div); + destroy_each(each_blocks, detaching); + } + }; +} + +function instance$d($$self, $$props, $$invalidate) { + + + + let { plugin } = $$props; + let { app } = $$props; + let { ducksView } = $$props; + const { main } = plugin.currGraphs; + const files = app.vault.getMarkdownFiles(); + const fileNames = files.map(file => file.basename); + const ducks = fileNames.filter(name => !main.neighbors(name).length); + const click_handler = async (duck, e) => await openOrSwitch$1(app, duck, e); + const mouseover_handler = (duck, e) => hoverPreview$1(e, ducksView, duck); + + $$self.$$set = $$props => { + if ("plugin" in $$props) $$invalidate(3, plugin = $$props.plugin); + if ("app" in $$props) $$invalidate(0, app = $$props.app); + if ("ducksView" in $$props) $$invalidate(1, ducksView = $$props.ducksView); + }; + + return [app, ducksView, ducks, plugin, click_handler, mouseover_handler]; +} + +class Ducks extends SvelteComponent { + constructor(options) { + super(); + init$1(this, options, instance$d, create_fragment$d, safe_not_equal, { plugin: 3, app: 0, ducksView: 1 }); + } +} + +class DucksView extends obsidian.ItemView { + constructor(leaf, plugin) { + super(leaf); + // TODO Duck icon + this.icon = "info"; + this.plugin = plugin; + } + async onload() { + super.onload(); + await this.plugin.saveSettings(); + this.app.workspace.onLayoutReady(async () => { + await this.draw(); + }); + } + getViewType() { + return STATS_VIEW; + } + getDisplayText() { + return "Breadcrumbs Ducks"; + } + async onOpen() { } + onClose() { + if (this.view) { + this.view.$destroy(); + } + return Promise.resolve(); + } + async draw() { + this.contentEl.empty(); + this.view = new Ducks({ + target: this.contentEl, + props: { plugin: this.plugin, app: this.app, ducksView: this }, + }); + } +} + +/** + * @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 = createCommonjsModule(function (module, exports) { +(function() { + + /** Used as a safe reference for `undefined` in pre-ES5 environments. */ + var undefined$1; + + /** Used as the semantic version number. */ + var VERSION = '4.17.21'; + + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** Error message constants. */ + var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.', FUNC_ERROR_TEXT = 'Expected a function', INVALID_TEMPL_VAR_ERROR_TEXT = 'Invalid `variable` option passed into `_.template`'; @@ -20474,592 +20977,203 @@ function getPrevNext(plugin, currNode) { } } -function noop$1() { } -function assign(tar, src) { - // @ts-ignore - for (const k in src) - tar[k] = src[k]; - return tar; -} -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 create_slot(definition, ctx, $$scope, fn) { - if (definition) { - const slot_ctx = get_slot_context(definition, ctx, $$scope, fn); - return definition[0](slot_ctx); - } -} -function get_slot_context(definition, ctx, $$scope, fn) { - return definition[1] && fn - ? assign($$scope.ctx.slice(), definition[1](fn(ctx))) - : $$scope.ctx; -} -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; - } - 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); - } -} -function exclude_internal_props(props) { - const result = {}; - for (const k in props) - if (k[0] !== '$') - result[k] = props[k]; - return result; -} -function null_to_empty(value) { - return value == null ? '' : value; -} +/* src\Components\Lists.svelte generated by Svelte v3.35.0 */ -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 svg_element(name) { - return document.createElementNS('http://www.w3.org/2000/svg', 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 add_css$7() { + var style = element("style"); + style.id = "svelte-ifpk85-style"; + style.textContent = "summary.hier-summary.svelte-ifpk85{color:var(--text-title-h2);font-size:larger}summary.svelte-ifpk85{color:var(--text-title-h3)}h5.BC-header.svelte-ifpk85{color:var(--text-title-h5)}ol.markdown-preview-view.svelte-ifpk85{padding-top:3px;padding-bottom:5px}"; + append(document.head, style); } -function children$1(element) { - return Array.from(element.childNodes); + +function get_each_context$7(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[9] = list[i]; + return child_ctx; } -function set_data(text, data) { - data = '' + data; - if (text.wholeText !== data) - text.data = data; + +function get_each_context_1$7(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[12] = list[i]; + return child_ctx; } -function set_style(node, key, value, important) { - node.style.setProperty(key, value, important ? 'important' : ''); + +function get_each_context_2$3(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[15] = list[i]; + return child_ctx; } -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; - } - } + +function get_each_context_3$2(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[18] = list[i]; + return child_ctx; } -let current_component; -function set_current_component(component) { - current_component = component; +// (20: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); + + 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-ifpk85"); + details.open = true; + attr(details, "class", "BC-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; + } + + 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(); + } + }; } -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); - } +// (23: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-ifpk85"); + }, + 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); + } + }; } -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(); -let outros; -function transition_in(block, local) { - if (block && block.i) { - outroing.delete(block); - block.i(local); - } -} -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 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; - } - } - } - for (const key in to_null_out) { - if (!(key in update)) - update[key] = undefined; - } - return update; -} -function get_spread_object(spread_props) { - return typeof spread_props === 'object' && spread_props !== null ? spread_props : {}; -} -function create_component(block) { - block && block.c(); -} -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$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); -} -/** - * Base class for Svelte components. Used when dev=false. - */ -class SvelteComponent { - $destroy() { - destroy_component(this, 1); - this.$destroy = noop$1; - } - $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\Lists.svelte generated by Svelte v3.35.0 */ - -function add_css$7() { - var style = element("style"); - style.id = "svelte-ifpk85-style"; - style.textContent = "summary.hier-summary.svelte-ifpk85{color:var(--text-title-h2);font-size:larger}summary.svelte-ifpk85{color:var(--text-title-h3)}h5.BC-header.svelte-ifpk85{color:var(--text-title-h5)}ol.markdown-preview-view.svelte-ifpk85{padding-top:3px;padding-bottom:5px}"; - append(document.head, style); -} - -function get_each_context$7(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[9] = list[i]; - return child_ctx; -} - -function get_each_context_1$7(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; -} - -// (20: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); - - 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-ifpk85"); - details.open = true; - attr(details, "class", "BC-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; - } - - 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(); - } - }; -} - -// (23: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-ifpk85"); - }, - 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); - } - }; -} - -// (24:14) {#if settings.showRelationType} -function create_if_block_4$1(ctx) { - let h5; - - return { - c() { - h5 = element("h5"); - h5.textContent = "Real"; - attr(h5, "class", "BC-header svelte-ifpk85"); - }, - m(target, anchor) { - insert(target, h5, anchor); - }, - d(detaching) { - if (detaching) detach(h5); - } - }; + +// (24:14) {#if settings.showRelationType} +function create_if_block_4$1(ctx) { + let h5; + + return { + c() { + h5 = element("h5"); + h5.textContent = "Real"; + attr(h5, "class", "BC-header svelte-ifpk85"); + }, + m(target, anchor) { + insert(target, h5, anchor); + }, + d(detaching) { + if (detaching) detach(h5); + } + }; } // (29:16) {#each square.realItems as realItem} @@ -22455,2465 +22569,2039 @@ class MatrixView extends obsidian.ItemView { } } -/* src\Components\KoFi.svelte generated by Svelte v3.35.0 */ - -function create_fragment$a(ctx) { - let script; - let script_src_value; - let t; - let div; - let mounted; - let dispose; +/* src\Components\Stats.svelte generated by Svelte v3.35.0 */ - 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 add_css$5() { + 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); +} - 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 get_each_context$5(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[27] = list[i]; + return child_ctx; } -function instance$a($$self, $$props, $$invalidate) { - let button; +function get_each_context_1$5(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[27] = list[i]; + return child_ctx; +} - var initializeKofi = () => { - kofiwidget2.init("Support Breadcrumbs development!", "#29abe0", "G2G454TZF"); - $$invalidate(0, button.innerHTML = kofiwidget2.getHTML(), button); - }; +function get_each_context_2$1(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[27] = list[i]; + return child_ctx; +} - function div_binding($$value) { - binding_callbacks[$$value ? "unshift" : "push"](() => { - button = $$value; - $$invalidate(0, button); - }); - } +function get_each_context_3(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[34] = list[i]; + child_ctx[36] = i; + return child_ctx; +} - return [button, initializeKofi, div_binding]; +function get_each_context_4(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[27] = list[i]; + return child_ctx; } -class KoFi extends SvelteComponent { - constructor(options) { - super(); - init$1(this, options, instance$a, create_fragment$a, safe_not_equal, {}); - } +function get_each_context_5(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[27] = list[i]; + return child_ctx; } -/* node_modules\svelte-icons\components\IconBase.svelte generated by Svelte v3.35.0 */ +function get_each_context_6(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[27] = list[i]; + return child_ctx; +} -function add_css$5() { - 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); +function get_each_context_7(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[27] = list[i]; + return child_ctx; } -// (18:2) {#if title} -function create_if_block$2(ctx) { - let title_1; +// (89:4) {#each DIRECTIONS as dir} +function create_each_block_7(ctx) { + let td; + let t_value = ARROW_DIRECTIONS[/*dir*/ ctx[27]] + ""; let t; return { c() { - title_1 = svg_element("title"); - t = text(/*title*/ ctx[0]); + td = element("td"); + t = text(t_value); + attr(td, "class", "svelte-rb5mhu"); }, 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]); + insert(target, td, anchor); + append(td, t); }, + p: noop$1, d(detaching) { - if (detaching) detach(title_1); + if (detaching) detach(td); } }; } -function create_fragment$9(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); +// (101:6) {#each DIRECTIONS as dir} +function create_each_block_6(ctx) { + let td; + let t0_value = /*data*/ ctx[1][/*i*/ ctx[36]][/*dir*/ ctx[27]].Merged.nodes.length + ""; + let t0; + let t1; + let td_aria_label_value; + let mounted; + let dispose; + + function click_handler() { + return /*click_handler*/ ctx[5](/*i*/ ctx[36], /*dir*/ ctx[27]); + } 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"); + td = element("td"); + t0 = text(t0_value); + t1 = space(); + attr(td, "aria-label-position", "left"); + attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1][/*i*/ ctx[36]][/*dir*/ ctx[27]].Merged.nodesStr); + attr(td, "class", "svelte-rb5mhu"); }, m(target, anchor) { - insert(target, svg, anchor); - if (if_block) if_block.m(svg, null); - append(svg, if_block_anchor); - - if (default_slot) { - default_slot.m(svg, null); - } - - 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; - } - - if (default_slot) { - if (default_slot.p && dirty & /*$$scope*/ 4) { - update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[2], dirty, null, null); - } - } + insert(target, td, anchor); + append(td, t0); + append(td, t1); - if (!current || dirty & /*viewBox*/ 2) { - attr(svg, "viewBox", /*viewBox*/ ctx[1]); + if (!mounted) { + dispose = listen(td, "click", click_handler); + mounted = true; } }, - i(local) { - if (current) return; - transition_in(default_slot, local); - current = true; - }, - o(local) { - transition_out(default_slot, local); - current = false; + p(new_ctx, dirty) { + ctx = new_ctx; }, d(detaching) { - if (detaching) detach(svg); - if (if_block) if_block.d(); - if (default_slot) default_slot.d(detaching); + if (detaching) detach(td); + mounted = false; + dispose(); } }; } -function instance$9($$self, $$props, $$invalidate) { - let { $$slots: slots = {}, $$scope } = $$props; - let { title = null } = $$props; - let { viewBox } = $$props; - - $$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); - }; - - return [title, viewBox, $$scope, slots]; -} +// (122:6) {#each DIRECTIONS as dir} +function create_each_block_5(ctx) { + let td; + let t0_value = /*data*/ ctx[1][/*i*/ ctx[36]][/*dir*/ ctx[27]].Merged.edges.length + ""; + let t0; + let t1; + let td_aria_label_value; + let mounted; + let dispose; -class IconBase extends SvelteComponent { - constructor(options) { - super(); - if (!document.getElementById("svelte-c8tyih-style")) add_css$5(); - init$1(this, options, instance$9, create_fragment$9, safe_not_equal, { title: 0, viewBox: 1 }); + function click_handler_2() { + return /*click_handler_2*/ ctx[8](/*i*/ ctx[36], /*dir*/ ctx[27]); } -} - -/* node_modules\svelte-icons\fa\FaListUl.svelte generated by Svelte v3.35.0 */ - -function create_default_slot$2(ctx) { - let path; 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"); + td = element("td"); + t0 = text(t0_value); + t1 = space(); + attr(td, "aria-label-position", "left"); + attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1][/*i*/ ctx[36]][/*dir*/ ctx[27]].Merged.edgesStr); + attr(td, "class", "svelte-rb5mhu"); }, m(target, anchor) { - insert(target, path, anchor); + insert(target, td, anchor); + append(td, t0); + append(td, t1); + + if (!mounted) { + dispose = listen(td, "click", click_handler_2); + mounted = true; + } + }, + p(new_ctx, dirty) { + ctx = new_ctx; }, d(detaching) { - if (detaching) detach(path); + if (detaching) detach(td); + mounted = false; + dispose(); } }; } -function create_fragment$8(ctx) { - let iconbase; - let current; - const iconbase_spread_levels = [{ viewBox: "0 0 512 512" }, /*$$props*/ ctx[0]]; - - let iconbase_props = { - $$slots: { default: [create_default_slot$2] }, - $$scope: { ctx } - }; +// (143:6) {#each DIRECTIONS as dir} +function create_each_block_4(ctx) { + let td; + let t0_value = /*data*/ ctx[1][/*i*/ ctx[36]][/*dir*/ ctx[27]].Implied.edges.length + ""; + let t0; + let t1; + let td_aria_label_value; + let mounted; + let dispose; - for (let i = 0; i < iconbase_spread_levels.length; i += 1) { - iconbase_props = assign(iconbase_props, iconbase_spread_levels[i]); + function click_handler_4() { + return /*click_handler_4*/ ctx[11](/*i*/ ctx[36], /*dir*/ ctx[27]); } - iconbase = new IconBase({ props: iconbase_props }); - return { c() { - create_component(iconbase.$$.fragment); + td = element("td"); + t0 = text(t0_value); + t1 = space(); + attr(td, "aria-label-position", "left"); + attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1][/*i*/ ctx[36]][/*dir*/ ctx[27]].Implied.edgesStr); + attr(td, "class", "svelte-rb5mhu"); }, 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])]) - : {}; + insert(target, td, anchor); + append(td, t0); + append(td, t1); - if (dirty & /*$$scope*/ 2) { - iconbase_changes.$$scope = { dirty, ctx }; + if (!mounted) { + dispose = listen(td, "click", click_handler_4); + mounted = true; } - - 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; + p(new_ctx, dirty) { + ctx = new_ctx; }, d(detaching) { - destroy_component(iconbase, detaching); + if (detaching) detach(td); + mounted = false; + dispose(); } }; } -function instance$8($$self, $$props, $$invalidate) { - $$self.$$set = $$new_props => { - $$invalidate(0, $$props = assign(assign({}, $$props), exclude_internal_props($$new_props))); - }; +// (95:2) {#each userHierarchies as hier, i} +function create_each_block_3(ctx) { + let tr0; + let td0; + let t0_value = /*hierStrs*/ ctx[3][/*i*/ ctx[36]] + ""; + let t0; + let t1; + let td1; + let t3; + let t4; + let td2; + let t5_value = lodash.sum(DIRECTIONS.map(func)) + ""; + let t5; + let td2_aria_label_value; + let t6; + let tr1; + let td3; + let t8; + let t9; + let td4; + let t10_value = lodash.sum(DIRECTIONS.map(func_1)) + ""; + let t10; + let td4_aria_label_value; + let t11; + let tr2; + let td5; + let t13; + let t14; + let td6; + let t15_value = lodash.sum(DIRECTIONS.map(func_2)) + ""; + let t15; + let td6_aria_label_value; + let mounted; + let dispose; + let each_value_6 = DIRECTIONS; + let each_blocks_2 = []; - $$props = exclude_internal_props($$props); - return [$$props]; -} + for (let i = 0; i < each_value_6.length; i += 1) { + each_blocks_2[i] = create_each_block_6(get_each_context_6(ctx, each_value_6, i)); + } -class FaListUl extends SvelteComponent { - constructor(options) { - super(); - init$1(this, options, instance$8, create_fragment$8, safe_not_equal, {}); + function func(...args) { + return /*func*/ ctx[6](/*i*/ ctx[36], ...args); } -} -/* node_modules\svelte-icons\fa\FaPlus.svelte generated by Svelte v3.35.0 */ + function click_handler_1() { + return /*click_handler_1*/ ctx[7](/*i*/ ctx[36]); + } -function create_default_slot$1(ctx) { - let path; + let each_value_5 = DIRECTIONS; + let each_blocks_1 = []; - 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); - } - }; -} + for (let i = 0; i < each_value_5.length; i += 1) { + each_blocks_1[i] = create_each_block_5(get_each_context_5(ctx, each_value_5, i)); + } -function create_fragment$7(ctx) { - let iconbase; - let current; - const iconbase_spread_levels = [{ viewBox: "0 0 448 512" }, /*$$props*/ ctx[0]]; + function func_1(...args) { + return /*func_1*/ ctx[9](/*i*/ ctx[36], ...args); + } - let iconbase_props = { - $$slots: { default: [create_default_slot$1] }, - $$scope: { ctx } - }; + function click_handler_3() { + return /*click_handler_3*/ ctx[10](/*i*/ ctx[36]); + } - for (let i = 0; i < iconbase_spread_levels.length; i += 1) { - iconbase_props = assign(iconbase_props, iconbase_spread_levels[i]); + let each_value_4 = DIRECTIONS; + let each_blocks = []; + + for (let i = 0; i < each_value_4.length; i += 1) { + each_blocks[i] = create_each_block_4(get_each_context_4(ctx, each_value_4, i)); } - iconbase = new IconBase({ props: iconbase_props }); + function func_2(...args) { + return /*func_2*/ ctx[12](/*i*/ ctx[36], ...args); + } + + function click_handler_5() { + return /*click_handler_5*/ ctx[13](/*i*/ ctx[36]); + } 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])]) - : {}; + tr0 = element("tr"); + td0 = element("td"); + t0 = text(t0_value); + t1 = space(); + td1 = element("td"); + td1.textContent = "Nodes"; + t3 = space(); - if (dirty & /*$$scope*/ 2) { - iconbase_changes.$$scope = { dirty, ctx }; + for (let i = 0; i < each_blocks_2.length; i += 1) { + each_blocks_2[i].c(); } - 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 instance$7($$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]; -} + t4 = space(); + td2 = element("td"); + t5 = text(t5_value); + t6 = space(); + tr1 = element("tr"); + td3 = element("td"); + td3.textContent = "Real Edges"; + t8 = space(); -class FaPlus extends SvelteComponent { - constructor(options) { - super(); - init$1(this, options, instance$7, create_fragment$7, safe_not_equal, {}); - } -} + for (let i = 0; i < each_blocks_1.length; i += 1) { + each_blocks_1[i].c(); + } -/* node_modules\svelte-icons\fa\FaRegTrashAlt.svelte generated by Svelte v3.35.0 */ + t9 = space(); + td4 = element("td"); + t10 = text(t10_value); + t11 = space(); + tr2 = element("tr"); + td5 = element("td"); + td5.textContent = "Implied Edges"; + t13 = space(); -function create_default_slot(ctx) { - let path; + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } - 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"); + 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-position", "left"); + attr(td2, "aria-label", td2_aria_label_value = /*cellStr*/ ctx[2](/*i*/ ctx[36], "Merged", "nodesStr")); + attr(td2, "class", "svelte-rb5mhu"); + attr(td3, "class", "svelte-rb5mhu"); + attr(td4, "aria-label-position", "left"); + attr(td4, "aria-label", td4_aria_label_value = /*cellStr*/ ctx[2](/*i*/ ctx[36], "Merged", "edgesStr")); + attr(td4, "class", "svelte-rb5mhu"); + attr(td5, "class", "svelte-rb5mhu"); + attr(td6, "aria-label-position", "left"); + attr(td6, "aria-label", td6_aria_label_value = /*cellStr*/ ctx[2](/*i*/ ctx[36], "Implied", "edgesStr")); + attr(td6, "class", "svelte-rb5mhu"); }, m(target, anchor) { - insert(target, path, anchor); - }, - d(detaching) { - if (detaching) detach(path); - } - }; -} + insert(target, tr0, anchor); + append(tr0, td0); + append(td0, t0); + append(tr0, t1); + append(tr0, td1); + append(tr0, t3); -function create_fragment$6(ctx) { - let iconbase; - let current; - const iconbase_spread_levels = [{ viewBox: "0 0 448 512" }, /*$$props*/ ctx[0]]; + for (let i = 0; i < each_blocks_2.length; i += 1) { + each_blocks_2[i].m(tr0, null); + } - let iconbase_props = { - $$slots: { default: [create_default_slot] }, - $$scope: { ctx } - }; + 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 < iconbase_spread_levels.length; i += 1) { - iconbase_props = assign(iconbase_props, iconbase_spread_levels[i]); - } + for (let i = 0; i < each_blocks_1.length; i += 1) { + each_blocks_1[i].m(tr1, null); + } - iconbase = new IconBase({ props: iconbase_props }); + append(tr1, t9); + append(tr1, td4); + append(td4, t10); + insert(target, t11, anchor); + insert(target, tr2, anchor); + append(tr2, td5); + append(tr2, t13); - return { - c() { - create_component(iconbase.$$.fragment); - }, - m(target, anchor) { - mount_component(iconbase, target, anchor); - current = true; + for (let i = 0; i < each_blocks.length; 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(ctx, [dirty]) { - const iconbase_changes = (dirty & /*$$props*/ 1) - ? get_spread_update(iconbase_spread_levels, [iconbase_spread_levels[0], get_spread_object(/*$$props*/ ctx[0])]) - : {}; + p(new_ctx, dirty) { + ctx = new_ctx; - if (dirty & /*$$scope*/ 2) { - iconbase_changes.$$scope = { dirty, ctx }; + if (dirty[0] & /*data*/ 2) { + each_value_6 = DIRECTIONS; + let i; + + for (i = 0; i < each_value_6.length; 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 < each_blocks_2.length; i += 1) { + each_blocks_2[i].d(1); + } + + each_blocks_2.length = each_value_6.length; } - 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); - } - }; -} + if (dirty[0] & /*data*/ 2) { + each_value_5 = DIRECTIONS; + let i; -function instance$6($$self, $$props, $$invalidate) { - $$self.$$set = $$new_props => { - $$invalidate(0, $$props = assign(assign({}, $$props), exclude_internal_props($$new_props))); - }; + for (i = 0; i < each_value_5.length; i += 1) { + const child_ctx = get_each_context_5(ctx, each_value_5, i); - $$props = exclude_internal_props($$props); - return [$$props]; -} + 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); + } + } -class FaRegTrashAlt extends SvelteComponent { - constructor(options) { - super(); - init$1(this, options, instance$6, create_fragment$6, safe_not_equal, {}); - } -} + for (; i < each_blocks_1.length; i += 1) { + each_blocks_1[i].d(1); + } -/* src\Components\UserHierarchies.svelte generated by Svelte v3.35.0 */ + each_blocks_1.length = each_value_5.length; + } -function add_css$4() { - var style = element("style"); - style.id = "svelte-5y4abu-style"; - style.textContent = "label.BC-Arrow-Label.svelte-5y4abu.svelte-5y4abu{display:inline-block;width:20px !important}div.GA-Buttons.svelte-5y4abu.svelte-5y4abu{padding-bottom:5px}details.BC-Hier-Details.svelte-5y4abu.svelte-5y4abu{border:1px solid var(--background-modifier-border);border-radius:10px;padding:10px 5px 10px 10px;margin-bottom:15px}.BC-Hier-Details.svelte-5y4abu summary.svelte-5y4abu::marker{font-size:10px}.BC-Hier-Details.svelte-5y4abu summary button.svelte-5y4abu{float:right}.icon.svelte-5y4abu.svelte-5y4abu{color:var(--text-normal);display:inline-block;padding-top:3px;width:17px;height:17px}"; - append(document.head, style); -} + if (dirty[0] & /*data*/ 2) { + each_value_4 = DIRECTIONS; + let i; -function get_each_context$5(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[12] = list[i]; - child_ctx[14] = i; - return child_ctx; -} + for (i = 0; i < each_value_4.length; i += 1) { + const child_ctx = get_each_context_4(ctx, each_value_4, i); -function get_each_context_1$5(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[15] = list[i]; - return child_ctx; + 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 < each_blocks.length; i += 1) { + each_blocks[i].d(1); + } + + each_blocks.length = each_value_4.length; + } + }, + 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); + } + }; } -// (92:6) {#each DIRECTIONS as dir} -function create_each_block_1$5(ctx) { - let div; - let label; - let t0_value = ARROW_DIRECTIONS[/*dir*/ ctx[15]] + ""; +// (166:4) {#each DIRECTIONS as dir} +function create_each_block_2$1(ctx) { + let td; + let t0_value = lodash.sum(/*data*/ ctx[1].map(func_3)) + ""; let t0; - let label_for_value; let t1; - let input; - let input_name_value; - let input_value_value; + let td_aria_label_value; let mounted; let dispose; - function change_handler(...args) { - return /*change_handler*/ ctx[10](/*i*/ ctx[14], /*dir*/ ctx[15], ...args); + function func_3(...args) { + return /*func_3*/ ctx[14](/*dir*/ ctx[27], ...args); + } + + function func_4(...args) { + return /*func_4*/ ctx[15](/*dir*/ ctx[27], ...args); + } + + function click_handler_6() { + return /*click_handler_6*/ ctx[16](/*dir*/ ctx[27]); } return { c() { - div = element("div"); - label = element("label"); + td = element("td"); t0 = text(t0_value); t1 = space(); - input = element("input"); - attr(label, "class", "BC-Arrow-Label svelte-5y4abu"); - attr(label, "for", label_for_value = /*dir*/ ctx[15]); - attr(input, "type", "text"); - attr(input, "size", "20"); - attr(input, "name", input_name_value = /*dir*/ ctx[15]); - input.value = input_value_value = /*hier*/ ctx[12][/*dir*/ ctx[15]]?.join(", ") ?? ""; + attr(td, "aria-label-position", "left"); + attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1].map(func_4).join("\n")); + attr(td, "class", "svelte-rb5mhu"); }, m(target, anchor) { - insert(target, div, anchor); - append(div, label); - append(label, t0); - append(div, t1); - append(div, input); + insert(target, td, anchor); + append(td, t0); + append(td, t1); if (!mounted) { - dispose = listen(input, "change", change_handler); + dispose = listen(td, "click", click_handler_6); mounted = true; } }, p(new_ctx, dirty) { ctx = new_ctx; - - if (dirty & /*currHiers*/ 1 && input_value_value !== (input_value_value = /*hier*/ ctx[12][/*dir*/ ctx[15]]?.join(", ") ?? "") && input.value !== input_value_value) { - input.value = input_value_value; - } }, d(detaching) { - if (detaching) detach(div); + if (detaching) detach(td); mounted = false; dispose(); } }; } -// (60:2) {#each currHiers as hier, i} -function create_each_block$5(ctx) { - let details; - let summary; - let t0_value = DIRECTIONS.map(func).map(func_1).join(" ") + ""; +// (208:4) {#each DIRECTIONS as dir} +function create_each_block_1$5(ctx) { + let td; + let t0_value = lodash.sum(/*data*/ ctx[1].map(func_5)) + ""; let t0; let t1; - let span; - let button0; - let t3; - let button1; - let t5; - let button2; - let t7; - let t8; + let td_aria_label_value; let mounted; let dispose; - function func(...args) { - return /*func*/ ctx[6](/*hier*/ ctx[12], ...args); - } - - function click_handler_3() { - return /*click_handler_3*/ ctx[7](/*i*/ ctx[14]); - } - - function click_handler_4() { - return /*click_handler_4*/ ctx[8](/*i*/ ctx[14]); + function func_5(...args) { + return /*func_5*/ ctx[17](/*dir*/ ctx[27], ...args); } - function click_handler_5() { - return /*click_handler_5*/ ctx[9](/*i*/ ctx[14]); + function func_6(...args) { + return /*func_6*/ ctx[18](/*dir*/ ctx[27], ...args); } - let each_value_1 = DIRECTIONS; - 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)); + function click_handler_7() { + return /*click_handler_7*/ ctx[19](/*dir*/ ctx[27]); } return { c() { - details = element("details"); - summary = element("summary"); + td = element("td"); t0 = text(t0_value); t1 = space(); - span = element("span"); - button0 = element("button"); - button0.textContent = "↑"; - t3 = space(); - button1 = element("button"); - button1.textContent = "↓"; - t5 = space(); - button2 = element("button"); - button2.textContent = "X"; - t7 = space(); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].c(); - } - - t8 = space(); - attr(button0, "aria-label", "Swap with Hierarchy Above"); - attr(button0, "class", "svelte-5y4abu"); - attr(button1, "aria-label", "Swap with Hierarchy Below"); - attr(button1, "class", "svelte-5y4abu"); - attr(button2, "aria-label", "Remove Hierarchy"); - attr(button2, "class", "svelte-5y4abu"); - attr(span, "class", "GA-Buttons"); - attr(summary, "class", "svelte-5y4abu"); - attr(details, "class", "BC-Hier-Details svelte-5y4abu"); + attr(td, "aria-label-position", "left"); + attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1].map(func_6).join("\n")); + attr(td, "class", "svelte-rb5mhu"); }, m(target, anchor) { - insert(target, details, anchor); - append(details, summary); - append(summary, t0); - append(summary, t1); - append(summary, span); - append(span, button0); - append(span, t3); - append(span, button1); - append(span, t5); - append(span, button2); - append(details, t7); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].m(details, null); - } - - append(details, t8); + insert(target, td, anchor); + append(td, t0); + append(td, t1); if (!mounted) { - dispose = [ - listen(button0, "click", click_handler_3), - listen(button1, "click", click_handler_4), - listen(button2, "click", click_handler_5) - ]; - + dispose = listen(td, "click", click_handler_7); mounted = true; } }, p(new_ctx, dirty) { ctx = new_ctx; - if (dirty & /*currHiers*/ 1 && t0_value !== (t0_value = DIRECTIONS.map(func).map(func_1).join(" ") + "")) set_data(t0, t0_value); - - if (dirty & /*DIRECTIONS, currHiers, splitAndTrim, update, ARROW_DIRECTIONS*/ 3) { - each_value_1 = DIRECTIONS; - 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, t8); - } - } - - 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); + if (detaching) detach(td); mounted = false; - run_all(dispose); + dispose(); } }; } -function create_fragment$5(ctx) { - let div4; - let div3; - let button0; - let div0; - let faplus; +// (246:4) {#each DIRECTIONS as dir} +function create_each_block$5(ctx) { + let td; + let t0_value = lodash.sum(/*data*/ ctx[1].map(func_7)) + ""; let t0; - let button1; - let div1; - let faregtrashalt; let t1; - let button2; - let div2; - let falistul; - let t2; - let current; + let td_aria_label_value; let mounted; let dispose; - faplus = new FaPlus({}); - faregtrashalt = new FaRegTrashAlt({}); - falistul = new FaListUl({}); - let each_value = /*currHiers*/ 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)); + function func_7(...args) { + return /*func_7*/ ctx[20](/*dir*/ ctx[27], ...args); + } + + function func_8(...args) { + return /*func_8*/ ctx[21](/*dir*/ ctx[27], ...args); + } + + function click_handler_8() { + return /*click_handler_8*/ ctx[22](/*dir*/ ctx[27]); } 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); + td = element("td"); + t0 = text(t0_value); 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-5y4abu"); - attr(button0, "aria-label", "Add New Hierarchy"); - attr(div1, "class", "icon svelte-5y4abu"); - attr(button1, "aria-label", "Reset All Hierarchies"); - attr(div2, "class", "icon svelte-5y4abu"); - attr(button2, "aria-label", "Show Hierarchies"); - attr(div3, "class", "GA-Buttons svelte-5y4abu"); + attr(td, "aria-label-position", "left"); + attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1].map(func_8).join("\n")); + attr(td, "class", "svelte-rb5mhu"); }, 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); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].m(div4, null); - } - - current = true; + insert(target, td, anchor); + append(td, t0); + append(td, t1); if (!mounted) { - dispose = [ - listen(button0, "click", /*click_handler*/ ctx[3]), - listen(button1, "click", /*click_handler_1*/ ctx[4]), - listen(button2, "click", /*click_handler_2*/ ctx[5]) - ]; - + dispose = listen(td, "click", click_handler_8); mounted = true; } }, - p(ctx, [dirty]) { - if (dirty & /*DIRECTIONS, currHiers, splitAndTrim, update, ARROW_DIRECTIONS, swapItems*/ 3) { - each_value = /*currHiers*/ ctx[0]; - let i; - - for (i = 0; i < each_value.length; i += 1) { - const child_ctx = get_each_context$5(ctx, each_value, i); + p(new_ctx, dirty) { + ctx = new_ctx; + }, + d(detaching) { + if (detaching) detach(td); + mounted = false; + dispose(); + } + }; +} - 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(div4, null); +function create_fragment$a(ctx) { + let table; + let thead; + let tr0; + let th0; + let t1; + let th1; + let t2; + let t3; + let tr1; + let td0; + let t4; + let td1; + let t6; + let t7; + let td2; + let t9; + let t10; + let tr2; + let td3; + let t12; + let td4; + let t14; + let t15; + let tr3; + let td5; + let t17; + let t18; + let tr4; + let td6; + let t20; + let each_value_7 = DIRECTIONS; + let each_blocks_4 = []; + + for (let i = 0; i < each_value_7.length; i += 1) { + each_blocks_4[i] = create_each_block_7(get_each_context_7(ctx, each_value_7, i)); + } + + 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 = DIRECTIONS; + let each_blocks_2 = []; + + for (let i = 0; i < each_value_2.length; 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 = DIRECTIONS; + let each_blocks_1 = []; + + for (let i = 0; i < each_value_1.length; i += 1) { + each_blocks_1[i] = create_each_block_1$5(get_each_context_1$5(ctx, each_value_1, i)); + } + + let each_value = DIRECTIONS; + 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() { + table = element("table"); + thead = element("thead"); + tr0 = element("tr"); + th0 = element("th"); + th0.textContent = "Hierarchy"; + t1 = space(); + th1 = element("th"); + t2 = text("Count"); + t3 = space(); + tr1 = element("tr"); + td0 = element("td"); + t4 = space(); + td1 = element("td"); + td1.textContent = "Measure"; + t6 = space(); + + for (let i = 0; i < each_blocks_4.length; i += 1) { + each_blocks_4[i].c(); + } + + t7 = space(); + td2 = element("td"); + td2.textContent = "Total"; + t9 = space(); + + for (let i = 0; i < each_blocks_3.length; i += 1) { + each_blocks_3[i].c(); + } + + t10 = space(); + tr2 = element("tr"); + td3 = element("td"); + td3.textContent = "Totals"; + t12 = space(); + td4 = element("td"); + td4.textContent = "Nodes"; + t14 = space(); + + for (let i = 0; i < each_blocks_2.length; i += 1) { + each_blocks_2[i].c(); + } + + t15 = space(); + tr3 = element("tr"); + td5 = element("td"); + td5.textContent = "Real Edges"; + t17 = space(); + + for (let i = 0; i < each_blocks_1.length; i += 1) { + each_blocks_1[i].c(); + } + + t18 = space(); + tr4 = element("tr"); + td6 = element("td"); + td6.textContent = "Implied Edges"; + t20 = space(); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + + attr(th0, "scope", "col"); + attr(th0, "class", "svelte-rb5mhu"); + attr(th1, "scope", "col"); + attr(th1, "colspan", DIRECTIONS.length + 2); + attr(th1, "class", "svelte-rb5mhu"); + attr(td0, "class", "svelte-rb5mhu"); + attr(td1, "class", "svelte-rb5mhu"); + attr(td2, "class", "svelte-rb5mhu"); + attr(td3, "rowspan", "3"); + attr(td3, "class", "svelte-rb5mhu"); + attr(td4, "class", "svelte-rb5mhu"); + attr(td5, "class", "svelte-rb5mhu"); + attr(td6, "class", "svelte-rb5mhu"); + attr(table, "class", "svelte-rb5mhu"); + }, + m(target, anchor) { + insert(target, table, anchor); + append(table, thead); + append(thead, tr0); + append(tr0, th0); + append(tr0, t1); + append(tr0, th1); + append(th1, t2); + append(table, t3); + append(table, tr1); + append(tr1, td0); + append(tr1, t4); + append(tr1, td1); + append(tr1, t6); + + for (let i = 0; i < each_blocks_4.length; i += 1) { + each_blocks_4[i].m(tr1, null); + } + + append(tr1, t7); + append(tr1, td2); + append(table, t9); + + for (let i = 0; i < each_blocks_3.length; i += 1) { + each_blocks_3[i].m(table, null); + } + + append(table, t10); + append(table, tr2); + append(tr2, td3); + append(tr2, t12); + append(tr2, td4); + append(tr2, t14); + + for (let i = 0; i < each_blocks_2.length; i += 1) { + each_blocks_2[i].m(tr2, null); + } + + append(table, t15); + append(table, tr3); + append(tr3, td5); + append(tr3, t17); + + for (let i = 0; i < each_blocks_1.length; i += 1) { + each_blocks_1[i].m(tr3, null); + } + + append(table, t18); + append(table, tr4); + append(tr4, td6); + append(tr4, t20); + + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(tr4, null); + } + }, + p(ctx, dirty) { + if (dirty & /*ARROW_DIRECTIONS, DIRECTIONS*/ 0) { + each_value_7 = DIRECTIONS; + let i; + + for (i = 0; i < each_value_7.length; i += 1) { + const child_ctx = get_each_context_7(ctx, each_value_7, i); + + if (each_blocks_4[i]) { + each_blocks_4[i].p(child_ctx, dirty); + } else { + each_blocks_4[i] = create_each_block_7(child_ctx); + each_blocks_4[i].c(); + each_blocks_4[i].m(tr1, t7); } } - for (; i < each_blocks.length; i += 1) { - each_blocks[i].d(1); + for (; i < each_blocks_4.length; i += 1) { + each_blocks_4[i].d(1); } - each_blocks.length = each_value.length; + each_blocks_4.length = each_value_7.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); - } - }; -} -const func_1 = dirFields => `(${dirFields})`; + if (dirty[0] & /*cellStr, data, hierStrs*/ 14) { + each_value_3 = /*userHierarchies*/ ctx[0]; + let i; -function instance$5($$self, $$props, $$invalidate) { - var __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) { - function adopt(value) { - return value instanceof P - ? value - : new P(function (resolve) { - resolve(value); - }); - } + for (i = 0; i < each_value_3.length; i += 1) { + const child_ctx = get_each_context_3(ctx, each_value_3, i); - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { - try { - step(generator.next(value)); - } catch(e) { - reject(e); + 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, t10); } } - function rejected(value) { - try { - step(generator["throw"](value)); - } catch(e) { - reject(e); + 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 = DIRECTIONS; + let i; + + for (i = 0; i < each_value_2.length; 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); } } - function step(result) { - result.done - ? resolve(result.value) - : adopt(result.value).then(fulfilled, rejected); + for (; i < each_blocks_2.length; i += 1) { + each_blocks_2[i].d(1); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); + each_blocks_2.length = each_value_2.length; + } + + if (dirty[0] & /*data*/ 2) { + each_value_1 = DIRECTIONS; + 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_1[i]) { + each_blocks_1[i].p(child_ctx, dirty); + } else { + each_blocks_1[i] = create_each_block_1$5(child_ctx); + each_blocks_1[i].c(); + each_blocks_1[i].m(tr3, null); + } + } + + for (; i < each_blocks_1.length; i += 1) { + each_blocks_1[i].d(1); + } + + each_blocks_1.length = each_value_1.length; + } + + if (dirty[0] & /*data*/ 2) { + each_value = DIRECTIONS; + 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(tr4, null); + } + } + + for (; i < each_blocks.length; i += 1) { + each_blocks[i].d(1); + } + + each_blocks.length = each_value.length; + } + }, + i: noop$1, + o: noop$1, + d(detaching) { + if (detaching) detach(table); + destroy_each(each_blocks_4, detaching); + 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$a($$self, $$props, $$invalidate) { + let { plugin } = $$props; - let currHiers = [...plugin.settings.userHierarchies]; + const { settings } = plugin; + const { userHierarchies, trailSeperator } = settings; + const hierGs = plugin.currGraphs; - function update(currHiers) { - return __awaiter(this, void 0, void 0, function* () { - $$invalidate(2, plugin.settings.userHierarchies = currHiers, plugin); - yield plugin.saveSettings(); - }); + function fillInInfo(dir, gType, hierData, nodesToo = true) { + const gInfo = hierData[dir][gType]; + + if (nodesToo) { + gInfo.nodes = gInfo.graph.nodes(); + gInfo.nodesStr = gInfo.nodes.map(n => makeWiki(settings.wikilinkIndex, n)).join("\n"); + } + + gInfo.edges = gInfo.graph.edges(); + const edgeStrArr = gInfo.graph.mapEdges((k, a, s, t) => `${makeWiki(settings.wikilinkIndex, nodesToo ? s : t)} ${nodesToo || dir !== "same" ? trailSeperator : "⟷"} ${makeWiki(settings.wikilinkIndex, nodesToo ? t : s)}`); + gInfo.edgesStr = edgeStrArr.join("\n"); } - const click_handler = async () => $$invalidate(0, currHiers = [...currHiers, blankUserHier()]); + 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: {} }, + //@ts-ignore + next: { Merged: {}, Closed: {}, Implied: {} }, + //@ts-ignore + prev: { Merged: {}, Closed: {}, Implied: {} } + }; - const click_handler_1 = async () => { - if (window.confirm("Are you sure you want to reset all hierarchies?")) { - $$invalidate(0, currHiers = []); - await update(currHiers); - } - }; + 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])); - const click_handler_2 = () => new obsidian.Notice(currHiers.map(hierToStr).join("\n\n")); - const func = (hier, dir) => hier[dir]?.join(", ") ?? ""; + hierData[dir].Merged.graph = mergedInDir; + fillInInfo(dir, "Merged", hierData); - const click_handler_3 = async i => { - $$invalidate(0, currHiers = swapItems(i, i - 1, currHiers)); - await update(currHiers); - }; + // Closed graphs + if (dir !== "same") { + hierData[dir].Closed.graph = closeImpliedLinks(mergedInDir, mergeGs(...Object.values(hier[getOppDir(dir)]))); + } else { + hierData[dir].Closed.graph = closeImpliedLinks(mergedInDir, mergedInDir); + } - const click_handler_4 = async i => { - $$invalidate(0, currHiers = swapItems(i, i + 1, currHiers)); - await update(currHiers); - }; + fillInInfo(dir, "Closed", hierData); - const click_handler_5 = async i => { - currHiers.splice(i, 1); - $$invalidate(0, currHiers); - await update(currHiers); - }; + if (dir !== "same") { + hierData[dir].Implied.graph = mergeGs(...Object.values(hier[getOppDir(dir)])); + } else { + hierData[dir].Implied.graph = closeImpliedLinks(mergedInDir, mergedInDir); + } - const change_handler = async (i, dir, e) => { - $$invalidate(0, currHiers[i][dir] = splitAndTrim(e.target.value), currHiers); - await update(currHiers); - }; + fillInInfo(dir, "Implied", hierData, false); + }); + + return hierData; + }); + + debug(settings, { data }); + const cellStr = (i, type, info) => DIRECTIONS.map(dir => data[i][dir][type][info]).join("\n"); + let hierStrs = userHierarchies.map(hierToStr); + const click_handler = async (i, dir) => await copy$1(data[i][dir].Merged.nodesStr); + const func = (i, dir) => data[i][dir].Merged.nodes.length; + const click_handler_1 = async i => await copy$1(cellStr(i, "Merged", "nodesStr")); + const click_handler_2 = async (i, dir) => await copy$1(data[i][dir].Merged.edgesStr); + const func_1 = (i, dir) => data[i][dir].Merged.edges.length; + const click_handler_3 = async i => await copy$1(cellStr(i, "Merged", "edgesStr")); + const click_handler_4 = async (i, dir) => await copy$1(data[i][dir].Implied.edgesStr); + const func_2 = (i, dir) => data[i][dir].Implied.edges.length; + const click_handler_5 = async i => await copy$1(cellStr(i, "Implied", "edgesStr")); + const func_3 = (dir, datum) => datum[dir].Merged.nodes.length; + const func_4 = (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_5 = (dir, datum) => datum[dir].Merged.edges.length; + const func_6 = (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_7 = (dir, datum) => datum[dir].Implied.edges.length; + const func_8 = (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(2, plugin = $$props.plugin); + if ("plugin" in $$props) $$invalidate(4, plugin = $$props.plugin); }; return [ - currHiers, - update, + userHierarchies, + data, + cellStr, + hierStrs, plugin, click_handler, + func, click_handler_1, click_handler_2, - func, + func_1, click_handler_3, click_handler_4, + func_2, click_handler_5, - change_handler + func_3, + func_4, + click_handler_6, + func_5, + func_6, + click_handler_7, + func_7, + func_8, + click_handler_8 ]; } -class UserHierarchies extends SvelteComponent { +class Stats extends SvelteComponent { constructor(options) { super(); - if (!document.getElementById("svelte-5y4abu-style")) add_css$4(); - init$1(this, options, instance$5, create_fragment$5, safe_not_equal, { plugin: 2 }); + if (!document.getElementById("svelte-rb5mhu-style")) add_css$5(); + init$1(this, options, instance$a, create_fragment$a, safe_not_equal, { plugin: 4 }, [-1, -1]); } } -class BCSettingTab extends obsidian.PluginSettingTab { - constructor(app, plugin) { - super(app, plugin); +class StatsView extends obsidian.ItemView { + constructor(leaf, plugin) { + super(leaf); + this.icon = "info"; 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(); - }; + async onload() { + super.onload(); + await this.plugin.saveSettings(); + this.app.workspace.onLayoutReady(async () => { + setTimeout(async () => await this.draw(), this.plugin.settings.dvWaitTime); }); - 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"); - } - })); + } + getViewType() { + return STATS_VIEW; + } + getDisplayText() { + return "Breadcrumbs Stats"; + } + async onOpen() { + await this.plugin.saveSettings(); + } + onClose() { + if (this.view) { + this.view.$destroy(); } - 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"); + 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 = getOutNeighbours(g, 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); } - })); - 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("Sorting Field Name") - .setDesc("The metadata field name used to indicate the order in which items should be sorted in the L/M view.") - .addText((text) => text.setValue(settings.orderField).onChange(async (value) => { - settings.orderField = 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, value ? "right" : "left"); - })); - const trailDetails = containerEl.createEl("details"); - trailDetails.createEl("summary", { text: "Trail/Grid" }); - new obsidian.Setting(trailDetails) - .setName("Show Breadcrumbs") - .setDesc("Show a set of different views at the top of the current note.") - .addToggle((toggle) => toggle.setValue(settings.showBCs).onChange(async (value) => { - settings.showBCs = 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 () => { - 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("Views to show") - .setDesc("Choose which of the views to show at the top of the note.\nTrail, Grid, and/or the Next-Previous view.") - .addToggle((toggle) => { - toggle - .setTooltip("Show Trail view") - .setValue(settings.showTrail) - .onChange(async (value) => { - settings.showTrail = value; - await plugin.saveSettings(); - await plugin.drawTrail(); - }); - }) - .addToggle((toggle) => { - toggle - .setTooltip("Show Grid view") - .setValue(settings.showGrid) - .onChange(async (value) => { - settings.showGrid = value; - await plugin.saveSettings(); - await plugin.drawTrail(); - }); - }) - .addToggle((toggle) => { - toggle - .setTooltip("Show Next/Previous view") - .setValue(settings.showPrevNext) - .onChange(async (value) => { - settings.showPrevNext = value; - await plugin.saveSettings(); - await plugin.drawTrail(); - }); - }); - 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) => { - var _a; - (_a = userHier[dir]) === null || _a === void 0 ? void 0 : _a.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("Write BCs to file Inline") - .setDesc("When writing BCs to file, should they be written inline (using Dataview syntax), or into the YAML of the note?") - .addToggle((toggle) => toggle.setValue(settings.writeBCsInline).onChange(async (value) => { - settings.writeBCsInline = value; - await plugin.saveSettings(); - })); - 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)); + return pathsArr; + } + async draw() { + this.contentEl.empty(); + this.view = new Stats({ + target: this.contentEl, + props: { plugin: this.plugin }, }); - new KoFi({ target: this.containerEl }); } } -/* src\Components\Stats.svelte generated by Svelte v3.35.0 */ - -function add_css$3() { - 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$4(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[27] = list[i]; - return child_ctx; -} - -function get_each_context_1$4(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[27] = list[i]; - return child_ctx; -} - -function get_each_context_2$1(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[27] = list[i]; - return child_ctx; -} - -function get_each_context_3(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[34] = list[i]; - child_ctx[36] = i; - return child_ctx; -} - -function get_each_context_4(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[27] = list[i]; - return child_ctx; -} - -function get_each_context_5(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[27] = list[i]; - return child_ctx; -} - -function get_each_context_6(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[27] = list[i]; - return child_ctx; -} - -function get_each_context_7(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[27] = list[i]; - return child_ctx; -} - -// (89:4) {#each DIRECTIONS as dir} -function create_each_block_7(ctx) { - let td; - let t_value = ARROW_DIRECTIONS[/*dir*/ ctx[27]] + ""; - let t; - - return { - c() { - td = element("td"); - t = text(t_value); - attr(td, "class", "svelte-rb5mhu"); - }, - m(target, anchor) { - insert(target, td, anchor); - append(td, t); - }, - p: noop$1, - d(detaching) { - if (detaching) detach(td); - } - }; -} +const MATRIX_VIEW = "BC-matrix"; +const STATS_VIEW = "BC-stats"; +const DUCK_VIEW = "BC-ducks"; +const VIEWS = [ + { + plain: "Matrix", + type: MATRIX_VIEW, + constructor: MatrixView, + openOnLoad: true, + }, + { + plain: "Stats", + type: STATS_VIEW, + constructor: StatsView, + openOnLoad: true, + }, + { plain: "Duck", type: DUCK_VIEW, constructor: DucksView, openOnLoad: false }, +]; +const TRAIL_ICON = "BC-trail-icon"; +const TRAIL_ICON_SVG = ''; +const splitLinksRegex = new RegExp(/\[\[(.+?)\]\]/g); +const dropHeaderOrAlias = new RegExp(/\[\[([^#|]+)\]\]/); +const VISTYPES = [ + "Force Directed Graph", + "Tidy Tree", + "Circle Packing", + "Edge Bundling", + "Arc Diagram", + "Sunburst", + "Tree Map", + "Icicle", + "Radial Tree", +]; +const DIRECTIONS = ["up", "same", "down", "next", "prev"]; +const ARROW_DIRECTIONS = { + up: "↑", + same: "↔", + down: "↓", + next: "→", + prev: "←", +}; +const RELATIONS = ["Parent", "Sibling", "Child"]; +const REAlCLOSED = ["Real", "Closed"]; +const ALLUNLINKED = ["All", "No Unlinked"]; +const blankUserHier = () => { + return { up: [], same: [], down: [], next: [], prev: [] }; +}; +const blankDirObjs = () => { + return { + up: {}, + same: {}, + down: {}, + next: {}, + prev: {}, + }; +}; +const blankDirUndef = () => { + return { + up: undefined, + same: undefined, + down: undefined, + next: undefined, + prev: undefined, + }; +}; +const DEFAULT_SETTINGS = { + userHierarchies: [ + { + up: ["up"], + same: ["same"], + down: ["down"], + next: ["next"], + prev: ["prev"], + }, + ], + indexNote: [""], + CSVPaths: "", + hierarchyNotes: [""], + hierarchyNoteDownFieldName: "", + hierarchyNoteUpFieldName: "", + refreshIndexOnActiveLeafChange: false, + altLinkFields: [], + useAllMetadata: true, + parseJugglLinksWithoutJuggl: false, + dvWaitTime: 5000, + refreshIntervalTime: 0, + defaultView: true, + orderField: "order", + showNameOrType: true, + showRelationType: true, + filterImpliedSiblingsOfDifferentTypes: false, + rlLeaf: true, + showBCs: true, + showTrail: true, + showGrid: true, + showPrevNext: true, + limitTrailCheckboxStates: {}, + hideTrailFieldName: "hide-trail", + gridDots: false, + dotsColour: "#000000", + gridHeatmap: false, + heatmapColour: getComputedStyle(document.body).getPropertyValue("--text-accent"), + showAll: false, + noPathMessage: `This note has no real or implied parents`, + trailSeperator: "→", + respectReadableLineLength: true, + limitWriteBCCheckboxStates: {}, + writeBCsInline: false, + showWriteAllBCsCmd: false, + visGraph: "Force Directed Graph", + visRelation: "Parent", + visClosed: "Real", + visAll: "All", + wikilinkIndex: true, + aliasesInIndex: false, + debugMode: false, + superDebugMode: false, +}; -// (101:6) {#each DIRECTIONS as dir} -function create_each_block_6(ctx) { - let td; - let t_value = /*data*/ ctx[1][/*i*/ ctx[36]][/*dir*/ ctx[27]].Merged.nodes.length + ""; +/* src\Components\KoFi.svelte generated by Svelte v3.35.0 */ + +function create_fragment$9(ctx) { + let script; + let script_src_value; let t; - let td_aria_label_value; + let div; let mounted; let dispose; - function click_handler() { - return /*click_handler*/ ctx[5](/*i*/ ctx[36], /*dir*/ ctx[27]); - } - return { c() { - td = element("td"); - t = text(t_value); - attr(td, "aria-label-position", "left"); - attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1][/*i*/ ctx[36]][/*dir*/ ctx[27]].Merged.nodesStr); - attr(td, "class", "svelte-rb5mhu"); + 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) { - insert(target, td, anchor); - append(td, t); + append(document.head, script); + insert(target, t, anchor); + insert(target, div, anchor); + /*div_binding*/ ctx[2](div); if (!mounted) { - dispose = listen(td, "click", click_handler); + dispose = listen(script, "load", /*initializeKofi*/ ctx[1]); mounted = true; } }, - p(new_ctx, dirty) { - ctx = new_ctx; - }, + p: noop$1, + i: noop$1, + o: noop$1, d(detaching) { - if (detaching) detach(td); + detach(script); + if (detaching) detach(t); + if (detaching) detach(div); + /*div_binding*/ ctx[2](null); mounted = false; dispose(); } }; } -// (120:6) {#each DIRECTIONS as dir} -function create_each_block_5(ctx) { - let td; - let t_value = /*data*/ ctx[1][/*i*/ ctx[36]][/*dir*/ ctx[27]].Merged.edges.length + ""; - let t; - let td_aria_label_value; - let mounted; - let dispose; +function instance$9($$self, $$props, $$invalidate) { + let button; - function click_handler_2() { - return /*click_handler_2*/ ctx[8](/*i*/ ctx[36], /*dir*/ ctx[27]); + 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$9, create_fragment$9, safe_not_equal, {}); } +} + +/* node_modules\svelte-icons\components\IconBase.svelte generated by Svelte v3.35.0 */ + +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); +} + +// (18:2) {#if title} +function create_if_block$2(ctx) { + let title_1; + let t; return { c() { - td = element("td"); - t = text(t_value); - attr(td, "aria-label-position", "left"); - attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1][/*i*/ ctx[36]][/*dir*/ ctx[27]].Merged.edgesStr); - attr(td, "class", "svelte-rb5mhu"); + title_1 = svg_element("title"); + t = text(/*title*/ ctx[0]); }, m(target, anchor) { - insert(target, td, anchor); - append(td, t); - - if (!mounted) { - dispose = listen(td, "click", click_handler_2); - mounted = true; - } + insert(target, title_1, anchor); + append(title_1, t); }, - p(new_ctx, dirty) { - ctx = new_ctx; + p(ctx, dirty) { + if (dirty & /*title*/ 1) set_data(t, /*title*/ ctx[0]); }, d(detaching) { - if (detaching) detach(td); - mounted = false; - dispose(); + if (detaching) detach(title_1); } }; } -// (139:6) {#each DIRECTIONS as dir} -function create_each_block_4(ctx) { - let td; - let t_value = /*data*/ ctx[1][/*i*/ ctx[36]][/*dir*/ ctx[27]].Implied.edges.length + ""; - let t; - let td_aria_label_value; - let mounted; - let dispose; - - function click_handler_4() { - return /*click_handler_4*/ ctx[11](/*i*/ ctx[36], /*dir*/ ctx[27]); - } +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); return { c() { - td = element("td"); - t = text(t_value); - attr(td, "aria-label-position", "left"); - attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1][/*i*/ ctx[36]][/*dir*/ ctx[27]].Implied.edgesStr); - attr(td, "class", "svelte-rb5mhu"); + 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, td, anchor); - append(td, t); + insert(target, svg, anchor); + if (if_block) if_block.m(svg, null); + append(svg, if_block_anchor); - if (!mounted) { - dispose = listen(td, "click", click_handler_4); - mounted = true; + if (default_slot) { + default_slot.m(svg, null); } + + current = true; }, - p(new_ctx, dirty) { - ctx = new_ctx; + 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; + } + + if (default_slot) { + if (default_slot.p && dirty & /*$$scope*/ 4) { + update_slot(default_slot, default_slot_template, ctx, /*$$scope*/ ctx[2], dirty, null, null); + } + } + + 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(td); - mounted = false; - dispose(); + if (detaching) detach(svg); + if (if_block) if_block.d(); + if (default_slot) default_slot.d(detaching); } }; } -// (95:2) {#each userHierarchies as hier, i} -function create_each_block_3(ctx) { - let tr0; - let td0; - let t0_value = /*hierStrs*/ ctx[3][/*i*/ ctx[36]] + ""; - let t0; - let t1; - let td1; - let t3; - let t4; - let td2; - let t5_value = lodash.sum(DIRECTIONS.map(func)) + ""; - let t5; - let td2_aria_label_value; - let t6; - let tr1; - let td3; - let t8; - let t9; - let td4; - let t10_value = lodash.sum(DIRECTIONS.map(func_1)) + ""; - let t10; - let td4_aria_label_value; - let t11; - let tr2; - let td5; - let t13; - let t14; - let td6; - let t15_value = lodash.sum(DIRECTIONS.map(func_2)) + ""; - let t15; - let td6_aria_label_value; - let mounted; - let dispose; - let each_value_6 = DIRECTIONS; - let each_blocks_2 = []; +function instance$8($$self, $$props, $$invalidate) { + let { $$slots: slots = {}, $$scope } = $$props; + let { title = null } = $$props; + let { viewBox } = $$props; - for (let i = 0; i < each_value_6.length; i += 1) { - each_blocks_2[i] = create_each_block_6(get_each_context_6(ctx, each_value_6, i)); - } + $$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); + }; - function func(...args) { - return /*func*/ ctx[6](/*i*/ ctx[36], ...args); - } + return [title, viewBox, $$scope, slots]; +} - function click_handler_1() { - return /*click_handler_1*/ ctx[7](/*i*/ ctx[36]); +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 }); } +} - let each_value_5 = DIRECTIONS; - let each_blocks_1 = []; - - for (let i = 0; i < each_value_5.length; i += 1) { - each_blocks_1[i] = create_each_block_5(get_each_context_5(ctx, each_value_5, i)); - } +/* node_modules\svelte-icons\fa\FaListUl.svelte generated by Svelte v3.35.0 */ - function func_1(...args) { - return /*func_1*/ ctx[9](/*i*/ ctx[36], ...args); - } +function create_default_slot$2(ctx) { + let path; - function click_handler_3() { - return /*click_handler_3*/ ctx[10](/*i*/ ctx[36]); - } + 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); + } + }; +} - let each_value_4 = DIRECTIONS; - let each_blocks = []; +function create_fragment$7(ctx) { + let iconbase; + let current; + const iconbase_spread_levels = [{ viewBox: "0 0 512 512" }, /*$$props*/ ctx[0]]; - for (let i = 0; i < each_value_4.length; i += 1) { - each_blocks[i] = create_each_block_4(get_each_context_4(ctx, each_value_4, i)); - } + let iconbase_props = { + $$slots: { default: [create_default_slot$2] }, + $$scope: { ctx } + }; - function func_2(...args) { - return /*func_2*/ ctx[12](/*i*/ ctx[36], ...args); + for (let i = 0; i < iconbase_spread_levels.length; i += 1) { + iconbase_props = assign(iconbase_props, iconbase_spread_levels[i]); } - function click_handler_5() { - return /*click_handler_5*/ ctx[13](/*i*/ ctx[36]); - } + iconbase = new IconBase({ props: iconbase_props }); 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 < each_blocks_2.length; 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 < each_blocks_1.length; 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 < each_blocks.length; 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-position", "left"); - attr(td2, "aria-label", td2_aria_label_value = /*cellStr*/ ctx[2](/*i*/ ctx[36], "Merged", "nodesStr")); - attr(td2, "class", "svelte-rb5mhu"); - attr(td3, "class", "svelte-rb5mhu"); - attr(td4, "aria-label-position", "left"); - attr(td4, "aria-label", td4_aria_label_value = /*cellStr*/ ctx[2](/*i*/ ctx[36], "Merged", "edgesStr")); - attr(td4, "class", "svelte-rb5mhu"); - attr(td5, "class", "svelte-rb5mhu"); - attr(td6, "aria-label-position", "left"); - attr(td6, "aria-label", td6_aria_label_value = /*cellStr*/ ctx[2](/*i*/ ctx[36], "Implied", "edgesStr")); - attr(td6, "class", "svelte-rb5mhu"); + create_component(iconbase.$$.fragment); }, 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 < each_blocks_2.length; 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 < each_blocks_1.length; 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); + 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])]) + : {}; - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].m(tr2, null); + if (dirty & /*$$scope*/ 2) { + iconbase_changes.$$scope = { dirty, ctx }; } - 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; - } + iconbase.$set(iconbase_changes); }, - p(new_ctx, dirty) { - ctx = new_ctx; - - if (dirty[0] & /*data*/ 2) { - each_value_6 = DIRECTIONS; - let i; - - for (i = 0; i < each_value_6.length; 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); - } - } + 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); + } + }; +} - for (; i < each_blocks_2.length; i += 1) { - each_blocks_2[i].d(1); - } +function instance$7($$self, $$props, $$invalidate) { + $$self.$$set = $$new_props => { + $$invalidate(0, $$props = assign(assign({}, $$props), exclude_internal_props($$new_props))); + }; - each_blocks_2.length = each_value_6.length; - } + $$props = exclude_internal_props($$props); + return [$$props]; +} - if (dirty[0] & /*data*/ 2) { - each_value_5 = DIRECTIONS; - let i; +class FaListUl extends SvelteComponent { + constructor(options) { + super(); + init$1(this, options, instance$7, create_fragment$7, safe_not_equal, {}); + } +} - for (i = 0; i < each_value_5.length; i += 1) { - const child_ctx = get_each_context_5(ctx, each_value_5, i); +/* node_modules\svelte-icons\fa\FaPlus.svelte generated by Svelte v3.35.0 */ - 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); - } - } +function create_default_slot$1(ctx) { + let path; - for (; i < each_blocks_1.length; i += 1) { - each_blocks_1[i].d(1); - } + 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); + } + }; +} - each_blocks_1.length = each_value_5.length; - } +function create_fragment$6(ctx) { + let iconbase; + let current; + const iconbase_spread_levels = [{ viewBox: "0 0 448 512" }, /*$$props*/ ctx[0]]; - if (dirty[0] & /*data*/ 2) { - each_value_4 = DIRECTIONS; - let i; + let iconbase_props = { + $$slots: { default: [create_default_slot$1] }, + $$scope: { ctx } + }; - for (i = 0; i < each_value_4.length; i += 1) { - const child_ctx = get_each_context_4(ctx, each_value_4, i); + for (let i = 0; i < iconbase_spread_levels.length; i += 1) { + iconbase_props = assign(iconbase_props, iconbase_spread_levels[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); - } - } + iconbase = new IconBase({ props: iconbase_props }); - for (; i < each_blocks.length; i += 1) { - each_blocks[i].d(1); - } + 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])]) + : {}; - each_blocks.length = each_value_4.length; + 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) { - 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); + destroy_component(iconbase, detaching); } }; } -// (160:4) {#each DIRECTIONS as dir} -function create_each_block_2$1(ctx) { - let td; - let t0_value = lodash.sum(/*data*/ ctx[1].map(func_3)) + ""; - let t0; - let t1; - let td_aria_label_value; - let mounted; - let dispose; +function instance$6($$self, $$props, $$invalidate) { + $$self.$$set = $$new_props => { + $$invalidate(0, $$props = assign(assign({}, $$props), exclude_internal_props($$new_props))); + }; - function func_3(...args) { - return /*func_3*/ ctx[14](/*dir*/ ctx[27], ...args); - } + $$props = exclude_internal_props($$props); + return [$$props]; +} - function func_4(...args) { - return /*func_4*/ ctx[15](/*dir*/ ctx[27], ...args); +class FaPlus extends SvelteComponent { + constructor(options) { + super(); + init$1(this, options, instance$6, create_fragment$6, safe_not_equal, {}); } +} - function click_handler_6() { - return /*click_handler_6*/ ctx[16](/*dir*/ ctx[27]); - } +/* node_modules\svelte-icons\fa\FaRegTrashAlt.svelte generated by Svelte v3.35.0 */ + +function create_default_slot(ctx) { + let path; return { c() { - td = element("td"); - t0 = text(t0_value); - t1 = space(); - attr(td, "aria-label-position", "left"); - attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1].map(func_4).join("\n")); - attr(td, "class", "svelte-rb5mhu"); + 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, 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; + insert(target, path, anchor); }, d(detaching) { - if (detaching) detach(td); - mounted = false; - dispose(); + if (detaching) detach(path); } }; } -// (201:4) {#each DIRECTIONS as dir} -function create_each_block_1$4(ctx) { - let td; - let t0_value = lodash.sum(/*data*/ ctx[1].map(func_5)) + ""; - let t0; - let t1; - let td_aria_label_value; - let mounted; - let dispose; +function create_fragment$5(ctx) { + let iconbase; + let current; + const iconbase_spread_levels = [{ viewBox: "0 0 448 512" }, /*$$props*/ ctx[0]]; - function func_5(...args) { - return /*func_5*/ ctx[17](/*dir*/ ctx[27], ...args); - } + let iconbase_props = { + $$slots: { default: [create_default_slot] }, + $$scope: { ctx } + }; - function func_6(...args) { - return /*func_6*/ ctx[18](/*dir*/ ctx[27], ...args); + for (let i = 0; i < iconbase_spread_levels.length; i += 1) { + iconbase_props = assign(iconbase_props, iconbase_spread_levels[i]); } - function click_handler_7() { - return /*click_handler_7*/ ctx[19](/*dir*/ ctx[27]); - } + iconbase = new IconBase({ props: iconbase_props }); return { c() { - td = element("td"); - t0 = text(t0_value); - t1 = space(); - attr(td, "aria-label-position", "left"); - attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1].map(func_6).join("\n")); - attr(td, "class", "svelte-rb5mhu"); + create_component(iconbase.$$.fragment); }, m(target, anchor) { - insert(target, td, anchor); - append(td, t0); - append(td, t1); + 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 (!mounted) { - dispose = listen(td, "click", click_handler_7); - mounted = true; + if (dirty & /*$$scope*/ 2) { + iconbase_changes.$$scope = { dirty, ctx }; } + + iconbase.$set(iconbase_changes); }, - p(new_ctx, dirty) { - ctx = new_ctx; + i(local) { + if (current) return; + transition_in(iconbase.$$.fragment, local); + current = true; + }, + o(local) { + transition_out(iconbase.$$.fragment, local); + current = false; }, d(detaching) { - if (detaching) detach(td); - mounted = false; - dispose(); + destroy_component(iconbase, detaching); } }; } -// (238:4) {#each DIRECTIONS as dir} -function create_each_block$4(ctx) { - let td; - let t0_value = lodash.sum(/*data*/ ctx[1].map(func_7)) + ""; +function instance$5($$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]; +} + +class FaRegTrashAlt extends SvelteComponent { + constructor(options) { + super(); + init$1(this, options, instance$5, create_fragment$5, safe_not_equal, {}); + } +} + +/* src\Components\UserHierarchies.svelte generated by Svelte v3.35.0 */ + +function add_css$3() { + var style = element("style"); + style.id = "svelte-5y4abu-style"; + style.textContent = "label.BC-Arrow-Label.svelte-5y4abu.svelte-5y4abu{display:inline-block;width:20px !important}div.GA-Buttons.svelte-5y4abu.svelte-5y4abu{padding-bottom:5px}details.BC-Hier-Details.svelte-5y4abu.svelte-5y4abu{border:1px solid var(--background-modifier-border);border-radius:10px;padding:10px 5px 10px 10px;margin-bottom:15px}.BC-Hier-Details.svelte-5y4abu summary.svelte-5y4abu::marker{font-size:10px}.BC-Hier-Details.svelte-5y4abu summary button.svelte-5y4abu{float:right}.icon.svelte-5y4abu.svelte-5y4abu{color:var(--text-normal);display:inline-block;padding-top:3px;width:17px;height:17px}"; + append(document.head, style); +} + +function get_each_context$4(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[12] = list[i]; + child_ctx[14] = i; + return child_ctx; +} + +function get_each_context_1$4(ctx, list, i) { + const child_ctx = ctx.slice(); + child_ctx[15] = list[i]; + return child_ctx; +} + +// (92:6) {#each DIRECTIONS as dir} +function create_each_block_1$4(ctx) { + let div; + let label; + let t0_value = ARROW_DIRECTIONS[/*dir*/ ctx[15]] + ""; let t0; + let label_for_value; let t1; - let td_aria_label_value; + let input; + let input_name_value; + let input_value_value; let mounted; let dispose; - function func_7(...args) { - return /*func_7*/ ctx[20](/*dir*/ ctx[27], ...args); - } - - function func_8(...args) { - return /*func_8*/ ctx[21](/*dir*/ ctx[27], ...args); - } - - function click_handler_8() { - return /*click_handler_8*/ ctx[22](/*dir*/ ctx[27]); + function change_handler(...args) { + return /*change_handler*/ ctx[10](/*i*/ ctx[14], /*dir*/ ctx[15], ...args); } return { c() { - td = element("td"); + div = element("div"); + label = element("label"); t0 = text(t0_value); t1 = space(); - attr(td, "aria-label-position", "left"); - attr(td, "aria-label", td_aria_label_value = /*data*/ ctx[1].map(func_8).join("\n")); - attr(td, "class", "svelte-rb5mhu"); + input = element("input"); + attr(label, "class", "BC-Arrow-Label svelte-5y4abu"); + attr(label, "for", label_for_value = /*dir*/ ctx[15]); + attr(input, "type", "text"); + attr(input, "size", "20"); + attr(input, "name", input_name_value = /*dir*/ ctx[15]); + input.value = input_value_value = /*hier*/ ctx[12][/*dir*/ ctx[15]]?.join(", ") ?? ""; }, m(target, anchor) { - insert(target, td, anchor); - append(td, t0); - append(td, t1); + insert(target, div, anchor); + append(div, label); + append(label, t0); + append(div, t1); + append(div, input); if (!mounted) { - dispose = listen(td, "click", click_handler_8); + dispose = listen(input, "change", change_handler); mounted = true; } }, p(new_ctx, dirty) { ctx = new_ctx; + + if (dirty & /*currHiers*/ 1 && input_value_value !== (input_value_value = /*hier*/ ctx[12][/*dir*/ ctx[15]]?.join(", ") ?? "") && input.value !== input_value_value) { + input.value = input_value_value; + } }, d(detaching) { - if (detaching) detach(td); + if (detaching) detach(div); mounted = false; dispose(); } }; } -function create_fragment$4(ctx) { - let table; - let thead; - let tr0; - let th0; +// (60:2) {#each currHiers as hier, i} +function create_each_block$4(ctx) { + let details; + let summary; + let t0_value = DIRECTIONS.map(func).map(func_1).join(" ") + ""; + let t0; let t1; - let th1; - let t2; + let span; + let button0; let t3; - let tr1; - let td0; - let t4; - let td1; - let t6; + let button1; + let t5; + let button2; let t7; - let td2; - let t9; - let t10; - let tr2; - let td3; - let t12; - let td4; - let t14; - let t15; - let tr3; - let td5; - let t17; - let t18; - let tr4; - let td6; - let t20; - let each_value_7 = DIRECTIONS; - let each_blocks_4 = []; + let t8; + let mounted; + let dispose; - for (let i = 0; i < each_value_7.length; i += 1) { - each_blocks_4[i] = create_each_block_7(get_each_context_7(ctx, each_value_7, i)); + function func(...args) { + return /*func*/ ctx[6](/*hier*/ ctx[12], ...args); } - 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)); + function click_handler_3() { + return /*click_handler_3*/ ctx[7](/*i*/ ctx[14]); } - let each_value_2 = DIRECTIONS; - let each_blocks_2 = []; - - for (let i = 0; i < each_value_2.length; i += 1) { - each_blocks_2[i] = create_each_block_2$1(get_each_context_2$1(ctx, each_value_2, i)); + function click_handler_4() { + return /*click_handler_4*/ ctx[8](/*i*/ ctx[14]); } - let each_value_1 = DIRECTIONS; - let each_blocks_1 = []; - - for (let i = 0; i < each_value_1.length; i += 1) { - each_blocks_1[i] = create_each_block_1$4(get_each_context_1$4(ctx, each_value_1, i)); + function click_handler_5() { + return /*click_handler_5*/ ctx[9](/*i*/ ctx[14]); } - let each_value = DIRECTIONS; + let each_value_1 = DIRECTIONS; 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)); + 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() { - table = element("table"); - thead = element("thead"); - tr0 = element("tr"); - th0 = element("th"); - th0.textContent = "Hierarchy"; + details = element("details"); + summary = element("summary"); + t0 = text(t0_value); t1 = space(); - th1 = element("th"); - t2 = text("Count"); + span = element("span"); + button0 = element("button"); + button0.textContent = "↑"; t3 = space(); - tr1 = element("tr"); - td0 = element("td"); - t4 = space(); - td1 = element("td"); - td1.textContent = "Measure"; - t6 = space(); - - for (let i = 0; i < each_blocks_4.length; i += 1) { - each_blocks_4[i].c(); - } - + button1 = element("button"); + button1.textContent = "↓"; + t5 = space(); + button2 = element("button"); + button2.textContent = "X"; t7 = space(); - td2 = element("td"); - td2.textContent = "Total"; - t9 = space(); - - for (let i = 0; i < each_blocks_3.length; i += 1) { - each_blocks_3[i].c(); - } - - t10 = space(); - tr2 = element("tr"); - td3 = element("td"); - td3.textContent = "Totals"; - t12 = space(); - td4 = element("td"); - td4.textContent = "Nodes"; - t14 = space(); - - for (let i = 0; i < each_blocks_2.length; i += 1) { - each_blocks_2[i].c(); - } - - t15 = space(); - tr3 = element("tr"); - td5 = element("td"); - td5.textContent = "Real Edges"; - t17 = space(); - - for (let i = 0; i < each_blocks_1.length; i += 1) { - each_blocks_1[i].c(); - } - - t18 = space(); - tr4 = element("tr"); - td6 = element("td"); - td6.textContent = "Implied Edges"; - t20 = space(); for (let i = 0; i < each_blocks.length; i += 1) { each_blocks[i].c(); } - attr(th0, "scope", "col"); - attr(th0, "class", "svelte-rb5mhu"); - attr(th1, "scope", "col"); - attr(th1, "colspan", DIRECTIONS.length + 2); - attr(th1, "class", "svelte-rb5mhu"); - attr(td0, "class", "svelte-rb5mhu"); - attr(td1, "class", "svelte-rb5mhu"); - attr(td2, "class", "svelte-rb5mhu"); - attr(td3, "rowspan", "3"); - attr(td3, "class", "svelte-rb5mhu"); - attr(td4, "class", "svelte-rb5mhu"); - attr(td5, "class", "svelte-rb5mhu"); - attr(td6, "class", "svelte-rb5mhu"); - attr(table, "class", "svelte-rb5mhu"); + t8 = space(); + attr(button0, "aria-label", "Swap with Hierarchy Above"); + attr(button0, "class", "svelte-5y4abu"); + attr(button1, "aria-label", "Swap with Hierarchy Below"); + attr(button1, "class", "svelte-5y4abu"); + attr(button2, "aria-label", "Remove Hierarchy"); + attr(button2, "class", "svelte-5y4abu"); + attr(span, "class", "GA-Buttons"); + attr(summary, "class", "svelte-5y4abu"); + attr(details, "class", "BC-Hier-Details svelte-5y4abu"); }, m(target, anchor) { - insert(target, table, anchor); - append(table, thead); - append(thead, tr0); - append(tr0, th0); - append(tr0, t1); - append(tr0, th1); - append(th1, t2); - append(table, t3); - append(table, tr1); - append(tr1, td0); - append(tr1, t4); - append(tr1, td1); - append(tr1, t6); - - for (let i = 0; i < each_blocks_4.length; i += 1) { - each_blocks_4[i].m(tr1, null); - } - - append(tr1, t7); - append(tr1, td2); - append(table, t9); - - for (let i = 0; i < each_blocks_3.length; i += 1) { - each_blocks_3[i].m(table, null); - } - - append(table, t10); - append(table, tr2); - append(tr2, td3); - append(tr2, t12); - append(tr2, td4); - append(tr2, t14); - - for (let i = 0; i < each_blocks_2.length; i += 1) { - each_blocks_2[i].m(tr2, null); - } - - append(table, t15); - append(table, tr3); - append(tr3, td5); - append(tr3, t17); - - for (let i = 0; i < each_blocks_1.length; i += 1) { - each_blocks_1[i].m(tr3, null); - } - - append(table, t18); - append(table, tr4); - append(tr4, td6); - append(tr4, t20); + insert(target, details, anchor); + append(details, summary); + append(summary, t0); + append(summary, t1); + append(summary, span); + append(span, button0); + append(span, t3); + append(span, button1); + append(span, t5); + append(span, button2); + append(details, t7); for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].m(tr4, null); + each_blocks[i].m(details, null); } - }, - p(ctx, dirty) { - if (dirty & /*ARROW_DIRECTIONS, DIRECTIONS*/ 0) { - each_value_7 = DIRECTIONS; - let i; - for (i = 0; i < each_value_7.length; i += 1) { - const child_ctx = get_each_context_7(ctx, each_value_7, i); - - if (each_blocks_4[i]) { - each_blocks_4[i].p(child_ctx, dirty); - } else { - each_blocks_4[i] = create_each_block_7(child_ctx); - each_blocks_4[i].c(); - each_blocks_4[i].m(tr1, t7); - } - } + append(details, t8); - for (; i < each_blocks_4.length; i += 1) { - each_blocks_4[i].d(1); - } + if (!mounted) { + dispose = [ + listen(button0, "click", click_handler_3), + listen(button1, "click", click_handler_4), + listen(button2, "click", click_handler_5) + ]; - each_blocks_4.length = each_value_7.length; + mounted = true; } + }, + p(new_ctx, dirty) { + ctx = new_ctx; + if (dirty & /*currHiers*/ 1 && t0_value !== (t0_value = DIRECTIONS.map(func).map(func_1).join(" ") + "")) set_data(t0, t0_value); - if (dirty[0] & /*cellStr, data, hierStrs*/ 14) { - each_value_3 = /*userHierarchies*/ ctx[0]; + if (dirty & /*DIRECTIONS, currHiers, splitAndTrim, update, ARROW_DIRECTIONS*/ 3) { + each_value_1 = DIRECTIONS; let i; - for (i = 0; i < each_value_3.length; i += 1) { - const child_ctx = get_each_context_3(ctx, each_value_3, 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_3[i]) { - each_blocks_3[i].p(child_ctx, dirty); + if (each_blocks[i]) { + each_blocks[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, t10); + each_blocks[i] = create_each_block_1$4(child_ctx); + each_blocks[i].c(); + each_blocks[i].m(details, t8); } } - for (; i < each_blocks_3.length; i += 1) { - each_blocks_3[i].d(1); + for (; i < each_blocks.length; i += 1) { + each_blocks[i].d(1); } - each_blocks_3.length = each_value_3.length; + each_blocks.length = each_value_1.length; } + }, + d(detaching) { + if (detaching) detach(details); + destroy_each(each_blocks, detaching); + mounted = false; + run_all(dispose); + } + }; +} - if (dirty[0] & /*data*/ 2) { - each_value_2 = DIRECTIONS; - let i; - - for (i = 0; i < each_value_2.length; i += 1) { - const child_ctx = get_each_context_2$1(ctx, each_value_2, i); +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 = /*currHiers*/ ctx[0]; + let each_blocks = []; - 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 (let i = 0; i < each_value.length; i += 1) { + each_blocks[i] = create_each_block$4(get_each_context$4(ctx, each_value, i)); + } - for (; i < each_blocks_2.length; i += 1) { - each_blocks_2[i].d(1); - } + 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(); - each_blocks_2.length = each_value_2.length; + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); } - if (dirty[0] & /*data*/ 2) { - each_value_1 = DIRECTIONS; - let i; + attr(div0, "class", "icon svelte-5y4abu"); + attr(button0, "aria-label", "Add New Hierarchy"); + attr(div1, "class", "icon svelte-5y4abu"); + attr(button1, "aria-label", "Reset All Hierarchies"); + attr(div2, "class", "icon svelte-5y4abu"); + attr(button2, "aria-label", "Show Hierarchies"); + attr(div3, "class", "GA-Buttons svelte-5y4abu"); + }, + 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); - for (i = 0; i < each_value_1.length; i += 1) { - const child_ctx = get_each_context_1$4(ctx, each_value_1, i); + for (let i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(div4, null); + } - if (each_blocks_1[i]) { - each_blocks_1[i].p(child_ctx, dirty); - } else { - each_blocks_1[i] = create_each_block_1$4(child_ctx); - each_blocks_1[i].c(); - each_blocks_1[i].m(tr3, null); - } - } + current = true; - for (; i < each_blocks_1.length; i += 1) { - each_blocks_1[i].d(1); - } + if (!mounted) { + dispose = [ + listen(button0, "click", /*click_handler*/ ctx[3]), + listen(button1, "click", /*click_handler_1*/ ctx[4]), + listen(button2, "click", /*click_handler_2*/ ctx[5]) + ]; - each_blocks_1.length = each_value_1.length; + mounted = true; } - - if (dirty[0] & /*data*/ 2) { - each_value = DIRECTIONS; + }, + p(ctx, [dirty]) { + if (dirty & /*DIRECTIONS, currHiers, splitAndTrim, update, ARROW_DIRECTIONS, swapItems*/ 3) { + each_value = /*currHiers*/ ctx[0]; let i; for (i = 0; i < each_value.length; i += 1) { @@ -24924,7 +24612,7 @@ function create_fragment$4(ctx) { } else { each_blocks[i] = create_each_block$4(child_ctx); each_blocks[i].c(); - each_blocks[i].m(tr4, null); + each_blocks[i].m(div4, null); } } @@ -24935,199 +24623,754 @@ function create_fragment$4(ctx) { each_blocks.length = each_value.length; } }, - i: noop$1, - o: noop$1, + 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(table); - destroy_each(each_blocks_4, detaching); - destroy_each(each_blocks_3, detaching); - destroy_each(each_blocks_2, detaching); - destroy_each(each_blocks_1, detaching); + if (detaching) detach(div4); + destroy_component(faplus); + destroy_component(faregtrashalt); + destroy_component(falistul); destroy_each(each_blocks, detaching); + mounted = false; + run_all(dispose); } }; } +const func_1 = dirFields => `(${dirFields})`; + function instance$4($$self, $$props, $$invalidate) { - - - let { plugin } = $$props; - const { settings } = plugin; - const { userHierarchies, trailSeperator } = settings; - const hierGs = plugin.currGraphs; + var __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P + ? value + : new P(function (resolve) { + resolve(value); + }); + } - function fillInInfo(dir, gType, hierData, nodesToo = true) { - const gInfo = hierData[dir][gType]; + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch(e) { + reject(e); + } + } - if (nodesToo) { - gInfo.nodes = gInfo.graph.nodes(); - gInfo.nodesStr = gInfo.nodes.map(n => makeWiki(settings.wikilinkIndex, n)).join("\n"); - } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch(e) { + reject(e); + } + } - gInfo.edges = gInfo.graph.edges(); - const edgeStrArr = gInfo.graph.mapEdges((k, a, s, t) => `${makeWiki(settings.wikilinkIndex, nodesToo ? s : t)} ${nodesToo || dir !== "same" ? trailSeperator : "⟷"} ${makeWiki(settings.wikilinkIndex, nodesToo ? t : s)}`); - gInfo.edgesStr = edgeStrArr.join("\n"); - } + function step(result) { + result.done + ? resolve(result.value) + : adopt(result.value).then(fulfilled, rejected); + } - 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: {} }, - //@ts-ignore - next: { Merged: {}, Closed: {}, Implied: {} }, - //@ts-ignore - prev: { Merged: {}, Closed: {}, Implied: {} } - }; + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; - 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])); + + let { plugin } = $$props; + let currHiers = [...plugin.settings.userHierarchies]; - hierData[dir].Merged.graph = mergedInDir; - fillInInfo(dir, "Merged", hierData); + function update(currHiers) { + return __awaiter(this, void 0, void 0, function* () { + $$invalidate(2, plugin.settings.userHierarchies = currHiers, plugin); + yield plugin.saveSettings(); + }); + } - // Closed graphs - if (dir !== "same") { - hierData[dir].Closed.graph = closeImpliedLinks(mergedInDir, mergeGs(...Object.values(hier[getOppDir(dir)]))); - } else { - hierData[dir].Closed.graph = closeImpliedLinks(mergedInDir, mergedInDir); - } + const click_handler = async () => $$invalidate(0, currHiers = [...currHiers, blankUserHier()]); - fillInInfo(dir, "Closed", hierData); + const click_handler_1 = async () => { + if (window.confirm("Are you sure you want to reset all hierarchies?")) { + $$invalidate(0, currHiers = []); + await update(currHiers); + } + }; - if (dir !== "same") { - hierData[dir].Implied.graph = mergeGs(...Object.values(hier[getOppDir(dir)])); - } else { - hierData[dir].Implied.graph = closeImpliedLinks(mergedInDir, mergedInDir); - } + const click_handler_2 = () => new obsidian.Notice(currHiers.map(hierToStr).join("\n\n")); + const func = (hier, dir) => hier[dir]?.join(", ") ?? ""; - fillInInfo(dir, "Implied", hierData, false); - }); + const click_handler_3 = async i => { + $$invalidate(0, currHiers = swapItems(i, i - 1, currHiers)); + await update(currHiers); + }; - return hierData; - }); + const click_handler_4 = async i => { + $$invalidate(0, currHiers = swapItems(i, i + 1, currHiers)); + await update(currHiers); + }; - debug(settings, { data }); - const cellStr = (i, type, info) => DIRECTIONS.map(dir => data[i][dir][type][info]).join("\n"); - let hierStrs = userHierarchies.map(hierToStr); - const click_handler = async (i, dir) => await copy$1(data[i][dir].Merged.nodesStr); - const func = (i, dir) => data[i][dir].Merged.nodes.length; - const click_handler_1 = async i => await copy$1(cellStr(i, "Merged", "nodesStr")); - const click_handler_2 = async (i, dir) => await copy$1(data[i][dir].Merged.edgesStr); - const func_1 = (i, dir) => data[i][dir].Merged.edges.length; - const click_handler_3 = async i => await copy$1(cellStr(i, "Merged", "edgesStr")); - const click_handler_4 = async (i, dir) => await copy$1(data[i][dir].Implied.edgesStr); - const func_2 = (i, dir) => data[i][dir].Implied.edges.length; - const click_handler_5 = async i => await copy$1(cellStr(i, "Implied", "edgesStr")); - const func_3 = (dir, datum) => datum[dir].Merged.nodes.length; - const func_4 = (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_5 = (dir, datum) => datum[dir].Merged.edges.length; - const func_6 = (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_7 = (dir, datum) => datum[dir].Implied.edges.length; - const func_8 = (dir, datum) => datum[dir].Implied.edgesStr; - const click_handler_8 = async dir => await copy$1(data.map(datum => datum[dir].Implied.edgesStr).join("\n")); + const click_handler_5 = async i => { + currHiers.splice(i, 1); + $$invalidate(0, currHiers); + await update(currHiers); + }; + + const change_handler = async (i, dir, e) => { + $$invalidate(0, currHiers[i][dir] = splitAndTrim(e.target.value), currHiers); + await update(currHiers); + }; $$self.$$set = $$props => { - if ("plugin" in $$props) $$invalidate(4, plugin = $$props.plugin); + if ("plugin" in $$props) $$invalidate(2, plugin = $$props.plugin); }; return [ - userHierarchies, - data, - cellStr, - hierStrs, + currHiers, + update, plugin, click_handler, - func, click_handler_1, click_handler_2, - func_1, + func, click_handler_3, click_handler_4, - func_2, click_handler_5, - func_3, - func_4, - click_handler_6, - func_5, - func_6, - click_handler_7, - func_7, - func_8, - click_handler_8 + change_handler ]; } -class Stats extends SvelteComponent { +class UserHierarchies extends SvelteComponent { constructor(options) { super(); - if (!document.getElementById("svelte-rb5mhu-style")) add_css$3(); - init$1(this, options, instance$4, create_fragment$4, safe_not_equal, { plugin: 4 }, [-1, -1]); + if (!document.getElementById("svelte-5y4abu-style")) add_css$3(); + init$1(this, options, instance$4, create_fragment$4, safe_not_equal, { plugin: 2 }); } } -class StatsView extends obsidian.ItemView { - constructor(leaf, plugin) { - super(leaf); - this.icon = "info"; +class BCSettingTab extends obsidian.PluginSettingTab { + constructor(app, plugin) { + super(app, plugin); 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); + 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", }); - } - 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 = getOutNeighbours(g, currPath.node); - const extPath = [currPath.node, ...currPath.path]; - queue.unshift(...newNodes.map((n) => { - return { node: n, path: extPath }; + 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"); + } })); - if (newNodes.length === 0) { - pathsArr.push(extPath); + } + 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(); + } + const activeMatrix = plugin.getActiveTYPEView(MATRIX_VIEW); + if (activeMatrix) { + await activeMatrix.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.getActiveTYPEView(MATRIX_VIEW).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.getActiveTYPEView(MATRIX_VIEW).draw(); + })); + new obsidian.Setting(MLViewDetails) + .setName("Sorting Field Name") + .setDesc("The metadata field name used to indicate the order in which items should be sorted in the L/M view.") + .addText((text) => text.setValue(settings.orderField).onChange(async (value) => { + settings.orderField = value; + await plugin.saveSettings(); + await plugin.getActiveTYPEView(MATRIX_VIEW).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.getActiveTYPEView(MATRIX_VIEW).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.getActiveTYPEView(MATRIX_VIEW)) === null || _a === void 0 ? void 0 : _a.onClose()); + await openView(this.app, MATRIX_VIEW, MatrixView, value ? "right" : "left"); + })); + const trailDetails = containerEl.createEl("details"); + trailDetails.createEl("summary", { text: "Trail/Grid" }); + new obsidian.Setting(trailDetails) + .setName("Show Breadcrumbs") + .setDesc("Show a set of different views at the top of the current note.") + .addToggle((toggle) => toggle.setValue(settings.showBCs).onChange(async (value) => { + settings.showBCs = value; + await plugin.saveSettings(); + await plugin.drawTrail(); + })); + const limitTrailFieldsDiv = trailDetails.createDiv({ + cls: "limit-ML-fields", + }); + limitTrailFieldsDiv.createEl("strong", { + text: "Limit Trail 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 () => { + checkboxStates[field] = cb.checked; + await plugin.saveSettings(); + console.log(settings.limitTrailCheckboxStates); + }); + }); + }); } - return pathsArr; - } - async draw() { - this.contentEl.empty(); - this.view = new Stats({ - target: this.contentEl, - props: { plugin: this.plugin }, + 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("Views to show") + .setDesc("Choose which of the views to show at the top of the note.\nTrail, Grid, and/or the Next-Previous view.") + .addToggle((toggle) => { + toggle + .setTooltip("Show Trail view") + .setValue(settings.showTrail) + .onChange(async (value) => { + settings.showTrail = value; + await plugin.saveSettings(); + await plugin.drawTrail(); + }); + }) + .addToggle((toggle) => { + toggle + .setTooltip("Show Grid view") + .setValue(settings.showGrid) + .onChange(async (value) => { + settings.showGrid = value; + await plugin.saveSettings(); + await plugin.drawTrail(); + }); + }) + .addToggle((toggle) => { + toggle + .setTooltip("Show Next/Previous view") + .setValue(settings.showPrevNext) + .onChange(async (value) => { + settings.showPrevNext = value; + await plugin.saveSettings(); + await plugin.drawTrail(); + }); + }); + 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) => { + var _a; + (_a = userHier[dir]) === null || _a === void 0 ? void 0 : _a.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("Write BCs to file Inline") + .setDesc("When writing BCs to file, should they be written inline (using Dataview syntax), or into the YAML of the note?") + .addToggle((toggle) => toggle.setValue(settings.writeBCsInline).onChange(async (value) => { + settings.writeBCsInline = value; + await plugin.saveSettings(); + })); + 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 }); } } @@ -34986,8 +35229,10 @@ class BCPlugin extends obsidian.Plugin { this.initEverything = async () => { const { settings } = this; this.currGraphs = await this.initGraphs(); - await openView(this.app, MATRIX_VIEW, MatrixView); - await openView(this.app, STATS_VIEW, StatsView); + for (const view of VIEWS) { + if (view.openOnLoad) + await openView(this.app, view.type, view.constructor); + } if (settings.showBCs) await this.drawTrail(); this.registerActiveLeafEvent(); @@ -34997,7 +35242,7 @@ class BCPlugin extends obsidian.Plugin { this.currGraphs = await this.initGraphs(); if (settings.showBCs) await this.drawTrail(); - const activeView = this.getActiveMatrixView(); + const activeView = this.getActiveTYPEView(MATRIX_VIEW); if (activeView) await activeView.draw(); }, settings.refreshIntervalTime * 1000); @@ -35081,9 +35326,12 @@ class BCPlugin extends obsidian.Plugin { if (!this.activeLeafChange) this.registerActiveLeafEvent(); this.currGraphs = await this.initGraphs(); - const activeView = this.getActiveMatrixView(); - if (activeView) - await activeView.draw(); + const activeMatrix = this.getActiveTYPEView(MATRIX_VIEW); + const activeDucks = this.getActiveTYPEView(DUCK_VIEW); + if (activeMatrix) + await activeMatrix.draw(); + if (activeDucks) + await activeDucks.draw(); if (this.settings.showTrail) await this.drawTrail(); new obsidian.Notice("Index refreshed"); @@ -35094,7 +35342,7 @@ class BCPlugin extends obsidian.Plugin { await this.refreshIndex(); } else { - const activeView = this.getActiveMatrixView(); + const activeView = this.getActiveTYPEView(MATRIX_VIEW); if (activeView) await activeView.draw(); if (this.settings.showBCs) @@ -35113,8 +35361,9 @@ class BCPlugin extends obsidian.Plugin { await this.saveSettings(); }); }); - this.registerView(STATS_VIEW, (leaf) => new StatsView(leaf, this)); - this.registerView(MATRIX_VIEW, (leaf) => new MatrixView(leaf, this)); + for (const view of VIEWS) { + this.registerView(view.type, (leaf) => new view.constructor(leaf, this)); + } this.app.workspace.onLayoutReady(async () => { var _a; if (this.app.plugins.enabledPlugins.has("dataview")) { @@ -35130,28 +35379,19 @@ class BCPlugin extends obsidian.Plugin { } }); obsidian.addIcon(TRAIL_ICON, TRAIL_ICON_SVG); - this.addCommand({ - id: "show-breadcrumbs-matrix-view", - name: "Open Matrix View", - //@ts-ignore - checkCallback: async (checking) => { - if (checking) { - return this.app.workspace.getLeavesOfType(MATRIX_VIEW).length === 0; - } - await openView(this.app, MATRIX_VIEW, MatrixView); - }, - }); - this.addCommand({ - id: "show-breadcrumbs-stats-view", - name: "Open Stats View", - //@ts-ignore - checkCallback: async (checking) => { - if (checking) { - return this.app.workspace.getLeavesOfType(STATS_VIEW).length === 0; - } - await openView(this.app, STATS_VIEW, StatsView); - }, - }); + for (const view of VIEWS) { + this.addCommand({ + id: `show-${view.type}-view`, + name: `Open ${view.plain} View`, + //@ts-ignore + checkCallback: async (checking) => { + if (checking) { + return this.app.workspace.getLeavesOfType(view.type).length === 0; + } + await openView(this.app, view.type, view.constructor); + }, + }); + } this.addCommand({ id: "Refresh-Breadcrumbs-Index", name: "Refresh Breadcrumbs Index", @@ -35191,16 +35431,16 @@ class BCPlugin extends obsidian.Plugin { }, checkCallback: () => this.settings.showWriteAllBCsCmd, }); - // TODO get a better icon for this - this.addRibbonIcon("dice", "Breadcrumbs Visualisation", () => new VisModal(this.app, this).open()); + this.addRibbonIcon(addFeatherIcon("tv"), "Breadcrumbs Visualisation", () => new VisModal(this.app, this).open()); this.statusBatItemEl = this.addStatusBarItem(); this.addSettingTab(new BCSettingTab(this.app, this)); } - getActiveMatrixView() { - const leaves = this.app.workspace.getLeavesOfType(MATRIX_VIEW); + getActiveTYPEView(type) { + const { constructor } = VIEWS.find((view) => view.type === type); + const leaves = this.app.workspace.getLeavesOfType(type); if (leaves && leaves.length >= 1) { const view = leaves[0].view; - if (view instanceof MatrixView) { + if (view instanceof constructor) { return view; } } @@ -35208,11 +35448,14 @@ class BCPlugin extends obsidian.Plugin { } // SECTION OneSource populateGraph(g, currFileName, fieldValues, dir, fieldName) { + //@ts-ignore addNodeIfNot(g, currFileName, { dir, fieldName }); if (fieldName === "") return; fieldValues.forEach((value) => { + //@ts-ignore addNodeIfNot(g, value, { dir, fieldName }); + //@ts-ignore addEdgeIfNot(g, currFileName, value, { dir, fieldName }); }); } @@ -35244,6 +35487,7 @@ class BCPlugin extends obsidian.Plugin { if (fieldName === "" || !row[fieldName]) return; addNodeIfNot(g, row[fieldName]); + //@ts-ignore addEdgeIfNot(g, row.file, row[fieldName], { dir, fieldName }); }); } @@ -35311,13 +35555,13 @@ class BCPlugin extends obsidian.Plugin { const g = graphs.hierGs[i][dir][fieldName]; const targets = hier[dir][fieldName]; this.populateGraph(g, currFileName, targets, dir, fieldName); + addNodeIfNot(graphs.main, currFileName, { + dir, + fieldName, + order: neighbours.order, + }); targets.forEach((target) => { var _a, _b; - addNodeIfNot(graphs.main, currFileName, { - dir, - fieldName, - order: neighbours.order, - }); addNodeIfNot(graphs.main, target, { dir, fieldName, @@ -35343,6 +35587,7 @@ class BCPlugin extends obsidian.Plugin { const gUp = graphs.hierGs.find((hierG) => hierG.up[hierarchyNoteUpFieldName]).up[hierarchyNoteUpFieldName]; hierarchyNotesArr.forEach((adjListItem) => { adjListItem.children.forEach((child) => { + //@ts-ignore addNodeIfNot(gUp, adjListItem.note, { dir: "up" }); gUp.addEdge(child, adjListItem.note, { dir: "up", @@ -35355,6 +35600,7 @@ class BCPlugin extends obsidian.Plugin { const gDown = graphs.hierGs.find((hierG) => hierG.down[hierarchyNoteDownFieldName]).down[hierarchyNoteDownFieldName]; hierarchyNotesArr.forEach((adjListItem) => { adjListItem.children.forEach((child) => { + //@ts-ignore addNodeIfNot(gDown, adjListItem.note, { dir: "down" }); gDown.addEdge(adjListItem.note, child, { dir: "down", @@ -35530,7 +35776,7 @@ class BCPlugin extends obsidian.Plugin { } onunload() { console.log("unloading"); - [MATRIX_VIEW, STATS_VIEW].forEach((type) => this.app.workspace.detachLeavesOfType(type)); + VIEWS.forEach((view) => this.app.workspace.detachLeavesOfType(view.type)); // Empty trailDiv this.visited.forEach((visit) => visit[1].remove()); } diff --git a/src/BreadcrumbsSettingTab.ts b/src/BreadcrumbsSettingTab.ts index 6e9d812a..f0a94576 100644 --- a/src/BreadcrumbsSettingTab.ts +++ b/src/BreadcrumbsSettingTab.ts @@ -266,8 +266,9 @@ export class BCSettingTab extends PluginSettingTab { if (settings.showTrail) { await plugin.drawTrail(); } - if (plugin.getActiveMatrixView()) { - await plugin.getActiveMatrixView().draw(); + const activeMatrix = plugin.getActiveTYPEView(MATRIX_VIEW); + if (activeMatrix) { + await activeMatrix.draw(); } }, num * 1000); plugin.registerInterval(plugin.refreshIntervalID); @@ -306,7 +307,7 @@ export class BCSettingTab extends PluginSettingTab { toggle.setValue(settings.showNameOrType).onChange(async (value) => { settings.showNameOrType = value; await plugin.saveSettings(); - await plugin.getActiveMatrixView().draw(); + await plugin.getActiveTYPEView(MATRIX_VIEW).draw(); }) ); @@ -319,7 +320,7 @@ export class BCSettingTab extends PluginSettingTab { toggle.setValue(settings.showRelationType).onChange(async (value) => { settings.showRelationType = value; await plugin.saveSettings(); - await plugin.getActiveMatrixView().draw(); + await plugin.getActiveTYPEView(MATRIX_VIEW).draw(); }) ); @@ -332,7 +333,7 @@ export class BCSettingTab extends PluginSettingTab { text.setValue(settings.orderField).onChange(async (value) => { settings.orderField = value; await plugin.saveSettings(); - await plugin.getActiveMatrixView().draw(); + await plugin.getActiveTYPEView(MATRIX_VIEW).draw(); }) ); @@ -347,7 +348,7 @@ export class BCSettingTab extends PluginSettingTab { .onChange(async (value) => { settings.filterImpliedSiblingsOfDifferentTypes = value; await plugin.saveSettings(); - await plugin.getActiveMatrixView().draw(); + await plugin.getActiveTYPEView(MATRIX_VIEW).draw(); }) ); @@ -360,7 +361,7 @@ export class BCSettingTab extends PluginSettingTab { toggle.setValue(settings.rlLeaf).onChange(async (value) => { settings.rlLeaf = value; await plugin.saveSettings(); - await plugin.getActiveMatrixView()?.onClose(); + await plugin.getActiveTYPEView(MATRIX_VIEW)?.onClose(); await openView( this.app, MATRIX_VIEW, diff --git a/src/constants.ts b/src/constants.ts index d1abbc11..58bdd0fd 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,3 +1,5 @@ +import type { Constructor } from "obsidian"; +import DucksView from "src/DucksView"; import type { BCSettings, Directions, @@ -5,9 +7,35 @@ import type { userHierarchy, visTypes, } from "src/interfaces"; +import MatrixView from "src/MatrixView"; +import StatsView from "src/StatsView"; export const MATRIX_VIEW = "BC-matrix"; export const STATS_VIEW = "BC-stats"; +export const DUCK_VIEW = "BC-ducks"; + +export type MyView = MatrixView | StatsView | DucksView; + +export const VIEWS: { + plain: string; + type: string; + constructor: Constructor; + openOnLoad: boolean; +}[] = [ + { + plain: "Matrix", + type: MATRIX_VIEW, + constructor: MatrixView, + openOnLoad: true, + }, + { + plain: "Stats", + type: STATS_VIEW, + constructor: StatsView, + openOnLoad: true, + }, + { plain: "Duck", type: DUCK_VIEW, constructor: DucksView, openOnLoad: false }, +]; export const TRAIL_ICON = "BC-trail-icon"; export const TRAIL_ICON_SVG =