From 4535e732847525e63497e6f3dff7269313f5c708 Mon Sep 17 00:00:00 2001 From: Professor348 <141444315+Professor348@users.noreply.github.com> Date: Sun, 18 Jan 2026 10:34:17 -0500 Subject: [PATCH 01/13] Worked on the file structure diagram --- Diagrams/.obsidian/appearance.json | 4 +- Diagrams/.obsidian/canvas.json | 4 + Diagrams/.obsidian/community-plugins.json | 3 + .../.obsidian/plugins/advanced-canvas/main.js | 7372 +++++++++++++++++ .../plugins/advanced-canvas/manifest.json | 11 + .../plugins/advanced-canvas/styles.css | 508 ++ Diagrams/.obsidian/workspace.json | 20 +- Diagrams/File Structure.canvas | 727 +- Diagrams/File Structure.png | Bin 0 -> 232311 bytes Diagrams/File_Structure.png | Bin 233641 -> 0 bytes 10 files changed, 8132 insertions(+), 517 deletions(-) create mode 100644 Diagrams/.obsidian/canvas.json create mode 100644 Diagrams/.obsidian/community-plugins.json create mode 100644 Diagrams/.obsidian/plugins/advanced-canvas/main.js create mode 100644 Diagrams/.obsidian/plugins/advanced-canvas/manifest.json create mode 100644 Diagrams/.obsidian/plugins/advanced-canvas/styles.css create mode 100644 Diagrams/File Structure.png delete mode 100644 Diagrams/File_Structure.png diff --git a/Diagrams/.obsidian/appearance.json b/Diagrams/.obsidian/appearance.json index 9e26dfeeb6e6..a8b1e375fd66 100644 --- a/Diagrams/.obsidian/appearance.json +++ b/Diagrams/.obsidian/appearance.json @@ -1 +1,3 @@ -{} \ No newline at end of file +{ + "theme": "moonstone" +} \ No newline at end of file diff --git a/Diagrams/.obsidian/canvas.json b/Diagrams/.obsidian/canvas.json new file mode 100644 index 000000000000..b7dd5188e42d --- /dev/null +++ b/Diagrams/.obsidian/canvas.json @@ -0,0 +1,4 @@ +{ + "snapToObjects": false, + "snapToGrid": true +} \ No newline at end of file diff --git a/Diagrams/.obsidian/community-plugins.json b/Diagrams/.obsidian/community-plugins.json new file mode 100644 index 000000000000..db856a363b41 --- /dev/null +++ b/Diagrams/.obsidian/community-plugins.json @@ -0,0 +1,3 @@ +[ + "advanced-canvas" +] \ No newline at end of file diff --git a/Diagrams/.obsidian/plugins/advanced-canvas/main.js b/Diagrams/.obsidian/plugins/advanced-canvas/main.js new file mode 100644 index 000000000000..1110599b4354 --- /dev/null +++ b/Diagrams/.obsidian/plugins/advanced-canvas/main.js @@ -0,0 +1,7372 @@ +/* +THIS IS A GENERATED/BUNDLED FILE BY ESBUILD +if you want to view the source, please visit the github repository of this plugin +*/ + +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/main.ts +var main_exports = {}; +__export(main_exports, { + default: () => AdvancedCanvasPlugin +}); +module.exports = __toCommonJS(main_exports); +var import_obsidian19 = require("obsidian"); + +// src/utils/icons-helper.ts +var import_obsidian = require("obsidian"); +var CUSTOM_ICONS = { + "shape-pill": ``, + "shape-parallelogram": ``, + "shape-predefined-process": ` + + + + + + `, + "shape-document": ``, + "shape-database": ` + + + + + `, + "border-solid": ``, + "border-dashed": ``, + "border-dotted": ``, + "path-solid": ``, + "path-dotted": ``, + "path-short-dashed": ``, + "path-long-dashed": ``, + "arrow-triangle": ``, + "arrow-triangle-outline": ``, + "arrow-thin-triangle": ``, + "arrow-halved-triangle": ``, + "arrow-diamond": ``, + "arrow-diamond-outline": ``, + "arrow-circle": ``, + "arrow-circle-outline": ``, + "pathfinding-method-bezier": ``, + "pathfinding-method-square": ``, + "arrows-selected": ` + + + + + + + + + + `, + "arrow-right-selected": ` + + + + + + + + `, + "arrow-left-selected": ` + + + + + + + + ` +}; +var IconsHelper = class { + static addIcons() { + for (const [id, svg] of Object.entries(CUSTOM_ICONS)) { + (0, import_obsidian.addIcon)(id, svg); + } + } +}; + +// src/utils/debug-helper.ts +var DebugHelper = class { + constructor(plugin) { + this.logging = true; + this.nodeAddedCount = 0; + this.nodeChangedCount = 0; + this.edgeAddedCount = 0; + this.edgeChangedCount = 0; + this.plugin = plugin; + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:canvas-changed", + (_canvas) => { + this.nodeAddedCount = 0; + this.nodeChangedCount = 0; + this.edgeAddedCount = 0; + this.edgeChangedCount = 0; + } + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-added", + (_canvas, _node) => { + if (this.logging) console.count("\u{1F7E2} NodeAdded"); + this.nodeAddedCount++; + } + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-changed", + (_canvas, _node) => { + if (this.logging) console.count("\u{1F7E1} NodeChanged"); + this.nodeChangedCount++; + } + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:edge-added", + (_canvas, _edge) => { + if (this.logging) console.count("\u{1F7E2} EdgeAdded"); + this.edgeAddedCount++; + } + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:edge-changed", + (_canvas, _edge) => { + if (this.logging) console.count("\u{1F7E1} EdgeChanged"); + this.edgeChangedCount++; + } + )); + } + resetEfficiency() { + this.nodeAddedCount = 0; + this.nodeChangedCount = 0; + this.edgeAddedCount = 0; + this.edgeChangedCount = 0; + } + logEfficiency() { + const canvas = this.plugin.getCurrentCanvas(); + if (!canvas) return; + console.log("NodeAdded Efficiency:", this.nodeAddedCount / canvas.nodes.size); + console.log("NodeChanged Efficiency:", this.nodeChangedCount / canvas.nodes.size); + console.log("EdgeAdded Efficiency:", this.edgeAddedCount / canvas.edges.size); + console.log("EdgeChanged Efficiency:", this.edgeChangedCount / canvas.edges.size); + } + static markBBox(canvas, bbox, duration = -1) { + const node = canvas.createTextNode({ + pos: { x: bbox.minX, y: bbox.minY }, + size: { width: bbox.maxX - bbox.minX, height: bbox.maxY - bbox.minY }, + text: "", + focus: false + }); + node.setData({ + ...node.getData(), + id: "debug-bbox", + color: "1", + styleAttributes: { + border: "invisible" + } + }); + if (duration >= 0) { + setTimeout(() => { + canvas.removeNode(node); + }, duration); + } + } +}; + +// src/settings.ts +var import_obsidian4 = require("obsidian"); + +// src/utils/bbox-helper.ts +var BBoxHelper = class { + static combineBBoxes(bboxes) { + let minX = Infinity; + let minY = Infinity; + let maxX = -Infinity; + let maxY = -Infinity; + for (let bbox of bboxes) { + minX = Math.min(minX, bbox.minX); + minY = Math.min(minY, bbox.minY); + maxX = Math.max(maxX, bbox.maxX); + maxY = Math.max(maxY, bbox.maxY); + } + return { minX, minY, maxX, maxY }; + } + static scaleBBox(bbox, scale) { + let diffX = (scale - 1) * (bbox.maxX - bbox.minX); + let diffY = (scale - 1) * (bbox.maxY - bbox.minY); + return { + minX: bbox.minX - diffX / 2, + maxX: bbox.maxX + diffX / 2, + minY: bbox.minY - diffY / 2, + maxY: bbox.maxY + diffY / 2 + }; + } + static isColliding(bbox1, bbox2) { + return bbox1.minX <= bbox2.maxX && bbox1.maxX >= bbox2.minX && bbox1.minY <= bbox2.maxY && bbox1.maxY >= bbox2.minY; + } + static insideBBox(position, bbox, canTouchEdge) { + if ("x" in position) { + const x = position.x, y = position.y; + return canTouchEdge ? x >= bbox.minX && x <= bbox.maxX && y >= bbox.minY && y <= bbox.maxY : x > bbox.minX && x < bbox.maxX && y > bbox.minY && y < bbox.maxY; + } + return canTouchEdge ? position.minX >= bbox.minX && position.maxX <= bbox.maxX && position.minY >= bbox.minY && position.maxY <= bbox.maxY : position.minX > bbox.minX && position.maxX < bbox.maxX && position.minY > bbox.minY && position.maxY < bbox.maxY; + } + static enlargeBBox(bbox, padding) { + return { + minX: bbox.minX - padding, + minY: bbox.minY - padding, + maxX: bbox.maxX + padding, + maxY: bbox.maxY + padding + }; + } + static moveInDirection(position, side, distance) { + switch (side) { + case "top": + return { x: position.x, y: position.y - distance }; + case "right": + return { x: position.x + distance, y: position.y }; + case "bottom": + return { x: position.x, y: position.y + distance }; + case "left": + return { x: position.x - distance, y: position.y }; + } + } + static getCenterOfBBoxSide(bbox, side) { + switch (side) { + case "top": + return { x: (bbox.minX + bbox.maxX) / 2, y: bbox.minY }; + case "right": + return { x: bbox.maxX, y: (bbox.minY + bbox.maxY) / 2 }; + case "bottom": + return { x: (bbox.minX + bbox.maxX) / 2, y: bbox.maxY }; + case "left": + return { x: bbox.minX, y: (bbox.minY + bbox.maxY) / 2 }; + } + } + static getSideVector(side) { + switch (side) { + case "top": + return { x: 0, y: 1 }; + case "right": + return { x: 1, y: 0 }; + case "bottom": + return { x: 0, y: -1 }; + case "left": + return { x: -1, y: 0 }; + default: + return { x: 0, y: 0 }; + } + } + static getOppositeSide(side) { + switch (side) { + case "top": + return "bottom"; + case "right": + return "left"; + case "bottom": + return "top"; + case "left": + return "right"; + } + } + static isHorizontal(side) { + return side === "left" || side === "right"; + } + static direction(side) { + return side === "right" || side === "bottom" ? 1 : -1; + } +}; + +// src/utils/canvas-helper.ts +var import_obsidian2 = require("obsidian"); +var _CanvasHelper = class _CanvasHelper { + static canvasCommand(plugin, check, run) { + return (checking) => { + const canvas = plugin.getCurrentCanvas(); + if (checking) return canvas !== null && check(canvas); + if (canvas) run(canvas); + return true; + }; + } + static createControlMenuButton(menuOption) { + const quickSetting = document.createElement("div"); + if (menuOption.id) quickSetting.id = menuOption.id; + quickSetting.classList.add("canvas-control-item"); + (0, import_obsidian2.setIcon)(quickSetting, menuOption.icon); + (0, import_obsidian2.setTooltip)(quickSetting, menuOption.label, { placement: "left" }); + quickSetting.addEventListener("click", () => { + var _a; + return (_a = menuOption.callback) == null ? void 0 : _a.call(menuOption); + }); + return quickSetting; + } + static addControlMenuButton(controlGroup, element) { + var _a; + if (element.id) (_a = controlGroup.querySelector(`#${element.id}`)) == null ? void 0 : _a.remove(); + controlGroup.appendChild(element); + } + static createCardMenuOption(canvas, menuOption, previewNodeSize, onPlaced) { + const menuOptionElement = document.createElement("div"); + if (menuOption.id) menuOptionElement.id = menuOption.id; + menuOptionElement.classList.add("canvas-card-menu-button"); + menuOptionElement.classList.add("mod-draggable"); + (0, import_obsidian2.setIcon)(menuOptionElement, menuOption.icon); + (0, import_obsidian2.setTooltip)(menuOptionElement, menuOption.label, { placement: "top" }); + menuOptionElement.addEventListener("click", (_e) => { + onPlaced(canvas, this.getCenterCoordinates(canvas, previewNodeSize())); + }); + menuOptionElement.addEventListener("pointerdown", (e) => { + canvas.dragTempNode(e, previewNodeSize(), (pos) => { + canvas.deselectAll(); + onPlaced(canvas, pos); + }); + }); + return menuOptionElement; + } + static addCardMenuOption(canvas, element) { + var _a; + if (element.id) (_a = canvas == null ? void 0 : canvas.cardMenuEl.querySelector(`#${element.id}`)) == null ? void 0 : _a.remove(); + canvas == null ? void 0 : canvas.cardMenuEl.appendChild(element); + } + static createPopupMenuOption(menuOption) { + const menuOptionElement = document.createElement("button"); + if (menuOption.id) menuOptionElement.id = menuOption.id; + menuOptionElement.classList.add("clickable-icon"); + (0, import_obsidian2.setIcon)(menuOptionElement, menuOption.icon); + (0, import_obsidian2.setTooltip)(menuOptionElement, menuOption.label, { placement: "top" }); + menuOptionElement.addEventListener("click", () => { + var _a; + return (_a = menuOption.callback) == null ? void 0 : _a.call(menuOption); + }); + return menuOptionElement; + } + static createExpandablePopupMenuOption(menuOption, subMenuOptions) { + const menuOptionElement = this.createPopupMenuOption({ + ...menuOption, + callback: () => { + var _a, _b, _c; + const submenuId = `${menuOption.id}-submenu`; + if (menuOptionElement.classList.contains("is-active")) { + menuOptionElement.classList.remove("is-active"); + (_b = (_a = menuOptionElement.parentElement) == null ? void 0 : _a.querySelector(`#${submenuId}`)) == null ? void 0 : _b.remove(); + return; + } + menuOptionElement.classList.add("is-active"); + const submenu = document.createElement("div"); + submenu.id = submenuId; + submenu.classList.add("canvas-submenu"); + for (const subMenuOption of subMenuOptions) { + const subMenuOptionElement = this.createPopupMenuOption(subMenuOption); + submenu.appendChild(subMenuOptionElement); + } + (_c = menuOptionElement.parentElement) == null ? void 0 : _c.appendChild(submenu); + } + }); + return menuOptionElement; + } + static addPopupMenuOption(canvas, element, index = -1) { + var _a; + const popupMenuEl = (_a = canvas == null ? void 0 : canvas.menu) == null ? void 0 : _a.menuEl; + if (!popupMenuEl) return; + if (element.id) { + const optionToReplace = popupMenuEl.querySelector(`#${element.id}`); + if (optionToReplace && index === -1) index = Array.from(popupMenuEl.children).indexOf(optionToReplace) - 1; + optionToReplace == null ? void 0 : optionToReplace.remove(); + } + const sisterElement = index >= 0 ? popupMenuEl.children[index] : popupMenuEl.children[popupMenuEl.children.length + index]; + popupMenuEl.insertAfter(element, sisterElement); + } + static getCenterCoordinates(canvas, nodeSize) { + const viewBounds = canvas.getViewportBBox(); + return { + x: (viewBounds.minX + viewBounds.maxX) / 2 - nodeSize.width / 2, + y: (viewBounds.minY + viewBounds.maxY) / 2 - nodeSize.height / 2 + }; + } + static getBBox(canvasElements) { + const bBoxes = canvasElements.map((element) => { + if (element.getBBox) return element.getBBox(); + const nodeData = element; + if (nodeData.x !== void 0 && nodeData.y !== void 0 && nodeData.width !== void 0 && nodeData.height !== void 0) + return { minX: nodeData.x, minY: nodeData.y, maxX: nodeData.x + nodeData.width, maxY: nodeData.y + nodeData.height }; + return null; + }).filter((bbox) => bbox !== null); + return BBoxHelper.combineBBoxes(bBoxes); + } + static getSmallestAllowedZoomBBox(canvas, bbox) { + if (canvas.screenshotting) return bbox; + if (canvas.canvasRect.width === 0 || canvas.canvasRect.height === 0) return bbox; + const widthZoom = canvas.canvasRect.width / (bbox.maxX - bbox.minX); + const heightZoom = canvas.canvasRect.height / (bbox.maxY - bbox.minY); + const requiredZoom = Math.min(widthZoom, heightZoom); + if (requiredZoom > _CanvasHelper.MAX_ALLOWED_ZOOM) { + const scaleFactor = requiredZoom / _CanvasHelper.MAX_ALLOWED_ZOOM; + return BBoxHelper.scaleBBox(bbox, scaleFactor); + } + return bbox; + } + static addStyleAttributesToPopup(plugin, canvas, styleAttributes, currentStyleAttributes, setStyleAttribute) { + if (!plugin.settings.getSetting("combineCustomStylesInDropdown")) + this.addStyleAttributesButtons(canvas, styleAttributes, currentStyleAttributes, setStyleAttribute); + else this.addStyleAttributesDropdownMenu(canvas, styleAttributes, currentStyleAttributes, setStyleAttribute); + } + static addStyleAttributesButtons(canvas, stylableAttributes, currentStyleAttributes, setStyleAttribute) { + var _a; + for (const stylableAttribute of stylableAttributes) { + const selectedStyle = (_a = stylableAttribute.options.find((option) => currentStyleAttributes[stylableAttribute.key] === option.value)) != null ? _a : stylableAttribute.options.find((value) => value.value === null); + const menuOption = _CanvasHelper.createExpandablePopupMenuOption({ + id: `menu-option-${stylableAttribute.key}`, + label: stylableAttribute.label, + icon: selectedStyle.icon + }, stylableAttribute.options.map((styleOption) => ({ + label: styleOption.label, + icon: styleOption.icon, + callback: () => { + setStyleAttribute(stylableAttribute, styleOption.value); + currentStyleAttributes[stylableAttribute.key] = styleOption.value; + (0, import_obsidian2.setIcon)(menuOption, styleOption.icon); + menuOption.dispatchEvent(new Event("click")); + } + }))); + _CanvasHelper.addPopupMenuOption(canvas, menuOption); + } + } + static addStyleAttributesDropdownMenu(canvas, stylableAttributes, currentStyleAttributes, setStyleAttribute) { + var _a, _b; + const STYLE_MENU_ID = "style-menu"; + const STYLE_MENU_DROPDOWN_ID = "style-menu-dropdown"; + const STYLE_MENU_DROPDOWN_SUBMENU_ID = "style-menu-dropdown-submenu"; + const popupMenuElement = (_a = canvas == null ? void 0 : canvas.menu) == null ? void 0 : _a.menuEl; + if (!popupMenuElement) return; + (_b = popupMenuElement.querySelector(`#${STYLE_MENU_ID}`)) == null ? void 0 : _b.remove(); + const styleMenuButtonElement = document.createElement("button"); + styleMenuButtonElement.id = STYLE_MENU_ID; + styleMenuButtonElement.classList.add("clickable-icon"); + (0, import_obsidian2.setIcon)(styleMenuButtonElement, "paintbrush"); + (0, import_obsidian2.setTooltip)(styleMenuButtonElement, "Style", { placement: "top" }); + popupMenuElement.appendChild(styleMenuButtonElement); + styleMenuButtonElement.addEventListener("click", () => { + var _a2, _b2, _c; + const isOpen = styleMenuButtonElement.classList.toggle("has-active-menu"); + if (!isOpen) { + (_a2 = popupMenuElement.querySelector(`#${STYLE_MENU_DROPDOWN_ID}`)) == null ? void 0 : _a2.remove(); + (_b2 = popupMenuElement.querySelector(`#${STYLE_MENU_DROPDOWN_SUBMENU_ID}`)) == null ? void 0 : _b2.remove(); + return; + } + const styleMenuDropdownElement = document.createElement("div"); + styleMenuDropdownElement.id = STYLE_MENU_DROPDOWN_ID; + styleMenuDropdownElement.classList.add("menu"); + styleMenuDropdownElement.style.position = "absolute"; + styleMenuDropdownElement.style.maxHeight = "initial"; + styleMenuDropdownElement.style.top = `${popupMenuElement.getBoundingClientRect().height}px`; + const canvasWrapperCenterX = canvas.wrapperEl.getBoundingClientRect().left + canvas.wrapperEl.getBoundingClientRect().width / 2; + const leftPosition = styleMenuButtonElement.getBoundingClientRect().left - popupMenuElement.getBoundingClientRect().left; + const rightPosition = popupMenuElement.getBoundingClientRect().right - styleMenuButtonElement.getBoundingClientRect().right; + if (popupMenuElement.getBoundingClientRect().left + leftPosition < canvasWrapperCenterX) + styleMenuDropdownElement.style.left = `${leftPosition}px`; + else styleMenuDropdownElement.style.right = `${rightPosition}px`; + for (const stylableAttribute of stylableAttributes) { + const stylableAttributeElement = document.createElement("div"); + stylableAttributeElement.classList.add("menu-item"); + stylableAttributeElement.classList.add("tappable"); + const iconElement = document.createElement("div"); + iconElement.classList.add("menu-item-icon"); + let selectedStyle = (_c = stylableAttribute.options.find((option) => currentStyleAttributes[stylableAttribute.key] === option.value)) != null ? _c : stylableAttribute.options.find((value) => value.value === null); + (0, import_obsidian2.setIcon)(iconElement, selectedStyle.icon); + stylableAttributeElement.appendChild(iconElement); + const labelElement = document.createElement("div"); + labelElement.classList.add("menu-item-title"); + labelElement.textContent = stylableAttribute.label; + stylableAttributeElement.appendChild(labelElement); + const expandIconElement = document.createElement("div"); + expandIconElement.classList.add("menu-item-icon"); + (0, import_obsidian2.setIcon)(expandIconElement, "chevron-right"); + stylableAttributeElement.appendChild(expandIconElement); + styleMenuDropdownElement.appendChild(stylableAttributeElement); + stylableAttributeElement.addEventListener("pointerenter", () => { + stylableAttributeElement.classList.add("selected"); + }); + stylableAttributeElement.addEventListener("pointerleave", () => { + stylableAttributeElement.classList.remove("selected"); + }); + stylableAttributeElement.addEventListener("click", () => { + var _a3; + (_a3 = popupMenuElement.querySelector(`#${STYLE_MENU_DROPDOWN_SUBMENU_ID}`)) == null ? void 0 : _a3.remove(); + const styleMenuDropdownSubmenuElement = document.createElement("div"); + styleMenuDropdownSubmenuElement.id = STYLE_MENU_DROPDOWN_SUBMENU_ID; + styleMenuDropdownSubmenuElement.classList.add("menu"); + styleMenuDropdownSubmenuElement.style.position = "absolute"; + styleMenuDropdownSubmenuElement.style.maxHeight = "initial"; + const topOffset = parseFloat(window.getComputedStyle(styleMenuDropdownElement).getPropertyValue("padding-top")) + (styleMenuDropdownElement.offsetHeight - styleMenuDropdownElement.clientHeight) / 2; + styleMenuDropdownSubmenuElement.style.top = `${stylableAttributeElement.getBoundingClientRect().top - topOffset - popupMenuElement.getBoundingClientRect().top}px`; + const leftPosition2 = styleMenuDropdownElement.getBoundingClientRect().right - popupMenuElement.getBoundingClientRect().left; + const rightPosition2 = popupMenuElement.getBoundingClientRect().right - styleMenuDropdownElement.getBoundingClientRect().left; + if (popupMenuElement.getBoundingClientRect().left + leftPosition2 < canvasWrapperCenterX) + styleMenuDropdownSubmenuElement.style.left = `${leftPosition2}px`; + else styleMenuDropdownSubmenuElement.style.right = `${rightPosition2}px`; + for (const styleOption of stylableAttribute.options) { + const styleMenuDropdownSubmenuOptionElement = this.createDropdownOptionElement({ + label: styleOption.label, + icon: styleOption.icon, + callback: () => { + setStyleAttribute(stylableAttribute, styleOption.value); + currentStyleAttributes[stylableAttribute.key] = styleOption.value; + selectedStyle = styleOption; + (0, import_obsidian2.setIcon)(iconElement, styleOption.icon); + styleMenuDropdownSubmenuElement.remove(); + } + }); + if (selectedStyle === styleOption) { + styleMenuDropdownSubmenuOptionElement.classList.add("mod-selected"); + const selectedIconElement = document.createElement("div"); + selectedIconElement.classList.add("menu-item-icon"); + selectedIconElement.classList.add("mod-selected"); + (0, import_obsidian2.setIcon)(selectedIconElement, "check"); + styleMenuDropdownSubmenuOptionElement.appendChild(selectedIconElement); + } + styleMenuDropdownSubmenuElement.appendChild(styleMenuDropdownSubmenuOptionElement); + } + popupMenuElement.appendChild(styleMenuDropdownSubmenuElement); + }); + } + popupMenuElement.appendChild(styleMenuDropdownElement); + }); + } + static createDropdownOptionElement(menuOption) { + const menuDropdownOptionElement = document.createElement("div"); + menuDropdownOptionElement.classList.add("menu-item"); + menuDropdownOptionElement.classList.add("tappable"); + const iconElement = document.createElement("div"); + iconElement.classList.add("menu-item-icon"); + (0, import_obsidian2.setIcon)(iconElement, menuOption.icon); + menuDropdownOptionElement.appendChild(iconElement); + const labelElement = document.createElement("div"); + labelElement.classList.add("menu-item-title"); + labelElement.textContent = menuOption.label; + menuDropdownOptionElement.appendChild(labelElement); + menuDropdownOptionElement.addEventListener("pointerenter", () => { + menuDropdownOptionElement.classList.add("selected"); + }); + menuDropdownOptionElement.addEventListener("pointerleave", () => { + menuDropdownOptionElement.classList.remove("selected"); + }); + menuDropdownOptionElement.addEventListener("click", () => { + var _a; + (_a = menuOption.callback) == null ? void 0 : _a.call(menuOption); + }); + return menuDropdownOptionElement; + } + static createDropdownSeparatorElement() { + const separatorElement = document.createElement("div"); + separatorElement.classList.add("menu-separator"); + return separatorElement; + } + static alignToGrid(value, gridSize = this.GRID_SIZE) { + return Math.round(value / gridSize) * gridSize; + } + static getBestSideForFloatingEdge(sourcePos, target) { + const targetBBox = target.getBBox(); + const possibleSides = ["top", "right", "bottom", "left"]; + const possibleTargetPos = possibleSides.map((side) => [side, BBoxHelper.getCenterOfBBoxSide(targetBBox, side)]); + let bestSide = null; + let bestDistance = Infinity; + for (const [side, pos] of possibleTargetPos) { + const distance = Math.sqrt(Math.pow(sourcePos.x - pos.x, 2) + Math.pow(sourcePos.y - pos.y, 2)); + if (distance < bestDistance) { + bestDistance = distance; + bestSide = side; + } + } + return bestSide; + } + static selectEdgesForNodes(canvas, direction) { + const selection = canvas.getSelectionData(); + if (selection.nodes.length === 0) return; + const edges = /* @__PURE__ */ new Set(); + for (const nodeData of selection.nodes) { + const node = canvas.nodes.get(nodeData.id); + if (!node) continue; + for (const edge of canvas.getEdgesForNode(node)) { + switch (direction) { + case "connected": + edges.add(edge); + break; + case "incoming": + if (edge.to.node === node) edges.add(edge); + break; + case "outgoing": + if (edge.from.node === node) edges.add(edge); + break; + } + } + } + canvas.updateSelection(() => { + canvas.selection = edges; + }); + } +}; +_CanvasHelper.GRID_SIZE = 20; +_CanvasHelper.MAX_ALLOWED_ZOOM = 1; +var CanvasHelper = _CanvasHelper; + +// src/canvas-extensions/canvas-extension.ts +var CanvasExtension = class { + constructor(plugin) { + this.plugin = plugin; + const isEnabled = this.isEnabled(); + if (!(isEnabled === true || this.plugin.settings.getSetting(isEnabled))) return; + this.init(); + } +}; + +// src/utils/svg-path-helper.ts +var SvgPathHelper = class { + static smoothenPathArray(positions, tension) { + let newPositions = [...positions]; + if (positions.length <= 2) return newPositions; + newPositions = [positions[0]]; + for (let i = 1; i < positions.length - 2; i++) { + const p1 = positions[i]; + const p2 = positions[i + 1]; + const p3 = positions[i + 2]; + const t1 = (1 - tension) / 2; + const t2 = 1 - t1; + const x = t2 * t2 * t2 * p1.x + 3 * t2 * t2 * t1 * p2.x + 3 * t2 * t1 * t1 * p3.x + t1 * t1 * t1 * p2.x; + const y = t2 * t2 * t2 * p1.y + 3 * t2 * t2 * t1 * p2.y + 3 * t2 * t1 * t1 * p3.y + t1 * t1 * t1 * p2.y; + newPositions.push({ x, y }); + } + const lastPoint = positions[positions.length - 1]; + newPositions.push(lastPoint); + return newPositions; + } + static pathArrayToSvgPath(positions) { + for (let i = 0; i < positions.length - 2; i++) { + const p1 = positions[i]; + const p2 = positions[i + 1]; + const p3 = positions[i + 2]; + const currentDirection = { + x: p2.x - p1.x, + y: p2.y - p1.y + }; + const nextDirection = { + x: p3.x - p2.x, + y: p3.y - p2.y + }; + if (currentDirection.x !== nextDirection.x && currentDirection.y !== nextDirection.y) continue; + positions.splice(i + 1, 1); + i--; + } + return positions.map( + (position, index) => `${index === 0 ? "M" : "L"} ${position.x} ${position.y}` + ).join(" "); + } + static pathArrayToRoundedSvgPath(pathArray, targetRadius) { + if (pathArray.length < 3) + return this.pathArrayToSvgPath(pathArray); + pathArray = pathArray.filter((position, index) => { + if (index === 0) return true; + const previous = pathArray[index - 1]; + return !(position.x === previous.x && position.y === previous.y); + }); + const commands = []; + commands.push(`M ${pathArray[0].x} ${pathArray[0].y}`); + for (let i = 1; i < pathArray.length - 1; i++) { + const previous = pathArray[i - 1]; + const current = pathArray[i]; + const next = pathArray[i + 1]; + const prevDelta = { x: current.x - previous.x, y: current.y - previous.y }; + const nextDelta = { x: next.x - current.x, y: next.y - current.y }; + const prevLen = Math.sqrt(prevDelta.x * prevDelta.x + prevDelta.y * prevDelta.y); + const nextLen = Math.sqrt(nextDelta.x * nextDelta.x + nextDelta.y * nextDelta.y); + const prevUnit = prevLen ? { x: prevDelta.x / prevLen, y: prevDelta.y / prevLen } : { x: 0, y: 0 }; + const nextUnit = nextLen ? { x: nextDelta.x / nextLen, y: nextDelta.y / nextLen } : { x: 0, y: 0 }; + let dot = prevUnit.x * nextUnit.x + prevUnit.y * nextUnit.y; + dot = Math.max(-1, Math.min(1, dot)); + const angle = Math.acos(dot); + if (angle < 0.01 || Math.abs(Math.PI - angle) < 0.01) { + commands.push(`L ${current.x} ${current.y}`); + continue; + } + const desiredOffset = targetRadius * Math.tan(angle / 2); + const d = Math.min(desiredOffset, prevLen / 2, nextLen / 2); + const effectiveRadius = d / Math.tan(angle / 2); + const firstAnchor = { + x: current.x - prevUnit.x * d, + y: current.y - prevUnit.y * d + }; + const secondAnchor = { + x: current.x + nextUnit.x * d, + y: current.y + nextUnit.y * d + }; + commands.push(`L ${firstAnchor.x} ${firstAnchor.y}`); + const cross = prevDelta.x * nextDelta.y - prevDelta.y * nextDelta.x; + const sweepFlag = cross < 0 ? 0 : 1; + commands.push(`A ${effectiveRadius} ${effectiveRadius} 0 0 ${sweepFlag} ${secondAnchor.x} ${secondAnchor.y}`); + } + const last = pathArray[pathArray.length - 1]; + commands.push(`L ${last.x} ${last.y}`); + return commands.join(" "); + } +}; + +// src/canvas-extensions/advanced-styles/edge-pathfinding-methods/edge-pathfinding-method.ts +var EdgePathfindingMethod = class { + constructor(plugin, canvas, fromNodeBBox, fromPos, fromBBoxSidePos, fromSide, toNodeBBox, toPos, toBBoxSidePos, toSide) { + this.plugin = plugin; + this.canvas = canvas; + this.fromNodeBBox = fromNodeBBox; + this.fromPos = fromPos; + this.fromBBoxSidePos = fromBBoxSidePos; + this.fromSide = fromSide; + this.toNodeBBox = toNodeBBox; + this.toPos = toPos; + this.toBBoxSidePos = toBBoxSidePos; + this.toSide = toSide; + } +}; + +// src/canvas-extensions/advanced-styles/edge-pathfinding-methods/pathfinding-a-star.ts +var MAX_MS_CALCULATION = 100; +var BASIC_DIRECTIONS = [ + { dx: 1, dy: 0 }, + { dx: -1, dy: 0 }, + { dx: 0, dy: 1 }, + { dx: 0, dy: -1 } +]; +var DIAGONAL_DIRECTIONS = [ + { dx: 1, dy: 1 }, + { dx: -1, dy: 1 }, + { dx: 1, dy: -1 }, + { dx: -1, dy: -1 } +]; +var DIAGONAL_COST = Math.sqrt(2); +var ROUND_PATH_RADIUS = 5; +var SMOOTHEN_PATH_TENSION = 0.2; +var Node = class { + constructor(x, y) { + this.x = x; + this.y = y; + this.gCost = 0; + this.hCost = 0; + this.fCost = 0; + this.parent = null; + } + // Only check for x and y, not gCost, hCost, fCost, or parent + inList(nodes) { + return nodes.some((n) => n.x === this.x && n.y === this.y); + } +}; +var EdgePathfindingAStar = class extends EdgePathfindingMethod { + getPath() { + const nodeBBoxes = [...this.canvas.nodes.values()].filter((node) => { + const nodeData = node.getData(); + if (nodeData.portal === true) return false; + const nodeBBox = node.getBBox(); + const nodeContainsFromPos = BBoxHelper.insideBBox(this.fromPos, nodeBBox, true); + const nodeContainsToPos = BBoxHelper.insideBBox(this.toPos, nodeBBox, true); + return !nodeContainsFromPos && !nodeContainsToPos; + }).map((node) => node.getBBox()); + const fromPosWithMargin = BBoxHelper.moveInDirection(this.fromPos, this.fromSide, 10); + const toPosWithMargin = BBoxHelper.moveInDirection(this.toPos, this.toSide, 10); + const allowDiagonal = this.plugin.settings.getSetting("edgeStylePathfinderAllowDiagonal"); + let pathArray = this.aStarAlgorithm(fromPosWithMargin, toPosWithMargin, nodeBBoxes, CanvasHelper.GRID_SIZE / 2, allowDiagonal); + if (!pathArray) return null; + pathArray.splice(0, 0, this.fromPos); + pathArray.splice(pathArray.length, 0, this.toPos); + let svgPath; + const roundPath = this.plugin.settings.getSetting("edgeStylePathfinderPathRounded"); + if (roundPath) { + if (allowDiagonal) + svgPath = SvgPathHelper.pathArrayToSvgPath(SvgPathHelper.smoothenPathArray(pathArray, SMOOTHEN_PATH_TENSION)); + else + svgPath = SvgPathHelper.pathArrayToRoundedSvgPath(pathArray, ROUND_PATH_RADIUS); + } else svgPath = SvgPathHelper.pathArrayToSvgPath(pathArray); + return { + svgPath, + center: pathArray[Math.floor(pathArray.length / 2)], + rotateArrows: false + }; + } + aStarAlgorithm(fromPos, toPos, obstacles, gridResolution, allowDiagonal) { + const start = new Node( + Math.floor(fromPos.x / gridResolution) * gridResolution, + Math.floor(fromPos.y / gridResolution) * gridResolution + ); + if (this.fromSide === "right" && fromPos.x !== start.x) start.x += gridResolution; + if (this.fromSide === "bottom" && fromPos.y !== start.y) start.y += gridResolution; + const end = new Node( + Math.floor(toPos.x / gridResolution) * gridResolution, + Math.floor(toPos.y / gridResolution) * gridResolution + ); + if (this.toSide === "right" && toPos.x !== end.x) end.x += gridResolution; + if (this.toSide === "bottom" && toPos.y !== end.y) end.y += gridResolution; + if (this.isInsideObstacle(start, obstacles) || this.isInsideObstacle(end, obstacles)) return null; + const openSet = [start]; + const closedSet = []; + const startTimestamp = performance.now(); + while (openSet.length > 0) { + let current = null; + let lowestFCost = Infinity; + for (const node of openSet) { + if (node.fCost < lowestFCost) { + current = node; + lowestFCost = node.fCost; + } + } + if (performance.now() - startTimestamp > MAX_MS_CALCULATION) + return null; + if (!current) + return null; + openSet.splice(openSet.indexOf(current), 1); + closedSet.push(current); + if (current.x === end.x && current.y === end.y) + return [fromPos, ...this.reconstructPath(current), toPos].map((node) => ({ x: node.x, y: node.y })); + if (!(current.x === start.x && current.y === start.y) && this.isTouchingObstacle(current, obstacles)) + continue; + for (const neighbor of this.getPossibleNeighbors(current, obstacles, gridResolution, allowDiagonal)) { + if (neighbor.inList(closedSet)) + continue; + const tentativeGCost = current.gCost + (allowDiagonal ? this.getMovementCost({ + dx: neighbor.x - current.x, + dy: neighbor.y - current.y + }) : 1); + if (!neighbor.inList(openSet) || tentativeGCost < neighbor.gCost) { + neighbor.parent = current; + neighbor.gCost = tentativeGCost; + neighbor.hCost = this.heuristic(neighbor, end); + neighbor.fCost = neighbor.gCost + neighbor.hCost; + openSet.push(neighbor); + } + } + } + return null; + } + // Manhattan distance + heuristic(node, end) { + return Math.abs(node.x - end.x) + Math.abs(node.y - end.y); + } + // Define a function to check if a position isn't inside any obstacle + isTouchingObstacle(node, obstacles) { + return obstacles.some((obstacle) => BBoxHelper.insideBBox(node, obstacle, true)); + } + isInsideObstacle(node, obstacles) { + return obstacles.some((obstacle) => BBoxHelper.insideBBox(node, obstacle, false)); + } + // Define a function to calculate movement cost based on direction + getMovementCost(direction) { + return direction.dx !== 0 && direction.dy !== 0 ? DIAGONAL_COST : 1; + } + getPossibleNeighbors(node, obstacles, gridResolution, allowDiagonal) { + const neighbors = []; + const availableDirections = allowDiagonal ? [...BASIC_DIRECTIONS, ...DIAGONAL_DIRECTIONS] : BASIC_DIRECTIONS; + for (const direction of availableDirections) { + const neighbor = new Node( + node.x + direction.dx * gridResolution, + node.y + direction.dy * gridResolution + ); + neighbor.gCost = node.gCost + this.getMovementCost(direction); + if (this.isInsideObstacle(neighbor, obstacles)) continue; + neighbors.push(neighbor); + } + return neighbors; + } + reconstructPath(node) { + const path = []; + while (node) { + path.push(node); + node = node.parent; + } + return path.reverse(); + } +}; + +// src/canvas-extensions/advanced-styles/edge-pathfinding-methods/pathfinding-direct.ts +var EdgePathfindingDirect = class extends EdgePathfindingMethod { + getPath() { + return { + svgPath: SvgPathHelper.pathArrayToSvgPath([this.fromPos, this.toPos]), + center: { + x: (this.fromPos.x + this.toPos.x) / 2, + y: (this.fromPos.y + this.toPos.y) / 2 + }, + rotateArrows: true + }; + } +}; + +// src/canvas-extensions/advanced-styles/edge-pathfinding-methods/pathfinding-square.ts +var ROUNDED_EDGE_RADIUS = 5; +var EdgePathfindingSquare = class extends EdgePathfindingMethod { + getPath() { + const pathArray = []; + let center = { + x: (this.fromPos.x + this.toPos.x) / 2, + y: (this.fromPos.y + this.toPos.y) / 2 + }; + const idealCenter = BBoxHelper.isHorizontal(this.fromSide) ? { + x: this.toBBoxSidePos.x, + y: this.fromBBoxSidePos.y + } : { + x: this.fromBBoxSidePos.x, + y: this.toBBoxSidePos.y + }; + const isPathCollidingAtFrom = this.fromSide === "top" && idealCenter.y > this.fromPos.y || this.fromSide === "bottom" && idealCenter.y < this.fromPos.y || this.fromSide === "left" && idealCenter.x > this.fromPos.x || this.fromSide === "right" && idealCenter.x < this.fromPos.x; + const isPathCollidingAtTo = this.toSide === "top" && idealCenter.y > this.toPos.y || this.toSide === "bottom" && idealCenter.y < this.toPos.y || this.toSide === "left" && idealCenter.x > this.toPos.x || this.toSide === "right" && idealCenter.x < this.toPos.x; + if (this.fromSide === this.toSide) { + const uPath = this.getUPath(this.fromPos, this.toPos, this.fromSide, this.toSide); + pathArray.push(...uPath.pathArray); + center = uPath.center; + } else if (BBoxHelper.isHorizontal(this.fromSide) === BBoxHelper.isHorizontal(this.toSide)) { + let zPath; + if (!isPathCollidingAtFrom || !isPathCollidingAtTo) { + zPath = this.getZPath(this.fromPos, this.toPos, this.fromSide, this.toSide); + pathArray.push(...zPath.pathArray); + } else { + const fromDirection = BBoxHelper.direction(this.fromSide); + const firstFromDetourPoint = BBoxHelper.isHorizontal(this.fromSide) ? { + x: CanvasHelper.alignToGrid(this.fromBBoxSidePos.x + fromDirection * CanvasHelper.GRID_SIZE), + y: this.fromBBoxSidePos.y + } : { + x: this.fromBBoxSidePos.x, + y: CanvasHelper.alignToGrid(this.fromBBoxSidePos.y + fromDirection * CanvasHelper.GRID_SIZE) + }; + const toDirection = BBoxHelper.direction(this.toSide); + const firstToDetourPoint = BBoxHelper.isHorizontal(this.toSide) ? { + x: CanvasHelper.alignToGrid(this.toBBoxSidePos.x + toDirection * CanvasHelper.GRID_SIZE), + y: this.toBBoxSidePos.y + } : { + x: this.toBBoxSidePos.x, + y: CanvasHelper.alignToGrid(this.toBBoxSidePos.y + toDirection * CanvasHelper.GRID_SIZE) + }; + const newFromSide = BBoxHelper.isHorizontal(this.fromSide) ? firstFromDetourPoint.y < this.fromPos.y ? "top" : "bottom" : firstFromDetourPoint.x < firstToDetourPoint.x ? "right" : "left"; + zPath = this.getZPath(firstFromDetourPoint, firstToDetourPoint, newFromSide, BBoxHelper.getOppositeSide(newFromSide)); + pathArray.push(this.fromPos); + pathArray.push(...zPath.pathArray); + pathArray.push(this.toPos); + } + center = zPath.center; + } else { + if (isPathCollidingAtFrom || isPathCollidingAtTo) { + if (isPathCollidingAtFrom && isPathCollidingAtTo) { + const direction = BBoxHelper.direction(this.fromSide); + let firstFromDetourPoint; + let secondFromDetourPoint; + if (BBoxHelper.isHorizontal(this.fromSide)) { + const combinedBBoxes = BBoxHelper.combineBBoxes([this.fromNodeBBox, this.toNodeBBox]); + firstFromDetourPoint = { + x: CanvasHelper.alignToGrid((direction > 0 ? combinedBBoxes.maxX : combinedBBoxes.minX) + direction * CanvasHelper.GRID_SIZE), + y: this.fromBBoxSidePos.y + }; + secondFromDetourPoint = { + x: firstFromDetourPoint.x, + y: BBoxHelper.getCenterOfBBoxSide(this.fromNodeBBox, this.toSide).y + }; + } else { + const combinedBBoxes = BBoxHelper.combineBBoxes([this.fromNodeBBox, this.toNodeBBox]); + firstFromDetourPoint = { + x: this.fromBBoxSidePos.x, + y: CanvasHelper.alignToGrid((direction > 0 ? combinedBBoxes.maxY : combinedBBoxes.minY) + direction * CanvasHelper.GRID_SIZE) + }; + secondFromDetourPoint = { + x: BBoxHelper.getCenterOfBBoxSide(this.fromNodeBBox, this.toSide).x, + y: firstFromDetourPoint.y + }; + } + const uPath = this.getUPath(secondFromDetourPoint, this.toPos, this.toSide, this.toSide); + pathArray.push(this.fromPos); + pathArray.push(firstFromDetourPoint); + pathArray.push(...uPath.pathArray); + center = pathArray[Math.floor(pathArray.length / 2)]; + } else { + if (isPathCollidingAtFrom) { + const direction = BBoxHelper.direction(this.fromSide); + const firstFromDetourPoint = BBoxHelper.isHorizontal(this.fromSide) ? { + x: CanvasHelper.alignToGrid(this.fromBBoxSidePos.x + direction * CanvasHelper.GRID_SIZE), + y: this.fromBBoxSidePos.y + } : { + x: this.fromBBoxSidePos.x, + y: CanvasHelper.alignToGrid(this.fromBBoxSidePos.y + direction * CanvasHelper.GRID_SIZE) + }; + const useUPath = BBoxHelper.isHorizontal(this.fromSide) ? this.toPos.y > BBoxHelper.getCenterOfBBoxSide(this.fromNodeBBox, BBoxHelper.getOppositeSide(this.toSide)).y === BBoxHelper.direction(this.toSide) > 0 : this.toPos.x > BBoxHelper.getCenterOfBBoxSide(this.fromNodeBBox, BBoxHelper.getOppositeSide(this.toSide)).x === BBoxHelper.direction(this.toSide) > 0; + const connectionSide = useUPath ? this.toSide : BBoxHelper.getOppositeSide(this.toSide); + const secondFromDetourPoint = BBoxHelper.isHorizontal(this.fromSide) ? { + x: firstFromDetourPoint.x, + y: BBoxHelper.getCenterOfBBoxSide(this.fromNodeBBox, connectionSide).y + } : { + x: BBoxHelper.getCenterOfBBoxSide(this.fromNodeBBox, connectionSide).x, + y: firstFromDetourPoint.y + }; + const path = useUPath ? this.getUPath(secondFromDetourPoint, this.toPos, this.toSide, this.toSide) : this.getZPath(secondFromDetourPoint, this.toPos, this.toSide, this.toSide); + pathArray.push(this.fromPos); + pathArray.push(firstFromDetourPoint); + pathArray.push(...path.pathArray); + center = path.center; + } + if (isPathCollidingAtTo) { + const direction = BBoxHelper.direction(this.toSide); + const firstToDetourPoint = BBoxHelper.isHorizontal(this.toSide) ? { + x: CanvasHelper.alignToGrid(this.toBBoxSidePos.x + direction * CanvasHelper.GRID_SIZE), + y: this.toBBoxSidePos.y + } : { + x: this.toBBoxSidePos.x, + y: CanvasHelper.alignToGrid(this.toBBoxSidePos.y + direction * CanvasHelper.GRID_SIZE) + }; + const useUPath = BBoxHelper.isHorizontal(this.toSide) ? this.fromPos.y > BBoxHelper.getCenterOfBBoxSide(this.toNodeBBox, BBoxHelper.getOppositeSide(this.fromSide)).y === BBoxHelper.direction(this.fromSide) > 0 : this.fromPos.x > BBoxHelper.getCenterOfBBoxSide(this.toNodeBBox, BBoxHelper.getOppositeSide(this.fromSide)).x === BBoxHelper.direction(this.fromSide) > 0; + const connectionSide = useUPath ? this.fromSide : BBoxHelper.getOppositeSide(this.fromSide); + const secondToDetourPoint = BBoxHelper.isHorizontal(this.toSide) ? { + x: firstToDetourPoint.x, + y: BBoxHelper.getCenterOfBBoxSide(this.toNodeBBox, connectionSide).y + } : { + x: BBoxHelper.getCenterOfBBoxSide(this.toNodeBBox, connectionSide).x, + y: firstToDetourPoint.y + }; + const path = useUPath ? this.getUPath(this.fromPos, secondToDetourPoint, this.fromSide, this.fromSide) : this.getZPath(this.fromPos, secondToDetourPoint, this.fromSide, this.fromSide); + pathArray.push(...path.pathArray); + pathArray.push(secondToDetourPoint); + pathArray.push(firstToDetourPoint); + pathArray.push(this.toPos); + center = path.center; + } + } + } else { + pathArray.push( + this.fromPos, + idealCenter, + this.toPos + ); + center = { + x: pathArray[1].x, + y: pathArray[1].y + }; + } + } + const svgPath = this.plugin.settings.getSetting("edgeStyleSquarePathRounded") ? SvgPathHelper.pathArrayToRoundedSvgPath(pathArray, ROUNDED_EDGE_RADIUS) : SvgPathHelper.pathArrayToSvgPath(pathArray); + return { svgPath, center, rotateArrows: false }; + } + getUPath(fromPos, toPos, fromSide, toSide) { + const direction = BBoxHelper.direction(fromSide); + if (BBoxHelper.isHorizontal(fromSide)) { + const xExtremum = direction > 0 ? Math.max(fromPos.x, toPos.x) : Math.min(fromPos.x, toPos.x); + const x = CanvasHelper.alignToGrid(xExtremum + direction * CanvasHelper.GRID_SIZE); + return { + pathArray: [ + fromPos, + { x, y: fromPos.y }, + { x, y: toPos.y }, + toPos + ], + center: { + x, + y: (fromPos.y + toPos.y) / 2 + } + }; + } else { + const yExtremum = direction > 0 ? Math.max(fromPos.y, toPos.y) : Math.min(fromPos.y, toPos.y); + const y = CanvasHelper.alignToGrid(yExtremum + direction * CanvasHelper.GRID_SIZE); + return { + pathArray: [ + fromPos, + { x: fromPos.x, y }, + { x: toPos.x, y }, + toPos + ], + center: { + x: (fromPos.x + toPos.x) / 2, + y + } + }; + } + } + getZPath(fromPos, toPos, fromSide, toSide) { + if (BBoxHelper.isHorizontal(fromSide)) { + const midX = fromPos.x + (toPos.x - fromPos.x) / 2; + return { + pathArray: [ + fromPos, + { x: midX, y: fromPos.y }, + { x: midX, y: toPos.y }, + toPos + ], + center: { + x: midX, + y: (fromPos.y + toPos.y) / 2 + } + }; + } else { + const midY = fromPos.y + (toPos.y - fromPos.y) / 2; + return { + pathArray: [ + fromPos, + { x: fromPos.x, y: midY }, + { x: toPos.x, y: midY }, + toPos + ], + center: { + x: (fromPos.x + toPos.x) / 2, + y: midY + } + }; + } + } +}; + +// src/utils/text-helper.ts +var TextHelper = class { + static toCamelCase(str) { + return str.replace(/-./g, (x) => x[1].toUpperCase()); + } + static toTitleCase(str) { + return str.toLowerCase().split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" "); + } +}; + +// src/canvas-extensions/advanced-styles/style-config.ts +function styleAttributeValidator(json) { + var _a; + const hasKey = json.key !== void 0; + const hasLabel = json.label !== void 0; + const hasOptions = Array.isArray(json.options); + if (!hasKey) console.error('Style attribute is missing the "key" property'); + if (!hasLabel) console.error('Style attribute is missing the "label" property'); + if (!hasOptions) console.error('Style attribute is missing the "options" property or it is not an array'); + json.key = TextHelper.toCamelCase(json.key); + let optionsValid = true; + let hasDefault = false; + for (const option of json.options) { + const hasIcon = option.icon !== void 0; + const hasLabel2 = option.label !== void 0; + const hasValue = option.value !== void 0; + if (!hasIcon) console.error(`Style attribute option (${(_a = option.value) != null ? _a : option.label}) is missing the "icon" property`); + if (!hasLabel2) console.error(`Style attribute option (${option.value}) is missing the "label" property`); + if (!hasValue) console.error(`Style attribute option (${option.label}) is missing the "value" property`); + if (!hasIcon || !hasLabel2 || !hasValue) optionsValid = false; + if (option.value === null) hasDefault = true; + } + if (!hasDefault) console.error('Style attribute is missing a default option (option with a "value" of null)'); + const isValid = hasKey && hasLabel && hasOptions && optionsValid && hasDefault; + return isValid ? json : null; +} +var BUILTIN_NODE_STYLE_ATTRIBUTES = [ + { + key: "textAlign", + label: "Text Alignment", + nodeTypes: ["text"], + options: [ + { + icon: "align-left", + label: "Left", + value: null + }, + { + icon: "align-center", + label: "Center", + value: "center" + }, + { + icon: "align-right", + label: "Right", + value: "right" + } + ] + }, + { + key: "shape", + label: "Shape", + nodeTypes: ["text"], + options: [ + { + icon: "rectangle-horizontal", + label: "Round Rectangle", + value: null + }, + { + icon: "shape-pill", + label: "Pill", + value: "pill" + }, + { + icon: "diamond", + label: "Diamond", + value: "diamond" + }, + { + icon: "shape-parallelogram", + label: "Parallelogram", + value: "parallelogram" + }, + { + icon: "circle", + label: "Circle", + value: "circle" + }, + { + icon: "shape-predefined-process", + label: "Predefined Process", + value: "predefined-process" + }, + { + icon: "shape-document", + label: "Document", + value: "document" + }, + { + icon: "shape-database", + label: "Database", + value: "database" + } + ] + }, + { + key: "border", + label: "Border", + options: [ + { + icon: "border-solid", + label: "Solid", + value: null + }, + { + icon: "border-dashed", + label: "Dashed", + value: "dashed" + }, + { + icon: "border-dotted", + label: "Dotted", + value: "dotted" + }, + { + icon: "eye-off", + label: "Invisible", + value: "invisible" + } + ] + } +]; +var BUILTIN_EDGE_STYLE_ATTRIBUTES = [ + { + key: "path", + label: "Path Style", + options: [ + { + icon: "path-solid", + label: "Solid", + value: null + }, + { + icon: "path-dotted", + label: "Dotted", + value: "dotted" + }, + { + icon: "path-short-dashed", + label: "Short Dashed", + value: "short-dashed" + }, + { + icon: "path-long-dashed", + label: "Long Dashed", + value: "long-dashed" + } + ] + }, + { + key: "arrow", + label: "Arrow Style", + options: [ + { + icon: "arrow-triangle", + label: "Triangle", + value: null + }, + { + icon: "arrow-triangle-outline", + label: "Triangle Outline", + value: "triangle-outline" + }, + { + icon: "arrow-thin-triangle", + label: "Thin Triangle", + value: "thin-triangle" + }, + { + icon: "arrow-halved-triangle", + label: "Halved Triangle", + value: "halved-triangle" + }, + { + icon: "arrow-diamond", + label: "Diamond", + value: "diamond" + }, + { + icon: "arrow-diamond-outline", + label: "Diamond Outline", + value: "diamond-outline" + }, + { + icon: "arrow-circle", + label: "Circle", + value: "circle" + }, + { + icon: "arrow-circle-outline", + label: "Circle Outline", + value: "circle-outline" + }, + { + icon: "tally-1", + label: "Blunt", + value: "blunt" + } + ] + }, + { + key: "pathfindingMethod", + label: "Pathfinding Method", + options: [ + { + icon: "pathfinding-method-bezier", + label: "Bezier", + value: null + }, + { + icon: "slash", + label: "Direct", + value: "direct" + }, + { + icon: "pathfinding-method-square", + label: "Square", + value: "square" + }, + { + icon: "map", + label: "A*", + value: "a-star" + } + ] + } +]; + +// src/managers/css-styles-config-manager.ts +var import_obsidian3 = require("obsidian"); +var CssStylesConfigManager = class { + constructor(plugin, trigger, validate) { + this.plugin = plugin; + this.validate = validate; + this.cachedConfig = null; + this.configRegex = new RegExp(`\\/\\*\\s*@${trigger}\\s*\\n([\\s\\S]*?)\\*\\/`, "g"); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "css-change", + () => { + this.cachedConfig = null; + } + )); + } + getStyles() { + if (this.cachedConfig) return this.cachedConfig; + this.cachedConfig = []; + const styleSheets = document.styleSheets; + for (let i = 0; i < styleSheets.length; i++) { + const sheet = styleSheets.item(i); + if (!sheet) continue; + const styleSheetConfigs = this.parseStyleConfigsFromCSS(sheet); + for (const config of styleSheetConfigs) { + const validConfig = this.validate(config); + if (!validConfig) continue; + this.cachedConfig.push(validConfig); + } + } + return this.cachedConfig; + } + parseStyleConfigsFromCSS(sheet) { + var _a, _b; + const textContent = (_b = (_a = sheet == null ? void 0 : sheet.ownerNode) == null ? void 0 : _a.textContent) == null ? void 0 : _b.trim(); + if (!textContent) return []; + const configs = []; + const matches = textContent.matchAll(this.configRegex); + for (const match of matches) { + const yamlString = match[1]; + const configYaml = (0, import_obsidian3.parseYaml)(yamlString); + configs.push(configYaml); + } + return configs; + } +}; + +// src/canvas-extensions/advanced-styles/edge-styles.ts +var GET_EDGE_CSS_STYLES_MANAGER = (plugin) => new CssStylesConfigManager(plugin, "advanced-canvas-edge-style", styleAttributeValidator); +var EDGE_PATHFINDING_METHODS = { + "direct": EdgePathfindingDirect, + "square": EdgePathfindingSquare, + "a-star": EdgePathfindingAStar +}; +var MAX_LIVE_UPDATE_SELECTION_SIZE = 5; +var EdgeStylesExtension = class extends CanvasExtension { + isEnabled() { + return "edgesStylingFeatureEnabled"; + } + init() { + this.cssStylesManager = GET_EDGE_CSS_STYLES_MANAGER(this.plugin); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:popup-menu-created", + (canvas) => this.onPopupMenuCreated(canvas) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:edge-changed", + (canvas, edge) => this.onEdgeChanged(canvas, edge) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:edge-center-requested", + (canvas, edge, center) => this.onEdgeCenterRequested(canvas, edge, center) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-added", + (canvas, node) => { + if (canvas.dirty.size > 1 && !canvas.isPasting) return; + this.updateAllEdgesInArea(canvas, node.getBBox()); + } + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-moved", + // Only update edges this way if a node got moved with the arrow keys + (canvas, node, keyboard) => node.initialized && keyboard ? this.updateAllEdgesInArea(canvas, node.getBBox()) : void 0 + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-removed", + (canvas, node) => this.updateAllEdgesInArea(canvas, node.getBBox()) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:dragging-state-changed", + (canvas, isDragging) => { + if (isDragging) return; + const selectedNodes = canvas.getSelectionData().nodes.map((nodeData) => canvas.nodes.get(nodeData.id)).filter((node) => node !== void 0); + const selectedNodeBBoxes = selectedNodes.map((node) => node.getBBox()); + const selectedNodeBBox = BBoxHelper.combineBBoxes(selectedNodeBBoxes); + this.updateAllEdgesInArea(canvas, selectedNodeBBox); + } + )); + } + // Skip if isDragging and setting isn't enabled and not connecting an edge + shouldUpdateEdge(canvas) { + return !canvas.isDragging || this.plugin.settings.getSetting("edgeStyleUpdateWhileDragging") || canvas.canvasEl.hasClass("is-connecting"); + } + onPopupMenuCreated(canvas) { + var _a; + const selectedEdges = [...canvas.selection].filter((item) => item.path !== void 0); + if (canvas.readonly || selectedEdges.length === 0 || selectedEdges.length !== canvas.selection.size) + return; + CanvasHelper.addStyleAttributesToPopup( + this.plugin, + canvas, + [ + ...BUILTIN_EDGE_STYLE_ATTRIBUTES, + /* Legacy */ + ...this.plugin.settings.getSetting("customEdgeStyleAttributes"), + ...this.cssStylesManager.getStyles() + ], + (_a = selectedEdges[0].getData().styleAttributes) != null ? _a : {}, + (attribute, value) => this.setStyleAttributeForSelection(canvas, attribute, value) + ); + } + setStyleAttributeForSelection(canvas, attribute, value) { + const selectedEdges = [...canvas.selection].filter((item) => item.path !== void 0); + for (const edge of selectedEdges) { + const edgeData = edge.getData(); + edge.setData({ + ...edgeData, + styleAttributes: { + ...edgeData.styleAttributes, + [attribute.key]: value + } + }); + } + canvas.pushHistory(canvas.getData()); + } + updateAllEdgesInArea(canvas, bbox) { + if (!this.shouldUpdateEdge(canvas)) return; + for (const edge of canvas.edges.values()) { + if (!BBoxHelper.isColliding(edge.getBBox(), bbox)) continue; + canvas.markDirty(edge); + } + } + onEdgeChanged(canvas, edge) { + var _a, _b, _c, _d, _e, _f, _g; + if (!canvas.dirty.has(edge) && !canvas.selection.has(edge)) return; + if (!this.shouldUpdateEdge(canvas)) { + const tooManySelected = canvas.selection.size > MAX_LIVE_UPDATE_SELECTION_SIZE; + if (tooManySelected) return; + const groupNodesSelected = [...canvas.selection].some((item) => { + var _a2; + return ((_a2 = item.getData()) == null ? void 0 : _a2.type) === "group"; + }); + if (groupNodesSelected) return; + } + const edgeData = edge.getData(); + if (!edge.bezier) return; + edge.center = void 0; + edge.updatePath(); + const pathfindingMethod = (_a = edgeData.styleAttributes) == null ? void 0 : _a.pathfindingMethod; + if (pathfindingMethod && pathfindingMethod in EDGE_PATHFINDING_METHODS) { + const fromNodeBBox = edge.from.node.getBBox(); + const fromBBoxSidePos = BBoxHelper.getCenterOfBBoxSide(fromNodeBBox, edge.from.side); + const fromPos = edge.from.end === "none" ? fromBBoxSidePos : edge.bezier.from; + const toNodeBBox = edge.to.node.getBBox(); + const toBBoxSidePos = BBoxHelper.getCenterOfBBoxSide(toNodeBBox, edge.to.side); + const toPos = edge.to.end === "none" ? toBBoxSidePos : edge.bezier.to; + const path = new EDGE_PATHFINDING_METHODS[pathfindingMethod]( + this.plugin, + canvas, + fromNodeBBox, + fromPos, + fromBBoxSidePos, + edge.from.side, + toNodeBBox, + toPos, + toBBoxSidePos, + edge.to.side + ).getPath(); + if (!path) return; + edge.center = path.center; + edge.path.interaction.setAttr("d", path == null ? void 0 : path.svgPath); + edge.path.display.setAttr("d", path == null ? void 0 : path.svgPath); + } + (_b = edge.labelElement) == null ? void 0 : _b.render(); + const arrowPolygonPoints = this.getArrowPolygonPoints((_c = edgeData.styleAttributes) == null ? void 0 : _c.arrow); + if ((_d = edge.fromLineEnd) == null ? void 0 : _d.el) (_e = edge.fromLineEnd.el.querySelector("polygon")) == null ? void 0 : _e.setAttribute("points", arrowPolygonPoints); + if ((_f = edge.toLineEnd) == null ? void 0 : _f.el) (_g = edge.toLineEnd.el.querySelector("polygon")) == null ? void 0 : _g.setAttribute("points", arrowPolygonPoints); + } + onEdgeCenterRequested(_canvas, edge, center) { + var _a, _b, _c, _d; + center.x = (_b = (_a = edge.center) == null ? void 0 : _a.x) != null ? _b : center.x; + center.y = (_d = (_c = edge.center) == null ? void 0 : _c.y) != null ? _d : center.y; + } + getArrowPolygonPoints(arrowStyle) { + if (arrowStyle === "halved-triangle") + return `-2,0 7.5,12 -2,12`; + else if (arrowStyle === "thin-triangle") + return `0,0 7,10 0,0 0,10 0,0 -7,10`; + else if (arrowStyle === "diamond" || arrowStyle === "diamond-outline") + return `0,0 5,10 0,20 -5,10`; + else if (arrowStyle === "circle" || arrowStyle === "circle-outline") + return `0 0, 4.95 1.8, 7.5 6.45, 6.6 11.7, 2.7 15, -2.7 15, -6.6 11.7, -7.5 6.45, -4.95 1.8`; + else if (arrowStyle === "blunt") + return `-10,8 10,8 10,6 -10,6`; + else + return `0,0 6.5,10.4 -6.5,10.4`; + } +}; + +// src/canvas-extensions/advanced-styles/node-styles.ts +var GET_NODE_CSS_STYLES_MANAGER = (plugin) => new CssStylesConfigManager(plugin, "advanced-canvas-node-style", styleAttributeValidator); +var NodeStylesExtension = class extends CanvasExtension { + isEnabled() { + return "nodeStylingFeatureEnabled"; + } + init() { + this.cssStylesManager = GET_NODE_CSS_STYLES_MANAGER(this.plugin); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:popup-menu-created", + (canvas) => this.onPopupMenuCreated(canvas) + )); + } + onPopupMenuCreated(canvas) { + var _a; + const selectionNodeData = canvas.getSelectionData().nodes; + if (canvas.readonly || selectionNodeData.length === 0 || selectionNodeData.length !== canvas.selection.size) + return; + const selectedNodeTypes = new Set(selectionNodeData.map((node) => node.type)); + const availableNodeStyles = [ + ...BUILTIN_NODE_STYLE_ATTRIBUTES, + /* Legacy */ + ...this.plugin.settings.getSetting("customNodeStyleAttributes"), + ...this.cssStylesManager.getStyles() + ].filter((style) => !style.nodeTypes || style.nodeTypes.some((type) => selectedNodeTypes.has(type))); + CanvasHelper.addStyleAttributesToPopup( + this.plugin, + canvas, + availableNodeStyles, + (_a = selectionNodeData[0].styleAttributes) != null ? _a : {}, + (attribute, value) => this.setStyleAttributeForSelection(canvas, attribute, value) + ); + } + setStyleAttributeForSelection(canvas, attribute, value) { + const selectionNodeData = canvas.getSelectionData().nodes; + for (const nodeData of selectionNodeData) { + const node = canvas.nodes.get(nodeData.id); + if (!node) continue; + if (attribute.nodeTypes && !attribute.nodeTypes.includes(nodeData.type)) continue; + node.setData({ + ...nodeData, + styleAttributes: { + ...nodeData.styleAttributes, + [attribute.key]: value + } + }); + } + canvas.pushHistory(canvas.getData()); + } +}; + +// src/canvas-extensions/variable-breakpoint-canvas-extension.ts +var VARIABLE_BREAKPOINT_CSS_VAR = "--variable-breakpoint"; +var VariableBreakpointCanvasExtension = class extends CanvasExtension { + isEnabled() { + return "variableBreakpointFeatureEnabled"; + } + init() { + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-breakpoint-changed", + (canvas, node, breakpointRef) => this.onNodeBreakpointChanged(canvas, node, breakpointRef) + )); + } + onNodeBreakpointChanged(canvas, node, breakpointRef) { + if (!node.initialized) return; + if (node.breakpoint === void 0) { + const computedStyle = window.getComputedStyle(node.nodeEl); + const variableBreakpointString = computedStyle.getPropertyValue(VARIABLE_BREAKPOINT_CSS_VAR); + let numberBreakpoint; + if (variableBreakpointString.length > 0 && !isNaN(numberBreakpoint = parseFloat(variableBreakpointString))) + node.breakpoint = numberBreakpoint; + else node.breakpoint = null; + } + if (node.breakpoint === null) return; + breakpointRef.value = canvas.zoom > node.breakpoint; + } +}; + +// src/settings.ts +var README_URL = "https://github.com/Developer-Mike/obsidian-advanced-canvas?tab=readme-ov-file"; +var SPENT_HOURS = 200; +var RECEIVED_DONATIONS = 357; +var HOURLY_RATE_GOAL = 20; +var KOFI_PAGE_URL = "https://ko-fi.com/X8X27IA08"; +var KOFI_BADGE_URI = "data:image/webp;base64,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"; +var DEFAULT_SETTINGS_VALUES = { + nodeTypeOnDoubleClick: "text", + alignNewNodesToGrid: true, + defaultTextNodeDimensions: [260, 60], + defaultFileNodeDimensions: [400, 400], + minNodeSize: 60, + maxNodeWidth: -1, + disableFontSizeRelativeToZoom: false, + canvasMetadataCompatibilityEnabled: true, + treatFileNodeEdgesAsLinks: true, + enableSingleNodeLinks: true, + combineCustomStylesInDropdown: false, + nodeStylingFeatureEnabled: true, + customNodeStyleAttributes: [], + defaultTextNodeColor: 0, + defaultTextNodeStyleAttributes: {}, + edgesStylingFeatureEnabled: true, + customEdgeStyleAttributes: [], + inheritEdgeColorFromNode: false, + defaultEdgeColor: 0, + defaultEdgeLineDirection: "unidirectional", + defaultEdgeStyleAttributes: {}, + edgeStyleUpdateWhileDragging: false, + edgeStyleSquarePathRounded: true, + edgeStylePathfinderAllowDiagonal: false, + edgeStylePathfinderPathRounded: true, + variableBreakpointFeatureEnabled: false, + zOrderingControlFeatureEnabled: false, + zOrderingControlShowOneLayerShiftOptions: false, + aspectRatioControlFeatureEnabled: false, + commandsFeatureEnabled: true, + zoomToClonedNode: true, + cloneNodeMargin: 20, + expandNodeStepSize: 20, + nativeFileSearchEnabled: true, + floatingEdgeFeatureEnabled: true, + allowFloatingEdgeCreation: false, + newEdgeFromSideFloating: false, + flipEdgeFeatureEnabled: true, + betterExportFeatureEnabled: true, + betterReadonlyEnabled: false, + hideBackgroundGridWhenInReadonly: true, + disableNodePopup: false, + disableZoom: false, + disablePan: false, + autoResizeNodeFeatureEnabled: false, + autoResizeNodeEnabledByDefault: false, + autoResizeNodeMaxHeight: -1, + autoResizeNodeSnapToGrid: true, + collapsibleGroupsFeatureEnabled: true, + collapsedGroupPreviewOnDrag: true, + focusModeFeatureEnabled: false, + presentationFeatureEnabled: true, + showSetStartNodeInPopup: false, + defaultSlideDimensions: [1200, 675], + wrapInSlidePadding: 20, + resetViewportOnPresentationEnd: true, + useArrowKeysToChangeSlides: true, + usePgUpPgDownKeysToChangeSlides: true, + zoomToSlideWithoutPadding: true, + useUnclampedZoomWhilePresenting: false, + fullscreenPresentationEnabled: true, + slideTransitionAnimationDuration: 0.5, + slideTransitionAnimationIntensity: 1.25, + canvasEncapsulationEnabled: false, + portalsFeatureEnabled: true, + showEdgesIntoDisabledPortals: true, + autoFileNodeEdgesFeatureEnabled: false, + autoFileNodeEdgesFrontmatterKey: "canvas-edges", + edgeHighlightEnabled: false, + highlightIncomingEdges: false, + edgeSelectionEnabled: false, + selectEdgeByDirection: false +}; +var SETTINGS = { + // @ts-ignore + general: { + label: "General", + description: "General settings of the Advanced Canvas plugin.", + disableToggle: true, + children: { + nodeTypeOnDoubleClick: { + label: "Node type on double click", + description: "The type of node that will be created when double clicking on the canvas.", + type: "dropdown", + options: { + "text": "Text", + "file": "File" + } + }, + alignNewNodesToGrid: { + label: "Always align new nodes to grid", + description: "When enabled, new nodes will be aligned to the grid.", + type: "boolean" + }, + defaultTextNodeDimensions: { + label: "Default text node dimensions", + description: "The default dimensions of a text node.", + type: "dimension", + parse: (value) => { + const width = Math.max(1, parseInt(value[0]) || 0); + const height = Math.max(1, parseInt(value[1]) || 0); + return [width, height]; + } + }, + defaultFileNodeDimensions: { + label: "Default file node dimensions", + description: "The default dimensions of a file node.", + type: "dimension", + parse: (value) => { + const width = Math.max(1, parseInt(value[0]) || 0); + const height = Math.max(1, parseInt(value[1]) || 0); + return [width, height]; + } + }, + minNodeSize: { + label: "Minimum node size", + description: "The minimum size (either width or height) of a node.", + type: "number", + parse: (value) => Math.max(1, parseInt(value) || 0) + }, + maxNodeWidth: { + label: "Maximum node width", + description: "The maximum width of a node. Set to -1 for no limit.", + type: "number", + parse: (value) => Math.max(-1, parseInt(value) || 0) + }, + disableFontSizeRelativeToZoom: { + label: "Disable font size relative to zoom", + description: "When enabled, the font size of e.g. group node titles and edge labels will not increase when zooming out.", + type: "boolean" + } + } + }, + commandsFeatureEnabled: { + label: "Extended commands", + description: "Add more commands to the canvas.", + infoSection: "canvas-commands", + children: { + zoomToClonedNode: { + label: "Zoom to cloned node", + description: "When enabled, the canvas will zoom to the cloned node.", + type: "boolean" + }, + cloneNodeMargin: { + label: "Clone node margin", + description: "The margin between the cloned node and the source node.", + type: "number", + parse: (value) => Math.max(0, parseInt(value) || 0) + }, + expandNodeStepSize: { + label: "Expand node step size", + description: "The step size for expanding the node.", + type: "number", + parse: (value) => Math.max(1, parseInt(value) || 0) + } + } + }, + canvasMetadataCompatibilityEnabled: { + label: "Enable .canvas metadata cache compatibility", + description: "Make .canvas files compatible with the backlinks and outgoing links feature and show the connections in the graph view.", + infoSection: "full-metadata-cache-support", + children: { + treatFileNodeEdgesAsLinks: { + label: "Treat edges between file nodes as links", + description: "When enabled, edges between file nodes will be treated as links. This means that if file node A.md has an edge to file node B.md in the canvas, file A.md will have a link to file B.md in the outgoing links section and show a connection in the graph view.", + type: "boolean" + }, + enableSingleNodeLinks: { + label: "Enable support for linking to a node using a [[wikilink]]", + description: "When enabled, you can link and embed a node using [[canvas-file#node-id]].", + type: "boolean" + } + } + }, + nativeFileSearchEnabled: { + label: "Native-like file search", + description: "When enabled, the file search will be done using the native Obsidian file search.", + infoSection: "native-like-file-search", + children: {} + }, + autoFileNodeEdgesFeatureEnabled: { + label: "Auto file node edges", + description: "Automatically create edges between file nodes based their frontmatter links.", + infoSection: "auto-file-node-edges", + children: { + autoFileNodeEdgesFrontmatterKey: { + label: "Frontmatter key name", + description: "The frontmatter key to fetch the outgoing edges from. (Keep the default to ensure best compatibility.)", + type: "text", + parse: (value) => value.trim() || "canvas-edges" + } + } + }, + portalsFeatureEnabled: { + label: "Portals", + description: "Create portals to other canvases.", + infoSection: "portals", + children: { + showEdgesIntoDisabledPortals: { + label: "Show edges into disabled portals", + description: "When enabled, edges into disabled portals will be shown.", + type: "boolean" + } + } + }, + collapsibleGroupsFeatureEnabled: { + label: "Collapsible groups", + description: "Group nodes can be collapsed and expanded to keep the canvas organized.", + infoSection: "collapsible-groups", + children: { + collapsedGroupPreviewOnDrag: { + label: "Collapsed group preview on drag", + description: "When enabled, a group that is collapsed show its border while dragging a node.", + type: "boolean" + } + } + }, + combineCustomStylesInDropdown: { + label: "Combine custom styles", + description: "Combine all style attributes of Advanced Canvas in a single dropdown.", + children: {} + }, + nodeStylingFeatureEnabled: { + label: "Node styling", + description: "Style your nodes with different shapes and borders.", + infoSection: "node-styles", + children: { + customNodeStyleAttributes: { + label: "Custom node style settings", + description: "Add custom style settings for nodes. (Go to GitHub for more information)", + type: "button", + onClick: () => window.open("https://github.com/Developer-Mike/obsidian-advanced-canvas/blob/main/README.md#custom-styles") + }, + defaultTextNodeColor: { + label: "Default text node color", + description: "The default color of a text node. The default range is from 0 to 6, where 0 is no color. The range can be extended by using the Custom Colors feature of Advanced Canvas.", + type: "number", + parse: (value) => Math.max(0, parseInt(value) || 0) + }, + defaultTextNodeStyleAttributes: { + label: "Default text node style attributes", + type: "styles", + getParameters(settingsManager) { + return [ + ...BUILTIN_NODE_STYLE_ATTRIBUTES, + /* BUILTINS */ + ...settingsManager.nodeCssStylesManager.getStyles(), + /* CUSTOM CSS STYLES */ + ...settingsManager.getSetting("customNodeStyleAttributes") + /* LEGACY CUSTOM STYLES */ + ].filter((setting) => { + var _a; + return setting.nodeTypes === void 0 || ((_a = setting.nodeTypes) == null ? void 0 : _a.includes("text")); + }); + } + } + } + }, + edgesStylingFeatureEnabled: { + label: "Edges styling", + description: "Style your edges with different path styles.", + infoSection: "edge-styles", + children: { + customEdgeStyleAttributes: { + label: "Custom edge style settings", + description: "Add custom style settings for edges. (Go to GitHub for more information)", + type: "button", + onClick: () => window.open("https://github.com/Developer-Mike/obsidian-advanced-canvas/blob/main/README.md#custom-styles") + }, + inheritEdgeColorFromNode: { + label: "Inherit edge color from node", + description: "When creating a new edge by dragging from a node, the edge will inherit the color of the node it is dragged from.", + type: "boolean" + }, + defaultEdgeColor: { + label: "Default edge color", + description: "The default color of an edge. The default range is from 0 to 6, where 0 is no color. The range can be extended by using the Custom Colors feature of Advanced Canvas.", + type: "number", + parse: (value) => Math.max(0, parseInt(value) || 0) + }, + defaultEdgeLineDirection: { + label: "Default edge line direction", + description: "The default line direction of an edge.", + type: "dropdown", + options: { + "nondirectional": "Nondirectional", + "unidirectional": "Unidirectional", + "bidirectional": "Bidirectional" + } + }, + defaultEdgeStyleAttributes: { + label: "Default edge style attributes", + type: "styles", + getParameters(settingsManager) { + return [ + ...BUILTIN_EDGE_STYLE_ATTRIBUTES, + /* BUILTINS */ + ...settingsManager.edgeCssStylesManager.getStyles(), + /* CUSTOM CSS STYLES */ + ...settingsManager.getSetting("customEdgeStyleAttributes") + /* LEGACY CUSTOM STYLES */ + ]; + } + }, + edgeStyleUpdateWhileDragging: { + label: "Update edge style while dragging (Can be very slow)", + description: "When enabled, the edge style will be updated while dragging an edge.", + type: "boolean" + }, + edgeStyleSquarePathRounded: { + label: "Square path rounded", + description: "When enabled, the square path's corners will be rounded.", + type: "boolean" + }, + edgeStylePathfinderAllowDiagonal: { + label: "A* allow diagonal", + description: "When enabled, the A* path style will allow diagonal paths.", + type: "boolean" + }, + edgeStylePathfinderPathRounded: { + label: "A* rounded path", + description: "When enabled, the A* path style will be rounded.", + type: "boolean" + } + } + }, + floatingEdgeFeatureEnabled: { + label: "Floating edges (auto edge side)", + description: "Floating edges are automatically placed on the most suitable side of the node.", + infoSection: "floating-edges-automatic-edge-side", + children: { + allowFloatingEdgeCreation: { + label: "Allow floating edges creation", + description: "Allow floating edges creation by dragging the edge over the target node without placing it over a specific side connection point. (If disabled, floating edges can only be created and used by other Advanced Canvas features.)", + type: "boolean" + }, + newEdgeFromSideFloating: { + label: "New edge from side floating", + description: 'When enabled, the "from" side of the edge will always be floating.', + type: "boolean" + } + } + }, + flipEdgeFeatureEnabled: { + label: "Flip edges", + description: "Flip the direction of edges using the popup menu.", + infoSection: "flip-edge", + children: {} + }, + presentationFeatureEnabled: { + label: "Presentations", + description: "Create a presentation from your canvas.", + infoSection: "presentation-mode", + children: { + showSetStartNodeInPopup: { + label: 'Show "Set Start Node" in node popup', + description: "If turned off, you can still set the start node using the corresponding command.", + type: "boolean" + }, + defaultSlideDimensions: { + label: "Default slide dimensions", + description: "The default dimensions of a slide.", + type: "dimension", + parse: (value) => { + const width = Math.max(1, parseInt(value[0]) || 0); + const height = Math.max(1, parseInt(value[1]) || 0); + return [width, height]; + } + }, + wrapInSlidePadding: { + label: "Wrap in slide padding", + description: "The padding of the slide when wrapping the canvas in a slide.", + type: "number", + parse: (value) => Math.max(0, parseInt(value) || 0) + }, + resetViewportOnPresentationEnd: { + label: "Reset viewport on presentation end", + description: "When enabled, the viewport will be reset to the original position after the presentation ends.", + type: "boolean" + }, + useArrowKeysToChangeSlides: { + label: "Use arrow keys to change slides", + description: "When enabled, you can use the arrow keys to change slides in presentation mode.", + type: "boolean" + }, + usePgUpPgDownKeysToChangeSlides: { + label: "Use PgUp/PgDown keys to change slides", + description: "When enabled, you can use the PgUp/PgDown keys to change slides in presentation mode (Makes the presentation mode compatible with most presentation remotes).", + type: "boolean" + }, + zoomToSlideWithoutPadding: { + label: "Zoom to slide without padding", + description: "When enabled, the canvas will zoom to the slide without padding.", + type: "boolean" + }, + useUnclampedZoomWhilePresenting: { + label: "Use unclamped zoom while presenting", + description: "When enabled, the zoom will not be clamped while presenting.", + type: "boolean" + }, + fullscreenPresentationEnabled: { + label: "Enter fullscreen while presenting", + description: "When enabled, presentations automatically request fullscreen. Disable to keep Obsidian windowed during presentations.", + type: "boolean" + }, + slideTransitionAnimationDuration: { + label: "Slide transition animation duration", + description: "The duration of the slide transition animation in seconds. Set to 0 to disable the animation.", + type: "number", + parse: (value) => Math.max(0, parseFloat(value) || 0) + }, + slideTransitionAnimationIntensity: { + label: "Slide transition animation intensity", + description: "The intensity of the slide transition animation. The higher the value, the more the canvas will zoom out before zooming in on the next slide.", + type: "number", + parse: (value) => Math.max(0, parseFloat(value) || 0) + } + } + }, + zOrderingControlFeatureEnabled: { + label: "Z ordering controls", + description: "Change the persistent z-index of nodes using the context menu.", + children: { + zOrderingControlShowOneLayerShiftOptions: { + label: "Show one layer shift options", + description: "When enabled, you can move nodes one layer forward or backward.", + type: "boolean" + } + } + }, + aspectRatioControlFeatureEnabled: { + label: "Aspect ratio control", + description: "Change the aspect ratio of nodes using the context menu.", + children: {} + }, + variableBreakpointFeatureEnabled: { + label: "Variable breakpoint", + description: `Change the zoom breakpoint (the zoom level at which the nodes won't render their content anymore) on a per-node basis using the ${VARIABLE_BREAKPOINT_CSS_VAR} CSS variable.`, + infoSection: "variable-breakpoints", + children: {} + }, + autoResizeNodeFeatureEnabled: { + label: "Auto resize node", + description: "Automatically resize the height of a node to fit the content.", + infoSection: "auto-node-resizing", + children: { + autoResizeNodeEnabledByDefault: { + label: "Enable auto resize by default", + description: "When enabled, the auto resize feature will be enabled by default for all nodes.", + type: "boolean" + }, + autoResizeNodeMaxHeight: { + label: "Max height", + description: "The maximum height of the node when auto resizing (-1 for unlimited).", + type: "number", + parse: (value) => { + var _a; + return Math.max(-1, (_a = parseInt(value)) != null ? _a : -1); + } + }, + autoResizeNodeSnapToGrid: { + label: "Snap to grid", + description: "When enabled, the height of the node will snap to the grid.", + type: "boolean" + } + } + }, + canvasEncapsulationEnabled: { + label: "Canvas encapsulation", + description: "Encapsulate a selection of nodes and edges into a new canvas using the context menu.", + infoSection: "encapsulate-selection", + children: {} + }, + betterReadonlyEnabled: { + label: "Better readonly", + description: "Improve the readonly mode.", + infoSection: "better-readonly", + children: { + hideBackgroundGridWhenInReadonly: { + label: "Hide background grid when in readonly", + description: "When enabled, the background grid will be hidden when in readonly mode.", + type: "boolean" + } + } + }, + edgeHighlightEnabled: { + label: "Edge highlight", + description: "Highlight outgoing (and optionally incoming) edges of a selected node.", + infoSection: "edge-highlight", + children: { + highlightIncomingEdges: { + label: "Highlight incoming edges", + description: "When enabled, incoming edges will also be highlighted.", + type: "boolean" + } + } + }, + edgeSelectionEnabled: { + label: "Edge selection", + description: "Select edges connected to the selected node(s) using the popup menu.", + infoSection: "edge-selection", + children: { + selectEdgeByDirection: { + label: "Select edge by direction", + description: "Select incoming or outgoing edges using separate popup menu items.", + type: "boolean" + } + } + }, + focusModeFeatureEnabled: { + label: "Focus mode", + description: "Focus on a single node and blur all other nodes.", + infoSection: "focus-mode", + children: {} + } +}; +var SettingsManager = class { + constructor(plugin) { + this.plugin = plugin; + this.nodeCssStylesManager = GET_NODE_CSS_STYLES_MANAGER(plugin); + this.edgeCssStylesManager = GET_EDGE_CSS_STYLES_MANAGER(plugin); + } + async loadSettings() { + this.settings = Object.assign({}, DEFAULT_SETTINGS_VALUES, await this.plugin.loadData()); + this.plugin.app.workspace.trigger("advanced-canvas:settings-changed"); + } + async saveSettings() { + await this.plugin.saveData(this.settings); + } + getSetting(key) { + return this.settings[key]; + } + async setSetting(data) { + this.settings = Object.assign(this.settings, data); + await this.saveSettings(); + this.plugin.app.workspace.trigger("advanced-canvas:settings-changed"); + } + addSettingsTab() { + this.settingsTab = new AdvancedCanvasPluginSettingTab(this.plugin, this); + this.plugin.addSettingTab(this.settingsTab); + } +}; +var AdvancedCanvasPluginSettingTab = class extends import_obsidian4.PluginSettingTab { + constructor(plugin, settingsManager) { + super(plugin.app, plugin); + this.settingsManager = settingsManager; + } + display() { + let { containerEl } = this; + containerEl.empty(); + this.createKofiBanner(containerEl); + for (const [headingId, heading] of Object.entries(SETTINGS)) { + this.createFeatureHeading( + containerEl, + heading.label, + heading.description, + heading.infoSection, + heading.disableToggle ? null : headingId + ); + const settingsHeaderChildrenContainerEl = document.createElement("div"); + settingsHeaderChildrenContainerEl.classList.add("settings-header-children"); + settingsHeaderChildrenContainerEl.appendChild(document.createElement("span")); + containerEl.appendChild(settingsHeaderChildrenContainerEl); + for (let [settingId, setting] of Object.entries(heading.children)) { + if (!(settingId in DEFAULT_SETTINGS_VALUES)) continue; + switch (setting.type) { + case "text": + this.createTextSetting(settingsHeaderChildrenContainerEl, settingId, setting); + break; + case "number": + this.createNumberSetting(settingsHeaderChildrenContainerEl, settingId, setting); + break; + case "dimension": + this.createDimensionSetting(settingsHeaderChildrenContainerEl, settingId, setting); + break; + case "boolean": + this.createBooleanSetting(settingsHeaderChildrenContainerEl, settingId, setting); + break; + case "dropdown": + this.createDropdownSetting(settingsHeaderChildrenContainerEl, settingId, setting); + break; + case "button": + this.createButtonSetting(settingsHeaderChildrenContainerEl, settingId, setting); + break; + case "styles": + this.createStylesSetting(settingsHeaderChildrenContainerEl, settingId, setting); + break; + } + } + } + } + createFeatureHeading(containerEl, label, description, infoSection, settingsKey) { + const setting = new import_obsidian4.Setting(containerEl).setHeading().setClass("ac-settings-heading").setName(label).setDesc(description); + if (infoSection !== void 0) { + setting.addExtraButton( + (button) => button.setTooltip("Open github documentation").setIcon("info").onClick(async () => { + window.open(`${README_URL}#${infoSection}`); + }) + ); + } + if (settingsKey !== null) { + setting.addToggle( + (toggle) => toggle.setTooltip("Requires a reload to take effect.").setValue(this.settingsManager.getSetting(settingsKey)).onChange(async (value) => { + await this.settingsManager.setSetting({ [settingsKey]: value }); + new import_obsidian4.Notice("Reload obsidian to apply the changes."); + }) + ); + } + return setting; + } + createTextSetting(containerEl, settingId, setting) { + new import_obsidian4.Setting(containerEl).setName(setting.label).setDesc(setting.description).addText( + (text) => text.setValue(this.settingsManager.getSetting(settingId)).onChange(async (value) => { + await this.settingsManager.setSetting({ [settingId]: setting.parse ? setting.parse(value) : value }); + }) + ); + } + createNumberSetting(containerEl, settingId, setting) { + new import_obsidian4.Setting(containerEl).setName(setting.label).setDesc(setting.description).addText( + (text) => text.setValue(this.settingsManager.getSetting(settingId).toString()).onChange(async (value) => { + await this.settingsManager.setSetting({ [settingId]: setting.parse(value) }); + }) + ); + } + createDimensionSetting(containerEl, settingId, setting) { + let text1; + let text2; + new import_obsidian4.Setting(containerEl).setName(setting.label).setDesc(setting.description).addText((text) => { + text1 = text.setValue(this.settingsManager.getSetting(settingId)[0].toString()).onChange(async (value) => await this.settingsManager.setSetting({ [settingId]: setting.parse([value, text2.getValue()]) })); + }).addText((text) => { + text2 = text.setValue(this.settingsManager.getSetting(settingId)[1].toString()).onChange(async (value) => await this.settingsManager.setSetting({ [settingId]: setting.parse([text1.getValue(), value]) })); + }); + } + createBooleanSetting(containerEl, settingId, setting) { + new import_obsidian4.Setting(containerEl).setName(setting.label).setDesc(setting.description).addToggle( + (toggle) => toggle.setValue(this.settingsManager.getSetting(settingId)).onChange(async (value) => { + await this.settingsManager.setSetting({ [settingId]: value }); + }) + ); + } + createDropdownSetting(containerEl, settingId, setting) { + new import_obsidian4.Setting(containerEl).setName(setting.label).setDesc(setting.description).addDropdown( + (dropdown) => dropdown.addOptions(setting.options).setValue(this.settingsManager.getSetting(settingId)).onChange(async (value) => { + await this.settingsManager.setSetting({ [settingId]: value }); + }) + ); + } + createButtonSetting(containerEl, settingId, setting) { + new import_obsidian4.Setting(containerEl).setName(setting.label).setDesc(setting.description).addButton( + (button) => button.setButtonText("Open").onClick(() => setting.onClick()) + ); + } + createStylesSetting(containerEl, settingId, setting) { + const nestedContainerEl = document.createElement("details"); + nestedContainerEl.classList.add("setting-item"); + containerEl.appendChild(nestedContainerEl); + const summaryEl = document.createElement("summary"); + summaryEl.textContent = setting.label; + nestedContainerEl.appendChild(summaryEl); + for (const styleAttribute of setting.getParameters(this.settingsManager)) { + new import_obsidian4.Setting(nestedContainerEl).setName(styleAttribute.label).addDropdown( + (dropdown) => { + var _a; + return dropdown.addOptions(Object.fromEntries(styleAttribute.options.map((option) => [option.value, option.value === null ? `${option.label} (default)` : option.label]))).setValue((_a = this.settingsManager.getSetting(settingId)[styleAttribute.key]) != null ? _a : "null").onChange(async (value) => { + const newValue = this.settingsManager.getSetting(settingId); + if (value === "null") delete newValue[styleAttribute.key]; + else newValue[styleAttribute.key] = value; + await this.settingsManager.setSetting({ + [settingId]: newValue + }); + }); + } + ); + } + } + async createKofiBanner(containerEl) { + const banner = document.createElement("div"); + banner.classList.add("kofi-banner"); + const title = document.createElement("h1"); + title.textContent = "Enjoying the plugin?"; + banner.appendChild(title); + const description = document.createElement("p"); + description.innerHTML = ` + Currently, Advanced Canvas has received about ${RECEIVED_DONATIONS}\xA3 in donations with a total of about ${SPENT_HOURS} hours spent on development.
+
+ Please help me develop this plugin further by reaching the goal of ${HOURLY_RATE_GOAL}\xA3/hour \u2764\uFE0F + `; + banner.appendChild(description); + const progressContainer = document.createElement("div"); + progressContainer.classList.add("progress-container"); + const progressbar = document.createElement("progress"); + progressbar.value = RECEIVED_DONATIONS / SPENT_HOURS; + progressbar.max = HOURLY_RATE_GOAL; + progressContainer.appendChild(progressbar); + const hourlyRate = document.createElement("span"); + hourlyRate.classList.add("hourly-rate"); + hourlyRate.textContent = `${(RECEIVED_DONATIONS / SPENT_HOURS).toString()}\xA3/h`; + progressContainer.appendChild(hourlyRate); + banner.appendChild(progressContainer); + const koFiButton = document.createElement("a"); + koFiButton.classList.add("ac-kofi-button"); + koFiButton.href = KOFI_PAGE_URL; + koFiButton.target = "_blank"; + const koFiImage = document.createElement("img"); + koFiImage.src = KOFI_BADGE_URI; + koFiButton.appendChild(koFiImage); + banner.appendChild(koFiButton); + containerEl.appendChild(banner); + } +}; + +// src/managers/windows-manager.ts +var WindowsManager = class { + constructor(plugin) { + this.windows = [window]; + this.plugin = plugin; + this.plugin.registerEvent(this.plugin.app.workspace.on( + "window-open", + (_win, window2) => this.windows.push(window2) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "window-close", + (_win, window2) => this.windows = this.windows.filter((w) => w !== window2) + )); + } +}; + +// src/patchers/canvas-patcher.ts +var import_view = require("@codemirror/view"); + +// node_modules/monkey-around/mjs/index.js +function around(obj, factories) { + const removers = Object.keys(factories).map((key) => around1(obj, key, factories[key])); + return removers.length === 1 ? removers[0] : function() { + removers.forEach((r) => r()); + }; +} +function around1(obj, method, createWrapper) { + const original = obj[method], hadOwn = obj.hasOwnProperty(method); + let current = createWrapper(original); + if (original) + Object.setPrototypeOf(current, original); + Object.setPrototypeOf(wrapper, current); + obj[method] = wrapper; + return remove; + function wrapper(...args) { + if (current === original && obj[method] === wrapper) + remove(); + return current.apply(this, args); + } + function remove() { + if (obj[method] === wrapper) { + if (hadOwn) + obj[method] = original; + else + delete obj[method]; + } + if (current === original) + return; + current = original; + Object.setPrototypeOf(wrapper, original || Function); + } +} + +// src/patchers/canvas-patcher.ts +var import_obsidian5 = require("obsidian"); + +// node_modules/tiny-jsonc/dist/index.js +var stringOrCommentRe = /("(?:\\?[^])*?")|(\/\/.*)|(\/\*[^]*?\*\/)/g; +var stringOrTrailingCommaRe = /("(?:\\?[^])*?")|(,\s*)(?=]|})/g; +var JSONC = { + parse: (text) => { + text = String(text); + try { + return JSON.parse(text); + } catch (e) { + return JSON.parse(text.replace(stringOrCommentRe, "$1").replace(stringOrTrailingCommaRe, "$1")); + } + } +}; +var dist_default = JSONC; + +// src/patchers/patcher.ts +var Patcher = class _Patcher { + constructor(plugin) { + this.plugin = plugin; + this.patch(); + } + static async waitForViewRequest(plugin, viewType, patch) { + return new Promise((resolve) => { + const uninstaller = around(plugin.app.viewRegistry.viewByType, { + [viewType]: (next) => function(...args) { + const view = next.call(this, ...args); + patch(view); + const patchedView = next.call(this, ...args); + uninstaller(); + resolve(patchedView); + return patchedView; + } + }); + }); + } + static OverrideExisting(fn) { + return Object.assign(fn, { __overrideExisting: true }); + } + static patchThisAndPrototype(plugin, object, patches, uninstallers) { + _Patcher.patch(plugin, object, patches, false, uninstallers); + return _Patcher.patchPrototype(plugin, object, patches, uninstallers); + } + static patchPrototype(plugin, target, patches, uninstallers) { + return _Patcher.patch(plugin, target, patches, true, uninstallers); + } + static patch(plugin, object, patches, prototype = false, uninstallers) { + if (!object) return null; + const target = prototype ? object.constructor.prototype : object; + for (const key of Object.keys(patches)) { + const patch = patches[key]; + if (patch == null ? void 0 : patch.__overrideExisting) { + if (typeof target[key] !== "function") + throw new Error(`Method ${String(key)} does not exist on target`); + } + } + const uninstaller = around(target, patches); + if (uninstallers) uninstallers.push(uninstaller); + plugin.register(uninstaller); + return object; + } + static tryPatchWorkspacePrototype(plugin, getTarget, patches, uninstallers) { + return new Promise((resolve) => { + const result = _Patcher.patchPrototype(plugin, getTarget(), patches, uninstallers); + if (result) { + resolve(result); + return; + } + const listener = plugin.app.workspace.on("layout-change", () => { + const result2 = _Patcher.patchPrototype(plugin, getTarget(), patches, uninstallers); + if (result2) { + plugin.app.workspace.offref(listener); + resolve(result2); + } + }); + plugin.registerEvent(listener); + }); + } +}; + +// src/utils/migration-helper.ts +var CURRENT_SPEC_VERSION = "1.0-1.0"; +var _MigrationHelper = class _MigrationHelper { + static needsMigration(canvas) { + var _a; + return ((_a = canvas.metadata) == null ? void 0 : _a.version) !== CURRENT_SPEC_VERSION; + } + static migrate(canvas) { + var _a, _b; + let version = (_b = (_a = canvas.metadata) == null ? void 0 : _a.version) != null ? _b : "undefined"; + if (version === CURRENT_SPEC_VERSION) return canvas; + while (version !== CURRENT_SPEC_VERSION) { + const migrationFunction = _MigrationHelper.MIGRATIONS[version]; + if (!migrationFunction) { + console.error(`No migration function found for version ${version}. Critical error!`); + break; + } + const { version: newVersion, canvas: migratedCanvas } = migrationFunction(canvas); + version = newVersion; + canvas = migratedCanvas; + if (!canvas.metadata) canvas.metadata = { version, frontmatter: {} }; + else canvas.metadata.version = version; + } + return canvas; + } +}; +_MigrationHelper.MIGRATIONS = { + undefined: (canvas) => { + var _a, _b, _c; + const TARGET_SPEC_VERSION = "1.0-1.0"; + let startNode; + const globalInterdimensionalEdges = {}; + for (const node of (_a = canvas.nodes) != null ? _a : []) { + node.dynamicHeight = node.autoResizeHeight; + delete node.autoResizeHeight; + node.ratio = node.sideRatio; + delete node.sideRatio; + node.collapsed = node.isCollapsed; + delete node.isCollapsed; + if (node.portalToFile) { + node.portal = true; + delete node.portalToFile; + } + if (node.isStartNode) { + startNode = node.id; + delete node.isStartNode; + } + if (node.edgesToNodeFromPortal) { + const edgesToNodeFromPortal = node.edgesToNodeFromPortal; + for (const [portalId, edges] of Object.entries(edgesToNodeFromPortal)) { + if (!(portalId in globalInterdimensionalEdges)) globalInterdimensionalEdges[portalId] = []; + for (const edge of edges) { + if (edge.fromNode !== node.id) edge.fromNode = `${portalId}-${edge.fromNode}`; + if (edge.toNode !== node.id) edge.toNode = `${portalId}-${edge.toNode}`; + } + globalInterdimensionalEdges[portalId].push(...edges); + } + delete node.edgesToNodeFromPortal; + } + } + for (const node of (_b = canvas.nodes) != null ? _b : []) { + if (!(node.id in globalInterdimensionalEdges)) continue; + node.interdimensionalEdges = globalInterdimensionalEdges[node.id]; + } + (_c = canvas.metadata) != null ? _c : canvas.metadata = { + version: TARGET_SPEC_VERSION, + frontmatter: {}, + startNode + }; + return { version: TARGET_SPEC_VERSION, canvas }; + } +}; +var MigrationHelper = _MigrationHelper; + +// src/patchers/canvas-patcher.ts +var CanvasPatcher = class extends Patcher { + async patch() { + const loadedCanvasViewLeafs = this.plugin.app.workspace.getLeavesOfType("canvas").filter((leaf) => !(0, import_obsidian5.requireApiVersion)("1.7.2") || !leaf.isDeferred); + if (loadedCanvasViewLeafs.length > 0) { + console.debug(`Patching and reloading loaded canvas views (Count: ${loadedCanvasViewLeafs.length})`); + this.patchCanvas(loadedCanvasViewLeafs.first().view); + for (const leaf of loadedCanvasViewLeafs) leaf.rebuildView(); + } else { + await Patcher.waitForViewRequest(this.plugin, "canvas", (view) => this.patchCanvas(view)); + console.debug(`Patched canvas view on first request`); + } + } + patchCanvas(view) { + const that = this; + Patcher.patchPrototype(this.plugin, view, { + setEphemeralState: Patcher.OverrideExisting((next) => function(state) { + var _a, _b, _c; + if (state == null ? void 0 : state.subpath) { + const nodeId = state.subpath.replace(/^#/, ""); + const node = this.canvas.nodes.get(nodeId); + if (node) { + this.canvas.selectOnly(node); + this.canvas.zoomToSelection(); + return; + } + } + if (((_b = (_a = state.match) == null ? void 0 : _a.matches) == null ? void 0 : _b[0]) && !((_c = state.match) == null ? void 0 : _c.nodeId)) { + const match = state.match.matches[0]; + const elementType = match[0] === 0 ? "nodes" : "edges"; + const elementIndex = match[1]; + const element = elementType === "nodes" ? Array.from(this.canvas.nodes.values())[elementIndex] : Array.from(this.canvas.edges.values())[elementIndex]; + if (element) { + this.canvas.selectOnly(element); + this.canvas.zoomToSelection(); + return; + } + } + return next.call(this, state); + }), + setViewData: Patcher.OverrideExisting((next) => function(json, ...args) { + json = json !== "" ? json : '{"nodes": [], "edges": []}'; + try { + const canvasData = dist_default.parse(json); + if (MigrationHelper.needsMigration(canvasData)) { + if (this.file) that.plugin.createFileSnapshot(this.file.path, json); + json = JSON.stringify(MigrationHelper.migrate(canvasData)); + } + } catch (e) { + console.error("Failed to migrate canvas data:", e); + } + let result; + try { + result = next.call(this, json, ...args); + } catch (e) { + console.error("Invalid JSON, repairing through Advanced Canvas:", e); + if (this.file) that.plugin.createFileSnapshot(this.file.path, json); + json = JSON.stringify(dist_default.parse(json), null, 2); + result = next.call(this, json, ...args); + } + that.plugin.app.workspace.trigger("advanced-canvas:canvas-changed", this.canvas); + return result; + }), + close: Patcher.OverrideExisting((next) => function(...args) { + that.plugin.app.workspace.trigger("advanced-canvas:canvas-view-unloaded:before", this); + return next.call(this, ...args); + }) + }); + Patcher.patchPrototype(this.plugin, view.canvas, { + markViewportChanged: Patcher.OverrideExisting((next) => function(...args) { + that.plugin.app.workspace.trigger("advanced-canvas:viewport-changed:before", this); + const result = next.call(this, ...args); + that.plugin.app.workspace.trigger("advanced-canvas:viewport-changed:after", this); + return result; + }), + markMoved: Patcher.OverrideExisting((next) => function(node) { + const result = next.call(this, node); + if (!this.viewportChanged) { + if (node.prevX !== node.x || node.prevY !== node.y) + that.plugin.app.workspace.trigger("advanced-canvas:node-moved", this, node, !this.isDragging); + if (node.prevWidth !== node.width || node.prevHeight !== node.height) + that.plugin.app.workspace.trigger("advanced-canvas:node-resized", this, node); + } + node.prevX = node.x; + node.prevY = node.y; + node.prevWidth = node.width; + node.prevHeight = node.height; + return result; + }), + onDoubleClick: Patcher.OverrideExisting((next) => function(event) { + const preventDefault = { value: false }; + that.plugin.app.workspace.trigger("advanced-canvas:double-click", this, event, preventDefault); + if (!preventDefault.value) next.call(this, event); + }), + setDragging: Patcher.OverrideExisting((next) => function(dragging) { + const result = next.call(this, dragging); + that.plugin.app.workspace.trigger("advanced-canvas:dragging-state-changed", this, dragging); + return result; + }), + // OBSIDIAN-FIX + cloneData: Patcher.OverrideExisting((next) => function(elements, shift) { + const result = next.call(this, elements, shift); + elements.nodes = elements.nodes.map((nodeData) => JSON.parse(JSON.stringify(nodeData))); + elements.edges = elements.edges.map((edgeData) => JSON.parse(JSON.stringify(edgeData))); + return result; + }), + getContainingNodes: Patcher.OverrideExisting((next) => function(bbox) { + const result = next.call(this, bbox); + that.plugin.app.workspace.trigger("advanced-canvas:containing-nodes-requested", this, bbox, result); + return result; + }), + updateSelection: Patcher.OverrideExisting((next) => function(update) { + const oldSelection = new Set(this.selection); + const result = next.call(this, update); + that.plugin.app.workspace.trigger("advanced-canvas:selection-changed", this, oldSelection, (update2) => next.call(this, update2)); + return result; + }), + createTextNode: Patcher.OverrideExisting((next) => function(...args) { + const node = next.call(this, ...args); + that.plugin.app.workspace.trigger("advanced-canvas:node-created", this, node); + return node; + }), + createFileNode: Patcher.OverrideExisting((next) => function(...args) { + const node = next.call(this, ...args); + that.plugin.app.workspace.trigger("advanced-canvas:node-created", this, node); + return node; + }), + createFileNodes: Patcher.OverrideExisting((next) => function(...args) { + const nodes = next.call(this, ...args); + nodes.forEach((node) => that.plugin.app.workspace.trigger("advanced-canvas:node-created", this, node)); + return nodes; + }), + createGroupNode: Patcher.OverrideExisting((next) => function(...args) { + const node = next.call(this, ...args); + that.plugin.app.workspace.trigger("advanced-canvas:node-created", this, node); + return node; + }), + createLinkNode: Patcher.OverrideExisting((next) => function(...args) { + const node = next.call(this, ...args); + that.plugin.app.workspace.trigger("advanced-canvas:node-created", this, node); + return node; + }), + addNode: Patcher.OverrideExisting((next) => function(node) { + that.patchNode(node); + return next.call(this, node); + }), + addEdge: Patcher.OverrideExisting((next) => function(edge) { + that.patchEdge(edge); + if (!this.viewportChanged) that.plugin.app.workspace.trigger("advanced-canvas:edge-created", this, edge); + return next.call(this, edge); + }), + removeNode: Patcher.OverrideExisting((next) => function(node) { + const result = next.call(this, node); + if (!this.isClearing) that.plugin.app.workspace.trigger("advanced-canvas:node-removed", this, node); + return result; + }), + removeEdge: Patcher.OverrideExisting((next) => function(edge) { + const result = next.call(this, edge); + if (!this.isClearing) that.plugin.app.workspace.trigger("advanced-canvas:edge-removed", this, edge); + return result; + }), + handleCopy: Patcher.OverrideExisting((next) => function(...args) { + this.isCopying = true; + const result = next.call(this, ...args); + this.isCopying = false; + return result; + }), + handlePaste: Patcher.OverrideExisting((next) => function(...args) { + this.isPasting = true; + const result = next.call(this, ...args); + this.isPasting = false; + return result; + }), + getSelectionData: Patcher.OverrideExisting((next) => function(...args) { + const result = next.call(this, ...args); + if (this.isCopying) that.plugin.app.workspace.trigger("advanced-canvas:copy", this, result); + return result; + }), + zoomToBbox: Patcher.OverrideExisting((next) => function(bbox) { + that.plugin.app.workspace.trigger("advanced-canvas:zoom-to-bbox:before", this, bbox); + const result = next.call(this, bbox); + that.plugin.app.workspace.trigger("advanced-canvas:zoom-to-bbox:after", this, bbox); + return result; + }), + // Custom + zoomToRealBbox: (_next) => function(bbox) { + if (this.canvasRect.width === 0 || this.canvasRect.height === 0) return; + that.plugin.app.workspace.trigger("advanced-canvas:zoom-to-bbox:before", this, bbox); + const widthZoom = this.canvasRect.width / (bbox.maxX - bbox.minX); + const heightZoom = this.canvasRect.height / (bbox.maxY - bbox.minY); + const zoom = this.screenshotting ? Math.min(widthZoom, heightZoom) : Math.clamp(Math.min(widthZoom, heightZoom), -4, 1); + this.tZoom = Math.log2(zoom); + this.zoomCenter = null; + this.tx = (bbox.minX + bbox.maxX) / 2; + this.ty = (bbox.minY + bbox.maxY) / 2; + this.markViewportChanged(); + that.plugin.app.workspace.trigger("advanced-canvas:zoom-to-bbox:after", this, bbox); + }, + setReadonly: Patcher.OverrideExisting((next) => function(readonly) { + const result = next.call(this, readonly); + that.plugin.app.workspace.trigger("advanced-canvas:readonly-changed", this, readonly); + return result; + }), + undo: Patcher.OverrideExisting((next) => function(...args) { + const result = next.call(this, ...args); + this.importData(this.getData(), true); + that.plugin.app.workspace.trigger("advanced-canvas:undo", this); + return result; + }), + redo: Patcher.OverrideExisting((next) => function(...args) { + const result = next.call(this, ...args); + this.importData(this.getData(), true); + that.plugin.app.workspace.trigger("advanced-canvas:redo", this); + return result; + }), + clear: Patcher.OverrideExisting((next) => function(...args) { + this.isClearing = true; + const result = next.call(this, ...args); + this.isClearing = false; + return result; + }), + /*setData: Patcher.OverrideExisting(next => function (...args: any): void { + // + const result = next.call(this, ...args) + // + return result + }),*/ + getData: Patcher.OverrideExisting((next) => function(...args) { + const result = next.call(this, ...args); + that.plugin.app.workspace.trigger("advanced-canvas:data-requested", this, result); + return result; + }), + importData: Patcher.OverrideExisting((next) => function(data, clearCanvas, silent) { + const targetFilePath = this.view.file.path; + const setData = (data2) => { + if (!this.view.file || this.view.file.path !== targetFilePath) return; + this.importData(data2, true, true); + }; + if (!silent) that.plugin.app.workspace.trigger("advanced-canvas:data-loaded:before", this, data, setData); + const result = next.call(this, data, clearCanvas); + if (!silent) that.plugin.app.workspace.trigger("advanced-canvas:data-loaded:after", this, data, setData); + return result; + }), + requestSave: Patcher.OverrideExisting((next) => function(...args) { + that.plugin.app.workspace.trigger("advanced-canvas:canvas-saved:before", this); + const result = next.call(this, ...args); + that.plugin.app.workspace.trigger("advanced-canvas:canvas-saved:after", this); + return result; + }) + }); + Patcher.patchPrototype(this.plugin, view.canvas.menu, { + render: Patcher.OverrideExisting((next) => function(...args) { + const result = next.call(this, ...args); + that.plugin.app.workspace.trigger("advanced-canvas:popup-menu-created", this.canvas); + next.call(this); + return result; + }) + }); + Patcher.patchPrototype(this.plugin, view.canvas.nodeInteractionLayer, { + setTarget: Patcher.OverrideExisting((next) => function(node) { + const result = next.call(this, node); + that.plugin.app.workspace.trigger("advanced-canvas:node-interaction", this.canvas, node); + return result; + }) + }); + this.plugin.registerEditorExtension([import_view.EditorView.updateListener.of((update) => { + if (!update.docChanged) return; + const editor = update.state.field(import_obsidian5.editorInfoField); + const node = editor.node; + if (!node) return; + that.plugin.app.workspace.trigger("advanced-canvas:node-text-content-changed", node.canvas, node, update); + })]); + } + patchNode(node) { + const that = this; + Patcher.patch(this.plugin, node, { + setData: Patcher.OverrideExisting((next) => function(data, addHistory) { + const result = next.call(this, data); + if (node.initialized && !node.isDirty) { + node.isDirty = true; + that.plugin.app.workspace.trigger("advanced-canvas:node-changed", this.canvas, node); + delete node.isDirty; + } + this.canvas.data = this.canvas.getData(); + if (this.initialized) this.canvas.view.requestSave(); + if (addHistory) this.canvas.pushHistory(this.canvas.data); + return result; + }), + setZIndex: (_next) => function(value) { + this.setData({ + ...this.getData(), + zIndex: value + }, true); + this.updateZIndex(); + }, + updateZIndex: Patcher.OverrideExisting((next) => function() { + const persistentZIndex = this.getData().zIndex; + if (persistentZIndex === void 0) return next.call(this); + this.canvas.zIndexCounter = Math.max(this.canvas.zIndexCounter, persistentZIndex); + this.renderZIndex(); + }), + renderZIndex: Patcher.OverrideExisting((next) => function() { + const persistentZIndex = this.getData().zIndex; + if (persistentZIndex === void 0) return next.call(this); + this.zIndex = persistentZIndex; + if (this.canvas.selection.size === 1 && this.canvas.selection.has(this)) + this.zIndex = this.canvas.zIndexCounter + 1; + this.nodeEl.style.zIndex = this.zIndex.toString(); + }), + setIsEditing: Patcher.OverrideExisting((next) => function(editing, ...args) { + const result = next.call(this, editing, ...args); + that.plugin.app.workspace.trigger("advanced-canvas:node-editing-state-changed", this.canvas, node, editing); + return result; + }), + updateBreakpoint: Patcher.OverrideExisting((next) => function(breakpoint) { + const breakpointRef = { value: breakpoint }; + that.plugin.app.workspace.trigger("advanced-canvas:node-breakpoint-changed", this.canvas, node, breakpointRef); + return next.call(this, breakpointRef.value); + }), + getBBox: Patcher.OverrideExisting((next) => function(...args) { + const result = next.call(this, ...args); + that.plugin.app.workspace.trigger("advanced-canvas:node-bbox-requested", this.canvas, node, result); + return result; + }), + onConnectionPointerdown: Patcher.OverrideExisting((next) => function(e, side) { + const addEdgeEventRef = that.plugin.app.workspace.on("advanced-canvas:edge-added", (_canvas, edge) => { + that.plugin.app.workspace.trigger("advanced-canvas:edge-connection-dragging:before", this.canvas, edge, e, true, "to"); + that.plugin.app.workspace.offref(addEdgeEventRef); + document.addEventListener("pointerup", (e2) => { + that.plugin.app.workspace.trigger("advanced-canvas:edge-connection-dragging:after", this.canvas, edge, e2, true, "to"); + }, { once: true }); + }); + const result = next.call(this, e, side); + return result; + }), + // File nodes + setFile: (next) => function(...args) { + const result = next.call(this, ...args); + that.plugin.app.workspace.trigger("advanced-canvas:node-changed", this.canvas, this); + return result; + }, + setFilePath: (next) => function(...args) { + const result = next.call(this, ...args); + that.plugin.app.workspace.trigger("advanced-canvas:node-changed", this.canvas, this); + return result; + } + }); + this.runAfterInitialized(node, () => { + this.plugin.app.workspace.trigger("advanced-canvas:node-added", node.canvas, node); + this.plugin.app.workspace.trigger("advanced-canvas:node-changed", node.canvas, node); + }); + } + patchEdge(edge) { + const that = this; + Patcher.patch(this.plugin, edge, { + setData: Patcher.OverrideExisting((next) => function(data, addHistory) { + const result = next.call(this, data); + if (this.initialized && !this.isDirty) { + this.isDirty = true; + that.plugin.app.workspace.trigger("advanced-canvas:edge-changed", this.canvas, this); + delete this.isDirty; + } + this.canvas.data = this.canvas.getData(); + if (this.initialized) this.canvas.view.requestSave(); + if (addHistory) this.canvas.pushHistory(this.canvas.getData()); + return result; + }), + render: Patcher.OverrideExisting((next) => function(...args) { + const result = next.call(this, ...args); + that.plugin.app.workspace.trigger("advanced-canvas:edge-changed", this.canvas, this); + return result; + }), + getCenter: Patcher.OverrideExisting((next) => function(...args) { + const result = next.call(this, ...args); + that.plugin.app.workspace.trigger("advanced-canvas:edge-center-requested", this.canvas, this, result); + return result; + }), + onConnectionPointerdown: Patcher.OverrideExisting((next) => function(e) { + const cancelRef = { value: false }; + that.plugin.app.workspace.trigger("advanced-canvas:edge-connection-try-dragging:before", this.canvas, this, e, cancelRef); + if (cancelRef.value) return; + const previousEnds = { from: this.from, to: this.to }; + const result = next.call(this, e); + const eventPos = this.canvas.posFromEvt(e); + const fromPos = BBoxHelper.getCenterOfBBoxSide(this.from.node.getBBox(), this.from.side); + const toPos = BBoxHelper.getCenterOfBBoxSide(this.to.node.getBBox(), this.to.side); + const draggingSide = Math.hypot(eventPos.x - fromPos.x, eventPos.y - fromPos.y) > Math.hypot(eventPos.x - toPos.x, eventPos.y - toPos.y) ? "to" : "from"; + that.plugin.app.workspace.trigger("advanced-canvas:edge-connection-dragging:before", this.canvas, this, e, false, draggingSide, previousEnds); + document.addEventListener("pointerup", (e2) => { + that.plugin.app.workspace.trigger("advanced-canvas:edge-connection-dragging:after", this.canvas, this, e2, false, draggingSide, previousEnds); + }, { once: true }); + return result; + }) + }); + this.runAfterInitialized(edge, () => { + this.plugin.app.workspace.trigger("advanced-canvas:edge-added", edge.canvas, edge); + }); + } + runAfterInitialized(canvasElement, onReady) { + if (canvasElement.initialized) { + onReady(); + return; + } + const that = this; + const uninstall = around(canvasElement, { + initialize: (next) => function(...args) { + const result = next.call(this, ...args); + onReady(); + uninstall(); + return result; + } + }); + that.plugin.register(uninstall); + } +}; + +// src/patchers/link-suggestions-patcher.ts +var import_obsidian6 = require("obsidian"); +var LinkSuggestionsPatcher = class extends Patcher { + async patch() { + var _a; + if (!this.plugin.settings.getSetting("enableSingleNodeLinks")) return; + const suggestManager = (_a = this.plugin.app.workspace.editorSuggest.suggests.find((s) => s.suggestManager)) == null ? void 0 : _a.suggestManager; + if (!suggestManager) return console.warn("LinkSuggestionsPatcher: No suggest manager found."); + const that = this; + Patcher.patchThisAndPrototype(this.plugin, suggestManager, { + getHeadingSuggestions: Patcher.OverrideExisting((next) => async function(context, path, subpath) { + const result = await next.call(this, context, path, subpath); + if (!path.endsWith(".canvas")) return result; + const currentFilePath = this.getSourcePath(); + const targetFile = this.app.metadataCache.getFirstLinkpathDest(path, currentFilePath); + if (!targetFile) return result; + if (!(targetFile instanceof import_obsidian6.TFile) || targetFile.extension !== "canvas") return result; + const fileCache = this.app.metadataCache.getFileCache(targetFile); + if (!fileCache) return result; + const canvasNodeCaches = fileCache.nodes; + if (!canvasNodeCaches) return result; + for (const [nodeId, nodeCache] of Object.entries(canvasNodeCaches)) { + if (nodeId === subpath) continue; + const suggestion = { + file: targetFile, + heading: nodeId, + level: 1, + matches: [], + path, + subpath: `#${nodeId}`, + score: 0, + type: "heading" + }; + result.push(suggestion); + } + return result; + }) + }); + } +}; + +// src/advanced-canvas-embed.ts +var import_obsidian7 = require("obsidian"); +var AdvancedCanvasEmbed = class extends import_obsidian7.Component { + constructor(context, file, subpath) { + super(); + this.onModifyCallback = (file) => { + if (file.path !== this.file.path) return; + this.loadFile(); + }; + this.context = context; + this.file = file; + this.subpath = subpath; + if (!subpath) console.warn("AdvancedCanvasEmbed: No subpath provided. This embed will not work as expected."); + } + onload() { + this.context.app.vault.on("modify", this.onModifyCallback); + } + onunload() { + this.context.app.vault.off("modify", this.onModifyCallback); + } + async loadFile() { + if (!this.subpath) return; + const nodeId = this.subpath.replace(/^#/, ""); + const canvasContent = await this.context.app.vault.cachedRead(this.file); + if (!canvasContent) return console.warn("AdvancedCanvasEmbed: No canvas content found."); + const canvasJson = JSON.parse(canvasContent); + const canvasNode = canvasJson.nodes.find((node) => node.id === nodeId); + if (!canvasNode) { + this.context.containerEl.classList.add("mod-empty"); + this.context.containerEl.textContent = "Node not found"; + return; + } + let nodeContent = ""; + if (canvasNode.type === "text") nodeContent = canvasNode.text; + else if (canvasNode.type === "group") nodeContent = `**Group Node:** ${canvasNode.label}`; + else if (canvasNode.type === "file") nodeContent = `**File Node:** ${canvasNode.file}`; + this.context.containerEl.classList.add("markdown-embed"); + this.context.containerEl.empty(); + import_obsidian7.MarkdownRenderer.render(this.context.app, nodeContent, this.context.containerEl, this.file.path, this); + } +}; + +// src/patchers/embed-patcher.ts +var EmbedPatcher = class extends Patcher { + async patch() { + if (!this.plugin.settings.getSetting("enableSingleNodeLinks")) return; + Patcher.patch(this.plugin, this.plugin.app.embedRegistry.embedByExtension, { + canvas: (next) => function(context, file, subpath) { + if (subpath) return new AdvancedCanvasEmbed(context, file, subpath); + return next.call(this, context, file, subpath); + } + }); + } +}; + +// src/patchers/metadata-cache-patcher.ts +var import_obsidian8 = require("obsidian"); + +// src/utils/hash-helper.ts +var HashHelper = class _HashHelper { + static async getFileHash(plugin, file) { + const bytes = await plugin.app.vault.readBinary(file); + const cryptoBytes = await crypto.subtle.digest("SHA-256", new Uint8Array(bytes)); + return _HashHelper.arrayBufferToHexString(cryptoBytes); + } + static arrayBufferToHexString(buffer) { + const uint8Array = new Uint8Array(buffer); + const hexArray = []; + for (const byte of uint8Array) { + hexArray.push((byte >>> 4).toString(16)); + hexArray.push((byte & 15).toString(16)); + } + return hexArray.join(""); + } +}; + +// src/utils/filepath-helper.ts +var FilepathHelper = class { + static extension(path) { + var _a; + return (path == null ? void 0 : path.includes(".")) ? (_a = path == null ? void 0 : path.split(".")) == null ? void 0 : _a.pop() : void 0; + } +}; + +// src/patchers/metadata-cache-patcher.ts +var MetadataCachePatcher = class extends Patcher { + async patch() { + if (!this.plugin.settings.getSetting("canvasMetadataCompatibilityEnabled")) return; + const that = this; + Patcher.patchPrototype(this.plugin, this.plugin.app.metadataCache, { + getCache: Patcher.OverrideExisting((next) => function(filepath, ...args) { + if (FilepathHelper.extension(filepath) === "canvas") { + if (!this.fileCache.hasOwnProperty(filepath)) return null; + const hash = this.fileCache[filepath].hash; + return this.metadataCache[hash] || null; + } + return next.call(this, filepath, ...args); + }), + computeFileMetadataAsync: Patcher.OverrideExisting((next) => async function(file, ...args) { + var _a, _b, _c, _d, _e, _f, _g; + if (FilepathHelper.extension(file.path) !== "canvas") + return next.call(this, file, ...args); + this.uniqueFileLookup.add(file.name.toLowerCase(), file); + const fileHash = await HashHelper.getFileHash(that.plugin, file); + this.saveFileCache(file.path, { + hash: fileHash, + // Hash wouldn't get set in the original function + mtime: file.stat.mtime, + size: file.stat.size + }); + const content = JSON.parse(await this.vault.cachedRead(file) || "{}"); + const frontmatter = (_a = content.metadata) == null ? void 0 : _a.frontmatter; + const frontmatterData = {}; + if (frontmatter) { + frontmatterData.frontmatterPosition = { + start: { line: 0, col: 0, offset: 0 }, + end: { line: 0, col: 0, offset: 0 } + }; + frontmatterData.frontmatter = frontmatter; + frontmatterData.frontmatterLinks = Object.entries(frontmatter).flatMap(([key, value]) => { + const getLinks = (value2) => value2.map((v) => { + if (!v.startsWith("[[") || !v.endsWith("]]")) return null; + const [link, ...aliases] = v.slice(2, -2).split("|"); + return { + key, + displayText: aliases.length > 0 ? aliases.join("|") : link, + link, + original: v + }; + }).filter((v) => v !== null); + if (typeof value === "string") return getLinks([value]); + else if (Array.isArray(value)) return getLinks(value); + return []; + }); + } + const fileNodesEmbeds = (_d = (_c = (_b = content.nodes) == null ? void 0 : _b.map((nodeData, index) => nodeData.type === "file" && nodeData.file ? { + link: nodeData.file, + original: nodeData.file, + displayText: nodeData.file, + position: { + start: { line: 0, col: 1, offset: 0 }, + // 0 for nodes + end: { line: 0, col: 1, offset: index } + // index of node + } + } : null)) == null ? void 0 : _c.filter((entry) => entry !== null)) != null ? _d : []; + const textEncoder = new TextEncoder(); + const nodesMetadataPromises = (_g = (_f = (_e = content.nodes) == null ? void 0 : _e.map((node) => node.type === "text" ? textEncoder.encode(node.text).buffer : null)) == null ? void 0 : _f.map((buffer) => buffer ? this.computeMetadataAsync(buffer) : Promise.resolve(null))) != null ? _g : []; + const nodesMetadata = await Promise.all(nodesMetadataPromises); + const textNodesEmbeds = nodesMetadata.map((metadata, index) => { + var _a2; + return ((_a2 = metadata == null ? void 0 : metadata.embeds) != null ? _a2 : []).map((embed2) => { + var _a3, _b2; + return { + ...embed2, + position: { + nodeId: (_b2 = (_a3 = content.nodes) == null ? void 0 : _a3[index]) == null ? void 0 : _b2.id, + start: { line: 0, col: 1, offset: 0 }, + // 0 for node + end: { line: 0, col: 1, offset: index } + // index of node + } + }; + }); + }).flat(); + const textNodesLinks = nodesMetadata.map((metadata, index) => { + var _a2; + return ((_a2 = metadata == null ? void 0 : metadata.links) != null ? _a2 : []).map((link) => { + var _a3, _b2; + return { + ...link, + position: { + nodeId: (_b2 = (_a3 = content.nodes) == null ? void 0 : _a3[index]) == null ? void 0 : _b2.id, + start: { line: 0, col: 1, offset: 0 }, + // 0 for node + end: { line: 0, col: 1, offset: index } + // index of node + } + }; + }); + }).flat(); + this.metadataCache[fileHash] = { + v: 1, + ...frontmatterData, + embeds: [ + ...fileNodesEmbeds, + ...textNodesEmbeds + ], + links: [ + ...textNodesLinks + ], + nodes: { + ...nodesMetadata.reduce((acc, metadata, index) => { + var _a2, _b2; + const nodeId = (_b2 = (_a2 = content.nodes) == null ? void 0 : _a2[index]) == null ? void 0 : _b2.id; + if (nodeId && metadata) + acc[nodeId] = metadata; + return acc; + }, {}) + } + }; + this.trigger("changed", file, "", this.metadataCache[fileHash]); + if (await Promise.race([this.workQueue.promise.then(() => false), new Promise((resolve) => setTimeout(() => resolve(true), 0))])) + this.trigger("finished", file, "", this.metadataCache[fileHash], true); + this.resolveLinks(file.path, content); + }), + resolveLinks: Patcher.OverrideExisting((next) => async function(filepath, cachedContent) { + var _a, _b; + if (FilepathHelper.extension(filepath) !== "canvas") + return next.call(this, filepath); + const file = this.vault.getAbstractFileByPath(filepath); + if (!file) return; + const metadataCache = this.metadataCache[(_a = this.fileCache[filepath]) == null ? void 0 : _a.hash]; + if (!metadataCache) return; + const metadataReferences = [...metadataCache.links || [], ...metadataCache.embeds || []]; + this.resolvedLinks[filepath] = metadataReferences.reduce((acc, metadataReference) => { + const resolvedLinkpath = this.getFirstLinkpathDest(metadataReference.link, filepath); + if (!resolvedLinkpath) return acc; + acc[resolvedLinkpath.path] = (acc[resolvedLinkpath.path] || 0) + 1; + return acc; + }, {}); + if (that.plugin.settings.getSetting("treatFileNodeEdgesAsLinks")) { + ; + ((_b = cachedContent.edges) != null ? _b : []).forEach((edge) => { + var _a2, _b2; + const from = (_a2 = cachedContent.nodes) == null ? void 0 : _a2.find((node) => node.id === edge.fromNode); + const to = (_b2 = cachedContent.nodes) == null ? void 0 : _b2.find((node) => node.id === edge.toNode); + if (!from || !to) return; + if (from.type !== "file" || to.type !== "file" || !from.file || !from.file) return; + const fromFile = from.file; + const toFile = to.file; + this.registerInternalLinkAC(file.name, fromFile, toFile); + if (!(edge.toEnd !== "none" || edge.fromEnd === "arrow")) + this.registerInternalLinkAC(file.name, toFile, fromFile); + }); + } + this.trigger("resolve", file); + this.trigger("resolved"); + }), + registerInternalLinkAC: (_next) => async function(canvasName, from, to) { + var _a, _b, _c, _d; + if (from === to) return; + const fromFile = this.vault.getAbstractFileByPath(from); + if (!fromFile || !(fromFile instanceof import_obsidian8.TFile)) return; + if (!["md", "canvas"].includes(fromFile.extension)) return; + const fromFileHash = (_b = (_a = this.fileCache[from]) == null ? void 0 : _a.hash) != null ? _b : await HashHelper.getFileHash(that.plugin, fromFile); + const fromFileMetadataCache = (_c = this.metadataCache[fromFileHash]) != null ? _c : { v: 1 }; + this.metadataCache[fromFileHash] = { + ...fromFileMetadataCache, + links: [ + ...fromFileMetadataCache.links || [], + { + link: to, + original: to, + displayText: `${canvasName} \u2192 ${to}`, + position: { + start: { line: 0, col: 0, offset: 0 }, + end: { line: 0, col: 0, offset: 0 } + } + } + ] + }; + this.resolvedLinks[from] = { + ...this.resolvedLinks[from], + [to]: (((_d = this.resolvedLinks[from]) == null ? void 0 : _d[to]) || 0) + 1 + }; + } + }); + this.plugin.registerEvent(this.plugin.app.vault.on("modify", (file) => { + if (FilepathHelper.extension(file.path) !== "canvas") return; + this.plugin.app.metadataCache.computeFileMetadataAsync(file); + })); + } +}; + +// src/patchers/backlinks-patcher.ts +var import_obsidian9 = require("obsidian"); +var BacklinksPatcher = class extends Patcher { + constructor() { + super(...arguments); + this.isRecomputingBacklinks = false; + } + async patch() { + if (!this.plugin.settings.getSetting("canvasMetadataCompatibilityEnabled")) return; + const that = this; + await Patcher.waitForViewRequest(this.plugin, "backlink", (view) => { + Patcher.patchPrototype(this.plugin, view.backlink, { + recomputeBacklink: Patcher.OverrideExisting((next) => function(file, ...args) { + that.isRecomputingBacklinks = true; + const result = next.call(this, file, ...args); + that.isRecomputingBacklinks = false; + return result; + }) + }); + }); + Patcher.patchPrototype(this.plugin, this.plugin.app.vault, { + recurseChildrenAC: (_next) => function(origin, traverse) { + for (let stack = [origin]; stack.length > 0; ) { + const current = stack.pop(); + if (current) { + traverse(current); + if (current instanceof import_obsidian9.TFolder) stack = stack.concat(current.children); + } + } + }, + getMarkdownFiles: Patcher.OverrideExisting((next) => function(...args) { + if (!that.isRecomputingBacklinks) return next.call(this, ...args); + const files = []; + const root = this.getRoot(); + this.recurseChildrenAC(root, (child) => { + if (child instanceof import_obsidian9.TFile && (child.extension === "md" || child.extension === "canvas")) { + files.push(child); + } + }); + return files; + }) + }); + } +}; + +// src/patchers/outgoing-links-patcher.ts +var OutgoingLinksPatcher = class extends Patcher { + async patch() { + if (!this.plugin.settings.getSetting("canvasMetadataCompatibilityEnabled")) return; + const that = this; + await Patcher.waitForViewRequest(this.plugin, "outgoing-link", (view) => { + Patcher.patchPrototype(this.plugin, view.outgoingLink, { + recomputeLinks: Patcher.OverrideExisting((next) => function(...args) { + var _a; + const isCanvas = ((_a = this.file) == null ? void 0 : _a.extension) === "canvas"; + if (isCanvas) this.file.extension = "md"; + const result = next.call(this, ...args); + if (isCanvas) this.file.extension = "canvas"; + return result; + }), + recomputeUnlinked: Patcher.OverrideExisting((next) => function(...args) { + var _a; + const isCanvas = ((_a = this.file) == null ? void 0 : _a.extension) === "canvas"; + if (isCanvas) this.file.extension = "md"; + const result = next.call(this, ...args); + if (isCanvas) this.file.extension = "canvas"; + return result; + }) + }); + }); + } +}; + +// src/patchers/properties-patcher.ts +var PropertiesPatcher = class extends Patcher { + async patch() { + if (!this.plugin.settings.getSetting("canvasMetadataCompatibilityEnabled")) return; + if (!this.plugin.app.viewRegistry.viewByType["file-properties"]) return; + const that = this; + await Patcher.waitForViewRequest(this.plugin, "file-properties", (view) => { + Patcher.patchPrototype(this.plugin, view, { + isSupportedFile: Patcher.OverrideExisting((next) => function(file) { + if ((file == null ? void 0 : file.extension) === "canvas") return true; + return next.call(this, file); + }), + updateFrontmatter: Patcher.OverrideExisting((next) => function(file, content) { + var _a, _b, _c; + if ((file == null ? void 0 : file.extension) === "canvas") { + let frontmatter; + try { + frontmatter = (_c = (_b = (_a = JSON.parse(content)) == null ? void 0 : _a.metadata) == null ? void 0 : _b.frontmatter) != null ? _c : {}; + } catch (e) { + frontmatter = {}; + } + this.rawFrontmatter = JSON.stringify(frontmatter, null, 2); + this.frontmatter = frontmatter; + return frontmatter; + } + return next.call(this, file, content); + }), + saveFrontmatter: Patcher.OverrideExisting((next) => function(frontmatter) { + var _a; + if (((_a = this.file) == null ? void 0 : _a.extension) === "canvas") { + if (this.file !== this.modifyingFile) return; + this.app.vault.process(this.file, (data) => { + const content = JSON.parse(data); + if (content == null ? void 0 : content.metadata) content.metadata.frontmatter = frontmatter; + return JSON.stringify(content, null, 2); + }); + return; + } + return next.call(this, frontmatter); + }) + }); + }); + } +}; + +// src/patchers/search-patcher.ts +var SearchPatcher = class extends Patcher { + async patch() { + if (!this.plugin.settings.getSetting("canvasMetadataCompatibilityEnabled")) return; + const that = this; + await Patcher.waitForViewRequest(this.plugin, "search", (view) => { + const uninstallers = []; + Patcher.patchThisAndPrototype(this.plugin, view, { + startSearch: (next) => function(...args) { + const result = next.call(this, ...args); + if (this.searchQuery) { + that.patchSearchQuery(this.searchQuery); + uninstallers.forEach((uninstall) => uninstall()); + } + return result; + } + }, uninstallers); + }); + } + patchSearchQuery(searchQuery) { + Patcher.patchThisAndPrototype(this.plugin, searchQuery, { + _match: Patcher.OverrideExisting((next) => function(data) { + var _a, _b; + const isCanvas = (_b = (_a = data.strings.filepath) == null ? void 0 : _a.endsWith(".canvas")) != null ? _b : false; + if (isCanvas && !data.cache) + data.cache = this.app.metadataCache.getCache(data.strings.filepath); + return next.call(this, data); + }) + }); + } +}; + +// src/patchers/search-command-patcher.ts +var import_obsidian10 = require("obsidian"); +var SearchCommandPatcher = class extends Patcher { + async patch() { + if (!this.plugin.settings.getSetting("nativeFileSearchEnabled")) return; + const that = this; + Patcher.patch(this.plugin, this.plugin.app.commands.commands["editor:open-search"], { + checkCallback: Patcher.OverrideExisting((next) => function(checking) { + if (that.plugin.app.workspace.activeEditor) return next.call(this, checking); + const activeCanvasView = that.plugin.getCurrentCanvasView(); + if (!activeCanvasView) return next.call(this, checking); + if (checking) return true; + if (!activeCanvasView.canvas.searchEl) new CanvasSearchView(activeCanvasView); + return true; + }) + }); + } +}; +var CanvasSearchView = class { + constructor(view) { + this.searchMatches = []; + this.matchIndex = 0; + this.view = view; + this.createSearchView(); + } + createSearchView() { + this.containerEl = document.createElement("div"); + this.containerEl.className = "document-search-container"; + const documentSearch = document.createElement("div"); + documentSearch.className = "document-search"; + this.containerEl.appendChild(documentSearch); + const searchInputContainer = document.createElement("div"); + searchInputContainer.className = "search-input-container document-search-input"; + documentSearch.appendChild(searchInputContainer); + this.searchInput = document.createElement("input"); + this.searchInput.type = "text"; + this.searchInput.placeholder = "Find..."; + this.searchInput.addEventListener("keydown", (e) => this.onKeyDown(e)); + this.searchInput.addEventListener("input", () => this.onInput()); + searchInputContainer.appendChild(this.searchInput); + this.searchCount = document.createElement("div"); + this.searchCount.className = "document-search-count"; + this.searchCount.style.display = "none"; + this.searchCount.textContent = "0 / 0"; + searchInputContainer.appendChild(this.searchCount); + const documentSearchButtons = document.createElement("div"); + documentSearchButtons.className = "document-search-buttons"; + documentSearch.appendChild(documentSearchButtons); + const previousButton = document.createElement("button"); + previousButton.className = "clickable-icon document-search-button"; + previousButton.setAttribute("aria-label", "Previous\nShift + F3"); + previousButton.setAttribute("data-tooltip-position", "top"); + (0, import_obsidian10.setIcon)(previousButton, "arrow-up"); + previousButton.addEventListener("click", () => this.changeMatch(this.matchIndex - 1)); + documentSearchButtons.appendChild(previousButton); + const nextButton = document.createElement("button"); + nextButton.className = "clickable-icon document-search-button"; + nextButton.setAttribute("aria-label", "Next\nF3"); + nextButton.setAttribute("data-tooltip-position", "top"); + (0, import_obsidian10.setIcon)(nextButton, "arrow-down"); + nextButton.addEventListener("click", () => this.changeMatch(this.matchIndex + 1)); + documentSearchButtons.appendChild(nextButton); + const closeButton = document.createElement("button"); + closeButton.className = "clickable-icon document-search-close-button"; + closeButton.setAttribute("aria-label", "Exit search"); + closeButton.setAttribute("data-tooltip-position", "top"); + (0, import_obsidian10.setIcon)(closeButton, "x"); + closeButton.addEventListener("click", () => this.close()); + documentSearch.appendChild(closeButton); + this.view.canvas.wrapperEl.appendChild(this.containerEl); + this.view.canvas.searchEl = this.containerEl; + this.searchInput.focus(); + } + onKeyDown(e) { + if (e.key === "Enter" || e.key === "F3") + this.changeMatch(this.matchIndex + (e.shiftKey ? -1 : 1)); + else if (e.key === "Escape") + this.close(); + } + onInput() { + const hasQuery = this.searchInput.value.length > 0; + this.searchCount.style.display = hasQuery ? "block" : "none"; + if (!hasQuery) this.searchMatches = []; + else { + this.searchMatches = Array.from(this.view.canvas.nodes.values()).map((node) => { + const nodeData = node.getData(); + let content = void 0; + if (nodeData.type === "text") content = nodeData.text; + else if (nodeData.type === "group") content = nodeData.label; + else if (nodeData.type === "file") content = node.child.data; + if (!content) return null; + const matches = []; + const regex = new RegExp(this.searchInput.value, "gi"); + let match; + while ((match = regex.exec(content)) !== null) { + matches.push([match.index, match.index + match[0].length]); + } + return { nodeId: node.id, content, matches }; + }).filter((match) => match && match.matches.length > 0); + } + this.changeMatch(0); + } + changeMatch(index) { + if (this.searchMatches.length === 0) this.matchIndex = -1; + else { + if (index < 0) index += this.searchMatches.length; + this.matchIndex = index % this.searchMatches.length; + } + const match = this.searchMatches[this.matchIndex]; + if (match) this.goToMatch(match); + this.searchCount.textContent = `${this.matchIndex + 1} / ${this.searchMatches.length}`; + } + goToMatch(match) { + this.view.setEphemeralState({ match }); + } + close() { + this.containerEl.remove(); + this.view.canvas.searchEl = void 0; + } +}; + +// src/canvas-extensions/metadata-canvas-extension.ts +var import_obsidian11 = require("obsidian"); +var MetadataCanvasExtension = class extends CanvasExtension { + constructor() { + super(...arguments); + this.canvasCssclassesCache = /* @__PURE__ */ new Map(); + } + isEnabled() { + return true; + } + init() { + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:canvas-changed", + (canvas) => this.onCanvasChanged(canvas) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:canvas-metadata-changed", + (canvas) => this.onMetadataChanged(canvas) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:canvas-view-unloaded:before", + (view) => this.onCanvasViewUnloaded(view) + )); + } + onCanvasChanged(canvas) { + var _a; + let metadata = (_a = canvas.data) == null ? void 0 : _a.metadata; + if (!metadata || metadata.version !== CURRENT_SPEC_VERSION) + return new import_obsidian11.Notice("Metadata node not found or version mismatch. Should have been migrated (but wasn't)."); + const that = this; + const validator = { + get(target, key) { + if (typeof target[key] === "object" && target[key] !== null) + return new Proxy(target[key], validator); + else return target[key]; + }, + set(target, key, value) { + target[key] = value; + that.plugin.app.workspace.trigger("advanced-canvas:canvas-metadata-changed", canvas); + canvas.requestSave(); + return true; + } + }; + canvas.metadata = new Proxy(metadata, validator); + this.plugin.app.workspace.trigger("advanced-canvas:canvas-metadata-changed", canvas); + } + onMetadataChanged(canvas) { + var _a, _b, _c; + if (this.canvasCssclassesCache.has(canvas.view)) + canvas.wrapperEl.classList.remove(...this.canvasCssclassesCache.get(canvas.view)); + const currentClasses = (_c = (_b = (_a = canvas.metadata) == null ? void 0 : _a.frontmatter) == null ? void 0 : _b.cssclasses) != null ? _c : []; + this.canvasCssclassesCache.set(canvas.view, currentClasses); + if (currentClasses.length > 0) canvas.wrapperEl.classList.add(...currentClasses); + } + onCanvasViewUnloaded(view) { + this.canvasCssclassesCache.delete(view); + } +}; + +// src/utils/modal-helper.ts +var import_obsidian12 = require("obsidian"); +var AbstractSelectionModal = class extends import_obsidian12.FuzzySuggestModal { + constructor(app, placeholder, suggestions) { + super(app); + this.suggestions = suggestions; + this.setPlaceholder(placeholder); + this.setInstructions([{ + command: "\u2191\u2193", + purpose: "to navigate" + }, { + command: "esc", + purpose: "to dismiss" + }]); + } + getItems() { + return this.suggestions; + } + getItemText(item) { + return item; + } + onChooseItem(item, evt) { + } + awaitInput() { + return new Promise((resolve, _reject) => { + this.onChooseItem = (item) => { + resolve(item); + }; + this.open(); + }); + } +}; +var FileNameModal = class extends import_obsidian12.SuggestModal { + constructor(app, parentPath, fileExtension) { + super(app); + this.parentPath = parentPath.replace(/^\//, "").replace(/\/$/, ""); + this.fileExtension = fileExtension; + } + getSuggestions(query) { + const queryWithoutExtension = query.replace(new RegExp(`\\.${this.fileExtension}$`), ""); + if (queryWithoutExtension === "") return []; + const queryWithExtension = queryWithoutExtension + "." + this.fileExtension; + const suggestions = [queryWithExtension]; + if (this.parentPath.length > 0) suggestions.splice(0, 0, `${this.parentPath}/${queryWithExtension}`); + return suggestions.filter((s) => this.app.vault.getAbstractFileByPath(s) === null); + } + renderSuggestion(text, el) { + el.setText(text); + } + onChooseSuggestion(_text, _evt) { + } + awaitInput() { + return new Promise((resolve, _reject) => { + this.onChooseSuggestion = (text) => { + resolve(text); + }; + this.open(); + }); + } +}; +var FileSelectModal = class extends import_obsidian12.SuggestModal { + constructor(app, extensionsRegex, suggestNewFile = false) { + super(app); + this.files = this.app.vault.getFiles().map((file) => file.path).filter((path) => { + var _a; + return (_a = FilepathHelper.extension(path)) == null ? void 0 : _a.match(extensionsRegex != null ? extensionsRegex : /.*/); + }); + this.suggestNewFile = suggestNewFile; + this.setPlaceholder("Type to search..."); + this.setInstructions([{ + command: "\u2191\u2193", + purpose: "to navigate" + }, { + command: "\u21B5", + purpose: "to open" + }, { + command: "shift \u21B5", + purpose: "to create" + }, { + command: "esc", + purpose: "to dismiss" + }]); + this.scope.register(["Shift"], "Enter", (e) => { + this.onChooseSuggestion(this.inputEl.value, e); + this.close(); + }); + } + getSuggestions(query) { + const suggestions = this.files.filter((path) => path.toLowerCase().includes(query.toLowerCase())); + if (suggestions.length === 0 && this.suggestNewFile) suggestions.push(query); + return suggestions; + } + renderSuggestion(path, el) { + const simplifiedPath = path.replace(/\.md$/, ""); + el.setText(simplifiedPath); + } + onChooseSuggestion(_path, _evt) { + } + awaitInput() { + return new Promise((resolve, _reject) => { + this.onChooseSuggestion = (path, _evt) => { + const file = this.app.vault.getAbstractFileByPath(path); + if (file instanceof import_obsidian12.TFile) + return resolve(file); + if (!this.suggestNewFile) return; + if (FilepathHelper.extension(path) === void 0) path += ".md"; + const newFile = this.app.vault.create(path, ""); + resolve(newFile); + }; + this.open(); + }); + } +}; + +// src/canvas-extensions/node-ratio-canvas-extension.ts +var NodeRatioCanvasExtension = class extends CanvasExtension { + isEnabled() { + return true; + } + init() { + this.plugin.registerEvent(this.plugin.app.workspace.on( + "canvas:node-menu", + (menu, node) => this.onNodeMenu(menu, node) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-resized", + (canvas, node) => this.onNodeResized(canvas, node) + )); + } + onNodeMenu(menu, node) { + if (!this.plugin.settings.getSetting("aspectRatioControlFeatureEnabled")) return; + menu.addItem((item) => { + item.setTitle("Set Aspect Ratio").setIcon("aspect-ratio").onClick(async () => { + const NO_RATIO = "No ratio enforcement"; + const newRatioString = await new AbstractSelectionModal(this.plugin.app, "Enter aspect ratio (width:height)", ["16:9", "4:3", "3:2", "1:1", NO_RATIO]).awaitInput(); + const nodeData = node.getData(); + if (newRatioString === NO_RATIO) { + node.setData({ + ...nodeData, + ratio: void 0 + }); + return; + } + const [width, height] = newRatioString.split(":").map(Number); + if (width && height) { + node.setData({ + ...nodeData, + ratio: width / height + }); + node.setData({ + ...node.getData(), + width: nodeData.height * (width / height) + }); + } + }); + }); + } + onNodeResized(_canvas, node) { + const nodeData = node.getData(); + if (!nodeData.ratio) return; + const nodeBBox = node.getBBox(); + const nodeSize = { + width: nodeBBox.maxX - nodeBBox.minX, + height: nodeBBox.maxY - nodeBBox.minY + }; + const nodeAspectRatio = nodeSize.width / nodeSize.height; + if (nodeAspectRatio < nodeData.ratio) + nodeSize.width = nodeSize.height * nodeData.ratio; + else nodeSize.height = nodeSize.width / nodeData.ratio; + node.setData({ + ...nodeData, + width: nodeSize.width, + height: nodeSize.height + }); + } +}; + +// src/canvas-extensions/group-canvas-extension.ts +var GROUP_NODE_SIZE = { width: 300, height: 300 }; +var GroupCanvasExtension = class extends CanvasExtension { + isEnabled() { + return true; + } + init() { + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:canvas-changed", + (canvas) => { + CanvasHelper.addCardMenuOption( + canvas, + CanvasHelper.createCardMenuOption( + canvas, + { + id: "create-group", + label: "Drag to add group", + icon: "group" + }, + () => GROUP_NODE_SIZE, + (canvas2, pos) => { + canvas2.createGroupNode({ + pos, + size: GROUP_NODE_SIZE + }); + } + ) + ); + } + )); + } +}; + +// src/canvas-extensions/presentation-canvas-extension.ts +var import_obsidian13 = require("obsidian"); +var START_SLIDE_NAME = "Start Slide"; +var DEFAULT_SLIDE_NAME = "New Slide"; +var PresentationCanvasExtension = class extends CanvasExtension { + constructor() { + super(...arguments); + this.savedViewport = null; + this.isPresentationMode = false; + this.visitedNodeIds = []; + this.fullscreenModalObserver = null; + this.presentationUsesFullscreen = false; + } + isEnabled() { + return "presentationFeatureEnabled"; + } + init() { + this.plugin.registerEvent(this.plugin.app.workspace.on( + "canvas:selection-menu", + (menu, canvas) => { + menu.addItem( + (item) => item.setTitle("Wrap in slide").setIcon("gallery-vertical").onClick(() => this.addSlide( + canvas, + void 0, + BBoxHelper.enlargeBBox(BBoxHelper.combineBBoxes( + [...canvas.selection.values()].map((element) => element.getBBox()) + ), this.plugin.settings.getSetting("wrapInSlidePadding")) + )) + ); + } + )); + this.plugin.addCommand({ + id: "create-new-slide", + name: "Create new slide", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (canvas) => !canvas.readonly && !this.isPresentationMode, + (canvas) => this.addSlide(canvas) + ) + }); + this.plugin.addCommand({ + id: "set-start-node", + name: "Set start node", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (canvas) => !canvas.readonly && !this.isPresentationMode && canvas.getSelectionData().nodes.length === 1, + (canvas) => this.setStartNode(canvas, canvas.nodes.get(canvas.getSelectionData().nodes[0].id)) + ) + }); + this.plugin.addCommand({ + id: "start-presentation", + name: "Start presentation", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (_canvas) => !this.isPresentationMode, + (canvas) => this.startPresentation(canvas) + ) + }); + this.plugin.addCommand({ + id: "continue-presentation", + name: "Continue presentation", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (_canvas) => !this.isPresentationMode, + (canvas) => this.startPresentation(canvas, true) + ) + }); + this.plugin.addCommand({ + id: "end-presentation", + name: "End presentation", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (_canvas) => this.isPresentationMode, + (canvas) => this.endPresentation(canvas) + ) + }); + this.plugin.addCommand({ + id: "previous-node", + name: "Previous node", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (_canvas) => this.isPresentationMode, + (canvas) => this.previousNode(canvas) + ) + }); + this.plugin.addCommand({ + id: "next-node", + name: "Next node", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (_canvas) => this.isPresentationMode, + (canvas) => this.nextNode(canvas) + ) + }); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:canvas-changed", + (canvas) => this.onCanvasChanged(canvas) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:popup-menu-created", + (canvas) => this.onPopupMenuCreated(canvas) + )); + } + onCanvasChanged(canvas) { + CanvasHelper.addCardMenuOption( + canvas, + CanvasHelper.createCardMenuOption( + canvas, + { + id: "new-slide", + label: "Drag to add slide", + icon: "gallery-vertical" + }, + () => this.getDefaultSlideSize(), + (canvas2, pos) => this.addSlide(canvas2, pos) + ) + ); + } + onPopupMenuCreated(canvas) { + if (!this.plugin.settings.getSetting("showSetStartNodeInPopup")) return; + const selectedNodesData = canvas.getSelectionData().nodes; + if (canvas.readonly || selectedNodesData.length !== 1 || canvas.selection.size > 1) return; + const selectedNode = canvas.nodes.get(selectedNodesData[0].id); + if (!selectedNode) return; + CanvasHelper.addPopupMenuOption( + canvas, + CanvasHelper.createPopupMenuOption({ + id: "start-node", + label: "Set as start slide", + icon: "play", + callback: () => this.setStartNode(canvas, selectedNode) + }) + ); + } + setStartNode(canvas, node) { + if (!node) return; + canvas.metadata["startNode"] = node.getData().id; + } + getDefaultSlideSize() { + const slideSize = this.plugin.settings.getSetting("defaultSlideDimensions"); + return { width: slideSize[0], height: slideSize[1] }; + } + getSlideAspectRatio() { + const slideSize = this.getDefaultSlideSize(); + return slideSize.width / slideSize.height; + } + addSlide(canvas, pos, bbox) { + const isStartNode = canvas.metadata["startNode"] === void 0; + const slideSize = this.getDefaultSlideSize(); + const slideAspectRatio = this.getSlideAspectRatio(); + if (bbox) { + const bboxWidth = bbox.maxX - bbox.minX; + const bboxHeight = bbox.maxY - bbox.minY; + if (bboxWidth / bboxHeight > slideAspectRatio) { + slideSize.width = bboxWidth; + slideSize.height = bboxWidth / slideAspectRatio; + } else { + slideSize.height = bboxHeight; + slideSize.width = bboxHeight * slideAspectRatio; + } + pos = { + x: bbox.minX, + y: bbox.minY + }; + } + if (!pos) pos = CanvasHelper.getCenterCoordinates(canvas, this.getDefaultSlideSize()); + const groupNode = canvas.createGroupNode({ + pos, + size: slideSize, + label: isStartNode ? START_SLIDE_NAME : DEFAULT_SLIDE_NAME, + focus: false + }); + groupNode.setData({ + ...groupNode.getData(), + ratio: slideAspectRatio + }); + if (isStartNode) canvas.metadata["startNode"] = groupNode.getData().id; + } + async animateNodeTransition(canvas, fromNode, toNode) { + const removePadding = this.plugin.settings.getSetting("zoomToSlideWithoutPadding"); + const animationDurationMs = this.plugin.settings.getSetting("slideTransitionAnimationDuration") * 1e3; + const toNodeBBox = CanvasHelper.getSmallestAllowedZoomBBox(canvas, toNode.getBBox()); + const toNodeBBoxPadded = removePadding ? toNodeBBox : BBoxHelper.enlargeBBox(toNodeBBox, 50); + console.log({ toNodeBBox, toNodeBBoxPadded }); + if (animationDurationMs > 0 && fromNode) { + const animationIntensity = this.plugin.settings.getSetting("slideTransitionAnimationIntensity"); + const fromNodeBBox = CanvasHelper.getSmallestAllowedZoomBBox(canvas, fromNode.getBBox()); + const fromNodeBBoxPadded = removePadding ? fromNodeBBox : BBoxHelper.enlargeBBox(fromNodeBBox, 50); + const currentNodeBBoxEnlarged = BBoxHelper.scaleBBox(fromNodeBBoxPadded, animationIntensity); + canvas.zoomToRealBbox(currentNodeBBoxEnlarged); + await sleep(animationDurationMs / 2); + if (fromNode.getData().id !== toNode.getData().id) { + const nextNodeBBoxEnlarged = BBoxHelper.scaleBBox(toNodeBBoxPadded, animationIntensity); + canvas.zoomToRealBbox(nextNodeBBoxEnlarged); + await sleep(animationDurationMs / 2); + } + } + canvas.zoomToRealBbox(toNodeBBoxPadded); + } + async startPresentation(canvas, tryContinue = false) { + if (!tryContinue || this.visitedNodeIds.length === 0) { + const startNode2 = canvas.metadata["startNode"] && canvas.nodes.get(canvas.metadata["startNode"]); + if (!startNode2) { + new import_obsidian13.Notice("No start node found. Please mark a node as a start node trough the popup menu."); + return; + } + this.visitedNodeIds = [startNode2.getData().id]; + } + this.savedViewport = { + x: canvas.tx, + y: canvas.ty, + zoom: canvas.tZoom + }; + const shouldEnterFullscreen = this.plugin.settings.getSetting("fullscreenPresentationEnabled"); + this.presentationUsesFullscreen = shouldEnterFullscreen; + canvas.wrapperEl.focus(); + canvas.wrapperEl.classList.add("presentation-mode"); + if (shouldEnterFullscreen) { + try { + await canvas.wrapperEl.requestFullscreen(); + } catch (_err) { + this.presentationUsesFullscreen = false; + } + } + canvas.setReadonly(true); + if (this.plugin.settings.getSetting("useUnclampedZoomWhilePresenting")) + canvas.screenshotting = true; + canvas.wrapperEl.onkeydown = (e) => { + if (e.key === "Escape") { + e.preventDefault(); + e.stopPropagation(); + this.endPresentation(canvas); + return; + } + if (this.plugin.settings.getSetting("useArrowKeysToChangeSlides")) { + if (e.key === "ArrowRight") this.nextNode(canvas); + else if (e.key === "ArrowLeft") this.previousNode(canvas); + } + if (this.plugin.settings.getSetting("usePgUpPgDownKeysToChangeSlides")) { + if (e.key === "PageDown") this.nextNode(canvas); + else if (e.key === "PageUp") this.previousNode(canvas); + } + }; + if (this.presentationUsesFullscreen) { + this.fullscreenModalObserver = new MutationObserver((mutationRecords) => { + mutationRecords.forEach((mutationRecord) => { + mutationRecord.addedNodes.forEach((node) => { + var _a; + document.body.removeChild(node); + (_a = document.fullscreenElement) == null ? void 0 : _a.appendChild(node); + }); + }); + const inputField = document.querySelector(".prompt-input"); + if (inputField) inputField.focus(); + }); + this.fullscreenModalObserver.observe(document.body, { childList: true }); + canvas.wrapperEl.onfullscreenchange = (_e) => { + if (document.fullscreenElement) return; + this.endPresentation(canvas); + }; + } + this.isPresentationMode = true; + if (this.presentationUsesFullscreen) + await sleep(500); + const startNodeId = this.visitedNodeIds.first(); + if (!startNodeId) return; + const startNode = canvas.nodes.get(startNodeId); + if (!startNode) return; + this.animateNodeTransition(canvas, void 0, startNode); + } + endPresentation(canvas) { + var _a; + if (!this.isPresentationMode) return; + if (this.presentationUsesFullscreen) { + (_a = this.fullscreenModalObserver) == null ? void 0 : _a.disconnect(); + this.fullscreenModalObserver = null; + canvas.wrapperEl.onfullscreenchange = null; + if (document.fullscreenElement) document.exitFullscreen(); + } + canvas.wrapperEl.onkeydown = null; + canvas.setReadonly(false); + if (this.plugin.settings.getSetting("useUnclampedZoomWhilePresenting")) + canvas.screenshotting = false; + canvas.wrapperEl.classList.remove("presentation-mode"); + if (this.plugin.settings.getSetting("resetViewportOnPresentationEnd")) + canvas.setViewport(this.savedViewport.x, this.savedViewport.y, this.savedViewport.zoom); + this.isPresentationMode = false; + this.presentationUsesFullscreen = false; + } + nextNode(canvas) { + var _a; + const fromNodeId = this.visitedNodeIds.last(); + if (!fromNodeId) return; + const fromNode = canvas.nodes.get(fromNodeId); + if (!fromNode) return; + const outgoingEdges = canvas.getEdgesForNode(fromNode).filter((edge) => edge.from.node.getData().id === fromNodeId); + let toNode = (_a = outgoingEdges.first()) == null ? void 0 : _a.to.node; + if (outgoingEdges.length > 1) { + const sortedEdges = outgoingEdges.sort((a, b) => { + if (!a.label) return 1; + if (!b.label) return -1; + return a.label.localeCompare(b.label); + }); + const traversedEdgesCount = this.visitedNodeIds.filter((visitedNodeId) => visitedNodeId === fromNodeId).length - 1; + const nextEdge = sortedEdges[traversedEdgesCount]; + toNode = nextEdge.to.node; + } + if (toNode) { + this.visitedNodeIds.push(toNode.getData().id); + this.animateNodeTransition(canvas, fromNode, toNode); + } else { + this.animateNodeTransition(canvas, fromNode, fromNode); + } + } + previousNode(canvas) { + const fromNodeId = this.visitedNodeIds.pop(); + if (!fromNodeId) return; + const fromNode = canvas.nodes.get(fromNodeId); + if (!fromNode) return; + const toNodeId = this.visitedNodeIds.last(); + let toNode = toNodeId ? canvas.nodes.get(toNodeId) : null; + if (!toNode) { + toNode = fromNode; + this.visitedNodeIds.push(fromNodeId); + } + this.animateNodeTransition(canvas, fromNode, toNode); + } +}; + +// src/canvas-extensions/z-ordering-canvas-extension.ts +var ZOrderingCanvasExtension = class extends CanvasExtension { + isEnabled() { + return "zOrderingControlFeatureEnabled"; + } + init() { + this.plugin.registerEvent(this.plugin.app.workspace.on( + "canvas:node-menu", + (menu, node) => this.nodeContextMenu(node, menu) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "canvas:selection-menu", + (menu, canvas) => this.selectionContextMenu(canvas, menu) + )); + } + nodeContextMenu(node, menu) { + this.addZOrderingContextMenuItems(node.canvas, [node], menu); + } + selectionContextMenu(canvas, menu) { + const selectedNodes = canvas.getSelectionData().nodes.map((nodeData) => canvas.nodes.get(nodeData.id)).filter((node) => node !== void 0); + this.addZOrderingContextMenuItems(canvas, selectedNodes, menu); + } + addZOrderingContextMenuItems(canvas, nodes, menu) { + menu.addSeparator(); + if (this.plugin.settings.getSetting("zOrderingControlShowOneLayerShiftOptions") && nodes.length === 1) { + menu.addItem((item) => { + item.setTitle("Move one layer forward"); + item.setIcon("arrow-up"); + item.onClick(() => this.moveOneLayer(canvas, nodes.first(), true)); + }); + menu.addItem((item) => { + item.setTitle("Move one layer backward"); + item.setIcon("arrow-down"); + item.onClick(() => this.moveOneLayer(canvas, nodes.first(), false)); + }); + } + menu.addItem((item) => { + item.setTitle("Bring to Front"); + item.setIcon("bring-to-front"); + item.onClick(() => this.moveMaxLayers(canvas, nodes, true)); + }); + menu.addItem((item) => { + item.setTitle("Send to Back"); + item.setIcon("send-to-back"); + item.onClick(() => this.moveMaxLayers(canvas, nodes, false)); + }); + if (nodes.some((node) => node.getData().zIndex !== void 0)) { + menu.addItem((item) => { + item.setTitle("Remove persistent z-index"); + item.setIcon("pin-off"); + item.onClick(() => this.removePersistentZIndexes(canvas, nodes)); + }); + } + menu.addSeparator(); + } + moveOneLayer(canvas, selectedNode, forward) { + const selectedNodeBBox = selectedNode.getBBox(); + const collidingNodes = [...canvas.nodes.values()].filter((node) => BBoxHelper.isColliding(selectedNodeBBox, node.getBBox())).filter((node) => node !== selectedNode); + const nearestZIndexNode = collidingNodes.sort((a, b) => forward ? a.zIndex - b.zIndex : b.zIndex - a.zIndex).filter((node) => forward ? node.zIndex > selectedNode.zIndex : node.zIndex < selectedNode.zIndex).first(); + if (nearestZIndexNode === void 0) return; + const targetZIndex = nearestZIndexNode.zIndex; + this.setNodesZIndex([nearestZIndexNode], selectedNode.zIndex); + this.setNodesZIndex([selectedNode], targetZIndex); + } + moveMaxLayers(canvas, selectedNodes, forward) { + let targetZIndex = forward ? Math.max(...this.getAllZIndexes(canvas)) + 1 : Math.min(...this.getAllZIndexes(canvas)) - selectedNodes.length; + this.setNodesZIndex(selectedNodes, targetZIndex); + } + removePersistentZIndexes(_canvas, nodes) { + for (const node of nodes) node.setZIndex(void 0); + } + setNodesZIndex(nodes, zIndex) { + const sortedNodes = nodes.sort((a, b) => a.zIndex - b.zIndex); + for (let i = 0; i < sortedNodes.length; i++) { + const node = sortedNodes[i]; + const finalZIndex = zIndex + i; + node.setZIndex(finalZIndex); + } + } + getAllZIndexes(canvas) { + return [...canvas.nodes.values()].map((n) => n.zIndex); + } +}; + +// src/canvas-extensions/better-readonly-canvas-extension.ts +var BetterReadonlyCanvasExtension = class extends CanvasExtension { + constructor() { + super(...arguments); + this.isMovingToBBox = false; + } + isEnabled() { + return "betterReadonlyEnabled"; + } + init() { + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:popup-menu-created", + (canvas) => this.updatePopupMenu(canvas) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:viewport-changed:before", + (canvas) => this.onBeforeViewPortChanged(canvas) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:zoom-to-bbox:before", + () => this.isMovingToBBox = true + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:readonly-changed", + (canvas, _readonly) => { + this.updatePopupMenu(canvas); + this.updateLockedZoom(canvas); + this.updateLockedPan(canvas); + } + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:canvas-changed", + (canvas) => this.addQuickSettings(canvas) + )); + } + onBeforeViewPortChanged(canvas) { + var _a, _b, _c, _d, _e, _f; + if (this.isMovingToBBox) { + this.isMovingToBBox = false; + this.updateLockedZoom(canvas); + this.updateLockedPan(canvas); + return; + } + if (!canvas.readonly) return; + if (this.plugin.settings.getSetting("disableZoom")) { + canvas.zoom = (_a = canvas.lockedZoom) != null ? _a : canvas.zoom; + canvas.tZoom = (_b = canvas.lockedZoom) != null ? _b : canvas.tZoom; + } + if (this.plugin.settings.getSetting("disablePan")) { + canvas.x = (_c = canvas.lockedX) != null ? _c : canvas.x; + canvas.tx = (_d = canvas.lockedX) != null ? _d : canvas.tx; + canvas.y = (_e = canvas.lockedY) != null ? _e : canvas.y; + canvas.ty = (_f = canvas.lockedY) != null ? _f : canvas.ty; + } + } + addQuickSettings(canvas) { + var _a; + const settingsContainer = (_a = canvas.quickSettingsButton) == null ? void 0 : _a.parentElement; + if (!settingsContainer) return; + CanvasHelper.addControlMenuButton( + settingsContainer, + this.createToggle({ + id: "disable-node-popup", + label: "Disable node popup", + icon: "arrow-up-right-from-circle", + callback: () => this.updatePopupMenu(canvas) + }, "disableNodePopup") + ); + CanvasHelper.addControlMenuButton( + settingsContainer, + this.createToggle({ + id: "disable-zoom", + label: "Disable zoom", + icon: "zoom-in", + callback: () => this.updateLockedZoom(canvas) + }, "disableZoom") + ); + CanvasHelper.addControlMenuButton( + settingsContainer, + this.createToggle({ + id: "disable-pan", + label: "Disable pan", + icon: "move", + callback: () => this.updateLockedPan(canvas) + }, "disablePan") + ); + } + createToggle(menuOption, settingKey) { + const toggle = CanvasHelper.createControlMenuButton({ + ...menuOption, + callback: () => (async () => { + var _a; + const newValue = !this.plugin.settings.getSetting(settingKey); + await this.plugin.settings.setSetting({ [settingKey]: newValue }); + toggle.dataset.toggled = this.plugin.settings.getSetting(settingKey).toString(); + (_a = menuOption.callback) == null ? void 0 : _a.call(this); + })() + }); + toggle.classList.add("show-while-readonly"); + toggle.dataset.toggled = this.plugin.settings.getSetting(settingKey).toString(); + return toggle; + } + updatePopupMenu(canvas) { + const hidden = canvas.readonly && this.plugin.settings.getSetting("disableNodePopup"); + canvas.menu.menuEl.style.visibility = hidden ? "hidden" : "visible"; + } + updateLockedZoom(canvas) { + canvas.lockedZoom = canvas.tZoom; + } + updateLockedPan(canvas) { + canvas.lockedX = canvas.tx; + canvas.lockedY = canvas.ty; + } +}; + +// src/canvas-extensions/encapsulate-canvas-extension.ts +var ENCAPSULATED_FILE_NODE_SIZE = { width: 300, height: 300 }; +var EncapsulateCanvasExtension = class extends CanvasExtension { + isEnabled() { + return "canvasEncapsulationEnabled"; + } + init() { + this.plugin.addCommand({ + id: "encapsulate-selection", + name: "Encapsulate selection", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (canvas) => !canvas.readonly && canvas.selection.size > 0, + (canvas) => this.encapsulateSelection(canvas) + ) + }); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "canvas:selection-menu", + (menu, canvas) => { + menu.addItem( + (item) => item.setTitle("Encapsulate").setIcon("file-plus").onClick(() => this.encapsulateSelection(canvas)) + ); + } + )); + } + async encapsulateSelection(canvas) { + var _a, _b, _c, _d; + const selection = canvas.getSelectionData(); + const canvasSettings = this.plugin.app.internalPlugins.plugins.canvas.instance.options; + const defaultNewCanvasLocation = canvasSettings.newFileLocation; + let targetFolderPath = this.plugin.app.vault.getRoot().path; + if (defaultNewCanvasLocation === "current") targetFolderPath = (_c = (_b = (_a = canvas.view.file) == null ? void 0 : _a.parent) == null ? void 0 : _b.path) != null ? _c : targetFolderPath; + else if (defaultNewCanvasLocation === "folder") targetFolderPath = (_d = canvasSettings.newFileFolderPath) != null ? _d : targetFolderPath; + const targetFilePath = await new FileNameModal( + this.plugin.app, + targetFolderPath, + "canvas" + ).awaitInput(); + const newFileData = { nodes: selection.nodes, edges: selection.edges }; + const file = await this.plugin.app.vault.create(targetFilePath, JSON.stringify(newFileData, null, 2)); + for (const nodeData of selection.nodes) { + const node = canvas.nodes.get(nodeData.id); + if (node) canvas.removeNode(node); + } + canvas.createFileNode({ + pos: { + x: selection.center.x - ENCAPSULATED_FILE_NODE_SIZE.width / 2, + y: selection.center.y - ENCAPSULATED_FILE_NODE_SIZE.height / 2 + }, + size: ENCAPSULATED_FILE_NODE_SIZE, + file + }); + } +}; + +// src/canvas-extensions/commands-canvas-extension.ts +var import_obsidian14 = require("obsidian"); +var DIRECTIONS = ["up", "down", "left", "right"]; +var CommandsCanvasExtension = class extends CanvasExtension { + isEnabled() { + return "commandsFeatureEnabled"; + } + init() { + this.plugin.addCommand({ + id: "toggle-readonly", + name: "Toggle readonly", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (_canvas) => true, + (canvas) => canvas.setReadonly(!canvas.readonly) + ) + }); + this.plugin.addCommand({ + id: "create-text-node", + name: "Create text node", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (canvas) => !canvas.readonly, + (canvas) => this.createTextNode(canvas) + ) + }); + this.plugin.addCommand({ + id: "create-file-node", + name: "Create file node", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (canvas) => !canvas.readonly, + (canvas) => this.createFileNode(canvas) + ) + }); + this.plugin.addCommand({ + id: "select-all-edges", + name: "Select all edges", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (_canvas) => true, + (canvas) => canvas.updateSelection( + () => canvas.selection = new Set(canvas.edges.values()) + ) + ) + }); + this.plugin.addCommand({ + id: "zoom-to-selection", + name: "Zoom to selection", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (canvas) => canvas.selection.size > 0, + (canvas) => canvas.zoomToSelection() + ) + }); + this.plugin.addCommand({ + id: "zoom-to-fit", + name: "Zoom to fit", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (_canvas) => true, + (canvas) => canvas.zoomToFit() + ) + }); + for (const direction of DIRECTIONS) { + this.plugin.addCommand({ + id: `clone-node-${direction}`, + name: `Clone node ${direction}`, + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (canvas) => { + var _a; + return !canvas.readonly && canvas.selection.size === 1 && ((_a = canvas.selection.values().next().value) == null ? void 0 : _a.getData().type) === "text"; + }, + (canvas) => this.cloneNode(canvas, direction) + ) + }); + this.plugin.addCommand({ + id: `expand-node-${direction}`, + name: `Expand node ${direction}`, + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (canvas) => !canvas.readonly && canvas.selection.size === 1, + (canvas) => this.expandNode(canvas, direction) + ) + }); + this.plugin.addCommand({ + id: `navigate-${direction}`, + name: `Navigate ${direction}`, + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (canvas) => canvas.getSelectionData().nodes.length === 1, + (canvas) => this.navigate(canvas, direction) + ) + }); + } + this.plugin.addCommand({ + id: "flip-selection-horizontally", + name: "Flip selection horizontally", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (canvas) => !canvas.readonly && canvas.selection.size > 0, + (canvas) => this.flipSelection( + canvas, + true + ) + ) + }); + this.plugin.addCommand({ + id: "flip-selection-vertically", + name: "Flip selection vertically", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (canvas) => !canvas.readonly && canvas.selection.size > 0, + (canvas) => this.flipSelection(canvas, false) + ) + }); + this.plugin.addCommand({ + id: "select-connected-edges", + name: "Select connected edges", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (canvas) => canvas.selection.size > 0, + (canvas) => CanvasHelper.selectEdgesForNodes(canvas, "connected") + ) + }); + this.plugin.addCommand({ + id: "select-incoming-edges", + name: "Select incoming edges", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (canvas) => canvas.selection.size > 0, + (canvas) => CanvasHelper.selectEdgesForNodes(canvas, "incoming") + ) + }); + this.plugin.addCommand({ + id: "select-outgoing-edges", + name: "Select outgoing edges", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (canvas) => canvas.selection.size > 0, + (canvas) => CanvasHelper.selectEdgesForNodes(canvas, "outgoing") + ) + }); + this.plugin.addCommand({ + id: "swap-nodes", + name: "Swap nodes", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (canvas) => !canvas.readonly && canvas.getSelectionData().nodes.length === 2, + (canvas) => { + const selectedNodes = canvas.getSelectionData().nodes.map((nodeData) => canvas.nodes.get(nodeData.id)).filter((node) => node !== void 0); + if (selectedNodes.length !== 2) return; + const [nodeA, nodeB] = selectedNodes; + const nodeAData = nodeA.getData(); + const nodeBData = nodeB.getData(); + nodeA.setData({ ...nodeAData, x: nodeBData.x, y: nodeBData.y, width: nodeBData.width, height: nodeBData.height }); + nodeB.setData({ ...nodeBData, x: nodeAData.x, y: nodeAData.y, width: nodeAData.width, height: nodeAData.height }); + canvas.pushHistory(canvas.getData()); + } + ) + }); + this.plugin.addCommand({ + id: "copy-wikilink-to-node", + name: "Copy wikilink to node", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (canvas) => !canvas.readonly && canvas.selection.size === 1, + (canvas) => { + const file = canvas.view.file; + if (!file) return; + const nodeData = canvas.getSelectionData().nodes[0]; + if (!nodeData) return; + const wikilink = `[[${file.path}#${nodeData.id}|${file.name} (${TextHelper.toTitleCase(nodeData.type)} node)]]`; + navigator.clipboard.writeText(wikilink); + new import_obsidian14.Notice("Copied wikilink to node to clipboard.", 2e3); + } + ) + }); + this.plugin.addCommand({ + id: "pull-outgoing-links-to-canvas", + name: "Pull outgoing links to canvas", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (canvas) => !canvas.readonly, + (canvas) => { + var _a, _b, _c; + const canvasFile = canvas.view.file; + if (!canvasFile) return; + let selectedNodeIds = canvas.getSelectionData().nodes.map((node) => node.id); + if (selectedNodeIds.length === 0) selectedNodeIds = [...canvas.nodes.keys()]; + const metadata = this.plugin.app.metadataCache.getFileCache(canvasFile); + if (!metadata) return; + const outgoingLinks = /* @__PURE__ */ new Set(); + for (const nodeId of selectedNodeIds) { + let relativeFile = canvasFile; + let nodeOutgoingLinks = (_b = (_a = metadata.nodes) == null ? void 0 : _a[nodeId]) == null ? void 0 : _b.links; + if (!nodeOutgoingLinks) { + const file = (_c = canvas.nodes.get(nodeId)) == null ? void 0 : _c.file; + if (!file) continue; + const fileMetadata = this.plugin.app.metadataCache.getFileCache(file); + nodeOutgoingLinks = fileMetadata == null ? void 0 : fileMetadata.links; + relativeFile = file; + } + if (!nodeOutgoingLinks) continue; + for (const nodeOutgoingLink of nodeOutgoingLinks) { + const resolvedLink = this.plugin.app.metadataCache.getFirstLinkpathDest(nodeOutgoingLink.link, relativeFile.path); + if (!(resolvedLink instanceof import_obsidian14.TFile)) continue; + outgoingLinks.add(resolvedLink); + } + } + const existingFileNodes = /* @__PURE__ */ new Set([canvas.view.file]); + for (const node of canvas.nodes.values()) { + if (node.getData().type !== "file" || !node.file) continue; + existingFileNodes.add(node.file); + } + for (const outgoingLink of outgoingLinks) { + if (existingFileNodes.has(outgoingLink)) continue; + this.createFileNode(canvas, outgoingLink); + } + } + ) + }); + this.plugin.addCommand({ + id: "pull-backlinks-to-canvas", + name: "Pull backlinks to canvas", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (canvas) => !canvas.readonly, + (canvas) => { + const canvasFile = canvas.view.file; + if (!canvasFile) return; + let selectedNodesData = canvas.getSelectionData().nodes.map((node) => node); + const backlinks = /* @__PURE__ */ new Set(); + if (selectedNodesData.length > 0) { + for (const nodeData of selectedNodesData) { + if (nodeData.type !== "file" || !nodeData.file) continue; + const file = this.plugin.app.vault.getFileByPath(nodeData.file); + if (!file) continue; + const nodeBacklinks = this.plugin.app.metadataCache.getBacklinksForFile(file); + if (!nodeBacklinks) continue; + for (const nodeBacklink of nodeBacklinks.data.keys()) { + const resolvedLink = this.plugin.app.metadataCache.getFirstLinkpathDest(nodeBacklink, file.path); + if (!(resolvedLink instanceof import_obsidian14.TFile)) continue; + backlinks.add(resolvedLink); + } + } + } else { + const canvasBacklinks = this.plugin.app.metadataCache.getBacklinksForFile(canvasFile); + if (!canvasBacklinks) return; + for (const canvasBacklink of canvasBacklinks.data.keys()) { + const resolvedLink = this.plugin.app.metadataCache.getFirstLinkpathDest(canvasBacklink, canvasFile.path); + if (!(resolvedLink instanceof import_obsidian14.TFile)) continue; + backlinks.add(resolvedLink); + } + } + const existingFileNodes = /* @__PURE__ */ new Set([canvas.view.file]); + for (const node of canvas.nodes.values()) { + if (node.getData().type !== "file" || !node.file) continue; + existingFileNodes.add(node.file); + } + for (const backlink of backlinks) { + if (existingFileNodes.has(backlink)) continue; + this.createFileNode(canvas, backlink); + } + } + ) + }); + } + createTextNode(canvas) { + const size = canvas.config.defaultTextNodeDimensions; + const pos = CanvasHelper.getCenterCoordinates(canvas, size); + canvas.createTextNode({ pos, size }); + } + async createFileNode(canvas, file) { + const size = canvas.config.defaultFileNodeDimensions; + const pos = CanvasHelper.getCenterCoordinates(canvas, size); + file != null ? file : file = await new FileSelectModal(this.plugin.app, void 0, true).awaitInput(); + canvas.createFileNode({ pos, size, file }); + } + cloneNode(canvas, cloneDirection) { + const sourceNode = canvas.selection.values().next().value; + if (!sourceNode) return; + const sourceNodeData = sourceNode.getData(); + const nodeMargin = this.plugin.settings.getSetting("cloneNodeMargin"); + const offset = { + x: (sourceNode.width + nodeMargin) * (cloneDirection === "left" ? -1 : cloneDirection === "right" ? 1 : 0), + y: (sourceNode.height + nodeMargin) * (cloneDirection === "up" ? -1 : cloneDirection === "down" ? 1 : 0) + }; + const clonedNode = canvas.createTextNode({ + pos: { + x: sourceNode.x + offset.x, + y: sourceNode.y + offset.y + }, + size: { + width: sourceNode.width, + height: sourceNode.height + } + }); + clonedNode.setData({ + ...clonedNode.getData(), + color: sourceNodeData.color, + styleAttributes: sourceNodeData.styleAttributes + }); + if (this.plugin.settings.getSetting("zoomToClonedNode")) + canvas.zoomToBbox(clonedNode.getBBox()); + } + expandNode(canvas, expandDirection) { + const node = canvas.selection.values().next().value; + if (!node) return; + const expandNodeStepSize = this.plugin.settings.getSetting("expandNodeStepSize"); + const expand = { + x: expandDirection === "left" ? -1 : expandDirection === "right" ? 1 : 0, + y: expandDirection === "up" ? -1 : expandDirection === "down" ? 1 : 0 + }; + node.setData({ + ...node.getData(), + width: node.width + expand.x * expandNodeStepSize, + height: node.height + expand.y * expandNodeStepSize + }); + } + flipSelection(canvas, horizontally) { + const selectionData = canvas.getSelectionData(); + if (selectionData.nodes.length === 0) return; + const nodeIds = /* @__PURE__ */ new Set(); + for (const nodeData of selectionData.nodes) { + nodeIds.add(nodeData.id); + const node = canvas.nodes.get(nodeData.id); + if (!node) continue; + const newX = horizontally ? 2 * selectionData.center.x - nodeData.x - nodeData.width : nodeData.x; + const newY = horizontally ? nodeData.y : 2 * selectionData.center.y - nodeData.y - nodeData.height; + node.setData({ + ...nodeData, + x: newX, + y: newY + }); + } + for (const edge of canvas.edges.values()) { + const edgeData = edge.getData(); + let newFromSide = edgeData.fromSide; + if (nodeIds.has(edgeData.fromNode) && BBoxHelper.isHorizontal(edgeData.fromSide) === horizontally) + newFromSide = BBoxHelper.getOppositeSide(edgeData.fromSide); + let newToSide = edgeData.toSide; + if (nodeIds.has(edgeData.toNode) && BBoxHelper.isHorizontal(edgeData.toSide) === horizontally) + newToSide = BBoxHelper.getOppositeSide(edgeData.toSide); + edge.setData({ + ...edgeData, + fromSide: newFromSide, + toSide: newToSide + }); + } + canvas.pushHistory(canvas.getData()); + } + navigate(canvas, direction) { + const node = this.getNextNode(canvas, direction); + if (!node) return; + canvas.updateSelection(() => { + canvas.selection = /* @__PURE__ */ new Set([node]); + }); + } + getNextNode(canvas, direction) { + var _a; + const selectedNodeData = (_a = canvas.getSelectionData().nodes) == null ? void 0 : _a.first(); + if (!selectedNodeData) return; + const selectedNodeBBox = { + minX: selectedNodeData.x, + minY: selectedNodeData.y, + maxX: selectedNodeData.x + selectedNodeData.width, + maxY: selectedNodeData.y + selectedNodeData.height + }; + const possibleTargetNodes = Array.from(canvas.nodes.values()).filter((node) => { + const nodeData = node.getData(); + return nodeData.id !== selectedNodeData.id && (nodeData.type === "text" || nodeData.type === "file"); + }); + const closestNode = possibleTargetNodes.reduce((closestNode2, node) => { + const nodeBBox = node.getBBox(); + const isInVerticalRange = selectedNodeBBox.minY <= nodeBBox.maxY && selectedNodeBBox.maxY >= nodeBBox.minY; + const isInHorizontalRange = selectedNodeBBox.minX <= nodeBBox.maxX && selectedNodeBBox.maxX >= nodeBBox.minX; + if (["up", "down"].includes(direction) && !isInHorizontalRange) return closestNode2; + if (["left", "right"].includes(direction) && !isInVerticalRange) return closestNode2; + let distance = -1; + switch (direction) { + case "up": + distance = selectedNodeBBox.minY - nodeBBox.maxY; + break; + case "down": + distance = nodeBBox.minY - selectedNodeBBox.maxY; + break; + case "left": + distance = selectedNodeBBox.minX - nodeBBox.maxX; + break; + case "right": + distance = nodeBBox.minX - selectedNodeBBox.maxX; + break; + } + if (distance < 0) return closestNode2; + if (!closestNode2) return { node, distance }; + if (distance < closestNode2.distance) return { node, distance }; + if (distance === closestNode2.distance) { + const selectedNodeCenter = { + x: selectedNodeData.x + selectedNodeData.width / 2, + y: selectedNodeData.y + selectedNodeData.height / 2 + }; + const closestNodeCenter = { + x: closestNode2.node.x + closestNode2.node.width / 2, + y: closestNode2.node.y + closestNode2.node.height / 2 + }; + const nodeCenter = { + x: node.x + node.width / 2, + y: node.y + node.height / 2 + }; + const closestNodeDistance = Math.sqrt( + Math.pow(selectedNodeCenter.x - closestNodeCenter.x, 2) + Math.pow(selectedNodeCenter.y - closestNodeCenter.y, 2) + ); + const nodeDistance = Math.sqrt( + Math.pow(selectedNodeCenter.x - nodeCenter.x, 2) + Math.pow(selectedNodeCenter.y - nodeCenter.y, 2) + ); + if (nodeDistance < closestNodeDistance) return { node, distance }; + } + return closestNode2; + }, null); + return closestNode == null ? void 0 : closestNode.node; + } +}; + +// src/canvas-extensions/auto-resize-node-canvas-extension.ts +var AutoResizeNodeCanvasExtension = class extends CanvasExtension { + isEnabled() { + return "autoResizeNodeFeatureEnabled"; + } + init() { + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-created", + (canvas, node) => this.onNodeCreated(canvas, node) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:popup-menu-created", + (canvas) => this.onPopupMenuCreated(canvas) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-editing-state-changed", + (canvas, node, editing) => this.onNodeEditingStateChanged(canvas, node, editing) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-text-content-changed", + (canvas, node, viewUpdate) => this.onNodeTextContentChanged(canvas, node, viewUpdate.view.dom) + )); + } + isValidNodeType(nodeData) { + return nodeData.type === "text" || nodeData.type === "file" && nodeData.file.endsWith(".md"); + } + onNodeCreated(_canvas, node) { + const autoResizeNodeEnabledByDefault = this.plugin.settings.getSetting("autoResizeNodeEnabledByDefault"); + if (!autoResizeNodeEnabledByDefault) return; + const nodeData = node.getData(); + if (nodeData.type !== "text" && nodeData.type !== "file") return; + node.setData({ + ...node.getData(), + dynamicHeight: true + }); + } + onPopupMenuCreated(canvas) { + if (canvas.readonly) return; + const selectedNodes = canvas.getSelectionData().nodes.filter((nodeData) => this.isValidNodeType(nodeData)).map((nodeData) => canvas.nodes.get(nodeData.id)).filter((node) => node !== void 0); + if (selectedNodes.length === 0) return; + const autoResizeHeightEnabled = selectedNodes.some((node) => node.getData().dynamicHeight); + CanvasHelper.addPopupMenuOption( + canvas, + CanvasHelper.createPopupMenuOption({ + id: "auto-resize-height", + label: autoResizeHeightEnabled ? "Disable auto-resize" : "Enable auto-resize", + icon: autoResizeHeightEnabled ? "scan-text" : "lock", + callback: () => this.toggleAutoResizeHeightEnabled(canvas, selectedNodes, autoResizeHeightEnabled) + }) + ); + } + toggleAutoResizeHeightEnabled(canvas, nodes, autoResizeHeight) { + nodes.forEach((node) => node.setData({ + ...node.getData(), + dynamicHeight: !autoResizeHeight + })); + this.onPopupMenuCreated(canvas); + } + canBeResized(node) { + const nodeData = node.getData(); + return nodeData.dynamicHeight; + } + async onNodeEditingStateChanged(_canvas, node, editing) { + if (!this.isValidNodeType(node.getData())) return; + if (!this.canBeResized(node)) return; + await sleep(10); + if (editing) { + this.onNodeTextContentChanged(_canvas, node, node.child.editMode.cm.dom); + return; + } + const renderedMarkdownContainer = node.nodeEl.querySelector(".markdown-preview-view.markdown-rendered"); + if (!renderedMarkdownContainer) return; + renderedMarkdownContainer.style.height = "min-content"; + let newHeight = renderedMarkdownContainer.clientHeight; + renderedMarkdownContainer.style.removeProperty("height"); + this.setNodeHeight(node, newHeight); + } + async onNodeTextContentChanged(_canvas, node, dom) { + if (!this.isValidNodeType(node.getData())) return; + if (!this.canBeResized(node)) return; + const cmScroller = dom.querySelector(".cm-scroller"); + if (!cmScroller) return; + cmScroller.style.height = "min-content"; + const newHeight = cmScroller.scrollHeight; + cmScroller.style.removeProperty("height"); + this.setNodeHeight(node, newHeight); + } + setNodeHeight(node, height) { + if (height === 0) return; + const maxHeight = this.plugin.settings.getSetting("autoResizeNodeMaxHeight"); + if (maxHeight != -1 && height > maxHeight) height = maxHeight; + const nodeData = node.getData(); + height = Math.max(height, node.canvas.config.minContainerDimension); + if (this.plugin.settings.getSetting("autoResizeNodeSnapToGrid")) + height = Math.ceil(height / CanvasHelper.GRID_SIZE) * CanvasHelper.GRID_SIZE; + node.setData({ + ...nodeData, + height + }); + } +}; + +// src/canvas-extensions/portals-canvas-extension.ts +var import_obsidian15 = require("obsidian"); +var PORTAL_PADDING = 50; +var MIN_OPEN_PORTAL_SIZE = { width: 200, height: 200 }; +var PortalsCanvasExtension = class _PortalsCanvasExtension extends CanvasExtension { + isEnabled() { + return "portalsFeatureEnabled"; + } + init() { + this.plugin.registerEvent(this.plugin.app.vault.on("modify", (file) => { + for (const canvas of this.plugin.getCanvases()) + this.onFileModified(canvas, file); + })); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:popup-menu-created", + (canvas) => this.onPopupMenu(canvas) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-removed", + (canvas, node) => this.onNodeRemoved(canvas, node) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-moved", + (canvas, node, _keyboard) => this.onNodeMoved(canvas, node) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-resized", + (canvas, node) => this.onNodeResized(canvas, node) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:dragging-state-changed", + (canvas, startedDragging) => this.onDraggingStateChanged(canvas, startedDragging) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:containing-nodes-requested", + (canvas, bbox, nodes) => this.onContainingNodesRequested(canvas, bbox, nodes) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:edge-connection-try-dragging:before", + (canvas, edge, event, cancelRef) => this.onEdgeConnectionTryDraggingBefore(canvas, edge, event, cancelRef) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:edge-connection-dragging:after", + (canvas, edge, event, newEdge, side, previousEnds) => this.onEdgeConnectionDraggingAfter(canvas, edge, event, newEdge, side, previousEnds) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:selection-changed", + (canvas, oldSelection, updateSelection) => this.onSelectionChanged(canvas, oldSelection, updateSelection) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:data-requested", + (canvas, data) => this.onGetData(canvas, data) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:data-loaded:before", + (canvas, data, setData) => { + this.onSetData(canvas, data).then((newData) => { + if (newData.nodes.length === data.nodes.length && newData.edges.length === data.edges.length) return; + setData(newData); + }); + } + )); + } + onFileModified(canvas, file) { + const isAffected = Object.values(canvas.nodes).filter( + (nodeData) => nodeData.getData().type === "file" && nodeData.currentPortalFile === file.path + ).length > 0; + if (!isAffected) return; + canvas.setData(canvas.getData()); + canvas.history.current--; + canvas.history.data.pop(); + } + onContainingNodesRequested(_canvas, _bbox, nodes) { + const filteredNodes = nodes.filter((node) => !_PortalsCanvasExtension.isPortalElement(node)); + nodes.splice(0, nodes.length, ...filteredNodes); + } + onSelectionChanged(canvas, _oldSelection, updateSelection) { + updateSelection(() => { + const updatedSelection = Array.from(canvas.selection).filter((canvasElement) => !_PortalsCanvasExtension.isPortalElement(canvasElement)); + canvas.selection = new Set(updatedSelection); + }); + } + onDraggingStateChanged(canvas, startedDragging) { + if (!startedDragging) return; + if (!canvas.getSelectionData().nodes.some((node) => node.type === "file" && node.portal)) return; + const objectSnappingEnabled = canvas.options.snapToObjects; + if (!objectSnappingEnabled) return; + canvas.toggleObjectSnapping(false); + const dragEndEventRef = this.plugin.app.workspace.on( + "advanced-canvas:dragging-state-changed", + (canvas2, startedDragging2) => { + if (startedDragging2) return; + canvas2.toggleObjectSnapping(objectSnappingEnabled); + this.plugin.app.workspace.offref(dragEndEventRef); + } + ); + this.plugin.registerEvent(dragEndEventRef); + } + onNodeMoved(canvas, portalNode) { + const portalNodeData = portalNode.getData(); + if (portalNodeData.type !== "file" || !portalNodeData.isPortalLoaded) return; + const nestedNodes = this.getContainingNodes(canvas, portalNode); + const containingNodesBBox = CanvasHelper.getBBox(nestedNodes); + const portalOffset = { + x: portalNodeData.x - containingNodesBBox.minX + PORTAL_PADDING, + y: portalNodeData.y - containingNodesBBox.minY + PORTAL_PADDING + }; + for (const nestedNode of nestedNodes) { + const nestedNodeData = nestedNode.getData(); + nestedNode.setData({ + ...nestedNodeData, + x: nestedNodeData.x + portalOffset.x, + y: nestedNodeData.y + portalOffset.y + }); + } + } + onNodeResized(_canvas, portalNode) { + const portalNodeData = portalNode.getData(); + if (portalNodeData.type !== "file" || !portalNodeData.isPortalLoaded) return; + portalNode.setData({ + ...portalNodeData, + x: portalNode.prevX ? portalNode.prevX : portalNodeData.x, + y: portalNode.prevY ? portalNode.prevY : portalNodeData.y, + width: portalNode.prevWidth ? portalNode.prevWidth : portalNodeData.width, + height: portalNode.prevHeight ? portalNode.prevHeight : portalNodeData.height + }); + } + onNodeRemoved(canvas, portalNode) { + const portalNodeData = portalNode.getData(); + if (portalNodeData.type !== "file" || !portalNodeData.portal) return; + for (const node of this.getContainingNodes(canvas, portalNode, false)) + canvas.removeNode(node); + for (const edge of this.getContainingEdges(canvas, portalNode, false)) + canvas.removeEdge(edge); + } + onEdgeConnectionTryDraggingBefore(_canvas, edge, _event, cancelRef) { + if (!_PortalsCanvasExtension.isPortalElement(edge)) return; + cancelRef.value = true; + new import_obsidian15.Notice("Updating edges from portals is not supported yet."); + } + onEdgeConnectionDraggingAfter(canvas, edge, _event, _newEdge, _side, _previousEnds) { + if (_PortalsCanvasExtension.isPortalElement(edge)) return; + if (!_PortalsCanvasExtension.isPortalElement(edge.from.node) || !_PortalsCanvasExtension.isPortalElement(edge.to.node)) return; + canvas.removeEdge(edge); + new import_obsidian15.Notice("Creating edges with both ends in portals are not supported yet."); + } + onPopupMenu(canvas) { + if (canvas.readonly) return; + const selectedFileNodes = canvas.getSelectionData().nodes.map((nodeData) => { + var _a; + const node = canvas.nodes.get(nodeData.id); + if (!node) return null; + if (nodeData.type !== "file") return null; + if (((_a = node.file) == null ? void 0 : _a.extension) === "canvas") return node; + if (nodeData.portal) this.setPortalOpen(canvas, node, false); + return null; + }).filter((node) => node !== null); + if (selectedFileNodes.length !== 1) return; + const portalNode = selectedFileNodes.first(); + const portalNodeData = portalNode.getData(); + if (portalNodeData.portal && portalNodeData.file !== portalNode.currentPortalFile) + this.setPortalOpen(canvas, portalNode, true); + CanvasHelper.addPopupMenuOption( + canvas, + CanvasHelper.createPopupMenuOption({ + id: "toggle-portal", + label: portalNodeData.portal ? "Close portal" : "Open portal", + icon: portalNodeData.portal ? "door-open" : "door-closed", + callback: () => { + this.setPortalOpen(canvas, portalNode, !portalNodeData.portal); + this.onPopupMenu(canvas); + } + }) + ); + } + setPortalOpen(canvas, portalNode, open) { + const portalNodeData = portalNode.getData(); + portalNode.setData({ + ...portalNodeData, + portal: open + }); + portalNode.currentPortalFile = open ? portalNodeData.file : void 0; + canvas.setData(canvas.getData()); + } + // Remove all edges and nodes from portals + onGetData(_canvas, data) { + data.nodes = data.nodes.filter((nodeData) => _PortalsCanvasExtension.getNestedIds(nodeData.id).length === 1); + for (const nodeData of data.nodes) delete nodeData.isPortalLoaded; + const portalsIdMap = new Map( + data.nodes.filter((nodeData) => nodeData.portal).map((nodeData) => [nodeData.id, nodeData]) + ); + data.edges = data.edges.filter((edgeData) => { + var _a; + if (_PortalsCanvasExtension.getNestedIds(edgeData.id).length > 1) return false; + const isFromNodeFromPortal = _PortalsCanvasExtension.getNestedIds(edgeData.fromNode).length > 1; + const isToNodeFromPortal = _PortalsCanvasExtension.getNestedIds(edgeData.toNode).length > 1; + if (!isFromNodeFromPortal && !isToNodeFromPortal) return true; + if (isFromNodeFromPortal && isToNodeFromPortal) return false; + const targetPortalId = this.getParentPortalId(isFromNodeFromPortal ? edgeData.fromNode : edgeData.toNode); + const targetPortalData = portalsIdMap.get(targetPortalId); + if (!targetPortalData) return false; + (_a = targetPortalData.interdimensionalEdges) != null ? _a : targetPortalData.interdimensionalEdges = []; + targetPortalData.interdimensionalEdges.push(edgeData); + return false; + }); + } + // Add all edges and nodes from portals + async onSetData(canvas, dataRef) { + const data = JSON.parse(JSON.stringify(dataRef)); + const addedData = await Promise.all(data.nodes.map((nodeData) => this.tryOpenPortal(canvas, nodeData))); + for (const newData of addedData) { + data.nodes.push(...newData.nodes); + data.edges.push(...newData.edges); + } + for (const nodeData of data.nodes) { + if (nodeData.type !== "file" || !nodeData.isPortalLoaded) continue; + const interdimensionalEdges = nodeData.interdimensionalEdges; + if (!interdimensionalEdges) continue; + for (const edge of interdimensionalEdges) data.edges.push(edge); + delete nodeData.interdimensionalEdges; + } + return data; + } + async tryOpenPortal(canvas, portalNodeData, nestedPortalFiles = /* @__PURE__ */ new Set()) { + const addedData = { nodes: [], edges: [] }; + if (portalNodeData.type !== "file" || !portalNodeData.portal) return addedData; + if (portalNodeData.file === canvas.view.file.path) return addedData; + if (nestedPortalFiles.has(portalNodeData.file)) return addedData; + nestedPortalFiles.add(portalNodeData.file); + const portalFile = this.plugin.app.vault.getAbstractFileByPath(portalNodeData.file); + if (!(portalFile instanceof import_obsidian15.TFile) || portalFile.extension !== "canvas") return addedData; + const portalFileDataString = await this.plugin.app.vault.cachedRead(portalFile); + if (portalFileDataString === "") return addedData; + const portalFileData = JSON.parse(portalFileDataString); + if (!portalFileData) return addedData; + portalNodeData.isPortalLoaded = true; + const sourceMinCoordinates = CanvasHelper.getBBox(portalFileData.nodes); + const portalOffset = { + x: portalNodeData.x - sourceMinCoordinates.minX + PORTAL_PADDING, + y: portalNodeData.y - sourceMinCoordinates.minY + PORTAL_PADDING + }; + for (const nodeDataFromPortal of portalFileData.nodes) { + const newNodeId = `${portalNodeData.id}-${nodeDataFromPortal.id}`; + const addedNode = { + ...nodeDataFromPortal, + id: newNodeId, + x: nodeDataFromPortal.x + portalOffset.x, + y: nodeDataFromPortal.y + portalOffset.y + }; + addedData.nodes.push(addedNode); + const nestedNodes = await this.tryOpenPortal(canvas, addedNode, nestedPortalFiles); + addedData.nodes.push(...nestedNodes.nodes); + addedData.edges.push(...nestedNodes.edges); + } + for (const edgeDataFromPortal of portalFileData.edges) { + const newEdgeId = `${portalNodeData.id}-${edgeDataFromPortal.id}`; + const fromNodeId = `${portalNodeData.id}-${edgeDataFromPortal.fromNode}`; + const toNodeId = `${portalNodeData.id}-${edgeDataFromPortal.toNode}`; + addedData.edges.push({ + ...edgeDataFromPortal, + id: newEdgeId, + fromNode: fromNodeId, + toNode: toNodeId + }); + } + const targetSize = this.getPortalSize(CanvasHelper.getBBox(addedData.nodes)); + portalNodeData.width = targetSize.width; + portalNodeData.height = targetSize.height; + return addedData; + } + // Helper functions + getPortalSize(sourceBBox) { + const sourceSize = { + width: sourceBBox.maxX - sourceBBox.minX, + height: sourceBBox.maxY - sourceBBox.minY + }; + const targetSize = { + width: Math.max(sourceSize.width + PORTAL_PADDING * 2, MIN_OPEN_PORTAL_SIZE.width), + height: Math.max(sourceSize.height + PORTAL_PADDING * 2, MIN_OPEN_PORTAL_SIZE.height) + }; + if (!Number.isFinite(targetSize.width)) targetSize.width = MIN_OPEN_PORTAL_SIZE.width; + if (!Number.isFinite(targetSize.height)) targetSize.height = MIN_OPEN_PORTAL_SIZE.height; + return targetSize; + } + getContainingNodes(canvas, portalNode, directChildren = true) { + return Array.from(canvas.nodes.values()).filter((node) => this.isChildOfPortal(portalNode.getData(), node.getData(), directChildren)); + } + getContainingEdges(canvas, portalNode, directChildren = true) { + return Array.from(canvas.edges.values()).filter((edge) => this.isChildOfPortal(portalNode.getData(), edge.getData(), directChildren)); + } + getParentPortalId(elementId) { + const nestedIds = _PortalsCanvasExtension.getNestedIds(elementId); + if (nestedIds.length < 2) return void 0; + return nestedIds.slice(0, -1).join("-"); + } + static getNestedIds(id) { + return id.split("-"); + } + static isPortalElement(canvasElement) { + return this.getNestedIds(canvasElement.id).length > 1; + } + isChildOfPortal(portal, canvasElement, directChild = true) { + return canvasElement.id !== portal.id && // Not the portal itself + canvasElement.id.startsWith(portal.id) && // Is a child of the portal + (!directChild || _PortalsCanvasExtension.getNestedIds(canvasElement.id).length === _PortalsCanvasExtension.getNestedIds(portal.id).length + 1); + } +}; + +// src/canvas-extensions/frontmatter-control-button-canvas-extension.ts +var import_obsidian16 = require("obsidian"); +var FrontmatterControlButtonCanvasExtension = class extends CanvasExtension { + isEnabled() { + return "canvasMetadataCompatibilityEnabled"; + } + init() { + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:canvas-changed", + (canvas) => this.addQuickSettings(canvas) + )); + } + addQuickSettings(canvas) { + var _a; + if (!canvas) return; + const settingsContainer = (_a = canvas.quickSettingsButton) == null ? void 0 : _a.parentElement; + if (!settingsContainer) return; + CanvasHelper.addControlMenuButton( + settingsContainer, + CanvasHelper.createControlMenuButton({ + id: "properties-button", + icon: "info", + label: "Properties", + callback: () => { + var _a2; + const propertiesPlugin = this.plugin.app.internalPlugins.plugins["properties"]; + if (!(propertiesPlugin == null ? void 0 : propertiesPlugin._loaded)) { + new import_obsidian16.Notice(`Core plugin "Properties view" was not found or isn't enabled. Enable it and restart Obsidian.`); + return; + } + let propertiesLeaf = (_a2 = this.plugin.app.workspace.getLeavesOfType("file-properties").first()) != null ? _a2 : null; + if (!propertiesLeaf) { + propertiesLeaf = this.plugin.app.workspace.getRightLeaf(false); + propertiesLeaf == null ? void 0 : propertiesLeaf.setViewState({ type: "file-properties" }); + } + if (propertiesLeaf) this.plugin.app.workspace.revealLeaf(propertiesLeaf); + } + }) + ); + } +}; + +// src/canvas-extensions/better-default-settings-canvas-extension.ts +var BetterDefaultSettingsCanvasExtension = class extends CanvasExtension { + isEnabled() { + return true; + } + init() { + this.modifyCanvasSettings(this.plugin.getCurrentCanvas()); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:settings-changed", + () => this.modifyCanvasSettings(this.plugin.getCurrentCanvas()) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:canvas-changed", + (canvas) => this.modifyCanvasSettings(canvas) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:double-click", + (canvas, event, preventDefault) => this.onDoubleClick(canvas, event, preventDefault) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-created", + (canvas, node) => { + this.enforceNodeGridAlignment(canvas, node); + this.applyDefaultNodeStyles(canvas, node); + } + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:edge-created", + (canvas, edge) => this.applyDefaultEdgeStyles(canvas, edge) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-resized", + (canvas, node) => this.enforceMaxNodeWidth(canvas, node) + )); + } + modifyCanvasSettings(canvas) { + if (!canvas) return; + const defaultTextNodeDimensionsArray = this.plugin.settings.getSetting("defaultTextNodeDimensions"); + canvas.config.defaultTextNodeDimensions = { + width: defaultTextNodeDimensionsArray[0], + height: defaultTextNodeDimensionsArray[1] + }; + const defaultFileNodeDimensionsArray = this.plugin.settings.getSetting("defaultFileNodeDimensions"); + canvas.config.defaultFileNodeDimensions = { + width: defaultFileNodeDimensionsArray[0], + height: defaultFileNodeDimensionsArray[1] + }; + canvas.config.minContainerDimension = this.plugin.settings.getSetting("minNodeSize"); + } + async onDoubleClick(canvas, event, preventDefault) { + if (event.defaultPrevented || event.target !== canvas.wrapperEl || canvas.isDragging || canvas.readonly) return; + preventDefault.value = true; + let pos = canvas.posFromEvt(event); + switch (this.plugin.settings.getSetting("nodeTypeOnDoubleClick")) { + case "file": + const file = await new FileSelectModal(this.plugin.app, void 0, true).awaitInput(); + canvas.createFileNode({ + pos, + position: "center", + file + }); + break; + default: + canvas.createTextNode({ + pos, + position: "center" + }); + break; + } + } + enforceNodeGridAlignment(_canvas, node) { + if (!this.plugin.settings.getSetting("alignNewNodesToGrid")) return; + const nodeData = node.getData(); + node.setData({ + ...nodeData, + x: CanvasHelper.alignToGrid(nodeData.x), + y: CanvasHelper.alignToGrid(nodeData.y) + }); + } + applyDefaultNodeStyles(_canvas, node) { + const nodeData = node.getData(); + if (nodeData.type !== "text") return; + let color = this.plugin.settings.getSetting("defaultTextNodeColor").toString(); + if (color === "0") color = void 0; + node.setData({ + ...nodeData, + color, + styleAttributes: { + ...nodeData.styleAttributes, + ...this.plugin.settings.getSetting("defaultTextNodeStyleAttributes") + } + }); + } + async applyDefaultEdgeStyles(canvas, edge) { + var _a; + const edgeData = edge.getData(); + let color = this.plugin.settings.getSetting("defaultEdgeColor").toString(); + if (this.plugin.settings.getSetting("inheritEdgeColorFromNode")) + color = (_a = edge.from.node.getData().color) != null ? _a : color; + if (color === "0") color = void 0; + edge.setData({ + ...edgeData, + color, + styleAttributes: { + ...edgeData.styleAttributes, + ...this.plugin.settings.getSetting("defaultEdgeStyleAttributes") + } + }); + if (canvas.canvasEl.hasClass("is-connecting")) { + await new Promise((resolve) => { + new MutationObserver(() => { + if (!canvas.canvasEl.hasClass("is-connecting")) resolve(); + }).observe(canvas.canvasEl, { attributes: true, attributeFilter: ["class"] }); + }); + } + const lineDirection = this.plugin.settings.getSetting("defaultEdgeLineDirection"); + edge.setData({ + ...edge.getData(), + fromEnd: lineDirection === "bidirectional" ? "arrow" : "none", + toEnd: lineDirection === "nondirectional" ? "none" : "arrow" + }); + } + enforceMaxNodeWidth(_canvas, node) { + const maxNodeWidth = this.plugin.settings.getSetting("maxNodeWidth"); + if (maxNodeWidth <= 0) return; + const nodeData = node.getData(); + if (nodeData.type !== "text" && nodeData.type !== "file" || nodeData.portal) return; + if (nodeData.width <= maxNodeWidth) return; + node.setData({ + ...nodeData, + x: node.prevX !== void 0 ? node.prevX : nodeData.x, + // Reset the position to the previous value + width: maxNodeWidth + }); + } +}; + +// src/canvas-extensions/color-palette-canvas-extension.ts +var DEFAULT_COLORS_COUNT = 6; +var CUSTOM_COLORS_MOD_STYLES_ID = "mod-custom-colors"; +var ColorPaletteCanvasExtension = class extends CanvasExtension { + constructor() { + super(...arguments); + this.observer = null; + } + isEnabled() { + return true; + } + init() { + this.plugin.registerEvent(this.plugin.app.workspace.on( + "window-open", + (_win, _window) => this.updateCustomColorModStyleClasses() + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "css-change", + () => this.updateCustomColorModStyleClasses() + )); + this.updateCustomColorModStyleClasses(); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:popup-menu-created", + (canvas) => this.patchColorSelection(canvas) + )); + this.plugin.register(() => { + var _a; + return (_a = this.observer) == null ? void 0 : _a.disconnect(); + }); + } + updateCustomColorModStyleClasses() { + var _a; + const customCss = this.getCustomColors().map((colorId) => ` + .mod-canvas-color-${colorId} { + --canvas-color: var(--canvas-color-${colorId}); + } + `).join(""); + for (const win of this.plugin.windowsManager.windows) { + const doc = win.document; + (_a = doc.getElementById(CUSTOM_COLORS_MOD_STYLES_ID)) == null ? void 0 : _a.remove(); + const customColorModStyle = doc.createElement("style"); + customColorModStyle.id = CUSTOM_COLORS_MOD_STYLES_ID; + doc.head.appendChild(customColorModStyle); + customColorModStyle.textContent = customCss; + } + } + patchColorSelection(canvas) { + if (this.observer) this.observer.disconnect(); + this.observer = new MutationObserver((mutations) => { + const colorMenuOpened = mutations.some( + (mutation) => Object.values(mutation.addedNodes).some( + (node) => node instanceof HTMLElement && node.classList.contains("canvas-submenu") && Object.values(node.childNodes).some( + (node2) => node2 instanceof HTMLElement && node2.classList.contains("canvas-color-picker-item") + ) + ) + ); + if (!colorMenuOpened) return; + const submenu = canvas.menu.menuEl.querySelector(".canvas-submenu"); + if (!submenu) return; + const currentNodeColor = canvas.getSelectionData().nodes.map((node) => node.color).last(); + for (const colorId of this.getCustomColors()) { + const customColorMenuItem = this.createColorMenuItem(canvas, colorId); + if (currentNodeColor === colorId) customColorMenuItem.classList.add("is-active"); + submenu.insertBefore(customColorMenuItem, submenu.lastChild); + } + }); + this.observer.observe(canvas.menu.menuEl, { childList: true }); + } + createColorMenuItem(canvas, colorId) { + const menuItem = document.createElement("div"); + menuItem.classList.add("canvas-color-picker-item"); + menuItem.classList.add(`mod-canvas-color-${colorId}`); + menuItem.addEventListener("click", () => { + menuItem.classList.add("is-active"); + for (const item of canvas.selection) { + item.setColor(colorId); + } + canvas.requestSave(); + }); + return menuItem; + } + getCustomColors() { + const colors = []; + while (true) { + const colorId = (DEFAULT_COLORS_COUNT + colors.length + 1).toString(); + if (!getComputedStyle(document.body).getPropertyValue(`--canvas-color-${colorId}`)) break; + colors.push(colorId); + } + return colors; + } +}; + +// src/canvas-extensions/collapsible-groups-canvas-extension.ts +var import_obsidian17 = require("obsidian"); +var CollapsibleGroupsCanvasExtension = class extends CanvasExtension { + isEnabled() { + return "collapsibleGroupsFeatureEnabled"; + } + init() { + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-changed", + (canvas, node) => this.onNodeChanged(canvas, node) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-bbox-requested", + (canvas, node, bbox) => this.onNodeBBoxRequested(canvas, node, bbox) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:copy", + (canvas, selectionData) => this.onCopy(canvas, selectionData) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:data-requested", + (_canvas, data) => this.expandNodes(data) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:data-loaded:before", + (_canvas, data, _setData) => this.collapseNodes(data) + )); + } + onNodeChanged(canvas, groupNode) { + var _a, _b; + const groupNodeData = groupNode.getData(); + if (groupNodeData.type !== "group") return; + (_a = groupNode.collapseEl) == null ? void 0 : _a.remove(); + const collapseEl = document.createElement("span"); + collapseEl.className = "collapse-button"; + (0, import_obsidian17.setIcon)(collapseEl, groupNodeData.collapsed ? "plus-circle" : "minus-circle"); + collapseEl.onclick = () => { + const groupNodeData2 = groupNode.getData(); + this.setCollapsed(canvas, groupNode, groupNodeData2.collapsed ? void 0 : true); + canvas.markMoved(groupNode); + }; + groupNode.collapseEl = collapseEl; + (_b = groupNode.labelEl) == null ? void 0 : _b.insertAdjacentElement("afterend", collapseEl); + } + onCopy(_canvas, selectionData) { + for (const collapsedGroupData of selectionData.nodes) { + if (collapsedGroupData.type !== "group" || !collapsedGroupData.collapsed || !collapsedGroupData.collapsedData) continue; + selectionData.nodes.push(...collapsedGroupData.collapsedData.nodes.map((nodeData) => ({ + ...nodeData, + // Restore the relative position of the node to the group + x: nodeData.x + collapsedGroupData.x, + y: nodeData.y + collapsedGroupData.y + }))); + selectionData.edges.push(...collapsedGroupData.collapsedData.edges); + } + } + setCollapsed(canvas, groupNode, collapsed) { + groupNode.setData({ ...groupNode.getData(), collapsed }); + canvas.setData(canvas.getData()); + canvas.history.current--; + canvas.pushHistory(canvas.getData()); + canvas.requestSave(); + } + onNodeBBoxRequested(canvas, node, bbox) { + var _a, _b; + const nodeData = node.getData(); + if (nodeData.type !== "group" || !nodeData.collapsed) return; + const collapseElBBox = (_a = node.collapseEl) == null ? void 0 : _a.getBoundingClientRect(); + if (!collapseElBBox) return; + const labelElBBox = (_b = node.labelEl) == null ? void 0 : _b.getBoundingClientRect(); + if (!labelElBBox) return; + const minPos = canvas.posFromClient({ x: collapseElBBox.left, y: collapseElBBox.top }); + const maxPos = canvas.posFromClient({ x: labelElBBox.right, y: collapseElBBox.bottom }); + bbox.minX = minPos.x; + bbox.minY = minPos.y; + bbox.maxX = maxPos.x; + bbox.maxY = maxPos.y; + } + expandNodes(data) { + data.nodes = data.nodes.flatMap((groupNodeData) => { + const collapsedData = groupNodeData.collapsedData; + if (collapsedData === void 0) return [groupNodeData]; + delete groupNodeData.collapsedData; + data.edges.push(...collapsedData.edges); + return [groupNodeData, ...collapsedData.nodes.map((nodeData) => ({ + ...nodeData, + // Restore the relative position of the node to the group + x: nodeData.x + groupNodeData.x, + y: nodeData.y + groupNodeData.y + }))]; + }); + } + collapseNodes(data) { + data.nodes.forEach((groupNodeData) => { + var _a, _b, _c, _d; + if (!groupNodeData.collapsed) return; + const groupNodeBBox = CanvasHelper.getBBox([groupNodeData]); + const containedNodesData = data.nodes.filter( + (nodeData) => nodeData.id !== groupNodeData.id && BBoxHelper.insideBBox(CanvasHelper.getBBox([nodeData]), groupNodeBBox, false) + ); + const containedEdgesData = data.edges.filter((edgeData) => { + return containedNodesData.some((nodeData) => nodeData.id === edgeData.fromNode) || containedNodesData.some((nodeData) => nodeData.id === edgeData.toNode); + }); + data.nodes = data.nodes.filter((nodeData) => !containedNodesData.includes(nodeData)); + data.edges = data.edges.filter((edgeData) => !containedEdgesData.includes(edgeData)); + const newContainedNodesData = containedNodesData.filter((nodeData) => { + var _a2, _b2, _c2; + return !((_c2 = (_b2 = (_a2 = groupNodeData.collapsedData) == null ? void 0 : _a2.nodes) == null ? void 0 : _b2.some((e) => e.id === nodeData.id)) != null ? _c2 : false); + }); + const newContainedEdgesData = containedEdgesData.filter((edgeData) => { + var _a2, _b2, _c2; + return !((_c2 = (_b2 = (_a2 = groupNodeData.collapsedData) == null ? void 0 : _a2.edges) == null ? void 0 : _b2.some((n) => n.id === edgeData.id)) != null ? _c2 : false); + }); + groupNodeData.collapsedData = { + nodes: [ + ...(_b = (_a = groupNodeData.collapsedData) == null ? void 0 : _a.nodes) != null ? _b : [], + ...newContainedNodesData.map((nodeData) => ({ + ...nodeData, + // Store the relative position of the node to the group + x: nodeData.x - groupNodeData.x, + y: nodeData.y - groupNodeData.y + })) + ], + edges: [ + ...(_d = (_c = groupNodeData.collapsedData) == null ? void 0 : _c.edges) != null ? _d : [], + ...newContainedEdgesData + ] + }; + }); + } +}; + +// src/canvas-extensions/focus-mode-canvas-extension.ts +var CONTROL_MENU_FOCUS_TOGGLE_ID = "focus-mode-toggle"; +var FocusModeCanvasExtension = class extends CanvasExtension { + isEnabled() { + return "focusModeFeatureEnabled"; + } + init() { + this.plugin.addCommand({ + id: "toggle-focus-mode", + name: "Toggle Focus Mode", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (_canvas) => true, + (canvas) => this.toggleFocusMode(canvas) + ) + }); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:canvas-changed", + (canvas) => this.addControlMenuToggle(canvas) + )); + } + addControlMenuToggle(canvas) { + var _a; + const settingsContainer = (_a = canvas.quickSettingsButton) == null ? void 0 : _a.parentElement; + if (!settingsContainer) return; + const controlMenuFocusToggle = CanvasHelper.createControlMenuButton({ + id: CONTROL_MENU_FOCUS_TOGGLE_ID, + label: "Focus Mode", + icon: "focus", + callback: () => this.toggleFocusMode(canvas) + }); + CanvasHelper.addControlMenuButton(settingsContainer, controlMenuFocusToggle); + } + toggleFocusMode(canvas) { + var _a, _b; + const controlMenuFocusToggle = (_b = (_a = canvas.quickSettingsButton) == null ? void 0 : _a.parentElement) == null ? void 0 : _b.querySelector(`#${CONTROL_MENU_FOCUS_TOGGLE_ID}`); + if (!controlMenuFocusToggle) return; + const newValue = controlMenuFocusToggle.dataset.toggled !== "true"; + canvas.wrapperEl.dataset.focusModeEnabled = newValue.toString(); + controlMenuFocusToggle.dataset.toggled = newValue.toString(); + } +}; + +// src/canvas-extensions/auto-file-node-edges-canvas-extension.ts +var AUTO_EDGE_ID_PREFIX = "afe"; +var AutoFileNodeEdgesCanvasExtension = class extends CanvasExtension { + isEnabled() { + return "autoFileNodeEdgesFeatureEnabled"; + } + init() { + this.plugin.registerEvent(this.plugin.app.metadataCache.on("changed", (file) => { + for (const canvas of this.plugin.getCanvases()) + this.onMetadataChanged(canvas, file); + })); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-added", + (canvas, node) => this.onNodeChanged(canvas, node) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-changed", + (canvas, node) => this.onNodeChanged(canvas, node) + )); + } + onMetadataChanged(canvas, file) { + var _a; + for (const node of canvas.nodes.values()) { + if (node.getData().type !== "file" || ((_a = node.file) == null ? void 0 : _a.path) !== file.path) continue; + this.updateFileNodeEdges(canvas, node); + } + } + onNodeChanged(canvas, node) { + if (node.getData().type !== "file") return; + for (const node2 of canvas.nodes.values()) { + if (node2.getData().type !== "file") continue; + this.updateFileNodeEdges(canvas, node2); + } + } + updateFileNodeEdges(canvas, node) { + const edges = this.getFileNodeEdges(canvas, node); + const newEdges = Array.from(edges.values()).filter((edge) => !canvas.edges.has(edge.id)); + canvas.importData({ nodes: [], edges: newEdges }, false, false); + for (const edge of canvas.edges.values()) { + if (edge.id.startsWith(`${AUTO_EDGE_ID_PREFIX}${node.id}`) && !edges.has(edge.id)) + canvas.removeEdge(edge); + } + } + getFileNodeEdges(canvas, node) { + var _a, _b; + const canvasFile = canvas.view.file; + if (!canvasFile || !node.file) return /* @__PURE__ */ new Map(); + const fileMetadata = this.plugin.app.metadataCache.getFileCache(node.file); + if (!fileMetadata) return /* @__PURE__ */ new Map(); + const linkedFilesFrontmatterKey = this.plugin.settings.getSetting("autoFileNodeEdgesFrontmatterKey"); + const fileLinksToBeLinkedTo = (_b = (_a = fileMetadata.frontmatterLinks) == null ? void 0 : _a.filter((link) => link.key.split(".")[0] === linkedFilesFrontmatterKey)) != null ? _b : []; + const filepathsToBeLinkedTo = fileLinksToBeLinkedTo.map((link) => this.plugin.app.metadataCache.getFirstLinkpathDest(link.link, canvasFile.path)).map((file) => file == null ? void 0 : file.path).filter((path) => path !== null); + const nodesToBeLinkedTo = Array.from(canvas.nodes.values()).filter((otherNode) => { + var _a2; + return otherNode.id !== node.id && filepathsToBeLinkedTo.includes((_a2 = otherNode.file) == null ? void 0 : _a2.path); + }); + const newEdges = /* @__PURE__ */ new Map(); + for (const otherNode of nodesToBeLinkedTo) { + const edgeId = `${AUTO_EDGE_ID_PREFIX}${node.id}${otherNode.id}`; + const bestFromSide = CanvasHelper.getBestSideForFloatingEdge(BBoxHelper.getCenterOfBBoxSide(otherNode.getBBox(), "right"), node); + const bestToSide = CanvasHelper.getBestSideForFloatingEdge(BBoxHelper.getCenterOfBBoxSide(node.getBBox(), "left"), otherNode); + newEdges.set(edgeId, { + id: edgeId, + fromNode: node.id, + fromSide: bestFromSide, + fromFloating: true, + toNode: otherNode.id, + toSide: bestToSide, + toFloating: true + }); + } + return newEdges; + } +}; + +// src/canvas-extensions/flip-edge-canvas-extension.ts +var FlipEdgeCanvasExtension = class extends CanvasExtension { + isEnabled() { + return "flipEdgeFeatureEnabled"; + } + init() { + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:popup-menu-created", + (canvas) => this.onPopupMenuCreated(canvas) + )); + } + onPopupMenuCreated(canvas) { + var _a, _b; + const popupMenuEl = (_a = canvas == null ? void 0 : canvas.menu) == null ? void 0 : _a.menuEl; + if (!popupMenuEl) return; + const POSSIBLE_ICONS = ["lucide-arrow-right", "lucide-move-horizontal", "line-horizontal"]; + let edgeDirectionButton = null; + for (const icon of POSSIBLE_ICONS) { + edgeDirectionButton = (_b = popupMenuEl.querySelector(`button:not([id]) > .svg-icon.${icon}`)) == null ? void 0 : _b.parentElement; + if (edgeDirectionButton) break; + } + if (!edgeDirectionButton) return; + edgeDirectionButton.addEventListener("click", () => this.onEdgeDirectionDropdownCreated(canvas)); + } + onEdgeDirectionDropdownCreated(canvas) { + const dropdownEl = document.body.querySelector("div.menu"); + if (!dropdownEl) return; + const separatorEl = CanvasHelper.createDropdownSeparatorElement(); + dropdownEl.appendChild(separatorEl); + const flipEdgeButton = CanvasHelper.createDropdownOptionElement({ + icon: "flip-horizontal-2", + label: "Flip Edge", + callback: () => this.flipEdge(canvas) + }); + dropdownEl.appendChild(flipEdgeButton); + } + flipEdge(canvas) { + const selectedEdges = [...canvas.selection].filter((item) => item.path !== void 0); + if (selectedEdges.length === 0) return; + for (const edge of selectedEdges) { + edge.update({ + ...edge.from, + node: edge.to.node, + side: edge.to.side + }, { + ...edge.to, + node: edge.from.node, + side: edge.from.side + }); + } + canvas.pushHistory(canvas.getData()); + } +}; + +// src/canvas-extensions/edge-selection-canvas-extension.ts +var DIRECTION_MENU_MAP = { + connected: { + id: "select-connected-edges", + icon: "arrows-selected", + label: "Select Connected Edges" + }, + outgoing: { + id: "select-outgoing-edges", + icon: "arrow-right-selected", + label: "Select Outgoing Edges" + }, + incoming: { + id: "select-incoming-edges", + icon: "arrow-left-selected", + label: "Select Incoming Edges" + } +}; +var EdgeSelectionCanvasExtension = class extends CanvasExtension { + isEnabled() { + return "edgeSelectionEnabled"; + } + init() { + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:popup-menu-created", + (canvas) => this.onPopupMenuCreated(canvas) + )); + } + onPopupMenuCreated(canvas) { + var _a; + const popupMenuEl = (_a = canvas == null ? void 0 : canvas.menu) == null ? void 0 : _a.menuEl; + if (!popupMenuEl) return; + const selectionNodeData = canvas.getSelectionData().nodes; + if (canvas.readonly || selectionNodeData.length === 0) return; + const selectEdgeByDirection = this.plugin.settings.getSetting("selectEdgeByDirection"); + const menuDirectionSet = /* @__PURE__ */ new Set(["connected"]); + if (selectionNodeData.length === 1) { + const node = canvas.nodes.get(selectionNodeData[0].id); + if (!node) return; + const edges = canvas.getEdgesForNode(node); + if (edges.length === 0) return; + if (selectEdgeByDirection) { + edges.forEach((edge) => { + if (edge.from.node === node) { + menuDirectionSet.add("outgoing"); + } else if (edge.to.node === node) { + menuDirectionSet.add("incoming"); + } + }); + } + } else if (selectEdgeByDirection) { + menuDirectionSet.add("outgoing"); + menuDirectionSet.add("incoming"); + } + menuDirectionSet.forEach((direction) => { + const config = DIRECTION_MENU_MAP[direction]; + CanvasHelper.addPopupMenuOption(canvas, CanvasHelper.createPopupMenuOption({ + ...config, + callback: () => CanvasHelper.selectEdgesForNodes(canvas, direction) + })); + }); + } +}; + +// node_modules/html-to-image/es/util.js +function resolveUrl(url, baseUrl) { + if (url.match(/^[a-z]+:\/\//i)) { + return url; + } + if (url.match(/^\/\//)) { + return window.location.protocol + url; + } + if (url.match(/^[a-z]+:/i)) { + return url; + } + const doc = document.implementation.createHTMLDocument(); + const base = doc.createElement("base"); + const a = doc.createElement("a"); + doc.head.appendChild(base); + doc.body.appendChild(a); + if (baseUrl) { + base.href = baseUrl; + } + a.href = url; + return a.href; +} +var uuid = /* @__PURE__ */ (() => { + let counter = 0; + const random = () => ( + // eslint-disable-next-line no-bitwise + `0000${(Math.random() * 36 ** 4 << 0).toString(36)}`.slice(-4) + ); + return () => { + counter += 1; + return `u${random()}${counter}`; + }; +})(); +function toArray(arrayLike) { + const arr = []; + for (let i = 0, l = arrayLike.length; i < l; i++) { + arr.push(arrayLike[i]); + } + return arr; +} +function px(node, styleProperty) { + const win = node.ownerDocument.defaultView || window; + const val = win.getComputedStyle(node).getPropertyValue(styleProperty); + return val ? parseFloat(val.replace("px", "")) : 0; +} +function getNodeWidth(node) { + const leftBorder = px(node, "border-left-width"); + const rightBorder = px(node, "border-right-width"); + return node.clientWidth + leftBorder + rightBorder; +} +function getNodeHeight(node) { + const topBorder = px(node, "border-top-width"); + const bottomBorder = px(node, "border-bottom-width"); + return node.clientHeight + topBorder + bottomBorder; +} +function getImageSize(targetNode, options = {}) { + const width = options.width || getNodeWidth(targetNode); + const height = options.height || getNodeHeight(targetNode); + return { width, height }; +} +function getPixelRatio() { + let ratio; + let FINAL_PROCESS; + try { + FINAL_PROCESS = process; + } catch (e) { + } + const val = FINAL_PROCESS && FINAL_PROCESS.env ? FINAL_PROCESS.env.devicePixelRatio : null; + if (val) { + ratio = parseInt(val, 10); + if (Number.isNaN(ratio)) { + ratio = 1; + } + } + return ratio || window.devicePixelRatio || 1; +} +var canvasDimensionLimit = 16384; +function checkCanvasDimensions(canvas) { + if (canvas.width > canvasDimensionLimit || canvas.height > canvasDimensionLimit) { + if (canvas.width > canvasDimensionLimit && canvas.height > canvasDimensionLimit) { + if (canvas.width > canvas.height) { + canvas.height *= canvasDimensionLimit / canvas.width; + canvas.width = canvasDimensionLimit; + } else { + canvas.width *= canvasDimensionLimit / canvas.height; + canvas.height = canvasDimensionLimit; + } + } else if (canvas.width > canvasDimensionLimit) { + canvas.height *= canvasDimensionLimit / canvas.width; + canvas.width = canvasDimensionLimit; + } else { + canvas.width *= canvasDimensionLimit / canvas.height; + canvas.height = canvasDimensionLimit; + } + } +} +function createImage(url) { + return new Promise((resolve, reject) => { + const img = new Image(); + img.decode = () => resolve(img); + img.onload = () => resolve(img); + img.onerror = reject; + img.crossOrigin = "anonymous"; + img.decoding = "async"; + img.src = url; + }); +} +async function svgToDataURL(svg) { + return Promise.resolve().then(() => new XMLSerializer().serializeToString(svg)).then(encodeURIComponent).then((html) => `data:image/svg+xml;charset=utf-8,${html}`); +} +async function nodeToDataURL(node, width, height) { + const xmlns = "http://www.w3.org/2000/svg"; + const svg = document.createElementNS(xmlns, "svg"); + const foreignObject = document.createElementNS(xmlns, "foreignObject"); + svg.setAttribute("width", `${width}`); + svg.setAttribute("height", `${height}`); + svg.setAttribute("viewBox", `0 0 ${width} ${height}`); + foreignObject.setAttribute("width", "100%"); + foreignObject.setAttribute("height", "100%"); + foreignObject.setAttribute("x", "0"); + foreignObject.setAttribute("y", "0"); + foreignObject.setAttribute("externalResourcesRequired", "true"); + svg.appendChild(foreignObject); + foreignObject.appendChild(node); + return svgToDataURL(svg); +} +var isInstanceOfElement = (node, instance) => { + if (node instanceof instance) + return true; + const nodePrototype = Object.getPrototypeOf(node); + if (nodePrototype === null) + return false; + return nodePrototype.constructor.name === instance.name || isInstanceOfElement(nodePrototype, instance); +}; + +// node_modules/html-to-image/es/clone-pseudos.js +function formatCSSText(style) { + const content = style.getPropertyValue("content"); + return `${style.cssText} content: '${content.replace(/'|"/g, "")}';`; +} +function formatCSSProperties(style) { + return toArray(style).map((name) => { + const value = style.getPropertyValue(name); + const priority = style.getPropertyPriority(name); + return `${name}: ${value}${priority ? " !important" : ""};`; + }).join(" "); +} +function getPseudoElementStyle(className, pseudo, style) { + const selector = `.${className}:${pseudo}`; + const cssText = style.cssText ? formatCSSText(style) : formatCSSProperties(style); + return document.createTextNode(`${selector}{${cssText}}`); +} +function clonePseudoElement(nativeNode, clonedNode, pseudo) { + const style = window.getComputedStyle(nativeNode, pseudo); + const content = style.getPropertyValue("content"); + if (content === "" || content === "none") { + return; + } + const className = uuid(); + try { + clonedNode.className = `${clonedNode.className} ${className}`; + } catch (err) { + return; + } + const styleElement = document.createElement("style"); + styleElement.appendChild(getPseudoElementStyle(className, pseudo, style)); + clonedNode.appendChild(styleElement); +} +function clonePseudoElements(nativeNode, clonedNode) { + clonePseudoElement(nativeNode, clonedNode, ":before"); + clonePseudoElement(nativeNode, clonedNode, ":after"); +} + +// node_modules/html-to-image/es/mimes.js +var WOFF = "application/font-woff"; +var JPEG = "image/jpeg"; +var mimes = { + woff: WOFF, + woff2: WOFF, + ttf: "application/font-truetype", + eot: "application/vnd.ms-fontobject", + png: "image/png", + jpg: JPEG, + jpeg: JPEG, + gif: "image/gif", + tiff: "image/tiff", + svg: "image/svg+xml", + webp: "image/webp" +}; +function getExtension(url) { + const match = /\.([^./]*?)$/g.exec(url); + return match ? match[1] : ""; +} +function getMimeType(url) { + const extension = getExtension(url).toLowerCase(); + return mimes[extension] || ""; +} + +// node_modules/html-to-image/es/dataurl.js +function getContentFromDataUrl(dataURL) { + return dataURL.split(/,/)[1]; +} +function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; +} +function makeDataUrl(content, mimeType) { + return `data:${mimeType};base64,${content}`; +} +async function fetchAsDataURL(url, init, process2) { + const res = await fetch(url, init); + if (res.status === 404) { + throw new Error(`Resource "${res.url}" not found`); + } + const blob = await res.blob(); + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onerror = reject; + reader.onloadend = () => { + try { + resolve(process2({ res, result: reader.result })); + } catch (error) { + reject(error); + } + }; + reader.readAsDataURL(blob); + }); +} +var cache = {}; +function getCacheKey(url, contentType, includeQueryParams) { + let key = url.replace(/\?.*/, ""); + if (includeQueryParams) { + key = url; + } + if (/ttf|otf|eot|woff2?/i.test(key)) { + key = key.replace(/.*\//, ""); + } + return contentType ? `[${contentType}]${key}` : key; +} +async function resourceToDataURL(resourceUrl, contentType, options) { + const cacheKey = getCacheKey(resourceUrl, contentType, options.includeQueryParams); + if (cache[cacheKey] != null) { + return cache[cacheKey]; + } + if (options.cacheBust) { + resourceUrl += (/\?/.test(resourceUrl) ? "&" : "?") + (/* @__PURE__ */ new Date()).getTime(); + } + let dataURL; + try { + const content = await fetchAsDataURL(resourceUrl, options.fetchRequestInit, ({ res, result }) => { + if (!contentType) { + contentType = res.headers.get("Content-Type") || ""; + } + return getContentFromDataUrl(result); + }); + dataURL = makeDataUrl(content, contentType); + } catch (error) { + dataURL = options.imagePlaceholder || ""; + let msg = `Failed to fetch resource: ${resourceUrl}`; + if (error) { + msg = typeof error === "string" ? error : error.message; + } + if (msg) { + console.warn(msg); + } + } + cache[cacheKey] = dataURL; + return dataURL; +} + +// node_modules/html-to-image/es/clone-node.js +async function cloneCanvasElement(canvas) { + const dataURL = canvas.toDataURL(); + if (dataURL === "data:,") { + return canvas.cloneNode(false); + } + return createImage(dataURL); +} +async function cloneVideoElement(video, options) { + if (video.currentSrc) { + const canvas = document.createElement("canvas"); + const ctx = canvas.getContext("2d"); + canvas.width = video.clientWidth; + canvas.height = video.clientHeight; + ctx === null || ctx === void 0 ? void 0 : ctx.drawImage(video, 0, 0, canvas.width, canvas.height); + const dataURL2 = canvas.toDataURL(); + return createImage(dataURL2); + } + const poster = video.poster; + const contentType = getMimeType(poster); + const dataURL = await resourceToDataURL(poster, contentType, options); + return createImage(dataURL); +} +async function cloneIFrameElement(iframe) { + var _a; + try { + if ((_a = iframe === null || iframe === void 0 ? void 0 : iframe.contentDocument) === null || _a === void 0 ? void 0 : _a.body) { + return await cloneNode(iframe.contentDocument.body, {}, true); + } + } catch (_b) { + } + return iframe.cloneNode(false); +} +async function cloneSingleNode(node, options) { + if (isInstanceOfElement(node, HTMLCanvasElement)) { + return cloneCanvasElement(node); + } + if (isInstanceOfElement(node, HTMLVideoElement)) { + return cloneVideoElement(node, options); + } + if (isInstanceOfElement(node, HTMLIFrameElement)) { + return cloneIFrameElement(node); + } + return node.cloneNode(false); +} +var isSlotElement = (node) => node.tagName != null && node.tagName.toUpperCase() === "SLOT"; +async function cloneChildren(nativeNode, clonedNode, options) { + var _a, _b; + let children = []; + if (isSlotElement(nativeNode) && nativeNode.assignedNodes) { + children = toArray(nativeNode.assignedNodes()); + } else if (isInstanceOfElement(nativeNode, HTMLIFrameElement) && ((_a = nativeNode.contentDocument) === null || _a === void 0 ? void 0 : _a.body)) { + children = toArray(nativeNode.contentDocument.body.childNodes); + } else { + children = toArray(((_b = nativeNode.shadowRoot) !== null && _b !== void 0 ? _b : nativeNode).childNodes); + } + if (children.length === 0 || isInstanceOfElement(nativeNode, HTMLVideoElement)) { + return clonedNode; + } + await children.reduce((deferred, child) => deferred.then(() => cloneNode(child, options)).then((clonedChild) => { + if (clonedChild) { + clonedNode.appendChild(clonedChild); + } + }), Promise.resolve()); + return clonedNode; +} +function cloneCSSStyle(nativeNode, clonedNode) { + const targetStyle = clonedNode.style; + if (!targetStyle) { + return; + } + const sourceStyle = window.getComputedStyle(nativeNode); + if (sourceStyle.cssText) { + targetStyle.cssText = sourceStyle.cssText; + targetStyle.transformOrigin = sourceStyle.transformOrigin; + } else { + toArray(sourceStyle).forEach((name) => { + let value = sourceStyle.getPropertyValue(name); + if (name === "font-size" && value.endsWith("px")) { + const reducedFont = Math.floor(parseFloat(value.substring(0, value.length - 2))) - 0.1; + value = `${reducedFont}px`; + } + if (isInstanceOfElement(nativeNode, HTMLIFrameElement) && name === "display" && value === "inline") { + value = "block"; + } + if (name === "d" && clonedNode.getAttribute("d")) { + value = `path(${clonedNode.getAttribute("d")})`; + } + targetStyle.setProperty(name, value, sourceStyle.getPropertyPriority(name)); + }); + } +} +function cloneInputValue(nativeNode, clonedNode) { + if (isInstanceOfElement(nativeNode, HTMLTextAreaElement)) { + clonedNode.innerHTML = nativeNode.value; + } + if (isInstanceOfElement(nativeNode, HTMLInputElement)) { + clonedNode.setAttribute("value", nativeNode.value); + } +} +function cloneSelectValue(nativeNode, clonedNode) { + if (isInstanceOfElement(nativeNode, HTMLSelectElement)) { + const clonedSelect = clonedNode; + const selectedOption = Array.from(clonedSelect.children).find((child) => nativeNode.value === child.getAttribute("value")); + if (selectedOption) { + selectedOption.setAttribute("selected", ""); + } + } +} +function decorate(nativeNode, clonedNode) { + if (isInstanceOfElement(clonedNode, Element)) { + cloneCSSStyle(nativeNode, clonedNode); + clonePseudoElements(nativeNode, clonedNode); + cloneInputValue(nativeNode, clonedNode); + cloneSelectValue(nativeNode, clonedNode); + } + return clonedNode; +} +async function ensureSVGSymbols(clone, options) { + const uses = clone.querySelectorAll ? clone.querySelectorAll("use") : []; + if (uses.length === 0) { + return clone; + } + const processedDefs = {}; + for (let i = 0; i < uses.length; i++) { + const use = uses[i]; + const id = use.getAttribute("xlink:href"); + if (id) { + const exist = clone.querySelector(id); + const definition = document.querySelector(id); + if (!exist && definition && !processedDefs[id]) { + processedDefs[id] = await cloneNode(definition, options, true); + } + } + } + const nodes = Object.values(processedDefs); + if (nodes.length) { + const ns = "http://www.w3.org/1999/xhtml"; + const svg = document.createElementNS(ns, "svg"); + svg.setAttribute("xmlns", ns); + svg.style.position = "absolute"; + svg.style.width = "0"; + svg.style.height = "0"; + svg.style.overflow = "hidden"; + svg.style.display = "none"; + const defs = document.createElementNS(ns, "defs"); + svg.appendChild(defs); + for (let i = 0; i < nodes.length; i++) { + defs.appendChild(nodes[i]); + } + clone.appendChild(svg); + } + return clone; +} +async function cloneNode(node, options, isRoot) { + if (!isRoot && options.filter && !options.filter(node)) { + return null; + } + return Promise.resolve(node).then((clonedNode) => cloneSingleNode(clonedNode, options)).then((clonedNode) => cloneChildren(node, clonedNode, options)).then((clonedNode) => decorate(node, clonedNode)).then((clonedNode) => ensureSVGSymbols(clonedNode, options)); +} + +// node_modules/html-to-image/es/embed-resources.js +var URL_REGEX = /url\((['"]?)([^'"]+?)\1\)/g; +var URL_WITH_FORMAT_REGEX = /url\([^)]+\)\s*format\((["']?)([^"']+)\1\)/g; +var FONT_SRC_REGEX = /src:\s*(?:url\([^)]+\)\s*format\([^)]+\)[,;]\s*)+/g; +function toRegex(url) { + const escaped = url.replace(/([.*+?^${}()|\[\]\/\\])/g, "\\$1"); + return new RegExp(`(url\\(['"]?)(${escaped})(['"]?\\))`, "g"); +} +function parseURLs(cssText) { + const urls = []; + cssText.replace(URL_REGEX, (raw, quotation, url) => { + urls.push(url); + return raw; + }); + return urls.filter((url) => !isDataUrl(url)); +} +async function embed(cssText, resourceURL, baseURL, options, getContentFromUrl) { + try { + const resolvedURL = baseURL ? resolveUrl(resourceURL, baseURL) : resourceURL; + const contentType = getMimeType(resourceURL); + let dataURL; + if (getContentFromUrl) { + const content = await getContentFromUrl(resolvedURL); + dataURL = makeDataUrl(content, contentType); + } else { + dataURL = await resourceToDataURL(resolvedURL, contentType, options); + } + return cssText.replace(toRegex(resourceURL), `$1${dataURL}$3`); + } catch (error) { + } + return cssText; +} +function filterPreferredFontFormat(str, { preferredFontFormat }) { + return !preferredFontFormat ? str : str.replace(FONT_SRC_REGEX, (match) => { + while (true) { + const [src, , format] = URL_WITH_FORMAT_REGEX.exec(match) || []; + if (!format) { + return ""; + } + if (format === preferredFontFormat) { + return `src: ${src};`; + } + } + }); +} +function shouldEmbed(url) { + return url.search(URL_REGEX) !== -1; +} +async function embedResources(cssText, baseUrl, options) { + if (!shouldEmbed(cssText)) { + return cssText; + } + const filteredCSSText = filterPreferredFontFormat(cssText, options); + const urls = parseURLs(filteredCSSText); + return urls.reduce((deferred, url) => deferred.then((css) => embed(css, url, baseUrl, options)), Promise.resolve(filteredCSSText)); +} + +// node_modules/html-to-image/es/embed-images.js +async function embedProp(propName, node, options) { + var _a; + const propValue = (_a = node.style) === null || _a === void 0 ? void 0 : _a.getPropertyValue(propName); + if (propValue) { + const cssString = await embedResources(propValue, null, options); + node.style.setProperty(propName, cssString, node.style.getPropertyPriority(propName)); + return true; + } + return false; +} +async function embedBackground(clonedNode, options) { + if (!await embedProp("background", clonedNode, options)) { + await embedProp("background-image", clonedNode, options); + } + if (!await embedProp("mask", clonedNode, options)) { + await embedProp("mask-image", clonedNode, options); + } +} +async function embedImageNode(clonedNode, options) { + const isImageElement = isInstanceOfElement(clonedNode, HTMLImageElement); + if (!(isImageElement && !isDataUrl(clonedNode.src)) && !(isInstanceOfElement(clonedNode, SVGImageElement) && !isDataUrl(clonedNode.href.baseVal))) { + return; + } + const url = isImageElement ? clonedNode.src : clonedNode.href.baseVal; + const dataURL = await resourceToDataURL(url, getMimeType(url), options); + await new Promise((resolve, reject) => { + clonedNode.onload = resolve; + clonedNode.onerror = reject; + const image = clonedNode; + if (image.decode) { + image.decode = resolve; + } + if (image.loading === "lazy") { + image.loading = "eager"; + } + if (isImageElement) { + clonedNode.srcset = ""; + clonedNode.src = dataURL; + } else { + clonedNode.href.baseVal = dataURL; + } + }); +} +async function embedChildren(clonedNode, options) { + const children = toArray(clonedNode.childNodes); + const deferreds = children.map((child) => embedImages(child, options)); + await Promise.all(deferreds).then(() => clonedNode); +} +async function embedImages(clonedNode, options) { + if (isInstanceOfElement(clonedNode, Element)) { + await embedBackground(clonedNode, options); + await embedImageNode(clonedNode, options); + await embedChildren(clonedNode, options); + } +} + +// node_modules/html-to-image/es/apply-style.js +function applyStyle(node, options) { + const { style } = node; + if (options.backgroundColor) { + style.backgroundColor = options.backgroundColor; + } + if (options.width) { + style.width = `${options.width}px`; + } + if (options.height) { + style.height = `${options.height}px`; + } + const manual = options.style; + if (manual != null) { + Object.keys(manual).forEach((key) => { + style[key] = manual[key]; + }); + } + return node; +} + +// node_modules/html-to-image/es/embed-webfonts.js +var cssFetchCache = {}; +async function fetchCSS(url) { + let cache2 = cssFetchCache[url]; + if (cache2 != null) { + return cache2; + } + const res = await fetch(url); + const cssText = await res.text(); + cache2 = { url, cssText }; + cssFetchCache[url] = cache2; + return cache2; +} +async function embedFonts(data, options) { + let cssText = data.cssText; + const regexUrl = /url\(["']?([^"')]+)["']?\)/g; + const fontLocs = cssText.match(/url\([^)]+\)/g) || []; + const loadFonts = fontLocs.map(async (loc) => { + let url = loc.replace(regexUrl, "$1"); + if (!url.startsWith("https://")) { + url = new URL(url, data.url).href; + } + return fetchAsDataURL(url, options.fetchRequestInit, ({ result }) => { + cssText = cssText.replace(loc, `url(${result})`); + return [loc, result]; + }); + }); + return Promise.all(loadFonts).then(() => cssText); +} +function parseCSS(source) { + if (source == null) { + return []; + } + const result = []; + const commentsRegex = /(\/\*[\s\S]*?\*\/)/gi; + let cssText = source.replace(commentsRegex, ""); + const keyframesRegex = new RegExp("((@.*?keyframes [\\s\\S]*?){([\\s\\S]*?}\\s*?)})", "gi"); + while (true) { + const matches = keyframesRegex.exec(cssText); + if (matches === null) { + break; + } + result.push(matches[0]); + } + cssText = cssText.replace(keyframesRegex, ""); + const importRegex = /@import[\s\S]*?url\([^)]*\)[\s\S]*?;/gi; + const combinedCSSRegex = "((\\s*?(?:\\/\\*[\\s\\S]*?\\*\\/)?\\s*?@media[\\s\\S]*?){([\\s\\S]*?)}\\s*?})|(([\\s\\S]*?){([\\s\\S]*?)})"; + const unifiedRegex = new RegExp(combinedCSSRegex, "gi"); + while (true) { + let matches = importRegex.exec(cssText); + if (matches === null) { + matches = unifiedRegex.exec(cssText); + if (matches === null) { + break; + } else { + importRegex.lastIndex = unifiedRegex.lastIndex; + } + } else { + unifiedRegex.lastIndex = importRegex.lastIndex; + } + result.push(matches[0]); + } + return result; +} +async function getCSSRules(styleSheets, options) { + const ret = []; + const deferreds = []; + styleSheets.forEach((sheet) => { + if ("cssRules" in sheet) { + try { + toArray(sheet.cssRules || []).forEach((item, index) => { + if (item.type === CSSRule.IMPORT_RULE) { + let importIndex = index + 1; + const url = item.href; + const deferred = fetchCSS(url).then((metadata) => embedFonts(metadata, options)).then((cssText) => parseCSS(cssText).forEach((rule) => { + try { + sheet.insertRule(rule, rule.startsWith("@import") ? importIndex += 1 : sheet.cssRules.length); + } catch (error) { + console.error("Error inserting rule from remote css", { + rule, + error + }); + } + })).catch((e) => { + console.error("Error loading remote css", e.toString()); + }); + deferreds.push(deferred); + } + }); + } catch (e) { + const inline = styleSheets.find((a) => a.href == null) || document.styleSheets[0]; + if (sheet.href != null) { + deferreds.push(fetchCSS(sheet.href).then((metadata) => embedFonts(metadata, options)).then((cssText) => parseCSS(cssText).forEach((rule) => { + inline.insertRule(rule, sheet.cssRules.length); + })).catch((err) => { + console.error("Error loading remote stylesheet", err); + })); + } + console.error("Error inlining remote css file", e); + } + } + }); + return Promise.all(deferreds).then(() => { + styleSheets.forEach((sheet) => { + if ("cssRules" in sheet) { + try { + toArray(sheet.cssRules || []).forEach((item) => { + ret.push(item); + }); + } catch (e) { + console.error(`Error while reading CSS rules from ${sheet.href}`, e); + } + } + }); + return ret; + }); +} +function getWebFontRules(cssRules) { + return cssRules.filter((rule) => rule.type === CSSRule.FONT_FACE_RULE).filter((rule) => shouldEmbed(rule.style.getPropertyValue("src"))); +} +async function parseWebFontRules(node, options) { + if (node.ownerDocument == null) { + throw new Error("Provided element is not within a Document"); + } + const styleSheets = toArray(node.ownerDocument.styleSheets); + const cssRules = await getCSSRules(styleSheets, options); + return getWebFontRules(cssRules); +} +async function getWebFontCSS(node, options) { + const rules = await parseWebFontRules(node, options); + const cssTexts = await Promise.all(rules.map((rule) => { + const baseUrl = rule.parentStyleSheet ? rule.parentStyleSheet.href : null; + return embedResources(rule.cssText, baseUrl, options); + })); + return cssTexts.join("\n"); +} +async function embedWebFonts(clonedNode, options) { + const cssText = options.fontEmbedCSS != null ? options.fontEmbedCSS : options.skipFonts ? null : await getWebFontCSS(clonedNode, options); + if (cssText) { + const styleNode = document.createElement("style"); + const sytleContent = document.createTextNode(cssText); + styleNode.appendChild(sytleContent); + if (clonedNode.firstChild) { + clonedNode.insertBefore(styleNode, clonedNode.firstChild); + } else { + clonedNode.appendChild(styleNode); + } + } +} + +// node_modules/html-to-image/es/index.js +async function toSvg(node, options = {}) { + const { width, height } = getImageSize(node, options); + const clonedNode = await cloneNode(node, options, true); + await embedWebFonts(clonedNode, options); + await embedImages(clonedNode, options); + applyStyle(clonedNode, options); + const datauri = await nodeToDataURL(clonedNode, width, height); + return datauri; +} +async function toCanvas(node, options = {}) { + const { width, height } = getImageSize(node, options); + const svg = await toSvg(node, options); + const img = await createImage(svg); + const canvas = document.createElement("canvas"); + const context = canvas.getContext("2d"); + const ratio = options.pixelRatio || getPixelRatio(); + const canvasWidth = options.canvasWidth || width; + const canvasHeight = options.canvasHeight || height; + canvas.width = canvasWidth * ratio; + canvas.height = canvasHeight * ratio; + if (!options.skipAutoScale) { + checkCanvasDimensions(canvas); + } + canvas.style.width = `${canvasWidth}`; + canvas.style.height = `${canvasHeight}`; + if (options.backgroundColor) { + context.fillStyle = options.backgroundColor; + context.fillRect(0, 0, canvas.width, canvas.height); + } + context.drawImage(img, 0, 0, canvas.width, canvas.height); + return canvas; +} +async function toPng(node, options = {}) { + const canvas = await toCanvas(node, options); + return canvas.toDataURL(); +} + +// src/canvas-extensions/export-canvas-extension.ts +var import_obsidian18 = require("obsidian"); +var MAX_ALLOWED_LOADING_TIME = 1e4; +var ExportCanvasExtension = class extends CanvasExtension { + isEnabled() { + return "betterExportFeatureEnabled"; + } + init() { + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-breakpoint-changed", + (canvas, node, breakpointRef) => { + if (canvas.screenshotting) breakpointRef.value = true; + } + )); + this.plugin.addCommand({ + id: "export-all-as-image", + name: "Export canvas as image", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (canvas) => canvas.nodes.size > 0, + (canvas) => this.showExportImageSettingsModal(canvas, null) + ) + }); + this.plugin.addCommand({ + id: "export-selected-as-image", + name: "Export selected nodes as image", + checkCallback: CanvasHelper.canvasCommand( + this.plugin, + (canvas) => canvas.selection.size > 0, + (canvas) => this.showExportImageSettingsModal( + canvas, + canvas.getSelectionData().nodes.map((nodeData) => canvas.nodes.get(nodeData.id)).filter((node) => node !== void 0) + ) + ) + }); + } + async showExportImageSettingsModal(canvas, nodesToExport) { + const modal = new import_obsidian18.Modal(this.plugin.app); + modal.setTitle("Export image settings"); + let pixelRatioSetting = null; + let noFontExportSetting = null; + let transparentBackgroundSetting = null; + const updateDynamicSettings = () => { + var _a, _b, _c, _d, _e, _f; + if (svg) { + (_a = pixelRatioSetting == null ? void 0 : pixelRatioSetting.settingEl) == null ? void 0 : _a.hide(); + (_b = noFontExportSetting == null ? void 0 : noFontExportSetting.settingEl) == null ? void 0 : _b.show(); + (_c = transparentBackgroundSetting == null ? void 0 : transparentBackgroundSetting.settingEl) == null ? void 0 : _c.hide(); + } else { + (_d = pixelRatioSetting == null ? void 0 : pixelRatioSetting.settingEl) == null ? void 0 : _d.show(); + (_e = noFontExportSetting == null ? void 0 : noFontExportSetting.settingEl) == null ? void 0 : _e.hide(); + (_f = transparentBackgroundSetting == null ? void 0 : transparentBackgroundSetting.settingEl) == null ? void 0 : _f.show(); + } + }; + let svg = false; + new import_obsidian18.Setting(modal.contentEl).setName("Export file format").setDesc("Choose the file format to export the canvas as.").addDropdown( + (dropdown) => dropdown.addOptions({ + png: "PNG", + svg: "SVG" + }).setValue(svg ? "svg" : "png").onChange((value) => { + svg = value === "svg"; + updateDynamicSettings(); + }) + ); + let pixelRatioFactor = 1; + pixelRatioSetting = new import_obsidian18.Setting(modal.contentEl).setName("Pixel ratio").setDesc("Higher pixel ratios result in higher resolution images but also larger file sizes.").addSlider( + (slider) => slider.setDynamicTooltip().setLimits(0.2, 5, 0.1).setValue(pixelRatioFactor).onChange((value) => pixelRatioFactor = value) + ); + let noFontExport = true; + noFontExportSetting = new import_obsidian18.Setting(modal.contentEl).setName("Skip font export").setDesc("This will not include the fonts in the exported SVG. This will make the SVG file smaller.").addToggle( + (toggle) => toggle.setValue(noFontExport).onChange((value) => noFontExport = value) + ); + let theme = document.body.classList.contains("theme-dark") ? "dark" : "light"; + new import_obsidian18.Setting(modal.contentEl).setName("Theme").setDesc("The theme used for the export.").addDropdown( + (dropdown) => dropdown.addOptions({ + light: "Light", + dark: "Dark" + }).setValue(theme).onChange((value) => theme = value) + ); + let watermark = false; + new import_obsidian18.Setting(modal.contentEl).setName("Show logo").setDesc("This will add an Obsidian + Advanced Canvas logo to the bottom left.").addToggle( + (toggle) => toggle.setValue(watermark).onChange((value) => watermark = value) + ); + let garbledText = false; + new import_obsidian18.Setting(modal.contentEl).setName("Privacy mode").setDesc("This will obscure any text on your canvas.").addToggle( + (toggle) => toggle.setValue(garbledText).onChange((value) => garbledText = value) + ); + let transparentBackground = false; + transparentBackgroundSetting = new import_obsidian18.Setting(modal.contentEl).setName("Transparent background").setDesc("This will make the background of the image transparent.").addToggle( + (toggle) => toggle.setValue(transparentBackground).onChange((value) => transparentBackground = value) + ); + new import_obsidian18.Setting(modal.contentEl).addButton( + (button) => button.setButtonText("Save").setCta().onClick(async () => { + modal.close(); + this.exportImage( + canvas, + nodesToExport, + svg, + svg ? 1 : pixelRatioFactor, + svg ? noFontExport : false, + theme, + watermark, + garbledText, + svg ? true : transparentBackground + ); + }) + ); + updateDynamicSettings(); + modal.open(); + } + async exportImage(canvas, nodesToExport, svg, pixelRatioFactor, noFontExport, theme, watermark, garbledText, transparentBackground) { + var _a, _b, _c; + const cachedTheme = document.body.classList.contains("theme-dark") ? "dark" : "light"; + if (theme !== cachedTheme) { + document.body.classList.toggle("theme-dark", theme === "dark"); + document.body.classList.toggle("theme-light", theme === "light"); + } + const isWholeCanvas = nodesToExport === null; + if (!nodesToExport) nodesToExport = [...canvas.nodes.values()]; + const nodesToExportIds = nodesToExport.map((node) => node.getData().id); + const edgesToExport = [...canvas.edges.values()].filter((edge) => { + const edgeData = edge.getData(); + return nodesToExportIds.includes(edgeData.fromNode) && nodesToExportIds.includes(edgeData.toNode); + }); + const backgroundColor = transparentBackground ? void 0 : window.getComputedStyle(canvas.canvasEl).getPropertyValue("--canvas-background"); + new import_obsidian18.Notice("Exporting the canvas. Please wait..."); + const interactionBlocker = this.getInteractionBlocker(); + document.body.appendChild(interactionBlocker); + canvas.screenshotting = true; + canvas.canvasEl.classList.add("is-exporting"); + if (garbledText) canvas.canvasEl.classList.add("is-text-garbled"); + let watermarkEl = null; + const cachedSelection = new Set(canvas.selection); + canvas.deselectAll(); + const cachedViewport = { x: canvas.x, y: canvas.y, zoom: canvas.zoom }; + try { + const targetBoundingBox = CanvasHelper.getBBox([...nodesToExport, ...edgesToExport]); + let enlargedTargetBoundingBox = BBoxHelper.scaleBBox(targetBoundingBox, 1.1); + const enlargedTargetBoundingBoxSize = { width: enlargedTargetBoundingBox.maxX - enlargedTargetBoundingBox.minX, height: enlargedTargetBoundingBox.maxY - enlargedTargetBoundingBox.minY }; + const canvasElSize = { width: canvas.canvasEl.clientWidth, height: canvas.canvasEl.clientHeight }; + const requiredPixelRatio = Math.max(enlargedTargetBoundingBoxSize.width / canvasElSize.width, enlargedTargetBoundingBoxSize.height / canvasElSize.height); + const pixelRatio = svg ? void 0 : Math.round(requiredPixelRatio * pixelRatioFactor); + watermarkEl = watermark ? this.getWatermark(enlargedTargetBoundingBox) : null; + if (watermarkEl) canvas.canvasEl.appendChild(watermarkEl); + const actualAspectRatio = canvas.canvasRect.width / canvas.canvasRect.height; + const targetAspectRatio = (enlargedTargetBoundingBox.maxX - enlargedTargetBoundingBox.minX) / (enlargedTargetBoundingBox.maxY - enlargedTargetBoundingBox.minY); + let adjustedBoundingBox = { ...enlargedTargetBoundingBox }; + if (actualAspectRatio > targetAspectRatio) { + const targetHeight = enlargedTargetBoundingBox.maxY - enlargedTargetBoundingBox.minY; + const actualWidth = targetHeight * actualAspectRatio; + adjustedBoundingBox.maxX = enlargedTargetBoundingBox.minX + actualWidth; + } else { + const targetWidth = enlargedTargetBoundingBox.maxX - enlargedTargetBoundingBox.minX; + const actualHeight = targetWidth / actualAspectRatio; + adjustedBoundingBox.maxY = enlargedTargetBoundingBox.minY + actualHeight; + } + canvas.zoomToRealBbox(adjustedBoundingBox); + canvas.setViewport(canvas.tx, canvas.ty, canvas.tZoom); + await sleep(10); + let canvasScale = parseFloat(((_a = canvas.canvasEl.style.transform.match(/scale\((\d+(\.\d+)?)\)/)) == null ? void 0 : _a[1]) || "1"); + const edgePathsBBox = BBoxHelper.combineBBoxes(edgesToExport.map((edge) => { + const edgeCenter = edge.getCenter(); + const labelWidth = edge.labelElement ? edge.labelElement.wrapperEl.getBoundingClientRect().width / canvasScale : 0; + return { minX: edgeCenter.x - labelWidth / 2, minY: edgeCenter.y, maxX: edgeCenter.x + labelWidth / 2, maxY: edgeCenter.y }; + })); + const enlargedEdgePathsBBox = BBoxHelper.enlargeBBox(edgePathsBBox, 1.1); + enlargedTargetBoundingBox = BBoxHelper.combineBBoxes([enlargedTargetBoundingBox, enlargedEdgePathsBBox]); + adjustedBoundingBox = BBoxHelper.combineBBoxes([adjustedBoundingBox, enlargedEdgePathsBBox]); + canvas.zoomToRealBbox(adjustedBoundingBox); + canvas.setViewport(canvas.tx, canvas.ty, canvas.tZoom); + await sleep(10); + const canvasViewportBBox = canvas.getViewportBBox(); + canvasScale = parseFloat(((_b = canvas.canvasEl.style.transform.match(/scale\((\d+(\.\d+)?)\)/)) == null ? void 0 : _b[1]) || "1"); + let width = (canvasViewportBBox.maxX - canvasViewportBBox.minX) * canvasScale; + let height = (canvasViewportBBox.maxY - canvasViewportBBox.minY) * canvasScale; + if (actualAspectRatio > targetAspectRatio) + width = height * targetAspectRatio; + else height = width / targetAspectRatio; + let unloadedNodes = nodesToExport.filter((node) => node.initialized === false || node.isContentMounted === false); + const startTimestamp = performance.now(); + while (unloadedNodes.length > 0 && performance.now() - startTimestamp < MAX_ALLOWED_LOADING_TIME) { + await sleep(10); + unloadedNodes = nodesToExport.filter((node) => node.initialized === false || node.isContentMounted === false); + console.info(`Waiting for ${unloadedNodes.length} nodes to finish loading...`); + } + if (unloadedNodes.length === 0) { + const nodeElements = nodesToExport.map((node) => node.nodeEl); + const edgePathAndArrowElements = edgesToExport.map((edge) => [edge.lineGroupEl, edge.lineEndGroupEl]).flat(); + const edgeLabelElements = edgesToExport.map((edge) => { + var _a2; + return (_a2 = edge.labelElement) == null ? void 0 : _a2.wrapperEl; + }).filter((labelElement) => labelElement !== void 0); + const filter = (element) => { + var _a2, _b2, _c2, _d; + if (((_a2 = element.classList) == null ? void 0 : _a2.contains("canvas-node")) && !nodeElements.includes(element)) + return false; + if (((_c2 = (_b2 = element.parentElement) == null ? void 0 : _b2.classList) == null ? void 0 : _c2.contains("canvas-edges")) && !edgePathAndArrowElements.includes(element)) + return false; + if (((_d = element.classList) == null ? void 0 : _d.contains("canvas-path-label-wrapper")) && !edgeLabelElements.includes(element)) + return false; + return true; + }; + const options = { + pixelRatio, + backgroundColor, + height, + width, + filter + }; + if (noFontExport) options.fontEmbedCSS = ""; + let imageDataUri = svg ? await toSvg(canvas.canvasEl, options) : await toPng(canvas.canvasEl, options); + if (svg) { + const header = ``; + imageDataUri = imageDataUri.replace( + encodeURIComponent(" canvas.selection = cachedSelection); + canvas.setViewport(cachedViewport.x, cachedViewport.y, cachedViewport.zoom); + interactionBlocker.remove(); + if (theme !== cachedTheme) { + document.body.classList.toggle("theme-dark", cachedTheme === "dark"); + document.body.classList.toggle("theme-light", cachedTheme === "light"); + } + } + } + getInteractionBlocker() { + const interactionBlocker = document.createElement("div"); + interactionBlocker.classList.add("progress-bar-container"); + const progressBar = document.createElement("div"); + progressBar.classList.add("progress-bar"); + interactionBlocker.appendChild(progressBar); + const progressBarMessage = document.createElement("div"); + progressBarMessage.classList.add("progress-bar-message", "u-center-text"); + progressBarMessage.innerText = "Generating image..."; + progressBar.appendChild(progressBarMessage); + const progressBarIndicator = document.createElement("div"); + progressBarIndicator.classList.add("progress-bar-indicator"); + progressBar.appendChild(progressBarIndicator); + const progressBarLine = document.createElement("div"); + progressBarLine.classList.add("progress-bar-line"); + progressBarIndicator.appendChild(progressBarLine); + const progressBarSublineIncrease = document.createElement("div"); + progressBarSublineIncrease.classList.add("progress-bar-subline", "mod-increase"); + progressBarIndicator.appendChild(progressBarSublineIncrease); + const progressBarSublineDecrease = document.createElement("div"); + progressBarSublineDecrease.classList.add("progress-bar-subline", "mod-decrease"); + progressBarIndicator.appendChild(progressBarSublineDecrease); + return interactionBlocker; + } + getWatermark(bbox) { + const bboxWidth = bbox.maxX - bbox.minX; + const width = Math.max(200, bboxWidth * 0.3); + const WATERMARK_SIZE = { width: 215, height: 25 }; + const height = WATERMARK_SIZE.height / WATERMARK_SIZE.width * width; + const watermarkPadding = { + x: bboxWidth * 0.02, + y: bboxWidth * 0.014 + }; + bbox.maxY += height + watermarkPadding.y; + const watermarkEl = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + watermarkEl.id = "watermark-ac"; + watermarkEl.style.transform = `translate(${bbox.minX + watermarkPadding.x}px, ${bbox.maxY - height - watermarkPadding.y}px)`; + watermarkEl.setAttrs({ + viewBox: `0 0 ${WATERMARK_SIZE.width} ${WATERMARK_SIZE.height}`, + width: width.toString(), + fill: "currentColor" + }); + watermarkEl.innerHTML = ''; + return watermarkEl; + } +}; + +// src/canvas-extensions/floating-edge-canvas-extension.ts +var FloatingEdgeCanvasExtension = class extends CanvasExtension { + isEnabled() { + return "floatingEdgeFeatureEnabled"; + } + init() { + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:data-loaded:after", + (canvas, data, setData) => this.onLoadData(canvas, data) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-moved", + (canvas, node) => this.onNodeMoved(canvas, node) + )); + if (this.plugin.settings.getSetting("allowFloatingEdgeCreation")) { + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:edge-connection-dragging:before", + (canvas, edge, event, newEdge, side) => this.onEdgeStartedDragging(canvas, edge, event, newEdge, side) + )); + } + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:edge-connection-dragging:after", + (canvas, edge, event, newEdge, side) => this.onEdgeStoppedDragging(canvas, edge, event, newEdge, side) + )); + } + onLoadData(canvas, data) { + for (const edgeData of data.edges) { + const edge = canvas.edges.get(edgeData.id); + if (!edge) return console.warn("Imported edge is not yet loaded :("); + this.updateEdgeConnectionSide(edge); + } + } + onNodeMoved(canvas, node) { + const affectedEdges = canvas.getEdgesForNode(node); + for (const edge of affectedEdges) + this.updateEdgeConnectionSide(edge); + } + updateEdgeConnectionSide(edge) { + const edgeData = edge.getData(); + if (edgeData.fromFloating) { + const fixedNodeConnectionPoint = BBoxHelper.getCenterOfBBoxSide(edge.to.node.getBBox(), edge.to.side); + const bestSide = CanvasHelper.getBestSideForFloatingEdge(fixedNodeConnectionPoint, edge.from.node); + if (bestSide !== edge.from.side) { + edge.setData({ + ...edgeData, + fromSide: bestSide + }); + } + } + if (edgeData.toFloating) { + const fixedNodeConnectionPoint = BBoxHelper.getCenterOfBBoxSide(edge.from.node.getBBox(), edge.from.side); + const bestSide = CanvasHelper.getBestSideForFloatingEdge(fixedNodeConnectionPoint, edge.to.node); + if (bestSide !== edge.to.side) { + edge.setData({ + ...edgeData, + toSide: bestSide + }); + } + } + } + onEdgeStartedDragging(canvas, edge, _event, newEdge, _side) { + if (newEdge && this.plugin.settings.getSetting("newEdgeFromSideFloating")) edge.setData({ + ...edge.getData(), + fromFloating: true + // New edges can only get dragged from the "from" side + }); + let cachedViewportNodes = null; + let hasNaNFloatingEdgeDropZones = false; + this.onPointerMove = (event) => { + if (cachedViewportNodes === null || hasNaNFloatingEdgeDropZones || canvas.viewportChanged) { + hasNaNFloatingEdgeDropZones = false; + cachedViewportNodes = canvas.getViewportNodes().map((node) => { + const nodeFloatingEdgeDropZone = this.getFloatingEdgeDropZoneForNode(node); + if (isNaN(nodeFloatingEdgeDropZone.minX) || isNaN(nodeFloatingEdgeDropZone.minY) || isNaN(nodeFloatingEdgeDropZone.maxX) || isNaN(nodeFloatingEdgeDropZone.maxY)) + hasNaNFloatingEdgeDropZones = true; + return [node, nodeFloatingEdgeDropZone]; + }); + } + for (const [node, nodeFloatingEdgeDropZoneClientRect] of cachedViewportNodes) { + const hovering = BBoxHelper.insideBBox({ x: event.clientX, y: event.clientY }, nodeFloatingEdgeDropZoneClientRect, true); + node.nodeEl.classList.toggle("hovering-floating-edge-zone", hovering); + } + }; + document.addEventListener("pointermove", this.onPointerMove); + } + onEdgeStoppedDragging(_canvas, edge, event, _newEdge, side) { + document.removeEventListener("pointermove", this.onPointerMove); + const dropZoneNode = side === "from" ? edge.from.node : edge.to.node; + const floatingEdgeDropZone = this.getFloatingEdgeDropZoneForNode(dropZoneNode); + const wasDroppedInFloatingEdgeDropZone = this.plugin.settings.getSetting("allowFloatingEdgeCreation") ? BBoxHelper.insideBBox({ x: event.clientX, y: event.clientY }, floatingEdgeDropZone, true) : false; + const edgeData = edge.getData(); + if (side === "from" && wasDroppedInFloatingEdgeDropZone == edgeData.fromFloating) return; + if (side === "to" && wasDroppedInFloatingEdgeDropZone == edgeData.toFloating) return; + if (side === "from") edgeData.fromFloating = wasDroppedInFloatingEdgeDropZone; + else edgeData.toFloating = wasDroppedInFloatingEdgeDropZone; + edge.setData(edgeData); + this.updateEdgeConnectionSide(edge); + } + getFloatingEdgeDropZoneForNode(node) { + const nodeElClientBoundingRect = node.nodeEl.getBoundingClientRect(); + const nodeFloatingEdgeDropZoneElStyle = window.getComputedStyle(node.nodeEl, ":after"); + const nodeFloatingEdgeDropZoneSize = { + width: parseFloat(nodeFloatingEdgeDropZoneElStyle.getPropertyValue("width")), + height: parseFloat(nodeFloatingEdgeDropZoneElStyle.getPropertyValue("height")) + }; + return { + minX: nodeElClientBoundingRect.left + (nodeElClientBoundingRect.width - nodeFloatingEdgeDropZoneSize.width) / 2, + minY: nodeElClientBoundingRect.top + (nodeElClientBoundingRect.height - nodeFloatingEdgeDropZoneSize.height) / 2, + maxX: nodeElClientBoundingRect.right - (nodeElClientBoundingRect.width - nodeFloatingEdgeDropZoneSize.width) / 2, + maxY: nodeElClientBoundingRect.bottom - (nodeElClientBoundingRect.height - nodeFloatingEdgeDropZoneSize.height) / 2 + }; + } +}; + +// src/canvas-extensions/edge-highlight-canvas-extension.ts +var EdgeHighlightCanvasExtension = class extends CanvasExtension { + isEnabled() { + return "edgeHighlightEnabled"; + } + init() { + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:selection-changed", + (canvas, oldSelection, updateSelection) => this.onSelectionChanged(canvas, oldSelection) + )); + } + onSelectionChanged(canvas, oldSelection) { + const connectedEdgesToBeHighlighted = new Set(canvas.getSelectionData().nodes.flatMap((nodeData) => { + var _a, _b; + return [ + ...(_a = canvas.edgeFrom.get(canvas.nodes.get(nodeData.id))) != null ? _a : [], + ...this.plugin.settings.getSetting("highlightIncomingEdges") ? (_b = canvas.edgeTo.get(canvas.nodes.get(nodeData.id))) != null ? _b : [] : [] + ]; + })); + for (const edge of canvas.edges.values()) { + edge.lineGroupEl.classList.toggle( + "is-focused", + canvas.selection.has(edge) || connectedEdgesToBeHighlighted.has(edge) + ); + } + } +}; + +// src/canvas-extensions/dataset-exposers/canvas-metadata-exposer.ts +var CanvasMetadataExposerExtension = class extends CanvasExtension { + isEnabled() { + return true; + } + init() { + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:canvas-metadata-changed", + (canvas) => this.updateExposedSettings(canvas) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:canvas-changed", + (canvas) => this.updateExposedSettings(canvas) + )); + } + updateExposedSettings(canvas) { + const startNodeId = canvas.metadata["startNode"]; + for (const [nodeId, node] of canvas.nodes) { + if (nodeId === startNodeId) node.nodeEl.dataset.isStartNode = "true"; + else delete node.nodeEl.dataset.isStartNode; + } + } +}; + +// src/canvas-extensions/dataset-exposers/node-exposer.ts +var CANVAS_NODE_IFRAME_BODY_CLASS = "canvas-node-iframe-body"; +function getExposedNodeData(settings) { + const exposedData = []; + if (settings.getSetting("nodeStylingFeatureEnabled")) exposedData.push("styleAttributes"); + if (settings.getSetting("collapsibleGroupsFeatureEnabled")) exposedData.push("collapsed"); + if (settings.getSetting("portalsFeatureEnabled")) exposedData.push("isPortalLoaded"); + return exposedData; +} +var NodeExposerExtension = class extends CanvasExtension { + isEnabled() { + return true; + } + init() { + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-changed", + (_canvas, node) => { + var _a, _b; + const nodeData = node == null ? void 0 : node.getData(); + if (!nodeData) return; + this.setDataAttributes(node.nodeEl, nodeData); + const iframe = (_b = (_a = node.nodeEl.querySelector("iframe")) == null ? void 0 : _a.contentDocument) == null ? void 0 : _b.body; + if (iframe) this.setDataAttributes(iframe, nodeData); + } + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-editing-state-changed", + (_canvas, node, editing) => { + var _a, _b; + if (!editing) return; + const nodeData = node.getData(); + if (!nodeData) return; + const iframe = (_b = (_a = node.nodeEl.querySelector("iframe")) == null ? void 0 : _a.contentDocument) == null ? void 0 : _b.body; + if (!iframe) return; + iframe.classList.add(CANVAS_NODE_IFRAME_BODY_CLASS); + new MutationObserver(() => iframe.classList.toggle(CANVAS_NODE_IFRAME_BODY_CLASS, true)).observe(iframe, { attributes: true, attributeFilter: ["class"] }); + this.setDataAttributes(iframe, nodeData); + } + )); + } + setDataAttributes(element, nodeData) { + for (const exposedDataKey of getExposedNodeData(this.plugin.settings)) { + const datasetPairs = nodeData[exposedDataKey] instanceof Object ? Object.entries(nodeData[exposedDataKey]) : [[exposedDataKey, nodeData[exposedDataKey]]]; + for (const [key, value] of datasetPairs) { + if (!value) delete element.dataset[key]; + else element.dataset[key] = value; + } + } + } +}; + +// src/canvas-extensions/dataset-exposers/node-interaction-exposer.ts +var TARGET_NODE_DATASET_PREFIX = "target"; +var NodeInteractionExposerExtension = class extends CanvasExtension { + isEnabled() { + return true; + } + init() { + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:node-interaction", + (canvas, node) => { + const nodeData = node == null ? void 0 : node.getData(); + if (!nodeData) return; + const interactionEl = canvas.nodeInteractionLayer.interactionEl; + if (!interactionEl) return; + for (const exposedDataKey of getExposedNodeData(this.plugin.settings)) { + const datasetPairs = nodeData[exposedDataKey] instanceof Object ? Object.entries(nodeData[exposedDataKey]) : [[exposedDataKey, nodeData[exposedDataKey]]]; + for (const [key, value] of datasetPairs) { + const modifiedKey = TARGET_NODE_DATASET_PREFIX + key.toString().charAt(0).toUpperCase() + key.toString().slice(1); + if (!value) delete interactionEl.dataset[modifiedKey]; + else interactionEl.dataset[modifiedKey] = value; + } + } + if (PortalsCanvasExtension.isPortalElement(node)) interactionEl.dataset.isFromPortal = "true"; + else delete interactionEl.dataset.isFromPortal; + } + )); + } +}; + +// src/canvas-extensions/dataset-exposers/edge-exposer.ts +function getExposedEdgeData(settings) { + const exposedData = []; + if (settings.getSetting("edgesStylingFeatureEnabled")) exposedData.push("styleAttributes"); + return exposedData; +} +var EdgeExposerExtension = class extends CanvasExtension { + isEnabled() { + return true; + } + init() { + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:edge-changed", + (_canvas, edge) => { + var _a, _b, _c, _d; + const edgeData = edge == null ? void 0 : edge.getData(); + if (!edgeData) return; + for (const exposedDataKey of getExposedEdgeData(this.plugin.settings)) { + const datasetPairs = edgeData[exposedDataKey] instanceof Object ? Object.entries(edgeData[exposedDataKey]) : [[exposedDataKey, edgeData[exposedDataKey]]]; + for (const [key, value] of datasetPairs) { + const stringifiedKey = key == null ? void 0 : key.toString(); + if (!stringifiedKey) continue; + if (!value) { + delete edge.path.display.dataset[stringifiedKey]; + if ((_a = edge.fromLineEnd) == null ? void 0 : _a.el) delete edge.fromLineEnd.el.dataset[stringifiedKey]; + if ((_b = edge.toLineEnd) == null ? void 0 : _b.el) delete edge.toLineEnd.el.dataset[stringifiedKey]; + } else { + edge.path.display.dataset[stringifiedKey] = value.toString(); + if ((_c = edge.fromLineEnd) == null ? void 0 : _c.el) edge.fromLineEnd.el.dataset[stringifiedKey] = value.toString(); + if ((_d = edge.toLineEnd) == null ? void 0 : _d.el) edge.toLineEnd.el.dataset[stringifiedKey] = value.toString(); + } + } + } + } + )); + } +}; + +// src/canvas-extensions/dataset-exposers/canvas-wrapper-exposer.ts +var EXPOSED_SETTINGS = [ + "disableFontSizeRelativeToZoom", + "hideBackgroundGridWhenInReadonly", + "collapsibleGroupsFeatureEnabled", + "collapsedGroupPreviewOnDrag", + "allowFloatingEdgeCreation" +]; +var CanvasWrapperExposerExtension = class extends CanvasExtension { + isEnabled() { + return true; + } + init() { + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:settings-changed", + () => this.updateExposedSettings(this.plugin.getCurrentCanvas()) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:canvas-changed", + (canvas) => this.updateExposedSettings(canvas) + )); + this.plugin.registerEvent(this.plugin.app.workspace.on( + "advanced-canvas:dragging-state-changed", + (canvas, dragging) => { + if (dragging) canvas.wrapperEl.dataset.isDragging = "true"; + else delete canvas.wrapperEl.dataset.isDragging; + } + )); + } + updateExposedSettings(canvas) { + if (!canvas) return; + for (const setting of EXPOSED_SETTINGS) { + canvas.wrapperEl.dataset[setting] = this.plugin.settings.getSetting(setting).toString(); + } + } +}; + +// src/main.ts +var PATCHERS = [ + CanvasPatcher, + LinkSuggestionsPatcher, + EmbedPatcher, + MetadataCachePatcher, + BacklinksPatcher, + OutgoingLinksPatcher, + PropertiesPatcher, + SearchPatcher, + SearchCommandPatcher +]; +var CANVAS_EXTENSIONS = [ + // Advanced JSON Canvas Extensions + MetadataCanvasExtension, + NodeStylesExtension, + EdgeStylesExtension, + NodeRatioCanvasExtension, + FloatingEdgeCanvasExtension, + AutoResizeNodeCanvasExtension, + CollapsibleGroupsCanvasExtension, + ColorPaletteCanvasExtension, + PresentationCanvasExtension, + PortalsCanvasExtension, + // UI Extensions (Non-savable data) + CanvasMetadataExposerExtension, + CanvasWrapperExposerExtension, + NodeExposerExtension, + EdgeExposerExtension, + NodeInteractionExposerExtension, + FrontmatterControlButtonCanvasExtension, + BetterDefaultSettingsCanvasExtension, + CommandsCanvasExtension, + BetterReadonlyCanvasExtension, + GroupCanvasExtension, + VariableBreakpointCanvasExtension, + EdgeHighlightCanvasExtension, + AutoFileNodeEdgesCanvasExtension, + FlipEdgeCanvasExtension, + ZOrderingCanvasExtension, + ExportCanvasExtension, + FocusModeCanvasExtension, + EncapsulateCanvasExtension, + EdgeSelectionCanvasExtension +]; +var AdvancedCanvasPlugin = class extends import_obsidian19.Plugin { + async onload() { + IconsHelper.addIcons(); + this.settings = new SettingsManager(this); + await this.settings.loadSettings(); + this.settings.addSettingsTab(); + this.windowsManager = new WindowsManager(this); + this.patchers = PATCHERS.map((Patcher2) => { + try { + return new Patcher2(this); + } catch (e) { + console.error(`Error initializing patcher ${Patcher2.name}:`, e); + } + }); + this.canvasExtensions = CANVAS_EXTENSIONS.map((Extension) => { + try { + return new Extension(this); + } catch (e) { + console.error(`Error initializing ac-extension ${Extension.name}:`, e); + } + }); + } + onunload() { + } + getCanvases() { + return this.app.workspace.getLeavesOfType("canvas").map((leaf) => { + var _a; + return (_a = leaf.view) == null ? void 0 : _a.canvas; + }).filter((canvas) => canvas); + } + getCurrentCanvasView() { + const canvasView = this.app.workspace.getActiveViewOfType(import_obsidian19.ItemView); + if ((canvasView == null ? void 0 : canvasView.getViewType()) !== "canvas") return null; + return canvasView; + } + getCurrentCanvas() { + var _a; + return ((_a = this.getCurrentCanvasView()) == null ? void 0 : _a.canvas) || null; + } + createFileSnapshot(path, content) { + var _a; + const fileRecoveryPlugin = (_a = this.app.internalPlugins.plugins["file-recovery"]) == null ? void 0 : _a.instance; + if (!fileRecoveryPlugin) return; + fileRecoveryPlugin.forceAdd(path, content); + } + // this.app.plugins.plugins["advanced-canvas"].enableDebugMode() + enableDebugMode() { + if (this.debugHelper) return; + this.debugHelper = new DebugHelper(this); + } +}; + +/* nosourcemap */ \ No newline at end of file diff --git a/Diagrams/.obsidian/plugins/advanced-canvas/manifest.json b/Diagrams/.obsidian/plugins/advanced-canvas/manifest.json new file mode 100644 index 000000000000..ab70d2d52e38 --- /dev/null +++ b/Diagrams/.obsidian/plugins/advanced-canvas/manifest.json @@ -0,0 +1,11 @@ +{ + "id": "advanced-canvas", + "name": "Advanced Canvas", + "version": "5.6.5", + "minAppVersion": "1.1.0", + "description": "Supercharge your canvas experience! Create presentations, flowcharts and more!", + "author": "Developer-Mike", + "authorUrl": "https://github.com/Developer-Mike", + "fundingUrl": "https://ko-fi.com/X8X27IA08", + "isDesktopOnly": false +} diff --git a/Diagrams/.obsidian/plugins/advanced-canvas/styles.css b/Diagrams/.obsidian/plugins/advanced-canvas/styles.css new file mode 100644 index 000000000000..5592a628015c --- /dev/null +++ b/Diagrams/.obsidian/plugins/advanced-canvas/styles.css @@ -0,0 +1,508 @@ +/* src/styles.scss */ +.properties-field > .setting-item-info { + flex: 0; + margin: 0; + padding: var(--size-4-1) var(--size-4-2); + border: var(--input-border-width) solid var(--background-modifier-border); + border-radius: var(--input-radius) 0 0 var(--input-radius); +} +.properties-field > .setting-item-control > input { + width: 100%; + border-radius: 0 var(--input-radius) var(--input-radius) 0; +} +.ac-settings-heading { + border-bottom: 1px solid var(--color-accent); +} +.ac-settings-heading:not(:first-child) { + margin-top: var(--size-4-10) !important; +} +.ac-settings-heading:has(.checkbox-container:not(.is-enabled)) { + border-bottom-color: var(--background-modifier-border-hover); +} +.ac-settings-heading .setting-item-description { + margin-inline-end: 20px; +} +.settings-header-children { + transform-origin: top center; + transform: scaleY(1); + transition: transform 0.2s ease-in-out; +} +.settings-header-children details { + flex-direction: column; + align-items: initial; +} +.ac-settings-heading:has(.checkbox-container:not(.is-enabled)) + .settings-header-children { + opacity: 0.5; + pointer-events: none; + height: 0; + transform: scaleY(0); +} +details.setting-item[open] > summary { + margin-bottom: 0.75em; +} +details.setting-item > *:not(summary) { + padding-left: 1em; + border-left: 1px solid var(--color-accent); +} +.kofi-banner { + position: relative; + display: flex; + flex-direction: column; + padding: var(--size-4-3); + background-color: var(--background-secondary); + border: 1px solid var(--divider-color); + border-radius: var(--radius-s); +} +.kofi-banner h1 { + margin: 0; + margin-bottom: 10px; + font-size: var(--font-ui-large); + font-weight: 600; +} +.kofi-banner .progress-container { + display: flex; + flex-direction: row; + align-items: center; + justify-items: center; +} +.kofi-banner .progress-container progress { + background: transparent; +} +.kofi-banner .progress-container progress::-webkit-progress-bar { + background-color: var(--background-modifier-border); + border-radius: var(--input-radius); +} +.kofi-banner .progress-container progress::-webkit-progress-value { + background-color: var(--color-accent); + border-radius: var(--input-radius); +} +.kofi-banner .progress-container .hourly-rate { + margin-left: 10px; + font-weight: 600; +} +.kofi-banner .ac-kofi-button { + align-self: flex-end; + width: min-content; + height: min-content; + line-height: 0; +} +.kofi-banner .ac-kofi-button img { + min-width: 100px; + width: 25%; + max-width: 200px; +} +.canvas-wrapper > .document-search-container { + transform: translateZ(0); + margin: 0; +} +.canvas-wrapper:not(.mod-readonly) .show-while-readonly { + display: none; +} +.canvas-control-item[data-toggled=true] { + background-color: var(--color-accent); +} +.canvas-control-item[data-toggled=true] svg { + stroke: var(--text-on-accent); +} +.reactive-node, +.canvas-node[data-shape=database], +.canvas-node[data-shape=document], +.canvas-node[data-shape=predefined-process], +.canvas-node[data-shape=diamond] { + --border-color: rgb(var(--canvas-color)); + --border-width: 3px; + --box-shadow: none; +} +.reactive-node.is-focused, +.is-focused.canvas-node[data-shape=database], +.is-focused.canvas-node[data-shape=document], +.is-focused.canvas-node[data-shape=predefined-process], +.is-focused.canvas-node[data-shape=diamond], +.reactive-node.is-selected, +.is-selected.canvas-node[data-shape=database], +.is-selected.canvas-node[data-shape=document], +.is-selected.canvas-node[data-shape=predefined-process], +.is-selected.canvas-node[data-shape=diamond] { + --border-color: var(--color-accent); + --border-width: 5px; + --box-shadow: var(--shadow-border-accent); +} +.reactive-node.is-themed, +.is-themed.canvas-node[data-shape=database], +.is-themed.canvas-node[data-shape=document], +.is-themed.canvas-node[data-shape=predefined-process], +.is-themed.canvas-node[data-shape=diamond] { + --border-color: rgba(var(--canvas-color), 0.7); +} +.reactive-node.is-themed.is-focused, +.is-themed.is-focused.canvas-node[data-shape=database], +.is-themed.is-focused.canvas-node[data-shape=document], +.is-themed.is-focused.canvas-node[data-shape=predefined-process], +.is-themed.is-focused.canvas-node[data-shape=diamond], +.reactive-node.is-themed.is-selected, +.is-themed.is-selected.canvas-node[data-shape=database], +.is-themed.is-selected.canvas-node[data-shape=document], +.is-themed.is-selected.canvas-node[data-shape=predefined-process], +.is-themed.is-selected.canvas-node[data-shape=diamond] { + --border-color: rgb(var(--canvas-color)); + --box-shadow: var(--shadow-border-themed); +} +.canvas-node[data-text-align=center] .markdown-preview-view { + scrollbar-gutter: auto; +} +.canvas-node[data-text-align=center] .markdown-preview-view .markdown-preview-section { + display: flex; + flex-direction: column; + justify-content: center; + min-height: 0 !important; + text-align: center; + vertical-align: middle; +} +.canvas-node[data-text-align=right] { + text-align: right; +} +.canvas-node[data-shape] .canvas-node-container .markdown-preview-view.markdown-rendered { + transform: unset; +} +.canvas-node[data-shape=pill] .canvas-node-container { + border-radius: 5000px; +} +.canvas-node[data-shape=diamond] { +} +.canvas-node[data-shape=diamond].is-focused, +.canvas-node[data-shape=diamond].is-selected { + border-radius: var(--radius-m); + outline: 2px solid var(--color-accent); + outline-offset: 5px; +} +.canvas-node[data-shape=diamond] .canvas-node-container { + border: none; + box-shadow: none !important; +} +.canvas-node[data-shape=diamond] .canvas-node-container:not(:has(.embed-iframe)) { + mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 141.42135624 141.42135624' preserveAspectRatio='none'%3E%3Cstyle%3E rect %7B transform-origin: center; transform: rotate(45deg) scale(1.05); %7D %3C/style%3E%3Crect rx='8' x='20.71067812' y='20.71067812' width='100' height='100' /%3E%3C/svg%3E"); + -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 141.42135624 141.42135624' preserveAspectRatio='none'%3E%3Cstyle%3E rect %7B transform-origin: center; transform: rotate(45deg) scale(1.05); %7D %3C/style%3E%3Crect rx='8' x='20.71067812' y='20.71067812' width='100' height='100' /%3E%3C/svg%3E"); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: 100%; + -webkit-mask-size: 100%; +} +.canvas-node[data-shape=diamond] .canvas-node-container .canvas-node-placeholder::after { + mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 141.42135624 141.42135624' preserveAspectRatio='none'%3E%3Cstyle%3E rect %7B transform-origin: center; transform: rotate(45deg) scale(1.05); %7D %3C/style%3E%3Crect rx='8' x='20.71067812' y='20.71067812' width='100' height='100' /%3E%3C/svg%3E"); + -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 141.42135624 141.42135624' preserveAspectRatio='none'%3E%3Cstyle%3E rect %7B transform-origin: center; transform: rotate(45deg) scale(1.05); %7D %3C/style%3E%3Crect rx='8' x='20.71067812' y='20.71067812' width='100' height='100' /%3E%3C/svg%3E"); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: 100%; + -webkit-mask-size: 100%; +} +.canvas-node[data-shape=diamond]::before { + mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 141.42135624 141.42135624' preserveAspectRatio='none'%3E%3Cstyle%3E rect %7B transform-origin: center; transform: rotate(45deg) scale(1.05); %7D %3C/style%3E%3Crect rx='8' x='20.71067812' y='20.71067812' width='100' height='100' /%3E%3C/svg%3E"); + -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 141.42135624 141.42135624' preserveAspectRatio='none'%3E%3Cstyle%3E rect %7B transform-origin: center; transform: rotate(45deg) scale(1.05); %7D %3C/style%3E%3Crect rx='8' x='20.71067812' y='20.71067812' width='100' height='100' /%3E%3C/svg%3E"); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: 100%; + -webkit-mask-size: 100%; + content: ""; + position: absolute; + top: calc(var(--border-width) * -1); + left: calc(var(--border-width) * -1); + width: calc(100% + var(--border-width) * 2); + height: calc(100% + var(--border-width) * 2); + background-color: var(--border-color); +} +.canvas-node[data-shape=parallelogram] .canvas-node-container { + transform: skewX(-20deg); + backface-visibility: hidden; +} +.canvas-node[data-shape=parallelogram] .canvas-node-container .canvas-node-content .markdown-embed-content { + transform: skewX(20deg); +} +.canvas-node[data-shape=circle] .canvas-node-container { + border-radius: 50%; +} +.canvas-node[data-shape=circle] .canvas-node-container .markdown-preview-view { + overflow-y: initial; +} +.canvas-node[data-shape=predefined-process] .canvas-node-container .canvas-node-content { + padding: 0 10px; +} +.canvas-node[data-shape=predefined-process] .canvas-node-container::before, +.canvas-node[data-shape=predefined-process] .canvas-node-container::after { + content: ""; + z-index: 1; + position: absolute; + top: 0; + width: 0; + height: 100%; + border-left: var(--border-width) solid var(--border-color); +} +.canvas-node[data-shape=predefined-process] .canvas-node-container::before { + left: calc(10px - var(--border-width)); +} +.canvas-node[data-shape=predefined-process] .canvas-node-container::after { + right: calc(10px - var(--border-width)); +} +.canvas-node[data-shape=document] { + --border-width: 2.5px; + filter: drop-shadow(0 var(--border-width) 0 var(--border-color)) drop-shadow(0 calc(var(--border-width) * -1) 0 var(--border-color)); +} +.canvas-node[data-shape=document] .canvas-node-container { + mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 75 45' preserveAspectRatio='none'%3E%3Cpath d='M75 0 75 39.375Q56.25 29.25 37.5 39.375 18.75 49.5 0 39.375L0 0Z' /%3E%3C/svg%3E"); + -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 75 45' preserveAspectRatio='none'%3E%3Cpath d='M75 0 75 39.375Q56.25 29.25 37.5 39.375 18.75 49.5 0 39.375L0 0Z' /%3E%3C/svg%3E"); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: 100%; + -webkit-mask-size: 100%; + border: var(--border-width) solid var(--border-color); + border-top: none; + border-bottom: none; +} +.canvas-node[data-shape=document].is-focused, +.canvas-node[data-shape=document].is-selected { + --border-width: 4px; +} +.canvas-node[data-shape=database] { +} +.canvas-node[data-shape=database] .canvas-node-container { + border: var(--border-width) solid var(--border-color); + border-bottom: 0; + border-top: 0; + border-radius: 0; + box-shadow: none !important; +} +.canvas-node[data-shape=database] .canvas-node-container .canvas-node-placeholder { + transform: translateY(25px); +} +.canvas-node[data-shape=database]::before, +.canvas-node[data-shape=database]::after { + content: ""; + position: absolute; + left: 0; + box-sizing: border-box; + width: 100%; + height: 50px; + border-radius: 50%; + border: var(--border-width) solid var(--border-color); + background-color: var(--background-primary); +} +.canvas-node[data-shape=database]::after { + top: -25px; +} +.canvas-node[data-shape=database]::before { + bottom: -25px; +} +.canvas-node[data-shape=database].is-themed .canvas-node-content { + background-color: transparent; +} +.canvas-node[data-shape=database].is-themed:not(:has(.embed-iframe)) .canvas-node-container, +.canvas-node[data-shape=database].is-themed:not(:has(.embed-iframe))::after, +.canvas-node[data-shape=database].is-themed:not(:has(.embed-iframe))::before { + box-shadow: inset 0 0 0 1000px rgba(var(--canvas-color), 0.07) !important; +} +.canvas-node[data-shape=database] .canvas-node-content:not(:has(.embed-iframe)) { + transform: translateY(20px); +} +.canvas-node[data-shape=database]:has(.embed-iframe)::after { + z-index: -1; +} +.canvas-node[data-border=dashed] .canvas-node-container { + box-shadow: none; + border-style: dashed; +} +.canvas-node[data-border=dotted] .canvas-node-container { + box-shadow: none; + border-style: dotted; +} +.canvas-node[data-border=invisible] { + box-shadow: none; +} +.canvas-node[data-border=invisible]:not(.is-focused):not(.is-selected) .canvas-node-container { + border-color: transparent !important; +} +.canvas-node[data-border=invisible] .canvas-node-label { + display: none; +} +.canvas-node[data-border=invisible] .canvas-node-container { + background-color: transparent; + box-shadow: none; +} +.canvas-node[data-border][data-shape=predefined-process] { + --border-width: 2px; +} +.canvas-node[data-border][data-shape=predefined-process] .is-focused, +.canvas-node[data-border][data-shape=predefined-process] .is-selected { + --border-width: 2px; +} +.canvas-node[data-border=dashed][data-shape=predefined-process] .canvas-node-container::before, +.canvas-node[data-border=dashed][data-shape=predefined-process] .canvas-node-container::after { + border-left: var(--border-width) dashed var(--border-color); +} +.canvas-node[data-border=dotted][data-shape=predefined-process] .canvas-node-container::before, +.canvas-node[data-border=dotted][data-shape=predefined-process] .canvas-node-container::after { + border-left: var(--border-width) dotted var(--border-color); +} +.canvas-node[data-border][data-shape=document] .canvas-node-container { + border-top: none; + border-bottom: none; +} +.canvas-edges path[data-path=dotted] { + stroke-dasharray: calc(3px * var(--zoom-multiplier)); +} +.canvas-edges path[data-path=short-dashed] { + stroke-dasharray: 9px; +} +.canvas-edges path[data-path=long-dashed] { + stroke-dasharray: 18px; +} +.canvas-edges [data-arrow=triangle-outline] polygon, +.canvas-edges [data-arrow=diamond-outline] polygon, +.canvas-edges [data-arrow=circle-outline] polygon { + fill: var(--canvas-background); + stroke: rgb(var(--canvas-color)); + stroke-width: calc(3px * var(--zoom-multiplier)); +} +.canvas-edges [data-arrow=thin-triangle] polygon { + fill: transparent; + stroke: rgb(var(--canvas-color)); + stroke-width: calc(4px * var(--zoom-multiplier)); +} +.canvas.is-exporting { + --zoom-multiplier: 1; +} +.canvas.is-exporting * { + pointer-events: none !important; + transition: none !important; +} +.canvas.is-exporting .collapse-button { + display: none; +} +.canvas.is-exporting #watermark-ac { + z-index: 9999999; + position: absolute; +} +.canvas-wrapper[data-collapsible-groups-feature-enabled=true] .canvas.is-exporting .canvas-node .canvas-group-label { + left: 0; +} +.progress-bar-modal-ac { + margin-top: 0.75em; +} +.progress-bar-modal-ac.error .setting-progress-bar { + color: var(--color-error); +} +.canvas-wrapper[data-disable-font-size-relative-to-zoom=true] { + --zoom-multiplier: 1 !important; +} +.canvas-wrapper.mod-readonly[data-hide-background-grid-when-in-readonly=true] .canvas-background { + visibility: hidden; +} +.collapse-button { + position: absolute; + left: 0; + top: calc(-1 * var(--size-4-1) * var(--zoom-multiplier)); + padding: var(--size-4-1) var(--size-4-2); + transform-origin: bottom left; + transform: translate(0, -100%) scale(var(--zoom-multiplier)); + border-radius: var(--radius-s); + color: var(--text-muted); + background-color: rgba(var(--canvas-color), 0.1); + font-size: 1.5em; + line-height: 1; + pointer-events: initial; + cursor: pointer; + transition: transform 500ms cubic-bezier(0.16, 1, 0.3, 1); +} +.canvas-wrapper[data-collapsible-groups-feature-enabled=true] .canvas-node .canvas-group-label { + left: calc(40px * var(--zoom-multiplier)); +} +.canvas-node[data-collapsed] .canvas-node-container { + display: none; +} +.canvas-node[data-collapsed] .canvas-group-label { + max-width: initial; +} +.canvas-wrapper[data-collapsed-group-preview-on-drag=true][data-is-dragging] .canvas-node[data-collapsed] .canvas-node-container { + display: block; + opacity: 0.5; + border-style: dashed; +} +.canvas-wrapper[data-collapsed-group-preview-on-drag=true][data-is-dragging] .canvas-node[data-collapsed] .canvas-node-container .canvas-node-content { + background-color: transparent; +} +.canvas-node-interaction-layer[data-target-collapsed] .canvas-node-resizer { + pointer-events: none; + cursor: inherit; +} +.canvas-node-interaction-layer[data-target-collapsed] .canvas-node-resizer .canvas-node-connection-point { + display: none; + pointer-events: none; +} +.canvas-wrapper[data-allow-floating-edge-creation=true] .canvas.is-connecting .canvas-node:not(.canvas-node-group)::after { + all: unset; + content: ""; + z-index: 100; + position: absolute; + top: 50%; + left: 50%; + width: max(10px, 100% - 50px * var(--zoom-multiplier) * 2); + height: max(10px, 100% - 50px * var(--zoom-multiplier) * 2); + transform: translate(-50%, -50%); + border-radius: var(--radius-m); + outline: calc(4px * var(--zoom-multiplier)) dashed hsla(var(--color-accent-hsl), 0.5); +} +.canvas-wrapper[data-allow-floating-edge-creation=true] .canvas.is-connecting .canvas-node:not(.canvas-node-group).hovering-floating-edge-zone::after { + outline-color: var(--color-accent); + outline-style: solid; + background-color: hsla(var(--color-accent-hsl), 0.1); +} +.canvas-wrapper[data-focus-mode-enabled=true] .canvas:has(.canvas-node.is-focused) .canvas-node:not(.is-focused) { + filter: blur(5px); +} +.canvas-wrapper[data-focus-mode-enabled=true] .canvas:has(.canvas-node.is-focused) .canvas-edges { + filter: blur(5px); +} +.canvas-wrapper[data-focus-mode-enabled=true] .canvas:has(.canvas-node.is-focused) .canvas-path-label-wrapper { + filter: blur(5px); +} +.canvas-wrapper.presentation-mode .canvas-controls { + visibility: hidden; +} +.canvas-wrapper.presentation-mode .canvas-card-menu { + visibility: hidden; +} +.canvas-wrapper:not(.presentation-mode) .canvas-node[data-is-start-node=true]::before { + content: "Start"; + position: absolute; + top: calc(-1 * var(--size-4-1) * var(--zoom-multiplier)); + right: 0; + transform: translate(0, -100%) scale(var(--zoom-multiplier)); + transform-origin: bottom right; + max-width: calc(100% / var(--zoom-multiplier)); + padding: var(--size-4-1) var(--size-4-2); + font-size: 1em; + border-radius: var(--radius-s); + color: var(--color-green); + background-color: rgba(var(--color-green-rgb), 0.1); +} +.canvas-node[data-is-portal-loaded=true] { + pointer-events: all; +} +.canvas-node[data-is-portal-loaded=true]:not(.is-focused) { + pointer-events: none; +} +.canvas-node[data-is-portal-loaded=true]:not(.is-focused) .canvas-node-label { + pointer-events: all; +} +.canvas-node[data-is-portal-loaded=true] .canvas-node-container { + background-color: transparent; + border-style: dashed; +} +.canvas-node[data-is-portal-loaded=true] .canvas-node-container .canvas-node-content { + display: none; +} +.canvas-node-interaction-layer[data-is-from-portal=true] .canvas-node-resizer { + pointer-events: none; + cursor: inherit; +} +.canvas-node-interaction-layer[data-is-from-portal=true] .canvas-node-resizer .canvas-node-connection-point { + pointer-events: all; +} diff --git a/Diagrams/.obsidian/workspace.json b/Diagrams/.obsidian/workspace.json index b1ee9a62a17d..2fc2bcc72d34 100644 --- a/Diagrams/.obsidian/workspace.json +++ b/Diagrams/.obsidian/workspace.json @@ -11,10 +11,17 @@ "id": "d3b4cee07f48b93b", "type": "leaf", "state": { - "type": "empty", - "state": {}, - "icon": "lucide-file", - "title": "New tab" + "type": "canvas", + "state": { + "file": "File Structure.canvas", + "viewState": { + "x": -670, + "y": 70, + "zoom": -0.2612571403908114 + } + }, + "icon": "lucide-layout-dashboard", + "title": "File Structure" } } ] @@ -177,5 +184,8 @@ } }, "active": "d3b4cee07f48b93b", - "lastOpenFiles": [] + "lastOpenFiles": [ + "File Structure.png", + "File Structure Light.png" + ] } \ No newline at end of file diff --git a/Diagrams/File Structure.canvas b/Diagrams/File Structure.canvas index 815461432420..111ba1d35e6d 100644 --- a/Diagrams/File Structure.canvas +++ b/Diagrams/File Structure.canvas @@ -1,647 +1,352 @@ { "nodes":[ - { - "id":"24bf9c010517c043", - "type":"group", - "styleAttributes":{ - "border":null - }, - "x":-480, - "y":-740, - "width":460, - "height":760, - "label":"Actuator Subsystems" - }, - {"id":"10d2e8f294485406","type":"group","x":40,"y":-740,"width":360,"height":520,"label":"Generic Devices"}, - {"id":"b257e56e060bcf72","type":"group","x":-1060,"y":-1080,"width":360,"height":300,"label":"Legend"}, - {"id":"c387321b908f5578","type":"group","x":-480,"y":-1160,"width":240,"height":360,"label":"Drive Subsystem"}, - { - "id":"6cb595b6641c5429", - "type":"text", - "text":"Turret", - "styleAttributes":{ - "textAlign":"center", - "shape":null - }, - "x":-440, - "y":-560, - "width":160, - "height":60, - "color":"5" - }, - { - "id":"7c67cdb9e592c4a8", - "type":"text", - "text":"Actuators_", - "styleAttributes":{"textAlign":"center","shape":"database"}, - "x":-440, - "y":-680, - "width":160, - "height":60 - }, - { - "id":"c60fab6b02e73c2d", + {"id":"c7a293dd880903d3","type":"group","x":-1100,"y":-100,"width":520,"height":760,"color":"#dbb8ff","label":"Robot"}, + {"id":"10d2e8f294485406","type":"group","x":-660,"y":-520,"width":420,"height":360,"color":"#000000","label":"Generic Devices"}, + {"id":"b257e56e060bcf72","type":"group","x":-1100,"y":-480,"width":380,"height":320,"color":"#000000","label":"Legend"}, + {"id":"74a8af74db0165b7","type":"group","x":-820,"y":-60,"width":200,"height":580,"color":"#8affc8","label":"Intake"}, + {"id":"f16505c7bd27356d","type":"group","x":-540,"y":-100,"width":300,"height":300,"color":"#dbb8ff","label":"Commands for Auto"}, + {"id":"adac891606d77fd1","type":"group","x":-1060,"y":-60,"width":200,"height":417,"color":"#8affc8","label":"Turret"}, + {"id":"6626b9ea1314feef","type":"group","x":-540,"y":260,"width":300,"height":220,"color":"#dbb8ff","label":"Auto Paths"}, + {"id":"80d156272a2fef37","type":"group","x":-1060,"y":400,"width":200,"height":180,"color":"#8affc8","label":"Lift"}, + { + "id":"02bb80ae766461f2", "type":"text", - "text":"Flywheel Motor", + "text":"Belt Servo", "styleAttributes":{"textAlign":"center","shape":"pill"}, - "x":-220, - "y":-560, + "x":-800, + "y":40, "width":160, "height":60, "color":"1" }, { - "id":"4b4b925b55e20a4b", + "id":"38e398b21a46cae2", "type":"text", - "text":"Rotation Motor", + "text":"Transfer Servo", "styleAttributes":{"textAlign":"center","shape":"pill"}, - "x":-220, - "y":-480, + "x":-800, + "y":120, "width":160, "height":60, "color":"1" }, { - "id":"b6ca95068fb87cd1", + "id":"d87d0682d6bf4d0e", "type":"text", - "text":"Specific\nDevices", + "text":"Upper Proximity Sensor 1", "styleAttributes":{"textAlign":"center","shape":"pill"}, - "x":-860, - "y":-1060, - "width":140, + "x":-800, + "y":200, + "width":160, "height":60, "color":"1" }, { - "id":"1e2cad7776a30e09", - "type":"text", - "text":"Folders", - "styleAttributes":{"textAlign":"center","shape":"database"}, - "x":-860, - "y":-960, - "width":140, - "height":60 - }, - { - "id":"fea165c26dfac7b4", - "type":"text", - "text":"Primary Classes", - "styleAttributes":{"textAlign":"center","shape":"predefined-process"}, - "x":-1040, - "y":-1060, - "width":140, - "height":80, - "color":"6" - }, - { - "id":"e39752447e25fe9b", - "type":"text", - "text":"Generic Device Classes", - "styleAttributes":{"textAlign":"center","shape":"circle"}, - "x":-1040, - "y":-880, - "width":140, - "height":80, - "color":"3" - }, - { - "id":"b3d29ccbc0207fba", - "type":"text", - "text":"Subsystem Classes", - "styleAttributes":{ - "textAlign":"center", - "shape":null - }, - "x":-1040, - "y":-960, - "width":140, - "height":60, - "color":"5" - }, - { - "id":"36c91406159c570c", + "id":"f1677c76d3d30cc6", "type":"text", - "text":"Lift", - "styleAttributes":{ - "textAlign":"center", - "shape":null - }, - "x":-440, - "y":-80, + "text":"Upper Proximity Sensor 2", + "styleAttributes":{"textAlign":"center","shape":"pill"}, + "x":-800, + "y":280, "width":160, "height":60, - "color":"5" + "color":"1" }, { - "id":"46567539d2a5035d", + "id":"1ec493d72b30265a", "type":"text", - "text":"Lift Motor?", + "text":"Lower Proximity Sensor 1", "styleAttributes":{"textAlign":"center","shape":"pill"}, - "x":-220, - "y":-80, + "x":-800, + "y":360, "width":160, "height":60, "color":"1" }, { - "id":"38a0d38b66a11a14", + "id":"aee4cb3f885593bd", "type":"text", - "text":"Intake Motor", + "text":"Lower Proximity Sensor 2", "styleAttributes":{"textAlign":"center","shape":"pill"}, - "x":-220, - "y":-320, + "x":-800, + "y":440, "width":160, "height":60, "color":"1" }, { - "id":"4d43db858659fbed", + "id":"eec09a5aa25e2138", "type":"text", - "text":"Belt Servo", + "text":"Intake Motor", "styleAttributes":{"textAlign":"center","shape":"pill"}, - "x":-220, - "y":-240, + "x":-800, + "y":-40, "width":160, "height":60, "color":"1" }, { - "id":"29fb84e8134463b3", + "id":"46567539d2a5035d", "type":"text", - "text":"Transfer Servo", + "text":"Lift Servo 1", "styleAttributes":{"textAlign":"center","shape":"pill"}, - "x":-220, - "y":-160, + "x":-1040, + "y":420, "width":160, "height":60, "color":"1" }, { - "id":"d8d4dacf5920c2cb", + "id":"d72359f7590e11bc", "type":"text", - "text":"Hood Servo", + "text":"Lift Servo 2", "styleAttributes":{"textAlign":"center","shape":"pill"}, - "x":-220, - "y":-400, + "x":-1040, + "y":500, "width":160, "height":60, "color":"1" }, { - "id":"3fe96a913c4c7045", + "id":"419358a94762377d", "type":"text", - "text":"Hardware_", - "styleAttributes":{"textAlign":"center","shape":"database"}, - "x":-1020, - "y":-680, - "width":140, - "height":60 + "text":"Drivetrain", + "styleAttributes":{"textAlign":"center"}, + "x":-820, + "y":560, + "width":200, + "height":60, + "color":"#8affc8" }, { - "id":"b0917a192e867cbe", + "id":"2dfa1560fb6faad8", "type":"text", - "text":"Teleop_", - "styleAttributes":{"textAlign":"center","shape":"database"}, - "x":-1020, - "y":-540, - "width":140, - "height":60 + "text":"Dual Proximity Sensor", + "styleAttributes":{"textAlign":"center","shape":"circle"}, + "x":-620, + "y":-280, + "width":160, + "height":80, + "color":"3" }, { - "id":"10a4fa2477f2c9da", + "id":"623d0968f6489291", "type":"text", - "text":"Main_", - "styleAttributes":{"textAlign":"center","shape":"database"}, - "x":-1220, - "y":-540, - "width":140, - "height":60 + "text":"Color/Proximity Sensor", + "styleAttributes":{"textAlign":"center","shape":"circle"}, + "x":-420, + "y":-280, + "width":160, + "height":80, + "color":"3" }, { - "id":"781182d601f21fe3", + "id":"64070cd56adeb48a", "type":"text", - "text":"Intake", - "styleAttributes":{ - "textAlign":"center", - "shape":null - }, - "x":-440, - "y":-320, + "text":"CRServo", + "styleAttributes":{"textAlign":"center","shape":"circle"}, + "x":-420, + "y":-380, "width":160, - "height":60, - "color":"5" + "height":80, + "color":"3" }, { - "id":"b681d02738b88d07", + "id":"f15beab66ca59231", "type":"text", - "text":"TeleOp Control", - "styleAttributes":{"textAlign":"center"}, - "x":-440, - "y":-980, + "text":"Hall Effect Sensor", + "styleAttributes":{"textAlign":"center","shape":"circle"}, + "x":-620, + "y":-380, "width":160, - "height":60, - "color":"5" + "height":80, + "color":"3" }, { - "id":"3cd44b1464241515", + "id":"ce3a4399dc294b02", "type":"text", - "text":"Processor Classes", - "styleAttributes":{"textAlign":"center","shape":"parallelogram"}, - "x":-860, - "y":-860, - "width":140, - "height":60, - "color":"#6efe6c" + "text":"Servo", + "styleAttributes":{"textAlign":"center","shape":"circle"}, + "x":-420, + "y":-480, + "width":160, + "height":80, + "color":"3" }, { - "id":"d728e0a74da6c0fd", + "id":"b31e377ce216f382", "type":"text", - "text":"Auto_", - "styleAttributes":{"textAlign":"center","shape":"database"}, - "x":-1020, - "y":-400, - "width":140, - "height":60 + "text":"DcMotorEx", + "styleAttributes":{"textAlign":"center","shape":"circle"}, + "x":-620, + "y":-480, + "width":160, + "height":80, + "color":"3" }, { - "id":"c950be02cfc42181", + "id":"c1da076e05ca442a", "type":"text", - "text":"Drivetrain_", - "styleAttributes":{"textAlign":"center","shape":"database"}, - "x":-440, - "y":-1100, - "width":160, + "text":"Robot Poses", + "styleAttributes":{"textAlign":"center"}, + "x":-500, + "y":300, + "width":220, "height":60 }, { - "id":"20c263df8c9982a4", + "id":"b4b3ed793e07669c", "type":"text", - "text":"Auto Pathing", + "text":"Movement Paths", "styleAttributes":{"textAlign":"center"}, - "x":-440, - "y":-900, - "width":160, - "height":60, - "color":"5" + "x":-500, + "y":380, + "width":220, + "height":60 }, { - "id":"f8f6dfb640cbfd1d", + "id":"b3d29ccbc0207fba", "type":"text", - "text":"Devices", + "text":"Subsystem Class", "styleAttributes":{ "textAlign":"center", - "shape":"circle", - "border":null + "shape":null }, - "x":120, - "y":-700, - "width":200, + "x":-1060, + "y":-300, + "width":120, "height":100, - "color":"3" + "color":"5" }, { - "id":"ce3a4399dc294b02", + "id":"fea165c26dfac7b4", "type":"text", - "text":"Servo", - "styleAttributes":{"textAlign":"center","shape":"circle"}, - "x":160, - "y":-400, - "width":120, - "height":60, - "color":"3" + "text":"Primary Classes", + "styleAttributes":{"textAlign":"center","shape":"predefined-process"}, + "x":-900, + "y":-300, + "width":140, + "height":100, + "color":"6" }, { - "id":"b31e377ce216f382", + "id":"e39752447e25fe9b", "type":"text", - "text":"DcMotorEx", + "text":"Generic Device Classes", "styleAttributes":{"textAlign":"center","shape":"circle"}, - "x":80, - "y":-480, + "x":-1060, + "y":-440, "width":120, - "height":60, + "height":100, "color":"3" }, { - "id":"64070cd56adeb48a", + "id":"b6ca95068fb87cd1", "type":"text", - "text":"CRServo", - "styleAttributes":{"textAlign":"center","shape":"circle"}, - "x":240, - "y":-320, - "width":120, - "height":60, - "color":"3" + "text":"Device Class Instances", + "styleAttributes":{"textAlign":"center","shape":"pill"}, + "x":-900, + "y":-440, + "width":140, + "height":100, + "color":"1" }, { - "id":"cb4e9f8e5320c422", + "id":"4b4b925b55e20a4b", "type":"text", - "text":"Robot (LOAD_Hardware_Class)", - "styleAttributes":{"textAlign":"center","shape":"predefined-process"}, - "x":-820, - "y":-620, - "width":260, + "text":"Rotation Motor", + "styleAttributes":{"textAlign":"center","shape":"pill"}, + "x":-1040, + "y":40, + "width":160, "height":60, - "color":"6" - } - ], - "edges":[ - { - "id":"a754ca4983fc848a", - "styleAttributes":{"pathfindingMethod":"square"}, - "toFloating":false, - "fromNode":"781182d601f21fe3", - "fromSide":"right", - "toNode":"38a0d38b66a11a14", - "toSide":"left" - }, - { - "id":"1ff69a492a801c93", - "styleAttributes":{"pathfindingMethod":"square"}, - "toFloating":false, - "fromNode":"781182d601f21fe3", - "fromSide":"right", - "toNode":"4d43db858659fbed", - "toSide":"left" - }, - { - "id":"63cb6bd74dfe514d", - "styleAttributes":{"pathfindingMethod":"square"}, - "toFloating":false, - "fromNode":"781182d601f21fe3", - "fromSide":"right", - "toNode":"29fb84e8134463b3", - "toSide":"left" - }, - { - "id":"f39b6af2b8e48183", - "styleAttributes":{"pathfindingMethod":"square"}, - "toFloating":false, - "fromNode":"6cb595b6641c5429", - "fromSide":"right", - "toNode":"c60fab6b02e73c2d", - "toSide":"left" - }, - { - "id":"67ba26aea9f89a01", - "styleAttributes":{"pathfindingMethod":"square"}, - "toFloating":false, - "fromNode":"6cb595b6641c5429", - "fromSide":"right", - "toNode":"4b4b925b55e20a4b", - "toSide":"left" - }, - { - "id":"e4ac46a6a34dfc96", - "styleAttributes":{"pathfindingMethod":"square"}, - "toFloating":false, - "fromFloating":false, - "fromNode":"6cb595b6641c5429", - "fromSide":"right", - "toNode":"d8d4dacf5920c2cb", - "toSide":"left" - }, - { - "id":"1a3c223f60e7960e", - "styleAttributes":{}, - "toFloating":false, - "fromNode":"36c91406159c570c", - "fromSide":"right", - "toNode":"46567539d2a5035d", - "toSide":"left" - }, - { - "id":"75fb7926f00bf1f2", - "styleAttributes":{"pathfindingMethod":"square"}, - "toFloating":false, - "fromFloating":false, - "fromNode":"b31e377ce216f382", - "fromSide":"left", - "toNode":"38a0d38b66a11a14", - "toSide":"right" - }, - { - "id":"e502478432f11ab2", - "styleAttributes":{"pathfindingMethod":"square"}, - "toFloating":false, - "fromFloating":false, - "fromNode":"b31e377ce216f382", - "fromSide":"left", - "toNode":"c60fab6b02e73c2d", - "toSide":"right" - }, - { - "id":"3d6234ec9ba8b80a", - "styleAttributes":{"pathfindingMethod":"square"}, - "toFloating":false, - "fromFloating":false, - "fromNode":"b31e377ce216f382", - "fromSide":"left", - "toNode":"4b4b925b55e20a4b", - "toSide":"right" - }, - { - "id":"ecf36fe8628d23d4", - "styleAttributes":{"pathfindingMethod":"square"}, - "toFloating":false, - "fromFloating":false, - "fromNode":"b31e377ce216f382", - "fromSide":"left", - "toNode":"46567539d2a5035d", - "toSide":"right" - }, - { - "id":"e520deaeb33f18ea", - "styleAttributes":{"pathfindingMethod":"square","path":"dotted"}, - "toFloating":false, - "fromFloating":false, - "fromNode":"10a4fa2477f2c9da", - "fromSide":"right", - "toNode":"3fe96a913c4c7045", - "toSide":"left" - }, - { - "id":"a490a71e7c0889c4", - "styleAttributes":{"pathfindingMethod":"square","path":"dotted"}, - "toFloating":false, - "fromFloating":false, - "fromNode":"10a4fa2477f2c9da", - "fromSide":"right", - "toNode":"b0917a192e867cbe", - "toSide":"left" - }, - { - "id":"fee5e7b645c72d49", - "styleAttributes":{"pathfindingMethod":"square","path":"dotted"}, - "toFloating":false, - "fromFloating":false, - "fromNode":"10a4fa2477f2c9da", - "fromSide":"right", - "toNode":"d728e0a74da6c0fd", - "toSide":"left" - }, - { - "id":"c27b4cd5b53a39a1", - "styleAttributes":{"pathfindingMethod":"square","path":"dotted"}, - "toFloating":false, - "fromFloating":false, - "fromNode":"3fe96a913c4c7045", - "fromSide":"right", - "toNode":"cb4e9f8e5320c422", - "toSide":"left" - }, - { - "id":"cb54500a03c6dae8", - "styleAttributes":{"pathfindingMethod":"square","path":"dotted"}, - "toFloating":false, - "fromNode":"3fe96a913c4c7045", - "fromSide":"right", - "toNode":"7c67cdb9e592c4a8", - "toSide":"left" - }, - { - "id":"5a67ba206c21c5d5", - "styleAttributes":{"pathfindingMethod":"square","path":"dotted"}, - "toFloating":false, - "fromFloating":false, - "fromNode":"3fe96a913c4c7045", - "fromSide":"right", - "toNode":"c950be02cfc42181", - "toSide":"left" - }, - { - "id":"730fdab1703e2384", - "styleAttributes":{"pathfindingMethod":"square"}, - "toFloating":false, - "fromNode":"cb4e9f8e5320c422", - "fromSide":"right", - "toNode":"36c91406159c570c", - "toSide":"left" - }, - { - "id":"227ee64c216dd8a2", - "styleAttributes":{"pathfindingMethod":"square"}, - "toFloating":false, - "fromNode":"cb4e9f8e5320c422", - "fromSide":"right", - "toNode":"6cb595b6641c5429", - "toSide":"left" + "color":"1" }, { - "id":"da5b6b4b304e2a2a", - "styleAttributes":{"pathfindingMethod":"square"}, - "toFloating":false, - "fromNode":"cb4e9f8e5320c422", - "fromSide":"right", - "toNode":"781182d601f21fe3", - "toSide":"left" + "id":"d8d4dacf5920c2cb", + "type":"text", + "text":"Hood Servo", + "styleAttributes":{"textAlign":"center","shape":"pill"}, + "x":-1040, + "y":120, + "width":160, + "height":60, + "color":"1" }, { - "id":"600959ea0be584d1", - "styleAttributes":{"pathfindingMethod":"square","path":"short-dashed"}, - "toFloating":false, - "fromFloating":false, - "fromNode":"ce3a4399dc294b02", - "fromSide":"left", - "toNode":"29fb84e8134463b3", - "toSide":"right" + "id":"65e50ccd01f10b0f", + "type":"text", + "text":"Gate Servo", + "styleAttributes":{"textAlign":"center","shape":"pill"}, + "x":-1040, + "y":200, + "width":160, + "height":60, + "color":"1" }, { - "id":"59e449d6190f7c62", - "styleAttributes":{"pathfindingMethod":"square","path":"short-dashed"}, - "toFloating":false, - "fromFloating":false, - "fromNode":"ce3a4399dc294b02", - "fromSide":"left", - "toNode":"d8d4dacf5920c2cb", - "toSide":"right" + "id":"43abf2fec7a606ad", + "type":"text", + "text":"Hall Effect Sensor", + "styleAttributes":{"textAlign":"center","shape":"pill"}, + "x":-1040, + "y":280, + "width":160, + "height":60, + "color":"1" }, { - "id":"b4c105fc0c9f9a0b", - "styleAttributes":{"pathfindingMethod":"square"}, - "toFloating":false, - "fromNode":"cb4e9f8e5320c422", - "fromSide":"right", - "toNode":"20c263df8c9982a4", - "toSide":"left" + "id":"c60fab6b02e73c2d", + "type":"text", + "text":"Flywheel Motor", + "styleAttributes":{"textAlign":"center","shape":"pill"}, + "x":-1040, + "y":-40, + "width":160, + "height":60, + "color":"1" }, { - "id":"6c06e6161a19b57b", - "styleAttributes":{"pathfindingMethod":"square"}, - "toFloating":false, - "fromFloating":false, - "fromNode":"cb4e9f8e5320c422", - "fromSide":"right", - "toNode":"b681d02738b88d07", - "toSide":"left" + "id":"67842095d0da2897", + "type":"text", + "text":"Pathing Commands", + "styleAttributes":{"textAlign":"center"}, + "x":-500, + "y":-60, + "width":220, + "height":60 }, { - "id":"c3e114e590ec207f", - "styleAttributes":{ - "path":"dotted", - "arrow":null - }, - "toFloating":false, - "fromNode":"7c67cdb9e592c4a8", - "fromSide":"bottom", - "toNode":"36c91406159c570c", - "toSide":"top" + "id":"2ad6fcaefb85ed3b", + "type":"text", + "text":"Subsystem Commands", + "styleAttributes":{"textAlign":"center"}, + "x":-500, + "y":20, + "width":220, + "height":60 }, { - "id":"b0839d6e6e68d597", - "styleAttributes":{}, - "toFloating":false, - "fromNode":"c950be02cfc42181", - "fromSide":"bottom", - "toNode":"20c263df8c9982a4", - "toSide":"top" - }, + "id":"93c5dfe3fdd55ae4", + "type":"text", + "text":"Compound Commands", + "styleAttributes":{"textAlign":"center"}, + "x":-500, + "y":100, + "width":220, + "height":60 + } + ], + "edges":[ { - "id":"3c47645c9d187d74", - "styleAttributes":{"path":"long-dashed","pathfindingMethod":"square"}, + "id":"93a7a5f1059609fd", + "styleAttributes":{"path":"dotted","pathfindingMethod":"direct"}, "toFloating":false, "fromFloating":false, - "fromNode":"64070cd56adeb48a", + "fromNode":"623d0968f6489291", "fromSide":"left", - "toNode":"4d43db858659fbed", + "toNode":"2dfa1560fb6faad8", "toSide":"right" - }, - { - "id":"7e25a3f58e5e8145", - "styleAttributes":{"path":"dotted"}, - "toFloating":false, - "fromNode":"7c67cdb9e592c4a8", - "fromSide":"right", - "toNode":"f8f6dfb640cbfd1d", - "toSide":"left" - }, - { - "id":"6befddbfcd1ec457", - "styleAttributes":{"path":"dotted"}, - "toFloating":false, - "fromNode":"f8f6dfb640cbfd1d", - "fromSide":"bottom", - "toNode":"ce3a4399dc294b02", - "toSide":"top" - }, - { - "id":"bb0e476818e13bff", - "styleAttributes":{"pathfindingMethod":"square","path":"dotted"}, - "toFloating":false, - "fromFloating":false, - "fromNode":"f8f6dfb640cbfd1d", - "fromSide":"bottom", - "toNode":"b31e377ce216f382", - "toSide":"top" - }, - { - "id":"450188924918c729", - "styleAttributes":{"pathfindingMethod":"square","path":"dotted"}, - "toFloating":false, - "fromFloating":false, - "fromNode":"f8f6dfb640cbfd1d", - "fromSide":"bottom", - "toNode":"64070cd56adeb48a", - "toSide":"top" } ], "metadata":{ diff --git a/Diagrams/File Structure.png b/Diagrams/File Structure.png new file mode 100644 index 0000000000000000000000000000000000000000..093392959be20b342765ffb064302aab0f613a23 GIT binary patch literal 232311 zcma&O1yogSw>C^{x=WS1#_U8k1GzA3(iKbf_<8B31@nu3(*n<=eD_u60>oP8swO7D24<~E7s+bcrhLJn|*DvOp zuFD!srqVnnM&c6_K`(o?2vc&7WQ|8l%GemM%X)E-6_*Kl%52b3J8a&9e6`LIqRM6i zyQ&_uN@nBxN#>U|Rw4_(xd8Zd%IW9$Y4=+7R(R+N-N zsK1ts92Wqhl>*WC{xyOrB3xe3uT6uk7${*QtQvDRIR1>lg9vLa{bxnU+`t-wiAuup z;C`QAm!!nApGOH@@LT8_-a43VX8#`36j_1juOs2%0!HBBa<0`8x|f+bp^ z$Jpu}aQx#Kuqi+VDZgj>u_<~QN?4QxBAHJ((3g4;VK+nmEwYkKV3RiMG|kZ0z#Ej5 zkAH9fr_{lWzz7kH+^Hojz$OKe!|(lTeBcAms{r$pt;zQzBaW$wF7>j;g7;4Z@cm8# z9#%%~vmoV@htYp4_NKYCMnCbx_B)X)Wgqzm>r1F`(#Hk8cmgTaLB=XwKgzhX6cK z57~?v%J!GhPowaZNdS7t>|m|(KQ1vq!be?G)O+^tg90z1C@4Y?T*43s zFgL?A10kp}{8?!A%K*}!eojIg7kEH>Jf-0;pMk9oDyaIsrUB>(g7;k*{}}+RPfh9j z!#;uIHno6Do-Eg+5f>M?6N+pN&BgcY;=qUd%8@%-_W0qst~u@i5fDe-l$nQ^=+ftA zJYedmVGs8+XWVk5yxt0VQxU({pbrFkP4B<6a9c6N;2?DfKakU)*YCa)4abuIcV8 z@uuMT@z$cy%bz1imww~wst@?Jk(G>N^NJY^z*F&yx6CIMuU1j4|+g1JQ~`Mjerm5)Rb)m|JGxAKzC5^h@^D@ zK~Xj!D>(ioe?T(=uuIaQj?{ui5RkMCA?(=S%YzCZ%m~#!My})%X3&tVMBQ(J|9JU_ zoqoy&M%Wrrvq1&-(NVtn&&Wv$dJ+yi@Z^2!c+x&Dw)Jm~`fDNBg3zEzY7j?C49mp! zkB0p@IAiH1_Pav>JiKd2%KGmk2$m=T z75L;sjVM1iIrOi+|31eYE?7^p4iIa(UX`4mpWifc`2W8V;rRVOtP2Ic1NCD>E2@B$ zAK>=o9_9wpadYFLpr8<_@vVluw?!6}I7jKwKo0K+{=efxaX+qwvMmHiHjY0^maZG! z$Kjulj?RaLU&h$Y0sFTJqIPVRfc(|Y5k|^d;=BG&R{L;S&nOprIHDEXR99Q)To;}$ zSo@$4YCqVN%9{Uq;7@`Aj-{Y-(lCL>7!JYGzpxNgBE;DNbw4~+I1yB{h_sdDe;;{j zcEH?@oUt*vi>oUM-CMQ>BGxntzjIhTdX-M27hmWU?|(lAZyX_9a{3DDcci#LbpTuh zwSgjPj-B5=Je(VDW@cu(#vIMX#f6yeJ|qWe?n%1cJN9`!V^2D-v)!n%eEFyIP0sPJ zBf)iZri=Ml6DgY$ZWnEevfdPs zQH_>>dKyUx8hPk}2oMehw$z+V?0@VdSgmvWB-EIRmDe4mR5h$nIc1lbQC^BN6gk|n zKlVW(ixedy0GFu|qnM3;L$}dqpaQeMqybU{79trK|Kzu&3@K24cDr29_TS$u&i-0I zWjqnlFG9F|lYINzCc=@R5%Q~2>5GHiVmp~~GAks-#IMxx%XGz~+9E9u>YWDb z2}HmI`&vDZy4dgXUa|)+?p4L}IWD{szdeVK5x*5U1=d&HNK(;xwfhbWP=cnVK(xR& z)N4N#EC&;+k?^rUL-E(hfaed9c^-frJ8tfo_?{393#_1L0AjTo%abLD@&Gp2T~nc5 zs1d9_?|*lr-|F!|E{ZtB;Y$k@V6QLlv5mt&L{yFzJ=K3jCVcP9yB9Il^ieE+Rc)tI z@7#Bs_8~|#R8&;dQLdvS0Z4e3kb;7O9OV@Drrnn9{V5ZFvu{IbRtv43GP9McjP_}- zUq?z~3KldxiT`CTRM>z&Lar_-fu1JiJV*u#V%{O!&DNm+CPAepa?q25ct}cF!@6C) z%dQwF>b3o*k<;tgN}u(fQ?gu@aa(L+VsH?q5VH68w@8NUgwZ003WokSC+DjP>eS^b zG|G3o@AjP5GhciyE3cF?Gc%KUe0MTsGFEG;o_Rmq6gx*fTg>Bh#`2_wY&iMid+i9% zdN`v-(5UlD-=?`t0=;TkZg9puxF0sC0aZqwCtAjUJzCLIwg7fy`UDP;3eDq2hp7B$ zA!aMKN6Bvb{2NLbj2``DFP7>i)TEuAAE*hg;b-{YUZe`YU{_L7Vpdq|%v45a&Uh6^ zc(&kOg^9`Y@I@2;x2wI5e)ANgB1;B*eEf~2ksvIwX?^Amcfa#xq_$wIwSlC|dXZni zvKyL5E~Co^0_Vkx8;cG#35k7>09m#&Y+#k<<9O|jM~%n2tK{~4B)Mw2yD-1F0J&(= zQj$~=Pp$>;JyBo7>@a1HHXRPtnHuw##@`@0eThukWvsGGxG1~jo#v?4*49nimG3%D z*WZ9+`or2Wcz4wa4<15!|iDt-d^pk0EbtpwLZX71)9rq_|9Sp zauP?+N*D8OVW$|i><-1abX!B(J?QjvI?`OWN`H*} zU@{xa`((l&Vzq+eXRF%O4HhVr_WbcTM!HT|cQrN4raP$|v}^N>pm$riM{sKbOHYjk zkTYKP9Hm)im7YbKVw(-6J~(j*goVS@Ih(PhXuDW@x7Yr%!G7-RYuidlhM;R~T%4vX zUrG??d8fNzj#0ah;Qbtd>;3M7(>cfd7BDY7FS@azb1#9A2PCJfOt;)=T#;dUQqN@4 zn@h*~y#Pd%TI}}xsT0<#hi@L6-CkdqW=B;#zH9F9=IFT2yMlb=AWB?XN>jFN0i25M z7Y!~3mDGUNRuLzr{v635W}UYEF0_MQLKD-@09a%YwSafXpve2L)!mpAYcu}j8Q#0i zK4tNUn4~3V1Evxor=?ms^C+h$#o2ycfTRmkwpQ2Iw;LV>yPKJY_N(O12DcwhKaBx< zaTvAWbF}UUVzNKj@9xAoo69j&{CSvk(8H|H*sw>1%M1SHBg0_)HH!**dSt{lkH4im zeq9cusN{Q~PRK14iL<&h4fVP(8(!C8sR=NW zAa1;AwTtJSut)*v!Y&*L?3&9k*&}z(jH#Pi#M>Gr4FQ|efW7ieNJ zVHhMuFI6)H-p;B@3&NXr+?-CNM;@|MiFzHwjN~SZ@2)|>+%GvfA*Lvnv`!qzTSTdo zo!6oCi1~1X^d7|t0V0T&S$>z+qTGQHazq05j%ydrRPLvJ=xrlNmJQX{b=DJ0CthP6 z{{Gc5B6?yE0w7a>P`I*fRM8zsy*6@9JHvO}H%2A*{3X-lXy9$|vCCAO2vOi!(Hk@| zQy38JQj?MphCxge-%Uy4e>m?kxz4Ult5>U`%Fc09oB(op=;vmE`v1cE*6x1WpWnbw z-A;Xq>m(x?NLe=G5eTSaKiU2APQ^G!O+rr9p66J^5>2D8qQQtqdgI_3@917+VG<1hDBflBV(??o&-*r>U7?9q|^FF7_eOA_VU1=xqa}BR zNk{v2DI!Ic{#&U*1EK4RJJY&$jPgUpHOATa2>DS!}1Q^o-O)&U5c6SyA{N1DZON;P#9%! z7u!$qz|>b_dV83R0qOA2Kyk_ys$(E<5?$+WOK@8toA9t z!#pykVe@zCY##D++m-_m=Ja4AjsU&Ex1%W^u@rSu8SYrkTSKG%))S^dr)&f96<<364I^FRAT*3+KJ@$~?k$vJ)ML*h+!7G#QjUPlS*yD&0%~4zTOPDd^ z=s*gA=bCk}haEnlA7U`#HChK^CwCdDIJ^}6ZHNi{5|M65Hf%2JoyB@Ttg+D|zd&zh zqYpZww5KOvZ6x~qsa_aN-C*%;*A|g%7KULh4JAn?T|U=bpS07Rx$TrX0!sxQwT$Qy zxQFHS17f%t4HWk^YE>?JOx7=6pPUc%NPx0|<-Q!)*>^L&P;`SgWLGr%qJax9!)h`G zlV#o&2M10(Y(c#A8IvW{om=l5M@Q^0fwy#ZN=6A{f+ZL69~NBSS6m#|rTBE%X-ZT( zh%|oQ(tS5jF!Mj?Jvztq}gQVNpJaMi9`jwm}_3A_0GI-Ixs zzS_Mcb63P*E#9*fH}J$0u^dNa{Vh1(v?3=|9_Fg80Clc`m8oIlLxT!Di&N z4dt7Jv+=YFS8cyJHE`k}SkMd=;xg@}BL&Zp*7LAD`VmfwsIhh4;l?7PCgA_h0D#;o zs54HUJmP7L=si;GLv|dnFn*$A`g&?V7we$V+7XT05bV}a8h5?Nu4*SF*AHj4Tm0@C zexW4}exbaoUFiMe6PD8t4A~oz=o!JTRh(>fufqUDZIm5#43nlz&=*5d#hH$;pn%KRRU*bmV_%pQgYuZ3S!4u3<>JoNV1NJt{@GQ%4- z_FPNSJ7$w(y6uF=T1}vZo;*yzMlcW-H|o-@{$yJgDEkjz&Fjae>mD{_12}Vh`$8}z z>sP+e2ZETC-d!K5bKZwQ7~#>tZ76|bK`phUXRsv>&7iX(J)!XpvfNmAjP>*?CGp+Ri{~7mJvIlL;Hor_4!K7l95Eyr@-q$ zv=w`KLDTh2X>zX(Djm!or-uUpuCoSQfQKHuBKnba4vrryvf#wag=*)0WRWo8gYsh=qcG=X)( zUE=6y)urJ-nFCT0)5bZsuMb8Z#F%%@Sa8-fy`{A@_qkY0vHH@&o8|Ep#i<#tc*WI} zxM__6sb})TioL|ewlIH!&*f$@qz&~PO?2BC1&&{SwIXzDE7T>rR!|^yEj|!WO#pV@ zHK1|enXt;d&mn-Hk!7E~F(*1+qK`u-6#))(DLxP;CW%GwD*#xl>isTMFdIr~Cb~k< zAY!o-JrQ^(Uvvbdzt#-0vzW+I+#U2&EOCW?{raS>)vQ07%yd88B~_r-0!XS`>@LEH zxGe&}=!n_^=l;OT2Q8;OhYYgDIidx>-RIP3c=iFeT6EU+<7?g}Tnbc_N%~e>bhrFB z9#@)(D^Tq1WQ`i6I1iIN&twpf4Wy*w{nNC7j!f5;AOB+7f+bY2mk>iT5FiHJTnDM^ zuWMXM?asERumE%>)Kmr9^XW8!2(EQ_pY2-B)X)js_Xn~u2*lOgNHEpHSFLTGve|a3 zQs8)0`s9r;QN_~5fZNv5Yi?wZa!rT8_YmjDkBL2$wRVp>CD|>#Kgm0&x>->Std8R^ zG(BZXVLep*S_%!A|i~&$3^ZDks#ot z??p`=1l8L;Qi9)Li%ecMT;l{8ddt5@wT%1QWt=Wl18!!so;Gt6lgr0n=FE zPhzfBpoRKeAJ5?h;8|a0|MqKVqe~5X{v;hG@Xc2v7J=|vAn_S^S$gVmdAxa@J5s^!*$MPru(A`vsVHqIsdd;tCO6Z zn|UZES=pct|5b=G17pyjOrn+-JrX>Pp+$U3ik_rlHJ@3v+4t$UOI*0c6Qy$x%Mw}K zmhE1l2Cm5_;$feJNccecbDvowuiqZ#7ti=LCE(Z)V5+o%Ogorqh*Ifi0{NSL1W(gZ zivB3F>Bs{%JEmd@NYkSaS0`$pCz0Lj7-13YC&-l2N&&1+6z4g zmR35MaGL)*z%z+(k*~`BN67}LxrGz{GZ+p-Y-;NL1HLVr96mA+ma&#C<@N~VaArw7 z>_trCBz$~0sT>r5U&%wsQBL^1jIU8JjxRq5)AQ(d%<#FDl-?LPwh`zVI?JlgIQtvJ z$S}ZO^7sl1)f2t}qS}9QI}*sL0TO_s*VNP;v*CEA5A`XOmX@}tHW(4YEu0=gGw$<) zl?M*4f~FxUs6>xnf=KD0P1E5BE>`!(9V4jh+`LI z|5o+WWh2Ycem549zb3h`J1Z?pkktt+z}V7|=M-i1H>y`?9BO#Uth zAp#WpeeBggTpBAL=hMY&KXHI7cz$@{6HANUgY@&KYYiSeLg@E7^?+OB`K)Ybjn|0{ zkfQAgO?1)#8ACvqI#6$yxTeE@tUHL>QKlj#2$T{E2z2CH4_8v8{gw@%YEpK={Ne%t z!mCInEwH?@1+_TKiy0A%oK$OTu|pgYgBV{c6H;GCb%@9xUbv6v7i8Pq&b%Jcfu6k0 z7I@n=g74R`&mEf0dp)#lslL=LXe{mzf8)5}+H~=Vi<>(xHg;5_ZD8wVD;NHW5Ky`7 zdiYTBJSn$i3cO!V*ifU?RfR6whPgFTb@@%k_{1~ z>K-BX`?g=pfSnlLvraOHetJ}2>2gq%9nuJ?`BiOMds4rS)-ikWDT(EJi(1FKeZM?Y z-Kg2Q+mQizb59NX#3z#9FCrpB=-g>U^emu5e`d%1`R+W?l+g<^diAVV0Bt8&a12D( ztGY}?2?`O^Oxt!_P3gX96J8XmZ*QNs<^ru8(pbqZoO*e zilkjZMzkYVk@u&;0Y&9iRG>WG$q{hvW;0u7J>BF?W5-7V<>aWOLvsKE_+mjs^H#1<81*2AUGW3Igy6aG_1j_x*D(fgC(G zAtA`DJ9JY*CN&+$`L|*+W1E@=W(!__U$(>+e|es!lN;M=r3H1lTGzb%!y86_vDS}j zh`@(P^P z$r$XuKm1MVE0`eMKQr}=&?l4)+TB=4PgQgwpTc0e3{UYF95Q)G#rH6Rja>sLQPwwrNY0Skq7+Bj8`}4?qpuf#jn} zY^x2XL;ADOfw;>bZm@_NNc!KJbt5`SzXg&Q{v_h@%AdighY8m2bf4R5qDXbgQY+&L zr+FhCr5RT(r_0nQ=EHpaK zHE(77N5M1zn-k;5XyMuND%W;gQ7+Dv0E4db4aOpT8W?N5P?-fMAtg#uqKO~T{IAXl z;1Hm2s}Bk$`U=RR8)QO%uI?W<{NsW9P;V~u>OR{H0E@81ZjQBE0jMYh;EX(3|FQq6 zp8oY^zziJjfvh-so6&EsJO&If3nb(*@(kohq(}Pn=&BLOe?rIKab%eqhy}qI<|}Al zS;JF|y-)y}OxU6IKww1A7}DFMM3cDRXhi+)#Z?U!3D89-bWxH+BxDDIccCx1BZ*o>ct z^G|Stp42`bc7z)=cxHwV>6rquI|rP(^VbN5JOEg^F~5f<6%_`S2u!~t;y>F8=Yq>~ zIEI$gj%U!JJg~spT}gg4>SOPpd0;#=qW$yukJ)w9C5BPKh|unnARNB-fR5WsG$aZi zr}r2XF7K&Kzr?ceX@%s+h!H!s9w0)&Lsys7HBdB26?C zmJvvwk4oO>G!0nDUyc^uEy?qBapCHFMHFP>cY$zmaiQPnkZFAD0x)FVPf9%$zXJ)w zW6To;W#w+5(iF1SeudfG+`MF$u-9=%4#WVPBtAF>fS455D5g_RrsUvIM@oRYyY~P8s9yslqW@Y-T(NJ89vkX-4`#XAy}8So>qzGFYa@y zSo2IYPQ$DtgvK6J?dM<7$P}Plq}4ioCOQnM`?MK>j`>nRqk!-6n7lLKCN^>cyO%qG zO;;h^5E?z#3^@c75)l!d138GBDR|AqbB*BoctRZtZJqbp&b|V4DF*(VeVFEy@i}@FQ@UX%jEFh~wkv9%n+B|% zetBWy#0L-0Yna^Cib~+#?g7AS$WmYCi-ibyED>ygGoRolh2|4v6@o`Y+|IMs#XGER z+nWLKm=a1#r~ux~PZ@l^Gpj4!aWpL4f^Dg{5tNCQ5pn>eo}Fth%TNm1xt}Zy$a;x` z5HX}W{BDjbun=Y3@1-#OWu-l$u&{tkC9ZL*oxDVf--MNKL!0@UeR6<*a#TRkR;bE{ zXhAlp@w@^`E|P$2!0Q3%Z0|u>-CNluN( zX%a^hZ4fuJ$579uWwvhvCi}kIMNdvI0N39>=|vSK$@3vkaa73`Gs-SwN`*8CC`$pX zFhHLp4hM2#zFp7qJ}hN50_bs|h$QHDwZpHHDOCSm1k3OC!cx>AupdL!rH%Jh4ggVd zv9bM8piP13p;tcbWke?;-Dg*w>yJfcbxPl!wG}n&$}JRsYd=vT*L)O1GG8dm7f_(sgsw+qJpBd>u%6xW#3* zb7A;UGeuNjdTjwzugv_BjU%SxbFG7Qv?sYiy-i_K^G4pw&Km;eVvCQjH?N=5=ywOP z8@22!?vX%z>5pG3VQo)URXs=aia=23s@81AX#b{#^G%Pidbynp+=)Dxs17!{u6SrW zvninwgws=#u!aeQ`iHx^H&|<4<>JDh@%;)k?r5*KMxuFFq9_(=lC-{i>1$n#G&&*U zdt&5UDfz9n&|W45X~sw|>tR`~l_7VyaBewUx%(ZQdXn$nKHgf!(<+QWIo_H?BXv63 z#f6l0)l_u1Kt5Z4cR|NzEX>h4*(^*k9%lw%rK>6g*}}z!GkcJsW3kG_Wksn_Cu+yZ z5yhx_UfS(&z+6udy-t_z={gFx18a*mujg+hp}_&C1$0LJ2qi#g1yI^%et?&_K8}9- z`ff~~0$QnYv+4O2J3{2xJKfCe;z=GKHdpo-Skn-0vAhB&j4 zhhAAtRT|aDlSqfzkR<=gfUsFW1r)!dNM07;iSj-L%aeQ3LW{Ed?8J_3C&}$QmTQ&! z_i~1w5+$2w4ww(^UjjBiZnJ-ydYKcAGV^lcVCv+_$h!|2y=P`S0^V>g+k>bdbS+V zPvK9Rbk^Ghr2IJ3-C%P#YoNNhM4vjZA2kC0$OC`jQ^dLu71WQRXn0S{&=4I_94IJP zqUHf(VzueXg(MvQ=)Rx?G2_Pm(~l!D1P!Z+>8V#_`=3(*l)(gzWz#$EnI1!~Lr>F+ zw&;T}#BYxA%9OzYofQ7pV4%2(N!oejo+a%59ma8usH8iMe5Eg{d^AKeUkVv1pZ{&(q(-9Ypf-YT>k@iN-N@(wX2vZvyo9+)g21_+M4d~F=bPvrZa-?q= z2+lxBItbdhkozt0-r$_;>BboRWZ`kZbi2!hsX9161hh} z?*Ojj&J0l5ZoR$SzH}hzCv`W}w*Rf*ea?-AHeru- z%mu}#UBM`lJA;~P&!WPh`InmLiOw~^j{ztFer~lU4e;Cd7_vO5f#8%)ysZRm zGRsPTX#>}4&%j^#Y;+lbcU@>4tuVVEt4$$rhOQrZ_dP_+)0MVR4=F)i$`S>?TUCBf zKML4ftQBRalioTTdp8@mj%WSm=-a3L8ojaw*NuyQFArAww{OUsUVt2lgn)7#Ej@kU zi}@wFqL`A&My-=$VC9~jR@PrCNBKxMcNOLr7XSjj2o71ZQO*#F5U)c75L6}Ls zEG#UfVqrl8Sewh!q}CAg0=%DXPPE#^YP~=et|~?46$wA)N*;%7$gp9&)bOfNiYo1I zD&;rL1@JaM#?yK!NQ&8pPBjh=5AYd|G)+f7-21`Z)KdW5&6b*0k=U#EDH%aL5%~YO zyx(UgLjWj&Oj2{8&cn$6ln{WQfRs%Tcpw-e5r@BgcBQGMm6tHG9z<(KDF*$)78S$x zxclbqNh{7G(|~Qo2zzODfxrLdb=I~QMOmrwlFvnh$GpZ3a5W&D_UCsiud~)J!wYz2 z+$(UZD~#KS0Yq=Mtw;0THnwssk7Duo+@b+cAeA&O1U(}+0;u7llZyxxd;&_+0D;O_ zAQWV4Exn52fUOMFLJ_B2e07KM{E0{>r$`oSFBU$YIkl%8iDvHYfU(|MU5KD=%#E%C z=?0mOV@Za@O}*_@UQQ0>ehp;gEqhEmp#rJQ*d5TbwtR%2C*a5{B8axUa48ze=NF#m zRt0JM=GmmD3ij@W->+yQSy*fAKH7`gzZE8>yEC>gV9_`n;XJ=<{-ludT_t79mF|w% zQ;w)g^Wl`4ku;FMriI!yKpLj$=ZY{tg-j_*i2I3SY|LxG_qX`69L3!}q}RII4#++b zT=IAE{WM(BU|4&#*y6VR?Ajn5cKiLxI?`hHHsihL4ZoTU>vfRXlvhLg%3Z7vU7HPo zFysLwbe$M9gdE1N06yQIA*Me_1E}2k!=e|e*_$Wfde$G5vZw=m5@G)AA<*OguaBrv z6ygSdpVxKQ;F(|hVl8@1cia$r%oYA4*5&lnw757}KjY9KGV`8DkxM;FXVYHT_IFM% zF$M4)Z{cKZEg-d9&O96$s8cOtjE`KHShsgW%x`F%R(;VeZ|!J3ZUZK2v4`U)olME> zZpo_8-8(DitMl*g6G}eF1u-7L_&Hj0Me8bBlMhx`ROUz4qYvb%5I#(5Fstk3vo|n- zam!(+Q?B9G~p@JsJPgKJETDWts|$eIngEulaA_fnnWJQ zSn-Cz@q^3Ph7`JKlk2Z$Za73mjbh5TCK|W4Qg4piuT{D(CtE5iDM<-*P=>b} z^_7iiK6#RdDF(C$h%Ry1xW6OI6n@d?Hf0p{A%S6KEyVXs!ZE}gqnlr zHt7*iT-KXmu<>TQ#r<;Ib!ON8;z%@OZ_P)2-P_yDjOsi@U_p%I%|n(%t&u&m~b~=&9zUMH+ zP40L;BeN+W=b$R@ugHw(m*YCr4>f_#7rY`i11ymQ;MzQ;aTs~;|SlU6f=6KX}%2bMK+ne0z_|4d3CC$I*uFhNqhq% z#H37eM@C<4NFUQRizx|4bR@cz>^%(+^0=hMAfWeEVoZXoeC ztDWJr`NW7$#04S~x^II2YARPbiTG!L8N~;klMkOcw1*wFWmH`(44-+lPaTPNFdfJ9 z<)_2kga)zDzktv;HQok%t><2T6gzo?@XXy4WPSA|A~Cu<3Z^GS!Ool5kS#ihd)tXdVvOK)Rjrz? zE^Km!^q#y>A{$O0Y)*xo7UPw6--D4yq%G*s8nRX>cUyU~;*1@Q^%$@w(CFx6`1;|2WDA~@+^etqjuLRU6TWqhX+>87Gno%D0CsogRON}eV4iRGNEGq&PF3foG0Z!z zK&(?*eX@^c%Dbi@{7Y)*v!ht|P7fa8bEbk9bv=r&SWLRC%cP0I~hUtmt+0*=|alRh~tjczUiDE8e7?AX$)rli`Vwn?h zlFdwgyUY^y88K{lVl>T?ji-nm%Asg3Jxx3YQJk(tqa}}UF-}f3<2#Ej>1kwW*2^ ztpeT=?KDL8nh7d`i##B!gn_9rLkf)A5a8DeLw&b8G#j&g%nQys?*N193Pv@z75C8`Ep@f^^TFGmqa}9MXvx2@&QanpTvv>cOZ6z zcOrZD#&dWsOwyQwQ_F24Y#eRIJ_J`p1fqEJNJ!$KFl&R(%Dd$J#EZ~~S;RU7d#Slm zxd+j7)4RN0f;Gh$R%o*_l`-#MO8~zP2{zrJ>DZT71;6?Le`L$VDmivJNwuI|-Vr$E zs^GyJ7SiM=`lOGX__k3nQzyL|J-s2A59gDNObUa<=LmcCiSO3%@>>hlg4}iXRy4Db zeEB<8-G^>#0zRPk$*(@V9{ONh8MA-zri!*%Y)e^fD?|y9LM|?ll>Rd@a-f81j&7?t zW-H5H;H&@w<{q1h13c5yre%>3k^b8ytQrcLru(i+v4t) zWhw#X&jF27%66`ZIihDs3hjbLKQ>V?1x$H4Q5jt+)4O~cckM8W6VE< zSG<4qef2V&j3aiN#@%j4M>Gz&YZjN{{<{xKh6q-(ks0=OYy0Rzqjim>Bq@LCkd4<* z)iFBwGklzLr>~O*nQ?u5MuZYvow;0!e4YK927G&4^XZI+VyscZyqc#tIHqeeEE(fCOy`D+ZKcktFuXxn>?e_hN zCO654QYax*woYyNb1Rg)$O>U0&_?iS=7n4C>MgaVYg<$Gc{0VFP|Ct?^Xh5sAVONY z{CF6^S2NTJA@J#;?Z6)+T!MUQn1u=C3V|^79x!3fz$jcz7hjo(T$Q{cpzQPnS@Xx` zT%o9#g>$8 z@_hr_B`I>Ncx2ppKAUIHyx;ziFfaB~0VBb@4K5_&@$c@Eg_(+sv{yU%ER={PyFw?(Hom#Dt< zUc&cYfBVjI#X2Q#HUFf&&XD4P^uUvEu)aH%ioSTp^!GWz}c^BV&~z3h&$+lwM316kpK zdaUlpoLCRN5#xmoQ7w<2ZY^hO(cMECC5#s~Ml+DIZMr6@t7^i?&fWVoX;Rx^GFeD* z^}c=JL^Gvug?~|HO1{YJJ$mQ=!Y7s2qrSpC96xPF zI9-jFd~6Weiw1isGwZjq#P3H?R5fZDiLscAHQ7h`dQp7_8tKj1(pQ6FesKZWYnLS- z#}6_slecLWfSwvLu}0vkZ-^TV>ml)}+|&BUxrsKZu`cy^czE45CUJV04x*S(BTcYx zQf?7pOOvU)s_qF$J_F)Qt^cju_Bx6G#RL_4?TchfMfQ?Sx%d&% zaK{*z;cNiD`21u?_?YTaOI0B6Qo|$%h)3b}q1ftJu)(g{}Jy0Fr&o9TTPi zHyfN3fc!H<2d?~eLXzJxV%@rFzXBIx4J3ztQllZ!L$PMFK^fJnK-sC^8x5=DxVX`r z%N~dvJkd-GZ^aCes4$_(tqwn{0qz35z>2+{l93qxd3jZW6mK+$t&!yRMBA+2T|a~E zm1$4706n!)6&4s6xo%Hj$9PA1{y45(m*SB{S-03m`}-3!`dXPx_P1WXGMQAb_051Q zlW$=QE?{8)6wQFUw#HS2bm_(+Uye8`qAh?-q|GxCPc<(x;4~ALBI8zd7RbdkC&4y} z<`lrz5npAXrb)0GQ&35VAE5$^)I*B(`{#D;B<>Qu@4}9FXBI!nKvw9gXqe=q%*o`W z1gRW$xZ})3wJC^+R*7$9yDUX{dDf$&QsFDgsjx?E_(op6vnM!4#~*Xw0QVI?V2;1~ z<7iF&;4&hO4XX)0zo|8KZjjMRPcT!qa`fw!mDa|~!J?}dH@L$0eJLhq!d*W;$ta)s zV^DeCfK{C~^7dTb=5RQ|f;3ywu`Visy>M@avO;(bUC_)(l1^ioPt8I6QV zp1L4zjReI+`$Hp1yzB`f00lomldZCO>*OoLaZ@xYq5|A`+X=4w=gJr|I23nD=ehdu zV)dF2qJE}=%?mYYStVa84KR#vSx*9n_n6P<)P^eoYU(+HTj8*aZ|byyX60iZ6AI1f zcJi&Tsz^GYJej|%e0eD_{x|i{{87EPZk^0ez`b!eZJ9V90WdALX5&d}SIL)CHMXu& zYQ?Lhska5V7G9@S9ere(qZ6EaF!d-A%OWTWJ=M;Iwts@ZgcHz_R>kkgRB<7m*P|EE z^O*rbPg4m6jEyqds5Ea-4~)0rO%-W%{1r$S22RE{HdZPnYYi!!k=jv&Sz#mSgE>_H z5%o99PFO-0{{XgTybPi*u;xM6DBy5xPM^Uvw}NHMut2e5Uk+-F5cQJJngA++B~VO4 z`R+v)GS$z%wpJnruxOeTHd^w32sYqCVykNa;Jn*5EOUCwQ*3)w)(dEgXgld7+rPe< z1y*(}sm*M|DEp-(-;e_FRq6%*3;DdwOHTd|8>4E#tv@q{F|B__!-mCd^6`AR#9@pD zq~5Pb*`?SfP3#)8`tw{NA8meTI?Ub0_b5AIQ+wQbF&*JsS_wl?;)y!djJ z!`@xPd(UR|)q3&BxDbK>D9ig)tUZp`+Qaqu!H(^zjMd`N6$v|!6mH(~Ww^|g`1J<2 zq4PoHZ>g_zfitkq{!{?A@;3g#td(*kiy!TxY|D|@>Y@`m@z6ju8Zt5OPDuvN2I z;P+_!@(>`H+kk0)^gjPAEq%w^zwoK{nv#GZ8jKqk?Kr(_upiC8qS~0a;>>V8wf5Le z>vw{9TCS|=Ep{GARvUC+nhG)ZhgGq2^@i>&cWczZv2 z1l4**bUy`I3=8`^PUb7TC?)y96Pzf!k43d0+93;^v42#|iU;ocB!%Skkx%;a5dq}& zbi>%JgO#)r)BN*pUaPqxUW;L`w!o$}mRtA~qYR%d4JXC!{kZ(Mb{7LRT}b2H4(^@iek6L2;n4N^=G3E9#Z&tpwf$q z5o~{UlrUB7eYfXpn0)tnZZAlPY<%T@hTAS(>U9rKKAFj*TmSOU8(wznx$;?^4{p>T z)|QC;$g7704IfHRVZlHL8Uv;fiN#|t+|j7^Z!8ONm*l>&?f2i8-!vb%l;XMNM~}Jt z@&w~v+1Ji&;U9cI;&vV$HCu`=Q|9O(U-UbZ4iP$Dtg`SAn==9- zbr?c~{OmTb<8G`tP5c(D=+%t8X5upAl-QB{Jomm|c<44w=mEdY6i@^zX)1j1r%=&p z2RaTYr$xGr_tD?^I8%gUj5;5IG_ z;gZJ?rWm@D-5MJTg%f*xbrwn;W981bvzFak5UmfNT0E!NZQr9J_0^#e5jh|~-uC7( z_S~_bcbWSl)N$R7!T$wJu|AA6N8~#ge)x!&+_k8uxsPM!Ow|KlP_VgWeqzEH6hv}1 z&-=Kea!NXwc?|H<_qxwEf^ck#AWuq3+zKi`HACR?B|6{slSXWE8$+fRhe|c)tVcd_ z20E(e+or%D*I=>-wVYlW987if5^S{!9O*itypMptG&?Ln5xA+7oMrHTeWo1ZLg9BU zcslEf^?bq6(bwkY#vbFY68oVg1At*{HTIyWDnlyt?~TeY(o~C{36`2($fhEwh|a5wn1LzxS$N zL1E#Rk687HZ;U9aS}{C@Pn~TtD27O7X(?-Mpg6_Yj|?FsL@s9;MYKf7xzpLhW*}(# zMYdWh=fMM`x+A}<9Jli1P{U$ld%hMgvq1oCa#Pk)rRUp!iZTk~O|F_Ftet1?oZK%ft1ie%8Cv9an-*3+5!7Gci-9X7>~2eiVV z23N&k#2HGF2jq!ncs!4%{`^M;#6Vww^am_cOdVo+bG@CPfZlW}0+C!cUBoY(>i`YC z*(7A8KNS+3r;#N2&HHcp_Z7;)*QiiIu* zSRcOF`Tj%=^>>-4TKF9C(OV-(byMxA#fsp8vJ(X-i8`ukvkg zG}+9?Ouj+LcjGX(sak%4?tGuVX3K2jLb7kJPa&Na$>8#*(xjyfgYsG^Wdw#r3>qrr@%F@z8gI9-q<6K{-Tctbp;pV zcag2FK2GlOVsDR@IlHq7*&f#%>2Bf$5xlE+)VqALzOtmP)?=AH!k!*-+?!(3y>n_h zs#pjc0l1H;^a1kfyLMsQM6r`i-}{k~k%JbrNm)_L{m4cX2d5WyxjIrBI z;DP@gYyqECPA8k90VAQN++9u%(U5(r5)VU!>s{;d@$(h5S9qkrMeW8Mk8MNzD&JmY zA(ddqO=Q!V$!Z5*^2%$DCB}116uSS9tGAA-D(d!zr5hxa76j>(4oT?_rBgZ%-Eim- zkx~Td29d5qbLj5w?(RImxAA%Iz2p7L=%X%|iKs+GZL)sHEMfZ8#sbsH}`!~XRI%c z4xLG9?iggY81x|7p8~ZM3nmacTH$Y|`Hg<|8vfbxJyp{Hj4{j4Kfox@qRYi5h)tFv z;6VwH9bkI}rP0H1}Vp-ucXD_C~MiLaWN5IwEfZn^wv0V7gz2fLd0Crk#Y!}WP@510wWRKGivRJ_VX|GnJJP7rHVS zoKr2#Z?~IQTB@sAfJa(TIOno`628ca%za0&JMNo2Ax3cOpGa6qI>pBGdmNoM9N z4>-b|$@Wdr50U$gXQg!ke|M!~Oy(iv0SRWq$vhw)Mnw#djwZV&dJq$#|Ce z3+I)90L-D3KP)eB=}8aHd6#{0khO{ac-WqeuiU$rxsq0rfg^=AzsO3~mM%LqL+M{N zO-t7vc&bbzvA>OpE_kJP-MNx;Q9kVF{e7e~WC3-bnOciaoA2`>rb*?CyMhM}r0g3$?Hj z3ZSZ{M6V4Rwm0p)H=5m4AOFKGen<{`G2nuhM)@ipB0?gwK(C2$Uy<< zg@w6qvn2M{&K`?_T5{s^zU|I4S0p8N%lj5?E|kZ~V!P%3P+4WT5wqLoxV_q%{D916 zp1BNSjeS2F_VzTZGS=(~m9BP(4#Q6-CW&`AKaMv&uzYMaDn>>U@)?Tb-nt3_@6v9s7t8O?j#X^x|5K>HmLt|a!+uXpn zp+|Fg!F`>d-fHO9PqGXkh@gaw(U<;omwbGgvG4zI&E!|V z)D7FbyLx}U9(X>~rLO!T7|D+Xp7&KzO$(|vKbb$}>qhI>ACx8jb8)pVVhF zRl+nMv5`@NLL$O3+k$1Ft&M!(eGi5T5u1v|C@0J@DN+#)3ie;K@eVJ(~;&?4Mp8O)87A zG~f*dvaOui^9U2Et;ozFlx%fVT1EGd9IWKWK#mWA1H_h(v!2wDOFq9fWWw@mNb%5X zBVF0U;VFr=go!)-C z<1C|9hpl85(7721x`sHU`jDwf=|=`vBDc;i62;XFeDkN>dTqsh_m3ClixwO+8b|IU zT8RC%U+Tvt$nj2|gGSf+nsKiRKZH~UFswzaRvOso-ZTlW3>qR=K01naz@ejDa#}P+ zowGKo*&BJz<`V8?h>IRGu|ZK~!^3M&eiWWw2~zARQd6X#DMaoMDRUr8=~a|Fj+>{9 zKGx{HALUC7lS`Z4JveI;_8}b)C30+q^y~6NK0vshdynGm?mK~#)a01PipH}c2Z>PMO)hxce_!4#+go0qcU=%+s zlYy7;jSQ$Th`gr}!8OEvc?;9aK7=)k9C!=sR4P0g>Dd6v@cAlokqtobcpR2GigoxZ#FgOTR5X*Oys-vU>*+#E+UdfsNr+R7`%# zV4VoBSCzIf=bh0n&L~n^MA;ARt^d!rSTQ{L^@n<-s6Xs-<@PW-_N33-0WvJ&_W?;?i=PM-Cg`rmV3?|uCzZ;GYL1Hu(_c=u+@(GM7U^65W+7G45p zFFmaK#J=%tjEfz$yz)1;wL>KA0Y{;&v%RF9O%MT@H>!~YGk(GKIH-1`VwLEr#l(nx zZK=Ty<5Tf@;_;}dim)n<#=G=c!{OErwDp%nWvRRy3S=HFzO_~pztP=g{m~wGY%chL zWgkIg{9FkCd_MjX(A1?5RpPOUFDPXhBFeHKoz4^DMVQueWe7F&_S9D1)zzzbZ!x6z zz4p}Yd-KDaMq@;3Jyr|t#5rs=b#;de)uvV~LlmqJ&El%L1bM=z?Dg&WfQix$~uEMe5dJeHr@L9MhM`* z(;Deg2EC}O&ktqhkFnoX9pDsl_FtrCJwL0nC(6B%tND&Fzmv!q*wpYJ2d%JNK%^Se zSl8(9{=-372%}_B@I^kt)#5y*agUV@nOD6*ATIS{qz7+pN697LZMfs#vy^(pIJj`zlS@qYhvnu_kQuh_4W#XOq_&@@44#f(r>~YS zZ?F8sF`P#DFoZpV^gV3R-6sEj28d|tD*W~Yv}>QX%MZ`O&$P}aS`l2mfj(~_!E85| zFn=wT*P=xsh~(}!#p^@o3!&UkiOuGMDsqXBcc^rn$V)r-rA;uho%M@q!|lN-xbU;) zKAv6YW$;7hmArvTBQ5{>S5JjXs0Sf+s3s=SnGdC7yF#DHUe8j1y4f%$^Ae|BRkMc2 zAoTLih0Jf^z1eNK&r8K=Y3BLN@;h^@qEH}{>?JcCb{oHnBcWZ0_o94R5fL^38PDhs zMrM4Z#hXtH7$}J*8O|pz)kS8Sa@i~zim%7X1@j|ZM4bwb z*ji7)9)Lnl<3V+Api)K!5*GpIF^_{_L+ck+`Z*4|xIG}DF<8N0I1lz_1b}1Z3S!K- zG>~#P?kt(7#*`QWEbE2kxZ}G+pR=<*?#M2d;jgSD3)(gCHe&Vnk*?4`zJhc>%IJqRgn2FKfEDGjErWNP)L5P(*;Ur2pPxC92hGNWN&z)kw8gr*Evbs|1EeWa&WB#>Nes0*_s>hzv=`w1 zFN(pur|iHkZCbJ6Rg~SMpOzjki>}egKE3b1B_lgcgi zoBT8SvVeTyZTSPg%pqSJ(eGp8zde80?B(awuZ8N`bCW^_u?GQ~_}f5M)=%0`Kj6rP z);Av5vNnhd0a84Se($?%ds3%5t3p05&;>b9${HTDjg!RRj`# zaw+&xFK{rfnBKRF4ztqS@jS{FF%-X3wk6oB3BQ`wT%MM_9{)mZdqCfWBCSKHzB3yq z7XzpLu8Pl~($V87#Py;5S^m?0cGv58h}hF#X-3M-xfFPwZdR5<+rCstiZ?`r`fKHH zQ^iJT>WjpmO_QjI3<>1nvz~K2Rk$FeTYUIP1^;ALouAiY<=LbwOj3_YnxxtYR;*KK zmgyWm&(u=(u%vu?0h4Rq5kNmjOlHXsTQ&=4MO4*Q{qhg4JHX|gb0}M7Wev7C(0)V|Sli8sBj+pguhf4je7M}(X#B+L% zyZ;XQzINc}KY87vdVx_?qVNu~7d;U*-M(h25fONrD#>Fip<%jp_E<>#gC?l4cNb`S{X$ScCuR#wl!Gn_i!V&-p zH(Ik}a>4Cv#V{xF4Im(>BzazMNM+zGR7K&c?AJG}sz^$)XBFdqC4$q8XvVc<;gS6D z>Uv5ALNGYeyea#D@n*KmJeqWh3EQ$M;xS;q`r4Qm{$>1@woK!Sf_By@dl7EIAPren zq-(TWnVFd-@Z43#5+nqf;u$2s&32+`^lJ`Z5=~nCHlT5Hxb2v!B(Ew358f3&s(>AEqpm-e@J|X;n5zUyq^77{l2H^ooUV*CcZGQZaFAE2fO&)`okE>sV zD*{^qOghrB;X+`69W-wfQ0h>P8|T5rBgou@E*OyFM-j4|T>S4Lzs1k{Od)+_0K`{c z-rZK?f8E^AzDny>w{rkjBWfxDMC%Be1K_#UBS_>w}npGkkd00#j=Uj|0zvF48y z-+mcM_~)uQff2QOoKFzf0KrR|43WH40lj?O9*cEy$_o@sJ%N?^8Me&(e@EGY!8kr zYyzSNfrQF9!SS+oqs?-hr9lcJgmpF}dCQ=jtB)%(BDKbm3BYeHdVRQ?`II8Gq2{vh z$?QepN)>A0fb=H)4AbqPhgEZoEQ|sS0}6gWMgRkMFaA8u$w6xa)FG9CkT7DePs5#6 z>s~{%rrtS{B^u%L^Zl-O!^Vt;Cd23Izo3{c&@M5{zXT3~NH_*Sp0%gblaXCl(E5vl z6zG3|^vJDYUc0sK2C8?tT+*tQHY%pOsP>Oe8!V}TYlD?c$r=XT3~+bw;I{2q?3&8t z|Gtk;q_3alI(ZZTqE=A~_zlcAZ-y}1FL8PN0SMaW>a^~k%b<(!+Cf`ugZukC>Kz{w zAi-b1nv;X$LTR;Oi0go!$dim7kQ@dGb)(A6sKrifz2oD=25Gf#T0h;*r}G^SV4M!t zEU)JTJe>9fT^mhAPGa&R>ib({h;SE8THE?cONsZCccf^ZeA@lS85=3P9t zV056X!%^Ga71y0e*}2ctayjc>W|r5wl#fz$sDqOKCyql1Zf?x+0Jp3LlnK0-@vUlx zrQeU5$#1wfbMy1NC%5gZ{F)i6&l6TUBs@5VrB%-uPQ08|YEPXvN`529d02B)r$oEL zhaT<%(lGZ`IRb&G3E>}>H|P%r1@#tEzaJj{vOdK9*r&c)_@E%fv3iMX58%-h>AHYV z+^AfuZNt$Y0A%F~C;#R{xfS|K=3wlY`QZH@-2wKFL(no%5^`ZB5}qyvip5lH1A+C* z=(k^m4xN*{DOwkAo=`Yc3d4kY^d9?mAl|zDjApmG|K&(fDZ(WhR+7C|8k*uYrOf zI8^Oj66#1^A8N%|R~0wNAo($J*ROh4Ro$TWlJoxGiy4iQD;V1(?GnXLM2Jmr!u=Le zvD&X2N*-|(=zU+xOv?}jsN1T9!2ZoDF`fuJq>ar%SW+(u`+2vnxgo@I=u#p;sg4?A z^{e8&2bDny4xoZc(if4(ylZwT2uD4cmaAzXif3VKJFYRcI> za?HL=Xfp~HxrZsFaJu|9m~-6SoL-+l_Wh%B_}e!hu%3x@HeHJpB|I~qGznPU!%&z( zrk{vY+p1oioH z`|ZhLx(R1(Lp?0Z;&}bN&xR$lZu5`M_8&cIJY|f95H!$7(h$ko-eC3_HI8Fj&pKv4=LdtKtNr^LoDA82eORE6fR zh-{R4Y7fT)imw>xZ(32(eQjLQC6?-@)qlD}C~RCh?ytAGM3I;pqgP3^mWh2Hplvj! zwfSvG7;*cV04qDhe@WDFT)r&cHnf6{x~|>KSo0x_Vr%upKxl-SlbU{ZJS{muHd>@O z!TE#3lU7b%-pbs*eWxJ?q2?dIYcNg#T*&IQK~%DoLC|1w&CUxk-^Y>%ULtmnWmLTs zw>?=R=X*sU4S<`q;R_-oQ>$wOA(7Vlgf_pA;>4e`-OQ#SCd|#{zR*nDq z%>*9yYpn7RWd_67zcW4%kU66XVqpvL*e(QL9nK-sG}O*S0=#+$zeVa_1cZmXHzCp# z_0xZrk(HH`4aB6(rI6D+_i&po))$I+#%0vW6FwDX7r0{Z*5x6{lVGZYcH-^Z1=VLK^qDu2bbQ&*_6c%XNUi#j4N%7_0uqN9>zEj(?8a++{ z(5$gosn1R6mdVWvl-_F1VEso*i{|W-wOjq%_>yw`*w5Yt;mKkFmD;<-nRpf;fDK}w zeGwH9xYlMn&j|bd%ekM)|hB}iF25EfxbFZ1G!rL(+dl^vH^GJt+rhke=)3PbL-ixe+mWW zqIdfXmCDm*+Ie|g_K&4IZZevH)^h68JKJrm2*A@o`oI~87aD2FG{(E0i z5$sp3f%ZWCm`$}2B)q{UfHvZ`K$m5--aVIB1+uH0uPU}W4-Q70!K6^Jp1%INb6|B- ztpNy{Pt>^+Bo^u-v|?lliI2GiI@PuT+&0sn zWBkrC@Yx^g7z9q`jVU<+`3c1{`S%L`b!p?>>k4PNa~HVvw=C6b1BgjYCPHv_a zL7c4EA8x*)SH!dG2Bf6uy=IXw)~Ti!EZH>zSVS3R6FQuQ9Bm^^+JnW@ZGBPL}kX>Lk4EzPA{`N{p+(A8toj;2MzD*mp66K+WBWP>%J z$>EL9lFz$p5xOisAoaX(DZTa3EunfGqG)rmp%`$2E~V<_$i8Cls9s;~+`q?46r&7GEC)EDrb1S5UdoKGnzi1I86vTcAsu=l(&(xm#a-XXw6v^Xnz3r@T%wTQOs85|rJ zEJQIyOuL?KFj1Ve{;*u#5BK}&+#U!PDJfT|<+LQVsBEtS96M*(SnZ2SCcP%2ooD@q zWnA*pmDJ3{R*{ocRVH}wRdwtB;A%jfzk^S!syOl08R#&yiZz?QT_XLA{&A zRmEy}U;mUw#sQT*W&I;?cCdO&CPM&?E>A?Fj3Kr;xX!O_i^n(f$~$&sYvQX-w`iML zLK@DJRHfn5IQwR=1weH3ucTofH(xu3OAv@jf z_2%z&bnV62s>eln!QE7*t#g-r>1u-E6RPZM3`5UbNf|kXj*tYs$eQKb7tba2bBXPiY|{soU4!{&sq(BkH>uvp;r}LDa<`HK!H*@4fX$?R*(4>VmzO@LH=K&@SMBwr+mGn3L4+mg`9jA7OO>U9y$(T3n zfuw23i|)RBPucvq<^68b#6*sjF7b9veFku`o@`8PJC3uMwEBPR-$a*6^-9PDj@&|S zq<_}7DP1G{&pAVT*OFyC_Q>-6%vzBX5`SeX6&3se_s1UzV1r#m(rU;i;RK2{zEb_` zveJ3&AyhlKgK1cq+0)zj%JWK?{%lTlZ7FcASmf>fv3I%2sun@X(~IV;%hOQCwFesY z3Yzr=KZ?--@aj zTP``BJ5;^@W%oZ=0PM7%_h$c^|7K-T^8{AaU4AT_>hgHhP(AL-STj7pIm{=yt%?i? z#jO_6*N>a<4Snt)Lnagg2j!%dR7t>f_Piyn`oHoJnXgVH1Q2xp*i_NLI6$HJ>hLHe z;!G=Wy<-sX^~M`>sKJ)VLzu2+4LNVs@)|l>=(ypJ&;B%R*#5RegE&M|(qlC@!J+k4 zLU#9i>GhNKyWMpQi$+vd_YBs9`{;Auzn`OKId&1ICJ3I(rVHH4-IlKc?WP%)7Jy+$#3SHof+=w!eXCcwlH`S)TI>@RfsGEjLPivC{?NCY1JN@I%ck5$G9F&IFudzUEB1d((d=&=dXDnKDPd@JsV;M}$kMzRn>iFw#ZZSiEsmwHTUjChFu-bj$~M^L{E7lBwJP2p5qg%^w5 zcf+cK)N5>Sd4QWAPxq3`FRzK}GG6pH>Z`JFIODf4=^gWHUorp)7@UTIKKS#qbI0CE zP2;n1_0jD4Od=6CGP{OT+JnV%eBZ}I-lkElO@Yy~B;l3*-Vkmeedjw!7ZvRwM{XiS!V z?uNKAr0}gD;Nc?Wpkf*vFxu{Y%#O>QFP`1XG04>Z$vqP2=sk$}ZO-BQ8<6bvQiOuP>wDPFi48~T=FD^mefnY7`(l)DHyGccdyv;;FZ(A|SGg)8X(V60TPQat z!m}5}QSLEB^wUcfxnB>ADRFV1NK!1_P+{8Jl+ar(YCcEqvxBf!{U4@2TX!ogbKl!o zoMW0is30V8-%|YOb~njkzs3#Mq#7T}hYti3jAJ@Af@F`z7yxSF{Ws^QkYUuF7=7%k zY3ANITYRi8O!1hyfl&6+Y5M1D^x+BceTWDa%z7X)M^4985ilY0d0cJ}g`5te0tUr0 z0o@L{>9stHszeqmWv!wvLOsCcW5wl?=H=C7Fr!%%+G!pJf{tx+L}m&ipiJvKBE_>B zMy2~c)`|brJ98N7B+Q(Tm0lUMDQ&F*f-}yKy?4aO9L1j);l9r<`xYhyGwW0!HpI&g zjJw{nQ0 z$;XWdeynk$D##QIJ!7la4U%FFL9$TnzXqb};%5NB^0}g4LUQ@Ze)2XrUJ@LQv=(~smrKA1Qo^7)XUQ(27d4>=Pju2DAv#Kds;u=&6~W5c02urk;F;{97HN!eB8S|MKott+WC8+Iohg^7cn znCFFhregINUNL?B0-<=`zbf~@cU^rRt9K5>1_pbAOymY{XqMMcTQqJ2i_k!;10M$B zyuPWq;*UVo-TuLc#SI$c2`8XA`2D*c7c6G7m(5=ZirOjY}rZw+;OZe$uXHWqyoZ;Xqas;Pt@)T!g_*8AKPcC$g_)#WPOP=yUs! z4fVuZ;9Qa%6?1cH0yqnCe*?(RpKGFKO}7W#7%yP1tYiF%}`4GjA?7rwm>h(saUVDE) z)37z_!1jZnC%O_b-^=Y(Fk}g1Euz$7{n#%)j_|WvquYZ3ctA8j7ez%|Hwd?josI}I{0z$K+`NWTv9Unex8rQfT_MLgV9Y=8@<4k!z z++U5iVxT&=D%=|dwggXv;=gQ> z<0SuB3ya>CTQCB$&B&*6pHolz0Av_q7XjqLg8Y^;Tr-s>ibqCb>+ilnh$<=~w;=87 z>hxUjY`4~ii`|DM&aTg{QwQ_QsehdDw}Bp|0<|bbHLs{)8uurg8!QJ zPFFO?fXjHrH8dWQ+uQd|N(fR+wmNTJxe%&*s*dNL6L$^0E(zd$jTO}uYiISS+~{W4z9U}X8b4+V9Ztqcw?Mf-P7-_!_P+Na z0Nr9E?JvC#L>{KH*u|eI-|;nNBg+pW()ELq==#iY7GHJ+E5Esdo1@@?@`N1GAp z8Ko}xy_w`Vd-B%kXV!a)wacEdi~#LHFf;<{Rp|Dl$O~+E>W#wonN2MgOYhr+%k2-S z@B4%+k4;-z=}~e`+jHUqVV#6<&#gsQHQO}G2HQ7Ott=T$)k#FeTAq0wSoEn)Bvw=v zf?`JOpO=gQXPZ_Z3xyDX<{gMutLdPOu%2>2k*(hjN7EI8I)(FGN{Swj^J(f9laE zQDrlZd`emhWv7upepFB38wY0Th*#rbVB zqDM4$IF0Qk5Ygd&0>l(?daoQ#n=Q|JT4-%0qWuTE>yiLF;!V6j~L{18mu?ac0RW@ z9BPJyQ(HJ@HzL)wF;lX8;{d~Lepl@&$AmJ2r1;M(_CY??I5WueYiUHbg88$HItgSS z|E*kM(`>np`<2)=4fp5kNU-Ti02mvQB2EpUtyR+e)zF_WQ%qzzhMx47?9_1mdy|E+ z_OLcW*3IXs->*p!2-AnB+23wjm+CjXMnXc`9GZBFF+8#|ls{Gb`1RG*#86iyY+9^k zVzw$X-vguQ$Sh;ISi6$e_OUH0Z2YOJk>;tT!d1|x4yg<>uvQ?YcQTSw>k%Kz956Ny{vD`fwVS9cwQ!cK$?}UeGHb?W~1{_(KV+Sx)}G zztrZ{&0Vk@CpY{hjzC$2Fl=w${=&Ho2ZNApiqu-CSYtup4B6+pH(!g(UYPF%JzF+t zf6A-3FX6Z;I^aRMMSWN(Y?p0#Op;H9FLT+^H>iT7WfFM4~X^L#jj~{^_ zsQr71k#-YVV&;mn-&{BkBk5K?0@cyCA4P9Z%=O{j&uv<;xX+U##SNy&d#re{XSJ`1 zt>E2E6+5nqP$Dm0zV@{1sLyG*tUD+|lX?W#10(lX%~bx^{nCoJC#nxPFItIl_@!DB zjwvQ)jS;nf&k&}mTWeC_ZWxxq0tqbct_gSTFXKO1CmfF??5JO`(BA0)fE!TQrs>mL z3?BJCyEsmh6T9zUH=mxvV|MmhGclb#N3p(HetC${3t;pcS6hmfZV|$MAJpMiK(T_i<6sd%+N2W z>u}x|<$V;M?R7oMfwMOzi8I7&znFC`y)$|^Qn7s$MwZoo641}NHI!a@+}z40@^F8- zzH2?+8mchlqE%+8T7A2Svm5&AsklQp^@`PoX~b?no~5w3(!D!s#%~$?ejOO{qA&E9 z<G1AyEOusM1Yy+=d z!!B)^Uoua^QM+oU3X#DGFS9mrOBc&ZX~C+`6GpyBW#I%{8nEDxx3BH)lN8g`UZH#e z#)y0bGPitjvO&K+noh`g{V_2I)FSuO;Nb6=?mLb>6*i-9>w#20OAsQRr=DvtYPBW>=@eLO!iWs9IZ^i zNd7=&F7Jbs5FALpJ?}B=vsaRREiA;SZPzbudteZSSwl-#!q=^%(a^VR;r9Gw2$(aN z*&DrHbskF9dvo@n48oGnqF%dbxfsQ_fcsxM>kCe_`RV zzv0P^NkpL~0py--kZ95oJ06vXso#MNMdxyji3$Qi)G&Q+->4Gr}1Ho#Vxk{h4 zl>xgNYKIa?{eb%4D)L;pbf$aB#`$cHXca>Ys7m-}X2ZmEwOrr7pLRLHwGe_@Z1`a( z@TU#Zy~4gL)N0?&Ga%CKYS^%H-=e^l(i3C{uUJ5ifag%k>8mIk#F7bC|4Ri51Bzg) z0C-R#h)imBl|XWFB8u#zI?}I1Vx`f~rj8#wB7n&e2}IB3nuhHL zU8Vk;OeyYHvnxL$`9&VT;?^vE8(r^OjeKg#=1szglUJ05I~Fa!S@vV!3C4%dF9dH9 zru5=dOt`Ol9A`(f!{Svvwn7LmevoLa9CBF*-IEEp9(+Zi75Y|a--wF?3}4t}(hLlO zi!Wex3`M-8aN5$oIp{BSIR7o^*gx~$s4S!Y?89`vCR>WzS#J`;b)nJAjUVSjA4}76 zNwq5!!~-!z9zIZDe$wOrf>>L$xg>ZramVS`KUEC;bsWdZp4b%@QQaEbkX`lszz0*` zT6}Q($;;=uEcpL2C4sO`=@vX;)%Ogt0-vK^pjf>=Hop;?Eu%>?sp|@aK1u=X zYeH@iwh&2vs^?o;VJ_mQVjXp*`xEjsuP!7HU$5P}n-f`(fNWK6XA3Gjn#fn0H)jtx?CZN0 z4r;kA?dv!S6Hav(nT=izHTI>$*K?lvm|Kq4JBrg--Sd^^#;eNbC;c_c0r%|e(FKXP zF`j3u(k@Mgk&V3O0~7b04qeFSHgbcN6)n0>&6i{HMnYHiCAcX>UQ^ojeXRO!NMt~{ z#!q_{+5fSY5YfWA3@;(33_5Us*}(t%cAyF!yzPXu*DdVxc;tQeIC}#Tk|2ex@ynjn$XSe^O2kZOe8K$7pkMy23N@T>dClGVinB%g zTF;+yJ$2KA24y;cs6mb5ug77nU(sv49%6PmtPnXO>`jt|&Lhw38F=4jC+QFDEPeAv>n||FRv#GpOM3 zn}7HRqeXtv_{B&0iRM;?KA_Y3$nejz5z}sf#p`49^zuw~9p$Vq_q`w{KvCCU?}b%{ z>3st{(yLasv-MagWD_Wr2A=9r)+dK8e!}&n)$EG`le^SF*=Xg-?tn0R=sjG!bd=O_ zwvxp1x-vKX+jUjF18mdv*=>upl+5;#;_Y&PUf6FvGfPzT5&ch;+d{|Q#LR~vnm(gF zckc|nA(DPsDIfd{drKh7=jP!Q>!TOjbL8p2gjy~JIIBiGAh+&Ma%|j;tSAnuF=oYs z0ezv(w)VNO>x>ESv(6uIr@}aBfG`*wa=w)x5vSKn;Q+PqE$oe_ILh0KB(p5#(s5{Lk4Jn*Yg8GE zVA21b4;&7_FfFq$KgG5N)QLQNhoid)Qu~(gvNw6IaxfEHe4Vs2eQinZWAswof&}N- z?}R~#%z@07C;9a68nk=8wG{dgP944T`Mt?@;eV~Yi(5nLcf0@LxoPgS-u%xl_!sXM zESid#14Idn!N(IF{B&XXff$FiVBcc67H-O9{IkjHlH{Pg+fK(o$*#oL*QbxutOjk9 z<)b~ISpf^v(c$QsJL*BRPe;2Acbp?0A5jW1iMd&(XY3F;fLTZ}v1uj!n!Y_lL!M0hm>TKxNAyl|xOQHc2F4DP zA|nZ@$&9DWIqV{6{I08C9I#>Y5GR2aMGPBedSXXK(fd%d{8A!e z{Au=_^XKgtutP;T2LzbB410dYFsV}egkK!Z8@hnRiZ-)DQ(!)$xq?ccjgF4cJ*tTU zJB)lg&AHw#N}jhKu!;i)-H{s9O^|qheoku5kAvB4(r0#_fB7l66q*<$Mt3=VS?Dbz z<6u0D-LPLVxk)i`DcUq)avop&d9H||M>RD?CM_FyV5qTfuELub_CVaevI6KIz8^9Y zZUp~52Y%0_XA_nG0pfW?2VTZR{o4RZ&w*q~OUSC(0i9n0lxYw&P~;Zo6?3oGXr8_- z!3e_!h0$T*0kE^W1kK80hj)gjwAJv5h`1NyjqMHU1z zU=rH!SKehWoW}O9jGs!Vrl0RWTn(w-DZSy1A_*E6PRCj@cWLYBUOB&Q@$UrWVhHy5 z0(Vi~F2a`^0~md!8b;LV6A&(2IY1#9x!^N0$dIeD=0pPbUJ!PRBsTps@Kn;j*|>bJ zx|BY5t?+zI7YN@NP!z5DZ@d&E@b*=a!c+c)`>S>NkNki`B845XaKEzoael4rLGbKI z>ssK30}NLPWIhgrjrUjbe2=vzj62SNdG(~NQoW^#9JnzImf_>zz6S=jp>HaYczht* zSOI-RkmqM4puY~}Bu@i-;Q`Vk(Zuzm#IGWR%)x58L7C^FDFw&%|37<^pkCKXeadfI z!3oI4>&#%tVuABd26g#%%=ox>G@`@>@46Q_U95LQO(lQ(UttxV8kpUnfoaO(|>cV&w*^l;9HO>I@T|>m4tgdUFW!)vsD%?6iygWKZgzxs9r+>@zKbN$1g`GyJqD%WnX zsMb;a5&y*_o#GKRpY&-^3;}s%Fpk%Cp#kxu$P zbd~zzRqnw4u%pFqt(~$9vHuNULKOu5WH7na0s5!D8z*~vIA}IELCVRi;)uneF4upQLOIBRttt=XOhxNmn z^_$lG6{GB>5#xj}S2fEVh0Ns6W1>DMy>zwLt>HU@mM`ncJrP;!wn$*Gd3!T6j~Jk* znm3-G2)mP&u@Hd#ruAUb;^;pkXCwEhtUHu6=cNna(U(S>}x zms4kWdl(wxk7}g{?+c~aRF{=SvzA||t%H2h)!+JMAJH8-uWO}<8Z6~6tRp-cW+Pv% zPdZRo%zEBe)44uU^=nL=vL01SgVZqN{QSHDRr^4bau%mH^E(|SdJ;Zj5qY^Q zFO^0$`H;01=2T_71b@BcNjD^X=rVA7D!t%&EM)e%Yr&mDqu3xsei-^folX%x0sO8O z&*ib@@xgKJ^Z`iQ!T(3`E`^cjollh-Mt=xurP)r8zVH4XpoUIuPa27p%(Dk;XJtVoJ1%S9U?Tlvk=XZ00>(-$9@jzZmU4^Lp;)QwNr(!Eek(p~g87$@eVA1n75 zjo^6hon9|gDowS^CT`MIYdS_uTPN>rGN_CNvfHcu2MF5;XeGH^zr-D>3v`}Z51Bns zt;5JNG^5IFvZIFr0rA=;(IYdOn)R7if0#KJ&ejgkc~5+G5^cbSVY+EF<2Pf;F)DYG zwas$BO6kt}#!(+;RvkXgV7_-jdu0PeE)oTOKT)95lzW~yKvM!6+z8^!exCJp69^ml7v70%l*NuZvtv4@|{$OYw1Te{}sDAZnry{Dyd=>8yLs#vGZs*#XA`WYoQ z-(6`P|M{k!KR-PHuA4kM{CWYSW#y>;PbsmG(FHM3R{na<#Y(t}cD4qj=b1F)ju;Q;H z+oNxpQ}3&z*Y3gPMuj?DRw+zwF6GP9o!sc^M(44P?plK!TX1FKn8(O?4hirl!=Ng8thj5VwcnAHKoQ? zG+P4^#u$~}oVO4!$tj4u)_Kgh9$OGA3}_~nO0_b(H-!d5re%l9<7bc;xhjy+xpHOH z_%6R4jtp}~{=a83%$_~SvGCWwWs6k-YxZ27hnxSeK!?*TQ+WtEN1i)QLB7}_ESM{DqYJ@cvOnhUMPb;X$r0gk( z82pi)W8%P@d*G*~+wh2MYMtkk^M z2MpTu1$`4 zdDO~1d+xCS(l==SAQNc5;1a7*(nAH(YiC#uK9l3myzDX2e-pW>-6E%0s6ttEG$i)e z=P(y*7A9+v0LIKud@f0q!{}U99IzNheUA5-0Gg$dks#;aE_pn4D9*EmUkq&Ve80?j z6793~m}0*(D5JG`>5TzntSg)cB#)q0vRMi0$>h7Zoq!i?0Hgoxf&=`-3Wix$%M(XO zRgmu3_~SELD?k^aO11KU_K)ZlQ%k&v9x;U`@AE23XwUmqE6YrMZ_^%{#B0WBn5DSc zaMw$=Hth5Jh!pGIzta~{8$#F?2PelH8;!%&c??G8EJZe`JY!X3F1P z!q-GXJS_FoNZJb%Z9v@dcXnX>Y|=+t(gF#dFC_K4ZSYauCsgD2c11r@r>3_7h?xov zX@oRseVHZjx~-PA?<=^lmZO5w1&0nc#Kn*B{YMut6E{t0)cAq8U_tQFb2pzF0Qs`% z%sP;T;LrCP%>wq=z=1umCmP9E#?SU0RdF=>;7hFSAA8I|fW!#IWW}z3`l?7_Tpgaf z%s6FPWqA-aZ67}q+(?ei%{_rU#Z9Y~JgyyZ657=U274!eJKk!Xd{S-N!1xV&0-enV8xb0gfiM=#GSo3l_MJogbB{A*k8}i0UJUUW`)W zIi)hFXYlWZptxo-sz1Fby|rPB7H~u*5m9I%I_12;=_vTxX_mf25VZ!n4cnhF;35tk zFjrWCAmwh~&&8p*S5S5wm?3G|L6c^VVFfp31lEA}=FE4<6SrJq=l*EGgDsU0sGc{d zAU}o;_`i$^u=2&3k0u7zY(C&v`3$I!OD!4R=7z4|lmDLwN7yx#UH=iY-SM~B!qPai}%z`}7Y=&JdA7zT zn~@N8K45CF`Fgt2aGamgo&*hyBv$ykt*X0pzU_1^xm^ALGz@=-8eY{zGi7?nazfKM z#JqS*d7)O;9ob^jGlootJs{dj`GS@XKDxnz86d{3P+6If2K~Dq))i#iFdWeH%0)?z zrSKE%hJk=mclB@^K}9bIp`~LuiO@GmLlfbhh*f028~h$f`kPdHIFiK&u`6oa7?lMn z)hm{-TvWIi%qEvW9|C`ZB;V8s{{JJGKsM+WwGZ9dXJ?!w3k1Pdw&i5uwv{6pT}mj8+y%-`<^AY`7Mh_=^M(F%yHCrh*7`-S3V6qzTAV9;Cg^B+eS@`1gdv?*#S6_zms? zhE05x#@8pqgCvt#xV+nmLWRVgZZghFQov3paP>7fP#A8lD~fs5b?DbW@B4MnfCDTW zs!u#-EJ{4#03!aUzWhAa;0BWmV^=xBzj8RFr2EXHqo$$R)$DCRa8>qOAo#@@Q#L@Z zYE-q;9)HwTo+ODt3APYampyF8v!GBG*$4{|mN`hN$FG2U^Y|5e5H})VM`Vmz>F!#; zw%~Y=TD{Il9nt97UEEpoWqgKkZ9oqWa4@R;+E^R@W6_`@SZfV#{T+^ufs!}$<=YR3 zwj@^QJ|u3b`XT+!GcED`O?^Uai+}g&u>m%O*>V*|zI+Qu?VQ^m`W0*c%mMf`$aA|LDdgQhP-ZxjtUT_KD!iKNIty7h zO9}0N`<8fpWWP66NlK7-MOD^%F3t;tt;LsX7nOU&7ZoGZO{xd;XFiSb3$5zEek`{9 zCIRy)_8qilUfb0R_-$jtnw}?kN%N+^8?kdezSV=-e-C{)#$EXF2QYWAkQD#18Z~p2 zBNa4IbR3>CsHnA0E7SPtVta%7{34;%O&3dbjBQCWE8!dtcnzFgLTUouZna%Fy?GGD z({Sb&{AUX{EKrIJ=$3a4<6Hm>a@`+GuNM+aFPtEdFt95UFEcX3!;=DA?A3bu|_ z#jV*fH;uf#23MIL?FP^uKF{BCP4aMv6|CRmeLc4y)QJt>2q)}lGE7DBbABghlxb1T z1stC_KXAkgaHDM3oB@Ld?hSBqEbBI_kpbe~A#`8r1mN0NL}Whf-X;2Pb#IRI?u^Pa zkT&53C|Uu{e+fD8gHA76mjg^@Sq#XyD3k^u7#gTOuo55JXtuJ)U?gLm;eTOlI4JWt+tLvN zh4#yV+sQMJ&^-Rxb3IaPcot(yCY{u{yjR_=^{Bt~rRo@E_IN?gD%^yxK5Q&vja__u z%MKtzinI9*^6yeY2qlFdG2!a~vwwJT+Be2lRXfxdlle^q8wEUI6!V)vcM>Y%sk}zk z4EIE~U5MEdGuMoIM)3Vt*`2TQxc%4Tf|=KafZm)hQz{OKELPO=Md>YgmnRMFKNHJv zHh1e?MV@1`%ro5;)IJYQnB+tLO4l>Qn$c0KhAgsb6xl5W{$Rj)!p3o`xrS24?7} zu6<_SY^!w&^zC49MOg++ffK9+Y-#w^dnq^Vpg#;~*T?LZu$CKWN@!QfC1{K3`EO4( z)nZ_8Vg}$cYT_0va4aQo*}X$-$I0en{yz55_4rkO!khW)1LH^ajl7)msnOnpVkJ0$ zzkjl|xjxL{X}iij>#U1%zEf|#>RrF$Nr;u|#D23}pe%Xpaj~C(?bri@XL}{s^5<>d zQt@M+A&rj!nZWtXHr4hX;wLI<(`~w{dtM}n{k5io;#>9#bqrx5(M_BNQaYz0Ivw>!(I4~gl_qA zfFMI^!(S$WNRrr)k&YClyjHa(W5V`B-`$LDs`+$$DR+`ZKOi*8^0AahP%p?NgPmAc zks1NwJ$UH`z5SYw3)WOGwT-h{$AJYHkOdUo`noK+V@aoci!5SJl1&VO7XX;AufQq4 zFRC9G*%;7TESi2>{D$k=k|~Qj5izwa=0%4SG-k2=FbCP|Cjs!)$EcWdW5@#@CRB8S z7ai60o#+1D3y53bk|8NVTcUn8aQGzha-c>!vI%U>6KS*_j!T*`16Mt)@F z3}pt1(++T?9Wn!kB;QDt1g=}K0G3wPB&V=>cJ_%<%Ii#f zy%qi*;Qh^$E>}h?q@?Ml21BZmo^59gaGLHCC)$wWr2AcQshV~i;KNGdTp!5UgXXZD z4_MGNuUI{Q4EQWpMi@K9R90iGE#zXIy{4wdzW)J^Yc@E@E4WYY%$BLHI;fYpy?4yqh&wNs0^1 zf@eFBteUw1+FIh>*w-^TV(*7&*L-?2G^Y{01@RgTOU$C1kIH4!-~C%G&9@wu@D(u8 zLD%?OjQqeyqFtppcKi-VVe!A)`+YT00`Y?=n+p1*cG6(^>_aNKIlxtj>}EG5YPnPg z;1DTa9L9^0-ZHlmzs^nU{Fwln=HJZg4eS?Mkx*B1=YSqcc-{(^;Gm(Xz*K`pR^c=t=_^g<2P8V=R zM%tQ%kI^1(duSPDMO0NW85*xN0b4ruireeYDi)`(R94e{E-l} z|CG9<{rq$nYdZFOXx(@}AWcTt&h7%h0x+5PPOg0puYbJ-i#XtcF*@~pcfB8KMHd9U zkllUiPkAjmCSG|ZQ>6q4h>gYgkbM{#kzY!A*6xiAKB(kMenQI(|8|Jlrni{RpBWpn z!w`I;__^Ksju?EqN2}FalM9YvRSC#ziym_&VgZ1gBPCrq4NlpvF8^a<&tO7=(H;)j zR}t~AS4e&fu1hk-`Y1B>^j6u9?+d|Ff2k>U&*<4mF&sGpV zNJo^un5V7JF}m@Uwwn|{f&rpyzKG`c5KM=cvFbOg>=&iLv})#<7}O3#E>qA8gH`Lg zru)sk#S-(5rw+#wG8nG&7ffKU3i5z);*q6}e6}^tB|SZ}ISM~i*Lz9q7_mo^bp_4+Vwp6#KehyTq{>tx)3<3!Ieni1I53kO)YO$uWJm- z^8XSzt7qB(>8t?*xTK_{sKFrD z8M>uUxmk{GE6NGx?=6GZkw^VEi(=asb05st<<#GtHH$(G4}&sS)m`iDgK@>*OGeo# z_}nvArY=@N316uC_SYo{Y&op}#fP2!WyQBk%$8{5dXdJ1CdW6Y>?bdH-Ku=mDZ#UB!dA4eB#B=EWo%hAmViGd3~jYo(|JL8@cV% z&yZ{xY*=96V{0q^(d<$^`5aCBGs!O$7@LYO&CjO#(`h#Mv+d~(JTVK1Lehal`jrLj zK2Q^)%BXKk&QGI0kA|7n+7*~mwpw1*_8(t6tn~Z%yUd&;2ylf8^cQc z%iIQl@Ezn~dT*mF{ju9AnWaVdxUQ}5;ITZLNnH~0aq6#_FWDQ%aQkSNPO$9 z$uce0o9A3wJ|h)m(=a^6F0&f`HZea z{5sJcv6S8RlqS(dA9jOx;ze_*Gb4KaXsD=BvrV|tA$(LC^wVT9nM&!`V_w04HB8&(DyOP$Hh2`iMH(YBJ!`ca-IWP&NCcuYc% zUbIEwH?Tktz^}EcT78N4%@KtI)Rdwo9Et#JCb1uzLbb=xa9OmLiVU!F4sH9em14n7 zj(8W?fM2M!!Qzu68-Y08)?1uR4EnhW4#|-LTs>y}l4Cs*=G4?5ax6q49#Wh3XVQkg zF1}knKS~ODQ6(iqjX1-4Tm+(}A4BRMk0aCOGaLS<1^Tzk3;QfubyjRXu!Nhx%&j{U zZPCUW9b`U(USK!X?k8k|hlJGm0e7-f1a7%8lbND|LgC@h;q0~qeL$RXr4&gm&tH6c zXWO@j>)^>r008`!e}~orfp>K>i+&=l8pdbr`6KM56**d_&h^G!tfmC+<})c@bjE2# z-`9{^N-ypZ*khZSFYt;oD`~@g3VH{vWwmLa{q?!JVjBdTQcaGkNl;)a)^2DWWl@CJ z1A(w;U*}h?!8m6j?)CjK6yk}th1GK#3j2r#m2j2{qR&;KjpDo~}U zu9Kvko!em-0~6CH<#kGjr2*A^woFV&NXW+DmkJ|{7s>s8h@3@E(6)2@tg)ULv~6#5 zdPg6G>BBg|TZ~iIb^_N7@Drc7t=R#*B>2wAJ-Wy!p9s9c2k%|yN4az$7JM34^#X4) z3@csqP?etfwU2SkrOiVf0xKO9v7)x|Xw5%SMIoR3?u0svH9Qc|`4rv8-)$F^pWRbh zua_~`XMP#N6dx%A#lNm<0r1Rqig=Dy=Te4tM6L{A48HQZI&^3GGVA;pj&+TSS}>V) ziTfbfdta<49(>W2=1ODs7vLxE$aI4!E|>Y)2w-vSBQiWgA4hgR-}vZhDBg|qRb_~_ zV=F%W@gOxDLfr(CpJpnUeJ!M?`8NxgpUe53Xa7%OUPhipXuc48@B{ee{`6UF+AoL; zYD)n?e(S+O+5Bqx!9*kg_{3d*D1^`3N{RJKDvNY}d}4dNTZ&0af<;pA+-@Q%Hz4CG z<)7;?Vxl+x`gKo8lgZeZ8m)vEz~VgrBD?(5fEMXPsJd0^4Arx^13eiQTLcXT^i|qM z!%57sqWH=!7f94?I~Hb3E}V}6CPdcRoGz8){Q9ky!d>rU$1mFL&(dB1m~1%-XWtqyX`~$pWiau6I7+3g!fU_<%0)*uTcZ%A4=EQN>QQovpAJ ze{|g{=Uup-|2{C$HtYhzX={m@P9MJ%&D8GqwN^&{lch$@>QW-z4kRDFC6+xudXvvF zI)2gl^}tF}?#j@SzP+Ycv;ew>SH&D6r=W$k*Sd&TB_Rzc*e?aKVJL)LD1f zC3$U20&MoOBGXY1aWGNT^YQKZ|6D<(Ay4Hy7V4EQ*;*~&T<{93mQz~;yR=liVq_N; z?sfv%4ybT;0GIkb&@X>Odc?CMi61Hq_WJPt|0j%f+{uy+(%l_edzkNMfbLr~&);%m zmM#ky{(O{+_~?Q4rXs3Z;#hH4t5Xm*7!}ABG$KCSzYg(PVmHr5-;T~wPJoJX%6mTP?s8F=Wj@<#F^?*o) zhLhzxuQ8Yw0PQ?&VYw{$#!{1pBn&fy_=1}Un}>cUV_|q0-_PHQEKLWul1Hm}^u9|dDhF)OgFG)CmV7EER=DnMhWrm99r_%ZeH2e_6ME@l4 zIh?iA)c@vxY0w!`?_GX=S7*5x@Ob(gd{o{IFA#4DGQ<6W{LMSxcg>@jf$O$gSYfl! zY)t!bEkIAE5l#15uacr>79gEXv~Jx>R1Jv7(F3`!8xg;I4WA!^xO~MbMB-rvF~^19 zNykBvV;3c zL<*im@wHtFTn-1w9DfpijF>!`Zta#O+}A=pD1@b{Ms8#Tj;!{Ne;XH%No&%Lm~qnt9n)>?c8A1tz!}~0q3S#?WCC-5#&nX1;Z&xpl4IP>`%EQBBq=0meSF%_&fp%2h7#yyi2c zZfEBUZi(keU}kUVPT*guW~Zf+Z9SWnc~_0TF=EpV0Nf)2xD3R;e-Gj307`gC zX=zbiU48}}NBnpkq2Ltj224Pb$Ibt8C9~vys7~*TtQ})};*wy{;p5K<+S7RBPI12* z|EzD_^#vTjL1lCnR`S80G+$9*b- z0&Y8yxcqEBD2oba0+OtM+3`Prt>k{UB^m;w2N|zA9vPfrw<+B_ZjrvuC#p#toHM_4Ue&T~xi*am`kyuE1SYnHg9E=J^nW@&7 z%#kfPpc;FS;HB;C70-GfsnYeH8Lk~<;!xK~1aY@UU6ub{W&ZLY;MI6Y3OXP*gx?ip z8y#v@%%=iWXE4(ll>Fmc%lZhq6vXx7)KzZyRSLiZGB zpi8T>+&*a&Dh9BhOo#g)lAeUC%fAEk-ISa~GfV(Sr={|Xk`ihOjs!{lyd~9Ht=Fhp zP^WB$L0`75jp^%rg}7lRJ5Cg2(%sVHKS2{eWnX+aSfJ|=R>*3<`CE`uMYrvqPz?cKK#!RRK(B0z(&?0TZ46N0?k`oRI5-y4Nxfe!Cjv>ai)xe^GHY^2<^p0ncz zFOegw&n|J^v$ajm=aNtx$w;I2B!t!1Gi864 zYY)Zc{CI{0)~~ip${T&ZFKex)B7@ze6cpZO@)Zt;?1129f78q(Q$EhQ%78H$8NmB8 zXg&z*6xjnwvg4g!u9n1zlFK7?TB33kVAX|7iMIU(8vx{8m|muZE3AZ)rdvabPT12{ z)|u-&y>Te?5>E^+8On~7HePL6@o>DGq<_HSRm7xK8>oo$%`89cfrE~Sj*SiDWb=V& zH%LTL=_tT@8EQ*_6+T@6Gk`(m`&8(=w;IWf!+IJRJD8?nVW)& zf)ivlRYG+<9L3d^&Q1~pu2Z|G^Ibill}GIS3Su+@_%3SzDDU%heOTBJJ`ob8p`52n z*yqRZI?75h(be|gpFK$62=|oB;`=&wzJvdL=0+jlndx+ZXXe+v3fnm()wMtm_S7UH zR{09&tpEcsaQP%Z%gF`sUD|B1wShy9}Sy*eu(OM#_*tHGB(DKW`h^9xX-Wpe%(_#@MBc=8l@L2B-d8#AcG_s(##~)4m;G$;Tlr zZ-ZO1&$3LJX*>YEmd=ctxUAWQW6-{I@w+*dupIiji71Sg=^(W~Wq?E!6`A!^r5u|O zn=y>z5Pqg*THEST0Uty}t0@acaiIu4fTNDcJIs-m*cSbX7Swx~Gms_r8?ZYB*@5?l zJOGnnEg$n!cIb zM>(j!Vb0YggHddEUMYpP`BD>B$5Bpp0$T+0`04obXO>GLJ_)Phyi7n!5I zD8Bg94SZVF*NRbtsYkgQI9bqmgQdbRgVyeU2CLhWvoZMrtrmT1I)ZHtR{{=5n-X-5+a)^)T2x(>GDo$;6g4=S= zY+|iyU2CL-6j6W&{fg_@E$hAc)`eytHgMwOs z+Mev81c9w2W>PbU>=I$?Q`;)cXFLe`aTDhYwM_lvl)0Ne$<2GqyATd`@A&m^F^yOy z9$L5LplO6}oH)Hw`hbj3O!#4;0BodU{sUL%oHFmB}xYzay_POgcs>m`?!acnX;29Ek~llk2u< z=TKh-iKZ;AUDRobZ`|)Q8oida*s5o|^bZbp11VT|@jEN`tAP!B6XvwJfF2#c%Hjl( z*?fm}Z|WOk%WBW`>~a`@x_v*SRx(w+K*hw$3eKwM4(E0PI7m_-c&!?Z=~g^Wjci77 zcI>}FbIdotdP_Ap&pF&}C#X;kb3s;ID&fi_rJ(aCEA zVRyxX7(iV!^7TB637Qfw*TzK9&Xos1G(;?6-jc35;4KjdJShPBCq6sO<-nu1Q?d14 z`S3Nrd+6}i4SG$rgVgFRgJo#Fb4O=s)E}#M;Q$up=2XFSxBJ2B~o_EU~((VO3y+au|)e5L1`4m)5Hts4Dxt@!vW=pzSC`-4+c?j; zY2wX`#K`ZVmGF2`?KEZpj09STO}adsRwE$WJOcee?&S%EdkAR!>WDyCv5CCj4PV=; zpJx0objw)@;I1s-`80slaFLv1^SMpg#^yH17O-I%ZHWB5M!=nM_k5tUF`5?SZaf`m z0K#vFOg1Y%6M5W?n>K75;M(pPc-St%7Hk5<(heXNi?Ba_*Y!hC{$UQm@=uyL7#O(ptn09SH4|8K?h&f5&;4tj4jN3J%k`cjZC5{B)BB z$oS!m^my^hQ=^OX~Z)n@6fB`=88Ro37TvlQ1emHi$iQb}iIBw*_d~U%zMQ z1Ii+sPTgSMoE(_+RZNC=an4&EZnjs79%o&VmunS^LnZB_R90mVORSOWF`Kt%T7Vy{Wwr7mpdsH^8zaQ*aG6dd@=xeVSNGw`c#Zi zufPr?`Pa|;_gnF!xQuxBJMpYt?{w}C1h_qp_UmyWYJq-302o$aY&omY?7{Eelk#C- zpsu5Cj$(1;Vew19)&pk<`)B|Uh`jk^xSw%g3J7<+@%Avtm;>_E3B9Dhz>11$Iz+eq ze0M*Ig!hT^qc`lzy}>5Vb9D7B0Ts}G#h&)-j(LRg)*JSdkM{5<1a7o%CG(r9vF!JO($i^a z(i&>P1%Pk*;RXx{-=^F^FpLT`fl2d~rbhIxt}`s)eS&vdawL5qa3c#ywSO~&@Rl_k zbyl(bj~_EYY4TC(?aLa@pAEIM`I$U}5K)o?0B#Yuh6#nOI=}UcP@=m5?gz|vwHlQ4 zBLRhq9Z>)MqprohF}5RJGaA=WKDKwrtYXc+45`;SEw77Acopv2?N<9KEz}w4W&~oS z_aJ<;&E7P_z>xQ#$p~{tI^PiRgq!Dee7-h z)4G!M`pB~x!SmR{>SS_qu{6qeYB#g%K5DQil>|**y!-lEU78pN?;PauOfZwxN`x!|Hv7kQkXE{2<>H-S8dU(3C&WPi@BA zo+8)19?jjd!+k3;9gmfj8iy%mokc)IbuiVI0jdQ2u#>yes)Y0~x#op0*P{hLHJ4@c zk4rALLs+pY?5>;BOi6#(QU91>kb?AYg!d>@tT1Q$jFd;LN%A;4pKx@&*?4m{l!ojm z1$9^pQlT6oxg~YzoU-g-1(T?7jX$O6w1Jv07BrWZ)}YSfa<#wE+szIQ!Ov>jW0bTh zi10TD(9)a_s?BDqWe7F=mXbkm|4P=n{NNEm=I*dnOs`eBUV1xLDk1RP*dP1N-c~C# zqSuysx3(+3yng>|73rzyk_ne&CFwsNf!)J-d#uA*vBX!eK#9HIUw&l5Giqmn8klqo zP<0Sc<)-ln=)%&zs7V{IGC@H=cyRzAN`o_a>##rl>5^f1fry9|2tz#KWn_pNRs=-ofQ-MotQs9KVLt|9Eg z4z%5T)e7H2(<9#g!~T^_jFf)Aa3sZ;%v4p_$4MlWbves8lP)&6N>O}JI%yjUQSMb) z+V~JhqQWmAfMjiOD0*cBGqtG=O>TMe-WJNmbQICGdycjg=8eu)&ft9Hf=s zAx3nRAWa{fCjSYzp`wDx-i^wD|1id(jT0cmO$w&VkHSDy8MKE4QD~kNFp`9@oP)$| zo(6oAxh1jl8ryWzWj_n#Hg5%xvK@+fLPC z#@pVZ@{-;Sa@zLMnTuMah)!(w3#q5Z*IPWrdk37>_Y+wj=DcmrNGHcLu%;vFU6BIM zsiZ4?8866c+MYNE(=F1Ekts}wsc1RY83c(OZoiP+z7Nthx7hwfa+-#82CVu@fBO{QUf`TM*Vh&aCKos%S6KvflkxlHqth4gEzyrJwqk zl$HYTyySw!_{dy!jIn8HNXRE`OssP|uy6*E&)^_FuV~2Oa3lo~b}5B%hNYxxV4NpS zqns{7Ft5}Tmu(nvTgP`)sZ$K)BV=V|Wq!tk6~f`t2CA6*-I9rkjk6F6s-u^s|deO3~-MSp*&3)Q%N|0p@knYf5C1$a`D z_$q=8Y?7GdEM;ahBJdgt8s}sGO4zT#uuFKc-IA;^(av#YYpHYScz8YEB@Xkjqd|Jb z&C?sI$W6QcqiikzsdzUi20?>pj@U{gV|K@XyI-oKRP%;q#Z6q|^hPW&4R`^)_)Y>#kqZzOQu7YPFA!G`}h$Lp-uLx|Q zsYN91p+}6G`GteZQ!D;C66vA$`O1rc^WH{2)j1bSj@PwK*2-xYlk-VmEoEaNreOFU zheb(s@UsZ~VS8hR++bnKYpojTTtnvOc}M^>OJOqkqPt?|;j@R@~lo6h>ChWN>g)g?1mki>o7_TNtE$=swXJMSl0b!-IZurKd&TnsF6GD zzfq7T2KQtt3Ge?b@AKp*sPSQ}(PU3I|6+0$XT;SbGuG`YvcDf@xr9|IcBc+d6h>=4I1z3j(>0lL{TUGKfUO=r7}ANY(E6sqNfdji;>tkjoM4p+f0 zC%v&SztE^PRyf!?$j?Uf`u31n+`FdSJZ)7En@ycjsFW&coJtV#M10s3N?fVb1dfEg zmb*LW7RMg3Z#T&DJg?l3*WSS#Dn~ZtN-D+OF&P+Ph87q3;?#ZGOV!RRbevTl%fteC zv9`lW+x-;vM!4$QJs}tdmS+9j**}ntRTv!WYBzcb`E!3H__*Ru`f|I?!Rd6uTW7Tx z!H~9KS^$d(+nZEvdf9woe=zk8zd*D0m+Nr|yxKnD*TbXTRi)_BuZGk38+ZvnMY^Lu z`~4S8MWGJDnKW_z3#_hZG!rEO{bFa{r$}-^9Uveb8mL(IN{E0H?#J~@R;=)D)1r4d z*OT?-tm8Tov(-}|vWGgT#qhLs6;9S|%j^>gX{SRfu5|;!6I@@>q^V$6K<%a^G=5Q# zSV4r7!Q&17o#P>LfMT~_(?Z=Jx$)fdVOPMX?07VIvk4`kqEh(5Z>iji>Cczc;;YE2 zjs21BAfe7QEwuxR{}3U)P!>dBow6j*4_ zSF~qnBtUIu?F|Lih^5w?AC9TRZ5nO}19R5bKp9|k9!pY?jyR%h=!j5X`gS#A}=ADvYF5p)AqjY8WzV)DF_+` zW&NRc<*jWbA`v#(8=Ro0f%uV69Knr@r@Xbr&8ytPVzEvKSD50nE0i^EFANCOcEss# z2?4Dp8p@NrFCXuCFvl*Tl7}A8s1+n0{&8)+Pu%==C%}mrG@@c7{JG%|V|ga9vhf@u zk1l&Z5IPYPLBTqGlPU`QhfV@u2^8pno^@fnc~q8rbh;hVPA+NBU|$m2`K6b9SccCI zJ@*EC*EKGaih!+yNz$?g`++*eXU*M0H)-mE(z3Vj5SnuCc==Gb#Pb-^V)cg0bMcYy z=IIIX4pv@<6k%@_y6t2nS#n~dk8Rgp|B3(BNn%?%+S%ov#6tZR&he>2W4HRSfPR6f z1BEfn+BP-S?r@gykW@3>}JjJ1PzVv3~jT2wYY?BXQ&&;{=@;zH{9q7-Ih|B0+rRq;Huc zwigz8DiJoO3yOm+j}jUc@hnHAYtqkMt;teHPcT73Bmy)Wl>hl%&In+6RaOmuyk(=J zqeEitdA$Dos4sf`HGQb~`rxWw_mzO#>3cz-oqP%}flNlqA-ltmq7dvxF?^X&0hoi- zVr(+1;?OJP1SMz`b}TTgL&D#=3Co5bKKP0|+sH56-U4%mZ(N>98@1zsp%Q=- z+{bU10%!8|tJgK{FX1P=jZ6uNEXB#0y?Hkxptxm~h^ds9>j~3<|9dm3v}atJDui^s za)n719p&D5+vN3Nzqy;^)_iwEP8@j{f-tGpkf)lWK-0|L{yBkMV=gm2TI zZIA9?d6_*!A~?)PNDiqOnq-$*Tp&sK&M*~rExx5(l+gi&_x)|;MZDag6XpA|If12M zkjs=90_wJq&LH}K-mlaU0D0(M&&yVb@n?tgc|lzKfU6*;vZ1ra%7w@Ar5Tr2*K@fr zg=^KqbEOuVR9t=x!DQ6=V`>Yiqk5>~W;mQ{19UcSx}abSDtBWxS`Y;e9>a?ouDRLI_{;y3D2CSZ9?f4k698Qh2=hmb>)yI$Ya5=k`@3ct* z6o0vF<=dh^;Wrhtb5eCirM(`X7q~4Zg?)`FP8&O|!J3~WMU7dU0 zyKS!s`~|~tADlG^&qdHuQ4Sve6XD&p*9-DWB&O3RiA`}tCcC?w2B0#+9~of#7UpcQ z|NhD?6H61P7uEAzU+{G$kJep<{q{n5N z@&lOHp6;>n!uj)We>WUWXcns0!g16VD-gq|>3xANkjofWA-*|C)c8dHUc7|T$@6)IiVHxNB zIhhmC&O=<%kW)J)JXvDT)8Sy2jAb_%_%9Nd4bFRaxFalV@7SpHen~EGzdhurbo6bO z3oMGgyo9OlEh+i6XQ!DpRHMhrETgEzM8CNP&NPdGi3El6m(ux@^GbR1*SR_8mK_q# z1`;(cytdDsE;M@@)#48BcQ4#a({*{C4!)P7Hdl~(P5MBFMd%n<+P`%Hn=r7gcMnj{ zd%_|j4Z`kEJym;(wbI6A+AE5Ig)&pr2bd0FjXU2la{k1oIq2)CQ_c)e9}r(~V}Tuf za0uoWTh5M9oK2OHj?S+EcBkx`e(BbKpJ#qvLjV=kTi*MN4H_Br5|T0RTI8!6Im%1qbZa z1l*2hzQB_=AX_hagwUk){i%tnz`SJMp*oEiF7^4WgGsPOj zccpDxWw-E2QBk7SB03tym1HOdcgafx^qjNnzSfL9!$3u)&{ylEm}f`MhXr}b?Yw85 z)-1J|a?Oh(a6FfHOCL(FXAQ3RTJeX?;M^&Y%^{FG_CQDC5Zxh^d*_!!&QXak&n>c= zC9YcR;_^cvZJm(I5FJ$Tg%ud}e-_8%2b+{+n+7K9#u$-DVm4NE9BN7wH=9bCnetKJ z$c=krM&C=0u@7f2`SKO|<1Aw^wo;`Z8|B_k7sjUB>{YKU=iO!G4(C<($F%e*C5Z~# z^W&LQhvf3M`TWbdyAkLIc)WVHCb8Z2awnUYAfO8RI@HB!ZMozZyeZK&I;z%Zp8)9) z&?thR&7fFNs8yybFyrlDkfzQt6Ybz|?Hc@KEaSy3vYdsam{6!ZRazA%EKO_u-Y|;l z6f^4L-)I)}6fZJ5dY}a0vm>eyrc&yJCT3fPuvdyTh*ek76pPnvO=a}?sTz^Ng!oo{ zbr+bf)$PchKW%W$|5RUb?s9Op+*Ud}#Fdv%3rESJTmx#ij`Htwr0Rl#?>wLOO?g@E zi8&=8DaTToE#JSLc-4y12KQC|W>bY=1fCW(j@DMrSeLt>#bz1s*W}vfd_$v>2y%e$ zLsaMD`g+*pWYFQupa<|3)cev7os2wp#VzLXe&vXh$WqGxcMX$3MkMTp4)iYArSH@V zL;NcG!f<8uaw+lq?!j53qA?Fy=-y5XbG7pJdM*A=Yqz#ptCNy}iqB-)@&&j$gJ)^DTU!{mH%&_M5-ip}J{`Pj<_PVgl0hEJZV@zsn3GiTB z481Ti%2e9~&s|D{8VQJC^819wB9na5%)ceraxwpTMb{!Aa^-|Gn*qIajUq{fp#zy8 zvY52E7|>%C|3hdG?5Ks!JwGqf!rnRfG)AYNCCp$PAUO0bhoN8|NlU#}R75$9L-3Y@ z&}Bspqr9kTXy9OBVV4|(em+SDFjG^*npFS(nxvk`?|MariiTF|E?q}`4=dmX6Vy5< zLTkNbx0aw5Ba=c-iLBTE+ynt#5HByD z`|7Boj_3s~j+Ew@i$0?U1D0~2zkkQ->T9+HY&}_93>dm+CnKeI=dGw7+^(`pVf7_E zBI0%7WqEPNYOIn5DfxTwXv~*)F|JrMvU4%(Epw_6oT!uOSqIHxI=5ct1P8&8nk{>%ySTl&Xc5F|dR8z&a7aR~)oO zPSl3XSDFA$zEWvrxqZSssoCcX_TPGOx#Gg@MzE4S|LhEzVK8Uk*!6-D;L5_T`d=gq z=b-m-TA3)Hd=pnqiSN5jjmd)1m1iL4>X_SPXDriDLA=Gsi1?Wd3Y3MoXJ>?O3Kz-O zGdkm_mvxQf!T8Ffd^96zwStNJF#o-Cfoq+Wkyqne2ax3Zi}- z8Kpitpeo6MP6vXPew|pz)KM?8^PLMU&z#5QxA&R39lUe!=3ZBgV-PY1yavFiEf*B~ zE+3u@XvVz{-^wKcew7ric=uqSmox0YjuIOd;1hFpb325U_N5VT$6Gz&Tm?dkk+vG(FrsSWt9IOiuO)OkYwj}uQA=5#SdeluUrx5dt^n-+A zm^PpGLtt^e{{0Xma4J}X7sLrd{0kli99`a6Qk?>;CEV?<#( zeUKVI-F$i(kmPC^u0tSK{f(xtwa?D;8)s)~Qc~)RhUNDf`o%=cVU%|kk9Jry1CT_d zRV1ucKVR0j5KVlYCj>0K$P_I|^sA`jMQPyQD+T;}3nX6a1je8bL&lz-o+|ro9^xo>F$1ubMLw5y!X9-b$zV4=bACb_{9()Id@`&w8pAMSq!tuU!HhWw}TZC-&u}C44gqf(wrK-qN+)d4Tc8NU-(Zvxok)G4(Ls~=CcHjAIIxpt+ zzLYIW*QJfST8q|FEhgENB;ip+EE-AE?vdL6%DzOK{lcW4SbK@a^GJeKD*&3DogK{r5k4nF|XEdcuU_?QdN&mibV_C0E5gm7Ni!lk%?7 z$*fqZ9{@oR-k}18z&6nw=UIHBi+1Jk9PoBKJ3AVx5O^;;s;69L;ccS#Pq`U{ z?Zgpvm8eE>6&Oik|9sgXVF!4cWS7nEQL_E?#R^Ym$;*${w~1jlmN8q-q_2nbKpH8A zlL73=Np=7*)g2k$rQF@0zKOhYx)U6hI?OqooI0}shR{d)GEtr6yG9$xC{80_FkR?M z@QQHIz!<;~c*F_8muR5|^mVd2zYP*g5E&i+WsBOL{5l7UE+Z@*{ZAi4R72FowBMxa;g7F@JE9F&w+~mAgZ~_Iyu}fCu_%)zrKl=4Ujj zvW2RJSq!oPb0(;>Mf5h+7bgKHgW|Q&9%;83BLcBl`&N$kJHpqQ|6ehR@b&FmpvQe- z0|T;vz(5QHv8{kn-ur|kMc|&Fl3m#`Db2oW$Z=fbjW-Wp#GJO z=+p|iLUtkH$2EjaQ637E^%E#0*1h|Z2Q&~&utB|XB2eB$+neR%4%k>)QMyn3 z;o!?8IdP^CPw+s;I$^ZNC^Qr7VzjK$>-3P-)vz4v@3LcsXA&RpOjK-{CdIBB?EX>~ z_KRPkno_jt-Cw>FU&qnQz7tE+)}4^jtSj70B0xx=J5rLthC7Nf!Tf6tkud>4?Da6N zKKUAovy>G4hmg;q`X){$V%HxX4zbQ1+#)3C52ktDU*>5jO`{)ns2KPT&@T?4 z-#tITCMbXqW-$818s|#^EJzbJjOQB)e!QCaUrsKX5g3q+0FcP@!&mBsIfe>5-&Yv4 ztOb3N=c0 zJcjx1@uBhg(c--Sg?#(+MvA8m&hiYd<7Q--wlFTU(#E`5L;?N!fb75v^mhi=+US8Is|JI~-Jl<25A-hKSoamta zbDd_`ypS3p%g7-~z@!jb`(9?qLot*5%hXN)TkW2C5DRKFk}THE4n?M9XB(YM)~8;< zann3J(@I%g*A3slfntKdd+rloQX`=E2>>CL5+3w5Rsnm@PQ-(4AYHlYJK%R<>`S8M zkPk#ZxhFC&evdj~et7S6iYhadrerrQr6eR^cZbZ_x_E@3YO#qINAO(+NYXUmW`gCN zNAFz9*%!iW6eM*kB;DSXq1)p^N*5nuy!9sb=h}jRfLKG}-H};C@v_&DgO*sb!26&D z8Gl2;;E0}ZTRh%p8CKl$k0^3gt6msTtk+`pW zR@M*XSRpFUJqz_w?00Vl_y+M8)0oLsLhttKWfQ-3IFs|1cMa`JDXIsWR?v@xcT^cu z7FcN-p}g`4@=66U7=8m;Wtoh9McIFTKF(&KGUE1CqGM*_U;RF8@^Z=)&5QUZgvf-* z*Vv(D7egGuiSjx1N>xsvgzsqW*sLE2v*-OonT zBcTw^G(7g-^$_z#KuG2?`&l`R40c#h)?zP4+4ORnXlqS%PPBe~N+^?|69TF^3M8L; z%NWvbzqFtUdQiQ|E`7VBgdD|bzNi9MgfxY)A0loiBlAKJ*fSIVHx1xvORmvn*c+62 zNg8N`00d^~%uGy7r|+Xi94S9n8i{xH_6AZSih$`Txqrm8?(JkCtzfuyy!Ak1rSPH@ zaD1aohccZg@?I=T)O$-MEIKtJwJ$9sJ@6v_!k*EwbscA|u7)KH^;_AK5ycMPI-845 zfuWZCK>vT(CiIb}6B;7;G&1h)+}s=FoSdHr71Dfsd|Ze%QjmJ!d=iV30)Dlfe?g09 z@`c=emG&#Fz66MMIUpznn%S zIP@Z?56Wb{(i#l~3273SsJ4)X|2<%cc_I4c%TG=*ewX{Vpnm4fjQA+HtC}d}Feg1& z>s*uV{6*{WJEumJ`LAEoxoer26r=w*_qDN~SMQSAiPW_ahSg8{_etG^#FmRpbzEAT zbAp+V!=1QLXKavZmVq4(MChH#muU)K0(*}KR!ge94|l`!vA$IC3dI>*Mi>|v@W{wP z+r=!4p?8z9Si)MiL$8-FCMM)QUF=@-NN)AY9}wWssq{;W!+w!BYEf2(66#`Om;|8c z0Fzc_%{w4M{5{wEkW|{VKN|Cy25#_!A?JKQRh#wO?ge{JkhJMunzA%uXOZue!u~s# z#F%?gp?yY|)JECN0$Y_{P3nE2%qz~DeBT@~q4Reyn5IU_sYl(Lk;&@eobx>i`ezv5 z=8E0dm_Rr@D$*bx0Oaf?l*mtN=|_wjg({?6Ov#MKeMB0~=o}3pr znO|~XwETNE(#Z&zMwS%4AB#iQyZDQ7Hfb3d$OKeGznEf1Mt}GUf%XGcUSK-7+Jp8} zJaRqEeVs`FkB8qa)w<~m=nVm z1ehDv6cPO0K!RqHUiJEh10yrFFa0!FrjdNae#q4#ze-wUe$n^O{YFsanoxf8*9%ns za3nzfUF!O4)~qRjVs$$6r+1h@+w5N2YJ4-3A78VDTDlq_Ab?clQdRV8irj8IG|DhpSji#t551m(=E6a&3_ubjaQq zVyB|kuxD&Y?EvXazv=@gXXhHpSH8*PpWV&m>h0cig2+u2wDQ@FjST~N84+pkw*bUU zc{SuFC3wb?kjq7O)mI|*WJjy~k``IxTR{1A@=1!18+H#)l5BGg9V`$LB?L!)G3p;e zXy1V{1;U4mW~P*H#859Z)S^WDlYhZ}{@*KLKvFf1zeUYBKm|J>Y z-P$0npdhIQq$L6^Ftn0-k_+qeYbdR=@w7P|9ZZI7kCWH~=Ow?ogEkZqd#)FyZ&mO5qI%6OZtutjSG6X714{il&K>sv`SAM~V zO&C69LB`oXF>GYCl=u&snmVyh%cqbbI2v;|k|}>X zkXMac!I!_#i|h+VN4QAf!G?k0OUF^3lNZ~W&Od{N9iY5F=pdZNk+Xwa1NfU3xN9 zpQExwAWgcQ4fDsmc`P~Db-FjzHJ{0R^*iYci7BlzO+<+$YX?H-NhP2PK83O$#&;Qu z4kn{{0#mBa=YF7tMTq@kTU`3TBXms~+C5Ob(5@l@C{2W&#CdLE=e=-16cqKJ^4`3E zRKDqu#P5O2CUd|09N-qb5c2UmHYC$gWZZ!n#!Q$)JhE+Z_Y*SM6e-plEwJDUP!D z6n#-O8w#4TOw zING~~_2VyYZ>iN>^q|W!AcB*HP+Q+bxiyv8<6(KFY%@vo%{S z@uK3rpTnnix#I3_HcvNjnUrt9qqDR1#buD$afFvN ze)ixuN|hrtx9XNiz``YwF5Uf-_*yKv9cHq01%>!`=6SQL=m-89O;h{EkyhCC_+6-B zq?U&FW}`PQ=^D!*UFxMGTicK}&-bl_WamI2kV_8)HYWYUgmDKDdXqCtyDyH&%JSX; zm%arA5@8LeY_>@)Ehv;?Yo?mzhB|lLon_h4Ia&f&@bIxPpPM7h3pd~q0T;*!Se4cl z!*f(vO{+h>JA0f4+7)thoYuLA$R@e62yp_7el{JP@y|+)xB0$FjQag87O$}5xA?Aq zK2DHuID*NlMfbD+6eXR%Xl#d&3$C{uE%Tj3C({oEcQBFX5&IKCNQ&=o%oI&m{CbH` zCIhp4eL%bEjKg`@Rs{V$PQyieTga8S)x$cuW@SuNuUgP*6aWeU?ATvuy#6S^Mtb9r z|GMszC?HlW_S{xSpM$2r7i%uoB##p>es01XU^R&`(m1Q0yklo#dq-) zyPd$U86Rd!{)awhO|F>1{gv=n(&SyslpiBT}9jgZP^?*zWXq zcfZ~QcibCb`Y=47_?J2L1UpW9@!hkvONOh^3;wPJEXvmzdh*T{pwiFeR#V6jP_S$7 zk;?x(c-ood`2m;)@0XO*<_@v^}F+& zO6E|W8X?Fp7lGYs z(0U&0Fhg0aFn~)@SJHg-c$2Shs_c8B`^{L#xPmS5EFKrc<%L=X4~c}pL9E@SVnRKw zRz$3g4E|2vi9f9E7ZpmsTaHN zhGFgytp(h-s?C`G91pt~7@+uJVx^=lC0OXW&qUoD>J1#t-jwUcHTkpsxXz0OJBDDUNviwXryJtrdE|N;v-PT>ugm`uK8;U+cJZjQIYz+9_}A8xX!^`{)78=aZN*Pn9*? zmA<3>Lt1PjAlVFzs=d69oU$1Ns)&UIHY2q+Z*jVRQRByBr^RPp#%?4yw>krBrd&=( zjsjRST9FND%{5=Wyu5I=N-)rbO7%DUh{Gu{^fYQ{LhH(7(N;9uNT5)_u=)@l-lql` z0zSNa@>*I1Ux%_|pKq2!`3N~Wp_UsB*Go0I-TokdWz-3)ty@7vr5utsu=ajAs;j@c zKd7|3v3;AIRUSno$05`4t2Lmv+!#)VXkB-s{2(pE>m7YatV6<@xr~ zS=n~J6IIzP%Q?jUY)t7IZbpv{{WNBo;c7$zs=!iR|;}Fh+(+KoTRr+(<6Sh{{f+ zvD0!lsi2f=Ca2@O8BIg)LkLzJ>tTKuBrayKM^|n!+r@0pTrSY$YS>w%l+&@bm&P_e z#w<?%=e*M~(*=HY^`DjFNG3!fy5o zz{F(DHQnGMldz%>s?&?tl`XSacB-Z(Az)Dp__LWa60FA%$4YpM@RNAkzbTMUgUNr} zBg8{MEl)J6)V1JJQn`_DYT>31N3V0ruT^IoDxLgc6CCRpbAR`E5!(?t7(?8+C6#R@ z=^E@OiN2nrXKGcD1_fwiumpDD?F+9h3OBf2j)YjdRj{ip4J zLFsVW^Aa}AID~nrm%i9Iulr9g_M@&0!&+(5Y)<{!@NdP}it*XTez;gg5pv2ZSo9M* zuN=NjF3UM(23Iiq?kU&U&Z6ozy7d}?-#FZ!v{l=!yzqJBaeSE;i52u2E3#BsnrP;c zh#@Srn_&E+^o2i&DN8$L-zykB^%@3&D~S z`_ARfw-k&`kB&n=&mK$TKe1tBiHcFkF6+wdl#M8G81&1)xA)T75K!nomoy8mhhc^x z{sE=$N3)_4vFSEaGWlFqs(_F6aB~9wA$~EI*Z-^jdf}iNW~IrFt3Wm_yi!3{tlF$D z*Kzy9ykP^E1yQQd2~Q0RGK^?wR2OkwU019AjlsYq+gRO+=>0T00Ufu)9}=*J;U{17 z$Qk$N2JGGOClEl0gEAXQEvKH{>O+_CSKPg#MU1j>fF08M_(Co;&XgMPe2bU0p>_1pVi^^i+LI# zFyl_AlOOzQqge8XiU-r>U23+_8du@xp~j?l2M+eOmJ18Po(xV2bB8R}e+k5Iy!BFE0&tfprVE-!kg z95H1#HIq(4W5S)0;xhH7x(&+MgJ#!_5?9{}Tg;UtJ@{YV`KLTzDJ34{609Ui9Gj093*(Wxd#Urfc_3l4m+B%vr- zL^qYjf3`do=wh0w>9$8|yU^EN{1v#h6)%d|3yO+p-o1OrT{`i1>FK6g=Idbhlw>T4 zxRKF@I2!fp1|8P2=XDnopR0+?&m<8u35n}gQ%Xk0k*c(o+NDQxFFe9Z78dx}Fy`8- z=h>NZwAPukg%Fe?)dp6J$6J?C65?G_^c+c6?-ma>?kfKarJAPG#*i2TdPEsJ=$$+D zW&@M8SuuJi8I5wLhQq2uc4=LrkMT#EA%sB1E4P)qR7`zRC{%5!ukSn=1!S4)dPIku zo$!=grO$Os(BtRtV{m@nnaZMIbb-5AVYLIX88E+SX4vSw7h<#O6S%cy;{9}$vQ|Rj z58=;Q$TS)T6i>#-$4OjXiznJjy>vd+$=)Q~jp%yeLLGzD$k<=dg7owG233aht*I%5 zb&C|u@tUE2b_iY6&m^mg0=SxZxMtEbcCw(GyXHYys-nlmi{+T&@Y;9wa3fYZ*|^8F*!fy`r#{(s zzIC!&<-2eeIO2FeHDCYB1Ia!~{IW8a=TFcW2BId=YO`a^P{{kNP2qI#ID5Rc!>I`}+{_gZ6a&usraNqRiy2^KX@)pSe{`fa86nV$0 zCIkw>#dK5n`=~BO%p}2k`i6Umh;)OGe^E~3@CC{S$j zz=&&p+Sc$1D}&bq^Q8IiJth`rO}xQg0L+?2$kKKej}O5pq2W-Z?Lwl$J_6aD8cL6k z8yL0}bZ2^ayAG%OzRh`k`zSh{kjt#XH6s)-+NIa7ftUNnG00LVsst1g{%DGZxXqN$ z-eotR{_Gp;C54M75+(J7CvANwLwz_-w>up`V%lZRH0?;Ilw4uvu72i0x|m4X9N<;A z+60ee3hf(>WDAAzIA!|_NKgReM*;jl2|L--#K7e?ih;`Z*LgD>ZU$ble?3JZ0ax68EFREe)ut<^*+!~L}v@?~sv^rX-48XSg2 z=WeIbavEl@0fYFX1;TIN)fT;&O>Vh~Zl6XWCzB-F1(r#t_=)1{C@-qiNd97yZfqw1 z_=_U@fhIQKvOMQj{4PZe1c+@vPdvvbB}L8Z>4(CR5(M98|B3ZSv{cP6Oeot{xaJVC-A(}E<${7%}OT0#e=} z!|htIT8RM*aLz^nme4pVJ+Zw(BBDoF> zoXDM_aaIipYaKT*N+VILAgkBFTixsZWV#OWAzoumK=ngrfAFjByUdQ)*<2iiXTUJv zDbpS3Ln@NkQ@5a|wKHpp7y<2 z6y1A!7gI(WeDYKMYk=*5im`)CVu;3lr?hixA=>lpg<|*x(2ki#5bwv$ZLYl2ZPTZt5U}6m7s>Q&e-3_kOr5OeU6ZN_`4R+49VxavdNA%Blz$r zBiFR7`|I*sq*tTs)RX&pUgfJK(?*K$?)F_A3V5({y3D5-9MPXSo7c})jlzsdwyrm!e!8pQD5=KO0To)y?MAc1Oj6`ZWF1P#8_oSG{Hya zndS$^*2N~=^wvjAx0)~cJN|e^c-ZvV1-_fwcGKmC%quBE&+wp@%?P^k8nKV%aHLaM z<{%?HD#4dyz9Ele9((z)LwH$!8U4eaJ;NFQ~Mbf z=F?LD2bF^|i!4!wTM!d&BRTcfS+aQ?B2roL)LP=(&)&S>4?z(PN~ zcbyF`2?=|iVzJq9DjLX)txYQ1=bR%1g*cfw$txSe=iw4=aJ}~T;@u?ZDO@3PHL0Ji z-Gg#h@NSpRUOrNMlo4uDdt)o5jVj8@j>)b}XWs>dp@ROEdw3cWfOTm~qK!(L5!hc| zWf)aI$0QT?TYi9$sS)*P(O@p_qr2TE!P7hU!&_RI&GQU+V{K@9+IRdv z)k}V6>!l=fGcjhy0s=qoy!s`NmK)Ga-ZX0eQiyCoIZ?h#?_gsJVoC}d%_w??xgG~ zcT8HwfCRFDUvR^a8Y28S23l~w2Ek^bF0?#5o9{C~3V=SO0Gg1e+kg5c6aO%o>uO37 zAM6*20RX9zJ^fdwpZMUJR^g#%@il*PtPQuHen;CJ(|=j(%?6Dy9yAiBZ(ea6RNpi> zY+2Nhe0T=54h<#Cc5u&KsSb(bwLWgILbQASTbf$$7P-)5lMZ#8{pluxmnSzdbFkqu z(GSp{LmqnOsC2j5;{aQM`#omH>*EKxl;xbW%-y*L-1iFUfs^JVtnfRdy*Ya}N6e=8 zIxTjZvhMr%n-Idd_EP*$sXH4~gAK*RH?KO=%vl=--XDN6t_SN11K`$lY1_5MHZ?7w zeRW%Xf~vS1v~wmH46tPI7}l?UyA&hns&ip1Fk|PAc15_9Ro=1v+=^yAmP^GY0;A%_ zI&?b7U+famXc|ANHd`7z%rUL!iaB z7oZ6;u%kc~mw+V&5ccJ(`FIVwb`j>P-Gluj|IpIpGv9|7+CO%EB6OnR)>55P0;KmGl0m)E%^q0nU%HI%`t&g&M-(+$nSDW!CZ}zi+OPASt zqE%&OOF>^o#<7}i4%uw$CHB>I8&?>n8J$*8EAB)rxI655YeXRprAzq7twmTkNU|N{?9QpKm>+Byx$e)UncYPVGoGBLkm_3g!|Xe#qwn)d}f+x`Awn!-VaKibvwlj-px zEfAWjsFuAAzv0>@vb^jse3_(ddKLdn&Q;sjJsT=4Q`zG9Q=njKj+@XzFJ-rD+co>Y zmK>?Gw@Tin=zT>zclA+Qi`6oYKf`H1sb?1} zjZ>CAG%@Xee2n>U`xG09$DUK(tzFIohZ#EOwznkcRe$R=+7@J1$H`)gQ|QN)nq)fs z6W4+LJ{44#g>d&Q5Za>Py^qiQ@=0M7`oh9fh7uNc*B$F}sk+);eeo+E&!f`P{08S! zl2^}V`0mTv(^~Xc9)huRrW-Evs(4GIdal;=htrFTN$}y_7ikkQ?&G})2;Y|rChmbQ ziuQ+eL6(iXfOD-!>8b)$nCbo3V?~@ew=DVH=(&_k8ZFj9S%E8PL6J;H+(5hLXU2hkSf8`pz86lHc!9jB}0RJM}_qE8m@ z(s_I^-xEk6t+=Zf>(KILTu9bfdw6}npi%1aK+2L-5lty?E3vJD`2lGAa$@y+%9eeBMA%h*=@VAcZw&xYvf5D2n#9Cov&5`Dnh#8wErV&R zS+5C*Fc8T>h6j=%y-|U)6~1gdTnB-{95GrEcy2gg(e$RdMG>M2-Ky3jgW~IwiwyuN z&Ha5+z3j+CdwA|>7N4EEp7;GQ`MficUhCO1T7^Xi@~Ih^H}}D71xX0(XLMBe)SFqK z-#YkIW5u=^^SN%A{bW3 zOK5gW?`lq(tv>qf%yhe-+29nP3cY23H7TN4`*JlqJ-K)t^J9O!g$*F877mivNGTZF{^)2b-ly67;mMW zsVu#^aVZwLXR-9-HwNrR@2(2Usa>Br@a*s5h-oC zw9>saXmYeE*|flEm9N?Zm)`N+Hio36;PSfCc=*z$KO0)fQR!)7Fej^hRF3%<5TB9u zCj0rDkzlC8>F?86Yt%$LjkJit!gKo5DjB9$0Azv;?Vnr)3h+)V-bXJ-Xip$+JH#v^ zE==t@@1WId5E|&NKcOd!L*F!K(;V3;Hh_jE+hB8#0}N=v2h~vB0O_u3vE#Vk$6P>L zyE1;V-*$b^JC+(x`B9Khy4c&Bc&FR&(0l)3GDdeT1%|sTQ(=`@UF5U;6z$6go3$f- z;#WhJ&tVr#v~;GfCNK48JqIq`Z3|Uu)aubtcU22c#2<)*ok=@W})-a#+ z?pD7FJQ7kc!~L*29rtLMvWH6?*UllGbH-$+vaOPp*FL!1^>DsP|0ZQ8OFw?cJx*U! zdOMk;&At2TVCKr!yXgwf-Wl;>Fq7dME&_&T04s zAPa@mPfk^A@A8~SAgW*A-2AnZ)|W|TN6$l)#igm;x)OqVq!kF8wRA>QsjxgCC6N1< zL70V6%G6KGqs*3J>O1db z8WtAX#aKdFH=7o#dd;HE*$>=qq7SaW5TniQa(-Q{iov|{x4mqe zEC=d6KClNfZHb~aCFMVJsZ))!kk<;|W~VivKR@Tcn4*6*cYwOTfe=!=?L1fisJYt{ zLWu)!@XA!8ylPDok+yldf`u%uB@xC_n<65u_+fwzFiGc%h8^V zx!v6yz4C^3<2!|=QwT<0K96iB1_YBIGbbBUs1uw#EbwKDePuHr^FaHfqqSx3cP;`V z!R4Rmz0R;-y~JRF!}rxuKsJq2aeap;d(n1;PN}Z;0h{HytSUTW=Wcx9t7bk5U*K(ImUc|r zv!G6?{-ABlP07#{&SxNdmYpo`Omx^LN%wpkJ z9tC+}BX@)&7{*=A68{(aw!VhWRzJkgS zEkLA)wxV4kWNM*%4P=PBkx!PRL%mmA%OT&vy#d*)NXW>2F+J)?w*wFtn@bqWUV?dT zf(8QX#;#k+OBNnGHuo}+q~5pq8f}%Eg=DO(kan$SRjr0wTYk;{_=3*p+?YW>P9vdW zkv-8Ll_6J43iT~{K^&VT;8SL+VuC1fbcSWypjideL_hRJBws|1~~+OYweyT|8j zd4RpG;cUY|@gDW*sR_T`_dPlAAYbvkQ1fAHb9zXrf2!54W-}v_$$Is|d6r$RqPl2T zc&A0df(BxptjhM1n+GkoFx0ulJjpN>7jM(_&5bus6W<hf zx^y%6`Ed0@HzxeHxmngTK^7G9Hvcg5%n^#{OA%*QXlsgHb?OpF8@rjDk@0oH6_A+0)Lsa&f_BuvBYvJcQU> zaX8)*Deq;dUd|m5mMCB4dw6Te#;r-Gk39~Ujj>xdpWUA$d1=z+zpVv5u~;w{{;L+@wJe0(#r?T8xZ z`|^bA%r3Tt+sg~Gv^j7Dh)_6sDZ_4)aM^wm$nqd+Mtp#i+cM4VoAcKQo9YxjpI{@hF=T35p-aQwEE-nIg;6Sh}jDL&F-XfPYYzKO%R%hX#-TFcz*xH(}`qP9Cnh{e)UU z1Q@HIe>uG0Hcypxgm0CSsSOgoLth&vi4J^!L7O_Ry?BKKZoRmB%8$v zH=Mp2P^=Kk#716h^(SdE=U54@IFj9nl;0hl8o(5>1SZOdpa%-czADVqbh50B>X42cI%T){rxO&X-PGA@%P54*pnVh6C}B}aqBu@kBO^LG^3`g#=%A|*=(YGs;n1G^)yiALdr62x__S*z9Kea1_q7EmhC zfB(HqX-75$_#Lste6R$R7D;PGK@`DEx$ysW8k6XjW|5cj!_shE36B-hh<)&MW>7;Y z2F!Z)Nn9#akrIanlV6E{*lln1w4i5N??2dDjJ?rq)XzZf|5|nXp|?}BdTdn6Ej0ew z-*&meb9;d3liTAdR1Yd)NYhC(mK%pv$at&(Y%4*hly|RF|Kr`R@2XFIwGt(>zy%*b z@d@nqK=;4c8C`#pBOHHt2G#HXv^xBGhx_vIRx|`f*zXa7ts; zpE|BCsHbD_H!i(gx7tm*ca)MS66sC0U}87UjMe$*5c@-=zr+qW8jIf^Q- z;I`=*+7VN=qF03a&2Ts&s+u8!9*(#&DlfDQPgYtgxDOl|KstP#zN@W1AyE@TrJ4h- zdsr36r2G;opm1do4-95;adC2T@(#mo84#7|o<#|_5Jqxpss`(K9r~+1l|uW|SRs4K zlFzO($48riK5dTyGe?V?X)s9k+tcdCcTS`0B}}bj9{KO6jhDhO;Njuhi_SJ#yv8YX zV`AfDFg~|EvI;(&iaPHu;a_~E?|8+g%*jzv(9A0)`2;f^@><=0JZlo%g_73p@la^h zeX%;L@_2eUfl~w!=O_{$9Lf-(7@=o=zcVb7QTdmBE4sgGvu?eN8a4L#64CA=2bvlh zU$X?*j9H%}?{S~*QKl$a?yrx^U1kzGn3{Zhu#6?!XM5G#Bqr*WRQT&mAbR1><(aH8q53gwet=ohF7n@yDZZAi`(1D zq$|W?w&<|FXw7>`TZ$@uGib(3G)a90&xJd#f&P;lx%HlCOuI6od<_7xmb$;c=e=w> z2OLRnA0ARetTeYV2B)@wx*c-o9oaKD2tSpgBEArplyYS(sc%~vb^*5VL2fxh7J z*nqZ3vY0K#(yFrxg#}1pRc&<-7H_)mi$IhX z2UEvW3yE;z`?`%8Z98ykZ}!kkHE^uMMH8$9cr{*+IjPrJE~BCeGAkBt8+FSJDmGnX zYg`_(g2%>S!J*L-vy96hef8dEb9)f6OFJKq;k*4l%DJeo(^eo(+0*R~4&ki>R1vel zWR`Ac-aQs1iNHP@I8&GuP=5r8G}x0`~p1i)Hxxv*l=!#=Mca z`kA~g_RB7_n$4Hro^c8V80qOjI{K#*bjOprzE4*ZLhKltNmLLA&mFDnC+!dTfc0hw z-`!IyEe%cIcdmBeD>VL0Nl9@KFj)-m`7w)M`tz@UQ(Oui@?q>^h>DrAihRFbyXKMTd0N_J9?c__o77m0 zBR+tZ16$Fq+h2iH<^%CaKCShuX*w3yB`Kol5!Nxy&R2!kq=FD$NXRu$3`aEKYCvl0 zMGkpzPYkb1Str(}#M*rKMO;#b$|!>e&%?s}RYTviA+>?I&?`QDFU$JYR0A5}WkKC6;=mMU*JY=>US%{Cf z%Wm_<9u=CEW+ z;6z_ZA`VS78%cYjf4+Y}=Z=Nm37BiLt3!>AjGR8e)zg6l*-mX_HJ?gL=~$O?Dwlh@ z5Qm_75v6ms1lGDO$KbOS=5V`=2RHPIbY1E|^4FTXs|BR!zZ(kI%uVM{37Kjx1!k+c z`SBxg*H`HfC|f2K0ajg{1a#Z=p{he|+%bT~H$XG|PHh<>L)P}JwAB1A)9F=y?o<~m zrH%~wo3Z7s;rjaA{ne~%{vV4_$@|NWa(va=9W*S=_Z=uS zgULU`c${X)wT~yhsT>}Tt{GMbv%Qb`GJo?<3KTMmE{0;r2uVJ!h1_%Pc{-j;wHR&& zTyV>Jexcvj_kHDt#geuzM$aN|3LkIH>bpU`vSVk;=EH!_xodm03Y|vIYu%L5ICgfo z!lNu5>dYZ1zR=#GLfqV9=F<<)aAyD-b6k8r>cd(A3)m$=v+(AG*AdQn*Dr$AUEd=-2o)+*$F)ed+W5k2CTK_j=_z zTU}^4I4iK2W?!N{{;PvYoW2J-O{s5ED8I7V9tIHG?Nugc42AFO5Ktvj(yHmPb%0M`TbR4?7k?!v9*~fT%o_Xh*FEbZk z6wcXu?X_3j>yF>w^vUrW^SGi5n2aN?pfzDQo*5O zLmWYn|7l7f(zYCs@HDuaagDm%>c`t~Vn`xc5#U{bW1!!40Kr}x)yQqzb2{A$zF`*e zu8~O30gMy-us-P$mgl6Ug8(0skjbutKFp(A;tAmOVGd)@LnZ&iNEK=IfEv{v)8jej zTs8*=2ale_l6nz`t@pQ?l6m+S0_rLHO$##^mraYEDEc7K&SV2gno^4W14a&16kA){ zsi7R;L>LwZ(D7M$B;k*5PW&)VR^r1?_5#srPzgl|`cL%c=Blb~jS$0*sbD2^GgElv zx0UA~x-P`4CmQukq#kzBk{Ptg%9cUi8jAHCLQ4C`uG;61T;XZUbk5gOh;8TQE@&?D zJ^-gqy#ewj7UP5F_&@{+cdIUuZ*KPG=tgPk`fk#Sz5uLU6W-`Tn;>xi%@fVvUezY9Lz2w0xlrEPsF;U*!4V+zy!4rPDtZaU(DX`6 z&J;yldkT8fwkrxBKPItFUA#gg2%VVt=2YuiBNOo1D4Ep^=wkXj6x{S2DjqFgoRJ|` zC4*LFl$QXBgpRr*#_|pxIIsZvL=8n^FHm(gu}1#*0iH%a&FOx8fi3Oa)Ug4m<8m^x!xi5@3Xq~zi0G3 zL(quSS!j*ZuJrUnj?HLHDxtJlk-~k&s2?EvPWNjWpZyu95Em*LVEVOlaM0wui+|^A z*0$|B$wWB{xsxCP(QqM-WV&drA8r+}kh9U7AIW%uyl(C~teqXkdI*G$lo<6(a7p+b z5!dq#T!Dpt7NFQP64k3hQa^ZRN4dMEYO5Url<>i8AITGQ?d5jVj-(+`+bNSo10eHd z=4(cg>XWUcZaFxIh?-Av&y;Vr#tN3V3c$?l899`60JCREjvCU8jQhz8HzUWNj{|Tv z^4M<&TToLpe%w2s^8)Ek=Nr$qlyt{!GXOw^gfmlV4LbUijd4)59id77$xFHluyN z{eX|X3~O&+nrepxY;<%y>-$cry6Q7scgQaO&JULd^A?v_^{!`Qyo13nAT;t;W7kbh zM}NJIO3verp>1*t_jNzw!#SOM^a~lOW$o!KATz7+z1#V1 z0!hc;X#UJhE;XWn0Bowz1t&j%*0!GU-xIuEo;<|4Qp0IaeQt{72M{|e<@9`{FzOIS zd9{D!*D=UHp$7okN&wVF^NDVWR~$Qb<$xY4w$*&Aa?@+9D6!wQ*Gf=rqt2SqtXHh5 z%O~bUPrj_r_zG_)R2r=h)Rru*PJF0IJ}w*?s6B(G4x}^zuIc3j8nlvyDHDzBwRYk| z(8UIa<>xBMM12yQB?XX5$ma5cc<0Il906Q{#krkTi?iyB&{|)H?-WO-L?7W;xN{R< zT9_?P{^H007gV}JBJF1k8kz)LIVm4hyO!LHwcW>-+tU^Nk`BBm-akd&aojKp=-XYiz!d9Y=+~%Axfbb!)tiDD_eq}kFBw=f7>sqJVR2cYeOJgauJ=E1j zAZW)5Ro^&S4@Q(-X>Fydt2uHx*`0+00`hIy2po-Ikj1_2rwF@?1FwVgbJ6>U`;q`P zJI6K$5gMe`Q7*_wUtdY#l&C9y4|63r_^1%os0)am8vRc+ZlIxYSN2p@nYjIE{n|6v z+V3NLCL2)vszkbdJjzcjZXN(GqC=~9SiMss6cC_R1d8fqWY@oa+WA}YUX66no?@Su zi{K=orNs`6Y|7P>ah(z!`$R5Jc{0yXXckIDsDY)jva+zB2;jW`7?+*s zD34~;czMjmL+By5Z*M!5SN^i_9iG)Y^^YQ$MGark71D)r&QrN8b0>6bPRGEG2L)H=)^}wE7n)nh82Lz+@ENm3%}r>HSo&~{$p!)N^46c><$Q|+PI0fo zr0+YI7Cz?{oMTAZ9<;hcF#?6m0spw30UUw1qR%ZXWfb->4!}N*!n}nUj?LB)KA|wF zJBdk264*qpyYDB|d2IpWdXEaFwJ?%5(5D zBTtp)RP)^bDG_X>26&r|pBkT4A;-X31$DzO-Rp(O*@w!G(}F(oHXDuxcSJ=+eU_y1 z*I{KB7+e?n=4xU_st&|5OUo8jj&{;vx!$RQ1Cf^{7kgNMr3BsbU@3H>k;Q}6^{o^u z5LgSFp`=wv=j$^7@>JBovu47xLws?MWAgyavKa}-dw}2j1z6-}JaQ{eBC)@e@SjFv z`y4E^(nyZ#9{sC!(z_OOLB0|K0reW5Q#^?`P!RN+6dkCRJ$)~jogJ~|U~KH4(Rs9n z$h`n0U~TY{@$CDRKSDtnwcXWK{h}j1Al_7mPI{$HYdw7NMo_U;k>7FCqvv(c#B}2X zh|ykN<7U=S9^l62xlRoI#0Xcvo2BF5etMhZv&RA~S@~Ui;~*J{76)a1Wo2Nei^*T1 z{wL}Spc>He*W}gh-hy)91X570QoY7tcI>J-bvaNHfb5vq+#wRe&dr}7KW5ZIBqV44 zq9!_F*1PfX!sJ}}@zF~&O9SBRwb2p{onh;Pw#-pvZlW)1C z;4xdhKpq+NT40rPcSW=^pTiws$%qvUS^dDR6EyLP83EF8crrS5g_Ffns8hI}R4jSn z?fu~9Vr0Pi&69AW=`jG$*e4$mG$`XC*j+o5{Dkb2A6bYXixlfR;&P zx@XBld~yy!iEVUX^sYS1ykz`J0-R%kWtEPJUSOvBT5_>e_OlUk5^-w!FEr@yQF8ti z;M_|f-=nBSW1c118f}K1%2$BSC_jt;n?l$3``N1}M@QX9HXo@S zpgbFC1(|UGUTlYNee31^2)kMF}_h|u09biztG>oT{yGM~#f2pCl)&b~ReFIDY zcWp5NG}!)8kic)M#KD2hfd@!bk@zSPXkYZ>_oS0QOFIk=4S`Jz@|!C12d^PwAp7zQ zv~@po{C}55r+>6eDSm2(R`C;-`7PZ70DA$=t%y1ppzFrh zFN<=O#WSlcm;z`;B`d&%t16mD=68+S#~Ugwh{Ckf~u(8Qr=~ z5ogI(^_|GL6@sMY`{v8}eDYJBenrh1S^XGSTsd!`Ocjdj#cm;c=-_u{T)^gA&C$S- z>Gdc+5|1?vpi`ov9#v8-(ElPkF=uwkm;&$XU!w#-uKYi+alaYz9ajK%Nvrngmf-@x z%;G-;yZ;Sl{+ZrF#}DhC(x*=0=gUATSPH^^b|&l^$kK~^|8(tK6QH(eP9alL$J6)- zxRhBMd8U4w=A*uIel<-50DrR-UUDxig4mxvVvh#MxZO{0TgrY+W0m9i`BT!#kp4|i z=)hW##}8WFrd?XBBxg1zzN<`V5&7Iq_Dje=;mViofSq}8 zb~cXV|4=R5o41bkH3PZ?_E$MDo z8~{Ke94zd2bh=d+@LOC2MZf_f&SrONvq@Go=ex=R0Rj*ZG_k*B_>FDI8X1V{pI^fG zEKZO=w_{ym5b{^GN62j>5mP?7=7D&zD=S#rAEvlQTv#y7zMnNMuGn~yo7ABI9FLIn&u(FI- zb??9c1|GvJe|={hD)9&j5gQOy9(^v&ji3Mh_~J|hZS?ycQRCbWQO|yHZ_DNiL!y$x z_o>v>Py4}TR?;Oz*@Vj?}h=$@tBs}KX6Y65O-|~bxH|-h~ofJ ztTm#h&4UmCVx%wcrG{;2EN1}bQvhSST;(_LZf(sU6rGgjtDzHA_3YST8lC`vFT73- zA203bP!>%oZZ**+%)o(O4=0pu<|$H1RMoiE~7T zC4KuzzA&6F{;)C@zI4cJ1qk|`V8q=5DAp;CL~MI(*43GKLGmaNOdc+eiwboM0oLa_ z%=j48%j$NJcfy+o#}E56yS#5?{Jgi@YMI8_ z33)hrbSwMCV84_xyIoO#2&DgG5fg_u9=N_(@dyTU_OU7mgu=J*L?!eEROAfwjsak&jN_aO~c8M?TfkVqmJTky%YhOf=3KVH76WE~~GKX7g6kTYww^u6Q z)2#+T;sF~*wLS5Zp81$3C2&TsyoBCtLGZql`SHZN1Y?;BA4DTU@=ho{L?#5QdFn(G zI-lC^0Z*C`zqFLu4|?svcZNn%~JR6-p3rOume{JO+!r_D*U5^+B(h)CW+m{{8||sJ)xyrebLO zZ9TDc2T1(g4!BdwKJy{cZ$(Tf$=kk`3~sxBg0+)^a+61SggyFg4a(u2E|#`S#v92% zW9fWj*>+>59P$NhKu_%i1NScWPKk#M*+CDMW*twS%AV%eKDi(R^7?*u7*JUPVdv8d z$L=4Ma_kl{f(HnUU0f#9r61z$l7yQTLQo=#R1@yRRaKC{SPxmO4La6v*<^6TdzVGt zhC`qDoemDhR%qE)S;zAT)k!NTf;E*zUteF)j)IB`9#6EOg{732o#Of_`H^%Q21$W+ z4UU{c^lNkxS1nj5_MP+|LwVrV-{0%i!p__f&vB1I+P!6s?eZOVOoWGb9LF@Ea!_gb zEjXa;7O-K*qUXd&?1NX8Vi7UK@IevELf#C?I`onNz? z!gt>KKb2(@XXM<;g%etV)n&(?Es|V zv{c0S7xiKY#)6WNV)D(u7)1E#vX`w{7I7v0eYQv_vaQK)IU3v z5*nI#Td`K4PxcdbO4p~ncDSz@n8Yj&Y+A2oe5y_erTV{xqekRD@7Do5{|vsUlsKOQ!jdejDqkV~IzOpEQc>u!0;k%#kq5<_ z+faDXVG(BtHaS`_8k?8cHa>q@=YXIU0TimSKaC0AqF^f{1dblwv2Wg_s2C_Hdh_lI zoWQ57pHrO9pi^beg|=>-qvkZpw32EC9z*&>dhfpc2)2E5j+u7n@<3sqb4Jm__Ue-m zep-nRs9F!pq$jXfqjCQ!(Ut{9% z%1-Zu~T$L6$3BoE~ z+;BPVXQ3ovVg}2i<@iGmZzVLR{u2{tOZ6d+hcu3@1{X%SgjXTz_qR%Tm z-A|#BuBzEYhWBq5amgbWWWp&gI_Y=R)BD|}GA3Jqy*@K}M)et|D0e_YJr06N#|G?f zfEWQyIGFMvP~hp)2X(^h?#Ok980ZBdjlo1{qT;eokMwfI(M7O9&k1?a*y8b@<}XRL z9^}s#AS}73kUu`f%+#A@)lrqSlTgbghkv7jG|cYt!4hQLY|}ljL6jIxL-xYOl-GzK zhsJn|6-1I~rp%GVEVdq>q)CFj^{yB-p^cYK!_lJkJ(KJ=avYPK@VGJB>^xwx7<52J zA9pY!(NrIwdhPyF1_-q`ru>|Un`DS^dAKXI@M+P11XIvsLi>_)TOk%Ku#jZ!-TAA{eQ@8l4H`w|mp)oyaF88YZvWW<+owa;g@C z0S>b{ob_906L`tdA@18W`zHP+<|K-JVF_dFTuJm7@A5vnDtGz^+XhFvqm*E&VBzqN z*x1_$*^%~(_jAv{-Xw4#4hfHx>&vYWQ@ZCz^l-}cNb@G+9~;jxLWzNdvUG4J$QT$8 zB?VgB+W}S7GB6lS`mw7SVrmaV6Y@Mh>Xi>(0+`2e&=m z5fLHfA(?8ZJ_Z2XaNIpvJ7;{Py}URL^_wW6ESD~uM5n$NgPE4%fYRxn{@z(1iPgTR z+4`qA>|2fu&r)4WTR{BmbI*I3>IR`4e~@HmByl>KgX)*MUDcU)iD!p-Rd$-g)hX@( zKie-r`Pubk_g#FZk(*ZSOh@9)u*Nlge3`(?RW%_*XKA{g;k2AcGXg%ZPw`9I)w{x; zOH1u@G%MNr&LJJg{W!<#A51Tc;3I_eU9~*(bp&KB)!F~1Rr>$UCw~f5f_WD{$My3s z%%#fsbCmkWISa+fu2U|QVgueflT-!xzj(EOuHjQk`;?k56i9j_7FRyPg8h4%{&Tes zoG9Yi1mFWR6=r#_|L5PYk)=?`U%mp)G)k{>^N9a*bLf9w=)o>g!V5sJAW*THxAfmD zG~ysjr2{8Vo5z54Y?F|H$@@>!V18bTA3KWgXFLGqDIm%K+ZbH=r(wVDWFrnsQ3m~0 zqZ%OD)~u!_v-0O$1>79Cummhc?60rj#sX~!MOOGPQ8(@(4E=9+$V>qAG4rVN{^eA_ zq(g&^`SkmqfEXsw2xVA?secQu@xW7k_|qr=ri+NIXlC~1&sSi`qsU+m|LUQ1hXD8J zMy|tUfVK|WZVqIr!hg=*z{jDv(VE0SmEZ5b3j%-tSEnrG0$shBi$?kScbLQ+8}rM* zzW)>|rt{llXIWwyOno`^;7b&pw6rv9YF|KWG0Vm;+U|E2CGrw#2vn|$>c+xbRSI`e z9f_F8cP38X=eg6_m4u|E+vufwzcs?wuktVeON1g*zE8t|YEk_uVJfVDrhF1g_=?%h zznpOJ@bI{wv(6BuJkPLup3F~7;M2q|BNqApl%@iil2cE{-pD){ka~85ibQ?!2!h?n z5yKal89fvLS#g39V^arQbO5a+{#ct0Z&ieS(;EK;u08clDDs{N`{K_JG=q~Cn5pbJ zK|f`YfBM#bre@6tWT^DU10_Il%58G#+?qcr8tO+qJ(Hwli>4Tbb+&>rnQ&-v%`9Mr zspaJzsOS{KI=9<*CTktj2~aePb?VeI<;~8=c0l; z1;%{&GxGm+dEikNRN?8u38&Pual3kWRaVpC29Bi8(UI z2PxZm+J8aBG5q;3R$`5@1CUpJ8*!;XN5s5QlJUX+tXA+!9MH$h&dvs;9-jW3*epPT z)-i#8wVjDauewaNI>Pan56UtVYW>zxnZFtphvRd^d!L|UqWet)2)ZcwxwyII=+(PI zGc_?lHw$7hA#}eUe*x*|#RiN7BQGO5NAQjebTy%%S{>mx(MrEwfll}f@};Ah7JJMA zaRFL9Y&GBRB^vw=~{Ax!P0SxJgi^V!y zMu#iuar{v@7WOv=sFVqeW|hWqNY$@40KnFQoujlCdyD~L0sOvZFWo#3xgv_s zwLO4J0~pLwRI~ML2FS`qLPu}!j%R42TiioqIR#!)BPG(o>)?*}&~9BX$>?y;o4NOu zqUVLU_{Ydn1N};82^-_ZhU9#7SxHdUO&#(@M{+ZfIYr^qb zUrUX{_IE?y*pijhmjb_rSK}tqK~mo%a?%zT#&w~{U4eG{NxH~O1={!Y$gMwhNuc6o zQD{$WA#tGz7C*n#M)kByC;q_zy+Gvwaf?0Lxy#-nZ}2)rMyyV`)gE0X0DkpVaB;e+Yv=?@MMv1n1n9zuU~UOaT}T`Nfin;vNN8}UW%-gE~l z@7;fu*yE@KhG?vPl}-y!EP60wcI4hyIJ>((4@Ad34;+wBOjOhYD?I=}`bY(7Z50z# z_T49(0PB<8UY~b-(=01~-G(9vhMyO$7?aNwB9TpCEaBG`zLfQ3kZo1IK!*5Uz4E-v zW+^IU5qNVv*=NKPxhjx9^5Uav0-JA#8?e@OUlv~QF?IMYl`S8RAz$FR-ab8&zE)PW zbjW52*bYncvY(3tWa0w>aX=kV^Z>o%;W-s#smw^`5hxG0uC5LMF@b5Ta=na=sdgOH zb!-vdjej$9s`2fPzS*&cGf!w%ywKbhRhkCc0A>+z9Kmcd;*H#tF?m91a6`~Ogx#Jm zdRG(!7>WJXc0w#iHMuJtkhBhrE*9Fz?0!&nOF-s9Pa#ggF27&HK^on<{sx&Q&oR&( zXy_wtQuJtKS8qq$3J{W*6|$hz>;17kiN#CYGxr{$E%B!AB;dWUd*~6qXET_Nqy!z` z!`8!Nu_RUDOIRS1&c&+Goc;mxS@+nHicHsKpYwsi?E0f=$E#&wn_|!SZ^e9*I5ejY zx6As5yG*+byV^;fE9eXn4F@x_pW@O0Wc*bl{N>+#0$`?9;lg0O`m?I?Lm@8w-?K-B z|NI7%P98SquZ{5%1!~x!yrh=>XMM|}f~Wdd-4Zf%J4P;KbogU-yd;46_p|1_6}9GV$rm=i4ZbCsB&c{==G!2q9Z zD90HPM*jji)7irVn6%u*MY6$09uE4 z&?s?!@=W&jKTrQ_U&;E-eQunk{@*&_cgJ9MLUlV_qN-|wI$8e5<)ORYCA0~-mQ;TO z88H8Oj#}iZG~wnwLYcpjmEVu|s|mm&mjvuDK)S-qCZ zbG@16A$qNof97nb9Tlc0ugzpVU^7T0Q2HG7__XYiEShqc5+nQTqZ2#sBY|px@}8$R zb_>OB9eo#gnqHC<6S$vQWe7RXhhTK$7ZZX_gP{(@-EGB~RwLJnd z3v-VmX>X3!Ul)K6%Hmb;4*m7-bSzHsJS$?lK^X@%ELFFSBNFYQalDvfWB z5|+#^lK~Y@19slMKC~_tu=0NlnmDL}qdXE8A` zL{O-CfKK8-pXK0YS**G~1H(XpThpUWkZMF%x| zLZkfuJ2;_lAT85diVj{U0vJMR-@Dj30OgUz;hxSXz=2rXmMZgM|D9!(=u-dV*2V=< zg$nj~=RY^mNq+#QUbzx4`hZf$^=u=h%j7n%(9+7hn%VKR#qCQMAS9_Qs(lj#IXr^f|`h!IqP*H_e#Pr13;%)v6iXw# zbo1Nfl6tf5i;KGdxp-YTQ+v=-9<$5W?C$l?!AYNE5|^cUqwuR;l+*Ky zel>JK6F#)Ylg^S*JbvJqb)X}UDX4apPa9Y0bY zQ7&KRx+Q4mF?kk;OY?i?HXb8Meb{~4XpW z;3t40`P6knGzWUyPUtz<-X9?CR>^|`+0d60Ow{&CrU=x_)p>QwgvN#}#YB5Ggs@GG z6nN#*%vexIRxNIp)Ph#&pZs1<%WyC+0eb{2?QGd>j;mL2kkY1Er2j4X?)yHGoR$ER zZqV}=u^I7$3v-z7-FNsv017jFBA zRBT#UefzB8K4kjfkb7G;kI{|8<9K!*CXqzoYJ|$UQNqd@8(Q~zk0!X=EqU2N*B2x^ zcOGu^iF$lfnLPHmJ>!CY-%mz|>0j9Wl= zj4S!K0p}1MzroPOjUg*c*jqnLEUh;BXP0N|4CTbNp4aGJq;sDtN$L&eti2M{B65xs zZUCkoyc_~TFyt7U$B~hcXwDPo++japI%QrdH|v+=pE!+;fq$21M#opp`<5+UeZ!vZ zpz_+NToWyv@xKN$Hk_gS8q2IXQ9-b^vUzoL+xtAO%*3~=nSAanwV7+Ui zunc#c4@I@JSmH9I3L*>Fv#D5#n0};AXsy~|o{j!N_)GCmGB<2 zN_D!mj@f3h+PeuGp~A&Abc}eR~09j$X+OZ~ABTG4@(HSR!7WE6Lla zR2tOlmA*lV$P|j9qzEdW9k0wMt?BY6s#P1^Ke8iiMKBJ1~0FgMyr2m@4)!pE)Je zxJ#~gi8#x1I<0C5u-++n=)Qu;KHYP@APi5xe{jcthM%)ylWLEKU2tw^V#WakM+Qa zXF^*S$57S|hR~GqL|#kI#OtHu$i)f2OGtzL`NCC|=|vykWs}#r`K&>@Gn&heYTOyi zJK>fVNqxwd5612YHDgTarv;+=?&nqw()1h--gayFK8W0bD%?zqBME5YwUS%D9t(+Z zAmfS5Lpvh+9TNk3(Q%Qir?C0Hu&wjF$Z3(hk@o8Y9~IIW$`ItFrD1~D*VYN%ggCe1 zIlR|eGdyGfm#j`U`s91fO9{w0*9}q>g?!<^^3f`ivXSNGHCpvOeYm?pjibEv+b_4qLHur;Zyi5sHYj&{=o`%$i>mOQp3h#J2EdPPfTq`91%^8}M-y zQ6n$Pku2mg=-hT7IB@b{Q}%$}rD>k~!8~E9oR=++o|`om4bcQE4n7(@?bJ85axU!H zrNh~x`^6?&Z8Jz|=dss3BxqvJ0my1ZjgJXPP$JqBG3Gj4^BGd zevHsVup^q5laWy$BnxtW?K!^b{6W&FrwReXS8=Ddd^3{fRC@vZ8E)g$nM1H_QreFlOr3W+1$XfacHw&h;NSn-hRfMC~>?ByPi+r>+$N_H{-KQJQSi2 z3Bs1xS!25Ok#MDeO%5U3w%RohnupH zMK3UM>s7$?No}@DP<_^VH36hJlS`GAMA1sr4TPp=Y;zw?y4>VZlh0j|oybETCI5o! z*D+v$0;Z=tXjRLfyiUS4e;dE&a~}gsJ^EZVY0}HN=9x#<{SPu3fs*LyA8*}@Ex6}& zOW{Bb4upc!pw}}}WUVT)q+Q%$7?s~z(m(7Yu76q(z?&}$X+Bx(anKPe^tvvKcYf1~ zLek*5=yc&Z%l5vi{u8>_YB~b6ifu!Hzj7xGLw_dB;TVDdE^kLq3UkVw4`B`jk+Ih| zY*x=uYZ%YmGiI$x0-HZScC=nu6gq;7GI9nuOMG13Uu z5SXu74RQBgen`08*ye5m;7Ikf=6g6~y1AEZeUU^8K8T@@rq*j~3NGufT=xRaOHr}= ztls6E)1UWEyzv-Xy4a+=Vz3p`6LNOB>bU5CYc#%`I(Bckdt?2QIveqEQA+TQgi#uw z6S3&0`JB~z!&_usuzdTenQ)Gv-6Jy>-4^A@?V>tO{aQ~`f;{KGG=5Lpvuh`kfa@P< z!_o|rst>oVY~6V}y<=FRMMluo=O?I}XRk~=Mql`|<#A+0gv1g;j;JR+ENodue+O-= z=|j+{b=2JsEhs&Hy4-x4jUOaSC`&r^B(6z9;tgVU#Qg`w29KWNU?&NSW|xy{Hza1T zgS_KrrsZ@nusy*ujYgiPAjQ_aWyvXb>>kYH+xrojVD_kfu0(6bB8`)WvNRswxp`SQ z!Skl(;l$$(CCnL8egpKP&uWROQxS?1d+Z7?P5U$93-703sArU~}b3m(}szb|HH8WT=XXU^lXh8oqS;#?BZJjR8c1=dF`AZ8wKUC z@UZ87GSsQbQ3@jF<*eCrMBNg4bzR7?V4q9u!|yrh?vEh3{d&}Lo&I_l(mHb_$xiG|$3-_DF5(ca|3`HxCh2UmU0IcW;{Q z%#PG#dfxij>&R(y;Xb^dwZ7mx8vyIDc2xA$*v5C1Lkfe=uFuv78nGa*9q)wUV#kX5 zQi+%eh-)fbpGu}EIGq9Hw8{)^e~eo@_=I5v=_hewjEejju38@Q!otF=$;?6_%ps+$ zg)5RMZB9VoSG+>f4-xI~_H5tcSt}m|zz&kinX8CA6t6i<(LQl=5h&5os*mV*umKKQ z#XU&%mh}s@zB6FGOXZ>?hXfprldk(C|DYh%?q$iy?!~dww~sQuyEMIkvbl}VPCxjlRGHpjb^3If|WxxsW}0k8Igb5Z>P0a1MbAhLxLOml@w?V(c1sw4t*UmERH1oXv2V zvh%n+sFJB4J0aSz!g*DLpKsuzRl}y)wqLsmncsSY5MIb;$uYv$epk%@4O`zT8cS^A zS!qLZ1m9WZ8Kq?25rk`5{l|N%0t7INdfyewwx1q z-_&Vn)-i)TB_TA|ASD;tF_olJ?RQFS;vx`sumB%R=6)I&aSB-M3siBB&o5@?Tvr~V z@m1@)4I#@IDk&pUV|5L6Fm!>b3SoFsGM5>#s0$KvEBsy*@M}{(+XA^?O?7a6dJUC) zPQ~GUy0k(*;75yGlbG+3OH1H-Sy;_uO9K`MjYSOLA7*803-rW(n7K>v$T(q)rNvWA zphlaxj2HKU8sWbkZM%RC-fWJg7dx2}`tv{|uQKDTKGvW|D`>YwR$t*@IPg5cNyuL1 z;_|VO@|4}NRe?bGdZ&P5CjUoT%N76S zCxNu>?9SBgI$!GHuzPiJvpQem-0Ug{X-@=M499vp66%n7N#0t8yxMV)(Xxv+1MnPbclO0>o+>a_!?Me@o+`&I*QMx>&G&Sdg+t`yEEJeZdUE<#R;!LOFQfVz0;hmB&|~ zgDcJwEdRPl2>x{8!H?X}j08c@ZVU_6A3n(E{yvJKa3^rXa52WBeZ1@+7_L2e`UuQT zKnvN%zv3@TEpeyfLGh0zw#)AHITwOysA&Z2k5*Hy6YEfak?i}b3AQEXCyC!T$LO85 z^XuQ8VQysgv?*02q;AkWCcByugio8!&gv4g|HNVec{SGKP@G3{8ZqWeiHFVX{xJZY zpn-trHo~5~3Y@-|1{67tt2|O;P6|4-J+F`$=apY7QO+x-3tEM|o2U^Wn551UbJT>T zNsOOqL9hlifZo^CKGM@I#|GEmg#!Dp-R;Gbmr!2}yZo!TBkiLeTuwRnvSpmQdlQ8M z*JDJ>a)V6E+0PTz`0kRi`v^yy&D3LMdiTWtDH1Pp`~iy-$nu1#7SLf53=h)HmxPNpQ=Ya8U#{N=1t5`-OpOzuh^= zZu1OYf_cl#6Zg_nrrkDkoqDBa1V~0nUzO)-%Xga7{a$Wvy+}v1(+3xPNBsIaH}G$b zHPlG%b$ZR}`|Bs~)yLB;t8Z`JnRVv#saDa4uTA=1;6Hm52_3biZ`YKc|ByB$GW0c-Kpy_#{P2H{+xI~qrr+0jK1OB>L{g z)P|ElJX67k!QgjkVS*oO)Mt|TLuRk*_eo(1A6%$~&E%MB^cUdE3Z4Z&YeY`QA4|0x4Dt&KLK}USq=!9i9mVZyFve#ax-fjpz($7VIIBeNt zIfYM-JkN|zZ+Be=d_9Ld+p&Z18u60Onpshk-sA5P&8lYRzE#~AE(JThf8S7sapg#g z*iSfPbi$NW_4eswLfS?{j=i>G)4j3G)Rgnq?c!czOX->NQ$N>OJ3)veVSDd3oF|I3 zTle4BM;G$|EbsiG*&I)=jHl=H5ybIu&9`tt{h4z*yW<^PRka)44?$&h#b=$!IK0Wr zemGjIpO>qAjt8^!I4m2h_7An$Zrc`6bB6^iL-P>h2Vz$0g|`p2hRxv*FAf6*ibOS zAvo@=ZRV9T0f#WyfT~sEOhTcXgg(FBQ3tcA^{`UV%zd0*qH)ui8*q-YAq@zksX)*i z92C3V;MhYa26@2yxyg%c=j+NShb#0aCY(Cx=y>N3phbR4+RnVtVRYjSH0{8Vf}+to9`REFfy&(XtjG? z)o1)86ZTssVeFf_T;H~>wu;?(`WU3Bn|c;8jZPsmTL5PC(q@xv@y_NqB{Xx8PQIj; zO$?fbzPzySfk6Nd^W*!@i=WKnv%xZvc>SE1bMwlQK;ekW}xa@yBhCs zRky;#D-2)mWi?83!`1dnjgu>tgR`UdY})zO?}jYClptcY#71uvXQR1^jS(}tcdrW3 z^xzuq?(DCA?9Wp358f8}xP&f=ej?pPTx^_oJD5r7(rVxLngX=!zJ%e^K!N~Ec_22Q zhjis&@sV3oDbKUl<>V9nx6>zRcjg?B#tl!7&{)e1&iR`YABlZKGagxsBnH*Zbp`=&i%sdU>aS#Nyk>~&Ly z@4iuS86>|zXChly`r3eAaa=*R@gua*^&<~8$0Hx7jB9Dd2GN4TwgFcXLSmoYZN)7f zr{|CfJ|uUqgGJKiVynB#$x{W?25l!)0c5l)r|^o$>%kT~a!*QeK~|ktt;(s|`%Mpf z9Jk%Q=A21W6K;KlXFCW>Q10wo5hdS1oz*)oAmM@Go931C(~)prW!u-ZVK-@S-!A2Z zp@crW`)i|xVF7NSF@19lHXv4YHVm^f8yCDkE@8C1M8;-6+U-uJVN=C#y>_9-);?Q( zNG#-Th;i}t8QSA&EE`w}JyG0~L4WQWRO_KCqrF_$Ov5^>A%6VFdC|0GdsBBKKdFA=V#tkM~fU3)+E7(*aK?5K=EysbSCZp+=qEH#0GVi(E;305A>p2`Amf z;$1&?YS+H({d6^w3`8+LHMDQrpJPglMPQU&c!%gu8R pFWjD*^uI5ykHGCBimum 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

7_PeZRl$DQXDx9>1wMDdBER_B9hnNLx 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 Ua^b{V@QHwhskKR^@u~3t0}Seec>n+a literal 0 HcmV?d00001 diff --git a/Diagrams/File_Structure.png b/Diagrams/File_Structure.png deleted file mode 100644 index 166df00c2742afbbab6b2376a0d48143e3fb438d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 233641 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

uLR8_o65m9toKLQ5`Y(ipT{XE{JCxoV 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

%IU@p@P9ah#{_<9;}wpswx$egqo=9!EcA zQr@>Na&d6s)XIHq`!zL1HtDr!>hk=4R72hVgjMu|!s`7ALLKh}ayo)wj@{j`iGDnhCpKF%3#IU>&2ZBSJ&NTMiBn8;9i>N*r8U=ORVu7<=EDguUV!(bi+ z**$P>b83$&Jf{31X@&Iez*8`ocXrY&NMfGGWSc|_-0i`m!SF5@muhZ5n>My<3~2uM zTIE3D6VlUYA4QVTmct>ioQc|>0OBR=B7wD^WD_~_U4#}SplkqH{R<0~ZQ^w$>F2U> zZ=2DvDV*<^#rQ1AIa#e&!Z#5gFPNO8{>V5aEZhbhrM41n?ofr}5p<=n8eDPO=u7<7 zKVG+ej39H_UmLHn+?-if%%TY)aWcvZ%IsT3zxFZM(%S5Br=7Z)1eiRqKFiGYv$$KR0gjg8;W%DUY2Vvf z?o*Cy*r>&a^!Lvn+kyG$_)C=-hpqTzWYTCrNrfsDa{mWULyi2dA3q$T8R|eGdDFF4 zw@^d$%sredp_BDDW>2CP4Q$S5-rmO^yYEb&ynHz~U|c3~Kk8RRM6N(`VK`1e6Dv_@ z80)xzz?<_^VHano>jx)~>A&CvH-9T0#Yfe#3}GrRFW3-KS4V6@-b4Z#wsEpD(gGR^ z!Y%O-kG>~qy#j#*&_{m@d9Mw<%C+$@?A$q1zwQ;U>Le|lx}YL$^{^dh!-no+8uZjI za2@geUNhE`#IKGN!C!}*n5vP|o|Jp@5I9;^8lGM4NKKaIh3 z=nTAv`s>2P?73a%o{4FUKp!Y|Z~cdmP3e zSmw1G0)4rf&1XMFAlG|0Hzx2lC_v7bC)3AjSg{a+f61|92~<&@C_ zMq>v{DXCNkv=$NZ?ZXpyt?~<0K;x`!JQC}u_XT!DWQdWK>YY<{GOi0Akl>x9ny(R? zlCrVB-f8Jp0hXZLTf+Q*8c{*+J9AVCEL@<*e{gn;0D8FnkMeAIom`4z>lQ9V1D;-9 z%TN;Sbv7y)21%r|Q_vn+Am!33Nd3_P%u9&4BJJ!3leo{Pz6MK6gM#=Ef`=Po6nz7#kx3QatA(#Ru|O6FNs54$@u3TPG)dHuBWNYH-F}CgbHZMn*;p z2V{@B2X!qeM8keP1e$D#ZAm0x#fKRzGnmDut=_9A2 z(gNnTEiF-+OmVAVb}N=$SO{i+C$O1;l0skX1TMIQ!FCAsRKQe_QGxS7Zca{H?qf8f zyc>;*Ku~aRM4eay1c1Qf33kW=$D9KNLC!N|XNPWi`TTG$dSdzGxwvu488!2&PW-Ie8pgjhnRh)8)b>Y=10o%C{Pb(xH;fgq*Dg1J7P)2z1~ zN6^&N5@MS9`>|nfLvLVXz?%0tUdoUaI%7L&7`!U2v(5r-ijz~s;GyHiN5`UdQDRL2zuKe>T08*IErH_gk(L@p z2S`C$&;nb&lBHMgEez;61qLGJ142rNEy3mm+H7+JH*f;Mq4)c=EdX6$>5+~fpV&Yu z#s!*@M`acz02bzRph@fm^RL~|&|_@!H5ahgJRh^<6sokJUphGW`1(q2e~v;fW>C-_ z!ZKc6<=x<8gpXtA`+3PYG5>(p=I_8Z3sv#>_}O$-oPvzsvr<;CM4`%~JLOm~==TA<+F*>UI= z*q)1?jgAug-V$}W?VuZEO9#0uE4SXOq2>`QwAiFJ+`RWM7T|2rr&mF-lR#1#_*j|L zs~>Y~jyD6ygD6;E={zu`6Fl8-ICt4zSoQo1VnPIi?AfD0x~u!yD0>?LMiJIT;y#^+81H-CTq+6Prs`Q{Zi?Ods2& z$_L*F^me@qr`TdZ3azk^nfNXylzHMGqVbElx*mY}gqlpP33lTf3Za7bA3qqt#0uWE zO0Lrsoz1)~+y8|62^>CxePyoL6{m7@Gt%5|9+I2N`Oiu@(J>&H_Vx#NlH{N@ zRtDG}ukIeTv_J;R95t%BSNxny;_l4|4q_Qlzuee1b#ZZ-HR5*8*Ts0F51zP&AnJ_X zns8|cO7CsQoP7}RAcybjMd7-lz_H-P->8QmG$j*bU|&Qb_q2$v{(p46Wmr{f*9M9ODkuihp@5Roohk^@(%q#rNVfqfDJ`vZ2na|n z8tE

Define all path variables

@@ -40,9 +40,8 @@ public class Pedro_Paths { public PathChain nearStart_to_nearPreload, nearStart_to_midPreload, nearStart_to_farPreload; public PathChain farStart_to_nearPreload, farStart_to_midPreload, farStart_to_farPreload; // Start Poses to Shooting Poses - public PathChain nearStart_to_midShoot; - //public PathChain nearStart_to_nearShoot, nearStart_to_midShoot, nearStart_to_farShoot; - //public PathChain farStart_to_nearShoot, farStart_to_midShoot, farStart_to_farShoot; + public PathChain nearStart_to_midShoot, nearStart_to_nearShoot; + public PathChain farStart_to_midShoot, farStart_to_farShoot; // Preloads to Shooting Positions public PathChain nearPreload_to_nearShoot, nearPreload_to_midShoot, nearPreload_to_farShoot; public PathChain midPreload_to_nearShoot, midPreload_to_midShoot, midPreload_to_farShoot; @@ -180,6 +179,13 @@ public void buildStart2ToPreloads(){ .build(); } public void buildStart1ToShootings(){ + nearStart_to_nearShoot = follower.pathBuilder() + .addPath(new BezierLine( + nearStart, + nearShoot + )) + .setLinearHeadingInterpolation(nearStart.getHeading(), nearShoot.getHeading()) + .build(); nearStart_to_midShoot = follower.pathBuilder() .addPath(new BezierLine( nearStart, @@ -188,6 +194,22 @@ public void buildStart1ToShootings(){ .setLinearHeadingInterpolation(nearStart.getHeading(), midShoot.getHeading()) .build(); } + public void buildStart2ToShootings(){ + farStart_to_midShoot = follower.pathBuilder() + .addPath(new BezierLine( + farStart, + midShoot + )) + .setLinearHeadingInterpolation(farStart.getHeading(), midShoot.getHeading()) + .build(); + farStart_to_farShoot = follower.pathBuilder() + .addPath(new BezierLine( + farStart, + farShoot + )) + .setLinearHeadingInterpolation(farStart.getHeading(), farShoot.getHeading()) + .build(); + } public void buildPreload1ToShootings(){ nearPreload_to_nearShoot = follower.pathBuilder() .addPath(new BezierLine( @@ -517,6 +539,7 @@ public void buildPaths(LoadHardwareClass.Alliance Alliance, Follower follow){ buildStart2ToPreloads(); // Paths going from each start position to each of the shooting positions. buildStart1ToShootings(); + buildStart2ToShootings(); // Paths going from each preload to each shooting position buildPreload1ToShootings(); buildPreload2ToShootings(); diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Teleop_/Teleop_Main_.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Teleop_/Teleop_Main_.java index 7f80337d4b8f..2c6b029bcf85 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Teleop_/Teleop_Main_.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Teleop_/Teleop_Main_.java @@ -64,13 +64,12 @@ public class Teleop_Main_ extends LinearOpMode { private final ElapsedTime runtime = new ElapsedTime(); private final TelemetryManager panelsTelemetry = PanelsTelemetry.INSTANCE.getTelemetry(); - // Variables for storing data for the second gamepad controls - public static double DylanStickDeadzones = 0.2; - public int shootingState = 0; public boolean turretOn = true; public TimerEx stateTimer = new TimerEx(1); public double hoodOffset = 0; + public Pose holdPoint = new Pose(72, 72, 90); + public Boolean holdJustTriggered = false; // Create a new instance of our Robot class LoadHardwareClass Robot = new LoadHardwareClass(this); @@ -176,6 +175,7 @@ public void runOpMode() { telemetry.addData("Turret Target Angle", Robot.turret.rotation.target); telemetry.addData("Turret Actual Angle", Robot.turret.rotation.getAngleAbsolute()); telemetry.addData("Turret Hood Angle", Robot.turret.getHood()); + telemetry.addData("Turret Offset", hoodOffset); telemetry.addLine(); panelsTelemetry.addData("Flywheel Target Speed", Robot.turret.flywheel.target); @@ -245,21 +245,39 @@ public void runOpMode() { */ public void Gamepad1() { - if (gamepad1.left_trigger >= 0.5 && gamepad1.right_trigger >= 0.5) { - Robot.drivetrain.speedMultiplier = 0.66; - } else if (gamepad1.left_trigger >= 0.5) { + double ariDeadZone = 0.3; + + if (gamepad1.left_trigger >= ariDeadZone && gamepad1.right_trigger >= ariDeadZone) { + if (!holdJustTriggered){ + holdPoint = Robot.drivetrain.follower.getPose(); + holdJustTriggered = true; + } + Robot.drivetrain.follower.holdPoint(holdPoint); + } else if (gamepad1.left_trigger >= ariDeadZone) { + if (holdJustTriggered){ + Robot.drivetrain.follower.startTeleOpDrive(); + holdJustTriggered = false; + } Robot.drivetrain.speedMultiplier = 0.33; - } else if (gamepad1.right_trigger >= 0.5) { + } else if (gamepad1.right_trigger >= ariDeadZone) { + if (holdJustTriggered){ + Robot.drivetrain.follower.startTeleOpDrive(); + holdJustTriggered = false; + } Robot.drivetrain.speedMultiplier = 1; } else { + if (holdJustTriggered){ + Robot.drivetrain.follower.startTeleOpDrive(); + holdJustTriggered = false; + } Robot.drivetrain.speedMultiplier = 0.66; } if (gamepad1.bWasPressed()){ if (selectedAlliance == LoadHardwareClass.Alliance.RED){ - Robot.drivetrain.follower.setPose(new Pose(8, 8, Math.toRadians(90))); + Robot.drivetrain.follower.setPose(new Pose(7, 7, Math.toRadians(90))); }else if (selectedAlliance == LoadHardwareClass.Alliance.BLUE){ - Robot.drivetrain.follower.setPose(new Pose(136, 8, Math.toRadians(90))); + Robot.drivetrain.follower.setPose(new Pose(137, 7, Math.toRadians(90))); } } @@ -326,16 +344,18 @@ public void Gamepad2() { } Robot.turret.updateAimbot(turretOn, true, hoodOffset); + double dylanStickDeadzones = 0.2; + //Intake Controls (Left Stick Y) if (shootingState == 0) { - if (Math.abs(gamepad2.left_stick_y) >= DylanStickDeadzones && - Math.abs(gamepad2.right_stick_y) >= DylanStickDeadzones) { + if (Math.abs(gamepad2.left_stick_y) >= dylanStickDeadzones && + Math.abs(gamepad2.right_stick_y) >= dylanStickDeadzones) { Robot.intake.setMode(intakeMode.INTAKING); - }else if (Math.abs(gamepad2.left_stick_y) >= DylanStickDeadzones && - Math.abs(gamepad2.right_stick_y) < DylanStickDeadzones) { + }else if (Math.abs(gamepad2.left_stick_y) >= dylanStickDeadzones && + Math.abs(gamepad2.right_stick_y) < dylanStickDeadzones) { Robot.intake.setMode(intakeMode.NO_BELT); - }else if (Math.abs(gamepad2.left_stick_y) < DylanStickDeadzones && - Math.abs(gamepad2.right_stick_y) >= DylanStickDeadzones) { + }else if (Math.abs(gamepad2.left_stick_y) < dylanStickDeadzones && + Math.abs(gamepad2.right_stick_y) >= dylanStickDeadzones) { Robot.intake.setMode(intakeMode.SHOOTING); }else if (gamepad2.back){ Robot.intake.setMode(intakeMode.REVERSING); @@ -344,7 +364,7 @@ public void Gamepad2() { } /* TODO Uncomment once autobelt control is finished - if (Math.abs(gamepad2.left_stick_y) >= DylanStickDeadzones) { + if (Math.abs(gamepad2.left_stick_y) >= dylanStickDeadzones) { Robot.intake.setMode(intakeMode.INTAKING); }else{ // OFF Robot.intake.setMode(intakeMode.OFF); diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/pedroPathing/Constants.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/pedroPathing/Constants.java index d4338b8b7e58..6677fe460c4c 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/pedroPathing/Constants.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/pedroPathing/Constants.java @@ -17,16 +17,16 @@ public class Constants { public static FollowerConstants followerConstants = new FollowerConstants() .mass(13.6) // TODO: Change this to the actual weight of the robot - .forwardZeroPowerAcceleration(-42.5878) - .lateralZeroPowerAcceleration(-68.2022) + .forwardZeroPowerAcceleration(-31.6509) + .lateralZeroPowerAcceleration(-69.7608) // Set following parameters to true to enable dual PID .useSecondaryTranslationalPIDF(false) .useSecondaryHeadingPIDF(false) .useSecondaryDrivePIDF(false) .centripetalScaling(0.0002) - .translationalPIDFCoefficients(new PIDFCoefficients(0.15, 0, 0.01, 0.05)) - .headingPIDFCoefficients(new PIDFCoefficients(2, 0, 0.1, 0.026)) - .drivePIDFCoefficients(new FilteredPIDFCoefficients(0.02, 0, 0.001, 0.6, 0.02)); + .translationalPIDFCoefficients(new PIDFCoefficients(0.2, 0.000003, 0.02, 0.03)) + .headingPIDFCoefficients(new PIDFCoefficients(1.2, 0, 0.03, 0.03)) + .drivePIDFCoefficients(new FilteredPIDFCoefficients(0.02, 0, 0.003, 0.6, 0.023)); public static PathConstraints pathConstraints = new PathConstraints( 0.99, @@ -49,8 +49,8 @@ public class Constants { .leftRearMotorDirection(DcMotorSimple.Direction.REVERSE) .rightFrontMotorDirection(DcMotorSimple.Direction.FORWARD) .rightRearMotorDirection(DcMotorSimple.Direction.FORWARD) - .xVelocity(65.1356) - .yVelocity(39.2622); + .xVelocity(80.4037) + .yVelocity(57.4415); public static PinpointConstants localizerConstants = new PinpointConstants() .forwardPodY(-3.25) diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/pedroPathing/Tuning.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/pedroPathing/Tuning.java index 01693c124f90..d411e473882f 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/pedroPathing/Tuning.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/pedroPathing/Tuning.java @@ -646,7 +646,7 @@ public void loop() { */ class LateralZeroPowerAccelerationTuner extends OpMode { private final ArrayList accelerations = new ArrayList<>(); - public static double VELOCITY = 35; + public static double VELOCITY = 50; private double previousVelocity; private long previousTimeNano; private boolean stopping; From 417e8bc38db99ba33d36dc538867cf52aaa49761 Mon Sep 17 00:00:00 2001 From: Professor348 <141444315+professor348@users.noreply.github.com> Date: Thu, 22 Jan 2026 19:45:18 -0500 Subject: [PATCH 03/13] A few PID and InterpLUT tweaks --- .../LOADCode/Main_/Auto_/Auto_Main_.java | 46 ++++--------------- .../Main_/Hardware_/Actuators_/Turret.java | 5 +- .../ftc/teamcode/pedroPathing/Constants.java | 2 +- 3 files changed, 15 insertions(+), 38 deletions(-) diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Auto_/Auto_Main_.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Auto_/Auto_Main_.java index 4bd7c93301dd..ffdf2e0774fc 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Auto_/Auto_Main_.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Auto_/Auto_Main_.java @@ -61,8 +61,6 @@ public void onInit() { new Near_9Ball(), new Far_9Ball(), new Far_6Ball() - //new test_Auto(), - //new Complex_Test_Auto() )); prompter.onComplete(() -> { selectedAlliance = prompter.get("alliance"); @@ -128,20 +126,6 @@ public void onStop(){ * The methods runAuto() and ToString() must be overridden for each auto. */ abstract static class Auto{ -// /** -// * This constructor must be called from the child class using super() -// * @param startingPose Indicates the starting pose of the robot -// * @param runTurret Indicates whether to run the turret auto aim functions -// */ -// Auto(Pose startingPose, Boolean runTurret){ -// turretOn = runTurret; -// startPose = startingPose; -// } -// Auto(Pose startingPose){ -// turretOn = true; -// startPose = startingPose; -// } - /** * @return The start pose of the robot for this auto. */ @@ -161,16 +145,13 @@ abstract static class Auto{ } private class Far_6Ball extends Auto{ - public Pose startPose = paths.farStart; - public boolean turretEnabled = true; - @Override public Pose getStartPose(){ - return startPose; + return paths.farStart; } @Override public boolean getTurretEnabled(){ - return turretEnabled; + return true; } @Override @@ -193,16 +174,13 @@ public void runAuto(){ } private class Far_9Ball extends Auto{ - public Pose startPose = paths.farStart; - public boolean turretEnabled = true; - @Override public Pose getStartPose(){ - return startPose; + return paths.farStart; } @Override public boolean getTurretEnabled(){ - return turretEnabled; + return true; } @Override @@ -230,16 +208,13 @@ public void runAuto(){ } private class Near_9Ball extends Auto{ - public Pose startPose = paths.nearStart; - public boolean turretEnabled = true; - @Override public Pose getStartPose(){ - return startPose; + return paths.nearStart; } @Override public boolean getTurretEnabled(){ - return turretEnabled; + return true; } @Override @@ -269,16 +244,13 @@ public void runAuto(){ } private class Near_12Ball extends Auto{ - public Pose startPose = paths.nearStart; - public boolean turretEnabled = true; - @Override public Pose getStartPose(){ - return startPose; + return paths.nearStart; } @Override public boolean getTurretEnabled(){ - return turretEnabled; + return true; } @Override @@ -342,4 +314,6 @@ public void runAuto(){ @Override public String toString(){return "Test Auto";} } + + } diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Turret.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Turret.java index 225b84840565..f933b3a2095c 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Turret.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Turret.java @@ -123,8 +123,9 @@ public void init(OpMode opmode, LoadHardwareClass robot){ hoodLUTnear.add(0, 0); hoodLUTfar.add(0, 0); + // -------------------------------------------------------- + // Near zone measurements - hoodLUTnear.add(0, 0); hoodLUTnear.add(53.5,108); hoodLUTnear.add(71,168); hoodLUTnear.add(77, 181); @@ -136,6 +137,8 @@ public void init(OpMode opmode, LoadHardwareClass robot){ hoodLUTfar.add(103, 200); hoodLUTfar.add(204, 200); + // -------------------------------------------------------- + // Safety points for LUTs hoodLUTnear.add(300, 200); hoodLUTfar.add(300, 200); diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/pedroPathing/Constants.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/pedroPathing/Constants.java index 6677fe460c4c..2eb2dc5b19db 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/pedroPathing/Constants.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/pedroPathing/Constants.java @@ -26,7 +26,7 @@ public class Constants { .centripetalScaling(0.0002) .translationalPIDFCoefficients(new PIDFCoefficients(0.2, 0.000003, 0.02, 0.03)) .headingPIDFCoefficients(new PIDFCoefficients(1.2, 0, 0.03, 0.03)) - .drivePIDFCoefficients(new FilteredPIDFCoefficients(0.02, 0, 0.003, 0.6, 0.023)); + .drivePIDFCoefficients(new FilteredPIDFCoefficients(0.02, 0, 0.002, 0.6, 0.02)); public static PathConstraints pathConstraints = new PathConstraints( 0.99, From 78af3fb6cde3ee4d370fb0b59a78ab7ccb174d58 Mon Sep 17 00:00:00 2001 From: Professor348 <141444315+Professor348@users.noreply.github.com> Date: Fri, 23 Jan 2026 08:09:22 -0500 Subject: [PATCH 04/13] Changed the weignt of the robot in PedroPathing's constants to be accurate. --- .../org/firstinspires/ftc/teamcode/pedroPathing/Constants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/pedroPathing/Constants.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/pedroPathing/Constants.java index 6677fe460c4c..62d2f3508788 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/pedroPathing/Constants.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/pedroPathing/Constants.java @@ -16,7 +16,7 @@ public class Constants { public static FollowerConstants followerConstants = new FollowerConstants() - .mass(13.6) // TODO: Change this to the actual weight of the robot + .mass(12.9) // TODO: Change this to the actual weight of the robot .forwardZeroPowerAcceleration(-31.6509) .lateralZeroPowerAcceleration(-69.7608) // Set following parameters to true to enable dual PID From 7d9e3063fd9a28848e9eb2144f1d4a91448b994d Mon Sep 17 00:00:00 2001 From: Professor348 <141444315+Professor348@users.noreply.github.com> Date: Fri, 23 Jan 2026 12:37:07 -0500 Subject: [PATCH 05/13] Added our Auto Webapp --- Auto Webapp/index.html | 698 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 698 insertions(+) create mode 100644 Auto Webapp/index.html diff --git a/Auto Webapp/index.html b/Auto Webapp/index.html new file mode 100644 index 000000000000..2358789a512a --- /dev/null +++ b/Auto Webapp/index.html @@ -0,0 +1,698 @@ + + + + + LOAD Auto Generator + + + + + + + + + + +

LOAD Robotics Auto Generator

+

+ The numbers next to the destinations indicate
+ the position on the field map below. The positions are
+ drawn for the Red side only, but are mirrored to the Blue side. +

+ +

Step 1: Setup

+ + + + +

Step 2: Commands

+
+ + +

Generated Auto Class

+
+ + + +
+ + + + + + + + From 009d9158dcbd3f519f739968cd6d07d603646e35 Mon Sep 17 00:00:00 2001 From: Professor348 <141444315+Professor348@users.noreply.github.com> Date: Thu, 29 Jan 2026 12:36:32 -0500 Subject: [PATCH 06/13] Update index.html --- Auto Webapp/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Auto Webapp/index.html b/Auto Webapp/index.html index 2358789a512a..de6429266aee 100644 --- a/Auto Webapp/index.html +++ b/Auto Webapp/index.html @@ -208,7 +208,7 @@

Generated Auto Class

const existingPaths = { nearStart: ["midShoot", "nearShoot"], - farStart: ["midShoot", "farShoot"], + farStart: ["farShoot", "midShoot"], nearPreload: ["nearShoot", "midShoot", "farShoot"], midPreload: ["nearShoot", "midShoot", "farShoot"], From 2f265fdfa73aeca069ee3d885fdb693c6318e083 Mon Sep 17 00:00:00 2001 From: Baron <126834072+BaronClaps@users.noreply.github.com> Date: Thu, 29 Jan 2026 22:56:16 -0600 Subject: [PATCH 07/13] Update Pedro FTC dependency version to 2.0.6 --- build.dependencies.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.dependencies.gradle b/build.dependencies.gradle index a61e71307f59..e96072b00a05 100644 --- a/build.dependencies.gradle +++ b/build.dependencies.gradle @@ -15,7 +15,7 @@ dependencies { implementation 'org.firstinspires.ftc:Vision:11.0.0' implementation 'androidx.appcompat:appcompat:1.2.0' - implementation 'com.pedropathing:ftc:2.0.5' + implementation 'com.pedropathing:ftc:2.0.6' implementation 'com.pedropathing:telemetry:1.0.0' implementation 'com.bylazar:fullpanels:1.0.9' } From d24eb066e55fdd0f73a7368029d023d0b7dc0ddf Mon Sep 17 00:00:00 2001 From: Professor348 <141444315+Professor348@users.noreply.github.com> Date: Fri, 30 Jan 2026 17:02:41 -0500 Subject: [PATCH 08/13] Added the variables (but not paths) for some of the missing paths for auto --- .../Hardware_/Drivetrain_/Pedro_Paths.java | 287 +++++------------- 1 file changed, 68 insertions(+), 219 deletions(-) diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Drivetrain_/Pedro_Paths.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Drivetrain_/Pedro_Paths.java index 88e094208303..8576aab7303f 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Drivetrain_/Pedro_Paths.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Drivetrain_/Pedro_Paths.java @@ -22,6 +22,9 @@ public class Pedro_Paths { public Pose nearPreload = new Pose(124.000, 83.500, Math.toRadians(0)); public Pose midPreload = new Pose(130.000, 59.500, Math.toRadians(0)); public Pose farPreload = new Pose(130.000, 35.500, Math.toRadians(0)); + public Pose hpPreload = new Pose(136, 8, -90); + public Pose rampIntake = new Pose(133, 55, 65); + public Pose hpIntake = null; // Shooting Poses public Pose nearShoot = new Pose(115, 120, Math.toRadians(-35)); public Pose midShoot = new Pose(85, 85, Math.toRadians(-15)); @@ -32,36 +35,83 @@ public class Pedro_Paths { public Pose nearLeave = new Pose(90,120, Math.toRadians(90)); public Pose midLeave = new Pose(95,55, Math.toRadians(90)); public Pose farLeave = new Pose(105,20, Math.toRadians(90)); + // Open Gate Pose + public Pose openGate = new Pose(128, 68, 90); /** - *

Define all path variables

+ *

Define all path variables.


+ * Comments indicate the start pose of the paths + */ + /** + *

+ *

Near Start Pose

*/ - // Start Poses to Preloads - public PathChain nearStart_to_nearPreload, nearStart_to_midPreload, nearStart_to_farPreload; - public PathChain farStart_to_nearPreload, farStart_to_midPreload, farStart_to_farPreload; - // Start Poses to Shooting Poses public PathChain nearStart_to_midShoot, nearStart_to_nearShoot; + /** + *

+ *

Far Start Pose

+ */ public PathChain farStart_to_midShoot, farStart_to_farShoot; - // Preloads to Shooting Positions + /** + *

+ *

Near Preload Pose

+ */ public PathChain nearPreload_to_nearShoot, nearPreload_to_midShoot, nearPreload_to_farShoot; + /** + *

+ *

Mid Preload Pose

+ */ public PathChain midPreload_to_nearShoot, midPreload_to_midShoot, midPreload_to_farShoot; + /** + *

+ *

Far Preload Pose

+ */ public PathChain farPreload_to_nearShoot, farPreload_to_midShoot, farPreload_to_farShoot; - // Shooting Positions to Preloads + /** + *

+ *

Human Player Preload Pose

+ */ + /** + *

+ *

Ramp Intake Pose

+ */ + /** + *

+ *

Human Player Random Intake Pose

+ */ + /** + *

+ *

Near Shooting Pose

+ */ public PathChain nearShoot_to_nearPreload, nearShoot_to_midPreload, nearShoot_to_farPreload; - public PathChain midShoot_to_nearPreload, midShoot_to_midPreload, midShoot_to_farPreload; - public PathChain farShoot_to_nearPreload, farShoot_to_midPreload, farShoot_to_farPreload; - // No-turret Shooting Positions to Preloads - public PathChain midShoot_noTurret_to_nearPreload, midShoot_noTurret_to_midPreload, midShoot_noTurret_to_farPreload; - public PathChain farShoot_noTurret_to_nearPreload, farShoot_noTurret_to_midPreload, farShoot_noTurret_to_farPreload; - // Shooting Positions to Leave Positions + public PathChain nearShoot_to_hpPreload, nearShoot_to_rampIntake, nearShoot_to_hpIntake; public PathChain nearShoot_to_nearLeave, nearShoot_to_midLeave; + public PathChain nearShoot_to_openGate; + /** + *

+ *

Mid Shooting Pose

+ */ + public PathChain midShoot_to_nearPreload, midShoot_to_midPreload, midShoot_to_farPreload; + public PathChain midShoot_to_hpPreload, midShoot_to_rampIntake, midShoot_to_hpIntake; public PathChain midShoot_to_nearLeave, midShoot_to_midLeave; + public PathChain midShoot_to_openGate; + /** + *

+ *

Far Shooting Pose

+ */ + public PathChain farShoot_to_nearPreload, farShoot_to_midPreload, farShoot_to_farPreload; + public PathChain farShoot_to_hpPreload, farShoot_to_rampIntake, farShoot_to_hpIntake; public PathChain farShoot_to_midLeave, farShoot_to_farLeave; - // Start Positions to Leave Positions - public PathChain nearStart_to_nearLeave, nearStart_to_midLeave; - public PathChain farStart_to_midLeave, farStart_to_farLeave; - // Start Positions to No-Turret shoot Positions - public PathChain nearStart_to_NoTurret_MidShoot, farStart_to_NoTurret_FarShoot; + public PathChain farShoot_to_openGate; + /** + *

+ *

Open Gate Pose

+ */ + public PathChain openGate_to_nearShoot, openGate_to_midShoot, openGate_to_farShoot; + public PathChain openGate_to_rampIntake; + + + public Pose autoMirror(Pose pose, LoadHardwareClass.Alliance alliance){ if (alliance == LoadHardwareClass.Alliance.BLUE){ @@ -87,97 +137,6 @@ private double mirrorHeading(double heading, LoadHardwareClass.Alliance alliance } } - public void buildStart1ToPreloads(){ - nearStart_to_nearPreload = follower.pathBuilder() - .addPath(new BezierCurve( - nearStart, - new Pose(89.000, 136.600), - new Pose(89.000, 78.000), - new Pose(95.000, 83.500), - new Pose(110.000, 83.500) - )) - .setLinearHeadingInterpolation(nearStart.getHeading(), Math.toRadians(0)) - .addPath(new BezierLine( - new Pose(110.000, 83.500), - nearPreload - )) - .setConstantHeadingInterpolation(Math.toRadians(0)) - .build(); - nearStart_to_midPreload = follower.pathBuilder() - .addPath(new BezierCurve( - nearStart, - new Pose(89.000, 136.600), - new Pose(89.000, 54.000), - new Pose(95.000, 59.500), - new Pose(110.000, 59.500) - )) - .setLinearHeadingInterpolation(nearStart.getHeading(), Math.toRadians(0)) - .addPath(new BezierLine( - new Pose(110.000, 59.500), - midPreload - )) - .setConstantHeadingInterpolation(Math.toRadians(0)) - .build(); - nearStart_to_farPreload = follower.pathBuilder() - .addPath(new BezierCurve( - nearStart, - new Pose(89.000, 136.600), - new Pose(89.000, 30.000), - new Pose(95.000, 35.500), - new Pose(110.000, 35.500) - )) - .setLinearHeadingInterpolation(nearStart.getHeading(), Math.toRadians(0)) - .addPath(new BezierLine( - new Pose(110.000, 35.500), - farPreload - )) - .setConstantHeadingInterpolation(Math.toRadians(0)) - .build(); - } - public void buildStart2ToPreloads(){ - farStart_to_nearPreload = follower.pathBuilder() - .addPath(new BezierCurve( - farStart, - new Pose(89.000, 79.000), - new Pose(95.000, 83.500), - new Pose(110.000, 83.500) - )) - .setLinearHeadingInterpolation(farStart.getHeading(), Math.toRadians(0)) - .addPath(new BezierLine( - new Pose(110.000, 83.500), - nearPreload - )) - .setConstantHeadingInterpolation(Math.toRadians(0)) - .build(); - farStart_to_midPreload = follower.pathBuilder() - .addPath(new BezierCurve( - farStart, - new Pose(89.000, 55.000), - new Pose(95.000, 59.500), - new Pose(110.000, 59.500) - )) - .setLinearHeadingInterpolation(nearStart.getHeading(), Math.toRadians(0)) - .addPath(new BezierLine( - new Pose(110.000, 59.500), - midPreload - )) - .setConstantHeadingInterpolation(Math.toRadians(0)) - .build(); - farStart_to_farPreload = follower.pathBuilder() - .addPath(new BezierCurve( - farStart, - new Pose(89.000, 25), - new Pose(95.000, 35.500), - new Pose(110.000, 35.500) - )) - .setLinearHeadingInterpolation(farStart.getHeading(), Math.toRadians(0)) - .addPath(new BezierLine( - new Pose(110.000, 35.500), - farPreload - )) - .setConstantHeadingInterpolation(Math.toRadians(0)) - .build(); - } public void buildStart1ToShootings(){ nearStart_to_nearShoot = follower.pathBuilder() .addPath(new BezierLine( @@ -363,57 +322,6 @@ public void buildShooting3ToPreloads(){ .setLinearHeadingInterpolation(farShoot.getHeading(), farPreload.getHeading()) .build(); } - public void buildShooting2NoTurretToPreloads(){ - midShoot_noTurret_to_nearPreload = follower.pathBuilder() - .addPath(new BezierLine( - noTurretMidShoot, - nearPreload - )) - .setLinearHeadingInterpolation(noTurretMidShoot.getHeading(), nearPreload.getHeading()) - .build(); - midShoot_noTurret_to_midPreload = follower.pathBuilder() - .addPath(new BezierCurve( - noTurretMidShoot, - new Pose(75, 56), - midPreload - )) - .setLinearHeadingInterpolation(noTurretMidShoot.getHeading(), midPreload.getHeading()) - .build(); - midShoot_noTurret_to_farPreload = follower.pathBuilder() - .addPath(new BezierCurve( - noTurretMidShoot, - new Pose(68, 30), - farPreload - )) - .setLinearHeadingInterpolation(noTurretMidShoot.getHeading(), farPreload.getHeading()) - .build(); - } - public void buildShooting3NoTurretToPreloads(){ - farShoot_noTurret_to_nearPreload = follower.pathBuilder() - .addPath(new BezierCurve( - noTurretFarShoot, - new Pose(73, 88), - nearPreload - )) - .setLinearHeadingInterpolation(noTurretFarShoot.getHeading(), nearPreload.getHeading()) - .build(); - farShoot_noTurret_to_midPreload = follower.pathBuilder() - .addPath(new BezierCurve( - noTurretFarShoot, - new Pose(78, 62), - midPreload - )) - .setLinearHeadingInterpolation(noTurretFarShoot.getHeading(), midPreload.getHeading()) - .build(); - farShoot_noTurret_to_farPreload = follower.pathBuilder() - .addPath(new BezierCurve( - noTurretFarShoot, - new Pose(82.5, 35), - farPreload - )) - .setLinearHeadingInterpolation(noTurretFarShoot.getHeading(), farPreload.getHeading()) - .build(); - } public void buildShooting1ToLeaves(){ nearShoot_to_nearLeave = follower.pathBuilder() .addPath(new BezierLine( @@ -462,54 +370,6 @@ public void buildShooting3ToLeaves(){ .setConstantHeadingInterpolation(farShoot.getHeading()) .build(); } - public void buildStart1ToLeaves(){ - nearStart_to_nearLeave = follower.pathBuilder() - .addPath(new BezierLine( - nearStart, - nearLeave - )) - .setConstantHeadingInterpolation(nearStart.getHeading()) - .build(); - nearStart_to_midLeave = follower.pathBuilder() - .addPath(new BezierLine( - nearStart, - farLeave - )) - .setConstantHeadingInterpolation(nearStart.getHeading()) - .build(); - } - public void buildStart2ToLeaves(){ - farStart_to_midLeave = follower.pathBuilder() - .addPath(new BezierLine( - farStart, - nearLeave - )) - .setConstantHeadingInterpolation(farStart.getHeading()) - .build(); - farStart_to_farLeave = follower.pathBuilder() - .addPath(new BezierLine( - farStart, - farLeave - )) - .setConstantHeadingInterpolation(farStart.getHeading()) - .build(); - } - public void buildStartsToNoTurretShoots(){ - nearStart_to_NoTurret_MidShoot = follower.pathBuilder() - .addPath(new BezierLine( - nearStart, - noTurretMidShoot - )) - .setLinearHeadingInterpolation(nearStart.getHeading(), noTurretMidShoot.getHeading()) - .build(); - farStart_to_NoTurret_FarShoot = follower.pathBuilder() - .addPath(new BezierLine( - farStart, - noTurretFarShoot - )) - .setLinearHeadingInterpolation(farStart.getHeading(), noTurretFarShoot.getHeading()) - .build(); - } /** @@ -534,9 +394,6 @@ public void buildPaths(LoadHardwareClass.Alliance Alliance, Follower follow){ /// All paths are for the RED side of the field. they will be mirrored if necessary. - // Paths going from each start position to each of the preloads. - buildStart1ToPreloads(); - buildStart2ToPreloads(); // Paths going from each start position to each of the shooting positions. buildStart1ToShootings(); buildStart2ToShootings(); @@ -548,17 +405,9 @@ public void buildPaths(LoadHardwareClass.Alliance Alliance, Follower follow){ buildShooting1ToPreloads(); buildShooting2ToPreloads(); buildShooting3ToPreloads(); - // Paths going from each no-turret shooting position to each preload - buildShooting2NoTurretToPreloads(); - buildShooting3NoTurretToPreloads(); // Paths going from each shooting position to the leave positions. buildShooting1ToLeaves(); buildShooting2ToLeaves(); buildShooting3ToLeaves(); - // Paths going from the start positions to the leave positions - buildStart1ToLeaves(); - buildStart2ToLeaves(); - // Paths going from the start positions to the no-turret shooting positions - buildStartsToNoTurretShoots(); } } From 94e5c32334606ee2ca405f4087333f3f59ac885a Mon Sep 17 00:00:00 2001 From: Professor348 <141444315+professor348@users.noreply.github.com> Date: Thu, 5 Feb 2026 19:51:23 -0500 Subject: [PATCH 09/13] Created some more paths for LOAD AAA --- .../LOADCode/Main_/Auto_/Auto_Main_.java | 46 ++-- .../Main_/Hardware_/Actuators_/Turret.java | 7 +- .../Hardware_/Drivetrain_/Pedro_Paths.java | 202 ++++++++++++++---- .../LOADCode/Main_/Teleop_/Teleop_Main_.java | 6 +- .../ftc/teamcode/LOADCode/Main_/Utils_.java | 3 - .../ftc/teamcode/LOADCode/Notes and TODOs | 4 +- .../teamcode/Prism/GoBildaPrismExample.java | 6 +- .../ftc/teamcode/pedroPathing/Constants.java | 2 +- 8 files changed, 196 insertions(+), 80 deletions(-) diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Auto_/Auto_Main_.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Auto_/Auto_Main_.java index ffdf2e0774fc..2fb7804b7993 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Auto_/Auto_Main_.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Auto_/Auto_Main_.java @@ -18,6 +18,7 @@ import org.firstinspires.ftc.teamcode.LOADCode.Main_.Hardware_.LoadHardwareClass; import org.firstinspires.ftc.teamcode.pedroPathing.Constants; +import dev.nextftc.core.commands.delays.WaitUntil; import dev.nextftc.core.commands.groups.SequentialGroup; import dev.nextftc.core.commands.utility.InstantCommand; import dev.nextftc.extensions.pedro.PedroComponent; @@ -60,22 +61,30 @@ public void onInit() { new Near_12Ball(), new Near_9Ball(), new Far_9Ball(), - new Far_6Ball() + new Far_6Ball(), + new test_Auto() )); prompter.onComplete(() -> { selectedAlliance = prompter.get("alliance"); selectedAuto = prompter.get("auto"); - telemetry.addData("Selection", "Complete"); - telemetry.addData("Alliance", selectedAlliance.toString()); - telemetry.addData("Auto", selectedAuto); telemetry.update(); // Build paths - paths.buildPaths(selectedAlliance, follower()); + paths.buildPaths(follower()); // Initialize all hardware of the robot - Robot.init(paths.autoMirror(selectedAuto.getStartPose(), selectedAlliance), follower()); + Robot.init(selectedAuto.getStartPose(), follower()); while (opModeInInit() && Robot.turret.zeroTurret()){ + telemetry.addLine("TURRET ZEROING"); + telemetry.addData("Selection", "Complete"); + telemetry.addData("Alliance", selectedAlliance.toString()); + telemetry.addData("Auto", selectedAuto); + telemetry.update(); sleep(0); } + telemetry.addLine("TURRET READY"); + telemetry.addData("Selection", "Complete"); + telemetry.addData("Alliance", selectedAlliance.toString()); + telemetry.addData("Auto", selectedAuto); + telemetry.update(); }); } @@ -110,8 +119,7 @@ public void onUpdate() { MecanumDrivetrainClass.robotPose = Robot.drivetrain.follower.getPose(); telemetry.addLine(); - telemetry.addData("FarStart", paths.farStart); - telemetry.addData("FarShoot", paths.noTurretFarShoot); + telemetry.addData("Mirror -90", Math.toDegrees(paths.autoMirror(new Pose(0,0,-90)).getHeading())); telemetry.update(); } @@ -161,7 +169,7 @@ public void runAuto(){ Commands.shootBalls(), Commands.setFlywheelState(Turret.flywheelState.ON), Commands.setIntakeMode(Intake.intakeMode.INTAKING), - Commands.runPath(paths.farShoot_noTurret_to_farPreload, true, 1), + Commands.runPath(paths.farShoot_to_farPreload, true, 1), Commands.runPath(paths.farPreload_to_farShoot, true, 1), Commands.shootBalls(), Commands.runPath(paths.farShoot_to_farLeave, true, 1) @@ -285,28 +293,24 @@ public void runAuto(){ } private class test_Auto extends Auto{ - public Pose startPose = paths.farStart; - public boolean turretEnabled = false; - @Override public Pose getStartPose(){ - return startPose; + return paths.farStart; } @Override public boolean getTurretEnabled(){ - return turretEnabled; + return true; } @Override public void runAuto(){ double tempSpeed = 1; new SequentialGroup( - Commands.runPath(paths.farStart_to_farPreload,true,tempSpeed), - Commands.runPath(paths.farPreload_to_farShoot,true,tempSpeed), - Commands.runPath(paths.farShoot_to_midPreload, true, tempSpeed), - Commands.runPath(paths.midPreload_to_midShoot, true, tempSpeed), - Commands.runPath(paths.midShoot_to_nearPreload, true, tempSpeed), - Commands.runPath(paths.nearPreload_to_nearShoot, true, tempSpeed) + Commands.runPath(paths.farStart_to_midShoot,true, tempSpeed), + Commands.runPath(paths.midShoot_to_openGateIntake,true, tempSpeed), + new WaitUntil(() -> gamepad1.b), + Commands.runPath(paths.openGateIntake_to_farShoot,true, tempSpeed), + Commands.runPath(paths.farShoot_to_openGateIntake,true, tempSpeed) ).schedule(); } @@ -314,6 +318,4 @@ public void runAuto(){ @Override public String toString(){return "Test Auto";} } - - } diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Turret.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Turret.java index f933b3a2095c..8b39f2b3010e 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Turret.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Turret.java @@ -210,8 +210,8 @@ public void updateAimbotWithVelocity(){ rotation.setAngle(Math.max(0, calcLocalizer()+blueOffset)%360, -Math.toDegrees(Robot.drivetrain.follower.getAngularVelocity())); } // Set the hood angle - Pose goalPose = new Pose(0-posOffset,144+posOffset,0); - if (LoadHardwareClass.selectedAlliance == LoadHardwareClass.Alliance.RED) {goalPose = new Pose(144+posOffset, 144+posOffset, 0);} + //Pose goalPose = new Pose(0-posOffset,144+posOffset,0); + //if (LoadHardwareClass.selectedAlliance == LoadHardwareClass.Alliance.RED) {goalPose = new Pose(144+posOffset, 144+posOffset, 0);} //setHood(hoodLUT.get(Robot.drivetrain.follower.getPose().distanceFrom(goalPose))); } @@ -318,9 +318,6 @@ public boolean zeroTurret(){ zeroed = true; } } - opMode.telemetry.addLine("ZEROING TURRET"); - opMode.telemetry.addData("Turret Power", rotation.getPower()); - opMode.telemetry.update(); return !zeroed; } diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Drivetrain_/Pedro_Paths.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Drivetrain_/Pedro_Paths.java index 8576aab7303f..631108236fc9 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Drivetrain_/Pedro_Paths.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Drivetrain_/Pedro_Paths.java @@ -11,6 +11,7 @@ public class Pedro_Paths { // The variable to store PedroPathing's follower object for path building private Follower follower; + private LoadHardwareClass.Alliance alliance = LoadHardwareClass.selectedAlliance; /** * Define primary poses to be used in paths @@ -36,7 +37,10 @@ public class Pedro_Paths { public Pose midLeave = new Pose(95,55, Math.toRadians(90)); public Pose farLeave = new Pose(105,20, Math.toRadians(90)); // Open Gate Pose - public Pose openGate = new Pose(128, 68, 90); + public Pose openGateBasic = new Pose(127.5, 72, Math.toRadians(90)); + public Pose openGateBasicReversed = new Pose(127.5, 72, Math.toRadians(-90)); + public Pose openGateIntakeGate = new Pose(131, 61.5, Math.toRadians(20)); + public Pose openGateIntakeRamp = new Pose(133, 55, Math.toRadians(40)); /** *

Define all path variables.


@@ -57,11 +61,13 @@ public class Pedro_Paths { *

Near Preload Pose

*/ public PathChain nearPreload_to_nearShoot, nearPreload_to_midShoot, nearPreload_to_farShoot; + public PathChain nearPreload_to_openGateBasic; /** *

*

Mid Preload Pose

*/ public PathChain midPreload_to_nearShoot, midPreload_to_midShoot, midPreload_to_farShoot; + public PathChain midPreload_to_openGateBasic; /** *

*

Far Preload Pose

@@ -84,36 +90,41 @@ public class Pedro_Paths { *

Near Shooting Pose

*/ public PathChain nearShoot_to_nearPreload, nearShoot_to_midPreload, nearShoot_to_farPreload; - public PathChain nearShoot_to_hpPreload, nearShoot_to_rampIntake, nearShoot_to_hpIntake; + public PathChain nearShoot_to_hpPreload, nearShoot_to_hpIntake; public PathChain nearShoot_to_nearLeave, nearShoot_to_midLeave; - public PathChain nearShoot_to_openGate; + public PathChain nearShoot_to_openGateIntake, nearShoot_to_openGateBasic; /** *

*

Mid Shooting Pose

*/ public PathChain midShoot_to_nearPreload, midShoot_to_midPreload, midShoot_to_farPreload; - public PathChain midShoot_to_hpPreload, midShoot_to_rampIntake, midShoot_to_hpIntake; + public PathChain midShoot_to_hpPreload, midShoot_to_hpIntake; public PathChain midShoot_to_nearLeave, midShoot_to_midLeave; - public PathChain midShoot_to_openGate; + public PathChain midShoot_to_openGateIntake, midShoot_to_openGateBasic; /** *

*

Far Shooting Pose

*/ public PathChain farShoot_to_nearPreload, farShoot_to_midPreload, farShoot_to_farPreload; - public PathChain farShoot_to_hpPreload, farShoot_to_rampIntake, farShoot_to_hpIntake; + public PathChain farShoot_to_hpPreload, farShoot_to_hpIntake; public PathChain farShoot_to_midLeave, farShoot_to_farLeave; - public PathChain farShoot_to_openGate; + public PathChain farShoot_to_openGateIntake, farShoot_to_openGateBasic; /** *

- *

Open Gate Pose

+ *

Open Gate Basic Pose (No Intake)

*/ - public PathChain openGate_to_nearShoot, openGate_to_midShoot, openGate_to_farShoot; - public PathChain openGate_to_rampIntake; + public PathChain openGateBasic_to_nearShoot, openGateBasic_to_midShoot, openGateBasic_to_farShoot; + /** + *

+ *

Open Gate Basic Pose (Intake)

+ */ + public PathChain openGateIntake_to_nearShoot, openGateIntake_to_midShoot, openGateIntake_to_farShoot; + - public Pose autoMirror(Pose pose, LoadHardwareClass.Alliance alliance){ + public Pose autoMirror(Pose pose){ if (alliance == LoadHardwareClass.Alliance.BLUE){ return new Pose( 144 - pose.getX(), @@ -187,7 +198,7 @@ public void buildPreload1ToShootings(){ nearPreload_to_farShoot = follower.pathBuilder() .addPath(new BezierCurve( nearPreload, - new Pose(80.000, 83.500), + autoMirror(new Pose(80.000, 83.500)), farShoot )) .setLinearHeadingInterpolation(nearPreload.getHeading(), farShoot.getHeading()) @@ -197,7 +208,7 @@ public void buildPreload2ToShootings(){ midPreload_to_nearShoot = follower.pathBuilder() .addPath(new BezierCurve( midPreload, - new Pose(65,59.5), + autoMirror(new Pose(65,59.5)), nearShoot )) .setLinearHeadingInterpolation(midPreload.getHeading(), nearShoot.getHeading()) @@ -205,7 +216,7 @@ public void buildPreload2ToShootings(){ midPreload_to_midShoot = follower.pathBuilder() .addPath(new BezierCurve( midPreload, - new Pose(65,59.5), + autoMirror(new Pose(65,59.5)), midShoot )) .setLinearHeadingInterpolation(midPreload.getHeading(), midShoot.getHeading()) @@ -213,7 +224,7 @@ public void buildPreload2ToShootings(){ midPreload_to_farShoot = follower.pathBuilder() .addPath(new BezierCurve( midPreload, - new Pose(90.000, 59.500), + autoMirror(new Pose(90.000, 59.500)), farShoot )) .setLinearHeadingInterpolation(midPreload.getHeading(), farShoot.getHeading()) @@ -223,8 +234,8 @@ public void buildPreload3ToShootings(){ farPreload_to_nearShoot = follower.pathBuilder() .addPath(new BezierCurve( farPreload, - new Pose(75,30), - new Pose(80,100), + autoMirror(new Pose(75,30)), + autoMirror(new Pose(80,100)), nearShoot )) .setLinearHeadingInterpolation(midPreload.getHeading(), nearShoot.getHeading()) @@ -232,7 +243,7 @@ public void buildPreload3ToShootings(){ farPreload_to_midShoot = follower.pathBuilder() .addPath(new BezierCurve( farPreload, - new Pose(85,32), + autoMirror(new Pose(90,41)), midShoot )) .setLinearHeadingInterpolation(midPreload.getHeading(), midShoot.getHeading()) @@ -249,7 +260,7 @@ public void buildShooting1ToPreloads(){ nearShoot_to_nearPreload = follower.pathBuilder() .addPath(new BezierCurve( nearShoot, - new Pose(60, 80), + autoMirror(new Pose(60, 80)), nearPreload )) .setLinearHeadingInterpolation(nearShoot.getHeading(), nearPreload.getHeading()) @@ -257,7 +268,7 @@ public void buildShooting1ToPreloads(){ nearShoot_to_midPreload = follower.pathBuilder() .addPath(new BezierCurve( nearShoot, - new Pose(60, 55), + autoMirror(new Pose(60, 55)), midPreload )) .setLinearHeadingInterpolation(nearShoot.getHeading(), midPreload.getHeading()) @@ -265,7 +276,7 @@ public void buildShooting1ToPreloads(){ nearShoot_to_farPreload = follower.pathBuilder() .addPath(new BezierCurve( nearShoot, - new Pose(60, 27), + autoMirror(new Pose(60, 27)), farPreload )) .setLinearHeadingInterpolation(nearShoot.getHeading(), farPreload.getHeading()) @@ -282,7 +293,7 @@ public void buildShooting2ToPreloads(){ midShoot_to_midPreload = follower.pathBuilder() .addPath(new BezierCurve( midShoot, - new Pose(75, 56), + autoMirror(new Pose(75, 56)), midPreload )) .setLinearHeadingInterpolation(midShoot.getHeading(), midPreload.getHeading()) @@ -290,7 +301,7 @@ public void buildShooting2ToPreloads(){ midShoot_to_farPreload = follower.pathBuilder() .addPath(new BezierCurve( midShoot, - new Pose(68, 30), + autoMirror(new Pose(68, 30)), farPreload )) .setLinearHeadingInterpolation(midShoot.getHeading(), farPreload.getHeading()) @@ -300,7 +311,7 @@ public void buildShooting3ToPreloads(){ farShoot_to_nearPreload = follower.pathBuilder() .addPath(new BezierCurve( farShoot, - new Pose(73, 88), + autoMirror(new Pose(73, 88)), nearPreload )) .setLinearHeadingInterpolation(farShoot.getHeading(), nearPreload.getHeading()) @@ -308,7 +319,7 @@ public void buildShooting3ToPreloads(){ farShoot_to_midPreload = follower.pathBuilder() .addPath(new BezierCurve( farShoot, - new Pose(78, 62), + autoMirror(new Pose(78, 62)), midPreload )) .setLinearHeadingInterpolation(farShoot.getHeading(), midPreload.getHeading()) @@ -316,7 +327,7 @@ public void buildShooting3ToPreloads(){ farShoot_to_farPreload = follower.pathBuilder() .addPath(new BezierCurve( farShoot, - new Pose(82.5, 35), + autoMirror(new Pose(82.5, 35)), farPreload )) .setLinearHeadingInterpolation(farShoot.getHeading(), farPreload.getHeading()) @@ -370,27 +381,132 @@ public void buildShooting3ToLeaves(){ .setConstantHeadingInterpolation(farShoot.getHeading()) .build(); } + public void buildMidShootToOpenGates(){ + midShoot_to_openGateBasic = follower.pathBuilder() + .addPath(new BezierCurve( + midShoot, + autoMirror(new Pose(94, 71)), + openGateBasic + )) + .setLinearHeadingInterpolation(midShoot.getHeading(), openGateBasic.getHeading()) + .build(); + midShoot_to_openGateIntake = follower.pathBuilder() + .addPath(new BezierCurve( + midShoot, + autoMirror(new Pose(96, 66.5)), + openGateIntakeGate + )) + .setLinearHeadingInterpolation(midShoot.getHeading(), openGateIntakeRamp.getHeading()) + .addPath(new BezierLine( + openGateIntakeGate, + openGateIntakeRamp + )) + .setLinearHeadingInterpolation(openGateIntakeGate.getHeading(), openGateIntakeRamp.getHeading()) + .build(); + } + public void buildFarShootToOpenGates(){ + farShoot_to_openGateBasic = follower.pathBuilder() + .addPath(new BezierCurve( + farShoot, + autoMirror(new Pose(94, 71)), + openGateBasic + )) + .setLinearHeadingInterpolation(midShoot.getHeading(), openGateBasic.getHeading()) + .build(); + farShoot_to_openGateIntake = follower.pathBuilder() + .addPath(new BezierCurve( + farShoot, + autoMirror(new Pose(96, 66.5)), + openGateIntakeGate + )) + .setLinearHeadingInterpolation(farShoot.getHeading(), openGateIntakeRamp.getHeading()) + .addPath(new BezierLine( + openGateIntakeGate, + openGateIntakeRamp + )) + .setLinearHeadingInterpolation(openGateIntakeGate.getHeading(), openGateIntakeRamp.getHeading()) + .build(); + } + public void buildOpenGateIntakeToShootings(){ + openGateIntake_to_farShoot = follower.pathBuilder() + .addPath(new BezierCurve( + openGateIntakeRamp, + autoMirror(new Pose(94, 71)), + farShoot + )) + .setLinearHeadingInterpolation(openGateIntakeRamp.getHeading(), farShoot.getHeading()) + .build(); + openGateIntake_to_midShoot = follower.pathBuilder() + .addPath(new BezierCurve( + openGateIntakeRamp, + autoMirror(new Pose(97, 60)), + midShoot + )) + .setLinearHeadingInterpolation(openGateIntakeRamp.getHeading(), midShoot.getHeading()) + .build(); + } + public void buildOpenGateBasicToShootings(){ + openGateBasic_to_farShoot = follower.pathBuilder() + .addPath(new BezierCurve( + openGateIntakeRamp, + autoMirror(new Pose(94, 71)), + farShoot + )) + .setLinearHeadingInterpolation(openGateBasic.getHeading(), farShoot.getHeading()) + .build(); + openGateBasic_to_midShoot = follower.pathBuilder() + .addPath(new BezierCurve( + openGateBasic, + autoMirror(new Pose(97, 67)), + midShoot + )) + .setLinearHeadingInterpolation(openGateBasic.getHeading(), midShoot.getHeading()) + .build(); + } + public void buildPreloadsToOpenGateBasic(){ + nearPreload_to_openGateBasic = follower.pathBuilder() + .addPath(new BezierCurve( + nearPreload, + autoMirror(new Pose(115, 75)), + openGateBasic + )) + .setLinearHeadingInterpolation(nearPreload.getHeading(), openGateBasic.getHeading()) + .build(); + midPreload_to_openGateBasic = follower.pathBuilder() + .addPath(new BezierCurve( + midPreload, + autoMirror(new Pose(110, 59)), + openGateBasicReversed + )) + .setLinearHeadingInterpolation(midPreload.getHeading(), openGateBasicReversed.getHeading()) + .build(); + } /** * Builds all the paths, mirroring them to the other side of the field if necessary */ - public void buildPaths(LoadHardwareClass.Alliance Alliance, Follower follow){ + public void buildPaths(Follower follow){ follower = follow; + alliance = LoadHardwareClass.selectedAlliance; - nearStart = autoMirror(nearStart, Alliance); - farStart = autoMirror(farStart, Alliance); - nearPreload = autoMirror(nearPreload, Alliance); - midPreload = autoMirror(midPreload, Alliance); - farPreload = autoMirror(farPreload, Alliance); - nearShoot = autoMirror(nearShoot, Alliance); - midShoot = autoMirror(midShoot, Alliance); - farShoot = autoMirror(farShoot, Alliance); - noTurretMidShoot = autoMirror(noTurretMidShoot, Alliance); - noTurretFarShoot = autoMirror(noTurretFarShoot, Alliance); - nearLeave = autoMirror(nearLeave, Alliance); - midLeave = autoMirror(midLeave, Alliance); - farLeave = autoMirror(farLeave, Alliance); + nearStart = autoMirror(nearStart); + farStart = autoMirror(farStart); + nearPreload = autoMirror(nearPreload); + midPreload = autoMirror(midPreload); + farPreload = autoMirror(farPreload); + nearShoot = autoMirror(nearShoot); + midShoot = autoMirror(midShoot); + farShoot = autoMirror(farShoot); + noTurretMidShoot = autoMirror(noTurretMidShoot); + noTurretFarShoot = autoMirror(noTurretFarShoot); + nearLeave = autoMirror(nearLeave); + midLeave = autoMirror(midLeave); + farLeave = autoMirror(farLeave); + openGateBasic = autoMirror(openGateBasic); + openGateBasicReversed = autoMirror(openGateBasicReversed); + openGateIntakeGate = autoMirror(openGateIntakeGate); + openGateIntakeRamp = autoMirror(openGateIntakeRamp); /// All paths are for the RED side of the field. they will be mirrored if necessary. @@ -409,5 +525,11 @@ public void buildPaths(LoadHardwareClass.Alliance Alliance, Follower follow){ buildShooting1ToLeaves(); buildShooting2ToLeaves(); buildShooting3ToLeaves(); + // Paths going from shooting positions to open gate positions + buildFarShootToOpenGates(); + buildMidShootToOpenGates(); + buildOpenGateIntakeToShootings(); + buildOpenGateBasicToShootings(); + buildPreloadsToOpenGateBasic(); } } diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Teleop_/Teleop_Main_.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Teleop_/Teleop_Main_.java index 2c6b029bcf85..33355fd39233 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Teleop_/Teleop_Main_.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Teleop_/Teleop_Main_.java @@ -117,10 +117,10 @@ public void runOpMode() { if (MecanumDrivetrainClass.robotPose == null){ startPoses pose = prompter.get("startPose"); if (pose.equals(startPoses.FAR)) { - startPose = Paths.autoMirror(Paths.farStart, selectedAlliance); + startPose = Paths.autoMirror(Paths.farStart); telemetry.addData("Start Pose", "Far Start Pose"); } else if (pose.equals(startPoses.NEAR)) { - startPose = Paths.autoMirror(Paths.nearStart, selectedAlliance); + startPose = Paths.autoMirror(Paths.nearStart); telemetry.addData("Start Pose", "Near Start Pose"); } }else{ @@ -140,7 +140,7 @@ public void runOpMode() { // Initialize all hardware of the robot Robot.init(startPose); runtime.reset(); - Paths.buildPaths(selectedAlliance, Robot.drivetrain.follower); + Paths.buildPaths(Robot.drivetrain.follower); Robot.drivetrain.startTeleOpDrive(); // run until the end of the match (driver presses STOP) diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Utils_.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Utils_.java index 14c2b3a1f60b..07e37dabe541 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Utils_.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Utils_.java @@ -2,7 +2,6 @@ import java.util.ArrayList; import java.util.Arrays; -import java.util.Comparator; import java.util.List; @@ -227,6 +226,4 @@ public telemetrySortCategory getTelemCategory(){ } } - - } diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Notes and TODOs b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Notes and TODOs index d5b4ec13edc1..09cb32ab86ba 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Notes and TODOs +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Notes and TODOs @@ -32,4 +32,6 @@ // TODO: create paths to pick up human player zone Artifacts and to open the gate -//TODO Link the PID update to the flywheel state so it can float instead of break at zero power \ No newline at end of file +// DONE Link the PID update to the flywheel state so it can float instead of break at zero power + +// TODO: create a custom Pose class that automirrors internally \ No newline at end of file diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/Prism/GoBildaPrismExample.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/Prism/GoBildaPrismExample.java index c844fe416215..a7a78b462bee 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/Prism/GoBildaPrismExample.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/Prism/GoBildaPrismExample.java @@ -20,7 +20,7 @@ * SOFTWARE. */ -package org.firstinspires.ftc.teamcode; +package org.firstinspires.ftc.teamcode.Prism; import static org.firstinspires.ftc.teamcode.Prism.GoBildaPrismDriver.LayerHeight; @@ -28,10 +28,6 @@ import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode; import com.qualcomm.robotcore.eventloop.opmode.TeleOp; -import org.firstinspires.ftc.teamcode.Prism.Color; -import org.firstinspires.ftc.teamcode.Prism.GoBildaPrismDriver; -import org.firstinspires.ftc.teamcode.Prism.PrismAnimations; - import java.util.concurrent.TimeUnit; /* diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/pedroPathing/Constants.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/pedroPathing/Constants.java index f24f08b0f786..2960689313b8 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/pedroPathing/Constants.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/pedroPathing/Constants.java @@ -58,7 +58,7 @@ public class Constants { .distanceUnit(DistanceUnit.INCH) .hardwareMapName("pinpoint") .encoderResolution(GoBildaPinpointDriver.GoBildaOdometryPods.goBILDA_4_BAR_POD) - .forwardEncoderDirection(GoBildaPinpointDriver.EncoderDirection.FORWARD) + .forwardEncoderDirection(GoBildaPinpointDriver.EncoderDirection.REVERSED) .strafeEncoderDirection(GoBildaPinpointDriver.EncoderDirection.FORWARD); public static Follower createFollower(HardwareMap hardwareMap) { From 902607ecc0f6b8d400ad3e0e0fbc02786fe070e1 Mon Sep 17 00:00:00 2001 From: Professor348 <141444315+professor348@users.noreply.github.com> Date: Fri, 6 Feb 2026 08:46:13 -0500 Subject: [PATCH 10/13] Created a smart intake command for ramp intaking --- .../LOADCode/Main_/Hardware_/Commands.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Commands.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Commands.java index f9b926519ea7..684d8bd47cda 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Commands.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Commands.java @@ -10,6 +10,7 @@ import dev.nextftc.core.commands.Command; import dev.nextftc.core.commands.delays.WaitUntil; +import dev.nextftc.core.commands.groups.ParallelRaceGroup; import dev.nextftc.core.commands.groups.SequentialGroup; import dev.nextftc.core.commands.utility.InstantCommand; import dev.nextftc.core.commands.utility.LambdaCommand; @@ -26,12 +27,16 @@ public Commands(@NonNull LoadHardwareClass robot){ // Delay timer for shooting sequence private static final TimerEx shootingTimerHalfSec = new TimerEx(0.5); private static final TimerEx shootingTimer2sec = new TimerEx(2); - private static Command resetShootingTimer1sec() { - return new LambdaCommand("resetShootingTimer1.5sec").setStart(shootingTimerHalfSec::restart); + private static final TimerEx shootingTimer5sec = new TimerEx(5); + private static Command resetShootingTimerHalfsec() { + return new LambdaCommand("resetShootingTimer0.5sec").setStart(shootingTimerHalfSec::restart); } private static Command resetShootingTimer2sec() { return new LambdaCommand("resetShootingTimer2sec").setStart(shootingTimer2sec::restart); } + private static Command resetShootingTimer5sec() { + return new LambdaCommand("resetShootingTimer5sec").setStart(shootingTimer2sec::restart); + } public Command runPath(PathChain path, boolean holdEnd, double maxPower) { return new FollowPath(path, holdEnd, maxPower); @@ -71,6 +76,18 @@ public Command setTransferState(Intake.transferState state) { ); } + public Command waitForArtifacts(){ + return new SequentialGroup( + setIntakeMode(Intake.intakeMode.INTAKING), + resetShootingTimer5sec(), + new WaitUntil(() -> Robot.intake.getTopSensorState() || Robot.intake.getBottomSensorState()), + new ParallelRaceGroup( + new WaitUntil(() -> Robot.intake.getTopSensorState() && Robot.intake.getBottomSensorState()), + new WaitUntil(shootingTimer5sec::isDone) + ) + ); + } + public Command shootBalls(){ return new SequentialGroup( // Ensure the flywheel is up to speed, if not, spin up first @@ -85,7 +102,7 @@ public Command shootBalls(){ // Shoot the last ball setIntakeMode(Intake.intakeMode.SHOOTING), setTransferState(Intake.transferState.UP), - resetShootingTimer1sec(), + resetShootingTimerHalfsec(), new WaitUntil(shootingTimerHalfSec::isDone), // Reset the systems From 9559c00d27039491699a5d27eff16316e783d22c Mon Sep 17 00:00:00 2001 From: NotABitcoinScam <152728412+NotABitcoinScam@users.noreply.github.com> Date: Fri, 6 Feb 2026 16:20:50 -0500 Subject: [PATCH 11/13] Added the beginnings of the Prism class in Devices.java --- .../Main_/Hardware_/Actuators_/Devices.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Devices.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Devices.java index 1464fc9d6324..f54d91096f05 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Devices.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Devices.java @@ -14,6 +14,10 @@ import com.qualcomm.robotcore.hardware.Servo; import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit; +import org.firstinspires.ftc.teamcode.LOADCode.Main_.Hardware_.LoadHardwareClass; +import org.firstinspires.ftc.teamcode.Prism.Color; +import org.firstinspires.ftc.teamcode.Prism.GoBildaPrismDriver; +import org.firstinspires.ftc.teamcode.Prism.PrismAnimations; import dev.nextftc.control.ControlSystem; import dev.nextftc.control.KineticState; @@ -343,4 +347,22 @@ public Boolean getTriggered(){ return !sensor.getState(); } } + + public static class GoBildaPrismBarClass { + + GoBildaPrismDriver prism; + + PrismAnimations.Solid solidColor = new PrismAnimations.Solid(Color.BLUE); + PrismAnimations.Blink blinkAnim = new PrismAnimations.Blink(Color.BLUE); + + public void init(@NonNull OpMode opmode, String prismDeviceName, Integer stripLength){ + prism = opmode.hardwareMap.get(GoBildaPrismDriver.class,prismDeviceName); + prism.setStripLength(stripLength); + + } + + public void setColor(Color color){ + + } + } } \ No newline at end of file From 935cbc5db4f1f23131e773b190cc5ff63317de96 Mon Sep 17 00:00:00 2001 From: Professor348 <141444315+professor348@users.noreply.github.com> Date: Fri, 6 Feb 2026 19:29:02 -0500 Subject: [PATCH 12/13] Auto work --- .../LOADCode/Main_/Auto_/Auto_Main_.java | 40 +++++++-- .../Main_/Hardware_/Actuators_/Devices.java | 2 - .../Main_/Hardware_/Actuators_/Turret.java | 20 ++++- .../LOADCode/Main_/Hardware_/Commands.java | 3 +- .../Hardware_/Drivetrain_/Pedro_Paths.java | 85 ++++++++++++++++++- .../LOADCode/Main_/Teleop_/Teleop_Main_.java | 29 +++---- 6 files changed, 147 insertions(+), 32 deletions(-) diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Auto_/Auto_Main_.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Auto_/Auto_Main_.java index 2fb7804b7993..da86fb6bd9bf 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Auto_/Auto_Main_.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Auto_/Auto_Main_.java @@ -5,6 +5,7 @@ import androidx.annotation.NonNull; +import com.pedropathing.geometry.BezierLine; import com.pedropathing.geometry.Pose; import com.qualcomm.robotcore.eventloop.opmode.Autonomous; import com.skeletonarmy.marrow.prompts.OptionPrompt; @@ -18,7 +19,8 @@ import org.firstinspires.ftc.teamcode.LOADCode.Main_.Hardware_.LoadHardwareClass; import org.firstinspires.ftc.teamcode.pedroPathing.Constants; -import dev.nextftc.core.commands.delays.WaitUntil; +import dev.nextftc.core.commands.delays.Delay; +import dev.nextftc.core.commands.groups.ParallelRaceGroup; import dev.nextftc.core.commands.groups.SequentialGroup; import dev.nextftc.core.commands.utility.InstantCommand; import dev.nextftc.extensions.pedro.PedroComponent; @@ -306,11 +308,37 @@ public boolean getTurretEnabled(){ public void runAuto(){ double tempSpeed = 1; new SequentialGroup( - Commands.runPath(paths.farStart_to_midShoot,true, tempSpeed), - Commands.runPath(paths.midShoot_to_openGateIntake,true, tempSpeed), - new WaitUntil(() -> gamepad1.b), - Commands.runPath(paths.openGateIntake_to_farShoot,true, tempSpeed), - Commands.runPath(paths.farShoot_to_openGateIntake,true, tempSpeed) + new ParallelRaceGroup( + new Delay(29), + new SequentialGroup( + Commands.setFlywheelState(Turret.flywheelState.ON), + Commands.runPath(paths.farStart_to_farShoot, true, 1), + Commands.shootBalls(), + Commands.setIntakeMode(Intake.intakeMode.INTAKING), + Commands.runPath(paths.farShoot_to_farPreload, true, 1), + Commands.runPath(paths.farPreload_to_farShoot, true, 1), + Commands.shootBalls(), + Commands.setIntakeMode(Intake.intakeMode.INTAKING), + Commands.runPath(paths.farShoot_to_rampIntake, true, 1), + Commands.runPath(paths.rampIntake_to_farShoot, true, 1), + Commands.shootBalls(), + Commands.setIntakeMode(Intake.intakeMode.INTAKING), + Commands.runPath(paths.farShoot_to_hpPreload, true, 1), + Commands.runPath(paths.hpPreload_to_farShoot, true, 1), + Commands.shootBalls(), + Commands.runPath(paths.farShoot_to_farLeave, true, 1) + ) + ), + Commands.runPath( + Robot.drivetrain.follower.pathBuilder().addPath( + new BezierLine( + Robot.drivetrain.follower.getPose(), + paths.farLeave + ) + ).setLinearHeadingInterpolation( + Robot.drivetrain.follower.getPose().getHeading(), + paths.farLeave.getHeading() + ).build(), true, 1) ).schedule(); } diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Devices.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Devices.java index f54d91096f05..d1e96d7aaa04 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Devices.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Devices.java @@ -14,7 +14,6 @@ import com.qualcomm.robotcore.hardware.Servo; import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit; -import org.firstinspires.ftc.teamcode.LOADCode.Main_.Hardware_.LoadHardwareClass; import org.firstinspires.ftc.teamcode.Prism.Color; import org.firstinspires.ftc.teamcode.Prism.GoBildaPrismDriver; import org.firstinspires.ftc.teamcode.Prism.PrismAnimations; @@ -358,7 +357,6 @@ public static class GoBildaPrismBarClass { public void init(@NonNull OpMode opmode, String prismDeviceName, Integer stripLength){ prism = opmode.hardwareMap.get(GoBildaPrismDriver.class,prismDeviceName); prism.setStripLength(stripLength); - } public void setColor(Color color){ diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Turret.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Turret.java index 8b39f2b3010e..6f5ca3da4c54 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Turret.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Turret.java @@ -220,7 +220,7 @@ public void updateAimbotWithVelocity(){ */ public void setGateState(gatestate state){ if (state == gatestate.CLOSED){ - gate.setAngle(0.48); + gate.setAngle(0.47); }else if (state == gatestate.OPEN){ gate.setAngle(0.5); } @@ -263,14 +263,28 @@ public gatestate getGate(){ * Currently uses Pinpoint Odometry and trigonometry to get the angle. */ public double calcLocalizer (){ - Pose goalPose = new Pose(4,140,0); - if (LoadHardwareClass.selectedAlliance == LoadHardwareClass.Alliance.RED) {goalPose = new Pose(140, 140, 0);} + Pose goalPose = calcGoalPose(); return (Math.toDegrees(Math.atan2( goalPose.getY()-Robot.drivetrain.follower.getPose().getY(), goalPose.getX()-Robot.drivetrain.follower.getPose().getX()) ) - Math.toDegrees(Robot.drivetrain.follower.getPose().getHeading()) + 90)%360; } + public Pose calcGoalPose(){ + robotZone.setPosition(Robot.drivetrain.follower.getPose().getX(), Robot.drivetrain.follower.getPose().getY()); + robotZone.setRotation(Robot.drivetrain.follower.getPose().getHeading()); + + Pose nearGoalPose = new Pose(8,140,0); + if (LoadHardwareClass.selectedAlliance == LoadHardwareClass.Alliance.RED) {nearGoalPose = new Pose(140, 140, 0);} + Pose farGoalPose = new Pose(16,140,0); + if (LoadHardwareClass.selectedAlliance == LoadHardwareClass.Alliance.RED) {farGoalPose = new Pose(136, 140, 0);} + + if(robotZone.isInside(LoadHardwareClass.FarLaunchZone)){ + return farGoalPose; + }else{ + return nearGoalPose; + } + } /** * Sets the RPM of the flywheel. diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Commands.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Commands.java index 684d8bd47cda..92c8e64d5688 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Commands.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Commands.java @@ -108,8 +108,7 @@ public Command shootBalls(){ // Reset the systems setIntakeMode(Intake.intakeMode.OFF), setGateState(Turret.gatestate.CLOSED), - setTransferState(Intake.transferState.DOWN), - setFlywheelState(Turret.flywheelState.OFF) + setTransferState(Intake.transferState.DOWN) ); } diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Drivetrain_/Pedro_Paths.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Drivetrain_/Pedro_Paths.java index 631108236fc9..5681b74c4454 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Drivetrain_/Pedro_Paths.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Drivetrain_/Pedro_Paths.java @@ -23,8 +23,8 @@ public class Pedro_Paths { public Pose nearPreload = new Pose(124.000, 83.500, Math.toRadians(0)); public Pose midPreload = new Pose(130.000, 59.500, Math.toRadians(0)); public Pose farPreload = new Pose(130.000, 35.500, Math.toRadians(0)); - public Pose hpPreload = new Pose(136, 8, -90); - public Pose rampIntake = new Pose(133, 55, 65); + public Pose hpPreload = new Pose(135, 8, -90); + public Pose rampIntake = new Pose(135, 44, 80); public Pose hpIntake = null; // Shooting Poses public Pose nearShoot = new Pose(115, 120, Math.toRadians(-35)); @@ -77,10 +77,12 @@ public class Pedro_Paths { *

*

Human Player Preload Pose

*/ + public PathChain hpPreload_to_nearShoot, hpPreload_to_midShoot, hpPreload_to_farShoot; /** *

*

Ramp Intake Pose

*/ + public PathChain rampIntake_to_nearShoot, rampIntake_to_midShoot, rampIntake_to_farShoot; /** *

*

Human Player Random Intake Pose

@@ -101,6 +103,7 @@ public class Pedro_Paths { public PathChain midShoot_to_hpPreload, midShoot_to_hpIntake; public PathChain midShoot_to_nearLeave, midShoot_to_midLeave; public PathChain midShoot_to_openGateIntake, midShoot_to_openGateBasic; + public PathChain midShoot_to_rampIntake; /** *

*

Far Shooting Pose

@@ -109,6 +112,7 @@ public class Pedro_Paths { public PathChain farShoot_to_hpPreload, farShoot_to_hpIntake; public PathChain farShoot_to_midLeave, farShoot_to_farLeave; public PathChain farShoot_to_openGateIntake, farShoot_to_openGateBasic; + public PathChain farShoot_to_rampIntake; /** *

*

Open Gate Basic Pose (No Intake)

@@ -453,6 +457,7 @@ public void buildOpenGateBasicToShootings(){ farShoot )) .setLinearHeadingInterpolation(openGateBasic.getHeading(), farShoot.getHeading()) + .setVelocityConstraint(10) .build(); openGateBasic_to_midShoot = follower.pathBuilder() .addPath(new BezierCurve( @@ -481,6 +486,72 @@ public void buildPreloadsToOpenGateBasic(){ .setLinearHeadingInterpolation(midPreload.getHeading(), openGateBasicReversed.getHeading()) .build(); } + public void buildShootingsToHPPreload(){ + farShoot_to_hpPreload = follower.pathBuilder() + .addPath(new BezierCurve( + farShoot, + autoMirror(new Pose(136, 30)), + hpPreload + )) + .setLinearHeadingInterpolation(farShoot.getHeading(), hpPreload.getHeading()) + .build(); + midShoot_to_hpPreload = follower.pathBuilder() + .addPath(new BezierCurve( + midShoot, + autoMirror(new Pose(87, 28)), + autoMirror(new Pose(138, 42)), + hpPreload + )) + .setLinearHeadingInterpolation(midShoot.getHeading(), hpPreload.getHeading()) + .build(); + } + public void buildShootingsToRampIntake(){ + midShoot_to_rampIntake = follower.pathBuilder() + .addPath(new BezierCurve( + midShoot, + autoMirror(new Pose(85, 40)), + autoMirror(new Pose(137, 2)), + autoMirror(new Pose(135, 30, rampIntake.getHeading())) + )) + .setLinearHeadingInterpolation(midShoot.getHeading(), rampIntake.getHeading()) + .addPath(new BezierLine( + autoMirror(new Pose(135, 30, rampIntake.getHeading())), + rampIntake + )) + .setConstantHeadingInterpolation(rampIntake.getHeading()) + .build(); + farShoot_to_rampIntake = follower.pathBuilder() + .addPath(new BezierCurve( + farShoot, + autoMirror(new Pose(137, 2)), + autoMirror(new Pose(135, 30, rampIntake.getHeading())) + )) + .setLinearHeadingInterpolation(farShoot.getHeading(), rampIntake.getHeading()) + .addPath(new BezierLine( + autoMirror(new Pose(135, 30, rampIntake.getHeading())), + rampIntake + )) + .setConstantHeadingInterpolation(rampIntake.getHeading()) + .build(); + } + public void buildHPPreloadToShootings(){ + hpPreload_to_farShoot = follower.pathBuilder() + .addPath(new BezierLine( + hpPreload, + farShoot + )) + .setLinearHeadingInterpolation(hpPreload.getHeading(), farShoot.getHeading()) + .build(); + } + public void buildRampIntakeToShootings(){ + rampIntake_to_farShoot = follower.pathBuilder() + .addPath(new BezierLine( + rampIntake, + farShoot + )) + .setLinearHeadingInterpolation(rampIntake.getHeading(), farShoot.getHeading()) + .build(); + } /** @@ -492,23 +563,27 @@ public void buildPaths(Follower follow){ nearStart = autoMirror(nearStart); farStart = autoMirror(farStart); + nearPreload = autoMirror(nearPreload); midPreload = autoMirror(midPreload); farPreload = autoMirror(farPreload); + hpPreload = autoMirror(hpPreload); + nearShoot = autoMirror(nearShoot); midShoot = autoMirror(midShoot); farShoot = autoMirror(farShoot); noTurretMidShoot = autoMirror(noTurretMidShoot); noTurretFarShoot = autoMirror(noTurretFarShoot); + nearLeave = autoMirror(nearLeave); midLeave = autoMirror(midLeave); farLeave = autoMirror(farLeave); + openGateBasic = autoMirror(openGateBasic); openGateBasicReversed = autoMirror(openGateBasicReversed); openGateIntakeGate = autoMirror(openGateIntakeGate); openGateIntakeRamp = autoMirror(openGateIntakeRamp); - /// All paths are for the RED side of the field. they will be mirrored if necessary. // Paths going from each start position to each of the shooting positions. buildStart1ToShootings(); @@ -531,5 +606,9 @@ public void buildPaths(Follower follow){ buildOpenGateIntakeToShootings(); buildOpenGateBasicToShootings(); buildPreloadsToOpenGateBasic(); + buildShootingsToHPPreload(); + buildShootingsToRampIntake(); + buildRampIntakeToShootings(); + buildHPPreloadToShootings(); } } diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Teleop_/Teleop_Main_.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Teleop_/Teleop_Main_.java index 33355fd39233..c06932b58092 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Teleop_/Teleop_Main_.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Teleop_/Teleop_Main_.java @@ -65,7 +65,6 @@ public class Teleop_Main_ extends LinearOpMode { private final TelemetryManager panelsTelemetry = PanelsTelemetry.INSTANCE.getTelemetry(); public int shootingState = 0; - public boolean turretOn = true; public TimerEx stateTimer = new TimerEx(1); public double hoodOffset = 0; public Pose holdPoint = new Pose(72, 72, 90); @@ -116,11 +115,11 @@ public void runOpMode() { telemetry.addData("Alliance", selectedAlliance); if (MecanumDrivetrainClass.robotPose == null){ startPoses pose = prompter.get("startPose"); - if (pose.equals(startPoses.FAR)) { - startPose = Paths.autoMirror(Paths.farStart); + if (pose == startPoses.FAR) { + startPose = Paths.farStart; telemetry.addData("Start Pose", "Far Start Pose"); - } else if (pose.equals(startPoses.NEAR)) { - startPose = Paths.autoMirror(Paths.nearStart); + } else if (pose == startPoses.NEAR) { + startPose = Paths.nearStart; telemetry.addData("Start Pose", "Near Start Pose"); } }else{ @@ -138,7 +137,11 @@ public void runOpMode() { // Wait for the game to start (driver presses START) waitForStart(); // Initialize all hardware of the robot - Robot.init(startPose); + if (selectedAlliance == LoadHardwareClass.Alliance.BLUE){ + Robot.init(startPose.mirror()); + }else{ + Robot.init(startPose); + } runtime.reset(); Paths.buildPaths(Robot.drivetrain.follower); Robot.drivetrain.startTeleOpDrive(); @@ -163,9 +166,7 @@ public void runOpMode() { telemetry.addData("SpeedMult", Robot.drivetrain.speedMultiplier); telemetry.addLine(); //positional telemetry - telemetry.addData("X Position", Robot.drivetrain.follower.getPose().getX()); - telemetry.addData("Y Position", Robot.drivetrain.follower.getPose().getY()); - telemetry.addData("Heading", Math.toDegrees(Robot.drivetrain.follower.getPose().getHeading())); + telemetry.addData("Robot Position [X, Y, H]", "[" + Robot.drivetrain.follower.getPose().getX() + ", " + Robot.drivetrain.follower.getPose().getY() + ", " + Robot.drivetrain.follower.getPose().getHeading() + "]"); telemetry.addData("Distance From Goal", Robot.drivetrain.distanceFromGoal()); telemetry.addLine(); @@ -175,7 +176,8 @@ public void runOpMode() { telemetry.addData("Turret Target Angle", Robot.turret.rotation.target); telemetry.addData("Turret Actual Angle", Robot.turret.rotation.getAngleAbsolute()); telemetry.addData("Turret Hood Angle", Robot.turret.getHood()); - telemetry.addData("Turret Offset", hoodOffset); + telemetry.addData("Turret Hood Offset", hoodOffset); + telemetry.addData("Turret Target [X, Y]", "[" + Robot.turret.calcGoalPose().getX() + ", " + Robot.turret.calcGoalPose().getY() + "]"); telemetry.addLine(); panelsTelemetry.addData("Flywheel Target Speed", Robot.turret.flywheel.target); @@ -337,12 +339,7 @@ public void Gamepad1() { * */ public void Gamepad2() { - - // Turret Aimbot - if (gamepad2.aWasPressed()){ - turretOn = !turretOn; - } - Robot.turret.updateAimbot(turretOn, true, hoodOffset); + Robot.turret.updateAimbot(true, true, hoodOffset); double dylanStickDeadzones = 0.2; From 6393fcad87590e03ef7340cd14c66bfcfe80c8e1 Mon Sep 17 00:00:00 2001 From: Professor348 <141444315+professor348@users.noreply.github.com> Date: Sat, 7 Feb 2026 19:17:22 -0500 Subject: [PATCH 13/13] Final changes during Battle Below the Canal --- .../LOADCode/Main_/Auto_/Auto_Main_.java | 16 +++++++-------- .../Main_/Hardware_/Actuators_/Devices.java | 6 ++++++ .../LOADCode/Main_/Hardware_/Commands.java | 8 +++++++- .../Hardware_/Drivetrain_/Pedro_Paths.java | 2 +- .../LOADCode/Main_/Teleop_/Teleop_Main_.java | 20 +++++++++++++++++-- 5 files changed, 40 insertions(+), 12 deletions(-) diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Auto_/Auto_Main_.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Auto_/Auto_Main_.java index da86fb6bd9bf..1d87de7c799e 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Auto_/Auto_Main_.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Auto_/Auto_Main_.java @@ -60,11 +60,11 @@ public void onInit() { )); prompter.prompt("auto", new OptionPrompt<>("Select Auto", + new MOE_365_FAR(), new Near_12Ball(), new Near_9Ball(), new Far_9Ball(), - new Far_6Ball(), - new test_Auto() + new Far_6Ball() )); prompter.onComplete(() -> { selectedAlliance = prompter.get("alliance"); @@ -270,17 +270,14 @@ public void runAuto(){ new InstantCommand(Commands.setFlywheelState(Turret.flywheelState.ON)), Commands.runPath(paths.nearStart_to_midShoot, true, 1), Commands.shootBalls(), - Commands.setFlywheelState(Turret.flywheelState.ON), Commands.setIntakeMode(Intake.intakeMode.INTAKING), Commands.runPath(paths.midShoot_to_nearPreload, true, 1), Commands.runPath(paths.nearPreload_to_midShoot, true, 1), Commands.shootBalls(), - Commands.setFlywheelState(Turret.flywheelState.ON), Commands.setIntakeMode(Intake.intakeMode.INTAKING), Commands.runPath(paths.midShoot_to_midPreload, true, 1), Commands.runPath(paths.midPreload_to_midShoot, true, 1), Commands.shootBalls(), - Commands.setFlywheelState(Turret.flywheelState.ON), Commands.setIntakeMode(Intake.intakeMode.INTAKING), Commands.runPath(paths.midShoot_to_farPreload, true, 1), Commands.runPath(paths.farPreload_to_midShoot, true, 1), @@ -294,7 +291,7 @@ public void runAuto(){ public String toString(){return "Near Zone 12 Ball";} } - private class test_Auto extends Auto{ + private class MOE_365_FAR extends Auto{ @Override public Pose getStartPose(){ return paths.farStart; @@ -306,7 +303,6 @@ public boolean getTurretEnabled(){ @Override public void runAuto(){ - double tempSpeed = 1; new SequentialGroup( new ParallelRaceGroup( new Delay(29), @@ -326,6 +322,10 @@ public void runAuto(){ Commands.runPath(paths.farShoot_to_hpPreload, true, 1), Commands.runPath(paths.hpPreload_to_farShoot, true, 1), Commands.shootBalls(), + Commands.setIntakeMode(Intake.intakeMode.INTAKING), + Commands.runPath(paths.farShoot_to_hpPreload, true, 1), + Commands.runPath(paths.hpPreload_to_farShoot, true, 1), + Commands.shootBalls(), Commands.runPath(paths.farShoot_to_farLeave, true, 1) ) ), @@ -344,6 +344,6 @@ public void runAuto(){ @NonNull @Override - public String toString(){return "Test Auto";} + public String toString(){return "MOE 365 Far Zone Auto";} } } diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Devices.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Devices.java index d1e96d7aaa04..17e38a9656e7 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Devices.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Devices.java @@ -145,6 +145,12 @@ public void setOffsetTicks(double ticks){ public void setOffsetDegrees(double degrees){ setOffsetTicks(degrees * (ticksPerRotation/360)); } + public double getOffsetTicks(){ + return offset; + } + public double getOffsetDegrees(){ + return offset/(ticksPerRotation/360); + } /** * Sets the runMode of the motor. * @param runMode The mode to set the motor to. diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Commands.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Commands.java index 92c8e64d5688..64854aad2535 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Commands.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Commands.java @@ -25,9 +25,13 @@ public Commands(@NonNull LoadHardwareClass robot){ } // Delay timer for shooting sequence + private static final TimerEx shootingTimerFifthSec = new TimerEx(0.2); private static final TimerEx shootingTimerHalfSec = new TimerEx(0.5); private static final TimerEx shootingTimer2sec = new TimerEx(2); private static final TimerEx shootingTimer5sec = new TimerEx(5); + private static Command resetShootingTimerFifthsec() { + return new LambdaCommand("resetShootingTimer0.2sec").setStart(shootingTimerFifthSec::restart); + } private static Command resetShootingTimerHalfsec() { return new LambdaCommand("resetShootingTimer0.5sec").setStart(shootingTimerHalfSec::restart); } @@ -94,8 +98,10 @@ public Command shootBalls(){ setFlywheelState(Turret.flywheelState.ON), // Shoot the first two balls - setIntakeMode(Intake.intakeMode.INTAKING), setGateState(Turret.gatestate.OPEN), + resetShootingTimerFifthsec(), + new WaitUntil(shootingTimerFifthSec::isDone), + setIntakeMode(Intake.intakeMode.INTAKING), resetShootingTimer2sec(), new WaitUntil(() -> (Robot.intake.getTopSensorState() && !Robot.intake.getBottomSensorState() && shootingTimer2sec.isDone())), diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Drivetrain_/Pedro_Paths.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Drivetrain_/Pedro_Paths.java index 5681b74c4454..a94d1a2ae09e 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Drivetrain_/Pedro_Paths.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Drivetrain_/Pedro_Paths.java @@ -24,7 +24,7 @@ public class Pedro_Paths { public Pose midPreload = new Pose(130.000, 59.500, Math.toRadians(0)); public Pose farPreload = new Pose(130.000, 35.500, Math.toRadians(0)); public Pose hpPreload = new Pose(135, 8, -90); - public Pose rampIntake = new Pose(135, 44, 80); + public Pose rampIntake = new Pose(135, 40, 80); public Pose hpIntake = null; // Shooting Poses public Pose nearShoot = new Pose(115, 120, Math.toRadians(-35)); diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Teleop_/Teleop_Main_.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Teleop_/Teleop_Main_.java index c06932b58092..14a9a2bdd3b9 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Teleop_/Teleop_Main_.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Teleop_/Teleop_Main_.java @@ -67,6 +67,8 @@ public class Teleop_Main_ extends LinearOpMode { public int shootingState = 0; public TimerEx stateTimer = new TimerEx(1); public double hoodOffset = 0; + public double turretOffset = 0; + public boolean turretOn = true; public Pose holdPoint = new Pose(72, 72, 90); public Boolean holdJustTriggered = false; @@ -145,6 +147,7 @@ public void runOpMode() { runtime.reset(); Paths.buildPaths(Robot.drivetrain.follower); Robot.drivetrain.startTeleOpDrive(); + Robot.intake.setTransfer(transferState.DOWN); // run until the end of the match (driver presses STOP) while (opModeIsActive()) { @@ -162,6 +165,7 @@ public void runOpMode() { double flywheelPercentage = (int) Math.round(Robot.turret.getFlywheelRPM()/Robot.turret.getFlywheelCurrentMaxSpeed() *100); telemetry.addData("Flywheel Percentage", flywheelPercentage+"%"); panelsTelemetry.addData("Flywheel Percentage", flywheelPercentage+"%"); + telemetry.addData("ALLIANCE", selectedAlliance); telemetry.addData("SpeedMult", Robot.drivetrain.speedMultiplier); telemetry.addLine(); @@ -254,7 +258,7 @@ public void Gamepad1() { holdPoint = Robot.drivetrain.follower.getPose(); holdJustTriggered = true; } - Robot.drivetrain.follower.holdPoint(holdPoint); + //Robot.drivetrain.follower.holdPoint(holdPoint); } else if (gamepad1.left_trigger >= ariDeadZone) { if (holdJustTriggered){ Robot.drivetrain.follower.startTeleOpDrive(); @@ -339,7 +343,11 @@ public void Gamepad1() { * */ public void Gamepad2() { - Robot.turret.updateAimbot(true, true, hoodOffset); + if (gamepad2.aWasPressed()){ + turretOn = !turretOn; + } + Robot.turret.updateAimbot(turretOn, true, hoodOffset); + Robot.turret.rotation.setOffsetDegrees(Robot.turret.rotation.getOffsetDegrees() + turretOffset); double dylanStickDeadzones = 0.2; @@ -385,6 +393,11 @@ public void Gamepad2() { }else if (gamepad2.dpadDownWasPressed()){ hoodOffset -= 10; } + if (gamepad2.dpadLeftWasPressed()){ + turretOffset += 2; + }else if (gamepad2.dpadLeftWasPressed()){ + turretOffset -= 2; + } //Shoot (B Button Press) @@ -392,6 +405,9 @@ public void Gamepad2() { if (gamepad2.bWasPressed() && shootingState < 1 && Robot.turret.getFlywheelRPM() > Robot.turret.getFlywheelCurrentMaxSpeed()-100) { shootingState++; } + if (gamepad2.xWasPressed()){ + shootingState = 3; + } switch (shootingState) { case 0: telemetry.addData("Shooting State", "OFF");

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 Date: Tue, 20 Jan 2026 19:13:42 -0500 Subject: [PATCH 02/13] Retuned pedro for new sprockets, retuned turret rotation PID, & added holdPosition function to Teleop_Main_ --- .../LOADCode/Main_/Auto_/Auto_Main_.java | 95 ++++++++++--------- .../Main_/Hardware_/Actuators_/Turret.java | 54 +++++++---- .../LOADCode/Main_/Hardware_/Commands.java | 18 ++-- .../Hardware_/Drivetrain_/Pedro_Paths.java | 37 ++++++-- .../LOADCode/Main_/Teleop_/Teleop_Main_.java | 52 ++++++---- .../ftc/teamcode/pedroPathing/Constants.java | 14 +-- .../ftc/teamcode/pedroPathing/Tuning.java | 2 +- 7 files changed, 171 insertions(+), 101 deletions(-) diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Auto_/Auto_Main_.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Auto_/Auto_Main_.java index 978d0c6fa1e8..4bd7c93301dd 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Auto_/Auto_Main_.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Auto_/Auto_Main_.java @@ -18,7 +18,6 @@ import org.firstinspires.ftc.teamcode.LOADCode.Main_.Hardware_.LoadHardwareClass; import org.firstinspires.ftc.teamcode.pedroPathing.Constants; -import dev.nextftc.core.commands.delays.Delay; import dev.nextftc.core.commands.groups.SequentialGroup; import dev.nextftc.core.commands.utility.InstantCommand; import dev.nextftc.extensions.pedro.PedroComponent; @@ -60,7 +59,8 @@ public void onInit() { new OptionPrompt<>("Select Auto", new Near_12Ball(), new Near_9Ball(), - new Leave_Far_Generic() + new Far_9Ball(), + new Far_6Ball() //new test_Auto(), //new Complex_Test_Auto() )); @@ -142,7 +142,14 @@ abstract static class Auto{ // startPose = startingPose; // } + /** + * @return The start pose of the robot for this auto. + */ abstract Pose getStartPose(); + + /** + * @return A boolean indicating whether the turret is enabled. + */ abstract boolean getTurretEnabled(); /** Override this to schedule the auto command*/ @@ -153,9 +160,9 @@ abstract static class Auto{ public abstract String toString(); } - private class Leave_Far_Generic extends Auto{ + private class Far_6Ball extends Auto{ public Pose startPose = paths.farStart; - public boolean turretEnabled = false; + public boolean turretEnabled = true; @Override public Pose getStartPose(){ @@ -169,21 +176,24 @@ public boolean getTurretEnabled(){ @Override public void runAuto(){ new SequentialGroup( - Commands.runPath(paths.farStart_to_NoTurret_FarShoot, true, 1), + Commands.runPath(paths.farStart_to_farShoot, true, 1), Commands.shootBalls(), + Commands.setFlywheelState(Turret.flywheelState.ON), Commands.setIntakeMode(Intake.intakeMode.INTAKING), Commands.runPath(paths.farShoot_noTurret_to_farPreload, true, 1), - Commands.setIntakeMode(Intake.intakeMode.OFF) + Commands.runPath(paths.farPreload_to_farShoot, true, 1), + Commands.shootBalls(), + Commands.runPath(paths.farShoot_to_farLeave, true, 1) ).schedule(); } @NonNull @Override - public String toString(){return "Far Zone No Turret Generic";} + public String toString(){return "Far Zone 6 Ball";} } - private class Near_9Ball extends Auto{ - public Pose startPose = paths.nearStart; + private class Far_9Ball extends Auto{ + public Pose startPose = paths.farStart; public boolean turretEnabled = true; @Override @@ -198,30 +208,28 @@ public boolean getTurretEnabled(){ @Override public void runAuto(){ new SequentialGroup( - Commands.setIntakeMode(Intake.intakeMode.INTAKING), - new InstantCommand(Commands.setFlywheelState(Turret.flywheelState.ON)), - Commands.runPath(paths.nearStart_to_midShoot, true, 1), + Commands.runPath(paths.farStart_to_farShoot, true, 1), Commands.shootBalls(), Commands.setFlywheelState(Turret.flywheelState.ON), Commands.setIntakeMode(Intake.intakeMode.INTAKING), - Commands.runPath(paths.midShoot_to_nearPreload, true, 1), - Commands.runPath(paths.nearPreload_to_midShoot, true, 1), + Commands.runPath(paths.farShoot_to_farPreload, true, 1), + Commands.runPath(paths.farPreload_to_farShoot, true, 1), Commands.shootBalls(), Commands.setFlywheelState(Turret.flywheelState.ON), Commands.setIntakeMode(Intake.intakeMode.INTAKING), - Commands.runPath(paths.midShoot_to_midPreload, true, 1), - Commands.runPath(paths.midPreload_to_midShoot, true, 1), + Commands.runPath(paths.farShoot_to_midPreload, true, 1), + Commands.runPath(paths.midPreload_to_farShoot, true, 1), Commands.shootBalls(), - Commands.runPath(paths.midShoot_to_nearLeave, true, 1) + Commands.runPath(paths.farShoot_to_farLeave, true, 1) ).schedule(); } @NonNull @Override - public String toString(){return "Near Zone 9 Ball Auto";} + public String toString(){return "Far Zone 9 Ball";} } - private class Near_12Ball extends Auto{ + private class Near_9Ball extends Auto{ public Pose startPose = paths.nearStart; public boolean turretEnabled = true; @@ -251,25 +259,17 @@ public void runAuto(){ Commands.runPath(paths.midShoot_to_midPreload, true, 1), Commands.runPath(paths.midPreload_to_midShoot, true, 1), Commands.shootBalls(), - Commands.setFlywheelState(Turret.flywheelState.ON), - Commands.setIntakeMode(Intake.intakeMode.INTAKING), - Commands.runPath(paths.midShoot_to_farPreload, true, 1), - Commands.runPath(paths.farPreload_to_midShoot, true, 1), - Commands.shootBalls(), Commands.runPath(paths.midShoot_to_nearLeave, true, 1) ).schedule(); } @NonNull @Override - public String toString(){return "Near Zone 12 Ball Auto";} + public String toString(){return "Near Zone 9 Ball";} } - /** - * This auto starts at the far zone - */ - private class Complex_Test_Auto extends Auto{ - public Pose startPose = paths.farStart; + private class Near_12Ball extends Auto{ + public Pose startPose = paths.nearStart; public boolean turretEnabled = true; @Override @@ -282,29 +282,34 @@ public boolean getTurretEnabled(){ } @Override - void runAuto() { + public void runAuto(){ new SequentialGroup( - new Delay(1), - //Commands.shootBalls(), Commands.setIntakeMode(Intake.intakeMode.INTAKING), - Commands.runPath(paths.farStart_to_farPreload, true, 1), - Commands.setIntakeMode(Intake.intakeMode.OFF), - Commands.runPath(paths.farPreload_to_farShoot, true, 1), - //Commands.shootBalls(), + new InstantCommand(Commands.setFlywheelState(Turret.flywheelState.ON)), + Commands.runPath(paths.nearStart_to_midShoot, true, 1), + Commands.shootBalls(), + Commands.setFlywheelState(Turret.flywheelState.ON), Commands.setIntakeMode(Intake.intakeMode.INTAKING), - Commands.runPath(paths.farStart_to_midPreload, true, 1), - Commands.setIntakeMode(Intake.intakeMode.OFF), - Commands.runPath(paths.midPreload_to_farShoot, true, 1), - //Commands.shootBalls(), - Commands.runPath(paths.farShoot_to_farLeave, true, 1) + Commands.runPath(paths.midShoot_to_nearPreload, true, 1), + Commands.runPath(paths.nearPreload_to_midShoot, true, 1), + Commands.shootBalls(), + Commands.setFlywheelState(Turret.flywheelState.ON), + Commands.setIntakeMode(Intake.intakeMode.INTAKING), + Commands.runPath(paths.midShoot_to_midPreload, true, 1), + Commands.runPath(paths.midPreload_to_midShoot, true, 1), + Commands.shootBalls(), + Commands.setFlywheelState(Turret.flywheelState.ON), + Commands.setIntakeMode(Intake.intakeMode.INTAKING), + Commands.runPath(paths.midShoot_to_farPreload, true, 1), + Commands.runPath(paths.farPreload_to_midShoot, true, 1), + Commands.shootBalls(), + Commands.runPath(paths.midShoot_to_nearLeave, true, 1) ).schedule(); } @NonNull @Override - public String toString() { - return "Complex Test Auto"; - } + public String toString(){return "Near Zone 12 Ball";} } private class test_Auto extends Auto{ diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Turret.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Turret.java index e2682fb4795e..225b84840565 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Turret.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Actuators_/Turret.java @@ -26,7 +26,7 @@ public class Turret { public final Devices.REVHallEffectSensorClass hall = new Devices.REVHallEffectSensorClass(); // Offset 20 degrees from directly forwards // Turret PID coefficients - public static PIDCoefficients turretCoefficients = new PIDCoefficients(0.02, 0.00000000005, 0.004); // 223RPM Motor + public static PIDCoefficients turretCoefficients = new PIDCoefficients(0.07, 0.00000000001, 0.003); // 223RPM Motor // Flywheel PID coefficients for various speeds //public static PIDCoefficients flywheelCoefficients = new PIDCoefficients(0.0002, 0, 0); // 4500 RPM @@ -78,7 +78,8 @@ public enum flywheelState { PolygonZone robotZone = new PolygonZone(15, 15); // The variable to store the InterpLUT table for turret hood aimbot - public Utils_.InterpLUT hoodLUT = new Utils_.InterpLUT(); + public Utils_.InterpLUT hoodLUTnear = new Utils_.InterpLUT(); + public Utils_.InterpLUT hoodLUTfar = new Utils_.InterpLUT(); public void init(OpMode opmode, LoadHardwareClass robot){ // Store important objects in their respective variables @@ -118,22 +119,30 @@ public void init(OpMode opmode, LoadHardwareClass robot){ flywheel2.setFFCoefficients(actualFlywheelFFCoefficients); // TODO Build hood InterpLUT for autoaim + // Safety points for LUTs + hoodLUTnear.add(0, 0); + hoodLUTfar.add(0, 0); + // Near zone measurements - hoodLUT.add(0, 0); - hoodLUT.add(53.5,108); - hoodLUT.add(71,168); - hoodLUT.add(77, 181); - hoodLUT.add(88,190); - hoodLUT.add(94.5,190); + hoodLUTnear.add(0, 0); + hoodLUTnear.add(53.5,108); + hoodLUTnear.add(71,168); + hoodLUTnear.add(77, 181); + hoodLUTnear.add(88,185); + hoodLUTnear.add(94.5,185); + hoodLUTnear.add(96, 180); + // Far zone measurements - hoodLUT.add(103, 200); - hoodLUT.add(204, 200); + hoodLUTfar.add(103, 200); + hoodLUTfar.add(204, 200); + + // Safety points for LUTs + hoodLUTnear.add(300, 200); + hoodLUTfar.add(300, 200); // Generate Lookup Table & Initialize servo position - hoodLUT.createLUT(); - Pose goalPose = new Pose(0,144,0); - if (LoadHardwareClass.selectedAlliance == LoadHardwareClass.Alliance.RED) {goalPose = new Pose(144, 144, 0);} - //setHood(hoodLUT.get(Robot.drivetrain.follower.getPose().distanceFrom(goalPose))); + hoodLUTnear.createLUT(); + hoodLUTfar.createLUT(); setHood(0); } @@ -161,6 +170,10 @@ public void updatePIDs(){ * Otherwise, sets the hood to the highest launch angle. */ public void updateAimbot(boolean turret, boolean hood, double hoodOffset){ + + robotZone.setPosition(Robot.drivetrain.follower.getPose().getX(), Robot.drivetrain.follower.getPose().getY()); + robotZone.setRotation(Robot.drivetrain.follower.getPose().getHeading()); + if (turret){ // Set the turret rotation if (LoadHardwareClass.selectedAlliance == LoadHardwareClass.Alliance.RED){ @@ -175,7 +188,12 @@ public void updateAimbot(boolean turret, boolean hood, double hoodOffset){ // Set the hood angle Pose goalPose = new Pose(0,144,0); if (LoadHardwareClass.selectedAlliance == LoadHardwareClass.Alliance.RED) {goalPose = new Pose(144, 144, 0);} - setHood(hoodLUT.get(Robot.drivetrain.follower.getPose().distanceFrom(goalPose)) + hoodOffset); + if (robotZone.isInside(LoadHardwareClass.FarLaunchZone)){ + setHood(hoodLUTfar.get(Robot.drivetrain.follower.getPose().distanceFrom(goalPose))); + }else{ + setHood(hoodLUTnear.get(Robot.drivetrain.follower.getPose().distanceFrom(goalPose))); + } + setHood(getHood() + hoodOffset); }else{ setHood(0); } @@ -199,7 +217,7 @@ public void updateAimbotWithVelocity(){ */ public void setGateState(gatestate state){ if (state == gatestate.CLOSED){ - gate.setAngle(0.47); + gate.setAngle(0.48); }else if (state == gatestate.OPEN){ gate.setAngle(0.5); } @@ -242,8 +260,8 @@ public gatestate getGate(){ * Currently uses Pinpoint Odometry and trigonometry to get the angle. */ public double calcLocalizer (){ - Pose goalPose = new Pose(0-posOffset,144+posOffset,0); - if (LoadHardwareClass.selectedAlliance == LoadHardwareClass.Alliance.RED) {goalPose = new Pose(144+posOffset, 144+posOffset, 0);} + Pose goalPose = new Pose(4,140,0); + if (LoadHardwareClass.selectedAlliance == LoadHardwareClass.Alliance.RED) {goalPose = new Pose(140, 140, 0);} return (Math.toDegrees(Math.atan2( goalPose.getY()-Robot.drivetrain.follower.getPose().getY(), diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Commands.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Commands.java index 248a3e8939e8..f9b926519ea7 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Commands.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Commands.java @@ -24,9 +24,13 @@ public Commands(@NonNull LoadHardwareClass robot){ } // Delay timer for shooting sequence - private static final TimerEx shootingTimer = new TimerEx(1); - private static Command resetShootingTimer() { - return new LambdaCommand("resetShootingTimer").setStart(shootingTimer::restart); + private static final TimerEx shootingTimerHalfSec = new TimerEx(0.5); + private static final TimerEx shootingTimer2sec = new TimerEx(2); + private static Command resetShootingTimer1sec() { + return new LambdaCommand("resetShootingTimer1.5sec").setStart(shootingTimerHalfSec::restart); + } + private static Command resetShootingTimer2sec() { + return new LambdaCommand("resetShootingTimer2sec").setStart(shootingTimer2sec::restart); } public Command runPath(PathChain path, boolean holdEnd, double maxPower) { @@ -75,14 +79,14 @@ public Command shootBalls(){ // Shoot the first two balls setIntakeMode(Intake.intakeMode.INTAKING), setGateState(Turret.gatestate.OPEN), - resetShootingTimer(), - new WaitUntil(() -> Robot.intake.getTopSensorState() && !Robot.intake.getBottomSensorState() && shootingTimer.isDone()), + resetShootingTimer2sec(), + new WaitUntil(() -> (Robot.intake.getTopSensorState() && !Robot.intake.getBottomSensorState() && shootingTimer2sec.isDone())), // Shoot the last ball setIntakeMode(Intake.intakeMode.SHOOTING), setTransferState(Intake.transferState.UP), - resetShootingTimer(), - new WaitUntil(shootingTimer::isDone), + resetShootingTimer1sec(), + new WaitUntil(shootingTimerHalfSec::isDone), // Reset the systems setIntakeMode(Intake.intakeMode.OFF), diff --git a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Drivetrain_/Pedro_Paths.java b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Drivetrain_/Pedro_Paths.java index 5a18905eb4d1..88e094208303 100644 --- a/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Drivetrain_/Pedro_Paths.java +++ b/TeamCode/src/main/java/org/firstinspires/ftc/teamcode/LOADCode/Main_/Hardware_/Drivetrain_/Pedro_Paths.java @@ -19,9 +19,9 @@ public class Pedro_Paths { public Pose nearStart = new Pose(118, 132, Math.toRadians(306)); public Pose farStart = new Pose(88, 7.4, Math.toRadians(90)); // Preload Poses - public Pose nearPreload = new Pose(127.000, 83.500, Math.toRadians(0)); - public Pose midPreload = new Pose(132.000, 59.500, Math.toRadians(0)); - public Pose farPreload = new Pose(132.000, 35.500, Math.toRadians(0)); + public Pose nearPreload = new Pose(124.000, 83.500, Math.toRadians(0)); + public Pose midPreload = new Pose(130.000, 59.500, Math.toRadians(0)); + public Pose farPreload = new Pose(130.000, 35.500, Math.toRadians(0)); // Shooting Poses public Pose nearShoot = new Pose(115, 120, Math.toRadians(-35)); public Pose midShoot = new Pose(85, 85, Math.toRadians(-15)); @@ -31,7 +31,7 @@ public class Pedro_Paths { // Leave Poses public Pose nearLeave = new Pose(90,120, Math.toRadians(90)); public Pose midLeave = new Pose(95,55, Math.toRadians(90)); - public Pose farLeave = new Pose(115,20, Math.toRadians(90)); + public Pose farLeave = new Pose(105,20, Math.toRadians(90)); /** *