{"version":3,"file":"slateboxjs.mjs","sources":["../node_modules/@svgdotjs/svg.js/src/utils/methods.js","../node_modules/@svgdotjs/svg.js/src/utils/utils.js","../node_modules/@svgdotjs/svg.js/src/modules/core/namespaces.js","../node_modules/@svgdotjs/svg.js/src/utils/window.js","../node_modules/@svgdotjs/svg.js/src/types/Base.js","../node_modules/@svgdotjs/svg.js/src/utils/adopter.js","../node_modules/@svgdotjs/svg.js/src/modules/optional/arrange.js","../node_modules/@svgdotjs/svg.js/src/modules/core/regex.js","../node_modules/@svgdotjs/svg.js/src/modules/optional/class.js","../node_modules/@svgdotjs/svg.js/src/modules/optional/css.js","../node_modules/@svgdotjs/svg.js/src/modules/optional/data.js","../node_modules/@svgdotjs/svg.js/src/modules/optional/memory.js","../node_modules/@svgdotjs/svg.js/src/types/Color.js","../node_modules/@svgdotjs/svg.js/src/types/Point.js","../node_modules/@svgdotjs/svg.js/src/types/Matrix.js","../node_modules/@svgdotjs/svg.js/src/modules/core/parser.js","../node_modules/@svgdotjs/svg.js/src/types/Box.js","../node_modules/@svgdotjs/svg.js/src/types/List.js","../node_modules/@svgdotjs/svg.js/src/modules/core/selector.js","../node_modules/@svgdotjs/svg.js/src/modules/core/event.js","../node_modules/@svgdotjs/svg.js/src/types/EventTarget.js","../node_modules/@svgdotjs/svg.js/src/modules/core/defaults.js","../node_modules/@svgdotjs/svg.js/src/types/SVGArray.js","../node_modules/@svgdotjs/svg.js/src/types/SVGNumber.js","../node_modules/@svgdotjs/svg.js/src/modules/core/attr.js","../node_modules/@svgdotjs/svg.js/src/elements/Dom.js","../node_modules/@svgdotjs/svg.js/src/elements/Element.js","../node_modules/@svgdotjs/svg.js/src/modules/optional/sugar.js","../node_modules/@svgdotjs/svg.js/src/modules/optional/transform.js","../node_modules/@svgdotjs/svg.js/src/elements/Container.js","../node_modules/@svgdotjs/svg.js/src/elements/Defs.js","../node_modules/@svgdotjs/svg.js/src/elements/Shape.js","../node_modules/@svgdotjs/svg.js/src/modules/core/circled.js","../node_modules/@svgdotjs/svg.js/src/elements/Ellipse.js","../node_modules/@svgdotjs/svg.js/src/elements/Fragment.js","../node_modules/@svgdotjs/svg.js/src/modules/core/gradiented.js","../node_modules/@svgdotjs/svg.js/src/elements/Gradient.js","../node_modules/@svgdotjs/svg.js/src/elements/Pattern.js","../node_modules/@svgdotjs/svg.js/src/elements/Image.js","../node_modules/@svgdotjs/svg.js/src/types/PointArray.js","../node_modules/@svgdotjs/svg.js/src/modules/core/pointed.js","../node_modules/@svgdotjs/svg.js/src/elements/Line.js","../node_modules/@svgdotjs/svg.js/src/elements/Marker.js","../node_modules/@svgdotjs/svg.js/src/animation/Controller.js","../node_modules/@svgdotjs/svg.js/src/utils/pathParser.js","../node_modules/@svgdotjs/svg.js/src/types/PathArray.js","../node_modules/@svgdotjs/svg.js/src/animation/Morphable.js","../node_modules/@svgdotjs/svg.js/src/elements/Path.js","../node_modules/@svgdotjs/svg.js/src/modules/core/poly.js","../node_modules/@svgdotjs/svg.js/src/elements/Polygon.js","../node_modules/@svgdotjs/svg.js/src/elements/Polyline.js","../node_modules/@svgdotjs/svg.js/src/elements/Rect.js","../node_modules/@svgdotjs/svg.js/src/animation/Queue.js","../node_modules/@svgdotjs/svg.js/src/animation/Animator.js","../node_modules/@svgdotjs/svg.js/src/animation/Timeline.js","../node_modules/@svgdotjs/svg.js/src/animation/Runner.js","../node_modules/@svgdotjs/svg.js/src/elements/Svg.js","../node_modules/@svgdotjs/svg.js/src/elements/Symbol.js","../node_modules/@svgdotjs/svg.js/src/modules/core/textable.js","../node_modules/@svgdotjs/svg.js/src/elements/Text.js","../node_modules/@svgdotjs/svg.js/src/elements/Tspan.js","../node_modules/@svgdotjs/svg.js/src/elements/Circle.js","../node_modules/@svgdotjs/svg.js/src/elements/ClipPath.js","../node_modules/@svgdotjs/svg.js/src/elements/ForeignObject.js","../node_modules/@svgdotjs/svg.js/src/modules/core/containerGeometry.js","../node_modules/@svgdotjs/svg.js/src/elements/G.js","../node_modules/@svgdotjs/svg.js/src/elements/A.js","../node_modules/@svgdotjs/svg.js/src/elements/Mask.js","../node_modules/@svgdotjs/svg.js/src/elements/Stop.js","../node_modules/@svgdotjs/svg.js/src/elements/Style.js","../node_modules/@svgdotjs/svg.js/src/elements/TextPath.js","../node_modules/@svgdotjs/svg.js/src/elements/Use.js","../node_modules/@svgdotjs/svg.js/src/main.js","../node_modules/@svgdotjs/svg.draggable.js/src/svg.draggable.js","../node_modules/@svgdotjs/svg.panzoom.js/dist/svg.panzoom.esm.js","../node_modules/@svgdotjs/svg.select.js/dist/svg.select.js","../node_modules/@svgdotjs/svg.resize.js/dist/svg.resize.js","../src/vendor/svg-connectable/utils/geometry.js","../src/vendor/svg-connectable/utils/markers.js","../src/vendor/svg-connectable/utils/handles.js","../src/vendor/svg-connectable/utils/interactions.js","../src/vendor/svg-connectable/svg.connectable.js","../src/core/ResizeRotate.ts","../src/core/Connector.ts","../src/core/Relationship.ts","../src/core/Relationships.ts","../src/core/Images.ts","../src/core/FontLoader.ts","../src/core/Editor.ts","../src/core/Links.ts","../src/vendor/raphael-path.ts","../src/utils.ts","../src/core/Animations.ts","../src/core/Filters.ts","../src/core/Menu.ts","../src/core/ShapeRegistry.ts","../src/core/compat.ts","../src/core/Node.ts","../src/core/NodesManager.ts","../src/core/Serialization.ts","../src/core/Invoker.ts","../src/core/PanZoom.ts","../src/core/BirdsEye.ts","../src/core/UndoRedo.ts","../src/core/MultiSelection.ts","../src/core/Grid.ts","../src/core/Keyboard.ts","../src/core/ContextMenu.ts","../src/core/Export.ts","../src/core/Collab.ts","../src/core/Theme.ts","../src/core/Layout.ts","../src/core/ZoomSlider.ts","../src/core/Presentation.ts","../src/core/Slate.ts","../src/core/Comments.ts","../src/compat-facade.ts","../src/index.ts"],"sourcesContent":["const methods = {}\nconst names = []\n\nexport function registerMethods(name, m) {\n  if (Array.isArray(name)) {\n    for (const _name of name) {\n      registerMethods(_name, m)\n    }\n    return\n  }\n\n  if (typeof name === 'object') {\n    for (const _name in name) {\n      registerMethods(_name, name[_name])\n    }\n    return\n  }\n\n  addMethodNames(Object.getOwnPropertyNames(m))\n  methods[name] = Object.assign(methods[name] || {}, m)\n}\n\nexport function getMethodsFor(name) {\n  return methods[name] || {}\n}\n\nexport function getMethodNames() {\n  return [...new Set(names)]\n}\n\nexport function addMethodNames(_names) {\n  names.push(..._names)\n}\n","// Map function\nexport function map(array, block) {\n  let i\n  const il = array.length\n  const result = []\n\n  for (i = 0; i < il; i++) {\n    result.push(block(array[i]))\n  }\n\n  return result\n}\n\n// Filter function\nexport function filter(array, block) {\n  let i\n  const il = array.length\n  const result = []\n\n  for (i = 0; i < il; i++) {\n    if (block(array[i])) {\n      result.push(array[i])\n    }\n  }\n\n  return result\n}\n\n// Degrees to radians\nexport function radians(d) {\n  return ((d % 360) * Math.PI) / 180\n}\n\n// Radians to degrees\nexport function degrees(r) {\n  return ((r * 180) / Math.PI) % 360\n}\n\n// Convert camel cased string to dash separated\nexport function unCamelCase(s) {\n  return s.replace(/([A-Z])/g, function (m, g) {\n    return '-' + g.toLowerCase()\n  })\n}\n\n// Capitalize first letter of a string\nexport function capitalize(s) {\n  return s.charAt(0).toUpperCase() + s.slice(1)\n}\n\n// Calculate proportional width and height values when necessary\nexport function proportionalSize(element, width, height, box) {\n  if (width == null || height == null) {\n    box = box || element.bbox()\n\n    if (width == null) {\n      width = (box.width / box.height) * height\n    } else if (height == null) {\n      height = (box.height / box.width) * width\n    }\n  }\n\n  return {\n    width: width,\n    height: height\n  }\n}\n\n/**\n * This function adds support for string origins.\n * It searches for an origin in o.origin o.ox and o.originX.\n * This way, origin: {x: 'center', y: 50} can be passed as well as ox: 'center', oy: 50\n **/\nexport function getOrigin(o, element) {\n  const origin = o.origin\n  // First check if origin is in ox or originX\n  let ox = o.ox != null ? o.ox : o.originX != null ? o.originX : 'center'\n  let oy = o.oy != null ? o.oy : o.originY != null ? o.originY : 'center'\n\n  // Then check if origin was used and overwrite in that case\n  if (origin != null) {\n    ;[ox, oy] = Array.isArray(origin)\n      ? origin\n      : typeof origin === 'object'\n        ? [origin.x, origin.y]\n        : [origin, origin]\n  }\n\n  // Make sure to only call bbox when actually needed\n  const condX = typeof ox === 'string'\n  const condY = typeof oy === 'string'\n  if (condX || condY) {\n    const { height, width, x, y } = element.bbox()\n\n    // And only overwrite if string was passed for this specific axis\n    if (condX) {\n      ox = ox.includes('left')\n        ? x\n        : ox.includes('right')\n          ? x + width\n          : x + width / 2\n    }\n\n    if (condY) {\n      oy = oy.includes('top')\n        ? y\n        : oy.includes('bottom')\n          ? y + height\n          : y + height / 2\n    }\n  }\n\n  // Return the origin as it is if it wasn't a string\n  return [ox, oy]\n}\n\nconst descriptiveElements = new Set(['desc', 'metadata', 'title'])\nexport const isDescriptive = (element) =>\n  descriptiveElements.has(element.nodeName)\n\nexport const writeDataToDom = (element, data, defaults = {}) => {\n  const cloned = { ...data }\n\n  for (const key in cloned) {\n    if (cloned[key].valueOf() === defaults[key]) {\n      delete cloned[key]\n    }\n  }\n\n  if (Object.keys(cloned).length) {\n    element.node.setAttribute('data-svgjs', JSON.stringify(cloned)) // see #428\n  } else {\n    element.node.removeAttribute('data-svgjs')\n    element.node.removeAttribute('svgjs:data')\n  }\n}\n","// Default namespaces\nexport const svg = 'http://www.w3.org/2000/svg'\nexport const html = 'http://www.w3.org/1999/xhtml'\nexport const xmlns = 'http://www.w3.org/2000/xmlns/'\nexport const xlink = 'http://www.w3.org/1999/xlink'\n","export const globals = {\n  window: typeof window === 'undefined' ? null : window,\n  document: typeof document === 'undefined' ? null : document\n}\n\nexport function registerWindow(win = null, doc = null) {\n  globals.window = win\n  globals.document = doc\n}\n\nconst save = {}\n\nexport function saveWindow() {\n  save.window = globals.window\n  save.document = globals.document\n}\n\nexport function restoreWindow() {\n  globals.window = save.window\n  globals.document = save.document\n}\n\nexport function withWindow(win, fn) {\n  saveWindow()\n  registerWindow(win, win.document)\n  fn(win, win.document)\n  restoreWindow()\n}\n\nexport function getWindow() {\n  return globals.window\n}\n","export default class Base {\n  // constructor (node/*, {extensions = []} */) {\n  //   // this.tags = []\n  //   //\n  //   // for (let extension of extensions) {\n  //   //   extension.setup.call(this, node)\n  //   //   this.tags.push(extension.name)\n  //   // }\n  // }\n}\n","import { addMethodNames } from './methods.js'\nimport { capitalize } from './utils.js'\nimport { svg } from '../modules/core/namespaces.js'\nimport { globals } from '../utils/window.js'\nimport Base from '../types/Base.js'\n\nconst elements = {}\nexport const root = '___SYMBOL___ROOT___'\n\n// Method for element creation\nexport function create(name, ns = svg) {\n  // create element\n  return globals.document.createElementNS(ns, name)\n}\n\nexport function makeInstance(element, isHTML = false) {\n  if (element instanceof Base) return element\n\n  if (typeof element === 'object') {\n    return adopter(element)\n  }\n\n  if (element == null) {\n    return new elements[root]()\n  }\n\n  if (typeof element === 'string' && element.trim().charAt(0) !== '<') {\n    return adopter(globals.document.querySelector(element))\n  }\n\n  // Make sure, that HTML elements are created with the correct namespace\n  const wrapper = isHTML ? globals.document.createElement('div') : create('svg')\n  wrapper.innerHTML = element.trim()\n\n  // We use firstElementChild here to skip potential comment nodes (#1339),\n  element = adopter(wrapper.firstElementChild)\n\n  // make sure, that element doesn't have its wrapper attached\n  wrapper.removeChild(wrapper.firstElementChild)\n  return element\n}\n\nexport function nodeOrNew(name, node) {\n  return node &&\n    (node instanceof globals.window.Node ||\n      (node.ownerDocument &&\n        node instanceof node.ownerDocument.defaultView.Node))\n    ? node\n    : create(name)\n}\n\n// Adopt existing svg elements\nexport function adopt(node) {\n  // check for presence of node\n  if (!node) return null\n\n  // make sure a node isn't already adopted\n  if (node.instance instanceof Base) return node.instance\n\n  if (node.nodeName === '#document-fragment') {\n    return new elements.Fragment(node)\n  }\n\n  // initialize variables\n  let className = capitalize(node.nodeName || 'Dom')\n\n  // Make sure that gradients are adopted correctly\n  if (className === 'LinearGradient' || className === 'RadialGradient') {\n    className = 'Gradient'\n\n    // Fallback to Dom if element is not known\n  } else if (!elements[className]) {\n    className = 'Dom'\n  }\n\n  return new elements[className](node)\n}\n\nlet adopter = adopt\n\nexport function mockAdopt(mock = adopt) {\n  adopter = mock\n}\n\nexport function register(element, name = element.name, asRoot = false) {\n  elements[name] = element\n  if (asRoot) elements[root] = element\n\n  addMethodNames(Object.getOwnPropertyNames(element.prototype))\n\n  return element\n}\n\nexport function getClass(name) {\n  return elements[name]\n}\n\n// Element id sequence\nlet did = 1000\n\n// Get next named element id\nexport function eid(name) {\n  return 'Svgjs' + capitalize(name) + did++\n}\n\n// Deep new id assignment\nexport function assignNewId(node) {\n  // do the same for SVG child nodes as well\n  for (let i = node.children.length - 1; i >= 0; i--) {\n    assignNewId(node.children[i])\n  }\n\n  if (node.id) {\n    node.id = eid(node.nodeName)\n    return node\n  }\n\n  return node\n}\n\n// Method for extending objects\nexport function extend(modules, methods) {\n  let key, i\n\n  modules = Array.isArray(modules) ? modules : [modules]\n\n  for (i = modules.length - 1; i >= 0; i--) {\n    for (key in methods) {\n      modules[i].prototype[key] = methods[key]\n    }\n  }\n}\n\nexport function wrapWithAttrCheck(fn) {\n  return function (...args) {\n    const o = args[args.length - 1]\n\n    if (o && o.constructor === Object && !(o instanceof Array)) {\n      return fn.apply(this, args.slice(0, -1)).attr(o)\n    } else {\n      return fn.apply(this, args)\n    }\n  }\n}\n","import { makeInstance } from '../../utils/adopter.js'\nimport { registerMethods } from '../../utils/methods.js'\n\n// Get all siblings, including myself\nexport function siblings() {\n  return this.parent().children()\n}\n\n// Get the current position siblings\nexport function position() {\n  return this.parent().index(this)\n}\n\n// Get the next element (will return null if there is none)\nexport function next() {\n  return this.siblings()[this.position() + 1]\n}\n\n// Get the next element (will return null if there is none)\nexport function prev() {\n  return this.siblings()[this.position() - 1]\n}\n\n// Send given element one step forward\nexport function forward() {\n  const i = this.position()\n  const p = this.parent()\n\n  // move node one step forward\n  p.add(this.remove(), i + 1)\n\n  return this\n}\n\n// Send given element one step backward\nexport function backward() {\n  const i = this.position()\n  const p = this.parent()\n\n  p.add(this.remove(), i ? i - 1 : 0)\n\n  return this\n}\n\n// Send given element all the way to the front\nexport function front() {\n  const p = this.parent()\n\n  // Move node forward\n  p.add(this.remove())\n\n  return this\n}\n\n// Send given element all the way to the back\nexport function back() {\n  const p = this.parent()\n\n  // Move node back\n  p.add(this.remove(), 0)\n\n  return this\n}\n\n// Inserts a given element before the targeted element\nexport function before(element) {\n  element = makeInstance(element)\n  element.remove()\n\n  const i = this.position()\n\n  this.parent().add(element, i)\n\n  return this\n}\n\n// Inserts a given element after the targeted element\nexport function after(element) {\n  element = makeInstance(element)\n  element.remove()\n\n  const i = this.position()\n\n  this.parent().add(element, i + 1)\n\n  return this\n}\n\nexport function insertBefore(element) {\n  element = makeInstance(element)\n  element.before(this)\n  return this\n}\n\nexport function insertAfter(element) {\n  element = makeInstance(element)\n  element.after(this)\n  return this\n}\n\nregisterMethods('Dom', {\n  siblings,\n  position,\n  next,\n  prev,\n  forward,\n  backward,\n  front,\n  back,\n  before,\n  after,\n  insertBefore,\n  insertAfter\n})\n","// Parse unit value\nexport const numberAndUnit =\n  /^([+-]?(\\d+(\\.\\d*)?|\\.\\d+)(e[+-]?\\d+)?)([a-z%]*)$/i\n\n// Parse hex value\nexport const hex = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i\n\n// Parse rgb value\nexport const rgb = /rgb\\((\\d+),(\\d+),(\\d+)\\)/\n\n// Parse reference id\nexport const reference = /(#[a-z_][a-z0-9\\-_]*)/i\n\n// splits a transformation chain\nexport const transforms = /\\)\\s*,?\\s*/\n\n// Whitespace\nexport const whitespace = /\\s/g\n\n// Test hex value\nexport const isHex = /^#[a-f0-9]{3}$|^#[a-f0-9]{6}$/i\n\n// Test rgb value\nexport const isRgb = /^rgb\\(/\n\n// Test for blank string\nexport const isBlank = /^(\\s+)?$/\n\n// Test for numeric string\nexport const isNumber = /^[+-]?(\\d+(\\.\\d*)?|\\.\\d+)(e[+-]?\\d+)?$/i\n\n// Test for image url\nexport const isImage = /\\.(jpg|jpeg|png|gif|svg)(\\?[^=]+.*)?/i\n\n// split at whitespace and comma\nexport const delimiter = /[\\s,]+/\n\n// Test for path letter\nexport const isPathLetter = /[MLHVCSQTAZ]/i\n","import { delimiter } from '../core/regex.js'\nimport { registerMethods } from '../../utils/methods.js'\n\n// Return array of classes on the node\nexport function classes() {\n  const attr = this.attr('class')\n  return attr == null ? [] : attr.trim().split(delimiter)\n}\n\n// Return true if class exists on the node, false otherwise\nexport function hasClass(name) {\n  return this.classes().indexOf(name) !== -1\n}\n\n// Add class to the node\nexport function addClass(name) {\n  if (!this.hasClass(name)) {\n    const array = this.classes()\n    array.push(name)\n    this.attr('class', array.join(' '))\n  }\n\n  return this\n}\n\n// Remove class from the node\nexport function removeClass(name) {\n  if (this.hasClass(name)) {\n    this.attr(\n      'class',\n      this.classes()\n        .filter(function (c) {\n          return c !== name\n        })\n        .join(' ')\n    )\n  }\n\n  return this\n}\n\n// Toggle the presence of a class on the node\nexport function toggleClass(name) {\n  return this.hasClass(name) ? this.removeClass(name) : this.addClass(name)\n}\n\nregisterMethods('Dom', {\n  classes,\n  hasClass,\n  addClass,\n  removeClass,\n  toggleClass\n})\n","import { isBlank } from '../core/regex.js'\nimport { registerMethods } from '../../utils/methods.js'\n\n// Dynamic style generator\nexport function css(style, val) {\n  const ret = {}\n  if (arguments.length === 0) {\n    // get full style as object\n    this.node.style.cssText\n      .split(/\\s*;\\s*/)\n      .filter(function (el) {\n        return !!el.length\n      })\n      .forEach(function (el) {\n        const t = el.split(/\\s*:\\s*/)\n        ret[t[0]] = t[1]\n      })\n    return ret\n  }\n\n  if (arguments.length < 2) {\n    // get style properties as array\n    if (Array.isArray(style)) {\n      for (const name of style) {\n        const cased = name\n        ret[name] = this.node.style.getPropertyValue(cased)\n      }\n      return ret\n    }\n\n    // get style for property\n    if (typeof style === 'string') {\n      return this.node.style.getPropertyValue(style)\n    }\n\n    // set styles in object\n    if (typeof style === 'object') {\n      for (const name in style) {\n        // set empty string if null/undefined/'' was given\n        this.node.style.setProperty(\n          name,\n          style[name] == null || isBlank.test(style[name]) ? '' : style[name]\n        )\n      }\n    }\n  }\n\n  // set style for property\n  if (arguments.length === 2) {\n    this.node.style.setProperty(\n      style,\n      val == null || isBlank.test(val) ? '' : val\n    )\n  }\n\n  return this\n}\n\n// Show element\nexport function show() {\n  return this.css('display', '')\n}\n\n// Hide element\nexport function hide() {\n  return this.css('display', 'none')\n}\n\n// Is element visible?\nexport function visible() {\n  return this.css('display') !== 'none'\n}\n\nregisterMethods('Dom', {\n  css,\n  show,\n  hide,\n  visible\n})\n","import { registerMethods } from '../../utils/methods.js'\nimport { filter, map } from '../../utils/utils.js'\n\n// Store data values on svg nodes\nexport function data(a, v, r) {\n  if (a == null) {\n    // get an object of attributes\n    return this.data(\n      map(\n        filter(\n          this.node.attributes,\n          (el) => el.nodeName.indexOf('data-') === 0\n        ),\n        (el) => el.nodeName.slice(5)\n      )\n    )\n  } else if (a instanceof Array) {\n    const data = {}\n    for (const key of a) {\n      data[key] = this.data(key)\n    }\n    return data\n  } else if (typeof a === 'object') {\n    for (v in a) {\n      this.data(v, a[v])\n    }\n  } else if (arguments.length < 2) {\n    try {\n      return JSON.parse(this.attr('data-' + a))\n    } catch (e) {\n      return this.attr('data-' + a)\n    }\n  } else {\n    this.attr(\n      'data-' + a,\n      v === null\n        ? null\n        : r === true || typeof v === 'string' || typeof v === 'number'\n          ? v\n          : JSON.stringify(v)\n    )\n  }\n\n  return this\n}\n\nregisterMethods('Dom', { data })\n","import { registerMethods } from '../../utils/methods.js'\n\n// Remember arbitrary data\nexport function remember(k, v) {\n  // remember every item in an object individually\n  if (typeof arguments[0] === 'object') {\n    for (const key in k) {\n      this.remember(key, k[key])\n    }\n  } else if (arguments.length === 1) {\n    // retrieve memory\n    return this.memory()[k]\n  } else {\n    // store memory\n    this.memory()[k] = v\n  }\n\n  return this\n}\n\n// Erase a given memory\nexport function forget() {\n  if (arguments.length === 0) {\n    this._memory = {}\n  } else {\n    for (let i = arguments.length - 1; i >= 0; i--) {\n      delete this.memory()[arguments[i]]\n    }\n  }\n  return this\n}\n\n// This triggers creation of a new hidden class which is not performant\n// However, this function is not rarely used so it will not happen frequently\n// Return local memory object\nexport function memory() {\n  return (this._memory = this._memory || {})\n}\n\nregisterMethods('Dom', { remember, forget, memory })\n","import { hex, isHex, isRgb, rgb, whitespace } from '../modules/core/regex.js'\n\nfunction sixDigitHex(hex) {\n  return hex.length === 4\n    ? [\n        '#',\n        hex.substring(1, 2),\n        hex.substring(1, 2),\n        hex.substring(2, 3),\n        hex.substring(2, 3),\n        hex.substring(3, 4),\n        hex.substring(3, 4)\n      ].join('')\n    : hex\n}\n\nfunction componentHex(component) {\n  const integer = Math.round(component)\n  const bounded = Math.max(0, Math.min(255, integer))\n  const hex = bounded.toString(16)\n  return hex.length === 1 ? '0' + hex : hex\n}\n\nfunction is(object, space) {\n  for (let i = space.length; i--; ) {\n    if (object[space[i]] == null) {\n      return false\n    }\n  }\n  return true\n}\n\nfunction getParameters(a, b) {\n  const params = is(a, 'rgb')\n    ? { _a: a.r, _b: a.g, _c: a.b, _d: 0, space: 'rgb' }\n    : is(a, 'xyz')\n      ? { _a: a.x, _b: a.y, _c: a.z, _d: 0, space: 'xyz' }\n      : is(a, 'hsl')\n        ? { _a: a.h, _b: a.s, _c: a.l, _d: 0, space: 'hsl' }\n        : is(a, 'lab')\n          ? { _a: a.l, _b: a.a, _c: a.b, _d: 0, space: 'lab' }\n          : is(a, 'lch')\n            ? { _a: a.l, _b: a.c, _c: a.h, _d: 0, space: 'lch' }\n            : is(a, 'cmyk')\n              ? { _a: a.c, _b: a.m, _c: a.y, _d: a.k, space: 'cmyk' }\n              : { _a: 0, _b: 0, _c: 0, space: 'rgb' }\n\n  params.space = b || params.space\n  return params\n}\n\nfunction cieSpace(space) {\n  if (space === 'lab' || space === 'xyz' || space === 'lch') {\n    return true\n  } else {\n    return false\n  }\n}\n\nfunction hueToRgb(p, q, t) {\n  if (t < 0) t += 1\n  if (t > 1) t -= 1\n  if (t < 1 / 6) return p + (q - p) * 6 * t\n  if (t < 1 / 2) return q\n  if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6\n  return p\n}\n\nexport default class Color {\n  constructor(...inputs) {\n    this.init(...inputs)\n  }\n\n  // Test if given value is a color\n  static isColor(color) {\n    return (\n      color && (color instanceof Color || this.isRgb(color) || this.test(color))\n    )\n  }\n\n  // Test if given value is an rgb object\n  static isRgb(color) {\n    return (\n      color &&\n      typeof color.r === 'number' &&\n      typeof color.g === 'number' &&\n      typeof color.b === 'number'\n    )\n  }\n\n  /*\n  Generating random colors\n  */\n  static random(mode = 'vibrant', t) {\n    // Get the math modules\n    const { random, round, sin, PI: pi } = Math\n\n    // Run the correct generator\n    if (mode === 'vibrant') {\n      const l = (81 - 57) * random() + 57\n      const c = (83 - 45) * random() + 45\n      const h = 360 * random()\n      const color = new Color(l, c, h, 'lch')\n      return color\n    } else if (mode === 'sine') {\n      t = t == null ? random() : t\n      const r = round(80 * sin((2 * pi * t) / 0.5 + 0.01) + 150)\n      const g = round(50 * sin((2 * pi * t) / 0.5 + 4.6) + 200)\n      const b = round(100 * sin((2 * pi * t) / 0.5 + 2.3) + 150)\n      const color = new Color(r, g, b)\n      return color\n    } else if (mode === 'pastel') {\n      const l = (94 - 86) * random() + 86\n      const c = (26 - 9) * random() + 9\n      const h = 360 * random()\n      const color = new Color(l, c, h, 'lch')\n      return color\n    } else if (mode === 'dark') {\n      const l = 10 + 10 * random()\n      const c = (125 - 75) * random() + 86\n      const h = 360 * random()\n      const color = new Color(l, c, h, 'lch')\n      return color\n    } else if (mode === 'rgb') {\n      const r = 255 * random()\n      const g = 255 * random()\n      const b = 255 * random()\n      const color = new Color(r, g, b)\n      return color\n    } else if (mode === 'lab') {\n      const l = 100 * random()\n      const a = 256 * random() - 128\n      const b = 256 * random() - 128\n      const color = new Color(l, a, b, 'lab')\n      return color\n    } else if (mode === 'grey') {\n      const grey = 255 * random()\n      const color = new Color(grey, grey, grey)\n      return color\n    } else {\n      throw new Error('Unsupported random color mode')\n    }\n  }\n\n  // Test if given value is a color string\n  static test(color) {\n    return typeof color === 'string' && (isHex.test(color) || isRgb.test(color))\n  }\n\n  cmyk() {\n    // Get the rgb values for the current color\n    const { _a, _b, _c } = this.rgb()\n    const [r, g, b] = [_a, _b, _c].map((v) => v / 255)\n\n    // Get the cmyk values in an unbounded format\n    const k = Math.min(1 - r, 1 - g, 1 - b)\n\n    if (k === 1) {\n      // Catch the black case\n      return new Color(0, 0, 0, 1, 'cmyk')\n    }\n\n    const c = (1 - r - k) / (1 - k)\n    const m = (1 - g - k) / (1 - k)\n    const y = (1 - b - k) / (1 - k)\n\n    // Construct the new color\n    const color = new Color(c, m, y, k, 'cmyk')\n    return color\n  }\n\n  hsl() {\n    // Get the rgb values\n    const { _a, _b, _c } = this.rgb()\n    const [r, g, b] = [_a, _b, _c].map((v) => v / 255)\n\n    // Find the maximum and minimum values to get the lightness\n    const max = Math.max(r, g, b)\n    const min = Math.min(r, g, b)\n    const l = (max + min) / 2\n\n    // If the r, g, v values are identical then we are grey\n    const isGrey = max === min\n\n    // Calculate the hue and saturation\n    const delta = max - min\n    const s = isGrey\n      ? 0\n      : l > 0.5\n        ? delta / (2 - max - min)\n        : delta / (max + min)\n    const h = isGrey\n      ? 0\n      : max === r\n        ? ((g - b) / delta + (g < b ? 6 : 0)) / 6\n        : max === g\n          ? ((b - r) / delta + 2) / 6\n          : max === b\n            ? ((r - g) / delta + 4) / 6\n            : 0\n\n    // Construct and return the new color\n    const color = new Color(360 * h, 100 * s, 100 * l, 'hsl')\n    return color\n  }\n\n  init(a = 0, b = 0, c = 0, d = 0, space = 'rgb') {\n    // This catches the case when a falsy value is passed like ''\n    a = !a ? 0 : a\n\n    // Reset all values in case the init function is rerun with new color space\n    if (this.space) {\n      for (const component in this.space) {\n        delete this[this.space[component]]\n      }\n    }\n\n    if (typeof a === 'number') {\n      // Allow for the case that we don't need d...\n      space = typeof d === 'string' ? d : space\n      d = typeof d === 'string' ? 0 : d\n\n      // Assign the values straight to the color\n      Object.assign(this, { _a: a, _b: b, _c: c, _d: d, space })\n      // If the user gave us an array, make the color from it\n    } else if (a instanceof Array) {\n      this.space = b || (typeof a[3] === 'string' ? a[3] : a[4]) || 'rgb'\n      Object.assign(this, { _a: a[0], _b: a[1], _c: a[2], _d: a[3] || 0 })\n    } else if (a instanceof Object) {\n      // Set the object up and assign its values directly\n      const values = getParameters(a, b)\n      Object.assign(this, values)\n    } else if (typeof a === 'string') {\n      if (isRgb.test(a)) {\n        const noWhitespace = a.replace(whitespace, '')\n        const [_a, _b, _c] = rgb\n          .exec(noWhitespace)\n          .slice(1, 4)\n          .map((v) => parseInt(v))\n        Object.assign(this, { _a, _b, _c, _d: 0, space: 'rgb' })\n      } else if (isHex.test(a)) {\n        const hexParse = (v) => parseInt(v, 16)\n        const [, _a, _b, _c] = hex.exec(sixDigitHex(a)).map(hexParse)\n        Object.assign(this, { _a, _b, _c, _d: 0, space: 'rgb' })\n      } else throw Error(\"Unsupported string format, can't construct Color\")\n    }\n\n    // Now add the components as a convenience\n    const { _a, _b, _c, _d } = this\n    const components =\n      this.space === 'rgb'\n        ? { r: _a, g: _b, b: _c }\n        : this.space === 'xyz'\n          ? { x: _a, y: _b, z: _c }\n          : this.space === 'hsl'\n            ? { h: _a, s: _b, l: _c }\n            : this.space === 'lab'\n              ? { l: _a, a: _b, b: _c }\n              : this.space === 'lch'\n                ? { l: _a, c: _b, h: _c }\n                : this.space === 'cmyk'\n                  ? { c: _a, m: _b, y: _c, k: _d }\n                  : {}\n    Object.assign(this, components)\n  }\n\n  lab() {\n    // Get the xyz color\n    const { x, y, z } = this.xyz()\n\n    // Get the lab components\n    const l = 116 * y - 16\n    const a = 500 * (x - y)\n    const b = 200 * (y - z)\n\n    // Construct and return a new color\n    const color = new Color(l, a, b, 'lab')\n    return color\n  }\n\n  lch() {\n    // Get the lab color directly\n    const { l, a, b } = this.lab()\n\n    // Get the chromaticity and the hue using polar coordinates\n    const c = Math.sqrt(a ** 2 + b ** 2)\n    let h = (180 * Math.atan2(b, a)) / Math.PI\n    if (h < 0) {\n      h *= -1\n      h = 360 - h\n    }\n\n    // Make a new color and return it\n    const color = new Color(l, c, h, 'lch')\n    return color\n  }\n  /*\n  Conversion Methods\n  */\n\n  rgb() {\n    if (this.space === 'rgb') {\n      return this\n    } else if (cieSpace(this.space)) {\n      // Convert to the xyz color space\n      let { x, y, z } = this\n      if (this.space === 'lab' || this.space === 'lch') {\n        // Get the values in the lab space\n        let { l, a, b } = this\n        if (this.space === 'lch') {\n          const { c, h } = this\n          const dToR = Math.PI / 180\n          a = c * Math.cos(dToR * h)\n          b = c * Math.sin(dToR * h)\n        }\n\n        // Undo the nonlinear function\n        const yL = (l + 16) / 116\n        const xL = a / 500 + yL\n        const zL = yL - b / 200\n\n        // Get the xyz values\n        const ct = 16 / 116\n        const mx = 0.008856\n        const nm = 7.787\n        x = 0.95047 * (xL ** 3 > mx ? xL ** 3 : (xL - ct) / nm)\n        y = 1.0 * (yL ** 3 > mx ? yL ** 3 : (yL - ct) / nm)\n        z = 1.08883 * (zL ** 3 > mx ? zL ** 3 : (zL - ct) / nm)\n      }\n\n      // Convert xyz to unbounded rgb values\n      const rU = x * 3.2406 + y * -1.5372 + z * -0.4986\n      const gU = x * -0.9689 + y * 1.8758 + z * 0.0415\n      const bU = x * 0.0557 + y * -0.204 + z * 1.057\n\n      // Convert the values to true rgb values\n      const pow = Math.pow\n      const bd = 0.0031308\n      const r = rU > bd ? 1.055 * pow(rU, 1 / 2.4) - 0.055 : 12.92 * rU\n      const g = gU > bd ? 1.055 * pow(gU, 1 / 2.4) - 0.055 : 12.92 * gU\n      const b = bU > bd ? 1.055 * pow(bU, 1 / 2.4) - 0.055 : 12.92 * bU\n\n      // Make and return the color\n      const color = new Color(255 * r, 255 * g, 255 * b)\n      return color\n    } else if (this.space === 'hsl') {\n      // https://bgrins.github.io/TinyColor/docs/tinycolor.html\n      // Get the current hsl values\n      let { h, s, l } = this\n      h /= 360\n      s /= 100\n      l /= 100\n\n      // If we are grey, then just make the color directly\n      if (s === 0) {\n        l *= 255\n        const color = new Color(l, l, l)\n        return color\n      }\n\n      // TODO I have no idea what this does :D If you figure it out, tell me!\n      const q = l < 0.5 ? l * (1 + s) : l + s - l * s\n      const p = 2 * l - q\n\n      // Get the rgb values\n      const r = 255 * hueToRgb(p, q, h + 1 / 3)\n      const g = 255 * hueToRgb(p, q, h)\n      const b = 255 * hueToRgb(p, q, h - 1 / 3)\n\n      // Make a new color\n      const color = new Color(r, g, b)\n      return color\n    } else if (this.space === 'cmyk') {\n      // https://gist.github.com/felipesabino/5066336\n      // Get the normalised cmyk values\n      const { c, m, y, k } = this\n\n      // Get the rgb values\n      const r = 255 * (1 - Math.min(1, c * (1 - k) + k))\n      const g = 255 * (1 - Math.min(1, m * (1 - k) + k))\n      const b = 255 * (1 - Math.min(1, y * (1 - k) + k))\n\n      // Form the color and return it\n      const color = new Color(r, g, b)\n      return color\n    } else {\n      return this\n    }\n  }\n\n  toArray() {\n    const { _a, _b, _c, _d, space } = this\n    return [_a, _b, _c, _d, space]\n  }\n\n  toHex() {\n    const [r, g, b] = this._clamped().map(componentHex)\n    return `#${r}${g}${b}`\n  }\n\n  toRgb() {\n    const [rV, gV, bV] = this._clamped()\n    const string = `rgb(${rV},${gV},${bV})`\n    return string\n  }\n\n  toString() {\n    return this.toHex()\n  }\n\n  xyz() {\n    // Normalise the red, green and blue values\n    const { _a: r255, _b: g255, _c: b255 } = this.rgb()\n    const [r, g, b] = [r255, g255, b255].map((v) => v / 255)\n\n    // Convert to the lab rgb space\n    const rL = r > 0.04045 ? Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92\n    const gL = g > 0.04045 ? Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92\n    const bL = b > 0.04045 ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92\n\n    // Convert to the xyz color space without bounding the values\n    const xU = (rL * 0.4124 + gL * 0.3576 + bL * 0.1805) / 0.95047\n    const yU = (rL * 0.2126 + gL * 0.7152 + bL * 0.0722) / 1.0\n    const zU = (rL * 0.0193 + gL * 0.1192 + bL * 0.9505) / 1.08883\n\n    // Get the proper xyz values by applying the bounding\n    const x = xU > 0.008856 ? Math.pow(xU, 1 / 3) : 7.787 * xU + 16 / 116\n    const y = yU > 0.008856 ? Math.pow(yU, 1 / 3) : 7.787 * yU + 16 / 116\n    const z = zU > 0.008856 ? Math.pow(zU, 1 / 3) : 7.787 * zU + 16 / 116\n\n    // Make and return the color\n    const color = new Color(x, y, z, 'xyz')\n    return color\n  }\n\n  /*\n  Input and Output methods\n  */\n\n  _clamped() {\n    const { _a, _b, _c } = this.rgb()\n    const { max, min, round } = Math\n    const format = (v) => max(0, min(round(v), 255))\n    return [_a, _b, _c].map(format)\n  }\n\n  /*\n  Constructing colors\n  */\n}\n","import Matrix from './Matrix.js'\n\nexport default class Point {\n  // Initialize\n  constructor(...args) {\n    this.init(...args)\n  }\n\n  // Clone point\n  clone() {\n    return new Point(this)\n  }\n\n  init(x, y) {\n    const base = { x: 0, y: 0 }\n\n    // ensure source as object\n    const source = Array.isArray(x)\n      ? { x: x[0], y: x[1] }\n      : typeof x === 'object'\n        ? { x: x.x, y: x.y }\n        : { x: x, y: y }\n\n    // merge source\n    this.x = source.x == null ? base.x : source.x\n    this.y = source.y == null ? base.y : source.y\n\n    return this\n  }\n\n  toArray() {\n    return [this.x, this.y]\n  }\n\n  transform(m) {\n    return this.clone().transformO(m)\n  }\n\n  // Transform point with matrix\n  transformO(m) {\n    if (!Matrix.isMatrixLike(m)) {\n      m = new Matrix(m)\n    }\n\n    const { x, y } = this\n\n    // Perform the matrix multiplication\n    this.x = m.a * x + m.c * y + m.e\n    this.y = m.b * x + m.d * y + m.f\n\n    return this\n  }\n}\n\nexport function point(x, y) {\n  return new Point(x, y).transformO(this.screenCTM().inverseO())\n}\n","import { delimiter } from '../modules/core/regex.js'\nimport { radians } from '../utils/utils.js'\nimport { register } from '../utils/adopter.js'\nimport Element from '../elements/Element.js'\nimport Point from './Point.js'\n\nfunction closeEnough(a, b, threshold) {\n  return Math.abs(b - a) < (threshold || 1e-6)\n}\n\nexport default class Matrix {\n  constructor(...args) {\n    this.init(...args)\n  }\n\n  static formatTransforms(o) {\n    // Get all of the parameters required to form the matrix\n    const flipBoth = o.flip === 'both' || o.flip === true\n    const flipX = o.flip && (flipBoth || o.flip === 'x') ? -1 : 1\n    const flipY = o.flip && (flipBoth || o.flip === 'y') ? -1 : 1\n    const skewX =\n      o.skew && o.skew.length\n        ? o.skew[0]\n        : isFinite(o.skew)\n          ? o.skew\n          : isFinite(o.skewX)\n            ? o.skewX\n            : 0\n    const skewY =\n      o.skew && o.skew.length\n        ? o.skew[1]\n        : isFinite(o.skew)\n          ? o.skew\n          : isFinite(o.skewY)\n            ? o.skewY\n            : 0\n    const scaleX =\n      o.scale && o.scale.length\n        ? o.scale[0] * flipX\n        : isFinite(o.scale)\n          ? o.scale * flipX\n          : isFinite(o.scaleX)\n            ? o.scaleX * flipX\n            : flipX\n    const scaleY =\n      o.scale && o.scale.length\n        ? o.scale[1] * flipY\n        : isFinite(o.scale)\n          ? o.scale * flipY\n          : isFinite(o.scaleY)\n            ? o.scaleY * flipY\n            : flipY\n    const shear = o.shear || 0\n    const theta = o.rotate || o.theta || 0\n    const origin = new Point(\n      o.origin || o.around || o.ox || o.originX,\n      o.oy || o.originY\n    )\n    const ox = origin.x\n    const oy = origin.y\n    // We need Point to be invalid if nothing was passed because we cannot default to 0 here. That is why NaN\n    const position = new Point(\n      o.position || o.px || o.positionX || NaN,\n      o.py || o.positionY || NaN\n    )\n    const px = position.x\n    const py = position.y\n    const translate = new Point(\n      o.translate || o.tx || o.translateX,\n      o.ty || o.translateY\n    )\n    const tx = translate.x\n    const ty = translate.y\n    const relative = new Point(\n      o.relative || o.rx || o.relativeX,\n      o.ry || o.relativeY\n    )\n    const rx = relative.x\n    const ry = relative.y\n\n    // Populate all of the values\n    return {\n      scaleX,\n      scaleY,\n      skewX,\n      skewY,\n      shear,\n      theta,\n      rx,\n      ry,\n      tx,\n      ty,\n      ox,\n      oy,\n      px,\n      py\n    }\n  }\n\n  static fromArray(a) {\n    return { a: a[0], b: a[1], c: a[2], d: a[3], e: a[4], f: a[5] }\n  }\n\n  static isMatrixLike(o) {\n    return (\n      o.a != null ||\n      o.b != null ||\n      o.c != null ||\n      o.d != null ||\n      o.e != null ||\n      o.f != null\n    )\n  }\n\n  // left matrix, right matrix, target matrix which is overwritten\n  static matrixMultiply(l, r, o) {\n    // Work out the product directly\n    const a = l.a * r.a + l.c * r.b\n    const b = l.b * r.a + l.d * r.b\n    const c = l.a * r.c + l.c * r.d\n    const d = l.b * r.c + l.d * r.d\n    const e = l.e + l.a * r.e + l.c * r.f\n    const f = l.f + l.b * r.e + l.d * r.f\n\n    // make sure to use local variables because l/r and o could be the same\n    o.a = a\n    o.b = b\n    o.c = c\n    o.d = d\n    o.e = e\n    o.f = f\n\n    return o\n  }\n\n  around(cx, cy, matrix) {\n    return this.clone().aroundO(cx, cy, matrix)\n  }\n\n  // Transform around a center point\n  aroundO(cx, cy, matrix) {\n    const dx = cx || 0\n    const dy = cy || 0\n    return this.translateO(-dx, -dy).lmultiplyO(matrix).translateO(dx, dy)\n  }\n\n  // Clones this matrix\n  clone() {\n    return new Matrix(this)\n  }\n\n  // Decomposes this matrix into its affine parameters\n  decompose(cx = 0, cy = 0) {\n    // Get the parameters from the matrix\n    const a = this.a\n    const b = this.b\n    const c = this.c\n    const d = this.d\n    const e = this.e\n    const f = this.f\n\n    // Figure out if the winding direction is clockwise or counterclockwise\n    const determinant = a * d - b * c\n    const ccw = determinant > 0 ? 1 : -1\n\n    // Since we only shear in x, we can use the x basis to get the x scale\n    // and the rotation of the resulting matrix\n    const sx = ccw * Math.sqrt(a * a + b * b)\n    const thetaRad = Math.atan2(ccw * b, ccw * a)\n    const theta = (180 / Math.PI) * thetaRad\n    const ct = Math.cos(thetaRad)\n    const st = Math.sin(thetaRad)\n\n    // We can then solve the y basis vector simultaneously to get the other\n    // two affine parameters directly from these parameters\n    const lam = (a * c + b * d) / determinant\n    const sy = (c * sx) / (lam * a - b) || (d * sx) / (lam * b + a)\n\n    // Use the translations\n    const tx = e - cx + cx * ct * sx + cy * (lam * ct * sx - st * sy)\n    const ty = f - cy + cx * st * sx + cy * (lam * st * sx + ct * sy)\n\n    // Construct the decomposition and return it\n    return {\n      // Return the affine parameters\n      scaleX: sx,\n      scaleY: sy,\n      shear: lam,\n      rotate: theta,\n      translateX: tx,\n      translateY: ty,\n      originX: cx,\n      originY: cy,\n\n      // Return the matrix parameters\n      a: this.a,\n      b: this.b,\n      c: this.c,\n      d: this.d,\n      e: this.e,\n      f: this.f\n    }\n  }\n\n  // Check if two matrices are equal\n  equals(other) {\n    if (other === this) return true\n    const comp = new Matrix(other)\n    return (\n      closeEnough(this.a, comp.a) &&\n      closeEnough(this.b, comp.b) &&\n      closeEnough(this.c, comp.c) &&\n      closeEnough(this.d, comp.d) &&\n      closeEnough(this.e, comp.e) &&\n      closeEnough(this.f, comp.f)\n    )\n  }\n\n  // Flip matrix on x or y, at a given offset\n  flip(axis, around) {\n    return this.clone().flipO(axis, around)\n  }\n\n  flipO(axis, around) {\n    return axis === 'x'\n      ? this.scaleO(-1, 1, around, 0)\n      : axis === 'y'\n        ? this.scaleO(1, -1, 0, around)\n        : this.scaleO(-1, -1, axis, around || axis) // Define an x, y flip point\n  }\n\n  // Initialize\n  init(source) {\n    const base = Matrix.fromArray([1, 0, 0, 1, 0, 0])\n\n    // ensure source as object\n    source =\n      source instanceof Element\n        ? source.matrixify()\n        : typeof source === 'string'\n          ? Matrix.fromArray(source.split(delimiter).map(parseFloat))\n          : Array.isArray(source)\n            ? Matrix.fromArray(source)\n            : typeof source === 'object' && Matrix.isMatrixLike(source)\n              ? source\n              : typeof source === 'object'\n                ? new Matrix().transform(source)\n                : arguments.length === 6\n                  ? Matrix.fromArray([].slice.call(arguments))\n                  : base\n\n    // Merge the source matrix with the base matrix\n    this.a = source.a != null ? source.a : base.a\n    this.b = source.b != null ? source.b : base.b\n    this.c = source.c != null ? source.c : base.c\n    this.d = source.d != null ? source.d : base.d\n    this.e = source.e != null ? source.e : base.e\n    this.f = source.f != null ? source.f : base.f\n\n    return this\n  }\n\n  inverse() {\n    return this.clone().inverseO()\n  }\n\n  // Inverses matrix\n  inverseO() {\n    // Get the current parameters out of the matrix\n    const a = this.a\n    const b = this.b\n    const c = this.c\n    const d = this.d\n    const e = this.e\n    const f = this.f\n\n    // Invert the 2x2 matrix in the top left\n    const det = a * d - b * c\n    if (!det) throw new Error('Cannot invert ' + this)\n\n    // Calculate the top 2x2 matrix\n    const na = d / det\n    const nb = -b / det\n    const nc = -c / det\n    const nd = a / det\n\n    // Apply the inverted matrix to the top right\n    const ne = -(na * e + nc * f)\n    const nf = -(nb * e + nd * f)\n\n    // Construct the inverted matrix\n    this.a = na\n    this.b = nb\n    this.c = nc\n    this.d = nd\n    this.e = ne\n    this.f = nf\n\n    return this\n  }\n\n  lmultiply(matrix) {\n    return this.clone().lmultiplyO(matrix)\n  }\n\n  lmultiplyO(matrix) {\n    const r = this\n    const l = matrix instanceof Matrix ? matrix : new Matrix(matrix)\n\n    return Matrix.matrixMultiply(l, r, this)\n  }\n\n  // Left multiplies by the given matrix\n  multiply(matrix) {\n    return this.clone().multiplyO(matrix)\n  }\n\n  multiplyO(matrix) {\n    // Get the matrices\n    const l = this\n    const r = matrix instanceof Matrix ? matrix : new Matrix(matrix)\n\n    return Matrix.matrixMultiply(l, r, this)\n  }\n\n  // Rotate matrix\n  rotate(r, cx, cy) {\n    return this.clone().rotateO(r, cx, cy)\n  }\n\n  rotateO(r, cx = 0, cy = 0) {\n    // Convert degrees to radians\n    r = radians(r)\n\n    const cos = Math.cos(r)\n    const sin = Math.sin(r)\n\n    const { a, b, c, d, e, f } = this\n\n    this.a = a * cos - b * sin\n    this.b = b * cos + a * sin\n    this.c = c * cos - d * sin\n    this.d = d * cos + c * sin\n    this.e = e * cos - f * sin + cy * sin - cx * cos + cx\n    this.f = f * cos + e * sin - cx * sin - cy * cos + cy\n\n    return this\n  }\n\n  // Scale matrix\n  scale() {\n    return this.clone().scaleO(...arguments)\n  }\n\n  scaleO(x, y = x, cx = 0, cy = 0) {\n    // Support uniform scaling\n    if (arguments.length === 3) {\n      cy = cx\n      cx = y\n      y = x\n    }\n\n    const { a, b, c, d, e, f } = this\n\n    this.a = a * x\n    this.b = b * y\n    this.c = c * x\n    this.d = d * y\n    this.e = e * x - cx * x + cx\n    this.f = f * y - cy * y + cy\n\n    return this\n  }\n\n  // Shear matrix\n  shear(a, cx, cy) {\n    return this.clone().shearO(a, cx, cy)\n  }\n\n  // eslint-disable-next-line no-unused-vars\n  shearO(lx, cx = 0, cy = 0) {\n    const { a, b, c, d, e, f } = this\n\n    this.a = a + b * lx\n    this.c = c + d * lx\n    this.e = e + f * lx - cy * lx\n\n    return this\n  }\n\n  // Skew Matrix\n  skew() {\n    return this.clone().skewO(...arguments)\n  }\n\n  skewO(x, y = x, cx = 0, cy = 0) {\n    // support uniformal skew\n    if (arguments.length === 3) {\n      cy = cx\n      cx = y\n      y = x\n    }\n\n    // Convert degrees to radians\n    x = radians(x)\n    y = radians(y)\n\n    const lx = Math.tan(x)\n    const ly = Math.tan(y)\n\n    const { a, b, c, d, e, f } = this\n\n    this.a = a + b * lx\n    this.b = b + a * ly\n    this.c = c + d * lx\n    this.d = d + c * ly\n    this.e = e + f * lx - cy * lx\n    this.f = f + e * ly - cx * ly\n\n    return this\n  }\n\n  // SkewX\n  skewX(x, cx, cy) {\n    return this.skew(x, 0, cx, cy)\n  }\n\n  // SkewY\n  skewY(y, cx, cy) {\n    return this.skew(0, y, cx, cy)\n  }\n\n  toArray() {\n    return [this.a, this.b, this.c, this.d, this.e, this.f]\n  }\n\n  // Convert matrix to string\n  toString() {\n    return (\n      'matrix(' +\n      this.a +\n      ',' +\n      this.b +\n      ',' +\n      this.c +\n      ',' +\n      this.d +\n      ',' +\n      this.e +\n      ',' +\n      this.f +\n      ')'\n    )\n  }\n\n  // Transform a matrix into another matrix by manipulating the space\n  transform(o) {\n    // Check if o is a matrix and then left multiply it directly\n    if (Matrix.isMatrixLike(o)) {\n      const matrix = new Matrix(o)\n      return matrix.multiplyO(this)\n    }\n\n    // Get the proposed transformations and the current transformations\n    const t = Matrix.formatTransforms(o)\n    const current = this\n    const { x: ox, y: oy } = new Point(t.ox, t.oy).transform(current)\n\n    // Construct the resulting matrix\n    const transformer = new Matrix()\n      .translateO(t.rx, t.ry)\n      .lmultiplyO(current)\n      .translateO(-ox, -oy)\n      .scaleO(t.scaleX, t.scaleY)\n      .skewO(t.skewX, t.skewY)\n      .shearO(t.shear)\n      .rotateO(t.theta)\n      .translateO(ox, oy)\n\n    // If we want the origin at a particular place, we force it there\n    if (isFinite(t.px) || isFinite(t.py)) {\n      const origin = new Point(ox, oy).transform(transformer)\n      // TODO: Replace t.px with isFinite(t.px)\n      // Doesn't work because t.px is also 0 if it wasn't passed\n      const dx = isFinite(t.px) ? t.px - origin.x : 0\n      const dy = isFinite(t.py) ? t.py - origin.y : 0\n      transformer.translateO(dx, dy)\n    }\n\n    // Translate now after positioning\n    transformer.translateO(t.tx, t.ty)\n    return transformer\n  }\n\n  // Translate matrix\n  translate(x, y) {\n    return this.clone().translateO(x, y)\n  }\n\n  translateO(x, y) {\n    this.e += x || 0\n    this.f += y || 0\n    return this\n  }\n\n  valueOf() {\n    return {\n      a: this.a,\n      b: this.b,\n      c: this.c,\n      d: this.d,\n      e: this.e,\n      f: this.f\n    }\n  }\n}\n\nexport function ctm() {\n  return new Matrix(this.node.getCTM())\n}\n\nexport function screenCTM() {\n  try {\n    /* https://bugzilla.mozilla.org/show_bug.cgi?id=1344537\n       This is needed because FF does not return the transformation matrix\n       for the inner coordinate system when getScreenCTM() is called on nested svgs.\n       However all other Browsers do that */\n    if (typeof this.isRoot === 'function' && !this.isRoot()) {\n      const rect = this.rect(1, 1)\n      const m = rect.node.getScreenCTM()\n      rect.remove()\n      return new Matrix(m)\n    }\n    return new Matrix(this.node.getScreenCTM())\n  } catch (e) {\n    console.warn(\n      `Cannot get CTM from SVG node ${this.node.nodeName}. Is the element rendered?`\n    )\n    return new Matrix()\n  }\n}\n\nregister(Matrix, 'Matrix')\n","import { globals } from '../../utils/window.js'\nimport { makeInstance } from '../../utils/adopter.js'\n\nexport default function parser() {\n  // Reuse cached element if possible\n  if (!parser.nodes) {\n    const svg = makeInstance().size(2, 0)\n    svg.node.style.cssText = [\n      'opacity: 0',\n      'position: absolute',\n      'left: -100%',\n      'top: -100%',\n      'overflow: hidden'\n    ].join(';')\n\n    svg.attr('focusable', 'false')\n    svg.attr('aria-hidden', 'true')\n\n    const path = svg.path().node\n\n    parser.nodes = { svg, path }\n  }\n\n  if (!parser.nodes.svg.node.parentNode) {\n    const b = globals.document.body || globals.document.documentElement\n    parser.nodes.svg.addTo(b)\n  }\n\n  return parser.nodes\n}\n","import { delimiter } from '../modules/core/regex.js'\nimport { globals } from '../utils/window.js'\nimport { register } from '../utils/adopter.js'\nimport { registerMethods } from '../utils/methods.js'\nimport Matrix from './Matrix.js'\nimport Point from './Point.js'\nimport parser from '../modules/core/parser.js'\n\nexport function isNulledBox(box) {\n  return !box.width && !box.height && !box.x && !box.y\n}\n\nexport function domContains(node) {\n  return (\n    node === globals.document ||\n    (\n      globals.document.documentElement.contains ||\n      function (node) {\n        // This is IE - it does not support contains() for top-level SVGs\n        while (node.parentNode) {\n          node = node.parentNode\n        }\n        return node === globals.document\n      }\n    ).call(globals.document.documentElement, node)\n  )\n}\n\nexport default class Box {\n  constructor(...args) {\n    this.init(...args)\n  }\n\n  addOffset() {\n    // offset by window scroll position, because getBoundingClientRect changes when window is scrolled\n    this.x += globals.window.pageXOffset\n    this.y += globals.window.pageYOffset\n    return new Box(this)\n  }\n\n  init(source) {\n    const base = [0, 0, 0, 0]\n    source =\n      typeof source === 'string'\n        ? source.split(delimiter).map(parseFloat)\n        : Array.isArray(source)\n          ? source\n          : typeof source === 'object'\n            ? [\n                source.left != null ? source.left : source.x,\n                source.top != null ? source.top : source.y,\n                source.width,\n                source.height\n              ]\n            : arguments.length === 4\n              ? [].slice.call(arguments)\n              : base\n\n    this.x = source[0] || 0\n    this.y = source[1] || 0\n    this.width = this.w = source[2] || 0\n    this.height = this.h = source[3] || 0\n\n    // Add more bounding box properties\n    this.x2 = this.x + this.w\n    this.y2 = this.y + this.h\n    this.cx = this.x + this.w / 2\n    this.cy = this.y + this.h / 2\n\n    return this\n  }\n\n  isNulled() {\n    return isNulledBox(this)\n  }\n\n  // Merge rect box with another, return a new instance\n  merge(box) {\n    const x = Math.min(this.x, box.x)\n    const y = Math.min(this.y, box.y)\n    const width = Math.max(this.x + this.width, box.x + box.width) - x\n    const height = Math.max(this.y + this.height, box.y + box.height) - y\n\n    return new Box(x, y, width, height)\n  }\n\n  toArray() {\n    return [this.x, this.y, this.width, this.height]\n  }\n\n  toString() {\n    return this.x + ' ' + this.y + ' ' + this.width + ' ' + this.height\n  }\n\n  transform(m) {\n    if (!(m instanceof Matrix)) {\n      m = new Matrix(m)\n    }\n\n    let xMin = Infinity\n    let xMax = -Infinity\n    let yMin = Infinity\n    let yMax = -Infinity\n\n    const pts = [\n      new Point(this.x, this.y),\n      new Point(this.x2, this.y),\n      new Point(this.x, this.y2),\n      new Point(this.x2, this.y2)\n    ]\n\n    pts.forEach(function (p) {\n      p = p.transform(m)\n      xMin = Math.min(xMin, p.x)\n      xMax = Math.max(xMax, p.x)\n      yMin = Math.min(yMin, p.y)\n      yMax = Math.max(yMax, p.y)\n    })\n\n    return new Box(xMin, yMin, xMax - xMin, yMax - yMin)\n  }\n}\n\nfunction getBox(el, getBBoxFn, retry) {\n  let box\n\n  try {\n    // Try to get the box with the provided function\n    box = getBBoxFn(el.node)\n\n    // If the box is worthless and not even in the dom, retry\n    // by throwing an error here...\n    if (isNulledBox(box) && !domContains(el.node)) {\n      throw new Error('Element not in the dom')\n    }\n  } catch (e) {\n    // ... and calling the retry handler here\n    box = retry(el)\n  }\n\n  return box\n}\n\nexport function bbox() {\n  // Function to get bbox is getBBox()\n  const getBBox = (node) => node.getBBox()\n\n  // Take all measures so that a stupid browser renders the element\n  // so we can get the bbox from it when we try again\n  const retry = (el) => {\n    try {\n      const clone = el.clone().addTo(parser().svg).show()\n      const box = clone.node.getBBox()\n      clone.remove()\n      return box\n    } catch (e) {\n      // We give up...\n      throw new Error(\n        `Getting bbox of element \"${\n          el.node.nodeName\n        }\" is not possible: ${e.toString()}`\n      )\n    }\n  }\n\n  const box = getBox(this, getBBox, retry)\n  const bbox = new Box(box)\n\n  return bbox\n}\n\nexport function rbox(el) {\n  const getRBox = (node) => node.getBoundingClientRect()\n  const retry = (el) => {\n    // There is no point in trying tricks here because if we insert the element into the dom ourselves\n    // it obviously will be at the wrong position\n    throw new Error(\n      `Getting rbox of element \"${el.node.nodeName}\" is not possible`\n    )\n  }\n\n  const box = getBox(this, getRBox, retry)\n  const rbox = new Box(box)\n\n  // If an element was passed, we want the bbox in the coordinate system of that element\n  if (el) {\n    return rbox.transform(el.screenCTM().inverseO())\n  }\n\n  // Else we want it in absolute screen coordinates\n  // Therefore we need to add the scrollOffset\n  return rbox.addOffset()\n}\n\n// Checks whether the given point is inside the bounding box\nexport function inside(x, y) {\n  const box = this.bbox()\n\n  return (\n    x > box.x && y > box.y && x < box.x + box.width && y < box.y + box.height\n  )\n}\n\nregisterMethods({\n  viewbox: {\n    viewbox(x, y, width, height) {\n      // act as getter\n      if (x == null) return new Box(this.attr('viewBox'))\n\n      // act as setter\n      return this.attr('viewBox', new Box(x, y, width, height))\n    },\n\n    zoom(level, point) {\n      // Its best to rely on the attributes here and here is why:\n      // clientXYZ: Doesn't work on non-root svgs because they dont have a CSSBox (silly!)\n      // getBoundingClientRect: Doesn't work because Chrome just ignores width and height of nested svgs completely\n      //                        that means, their clientRect is always as big as the content.\n      //                        Furthermore this size is incorrect if the element is further transformed by its parents\n      // computedStyle: Only returns meaningful values if css was used with px. We dont go this route here!\n      // getBBox: returns the bounding box of its content - that doesn't help!\n      let { width, height } = this.attr(['width', 'height'])\n\n      // Width and height is a string when a number with a unit is present which we can't use\n      // So we try clientXYZ\n      if (\n        (!width && !height) ||\n        typeof width === 'string' ||\n        typeof height === 'string'\n      ) {\n        width = this.node.clientWidth\n        height = this.node.clientHeight\n      }\n\n      // Giving up...\n      if (!width || !height) {\n        throw new Error(\n          'Impossible to get absolute width and height. Please provide an absolute width and height attribute on the zooming element'\n        )\n      }\n\n      const v = this.viewbox()\n\n      const zoomX = width / v.width\n      const zoomY = height / v.height\n      const zoom = Math.min(zoomX, zoomY)\n\n      if (level == null) {\n        return zoom\n      }\n\n      let zoomAmount = zoom / level\n\n      // Set the zoomAmount to the highest value which is safe to process and recover from\n      // The * 100 is a bit of wiggle room for the matrix transformation\n      if (zoomAmount === Infinity) zoomAmount = Number.MAX_SAFE_INTEGER / 100\n\n      point =\n        point || new Point(width / 2 / zoomX + v.x, height / 2 / zoomY + v.y)\n\n      const box = new Box(v).transform(\n        new Matrix({ scale: zoomAmount, origin: point })\n      )\n\n      return this.viewbox(box)\n    }\n  }\n})\n\nregister(Box, 'Box')\n","import { extend } from '../utils/adopter.js'\n// import { subClassArray } from './ArrayPolyfill.js'\n\nclass List extends Array {\n  constructor(arr = [], ...args) {\n    super(arr, ...args)\n    if (typeof arr === 'number') return this\n    this.length = 0\n    this.push(...arr)\n  }\n}\n\n/* = subClassArray('List', Array, function (arr = []) {\n  // This catches the case, that native map tries to create an array with new Array(1)\n  if (typeof arr === 'number') return this\n  this.length = 0\n  this.push(...arr)\n}) */\n\nexport default List\n\nextend([List], {\n  each(fnOrMethodName, ...args) {\n    if (typeof fnOrMethodName === 'function') {\n      return this.map((el, i, arr) => {\n        return fnOrMethodName.call(el, el, i, arr)\n      })\n    } else {\n      return this.map((el) => {\n        return el[fnOrMethodName](...args)\n      })\n    }\n  },\n\n  toArray() {\n    return Array.prototype.concat.apply([], this)\n  }\n})\n\nconst reserved = ['toArray', 'constructor', 'each']\n\nList.extend = function (methods) {\n  methods = methods.reduce((obj, name) => {\n    // Don't overwrite own methods\n    if (reserved.includes(name)) return obj\n\n    // Don't add private methods\n    if (name[0] === '_') return obj\n\n    // Allow access to original Array methods through a prefix\n    if (name in Array.prototype) {\n      obj['$' + name] = Array.prototype[name]\n    }\n\n    // Relay every call to each()\n    obj[name] = function (...attrs) {\n      return this.each(name, ...attrs)\n    }\n    return obj\n  }, {})\n\n  extend([List], methods)\n}\n","import { adopt } from '../../utils/adopter.js'\nimport { globals } from '../../utils/window.js'\nimport { map } from '../../utils/utils.js'\nimport List from '../../types/List.js'\n\nexport default function baseFind(query, parent) {\n  return new List(\n    map((parent || globals.document).querySelectorAll(query), function (node) {\n      return adopt(node)\n    })\n  )\n}\n\n// Scoped find method\nexport function find(query) {\n  return baseFind(query, this.node)\n}\n\nexport function findOne(query) {\n  return adopt(this.node.querySelector(query))\n}\n","import { delimiter } from './regex.js'\nimport { makeInstance } from '../../utils/adopter.js'\nimport { globals } from '../../utils/window.js'\n\nlet listenerId = 0\nexport const windowEvents = {}\n\nexport function getEvents(instance) {\n  let n = instance.getEventHolder()\n\n  // We dont want to save events in global space\n  if (n === globals.window) n = windowEvents\n  if (!n.events) n.events = {}\n  return n.events\n}\n\nexport function getEventTarget(instance) {\n  return instance.getEventTarget()\n}\n\nexport function clearEvents(instance) {\n  let n = instance.getEventHolder()\n  if (n === globals.window) n = windowEvents\n  if (n.events) n.events = {}\n}\n\n// Add event binder in the SVG namespace\nexport function on(node, events, listener, binding, options) {\n  const l = listener.bind(binding || node)\n  const instance = makeInstance(node)\n  const bag = getEvents(instance)\n  const n = getEventTarget(instance)\n\n  // events can be an array of events or a string of events\n  events = Array.isArray(events) ? events : events.split(delimiter)\n\n  // add id to listener\n  if (!listener._svgjsListenerId) {\n    listener._svgjsListenerId = ++listenerId\n  }\n\n  events.forEach(function (event) {\n    const ev = event.split('.')[0]\n    const ns = event.split('.')[1] || '*'\n\n    // ensure valid object\n    bag[ev] = bag[ev] || {}\n    bag[ev][ns] = bag[ev][ns] || {}\n\n    // reference listener\n    bag[ev][ns][listener._svgjsListenerId] = l\n\n    // add listener\n    n.addEventListener(ev, l, options || false)\n  })\n}\n\n// Add event unbinder in the SVG namespace\nexport function off(node, events, listener, options) {\n  const instance = makeInstance(node)\n  const bag = getEvents(instance)\n  const n = getEventTarget(instance)\n\n  // listener can be a function or a number\n  if (typeof listener === 'function') {\n    listener = listener._svgjsListenerId\n    if (!listener) return\n  }\n\n  // events can be an array of events or a string or undefined\n  events = Array.isArray(events) ? events : (events || '').split(delimiter)\n\n  events.forEach(function (event) {\n    const ev = event && event.split('.')[0]\n    const ns = event && event.split('.')[1]\n    let namespace, l\n\n    if (listener) {\n      // remove listener reference\n      if (bag[ev] && bag[ev][ns || '*']) {\n        // removeListener\n        n.removeEventListener(\n          ev,\n          bag[ev][ns || '*'][listener],\n          options || false\n        )\n\n        delete bag[ev][ns || '*'][listener]\n      }\n    } else if (ev && ns) {\n      // remove all listeners for a namespaced event\n      if (bag[ev] && bag[ev][ns]) {\n        for (l in bag[ev][ns]) {\n          off(n, [ev, ns].join('.'), l)\n        }\n\n        delete bag[ev][ns]\n      }\n    } else if (ns) {\n      // remove all listeners for a specific namespace\n      for (event in bag) {\n        for (namespace in bag[event]) {\n          if (ns === namespace) {\n            off(n, [event, ns].join('.'))\n          }\n        }\n      }\n    } else if (ev) {\n      // remove all listeners for the event\n      if (bag[ev]) {\n        for (namespace in bag[ev]) {\n          off(n, [ev, namespace].join('.'))\n        }\n\n        delete bag[ev]\n      }\n    } else {\n      // remove all listeners on a given node\n      for (event in bag) {\n        off(n, event)\n      }\n\n      clearEvents(instance)\n    }\n  })\n}\n\nexport function dispatch(node, event, data, options) {\n  const n = getEventTarget(node)\n\n  // Dispatch event\n  if (event instanceof globals.window.Event) {\n    n.dispatchEvent(event)\n  } else {\n    event = new globals.window.CustomEvent(event, {\n      detail: data,\n      cancelable: true,\n      ...options\n    })\n    n.dispatchEvent(event)\n  }\n  return event\n}\n","import { dispatch, off, on } from '../modules/core/event.js'\nimport { register } from '../utils/adopter.js'\nimport Base from './Base.js'\n\nexport default class EventTarget extends Base {\n  addEventListener() {}\n\n  dispatch(event, data, options) {\n    return dispatch(this, event, data, options)\n  }\n\n  dispatchEvent(event) {\n    const bag = this.getEventHolder().events\n    if (!bag) return true\n\n    const events = bag[event.type]\n\n    for (const i in events) {\n      for (const j in events[i]) {\n        events[i][j](event)\n      }\n    }\n\n    return !event.defaultPrevented\n  }\n\n  // Fire given event\n  fire(event, data, options) {\n    this.dispatch(event, data, options)\n    return this\n  }\n\n  getEventHolder() {\n    return this\n  }\n\n  getEventTarget() {\n    return this\n  }\n\n  // Unbind event from listener\n  off(event, listener, options) {\n    off(this, event, listener, options)\n    return this\n  }\n\n  // Bind given event to listener\n  on(event, listener, binding, options) {\n    on(this, event, listener, binding, options)\n    return this\n  }\n\n  removeEventListener() {}\n}\n\nregister(EventTarget, 'EventTarget')\n","export function noop() {}\n\n// Default animation values\nexport const timeline = {\n  duration: 400,\n  ease: '>',\n  delay: 0\n}\n\n// Default attribute values\nexport const attrs = {\n  // fill and stroke\n  'fill-opacity': 1,\n  'stroke-opacity': 1,\n  'stroke-width': 0,\n  'stroke-linejoin': 'miter',\n  'stroke-linecap': 'butt',\n  fill: '#000000',\n  stroke: '#000000',\n  opacity: 1,\n\n  // position\n  x: 0,\n  y: 0,\n  cx: 0,\n  cy: 0,\n\n  // size\n  width: 0,\n  height: 0,\n\n  // radius\n  r: 0,\n  rx: 0,\n  ry: 0,\n\n  // gradient\n  offset: 0,\n  'stop-opacity': 1,\n  'stop-color': '#000000',\n\n  // text\n  'text-anchor': 'start'\n}\n","import { delimiter } from '../modules/core/regex.js'\n\nexport default class SVGArray extends Array {\n  constructor(...args) {\n    super(...args)\n    this.init(...args)\n  }\n\n  clone() {\n    return new this.constructor(this)\n  }\n\n  init(arr) {\n    // This catches the case, that native map tries to create an array with new Array(1)\n    if (typeof arr === 'number') return this\n    this.length = 0\n    this.push(...this.parse(arr))\n    return this\n  }\n\n  // Parse whitespace separated string\n  parse(array = []) {\n    // If already is an array, no need to parse it\n    if (array instanceof Array) return array\n\n    return array.trim().split(delimiter).map(parseFloat)\n  }\n\n  toArray() {\n    return Array.prototype.concat.apply([], this)\n  }\n\n  toSet() {\n    return new Set(this)\n  }\n\n  toString() {\n    return this.join(' ')\n  }\n\n  // Flattens the array if needed\n  valueOf() {\n    const ret = []\n    ret.push(...this)\n    return ret\n  }\n}\n","import { numberAndUnit } from '../modules/core/regex.js'\n\n// Module for unit conversions\nexport default class SVGNumber {\n  // Initialize\n  constructor(...args) {\n    this.init(...args)\n  }\n\n  convert(unit) {\n    return new SVGNumber(this.value, unit)\n  }\n\n  // Divide number\n  divide(number) {\n    number = new SVGNumber(number)\n    return new SVGNumber(this / number, this.unit || number.unit)\n  }\n\n  init(value, unit) {\n    unit = Array.isArray(value) ? value[1] : unit\n    value = Array.isArray(value) ? value[0] : value\n\n    // initialize defaults\n    this.value = 0\n    this.unit = unit || ''\n\n    // parse value\n    if (typeof value === 'number') {\n      // ensure a valid numeric value\n      this.value = isNaN(value)\n        ? 0\n        : !isFinite(value)\n          ? value < 0\n            ? -3.4e38\n            : +3.4e38\n          : value\n    } else if (typeof value === 'string') {\n      unit = value.match(numberAndUnit)\n\n      if (unit) {\n        // make value numeric\n        this.value = parseFloat(unit[1])\n\n        // normalize\n        if (unit[5] === '%') {\n          this.value /= 100\n        } else if (unit[5] === 's') {\n          this.value *= 1000\n        }\n\n        // store unit\n        this.unit = unit[5]\n      }\n    } else {\n      if (value instanceof SVGNumber) {\n        this.value = value.valueOf()\n        this.unit = value.unit\n      }\n    }\n\n    return this\n  }\n\n  // Subtract number\n  minus(number) {\n    number = new SVGNumber(number)\n    return new SVGNumber(this - number, this.unit || number.unit)\n  }\n\n  // Add number\n  plus(number) {\n    number = new SVGNumber(number)\n    return new SVGNumber(this + number, this.unit || number.unit)\n  }\n\n  // Multiply number\n  times(number) {\n    number = new SVGNumber(number)\n    return new SVGNumber(this * number, this.unit || number.unit)\n  }\n\n  toArray() {\n    return [this.value, this.unit]\n  }\n\n  toJSON() {\n    return this.toString()\n  }\n\n  toString() {\n    return (\n      (this.unit === '%'\n        ? ~~(this.value * 1e8) / 1e6\n        : this.unit === 's'\n          ? this.value / 1e3\n          : this.value) + this.unit\n    )\n  }\n\n  valueOf() {\n    return this.value\n  }\n}\n","import { attrs as defaults } from './defaults.js'\nimport { isNumber } from './regex.js'\nimport Color from '../../types/Color.js'\nimport SVGArray from '../../types/SVGArray.js'\nimport SVGNumber from '../../types/SVGNumber.js'\n\nconst colorAttributes = new Set([\n  'fill',\n  'stroke',\n  'color',\n  'bgcolor',\n  'stop-color',\n  'flood-color',\n  'lighting-color'\n])\n\nconst hooks = []\nexport function registerAttrHook(fn) {\n  hooks.push(fn)\n}\n\n// Set svg element attribute\nexport default function attr(attr, val, ns) {\n  // act as full getter\n  if (attr == null) {\n    // get an object of attributes\n    attr = {}\n    val = this.node.attributes\n\n    for (const node of val) {\n      attr[node.nodeName] = isNumber.test(node.nodeValue)\n        ? parseFloat(node.nodeValue)\n        : node.nodeValue\n    }\n\n    return attr\n  } else if (attr instanceof Array) {\n    // loop through array and get all values\n    return attr.reduce((last, curr) => {\n      last[curr] = this.attr(curr)\n      return last\n    }, {})\n  } else if (typeof attr === 'object' && attr.constructor === Object) {\n    // apply every attribute individually if an object is passed\n    for (val in attr) this.attr(val, attr[val])\n  } else if (val === null) {\n    // remove value\n    this.node.removeAttribute(attr)\n  } else if (val == null) {\n    // act as a getter if the first and only argument is not an object\n    val = this.node.getAttribute(attr)\n    return val == null\n      ? defaults[attr]\n      : isNumber.test(val)\n        ? parseFloat(val)\n        : val\n  } else {\n    // Loop through hooks and execute them to convert value\n    val = hooks.reduce((_val, hook) => {\n      return hook(attr, _val, this)\n    }, val)\n\n    // ensure correct numeric values (also accepts NaN and Infinity)\n    if (typeof val === 'number') {\n      val = new SVGNumber(val)\n    } else if (colorAttributes.has(attr) && Color.isColor(val)) {\n      // ensure full hex color\n      val = new Color(val)\n    } else if (val.constructor === Array) {\n      // Check for plain arrays and parse array values\n      val = new SVGArray(val)\n    }\n\n    // if the passed attribute is leading...\n    if (attr === 'leading') {\n      // ... call the leading method instead\n      if (this.leading) {\n        this.leading(val)\n      }\n    } else {\n      // set given attribute on node\n      typeof ns === 'string'\n        ? this.node.setAttributeNS(ns, attr, val.toString())\n        : this.node.setAttribute(attr, val.toString())\n    }\n\n    // rebuild if required\n    if (this.rebuild && (attr === 'font-size' || attr === 'x')) {\n      this.rebuild()\n    }\n  }\n\n  return this\n}\n","import {\n  adopt,\n  assignNewId,\n  eid,\n  extend,\n  makeInstance,\n  create,\n  register\n} from '../utils/adopter.js'\nimport { find, findOne } from '../modules/core/selector.js'\nimport { globals } from '../utils/window.js'\nimport { map } from '../utils/utils.js'\nimport { svg, html } from '../modules/core/namespaces.js'\nimport EventTarget from '../types/EventTarget.js'\nimport List from '../types/List.js'\nimport attr from '../modules/core/attr.js'\n\nexport default class Dom extends EventTarget {\n  constructor(node, attrs) {\n    super()\n    this.node = node\n    this.type = node.nodeName\n\n    if (attrs && node !== attrs) {\n      this.attr(attrs)\n    }\n  }\n\n  // Add given element at a position\n  add(element, i) {\n    element = makeInstance(element)\n\n    // If non-root svg nodes are added we have to remove their namespaces\n    if (\n      element.removeNamespace &&\n      this.node instanceof globals.window.SVGElement\n    ) {\n      element.removeNamespace()\n    }\n\n    if (i == null) {\n      this.node.appendChild(element.node)\n    } else if (element.node !== this.node.childNodes[i]) {\n      this.node.insertBefore(element.node, this.node.childNodes[i])\n    }\n\n    return this\n  }\n\n  // Add element to given container and return self\n  addTo(parent, i) {\n    return makeInstance(parent).put(this, i)\n  }\n\n  // Returns all child elements\n  children() {\n    return new List(\n      map(this.node.children, function (node) {\n        return adopt(node)\n      })\n    )\n  }\n\n  // Remove all elements in this container\n  clear() {\n    // remove children\n    while (this.node.hasChildNodes()) {\n      this.node.removeChild(this.node.lastChild)\n    }\n\n    return this\n  }\n\n  // Clone element\n  clone(deep = true, assignNewIds = true) {\n    // write dom data to the dom so the clone can pickup the data\n    this.writeDataToDom()\n\n    // clone element\n    let nodeClone = this.node.cloneNode(deep)\n    if (assignNewIds) {\n      // assign new id\n      nodeClone = assignNewId(nodeClone)\n    }\n    return new this.constructor(nodeClone)\n  }\n\n  // Iterates over all children and invokes a given block\n  each(block, deep) {\n    const children = this.children()\n    let i, il\n\n    for (i = 0, il = children.length; i < il; i++) {\n      block.apply(children[i], [i, children])\n\n      if (deep) {\n        children[i].each(block, deep)\n      }\n    }\n\n    return this\n  }\n\n  element(nodeName, attrs) {\n    return this.put(new Dom(create(nodeName), attrs))\n  }\n\n  // Get first child\n  first() {\n    return adopt(this.node.firstChild)\n  }\n\n  // Get a element at the given index\n  get(i) {\n    return adopt(this.node.childNodes[i])\n  }\n\n  getEventHolder() {\n    return this.node\n  }\n\n  getEventTarget() {\n    return this.node\n  }\n\n  // Checks if the given element is a child\n  has(element) {\n    return this.index(element) >= 0\n  }\n\n  html(htmlOrFn, outerHTML) {\n    return this.xml(htmlOrFn, outerHTML, html)\n  }\n\n  // Get / set id\n  id(id) {\n    // generate new id if no id set\n    if (typeof id === 'undefined' && !this.node.id) {\n      this.node.id = eid(this.type)\n    }\n\n    // don't set directly with this.node.id to make `null` work correctly\n    return this.attr('id', id)\n  }\n\n  // Gets index of given element\n  index(element) {\n    return [].slice.call(this.node.childNodes).indexOf(element.node)\n  }\n\n  // Get the last child\n  last() {\n    return adopt(this.node.lastChild)\n  }\n\n  // matches the element vs a css selector\n  matches(selector) {\n    const el = this.node\n    const matcher =\n      el.matches ||\n      el.matchesSelector ||\n      el.msMatchesSelector ||\n      el.mozMatchesSelector ||\n      el.webkitMatchesSelector ||\n      el.oMatchesSelector ||\n      null\n    return matcher && matcher.call(el, selector)\n  }\n\n  // Returns the parent element instance\n  parent(type) {\n    let parent = this\n\n    // check for parent\n    if (!parent.node.parentNode) return null\n\n    // get parent element\n    parent = adopt(parent.node.parentNode)\n\n    if (!type) return parent\n\n    // loop through ancestors if type is given\n    do {\n      if (\n        typeof type === 'string' ? parent.matches(type) : parent instanceof type\n      )\n        return parent\n    } while ((parent = adopt(parent.node.parentNode)))\n\n    return parent\n  }\n\n  // Basically does the same as `add()` but returns the added element instead\n  put(element, i) {\n    element = makeInstance(element)\n    this.add(element, i)\n    return element\n  }\n\n  // Add element to given container and return container\n  putIn(parent, i) {\n    return makeInstance(parent).add(this, i)\n  }\n\n  // Remove element\n  remove() {\n    if (this.parent()) {\n      this.parent().removeElement(this)\n    }\n\n    return this\n  }\n\n  // Remove a given child\n  removeElement(element) {\n    this.node.removeChild(element.node)\n\n    return this\n  }\n\n  // Replace this with element\n  replace(element) {\n    element = makeInstance(element)\n\n    if (this.node.parentNode) {\n      this.node.parentNode.replaceChild(element.node, this.node)\n    }\n\n    return element\n  }\n\n  round(precision = 2, map = null) {\n    const factor = 10 ** precision\n    const attrs = this.attr(map)\n\n    for (const i in attrs) {\n      if (typeof attrs[i] === 'number') {\n        attrs[i] = Math.round(attrs[i] * factor) / factor\n      }\n    }\n\n    this.attr(attrs)\n    return this\n  }\n\n  // Import / Export raw svg\n  svg(svgOrFn, outerSVG) {\n    return this.xml(svgOrFn, outerSVG, svg)\n  }\n\n  // Return id on string conversion\n  toString() {\n    return this.id()\n  }\n\n  words(text) {\n    // This is faster than removing all children and adding a new one\n    this.node.textContent = text\n    return this\n  }\n\n  wrap(node) {\n    const parent = this.parent()\n\n    if (!parent) {\n      return this.addTo(node)\n    }\n\n    const position = parent.index(this)\n    return parent.put(node, position).put(this)\n  }\n\n  // write svgjs data to the dom\n  writeDataToDom() {\n    // dump variables recursively\n    this.each(function () {\n      this.writeDataToDom()\n    })\n\n    return this\n  }\n\n  // Import / Export raw svg\n  xml(xmlOrFn, outerXML, ns) {\n    if (typeof xmlOrFn === 'boolean') {\n      ns = outerXML\n      outerXML = xmlOrFn\n      xmlOrFn = null\n    }\n\n    // act as getter if no svg string is given\n    if (xmlOrFn == null || typeof xmlOrFn === 'function') {\n      // The default for exports is, that the outerNode is included\n      outerXML = outerXML == null ? true : outerXML\n\n      // write svgjs data to the dom\n      this.writeDataToDom()\n      let current = this\n\n      // An export modifier was passed\n      if (xmlOrFn != null) {\n        current = adopt(current.node.cloneNode(true))\n\n        // If the user wants outerHTML we need to process this node, too\n        if (outerXML) {\n          const result = xmlOrFn(current)\n          current = result || current\n\n          // The user does not want this node? Well, then he gets nothing\n          if (result === false) return ''\n        }\n\n        // Deep loop through all children and apply modifier\n        current.each(function () {\n          const result = xmlOrFn(this)\n          const _this = result || this\n\n          // If modifier returns false, discard node\n          if (result === false) {\n            this.remove()\n\n            // If modifier returns new node, use it\n          } else if (result && this !== _this) {\n            this.replace(_this)\n          }\n        }, true)\n      }\n\n      // Return outer or inner content\n      return outerXML ? current.node.outerHTML : current.node.innerHTML\n    }\n\n    // Act as setter if we got a string\n\n    // The default for import is, that the current node is not replaced\n    outerXML = outerXML == null ? false : outerXML\n\n    // Create temporary holder\n    const well = create('wrapper', ns)\n    const fragment = globals.document.createDocumentFragment()\n\n    // Dump raw svg\n    well.innerHTML = xmlOrFn\n\n    // Transplant nodes into the fragment\n    for (let len = well.children.length; len--; ) {\n      fragment.appendChild(well.firstElementChild)\n    }\n\n    const parent = this.parent()\n\n    // Add the whole fragment at once\n    return outerXML ? this.replace(fragment) && parent : this.add(fragment)\n  }\n}\n\nextend(Dom, { attr, find, findOne })\nregister(Dom, 'Dom')\n","import { bbox, rbox, inside } from '../types/Box.js'\nimport { ctm, screenCTM } from '../types/Matrix.js'\nimport {\n  extend,\n  getClass,\n  makeInstance,\n  register,\n  root\n} from '../utils/adopter.js'\nimport { globals } from '../utils/window.js'\nimport { point } from '../types/Point.js'\nimport { proportionalSize, writeDataToDom } from '../utils/utils.js'\nimport { reference } from '../modules/core/regex.js'\nimport Dom from './Dom.js'\nimport List from '../types/List.js'\nimport SVGNumber from '../types/SVGNumber.js'\n\nexport default class Element extends Dom {\n  constructor(node, attrs) {\n    super(node, attrs)\n\n    // initialize data object\n    this.dom = {}\n\n    // create circular reference\n    this.node.instance = this\n\n    if (node.hasAttribute('data-svgjs') || node.hasAttribute('svgjs:data')) {\n      // pull svgjs data from the dom (getAttributeNS doesn't work in html5)\n      this.setData(\n        JSON.parse(node.getAttribute('data-svgjs')) ??\n          JSON.parse(node.getAttribute('svgjs:data')) ??\n          {}\n      )\n    }\n  }\n\n  // Move element by its center\n  center(x, y) {\n    return this.cx(x).cy(y)\n  }\n\n  // Move by center over x-axis\n  cx(x) {\n    return x == null\n      ? this.x() + this.width() / 2\n      : this.x(x - this.width() / 2)\n  }\n\n  // Move by center over y-axis\n  cy(y) {\n    return y == null\n      ? this.y() + this.height() / 2\n      : this.y(y - this.height() / 2)\n  }\n\n  // Get defs\n  defs() {\n    const root = this.root()\n    return root && root.defs()\n  }\n\n  // Relative move over x and y axes\n  dmove(x, y) {\n    return this.dx(x).dy(y)\n  }\n\n  // Relative move over x axis\n  dx(x = 0) {\n    return this.x(new SVGNumber(x).plus(this.x()))\n  }\n\n  // Relative move over y axis\n  dy(y = 0) {\n    return this.y(new SVGNumber(y).plus(this.y()))\n  }\n\n  getEventHolder() {\n    return this\n  }\n\n  // Set height of element\n  height(height) {\n    return this.attr('height', height)\n  }\n\n  // Move element to given x and y values\n  move(x, y) {\n    return this.x(x).y(y)\n  }\n\n  // return array of all ancestors of given type up to the root svg\n  parents(until = this.root()) {\n    const isSelector = typeof until === 'string'\n    if (!isSelector) {\n      until = makeInstance(until)\n    }\n    const parents = new List()\n    let parent = this\n\n    while (\n      (parent = parent.parent()) &&\n      parent.node !== globals.document &&\n      parent.nodeName !== '#document-fragment'\n    ) {\n      parents.push(parent)\n\n      if (!isSelector && parent.node === until.node) {\n        break\n      }\n      if (isSelector && parent.matches(until)) {\n        break\n      }\n      if (parent.node === this.root().node) {\n        // We worked our way to the root and didn't match `until`\n        return null\n      }\n    }\n\n    return parents\n  }\n\n  // Get referenced element form attribute value\n  reference(attr) {\n    attr = this.attr(attr)\n    if (!attr) return null\n\n    const m = (attr + '').match(reference)\n    return m ? makeInstance(m[1]) : null\n  }\n\n  // Get parent document\n  root() {\n    const p = this.parent(getClass(root))\n    return p && p.root()\n  }\n\n  // set given data to the elements data property\n  setData(o) {\n    this.dom = o\n    return this\n  }\n\n  // Set element size to given width and height\n  size(width, height) {\n    const p = proportionalSize(this, width, height)\n\n    return this.width(new SVGNumber(p.width)).height(new SVGNumber(p.height))\n  }\n\n  // Set width of element\n  width(width) {\n    return this.attr('width', width)\n  }\n\n  // write svgjs data to the dom\n  writeDataToDom() {\n    writeDataToDom(this, this.dom)\n    return super.writeDataToDom()\n  }\n\n  // Move over x-axis\n  x(x) {\n    return this.attr('x', x)\n  }\n\n  // Move over y-axis\n  y(y) {\n    return this.attr('y', y)\n  }\n}\n\nextend(Element, {\n  bbox,\n  rbox,\n  inside,\n  point,\n  ctm,\n  screenCTM\n})\n\nregister(Element, 'Element')\n","import { registerMethods } from '../../utils/methods.js'\nimport Color from '../../types/Color.js'\nimport Element from '../../elements/Element.js'\nimport Matrix from '../../types/Matrix.js'\nimport Point from '../../types/Point.js'\nimport SVGNumber from '../../types/SVGNumber.js'\n\n// Define list of available attributes for stroke and fill\nconst sugar = {\n  stroke: [\n    'color',\n    'width',\n    'opacity',\n    'linecap',\n    'linejoin',\n    'miterlimit',\n    'dasharray',\n    'dashoffset'\n  ],\n  fill: ['color', 'opacity', 'rule'],\n  prefix: function (t, a) {\n    return a === 'color' ? t : t + '-' + a\n  }\n}\n\n// Add sugar for fill and stroke\n;['fill', 'stroke'].forEach(function (m) {\n  const extension = {}\n  let i\n\n  extension[m] = function (o) {\n    if (typeof o === 'undefined') {\n      return this.attr(m)\n    }\n    if (\n      typeof o === 'string' ||\n      o instanceof Color ||\n      Color.isRgb(o) ||\n      o instanceof Element\n    ) {\n      this.attr(m, o)\n    } else {\n      // set all attributes from sugar.fill and sugar.stroke list\n      for (i = sugar[m].length - 1; i >= 0; i--) {\n        if (o[sugar[m][i]] != null) {\n          this.attr(sugar.prefix(m, sugar[m][i]), o[sugar[m][i]])\n        }\n      }\n    }\n\n    return this\n  }\n\n  registerMethods(['Element', 'Runner'], extension)\n})\n\nregisterMethods(['Element', 'Runner'], {\n  // Let the user set the matrix directly\n  matrix: function (mat, b, c, d, e, f) {\n    // Act as a getter\n    if (mat == null) {\n      return new Matrix(this)\n    }\n\n    // Act as a setter, the user can pass a matrix or a set of numbers\n    return this.attr('transform', new Matrix(mat, b, c, d, e, f))\n  },\n\n  // Map rotation to transform\n  rotate: function (angle, cx, cy) {\n    return this.transform({ rotate: angle, ox: cx, oy: cy }, true)\n  },\n\n  // Map skew to transform\n  skew: function (x, y, cx, cy) {\n    return arguments.length === 1 || arguments.length === 3\n      ? this.transform({ skew: x, ox: y, oy: cx }, true)\n      : this.transform({ skew: [x, y], ox: cx, oy: cy }, true)\n  },\n\n  shear: function (lam, cx, cy) {\n    return this.transform({ shear: lam, ox: cx, oy: cy }, true)\n  },\n\n  // Map scale to transform\n  scale: function (x, y, cx, cy) {\n    return arguments.length === 1 || arguments.length === 3\n      ? this.transform({ scale: x, ox: y, oy: cx }, true)\n      : this.transform({ scale: [x, y], ox: cx, oy: cy }, true)\n  },\n\n  // Map translate to transform\n  translate: function (x, y) {\n    return this.transform({ translate: [x, y] }, true)\n  },\n\n  // Map relative translations to transform\n  relative: function (x, y) {\n    return this.transform({ relative: [x, y] }, true)\n  },\n\n  // Map flip to transform\n  flip: function (direction = 'both', origin = 'center') {\n    if ('xybothtrue'.indexOf(direction) === -1) {\n      origin = direction\n      direction = 'both'\n    }\n\n    return this.transform({ flip: direction, origin: origin }, true)\n  },\n\n  // Opacity\n  opacity: function (value) {\n    return this.attr('opacity', value)\n  }\n})\n\nregisterMethods('radius', {\n  // Add x and y radius\n  radius: function (x, y = x) {\n    const type = (this._element || this).type\n    return type === 'radialGradient'\n      ? this.attr('r', new SVGNumber(x))\n      : this.rx(x).ry(y)\n  }\n})\n\nregisterMethods('Path', {\n  // Get path length\n  length: function () {\n    return this.node.getTotalLength()\n  },\n  // Get point at length\n  pointAt: function (length) {\n    return new Point(this.node.getPointAtLength(length))\n  }\n})\n\nregisterMethods(['Element', 'Runner'], {\n  // Set font\n  font: function (a, v) {\n    if (typeof a === 'object') {\n      for (v in a) this.font(v, a[v])\n      return this\n    }\n\n    return a === 'leading'\n      ? this.leading(v)\n      : a === 'anchor'\n        ? this.attr('text-anchor', v)\n        : a === 'size' ||\n            a === 'family' ||\n            a === 'weight' ||\n            a === 'stretch' ||\n            a === 'variant' ||\n            a === 'style'\n          ? this.attr('font-' + a, v)\n          : this.attr(a, v)\n  }\n})\n\n// Add events to elements\nconst methods = [\n  'click',\n  'dblclick',\n  'mousedown',\n  'mouseup',\n  'mouseover',\n  'mouseout',\n  'mousemove',\n  'mouseenter',\n  'mouseleave',\n  'touchstart',\n  'touchmove',\n  'touchleave',\n  'touchend',\n  'touchcancel',\n  'contextmenu',\n  'wheel',\n  'pointerdown',\n  'pointermove',\n  'pointerup',\n  'pointerleave',\n  'pointercancel'\n].reduce(function (last, event) {\n  // add event to Element\n  const fn = function (f) {\n    if (f === null) {\n      this.off(event)\n    } else {\n      this.on(event, f)\n    }\n    return this\n  }\n\n  last[event] = fn\n  return last\n}, {})\n\nregisterMethods('Element', methods)\n","import { getOrigin, isDescriptive } from '../../utils/utils.js'\nimport { delimiter, transforms } from '../core/regex.js'\nimport { registerMethods } from '../../utils/methods.js'\nimport Matrix from '../../types/Matrix.js'\n\n// Reset all transformations\nexport function untransform() {\n  return this.attr('transform', null)\n}\n\n// merge the whole transformation chain into one matrix and returns it\nexport function matrixify() {\n  const matrix = (this.attr('transform') || '')\n    // split transformations\n    .split(transforms)\n    .slice(0, -1)\n    .map(function (str) {\n      // generate key => value pairs\n      const kv = str.trim().split('(')\n      return [\n        kv[0],\n        kv[1].split(delimiter).map(function (str) {\n          return parseFloat(str)\n        })\n      ]\n    })\n    .reverse()\n    // merge every transformation into one matrix\n    .reduce(function (matrix, transform) {\n      if (transform[0] === 'matrix') {\n        return matrix.lmultiply(Matrix.fromArray(transform[1]))\n      }\n      return matrix[transform[0]].apply(matrix, transform[1])\n    }, new Matrix())\n\n  return matrix\n}\n\n// add an element to another parent without changing the visual representation on the screen\nexport function toParent(parent, i) {\n  if (this === parent) return this\n\n  if (isDescriptive(this.node)) return this.addTo(parent, i)\n\n  const ctm = this.screenCTM()\n  const pCtm = parent.screenCTM().inverse()\n\n  this.addTo(parent, i).untransform().transform(pCtm.multiply(ctm))\n\n  return this\n}\n\n// same as above with parent equals root-svg\nexport function toRoot(i) {\n  return this.toParent(this.root(), i)\n}\n\n// Add transformations\nexport function transform(o, relative) {\n  // Act as a getter if no object was passed\n  if (o == null || typeof o === 'string') {\n    const decomposed = new Matrix(this).decompose()\n    return o == null ? decomposed : decomposed[o]\n  }\n\n  if (!Matrix.isMatrixLike(o)) {\n    // Set the origin according to the defined transform\n    o = { ...o, origin: getOrigin(o, this) }\n  }\n\n  // The user can pass a boolean, an Element or an Matrix or nothing\n  const cleanRelative = relative === true ? this : relative || false\n  const result = new Matrix(cleanRelative).transform(o)\n  return this.attr('transform', result)\n}\n\nregisterMethods('Element', {\n  untransform,\n  matrixify,\n  toParent,\n  toRoot,\n  transform\n})\n","import { register } from '../utils/adopter.js'\nimport Element from './Element.js'\n\nexport default class Container extends Element {\n  flatten() {\n    this.each(function () {\n      if (this instanceof Container) {\n        return this.flatten().ungroup()\n      }\n    })\n\n    return this\n  }\n\n  ungroup(parent = this.parent(), index = parent.index(this)) {\n    // when parent != this, we want append all elements to the end\n    index = index === -1 ? parent.children().length : index\n\n    this.each(function (i, children) {\n      // reverse each\n      return children[children.length - i - 1].toParent(parent, index)\n    })\n\n    return this.remove()\n  }\n}\n\nregister(Container, 'Container')\n","import { nodeOrNew, register } from '../utils/adopter.js'\nimport Container from './Container.js'\n\nexport default class Defs extends Container {\n  constructor(node, attrs = node) {\n    super(nodeOrNew('defs', node), attrs)\n  }\n\n  flatten() {\n    return this\n  }\n\n  ungroup() {\n    return this\n  }\n}\n\nregister(Defs, 'Defs')\n","import { register } from '../utils/adopter.js'\nimport Element from './Element.js'\n\nexport default class Shape extends Element {}\n\nregister(Shape, 'Shape')\n","import SVGNumber from '../../types/SVGNumber.js'\n\n// Radius x value\nexport function rx(rx) {\n  return this.attr('rx', rx)\n}\n\n// Radius y value\nexport function ry(ry) {\n  return this.attr('ry', ry)\n}\n\n// Move over x-axis\nexport function x(x) {\n  return x == null ? this.cx() - this.rx() : this.cx(x + this.rx())\n}\n\n// Move over y-axis\nexport function y(y) {\n  return y == null ? this.cy() - this.ry() : this.cy(y + this.ry())\n}\n\n// Move by center over x-axis\nexport function cx(x) {\n  return this.attr('cx', x)\n}\n\n// Move by center over y-axis\nexport function cy(y) {\n  return this.attr('cy', y)\n}\n\n// Set width of element\nexport function width(width) {\n  return width == null ? this.rx() * 2 : this.rx(new SVGNumber(width).divide(2))\n}\n\n// Set height of element\nexport function height(height) {\n  return height == null\n    ? this.ry() * 2\n    : this.ry(new SVGNumber(height).divide(2))\n}\n","import {\n  extend,\n  nodeOrNew,\n  register,\n  wrapWithAttrCheck\n} from '../utils/adopter.js'\nimport { proportionalSize } from '../utils/utils.js'\nimport { registerMethods } from '../utils/methods.js'\nimport SVGNumber from '../types/SVGNumber.js'\nimport Shape from './Shape.js'\nimport * as circled from '../modules/core/circled.js'\n\nexport default class Ellipse extends Shape {\n  constructor(node, attrs = node) {\n    super(nodeOrNew('ellipse', node), attrs)\n  }\n\n  size(width, height) {\n    const p = proportionalSize(this, width, height)\n\n    return this.rx(new SVGNumber(p.width).divide(2)).ry(\n      new SVGNumber(p.height).divide(2)\n    )\n  }\n}\n\nextend(Ellipse, circled)\n\nregisterMethods('Container', {\n  // Create an ellipse\n  ellipse: wrapWithAttrCheck(function (width = 0, height = width) {\n    return this.put(new Ellipse()).size(width, height).move(0, 0)\n  })\n})\n\nregister(Ellipse, 'Ellipse')\n","import Dom from './Dom.js'\nimport { globals } from '../utils/window.js'\nimport { register, create } from '../utils/adopter.js'\n\nclass Fragment extends Dom {\n  constructor(node = globals.document.createDocumentFragment()) {\n    super(node)\n  }\n\n  // Import / Export raw xml\n  xml(xmlOrFn, outerXML, ns) {\n    if (typeof xmlOrFn === 'boolean') {\n      ns = outerXML\n      outerXML = xmlOrFn\n      xmlOrFn = null\n    }\n\n    // because this is a fragment we have to put all elements into a wrapper first\n    // before we can get the innerXML from it\n    if (xmlOrFn == null || typeof xmlOrFn === 'function') {\n      const wrapper = new Dom(create('wrapper', ns))\n      wrapper.add(this.node.cloneNode(true))\n\n      return wrapper.xml(false, ns)\n    }\n\n    // Act as setter if we got a string\n    return super.xml(xmlOrFn, false, ns)\n  }\n}\n\nregister(Fragment, 'Fragment')\n\nexport default Fragment\n","import SVGNumber from '../../types/SVGNumber.js'\n\nexport function from(x, y) {\n  return (this._element || this).type === 'radialGradient'\n    ? this.attr({ fx: new SVGNumber(x), fy: new SVGNumber(y) })\n    : this.attr({ x1: new SVGNumber(x), y1: new SVGNumber(y) })\n}\n\nexport function to(x, y) {\n  return (this._element || this).type === 'radialGradient'\n    ? this.attr({ cx: new SVGNumber(x), cy: new SVGNumber(y) })\n    : this.attr({ x2: new SVGNumber(x), y2: new SVGNumber(y) })\n}\n","import {\n  extend,\n  nodeOrNew,\n  register,\n  wrapWithAttrCheck\n} from '../utils/adopter.js'\nimport { registerMethods } from '../utils/methods.js'\nimport Box from '../types/Box.js'\nimport Container from './Container.js'\nimport baseFind from '../modules/core/selector.js'\nimport * as gradiented from '../modules/core/gradiented.js'\n\nexport default class Gradient extends Container {\n  constructor(type, attrs) {\n    super(\n      nodeOrNew(type + 'Gradient', typeof type === 'string' ? null : type),\n      attrs\n    )\n  }\n\n  // custom attr to handle transform\n  attr(a, b, c) {\n    if (a === 'transform') a = 'gradientTransform'\n    return super.attr(a, b, c)\n  }\n\n  bbox() {\n    return new Box()\n  }\n\n  targets() {\n    return baseFind('svg [fill*=' + this.id() + ']')\n  }\n\n  // Alias string conversion to fill\n  toString() {\n    return this.url()\n  }\n\n  // Update gradient\n  update(block) {\n    // remove all stops\n    this.clear()\n\n    // invoke passed block\n    if (typeof block === 'function') {\n      block.call(this, this)\n    }\n\n    return this\n  }\n\n  // Return the fill id\n  url() {\n    return 'url(#' + this.id() + ')'\n  }\n}\n\nextend(Gradient, gradiented)\n\nregisterMethods({\n  Container: {\n    // Create gradient element in defs\n    gradient(...args) {\n      return this.defs().gradient(...args)\n    }\n  },\n  // define gradient\n  Defs: {\n    gradient: wrapWithAttrCheck(function (type, block) {\n      return this.put(new Gradient(type)).update(block)\n    })\n  }\n})\n\nregister(Gradient, 'Gradient')\n","import { nodeOrNew, register, wrapWithAttrCheck } from '../utils/adopter.js'\nimport { registerMethods } from '../utils/methods.js'\nimport Box from '../types/Box.js'\nimport Container from './Container.js'\nimport baseFind from '../modules/core/selector.js'\n\nexport default class Pattern extends Container {\n  // Initialize node\n  constructor(node, attrs = node) {\n    super(nodeOrNew('pattern', node), attrs)\n  }\n\n  // custom attr to handle transform\n  attr(a, b, c) {\n    if (a === 'transform') a = 'patternTransform'\n    return super.attr(a, b, c)\n  }\n\n  bbox() {\n    return new Box()\n  }\n\n  targets() {\n    return baseFind('svg [fill*=' + this.id() + ']')\n  }\n\n  // Alias string conversion to fill\n  toString() {\n    return this.url()\n  }\n\n  // Update pattern by rebuilding\n  update(block) {\n    // remove content\n    this.clear()\n\n    // invoke passed block\n    if (typeof block === 'function') {\n      block.call(this, this)\n    }\n\n    return this\n  }\n\n  // Return the fill id\n  url() {\n    return 'url(#' + this.id() + ')'\n  }\n}\n\nregisterMethods({\n  Container: {\n    // Create pattern element in defs\n    pattern(...args) {\n      return this.defs().pattern(...args)\n    }\n  },\n  Defs: {\n    pattern: wrapWithAttrCheck(function (width, height, block) {\n      return this.put(new Pattern()).update(block).attr({\n        x: 0,\n        y: 0,\n        width: width,\n        height: height,\n        patternUnits: 'userSpaceOnUse'\n      })\n    })\n  }\n})\n\nregister(Pattern, 'Pattern')\n","import { isImage } from '../modules/core/regex.js'\nimport { nodeOrNew, register, wrapWithAttrCheck } from '../utils/adopter.js'\nimport { off, on } from '../modules/core/event.js'\nimport { registerAttrHook } from '../modules/core/attr.js'\nimport { registerMethods } from '../utils/methods.js'\nimport { xlink } from '../modules/core/namespaces.js'\nimport Pattern from './Pattern.js'\nimport Shape from './Shape.js'\nimport { globals } from '../utils/window.js'\n\nexport default class Image extends Shape {\n  constructor(node, attrs = node) {\n    super(nodeOrNew('image', node), attrs)\n  }\n\n  // (re)load image\n  load(url, callback) {\n    if (!url) return this\n\n    const img = new globals.window.Image()\n\n    on(\n      img,\n      'load',\n      function (e) {\n        const p = this.parent(Pattern)\n\n        // ensure image size\n        if (this.width() === 0 && this.height() === 0) {\n          this.size(img.width, img.height)\n        }\n\n        if (p instanceof Pattern) {\n          // ensure pattern size if not set\n          if (p.width() === 0 && p.height() === 0) {\n            p.size(this.width(), this.height())\n          }\n        }\n\n        if (typeof callback === 'function') {\n          callback.call(this, e)\n        }\n      },\n      this\n    )\n\n    on(img, 'load error', function () {\n      // dont forget to unbind memory leaking events\n      off(img)\n    })\n\n    return this.attr('href', (img.src = url), xlink)\n  }\n}\n\nregisterAttrHook(function (attr, val, _this) {\n  // convert image fill and stroke to patterns\n  if (attr === 'fill' || attr === 'stroke') {\n    if (isImage.test(val)) {\n      val = _this.root().defs().image(val)\n    }\n  }\n\n  if (val instanceof Image) {\n    val = _this\n      .root()\n      .defs()\n      .pattern(0, 0, (pattern) => {\n        pattern.add(val)\n      })\n  }\n\n  return val\n})\n\nregisterMethods({\n  Container: {\n    // create image element, load image and set its size\n    image: wrapWithAttrCheck(function (source, callback) {\n      return this.put(new Image()).size(0, 0).load(source, callback)\n    })\n  }\n})\n\nregister(Image, 'Image')\n","import { delimiter } from '../modules/core/regex.js'\nimport SVGArray from './SVGArray.js'\nimport Box from './Box.js'\nimport Matrix from './Matrix.js'\n\nexport default class PointArray extends SVGArray {\n  // Get bounding box of points\n  bbox() {\n    let maxX = -Infinity\n    let maxY = -Infinity\n    let minX = Infinity\n    let minY = Infinity\n    this.forEach(function (el) {\n      maxX = Math.max(el[0], maxX)\n      maxY = Math.max(el[1], maxY)\n      minX = Math.min(el[0], minX)\n      minY = Math.min(el[1], minY)\n    })\n    return new Box(minX, minY, maxX - minX, maxY - minY)\n  }\n\n  // Move point string\n  move(x, y) {\n    const box = this.bbox()\n\n    // get relative offset\n    x -= box.x\n    y -= box.y\n\n    // move every point\n    if (!isNaN(x) && !isNaN(y)) {\n      for (let i = this.length - 1; i >= 0; i--) {\n        this[i] = [this[i][0] + x, this[i][1] + y]\n      }\n    }\n\n    return this\n  }\n\n  // Parse point string and flat array\n  parse(array = [0, 0]) {\n    const points = []\n\n    // if it is an array, we flatten it and therefore clone it to 1 depths\n    if (array instanceof Array) {\n      array = Array.prototype.concat.apply([], array)\n    } else {\n      // Else, it is considered as a string\n      // parse points\n      array = array.trim().split(delimiter).map(parseFloat)\n    }\n\n    // validate points - https://svgwg.org/svg2-draft/shapes.html#DataTypePoints\n    // Odd number of coordinates is an error. In such cases, drop the last odd coordinate.\n    if (array.length % 2 !== 0) array.pop()\n\n    // wrap points in two-tuples\n    for (let i = 0, len = array.length; i < len; i = i + 2) {\n      points.push([array[i], array[i + 1]])\n    }\n\n    return points\n  }\n\n  // Resize poly string\n  size(width, height) {\n    let i\n    const box = this.bbox()\n\n    // recalculate position of all points according to new size\n    for (i = this.length - 1; i >= 0; i--) {\n      if (box.width)\n        this[i][0] = ((this[i][0] - box.x) * width) / box.width + box.x\n      if (box.height)\n        this[i][1] = ((this[i][1] - box.y) * height) / box.height + box.y\n    }\n\n    return this\n  }\n\n  // Convert array to line object\n  toLine() {\n    return {\n      x1: this[0][0],\n      y1: this[0][1],\n      x2: this[1][0],\n      y2: this[1][1]\n    }\n  }\n\n  // Convert array to string\n  toString() {\n    const array = []\n    // convert to a poly point string\n    for (let i = 0, il = this.length; i < il; i++) {\n      array.push(this[i].join(','))\n    }\n\n    return array.join(' ')\n  }\n\n  transform(m) {\n    return this.clone().transformO(m)\n  }\n\n  // transform points with matrix (similar to Point.transform)\n  transformO(m) {\n    if (!Matrix.isMatrixLike(m)) {\n      m = new Matrix(m)\n    }\n\n    for (let i = this.length; i--; ) {\n      // Perform the matrix multiplication\n      const [x, y] = this[i]\n      this[i][0] = m.a * x + m.c * y + m.e\n      this[i][1] = m.b * x + m.d * y + m.f\n    }\n\n    return this\n  }\n}\n","import PointArray from '../../types/PointArray.js'\n\nexport const MorphArray = PointArray\n\n// Move by left top corner over x-axis\nexport function x(x) {\n  return x == null ? this.bbox().x : this.move(x, this.bbox().y)\n}\n\n// Move by left top corner over y-axis\nexport function y(y) {\n  return y == null ? this.bbox().y : this.move(this.bbox().x, y)\n}\n\n// Set width of element\nexport function width(width) {\n  const b = this.bbox()\n  return width == null ? b.width : this.size(width, b.height)\n}\n\n// Set height of element\nexport function height(height) {\n  const b = this.bbox()\n  return height == null ? b.height : this.size(b.width, height)\n}\n","import {\n  extend,\n  nodeOrNew,\n  register,\n  wrapWithAttrCheck\n} from '../utils/adopter.js'\nimport { proportionalSize } from '../utils/utils.js'\nimport { registerMethods } from '../utils/methods.js'\nimport PointArray from '../types/PointArray.js'\nimport Shape from './Shape.js'\nimport * as pointed from '../modules/core/pointed.js'\n\nexport default class Line extends Shape {\n  // Initialize node\n  constructor(node, attrs = node) {\n    super(nodeOrNew('line', node), attrs)\n  }\n\n  // Get array\n  array() {\n    return new PointArray([\n      [this.attr('x1'), this.attr('y1')],\n      [this.attr('x2'), this.attr('y2')]\n    ])\n  }\n\n  // Move by left top corner\n  move(x, y) {\n    return this.attr(this.array().move(x, y).toLine())\n  }\n\n  // Overwrite native plot() method\n  plot(x1, y1, x2, y2) {\n    if (x1 == null) {\n      return this.array()\n    } else if (typeof y1 !== 'undefined') {\n      x1 = { x1, y1, x2, y2 }\n    } else {\n      x1 = new PointArray(x1).toLine()\n    }\n\n    return this.attr(x1)\n  }\n\n  // Set element size to given width and height\n  size(width, height) {\n    const p = proportionalSize(this, width, height)\n    return this.attr(this.array().size(p.width, p.height).toLine())\n  }\n}\n\nextend(Line, pointed)\n\nregisterMethods({\n  Container: {\n    // Create a line element\n    line: wrapWithAttrCheck(function (...args) {\n      // make sure plot is called as a setter\n      // x1 is not necessarily a number, it can also be an array, a string and a PointArray\n      return Line.prototype.plot.apply(\n        this.put(new Line()),\n        args[0] != null ? args : [0, 0, 0, 0]\n      )\n    })\n  }\n})\n\nregister(Line, 'Line')\n","import { nodeOrNew, register, wrapWithAttrCheck } from '../utils/adopter.js'\nimport { registerMethods } from '../utils/methods.js'\nimport Container from './Container.js'\n\nexport default class Marker extends Container {\n  // Initialize node\n  constructor(node, attrs = node) {\n    super(nodeOrNew('marker', node), attrs)\n  }\n\n  // Set height of element\n  height(height) {\n    return this.attr('markerHeight', height)\n  }\n\n  orient(orient) {\n    return this.attr('orient', orient)\n  }\n\n  // Set marker refX and refY\n  ref(x, y) {\n    return this.attr('refX', x).attr('refY', y)\n  }\n\n  // Return the fill id\n  toString() {\n    return 'url(#' + this.id() + ')'\n  }\n\n  // Update marker\n  update(block) {\n    // remove all content\n    this.clear()\n\n    // invoke passed block\n    if (typeof block === 'function') {\n      block.call(this, this)\n    }\n\n    return this\n  }\n\n  // Set width of element\n  width(width) {\n    return this.attr('markerWidth', width)\n  }\n}\n\nregisterMethods({\n  Container: {\n    marker(...args) {\n      // Create marker element in defs\n      return this.defs().marker(...args)\n    }\n  },\n  Defs: {\n    // Create marker\n    marker: wrapWithAttrCheck(function (width, height, block) {\n      // Set default viewbox to match the width and height, set ref to cx and cy and set orient to auto\n      return this.put(new Marker())\n        .size(width, height)\n        .ref(width / 2, height / 2)\n        .viewbox(0, 0, width, height)\n        .attr('orient', 'auto')\n        .update(block)\n    })\n  },\n  marker: {\n    // Create and attach markers\n    marker(marker, width, height, block) {\n      let attr = ['marker']\n\n      // Build attribute name\n      if (marker !== 'all') attr.push(marker)\n      attr = attr.join('-')\n\n      // Set marker attribute\n      marker =\n        arguments[1] instanceof Marker\n          ? arguments[1]\n          : this.defs().marker(width, height, block)\n\n      return this.attr(attr, marker)\n    }\n  }\n})\n\nregister(Marker, 'Marker')\n","import { timeline } from '../modules/core/defaults.js'\nimport { extend } from '../utils/adopter.js'\n\n/***\nBase Class\n==========\nThe base stepper class that will be\n***/\n\nfunction makeSetterGetter(k, f) {\n  return function (v) {\n    if (v == null) return this[k]\n    this[k] = v\n    if (f) f.call(this)\n    return this\n  }\n}\n\nexport const easing = {\n  '-': function (pos) {\n    return pos\n  },\n  '<>': function (pos) {\n    return -Math.cos(pos * Math.PI) / 2 + 0.5\n  },\n  '>': function (pos) {\n    return Math.sin((pos * Math.PI) / 2)\n  },\n  '<': function (pos) {\n    return -Math.cos((pos * Math.PI) / 2) + 1\n  },\n  bezier: function (x1, y1, x2, y2) {\n    // see https://www.w3.org/TR/css-easing-1/#cubic-bezier-algo\n    return function (t) {\n      if (t < 0) {\n        if (x1 > 0) {\n          return (y1 / x1) * t\n        } else if (x2 > 0) {\n          return (y2 / x2) * t\n        } else {\n          return 0\n        }\n      } else if (t > 1) {\n        if (x2 < 1) {\n          return ((1 - y2) / (1 - x2)) * t + (y2 - x2) / (1 - x2)\n        } else if (x1 < 1) {\n          return ((1 - y1) / (1 - x1)) * t + (y1 - x1) / (1 - x1)\n        } else {\n          return 1\n        }\n      } else {\n        return 3 * t * (1 - t) ** 2 * y1 + 3 * t ** 2 * (1 - t) * y2 + t ** 3\n      }\n    }\n  },\n  // see https://www.w3.org/TR/css-easing-1/#step-timing-function-algo\n  steps: function (steps, stepPosition = 'end') {\n    // deal with \"jump-\" prefix\n    stepPosition = stepPosition.split('-').reverse()[0]\n\n    let jumps = steps\n    if (stepPosition === 'none') {\n      --jumps\n    } else if (stepPosition === 'both') {\n      ++jumps\n    }\n\n    // The beforeFlag is essentially useless\n    return (t, beforeFlag = false) => {\n      // Step is called currentStep in referenced url\n      let step = Math.floor(t * steps)\n      const jumping = (t * step) % 1 === 0\n\n      if (stepPosition === 'start' || stepPosition === 'both') {\n        ++step\n      }\n\n      if (beforeFlag && jumping) {\n        --step\n      }\n\n      if (t >= 0 && step < 0) {\n        step = 0\n      }\n\n      if (t <= 1 && step > jumps) {\n        step = jumps\n      }\n\n      return step / jumps\n    }\n  }\n}\n\nexport class Stepper {\n  done() {\n    return false\n  }\n}\n\n/***\nEasing Functions\n================\n***/\n\nexport class Ease extends Stepper {\n  constructor(fn = timeline.ease) {\n    super()\n    this.ease = easing[fn] || fn\n  }\n\n  step(from, to, pos) {\n    if (typeof from !== 'number') {\n      return pos < 1 ? from : to\n    }\n    return from + (to - from) * this.ease(pos)\n  }\n}\n\n/***\nController Types\n================\n***/\n\nexport class Controller extends Stepper {\n  constructor(fn) {\n    super()\n    this.stepper = fn\n  }\n\n  done(c) {\n    return c.done\n  }\n\n  step(current, target, dt, c) {\n    return this.stepper(current, target, dt, c)\n  }\n}\n\nfunction recalculate() {\n  // Apply the default parameters\n  const duration = (this._duration || 500) / 1000\n  const overshoot = this._overshoot || 0\n\n  // Calculate the PID natural response\n  const eps = 1e-10\n  const pi = Math.PI\n  const os = Math.log(overshoot / 100 + eps)\n  const zeta = -os / Math.sqrt(pi * pi + os * os)\n  const wn = 3.9 / (zeta * duration)\n\n  // Calculate the Spring values\n  this.d = 2 * zeta * wn\n  this.k = wn * wn\n}\n\nexport class Spring extends Controller {\n  constructor(duration = 500, overshoot = 0) {\n    super()\n    this.duration(duration).overshoot(overshoot)\n  }\n\n  step(current, target, dt, c) {\n    if (typeof current === 'string') return current\n    c.done = dt === Infinity\n    if (dt === Infinity) return target\n    if (dt === 0) return current\n\n    if (dt > 100) dt = 16\n\n    dt /= 1000\n\n    // Get the previous velocity\n    const velocity = c.velocity || 0\n\n    // Apply the control to get the new position and store it\n    const acceleration = -this.d * velocity - this.k * (current - target)\n    const newPosition = current + velocity * dt + (acceleration * dt * dt) / 2\n\n    // Store the velocity\n    c.velocity = velocity + acceleration * dt\n\n    // Figure out if we have converged, and if so, pass the value\n    c.done = Math.abs(target - newPosition) + Math.abs(velocity) < 0.002\n    return c.done ? target : newPosition\n  }\n}\n\nextend(Spring, {\n  duration: makeSetterGetter('_duration', recalculate),\n  overshoot: makeSetterGetter('_overshoot', recalculate)\n})\n\nexport class PID extends Controller {\n  constructor(p = 0.1, i = 0.01, d = 0, windup = 1000) {\n    super()\n    this.p(p).i(i).d(d).windup(windup)\n  }\n\n  step(current, target, dt, c) {\n    if (typeof current === 'string') return current\n    c.done = dt === Infinity\n\n    if (dt === Infinity) return target\n    if (dt === 0) return current\n\n    const p = target - current\n    let i = (c.integral || 0) + p * dt\n    const d = (p - (c.error || 0)) / dt\n    const windup = this._windup\n\n    // antiwindup\n    if (windup !== false) {\n      i = Math.max(-windup, Math.min(i, windup))\n    }\n\n    c.error = p\n    c.integral = i\n\n    c.done = Math.abs(p) < 0.001\n\n    return c.done ? target : current + (this.P * p + this.I * i + this.D * d)\n  }\n}\n\nextend(PID, {\n  windup: makeSetterGetter('_windup'),\n  p: makeSetterGetter('P'),\n  i: makeSetterGetter('I'),\n  d: makeSetterGetter('D')\n})\n","import { isPathLetter } from '../modules/core/regex.js'\nimport Point from '../types/Point.js'\n\nconst segmentParameters = {\n  M: 2,\n  L: 2,\n  H: 1,\n  V: 1,\n  C: 6,\n  S: 4,\n  Q: 4,\n  T: 2,\n  A: 7,\n  Z: 0\n}\n\nconst pathHandlers = {\n  M: function (c, p, p0) {\n    p.x = p0.x = c[0]\n    p.y = p0.y = c[1]\n\n    return ['M', p.x, p.y]\n  },\n  L: function (c, p) {\n    p.x = c[0]\n    p.y = c[1]\n    return ['L', c[0], c[1]]\n  },\n  H: function (c, p) {\n    p.x = c[0]\n    return ['H', c[0]]\n  },\n  V: function (c, p) {\n    p.y = c[0]\n    return ['V', c[0]]\n  },\n  C: function (c, p) {\n    p.x = c[4]\n    p.y = c[5]\n    return ['C', c[0], c[1], c[2], c[3], c[4], c[5]]\n  },\n  S: function (c, p) {\n    p.x = c[2]\n    p.y = c[3]\n    return ['S', c[0], c[1], c[2], c[3]]\n  },\n  Q: function (c, p) {\n    p.x = c[2]\n    p.y = c[3]\n    return ['Q', c[0], c[1], c[2], c[3]]\n  },\n  T: function (c, p) {\n    p.x = c[0]\n    p.y = c[1]\n    return ['T', c[0], c[1]]\n  },\n  Z: function (c, p, p0) {\n    p.x = p0.x\n    p.y = p0.y\n    return ['Z']\n  },\n  A: function (c, p) {\n    p.x = c[5]\n    p.y = c[6]\n    return ['A', c[0], c[1], c[2], c[3], c[4], c[5], c[6]]\n  }\n}\n\nconst mlhvqtcsaz = 'mlhvqtcsaz'.split('')\n\nfor (let i = 0, il = mlhvqtcsaz.length; i < il; ++i) {\n  pathHandlers[mlhvqtcsaz[i]] = (function (i) {\n    return function (c, p, p0) {\n      if (i === 'H') c[0] = c[0] + p.x\n      else if (i === 'V') c[0] = c[0] + p.y\n      else if (i === 'A') {\n        c[5] = c[5] + p.x\n        c[6] = c[6] + p.y\n      } else {\n        for (let j = 0, jl = c.length; j < jl; ++j) {\n          c[j] = c[j] + (j % 2 ? p.y : p.x)\n        }\n      }\n\n      return pathHandlers[i](c, p, p0)\n    }\n  })(mlhvqtcsaz[i].toUpperCase())\n}\n\nfunction makeAbsolut(parser) {\n  const command = parser.segment[0]\n  return pathHandlers[command](parser.segment.slice(1), parser.p, parser.p0)\n}\n\nfunction segmentComplete(parser) {\n  return (\n    parser.segment.length &&\n    parser.segment.length - 1 ===\n      segmentParameters[parser.segment[0].toUpperCase()]\n  )\n}\n\nfunction startNewSegment(parser, token) {\n  parser.inNumber && finalizeNumber(parser, false)\n  const pathLetter = isPathLetter.test(token)\n\n  if (pathLetter) {\n    parser.segment = [token]\n  } else {\n    const lastCommand = parser.lastCommand\n    const small = lastCommand.toLowerCase()\n    const isSmall = lastCommand === small\n    parser.segment = [small === 'm' ? (isSmall ? 'l' : 'L') : lastCommand]\n  }\n\n  parser.inSegment = true\n  parser.lastCommand = parser.segment[0]\n\n  return pathLetter\n}\n\nfunction finalizeNumber(parser, inNumber) {\n  if (!parser.inNumber) throw new Error('Parser Error')\n  parser.number && parser.segment.push(parseFloat(parser.number))\n  parser.inNumber = inNumber\n  parser.number = ''\n  parser.pointSeen = false\n  parser.hasExponent = false\n\n  if (segmentComplete(parser)) {\n    finalizeSegment(parser)\n  }\n}\n\nfunction finalizeSegment(parser) {\n  parser.inSegment = false\n  if (parser.absolute) {\n    parser.segment = makeAbsolut(parser)\n  }\n  parser.segments.push(parser.segment)\n}\n\nfunction isArcFlag(parser) {\n  if (!parser.segment.length) return false\n  const isArc = parser.segment[0].toUpperCase() === 'A'\n  const length = parser.segment.length\n\n  return isArc && (length === 4 || length === 5)\n}\n\nfunction isExponential(parser) {\n  return parser.lastToken.toUpperCase() === 'E'\n}\n\nconst pathDelimiters = new Set([' ', ',', '\\t', '\\n', '\\r', '\\f'])\nexport function pathParser(d, toAbsolute = true) {\n  let index = 0\n  let token = ''\n  const parser = {\n    segment: [],\n    inNumber: false,\n    number: '',\n    lastToken: '',\n    inSegment: false,\n    segments: [],\n    pointSeen: false,\n    hasExponent: false,\n    absolute: toAbsolute,\n    p0: new Point(),\n    p: new Point()\n  }\n\n  while (((parser.lastToken = token), (token = d.charAt(index++)))) {\n    if (!parser.inSegment) {\n      if (startNewSegment(parser, token)) {\n        continue\n      }\n    }\n\n    if (token === '.') {\n      if (parser.pointSeen || parser.hasExponent) {\n        finalizeNumber(parser, false)\n        --index\n        continue\n      }\n      parser.inNumber = true\n      parser.pointSeen = true\n      parser.number += token\n      continue\n    }\n\n    if (!isNaN(parseInt(token))) {\n      if (parser.number === '0' || isArcFlag(parser)) {\n        parser.inNumber = true\n        parser.number = token\n        finalizeNumber(parser, true)\n        continue\n      }\n\n      parser.inNumber = true\n      parser.number += token\n      continue\n    }\n\n    if (pathDelimiters.has(token)) {\n      if (parser.inNumber) {\n        finalizeNumber(parser, false)\n      }\n      continue\n    }\n\n    if (token === '-' || token === '+') {\n      if (parser.inNumber && !isExponential(parser)) {\n        finalizeNumber(parser, false)\n        --index\n        continue\n      }\n      parser.number += token\n      parser.inNumber = true\n      continue\n    }\n\n    if (token.toUpperCase() === 'E') {\n      parser.number += token\n      parser.hasExponent = true\n      continue\n    }\n\n    if (isPathLetter.test(token)) {\n      if (parser.inNumber) {\n        finalizeNumber(parser, false)\n      } else if (!segmentComplete(parser)) {\n        throw new Error('parser Error')\n      } else {\n        finalizeSegment(parser)\n      }\n      --index\n    }\n  }\n\n  if (parser.inNumber) {\n    finalizeNumber(parser, false)\n  }\n\n  if (parser.inSegment && segmentComplete(parser)) {\n    finalizeSegment(parser)\n  }\n\n  return parser.segments\n}\n","import SVGArray from './SVGArray.js'\nimport parser from '../modules/core/parser.js'\nimport Box from './Box.js'\nimport { pathParser } from '../utils/pathParser.js'\n\nfunction arrayToString(a) {\n  let s = ''\n  for (let i = 0, il = a.length; i < il; i++) {\n    s += a[i][0]\n\n    if (a[i][1] != null) {\n      s += a[i][1]\n\n      if (a[i][2] != null) {\n        s += ' '\n        s += a[i][2]\n\n        if (a[i][3] != null) {\n          s += ' '\n          s += a[i][3]\n          s += ' '\n          s += a[i][4]\n\n          if (a[i][5] != null) {\n            s += ' '\n            s += a[i][5]\n            s += ' '\n            s += a[i][6]\n\n            if (a[i][7] != null) {\n              s += ' '\n              s += a[i][7]\n            }\n          }\n        }\n      }\n    }\n  }\n\n  return s + ' '\n}\n\nexport default class PathArray extends SVGArray {\n  // Get bounding box of path\n  bbox() {\n    parser().path.setAttribute('d', this.toString())\n    return new Box(parser.nodes.path.getBBox())\n  }\n\n  // Move path string\n  move(x, y) {\n    // get bounding box of current situation\n    const box = this.bbox()\n\n    // get relative offset\n    x -= box.x\n    y -= box.y\n\n    if (!isNaN(x) && !isNaN(y)) {\n      // move every point\n      for (let l, i = this.length - 1; i >= 0; i--) {\n        l = this[i][0]\n\n        if (l === 'M' || l === 'L' || l === 'T') {\n          this[i][1] += x\n          this[i][2] += y\n        } else if (l === 'H') {\n          this[i][1] += x\n        } else if (l === 'V') {\n          this[i][1] += y\n        } else if (l === 'C' || l === 'S' || l === 'Q') {\n          this[i][1] += x\n          this[i][2] += y\n          this[i][3] += x\n          this[i][4] += y\n\n          if (l === 'C') {\n            this[i][5] += x\n            this[i][6] += y\n          }\n        } else if (l === 'A') {\n          this[i][6] += x\n          this[i][7] += y\n        }\n      }\n    }\n\n    return this\n  }\n\n  // Absolutize and parse path to array\n  parse(d = 'M0 0') {\n    if (Array.isArray(d)) {\n      d = Array.prototype.concat.apply([], d).toString()\n    }\n\n    return pathParser(d)\n  }\n\n  // Resize path string\n  size(width, height) {\n    // get bounding box of current situation\n    const box = this.bbox()\n    let i, l\n\n    // If the box width or height is 0 then we ignore\n    // transformations on the respective axis\n    box.width = box.width === 0 ? 1 : box.width\n    box.height = box.height === 0 ? 1 : box.height\n\n    // recalculate position of all points according to new size\n    for (i = this.length - 1; i >= 0; i--) {\n      l = this[i][0]\n\n      if (l === 'M' || l === 'L' || l === 'T') {\n        this[i][1] = ((this[i][1] - box.x) * width) / box.width + box.x\n        this[i][2] = ((this[i][2] - box.y) * height) / box.height + box.y\n      } else if (l === 'H') {\n        this[i][1] = ((this[i][1] - box.x) * width) / box.width + box.x\n      } else if (l === 'V') {\n        this[i][1] = ((this[i][1] - box.y) * height) / box.height + box.y\n      } else if (l === 'C' || l === 'S' || l === 'Q') {\n        this[i][1] = ((this[i][1] - box.x) * width) / box.width + box.x\n        this[i][2] = ((this[i][2] - box.y) * height) / box.height + box.y\n        this[i][3] = ((this[i][3] - box.x) * width) / box.width + box.x\n        this[i][4] = ((this[i][4] - box.y) * height) / box.height + box.y\n\n        if (l === 'C') {\n          this[i][5] = ((this[i][5] - box.x) * width) / box.width + box.x\n          this[i][6] = ((this[i][6] - box.y) * height) / box.height + box.y\n        }\n      } else if (l === 'A') {\n        // resize radii\n        this[i][1] = (this[i][1] * width) / box.width\n        this[i][2] = (this[i][2] * height) / box.height\n\n        // move position values\n        this[i][6] = ((this[i][6] - box.x) * width) / box.width + box.x\n        this[i][7] = ((this[i][7] - box.y) * height) / box.height + box.y\n      }\n    }\n\n    return this\n  }\n\n  // Convert array to string\n  toString() {\n    return arrayToString(this)\n  }\n}\n","import { Ease } from './Controller.js'\nimport {\n  delimiter,\n  numberAndUnit,\n  isPathLetter\n} from '../modules/core/regex.js'\nimport { extend } from '../utils/adopter.js'\nimport Color from '../types/Color.js'\nimport PathArray from '../types/PathArray.js'\nimport SVGArray from '../types/SVGArray.js'\nimport SVGNumber from '../types/SVGNumber.js'\n\nconst getClassForType = (value) => {\n  const type = typeof value\n\n  if (type === 'number') {\n    return SVGNumber\n  } else if (type === 'string') {\n    if (Color.isColor(value)) {\n      return Color\n    } else if (delimiter.test(value)) {\n      return isPathLetter.test(value) ? PathArray : SVGArray\n    } else if (numberAndUnit.test(value)) {\n      return SVGNumber\n    } else {\n      return NonMorphable\n    }\n  } else if (morphableTypes.indexOf(value.constructor) > -1) {\n    return value.constructor\n  } else if (Array.isArray(value)) {\n    return SVGArray\n  } else if (type === 'object') {\n    return ObjectBag\n  } else {\n    return NonMorphable\n  }\n}\n\nexport default class Morphable {\n  constructor(stepper) {\n    this._stepper = stepper || new Ease('-')\n\n    this._from = null\n    this._to = null\n    this._type = null\n    this._context = null\n    this._morphObj = null\n  }\n\n  at(pos) {\n    return this._morphObj.morph(\n      this._from,\n      this._to,\n      pos,\n      this._stepper,\n      this._context\n    )\n  }\n\n  done() {\n    const complete = this._context.map(this._stepper.done).reduce(function (\n      last,\n      curr\n    ) {\n      return last && curr\n    }, true)\n    return complete\n  }\n\n  from(val) {\n    if (val == null) {\n      return this._from\n    }\n\n    this._from = this._set(val)\n    return this\n  }\n\n  stepper(stepper) {\n    if (stepper == null) return this._stepper\n    this._stepper = stepper\n    return this\n  }\n\n  to(val) {\n    if (val == null) {\n      return this._to\n    }\n\n    this._to = this._set(val)\n    return this\n  }\n\n  type(type) {\n    // getter\n    if (type == null) {\n      return this._type\n    }\n\n    // setter\n    this._type = type\n    return this\n  }\n\n  _set(value) {\n    if (!this._type) {\n      this.type(getClassForType(value))\n    }\n\n    let result = new this._type(value)\n    if (this._type === Color) {\n      result = this._to\n        ? result[this._to[4]]()\n        : this._from\n          ? result[this._from[4]]()\n          : result\n    }\n\n    if (this._type === ObjectBag) {\n      result = this._to\n        ? result.align(this._to)\n        : this._from\n          ? result.align(this._from)\n          : result\n    }\n\n    result = result.toConsumable()\n\n    this._morphObj = this._morphObj || new this._type()\n    this._context =\n      this._context ||\n      Array.apply(null, Array(result.length))\n        .map(Object)\n        .map(function (o) {\n          o.done = true\n          return o\n        })\n    return result\n  }\n}\n\nexport class NonMorphable {\n  constructor(...args) {\n    this.init(...args)\n  }\n\n  init(val) {\n    val = Array.isArray(val) ? val[0] : val\n    this.value = val\n    return this\n  }\n\n  toArray() {\n    return [this.value]\n  }\n\n  valueOf() {\n    return this.value\n  }\n}\n\nexport class TransformBag {\n  constructor(...args) {\n    this.init(...args)\n  }\n\n  init(obj) {\n    if (Array.isArray(obj)) {\n      obj = {\n        scaleX: obj[0],\n        scaleY: obj[1],\n        shear: obj[2],\n        rotate: obj[3],\n        translateX: obj[4],\n        translateY: obj[5],\n        originX: obj[6],\n        originY: obj[7]\n      }\n    }\n\n    Object.assign(this, TransformBag.defaults, obj)\n    return this\n  }\n\n  toArray() {\n    const v = this\n\n    return [\n      v.scaleX,\n      v.scaleY,\n      v.shear,\n      v.rotate,\n      v.translateX,\n      v.translateY,\n      v.originX,\n      v.originY\n    ]\n  }\n}\n\nTransformBag.defaults = {\n  scaleX: 1,\n  scaleY: 1,\n  shear: 0,\n  rotate: 0,\n  translateX: 0,\n  translateY: 0,\n  originX: 0,\n  originY: 0\n}\n\nconst sortByKey = (a, b) => {\n  return a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0\n}\n\nexport class ObjectBag {\n  constructor(...args) {\n    this.init(...args)\n  }\n\n  align(other) {\n    const values = this.values\n    for (let i = 0, il = values.length; i < il; ++i) {\n      // If the type is the same we only need to check if the color is in the correct format\n      if (values[i + 1] === other[i + 1]) {\n        if (values[i + 1] === Color && other[i + 7] !== values[i + 7]) {\n          const space = other[i + 7]\n          const color = new Color(this.values.splice(i + 3, 5))\n            [space]()\n            .toArray()\n          this.values.splice(i + 3, 0, ...color)\n        }\n\n        i += values[i + 2] + 2\n        continue\n      }\n\n      if (!other[i + 1]) {\n        return this\n      }\n\n      // The types differ, so we overwrite the new type with the old one\n      // And initialize it with the types default (e.g. black for color or 0 for number)\n      const defaultObject = new other[i + 1]().toArray()\n\n      // Than we fix the values array\n      const toDelete = values[i + 2] + 3\n\n      values.splice(\n        i,\n        toDelete,\n        other[i],\n        other[i + 1],\n        other[i + 2],\n        ...defaultObject\n      )\n\n      i += values[i + 2] + 2\n    }\n    return this\n  }\n\n  init(objOrArr) {\n    this.values = []\n\n    if (Array.isArray(objOrArr)) {\n      this.values = objOrArr.slice()\n      return\n    }\n\n    objOrArr = objOrArr || {}\n    const entries = []\n\n    for (const i in objOrArr) {\n      const Type = getClassForType(objOrArr[i])\n      const val = new Type(objOrArr[i]).toArray()\n      entries.push([i, Type, val.length, ...val])\n    }\n\n    entries.sort(sortByKey)\n\n    this.values = entries.reduce((last, curr) => last.concat(curr), [])\n    return this\n  }\n\n  toArray() {\n    return this.values\n  }\n\n  valueOf() {\n    const obj = {}\n    const arr = this.values\n\n    // for (var i = 0, len = arr.length; i < len; i += 2) {\n    while (arr.length) {\n      const key = arr.shift()\n      const Type = arr.shift()\n      const num = arr.shift()\n      const values = arr.splice(0, num)\n      obj[key] = new Type(values) // .valueOf()\n    }\n\n    return obj\n  }\n}\n\nconst morphableTypes = [NonMorphable, TransformBag, ObjectBag]\n\nexport function registerMorphableType(type = []) {\n  morphableTypes.push(...[].concat(type))\n}\n\nexport function makeMorphable() {\n  extend(morphableTypes, {\n    to(val) {\n      return new Morphable()\n        .type(this.constructor)\n        .from(this.toArray()) // this.valueOf())\n        .to(val)\n    },\n    fromArray(arr) {\n      this.init(arr)\n      return this\n    },\n    toConsumable() {\n      return this.toArray()\n    },\n    morph(from, to, pos, stepper, context) {\n      const mapper = function (i, index) {\n        return stepper.step(i, to[index], pos, context[index], context)\n      }\n\n      return this.fromArray(from.map(mapper))\n    }\n  })\n}\n","import { nodeOrNew, register, wrapWithAttrCheck } from '../utils/adopter.js'\nimport { proportionalSize } from '../utils/utils.js'\nimport { registerMethods } from '../utils/methods.js'\nimport PathArray from '../types/PathArray.js'\nimport Shape from './Shape.js'\n\nexport default class Path extends Shape {\n  // Initialize node\n  constructor(node, attrs = node) {\n    super(nodeOrNew('path', node), attrs)\n  }\n\n  // Get array\n  array() {\n    return this._array || (this._array = new PathArray(this.attr('d')))\n  }\n\n  // Clear array cache\n  clear() {\n    delete this._array\n    return this\n  }\n\n  // Set height of element\n  height(height) {\n    return height == null\n      ? this.bbox().height\n      : this.size(this.bbox().width, height)\n  }\n\n  // Move by left top corner\n  move(x, y) {\n    return this.attr('d', this.array().move(x, y))\n  }\n\n  // Plot new path\n  plot(d) {\n    return d == null\n      ? this.array()\n      : this.clear().attr(\n          'd',\n          typeof d === 'string' ? d : (this._array = new PathArray(d))\n        )\n  }\n\n  // Set element size to given width and height\n  size(width, height) {\n    const p = proportionalSize(this, width, height)\n    return this.attr('d', this.array().size(p.width, p.height))\n  }\n\n  // Set width of element\n  width(width) {\n    return width == null\n      ? this.bbox().width\n      : this.size(width, this.bbox().height)\n  }\n\n  // Move by left top corner over x-axis\n  x(x) {\n    return x == null ? this.bbox().x : this.move(x, this.bbox().y)\n  }\n\n  // Move by left top corner over y-axis\n  y(y) {\n    return y == null ? this.bbox().y : this.move(this.bbox().x, y)\n  }\n}\n\n// Define morphable array\nPath.prototype.MorphArray = PathArray\n\n// Add parent method\nregisterMethods({\n  Container: {\n    // Create a wrapped path element\n    path: wrapWithAttrCheck(function (d) {\n      // make sure plot is called as a setter\n      return this.put(new Path()).plot(d || new PathArray())\n    })\n  }\n})\n\nregister(Path, 'Path')\n","import { proportionalSize } from '../../utils/utils.js'\nimport PointArray from '../../types/PointArray.js'\n\n// Get array\nexport function array() {\n  return this._array || (this._array = new PointArray(this.attr('points')))\n}\n\n// Clear array cache\nexport function clear() {\n  delete this._array\n  return this\n}\n\n// Move by left top corner\nexport function move(x, y) {\n  return this.attr('points', this.array().move(x, y))\n}\n\n// Plot new path\nexport function plot(p) {\n  return p == null\n    ? this.array()\n    : this.clear().attr(\n        'points',\n        typeof p === 'string' ? p : (this._array = new PointArray(p))\n      )\n}\n\n// Set element size to given width and height\nexport function size(width, height) {\n  const p = proportionalSize(this, width, height)\n  return this.attr('points', this.array().size(p.width, p.height))\n}\n","import {\n  extend,\n  nodeOrNew,\n  register,\n  wrapWithAttrCheck\n} from '../utils/adopter.js'\nimport { registerMethods } from '../utils/methods.js'\nimport PointArray from '../types/PointArray.js'\nimport Shape from './Shape.js'\nimport * as pointed from '../modules/core/pointed.js'\nimport * as poly from '../modules/core/poly.js'\n\nexport default class Polygon extends Shape {\n  // Initialize node\n  constructor(node, attrs = node) {\n    super(nodeOrNew('polygon', node), attrs)\n  }\n}\n\nregisterMethods({\n  Container: {\n    // Create a wrapped polygon element\n    polygon: wrapWithAttrCheck(function (p) {\n      // make sure plot is called as a setter\n      return this.put(new Polygon()).plot(p || new PointArray())\n    })\n  }\n})\n\nextend(Polygon, pointed)\nextend(Polygon, poly)\nregister(Polygon, 'Polygon')\n","import {\n  extend,\n  nodeOrNew,\n  register,\n  wrapWithAttrCheck\n} from '../utils/adopter.js'\nimport { registerMethods } from '../utils/methods.js'\nimport PointArray from '../types/PointArray.js'\nimport Shape from './Shape.js'\nimport * as pointed from '../modules/core/pointed.js'\nimport * as poly from '../modules/core/poly.js'\n\nexport default class Polyline extends Shape {\n  // Initialize node\n  constructor(node, attrs = node) {\n    super(nodeOrNew('polyline', node), attrs)\n  }\n}\n\nregisterMethods({\n  Container: {\n    // Create a wrapped polygon element\n    polyline: wrapWithAttrCheck(function (p) {\n      // make sure plot is called as a setter\n      return this.put(new Polyline()).plot(p || new PointArray())\n    })\n  }\n})\n\nextend(Polyline, pointed)\nextend(Polyline, poly)\nregister(Polyline, 'Polyline')\n","import {\n  extend,\n  nodeOrNew,\n  register,\n  wrapWithAttrCheck\n} from '../utils/adopter.js'\nimport { registerMethods } from '../utils/methods.js'\nimport { rx, ry } from '../modules/core/circled.js'\nimport Shape from './Shape.js'\n\nexport default class Rect extends Shape {\n  // Initialize node\n  constructor(node, attrs = node) {\n    super(nodeOrNew('rect', node), attrs)\n  }\n}\n\nextend(Rect, { rx, ry })\n\nregisterMethods({\n  Container: {\n    // Create a rect element\n    rect: wrapWithAttrCheck(function (width, height) {\n      return this.put(new Rect()).size(width, height)\n    })\n  }\n})\n\nregister(Rect, 'Rect')\n","export default class Queue {\n  constructor() {\n    this._first = null\n    this._last = null\n  }\n\n  // Shows us the first item in the list\n  first() {\n    return this._first && this._first.value\n  }\n\n  // Shows us the last item in the list\n  last() {\n    return this._last && this._last.value\n  }\n\n  push(value) {\n    // An item stores an id and the provided value\n    const item =\n      typeof value.next !== 'undefined'\n        ? value\n        : { value: value, next: null, prev: null }\n\n    // Deal with the queue being empty or populated\n    if (this._last) {\n      item.prev = this._last\n      this._last.next = item\n      this._last = item\n    } else {\n      this._last = item\n      this._first = item\n    }\n\n    // Return the current item\n    return item\n  }\n\n  // Removes the item that was returned from the push\n  remove(item) {\n    // Relink the previous item\n    if (item.prev) item.prev.next = item.next\n    if (item.next) item.next.prev = item.prev\n    if (item === this._last) this._last = item.prev\n    if (item === this._first) this._first = item.next\n\n    // Invalidate item\n    item.prev = null\n    item.next = null\n  }\n\n  shift() {\n    // Check if we have a value\n    const remove = this._first\n    if (!remove) return null\n\n    // If we do, remove it and relink things\n    this._first = remove.next\n    if (this._first) this._first.prev = null\n    this._last = this._first ? this._last : null\n    return remove.value\n  }\n}\n","import { globals } from '../utils/window.js'\nimport Queue from './Queue.js'\n\nconst Animator = {\n  nextDraw: null,\n  frames: new Queue(),\n  timeouts: new Queue(),\n  immediates: new Queue(),\n  timer: () => globals.window.performance || globals.window.Date,\n  transforms: [],\n\n  frame(fn) {\n    // Store the node\n    const node = Animator.frames.push({ run: fn })\n\n    // Request an animation frame if we don't have one\n    if (Animator.nextDraw === null) {\n      Animator.nextDraw = globals.window.requestAnimationFrame(Animator._draw)\n    }\n\n    // Return the node so we can remove it easily\n    return node\n  },\n\n  timeout(fn, delay) {\n    delay = delay || 0\n\n    // Work out when the event should fire\n    const time = Animator.timer().now() + delay\n\n    // Add the timeout to the end of the queue\n    const node = Animator.timeouts.push({ run: fn, time: time })\n\n    // Request another animation frame if we need one\n    if (Animator.nextDraw === null) {\n      Animator.nextDraw = globals.window.requestAnimationFrame(Animator._draw)\n    }\n\n    return node\n  },\n\n  immediate(fn) {\n    // Add the immediate fn to the end of the queue\n    const node = Animator.immediates.push(fn)\n    // Request another animation frame if we need one\n    if (Animator.nextDraw === null) {\n      Animator.nextDraw = globals.window.requestAnimationFrame(Animator._draw)\n    }\n\n    return node\n  },\n\n  cancelFrame(node) {\n    node != null && Animator.frames.remove(node)\n  },\n\n  clearTimeout(node) {\n    node != null && Animator.timeouts.remove(node)\n  },\n\n  cancelImmediate(node) {\n    node != null && Animator.immediates.remove(node)\n  },\n\n  _draw(now) {\n    // Run all the timeouts we can run, if they are not ready yet, add them\n    // to the end of the queue immediately! (bad timeouts!!! [sarcasm])\n    let nextTimeout = null\n    const lastTimeout = Animator.timeouts.last()\n    while ((nextTimeout = Animator.timeouts.shift())) {\n      // Run the timeout if its time, or push it to the end\n      if (now >= nextTimeout.time) {\n        nextTimeout.run()\n      } else {\n        Animator.timeouts.push(nextTimeout)\n      }\n\n      // If we hit the last item, we should stop shifting out more items\n      if (nextTimeout === lastTimeout) break\n    }\n\n    // Run all of the animation frames\n    let nextFrame = null\n    const lastFrame = Animator.frames.last()\n    while (nextFrame !== lastFrame && (nextFrame = Animator.frames.shift())) {\n      nextFrame.run(now)\n    }\n\n    let nextImmediate = null\n    while ((nextImmediate = Animator.immediates.shift())) {\n      nextImmediate()\n    }\n\n    // If we have remaining timeouts or frames, draw until we don't anymore\n    Animator.nextDraw =\n      Animator.timeouts.first() || Animator.frames.first()\n        ? globals.window.requestAnimationFrame(Animator._draw)\n        : null\n  }\n}\n\nexport default Animator\n","import { globals } from '../utils/window.js'\nimport { registerMethods } from '../utils/methods.js'\nimport Animator from './Animator.js'\nimport EventTarget from '../types/EventTarget.js'\n\nconst makeSchedule = function (runnerInfo) {\n  const start = runnerInfo.start\n  const duration = runnerInfo.runner.duration()\n  const end = start + duration\n  return {\n    start: start,\n    duration: duration,\n    end: end,\n    runner: runnerInfo.runner\n  }\n}\n\nconst defaultSource = function () {\n  const w = globals.window\n  return (w.performance || w.Date).now()\n}\n\nexport default class Timeline extends EventTarget {\n  // Construct a new timeline on the given element\n  constructor(timeSource = defaultSource) {\n    super()\n\n    this._timeSource = timeSource\n\n    // terminate resets all variables to their initial state\n    this.terminate()\n  }\n\n  active() {\n    return !!this._nextFrame\n  }\n\n  finish() {\n    // Go to end and pause\n    this.time(this.getEndTimeOfTimeline() + 1)\n    return this.pause()\n  }\n\n  // Calculates the end of the timeline\n  getEndTime() {\n    const lastRunnerInfo = this.getLastRunnerInfo()\n    const lastDuration = lastRunnerInfo ? lastRunnerInfo.runner.duration() : 0\n    const lastStartTime = lastRunnerInfo ? lastRunnerInfo.start : this._time\n    return lastStartTime + lastDuration\n  }\n\n  getEndTimeOfTimeline() {\n    const endTimes = this._runners.map((i) => i.start + i.runner.duration())\n    return Math.max(0, ...endTimes)\n  }\n\n  getLastRunnerInfo() {\n    return this.getRunnerInfoById(this._lastRunnerId)\n  }\n\n  getRunnerInfoById(id) {\n    return this._runners[this._runnerIds.indexOf(id)] || null\n  }\n\n  pause() {\n    this._paused = true\n    return this._continue()\n  }\n\n  persist(dtOrForever) {\n    if (dtOrForever == null) return this._persist\n    this._persist = dtOrForever\n    return this\n  }\n\n  play() {\n    // Now make sure we are not paused and continue the animation\n    this._paused = false\n    return this.updateTime()._continue()\n  }\n\n  reverse(yes) {\n    const currentSpeed = this.speed()\n    if (yes == null) return this.speed(-currentSpeed)\n\n    const positive = Math.abs(currentSpeed)\n    return this.speed(yes ? -positive : positive)\n  }\n\n  // schedules a runner on the timeline\n  schedule(runner, delay, when) {\n    if (runner == null) {\n      return this._runners.map(makeSchedule)\n    }\n\n    // The start time for the next animation can either be given explicitly,\n    // derived from the current timeline time or it can be relative to the\n    // last start time to chain animations directly\n\n    let absoluteStartTime = 0\n    const endTime = this.getEndTime()\n    delay = delay || 0\n\n    // Work out when to start the animation\n    if (when == null || when === 'last' || when === 'after') {\n      // Take the last time and increment\n      absoluteStartTime = endTime\n    } else if (when === 'absolute' || when === 'start') {\n      absoluteStartTime = delay\n      delay = 0\n    } else if (when === 'now') {\n      absoluteStartTime = this._time\n    } else if (when === 'relative') {\n      const runnerInfo = this.getRunnerInfoById(runner.id)\n      if (runnerInfo) {\n        absoluteStartTime = runnerInfo.start + delay\n        delay = 0\n      }\n    } else if (when === 'with-last') {\n      const lastRunnerInfo = this.getLastRunnerInfo()\n      const lastStartTime = lastRunnerInfo ? lastRunnerInfo.start : this._time\n      absoluteStartTime = lastStartTime\n    } else {\n      throw new Error('Invalid value for the \"when\" parameter')\n    }\n\n    // Manage runner\n    runner.unschedule()\n    runner.timeline(this)\n\n    const persist = runner.persist()\n    const runnerInfo = {\n      persist: persist === null ? this._persist : persist,\n      start: absoluteStartTime + delay,\n      runner\n    }\n\n    this._lastRunnerId = runner.id\n\n    this._runners.push(runnerInfo)\n    this._runners.sort((a, b) => a.start - b.start)\n    this._runnerIds = this._runners.map((info) => info.runner.id)\n\n    this.updateTime()._continue()\n    return this\n  }\n\n  seek(dt) {\n    return this.time(this._time + dt)\n  }\n\n  source(fn) {\n    if (fn == null) return this._timeSource\n    this._timeSource = fn\n    return this\n  }\n\n  speed(speed) {\n    if (speed == null) return this._speed\n    this._speed = speed\n    return this\n  }\n\n  stop() {\n    // Go to start and pause\n    this.time(0)\n    return this.pause()\n  }\n\n  time(time) {\n    if (time == null) return this._time\n    this._time = time\n    return this._continue(true)\n  }\n\n  // Remove the runner from this timeline\n  unschedule(runner) {\n    const index = this._runnerIds.indexOf(runner.id)\n    if (index < 0) return this\n\n    this._runners.splice(index, 1)\n    this._runnerIds.splice(index, 1)\n\n    runner.timeline(null)\n    return this\n  }\n\n  // Makes sure, that after pausing the time doesn't jump\n  updateTime() {\n    if (!this.active()) {\n      this._lastSourceTime = this._timeSource()\n    }\n    return this\n  }\n\n  // Checks if we are running and continues the animation\n  _continue(immediateStep = false) {\n    Animator.cancelFrame(this._nextFrame)\n    this._nextFrame = null\n\n    if (immediateStep) return this._stepImmediate()\n    if (this._paused) return this\n\n    this._nextFrame = Animator.frame(this._step)\n    return this\n  }\n\n  _stepFn(immediateStep = false) {\n    // Get the time delta from the last time and update the time\n    const time = this._timeSource()\n    let dtSource = time - this._lastSourceTime\n\n    if (immediateStep) dtSource = 0\n\n    const dtTime = this._speed * dtSource + (this._time - this._lastStepTime)\n    this._lastSourceTime = time\n\n    // Only update the time if we use the timeSource.\n    // Otherwise use the current time\n    if (!immediateStep) {\n      // Update the time\n      this._time += dtTime\n      this._time = this._time < 0 ? 0 : this._time\n    }\n    this._lastStepTime = this._time\n    this.fire('time', this._time)\n\n    // This is for the case that the timeline was seeked so that the time\n    // is now before the startTime of the runner. That is why we need to set\n    // the runner to position 0\n\n    // FIXME:\n    // However, resetting in insertion order leads to bugs. Considering the case,\n    // where 2 runners change the same attribute but in different times,\n    // resetting both of them will lead to the case where the later defined\n    // runner always wins the reset even if the other runner started earlier\n    // and therefore should win the attribute battle\n    // this can be solved by resetting them backwards\n    for (let k = this._runners.length; k--; ) {\n      // Get and run the current runner and ignore it if its inactive\n      const runnerInfo = this._runners[k]\n      const runner = runnerInfo.runner\n\n      // Make sure that we give the actual difference\n      // between runner start time and now\n      const dtToStart = this._time - runnerInfo.start\n\n      // Dont run runner if not started yet\n      // and try to reset it\n      if (dtToStart <= 0) {\n        runner.reset()\n      }\n    }\n\n    // Run all of the runners directly\n    let runnersLeft = false\n    for (let i = 0, len = this._runners.length; i < len; i++) {\n      // Get and run the current runner and ignore it if its inactive\n      const runnerInfo = this._runners[i]\n      const runner = runnerInfo.runner\n      let dt = dtTime\n\n      // Make sure that we give the actual difference\n      // between runner start time and now\n      const dtToStart = this._time - runnerInfo.start\n\n      // Dont run runner if not started yet\n      if (dtToStart <= 0) {\n        runnersLeft = true\n        continue\n      } else if (dtToStart < dt) {\n        // Adjust dt to make sure that animation is on point\n        dt = dtToStart\n      }\n\n      if (!runner.active()) continue\n\n      // If this runner is still going, signal that we need another animation\n      // frame, otherwise, remove the completed runner\n      const finished = runner.step(dt).done\n      if (!finished) {\n        runnersLeft = true\n        // continue\n      } else if (runnerInfo.persist !== true) {\n        // runner is finished. And runner might get removed\n        const endTime = runner.duration() - runner.time() + this._time\n\n        if (endTime + runnerInfo.persist < this._time) {\n          // Delete runner and correct index\n          runner.unschedule()\n          --i\n          --len\n        }\n      }\n    }\n\n    // Basically: we continue when there are runners right from us in time\n    // when -->, and when runners are left from us when <--\n    if (\n      (runnersLeft && !(this._speed < 0 && this._time === 0)) ||\n      (this._runnerIds.length && this._speed < 0 && this._time > 0)\n    ) {\n      this._continue()\n    } else {\n      this.pause()\n      this.fire('finished')\n    }\n\n    return this\n  }\n\n  terminate() {\n    // cleanup memory\n\n    // Store the timing variables\n    this._startTime = 0\n    this._speed = 1.0\n\n    // Determines how long a runner is hold in memory. Can be a dt or true/false\n    this._persist = 0\n\n    // Keep track of the running animations and their starting parameters\n    this._nextFrame = null\n    this._paused = true\n    this._runners = []\n    this._runnerIds = []\n    this._lastRunnerId = -1\n    this._time = 0\n    this._lastSourceTime = 0\n    this._lastStepTime = 0\n\n    // Make sure that step is always called in class context\n    this._step = this._stepFn.bind(this, false)\n    this._stepImmediate = this._stepFn.bind(this, true)\n  }\n}\n\nregisterMethods({\n  Element: {\n    timeline: function (timeline) {\n      if (timeline == null) {\n        this._timeline = this._timeline || new Timeline()\n        return this._timeline\n      } else {\n        this._timeline = timeline\n        return this\n      }\n    }\n  }\n})\n","import { Controller, Ease, Stepper } from './Controller.js'\nimport { extend, register } from '../utils/adopter.js'\nimport { from, to } from '../modules/core/gradiented.js'\nimport { getOrigin } from '../utils/utils.js'\nimport { noop, timeline } from '../modules/core/defaults.js'\nimport { registerMethods } from '../utils/methods.js'\nimport { rx, ry } from '../modules/core/circled.js'\nimport Animator from './Animator.js'\nimport Box from '../types/Box.js'\nimport EventTarget from '../types/EventTarget.js'\nimport Matrix from '../types/Matrix.js'\nimport Morphable, { TransformBag, ObjectBag } from './Morphable.js'\nimport Point from '../types/Point.js'\nimport SVGNumber from '../types/SVGNumber.js'\nimport Timeline from './Timeline.js'\n\nexport default class Runner extends EventTarget {\n  constructor(options) {\n    super()\n\n    // Store a unique id on the runner, so that we can identify it later\n    this.id = Runner.id++\n\n    // Ensure a default value\n    options = options == null ? timeline.duration : options\n\n    // Ensure that we get a controller\n    options = typeof options === 'function' ? new Controller(options) : options\n\n    // Declare all of the variables\n    this._element = null\n    this._timeline = null\n    this.done = false\n    this._queue = []\n\n    // Work out the stepper and the duration\n    this._duration = typeof options === 'number' && options\n    this._isDeclarative = options instanceof Controller\n    this._stepper = this._isDeclarative ? options : new Ease()\n\n    // We copy the current values from the timeline because they can change\n    this._history = {}\n\n    // Store the state of the runner\n    this.enabled = true\n    this._time = 0\n    this._lastTime = 0\n\n    // At creation, the runner is in reset state\n    this._reseted = true\n\n    // Save transforms applied to this runner\n    this.transforms = new Matrix()\n    this.transformId = 1\n\n    // Looping variables\n    this._haveReversed = false\n    this._reverse = false\n    this._loopsDone = 0\n    this._swing = false\n    this._wait = 0\n    this._times = 1\n\n    this._frameId = null\n\n    // Stores how long a runner is stored after being done\n    this._persist = this._isDeclarative ? true : null\n  }\n\n  static sanitise(duration, delay, when) {\n    // Initialise the default parameters\n    let times = 1\n    let swing = false\n    let wait = 0\n    duration = duration ?? timeline.duration\n    delay = delay ?? timeline.delay\n    when = when || 'last'\n\n    // If we have an object, unpack the values\n    if (typeof duration === 'object' && !(duration instanceof Stepper)) {\n      delay = duration.delay ?? delay\n      when = duration.when ?? when\n      swing = duration.swing || swing\n      times = duration.times ?? times\n      wait = duration.wait ?? wait\n      duration = duration.duration ?? timeline.duration\n    }\n\n    return {\n      duration: duration,\n      delay: delay,\n      swing: swing,\n      times: times,\n      wait: wait,\n      when: when\n    }\n  }\n\n  active(enabled) {\n    if (enabled == null) return this.enabled\n    this.enabled = enabled\n    return this\n  }\n\n  /*\n  Private Methods\n  ===============\n  Methods that shouldn't be used externally\n  */\n  addTransform(transform) {\n    this.transforms.lmultiplyO(transform)\n    return this\n  }\n\n  after(fn) {\n    return this.on('finished', fn)\n  }\n\n  animate(duration, delay, when) {\n    const o = Runner.sanitise(duration, delay, when)\n    const runner = new Runner(o.duration)\n    if (this._timeline) runner.timeline(this._timeline)\n    if (this._element) runner.element(this._element)\n    return runner.loop(o).schedule(o.delay, o.when)\n  }\n\n  clearTransform() {\n    this.transforms = new Matrix()\n    return this\n  }\n\n  // TODO: Keep track of all transformations so that deletion is faster\n  clearTransformsFromQueue() {\n    if (\n      !this.done ||\n      !this._timeline ||\n      !this._timeline._runnerIds.includes(this.id)\n    ) {\n      this._queue = this._queue.filter((item) => {\n        return !item.isTransform\n      })\n    }\n  }\n\n  delay(delay) {\n    return this.animate(0, delay)\n  }\n\n  duration() {\n    return this._times * (this._wait + this._duration) - this._wait\n  }\n\n  during(fn) {\n    return this.queue(null, fn)\n  }\n\n  ease(fn) {\n    this._stepper = new Ease(fn)\n    return this\n  }\n  /*\n  Runner Definitions\n  ==================\n  These methods help us define the runtime behaviour of the Runner or they\n  help us make new runners from the current runner\n  */\n\n  element(element) {\n    if (element == null) return this._element\n    this._element = element\n    element._prepareRunner()\n    return this\n  }\n\n  finish() {\n    return this.step(Infinity)\n  }\n\n  loop(times, swing, wait) {\n    // Deal with the user passing in an object\n    if (typeof times === 'object') {\n      swing = times.swing\n      wait = times.wait\n      times = times.times\n    }\n\n    // Sanitise the values and store them\n    this._times = times || Infinity\n    this._swing = swing || false\n    this._wait = wait || 0\n\n    // Allow true to be passed\n    if (this._times === true) {\n      this._times = Infinity\n    }\n\n    return this\n  }\n\n  loops(p) {\n    const loopDuration = this._duration + this._wait\n    if (p == null) {\n      const loopsDone = Math.floor(this._time / loopDuration)\n      const relativeTime = this._time - loopsDone * loopDuration\n      const position = relativeTime / this._duration\n      return Math.min(loopsDone + position, this._times)\n    }\n    const whole = Math.floor(p)\n    const partial = p % 1\n    const time = loopDuration * whole + this._duration * partial\n    return this.time(time)\n  }\n\n  persist(dtOrForever) {\n    if (dtOrForever == null) return this._persist\n    this._persist = dtOrForever\n    return this\n  }\n\n  position(p) {\n    // Get all of the variables we need\n    const x = this._time\n    const d = this._duration\n    const w = this._wait\n    const t = this._times\n    const s = this._swing\n    const r = this._reverse\n    let position\n\n    if (p == null) {\n      /*\n      This function converts a time to a position in the range [0, 1]\n      The full explanation can be found in this desmos demonstration\n        https://www.desmos.com/calculator/u4fbavgche\n      The logic is slightly simplified here because we can use booleans\n      */\n\n      // Figure out the value without thinking about the start or end time\n      const f = function (x) {\n        const swinging = s * Math.floor((x % (2 * (w + d))) / (w + d))\n        const backwards = (swinging && !r) || (!swinging && r)\n        const uncliped =\n          (Math.pow(-1, backwards) * (x % (w + d))) / d + backwards\n        const clipped = Math.max(Math.min(uncliped, 1), 0)\n        return clipped\n      }\n\n      // Figure out the value by incorporating the start time\n      const endTime = t * (w + d) - w\n      position =\n        x <= 0\n          ? Math.round(f(1e-5))\n          : x < endTime\n            ? f(x)\n            : Math.round(f(endTime - 1e-5))\n      return position\n    }\n\n    // Work out the loops done and add the position to the loops done\n    const loopsDone = Math.floor(this.loops())\n    const swingForward = s && loopsDone % 2 === 0\n    const forwards = (swingForward && !r) || (r && swingForward)\n    position = loopsDone + (forwards ? p : 1 - p)\n    return this.loops(position)\n  }\n\n  progress(p) {\n    if (p == null) {\n      return Math.min(1, this._time / this.duration())\n    }\n    return this.time(p * this.duration())\n  }\n\n  /*\n  Basic Functionality\n  ===================\n  These methods allow us to attach basic functions to the runner directly\n  */\n  queue(initFn, runFn, retargetFn, isTransform) {\n    this._queue.push({\n      initialiser: initFn || noop,\n      runner: runFn || noop,\n      retarget: retargetFn,\n      isTransform: isTransform,\n      initialised: false,\n      finished: false\n    })\n    const timeline = this.timeline()\n    timeline && this.timeline()._continue()\n    return this\n  }\n\n  reset() {\n    if (this._reseted) return this\n    this.time(0)\n    this._reseted = true\n    return this\n  }\n\n  reverse(reverse) {\n    this._reverse = reverse == null ? !this._reverse : reverse\n    return this\n  }\n\n  schedule(timeline, delay, when) {\n    // The user doesn't need to pass a timeline if we already have one\n    if (!(timeline instanceof Timeline)) {\n      when = delay\n      delay = timeline\n      timeline = this.timeline()\n    }\n\n    // If there is no timeline, yell at the user...\n    if (!timeline) {\n      throw Error('Runner cannot be scheduled without timeline')\n    }\n\n    // Schedule the runner on the timeline provided\n    timeline.schedule(this, delay, when)\n    return this\n  }\n\n  step(dt) {\n    // If we are inactive, this stepper just gets skipped\n    if (!this.enabled) return this\n\n    // Update the time and get the new position\n    dt = dt == null ? 16 : dt\n    this._time += dt\n    const position = this.position()\n\n    // Figure out if we need to run the stepper in this frame\n    const running = this._lastPosition !== position && this._time >= 0\n    this._lastPosition = position\n\n    // Figure out if we just started\n    const duration = this.duration()\n    const justStarted = this._lastTime <= 0 && this._time > 0\n    const justFinished = this._lastTime < duration && this._time >= duration\n\n    this._lastTime = this._time\n    if (justStarted) {\n      this.fire('start', this)\n    }\n\n    // Work out if the runner is finished set the done flag here so animations\n    // know, that they are running in the last step (this is good for\n    // transformations which can be merged)\n    const declarative = this._isDeclarative\n    this.done = !declarative && !justFinished && this._time >= duration\n\n    // Runner is running. So its not in reset state anymore\n    this._reseted = false\n\n    let converged = false\n    // Call initialise and the run function\n    if (running || declarative) {\n      this._initialise(running)\n\n      // clear the transforms on this runner so they dont get added again and again\n      this.transforms = new Matrix()\n      converged = this._run(declarative ? dt : position)\n\n      this.fire('step', this)\n    }\n    // correct the done flag here\n    // declarative animations itself know when they converged\n    this.done = this.done || (converged && declarative)\n    if (justFinished) {\n      this.fire('finished', this)\n    }\n    return this\n  }\n\n  /*\n  Runner animation methods\n  ========================\n  Control how the animation plays\n  */\n  time(time) {\n    if (time == null) {\n      return this._time\n    }\n    const dt = time - this._time\n    this.step(dt)\n    return this\n  }\n\n  timeline(timeline) {\n    // check explicitly for undefined so we can set the timeline to null\n    if (typeof timeline === 'undefined') return this._timeline\n    this._timeline = timeline\n    return this\n  }\n\n  unschedule() {\n    const timeline = this.timeline()\n    timeline && timeline.unschedule(this)\n    return this\n  }\n\n  // Run each initialise function in the runner if required\n  _initialise(running) {\n    // If we aren't running, we shouldn't initialise when not declarative\n    if (!running && !this._isDeclarative) return\n\n    // Loop through all of the initialisers\n    for (let i = 0, len = this._queue.length; i < len; ++i) {\n      // Get the current initialiser\n      const current = this._queue[i]\n\n      // Determine whether we need to initialise\n      const needsIt = this._isDeclarative || (!current.initialised && running)\n      running = !current.finished\n\n      // Call the initialiser if we need to\n      if (needsIt && running) {\n        current.initialiser.call(this)\n        current.initialised = true\n      }\n    }\n  }\n\n  // Save a morpher to the morpher list so that we can retarget it later\n  _rememberMorpher(method, morpher) {\n    this._history[method] = {\n      morpher: morpher,\n      caller: this._queue[this._queue.length - 1]\n    }\n\n    // We have to resume the timeline in case a controller\n    // is already done without being ever run\n    // This can happen when e.g. this is done:\n    //    anim = el.animate(new SVG.Spring)\n    // and later\n    //    anim.move(...)\n    if (this._isDeclarative) {\n      const timeline = this.timeline()\n      timeline && timeline.play()\n    }\n  }\n\n  // Try to set the target for a morpher if the morpher exists, otherwise\n  // Run each run function for the position or dt given\n  _run(positionOrDt) {\n    // Run all of the _queue directly\n    let allfinished = true\n    for (let i = 0, len = this._queue.length; i < len; ++i) {\n      // Get the current function to run\n      const current = this._queue[i]\n\n      // Run the function if its not finished, we keep track of the finished\n      // flag for the sake of declarative _queue\n      const converged = current.runner.call(this, positionOrDt)\n      current.finished = current.finished || converged === true\n      allfinished = allfinished && current.finished\n    }\n\n    // We report when all of the constructors are finished\n    return allfinished\n  }\n\n  // do nothing and return false\n  _tryRetarget(method, target, extra) {\n    if (this._history[method]) {\n      // if the last method wasn't even initialised, throw it away\n      if (!this._history[method].caller.initialised) {\n        const index = this._queue.indexOf(this._history[method].caller)\n        this._queue.splice(index, 1)\n        return false\n      }\n\n      // for the case of transformations, we use the special retarget function\n      // which has access to the outer scope\n      if (this._history[method].caller.retarget) {\n        this._history[method].caller.retarget.call(this, target, extra)\n        // for everything else a simple morpher change is sufficient\n      } else {\n        this._history[method].morpher.to(target)\n      }\n\n      this._history[method].caller.finished = false\n      const timeline = this.timeline()\n      timeline && timeline.play()\n      return true\n    }\n    return false\n  }\n}\n\nRunner.id = 0\n\nexport class FakeRunner {\n  constructor(transforms = new Matrix(), id = -1, done = true) {\n    this.transforms = transforms\n    this.id = id\n    this.done = done\n  }\n\n  clearTransformsFromQueue() {}\n}\n\nextend([Runner, FakeRunner], {\n  mergeWith(runner) {\n    return new FakeRunner(\n      runner.transforms.lmultiply(this.transforms),\n      runner.id\n    )\n  }\n})\n\n// FakeRunner.emptyRunner = new FakeRunner()\n\nconst lmultiply = (last, curr) => last.lmultiplyO(curr)\nconst getRunnerTransform = (runner) => runner.transforms\n\nfunction mergeTransforms() {\n  // Find the matrix to apply to the element and apply it\n  const runners = this._transformationRunners.runners\n  const netTransform = runners\n    .map(getRunnerTransform)\n    .reduce(lmultiply, new Matrix())\n\n  this.transform(netTransform)\n\n  this._transformationRunners.merge()\n\n  if (this._transformationRunners.length() === 1) {\n    this._frameId = null\n  }\n}\n\nexport class RunnerArray {\n  constructor() {\n    this.runners = []\n    this.ids = []\n  }\n\n  add(runner) {\n    if (this.runners.includes(runner)) return\n    const id = runner.id + 1\n\n    this.runners.push(runner)\n    this.ids.push(id)\n\n    return this\n  }\n\n  clearBefore(id) {\n    const deleteCnt = this.ids.indexOf(id + 1) || 1\n    this.ids.splice(0, deleteCnt, 0)\n    this.runners\n      .splice(0, deleteCnt, new FakeRunner())\n      .forEach((r) => r.clearTransformsFromQueue())\n    return this\n  }\n\n  edit(id, newRunner) {\n    const index = this.ids.indexOf(id + 1)\n    this.ids.splice(index, 1, id + 1)\n    this.runners.splice(index, 1, newRunner)\n    return this\n  }\n\n  getByID(id) {\n    return this.runners[this.ids.indexOf(id + 1)]\n  }\n\n  length() {\n    return this.ids.length\n  }\n\n  merge() {\n    let lastRunner = null\n    for (let i = 0; i < this.runners.length; ++i) {\n      const runner = this.runners[i]\n\n      const condition =\n        lastRunner &&\n        runner.done &&\n        lastRunner.done &&\n        // don't merge runner when persisted on timeline\n        (!runner._timeline ||\n          !runner._timeline._runnerIds.includes(runner.id)) &&\n        (!lastRunner._timeline ||\n          !lastRunner._timeline._runnerIds.includes(lastRunner.id))\n\n      if (condition) {\n        // the +1 happens in the function\n        this.remove(runner.id)\n        const newRunner = runner.mergeWith(lastRunner)\n        this.edit(lastRunner.id, newRunner)\n        lastRunner = newRunner\n        --i\n      } else {\n        lastRunner = runner\n      }\n    }\n\n    return this\n  }\n\n  remove(id) {\n    const index = this.ids.indexOf(id + 1)\n    this.ids.splice(index, 1)\n    this.runners.splice(index, 1)\n    return this\n  }\n}\n\nregisterMethods({\n  Element: {\n    animate(duration, delay, when) {\n      const o = Runner.sanitise(duration, delay, when)\n      const timeline = this.timeline()\n      return new Runner(o.duration)\n        .loop(o)\n        .element(this)\n        .timeline(timeline.play())\n        .schedule(o.delay, o.when)\n    },\n\n    delay(by, when) {\n      return this.animate(0, by, when)\n    },\n\n    // this function searches for all runners on the element and deletes the ones\n    // which run before the current one. This is because absolute transformations\n    // overwrite anything anyway so there is no need to waste time computing\n    // other runners\n    _clearTransformRunnersBefore(currentRunner) {\n      this._transformationRunners.clearBefore(currentRunner.id)\n    },\n\n    _currentTransform(current) {\n      return (\n        this._transformationRunners.runners\n          // we need the equal sign here to make sure, that also transformations\n          // on the same runner which execute before the current transformation are\n          // taken into account\n          .filter((runner) => runner.id <= current.id)\n          .map(getRunnerTransform)\n          .reduce(lmultiply, new Matrix())\n      )\n    },\n\n    _addRunner(runner) {\n      this._transformationRunners.add(runner)\n\n      // Make sure that the runner merge is executed at the very end of\n      // all Animator functions. That is why we use immediate here to execute\n      // the merge right after all frames are run\n      Animator.cancelImmediate(this._frameId)\n      this._frameId = Animator.immediate(mergeTransforms.bind(this))\n    },\n\n    _prepareRunner() {\n      if (this._frameId == null) {\n        this._transformationRunners = new RunnerArray().add(\n          new FakeRunner(new Matrix(this))\n        )\n      }\n    }\n  }\n})\n\n// Will output the elements from array A that are not in the array B\nconst difference = (a, b) => a.filter((x) => !b.includes(x))\n\nextend(Runner, {\n  attr(a, v) {\n    return this.styleAttr('attr', a, v)\n  },\n\n  // Add animatable styles\n  css(s, v) {\n    return this.styleAttr('css', s, v)\n  },\n\n  styleAttr(type, nameOrAttrs, val) {\n    if (typeof nameOrAttrs === 'string') {\n      return this.styleAttr(type, { [nameOrAttrs]: val })\n    }\n\n    let attrs = nameOrAttrs\n    if (this._tryRetarget(type, attrs)) return this\n\n    let morpher = new Morphable(this._stepper).to(attrs)\n    let keys = Object.keys(attrs)\n\n    this.queue(\n      function () {\n        morpher = morpher.from(this.element()[type](keys))\n      },\n      function (pos) {\n        this.element()[type](morpher.at(pos).valueOf())\n        return morpher.done()\n      },\n      function (newToAttrs) {\n        // Check if any new keys were added\n        const newKeys = Object.keys(newToAttrs)\n        const differences = difference(newKeys, keys)\n\n        // If their are new keys, initialize them and add them to morpher\n        if (differences.length) {\n          // Get the values\n          const addedFromAttrs = this.element()[type](differences)\n\n          // Get the already initialized values\n          const oldFromAttrs = new ObjectBag(morpher.from()).valueOf()\n\n          // Merge old and new\n          Object.assign(oldFromAttrs, addedFromAttrs)\n          morpher.from(oldFromAttrs)\n        }\n\n        // Get the object from the morpher\n        const oldToAttrs = new ObjectBag(morpher.to()).valueOf()\n\n        // Merge in new attributes\n        Object.assign(oldToAttrs, newToAttrs)\n\n        // Change morpher target\n        morpher.to(oldToAttrs)\n\n        // Make sure that we save the work we did so we don't need it to do again\n        keys = newKeys\n        attrs = newToAttrs\n      }\n    )\n\n    this._rememberMorpher(type, morpher)\n    return this\n  },\n\n  zoom(level, point) {\n    if (this._tryRetarget('zoom', level, point)) return this\n\n    let morpher = new Morphable(this._stepper).to(new SVGNumber(level))\n\n    this.queue(\n      function () {\n        morpher = morpher.from(this.element().zoom())\n      },\n      function (pos) {\n        this.element().zoom(morpher.at(pos), point)\n        return morpher.done()\n      },\n      function (newLevel, newPoint) {\n        point = newPoint\n        morpher.to(newLevel)\n      }\n    )\n\n    this._rememberMorpher('zoom', morpher)\n    return this\n  },\n\n  /**\n   ** absolute transformations\n   **/\n\n  //\n  // M v -----|-----(D M v = F v)------|----->  T v\n  //\n  // 1. define the final state (T) and decompose it (once)\n  //    t = [tx, ty, the, lam, sy, sx]\n  // 2. on every frame: pull the current state of all previous transforms\n  //    (M - m can change)\n  //   and then write this as m = [tx0, ty0, the0, lam0, sy0, sx0]\n  // 3. Find the interpolated matrix F(pos) = m + pos * (t - m)\n  //   - Note F(0) = M\n  //   - Note F(1) = T\n  // 4. Now you get the delta matrix as a result: D = F * inv(M)\n\n  transform(transforms, relative, affine) {\n    // If we have a declarative function, we should retarget it if possible\n    relative = transforms.relative || relative\n    if (\n      this._isDeclarative &&\n      !relative &&\n      this._tryRetarget('transform', transforms)\n    ) {\n      return this\n    }\n\n    // Parse the parameters\n    const isMatrix = Matrix.isMatrixLike(transforms)\n    affine =\n      transforms.affine != null\n        ? transforms.affine\n        : affine != null\n          ? affine\n          : !isMatrix\n\n    // Create a morpher and set its type\n    const morpher = new Morphable(this._stepper).type(\n      affine ? TransformBag : Matrix\n    )\n\n    let origin\n    let element\n    let current\n    let currentAngle\n    let startTransform\n\n    function setup() {\n      // make sure element and origin is defined\n      element = element || this.element()\n      origin = origin || getOrigin(transforms, element)\n\n      startTransform = new Matrix(relative ? undefined : element)\n\n      // add the runner to the element so it can merge transformations\n      element._addRunner(this)\n\n      // Deactivate all transforms that have run so far if we are absolute\n      if (!relative) {\n        element._clearTransformRunnersBefore(this)\n      }\n    }\n\n    function run(pos) {\n      // clear all other transforms before this in case something is saved\n      // on this runner. We are absolute. We dont need these!\n      if (!relative) this.clearTransform()\n\n      const { x, y } = new Point(origin).transform(\n        element._currentTransform(this)\n      )\n\n      let target = new Matrix({ ...transforms, origin: [x, y] })\n      let start = this._isDeclarative && current ? current : startTransform\n\n      if (affine) {\n        target = target.decompose(x, y)\n        start = start.decompose(x, y)\n\n        // Get the current and target angle as it was set\n        const rTarget = target.rotate\n        const rCurrent = start.rotate\n\n        // Figure out the shortest path to rotate directly\n        const possibilities = [rTarget - 360, rTarget, rTarget + 360]\n        const distances = possibilities.map((a) => Math.abs(a - rCurrent))\n        const shortest = Math.min(...distances)\n        const index = distances.indexOf(shortest)\n        target.rotate = possibilities[index]\n      }\n\n      if (relative) {\n        // we have to be careful here not to overwrite the rotation\n        // with the rotate method of Matrix\n        if (!isMatrix) {\n          target.rotate = transforms.rotate || 0\n        }\n        if (this._isDeclarative && currentAngle) {\n          start.rotate = currentAngle\n        }\n      }\n\n      morpher.from(start)\n      morpher.to(target)\n\n      const affineParameters = morpher.at(pos)\n      currentAngle = affineParameters.rotate\n      current = new Matrix(affineParameters)\n\n      this.addTransform(current)\n      element._addRunner(this)\n      return morpher.done()\n    }\n\n    function retarget(newTransforms) {\n      // only get a new origin if it changed since the last call\n      if (\n        (newTransforms.origin || 'center').toString() !==\n        (transforms.origin || 'center').toString()\n      ) {\n        origin = getOrigin(newTransforms, element)\n      }\n\n      // overwrite the old transformations with the new ones\n      transforms = { ...newTransforms, origin }\n    }\n\n    this.queue(setup, run, retarget, true)\n    this._isDeclarative && this._rememberMorpher('transform', morpher)\n    return this\n  },\n\n  // Animatable x-axis\n  x(x) {\n    return this._queueNumber('x', x)\n  },\n\n  // Animatable y-axis\n  y(y) {\n    return this._queueNumber('y', y)\n  },\n\n  ax(x) {\n    return this._queueNumber('ax', x)\n  },\n\n  ay(y) {\n    return this._queueNumber('ay', y)\n  },\n\n  dx(x = 0) {\n    return this._queueNumberDelta('x', x)\n  },\n\n  dy(y = 0) {\n    return this._queueNumberDelta('y', y)\n  },\n\n  dmove(x, y) {\n    return this.dx(x).dy(y)\n  },\n\n  _queueNumberDelta(method, to) {\n    to = new SVGNumber(to)\n\n    // Try to change the target if we have this method already registered\n    if (this._tryRetarget(method, to)) return this\n\n    // Make a morpher and queue the animation\n    const morpher = new Morphable(this._stepper).to(to)\n    let from = null\n    this.queue(\n      function () {\n        from = this.element()[method]()\n        morpher.from(from)\n        morpher.to(from + to)\n      },\n      function (pos) {\n        this.element()[method](morpher.at(pos))\n        return morpher.done()\n      },\n      function (newTo) {\n        morpher.to(from + new SVGNumber(newTo))\n      }\n    )\n\n    // Register the morpher so that if it is changed again, we can retarget it\n    this._rememberMorpher(method, morpher)\n    return this\n  },\n\n  _queueObject(method, to) {\n    // Try to change the target if we have this method already registered\n    if (this._tryRetarget(method, to)) return this\n\n    // Make a morpher and queue the animation\n    const morpher = new Morphable(this._stepper).to(to)\n    this.queue(\n      function () {\n        morpher.from(this.element()[method]())\n      },\n      function (pos) {\n        this.element()[method](morpher.at(pos))\n        return morpher.done()\n      }\n    )\n\n    // Register the morpher so that if it is changed again, we can retarget it\n    this._rememberMorpher(method, morpher)\n    return this\n  },\n\n  _queueNumber(method, value) {\n    return this._queueObject(method, new SVGNumber(value))\n  },\n\n  // Animatable center x-axis\n  cx(x) {\n    return this._queueNumber('cx', x)\n  },\n\n  // Animatable center y-axis\n  cy(y) {\n    return this._queueNumber('cy', y)\n  },\n\n  // Add animatable move\n  move(x, y) {\n    return this.x(x).y(y)\n  },\n\n  amove(x, y) {\n    return this.ax(x).ay(y)\n  },\n\n  // Add animatable center\n  center(x, y) {\n    return this.cx(x).cy(y)\n  },\n\n  // Add animatable size\n  size(width, height) {\n    // animate bbox based size for all other elements\n    let box\n\n    if (!width || !height) {\n      box = this._element.bbox()\n    }\n\n    if (!width) {\n      width = (box.width / box.height) * height\n    }\n\n    if (!height) {\n      height = (box.height / box.width) * width\n    }\n\n    return this.width(width).height(height)\n  },\n\n  // Add animatable width\n  width(width) {\n    return this._queueNumber('width', width)\n  },\n\n  // Add animatable height\n  height(height) {\n    return this._queueNumber('height', height)\n  },\n\n  // Add animatable plot\n  plot(a, b, c, d) {\n    // Lines can be plotted with 4 arguments\n    if (arguments.length === 4) {\n      return this.plot([a, b, c, d])\n    }\n\n    if (this._tryRetarget('plot', a)) return this\n\n    const morpher = new Morphable(this._stepper)\n      .type(this._element.MorphArray)\n      .to(a)\n\n    this.queue(\n      function () {\n        morpher.from(this._element.array())\n      },\n      function (pos) {\n        this._element.plot(morpher.at(pos))\n        return morpher.done()\n      }\n    )\n\n    this._rememberMorpher('plot', morpher)\n    return this\n  },\n\n  // Add leading method\n  leading(value) {\n    return this._queueNumber('leading', value)\n  },\n\n  // Add animatable viewbox\n  viewbox(x, y, width, height) {\n    return this._queueObject('viewbox', new Box(x, y, width, height))\n  },\n\n  update(o) {\n    if (typeof o !== 'object') {\n      return this.update({\n        offset: arguments[0],\n        color: arguments[1],\n        opacity: arguments[2]\n      })\n    }\n\n    if (o.opacity != null) this.attr('stop-opacity', o.opacity)\n    if (o.color != null) this.attr('stop-color', o.color)\n    if (o.offset != null) this.attr('offset', o.offset)\n\n    return this\n  }\n})\n\nextend(Runner, { rx, ry, from, to })\nregister(Runner, 'Runner')\n","import {\n  adopt,\n  nodeOrNew,\n  register,\n  wrapWithAttrCheck\n} from '../utils/adopter.js'\nimport { svg, xlink, xmlns } from '../modules/core/namespaces.js'\nimport { registerMethods } from '../utils/methods.js'\nimport Container from './Container.js'\nimport Defs from './Defs.js'\nimport { globals } from '../utils/window.js'\n\nexport default class Svg extends Container {\n  constructor(node, attrs = node) {\n    super(nodeOrNew('svg', node), attrs)\n    this.namespace()\n  }\n\n  // Creates and returns defs element\n  defs() {\n    if (!this.isRoot()) return this.root().defs()\n\n    return adopt(this.node.querySelector('defs')) || this.put(new Defs())\n  }\n\n  isRoot() {\n    return (\n      !this.node.parentNode ||\n      (!(this.node.parentNode instanceof globals.window.SVGElement) &&\n        this.node.parentNode.nodeName !== '#document-fragment')\n    )\n  }\n\n  // Add namespaces\n  namespace() {\n    if (!this.isRoot()) return this.root().namespace()\n    return this.attr({ xmlns: svg, version: '1.1' }).attr(\n      'xmlns:xlink',\n      xlink,\n      xmlns\n    )\n  }\n\n  removeNamespace() {\n    return this.attr({ xmlns: null, version: null })\n      .attr('xmlns:xlink', null, xmlns)\n      .attr('xmlns:svgjs', null, xmlns)\n  }\n\n  // Check if this is a root svg\n  // If not, call root() from this element\n  root() {\n    if (this.isRoot()) return this\n    return super.root()\n  }\n}\n\nregisterMethods({\n  Container: {\n    // Create nested svg document\n    nested: wrapWithAttrCheck(function () {\n      return this.put(new Svg())\n    })\n  }\n})\n\nregister(Svg, 'Svg', true)\n","import { nodeOrNew, register, wrapWithAttrCheck } from '../utils/adopter.js'\nimport { registerMethods } from '../utils/methods.js'\nimport Container from './Container.js'\n\nexport default class Symbol extends Container {\n  // Initialize node\n  constructor(node, attrs = node) {\n    super(nodeOrNew('symbol', node), attrs)\n  }\n}\n\nregisterMethods({\n  Container: {\n    symbol: wrapWithAttrCheck(function () {\n      return this.put(new Symbol())\n    })\n  }\n})\n\nregister(Symbol, 'Symbol')\n","import { globals } from '../../utils/window.js'\n\n// Create plain text node\nexport function plain(text) {\n  // clear if build mode is disabled\n  if (this._build === false) {\n    this.clear()\n  }\n\n  // create text node\n  this.node.appendChild(globals.document.createTextNode(text))\n\n  return this\n}\n\n// Get length of text element\nexport function length() {\n  return this.node.getComputedTextLength()\n}\n\n// Move over x-axis\n// Text is moved by its bounding box\n// text-anchor does NOT matter\nexport function x(x, box = this.bbox()) {\n  if (x == null) {\n    return box.x\n  }\n\n  return this.attr('x', this.attr('x') + x - box.x)\n}\n\n// Move over y-axis\nexport function y(y, box = this.bbox()) {\n  if (y == null) {\n    return box.y\n  }\n\n  return this.attr('y', this.attr('y') + y - box.y)\n}\n\nexport function move(x, y, box = this.bbox()) {\n  return this.x(x, box).y(y, box)\n}\n\n// Move center over x-axis\nexport function cx(x, box = this.bbox()) {\n  if (x == null) {\n    return box.cx\n  }\n\n  return this.attr('x', this.attr('x') + x - box.cx)\n}\n\n// Move center over y-axis\nexport function cy(y, box = this.bbox()) {\n  if (y == null) {\n    return box.cy\n  }\n\n  return this.attr('y', this.attr('y') + y - box.cy)\n}\n\nexport function center(x, y, box = this.bbox()) {\n  return this.cx(x, box).cy(y, box)\n}\n\nexport function ax(x) {\n  return this.attr('x', x)\n}\n\nexport function ay(y) {\n  return this.attr('y', y)\n}\n\nexport function amove(x, y) {\n  return this.ax(x).ay(y)\n}\n\n// Enable / disable build mode\nexport function build(build) {\n  this._build = !!build\n  return this\n}\n","import {\n  adopt,\n  extend,\n  nodeOrNew,\n  register,\n  wrapWithAttrCheck\n} from '../utils/adopter.js'\nimport { registerMethods } from '../utils/methods.js'\nimport SVGNumber from '../types/SVGNumber.js'\nimport Shape from './Shape.js'\nimport { globals } from '../utils/window.js'\nimport * as textable from '../modules/core/textable.js'\nimport { isDescriptive, writeDataToDom } from '../utils/utils.js'\n\nexport default class Text extends Shape {\n  // Initialize node\n  constructor(node, attrs = node) {\n    super(nodeOrNew('text', node), attrs)\n\n    this.dom.leading = this.dom.leading ?? new SVGNumber(1.3) // store leading value for rebuilding\n    this._rebuild = true // enable automatic updating of dy values\n    this._build = false // disable build mode for adding multiple lines\n  }\n\n  // Set / get leading\n  leading(value) {\n    // act as getter\n    if (value == null) {\n      return this.dom.leading\n    }\n\n    // act as setter\n    this.dom.leading = new SVGNumber(value)\n\n    return this.rebuild()\n  }\n\n  // Rebuild appearance type\n  rebuild(rebuild) {\n    // store new rebuild flag if given\n    if (typeof rebuild === 'boolean') {\n      this._rebuild = rebuild\n    }\n\n    // define position of all lines\n    if (this._rebuild) {\n      const self = this\n      let blankLineOffset = 0\n      const leading = this.dom.leading\n\n      this.each(function (i) {\n        if (isDescriptive(this.node)) return\n\n        const fontSize = globals.window\n          .getComputedStyle(this.node)\n          .getPropertyValue('font-size')\n\n        const dy = leading * new SVGNumber(fontSize)\n\n        if (this.dom.newLined) {\n          this.attr('x', self.attr('x'))\n\n          if (this.text() === '\\n') {\n            blankLineOffset += dy\n          } else {\n            this.attr('dy', i ? dy + blankLineOffset : 0)\n            blankLineOffset = 0\n          }\n        }\n      })\n\n      this.fire('rebuild')\n    }\n\n    return this\n  }\n\n  // overwrite method from parent to set data properly\n  setData(o) {\n    this.dom = o\n    this.dom.leading = new SVGNumber(o.leading || 1.3)\n    return this\n  }\n\n  writeDataToDom() {\n    writeDataToDom(this, this.dom, { leading: 1.3 })\n    return this\n  }\n\n  // Set the text content\n  text(text) {\n    // act as getter\n    if (text === undefined) {\n      const children = this.node.childNodes\n      let firstLine = 0\n      text = ''\n\n      for (let i = 0, len = children.length; i < len; ++i) {\n        // skip textPaths - they are no lines\n        if (children[i].nodeName === 'textPath' || isDescriptive(children[i])) {\n          if (i === 0) firstLine = i + 1\n          continue\n        }\n\n        // add newline if its not the first child and newLined is set to true\n        if (\n          i !== firstLine &&\n          children[i].nodeType !== 3 &&\n          adopt(children[i]).dom.newLined === true\n        ) {\n          text += '\\n'\n        }\n\n        // add content of this node\n        text += children[i].textContent\n      }\n\n      return text\n    }\n\n    // remove existing content\n    this.clear().build(true)\n\n    if (typeof text === 'function') {\n      // call block\n      text.call(this, this)\n    } else {\n      // store text and make sure text is not blank\n      text = (text + '').split('\\n')\n\n      // build new lines\n      for (let j = 0, jl = text.length; j < jl; j++) {\n        this.newLine(text[j])\n      }\n    }\n\n    // disable build mode and rebuild lines\n    return this.build(false).rebuild()\n  }\n}\n\nextend(Text, textable)\n\nregisterMethods({\n  Container: {\n    // Create text element\n    text: wrapWithAttrCheck(function (text = '') {\n      return this.put(new Text()).text(text)\n    }),\n\n    // Create plain text element\n    plain: wrapWithAttrCheck(function (text = '') {\n      return this.put(new Text()).plain(text)\n    })\n  }\n})\n\nregister(Text, 'Text')\n","import {\n  extend,\n  nodeOrNew,\n  register,\n  wrapWithAttrCheck\n} from '../utils/adopter.js'\nimport { globals } from '../utils/window.js'\nimport { registerMethods } from '../utils/methods.js'\nimport SVGNumber from '../types/SVGNumber.js'\nimport Shape from './Shape.js'\nimport Text from './Text.js'\nimport * as textable from '../modules/core/textable.js'\n\nexport default class Tspan extends Shape {\n  // Initialize node\n  constructor(node, attrs = node) {\n    super(nodeOrNew('tspan', node), attrs)\n    this._build = false // disable build mode for adding multiple lines\n  }\n\n  // Shortcut dx\n  dx(dx) {\n    return this.attr('dx', dx)\n  }\n\n  // Shortcut dy\n  dy(dy) {\n    return this.attr('dy', dy)\n  }\n\n  // Create new line\n  newLine() {\n    // mark new line\n    this.dom.newLined = true\n\n    // fetch parent\n    const text = this.parent()\n\n    // early return in case we are not in a text element\n    if (!(text instanceof Text)) {\n      return this\n    }\n\n    const i = text.index(this)\n\n    const fontSize = globals.window\n      .getComputedStyle(this.node)\n      .getPropertyValue('font-size')\n    const dy = text.dom.leading * new SVGNumber(fontSize)\n\n    // apply new position\n    return this.dy(i ? dy : 0).attr('x', text.x())\n  }\n\n  // Set text content\n  text(text) {\n    if (text == null)\n      return this.node.textContent + (this.dom.newLined ? '\\n' : '')\n\n    if (typeof text === 'function') {\n      this.clear().build(true)\n      text.call(this, this)\n      this.build(false)\n    } else {\n      this.plain(text)\n    }\n\n    return this\n  }\n}\n\nextend(Tspan, textable)\n\nregisterMethods({\n  Tspan: {\n    tspan: wrapWithAttrCheck(function (text = '') {\n      const tspan = new Tspan()\n\n      // clear if build mode is disabled\n      if (!this._build) {\n        this.clear()\n      }\n\n      // add new tspan\n      return this.put(tspan).text(text)\n    })\n  },\n  Text: {\n    newLine: function (text = '') {\n      return this.tspan(text).newLine()\n    }\n  }\n})\n\nregister(Tspan, 'Tspan')\n","import { cx, cy, height, width, x, y } from '../modules/core/circled.js'\nimport {\n  extend,\n  nodeOrNew,\n  register,\n  wrapWithAttrCheck\n} from '../utils/adopter.js'\nimport { registerMethods } from '../utils/methods.js'\nimport SVGNumber from '../types/SVGNumber.js'\nimport Shape from './Shape.js'\n\nexport default class Circle extends Shape {\n  constructor(node, attrs = node) {\n    super(nodeOrNew('circle', node), attrs)\n  }\n\n  radius(r) {\n    return this.attr('r', r)\n  }\n\n  // Radius x value\n  rx(rx) {\n    return this.attr('r', rx)\n  }\n\n  // Alias radius x value\n  ry(ry) {\n    return this.rx(ry)\n  }\n\n  size(size) {\n    return this.radius(new SVGNumber(size).divide(2))\n  }\n}\n\nextend(Circle, { x, y, cx, cy, width, height })\n\nregisterMethods({\n  Container: {\n    // Create circle element\n    circle: wrapWithAttrCheck(function (size = 0) {\n      return this.put(new Circle()).size(size).move(0, 0)\n    })\n  }\n})\n\nregister(Circle, 'Circle')\n","import { nodeOrNew, register, wrapWithAttrCheck } from '../utils/adopter.js'\nimport { registerMethods } from '../utils/methods.js'\nimport Container from './Container.js'\nimport baseFind from '../modules/core/selector.js'\n\nexport default class ClipPath extends Container {\n  constructor(node, attrs = node) {\n    super(nodeOrNew('clipPath', node), attrs)\n  }\n\n  // Unclip all clipped elements and remove itself\n  remove() {\n    // unclip all targets\n    this.targets().forEach(function (el) {\n      el.unclip()\n    })\n\n    // remove clipPath from parent\n    return super.remove()\n  }\n\n  targets() {\n    return baseFind('svg [clip-path*=' + this.id() + ']')\n  }\n}\n\nregisterMethods({\n  Container: {\n    // Create clipping element\n    clip: wrapWithAttrCheck(function () {\n      return this.defs().put(new ClipPath())\n    })\n  },\n  Element: {\n    // Distribute clipPath to svg element\n    clipper() {\n      return this.reference('clip-path')\n    },\n\n    clipWith(element) {\n      // use given clip or create a new one\n      const clipper =\n        element instanceof ClipPath\n          ? element\n          : this.parent().clip().add(element)\n\n      // apply mask\n      return this.attr('clip-path', 'url(#' + clipper.id() + ')')\n    },\n\n    // Unclip element\n    unclip() {\n      return this.attr('clip-path', null)\n    }\n  }\n})\n\nregister(ClipPath, 'ClipPath')\n","import { nodeOrNew, register, wrapWithAttrCheck } from '../utils/adopter.js'\nimport { registerMethods } from '../utils/methods.js'\nimport Element from './Element.js'\n\nexport default class ForeignObject extends Element {\n  constructor(node, attrs = node) {\n    super(nodeOrNew('foreignObject', node), attrs)\n  }\n}\n\nregisterMethods({\n  Container: {\n    foreignObject: wrapWithAttrCheck(function (width, height) {\n      return this.put(new ForeignObject()).size(width, height)\n    })\n  }\n})\n\nregister(ForeignObject, 'ForeignObject')\n","import Matrix from '../../types/Matrix.js'\nimport Point from '../../types/Point.js'\nimport Box from '../../types/Box.js'\nimport { proportionalSize } from '../../utils/utils.js'\nimport { getWindow } from '../../utils/window.js'\n\nexport function dmove(dx, dy) {\n  this.children().forEach((child) => {\n    let bbox\n\n    // We have to wrap this for elements that dont have a bbox\n    // e.g. title and other descriptive elements\n    try {\n      // Get the childs bbox\n      // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1905039\n      // Because bbox for nested svgs returns the contents bbox in the coordinate space of the svg itself (weird!), we cant use bbox for svgs\n      // Therefore we have to use getBoundingClientRect. But THAT is broken (as explained in the bug).\n      // Funnily enough the broken behavior would work for us but that breaks it in chrome\n      // So we have to replicate the broken behavior of FF by just reading the attributes of the svg itself\n      bbox =\n        child.node instanceof getWindow().SVGSVGElement\n          ? new Box(child.attr(['x', 'y', 'width', 'height']))\n          : child.bbox()\n    } catch (e) {\n      return\n    }\n\n    // Get childs matrix\n    const m = new Matrix(child)\n    // Translate childs matrix by amount and\n    // transform it back into parents space\n    const matrix = m.translate(dx, dy).transform(m.inverse())\n    // Calculate new x and y from old box\n    const p = new Point(bbox.x, bbox.y).transform(matrix)\n    // Move element\n    child.move(p.x, p.y)\n  })\n\n  return this\n}\n\nexport function dx(dx) {\n  return this.dmove(dx, 0)\n}\n\nexport function dy(dy) {\n  return this.dmove(0, dy)\n}\n\nexport function height(height, box = this.bbox()) {\n  if (height == null) return box.height\n  return this.size(box.width, height, box)\n}\n\nexport function move(x = 0, y = 0, box = this.bbox()) {\n  const dx = x - box.x\n  const dy = y - box.y\n\n  return this.dmove(dx, dy)\n}\n\nexport function size(width, height, box = this.bbox()) {\n  const p = proportionalSize(this, width, height, box)\n  const scaleX = p.width / box.width\n  const scaleY = p.height / box.height\n\n  this.children().forEach((child) => {\n    const o = new Point(box).transform(new Matrix(child).inverse())\n    child.scale(scaleX, scaleY, o.x, o.y)\n  })\n\n  return this\n}\n\nexport function width(width, box = this.bbox()) {\n  if (width == null) return box.width\n  return this.size(width, box.height, box)\n}\n\nexport function x(x, box = this.bbox()) {\n  if (x == null) return box.x\n  return this.move(x, box.y, box)\n}\n\nexport function y(y, box = this.bbox()) {\n  if (y == null) return box.y\n  return this.move(box.x, y, box)\n}\n","import {\n  nodeOrNew,\n  register,\n  wrapWithAttrCheck,\n  extend\n} from '../utils/adopter.js'\nimport { registerMethods } from '../utils/methods.js'\nimport Container from './Container.js'\nimport * as containerGeometry from '../modules/core/containerGeometry.js'\n\nexport default class G extends Container {\n  constructor(node, attrs = node) {\n    super(nodeOrNew('g', node), attrs)\n  }\n}\n\nextend(G, containerGeometry)\n\nregisterMethods({\n  Container: {\n    // Create a group element\n    group: wrapWithAttrCheck(function () {\n      return this.put(new G())\n    })\n  }\n})\n\nregister(G, 'G')\n","import {\n  nodeOrNew,\n  register,\n  wrapWithAttrCheck,\n  extend\n} from '../utils/adopter.js'\nimport { registerMethods } from '../utils/methods.js'\nimport { xlink } from '../modules/core/namespaces.js'\nimport Container from './Container.js'\nimport * as containerGeometry from '../modules/core/containerGeometry.js'\n\nexport default class A extends Container {\n  constructor(node, attrs = node) {\n    super(nodeOrNew('a', node), attrs)\n  }\n\n  // Link target attribute\n  target(target) {\n    return this.attr('target', target)\n  }\n\n  // Link url\n  to(url) {\n    return this.attr('href', url, xlink)\n  }\n}\n\nextend(A, containerGeometry)\n\nregisterMethods({\n  Container: {\n    // Create a hyperlink element\n    link: wrapWithAttrCheck(function (url) {\n      return this.put(new A()).to(url)\n    })\n  },\n  Element: {\n    unlink() {\n      const link = this.linker()\n\n      if (!link) return this\n\n      const parent = link.parent()\n\n      if (!parent) {\n        return this.remove()\n      }\n\n      const index = parent.index(link)\n      parent.add(this, index)\n\n      link.remove()\n      return this\n    },\n    linkTo(url) {\n      // reuse old link if possible\n      let link = this.linker()\n\n      if (!link) {\n        link = new A()\n        this.wrap(link)\n      }\n\n      if (typeof url === 'function') {\n        url.call(link, link)\n      } else {\n        link.to(url)\n      }\n\n      return this\n    },\n    linker() {\n      const link = this.parent()\n      if (link && link.node.nodeName.toLowerCase() === 'a') {\n        return link\n      }\n\n      return null\n    }\n  }\n})\n\nregister(A, 'A')\n","import { nodeOrNew, register, wrapWithAttrCheck } from '../utils/adopter.js'\nimport { registerMethods } from '../utils/methods.js'\nimport Container from './Container.js'\nimport baseFind from '../modules/core/selector.js'\n\nexport default class Mask extends Container {\n  // Initialize node\n  constructor(node, attrs = node) {\n    super(nodeOrNew('mask', node), attrs)\n  }\n\n  // Unmask all masked elements and remove itself\n  remove() {\n    // unmask all targets\n    this.targets().forEach(function (el) {\n      el.unmask()\n    })\n\n    // remove mask from parent\n    return super.remove()\n  }\n\n  targets() {\n    return baseFind('svg [mask*=' + this.id() + ']')\n  }\n}\n\nregisterMethods({\n  Container: {\n    mask: wrapWithAttrCheck(function () {\n      return this.defs().put(new Mask())\n    })\n  },\n  Element: {\n    // Distribute mask to svg element\n    masker() {\n      return this.reference('mask')\n    },\n\n    maskWith(element) {\n      // use given mask or create a new one\n      const masker =\n        element instanceof Mask ? element : this.parent().mask().add(element)\n\n      // apply mask\n      return this.attr('mask', 'url(#' + masker.id() + ')')\n    },\n\n    // Unmask element\n    unmask() {\n      return this.attr('mask', null)\n    }\n  }\n})\n\nregister(Mask, 'Mask')\n","import { nodeOrNew, register } from '../utils/adopter.js'\nimport Element from './Element.js'\nimport SVGNumber from '../types/SVGNumber.js'\nimport { registerMethods } from '../utils/methods.js'\n\nexport default class Stop extends Element {\n  constructor(node, attrs = node) {\n    super(nodeOrNew('stop', node), attrs)\n  }\n\n  // add color stops\n  update(o) {\n    if (typeof o === 'number' || o instanceof SVGNumber) {\n      o = {\n        offset: arguments[0],\n        color: arguments[1],\n        opacity: arguments[2]\n      }\n    }\n\n    // set attributes\n    if (o.opacity != null) this.attr('stop-opacity', o.opacity)\n    if (o.color != null) this.attr('stop-color', o.color)\n    if (o.offset != null) this.attr('offset', new SVGNumber(o.offset))\n\n    return this\n  }\n}\n\nregisterMethods({\n  Gradient: {\n    // Add a color stop\n    stop: function (offset, color, opacity) {\n      return this.put(new Stop()).update(offset, color, opacity)\n    }\n  }\n})\n\nregister(Stop, 'Stop')\n","import { nodeOrNew, register } from '../utils/adopter.js'\nimport { registerMethods } from '../utils/methods.js'\nimport { unCamelCase } from '../utils/utils.js'\nimport Element from './Element.js'\n\nfunction cssRule(selector, rule) {\n  if (!selector) return ''\n  if (!rule) return selector\n\n  let ret = selector + '{'\n\n  for (const i in rule) {\n    ret += unCamelCase(i) + ':' + rule[i] + ';'\n  }\n\n  ret += '}'\n\n  return ret\n}\n\nexport default class Style extends Element {\n  constructor(node, attrs = node) {\n    super(nodeOrNew('style', node), attrs)\n  }\n\n  addText(w = '') {\n    this.node.textContent += w\n    return this\n  }\n\n  font(name, src, params = {}) {\n    return this.rule('@font-face', {\n      fontFamily: name,\n      src: src,\n      ...params\n    })\n  }\n\n  rule(selector, obj) {\n    return this.addText(cssRule(selector, obj))\n  }\n}\n\nregisterMethods('Dom', {\n  style(selector, obj) {\n    return this.put(new Style()).rule(selector, obj)\n  },\n  fontface(name, src, params) {\n    return this.put(new Style()).font(name, src, params)\n  }\n})\n\nregister(Style, 'Style')\n","import { nodeOrNew, register, wrapWithAttrCheck } from '../utils/adopter.js'\nimport { registerMethods } from '../utils/methods.js'\nimport { xlink } from '../modules/core/namespaces.js'\nimport Path from './Path.js'\nimport PathArray from '../types/PathArray.js'\nimport Text from './Text.js'\nimport baseFind from '../modules/core/selector.js'\n\nexport default class TextPath extends Text {\n  // Initialize node\n  constructor(node, attrs = node) {\n    super(nodeOrNew('textPath', node), attrs)\n  }\n\n  // return the array of the path track element\n  array() {\n    const track = this.track()\n\n    return track ? track.array() : null\n  }\n\n  // Plot path if any\n  plot(d) {\n    const track = this.track()\n    let pathArray = null\n\n    if (track) {\n      pathArray = track.plot(d)\n    }\n\n    return d == null ? pathArray : this\n  }\n\n  // Get the path element\n  track() {\n    return this.reference('href')\n  }\n}\n\nregisterMethods({\n  Container: {\n    textPath: wrapWithAttrCheck(function (text, path) {\n      // Convert text to instance if needed\n      if (!(text instanceof Text)) {\n        text = this.text(text)\n      }\n\n      return text.path(path)\n    })\n  },\n  Text: {\n    // Create path for text to run on\n    path: wrapWithAttrCheck(function (track, importNodes = true) {\n      const textPath = new TextPath()\n\n      // if track is a path, reuse it\n      if (!(track instanceof Path)) {\n        // create path element\n        track = this.defs().path(track)\n      }\n\n      // link textPath to path and add content\n      textPath.attr('href', '#' + track, xlink)\n\n      // Transplant all nodes from text to textPath\n      let node\n      if (importNodes) {\n        while ((node = this.node.firstChild)) {\n          textPath.node.appendChild(node)\n        }\n      }\n\n      // add textPath element as child node and return textPath\n      return this.put(textPath)\n    }),\n\n    // Get the textPath children\n    textPath() {\n      return this.findOne('textPath')\n    }\n  },\n  Path: {\n    // creates a textPath from this path\n    text: wrapWithAttrCheck(function (text) {\n      // Convert text to instance if needed\n      if (!(text instanceof Text)) {\n        text = new Text().addTo(this.parent()).text(text)\n      }\n\n      // Create textPath from text and path and return\n      return text.path(this)\n    }),\n\n    targets() {\n      return baseFind('svg textPath').filter((node) => {\n        return (node.attr('href') || '').includes(this.id())\n      })\n\n      // Does not work in IE11. Use when IE support is dropped\n      // return baseFind('svg textPath[*|href*=' + this.id() + ']')\n    }\n  }\n})\n\nTextPath.prototype.MorphArray = PathArray\nregister(TextPath, 'TextPath')\n","import { nodeOrNew, register, wrapWithAttrCheck } from '../utils/adopter.js'\nimport { registerMethods } from '../utils/methods.js'\nimport { xlink } from '../modules/core/namespaces.js'\nimport Shape from './Shape.js'\n\nexport default class Use extends Shape {\n  constructor(node, attrs = node) {\n    super(nodeOrNew('use', node), attrs)\n  }\n\n  // Use element as a reference\n  use(element, file) {\n    // Set lined element\n    return this.attr('href', (file || '') + '#' + element, xlink)\n  }\n}\n\nregisterMethods({\n  Container: {\n    // Create a use element\n    use: wrapWithAttrCheck(function (element, file) {\n      return this.put(new Use()).use(element, file)\n    })\n  }\n})\n\nregister(Use, 'Use')\n","/* Optional Modules */\nimport './modules/optional/arrange.js'\nimport './modules/optional/class.js'\nimport './modules/optional/css.js'\nimport './modules/optional/data.js'\nimport './modules/optional/memory.js'\nimport './modules/optional/sugar.js'\nimport './modules/optional/transform.js'\n\nimport { extend, makeInstance } from './utils/adopter.js'\nimport { getMethodNames, getMethodsFor } from './utils/methods.js'\nimport Box from './types/Box.js'\nimport Color from './types/Color.js'\nimport Container from './elements/Container.js'\nimport Defs from './elements/Defs.js'\nimport Dom from './elements/Dom.js'\nimport Element from './elements/Element.js'\nimport Ellipse from './elements/Ellipse.js'\nimport EventTarget from './types/EventTarget.js'\nimport Fragment from './elements/Fragment.js'\nimport Gradient from './elements/Gradient.js'\nimport Image from './elements/Image.js'\nimport Line from './elements/Line.js'\nimport List from './types/List.js'\nimport Marker from './elements/Marker.js'\nimport Matrix from './types/Matrix.js'\nimport Morphable, {\n  NonMorphable,\n  ObjectBag,\n  TransformBag,\n  makeMorphable,\n  registerMorphableType\n} from './animation/Morphable.js'\nimport Path from './elements/Path.js'\nimport PathArray from './types/PathArray.js'\nimport Pattern from './elements/Pattern.js'\nimport PointArray from './types/PointArray.js'\nimport Point from './types/Point.js'\nimport Polygon from './elements/Polygon.js'\nimport Polyline from './elements/Polyline.js'\nimport Rect from './elements/Rect.js'\nimport Runner from './animation/Runner.js'\nimport SVGArray from './types/SVGArray.js'\nimport SVGNumber from './types/SVGNumber.js'\nimport Shape from './elements/Shape.js'\nimport Svg from './elements/Svg.js'\nimport Symbol from './elements/Symbol.js'\nimport Text from './elements/Text.js'\nimport Tspan from './elements/Tspan.js'\nimport * as defaults from './modules/core/defaults.js'\nimport * as utils from './utils/utils.js'\nimport * as namespaces from './modules/core/namespaces.js'\nimport * as regex from './modules/core/regex.js'\n\nexport {\n  Morphable,\n  registerMorphableType,\n  makeMorphable,\n  TransformBag,\n  ObjectBag,\n  NonMorphable\n}\n\nexport { defaults, utils, namespaces, regex }\nexport const SVG = makeInstance\nexport { default as parser } from './modules/core/parser.js'\nexport { default as find } from './modules/core/selector.js'\nexport * from './modules/core/event.js'\nexport * from './utils/adopter.js'\nexport {\n  getWindow,\n  registerWindow,\n  restoreWindow,\n  saveWindow,\n  withWindow\n} from './utils/window.js'\n\n/* Animation Modules */\nexport { default as Animator } from './animation/Animator.js'\nexport {\n  Controller,\n  Ease,\n  PID,\n  Spring,\n  easing\n} from './animation/Controller.js'\nexport { default as Queue } from './animation/Queue.js'\nexport { default as Runner } from './animation/Runner.js'\nexport { default as Timeline } from './animation/Timeline.js'\n\n/* Types */\nexport { default as Array } from './types/SVGArray.js'\nexport { default as Box } from './types/Box.js'\nexport { default as Color } from './types/Color.js'\nexport { default as EventTarget } from './types/EventTarget.js'\nexport { default as Matrix } from './types/Matrix.js'\nexport { default as Number } from './types/SVGNumber.js'\nexport { default as PathArray } from './types/PathArray.js'\nexport { default as Point } from './types/Point.js'\nexport { default as PointArray } from './types/PointArray.js'\nexport { default as List } from './types/List.js'\n\n/* Elements */\nexport { default as Circle } from './elements/Circle.js'\nexport { default as ClipPath } from './elements/ClipPath.js'\nexport { default as Container } from './elements/Container.js'\nexport { default as Defs } from './elements/Defs.js'\nexport { default as Dom } from './elements/Dom.js'\nexport { default as Element } from './elements/Element.js'\nexport { default as Ellipse } from './elements/Ellipse.js'\nexport { default as ForeignObject } from './elements/ForeignObject.js'\nexport { default as Fragment } from './elements/Fragment.js'\nexport { default as Gradient } from './elements/Gradient.js'\nexport { default as G } from './elements/G.js'\nexport { default as A } from './elements/A.js'\nexport { default as Image } from './elements/Image.js'\nexport { default as Line } from './elements/Line.js'\nexport { default as Marker } from './elements/Marker.js'\nexport { default as Mask } from './elements/Mask.js'\nexport { default as Path } from './elements/Path.js'\nexport { default as Pattern } from './elements/Pattern.js'\nexport { default as Polygon } from './elements/Polygon.js'\nexport { default as Polyline } from './elements/Polyline.js'\nexport { default as Rect } from './elements/Rect.js'\nexport { default as Shape } from './elements/Shape.js'\nexport { default as Stop } from './elements/Stop.js'\nexport { default as Style } from './elements/Style.js'\nexport { default as Svg } from './elements/Svg.js'\nexport { default as Symbol } from './elements/Symbol.js'\nexport { default as Text } from './elements/Text.js'\nexport { default as TextPath } from './elements/TextPath.js'\nexport { default as Tspan } from './elements/Tspan.js'\nexport { default as Use } from './elements/Use.js'\n\nextend([Svg, Symbol, Image, Pattern, Marker], getMethodsFor('viewbox'))\n\nextend([Line, Polyline, Polygon, Path], getMethodsFor('marker'))\n\nextend(Text, getMethodsFor('Text'))\nextend(Path, getMethodsFor('Path'))\n\nextend(Defs, getMethodsFor('Defs'))\n\nextend([Text, Tspan], getMethodsFor('Tspan'))\n\nextend([Rect, Ellipse, Gradient, Runner], getMethodsFor('radius'))\n\nextend(EventTarget, getMethodsFor('EventTarget'))\nextend(Dom, getMethodsFor('Dom'))\nextend(Element, getMethodsFor('Element'))\nextend(Shape, getMethodsFor('Shape'))\nextend([Container, Fragment], getMethodsFor('Container'))\nextend(Gradient, getMethodsFor('Gradient'))\n\nextend(Runner, getMethodsFor('Runner'))\n\nList.extend(getMethodNames())\n\nregisterMorphableType([\n  SVGNumber,\n  Color,\n  Box,\n  Matrix,\n  SVGArray,\n  PointArray,\n  PathArray,\n  Point\n])\n\nmakeMorphable()\n","import { Box, Element, G, extend, off, on } from '@svgdotjs/svg.js'\n\nconst getCoordsFromEvent = (ev) => {\n  if (ev.changedTouches) {\n    ev = ev.changedTouches[0]\n  }\n  return { x: ev.clientX, y: ev.clientY }\n}\n\n// Creates handler, saves it\nclass DragHandler {\n  constructor(el) {\n    el.remember('_draggable', this)\n    this.el = el\n\n    this.drag = this.drag.bind(this)\n    this.startDrag = this.startDrag.bind(this)\n    this.endDrag = this.endDrag.bind(this)\n  }\n\n  // Enables or disabled drag based on input\n  init(enabled) {\n    if (enabled) {\n      this.el.on('mousedown.drag', this.startDrag)\n      this.el.on('touchstart.drag', this.startDrag, { passive: false })\n    } else {\n      this.el.off('mousedown.drag')\n      this.el.off('touchstart.drag')\n    }\n  }\n\n  // Start dragging\n  startDrag(ev) {\n    const isMouse = !ev.type.indexOf('mouse')\n\n    // Check for left button\n    if (isMouse && ev.which !== 1 && ev.buttons !== 0) {\n      return\n    }\n\n    // Fire beforedrag event\n    if (\n      this.el.dispatch('beforedrag', { event: ev, handler: this })\n        .defaultPrevented\n    ) {\n      return\n    }\n\n    // Prevent browser drag behavior as soon as possible\n    ev.preventDefault()\n\n    // Prevent propagation to a parent that might also have dragging enabled\n    ev.stopPropagation()\n\n    // Make sure that start events are unbound so that one element\n    // is only dragged by one input only\n    this.init(false)\n\n    this.box = this.el.bbox()\n    this.lastClick = this.el.point(getCoordsFromEvent(ev))\n\n    const eventMove = (isMouse ? 'mousemove' : 'touchmove') + '.drag'\n    const eventEnd = (isMouse ? 'mouseup' : 'touchend') + '.drag'\n\n    // Bind drag and end events to window\n    on(window, eventMove, this.drag, this, { passive: false })\n    on(window, eventEnd, this.endDrag, this, { passive: false })\n\n    // Fire dragstart event\n    this.el.fire('dragstart', { event: ev, handler: this, box: this.box })\n  }\n\n  // While dragging\n  drag(ev) {\n    const { box, lastClick } = this\n\n    const currentClick = this.el.point(getCoordsFromEvent(ev))\n    const dx = currentClick.x - lastClick.x\n    const dy = currentClick.y - lastClick.y\n\n    if (!dx && !dy) return box\n\n    const x = box.x + dx\n    const y = box.y + dy\n    this.box = new Box(x, y, box.w, box.h)\n    this.lastClick = currentClick\n\n    if (\n      this.el.dispatch('dragmove', {\n        event: ev,\n        handler: this,\n        box: this.box,\n        dx,\n        dy,\n      }).defaultPrevented\n    ) {\n      return\n    }\n\n    this.move(x, y)\n  }\n\n  move(x, y) {\n    // Svg elements bbox depends on their content even though they have\n    // x, y, width and height - strange!\n    // Thats why we handle them the same as groups\n    if (this.el.type === 'svg') {\n      G.prototype.move.call(this.el, x, y)\n    } else {\n      this.el.move(x, y)\n    }\n  }\n\n  endDrag(ev) {\n    // final drag\n    this.drag(ev)\n\n    // fire dragend event\n    this.el.fire('dragend', { event: ev, handler: this, box: this.box })\n\n    // unbind events\n    off(window, 'mousemove.drag')\n    off(window, 'touchmove.drag')\n    off(window, 'mouseup.drag')\n    off(window, 'touchend.drag')\n\n    // Rebind initial Events\n    this.init(true)\n  }\n}\n\nextend(Element, {\n  draggable(enable = true) {\n    const dragHandler = this.remember('_draggable') || new DragHandler(this)\n    dragHandler.init(enable)\n    return this\n  },\n})\n","/*!\n* @svgdotjs/svg.panzoom.js - A plugin for svg.js that enables panzoom for viewport elements\n* @version 2.1.2\n* https://github.com/svgdotjs/svg.panzoom.js#readme\n*\n* @copyright undefined\n* @license MIT\n*\n* BUILT: Thu Jul 22 2021 14:51:35 GMT+0200 (Mitteleuropäische Sommerzeit)\n*/;\nimport { extend, Svg, on, off, Box, Matrix } from '@svgdotjs/svg.js';\n\nvar normalizeEvent = function normalizeEvent(ev) {\n  return ev.touches || [{\n    clientX: ev.clientX,\n    clientY: ev.clientY\n  }];\n};\n\nextend(Svg, {\n  panZoom: function panZoom(options) {\n    var _options,\n        _options$zoomFactor,\n        _options$zoomMin,\n        _options$zoomMax,\n        _options$wheelZoom,\n        _options$pinchZoom,\n        _options$panning,\n        _options$panButton,\n        _options$oneFingerPan,\n        _options$margins,\n        _options$wheelZoomDel,\n        _options$wheelZoomDel2,\n        _this = this;\n\n    this.off('.panZoom'); // when called with false, disable panZoom\n\n    if (options === false) return this;\n    options = (_options = options) != null ? _options : {};\n    var zoomFactor = (_options$zoomFactor = options.zoomFactor) != null ? _options$zoomFactor : 2;\n    var zoomMin = (_options$zoomMin = options.zoomMin) != null ? _options$zoomMin : Number.MIN_VALUE;\n    var zoomMax = (_options$zoomMax = options.zoomMax) != null ? _options$zoomMax : Number.MAX_VALUE;\n    var doWheelZoom = (_options$wheelZoom = options.wheelZoom) != null ? _options$wheelZoom : true;\n    var doPinchZoom = (_options$pinchZoom = options.pinchZoom) != null ? _options$pinchZoom : true;\n    var doPanning = (_options$panning = options.panning) != null ? _options$panning : true;\n    var panButton = (_options$panButton = options.panButton) != null ? _options$panButton : 0;\n    var oneFingerPan = (_options$oneFingerPan = options.oneFingerPan) != null ? _options$oneFingerPan : false;\n    var margins = (_options$margins = options.margins) != null ? _options$margins : false;\n    var wheelZoomDeltaModeLinePixels = (_options$wheelZoomDel = options.wheelZoomDeltaModeLinePixels) != null ? _options$wheelZoomDel : 17;\n    var wheelZoomDeltaModeScreenPixels = (_options$wheelZoomDel2 = options.wheelZoomDeltaModeScreenPixels) != null ? _options$wheelZoomDel2 : 53;\n    var lastP;\n    var lastTouches;\n    var zoomInProgress = false;\n    var viewbox = this.viewbox();\n\n    var restrictToMargins = function restrictToMargins(box) {\n      if (!margins) return box;\n      var top = margins.top,\n          left = margins.left,\n          bottom = margins.bottom,\n          right = margins.right;\n\n      var _this$attr = _this.attr(['width', 'height']),\n          width = _this$attr.width,\n          height = _this$attr.height;\n\n      var preserveAspectRatio = _this.node.preserveAspectRatio.baseVal; // The current viewport (exactly what is shown on the screen, what we ultimately want to restrict)\n      // is not always exactly the same as current viewbox. They are different when the viewbox aspectRatio and the svg aspectRatio\n      // are different and preserveAspectRatio is not \"none\". These offsets represent the difference in user coordinates\n      // between the side of the viewbox and the side of the viewport.\n\n      var viewportLeftOffset = 0;\n      var viewportRightOffset = 0;\n      var viewportTopOffset = 0;\n      var viewportBottomOffset = 0; // preserveAspectRatio none has no offsets\n\n      if (preserveAspectRatio.align !== preserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE) {\n        var svgAspectRatio = width / height;\n        var viewboxAspectRatio = viewbox.width / viewbox.height; // when aspectRatios are the same, there are no offsets\n\n        if (viewboxAspectRatio !== svgAspectRatio) {\n          // aspectRatio unknown is like meet because that's the default\n          var isMeet = preserveAspectRatio.meetOrSlice !== preserveAspectRatio.SVG_MEETORSLICE_SLICE;\n          var changedAxis = svgAspectRatio > viewboxAspectRatio ? 'width' : 'height';\n          var isWidth = changedAxis === 'width';\n          var changeHorizontal = isMeet && isWidth || !isMeet && !isWidth;\n          var ratio = changeHorizontal ? svgAspectRatio / viewboxAspectRatio : viewboxAspectRatio / svgAspectRatio;\n          var offset = box[changedAxis] - box[changedAxis] * ratio;\n\n          if (changeHorizontal) {\n            if (preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMIN || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMID || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMAX) {\n              viewportLeftOffset = offset / 2;\n              viewportRightOffset = -offset / 2;\n            } else if (preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMIN || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMID || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMAX) {\n              viewportRightOffset = -offset;\n            } else if (preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMIN || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMID || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMAX) {\n              viewportLeftOffset = offset;\n            }\n          } else {\n            if (preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMID || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMID || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMID) {\n              viewportTopOffset = offset / 2;\n              viewportBottomOffset = -offset / 2;\n            } else if (preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMIN || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMIN || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMIN) {\n              viewportBottomOffset = -offset;\n            } else if (preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMAX || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMAX || preserveAspectRatio.align === preserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMAX) {\n              viewportTopOffset = offset;\n            }\n          }\n        }\n      } // when box.x == leftLimit, the image is panned to the left,\n      // i.e the current box is to the right of the initial viewbox,\n      // and only the right part of the initial image is visible, i.e.\n      // the right side of the initial viewbox minus left margin (viewbox.x+viewbox.width-left)\n      // is aligned with the left side of the viewport (box.x + viewportLeftOffset):\n      // viewbox.width + viewbox.x - left = box.x + viewportLeftOffset\n      // viewbox.width + viewbox.x - left - viewportLeftOffset = box.x (= leftLimit)\n\n\n      var leftLimit = viewbox.width + viewbox.x - left - viewportLeftOffset; // when box.x == rightLimit, the image is panned to the right,\n      // i.e the current box is to the left of the initial viewbox\n      // and only the left part of the initial image is visible, i.e\n      // the left side of the initial viewbox plus right margin (viewbox.x + right)\n      // is aligned with the right side of the viewport (box.x + box.width + viewportRightOffset)\n      // viewbox.x + right = box.x + box.width + viewportRightOffset\n      // viewbox.x + right - box.width - viewportRightOffset = box.x (= rightLimit)\n\n      var rightLimit = viewbox.x + right - box.width - viewportRightOffset; // same with top and bottom\n\n      var topLimit = viewbox.height + viewbox.y - top - viewportTopOffset;\n      var bottomLimit = viewbox.y + bottom - box.height - viewportBottomOffset;\n      box.x = Math.min(leftLimit, Math.max(rightLimit, box.x)); // enforce rightLimit <= box.x <= leftLimit\n\n      box.y = Math.min(topLimit, Math.max(bottomLimit, box.y)); // enforce bottomLimit <= box.y <= topLimit\n\n      return box;\n    };\n\n    var wheelZoom = function wheelZoom(ev) {\n      ev.preventDefault(); // When wheeling on a mouse,\n      // - chrome by default uses deltaY = 53, deltaMode = 0 (pixel)\n      // - firefox by default uses deltaY = 3, deltaMode = 1 (line)\n      // - chrome and firefox on windows after configuring \"One screen at a time\"\n      //   use deltaY = 1, deltaMode = 2 (screen)\n      //\n      // Note that when when wheeling on a touchpad, deltaY depends on how fast\n      // you swipe, but the deltaMode is still different between the browsers.\n      //\n      // Normalize everything so that zooming speed is approximately the same in all cases\n\n      var normalizedPixelDeltaY;\n\n      switch (ev.deltaMode) {\n        case 1:\n          normalizedPixelDeltaY = ev.deltaY * wheelZoomDeltaModeLinePixels;\n          break;\n\n        case 2:\n          normalizedPixelDeltaY = ev.deltaY * wheelZoomDeltaModeScreenPixels;\n          break;\n\n        default:\n          // 0 (already pixels) or new mode (avoid crashing)\n          normalizedPixelDeltaY = ev.deltaY;\n          break;\n      }\n\n      var lvl = Math.pow(1 + zoomFactor, -1 * normalizedPixelDeltaY / 100) * this.zoom();\n      var p = this.point(ev.clientX, ev.clientY);\n\n      if (lvl > zoomMax) {\n        lvl = zoomMax;\n      }\n\n      if (lvl < zoomMin) {\n        lvl = zoomMin;\n      }\n\n      if (this.dispatch('zoom', {\n        level: lvl,\n        focus: p\n      }).defaultPrevented) {\n        return this;\n      }\n\n      this.zoom(lvl, p);\n\n      if (margins) {\n        var box = restrictToMargins(this.viewbox());\n        this.viewbox(box);\n      }\n    };\n\n    var pinchZoomStart = function pinchZoomStart(ev) {\n      lastTouches = normalizeEvent(ev); // Start panning in case only one touch is found\n\n      if (lastTouches.length < 2) {\n        if (doPanning && oneFingerPan) {\n          panStart.call(this, ev);\n        }\n\n        return;\n      } // Stop panning for more than one touch\n\n\n      if (doPanning && oneFingerPan) {\n        panStop.call(this, ev);\n      } // We call it so late, so the user is still able to scroll / reload the page via gesture\n      // In case oneFingerPan is not active\n\n\n      ev.preventDefault();\n\n      if (this.dispatch('pinchZoomStart', {\n        event: ev\n      }).defaultPrevented) {\n        return;\n      }\n\n      this.off('touchstart.panZoom', pinchZoomStart);\n      zoomInProgress = true;\n      on(document, 'touchmove.panZoom', pinchZoom, this, {\n        passive: false\n      });\n      on(document, 'touchend.panZoom', pinchZoomStop, this, {\n        passive: false\n      });\n    };\n\n    var pinchZoomStop = function pinchZoomStop(ev) {\n      ev.preventDefault();\n      var currentTouches = normalizeEvent(ev);\n\n      if (currentTouches.length > 1) {\n        return;\n      }\n\n      zoomInProgress = false;\n      this.dispatch('pinchZoomEnd', {\n        event: ev\n      });\n      off(document, 'touchmove.panZoom', pinchZoom);\n      off(document, 'touchend.panZoom', pinchZoomStop);\n      this.on('touchstart.panZoom', pinchZoomStart);\n\n      if (currentTouches.length && doPanning && oneFingerPan) {\n        panStart.call(this, ev);\n      }\n    };\n\n    var pinchZoom = function pinchZoom(ev) {\n      ev.preventDefault();\n      var currentTouches = normalizeEvent(ev);\n      var zoom = this.zoom(); // Distance Formula\n\n      var lastDelta = Math.sqrt(Math.pow(lastTouches[0].clientX - lastTouches[1].clientX, 2) + Math.pow(lastTouches[0].clientY - lastTouches[1].clientY, 2));\n      var currentDelta = Math.sqrt(Math.pow(currentTouches[0].clientX - currentTouches[1].clientX, 2) + Math.pow(currentTouches[0].clientY - currentTouches[1].clientY, 2));\n      var zoomAmount = lastDelta / currentDelta;\n\n      if (zoom < zoomMin && zoomAmount > 1 || zoom > zoomMax && zoomAmount < 1) {\n        zoomAmount = 1;\n      }\n\n      var currentFocus = {\n        x: currentTouches[0].clientX + 0.5 * (currentTouches[1].clientX - currentTouches[0].clientX),\n        y: currentTouches[0].clientY + 0.5 * (currentTouches[1].clientY - currentTouches[0].clientY)\n      };\n      var lastFocus = {\n        x: lastTouches[0].clientX + 0.5 * (lastTouches[1].clientX - lastTouches[0].clientX),\n        y: lastTouches[0].clientY + 0.5 * (lastTouches[1].clientY - lastTouches[0].clientY)\n      };\n      var p = this.point(currentFocus.x, currentFocus.y);\n      var focusP = this.point(2 * currentFocus.x - lastFocus.x, 2 * currentFocus.y - lastFocus.y);\n      var box = new Box(this.viewbox()).transform(new Matrix().translate(-focusP.x, -focusP.y).scale(zoomAmount, 0, 0).translate(p.x, p.y));\n      restrictToMargins(box);\n      this.viewbox(box);\n      lastTouches = currentTouches;\n      this.dispatch('zoom', {\n        box: box,\n        focus: focusP\n      });\n    };\n\n    var panStart = function panStart(ev) {\n      var isMouse = ev.type.indexOf('mouse') > -1; // In case panStart is called with touch, ev.button is undefined\n\n      if (isMouse && ev.button !== panButton && ev.which !== panButton + 1) {\n        return;\n      }\n\n      ev.preventDefault();\n      this.off('mousedown.panZoom', panStart);\n      lastTouches = normalizeEvent(ev);\n      if (zoomInProgress) return;\n      this.dispatch('panStart', {\n        event: ev\n      });\n      lastP = {\n        x: lastTouches[0].clientX,\n        y: lastTouches[0].clientY\n      };\n      on(document, 'touchmove.panZoom mousemove.panZoom', panning, this, {\n        passive: false\n      });\n      on(document, 'touchend.panZoom mouseup.panZoom', panStop, this, {\n        passive: false\n      });\n    };\n\n    var panStop = function panStop(ev) {\n      ev.preventDefault();\n      off(document, 'touchmove.panZoom mousemove.panZoom', panning);\n      off(document, 'touchend.panZoom mouseup.panZoom', panStop);\n      this.on('mousedown.panZoom', panStart);\n      this.dispatch('panEnd', {\n        event: ev\n      });\n    };\n\n    var panning = function panning(ev) {\n      ev.preventDefault();\n      var currentTouches = normalizeEvent(ev);\n      var currentP = {\n        x: currentTouches[0].clientX,\n        y: currentTouches[0].clientY\n      };\n      var p1 = this.point(currentP.x, currentP.y);\n      var p2 = this.point(lastP.x, lastP.y);\n      var deltaP = [p2.x - p1.x, p2.y - p1.y];\n\n      if (!deltaP[0] && !deltaP[1]) {\n        return;\n      }\n\n      var box = new Box(this.viewbox()).transform(new Matrix().translate(deltaP[0], deltaP[1]));\n      lastP = currentP;\n      restrictToMargins(box);\n\n      if (this.dispatch('panning', {\n        box: box,\n        event: ev\n      }).defaultPrevented) {\n        return;\n      }\n\n      this.viewbox(box);\n    };\n\n    if (doWheelZoom) {\n      this.on('wheel.panZoom', wheelZoom, this, {\n        passive: false\n      });\n    }\n\n    if (doPinchZoom) {\n      this.on('touchstart.panZoom', pinchZoomStart, this, {\n        passive: false\n      });\n    }\n\n    if (doPanning) {\n      this.on('mousedown.panZoom', panStart, this, {\n        passive: false\n      });\n    }\n\n    return this;\n  }\n});\n//# sourceMappingURL=svg.panzoom.esm.js.map\n","/*!\n* @svgdotjs/svg.select.js - An extension of svg.js which allows to select elements with mouse\n* @version 4.0.3\n* https://github.com/svgdotjs/svg.select.js\n*\n* @copyright Ulrich-Matthias Schäfer\n* @license MIT\n*\n* BUILT: Tue May 06 2025 16:29:41 GMT+0200 (Central European Summer Time)\n*/\n;\nimport { G, getWindow, extend, Element, Polygon, Polyline, Line } from \"@svgdotjs/svg.js\";\nfunction getMoseDownFunc(eventName, el, points, index = null) {\n  return function(ev) {\n    ev.preventDefault();\n    ev.stopPropagation();\n    var x = ev.pageX || ev.touches[0].pageX;\n    var y = ev.pageY || ev.touches[0].pageY;\n    el.fire(eventName, { x, y, event: ev, index, points });\n  };\n}\nfunction transformPoint([x, y], { a, b, c, d, e, f }) {\n  return [x * a + y * c + e, x * b + y * d + f];\n}\nclass SelectHandler {\n  constructor(el) {\n    this.el = el;\n    el.remember(\"_selectHandler\", this);\n    this.selection = new G();\n    this.order = [\"lt\", \"t\", \"rt\", \"r\", \"rb\", \"b\", \"lb\", \"l\", \"rot\"];\n    this.mutationHandler = this.mutationHandler.bind(this);\n    const win = getWindow();\n    this.observer = new win.MutationObserver(this.mutationHandler);\n  }\n  init(options) {\n    this.createHandle = options.createHandle || this.createHandleFn;\n    this.createRot = options.createRot || this.createRotFn;\n    this.updateHandle = options.updateHandle || this.updateHandleFn;\n    this.updateRot = options.updateRot || this.updateRotFn;\n    this.el.root().put(this.selection);\n    this.updatePoints();\n    this.createSelection();\n    this.createResizeHandles();\n    this.updateResizeHandles();\n    this.createRotationHandle();\n    this.updateRotationHandle();\n    this.observer.observe(this.el.node, { attributes: true });\n  }\n  active(val, options) {\n    if (!val) {\n      this.selection.clear().remove();\n      this.observer.disconnect();\n      return;\n    }\n    this.init(options);\n  }\n  createSelection() {\n    this.selection.polygon(this.handlePoints).addClass(\"svg_select_shape\");\n  }\n  updateSelection() {\n    this.selection.get(0).plot(this.handlePoints);\n  }\n  createResizeHandles() {\n    this.handlePoints.forEach((p, index, arr) => {\n      const name = this.order[index];\n      this.createHandle.call(this, this.selection, p, index, arr, name);\n      this.selection.get(index + 1).addClass(\"svg_select_handle svg_select_handle_\" + name).on(\"mousedown.selection touchstart.selection\", getMoseDownFunc(name, this.el, this.handlePoints, index));\n    });\n  }\n  createHandleFn(group) {\n    group.polyline();\n  }\n  updateHandleFn(shape, point, index, arr) {\n    const before = arr.at(index - 1);\n    const next = arr[(index + 1) % arr.length];\n    const p = point;\n    const diff1 = [p[0] - before[0], p[1] - before[1]];\n    const diff2 = [p[0] - next[0], p[1] - next[1]];\n    const len1 = Math.sqrt(diff1[0] * diff1[0] + diff1[1] * diff1[1]);\n    const len2 = Math.sqrt(diff2[0] * diff2[0] + diff2[1] * diff2[1]);\n    const normalized1 = [diff1[0] / len1, diff1[1] / len1];\n    const normalized2 = [diff2[0] / len2, diff2[1] / len2];\n    const beforeNew = [p[0] - normalized1[0] * 10, p[1] - normalized1[1] * 10];\n    const nextNew = [p[0] - normalized2[0] * 10, p[1] - normalized2[1] * 10];\n    shape.plot([beforeNew, p, nextNew]);\n  }\n  updateResizeHandles() {\n    this.handlePoints.forEach((p, index, arr) => {\n      const name = this.order[index];\n      this.updateHandle.call(this, this.selection.get(index + 1), p, index, arr, name);\n    });\n  }\n  createRotFn(group) {\n    group.line();\n    group.circle(5);\n  }\n  getPoint(name) {\n    return this.handlePoints[this.order.indexOf(name)];\n  }\n  getPointHandle(name) {\n    return this.selection.get(this.order.indexOf(name) + 1);\n  }\n  updateRotFn(group, rotPoint) {\n    const topPoint = this.getPoint(\"t\");\n    group.get(0).plot(topPoint[0], topPoint[1], rotPoint[0], rotPoint[1]);\n    group.get(1).center(rotPoint[0], rotPoint[1]);\n  }\n  createRotationHandle() {\n    const handle = this.selection.group().addClass(\"svg_select_handle_rot\").on(\"mousedown.selection touchstart.selection\", getMoseDownFunc(\"rot\", this.el, this.handlePoints));\n    this.createRot.call(this, handle);\n  }\n  updateRotationHandle() {\n    const group = this.selection.findOne(\"g.svg_select_handle_rot\");\n    this.updateRot(group, this.rotationPoint, this.handlePoints);\n  }\n  // gets new bounding box points and transform them into the elements space\n  updatePoints() {\n    const bbox = this.el.bbox();\n    const fromShapeToUiMatrix = this.el.root().screenCTM().inverseO().multiplyO(this.el.screenCTM());\n    this.handlePoints = this.getHandlePoints(bbox).map((p) => transformPoint(p, fromShapeToUiMatrix));\n    this.rotationPoint = transformPoint(this.getRotationPoint(bbox), fromShapeToUiMatrix);\n  }\n  // A collection of all the points we need to draw our ui\n  getHandlePoints({ x, x2, y, y2, cx, cy } = this.el.bbox()) {\n    return [\n      [x, y],\n      [cx, y],\n      [x2, y],\n      [x2, cy],\n      [x2, y2],\n      [cx, y2],\n      [x, y2],\n      [x, cy]\n    ];\n  }\n  // A collection of all the points we need to draw our ui\n  getRotationPoint({ y, cx } = this.el.bbox()) {\n    return [cx, y - 20];\n  }\n  mutationHandler() {\n    this.updatePoints();\n    this.updateSelection();\n    this.updateResizeHandles();\n    this.updateRotationHandle();\n  }\n}\nclass PointSelectHandler {\n  constructor(el) {\n    this.el = el;\n    el.remember(\"_pointSelectHandler\", this);\n    this.selection = new G();\n    this.order = [\"lt\", \"t\", \"rt\", \"r\", \"rb\", \"b\", \"lb\", \"l\", \"rot\"];\n    this.mutationHandler = this.mutationHandler.bind(this);\n    const win = getWindow();\n    this.observer = new win.MutationObserver(this.mutationHandler);\n  }\n  init(options) {\n    this.createHandle = options.createHandle || this.createHandleFn;\n    this.updateHandle = options.updateHandle || this.updateHandleFn;\n    this.el.root().put(this.selection);\n    this.updatePoints();\n    this.createSelection();\n    this.createPointHandles();\n    this.updatePointHandles();\n    this.observer.observe(this.el.node, { attributes: true });\n  }\n  active(val, options) {\n    if (!val) {\n      this.selection.clear().remove();\n      this.observer.disconnect();\n      return;\n    }\n    this.init(options);\n  }\n  createSelection() {\n    this.selection.polygon(this.points).addClass(\"svg_select_shape_pointSelect\");\n  }\n  updateSelection() {\n    this.selection.get(0).plot(this.points);\n  }\n  createPointHandles() {\n    this.points.forEach((p, index, arr) => {\n      this.createHandle.call(this, this.selection, p, index, arr);\n      this.selection.get(index + 1).addClass(\"svg_select_handle_point\").on(\"mousedown.selection touchstart.selection\", getMoseDownFunc(\"point\", this.el, this.points, index));\n    });\n  }\n  createHandleFn(group) {\n    group.circle(5);\n  }\n  updateHandleFn(shape, point) {\n    shape.center(point[0], point[1]);\n  }\n  updatePointHandles() {\n    this.points.forEach((p, index, arr) => {\n      this.updateHandle.call(this, this.selection.get(index + 1), p, index, arr);\n    });\n  }\n  // gets new bounding box points and transform them into the elements space\n  updatePoints() {\n    const fromShapeToUiMatrix = this.el.root().screenCTM().inverseO().multiplyO(this.el.screenCTM());\n    this.points = this.el.array().map((p) => transformPoint(p, fromShapeToUiMatrix));\n  }\n  mutationHandler() {\n    this.updatePoints();\n    this.updateSelection();\n    this.updatePointHandles();\n  }\n}\nconst getSelectFn = (handleClass) => {\n  return function(enabled = true, options = {}) {\n    if (typeof enabled === \"object\") {\n      options = enabled;\n      enabled = true;\n    }\n    let selectHandler = this.remember(\"_\" + handleClass.name);\n    if (!selectHandler) {\n      if (enabled.prototype instanceof SelectHandler) {\n        selectHandler = new enabled(this);\n        enabled = true;\n      } else {\n        selectHandler = new handleClass(this);\n      }\n      this.remember(\"_\" + handleClass.name, selectHandler);\n    }\n    selectHandler.active(enabled, options);\n    return this;\n  };\n};\nextend(Element, {\n  select: getSelectFn(SelectHandler)\n});\nextend([Polygon, Polyline, Line], {\n  pointSelect: getSelectFn(PointSelectHandler)\n});\nexport {\n  PointSelectHandler,\n  SelectHandler\n};\n//# sourceMappingURL=svg.select.js.map\n","/*!\n* @svgdotjs/svg.resize.js - An extension for svg.js which allows to resize elements which are selected\n* @version 2.0.5\n* https://github.com/svgdotjs/svg.resize.js\n*\n* @copyright [object Object]\n* @license MIT\n*\n* BUILT: Wed Nov 20 2024 23:15:57 GMT+0100 (Central European Standard Time)\n*/\n;\nimport \"@svgdotjs/svg.select.js\";\nimport { on, Box, Matrix, Point, off, extend, Element } from \"@svgdotjs/svg.js\";\nconst getCoordsFromEvent = (ev) => {\n  if (ev.changedTouches) {\n    ev = ev.changedTouches[0];\n  }\n  return { x: ev.clientX, y: ev.clientY };\n};\nconst maxBoxFromPoints = (points) => {\n  let x = Infinity;\n  let y = Infinity;\n  let x2 = -Infinity;\n  let y2 = -Infinity;\n  for (let i = 0; i < points.length; i++) {\n    const p = points[i];\n    x = Math.min(x, p[0]);\n    y = Math.min(y, p[1]);\n    x2 = Math.max(x2, p[0]);\n    y2 = Math.max(y2, p[1]);\n  }\n  return new Box(x, y, x2 - x, y2 - y);\n};\nfunction scaleBox(box, origin, scale) {\n  const points = [\n    [box.x, box.y],\n    [box.x + box.width, box.y],\n    [box.x + box.width, box.y + box.height],\n    [box.x, box.y + box.height]\n  ];\n  const newPoints = points.map(([x, y]) => {\n    const translatedX = x - origin[0];\n    const translatedY = y - origin[1];\n    const scaledX = translatedX * scale;\n    const scaledY = translatedY * scale;\n    return [scaledX + origin[0], scaledY + origin[1]];\n  });\n  return maxBoxFromPoints(newPoints);\n}\nclass ResizeHandler {\n  constructor(el) {\n    this.el = el;\n    el.remember(\"_ResizeHandler\", this);\n    this.lastCoordinates = null;\n    this.eventType = \"\";\n    this.lastEvent = null;\n    this.handleResize = this.handleResize.bind(this);\n    this.resize = this.resize.bind(this);\n    this.endResize = this.endResize.bind(this);\n    this.rotate = this.rotate.bind(this);\n    this.movePoint = this.movePoint.bind(this);\n  }\n  active(value, options) {\n    this.preserveAspectRatio = options.preserveAspectRatio ?? false;\n    this.aroundCenter = options.aroundCenter ?? false;\n    this.grid = options.grid ?? 0;\n    this.degree = options.degree ?? 0;\n    this.el.off(\".resize\");\n    if (!value) return;\n    this.el.on(\n      [\n        \"lt.resize\",\n        \"rt.resize\",\n        \"rb.resize\",\n        \"lb.resize\",\n        \"t.resize\",\n        \"r.resize\",\n        \"b.resize\",\n        \"l.resize\",\n        \"rot.resize\",\n        \"point.resize\"\n      ],\n      this.handleResize\n    );\n    if (this.lastEvent) {\n      if (this.eventType === \"rot\") {\n        this.rotate(this.lastEvent);\n      } else if (this.eventType === \"point\") {\n        this.movePoint(this.lastEvent);\n      } else {\n        this.resize(this.lastEvent);\n      }\n    }\n  }\n  // This is called when a user clicks on one of the resize points\n  handleResize(e) {\n    this.eventType = e.type;\n    const { event, index, points } = e.detail;\n    const isMouse = !event.type.indexOf(\"mouse\");\n    if (isMouse && (event.which || event.buttons) !== 1) {\n      return;\n    }\n    if (this.el.dispatch(\"beforeresize\", { event: e, handler: this }).defaultPrevented) {\n      return;\n    }\n    this.box = this.el.bbox();\n    this.startPoint = this.el.point(getCoordsFromEvent(event));\n    this.index = index;\n    this.points = points.slice();\n    const eventMove = (isMouse ? \"mousemove\" : \"touchmove\") + \".resize\";\n    const eventEnd = (isMouse ? \"mouseup\" : \"touchcancel.resize touchend\") + \".resize\";\n    if (e.type === \"point\") {\n      on(window, eventMove, this.movePoint);\n    } else if (e.type === \"rot\") {\n      on(window, eventMove, this.rotate);\n    } else {\n      on(window, eventMove, this.resize);\n    }\n    on(window, eventEnd, this.endResize);\n  }\n  resize(e) {\n    this.lastEvent = e;\n    const endPoint = this.snapToGrid(this.el.point(getCoordsFromEvent(e)));\n    let dx = endPoint.x - this.startPoint.x;\n    let dy = endPoint.y - this.startPoint.y;\n    if (this.preserveAspectRatio && this.aroundCenter) {\n      dx *= 2;\n      dy *= 2;\n    }\n    const x = this.box.x + dx;\n    const y = this.box.y + dy;\n    const x2 = this.box.x2 + dx;\n    const y2 = this.box.y2 + dy;\n    let box = new Box(this.box);\n    if (this.eventType.includes(\"l\")) {\n      box.x = Math.min(x, this.box.x2);\n      box.x2 = Math.max(x, this.box.x2);\n    }\n    if (this.eventType.includes(\"r\")) {\n      box.x = Math.min(x2, this.box.x);\n      box.x2 = Math.max(x2, this.box.x);\n    }\n    if (this.eventType.includes(\"t\")) {\n      box.y = Math.min(y, this.box.y2);\n      box.y2 = Math.max(y, this.box.y2);\n    }\n    if (this.eventType.includes(\"b\")) {\n      box.y = Math.min(y2, this.box.y);\n      box.y2 = Math.max(y2, this.box.y);\n    }\n    box.width = box.x2 - box.x;\n    box.height = box.y2 - box.y;\n    if (this.preserveAspectRatio) {\n      const scaleX = box.width / this.box.width;\n      const scaleY = box.height / this.box.height;\n      const order = [\"lt\", \"t\", \"rt\", \"r\", \"rb\", \"b\", \"lb\", \"l\"];\n      const origin = (order.indexOf(this.eventType) + 4) % order.length;\n      const constantPoint = this.aroundCenter ? [this.box.cx, this.box.cy] : this.points[origin];\n      let scale = this.eventType.includes(\"t\") || this.eventType.includes(\"b\") ? scaleY : scaleX;\n      scale = this.eventType.length === 2 ? Math.max(scaleX, scaleY) : scale;\n      box = scaleBox(this.box, constantPoint, scale);\n    }\n    if (this.el.dispatch(\"resize\", {\n      box: new Box(box),\n      angle: 0,\n      eventType: this.eventType,\n      event: e,\n      handler: this\n    }).defaultPrevented) {\n      return;\n    }\n    this.el.size(box.width, box.height).move(box.x, box.y);\n  }\n  movePoint(e) {\n    this.lastEvent = e;\n    const { x, y } = this.snapToGrid(this.el.point(getCoordsFromEvent(e)));\n    const pointArr = this.el.array().slice();\n    pointArr[this.index] = [x, y];\n    if (this.el.dispatch(\"resize\", {\n      box: maxBoxFromPoints(pointArr),\n      angle: 0,\n      eventType: this.eventType,\n      event: e,\n      handler: this\n    }).defaultPrevented) {\n      return;\n    }\n    this.el.plot(pointArr);\n  }\n  rotate(e) {\n    this.lastEvent = e;\n    const startPoint = this.startPoint;\n    const endPoint = this.el.point(getCoordsFromEvent(e));\n    const { cx, cy } = this.box;\n    const dx1 = startPoint.x - cx;\n    const dy1 = startPoint.y - cy;\n    const dx2 = endPoint.x - cx;\n    const dy2 = endPoint.y - cy;\n    const c = Math.sqrt(dx1 * dx1 + dy1 * dy1) * Math.sqrt(dx2 * dx2 + dy2 * dy2);\n    if (c === 0) {\n      return;\n    }\n    let angle = Math.acos((dx1 * dx2 + dy1 * dy2) / c) / Math.PI * 180;\n    if (!angle) return;\n    if (endPoint.x < startPoint.x) {\n      angle = -angle;\n    }\n    const matrix = new Matrix(this.el);\n    const { x: ox, y: oy } = new Point(cx, cy).transformO(matrix);\n    const { rotate } = matrix.decompose();\n    const resultAngle = this.snapToAngle(rotate + angle) - rotate;\n    if (this.el.dispatch(\"resize\", {\n      box: this.box,\n      angle: resultAngle,\n      eventType: this.eventType,\n      event: e,\n      handler: this\n    }).defaultPrevented) {\n      return;\n    }\n    this.el.transform(matrix.rotateO(resultAngle, ox, oy));\n  }\n  endResize(ev) {\n    if (this.eventType !== \"rot\" && this.eventType !== \"point\") {\n      this.resize(ev);\n    }\n    this.lastEvent = null;\n    this.eventType = \"\";\n    off(window, \"mousemove.resize touchmove.resize\");\n    off(window, \"mouseup.resize touchend.resize\");\n  }\n  snapToGrid(point) {\n    if (this.grid) {\n      point.x = Math.round(point.x / this.grid) * this.grid;\n      point.y = Math.round(point.y / this.grid) * this.grid;\n    }\n    return point;\n  }\n  snapToAngle(angle) {\n    if (this.degree) {\n      angle = Math.round(angle / this.degree) * this.degree;\n    }\n    return angle;\n  }\n}\nextend(Element, {\n  // Resize element with mouse\n  resize: function(enabled = true, options = {}) {\n    if (typeof enabled === \"object\") {\n      options = enabled;\n      enabled = true;\n    }\n    let resizeHandler = this.remember(\"_ResizeHandler\");\n    if (!resizeHandler) {\n      if (enabled.prototype instanceof ResizeHandler) {\n        resizeHandler = new enabled(this);\n        enabled = true;\n      } else {\n        resizeHandler = new ResizeHandler(this);\n      }\n      this.remember(\"_resizeHandler\", resizeHandler);\n    }\n    resizeHandler.active(enabled, options);\n    return this;\n  }\n});\nexport {\n  ResizeHandler\n};\n//# sourceMappingURL=svg.resize.js.map\n","/**\n * Geometry utilities for SVG Connectable\n * Handles coordinate calculations, edge detection, and path computation\n */\n\n/**\n * Helper function to calculate angle between two points\n */\nfunction calculateAngle(p1, p2) {\n  return (Math.atan2(p2[1] - p1[1], p2[0] - p1[0]) * 180) / Math.PI;\n}\n\n/**\n * Helper function to get the tangent angle at a point on a curve\n */\nfunction getTangentAngle(pathData, isStart) {\n  if (pathData.length < 2) return 0;\n\n  if (isStart) {\n    // For start point, use direction from first to second control point\n    const p1 = [pathData[0][1], pathData[0][2]]; // M command\n    const nextCmd = pathData[1];\n    let p2;\n\n    if (nextCmd[0] === \"C\") {\n      // Cubic bezier - use first control point\n      p2 = [nextCmd[1], nextCmd[2]];\n    } else if (nextCmd[0] === \"L\") {\n      // Line - use end point\n      p2 = [nextCmd[1], nextCmd[2]];\n    } else {\n      // Fallback\n      p2 = [nextCmd[nextCmd.length - 2], nextCmd[nextCmd.length - 1]];\n    }\n\n    return calculateAngle(p1, p2);\n  } else {\n    // For end point, use direction from last control point to end\n    const lastCmd = pathData[pathData.length - 1];\n    const p2 = [lastCmd[lastCmd.length - 2], lastCmd[lastCmd.length - 1]];\n    let p1;\n\n    if (lastCmd[0] === \"C\") {\n      // Cubic bezier - use last control point\n      p1 = [lastCmd[lastCmd.length - 4], lastCmd[lastCmd.length - 3]];\n    } else if (pathData.length > 1) {\n      // Use previous point\n      const prevCmd = pathData[pathData.length - 2];\n      p1 = [prevCmd[prevCmd.length - 2], prevCmd[prevCmd.length - 1]];\n    } else {\n      // Fallback\n      p1 = [lastCmd[1], lastCmd[2]];\n    }\n\n    return calculateAngle(p1, p2);\n  }\n}\n\n/**\n * Transform a point from element-local coordinates to SVG user coordinates.\n * This properly handles the viewBox transform that getCTM() includes.\n *\n * getCTM() = viewBoxTransform * elementOwnTransform\n * We need just: elementOwnTransform * localPoint\n * So: svgUserCoords = inverse(rootCTM) * elementCTM * localPoint\n */\nfunction localToSvgCoords(element, localX, localY) {\n  try {\n    // Get the root SVG element\n    const svgRoot = element.node.ownerSVGElement || element.node;\n\n    // Use SVGPoint + getScreenCTM for reliable coordinate transformation\n    const screenCTM = element.node.getScreenCTM();\n    const rootScreenCTM = svgRoot.getScreenCTM();\n\n    if (!screenCTM || !rootScreenCTM) {\n      return [localX, localY];\n    }\n\n    // Transform local point to screen coordinates using element's screenCTM\n    const screenX = screenCTM.a * localX + screenCTM.c * localY + screenCTM.e;\n    const screenY = screenCTM.b * localX + screenCTM.d * localY + screenCTM.f;\n\n    // Transform screen coordinates back to SVG user coordinates using inverse of root's screenCTM\n    const det = rootScreenCTM.a * rootScreenCTM.d - rootScreenCTM.b * rootScreenCTM.c;\n    if (Math.abs(det) < 1e-10) {\n      return [localX, localY];\n    }\n\n    const invA = rootScreenCTM.d / det;\n    const invB = -rootScreenCTM.b / det;\n    const invC = -rootScreenCTM.c / det;\n    const invD = rootScreenCTM.a / det;\n    const invE = (rootScreenCTM.c * rootScreenCTM.f - rootScreenCTM.d * rootScreenCTM.e) / det;\n    const invF = (rootScreenCTM.b * rootScreenCTM.e - rootScreenCTM.a * rootScreenCTM.f) / det;\n\n    const svgX = invA * screenX + invC * screenY + invE;\n    const svgY = invB * screenX + invD * screenY + invF;\n\n    return [svgX, svgY];\n  } catch (e) {\n    return [localX, localY];\n  }\n}\n\n/**\n * Transform a point from SVG user coordinates to element-local coordinates.\n */\nfunction svgCoordsToLocal(element, svgX, svgY) {\n  try {\n    const svgRoot = element.node.ownerSVGElement || element.node;\n    const screenCTM = element.node.getScreenCTM();\n    const rootScreenCTM = svgRoot.getScreenCTM();\n\n    if (!screenCTM || !rootScreenCTM) {\n      return [svgX, svgY];\n    }\n\n    // First: SVG user coords → screen coords using root's screenCTM\n    const screenX = rootScreenCTM.a * svgX + rootScreenCTM.c * svgY + rootScreenCTM.e;\n    const screenY = rootScreenCTM.b * svgX + rootScreenCTM.d * svgY + rootScreenCTM.f;\n\n    // Then: screen coords → element local coords using inverse of element's screenCTM\n    const det = screenCTM.a * screenCTM.d - screenCTM.b * screenCTM.c;\n    if (Math.abs(det) < 1e-10) {\n      return [svgX, svgY];\n    }\n\n    const invA = screenCTM.d / det;\n    const invB = -screenCTM.b / det;\n    const invC = -screenCTM.c / det;\n    const invD = screenCTM.a / det;\n    const invE = (screenCTM.c * screenCTM.f - screenCTM.d * screenCTM.e) / det;\n    const invF = (screenCTM.b * screenCTM.e - screenCTM.a * screenCTM.f) / det;\n\n    const localX = invA * screenX + invC * screenY + invE;\n    const localY = invB * screenX + invD * screenY + invF;\n\n    return [localX, localY];\n  } catch (e) {\n    return [svgX, svgY];\n  }\n}\n\n/**\n * getElementCenter\n * Gets the center point of an SVG element in SVG user coordinates\n */\nfunction getElementCenter(element) {\n  const bbox = element.bbox();\n  return localToSvgCoords(element, bbox.cx, bbox.cy);\n}\n\n/**\n * getClosestPointOnEdge\n * Calculates the closest point on the edge of a shape to another point.\n * All coordinates are in SVG user coordinate space (viewBox coords).\n */\n/**\n * For vector (path) shapes, attach the connector to the ACTUAL path outline\n * rather than the bounding box, so arrows touch the real shape (star arms, etc.).\n * Samples the tagged shape <path> and picks the outline point best aligned with\n * the ray from the shape centre toward `targetPoint`. Returns null for shapes\n * without a tagged path (native rect/circle/ellipse keep their exact math).\n */\nfunction closestPointOnPathOutline(shape, targetPoint) {\n  try {\n    const node = shape && shape.node;\n    let pathEl =\n      node && node.querySelector && node.querySelector(\"path[data-shape-path]\");\n    // svgContent nodes (custom SVG artwork — e.g. a flower/cloud shape) have no\n    // tagged shape path, so the connector was falling back to the bounding BOX and\n    // the arrow floated in the empty corner instead of touching the artwork. Use\n    // the largest <path> inside the node's nested <svg> as the outline so the arrow\n    // attaches flush to the shape. (Native rect/circle have no nested path → still\n    // null → their exact edge math is used, unchanged.)\n    if (!pathEl && node && node.querySelectorAll) {\n      let bestArea = 0;\n      node\n        .querySelectorAll(\"svg path:not([data-node-background-path])\")\n        .forEach((cand) => {\n          if (typeof cand.getTotalLength !== \"function\") return;\n          try {\n            const b = cand.getBBox();\n            const area = b.width * b.height;\n            if (area > bestArea) {\n              bestArea = area;\n              pathEl = cand;\n            }\n          } catch (e) {\n            /* noop */\n          }\n        });\n    }\n    if (!pathEl || typeof pathEl.getTotalLength !== \"function\") return null;\n    const total = pathEl.getTotalLength();\n    if (!total || !isFinite(total)) return null;\n\n    // The path lives in a nested <svg> with its own viewBox. Convert its local\n    // points to the connector's coordinate space via screen CTMs: path-local →\n    // screen → root SVG user space (the space getElementCenter/points use).\n    // ownerSVGElement is the NEAREST ancestor <svg>. A shape outline lives in a\n    // nested <svg> (its own viewBox), so ownerSVGElement is that nested svg —\n    // whose screen CTM equals the path's, making the local→user transform a no-op\n    // (outline points come back in viewBox coords and get rejected as \"too far\").\n    // Walk up to the OUTERMOST svg, which is the connector's coordinate space.\n    let rootSvg = pathEl.ownerSVGElement;\n    while (rootSvg && rootSvg.ownerSVGElement) rootSvg = rootSvg.ownerSVGElement;\n    const pathCTM = pathEl.getScreenCTM && pathEl.getScreenCTM();\n    const rootScreenCTM = rootSvg && rootSvg.getScreenCTM && rootSvg.getScreenCTM();\n    if (!rootSvg || !pathCTM || !rootScreenCTM) return null;\n    const rootInv = rootScreenCTM.inverse();\n    const sp = rootSvg.createSVGPoint();\n    const toUser = (lx, ly) => {\n      sp.x = lx;\n      sp.y = ly;\n      const u = sp.matrixTransform(pathCTM).matrixTransform(rootInv);\n      return [u.x, u.y];\n    };\n\n    const [cx, cy] = getElementCenter(shape);\n    const dirX = targetPoint[0] - cx;\n    const dirY = targetPoint[1] - cy;\n    const dm = Math.sqrt(dirX * dirX + dirY * dirY) || 1;\n    const ux = dirX / dm;\n    const uy = dirY / dm;\n\n    let best = null;\n    let bestScore = -Infinity;\n    // getPointAtLength is an expensive DOM call, and this runs on every connector\n    // update (every frame of a node drag). The path's LOCAL outline is constant —\n    // only its transform changes — so sample the local points ONCE and cache them\n    // on the element, then just matrix-transform the cached points per frame. This\n    // is what made dragging nodes with complex custom-shape connectors slow.\n    const N = 96;\n    let samples = pathEl.__outlineSamples;\n    if (!samples || pathEl.__outlineLen !== total) {\n      samples = new Array(N);\n      for (let i = 0; i < N; i++) {\n        const lp = pathEl.getPointAtLength((i / N) * total);\n        samples[i] = [lp.x, lp.y];\n      }\n      pathEl.__outlineSamples = samples;\n      pathEl.__outlineLen = total;\n    }\n    for (let i = 0; i < samples.length; i++) {\n      const [wx, wy] = toUser(samples[i][0], samples[i][1]);\n      if (!isFinite(wx) || !isFinite(wy)) continue;\n      const px = wx - cx;\n      const py = wy - cy;\n      const proj = px * ux + py * uy; // toward the target direction\n      const perp = Math.abs(px * uy - py * ux); // offset from the ray\n      const score = proj - perp * 1.5; // outermost point on the ray\n      if (score > bestScore) {\n        bestScore = score;\n        best = [wx, wy];\n      }\n    }\n    return best;\n  } catch (e) {\n    return null;\n  }\n}\n\nfunction getClosestPointOnEdge(shape, targetPoint) {\n  // Vector shapes: attach to the real outline when we can transform it reliably.\n  // (Guarded — nested-SVG viewBox paths need the correct coordinate transform;\n  // falls back to the bbox intersection otherwise so the connector never breaks.)\n  const outline = closestPointOnPathOutline(shape, targetPoint);\n  if (outline && isFinite(outline[0]) && isFinite(outline[1])) {\n    // Sanity: the outline point must be within a reasonable distance of the\n    // shape's bbox (guards against a bad coordinate transform sending it away).\n    const bb = shape.bbox();\n    const [ccx, ccy] = localToSvgCoords(shape, bb.cx, bb.cy);\n    const span = Math.max(bb.width, bb.height, 1) * 3;\n    if (Math.hypot(outline[0] - ccx, outline[1] - ccy) <= span) {\n      return outline;\n    }\n  }\n\n  const bbox = shape.bbox();\n\n  // Convert target point from SVG coords to shape's local coords\n  const [localTargetX, localTargetY] = svgCoordsToLocal(shape, targetPoint[0], targetPoint[1]);\n\n  // Calculate direction vector from shape center to local target point\n  const centerX = bbox.cx;\n  const centerY = bbox.cy;\n  const dx = localTargetX - centerX;\n  const dy = localTargetY - centerY;\n  const distance = Math.sqrt(dx * dx + dy * dy);\n\n  // Avoid division by zero\n  if (distance === 0) {\n    return localToSvgCoords(shape, centerX, centerY);\n  }\n\n  // Normalize direction vector\n  const ux = dx / distance;\n  const uy = dy / distance;\n\n  // Calculate edge point in local coordinates\n  let localEdgePoint;\n\n  if (shape.type === \"circle\") {\n    const radius = parseFloat(shape.attr(\"r\")) || 0;\n    localEdgePoint = [centerX + radius * ux, centerY + radius * uy];\n  } else if (shape.type === \"ellipse\") {\n    const rx = parseFloat(shape.attr(\"rx\")) || 0;\n    const ry = parseFloat(shape.attr(\"ry\")) || 0;\n    const angle = Math.atan2(uy, ux);\n    localEdgePoint = [\n      centerX + rx * Math.cos(angle),\n      centerY + ry * Math.sin(angle),\n    ];\n  } else {\n    // For rectangles/groups, find intersection with bbox edges\n    const left = bbox.x;\n    const right = bbox.x + bbox.width;\n    const top = bbox.y;\n    const bottom = bbox.y + bbox.height;\n\n    const intersections = [];\n\n    if (ux !== 0) {\n      const t = (left - centerX) / ux;\n      const y = centerY + t * uy;\n      if (y >= top && y <= bottom && t > 0) {\n        intersections.push([left, y, t]);\n      }\n    }\n\n    if (ux !== 0) {\n      const t = (right - centerX) / ux;\n      const y = centerY + t * uy;\n      if (y >= top && y <= bottom && t > 0) {\n        intersections.push([right, y, t]);\n      }\n    }\n\n    if (uy !== 0) {\n      const t = (top - centerY) / uy;\n      const x = centerX + t * ux;\n      if (x >= left && x <= right && t > 0) {\n        intersections.push([x, top, t]);\n      }\n    }\n\n    if (uy !== 0) {\n      const t = (bottom - centerY) / uy;\n      const x = centerX + t * ux;\n      if (x >= left && x <= right && t > 0) {\n        intersections.push([x, bottom, t]);\n      }\n    }\n\n    if (intersections.length > 0) {\n      intersections.sort(function (a, b) {\n        return a[2] - b[2];\n      });\n      localEdgePoint = [intersections[0][0], intersections[0][1]];\n    } else {\n      localEdgePoint = [centerX, centerY];\n    }\n  }\n\n  // Transform edge point back to SVG user coordinates\n  const [worldEdgeX, worldEdgeY] = localToSvgCoords(shape, localEdgePoint[0], localEdgePoint[1]);\n\n  if (isNaN(worldEdgeX) || isNaN(worldEdgeY) || !isFinite(worldEdgeX) || !isFinite(worldEdgeY)) {\n    return localToSvgCoords(shape, centerX, centerY);\n  }\n\n  return [worldEdgeX, worldEdgeY];\n}\n\n/**\n * computeConnectorCoordinates\n * Computes the connector path between source and target elements.\n * All coordinates are in SVG user coordinate space.\n */\n/**\n * Compute a fixed anchor point on a shape from a normalized local anchor\n * {x,y} in 0..1 (0,0 = top-left, 0.5,0.5 = center, 1,1 = bottom-right of the\n * shape's local bbox), transformed to SVG user coords through the shape's\n * matrix. Because the transform includes rotation, an edge-pinned endpoint\n * rotates WITH the node (edge-pin mode).\n */\nfunction anchorPointOnShape(shape, anchor) {\n  const bbox = shape.bbox();\n  const lx = bbox.x + (anchor.x != null ? anchor.x : 0.5) * bbox.width;\n  const ly = bbox.y + (anchor.y != null ? anchor.y : 0.5) * bbox.height;\n  const [wx, wy] = localToSvgCoords(shape, lx, ly);\n  if (isNaN(wx) || isNaN(wy) || !isFinite(wx) || !isFinite(wy)) {\n    return getElementCenter(shape);\n  }\n  return [wx, wy];\n}\n\n/**\n * edgeNormalAt\n * Outward unit normal of the node EDGE that `portSvg` sits on, in SVG coords.\n * For a rectangle this is axis-aligned (perpendicular to the specific edge), which\n * is what makes an arrow tip meet the edge at 90° — unlike the radial center→port\n * direction, which only equals the normal at edge midpoints. Rotation is honored\n * by mapping the local normal through two points. Returns null on failure so the\n * caller can fall back to the radial direction (correct for circles).\n */\nfunction edgeNormalAt(shape, portSvg) {\n  try {\n    const bb = shape.bbox();\n    if (!bb || !bb.width || !bb.height) return null;\n    const [lx, ly] = svgCoordsToLocal(shape, portSvg[0], portSvg[1]);\n    const nx = (lx - bb.x) / bb.width;\n    const ny = (ly - bb.y) / bb.height;\n    const dl = nx;\n    const dr = 1 - nx;\n    const dt = ny;\n    const db = 1 - ny;\n    const m = Math.min(dl, dr, dt, db);\n    let lnx = 0;\n    let lny = 0;\n    if (m === dl) lnx = -1;\n    else if (m === dr) lnx = 1;\n    else if (m === dt) lny = -1;\n    else lny = 1;\n    // Map the local normal DIRECTION to SVG coords via center and center+normal.\n    const p0 = localToSvgCoords(shape, bb.cx, bb.cy);\n    const p1 = localToSvgCoords(shape, bb.cx + lnx, bb.cy + lny);\n    const vx = p1[0] - p0[0];\n    const vy = p1[1] - p0[1];\n    const mag = Math.hypot(vx, vy);\n    if (!(mag > 0.0001)) return null;\n    return [vx / mag, vy / mag];\n  } catch (e) {\n    return null;\n  }\n}\n\nfunction computeConnectorCoordinates(con) {\n  const temp = {};\n\n  if (!con.source || !con.target) {\n    return [\n      [\"M\", 0, 0],\n      [\"L\", 50, 50],\n    ];\n  }\n\n  // Get centers in SVG user coordinates\n  const sourceCenter = getElementCenter(con.source);\n  const targetCenter = getElementCenter(con.target);\n\n  // Calculate attachment points\n  // Edge-pin mode: a fixed normalized local anchor that rotates with the node.\n  if (con.sourceAnchor) {\n    temp.point1 = anchorPointOnShape(con.source, con.sourceAnchor);\n  } else if (con.sourceAttach === \"center\") {\n    temp.point1 = sourceCenter;\n  } else {\n    // Endpoint sits exactly on the node edge. The arrow marker is anchored at\n    // its TIP (refX), so the point touches the edge — no outward offset needed\n    // (an offset here would leave a gap between the arrow tip and the node).\n    temp.point1 = getClosestPointOnEdge(con.source, targetCenter);\n  }\n\n  if (con.targetAnchor) {\n    temp.point2 = anchorPointOnShape(con.target, con.targetAnchor);\n  } else if (con.targetAttach === \"center\") {\n    temp.point2 = targetCenter;\n  } else {\n    // Endpoint sits exactly on the node edge (arrow is tip-anchored — see above).\n    temp.point2 = getClosestPointOnEdge(con.target, sourceCenter);\n  }\n\n  const pp1 = temp.point1;\n  const pp2 = temp.point2;\n\n  let points;\n\n  if (con.type === \"curved\") {\n    const dx = pp2[0] - pp1[0];\n    const dy = pp2[1] - pp1[1];\n    const distance = Math.sqrt(dx * dx + dy * dy);\n\n    if (distance < 1) {\n      return [[\"M\", pp1[0], pp1[1]], [\"L\", pp2[0], pp2[1]]];\n    }\n\n    // Perpendicular-port curve: leave the source and ENTER the target along the\n    // line through each node's CENTER, so each endpoint meets the edge at ~90°\n    // and the arrowhead points at the node's center. Adapts as nodes move and\n    // works for both fixed (absolute anchor) and auto-flow (relative) endpoints.\n    const norm = (vx, vy, fx, fy) => {\n      const m = Math.sqrt(vx * vx + vy * vy);\n      if (m > 0.0001) return [vx / m, vy / m];\n      const fm = Math.sqrt(fx * fx + fy * fy) || 1;\n      return [fx / fm, fy / fm];\n    };\n    // Direction the curve enters/leaves each port:\n    //  - RELATIVE endpoint (auto-flow, no anchor): aim along the line through the\n    //    node CENTER so the arrowhead points at the center (user preference #7).\n    //  - PINNED endpoint (absolute anchor, dropped at a spot): meet the edge at\n    //    90° at the pin point via the axis-aligned edge normal — so a pinned\n    //    arrow stays perpendicular to the edge where it was dropped.\n    const sDir = con.sourceAnchor\n      ? edgeNormalAt(con.source, pp1) ||\n        norm(pp1[0] - sourceCenter[0], pp1[1] - sourceCenter[1], dx, dy)\n      : norm(pp1[0] - sourceCenter[0], pp1[1] - sourceCenter[1], dx, dy);\n    const tDir = con.targetAnchor\n      ? edgeNormalAt(con.target, pp2) ||\n        norm(pp2[0] - targetCenter[0], pp2[1] - targetCenter[1], -dx, -dy)\n      : norm(pp2[0] - targetCenter[0], pp2[1] - targetCenter[1], -dx, -dy);\n    // Handle length: the \"Line Curve\" slider (lineCurviness, 0..1) scales how far\n    // the control points bow out, as a fraction of the span — so the slider is\n    // always responsive. A small floor keeps the perpendicular approach visible.\n    const curviness =\n      typeof con.lineCurviness === \"number\" ? con.lineCurviness : 0.3;\n    const handle = Math.max(20, distance * (0.12 + curviness * 0.55));\n\n    const cp1 = [pp1[0] + sDir[0] * handle, pp1[1] + sDir[1] * handle];\n    const cp2 = [pp2[0] + tDir[0] * handle, pp2[1] + tDir[1] * handle];\n\n    if (con.lineCurveType === \"quadratic\") {\n      // Quadratic bezier: a single control point (the average of the two cubic\n      // control points) gives a similar bow with one handle. Without this the\n      // Cubic/Quadratic toggle changed the model but rendered the same cubic curve.\n      const qcp = [(cp1[0] + cp2[0]) / 2, (cp1[1] + cp2[1]) / 2];\n      points = [\n        [\"M\", pp1[0], pp1[1]],\n        [\"Q\", qcp[0], qcp[1], pp2[0], pp2[1]],\n      ];\n    } else {\n      points = [\n        [\"M\", pp1[0], pp1[1]],\n        [\"C\", cp1[0], cp1[1], cp2[0], cp2[1], pp2[0], pp2[1]],\n      ];\n    }\n  } else if (con.type === \"orthogonal\") {\n    const dx = pp2[0] - pp1[0];\n    const dy = pp2[1] - pp1[1];\n\n    const sourceIsLeft = pp1[0] < sourceCenter[0];\n    const sourceIsTop = pp1[1] < sourceCenter[1];\n    const targetIsLeft = pp2[0] < targetCenter[0];\n    const targetIsTop = pp2[1] < targetCenter[1];\n\n    let midX, midY;\n\n    // Miro-clean routing: when the two anchors are nearly co-linear (small\n    // perpendicular offset), draw a straight run instead of a tiny ~22px jog.\n    // Source/target anchors carry a small inherent x/y offset even for\n    // center-aligned nodes, which otherwise reads as an ugly step. Snapping both\n    // ends to the shared mid-coordinate keeps each point on its node edge.\n    const ORTHO_SNAP = 32;\n    if (Math.abs(dx) <= ORTHO_SNAP && Math.abs(dy) > ORTHO_SNAP) {\n      const cx = (pp1[0] + pp2[0]) / 2;\n      points = [\n        [\"M\", cx, pp1[1]],\n        [\"L\", cx, pp2[1]],\n      ];\n    } else if (Math.abs(dy) <= ORTHO_SNAP && Math.abs(dx) > ORTHO_SNAP) {\n      const cy = (pp1[1] + pp2[1]) / 2;\n      points = [\n        [\"M\", pp1[0], cy],\n        [\"L\", pp2[0], cy],\n      ];\n    } else if (Math.abs(dx) > Math.abs(dy)) {\n      if ((sourceIsLeft && targetIsLeft) || (!sourceIsLeft && !targetIsLeft)) {\n        const offset = Math.max(con.curveRadius, Math.abs(dy) / 2);\n        midY = pp1[1] + (dy > 0 ? -offset : offset);\n        points = [\n          [\"M\", pp1[0], pp1[1]],\n          [\"L\", pp1[0], midY],\n          [\"L\", pp2[0], midY],\n          [\"L\", pp2[0], pp2[1]],\n        ];\n      } else {\n        midX = pp1[0] + dx / 2;\n        points = [\n          [\"M\", pp1[0], pp1[1]],\n          [\"L\", midX, pp1[1]],\n          [\"L\", midX, pp2[1]],\n          [\"L\", pp2[0], pp2[1]],\n        ];\n      }\n    } else {\n      if ((sourceIsTop && targetIsTop) || (!sourceIsTop && !targetIsTop)) {\n        const offset = Math.max(con.curveRadius, Math.abs(dx) / 2);\n        midX = pp1[0] + (dx > 0 ? -offset : offset);\n        points = [\n          [\"M\", pp1[0], pp1[1]],\n          [\"L\", midX, pp1[1]],\n          [\"L\", midX, pp2[1]],\n          [\"L\", pp2[0], pp2[1]],\n        ];\n      } else {\n        midY = pp1[1] + dy / 2;\n        points = [\n          [\"M\", pp1[0], pp1[1]],\n          [\"L\", pp1[0], midY],\n          [\"L\", pp2[0], midY],\n          [\"L\", pp2[0], pp2[1]],\n        ];\n      }\n    }\n  } else {\n    // Straight line (default)\n    points = [\n      [\"M\", pp1[0], pp1[1]],\n      [\"L\", pp2[0], pp2[1]],\n    ];\n  }\n\n  // Push the line forward to the source arrowhead's BASE. Its marker uses\n  // refX=arrowWidth, so the left-facing tip remains on the original node edge.\n  const sourceArrowWidth = con.markerSource && con.markerSource.size;\n  if (sourceArrowWidth && points && points.length >= 2) {\n    const span = Math.hypot(pp2[0] - pp1[0], pp2[1] - pp1[1]);\n    if (span > sourceArrowWidth * 1.5) {\n      const first = points[0];\n      const next = points[1];\n      const sx = first[first.length - 2];\n      const sy = first[first.length - 1];\n      let tx = next[1] - sx;\n      let ty = next[2] - sy;\n      const m = Math.hypot(tx, ty);\n      if (m > 0.001) {\n        tx /= m;\n        ty /= m;\n        first[first.length - 2] = sx + tx * sourceArrowWidth;\n        first[first.length - 1] = sy + ty * sourceArrowWidth;\n        if (next[0] === \"C\" || next[0] === \"Q\") {\n          next[1] += tx * sourceArrowWidth;\n          next[2] += ty * sourceArrowWidth;\n        }\n      }\n    }\n  }\n\n  // Pull the drawn line back to the arrowhead's BASE at the arrowed (target) end.\n  // The stroke is much thinner than the arrowhead's base but WIDER than its narrow\n  // tip, so a line drawn all the way to the tip pokes out the arrowhead's sides\n  // near the point (looks like the line doesn't conform to the arrow). Paired with\n  // the base-anchored target marker (refX=0), the arrowhead still extends forward\n  // so its TIP lands exactly on the node edge (pp2) — endpoint accuracy (#4) is\n  // preserved. Guarded to connectors long enough that the trim can't invert.\n  const aw = con.markerTarget && con.markerTarget.size;\n  if (aw && points && points.length >= 2) {\n    const span = Math.hypot(pp2[0] - pp1[0], pp2[1] - pp1[1]);\n    if (span > aw * 1.5) {\n      const last = points[points.length - 1];\n      const ex = last[last.length - 2];\n      const ey = last[last.length - 1];\n      let rx, ry;\n      if (last[0] === \"C\") {\n        rx = last[3]; // cp2\n        ry = last[4];\n      } else {\n        const prev = points[points.length - 2];\n        rx = prev[prev.length - 2];\n        ry = prev[prev.length - 1];\n      }\n      let tx = ex - rx;\n      let ty = ey - ry;\n      const m = Math.hypot(tx, ty);\n      if (m > 0.001) {\n        tx /= m;\n        ty /= m;\n        last[last.length - 2] = ex - tx * aw;\n        last[last.length - 1] = ey - ty * aw;\n        // Shift the trailing control point too so the approach tangent (and thus\n        // the arrow's aim) is unchanged.\n        if (last[0] === \"C\") {\n          last[3] -= tx * aw;\n          last[4] -= ty * aw;\n        }\n      }\n    }\n  }\n\n  return points;\n}\n\nexport {\n  calculateAngle,\n  getTangentAngle,\n  getElementCenter,\n  getClosestPointOnEdge,\n  computeConnectorCoordinates,\n  svgCoordsToLocal,\n};\n","/**\n * Marker utilities for SVG Connectable\n * Handles marker creation, management, and styling\n */\n\nimport { calculateAngle, getTangentAngle } from \"./geometry.js\";\n\n/**\n * createMarker\n * Creates a marker with proper orientation and proportional sizing\n */\nfunction createMarker(type, angle, isSource, strokeWidth, markers, color) {\n  if (!type || type === \"null\") return null;\n\n  // Scale marker size based on stroke width with better minimum sizing\n  const baseSize = 12; // Increased base marker size for thin lines\n  const markerSize = Math.max(baseSize, strokeWidth * 3 + 6); // Better scaling formula\n  const arrowWidth = markerSize;\n  const arrowHeight = markerSize * 0.8; // Slightly narrower for better proportions\n\n  const markerId =\n    (isSource ? \"source-\" : \"target-\") +\n    \"triangle-\" +\n    Math.random().toString(16).substr(2, 8);\n  const markerEl = markers.defs().marker(arrowWidth, arrowHeight);\n\n  markerEl.attr({\n    id: markerId,\n    viewBox: \"0 0 \" + arrowWidth + \" \" + arrowHeight,\n    // Both ends are BASE-anchored. Geometry trims the drawn line by one marker\n    // length, leaving the head to fill the gap to the node edge. The thin stroke\n    // therefore never runs through the triangle or blunts its point.\n    refX: isSource ? String(arrowWidth) : \"0\",\n    refY: arrowHeight / 2, // Center vertically\n    // userSpaceOnUse (was \"strokeWidth\"): with strokeWidth units the rendered\n    // marker is markerWidth × strokeWidth, but markerSize ALREADY scales with\n    // strokeWidth (strokeWidth*3+6) — so the arrowhead was double-scaled and grew\n    // ~10× the line width (a huge triangle). In user space the arrowhead is a\n    // sensible absolute size that still grows with thicker lines via markerSize,\n    // matching Miro's slim proportional heads.\n    markerUnits: \"userSpaceOnUse\",\n    markerWidth: arrowWidth, // absolute px (viewBox already 0..arrowWidth)\n    markerHeight: arrowHeight,\n    orient: \"auto\",\n  });\n\n  // Create arrow path with correct pointing direction\n  const path = markerEl.path();\n  const halfHeight = arrowHeight / 2;\n\n  if (isSource) {\n    // Source arrow points away from the line (left-pointing)\n    path.attr({\n      d:\n        \"M 0 \" +\n        halfHeight +\n        \" L \" +\n        arrowWidth +\n        \" 0 L \" +\n        arrowWidth +\n        \" \" +\n        arrowHeight +\n        \" z\",\n    });\n  } else {\n    // Target arrow points toward the target (right-pointing)\n    path.attr({\n      d:\n        \"M 0 0 L 0 \" +\n        arrowHeight +\n        \" L \" +\n        arrowWidth +\n        \" \" +\n        halfHeight +\n        \" z\",\n    });\n  }\n\n  path.fill(color);\n\n  return {\n    element: markerEl,\n    id: markerId,\n    size: markerSize,\n  };\n}\n\n/**\n * setMarker\n * The function that sets the markers\n *\n * @name setMarker\n * @function\n * @param {Connectable} con The connectable instance\n * @param {String} sourceMarker 'default' / 'null' for source end\n * @param {String} targetMarker 'default' / 'null' for target end\n * @param {SVGElement} markersContainer Optional parent for marker elements\n * @return {Connectable} The connectable instance.\n */\nfunction setMarker(con, sourceMarker, targetMarker, markersContainer) {\n  if (markersContainer) con.markers = markersContainer;\n\n  // Keep the marker configuration authoritative. Width changes rebuild marker\n  // elements from these fields, so stale values could otherwise bring back an\n  // arrowhead that an independent endpoint toggle had just removed.\n  con.markerSourceType = sourceMarker || \"null\";\n  con.markerTargetType = targetMarker || \"null\";\n\n  // Clean up existing markers\n  if (con.markerSource) {\n    con.markerSource.element.remove();\n    con.connector.attr(\"marker-start\", null);\n  }\n  if (con.markerTarget) {\n    con.markerTarget.element.remove();\n    con.connector.attr(\"marker-end\", null);\n  }\n\n  // Set source marker\n  if (sourceMarker && sourceMarker !== \"null\") {\n    con.markerSource = createMarker(\n      sourceMarker,\n      0,\n      true,\n      con.strokeWidth,\n      con.markers || markersContainer,\n      con.color\n    );\n    con.connector.attr(\"marker-start\", \"url(#\" + con.markerSource.id + \")\");\n  } else {\n    con.markerSource = null;\n  }\n\n  // Set target marker\n  if (targetMarker && targetMarker !== \"null\") {\n    con.markerTarget = createMarker(\n      targetMarker,\n      0,\n      false,\n      con.strokeWidth,\n      con.markers || markersContainer,\n      con.color\n    );\n    con.connector.attr(\"marker-end\", \"url(#\" + con.markerTarget.id + \")\");\n  } else {\n    con.markerTarget = null;\n  }\n\n  return con;\n}\n\n/**\n * setMarkerSettings\n * Updates marker settings for source and target\n *\n * @name setMarkerSettings\n * @function\n * @param {Connectable} con The connectable instance\n * @param {String} sourceMarker Marker type for source end\n * @param {String} targetMarker Marker type for target end\n * @return {Connectable} The connectable instance.\n */\nfunction setMarkerSettings(con, sourceMarker, targetMarker) {\n  con.markerSourceType = sourceMarker || \"null\";\n  con.markerTargetType = targetMarker || \"null\";\n  setMarker(con, con.markerSourceType, con.markerTargetType);\n  return con;\n}\n\n/**\n * setStrokeWidth\n * Updates the stroke width and recreates markers with proper scaling\n *\n * @name setStrokeWidth\n * @function\n * @param {Connectable} con The connectable instance\n * @param {Number} width The new stroke width\n * @return {Connectable} The connectable instance.\n */\nfunction setStrokeWidth(con, width) {\n  con.strokeWidth = width || 2;\n  con.connector.attr(\"stroke-width\", con.strokeWidth);\n  // Recreate markers with new scaling\n  setMarker(con, con.markerSourceType, con.markerTargetType);\n  return con;\n}\n\n/**\n * setConnectorColor\n * Sets the connector color and updates markers\n *\n * @name setConnectorColor\n * @function\n * @param {Connectable} con The connectable instance\n * @param {String} color The new color.\n * @return {undefined}\n */\nfunction setConnectorColor(con, color) {\n  con.color = color;\n  con.connector.stroke(color).attr(\"stroke-width\", con.strokeWidth);\n  if (con.markerSource) {\n    con.markerSource.element.children().forEach(function (child) {\n      if (child.type === \"path\") child.fill(color);\n    });\n  }\n  if (con.markerTarget) {\n    con.markerTarget.element.children().forEach(function (child) {\n      if (child.type === \"path\") child.fill(color);\n    });\n  }\n}\n\nexport {\n  createMarker,\n  setMarker,\n  setMarkerSettings,\n  setStrokeWidth,\n  setConnectorColor,\n};\n","/**\n * Handle utilities for SVG Connectable\n * Handles draggable handle creation, drag/drop operations, and drop target detection\n */\n\nimport { getElementCenter } from \"./geometry.js\";\nimport { computeConnectorCoordinates } from \"./geometry.js\";\nimport { svgCoordsToLocal } from \"./geometry.js\";\n\n/**\n * Normalized [0,1] anchor for a world point on a node, snapped to the nearest\n * edge — the same mapping the host uses when it commits a drop-to-pin, so the\n * live drag PREVIEW matches where the endpoint will actually land.\n */\nfunction snappedAnchorForDrop(node, worldPos) {\n  try {\n    const [lx, ly] = svgCoordsToLocal(node, worldPos[0], worldPos[1]);\n    const bb = node.bbox();\n    if (!bb || !bb.width || !bb.height) return null;\n    let ax = Math.max(0, Math.min(1, (lx - bb.x) / bb.width));\n    let ay = Math.max(0, Math.min(1, (ly - bb.y) / bb.height));\n    const dl = ax, dr = 1 - ax, dt = ay, db = 1 - ay;\n    const m = Math.min(dl, dr, dt, db);\n    if (m === dl) ax = 0;\n    else if (m === dr) ax = 1;\n    else if (m === dt) ay = 0;\n    else ay = 1;\n    return { x: ax, y: ay };\n  } catch (e) {\n    return null;\n  }\n}\n\n/**\n * Helper function to check if a plugin method is available\n */\nfunction hasMethod(element, methodName) {\n  return element && typeof element[methodName] === \"function\";\n}\n\n/**\n * createHandle\n * Creates a draggable handle circle at a connector endpoint\n *\n * @name createHandle\n * @function\n * @param {Connectable} con The connectable instance\n * @param {Boolean} isSource Whether this is a source handle (true) or target handle (false)\n * @param {Array} position Initial position [x, y]\n * @return {Object} Handle object with element and metadata\n */\nfunction createHandle(con, isSource, position) {\n  if (!con.showHandles) return null;\n\n  const handle = con.container\n    .circle(con.handleRadius * 2)\n    .attr({\n      cx: position[0],\n      cy: position[1],\n      fill: con.handleFill,\n      stroke: con.handleStroke,\n      \"stroke-width\": con.handleStrokeWidth,\n      \"pointer-events\": \"all\",\n    })\n    .addClass(\"connector-handle\")\n    .addClass(isSource ? \"connector-handle-source\" : \"connector-handle-target\");\n\n  // Set cursor for handle\n  try {\n    handle.node.style.cursor = \"grab\";\n  } catch (e) {\n    handle.node.setAttribute(\"style\", \"cursor: grab\");\n  }\n\n  const handleObj = {\n    element: handle,\n    isSource: isSource,\n    position: position,\n    isDetached: false,\n    originalTarget: isSource ? con.source : con.target,\n  };\n\n  // Make handle draggable\n  setupHandleDrag(con, handleObj);\n\n  return handleObj;\n}\n\n/**\n * setupHandleDrag\n * Sets up drag functionality for a handle using SVG.js draggable plugin\n *\n * @name setupHandleDrag\n * @function\n * @param {Connectable} con The connectable instance\n * @param {Object} handleObj The handle object to make draggable\n */\nfunction setupHandleDrag(con, handleObj) {\n  let dragTarget = null;\n  let startPosition = [0, 0];\n\n  // Check if draggable plugin is available\n  if (!hasMethod(handleObj.element, \"draggable\")) {\n    console.warn(\n      \"svg.draggable.js plugin not available for connector handles. Install @svgdotjs/svg.draggable.js for proper drag functionality.\"\n    );\n    return;\n  }\n\n  // Make the handle draggable using SVG.js plugin\n  handleObj.element.draggable();\n\n  // Set up drag event handlers\n  handleObj.element\n    .on(\"beforedrag\", function (event) {\n      // Store starting position\n      startPosition = [handleObj.element.cx(), handleObj.element.cy()];\n\n      // Change cursor to grabbing\n      try {\n        handleObj.element.node.style.cursor = \"grabbing\";\n      } catch (ex) {\n        handleObj.element.node.setAttribute(\"style\", \"cursor: grabbing\");\n      }\n\n      // Bring handle to front\n      handleObj.element.front();\n\n      // Detach handle from its current connection\n      detachHandle(con, handleObj);\n    })\n    .on(\"dragmove\", function (event) {\n      // Get current handle position (SVG.js draggable plugin handles coordinate transformation)\n      const currentPos = [handleObj.element.cx(), handleObj.element.cy()];\n      handleObj.position = currentPos;\n\n      // Resolve the drop target FIRST so the live preview can render the actual\n      // pinned/edge layout it would have if dropped here (not a raw line to the\n      // pointer). Then update the connector using that target.\n      const mouseEvent = event.detail.event;\n      dragTarget = findDropTarget(con, mouseEvent, handleObj);\n      highlightDropTarget(dragTarget);\n\n      updateConnectorForDrag(con, handleObj, currentPos, dragTarget);\n    })\n    .on(\"dragend\", function (event) {\n      // Reset cursor\n      try {\n        handleObj.element.node.style.cursor = \"grab\";\n      } catch (ex) {\n        handleObj.element.node.setAttribute(\"style\", \"cursor: grab\");\n      }\n\n      // Clean up debug visualizations\n      if (con.debugMode) {\n        clearHitZoneVisualizations(con.container);\n      }\n\n      // Handle drop\n      if (dragTarget) {\n        attachHandleToTarget(con, handleObj, dragTarget);\n        clearDropTargetHighlight();\n      } else {\n        // Dropped on canvas - create phantom rect at drop location\n        const dropPosition = [handleObj.element.cx(), handleObj.element.cy()];\n        const phantomRect = createPhantomRect(con, dropPosition);\n\n        // Track phantom rect on connector for cleanup\n        if (handleObj.isSource) {\n          con._sourcePhantomRect = phantomRect;\n        } else {\n          con._targetPhantomRect = phantomRect;\n        }\n\n        // Attach handle to the phantom rect\n        attachHandleToTarget(con, handleObj, phantomRect);\n      }\n\n      dragTarget = null;\n    });\n}\n\n/**\n * detachHandle\n * Detaches a handle from its current target, making the connector floating\n *\n * @name detachHandle\n * @function\n * @param {Connectable} con The connectable instance\n * @param {Object} handleObj The handle object to detach\n */\nfunction detachHandle(con, handleObj) {\n  handleObj.isDetached = true;\n\n  // Store the original target for potential reconnection\n  if (!handleObj.originalTarget) {\n    handleObj.originalTarget = handleObj.isSource ? con.source : con.target;\n  }\n\n  // Store the original line type to preserve it during drag\n  if (!handleObj.originalType) {\n    handleObj.originalType = con.type;\n  }\n\n  // Clean up phantom rects if the current target is a phantom\n  const currentTarget = handleObj.isSource ? con.source : con.target;\n  if (currentTarget && currentTarget._isPhantomRect) {\n    currentTarget.remove();\n\n    // Clear phantom rect reference\n    if (handleObj.isSource) {\n      con._sourcePhantomRect = null;\n    } else {\n      con._targetPhantomRect = null;\n    }\n  }\n\n  // The connector will now have one floating end\n  if (handleObj.isSource) {\n    con.source = null; // Source is now floating\n  } else {\n    con.target = null; // Target is now floating\n  }\n}\n\n/**\n * updateConnectorForDrag\n * Updates the connector path while a handle is being dragged\n *\n * @name updateConnectorForDrag\n * @function\n * @param {Connectable} con The connectable instance\n * @param {Object} handleObj The handle being dragged\n * @param {Array} position Current drag position [x, y]\n */\nfunction updateConnectorForDrag(con, handleObj, position, dropTarget) {\n  // Use the preserved line type from when the handle was detached\n  const lineType = handleObj.originalType || con.type;\n\n  // Over a real drop target → preview the ACTUAL pinned layout (endpoint snapped\n  // to the nearest edge, arrow perpendicular) instead of a raw line to the\n  // pointer, so the drag conforms to where it will land. Guarded to real nodes\n  // (has bbox), never phantom/handle elements.\n  let previewNode = null;\n  let previewAnchor = null;\n  if (\n    dropTarget &&\n    typeof dropTarget.bbox === \"function\" &&\n    !dropTarget._isPhantomRect &&\n    !(dropTarget.hasClass && dropTarget.hasClass(\"connector-handle\"))\n  ) {\n    previewAnchor = snappedAnchorForDrop(dropTarget, position);\n    if (previewAnchor) previewNode = dropTarget;\n  }\n\n  // Create a mock element to represent the floating endpoint\n  const mockElement = {\n    bbox: function () {\n      return {\n        x: position[0] - 5,\n        y: position[1] - 5,\n        width: 10,\n        height: 10,\n        cx: position[0],\n        cy: position[1],\n      };\n    },\n    node: {\n      getCTM: function () {\n        return { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 };\n      },\n    },\n  };\n\n  // Temporarily store original values\n  const originalSource = con.source;\n  const originalTarget = con.target;\n  const originalType = con.type;\n  const originalSourceAnchor = con.sourceAnchor;\n  const originalTargetAnchor = con.targetAnchor;\n\n  try {\n    // Set up temporary connector state for path calculation\n    con.type = lineType;\n\n    if (handleObj.isSource) {\n      // Source handle is being dragged\n      if (previewNode) {\n        // Preview the pinned layout on the hovered node.\n        con.source = previewNode;\n        con.sourceAnchor = previewAnchor;\n      } else {\n        con.source = mockElement;\n        con.sourceAnchor = null;\n      }\n      if (!con.target) {\n        // Both ends floating - create a simple target for calculation\n        con.target = {\n          bbox: function () {\n            return {\n              x: position[0] + 45,\n              y: position[1] - 5,\n              width: 10,\n              height: 10,\n              cx: position[0] + 50,\n              cy: position[1],\n            };\n          },\n          node: {\n            getCTM: function () {\n              return { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 };\n            },\n          },\n        };\n      }\n    } else {\n      // Target handle is being dragged\n      if (previewNode) {\n        // Preview the pinned layout on the hovered node.\n        con.target = previewNode;\n        con.targetAnchor = previewAnchor;\n      } else {\n        con.target = mockElement;\n        con.targetAnchor = null;\n      }\n      if (!con.source) {\n        // Both ends floating - create a simple source for calculation\n        con.source = {\n          bbox: function () {\n            return {\n              x: position[0] - 55,\n              y: position[1] - 5,\n              width: 10,\n              height: 10,\n              cx: position[0] - 50,\n              cy: position[1],\n            };\n          },\n          node: {\n            getCTM: function () {\n              return { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 };\n            },\n          },\n        };\n      }\n    }\n\n    // Use the existing path calculation logic\n    const pathData = computeConnectorCoordinates(con);\n\n    // Update connector and hit area\n    con.connector.plot(pathData);\n    con.hitArea.plot(pathData);\n  } finally {\n    // Restore original values (incl. anchors — the preview must never leak into\n    // the committed connection; the real pin is set on dragend by the host).\n    con.source = originalSource;\n    con.target = originalTarget;\n    con.type = originalType;\n    con.sourceAnchor = originalSourceAnchor;\n    con.targetAnchor = originalTargetAnchor;\n  }\n}\n\n/**\n * isPointInElement\n * Checks if a point is inside an element, accounting for transformations\n *\n * @name isPointInElement\n * @function\n * @param {SVGElement} element The element to test\n * @param {Array} point The point [x, y] in SVG coordinates\n * @param {Boolean} debugMode Whether to show debug visualization\n * @return {Boolean} True if point is inside element\n */\nfunction isPointInElement(element, point, debugMode = false) {\n  try {\n    // Get the element's CTM and bounding box\n    const ctm = element.node.getCTM();\n    const bbox = element.bbox();\n\n    if (debugMode) {\n      console.log(\"Hit test debug:\", {\n        element: element.type,\n        point: point,\n        bbox: bbox,\n        ctm: ctm,\n      });\n    }\n\n    // Convert point from world coordinates to element's local coordinates\n    const det = ctm.a * ctm.d - ctm.b * ctm.c;\n    if (Math.abs(det) < 1e-10) {\n      // Singular matrix, fallback to simple bbox test\n      if (debugMode) {\n        console.log(\"Using fallback bbox test due to singular matrix\");\n      }\n      return (\n        point[0] >= bbox.x &&\n        point[0] <= bbox.x + bbox.width &&\n        point[1] >= bbox.y &&\n        point[1] <= bbox.y + bbox.height\n      );\n    }\n\n    // Inverse transformation\n    const invA = ctm.d / det;\n    const invB = -ctm.b / det;\n    const invC = -ctm.c / det;\n    const invD = ctm.a / det;\n    const invE = (ctm.c * ctm.f - ctm.d * ctm.e) / det;\n    const invF = (ctm.b * ctm.e - ctm.a * ctm.f) / det;\n\n    // Transform point to local coordinates\n    const localX = invA * point[0] + invC * point[1] + invE;\n    const localY = invB * point[0] + invD * point[1] + invF;\n\n    if (debugMode) {\n      console.log(\"Local coordinates:\", { localX, localY });\n    }\n\n    let result = false;\n\n    // Test against local bounding box\n    if (element.type === \"circle\") {\n      const cx = parseFloat(element.attr(\"cx\")) || bbox.cx;\n      const cy = parseFloat(element.attr(\"cy\")) || bbox.cy;\n      const r = parseFloat(element.attr(\"r\")) || 0;\n      const dx = localX - cx;\n      const dy = localY - cy;\n      result = dx * dx + dy * dy <= r * r;\n      if (debugMode) {\n        console.log(\"Circle test:\", {\n          cx,\n          cy,\n          r,\n          dx,\n          dy,\n          distance: Math.sqrt(dx * dx + dy * dy),\n          result,\n        });\n      }\n    } else if (element.type === \"ellipse\") {\n      const cx = parseFloat(element.attr(\"cx\")) || bbox.cx;\n      const cy = parseFloat(element.attr(\"cy\")) || bbox.cy;\n      const rx = parseFloat(element.attr(\"rx\")) || 0;\n      const ry = parseFloat(element.attr(\"ry\")) || 0;\n      const dx = localX - cx;\n      const dy = localY - cy;\n      result = (dx * dx) / (rx * rx) + (dy * dy) / (ry * ry) <= 1;\n      if (debugMode) {\n        console.log(\"Ellipse test:\", { cx, cy, rx, ry, dx, dy, result });\n      }\n    } else {\n      // For rectangles and other shapes, test against local bounding box\n      result =\n        localX >= bbox.x &&\n        localX <= bbox.x + bbox.width &&\n        localY >= bbox.y &&\n        localY <= bbox.y + bbox.height;\n      if (debugMode) {\n        console.log(\"Rect test:\", {\n          localX,\n          localY,\n          bboxX: bbox.x,\n          bboxY: bbox.y,\n          bboxWidth: bbox.width,\n          bboxHeight: bbox.height,\n          result,\n        });\n      }\n    }\n\n    return result;\n  } catch (e) {\n    // Fallback to simple bbox test if anything fails\n    if (debugMode) {\n      console.log(\"Exception in hit test, using fallback:\", e);\n    }\n    const bbox = element.bbox();\n    return (\n      point[0] >= bbox.x &&\n      point[0] <= bbox.x + bbox.width &&\n      point[1] >= bbox.y &&\n      point[1] <= bbox.y + bbox.height\n    );\n  }\n}\n\n/**\n * visualizeHitZone\n * Creates debug visualization for element hit zones\n *\n * @name visualizeHitZone\n * @function\n * @param {SVGElement} element The element to visualize\n * @param {SVGElement} container The container to add debug elements to\n * @return {SVGElement} Debug visualization element\n */\nfunction visualizeHitZone(element, container) {\n  try {\n    const bbox = element.bbox();\n    const ctm = element.node.getCTM();\n\n    // Create debug group\n    const debugGroup = container.group().addClass(\"debug-hit-zone\");\n\n    // Show original bounding box in light red\n    const originalBox = debugGroup.rect(bbox.width, bbox.height).attr({\n      x: bbox.x,\n      y: bbox.y,\n      fill: \"none\",\n      stroke: \"#ffcccc\",\n      \"stroke-width\": 1,\n      \"stroke-dasharray\": \"2,2\",\n    });\n\n    // Show transformed bounding box in bright red\n    if (ctm) {\n      // Transform the four corners of the bounding box\n      const corners = [\n        [bbox.x, bbox.y],\n        [bbox.x + bbox.width, bbox.y],\n        [bbox.x + bbox.width, bbox.y + bbox.height],\n        [bbox.x, bbox.y + bbox.height],\n      ];\n\n      const transformedCorners = corners.map((corner) => [\n        ctm.a * corner[0] + ctm.c * corner[1] + ctm.e,\n        ctm.b * corner[0] + ctm.d * corner[1] + ctm.f,\n      ]);\n\n      // Create polygon showing actual hit zone\n      const pathData =\n        transformedCorners\n          .map(\n            (corner, i) => (i === 0 ? \"M\" : \"L\") + corner[0] + \",\" + corner[1]\n          )\n          .join(\" \") + \" Z\";\n\n      debugGroup.path(pathData).attr({\n        fill: \"rgba(255, 0, 0, 0.1)\",\n        stroke: \"#ff0000\",\n        \"stroke-width\": 2,\n        \"stroke-dasharray\": \"5,3\",\n      });\n    }\n\n    // Add center point\n    let centerX, centerY;\n    try {\n      centerX = ctm.a * bbox.cx + ctm.c * bbox.cy + ctm.e;\n      centerY = ctm.b * bbox.cx + ctm.d * bbox.cy + ctm.f;\n    } catch (e) {\n      centerX = bbox.cx;\n      centerY = bbox.cy;\n    }\n\n    debugGroup.circle(4).attr({\n      cx: centerX,\n      cy: centerY,\n      fill: \"#ff0000\",\n    });\n\n    return debugGroup;\n  } catch (e) {\n    console.warn(\"Error creating hit zone visualization:\", e);\n    return null;\n  }\n}\n\n/**\n * clearHitZoneVisualizations\n * Removes all debug hit zone visualizations\n *\n * @name clearHitZoneVisualizations\n * @function\n * @param {SVGElement} container The container to clear debug elements from\n */\nfunction clearHitZoneVisualizations(container) {\n  try {\n    const debugElements = container.find(\".debug-hit-zone\");\n    debugElements.forEach((el) => el.remove());\n  } catch (e) {\n    console.warn(\"Error clearing hit zone visualizations:\", e);\n  }\n}\n\n/**\n * findDropTarget\n * Finds a valid drop target under the mouse cursor\n *\n * @name findDropTarget\n * @function\n * @param {Connectable} con The connectable instance\n * @param {Event} e Mouse event\n * @param {Object} handleObj The handle being dragged\n * @return {SVGElement|null} Valid drop target or null\n */\nfunction findDropTarget(con, e, handleObj) {\n  const debugMode = con.debugMode || false;\n\n  // Clear previous debug visualizations if in debug mode\n  if (debugMode) {\n    clearHitZoneVisualizations(con.container);\n  }\n\n  // Find all actual target shapes in the entire SVG by their characteristics\n  function findTargetShapes(container) {\n    const shapes = [];\n\n    function searchRecursively(element) {\n      // Check if this element is a target shape\n      if (isTargetShape(element)) {\n        shapes.push(element);\n      }\n\n      // Recursively search children (for groups, etc.)\n      if (element.children && typeof element.children === \"function\") {\n        element.children().forEach(searchRecursively);\n      }\n    }\n\n    searchRecursively(container);\n    return shapes;\n  }\n\n  // Determine what makes a shape a valid drop target\n  function isTargetShape(element) {\n    // Must be a shape element\n    const validShapeTypes = [\"circle\", \"rect\", \"ellipse\", \"polygon\", \"path\"];\n    if (!validShapeTypes.includes(element.type)) {\n      return false;\n    }\n\n    // Must not be a connector element\n    if (element.attr(\"connectortype\")) {\n      return false;\n    }\n\n    // Must not be a connector handle\n    if (element.hasClass && element.hasClass(\"connector-handle\")) {\n      return false;\n    }\n\n    // Must not be a phantom rect\n    if (element._isPhantomRect) {\n      return false;\n    }\n\n    // Must not be debug visualization elements\n    if (element.hasClass && element.hasClass(\"debug-hit-zone\")) {\n      return false;\n    }\n\n    // Exclude plugin UI elements - check for common plugin class patterns\n    if (element.hasClass) {\n      const classList = element.node.classList;\n      if (classList) {\n        // svg.select.js plugin elements\n        if (\n          classList.contains(\"svg_select_boundingRect\") ||\n          classList.contains(\"svg_select_points\") ||\n          classList.contains(\"svg_select_selector\")\n        ) {\n          return false;\n        }\n\n        // svg.resize.js plugin elements\n        if (\n          classList.contains(\"svg_resize_rotationPoint\") ||\n          classList.contains(\"svg_resize_handle\") ||\n          classList.contains(\"svg_resize_point\")\n        ) {\n          return false;\n        }\n\n        // General plugin indicators\n        if (\n          classList.contains(\"svg_draggable_handle\") ||\n          classList.contains(\"plugin-ui\") ||\n          classList.contains(\"ui-element\")\n        ) {\n          return false;\n        }\n      }\n    }\n\n    // Exclude very small elements (likely handles) - reasonable minimum size for user shapes\n    const bbox = element.bbox();\n    if (bbox.width < 10 || bbox.height < 10) {\n      return false;\n    }\n\n    // Exclude elements with cursor styles that indicate UI elements. NOTE: do\n    // NOT exclude cursor:\"move\" — node shapes are draggable and legitimately use\n    // it (Miro-style affordance); excluding it made nodes invisible to endpoint\n    // drop detection so reconnecting onto a node failed. Only the resize/crosshair\n    // cursors mark true plugin handles.\n    try {\n      const computedStyle = window.getComputedStyle(element.node);\n      const cursor = computedStyle.cursor;\n      if (\n        cursor === \"nw-resize\" ||\n        cursor === \"ne-resize\" ||\n        cursor === \"sw-resize\" ||\n        cursor === \"se-resize\" ||\n        cursor === \"ew-resize\" ||\n        cursor === \"ns-resize\" ||\n        cursor === \"crosshair\"\n      ) {\n        return false;\n      }\n    } catch (e) {\n      // Ignore if style checking fails\n    }\n\n    // Check for data attributes that indicate plugin elements\n    const dataAttrs = element.node.dataset;\n    if (dataAttrs) {\n      if (\n        dataAttrs.svgjs ||\n        dataAttrs.plugin ||\n        dataAttrs.handle ||\n        dataAttrs.ui\n      ) {\n        return false;\n      }\n    }\n\n    // Check if element is in a plugin-specific parent group\n    let parent = element.parent();\n    while (parent && parent.type !== \"svg\") {\n      if (parent.hasClass) {\n        const parentClasses = parent.node.classList;\n        if (\n          parentClasses &&\n          (parentClasses.contains(\"svg_select_group\") ||\n            parentClasses.contains(\"svg_resize_group\") ||\n            parentClasses.contains(\"plugin-ui-group\"))\n        ) {\n          return false;\n        }\n      }\n      // Check for plugin-specific ID patterns on parent\n      const parentId = parent.attr(\"id\");\n      if (\n        parentId &&\n        (parentId.includes(\"_select_\") ||\n          parentId.includes(\"_resize_\") ||\n          parentId.includes(\"plugin\"))\n      ) {\n        return false;\n      }\n      parent = parent.parent();\n    }\n\n    // Check for specific ID patterns that suggest plugin elements\n    const elementId = element.attr(\"id\");\n    if (\n      elementId &&\n      (elementId.includes(\"_select_\") ||\n        elementId.includes(\"_resize_\") ||\n        elementId.includes(\"_handle_\") ||\n        elementId.includes(\"_rotation_\") ||\n        elementId.includes(\"plugin\") ||\n        elementId.startsWith(\"svg_\"))\n    ) {\n      return false;\n    }\n\n    // Additional filtering - target shapes likely have fills or strokes\n    const fill = element.attr(\"fill\");\n    const stroke = element.attr(\"stroke\");\n    if (!fill && !stroke) {\n      return false; // Probably not a visible target shape\n    }\n\n    // Exclude elements with transparent or very light fills (often UI elements)\n    if (fill === \"transparent\" || fill === \"none\") {\n      // Only allow if it has a visible stroke\n      if (!stroke || stroke === \"none\" || stroke === \"transparent\") {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  // Get the root SVG container\n  const rootSvg = con.container.root();\n\n  // Calculate mouse coordinates relative to the root SVG\n  const svgRect = rootSvg.node.getBoundingClientRect();\n  const svgX = e.clientX - svgRect.left;\n  const svgY = e.clientY - svgRect.top;\n\n  if (debugMode) {\n    console.log(\"Drop target search at:\", { svgX, svgY });\n  }\n\n  // Find all target shapes\n  const targetShapes = findTargetShapes(rootSvg);\n\n  if (debugMode) {\n    console.log(\"Found target shapes:\", targetShapes.length);\n    targetShapes.forEach((element, index) => {\n      console.log(`Target shape ${index}:`, {\n        type: element.type,\n        id: element.attr(\"id\"),\n        classes: element.node.classList\n          ? Array.from(element.node.classList)\n          : [],\n        fill: element.attr(\"fill\"),\n        stroke: element.attr(\"stroke\"),\n        bbox: element.bbox(),\n        isValid: isValidDropTarget(con, element, handleObj),\n      });\n    });\n\n    // Show hit zones for all valid target shapes\n    targetShapes.forEach((element) => {\n      if (isValidDropTarget(con, element, handleObj)) {\n        visualizeHitZone(element, con.container);\n      }\n    });\n  }\n\n  // Check which target shapes contain the mouse point\n  const candidates = [];\n\n  targetShapes.forEach(function (element) {\n    if (isValidDropTarget(con, element, handleObj)) {\n      try {\n        // Use CTM-aware hit testing for accurate detection on rotated elements\n        const hitResult = isPointInElement(element, [svgX, svgY], debugMode);\n\n        if (hitResult) {\n          // Calculate distance to center for priority (closest wins)\n          // Use CTM-aware center calculation\n          let centerX, centerY;\n          try {\n            const bbox = element.bbox();\n            const ctm = element.node.getCTM();\n            centerX = ctm.a * bbox.cx + ctm.c * bbox.cy + ctm.e;\n            centerY = ctm.b * bbox.cx + ctm.d * bbox.cy + ctm.f;\n          } catch (e) {\n            const bbox = element.bbox();\n            centerX = bbox.cx;\n            centerY = bbox.cy;\n          }\n\n          const distance = Math.sqrt(\n            Math.pow(svgX - centerX, 2) + Math.pow(svgY - centerY, 2)\n          );\n\n          if (debugMode) {\n            console.log(\"Found candidate:\", {\n              element: element.type,\n              distance,\n            });\n          }\n\n          candidates.push({ element: element, distance: distance });\n        }\n      } catch (ex) {\n        // Skip elements that cause errors\n        console.warn(\"Error checking element for drop target:\", ex);\n      }\n    }\n  });\n\n  // Return the closest candidate if any\n  if (candidates.length > 0) {\n    candidates.sort(function (a, b) {\n      return a.distance - b.distance;\n    });\n    if (debugMode) {\n      console.log(\"Selected closest candidate:\", candidates[0]);\n    }\n    return candidates[0].element;\n  }\n\n  if (debugMode) {\n    console.log(\"No drop target found\");\n  }\n  return null;\n}\n\n/**\n * isValidDropTarget\n * Checks if an element is a valid drop target for a handle\n *\n * @name isValidDropTarget\n * @function\n * @param {Connectable} con The connectable instance\n * @param {SVGElement} element The potential target element\n * @param {Object} handleObj The handle being dragged\n * @return {Boolean} True if valid drop target\n */\nfunction isValidDropTarget(con, element, handleObj) {\n  // Dropping back on the endpoint's OWN current node is ALLOWED — that is how you\n  // reposition a pinned endpoint along its node's edge (handleEndpointChange re-pins it\n  // via pinDropAnchor). Excluding the current target here made the node invisible to the\n  // drop hit-test, so a same-node reposition fell through to a canvas drop: the endpoint\n  // detached into a free-floating point (straight line, no longer followed the node) and\n  // the same-node re-pin path was effectively unreachable.\n\n  // A drop target must be part of an ACTUAL NODE (have a data-node-id ancestor). Without\n  // this, valid-looking shapes that are NOT nodes — the node's connection-plug dots\n  // (circles), connector arrowheads (polygons), birdseye/minimap shapes — matched the hit\n  // test; dropping on one derived a null targetNodeId → the endpoint went free-floating and\n  // flew off to a stale coordinate. Requiring a node id also stops endpoints snapping to the\n  // four plug-dot icons.\n  try {\n    let nel = element.node;\n    while (nel && nel.getAttribute && !nel.getAttribute(\"data-node-id\")) {\n      nel = nel.parentNode;\n    }\n    if (!(nel && nel.getAttribute && nel.getAttribute(\"data-node-id\"))) {\n      return false;\n    }\n  } catch (e) {\n    return false;\n  }\n\n  // Don't allow dropping on connector elements themselves\n  if (element.attr(\"connectortype\")) return false;\n\n  // Don't allow dropping on handles\n  if (element.hasClass && element.hasClass(\"connector-handle\")) return false;\n\n  // Don't allow dropping on phantom rects\n  if (element._isPhantomRect) return false;\n\n  // Don't allow connecting to the other end of the same connector\n  const otherTarget = handleObj.isSource ? con.target : con.source;\n  if (element === otherTarget) return false;\n\n  return true;\n}\n\n/**\n * attachHandleToTarget\n * Attaches a handle to a new target element\n *\n * @name attachHandleToTarget\n * @function\n * @param {Connectable} con The connectable instance\n * @param {Object} handleObj The handle to attach\n * @param {SVGElement} target The target element to attach to\n */\nfunction attachHandleToTarget(con, handleObj, target) {\n  // Capture the actual DROP POINT (the handle's position at release, in world\n  // coords) BEFORE any snap/reposition, so the model can attach the connection\n  // exactly where the user dropped rather than at the target's center.\n  let dropPoint = null;\n  try {\n    dropPoint = { x: handleObj.element.cx(), y: handleObj.element.cy() };\n  } catch (e) {\n    /* noop */\n  }\n\n  // Store old target for event cleanup\n  const oldTarget = handleObj.isSource ? con.source : con.target;\n\n  // Clean up phantom rect if oldTarget was a phantom\n  if (oldTarget && oldTarget._isPhantomRect) {\n    oldTarget.remove();\n\n    // Clear phantom rect reference\n    if (handleObj.isSource) {\n      con._sourcePhantomRect = null;\n    } else {\n      con._targetPhantomRect = null;\n    }\n  }\n\n  // Reattach the handle to the new target\n  if (handleObj.isSource) {\n    con.source = target;\n  } else {\n    con.target = target;\n  }\n\n  handleObj.isDetached = false;\n\n  // Update connector arrays and event listeners\n  // Handle both floating handle attachment (oldTarget = null) and reattachment (oldTarget != target)\n  if (!oldTarget || oldTarget !== target) {\n    // Create the correct update function based on which handle is being reattached\n    let updateFunction;\n    if (handleObj.isSource) {\n      updateFunction = function (event) {\n        con.update();\n      };\n    } else {\n      updateFunction = function (event) {\n        con.update();\n      };\n    }\n\n    // Get the stored update function for proper removal\n    const storedFunctionKey = handleObj.isSource\n      ? \"_sourceUpdateFunction\"\n      : \"_targetUpdateFunction\";\n    const oldUpdateFunction = con[storedFunctionKey];\n\n    // Remove old event listeners if we have the function reference\n    if (oldUpdateFunction && oldTarget) {\n      oldTarget.off(\"dragmove\", oldUpdateFunction);\n      oldTarget.off(\"beforedrag\", oldUpdateFunction);\n      oldTarget.off(\"dragstart\", oldUpdateFunction);\n      oldTarget.off(\"dragend\", oldUpdateFunction);\n      oldTarget.off(\"resize\", oldUpdateFunction);\n      oldTarget.off(\"rotate\", oldUpdateFunction);\n      oldTarget.off(\"transform\", oldUpdateFunction);\n    }\n\n    // Update cons arrays - remove connector from old element, add to new element\n    if (handleObj.isSource) {\n      // For source reattachment, manage the main cons array\n      if (oldTarget && oldTarget.cons) {\n        const index = oldTarget.cons.indexOf(con);\n        if (index > -1) {\n          oldTarget.cons.splice(index, 1);\n        }\n      }\n      // Add to new source element's cons array\n      target.cons = target.cons || [];\n      if (target.cons.indexOf(con) === -1) {\n        target.cons.push(con);\n      }\n    } else {\n      // For target reattachment, ensure the target has connector tracking\n      // Remove from old target's connector tracking if it exists\n      if (oldTarget && oldTarget.targetCons) {\n        const index = oldTarget.targetCons.indexOf(con);\n        if (index > -1) {\n          oldTarget.targetCons.splice(index, 1);\n        }\n      }\n      // Add to new target element's tracking\n      target.targetCons = target.targetCons || [];\n      if (target.targetCons.indexOf(con) === -1) {\n        target.targetCons.push(con);\n      }\n    }\n\n    // Store the new update function on the connector for future removal\n    con[storedFunctionKey] = updateFunction;\n\n    // Add new event listeners to the new target - ONLY the correct function type\n    target.on(\"dragmove\", updateFunction);\n    target.on(\"beforedrag\", updateFunction);\n    target.on(\"dragstart\", updateFunction);\n    target.on(\"dragend\", updateFunction);\n    target.on(\"resize\", updateFunction);\n    target.on(\"rotate\", updateFunction);\n    target.on(\"transform\", updateFunction);\n  }\n\n  // Update the connector to use proper path calculation\n  con.update();\n\n  // Move the handle to the proper position on the target's edge\n  if (con.source && con.target) {\n    const pathData = computeConnectorCoordinates(con);\n    if (pathData && pathData.length >= 2) {\n      let newPosition;\n      if (handleObj.isSource) {\n        // Source handle goes to start of path\n        newPosition = [pathData[0][1], pathData[0][2]];\n      } else {\n        // Target handle goes to end of path\n        const lastCommand = pathData[pathData.length - 1];\n        newPosition = [\n          lastCommand[lastCommand.length - 2],\n          lastCommand[lastCommand.length - 1],\n        ];\n      }\n\n      // Update handle position\n      handleObj.position = newPosition;\n      handleObj.element.center(newPosition[0], newPosition[1]);\n    }\n  }\n\n  // Notify the host model that an endpoint changed (reattached to a node, or a\n  // free-floating phantom drop) so it can update the association, broadcast to\n  // peers, and persist. The vendored lib is view-only; Connector wires this.\n  if (typeof con.onEndpointChange === \"function\") {\n    const isPhantom = !!target._isPhantomRect;\n    let targetNodeId = null;\n    if (!isPhantom) {\n      try {\n        // findDropTarget returns the SHAPE (rect/circle/…), a child of the\n        // node group; data-node-id lives on the group, so walk up to find it.\n        let el = target.node || null;\n        while (el && el.getAttribute && !el.getAttribute(\"data-node-id\")) {\n          el = el.parentNode;\n        }\n        targetNodeId =\n          (el && el.getAttribute && el.getAttribute(\"data-node-id\")) || null;\n      } catch (e) {\n        /* noop */\n      }\n    }\n    // Prefer the actual drop point (handle release position); fall back to the\n    // target center only if unavailable.\n    let point = dropPoint;\n    if (!point) {\n      try {\n        point = { x: target.cx(), y: target.cy() };\n      } catch (e) {\n        /* noop */\n      }\n    }\n    con.onEndpointChange({\n      which: handleObj.isSource ? \"source\" : \"target\",\n      targetNodeId,\n      isPhantom,\n      point,\n    });\n  }\n}\n\n// Keep track of currently highlighted target to avoid re-applying\nlet currentlyHighlighted = null;\n\n/**\n * highlightDropTarget\n * Highlights a potential drop target during drag with clean animated dashed border\n *\n * @name highlightDropTarget\n * @function\n * @param {SVGElement|null} target The target to highlight\n */\nfunction highlightDropTarget(target) {\n  // If it's the same target as already highlighted, do nothing\n  if (target === currentlyHighlighted) {\n    return;\n  }\n\n  // Clear previous highlights\n  clearDropTargetHighlight();\n\n  if (target) {\n    currentlyHighlighted = target;\n\n    // Store original styles\n    target._originalStroke = target.attr(\"stroke\");\n    target._originalStrokeWidth = target.attr(\"stroke-width\");\n    target._originalStrokeDasharray = target.attr(\"stroke-dasharray\");\n    target._originalStrokeOpacity = target.attr(\"stroke-opacity\");\n\n    // Apply clean animated dashed border\n    target.attr({\n      stroke: \"#007cff\", // Professional blue\n      \"stroke-width\": 3, // Clean consistent width\n      \"stroke-dasharray\": \"8,4\", // Longer dashes for cleaner look\n      \"stroke-opacity\": 0.8, // Slightly transparent\n    });\n\n    // Add CSS animation for dash movement\n    try {\n      const style = target.node.style;\n      style.strokeDashoffset = \"0\";\n      style.animation = \"connector-dash-flow 1.5s linear infinite\";\n\n      // Inject CSS if not already present\n      if (!document.getElementById(\"connector-highlight-styles\")) {\n        const styleSheet = document.createElement(\"style\");\n        styleSheet.id = \"connector-highlight-styles\";\n        styleSheet.textContent = `\n          @keyframes connector-dash-flow {\n            0% { stroke-dashoffset: 0; }\n            100% { stroke-dashoffset: 24; }\n          }\n        `;\n        document.head.appendChild(styleSheet);\n      }\n    } catch (ex) {\n      // Fallback if animation fails\n      console.warn(\"Could not apply highlight animation:\", ex);\n    }\n  } else {\n    currentlyHighlighted = null;\n  }\n}\n\n/**\n * clearDropTargetHighlight\n * Clears drop target highlighting\n *\n * @name clearDropTargetHighlight\n * @function\n */\nfunction clearDropTargetHighlight() {\n  // Clear the currently highlighted target if any\n  if (\n    currentlyHighlighted &&\n    currentlyHighlighted._originalStroke !== undefined\n  ) {\n    currentlyHighlighted.attr({\n      stroke: currentlyHighlighted._originalStroke,\n      \"stroke-width\": currentlyHighlighted._originalStrokeWidth,\n      \"stroke-dasharray\": currentlyHighlighted._originalStrokeDasharray,\n      \"stroke-opacity\": currentlyHighlighted._originalStrokeOpacity,\n    });\n\n    // Clear animation\n    try {\n      const style = currentlyHighlighted.node.style;\n      style.animation = \"\";\n      style.strokeDashoffset = \"\";\n    } catch (ex) {\n      // Ignore if style clearing fails\n    }\n\n    // Clean up stored properties\n    delete currentlyHighlighted._originalStroke;\n    delete currentlyHighlighted._originalStrokeWidth;\n    delete currentlyHighlighted._originalStrokeDasharray;\n    delete currentlyHighlighted._originalStrokeOpacity;\n  }\n\n  currentlyHighlighted = null;\n}\n\n/**\n * updateHandles\n * Updates or creates the connector handles at the endpoints\n *\n * @name updateHandles\n * @function\n * @param {Connectable} con The connectable instance\n * @param {Array} pathData The path data array from computeConnectorCoordinates\n * @return {undefined}\n */\nfunction updateHandles(con, pathData) {\n  if (!con.showHandles || !pathData || pathData.length < 2) {\n    // Remove handles if they exist but aren't needed\n    if (con.sourceHandle) {\n      con.sourceHandle.element.remove();\n      con.sourceHandle = null;\n    }\n    if (con.targetHandle) {\n      con.targetHandle.element.remove();\n      con.targetHandle = null;\n    }\n    return;\n  }\n\n  // Get start and end points from path data\n  const startPoint = [pathData[0][1], pathData[0][2]]; // First M command\n  const lastCmd = pathData[pathData.length - 1];\n  const endPoint = [lastCmd[lastCmd.length - 2], lastCmd[lastCmd.length - 1]]; // Last point\n\n  // Create or update source handle\n  if (!con.sourceHandle) {\n    con.sourceHandle = createHandle(con, true, startPoint);\n  } else {\n    con.sourceHandle.element.attr({\n      cx: startPoint[0],\n      cy: startPoint[1],\n    });\n    con.sourceHandle.position = startPoint;\n  }\n\n  // Create or update target handle\n  if (!con.targetHandle) {\n    con.targetHandle = createHandle(con, false, endPoint);\n  } else {\n    con.targetHandle.element.attr({\n      cx: endPoint[0],\n      cy: endPoint[1],\n    });\n    con.targetHandle.position = endPoint;\n  }\n}\n\n/**\n * createPhantomRect\n * Creates a transparent rectangular placeholder at the dropped location\n *\n * @name createPhantomRect\n * @function\n * @param {Connectable} con The connectable instance\n * @param {Array} position Position [x, y] where the rect should be created\n * @return {Object} Phantom rect element\n */\nfunction createPhantomRect(con, position) {\n  const rect = con.container\n    .rect(20, 20)\n    .attr({\n      x: position[0] - 10,\n      y: position[1] - 10,\n      fill: \"transparent\",\n      stroke: \"none\",\n      \"pointer-events\": \"none\",\n    })\n    .addClass(\"connector-phantom-rect\");\n\n  // Mark as phantom for identification\n  rect._isPhantomRect = true;\n\n  return rect;\n}\n\nexport {\n  createHandle,\n  setupHandleDrag,\n  detachHandle,\n  updateConnectorForDrag,\n  findDropTarget,\n  isValidDropTarget,\n  attachHandleToTarget,\n  highlightDropTarget,\n  clearDropTargetHighlight,\n  updateHandles,\n  createPhantomRect,\n  isPointInElement,\n  visualizeHitZone,\n  clearHitZoneVisualizations,\n};\n","/**\n * Interaction utilities for SVG Connectable\n * Handles selection, debug mode, plugin integrations, and interactive features\n */\n\n/**\n * Helper function to check if a plugin method is available\n */\nfunction hasMethod(element, methodName) {\n  return element && typeof element[methodName] === \"function\";\n}\n\n/**\n * selectConnector\n * Shows handles for this connector and hides them for others\n *\n * @name selectConnector\n * @function\n * @param {Connectable} con The connectable instance\n * @param {Object} activeConnector Current active connector reference (passed by reference)\n * @return {undefined}\n */\nfunction selectConnector(con, activeConnectorRef) {\n  // Deselect any currently active connector\n  if (activeConnectorRef.current && activeConnectorRef.current !== con) {\n    deselectConnector(activeConnectorRef.current);\n  }\n\n  // Select this connector\n  activeConnectorRef.current = con;\n  con.isSelected = true;\n  con.showHandles = true;\n  con.update(); // This will create the handles\n}\n\n/**\n * deselectConnector\n * Hides handles for this connector\n *\n * @name deselectConnector\n * @function\n * @param {Connectable} con The connectable instance\n * @return {undefined}\n */\nfunction deselectConnector(con) {\n  con.isSelected = false;\n  con.showHandles = false;\n  con.update(); // This will remove the handles\n}\n\n/**\n * toggleSelection\n * Toggles the selection state of this connector\n *\n * @name toggleSelection\n * @function\n * @param {Connectable} con The connectable instance\n * @param {Object} activeConnectorRef Current active connector reference (passed by reference)\n * @return {undefined}\n */\nfunction toggleSelection(con, activeConnectorRef) {\n  if (con.isSelected) {\n    deselectConnector(con);\n    if (activeConnectorRef.current === con) {\n      activeConnectorRef.current = null;\n    }\n  } else {\n    selectConnector(con, activeConnectorRef);\n  }\n}\n\n/**\n * setupClickHandlers\n * Sets up click handlers for connector selection with click vs drag detection\n *\n * @name setupClickHandlers\n * @function\n * @param {Connectable} con The connectable instance\n * @param {Object} activeConnectorRef Current active connector reference (passed by reference)\n * @return {undefined}\n */\nfunction setupClickHandlers(con, activeConnectorRef) {\n  // Track mouse position for click vs drag detection\n  let mouseDownPos = null;\n  const DRAG_THRESHOLD = 5; // pixels - if mouse moves more than this, it's a drag not a click\n\n  function handleMouseDown(event) {\n    mouseDownPos = { x: event.clientX, y: event.clientY };\n  }\n\n  function handleMouseUp(event) {\n    if (!mouseDownPos) return;\n\n    // Calculate distance moved\n    const dx = event.clientX - mouseDownPos.x;\n    const dy = event.clientY - mouseDownPos.y;\n    const distance = Math.sqrt(dx * dx + dy * dy);\n\n    // Only trigger click if mouse didn't move significantly (not a pan/drag)\n    if (distance < DRAG_THRESHOLD) {\n      // Let the click reach the canvas too (so the host can clear other\n      // selection), but notify the host that THIS line was clicked. The host\n      // (Connector) decides what to do — show a cog / open the line pane. We do\n      // NOT call the old toggleSelection here: it left the connector \"selected\"\n      // with a deselect that only fired on a bare-container click, which made\n      // the canvas feel stuck (only pannable) until a refresh.\n      if (typeof con.onLineClick === \"function\") {\n        con.onLineClick(event);\n      }\n    }\n\n    mouseDownPos = null;\n  }\n\n  // Use mousedown/mouseup for click detection instead of .click()\n  con.hitArea.on(\"mousedown\", handleMouseDown);\n  con.hitArea.on(\"mouseup\", handleMouseUp);\n  con.connector.on(\"mousedown\", handleMouseDown);\n  con.connector.on(\"mouseup\", handleMouseUp);\n}\n\n/**\n * setConnectorAttachment\n * Sets the connector's attachment type.\n *\n * @name setConnectorAttachment\n * @function\n * @param {Connectable} con The connectable instance\n * @param {String} element Can be either 'source' or 'target'\n * @param {String} type Can be either 'center' or 'perifery'\n * @return {undefined}\n */\nfunction setConnectorAttachment(con, element, type) {\n  con[element + \"Attach\"] = type;\n  con.update();\n}\n\n/**\n * setHandleVisibility\n * Shows or hides the connector handles.\n *\n * @name setHandleVisibility\n * @function\n * @param {Connectable} con The connectable instance\n * @param {Boolean} visible Whether handles should be visible\n * @return {Connectable} The connectable instance.\n */\nfunction setHandleVisibility(con, visible) {\n  con.showHandles = visible;\n  con.update(); // This will create or remove handles based on showHandles\n  return con;\n}\n\n/**\n * getHandles\n * Returns the current handle elements.\n *\n * @name getHandles\n * @function\n * @param {Connectable} con The connectable instance\n * @return {Object} Object with sourceHandle and targetHandle properties\n */\nfunction getHandles(con) {\n  return {\n    sourceHandle: con.sourceHandle,\n    targetHandle: con.targetHandle,\n  };\n}\n\n/**\n * setClickAreaWidth\n * Sets the width of the invisible click area.\n *\n * @name setClickAreaWidth\n * @function\n * @param {Connectable} con The connectable instance\n * @param {Number} width The click area width in pixels\n * @return {Connectable} The connectable instance.\n */\nfunction setClickAreaWidth(con, width) {\n  con.clickAreaWidth = Math.max(6, width || 12); // Minimum 6px\n  con.hitArea.attr(\"stroke-width\", con.clickAreaWidth);\n  return con;\n}\n\n/**\n * setConnector\n * Sets the connector\n *\n * @name setConnector\n * @function\n * @param {Connectable} con The connectable instance\n * @param {SVGElement} connector Can be either an SVGElement or 'default'\n * @return {undefined}\n */\nfunction setConnector(con, connector) {\n  if (connector) {\n    con.connector.remove();\n    if (connector == \"default\") {\n      con.connector = con.container\n        .path()\n        .attr(\"connectortype\", \"default\")\n        .fill(\"none\")\n        .stroke(\"#000000\")\n        .attr(\"stroke-width\", 2);\n      // Set connector color using the color utility\n      con.connector.stroke(con.color).attr(\"stroke-width\", con.strokeWidth);\n    } else con.connector = connector;\n    con.update();\n  }\n}\n\n/**\n * setType\n * Sets the connector's type.\n *\n * @name setType\n * @function\n * @param {Connectable} con The connectable instance\n * @param {String} type Can be either 'straight', 'curved', or 'orthogonal'\n * @return {undefined}\n */\nfunction setType(con, type) {\n  if ([\"straight\", \"curved\", \"orthogonal\"].indexOf(type) != -1) {\n    if (con.type != type) {\n      con.type = type;\n      con.update();\n    }\n  }\n}\n\n/**\n * setDebugMode\n * Sets the debug mode for visualizing hit areas.\n *\n * @name setDebugMode\n * @function\n * @param {Connectable} con The connectable instance\n * @param {Boolean} enabled Whether debug mode should be enabled\n * @return {Connectable} The connectable instance.\n */\nfunction setDebugMode(con, enabled) {\n  con.debugMode = enabled;\n\n  // Update hit area visualization\n  con.hitArea.attr({\n    stroke: con.debugMode ? \"#ff0000\" : \"#000000\",\n    \"stroke-opacity\": con.debugMode ? 0.5 : 0.01,\n  });\n\n  return con;\n}\n\n/**\n * toggleDebugMode\n * Toggles the debug mode for visualizing hit areas.\n *\n * @name toggleDebugMode\n * @function\n * @param {Connectable} con The connectable instance\n * @return {Connectable} The connectable instance.\n */\nfunction toggleDebugMode(con) {\n  return setDebugMode(con, !con.debugMode);\n}\n\n/**\n * makeSelectable\n * Makes the source and target elements selectable (requires @svgdotjs/svg.select.js)\n *\n * @name makeSelectable\n * @function\n * @param {Connectable} con The connectable instance\n * @param {Object} options Options for the select plugin\n * @return {Connectable} The connectable instance.\n */\nfunction makeSelectable(con, options) {\n  options = options || {};\n\n  if (hasMethod(con.source, \"select\")) {\n    con.source.select(options);\n  } else {\n    console.warn(\n      \"svg.select.js plugin not available. Install @svgdotjs/svg.select.js to use selection features.\"\n    );\n  }\n\n  if (hasMethod(con.target, \"select\")) {\n    con.target.select(options);\n  } else {\n    console.warn(\n      \"svg.select.js plugin not available. Install @svgdotjs/svg.select.js to use selection features.\"\n    );\n  }\n\n  return con;\n}\n\n/**\n * makeDraggable\n * Makes the source and target elements draggable (requires @svgdotjs/svg.draggable.js)\n *\n * @name makeDraggable\n * @function\n * @param {Connectable} con The connectable instance\n * @param {Object} options Options for the draggable plugin\n * @return {Connectable} The connectable instance.\n */\nfunction makeDraggable(con, options) {\n  options = options || {};\n\n  if (hasMethod(con.source, \"draggable\")) {\n    con.source.draggable(); // Enable with defaults\n    // Bind connector updates to new drag events (these should already be bound)\n  } else {\n    console.warn(\n      \"svg.draggable.js plugin not available. Install @svgdotjs/svg.draggable.js to use dragging features.\"\n    );\n  }\n\n  if (hasMethod(con.target, \"draggable\")) {\n    con.target.draggable(); // Enable with defaults\n    // Bind connector updates to new drag events (these should already be bound)\n  } else {\n    console.warn(\n      \"svg.draggable.js plugin not available. Install @svgdotjs/svg.draggable.js to use dragging features.\"\n    );\n  }\n\n  return con;\n}\n\n/**\n * makeResizable (experimental)\n * Adds resize handles if svg.resize.js is available\n */\nfunction makeResizable(con, options) {\n  options = options || {};\n\n  if (hasMethod(con.source, \"resize\")) {\n    con.source.resize(options);\n    // Resize event handlers are already bound above\n  } else {\n    console.warn(\n      \"svg.resize.js plugin not available. Install @svgdotjs/svg.resize.js to use resize features.\"\n    );\n  }\n\n  if (hasMethod(con.target, \"resize\")) {\n    con.target.resize(options);\n    // Resize event handlers are already bound above\n  } else {\n    console.warn(\n      \"svg.resize.js plugin not available. Install @svgdotjs/svg.resize.js to use resize features.\"\n    );\n  }\n\n  return con;\n}\n\n/**\n * makeInteractive\n * Makes the source and target elements both selectable, draggable and resizable (requires interactive plugins)\n *\n * @name makeInteractive\n * @function\n * @param {Connectable} con The connectable instance\n * @param {Object} selectOptions Options for the select plugin\n * @param {Object} dragOptions Options for the draggable plugin\n * @param {Object} resizeOptions Options for the resize plugin\n * @param {Function} onMakeInteractive Optional callback fired when interactive features are successfully enabled\n * @return {Connectable} The connectable instance.\n */\nfunction makeInteractive(\n  con,\n  selectOptions,\n  dragOptions,\n  resizeOptions,\n  onMakeInteractive\n) {\n  // Provide default options if not specified\n  selectOptions = selectOptions || {};\n  dragOptions = dragOptions || {};\n  resizeOptions = resizeOptions || {};\n\n  // Check which plugins are available before applying them\n  const availablePlugins = {\n    draggable:\n      hasMethod(con.source, \"draggable\") && hasMethod(con.target, \"draggable\"),\n    selectable:\n      hasMethod(con.source, \"select\") && hasMethod(con.target, \"select\"),\n    resizable:\n      hasMethod(con.source, \"resize\") && hasMethod(con.target, \"resize\"),\n  };\n\n  // Initialise dragging first so the draggable plugin captures the primary\n  // pointer events before any overlay elements are added by the selector.\n  makeDraggable(con, dragOptions);\n  makeSelectable(con, selectOptions);\n  makeResizable(con, resizeOptions);\n\n  // Call the callback if provided and at least one plugin is available\n  if (onMakeInteractive && typeof onMakeInteractive === \"function\") {\n    const hasAnyPlugin =\n      availablePlugins.draggable ||\n      availablePlugins.selectable ||\n      availablePlugins.resizable;\n    if (hasAnyPlugin) {\n      onMakeInteractive(con, availablePlugins);\n    }\n  }\n\n  return con;\n}\n\nexport {\n  selectConnector,\n  deselectConnector,\n  toggleSelection,\n  setupClickHandlers,\n  setConnectorAttachment,\n  setHandleVisibility,\n  getHandles,\n  setClickAreaWidth,\n  setConnector,\n  setType,\n  setDebugMode,\n  toggleDebugMode,\n  makeSelectable,\n  makeDraggable,\n  makeResizable,\n  makeInteractive,\n};\n","/*!\n * SVG.js Connectable Plugin v2.2.0\n * =================================\n *\n * A JavaScript library for connecting SVG things - compatible with SVG.js 3.x\n *\n * svg.connectable.js 2.2.0\n * Licensed under the MIT license.\n * Copyright (c) 2014-15 jillix\n * Copyright (c) 2015-17 Loredana Cirstea\n * Copyright (c) 2015 Christian Tzurcanu - Algorithm for creating connector curves, connector paths.\n * Copyright (c) 2025 - Updated for SVG.js 3.x compatibility with optional interactive features\n *\n * */\n\nimport { Element, SVG, extend } from \"@svgdotjs/svg.js\";\n\n// Import utility modules\nimport {\n  computeConnectorCoordinates,\n  getElementCenter,\n  getClosestPointOnEdge,\n  svgCoordsToLocal,\n} from \"./utils/geometry.js\";\nimport {\n  setMarker,\n  setMarkerSettings,\n  setStrokeWidth,\n  setConnectorColor,\n} from \"./utils/markers.js\";\nimport { updateHandles } from \"./utils/handles.js\";\nimport {\n  selectConnector,\n  deselectConnector,\n  toggleSelection,\n  setupClickHandlers,\n  setConnectorAttachment,\n  setHandleVisibility,\n  getHandles,\n  setClickAreaWidth,\n  setConnector,\n  setType,\n  setDebugMode,\n  toggleDebugMode,\n  makeSelectable,\n  makeDraggable,\n  makeResizable,\n  makeInteractive,\n} from \"./utils/interactions.js\";\n\nlet container = null;\nlet markers = null;\n// Create a single shared reference object for all connectors\nconst globalActiveConnectorRef = { current: null };\n\n/**\n * Helper function to check if a plugin method is available\n */\nfunction hasMethod(element, methodName) {\n  return element && typeof element[methodName] === \"function\";\n}\n\n/**\n * connectable\n * Connects two elements with interactive handles for drag-and-drop reconnection.\n *\n * @name connectable\n * @function\n * @param {Object} options An object containing any of the following fields:\n *\n *  - `container` (SVGElement): The connector elements container. Defaults to source parent.\n *  - `markers` (SVGElement): The marker elements container. Defaults to source parent.\n *  - `sourceAttach` (String): Connector attachment for source element: 'center' / 'perifery'. Defaults to 'perifery'\n *  - `targetAttach` (String): Connector attachment for target element: 'center' / 'perifery'. Defaults to 'perifery'\n *  - `type` (String): Connector type: 'straight', 'curved', or 'orthogonal'. Defaults to 'straight'\n *  - `marker` (String): Can be: an SVGElement / 'null' / 'default'. Defaults to 'null'\n *  - `markerSource` (String): Arrow marker for source end: 'null' / 'default'. Defaults to 'null'\n *  - `markerTarget` (String): Arrow marker for target end: 'null' / 'default'. Defaults to 'default'\n *  - `color` (String): Connector color. Defaults to '#000000'.\n *  - `strokeWidth` (Number): Connector stroke width. Defaults to 2.\n *  - `curveRadius` (Number): Radius for curved connections. Defaults to 20.\n *  - `showHandles` (Boolean): Whether to show draggable handles at connector endpoints. Defaults to false (click to show).\n *  - `handleRadius` (Number): Radius of connector handles. Defaults to 6.\n *  - `handleStrokeWidth` (Number): Stroke width of handles. Defaults to 2.\n *  - `handleStroke` (String): Handle stroke color. Defaults to '#007cff'.\n *  - `handleFill` (String): Handle fill color. Defaults to 'none'.\n *  - `clickAreaWidth` (Number): Width of invisible click area for easier selection. Defaults to max(12, strokeWidth * 3).\n *  - `debugMode` (Boolean): Whether to visualize hit areas for debugging. Defaults to false.\n *\n * @param {SVGElement} elmTarget The target SVG element.\n * @return {Object} The connectable object containing:\n *\n *  - `source` (SVGElement): The source element.\n *  - `target` (SVGElement): The target element.\n *  - `connector` (SVGElement): The connector element (line / path / polygon).\n *  - `markerSource` (SVGElement): The source marker element.\n *  - `markerTarget` (SVGElement): The target marker element.\n *  - `sourceHandle` (Object): The source endpoint handle with drag-and-drop functionality.\n *  - `targetHandle` (Object): The target endpoint handle with drag-and-drop functionality.\n *  - `hitArea` (SVGElement): The invisible click area element.\n *  - [`computeConnectorCoordinates` (Function)](#computeconnectorcoordinatescon)\n *  - [`update` (Function)](#update)\n *  - [`updateHandles` (Function)](#updatehandles)\n *  - [`setConnectorColor` (Function)](#setconnectorcolorcolor-c)\n *  - [`setMarker` (Function)](#setmarker)\n *  - [`setConnectorAttachment` (Function)](#setconnectorattachment)\n *  - [`setHandleVisibility` (Function)](#sethandlevisibility)\n *  - [`getHandles` (Function)](#gethandles)\n *  - [`setClickAreaWidth` (Function)](#setclickareawidth)\n *  - [`selectConnector` (Function)](#selectconnector)\n *  - [`deselectConnector` (Function)](#deselectconnector)\n *  - [`toggleSelection` (Function)](#toggleselection)\n *  - [`setConnector` (Function)](#setconnector)\n *  - [`setType` (Function)](#settype)\n *  - [`setDebugMode` (Function)](#setdebugmode)\n *  - [`toggleDebugMode` (Function)](#toggledebugmode)\n *  - [`makeSelectable` (Function)](#makeselectableoptions) - *Optional: requires @svgdotjs/svg.select.js*\n *  - [`makeDraggable` (Function)](#makedraggableoptions) - *Optional: requires @svgdotjs/svg.draggable.js*\n *  - [`makeInteractive` (Function)](#makeinteractiveselectoptions-dragoptions) - *Optional: requires interactive plugins*\n */\n\nfunction connectable(options, elmTarget) {\n  const con = {};\n\n  if (elmTarget === undefined) {\n    elmTarget = options;\n    options = {};\n  }\n\n  container = options.container || this.parent() || container;\n  const elmSource = this;\n  markers = options.markers || this.parent() || markers;\n\n  // Store container reference for utility functions\n  con.container = container;\n\n  // Append the SVG elements\n  con.source = elmSource; //'center', 'perifery'\n  con.target = elmTarget;\n  con.type = options.type || \"straight\"; //'straight', 'curved', 'orthogonal'\n\n  // Initialize core properties early (before creating elements)\n  con.strokeWidth = options.strokeWidth || 2;\n  con.color = options.color || \"#000000\";\n\n  // Click area configuration - calculate this early\n  con.clickAreaWidth =\n    options.clickAreaWidth || Math.max(12, con.strokeWidth * 3); // Minimum 12px click area\n\n  // Debug mode for visualizing hit areas\n  con.debugMode = options.debugMode || false;\n\n  if (options.connector) {\n    const target = SVG.find(\n      \"#\" + options.connector.node.getAttribute(\"href\").slice(1)\n    )[0];\n    if (target && target.type == \"path\") {\n      con.connector = options.connector;\n      const patharr = target.array();\n      if (\n        !(patharr[1] && patharr[1][0] == \"M\") ||\n        !(patharr[2] && patharr[2][0] == \"M\")\n      ) {\n        const box = target.bbox();\n        patharr.splice(\n          0,\n          0,\n          [\"M\", box.x + box.width / 2, box.y],\n          [\"M\", box.x + box.width / 2, box.y + box.height]\n        );\n        target.plot(patharr);\n      }\n      con.connector.target = target;\n    }\n  }\n\n  if (!con.connector) {\n    con.connector = container\n      .path()\n      .attr(\"connectortype\", \"default\")\n      .fill(\"none\")\n      .stroke(con.color)\n      .attr(\"stroke-width\", con.strokeWidth);\n  }\n\n  // Create invisible hit area for easier clicking (now with correct width)\n  con.hitArea = container.path().attr({\n    connectortype: \"hitarea\",\n    fill: \"none\",\n    stroke: con.debugMode ? \"#ff0000\" : \"#000000\",\n    \"stroke-width\": con.clickAreaWidth,\n    \"stroke-opacity\": con.debugMode ? 0.5 : 0.01, // Visible in debug mode, nearly invisible otherwise\n    \"pointer-events\": \"stroke\",\n  });\n\n  // Set cursor styles using setAttribute for broader compatibility\n  try {\n    con.connector.node.style.cursor = \"pointer\";\n    con.hitArea.node.style.cursor = \"pointer\";\n  } catch (e) {\n    // Fallback: use setAttribute\n    con.connector.node.setAttribute(\"style\", \"cursor: pointer\");\n    con.hitArea.node.setAttribute(\"style\", \"cursor: pointer\");\n  }\n\n  // Ensure hit area is behind the visible connector\n  con.hitArea.back();\n\n  con.sourceAttach = options.sourceAttach || \"perifery\";\n  con.targetAttach = options.targetAttach || \"perifery\";\n  // Edge-pin mode: normalized local anchor {x,y} in 0..1 on the source/target\n  // node. When set, the endpoint is pinned to that point and rotates with the\n  // node (instead of auto-flow to the nearest edge). null = auto-flow.\n  con.sourceAnchor = options.sourceAnchor || null;\n  con.targetAnchor = options.targetAnchor || null;\n  con.curveRadius = options.curveRadius || 20;\n  // Bezier bow amount as a 0..1 fraction of the connector length (the app's\n  // \"Line Curve\" slider). Distinct from curveRadius (a pixel value used by the\n  // orthogonal router). Defaults to a moderate curve.\n  con.lineCurviness =\n    typeof options.lineCurviness === \"number\" ? options.lineCurviness : 0.3;\n  // Bezier sub-type: 'cubic' (default, two control points) or 'quadratic' (one).\n  con.lineCurveType = options.lineCurveType || \"cubic\";\n\n  // Support for separate source and target markers\n  con.markerSourceType = options.markerSource || \"null\";\n  con.markerTargetType = options.markerTarget || options.marker || \"default\";\n\n  // Handle configuration\n  con.showHandles = options.showHandles || false; // Default to false - only show when clicked\n  con.handleRadius = options.handleRadius || 6;\n  con.handleStrokeWidth = options.handleStrokeWidth || 2;\n  con.handleStroke = options.handleStroke || \"#007cff\";\n  con.handleFill = options.handleFill || \"none\";\n  con.isSelected = false; // Track selection state\n\n  // Add computeConnectorCoordinates method\n  con.computeConnectorCoordinates = function (conInstance) {\n    return computeConnectorCoordinates(conInstance || con);\n  };\n\n  elmSource.cons = elmSource.cons || [];\n  elmSource.cons.push(con);\n\n  // Also track the connector on the target element\n  elmTarget.targetCons = elmTarget.targetCons || [];\n  elmTarget.targetCons.push(con);\n\n  /**\n   * update\n   * Updates the connector's path and handles\n   *\n   * @name update\n   * @function\n   * @return {undefined}\n   */\n  con.update = function () {\n    if (con.connector.attr(\"connectortype\") == \"default\") {\n      const pathData = con.computeConnectorCoordinates(con);\n\n      // Validate path data before plotting\n      let isValid = true;\n      for (let i = 0; i < pathData.length; i++) {\n        for (let j = 1; j < pathData[i].length; j++) {\n          if (isNaN(pathData[i][j]) || !isFinite(pathData[i][j])) {\n            console.error(\n              \"Invalid coordinate in path data:\",\n              pathData[i][j],\n              \"at\",\n              [i, j]\n            );\n            isValid = false;\n          }\n        }\n      }\n\n      if (isValid) {\n        con.connector.plot(pathData);\n        con.hitArea.plot(pathData); // Update hit area with same path\n        updateHandles(con, pathData);\n        // Keep the edge LABEL (if any) centered on the line as it reshapes.\n        if (con.positionLabel) con.positionLabel();\n      } else {\n        console.error(\"Skipping plot due to invalid path data\");\n      }\n    }\n  };\n\n  // Initialize markers using utility function\n  setMarker(con, con.markerSourceType, con.markerTargetType, markers);\n\n  // Initialize handles (will be positioned in first update)\n  con.sourceHandle = null;\n  con.targetHandle = null;\n\n  // Attach methods from utility modules\n  con.setMarker = function (sourceMarker, targetMarker, markersContainer) {\n    return setMarker(con, sourceMarker, targetMarker, markersContainer);\n  };\n\n  con.setMarkerSettings = function (sourceMarker, targetMarker) {\n    return setMarkerSettings(con, sourceMarker, targetMarker);\n  };\n\n  // --- Edge label (Miro-style) ---------------------------------------------\n  // A connector can carry a text label centered on the line. Rendered lazily —\n  // connectors WITHOUT a label create no extra elements and positionLabel() is a\n  // no-op, so existing connectors are completely unaffected.\n  con.positionLabel = function () {\n    if (!con.label || !con.connector || !con.connector.node) return;\n    try {\n      const total = con.connector.node.getTotalLength();\n      if (!total || !isFinite(total)) return;\n      const mid = con.connector.node.getPointAtLength(total / 2);\n      con.label.center(mid.x, mid.y);\n      if (con.labelBg) {\n        const bb = con.label.bbox();\n        con.labelBg\n          .size(bb.width + 10, bb.height + 4)\n          .center(mid.x, mid.y);\n      }\n    } catch (e) {\n      /* noop */\n    }\n  };\n\n  con.setLabel = function (text) {\n    con.labelText = text == null ? \"\" : String(text);\n    if (!con.labelText) {\n      if (con.label) {\n        con.label.remove();\n        con.label = null;\n      }\n      if (con.labelBg) {\n        con.labelBg.remove();\n        con.labelBg = null;\n      }\n      return;\n    }\n    if (!con.label) {\n      // A translucent chip behind the text keeps it readable over the line.\n      con.labelBg = container\n        .rect(0, 0)\n        .attr({ fill: \"#ffffff\", \"fill-opacity\": 0.85, \"pointer-events\": \"none\" })\n        .radius(3);\n      con.label = container\n        .text(con.labelText)\n        .attr({\n          \"font-size\": 13,\n          \"font-family\": \"Arial, sans-serif\",\n          fill: \"#333333\",\n          \"text-anchor\": \"middle\",\n          \"pointer-events\": \"none\",\n        });\n    } else {\n      con.label.text(con.labelText);\n    }\n    con.positionLabel();\n  };\n\n  con.setStrokeWidth = function (width) {\n    return setStrokeWidth(con, width);\n  };\n\n  con.setConnectorColor = function (color) {\n    setConnectorColor(con, color);\n    return con;\n  };\n\n  // Fully remove this connector's DOM (line, hit area, handles, markers, and\n  // any free-floating phantom rects). Without this, removing a connection left\n  // the SVG elements behind as \"rogue lines\" (the caller only knew con.line/\n  // con.marker, which don't exist — the real elements are con.connector etc.).\n  con.remove = function () {\n    const rm = (el) => {\n      try {\n        el && el.remove && el.remove();\n      } catch (e) {\n        /* noop */\n      }\n    };\n    rm(con.connector);\n    rm(con.hitArea);\n    rm(con.sourceHandle && con.sourceHandle.element);\n    rm(con.targetHandle && con.targetHandle.element);\n    rm(con.markerSource);\n    rm(con.markerTarget);\n    rm(con._sourcePhantomRect);\n    rm(con._targetPhantomRect);\n    rm(con.label);\n    rm(con.labelBg);\n    return con;\n  };\n\n  // Compute the endpoint's CURRENT attachment as a normalized local anchor\n  // {x,y} in 0..1 on the node — used to switch an endpoint to ABSOLUTE lock\n  // (freeze it where it is now) for L5.\n  con.getCurrentAnchor = function (which) {\n    const shape = which === \"source\" ? con.source : con.target;\n    const other = which === \"source\" ? con.target : con.source;\n    if (!shape || !shape.bbox || !other) return { x: 0.5, y: 0.5 };\n    try {\n      const otherCenter = getElementCenter(other);\n      const edge = getClosestPointOnEdge(shape, otherCenter); // world coords\n      const local = svgCoordsToLocal(shape, edge[0], edge[1]);\n      const bb = shape.bbox();\n      if (!bb.width || !bb.height) return { x: 0.5, y: 0.5 };\n      return {\n        x: (local[0] - bb.x) / bb.width,\n        y: (local[1] - bb.y) / bb.height,\n      };\n    } catch (e) {\n      return { x: 0.5, y: 0.5 };\n    }\n  };\n\n  // Edge-pin API: pin (or unpin with null) an endpoint to a normalized local\n  // anchor {x,y} in 0..1 on the source/target node; re-solves immediately.\n  con.setAttachmentAnchor = function (which, anchor) {\n    if (which === \"source\") con.sourceAnchor = anchor || null;\n    else if (which === \"target\") con.targetAnchor = anchor || null;\n    con.update();\n    return con;\n  };\n\n  con.updateHandles = function (pathData) {\n    updateHandles(con, pathData);\n  };\n\n  con.selectConnector = function () {\n    selectConnector(con, globalActiveConnectorRef);\n  };\n\n  con.deselectConnector = function () {\n    deselectConnector(con);\n    if (globalActiveConnectorRef.current === con) {\n      globalActiveConnectorRef.current = null;\n    }\n  };\n\n  con.toggleSelection = function () {\n    toggleSelection(con, globalActiveConnectorRef);\n  };\n\n  con.setConnectorAttachment = function (element, type) {\n    setConnectorAttachment(con, element, type);\n  };\n\n  con.setHandleVisibility = function (visible) {\n    return setHandleVisibility(con, visible);\n  };\n\n  con.getHandles = function () {\n    return getHandles(con);\n  };\n\n  con.setClickAreaWidth = function (width) {\n    return setClickAreaWidth(con, width);\n  };\n\n  con.setConnector = function (connector) {\n    setConnector(con, connector);\n  };\n\n  con.setType = function (type) {\n    setType(con, type);\n  };\n\n  con.setDebugMode = function (enabled) {\n    return setDebugMode(con, enabled);\n  };\n\n  con.toggleDebugMode = function () {\n    return toggleDebugMode(con);\n  };\n\n  con.makeSelectable = function (options) {\n    return makeSelectable(con, options);\n  };\n\n  con.makeDraggable = function (options) {\n    return makeDraggable(con, options);\n  };\n\n  con.makeResizable = function (options) {\n    return makeResizable(con, options);\n  };\n\n  con.makeInteractive = function (selectOptions, dragOptions, resizeOptions) {\n    return makeInteractive(con, selectOptions, dragOptions, resizeOptions);\n  };\n\n  // Set up click handlers using utility function\n  setupClickHandlers(con, globalActiveConnectorRef);\n\n  con.update();\n\n  // Generic update function for backward compatibility\n  function updateConnector(event) {\n    con.update();\n  }\n\n  // Create element-specific update functions to preserve context\n  function updateConnectorFromSource(event) {\n    // No need to track angles anymore - CTM handles all transformations\n    con.update();\n  }\n\n  function updateConnectorFromTarget(event) {\n    // No need to track angles anymore - CTM handles all transformations\n    con.update();\n  }\n\n  // Store update functions on the connector for proper removal during reattachment\n  con._sourceUpdateFunction = updateConnectorFromSource;\n  con._targetUpdateFunction = updateConnectorFromTarget;\n\n  // Bind to drag events\n  elmSource.on(\"dragmove\", updateConnectorFromSource);\n  elmTarget.on(\"dragmove\", updateConnectorFromTarget);\n\n  // If elements have the new draggable plugin, update on those events too\n  elmSource.on(\"beforedrag\", updateConnectorFromSource);\n  elmSource.on(\"dragstart\", updateConnectorFromSource);\n  elmSource.on(\"dragend\", updateConnectorFromSource);\n  elmTarget.on(\"beforedrag\", updateConnectorFromTarget);\n  elmTarget.on(\"dragstart\", updateConnectorFromTarget);\n  elmTarget.on(\"dragend\", updateConnectorFromTarget);\n\n  // Bind to resize events for both source and target elements (these can include rotation)\n  elmSource.on(\"resize\", updateConnectorFromSource);\n  elmTarget.on(\"resize\", updateConnectorFromTarget);\n\n  // Bind to rotation-specific events if available\n  elmSource.on(\"rotate\", updateConnectorFromSource);\n  elmTarget.on(\"rotate\", updateConnectorFromTarget);\n\n  // Bind to transform events to catch any transformation changes\n  elmSource.on(\"transform\", updateConnectorFromSource);\n  elmTarget.on(\"transform\", updateConnectorFromTarget);\n\n  // Store update function for external access\n  con.updateConnector = updateConnector;\n\n  // Set initial connector color\n  setConnectorColor(con, con.color);\n\n  return con;\n}\n\n// Extend Element with the connectable method and convenience methods\nextend(Element, {\n  connectable: connectable,\n\n  /**\n   * makeConnectableAndInteractive\n   * Creates a connection to target and makes both elements interactive\n   *\n   * @param {Object} connectOptions Options for the connectable plugin\n   * @param {SVGElement} target The target element to connect to\n   * @param {Object} selectOptions Options for the select plugin\n   * @param {Object} dragOptions Options for the draggable plugin\n   * @return {Connectable} The connectable instance.\n   */\n  makeConnectableAndInteractive: function (\n    connectOptions,\n    target,\n    selectOptions,\n    dragOptions\n  ) {\n    const connection = this.connectable(connectOptions, target);\n    connection.makeInteractive(selectOptions, dragOptions);\n    return connection;\n  },\n});\n","import \"@svgdotjs/svg.select.js\";\nimport \"@svgdotjs/svg.resize.js\";\nimport type { Node } from \"./Node\";\n\n/**\n * Compute the L-bracket polyline points for one svg.select.js resize handle.\n * Mirrors svg.select.js' default updateHandle, but guards the divide-by-distance\n * (adjacent handle points can transiently coincide → r/c = 0 → NaN) and returns\n * `null` when any input/result is non-finite so the caller skips the plot. This\n * is what kept multi-select (Cmd+A/Cmd+D) from flooding the console with\n * \"<polyline> points: Expected number, NaN\" errors.\n */\nexport function computeSelectHandlePlot(\n  point: [number, number],\n  prev: [number, number],\n  next: [number, number]\n): Array<[number, number]> | null {\n  const a = point;\n  const l = [a[0] - prev[0], a[1] - prev[1]];\n  const h = [a[0] - next[0], a[1] - next[1]];\n  const r = Math.sqrt(l[0] * l[0] + l[1] * l[1]) || 1;\n  const c = Math.sqrt(h[0] * h[0] + h[1] * h[1]) || 1;\n  const d = [l[0] / r, l[1] / r];\n  const u = [h[0] / c, h[1] / c];\n  const p: [number, number] = [a[0] - 10 * d[0], a[1] - 10 * d[1]];\n  const H: [number, number] = [a[0] - 10 * u[0], a[1] - 10 * u[1]];\n  const plot: Array<[number, number]> = [p, a, H];\n  const finite = plot.every(\n    (pt) => Number.isFinite(pt[0]) && Number.isFinite(pt[1])\n  );\n  return finite ? plot : null;\n}\n\nexport interface ResizeRotateOptions {\n  resizeEnabled?: boolean;\n  rotateEnabled?: boolean;\n  preserveAspectRatio?: boolean;\n  aroundCenter?: boolean;\n  grid?: number;\n  degree?: number;\n  onResize?: (event: any) => void;\n  onRotate?: (event: any) => void;\n}\n\nexport class ResizeRotate {\n  private node: Node;\n  private target: any;\n  private options: ResizeRotateOptions;\n  private isActive: boolean = false;\n  private _interacting = false;\n  private _didRotate = false;\n  private _didResize = false;\n  private _endListener: (() => void) | null = null;\n  // Canonical world position captured at the START of a resize/rotate, before\n  // svg.resize.js displaces children in local space. Used to convert the\n  // plugin's local box back to world coords in handleResize.\n  private _preInteractionPos: { x: number; y: number } | null = null;\n\n  /**\n   * Creates resize/rotate handle management for a node.\n   *\n   * @param node    - The parent Node instance\n   * @param options - Resize/rotate configuration\n   */\n  constructor(node: Node, options: ResizeRotateOptions = {}) {\n    this.node = node;\n    // Custom vector shapes use a transparent proxy <rect> as the resize/select\n    // target (the nested <svg> backgroundRect can't be resized by svg.resize.js).\n    this.target = (node as any).resizeTarget ?? node.backgroundRect;\n    this.options = {\n      resizeEnabled: true,\n      rotateEnabled: true,\n      preserveAspectRatio: false,\n      aroundCenter: false,\n      grid: 0,\n      degree: 0,\n      ...options,\n    };\n  }\n\n  /** Enable resize and rotate handles on the node. */\n  public enable() {\n    if (this.isActive) return;\n    // Re-resolve in case the proxy was created after construction (custom shapes\n    // build the proxy during async shape rendering).\n    this.target = (this.node as any).resizeTarget ?? this.node.backgroundRect;\n    // Guard: backgroundRect may not be initialized if node creation failed\n    if (!this.target) {\n      console.warn(\"RESIZE_ROTATE_DEBUG: Cannot enable — target (backgroundRect) not available on\", this.node?.id);\n      return;\n    }\n\n    try {\n      // Use the correct svg.select.js API for generic shapes (rect, circle, ellipse)\n      const element: any = this.target;\n\n      // Make the whole group selectable / rotatable\n      if (typeof element.select === \"function\") {\n        element.select({\n          rotationPoint: this.options.rotateEnabled,\n          // svg.select.js' default updateHandle divides by the distance between\n          // adjacent handle points; when a transient/degenerate bbox makes points\n          // coincide (or the screenCTM collapses), that divide-by-zero plots\n          // \"NaN\" polyline points and floods the console (notably on multi-select\n          // via the keyboard). This replicates the default L-bracket exactly but\n          // guards the division and never plots non-finite points.\n          updateHandle: (handle: any, point: any, index: number, points: any[]) => {\n            const prev = points[(index - 1 + points.length) % points.length];\n            const next = points[(index + 1) % points.length];\n            const plot = computeSelectHandlePlot(point, prev, next);\n            if (plot) handle.plot(plot);\n          },\n        });\n      }\n\n      // Attach resize capability (applies a transform on the group)\n      if (this.options.resizeEnabled && typeof element.resize === \"function\") {\n        element.resize({\n          preserveAspectRatio: this.options.preserveAspectRatio,\n          aroundCenter: this.options.aroundCenter,\n          grid: this.options.grid ?? 1,\n          degree: this.options.degree ?? 0.1,\n        });\n      }\n\n      // Normalize plugin-generated selection UI after svg.select.js appends it.\n      this.styleSelectionUi();\n\n      // Add event listeners\n      this.addEventListeners();\n\n      this.isActive = true;\n    } catch (error) {\n      console.warn(\"Failed to enable resize/rotate:\", error);\n    }\n  }\n\n  /**\n   * Keep svg.select.js' generated control layer non-obscuring and make the\n   * L-shaped polyline handles easier to grab. These inline attributes are\n   * intentional because consumers can use the built JS without loading CSS.\n   */\n  private styleSelectionUi() {\n    // Defer to next frame — svg.select.js may not have appended handles yet\n    requestAnimationFrame(() => {\n      try {\n        const svgNode = this.target.node;\n        const root = svgNode.ownerSVGElement || svgNode;\n\n        const selectionShapes = root.querySelectorAll(\n          \".svg_select_shape, .svg_select_shape_pointSelect\"\n        );\n        selectionShapes.forEach((shape: SVGElement) => {\n          shape.setAttribute(\"fill\", \"none\");\n          shape.setAttribute(\"fill-opacity\", \"0\");\n          shape.setAttribute(\"pointer-events\", \"none\");\n          (shape.style as any).fill = \"none\";\n          (shape.style as any).fillOpacity = \"0\";\n          shape.style.pointerEvents = \"none\";\n        });\n\n        const handles = root.querySelectorAll(\".svg_select_handle\");\n        handles.forEach((h: SVGElement) => {\n          // Miro-style: light-blue corner/edge handles (was chunky black #333).\n          // stroke-width 6 keeps them easy to grab while looking far lighter than\n          // the old 8px black brackets.\n          h.setAttribute(\"stroke-width\", \"6\");\n          h.setAttribute(\"stroke\", \"#4A90E2\");\n          h.style.pointerEvents = \"all\";\n        });\n      } catch (e) {\n        console.warn(\"RESIZE_ROTATE_DEBUG: Failed to widen handle hit areas:\", e);\n      }\n    });\n  }\n\n  /** Disable resize and rotate handles on the node. */\n  public disable() {\n    if (!this.isActive) return;\n\n    try {\n      const element: any = this.target;\n\n      // Disable selection and resize if APIs are available\n      if (typeof element.select === \"function\") {\n        element.select(false);\n      }\n      if (typeof element.resize === \"function\") {\n        element.resize(false);\n      }\n\n      this.removeEventListeners();\n      this.isActive = false;\n    } catch (error) {\n      console.warn(\"Failed to disable resize/rotate:\", error);\n    }\n  }\n\n  private addEventListeners() {\n    // Miro interaction contract: resize freely by default; hold Shift when the\n    // drag begins to preserve the current proportions. The plugin exposes its\n    // live handler in `beforeresize`, before it snapshots the starting box.\n    this.target.on(\"beforeresize.resizerotate\", (event: any) => {\n      const handler = event.detail?.handler;\n      const pointerEvent = event.detail?.event?.detail?.event;\n      if (handler) {\n        handler.preserveAspectRatio = Boolean(\n          this.options.preserveAspectRatio || pointerEvent?.shiftKey\n        );\n      }\n    });\n\n    // Hide connection handles when resize/rotate starts\n    this.target.on(\"mousedown.resizerotate touchstart.resizerotate\", (event: any) => {\n      // Check if the event is on a resize/rotate handle\n      if (this.isResizeRotateHandle(event.target)) {\n        if (this.node.isConnectionHandlesEnabled()) {\n          this.node.disableConnectionHandles();\n        }\n        this._interacting = true;\n        this._didRotate = false;\n        this._didResize = false;\n      }\n    });\n\n    // Emit the v1 end-of-interaction package once, on pointer release\n    this._endListener = () => {\n      if (!this._interacting) return;\n      this._interacting = false;\n      // Re-assert the canonical model: strip rotation baked into the shape/text\n      // during the interaction and move it to the group transform, with children\n      // normalized back to the local origin. This is what makes resize/rotate\n      // survive a reload without the node flying off-screen.\n      if ((this._didRotate || this._didResize) && this.node.finalizeInteraction) {\n        this.node.finalizeInteraction();\n      }\n      this._preInteractionPos = null;\n      const slate = this.node.slate as any;\n      if (this._didRotate) {\n        slate?.broadcast?.(\"onNodeRotated\", {\n          id: this.node.id,\n          rotate: this.node.options.rotate,\n          width: this.node.options.width,\n          height: this.node.options.height,\n        });\n      } else if (this._didResize) {\n        slate?.broadcast?.(\"onNodeResized\", {\n          id: this.node.id,\n          width: this.node.options.width,\n          height: this.node.options.height,\n          rotate: this.node.options.rotate,\n          vectorPath: this.node.options.vectorPath,\n        });\n        // Re-fit the text once the resize has FULLY settled. During the drag,\n        // fitTextToNode (via centerText in setSize) measures transient, mid-rewrap\n        // geometry and can leave the text unscaled/overflowing on a shrunk node. A\n        // final centerText on the reflowed DOM applies the correct fit (Miro-style).\n        requestAnimationFrame(() => {\n          try {\n            this.node.centerText?.();\n          } catch (e) {\n            /* noop */\n          }\n        });\n      }\n      this._didRotate = false;\n      this._didResize = false;\n    };\n    window.addEventListener(\"pointerup\", this._endListener);\n    window.addEventListener(\"touchend\", this._endListener);\n\n    // Re-show connection handles when resize/rotate ends\n    this.target.on(\"resize\", (event: any) => {\n      // Capture the canonical world position ONCE, before svg.resize.js has\n      // displaced any children this interaction (handleResize converts the\n      // plugin's local box against this).\n      if (this._preInteractionPos === null) {\n        this._preInteractionPos = {\n          x: this.node.options.x ?? 0,\n          y: this.node.options.y ?? 0,\n        };\n      }\n      // A resize event means an interaction is in progress (the handle's own\n      // mousedown does not reliably bubble through the target); track its\n      // kind for the end-of-drag package\n      this._interacting = true;\n      // svg.resize.js includes an angle field on plain resize events too —\n      // only a non-zero angle indicates actual rotation; a box indicates\n      // a size change\n      if (event.detail?.box) {\n        this._didResize = true;\n      }\n      if (\n        typeof event.detail?.angle === \"number\" &&\n        event.detail.angle !== 0\n      ) {\n        this._didRotate = true;\n      }\n\n      this.handleResize(event);\n      this.options.onResize?.(event);\n\n      // Re-enable connection handles after resize completes\n      if (this.node.slate && this.node.slate.getSelectedNodes().includes(this.node)) {\n        // Only re-enable if this node is still selected\n        setTimeout(() => {\n          this.node.enableConnectionHandles();\n        }, 50);\n      }\n\n      // Notify slate of node change (for BirdsEye refresh)\n      this.node.slate?.notifyNodeChanged(this.node);\n    });\n  }\n\n  private isResizeRotateHandle(target: any): boolean {\n    if (!target || !target.classList) return false;\n\n    const handleClasses = [\n      \"svg_select_handle\",\n      \"svg_select_handle_rot\",\n      \"svg_select_handle_lt\",\n      \"svg_select_handle_rt\",\n      \"svg_select_handle_rb\",\n      \"svg_select_handle_lb\",\n      \"svg_select_handle_t\",\n      \"svg_select_handle_r\",\n      \"svg_select_handle_b\",\n      \"svg_select_handle_l\",\n    ];\n\n    for (const className of handleClasses) {\n      if (target.classList.contains(className)) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  private removeEventListeners() {\n    this.target.off(\"resize\");\n    this.target.off(\"beforeresize.resizerotate\");\n    this.target.off(\"mousedown.resizerotate touchstart.resizerotate\");\n    if (this._endListener) {\n      window.removeEventListener(\"pointerup\", this._endListener);\n      window.removeEventListener(\"touchend\", this._endListener);\n      this._endListener = null;\n    }\n  }\n\n  private handleResize(event: any) {\n    // The resize plugin emits the final box in event.detail.box\n    if (event.detail && event.detail.box) {\n      const box = event.detail.box as any;\n\n      // Persist and recentre text since we change actual width/height of shape\n      this.node.options.width = box.width;\n      this.node.options.height = box.height;\n      // svg.resize.js reports box.x/y in the group's LOCAL space (children are\n      // normalized to the local origin at interaction start). Convert to a WORLD\n      // position: pre-interaction world + local delta. Storing box.x directly\n      // would write a local coord into options.x and get double-counted against\n      // the group translate on reload (node flies off-screen).\n      const base = this._preInteractionPos ?? {\n        x: this.node.options.x ?? 0,\n        y: this.node.options.y ?? 0,\n      };\n      this.node.options.x = base.x + box.x;\n      this.node.options.y = base.y + box.y;\n\n      // Call setSize to update nested SVG and other elements\n      this.node.setSize(box.width, box.height);\n\n      this.node.centerText();\n\n      // Connectors follow LIVE during resize (M7): svg.connectable re-solves on\n      // a \"transform\" event on the connected group. handleResize runs each\n      // resize frame, so fire it here to re-layout attached lines in real time\n      // (previously they only updated at the end of the interaction).\n      try {\n        this.node.svgGroup?.fire?.(\"transform\");\n      } catch (e) {\n        /* noop */\n      }\n\n      // If a rotation happened, the resize event carries angle (delta)\n      // svg.resize.js applies rotation incrementally to backgroundRect\n      // We need to read the ACTUAL cumulative rotation from backgroundRect.transform()\n      if (event.detail && typeof event.detail.angle === \"number\") {\n        const deltaAngle = event.detail.angle as number;\n\n        // Read the cumulative rotation from backgroundRect (where svg.resize.js applies it)\n        let backgroundRectRotation = 0;\n        try {\n          const targetTransform = this.target.transform();\n          backgroundRectRotation = targetTransform?.rotate || 0;\n        } catch (e) {\n          console.warn(\"RESIZE_ROTATE_DEBUG: Failed to read backgroundRect rotation:\", e);\n        }\n\n        // Also get any existing rotation on svgGroup (from setRotation, e.g., duplicated nodes)\n        let existingSvgGroupRotation = 0;\n        try {\n          const groupTransform = this.node.svgGroup.transform();\n          existingSvgGroupRotation = groupTransform?.rotate || 0;\n        } catch (e) {\n          console.warn(\"RESIZE_ROTATE_DEBUG: Failed to read svgGroup rotation:\", e);\n        }\n\n        // Total rotation = svgGroup rotation + backgroundRect rotation\n        const totalRotation = existingSvgGroupRotation + backgroundRectRotation;\n\n        // Store the rotation angle - create the rotate object if it doesn't exist\n        if (!this.node.options.rotate) {\n          this.node.options.rotate = { rotationAngle: 0 };\n        }\n        this.node.options.rotate.rotationAngle = totalRotation;\n\n        // Rotate content elements to match background rotation\n        // Use deltaAngle because content elements are children of svgGroup\n        // and we're applying incremental rotation to match backgroundRect\n        if (\n          this.node.textElement &&\n          typeof this.node.textElement.rotate === \"function\"\n        ) {\n          // For regular nodes: rotate text element\n          const bbox = this.target.bbox();\n          this.node.textElement.rotate(deltaAngle, bbox.cx, bbox.cy);\n        } else if (\n          this.node.nestedSvg &&\n          typeof this.node.nestedSvg.rotate === \"function\"\n        ) {\n          // For SVG content nodes: rotate nested SVG\n          const bbox = this.target.bbox();\n          this.node.nestedSvg.rotate(deltaAngle, bbox.cx, bbox.cy);\n        }\n      }\n    }\n  }\n\n  public isEnabled(): boolean {\n    return this.isActive;\n  }\n\n  /** Destroy the resize/rotate instance, disabling all plugins and clearing references */\n  public destroy(): void {\n    this.disable();\n    (this as any).node = null;\n    this.target = null;\n  }\n\n  public updateOptions(options: Partial<ResizeRotateOptions>) {\n    this.options = { ...this.options, ...options };\n\n    if (this.isActive) {\n      // Reapply with new options\n      this.disable();\n      this.enable();\n    }\n  }\n\n  public refresh() {\n    // Force a refresh of resize/rotate handles by disabling and re-enabling\n    // This is necessary after operations like drag that change position\n    if (this.isActive) {\n      this.disable();\n      this.enable();\n    }\n  }\n}\n","import { SVG } from \"@svgdotjs/svg.js\";\nimport type { Node } from \"./Node\";\nimport type { Slate } from \"./Slate\";\n// NOTE: svg.connectable.js is imported in src/index.ts - do not import here to avoid conflicts\n\n// Ensure SVG is available globally for svg.connectable.js\nif (typeof window !== \"undefined\") {\n  (window as any).SVG = SVG;\n}\n\nexport interface ConnectorOptions {\n  enabled?: boolean;\n  lineContainer?: any; // SVG group for line elements\n  markerContainer?: any; // SVG group for marker elements\n  padEllipse?: boolean;\n  defaultLineColor?: string;\n  defaultLineWidth?: number;\n  onConnect?: (connection: Connection) => void;\n  onDisconnect?: (connection: Connection) => void;\n\n  // svg.connectable.js specific options with defaults\n  type?: \"straight\" | \"curved\" | \"orthogonal\";\n  color?: string;\n  strokeWidth?: number;\n  sourceAttach?: \"center\" | \"perifery\";\n  targetAttach?: \"center\" | \"perifery\";\n  markerSource?: string;\n  markerTarget?: string;\n  showHandles?: boolean;\n  curveRadius?: number;\n}\n\nexport interface Connection {\n  id: string;\n  source: Node; // Source node\n  target: Node; // Target node\n  connectable: any; // The svg.connectable.js object\n  lineColor?: string;\n  lineWidth?: number;\n  lineOpacity?: number;\n  lineEffect?: string;\n  label?: string; // Optional text label centered on the edge (Miro-style).\n  // Edge-pin mode: normalized local anchor {x,y} in 0..1 on source/target.\n  // Omitted/undefined = auto-flow (endpoint re-solves to the nearest edge).\n  sourceAnchor?: { x: number; y: number } | null;\n  targetAnchor?: { x: number; y: number } | null;\n}\n\nexport class Connector {\n  private node: Node;\n  private slate: Slate;\n  private options: ConnectorOptions;\n  private connections: Map<string, Connection> = new Map();\n  private isActive: boolean = false;\n\n  /**\n   * Creates a connector for a node. Manages connection lines to other nodes.\n   *\n   * @param node    - The parent Node instance\n   * @param options - Connector configuration (line color, width, type, etc.)\n   */\n  constructor(node: Node, options: ConnectorOptions = {}) {\n    this.node = node;\n    this.slate = node.slate;\n    this.options = {\n      enabled: false,\n      padEllipse: true,\n      defaultLineColor: \"#666666\",\n      defaultLineWidth: 2,\n\n      // svg.connectable.js defaults as specified by user\n      type: \"curved\",\n      color: \"#007cff\",\n      strokeWidth: 3,\n      sourceAttach: \"perifery\",\n      targetAttach: \"perifery\",\n      markerSource: \"null\",\n      markerTarget: \"default\",\n      showHandles: true,\n      curveRadius: 30,\n\n      ...options,\n    };\n\n    console.log(\"CONNECTOR_DEBUG: Created connector for node\", this.node.id);\n  }\n\n  /** Enable the connector, making connection handles available. */\n  public enable() {\n    if (this.isActive) return;\n\n    try {\n      console.log(\"CONNECTOR_DEBUG: Enabling connector for node\", this.node.id);\n\n      // Check if svg.connectable.js is compatible\n      if (!(this.node.svgGroup as any).connectable) {\n        console.warn(\n          \"CONNECTOR_DEBUG: svg.connectable.js not available - may need SVG.js 3+ compatibility update\"\n        );\n        console.warn(\n          \"CONNECTOR_DEBUG: Connector functionality will be limited until svg.connectable.js is updated\"\n        );\n        // Don't return here - allow the connector to be \"enabled\" but with limited functionality\n      }\n\n      // Ensure we have containers for lines and markers\n      this.ensureContainers();\n\n      this.isActive = true;\n      console.log(\"CONNECTOR_DEBUG: Connector enabled for node\", this.node.id);\n    } catch (error) {\n      console.warn(\"CONNECTOR_DEBUG: Failed to enable connector:\", error);\n    }\n  }\n\n  /** Disable the connector and remove all connections. */\n  public disable() {\n    if (!this.isActive) return;\n\n    try {\n      console.log(\n        \"CONNECTOR_DEBUG: Disabling connector for node\",\n        this.node.id\n      );\n\n      // Disconnect all existing connections\n      this.disconnectAll();\n\n      this.isActive = false;\n      console.log(\"CONNECTOR_DEBUG: Connector disabled for node\", this.node.id);\n    } catch (error) {\n      console.warn(\"CONNECTOR_DEBUG: Failed to disable connector:\", error);\n    }\n  }\n\n  public destroy(): void {\n    this.disable();\n    this.connections.clear();\n  }\n\n  private ensureContainers() {\n    // Use existing containers or create new ones\n    if (!this.options.lineContainer) {\n      // Create a lines container in the slate if it doesn't exist\n      if (!this.slate.linesContainer) {\n        this.slate.linesContainer = this.slate.canvas.group();\n        console.log(\"CONNECTOR_DEBUG: Created global lines container\");\n      }\n      this.options.lineContainer = this.slate.linesContainer;\n    }\n\n    if (!this.options.markerContainer) {\n      // Create a markers container in the slate if it doesn't exist\n      if (!this.slate.markersContainer) {\n        this.slate.markersContainer = this.slate.canvas.group();\n        console.log(\"CONNECTOR_DEBUG: Created global markers container\");\n      }\n      this.options.markerContainer = this.slate.markersContainer;\n    }\n  }\n\n  public connectTo(\n    targetNode: any,\n    connectionOptions: Partial<Connection> = {}\n  ): Connection | null {\n    if (!this.isActive) {\n      console.warn(\n        \"CONNECTOR_DEBUG: Connector not enabled for node\",\n        this.node.id\n      );\n      return null;\n    }\n\n    try {\n      console.log(\n        \"CONNECTOR_DEBUG: Connecting\",\n        this.node.id,\n        \"to\",\n        targetNode.id\n      );\n\n      // Parallel edges: the association drives the connection id (e.g.\n      // `A->B~2`), so a second line to the same node gets its own key instead of\n      // colliding with the first. Falls back to the pair id for direct callers.\n      const connectionId =\n        (connectionOptions as any).connectionId ||\n        `${this.node.id}->${targetNode.id}`;\n\n      // Check if connection already exists\n      if (this.connections.has(connectionId)) {\n        console.warn(\n          \"CONNECTOR_DEBUG: Connection already exists:\",\n          connectionId\n        );\n        return this.connections.get(connectionId)!;\n      }\n\n      // Compatibility check for svg.connectable.js\n      if (!(this.node.svgGroup as any).connectable) {\n        console.error(\n          \"CONNECTOR_DEBUG: svg.connectable.js not properly loaded or incompatible with SVG.js 3+\"\n        );\n        return null;\n      }\n\n      // Per-connection overrides (from the association record) so a saved line\n      // type / curviness / arrows render correctly on create AND after reload.\n      const co = connectionOptions as any;\n      const typeMap: Record<string, string> = {\n        bezier: \"curved\",\n        curved: \"curved\",\n        orthogonal: \"orthogonal\",\n        straight: \"straight\",\n        linear: \"straight\",\n      };\n      const connType = co.lineType\n        ? typeMap[co.lineType] || \"curved\"\n        : this.options.type;\n      const markerSource =\n        co.showParentArrow != null\n          ? co.showParentArrow\n            ? this.options.markerSource || \"arrow\"\n            : \"null\"\n          : this.options.markerSource;\n      const markerTarget =\n        co.showChildArrow != null\n          ? co.showChildArrow\n            ? this.options.markerTarget || \"arrow\"\n            : \"null\"\n          : this.options.markerTarget;\n\n      // Use svg.connectable.js to create the connection with full options\n      const connectableObj = (this.node.svgGroup as any).connectable(\n        {\n          container: this.options.lineContainer,\n          markers: this.options.markerContainer,\n          type: connType,\n          color: co.lineColor || this.options.color,\n          strokeWidth: co.lineWidth || this.options.strokeWidth,\n          sourceAttach: this.options.sourceAttach,\n          targetAttach: this.options.targetAttach,\n          markerSource,\n          markerTarget,\n          showHandles: this.options.showHandles,\n          curveRadius: this.options.curveRadius,\n          lineCurviness: co.lineCurviness,\n          lineCurveType: (co as any).lineCurveType,\n          // Edge-pin mode (optional): normalized local anchors {x,y} 0..1\n          sourceAnchor: connectionOptions.sourceAnchor,\n          targetAnchor: connectionOptions.targetAnchor,\n        },\n        targetNode.svgGroup\n      );\n\n      // Verify the connection was created successfully\n      if (!connectableObj) {\n        console.error(\"CONNECTOR_DEBUG: Failed to create connectable object\");\n        return null;\n      }\n\n      // Create connection object\n      const connection: Connection = {\n        id: connectionId,\n        source: this.node,\n        target: targetNode,\n        connectable: connectableObj,\n        lineColor: connectionOptions.lineColor || this.options.defaultLineColor,\n        lineWidth: connectionOptions.lineWidth || this.options.defaultLineWidth,\n        ...connectionOptions,\n      };\n\n      // Apply styling if available\n      if (connection.lineColor && connectableObj.setLineColor) {\n        connectableObj.setLineColor(connection.lineColor);\n      }\n      this.applyLineAppearance(connectableObj, connection);\n      // Render the edge label (if this connection carries one).\n      if (connection.label && connectableObj.setLabel) {\n        connectableObj.setLabel(connection.label);\n      }\n\n      // Store the connection\n      this.connections.set(connectionId, connection);\n\n      // Keep arrowheads above the nodes (M4): the markers container is a lazy\n      // canvas group whose z-order otherwise depends on creation order, so a\n      // node created later would cover the arrowhead pointing into it.\n      try {\n        this.slate.markersContainer?.front?.();\n      } catch (e) {\n        /* noop */\n      }\n\n      // Wire endpoint-drag → model. When the user drags a source/target handle\n      // and drops it, the vendored lib reattaches the VIEW; this callback\n      // updates the association model, broadcasts to peers, and persists (L1).\n      connectableObj.onEndpointChange = (info: any) =>\n        this.handleEndpointChange(connection, info);\n\n      // Also store on target node (for bidirectional lookup)\n      if (targetNode.connector) {\n        // Keyed by the unique connection id (not the pair) so parallel edges each\n        // get their own reverse-lookup entry instead of overwriting one another.\n        const reverseId = `${targetNode.id}<-${connectionId}`;\n        targetNode.connector.connections.set(reverseId, connection);\n      }\n\n      console.log(\"CONNECTOR_DEBUG: Successfully connected\", connectionId);\n\n      // Clicking a connection line shows a cog affordance; clicking the cog\n      // asks the HOST to open its line-properties pane (M1/M2). Wired via the\n      // vendored onLineClick hook (fires on a clean click of the line/hit area).\n      connectableObj.onLineClick = () => {\n        if (this.node.slate?.isReadOnly?.()) return;\n        this.showLineCog(connection, connectableObj, targetNode.id);\n      };\n\n      // Miro-style: endpoint handles are hidden (CSS) until the connection is\n      // hovered or selected. Wire the hover reveal here (handles are created\n      // lazily, so we read them at hover time, not now).\n      this.wireHandleReveal(connectableObj);\n\n      // Trigger callback\n      this.options.onConnect?.(connection);\n\n      return connection;\n    } catch (error) {\n      console.error(\"CONNECTOR_DEBUG: Failed to create connection:\", error);\n      console.error(\n        \"CONNECTOR_DEBUG: This might be due to SVG.js 3+ compatibility issues with svg.connectable.js\"\n      );\n      return null;\n    }\n  }\n\n  /**\n   * Connect this node to a bare WORLD point (free-floating endpoint, L1b).\n   * Backed by an invisible 1px \"phantom\" rect at the point so the existing\n   * svg.connectable geometry (edge-solve on the target's bbox) works unchanged.\n   * The synthetic id keys the connection like a normal one.\n   */\n  public connectToPoint(\n    point: { x: number; y: number },\n    synthId: string,\n    connectionOptions: Partial<Connection> = {}\n  ): Connection | null {\n    if (!this.isActive) this.enable();\n    const container: any = this.options.lineContainer || this.slate.canvas;\n    if (!container) return null;\n    const phantom = container\n      .rect(1, 1)\n      .move(point.x - 0.5, point.y - 0.5)\n      .fill(\"none\")\n      .opacity(0);\n    (phantom as any)._isPhantomRect = true;\n    const fakeTarget: any = { id: synthId, svgGroup: phantom, _isFloating: true };\n    const conn = this.connectTo(fakeTarget, connectionOptions);\n    if (conn) (conn as any)._phantom = phantom;\n    return conn;\n  }\n\n  public disconnectFrom(targetNode: any): boolean {\n    // Disconnect EVERY edge to this target (the canonical `A->B` plus any parallel\n    // `A->B~N`), so node deletion / disconnect-from-child never orphans a line.\n    const base = `${this.node.id}->${targetNode.id}`;\n    const ids = [...this.connections.keys()].filter(\n      (id) => id === base || id.startsWith(`${base}~`)\n    );\n    if (ids.length === 0) return this.disconnectById(base);\n    let ok = false;\n    for (const id of ids) ok = this.disconnectById(id) || ok;\n    return ok;\n  }\n\n  public disconnectById(connectionId: string): boolean {\n    try {\n      const connection = this.connections.get(connectionId);\n      if (!connection) {\n        console.warn(\"CONNECTOR_DEBUG: Connection not found:\", connectionId);\n        return false;\n      }\n\n      console.log(\"CONNECTOR_DEBUG: Disconnecting\", connectionId);\n\n      // Fully remove the connectable's DOM (line + hit area + handles + markers\n      // + phantoms). The connectable exposes con.remove(); the old code removed\n      // con.line/con.marker which don't exist, leaving rogue lines behind (L4).\n      try {\n        if (connection.connectable?.remove) {\n          connection.connectable.remove();\n        } else {\n          connection.connectable?.connector?.remove?.();\n          connection.connectable?.hitArea?.remove?.();\n        }\n        (connection as any)._phantom?.remove?.();\n      } catch (e) {\n        /* noop */\n      }\n\n      // Remove from both nodes' connection maps\n      this.connections.delete(connectionId);\n\n      // Remove reverse connection from target node (unique-id keyed, matching\n      // how it was stored in connectTo — so parallel edges clean up individually).\n      if (connection.target && connection.target.connector) {\n        const reverseId = `${connection.target.id}<-${connectionId}`;\n        connection.target.connector.connections.delete(reverseId);\n      }\n\n      console.log(\"CONNECTOR_DEBUG: Successfully disconnected\", connectionId);\n\n      // Trigger callback\n      this.options.onDisconnect?.(connection);\n\n      return true;\n    } catch (error) {\n      console.error(\"CONNECTOR_DEBUG: Failed to disconnect:\", error);\n      return false;\n    }\n  }\n\n  public disconnectAll(): void {\n    console.log(\n      \"CONNECTOR_DEBUG: Disconnecting all connections for node\",\n      this.node.id\n    );\n\n    const connectionIds = Array.from(this.connections.keys());\n    for (const connectionId of connectionIds) {\n      this.disconnectById(connectionId);\n    }\n  }\n\n  public getConnections(): Connection[] {\n    return Array.from(this.connections.values());\n  }\n\n  public getConnection(targetNodeId: string): Connection | null {\n    const connectionId = `${this.node.id}->${targetNodeId}`;\n    return this.connections.get(connectionId) || null;\n  }\n\n  public updateConnection(\n    connectionId: string,\n    updates: Partial<Connection>\n  ): boolean {\n    try {\n      const connection = this.connections.get(connectionId);\n      if (!connection) {\n        console.warn(\n          \"CONNECTOR_DEBUG: Connection not found for update:\",\n          connectionId\n        );\n        return false;\n      }\n\n      // Update connection properties\n      Object.assign(connection, updates);\n\n      const c = connection.connectable;\n      if (c) {\n        // Color (the connectable exposes setConnectorColor, not setLineColor)\n        if (updates.lineColor != null && c.setConnectorColor) {\n          c.setConnectorColor(updates.lineColor);\n        }\n        if (updates.lineWidth != null && c.setStrokeWidth) {\n          c.setStrokeWidth(updates.lineWidth);\n        }\n        this.applyLineAppearance(c, connection);\n        // Edge label (Miro-style): set/update/clear the text centered on the line.\n        if ((updates as any).label != null && c.setLabel) {\n          c.setLabel((updates as any).label);\n        }\n        // Line type: pane uses bezier/orthogonal; connectable uses\n        // straight/curved/orthogonal.\n        if ((updates as any).lineType != null && c.setType) {\n          const map: Record<string, string> = {\n            bezier: \"curved\",\n            curved: \"curved\",\n            orthogonal: \"orthogonal\",\n            straight: \"straight\",\n            linear: \"straight\",\n          };\n          c.setType(map[(updates as any).lineType] || \"curved\");\n        }\n        if ((updates as any).lineCurviness != null) {\n          // 0..1 bezier bow fraction (NOT the pixel curveRadius).\n          c.lineCurviness = (updates as any).lineCurviness;\n        }\n        if ((updates as any).lineCurveType != null) {\n          // Bezier sub-type: 'cubic' | 'quadratic' — re-solve so the curve redraws.\n          c.lineCurveType = (updates as any).lineCurveType;\n          c.update?.();\n        }\n        // Arrow markers: source = parent arrow, target = child arrow\n        if (\n          (updates as any).showParentArrow != null ||\n          (updates as any).showChildArrow != null\n        ) {\n          const src =\n            ((updates as any).showParentArrow ??\n            (connection as any).showParentArrow)\n              ? \"arrow\"\n              : \"null\";\n          const tgt =\n            ((updates as any).showChildArrow ??\n            (connection as any).showChildArrow ??\n            true)\n              ? \"arrow\"\n              : \"null\";\n          c.setMarker?.(src, tgt);\n        }\n        // Re-solve the path so any geometry-affecting change takes effect\n        c.update?.();\n      }\n\n      console.log(\"CONNECTOR_DEBUG: Updated connection\", connectionId);\n      return true;\n    } catch (error) {\n      console.error(\"CONNECTOR_DEBUG: Failed to update connection:\", error);\n      return false;\n    }\n  }\n\n  /** Apply v1 line opacity/effect fields to the visible connector path. */\n  private applyLineAppearance(connectable: any, connection: Connection): void {\n    const line = connectable?.connector;\n    if (!line?.attr) return;\n    if (connection.lineOpacity != null) {\n      line.attr(\"stroke-opacity\", connection.lineOpacity);\n    }\n    if (connection.lineEffect !== undefined) {\n      const filters: Record<string, string> = {\n        dropShadow: \"drop-shadow(3px 3px 4px rgba(0,0,0,0.3))\",\n        postItNote: \"drop-shadow(0 4px 2px rgba(0,0,0,0.5))\",\n        blur: \"blur(2px)\",\n        pencil: \"url(#sb-pencil-filter)\",\n      };\n      line.attr(\"filter\", filters[connection.lineEffect] || null);\n    }\n  }\n\n  /**\n   * Edge-pin mode: pin (or unpin with null) a connection's endpoint to a\n   * normalized local anchor {x,y} in 0..1 on the source or target node.\n   * A pinned endpoint stays on that point and rotates with the node; null\n   * restores auto-flow (nearest-edge). Re-solves immediately.\n   */\n  public setConnectionAnchor(\n    targetNodeId: string,\n    which: \"source\" | \"target\",\n    anchor: { x: number; y: number } | null\n  ): boolean {\n    const connection = this.connections.get(`${this.node.id}->${targetNodeId}`);\n    if (!connection) return false;\n    if (which === \"source\") connection.sourceAnchor = anchor;\n    else connection.targetAnchor = anchor;\n    connection.connectable?.setAttachmentAnchor?.(which, anchor);\n    return true;\n  }\n\n  /**\n   * Endpoint-drag → model (L1). The vendored lib has already reattached the\n   * VIEW when this fires; we reconcile the association MODEL so the change\n   * broadcasts to peers and persists. Reattaching to a node rebuilds the\n   * association (remove old + add new) through the already-synced/persisted\n   * addAssociation/removeAssociation. Deferred a tick so the lib's dragend\n   * finishes before we tear down/recreate the connection.\n   *\n   * Free-floating (phantom) drops are L1b — not yet persisted; left as a\n   * view-only endpoint for now (no rogue model state).\n   */\n  private handleEndpointChange(\n    connection: Connection,\n    info: { which: \"source\" | \"target\"; targetNodeId: string | null; isPhantom: boolean; point: any }\n  ): void {\n    const { which, targetNodeId, isPhantom, point } = info;\n    const props = {\n      lineColor: connection.lineColor,\n      lineWidth: connection.lineWidth,\n      lineType: (connection as any).lineType,\n      lineCurviness: (connection as any).lineCurviness,\n      lineCurveType: (connection as any).lineCurveType,\n      showParentArrow: (connection as any).showParentArrow,\n      showChildArrow: (connection as any).showChildArrow,\n    };\n    // The connection's ORIGINAL child id (stable in the id `parent->child`),\n    // used for the same-node re-pin check + child lookup. STRIP any parallel-edge\n    // `~N` suffix: id `A->B~2` must yield child \"B\", not \"B~2\" — otherwise the\n    // same-node check below fails and the reconnect remove+adds → DUPLICATE edge\n    // (moving a parallel line \"copies\" it). Removal/pinning key on connection.id\n    // (the SPECIFIC edge), not the child, so parallels aren't over-removed.\n    const origChildId = (connection.id.split(\"->\")[1] || \"\")\n      .trim()\n      .replace(/~\\d+$/, \"\");\n\n    setTimeout(() => {\n      try {\n        if (which === \"target\") {\n          const parent: any = connection.source;\n          if (!parent?.relationships) return;\n          if (isPhantom || !targetNodeId) {\n            // Dropped on empty canvas → free-floating target endpoint (L1b)\n            if (!point) return;\n            if (origChildId) parent.relationships.removeAssociation(connection.id);\n            parent.relationships.addFloatingAssociation(point, props);\n          } else {\n            // Reattach to a node (L1a) — pin the TARGET endpoint at the DROP\n            // POINT so the arrow connects exactly where the user dropped (U3).\n            const newNode = this.slate.nodes.one(targetNodeId);\n            if (!newNode) return;\n            if (newNode.id === origChildId) {\n              // Dropped back on the SAME target node → just RE-PIN the anchor at\n              // the new drop point (reposition the pin) instead of bailing. This\n              // is how you move a pinned endpoint along its own node's edge.\n              this.pinDropAnchor(parent, connection.id, newNode, \"targetAnchor\", point);\n              return;\n            }\n            if (origChildId) parent.relationships.removeAssociation(connection.id);\n            parent.relationships.addAssociation(newNode, props);\n            this.pinDropAnchor(parent, newNode.id, newNode, \"targetAnchor\", point);\n          }\n        } else {\n          // Source-end reattach to a node (source floating not yet modeled)\n          if (isPhantom || !targetNodeId) return;\n          const oldParent: any = connection.source;\n          const child: any = connection.target;\n          const newNode = this.slate.nodes.one(targetNodeId);\n          if (!newNode || !child || !oldParent?.relationships) return;\n          if (newNode.id === oldParent.id) {\n            // Dropped back on the SAME source node → re-pin the source anchor at\n            // the new drop point instead of bailing.\n            this.pinDropAnchor(oldParent, child.id, newNode, \"sourceAnchor\", point);\n            return;\n          }\n          oldParent.relationships.removeAssociation(connection.id);\n          newNode.relationships?.addAssociation(child, props);\n          // Pin the SOURCE endpoint at the drop point on the new source node.\n          this.pinDropAnchor(newNode, child.id, newNode, \"sourceAnchor\", point);\n        }\n      } catch (e) {\n        console.warn(\"CONNECTOR_DEBUG: endpoint change → model failed:\", e);\n      }\n    }, 0);\n  }\n\n  /**\n   * U3: pin an endpoint at the exact drop point on a node. Converts the world\n   * drop point into a normalized [0,1] anchor on the node's box and stores it as\n   * the source/target anchor (persists + renders there). Skipped for rotated\n   * nodes (world→local normalization would be wrong) — those fall back to\n   * auto-flow. relationships owner is `ownerNode`; the association is childId.\n   */\n  private pinDropAnchor(\n    ownerNode: any,\n    childId: string,\n    anchorNode: any,\n    which: \"sourceAnchor\" | \"targetAnchor\",\n    point: { x: number; y: number } | null\n  ): void {\n    try {\n      if (!point) return;\n      const o = anchorNode?.options || {};\n      if (!o.width || !o.height) return;\n      const clamp = (v: number) => Math.max(0, Math.min(1, v));\n      // Un-rotate the world drop point into the node's LOCAL (unrotated) frame so the\n      // normalized anchor is correct on ROTATED nodes too. The node rotates around its\n      // center by rotationAngle; the connectable re-applies that rotation when rendering\n      // a stored local anchor (getCurrentAnchor round-trips through the shape CTM), so a\n      // correct local anchor renders exactly at the drop point. Previously this bailed on\n      // rotated nodes → the endpoint fell back to auto-flow (nearest edge) and \"reverted\"\n      // away from where the user dropped it (the reported bug).\n      let px = point.x;\n      let py = point.y;\n      const angle = o.rotate?.rotationAngle || 0;\n      if (angle) {\n        const cx = (o.x || 0) + o.width / 2;\n        const cy = (o.y || 0) + o.height / 2;\n        const rad = (-angle * Math.PI) / 180;\n        const dx = px - cx;\n        const dy = py - cy;\n        px = cx + dx * Math.cos(rad) - dy * Math.sin(rad);\n        py = cy + dx * Math.sin(rad) + dy * Math.cos(rad);\n      }\n      let ax = clamp((px - (o.x || 0)) / o.width);\n      let ay = clamp((py - (o.y || 0)) / o.height);\n      // Snap to the nearest EDGE so the arrowhead sits ON the node's boundary\n      // (touching it, on the side the user dropped) instead of at an interior\n      // point — an interior anchor put the arrowhead inside/covered by the node\n      // and made the line's edge-solve disagree with the pinned arrowhead,\n      // rendering a detached/inverted arrow that didn't track the node cleanly.\n      const dl = ax;\n      const dr = 1 - ax;\n      const dt = ay;\n      const db = 1 - ay;\n      const nearest = Math.min(dl, dr, dt, db);\n      if (nearest === dl) ax = 0;\n      else if (nearest === dr) ax = 1;\n      else if (nearest === dt) ay = 0;\n      else ay = 1;\n      const anchor = { x: ax, y: ay };\n      const rels = ownerNode?.relationships;\n      // `childId` may be a specific association id (`A->B~2`, passed for reconnect\n      // pinning) OR a bare child id — prefer the exact edge, fall back to child.\n      const assoc =\n        rels?.associations?.find((a: any) => a.id === childId) ||\n        rels?.associations?.find((a: any) => a.childId === childId);\n      if (assoc?.id) {\n        rels.applyLineProperty(assoc.id, which, anchor);\n        // Broadcast the pinned anchor so it PERSISTS and syncs. The reconnect's\n        // addAssociation save fires before this anchor is set, so without a\n        // broadcast the drop-side anchor is lost on reload (reverts to auto-edge).\n        (ownerNode.slate as any)?.broadcast?.(\"onLinePropertiesChanged\", {\n          id: ownerNode.id,\n          prop: which,\n          val: anchor,\n          associationId: assoc.id,\n        });\n      }\n    } catch (e) {\n      /* noop */\n    }\n  }\n\n  /**\n   * L5 per-endpoint locking. mode \"absolute\" freezes the endpoint at its\n   * current spot on the node (a normalized local anchor that then moves/rotates\n   * with the node); \"relative\" clears it back to auto-flow (nearest-edge).\n   * Returns the anchor that was set (or null) so callers can persist it.\n   */\n  public setEndpointLock(\n    connectionId: string,\n    which: \"source\" | \"target\",\n    mode: \"absolute\" | \"relative\"\n  ): { x: number; y: number } | null {\n    const connection = this.connections.get(connectionId);\n    if (!connection) return null;\n    const c: any = connection.connectable;\n    if (mode === \"absolute\") {\n      const anchor = c?.getCurrentAnchor?.(which) || { x: 0.5, y: 0.5 };\n      (connection as any)[which + \"Anchor\"] = anchor;\n      c?.setAttachmentAnchor?.(which, anchor);\n      return anchor;\n    }\n    (connection as any)[which + \"Anchor\"] = null;\n    c?.setAttachmentAnchor?.(which, null);\n    return null;\n  }\n\n  /**\n   * Show a cog affordance at the midpoint of a clicked line (M1/M2). Clicking\n   * the cog opens the host's line-properties pane. Only one cog is shown at a\n   * time (tracked on the slate) and it clears on canvas/node interaction.\n   */\n  /**\n   * Miro-style hover reveal for a connection's endpoint handles. Handles are\n   * hidden by default (CSS) and shown while the pointer is over the line, its\n   * hit area, or a handle — then hidden again on leave, UNLESS the connection is\n   * selected (`_handlesPinned`, set by showLineCog / cleared by clearLineCog).\n   * Handles are created lazily by the vendored lib, so we resolve them at event\n   * time rather than capturing them now.\n   */\n  private wireHandleReveal(con: any): void {\n    const handleEls = (): any[] =>\n      [con.sourceHandle?.element, con.targetHandle?.element].filter(\n        (h: any) => h && h.node\n      );\n    const reveal = (visible: boolean): void => {\n      handleEls().forEach((h: any) => {\n        if (visible) h.node.classList.add(\"connector-handle--revealed\");\n        // Keep shown while selected (pinned) OR while a handle is mid-drag —\n        // otherwise dragging an endpoint off the line hides it and breaks the\n        // reconnect.\n        else if (!con._handlesPinned && !con._handlesDragging)\n          h.node.classList.remove(\"connector-handle--revealed\");\n      });\n    };\n    // Exposed so selection (showLineCog) can pin and clearLineCog can release.\n    con._revealHandles = reveal;\n    const armHandleHover = (): void =>\n      handleEls().forEach((h: any) => {\n        if (h._revealArmed) return;\n        h._revealArmed = true;\n        h.on?.(\"mouseenter\", () => reveal(true));\n        h.on?.(\"mouseleave\", () => reveal(false));\n        // Keep the endpoint visible + draggable for the whole drag gesture.\n        h.on?.(\"dragstart\", () => {\n          con._handlesDragging = true;\n          reveal(true);\n        });\n        h.on?.(\"dragend\", () => {\n          con._handlesDragging = false;\n          if (!con._handlesPinned) reveal(false);\n        });\n      });\n    [con.hitArea, con.connector].forEach((el: any) => {\n      el?.on?.(\"mouseenter\", () => {\n        reveal(true);\n        armHandleHover();\n      });\n      el?.on?.(\"mouseleave\", () => reveal(false));\n    });\n  }\n\n  private showLineCog(connection: Connection, con: any, targetId: string): void {\n    const slate: any = this.slate;\n    slate.clearLineCog?.();\n    const line = con?.connector;\n    let cx: number, cy: number;\n    try {\n      const bb = line.bbox();\n      cx = bb.cx;\n      cy = bb.cy;\n    } catch (e) {\n      return;\n    }\n    const container: any = slate.markersContainer || slate.canvas;\n    if (!container) return;\n\n    // Line context toolbar (G2/Q2) — modern Miro-style pill at the line midpoint:\n    // delete + cog. (The old \"plug\" did nothing and was dropped; the cog opens\n    // the line pane AND shows per-endpoint lock/relative toggles — Q3.)\n    const R = 15;\n    const GAP = 6;\n    const NEUTRAL = \"#5b6472\";\n    const tools: Array<{ key: string; color: string; onClick: () => void }> = [\n      {\n        key: \"delete\",\n        color: \"#e5484d\",\n        onClick: () => {\n          (this.node as any).relationships?.removeAssociation?.(targetId);\n          slate.clearLineCog?.();\n        },\n      },\n      {\n        key: \"cog\",\n        color: NEUTRAL,\n        onClick: () => {\n          this.openLinePane(connection, con, targetId);\n          this.showEndpointLockToggles(connection, con, targetId);\n        },\n      },\n    ];\n    const n = tools.length;\n    const stepX = R * 2 + GAP;\n    const totalW = n * (R * 2) + (n - 1) * GAP;\n    const startX = cx - totalW / 2 + R;\n\n    const bar = container.group().addClass(\"line-cog\").addClass(\"line-toolbar\");\n    bar\n      .rect(totalW + 14, R * 2 + 10)\n      .radius((R * 2 + 10) / 2)\n      .center(cx, cy)\n      .fill(\"#ffffff\")\n      .stroke({ color: \"#e3e5ea\", width: 1 });\n    const NodeCls: any = (this.node as any).constructor;\n    tools.forEach((t, i) => {\n      const bx = startX + i * stepX;\n      const btn = bar.group().addClass(`line-tool-${t.key}`);\n      btn.circle(R * 2).center(bx, cy).fill(\"#ffffff\").attr(\"fill-opacity\", 0.001);\n      NodeCls.drawToolIcon?.(btn, t.key, bx, cy, t.color);\n      btn.attr(\"pointer-events\", \"all\");\n      try {\n        btn.node.style.cursor = \"pointer\";\n      } catch (e) {\n        /* noop */\n      }\n      btn.on(\"mousedown\", (e: any) => e.stopPropagation?.());\n      btn.on(\"click\", (e: any) => {\n        e.stopPropagation?.();\n        t.onClick();\n      });\n    });\n    bar.attr(\"pointer-events\", \"all\");\n    slate._activeLineCog = bar;\n    // Also select the connector so its endpoint handles show — this is what\n    // makes the endpoints draggable (L1 snap-anywhere). Tracked on the slate so\n    // clearLineCog() (canvas click / node select) deselects it — no stuck state.\n    try {\n      con.selectConnector?.();\n      slate._activeLineConnectable = con;\n      // Pin the endpoint handles visible while this connection is selected.\n      con._handlesPinned = true;\n      con._revealHandles?.(true);\n    } catch (e) {\n      /* noop */\n    }\n    // markers/cog stay on top\n    try {\n      slate.markersContainer?.front?.();\n    } catch (e) {\n      /* noop */\n    }\n  }\n\n  private openLinePane(connection: Connection, con: any, targetId: string): void {\n    const events = this.node.slate?.options?.events;\n    if (!events?.onLineMenuRequested) return;\n    // The host pane (LineProperties) reads association.child.options.id, so pass\n    // the ENRICHED association (live parent/child refs) from the .associations\n    // getter, not the raw assocMap record (which lacks .child → pane crash).\n    const rels: any = (this.node as any).relationships;\n    const association =\n      rels?.associations?.find((a: any) => a.childId === targetId) ??\n      rels?.getAssociation?.(targetId) ??\n      connection;\n    events.onLineMenuRequested(this.node, association, (opts: any = {}) => {\n      // Apply pane edits through the association model (syncs + persists)\n      if (association?.id && (this.node as any).relationships) {\n        for (const [prop, val] of Object.entries(opts)) {\n          (this.node as any).relationships.applyLineProperty(\n            association.id,\n            prop,\n            val\n          );\n        }\n      }\n    });\n  }\n\n  /**\n   * Q3: show a lock/relative toggle at EACH endpoint (source + target) when the\n   * line cog is clicked. Clicking a toggle flips absolute (pinned anchor) ↔\n   * relative (auto-flow) via applyLineProperty, and broadcasts for collab parity.\n   */\n  private showEndpointLockToggles(\n    connection: Connection,\n    con: any,\n    targetId: string\n  ): void {\n    const slate: any = this.slate;\n    // clear any previous toggle set\n    if (slate._activeEndpointToggles) {\n      slate._activeEndpointToggles.forEach((g: any) => {\n        try {\n          g.remove();\n        } catch (e) {\n          /* noop */\n        }\n      });\n    }\n    slate._activeEndpointToggles = [];\n\n    const lineNode: any = con?.connector?.node;\n    if (!lineNode || !lineNode.getPointAtLength) return;\n    let total = 0;\n    try {\n      total = lineNode.getTotalLength();\n    } catch (e) {\n      return;\n    }\n    const p0 = lineNode.getPointAtLength(0);\n    const p1 = lineNode.getPointAtLength(total);\n\n    const rels: any = (this.node as any).relationships;\n    const assoc = rels?.associations?.find((a: any) => a.childId === targetId);\n    if (!assoc) return;\n\n    // Match path ends to nodes: p0/p1 → source(this.node) / target(targetId),\n    // then INSET the toggle inward from each end so it sits clear of the node\n    // edge + the endpoint drag-handle (and is reliably clickable).\n    const centerOf = (n: any) => {\n      const o = n?.options || {};\n      return { x: (o.x || 0) + (o.width || 0) / 2, y: (o.y || 0) + (o.height || 0) / 2 };\n    };\n    const dist = (p: any, c: any) => Math.hypot(p.x - c.x, p.y - c.y);\n    const srcC = centerOf(this.node);\n    const srcAtStart = dist(p0, srcC) <= dist(p1, srcC);\n    const inset = Math.min(34, total * 0.28);\n    const srcPt = lineNode.getPointAtLength(srcAtStart ? inset : total - inset);\n    const tgtPt = lineNode.getPointAtLength(srcAtStart ? total - inset : inset);\n\n    const container: any = slate.markersContainer || slate.canvas;\n    const NEUTRAL = \"#5b6472\";\n    const ABS = \"#4051B5\";\n\n    const makeToggle = (pt: any, which: \"source\" | \"target\") => {\n      const absolute =\n        which === \"source\" ? !!assoc.sourceAnchor : !!assoc.targetAnchor;\n      const color = absolute ? ABS : NEUTRAL;\n      const g = container\n        .group()\n        .addClass(\"endpoint-lock\")\n        .addClass(`endpoint-lock-${which}`)\n        .addClass(absolute ? \"endpoint-lock-absolute\" : \"endpoint-lock-relative\");\n      g.circle(24).center(pt.x, pt.y).fill(\"#ffffff\").stroke({ color, width: 1.5 });\n      Connector.drawLockIcon(g, pt.x, pt.y, color, absolute);\n      // Transparent hit circle ON TOP so a click anywhere on the toggle registers\n      // (the padlock's fill:none paths are not hit-testable at their centers).\n      g.circle(24).center(pt.x, pt.y).fill(\"#ffffff\").attr(\"fill-opacity\", 0.001);\n      g.attr(\"pointer-events\", \"all\");\n      try {\n        g.node.style.cursor = \"pointer\";\n      } catch (e) {\n        /* noop */\n      }\n      g.on(\"mousedown\", (e: any) => e.stopPropagation?.());\n      g.on(\"click\", (e: any) => {\n        e.stopPropagation?.();\n        const prop = which === \"source\" ? \"sourceLock\" : \"targetLock\";\n        const val = absolute ? \"relative\" : \"absolute\";\n        try {\n          rels.applyLineProperty(assoc.id, prop, val);\n        } catch (err) {\n          /* noop */\n        }\n        // Collab parity: mirror the on-canvas toggle to peers.\n        try {\n          slate.broadcast?.(\"onLinePropertiesChanged\", {\n            id: this.node.id,\n            associationId: assoc.id,\n            prop,\n            val,\n          });\n        } catch (err) {\n          /* noop */\n        }\n        // Re-render toggles to reflect the new state.\n        this.showEndpointLockToggles(connection, con, targetId);\n      });\n      slate._activeEndpointToggles.push(g);\n    };\n\n    makeToggle(srcPt, \"source\");\n    makeToggle(tgtPt, \"target\");\n    try {\n      slate.markersContainer?.front?.();\n    } catch (e) {\n      /* noop */\n    }\n  }\n\n  /** Draw a small padlock (closed = absolute/locked, open = relative). */\n  private static drawLockIcon(\n    g: any,\n    cx: number,\n    cy: number,\n    color: string,\n    locked: boolean\n  ): void {\n    const s = { color, width: 1.4, linecap: \"round\", linejoin: \"round\" };\n    // body\n    g.rect(11, 8)\n      .radius(1.5)\n      .move(cx - 5.5, cy - 0.5)\n      .fill(\"none\")\n      .stroke(s);\n    // shackle: closed arc when locked, open (raised/partial) when relative\n    if (locked) {\n      g.path(\n        `M ${cx - 3.4} ${cy - 0.5} v -2.2 a 3.4 3.4 0 0 1 6.8 0 v 2.2`\n      )\n        .fill(\"none\")\n        .stroke(s);\n    } else {\n      g.path(`M ${cx - 3.4} ${cy - 0.5} v -2.2 a 3.4 3.4 0 0 1 6.8 -0.6`)\n        .fill(\"none\")\n        .stroke(s);\n    }\n    // keyhole dot\n    g.circle(1.6).center(cx, cy + 3).fill(color);\n  }\n\n  public isEnabled(): boolean {\n    return this.isActive;\n  }\n\n  public updateOptions(options: Partial<ConnectorOptions>) {\n    this.options = { ...this.options, ...options };\n    console.log(\"CONNECTOR_DEBUG: Updated options for node\", this.node.id);\n  }\n}\n","/**\n * Relationship.ts - Association interface and helpers\n *\n * Defines the data model for connections between nodes,\n * matching the v1 JSON association format.\n */\n\nexport interface Association {\n  id: string;\n  parentId: string;\n  childId: string;\n  lineColor: string;\n  lineOpacity: number;\n  lineEffect: string;\n  // bezier | orthogonal | straight | linear | curved (pane + connectable)\n  lineType: string;\n  lineCurveType: \"cubic\" | \"quadratic\";\n  lineCurviness: number;\n  lineWidth: number;\n  isStraightLine: boolean;\n  showParentArrow: boolean;\n  showChildArrow: boolean;\n  // Free-floating endpoints (L1b): when an endpoint isn't attached to a node it\n  // holds a bare world point. targetPoint set ⇒ the target end floats (childId\n  // is a synthetic __free_* id); sourcePoint set ⇒ the source end floats.\n  sourcePoint?: { x: number; y: number } | null;\n  targetPoint?: { x: number; y: number } | null;\n  // Per-endpoint locking (L5): a normalized local anchor {x,y} 0..1 pins the\n  // endpoint to a fixed spot on the node (ABSOLUTE, rotates/moves with it);\n  // null = RELATIVE (auto-flow, re-solves to the nearest edge).\n  sourceAnchor?: { x: number; y: number } | null;\n  targetAnchor?: { x: number; y: number } | null;\n  // Optional text label centered on the edge (Miro-style). Empty/undefined = none.\n  label?: string;\n}\n\n/** Create a default association between two node IDs */\nexport function createDefaultAssociation(\n  parentId: string,\n  childId: string,\n  overrides?: Partial<Association>\n): Association {\n  return {\n    id: `${parentId}->${childId}`,\n    parentId,\n    childId,\n    lineColor: \"#666666\",\n    lineOpacity: 1,\n    lineEffect: \"\",\n    lineType: \"bezier\",\n    lineCurveType: \"cubic\",\n    lineCurviness: 0.1,\n    lineWidth: 3,\n    isStraightLine: false,\n    showParentArrow: false,\n    showChildArrow: true,\n    ...overrides,\n  };\n}\n","/**\n * Relationships.ts - Manages parent-child associations on a Node\n *\n * Following the isolated class pattern (like ResizeRotate, Connector):\n * - Constructor takes node and options\n * - Has enable(), disable(), serialize() methods\n * - Owned by Node, coordinates with Connector for rendering\n */\n\nimport { Association, createDefaultAssociation } from \"./Relationship\";\nimport type { Node } from \"./Node\";\nimport type { Slate } from \"./Slate\";\n\nexport interface RelationshipsOptions {\n  enabled?: boolean;\n}\n\nexport class Relationships {\n  private node: Node;\n  private slate: Slate;\n  private assocMap: Map<string, Association> = new Map();\n\n  /**\n   * v1 contract: `.associations` is a plain ARRAY whose entries carry live\n   * `parent`/`child` node references (host apps read `a.parent.options.id`\n   * and PropType it as an array). The Map stays internal.\n   */\n  public get associations(): Array<Association & { parent: any; child: any }> {\n    const slate = (this.node as any)?.slate;\n    return Array.from(this.assocMap.values()).map((a) => ({\n      ...a,\n      parent:\n        slate?.nodes?.one?.(a.parentId) ??\n        (a.parentId === this.node.id ? this.node : undefined),\n      child:\n        slate?.nodes?.one?.(a.childId) ??\n        (a.childId === this.node.id ? this.node : undefined),\n    }));\n  }\n  private isActive: boolean = false;\n\n  constructor(node: Node, options: RelationshipsOptions = {}) {\n    this.node = node;\n    this.slate = node.slate;\n    this.isActive = options.enabled ?? true;\n  }\n\n  // ─── Association management ──────────────────────────────────────\n\n  /**\n   * Add an association from this node (parent) to a child node.\n   * Creates the visual connection via the Connector system.\n   */\n  public addAssociation(\n    childNode: any,\n    data?: Partial<Association>\n  ): Association {\n    const assoc = createDefaultAssociation(this.node.id, childNode.id, data);\n\n    // Parallel edges (Miro-style): allow MORE THAN ONE line between the same pair.\n    // The first edge keeps the canonical `parent->child` id (back-compat with saved\n    // slates + collab + the reverse lookup); an additional edge to a child that's\n    // already connected gets a unique `~N` suffix so it renders as a SEPARATE line\n    // instead of being deduped away. A caller that passes an explicit id\n    // (deserialize / remote collab add) keeps that id verbatim.\n    if (!data?.id && this.assocMap.has(assoc.id)) {\n      let n = 2;\n      while (this.assocMap.has(`${assoc.id}~${n}`)) n++;\n      assoc.id = `${assoc.id}~${n}`;\n    }\n\n    // Store the association\n    this.assocMap.set(assoc.id, assoc);\n\n    // Create visual connection through Connector\n    this.renderAssociation(assoc, childNode);\n\n    // Broadcast to collaborators (suppressed during remote apply/load)\n    (this.node as any).slate?.broadcast?.(\"addRelationship\", { ...assoc });\n\n    console.log(\n      \"RELATIONSHIP_DEBUG: Added association\",\n      assoc.id,\n      \"from\",\n      this.node.id,\n      \"to\",\n      childNode.id\n    );\n\n    return assoc;\n  }\n\n  /**\n   * Remove a specific association by child node ID.\n   */\n  public removeAssociation(childIdOrAssocId: string): boolean {\n    // Accept either a specific association id (`A->B~2` → remove just that\n    // parallel edge) or a child id (`B` → remove EVERY edge to that child, so\n    // node deletion / disconnect-from-child never orphans a parallel line).\n    const direct = this.assocMap.get(childIdOrAssocId);\n    const matches = direct\n      ? [direct]\n      : Array.from(this.assocMap.values()).filter(\n          (a) => a.childId === childIdOrAssocId\n        );\n\n    if (matches.length === 0) {\n      console.warn(\n        \"RELATIONSHIP_DEBUG: Association not found:\",\n        childIdOrAssocId\n      );\n      return false;\n    }\n\n    for (const assoc of matches) {\n      // Each edge (canonical or parallel) is keyed by its unique association id\n      // in the connector, so remove by that id.\n      if (this.node.connector) {\n        this.node.connector.disconnectById(assoc.id);\n      }\n      this.assocMap.delete(assoc.id);\n      console.log(\"RELATIONSHIP_DEBUG: Removed association\", assoc.id);\n\n      // Broadcast to collaborators (suppressed during remote apply/teardown).\n      // Include the id so a peer removes the exact parallel edge, not all of them.\n      (this.node as any).slate?.broadcast?.(\"removeRelationship\", {\n        parentId: this.node.id,\n        childId: assoc.childId,\n        id: assoc.id,\n      });\n    }\n    return true;\n  }\n\n  /**\n   * Remove all associations from this node.\n   */\n  public removeAll(): void {\n    const ids = Array.from(this.assocMap.keys());\n    for (const id of ids) {\n      // Remove by the exact association id (handles parallel edges correctly).\n      this.removeAssociation(id);\n    }\n  }\n\n  /**\n   * Apply a single line property (from the line-properties pane) to one\n   * association: update the stored record (so it serializes/persists) AND\n   * re-render the connector. Used by the onLinePropertiesChanged apply path\n   * (local invoke + remote collab), which is why line edits now sync + persist.\n   */\n  public applyLineProperty(\n    associationId: string,\n    prop: string,\n    val: any\n  ): boolean {\n    let assoc = this.assocMap.get(associationId);\n    if (!assoc) {\n      for (const a of this.assocMap.values()) {\n        if (a.id === associationId) {\n          assoc = a;\n          break;\n        }\n      }\n    }\n    if (!assoc) return false;\n    // Key the connector op on the ASSOCIATION id, not the pair — else parallel\n    // edges (`A->B~2`) all collapse onto the canonical `A->B` connection, so a line\n    // property (color/width/type/lock/label) set on one parallel edge lands on (or\n    // overwrites) the wrong one. For a canonical edge assoc.id === `A->B` anyway.\n    const connId = assoc.id;\n\n    // L5 locking: prop 'sourceLock'/'targetLock' with val 'absolute'|'relative'\n    // toggles the endpoint's anchor. Persist the resolved anchor on the record.\n    if (prop === \"sourceLock\" || prop === \"targetLock\") {\n      const which = prop === \"sourceLock\" ? \"source\" : \"target\";\n      const anchor = this.node.connector?.setEndpointLock(\n        connId,\n        which,\n        val === \"absolute\" ? \"absolute\" : \"relative\"\n      );\n      (assoc as any)[which + \"Anchor\"] = anchor ?? null;\n      return true;\n    }\n\n    (assoc as any)[prop] = val;\n    // Anchor props set directly re-solve the connector; others restyle it.\n    if (prop === \"sourceAnchor\" || prop === \"targetAnchor\") {\n      const which = prop === \"sourceAnchor\" ? \"source\" : \"target\";\n      const connection = this.node.connector?.getConnections?.()\n        .find((c: any) => c.id === connId);\n      (connection as any)?.connectable?.setAttachmentAnchor?.(which, val);\n    } else {\n      this.node.connector?.updateConnection(connId, { [prop]: val } as any);\n    }\n    return true;\n  }\n\n  /**\n   * Update all associations with new options (e.g., line color change).\n   */\n  public updateAssociationsWith(opts: Partial<Association>): void {\n    for (const [id, assoc] of this.assocMap) {\n      Object.assign(assoc, opts);\n\n      // Update visual if connector supports it. Key by the association id (not the\n      // pair) so parallel edges (`A->B~2`) recolor the correct connection.\n      if (this.node.connector) {\n        this.node.connector.updateConnection(assoc.id, {\n          lineColor: assoc.lineColor,\n          lineWidth: assoc.lineWidth,\n          lineOpacity: assoc.lineOpacity,\n          lineEffect: assoc.lineEffect,\n        });\n      }\n    }\n  }\n\n  /**\n   * Refresh all visual connections (e.g., after drag/move).\n   * Called during node drag to update connector positions.\n   */\n  public refresh(): void {\n    // svg.connectable.js handles position updates automatically during drag\n    // This method is here for compatibility with v1 API\n    // and for any manual refresh needs\n    console.log(\n      \"RELATIONSHIP_DEBUG: Refreshing associations for\",\n      this.node.id\n    );\n  }\n\n  /**\n   * Refresh only this node's own relationships (as parent).\n   * Used by Invoker when line color changes.\n   */\n  public refreshOwnRelationships(): void {\n    for (const [id, assoc] of this.assocMap) {\n      const childNode = this.slate.nodes.one(assoc.childId);\n      if (childNode && this.node.connector) {\n        // Re-render the connection with current association data\n        const connId = `${this.node.id}->${assoc.childId}`;\n        this.node.connector.updateConnection(connId, {\n          lineColor: assoc.lineColor,\n          lineWidth: assoc.lineWidth,\n          lineOpacity: assoc.lineOpacity,\n          lineEffect: assoc.lineEffect,\n        });\n      }\n    }\n  }\n\n  // ─── Query methods ───────────────────────────────────────────────\n\n  /** Get all associations where this node is the parent */\n  public getAssociations(): Association[] {\n    return Array.from(this.assocMap.values());\n  }\n\n  /** Get a specific association by child ID (the canonical edge to that child) */\n  public getAssociation(childId: string): Association | undefined {\n    return this.assocMap.get(`${this.node.id}->${childId}`);\n  }\n\n  /** True if an association with this exact id exists (parallel-edge aware). */\n  public hasAssociationId(id: string): boolean {\n    return this.assocMap.has(id);\n  }\n\n  /** Check if this node has any associations */\n  public hasAssociations(): boolean {\n    return this.assocMap.size > 0;\n  }\n\n  /** Get count of associations */\n  public count(): number {\n    return this.assocMap.size;\n  }\n\n  // ─── Serialization ───────────────────────────────────────────────\n\n  /** Serialize all associations to JSON-compatible format */\n  public serialize(): { associations: Association[] } {\n    return {\n      associations: Array.from(this.assocMap.values()),\n    };\n  }\n\n  // ─── Lifecycle ───────────────────────────────────────────────────\n\n  public enable(): void {\n    this.isActive = true;\n  }\n\n  public disable(): void {\n    this.isActive = false;\n  }\n\n  public isEnabled(): boolean {\n    return this.isActive;\n  }\n\n  /** Destroy the relationships, removing all associations and clearing references */\n  public destroy(): void {\n    this.removeAll();\n    this.disable();\n    this.assocMap.clear();\n    (this as any).node = null;\n    (this as any).slate = null;\n  }\n\n  // ─── Private helpers ─────────────────────────────────────────────\n\n  private renderAssociation(assoc: Association, childNode: any): void {\n    if (!this.node.connector) return;\n\n    // Ensure connector is enabled\n    if (!this.node.connector.isEnabled()) {\n      this.node.connector.enable();\n    }\n\n    const props: any = {\n      // Drive the connection identity from the association id so parallel edges\n      // (`parent->child~N`) render as separate connections instead of colliding\n      // on the pair-based key.\n      connectionId: assoc.id,\n      lineColor: assoc.lineColor,\n      lineWidth: assoc.lineWidth,\n      lineOpacity: assoc.lineOpacity,\n      lineEffect: assoc.lineEffect,\n      lineType: (assoc as any).lineType,\n      lineCurviness: (assoc as any).lineCurviness,\n      lineCurveType: (assoc as any).lineCurveType,\n      showParentArrow: (assoc as any).showParentArrow,\n      showChildArrow: (assoc as any).showChildArrow,\n      sourceAnchor: (assoc as any).sourceAnchor,\n      targetAnchor: (assoc as any).targetAnchor,\n      label: (assoc as any).label,\n    };\n\n    // Free-floating target endpoint (L1b): connect to a bare point, not a node.\n    if ((assoc as any).targetPoint) {\n      this.node.connector.connectToPoint(\n        (assoc as any).targetPoint,\n        assoc.childId,\n        props\n      );\n      return;\n    }\n\n    if (!childNode) return;\n    // Create connection with the association's full visual properties so a\n    // saved line type / curviness / arrows render correctly (incl. on reload).\n    this.node.connector.connectTo(childNode, props);\n  }\n\n  /**\n   * Add a free-floating association whose target is a bare world point rather\n   * than a node (L1b). Backed by a phantom endpoint; broadcasts + persists like\n   * a normal association (targetPoint travels in the record).\n   */\n  public addFloatingAssociation(\n    point: { x: number; y: number },\n    data?: Partial<Association>\n  ): Association {\n    const childId =\n      (data as any)?.childId ||\n      `__free_${Math.random().toString(36).slice(2, 10)}`;\n    const assoc = createDefaultAssociation(this.node.id, childId, {\n      ...data,\n      childId,\n      targetPoint: point,\n    });\n    this.assocMap.set(assoc.id, assoc);\n    this.renderAssociation(assoc, null);\n    (this.node as any).slate?.broadcast?.(\"addRelationship\", { ...assoc });\n    return assoc;\n  }\n}\n","/**\n * Images.ts - Image fill support for nodes\n *\n * Following the isolated class pattern:\n * - Constructor takes node\n * - Has set(), clear() methods\n * - Manages image fills via SVG patterns\n */\n\nimport type { Node } from \"./Node\";\n\nexport class Images {\n  private node: Node;\n  private patternElement: any = null;\n  private imageUrl: string = \"\";\n  private origWidth: number = 0;\n  private origHeight: number = 0;\n  private preserveAspectRatio: boolean = true;\n\n  constructor(node: Node) {\n    this.node = node;\n  }\n\n  /**\n   * Set an image fill on the node's background.\n   *\n   * Uses SVG pattern fills for proper scaling within the shape.\n   */\n  public set(\n    url: string,\n    width?: number,\n    height?: number,\n    preserveAspectRatio: boolean = true\n  ): void {\n    this.imageUrl = url;\n    this.origWidth = width || this.node.options.width || 100;\n    this.origHeight = height || this.node.options.height || 60;\n    this.preserveAspectRatio = preserveAspectRatio;\n\n    // Store on node options\n    this.node.options.image = url;\n    this.node.options.imageOrigWidth = this.origWidth;\n    this.node.options.imageOrigHeight = this.origHeight;\n\n    this.render();\n  }\n\n  /**\n   * Clear the image fill and restore the background color.\n   */\n  public clear(): void {\n    if (this.patternElement) {\n      this.patternElement.remove();\n      this.patternElement = null;\n    }\n\n    this.imageUrl = \"\";\n    this.node.options.image = undefined;\n\n    // Restore solid fill on the visible shape, not the nested SVG wrapper.\n    const shape = this.node.contentPath ?? this.node.backgroundRect;\n    if (shape) {\n      shape.fill(this.node.options.backgroundColor || \"#f0f0f0\");\n    }\n  }\n\n  /** Destroy the images instance, clearing all image data */\n  public destroy(): void {\n    this.clear();\n    (this as any).node = null;\n  }\n\n  /**\n   * Update the image (e.g., after resize).\n   */\n  public update(): void {\n    if (this.imageUrl) {\n      this.render();\n    }\n  }\n\n  /** Check if an image is set */\n  public hasImage(): boolean {\n    return !!this.imageUrl;\n  }\n\n  // ─── Private ─────────────────────────────────────────────────────\n\n  private render(): void {\n    const shape = this.node.contentPath ?? this.node.backgroundRect;\n    if (!this.imageUrl || !shape) return;\n\n    try {\n      // Remove old pattern if exists\n      if (this.patternElement) {\n        this.patternElement.remove();\n      }\n\n      const w = this.node.options.width || 100;\n      const h = this.node.options.height || 60;\n\n      // Create SVG pattern with image\n      const root = this.node.svgGroup.root();\n      if (!root) return;\n\n      // Get or create defs element\n      let defs = root.defs();\n\n      // Create pattern\n      this.patternElement = defs\n        .pattern(w, h, (add: any) => {\n          add\n            .image(this.imageUrl)\n            .size(w, h)\n            .attr(\"preserveAspectRatio\", this.preserveAspectRatio ? \"xMidYMid meet\" : \"xMidYMid slice\");\n        })\n        .attr(\"patternUnits\", \"objectBoundingBox\")\n        .attr(\"width\", \"100%\")\n        .attr(\"height\", \"100%\");\n\n      // Apply pattern as fill\n      shape.fill(this.patternElement);\n\n      console.log(\n        \"IMAGES_DEBUG: Set image fill for\",\n        this.node.id,\n        \"url:\",\n        this.imageUrl\n      );\n    } catch (error) {\n      console.error(\"IMAGES_DEBUG: Failed to set image:\", error);\n    }\n  }\n}\n","/**\n * FontLoader.ts - Google Fonts loading on demand\n *\n * Loads fonts from Google Fonts API, caches loaded fonts,\n * and provides a method to scan all nodes and load unique fonts.\n */\n\nconst loadedFonts: Set<string> = new Set();\nconst pendingLoads: Map<string, Promise<void>> = new Map();\n\n// System fonts that don't need loading\nconst systemFonts = new Set([\n  \"arial\",\n  \"arial, sans-serif\",\n  \"helvetica\",\n  \"helvetica, sans-serif\",\n  \"times new roman\",\n  \"times\",\n  \"courier\",\n  \"courier new\",\n  \"georgia\",\n  \"verdana\",\n  \"tahoma\",\n  \"trebuchet ms\",\n  \"sans-serif\",\n  \"serif\",\n  \"monospace\",\n  \"cursive\",\n  \"fantasy\",\n]);\n\n/**\n * Load a single Google Font by name.\n * Idempotent — won't reload already-loaded fonts.\n */\nexport function loadFont(fontFamily: string): Promise<void> {\n  // Normalize font name\n  const normalized = fontFamily.trim();\n  const lower = normalized.toLowerCase();\n\n  // Skip system fonts\n  if (systemFonts.has(lower)) {\n    return Promise.resolve();\n  }\n\n  // Already loaded\n  if (loadedFonts.has(lower)) {\n    return Promise.resolve();\n  }\n\n  // Already loading\n  if (pendingLoads.has(lower)) {\n    return pendingLoads.get(lower)!;\n  }\n\n  const promise = new Promise<void>((resolve, reject) => {\n    if (typeof document === \"undefined\") {\n      resolve();\n      return;\n    }\n\n    // Extract just the font name (remove fallbacks like \", sans-serif\")\n    const primaryFont = normalized.split(\",\")[0].trim().replace(/['\"]/g, \"\");\n\n    // Host apps (e.g. slatebox.com via @fontsource) often bundle fonts\n    // themselves — if the face is already available, don't inject a\n    // competing Google Fonts stylesheet\n    try {\n      if (document.fonts?.check?.(`12px \"${primaryFont}\"`)) {\n        loadedFonts.add(lower);\n        resolve();\n        return;\n      }\n    } catch {\n      // document.fonts unavailable (older browsers/jsdom) — proceed to load\n    }\n\n    // Create link element for Google Fonts\n    const link = document.createElement(\"link\");\n    link.rel = \"stylesheet\";\n    link.href = `https://fonts.googleapis.com/css2?family=${encodeURIComponent(\n      primaryFont\n    )}:wght@300;400;500;600;700&display=swap`;\n\n    link.onload = () => {\n      loadedFonts.add(lower);\n      pendingLoads.delete(lower);\n      console.log(\"FONT_DEBUG: Loaded font:\", primaryFont);\n      resolve();\n    };\n\n    link.onerror = () => {\n      pendingLoads.delete(lower);\n      console.warn(\"FONT_DEBUG: Failed to load font:\", primaryFont);\n      // Resolve anyway — don't block rendering for a font failure\n      resolve();\n    };\n\n    document.head.appendChild(link);\n  });\n\n  pendingLoads.set(lower, promise);\n  return promise;\n}\n\n/**\n * Scan all nodes in a slate and load any unique fonts.\n */\nexport async function loadAllFonts(slate: any): Promise<void> {\n  const fonts = new Set<string>();\n\n  const nodes = slate.nodes?.allNodes || [];\n  for (const node of nodes) {\n    if (node.options?.fontFamily) {\n      fonts.add(node.options.fontFamily);\n    }\n  }\n\n  const promises = Array.from(fonts).map((f) => loadFont(f));\n  await Promise.all(promises);\n\n  console.log(\"FONT_DEBUG: All fonts loaded:\", Array.from(fonts));\n}\n\n/** Check if a font has been loaded */\nexport function isFontLoaded(fontFamily: string): boolean {\n  return loadedFonts.has(fontFamily.toLowerCase().trim());\n}\n","/**\n * Editor.ts - Text editing integration for nodes\n *\n * Following the isolated class pattern:\n * - Constructor takes node\n * - Has set(), get() methods\n * - Manages text content, font, alignment, and auto text offset\n */\n\nimport { loadFont } from \"./FontLoader\";\nimport type { Node } from \"./Node\";\n\nexport class Editor {\n  private node: Node;\n  private _inlineEditing = false;\n  private _inlineFO: SVGForeignObjectElement | null = null;\n\n  constructor(node: Node) {\n    this.node = node;\n  }\n\n  /** Destroy the editor, clearing all references */\n  public destroy(): void {\n    if (this._inlineEditing) this.cancelInline();\n    (this as any).node = null;\n  }\n\n  /** Whether an inline (on-canvas) edit is currently active. */\n  public isInlineEditing(): boolean {\n    return this._inlineEditing;\n  }\n\n  /**\n   * Start inline (on-canvas) text editing — Miro-style. Overlays a\n   * contenteditable box exactly on the node (inside its group so it tracks\n   * pan/zoom/position), pre-filled + all-selected. Enter commits, Shift+Enter\n   * inserts a newline, Escape cancels, blur commits.\n   *\n   * Commit routes through collab.invoke + collab.send (the same persist/sync path\n   * the drawer uses via onNodeTextChanged), so the edit survives reload and syncs\n   * to collaborators. SVG-content nodes (no textElement) are skipped.\n   */\n  public startInline(): void {\n    const node = this.node;\n    if (this._inlineEditing || !node || node.nestedSvg) return;\n    const group = (node.svgGroup as any)?.node as SVGGElement | undefined;\n    if (!group) return;\n\n    const w = node.options.width || 100;\n    const h = node.options.height || 60;\n    const SVGNS = \"http://www.w3.org/2000/svg\";\n    const fo = document.createElementNS(\n      SVGNS,\n      \"foreignObject\"\n    ) as SVGForeignObjectElement;\n    fo.setAttribute(\"x\", \"0\");\n    fo.setAttribute(\"y\", \"0\");\n    fo.setAttribute(\"width\", String(w));\n    fo.setAttribute(\"height\", String(h));\n    fo.style.overflow = \"visible\";\n\n    const div = document.createElement(\"div\");\n    div.setAttribute(\"contenteditable\", \"true\");\n    div.className = \"sb-inline-editor\";\n    div.textContent = node.options.text || \"\";\n    div.style.cssText = [\n      `width:${w}px`,\n      `height:${h}px`,\n      \"box-sizing:border-box\",\n      \"display:flex\",\n      \"align-items:center\",\n      \"justify-content:center\",\n      \"text-align:center\",\n      \"outline:none\",\n      \"padding:4px\",\n      \"cursor:text\",\n      \"word-break:break-word\",\n      \"overflow:hidden\",\n      \"white-space:pre-wrap\",\n      `font-family:${node.options.fontFamily || \"Arial, sans-serif\"}`,\n      `font-size:${node.options.fontSize || 14}px`,\n      `color:${node.options.fontColor || \"#000000\"}`,\n    ].join(\";\");\n    fo.appendChild(div);\n    group.appendChild(fo);\n    this._inlineFO = fo;\n    this._inlineEditing = true;\n    // Hide the rendered SVG text while the editor box is showing.\n    (node.textElement as any)?.hide?.();\n\n    const finish = (save: boolean) => {\n      if (!this._inlineEditing) return;\n      this._inlineEditing = false;\n      const newText = (div.innerText || \"\").replace(/\\n+$/, \"\");\n      try {\n        fo.remove();\n      } catch {\n        /* already gone */\n      }\n      this._inlineFO = null;\n      (node.textElement as any)?.show?.();\n      if (save && newText !== (node.options.text || \"\")) {\n        const pkg = {\n          type: \"onNodeTextChanged\",\n          data: { id: node.id, text: newText },\n        };\n        const slate = node.slate as any;\n        const collab = slate?.collab;\n        if (collab?.invoke) {\n          // Apply locally, then broadcast + record ONE undo checkpoint.\n          // broadcast() does collab.send AND undoRedo.snap(), so the edit syncs to\n          // collaborators and becomes its own undo step. (A plain click no longer\n          // snaps — see toFront(false) — so this yields clean stepwise undo.)\n          collab.invoke(pkg);\n          if (typeof slate.broadcast === \"function\") {\n            slate.broadcast(\"onNodeTextChanged\", pkg.data);\n          } else {\n            collab.send?.(pkg);\n          }\n        } else {\n          // No collab layer (e.g. standalone) — apply directly.\n          (node as any).setText?.(newText);\n        }\n      }\n    };\n\n    div.addEventListener(\"keydown\", (ev) => {\n      ev.stopPropagation();\n      if (ev.key === \"Enter\" && !ev.shiftKey) {\n        ev.preventDefault();\n        finish(true);\n      } else if (ev.key === \"Escape\") {\n        ev.preventDefault();\n        finish(false);\n      }\n    });\n    div.addEventListener(\"blur\", () => finish(true));\n\n    // Focus + select-all on the next tick (after it's in the DOM).\n    setTimeout(() => {\n      try {\n        div.focus();\n        const range = document.createRange();\n        range.selectNodeContents(div);\n        const sel = window.getSelection();\n        sel?.removeAllRanges();\n        sel?.addRange(range);\n      } catch {\n        /* headless */\n      }\n    }, 0);\n  }\n\n  /** Cancel an in-progress inline edit without saving. */\n  public cancelInline(): void {\n    if (!this._inlineEditing) return;\n    this._inlineEditing = false;\n    try {\n      this._inlineFO?.remove();\n    } catch {\n      /* noop */\n    }\n    this._inlineFO = null;\n    (this.node?.textElement as any)?.show?.();\n  }\n\n  /**\n   * Set text content and properties on the node.\n   * This is the primary method used by collaboration events\n   * and the text editing pane.\n   */\n  public async set(\n    text: string,\n    fontSize?: number,\n    fontFamily?: string,\n    fontColor?: string,\n    opacity?: number,\n    textXAlign?: \"left\" | \"center\" | \"right\",\n    textYAlign?: \"top\" | \"middle\" | \"bottom\"\n  ): Promise<void> {\n    // Update options\n    if (text !== undefined) this.node.options.text = text;\n    if (fontSize !== undefined) this.node.options.fontSize = fontSize;\n    if (fontColor !== undefined) this.node.options.fontColor = fontColor;\n    if (opacity !== undefined) this.node.options.textOpacity = opacity;\n    if (textXAlign !== undefined) this.node.options.textXAlign = textXAlign;\n    if (textYAlign !== undefined) this.node.options.textYAlign = textYAlign;\n\n    // Load font if changed\n    if (fontFamily !== undefined && fontFamily !== this.node.options.fontFamily) {\n      this.node.options.fontFamily = fontFamily;\n      await loadFont(fontFamily);\n    }\n\n    // Apply text changes\n    this.applyText();\n  }\n\n  /**\n   * Get current text properties.\n   */\n  public get(): {\n    text: string;\n    fontSize: number;\n    fontFamily: string;\n    fontColor: string;\n    textOpacity: number;\n    textXAlign: string;\n    textYAlign: string;\n  } {\n    return {\n      text: this.node.options.text || \"\",\n      fontSize: this.node.options.fontSize || 14,\n      fontFamily: this.node.options.fontFamily || \"Arial, sans-serif\",\n      fontColor: this.node.options.fontColor || \"#000000\",\n      textOpacity: this.node.options.textOpacity ?? 1,\n      textXAlign: this.node.options.textXAlign || \"center\",\n      textYAlign: this.node.options.textYAlign || \"middle\",\n    };\n  }\n\n  /**\n   * Calculate auto text offset based on node shape and text size.\n   */\n  public calculateAutoOffset(): { x: number; y: number } {\n    if (!this.node.textElement) {\n      return { x: 0, y: 0 };\n    }\n\n    try {\n      const textBBox = this.node.textElement.bbox();\n      const nodeWidth = this.node.options.width || 100;\n      const nodeHeight = this.node.options.height || 60;\n\n      return {\n        x: (nodeWidth - textBBox.width) / 2,\n        y: (nodeHeight - textBBox.height) / 2,\n      };\n    } catch {\n      return { x: 0, y: 0 };\n    }\n  }\n\n  // ─── Private ─────────────────────────────────────────────────────\n\n  private applyText(): void {\n    // Skip for SVG content nodes\n    if (!this.node.textElement) return;\n\n    const { text, fontSize, fontFamily, fontColor, textOpacity } =\n      this.node.options;\n\n    // Update text content\n    this.node.textElement.text(text || \"\");\n\n    // Update font properties\n    this.node.textElement.font({\n      family: fontFamily || \"Arial, sans-serif\",\n      size: fontSize || 14,\n      fill: fontColor || \"#000000\",\n      opacity: textOpacity ?? 1,\n    });\n\n    // Re-center text\n    if (typeof this.node.centerText === \"function\") {\n      this.node.centerText();\n    }\n\n    // Auto-resize if enabled\n    if (this.node.slate?.options?.autoResizeNodesBasedOnText) {\n      this.autoResize();\n    }\n  }\n\n  private autoResize(): void {\n    if (!this.node.textElement) return;\n\n    try {\n      const textBBox = this.node.textElement.bbox();\n      const padding = 20; // Minimum padding around text\n\n      const minWidth = textBBox.width + padding * 2;\n      const minHeight = textBBox.height + padding * 2;\n\n      const currentWidth = this.node.options.width || 100;\n      const currentHeight = this.node.options.height || 60;\n\n      // Only resize if text is larger than current node\n      if (minWidth > currentWidth || minHeight > currentHeight) {\n        const newWidth = Math.max(currentWidth, minWidth);\n        const newHeight = Math.max(currentHeight, minHeight);\n        this.node.setSize(newWidth, newHeight);\n      }\n    } catch {\n      // bbox may not be available in all states\n    }\n  }\n}\n","/**\n * Links.ts - Node link management (URL, currentSlate, externalSlate)\n *\n * Following the isolated class pattern.\n */\n\nimport type { NodeLinkOptions } from \"./Node\";\nimport type { Node } from \"./Node\";\n\nexport class Links {\n  private node: Node;\n  private linkData: NodeLinkOptions | null = null;\n\n  constructor(node: Node) {\n    this.node = node;\n\n    // Initialize from options if present\n    if (node.options.link?.show) {\n      this.linkData = { ...node.options.link };\n    }\n  }\n\n  /**\n   * Set a link on this node.\n   *\n   * @param linkOptions - Link configuration\n   * @param sendCollab - If true, broadcast via collaboration\n   */\n  public set(linkOptions: NodeLinkOptions, sendCollab: boolean = true): void {\n    this.linkData = {\n      show: true,\n      ...linkOptions,\n    };\n\n    // Update node options\n    this.node.options.link = { ...this.linkData };\n\n    // Refresh the on-node link badge (Miro-style indicator).\n    this.node.updateLinkIndicator?.();\n\n    console.log(\"LINKS_DEBUG: Set link on\", this.node.id, this.linkData);\n\n    // Broadcast via collab if needed\n    if (sendCollab && this.node.slate?.collab?.isCollabConnected()) {\n      this.node.slate.collab.send({\n        type: \"onNodeLinkAdded\",\n        data: {\n          id: this.node.id,\n          link: this.linkData,\n        },\n      });\n    }\n  }\n\n  /**\n   * Remove the link from this node.\n   *\n   * @param sendCollab - If true, broadcast via collaboration\n   */\n  public unset(sendCollab: boolean = true): void {\n    this.linkData = null;\n    this.node.options.link = undefined;\n\n    // Remove the on-node link badge.\n    this.node.updateLinkIndicator?.();\n\n    console.log(\"LINKS_DEBUG: Removed link from\", this.node.id);\n\n    // Broadcast via collab if needed\n    if (sendCollab && this.node.slate?.collab?.isCollabConnected()) {\n      this.node.slate.collab.send({\n        type: \"onNodeLinkRemoved\",\n        data: { id: this.node.id },\n      });\n    }\n  }\n\n  /** Get current link data */\n  public get(): NodeLinkOptions | null {\n    return this.linkData;\n  }\n\n  /** Check if a link is set */\n  public hasLink(): boolean {\n    return this.linkData?.show === true;\n  }\n\n  /** Get link type */\n  public getType(): string | undefined {\n    return this.linkData?.type;\n  }\n\n  /** Navigate to the link (opens URL or fires slate event) */\n  public navigate(): void {\n    if (!this.linkData) return;\n\n    switch (this.linkData.type) {\n      case \"url\":\n        if (this.linkData.data && typeof window !== \"undefined\") {\n          window.open(this.linkData.data, \"_blank\");\n        }\n        break;\n      case \"currentSlate\":\n      case \"externalSlate\":\n        // Delegate to app via events\n        console.log(\n          \"LINKS_DEBUG: Navigate to slate\",\n          this.linkData.data\n        );\n        break;\n    }\n  }\n\n  /** Destroy the links instance, unsetting any active link */\n  public destroy(): void {\n    if (this.linkData) {\n      this.unset(false);\n    }\n    this.linkData = null;\n    (this as any).node = null;\n  }\n}\n","/**\n * raphael-path.ts — focused TypeScript port of Raphael.js path/transform\n * helpers (parsePathString, pathToAbsolute, path2curve, transformPath).\n *\n * Ported from Raphael 2.3.0 (MIT License, Copyright (c) 2008-2013 Dmitry\n * Baranovskiy, Copyright (c) 2008-2013 Sencha Labs) to preserve the exact\n * output semantics of v1's `Slatebox.utils._transformPath(path, transform)`:\n * the input path is curve-ified (M + C commands only) and the transform\n * string uses Raphael grammar — `t/T dx,dy`, `s/S sx[,sy[,cx,cy]]`,\n * `r/R deg[,cx,cy]`, `m/M a,b,c,d,e,f` — with scale/rotate defaulting to the\n * path's bounding-box center.\n */\n\ntype PathSegment = [string, ...number[]];\nexport type PathArray = PathSegment[];\n\nconst SPACES = \"\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0 ᠎             　  \";\nconst PATH_COMMAND = new RegExp(\n  `([a-z])[${SPACES},]*((-?\\\\d*\\\\.?\\\\d*(?:e[\\\\-+]?\\\\d+)?[${SPACES}]*,?[${SPACES}]*)+)`,\n  \"ig\"\n);\nconst PATH_VALUES = new RegExp(\n  `(-?\\\\d*\\\\.?\\\\d*(?:e[\\\\-+]?\\\\d+)?)[${SPACES}]*,?[${SPACES}]*`,\n  \"ig\"\n);\nconst TRANSFORM_COMMAND = new RegExp(\n  `([rstm])[${SPACES},]*((-?\\\\d*\\\\.?\\\\d*(?:e[\\\\-+]?\\\\d+)?[${SPACES}]*,?[${SPACES}]*)+)`,\n  \"ig\"\n);\n\n/** Parse an SVG path string into Raphael's array-of-segments form. */\nexport function parsePathString(pathString: string | PathArray): PathArray {\n  if (!pathString) return [];\n  if (Array.isArray(pathString)) return pathString as PathArray;\n\n  const paramCounts: Record<string, number> = {\n    a: 7, c: 6, h: 1, l: 2, m: 2, r: 4, q: 4, s: 4, t: 2, v: 1, z: 0,\n  };\n  const data: PathArray = [];\n\n  String(pathString).replace(\n    PATH_COMMAND,\n    (_a: string, b: string, c: string) => {\n      const params: number[] = [];\n      let name = b.toLowerCase();\n      c.replace(PATH_VALUES, (_all: string, param: string) => {\n        if (param) params.push(+param);\n        return \"\";\n      });\n      if (name === \"m\" && params.length > 2) {\n        data.push([b, ...params.splice(0, 2)] as PathSegment);\n        name = \"l\";\n        b = b === \"m\" ? \"l\" : \"L\";\n      }\n      if (name === \"r\") {\n        data.push([b, ...params] as PathSegment);\n      } else {\n        while (params.length >= paramCounts[name]) {\n          data.push([b, ...params.splice(0, paramCounts[name])] as PathSegment);\n          if (!paramCounts[name]) break;\n        }\n      }\n      return \"\";\n    }\n  );\n  return data;\n}\n\n/** Convert a path to absolute coordinates. */\nexport function pathToAbsolute(pathArray: string | PathArray): PathArray {\n  const pathArr = parsePathString(pathArray as any);\n  if (!pathArr.length) return [[\"M\", 0, 0]];\n\n  const res: PathArray = [];\n  let x = 0, y = 0, mx = 0, my = 0, start = 0;\n\n  if (pathArr[0][0] === \"M\") {\n    x = +pathArr[0][1];\n    y = +pathArr[0][2];\n    mx = x;\n    my = y;\n    start++;\n    res[0] = [\"M\", x, y];\n  }\n\n  for (let i = start; i < pathArr.length; i++) {\n    const r: PathSegment = [\"\"] as any;\n    const pa = pathArr[i];\n    res.push(r);\n    if (pa[0] !== pa[0].toUpperCase()) {\n      r[0] = pa[0].toUpperCase();\n      switch (r[0]) {\n        case \"A\":\n          r[1] = pa[1] as number; r[2] = pa[2] as number; r[3] = pa[3] as number;\n          r[4] = pa[4] as number; r[5] = pa[5] as number;\n          r[6] = +(pa[6] as number) + x; r[7] = +(pa[7] as number) + y;\n          break;\n        case \"V\":\n          r[1] = +pa[1] + y;\n          break;\n        case \"H\":\n          r[1] = +pa[1] + x;\n          break;\n        case \"M\":\n          mx = +pa[1] + x;\n          my = +pa[2] + y;\n          r[1] = mx; r[2] = my;\n          break;\n        default:\n          for (let j = 1; j < pa.length; j++) {\n            r[j] = +(pa[j] as number) + (j % 2 ? x : y);\n          }\n      }\n    } else {\n      for (let k = 0; k < pa.length; k++) r[k] = pa[k] as any;\n    }\n    switch (r[0]) {\n      case \"Z\":\n        x = mx; y = my;\n        break;\n      case \"H\":\n        x = r[1] as number;\n        break;\n      case \"V\":\n        y = r[1] as number;\n        break;\n      case \"M\":\n        mx = r[r.length - 2] as number;\n        my = r[r.length - 1] as number;\n        x = r[r.length - 2] as number;\n        y = r[r.length - 1] as number;\n        break;\n      default:\n        x = r[r.length - 2] as number;\n        y = r[r.length - 1] as number;\n    }\n  }\n  return res;\n}\n\n// ─── curve conversion helpers ────────────────────────────────────────\n\nfunction l2c(x1: number, y1: number, x2: number, y2: number): number[] {\n  return [x1, y1, x2, y2, x2, y2];\n}\n\nfunction q2c(x1: number, y1: number, ax: number, ay: number, x2: number, y2: number): number[] {\n  const _13 = 1 / 3, _23 = 2 / 3;\n  return [\n    _13 * x1 + _23 * ax, _13 * y1 + _23 * ay,\n    _13 * x2 + _23 * ax, _13 * y2 + _23 * ay,\n    x2, y2,\n  ];\n}\n\nfunction rotate(x: number, y: number, rad: number): { x: number; y: number } {\n  return { x: x * Math.cos(rad) - y * Math.sin(rad), y: x * Math.sin(rad) + y * Math.cos(rad) };\n}\n\nfunction a2c(\n  x1: number, y1: number, rx: number, ry: number, angle: number,\n  largeArcFlag: number, sweepFlag: number, x2: number, y2: number,\n  recursive?: number[]\n): number[] {\n  const _120 = (Math.PI * 120) / 180;\n  const rad = (Math.PI / 180) * (+angle || 0);\n  let res: number[] = [];\n  let xy: { x: number; y: number };\n  let f1 = 0, f2 = 0, cx = 0, cy = 0;\n\n  if (!recursive) {\n    xy = rotate(x1, y1, -rad);\n    x1 = xy.x; y1 = xy.y;\n    xy = rotate(x2, y2, -rad);\n    x2 = xy.x; y2 = xy.y;\n    const x = (x1 - x2) / 2;\n    const y = (y1 - y2) / 2;\n    let h = (x * x) / (rx * rx) + (y * y) / (ry * ry);\n    if (h > 1) {\n      h = Math.sqrt(h);\n      rx = h * rx;\n      ry = h * ry;\n    }\n    const rx2 = rx * rx, ry2 = ry * ry;\n    const k =\n      (largeArcFlag === sweepFlag ? -1 : 1) *\n      Math.sqrt(Math.abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x)));\n    cx = (k * rx * y) / ry + (x1 + x2) / 2;\n    cy = (k * -ry * x) / rx + (y1 + y2) / 2;\n    f1 = Math.asin(Number(((y1 - cy) / ry).toFixed(9)));\n    f2 = Math.asin(Number(((y2 - cy) / ry).toFixed(9)));\n\n    f1 = x1 < cx ? Math.PI - f1 : f1;\n    f2 = x2 < cx ? Math.PI - f2 : f2;\n    if (f1 < 0) f1 = Math.PI * 2 + f1;\n    if (f2 < 0) f2 = Math.PI * 2 + f2;\n    if (sweepFlag && f1 > f2) f1 -= Math.PI * 2;\n    if (!sweepFlag && f2 > f1) f2 -= Math.PI * 2;\n  } else {\n    f1 = recursive[0]; f2 = recursive[1]; cx = recursive[2]; cy = recursive[3];\n  }\n\n  let df = f2 - f1;\n  if (Math.abs(df) > _120) {\n    const f2old = f2, x2old = x2, y2old = y2;\n    f2 = f1 + _120 * (sweepFlag && f2 > f1 ? 1 : -1);\n    x2 = cx + rx * Math.cos(f2);\n    y2 = cy + ry * Math.sin(f2);\n    res = a2c(x2, y2, rx, ry, angle, 0, sweepFlag, x2old, y2old, [f2, f2old, cx, cy]);\n  }\n  df = f2 - f1;\n\n  const c1 = Math.cos(f1), s1 = Math.sin(f1);\n  const c2 = Math.cos(f2), s2 = Math.sin(f2);\n  const t = Math.tan(df / 4);\n  const hx = (4 / 3) * rx * t;\n  const hy = (4 / 3) * ry * t;\n  const m1 = [x1, y1];\n  const m2 = [x1 + hx * s1, y1 - hy * c1];\n  const m3 = [x2 + hx * s2, y2 - hy * c2];\n  const m4 = [x2, y2];\n  m2[0] = 2 * m1[0] - m2[0];\n  m2[1] = 2 * m1[1] - m2[1];\n\n  if (recursive) {\n    return [m2[0], m2[1], m3[0], m3[1], m4[0], m4[1]].concat(res);\n  }\n  res = [m2[0], m2[1], m3[0], m3[1], m4[0], m4[1]].concat(res);\n  const newres: number[] = [];\n  for (let i = 0; i < res.length; i++) {\n    newres[i] =\n      i % 2\n        ? rotate(res[i - 1], res[i], rad).y\n        : rotate(res[i], res[i + 1], rad).x;\n  }\n  return newres;\n}\n\n/** Convert any path to absolute cubic-curve form (M + C segments only). */\nexport function path2curve(path: string | PathArray): PathArray {\n  const p = pathToAbsolute(path);\n  const attrs = { x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null as number | null, qy: null as number | null };\n\n  const processPath = (seg: PathSegment, d: typeof attrs, pcom: string): PathSegment => {\n    let nx: number, ny: number;\n    if (!seg) return [\"C\", d.x, d.y, d.x, d.y, d.x, d.y];\n    if (seg[0] !== \"T\" && seg[0] !== \"Q\") {\n      d.qx = null;\n      d.qy = null;\n    }\n    switch (seg[0]) {\n      case \"M\":\n        d.X = seg[1] as number;\n        d.Y = seg[2] as number;\n        break;\n      case \"A\":\n        return [\"C\", ...a2c(d.x, d.y, ...(seg.slice(1) as number[]) as [number, number, number, number, number, number, number])] as PathSegment;\n      case \"S\": {\n        let cx: number, cy: number;\n        if (pcom === \"C\" || pcom === \"S\") {\n          cx = d.x * 2 - d.bx;\n          cy = d.y * 2 - d.by;\n        } else {\n          cx = d.x;\n          cy = d.y;\n        }\n        return [\"C\", cx, cy, ...(seg.slice(1) as number[])] as PathSegment;\n      }\n      case \"T\":\n        if (pcom === \"Q\" || pcom === \"T\") {\n          d.qx = d.x * 2 - (d.qx as number);\n          d.qy = d.y * 2 - (d.qy as number);\n        } else {\n          d.qx = d.x;\n          d.qy = d.y;\n        }\n        return [\"C\", ...q2c(d.x, d.y, d.qx!, d.qy!, seg[1] as number, seg[2] as number)] as PathSegment;\n      case \"Q\":\n        d.qx = seg[1] as number;\n        d.qy = seg[2] as number;\n        return [\"C\", ...q2c(d.x, d.y, seg[1] as number, seg[2] as number, seg[3] as number, seg[4] as number)] as PathSegment;\n      case \"L\":\n        return [\"C\", ...l2c(d.x, d.y, seg[1] as number, seg[2] as number)] as PathSegment;\n      case \"H\":\n        return [\"C\", ...l2c(d.x, d.y, seg[1] as number, d.y)] as PathSegment;\n      case \"V\":\n        return [\"C\", ...l2c(d.x, d.y, d.x, seg[1] as number)] as PathSegment;\n      case \"Z\":\n        return [\"C\", ...l2c(d.x, d.y, d.X, d.Y)] as PathSegment;\n    }\n    return seg;\n  };\n\n  const fixArc = (pp: PathArray, i: number, pcoms: string[]) => {\n    if (pp[i].length > 7) {\n      pp[i].shift();\n      const pi = pp[i] as unknown as number[];\n      while (pi.length) {\n        pcoms[i] = \"A\";\n        pp.splice(i++, 0, [\"C\", ...pi.splice(0, 6)] as PathSegment);\n      }\n      pp.splice(i, 1);\n    }\n  };\n\n  const pcoms: string[] = [];\n  let pfirst = \"\";\n  let pcom = \"\";\n\n  for (let i = 0; i < p.length; i++) {\n    pfirst = \"\";\n    if (p[i]) pfirst = p[i][0];\n    if (pfirst !== \"C\") {\n      pcoms[i] = pfirst;\n      if (i) pcom = pcoms[i - 1];\n    }\n    p[i] = processPath(p[i], attrs, pcom);\n    if (pcoms[i] !== \"A\" && pfirst === \"C\") pcoms[i] = \"C\";\n    fixArc(p, i, pcoms);\n\n    const seg = p[i];\n    const seglen = seg.length;\n    attrs.x = seg[seglen - 2] as number;\n    attrs.y = seg[seglen - 1] as number;\n    attrs.bx = parseFloat(seg[seglen - 4] as any) || attrs.x;\n    attrs.by = parseFloat(seg[seglen - 3] as any) || attrs.y;\n  }\n  return p;\n}\n\n// ─── bbox ────────────────────────────────────────────────────────────\n\nfunction curveDim(\n  p1x: number, p1y: number, c1x: number, c1y: number,\n  c2x: number, c2y: number, p2x: number, p2y: number\n) {\n  const dot = (t: number, pA: number, cA: number, cB: number, pB: number) => {\n    const mt = 1 - t;\n    return mt * mt * mt * pA + 3 * mt * mt * t * cA + 3 * mt * t * t * cB + t * t * t * pB;\n  };\n\n  const xs = [p1x, p2x];\n  const ys = [p1y, p2y];\n\n  const roots = (A: number, B: number, C: number): number[] => {\n    const out: number[] = [];\n    if (Math.abs(A) < 1e-12) {\n      if (Math.abs(B) > 1e-12) {\n        const t = -C / B;\n        if (t > 0 && t < 1) out.push(t);\n      }\n    } else {\n      const disc = B * B - 4 * A * C;\n      if (disc >= 0) {\n        const sq = Math.sqrt(disc);\n        const t1 = (-B + sq) / (2 * A);\n        const t2 = (-B - sq) / (2 * A);\n        if (t1 > 0 && t1 < 1) out.push(t1);\n        if (t2 > 0 && t2 < 1) out.push(t2);\n      }\n    }\n    return out;\n  };\n\n  // dx/dt = 3[ (c1-p1) + 2(c2-2c1+p1)... ] — use standard derivative coeffs\n  const droots = (pA: number, cA: number, cB: number, pB: number): number[] => {\n    const A = 3 * (pB - 3 * cB + 3 * cA - pA);\n    const B = 6 * (cB - 2 * cA + pA);\n    const C = 3 * (cA - pA);\n    return roots(A, B, C);\n  };\n\n  droots(p1x, c1x, c2x, p2x).forEach((t) => xs.push(dot(t, p1x, c1x, c2x, p2x)));\n  droots(p1y, c1y, c2y, p2y).forEach((t) => ys.push(dot(t, p1y, c1y, c2y, p2y)));\n\n  return {\n    min: { x: Math.min(...xs), y: Math.min(...ys) },\n    max: { x: Math.max(...xs), y: Math.max(...ys) },\n  };\n}\n\nexport interface PathBBox {\n  x: number;\n  y: number;\n  x2: number;\n  y2: number;\n  width: number;\n  height: number;\n  cx: number;\n  cy: number;\n}\n\n/** Bounding box of a path (computed analytically from its curve form). */\nexport function pathBBox(path: string | PathArray): PathBBox {\n  const p = path2curve(path);\n  if (!p.length) {\n    return { x: 0, y: 0, width: 0, height: 0, x2: 0, y2: 0, cx: 0, cy: 0 };\n  }\n  let x = 0, y = 0;\n  const X: number[] = [];\n  const Y: number[] = [];\n  for (const seg of p) {\n    if (seg[0] === \"M\") {\n      x = seg[1] as number;\n      y = seg[2] as number;\n      X.push(x);\n      Y.push(y);\n    } else {\n      const dim = curveDim(x, y, ...(seg.slice(1) as number[]) as [number, number, number, number, number, number]);\n      X.push(dim.min.x, dim.max.x);\n      Y.push(dim.min.y, dim.max.y);\n      x = seg[5] as number;\n      y = seg[6] as number;\n    }\n  }\n  const xmin = Math.min(...X);\n  const ymin = Math.min(...Y);\n  const xmax = Math.max(...X);\n  const ymax = Math.max(...Y);\n  const width = xmax - xmin;\n  const height = ymax - ymin;\n  return {\n    x: xmin, y: ymin, x2: xmax, y2: ymax,\n    width, height,\n    cx: xmin + width / 2, cy: ymin + height / 2,\n  };\n}\n\n// ─── transform ───────────────────────────────────────────────────────\n\n/** Minimal affine matrix matching Raphael's Matrix semantics. */\nexport class Matrix {\n  a = 1; b = 0; c = 0; d = 1; e = 0; f = 0;\n\n  constructor(a?: number, b?: number, c?: number, d?: number, e?: number, f?: number) {\n    if (a != null) {\n      this.a = +a; this.b = +b!; this.c = +c!;\n      this.d = +d!; this.e = +e!; this.f = +f!;\n    }\n  }\n\n  add(a: number, b: number, c: number, d: number, e: number, f: number): void {\n    const m: number[][] = [\n      [this.a, this.c, this.e],\n      [this.b, this.d, this.f],\n      [0, 0, 1],\n    ];\n    const matrix: number[][] = [\n      [a, c, e],\n      [b, d, f],\n      [0, 0, 1],\n    ];\n    const out: number[][] = [[0, 0, 0], [0, 0, 0], [0, 0, 0]];\n    for (let x = 0; x < 3; x++) {\n      for (let yy = 0; yy < 3; yy++) {\n        let res = 0;\n        for (let z = 0; z < 3; z++) {\n          res += m[x][z] * matrix[z][yy];\n        }\n        out[x][yy] = res;\n      }\n    }\n    this.a = out[0][0]; this.b = out[1][0]; this.c = out[0][1];\n    this.d = out[1][1]; this.e = out[0][2]; this.f = out[1][2];\n  }\n\n  translate(x: number, y: number): void {\n    this.add(1, 0, 0, 1, x, y);\n  }\n\n  scale(x: number, y?: number, cx?: number, cy?: number): void {\n    if (y == null) y = x;\n    if (cx || cy) this.add(1, 0, 0, 1, cx || 0, cy || 0);\n    this.add(x, 0, 0, y, 0, 0);\n    if (cx || cy) this.add(1, 0, 0, 1, -(cx || 0), -(cy || 0));\n  }\n\n  rotate(a: number, x?: number, y?: number): void {\n    a = (a * Math.PI) / 180;\n    x = x || 0;\n    y = y || 0;\n    const cos = +Math.cos(a).toFixed(9);\n    const sin = +Math.sin(a).toFixed(9);\n    this.add(cos, sin, -sin, cos, x, y);\n    this.add(1, 0, 0, 1, -x, -y);\n  }\n\n  x(x: number, y: number): number {\n    return x * this.a + y * this.c + this.e;\n  }\n\n  y(x: number, y: number): number {\n    return x * this.b + y * this.d + this.f;\n  }\n}\n\n/** Parse a Raphael transform string into command segments. */\nexport function parseTransformString(tstr: string | any[]): any[] {\n  if (!tstr) return [];\n  if (Array.isArray(tstr)) return tstr;\n  const data: any[] = [];\n  String(tstr).replace(TRANSFORM_COMMAND, (_all: string, b: string, c: string) => {\n    const params: number[] = [];\n    c.replace(PATH_VALUES, (_a: string, param: string) => {\n      if (param) params.push(+param);\n      return \"\";\n    });\n    data.push([b, ...params]);\n    return \"\";\n  });\n  return data;\n}\n\n/**\n * Build the affine matrix for a transform string applied to a path (Raphael\n * `transform2matrix`): scale/rotate without explicit centers pivot on the\n * path's bounding-box center; uppercase T/S/R behave like their lowercase\n * forms here because a raw path carries no prior transform state.\n */\nexport function transform2matrix(tstr: string, bbox: PathBBox): Matrix {\n  const tdata = parseTransformString(tstr);\n  const m = new Matrix();\n  for (const t of tdata) {\n    const tlen = t.length;\n    const command = String(t[0]).toLowerCase();\n    const absolute = t[0] !== command; // uppercase\n    const inver = absolute ? new Matrix() : null;\n\n    if (command === \"t\" && tlen === 3) {\n      if (absolute) {\n        const x1 = inver!.x(0, 0);\n        const y1 = inver!.y(0, 0);\n        m.translate(t[1] - x1, t[2] - y1);\n      } else {\n        m.translate(t[1], t[2]);\n      }\n    } else if (command === \"r\") {\n      if (tlen === 2) {\n        m.rotate(t[1], bbox.x + bbox.width / 2, bbox.y + bbox.height / 2);\n      } else if (tlen === 4) {\n        if (absolute) {\n          const x2 = inver!.x(t[2], t[3]);\n          const y2 = inver!.y(t[2], t[3]);\n          m.rotate(t[1], x2, y2);\n        } else {\n          m.rotate(t[1], t[2], t[3]);\n        }\n      }\n    } else if (command === \"s\") {\n      if (tlen === 2 || tlen === 3) {\n        m.scale(t[1], t[tlen - 1], bbox.x + bbox.width / 2, bbox.y + bbox.height / 2);\n      } else if (tlen === 4) {\n        if (absolute) {\n          const x2 = inver!.x(t[2], t[3]);\n          const y2 = inver!.y(t[2], t[3]);\n          m.scale(t[1], t[1], x2, y2);\n        } else {\n          m.scale(t[1], t[1], t[2], t[3]);\n        }\n      } else if (tlen === 5) {\n        if (absolute) {\n          const x2 = inver!.x(t[3], t[4]);\n          const y2 = inver!.y(t[3], t[4]);\n          m.scale(t[1], t[2], x2, y2);\n        } else {\n          m.scale(t[1], t[2], t[3], t[4]);\n        }\n      }\n    } else if (command === \"m\" && tlen === 7) {\n      m.add(t[1], t[2], t[3], t[4], t[5], t[6]);\n    }\n  }\n  return m;\n}\n\n/** Apply an affine matrix to every coordinate of a curve-ified path. */\nexport function mapPath(path: PathArray, matrix: Matrix): PathArray {\n  if (!matrix || !path) return path;\n  const res: PathArray = [];\n  for (let i = 0; i < path.length; i++) {\n    const seg = path[i];\n    const out: PathSegment = [seg[0]] as any;\n    for (let j = 1; j < seg.length; j += 2) {\n      const x = matrix.x(seg[j] as number, seg[j + 1] as number);\n      const y = matrix.y(seg[j] as number, seg[j + 1] as number);\n      out[j] = x;\n      out[j + 1] = y;\n    }\n    res.push(out);\n  }\n  return res;\n}\n\n/**\n * Raphael.transformPath equivalent: curve-ify `path`, apply the Raphael\n * transform string, return the transformed path as a string (\"M…C…\").\n */\nexport function transformPath(path: string, tstr: string): string {\n  const curves = path2curve(path);\n  const bbox = pathBBox(curves);\n  const matrix = transform2matrix(tstr, bbox);\n  return mapPath(curves, matrix)\n    .map((seg) => seg[0] + (seg.slice(1) as number[]).join(\",\"))\n    .join(\"\");\n}\n","/**\n * utils.ts - Utility functions matching v1 Slatebox.utils\n *\n * Provides all utility functions used by the app.\n */\n\nimport { pathBBox, transformPath } from \"./vendor/raphael-path\";\n\n/** Generate a unique ID string */\nexport function guid(length: number = 10): string {\n  const chars =\n    \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";\n  let result = \"\";\n  for (let i = 0; i < length; i++) {\n    result += chars.charAt(Math.floor(Math.random() * chars.length));\n  }\n  return result;\n}\n\n/**\n * Determine whether white or black text has better contrast against the\n * given background color. Uses the v1 WCAG relative-luminance contrast\n * algorithm so drop-in results match the original library exactly.\n */\nexport function whiteOrBlack(hexColor: string): \"#ffffff\" | \"#000000\" {\n  function getRGB(c: string): number {\n    return parseInt(c, 16) || 0;\n  }\n  function getsRGB(c: string): number {\n    const v = getRGB(c) / 255;\n    return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);\n  }\n  function getLuminance(hex: string): number {\n    return (\n      0.2126 * getsRGB(hex.substr(1, 2)) +\n      0.7152 * getsRGB(hex.substr(3, 2)) +\n      0.0722 * getsRGB(hex.substr(-2))\n    );\n  }\n  function getContrast(f: string, b: string): number {\n    const L1 = getLuminance(f);\n    const L2 = getLuminance(b);\n    return (Math.max(L1, L2) + 0.05) / (Math.min(L1, L2) + 0.05);\n  }\n  const whiteContrast = getContrast(hexColor || \"#fff\", \"#ffffff\");\n  const blackContrast = getContrast(hexColor || \"#fff\", \"#000000\");\n  return whiteContrast > blackContrast ? \"#ffffff\" : \"#000000\";\n}\n\n/**\n * Measure text dimensions — v1 contract: font string is\n * `\"<style> <size>pt <family>\"` and the result is `{width, height}`\n * (multi-line aware; height accumulates per line).\n */\nexport function getTextWidth(\n  text: string,\n  font: string = \"normal 10pt Arial\"\n): { width: number; height: number } {\n  const splitText = String(text).split(\"\\n\");\n  const fontSplit = font.split(\" \");\n  const fontWeight = \"normal\";\n  const fontSize = fontSplit?.[0]?.includes(\"pt\")\n    ? parseFloat(fontSplit?.[0]?.replace(/pt/gi, \"\"))\n    : 10;\n  const fontFamily = fontSplit?.slice(1).join(\" \").trim();\n\n  if (typeof document === \"undefined\") {\n    return {\n      width: Math.max(...splitText.map((t) => t.length)) * fontSize * 0.6,\n      height: splitText.length * fontSize * 1.4 + 10,\n    };\n  }\n\n  const textWidthCanvas = document.createElement(\"canvas\");\n  const metrics: TextMetrics[] = [];\n  const multiplier = 0.98;\n  splitText.forEach((t) => {\n    const context = textWidthCanvas.getContext(\"2d\");\n    if (!context) return;\n    const calculatedFontSize = fontSize * multiplier;\n    context.font = `${fontWeight} ${calculatedFontSize}pt ${fontFamily}`;\n    metrics.push(context.measureText(t));\n  });\n  textWidthCanvas.remove();\n\n  if (metrics.length === 0) {\n    return {\n      width: Math.max(...splitText.map((t) => t.length)) * fontSize * 0.6,\n      height: splitText.length * fontSize * 1.4 + 10,\n    };\n  }\n\n  let height = 0;\n  metrics.forEach((m) => {\n    height +=\n      ((m as any).actualBoundingBoxAscent || fontSize) +\n      ((m as any).actualBoundingBoxDescent || fontSize * 0.3) +\n      5;\n  });\n  return {\n    width: Math.max(...metrics.map((m) => m.width)),\n    height: height + 10,\n  };\n}\n\n/**\n * WCAG contrast ratio between two hex colors (1 = identical, 21 = black/white).\n * Used to decide whether text is readable on a fill before auto-flipping it.\n */\nexport function contrastRatio(hex1: string, hex2: string): number {\n  const lum = (hex: string): number => {\n    const h = (hex || \"\").replace(\"#\", \"\");\n    if (h.length < 6) return 0;\n    const srgb = (c: number) => {\n      const v = c / 255;\n      return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);\n    };\n    const r = srgb(parseInt(h.substr(0, 2), 16) || 0);\n    const g = srgb(parseInt(h.substr(2, 2), 16) || 0);\n    const b = srgb(parseInt(h.substr(4, 2), 16) || 0);\n    return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n  };\n  const l1 = lum(hex1);\n  const l2 = lum(hex2);\n  return (Math.max(l1, l2) + 0.05) / (Math.min(l1, l2) + 0.05);\n}\n\n/**\n * Get the bounding box of an SVG path string — v1 contract: Raphael-style\n * bbox `{x, y, x2, y2, width, height, cx, cy}` computed analytically\n * (curves included), no DOM required.\n */\nexport function getBBox(opts: { path: string }): {\n  x: number;\n  y: number;\n  x2: number;\n  y2: number;\n  width: number;\n  height: number;\n  cx: number;\n  cy: number;\n} {\n  if (!opts?.path) {\n    return { x: 0, y: 0, x2: 100, y2: 100, width: 100, height: 100, cx: 50, cy: 50 };\n  }\n  return pathBBox(opts.path);\n}\n\n/**\n * v1: `Slatebox.utils._transformPath(path, transform)` — apply a Raphael\n * transform string (`t/T`, `s/S`, `r/R`, `m/M`) to a path, returning the\n * curve-ified transformed path string. Scale/rotate without explicit\n * centers pivot on the path's bounding-box center, exactly like Raphael.\n */\nexport function _transformPath(path: string, transform: string): string {\n  return transformPath(path, transform);\n}\n\n/**\n * Create multi-line text by wrapping at a given number of lines.\n */\nexport function createMultiLineText(text: string, lineCount: number): string {\n  const words = String(text).split(/ /g);\n  const chars = String(text).split(\"\");\n  const charsPerLine = chars.length / lineCount;\n  const lines: string[] = [];\n  let wordsOnLine: string[] = [];\n  let curCharCount = 0;\n  words.forEach((w) => {\n    curCharCount += w.length;\n    if (curCharCount < charsPerLine || lines.length === lineCount - 1) {\n      wordsOnLine.push(w);\n    } else {\n      lines.push(wordsOnLine.join(\" \"));\n      curCharCount = w.length;\n      wordsOnLine = [w];\n    }\n  });\n  if (wordsOnLine.length > 0) {\n    lines.push(wordsOnLine.join(\" \"));\n  }\n  return lines.join(\"\\n\");\n}\n\n/** Generate random integer between min and max (inclusive) */\nexport function randomInt(min: number, max: number): number {\n  return Math.floor(Math.random() * (max - min + 1)) + min;\n}\n\n/**\n * Calculate proportionate width and height for resizing,\n * preserving aspect ratio.\n */\nexport function obtainProportionateWidthAndHeightForResizing(\n  originalWidth: number,\n  originalHeight: number,\n  targetWidth: number,\n  targetHeight: number,\n  preserveAspectRatio: boolean = true\n): { width: number; height: number } {\n  if (!preserveAspectRatio) {\n    return { width: targetWidth, height: targetHeight };\n  }\n\n  const ratio = Math.min(\n    targetWidth / originalWidth,\n    targetHeight / originalHeight\n  );\n\n  return {\n    width: originalWidth * ratio,\n    height: originalHeight * ratio,\n  };\n}\n\n/**\n * Build node style from a theme definition.\n */\nexport function buildNodeStyleFromTheme(opts: {\n  theme: any;\n  childNumber: number;\n}): any {\n  // Re-export from Theme.ts for backwards compatibility\n  const { buildNodeStyleFromTheme: build } = require(\"./core/Theme\");\n  return build(opts.theme, opts.childNumber);\n}\n\n/** Make a string safe for use in URLs */\nexport function safeForUrls(str: string): string {\n  return str\n    .replace(/[^a-zA-Z0-9\\s-]/g, \"\")\n    .replace(/\\s+/g, \"-\")\n    .toLowerCase();\n}\n\n/** Check if value is a DOM element */\nexport function isElement(obj: any): boolean {\n  return obj instanceof HTMLElement || obj instanceof SVGElement;\n}\n\n/** Shorthand for document.getElementById */\nexport function el(id: string): HTMLElement | null {\n  if (typeof document === \"undefined\") return null;\n  return document.getElementById(id);\n}\n\n/** Detect Safari browser */\nexport function isSafari(): boolean {\n  if (typeof navigator === \"undefined\") return false;\n  return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n}\n\n/** Detect mobile device */\nexport function isMobile(): boolean {\n  if (typeof navigator === \"undefined\") return false;\n  return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(\n    navigator.userAgent\n  );\n}\n\n/** Stop event propagation and prevent default */\nexport function stopEvent(evt: Event): void {\n  if (evt) {\n    evt.preventDefault();\n    evt.stopPropagation();\n  }\n}\n\n/** Split an array into chunks of a given size */\nexport function chunk<T>(arr: T[], size: number): T[][] {\n  const chunks: T[][] = [];\n  for (let i = 0; i < arr.length; i += size) {\n    chunks.push(arr.slice(i, i + size));\n  }\n  return chunks;\n}\n","/** SVG-safe node animations exposed through the v1-compatible filter catalog. */\n\nexport interface AnimationDef {\n  id: string;\n  types: Array<\"text\" | \"vect\">;\n  display: string;\n  description: string;\n  isInfinite?: boolean;\n  css: string;\n}\n\nconst once = \"0.6s cubic-bezier(0.4, 0, 0.2, 1) both\";\n\nconst animationDefs: Record<string, AnimationDef> = {\n  mystery: {\n    id: \"sb-mystery\",\n    types: [\"text\", \"vect\"],\n    display: \"Mystery\",\n    description: \"Gentle fade in with a subtle zoom\",\n    css: `.sb-animation-mystery{animation:sb-mystery ${once}}@keyframes sb-mystery{0%{opacity:0;transform:scale(1.2)}50%{opacity:.5;transform:scale(1.1)}100%{opacity:1;transform:scale(1)}}`,\n  },\n  fadeSlideUp: {\n    id: \"sb-fade-slide-up\",\n    types: [\"text\", \"vect\"],\n    display: \"Fade up\",\n    description: \"Smooth upward entrance\",\n    css: `.sb-animation-fadeSlideUp{animation:sb-fade-slide-up ${once}}@keyframes sb-fade-slide-up{0%{opacity:0;transform:translateY(100%) rotateX(40deg)}100%{opacity:1;transform:translateY(0) rotateX(0)}}`,\n  },\n  fadeSlideDown: {\n    id: \"sb-fade-slide-down\",\n    types: [\"text\", \"vect\"],\n    display: \"Fade down\",\n    description: \"Smooth downward entrance\",\n    css: `.sb-animation-fadeSlideDown{animation:sb-fade-slide-down ${once}}@keyframes sb-fade-slide-down{0%{opacity:0;transform:translateY(-100%) rotateX(-40deg)}100%{opacity:1;transform:translateY(0) rotateX(0)}}`,\n  },\n  bumpUpIn: {\n    id: \"sb-bump-up-in\",\n    types: [\"text\", \"vect\"],\n    display: \"Bump up\",\n    description: \"Playful bounce from below\",\n    css: `.sb-animation-bumpUpIn{animation:sb-bump-up-in ${once}}@keyframes sb-bump-up-in{0%{opacity:0;transform:scale(.8) rotate(-3deg) translateY(100%)}55%{opacity:.8;transform:scale(1.1) rotate(2deg) translateY(-20%)}100%{opacity:1;transform:scale(1) translateY(0)}}`,\n  },\n  bumpDownIn: {\n    id: \"sb-bump-down-in\",\n    types: [\"text\", \"vect\"],\n    display: \"Bump down\",\n    description: \"Playful bounce from above\",\n    css: `.sb-animation-bumpDownIn{animation:sb-bump-down-in ${once}}@keyframes sb-bump-down-in{0%{opacity:0;transform:scale(.8) rotate(3deg) translateY(-100%)}55%{opacity:.8;transform:scale(1.1) rotate(-2deg) translateY(20%)}100%{opacity:1;transform:scale(1) translateY(0)}}`,\n  },\n  impactSlide: {\n    id: \"sb-impact-slide\",\n    types: [\"text\", \"vect\"],\n    display: \"Impact slide\",\n    description: \"Fast slide with a firm landing\",\n    css: `.sb-animation-impactSlide{animation:sb-impact-slide .6s cubic-bezier(.18,.89,.32,1.28) both}@keyframes sb-impact-slide{0%{opacity:0;transform:translateX(-200%) scale(2) skew(-25deg)}45%{opacity:1;transform:translateX(8%) scale(1.15) skew(8deg)}100%{opacity:1;transform:translateX(0) scale(1) skew(0)}}`,\n  },\n  powerSmash: {\n    id: \"sb-power-smash\",\n    types: [\"text\", \"vect\"],\n    display: \"Power smash\",\n    description: \"Dramatic drop with a spring finish\",\n    css: `.sb-animation-powerSmash{animation:sb-power-smash .6s cubic-bezier(.68,-.6,.32,1.6) both}@keyframes sb-power-smash{0%{opacity:0;transform:translateY(-150%) scale(.2)}25%{opacity:1;transform:translateY(0) scale(1.5)}55%{transform:scale(.8) rotate(-3deg)}100%{opacity:1;transform:scale(1) rotate(0)}}`,\n  },\n  torqueWarp: {\n    id: \"sb-torque-warp\",\n    types: [\"text\", \"vect\"],\n    display: \"Torque warp\",\n    description: \"Elastic horizontal twist\",\n    css: `.sb-animation-torqueWarp{animation:sb-torque-warp .6s cubic-bezier(.7,-.3,.1,1.3) both}@keyframes sb-torque-warp{0%{opacity:0;transform:translateX(-100%) scaleX(.1) skew(45deg)}45%{opacity:1;transform:translateX(10%) scaleX(1.3) skew(-12deg)}100%{opacity:1;transform:translateX(0) scaleX(1) skew(0)}}`,\n  },\n  unroll: {\n    id: \"sb-unroll\",\n    types: [\"text\", \"vect\"],\n    display: \"Unroll\",\n    description: \"Unfurls from the top\",\n    css: `.sb-animation-unroll{transform-origin:top;animation:sb-unroll .6s cubic-bezier(.33,1,.68,1) both}@keyframes sb-unroll{0%{opacity:0;transform:rotateX(-180deg) scaleY(.1)}60%{opacity:.8;transform:rotateX(-35deg) scaleY(.8)}100%{opacity:1;transform:rotateX(0) scaleY(1)}}`,\n  },\n  smoke: {\n    id: \"sb-smoke\",\n    types: [\"text\", \"vect\"],\n    display: \"Smoke\",\n    description: \"Soft blurred emergence\",\n    css: `.sb-animation-smoke{animation:sb-smoke ${once}}@keyframes sb-smoke{0%{opacity:0;transform:scale(1.5) rotate(5deg);filter:blur(10px)}55%{opacity:.75;transform:scale(1.1) rotate(-2deg);filter:blur(3px)}100%{opacity:1;transform:scale(1);filter:blur(0)}}`,\n  },\n  fractured: {\n    id: \"sb-fractured\",\n    types: [\"text\", \"vect\"],\n    display: \"Fractured\",\n    description: \"Sharp geometric reveal\",\n    css: `.sb-animation-fractured{animation:sb-fractured ${once}}@keyframes sb-fractured{0%{opacity:0;clip-path:polygon(50% 50%,50% 50%,50% 50%);transform:rotate(45deg) scale(.3)}55%{opacity:.7;clip-path:polygon(10% 0,90% 0,100% 100%,0 100%);transform:rotate(-8deg) scale(1.1)}100%{opacity:1;clip-path:polygon(0 0,100% 0,100% 100%,0 100%);transform:rotate(0) scale(1)}}`,\n  },\n  flux: {\n    id: \"sb-flux\",\n    types: [\"text\", \"vect\"],\n    display: \"Flux\",\n    description: \"Spinning elastic entrance\",\n    css: `.sb-animation-flux{animation:sb-flux .6s cubic-bezier(.68,-.6,.32,1.6) both}@keyframes sb-flux{0%{opacity:0;transform:scale(.1) rotate(180deg)}55%{opacity:.7;transform:scale(1.3) rotate(-25deg)}100%{opacity:1;transform:scale(1) rotate(0)}}`,\n  },\n  springy: {\n    id: \"sb-springy\",\n    types: [\"text\", \"vect\"],\n    display: \"Springy\",\n    description: \"Bouncy diagonal entrance\",\n    css: `.sb-animation-springy{animation:sb-springy .7s cubic-bezier(.37,0,.63,1) both}@keyframes sb-springy{0%{opacity:0;transform:scale(1.8) translate(80px,-80px)}35%{opacity:.5;transform:scale(.8) translate(-20px,20px)}70%{opacity:.8;transform:scale(1.1) translate(6px,-6px)}100%{opacity:1;transform:scale(1) translate(0,0)}}`,\n  },\n  breathe: {\n    id: \"sb-breathe-slow\",\n    types: [\"vect\"],\n    display: \"Breathe\",\n    description: \"Subtle continuous breathing\",\n    isInfinite: true,\n    css: `.sb-animation-breathe{animation:sb-breathe 4s ease-in-out infinite}@keyframes sb-breathe{0%,100%{transform:scale(1)}50%{transform:scale(1.05)}}`,\n  },\n  pulse: {\n    id: \"sb-pulse\",\n    types: [\"vect\"],\n    display: \"Pulse\",\n    description: \"Strong continuous pulse\",\n    isInfinite: true,\n    css: `.sb-animation-pulse{animation:sb-pulse .7s ease-in-out infinite}@keyframes sb-pulse{0%,100%{transform:scale(1)}50%{transform:scale(1.09)}}`,\n  },\n  rotate: {\n    id: \"sb-rotate\",\n    types: [\"vect\"],\n    display: \"Rotate\",\n    description: \"Smooth continuous rotation\",\n    isInfinite: true,\n    css: `.sb-animation-rotate{animation:sb-rotate 8s linear infinite}@keyframes sb-rotate{to{transform:rotate(360deg)}}`,\n  },\n};\n\nconst baseCss = `.sb-node-animation{transform-box:fill-box;transform-origin:center}`;\n\nexport function getAvailableAnimations(): Record<string, AnimationDef> {\n  return { ...animationDefs };\n}\n\nfunction animationClass(name: string): string {\n  return `sb-animation-${name}`;\n}\n\nexport function installAnimationStyles(element: any): void {\n  const root = element?.root?.();\n  const defs = root?.defs?.();\n  if (!defs || defs.findOne?.(\"#sb-node-animation-styles\")) return;\n  const style = defs.element(\"style\").id(\"sb-node-animation-styles\");\n  style.attr(\"type\", \"text/css\");\n  style.node.textContent = baseCss + Object.values(animationDefs).map((def) => def.css).join(\"\");\n}\n\nexport function applyAnimation(element: any, name: string): boolean {\n  if (!element || !animationDefs[name]) return false;\n  installAnimationStyles(element);\n  removeAnimations(element);\n  const dom = element.node as SVGElement | undefined;\n  // Restart finite animations when the same menu item is chosen again.\n  if (dom) {\n    void (dom as SVGGraphicsElement).getBBox?.();\n    dom.classList.add(\"sb-node-animation\", animationClass(name));\n  }\n  return true;\n}\n\nexport function removeAnimations(element: any): void {\n  const dom = element?.node as SVGElement | undefined;\n  if (!dom) return;\n  for (const name of Object.keys(animationDefs)) dom.classList.remove(animationClass(name));\n  dom.classList.remove(\"sb-node-animation\");\n}\n","/**\n * Filters.ts - SVG filter effects for nodes\n *\n * SVG.js filter equivalents for v1 Raphael effects:\n * - dropShadow, blur, outline\n * - Apply to vect (shape) and text separately\n */\n\nexport interface FilterDef {\n  name: string;\n  /** Which element types this effect can target (v1 parity: ['text','vect']). */\n  types?: string[];\n  apply: (element: any) => void;\n  remove: (element: any) => void;\n}\n\nimport type { Node } from \"./Node\";\nimport { whiteOrBlack } from \"../utils\";\nimport { applyAnimation, removeAnimations } from \"./Animations\";\n\n// ─── Built-in filter definitions ─────────────────────────────────────\n\nconst filterDefs: Map<string, FilterDef> = new Map();\n\nfilterDefs.set(\"dropShadow\", {\n  name: \"dropShadow\",\n  types: [\"text\", \"vect\", \"image\", \"line\"],\n  apply: (element: any) => {\n    try {\n      element.attr(\n        \"filter\",\n        \"drop-shadow(3px 3px 4px rgba(0,0,0,0.3))\"\n      );\n    } catch {\n      // SVG filter fallback if CSS filter not supported\n    }\n  },\n  remove: (element: any) => {\n    try {\n      element.attr(\"filter\", null);\n    } catch {}\n  },\n});\n\nfilterDefs.set(\"blur\", {\n  name: \"blur\",\n  types: [\"text\", \"vect\", \"image\", \"line\"],\n  apply: (element: any) => {\n    try {\n      element.attr(\"filter\", \"blur(2px)\");\n    } catch {}\n  },\n  remove: (element: any) => {\n    try {\n      element.attr(\"filter\", null);\n    } catch {}\n  },\n});\n\nfilterDefs.set(\"outline\", {\n  name: \"outline\",\n  types: [\"text\", \"vect\"],\n  apply: (element: any) => {\n    try {\n      // Save original stroke before changing\n      const origStroke = element.attr(\"stroke\");\n      const origStrokeWidth = element.attr(\"stroke-width\");\n      element.data(\"original-stroke\", origStroke || \"#333\");\n      element.data(\"original-stroke-width\", origStrokeWidth || 2);\n      // Outline color contrasts the element's fill so it reads as a clean halo\n      // (dark text → white outline, light text → black). Was a hardcoded #ff0000\n      // red placeholder that looked wrong on virtually any text/shape.\n      const fill = element.attr(\"fill\");\n      const outlineColor =\n        typeof fill === \"string\" && /^#[0-9a-fA-F]{3,6}$/.test(fill)\n          ? whiteOrBlack(fill)\n          : \"#ffffff\";\n      element.stroke({ color: outlineColor, width: 3 });\n      // On TEXT the stroke is painted OVER the fill by default, so a 3px stroke\n      // bleeds across the thin glyph strokes and turns the letters into an\n      // illegible blob. Paint the stroke BEHIND the fill (paint-order: stroke) so\n      // the outline reads as a clean halo. Shapes (rect/path) keep the default so\n      // their border stays a full 3px.\n      if (element.type === \"text\") {\n        element.attr(\"paint-order\", \"stroke\");\n      }\n    } catch {}\n  },\n  remove: (element: any) => {\n    try {\n      // Restore original stroke\n      element.stroke({\n        color: element.data(\"original-stroke\") || \"#333\",\n        width: element.data(\"original-stroke-width\") || 2,\n      });\n      element.attr(\"paint-order\", null);\n    } catch {}\n  },\n});\n\n// v1 parity: \"post-it note\" is a soft drop shadow (v1 built it from\n// feGaussianBlur + feOffset + feMerge); a CSS drop-shadow reproduces it.\nfilterDefs.set(\"postItNote\", {\n  name: \"postItNote\",\n  types: [\"text\", \"vect\", \"image\", \"line\"],\n  apply: (element: any) => {\n    try {\n      element.attr(\"filter\", \"drop-shadow(0 4px 2px rgba(0,0,0,0.5))\");\n    } catch {}\n  },\n  remove: (element: any) => {\n    try {\n      element.attr(\"filter\", null);\n    } catch {}\n  },\n});\n\n// v1 parity: \"pencil\" is a hand-drawn/sketch look — feTurbulence +\n// feDisplacementMap jitter the edges. CSS can't express this, so we register a\n// reusable SVG <filter> in the canvas <defs> and reference it by url.\nfilterDefs.set(\"pencil\", {\n  name: \"pencil\",\n  types: [\"text\", \"vect\", \"image\"],\n  apply: (element: any) => {\n    try {\n      const root = element.root?.();\n      const defs = root?.defs?.();\n      if (defs && !defs.findOne?.(\"#sb-pencil-filter\")) {\n        const f = defs.element(\"filter\").id(\"sb-pencil-filter\");\n        f.attr({\n          x: \"-10%\",\n          y: \"-10%\",\n          width: \"120%\",\n          height: \"120%\",\n        });\n        f.node.innerHTML =\n          '<feTurbulence type=\"fractalNoise\" baseFrequency=\"0.03\" numOctaves=\"3\" seed=\"1\" result=\"noise\"/>' +\n          '<feDisplacementMap xChannelSelector=\"R\" yChannelSelector=\"G\" scale=\"3\" in=\"SourceGraphic\" in2=\"noise\"/>';\n      }\n      element.attr(\"filter\", \"url(#sb-pencil-filter)\");\n    } catch {}\n  },\n  remove: (element: any) => {\n    try {\n      element.attr(\"filter\", null);\n    } catch {}\n  },\n});\n\n// ─── Filters class (isolated class pattern) ─────────────────────────\n\nexport class Filters {\n  private node: Node;\n  private activeFilters: Set<string> = new Set();\n  private hidden: boolean = false;\n\n  constructor(node: Node) {\n    this.node = node;\n  }\n\n  /**\n   * Apply a named filter to the node.\n   *\n   * @param filterName - Name of the filter (e.g., \"dropShadow\", \"blur\")\n   * @param target - \"vect\" for shape, \"text\" for text, or both\n   */\n  public apply(\n    filterName: string,\n    target: \"vect\" | \"text\" | \"both\" = \"both\"\n  ): void {\n    const def = filterDefs.get(filterName);\n    if (!def) {\n      console.warn(\"FILTERS_DEBUG: Unknown filter:\", filterName);\n      return;\n    }\n\n    if (target === \"vect\" || target === \"both\") {\n      if (this.node.backgroundRect) {\n        def.apply(this.node.backgroundRect);\n      }\n    }\n\n    if (target === \"text\" || target === \"both\") {\n      if (this.node.textElement) {\n        def.apply(this.node.textElement);\n      }\n    }\n\n    this.activeFilters.add(filterName);\n\n    // Store in node options\n    if (!this.node.options.filters) {\n      this.node.options.filters = {};\n    }\n    if (target === \"vect\" || target === \"both\") {\n      this.node.options.filters.vect = filterName;\n    }\n    if (target === \"text\" || target === \"both\") {\n      this.node.options.filters.text = filterName;\n    }\n\n    console.log(\n      \"FILTERS_DEBUG: Applied\",\n      filterName,\n      \"to\",\n      this.node.id,\n      \"target:\",\n      target\n    );\n  }\n\n  /**\n   * Remove a specific filter from the node.\n   */\n  public remove(filterName: string): void {\n    const def = filterDefs.get(filterName);\n    if (!def) return;\n\n    if (this.node.backgroundRect) {\n      def.remove(this.node.backgroundRect);\n    }\n    if (this.node.textElement) {\n      def.remove(this.node.textElement);\n    }\n\n    this.activeFilters.delete(filterName);\n  }\n\n  /**\n   * Remove all filters from the node.\n   */\n  public removeAll(): void {\n    for (const name of this.activeFilters) {\n      this.remove(name);\n    }\n    this.activeFilters.clear();\n  }\n\n  /** Apply one exclusive animation to a node element. */\n  public applyAnimation(\n    animationName: string,\n    target: \"vect\" | \"text\"\n  ): boolean {\n    const element = target === \"text\" ? this.node.textElement : this.node.backgroundRect;\n    if (!applyAnimation(element, animationName)) return false;\n    if (!this.node.options.animations) this.node.options.animations = {};\n    this.node.options.animations[target] = animationName;\n    return true;\n  }\n\n  /** Clear the animation from a node element without affecting filter effects. */\n  public removeAnimation(target: \"vect\" | \"text\"): void {\n    const element = target === \"text\" ? this.node.textElement : this.node.backgroundRect;\n    removeAnimations(element);\n    if (this.node.options.animations) this.node.options.animations[target] = undefined;\n  }\n\n  /**\n   * Toggle filter visibility (hide/show without removing).\n   */\n  public toggleVisibility(hide: boolean): void {\n    this.hidden = hide;\n    if (hide) {\n      // Temporarily remove all filter effects\n      for (const name of this.activeFilters) {\n        const def = filterDefs.get(name);\n        if (def) {\n          if (this.node.backgroundRect) def.remove(this.node.backgroundRect);\n          if (this.node.textElement) def.remove(this.node.textElement);\n        }\n      }\n    } else {\n      // Re-apply all active filters\n      for (const name of this.activeFilters) {\n        const def = filterDefs.get(name);\n        if (def) {\n          if (this.node.backgroundRect) def.apply(this.node.backgroundRect);\n          if (this.node.textElement) def.apply(this.node.textElement);\n        }\n      }\n    }\n  }\n\n  /** Get list of active filter names */\n  public getActive(): string[] {\n    return Array.from(this.activeFilters);\n  }\n\n  /** Check if a specific filter is active */\n  public isActive(filterName: string): boolean {\n    return this.activeFilters.has(filterName);\n  }\n\n  /** Destroy the filters instance, removing all active filters */\n  public destroy(): void {\n    this.removeAll();\n    this.activeFilters.clear();\n    this.hidden = false;\n    (this as any).node = null;\n  }\n}\n\n// ─── Registry API ────────────────────────────────────────────────────\n\n/** Register a custom filter definition */\nexport function registerFilter(def: FilterDef): void {\n  filterDefs.set(def.name, def);\n}\n\n/** Get all available filter names */\nexport function getFilterNames(): string[] {\n  return Array.from(filterDefs.keys());\n}\n\n/**\n * v1-parity shape for `slate.filters.availableFilters`: an object keyed by\n * filter name, each carrying its `types` array (which element kinds it targets).\n * The app iterates Object.keys(...) and reads `[name].types`.\n */\nexport function getAvailableFilters(): Record<string, { types: string[] }> {\n  const out: Record<string, { types: string[] }> = {};\n  for (const [name, def] of filterDefs) {\n    out[name] = { types: def.types || [\"text\", \"vect\"] };\n  }\n  return out;\n}\n","/**\n * Menu.ts - Node context menu system\n *\n * Following the isolated class pattern:\n * - Tab-based menu (color, text, shape, image, effect, AI)\n * - Configurable via node show* options\n * - Delegates to Slate events for actual UI rendering\n */\n\nexport interface MenuOptions {\n  enabled?: boolean;\n}\n\nimport type { Node } from \"./Node\";\nimport type { Slate } from \"./Slate\";\n\nexport class Menu {\n  private node: Node;\n  private slate: Slate;\n  private options: MenuOptions;\n  private isOpen: boolean = false;\n\n  constructor(node: Node, options: MenuOptions = {}) {\n    this.node = node;\n    this.slate = node.slate;\n    this.options = {\n      enabled: true,\n      ...options,\n    };\n  }\n\n  /**\n   * Open the menu for this node.\n   * Delegates to the slate's onMenuRequested event for actual UI rendering.\n   */\n  public open(): void {\n    if (!this.options.enabled) return;\n    if (this.node.options.allowMenu === false) return;\n\n    // Collect which tabs should be visible based on node options\n    const tabs = this.getVisibleTabs();\n\n    // Delegate to app via slate events\n    if (this.slate.options.events?.onMenuRequested) {\n      this.isOpen = true;\n      this.slate.options.events.onMenuRequested(this.node, (result: any) => {\n        this.isOpen = false;\n        console.log(\"MENU_DEBUG: Menu closed for\", this.node.id);\n      });\n    } else {\n      // No handler registered — don't leave isOpen stuck\n      this.isOpen = false;\n    }\n\n    console.log(\n      \"MENU_DEBUG: Menu opened for\",\n      this.node.id,\n      \"tabs:\",\n      tabs\n    );\n  }\n\n  /** Close the menu */\n  public close(): void {\n    this.isOpen = false;\n  }\n\n  /** Check if menu is currently open */\n  public isMenuOpen(): boolean {\n    return this.isOpen;\n  }\n\n  /** Get list of visible tabs based on node options */\n  public getVisibleTabs(): string[] {\n    const tabs: string[] = [];\n    const opts = this.node.options;\n\n    if (opts.showColorTab !== false) tabs.push(\"color\");\n    if (opts.showTextTab !== false) tabs.push(\"text\");\n    if (opts.showShapeTab !== false) tabs.push(\"shape\");\n    if (opts.showImageTab !== false) tabs.push(\"image\");\n    if (opts.showEffectTab !== false) tabs.push(\"effect\");\n    if (opts.showAITab !== false) tabs.push(\"ai\");\n\n    return tabs;\n  }\n\n  /** Enable/disable the menu */\n  public enable(): void {\n    this.options.enabled = true;\n  }\n\n  public disable(): void {\n    this.options.enabled = false;\n    this.close();\n  }\n\n  public isEnabled(): boolean {\n    return this.options.enabled!;\n  }\n\n  /** Destroy the menu, closing it and clearing references */\n  public destroy(): void {\n    this.close();\n    this.options.enabled = false;\n    (this as any).node = null;\n    (this as any).slate = null;\n  }\n}\n","/**\n * ShapeRegistry.ts - Named shape definitions with SVG path data\n *\n * Provides a registry of named shapes that can be used as node backgrounds.\n * Each shape provides an SVG path string, default dimensions, and metadata.\n */\n\nexport interface ShapeDefinition {\n  /** SVG path data string (d attribute) */\n  path: string;\n  /** Default width for the shape */\n  defaultWidth: number;\n  /** Default height for the shape */\n  defaultHeight: number;\n  /** Whether this shape uses rx/ry for rounded corners */\n  hasRounding?: boolean;\n  /** ViewBox for the path (minX minY width height) */\n  viewBox: string;\n}\n\n// ─── Named shape definitions ─────────────────────────────────────────\n\nconst shapes: Map<string, ShapeDefinition> = new Map();\n\n// Rectangle (basic - handled natively by SVG.js rect, but registered for completeness)\nshapes.set(\"rectangle\", {\n  path: \"M 0 0 H 100 V 60 H 0 Z\",\n  defaultWidth: 100,\n  defaultHeight: 60,\n  viewBox: \"0 0 100 60\",\n});\n\n// Rounded rectangle\nshapes.set(\"roundedrectangle\", {\n  path: \"M 10 0 H 90 Q 100 0 100 10 V 50 Q 100 60 90 60 H 10 Q 0 60 0 50 V 10 Q 0 0 10 0 Z\",\n  defaultWidth: 100,\n  defaultHeight: 60,\n  hasRounding: true,\n  viewBox: \"0 0 100 60\",\n});\n\n// Ellipse (handled natively, registered for completeness)\nshapes.set(\"ellipse\", {\n  path: \"M 50 0 A 50 30 0 1 1 50 60 A 50 30 0 1 1 50 0 Z\",\n  defaultWidth: 100,\n  defaultHeight: 60,\n  viewBox: \"0 0 100 60\",\n});\n\n// Circle (handled natively, registered for completeness)\nshapes.set(\"circle\", {\n  path: \"M 50 0 A 50 50 0 1 1 50 100 A 50 50 0 1 1 50 0 Z\",\n  defaultWidth: 100,\n  defaultHeight: 100,\n  viewBox: \"0 0 100 100\",\n});\n\n// Star (5-point)\nshapes.set(\"star\", {\n  path: \"M 50 0 L 61.8 38.2 L 100 38.2 L 69.1 61.8 L 80.9 100 L 50 76.4 L 19.1 100 L 30.9 61.8 L 0 38.2 L 38.2 38.2 Z\",\n  defaultWidth: 100,\n  defaultHeight: 100,\n  viewBox: \"0 0 100 100\",\n});\n\n// Triangle (equilateral, pointing up)\nshapes.set(\"triangle\", {\n  path: \"M 50 0 L 100 87 L 0 87 Z\",\n  defaultWidth: 100,\n  defaultHeight: 87,\n  viewBox: \"0 0 100 87\",\n});\n\n// Pentagon\nshapes.set(\"pentagon\", {\n  path: \"M 50 0 L 97.6 34.5 L 79.4 90.5 L 20.6 90.5 L 2.4 34.5 Z\",\n  defaultWidth: 100,\n  defaultHeight: 95,\n  viewBox: \"0 0 100 95\",\n});\n\n// Hexagon\nshapes.set(\"hexagon\", {\n  path: \"M 25 0 L 75 0 L 100 43.3 L 75 86.6 L 25 86.6 L 0 43.3 Z\",\n  defaultWidth: 100,\n  defaultHeight: 87,\n  viewBox: \"0 0 100 87\",\n});\n\n// Octagon\nshapes.set(\"octagon\", {\n  path: \"M 29.3 0 L 70.7 0 L 100 29.3 L 100 70.7 L 70.7 100 L 29.3 100 L 0 70.7 L 0 29.3 Z\",\n  defaultWidth: 100,\n  defaultHeight: 100,\n  viewBox: \"0 0 100 100\",\n});\n\n// Trapezium (trapezoid)\nshapes.set(\"trapezium\", {\n  path: \"M 20 0 L 80 0 L 100 60 L 0 60 Z\",\n  defaultWidth: 100,\n  defaultHeight: 60,\n  viewBox: \"0 0 100 60\",\n});\n\n// Parallelogram\nshapes.set(\"parallelogram\", {\n  path: \"M 20 0 L 100 0 L 80 60 L 0 60 Z\",\n  defaultWidth: 100,\n  defaultHeight: 60,\n  viewBox: \"0 0 100 60\",\n});\n\n// Right arrow\nshapes.set(\"rarrow\", {\n  path: \"M 0 15 L 70 15 L 70 0 L 100 30 L 70 60 L 70 45 L 0 45 Z\",\n  defaultWidth: 100,\n  defaultHeight: 60,\n  viewBox: \"0 0 100 60\",\n});\n\n// Left arrow\nshapes.set(\"larrow\", {\n  path: \"M 100 15 L 30 15 L 30 0 L 0 30 L 30 60 L 30 45 L 100 45 Z\",\n  defaultWidth: 100,\n  defaultHeight: 60,\n  viewBox: \"0 0 100 60\",\n});\n\n// Diamond / Rhombus\nshapes.set(\"diamond\", {\n  path: \"M 50 0 L 100 50 L 50 100 L 0 50 Z\",\n  defaultWidth: 100,\n  defaultHeight: 100,\n  viewBox: \"0 0 100 100\",\n});\n\n// ─── Registry API ────────────────────────────────────────────────────\n\n/** Get a shape definition by name */\nexport function getShape(name: string): ShapeDefinition | undefined {\n  return shapes.get(name.toLowerCase());\n}\n\n/** Check if a named shape exists */\nexport function hasShape(name: string): boolean {\n  return shapes.has(name.toLowerCase());\n}\n\n/** Register a custom shape */\nexport function registerShape(\n  name: string,\n  definition: ShapeDefinition\n): void {\n  shapes.set(name.toLowerCase(), definition);\n}\n\n/** Get all registered shape names */\nexport function getShapeNames(): string[] {\n  return Array.from(shapes.keys());\n}\n\n/** Check if a shape name is a \"native\" shape (rect/circle/ellipse) handled by SVG.js directly */\nexport function isNativeShape(name: string): boolean {\n  const native = [\"rectangle\", \"circle\", \"ellipse\"];\n  return native.includes(name.toLowerCase());\n}\n\n/**\n * Resolve a shape name or vectorPath to its path data.\n *\n * Logic:\n * 1. If vectorPath is a named shape key → look up in registry\n * 2. If vectorPath starts with \"M\" (SVG path) → use directly\n * 3. If shape is a named shape → look up in registry\n * 4. Otherwise → return undefined (use native rect/circle/ellipse)\n */\nexport function resolveShapePath(\n  shape?: string,\n  vectorPath?: string\n): ShapeDefinition | undefined {\n  // vectorPath takes precedence\n  if (vectorPath) {\n    // Check if it's a named shape key\n    const named = getShape(vectorPath);\n    if (named) return named;\n\n    // Check if it's a raw SVG path string\n    if (vectorPath.trim().startsWith(\"M\") || vectorPath.trim().startsWith(\"m\")) {\n      return {\n        path: vectorPath,\n        defaultWidth: 100,\n        defaultHeight: 60,\n        viewBox: \"0 0 100 60\", // Caller should recalculate from path bounds\n      };\n    }\n  }\n\n  // Fall back to shape name\n  if (shape) {\n    const named = getShape(shape);\n    if (named) return named;\n\n    // A raw SVG path passed as the shape value (the app's shape picker sends\n    // the path string as `shape`). Treat it like a vector path.\n    if (shape.trim().startsWith(\"M\") || shape.trim().startsWith(\"m\")) {\n      return {\n        path: shape,\n        defaultWidth: 100,\n        defaultHeight: 60,\n        viewBox: \"0 0 100 60\", // caller recalculates from path bounds\n      };\n    }\n  }\n\n  return undefined;\n}\n","/**\n * compat.ts - Property name adapter layer for v1 ↔ v2 compatibility\n *\n * Maps v1 property names to v2 and vice versa so that existing v1 JSON\n * data can be loaded into v2 and v2 can export in v1-compatible format.\n */\n\nimport type { NodeOptions } from \"./Node\";\nimport type { SlateOptions } from \"./Slate\";\n\n// ─── Node property mappings ──────────────────────────────────────────\n\n/** Convert v1 node JSON properties to v2 NodeOptions */\nexport function v1NodeToV2(v1: Record<string, any>): Partial<NodeOptions> {\n  const v2: Record<string, any> = { ...v1 };\n\n  // Position aliases\n  if (v1.xPos !== undefined && v2.x === undefined) {\n    v2.x = v1.xPos;\n    delete v2.xPos;\n  }\n  if (v1.yPos !== undefined && v2.y === undefined) {\n    v2.y = v1.yPos;\n    delete v2.yPos;\n  }\n\n  // Color aliases\n  if (v1.foregroundColor !== undefined && v2.fontColor === undefined) {\n    v2.fontColor = v1.foregroundColor;\n    delete v2.foregroundColor;\n  }\n\n  // Shape mapping: v1 shapeHint → v2 shape (if shape isn't already set)\n  if (v1.shapeHint !== undefined && v2.shape === undefined) {\n    v2.shape = mapShapeHintToShape(v1.shapeHint);\n    delete v2.shapeHint;\n  }\n\n  // SVG string alias\n  if (v1.svgString !== undefined && v2.svgContent === undefined) {\n    v2.svgContent = v1.svgString;\n    delete v2.svgString;\n  }\n\n  // Boolean flag: v1 uses blnStraight in associations\n  if (v1.blnStraight !== undefined) {\n    v2.isStraightLine = v1.blnStraight;\n    delete v2.blnStraight;\n  }\n\n  return v2 as Partial<NodeOptions>;\n}\n\n/** Convert v2 NodeOptions to v1 node JSON format */\nexport function v2NodeToV1(v2: Partial<NodeOptions>): Record<string, any> {\n  const v1: Record<string, any> = { ...v2 };\n\n  // Position aliases\n  v1.xPos = v2.x;\n  v1.yPos = v2.y;\n\n  // Color aliases\n  v1.foregroundColor = v2.fontColor;\n\n  // Shape mapping: v2 shape → v1 shapeHint\n  if (v2.shape) {\n    v1.shapeHint = v2.shape;\n  }\n\n  // SVG string alias\n  if (v2.svgContent) {\n    v1.svgString = v2.svgContent;\n  }\n\n  return v1;\n}\n\n// ─── Slate property mappings ─────────────────────────────────────────\n\n/** Convert v1 slate JSON options to v2 SlateOptions */\nexport function v1SlateToV2(v1: Record<string, any>): Partial<SlateOptions> {\n  const v2: Record<string, any> = { ...v1 };\n\n  // v1 uses \"container\" as string selector, v2 uses element parameter\n  // Just preserve it as-is for downstream handling\n\n  // v1's flat `showbirdsEye` / `sizeOfbirdsEye` flags drive v2's structured\n  // birdsEye options (explicit v2 birdsEye settings win)\n  if (v1.showbirdsEye !== undefined) {\n    v2.birdsEye = {\n      enabled: !!v1.showbirdsEye,\n      // Top-right by default so it doesn't collide with the host's bottom\n      // chat/huddle panel (slatebox docks those bottom-right).\n      position: \"top-right\",\n      ...(v1.sizeOfbirdsEye\n        ? { width: v1.sizeOfbirdsEye, height: v1.sizeOfbirdsEye }\n        : {}),\n      ...(v1.birdsEye || {}),\n    };\n  }\n\n  return v2 as Partial<SlateOptions>;\n}\n\n/** Convert v2 SlateOptions to v1 slate JSON format */\nexport function v2SlateToV1(v2: Partial<SlateOptions>): Record<string, any> {\n  const v1: Record<string, any> = { ...v2 };\n  return v1;\n}\n\n// ─── Association property mappings ───────────────────────────────────\n\nexport interface V1Association {\n  childId: string;\n  parentId: string;\n  isStraightLine?: boolean;\n  blnStraight?: boolean;\n  lineColor?: string;\n  lineEffect?: string;\n  lineOpacity?: number;\n  lineType?: string;\n  lineCurviness?: number;\n  lineCurveType?: string;\n  lineWidth?: number;\n  showParentArrow?: boolean;\n  showChildArrow?: boolean;\n}\n\nexport interface V2Association {\n  id?: string;\n  childId: string;\n  parentId: string;\n  isStraightLine: boolean;\n  lineColor: string;\n  lineEffect: string;\n  lineOpacity: number;\n  lineType: string;\n  lineCurveType: \"cubic\" | \"quadratic\";\n  lineCurviness: number;\n  lineWidth: number;\n  showParentArrow: boolean;\n  showChildArrow: boolean;\n  // Free-floating endpoints (L1b)\n  sourcePoint?: { x: number; y: number } | null;\n  targetPoint?: { x: number; y: number } | null;\n  sourceAnchor?: { x: number; y: number } | null;\n  targetAnchor?: { x: number; y: number } | null;\n  label?: string;\n}\n\n/** Convert v1 association to v2 format */\nexport function v1AssociationToV2(v1: Record<string, any>): V2Association {\n  return {\n    id: v1.id || `${v1.parentId}->${v1.childId}`,\n    childId: v1.childId,\n    parentId: v1.parentId,\n    isStraightLine: v1.isStraightLine ?? v1.blnStraight ?? false,\n    lineColor: v1.lineColor || \"#666666\",\n    lineEffect: v1.lineEffect || \"\",\n    lineOpacity: v1.lineOpacity ?? 1,\n    lineType: v1.lineType || \"bezier\",\n    lineCurveType: v1.lineCurveType || \"cubic\",\n    lineCurviness: v1.lineCurviness ?? 0.1,\n    lineWidth: v1.lineWidth ?? 3,\n    showParentArrow: v1.showParentArrow ?? false,\n    showChildArrow: v1.showChildArrow ?? true,\n    sourcePoint: v1.sourcePoint ?? null,\n    targetPoint: v1.targetPoint ?? null,\n    sourceAnchor: v1.sourceAnchor ?? null,\n    targetAnchor: v1.targetAnchor ?? null,\n    label: v1.label ?? \"\",\n  };\n}\n\n/** Convert v2 association to v1 format */\nexport function v2AssociationToV1(v2: V2Association): Record<string, any> {\n  return {\n    // Persist the association id so parallel edges (`A->B~2`) survive a save/reload\n    // round-trip instead of collapsing back onto the canonical `A->B` and deduping.\n    id: v2.id,\n    childId: v2.childId,\n    parentId: v2.parentId,\n    isStraightLine: v2.isStraightLine,\n    lineColor: v2.lineColor,\n    lineEffect: v2.lineEffect,\n    lineOpacity: v2.lineOpacity,\n    lineType: v2.lineType,\n    lineCurveType: v2.lineCurveType,\n    lineCurviness: v2.lineCurviness,\n    lineWidth: v2.lineWidth,\n    showParentArrow: v2.showParentArrow,\n    showChildArrow: v2.showChildArrow,\n    sourcePoint: v2.sourcePoint ?? null,\n    targetPoint: v2.targetPoint ?? null,\n    sourceAnchor: v2.sourceAnchor ?? null,\n    targetAnchor: v2.targetAnchor ?? null,\n    label: v2.label ?? \"\",\n  };\n}\n\n// ─── Shape hint mapping ──────────────────────────────────────────────\n\n/** Map v1 shapeHint string to v2 shape name */\nfunction mapShapeHintToShape(shapeHint: string): string {\n  const map: Record<string, string> = {\n    rect: \"rectangle\",\n    rectangle: \"rectangle\",\n    roundedrectangle: \"roundedrectangle\",\n    ellipse: \"ellipse\",\n    circle: \"circle\",\n    star: \"star\",\n    trapezium: \"trapezium\",\n    triangle: \"triangle\",\n    pentagon: \"pentagon\",\n    parallelogram: \"parallelogram\",\n    octagon: \"octagon\",\n    hexagon: \"hexagon\",\n    rarrow: \"rarrow\",\n    larrow: \"larrow\",\n  };\n\n  return map[shapeHint.toLowerCase()] || shapeHint;\n}\n\n// ─── Bulk conversion helpers ─────────────────────────────────────────\n\n/** Convert an entire v1 slate JSON to v2-compatible format */\nexport function convertV1JsonToV2(v1Json: any): any {\n  const v2: any = {\n    options: v1SlateToV2(v1Json.options || {}),\n    nodes: [],\n    shareId: v1Json.shareId || \"\",\n  };\n\n  if (Array.isArray(v1Json.nodes)) {\n    v2.nodes = v1Json.nodes.map((v1Node: any) => {\n      const nodeOptions = v1NodeToV2(v1Node.options || {});\n      const relationships: any = { associations: [] };\n\n      if (v1Node.relationships?.associations) {\n        relationships.associations = v1Node.relationships.associations.map(\n          (a: any) => v1AssociationToV2(a)\n        );\n      }\n\n      return {\n        options: nodeOptions,\n        relationships,\n      };\n    });\n  }\n\n  return v2;\n}\n\n/** Convert v2 slate data to v1 JSON format */\nexport function convertV2JsonToV1(v2Json: any): any {\n  const v1: any = {\n    options: v2SlateToV1(v2Json.options || {}),\n    nodes: [],\n    shareId: v2Json.shareId || \"\",\n  };\n\n  if (Array.isArray(v2Json.nodes)) {\n    v1.nodes = v2Json.nodes.map((v2Node: any) => {\n      const nodeOptions = v2NodeToV1(v2Node.options || {});\n      const relationships: any = { associations: [] };\n\n      if (v2Node.relationships?.associations) {\n        relationships.associations = v2Node.relationships.associations.map(\n          (a: any) => v2AssociationToV1(a)\n        );\n      }\n\n      return {\n        options: nodeOptions,\n        relationships,\n      };\n    });\n  }\n\n  return v1;\n}\n","import {\n  G,\n  Rect,\n  Text,\n  Element as SVGElement,\n  Circle,\n  Ellipse,\n  Path,\n} from \"@svgdotjs/svg.js\";\n\nimport \"@svgdotjs/svg.draggable.js\";\n// Outline-aware edge point (attaches to the real shape outline incl. svgContent\n// artwork) — used to make the connect-drag PREVIEW match the committed connector.\n// @ts-ignore — vendored JS module has no type declarations.\nimport { getClosestPointOnEdge } from \"../vendor/svg-connectable/utils/geometry.js\";\nimport { ResizeRotate, ResizeRotateOptions } from \"./ResizeRotate\";\nimport type { Slate } from \"./Slate\";\nimport { Connector, ConnectorOptions } from \"./Connector\";\nimport { Relationships } from \"./Relationships\";\nimport { Images } from \"./Images\";\nimport { Editor } from \"./Editor\";\nimport { Links } from \"./Links\";\nimport { Filters } from \"./Filters\";\nimport { Menu } from \"./Menu\";\nimport { resolveShapePath } from \"./ShapeRegistry\";\nimport { v2NodeToV1 } from \"./compat\";\nimport { whiteOrBlack, contrastRatio } from \"../utils\";\n\ninterface SnapRect {\n  x: number;\n  y: number;\n  width: number;\n  height: number;\n}\n\n/**\n * Smart-align a rect to a set of neighbor rects: return the position where the\n * rect's nearest edge/center (left/center/right, top/middle/bottom) lines up\n * with a neighbor's matching edge/center, within `threshold` px. Unchanged when\n * nothing is close. Pure + independently testable (drives node snap-to-objects).\n */\nexport function snapRectToNeighbors(\n  rect: SnapRect,\n  others: SnapRect[],\n  threshold = 8\n): { x: number; y: number } {\n  const { x, y, width: w, height: h } = rect;\n  const myXs = [x, x + w / 2, x + w];\n  const myYs = [y, y + h / 2, y + h];\n  let snapX = x;\n  let snapY = y;\n  let bestDX = threshold;\n  let bestDY = threshold;\n  for (const o of others) {\n    const otherXs = [o.x, o.x + o.width / 2, o.x + o.width];\n    const otherYs = [o.y, o.y + o.height / 2, o.y + o.height];\n    for (const mx of myXs) {\n      for (const oX of otherXs) {\n        const d = Math.abs(mx - oX);\n        if (d < bestDX) {\n          bestDX = d;\n          snapX = x + (oX - mx);\n        }\n      }\n    }\n    for (const my of myYs) {\n      for (const oY of otherYs) {\n        const d = Math.abs(my - oY);\n        if (d < bestDY) {\n          bestDY = d;\n          snapY = y + (oY - my);\n        }\n      }\n    }\n  }\n  return { x: snapX, y: snapY };\n}\n\nexport interface NodeLinkOptions {\n  show?: boolean;\n  type?: \"url\" | \"currentSlate\" | \"externalSlate\";\n  data?: string;\n  thumbnail?: string;\n}\n\nexport interface NodeFilterOptions {\n  vect?: string;\n  text?: string;\n}\n\nexport interface NodeAnimationOptions {\n  vect?: string;\n  text?: string;\n}\n\nexport interface NodeAIOptions {\n  textToChildNodes?: any;\n  textToImage?: any;\n}\n\nexport interface NodeOptions {\n  id: string;\n\n  // Position (v1 compat: xPos/yPos mapped via compat layer)\n  x?: number;\n  y?: number;\n\n  // Dimensions\n  width?: number;\n  height?: number;\n\n  // Identity\n  name?: string;\n  groupId?: string;\n\n  // Text content\n  text?: string;\n  fontSize?: number;\n  fontFamily?: string;\n  fontColor?: string; // v1 compat: foregroundColor mapped via compat layer\n  fontStyle?: string;\n  textOpacity?: number;\n  textXAlign?: \"left\" | \"center\" | \"right\";\n  textYAlign?: \"top\" | \"middle\" | \"bottom\";\n  textOffset?: {\n    x?: number;\n    y?: number;\n  };\n\n  // Appearance\n  backgroundColor?: string;\n  borderColor?: string;\n  borderWidth?: number;\n  borderStyle?:\n    | \"solid\"\n    | \"dashed\"\n    | \"dotted\"\n    | \"-\"\n    | \".\"\n    | \"--.\"\n    | \"combo\";\n  borderOpacity?: number;\n  borderDisplayOnly?: boolean;\n  opacity?: number;\n\n  // Shape (v1 compat: shapeHint mapped via compat layer)\n  shape?: string; // \"rectangle\" | \"circle\" | \"ellipse\" | named shapes from ShapeRegistry\n  vectorPath?: string; // SVG path string or named shape key\n  shapeHint?: string; // v1 compat: maps to shape via adapter\n\n  // SVG content\n  svgContent?: string;\n  svgString?: string; // v1 compat alias for svgContent\n\n  // Image\n  image?: string;\n  imageOrigWidth?: number;\n  imageOrigHeight?: number;\n\n  // Line properties (for connections originating from this node)\n  lineColor?: string;\n  lineOpacity?: number;\n  lineEffect?: string;\n  lineType?: \"bezier\" | \"linear\" | \"straight\";\n  lineCurveType?: \"cubic\" | \"quadratic\";\n  lineCurviness?: number;\n  lineWidth?: number;\n\n  // Behavior flags\n  allowDrag?: boolean;\n  isLocked?: boolean;\n  disableDrag?: boolean;\n  allowMenu?: boolean;\n  allowContext?: boolean;\n  allowResize?: boolean;\n\n  // Menu tab visibility\n  showDelete?: boolean;\n  showAdd?: boolean;\n  showResize?: boolean;\n  showRotate?: boolean;\n  showMenu?: boolean;\n  showColorTab?: boolean;\n  showTextTab?: boolean;\n  showAITab?: boolean;\n  showShapeTab?: boolean;\n  showImageTab?: boolean;\n  showEffectTab?: boolean;\n\n  // Relationship UI flags\n  showRelationshipConnector?: boolean;\n  showRelationshipDelete?: boolean;\n  showRelationshipProperties?: boolean;\n  showRelationshipReassign?: boolean;\n  showAddAndDeleteConditionally?: boolean;\n  spaceBetweenNodesWhenAdding?: number;\n  disableMenuAsTemplate?: boolean;\n\n  // Special node types\n  isComment?: boolean;\n  isCategory?: boolean;\n  categoryName?: string;\n  humanTouch?: boolean;\n\n  // Display helpers\n  iconFor?: string;\n  defaultShaped?: boolean;\n  pinUnderneath?: boolean;\n\n  // Rotation\n  rotate?: {\n    rotationAngle?: number;\n  };\n\n  // Sub-systems\n  resizeRotate?: ResizeRotateOptions;\n  connector?: ConnectorOptions;\n\n  // Link\n  link?: NodeLinkOptions;\n\n  // Filters & Effects\n  filters?: NodeFilterOptions;\n\n  // Animations\n  animations?: NodeAnimationOptions;\n\n  // AI\n  ai?: NodeAIOptions;\n\n  // Custom render hook\n  customRender?: (group: G, options: NodeOptions) => void;\n}\n\nexport class Node {\n  public id: string;\n  public options: NodeOptions;\n  public svgGroup!: G;\n  public backgroundRect!: Rect | Circle | Ellipse | G;\n  /**\n   * For path shapes, backgroundRect is the nested <svg> wrapper used for\n   * sizing/handles; the actual fill/stroke live on this inner <path>. Undefined\n   * only for the unknown-shape compatibility rectangle and SVG-content setup.\n   */\n  public contentPath?: any;\n  // Transparent same-size <rect> used as the svg.select/svg.resize target for\n  // path shapes (the nested <svg> backgroundRect can't be resized by the\n  // plugin). Undefined for the unknown-shape compatibility fallback.\n  public resizeTarget?: any;\n  public textElement!: Text;\n  public nestedSvg?: any; // Store reference to nested SVG for SVG content\n  public resizeRotate!: ResizeRotate;\n  public connector!: Connector;\n  public relationships!: Relationships;\n  public images!: Images;\n  public editor!: Editor;\n  public links!: Links;\n  public filters!: Filters;\n  public menu!: Menu;\n\n  // Connection handles for adding new nodes with automatic connections\n  private connectionHandles: {\n    top?: Circle;\n    right?: Circle;\n    bottom?: Circle;\n    left?: Circle;\n    container?: G;\n  } = {};\n  private connectionHandlesVisible: boolean = false;\n  // Hover-reveal (Miro-style) bookkeeping: a debounce timer so moving from the\n  // node to an offset plug-circle doesn't hide it, and a flag marking that the\n  // handles are pinned by SELECTION (so hover-leave must not hide them).\n  private _connHandleHideTimer: ReturnType<typeof setTimeout> | null = null;\n  private _connHandlesPinned: boolean = false;\n  private connectionPreview?: {\n    node?: Rect | Circle | Ellipse | any;\n    connector?: any;\n    container?: G;\n  };\n\n  public slate: Slate; // type-only import — accessed by sub-modules (Connector, Editor, etc.)\n  private isDragging: boolean = false;\n  private wasSelectedBeforeDrag: boolean = false;\n  private preDragTransform: { translateX: number; translateY: number } | null = null;\n  private preDragPosition: { x: number; y: number } | null = null;\n  // Pointer position (client coords) at drag start — drag is positioned from the\n  // pointer delta in world units so rotation never distorts the movement.\n  private _dragStartPointer: { x: number; y: number } | null = null;\n  // Other selected nodes to move together when this node is dragged as part of a\n  // multi-selection (each with its own pre-drag position).\n  private _groupDragSiblings: Array<{ node: Node; x: number; y: number }> = [];\n\n  /** Resolves when the node is fully created (SVG elements, connector, relationships, etc.) */\n  public ready: Promise<void>;\n  private _lastClickTime = 0;\n  private _resolveReady!: () => void;\n  private _rejectReady!: (reason?: unknown) => void;\n  private _initFailed: boolean = false;\n  private _destroyed: boolean = false;\n  private _svgViewboxTimeoutId: ReturnType<typeof setTimeout> | null = null;\n  private _dragEndTimeoutId: ReturnType<typeof setTimeout> | null = null;\n  private _previewViewboxTimeoutId: ReturnType<typeof setTimeout> | null = null;\n  private _connectTimeoutId: ReturnType<typeof setTimeout> | null = null;\n\n  /**\n   * Creates a new diagram node.\n   *\n   * Nodes support two mutually exclusive content types: text content (default)\n   * and SVG content (when `options.svgContent` is set). The node is created\n   * asynchronously — await `node.ready` before using sub-modules.\n   *\n   * @param options - Node configuration (position, size, shape, text, colors, etc.)\n   * @param slate  - The parent Slate instance\n   *\n   * @example\n   * ```ts\n   * const node = slate.addNode({\n   *   x: 100, y: 100, width: 120, height: 80,\n   *   text: 'Hello', shape: 'rectangle', backgroundColor: '#4ecdc4'\n   * });\n   * await node.ready;\n   * node.setRotation(45);\n   * ```\n   */\n  constructor(options: NodeOptions, slate: Slate) {\n    this.id = options.id || this.generateId();\n    this.slate = slate;\n\n    console.log(\"NODE_DEBUG: Constructor called\", { id: this.id, options });\n\n    // Default options\n    this.options = {\n      x: 50,\n      y: 50,\n      width: 100,\n      height: 60,\n      text: \"Node\",\n      fontSize: 14,\n      fontFamily: \"Arial, sans-serif\",\n      fontColor: \"#000000\",\n      textOpacity: 1,\n      textXAlign: \"center\",\n      textYAlign: \"middle\",\n      backgroundColor: \"#f0f0f0\",\n      borderColor: \"#cccccc\",\n      borderWidth: 1,\n      allowDrag: true,\n      isLocked: false,\n      shape: \"rectangle\",\n      // v1 UI-affordance defaults — host apps gate their node UI (drawer\n      // tabs, delete/add buttons, relationship controls) on these flags\n      showDelete: true,\n      showResize: true,\n      showAdd: true,\n      showRotate: true,\n      showMenu: true,\n      showColorTab: true,\n      showTextTab: true,\n      showAITab: true,\n      showShapeTab: true,\n      showImageTab: true,\n      showEffectTab: true,\n      showRelationshipConnector: true,\n      showRelationshipDelete: true,\n      showRelationshipProperties: true,\n      showRelationshipReassign: true,\n      allowMenu: true,\n      allowContext: true,\n      rotate: {\n        rotationAngle: 0,\n      },\n      textOffset: {\n        x: 0,\n        y: 0,\n      },\n      resizeRotate: {\n        resizeEnabled: true,\n        rotateEnabled: true,\n        preserveAspectRatio: false,\n        aroundCenter: false,\n        grid: 0,\n        degree: 0,\n      },\n      ...options,\n    };\n\n    this.ready = new Promise<void>((resolve, reject) => {\n      this._resolveReady = resolve;\n      this._rejectReady = reject;\n    });\n\n    console.log(\"NODE_DEBUG: Calling createAsync for\", this.id);\n    this.createAsync();\n  }\n\n  private generateId(): string {\n    return \"node_\" + Math.random().toString(36).substr(2, 9);\n  }\n\n  private async createAsync() {\n    console.log(\"NODE_DEBUG: createAsync started for\", this.id);\n\n    try {\n      // Wait for viewport to be ready, then create the node\n      const viewport = await this.slate.getViewportAsync();\n      console.log(\"NODE_DEBUG: Got viewport for\", this.id, viewport);\n\n      this.svgGroup = viewport.group();\n      // Add data-node-id attribute for test selectors\n      this.svgGroup.attr('data-node-id', this.id);\n      // Accessibility: make nodes focusable and readable by screen readers\n      this.svgGroup.node.setAttribute(\"tabindex\", \"0\");\n      this.svgGroup.node.setAttribute(\"role\", \"button\");\n      // Miro-style: a move cursor on hover signals the node is draggable (was the\n      // default arrow, which gave no affordance).\n      if (this.svgGroup.node.style) this.svgGroup.node.style.cursor = \"move\";\n      // Miro-style: reveal the connection plug-circles on hover (not just select).\n      this.wireConnectionHandleHover();\n      console.log(\"NODE_DEBUG: Created svgGroup for\", this.id, this.svgGroup);\n\n      // Continue with the rest of the creation process\n      this.finishCreate();\n    } catch (error) {\n      console.error(\"NODE_DEBUG: Error in createAsync for\", this.id, error);\n      this._initFailed = true;\n      this._rejectReady(error);\n    }\n  }\n\n  private finishCreate() {\n    console.log(\"NODE_DEBUG: finishCreate started for\", this.id);\n\n    // If svgContent is provided, use transparent background and skip default text\n    const hasSvg = !!this.options.svgContent;\n    console.log(\"NODE_DEBUG: hasSvg =\", hasSvg, \"for\", this.id);\n\n    if (hasSvg) {\n      // Force transparent background and no stroke so resize handles still work\n      this.options.backgroundColor = \"none\";\n      this.options.borderWidth = 0;\n      console.log(\"NODE_DEBUG: Updated options for SVG content\", this.id);\n    }\n\n    // Create the background shape (always needed for handles)\n    console.log(\"NODE_DEBUG: About to call createBackground for\", this.id);\n    this.createBackground();\n\n    // Create the text element only when no custom SVG\n    if (!hasSvg) {\n      console.log(\"NODE_DEBUG: About to call createText for\", this.id);\n      this.createText();\n    } else {\n      console.log(\"NODE_DEBUG: Skipping createText (SVG content) for\", this.id);\n    }\n\n    // Position the node\n    console.log(\n      \"NODE_DEBUG: About to position node\",\n      this.id,\n      \"at\",\n      this.options.x,\n      this.options.y\n    );\n    this.position(this.options.x!, this.options.y!);\n\n    // Render svgContent if provided\n    if (this.options.svgContent) {\n      const w = this.options.width!;\n      const h = this.options.height!;\n\n      // Get background rect position and match it\n      const bgX = (this.backgroundRect as any).x?.() ?? 0;\n      const bgY = (this.backgroundRect as any).y?.() ?? 0;\n\n      // Store reference to nested SVG for later resizing\n      this.nestedSvg = this.svgGroup.nested().size(w, h).move(bgX, bgY);\n      this.nestedSvg.svg(this.options.svgContent);\n\n      // Use SVG.js native viewbox method for proper scaling\n      this._svgViewboxTimeoutId = setTimeout(() => {\n        if (this._destroyed || !this.nestedSvg) return;\n        const content = this.nestedSvg.children()[0] as any;\n        if (content) {\n          // Try to get bbox first\n          let bb = content.bbox();\n          console.log(\"NODE_DEBUG: Delayed bbox:\", bb, \"Node size:\", w, h);\n\n          // If bbox is invalid, try getting path bounds from the SVG content string\n          if (bb.width <= 0 || bb.height <= 0) {\n            bb = this.calculatePathBounds(this.options.svgContent!, w, h);\n            console.log(\"NODE_DEBUG: Calculated bounds:\", bb);\n          }\n\n          if (bb.width > 0 && bb.height > 0) {\n            // Use SVG.js native viewbox method to scale content to fit\n            this.nestedSvg.viewbox(bb.x, bb.y, bb.width, bb.height);\n\n            // Custom artwork follows the node's dimensions, so an ordinary\n            // resize can stretch it. ResizeRotate uses Shift to preserve the\n            // node's ratio when that is what the user wants.\n            this.nestedSvg.node.setAttribute(\"preserveAspectRatio\", \"none\");\n\n            console.log(\n              `NODE_DEBUG: Set viewbox(${bb.x}, ${bb.y}, ${bb.width}, ${bb.height}) with preserveAspectRatio=\"none\"`\n            );\n          } else {\n            console.log(\"NODE_DEBUG: Invalid bounds, trying default viewbox approach\");\n            // Fallback: set a reasonable viewbox for typical icon content\n            this.nestedSvg.viewbox(0, 0, 24, 24);\n            this.nestedSvg.node.setAttribute(\"preserveAspectRatio\", \"none\");\n          }\n        }\n      }, 10);\n    }\n\n    // Initialize resize/rotate functionality\n    // Circles must preserve aspect ratio to stay circular\n    const resizeRotateOpts = { ...this.options.resizeRotate };\n    if (this.options.shape === \"circle\") {\n      resizeRotateOpts.preserveAspectRatio = true;\n    }\n    this.resizeRotate = new ResizeRotate(this, resizeRotateOpts);\n\n    // Initialize connector functionality\n    this.connector = new Connector(this, this.options.connector);\n\n    // Initialize relationships (parent-child association management)\n    this.relationships = new Relationships(this);\n\n    // Initialize images (image fill support)\n    this.images = new Images(this);\n\n    // Initialize editor (text editing integration)\n    this.editor = new Editor(this);\n\n    // Initialize links (URL, slate links)\n    this.links = new Links(this);\n\n    // Initialize filters (visual effects)\n    this.filters = new Filters(this);\n\n    // Initialize menu (context menu system)\n    this.menu = new Menu(this);\n\n    // Apply image if specified in options\n    if (this.options.image) {\n      this.images.set(\n        this.options.image,\n        this.options.imageOrigWidth,\n        this.options.imageOrigHeight\n      );\n    }\n\n    // Apply filters if specified in options\n    if (this.options.filters?.vect) {\n      this.filters.apply(this.options.filters.vect, \"vect\");\n    }\n    if (this.options.filters?.text) {\n      this.filters.apply(this.options.filters.text, \"text\");\n    }\n    if (this.options.animations?.vect) {\n      this.filters.applyAnimation(this.options.animations.vect, \"vect\");\n    }\n    if (this.options.animations?.text) {\n      this.filters.applyAnimation(this.options.animations.text, \"text\");\n    }\n\n    // Make draggable if allowed\n    if (this.options.allowDrag && !this.options.isLocked) {\n      this.makeDraggable();\n    }\n\n    // Set up automatic selection behavior\n    this.setupSelectionBehavior();\n\n    // Custom render hook (executes after svgContent so it can modify nested)\n    if (typeof this.options.customRender === \"function\") {\n      this.options.customRender(this.svgGroup, this.options);\n    }\n\n    if (!hasSvg) {\n      this.centerTextInitial();\n    }\n\n    // Apply initial rotation if specified in options\n    if (this.options.rotate?.rotationAngle) {\n      this.applyPositionAndRotation();\n    }\n\n    console.log(\"NODE_DEBUG: finishCreate continuing for\", this.id);\n\n    // Set initial accessibility label from node text\n    this.svgGroup.node.setAttribute(\"aria-label\", this.options.text || \"Unnamed node\");\n\n    // Keep connector arrowheads above nodes (M4): a node added after existing\n    // connections must not cover their arrowheads.\n    try {\n      (this.slate as any).markersContainer?.front?.();\n    } catch (e) {\n      /* noop */\n    }\n\n    // Show a link badge if this node carries a link (Miro-style indicator).\n    this.updateLinkIndicator();\n\n    // Signal that the node is fully created\n    this._resolveReady();\n  }\n\n  /** Small \"↗\" badge shown on a node that has a link; clicking it follows the\n   * link (Links.navigate). Rebuilt whenever the link changes (Links.set/unset).\n   * Lives inside svgGroup so it tracks the node's position/size automatically. */\n  private _linkBadge?: any;\n  public updateLinkIndicator(): void {\n    try {\n      if (this._linkBadge) {\n        this._linkBadge.remove();\n        this._linkBadge = undefined;\n      }\n      const link: any = this.options.link;\n      if (!link?.show || !link.data) return;\n      const w = this.options.width || 0;\n      const h = this.options.height || 0;\n      const R = 11;\n      // Match the comment badge: hug the shape for non-rect shapes instead of\n      // floating in the empty bbox corner.\n      let cx = w - R - 3;\n      let cy = R + 3;\n      const shp = this.options.shape;\n      if (this.contentPath || this.nestedSvg) {\n        cx = w * 0.72;\n        cy = h * 0.28;\n      } else if (shp === \"circle\" || shp === \"ellipse\") {\n        cx = w * 0.85;\n        cy = h * 0.15;\n      }\n      const badge = this.svgGroup.group();\n      badge.node.setAttribute(\"class\", \"node-link-badge\");\n      badge.node.setAttribute(\"style\", \"cursor:pointer\");\n      badge\n        .circle(R * 2)\n        .move(cx - R, cy - R)\n        .fill(\"#2d6cdf\")\n        .stroke({ color: \"#fff\", width: 1.5 });\n      // Raw <text> so x/y/anchor apply directly (SVG.js text() wraps a tspan\n      // that ignores them, mispositioning the glyph).\n      const NS = \"http://www.w3.org/2000/svg\";\n      const glyph = document.createElementNS(NS, \"text\");\n      glyph.setAttribute(\"x\", String(cx));\n      glyph.setAttribute(\"y\", String(cy));\n      glyph.setAttribute(\"text-anchor\", \"middle\");\n      glyph.setAttribute(\"dominant-baseline\", \"central\");\n      glyph.setAttribute(\"font-family\", \"sans-serif\");\n      glyph.setAttribute(\"font-size\", \"15\");\n      glyph.setAttribute(\"font-weight\", \"bold\");\n      glyph.setAttribute(\"fill\", \"#fff\");\n      glyph.setAttribute(\"pointer-events\", \"none\");\n      glyph.textContent = \"↗\";\n      badge.node.appendChild(glyph);\n      badge.on(\"click\", (e: any) => {\n        e.stopPropagation();\n        e.preventDefault?.();\n        this.links?.navigate();\n      });\n      this._linkBadge = badge;\n    } catch (e) {\n      /* noop — badge is non-critical decoration */\n    }\n  }\n\n  private createBackground() {\n    console.log(\n      \"NODE_DEBUG: createBackground called for\",\n      this.id,\n      \"shape:\",\n      this.options.shape\n    );\n\n    const {\n      width,\n      height,\n      backgroundColor,\n      borderColor,\n      borderWidth,\n      borderStyle,\n      borderOpacity,\n      shape,\n      vectorPath,\n      opacity,\n    } = this.options;\n\n    // Build stroke options. borderStyle → dasharray uses the shared mapping so\n    // the app's symbol styles ('-', '.', '--.') survive a reload (deserialize).\n    const strokeOpts: { color: string; width: number; dasharray?: string; opacity?: number } = { color: borderColor!, width: borderWidth! };\n    void borderStyle; // consumed via borderDashArray()\n    const dash = this.borderDashArray();\n    if (dash !== \"none\") {\n      strokeOpts.dasharray = dash;\n    }\n    if (borderOpacity !== undefined) {\n      strokeOpts.opacity = borderOpacity;\n    }\n\n    // Try to resolve a named shape or vector path\n    const shapeDef = resolveShapePath(shape, vectorPath);\n\n    if (shapeDef) {\n      // Render as SVG path — use a nested SVG with viewBox for proper scaling\n      const nested = this.svgGroup\n        .nested()\n        .size(width!, height!);\n\n      // Shapes occupy the complete node bounds and therefore stretch during a\n      // normal resize. A circle is the exception: its resize contract keeps it\n      // square, and `meet` also protects malformed legacy dimensions.\n      const shapeName = String(vectorPath || shape || \"\").toLowerCase();\n      if (shapeName !== \"circle\") {\n        nested.node.setAttribute(\"preserveAspectRatio\", \"none\");\n      }\n\n      const pathEl = nested\n        .path(shapeDef.path)\n        .fill(backgroundColor!)\n        .stroke(strokeOpts);\n\n      // Compute viewBox from the actual path bounds (handles absolute-coordinate paths from v1)\n      try {\n        const bb = pathEl.bbox();\n        if (bb.width > 0 && bb.height > 0) {\n          nested.viewbox(bb.x, bb.y, bb.width, bb.height);\n        } else {\n          nested.viewbox(shapeDef.viewBox);\n        }\n      } catch {\n        nested.viewbox(shapeDef.viewBox);\n      }\n\n      if (opacity !== undefined) {\n        pathEl.opacity(opacity);\n      }\n\n      // Store the nested SVG as backgroundRect for compatibility\n      // The nested element is used for bbox calculations and selection handles\n      this.backgroundRect = nested as any;\n      // The inner path carries fill/stroke — style it (not the nested wrapper).\n      this.contentPath = pathEl;\n      // Tag it so the connector geometry can attach to the ACTUAL outline (not\n      // the bounding box) for vector shapes.\n      try {\n        pathEl.node.setAttribute(\"data-node-background-path\", \"1\");\n        // SVG-content nodes draw their actual artwork in a second nested SVG.\n        // Do not advertise this invisible background path as their connector\n        // outline; geometry will select the artwork path instead.\n        if (!this.options.svgContent) {\n          pathEl.node.setAttribute(\"data-shape-path\", \"1\");\n        }\n      } catch (e) {\n        /* noop */\n      }\n      // svg.resize.js can't resize a nested <svg> target — its point()/bbox()\n      // map to the child viewBox space, so corner-drags produce ~0 delta and the\n      // shape won't resize. Give path shapes a transparent same-size <rect> as\n      // the select/resize target; setSize() syncs the nested svg on each resize\n      // frame. pointer-events:none so it never intercepts clicks/drags (the shape\n      // path + svgGroup handle those); the select/resize handles are their own\n      // layer and don't need the target to be interactive.\n      try {\n        this.resizeTarget = (this.svgGroup as any)\n          .rect(width!, height!)\n          .fill({ color: \"#000\", opacity: 0 })\n          .stroke({ width: 0 })\n          .move(0, 0);\n        this.resizeTarget.node.setAttribute(\"data-resize-proxy\", \"1\");\n        this.resizeTarget.node.style.pointerEvents = \"none\";\n      } catch (e) {\n        /* noop */\n      }\n    } else {\n      // Unknown shapes retain the compatibility rectangle fallback. All\n      // registered primitives and custom shapes use the path pipeline above.\n      this.contentPath = undefined;\n      switch (shape) {\n        case \"circle\": {\n          const radius = Math.min(width!, height!) / 2;\n          this.backgroundRect = this.svgGroup\n            .circle(radius * 2)\n            .fill(backgroundColor!)\n            .stroke(strokeOpts);\n          break;\n        }\n        case \"ellipse\":\n          this.backgroundRect = this.svgGroup\n            .ellipse(width!, height!)\n            .fill(backgroundColor!)\n            .stroke(strokeOpts);\n          break;\n        default: // rectangle\n          this.backgroundRect = this.svgGroup\n            .rect(width!, height!)\n            .fill(backgroundColor!)\n            .stroke(strokeOpts)\n            .radius(4);\n          break;\n      }\n\n      if (opacity !== undefined) {\n        this.backgroundRect.opacity(opacity);\n      }\n    }\n\n    // Re-apply the fill gradient-aware — the chained .fill() above set the raw\n    // string, so a v1 \"colorA-colorB\" gradient would have rendered black.\n    if (backgroundColor && String(backgroundColor).includes(\"-\")) {\n      this.applyShapeFill(this.contentPath ?? this.backgroundRect, backgroundColor);\n    }\n\n    console.log(\n      \"NODE_DEBUG: createBackground completed for\",\n      this.id,\n      \"backgroundRect:\",\n      this.backgroundRect\n    );\n  }\n\n  /**\n   * Change the node's shape at runtime (U5). `shape` may be a named shape or a\n   * raw SVG path string. Removes the old shape element, re-renders the new one\n   * behind the text/content, and re-binds selection so resize/rotate follow the\n   * new shape. No-op for SVG-content nodes.\n   */\n  public setShape(shape: string, vectorPath?: string): void {\n    if (!this.svgGroup || this.nestedSvg) return; // SVG-content nodes have no shape\n    const wasSelected =\n      !!this.resizeRotate && this.resizeRotate.isEnabled();\n    try {\n      if (wasSelected) this.resizeRotate.disable();\n    } catch (e) {\n      /* noop */\n    }\n    try {\n      (this.backgroundRect as any)?.remove?.();\n    } catch (e) {\n      /* noop */\n    }\n    this.backgroundRect = undefined as any;\n    this.contentPath = undefined;\n    try {\n      this.resizeTarget?.remove?.();\n    } catch (e) {\n      /* noop */\n    }\n    this.resizeTarget = undefined;\n\n    this.options.shape = shape;\n    // Sync vectorPath to THIS shape change (default it to `shape` when no explicit\n    // vectorPath is given). Two things matter here:\n    //  1. It must never be a STALE value — a leftover vectorPath (e.g. the default\n    //     node's \"rectangle\") would override the new shape via resolveShapePath()\n    //     and render the OLD one (\"I changed the shape but it stayed a rectangle\").\n    //  2. It must REFLECT the current shape — the app's Shape tab reads\n    //     options.vectorPath to highlight the active swatch, so clearing it left the\n    //     tab unable to show which shape is selected after a change.\n    // Defaulting to `shape` satisfies both: vectorPath always equals the current\n    // shape (never stale), and the pane can read it. (resolveShapePath prioritizes\n    // vectorPath, but it now holds the same value as `shape`, so the render is\n    // identical.)\n    this.options.vectorPath = vectorPath ?? shape;\n\n    this.createBackground();\n    // Keep the shape behind the text and any other content.\n    try {\n      (this.backgroundRect as any)?.back?.();\n    } catch (e) {\n      /* noop */\n    }\n    try {\n      this.centerText();\n    } catch (e) {\n      /* noop */\n    }\n    this.applyPositionAndRotation();\n    // Re-bind resize/rotate + handles to the new shape via the orchestrator.\n    try {\n      if (wasSelected) this.slate?.updateSelectionResizeRotate?.();\n    } catch (e) {\n      /* noop */\n    }\n  }\n\n  private createText() {\n    console.log(\"NODE_DEBUG: createText called for\", this.id);\n\n    const { text, fontSize, fontFamily, fontColor, fontStyle, textOpacity } =\n      this.options;\n\n    this.textElement = this.svgGroup.text(this.wrapTextToWidth(text!)).font({\n      family: fontFamily!,\n      size: fontSize!,\n      fill: fontColor!,\n      opacity: textOpacity!,\n    });\n\n    // Use SVG native text anchoring for reliable centering\n    this.textElement.attr({\n      'text-anchor': 'middle',\n      'dominant-baseline': 'central',\n      'font-style': fontStyle || null,\n    });\n\n    console.log(\n      \"NODE_DEBUG: createText completed for\",\n      this.id,\n      \"textElement:\",\n      this.textElement\n    );\n    this.centerText();\n    this.fitHeightToText();\n  }\n\n  /**\n   * Apply the node's fill opacity (options.opacity) to the shape element. Mirrors\n   * what createBackground does on load, for the edit path (color pane opacity\n   * slider), which otherwise only updated options.\n   */\n  public applyOpacity(): void {\n    const el: any = this.contentPath ?? this.backgroundRect;\n    if (el?.opacity && this.options.opacity !== undefined) {\n      el.opacity(this.options.opacity);\n    }\n  }\n\n  /**\n   * Re-apply font (size / family / color / opacity) from options to the text\n   * element and re-center for alignment. The text pane sends font changes via\n   * onNodeTextChanged; without this they only updated options, never the render.\n   */\n  public applyTextStyle(): void {\n    if (!this.textElement) return;\n    const { fontSize, fontFamily, fontColor, fontStyle, textOpacity } =\n      this.options;\n    this.textElement.font({\n      family: fontFamily!,\n      size: fontSize!,\n      fill: fontColor!,\n      opacity: textOpacity!,\n    });\n    this.textElement.attr(\"font-style\", fontStyle || null);\n    // Re-wrap with the new font metrics — a larger font fits fewer words per line,\n    // so without this the text would overflow the node after a size change.\n    if (this.options.text) {\n      this.textElement.text(this.wrapTextToWidth(this.options.text));\n    }\n    this.centerText();\n  }\n\n  /**\n   * \"Snap to neighbors\" (Miro smart-align): nudge (x, y) so one of this node's\n   * edges or center lines up with a nearby node's matching edge/center. Gated by\n   * the caller on viewPort.snapToObjects.\n   */\n  private snapToNeighbors(x: number, y: number): { x: number; y: number } {\n    const rect = {\n      x,\n      y,\n      width: this.options.width || 0,\n      height: this.options.height || 0,\n    };\n    const others = this.slate.nodes.allNodes\n      .filter((n: Node) => n !== this)\n      .map((n: Node) => ({\n        x: n.options.x || 0,\n        y: n.options.y || 0,\n        width: n.options.width || 0,\n        height: n.options.height || 0,\n      }));\n    return snapRectToNeighbors(rect, others);\n  }\n\n  /**\n   * Word-wrap `text` to the node's inner width, returning it with newlines\n   * inserted at break points (SVG.js renders one tspan per line). Explicit\n   * newlines are preserved; a single word longer than the width stays on its own\n   * line rather than being split mid-word. Falls back to a character estimate\n   * when canvas measurement isn't available.\n   */\n  /**\n   * Fraction of the bounding box usable for text, by shape. Tapering shapes\n   * (diamond, triangle, star) have a much smaller INSCRIBED area than their\n   * bounding box, so text laid out to the full width spills past the angled\n   * edges (e.g. a diamond's usable width is roughly half its bbox). Rectangles\n   * use the full box. Applied to BOTH wrap width and fit scale so text wraps +\n   * shrinks to stay inside the actual shape, not just its bounding rect.\n   */\n  private shapeTextInset(): number {\n    const shape = String(this.options.shape || \"rectangle\").toLowerCase();\n    if (shape.includes(\"diamond\")) return 0.6;\n    if (shape.includes(\"triangle\")) return 0.55;\n    if (shape.includes(\"star\")) return 0.5;\n    if (shape.includes(\"ellipse\") || shape.includes(\"circle\")) return 0.82;\n    return 1;\n  }\n\n  private wrapTextToWidth(text: string): string {\n    if (!text) return text;\n    const maxWidth = Math.max(\n      24,\n      (this.options.width || 100) * this.shapeTextInset() - 14\n    );\n    const fontSize = this.options.fontSize || 14;\n    const fontFamily = this.options.fontFamily || \"sans-serif\";\n    let ctx: any = null;\n    try {\n      const canvas =\n        (this as any)._measureCanvas ||\n        ((this as any)._measureCanvas = document.createElement(\"canvas\"));\n      ctx = canvas.getContext(\"2d\");\n      if (ctx) ctx.font = `${fontSize}px ${fontFamily}`;\n    } catch (e) {\n      ctx = null;\n    }\n    const measure = (s: string) =>\n      ctx ? ctx.measureText(s).width : s.length * fontSize * 0.55;\n    const out: string[] = [];\n    for (const para of String(text).split(\"\\n\")) {\n      const words = para.split(/\\s+/).filter(Boolean);\n      if (!words.length) {\n        out.push(\"\");\n        continue;\n      }\n      let line = \"\";\n      for (const word of words) {\n        // A single word wider than the line (e.g. a long URL) → hard-break it into\n        // character chunks so it can't overflow the node.\n        if (measure(word) > maxWidth) {\n          if (line) {\n            out.push(line);\n            line = \"\";\n          }\n          let chunk = \"\";\n          for (const ch of word) {\n            if (chunk && measure(chunk + ch) > maxWidth) {\n              out.push(chunk);\n              chunk = ch;\n            } else {\n              chunk += ch;\n            }\n          }\n          line = chunk;\n          continue;\n        }\n        const test = line ? `${line} ${word}` : word;\n        if (line && measure(test) > maxWidth) {\n          out.push(line);\n          line = word;\n        } else {\n          line = test;\n        }\n      }\n      if (line) out.push(line);\n    }\n    return out.join(\"\\n\");\n  }\n\n  /**\n   * Grow the node's height so wrapped text fits inside it (Miro-style: nodes\n   * grow to fit typed content). Only ever grows — never shrinks — to avoid\n   * jumpiness when text is removed. Derived from the text, so it's re-applied on\n   * load without needing to be persisted separately. No-op in headless tests\n   * where getBBox is unavailable.\n   */\n  private fitHeightToText(): void {\n    if (!this.textElement || this.nestedSvg) return;\n    let textHeight = 0;\n    try {\n      textHeight = (this.textElement.node as any).getBBox?.()?.height || 0;\n    } catch (e) {\n      return;\n    }\n    if (!textHeight) return;\n    const needed = Math.ceil(textHeight) + 14; // vertical padding\n    if (needed > (this.options.height || 0) + 1) {\n      this.setSize(this.options.width || 100, needed);\n    }\n  }\n\n  /** Position the text element within the background shape based on alignment settings. */\n  public centerText() {\n    // Skip if no text element (e.g., when using SVG content)\n    if (!this.textElement) return;\n\n    const { width, height, textXAlign, textYAlign, textOffset } = this.options;\n\n    // Get the background shape's position within the group\n    const shapeX = (this.backgroundRect as any).x?.() ?? 0;\n    const shapeY = (this.backgroundRect as any).y?.() ?? 0;\n\n    // Since text-anchor=\"middle\" and dominant-baseline=\"central\",\n    // we position the text at the CENTER of the shape and SVG handles the rest\n    let x = shapeX + width! / 2 + (textOffset?.x || 0);\n    let y = shapeY + height! / 2 + (textOffset?.y || 0);\n\n    // Horizontal alignment adjustments\n    switch (textXAlign) {\n      case \"left\":\n        x = shapeX + 5 + (textOffset?.x || 0);\n        this.textElement.attr('text-anchor', 'start');\n        break;\n      case \"right\":\n        x = shapeX + width! - 5 + (textOffset?.x || 0);\n        this.textElement.attr('text-anchor', 'end');\n        break;\n      default: // center\n        this.textElement.attr('text-anchor', 'middle');\n        break;\n    }\n\n    // Vertical alignment adjustments\n    switch (textYAlign) {\n      case \"top\":\n        y = shapeY + 5 + (textOffset?.y || 0);\n        this.textElement.attr('dominant-baseline', 'hanging');\n        break;\n      case \"bottom\":\n        y = shapeY + height! - 5 + (textOffset?.y || 0);\n        this.textElement.attr('dominant-baseline', 'auto');\n        break;\n      default: // middle\n        this.textElement.attr('dominant-baseline', 'central');\n        break;\n    }\n\n    // Multi-line text: SVG.js stacks tspans downward from the first line, so for\n    // middle/default vertical alignment shift the block up by half its extra\n    // height to keep it centered in the shape.\n    const lineCount =\n      this.textElement.node.querySelectorAll?.(\"tspan\")?.length || 1;\n    if (lineCount > 1 && textYAlign !== \"top\" && textYAlign !== \"bottom\") {\n      const lineHeight = (this.options.fontSize || 14) * 1.3;\n      y -= ((lineCount - 1) * lineHeight) / 2;\n    }\n\n    // Use x/y attributes directly for proper text-anchor behavior\n    this.textElement.attr({ x, y });\n\n    // Miro-style auto-fit: if the text (at its set fontSize) doesn't fit the node,\n    // scale it down so it stays INSIDE the shape instead of spilling out. The\n    // stored fontSize is untouched — only the rendered size shrinks — so the user's\n    // choice is preserved and restored when the node is made large enough.\n    this.fitTextToNode();\n  }\n\n  /**\n   * Shrink the rendered text to fit within the node bounds (Miro shape behavior).\n   * Applies a uniform scale transform around the text's visual center; never grows\n   * beyond 1 (the set size) and never shrinks below a readable floor.\n   */\n  private fitTextToNode(): void {\n    if (!this.textElement || this.nestedSvg) return;\n    const t = this.textElement as any;\n    // Clear any prior fit-scale so we measure the NATURAL text size.\n    try {\n      t.attr(\"transform\", null);\n    } catch (e) {\n      return;\n    }\n    let bb: any;\n    try {\n      bb = (t.node as any).getBBox();\n    } catch (e) {\n      return;\n    }\n    if (!bb || bb.width <= 0 || bb.height <= 0) return;\n    // Inset for tapering shapes (diamond/triangle/star/ellipse) so the text is\n    // scaled to the inscribed area, not the bounding box — otherwise it spills\n    // past the angled edges.\n    const inset = this.shapeTextInset();\n    const availW = (this.options.width || 0) * inset - 12; // horizontal padding\n    const availH = (this.options.height || 0) * inset - 10; // vertical padding\n    if (availW <= 0 || availH <= 0) return;\n    let scale = Math.min(availW / bb.width, availH / bb.height);\n    if (scale >= 0.999) return; // already fits — leave at full size\n    scale = Math.max(scale, 0.3); // don't shrink to unreadable\n    // Scale around the text's geometric center so it stays where it was centered,\n    // regardless of alignment / multi-line stacking.\n    const gcx = bb.x + bb.width / 2;\n    const gcy = bb.y + bb.height / 2;\n    try {\n      t.attr(\n        \"transform\",\n        `translate(${gcx} ${gcy}) scale(${scale.toFixed(\n          4\n        )}) translate(${-gcx} ${-gcy})`\n      );\n    } catch (e) {\n      /* noop */\n    }\n  }\n\n  private makeDraggable() {\n    // Use svg.draggable.js to make the group draggable\n    (this.svgGroup as any).draggable();\n\n    // Add event listeners for drag events with proper namespacing\n    this.svgGroup.on(\"dragstart.node\", (event: any) => {\n      console.log(\"DRAG_DEBUG: Drag started on\", this.id);\n\n      // Raise visually during drag, but DON'T persist/undo it — a plain click is\n      // a zero-distance drag, and persisting z-order per click flooded the undo\n      // stack (making undo feel broken). Deliberate \"bring to front\" still persists.\n      this.toFront(false);\n\n      // Selection behavior - ensure this node is selected when drag starts\n      const isCurrentlySelected = this.slate.getSelectedNodes().includes(this);\n\n      // Check for multi-select modifier keys from the original pointer/mouse event.\n      // Shift is included for Miro parity (shift-click adds to the selection), the\n      // same modifier MultiSelection uses for additive rect-select.\n      const origEvt = event.detail?.event || event;\n      const isMultiSelect =\n        origEvt?.ctrlKey || origEvt?.metaKey || origEvt?.shiftKey;\n\n      if (!isCurrentlySelected) {\n        console.log(\n          \"SELECTION_DEBUG: Drag started on unselected node\",\n          this.id,\n          \"- selecting it, addToSelection:\",\n          isMultiSelect\n        );\n        // Select this node (respect Ctrl/Meta for multi-select)\n        this.slate.selectNodes([this], isMultiSelect);\n      } else {\n        console.log(\n          \"SELECTION_DEBUG: Drag started on already selected node\",\n          this.id\n        );\n      }\n\n      this.isDragging = true;\n      this.wasSelectedBeforeDrag = true; // Always true now since we ensure selection\n\n      // Hide the drag-to-connect plug handles for the duration of the drag. They\n      // live in a global canvas group (not this node's group), so they don't\n      // follow the node while it moves — leaving \"ghost\" dots behind at the old\n      // position. Force-hide past the selection pin; drag-end re-anchors them.\n      this.hideConnectionHandles();\n      this.slate.getSelectedNodes?.().forEach((n) => {\n        if (n !== this) (n as any).hideConnectionHandles?.();\n      });\n\n      // Store the transform at drag start so we can calculate drag delta later\n      const transform = this.svgGroup.transform();\n      this.preDragTransform = {\n        translateX: transform.translateX || 0,\n        translateY: transform.translateY || 0\n      };\n\n      // CRITICAL: Store the actual position using this.options which is the stored logical position\n      // Don't use svgGroup.x() which returns transformed bbox for rotated groups\n      // Don't use backgroundRect.bbox() which returns local coords (0,0) relative to group\n      this.preDragPosition = {\n        x: this.options.x ?? 0,\n        y: this.options.y ?? 0\n      };\n      // Capture the pointer position so dragmove can position the node from the\n      // pointer delta (world units) rather than svg.draggable's child-move,\n      // which distorts under a group rotation.\n      this._dragStartPointer = this.pointerFromDragEvent(event);\n\n      // Group move: if this node is part of a multi-selection, remember the other\n      // selected nodes + their positions so dragmove can move them in lockstep.\n      this._groupDragSiblings = [];\n      try {\n        const selected: Node[] = this.slate.getSelectedNodes?.() || [];\n        if (selected.length > 1 && selected.includes(this)) {\n          for (const other of selected) {\n            if (other === this) continue;\n            this._groupDragSiblings.push({\n              node: other,\n              x: other.options.x ?? 0,\n              y: other.options.y ?? 0,\n            });\n          }\n        }\n      } catch (e) {\n        /* noop */\n      }\n      console.log(\"DRAG_DEBUG: Stored pre-drag transform:\", this.preDragTransform, \"position:\", this.preDragPosition);\n\n      // Temporarily disable resize/rotate during drag for clean dragging\n      // The selection system will handle this through updateSelectionResizeRotate\n      this.slate.disableNodeResizeRotate(this);\n      // Hide the cog during drag; it re-shows at the new spot on drag end.\n      this.hideNodeCog();\n    });\n\n    this.svgGroup.on(\"dragend.node\", (event: any) => {\n      console.log(\"DRAG_DEBUG: Drag ended on\", this.id);\n\n      // options.x/y were kept current by the controlled dragmove handler\n      // (pointer delta in world units), so no box math is needed here. As a\n      // fallback for environments that fire dragend without any dragmove, apply\n      // the final pointer delta if we have one.\n      const ptr = this.pointerFromDragEvent(event);\n      if (ptr && this._dragStartPointer && this.preDragPosition) {\n        const zoom = this.slate.getZoom?.() || 1;\n        const fdx = (ptr.x - this._dragStartPointer.x) / zoom;\n        const fdy = (ptr.y - this._dragStartPointer.y) / zoom;\n        this.options.x = this.preDragPosition.x + fdx;\n        this.options.y = this.preDragPosition.y + fdy;\n        // Snap the FINAL (persisted) position to the grid when enabled — this is\n        // the value that broadcasts + saves, so it must snap too (no-op unless on).\n        let feffDx = fdx;\n        let feffDy = fdy;\n        const fsnapped = this.slate.grid?.snapPoint?.(\n          this.options.x,\n          this.options.y\n        );\n        if (fsnapped) {\n          this.options.x = fsnapped.x;\n          this.options.y = fsnapped.y;\n          feffDx = fsnapped.x - this.preDragPosition.x;\n          feffDy = fsnapped.y - this.preDragPosition.y;\n        }\n        // Snap to neighbors on the FINAL position too (this is what persists).\n        if (this.slate.options.viewPort?.snapToObjects) {\n          const aligned = this.snapToNeighbors(this.options.x, this.options.y);\n          this.options.x = aligned.x;\n          this.options.y = aligned.y;\n          feffDx = this.options.x - this.preDragPosition.x;\n          feffDy = this.options.y - this.preDragPosition.y;\n        }\n        // Finalize group siblings with the same (snapped) delta.\n        for (const sib of this._groupDragSiblings) {\n          sib.node.options.x = sib.x + feffDx;\n          sib.node.options.y = sib.y + feffDy;\n          sib.node.applyPositionAndRotation();\n        }\n      }\n\n      // Capture the moved group before clearing pre-drag state.\n      const movedSiblings = this._groupDragSiblings;\n      this._groupDragSiblings = [];\n\n      // Did the node (or any group sibling) ACTUALLY move? A pure click fires\n      // dragstart+dragend with a zero delta; broadcasting onNodesMove then records\n      // a no-op undo snapshot, so every click became an undo step and undo felt\n      // broken. Only broadcast when something really moved. When we can't tell\n      // (no pre-drag position captured), broadcast to be safe.\n      const startPos = this.preDragPosition;\n      const EPS = 0.5;\n      const curX = this.options.x ?? 0;\n      const curY = this.options.y ?? 0;\n      const primaryMoved =\n        !startPos ||\n        Math.abs(curX - startPos.x) > EPS ||\n        Math.abs(curY - startPos.y) > EPS;\n      const siblingMoved = movedSiblings.some(\n        (s) =>\n          Math.abs((s.node.options.x ?? 0) - s.x) > EPS ||\n          Math.abs((s.node.options.y ?? 0) - s.y) > EPS\n      );\n      const actuallyMoved = primaryMoved || siblingMoved;\n\n      // Clear pre-drag state\n      this.preDragTransform = null;\n      this.preDragPosition = null;\n      this._dragStartPointer = null;\n\n      // Re-assert the canonical model: children at local origin, group transform\n      // carrying position (+ rotation).\n      this.applyPositionAndRotation();\n\n      // Notify the host app of the completed move (v1 package shape) — include\n      // every node that moved as part of a group drag so they sync + persist.\n      // Skipped for a zero-distance drag (a click) so undo isn't polluted.\n      if (actuallyMoved) {\n        this.slate.broadcast?.(\"onNodesMove\", {\n          nodeOptions: [\n            v2NodeToV1(this.options),\n            ...movedSiblings.map((s) => v2NodeToV1(s.node.options)),\n          ],\n        });\n      }\n\n      // Small delay to distinguish drag from click - reduced for better responsiveness\n      this._dragEndTimeoutId = setTimeout(() => {\n        if (this._destroyed) return;\n        this.isDragging = false;\n\n        // Ensure the dragged node remains selected after drag\n        const isCurrentlySelected = this.slate\n          .getSelectedNodes()\n          .includes(this);\n\n        if (!isCurrentlySelected) {\n          console.log(\n            \"SELECTION_DEBUG: Drag ended on unselected node\",\n            this.id,\n            \"- selecting it\"\n          );\n          this.slate.selectNodes([this], false);\n        } else {\n          console.log(\n            \"SELECTION_DEBUG: Drag ended on selected node\",\n            this.id,\n            \"- re-enabling resize/rotate\"\n          );\n          // Re-enable resize/rotate since drag is complete\n          this.slate.updateSelectionResizeRotate();\n        }\n\n        // Notify slate of node position change (for BirdsEye refresh)\n        this.slate.notifyNodeChanged(this);\n\n        // Re-anchor the plug handles at the node's NEW position (they were hidden\n        // for the drag). Only if still pinned/selected — otherwise they stay\n        // hidden until the next hover, at the correct spot.\n        if (this._connHandlesPinned) this.showConnectionHandles();\n      }, 10); // Reduced from 50ms to 10ms\n    });\n\n    // Controlled drag: position the node from the POINTER delta in world units,\n    // preserving rotation, instead of svg.draggable's default child-move (which\n    // is computed in the group's rotated local frame → the node flies wildly\n    // when a rotated node is dragged). We preventDefault to suppress the default\n    // move and drive the transform ourselves via applyPositionAndRotation.\n    this.svgGroup.on(\"dragmove.node\", (event: any) => {\n      this.isDragging = true;\n      const ptr = this.pointerFromDragEvent(event);\n      if (ptr && this._dragStartPointer && this.preDragPosition) {\n        event.preventDefault?.();\n        const zoom = this.slate.getZoom?.() || 1;\n        const dx = (ptr.x - this._dragStartPointer.x) / zoom;\n        const dy = (ptr.y - this._dragStartPointer.y) / zoom;\n        this.options.x = this.preDragPosition.x + dx;\n        this.options.y = this.preDragPosition.y + dy;\n        // Snap to grid when enabled — no-op unless slate.grid.snapToGrid is on.\n        // Snap the primary node, then move group siblings by the SNAPPED delta so\n        // a multi-selection keeps its relative layout instead of each node\n        // snapping independently.\n        let effDx = dx;\n        let effDy = dy;\n        const snapped = this.slate.grid?.snapPoint?.(\n          this.options.x,\n          this.options.y\n        );\n        if (snapped) {\n          this.options.x = snapped.x;\n          this.options.y = snapped.y;\n          effDx = snapped.x - this.preDragPosition.x;\n          effDy = snapped.y - this.preDragPosition.y;\n        }\n        // Snap to neighbors (align edges/centers) when enabled — no-op otherwise.\n        if (this.slate.options.viewPort?.snapToObjects) {\n          const aligned = this.snapToNeighbors(this.options.x, this.options.y);\n          this.options.x = aligned.x;\n          this.options.y = aligned.y;\n          effDx = this.options.x - this.preDragPosition.x;\n          effDy = this.options.y - this.preDragPosition.y;\n        }\n        this.applyPositionAndRotation();\n        // Group move: shift every other selected node by the same (snapped) delta.\n        for (const sib of this._groupDragSiblings) {\n          sib.node.options.x = sib.x + effDx;\n          sib.node.options.y = sib.y + effDy;\n          sib.node.applyPositionAndRotation();\n        }\n        // svg.draggable raises the dragged node to front, which would push\n        // connector arrowheads behind it (Q1). Keep markers on top each frame.\n        try {\n          (this.slate as any).markersContainer?.front?.();\n        } catch (e) {\n          /* noop */\n        }\n      }\n    });\n  }\n\n  /**\n   * Extract the pointer position in client coordinates from an svg.draggable\n   * event (or a raw DOM event). svg.draggable exposes the source event at\n   * event.detail.event; touch events carry it under touches/changedTouches.\n   */\n  private pointerFromDragEvent(event: any): { x: number; y: number } | null {\n    const src = event?.detail?.event ?? event;\n    if (!src) return null;\n    const pt =\n      src.touches?.[0] ?? src.changedTouches?.[0] ?? src;\n    if (typeof pt.clientX === \"number\" && typeof pt.clientY === \"number\") {\n      return { x: pt.clientX, y: pt.clientY };\n    }\n    return null;\n  }\n\n  public position(\n    x: number,\n    y: number,\n    callback?: () => void,\n    easing?: any,\n    duration?: number\n  ) {\n    console.log(\n      \"NODE_DEBUG: position called for\",\n      this.id,\n      \"x:\",\n      x,\n      \"y:\",\n      y,\n      \"duration:\",\n      duration\n    );\n\n    const startX = this.options.x ?? x;\n    const startY = this.options.y ?? y;\n    this.options.x = x;\n    this.options.y = y;\n\n    const canAnimate =\n      !!duration &&\n      duration > 0 &&\n      typeof requestAnimationFrame !== \"undefined\" &&\n      typeof performance !== \"undefined\" &&\n      (startX !== x || startY !== y);\n\n    if (canAnimate) {\n      // Tween options.x/y and re-apply the group transform each frame. We do NOT\n      // use svg.js animate().move(): that animates the shape's CHILDREN in the\n      // group's local frame, so on a ROTATED node the movement is computed\n      // through the rotation and the node flies wildly before landing (seen on\n      // the mirrored/collab canvas). Driving applyPositionAndRotation() keeps\n      // rotation intact and moves the node in a straight world-space line.\n      const t0 = performance.now();\n      const step = () => {\n        if (this._destroyed || !this.svgGroup) return;\n        const p = Math.min(1, (performance.now() - t0) / (duration as number));\n        // easeInOutQuad\n        const e = p < 0.5 ? 2 * p * p : 1 - Math.pow(-2 * p + 2, 2) / 2;\n        this.options.x = startX + (x - startX) * e;\n        this.options.y = startY + (y - startY) * e;\n        this.applyPositionAndRotation();\n        if (p < 1) {\n          requestAnimationFrame(step);\n        } else {\n          this.options.x = x;\n          this.options.y = y;\n          this.applyPositionAndRotation();\n          if (callback) callback();\n        }\n      };\n      requestAnimationFrame(step);\n    } else {\n      // Move immediately (translate + rotate composed)\n      this.applyPositionAndRotation();\n      if (callback) callback();\n    }\n  }\n\n  /** Bring the node to the front of the SVG z-order. */\n  /**\n   * Raise this node to the top of the SVG z-order. When `persist` is true\n   * (deliberate \"bring to front\"), it broadcasts + records an undo step. Pass\n   * false for the transient raise on pointer-down/drag-start so a plain click\n   * doesn't persist a z-order change or pollute the undo stack.\n   */\n  public toFront(persist = true) {\n    this.svgGroup.front();\n    if (persist) this.slate.broadcast?.(\"onNodeToFront\", { id: this.id });\n  }\n\n  /** Send the node to the back of the SVG z-order. */\n  public toBack(persist = true) {\n    this.svgGroup.back();\n    if (persist) this.slate.broadcast?.(\"onNodeToBack\", { id: this.id });\n  }\n\n  /**\n   * Comment-count badge (Miro-style): a small count bubble at the node's\n   * top-right corner. NON-destructive — it lives in the node's SVG group (so it\n   * tracks pan/zoom/position/rotation for free) and never touches the node's text\n   * or fill. `resolved` picks the color (green = resolved, red = unresolved,\n   * grey = unknown/empty). Pass count <= 0 (or call clearCommentBadge) to remove.\n   */\n  public setCommentBadge(\n    count: number,\n    kind: \"resolved\" | \"unresolved\" | \"empty\" = \"unresolved\"\n  ): void {\n    this.clearCommentBadge();\n    if (!count || count < 0 || !this.svgGroup) return;\n    const w = this.options.width || 100;\n    const h = this.options.height || 100;\n    const r = 11;\n    // Badge sits at the node's top-right. For a plain rectangle that's the corner;\n    // for round or custom vector shapes the bbox corner is EMPTY (the shape\n    // doesn't fill it), so the badge would float off the shape. Pull it inward so\n    // it hugs the shape's upper-right instead.\n    let cx = w - 2;\n    let cy = 2;\n    const shp = String(\n      this.options.vectorPath || this.options.shape || \"rectangle\"\n    ).toLowerCase();\n    if (this.nestedSvg) {\n      // SVG-content artwork is not necessarily rectangular.\n      cx = w * 0.72;\n      cy = h * 0.28;\n    } else if (shp === \"circle\" || shp === \"ellipse\") {\n      // On the round edge at ~45° (top-right).\n      cx = w * 0.85;\n      cy = h * 0.15;\n    } else if (\n      this.contentPath &&\n      shp !== \"rectangle\" &&\n      shp !== \"roundedrectangle\"\n    ) {\n      // Custom vector shape: pull inward along the diagonal so the badge hugs\n      // the artwork rather than floating at the bounding-box corner.\n      cx = w * 0.72;\n      cy = h * 0.28;\n    }\n    const color =\n      kind === \"resolved\"\n        ? \"#2e7d32\"\n        : kind === \"empty\"\n        ? \"#6b7280\"\n        : \"#e5484d\";\n    const badge = this.svgGroup.group().addClass(\"comment-badge\");\n    badge.circle(r * 2).center(cx, cy).fill(color).stroke({\n      color: \"#ffffff\",\n      width: 1.5,\n    });\n    const label = count > 99 ? \"99+\" : String(count);\n    badge\n      .text(label)\n      .font({\n        size: 12,\n        anchor: \"middle\",\n        family: \"sans-serif\",\n        weight: \"bold\",\n      })\n      .fill(\"#ffffff\")\n      .center(cx, cy)\n      .attr(\"dy\", \"0.05em\");\n    badge.attr(\"pointer-events\", \"none\");\n    (this as any)._commentBadge = badge;\n    // Remember it so it can be re-anchored after a resize (the badge is placed at\n    // width-2, which changes when the node is resized).\n    (this as any)._commentBadgeState = { count, kind };\n  }\n\n  /** Remove the comment-count badge if present. */\n  public clearCommentBadge(): void {\n    const b = (this as any)._commentBadge;\n    if (b) {\n      try {\n        b.remove();\n      } catch {\n        /* already gone */\n      }\n      (this as any)._commentBadge = undefined;\n    }\n    (this as any)._commentBadgeState = undefined;\n  }\n\n  /**\n   * Remove the node from the canvas (light teardown).\n   * Cleans up DOM elements but does NOT disable sub-modules. Use `destroy()` for full teardown.\n   */\n  public remove() {\n    // Clean up connection handles container (created on slate.canvas, not in svgGroup)\n    if (this.connectionHandles.container) {\n      this.connectionHandles.container.remove();\n      this.connectionHandles.container = undefined;\n    }\n    // Clean up connection preview container\n    if (this.connectionPreview?.container) {\n      this.connectionPreview.container.remove();\n      this.connectionPreview.container = undefined;\n    }\n    // Clean up the selection toolbar (delete/connect/gear pill). It's rendered in a\n    // GLOBAL container, not svgGroup, so removing the group won't take it — without\n    // this an in-toolbar delete leaves a stale cog floating for a node that's gone.\n    this.hideNodeCog();\n    // Remove the main SVG group (cleans up all child elements and sub-system references)\n    this.svgGroup.remove();\n  }\n\n  /**\n   * Destroy the node completely, cleaning up all timers, event handlers,\n   * and owned sub-modules. Pattern matches PanZoom.ts.\n   */\n  public destroy(): void {\n    this._destroyed = true;\n\n    // Clear all pending timeouts\n    if (this._svgViewboxTimeoutId !== null) {\n      clearTimeout(this._svgViewboxTimeoutId);\n      this._svgViewboxTimeoutId = null;\n    }\n    if (this._dragEndTimeoutId !== null) {\n      clearTimeout(this._dragEndTimeoutId);\n      this._dragEndTimeoutId = null;\n    }\n    if (this._previewViewboxTimeoutId !== null) {\n      clearTimeout(this._previewViewboxTimeoutId);\n      this._previewViewboxTimeoutId = null;\n    }\n    if (this._connectTimeoutId !== null) {\n      clearTimeout(this._connectTimeoutId);\n      this._connectTimeoutId = null;\n    }\n\n    // Disable owned sub-modules (each handles its own cleanup)\n    if (this.resizeRotate && this.resizeRotate.isEnabled()) {\n      this.resizeRotate.disable();\n    }\n    if (this.connector && (this.connector as any).isActive) {\n      this.connector.disable();\n    }\n    if (this.relationships) {\n      this.relationships.disable();\n      this.relationships.removeAll();\n    }\n\n    // Clean up connection handles container\n    if (this.connectionHandles.container) {\n      this.connectionHandles.container.remove();\n      this.connectionHandles.container = undefined;\n    }\n    // Clean up connection preview container\n    if (this.connectionPreview?.container) {\n      this.connectionPreview.container.remove();\n      this.connectionPreview.container = undefined;\n    }\n\n    // Remove the main SVG group (cleans up all child elements)\n    this.svgGroup.remove();\n    this.isDragging = false;\n  }\n\n  /** Hide the node visually (sets display:none). */\n  public hide() {\n    this.svgGroup.hide();\n  }\n\n  /** Show the node after hide(). */\n  public show() {\n    this.svgGroup.show();\n  }\n\n  /**\n   * Set the node[s text content. No-op on SVG content nodes.\n   *\n   * @param text - New text string\n   */\n  public setText(text: string) {\n    // Skip if no text element (e.g., when using SVG content)\n    if (!this.textElement) return;\n\n    const changed = this.options.text !== text;\n    this.options.text = text;\n    this.textElement.text(this.wrapTextToWidth(text));\n    this.centerText();\n    this.fitHeightToText();\n    // Update accessibility label\n    this.svgGroup.node.setAttribute(\"aria-label\", text || \"Unnamed node\");\n    if (changed) {\n      this.slate.broadcast?.(\"onNodeTextChanged\", { id: this.id, text });\n    }\n  }\n\n  /**\n   * Resize the node to new dimensions. For circles, forces width === height.\n   *\n   * @param width  - New width\n   * @param height - New height\n   */\n  public setSize(width: number, height: number) {\n    if (this.options.shape === \"circle\") {\n      const diameter = Math.min(width, height);\n      width = diameter;\n      height = diameter;\n    }\n    this.options.width = width;\n    this.options.height = height;\n\n    // Update background - need to check type for proper method\n    if (this.backgroundRect instanceof Rect) {\n      this.backgroundRect.size(width, height);\n    } else if (this.backgroundRect instanceof Circle) {\n      // For circles, use the smaller dimension to keep it circular\n      const diameter = Math.min(width, height);\n      this.backgroundRect.size(diameter, diameter);\n      // Also update stored dimensions to match the circle\n      this.options.width = diameter;\n      this.options.height = diameter;\n    } else if (this.backgroundRect instanceof Ellipse) {\n      this.backgroundRect.size(width, height);\n    } else {\n      // Custom shapes (nested SVG with path): resize via SVG native size()\n      try {\n        (this.backgroundRect as any).size?.(width, height);\n      } catch (_) {\n        console.warn(\"NODE_DEBUG: Failed to resize custom shape backgroundRect:\", _);\n      }\n    }\n\n    // Update nested SVG size using stored reference and SVG.js native methods\n    if (this.nestedSvg) {\n      const bgX = (this.backgroundRect as any).x?.() ?? 0;\n      const bgY = (this.backgroundRect as any).y?.() ?? 0;\n\n      // Use SVG.js native size() and move() methods\n      this.nestedSvg.size(width, height).move(bgX, bgY);\n    }\n\n    // Keep the custom-shape resize proxy in lockstep with the shape so the\n    // select/resize handles stay on the shape's bounding box after a resize.\n    if (this.resizeTarget) {\n      try {\n        this.resizeTarget.size(width, height);\n      } catch (_) {\n        /* noop */\n      }\n    }\n\n    // Re-wrap the text to the NEW width so it reflows on resize (Miro-style) —\n    // the wrap points are baked into the tspans, so a resize alone wouldn't\n    // change them. Then re-center (only if a text element exists).\n    if (this.textElement && this.options.text) {\n      this.textElement.text(this.wrapTextToWidth(this.options.text));\n    }\n    this.centerText();\n\n    // Reposition the link badge to the new top-right corner (it's anchored to\n    // the node width, which just changed).\n    if (this._linkBadge) this.updateLinkIndicator();\n\n    // Re-anchor the comment-count badge too (also placed at width-2).\n    const cbs = (this as any)._commentBadgeState;\n    if (cbs) this.setCommentBadge(cbs.count, cbs.kind);\n  }\n\n  /**\n   * Change the node[s background and/or border colors.\n   *\n   * @param backgroundColor - New fill color (or undefined to keep current)\n   * @param borderColor     - New stroke color (or undefined to keep current)\n   */\n  /**\n   * Apply a fill to `el` that may be a solid hex OR a v1-style \"colorA-colorB\"\n   * gradient (slatebox.com stores gradient fills dash-separated). Without this a\n   * gradient string was passed straight to SVG fill and rendered black.\n   */\n  private applyShapeFill(el: any, color?: string): void {\n    if (!el?.fill || !color) return;\n    const parts = String(color).split(\"-\").filter(Boolean);\n    if (parts.length >= 2) {\n      try {\n        const grad = (this.svgGroup as any).gradient(\"linear\", (add: any) => {\n          add.stop(0, parts[0]);\n          add.stop(1, parts[parts.length - 1]);\n        });\n        el.fill(grad);\n        return;\n      } catch (e) {\n        /* fall through to solid */\n      }\n    }\n    el.fill(parts[0] || color);\n  }\n\n  public setColors(backgroundColor?: string, borderColor?: string) {\n    // Path shapes carry fill/stroke on the inner <path>, not the nested wrapper.\n    const styleEl: any = this.contentPath ?? this.backgroundRect;\n    if (backgroundColor) {\n      this.options.backgroundColor = backgroundColor;\n      this.applyShapeFill(styleEl, backgroundColor);\n      // Keep text readable on the new fill: if the font color is an AUTO value\n      // (black/white/unset), flip it to whichever contrasts — otherwise white\n      // default text goes invisible on a light background. Custom colors are\n      // preserved. Both windows compute the same value, so it stays in sync.\n      const fc = String(this.options.fontColor || \"\").toLowerCase();\n      const isAutoFont = [\n        \"\",\n        \"#fff\",\n        \"#ffffff\",\n        \"#000\",\n        \"#000000\",\n        \"white\",\n        \"black\",\n      ].includes(fc);\n      // Only flip when the current text would be HARD TO READ on the new fill\n      // (contrast < 3:1) — so white-on-#fafafa (~1:1) flips, but a deliberate\n      // white-on-red (~4:1, e.g. from a theme) is left alone.\n      const currentFont = this.options.fontColor || \"#000000\";\n      if (\n        isAutoFont &&\n        this.textElement &&\n        backgroundColor.startsWith(\"#\") &&\n        contrastRatio(currentFont, backgroundColor) < 3\n      ) {\n        const ideal = whiteOrBlack(backgroundColor);\n        this.options.fontColor = ideal;\n        try {\n          this.textElement.font({ fill: ideal });\n        } catch (e) {\n          /* noop */\n        }\n      }\n    }\n\n    if (borderColor) {\n      this.options.borderColor = borderColor;\n      styleEl.stroke({ color: borderColor });\n    }\n\n    if (backgroundColor || borderColor) {\n      // v1 package shape: data.color carries the background color\n      this.slate.broadcast?.(\"onNodeColorChanged\", {\n        id: this.id,\n        color: this.options.backgroundColor,\n        borderColor: this.options.borderColor,\n      });\n    }\n  }\n\n  /**\n   * Re-apply the border stroke (color / width / style / opacity) from options.\n   * The app's border pane sends one { prop, val } at a time, so we repaint the\n   * whole stroke from current options each change. borderStyle accepts the app's\n   * symbols ('-', '.', '--.') or words ('dashed', 'dotted'); dash lengths scale\n   * with the border width. No-op when there's no plain shape stroke (e.g. SVG\n   * content / nested path shapes).\n   */\n  public applyBorder(): void {\n    // Path shapes carry the stroke on the inner <path>, not the nested wrapper.\n    const rect: any = this.contentPath ?? this.backgroundRect;\n    if (!rect || typeof rect.stroke !== \"function\") return;\n    const { borderColor, borderWidth, borderOpacity } = this.options;\n    const strokeOpts: {\n      color?: string;\n      width?: number;\n      opacity?: number;\n      dasharray?: string;\n    } = { dasharray: this.borderDashArray() };\n    if (borderColor) strokeOpts.color = borderColor;\n    if (borderWidth !== undefined) strokeOpts.width = borderWidth;\n    if (borderOpacity !== undefined) strokeOpts.opacity = borderOpacity;\n    rect.stroke(strokeOpts);\n  }\n\n  /**\n   * SVG stroke-dasharray for the current borderStyle, scaled by border width.\n   * Accepts the app's symbols ('-', '.', '--.') and words ('dashed', 'dotted').\n   * Returns \"none\" for solid. Shared by createBackground (load path) and\n   * applyBorder (edit path) so border style survives a reload.\n   */\n  private borderDashArray(): string {\n    const { borderStyle, borderWidth } = this.options;\n    const w = borderWidth || 1;\n    const dash: Record<string, number[]> = {\n      \"-\": [3, 1],\n      dashed: [3, 1],\n      \".\": [1, 1],\n      dotted: [1, 1],\n      \"--.\": [8, 3, 1, 3],\n      combo: [8, 3, 1, 3],\n    };\n    return borderStyle && dash[borderStyle]\n      ? dash[borderStyle].map((n) => n * w).join(\",\")\n      : \"none\";\n  }\n\n  /** Lock the node, disabling drag and resize/rotate. */\n  public lock() {\n    this.options.isLocked = true;\n    this.options.allowDrag = false;\n    if ((this.svgGroup as any).draggable) {\n      (this.svgGroup as any).draggable(false);\n    }\n    // Disable resize/rotate when locked\n    this.disableResizeRotate();\n  }\n\n  /** Unlock the node, re-enabling drag and resize/rotate. */\n  public unlock() {\n    this.options.isLocked = false;\n    this.options.allowDrag = true;\n    this.makeDraggable();\n    // Re-enable resize/rotate if this node is currently selected\n    this.enableResizeRotate();\n  }\n\n  // Resize/Rotate functionality - managed by Slate\n  /** Enable resize and rotate handles. Delegates to the Slate for centralized selection management. */\n  public enableResizeRotate() {\n    // Delegate to Slate - don't manage directly\n    console.log(\n      \"NODE_DEBUG: enableResizeRotate called on\",\n      this.id,\n      \"- delegating to Slate\"\n    );\n    this.slate.enableNodeResizeRotate(this);\n  }\n\n  /** Disable resize and rotate handles. Delegates to the Slate. */\n  public disableResizeRotate() {\n    // Delegate to Slate - don't manage directly\n    console.log(\n      \"NODE_DEBUG: disableResizeRotate called on\",\n      this.id,\n      \"- delegating to Slate\"\n    );\n    this.slate.disableNodeResizeRotate(this);\n  }\n\n  /** Enable resize handles only. */\n  public enableResize() {\n    this.resizeRotate.updateOptions({ resizeEnabled: true });\n    // Note: Slate manages when to actually enable/disable\n  }\n\n  /** Disable resize handles only. */\n  public disableResize() {\n    this.resizeRotate.updateOptions({ resizeEnabled: false });\n    // Note: Slate manages when to actually enable/disable\n  }\n\n  /** Enable rotate handle only. */\n  public enableRotate() {\n    this.resizeRotate.updateOptions({ rotateEnabled: true });\n    // Note: Slate manages when to actually enable/disable\n  }\n\n  /** Disable rotate handle only. */\n  public disableRotate() {\n    this.resizeRotate.updateOptions({ rotateEnabled: false });\n    // Note: Slate manages when to actually enable/disable\n  }\n\n  public isResizeRotateEnabled(): boolean {\n    return this.resizeRotate.isEnabled();\n  }\n\n  /**\n   * Set the node[s rotation angle.\n   *\n   * @param angle - Rotation in degrees (positive = clockwise)\n   */\n  public setRotation(angle: number, duration?: number) {\n    if (!this.options.rotate) {\n      this.options.rotate = { rotationAngle: 0 };\n    }\n    const start = this.options.rotate.rotationAngle || 0;\n    const canAnimate =\n      !!duration &&\n      duration > 0 &&\n      typeof requestAnimationFrame !== \"undefined\" &&\n      typeof performance !== \"undefined\" &&\n      start !== angle;\n\n    if (canAnimate) {\n      // Tween the angle so a remotely-applied rotation animates in this window\n      // instead of snapping (collab bug #5) — same easing as the move tween.\n      const delta = angle - start;\n      const t0 = performance.now();\n      const step = () => {\n        if (this._destroyed || !this.svgGroup || !this.options.rotate) return;\n        const p = Math.min(1, (performance.now() - t0) / (duration as number));\n        const e = p < 0.5 ? 2 * p * p : 1 - Math.pow(-2 * p + 2, 2) / 2;\n        this.options.rotate.rotationAngle = start + delta * e;\n        this.applyPositionAndRotation();\n        if (p < 1) {\n          requestAnimationFrame(step);\n        } else {\n          this.options.rotate.rotationAngle = angle;\n          this.applyPositionAndRotation();\n        }\n      };\n      requestAnimationFrame(step);\n    } else {\n      this.options.rotate.rotationAngle = angle;\n      this.applyPositionAndRotation();\n    }\n  }\n\n  /**\n   * Set the group's transform to translate(options.x, options.y) followed by a\n   * rotation around the node's visual center. The shape/text are drawn at the\n   * group's local origin, so position is a pure translate and rotation must be\n   * COMPOSED on top of it — replacing the matrix (as an origin:'center' rotate\n   * alone does) would drop the translate and fling the node far off-screen on\n   * reload. Single source of truth for the group transform.\n   */\n  private applyPositionAndRotation() {\n    if (!this.svgGroup) return;\n    const x = this.options.x || 0;\n    const y = this.options.y || 0;\n    const w = this.options.width || 0;\n    const h = this.options.height || 0;\n    const angle = this.options.rotate?.rotationAngle || 0;\n\n    // Canonical model: the shape/text live at the group's LOCAL origin and the\n    // group transform carries position + rotation. But svg.js move()/animate().\n    // move() — used by drag and by animated/collab/host-replay moves — displaces\n    // the group's CHILDREN in local space instead of touching the group\n    // transform. If left displaced, that local offset is double-counted against\n    // the translate we set below and the node renders far off-screen (the\n    // \"flies away on reload\" bug). So first pull the children back to the local\n    // origin, reading their true local bbox with the group transform cleared.\n    if (\n      typeof this.svgGroup.node?.removeAttribute === \"function\" &&\n      typeof this.svgGroup.bbox === \"function\"\n    ) {\n      try {\n        this.svgGroup.node.removeAttribute(\"transform\");\n        const bb = this.svgGroup.bbox();\n        if (bb && (Math.abs(bb.x) > 0.01 || Math.abs(bb.y) > 0.01)) {\n          this.svgGroup.children().forEach((child: any) => {\n            if (typeof child?.dmove === \"function\") child.dmove(-bb.x, -bb.y);\n          });\n        }\n      } catch (e) {\n        console.warn(\"NODE_DEBUG: child normalization failed:\", e);\n      }\n    }\n\n    // Defend against DOUBLE-rotation of the text/nested content. During a live UI\n    // rotate, ResizeRotate bakes an individual rotation onto the text element (so it\n    // follows in real time). The group transform set below ALSO rotates them (they're\n    // children), so if that baked rotation is left on, the text renders at 2x the node's\n    // angle. finalizeInteraction strips it on interaction-end, but that can be missed\n    // (e.g. an intervening drag/render/reload) — strip any residual child rotation here\n    // too, then re-center. Cheap: only fires when a baked rotation is actually present.\n    try {\n      const stripBakedRotation = (el: any): boolean => {\n        if (!el?.node?.removeAttribute) return false;\n        const tr = typeof el.transform === \"function\" ? el.transform() : null;\n        if (tr && Math.abs(tr.rotate || 0) > 0.01) {\n          el.node.removeAttribute(\"transform\");\n          return true;\n        }\n        return false;\n      };\n      const strippedText = stripBakedRotation(this.textElement);\n      stripBakedRotation(this.nestedSvg);\n      if (strippedText && typeof this.centerText === \"function\") {\n        this.centerText();\n      }\n    } catch (e) {\n      /* noop */\n    }\n\n    // Set the group transform EXPLICITLY as an SVG transform string —\n    // deterministic, no SVG.js object-form / relative-compose ambiguity.\n    // SVG applies right-to-left: a local point is first rotated about the\n    // node's own center (w/2,h/2), then translated to (x,y). The shape/text\n    // are drawn at the group's local origin, so the node renders at (x,y)\n    // rotated about its visual center — stable across reloads.\n    const t = angle\n      ? `translate(${x} ${y}) rotate(${angle} ${w / 2} ${h / 2})`\n      : `translate(${x} ${y})`;\n    this.svgGroup.node.setAttribute(\"transform\", t);\n\n    // Notify connectors so they re-solve their anchors and stay attached\n    // through position AND rotation changes. svg.connectable listens for a\n    // \"transform\" event on the connected groups (con.update()); we set the\n    // transform via setAttribute, which fires nothing on its own, so a rotated\n    // node's connectors never followed (collab bug #4). Firing it here covers\n    // every path (drag, rotate, tween, load) since they all funnel through here.\n    try {\n      this.svgGroup.fire?.(\"transform\");\n    } catch (e) {\n      /* noop */\n    }\n\n    // A node move re-solves any attached connector, so the line's cog +\n    // endpoint-lock toggles (positioned at the old geometry) would DRIFT (U2).\n    // Clear them — Miro likewise hides connector UI during moves; the user\n    // re-clicks the line for fresh, correctly-placed affordances.\n    try {\n      if ((this.slate as any)._activeLineCog || (this.slate as any)._activeEndpointToggles) {\n        (this.slate as any).clearLineCog?.();\n      }\n    } catch (e) {\n      /* noop */\n    }\n  }\n\n  /**\n   * Re-assert the canonical model after a resize/rotate interaction. During the\n   * interaction svg.resize.js transforms the backgroundRect (and we rotate the\n   * text/nested separately) — rotation is baked into those CHILDREN. Here we\n   * strip those child transforms so rotation lives only on the group, then\n   * apply the canonical group transform (which also normalizes child position\n   * back to the local origin). Without this the shape carries a baked rotation\n   * AND the group re-applies rotation on reload → double rotation / fly-off.\n   */\n  public finalizeInteraction() {\n    const clear = (el: any) => {\n      try {\n        if (el?.node?.removeAttribute) el.node.removeAttribute(\"transform\");\n      } catch (e) {\n        /* noop */\n      }\n    };\n    clear(this.backgroundRect);\n    clear(this.textElement);\n    clear(this.nestedSvg);\n    this.applyPositionAndRotation();\n    if (this.textElement) this.centerText();\n  }\n\n  /**\n   * Get the current rotation angle. Reads from options.rotate first,\n   * then falls back to svgGroup transform and backgroundRect transform.\n   *\n   * @returns Rotation angle in degrees\n   */\n  public getRotation(): number {\n    // PRIORITY: options.rotate.rotationAngle is always kept up-to-date by both:\n    // - setRotation() (programmatic rotation)\n    // - handleResize() in ResizeRotate.ts (manual UI rotation)\n    // This is the single source of truth for rotation\n    if (this.options.rotate?.rotationAngle !== undefined && this.options.rotate.rotationAngle !== 0) {\n      return this.options.rotate.rotationAngle;\n    }\n\n    // Fallback: Check svgGroup transform (set by setRotation or initial options).\n    // Guard existence first — this runs during a save that can serialize a node\n    // still mid-async-creation (svgGroup/backgroundRect undefined); that's the\n    // expected \"not ready, rotation is 0\" case, not an error to warn about.\n    if (this.svgGroup) {\n      try {\n        const groupTransform = (this.svgGroup as any).transform();\n        if (groupTransform && typeof groupTransform.rotate !== 'undefined' && groupTransform.rotate !== 0) {\n          return groupTransform.rotate;\n        }\n      } catch (e) {\n        console.warn(\"NODE_DEBUG: Failed to read svgGroup transform for rotation:\", e);\n      }\n    }\n\n    // Fallback: Check backgroundRect (svg.select.js applies rotation here during manual rotate)\n    if (this.backgroundRect) {\n      try {\n        const transform = (this.backgroundRect as any).transform();\n        if (transform && typeof transform.rotation !== 'undefined') {\n          return transform.rotation;\n        }\n        if (transform && typeof transform.rotate !== 'undefined') {\n          return transform.rotate;\n        }\n      } catch (e) {\n        console.warn(\"NODE_DEBUG: Failed to read backgroundRect transform for rotation:\", e);\n      }\n    }\n\n    return 0;\n  }\n\n  // Connector functionality\n  /** Enable the node[s connector so it can form connections to other nodes. */\n  public enableConnector() {\n    this.connector.enable();\n  }\n\n  /**\n   * Enable connector with interactive features (selectable, draggable lines).\n   *\n   * @param makeInteractiveCallback - Optional callback after interactive features are set up\n   */\n  public enableConnectorWithInteractive(makeInteractiveCallback?: boolean) {\n    console.log(\n      \"NODE_DEBUG: enableConnectorWithInteractive called for\",\n      this.id\n    );\n\n    // Enable basic connector functionality\n    this.connector.enable();\n\n    // Check if svg.connectable.js is available and has makeInteractive\n    const svgGroup = this.svgGroup as any;\n    if (svgGroup && typeof svgGroup.connectable === \"function\") {\n      console.log(\n        \"NODE_DEBUG: svg.connectable.js detected, setting up interactive features for\",\n        this.id\n      );\n\n      // Hook into makeInteractive if available\n      if (makeInteractiveCallback) {\n        // Check if connectable plugin has makeInteractive method\n        try {\n          // Create a test connection to see if makeInteractive is available\n          const testConnection = svgGroup.connectable({}, svgGroup);\n          if (\n            testConnection &&\n            typeof testConnection.makeInteractive === \"function\"\n          ) {\n            console.log(\n              \"NODE_DEBUG: makeInteractive method available, enabling connection handles for\",\n              this.id\n            );\n\n            // Enable connection handles when makeInteractive is called\n            this.enableConnectionHandles();\n\n            // Hook into the makeInteractive method with callback\n            testConnection.makeInteractive();\n\n            // Clean up test connection\n            if (testConnection.connector && testConnection.connector.remove) {\n              testConnection.connector.remove();\n            }\n          } else {\n            console.log(\n              \"NODE_DEBUG: makeInteractive method not available for\",\n              this.id\n            );\n          }\n        } catch (error) {\n          console.warn(\n            \"NODE_DEBUG: Error testing svg.connectable.js makeInteractive:\",\n            error\n          );\n        }\n      }\n    } else {\n      console.log(\"NODE_DEBUG: svg.connectable.js not available for\", this.id);\n    }\n  }\n\n  /** Disable the node[s connector and remove all connections. */\n  public disableConnector() {\n    this.connector.disable();\n  }\n\n  /**\n   * Create a connection line from this node to a target node.\n   *\n   * @param targetNode - The node to connect to\n   * @param connectionOptions - Line color, width, type, etc.\n   * @returns The connection object\n   *\n   * @example\n   * ```ts\n   * node1.connectTo(node2, { lineColor: '#e94560', lineWidth: 3, type: 'curved' });\n   * ```\n   */\n  public connectTo(targetNode: any, connectionOptions?: any) {\n    return this.connector.connectTo(targetNode, connectionOptions);\n  }\n\n  public disconnectFrom(targetNode: any): boolean {\n    return this.connector.disconnectFrom(targetNode);\n  }\n\n  public disconnectAll(): void {\n    this.connector.disconnectAll();\n  }\n\n  /** @returns All connection objects for this node. */\n  public getConnections() {\n    return this.connector.getConnections();\n  }\n\n  /**\n   * Get a specific connection by target node ID.\n   *\n   * @param targetNodeId - The target node[s ID\n   * @returns The connection object or null if not found\n   */\n  public getConnection(targetNodeId: string) {\n    return this.connector.getConnection(targetNodeId);\n  }\n\n  public isConnectorEnabled(): boolean {\n    return this.connector.isEnabled();\n  }\n\n  private centerTextInitial() {\n    this.centerText();\n  }\n\n  private calculatePathBounds(\n    svgContent: string,\n    width: number,\n    height: number\n  ): { x: number; y: number; width: number; height: number } {\n    // Try to extract viewBox from SVG if present\n    const viewBoxMatch = svgContent.match(/viewBox=[\"']([^\"']+)[\"']/);\n    if (viewBoxMatch) {\n      const viewBoxValues = viewBoxMatch[1].split(/\\s+/).map(Number);\n      if (viewBoxValues.length === 4) {\n        return {\n          x: viewBoxValues[0],\n          y: viewBoxValues[1],\n          width: viewBoxValues[2],\n          height: viewBoxValues[3],\n        };\n      }\n    }\n\n    // Try to extract width/height attributes from SVG\n    const widthMatch = svgContent.match(/width=[\"']([^\"']+)[\"']/);\n    const heightMatch = svgContent.match(/height=[\"']([^\"']+)[\"']/);\n\n    if (widthMatch && heightMatch) {\n      const svgWidth = parseInt(widthMatch[1]);\n      const svgHeight = parseInt(heightMatch[1]);\n      if (!isNaN(svgWidth) && !isNaN(svgHeight)) {\n        return { x: 0, y: 0, width: svgWidth, height: svgHeight };\n      }\n    }\n\n    // Fallback: assume common icon size\n    return { x: 0, y: 0, width: 24, height: 24 };\n  }\n\n  // Selection Management\n  private setupSelectionBehavior() {\n    // v1 contract: double-click asks the HOST to render its text pane\n    // (native dblclick as a fallback for programmatic dispatch; interactive\n    // double-clicks are detected in the pointerup path below)\n    this.svgGroup.on(\"dblclick\", (event: any) => {\n      if (this.isResizeRotateHandle(event.target)) return;\n      this.handleDoubleClickEdit();\n    });\n\n    // SOLUTION: Use pointerdown/pointerup with position-based click detection\n    let clickStartPosition: { x: number; y: number } | null = null;\n    const CLICK_THRESHOLD = 5; // pixels - if movement is less than this, it's a click\n\n    this.svgGroup.on(\"pointerdown\", (event: any) => {\n      // Skip if clicking on resize/rotate handles\n      if (this.isResizeRotateHandle(event.target)) {\n        console.log(\n          \"SELECTION_DEBUG: Clicked on resize/rotate handle, skipping selection logic\"\n        );\n        return;\n      }\n\n      // Record starting position for click detection\n      clickStartPosition = {\n        x: event.clientX || event.detail?.x || 0,\n        y: event.clientY || event.detail?.y || 0,\n      };\n    });\n\n    this.svgGroup.on(\"pointerup\", (event: any) => {\n      // Skip if clicking on resize/rotate handles\n      if (this.isResizeRotateHandle(event.target)) {\n        console.log(\n          \"SELECTION_DEBUG: Clicked on resize/rotate handle, skipping selection logic\"\n        );\n        clickStartPosition = null;\n        return;\n      }\n\n      if (clickStartPosition) {\n        const endPosition = {\n          x: event.clientX || event.detail?.x || 0,\n          y: event.clientY || event.detail?.y || 0,\n        };\n\n        const distance = Math.sqrt(\n          Math.pow(endPosition.x - clickStartPosition.x, 2) +\n            Math.pow(endPosition.y - clickStartPosition.y, 2)\n        );\n\n        if (distance <= CLICK_THRESHOLD) {\n          console.log(\n            \"SELECTION_DEBUG: Node clicked (position-based detection)\",\n            this.id\n          );\n\n          // In read-only / view mode, clicking a linked node follows its link\n          // (Miro-style — in edit mode the \"↗\" badge is the follow affordance so\n          // a normal click can still select/edit).\n          if (this.links?.hasLink?.() && this.slate.isReadOnly?.()) {\n            this.links.navigate();\n          } else {\n            // Check for multi-select modifier keys (shift included for Miro parity)\n            const isMultiSelect =\n              event.ctrlKey || event.metaKey || event.shiftKey;\n\n            // Let Slate handle the selection logic and resize/rotate enabling.\n            // (Modifier-click TOGGLE-off is intentionally NOT implemented: two\n            // attempts both destabilized multi-select — the pointerup/drag-start\n            // selection interplay is subtle, and additive shift-click is the\n            // behavior that matters. Documented as future work; needs a careful\n            // rework of the selection event flow, not a spot toggle here.)\n            this.slate.selectNodes([this], isMultiSelect);\n\n            // Double-click detection: svg.draggable's pointer handling\n            // suppresses native dblclick synthesis, so detect two quick\n            // clicks ourselves and request the host's text pane\n            const now = Date.now();\n            if (now - this._lastClickTime < 400) {\n              this._lastClickTime = 0;\n              this.handleDoubleClickEdit();\n            } else {\n              this._lastClickTime = now;\n            }\n          }\n        }\n\n        clickStartPosition = null;\n      }\n    });\n  }\n\n  /**\n   * Ask the host application to render its text-editing pane (v1's\n   * onTextPaneRequested contract). The callback the host invokes applies\n   * the edits via the Editor. No-op for read-only viewers, locked nodes,\n   * or when the host registered no handler.\n   */\n  public requestTextPane(): void {\n    const events = this.slate.options.events;\n    if (!events?.onTextPaneRequested) return;\n    if (this.slate.isReadOnly?.() || this.slate.isCommentOnly?.()) return;\n    if (this.options.isLocked) return;\n    events.onTextPaneRequested(this, (opts: any = {}) => {\n      this.editor?.set(\n        opts.text ?? this.options.text ?? \"\",\n        opts.fontSize,\n        opts.fontFamily,\n        opts.fontColor ?? opts.foregroundColor,\n        opts.textOpacity ?? opts.opacity,\n        opts.textXAlign,\n        opts.textYAlign\n      );\n    });\n  }\n\n  /**\n   * Double-click behaviour. Miro parity: double-clicking an ordinary text node\n   * edits its text inline on the canvas. Comment nodes, SVG-content nodes, locked\n   * / read-only nodes have no inline-editable text, so they fall back to the host\n   * text pane. The properties drawer stays reachable either way via the selection\n   * cog (which opens the same pane), so this doesn't remove drawer access.\n   */\n  public handleDoubleClickEdit(): void {\n    // Miro parity: double-clicking a GROUPED node enters the group for member\n    // editing (instead of text editing), unless we're already inside that group.\n    const slate: any = this.slate;\n    const gid = this.options.groupId;\n    if (\n      gid &&\n      typeof slate?.enterGroup === \"function\" &&\n      slate.getEnteredGroupId?.() !== gid\n    ) {\n      slate.enterGroup(gid, this);\n      return;\n    }\n    if (\n      !this.options.isComment &&\n      !this.nestedSvg &&\n      !this.options.isLocked &&\n      !this.slate.isReadOnly?.() &&\n      !this.slate.isCommentOnly?.() &&\n      typeof this.editor?.startInline === \"function\"\n    ) {\n      this.editor.startInline();\n    } else {\n      this.requestTextPane();\n    }\n  }\n\n  // Helper method to identify resize/rotate handles\n  private isResizeRotateHandle(target: any): boolean {\n    if (!target || !target.classList) return false;\n\n    // Check for common resize/rotate handle classes from svg.select.js and svg.resize.js\n    const handleClasses = [\n      \"svg-select-point\",\n      \"svg-resize-handle\",\n      \"svg_select_handle\",\n      \"svg_select_handle_rot\",\n      \"svg_select_handle_lt\",\n      \"svg_select_handle_rt\",\n      \"svg_select_handle_rb\",\n      \"svg_select_handle_lb\",\n      \"svg_select_handle_t\",\n      \"svg_select_handle_r\",\n      \"svg_select_handle_b\",\n      \"svg_select_handle_l\",\n      \"svg_select_handle_point\",\n    ];\n\n    // Check if target has any of the handle classes\n    for (const className of handleClasses) {\n      if (target.classList.contains(className)) {\n        return true;\n      }\n    }\n\n    // Also check data attributes that might be set by the plugins\n    if (\n      target.getAttribute &&\n      (target.getAttribute(\"data-handle\") ||\n        target.getAttribute(\"data-resize\") ||\n        target.getAttribute(\"data-rotate\"))\n    ) {\n      return true;\n    }\n\n    return false;\n  }\n\n  // Selection state management (handled by Slate)\n  /** Called by the Slate when this node is selected. */\n  public onSelected() {\n    console.log(\"SELECTION_DEBUG: Node selected\", this.id);\n    // Note: Slate now handles resize/rotate enabling + the node cog (M1)\n  }\n\n  private _nodeCog?: any;\n\n  /**\n   * Show the node context toolbar (G1) — a compact strip CENTERED ABOVE the\n   * node (legacy parity) with: delete, plug (drag-to-connect), cog (settings).\n   * Only shown on single selection (Slate.updateSelectionResizeRotate drives it).\n   */\n  public showNodeCog(): void {\n    if (this.options.allowMenu === false) return;\n    this.hideNodeCog();\n    const slate: any = this.slate;\n    const container: any = slate.markersContainer || slate.canvas;\n    if (!container || !this.svgGroup) return;\n    let cx: number, topY: number;\n    try {\n      const rb = this.svgGroup.rbox(slate.canvas); // world AABB (follows rotation)\n      cx = rb.x + rb.width / 2;\n      topY = rb.y;\n    } catch (e) {\n      cx = (this.options.x || 0) + (this.options.width || 0) / 2;\n      topY = this.options.y || 0;\n    }\n\n    const R = 15; // button hit radius\n    const GAP = 6; // gap between buttons\n    const NEUTRAL = \"#5b6472\";\n    const tools: Array<{\n      key: string;\n      color: string;\n      onClick?: () => void;\n      onPress?: (e: any) => void;\n    }> = [\n      { key: \"delete\", color: \"#e5484d\", onClick: () => this.slate.removeNode(this.id) },\n      // plug: press-drag-to-connect (G3) — starts on pointerdown, not click.\n      { key: \"plug\", color: NEUTRAL, onPress: (e: any) => this.startConnectDrag(e) },\n      { key: \"cog\", color: NEUTRAL, onClick: () => this.menu?.open?.() },\n    ];\n    const n = tools.length;\n    const stepX = R * 2 + GAP;\n    const totalW = n * (R * 2) + (n - 1) * GAP;\n    const startX = cx - totalW / 2 + R;\n    // Sit clearly above the node, the rotate handle, AND the top connection plug\n    // (which sits ~topOffset(35)+radius(8) ≈ 43px above the node top). Without the\n    // extra clearance the pill overlaps and covers that top \"create relationship\"\n    // dot on hover.\n    const barY = topY - (R + 28 + 36);\n\n    const bar = container.group().addClass(\"node-cog\").addClass(\"node-toolbar\");\n    // Modern (Miro-style) flat white pill.\n    bar\n      .rect(totalW + 14, R * 2 + 10)\n      .radius((R * 2 + 10) / 2)\n      .center(cx, barY)\n      .fill(\"#ffffff\")\n      .stroke({ color: \"#e3e5ea\", width: 1 });\n\n    tools.forEach((t, i) => {\n      const bx = startX + i * stepX;\n      const btn = bar.group().addClass(`node-tool-${t.key}`);\n      // transparent hit circle\n      btn.circle(R * 2).center(bx, barY).fill(\"#ffffff\").attr(\"fill-opacity\", 0.001);\n      Node.drawToolIcon(btn, t.key, bx, barY, t.color);\n      btn.attr(\"pointer-events\", \"all\");\n      try {\n        btn.node.style.cursor = \"pointer\";\n      } catch (e) {\n        /* noop */\n      }\n      btn.on(\"mousedown\", (e: any) => {\n        e.stopPropagation?.();\n        if (t.onPress) t.onPress(e);\n      });\n      btn.on(\"click\", (e: any) => {\n        e.stopPropagation?.();\n        t.onClick?.();\n      });\n    });\n\n    bar.attr(\"pointer-events\", \"all\");\n    this._nodeCog = bar;\n    try {\n      slate.markersContainer?.front?.();\n    } catch (e) {\n      /* noop */\n    }\n  }\n\n  /** Draw a crisp monochrome line-icon (delete/plug/cog) centered at (cx,cy). */\n  public static drawToolIcon(g: any, kind: string, cx: number, cy: number, color: string): void {\n    const s = { color, width: 1.6, linecap: \"round\", linejoin: \"round\" };\n    if (kind === \"delete\") {\n      // trash can\n      g.line(cx - 6, cy - 5, cx + 6, cy - 5).stroke(s); // lid\n      g.line(cx - 2.5, cy - 5, cx - 2, cy - 7.5).stroke(s);\n      g.line(cx + 2.5, cy - 5, cx + 2, cy - 7.5).stroke(s);\n      g.line(cx - 2, cy - 7.5, cx + 2, cy - 7.5).stroke(s); // handle\n      g.path(`M ${cx - 4.5} ${cy - 4} L ${cx - 3.8} ${cy + 6.5} L ${cx + 3.8} ${cy + 6.5} L ${cx + 4.5} ${cy - 4}`)\n        .fill(\"none\")\n        .stroke(s);\n      g.line(cx - 1.3, cy - 2, cx - 1.3, cy + 4).stroke({ color, width: 1.1, linecap: \"round\" });\n      g.line(cx + 1.3, cy - 2, cx + 1.3, cy + 4).stroke({ color, width: 1.1, linecap: \"round\" });\n    } else if (kind === \"plug\") {\n      // connection: two endpoints joined by a line (\"draw a connector\")\n      g.line(cx - 4, cy + 4, cx + 4, cy - 4).stroke(s);\n      g.circle(4.4).center(cx - 4.5, cy + 4.5).fill(color);\n      g.circle(4.4).center(cx + 4.5, cy - 4.5).fill(\"#ffffff\").stroke(s);\n    } else {\n      // cog (settings) — glyph is crisp + monochrome\n      g.text(\"⚙\")\n        .font({ size: 17, anchor: \"middle\", family: \"sans-serif\" })\n        .fill(color)\n        .center(cx, cy)\n        .attr(\"dy\", \"0.05em\");\n    }\n  }\n\n  public hideNodeCog(): void {\n    if (this._nodeCog) {\n      try {\n        this._nodeCog.remove();\n      } catch (e) {\n        /* noop */\n      }\n      this._nodeCog = undefined;\n    }\n  }\n\n  /**\n   * Plug drag-to-connect (G3): press the plug and drag — a dashed rubber-band\n   * line follows the pointer from this node; dropping on another node creates an\n   * association (connector) to it. Dropping on empty canvas does nothing.\n   */\n  public startConnectDrag(startEvent: any): void {\n    const slate: any = this.slate;\n    const canvas: any = slate.canvas;\n    if (!canvas) return;\n    // Guard against re-entry (a single press can emit both pointerdown+mousedown).\n    if ((this as any)._connectDragging) return;\n    (this as any)._connectDragging = true;\n    const container: any = slate.markersContainer || canvas;\n\n    // Start point = this node's center in world (canvas user) coordinates.\n    let sx: number, sy: number;\n    try {\n      const rb = this.svgGroup.rbox(canvas);\n      sx = rb.cx;\n      sy = rb.cy;\n    } catch (e) {\n      sx = (this.options.x || 0) + (this.options.width || 0) / 2;\n      sy = (this.options.y || 0) + (this.options.height || 0) / 2;\n    }\n\n    const temp = container\n      .path(`M ${sx} ${sy} L ${sx} ${sy}`)\n      .fill(\"none\")\n      .stroke({ color: \"#007cff\", width: 2, dasharray: \"6,4\", linecap: \"round\" })\n      .addClass(\"connect-drag-line\");\n    temp.attr(\"pointer-events\", \"none\");\n    // Arrowhead so the preview shows the tip meeting the node.\n    let previewArrow: any = null;\n    try {\n      previewArrow = container.marker(7, 7, (add: any) => {\n        add.path(\"M0,0 L7,3.5 L0,7 z\").fill(\"#007cff\").attr(\"pointer-events\", \"none\");\n      });\n      previewArrow.ref(6, 3.5);\n      previewArrow.attr(\"pointer-events\", \"none\");\n      (temp as any).marker(\"end\", previewArrow);\n    } catch (e) {\n      /* noop */\n    }\n    try {\n      slate.markersContainer?.front?.();\n    } catch (e) {\n      /* noop */\n    }\n\n    const norm = (vx: number, vy: number, fx: number, fy: number) => {\n      const m = Math.hypot(vx, vy);\n      if (m > 0.0001) return [vx / m, vy / m];\n      const fm = Math.hypot(fx, fy) || 1;\n      return [fx / fm, fy / fm];\n    };\n    // Point on an axis-aligned rect's edge along the direction center→(px,py).\n    const edgePoint = (o: any, px: number, py: number) => {\n      const cx = (o.x || 0) + (o.width || 0) / 2;\n      const cy = (o.y || 0) + (o.height || 0) / 2;\n      const dx = px - cx;\n      const dy = py - cy;\n      if (Math.abs(dx) < 0.001 && Math.abs(dy) < 0.001) return { x: cx, y: cy };\n      const sxr = dx !== 0 ? (o.width || 0) / 2 / Math.abs(dx) : Infinity;\n      const syr = dy !== 0 ? (o.height || 0) / 2 / Math.abs(dy) : Infinity;\n      const sc = Math.min(sxr, syr);\n      return { x: cx + dx * sc, y: cy + dy * sc };\n    };\n\n    let hovered: any = null;\n    const clearHover = () => {\n      if (hovered) {\n        try {\n          if (hovered._preHiStroke !== undefined) {\n            hovered.node.backgroundRect?.attr?.(\"stroke\", hovered._preHiStroke);\n          }\n          hovered.node.backgroundRect?.attr?.({\n            \"stroke-dasharray\": null,\n            \"stroke-opacity\": null,\n          });\n        } catch (e) {\n          /* noop */\n        }\n        hovered = null;\n      }\n    };\n\n    const toWorld = (clientX: number, clientY: number) => {\n      try {\n        return canvas.point(clientX, clientY);\n      } catch (e) {\n        return { x: sx, y: sy };\n      }\n    };\n\n    const nodeUnder = (clientX: number, clientY: number): Node | null => {\n      // Hide the preview (path + its arrow marker) so it doesn't intercept the\n      // hit-test for the node underneath the pointer.\n      let prevDisplay: string | undefined;\n      try {\n        prevDisplay = temp.node.style.display;\n        temp.node.style.display = \"none\";\n      } catch (e) {\n        /* noop */\n      }\n      const el = document.elementFromPoint(clientX, clientY) as Element | null;\n      try {\n        if (prevDisplay !== undefined) temp.node.style.display = prevDisplay;\n      } catch (e) {\n        /* noop */\n      }\n      const g = (el as any)?.closest?.(\"[data-node-id]\");\n      const id = g?.getAttribute?.(\"data-node-id\");\n      if (id && id !== this.id) return slate.nodes?.one?.(id) || null;\n      // elementFromPoint may land on a connection handle / resize handle (a global\n      // overlay circle with NO node ancestor) that sits over a node — those aren't\n      // drop targets. See THROUGH them: geometrically find the node whose rendered\n      // box contains the pointer, so a drop over a dot still connects to its node.\n      try {\n        const nodes = slate.nodes?.allNodes || [];\n        for (const n of nodes) {\n          if (!n || n.id === this.id) continue;\n          const box = document\n            .querySelector(`#slateCanvas [data-node-id=\"${n.id}\"]`)\n            ?.getBoundingClientRect?.();\n          // Small margin so a handle sitting just outside the edge still resolves.\n          const pad = 14;\n          if (\n            box &&\n            clientX >= box.left - pad &&\n            clientX <= box.right + pad &&\n            clientY >= box.top - pad &&\n            clientY <= box.bottom + pad\n          ) {\n            return n;\n          }\n        }\n      } catch (e) {\n        /* noop */\n      }\n      return null;\n    };\n\n    const onMove = (ev: any) => {\n      const w = toWorld(ev.clientX, ev.clientY);\n      const target = nodeUnder(ev.clientX, ev.clientY);\n\n      if (target && (target as any).options) {\n        // Curve to a perpendicular approach on the hovered node so the arrow\n        // tip meets its edge at ~90°, pointing at the node center.\n        const to = (target as any).options;\n        const tcx = (to.x || 0) + (to.width || 0) / 2;\n        const tcy = (to.y || 0) + (to.height || 0) / 2;\n        // Outline-aware attach so the PREVIEW matches the committed connector for\n        // custom/svgContent shapes (arrow flush to the artwork, not the bbox);\n        // falls back to the bbox edge if the outline can't be resolved.\n        const oEdge = (node: any, opt: any, px: number, py: number) => {\n          try {\n            const g = node && node.svgGroup;\n            if (g) {\n              const q = getClosestPointOnEdge(g, [px, py]);\n              if (q && isFinite(q[0]) && isFinite(q[1]))\n                return { x: q[0], y: q[1] };\n            }\n          } catch (e) {\n            /* noop */\n          }\n          return edgePoint(opt, px, py);\n        };\n        const tp = oEdge(target, to, sx, sy); // target outline toward source\n        const sp = oEdge(this, this.options, tcx, tcy); // source outline toward target center\n        const dx = tp.x - sp.x;\n        const dy = tp.y - sp.y;\n        const dist = Math.hypot(dx, dy) || 1;\n        const sDir = norm(sp.x - sx, sp.y - sy, dx, dy);\n        const tDir = norm(tp.x - tcx, tp.y - tcy, -dx, -dy);\n        const handle = Math.max(30, Math.min(dist * 0.45, 90));\n        const cp1x = sp.x + sDir[0] * handle;\n        const cp1y = sp.y + sDir[1] * handle;\n        const cp2x = tp.x + tDir[0] * handle;\n        const cp2y = tp.y + tDir[1] * handle;\n        temp.plot(\n          `M ${sp.x} ${sp.y} C ${cp1x} ${cp1y} ${cp2x} ${cp2y} ${tp.x} ${tp.y}`\n        );\n      } else {\n        // Free drag: straight line from the source center to the pointer.\n        temp.plot(`M ${sx} ${sy} L ${w.x} ${w.y}`);\n      }\n\n      if (target !== (hovered?.node || null)) {\n        clearHover();\n        if (target && (target as any).backgroundRect) {\n          const br = (target as any).backgroundRect;\n          hovered = { node: target, _preHiStroke: br.attr(\"stroke\") };\n          try {\n            br.attr({ stroke: \"#007cff\", \"stroke-dasharray\": \"8,4\", \"stroke-opacity\": 0.9 });\n          } catch (e) {\n            /* noop */\n          }\n        }\n      }\n    };\n\n    const onUp = (ev: any) => {\n      window.removeEventListener(\"pointermove\", onMove, true);\n      window.removeEventListener(\"pointerup\", onUp, true);\n      (this as any)._connectDragging = false;\n      try {\n        temp.remove();\n        previewArrow?.remove?.();\n        // Bulletproof: clear any stray preview paths too.\n        const strays = (canvas.node as any).querySelectorAll(\n          \".connect-drag-line\"\n        );\n        strays.forEach((el: Element) => el.remove());\n      } catch (e) {\n        /* noop */\n      }\n      const target = nodeUnder(ev.clientX, ev.clientY);\n      clearHover();\n      if (target && target.id !== this.id) {\n        try {\n          // Pin the new edge's target endpoint at the DROP point (normalized 0..1\n          // anchor on the target node), so the arrow lands exactly where the user\n          // dropped it (named bug #4) AND a second/parallel line to the same node\n          // is visually distinct instead of overlapping the first at the auto edge\n          // point.\n          let data: any = undefined;\n          try {\n            const w = toWorld(ev.clientX, ev.clientY);\n            const to = (target as any).options;\n            const ax = Math.max(\n              0,\n              Math.min(1, (w.x - (to.x || 0)) / (to.width || 1))\n            );\n            const ay = Math.max(\n              0,\n              Math.min(1, (w.y - (to.y || 0)) / (to.height || 1))\n            );\n            // Only PIN an absolute anchor when the drop is DELIBERATELY near an edge.\n            // A drop in the node's interior/center uses RELATIVE auto-flow so the arrow\n            // attaches at the natural source-facing edge (arrowhead visible outside the\n            // node), instead of snapping to an arbitrary edge that routes the arrow\n            // awkwardly around and can obscure the head. (There is no 'center' target.)\n            const edgeDist = Math.min(ax, 1 - ax, ay, 1 - ay);\n            if (edgeDist < 0.25) {\n              // Near an edge — pin to that edge (perimeter), keeping the along-edge\n              // position so parallel edges dropped at different edges stay distinct.\n              let sx = ax,\n                sy = ay;\n              const dl = ax,\n                dr = 1 - ax,\n                dt = ay,\n                db = 1 - ay;\n              const m = Math.min(dl, dr, dt, db);\n              if (m === dl) sx = 0;\n              else if (m === dr) sx = 1;\n              else if (m === dt) sy = 0;\n              else sy = 1;\n              data = { targetAnchor: { x: sx, y: sy } };\n            }\n            // else: interior drop → data stays undefined → relative auto-flow to the\n            // source-facing edge (like a normal connection).\n          } catch (e) {\n            /* fall back to auto-attach */\n          }\n          this.relationships.addAssociation(target, data);\n        } catch (e) {\n          /* noop */\n        }\n      } else if (!target) {\n        // Miro parity: dropping the connector on EMPTY canvas creates a NEW node\n        // at the drop point, connected from this node — fast mind-map growth.\n        try {\n          const w = toWorld(ev.clientX, ev.clientY);\n          // nodeUnder EXCLUDES this node (self), so a release back ON the source\n          // also arrives here with target=null — that's a CANCEL, not empty canvas.\n          // Guard against spawning a node on top of the source (a self-drop no-op).\n          const o = this.options;\n          const pad = 16;\n          const overSelf =\n            w.x >= (o.x || 0) - pad &&\n            w.x <= (o.x || 0) + (o.width || 0) + pad &&\n            w.y >= (o.y || 0) - pad &&\n            w.y <= (o.y || 0) + (o.height || 0) + pad;\n          if (!slate.isReadOnly?.() && !overSelf) {\n            const nw = 120;\n            const nh = 70;\n            const newNode = slate.addNode({\n              x: Math.round(w.x - nw / 2),\n              y: Math.round(w.y - nh / 2),\n              width: nw,\n              height: nh,\n              text: \"\",\n            });\n            if (newNode) {\n              // Connect once the new node has finished rendering (createAsync), so\n              // the connector attaches to a laid-out shape.\n              const connect = () => {\n                try {\n                  this.relationships.addAssociation(newNode);\n                } catch (e) {\n                  /* noop */\n                }\n              };\n              if ((newNode as any).ready?.then)\n                (newNode as any).ready.then(connect);\n              else connect();\n              slate.selectNodes?.([newNode]);\n            }\n          }\n        } catch (e) {\n          /* noop */\n        }\n      }\n    };\n\n    window.addEventListener(\"pointermove\", onMove, true);\n    window.addEventListener(\"pointerup\", onUp, true);\n  }\n\n  /** Called by the Slate when this node is deselected. */\n  public onDeselected() {\n    console.log(\"SELECTION_DEBUG: Node deselected\", this.id);\n    // Note: Slate now handles resize/rotate disabling\n  }\n\n  // Connection Handles for New Node Creation\n  private createConnectionHandles() {\n    if (this.connectionHandles.container) {\n      console.log(\n        \"CONNECTION_HANDLES_DEBUG: Handles already exist for\",\n        this.id\n      );\n      return;\n    }\n\n    console.log(\n      \"CONNECTION_HANDLES_DEBUG: Creating connection handles for\",\n      this.id\n    );\n\n    // Create container for all connection handles at canvas level\n    // IMPORTANT: Must be outside svgGroup to avoid affecting group's bbox during drag\n    this.connectionHandles.container = this.slate.canvas.group();\n    // The circles sit just OUTSIDE the node, so moving from node → circle briefly\n    // leaves the node's hover region. Keep them alive while the pointer is over\n    // the handle container (cancels the hide debounce).\n    this.connectionHandles.container.on(\"mouseenter\", () =>\n      this.revealConnHandlesOnHover()\n    );\n    this.connectionHandles.container.on(\"mouseleave\", () =>\n      this.scheduleConnHandlesHide()\n    );\n\n    const handleRadius = 8;\n    const handleColor = \"#007cff\";\n    const handleStroke = \"#ffffff\";\n    const handleStrokeWidth = 2;\n\n    // Create four connection handles positioned around the node\n    const positions = {\n      top: { x: 0, y: -handleRadius - 5 },\n      right: { x: handleRadius + 5, y: 0 },\n      bottom: { x: 0, y: handleRadius + 5 },\n      left: { x: -handleRadius - 5, y: 0 },\n    };\n\n    Object.entries(positions).forEach(([direction, offset]) => {\n      if (!this.connectionHandles.container) return;\n\n      const handle = this.connectionHandles.container\n        .circle(handleRadius * 2)\n        .fill(handleColor)\n        .stroke({ color: handleStroke, width: handleStrokeWidth })\n        .addClass(`connection-handle connection-handle-${direction}`);\n\n      // Set cursor style using DOM node\n      handle.node.style.cursor = \"pointer\";\n\n      // Store reference\n      this.connectionHandles[direction as keyof typeof positions] = handle;\n\n      // Add hover effects for preview\n      handle.on(\"mouseenter\", () =>\n        this.showConnectionPreview(\n          direction as \"top\" | \"right\" | \"bottom\" | \"left\"\n        )\n      );\n      handle.on(\"mouseleave\", () => this.hideConnectionPreview());\n\n      // Add click handler for node creation and connection\n      handle.on(\"click\", (event: any) => {\n        event.stopPropagation();\n        console.log(\n          `CONNECTION_HANDLES_DEBUG: ${direction} handle clicked on`,\n          this.id\n        );\n\n        // Create new connected node\n        this.createConnectedNode(\n          direction as \"top\" | \"right\" | \"bottom\" | \"left\"\n        );\n      });\n\n      // Miro-style: DRAG from a plug-circle to connect to another node (or create\n      // one at the drop). A plain click still creates a node in that direction\n      // (above). We distinguish drag from click with a small movement threshold —\n      // once the pointer moves past it, we hand off to startConnectDrag (same path\n      // as the plug tool) and suppress the ensuing click.\n      handle.on(\"pointerdown\", (event: any) => {\n        if (this.slate?.isReadOnly?.()) return;\n        event.stopPropagation();\n        const startX = event.clientX;\n        const startY = event.clientY;\n        let handedOff = false;\n        const cleanup = () => {\n          window.removeEventListener(\"pointermove\", onMove, true);\n          window.removeEventListener(\"pointerup\", onUp, true);\n        };\n        const onMove = (e: PointerEvent) => {\n          if (handedOff) return;\n          if (Math.hypot(e.clientX - startX, e.clientY - startY) > 5) {\n            handedOff = true;\n            cleanup();\n            // Swallow the click that would otherwise fire createConnectedNode.\n            const swallow = (ce: Event) => {\n              ce.stopPropagation();\n              (handle.node as any).removeEventListener(\"click\", swallow, true);\n            };\n            (handle.node as any).addEventListener(\"click\", swallow, true);\n            this.startConnectDrag(event);\n          }\n        };\n        const onUp = () => cleanup();\n        window.addEventListener(\"pointermove\", onMove, true);\n        window.addEventListener(\"pointerup\", onUp, true);\n      });\n    });\n\n    // Initially hidden\n    if (this.connectionHandles.container) {\n      this.connectionHandles.container.hide();\n    }\n    this.updateConnectionHandlePositions();\n  }\n\n  private updateConnectionHandlePositions() {\n    if (!this.connectionHandles.container || !this.connectionHandlesVisible)\n      return;\n\n    // Get the backgroundRect's bbox and transformation matrix\n    // This is the same approach svg.select.js uses for resize handles\n    const bbox = this.backgroundRect.bbox();\n\n    // Get transformation matrices\n    const elMatrix = (this.backgroundRect as any).screenCTM();\n    const rootMatrix = (this.backgroundRect as any).root().screenCTM();\n    const fromShapeToUiMatrix = rootMatrix.inverseO().multiplyO(elMatrix);\n\n    // Helper function to transform points (same as svg.select.js transformPoint)\n    const transformPoint = ([x, y]: number[], { a, b, c, d, e, f }: any) => {\n      return [x * a + y * c + e, x * b + y * d + f];\n    };\n\n    const centerX = bbox.x + bbox.width / 2;\n    const centerY = bbox.y + bbox.height / 2;\n\n    // Better spacing to avoid overlaps and clear the rotate icon\n    const topOffset = 35;\n    const sideOffset = 20;\n\n    // Define positions in bbox space (before transformation)\n    const bboxPositions = {\n      top: [centerX, bbox.y - topOffset],\n      right: [bbox.x + bbox.width + sideOffset, centerY],\n      bottom: [centerX, bbox.y + bbox.height + sideOffset],\n      left: [bbox.x - sideOffset, centerY],\n    };\n\n    // Transform each position using the transformation matrix\n    Object.entries(bboxPositions).forEach(([direction, pos]) => {\n      const handle = this.connectionHandles[direction as keyof typeof bboxPositions];\n      if (handle) {\n        const [transformedX, transformedY] = transformPoint(pos, fromShapeToUiMatrix);\n        handle.center(transformedX, transformedY);\n      }\n    });\n  }\n\n  /**\n   * Miro-style: reveal the plug-circles when the node is hovered (not just when\n   * selected), so you can drag-to-connect without selecting first. A hide\n   * debounce bridges the small gap between the node edge and the offset circles;\n   * selection pins them (`_connHandlesPinned`); a connect-drag keeps them alive.\n   */\n  private wireConnectionHandleHover(): void {\n    if (!this.svgGroup) return;\n    this.svgGroup.on(\"mouseenter\", () => this.revealConnHandlesOnHover());\n    this.svgGroup.on(\"mouseleave\", () => this.scheduleConnHandlesHide());\n  }\n\n  private revealConnHandlesOnHover(): void {\n    if (this.slate?.isReadOnly?.()) return;\n    // Don't reveal while this node is being dragged. The pointer stays over the\n    // moving node so mouseenter re-fires, which re-showed the plug handles at their\n    // stale (pre-drag) position — leaving \"ghost\" dots behind at the old spot while\n    // the node moved away. dragstart hides them and dragend re-anchors them at the\n    // new position (see makeDraggable), i.e. hide-on-mousedown / show-on-mouseup.\n    if (this.isDragging) return;\n    if (this._connHandleHideTimer) {\n      clearTimeout(this._connHandleHideTimer);\n      this._connHandleHideTimer = null;\n    }\n    if (!this.connectionHandlesVisible) this.showConnectionHandles();\n  }\n\n  private scheduleConnHandlesHide(): void {\n    if (this._connHandlesPinned) return; // selected → keep shown\n    if (this._connHandleHideTimer) clearTimeout(this._connHandleHideTimer);\n    this._connHandleHideTimer = setTimeout(() => {\n      this._connHandleHideTimer = null;\n      if (this._connHandlesPinned || (this as any)._connectDragging) return;\n      this.hideConnectionHandles();\n    }, 220);\n  }\n\n  private showConnectionHandles() {\n    if (!this.connectionHandles.container) {\n      this.createConnectionHandles();\n    }\n\n    console.log(\n      \"CONNECTION_HANDLES_DEBUG: Showing connection handles for\",\n      this.id\n    );\n    this.connectionHandlesVisible = true;\n    if (this.connectionHandles.container) {\n      this.connectionHandles.container.show();\n    }\n    this.updateConnectionHandlePositions();\n  }\n\n  private hideConnectionHandles() {\n    if (!this.connectionHandles.container) return;\n\n    console.log(\n      \"CONNECTION_HANDLES_DEBUG: Hiding connection handles for\",\n      this.id\n    );\n    this.connectionHandlesVisible = false;\n    if (this.connectionHandles.container) {\n      this.connectionHandles.container.hide();\n    }\n    this.hideConnectionPreview();\n  }\n\n  private showConnectionPreview(\n    direction: \"top\" | \"right\" | \"bottom\" | \"left\"\n  ) {\n    // Prevent creating duplicate previews\n    if (this.connectionPreview?.container) {\n      return; // Preview already exists, don't create another\n    }\n\n    console.log(\n      \"CONNECTION_HANDLES_DEBUG: Showing preview for\",\n      direction,\n      \"on\",\n      this.id\n    );\n\n    // Clean up existing preview (shouldn't be needed now, but safe)\n    this.hideConnectionPreview();\n\n    // Create preview container in ROOT space (not in node's group) to avoid coordinate system issues\n    // The node's svgGroup might be rotated, which would interfere with the preview rotation\n    const viewport = this.svgGroup.root();\n    this.connectionPreview = {\n      container: viewport.group().attr(\"pointer-events\", \"none\"),\n    };\n\n    const nodeWidth = this.options.width!;\n    const nodeHeight = this.options.height!;\n    const spacing = 75; // Reduced spacing for better layout (was 120)\n\n    // Get the current node's rotation angle\n    const rotationAngle = this.getRotation();\n\n    // Get the ACTUAL center of the rotated shape (not the bbox center)\n    // For rotated shapes, bbox() gives the axis-aligned bounding box which has a different center\n    // We need to use rbox() to get the real position after rotation\n    const rbox = (this.backgroundRect as any).rbox(this.backgroundRect.root());\n    const actualCenterX = rbox.cx;\n    const actualCenterY = rbox.cy;\n\n    // Get the connection handle's position (the blue dot that was hovered)\n    const handle = this.connectionHandles[direction];\n    if (!handle) {\n      console.warn(\"CONNECTION_HANDLES_DEBUG: Handle not found for direction\", direction);\n      return;\n    }\n\n    // Get the handle's center position (the blue dot)\n    const handleBBox = handle.bbox();\n    const handleCenter = {\n      x: handleBBox.x + handleBBox.width / 2,\n      y: handleBBox.y + handleBBox.height / 2,\n    };\n\n    // Calculate the perpendicular direction from geometry\n    // The vector from node center to handle IS the perpendicular direction to that edge\n    const dirX = handleCenter.x - actualCenterX;\n    const dirY = handleCenter.y - actualCenterY;\n    const dirLength = Math.sqrt(dirX * dirX + dirY * dirY);\n\n    // Normalize to unit vector (this is our perpendicular direction)\n    const rotatedDirX = dirX / dirLength;\n    const rotatedDirY = dirY / dirLength;\n\n    // Calculate edge distance by finding the actual edge position using transformation matrix\n    const bbox = this.backgroundRect.bbox();\n    const bboxCenterX = bbox.x + bbox.width / 2;\n    const bboxCenterY = bbox.y + bbox.height / 2;\n\n    const elMatrix = (this.backgroundRect as any).screenCTM();\n    const rootMatrix = (this.backgroundRect as any).root().screenCTM();\n    const fromShapeToUiMatrix = rootMatrix.inverseO().multiplyO(elMatrix);\n\n    // Inverse transform the direction vector to bbox space to correctly identify the edge\n    const inverseMatrix = fromShapeToUiMatrix.inverse();\n\n    // Transform direction vector (not point) - use matrix without translation\n    const bboxDirX = rotatedDirX * inverseMatrix.a + rotatedDirY * inverseMatrix.c;\n    const bboxDirY = rotatedDirX * inverseMatrix.b + rotatedDirY * inverseMatrix.d;\n\n    // Now determine which bbox edge based on bbox-space direction\n    let bboxEdgeX, bboxEdgeY;\n    const absX = Math.abs(bboxDirX);\n    const absY = Math.abs(bboxDirY);\n\n    if (absY > absX) {\n      // Top or bottom edge in bbox space\n      if (bboxDirY < 0) {\n        // Top edge\n        bboxEdgeX = bboxCenterX;\n        bboxEdgeY = bbox.y;\n      } else {\n        // Bottom edge\n        bboxEdgeX = bboxCenterX;\n        bboxEdgeY = bbox.y + bbox.height;\n      }\n    } else {\n      // Left or right edge in bbox space\n      if (bboxDirX < 0) {\n        // Left edge\n        bboxEdgeX = bbox.x;\n        bboxEdgeY = bboxCenterY;\n      } else {\n        // Right edge\n        bboxEdgeX = bbox.x + bbox.width;\n        bboxEdgeY = bboxCenterY;\n      }\n    }\n\n    // Transform edge position to world space\n    const transformPoint = ([x, y]: number[], { a, b, c, d, e, f }: any) => {\n      return [x * a + y * c + e, x * b + y * d + f];\n    };\n\n    const [worldEdgeX, worldEdgeY] = transformPoint([bboxEdgeX, bboxEdgeY], fromShapeToUiMatrix);\n\n    // Calculate actual edge distance in world space\n    const sourceEdgeDistance = Math.sqrt(\n      Math.pow(worldEdgeX - actualCenterX, 2) + Math.pow(worldEdgeY - actualCenterY, 2)\n    );\n\n    const previewEdgeDistance = sourceEdgeDistance; // Same size and rotation\n\n    // Position preview with consistent edge-to-edge gap\n    // Total distance = source center to edge + gap + preview edge to center\n    const totalDistance = sourceEdgeDistance + spacing + previewEdgeDistance;\n\n    const newCenterX = actualCenterX + rotatedDirX * totalDistance;\n    const newCenterY = actualCenterY + rotatedDirY * totalDistance;\n    const newNodeX = newCenterX - nodeWidth / 2;\n    const newNodeY = newCenterY - nodeHeight / 2;\n\n    // Ensure container exists\n    if (!this.connectionPreview.container) {\n      console.warn(\"CONNECTION_HANDLES_DEBUG: Preview container not found\");\n      return;\n    }\n\n    // Create ghost node preview that mirrors the original node's shape\n    this.connectionPreview.node = this.createPreviewShape(\n      this.connectionPreview.container,\n      newNodeX,\n      newNodeY,\n      nodeWidth,\n      nodeHeight,\n      rotationAngle // Pass rotation angle to preview\n    );\n\n    // Calculate arrow endpoint to touch the preview node's near edge\n    // Preview near edge is at: sourceCenter + direction * (sourceEdgeDistance + spacing)\n    // Arrow should extend from handle to this exact point\n    const previewNearEdgeDistance = sourceEdgeDistance + spacing;\n    const arrowLength = previewNearEdgeDistance - dirLength; // dirLength is distance from center to handle\n    const arrowEnd = {\n      x: handleCenter.x + rotatedDirX * arrowLength,\n      y: handleCenter.y + rotatedDirY * arrowLength,\n    };\n\n    // Create the connector line from handle center extending perpendicular to the edge\n    this.connectionPreview.connector = this.connectionPreview.container\n      .line(handleCenter.x, handleCenter.y, arrowEnd.x, arrowEnd.y)\n      .stroke({ color: \"#007cff\", width: 2, opacity: 0.7 })\n      .attr(\"pointer-events\", \"none\");\n\n    // Add arrowhead at the end of the perpendicular line\n    this.addArrowheadToConnector(\n      this.connectionPreview.container,\n      handleCenter,\n      arrowEnd\n    );\n  }\n\n  private createPreviewShape(\n    container: any,\n    x: number,\n    y: number,\n    width: number,\n    height: number,\n    rotationAngle: number = 0\n  ): any {\n    let previewNode;\n    const fillColor = this.options.backgroundColor || \"#007cff\"; // Use node's actual color\n    const strokeColor = \"#ffffff\";\n    const strokeWidth = 2;\n    const opacity = 0.6;\n\n    // Calculate the center point for rotation\n    const centerX = x + width / 2;\n    const centerY = y + height / 2;\n\n    // Mirror the original node's shape\n    switch (this.options.shape) {\n      case \"circle\":\n        const radius = Math.min(width, height) / 2;\n        previewNode = container\n          .circle(radius * 2)\n          .center(centerX, centerY)\n          .fill(fillColor)\n          .stroke({ color: strokeColor, width: strokeWidth })\n          .opacity(opacity);\n        if (rotationAngle !== 0) {\n          previewNode.rotate(rotationAngle, centerX, centerY);\n        }\n        break;\n\n      case \"ellipse\":\n        previewNode = container\n          .ellipse(width, height)\n          .center(centerX, centerY)\n          .fill(fillColor)\n          .stroke({ color: strokeColor, width: strokeWidth })\n          .opacity(opacity);\n        if (rotationAngle !== 0) {\n          previewNode.rotate(rotationAngle, centerX, centerY);\n        }\n        break;\n\n      default: // rectangle or any other shape defaults to rectangle\n        if (this.options.svgContent) {\n          // For SVG content nodes, create a preview that shows the actual SVG\n          previewNode = container\n            .rect(width, height)\n            .move(x, y)\n            .fill(\"none\")\n            .stroke({ color: strokeColor, width: strokeWidth })\n            .opacity(opacity)\n            .radius(4);\n\n          // Create nested SVG with the actual content\n          const previewSvg = container.nested().size(width, height).move(x, y);\n          previewSvg.svg(this.options.svgContent);\n\n          // Apply the preview styling to the nested content\n          this._previewViewboxTimeoutId = setTimeout(() => {\n            if (this._destroyed) return;\n            const content = previewSvg.children()[0] as any;\n            if (content) {\n              let bb = content.bbox();\n              if (bb.width <= 0 || bb.height <= 0) {\n                bb = this.calculatePathBounds(\n                  this.options.svgContent!,\n                  width,\n                  height\n                );\n              }\n\n              if (bb.width > 0 && bb.height > 0) {\n                previewSvg.viewbox(bb.x, bb.y, bb.width, bb.height);\n                previewSvg.node.setAttribute(\"preserveAspectRatio\", \"none\");\n              }\n\n              // Apply blue color and opacity to the SVG content\n              content.fill(fillColor).opacity(opacity);\n            }\n          }, 1);\n\n          previewSvg.attr(\"pointer-events\", \"none\");\n\n          // Apply rotation if specified\n          if (rotationAngle !== 0) {\n            previewNode.rotate(rotationAngle, centerX, centerY);\n            previewSvg.rotate(rotationAngle, centerX, centerY);\n          }\n        } else {\n          // Regular rectangle node\n          previewNode = container\n            .rect(width, height)\n            .move(x, y)\n            .fill(fillColor)\n            .stroke({ color: strokeColor, width: strokeWidth })\n            .opacity(opacity)\n            .radius(4);\n\n          // Apply rotation if specified\n          if (rotationAngle !== 0) {\n            previewNode.rotate(rotationAngle, centerX, centerY);\n          }\n        }\n        break;\n    }\n\n    return previewNode.attr(\"pointer-events\", \"none\");\n  }\n\n  private addArrowheadToConnector(\n    container: any,\n    start: { x: number; y: number },\n    end: { x: number; y: number }\n  ) {\n    // Calculate arrow direction\n    const dx = end.x - start.x;\n    const dy = end.y - start.y;\n    const length = Math.sqrt(dx * dx + dy * dy);\n\n    if (length === 0) return;\n\n    // Normalize direction\n    const unitX = dx / length;\n    const unitY = dy / length;\n\n    // Arrow size\n    const arrowLength = 12;\n    const arrowWidth = 6;\n\n    // Position arrowhead at the end of the line\n    const arrowTipX = end.x;\n    const arrowTipY = end.y;\n\n    // Calculate arrow base points\n    const baseX = arrowTipX - unitX * arrowLength;\n    const baseY = arrowTipY - unitY * arrowLength;\n\n    // Perpendicular vector for arrow width\n    const perpX = -unitY * arrowWidth;\n    const perpY = unitX * arrowWidth;\n\n    // Arrow points\n    const arrowPoints = [\n      [arrowTipX, arrowTipY],\n      [baseX + perpX, baseY + perpY],\n      [baseX - perpX, baseY - perpY],\n      [arrowTipX, arrowTipY],\n    ];\n\n    // Create arrowhead\n    container\n      .polygon(arrowPoints)\n      .fill(\"#007cff\")\n      .opacity(0.8)\n      .attr(\"pointer-events\", \"none\");\n  }\n\n  private hideConnectionPreview() {\n    if (this.connectionPreview?.container) {\n      this.connectionPreview.container.remove();\n      this.connectionPreview = undefined;\n    }\n  }\n\n  /** Show connection handles (4 blue dots) on this node for creating connected siblings. */\n  public enableConnectionHandles() {\n    console.log(\n      \"CONNECTION_HANDLES_DEBUG: enableConnectionHandles called for\",\n      this.id\n    );\n    // Pinned by selection → hover-leave won't hide them.\n    this._connHandlesPinned = true;\n    if (this._connHandleHideTimer) {\n      clearTimeout(this._connHandleHideTimer);\n      this._connHandleHideTimer = null;\n    }\n    // While THIS node is mid-drag, don't show the plug handles: they live in a\n    // global canvas group (not the node's group) so they wouldn't follow the node\n    // and would leave \"ghost\" dots at the old position. Selection re-runs\n    // updateSelectionResizeRotate() during drag (resize/rotate toggling), which\n    // lands here — stay pinned but hidden; drag-end re-anchors them at the new spot.\n    if (this.isDragging) return;\n    this.showConnectionHandles();\n  }\n\n  /** Hide connection handles on this node. */\n  public disableConnectionHandles() {\n    console.log(\n      \"CONNECTION_HANDLES_DEBUG: disableConnectionHandles called for\",\n      this.id\n    );\n    this._connHandlesPinned = false;\n    this.hideConnectionHandles();\n  }\n\n  public isConnectionHandlesEnabled(): boolean {\n    return this.connectionHandlesVisible;\n  }\n\n  private getNodeEdgePoint(\n    bbox: any,\n    direction: \"top\" | \"right\" | \"bottom\" | \"left\"\n  ): { x: number; y: number } {\n    const centerX = bbox.x + bbox.width / 2;\n    const centerY = bbox.y + bbox.height / 2;\n\n    // Calculate edge points based on node shape and direction\n    switch (direction) {\n      case \"top\":\n        return { x: centerX, y: bbox.y };\n      case \"right\":\n        return { x: bbox.x + bbox.width, y: centerY };\n      case \"bottom\":\n        return { x: centerX, y: bbox.y + bbox.height };\n      case \"left\":\n        return { x: bbox.x, y: centerY };\n    }\n  }\n\n  private createConnectedNode(\n    direction: \"top\" | \"right\" | \"bottom\" | \"left\"\n  ): void {\n    console.log(\n      \"CONNECTION_HANDLES_DEBUG: Creating connected node in direction\",\n      direction,\n      \"from\",\n      this.id\n    );\n\n    try {\n      // Calculate position for new node (same as preview calculation)\n      const nodeWidth = this.options.width!;\n      const nodeHeight = this.options.height!;\n      const spacing = 75;\n\n      // Get the current node's rotation angle\n      const rotationAngle = this.getRotation();\n      const rotationRad = (rotationAngle * Math.PI) / 180;\n\n      // Calculate direction vector in the rotated coordinate space\n      let dirX = 0, dirY = 0;\n      switch (direction) {\n        case \"top\":\n          dirX = 0;\n          dirY = -1;\n          break;\n        case \"right\":\n          dirX = 1;\n          dirY = 0;\n          break;\n        case \"bottom\":\n          dirX = 0;\n          dirY = 1;\n          break;\n        case \"left\":\n          dirX = -1;\n          dirY = 0;\n          break;\n      }\n\n      // Rotate the direction vector by the node's rotation angle\n      const rotatedDirX = dirX * Math.cos(rotationRad) - dirY * Math.sin(rotationRad);\n      const rotatedDirY = dirX * Math.sin(rotationRad) + dirY * Math.cos(rotationRad);\n\n      // Get the ACTUAL center of the rotated shape (not the bbox center)\n      const rbox = (this.backgroundRect as any).rbox(this.backgroundRect.root());\n      const actualCenterX = rbox.cx;\n      const actualCenterY = rbox.cy;\n\n      // Calculate new node position based on rotated direction\n      // Use transformation matrix to get accurate edge distance (accounts for rotation)\n\n      const bbox = this.backgroundRect.bbox();\n      const bboxCenterX = bbox.x + bbox.width / 2;\n      const bboxCenterY = bbox.y + bbox.height / 2;\n\n      // Find the bbox edge position based on direction\n      let bboxEdgeX, bboxEdgeY;\n      switch (direction) {\n        case 'top':\n          bboxEdgeX = bboxCenterX;\n          bboxEdgeY = bbox.y;\n          break;\n        case 'right':\n          bboxEdgeX = bbox.x + bbox.width;\n          bboxEdgeY = bboxCenterY;\n          break;\n        case 'bottom':\n          bboxEdgeX = bboxCenterX;\n          bboxEdgeY = bbox.y + bbox.height;\n          break;\n        case 'left':\n          bboxEdgeX = bbox.x;\n          bboxEdgeY = bboxCenterY;\n          break;\n      }\n\n      // Transform edge position to world space\n      const elMatrix = (this.backgroundRect as any).screenCTM();\n      const rootMatrix = (this.backgroundRect as any).root().screenCTM();\n      const fromShapeToUiMatrix = rootMatrix.inverseO().multiplyO(elMatrix);\n\n      const transformPoint = ([x, y]: number[], { a, b, c, d, e, f }: any) => {\n        return [x * a + y * c + e, x * b + y * d + f];\n      };\n\n      const [worldEdgeX, worldEdgeY] = transformPoint([bboxEdgeX, bboxEdgeY], fromShapeToUiMatrix);\n\n      // Calculate actual edge distance in world space\n      const sourceEdgeDistance = Math.sqrt(\n        Math.pow(worldEdgeX - actualCenterX, 2) + Math.pow(worldEdgeY - actualCenterY, 2)\n      );\n\n      const newNodeEdgeDistance = sourceEdgeDistance; // Same size and rotation\n\n      // Position with consistent edge-to-edge gap\n      // Total distance = source center to edge + gap + new node edge to center\n      const totalDistance = sourceEdgeDistance + spacing + newNodeEdgeDistance;\n\n      const newCenterX = actualCenterX + rotatedDirX * totalDistance;\n      const newCenterY = actualCenterY + rotatedDirY * totalDistance;\n      const newNodeX = newCenterX - nodeWidth / 2;\n      const newNodeY = newCenterY - nodeHeight / 2;\n\n      // Clone the current node's options for the new node (including rotation)\n      const newNodeOptions = this.cloneNodeOptions(newNodeX, newNodeY, rotationAngle);\n\n      // Create the new node via Slate\n      const newNode = this.slate.addNode(newNodeOptions);\n\n      if (!newNode) {\n        console.error(\"CONNECTION_HANDLES_DEBUG: Failed to create new node\");\n        return;\n      }\n\n      console.log(\n        \"CONNECTION_HANDLES_DEBUG: Created new node\",\n        newNode.id,\n        \"at\",\n        newNodeX,\n        newNodeY\n      );\n\n      // Hide the preview and handles before creating connection\n      this.hideConnectionPreview();\n\n      // Wait a moment for the new node to be fully created, then connect\n      this._connectTimeoutId = setTimeout(() => {\n        if (!this._destroyed) this.connectToNode(newNode);\n      }, 100);\n    } catch (error) {\n      console.error(\n        \"CONNECTION_HANDLES_DEBUG: Error creating connected node:\",\n        error\n      );\n    }\n  }\n\n  private cloneNodeOptions(x: number, y: number, rotationAngle?: number): any {\n    // Generate unique ID for the new node\n    const newId = \"node_\" + Math.random().toString(36).substr(2, 9);\n\n    // Clone most options from current node but with new position and ID\n    const options: any = {\n      ...this.options,\n      id: newId,\n      x: x,\n      y: y,\n      text: `Node ${newId.split(\"_\")[1]}`, // Give it a different default text\n      // Inherit the source node's rotation angle so the new node MATCHES the drag preview,\n      // but give it its OWN independent rotate object — a fresh object, NOT the shared\n      // reference the `...this.options` spread would leave. That shared reference was the\n      // bug: rotating the source LATER also rotated the new node (both pointed at the same\n      // object, applied on the new node's next drag). A fresh copy makes each node rotate\n      // independently from then on.\n      rotate: {\n        rotationAngle:\n          (rotationAngle !== undefined\n            ? rotationAngle\n            : this.options.rotate?.rotationAngle) || 0,\n      },\n    };\n\n    return options;\n  }\n\n  private connectToNode(targetNode: any): void {\n    // Route through the RELATIONSHIPS model, not connector.connectTo() directly.\n    // addAssociation() (a) records the association in assocMap so it serializes\n    // and survives a reload, (b) renders the connector line, and (c) broadcasts\n    // \"addRelationship\" so peers get it too. Calling connector.connectTo()\n    // directly was visual-only — the line neither synced to collaborators nor\n    // survived a refresh (collab bugs #3 + #6).\n    if (this.relationships) {\n      // Don't duplicate an existing association\n      if (this.relationships.getAssociation?.(targetNode.id)) {\n        return;\n      }\n      this.relationships.addAssociation(targetNode);\n      return;\n    }\n\n    // Fallback (relationships unavailable): visual-only connector\n    if (!this.connector) {\n      console.warn(\n        \"CONNECTION_HANDLES_DEBUG: Connector not initialized for\",\n        this.id\n      );\n      return;\n    }\n    if (!this.connector.isEnabled()) this.connector.enable();\n    this.connector.connectTo(targetNode);\n  }\n}\n","import { Node, NodeOptions } from './Node'\nimport type { Slate } from './Slate'\n\nexport class NodesManager {\n  private slate: Slate\n  private nodes: Map<string, Node> = new Map()\n\n  constructor(slate: Slate) {\n    this.slate = slate\n  }\n\n  public add(options: Partial<NodeOptions> = {}): Node {\n    // Ensure we have an ID\n    if (!options.id) {\n      options.id = this.generateId()\n    }\n\n    // Check if node with this ID already exists\n    if (this.nodes.has(options.id)) {\n      console.warn(`Node with id \"${options.id}\" already exists`)\n      return this.nodes.get(options.id)!\n    }\n\n    // Create the node\n    const node = new Node(options as NodeOptions, this.slate)\n    \n    // Add to collection\n    this.nodes.set(node.id, node)\n    \n    return node\n  }\n\n  public remove(id: string): boolean {\n    const node = this.nodes.get(id)\n    if (node) {\n      // Clean up EVERY association involving this node so no rogue connector\n      // lines or stale associations survive the delete (parity + no-rogue-lines):\n      //  (a) this node's own outgoing associations (it is the parent)\n      try {\n        (node as any).relationships?.removeAll?.()\n      } catch (e) {\n        /* noop */\n      }\n      //  (b) incoming associations from other nodes (this node is the child)\n      this.allNodes.forEach((other) => {\n        if (other.id === id) return\n        try {\n          if ((other as any).relationships?.getAssociation?.(id)) {\n            (other as any).relationships.removeAssociation(id)\n          }\n        } catch (e) {\n          /* noop */\n        }\n      })\n      node.remove()\n      this.nodes.delete(id)\n      return true\n    }\n    return false\n  }\n\n  public one(id: string): Node | undefined {\n    return this.nodes.get(id)\n  }\n\n  public get allNodes(): Node[] {\n    return Array.from(this.nodes.values())\n  }\n\n  public clear(): void {\n    this.allNodes.forEach(node => node.remove())\n    this.nodes.clear()\n  }\n\n  /** Destroy the nodes manager, clearing all nodes */\n  public destroy(): void {\n    this.clear();\n    (this as any).slate = null;\n  }\n\n  /**\n   * Move nodes from a collab package. Accepts BOTH shapes:\n   *  - v2: `data.nodes: [{id, x, y}]`\n   *  - v1: `data.nodeOptions: [{id, xPos, yPos, groupId, isLocked}]`\n   *    (drag, arrangement, grouping, and group-lock broadcasts)\n   */\n  public moveNodes(packageData: any, options: { animate?: boolean } = {}) {\n    const data = packageData?.data ?? packageData ?? {};\n    // Programmatic/collab moves GLIDE (v1 animated); a drag-end broadcast\n    // carries no dur, so default to a smooth ~400ms unless explicitly 0.\n    const duration =\n      options.animate === false || data.dur === 0\n        ? 0\n        : data.dur ?? 400;\n\n    const moves: Array<{\n      id: string\n      x: number\n      y: number\n      groupId?: string | null\n      hasGroupId: boolean\n      isLocked?: boolean\n    }> = [];\n    if (Array.isArray(data.nodes)) {\n      data.nodes.forEach((n: any) =>\n        moves.push({\n          id: n.id,\n          x: n.x,\n          y: n.y,\n          groupId: n.groupId,\n          hasGroupId: Object.prototype.hasOwnProperty.call(n, 'groupId'),\n          isLocked: n.isLocked,\n        })\n      );\n    }\n    if (Array.isArray(data.nodeOptions)) {\n      data.nodeOptions.forEach((n: any) =>\n        moves.push({\n          id: n.id,\n          x: n.xPos ?? n.x,\n          y: n.yPos ?? n.y,\n          groupId: n.groupId,\n          hasGroupId: Object.prototype.hasOwnProperty.call(n, 'groupId'),\n          isLocked: n.isLocked,\n        })\n      );\n    }\n\n    moves.forEach((m) => {\n      const node = this.one(m.id);\n      if (!node) return;\n      if (typeof m.x === \"number\" && typeof m.y === \"number\") {\n        node.position(m.x, m.y, undefined, undefined, duration);\n      }\n      // onNodesMove is also the established persistence/collaboration package\n      // for groups and group locks. Applying only x/y made those mutations look\n      // correct locally and in Mongo while every remote client silently dropped\n      // the grouping/lock state.\n      if (m.hasGroupId) {\n        node.options.groupId = m.groupId || undefined;\n      }\n      if (m.isLocked === true && !node.options.isLocked) {\n        node.lock();\n      } else if (m.isLocked === false && node.options.isLocked) {\n        node.unlock();\n      }\n    });\n  }\n\n  /** Create an association from a collab package: `{parentId, childId, ...opts}` */\n  public addRelationship(relationshipData: any) {\n    const { parentId, childId, targetPoint } = relationshipData || {};\n    const parent = parentId ? this.one(parentId) : undefined;\n    if (!parent) {\n      console.warn(\"NODESMANAGER_DEBUG: addRelationship missing parent\", parentId);\n      return;\n    }\n    // Idempotent by the EXACT association id (parallel edges have distinct ids\n    // like `A->B~2`, so keying on childId alone would wrongly drop the second\n    // line). Falls back to childId for legacy packages that carry no id.\n    const rid = (relationshipData as any).id;\n    if (rid) {\n      if ((parent as any).relationships?.hasAssociationId?.(rid)) return;\n    } else if ((parent as any).relationships?.getAssociation?.(childId)) {\n      return;\n    }\n\n    // Free-floating endpoint (L1b): target is a bare point, no child node.\n    if (targetPoint) {\n      (parent as any).relationships?.addFloatingAssociation(\n        targetPoint,\n        relationshipData\n      );\n      return;\n    }\n\n    const child = childId ? this.one(childId) : undefined;\n    if (!child) {\n      console.warn(\n        \"NODESMANAGER_DEBUG: addRelationship missing child\",\n        parentId,\n        childId\n      );\n      return;\n    }\n    (parent as any).relationships?.addAssociation(child, relationshipData);\n  }\n\n  /** Remove an association from a collab package: `{parentId, childId, id?}` */\n  public removeRelationship(relationshipData: any) {\n    const { parentId, childId, id } = relationshipData || {};\n    const parent = parentId ? this.one(parentId) : undefined;\n    if (!parent || (!childId && !id)) return;\n    // Prefer the exact association id so a peer removes only the intended\n    // parallel edge; fall back to childId (removes all edges to that child).\n    (parent as any).relationships?.removeAssociation(id || childId);\n  }\n\n  private generateId(): string {\n    return 'node_' + Math.random().toString(36).substr(2, 9) + '_' + Date.now()\n  }\n\n  public count(): number {\n    return this.nodes.size\n  }\n\n  public forEach(callback: (node: Node, id: string) => void): void {\n    this.nodes.forEach(callback)\n  }\n\n  public filter(predicate: (node: Node) => boolean): Node[] {\n    return this.allNodes.filter(predicate)\n  }\n\n  public find(predicate: (node: Node) => boolean): Node | undefined {\n    return this.allNodes.find(predicate)\n  }\n}\n","/**\n * Serialization.ts - Full serialize/deserialize for SlateboxJS v3\n *\n * Produces and consumes JSON matching the v1 format:\n * {\n *   \"options\": { SlateOptions },\n *   \"nodes\": [\n *     {\n *       \"options\": { NodeOptions with xPos/yPos },\n *       \"relationships\": {\n *         \"associations\": [ Association ]\n *       }\n *     }\n *   ],\n *   \"shareId\": \"string\"\n * }\n */\n\nimport type { NodeOptions } from \"./Node\";\nimport type { SlateOptions } from \"./Slate\";\nimport {\n  v1NodeToV2,\n  v2NodeToV1,\n  v1AssociationToV2,\n  v2AssociationToV1,\n  type V2Association,\n} from \"./compat\";\n\n// ─── JSON type definitions ───────────────────────────────────────────\n\nexport interface SlateJSON {\n  options: Record<string, any>;\n  nodes: NodeJSON[];\n  shareId: string;\n}\n\nexport interface NodeJSON {\n  options: Record<string, any>;\n  relationships: {\n    associations: Record<string, any>[];\n  };\n}\n\n// ─── Serialization ───────────────────────────────────────────────────\n\n/**\n * Serialize an entire Slate instance to the v1-compatible JSON format.\n *\n * @param slate - The Slate instance to serialize\n * @param nodes - Optional subset of nodes to include (defaults to all)\n * @param asPresentation - If true, includes presentation ordering metadata\n */\nexport function serialize(\n  slate: any,\n  nodes?: any[],\n  asPresentation?: boolean\n): SlateJSON {\n  const targetNodes = nodes || slate.nodes.allNodes;\n\n  const serializedNodes: NodeJSON[] = targetNodes.map((node: any) =>\n    serializeNode(node)\n  );\n\n  // If asPresentation, add ordering index to each node\n  if (asPresentation) {\n    serializedNodes.forEach((n, idx) => {\n      n.options._presentationIndex = idx;\n    });\n  }\n\n  return {\n    options: serializeSlateOptions(slate.options),\n    nodes: serializedNodes,\n    shareId: slate.options.shareId || \"\",\n  };\n}\n\n/**\n * Deserialize JSON into an existing Slate instance.\n * Clears existing nodes and replaces with deserialized content.\n *\n * @param json - The v1-compatible JSON to load\n * @param slate - The Slate instance to load into\n * @param preserve - If true, don't clear existing nodes (merge mode)\n * @param skipZoom - If true, don't adjust zoom/pan after load\n */\nexport async function deserialize(\n  json: SlateJSON | string,\n  slate: any,\n  preserve: boolean = false,\n  skipZoom: boolean = false\n): Promise<void> {\n  const data: SlateJSON =\n    typeof json === \"string\" ? JSON.parse(json) : json;\n\n  // Loading is not a user action: suppress onSlateChanged emission for the\n  // duration (v1's loadJSON never fired change packages per node)\n  slate.beginRemoteApply?.();\n  try {\n    await deserializeInner(data, slate, preserve, skipZoom);\n  } finally {\n    slate.endRemoteApply?.();\n  }\n}\n\nasync function deserializeInner(\n  data: SlateJSON,\n  slate: any,\n  preserve: boolean,\n  skipZoom: boolean\n): Promise<void> {\n  // Apply slate options (merge with existing)\n  if (data.options) {\n    const slateOpts = deserializeSlateOptions(data.options);\n    Object.assign(slate.options, slateOpts);\n\n    // Apply shareId\n    if (data.shareId) {\n      slate.options.shareId = data.shareId;\n    }\n\n    // Re-apply background now that containerStyle may have changed\n    slate.applyContainerStyle?.();\n  }\n\n  // Clear existing nodes unless preserving\n  if (!preserve) {\n    slate.nodes.clear();\n    // Connectors render in a GLOBAL container (slate.linesContainer), not the node\n    // groups — so nodes.clear() alone can leave orphaned connector paths behind\n    // (e.g. an undo that removes async-created copies leaves rogue lines). Wipe the\n    // container so the rebuild below re-renders exactly the snapshot's connectors.\n    try {\n      (slate as any).linesContainer?.clear?.();\n    } catch (e) {\n      /* noop */\n    }\n  }\n\n  // First pass: create all nodes (without relationships)\n  const nodeMap = new Map<string, any>();\n\n  if (Array.isArray(data.nodes)) {\n    for (const nodeJson of data.nodes) {\n      const nodeOpts = deserializeNodeOptions(nodeJson.options);\n\n      // Check if node already exists (in merge mode)\n      const existing = slate.nodes.one(nodeOpts.id);\n      if (existing) {\n        // Update existing node options\n        Object.assign(existing.options, nodeOpts);\n        if (nodeOpts.x !== undefined && nodeOpts.y !== undefined) {\n          existing.position(nodeOpts.x, nodeOpts.y);\n        }\n        nodeMap.set(nodeOpts.id!, existing);\n      } else {\n        const node = slate.addNode(nodeOpts);\n        if (node) {\n          nodeMap.set(node.id, node);\n        }\n      }\n    }\n\n    // Wait for all nodes to finish async creation (SVG elements, connectors, etc.)\n    const readyPromises: Promise<void>[] = [];\n    for (const node of nodeMap.values()) {\n      if (node.ready) {\n        readyPromises.push(node.ready);\n      }\n    }\n    if (readyPromises.length > 0) {\n      await Promise.all(readyPromises);\n    }\n\n    // Second pass: create relationships (deferred binding — nodes are now fully initialized)\n    for (const nodeJson of data.nodes) {\n      const nodeId = nodeJson.options.id || nodeJson.options.xPos !== undefined\n        ? v1NodeToV2(nodeJson.options).id\n        : nodeJson.options.id;\n\n      if (!nodeId) continue;\n\n      const parentNode = nodeMap.get(nodeId as string) || slate.nodes.one(nodeId as string);\n      if (!parentNode) continue;\n\n      const associations = nodeJson.relationships?.associations;\n      if (!Array.isArray(associations) || associations.length === 0) continue;\n\n      for (const assocData of associations) {\n        const assoc = v1AssociationToV2(assocData);\n\n        // Free-floating endpoint (L1b): no child node — render at the point.\n        if ((assoc as any).targetPoint && parentNode?.relationships) {\n          parentNode.relationships.addFloatingAssociation(\n            (assoc as any).targetPoint,\n            assoc\n          );\n          continue;\n        }\n\n        const childNode =\n          nodeMap.get(assoc.childId) || slate.nodes.one(assoc.childId);\n\n        if (childNode && parentNode) {\n          // Store relationship data on the node for the Relationships system\n          if (parentNode.relationships) {\n            parentNode.relationships.addAssociation(childNode, assoc);\n          } else {\n            // Fallback: use basic connector\n            try {\n              if (!parentNode.connector.isEnabled()) {\n                parentNode.connector.enable();\n              }\n              parentNode.connector.connectTo(childNode, {\n                lineColor: assoc.lineColor,\n                lineWidth: assoc.lineWidth,\n              });\n            } catch (e) {\n              console.warn(\n                \"SERIALIZATION_DEBUG: Failed to create connection\",\n                assoc.parentId,\n                \"->\",\n                assoc.childId,\n                e\n              );\n            }\n          }\n        }\n      }\n    }\n  }\n\n  // Adjust zoom/pan to fit content unless skipped.\n  //\n  // A single fixed-delay fit is unreliable: on a full page load the host may\n  // call loadJSON before #slateCanvas has been laid out, so the container is\n  // 0-sized and fit() computes a garbage viewBox that never self-corrects\n  // (the \"node loads but the view never frames it\" bug). Instead, poll until\n  // the container has real pixel dimensions AND nodes exist, then fit — and\n  // fit once more on the next frame to settle after any final container\n  // resize. This runs only during initial load, so it won't fight later user\n  // panning.\n  if (!skipZoom && slate.panZoom) {\n    const contentCenterX = () => {\n      const ns = slate.nodes?.allNodes ?? [];\n      if (!ns.length) return null;\n      let minX = Infinity,\n        maxX = -Infinity;\n      for (const n of ns) {\n        const x = n.options.x ?? 0;\n        const w = n.options.width ?? 100;\n        minX = Math.min(minX, x);\n        maxX = Math.max(maxX, x + w);\n      }\n      return (minX + maxX) / 2;\n    };\n    const attemptFit = (tries: number) => {\n      if ((slate as any)._destroyed) return;\n      const rect = slate.element?.getBoundingClientRect?.();\n      const sized = !!rect && rect.width > 1 && rect.height > 1;\n      const ccx = contentCenterX();\n      if (sized && ccx !== null) {\n        try {\n          slate.fitToContent();\n        } catch (e) {\n          /* noop */\n        }\n        // Verify the fit actually framed the content — fit() no-ops if pan/zoom\n        // isn't enabled yet or ran on a transient state, so confirm the viewBox\n        // now centers on the content before we stop retrying.\n        const vb = slate.canvas?.viewbox?.();\n        const framed =\n          vb && Math.abs(vb.x + vb.width / 2 - ccx) < vb.width / 2;\n        if (framed) {\n          if (typeof requestAnimationFrame !== \"undefined\") {\n            requestAnimationFrame(() => {\n              try {\n                slate.fitToContent();\n              } catch (e) {\n                /* noop */\n              }\n            });\n          }\n          return;\n        }\n      }\n      if (tries < 60) setTimeout(() => attemptFit(tries + 1), 50);\n    };\n    attemptFit(0);\n  }\n}\n\n// ─── Node serialization ──────────────────────────────────────────────\n\n/** Serialize a single Node to the v1-compatible JSON format */\nexport function serializeNode(node: any): NodeJSON {\n  const opts = v2NodeToV1(node.options);\n\n  // Ensure position is current\n  if (node.svgGroup) {\n    try {\n      const bbox = node.svgGroup.bbox();\n      opts.xPos = node.options.x ?? bbox.x;\n      opts.yPos = node.options.y ?? bbox.y;\n    } catch (e) {\n      opts.xPos = node.options.x ?? 0;\n      opts.yPos = node.options.y ?? 0;\n    }\n  }\n\n  // Serialize rotation\n  if (node.getRotation) {\n    const rotation = node.getRotation();\n    if (rotation !== 0) {\n      opts.rotate = { rotationAngle: rotation };\n    }\n  }\n\n  // Serialize relationships\n  const associations: Record<string, any>[] = [];\n\n  if (node.relationships && typeof node.relationships.serialize === \"function\") {\n    const relData = node.relationships.serialize();\n    if (relData?.associations) {\n      associations.push(\n        ...relData.associations.map((a: any) => v2AssociationToV1(a))\n      );\n    }\n  } else if (node.connector) {\n    // Fallback: serialize from connector\n    const connections = node.connector.getConnections();\n    for (const conn of connections) {\n      // Only serialize outgoing connections (source is this node)\n      if (conn.source === node || conn.source?.id === node.id) {\n        associations.push({\n          childId: conn.target?.id || conn.target,\n          parentId: node.id,\n          isStraightLine: false,\n          lineColor: conn.lineColor || \"#666666\",\n          lineEffect: \"\",\n          lineOpacity: 1,\n          lineType: \"bezier\",\n          lineCurviness: 0.1,\n          lineCurveType: \"cubic\",\n          lineWidth: conn.lineWidth || 3,\n        });\n      }\n    }\n  }\n\n  return {\n    options: opts,\n    relationships: {\n      associations,\n    },\n  };\n}\n\n/** Convert JSON node options to v2 NodeOptions */\nexport function deserializeNodeOptions(\n  jsonOpts: Record<string, any>\n): Partial<NodeOptions> {\n  return v1NodeToV2(jsonOpts);\n}\n\n// ─── Slate options serialization ─────────────────────────────────────\n\n/** Serialize SlateOptions for JSON output */\nfunction serializeSlateOptions(options: SlateOptions): Record<string, any> {\n  // Deep clone to avoid modifying the original\n  const out: Record<string, any> = {};\n\n  // Copy all serializable properties\n  const keys = [\n    \"id\", \"name\", \"description\", \"container\", \"instance\", \"shareId\",\n    \"enabled\", \"allowDrag\", \"followMe\", \"mindMapMode\",\n    \"autoResizeNodesBasedOnText\", \"useLayoutQuadrants\",\n    \"autoEnableDefaultFilters\",\n    \"showbirdsEye\", \"sizeOfbirdsEye\", \"showMultiSelect\",\n    \"showZoom\", \"showUndoRedo\", \"showStatus\", \"showLocks\",\n    \"isPublic\", \"isUnlisted\", \"isPrivate\", \"isTemplate\",\n    \"basedOnTemplate\", \"basedOnThemeId\", \"syncWithTheme\",\n    \"allowCollaboration\", \"eligibleForThemeCompilation\",\n    \"defaultLineColor\", \"themeId\",\n    \"layoutType\", \"disableAutoLayoutOfManuallyPositionedNodes\",\n    \"nodeOrder\",\n    \"huddleType\", \"huddleEnabled\",\n    \"tags\", \"templateMarkdown\", \"templatePrompt\", \"ai\",\n  ];\n\n  for (const key of keys) {\n    if ((options as any)[key] !== undefined) {\n      out[key] = (options as any)[key];\n    }\n  }\n\n  // Serialize nested objects\n  if (options.viewPort) {\n    out.viewPort = { ...options.viewPort };\n  }\n  if (options.containerStyle) {\n    out.containerStyle = { ...options.containerStyle };\n  }\n\n  return out;\n}\n\n/** Deserialize JSON slate options to SlateOptions */\nfunction deserializeSlateOptions(\n  jsonOpts: Record<string, any>\n): Partial<SlateOptions> {\n  // v1 → v2 mapping is mostly 1:1 for slate options\n  return jsonOpts as Partial<SlateOptions>;\n}\n\n// ─── Snapshot helper ─────────────────────────────────────────────────\n\n/**\n * Take a snapshot of the current slate state.\n * Used by undo/redo system.\n */\nexport function snapshot(slate: any): SlateJSON {\n  return serialize(slate);\n}\n","import type { Slate } from \"./Slate\";\nimport type { SlatePackage } from \"./SlatePackage\";\nimport { v1NodeToV2 } from \"./compat\";\nimport { deserialize } from \"./Serialization\";\n\nexport class Invoker {\n  private slate: Slate\n\n  constructor(slate: Slate) {\n    this.slate = slate\n  }\n\n  /** Destroy the invoker, clearing all callback references */\n  public destroy(): void {\n    (this as any).slate = null;\n  }\n\n  onZoom(pkg: SlatePackage) {\n    if (this.slate.options.followMe) {\n      const level = pkg.data.zoomLevel\n      if (typeof level === 'number' && level > 0) {\n        // Apply directly through panZoom — Slate.zoom would re-broadcast\n        this.slate.panZoom?.zoom(level)\n      }\n    }\n  }\n\n  onNodePositioned(pkg: SlatePackage) {\n    const node = this.slate.nodes.one(pkg.data.id)\n    if (node) {\n      node.position(\n        pkg.data.location.x,\n        pkg.data.location.y,\n        () => {},\n        pkg.data.easing,\n        pkg.data.duration || 500\n      )\n    }\n  }\n\n  onNodeLinkRemoved(pkg: SlatePackage) {\n    const node = this.slate.nodes.one(pkg.data.id)\n    if (node?.links) {\n      node.links.unset(false)\n    }\n  }\n\n  onNodeLinkAdded(pkg: SlatePackage) {\n    const node = this.slate.nodes.one(pkg.data.id)\n    // The package carries the link under data.link (see Links.set); passing the\n    // whole pkg here stored the entire collab envelope as options.link and\n    // corrupted the link on reload / for remote peers.\n    const link = (pkg.data as any)?.link\n    if (node?.links && link) {\n      node.links.set(link, false)\n    }\n  }\n\n  onNodeUnlocked(pkg: SlatePackage) {\n    const node = this.slate.nodes.one(pkg.data.id)\n    if (node) {\n      node.unlock()\n    }\n  }\n\n  onNodeLocked(pkg: SlatePackage) {\n    const node = this.slate.nodes.one(pkg.data.id)\n    if (node) {\n      node.lock()\n    }\n  }\n\n  onNodeBehaviorChanged(pkg: SlatePackage) {\n    const node = this.slate.nodes.one(pkg.data.id)\n    if (node) {\n      pkg.data.behaviorChanges.forEach((b: any) => {\n        if (typeof b.value === 'object') {\n          (node.options as any)[b.name] = b.value.val\n          Object.keys(b.value).forEach((k) => {\n            if (k !== 'val') {\n              (node.options as any)[k] = b.value[k]\n            }\n          })\n        } else {\n          (node.options as any)[b.name] = b.value\n        }\n      })\n    }\n  }\n\n  onNodeToBack(pkg: SlatePackage) {\n    const node = this.slate.nodes.one(pkg.data.id)\n    if (node) {\n      node.toBack()\n    }\n  }\n\n  onNodeToFront(pkg: SlatePackage) {\n    const node = this.slate.nodes.one(pkg.data.id)\n    if (node) {\n      node.toFront()\n    }\n  }\n\n  onNodeShapeChanged(pkg: SlatePackage) {\n    const node = this.slate.nodes.one(pkg.data.id)\n    if (!node) return\n    const shape = (pkg.data as any).shape ?? (pkg.data as any).vectorPath\n    // Carry any co-sent props (border, etc.), then re-render the shape.\n    Object.assign(node.options, pkg.data)\n    if (shape) {\n      node.setShape(shape, (pkg.data as any).vectorPath)\n    }\n  }\n\n  onNodeAdded(pkg: SlatePackage) {\n    if (pkg.data?.multiSelectCopy) {\n      // Handle multi-selection copy\n      console.log('Multi-select copy:', pkg.data)\n    } else if (pkg.data.id && pkg.data.options && !pkg.data.nodeOptions) {\n      // Add node connected to a specific parent (data.id = PARENT id)\n      const parentNode = this.slate.nodes.one(pkg.data.id)\n      if (parentNode) {\n        // Create connected node\n        this.slate.nodes.add({\n          ...pkg.data.options,\n          x: pkg.data.targetXPos || 100,\n          y: pkg.data.targetYPos || 100\n        })\n      }\n    } else {\n      // Straight up node addition — packages carry v1-shaped options\n      // (xPos/yPos/foregroundColor/…); convert before creating\n      let nodesToCreate = pkg.data.nodeOptions\n      if (!Array.isArray(nodesToCreate)) {\n        nodesToCreate = [nodesToCreate]\n      }\n      nodesToCreate.filter(Boolean).forEach((nOpts: any) => {\n        const exists = this.slate.nodes.one(nOpts.id)\n        if (!exists) {\n          this.slate.nodes.add(v1NodeToV2(nOpts) as any)\n        }\n      })\n    }\n  }\n\n  onNodeImageChanged(pkg: SlatePackage) {\n    const node = this.slate.nodes.one(pkg.data.id)\n    if (!node?.images) return\n    // App sends { img: <url>, w, h } (or clears with a falsy img).\n    const url = (pkg.data as any).img ?? (pkg.data as any).image\n    if (url) {\n      node.images.set(url, (pkg.data as any).w, (pkg.data as any).h)\n    } else {\n      node.images.clear()\n    }\n  }\n\n  onNodeDeleted(pkg: SlatePackage) {\n    this.slate.nodes.remove(pkg.data.id)\n  }\n\n  onNodeResized(pkg: SlatePackage) {\n    const node = this.slate.nodes.one(pkg.data.id)\n    if (node) {\n      Object.assign(node.options, pkg.data)\n      node.setSize(pkg.data.width, pkg.data.height)\n    }\n  }\n\n  onNodeRotated(pkg: SlatePackage) {\n    const node = this.slate.nodes.one(pkg.data.id)\n    if (node) {\n      if (pkg.data.textOffset !== undefined) {\n        node.options.textOffset = pkg.data.textOffset\n      }\n      const angle =\n        pkg.data.rotate?.rotationAngle ?? pkg.data.rotationAngle\n      if (typeof angle === 'number') {\n        // Animate remotely-applied rotation (collab bug #5) so it glides in\n        // this window like drag does, instead of snapping.\n        node.setRotation(angle, 400)\n      }\n      if (pkg.data.width && pkg.data.height) {\n        node.setSize(pkg.data.width, pkg.data.height)\n      }\n    }\n  }\n\n  onNodeColorChanged(pkg: SlatePackage) {\n    const node = this.slate.nodes.one(pkg.data.id)\n    if (node) {\n      // v1 packages carry the background as `color`; accept both\n      node.setColors(\n        pkg.data.color ?? pkg.data.backgroundColor,\n        pkg.data.borderColor\n      )\n      if (pkg.data.opacity !== undefined) {\n        node.options.opacity = pkg.data.opacity\n        node.applyOpacity()\n      }\n    }\n  }\n\n  onNodeTextChanged(pkg: SlatePackage) {\n    const node = this.slate.nodes.one(pkg.data.id)\n    if (!node) return\n    // Update font/alignment options FIRST — only when present (a text-only\n    // package must not wipe font settings with undefined).\n    if (pkg.data.fontSize !== undefined) node.options.fontSize = pkg.data.fontSize\n    if (pkg.data.fontFamily !== undefined) node.options.fontFamily = pkg.data.fontFamily\n    if (pkg.data.fontColor !== undefined) node.options.fontColor = pkg.data.fontColor\n    if (pkg.data.textOpacity !== undefined) node.options.textOpacity = pkg.data.textOpacity\n    if (pkg.data.textXAlign !== undefined) node.options.textXAlign = pkg.data.textXAlign\n    if (pkg.data.textYAlign !== undefined) node.options.textYAlign = pkg.data.textYAlign\n    // Apply the text string (if any), then re-render font + alignment.\n    if (pkg.data.text !== undefined) node.setText(pkg.data.text)\n    node.applyTextStyle()\n  }\n\n  onNodeAITextChanged(pkg: SlatePackage) {\n    const node = this.slate.nodes.one(pkg.data.id)\n    if (node) {\n      // Merge with NEW winning (existing fields not in the package are kept).\n      // The order was reversed, so a re-set of the same field was ignored and a\n      // remote peer never picked up another client's AI change. Matches the\n      // update semantics of onSlateAISet.\n      node.options.ai = { ...node.options.ai, ...pkg.data.ai }\n    }\n  }\n\n  addRelationship(pkg: SlatePackage) {\n    this.slate.nodes.addRelationship(pkg.data)\n  }\n\n  removeRelationship(pkg: SlatePackage) {\n    this.slate.nodes.removeRelationship(pkg.data)\n  }\n\n  onNodesMove(pkg: SlatePackage) {\n    // Remote moves glide by default (v1 semantics); moveNodes honors an\n    // explicit dur:0 for instant placement\n    this.slate.nodes.moveNodes(pkg)\n  }\n\n  onNodeEffectChanged(pkg: SlatePackage) {\n    const node = this.slate.nodes.one(pkg.data.id)\n    if (!node?.filters) return\n    // App sends { filter: { apply: 'vect'|'text'|'image', id: <filterName|null> } }.\n    const filter = (pkg.data as any).filter\n    if (!filter) return\n    const target = filter.apply === 'text' ? 'text' : 'vect'\n    const optKey = target === 'text' ? 'text' : 'vect'\n    if (filter.isAnimation) {\n      node.filters.removeAnimation(target)\n      if (filter.id && filter.id !== 'None' && filter.id !== 'none') {\n        node.filters.applyAnimation(filter.id, target)\n      }\n      return\n    }\n    const prev = node.options.filters?.[optKey]\n    // Exclusive toggle: remove the previously-applied effect for this target.\n    if (prev) node.filters.remove(prev)\n    if (filter.id) {\n      node.filters.apply(filter.id, target as 'vect' | 'text' | 'both')\n    } else if (node.options.filters) {\n      // Deselected → clear the stored id.\n      node.options.filters[optKey] = undefined\n    }\n  }\n\n  onNodeBorderPropertiesChanged(pkg: SlatePackage) {\n    const node = this.slate.nodes.one(pkg.data.id)\n    if (!node) return\n    const { prop, val } = pkg.data as any\n    if (prop !== undefined) {\n      // Pane shape: one { prop, val } at a time (borderColor / borderWidth /\n      // borderStyle / borderOpacity).\n      ;(node.options as any)[prop] = val\n    } else {\n      // Legacy bulk shape.\n      if (pkg.data.borderColor !== undefined) node.options.borderColor = pkg.data.borderColor\n      if (pkg.data.borderWidth !== undefined) node.options.borderWidth = pkg.data.borderWidth\n    }\n    node.applyBorder()\n  }\n\n  onLinePropertiesChanged(pkg: SlatePackage) {\n    const data = Array.isArray(pkg.data) ? pkg.data : [pkg.data]\n    data.forEach((p: any) => {\n      const node = this.slate.nodes.one(p.id)\n      if (!node) return\n      // Pane packages: { prop, val, associationId } — update the specific\n      // association's line property AND re-render its connector. Applied for\n      // both local edits and remote (collab) so line changes sync + persist.\n      if (p.associationId && p.prop !== undefined && node.relationships) {\n        node.relationships.applyLineProperty(p.associationId, p.prop, p.val)\n      } else if (p.options) {\n        // Fallback: bulk options merge (legacy shape)\n        Object.assign(node.options, p.options)\n      }\n    })\n  }\n\n  onFollowMeChanged(pkg: SlatePackage) {\n    this.slate.options.followMe = pkg.data?.followMe\n  }\n\n  onCanvasMove(pkg: SlatePackage) {\n    if (this.slate.options.followMe) {\n      const { left, top } = pkg.data || {}\n      if (typeof left === 'number' && typeof top === 'number') {\n        this.slate.pan({ x: left, y: top })\n      }\n    }\n  }\n\n  onSlateThemeChanged(pkg: SlatePackage) {\n    const theme = pkg.data?.theme\n    if (theme?._id) this.slate.options.themeId = theme._id\n    if (theme) {\n      // Apply the theme (container bg, line color, per-node parent/child styles).\n      this.slate.applyTheme(theme, (pkg.data as any)?.syncWithTheme)\n    }\n  }\n\n  onSlateLayoutTypeChanged(pkg: SlatePackage) {\n    if (pkg.data.layoutType != null) {\n      this.slate.options.layoutType = pkg.data.layoutType\n    }\n    if (pkg.data.disableAutoLayoutOfManuallyPositionedNodes != null) {\n      this.slate.options.disableAutoLayoutOfManuallyPositionedNodes =\n        pkg.data.disableAutoLayoutOfManuallyPositionedNodes\n    }\n  }\n\n  onSlateBackgroundEffectChanged(pkg: SlatePackage) {\n    this.slate.options.containerStyle!.backgroundEffect = pkg.data.effect\n    // Apply background effect\n    console.log('Background effect changed:', pkg.data.effect)\n  }\n\n  onSlateBackgroundImageChanged(pkg: SlatePackage) {\n    if (pkg.data.bg) {\n      this.slate.options.containerStyle!.backgroundImage = pkg.data.bg.url\n      this.slate.options.containerStyle!.backgroundSize = pkg.data.bg.size\n      // An image supersedes any gradient (which otherwise wins in applyContainerStyle).\n      this.slate.options.containerStyle!.backgroundColorAsGradient = false\n    } else {\n      const c = this.slate.options.containerStyle?.prevBackgroundColor || '#fff'\n      this.slate.options.containerStyle!.backgroundColor = c\n      this.slate.options.containerStyle!.backgroundImage = undefined\n      this.slate.options.containerStyle!.backgroundEffect = undefined\n    }\n    // Push the option change onto the container element (was a no-op before).\n    this.slate.applyContainerStyle()\n  }\n\n  onSlateBackgroundColorChanged(pkg: SlatePackage) {\n    const cs = this.slate.options.containerStyle!;\n    cs.backgroundColor = pkg.data.color\n    cs.backgroundColorAsGradient = pkg.data.asGradient\n    cs.backgroundGradientType = pkg.data.gradientType\n    cs.backgroundGradientColors = pkg.data.gradientColors\n    cs.backgroundGradientStrategy = pkg.data.gradientStrategy\n    cs.backgroundImage = undefined\n    cs.backgroundEffect = undefined\n    // Actually paint the container (previously only options were updated).\n    this.slate.applyContainerStyle()\n  }\n\n  onLineColorChanged(pkg: SlatePackage) {\n    this.slate.options.defaultLineColor = pkg.data.color\n    this.slate.nodes.allNodes.forEach((node: any) => {\n      node.options.lineColor = pkg.data.color\n      if (node.relationships?.associations) {\n        node.relationships.associations.forEach((a: any) => {\n          a.lineColor = pkg.data.color\n        })\n        node.relationships.refreshOwnRelationships()\n      }\n    })\n  }\n\n  onSlateAISet(pkg: SlatePackage) {\n    this.slate.options.ai = {\n      ...(this.slate.options.ai || {}),\n      ...pkg.data,\n    }\n  }\n\n  onSlateNameChanged(pkg: SlatePackage) {\n    this.slate.options.name = pkg.data.name\n  }\n\n  onSlateDescriptionChanged(pkg: SlatePackage) {\n    this.slate.options.description = pkg.data.description\n  }\n\n  /** Apply an authoritative full-document baseline (undo/redo collaboration). */\n  async onSlateReplaced(pkg: SlatePackage) {\n    const snapshot = pkg.data?.snapshot\n    if (!snapshot) return\n    await deserialize(snapshot, this.slate, false, true)\n  }\n\n  onSlateShowGridChanged(pkg: SlatePackage) {\n    this.slate.options.viewPort!.showGrid = pkg.data.showGrid\n    // Actually show/hide the grid overlay — previously this only logged, so the\n    // \"Show Grid\" toggle set the option but never rendered the grid.\n    if (pkg.data.showGrid) {\n      this.slate.grid?.show()\n    } else {\n      this.slate.grid?.hide()\n    }\n  }\n\n  onSlateMindMapModeChanged(pkg: SlatePackage) {\n    this.slate.options.mindMapMode = pkg.data.mindMapMode\n  }\n\n  onSlateAutoResizeNodesBasedOnTextChanged(pkg: SlatePackage) {\n    this.slate.options.autoResizeNodesBasedOnText = pkg.data.autoResizeNodesBasedOnText\n  }\n\n  onSlateTagsAndTemplateMarkdownChanged(pkg: SlatePackage) {\n    this.slate.options.tags = pkg.data.tags\n    this.slate.options.templateMarkdown = pkg.data.templateMarkdown\n    this.slate.options.templatePrompt = pkg.data.templatePrompt\n  }\n\n  onSlateTemplateChanged(pkg: SlatePackage) {\n    this.slate.options.isTemplate = pkg.data.isTemplate\n  }\n\n  onSlateSnapToObjectsChanged(pkg: SlatePackage) {\n    this.slate.options.viewPort!.snapToObjects = pkg.data.snapToObjects\n  }\n\n  onSlateSnapToGridChanged(pkg: SlatePackage) {\n    this.slate.options.viewPort!.snapToGrid = pkg.data.snapToGrid\n    // Wire the toggle into the live Grid so node drags snap (or stop snapping).\n    this.slate.grid?.updateOptions({ snapToGrid: !!pkg.data.snapToGrid })\n  }\n\n  onSlateFollowMeChanged(pkg: SlatePackage) {\n    this.slate.options.followMe = pkg.data.followMe\n  }\n\n  onSlateHuddleChanged(pkg: SlatePackage) {\n    if (pkg.data.huddleType != null) {\n      this.slate.options.huddleType = pkg.data.huddleType\n    }\n    if (pkg.data.huddleEnabled != null) {\n      this.slate.options.huddleEnabled = pkg.data.huddleEnabled\n    }\n  }\n}\n","import '@svgdotjs/svg.panzoom.js'\n\nexport interface PanZoomOptions {\n  enabled?: boolean\n  panning?: boolean\n  pinchZoom?: boolean\n  wheelZoom?: boolean\n  panButton?: number\n  oneFingerPan?: boolean\n  margins?: { top?: number; left?: number; right?: number; bottom?: number } | false\n  zoomFactor?: number\n  zoomMin?: number\n  zoomMax?: number\n  wheelZoomDeltaModeLinePixels?: number\n  wheelZoomDeltaModeScreenPixels?: number\n  momentum?: boolean\n  momentumSlowdown?: number\n  showControls?: boolean  // Show +/- zoom buttons\n  controlsPosition?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'\n  onPan?: (event: any) => void\n  onZoom?: (event: any) => void\n  onPanStart?: (event: any) => void\n  onPanEnd?: (event: any) => void\n}\n\nexport class PanZoom {\n  private canvas: any\n  private slate: any\n  private options: PanZoomOptions\n  private isEnabled: boolean = false\n  private controlsContainer: HTMLDivElement | null = null\n\n  /**\n   * Creates the pan/zoom handler. Enables panning and zooming on the canvas.\n   *\n   * @param slate   - The parent Slate instance\n   * @param options - Pan/zoom configuration (zoom factor, min/max, controls, etc.)\n   */\n  constructor(slate: any, options: PanZoomOptions = {}) {\n    this.slate = slate\n    this.canvas = slate.canvas\n    this.options = {\n      enabled: true,\n      panning: true,\n      pinchZoom: true,\n      wheelZoom: true, // Enable wheel zoom for Ctrl+scroll\n      // Middle-mouse drag pans (Miro/Figma convention). This frees LEFT-drag on\n      // empty canvas for rubber-band multi-select (MultiSelection) instead of\n      // both firing at once. Trackpad/wheel pan is a separate custom handler.\n      panButton: 1,\n      oneFingerPan: false,\n      margins: false,\n      zoomFactor: 0.3,\n      zoomMin: 0.1,\n      zoomMax: 10,\n      wheelZoomDeltaModeLinePixels: 17,\n      wheelZoomDeltaModeScreenPixels: 53,\n      momentum: true, // Enable kinetic scrolling with inertia\n      momentumSlowdown: 0.8, // Slowdown factor for momentum panning\n      showControls: false, // BirdsEye has integrated zoom controls now\n      controlsPosition: 'bottom-right',\n      ...options\n    }\n\n    if (this.options.enabled) {\n      this.init()\n    }\n  }\n\n  private init() {\n    try {\n      // svg.panzoom.js handles drag-to-pan (background) and pinch-zoom.\n      // We handle the WHEEL ourselves (below) for Miro-style behavior, so\n      // the plugin's wheelZoom stays off.\n      this.canvas.panZoom({\n        panning: this.options.panning,\n        pinchZoom: this.options.pinchZoom,\n        wheelZoom: false,\n        panButton: this.options.panButton,\n        oneFingerPan: this.options.oneFingerPan,\n        margins: this.options.margins,\n        zoomFactor: this.options.zoomFactor,\n        zoomMin: this.options.zoomMin,\n        zoomMax: this.options.zoomMax,\n        wheelZoomDeltaModeLinePixels: this.options.wheelZoomDeltaModeLinePixels,\n        wheelZoomDeltaModeScreenPixels: this.options.wheelZoomDeltaModeScreenPixels,\n        momentum: this.options.momentum,\n        momentumSlowdown: this.options.momentumSlowdown\n      })\n\n      this.attachWheelHandler()\n\n      this.isEnabled = true\n\n      // Add event listeners\n      if (this.options.onPanStart) {\n        this.canvas.on('panStart', this.options.onPanStart)\n      }\n      if (this.options.onPan) {\n        this.canvas.on('panning', this.options.onPan)\n      }\n      if (this.options.onPanEnd) {\n        this.canvas.on('panEnd', this.options.onPanEnd)\n      }\n      if (this.options.onZoom) {\n        this.canvas.on('zoom', this.options.onZoom)\n      }\n\n      // Create zoom controls if enabled\n      if (this.options.showControls) {\n        this.createZoomControls()\n      }\n\n      console.log('PanZoom initialized successfully with svg.panzoom.js')\n    } catch (error) {\n      console.warn('Failed to initialize pan/zoom:', error)\n    }\n  }\n\n  private _wheelHandler: ((e: WheelEvent) => void) | null = null\n\n  /**\n   * Miro-style wheel behavior on the canvas:\n   *  - two-finger trackpad scroll (plain wheel) → PAN\n   *  - ctrl/⌘ + wheel (pinch on trackpads, or modifier + wheel) → ZOOM at\n   *    the cursor\n   * Works directly on the viewBox so it's consistent with the infinite\n   * canvas and independent of the plugin's wheel logic.\n   */\n  private attachWheelHandler(): void {\n    const node = this.canvas.node as SVGSVGElement\n    if (!node || typeof node.addEventListener !== \"function\") return\n    this._wheelHandler = (e: WheelEvent) => {\n      if (!this.isEnabled) return\n      e.preventDefault()\n\n      const vb = this.canvas.viewbox()\n      const rect = node.getBoundingClientRect()\n      const px = rect.width || vb.width\n      const unitsPerPx = vb.width / px\n\n      if (e.ctrlKey || e.metaKey) {\n        // Zoom toward the cursor. deltaY<0 (pinch out / scroll up) zooms in.\n        // Gentle coefficient so a single wheel notch is a smooth ~1.1-1.2x,\n        // and trackpad pinch (many small deltas) accumulates naturally.\n        const factor = Math.exp(-e.deltaY * 0.0025)\n        const min = this.options.zoomMin ?? 0.1\n        const max = this.options.zoomMax ?? 10\n        const curZoom = px / vb.width\n        let newZoom = curZoom * factor\n        newZoom = Math.max(min, Math.min(max, newZoom))\n        const newW = px / newZoom\n        const newH = (vb.height / vb.width) * newW\n        // Keep the world point under the cursor fixed\n        const px0 = e.clientX - rect.left\n        const py0 = e.clientY - rect.top\n        const wx = vb.x + px0 * unitsPerPx\n        const wy = vb.y + py0 * (vb.height / rect.height || unitsPerPx)\n        const nx = wx - (px0 / px) * newW\n        const ny = wy - (py0 / (rect.height || px)) * newH\n        this.canvas.viewbox(nx, ny, newW, newH)\n      } else {\n        // Pan by the scroll delta (screen px → world units)\n        this.canvas.viewbox(\n          vb.x + e.deltaX * unitsPerPx,\n          vb.y + e.deltaY * unitsPerPx,\n          vb.width,\n          vb.height\n        )\n      }\n\n      // Notify listeners (coordinate display, followMe broadcast on panEnd)\n      this.options.onPan?.(e)\n      this.options.onZoom?.(e)\n    }\n    node.addEventListener(\"wheel\", this._wheelHandler, { passive: false })\n  }\n\n  private createZoomControls(): void {\n    // Create controls container\n    this.controlsContainer = document.createElement('div')\n    this.controlsContainer.className = 'svg-pan-zoom-controls'\n\n    // Position the container\n    const position = this.options.controlsPosition || 'top-left'\n    this.controlsContainer.style.position = 'absolute'\n    this.controlsContainer.style.zIndex = '100'\n\n    switch (position) {\n      case 'top-left':\n        this.controlsContainer.style.top = '10px'\n        this.controlsContainer.style.left = '10px'\n        break\n      case 'top-right':\n        this.controlsContainer.style.top = '10px'\n        this.controlsContainer.style.right = '10px'\n        break\n      case 'bottom-left':\n        this.controlsContainer.style.bottom = '10px'\n        this.controlsContainer.style.left = '10px'\n        break\n      case 'bottom-right':\n        this.controlsContainer.style.bottom = '10px'\n        this.controlsContainer.style.right = '10px'\n        break\n    }\n\n    // Create zoom in button\n    const zoomInBtn = document.createElement('button')\n    zoomInBtn.textContent = '+'\n    zoomInBtn.title = 'Zoom In'\n    zoomInBtn.addEventListener('click', () => this.zoomIn())\n    this.controlsContainer.appendChild(zoomInBtn)\n\n    // Create zoom out button\n    const zoomOutBtn = document.createElement('button')\n    zoomOutBtn.textContent = '−'  // Using minus sign character\n    zoomOutBtn.title = 'Zoom Out'\n    zoomOutBtn.addEventListener('click', () => this.zoomOut())\n    this.controlsContainer.appendChild(zoomOutBtn)\n\n    // Create reset button\n    const resetBtn = document.createElement('button')\n    resetBtn.textContent = '⟲'  // Reset icon\n    resetBtn.title = 'Reset View'\n    resetBtn.addEventListener('click', () => this.reset())\n    this.controlsContainer.appendChild(resetBtn)\n\n    // Add to slate element\n    this.slate.element.appendChild(this.controlsContainer)\n  }\n\n  private removeZoomControls(): void {\n    if (this.controlsContainer && this.controlsContainer.parentNode) {\n      this.controlsContainer.parentNode.removeChild(this.controlsContainer)\n      this.controlsContainer = null\n    }\n  }\n\n  public enable() {\n    if (!this.isEnabled) {\n      this.init()\n    }\n    this.options.enabled = true\n  }\n\n  public disable() {\n    if (this.isEnabled) {\n      this.canvas.panZoom(false)\n      this.isEnabled = false\n    }\n    this.options.enabled = false\n  }\n\n  public enablePan() {\n    this.options.panning = true\n    if (this.isEnabled) {\n      this.canvas.panZoom({ ...this.getAllOptions(), panning: true })\n    }\n  }\n\n  public disablePan() {\n    this.options.panning = false\n    if (this.isEnabled) {\n      this.canvas.panZoom({ ...this.getAllOptions(), panning: false })\n    }\n  }\n\n  public enableZoom() {\n    this.options.wheelZoom = true\n    this.options.pinchZoom = true\n    if (this.isEnabled) {\n      this.canvas.panZoom({ ...this.getAllOptions(), wheelZoom: true, pinchZoom: true })\n    }\n  }\n\n  public disableZoom() {\n    this.options.wheelZoom = false\n    this.options.pinchZoom = false\n    if (this.isEnabled) {\n      this.canvas.panZoom({ ...this.getAllOptions(), wheelZoom: false, pinchZoom: false })\n    }\n  }\n\n  public pan(point: { x: number; y: number }) {\n    if (this.isEnabled) {\n      // Get current viewbox\n      const vb = this.canvas.viewbox()\n      // Pan by setting new viewbox position\n      this.canvas.viewbox(point.x, point.y, vb.width, vb.height)\n    }\n  }\n\n  public panBy(delta: { x: number; y: number }) {\n    if (this.isEnabled) {\n      const vb = this.canvas.viewbox()\n      this.canvas.viewbox(vb.x + delta.x, vb.y + delta.y, vb.width, vb.height)\n    }\n  }\n\n  public zoom(level: number, point?: { x: number; y: number }) {\n    if (this.isEnabled) {\n      if (point) {\n        this.canvas.zoom(level, point)\n      } else {\n        this.canvas.zoom(level)\n      }\n    }\n  }\n\n  public zoomBy(factor: number) {\n    if (this.isEnabled) {\n      const currentZoom = this.getZoom()\n      this.canvas.zoom(currentZoom * factor)\n    }\n  }\n\n  /** Zoom in one step. */\n  public zoomIn() {\n    if (this.isEnabled) {\n      const currentZoom = this.getZoom()\n      this.canvas.zoom(currentZoom * 1.25)\n    }\n  }\n\n  /** Zoom out one step. */\n  public zoomOut() {\n    if (this.isEnabled) {\n      const currentZoom = this.getZoom()\n      this.canvas.zoom(currentZoom * 0.8)\n    }\n  }\n\n  public zoomAtPoint(level: number, point: { x: number; y: number }) {\n    if (this.isEnabled) {\n      this.canvas.zoom(level, point)\n    }\n  }\n\n  public reset() {\n    if (!this.isEnabled) return\n    // Reset to 1:1 (viewBox = container px) centered on the current view\n    // center — never a hardcoded origin box — then fit content if any.\n    const px = this.containerPx()\n    const vb = this.canvas.viewbox() || { x: 0, y: 0, width: px.w, height: px.h }\n    const cx = (vb.x || 0) + (vb.width || px.w) / 2\n    const cy = (vb.y || 0) + (vb.height || px.h) / 2\n    this.canvas.viewbox(cx - px.w / 2, cy - px.h / 2, px.w, px.h)\n    this.fit()\n  }\n\n  /** Container pixel size (the infinite canvas fills its element). */\n  private containerPx(): { w: number; h: number } {\n    const el = this.slate?.element\n    const rect = el?.getBoundingClientRect?.()\n    return {\n      w: Math.max(1, Math.round(rect?.width || this.canvas.node.clientWidth || 800)),\n      h: Math.max(1, Math.round(rect?.height || this.canvas.node.clientHeight || 600)),\n    }\n  }\n\n  public resetZoom() {\n    if (this.isEnabled) {\n      this.canvas.zoom(1)\n    }\n  }\n\n  public resetPan() {\n    if (this.isEnabled) {\n      const vb = this.canvas.viewbox()\n      this.canvas.viewbox(0, 0, vb.width, vb.height)\n    }\n  }\n\n  public fit() {\n    // Fit all node content in view\n    if (!this.isEnabled) return\n\n    // Compute bounds from the slate's actual nodes, not SVG bbox (which includes markers/defs at origin)\n    const nodes = this.slate?.nodes?.allNodes\n    if (!nodes || nodes.length === 0) return\n\n    let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity\n    for (const node of nodes) {\n      const x = node.options.x ?? 0\n      const y = node.options.y ?? 0\n      const w = node.options.width ?? 100\n      const h = node.options.height ?? 60\n      minX = Math.min(minX, x)\n      minY = Math.min(minY, y)\n      maxX = Math.max(maxX, x + w)\n      maxY = Math.max(maxY, y + h)\n    }\n\n    if (!isFinite(minX)) return\n\n    const contentWidth = maxX - minX\n    const contentHeight = maxY - minY\n    const padding = 50\n\n    // Compute viewbox that centers content with padding\n    const vbWidth = contentWidth + padding * 2\n    const vbHeight = contentHeight + padding * 2\n    const px = this.containerPx()\n    const containerAspect = px.w / px.h\n    const contentAspect = vbWidth / vbHeight\n\n    let finalW = vbWidth, finalH = vbHeight\n    if (contentAspect > containerAspect) {\n      finalH = finalW / containerAspect\n    } else {\n      finalW = finalH * containerAspect\n    }\n\n    // Never zoom IN past 1:1 just to fill (Miro/v1 behavior): the viewBox is\n    // at least the container's pixel size, so small content sits at 100%\n    // centered rather than blown up to 400%+. Larger content still zooms out.\n    if (finalW < px.w) {\n      finalW = px.w\n      finalH = px.h\n    }\n\n    const cx = minX + contentWidth / 2\n    const cy = minY + contentHeight / 2\n    this.canvas.viewbox(\n      cx - finalW / 2,\n      cy - finalH / 2,\n      finalW,\n      finalH\n    )\n  }\n\n  public center() {\n    if (!this.isEnabled) return\n    // Center on the NODES' bounding box, not canvas.bbox() — the latter\n    // includes marker/def elements near origin and would pull the view off\n    // the actual content.\n    const nodes = this.slate?.nodes?.allNodes\n    const vb = this.canvas.viewbox()\n    if (!nodes || nodes.length === 0) return\n    let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity\n    for (const node of nodes) {\n      const x = node.options.x ?? 0\n      const y = node.options.y ?? 0\n      const w = node.options.width ?? 100\n      const h = node.options.height ?? 60\n      minX = Math.min(minX, x); minY = Math.min(minY, y)\n      maxX = Math.max(maxX, x + w); maxY = Math.max(maxY, y + h)\n    }\n    if (!isFinite(minX)) return\n    const cx = (minX + maxX) / 2\n    const cy = (minY + maxY) / 2\n    this.canvas.viewbox(cx - vb.width / 2, cy - vb.height / 2, vb.width, vb.height)\n  }\n\n  /** @returns Current zoom level (1 = 100%). */\n  public getZoom(): number {\n    if (!this.isEnabled) return 1\n    try {\n      // svg.panzoom.js stores zoom level on the canvas\n      return (this.canvas as any).zoom() || 1\n    } catch (e) {\n      return 1\n    }\n  }\n\n  /** @returns Current pan position as { x, y }. */\n  public getPan(): { x: number; y: number } {\n    if (!this.isEnabled) return { x: 0, y: 0 }\n    try {\n      const vb = this.canvas.viewbox()\n      return { x: vb.x, y: vb.y }\n    } catch (e) {\n      return { x: 0, y: 0 }\n    }\n  }\n\n  public resize() {\n    // svg.panzoom.js handles this automatically\n    // Just update the canvas size if needed\n  }\n\n  public destroy() {\n    if (this._wheelHandler && this.canvas.node?.removeEventListener) {\n      this.canvas.node.removeEventListener(\"wheel\", this._wheelHandler)\n      this._wheelHandler = null\n    }\n    if (this.isEnabled) {\n      this.canvas.panZoom(false)\n\n      // Remove event listeners\n      this.canvas.off('panStart')\n      this.canvas.off('panning')\n      this.canvas.off('panEnd')\n      this.canvas.off('zoom')\n\n      // Remove zoom controls\n      this.removeZoomControls()\n\n      this.isEnabled = false\n    }\n  }\n\n  /** @returns Whether pan/zoom is initialized and enabled. */\n  public isInitialized(): boolean {\n    return this.isEnabled\n  }\n\n  private getAllOptions() {\n    return {\n      panning: this.options.panning,\n      pinchZoom: this.options.pinchZoom,\n      wheelZoom: this.options.wheelZoom,\n      panButton: this.options.panButton,\n      oneFingerPan: this.options.oneFingerPan,\n      margins: this.options.margins,\n      zoomFactor: this.options.zoomFactor,\n      zoomMin: this.options.zoomMin,\n      zoomMax: this.options.zoomMax,\n      wheelZoomDeltaModeLinePixels: this.options.wheelZoomDeltaModeLinePixels,\n      wheelZoomDeltaModeScreenPixels: this.options.wheelZoomDeltaModeScreenPixels,\n      momentum: this.options.momentum,\n      momentumSlowdown: this.options.momentumSlowdown\n    }\n  }\n}\n","import { SVG, Svg, Rect, Element } from \"@svgdotjs/svg.js\";\nimport type { Slate } from \"./Slate\";\nimport type { Node } from \"./Node\";\n\nexport interface BirdsEyeOptions {\n  enabled?: boolean;\n  position?: \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\";\n  width?: number;\n  height?: number;\n  backgroundColor?: string;\n  viewportColor?: string;\n  viewportBorderColor?: string;\n  nodeColor?: string;\n  borderRadius?: number;\n  margin?: number;\n  showZoomControls?: boolean;  // Show +/- zoom buttons below minimap\n}\n\nexport class BirdsEye {\n  private slate: Slate;\n  private options: BirdsEyeOptions;\n  private container: HTMLDivElement | null = null;\n  private miniCanvas: Svg | null = null;\n  private viewportIndicator: Rect | null = null;\n  private nodeShapes: Map<string, Element> = new Map();\n  private _enabled: boolean = false;\n  private isDragging: boolean = false;\n  private scale: number = 0.1;\n  private dragStartX: number = 0;\n  private dragStartY: number = 0;\n  private viewportStartX: number = 0;\n  private viewportStartY: number = 0;\n  private zoomControlsContainer: HTMLDivElement | null = null;\n\n  // Event handler references for cleanup\n  private boundMouseMove: ((e: MouseEvent) => void) | null = null;\n  private boundMouseUp: ((e: MouseEvent) => void) | null = null;\n\n  constructor(slate: Slate, options: BirdsEyeOptions = {}) {\n    this.slate = slate;\n    this.options = {\n      enabled: false,\n      position: \"bottom-right\",  // Miro-style: bottom-right by default\n      width: 200,\n      height: 150,\n      backgroundColor: \"rgba(255, 255, 255, 0.95)\",\n      viewportColor: \"rgba(66, 133, 244, 0.3)\",\n      viewportBorderColor: \"#4285f4\",\n      nodeColor: \"#666666\",\n      borderRadius: 4,\n      margin: 10,\n      showZoomControls: true,  // Show zoom controls by default\n      ...options,\n    };\n  }\n\n  public enable(): void {\n    if (this._enabled) return;\n    this._enabled = true;\n\n    this.createContainer();\n    this.createMiniCanvas();\n    this.renderNodes();\n    this.createViewportIndicator();\n    this.setupEventListeners();\n    this.updateViewport();\n\n    // Create zoom controls if enabled\n    if (this.options.showZoomControls) {\n      this.createZoomControls();\n    }\n\n    console.log(\"BIRDSEYE_DEBUG: BirdsEye enabled\");\n  }\n\n  public disable(): void {\n    if (!this._enabled) return;\n    this._enabled = false;\n\n    this.removeEventListeners();\n    this.removeZoomControls();\n\n    if (this.container && this.container.parentNode) {\n      this.container.parentNode.removeChild(this.container);\n    }\n\n    this.container = null;\n    this.miniCanvas = null;\n    this.viewportIndicator = null;\n    this.nodeShapes.clear();\n\n    console.log(\"BIRDSEYE_DEBUG: BirdsEye disabled\");\n  }\n\n  public isEnabled(): boolean {\n    return this._enabled;\n  }\n\n  public refresh(): void {\n    if (!this._enabled) return;\n\n    // Re-render all nodes\n    this.renderNodes();\n    this.updateViewport();\n  }\n\n  public updateViewport(): void {\n    if (!this._enabled || !this.viewportIndicator || !this.miniCanvas) return;\n\n    const panZoom = this.slate.panZoom;\n    if (!panZoom) return;\n\n    // Get current viewport state from main canvas\n    const zoom = panZoom.getZoom() || 1;\n    const pan = panZoom.getPan() || { x: 0, y: 0 };\n\n    // Get the main canvas dimensions\n    const viewportWidth = this.options.width! || 200;\n    const viewportHeight = this.options.height! || 150;\n\n    // Calculate content bounds for scaling\n    const bounds = this.calculateContentBounds();\n\n    // Calculate the scale to fit content in minimap\n    const contentWidth = Math.max(bounds.maxX - bounds.minX, 1);\n    const contentHeight = Math.max(bounds.maxY - bounds.minY, 1);\n\n    // Add padding to bounds\n    const padding = 100;\n    const totalWidth = contentWidth + padding * 2;\n    const totalHeight = contentHeight + padding * 2;\n\n    // Calculate scale to fit content\n    this.scale = Math.min(\n      viewportWidth / totalWidth,\n      viewportHeight / totalHeight\n    );\n\n    // Get visible area in main canvas coordinates\n    const visibleWidth =\n      (this.slate.options.viewPort?.originalWidth || 800) / zoom;\n    const visibleHeight =\n      (this.slate.options.viewPort?.originalHeight || 600) / zoom;\n\n    // Calculate viewport indicator position in minimap coordinates\n    // pan.x/pan.y are the viewbox origin (top-left of visible area in world coords)\n    // Minimap coordinate 0 corresponds to (minX - padding) in world coords\n    // So: minimapX = (worldX - minX + padding) * scale\n    const viewportX = (pan.x - bounds.minX + padding) * this.scale;\n    const viewportY = (pan.y - bounds.minY + padding) * this.scale;\n    const viewportW = visibleWidth * this.scale;\n    const viewportH = visibleHeight * this.scale;\n\n    // Update the viewport indicator\n    this.viewportIndicator.move(viewportX, viewportY);\n    this.viewportIndicator.size(Math.max(viewportW, 10), Math.max(viewportH, 10));\n  }\n\n  public updateNodePosition(node: Node): void {\n    if (!this._enabled) return;\n\n    const shape = this.nodeShapes.get(node.id);\n    if (!shape) return;\n\n    // Get the bounds for proper positioning\n    const bounds = this.calculateContentBounds();\n    const padding = 100;\n\n    // Update shape position (Q4: animate so the minimap glides when nodes change)\n    const x = (node.options.x! - bounds.minX + padding) * this.scale;\n    const y = (node.options.y! - bounds.minY + padding) * this.scale;\n\n    this.animateShapeMove(shape as any, x, y);\n\n    // Reflect the node's rotation in the minimap (fidelity with the canvas).\n    const w = (node.options.width || 100) * this.scale;\n    const h = (node.options.height || 60) * this.scale;\n    this.applyShapeRotation(shape as any, node, x, y, w, h);\n  }\n\n  /**\n   * Rotate a minimap shape to match the node's rotation, about its center.\n   * Absolute (transform, not the relative .rotate()) so repeated updates don't\n   * accumulate. Position (x/y attrs from move) is unaffected.\n   */\n  private applyShapeRotation(\n    shape: any,\n    node: Node,\n    x: number,\n    y: number,\n    w: number,\n    h: number\n  ): void {\n    const angle = node.options.rotate?.rotationAngle || 0;\n    try {\n      shape.transform({ rotate: angle, origin: [x + w / 2, y + h / 2] });\n    } catch (e) {\n      /* noop */\n    }\n  }\n\n  /**\n   * Q4: tween a minimap shape to (x,y) with a short easeInOutQuad rAF animation,\n   * cancelling any in-flight tween so it retargets smoothly (e.g. during a drag).\n   */\n  private animateShapeMove(shape: any, x: number, y: number, duration = 220): void {\n    if (typeof requestAnimationFrame === \"undefined\") {\n      try {\n        shape.move(x, y);\n      } catch (e) {\n        /* noop */\n      }\n      return;\n    }\n    let fromX = x;\n    let fromY = y;\n    try {\n      fromX = shape.x();\n      fromY = shape.y();\n    } catch (e) {\n      /* noop */\n    }\n    if (shape._beRaf) {\n      try {\n        cancelAnimationFrame(shape._beRaf);\n      } catch (e) {\n        /* noop */\n      }\n    }\n    const ease = (t: number) =>\n      t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;\n    let startTs: number | null = null;\n    const tick = (now: number) => {\n      if (startTs === null) startTs = now;\n      const p = Math.min(1, (now - startTs) / duration);\n      const e = ease(p);\n      try {\n        shape.move(fromX + (x - fromX) * e, fromY + (y - fromY) * e);\n      } catch (err) {\n        /* noop */\n      }\n      if (p < 1) shape._beRaf = requestAnimationFrame(tick);\n      else shape._beRaf = null;\n    };\n    shape._beRaf = requestAnimationFrame(tick);\n  }\n\n  public addNodeShape(node: Node): void {\n    if (!this._enabled || !this.miniCanvas) return;\n\n    const bounds = this.calculateContentBounds();\n    const padding = 100;\n\n    const x = (node.options.x! - bounds.minX + padding) * this.scale;\n    const y = (node.options.y! - bounds.minY + padding) * this.scale;\n    const w = (node.options.width || 100) * this.scale;\n    const h = (node.options.height || 60) * this.scale;\n\n    let shape: Element;\n    if (node.options.shape === \"circle\") {\n      const radius = Math.min(w, h) / 2;\n      shape = this.miniCanvas.circle(radius * 2).move(x, y);\n    } else {\n      shape = this.miniCanvas.rect(w, h).move(x, y);\n    }\n\n    shape.fill(node.options.backgroundColor || this.options.nodeColor!);\n    shape.stroke({ width: 0 });\n\n    // Reflect an already-rotated node in the minimap on creation.\n    this.applyShapeRotation(shape as any, node, x, y, w, h);\n\n    this.nodeShapes.set(node.id, shape);\n\n    // Q4: fade the new shape in.\n    try {\n      shape.opacity(0);\n      (shape as any).animate(220).opacity(1);\n    } catch (e) {\n      /* noop */\n    }\n\n    // Ensure viewport indicator stays on top\n    if (this.viewportIndicator) {\n      this.viewportIndicator.front();\n    }\n  }\n\n  public removeNodeShape(nodeId: string): void {\n    const shape = this.nodeShapes.get(nodeId);\n    if (shape) {\n      // Q4: fade out, then remove.\n      try {\n        if ((shape as any)._beRaf) cancelAnimationFrame((shape as any)._beRaf);\n        (shape as any)\n          .animate(180)\n          .opacity(0)\n          .after(() => {\n            try {\n              shape.remove();\n            } catch (e) {\n              /* noop */\n            }\n          });\n      } catch (e) {\n        try {\n          shape.remove();\n        } catch (err) {\n          /* noop */\n        }\n      }\n      this.nodeShapes.delete(nodeId);\n    }\n  }\n\n  private createContainer(): void {\n    this.container = document.createElement(\"div\");\n    this.container.className = \"slateboxjs-birdseye\";\n\n    // Position the container\n    const position = this.options.position || \"bottom-right\";\n    const margin = this.options.margin || 10;\n\n    this.container.style.position = \"absolute\";\n    this.container.style.width = `${this.options.width}px`;\n    this.container.style.height = `${this.options.height}px`;\n    this.container.style.backgroundColor = this.options.backgroundColor!;\n    this.container.style.borderRadius = `${this.options.borderRadius}px`;\n    this.container.style.border = \"1px solid #ccc\";\n    this.container.style.boxShadow = \"0 2px 8px rgba(0,0,0,0.15)\";\n    this.container.style.overflow = \"hidden\";\n    this.container.style.zIndex = \"100\";\n\n    // Set position based on option\n    switch (position) {\n      case \"top-left\":\n        this.container.style.top = `${margin}px`;\n        this.container.style.left = `${margin}px`;\n        break;\n      case \"top-right\":\n        this.container.style.top = `${margin}px`;\n        this.container.style.right = `${margin}px`;\n        break;\n      case \"bottom-left\":\n        this.container.style.bottom = `${margin}px`;\n        this.container.style.left = `${margin}px`;\n        break;\n      case \"bottom-right\":\n      default:\n        this.container.style.bottom = `${margin}px`;\n        this.container.style.right = `${margin}px`;\n        break;\n    }\n\n    // Add to slate element\n    this.slate.element.appendChild(this.container);\n  }\n\n  private createMiniCanvas(): void {\n    if (!this.container) return;\n\n    this.miniCanvas = SVG()\n      .addTo(this.container)\n      .size(this.options.width!, this.options.height!);\n\n    // Set a light background\n    this.miniCanvas.rect(this.options.width!, this.options.height!).fill(\"#f8f9fa\");\n  }\n\n  private renderNodes(): void {\n    if (!this.miniCanvas) return;\n\n    // Clear existing node shapes\n    this.nodeShapes.forEach((shape) => shape.remove());\n    this.nodeShapes.clear();\n\n    // Calculate bounds and scale\n    const bounds = this.calculateContentBounds();\n    const padding = 100;\n    const contentWidth = Math.max(bounds.maxX - bounds.minX, 1);\n    const contentHeight = Math.max(bounds.maxY - bounds.minY, 1);\n    const totalWidth = contentWidth + padding * 2;\n    const totalHeight = contentHeight + padding * 2;\n\n    this.scale = Math.min(\n      this.options.width! / totalWidth,\n      this.options.height! / totalHeight\n    );\n\n    // Render each node\n    const nodes = this.slate.getAllNodes();\n    nodes.forEach((node) => {\n      const x = (node.options.x! - bounds.minX + padding) * this.scale;\n      const y = (node.options.y! - bounds.minY + padding) * this.scale;\n      const w = Math.max((node.options.width || 100) * this.scale, 2);\n      const h = Math.max((node.options.height || 60) * this.scale, 2);\n\n      let shape: Element;\n      if (node.options.shape === \"circle\") {\n        const radius = Math.min(w, h) / 2;\n        shape = this.miniCanvas!.circle(radius * 2).move(x, y);\n      } else {\n        shape = this.miniCanvas!.rect(w, h).move(x, y);\n      }\n\n      shape.fill(node.options.backgroundColor || this.options.nodeColor!);\n      shape.stroke({ width: 0 });\n\n      // Apply rotation if the node is rotated\n      const rotationAngle = node.options.rotate?.rotationAngle || 0;\n      if (rotationAngle !== 0) {\n        // Rotate around the center of the shape\n        const cx = x + w / 2;\n        const cy = y + h / 2;\n        (shape as any).rotate(rotationAngle, cx, cy);\n      }\n\n      this.nodeShapes.set(node.id, shape);\n    });\n  }\n\n  private createViewportIndicator(): void {\n    if (!this.miniCanvas) return;\n\n    this.viewportIndicator = this.miniCanvas\n      .rect(50, 40)\n      .fill(this.options.viewportColor!)\n      .stroke({ color: this.options.viewportBorderColor!, width: 2 })\n      .css({ cursor: \"move\" });\n\n    // Make it draggable\n    this.viewportIndicator.on(\"mousedown\", (e: Event) => {\n      e.preventDefault();\n      e.stopPropagation();\n\n      const mouseEvent = e as MouseEvent;\n      this.isDragging = true;\n      this.dragStartX = mouseEvent.clientX;\n      this.dragStartY = mouseEvent.clientY;\n\n      // Store current viewport position\n      const bbox = this.viewportIndicator!.bbox();\n      this.viewportStartX = bbox.x;\n      this.viewportStartY = bbox.y;\n\n      // Add temporary listeners\n      this.boundMouseMove = this.handleMouseMove.bind(this);\n      this.boundMouseUp = this.handleMouseUp.bind(this);\n      document.addEventListener(\"mousemove\", this.boundMouseMove);\n      document.addEventListener(\"mouseup\", this.boundMouseUp);\n    });\n\n    // Miro parity: click ANYWHERE ELSE in the minimap to JUMP the viewport, centered\n    // on the clicked point. (The indicator's own mousedown stops propagation, so\n    // dragging it still pans continuously — this only fires for clicks off it.)\n    this.miniCanvas.on(\"mousedown\", (e: Event) => {\n      const me = e as MouseEvent;\n      try {\n        const p = (this.miniCanvas as any).point(me.clientX, me.clientY);\n        const iw = this.viewportIndicator?.bbox().width || 50;\n        const ih = this.viewportIndicator?.bbox().height || 40;\n        const bounds = this.calculateContentBounds();\n        const padding = 100;\n        const panX = (p.x - iw / 2) / this.scale + bounds.minX - padding;\n        const panY = (p.y - ih / 2) / this.scale + bounds.minY - padding;\n        this.slate.panZoom?.pan({ x: panX, y: panY });\n      } catch (err) {\n        /* noop */\n      }\n    });\n  }\n\n  private handleMouseMove(e: MouseEvent): void {\n    if (!this.isDragging || !this.viewportIndicator) return;\n\n    const deltaX = e.clientX - this.dragStartX;\n    const deltaY = e.clientY - this.dragStartY;\n\n    // Move viewport indicator\n    const newX = this.viewportStartX + deltaX;\n    const newY = this.viewportStartY + deltaY;\n    this.viewportIndicator.move(newX, newY);\n\n    // Convert minimap movement to main canvas pan\n    // Scale factor converts minimap coords to main canvas coords\n    const bounds = this.calculateContentBounds();\n    const padding = 100;\n\n    // Calculate new pan position (inverse of updateViewport formula)\n    // minimapX = (panX - minX + padding) * scale\n    // Solving for panX: panX = (minimapX / scale) + minX - padding\n    const panX = (newX / this.scale) + bounds.minX - padding;\n    const panY = (newY / this.scale) + bounds.minY - padding;\n\n    this.slate.panZoom?.pan({ x: panX, y: panY });\n  }\n\n  private handleMouseUp(): void {\n    this.isDragging = false;\n\n    // Remove temporary listeners\n    if (this.boundMouseMove) {\n      document.removeEventListener(\"mousemove\", this.boundMouseMove);\n      this.boundMouseMove = null;\n    }\n    if (this.boundMouseUp) {\n      document.removeEventListener(\"mouseup\", this.boundMouseUp);\n      this.boundMouseUp = null;\n    }\n  }\n\n  private setupEventListeners(): void {\n    // Listen for pan/zoom changes on canvas (these events DO work on canvas)\n    if (this.slate.canvas) {\n      // Subscribe to panzoom events if available\n      (this.slate.canvas as any).on?.(\"zoom.birdseye\", () => {\n        this.updateViewport();\n      });\n\n      (this.slate.canvas as any).on?.(\"panning.birdseye\", () => {\n        this.updateViewport();\n      });\n\n      // Also listen for panEnd which is more reliable\n      (this.slate.canvas as any).on?.(\"panEnd.birdseye\", () => {\n        this.updateViewport();\n      });\n\n      // Note: Node drag/resize events don't bubble to canvas in SVG.js\n      // Instead, Slate.notifyNodeChanged() calls scheduleRefresh() directly\n    }\n\n    // We'll also poll for changes as a fallback\n    this.startPolling();\n  }\n\n  private refreshTimeoutId: number | null = null;\n\n  /**\n   * Schedule a refresh using trailing-edge debounce.\n   * Waits until events settle (300ms of no activity) before refreshing.\n   * This avoids unnecessary updates during continuous operations like rotation.\n   */\n  public scheduleRefresh(): void {\n    // Clear any pending refresh\n    if (this.refreshTimeoutId !== null) {\n      window.clearTimeout(this.refreshTimeoutId);\n    }\n\n    // Schedule refresh after events settle\n    this.refreshTimeoutId = window.setTimeout(() => {\n      this.refresh();\n      this.refreshTimeoutId = null;\n    }, 300);\n  }\n\n  private removeEventListeners(): void {\n    // Remove temporary document-level drag listeners (may still be attached\n    // if mousedown fired without a matching mouseup, e.g. focus loss)\n    if (this.boundMouseMove) {\n      document.removeEventListener(\"mousemove\", this.boundMouseMove);\n      this.boundMouseMove = null;\n    }\n    if (this.boundMouseUp) {\n      document.removeEventListener(\"mouseup\", this.boundMouseUp);\n      this.boundMouseUp = null;\n    }\n    this.isDragging = false;\n\n    // Remove canvas event listeners (using namespaced events)\n    if (this.slate.canvas) {\n      (this.slate.canvas as any).off?.(\".birdseye\");\n    }\n\n    // Clear any pending refresh\n    if (this.refreshTimeoutId !== null) {\n      window.clearTimeout(this.refreshTimeoutId);\n      this.refreshTimeoutId = null;\n    }\n\n    this.stopPolling();\n  }\n\n  private pollIntervalId: number | null = null;\n\n  private startPolling(): void {\n    // Poll for viewport changes every 100ms as a fallback\n    this.pollIntervalId = window.setInterval(() => {\n      if (this._enabled) {\n        this.updateViewport();\n      }\n    }, 100);\n  }\n\n  private stopPolling(): void {\n    if (this.pollIntervalId !== null) {\n      window.clearInterval(this.pollIntervalId);\n      this.pollIntervalId = null;\n    }\n  }\n\n  private createZoomControls(): void {\n    if (!this.container) return;\n\n    // Create zoom controls bar below the minimap (Miro style)\n    this.zoomControlsContainer = document.createElement(\"div\");\n    this.zoomControlsContainer.className = \"slateboxjs-birdseye-zoom-controls\";\n    this.zoomControlsContainer.style.cssText = `\n      display: flex;\n      justify-content: center;\n      align-items: center;\n      gap: 4px;\n      padding: 6px 8px;\n      background: rgba(255, 255, 255, 0.95);\n      border-top: 1px solid #e0e0e0;\n      border-radius: 0 0 ${this.options.borderRadius}px ${this.options.borderRadius}px;\n    `;\n\n    // Zoom out button\n    const zoomOutBtn = document.createElement(\"button\");\n    zoomOutBtn.textContent = \"−\";\n    zoomOutBtn.title = \"Zoom Out\";\n    zoomOutBtn.style.cssText = this.getZoomButtonStyle();\n    zoomOutBtn.addEventListener(\"click\", () => this.slate.panZoom?.zoomOut());\n    this.zoomControlsContainer.appendChild(zoomOutBtn);\n\n    // Zoom percentage display\n    const zoomDisplay = document.createElement(\"span\");\n    zoomDisplay.id = \"birdseye-zoom-display\";\n    zoomDisplay.style.cssText = `\n      font-size: 12px;\n      font-family: -apple-system, BlinkMacSystemFont, sans-serif;\n      color: #333;\n      min-width: 45px;\n      text-align: center;\n      cursor: pointer;\n    `;\n    zoomDisplay.textContent = \"100%\";\n    zoomDisplay.title = \"Reset to 100%\";\n    zoomDisplay.addEventListener(\"click\", () => {\n      this.slate.panZoom?.reset();\n      this.updateZoomDisplay();\n    });\n    this.zoomControlsContainer.appendChild(zoomDisplay);\n\n    // Zoom in button\n    const zoomInBtn = document.createElement(\"button\");\n    zoomInBtn.textContent = \"+\";\n    zoomInBtn.title = \"Zoom In\";\n    zoomInBtn.style.cssText = this.getZoomButtonStyle();\n    zoomInBtn.addEventListener(\"click\", () => this.slate.panZoom?.zoomIn());\n    this.zoomControlsContainer.appendChild(zoomInBtn);\n\n    // Append to container\n    this.container.appendChild(this.zoomControlsContainer);\n\n    // Start updating zoom display\n    this.startZoomDisplayUpdates();\n  }\n\n  private getZoomButtonStyle(): string {\n    return `\n      width: 28px;\n      height: 28px;\n      border: 1px solid #e0e0e0;\n      background: #f8f9fa;\n      cursor: pointer;\n      border-radius: 4px;\n      font-size: 16px;\n      font-weight: 500;\n      color: #333;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      transition: all 0.15s ease;\n    `;\n  }\n\n  private updateZoomDisplay(): void {\n    const display = this.container?.querySelector(\"#birdseye-zoom-display\") as HTMLElement;\n    if (display && this.slate.panZoom) {\n      const zoom = this.slate.panZoom.getZoom() || 1;\n      display.textContent = `${Math.round(zoom * 100)}%`;\n    }\n  }\n\n  private zoomDisplayIntervalId: number | null = null;\n\n  private startZoomDisplayUpdates(): void {\n    // Update zoom display periodically\n    this.zoomDisplayIntervalId = window.setInterval(() => {\n      if (this._enabled) {\n        this.updateZoomDisplay();\n      }\n    }, 200);\n  }\n\n  private removeZoomControls(): void {\n    if (this.zoomDisplayIntervalId !== null) {\n      window.clearInterval(this.zoomDisplayIntervalId);\n      this.zoomDisplayIntervalId = null;\n    }\n\n    if (this.zoomControlsContainer && this.zoomControlsContainer.parentNode) {\n      this.zoomControlsContainer.parentNode.removeChild(this.zoomControlsContainer);\n      this.zoomControlsContainer = null;\n    }\n  }\n\n  private calculateContentBounds(): {\n    minX: number;\n    minY: number;\n    maxX: number;\n    maxY: number;\n  } {\n    const nodes = this.slate.getAllNodes();\n\n    if (nodes.length === 0) {\n      // Return default viewport bounds if no nodes\n      const width = this.slate.options.viewPort?.originalWidth || 800;\n      const height = this.slate.options.viewPort?.originalHeight || 600;\n      return { minX: 0, minY: 0, maxX: width, maxY: height };\n    }\n\n    let minX = Infinity;\n    let minY = Infinity;\n    let maxX = -Infinity;\n    let maxY = -Infinity;\n\n    nodes.forEach((node) => {\n      const x = node.options.x || 0;\n      const y = node.options.y || 0;\n      const w = node.options.width || 100;\n      const h = node.options.height || 60;\n\n      minX = Math.min(minX, x);\n      minY = Math.min(minY, y);\n      maxX = Math.max(maxX, x + w);\n      maxY = Math.max(maxY, y + h);\n    });\n\n    // Frame the ACTUAL node content (M5). Do NOT expand to include the origin\n    // (0,0) or the viewport size — nodes live far out in world space (~10000),\n    // so forcing origin into the bounds spanned 0→10000 and shoved the content\n    // into the far bottom-right corner / off the minimap. The per-node padding\n    // in the placement math centers the content Miro-style.\n    return { minX, minY, maxX, maxY };\n  }\n}\n","/**\n * UndoRedo.ts - Snapshot-based undo/redo system\n *\n * Takes full JSON snapshots of the slate state.\n * Uses a 3-second debounce before saving snapshots.\n */\n\nimport { serialize, deserialize, type SlateJSON } from \"./Serialization\";\n\nexport interface UndoRedoOptions {\n  enabled?: boolean;\n  maxHistory?: number;\n  debounceMs?: number;\n}\n\nexport class UndoRedo {\n  private slate: any;\n  private options: UndoRedoOptions;\n  private undoStack: SlateJSON[] = [];\n  private redoStack: SlateJSON[] = [];\n  private debounceTimer: any = null;\n  private isRestoring: boolean = false;\n  private restoreQueue: Promise<void> = Promise.resolve();\n  private pendingRestores: number = 0;\n\n  constructor(slate: any, options: UndoRedoOptions = {}) {\n    this.slate = slate;\n    this.options = {\n      enabled: true,\n      maxHistory: 50,\n      // Coalesce a burst of edits into one undo step, but land the snapshot soon\n      // after activity stops so undo is responsive.\n      debounceMs: 500,\n      ...options,\n    };\n  }\n\n  /**\n   * Take a snapshot of the current state.\n   * Debounced to avoid excessive snapshots during rapid changes.\n   *\n   * @param init - If true, take immediately without debounce (initial state)\n   */\n  public snap(init: boolean = false): void {\n    if (!this.options.enabled || this.isRestoring) return;\n\n    if (init) {\n      this.takeSnapshot();\n      return;\n    }\n\n    // Debounce\n    if (this.debounceTimer) {\n      clearTimeout(this.debounceTimer);\n    }\n\n    this.debounceTimer = setTimeout(() => {\n      // Null the handle BEFORE snapshotting so undo()'s \"flush pending\" check\n      // (if (this.debounceTimer) forceSnapshot()) doesn't then push a duplicate\n      // of a state we just captured — which made undo() a no-op.\n      this.debounceTimer = null;\n      this.takeSnapshot();\n    }, this.options.debounceMs);\n  }\n\n  /**\n   * Take an immediate snapshot, bypassing the debounce timer.\n   * Useful for programmatic undo/redo sequences where you need\n   * guaranteed snapshot state right now (e.g., tests, scripts).\n   */\n  public forceSnapshot(): void {\n    if (!this.options.enabled || this.isRestoring) return;\n\n    // Clear any pending debounced snapshot\n    if (this.debounceTimer) {\n      clearTimeout(this.debounceTimer);\n      this.debounceTimer = null;\n    }\n\n    this.takeSnapshot();\n  }\n\n  /**\n   * Undo the last change. Restores the previous snapshot.\n   */\n  public undo(): boolean {\n    // Capture any pending (debounced) change first, so an edit made moments ago\n    // is on the stack and can be undone immediately.\n    if (this.debounceTimer) this.forceSnapshot();\n    if (this.undoStack.length <= 1) {\n      console.log(\"UNDOREDO_DEBUG: Nothing to undo\");\n      return false;\n    }\n\n    // Save current state to redo stack\n    const current = this.undoStack.pop()!;\n    this.redoStack.push(current);\n\n    // Restore previous state\n    const previous = this.undoStack[this.undoStack.length - 1];\n    this.restore(previous, \"undo\");\n\n    console.log(\n      \"UNDOREDO_DEBUG: Undo performed. Undo stack:\",\n      this.undoStack.length,\n      \"Redo stack:\",\n      this.redoStack.length\n    );\n\n    return true;\n  }\n\n  /**\n   * Redo the last undone change.\n   */\n  public redo(): boolean {\n    if (this.redoStack.length === 0) {\n      console.log(\"UNDOREDO_DEBUG: Nothing to redo\");\n      return false;\n    }\n\n    // Pop from redo stack\n    const next = this.redoStack.pop()!;\n\n    // Push to undo stack\n    this.undoStack.push(next);\n\n    // Restore state\n    this.restore(next, \"redo\");\n\n    console.log(\n      \"UNDOREDO_DEBUG: Redo performed. Undo stack:\",\n      this.undoStack.length,\n      \"Redo stack:\",\n      this.redoStack.length\n    );\n\n    return true;\n  }\n\n  /** Check if undo is available */\n  public canUndo(): boolean {\n    return this.undoStack.length > 1;\n  }\n\n  /** Check if redo is available */\n  public canRedo(): boolean {\n    return this.redoStack.length > 0;\n  }\n\n  /** Clear all history */\n  public clear(): void {\n    this.undoStack = [];\n    this.redoStack = [];\n    if (this.debounceTimer) {\n      clearTimeout(this.debounceTimer);\n    }\n  }\n\n  /** Destroy the undo/redo system, clearing all history and references */\n  public destroy(): void {\n    this.clear();\n    this.isRestoring = false;\n    (this as any).slate = null;\n  }\n\n  // ─── Private ─────────────────────────────────────────────────────\n\n  private takeSnapshot(): void {\n    let snapshot: SlateJSON;\n    try {\n      snapshot = serialize(this.slate);\n    } catch (e) {\n      // Slate not fully constructed / serializable yet — skip this snapshot.\n      return;\n    }\n\n    // Clear redo stack on new change\n    this.redoStack = [];\n\n    // Add to undo stack\n    this.undoStack.push(snapshot);\n\n    // Trim if exceeds max\n    if (this.undoStack.length > this.options.maxHistory!) {\n      this.undoStack.shift();\n    }\n\n    console.log(\n      \"UNDOREDO_DEBUG: Snapshot taken. Stack size:\",\n      this.undoStack.length\n    );\n  }\n\n  private restore(snapshot: SlateJSON, action: \"undo\" | \"redo\"): void {\n    // Restoring creates SVG nodes asynchronously. Serialize rapid undo/redo\n    // requests so an older restore cannot finish after a newer one and win.\n    this.pendingRestores += 1;\n    this.isRestoring = true;\n    this.restoreQueue = this.restoreQueue\n      .then(async () => {\n        await deserialize(snapshot, this.slate, false, true);\n\n        // A local undo/redo is still a document mutation. Broadcast one\n        // authoritative full-state baseline so remote peers restore the same\n        // document and the host's onSlateChanged persistence path runs.\n        const snapshotJSON = JSON.stringify(snapshot);\n        this.slate.broadcast?.(\"onSlateReplaced\", {\n          action,\n          snapshot: snapshotJSON,\n        });\n\n        // The Meteor host persists named snapshots through this callback and\n        // expects both fields (passing only `action` made the method unusable).\n        this.slate.options.events?.onTakeSnapshot?.({\n          action,\n          slateId: this.slate.options.id,\n          snapshot: snapshotJSON,\n        });\n      })\n      .catch((err: Error) =>\n        console.error(\"UNDOREDO_DEBUG: Restore failed\", err)\n      )\n      .finally(() => {\n        this.pendingRestores -= 1;\n        if (this.pendingRestores === 0) this.isRestoring = false;\n      });\n  }\n}\n","/**\n * MultiSelection.ts - Rectangle drag selection\n *\n * Provides:\n * - Shift+click: add/remove from selection\n * - Canvas drag: rectangle selection\n * - Visual selection rectangle\n * - Group move/delete operations\n */\n\nexport interface MultiSelectionOptions {\n  enabled?: boolean;\n  selectionColor?: string;\n  selectionOpacity?: number;\n}\n\nexport class MultiSelection {\n  private slate: any;\n  private options: MultiSelectionOptions;\n  private selectionRect: any = null;\n  private startPoint: { x: number; y: number } | null = null;\n  private isSelecting: boolean = false;\n  // Window-level drag handlers (bound only while a rubber-band is in progress) so\n  // the drag survives pointer capture and the cursor leaving the SVG.\n  private _winMove: ((e: PointerEvent) => void) | null = null;\n  private _winUp: ((e: PointerEvent) => void) | null = null;\n\n  constructor(slate: any, options: MultiSelectionOptions = {}) {\n    this.slate = slate;\n    this.options = {\n      enabled: true,\n      selectionColor: \"#4a90e2\",\n      selectionOpacity: 0.15,\n      ...options,\n    };\n\n    if (this.options.enabled) {\n      this.bindEvents();\n    }\n  }\n\n  public enable(): void {\n    this.options.enabled = true;\n    this.bindEvents();\n  }\n\n  public disable(): void {\n    this.options.enabled = false;\n    this.unbindEvents();\n    this.cancelSelection();\n  }\n\n  public isEnabled(): boolean {\n    return this.options.enabled!;\n  }\n\n  // ─── Event binding ───────────────────────────────────────────────\n\n  private bindEvents(): void {\n    const canvas = this.slate.canvas;\n    if (!canvas) return;\n\n    canvas.on(\"pointerdown.multiselect\", (event: any) => {\n      if (!this.options.enabled) return;\n\n      // Only start selection on direct canvas click (not on nodes)\n      const target = event.target;\n      const isCanvas =\n        target === canvas.node || target?.tagName === \"svg\";\n\n      if (!isCanvas) return;\n\n      // Get SVG point from pointer position\n      const pt = this.getSvgPoint(event);\n      if (!pt) return;\n\n      this.startPoint = pt;\n      this.isSelecting = true;\n\n      // Create selection rectangle\n      this.selectionRect = canvas\n        .rect(0, 0)\n        .move(pt.x, pt.y)\n        .fill({\n          color: this.options.selectionColor!,\n          opacity: this.options.selectionOpacity!,\n        })\n        .stroke({\n          color: this.options.selectionColor!,\n          width: 1,\n          dasharray: \"4,4\",\n        })\n        .attr(\"pointer-events\", \"none\");\n\n      // Track the rest of the drag on window (survives pointer capture / the\n      // cursor moving over nodes or off the SVG).\n      this._winMove = (e: PointerEvent) => this.onSelectMove(e);\n      this._winUp = (e: PointerEvent) => this.onSelectUp(e);\n      window.addEventListener(\"pointermove\", this._winMove, true);\n      window.addEventListener(\"pointerup\", this._winUp, true);\n    });\n  }\n\n  private onSelectMove(event: PointerEvent): void {\n    if (!this.isSelecting || !this.startPoint || !this.selectionRect) return;\n    const pt = this.getSvgPoint(event);\n    if (!pt) return;\n    const x = Math.min(this.startPoint.x, pt.x);\n    const y = Math.min(this.startPoint.y, pt.y);\n    const w = Math.abs(pt.x - this.startPoint.x);\n    const h = Math.abs(pt.y - this.startPoint.y);\n    this.selectionRect.move(x, y).size(w, h);\n  }\n\n  private onSelectUp(event: PointerEvent): void {\n    this.detachWindowHandlers();\n    if (!this.isSelecting || !this.startPoint) {\n      this.cancelSelection();\n      return;\n    }\n    const pt = this.getSvgPoint(event);\n    if (pt) {\n      const x = Math.min(this.startPoint.x, pt.x);\n      const y = Math.min(this.startPoint.y, pt.y);\n      const w = Math.abs(pt.x - this.startPoint.x);\n      const h = Math.abs(pt.y - this.startPoint.y);\n      if (w > 5 && h > 5) {\n        this.selectNodesInRect(x, y, w, h, event.shiftKey);\n      }\n    }\n    this.cancelSelection();\n  }\n\n  private detachWindowHandlers(): void {\n    if (this._winMove) {\n      window.removeEventListener(\"pointermove\", this._winMove, true);\n      this._winMove = null;\n    }\n    if (this._winUp) {\n      window.removeEventListener(\"pointerup\", this._winUp, true);\n      this._winUp = null;\n    }\n  }\n\n  private unbindEvents(): void {\n    const canvas = this.slate.canvas;\n    if (!canvas) return;\n\n    canvas.off(\"pointerdown.multiselect\");\n    this.detachWindowHandlers();\n  }\n\n  private cancelSelection(): void {\n    this.isSelecting = false;\n    this.startPoint = null;\n    if (this.selectionRect) {\n      this.selectionRect.remove();\n      this.selectionRect = null;\n    }\n  }\n\n  // ─── Node selection ──────────────────────────────────────────────\n\n  private selectNodesInRect(\n    x: number,\n    y: number,\n    w: number,\n    h: number,\n    addToSelection: boolean\n  ): void {\n    const nodesInRect: any[] = [];\n\n    const allNodes = this.slate.nodes.allNodes;\n    for (const node of allNodes) {\n      try {\n        // The selection rect (x,y,w,h) is in SVG world coords (viewBox space).\n        // node.svgGroup.bbox() is the group's LOCAL bbox (~0,0,w,h) — the wrong\n        // space. Use the node's world position/size (options) instead.\n        const o = node.options;\n        const nx = o.x ?? 0;\n        const ny = o.y ?? 0;\n        const nw = o.width ?? 0;\n        const nh = o.height ?? 0;\n        if (nx < x + w && nx + nw > x && ny < y + h && ny + nh > y) {\n          nodesInRect.push(node);\n        }\n      } catch {\n        // Skip nodes without valid geometry\n      }\n    }\n\n    if (nodesInRect.length > 0) {\n      this.slate.selectNodes(nodesInRect, addToSelection);\n      // A real-mouse rubber-band ends with a `click` on the canvas, which the\n      // Slate canvas-click handler treats as an empty-space click and would\n      // clearSelection() — wiping the selection we just made (so a following\n      // drag can't group-move it). Stamp the moment so that handler skips the\n      // very next canvas click. (Synthetic-event tests don't fire the click, so\n      // this path was invisible to the e2e.)\n      (this.slate as any)._rubberBandSelectedAt = Date.now();\n      console.log(\n        \"MULTISELECT_DEBUG: Selected\",\n        nodesInRect.length,\n        \"nodes in rectangle\"\n      );\n    }\n  }\n\n  // ─── Helpers ─────────────────────────────────────────────────────\n\n  private getSvgPoint(event: any): { x: number; y: number } | null {\n    try {\n      const canvas = this.slate.canvas;\n      const svgNode = canvas.node;\n      const pt = svgNode.createSVGPoint();\n      pt.x = event.clientX;\n      pt.y = event.clientY;\n      const svgPt = pt.matrixTransform(svgNode.getScreenCTM().inverse());\n      return { x: svgPt.x, y: svgPt.y };\n    } catch {\n      return null;\n    }\n  }\n\n  // ─── Group operations ────────────────────────────────────────────\n\n  /** Delete all selected nodes */\n  public deleteSelected(): void {\n    const selected = this.slate.getSelectedNodes();\n    for (const node of selected) {\n      this.slate.removeNode(node.id);\n    }\n    this.slate.clearSelection();\n  }\n\n  /** Move all selected nodes by a delta */\n  public moveSelected(dx: number, dy: number): void {\n    const selected = this.slate.getSelectedNodes();\n    for (const node of selected) {\n      const x = (node.options.x || 0) + dx;\n      const y = (node.options.y || 0) + dy;\n      node.position(x, y);\n    }\n  }\n}\n","/**\n * Grid.ts - Grid overlay and snap-to-grid functionality\n */\n\nexport interface GridOptions {\n  enabled?: boolean;\n  gridSize?: number;\n  gridColor?: string;\n  gridOpacity?: number;\n  snapToGrid?: boolean;\n  snapToObjects?: boolean;\n}\n\nexport class Grid {\n  private slate: any;\n  private options: GridOptions;\n  private gridGroup: any = null;\n  private isVisible: boolean = false;\n\n  constructor(slate: any, options: GridOptions = {}) {\n    this.slate = slate;\n    this.options = {\n      enabled: false,\n      gridSize: 20,\n      gridColor: \"#e0e0e0\",\n      gridOpacity: 0.5,\n      snapToGrid: false,\n      snapToObjects: false,\n      ...options,\n    };\n  }\n\n  /** Show the grid overlay */\n  public show(): void {\n    if (this.isVisible) return;\n\n    this.isVisible = true;\n    this.render();\n  }\n\n  /** Hide the grid overlay */\n  public hide(): void {\n    this.isVisible = false;\n    if (this.gridGroup) {\n      this.gridGroup.remove();\n      this.gridGroup = null;\n    }\n  }\n\n  /** Destroy the grid and clean up */\n  public destroy(): void {\n    this.hide();\n  }\n\n  /** Toggle grid visibility */\n  public toggle(): void {\n    if (this.isVisible) {\n      this.hide();\n    } else {\n      this.show();\n    }\n  }\n\n  /** Check if grid is currently visible */\n  public isShown(): boolean {\n    return this.isVisible;\n  }\n\n  /** Snap a coordinate to the nearest grid point */\n  public snapPoint(\n    x: number,\n    y: number\n  ): { x: number; y: number } {\n    if (!this.options.snapToGrid) return { x, y };\n\n    const size = this.options.gridSize!;\n    return {\n      x: Math.round(x / size) * size,\n      y: Math.round(y / size) * size,\n    };\n  }\n\n  /** Update grid options */\n  public updateOptions(options: Partial<GridOptions>): void {\n    Object.assign(this.options, options);\n    if (this.isVisible) {\n      this.hide();\n      this.show();\n    }\n  }\n\n  // ─── Private ─────────────────────────────────────────────────────\n\n  private render(): void {\n    if (!this.slate.canvas) return;\n\n    // Remove old grid\n    if (this.gridGroup) {\n      this.gridGroup.remove();\n    }\n\n    const canvas = this.slate.canvas;\n    const viewbox = canvas.viewbox();\n    const size = this.options.gridSize!;\n    const color = this.options.gridColor!;\n    const opacity = this.options.gridOpacity!;\n\n    // Extend grid beyond viewbox for panning\n    const startX = Math.floor(viewbox.x / size) * size - size * 5;\n    const startY = Math.floor(viewbox.y / size) * size - size * 5;\n    const endX = viewbox.x + viewbox.width + size * 5;\n    const endY = viewbox.y + viewbox.height + size * 5;\n\n    this.gridGroup = canvas.group().attr(\"pointer-events\", \"none\");\n\n    // Draw vertical lines\n    for (let x = startX; x <= endX; x += size) {\n      this.gridGroup\n        .line(x, startY, x, endY)\n        .stroke({ color, width: 0.5, opacity });\n    }\n\n    // Draw horizontal lines\n    for (let y = startY; y <= endY; y += size) {\n      this.gridGroup\n        .line(startX, y, endX, y)\n        .stroke({ color, width: 0.5, opacity });\n    }\n\n    // Send grid to back\n    this.gridGroup.back();\n  }\n}\n","/**\n * Keyboard.ts - Global keyboard bindings\n *\n * Provides keyboard shortcuts for common actions:\n * - Delete/Backspace: remove selected nodes\n * - Ctrl+Z / Cmd+Z: undo\n * - Ctrl+Y / Cmd+Shift+Z: redo\n * - Ctrl+A / Cmd+A: select all\n * - Ctrl+C / Ctrl+V: copy / paste selected nodes\n * - Ctrl+D: duplicate selected nodes in place (offset)\n * - Arrow keys: nudge selected nodes\n * - Escape: deselect all\n */\n\nimport { guid } from \"../utils\";\nimport { v2NodeToV1 } from \"./compat\";\n\nexport interface KeyboardOptions {\n  enabled?: boolean;\n  nudgeDistance?: number;\n}\n\nexport class Keyboard {\n  private slate: any;\n  private options: KeyboardOptions;\n  private boundHandler: ((e: KeyboardEvent) => void) | null = null;\n  // Internal clipboard of copied node options (deep-cloned snapshots).\n  private clipboard: any[] = [];\n  // Internal edges (connectors) among the copied nodes, rewired on paste.\n  private clipboardEdges: any[] = [];\n  // How many times the current clipboard has been pasted — so repeated pastes\n  // CASCADE (each further from the source) instead of stacking on one spot (Miro).\n  private pasteCount = 0;\n  // Debounce handle for persisting arrow-key nudges.\n  private nudgeTimer: ReturnType<typeof setTimeout> | null = null;\n\n  constructor(slate: any, options: KeyboardOptions = {}) {\n    this.slate = slate;\n    this.options = {\n      enabled: true,\n      nudgeDistance: 5,\n      ...options,\n    };\n  }\n\n  /** Bind global keyboard shortcuts */\n  public bindGlobal(): void {\n    if (this.boundHandler) return;\n\n    this.boundHandler = (e: KeyboardEvent) => this.handleKeyDown(e);\n    document.addEventListener(\"keydown\", this.boundHandler);\n    console.log(\"KEYBOARD_DEBUG: Global bindings active\");\n  }\n\n  /** Unbind global keyboard shortcuts */\n  public unbindGlobal(): void {\n    if (this.boundHandler) {\n      document.removeEventListener(\"keydown\", this.boundHandler);\n      this.boundHandler = null;\n      console.log(\"KEYBOARD_DEBUG: Global bindings removed\");\n    }\n  }\n\n  /** Enable keyboard shortcuts */\n  public enable(): void {\n    this.options.enabled = true;\n  }\n\n  /** Disable keyboard shortcuts (keeps bindings, ignores events) */\n  public disable(): void {\n    this.options.enabled = false;\n  }\n\n  // ─── Private ─────────────────────────────────────────────────────\n\n  private handleKeyDown(e: KeyboardEvent): void {\n    if (!this.options.enabled) return;\n\n    // Don't intercept when typing in inputs\n    const target = e.target as HTMLElement;\n    if (\n      target.tagName === \"INPUT\" ||\n      target.tagName === \"TEXTAREA\" ||\n      target.isContentEditable\n    ) {\n      return;\n    }\n\n    const isMod = e.ctrlKey || e.metaKey;\n\n    switch (e.key) {\n      case \"Delete\":\n      case \"Backspace\":\n        this.deleteSelected(e);\n        break;\n\n      case \"z\":\n        if (isMod && e.shiftKey) {\n          this.redo(e);\n        } else if (isMod) {\n          this.undo(e);\n        }\n        break;\n\n      case \"y\":\n        if (isMod) {\n          this.redo(e);\n        }\n        break;\n\n      case \"a\":\n        if (isMod) {\n          this.selectAll(e);\n        }\n        break;\n\n      case \"c\":\n        if (isMod) {\n          this.copySelected(e);\n        }\n        break;\n\n      case \"v\":\n        if (isMod) {\n          this.pasteClipboard(e);\n        }\n        break;\n\n      case \"d\":\n        if (isMod) {\n          this.duplicateSelected(e);\n        }\n        break;\n\n      case \"g\":\n      case \"G\":\n        if (isMod) {\n          e.preventDefault();\n          if (e.shiftKey) {\n            this.slate.ungroupNodes?.();\n          } else {\n            this.slate.groupNodes?.();\n          }\n        }\n        break;\n\n      case \"]\":\n        if (isMod) {\n          this.bringToFront(e);\n        }\n        break;\n\n      case \"[\":\n        if (isMod) {\n          this.sendToBack(e);\n        }\n        break;\n\n      case \"Escape\":\n        this.deselect(e);\n        break;\n\n      case \"?\":\n        // Show keyboard shortcuts reference\n        console.log(\n          \"SlateboxJS Keyboard Shortcuts:\\n\" +\n          \"  Delete/Backspace — remove selected\\n\" +\n          \"  Ctrl+Z — undo\\n\" +\n          \"  Ctrl+Y — redo\\n\" +\n          \"  Ctrl+A — select all\\n\" +\n          \"  Ctrl+C / Ctrl+V — copy / paste\\n\" +\n          \"  Ctrl+D — duplicate\\n\" +\n          \"  Ctrl+] / Ctrl+[ — bring to front / send to back\\n\" +\n          \"  Escape — deselect\\n\" +\n          \"  Arrow keys — nudge selected (Shift = larger step)\\n\" +\n          \"  Tab — focus next node\\n\" +\n          \"  Enter/Space — select focused node\\n\" +\n          \"  ? — show this help\"\n        );\n        this.slate.announce?.(\"Keyboard shortcuts reference logged to console\");\n        break;\n\n      case \"F2\":\n        // Miro-style: edit the selected node's text inline on the canvas.\n        this.startInlineEditSelected(e);\n        break;\n\n      case \"Enter\":\n        // If exactly one node is selected, Enter begins inline text editing\n        // (Miro parity); otherwise fall back to selecting the focused node.\n        if (this.startInlineEditSelected(e)) break;\n        this.selectFocused(e);\n        break;\n\n      case \" \":\n        // Select the currently focused node (if a node SVG group has focus)\n        this.selectFocused(e);\n        break;\n\n      case \"Tab\":\n        // Let native Tab navigation work for node focusing\n        // When Shift+Tab is pressed, let browser handle reverse order\n        break;\n\n      case \"ArrowUp\":\n      case \"ArrowDown\":\n      case \"ArrowLeft\":\n      case \"ArrowRight\":\n        this.handleArrowKey(e);\n        break;\n    }\n  }\n\n  private deleteSelected(e: KeyboardEvent): void {\n    const selected = this.slate.getSelectedNodes();\n    if (selected.length === 0) return;\n\n    // Host permission checks (v1 contract): read-only/comment-only viewers\n    // cannot delete; comment nodes additionally need canRemoveComments\n    if (this.slate.isReadOnly?.() || this.slate.isCommentOnly?.()) return;\n\n    e.preventDefault();\n    for (const node of [...selected]) {\n      if (node.options?.isComment && !this.slate.canRemoveComments?.()) {\n        continue;\n      }\n      this.slate.removeNode(node.id);\n    }\n    this.slate.clearSelection();\n  }\n\n  private undo(e: KeyboardEvent): void {\n    e.preventDefault();\n    if (this.slate.undoRedo) {\n      this.slate.undoRedo.undo();\n    }\n  }\n\n  private redo(e: KeyboardEvent): void {\n    e.preventDefault();\n    if (this.slate.undoRedo) {\n      this.slate.undoRedo.redo();\n    }\n  }\n\n  private selectAll(e: KeyboardEvent): void {\n    e.preventDefault();\n    const allNodes = this.slate.nodes.allNodes;\n    if (allNodes.length > 0) {\n      this.slate.selectNodes(allNodes, false);\n    }\n  }\n\n  private deselect(e: KeyboardEvent): void {\n    e.preventDefault();\n    // Inside a group? Escape first steps OUT to re-select the whole group\n    // (Miro), and only a second Escape clears the selection.\n    if (this.slate.getEnteredGroupId?.()) {\n      this.slate.exitGroup?.();\n      return;\n    }\n    this.slate.clearSelection();\n  }\n\n  /**\n   * A serializable snapshot of a node's paintable options — enough to recreate\n   * it, minus identity (id) and relationship arrays (which reference the OLD node\n   * ids and would create dangling connections on a copy).\n   */\n  private snapshotNode(node: any): any {\n    let snap: any = {};\n    try {\n      snap = JSON.parse(JSON.stringify(node.options || {}));\n    } catch (err) {\n      snap = { ...(node.options || {}) };\n    }\n    const srcId = snap.id; // keep the source id so copies can rewire internal edges\n    delete snap.id;\n    delete snap.parentArrowForChildren;\n    delete snap.noChildArrowForChildren;\n    delete snap.associations;\n    delete snap.relationships;\n    if (srcId) snap.__srcId = srcId;\n    return snap;\n  }\n\n  /**\n   * Capture the connectors whose BOTH endpoints are within `nodes` — the internal\n   * edges of a selection. Duplicating/pasting a connected group must recreate these\n   * between the copies (Miro parity), or the copies come out disconnected.\n   */\n  private internalEdges(nodes: any[]): any[] {\n    const idSet = new Set(nodes.map((n: any) => n.id));\n    const edges: any[] = [];\n    for (const n of nodes) {\n      const am = n.relationships?.assocMap;\n      if (!am) continue;\n      for (const as of am.values()) {\n        if (idSet.has((as as any).childId)) {\n          let data: any = {};\n          try {\n            data = JSON.parse(JSON.stringify(as));\n          } catch (e) {\n            data = { ...(as as any) };\n          }\n          // Strip the id fields that reference the ORIGINAL nodes — the recreated\n          // edge must derive parent/child/id from the COPIES, or persistence\n          // re-attributes it to the source node on reload (a phantom extra edge).\n          delete data.id;\n          delete data.childId;\n          delete data.parentId;\n          edges.push({ parentSrcId: n.id, childSrcId: (as as any).childId, data });\n        }\n      }\n    }\n    return edges;\n  }\n\n  /** Ctrl/Cmd+C — copy the selected nodes to the internal clipboard. */\n  private copySelected(e: KeyboardEvent): void {\n    const selected = this.slate.getSelectedNodes?.() || [];\n    if (selected.length === 0) return;\n    e.preventDefault();\n    this.clipboard = selected.map((n: any) => this.snapshotNode(n));\n    this.clipboardEdges = this.internalEdges(selected);\n    this.pasteCount = 0; // fresh clipboard → restart the paste cascade\n    this.slate.announce?.(`Copied ${this.clipboard.length} node(s)`);\n  }\n\n  /** Ctrl/Cmd+V — paste the clipboard nodes (offset), then select the copies. */\n  private pasteClipboard(e: KeyboardEvent): void {\n    if (this.clipboard.length === 0) return;\n    e.preventDefault();\n    // Cascade: 1st paste +20, 2nd +40, … so repeated pastes don't stack on one spot.\n    this.pasteCount++;\n    this.createCopies(this.clipboard, 20 * this.pasteCount, this.clipboardEdges);\n  }\n\n  /** Ctrl/Cmd+] — bring the selected node(s) to the front of the z-order. */\n  private bringToFront(e: KeyboardEvent): void {\n    const selected = this.slate.getSelectedNodes?.() || [];\n    if (selected.length === 0) return;\n    e.preventDefault();\n    // node.toFront() broadcasts onNodeToFront, so it persists + syncs to collab.\n    for (const node of selected) node.toFront?.();\n  }\n\n  /** Ctrl/Cmd+[ — send the selected node(s) to the back of the z-order. */\n  private sendToBack(e: KeyboardEvent): void {\n    const selected = this.slate.getSelectedNodes?.() || [];\n    if (selected.length === 0) return;\n    e.preventDefault();\n    for (const node of selected) node.toBack?.();\n  }\n\n  /** Ctrl/Cmd+D — duplicate the current selection in place (offset). */\n  private duplicateSelected(e: KeyboardEvent): void {\n    const selected = this.slate.getSelectedNodes?.() || [];\n    if (selected.length === 0) return;\n    e.preventDefault();\n    const snaps = selected.map((n: any) => this.snapshotNode(n));\n    this.createCopies(snaps, 20, this.internalEdges(selected));\n  }\n\n  /**\n   * Create fresh nodes from option snapshots, offset by (offset,offset) and each\n   * given a new id, then select the new nodes. addNode() broadcasts onNodeAdded,\n   * so copies persist + sync to collab peers like any other added node.\n   */\n  private createCopies(\n    snapshots: any[],\n    offset: number,\n    edges: any[] = []\n  ): void {\n    if (this.slate.isReadOnly?.() || this.slate.isCommentOnly?.()) return;\n    const created: any[] = [];\n    const srcToCopy = new Map<string, any>();\n    for (const snap of snapshots) {\n      const opts = { ...snap };\n      const srcId = opts.__srcId;\n      delete opts.__srcId;\n      opts.id = guid();\n      opts.x = (opts.x || 0) + offset;\n      opts.y = (opts.y || 0) + offset;\n      try {\n        const node = this.slate.addNode(opts);\n        if (node) {\n          created.push(node);\n          if (srcId) srcToCopy.set(srcId, node);\n        }\n      } catch (err) {\n        /* noop */\n      }\n    }\n    if (created.length > 0) {\n      const finish = () => {\n        this.slate.selectNodes?.(created, false);\n        // Rewire internal connectors between the copies (Miro parity): a connector\n        // whose BOTH endpoints were duplicated is recreated between the new nodes.\n        for (const edge of edges) {\n          const p = srcToCopy.get(edge.parentSrcId);\n          const c = srcToCopy.get(edge.childSrcId);\n          if (p && c) {\n            try {\n              p.relationships?.addAssociation?.(c, edge.data);\n            } catch (e) {\n              /* noop */\n            }\n          }\n        }\n      };\n      const pending = created.map((n: any) => n?.ready).filter(Boolean);\n      if (pending.length) {\n        Promise.all(pending).then(finish).catch(finish);\n      } else {\n        setTimeout(finish, 120);\n      }\n      this.slate.announce?.(`Pasted ${created.length} node(s)`);\n    }\n  }\n\n  private nudge(dx: number, dy: number, e: KeyboardEvent): void {\n    const selected = this.slate.getSelectedNodes();\n    if (selected.length === 0) return;\n\n    e.preventDefault();\n    for (const node of selected) {\n      const x = (node.options.x || 0) + dx;\n      const y = (node.options.y || 0) + dy;\n      node.position(x, y);\n    }\n\n    // node.position() alone doesn't broadcast, so a nudge never persisted / synced\n    // (the node snapped back on reload). Broadcast onNodesMove — same package the\n    // drag-end emits — so the host saves it. Debounced so holding an arrow key\n    // batches into one save instead of hammering the server per keypress.\n    if (this.nudgeTimer) clearTimeout(this.nudgeTimer);\n    this.nudgeTimer = setTimeout(() => {\n      this.nudgeTimer = null;\n      const sel = this.slate.getSelectedNodes?.() || [];\n      if (sel.length > 0) {\n        this.slate.broadcast?.(\"onNodesMove\", {\n          nodeOptions: sel.map((n: any) => v2NodeToV1(n.options)),\n        });\n      }\n    }, 250);\n  }\n\n  private handleArrowKey(e: KeyboardEvent): void {\n    const selected = this.slate.getSelectedNodes();\n    if (selected.length > 0) {\n      // Nodes selected — nudge them. Shift = a larger jump (Miro parity): a plain\n      // arrow moves by nudgeDistance, Shift+arrow by 4× for coarse positioning.\n      const base = this.options.nudgeDistance!;\n      const d = e.shiftKey ? base * 4 : base;\n      switch (e.key) {\n        case \"ArrowUp\":    this.nudge(0, -d, e); break;\n        case \"ArrowDown\":  this.nudge(0, d, e); break;\n        case \"ArrowLeft\":  this.nudge(-d, 0, e); break;\n        case \"ArrowRight\": this.nudge(d, 0, e); break;\n      }\n    } else {\n      // No selection — navigate focus between nodes\n      const nodes = this.slate.getAllNodes();\n      if (nodes.length === 0) return;\n\n      const focused = document.activeElement;\n      const currentIdx = nodes.findIndex((n: any) => n.svgGroup?.node === focused);\n\n      let nextIdx = currentIdx;\n      if (e.key === \"ArrowRight\" || e.key === \"ArrowDown\") {\n        nextIdx = currentIdx < 0 ? 0 : Math.min(currentIdx + 1, nodes.length - 1);\n      } else {\n        nextIdx = currentIdx < 0 ? nodes.length - 1 : Math.max(currentIdx - 1, 0);\n      }\n\n      if (nextIdx >= 0 && nextIdx < nodes.length) {\n        e.preventDefault();\n        nodes[nextIdx].svgGroup?.node?.focus();\n      }\n    }\n  }\n\n  private selectFocused(e: KeyboardEvent): void {\n    const focused = document.activeElement;\n    const nodes = this.slate.getAllNodes();\n    const node = nodes.find((n: any) => n.svgGroup?.node === focused);\n    if (node) {\n      e.preventDefault();\n      this.slate.selectNodes([node], false);\n    }\n  }\n\n  /**\n   * If exactly one node is selected, begin inline text editing on it.\n   * Returns true when it started an edit (so callers can stop falling through).\n   * Skips SVG-content nodes (they have no editable text).\n   */\n  private startInlineEditSelected(e: KeyboardEvent): boolean {\n    const selected = (this.slate as any).selectedNodes || [];\n    if (selected.length !== 1) return false;\n    const node = selected[0];\n    if (!node?.editor?.startInline || node.nestedSvg) return false;\n    e.preventDefault();\n    node.editor.startInline();\n    return true;\n  }\n}\n","/**\n * ContextMenu.ts — right-click context menu for nodes (Miro parity).\n *\n * Surfaces node actions that already exist and broadcast (so they persist + sync\n * to collab): bring-to-front / send-to-back / duplicate / delete. Rendered as a\n * small positioned HTML overlay so it can carry text labels cleanly.\n *\n * Isolated-class pattern: constructor takes the slate; enable()/disable() bind\n * and unbind the global contextmenu listener.\n */\n\nimport { guid } from \"../utils\";\n\ninterface MenuItem {\n  label?: string;\n  act?: () => void;\n  danger?: boolean;\n  divider?: boolean;\n}\n\nexport class ContextMenu {\n  private slate: any;\n  private el: HTMLElement | null = null;\n  // Nodes the menu acts on — snapshotted at open() so a selection change between\n  // opening the menu and clicking an item (e.g. the right-click's own pointerup\n  // collapsing a multi-selection) can't make the action a no-op.\n  private targetNodes: any[] = [];\n  private boundContext: ((e: MouseEvent) => void) | null = null;\n  private boundDismiss: ((e: Event) => void) | null = null;\n  private boundEsc: ((e: KeyboardEvent) => void) | null = null;\n\n  constructor(slate: any) {\n    this.slate = slate;\n  }\n\n  /** Bind the global contextmenu handler. */\n  public enable(): void {\n    if (this.boundContext) return;\n    this.boundContext = (e: MouseEvent) => this.onContextMenu(e);\n    document.addEventListener(\"contextmenu\", this.boundContext, true);\n  }\n\n  /** Unbind + close. */\n  public disable(): void {\n    if (this.boundContext) {\n      document.removeEventListener(\"contextmenu\", this.boundContext, true);\n      this.boundContext = null;\n    }\n    this.close();\n  }\n\n  // ─── Private ─────────────────────────────────────────────────────\n\n  private onContextMenu(e: MouseEvent): void {\n    const target = e.target as Element | null;\n    const group = target?.closest?.(\"[data-node-id]\") as Element | null;\n    const id = group?.getAttribute?.(\"data-node-id\");\n    if (!id) {\n      // Not over a node — leave the native menu / other handlers alone.\n      this.close();\n      return;\n    }\n    const node = this.slate.nodes?.one?.(id);\n    if (!node) return;\n    e.preventDefault();\n\n    // Right-clicking a node selects it (unless it's already part of the\n    // selection, so a multi-selection stays intact for the action).\n    const selected: any[] = this.slate.getSelectedNodes?.() || [];\n    if (!selected.includes(node)) {\n      this.slate.selectNodes?.([node], false);\n    }\n    this.open(e.clientX, e.clientY);\n  }\n\n  private open(x: number, y: number): void {\n    this.close();\n\n    const menu = document.createElement(\"div\");\n    menu.className = \"sb-context-menu\";\n    menu.style.cssText =\n      \"position:fixed;z-index:100000;background:#fff;border:1px solid #e3e5ea;\" +\n      \"border-radius:8px;box-shadow:0 6px 24px rgba(0,0,0,0.18);padding:4px 0;\" +\n      \"min-width:180px;font:13px/1.4 system-ui,-apple-system,sans-serif;color:#222;\" +\n      \"user-select:none;\";\n    menu.style.left = `${x}px`;\n    menu.style.top = `${y}px`;\n\n    // Snapshot the selection now (see field comment).\n    this.targetNodes = [...(this.slate.getSelectedNodes?.() || [])];\n    const selCount = this.targetNodes.length;\n    const items: MenuItem[] = [\n      { label: \"Bring to front\", act: () => this.forEachTarget((n) => n.toFront?.()) },\n      { label: \"Send to back\", act: () => this.forEachTarget((n) => n.toBack?.()) },\n      { label: \"Duplicate\", act: () => this.duplicateTargets() },\n      { label: \"Delete\", act: () => this.deleteTargets(), danger: true },\n    ];\n    // Alignment tools only make sense for a multi-selection (Miro-style).\n    if (selCount >= 2) {\n      items.push(\n        { divider: true },\n        { label: \"Align left\", act: () => this.slate.alignNodes?.(\"left\", this.targetNodes) },\n        { label: \"Align center\", act: () => this.slate.alignNodes?.(\"centerH\", this.targetNodes) },\n        { label: \"Align right\", act: () => this.slate.alignNodes?.(\"right\", this.targetNodes) },\n        { label: \"Align top\", act: () => this.slate.alignNodes?.(\"top\", this.targetNodes) },\n        { label: \"Align middle\", act: () => this.slate.alignNodes?.(\"middle\", this.targetNodes) },\n        { label: \"Align bottom\", act: () => this.slate.alignNodes?.(\"bottom\", this.targetNodes) }\n      );\n    }\n    if (selCount >= 3) {\n      items.push(\n        { label: \"Distribute horizontally\", act: () => this.slate.distributeNodes?.(\"horizontal\", this.targetNodes) },\n        { label: \"Distribute vertically\", act: () => this.slate.distributeNodes?.(\"vertical\", this.targetNodes) }\n      );\n    }\n\n    for (const it of items) {\n      if (it.divider) {\n        const hr = document.createElement(\"div\");\n        hr.style.cssText = \"height:1px;background:#e3e5ea;margin:4px 0;\";\n        menu.appendChild(hr);\n        continue;\n      }\n      const row = document.createElement(\"div\");\n      row.textContent = it.label || \"\";\n      row.style.cssText =\n        \"padding:7px 16px;cursor:pointer;white-space:nowrap;\" +\n        (it.danger ? \"color:#d32f2f;\" : \"\");\n      row.addEventListener(\"mouseenter\", () => {\n        row.style.background = it.danger ? \"#fdecea\" : \"#f2f4f7\";\n      });\n      row.addEventListener(\"mouseleave\", () => {\n        row.style.background = \"\";\n      });\n      row.addEventListener(\"click\", (ev) => {\n        ev.stopPropagation();\n        try {\n          it.act?.();\n        } catch (err) {\n          /* noop */\n        }\n        this.close();\n      });\n      menu.appendChild(row);\n    }\n\n    document.body.appendChild(menu);\n    this.el = menu;\n\n    // Keep the menu on screen.\n    const r = menu.getBoundingClientRect();\n    if (r.right > window.innerWidth) {\n      menu.style.left = `${Math.max(4, window.innerWidth - r.width - 8)}px`;\n    }\n    if (r.bottom > window.innerHeight) {\n      menu.style.top = `${Math.max(4, window.innerHeight - r.height - 8)}px`;\n    }\n\n    // Dismiss on outside pointerdown or Escape (defer so the opening click\n    // doesn't immediately close it).\n    this.boundDismiss = (ev: Event) => {\n      if (this.el && !this.el.contains(ev.target as Node)) this.close();\n    };\n    this.boundEsc = (ev: KeyboardEvent) => {\n      if (ev.key === \"Escape\") this.close();\n    };\n    setTimeout(() => {\n      if (this.boundDismiss) {\n        document.addEventListener(\"pointerdown\", this.boundDismiss, true);\n      }\n      if (this.boundEsc) {\n        document.addEventListener(\"keydown\", this.boundEsc, true);\n      }\n    }, 0);\n  }\n\n  private close(): void {\n    if (this.el) {\n      this.el.remove();\n      this.el = null;\n    }\n    if (this.boundDismiss) {\n      document.removeEventListener(\"pointerdown\", this.boundDismiss, true);\n      this.boundDismiss = null;\n    }\n    if (this.boundEsc) {\n      document.removeEventListener(\"keydown\", this.boundEsc, true);\n      this.boundEsc = null;\n    }\n  }\n\n  private forEachTarget(fn: (n: any) => void): void {\n    for (const n of this.targetNodes) fn(n);\n  }\n\n  /** Delete the target nodes (removeNode broadcasts onNodeDeleted → persists). */\n  private deleteTargets(): void {\n    if (this.slate.isReadOnly?.() || this.slate.isCommentOnly?.()) return;\n    for (const n of [...this.targetNodes]) this.slate.removeNode?.(n.id);\n    this.slate.clearSelection?.();\n  }\n\n  /** Duplicate the target nodes offset (+20,+20); addNode broadcasts → persists. */\n  private duplicateTargets(): void {\n    if (this.slate.isReadOnly?.() || this.slate.isCommentOnly?.()) return;\n    const created: any[] = [];\n    const srcToCopy = new Map<string, any>();\n    const idSet = new Set(this.targetNodes.map((n: any) => n.id));\n    for (const n of this.targetNodes) {\n      let opts: any;\n      try {\n        opts = JSON.parse(JSON.stringify(n.options || {}));\n      } catch (err) {\n        opts = { ...(n.options || {}) };\n      }\n      const srcId = opts.id;\n      opts.id = guid();\n      opts.x = (opts.x || 0) + 20;\n      opts.y = (opts.y || 0) + 20;\n      delete opts.parentArrowForChildren;\n      delete opts.noChildArrowForChildren;\n      delete opts.associations;\n      try {\n        const node = this.slate.addNode?.(opts);\n        if (node) {\n          created.push(node);\n          if (srcId) srcToCopy.set(srcId, node);\n        }\n      } catch (err) {\n        /* noop */\n      }\n    }\n    // Internal connectors (both endpoints duplicated) → recreate between copies\n    // so a right-click \"Duplicate\" of a connected group keeps its edges (Miro).\n    const edges: any[] = [];\n    for (const n of this.targetNodes) {\n      const am = n.relationships?.assocMap;\n      if (!am) continue;\n      for (const as of am.values()) {\n        if (idSet.has((as as any).childId)) {\n          let data: any = {};\n          try {\n            data = JSON.parse(JSON.stringify(as));\n          } catch (e) {\n            data = { ...(as as any) };\n          }\n          // Strip id fields referencing the ORIGINAL nodes so the recreated edge\n          // derives parent/child/id from the COPIES (else reload adds a phantom edge).\n          delete data.id;\n          delete data.childId;\n          delete data.parentId;\n          edges.push({\n            parentSrcId: n.id,\n            childSrcId: (as as any).childId,\n            data,\n          });\n        }\n      }\n    }\n    if (created.length > 0) {\n      const finish = () => {\n        this.slate.selectNodes?.(created, false);\n        for (const edge of edges) {\n          const p = srcToCopy.get(edge.parentSrcId);\n          const c = srcToCopy.get(edge.childSrcId);\n          if (p && c) {\n            try {\n              p.relationships?.addAssociation?.(c, edge.data);\n            } catch (e) {\n              /* noop */\n            }\n          }\n        }\n      };\n      const pending = created.map((n: any) => n?.ready).filter(Boolean);\n      if (pending.length) {\n        Promise.all(pending).then(finish).catch(finish);\n      } else {\n        setTimeout(finish, 120);\n      }\n    }\n  }\n}\n","/**\n * Export.ts - SVG and PNG export functionality\n *\n * Provides methods to export the slate canvas as SVG or PNG.\n */\n\nexport interface ExportOptions {\n  /** Exclude the background from export */\n  noBackground?: boolean;\n  /** Export only the background (no nodes) */\n  backgroundOnly?: boolean;\n  /** Specific nodes to include (if undefined, all nodes) */\n  nodes?: any[];\n  /** For PNG: return as base64 string */\n  base64?: boolean;\n  /** For PNG: return as binary Blob */\n  asBinary?: boolean;\n  /** For PNG: include alpha transparency */\n  alpha?: boolean;\n  /** Use data image URLs for embedded images */\n  useDataImageUrls?: boolean;\n  /** Scale factor for PNG export */\n  scale?: number;\n}\n\n/**\n * Export the slate canvas as SVG string.\n */\nexport function exportSVG(\n  slate: any,\n  opts: ExportOptions = {},\n  callback?: (svg: string) => void\n): string {\n  const canvas = slate.canvas;\n  if (!canvas) {\n    const err = \"\";\n    callback?.(err);\n    return err;\n  }\n\n  try {\n    // Clone the SVG to avoid modifying the original\n    const svgNode = canvas.node.cloneNode(true) as SVGElement;\n\n    // Remove non-exportable elements\n    const removeSelectors = [\n      // All svg.select.js overlays (handles, rotate handle, bounding rect,\n      // selection shape) — matched by prefix so none are missed.\n      '[class*=\"svg_select\"]',\n      \".connection-handle\", // node drag-to-connect plugs\n      \".connector-handle\", // line endpoint drag handles (distinct class!)\n      // UI chrome that shouldn't appear in an exported diagram:\n      \".comment-badge\", // comment-count badges (rendered in the node group)\n      \".node-link-badge\", // link indicator badge (also in the node group)\n      \".node-cog\", // selection toolbar (delete/connect/cog pill)\n      \".node-toolbar\",\n      \".line-cog\", // line selection pill (delete/cog) — parallel to the node cog\n      \".line-toolbar\",\n      \"#slate-coordinates\",\n      // Connector hit areas: invisible wide paths used only for click detection\n      // (attribute-tagged, so the class selectors above miss them). Not visible\n      // content — strip them so the export has no near-invisible cruft / bbox skew.\n      '[connectortype=\"hitarea\"]',\n    ];\n\n    for (const sel of removeSelectors) {\n      const elements = svgNode.querySelectorAll(sel);\n      elements.forEach((el) => el.remove());\n    }\n\n    // Handle background option\n    if (opts.noBackground) {\n      // Remove background rect if exists\n      const bgRect = svgNode.querySelector(\"rect[data-background]\");\n      if (bgRect) bgRect.remove();\n    }\n\n    // Handle nodes filtering\n    if (opts.backgroundOnly) {\n      // Remove all node groups\n      const groups = svgNode.querySelectorAll(\"[data-node-id]\");\n      groups.forEach((g) => g.remove());\n    } else if (opts.nodes) {\n      // Keep only specified nodes — accepts node objects OR id strings\n      // (v1's node.png passes ids: slate.png({nodes: [id], ...}))\n      const keepIds = new Set(\n        opts.nodes.map((n: any) => (typeof n === \"string\" ? n : n.id))\n      );\n      const allGroups = svgNode.querySelectorAll(\"[data-node-id]\");\n      allGroups.forEach((g) => {\n        const nodeId = g.getAttribute(\"data-node-id\");\n        if (nodeId && !keepIds.has(nodeId)) {\n          g.remove();\n        }\n      });\n    }\n\n    // Frame the export to the CONTENT bounds (all remaining node groups), NOT the\n    // canvas's current pan/zoom viewBox — otherwise a scrolled or zoomed-in view\n    // exports clipped or blank. This gives the whole diagram every time (Miro).\n    try {\n      const groups = svgNode.querySelectorAll(\"[data-node-id]\");\n      if (groups.length > 0) {\n        const pad = 40;\n        let minX = Infinity;\n        let minY = Infinity;\n        let maxX = -Infinity;\n        let maxY = -Infinity;\n        for (const g of Array.from(groups)) {\n          const id = g.getAttribute(\"data-node-id\");\n          const node = slate.nodes?.one?.(id);\n          const o = node?.options;\n          if (!o) continue;\n          const x = o.x || 0;\n          const y = o.y || 0;\n          const w = o.width || 0;\n          const h = o.height || 0;\n          // Account for ROTATION: a rotated node's corners extend past its\n          // un-rotated bbox, so frame to the rotated corner extent or it gets\n          // clipped. rotate may be a number or a {rotationAngle} object.\n          const angle =\n            Number(\n              typeof o.rotate === \"object\" ? o.rotate?.rotationAngle : o.rotate\n            ) || 0;\n          if (angle) {\n            const cx = x + w / 2;\n            const cy = y + h / 2;\n            const rad = (angle * Math.PI) / 180;\n            const cos = Math.cos(rad);\n            const sin = Math.sin(rad);\n            for (const [px, py] of [\n              [x, y],\n              [x + w, y],\n              [x + w, y + h],\n              [x, y + h],\n            ]) {\n              const dx = px - cx;\n              const dy = py - cy;\n              const rx = cx + dx * cos - dy * sin;\n              const ry = cy + dx * sin + dy * cos;\n              minX = Math.min(minX, rx);\n              minY = Math.min(minY, ry);\n              maxX = Math.max(maxX, rx);\n              maxY = Math.max(maxY, ry);\n            }\n          } else {\n            minX = Math.min(minX, x);\n            minY = Math.min(minY, y);\n            maxX = Math.max(maxX, x + w);\n            maxY = Math.max(maxY, y + h);\n          }\n        }\n        if (isFinite(minX) && maxX > minX) {\n          const vbW = maxX - minX + pad * 2;\n          const vbH = maxY - minY + pad * 2;\n          svgNode.setAttribute(\n            \"viewBox\",\n            `${minX - pad} ${minY - pad} ${vbW} ${vbH}`\n          );\n          svgNode.setAttribute(\"width\", String(Math.round(vbW)));\n          svgNode.setAttribute(\"height\", String(Math.round(vbH)));\n          svgNode.setAttribute(\"preserveAspectRatio\", \"xMidYMid meet\");\n        }\n      }\n    } catch (e) {\n      /* noop — fall back to the cloned canvas viewBox */\n    }\n\n    // Serialize to string\n    const serializer = new XMLSerializer();\n    let svgString = serializer.serializeToString(svgNode);\n\n    // Add XML declaration\n    svgString =\n      '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n' + svgString;\n\n    callback?.(svgString);\n    return svgString;\n  } catch (error) {\n    console.error(\"EXPORT_DEBUG: SVG export failed:\", error);\n    const err = \"\";\n    callback?.(err);\n    return err;\n  }\n}\n\n/**\n * Export the slate canvas as PNG.\n *\n * @returns Promise that resolves with base64 string or Blob\n */\nexport async function exportPNG(\n  slate: any,\n  opts: ExportOptions = {},\n  callback?: (result: string | Blob) => void\n): Promise<string | Blob> {\n  const svgString = exportSVG(slate, opts);\n  if (!svgString) {\n    const result = opts.asBinary ? new Blob() : \"\";\n    callback?.(result);\n    return result;\n  }\n\n  const scale = opts.scale || 2; // Default 2x for better quality\n\n  try {\n    // Size the PNG to the EXPORTED svg's dimensions (fit-to-content), NOT the\n    // canvas's current pan/zoom viewport — else the PNG comes out at the viewport\n    // size with the diagram letterboxed/mis-scaled. exportSVG stamps the content\n    // viewBox; read its W/H, falling back to the viewport only if absent.\n    const canvas = slate.canvas;\n    let baseW: number;\n    let baseH: number;\n    const vbMatch = svgString.match(\n      /viewBox=\"[\\d.\\-]+\\s+[\\d.\\-]+\\s+([\\d.\\-]+)\\s+([\\d.\\-]+)\"/\n    );\n    if (vbMatch) {\n      baseW = parseFloat(vbMatch[1]);\n      baseH = parseFloat(vbMatch[2]);\n    } else {\n      const viewbox = canvas.viewbox();\n      baseW = viewbox.width;\n      baseH = viewbox.height;\n    }\n    const width = baseW * scale;\n    const height = baseH * scale;\n\n    // Create canvas element for rendering\n    const renderCanvas = document.createElement(\"canvas\");\n    renderCanvas.width = width;\n    renderCanvas.height = height;\n    const ctx = renderCanvas.getContext(\"2d\")!;\n\n    // Set white background unless alpha is requested\n    if (!opts.alpha) {\n      ctx.fillStyle =\n        slate.options.containerStyle?.backgroundColor || \"#ffffff\";\n      ctx.fillRect(0, 0, width, height);\n    }\n\n    // Create image from SVG\n    const img = new Image();\n    const svgBlob = new Blob([svgString], {\n      type: \"image/svg+xml;charset=utf-8\",\n    });\n    const url = URL.createObjectURL(svgBlob);\n\n    return new Promise<string | Blob>((resolve, reject) => {\n      img.onload = () => {\n        ctx.drawImage(img, 0, 0, width, height);\n        URL.revokeObjectURL(url);\n\n        if (opts.asBinary) {\n          renderCanvas.toBlob(\n            (blob) => {\n              const result = blob || new Blob();\n              callback?.(result);\n              resolve(result);\n            },\n            \"image/png\"\n          );\n        } else {\n          const dataUrl = renderCanvas.toDataURL(\"image/png\");\n          const result = opts.base64\n            ? dataUrl.split(\",\")[1] // Just the base64 part\n            : dataUrl; // Full data URL\n          callback?.(result);\n          resolve(result);\n        }\n      };\n\n      img.onerror = (err) => {\n        URL.revokeObjectURL(url);\n        console.error(\"EXPORT_DEBUG: PNG rendering failed:\", err);\n        const result = opts.asBinary ? new Blob() : \"\";\n        callback?.(result);\n        resolve(result);\n      };\n\n      img.src = url;\n    });\n  } catch (error) {\n    console.error(\"EXPORT_DEBUG: PNG export failed:\", error);\n    const result = opts.asBinary ? new Blob() : \"\";\n    callback?.(result);\n    return result;\n  }\n}\n","/**\n * Collab.ts - Collaboration core using Yjs + y-websocket\n *\n * Provides CRDT-based real-time collaboration, matching v1's\n * collab system architecture.\n *\n * Note: yjs and y-websocket are optional peer dependencies.\n * If not installed, collaboration features are no-ops.\n */\n\nexport interface CollabOptions {\n  /** WebSocket URL for y-websocket server */\n  wsUrl?: string;\n  /** Query-string params sent on connect (e.g. HMAC bearer + timestamp) */\n  wsParams?: Record<string, string>;\n  /** Optionally inject the yjs module (skips the dynamic import) */\n  Y?: any;\n  /** Optionally inject the y-websocket WebsocketProvider class */\n  WebsocketProvider?: any;\n  /** Room/document name (usually the slate ID) */\n  roomName?: string;\n  /** Client display name */\n  userName?: string;\n  /** Client color for cursor */\n  userColor?: string;\n  /** Called when a remote package is received */\n  onReceive?: (pkg: any) => void;\n  /** Called when connection status changes */\n  onStatusChange?: (status: \"connected\" | \"disconnected\" | \"connecting\") => void;\n  /** Called when awareness (user presence) changes */\n  onAwarenessChange?: (users: CollabUser[]) => void;\n}\n\nexport interface CollabUser {\n  clientID: number;\n  userName: string;\n  color: string;\n  cursor?: { x: number; y: number };\n}\n\nexport type CollabPackage = SlatePackage; // Backward-compat alias\n\nimport type { Slate } from \"./Slate\";\nimport type { SlatePackage } from \"./SlatePackage\";\n\nexport class Collab {\n  private slate: Slate;\n  private options: CollabOptions;\n  private doc: any = null; // Y.Doc\n  private provider: any = null; // WebsocketProvider\n  private collabMap: any = null; // Y.Map\n  private awareness: any = null;\n  private isConnected: boolean = false;\n  private clientID: number = 0;\n  private cursorElements: Map<number, any> = new Map();\n  private _cursorMoveHandler: ((e: any) => void) | null = null;\n  private _cursorTrackingNode: any = null;\n  /** Connection/user payload returned by the host's onInitCollaboration */\n  public userBaseData?: Record<string, any>;\n\n  constructor(slate: Slate, options: CollabOptions = {}) {\n    this.slate = slate;\n    this.options = {\n      wsUrl: \"ws://localhost:1234\",\n      roomName: \"default-slate\",\n      userName: \"Anonymous\",\n      userColor: \"#\" + Math.floor(Math.random() * 16777215).toString(16),\n      ...options,\n    };\n  }\n\n  /**\n   * Initialize collaboration.\n   * Requires yjs and y-websocket to be installed.\n   */\n  public async init(opts?: Partial<CollabOptions>): Promise<void> {\n    if (opts) {\n      Object.assign(this.options, opts);\n    }\n\n    try {\n      // Lazy dynamic imports keep yjs optional at install time while letting\n      // the CONSUMER's bundler resolve the specifiers (a Function()-wrapped\n      // import is invisible to bundlers and can never resolve in a browser).\n      // Hosts may also inject the modules directly via options.\n      const Y =\n        this.options.Y ||\n        ((await import(/* @vite-ignore */ \"yjs\" as any)) as any);\n      const WebsocketProvider =\n        this.options.WebsocketProvider ||\n        ((await import(/* @vite-ignore */ \"y-websocket\" as any)) as any)\n          .WebsocketProvider;\n\n      // Create Y.Doc\n      this.doc = new Y.Doc();\n      this.clientID = this.doc.clientID;\n\n      // Ask the host app for connection details BEFORE connecting.\n      // The app returns `{websocketUrl, websocketParams: {bearer, timestamp},\n      // color, userName, ...}` — websocketParams carries the HMAC auth the\n      // production collab server requires. (v1 semantics: awaited.)\n      let userBaseData: Record<string, any> | undefined;\n      const initCb = this.slate.options.events?.onInitCollaboration;\n      if (initCb) {\n        try {\n          userBaseData =\n            (await initCb(this.clientID.toString())) || undefined;\n        } catch (error) {\n          console.warn(\n            \"COLLAB_DEBUG: onInitCollaboration threw; using static options\",\n            error\n          );\n        }\n      }\n      if (userBaseData) {\n        this.userBaseData = userBaseData;\n        if (userBaseData.websocketUrl) {\n          this.options.wsUrl = userBaseData.websocketUrl;\n        }\n        if (userBaseData.websocketParams) {\n          this.options.wsParams = userBaseData.websocketParams;\n        }\n        if (userBaseData.userName) {\n          this.options.userName = userBaseData.userName;\n        }\n        if (userBaseData.color) {\n          this.options.userColor = userBaseData.color;\n        }\n      }\n\n      // Create shared map for collab packages\n      this.collabMap = this.doc.getMap(\"collabPackages\");\n\n      // Set up observer for remote changes\n      this.collabMap.observe((event: any) => {\n        if (event.transaction.local) return; // Skip local changes\n\n        event.changes.keys.forEach((change: any, key: string) => {\n          if (change.action === \"add\" || change.action === \"update\") {\n            const pkg = this.collabMap.get(key);\n            if (pkg) {\n              this.handleRemotePackage(pkg);\n            }\n          }\n        });\n      });\n\n      // Create WebSocket provider — params carry auth (e.g. HMAC bearer +\n      // timestamp) as query string values, matching y-websocket's API\n      this.provider = new WebsocketProvider(\n        this.options.wsUrl!,\n        this.options.roomName!,\n        this.doc,\n        {\n          connect: true,\n          params: this.options.wsParams || {},\n        }\n      );\n\n      // Set up awareness (user presence)\n      this.awareness = this.provider.awareness;\n      this.awareness.setLocalStateField(\"user\", {\n        name: this.options.userName,\n        color: this.options.userColor,\n      });\n\n      // Listen for awareness changes (presence + remote cursor movement)\n      const notifyUsersChanged = () => {\n        const users = this.getCollabUsers();\n        this.options.onAwarenessChange?.(users);\n        this.slate.options.events?.onCollaborationUsersChanged?.(users);\n        this.renderRemoteCursors(users);\n      };\n      this.awareness.on(\"change\", notifyUsersChanged);\n\n      // Broadcast this client's pointer position so peers can show its cursor\n      this.setupCursorTracking();\n\n      // Same-origin peers sync over y-websocket's BroadcastChannel INSIDE the\n      // provider constructor — their states can land before the listener\n      // above attaches. Emit the initial roster if remote states already exist.\n      if (this.getCollabUsers().length > 0) {\n        notifyUsersChanged();\n      }\n\n      // Connection status\n      this.provider.on(\"status\", (event: any) => {\n        this.isConnected = event.status === \"connected\";\n        this.options.onStatusChange?.(event.status);\n      });\n\n      // isConnected will be set by the status event handler above when the\n      // WebSocket actually connects. (onInitCollaboration already ran —\n      // awaited before the provider was created.)\n\n      console.log(\n        \"COLLAB_DEBUG: Initialized collaboration for room\",\n        this.options.roomName,\n        \"clientID:\",\n        this.clientID\n      );\n    } catch (error: unknown) {\n      const e = error as any;\n      if (\n        e.code === \"MODULE_NOT_FOUND\" ||\n        e.message?.includes(\"Cannot find module\")\n      ) {\n        console.warn(\n          \"COLLAB_DEBUG: yjs/y-websocket not installed. Collaboration disabled.\",\n          \"Install with: npm install yjs y-websocket\"\n        );\n      } else {\n        console.error(\"COLLAB_DEBUG: Failed to initialize collaboration:\", e);\n      }\n    }\n  }\n\n  /**\n   * Execute collab packages locally (from Invoker).\n   */\n  public invoke(packages: SlatePackage | SlatePackage[]): void {\n    const pkgs = Array.isArray(packages) ? packages : [packages];\n\n    for (const pkg of pkgs) {\n      this.exe(pkg);\n      // Host-owned panes use invoke() to apply locally and send() to sync/save.\n      // Unlike engine-originated mutations, that path never called\n      // Slate.broadcast(), so it silently skipped undo history. Remote Yjs\n      // packages call exe() directly and therefore do not create local history.\n      this.slate.recordUndoFor?.(pkg.type);\n    }\n  }\n\n  /**\n   * Send collab packages to remote peers.\n   *\n   * v1 contract: every send() surfaced back to the host through\n   * `onSlateChanged` (the yjs local-echo drove the app's save flow), so\n   * emit for each package after transmitting — the host's persistence\n   * depends on it even when no collab server is connected.\n   */\n  public send(packages: SlatePackage | SlatePackage[]): void {\n    const pkgs = Array.isArray(packages) ? packages : [packages];\n\n    if (this.collabMap) {\n      for (const pkg of pkgs) {\n        // A full-state replacement (undo/redo) supersedes every accumulated\n        // document mutation. Clear the replay log first so stale add/change\n        // packages cannot corrupt the restored baseline on reconnect.\n        if (pkg.type === \"onSlateReplaced\") {\n          this.pruneBeforeSlateReplacement();\n        }\n\n        const key = `${pkg.type}_${Date.now()}_${Math.random()\n          .toString(36)\n          .substr(2, 5)}`;\n\n        // A line-property change (lineType, sourceLock/targetLock, lineColor…)\n        // supersedes any earlier change to the SAME property on the SAME\n        // association. The collab doc accumulates and is replayed on reload, and\n        // the replay order is not guaranteed to be recency order — so leaving the\n        // old package in means e.g. toggling Absolute→Relative can be re-applied\n        // as Absolute and the toggle \"reverts\". Prune the superseded ones first.\n        if (pkg.type === \"onLinePropertiesChanged\") {\n          this.pruneSupersededLineProperty(pkg.data);\n        }\n\n        this.collabMap.set(key, {\n          ...pkg,\n          clientID: this.clientID,\n          timestamp: Date.now(),\n        });\n\n        // The collab doc accumulates every package and is replayed on reload/\n        // sync. Without this, a deleted node's earlier onNodeAdded would be\n        // re-applied on reload and the node would come back. When a node is\n        // deleted, prune its add/change packages so the replay can't recreate it.\n        if (pkg.type === \"onNodeDeleted\") {\n          const deletedId = (pkg.data as any)?.id;\n          if (deletedId != null) this.pruneNodePackages(deletedId);\n        }\n      }\n    } else {\n      // Normal pre-init / no-server path: still surface to the host below\n      console.log(\n        \"COLLAB_DEBUG: send() before collab init — emitting locally only\"\n      );\n    }\n\n    for (const pkg of pkgs) {\n      (this.slate as any).emitSlateChange?.(pkg.type, pkg.data);\n    }\n  }\n\n  /**\n   * Remove a node's accumulated packages (onNodeAdded + onNodeXXXChanged) from\n   * the shared collab doc so a reload/sync replay can't recreate a deleted node.\n   * Keeps onNodeDeleted tombstones (harmless no-ops on replay). Node packages\n   * carry data.id; move/batch packages use array data and are left alone.\n   */\n  private pruneNodePackages(nodeId: string): void {\n    if (!this.collabMap) return;\n    try {\n      const toDelete: string[] = [];\n      this.collabMap.forEach((val: any, key: string) => {\n        const d: any = val?.data;\n        const id = d && !Array.isArray(d) ? d.id : undefined;\n        if (id === nodeId && val?.type !== \"onNodeDeleted\") {\n          toDelete.push(key);\n        }\n      });\n      for (const key of toDelete) this.collabMap.delete(key);\n    } catch (e) {\n      /* noop */\n    }\n  }\n\n  /** Remove the mutation replay log before installing a full-state baseline. */\n  private pruneBeforeSlateReplacement(): void {\n    if (!this.collabMap) return;\n    try {\n      const keys: string[] = [];\n      this.collabMap.forEach((_val: any, key: string) => keys.push(key));\n      for (const key of keys) this.collabMap.delete(key);\n    } catch (e) {\n      /* noop */\n    }\n  }\n\n  /**\n   * Remove earlier onLinePropertiesChanged packages that target the SAME\n   * property on the SAME association, so a reload/sync replay applies only the\n   * latest value. Matches on (node id, associationId, prop). Guards the \"the\n   * Absolute/Relative (and Bezier/Orthogonal) toggle reverts after reload\" bug:\n   * the doc kept both the old and new value and replay order — not recency —\n   * decided the winner.\n   */\n  private pruneSupersededLineProperty(data: any): void {\n    if (!this.collabMap || !data || Array.isArray(data)) return;\n    const { id, associationId, prop } = data as any;\n    if (prop == null) return;\n    try {\n      const toDelete: string[] = [];\n      this.collabMap.forEach((val: any, key: string) => {\n        if (val?.type !== \"onLinePropertiesChanged\") return;\n        const d: any = val?.data;\n        if (!d || Array.isArray(d)) return;\n        if (d.id === id && d.associationId === associationId && d.prop === prop) {\n          toDelete.push(key);\n        }\n      });\n      for (const key of toDelete) this.collabMap.delete(key);\n    } catch (e) {\n      /* noop */\n    }\n  }\n\n  /**\n   * Execute a single collab package using the Invoker.\n   */\n  public exe(pkg: SlatePackage): void {\n    const invoker = this.slate.invoker;\n    if (!invoker) {\n      console.warn(\"COLLAB_DEBUG: No invoker available\");\n      return;\n    }\n\n    const methodName = pkg.type;\n\n    if (typeof (invoker as any)[methodName] === \"function\") {\n      // Applying a remote package must not re-emit onSlateChanged (echo)\n      this.slate.beginRemoteApply?.();\n      try {\n        const result = (invoker as any)[methodName](pkg);\n        result?.catch?.((error: unknown) =>\n          console.warn(\"COLLAB_DEBUG: Async invoker failed:\", methodName, error)\n        );\n      } finally {\n        this.slate.endRemoteApply?.();\n      }\n    } else {\n      console.warn(\"COLLAB_DEBUG: Unknown collab type:\", methodName);\n    }\n\n    // Trigger collab event\n    this.slate.options.events?.onCollaboration?.(pkg);\n  }\n\n  /**\n   * Update local cursor position and broadcast to peers.\n   */\n  /**\n   * Merge additional data into this client's awareness \"user\" state\n   * (v1 parity: `collab.updateUserData(data)`), e.g. custom status the\n   * host app broadcasts to other collaborators.\n   */\n  public updateUserData(data: Record<string, any>): void {\n    if (!this.awareness) return;\n    const current = this.awareness.getLocalState()?.user || {};\n    this.awareness.setLocalStateField(\"user\", { ...current, ...data });\n  }\n\n  public updateCursor(x: number, y: number): void {\n    if (!this.awareness) return;\n\n    this.awareness.setLocalStateField(\"cursor\", {\n      x,\n      y,\n      zoom: this.slate.getZoom?.() || 1,\n    });\n  }\n\n  /**\n   * Track this client's pointer over the canvas and broadcast its WORLD\n   * position (via the SVG CTM, so it's pan/zoom-independent) to peers. Remote\n   * clients render it through renderCursor(). Throttled to ~25fps.\n   */\n  private setupCursorTracking(): void {\n    const node = this.slate.canvas?.node;\n    if (!node || typeof node.addEventListener !== \"function\") return;\n    if (this._cursorMoveHandler) return; // already tracking\n    let last = 0;\n    this._cursorMoveHandler = (e: any) => {\n      const now =\n        typeof performance !== \"undefined\" ? performance.now() : +new Date();\n      if (now - last < 40) return;\n      last = now;\n      try {\n        // canvas.point() maps client coords → SVG user (world) coords\n        const p = this.slate.canvas.point(e.clientX, e.clientY);\n        this.updateCursor(p.x, p.y);\n      } catch (_) {\n        /* noop */\n      }\n    };\n    node.addEventListener(\"pointermove\", this._cursorMoveHandler);\n    this._cursorTrackingNode = node;\n  }\n\n  /**\n   * Render (or update) remote collaborators' cursors and remove cursors for\n   * clients that have left. Called on every awareness change.\n   */\n  private renderRemoteCursors(users: CollabUser[]): void {\n    if (!this.slate.canvas) return;\n    const present = new Set(users.map((u) => u.clientID));\n    for (const [id, el] of this.cursorElements) {\n      if (!present.has(id)) {\n        try {\n          el.remove();\n        } catch (_) {\n          /* noop */\n        }\n        this.cursorElements.delete(id);\n      }\n    }\n    for (const u of users) {\n      if (u.cursor) this.renderCursor(u);\n    }\n  }\n\n  /**\n   * Render a remote cursor on the canvas, reusing its group across updates so\n   * frequent cursor moves don't thrash the DOM.\n   */\n  public renderCursor(user: CollabUser): void {\n    if (!user.cursor || !this.slate.canvas) return;\n\n    let g = this.cursorElements.get(user.clientID);\n    if (!g || !g.node || !g.node.parentNode) {\n      g = this.slate.canvas.group();\n\n      // Arrow pointer in the collaborator's color with a white outline.\n      g.polygon(\"0,0 0,17 4.5,13 7.5,19.5 10.5,18 7.5,11.5 13,11.5\")\n        .fill(user.color)\n        .stroke({ color: \"#fff\", width: 1.2 })\n        .attr(\"stroke-linejoin\", \"round\");\n\n      // Name label: white rounded-rect background with the name in the user's\n      // color on top (matches the pre-regression presence style).\n      const label = g.group();\n      const name = user.userName || \"Anonymous\";\n      const txt = label\n        .text(name)\n        .font({ size: 12, family: \"Roboto, Helvetica, Arial, sans-serif\" })\n        .fill(user.color);\n      let tw = 60;\n      let th = 16;\n      try {\n        const bb = txt.bbox();\n        if (bb && bb.width) {\n          tw = bb.width;\n          th = bb.height;\n        }\n      } catch (_) {\n        /* bbox unavailable — use fallback size */\n      }\n      const padX = 8;\n      const padY = 4;\n      const rect = label\n        .rect(tw + padX * 2, th + padY * 2)\n        .radius(6)\n        .fill(\"#fff\")\n        .stroke({ color: user.color, width: 1 });\n      rect.back(); // behind the text\n      txt.move(padX, padY);\n      // Offset the label from the pointer tip\n      label.transform({ translateX: 16, translateY: 6 });\n\n      g.attr(\"pointer-events\", \"none\");\n      this.cursorElements.set(user.clientID, g);\n    }\n    // Position in world space (the group lives in the canvas viewBox), so it\n    // lands at the right spot regardless of each viewer's pan/zoom.\n    g.transform({ translateX: user.cursor.x, translateY: user.cursor.y });\n  }\n\n  /**\n   * Get all connected collaboration users.\n   */\n  public getCollabUsers(): CollabUser[] {\n    if (!this.awareness) return [];\n\n    const users: CollabUser[] = [];\n    const states = this.awareness.getStates();\n\n    states.forEach((state: any, clientID: number) => {\n      if (clientID === this.clientID) return; // Skip self\n\n      users.push({\n        clientID,\n        userName: state.user?.name || \"Anonymous\",\n        color: state.user?.color || \"#999\",\n        cursor: state.cursor,\n      });\n    });\n\n    return users;\n  }\n\n  /**\n   * Disconnect from collaboration.\n   */\n  public disconnect(): void {\n    // Stop broadcasting local pointer + remove all rendered cursors\n    if (this._cursorMoveHandler && this._cursorTrackingNode) {\n      try {\n        this._cursorTrackingNode.removeEventListener(\n          \"pointermove\",\n          this._cursorMoveHandler\n        );\n      } catch (_) {\n        /* noop */\n      }\n    }\n    this._cursorMoveHandler = null;\n    this._cursorTrackingNode = null;\n    for (const [, element] of this.cursorElements) {\n      element.remove();\n    }\n    this.cursorElements.clear();\n\n    if (this.provider) {\n      this.provider.disconnect();\n      this.provider = null;\n    }\n    if (this.doc) {\n      this.doc.destroy();\n      this.doc = null;\n    }\n    this.collabMap = null;\n    this.awareness = null;\n    this.isConnected = false;\n    console.log(\"COLLAB_DEBUG: Disconnected\");\n  }\n\n  /** Check if collaboration is connected */\n  public isCollabConnected(): boolean {\n    return this.isConnected;\n  }\n\n  /** Destroy the collab instance, disconnecting and cleaning up all resources */\n  public destroy(): void {\n    this.disconnect();\n    (this as any).slate = null;\n    this.options = {} as CollabOptions;\n  }\n\n  /** Get client ID */\n  public getClientID(): number {\n    return this.clientID;\n  }\n\n  // ─── Private ─────────────────────────────────────────────────────\n\n  private handleRemotePackage(pkg: SlatePackage): void {\n    console.log(\"COLLAB_DEBUG: Received remote package:\", pkg.type);\n\n    // Execute the package locally\n    this.exe(pkg);\n\n    // Notify via callback\n    this.options.onReceive?.(pkg);\n  }\n}\n","/**\n * Theme.ts - Theme system for applying visual styles to slates\n *\n * A theme contains a parent style and up to N child styles.\n * When applied, nodes cycle through child styles based on their index.\n */\n\nexport interface ThemeStyle {\n  image?: string;\n  backgroundColor?: string;\n  nodeColor?: string;\n  opacity?: number;\n  borderOpacity?: number;\n  borderColor?: string;\n  borderStyle?:\n    | \"solid\"\n    | \"dashed\"\n    | \"dotted\"\n    | \"-\"\n    | \".\"\n    | \"--.\"\n    | \"combo\";\n  borderWidth?: number;\n  fontColor?: string;\n  foregroundColor?: string;\n  fontFamily?: string;\n  fontSize?: number;\n  fontStyle?: string;\n  textOpacity?: number;\n  lineColor?: string;\n  lineOpacity?: number;\n  lineEffect?: string;\n  lineWidth?: number;\n  filters?: {\n    vect?: string | null;\n    text?: string | null;\n    line?: string | null;\n  };\n  vectorPath?: string;\n  shape?: string;\n}\n\nexport interface ThemeDefinition {\n  _id?: string;\n  name?: string;\n  description?: string;\n  containerStyle?: {\n    backgroundColor?: string;\n  };\n  defaultLineColor?: string;\n  styles?: {\n    parent?: ThemeStyle;\n    [key: string]: ThemeStyle | undefined; // child_1, child_2, etc.\n  };\n}\n\n/**\n * Apply a theme to a slate. Updates node styles based on theme definitions.\n *\n * @param slate - The Slate instance\n * @param theme - Theme definition\n * @param syncWithTheme - If true, persist theme sync setting\n * @param revertTheme - If true, revert to pre-theme styles (not implemented yet)\n */\nexport function applyTheme(\n  slate: any,\n  theme: ThemeDefinition,\n  syncWithTheme: boolean = false,\n  revertTheme: boolean = false\n): void {\n  if (!theme) return;\n\n  // Update slate options\n  if (theme._id) {\n    slate.options.themeId = theme._id;\n  }\n  if (syncWithTheme) {\n    slate.options.syncWithTheme = true;\n  }\n\n  // Apply container style\n  if (theme.containerStyle?.backgroundColor) {\n    slate.options.containerStyle = slate.options.containerStyle || {};\n    slate.options.containerStyle.backgroundColor =\n      theme.containerStyle.backgroundColor;\n    // Paint it onto the container (setting the option alone is a no-op).\n    slate.applyContainerStyle?.();\n  }\n\n  // Apply default line color (for future connections) AND re-color EXISTING\n  // connections — a theme restyles the WHOLE slate (it recolors nodes below), so\n  // existing lines shouldn't stay their old color while everything else changes.\n  if (theme.defaultLineColor) {\n    slate.options.defaultLineColor = theme.defaultLineColor;\n    slate.nodes?.allNodes?.forEach((node: any) => {\n      node.relationships?.updateAssociationsWith?.({\n        lineColor: theme.defaultLineColor,\n      });\n    });\n  }\n\n  // Apply styles to nodes. In mindMapMode over a connected tree, color by\n  // HIERARCHY — root(s) get the parent style, each level down cycles child_1,\n  // child_2, … — so the theme follows the mind-map's structure (v1/Miro parity).\n  // For a flat slate (no associations) fall back to insertion-order cycling so\n  // every node still gets a distinct style (and existing behavior is unchanged).\n  const nodes = slate.nodes.allNodes;\n  if (!nodes || nodes.length === 0 || !theme.styles) return;\n\n  const depthByNodeId = computeHierarchyDepths(slate, nodes);\n\n  nodes.forEach((node: any, index: number) => {\n    const childNumber = depthByNodeId\n      ? depthByNodeId.get(node.options.id) ?? 0\n      : index;\n    const style = buildNodeStyleFromTheme(theme, childNumber);\n    if (style) {\n      applyStyleToNode(node, style);\n    }\n  });\n\n  console.log(\"THEME_DEBUG: Applied theme\", theme.name || theme._id);\n}\n\n/**\n * Depth of each node in the association tree, for mindMapMode theme coloring.\n * Returns null (→ caller uses insertion-order index) when mindMapMode is off or\n * the slate has no associations at all (a flat slate), so unconnected nodes keep\n * distinct cycling styles and non-mind-map slates are unaffected.\n */\nfunction computeHierarchyDepths(\n  slate: any,\n  nodes: any[]\n): Map<string, number> | null {\n  if (!slate?.options?.mindMapMode) return null;\n\n  const childIds = new Set<string>();\n  const childrenOf = new Map<string, string[]>();\n  let hasEdges = false;\n  for (const n of nodes) {\n    const assocMap = n.relationships?.assocMap;\n    const kids: string[] = assocMap\n      ? Array.from(assocMap.values())\n          .map((a: any) => a.childId || a.child?.id)\n          .filter(Boolean)\n      : [];\n    if (kids.length) hasEdges = true;\n    childrenOf.set(n.options.id, kids);\n    kids.forEach((k) => childIds.add(k));\n  }\n  if (!hasEdges) return null;\n\n  // Roots = nodes that are nobody's child. BFS assigns depth (root = 0 = parent).\n  const depth = new Map<string, number>();\n  const queue: Array<[string, number]> = [];\n  for (const n of nodes) {\n    if (!childIds.has(n.options.id)) queue.push([n.options.id, 0]);\n  }\n  while (queue.length) {\n    const [id, d] = queue.shift()!;\n    if (depth.has(id)) continue;\n    depth.set(id, d);\n    for (const k of childrenOf.get(id) || []) queue.push([k, d + 1]);\n  }\n  // Cycle/orphan safety: anything unreached gets parent style.\n  for (const n of nodes) {\n    if (!depth.has(n.options.id)) depth.set(n.options.id, 0);\n  }\n  return depth;\n}\n\n/**\n * Build node style from theme based on child number.\n * The first node uses parent style, subsequent nodes cycle through child_1, child_2, etc.\n */\nexport function buildNodeStyleFromTheme(\n  theme: ThemeDefinition,\n  childNumber: number\n): ThemeStyle | null {\n  if (!theme.styles) return null;\n\n  // First node gets parent style\n  if (childNumber === 0 && theme.styles.parent) {\n    return theme.styles.parent;\n  }\n\n  // Subsequent nodes cycle through child styles\n  const childKeys = Object.keys(theme.styles).filter((k) =>\n    k.startsWith(\"child_\")\n  );\n\n  if (childKeys.length === 0) {\n    return theme.styles.parent || null;\n  }\n\n  const childIndex = (childNumber - 1) % childKeys.length;\n  const key = `child_${childIndex + 1}`;\n  return theme.styles[key] || theme.styles.parent || null;\n}\n\nfunction applyStyleToNode(node: any, style: ThemeStyle): void {\n  // The app's saved theme styles use v1 field names (nodeColor for fill,\n  // foregroundColor for text). Accept both so DB themes apply correctly.\n  const s = style as any;\n  const backgroundColor = style.backgroundColor ?? s.nodeColor;\n  const fontColor = style.fontColor ?? s.foregroundColor;\n\n  // A saved app theme is a complete visual style, not just a color palette.\n  // Copy every explicitly-present scalar before repainting so createBackground,\n  // setShape, and the apply* helpers all read one coherent option set.\n  const optionKeys = [\n    \"opacity\",\n    \"borderOpacity\",\n    \"borderColor\",\n    \"borderStyle\",\n    \"borderWidth\",\n    \"fontFamily\",\n    \"fontSize\",\n    \"fontStyle\",\n    \"textOpacity\",\n    \"lineColor\",\n    \"lineOpacity\",\n    \"lineEffect\",\n    \"lineWidth\",\n  ] as const;\n  for (const key of optionKeys) {\n    if (Object.prototype.hasOwnProperty.call(style, key)) {\n      node.options[key] = (style as any)[key];\n    }\n  }\n\n  if (backgroundColor) {\n    node.options.backgroundColor = backgroundColor;\n  }\n  if (fontColor) {\n    node.options.fontColor = fontColor;\n  }\n\n  const changesShape = !!(style.vectorPath || style.shape);\n  if (changesShape) {\n    // Filters and image patterns point at the old shape element. Tear them down\n    // before replacing it, then restore the theme's own image/effects below.\n    node.filters?.removeAll?.();\n    node.images?.clear?.();\n    const shape = style.shape || style.vectorPath!;\n    node.setShape?.(shape, style.vectorPath);\n  }\n\n  // Apply all paintable node properties to the (possibly new) shape.\n  node.setColors?.(backgroundColor, style.borderColor);\n  node.applyBorder?.();\n  node.applyOpacity?.();\n\n  if (\n    fontColor ||\n    style.fontSize !== undefined ||\n    style.fontFamily ||\n    style.textOpacity !== undefined ||\n    style.fontStyle\n  ) {\n    node.applyTextStyle?.();\n  }\n\n  if (Object.prototype.hasOwnProperty.call(style, \"image\")) {\n    if (style.image) node.images?.set?.(style.image);\n    else node.images?.clear?.();\n  }\n\n  if (style.filters) {\n    node.filters?.removeAll?.();\n    node.options.filters = {};\n    if (style.filters.vect) node.filters?.apply?.(style.filters.vect, \"vect\");\n    if (style.filters.text) node.filters?.apply?.(style.filters.text, \"text\");\n  }\n\n  // Existing connections inherit the themed parent node's line style. New\n  // connections already read these values from node.options.\n  const lineStyle: Record<string, any> = {};\n  for (const key of [\n    \"lineColor\",\n    \"lineOpacity\",\n    \"lineEffect\",\n    \"lineWidth\",\n  ] as const) {\n    if (Object.prototype.hasOwnProperty.call(style, key)) {\n      lineStyle[key] = style[key];\n    }\n  }\n  if (Object.keys(lineStyle).length) {\n    node.relationships?.updateAssociationsWith?.(lineStyle);\n  }\n}\n","/**\n * Layout.ts - Layout algorithms for node positioning\n *\n * Provides overlap removal and auto-layout capabilities.\n */\n\nexport interface LayoutMove {\n  id: string;\n  x: number;\n  y: number;\n}\n\n/**\n * Remove overlapping nodes by pushing them apart.\n *\n * @param slate - The Slate instance\n * @param enableAttraction - If true, nodes are slightly attracted to center\n * @param threshold - Minimum distance between nodes\n */\nexport function removeLayoutOverlaps(\n  slate: any,\n  enableAttraction: boolean = false,\n  threshold: number = 20\n): void {\n  const nodes = slate.nodes.allNodes;\n  if (nodes.length < 2) return;\n\n  const maxIterations = 100;\n  let hasOverlap = true;\n  let iteration = 0;\n\n  while (hasOverlap && iteration < maxIterations) {\n    hasOverlap = false;\n    iteration++;\n\n    for (let i = 0; i < nodes.length; i++) {\n      for (let j = i + 1; j < nodes.length; j++) {\n        const a = nodes[i];\n        const b = nodes[j];\n\n        const ax = a.options.x || 0;\n        const ay = a.options.y || 0;\n        const aw = a.options.width || 100;\n        const ah = a.options.height || 60;\n\n        const bx = b.options.x || 0;\n        const by = b.options.y || 0;\n        const bw = b.options.width || 100;\n        const bh = b.options.height || 60;\n\n        // Check overlap\n        const overlapX = ax < bx + bw + threshold && ax + aw + threshold > bx;\n        const overlapY = ay < by + bh + threshold && ay + ah + threshold > by;\n\n        if (overlapX && overlapY) {\n          hasOverlap = true;\n\n          // Push nodes apart\n          const dx = (ax + aw / 2) - (bx + bw / 2);\n          const dy = (ay + ah / 2) - (by + bh / 2);\n          const dist = Math.sqrt(dx * dx + dy * dy) || 1;\n\n          const pushX = (dx / dist) * (threshold / 2);\n          const pushY = (dy / dist) * (threshold / 2);\n\n          a.position(ax + pushX, ay + pushY);\n          b.position(bx - pushX, by - pushY);\n        }\n      }\n    }\n  }\n\n  if (enableAttraction) {\n    // Gently attract nodes toward center of mass\n    const cx = nodes.reduce((sum: number, n: any) => sum + (n.options.x || 0), 0) / nodes.length;\n    const cy = nodes.reduce((sum: number, n: any) => sum + (n.options.y || 0), 0) / nodes.length;\n\n    for (const node of nodes) {\n      const nx = node.options.x || 0;\n      const ny = node.options.y || 0;\n      const dx = cx - nx;\n      const dy = cy - ny;\n      node.position(nx + dx * 0.05, ny + dy * 0.05);\n    }\n  }\n\n  console.log(\n    \"LAYOUT_DEBUG: Overlap removal completed in\",\n    iteration,\n    \"iterations\"\n  );\n}\n\n/**\n * Apply a set of pre-computed layout moves to nodes.\n *\n * @param slate - The Slate instance\n * @param moves - Array of { id, x, y } moves\n * @param callback - Called when animation completes\n * @param noAnimation - If true, move instantly\n */\nexport function applyLayout(\n  slate: any,\n  moves: LayoutMove[],\n  callback?: () => void,\n  noAnimation: boolean = false\n): void {\n  const duration = noAnimation ? 0 : 500;\n  let completed = 0;\n\n  for (const move of moves) {\n    const node = slate.nodes.one(move.id);\n    if (node) {\n      node.position(move.x, move.y, () => {\n        completed++;\n        if (completed >= moves.length && callback) {\n          callback();\n        }\n      }, undefined, duration);\n    } else {\n      completed++;\n    }\n  }\n\n  if (moves.length === 0 && callback) {\n    callback();\n  }\n}\n\n/**\n * Package the current layout positions for all nodes.\n * Can be transmitted via collab and applied elsewhere.\n */\nexport function packageLayout(slate: any): LayoutMove[] {\n  return slate.nodes.allNodes.map((node: any) => ({\n    id: node.id,\n    x: node.options.x || 0,\n    y: node.options.y || 0,\n  }));\n}\n","/**\n * ZoomSlider.ts - Visual zoom slider control\n *\n * Creates a zoom slider UI element that integrates with PanZoom.\n */\n\nexport interface ZoomSliderOptions {\n  enabled?: boolean;\n  position?: \"bottom-right\" | \"bottom-left\" | \"top-right\" | \"top-left\";\n  minZoom?: number;\n  maxZoom?: number;\n}\n\nexport class ZoomSlider {\n  private slate: any;\n  private options: ZoomSliderOptions;\n  private container: HTMLElement | null = null;\n  private slider: HTMLInputElement | null = null;\n  private label: HTMLElement | null = null;\n  private _intervalId: ReturnType<typeof setInterval> | null = null;\n\n  constructor(slate: any, options: ZoomSliderOptions = {}) {\n    this.slate = slate;\n    this.options = {\n      enabled: false,\n      position: \"bottom-right\",\n      minZoom: 0.1,\n      maxZoom: 10,\n      ...options,\n    };\n\n    if (this.options.enabled) {\n      this.create();\n    }\n  }\n\n  /** Show the zoom slider */\n  public show(): void {\n    if (!this.container) {\n      this.create();\n    }\n    if (this.container) {\n      this.container.style.display = \"flex\";\n    }\n  }\n\n  /** Hide the zoom slider */\n  public hide(): void {\n    if (this.container) {\n      this.container.style.display = \"none\";\n    }\n  }\n\n  /** Destroy the zoom slider */\n  public destroy(): void {\n    // Clear the refresh interval\n    if (this._intervalId !== null) {\n      clearInterval(this._intervalId);\n      this._intervalId = null;\n    }\n    if (this.container) {\n      this.container.remove();\n      this.container = null;\n      this.slider = null;\n      this.label = null;\n    }\n  }\n\n  /** Update the slider to reflect current zoom level */\n  public update(): void {\n    if (!this.slider || !this.label) return;\n    const zoom = this.slate.getZoom?.() || 1;\n    this.slider.value = String(zoom);\n    this.label.textContent = `${Math.round(zoom * 100)}%`;\n  }\n\n  // ─── Private ─────────────────────────────────────────────────────\n\n  private create(): void {\n    if (!this.slate.element) return;\n\n    // Ensure parent has relative positioning\n    this.slate.element.style.position =\n      this.slate.element.style.position || \"relative\";\n\n    this.container = document.createElement(\"div\");\n    this.container.className = \"slatebox-zoom-slider\";\n\n    // Position based on option\n    const positionStyles: Record<string, string> = {\n      \"bottom-right\": \"bottom: 10px; right: 10px;\",\n      \"bottom-left\": \"bottom: 10px; left: 10px;\",\n      \"top-right\": \"top: 10px; right: 10px;\",\n      \"top-left\": \"top: 10px; left: 10px;\",\n    };\n\n    this.container.style.cssText = `\n      position: absolute;\n      ${positionStyles[this.options.position!]}\n      display: flex;\n      align-items: center;\n      gap: 8px;\n      background: rgba(0, 0, 0, 0.7);\n      color: white;\n      padding: 6px 12px;\n      border-radius: 4px;\n      z-index: 1000;\n      font-family: sans-serif;\n      font-size: 12px;\n    `;\n\n    // Zoom out button\n    const zoomOut = document.createElement(\"button\");\n    zoomOut.textContent = \"-\";\n    zoomOut.style.cssText =\n      \"background:none;border:none;color:white;cursor:pointer;font-size:16px;padding:0 4px;\";\n    zoomOut.onclick = () => this.slate.zoomOut?.();\n    this.container.appendChild(zoomOut);\n\n    // Slider\n    this.slider = document.createElement(\"input\");\n    this.slider.type = \"range\";\n    this.slider.min = String(this.options.minZoom);\n    this.slider.max = String(this.options.maxZoom);\n    this.slider.step = \"0.1\";\n    this.slider.value = \"1\";\n    this.slider.style.cssText = \"width: 100px; cursor: pointer;\";\n    this.slider.oninput = () => {\n      const val = parseFloat(this.slider!.value);\n      this.slate.zoom?.(val);\n      this.update();\n    };\n    this.container.appendChild(this.slider);\n\n    // Zoom in button\n    const zoomIn = document.createElement(\"button\");\n    zoomIn.textContent = \"+\";\n    zoomIn.style.cssText =\n      \"background:none;border:none;color:white;cursor:pointer;font-size:16px;padding:0 4px;\";\n    zoomIn.onclick = () => this.slate.zoomIn?.();\n    this.container.appendChild(zoomIn);\n\n    // Label\n    this.label = document.createElement(\"span\");\n    this.label.textContent = \"100%\";\n    this.label.style.cssText = \"min-width: 40px; text-align: right;\";\n    this.container.appendChild(this.label);\n\n    // Fit-to-content button (Miro \"zoom to fit\"): pans + zooms so every node is\n    // in view. Uses the ⤢ glyph; calls slate.fitToContent(). Inserted as the\n    // LEFTMOST control so it isn't overlapped by the bottom-right add-node FAB\n    // (which sits over the slider's right edge and would eat the click).\n    const fit = document.createElement(\"button\");\n    fit.textContent = \"⤢\";\n    fit.title = \"Fit to content\";\n    fit.setAttribute(\"aria-label\", \"fitToContent\");\n    fit.style.cssText =\n      \"background:none;border:none;color:white;cursor:pointer;font-size:15px;padding:0 4px;line-height:1;\";\n    fit.onclick = () => this.slate.fitToContent?.();\n    this.container.insertBefore(fit, this.container.firstChild);\n\n    this.slate.element.appendChild(this.container);\n\n    // Update periodically\n    this._intervalId = setInterval(() => this.update(), 500);\n  }\n}\n","/**\n * Presentation.ts - Step-through presentation mode\n *\n * Allows stepping through nodes in order, zooming/panning to each.\n */\n\nexport interface PresentationStep {\n  nodeId: string;\n  index: number;\n}\n\nexport class Presentation {\n  private slate: any;\n  private steps: PresentationStep[] = [];\n  private currentStep: number = -1;\n  private isActive: boolean = false;\n  /** Zoom level applied when focusing a step's node. */\n  public zoomLevel: number = 1.5;\n\n  constructor(slate: any) {\n    this.slate = slate;\n  }\n\n  /**\n   * Extract presentation layout from current nodes.\n   * Orders nodes by their _presentationIndex or by position (top-to-bottom, left-to-right).\n   */\n  public extractLayout(opts?: {\n    nodeIds?: string[];\n  }): PresentationStep[] {\n    let nodes = this.slate.nodes.allNodes;\n\n    // Filter to specific nodes if provided\n    if (opts?.nodeIds) {\n      const ids = new Set(opts.nodeIds);\n      nodes = nodes.filter((n: any) => ids.has(n.id));\n    }\n\n    // Sort by presentation index if available, otherwise by position\n    nodes.sort((a: any, b: any) => {\n      const ai = a.options._presentationIndex;\n      const bi = b.options._presentationIndex;\n      if (ai !== undefined && bi !== undefined) return ai - bi;\n\n      // Sort by Y then X (top-to-bottom, left-to-right)\n      const dy = (a.options.y || 0) - (b.options.y || 0);\n      if (Math.abs(dy) > 30) return dy;\n      return (a.options.x || 0) - (b.options.x || 0);\n    });\n\n    this.steps = nodes.map((node: any, index: number) => ({\n      nodeId: node.id,\n      index,\n    }));\n\n    return this.steps;\n  }\n\n  /**\n   * Build the hierarchical presentation layout (preziData) — a tree of root\n   * nodes → children with per-node metrics + descriptions. This is the structure\n   * the AI consumes to decide the presentation ORDER (ported from v1\n   * slate.extractPresentationLayout). Bbox is relative to the content top-left.\n   */\n  public extractPresentationLayout(): any {\n    const all: any[] = this.slate.nodes?.allNodes || [];\n    const nodes = all.filter((n) => !n.options?.isCategory);\n\n    // Content bounds (orientation) for relative bbox coordinates.\n    let minX = Infinity;\n    let minY = Infinity;\n    let maxX = -Infinity;\n    let maxY = -Infinity;\n    nodes.forEach((n) => {\n      const o = n.options || {};\n      minX = Math.min(minX, o.x || 0);\n      minY = Math.min(minY, o.y || 0);\n      maxX = Math.max(maxX, (o.x || 0) + (o.width || 0));\n      maxY = Math.max(maxY, (o.y || 0) + (o.height || 0));\n    });\n    if (!isFinite(minX)) {\n      minX = 0;\n      minY = 0;\n      maxX = 0;\n      maxY = 0;\n    }\n    const orient = { left: minX, top: minY, width: maxX - minX, height: maxY - minY };\n\n    const byId = new Map<string, any>(nodes.map((n) => [n.id, n]));\n    const childIdsOf = (node: any): string[] =>\n      (node.relationships?.associations || [])\n        .map((a: any) => a.childId)\n        .filter((id: string) => byId.has(id));\n    const isChildOfAny = (node: any): boolean =>\n      nodes.some((p) =>\n        (p.relationships?.associations || []).some((a: any) => a.childId === node.id)\n      );\n\n    const processed = new Set<string>();\n    const processNode = (node: any): any => {\n      if (processed.has(node.id)) return null;\n      processed.add(node.id);\n      const o = node.options || {};\n      const children = childIdsOf(node)\n        .map((id) => byId.get(id))\n        .filter(Boolean);\n      return {\n        nodeId: node.id,\n        metrics: {\n          rotation: Math.ceil(o.rotate?.rotationAngle || 0),\n          bbox: {\n            x: Number(((o.x || 0) - orient.left).toFixed(2)),\n            y: Number(((o.y || 0) - orient.top).toFixed(2)),\n            width: Number((o.width || 0).toFixed(2)),\n            height: Number((o.height || 0).toFixed(2)),\n          },\n        },\n        description: o.text || o.description || \"\",\n        image: o.image,\n        numberOfChildrenNodes: children.length,\n        childrenNodes: children.map(processNode).filter(Boolean),\n      };\n    };\n\n    const rootNodes = nodes.filter((n) => !isChildOfAny(n));\n    return {\n      presentationHeight: Math.ceil(orient.height),\n      presentationWidth: Math.ceil(orient.width),\n      nodes: rootNodes.map(processNode).filter(Boolean),\n    };\n  }\n\n  /**\n   * Set the step order explicitly (e.g. from the AI's returned ordering). IDs\n   * that don't exist are skipped; any nodes the AI omitted are appended in the\n   * default layout order so nothing is lost.\n   */\n  public setStepOrder(nodeIds: string[]): PresentationStep[] {\n    const all: any[] = this.slate.nodes?.allNodes || [];\n    const exists = new Set(all.map((n) => n.id));\n    const seen = new Set<string>();\n    const ordered: string[] = [];\n    (nodeIds || []).forEach((id) => {\n      if (exists.has(id) && !seen.has(id)) {\n        seen.add(id);\n        ordered.push(id);\n      }\n    });\n    // Append any missing nodes in default order.\n    this.extractLayout().forEach((s) => {\n      if (!seen.has(s.nodeId)) {\n        seen.add(s.nodeId);\n        ordered.push(s.nodeId);\n      }\n    });\n    this.steps = ordered.map((nodeId, index) => ({ nodeId, index }));\n    this.currentStep = -1;\n    return this.steps;\n  }\n\n  /** Start presentation mode */\n  public start(): void {\n    if (this.steps.length === 0) {\n      this.extractLayout();\n    }\n    this.isActive = true;\n    this.currentStep = -1;\n    this.next();\n  }\n\n  /** Stop presentation mode */\n  public stop(): void {\n    this.isActive = false;\n    this.currentStep = -1;\n  }\n\n  /** Go to next step */\n  public next(): boolean {\n    if (this.currentStep >= this.steps.length - 1) return false;\n    this.currentStep++;\n    this.goToStep(this.currentStep);\n    return true;\n  }\n\n  /** Go to previous step */\n  public previous(): boolean {\n    if (this.currentStep <= 0) return false;\n    this.currentStep--;\n    this.goToStep(this.currentStep);\n    return true;\n  }\n\n  /**\n   * Go to a specific step, smoothly panning+zooming the viewport so the step's\n   * node is centered (P3). Pass duration 0 for an instant jump.\n   */\n  public goToStep(index: number, duration: number = 450): void {\n    if (index < 0 || index >= this.steps.length) return;\n\n    this.currentStep = index;\n    const step = this.steps[index];\n    const node: any = this.slate.nodes.one(step.nodeId);\n    if (!node) return;\n\n    // Center on the node's WORLD center. The target viewbox has the node's\n    // center in the middle; its dimensions come from the target zoom: at zoom Z\n    // the viewbox is (containerPx / Z), i.e. current viewbox scaled by\n    // (currentZoom / Z). We then tween the viewbox from current → target.\n    try {\n      const o = node.options || {};\n      const nx = (o.x || 0) + (o.width || 0) / 2;\n      const ny = (o.y || 0) + (o.height || 0) / 2;\n\n      const canvas = (this.slate as any).canvas;\n      const vb = canvas.viewbox();\n      const zc = (this.slate as any).panZoom?.getZoom?.() ?? 1;\n      const tw = (vb.width * zc) / this.zoomLevel;\n      const th = (vb.height * zc) / this.zoomLevel;\n      const target = { x: nx - tw / 2, y: ny - th / 2, width: tw, height: th };\n      this.animateViewbox(\n        { x: vb.x, y: vb.y, width: vb.width, height: vb.height },\n        target,\n        duration\n      );\n    } catch {\n      // Best-effort pan/zoom\n    }\n    // Note: intentionally do NOT select the node — presentation is a clean,\n    // read-only view (no edit toolbar / handles / connection anchors).\n  }\n\n  private _animRaf: number | null = null;\n\n  /** Tween the canvas viewbox from → to over `duration` ms (easeInOutQuad). */\n  private animateViewbox(\n    from: { x: number; y: number; width: number; height: number },\n    to: { x: number; y: number; width: number; height: number },\n    duration: number\n  ): void {\n    const canvas = (this.slate as any).canvas;\n    const set = (x: number, y: number, w: number, h: number) => {\n      try {\n        canvas.viewbox(x, y, w, h);\n      } catch {\n        /* noop */\n      }\n    };\n    if (this._animRaf != null) {\n      try {\n        cancelAnimationFrame(this._animRaf);\n      } catch {\n        /* noop */\n      }\n      this._animRaf = null;\n    }\n    if (!duration || duration <= 0 || typeof requestAnimationFrame === \"undefined\") {\n      set(to.x, to.y, to.width, to.height);\n      return;\n    }\n    const ease = (t: number) =>\n      t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;\n    let startTs: number | null = null;\n    const tick = (now: number) => {\n      if (startTs === null) startTs = now;\n      const p = Math.min(1, (now - startTs) / duration);\n      const e = ease(p);\n      set(\n        from.x + (to.x - from.x) * e,\n        from.y + (to.y - from.y) * e,\n        from.width + (to.width - from.width) * e,\n        from.height + (to.height - from.height) * e\n      );\n      if (p < 1) this._animRaf = requestAnimationFrame(tick);\n      else this._animRaf = null;\n    };\n    this._animRaf = requestAnimationFrame(tick);\n  }\n\n  /** Get current step index */\n  public getCurrentStep(): number {\n    return this.currentStep;\n  }\n\n  /** Get total steps */\n  public getTotalSteps(): number {\n    return this.steps.length;\n  }\n\n  /** Check if presentation is active */\n  public isPresenting(): boolean {\n    return this.isActive;\n  }\n\n  /** Destroy the presentation, stopping if active */\n  public destroy(): void {\n    this.stop();\n    this.steps = [];\n    this.currentStep = -1;\n    (this as any).slate = null;\n  }\n}\n","import { SVG, Svg } from \"@svgdotjs/svg.js\";\nimport { Node, NodeOptions } from \"./Node\";\nimport { NodesManager } from \"./NodesManager\";\nimport { Invoker } from \"./Invoker\";\nimport { PanZoom, PanZoomOptions } from \"./PanZoom\";\nimport { BirdsEye, BirdsEyeOptions } from \"./BirdsEye\";\nimport {\n  serialize,\n  deserialize,\n  snapshot as takeSnapshot,\n  type SlateJSON,\n} from \"./Serialization\";\nimport { UndoRedo } from \"./UndoRedo\";\nimport { MultiSelection } from \"./MultiSelection\";\nimport { Grid } from \"./Grid\";\nimport { Keyboard } from \"./Keyboard\";\nimport { ContextMenu } from \"./ContextMenu\";\nimport { exportSVG, exportPNG, type ExportOptions } from \"./Export\";\nimport { Collab, CollabUser } from \"./Collab\";\nimport type { SlatePackage } from \"./SlatePackage\";\nimport { v2NodeToV1 } from \"./compat\";\nimport { guid } from \"../utils\";\nimport { applyTheme, type ThemeDefinition } from \"./Theme\";\nimport {\n  removeLayoutOverlaps,\n  applyLayout as applyLayoutMoves,\n  packageLayout,\n  type LayoutMove,\n} from \"./Layout\";\nimport { Association } from \"./Relationship\";\nimport { ZoomSlider } from \"./ZoomSlider\";\nimport { Presentation } from \"./Presentation\";\nimport { getAvailableFilters } from \"./Filters\";\nimport { getAvailableAnimations, type AnimationDef } from \"./Animations\";\nimport { loadAllFonts as loadAllFontsForSlate } from \"./FontLoader\";\n\nexport interface SlateEvents {\n  onSlateChanged?: (pkg: SlatePackage, collabUsers?: CollabUser[]) => void;\n  /**\n   * Called before the collab websocket connects. May return (or resolve to)\n   * connection details: `{websocketUrl, websocketParams: {bearer, timestamp},\n   * userName, color, ...}` — websocketParams carries server auth.\n   */\n  onInitCollaboration?: (\n    clientID: string\n  ) => void | Record<string, any> | Promise<void | Record<string, any>>;\n  onTextPaneRequested?: (node: Node, cb: Function) => void;\n  onLineMenuRequested?: (node: Node, association: Association, cb: Function) => void;\n  onTakeSnapshot?: (opts?: Record<string, any>) => void;\n  onConfirmRequested?: (title: string, msg: string, cb: Function) => void;\n  onCollaborationUsersChanged?: (users: CollabUser[]) => void;\n  onCollaborationUsersRemoved?: (users: CollabUser[]) => void;\n  onCollaboration?: (pkg: SlatePackage) => void;\n  onNodeDragged?: (node: Node, evt: MouseEvent) => void;\n  onCanvasClicked?: (evt: MouseEvent) => void;\n  /** Fired when a multi-node selection forms (nodes) or ends ([]) */\n  onGroupSelection?: (selectedNodes: Node[]) => void;\n  onImagesRequested?: (opts: Record<string, any>) => void;\n  onRequestSave?: (opts?: Record<string, any>) => void;\n  onCreateImage?: (opts: Record<string, any>, cb: Function) => void;\n  onMenuRequested?: (node: Node, cb: Function) => void;\n  isReadOnly?: () => boolean;\n  isCommentOnly?: () => boolean;\n  canRemoveComments?: () => boolean;\n}\n\nexport interface SlateOptions {\n  // Identity\n  id?: string;\n  name?: string;\n  description?: string;\n  container?: string;\n  instance?: string;\n  shareId?: string;\n\n  // Behavior\n  enabled?: boolean;\n  allowDrag?: boolean;\n  followMe?: boolean;\n  mindMapMode?: boolean;\n  autoResizeNodesBasedOnText?: boolean;\n  useLayoutQuadrants?: boolean;\n  autoEnableDefaultFilters?: boolean;\n\n  // UI visibility\n  showbirdsEye?: boolean;\n  sizeOfbirdsEye?: number;\n  showMultiSelect?: boolean;\n  showZoom?: boolean;\n  showUndoRedo?: boolean;\n  showStatus?: boolean;\n  showLocks?: boolean;\n\n  // Access control\n  isPublic?: boolean;\n  isUnlisted?: boolean;\n  isPrivate?: boolean;\n  isTemplate?: boolean;\n  basedOnTemplate?: string;\n  basedOnThemeId?: string;\n  syncWithTheme?: boolean;\n\n  // Collaboration\n  allowCollaboration?: boolean;\n  eligibleForThemeCompilation?: boolean;\n\n  // Viewport\n  viewPort?: {\n    originalWidth?: number;\n    originalHeight?: number;\n    width?: number;\n    height?: number;\n    left?: number;\n    top?: number;\n    showGrid?: boolean;\n    gridSize?: number;\n    snapToObjects?: boolean;\n    snapToGrid?: boolean;\n    showCoordinates?: boolean;\n    useInertiaScrolling?: boolean;\n    zoom?: {\n      r?: number;\n      w?: number;\n      h?: number;\n    };\n  };\n\n  // Appearance\n  containerStyle?: {\n    backgroundColor?: string;\n    backgroundColorAsGradient?: boolean;\n    backgroundGradientType?: \"linear\" | \"radial\";\n    backgroundGradientColors?: string[];\n    backgroundGradientStrategy?: \"horizontal\" | \"vertical\" | \"diagonal\";\n    backgroundImage?: string;\n    backgroundSize?: \"contain\" | \"cover\" | \"repeat\";\n    backgroundEffect?: string;\n    prevBackgroundColor?: string;\n  };\n\n  // Defaults\n  defaultLineColor?: string;\n  themeId?: string;\n\n  // Layout\n  layoutType?: \"manual\" | \"auto\";\n  disableAutoLayoutOfManuallyPositionedNodes?: boolean;\n  nodeOrder?: string[]; // Array of node IDs for z-ordering\n\n  // Huddle\n  huddleType?: \"none\" | \"basic\" | \"advanced\";\n  huddleEnabled?: boolean;\n\n  // Metadata\n  tags?: string[];\n  templateMarkdown?: string;\n  templatePrompt?: string;\n  ai?: any;\n\n  // Sub-systems\n  panZoom?: PanZoomOptions;\n  birdsEye?: BirdsEyeOptions;\n\n  // Events\n  events?: SlateEvents;\n}\n\nexport class Slate {\n  public element: HTMLElement;\n  public canvas!: Svg;\n  public nodes!: NodesManager;\n  public invoker!: Invoker;\n  public panZoom!: PanZoom;\n  public birdsEye!: BirdsEye;\n  public undoRedo!: UndoRedo;\n  public multiSelection!: MultiSelection;\n  public grid!: Grid;\n  public keyboard!: Keyboard;\n  public contextMenu!: ContextMenu;\n  public collab!: Collab;\n  public zoomSlider!: ZoomSlider;\n  public presentation!: Presentation;\n  public options: SlateOptions;\n  // Runtime-injected by Connector for global line/marker containers\n  public linesContainer?: any;\n  public markersContainer?: any;\n  /** The single active line-properties cog affordance (M1), if shown. */\n  public _activeLineCog?: any;\n  /** The connectable whose endpoint handles are currently shown (L1/M8). */\n  public _activeLineConnectable?: any;\n  /** The active per-endpoint lock/relative toggle affordances (Q3). */\n  public _activeEndpointToggles?: any[];\n  private selectedNodes: Node[] = [];\n  private groupResizeRotate: any = null; // Will hold the group resize/rotate controller\n  /**\n   * The groupId currently \"entered\" for individual-member editing (Miro\n   * double-click-into-group). When set, clicking a member of THIS group selects\n   * just that member instead of expanding to the whole group. null = not inside\n   * any group.\n   */\n  private enteredGroupId: string | null = null;\n  private _coordinateIntervalId: ReturnType<typeof setInterval> | null = null;\n  private _destroyed: boolean = false;\n  private _applyingRemote: boolean = false;\n  private _hadGroupSelection: boolean = false;\n  private _emitDeferred: boolean = false;\n  private _emitQueue: SlatePackage[] = [];\n  private _birdsEyeTimeoutId: ReturnType<typeof setTimeout> | null = null;\n  private _coordDisplayTimeoutId: ReturnType<typeof setTimeout> | null = null;\n  private _nodeNotifyTimeoutId: ReturnType<typeof setTimeout> | null = null;\n  private _liveRegion: HTMLElement | null = null; // Hidden aria-live region for screen readers\n  private _resizeObserver: ResizeObserver | null = null;\n\n  /**\n   * v1-parity `slate.filters.availableFilters` — the node Effects pane reads\n   * `node.slate.filters.availableFilters` (keyed by name, each with `types`) to\n   * decide which effects to offer. Per-node application lives on `node.filters`.\n   */\n  public get filters(): {\n    availableFilters: Record<string, { types: string[] }>;\n    availableAnimations: Record<string, AnimationDef>;\n  } {\n    return {\n      availableFilters: getAvailableFilters(),\n      availableAnimations: getAvailableAnimations(),\n    };\n  }\n\n  /**\n   * Creates a new Slate — the main orchestrator for a diagramming canvas.\n   *\n   * Initializes the SVG canvas, sets up all sub-modules (nodes manager,\n   * pan/zoom, selection, grid, keyboard shortcuts, undo/redo, etc.),\n   * and attaches event handlers.\n   *\n   * @param element - CSS selector string or HTMLElement to mount the canvas on\n   * @param options - Full slate configuration (see SlateOptions interface)\n   * @throws If element is a selector string and no matching element is found\n   *\n   * @example\n   * ```ts\n   * import { Slate } from 'slateboxjs';\n   * const slate = new Slate('#canvas', {\n   *   viewPort: { originalWidth: 1200, originalHeight: 800 },\n   *   panZoom: { enabled: true }\n   * });\n   * ```\n   */\n  constructor(element: string | HTMLElement, options: SlateOptions = {}) {\n    // Get or create the target element\n    if (typeof element === \"string\") {\n      const found = document.querySelector(element) as HTMLElement;\n      if (!found) {\n        throw new Error(`Element with selector \"${element}\" not found`);\n      }\n      this.element = found;\n    } else {\n      this.element = element;\n    }\n\n    // Register on window for host-app debugging and e2e tooling\n    if (typeof window !== \"undefined\") {\n      const w = window as any;\n      w.__slateboxInstances = w.__slateboxInstances || [];\n      w.__slateboxInstances.push(this);\n    }\n\n    // Default options\n    this.options = {\n      name: \"Untitled Slate\",\n      description: \"\",\n      followMe: true,\n      mindMapMode: false,\n      autoResizeNodesBasedOnText: true,\n      viewPort: {\n        originalWidth: 800,\n        originalHeight: 600,\n        showGrid: false,\n        snapToObjects: false,\n        showCoordinates: true,\n      },\n      containerStyle: {\n        backgroundColor: \"#ffffff\",\n        backgroundColorAsGradient: false,\n        backgroundGradientType: \"linear\",\n        backgroundGradientColors: [],\n        backgroundGradientStrategy: \"horizontal\",\n        backgroundImage: undefined,\n        backgroundSize: \"contain\",\n        backgroundEffect: undefined,\n        prevBackgroundColor: \"#ffffff\",\n      },\n      defaultLineColor: \"#000000\",\n      themeId: undefined,\n      layoutType: \"manual\",\n      disableAutoLayoutOfManuallyPositionedNodes: false,\n      huddleType: \"none\",\n      huddleEnabled: false,\n      tags: [],\n      templateMarkdown: \"\",\n      templatePrompt: \"\",\n      isTemplate: false,\n      ai: {},\n      panZoom: {\n        enabled: true,\n        panning: true,\n        pinchZoom: true,\n        wheelZoom: false, // Disable wheel zoom - use pinch to zoom, scroll to pan\n        zoomFactor: 0.3,\n        zoomMin: 0.1,\n        zoomMax: 10,\n      },\n      ...options,\n    };\n\n    this.init();\n  }\n\n  private init() {\n    // Initialize SVG canvas\n    this.canvas = SVG().addTo(this.element);\n\n    // Accessibility: label the canvas for screen readers\n    this.canvas.node.setAttribute(\"role\", \"img\");\n    this.canvas.node.setAttribute(\"aria-label\", this.options.name || \"Diagram canvas\");\n    this.canvas.node.setAttribute(\"tabindex\", \"0\");\n\n    // Accessibility: create hidden live region for screen-reader announcements\n    this._liveRegion = document.createElement(\"div\");\n    this._liveRegion.setAttribute(\"aria-live\", \"polite\");\n    this._liveRegion.setAttribute(\"aria-atomic\", \"true\");\n    this._liveRegion.style.cssText =\n      \"position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;\";\n    this.element.appendChild(this._liveRegion);\n\n    // ── Infinite canvas ──\n    // The SVG root FILLS its container; the visible region is driven entirely\n    // by the viewBox (Miro-style). Nothing is clipped to a fixed box — pan/\n    // zoom just move the viewBox across an unbounded plane.\n    this.element.style.overflow = this.element.style.overflow || \"hidden\";\n    if (getComputedStyle(this.element).position === \"static\") {\n      this.element.style.position = \"relative\";\n    }\n    const svgNode = this.canvas.node as SVGSVGElement;\n    if (svgNode?.style) {\n      svgNode.style.width = \"100%\";\n      svgNode.style.height = \"100%\";\n      svgNode.style.display = \"block\";\n    }\n    svgNode?.removeAttribute?.(\"width\");\n    svgNode?.removeAttribute?.(\"height\");\n    svgNode?.setAttribute?.(\"preserveAspectRatio\", \"xMidYMid slice\");\n\n    // Initial viewBox = container pixel size at zoom 1 (1 unit = 1px),\n    // centered on the world origin so content near it is in view. Falls back\n    // to sensible defaults before the element has been laid out.\n    const rect = this.element.getBoundingClientRect();\n    this.options.viewPort = this.options.viewPort || {};\n    // Honor an explicit originalWidth/Height for the initial viewBox; else\n    // measure the container. The ResizeObserver keeps it synced to real px.\n    const vw =\n      this.options.viewPort.originalWidth || Math.round(rect.width) || 800;\n    const vh =\n      this.options.viewPort.originalHeight || Math.round(rect.height) || 600;\n    this.options.viewPort.originalWidth = vw;\n    this.options.viewPort.originalHeight = vh;\n    // Default framing: origin at top-left (matches v1's initial viewBox), so\n    // content near (0,0) is visible immediately. Content placed far away\n    // (e.g. the app seeds nodes near 10000,10000) is framed by the host's\n    // scaleToFitAndCenter/fitToContent after load. Honors an explicit\n    // viewPort.left/top when provided.\n    const originX = this.options.viewPort.left ?? 0;\n    const originY = this.options.viewPort.top ?? 0;\n    this.canvas.viewbox(originX, originY, vw, vh);\n\n    // Keep the viewBox 1:1 with the container as it resizes (preserve zoom\n    // and center point) so the canvas always fills and never distorts.\n    this._setupResizeObserver();\n\n    // Initialize nodes manager\n    this.nodes = new NodesManager(this);\n\n    // Initialize invoker with the contract methods\n    this.invoker = new Invoker(this);\n\n    // Apply background color/gradient/image from options\n    this.applyContainerStyle();\n\n    // Set up selection management\n    this.setupSelectionHandling();\n\n    // Set up coordinate display callbacks before pan/zoom initialization\n    if (this.options.viewPort?.showCoordinates) {\n      this.setupCoordinateCallbacks();\n    }\n\n    // Initialize pan/zoom functionality\n    this.panZoom = new PanZoom(this, this.options.panZoom);\n\n    // Initialize birds eye / minimap\n    this.birdsEye = new BirdsEye(this, this.options.birdsEye);\n    if (this.options.birdsEye?.enabled) {\n      // Delay enable to ensure canvas is ready\n      this._birdsEyeTimeoutId = setTimeout(() => {\n        if (!this._destroyed) this.birdsEye.enable();\n      }, 200);\n    }\n\n    // Initialize undo/redo + take an empty baseline so the very first edit on a\n    // fresh slate is undoable (loadJSON re-baselines for loaded documents).\n    this.undoRedo = new UndoRedo(this, {\n      enabled: this.options.showUndoRedo !== false,\n    });\n    this.undoRedo.snap?.(true);\n\n    // Initialize multi-selection\n    this.multiSelection = new MultiSelection(this, {\n      enabled: this.options.showMultiSelect !== false,\n    });\n\n    // Initialize grid\n    this.grid = new Grid(this, {\n      enabled: this.options.viewPort?.showGrid || false,\n      gridSize: this.options.viewPort?.gridSize || 20,\n      // Re-apply the persisted snap-to-grid setting so it survives reload.\n      snapToGrid: this.options.viewPort?.snapToGrid || false,\n    });\n    if (this.options.viewPort?.showGrid) {\n      this.grid.show();\n    }\n\n    // Initialize keyboard bindings\n    this.keyboard = new Keyboard(this);\n    if (this.options.enabled !== false) {\n      this.keyboard.bindGlobal();\n    }\n\n    // Right-click context menu (bring-to-front / back / duplicate / delete)\n    this.contextMenu = new ContextMenu(this);\n    if (this.options.enabled !== false) {\n      this.contextMenu.enable();\n    }\n\n    // Initialize collaboration (lazy — call collab.init() to connect)\n    this.collab = new Collab(this);\n\n    // Initialize zoom slider\n    this.zoomSlider = new ZoomSlider(this, {\n      enabled: this.options.showZoom || false,\n    });\n\n    // Initialize presentation mode\n    this.presentation = new Presentation(this);\n\n    // Make canvas responsive\n    this.makeResponsive();\n\n    // Add coordinate display element after pan/zoom is ready\n    if (this.options.viewPort?.showCoordinates) {\n      this._coordDisplayTimeoutId = setTimeout(() => {\n        if (!this._destroyed) this.addCoordinateDisplay();\n      }, 150);\n    }\n  }\n\n  /**\n   * Destroy the Slate, cleaning up all sub-modules, timers, and event listeners.\n   * Follows the PanZoom.ts pattern: clear timers → remove listeners → chain to owned objects.\n   */\n  public destroy(): void {\n    this._destroyed = true;\n\n    if (this._resizeObserver) {\n      this._resizeObserver.disconnect();\n      this._resizeObserver = null;\n    }\n\n    // Deregister from the window instance list\n    if (typeof window !== \"undefined\") {\n      const w = window as any;\n      if (Array.isArray(w.__slateboxInstances)) {\n        w.__slateboxInstances = w.__slateboxInstances.filter(\n          (s: any) => s !== this\n        );\n      }\n    }\n\n    // Clear all pending timeouts\n    if (this._birdsEyeTimeoutId !== null) {\n      clearTimeout(this._birdsEyeTimeoutId);\n      this._birdsEyeTimeoutId = null;\n    }\n    if (this._coordDisplayTimeoutId !== null) {\n      clearTimeout(this._coordDisplayTimeoutId);\n      this._coordDisplayTimeoutId = null;\n    }\n    if (this._nodeNotifyTimeoutId !== null) {\n      clearTimeout(this._nodeNotifyTimeoutId);\n      this._nodeNotifyTimeoutId = null;\n    }\n\n    // Clear coordinate polling interval\n    if (this._coordinateIntervalId !== null) {\n      clearInterval(this._coordinateIntervalId);\n      this._coordinateIntervalId = null;\n    }\n\n    // Remove coordinate display element\n    const coordDisplay = this.element.querySelector(\"#slate-coordinates\") as HTMLElement;\n    if (coordDisplay) {\n      coordDisplay.remove();\n    }\n\n    // Remove canvas click handler\n    this.canvas.off(\"click\");\n\n    // Chain destroy to sub-modules\n    if (this.panZoom) {\n      this.panZoom.destroy();\n    }\n    if (this.birdsEye) {\n      this.birdsEye.disable();\n    }\n    if (this.zoomSlider) {\n      this.zoomSlider.destroy();\n    }\n    if (this.keyboard) {\n      this.keyboard.unbindGlobal();\n    }\n    if (this.contextMenu) {\n      this.contextMenu.disable();\n    }\n    if (this.multiSelection) {\n      this.multiSelection.disable();\n    }\n    if (this.undoRedo) {\n      this.undoRedo.clear();\n    }\n    if (this.collab) {\n      this.collab.disconnect();\n    }\n    if (this.presentation) {\n      this.presentation.stop();\n    }\n    if (this.grid) {\n      this.grid.hide();\n    }\n\n    // Clear all nodes\n    if (this.nodes) {\n      this.nodes.clear();\n    }\n\n    // Remove the SVG canvas\n    if (this.canvas) {\n      this.canvas.remove();\n    }\n\n    // Remove live region\n    if (this._liveRegion) {\n      this._liveRegion.remove();\n      this._liveRegion = null;\n    }\n  }\n\n  /**\n   * Announce a message to screen readers via the hidden aria-live region.\n   * Used for state changes: node add/remove, selection changes, zoom changes.\n   */\n  public announce(msg: string): void {\n    if (this._liveRegion) {\n      // Clear and set to force re-announcement\n      this._liveRegion.textContent = \"\";\n      // Use setTimeout to ensure the clear is processed before the new text\n      setTimeout(() => { if (this._liveRegion) this._liveRegion.textContent = msg; }, 50);\n    }\n  }\n\n  /**\n   * Emit a v1-compatible change package to the host application via\n   * `options.events.onSlateChanged(pkg, collabUsers)`.\n   *\n   * Suppressed while a remote package is being applied (see\n   * {@link beginRemoteApply}) so remote changes are never echoed back to the\n   * host as local ones — mirroring v1's clientID filtering.\n   *\n   * @param type - v1 package type (e.g. \"onNodeAdded\", \"onNodesMove\")\n   * @param data - v1-shaped package data\n   */\n  public emitSlateChange(type: string, data: Record<string, any> = {}): void {\n    if (this._applyingRemote || this._destroyed) return;\n    const cb = this.options.events?.onSlateChanged;\n    if (!cb) return;\n    const pkg: SlatePackage = { type, data };\n    if (this.options.instance) pkg.instanceId = this.options.instance;\n\n    // v1 timing: onSlateChanged arrived via the async collab echo, so host\n    // apps assume collab init already ran (e.g. slatebox.com reads its\n    // collaborator ref). While deferred, queue packages for later flush.\n    if (this._emitDeferred) {\n      this._emitQueue.push(pkg);\n      return;\n    }\n\n    let users: CollabUser[] = [];\n    try {\n      users = this.collab?.getCollabUsers?.() ?? [];\n    } catch {\n      // collab is optional — no users available\n    }\n    try {\n      const result: any = cb(pkg, users);\n      // Host handlers are often async — surface rejections as warnings\n      // instead of unhandled promise rejections\n      result?.catch?.((error: unknown) =>\n        console.warn(\"SLATE_EVENTS_DEBUG: onSlateChanged handler rejected\", error)\n      );\n    } catch (error) {\n      console.warn(\"SLATE_EVENTS_DEBUG: onSlateChanged handler threw\", error);\n    }\n  }\n\n  /**\n   * Broadcast a library-originated change to collaborators AND surface it to\n   * the host (collab.send emits onSlateChanged — v1 echo semantics). This is\n   * what interactive mutations (drag, resize, rotate, z-order, delete…) call:\n   * in v1 every one of them went out through collab.send. Suppressed while a\n   * remote package is being applied so remote changes never re-broadcast.\n   */\n  public broadcast(type: string, data: Record<string, any> = {}): void {\n    if (this._applyingRemote || this._destroyed) return;\n    if (typeof this.collab?.send === \"function\") {\n      this.collab.send({ type, data });\n    } else {\n      this.emitSlateChange(type, data);\n    }\n    // Record an undo snapshot for state-mutating changes (debounced so a drag or\n    // a burst of edits collapses into one undo step). View/presence events don't\n    // change document state, so they're excluded.\n    this.recordUndoFor(type);\n  }\n\n  /** Record a debounced undo checkpoint for a document-mutating package. */\n  public recordUndoFor(type: string): void {\n    if (this.undoRedo && !Slate.NON_UNDOABLE.has(type)) {\n      this.undoRedo.snap?.();\n    }\n  }\n\n  /** Broadcast types that change the viewport/presence, not document state. */\n  private static readonly NON_UNDOABLE = new Set<string>([\n    \"onZoom\",\n    \"onCanvasMove\",\n    \"onFollowMeChanged\",\n    \"onSlateFollowMeChanged\",\n    \"onSlateHuddleChanged\",\n    \"onCursorMoved\",\n    \"onPresenceChanged\",\n    \"onSlateChanged\",\n    // UndoRedo already moved the history pointer before broadcasting this\n    // authoritative state; recording it again would create a duplicate step.\n    \"onSlateReplaced\",\n  ]);\n\n  /** Queue onSlateChanged packages until flushEmits() (v1 collab-init timing). */\n  public deferEmits(): void {\n    this._emitDeferred = true;\n  }\n\n  /** Deliver queued packages and resume synchronous emission. */\n  public flushEmits(): void {\n    this._emitDeferred = false;\n    const queued = this._emitQueue.splice(0);\n    for (const pkg of queued) {\n      this.emitSlateChange(pkg.type, pkg.data);\n    }\n  }\n\n  /**\n   * Apply `options.containerStyle` (background color / gradient / image) to\n   * the container element. v1's canvas.refreshBackground equivalent — called\n   * during init and again after loadJSON replaces the options.\n   */\n  public applyContainerStyle(): void {\n    const cs = this.options.containerStyle;\n    if (!cs || !this.element) return;\n\n    const el = this.element;\n\n    if (\n      cs.backgroundColorAsGradient &&\n      Array.isArray(cs.backgroundGradientColors) &&\n      cs.backgroundGradientColors.length > 1\n    ) {\n      const colors = cs.backgroundGradientColors.join(\", \");\n      el.style.backgroundImage =\n        cs.backgroundGradientType === \"radial\"\n          ? `radial-gradient(circle, ${colors})`\n          : `linear-gradient(${colors})`;\n    } else if (cs.backgroundImage) {\n      el.style.backgroundImage = `url(${cs.backgroundImage})`;\n      if (cs.backgroundSize) el.style.backgroundSize = cs.backgroundSize;\n    } else {\n      el.style.backgroundImage = \"\";\n    }\n\n    if (cs.backgroundColor) {\n      el.style.backgroundColor = cs.backgroundColor;\n    }\n  }\n\n  /** v1: host-supplied permission check — true when the viewer cannot edit. */\n  public isReadOnly(): boolean {\n    return !!this.options.events?.isReadOnly?.();\n  }\n\n  /** v1: host-supplied permission check — true when only comments are allowed. */\n  public isCommentOnly(): boolean {\n    return !!this.options.events?.isCommentOnly?.();\n  }\n\n  /** v1: host-supplied permission check for removing comment nodes. */\n  public canRemoveComments(): boolean {\n    return !!this.options.events?.canRemoveComments?.();\n  }\n\n  /** Suppress emitSlateChange while applying a remote package (v1 echo semantics). */\n  public beginRemoteApply(): void {\n    this._applyingRemote = true;\n  }\n\n  /** Re-enable emitSlateChange after a remote package has been applied. */\n  public endRemoteApply(): void {\n    this._applyingRemote = false;\n  }\n\n  private setupCoordinateCallbacks() {\n    // Store original callbacks\n    const originalOnPan = this.options.panZoom?.onPan;\n    const originalOnZoom = this.options.panZoom?.onZoom;\n\n    // Set up callbacks that will update coordinates\n    if (!this.options.panZoom) {\n      this.options.panZoom = {};\n    }\n\n    this.options.panZoom.onPan = (pan: any) => {\n      this.updateCoordinateDisplay();\n      if (originalOnPan) {\n        originalOnPan(pan);\n      }\n    };\n\n    this.options.panZoom.onZoom = (zoom: any) => {\n      this.updateCoordinateDisplay();\n      if (originalOnZoom) {\n        originalOnZoom(zoom);\n      }\n    };\n\n    // v1 contract: a completed pan broadcasts onCanvasMove\n    const originalOnPanEnd = this.options.panZoom.onPanEnd;\n    this.options.panZoom.onPanEnd = (evt: any) => {\n      if (originalOnPanEnd) {\n        originalOnPanEnd(evt);\n      }\n      try {\n        const pan = this.getPan();\n        this.broadcast(\"onCanvasMove\", {\n          left: pan.x,\n          top: pan.y,\n          relative: { x: pan.x, y: pan.y },\n          orient: this.getOrientation(),\n        });\n      } catch {\n        // pan/zoom may not be initialized yet\n      }\n    };\n  }\n\n  private addCoordinateDisplay() {\n    // Dev-only debug readout — hidden unless explicitly opted in. It must never\n    // show in production (or in the presentation view).\n    if (!(this.options as any).showCoordinates) return;\n    console.log(\"COORD_DEBUG: Starting coordinate display creation\");\n\n    // Create coordinate display in upper left\n    const coordDisplay = document.createElement(\"div\");\n    coordDisplay.id = \"slate-coordinates\";\n    coordDisplay.style.cssText = `\n      position: absolute;\n      top: 10px;\n      left: 10px;\n      background: rgba(0, 0, 0, 0.7);\n      color: white;\n      padding: 8px 12px;\n      border-radius: 4px;\n      font-family: monospace;\n      font-size: 12px;\n      pointer-events: none;\n      z-index: 1000;\n      min-width: 150px;\n    `;\n\n    // Ensure parent element has relative positioning\n    this.element.style.position = this.element.style.position || \"relative\";\n    this.element.appendChild(coordDisplay);\n\n    console.log(\n      \"COORD_DEBUG: Coordinate display element created and added to DOM\"\n    );\n    console.log(\"COORD_DEBUG: Element style:\", coordDisplay.style.cssText);\n    console.log(\"COORD_DEBUG: Parent element:\", this.element);\n\n    // Set initial text immediately\n    coordDisplay.textContent = \"x: 0, y: 0, zoom: 1.00\";\n\n    // Start immediate coordinate tracking\n    this.updateCoordinateDisplay();\n\n    // Start polling for coordinate updates as fallback\n    this.startCoordinatePolling();\n  }\n\n  private startCoordinatePolling() {\n    if (this._destroyed) return;\n    console.log(\"COORD_DEBUG: Starting coordinate polling\");\n\n    // Poll every 200ms to update coordinates (reduced frequency)\n    this._coordinateIntervalId = setInterval(() => {\n      if (!this._destroyed) this.updateCoordinateDisplay();\n    }, 200);\n  }\n\n  private updateCoordinateDisplay() {\n    const coordDisplay = this.element.querySelector(\n      \"#slate-coordinates\"\n    ) as HTMLElement;\n    if (!coordDisplay) {\n      console.log(\"COORD_DEBUG: No coordinate display element found in DOM\");\n      return;\n    }\n\n    try {\n      // Get current pan and zoom values\n      let pan = { x: 0, y: 0 };\n      let zoom = 1;\n\n      if (this.panZoom && this.panZoom.isInitialized()) {\n        pan = this.getPan();\n        zoom = this.getZoom();\n        console.log(\n          \"COORD_DEBUG: Got values from panZoom - pan:\",\n          pan,\n          \"zoom:\",\n          zoom\n        );\n      } else {\n        // Fallback: get directly from viewBox\n        const viewBox = this.canvas.viewbox();\n        pan = { x: viewBox.x, y: viewBox.y };\n        const px = this.element.getBoundingClientRect().width || viewBox.width;\n        zoom = px / viewBox.width || 1;\n        console.log(\n          \"COORD_DEBUG: Got fallback values from viewBox - pan:\",\n          pan,\n          \"zoom:\",\n          zoom\n        );\n      }\n\n      const newText = `x: ${Math.round(pan.x)}, y: ${Math.round(\n        pan.y\n      )}, zoom: ${zoom.toFixed(2)}`;\n      coordDisplay.textContent = newText;\n\n      // Log occasionally to verify it's working\n      if (Math.random() < 0.1) {\n        // 10% chance to log\n        console.log(\"COORD_DEBUG: Updated coordinates to:\", newText);\n      }\n    } catch (error) {\n      console.error(\"COORD_DEBUG: Error updating coordinates:\", error);\n      coordDisplay.textContent = \"x: ?, y: ?, zoom: ?\";\n    }\n  }\n\n  private makeResponsive() {\n    // No-op: the infinite-canvas setup in init() already established a\n    // container-filling SVG (width/height 100%) with a viewBox centered on\n    // the world origin. Overwriting the viewBox here would undo that.\n  }\n\n  /**\n   * Add a new node to the slate.\n   *\n   * @param options - Node options including position, size, text, shape, colors, etc.\n   * @returns The newly created Node instance\n   *\n   * @example\n   * ```ts\n   * slate.addNode({\n   *   id: 'my-node', x: 200, y: 150,\n   *   width: 120, height: 80, text: 'Hello',\n   *   shape: 'rectangle', backgroundColor: '#4ecdc4'\n   * });\n   * ```\n   */\n  public addNode(options: Partial<NodeOptions> = {}) {\n    const node = this.nodes.add(options);\n    // Notify BirdsEye of the new node after a short delay for rendering\n    this._nodeNotifyTimeoutId = setTimeout(() => {\n      if (!this._destroyed) this.notifyNodeChanged();\n      this.announce(`Node added: ${node.options.text || \"(unnamed)\"}`);\n    }, 100);\n    this.broadcast(\"onNodeAdded\", {\n      id: node.id,\n      nodeOptions: v2NodeToV1(node.options),\n    });\n    return node;\n  }\n\n  /** Remove a node by ID. */\n  public removeNode(id: string) {\n    const node = this.nodes.one(id);\n    const text = node?.options?.text || \"(unnamed)\";\n    const isComment = !!node?.options?.isComment;\n    // If the node is currently SELECTED, tear down its svg.select resize/rotate overlay\n    // (selection box + handles) BEFORE removing it — those handles live in a separate\n    // overlay and select(false) needs the element to still exist, or deleting a selected\n    // node leaves the whole rogue selection box floating with nothing selected. (Done\n    // here, not in node.remove(), to preserve remove()'s light \"don't disable sub-modules\"\n    // contract — this is the permanent user-delete path.)\n    if (node && this.selectedNodes.some((n) => n.id === id)) {\n      try {\n        (node as any).resizeRotate?.disable();\n      } catch (e) {\n        /* noop */\n      }\n      this.selectedNodes = this.selectedNodes.filter((n) => n.id !== id);\n    }\n    const result = this.nodes.remove(id);\n    // Notify BirdsEye of the removed node\n    this.notifyNodeChanged();\n    this.announce(`Node removed: ${text}`);\n    if (result) {\n      this.broadcast(\"onNodeDeleted\", { id, isComment });\n    }\n    return result;\n  }\n\n  /**\n   * Notify that a node has changed (position, rotation, added, removed)\n   * This triggers BirdsEye refresh if enabled\n   */\n  public notifyNodeChanged(node?: Node): void {\n    if (this.birdsEye?.isEnabled()) {\n      this.birdsEye.scheduleRefresh();\n    }\n  }\n\n  /** @returns The node with the given ID, or undefined if not found. */\n  public getNode(id: string) {\n    return this.nodes.one(id);\n  }\n\n  /** @returns All nodes currently on the slate. */\n  public getAllNodes(): Node[] {\n    return this.nodes.allNodes;\n  }\n\n  // Get the pan/zoom viewport for adding content that should pan/zoom\n  /** @returns The SVG root canvas (used as the viewport for pan/zoom). */\n  public getViewport(): Svg {\n    // SVG.js panzoom works directly with root canvas - no viewport nesting needed!\n    console.log(\"VIEWPORT_DEBUG: Using root canvas (SVG.js panzoom)\");\n    return this.canvas;\n  }\n\n  // Get viewport with retry logic for proper initialization\n  /** @returns Promise resolving to the SVG root canvas. */\n  public getViewportAsync(): Promise<Svg> {\n    // SVG.js panzoom works directly with root canvas - immediate return\n    console.log(\n      \"VIEWPORT_DEBUG: Returning root canvas immediately (SVG.js panzoom)\"\n    );\n    return Promise.resolve(this.canvas);\n  }\n\n  // Pan/Zoom API methods\n  /** Enable pan and zoom interactions. */\n  public enablePanZoom() {\n    this.panZoom.enable();\n  }\n\n  /** Disable pan and zoom interactions. */\n  public disablePanZoom() {\n    this.panZoom.disable();\n  }\n\n  /** Enable canvas panning. */\n  public enablePan() {\n    this.panZoom.enablePan();\n  }\n\n  /** Disable canvas panning. */\n  public disablePan() {\n    this.panZoom.disablePan();\n  }\n\n  /** Enable canvas zoom. */\n  public enableZoom() {\n    this.panZoom.enableZoom();\n  }\n\n  /** Disable canvas zoom. */\n  public disableZoom() {\n    this.panZoom.disableZoom();\n  }\n\n  /**\n   * Pan to a specific position.\n   * @param point - { x, y } target position\n   */\n  public pan(point: { x: number; y: number }) {\n    this.panZoom.pan(point);\n  }\n\n  /**\n   * Pan by a relative delta.\n   * @param delta - { dx, dy } distance to pan\n   */\n  public panBy(delta: { x: number; y: number }) {\n    this.panZoom.panBy(delta);\n  }\n\n  /**\n   * Set the zoom level.\n   * @param level - Zoom factor (1 = 100%)\n   */\n  public zoom(level: number) {\n    this.panZoom.zoom(level);\n    this.announce(`Zoom: ${Math.round(level * 100)}%`);\n    this.broadcast(\"onZoom\", { zoomLevel: level });\n  }\n\n  /**\n   * Zoom by a relative factor.\n   * @param factor - Multiplier applied to current zoom\n   */\n  public zoomBy(factor: number) {\n    this.panZoom.zoomBy(factor);\n  }\n\n  /** Zoom in one step. */\n  public zoomIn() {\n    this.panZoom.zoomIn();\n  }\n\n  /** Zoom out one step. */\n  public zoomOut() {\n    this.panZoom.zoomOut();\n  }\n\n  /**\n   * Zoom centered on a point.\n   * @param level - Target zoom level\n   * @param point - { x, y } focus point\n   */\n  public zoomAtPoint(level: number, point: { x: number; y: number }) {\n    this.panZoom.zoomAtPoint(level, point);\n  }\n\n  /** Reset both pan and zoom to defaults. */\n  public resetPanZoom() {\n    this.panZoom.reset();\n  }\n\n  /** Reset zoom to 100%. */\n  public resetZoom() {\n    this.panZoom.resetZoom();\n  }\n\n  /** Reset pan position to origin. */\n  public resetPan() {\n    this.panZoom.resetPan();\n  }\n\n  /** Zoom/pan to fit all nodes in the viewport. */\n  public fitToContent() {\n    this.panZoom.fit();\n  }\n\n  /** Pan to center all nodes in the viewport. */\n  public centerContent() {\n    this.panZoom.center();\n  }\n\n  /** @returns Current zoom level (1 = 100%). */\n  public getZoom(): number {\n    return this.panZoom.getZoom();\n  }\n\n  /** @returns Current pan position as { x, y }. */\n  public getPan(): { x: number; y: number } {\n    return this.panZoom.getPan();\n  }\n\n  /** Notify pan/zoom that the viewport was resized. */\n  public resizePanZoom() {\n    this.panZoom.resize();\n  }\n\n  /**\n   * Keep the viewBox 1:1 with the container pixel size across resizes so the\n   * infinite canvas always fills its element and never distorts. Preserves\n   * the current zoom level and the world-point at the viewBox center.\n   */\n  private _setupResizeObserver(): void {\n    if (typeof ResizeObserver === \"undefined\") return;\n    let lastW = 0;\n    let lastH = 0;\n    this._resizeObserver = new ResizeObserver(() => {\n      if (this._destroyed) return;\n      const rect = this.element.getBoundingClientRect();\n      const pw = Math.max(1, Math.round(rect.width));\n      const ph = Math.max(1, Math.round(rect.height));\n      if (pw === lastW && ph === lastH) return;\n\n      const vb = this.canvas.viewbox();\n      // Current on-screen scale (viewBox units per pixel). Use the previous\n      // container width to recover it; fall back to viewBox/px on first run.\n      const unitsPerPx = vb.width / (lastW || pw);\n      lastW = pw;\n      lastH = ph;\n\n      const cx = vb.x + vb.width / 2;\n      const cy = vb.y + vb.height / 2;\n      const newW = pw * unitsPerPx;\n      const newH = ph * unitsPerPx;\n      this.canvas.viewbox(cx - newW / 2, cy - newH / 2, newW, newH);\n      this.options.viewPort = this.options.viewPort || {};\n      this.options.viewPort.originalWidth = pw;\n      this.options.viewPort.originalHeight = ph;\n    });\n    this._resizeObserver.observe(this.element);\n  }\n\n  /**\n   * Bounding-box orientation of the current content (v1 contract):\n   * `{orientation, width, height, left, top}` computed over all nodes with\n   * 10px padding, falling back to the viewport dimensions when empty.\n   */\n  public getOrientation(): {\n    orientation: \"landscape\" | \"portrait\";\n    width: number;\n    height: number;\n    left: number;\n    top: number;\n  } {\n    const all = this.nodes?.allNodes ?? [];\n    const vp: any = this.options.viewPort || {};\n    let width = vp.width ?? vp.originalWidth ?? 800;\n    let height = vp.height ?? vp.originalHeight ?? 600;\n    let left = 0;\n    let top = 0;\n    let orientation: \"landscape\" | \"portrait\" = \"landscape\";\n\n    if (all.length > 0) {\n      const pad = 10;\n      let minX = Infinity;\n      let minY = Infinity;\n      let maxX = -Infinity;\n      let maxY = -Infinity;\n      all.forEach((n: any) => {\n        const x = n.options.x ?? 0;\n        const y = n.options.y ?? 0;\n        const w = n.options.width ?? 0;\n        const h = n.options.height ?? 0;\n        minX = Math.min(minX, x - pad);\n        minY = Math.min(minY, y - pad);\n        maxX = Math.max(maxX, x + w + pad);\n        maxY = Math.max(maxY, y + h + pad);\n      });\n      left = Math.abs(minX);\n      top = Math.abs(minY);\n      width = maxX - minX;\n      height = maxY - minY;\n      if (height > width) orientation = \"portrait\";\n    }\n\n    return { orientation, width, height, left, top };\n  }\n\n  // Selection Management\n  private setupSelectionHandling() {\n    // Add canvas click handler to deselect all nodes when clicking empty space\n    this.canvas.on(\"click\", (event: any) => {\n      console.log(\n        \"SELECTION_DEBUG: Canvas click detected\",\n        event.target,\n        \"vs\",\n        this.canvas.node\n      );\n\n      // Check if the click target is the canvas itself or a child of canvas but not a node\n      const isCanvasClick =\n        event.target === this.canvas.node ||\n        (event.target && event.target.tagName === \"svg\");\n\n      // Skip the deselect if this click is the tail end of a rubber-band drag\n      // that just selected nodes — otherwise the drag-selection is wiped the\n      // instant it's made (breaking group-move on the selection).\n      const sinceRubberBand = Date.now() - ((this as any)._rubberBandSelectedAt || 0);\n      if (sinceRubberBand < 400) {\n        (this as any)._rubberBandSelectedAt = 0;\n        return;\n      }\n\n      if (isCanvasClick) {\n        console.log(\"SELECTION_DEBUG: Canvas clicked - deselecting all\");\n        // Clicking empty canvas also steps out of any entered group.\n        this.enteredGroupId = null;\n        this.clearSelection();\n        this.clearLineCog();\n        // v1 contract: notify the host (used to close app-side panes)\n        this.options.events?.onCanvasClicked?.(event);\n      } else {\n        console.log(\n          \"SELECTION_DEBUG: Click on non-canvas element, not deselecting\"\n        );\n      }\n    });\n\n    // Miro parity: double-click on EMPTY canvas drops a new node at the cursor.\n    // (Double-click on a NODE edits its text — the isCanvasClick guard separates the\n    // two.) NOTE: auto-entering the inline editor on create was attempted 4 ways\n    // (await ready, poll for svgGroup, next-frame defer, preventDefault) — the editor\n    // opens fine programmatically but never survives the real double-click's event/\n    // render sequence, so we create + select and let the user double-click to edit.\n    this.canvas.on(\"dblclick\", (event: any) => {\n      const isCanvasClick =\n        event.target === this.canvas.node ||\n        (event.target && event.target.tagName === \"svg\");\n      if (!isCanvasClick) return;\n      if (this.isReadOnly?.()) return;\n      try {\n        const world = this.canvas.point(event.clientX, event.clientY);\n        const w = 120;\n        const h = 70;\n        const node = this.addNode({\n          x: Math.round(world.x - w / 2),\n          y: Math.round(world.y - h / 2),\n          width: w,\n          height: h,\n          text: \"\",\n        });\n        this.selectNodes?.([node]);\n      } catch (e) {\n        /* noop */\n      }\n    });\n  }\n\n  /**\n   * Select one or more nodes on the slate.\n   *\n   * This is the SINGLE ORCHESTRATOR for selection. It:\n   * 1. Clears current selection unless addToSelection is true\n   * 2. Adds the specified nodes to the selection set\n   * 3. Calls updateSelectionResizeRotate() to enable handles on selected nodes\n   * 4. Fires onSelectionChanged event\n   *\n   * @param nodes - Array of nodes to select\n   * @param addToSelection - If true, adds to existing selection instead of replacing it\n   *\n   * @example\n   * ```ts\n   * // Select a single node\n   * slate.selectNodes([node]);\n   * // Add to existing selection\n   * slate.selectNodes([node2, node3], true);\n   * ```\n   */\n  public selectNodes(nodes: Node[], addToSelection: boolean = false) {\n    console.log(\n      \"SELECTION_DEBUG: Selecting nodes\",\n      nodes.map((n) => n.id),\n      \"addToSelection:\",\n      addToSelection\n    );\n\n    // Selecting a node clears any line cog affordance.\n    this.clearLineCog();\n\n    // Miro-style groups: clicking a single member of a group selects the WHOLE\n    // group — unless we've \"entered\" that group to edit its members. Selecting\n    // anything outside the entered group also exits it. Marquee/programmatic\n    // multi-node selects (length > 1) are left untouched.\n    if (nodes.length === 1) {\n      const gid = this.getGroupIdOf(nodes[0]);\n      if (this.enteredGroupId && gid !== this.enteredGroupId) {\n        this.enteredGroupId = null;\n      }\n      if (gid && gid !== this.enteredGroupId) {\n        const members = this.getGroupMembers(gid);\n        if (members.length > 1) nodes = members;\n      }\n    }\n\n    // If not adding to selection, clear current selection first\n    if (!addToSelection) {\n      this.clearSelection();\n    }\n\n    // Add new nodes to selection (avoid duplicates)\n    nodes.forEach((node) => {\n      if (!this.selectedNodes.includes(node)) {\n        this.selectedNodes.push(node);\n        node.onSelected();\n      }\n    });\n\n    // Enable resize/rotate for the selection - CENTRALIZED CONTROL\n    this.updateSelectionResizeRotate();\n\n    // Announce selection change\n    const count = this.selectedNodes.length;\n    if (count === 0) {\n      this.announce(\"No nodes selected\");\n    } else if (count === 1) {\n      this.announce(`Node selected: ${this.selectedNodes[0].options.text || \"(unnamed)\"}`);\n    } else {\n      this.announce(`${count} nodes selected`);\n    }\n\n    // v1 contract: multi-node selections notify the host (group toolbar etc.)\n    if (count > 1) {\n      this._hadGroupSelection = true;\n      this.options.events?.onGroupSelection?.(this.selectedNodes.slice());\n    }\n  }\n\n  // SINGLE ORCHESTRATOR for resize/rotate management\n  /** Re-evaluate which nodes should have resize/rotate handles based on current selection. */\n  public updateSelectionResizeRotate() {\n    console.log(\n      \"SELECTION_DEBUG: Updating resize/rotate for\",\n      this.selectedNodes.length,\n      \"selected nodes\"\n    );\n\n    // First, disable ALL resize/rotate on ALL nodes to prevent conflicts\n    this.nodes.allNodes.forEach((node) => {\n      if (node.resizeRotate.isEnabled()) {\n        node.resizeRotate.disable();\n        console.log(\"SELECTION_DEBUG: Disabled resize/rotate on\", node.id);\n      }\n\n      // Also disable connection handles on all nodes\n      if (node.isConnectionHandlesEnabled()) {\n        node.disableConnectionHandles();\n        console.log(\"SELECTION_DEBUG: Disabled connection handles on\", node.id);\n      }\n\n      // Remove any node-properties cog affordance (M1)\n      (node as any).hideNodeCog?.();\n    });\n\n    // Remove any existing group controller\n    this.disableGroupResizeRotate();\n\n    if (this.selectedNodes.length === 0) {\n      // No selection - all resize/rotate disabled\n      console.log(\n        \"SELECTION_DEBUG: No nodes selected - all resize/rotate disabled\"\n      );\n      return;\n    }\n\n    if (this.selectedNodes.length === 1) {\n      // Single node selection - enable its individual resize/rotate and connection handles\n      const selectedNode = this.selectedNodes[0];\n      selectedNode.resizeRotate.enable();\n\n      selectedNode.enableConnectionHandles();\n      // Show the node-properties cog affordance (M1)\n      (selectedNode as any).showNodeCog?.();\n      console.log(\n        \"SELECTION_DEBUG: Enabled individual resize/rotate and connection handles on\",\n        selectedNode.id\n      );\n    } else {\n      // Multiple nodes - create group resize/rotate controller\n      // For now, disable connection handles for multi-selection\n      console.log(\n        \"SELECTION_DEBUG: Creating group resize/rotate for\",\n        this.selectedNodes.length,\n        \"nodes (connection handles disabled for multi-selection)\"\n      );\n      this.createGroupResizeRotate();\n    }\n  }\n\n  // Node-level resize/rotate control (called by Node methods)\n  /** Request resize/rotate enable for a specific node (checked against selection). */\n  public enableNodeResizeRotate(node: Node) {\n    // Only enable if this node is currently selected\n    if (this.selectedNodes.includes(node)) {\n      console.log(\n        \"SELECTION_DEBUG: Node\",\n        node.id,\n        \"requested resize/rotate enable - already selected\"\n      );\n      // Already handled by updateSelectionResizeRotate\n    } else {\n      console.log(\n        \"SELECTION_DEBUG: Node\",\n        node.id,\n        \"requested resize/rotate enable - selecting it\"\n      );\n      // Select the node (which will enable its resize/rotate)\n      this.selectNodes([node], false);\n    }\n  }\n\n  /** Disable resize/rotate for a specific node. */\n  public disableNodeResizeRotate(node: Node) {\n    console.log(\n      \"SELECTION_DEBUG: Node\",\n      node.id,\n      \"requested resize/rotate disable\"\n    );\n    // Disable the node's resize/rotate directly\n    if (node.resizeRotate.isEnabled()) {\n      node.resizeRotate.disable();\n    }\n\n    // Also hide connection handles during resize/rotate operations\n    if (node.isConnectionHandlesEnabled()) {\n      node.disableConnectionHandles();\n    }\n  }\n\n  private disableGroupResizeRotate() {\n    console.log(\"SELECTION_DEBUG: Disabling group resize/rotate\");\n\n    // Disable individual resize/rotate on all selected nodes\n    this.selectedNodes.forEach((node) => {\n      node.disableResizeRotate();\n    });\n\n    // Remove group controller if it exists\n    if (this.groupResizeRotate) {\n      this.groupResizeRotate.remove();\n      this.groupResizeRotate = null;\n    }\n  }\n\n  private createGroupResizeRotate() {\n    console.log(\"SELECTION_DEBUG: Creating group resize/rotate controller\");\n\n    // Remove existing group controller\n    if (this.groupResizeRotate) {\n      this.groupResizeRotate.remove();\n    }\n\n    // Calculate bounding box of all selected nodes\n    const groupBBox = this.calculateGroupBoundingBox();\n\n    // Bail out on a non-finite or degenerate box — feeding NaN/zero-size geometry\n    // to svg.select.js produces \"NaN\" polyline-handle errors.\n    if (\n      ![groupBBox.x, groupBBox.y, groupBBox.width, groupBBox.height].every(\n        Number.isFinite\n      ) ||\n      groupBBox.width <= 0 ||\n      groupBBox.height <= 0\n    ) {\n      return;\n    }\n\n    // Create a temporary group element for resize/rotate handles\n    this.groupResizeRotate = this.canvas.group();\n\n    // Dashed bounding rect around the whole selection — a clean visual indicator\n    // that multiple nodes are selected. (Nodes are still moved together by drag.)\n    this.groupResizeRotate\n      .rect(groupBBox.width, groupBBox.height)\n      .move(groupBBox.x, groupBBox.y)\n      .fill(\"transparent\")\n      .stroke({ color: \"#4a90e2\", width: 2, dasharray: \"5,5\" })\n      .attr(\"pointer-events\", \"none\");\n\n    // Rotate-as-one: an interactive knob above the box rotates every selected node\n    // about the group centre (position + own angle), so a group turns as a unit.\n    // Skipped when any member is locked. (Group RESIZE remains out of scope.)\n    const anyLocked = this.selectedNodes.some((n) => n.options.isLocked);\n    if (!anyLocked) this.addGroupRotateHandle(groupBBox);\n  }\n\n  /**\n   * Attach an interactive rotate knob to the group-selection outline. Dragging it\n   * rotates every selected node about the group centre: each member's centre is\n   * revolved around the group centre and the same delta is added to the member's\n   * own rotationAngle, so the whole selection turns rigidly (Miro group rotate).\n   *\n   * Angle math is done in SCREEN space (invariant to the uniform viewBox zoom/pan),\n   * then the delta is applied in world space to positions + per-node angles.\n   */\n  private addGroupRotateHandle(groupBBox: {\n    x: number;\n    y: number;\n    width: number;\n    height: number;\n  }): void {\n    const g = this.groupResizeRotate;\n    if (!g) return;\n    // A rendering affordance must never break selection — any SVG hiccup here is\n    // swallowed so the outline still shows and the selection stays usable.\n    try {\n    const cx = groupBBox.x + groupBBox.width / 2;\n    const cy = groupBBox.y + groupBBox.height / 2;\n    const offset = 28; // world units above the top edge\n    const knobY = groupBBox.y - offset;\n\n    g.line(cx, groupBBox.y, cx, knobY)\n      .stroke({ color: \"#4a90e2\", width: 1 })\n      .attr(\"pointer-events\", \"none\");\n    const knob = g\n      .circle(14)\n      .center(cx, knobY)\n      .fill(\"#ffffff\")\n      .stroke({ color: \"#4a90e2\", width: 2 });\n    const setCursor = (c: string) => {\n      const el = knob.node as any;\n      if (el?.style) el.style.cursor = c;\n    };\n    setCursor(\"grab\");\n    knob.attr(\"pointer-events\", \"all\");\n\n    let dragging = false;\n    let startAngle = 0;\n    let pivot = { x: 0, y: 0 };\n    let snapshot: { node: Node; cx: number; cy: number; angle: number }[] = [];\n\n    const pivotScreen = () => {\n      const m = (g.node as any as SVGGraphicsElement).getScreenCTM();\n      if (!m) return { x: 0, y: 0 };\n      return { x: m.a * cx + m.c * cy + m.e, y: m.b * cx + m.d * cy + m.f };\n    };\n\n    const onMove = (e: PointerEvent) => {\n      if (!dragging) return;\n      const cur = Math.atan2(e.clientY - pivot.y, e.clientX - pivot.x);\n      let deltaDeg = ((cur - startAngle) * 180) / Math.PI;\n      if (e.shiftKey) deltaDeg = Math.round(deltaDeg / 15) * 15; // 15° snap\n      const rad = (deltaDeg * Math.PI) / 180;\n      const cos = Math.cos(rad);\n      const sin = Math.sin(rad);\n      snapshot.forEach((s) => {\n        const dx = s.cx - cx;\n        const dy = s.cy - cy;\n        const ncx = cx + dx * cos - dy * sin;\n        const ncy = cy + dx * sin + dy * cos;\n        const w = s.node.options.width || 0;\n        const h = s.node.options.height || 0;\n        const rot = (s.node.options.rotate =\n          s.node.options.rotate || ({} as any));\n        rot.rotationAngle = s.angle + deltaDeg;\n        s.node.position(ncx - w / 2, ncy - h / 2);\n      });\n    };\n\n    const onUp = () => {\n      if (!dragging) return;\n      dragging = false;\n      setCursor(\"grab\");\n      window.removeEventListener(\"pointermove\", onMove);\n      window.removeEventListener(\"pointerup\", onUp);\n      this.broadcast(\"onNodesMove\", {\n        nodeOptions: this.selectedNodes.map((n) => v2NodeToV1(n.options)),\n      });\n      // Redraw the outline to wrap the freshly-rotated group.\n      this.updateSelectionResizeRotate();\n    };\n\n    knob.on(\"pointerdown\", (e: any) => {\n      e.preventDefault?.();\n      e.stopPropagation?.();\n      dragging = true;\n      pivot = pivotScreen();\n      startAngle = Math.atan2(e.clientY - pivot.y, e.clientX - pivot.x);\n      snapshot = this.selectedNodes.map((n) => ({\n        node: n,\n        cx: (n.options.x || 0) + (n.options.width || 0) / 2,\n        cy: (n.options.y || 0) + (n.options.height || 0) / 2,\n        angle: n.options.rotate?.rotationAngle || 0,\n      }));\n      setCursor(\"grabbing\");\n      window.addEventListener(\"pointermove\", onMove);\n      window.addEventListener(\"pointerup\", onUp);\n    });\n    } catch (e) {\n      /* rotate knob is best-effort; selection remains usable without it */\n    }\n  }\n\n  private calculateGroupBoundingBox() {\n    if (this.selectedNodes.length === 0) {\n      return { x: 0, y: 0, width: 100, height: 100 };\n    }\n\n    let minX = Infinity,\n      minY = Infinity,\n      maxX = -Infinity,\n      maxY = -Infinity;\n\n    // Use each node's LOGICAL position/size (options), not svgGroup.bbox() —\n    // bbox() returns the group's *local* box (origin 0,0, ignoring the node's\n    // translate), so the group box collapsed to the canvas origin. Off-screen\n    // there, svg.select.js computed a degenerate screenCTM and emitted a storm\n    // of \"NaN\" polyline-handle errors on every multi-select.\n    // Use each node's ROTATION-AWARE world box so the dashed outline tightly encloses\n    // rotated nodes (a rotated node's option box is smaller than its visual extent).\n    this.selectedNodes.forEach((node) => {\n      const rb = this.rotatedBounds(node);\n      minX = Math.min(minX, rb.minX);\n      minY = Math.min(minY, rb.minY);\n      maxX = Math.max(maxX, rb.maxX);\n      maxY = Math.max(maxY, rb.maxY);\n    });\n\n    return {\n      x: minX,\n      y: minY,\n      width: maxX - minX,\n      height: maxY - minY,\n    };\n  }\n\n  private createGroupHandle(\n    selection: any,\n    point: any,\n    index: number,\n    points: any[]\n  ) {\n    // Create resize handle for the group\n    selection\n      .circle(8)\n      .fill(\"#4a90e2\")\n      .stroke(\"#ffffff\")\n      .attr(\"stroke-width\", 2);\n  }\n\n  private updateGroupHandle(\n    handle: any,\n    point: any,\n    index: number,\n    points: any[]\n  ) {\n    // Update handle position\n    handle.center(point[0], point[1]);\n  }\n\n  private handleGroupResize(event: any) {\n    console.log(\"SELECTION_DEBUG: Group resize event\", event);\n\n    const { box } = event.detail;\n    const originalGroupBBox = this.calculateGroupBoundingBox();\n\n    // Calculate scale factors\n    const scaleX = box.width / originalGroupBBox.width;\n    const scaleY = box.height / originalGroupBBox.height;\n\n    // Apply resize to each selected node\n    this.selectedNodes.forEach((node) => {\n      const nodeBBox = node.svgGroup.bbox();\n\n      // Calculate new position and size relative to group\n      const relativeX = (nodeBBox.x - originalGroupBBox.x) * scaleX;\n      const relativeY = (nodeBBox.y - originalGroupBBox.y) * scaleY;\n      const newWidth = nodeBBox.width * scaleX;\n      const newHeight = nodeBBox.height * scaleY;\n\n      // Apply to node\n      node.setSize(newWidth, newHeight);\n      node.position(box.x + relativeX, box.y + relativeY);\n    });\n  }\n\n  private handleGroupRotate(event: any) {\n    console.log(\"SELECTION_DEBUG: Group rotate event\", event);\n\n    const { angle } = event.detail;\n    const groupBBox = this.calculateGroupBoundingBox();\n    const centerX = groupBBox.x + groupBBox.width / 2;\n    const centerY = groupBBox.y + groupBBox.height / 2;\n\n    // Apply rotation to each selected node around group center\n    this.selectedNodes.forEach((node) => {\n      const currentRotation = node.getRotation();\n      node.setRotation(currentRotation + angle);\n\n      // You might also want to rotate the position around the group center\n      // This would require more complex calculations\n    });\n  }\n\n  /** Select a single node (convenience wrapper for selectNodes). */\n  public selectNode(node: Node) {\n    // Maintain backward compatibility - convert to new selectNodes method\n    this.selectNodes([node], false);\n  }\n\n  /** Deselect a single node. */\n  public deselectNode(node: Node) {\n    if (this.selectedNodes.includes(node)) {\n      console.log(\"SELECTION_DEBUG: Deselecting node\", node.id);\n      this.selectedNodes = this.selectedNodes.filter((n) => n !== node);\n      node.onDeselected();\n\n      // Update group resize/rotate\n      if (this.selectedNodes.length === 0) {\n        this.disableGroupResizeRotate();\n      } else {\n        this.updateSelectionResizeRotate();\n      }\n    }\n  }\n\n  /** Deselect all currently selected nodes. */\n  /** Remove the active line cog + endpoint handles (M1/L1), if any. */\n  public clearLineCog(): void {\n    if (this._activeLineCog) {\n      try {\n        this._activeLineCog.remove();\n      } catch (e) {\n        /* noop */\n      }\n      this._activeLineCog = undefined;\n    }\n    if (this._activeLineConnectable) {\n      try {\n        // Release the pinned endpoint handles so they hide again (Miro-style).\n        (this._activeLineConnectable as any)._handlesPinned = false;\n        (this._activeLineConnectable as any)._revealHandles?.(false);\n        this._activeLineConnectable.deselectConnector?.();\n      } catch (e) {\n        /* noop */\n      }\n      this._activeLineConnectable = undefined;\n    }\n    if (this._activeEndpointToggles) {\n      this._activeEndpointToggles.forEach((g) => {\n        try {\n          g.remove();\n        } catch (e) {\n          /* noop */\n        }\n      });\n      this._activeEndpointToggles = undefined;\n    }\n  }\n\n  public clearSelection() {\n    console.log(\"SELECTION_DEBUG: Clearing selection\");\n\n    // Notify all selected nodes they're being deselected\n    this.selectedNodes.forEach((node) => {\n      node.onDeselected();\n    });\n\n    // Clear the selection array\n    this.selectedNodes = [];\n\n    // Disable all resize/rotate controls and connection handles - CENTRALIZED CONTROL\n    this.updateSelectionResizeRotate();\n\n    // v1 contract: a group selection ending notifies the host with []\n    if (this._hadGroupSelection) {\n      this._hadGroupSelection = false;\n      this.options.events?.onGroupSelection?.([]);\n    }\n  }\n\n  /** @returns Array of currently selected nodes. */\n  public getSelectedNodes(): Node[] {\n    return this.selectedNodes;\n  }\n\n  // Backward compatibility\n  /** @returns The first selected node, or null if none selected. */\n  public getSelectedNode(): Node | null {\n    return this.selectedNodes.length > 0 ? this.selectedNodes[0] : null;\n  }\n\n  /**\n   * Align the selected (or given) nodes to their shared bounding box (Miro-style).\n   * mode: left | centerH | right | top | middle | bottom. Broadcasts onNodesMove\n   * so the change persists + syncs to collab. No-op for < 2 nodes.\n   */\n  /**\n   * Axis-aligned bounding box of a node in WORLD coords, accounting for its\n   * rotation (the four corners rotated about the node's center). Un-rotated → the\n   * option box; rotated → the tight box enclosing the visually-rotated shape. This\n   * is what alignment, distribution and the group-selection outline must use so\n   * rotated nodes line up by what you SEE, not by their un-rotated option box.\n   */\n  private rotatedBounds(node: Node): {\n    minX: number;\n    minY: number;\n    maxX: number;\n    maxY: number;\n  } {\n    const o = node.options;\n    const x = o.x || 0;\n    const y = o.y || 0;\n    const w = o.width || 0;\n    const h = o.height || 0;\n    const angle = o.rotate?.rotationAngle || 0;\n    if (!angle) return { minX: x, minY: y, maxX: x + w, maxY: y + h };\n    const cxp = x + w / 2;\n    const cyp = y + h / 2;\n    const rad = (angle * Math.PI) / 180;\n    const cos = Math.cos(rad);\n    const sin = Math.sin(rad);\n    let minX = Infinity;\n    let minY = Infinity;\n    let maxX = -Infinity;\n    let maxY = -Infinity;\n    const corners: number[][] = [\n      [x, y],\n      [x + w, y],\n      [x + w, y + h],\n      [x, y + h],\n    ];\n    for (const [px, py] of corners) {\n      const dx = px - cxp;\n      const dy = py - cyp;\n      const rx = cxp + dx * cos - dy * sin;\n      const ry = cyp + dx * sin + dy * cos;\n      minX = Math.min(minX, rx);\n      minY = Math.min(minY, ry);\n      maxX = Math.max(maxX, rx);\n      maxY = Math.max(maxY, ry);\n    }\n    return { minX, minY, maxX, maxY };\n  }\n\n  public alignNodes(mode: string, nodes?: Node[]): void {\n    const sel = nodes || this.getSelectedNodes();\n    if (!sel || sel.length < 2) return;\n    // Align by each node's VISUAL (rotation-aware) box, and move via a DELTA on the\n    // node's own option position so its rotation is preserved. Aligning raw options.x\n    // made rotated nodes' visual edges disagree with the rest (they \"don't line up\").\n    const b = sel.map((n) => {\n      const rb = this.rotatedBounds(n);\n      return {\n        n,\n        minX: rb.minX,\n        maxX: rb.maxX,\n        minY: rb.minY,\n        maxY: rb.maxY,\n        cx: (rb.minX + rb.maxX) / 2,\n        cy: (rb.minY + rb.maxY) / 2,\n        ox: n.options.x || 0,\n        oy: n.options.y || 0,\n      };\n    });\n    const gMinX = Math.min(...b.map((o) => o.minX));\n    const gMaxX = Math.max(...b.map((o) => o.maxX));\n    const gMinY = Math.min(...b.map((o) => o.minY));\n    const gMaxY = Math.max(...b.map((o) => o.maxY));\n    const gcx = (gMinX + gMaxX) / 2;\n    const gcy = (gMinY + gMaxY) / 2;\n    for (const o of b) {\n      let x = o.ox;\n      let y = o.oy;\n      switch (mode) {\n        case \"left\": x = o.ox + (gMinX - o.minX); break;\n        case \"right\": x = o.ox + (gMaxX - o.maxX); break;\n        case \"centerH\": x = o.ox + (gcx - o.cx); break;\n        case \"top\": y = o.oy + (gMinY - o.minY); break;\n        case \"bottom\": y = o.oy + (gMaxY - o.maxY); break;\n        case \"middle\": y = o.oy + (gcy - o.cy); break;\n        default: return;\n      }\n      o.n.position(x, y);\n    }\n    this.broadcast(\"onNodesMove\", {\n      nodeOptions: sel.map((n) => v2NodeToV1(n.options)),\n    });\n    // The nodes moved — refresh the selection UI so the dashed group outline (and the\n    // per-node handles) re-wrap the NEW positions. Without this the outline kept its\n    // stale pre-align extent, making aligned nodes look like they'd moved \"to the\n    // center\" of a too-wide box.\n    this.updateSelectionResizeRotate();\n  }\n\n  /**\n   * Evenly distribute the selected (or given) nodes along an axis so the gaps\n   * between them are equal; the outermost two stay put. axis: horizontal |\n   * vertical. Broadcasts onNodesMove. No-op for < 3 nodes.\n   */\n  public distributeNodes(axis: string, nodes?: Node[]): void {\n    const sel = nodes || this.getSelectedNodes();\n    if (!sel || sel.length < 3) return;\n    // Distribute by each node's VISUAL (rotation-aware) box; move via an option\n    // DELTA so rotation is preserved and the gaps you SEE come out equal.\n    const b = sel.map((n) => {\n      const rb = this.rotatedBounds(n);\n      return {\n        n,\n        minX: rb.minX,\n        maxX: rb.maxX,\n        minY: rb.minY,\n        maxY: rb.maxY,\n        w: rb.maxX - rb.minX,\n        h: rb.maxY - rb.minY,\n        ox: n.options.x || 0,\n        oy: n.options.y || 0,\n      };\n    });\n    if (axis === \"horizontal\") {\n      b.sort((p, q) => p.minX - q.minX);\n      const left = b[0].minX;\n      const right = b[b.length - 1].maxX;\n      const totalW = b.reduce((s, o) => s + o.w, 0);\n      const gap = (right - left - totalW) / (b.length - 1);\n      let cursor = left;\n      for (const o of b) {\n        o.n.position(o.ox + (cursor - o.minX), o.oy);\n        cursor += o.w + gap;\n      }\n    } else if (axis === \"vertical\") {\n      b.sort((p, q) => p.minY - q.minY);\n      const top = b[0].minY;\n      const bottom = b[b.length - 1].maxY;\n      const totalH = b.reduce((s, o) => s + o.h, 0);\n      const gap = (bottom - top - totalH) / (b.length - 1);\n      let cursor = top;\n      for (const o of b) {\n        o.n.position(o.ox, o.oy + (cursor - o.minY));\n        cursor += o.h + gap;\n      }\n    } else {\n      return;\n    }\n    this.broadcast(\"onNodesMove\", {\n      nodeOptions: sel.map((n) => v2NodeToV1(n.options)),\n    });\n    // The nodes moved — refresh the selection UI so the dashed group outline (and the\n    // per-node handles) re-wrap the NEW positions. Without this the outline kept its\n    // stale pre-align extent, making aligned nodes look like they'd moved \"to the\n    // center\" of a too-wide box.\n    this.updateSelectionResizeRotate();\n  }\n\n  // ─── Grouping (Miro-style) ──────────────────────────────────────────\n  //\n  // A group is simply a set of nodes sharing a `groupId`. There is NO reparenting:\n  // nodes stay in the canvas, so connectors/serialization are untouched. Group\n  // behaviour is layered on the existing multi-selection machinery — selecting a\n  // member selects all members, and drag/rotate/lock then act on the whole set.\n\n  /** All nodes belonging to the given groupId (empty if none/falsy). */\n  public getGroupMembers(groupId: string | null | undefined): Node[] {\n    if (!groupId) return [];\n    return this.nodes.allNodes.filter(\n      (n) => (n.options.groupId as string) === groupId\n    );\n  }\n\n  /** The groupId of a node, or null if it isn't grouped. */\n  public getGroupIdOf(node: Node): string | null {\n    return (node?.options?.groupId as string) || null;\n  }\n\n  /** True if the node is a member of any group. */\n  public isGrouped(node: Node): boolean {\n    return !!this.getGroupIdOf(node);\n  }\n\n  /** The groupId currently entered for member editing, or null. */\n  public getEnteredGroupId(): string | null {\n    return this.enteredGroupId;\n  }\n\n  /**\n   * Expand a node list to include every group-mate of any grouped node in it\n   * (deduped, order-stable). Used so lock/rotate/etc. apply to whole groups.\n   */\n  private expandToGroups(nodes: Node[]): Node[] {\n    const out = new Map<string, Node>();\n    nodes.forEach((n) => {\n      out.set(n.id, n);\n      const g = this.getGroupIdOf(n);\n      if (g) this.getGroupMembers(g).forEach((m) => out.set(m.id, m));\n    });\n    return [...out.values()];\n  }\n\n  /**\n   * Group the selected (or given) nodes into ONE group so they select/move/rotate/\n   * lock as a unit. Assigns a fresh groupId to every member (flattening any prior\n   * groups in the selection into the new one, Miro-style). Persists via onNodesMove\n   * and re-selects the whole new group. No-op for < 2 nodes.\n   * @returns the new groupId, or null if nothing was grouped.\n   */\n  public groupNodes(nodes?: Node[]): string | null {\n    const sel = (nodes || this.getSelectedNodes()).slice();\n    if (sel.length < 2) return null;\n    const gid = \"grp-\" + guid(8);\n    sel.forEach((n) => {\n      n.options.groupId = gid;\n    });\n    this.enteredGroupId = null;\n    this.broadcast(\"onNodesMove\", {\n      nodeOptions: sel.map((n) => v2NodeToV1(n.options)),\n    });\n    // Re-select as a group (single outline, no per-node handles).\n    this.selectNodes(sel);\n    return gid;\n  }\n\n  /**\n   * Ungroup: dissolve every group represented in the selected (or given) nodes by\n   * clearing each member's groupId. Persists and keeps the nodes multi-selected.\n   */\n  public ungroupNodes(nodes?: Node[]): void {\n    const sel = nodes || this.getSelectedNodes();\n    const gids = new Set<string>();\n    sel.forEach((n) => {\n      const g = this.getGroupIdOf(n);\n      if (g) gids.add(g);\n    });\n    if (!gids.size) return;\n    const affected: Node[] = [];\n    gids.forEach((g) => {\n      this.getGroupMembers(g).forEach((m) => {\n        m.options.groupId = undefined;\n        affected.push(m);\n      });\n    });\n    this.enteredGroupId = null;\n    this.broadcast(\"onNodesMove\", {\n      // Use an explicit null tombstone in the collaboration package. JSON/Yjs\n      // transports may omit `undefined`, which would leave peers in the old\n      // group forever instead of clearing it.\n      nodeOptions: affected.map((n) => ({\n        ...v2NodeToV1(n.options),\n        groupId: null,\n      })),\n    });\n    this.selectNodes(affected);\n  }\n\n  /**\n   * Lock the selected (or given) nodes — and, for any grouped node, its whole\n   * group — disabling drag/resize. Persists via onNodesMove.\n   */\n  public lockNodes(nodes?: Node[]): void {\n    const targets = this.expandToGroups(nodes || this.getSelectedNodes());\n    if (!targets.length) return;\n    targets.forEach((n) => n.lock());\n    this.broadcast(\"onNodesMove\", {\n      nodeOptions: targets.map((n) => v2NodeToV1(n.options)),\n    });\n    this.updateSelectionResizeRotate();\n  }\n\n  /** Unlock the selected (or given) nodes and their groups. */\n  public unlockNodes(nodes?: Node[]): void {\n    const targets = this.expandToGroups(nodes || this.getSelectedNodes());\n    if (!targets.length) return;\n    targets.forEach((n) => n.unlock());\n    this.broadcast(\"onNodesMove\", {\n      nodeOptions: targets.map((n) => v2NodeToV1(n.options)),\n    });\n    this.updateSelectionResizeRotate();\n  }\n\n  /** True if every given (or selected) node is locked. */\n  public isSelectionLocked(nodes?: Node[]): boolean {\n    const t = nodes || this.getSelectedNodes();\n    return t.length > 0 && t.every((n) => !!n.options.isLocked);\n  }\n\n  /**\n   * Enter a group for individual-member editing (Miro double-click-into-group).\n   * Selects `member` if given, else the first member. While entered, clicking a\n   * member selects just that member instead of the whole group.\n   */\n  public enterGroup(groupId: string, member?: Node): void {\n    const members = this.getGroupMembers(groupId);\n    if (!members.length) return;\n    this.enteredGroupId = groupId;\n    this.selectNodes([member && members.includes(member) ? member : members[0]]);\n  }\n\n  /** Exit the currently-entered group and re-select it as a whole. */\n  public exitGroup(): void {\n    const gid = this.enteredGroupId;\n    this.enteredGroupId = null;\n    if (!gid) return;\n    const members = this.getGroupMembers(gid);\n    if (members.length) this.selectNodes(members);\n  }\n\n  // ─── Serialization API ──────────────────────────────────────────────\n\n  /**\n   * Export the slate to a JSON string in v1-compatible format.\n   *\n   * @param nodes - Optional subset of nodes to include\n   * @param asPresentation - If true, includes presentation ordering\n   * @returns JSON string\n   */\n  public exportJSON(nodes?: Node[], asPresentation?: boolean): string {\n    const json = serialize(this, nodes, asPresentation);\n    return JSON.stringify(json);\n  }\n\n  /**\n   * Load a v1-compatible JSON string or object into this slate.\n   *\n   * @param json - JSON string or SlateJSON object\n   * @param preserve - If true, merge with existing nodes instead of replacing\n   * @param skipZoom - If true, don't adjust zoom/pan after load\n   * @param useMainCanvas - Reserved for future use\n   */\n  public async loadJSON(\n    json: string | SlateJSON,\n    preserve: boolean = false,\n    skipZoom: boolean = false,\n    useMainCanvas?: boolean\n  ): Promise<void> {\n    await deserialize(json, this, preserve, skipZoom);\n    // Baseline snapshot of the loaded document so the first edit is undoable.\n    this.undoRedo?.clear?.();\n    this.undoRedo?.snap?.(true);\n  }\n\n  /**\n   * Take a snapshot of the current slate state.\n   * Used by undo/redo system.\n   *\n   * @returns SlateJSON object (not stringified)\n   */\n  public snapshot(): SlateJSON {\n    return takeSnapshot(this);\n  }\n\n  // ─── Export API ─────────────────────────────────────────────────\n\n  /**\n   * Export the slate as an SVG string.\n   */\n  public svg(\n    opts?: ExportOptions,\n    callback?: (svg: string) => void\n  ): string {\n    return exportSVG(this, opts, callback);\n  }\n\n  /**\n   * Export the slate as a PNG (async).\n   */\n  public async png(\n    opts?: ExportOptions,\n    callback?: (result: string | Blob) => void\n  ): Promise<string | Blob> {\n    return exportPNG(this, opts, callback);\n  }\n\n  /**\n   * Synchronous-style PNG export (returns a Promise).\n   * Alias for png() for v1 compatibility.\n   */\n  public pngSync(opts?: ExportOptions): Promise<string | Blob> {\n    return this.png(opts);\n  }\n\n  // ─── Theme API ──────────────────────────────────────────────────\n\n  /** Apply a theme to this slate */\n  public applyTheme(\n    theme: ThemeDefinition,\n    syncWithTheme?: boolean,\n    revertTheme?: boolean\n  ): void {\n    applyTheme(this, theme, syncWithTheme, revertTheme);\n  }\n\n  // ─── Layout API ─────────────────────────────────────────────────\n\n  /** Remove overlapping nodes by pushing them apart */\n  public removeLayoutOverlaps(\n    enableAttraction?: boolean,\n    threshold?: number\n  ): void {\n    removeLayoutOverlaps(this, enableAttraction, threshold);\n  }\n\n  /** Apply pre-computed layout moves */\n  public applyLayout(\n    moves: LayoutMove[],\n    cb?: () => void,\n    noAnimation?: boolean\n  ): void {\n    applyLayoutMoves(this, moves, cb, noAnimation);\n  }\n\n  /** Package current node positions for layout transfer */\n  public packageLayout(): LayoutMove[] {\n    return packageLayout(this);\n  }\n\n  // ─── Lock display API ───────────────────────────────────────────\n\n  /** Show lock icons on all locked nodes */\n  public displayLocks(): void {\n    this.nodes.allNodes.forEach((node: Node) => {\n      if (node.options.isLocked) {\n        // Visual lock indicator could be added here\n        console.log(\"LOCK_DEBUG: Displaying lock for\", node.id);\n      }\n    });\n  }\n\n  /** Hide all lock icons */\n  public hideLocks(): void {\n    console.log(\"LOCK_DEBUG: Hiding all locks\");\n  }\n\n  // ─── Font loading ───────────────────────────────────────────────\n\n  /** Load all fonts used by nodes in this slate */\n  public async loadAllFonts(): Promise<void> {\n    await loadAllFontsForSlate(this);\n  }\n}\n","/**\n * Comments.ts - Comment node type support\n *\n * Comments are special nodes with isComment=true.\n * Provides creation/deletion and integration with collab events.\n */\n\nexport interface CommentOptions {\n  text: string;\n  x?: number;\n  y?: number;\n  author?: string;\n  timestamp?: number;\n}\n\n/**\n * Create a comment node on the slate.\n */\nexport function createComment(\n  slate: any,\n  options: CommentOptions\n): any {\n  const node = slate.addNode({\n    text: options.text,\n    x: options.x || 100,\n    y: options.y || 100,\n    width: 150,\n    height: 80,\n    backgroundColor: \"#fffde7\",\n    borderColor: \"#ffd54f\",\n    borderWidth: 1,\n    fontColor: \"#333\",\n    fontSize: 12,\n    isComment: true,\n    showDelete: true,\n    showAdd: false,\n    showResize: true,\n    showRotate: false,\n    showMenu: false,\n    allowResize: true,\n    // Author/timestamp must be part of the node at creation so they're carried\n    // by the onNodeAdded broadcast + the save. Setting them AFTER addNode left\n    // them out of the persisted state, so they were lost on reload.\n    commentAuthor: options.author,\n    commentTimestamp: options.timestamp || Date.now(),\n  });\n\n  return node;\n}\n\n/**\n * Remove a comment node from the slate.\n */\nexport function removeComment(\n  slate: any,\n  nodeId: string\n): boolean {\n  const node = slate.nodes.one(nodeId);\n  if (!node || !node.options.isComment) {\n    return false;\n  }\n  return slate.removeNode(nodeId);\n}\n\n/**\n * Get all comment nodes on the slate.\n */\nexport function getComments(slate: any): any[] {\n  return slate.nodes.allNodes.filter(\n    (n: any) => n.options.isComment === true\n  );\n}\n","/**\n * compat-facade.ts — v1 runtime API facade\n *\n * Lets code written against the Raphael-era `slateboxjs` package\n * (`import { Slatebox } from 'slateboxjs'` → `new Slatebox.slate(options, events).init()`)\n * run on the v2 engine without changes. This module is the migration layer:\n * it wraps the modern v2 classes (`Slate`, `Node`, …) rather than modifying\n * their public APIs.\n *\n * Scope covered here (see docs/drop-in-contract.md):\n *  §A — namespace shape: `Slatebox.slate`, `Slatebox.node`, `Slatebox.base`,\n *        `Slatebox.utils`, plus the `window.Slatebox` global (wired in index.ts)\n *  §B (partial) — `(options, events)` constructor signature, `container`\n *        resolution by element id, async `.init()` resolving to the slate\n *  §C (partial) — `nodes.add/addRange/one/allNodes`, `exportJSON/loadJSON`\n *\n * Deeper option/event wiring, layout/canvas/controller methods and collab\n * bridging are tracked as separate contract items.\n */\n\nimport { Slate } from \"./core/Slate\";\nimport type { Node as V2Node, NodeOptions } from \"./core/Node\";\nimport * as utilsModule from \"./utils\";\nimport { v1NodeToV2, v1SlateToV2, v2NodeToV1 } from \"./core/compat\";\nimport { getAvailableFilters } from \"./core/Filters\";\nimport { getAvailableAnimations, type AnimationDef } from \"./core/Animations\";\n\n/** v1-style events object passed as the 2nd constructor argument. */\nexport type V1Events = Record<string, ((...args: any[]) => any) | undefined>;\n\n/**\n * v1-style node: constructed standalone (no slate required) and later\n * attached via `slate.nodes.add(node)`. Keeps its v1-shaped `options`\n * object; once added, `v2` points at the live v2 Node.\n */\nclass node {\n  /**\n   * Live v1-shaped options (xPos/yPos/foregroundColor/…). Before attachment\n   * the proxy behaves like a plain object. Once attached, reads reflect the\n   * current v2 NodeOptions and writes update both the v1 view and v2 model.\n   */\n  public options: Record<string, any>;\n\n  private optionState: Record<string, any>;\n\n  /** The live v2 node once this wrapper has been added to a slate. */\n  public v2?: V2Node;\n\n  /** Back-reference to the owning facade slate (set on add, like v1). */\n  public slate?: slate;\n\n  /** v1: `node.resize.set(w, h)` then `node.resize.send()` */\n  public resize: NodeResizeFacade;\n\n  /** v1: `node.relationships.addAssociation(otherNode)` / `.associations` */\n  public relationships: NodeRelationshipsFacade;\n\n  constructor(options: Record<string, any> = {}) {\n    this.optionState = { id: utilsModule.guid(), ...options };\n    this.options = new Proxy(this.optionState, {\n      get: (target, property, receiver) => {\n        if (typeof property !== \"string\" || !this.v2) {\n          return Reflect.get(target, property, receiver);\n        }\n        const live = v2NodeToV1(this.v2.options || {});\n        return Object.prototype.hasOwnProperty.call(live, property)\n          ? live[property]\n          : Reflect.get(target, property, receiver);\n      },\n      set: (target, property, value, receiver) => {\n        const written = Reflect.set(target, property, value, receiver);\n        if (written && typeof property === \"string\" && this.v2) {\n          Object.assign(this.v2.options, v1NodeToV2({ [property]: value }));\n        }\n        return written;\n      },\n      deleteProperty: (target, property) => {\n        const deleted = Reflect.deleteProperty(target, property);\n        if (deleted && typeof property === \"string\" && this.v2) {\n          const v2Property =\n            {\n              xPos: \"x\",\n              yPos: \"y\",\n              foregroundColor: \"fontColor\",\n              shapeHint: \"shape\",\n              svgString: \"svgContent\",\n            }[property] || property;\n          delete (this.v2.options as Record<string, any>)[v2Property];\n        }\n        return deleted;\n      },\n      ownKeys: (target) => {\n        if (!this.v2) return Reflect.ownKeys(target);\n        const liveKeys = Reflect.ownKeys(v2NodeToV1(this.v2.options || {}));\n        return Array.from(new Set([...Reflect.ownKeys(target), ...liveKeys]));\n      },\n      getOwnPropertyDescriptor: (target, property) => {\n        const existing = Reflect.getOwnPropertyDescriptor(target, property);\n        if (existing || !this.v2 || typeof property !== \"string\") {\n          return existing;\n        }\n        const live = v2NodeToV1(this.v2.options || {});\n        if (Object.prototype.hasOwnProperty.call(live, property)) {\n          return { configurable: true, enumerable: true, writable: true };\n        }\n        return undefined;\n      },\n    });\n    this.resize = new NodeResizeFacade(this);\n    this.relationships = new NodeRelationshipsFacade(this);\n  }\n\n  /**\n   * v1: `node.png(withNodes?, cb)` — export this node (or the given group of\n   * node ids) as a transparent-background PNG blob.\n   */\n  public png(\n    withNodes: string[] | ((blob: Blob) => void) | undefined,\n    cb?: (blob: Blob) => void,\n  ): void {\n    // v1 allows node.png(cb) with the group omitted\n    const callback = typeof withNodes === \"function\" ? withNodes : cb;\n    const group = Array.isArray(withNodes) ? withNodes : undefined;\n    const v2Node = this.v2;\n    if (!v2Node || !callback) return;\n    const nodes = group && group.length > 0 ? group : [v2Node.id];\n    (v2Node.slate as any).png(\n      { nodes, noBackground: true, asBinary: true },\n      (blob: any) => callback(blob),\n    );\n  }\n\n  /** v1: `node.svg(withNodes?, cb)` — same as png but returns the SVG string. */\n  public svg(\n    withNodes: string[] | ((svg: string) => void) | undefined,\n    cb?: (svg: string) => void,\n  ): void {\n    const callback = typeof withNodes === \"function\" ? withNodes : cb;\n    const group = Array.isArray(withNodes) ? withNodes : undefined;\n    const v2Node = this.v2;\n    if (!v2Node || !callback) return;\n    const nodes = group && group.length > 0 ? group : [v2Node.id];\n    (v2Node.slate as any).svg({ nodes, noBackground: true }, (svg: string) =>\n      callback(svg),\n    );\n  }\n\n  /**\n   * v1 API: position the node. `position('center')` centers it in the current\n   * viewport (used right after adding a node from the shape palette);\n   * `position({x, y})` / `position(x, y)` sets an explicit position. Before the\n   * node is added (no v2 yet) this just stashes coordinates on options.\n   */\n  public position(coords?: any, maybeY?: number): this {\n    const v2: any = this.v2;\n    // Explicit coordinates (object or x,y pair).\n    const explicit =\n      coords && typeof coords === \"object\"\n        ? { x: coords.x, y: coords.y }\n        : typeof coords === \"number\"\n          ? { x: coords, y: maybeY }\n          : null;\n\n    if (!v2) {\n      if (explicit) {\n        this.options.x = explicit.x;\n        this.options.y = explicit.y;\n      }\n      return this;\n    }\n\n    if (explicit && explicit.x != null && explicit.y != null) {\n      v2.position(explicit.x, explicit.y);\n      return this;\n    }\n\n    // 'center' (or no args): center the node in the current viewport.\n    try {\n      const svgEl: any = (v2.slate as any)?.canvas?.node;\n      const vb = svgEl?.getAttribute?.(\"viewBox\");\n      if (vb) {\n        const p = String(vb)\n          .split(/[\\s,]+/)\n          .map(Number);\n        if (p.length === 4 && p.every((n) => !isNaN(n))) {\n          const cx = p[0] + p[2] / 2;\n          const cy = p[1] + p[3] / 2;\n          const w = v2.options.width || 0;\n          const h = v2.options.height || 0;\n          v2.position(cx - w / 2, cy - h / 2);\n        }\n      }\n    } catch (e) {\n      /* noop — centering is a nicety, never fatal */\n    }\n    return this;\n  }\n}\n\n/**\n * v1 resize sub-object: `set()` stages new dimensions, `send()` applies them\n * (v1 additionally broadcast to collab; broadcasting is the host app's job\n * via the packages it already sends).\n */\nclass NodeResizeFacade {\n  private owner: node;\n  private pending?: { width: number; height: number };\n\n  constructor(owner: node) {\n    this.owner = owner;\n  }\n\n  public set(width: number, height: number): void {\n    this.pending = { width, height };\n    this.owner.options.width = width;\n    this.owner.options.height = height;\n    // v1 applied the size immediately on set(); send() finalized/broadcast\n    this.owner.v2?.setSize(width, height);\n  }\n\n  public send(): void {\n    if (!this.pending || !this.owner.v2) return;\n    const v2Node = this.owner.v2;\n    v2Node.setSize(this.pending.width, this.pending.height);\n    // v1: send() broadcasts the resize as an onNodeResized package\n    (v2Node.slate as any)?.emitSlateChange?.(\"onNodeResized\", {\n      id: v2Node.id,\n      width: this.pending.width,\n      height: this.pending.height,\n      rotate: (v2Node.options as any).rotate,\n      vectorPath: (v2Node.options as any).vectorPath,\n      associations: (\n        (v2Node as any).relationships?.getAssociations?.() ?? []\n      ).map((a: any) => ({\n        parentId: a.parentId,\n        childId: a.childId,\n        linePath: \"\",\n      })),\n    });\n    this.pending = undefined;\n  }\n}\n\n/**\n * v1 relationships sub-object. v1 exposed `.associations` as an array whose\n * entries carry live `parent`/`child` node references (the Meteor app reads\n * `a.parent.options.id`); v2 stores plain id-based Association records.\n */\nclass NodeRelationshipsFacade {\n  private owner: node;\n\n  constructor(owner: node) {\n    this.owner = owner;\n  }\n\n  /** v1: `node.relationships.addAssociation(childNode, data?)` */\n  public addAssociation(child: node | V2Node, data?: Record<string, any>) {\n    if (!this.owner.v2) {\n      throw new Error(\n        \"SLATEBOX_COMPAT: add the node to a slate before creating associations\",\n      );\n    }\n    const childV2 = child instanceof node ? child.v2 : child;\n    if (!childV2) {\n      throw new Error(\n        \"SLATEBOX_COMPAT: child node must be added to the slate first\",\n      );\n    }\n    return (this.owner.v2 as any).relationships?.addAssociation(childV2, data);\n  }\n\n  /** v1: `.associations` — array with live parent/child wrapper references */\n  public get associations(): Array<Record<string, any>> {\n    const v2Node = this.owner.v2;\n    const slateFacade = this.owner.slate;\n    if (!v2Node || !slateFacade) return [];\n    const list =\n      (v2Node as any).relationships?.getAssociations?.() ?? ([] as any[]);\n    return list.map((a: any) => ({\n      ...a,\n      parent: slateFacade.nodes.one(a.parentId),\n      child: slateFacade.nodes.one(a.childId),\n    }));\n  }\n}\n\n/**\n * Facade over the v2 NodesManager exposing the v1 `slate.nodes` surface.\n * v1 takes node INSTANCES (`nodes.add(new Slatebox.node({...}))`) while v2's\n * manager takes plain options — this adapter accepts both.\n */\nclass NodesFacade {\n  private owner: slate;\n  private wrappers = new Map<string, node>();\n\n  constructor(owner: slate) {\n    this.owner = owner;\n  }\n\n  private get v2Slate(): Slate {\n    if (!this.owner.v2) {\n      throw new Error(\n        \"SLATEBOX_COMPAT: slate.init() must complete before using slate.nodes\",\n      );\n    }\n    return this.owner.v2;\n  }\n\n  /** v1: `slate.nodes.add(nodeInstance)` — also accepts a plain options object. */\n  public add(n: node | Record<string, any>): node {\n    const wrapper = n instanceof node ? n : new node(n);\n    const v2Options = v1NodeToV2(wrapper.options) as Partial<NodeOptions>;\n    // Route through Slate.addNode (not NodesManager directly) so host-facing\n    // side effects fire: onSlateChanged emission, BirdsEye refresh, a11y announce\n    const v2Node = this.v2Slate.addNode(v2Options);\n    wrapper.v2 = v2Node;\n    wrapper.slate = this.owner;\n    this.wrappers.set(v2Node.id, wrapper);\n    return wrapper;\n  }\n\n  /** v1: `slate.nodes.addRange([...])` */\n  public addRange(list: Array<node | Record<string, any>>): node[] {\n    return (list || []).map((n) => this.add(n));\n  }\n\n  /** v1: `slate.nodes.one(id)` → node (or undefined) */\n  public one(id: string): node | undefined {\n    const v2Node = this.v2Slate.nodes.one(id);\n    if (!v2Node) return undefined;\n    return this.wrap(v2Node);\n  }\n\n  /** v1: `slate.nodes.allNodes` → array property */\n  public get allNodes(): node[] {\n    return this.v2Slate.nodes.allNodes.map((n) => this.wrap(n));\n  }\n\n  /**\n   * v1: `slate.nodes.packageLayout()` — payload sent to the server-side\n   * layout calculator: `{layoutType, associations, nodes, uniqueIds, subgraphs}`.\n   */\n  public packageLayout(): Record<string, any> {\n    const v2 = this.v2Slate;\n    const all = v2.nodes.allNodes;\n    const associations: Array<Record<string, any>> = [];\n    const nodes: Record<string, any> = {};\n    const subgraphs: Record<string, string[]> = {};\n\n    all.forEach((nx: any) => {\n      const opts = nx.options || {};\n      const v1Opts = v2NodeToV1(opts);\n      (nx.relationships?.getAssociations?.() ?? []).forEach((a: any) => {\n        associations.push({\n          parentId: a.parentId,\n          childId: a.childId,\n          lineWidth: a.lineWidth,\n          lineType: a.lineType,\n          lineCurveType: a.lineCurveType,\n          lineCurviness: a.lineCurviness,\n          lineOpacity: a.lineOpacity,\n          showParentArrow: a.showParentArrow,\n          showChildArrow: a.showChildArrow,\n        });\n      });\n      if (!nodes[nx.id]) {\n        nodes[nx.id] = {\n          width: +(opts.width || 0),\n          height: +(opts.height || 0),\n          shape: v1Opts.shapeHint || opts.shape || \"rect\",\n          color: opts.backgroundColor,\n          textColor: v1Opts.foregroundColor ?? opts.fontColor,\n          text: opts.text,\n          groupId: opts.groupId ?? null,\n        };\n      }\n      const gid = String(opts.groupId ?? \"null\");\n      if (!subgraphs[gid]) subgraphs[gid] = [];\n      subgraphs[gid].push(nx.id);\n    });\n\n    return {\n      layoutType: this.owner.options.layoutType,\n      associations,\n      nodes,\n      uniqueIds: Object.keys(nodes),\n      subgraphs,\n    };\n  }\n\n  /**\n   * v1: `slate.nodes.applyLayout(layout, cbOrOpts?)` — layout is the server\n   * response `{exportNodes: {id: {x, y}}}` with stringly coordinates.\n   */\n  public applyLayout(\n    layout: Record<string, any>,\n    cbOrOpts?: (() => void) | { skipCenter?: boolean },\n  ): void {\n    const v2 = this.v2Slate;\n    const exportNodes = layout?.exportNodes || {};\n    const cb = typeof cbOrOpts === \"function\" ? cbOrOpts : undefined;\n    const opts = typeof cbOrOpts === \"object\" ? cbOrOpts : {};\n\n    const moves = Object.keys(exportNodes)\n      .filter((id) => v2.nodes.one(id))\n      .map((id) => ({\n        id,\n        x: parseFloat(exportNodes[id].x),\n        y: parseFloat(exportNodes[id].y),\n      }));\n    v2.applyLayout(moves, cb);\n    if (!opts.skipCenter) {\n      v2.centerContent();\n    }\n  }\n\n  /**\n   * v1: `slate.nodes.nodeMovePackage({dur, moves: [{id, x: dx, y: dy}]})` —\n   * moves are RELATIVE deltas; the returned package carries the resulting\n   * ABSOLUTE positions in v1 shape, ready for `collab.exe({type:'onNodesMove'})`.\n   */\n  public nodeMovePackage(\n    opts: {\n      dur?: number;\n      easing?: string;\n      moves?: Array<{ id: string; x: number; y: number }>;\n      nodes?: Array<node | V2Node>;\n    } = {},\n  ): Record<string, any> {\n    const v2 = this.v2Slate;\n    const deltas = new Map((opts.moves || []).map((m) => [m.id, m] as const));\n    const targets: any[] = opts.nodes\n      ? opts.nodes.map((n) => (n instanceof node ? n.v2 : n)).filter(Boolean)\n      : opts.moves\n        ? (opts.moves.map((m) => v2.nodes.one(m.id)).filter(Boolean) as any[])\n        : v2.nodes.allNodes;\n\n    return {\n      dur: opts.dur ?? 300,\n      easing: opts.easing ?? \">\",\n      textPositions: targets.map((nx: any) => ({\n        id: nx.id,\n        textPosition: { x: 0, y: 0, transform: \"\" },\n      })),\n      nodeOptions: targets.map((nx: any) => {\n        const delta = deltas.get(nx.id);\n        const v1Opts = v2NodeToV1(nx.options || {});\n        return {\n          id: nx.id,\n          vectorPath: v1Opts.vectorPath,\n          xPos: (v1Opts.xPos ?? 0) + (delta?.x ?? 0),\n          yPos: (v1Opts.yPos ?? 0) + (delta?.y ?? 0),\n        };\n      }),\n      associations: targets.flatMap((nx: any) =>\n        (nx.relationships?.getAssociations?.() ?? []).map((a: any) => ({\n          parentId: a.parentId,\n          childId: a.childId,\n          linePath: \"\",\n          id: a.id,\n        })),\n      ),\n    };\n  }\n\n  /**\n   * Return the stable wrapper for a v2 node, creating one lazily for nodes\n   * that came into existence outside this facade (e.g. loadJSON).\n   */\n  private wrap(v2Node: V2Node): node {\n    let wrapper = this.wrappers.get(v2Node.id);\n    if (!wrapper) {\n      wrapper = new node({ ...(v2Node.options as Record<string, any>) });\n      wrapper.options.id = v2Node.id;\n      this.wrappers.set(v2Node.id, wrapper);\n    }\n    // loadJSON() replaces the engine's Node instances while preserving their\n    // ids. Keep the stable v1 wrapper identity, but always bind it to the live\n    // v2 node so post-load moves and relationships serialize correctly.\n    wrapper.v2 = v2Node;\n    wrapper.slate = this.owner;\n    return wrapper;\n  }\n}\n\n/**\n * v1-style slate: `const s = await new Slatebox.slate(options, events).init()`.\n *\n * v1 differences bridged here:\n *  - constructor takes `(options, events)`; v2 takes `(element, options)`\n *  - `options.container` is an element ID string (e.g. \"slateCanvas\"); v2\n *    wants the element (or a CSS selector)\n *  - `.init()` is async and resolves to the slate itself\n */\nclass slate {\n  public options: Record<string, any>;\n  public events: V1Events;\n  public nodes: NodesFacade;\n\n  /** The live v2 Slate once init() has run. */\n  public v2?: Slate;\n\n  private _shareId: string;\n  public userId?: string;\n  public orgId?: string;\n\n  /**\n   * v1: hosts assign `slate.shareId = X` AFTER init (createSlate.js does) and\n   * expect it to persist through exportJSON. Route writes into the live v2\n   * options (which serialization reads) once available.\n   */\n  public get shareId(): string {\n    return (\n      ((this.v2 as any)?.options?.shareId as string | undefined) ??\n      this._shareId\n    );\n  }\n\n  public set shareId(value: string) {\n    this._shareId = value;\n    if (this.v2) {\n      (this.v2 as any).options.shareId = value;\n    }\n  }\n\n  /** v1: `slate.savingTemplateImage` — host-managed re-entrancy flag */\n  public savingTemplateImage = false;\n\n  /** v1: `slate.controller.scaleToFitAndCenter(cb?, dur?)` */\n  public controller: {\n    scaleToFitAndCenter: (cb?: () => void, dur?: number) => void;\n  };\n\n  /** v1: `slate.canvas.hideBg(opacity?)` — clear background for snapshots */\n  public canvas: { hideBg: (opacity?: number) => void };\n\n  /** The step-through presentation controller (start/next/previous/stop). */\n  public get presentation(): any {\n    return this.v2?.presentation;\n  }\n\n  constructor(options: Record<string, any> = {}, events: V1Events = {}) {\n    // Spread FIRST: hosts pass `id: undefined` for new slates, and spreading\n    // after the default would clobber the generated guid with undefined —\n    // losing the id the URL/persistence layer expects.\n    this.options = {\n      ...options,\n      id: options.id || utilsModule.guid(),\n    };\n    this.events = events || {};\n    this._shareId = this.options.shareId || utilsModule.guid();\n    this.nodes = new NodesFacade(this);\n\n    this.controller = {\n      scaleToFitAndCenter: (cb?: () => void) => {\n        this.assertReady();\n        // fitToContent() already frames AND centers on the node bounds.\n        // Do NOT also call centerContent() — it centers on the whole-SVG\n        // bbox (contaminated by marker/def elements near origin) and would\n        // yank the view off the content.\n        this.v2!.fitToContent();\n        cb?.();\n      },\n    };\n\n    this.canvas = {\n      hideBg: () => {\n        this.assertReady();\n        const el = (this.v2 as any).element as HTMLElement | undefined;\n        if (el) {\n          el.style.backgroundColor = \"transparent\";\n          el.style.backgroundImage = \"none\";\n        }\n      },\n    };\n  }\n\n  /** Resolve v1 `options.container` (id string or element) to an HTMLElement. */\n  private resolveContainer(): HTMLElement {\n    const container = this.options.container;\n    if (container && typeof container !== \"string\") {\n      // Already an element\n      return container as HTMLElement;\n    }\n    if (typeof container === \"string\" && container.length > 0) {\n      // v1 semantics: bare element id first, CSS selector as fallback\n      const byId = document.getElementById(container);\n      if (byId) return byId;\n      const bySelector = document.querySelector<HTMLElement>(container);\n      if (bySelector) return bySelector;\n      throw new Error(\n        `SLATEBOX_COMPAT: container \"${container}\" not found in document`,\n      );\n    }\n    throw new Error(\"SLATEBOX_COMPAT: options.container is required\");\n  }\n\n  /** v1: async init resolving to the slate itself. */\n  public async init(): Promise<this> {\n    const element = this.resolveContainer();\n    const v2Options = v1SlateToV2(this.options) as Record<string, any>;\n    delete v2Options.container;\n    if (this.options.shareId === undefined) {\n      v2Options.shareId = this._shareId;\n    }\n    // v1 takes events as the 2nd constructor arg; v2 nests them in options.\n    // The callback names are shared between both generations.\n    v2Options.events = this.events;\n    this.v2 = new Slate(element, v2Options);\n    // v2 Slate self-initializes; readiness is signaled by the viewport promise\n    await this.v2.getViewportAsync();\n\n    // v1 maintained `options.viewPort.zoom = {w, h, l, t, r}` at runtime and\n    // the Meteor app reads `zoom.r` directly (QuickNodeActions). Expose `r`\n    // as a live getter over the v2 zoom level.\n    if (!this.options.viewPort) this.options.viewPort = {};\n    const zoomState: Record<string, any> = {\n      ...(this.options.viewPort.zoom || {}),\n    };\n    Object.defineProperty(zoomState, \"r\", {\n      enumerable: true,\n      get: () => {\n        try {\n          return this.v2?.getZoom() || 1;\n        } catch {\n          return 1;\n        }\n      },\n    });\n    this.options.viewPort.zoom = zoomState;\n\n    // v1: slate.init() auto-connects collaboration (after a short delay)\n    // when allowCollaboration is on. Only meaningful when the host has\n    // registered onInitCollaboration to supply the URL + auth params.\n    // v1 TIMING: onSlateChanged never fired before collab init completed\n    // (packages traveled through the yjs echo), and host apps rely on that —\n    // defer emissions until the handshake settles, then flush.\n    if (\n      (this.options.allowCollaboration ?? true) &&\n      this.events.onInitCollaboration\n    ) {\n      const v2 = this.v2 as any;\n      v2.deferEmits?.();\n      setTimeout(() => {\n        const initPromise: Promise<void> =\n          v2?.collab?.init({ roomName: this.options.id }) ?? Promise.resolve();\n        initPromise\n          .catch((error: unknown) =>\n            console.warn(\"SLATEBOX_COMPAT: collab init failed\", error),\n          )\n          .finally(() => v2?.flushEmits?.());\n      }, 100);\n    }\n\n    return this;\n  }\n\n  /** v1: `slate.exportJSON()` → JSON string */\n  public exportJSON(): string {\n    this.assertReady();\n    return this.v2!.exportJSON();\n  }\n\n  /** v1: `slate.loadJSON(jsonString)` */\n  public async loadJSON(json: string): Promise<void> {\n    this.assertReady();\n    await this.v2!.loadJSON(json);\n  }\n\n  /**\n   * Lifecycle: `slate.destroy()` — tears down the slate. Delegates to the v2\n   * Slate's destroy(), which deregisters from `window.__slateboxInstances`,\n   * disconnects the ResizeObserver, clears all timers/intervals, removes the\n   * canvas handler, and chains destroy to sub-modules (panZoom/zoomSlider/…).\n   *\n   * The host app MUST call this when unmounting a canvas (React unmount / route\n   * change) — otherwise every navigation LEAKS a Slate: its timers, observers,\n   * and `__slateboxInstances` entry persist (the array grows unbounded across\n   * navigations). Best-effort: safe to call more than once and before ready.\n   */\n  public destroy(): void {\n    try {\n      this.v2?.destroy();\n    } catch (e) {\n      /* best-effort teardown — never throw from destroy */\n    }\n  }\n\n  /**\n   * v1: `slate.getOrientation()` → `{orientation, width, height, left, top}`\n   * computed over the bounding box of all nodes (10px padding, like v1),\n   * falling back to the viewport dimensions when the slate is empty.\n   */\n  public getOrientation(): {\n    orientation: \"landscape\" | \"portrait\";\n    width: number;\n    height: number;\n    left: number;\n    top: number;\n  } {\n    this.assertReady();\n    return this.v2!.getOrientation();\n  }\n\n  /**\n   * v1: `slate.collab.exe/invoke/send/updateUserData` — the live v2 Collab\n   * instance exposes the same four methods.\n   */\n  public get collab() {\n    this.assertReady();\n    return (this.v2 as any).collab;\n  }\n\n  /** v1: `slate.keyboard.bindGlobal()/unbindGlobal()` (NodeDrawer uses it) */\n  public get keyboard() {\n    this.assertReady();\n    return (this.v2 as any).keyboard;\n  }\n\n  /**\n   * v1: `slate.filters.availableFilters` — an object keyed by filter name, each\n   * with a `types` array. The node Effects pane iterates Object.keys(...) and\n   * reads `[name].types` to decide which effects to show, so the shape matters.\n   */\n  public get filters(): {\n    availableFilters: Record<string, { types: string[] }>;\n    availableAnimations: Record<string, AnimationDef>;\n  } {\n    return {\n      availableFilters: getAvailableFilters(),\n      availableAnimations: getAvailableAnimations(),\n    };\n  }\n\n  /** v1: `slate.undoRedo` / `slate.birdsEye` passthroughs */\n  public get undoRedo() {\n    this.assertReady();\n    return (this.v2 as any).undoRedo;\n  }\n\n  public get birdsEye() {\n    this.assertReady();\n    return (this.v2 as any).birdsEye;\n  }\n\n  /**\n   * Grouping/locking controls used by the canonical app. These deliberately\n   * live on the facade so hosts never need to discover the active engine via\n   * the internal `window.__slateboxInstances` lifecycle registry.\n   *\n   * Event callbacks such as `onGroupSelection` carry live v2 nodes, while\n   * older integrations may pass facade node wrappers. Accept both shapes and\n   * delegate the actual mutation to the engine so persistence, collaboration,\n   * and undo continue through the normal `onNodesMove` path.\n   */\n  public groupNodes(nodes?: Array<node | V2Node>): string | null {\n    this.assertReady();\n    return this.v2!.groupNodes(this.unwrapNodes(nodes));\n  }\n\n  public ungroupNodes(nodes?: Array<node | V2Node>): void {\n    this.assertReady();\n    this.v2!.ungroupNodes(this.unwrapNodes(nodes));\n  }\n\n  public lockNodes(nodes?: Array<node | V2Node>): void {\n    this.assertReady();\n    this.v2!.lockNodes(this.unwrapNodes(nodes));\n  }\n\n  public unlockNodes(nodes?: Array<node | V2Node>): void {\n    this.assertReady();\n    this.v2!.unlockNodes(this.unwrapNodes(nodes));\n  }\n\n  public isSelectionLocked(nodes?: Array<node | V2Node>): boolean {\n    this.assertReady();\n    return this.v2!.isSelectionLocked(this.unwrapNodes(nodes));\n  }\n\n  private unwrapNodes(nodes?: Array<node | V2Node>): V2Node[] | undefined {\n    if (!nodes) return undefined;\n    return nodes\n      .map((candidate) =>\n        candidate instanceof node ? candidate.v2 : candidate,\n      )\n      .filter((candidate): candidate is V2Node => !!candidate);\n  }\n\n  /**\n   * v1: `slate.disable(exemptSlate?, exemptNodes?, full?)` — freeze\n   * interactions (used when the app opens read-only/embedded views).\n   */\n  public disable(\n    exemptSlate?: unknown,\n    exemptNodes?: unknown,\n    full?: boolean,\n  ): void {\n    this.assertReady();\n    const v2 = this.v2 as any;\n    if (!exemptNodes) {\n      v2.nodes.allNodes.forEach((n: any) => n.lock?.());\n    }\n    if (!exemptSlate) {\n      this.options.enabled = false;\n      this.options.allowDrag = false;\n      v2.disablePanZoom?.();\n      if (full) {\n        v2.birdsEye?.disable?.();\n        v2.zoomSlider?.disable?.();\n      }\n    }\n  }\n\n  /** v1: `slate.enable(exemptSlate?, exemptNodes?)` — reverse of disable() */\n  public enable(exemptSlate?: unknown, exemptNodes?: unknown): void {\n    this.assertReady();\n    const v2 = this.v2 as any;\n    if (!exemptNodes) {\n      v2.nodes.allNodes.forEach((n: any) => {\n        if (!n.options?.isLocked) n.unlock?.();\n      });\n    }\n    if (!exemptSlate) {\n      this.options.enabled = true;\n      this.options.allowDrag = true;\n      v2.enablePanZoom?.();\n    }\n  }\n\n  /** v1: `slate.png({base64: true}, cb)` — thumbnail export */\n  public png(\n    opts?: Record<string, any>,\n    callback?: (result: string | Blob) => void,\n  ): Promise<string | Blob> {\n    this.assertReady();\n    return this.v2!.png(opts as any, callback);\n  }\n\n  private assertReady(): void {\n    if (!this.v2) {\n      throw new Error(\"SLATEBOX_COMPAT: slate.init() must complete before use\");\n    }\n  }\n}\n\n/**\n * v1 exported a `base` class carrying a static plugin registry. The Meteor\n * app does not use it directly (verified against all 13 importing files);\n * this minimal port exists so `Slatebox.base` is present for any external\n * v1 consumers that subclass it.\n */\nclass base {\n  private static availablePlugins: Record<\n    string,\n    Array<{ name: string; plugin: new (payload?: any) => any }>\n  > = {};\n\n  public plugins?: Record<string, any>;\n\n  constructor(initPayload?: any) {\n    this.registerPlugins(initPayload);\n  }\n\n  public registerPlugins(initPayload?: any): void {\n    const root = this.constructor.name;\n    const registered = base.availablePlugins[root];\n    if (registered) {\n      registered.forEach(({ name, plugin: Plugin }) => {\n        if (!this.plugins) this.plugins = {};\n        this.plugins[name] = new Plugin(initPayload);\n      });\n    }\n  }\n\n  public static registerPlugin(details: {\n    name: string;\n    plugin: new (payload?: any) => any;\n  }): void {\n    if (!details?.name || !details?.plugin) {\n      throw new Error(\n        \"Plugins must provide a name and a plugin (class definition)\",\n      );\n    }\n    const root = Object.getPrototypeOf(details.plugin).name;\n    if (!base.availablePlugins[root]) {\n      base.availablePlugins[root] = [];\n    }\n    base.availablePlugins[root] = [...base.availablePlugins[root], details];\n  }\n}\n\n/**\n * The v1 namespace object: `import { Slatebox } from 'slateboxjs'`.\n * Also assigned to `window.Slatebox` in index.ts.\n */\nexport const Slatebox = {\n  slate,\n  node,\n  base,\n  utils: utilsModule,\n};\n\nexport { slate as CompatSlate, node as CompatNode, base as CompatBase };\n","import { SVG } from '@svgdotjs/svg.js'\nimport '@svgdotjs/svg.draggable.js'\nimport '@svgdotjs/svg.panzoom.js'\nimport '@svgdotjs/svg.select.js'\nimport '@svgdotjs/svg.select.js/src/svg.select.css'\nimport '@svgdotjs/svg.resize.js'\nimport './vendor/svg-connectable/svg.connectable.js'\nimport './styles/slateboxjs.css'\n\n// Core classes\nimport { Slate } from './core/Slate'\nimport { Node } from './core/Node'\nimport { Invoker } from './core/Invoker'\nimport { PanZoom } from './core/PanZoom'\nimport { ResizeRotate } from './core/ResizeRotate'\nimport { BirdsEye } from './core/BirdsEye'\nimport { Connector } from './core/Connector'\nimport { NodesManager } from './core/NodesManager'\n\n// Data & Serialization (function-based modules)\nimport * as Serialization from './core/Serialization'\nimport * as ShapeRegistry from './core/ShapeRegistry'\nimport * as Relationship from './core/Relationship'\nimport { Relationships } from './core/Relationships'\n\n// Compatibility layer\nimport * as compat from './core/compat'\n\n// Content & Text\nimport * as FontLoader from './core/FontLoader'\nimport { Images } from './core/Images'\nimport { Editor } from './core/Editor'\n\n// UI Features\nimport { UndoRedo } from './core/UndoRedo'\nimport { MultiSelection } from './core/MultiSelection'\nimport { Grid } from './core/Grid'\nimport { Menu } from './core/Menu'\nimport { Keyboard } from './core/Keyboard'\nimport { ContextMenu } from './core/ContextMenu'\nimport { Filters, registerFilter, getFilterNames } from './core/Filters'\nimport { Links } from './core/Links'\n\n// Export (function-based module)\nimport * as ExportModule from './core/Export'\n\n// Collaboration\nimport { Collab } from './core/Collab'\n\n// App Integration (function-based modules)\nimport * as Theme from './core/Theme'\nimport * as Layout from './core/Layout'\nimport { ZoomSlider } from './core/ZoomSlider'\nimport * as Comments from './core/Comments'\nimport { Presentation } from './core/Presentation'\n\n// Utilities\nimport * as utils from './utils'\n\n// v1 runtime API facade (`Slatebox.slate/node/base/utils`)\nimport { Slatebox } from './compat-facade'\n\n// Export all classes and utilities\nexport {\n  // Core\n  Slate,\n  Node,\n  Invoker,\n  PanZoom,\n  ResizeRotate,\n  BirdsEye,\n  Connector,\n  NodesManager,\n  // Data & Serialization\n  Serialization,\n  ShapeRegistry,\n  Relationship,\n  Relationships,\n  // Compatibility\n  compat,\n  // Content & Text\n  FontLoader,\n  Images,\n  Editor,\n  // UI Features\n  UndoRedo,\n  MultiSelection,\n  Grid,\n  Menu,\n  Keyboard,\n  ContextMenu,\n  Filters,\n  registerFilter,\n  getFilterNames,\n  Links,\n  // Export\n  ExportModule,\n  // Collaboration\n  Collab,\n  // App Integration\n  Theme,\n  Layout,\n  ZoomSlider,\n  Comments,\n  Presentation,\n  // Utilities\n  utils,\n  // v1 runtime API facade\n  Slatebox,\n}\n\n// Re-export types for convenience\nexport type { SlateJSON, NodeJSON } from './core/Serialization'\nexport type { ShapeDefinition } from './core/ShapeRegistry'\nexport type { Association } from './core/Relationship'\nexport type { CollabOptions, CollabUser, CollabPackage } from './core/Collab'\nexport type { SlatePackage } from './core/SlatePackage'\nexport type { ExportOptions } from './core/Export'\nexport type { ThemeStyle, ThemeDefinition } from './core/Theme'\nexport type { LayoutMove } from './core/Layout'\nexport type { CommentOptions } from './core/Comments'\nexport type { PresentationStep } from './core/Presentation'\nexport type { FilterDef } from './core/Filters'\n\n/**\n * SlateboxJS — Modern diagramming library built with SVG.js.\n *\n * Create interactive diagrams with draggable nodes, pan/zoom,\n * resize/rotate, connections, and more.\n *\n * @example\n * ```ts\n * import SlateboxJS from 'slateboxjs'\n *\n * const slate = SlateboxJS('#container', {\n *   viewPort: { originalWidth: 800, originalHeight: 600 },\n *   panZoom: { enabled: true }\n * })\n *\n * slate.addNode({\n *   id: 'node1', x: 100, y: 100,\n *   width: 120, height: 80, text: 'Hello',\n *   backgroundColor: '#4ecdc4'\n * })\n * ```\n *\n * @param element - CSS selector string or HTMLElement to mount the canvas on\n * @param options - Configuration options for the slate\n * @returns A new Slate instance\n */\nexport function SlateboxJS(element: string | HTMLElement, options: any = {}) {\n  return new Slate(element, options)\n}\n\n// Attach to window for global usage\nif (typeof window !== 'undefined') {\n  (window as any).SlateboxJS = SlateboxJS\n  ;(window as any).Slate = Slate\n  ;(window as any).Node = Node\n  ;(window as any).PanZoom = PanZoom\n  ;(window as any).ResizeRotate = ResizeRotate\n  ;(window as any).BirdsEye = BirdsEye\n  ;(window as any).Connector = Connector\n  ;(window as any).Serialization = Serialization\n  ;(window as any).ShapeRegistry = ShapeRegistry\n  ;(window as any).Relationship = Relationship\n  ;(window as any).Relationships = Relationships\n  ;(window as any).FontLoader = FontLoader\n  ;(window as any).Images = Images\n  ;(window as any).Editor = Editor\n  ;(window as any).UndoRedo = UndoRedo\n  ;(window as any).MultiSelection = MultiSelection\n  ;(window as any).Grid = Grid\n  ;(window as any).Menu = Menu\n  ;(window as any).Keyboard = Keyboard\n  ;(window as any).ContextMenu = ContextMenu\n  ;(window as any).Filters = Filters\n  ;(window as any).Links = Links\n  ;(window as any).Export = ExportModule\n  ;(window as any).Collab = Collab\n  ;(window as any).Theme = Theme\n  ;(window as any).Layout = Layout\n  ;(window as any).ZoomSlider = ZoomSlider\n  ;(window as any).Comments = Comments\n  ;(window as any).Presentation = Presentation\n  ;(window as any).Slatebox = Object.assign({}, Slatebox, { compat })\n}\n\n// Default export\nexport default SlateboxJS\n"],"names":["methods","names","registerMethods","name","m","_name","addMethodNames","getMethodsFor","getMethodNames","_names","map","array","block","i","il","result","filter","radians","d","unCamelCase","s","g","capitalize","proportionalSize","element","width","height","box","getOrigin","o","origin","ox","oy","condX","condY","x","y","descriptiveElements","isDescriptive","writeDataToDom","data","defaults","cloned","key","svg","html","xmlns","xlink","globals","getWindow","Base","elements","root","create","ns","makeInstance","isHTML","adopter","wrapper","nodeOrNew","node","adopt","className","register","asRoot","getClass","did","eid","assignNewId","extend","modules","wrapWithAttrCheck","fn","args","siblings","position","next","prev","forward","backward","front","back","before","after","insertBefore","insertAfter","numberAndUnit","hex","rgb","reference","transforms","whitespace","isHex","isRgb","isBlank","isNumber","isImage","delimiter","isPathLetter","classes","attr","hasClass","addClass","removeClass","c","toggleClass","css","style","val","ret","el","t","cased","show","hide","visible","a","v","r","remember","k","forget","memory","sixDigitHex","componentHex","component","integer","is","object","space","getParameters","b","params","cieSpace","hueToRgb","p","q","Color","inputs","color","mode","random","round","sin","pi","l","h","grey","_a","_b","_c","max","min","isGrey","delta","values","noWhitespace","hexParse","_d","components","z","dToR","yL","xL","zL","ct","mx","nm","rU","gU","bU","pow","bd","rV","gV","bV","r255","g255","b255","rL","gL","bL","xU","yU","zU","format","Point","base","source","Matrix","point","closeEnough","threshold","Matrix$1","flipBoth","flipX","flipY","skewX","skewY","scaleX","scaleY","shear","theta","px","py","translate","tx","ty","relative","rx","ry","e","f","cx","cy","matrix","dx","dy","determinant","ccw","sx","thetaRad","st","lam","sy","other","comp","axis","around","Element","det","na","nb","nc","nd","ne","nf","cos","lx","ly","current","transformer","ctm","screenCTM","rect","parser","path","isNulledBox","domContains","Box","xMin","xMax","yMin","yMax","getBox","getBBoxFn","retry","bbox","clone","rbox","inside","level","zoomX","zoomY","zoom","zoomAmount","List","arr","fnOrMethodName","reserved","obj","attrs","baseFind","query","parent","find","findOne","listenerId","windowEvents","getEvents","instance","n","getEventTarget","clearEvents","on","events","listener","binding","options","bag","event","ev","off","namespace","dispatch","EventTarget","j","noop","timeline","SVGArray","SVGNumber","unit","number","value","colorAttributes","hooks","registerAttrHook","last","curr","_val","hook","Dom","deep","assignNewIds","nodeClone","children","nodeName","htmlOrFn","outerHTML","id","selector","matcher","type","precision","factor","svgOrFn","outerSVG","text","xmlOrFn","outerXML","_this","well","fragment","len","until","isSelector","parents","sugar","extension","mat","angle","direction","length","untransform","matrixify","str","kv","transform","toParent","pCtm","toRoot","decomposed","cleanRelative","Container","index","Defs","Shape","Ellipse","circled","Fragment","from","to","Gradient","gradiented","Pattern","url","callback","img","Image","pattern","PointArray","maxX","maxY","minX","minY","points","MorphArray","Line","x1","y1","x2","y2","pointed","Marker","orient","marker","makeSetterGetter","easing","pos","steps","stepPosition","jumps","beforeFlag","step","jumping","Stepper","Ease","Controller","target","dt","recalculate","duration","overshoot","eps","os","zeta","wn","Spring","velocity","acceleration","newPosition","PID","windup","segmentParameters","pathHandlers","p0","mlhvqtcsaz","jl","makeAbsolut","command","segmentComplete","startNewSegment","token","finalizeNumber","pathLetter","lastCommand","small","isSmall","inNumber","finalizeSegment","isArcFlag","isArc","isExponential","pathDelimiters","pathParser","toAbsolute","arrayToString","PathArray","getClassForType","NonMorphable","morphableTypes","ObjectBag","Morphable","stepper","TransformBag","sortByKey","defaultObject","toDelete","objOrArr","entries","Type","num","registerMorphableType","makeMorphable","context","mapper","Path","clear","move","plot","size","Polygon","poly","Polyline","Rect","Queue","item","remove","Animator","delay","time","now","nextTimeout","lastTimeout","nextFrame","lastFrame","nextImmediate","makeSchedule","runnerInfo","start","end","defaultSource","w","Timeline","timeSource","lastRunnerInfo","lastDuration","endTimes","dtOrForever","yes","currentSpeed","positive","runner","when","absoluteStartTime","endTime","persist","info","speed","immediateStep","dtSource","dtTime","runnersLeft","dtToStart","Runner","times","swing","wait","enabled","loopDuration","loopsDone","whole","partial","swinging","backwards","uncliped","swingForward","initFn","runFn","retargetFn","isTransform","reverse","running","justStarted","justFinished","declarative","converged","needsIt","method","morpher","positionOrDt","allfinished","extra","FakeRunner","done","lmultiply","getRunnerTransform","mergeTransforms","netTransform","RunnerArray","deleteCnt","newRunner","lastRunner","by","currentRunner","difference","nameOrAttrs","keys","newToAttrs","newKeys","differences","addedFromAttrs","oldFromAttrs","oldToAttrs","newLevel","newPoint","affine","isMatrix","currentAngle","startTransform","setup","run","rTarget","rCurrent","possibilities","distances","shortest","affineParameters","retarget","newTransforms","newTo","Svg","Symbol","plain","center","ax","ay","amove","build","Text","rebuild","self","blankLineOffset","leading","fontSize","firstLine","textable","Tspan","tspan","Circle","ClipPath","clipper","ForeignObject","dmove","child","G","containerGeometry","A","link","Mask","masker","Stop","offset","opacity","cssRule","rule","Style","src","TextPath","track","pathArray","importNodes","textPath","Use","file","SVG","getCoordsFromEvent","DragHandler","isMouse","eventMove","eventEnd","lastClick","currentClick","enable","normalizeEvent","_options","_options$zoomFactor","_options$zoomMin","_options$zoomMax","_options$wheelZoom","_options$pinchZoom","_options$panning","_options$panButton","_options$oneFingerPan","_options$margins","_options$wheelZoomDel","_options$wheelZoomDel2","zoomFactor","zoomMin","zoomMax","doWheelZoom","doPinchZoom","doPanning","panButton","oneFingerPan","margins","wheelZoomDeltaModeLinePixels","wheelZoomDeltaModeScreenPixels","lastP","lastTouches","zoomInProgress","viewbox","restrictToMargins","top","left","bottom","right","_this$attr","preserveAspectRatio","viewportLeftOffset","viewportRightOffset","viewportTopOffset","viewportBottomOffset","svgAspectRatio","viewboxAspectRatio","isMeet","changedAxis","isWidth","changeHorizontal","ratio","leftLimit","rightLimit","topLimit","bottomLimit","wheelZoom","normalizedPixelDeltaY","lvl","pinchZoomStart","panStart","panStop","pinchZoom","pinchZoomStop","currentTouches","lastDelta","currentDelta","currentFocus","lastFocus","focusP","panning","currentP","p1","p2","deltaP","getMoseDownFunc","eventName","transformPoint","SelectHandler","win","group","shape","diff1","diff2","len1","len2","normalized1","normalized2","beforeNew","nextNew","rotPoint","topPoint","handle","fromShapeToUiMatrix","PointSelectHandler","getSelectFn","handleClass","selectHandler","maxBoxFromPoints","scaleBox","scale","newPoints","translatedX","translatedY","scaledX","scaledY","ResizeHandler","endPoint","order","constantPoint","pointArr","startPoint","dx1","dy1","dx2","dy2","rotate","resultAngle","resizeHandler","localToSvgCoords","localX","localY","svgRoot","rootScreenCTM","screenX","screenY","invA","invB","invC","invD","invE","invF","svgX","svgY","svgCoordsToLocal","getElementCenter","closestPointOnPathOutline","targetPoint","pathEl","bestArea","cand","area","total","rootSvg","pathCTM","rootInv","sp","toUser","u","dirX","dirY","dm","ux","uy","best","bestScore","N","samples","lp","wx","wy","proj","perp","score","getClosestPointOnEdge","outline","bb","ccx","ccy","span","localTargetX","localTargetY","centerX","centerY","distance","localEdgePoint","radius","intersections","worldEdgeX","worldEdgeY","anchorPointOnShape","anchor","edgeNormalAt","portSvg","nx","ny","dl","dr","db","lnx","lny","vx","vy","mag","computeConnectorCoordinates","con","temp","sourceCenter","targetCenter","pp1","pp2","norm","fx","fy","fm","sDir","tDir","curviness","cp1","cp2","qcp","sourceIsLeft","sourceIsTop","targetIsLeft","targetIsTop","midX","midY","ORTHO_SNAP","sourceArrowWidth","first","aw","ex","ey","createMarker","isSource","strokeWidth","markers","markerSize","arrowWidth","arrowHeight","markerId","markerEl","halfHeight","setMarker","sourceMarker","targetMarker","markersContainer","setMarkerSettings","setStrokeWidth","setConnectorColor","snappedAnchorForDrop","worldPos","hasMethod","methodName","createHandle","handleObj","setupHandleDrag","dragTarget","detachHandle","currentPos","mouseEvent","findDropTarget","highlightDropTarget","updateConnectorForDrag","clearHitZoneVisualizations","attachHandleToTarget","clearDropTargetHighlight","dropPosition","phantomRect","createPhantomRect","currentTarget","dropTarget","lineType","previewNode","previewAnchor","mockElement","originalSource","originalTarget","originalType","originalSourceAnchor","originalTargetAnchor","pathData","isPointInElement","debugMode","visualizeHitZone","container","debugGroup","originalBox","corner","findTargetShapes","shapes","searchRecursively","isTargetShape","classList","cursor","dataAttrs","parentClasses","parentId","elementId","fill","stroke","svgRect","targetShapes","isValidDropTarget","candidates","nel","otherTarget","dropPoint","oldTarget","updateFunction","storedFunctionKey","oldUpdateFunction","isPhantom","targetNodeId","currentlyHighlighted","styleSheet","updateHandles","lastCmd","selectConnector","activeConnectorRef","deselectConnector","toggleSelection","setupClickHandlers","mouseDownPos","DRAG_THRESHOLD","handleMouseDown","handleMouseUp","setConnectorAttachment","setHandleVisibility","getHandles","setClickAreaWidth","setConnector","connector","setType","setDebugMode","toggleDebugMode","makeSelectable","makeDraggable","makeResizable","makeInteractive","selectOptions","dragOptions","resizeOptions","onMakeInteractive","globalActiveConnectorRef","connectable","elmTarget","elmSource","patharr","conInstance","isValid","mid","rm","which","otherCenter","edge","local","updateConnector","updateConnectorFromSource","updateConnectorFromTarget","connectOptions","connection","computeSelectHandlePlot","H","pt","ResizeRotate","error","svgNode","handler","pointerEvent","slate","handleClasses","deltaAngle","backgroundRectRotation","existingSvgGroupRotation","totalRotation","Connector","targetNode","connectionOptions","connectionId","co","typeMap","connType","markerSource","markerTarget","connectableObj","reverseId","synthId","phantom","fakeTarget","conn","ids","ok","connectionIds","updates","tgt","line","filters","props","origChildId","newNode","oldParent","ownerNode","childId","anchorNode","clamp","rad","nearest","rels","assoc","handleEls","reveal","armHandleHover","targetId","R","GAP","tools","stepX","totalW","startX","bar","NodeCls","bx","btn","association","opts","prop","lineNode","centerOf","dist","srcC","srcAtStart","inset","srcPt","tgtPt","NEUTRAL","ABS","makeToggle","absolute","locked","createDefaultAssociation","overrides","Relationships","childNode","childIdOrAssocId","direct","matches","associationId","connId","Images","defs","add","loadedFonts","pendingLoads","systemFonts","loadFont","fontFamily","normalized","lower","promise","resolve","reject","primaryFont","loadAllFonts","fonts","nodes","promises","isFontLoaded","Editor","fo","div","finish","save","newText","pkg","collab","range","sel","fontColor","textXAlign","textYAlign","textBBox","nodeWidth","nodeHeight","textOpacity","padding","minWidth","minHeight","currentWidth","currentHeight","newWidth","newHeight","Links","linkOptions","sendCollab","SPACES","PATH_COMMAND","PATH_VALUES","TRANSFORM_COMMAND","parsePathString","pathString","paramCounts","_all","param","pathToAbsolute","pathArr","res","my","pa","l2c","q2c","_13","_23","a2c","largeArcFlag","sweepFlag","recursive","_120","xy","f1","f2","rx2","ry2","df","f2old","x2old","y2old","c1","s1","c2","s2","hx","hy","m1","m2","m3","m4","newres","path2curve","processPath","seg","pcom","fixArc","pp","pcoms","pfirst","seglen","curveDim","p1x","p1y","c1x","c1y","c2x","c2y","p2x","p2y","dot","pA","cA","cB","pB","mt","xs","ys","roots","B","C","out","disc","sq","t1","t2","droots","pathBBox","X","Y","dim","xmin","ymin","xmax","ymax","yy","parseTransformString","tstr","transform2matrix","tdata","tlen","inver","mapPath","transformPath","curves","guid","chars","whiteOrBlack","hexColor","getRGB","getsRGB","getLuminance","getContrast","L1","L2","whiteContrast","blackContrast","getTextWidth","font","splitText","fontSplit","fontWeight","textWidthCanvas","metrics","multiplier","calculatedFontSize","contrastRatio","hex1","hex2","lum","srgb","l1","l2","getBBox","_transformPath","createMultiLineText","lineCount","words","charsPerLine","lines","wordsOnLine","curCharCount","randomInt","obtainProportionateWidthAndHeightForResizing","originalWidth","originalHeight","targetWidth","targetHeight","buildNodeStyleFromTheme","safeForUrls","isElement","isSafari","isMobile","stopEvent","evt","chunk","chunks","once","animationDefs","baseCss","getAvailableAnimations","animationClass","installAnimationStyles","def","applyAnimation","removeAnimations","dom","filterDefs","origStroke","origStrokeWidth","outlineColor","Filters","filterName","animationName","registerFilter","getFilterNames","getAvailableFilters","Menu","tabs","getShape","hasShape","registerShape","definition","getShapeNames","isNativeShape","resolveShapePath","vectorPath","named","v1NodeToV2","v1","v2","mapShapeHintToShape","v2NodeToV1","v1SlateToV2","v2SlateToV1","v1AssociationToV2","v2AssociationToV1","shapeHint","convertV1JsonToV2","v1Json","v1Node","nodeOptions","relationships","convertV2JsonToV1","v2Json","v2Node","snapRectToNeighbors","others","myXs","myYs","snapX","snapY","bestDX","bestDY","otherXs","otherYs","oX","oY","Node","viewport","hasSvg","bgX","bgY","content","resizeRotateOpts","shp","badge","glyph","backgroundColor","borderColor","borderWidth","borderStyle","borderOpacity","strokeOpts","dash","shapeDef","nested","wasSelected","fontStyle","maxWidth","ctx","measure","para","word","ch","test","textHeight","needed","textOffset","shapeX","shapeY","lineHeight","availW","availH","gcx","gcy","isCurrentlySelected","origEvt","isMultiSelect","selected","ptr","fdx","fdy","feffDx","feffDy","fsnapped","aligned","sib","movedSiblings","startPos","EPS","curX","curY","primaryMoved","siblingMoved","actuallyMoved","effDx","effDy","snapped","startY","t0","count","kind","label","changed","diameter","_","cbs","parts","grad","styleEl","fc","isAutoFont","currentFont","ideal","stripBakedRotation","tr","strippedText","groupTransform","makeInteractiveCallback","svgGroup","testConnection","svgContent","viewBoxMatch","viewBoxValues","widthMatch","heightMatch","svgWidth","svgHeight","clickStartPosition","CLICK_THRESHOLD","endPosition","gid","topY","rb","barY","startEvent","canvas","previewArrow","edgePoint","sxr","syr","sc","hovered","clearHover","toWorld","clientX","clientY","nodeUnder","prevDisplay","pad","onMove","tcx","tcy","oEdge","opt","tp","cp1x","cp1y","cp2x","cp2y","br","onUp","overSelf","connect","handleRadius","handleColor","handleStroke","handleStrokeWidth","positions","handedOff","cleanup","swallow","ce","elMatrix","topOffset","sideOffset","bboxPositions","transformedX","transformedY","spacing","rotationAngle","actualCenterX","actualCenterY","handleBBox","handleCenter","dirLength","rotatedDirX","rotatedDirY","bboxCenterX","bboxCenterY","inverseMatrix","bboxDirX","bboxDirY","bboxEdgeX","bboxEdgeY","absX","sourceEdgeDistance","previewEdgeDistance","totalDistance","newCenterX","newCenterY","newNodeX","newNodeY","arrowLength","arrowEnd","fillColor","strokeColor","previewSvg","unitX","unitY","arrowTipX","arrowTipY","baseX","baseY","perpX","perpY","arrowPoints","rotationRad","newNodeEdgeDistance","newNodeOptions","newId","NodesManager","packageData","moves","relationshipData","rid","predicate","serialize","asPresentation","serializedNodes","serializeNode","idx","serializeSlateOptions","deserialize","json","preserve","skipZoom","deserializeInner","slateOpts","nodeMap","nodeJson","nodeOpts","deserializeNodeOptions","existing","readyPromises","nodeId","parentNode","associations","assocData","contentCenterX","attemptFit","tries","sized","vb","rotation","relData","connections","jsonOpts","snapshot","Invoker","nodesToCreate","nOpts","optKey","theme","cs","PanZoom","unitsPerPx","newZoom","newW","newH","px0","py0","zoomInBtn","zoomOutBtn","resetBtn","currentZoom","contentWidth","contentHeight","vbWidth","vbHeight","containerAspect","contentAspect","finalW","finalH","BirdsEye","panZoom","pan","viewportWidth","viewportHeight","bounds","totalWidth","totalHeight","visibleWidth","visibleHeight","viewportX","viewportY","viewportW","viewportH","fromX","fromY","ease","startTs","tick","margin","me","iw","ih","panX","panY","deltaX","deltaY","newX","newY","zoomDisplay","display","UndoRedo","init","previous","action","snapshotJSON","err","MultiSelection","addToSelection","nodesInRect","allNodes","nw","nh","svgPt","Grid","endX","endY","Keyboard","isMod","snap","srcId","idSet","edges","am","as","snaps","snapshots","created","srcToCopy","pending","focused","currentIdx","nextIdx","ContextMenu","menu","selCount","items","it","hr","row","exportSVG","removeSelectors","bgRect","keepIds","groups","vbW","vbH","svgString","exportPNG","baseW","baseH","vbMatch","renderCanvas","svgBlob","blob","dataUrl","Collab","WebsocketProvider","userBaseData","initCb","change","notifyUsersChanged","users","packages","pkgs","deletedId","invoker","present","user","txt","tw","th","padX","padY","state","clientID","applyTheme","syncWithTheme","revertTheme","depthByNodeId","computeHierarchyDepths","childNumber","applyStyleToNode","childIds","childrenOf","hasEdges","assocMap","kids","depth","queue","childKeys","optionKeys","lineStyle","removeLayoutOverlaps","enableAttraction","maxIterations","hasOverlap","iteration","ah","bw","bh","overlapX","overlapY","pushX","pushY","sum","applyLayout","noAnimation","completed","packageLayout","ZoomSlider","positionStyles","zoomOut","zoomIn","fit","Presentation","ai","bi","byId","childIdsOf","isChildOfAny","processed","processNode","rootNodes","nodeIds","all","exists","seen","ordered","zc","set","_Slate","found","vw","vh","originX","originY","coordDisplay","msg","cb","queued","colors","originalOnPan","originalOnZoom","originalOnPanEnd","viewBox","isComment","lastW","lastH","pw","ph","vp","orientation","isCanvasClick","world","members","selectedNode","groupBBox","knobY","knob","setCursor","dragging","startAngle","pivot","pivotScreen","deltaDeg","ncx","ncy","rot","selection","originalGroupBBox","nodeBBox","relativeX","relativeY","currentRotation","cxp","cyp","corners","gMinX","gMaxX","gMinY","gMaxY","gap","totalH","groupId","gids","affected","targets","member","useMainCanvas","takeSnapshot","applyLayoutMoves","loadAllFontsForSlate","Slate","createComment","removeComment","getComments","utilsModule.guid","property","receiver","live","written","deleted","v2Property","liveKeys","NodeResizeFacade","NodeRelationshipsFacade","withNodes","coords","maybeY","explicit","owner","childV2","slateFacade","NodesFacade","v2Options","list","subgraphs","v1Opts","layout","cbOrOpts","exportNodes","deltas","bySelector","zoomState","candidate","exemptSlate","exemptNodes","full","_base","initPayload","registered","Plugin","details","Slatebox","utilsModule","SlateboxJS","Serialization","ShapeRegistry","Relationship","FontLoader","ExportModule","Theme","Layout","Comments","compat"],"mappings":"AAAA,MAAMA,KAAU,CAAA,GACVC,KAAQ,CAAA;AAEP,SAASC,EAAgBC,GAAMC,GAAG;AACvC,MAAI,MAAM,QAAQD,CAAI,GAAG;AACvB,eAAWE,KAASF;AAClB,MAAAD,EAAgBG,GAAOD,CAAC;AAE1B;AAAA,EACF;AAEA,MAAI,OAAOD,KAAS,UAAU;AAC5B,eAAWE,KAASF;AAClB,MAAAD,EAAgBG,GAAOF,EAAKE,CAAK,CAAC;AAEpC;AAAA,EACF;AAEA,EAAAC,GAAe,OAAO,oBAAoBF,CAAC,CAAC,GAC5CJ,GAAQG,CAAI,IAAI,OAAO,OAAOH,GAAQG,CAAI,KAAK,CAAA,GAAIC,CAAC;AACtD;AAEO,SAASG,GAAcJ,GAAM;AAClC,SAAOH,GAAQG,CAAI,KAAK,CAAA;AAC1B;AAEO,SAASK,KAAiB;AAC/B,SAAO,CAAC,GAAG,IAAI,IAAIP,EAAK,CAAC;AAC3B;AAEO,SAASK,GAAeG,GAAQ;AACrC,EAAAR,GAAM,KAAK,GAAGQ,CAAM;AACtB;AC/BO,SAASC,GAAIC,GAAOC,GAAO;AAChC,MAAIC;AACJ,QAAMC,IAAKH,EAAM,QACXI,IAAS,CAAA;AAEf,OAAKF,IAAI,GAAGA,IAAIC,GAAID;AAClB,IAAAE,EAAO,KAAKH,EAAMD,EAAME,CAAC,CAAC,CAAC;AAG7B,SAAOE;AACT;AAGO,SAASC,GAAOL,GAAOC,GAAO;AACnC,MAAIC;AACJ,QAAMC,IAAKH,EAAM,QACXI,IAAS,CAAA;AAEf,OAAKF,IAAI,GAAGA,IAAIC,GAAID;AAClB,IAAID,EAAMD,EAAME,CAAC,CAAC,KAChBE,EAAO,KAAKJ,EAAME,CAAC,CAAC;AAIxB,SAAOE;AACT;AAGO,SAASE,GAAQC,GAAG;AACzB,SAASA,IAAI,MAAO,KAAK,KAAM;AACjC;AAQO,SAASC,GAAYC,GAAG;AAC7B,SAAOA,EAAE,QAAQ,YAAY,SAAUhB,GAAGiB,GAAG;AAC3C,WAAO,MAAMA,EAAE,YAAW;AAAA,EAC5B,CAAC;AACH;AAGO,SAASC,GAAWF,GAAG;AAC5B,SAAOA,EAAE,OAAO,CAAC,EAAE,gBAAgBA,EAAE,MAAM,CAAC;AAC9C;AAGO,SAASG,GAAiBC,GAASC,GAAOC,GAAQC,GAAK;AAC5D,UAAIF,KAAS,QAAQC,KAAU,UAC7BC,IAAMA,KAAOH,EAAQ,KAAI,GAErBC,KAAS,OACXA,IAASE,EAAI,QAAQA,EAAI,SAAUD,IAC1BA,KAAU,SACnBA,IAAUC,EAAI,SAASA,EAAI,QAASF,KAIjC;AAAA,IACL,OAAOA;AAAA,IACP,QAAQC;AAAA,EACZ;AACA;AAOO,SAASE,GAAUC,GAAGL,GAAS;AACpC,QAAMM,IAASD,EAAE;AAEjB,MAAIE,IAAKF,EAAE,MAAM,OAAOA,EAAE,KAAKA,EAAE,WAAW,OAAOA,EAAE,UAAU,UAC3DG,IAAKH,EAAE,MAAM,OAAOA,EAAE,KAAKA,EAAE,WAAW,OAAOA,EAAE,UAAU;AAG/D,EAAIC,KAAU,SACX,CAACC,GAAIC,CAAE,IAAI,MAAM,QAAQF,CAAM,IAC5BA,IACA,OAAOA,KAAW,WAChB,CAACA,EAAO,GAAGA,EAAO,CAAC,IACnB,CAACA,GAAQA,CAAM;AAIvB,QAAMG,IAAQ,OAAOF,KAAO,UACtBG,IAAQ,OAAOF,KAAO;AAC5B,MAAIC,KAASC,GAAO;AAClB,UAAM,EAAE,QAAAR,GAAQ,OAAAD,GAAO,GAAAU,GAAG,GAAAC,EAAC,IAAKZ,EAAQ,KAAI;AAG5C,IAAIS,MACFF,IAAKA,EAAG,SAAS,MAAM,IACnBI,IACAJ,EAAG,SAAS,OAAO,IACjBI,IAAIV,IACJU,IAAIV,IAAQ,IAGhBS,MACFF,IAAKA,EAAG,SAAS,KAAK,IAClBI,IACAJ,EAAG,SAAS,QAAQ,IAClBI,IAAIV,IACJU,IAAIV,IAAS;AAAA,EAEvB;AAGA,SAAO,CAACK,GAAIC,CAAE;AAChB;AAEA,MAAMK,KAAsB,oBAAI,IAAI,CAAC,QAAQ,YAAY,OAAO,CAAC,GACpDC,KAAgB,CAACd,MAC5Ba,GAAoB,IAAIb,EAAQ,QAAQ,GAE7Be,KAAiB,CAACf,GAASgB,GAAMC,IAAW,CAAA,MAAO;AAC9D,QAAMC,IAAS,EAAE,GAAGF,EAAI;AAExB,aAAWG,KAAOD;AAChB,IAAIA,EAAOC,CAAG,EAAE,QAAO,MAAOF,EAASE,CAAG,KACxC,OAAOD,EAAOC,CAAG;AAIrB,EAAI,OAAO,KAAKD,CAAM,EAAE,SACtBlB,EAAQ,KAAK,aAAa,cAAc,KAAK,UAAUkB,CAAM,CAAC,KAE9DlB,EAAQ,KAAK,gBAAgB,YAAY,GACzCA,EAAQ,KAAK,gBAAgB,YAAY;AAE7C,GCtIaoB,KAAM,8BACNC,KAAO,gCACPC,KAAQ,iCACRC,KAAQ,gCCJRC,IAAU;AAAA,EACrB,QAAQ,OAAO,SAAW,MAAc,OAAO;AAAA,EAC/C,UAAU,OAAO,WAAa,MAAc,OAAO;AACrD;AA0BO,SAASC,KAAY;AAC1B,SAAOD,EAAQ;AACjB;AC/Be,MAAME,GAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAS1B;ACHA,MAAMC,KAAW,CAAA,GACJC,KAAO;AAGb,SAASC,GAAOlD,GAAMmD,IAAKV,IAAK;AAErC,SAAOI,EAAQ,SAAS,gBAAgBM,GAAInD,CAAI;AAClD;AAEO,SAASoD,GAAa/B,GAASgC,IAAS,IAAO;AACpD,MAAIhC,aAAmB0B,GAAM,QAAO1B;AAEpC,MAAI,OAAOA,KAAY;AACrB,WAAOiC,GAAQjC,CAAO;AAGxB,MAAIA,KAAW;AACb,WAAO,IAAI2B,GAASC,EAAI,EAAC;AAG3B,MAAI,OAAO5B,KAAY,YAAYA,EAAQ,KAAI,EAAG,OAAO,CAAC,MAAM;AAC9D,WAAOiC,GAAQT,EAAQ,SAAS,cAAcxB,CAAO,CAAC;AAIxD,QAAMkC,IAAUF,IAASR,EAAQ,SAAS,cAAc,KAAK,IAAIK,GAAO,KAAK;AAC7E,SAAAK,EAAQ,YAAYlC,EAAQ,KAAI,GAGhCA,IAAUiC,GAAQC,EAAQ,iBAAiB,GAG3CA,EAAQ,YAAYA,EAAQ,iBAAiB,GACtClC;AACT;AAEO,SAASmC,EAAUxD,GAAMyD,GAAM;AACpC,SAAOA,MACJA,aAAgBZ,EAAQ,OAAO,QAC7BY,EAAK,iBACJA,aAAgBA,EAAK,cAAc,YAAY,QACjDA,IACAP,GAAOlD,CAAI;AACjB;AAGO,SAAS0D,GAAMD,GAAM;AAE1B,MAAI,CAACA,EAAM,QAAO;AAGlB,MAAIA,EAAK,oBAAoBV,GAAM,QAAOU,EAAK;AAE/C,MAAIA,EAAK,aAAa;AACpB,WAAO,IAAIT,GAAS,SAASS,CAAI;AAInC,MAAIE,IAAYxC,GAAWsC,EAAK,YAAY,KAAK;AAGjD,SAAIE,MAAc,oBAAoBA,MAAc,mBAClDA,IAAY,aAGFX,GAASW,CAAS,MAC5BA,IAAY,QAGP,IAAIX,GAASW,CAAS,EAAEF,CAAI;AACrC;AAEA,IAAIH,KAAUI;AAMP,SAASE,EAASvC,GAASrB,IAAOqB,EAAQ,MAAMwC,IAAS,IAAO;AACrE,SAAAb,GAAShD,CAAI,IAAIqB,GACbwC,MAAQb,GAASC,EAAI,IAAI5B,IAE7BlB,GAAe,OAAO,oBAAoBkB,EAAQ,SAAS,CAAC,GAErDA;AACT;AAEO,SAASyC,GAAS9D,GAAM;AAC7B,SAAOgD,GAAShD,CAAI;AACtB;AAGA,IAAI+D,KAAM;AAGH,SAASC,GAAIhE,GAAM;AACxB,SAAO,UAAUmB,GAAWnB,CAAI,IAAI+D;AACtC;AAGO,SAASE,GAAYR,GAAM;AAEhC,WAAS/C,IAAI+C,EAAK,SAAS,SAAS,GAAG/C,KAAK,GAAGA;AAC7C,IAAAuD,GAAYR,EAAK,SAAS/C,CAAC,CAAC;AAG9B,SAAI+C,EAAK,OACPA,EAAK,KAAKO,GAAIP,EAAK,QAAQ,IACpBA;AAIX;AAGO,SAASS,EAAOC,GAAStE,GAAS;AACvC,MAAI2C,GAAK9B;AAIT,OAFAyD,IAAU,MAAM,QAAQA,CAAO,IAAIA,IAAU,CAACA,CAAO,GAEhDzD,IAAIyD,EAAQ,SAAS,GAAGzD,KAAK,GAAGA;AACnC,SAAK8B,KAAO3C;AACV,MAAAsE,EAAQzD,CAAC,EAAE,UAAU8B,CAAG,IAAI3C,EAAQ2C,CAAG;AAG7C;AAEO,SAAS4B,EAAkBC,GAAI;AACpC,SAAO,YAAaC,GAAM;AACxB,UAAM5C,IAAI4C,EAAKA,EAAK,SAAS,CAAC;AAE9B,WAAI5C,KAAKA,EAAE,gBAAgB,UAAU,EAAEA,aAAa,SAC3C2C,EAAG,MAAM,MAAMC,EAAK,MAAM,GAAG,EAAE,CAAC,EAAE,KAAK5C,CAAC,IAExC2C,EAAG,MAAM,MAAMC,CAAI;AAAA,EAE9B;AACF;AC3IO,SAASC,KAAW;AACzB,SAAO,KAAK,OAAM,EAAG,SAAQ;AAC/B;AAGO,SAASC,KAAW;AACzB,SAAO,KAAK,SAAS,MAAM,IAAI;AACjC;AAGO,SAASC,KAAO;AACrB,SAAO,KAAK,SAAQ,EAAG,KAAK,SAAQ,IAAK,CAAC;AAC5C;AAGO,SAASC,KAAO;AACrB,SAAO,KAAK,SAAQ,EAAG,KAAK,SAAQ,IAAK,CAAC;AAC5C;AAGO,SAASC,KAAU;AACxB,QAAM,IAAI,KAAK,SAAQ;AAIvB,SAHU,KAAK,OAAM,EAGnB,IAAI,KAAK,OAAM,GAAI,IAAI,CAAC,GAEnB;AACT;AAGO,SAASC,KAAW;AACzB,QAAM,IAAI,KAAK,SAAQ;AAGvB,SAFU,KAAK,OAAM,EAEnB,IAAI,KAAK,OAAM,GAAI,IAAI,IAAI,IAAI,CAAC,GAE3B;AACT;AAGO,SAASC,KAAQ;AAItB,SAHU,KAAK,OAAM,EAGnB,IAAI,KAAK,OAAM,CAAE,GAEZ;AACT;AAGO,SAASC,KAAO;AAIrB,SAHU,KAAK,OAAM,EAGnB,IAAI,KAAK,OAAM,GAAI,CAAC,GAEf;AACT;AAGO,SAASC,GAAO1D,GAAS;AAC9B,EAAAA,IAAU+B,GAAa/B,CAAO,GAC9BA,EAAQ,OAAM;AAEd,QAAMX,IAAI,KAAK,SAAQ;AAEvB,cAAK,OAAM,EAAG,IAAIW,GAASX,CAAC,GAErB;AACT;AAGO,SAASsE,GAAM3D,GAAS;AAC7B,EAAAA,IAAU+B,GAAa/B,CAAO,GAC9BA,EAAQ,OAAM;AAEd,QAAMX,IAAI,KAAK,SAAQ;AAEvB,cAAK,OAAM,EAAG,IAAIW,GAASX,IAAI,CAAC,GAEzB;AACT;AAEO,SAASuE,GAAa5D,GAAS;AACpC,SAAAA,IAAU+B,GAAa/B,CAAO,GAC9BA,EAAQ,OAAO,IAAI,GACZ;AACT;AAEO,SAAS6D,GAAY7D,GAAS;AACnC,SAAAA,IAAU+B,GAAa/B,CAAO,GAC9BA,EAAQ,MAAM,IAAI,GACX;AACT;AAEAtB,EAAgB,OAAO;AAAA,EACrB,UAAAwE;AAAA,EACA,UAAAC;AAAA,EACA,MAAAC;AAAA,EACA,MAAAC;AAAA,EACA,SAAAC;AAAA,EACA,UAAAC;AAAA,EACA,OAAAC;AAAA,EACA,MAAAC;AAAA,EACA,QAAAC;AAAA,EACA,OAAAC;AAAA,EACA,cAAAC;AAAA,EACA,aAAAC;AACF,CAAC;AChHM,MAAMC,KACX,sDAGWC,KAAM,6CAGNC,KAAM,4BAGNC,KAAY,0BAGZC,KAAa,cAGbC,KAAa,OAGbC,KAAQ,kCAGRC,KAAQ,UAGRC,KAAU,YAGVC,KAAW,2CAGXC,KAAU,yCAGVC,KAAY,UAGZC,KAAe;AClCrB,SAASC,KAAU;AACxB,QAAMC,IAAO,KAAK,KAAK,OAAO;AAC9B,SAAOA,KAAQ,OAAO,CAAA,IAAKA,EAAK,KAAI,EAAG,MAAMH,EAAS;AACxD;AAGO,SAASI,GAASlG,GAAM;AAC7B,SAAO,KAAK,QAAO,EAAG,QAAQA,CAAI,MAAM;AAC1C;AAGO,SAASmG,GAASnG,GAAM;AAC7B,MAAI,CAAC,KAAK,SAASA,CAAI,GAAG;AACxB,UAAMQ,IAAQ,KAAK,QAAO;AAC1B,IAAAA,EAAM,KAAKR,CAAI,GACf,KAAK,KAAK,SAASQ,EAAM,KAAK,GAAG,CAAC;AAAA,EACpC;AAEA,SAAO;AACT;AAGO,SAAS4F,GAAYpG,GAAM;AAChC,SAAI,KAAK,SAASA,CAAI,KACpB,KAAK;AAAA,IACH;AAAA,IACA,KAAK,QAAO,EACT,OAAO,SAAUqG,GAAG;AACnB,aAAOA,MAAMrG;AAAA,IACf,CAAC,EACA,KAAK,GAAG;AAAA,EACjB,GAGS;AACT;AAGO,SAASsG,GAAYtG,GAAM;AAChC,SAAO,KAAK,SAASA,CAAI,IAAI,KAAK,YAAYA,CAAI,IAAI,KAAK,SAASA,CAAI;AAC1E;AAEAD,EAAgB,OAAO;AAAA,EACrB,SAAAiG;AAAA,EACA,UAAAE;AAAA,EACA,UAAAC;AAAA,EACA,aAAAC;AAAA,EACA,aAAAE;AACF,CAAC;AChDM,SAASC,GAAIC,GAAOC,GAAK;AAC9B,QAAMC,IAAM,CAAA;AACZ,MAAI,UAAU,WAAW;AAEvB,gBAAK,KAAK,MAAM,QACb,MAAM,SAAS,EACf,OAAO,SAAUC,GAAI;AACpB,aAAO,CAAC,CAACA,EAAG;AAAA,IACd,CAAC,EACA,QAAQ,SAAUA,GAAI;AACrB,YAAMC,IAAID,EAAG,MAAM,SAAS;AAC5B,MAAAD,EAAIE,EAAE,CAAC,CAAC,IAAIA,EAAE,CAAC;AAAA,IACjB,CAAC,GACIF;AAGT,MAAI,UAAU,SAAS,GAAG;AAExB,QAAI,MAAM,QAAQF,CAAK,GAAG;AACxB,iBAAWxG,KAAQwG,GAAO;AACxB,cAAMK,IAAQ7G;AACd,QAAA0G,EAAI1G,CAAI,IAAI,KAAK,KAAK,MAAM,iBAAiB6G,CAAK;AAAA,MACpD;AACA,aAAOH;AAAA,IACT;AAGA,QAAI,OAAOF,KAAU;AACnB,aAAO,KAAK,KAAK,MAAM,iBAAiBA,CAAK;AAI/C,QAAI,OAAOA,KAAU;AACnB,iBAAWxG,KAAQwG;AAEjB,aAAK,KAAK,MAAM;AAAA,UACdxG;AAAA,UACAwG,EAAMxG,CAAI,KAAK,QAAQ2F,GAAQ,KAAKa,EAAMxG,CAAI,CAAC,IAAI,KAAKwG,EAAMxG,CAAI;AAAA,QAC5E;AAAA,EAGE;AAGA,SAAI,UAAU,WAAW,KACvB,KAAK,KAAK,MAAM;AAAA,IACdwG;AAAA,IACAC,KAAO,QAAQd,GAAQ,KAAKc,CAAG,IAAI,KAAKA;AAAA,EAC9C,GAGS;AACT;AAGO,SAASK,KAAO;AACrB,SAAO,KAAK,IAAI,WAAW,EAAE;AAC/B;AAGO,SAASC,KAAO;AACrB,SAAO,KAAK,IAAI,WAAW,MAAM;AACnC;AAGO,SAASC,KAAU;AACxB,SAAO,KAAK,IAAI,SAAS,MAAM;AACjC;AAEAjH,EAAgB,OAAO;AAAA,EACrB,KAAAwG;AAAA,EACA,MAAAO;AAAA,EACA,MAAAC;AAAA,EACA,SAAAC;AACF,CAAC;AC1EM,SAAS3E,GAAK4E,GAAGC,GAAGC,GAAG;AAC5B,MAAIF,KAAK;AAEP,WAAO,KAAK;AAAA,MACV1G;AAAA,QACEM;AAAA,UACE,KAAK,KAAK;AAAA,UACV,CAAC8F,MAAOA,EAAG,SAAS,QAAQ,OAAO,MAAM;AAAA,QACnD;AAAA,QACQ,CAACA,MAAOA,EAAG,SAAS,MAAM,CAAC;AAAA,MACnC;AAAA,IACA;AACS,MAAIM,aAAa,OAAO;AAC7B,UAAM5E,IAAO,CAAA;AACb,eAAWG,KAAOyE;AAChB,MAAA5E,EAAKG,CAAG,IAAI,KAAK,KAAKA,CAAG;AAE3B,WAAOH;AAAA,EACT,WAAW,OAAO4E,KAAM;AACtB,SAAKC,KAAKD;AACR,WAAK,KAAKC,GAAGD,EAAEC,CAAC,CAAC;AAAA,WAEV,UAAU,SAAS;AAC5B,QAAI;AACF,aAAO,KAAK,MAAM,KAAK,KAAK,UAAUD,CAAC,CAAC;AAAA,IAC1C,QAAY;AACV,aAAO,KAAK,KAAK,UAAUA,CAAC;AAAA,IAC9B;AAAA;AAEA,SAAK;AAAA,MACH,UAAUA;AAAA,MACVC,MAAM,OACF,OACAC,MAAM,MAAQ,OAAOD,KAAM,YAAY,OAAOA,KAAM,WAClDA,IACA,KAAK,UAAUA,CAAC;AAAA,IAC5B;AAGE,SAAO;AACT;AAEAnH,EAAgB,OAAO,EAAE,MAAAsC,GAAI,CAAE;AC3CxB,SAAS+E,GAASC,GAAGH,GAAG;AAE7B,MAAI,OAAO,UAAU,CAAC,KAAM;AAC1B,eAAW1E,KAAO6E;AAChB,WAAK,SAAS7E,GAAK6E,EAAE7E,CAAG,CAAC;AAAA,OAEtB;AAAA,QAAI,UAAU,WAAW;AAE9B,aAAO,KAAK,OAAM,EAAG6E,CAAC;AAGtB,SAAK,SAASA,CAAC,IAAIH;AAAA;AAGrB,SAAO;AACT;AAGO,SAASI,KAAS;AACvB,MAAI,UAAU,WAAW;AACvB,SAAK,UAAU,CAAA;AAAA;AAEf,aAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG;AACzC,aAAO,KAAK,SAAS,UAAU,CAAC,CAAC;AAGrC,SAAO;AACT;AAKO,SAASC,KAAS;AACvB,SAAQ,KAAK,UAAU,KAAK,WAAW,CAAA;AACzC;AAEAxH,EAAgB,OAAO,EAAE,UAAAqH,IAAU,QAAAE,IAAQ,QAAAC,GAAM,CAAE;ACrCnD,SAASC,GAAYpC,GAAK;AACxB,SAAOA,EAAI,WAAW,IAClB;AAAA,IACE;AAAA,IACAA,EAAI,UAAU,GAAG,CAAC;AAAA,IAClBA,EAAI,UAAU,GAAG,CAAC;AAAA,IAClBA,EAAI,UAAU,GAAG,CAAC;AAAA,IAClBA,EAAI,UAAU,GAAG,CAAC;AAAA,IAClBA,EAAI,UAAU,GAAG,CAAC;AAAA,IAClBA,EAAI,UAAU,GAAG,CAAC;AAAA,EAC1B,EAAQ,KAAK,EAAE,IACTA;AACN;AAEA,SAASqC,GAAaC,GAAW;AAC/B,QAAMC,IAAU,KAAK,MAAMD,CAAS,GAE9BtC,IADU,KAAK,IAAI,GAAG,KAAK,IAAI,KAAKuC,CAAO,CAAC,EAC9B,SAAS,EAAE;AAC/B,SAAOvC,EAAI,WAAW,IAAI,MAAMA,IAAMA;AACxC;AAEA,SAASwC,GAAGC,GAAQC,GAAO;AACzB,WAASpH,IAAIoH,EAAM,QAAQpH;AACzB,QAAImH,EAAOC,EAAMpH,CAAC,CAAC,KAAK;AACtB,aAAO;AAGX,SAAO;AACT;AAEA,SAASqH,GAAcd,GAAGe,GAAG;AAC3B,QAAMC,IAASL,GAAGX,GAAG,KAAK,IACtB,EAAE,IAAIA,EAAE,GAAG,IAAIA,EAAE,GAAG,IAAIA,EAAE,GAAG,IAAI,GAAG,OAAO,MAAK,IAChDW,GAAGX,GAAG,KAAK,IACT,EAAE,IAAIA,EAAE,GAAG,IAAIA,EAAE,GAAG,IAAIA,EAAE,GAAG,IAAI,GAAG,OAAO,MAAK,IAChDW,GAAGX,GAAG,KAAK,IACT,EAAE,IAAIA,EAAE,GAAG,IAAIA,EAAE,GAAG,IAAIA,EAAE,GAAG,IAAI,GAAG,OAAO,MAAK,IAChDW,GAAGX,GAAG,KAAK,IACT,EAAE,IAAIA,EAAE,GAAG,IAAIA,EAAE,GAAG,IAAIA,EAAE,GAAG,IAAI,GAAG,OAAO,MAAK,IAChDW,GAAGX,GAAG,KAAK,IACT,EAAE,IAAIA,EAAE,GAAG,IAAIA,EAAE,GAAG,IAAIA,EAAE,GAAG,IAAI,GAAG,OAAO,MAAK,IAChDW,GAAGX,GAAG,MAAM,IACV,EAAE,IAAIA,EAAE,GAAG,IAAIA,EAAE,GAAG,IAAIA,EAAE,GAAG,IAAIA,EAAE,GAAG,OAAO,OAAM,IACnD,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,OAAO,MAAK;AAEjD,SAAAgB,EAAO,QAAQD,KAAKC,EAAO,OACpBA;AACT;AAEA,SAASC,GAASJ,GAAO;AACvB,SAAIA,MAAU,SAASA,MAAU,SAASA,MAAU;AAKtD;AAEA,SAASK,GAASC,GAAGC,GAAGzB,GAAG;AAGzB,SAFIA,IAAI,MAAGA,KAAK,IACZA,IAAI,MAAGA,KAAK,IACZA,IAAI,IAAI,IAAUwB,KAAKC,IAAID,KAAK,IAAIxB,IACpCA,IAAI,IAAI,IAAUyB,IAClBzB,IAAI,IAAI,IAAUwB,KAAKC,IAAID,MAAM,IAAI,IAAIxB,KAAK,IAC3CwB;AACT;AAEe,MAAME,EAAM;AAAA,EACzB,eAAeC,GAAQ;AACrB,SAAK,KAAK,GAAGA,CAAM;AAAA,EACrB;AAAA;AAAA,EAGA,OAAO,QAAQC,GAAO;AACpB,WACEA,MAAUA,aAAiBF,KAAS,KAAK,MAAME,CAAK,KAAK,KAAK,KAAKA,CAAK;AAAA,EAE5E;AAAA;AAAA,EAGA,OAAO,MAAMA,GAAO;AAClB,WACEA,KACA,OAAOA,EAAM,KAAM,YACnB,OAAOA,EAAM,KAAM,YACnB,OAAOA,EAAM,KAAM;AAAA,EAEvB;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,OAAOC,IAAO,WAAW7B,GAAG;AAEjC,UAAM,EAAE,QAAA8B,GAAQ,OAAAC,GAAO,KAAAC,GAAK,IAAIC,EAAE,IAAK;AAGvC,QAAIJ,MAAS,WAAW;AACtB,YAAMK,IAAK,KAAWJ,EAAM,IAAK,IAC3BrC,IAAK,KAAWqC,EAAM,IAAK,IAC3BK,IAAI,MAAML,EAAM;AAEtB,aADc,IAAIJ,EAAMQ,GAAGzC,GAAG0C,GAAG,KAAK;AAAA,IAExC,WAAWN,MAAS,QAAQ;AAC1B,MAAA7B,IAAIA,KAAY8B;AAChB,YAAMvB,IAAIwB,EAAM,KAAKC,EAAK,IAAIC,IAAKjC,IAAK,MAAM,IAAI,IAAI,GAAG,GACnD1F,IAAIyH,EAAM,KAAKC,EAAK,IAAIC,IAAKjC,IAAK,MAAM,GAAG,IAAI,GAAG,GAClDoB,IAAIW,EAAM,MAAMC,EAAK,IAAIC,IAAKjC,IAAK,MAAM,GAAG,IAAI,GAAG;AAEzD,aADc,IAAI0B,EAAMnB,GAAGjG,GAAG8G,CAAC;AAAA,IAEjC,WAAWS,MAAS,UAAU;AAC5B,YAAMK,IAAK,IAAWJ,EAAM,IAAK,IAC3BrC,IAAK,KAAUqC,EAAM,IAAK,GAC1BK,IAAI,MAAML,EAAM;AAEtB,aADc,IAAIJ,EAAMQ,GAAGzC,GAAG0C,GAAG,KAAK;AAAA,IAExC,WAAWN,MAAS,QAAQ;AAC1B,YAAMK,IAAI,KAAK,KAAKJ,EAAM,GACpBrC,IAAK,KAAYqC,EAAM,IAAK,IAC5BK,IAAI,MAAML,EAAM;AAEtB,aADc,IAAIJ,EAAMQ,GAAGzC,GAAG0C,GAAG,KAAK;AAAA,IAExC,WAAWN,MAAS,OAAO;AACzB,YAAMtB,IAAI,MAAMuB,EAAM,GAChBxH,IAAI,MAAMwH,EAAM,GAChBV,IAAI,MAAMU,EAAM;AAEtB,aADc,IAAIJ,EAAMnB,GAAGjG,GAAG8G,CAAC;AAAA,IAEjC,WAAWS,MAAS,OAAO;AACzB,YAAMK,IAAI,MAAMJ,EAAM,GAChBzB,IAAI,MAAMyB,MAAW,KACrBV,IAAI,MAAMU,MAAW;AAE3B,aADc,IAAIJ,EAAMQ,GAAG7B,GAAGe,GAAG,KAAK;AAAA,IAExC,WAAWS,MAAS,QAAQ;AAC1B,YAAMO,IAAO,MAAMN,EAAM;AAEzB,aADc,IAAIJ,EAAMU,GAAMA,GAAMA,CAAI;AAAA,IAE1C;AACE,YAAM,IAAI,MAAM,+BAA+B;AAAA,EAEnD;AAAA;AAAA,EAGA,OAAO,KAAKR,GAAO;AACjB,WAAO,OAAOA,KAAU,aAAa/C,GAAM,KAAK+C,CAAK,KAAK9C,GAAM,KAAK8C,CAAK;AAAA,EAC5E;AAAA,EAEA,OAAO;AAEL,UAAM,EAAE,IAAAS,GAAI,IAAAC,GAAI,IAAAC,EAAE,IAAK,KAAK,IAAG,GACzB,CAAChC,GAAGjG,GAAG8G,CAAC,IAAI,CAACiB,GAAIC,GAAIC,CAAE,EAAE,IAAI,CAACjC,MAAMA,IAAI,GAAG,GAG3CG,IAAI,KAAK,IAAI,IAAIF,GAAG,IAAIjG,GAAG,IAAI8G,CAAC;AAEtC,QAAIX,MAAM;AAER,aAAO,IAAIiB,EAAM,GAAG,GAAG,GAAG,GAAG,MAAM;AAGrC,UAAMjC,KAAK,IAAIc,IAAIE,MAAM,IAAIA,IACvBpH,KAAK,IAAIiB,IAAImG,MAAM,IAAIA,IACvBpF,KAAK,IAAI+F,IAAIX,MAAM,IAAIA;AAI7B,WADc,IAAIiB,EAAMjC,GAAGpG,GAAGgC,GAAGoF,GAAG,MAAM;AAAA,EAE5C;AAAA,EAEA,MAAM;AAEJ,UAAM,EAAE,IAAA4B,GAAI,IAAAC,GAAI,IAAAC,EAAE,IAAK,KAAK,IAAG,GACzB,CAAChC,GAAGjG,GAAG8G,CAAC,IAAI,CAACiB,GAAIC,GAAIC,CAAE,EAAE,IAAI,CAACjC,MAAMA,IAAI,GAAG,GAG3CkC,IAAM,KAAK,IAAIjC,GAAGjG,GAAG8G,CAAC,GACtBqB,IAAM,KAAK,IAAIlC,GAAGjG,GAAG8G,CAAC,GACtBc,KAAKM,IAAMC,KAAO,GAGlBC,IAASF,MAAQC,GAGjBE,IAAQH,IAAMC,GACdpI,IAAIqI,IACN,IACAR,IAAI,MACFS,KAAS,IAAIH,IAAMC,KACnBE,KAASH,IAAMC,IACfN,IAAIO,IACN,IACAF,MAAQjC,MACJjG,IAAI8G,KAAKuB,KAASrI,IAAI8G,IAAI,IAAI,MAAM,IACtCoB,MAAQlI,MACJ8G,IAAIb,KAAKoC,IAAQ,KAAK,IACxBH,MAAQpB,MACJb,IAAIjG,KAAKqI,IAAQ,KAAK,IACxB;AAIV,WADc,IAAIjB,EAAM,MAAMS,GAAG,MAAM9H,GAAG,MAAM6H,GAAG,KAAK;AAAA,EAE1D;AAAA,EAEA,KAAK7B,IAAI,GAAGe,IAAI,GAAG3B,IAAI,GAAGtF,IAAI,GAAG+G,IAAQ,OAAO;AAK9C,QAHAb,IAAKA,KAAI,GAGL,KAAK;AACP,iBAAWS,KAAa,KAAK;AAC3B,eAAO,KAAK,KAAK,MAAMA,CAAS,CAAC;AAIrC,QAAI,OAAOT,KAAM;AAEf,MAAAa,IAAQ,OAAO/G,KAAM,WAAWA,IAAI+G,GACpC/G,IAAI,OAAOA,KAAM,WAAW,IAAIA,GAGhC,OAAO,OAAO,MAAM,EAAE,IAAIkG,GAAG,IAAIe,GAAG,IAAI3B,GAAG,IAAItF,GAAG,OAAA+G,EAAK,CAAE;AAAA,aAEhDb,aAAa;AACtB,WAAK,QAAQe,MAAM,OAAOf,EAAE,CAAC,KAAM,WAAWA,EAAE,CAAC,IAAIA,EAAE,CAAC,MAAM,OAC9D,OAAO,OAAO,MAAM,EAAE,IAAIA,EAAE,CAAC,GAAG,IAAIA,EAAE,CAAC,GAAG,IAAIA,EAAE,CAAC,GAAG,IAAIA,EAAE,CAAC,KAAK,EAAC,CAAE;AAAA,aAC1DA,aAAa,QAAQ;AAE9B,YAAMuC,IAASzB,GAAcd,GAAGe,CAAC;AACjC,aAAO,OAAO,MAAMwB,CAAM;AAAA,IAC5B,WAAW,OAAOvC,KAAM;AACtB,UAAIvB,GAAM,KAAKuB,CAAC,GAAG;AACjB,cAAMwC,IAAexC,EAAE,QAAQzB,IAAY,EAAE,GACvC,CAACyD,GAAIC,GAAIC,CAAE,IAAI9D,GAClB,KAAKoE,CAAY,EACjB,MAAM,GAAG,CAAC,EACV,IAAI,CAACvC,MAAM,SAASA,CAAC,CAAC;AACzB,eAAO,OAAO,MAAM,EAAE,IAAA+B,GAAI,IAAAC,GAAI,IAAAC,GAAI,IAAI,GAAG,OAAO,MAAK,CAAE;AAAA,MACzD,WAAW1D,GAAM,KAAKwB,CAAC,GAAG;AACxB,cAAMyC,IAAW,CAACxC,MAAM,SAASA,GAAG,EAAE,GAChC,GAAG+B,GAAIC,GAAIC,CAAE,IAAI/D,GAAI,KAAKoC,GAAYP,CAAC,CAAC,EAAE,IAAIyC,CAAQ;AAC5D,eAAO,OAAO,MAAM,EAAE,IAAAT,GAAI,IAAAC,GAAI,IAAAC,GAAI,IAAI,GAAG,OAAO,MAAK,CAAE;AAAA,MACzD,MAAO,OAAM,MAAM,kDAAkD;AAIvE,UAAM,EAAE,IAAAF,GAAI,IAAAC,GAAI,IAAAC,GAAI,IAAAQ,EAAE,IAAK,MACrBC,IACJ,KAAK,UAAU,QACX,EAAEX,GAAO,GAAGC,GAAI,GAAGC,EAAE,IACrB,KAAK,UAAU,QACb,EAAE,GAAGF,GAAI,GAAGC,GAAI,GAAGC,EAAE,IACrB,KAAK,UAAU,QACb,EAAE,GAAGF,GAAI,GAAGC,GAAIC,EAAK,IACrB,KAAK,UAAU,QACb,EAAE,GAAGF,GAAIC,GAAO,GAAGC,EAAE,IACrB,KAAK,UAAU,QACb,EAAE,GAAGF,GAAI,GAAGC,GAAI,GAAGC,EAAE,IACrB,KAAK,UAAU,SACb,EAAE,GAAGF,GAAI,GAAGC,GAAI,GAAGC,GAAI,GAAGQ,EAAE,IAC5B,CAAA;AAChB,WAAO,OAAO,MAAMC,CAAU;AAAA,EAChC;AAAA,EAEA,MAAM;AAEJ,UAAM,EAAE,GAAA5H,GAAG,GAAAC,GAAG,GAAA4H,EAAC,IAAK,KAAK,IAAG,GAGtBf,IAAI,MAAM7G,IAAI,IACdgF,IAAI,OAAOjF,IAAIC,IACf+F,IAAI,OAAO/F,IAAI4H;AAIrB,WADc,IAAIvB,EAAMQ,GAAG7B,GAAGe,GAAG,KAAK;AAAA,EAExC;AAAA,EAEA,MAAM;AAEJ,UAAM,EAAE,GAAAc,GAAG,GAAA7B,GAAG,GAAAe,EAAC,IAAK,KAAK,IAAG,GAGtB3B,IAAI,KAAK,KAAKY,KAAK,IAAIe,KAAK,CAAC;AACnC,QAAIe,IAAK,MAAM,KAAK,MAAMf,GAAGf,CAAC,IAAK,KAAK;AACxC,WAAI8B,IAAI,MACNA,KAAK,IACLA,IAAI,MAAMA,IAIE,IAAIT,EAAMQ,GAAGzC,GAAG0C,GAAG,KAAK;AAAA,EAExC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM;AACJ,QAAI,KAAK,UAAU;AACjB,aAAO;AACF,QAAIb,GAAS,KAAK,KAAK,GAAG;AAE/B,UAAI,EAAE,GAAAlG,GAAG,GAAAC,GAAG,GAAA4H,MAAM;AAClB,UAAI,KAAK,UAAU,SAAS,KAAK,UAAU,OAAO;AAEhD,YAAI,EAAE,GAAAf,GAAG,GAAA7B,GAAG,GAAAe,MAAM;AAClB,YAAI,KAAK,UAAU,OAAO;AACxB,gBAAM,EAAE,GAAA3B,GAAG,GAAA0C,MAAM,MACXe,IAAO,KAAK,KAAK;AACvB,UAAA7C,IAAIZ,IAAI,KAAK,IAAIyD,IAAOf,CAAC,GACzBf,IAAI3B,IAAI,KAAK,IAAIyD,IAAOf,CAAC;AAAA,QAC3B;AAGA,cAAMgB,KAAMjB,IAAI,MAAM,KAChBkB,IAAK/C,IAAI,MAAM8C,GACfE,IAAKF,IAAK/B,IAAI,KAGdkC,IAAK,KAAK,KACVC,IAAK,SACLC,IAAK;AACX,QAAApI,IAAI,WAAWgI,KAAM,IAAIG,IAAKH,KAAM,KAAKA,IAAKE,KAAME,IACpDnI,IAAI,KAAO8H,KAAM,IAAII,IAAKJ,KAAM,KAAKA,IAAKG,KAAME,IAChDP,IAAI,WAAWI,KAAM,IAAIE,IAAKF,KAAM,KAAKA,IAAKC,KAAME;AAAA,MACtD;AAGA,YAAMC,IAAKrI,IAAI,SAASC,IAAI,UAAU4H,IAAI,SACpCS,IAAKtI,IAAI,UAAUC,IAAI,SAAS4H,IAAI,QACpCU,IAAKvI,IAAI,SAASC,IAAI,SAAS4H,IAAI,OAGnCW,IAAM,KAAK,KACXC,IAAK,UACLtD,IAAIkD,IAAKI,IAAK,QAAQD,EAAIH,GAAI,IAAI,GAAG,IAAI,QAAQ,QAAQA,GACzDnJ,IAAIoJ,IAAKG,IAAK,QAAQD,EAAIF,GAAI,IAAI,GAAG,IAAI,QAAQ,QAAQA,GACzDtC,IAAIuC,IAAKE,IAAK,QAAQD,EAAID,GAAI,IAAI,GAAG,IAAI,QAAQ,QAAQA;AAI/D,aADc,IAAIjC,EAAM,MAAMnB,GAAG,MAAMjG,GAAG,MAAM8G,CAAC;AAAA,IAEnD,WAAW,KAAK,UAAU,OAAO;AAG/B,UAAI,EAAE,GAAAe,GAAG,GAAA9H,GAAG,GAAA6H,MAAM;AAMlB,UALAC,KAAK,KACL9H,KAAK,KACL6H,KAAK,KAGD7H,MAAM;AACR,eAAA6H,KAAK,KACS,IAAIR,EAAMQ,GAAGA,GAAGA,CAAC;AAKjC,YAAMT,IAAIS,IAAI,MAAMA,KAAK,IAAI7H,KAAK6H,IAAI7H,IAAI6H,IAAI7H,GACxCmH,IAAI,IAAIU,IAAIT,GAGZ,IAAI,MAAMF,GAASC,GAAGC,GAAGU,IAAI,IAAI,CAAC,GAClC7H,IAAI,MAAMiH,GAASC,GAAGC,GAAGU,CAAC,GAC1Bf,IAAI,MAAMG,GAASC,GAAGC,GAAGU,IAAI,IAAI,CAAC;AAIxC,aADc,IAAIT,EAAM,GAAGpH,GAAG8G,CAAC;AAAA,IAEjC,WAAW,KAAK,UAAU,QAAQ;AAGhC,YAAM,EAAE,GAAA3B,GAAG,GAAApG,GAAG,GAAAgC,GAAG,GAAAoF,EAAC,IAAK,MAGjBF,IAAI,OAAO,IAAI,KAAK,IAAI,GAAGd,KAAK,IAAIgB,KAAKA,CAAC,IAC1CnG,IAAI,OAAO,IAAI,KAAK,IAAI,GAAGjB,KAAK,IAAIoH,KAAKA,CAAC,IAC1CW,IAAI,OAAO,IAAI,KAAK,IAAI,GAAG/F,KAAK,IAAIoF,KAAKA,CAAC;AAIhD,aADc,IAAIiB,EAAMnB,GAAGjG,GAAG8G,CAAC;AAAA,IAEjC;AACE,aAAO;AAAA,EAEX;AAAA,EAEA,UAAU;AACR,UAAM,EAAE,IAAAiB,GAAI,IAAAC,GAAI,IAAAC,GAAI,IAAAQ,GAAI,OAAA7B,EAAK,IAAK;AAClC,WAAO,CAACmB,GAAIC,GAAIC,GAAIQ,GAAI7B,CAAK;AAAA,EAC/B;AAAA,EAEA,QAAQ;AACN,UAAM,CAACX,GAAGjG,GAAG8G,CAAC,IAAI,KAAK,SAAQ,EAAG,IAAIP,EAAY;AAClD,WAAO,IAAIN,CAAC,GAAGjG,CAAC,GAAG8G,CAAC;AAAA,EACtB;AAAA,EAEA,QAAQ;AACN,UAAM,CAAC0C,GAAIC,GAAIC,CAAE,IAAI,KAAK,SAAQ;AAElC,WADe,OAAOF,CAAE,IAAIC,CAAE,IAAIC,CAAE;AAAA,EAEtC;AAAA,EAEA,WAAW;AACT,WAAO,KAAK,MAAK;AAAA,EACnB;AAAA,EAEA,MAAM;AAEJ,UAAM,EAAE,IAAIC,GAAM,IAAIC,GAAM,IAAIC,MAAS,KAAK,IAAG,GAC3C,CAAC5D,GAAGjG,GAAG8G,CAAC,IAAI,CAAC6C,GAAMC,GAAMC,CAAI,EAAE,IAAI,CAAC7D,MAAMA,IAAI,GAAG,GAGjD8D,IAAK7D,IAAI,UAAU,KAAK,KAAKA,IAAI,SAAS,OAAO,GAAG,IAAIA,IAAI,OAC5D8D,IAAK/J,IAAI,UAAU,KAAK,KAAKA,IAAI,SAAS,OAAO,GAAG,IAAIA,IAAI,OAC5DgK,IAAKlD,IAAI,UAAU,KAAK,KAAKA,IAAI,SAAS,OAAO,GAAG,IAAIA,IAAI,OAG5DmD,KAAMH,IAAK,SAASC,IAAK,SAASC,IAAK,UAAU,SACjDE,KAAMJ,IAAK,SAASC,IAAK,SAASC,IAAK,UAAU,GACjDG,KAAML,IAAK,SAASC,IAAK,SAASC,IAAK,UAAU,SAGjDlJ,IAAImJ,IAAK,UAAW,KAAK,IAAIA,GAAI,IAAI,CAAC,IAAI,QAAQA,IAAK,KAAK,KAC5DlJ,IAAImJ,IAAK,UAAW,KAAK,IAAIA,GAAI,IAAI,CAAC,IAAI,QAAQA,IAAK,KAAK,KAC5DvB,IAAIwB,IAAK,UAAW,KAAK,IAAIA,GAAI,IAAI,CAAC,IAAI,QAAQA,IAAK,KAAK;AAIlE,WADc,IAAI/C,EAAMtG,GAAGC,GAAG4H,GAAG,KAAK;AAAA,EAExC;AAAA;AAAA;AAAA;AAAA,EAMA,WAAW;AACT,UAAM,EAAE,IAAAZ,GAAI,IAAAC,GAAI,IAAAC,EAAE,IAAK,KAAK,IAAG,GACzB,EAAE,KAAAC,GAAK,KAAAC,GAAK,OAAAV,MAAU,MACtB2C,IAAS,CAACpE,MAAMkC,EAAI,GAAGC,EAAIV,EAAMzB,CAAC,GAAG,GAAG,CAAC;AAC/C,WAAO,CAAC+B,GAAIC,GAAIC,CAAE,EAAE,IAAImC,CAAM;AAAA,EAChC;AAAA;AAAA;AAAA;AAKF;AC/be,MAAMC,EAAM;AAAA;AAAA,EAEzB,eAAejH,GAAM;AACnB,SAAK,KAAK,GAAGA,CAAI;AAAA,EACnB;AAAA;AAAA,EAGA,QAAQ;AACN,WAAO,IAAIiH,EAAM,IAAI;AAAA,EACvB;AAAA,EAEA,KAAKvJ,GAAGC,GAAG;AACT,UAAMuJ,IAAO,EAAE,GAAG,GAAG,GAAG,EAAC,GAGnBC,IAAS,MAAM,QAAQzJ,CAAC,IAC1B,EAAE,GAAGA,EAAE,CAAC,GAAG,GAAGA,EAAE,CAAC,EAAC,IAClB,OAAOA,KAAM,WACX,EAAE,GAAGA,EAAE,GAAG,GAAGA,EAAE,EAAC,IAChB,EAAE,GAAGA,GAAG,GAAGC,EAAC;AAGlB,gBAAK,IAAIwJ,EAAO,KAAK,OAAOD,EAAK,IAAIC,EAAO,GAC5C,KAAK,IAAIA,EAAO,KAAK,OAAOD,EAAK,IAAIC,EAAO,GAErC;AAAA,EACT;AAAA,EAEA,UAAU;AACR,WAAO,CAAC,KAAK,GAAG,KAAK,CAAC;AAAA,EACxB;AAAA,EAEA,UAAUxL,GAAG;AACX,WAAO,KAAK,QAAQ,WAAWA,CAAC;AAAA,EAClC;AAAA;AAAA,EAGA,WAAWA,GAAG;AACZ,IAAKyL,EAAO,aAAazL,CAAC,MACxBA,IAAI,IAAIyL,EAAOzL,CAAC;AAGlB,UAAM,EAAE,GAAA+B,GAAG,GAAAC,MAAM;AAGjB,gBAAK,IAAIhC,EAAE,IAAI+B,IAAI/B,EAAE,IAAIgC,IAAIhC,EAAE,GAC/B,KAAK,IAAIA,EAAE,IAAI+B,IAAI/B,EAAE,IAAIgC,IAAIhC,EAAE,GAExB;AAAA,EACT;AACF;AAEO,SAAS0L,GAAM3J,GAAGC,GAAG;AAC1B,SAAO,IAAIsJ,EAAMvJ,GAAGC,CAAC,EAAE,WAAW,KAAK,UAAS,EAAG,SAAQ,CAAE;AAC/D;AClDA,SAAS2J,GAAY3E,GAAGe,GAAG6D,GAAW;AACpC,SAAO,KAAK,IAAI7D,IAAIf,CAAC,IAAkB;AACzC;AAEe,IAAA6E,IAAA,MAAMJ,EAAO;AAAA,EAC1B,eAAepH,GAAM;AACnB,SAAK,KAAK,GAAGA,CAAI;AAAA,EACnB;AAAA,EAEA,OAAO,iBAAiB5C,GAAG;AAEzB,UAAMqK,IAAWrK,EAAE,SAAS,UAAUA,EAAE,SAAS,IAC3CsK,IAAQtK,EAAE,SAASqK,KAAYrK,EAAE,SAAS,OAAO,KAAK,GACtDuK,IAAQvK,EAAE,SAASqK,KAAYrK,EAAE,SAAS,OAAO,KAAK,GACtDwK,IACJxK,EAAE,QAAQA,EAAE,KAAK,SACbA,EAAE,KAAK,CAAC,IACR,SAASA,EAAE,IAAI,IACbA,EAAE,OACF,SAASA,EAAE,KAAK,IACdA,EAAE,QACF,GACJyK,IACJzK,EAAE,QAAQA,EAAE,KAAK,SACbA,EAAE,KAAK,CAAC,IACR,SAASA,EAAE,IAAI,IACbA,EAAE,OACF,SAASA,EAAE,KAAK,IACdA,EAAE,QACF,GACJ0K,IACJ1K,EAAE,SAASA,EAAE,MAAM,SACfA,EAAE,MAAM,CAAC,IAAIsK,IACb,SAAStK,EAAE,KAAK,IACdA,EAAE,QAAQsK,IACV,SAAStK,EAAE,MAAM,IACfA,EAAE,SAASsK,IACXA,GACJK,IACJ3K,EAAE,SAASA,EAAE,MAAM,SACfA,EAAE,MAAM,CAAC,IAAIuK,IACb,SAASvK,EAAE,KAAK,IACdA,EAAE,QAAQuK,IACV,SAASvK,EAAE,MAAM,IACfA,EAAE,SAASuK,IACXA,GACJK,IAAQ5K,EAAE,SAAS,GACnB6K,IAAQ7K,EAAE,UAAUA,EAAE,SAAS,GAC/BC,IAAS,IAAI4J;AAAA,MACjB7J,EAAE,UAAUA,EAAE,UAAUA,EAAE,MAAMA,EAAE;AAAA,MAClCA,EAAE,MAAMA,EAAE;AAAA,IAChB,GACUE,IAAKD,EAAO,GACZE,IAAKF,EAAO,GAEZ6C,IAAW,IAAI+G;AAAA,MACnB7J,EAAE,YAAYA,EAAE,MAAMA,EAAE,aAAa;AAAA,MACrCA,EAAE,MAAMA,EAAE,aAAa;AAAA,IAC7B,GACU8K,IAAKhI,EAAS,GACdiI,IAAKjI,EAAS,GACdkI,IAAY,IAAInB;AAAA,MACpB7J,EAAE,aAAaA,EAAE,MAAMA,EAAE;AAAA,MACzBA,EAAE,MAAMA,EAAE;AAAA,IAChB,GACUiL,IAAKD,EAAU,GACfE,IAAKF,EAAU,GACfG,IAAW,IAAItB;AAAA,MACnB7J,EAAE,YAAYA,EAAE,MAAMA,EAAE;AAAA,MACxBA,EAAE,MAAMA,EAAE;AAAA,IAChB,GACUoL,IAAKD,EAAS,GACdE,IAAKF,EAAS;AAGpB,WAAO;AAAA,MACL,QAAAT;AAAA,MACA,QAAAC;AAAA,MACA,OAAAH;AAAA,MACA,OAAAC;AAAA,MACA,OAAAG;AAAA,MACA,OAAAC;AAAA,MACA,IAAAO;AAAA,MACA,IAAAC;AAAA,MACA,IAAAJ;AAAA,MACA,IAAAC;AAAA,MACA,IAAAhL;AAAA,MACA,IAAAC;AAAA,MACA,IAAA2K;AAAA,MACA,IAAAC;AAAA,IACN;AAAA,EACE;AAAA,EAEA,OAAO,UAAUxF,GAAG;AAClB,WAAO,EAAE,GAAGA,EAAE,CAAC,GAAG,GAAGA,EAAE,CAAC,GAAG,GAAGA,EAAE,CAAC,GAAG,GAAGA,EAAE,CAAC,GAAG,GAAGA,EAAE,CAAC,GAAG,GAAGA,EAAE,CAAC,EAAC;AAAA,EAC/D;AAAA,EAEA,OAAO,aAAavF,GAAG;AACrB,WACEA,EAAE,KAAK,QACPA,EAAE,KAAK,QACPA,EAAE,KAAK,QACPA,EAAE,KAAK,QACPA,EAAE,KAAK,QACPA,EAAE,KAAK;AAAA,EAEX;AAAA;AAAA,EAGA,OAAO,eAAeoH,GAAG3B,GAAGzF,GAAG;AAE7B,UAAMuF,IAAI6B,EAAE,IAAI3B,EAAE,IAAI2B,EAAE,IAAI3B,EAAE,GACxBa,IAAIc,EAAE,IAAI3B,EAAE,IAAI2B,EAAE,IAAI3B,EAAE,GACxBd,IAAIyC,EAAE,IAAI3B,EAAE,IAAI2B,EAAE,IAAI3B,EAAE,GACxBpG,IAAI+H,EAAE,IAAI3B,EAAE,IAAI2B,EAAE,IAAI3B,EAAE,GACxB6F,IAAIlE,EAAE,IAAIA,EAAE,IAAI3B,EAAE,IAAI2B,EAAE,IAAI3B,EAAE,GAC9B8F,IAAInE,EAAE,IAAIA,EAAE,IAAI3B,EAAE,IAAI2B,EAAE,IAAI3B,EAAE;AAGpC,WAAAzF,EAAE,IAAIuF,GACNvF,EAAE,IAAIsG,GACNtG,EAAE,IAAI2E,GACN3E,EAAE,IAAIX,GACNW,EAAE,IAAIsL,GACNtL,EAAE,IAAIuL,GAECvL;AAAA,EACT;AAAA,EAEA,OAAOwL,GAAIC,GAAIC,GAAQ;AACrB,WAAO,KAAK,MAAK,EAAG,QAAQF,GAAIC,GAAIC,CAAM;AAAA,EAC5C;AAAA;AAAA,EAGA,QAAQF,GAAIC,GAAIC,GAAQ;AACtB,UAAMC,IAAKH,KAAM,GACXI,IAAKH,KAAM;AACjB,WAAO,KAAK,WAAW,CAACE,GAAI,CAACC,CAAE,EAAE,WAAWF,CAAM,EAAE,WAAWC,GAAIC,CAAE;AAAA,EACvE;AAAA;AAAA,EAGA,QAAQ;AACN,WAAO,IAAI5B,EAAO,IAAI;AAAA,EACxB;AAAA;AAAA,EAGA,UAAUwB,IAAK,GAAGC,IAAK,GAAG;AAExB,UAAMlG,IAAI,KAAK,GACTe,IAAI,KAAK,GACT3B,IAAI,KAAK,GACTtF,IAAI,KAAK,GACTiM,IAAI,KAAK,GACTC,IAAI,KAAK,GAGTM,IAActG,IAAIlG,IAAIiH,IAAI3B,GAC1BmH,IAAMD,IAAc,IAAI,IAAI,IAI5BE,IAAKD,IAAM,KAAK,KAAKvG,IAAIA,IAAIe,IAAIA,CAAC,GAClC0F,IAAW,KAAK,MAAMF,IAAMxF,GAAGwF,IAAMvG,CAAC,GACtCsF,IAAS,MAAM,KAAK,KAAMmB,GAC1BxD,IAAK,KAAK,IAAIwD,CAAQ,GACtBC,IAAK,KAAK,IAAID,CAAQ,GAItBE,KAAO3G,IAAIZ,IAAI2B,IAAIjH,KAAKwM,GACxBM,IAAMxH,IAAIoH,KAAOG,IAAM3G,IAAIe,MAAOjH,IAAI0M,KAAOG,IAAM5F,IAAIf,IAGvD0F,IAAKK,IAAIE,IAAKA,IAAKhD,IAAKuD,IAAKN,KAAMS,IAAM1D,IAAKuD,IAAKE,IAAKE,IACxDjB,IAAKK,IAAIE,IAAKD,IAAKS,IAAKF,IAAKN,KAAMS,IAAMD,IAAKF,IAAKvD,IAAK2D;AAG9D,WAAO;AAAA;AAAA,MAEL,QAAQJ;AAAA,MACR,QAAQI;AAAA,MACR,OAAOD;AAAA,MACP,QAAQrB;AAAA,MACR,YAAYI;AAAA,MACZ,YAAYC;AAAA,MACZ,SAASM;AAAA,MACT,SAASC;AAAA;AAAA,MAGT,GAAG,KAAK;AAAA,MACR,GAAG,KAAK;AAAA,MACR,GAAG,KAAK;AAAA,MACR,GAAG,KAAK;AAAA,MACR,GAAG,KAAK;AAAA,MACR,GAAG,KAAK;AAAA,IACd;AAAA,EACE;AAAA;AAAA,EAGA,OAAOW,GAAO;AACZ,QAAIA,MAAU,KAAM,QAAO;AAC3B,UAAMC,IAAO,IAAIrC,EAAOoC,CAAK;AAC7B,WACElC,GAAY,KAAK,GAAGmC,EAAK,CAAC,KAC1BnC,GAAY,KAAK,GAAGmC,EAAK,CAAC,KAC1BnC,GAAY,KAAK,GAAGmC,EAAK,CAAC,KAC1BnC,GAAY,KAAK,GAAGmC,EAAK,CAAC,KAC1BnC,GAAY,KAAK,GAAGmC,EAAK,CAAC,KAC1BnC,GAAY,KAAK,GAAGmC,EAAK,CAAC;AAAA,EAE9B;AAAA;AAAA,EAGA,KAAKC,GAAMC,GAAQ;AACjB,WAAO,KAAK,MAAK,EAAG,MAAMD,GAAMC,CAAM;AAAA,EACxC;AAAA,EAEA,MAAMD,GAAMC,GAAQ;AAClB,WAAOD,MAAS,MACZ,KAAK,OAAO,IAAI,GAAGC,GAAQ,CAAC,IAC5BD,MAAS,MACP,KAAK,OAAO,GAAG,IAAI,GAAGC,CAAM,IAC5B,KAAK,OAAO,IAAI,IAAID,GAAMC,KAAUD,CAAI;AAAA,EAChD;AAAA;AAAA,EAGA,KAAKvC,GAAQ;AACX,UAAMD,IAAOE,EAAO,UAAU,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;AAGhD,WAAAD,IACEA,aAAkByC,KACdzC,EAAO,UAAS,IAChB,OAAOA,KAAW,WAChBC,EAAO,UAAUD,EAAO,MAAM3F,EAAS,EAAE,IAAI,UAAU,CAAC,IACxD,MAAM,QAAQ2F,CAAM,IAClBC,EAAO,UAAUD,CAAM,IACvB,OAAOA,KAAW,YAAYC,EAAO,aAAaD,CAAM,IACtDA,IACA,OAAOA,KAAW,WAChB,IAAIC,EAAM,EAAG,UAAUD,CAAM,IAC7B,UAAU,WAAW,IACnBC,EAAO,UAAU,CAAA,EAAG,MAAM,KAAK,SAAS,CAAC,IACzCF,GAGhB,KAAK,IAAIC,EAAO,KAAK,OAAOA,EAAO,IAAID,EAAK,GAC5C,KAAK,IAAIC,EAAO,KAAK,OAAOA,EAAO,IAAID,EAAK,GAC5C,KAAK,IAAIC,EAAO,KAAK,OAAOA,EAAO,IAAID,EAAK,GAC5C,KAAK,IAAIC,EAAO,KAAK,OAAOA,EAAO,IAAID,EAAK,GAC5C,KAAK,IAAIC,EAAO,KAAK,OAAOA,EAAO,IAAID,EAAK,GAC5C,KAAK,IAAIC,EAAO,KAAK,OAAOA,EAAO,IAAID,EAAK,GAErC;AAAA,EACT;AAAA,EAEA,UAAU;AACR,WAAO,KAAK,MAAK,EAAG,SAAQ;AAAA,EAC9B;AAAA;AAAA,EAGA,WAAW;AAET,UAAMvE,IAAI,KAAK,GACTe,IAAI,KAAK,GACT3B,IAAI,KAAK,GACTtF,IAAI,KAAK,GACTiM,IAAI,KAAK,GACTC,IAAI,KAAK,GAGTkB,IAAMlH,IAAIlG,IAAIiH,IAAI3B;AACxB,QAAI,CAAC8H,EAAK,OAAM,IAAI,MAAM,mBAAmB,IAAI;AAGjD,UAAMC,IAAKrN,IAAIoN,GACTE,IAAK,CAACrG,IAAImG,GACVG,IAAK,CAACjI,IAAI8H,GACVI,IAAKtH,IAAIkH,GAGTK,IAAK,EAAEJ,IAAKpB,IAAIsB,IAAKrB,IACrBwB,IAAK,EAAEJ,IAAKrB,IAAIuB,IAAKtB;AAG3B,gBAAK,IAAImB,GACT,KAAK,IAAIC,GACT,KAAK,IAAIC,GACT,KAAK,IAAIC,GACT,KAAK,IAAIC,GACT,KAAK,IAAIC,GAEF;AAAA,EACT;AAAA,EAEA,UAAUrB,GAAQ;AAChB,WAAO,KAAK,QAAQ,WAAWA,CAAM;AAAA,EACvC;AAAA,EAEA,WAAWA,GAAQ;AACjB,UAAMjG,IAAI,MACJ2B,IAAIsE,aAAkB1B,IAAS0B,IAAS,IAAI1B,EAAO0B,CAAM;AAE/D,WAAO1B,EAAO,eAAe5C,GAAG3B,GAAG,IAAI;AAAA,EACzC;AAAA;AAAA,EAGA,SAASiG,GAAQ;AACf,WAAO,KAAK,QAAQ,UAAUA,CAAM;AAAA,EACtC;AAAA,EAEA,UAAUA,GAAQ;AAEhB,UAAMtE,IAAI,MACJ3B,IAAIiG,aAAkB1B,IAAS0B,IAAS,IAAI1B,EAAO0B,CAAM;AAE/D,WAAO1B,EAAO,eAAe5C,GAAG3B,GAAG,IAAI;AAAA,EACzC;AAAA;AAAA,EAGA,OAAOA,GAAG+F,GAAIC,GAAI;AAChB,WAAO,KAAK,MAAK,EAAG,QAAQhG,GAAG+F,GAAIC,CAAE;AAAA,EACvC;AAAA,EAEA,QAAQhG,GAAG+F,IAAK,GAAGC,IAAK,GAAG;AAEzB,IAAAhG,IAAIrG,GAAQqG,CAAC;AAEb,UAAMuH,IAAM,KAAK,IAAIvH,CAAC,GAChByB,IAAM,KAAK,IAAIzB,CAAC,GAEhB,EAAE,GAAAF,GAAG,GAAAe,GAAG,GAAA3B,GAAG,GAAAtF,GAAG,GAAAiM,GAAG,GAAAC,MAAM;AAE7B,gBAAK,IAAIhG,IAAIyH,IAAM1G,IAAIY,GACvB,KAAK,IAAIZ,IAAI0G,IAAMzH,IAAI2B,GACvB,KAAK,IAAIvC,IAAIqI,IAAM3N,IAAI6H,GACvB,KAAK,IAAI7H,IAAI2N,IAAMrI,IAAIuC,GACvB,KAAK,IAAIoE,IAAI0B,IAAMzB,IAAIrE,IAAMuE,IAAKvE,IAAMsE,IAAKwB,IAAMxB,GACnD,KAAK,IAAID,IAAIyB,IAAM1B,IAAIpE,IAAMsE,IAAKtE,IAAMuE,IAAKuB,IAAMvB,GAE5C;AAAA,EACT;AAAA;AAAA,EAGA,QAAQ;AACN,WAAO,KAAK,QAAQ,OAAO,GAAG,SAAS;AAAA,EACzC;AAAA,EAEA,OAAOnL,GAAGC,IAAID,GAAGkL,IAAK,GAAGC,IAAK,GAAG;AAE/B,IAAI,UAAU,WAAW,MACvBA,IAAKD,GACLA,IAAKjL,GACLA,IAAID;AAGN,UAAM,EAAE,GAAAiF,GAAG,GAAAe,GAAG,GAAA3B,GAAG,GAAAtF,GAAG,GAAAiM,GAAG,GAAAC,MAAM;AAE7B,gBAAK,IAAIhG,IAAIjF,GACb,KAAK,IAAIgG,IAAI/F,GACb,KAAK,IAAIoE,IAAIrE,GACb,KAAK,IAAIjB,IAAIkB,GACb,KAAK,IAAI+K,IAAIhL,IAAIkL,IAAKlL,IAAIkL,GAC1B,KAAK,IAAID,IAAIhL,IAAIkL,IAAKlL,IAAIkL,GAEnB;AAAA,EACT;AAAA;AAAA,EAGA,MAAMlG,GAAGiG,GAAIC,GAAI;AACf,WAAO,KAAK,MAAK,EAAG,OAAOlG,GAAGiG,GAAIC,CAAE;AAAA,EACtC;AAAA;AAAA,EAGA,OAAOwB,GAAIzB,IAAK,GAAGC,IAAK,GAAG;AACzB,UAAM,EAAE,GAAAlG,GAAG,GAAAe,GAAG,GAAA3B,GAAG,GAAAtF,GAAG,GAAAiM,GAAG,GAAAC,MAAM;AAE7B,gBAAK,IAAIhG,IAAIe,IAAI2G,GACjB,KAAK,IAAItI,IAAItF,IAAI4N,GACjB,KAAK,IAAI3B,IAAIC,IAAI0B,IAAKxB,IAAKwB,GAEpB;AAAA,EACT;AAAA;AAAA,EAGA,OAAO;AACL,WAAO,KAAK,QAAQ,MAAM,GAAG,SAAS;AAAA,EACxC;AAAA,EAEA,MAAM3M,GAAGC,IAAID,GAAGkL,IAAK,GAAGC,IAAK,GAAG;AAE9B,IAAI,UAAU,WAAW,MACvBA,IAAKD,GACLA,IAAKjL,GACLA,IAAID,IAINA,IAAIlB,GAAQkB,CAAC,GACbC,IAAInB,GAAQmB,CAAC;AAEb,UAAM0M,IAAK,KAAK,IAAI3M,CAAC,GACf4M,IAAK,KAAK,IAAI3M,CAAC,GAEf,EAAE,GAAG,GAAA+F,GAAG,GAAG,GAAAjH,GAAG,GAAAiM,GAAG,GAAAC,MAAM;AAE7B,gBAAK,IAAI,IAAIjF,IAAI2G,GACjB,KAAK,IAAI3G,IAAI,IAAI4G,GACjB,KAAK,IAAI,IAAI7N,IAAI4N,GACjB,KAAK,IAAI5N,IAAI,IAAI6N,GACjB,KAAK,IAAI5B,IAAIC,IAAI0B,IAAKxB,IAAKwB,GAC3B,KAAK,IAAI1B,IAAID,IAAI4B,IAAK1B,IAAK0B,GAEpB;AAAA,EACT;AAAA;AAAA,EAGA,MAAM5M,GAAGkL,GAAIC,GAAI;AACf,WAAO,KAAK,KAAKnL,GAAG,GAAGkL,GAAIC,CAAE;AAAA,EAC/B;AAAA;AAAA,EAGA,MAAMlL,GAAGiL,GAAIC,GAAI;AACf,WAAO,KAAK,KAAK,GAAGlL,GAAGiL,GAAIC,CAAE;AAAA,EAC/B;AAAA,EAEA,UAAU;AACR,WAAO,CAAC,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAAA,EACxD;AAAA;AAAA,EAGA,WAAW;AACT,WACE,YACA,KAAK,IACL,MACA,KAAK,IACL,MACA,KAAK,IACL,MACA,KAAK,IACL,MACA,KAAK,IACL,MACA,KAAK,IACL;AAAA,EAEJ;AAAA;AAAA,EAGA,UAAUzL,GAAG;AAEX,QAAIgK,EAAO,aAAahK,CAAC;AAEvB,aADe,IAAIgK,EAAOhK,CAAC,EACb,UAAU,IAAI;AAI9B,UAAMkF,IAAI8E,EAAO,iBAAiBhK,CAAC,GAC7BmN,IAAU,MACV,EAAE,GAAGjN,GAAI,GAAGC,EAAE,IAAK,IAAI0J,EAAM3E,EAAE,IAAIA,EAAE,EAAE,EAAE,UAAUiI,CAAO,GAG1DC,IAAc,IAAIpD,EAAM,EAC3B,WAAW9E,EAAE,IAAIA,EAAE,EAAE,EACrB,WAAWiI,CAAO,EAClB,WAAW,CAACjN,GAAI,CAACC,CAAE,EACnB,OAAO+E,EAAE,QAAQA,EAAE,MAAM,EACzB,MAAMA,EAAE,OAAOA,EAAE,KAAK,EACtB,OAAOA,EAAE,KAAK,EACd,QAAQA,EAAE,KAAK,EACf,WAAWhF,GAAIC,CAAE;AAGpB,QAAI,SAAS+E,EAAE,EAAE,KAAK,SAASA,EAAE,EAAE,GAAG;AACpC,YAAMjF,IAAS,IAAI4J,EAAM3J,GAAIC,CAAE,EAAE,UAAUiN,CAAW,GAGhDzB,IAAK,SAASzG,EAAE,EAAE,IAAIA,EAAE,KAAKjF,EAAO,IAAI,GACxC2L,IAAK,SAAS1G,EAAE,EAAE,IAAIA,EAAE,KAAKjF,EAAO,IAAI;AAC9C,MAAAmN,EAAY,WAAWzB,GAAIC,CAAE;AAAA,IAC/B;AAGA,WAAAwB,EAAY,WAAWlI,EAAE,IAAIA,EAAE,EAAE,GAC1BkI;AAAA,EACT;AAAA;AAAA,EAGA,UAAU9M,GAAGC,GAAG;AACd,WAAO,KAAK,MAAK,EAAG,WAAWD,GAAGC,CAAC;AAAA,EACrC;AAAA,EAEA,WAAWD,GAAGC,GAAG;AACf,gBAAK,KAAKD,KAAK,GACf,KAAK,KAAKC,KAAK,GACR;AAAA,EACT;AAAA,EAEA,UAAU;AACR,WAAO;AAAA,MACL,GAAG,KAAK;AAAA,MACR,GAAG,KAAK;AAAA,MACR,GAAG,KAAK;AAAA,MACR,GAAG,KAAK;AAAA,MACR,GAAG,KAAK;AAAA,MACR,GAAG,KAAK;AAAA,IACd;AAAA,EACE;AACF;AAEO,SAAS8M,KAAM;AACpB,SAAO,IAAIrD,EAAO,KAAK,KAAK,OAAM,CAAE;AACtC;AAEO,SAASsD,KAAY;AAC1B,MAAI;AAKF,QAAI,OAAO,KAAK,UAAW,cAAc,CAAC,KAAK,UAAU;AACvD,YAAMC,IAAO,KAAK,KAAK,GAAG,CAAC,GACrBhP,IAAIgP,EAAK,KAAK,aAAY;AAChC,aAAAA,EAAK,OAAM,GACJ,IAAIvD,EAAOzL,CAAC;AAAA,IACrB;AACA,WAAO,IAAIyL,EAAO,KAAK,KAAK,aAAY,CAAE;AAAA,EAC5C,QAAY;AACV,mBAAQ;AAAA,MACN,gCAAgC,KAAK,KAAK,QAAQ;AAAA,IACxD,GACW,IAAIA,EAAM;AAAA,EACnB;AACF;AAEA9H,EAAS8H,GAAQ,QAAQ;AC3hBV,SAASwD,KAAS;AAE/B,MAAI,CAACA,GAAO,OAAO;AACjB,UAAMzM,IAAMW,GAAY,EAAG,KAAK,GAAG,CAAC;AACpC,IAAAX,EAAI,KAAK,MAAM,UAAU;AAAA,MACvB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACN,EAAM,KAAK,GAAG,GAEVA,EAAI,KAAK,aAAa,OAAO,GAC7BA,EAAI,KAAK,eAAe,MAAM;AAE9B,UAAM0M,IAAO1M,EAAI,OAAO;AAExB,IAAAyM,GAAO,QAAQ,EAAE,KAAAzM,GAAK,MAAA0M,EAAI;AAAA,EAC5B;AAEA,MAAI,CAACD,GAAO,MAAM,IAAI,KAAK,YAAY;AACrC,UAAMlH,IAAInF,EAAQ,SAAS,QAAQA,EAAQ,SAAS;AACpD,IAAAqM,GAAO,MAAM,IAAI,MAAMlH,CAAC;AAAA,EAC1B;AAEA,SAAOkH,GAAO;AAChB;ACrBO,SAASE,GAAY5N,GAAK;AAC/B,SAAO,CAACA,EAAI,SAAS,CAACA,EAAI,UAAU,CAACA,EAAI,KAAK,CAACA,EAAI;AACrD;AAEO,SAAS6N,GAAY5L,GAAM;AAChC,SACEA,MAASZ,EAAQ,aAEfA,EAAQ,SAAS,gBAAgB,YACjC,SAAUY,GAAM;AAEd,WAAOA,EAAK;AACV,MAAAA,IAAOA,EAAK;AAEd,WAAOA,MAASZ,EAAQ;AAAA,EAC1B,GACA,KAAKA,EAAQ,SAAS,iBAAiBY,CAAI;AAEjD;AAEe,MAAM6L,EAAI;AAAA,EACvB,eAAehL,GAAM;AACnB,SAAK,KAAK,GAAGA,CAAI;AAAA,EACnB;AAAA,EAEA,YAAY;AAEV,gBAAK,KAAKzB,EAAQ,OAAO,aACzB,KAAK,KAAKA,EAAQ,OAAO,aAClB,IAAIyM,EAAI,IAAI;AAAA,EACrB;AAAA,EAEA,KAAK7D,GAAQ;AACX,UAAMD,IAAO,CAAC,GAAG,GAAG,GAAG,CAAC;AACxB,WAAAC,IACE,OAAOA,KAAW,WACdA,EAAO,MAAM3F,EAAS,EAAE,IAAI,UAAU,IACtC,MAAM,QAAQ2F,CAAM,IAClBA,IACA,OAAOA,KAAW,WAChB;AAAA,MACEA,EAAO,QAAQ,OAAOA,EAAO,OAAOA,EAAO;AAAA,MAC3CA,EAAO,OAAO,OAAOA,EAAO,MAAMA,EAAO;AAAA,MACzCA,EAAO;AAAA,MACPA,EAAO;AAAA,IACvB,IACc,UAAU,WAAW,IACnB,GAAG,MAAM,KAAK,SAAS,IACvBD,GAEZ,KAAK,IAAIC,EAAO,CAAC,KAAK,GACtB,KAAK,IAAIA,EAAO,CAAC,KAAK,GACtB,KAAK,QAAQ,KAAK,IAAIA,EAAO,CAAC,KAAK,GACnC,KAAK,SAAS,KAAK,IAAIA,EAAO,CAAC,KAAK,GAGpC,KAAK,KAAK,KAAK,IAAI,KAAK,GACxB,KAAK,KAAK,KAAK,IAAI,KAAK,GACxB,KAAK,KAAK,KAAK,IAAI,KAAK,IAAI,GAC5B,KAAK,KAAK,KAAK,IAAI,KAAK,IAAI,GAErB;AAAA,EACT;AAAA,EAEA,WAAW;AACT,WAAO2D,GAAY,IAAI;AAAA,EACzB;AAAA;AAAA,EAGA,MAAM5N,GAAK;AACT,UAAMQ,IAAI,KAAK,IAAI,KAAK,GAAGR,EAAI,CAAC,GAC1BS,IAAI,KAAK,IAAI,KAAK,GAAGT,EAAI,CAAC,GAC1BF,IAAQ,KAAK,IAAI,KAAK,IAAI,KAAK,OAAOE,EAAI,IAAIA,EAAI,KAAK,IAAIQ,GAC3DT,IAAS,KAAK,IAAI,KAAK,IAAI,KAAK,QAAQC,EAAI,IAAIA,EAAI,MAAM,IAAIS;AAEpE,WAAO,IAAIqN,EAAItN,GAAGC,GAAGX,GAAOC,CAAM;AAAA,EACpC;AAAA,EAEA,UAAU;AACR,WAAO,CAAC,KAAK,GAAG,KAAK,GAAG,KAAK,OAAO,KAAK,MAAM;AAAA,EACjD;AAAA,EAEA,WAAW;AACT,WAAO,KAAK,IAAI,MAAM,KAAK,IAAI,MAAM,KAAK,QAAQ,MAAM,KAAK;AAAA,EAC/D;AAAA,EAEA,UAAUtB,GAAG;AACX,IAAMA,aAAayL,MACjBzL,IAAI,IAAIyL,EAAOzL,CAAC;AAGlB,QAAIsP,IAAO,OACPC,IAAO,QACPC,IAAO,OACPC,IAAO;AASX,WAPY;AAAA,MACV,IAAInE,EAAM,KAAK,GAAG,KAAK,CAAC;AAAA,MACxB,IAAIA,EAAM,KAAK,IAAI,KAAK,CAAC;AAAA,MACzB,IAAIA,EAAM,KAAK,GAAG,KAAK,EAAE;AAAA,MACzB,IAAIA,EAAM,KAAK,IAAI,KAAK,EAAE;AAAA,IAChC,EAEQ,QAAQ,SAAUnD,GAAG;AACvB,MAAAA,IAAIA,EAAE,UAAUnI,CAAC,GACjBsP,IAAO,KAAK,IAAIA,GAAMnH,EAAE,CAAC,GACzBoH,IAAO,KAAK,IAAIA,GAAMpH,EAAE,CAAC,GACzBqH,IAAO,KAAK,IAAIA,GAAMrH,EAAE,CAAC,GACzBsH,IAAO,KAAK,IAAIA,GAAMtH,EAAE,CAAC;AAAA,IAC3B,CAAC,GAEM,IAAIkH,EAAIC,GAAME,GAAMD,IAAOD,GAAMG,IAAOD,CAAI;AAAA,EACrD;AACF;AAEA,SAASE,GAAOhJ,GAAIiJ,GAAWC,GAAO;AACpC,MAAIrO;AAEJ,MAAI;AAMF,QAJAA,IAAMoO,EAAUjJ,EAAG,IAAI,GAInByI,GAAY5N,CAAG,KAAK,CAAC6N,GAAY1I,EAAG,IAAI;AAC1C,YAAM,IAAI,MAAM,wBAAwB;AAAA,EAE5C,QAAY;AAEV,IAAAnF,IAAMqO,EAAMlJ,CAAE;AAAA,EAChB;AAEA,SAAOnF;AACT;AAEO,SAASsO,KAAO;AAsBrB,QAAMtO,IAAMmO,GAAO,MApBH,CAAClM,MAASA,EAAK,QAAO,GAIxB,CAACkD,MAAO;AACpB,QAAI;AACF,YAAMoJ,IAAQpJ,EAAG,MAAK,EAAG,MAAMuI,GAAM,EAAG,GAAG,EAAE,KAAI,GAC3C1N,IAAMuO,EAAM,KAAK,QAAO;AAC9B,aAAAA,EAAM,OAAM,GACLvO;AAAA,IACT,SAASwL,GAAG;AAEV,YAAM,IAAI;AAAA,QACR,4BACErG,EAAG,KAAK,QAClB,sBAA8BqG,EAAE,UAAU;AAAA,MAC1C;AAAA,IACI;AAAA,EACF,CAEuC;AAGvC,SAFa,IAAIsC,EAAI9N,CAAG;AAG1B;AAEO,SAASwO,GAAKrJ,GAAI;AAUvB,QAAMnF,IAAMmO,GAAO,MATH,CAAClM,MAASA,EAAK,sBAAqB,GACtC,CAACkD,MAAO;AAGpB,UAAM,IAAI;AAAA,MACR,4BAA4BA,EAAG,KAAK,QAAQ;AAAA,IAClD;AAAA,EACE,CAEuC,GACjCqJ,IAAO,IAAIV,EAAI9N,CAAG;AAGxB,SAAImF,IACKqJ,EAAK,UAAUrJ,EAAG,UAAS,EAAG,SAAQ,CAAE,IAK1CqJ,EAAK,UAAS;AACvB;AAGO,SAASC,GAAOjO,GAAGC,GAAG;AAC3B,QAAMT,IAAM,KAAK,KAAI;AAErB,SACEQ,IAAIR,EAAI,KAAKS,IAAIT,EAAI,KAAKQ,IAAIR,EAAI,IAAIA,EAAI,SAASS,IAAIT,EAAI,IAAIA,EAAI;AAEvE;AAEAzB,EAAgB;AAAA,EACd,SAAS;AAAA,IACP,QAAQiC,GAAGC,GAAGX,GAAOC,GAAQ;AAE3B,aAAIS,KAAK,OAAa,IAAIsN,EAAI,KAAK,KAAK,SAAS,CAAC,IAG3C,KAAK,KAAK,WAAW,IAAIA,EAAItN,GAAGC,GAAGX,GAAOC,CAAM,CAAC;AAAA,IAC1D;AAAA,IAEA,KAAK2O,GAAOvE,GAAO;AAQjB,UAAI,EAAE,OAAArK,GAAO,QAAAC,EAAM,IAAK,KAAK,KAAK,CAAC,SAAS,QAAQ,CAAC;AAcrD,WATG,CAACD,KAAS,CAACC,KACZ,OAAOD,KAAU,YACjB,OAAOC,KAAW,cAElBD,IAAQ,KAAK,KAAK,aAClBC,IAAS,KAAK,KAAK,eAIjB,CAACD,KAAS,CAACC;AACb,cAAM,IAAI;AAAA,UACR;AAAA,QACV;AAGM,YAAM2F,IAAI,KAAK,QAAO,GAEhBiJ,IAAQ7O,IAAQ4F,EAAE,OAClBkJ,IAAQ7O,IAAS2F,EAAE,QACnBmJ,IAAO,KAAK,IAAIF,GAAOC,CAAK;AAElC,UAAIF,KAAS;AACX,eAAOG;AAGT,UAAIC,IAAaD,IAAOH;AAIxB,MAAII,MAAe,UAAUA,IAAa,OAAO,mBAAmB,MAEpE3E,IACEA,KAAS,IAAIJ,EAAMjK,IAAQ,IAAI6O,IAAQjJ,EAAE,GAAG3F,IAAS,IAAI6O,IAAQlJ,EAAE,CAAC;AAEtE,YAAM1F,IAAM,IAAI8N,EAAIpI,CAAC,EAAE;AAAA,QACrB,IAAIwE,EAAO,EAAE,OAAO4E,GAAY,QAAQ3E,EAAK,CAAE;AAAA,MACvD;AAEM,aAAO,KAAK,QAAQnK,CAAG;AAAA,IACzB;AAAA,EACJ;AACA,CAAC;AAEDoC,EAAS0L,GAAK,KAAK;AC1QnB,MAAMiB,WAAa,MAAM;AAAA,EACvB,YAAYC,IAAM,OAAOlM,GAAM;AAE7B,QADA,MAAMkM,GAAK,GAAGlM,CAAI,GACd,OAAOkM,KAAQ,SAAU,QAAO;AACpC,SAAK,SAAS,GACd,KAAK,KAAK,GAAGA,CAAG;AAAA,EAClB;AACF;AAWAtM,EAAO,CAACqM,EAAI,GAAG;AAAA,EACb,KAAKE,MAAmBnM,GAAM;AAC5B,WAAI,OAAOmM,KAAmB,aACrB,KAAK,IAAI,CAAC9J,GAAIjG,GAAG8P,MACfC,EAAe,KAAK9J,GAAIA,GAAIjG,GAAG8P,CAAG,CAC1C,IAEM,KAAK,IAAI,CAAC7J,MACRA,EAAG8J,CAAc,EAAE,GAAGnM,CAAI,CAClC;AAAA,EAEL;AAAA,EAEA,UAAU;AACR,WAAO,MAAM,UAAU,OAAO,MAAM,CAAA,GAAI,IAAI;AAAA,EAC9C;AACF,CAAC;AAED,MAAMoM,KAAW,CAAC,WAAW,eAAe,MAAM;AAElDH,GAAK,SAAS,SAAU1Q,GAAS;AAC/B,EAAAA,IAAUA,EAAQ,OAAO,CAAC8Q,GAAK3Q,OAEzB0Q,GAAS,SAAS1Q,CAAI,KAGtBA,EAAK,CAAC,MAAM,QAGZA,KAAQ,MAAM,cAChB2Q,EAAI,MAAM3Q,CAAI,IAAI,MAAM,UAAUA,CAAI,IAIxC2Q,EAAI3Q,CAAI,IAAI,YAAa4Q,GAAO;AAC9B,WAAO,KAAK,KAAK5Q,GAAM,GAAG4Q,CAAK;AAAA,EACjC,IACOD,IACN,CAAA,CAAE,GAELzM,EAAO,CAACqM,EAAI,GAAG1Q,CAAO;AACxB;ACzDe,SAASgR,GAASC,GAAOC,GAAQ;AAC9C,SAAO,IAAIR;AAAA,IACThQ,IAAKwQ,KAAUlO,EAAQ,UAAU,iBAAiBiO,CAAK,GAAG,SAAUrN,GAAM;AACxE,aAAOC,GAAMD,CAAI;AAAA,IACnB,CAAC;AAAA,EACL;AACA;AAGO,SAASuN,GAAKF,GAAO;AAC1B,SAAOD,GAASC,GAAO,KAAK,IAAI;AAClC;AAEO,SAASG,GAAQH,GAAO;AAC7B,SAAOpN,GAAM,KAAK,KAAK,cAAcoN,CAAK,CAAC;AAC7C;AChBA,IAAII,KAAa;AACV,MAAMC,KAAe,CAAA;AAErB,SAASC,GAAUC,GAAU;AAClC,MAAIC,IAAID,EAAS,eAAc;AAG/B,SAAIC,MAAMzO,EAAQ,WAAQyO,IAAIH,KACzBG,EAAE,WAAQA,EAAE,SAAS,CAAA,IACnBA,EAAE;AACX;AAEO,SAASC,GAAeF,GAAU;AACvC,SAAOA,EAAS,eAAc;AAChC;AAEO,SAASG,GAAYH,GAAU;AACpC,MAAIC,IAAID,EAAS,eAAc;AAC/B,EAAIC,MAAMzO,EAAQ,WAAQyO,IAAIH,KAC1BG,EAAE,WAAQA,EAAE,SAAS,CAAA;AAC3B;AAGO,SAASG,GAAGhO,GAAMiO,GAAQC,GAAUC,GAASC,GAAS;AAC3D,QAAM/I,IAAI6I,EAAS,KAAKC,KAAWnO,CAAI,GACjC4N,IAAWjO,GAAaK,CAAI,GAC5BqO,IAAMV,GAAUC,CAAQ,GACxBC,IAAIC,GAAeF,CAAQ;AAGjC,EAAAK,IAAS,MAAM,QAAQA,CAAM,IAAIA,IAASA,EAAO,MAAM5L,EAAS,GAG3D6L,EAAS,qBACZA,EAAS,mBAAmB,EAAET,KAGhCQ,EAAO,QAAQ,SAAUK,GAAO;AAC9B,UAAMC,IAAKD,EAAM,MAAM,GAAG,EAAE,CAAC,GACvB5O,IAAK4O,EAAM,MAAM,GAAG,EAAE,CAAC,KAAK;AAGlC,IAAAD,EAAIE,CAAE,IAAIF,EAAIE,CAAE,KAAK,CAAA,GACrBF,EAAIE,CAAE,EAAE7O,CAAE,IAAI2O,EAAIE,CAAE,EAAE7O,CAAE,KAAK,CAAA,GAG7B2O,EAAIE,CAAE,EAAE7O,CAAE,EAAEwO,EAAS,gBAAgB,IAAI7I,GAGzCwI,EAAE,iBAAiBU,GAAIlJ,GAAG+I,KAAW,EAAK;AAAA,EAC5C,CAAC;AACH;AAGO,SAASI,GAAIxO,GAAMiO,GAAQC,GAAUE,GAAS;AACnD,QAAMR,IAAWjO,GAAaK,CAAI,GAC5BqO,IAAMV,GAAUC,CAAQ,GACxBC,IAAIC,GAAeF,CAAQ;AAGjC,EAAI,OAAOM,KAAa,eACtBA,IAAWA,EAAS,kBAChB,CAACA,OAIPD,IAAS,MAAM,QAAQA,CAAM,IAAIA,KAAUA,KAAU,IAAI,MAAM5L,EAAS,GAExE4L,EAAO,QAAQ,SAAUK,GAAO;AAC9B,UAAMC,IAAKD,KAASA,EAAM,MAAM,GAAG,EAAE,CAAC,GAChC5O,IAAK4O,KAASA,EAAM,MAAM,GAAG,EAAE,CAAC;AACtC,QAAIG,GAAWpJ;AAEf,QAAI6I;AAEF,MAAIG,EAAIE,CAAE,KAAKF,EAAIE,CAAE,EAAE7O,KAAM,GAAG,MAE9BmO,EAAE;AAAA,QACAU;AAAA,QACAF,EAAIE,CAAE,EAAE7O,KAAM,GAAG,EAAEwO,CAAQ;AAAA,QAC3BE,KAAW;AAAA,MACrB,GAEQ,OAAOC,EAAIE,CAAE,EAAE7O,KAAM,GAAG,EAAEwO,CAAQ;AAAA,aAE3BK,KAAM7O;AAEf,UAAI2O,EAAIE,CAAE,KAAKF,EAAIE,CAAE,EAAE7O,CAAE,GAAG;AAC1B,aAAK2F,KAAKgJ,EAAIE,CAAE,EAAE7O,CAAE;AAClB,UAAA8O,GAAIX,GAAG,CAACU,GAAI7O,CAAE,EAAE,KAAK,GAAG,GAAG2F,CAAC;AAG9B,eAAOgJ,EAAIE,CAAE,EAAE7O,CAAE;AAAA,MACnB;AAAA,eACSA;AAET,WAAK4O,KAASD;AACZ,aAAKI,KAAaJ,EAAIC,CAAK;AACzB,UAAI5O,MAAO+O,KACTD,GAAIX,GAAG,CAACS,GAAO5O,CAAE,EAAE,KAAK,GAAG,CAAC;AAAA,aAIzB6O;AAET,UAAIF,EAAIE,CAAE,GAAG;AACX,aAAKE,KAAaJ,EAAIE,CAAE;AACtB,UAAAC,GAAIX,GAAG,CAACU,GAAIE,CAAS,EAAE,KAAK,GAAG,CAAC;AAGlC,eAAOJ,EAAIE,CAAE;AAAA,MACf;AAAA,WACK;AAEL,WAAKD,KAASD;AACZ,QAAAG,GAAIX,GAAGS,CAAK;AAGd,MAAAP,GAAYH,CAAQ;AAAA,IACtB;AAAA,EACF,CAAC;AACH;AAEO,SAASc,GAAS1O,GAAMsO,GAAO1P,GAAMwP,GAAS;AACnD,QAAMP,IAAIC,GAAe9N,CAAI;AAG7B,SAAIsO,aAAiBlP,EAAQ,OAAO,UAGlCkP,IAAQ,IAAIlP,EAAQ,OAAO,YAAYkP,GAAO;AAAA,IAC5C,QAAQ1P;AAAA,IACR,YAAY;AAAA,IACZ,GAAGwP;AAAA,EACT,CAAK,IACDP,EAAE,cAAcS,CAAK,GAEhBA;AACT;AC1Ie,MAAMK,WAAoBrP,GAAK;AAAA,EAC5C,mBAAmB;AAAA,EAAC;AAAA,EAEpB,SAASgP,GAAO1P,GAAMwP,GAAS;AAC7B,WAAOM,GAAS,MAAMJ,GAAO1P,GAAMwP,CAAO;AAAA,EAC5C;AAAA,EAEA,cAAcE,GAAO;AACnB,UAAMD,IAAM,KAAK,iBAAiB;AAClC,QAAI,CAACA,EAAK,QAAO;AAEjB,UAAMJ,IAASI,EAAIC,EAAM,IAAI;AAE7B,eAAWrR,KAAKgR;AACd,iBAAWW,KAAKX,EAAOhR,CAAC;AACtB,QAAAgR,EAAOhR,CAAC,EAAE2R,CAAC,EAAEN,CAAK;AAItB,WAAO,CAACA,EAAM;AAAA,EAChB;AAAA;AAAA,EAGA,KAAKA,GAAO1P,GAAMwP,GAAS;AACzB,gBAAK,SAASE,GAAO1P,GAAMwP,CAAO,GAC3B;AAAA,EACT;AAAA,EAEA,iBAAiB;AACf,WAAO;AAAA,EACT;AAAA,EAEA,iBAAiB;AACf,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,IAAIE,GAAOJ,GAAUE,GAAS;AAC5B,WAAAI,GAAI,MAAMF,GAAOJ,GAAUE,CAAO,GAC3B;AAAA,EACT;AAAA;AAAA,EAGA,GAAGE,GAAOJ,GAAUC,GAASC,GAAS;AACpC,WAAAJ,GAAG,MAAMM,GAAOJ,GAAUC,GAASC,CAAO,GACnC;AAAA,EACT;AAAA,EAEA,sBAAsB;AAAA,EAAC;AACzB;AAEAjO,EAASwO,IAAa,aAAa;ACvD5B,SAASE,KAAO;AAAC;AAGjB,MAAMC,KAAW;AAAA,EACtB,UAAU;AAAA,EACV,MAAM;AAAA,EACN,OAAO;AACT,GAGa3B,KAAQ;AAAA;AAAA,EAEnB,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AAAA;AAAA,EAGT,GAAG;AAAA,EACH,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,IAAI;AAAA;AAAA,EAGJ,OAAO;AAAA,EACP,QAAQ;AAAA;AAAA,EAGR,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,IAAI;AAAA;AAAA,EAGJ,QAAQ;AAAA,EACR,gBAAgB;AAAA,EAChB,cAAc;AAAA;AAAA,EAGd,eAAe;AACjB;ACzCe,MAAM4B,WAAiB,MAAM;AAAA,EAC1C,eAAelO,GAAM;AACnB,UAAM,GAAGA,CAAI,GACb,KAAK,KAAK,GAAGA,CAAI;AAAA,EACnB;AAAA,EAEA,QAAQ;AACN,WAAO,IAAI,KAAK,YAAY,IAAI;AAAA,EAClC;AAAA,EAEA,KAAKkM,GAAK;AAER,WAAI,OAAOA,KAAQ,WAAiB,QACpC,KAAK,SAAS,GACd,KAAK,KAAK,GAAG,KAAK,MAAMA,CAAG,CAAC,GACrB;AAAA,EACT;AAAA;AAAA,EAGA,MAAMhQ,IAAQ,IAAI;AAEhB,WAAIA,aAAiB,QAAcA,IAE5BA,EAAM,KAAI,EAAG,MAAMsF,EAAS,EAAE,IAAI,UAAU;AAAA,EACrD;AAAA,EAEA,UAAU;AACR,WAAO,MAAM,UAAU,OAAO,MAAM,CAAA,GAAI,IAAI;AAAA,EAC9C;AAAA,EAEA,QAAQ;AACN,WAAO,IAAI,IAAI,IAAI;AAAA,EACrB;AAAA,EAEA,WAAW;AACT,WAAO,KAAK,KAAK,GAAG;AAAA,EACtB;AAAA;AAAA,EAGA,UAAU;AACR,UAAMY,IAAM,CAAA;AACZ,WAAAA,EAAI,KAAK,GAAG,IAAI,GACTA;AAAA,EACT;AACF;AC3Ce,MAAM+L,EAAU;AAAA;AAAA,EAE7B,eAAenO,GAAM;AACnB,SAAK,KAAK,GAAGA,CAAI;AAAA,EACnB;AAAA,EAEA,QAAQoO,GAAM;AACZ,WAAO,IAAID,EAAU,KAAK,OAAOC,CAAI;AAAA,EACvC;AAAA;AAAA,EAGA,OAAOC,GAAQ;AACb,WAAAA,IAAS,IAAIF,EAAUE,CAAM,GACtB,IAAIF,EAAU,OAAOE,GAAQ,KAAK,QAAQA,EAAO,IAAI;AAAA,EAC9D;AAAA,EAEA,KAAKC,GAAOF,GAAM;AAChB,WAAAA,IAAO,MAAM,QAAQE,CAAK,IAAIA,EAAM,CAAC,IAAIF,GACzCE,IAAQ,MAAM,QAAQA,CAAK,IAAIA,EAAM,CAAC,IAAIA,GAG1C,KAAK,QAAQ,GACb,KAAK,OAAOF,KAAQ,IAGhB,OAAOE,KAAU,WAEnB,KAAK,QAAQ,MAAMA,CAAK,IACpB,IACC,SAASA,CAAK,IAIbA,IAHAA,IAAQ,IACN,SACA,QAEC,OAAOA,KAAU,YAC1BF,IAAOE,EAAM,MAAMzN,EAAa,GAE5BuN,MAEF,KAAK,QAAQ,WAAWA,EAAK,CAAC,CAAC,GAG3BA,EAAK,CAAC,MAAM,MACd,KAAK,SAAS,MACLA,EAAK,CAAC,MAAM,QACrB,KAAK,SAAS,MAIhB,KAAK,OAAOA,EAAK,CAAC,MAGhBE,aAAiBH,MACnB,KAAK,QAAQG,EAAM,QAAO,GAC1B,KAAK,OAAOA,EAAM,OAIf;AAAA,EACT;AAAA;AAAA,EAGA,MAAMD,GAAQ;AACZ,WAAAA,IAAS,IAAIF,EAAUE,CAAM,GACtB,IAAIF,EAAU,OAAOE,GAAQ,KAAK,QAAQA,EAAO,IAAI;AAAA,EAC9D;AAAA;AAAA,EAGA,KAAKA,GAAQ;AACX,WAAAA,IAAS,IAAIF,EAAUE,CAAM,GACtB,IAAIF,EAAU,OAAOE,GAAQ,KAAK,QAAQA,EAAO,IAAI;AAAA,EAC9D;AAAA;AAAA,EAGA,MAAMA,GAAQ;AACZ,WAAAA,IAAS,IAAIF,EAAUE,CAAM,GACtB,IAAIF,EAAU,OAAOE,GAAQ,KAAK,QAAQA,EAAO,IAAI;AAAA,EAC9D;AAAA,EAEA,UAAU;AACR,WAAO,CAAC,KAAK,OAAO,KAAK,IAAI;AAAA,EAC/B;AAAA,EAEA,SAAS;AACP,WAAO,KAAK,SAAQ;AAAA,EACtB;AAAA,EAEA,WAAW;AACT,YACG,KAAK,SAAS,MACX,CAAC,EAAE,KAAK,QAAQ,OAAO,MACvB,KAAK,SAAS,MACZ,KAAK,QAAQ,MACb,KAAK,SAAS,KAAK;AAAA,EAE7B;AAAA,EAEA,UAAU;AACR,WAAO,KAAK;AAAA,EACd;AACF;ACjGA,MAAME,KAAkB,oBAAI,IAAI;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC,GAEKC,KAAQ,CAAA;AACP,SAASC,GAAiB1O,GAAI;AACnC,EAAAyO,GAAM,KAAKzO,CAAE;AACf;AAGe,SAAS4B,GAAKA,GAAMQ,GAAKtD,GAAI;AAE1C,MAAI8C,KAAQ,MAAM;AAEhB,IAAAA,IAAO,CAAA,GACPQ,IAAM,KAAK,KAAK;AAEhB,eAAWhD,KAAQgD;AACjB,MAAAR,EAAKxC,EAAK,QAAQ,IAAImC,GAAS,KAAKnC,EAAK,SAAS,IAC9C,WAAWA,EAAK,SAAS,IACzBA,EAAK;AAGX,WAAOwC;AAAA,EACT,OAAO;AAAA,QAAIA,aAAgB;AAEzB,aAAOA,EAAK,OAAO,CAAC+M,GAAMC,OACxBD,EAAKC,CAAI,IAAI,KAAK,KAAKA,CAAI,GACpBD,IACN,CAAA,CAAE;AACA,QAAI,OAAO/M,KAAS,YAAYA,EAAK,gBAAgB;AAE1D,WAAKQ,KAAOR,EAAM,MAAK,KAAKQ,GAAKR,EAAKQ,CAAG,CAAC;AAAA,aACjCA,MAAQ;AAEjB,WAAK,KAAK,gBAAgBR,CAAI;AAAA,SACzB;AAAA,UAAIQ,KAAO;AAEhB,eAAAA,IAAM,KAAK,KAAK,aAAaR,CAAI,GAC1BQ,KAAO,OACVnE,GAAS2D,CAAI,IACbL,GAAS,KAAKa,CAAG,IACf,WAAWA,CAAG,IACdA;AAGN,MAAAA,IAAMqM,GAAM,OAAO,CAACI,GAAMC,MACjBA,EAAKlN,GAAMiN,GAAM,IAAI,GAC3BzM,CAAG,GAGF,OAAOA,KAAQ,WACjBA,IAAM,IAAIgM,EAAUhM,CAAG,IACdoM,GAAgB,IAAI5M,CAAI,KAAKqC,EAAM,QAAQ7B,CAAG,IAEvDA,IAAM,IAAI6B,EAAM7B,CAAG,IACVA,EAAI,gBAAgB,UAE7BA,IAAM,IAAI+L,GAAS/L,CAAG,IAIpBR,MAAS,YAEP,KAAK,WACP,KAAK,QAAQQ,CAAG,IAIlB,OAAOtD,KAAO,WACV,KAAK,KAAK,eAAeA,GAAI8C,GAAMQ,EAAI,SAAQ,CAAE,IACjD,KAAK,KAAK,aAAaR,GAAMQ,EAAI,SAAQ,CAAE,GAI7C,KAAK,YAAYR,MAAS,eAAeA,MAAS,QACpD,KAAK,QAAO;AAAA;AAAA;AAIhB,SAAO;AACT;AC5Ee,MAAMmN,WAAYhB,GAAY;AAAA,EAC3C,YAAY3O,GAAMmN,GAAO;AACvB,UAAK,GACL,KAAK,OAAOnN,GACZ,KAAK,OAAOA,EAAK,UAEbmN,KAASnN,MAASmN,KACpB,KAAK,KAAKA,CAAK;AAAA,EAEnB;AAAA;AAAA,EAGA,IAAIvP,GAASX,GAAG;AACd,WAAAW,IAAU+B,GAAa/B,CAAO,GAI5BA,EAAQ,mBACR,KAAK,gBAAgBwB,EAAQ,OAAO,cAEpCxB,EAAQ,gBAAe,GAGrBX,KAAK,OACP,KAAK,KAAK,YAAYW,EAAQ,IAAI,IACzBA,EAAQ,SAAS,KAAK,KAAK,WAAWX,CAAC,KAChD,KAAK,KAAK,aAAaW,EAAQ,MAAM,KAAK,KAAK,WAAWX,CAAC,CAAC,GAGvD;AAAA,EACT;AAAA;AAAA,EAGA,MAAMqQ,GAAQrQ,GAAG;AACf,WAAO0C,GAAa2N,CAAM,EAAE,IAAI,MAAMrQ,CAAC;AAAA,EACzC;AAAA;AAAA,EAGA,WAAW;AACT,WAAO,IAAI6P;AAAA,MACThQ,GAAI,KAAK,KAAK,UAAU,SAAUkD,GAAM;AACtC,eAAOC,GAAMD,CAAI;AAAA,MACnB,CAAC;AAAA,IACP;AAAA,EACE;AAAA;AAAA,EAGA,QAAQ;AAEN,WAAO,KAAK,KAAK;AACf,WAAK,KAAK,YAAY,KAAK,KAAK,SAAS;AAG3C,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM4P,IAAO,IAAMC,IAAe,IAAM;AAEtC,SAAK,eAAc;AAGnB,QAAIC,IAAY,KAAK,KAAK,UAAUF,CAAI;AACxC,WAAIC,MAEFC,IAAYtP,GAAYsP,CAAS,IAE5B,IAAI,KAAK,YAAYA,CAAS;AAAA,EACvC;AAAA;AAAA,EAGA,KAAK9S,GAAO4S,GAAM;AAChB,UAAMG,IAAW,KAAK,SAAQ;AAC9B,QAAI9S,GAAGC;AAEP,SAAKD,IAAI,GAAGC,IAAK6S,EAAS,QAAQ9S,IAAIC,GAAID;AACxC,MAAAD,EAAM,MAAM+S,EAAS9S,CAAC,GAAG,CAACA,GAAG8S,CAAQ,CAAC,GAElCH,KACFG,EAAS9S,CAAC,EAAE,KAAKD,GAAO4S,CAAI;AAIhC,WAAO;AAAA,EACT;AAAA,EAEA,QAAQI,GAAU7C,GAAO;AACvB,WAAO,KAAK,IAAI,IAAIwC,GAAIlQ,GAAOuQ,CAAQ,GAAG7C,CAAK,CAAC;AAAA,EAClD;AAAA;AAAA,EAGA,QAAQ;AACN,WAAOlN,GAAM,KAAK,KAAK,UAAU;AAAA,EACnC;AAAA;AAAA,EAGA,IAAIhD,GAAG;AACL,WAAOgD,GAAM,KAAK,KAAK,WAAWhD,CAAC,CAAC;AAAA,EACtC;AAAA,EAEA,iBAAiB;AACf,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,iBAAiB;AACf,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,IAAIW,GAAS;AACX,WAAO,KAAK,MAAMA,CAAO,KAAK;AAAA,EAChC;AAAA,EAEA,KAAKqS,GAAUC,GAAW;AACxB,WAAO,KAAK,IAAID,GAAUC,GAAWjR,EAAI;AAAA,EAC3C;AAAA;AAAA,EAGA,GAAGkR,GAAI;AAEL,WAAI,OAAOA,IAAO,OAAe,CAAC,KAAK,KAAK,OAC1C,KAAK,KAAK,KAAK5P,GAAI,KAAK,IAAI,IAIvB,KAAK,KAAK,MAAM4P,CAAE;AAAA,EAC3B;AAAA;AAAA,EAGA,MAAMvS,GAAS;AACb,WAAO,CAAA,EAAG,MAAM,KAAK,KAAK,KAAK,UAAU,EAAE,QAAQA,EAAQ,IAAI;AAAA,EACjE;AAAA;AAAA,EAGA,OAAO;AACL,WAAOqC,GAAM,KAAK,KAAK,SAAS;AAAA,EAClC;AAAA;AAAA,EAGA,QAAQmQ,GAAU;AAChB,UAAMlN,IAAK,KAAK,MACVmN,IACJnN,EAAG,WACHA,EAAG,mBACHA,EAAG,qBACHA,EAAG,sBACHA,EAAG,yBACHA,EAAG,oBACH;AACF,WAAOmN,KAAWA,EAAQ,KAAKnN,GAAIkN,CAAQ;AAAA,EAC7C;AAAA;AAAA,EAGA,OAAOE,GAAM;AACX,QAAIhD,IAAS;AAGb,QAAI,CAACA,EAAO,KAAK,WAAY,QAAO;AAKpC,QAFAA,IAASrN,GAAMqN,EAAO,KAAK,UAAU,GAEjC,CAACgD,EAAM,QAAOhD;AAGlB;AACE,UACE,OAAOgD,KAAS,WAAWhD,EAAO,QAAQgD,CAAI,IAAIhD,aAAkBgD;AAEpE,eAAOhD;AAAA,WACDA,IAASrN,GAAMqN,EAAO,KAAK,UAAU;AAE/C,WAAOA;AAAA,EACT;AAAA;AAAA,EAGA,IAAI1P,GAASX,GAAG;AACd,WAAAW,IAAU+B,GAAa/B,CAAO,GAC9B,KAAK,IAAIA,GAASX,CAAC,GACZW;AAAA,EACT;AAAA;AAAA,EAGA,MAAM0P,GAAQrQ,GAAG;AACf,WAAO0C,GAAa2N,CAAM,EAAE,IAAI,MAAMrQ,CAAC;AAAA,EACzC;AAAA;AAAA,EAGA,SAAS;AACP,WAAI,KAAK,YACP,KAAK,SAAS,cAAc,IAAI,GAG3B;AAAA,EACT;AAAA;AAAA,EAGA,cAAcW,GAAS;AACrB,gBAAK,KAAK,YAAYA,EAAQ,IAAI,GAE3B;AAAA,EACT;AAAA;AAAA,EAGA,QAAQA,GAAS;AACf,WAAAA,IAAU+B,GAAa/B,CAAO,GAE1B,KAAK,KAAK,cACZ,KAAK,KAAK,WAAW,aAAaA,EAAQ,MAAM,KAAK,IAAI,GAGpDA;AAAA,EACT;AAAA,EAEA,MAAM2S,IAAY,GAAGzT,IAAM,MAAM;AAC/B,UAAM0T,IAAS,MAAMD,GACfpD,IAAQ,KAAK,KAAKrQ,CAAG;AAE3B,eAAWG,KAAKkQ;AACd,MAAI,OAAOA,EAAMlQ,CAAC,KAAM,aACtBkQ,EAAMlQ,CAAC,IAAI,KAAK,MAAMkQ,EAAMlQ,CAAC,IAAIuT,CAAM,IAAIA;AAI/C,gBAAK,KAAKrD,CAAK,GACR;AAAA,EACT;AAAA;AAAA,EAGA,IAAIsD,GAASC,GAAU;AACrB,WAAO,KAAK,IAAID,GAASC,GAAU1R,EAAG;AAAA,EACxC;AAAA;AAAA,EAGA,WAAW;AACT,WAAO,KAAK,GAAE;AAAA,EAChB;AAAA,EAEA,MAAM2R,GAAM;AAEV,gBAAK,KAAK,cAAcA,GACjB;AAAA,EACT;AAAA,EAEA,KAAK3Q,GAAM;AACT,UAAMsN,IAAS,KAAK,OAAM;AAE1B,QAAI,CAACA;AACH,aAAO,KAAK,MAAMtN,CAAI;AAGxB,UAAMe,IAAWuM,EAAO,MAAM,IAAI;AAClC,WAAOA,EAAO,IAAItN,GAAMe,CAAQ,EAAE,IAAI,IAAI;AAAA,EAC5C;AAAA;AAAA,EAGA,iBAAiB;AAEf,gBAAK,KAAK,WAAY;AACpB,WAAK,eAAc;AAAA,IACrB,CAAC,GAEM;AAAA,EACT;AAAA;AAAA,EAGA,IAAI6P,GAASC,GAAUnR,GAAI;AAQzB,QAPI,OAAOkR,KAAY,cACrBlR,IAAKmR,GACLA,IAAWD,GACXA,IAAU,OAIRA,KAAW,QAAQ,OAAOA,KAAY,YAAY;AAEpD,MAAAC,IAAWA,KAAmB,IAG9B,KAAK,eAAc;AACnB,UAAIzF,IAAU;AAGd,UAAIwF,KAAW,MAAM;AAInB,YAHAxF,IAAUnL,GAAMmL,EAAQ,KAAK,UAAU,EAAI,CAAC,GAGxCyF,GAAU;AACZ,gBAAM1T,IAASyT,EAAQxF,CAAO;AAI9B,cAHAA,IAAUjO,KAAUiO,GAGhBjO,MAAW,GAAO,QAAO;AAAA,QAC/B;AAGA,QAAAiO,EAAQ,KAAK,WAAY;AACvB,gBAAMjO,IAASyT,EAAQ,IAAI,GACrBE,IAAQ3T,KAAU;AAGxB,UAAIA,MAAW,KACb,KAAK,OAAM,IAGFA,KAAU,SAAS2T,KAC5B,KAAK,QAAQA,CAAK;AAAA,QAEtB,GAAG,EAAI;AAAA,MACT;AAGA,aAAOD,IAAWzF,EAAQ,KAAK,YAAYA,EAAQ,KAAK;AAAA,IAC1D;AAKA,IAAAyF,IAAWA,KAAmB;AAG9B,UAAME,IAAOtR,GAAO,WAAWC,CAAE,GAC3BsR,IAAW5R,EAAQ,SAAS,uBAAsB;AAGxD,IAAA2R,EAAK,YAAYH;AAGjB,aAASK,IAAMF,EAAK,SAAS,QAAQE;AACnC,MAAAD,EAAS,YAAYD,EAAK,iBAAiB;AAG7C,UAAMzD,IAAS,KAAK,OAAM;AAG1B,WAAOuD,IAAW,KAAK,QAAQG,CAAQ,KAAK1D,IAAS,KAAK,IAAI0D,CAAQ;AAAA,EACxE;AACF;AAEAvQ,EAAOkP,IAAK,EAAE,MAAAnN,IAAM,MAAA+K,IAAM,SAAAC,GAAO,CAAE;AACnCrN,EAASwP,IAAK,KAAK;ACpVJ,MAAMlF,WAAgBkF,GAAI;AAAA,EACvC,YAAY3P,GAAMmN,GAAO;AACvB,UAAMnN,GAAMmN,CAAK,GAGjB,KAAK,MAAM,CAAA,GAGX,KAAK,KAAK,WAAW,OAEjBnN,EAAK,aAAa,YAAY,KAAKA,EAAK,aAAa,YAAY,MAEnE,KAAK;AAAA,MACH,KAAK,MAAMA,EAAK,aAAa,YAAY,CAAC,KACxC,KAAK,MAAMA,EAAK,aAAa,YAAY,CAAC,KAC1C,CAAA;AAAA,IACV;AAAA,EAEE;AAAA;AAAA,EAGA,OAAOzB,GAAGC,GAAG;AACX,WAAO,KAAK,GAAGD,CAAC,EAAE,GAAGC,CAAC;AAAA,EACxB;AAAA;AAAA,EAGA,GAAGD,GAAG;AACJ,WAAOA,KAAK,OACR,KAAK,EAAC,IAAK,KAAK,MAAK,IAAK,IAC1B,KAAK,EAAEA,IAAI,KAAK,MAAK,IAAK,CAAC;AAAA,EACjC;AAAA;AAAA,EAGA,GAAGC,GAAG;AACJ,WAAOA,KAAK,OACR,KAAK,EAAC,IAAK,KAAK,OAAM,IAAK,IAC3B,KAAK,EAAEA,IAAI,KAAK,OAAM,IAAK,CAAC;AAAA,EAClC;AAAA;AAAA,EAGA,OAAO;AACL,UAAMgB,IAAO,KAAK,KAAI;AACtB,WAAOA,KAAQA,EAAK,KAAI;AAAA,EAC1B;AAAA;AAAA,EAGA,MAAMjB,GAAGC,GAAG;AACV,WAAO,KAAK,GAAGD,CAAC,EAAE,GAAGC,CAAC;AAAA,EACxB;AAAA;AAAA,EAGA,GAAGD,IAAI,GAAG;AACR,WAAO,KAAK,EAAE,IAAIyQ,EAAUzQ,CAAC,EAAE,KAAK,KAAK,GAAG,CAAC;AAAA,EAC/C;AAAA;AAAA,EAGA,GAAGC,IAAI,GAAG;AACR,WAAO,KAAK,EAAE,IAAIwQ,EAAUxQ,CAAC,EAAE,KAAK,KAAK,GAAG,CAAC;AAAA,EAC/C;AAAA,EAEA,iBAAiB;AACf,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,OAAOV,GAAQ;AACb,WAAO,KAAK,KAAK,UAAUA,CAAM;AAAA,EACnC;AAAA;AAAA,EAGA,KAAKS,GAAGC,GAAG;AACT,WAAO,KAAK,EAAED,CAAC,EAAE,EAAEC,CAAC;AAAA,EACtB;AAAA;AAAA,EAGA,QAAQ0S,IAAQ,KAAK,QAAQ;AAC3B,UAAMC,IAAa,OAAOD,KAAU;AACpC,IAAKC,MACHD,IAAQvR,GAAauR,CAAK;AAE5B,UAAME,IAAU,IAAItE,GAAI;AACxB,QAAIQ,IAAS;AAEb,YACGA,IAASA,EAAO,OAAM,MACvBA,EAAO,SAASlO,EAAQ,YACxBkO,EAAO,aAAa,yBAEpB8D,EAAQ,KAAK9D,CAAM,GAEf,GAAC6D,KAAc7D,EAAO,SAAS4D,EAAM,QAGrCC,KAAc7D,EAAO,QAAQ4D,CAAK;AAGtC,UAAI5D,EAAO,SAAS,KAAK,KAAI,EAAG;AAE9B,eAAO;AAIX,WAAO8D;AAAA,EACT;AAAA;AAAA,EAGA,UAAU5O,GAAM;AAEd,QADAA,IAAO,KAAK,KAAKA,CAAI,GACjB,CAACA,EAAM,QAAO;AAElB,UAAMhG,KAAKgG,IAAO,IAAI,MAAMX,EAAS;AACrC,WAAOrF,IAAImD,GAAanD,EAAE,CAAC,CAAC,IAAI;AAAA,EAClC;AAAA;AAAA,EAGA,OAAO;AACL,UAAMmI,IAAI,KAAK,OAAOtE,GAASb,EAAI,CAAC;AACpC,WAAOmF,KAAKA,EAAE,KAAI;AAAA,EACpB;AAAA;AAAA,EAGA,QAAQ1G,GAAG;AACT,gBAAK,MAAMA,GACJ;AAAA,EACT;AAAA;AAAA,EAGA,KAAKJ,GAAOC,GAAQ;AAClB,UAAM6G,IAAIhH,GAAiB,MAAME,GAAOC,CAAM;AAE9C,WAAO,KAAK,MAAM,IAAIkR,EAAUrK,EAAE,KAAK,CAAC,EAAE,OAAO,IAAIqK,EAAUrK,EAAE,MAAM,CAAC;AAAA,EAC1E;AAAA;AAAA,EAGA,MAAM9G,GAAO;AACX,WAAO,KAAK,KAAK,SAASA,CAAK;AAAA,EACjC;AAAA;AAAA,EAGA,iBAAiB;AACf,WAAAc,GAAe,MAAM,KAAK,GAAG,GACtB,MAAM,eAAc;AAAA,EAC7B;AAAA;AAAA,EAGA,EAAEJ,GAAG;AACH,WAAO,KAAK,KAAK,KAAKA,CAAC;AAAA,EACzB;AAAA;AAAA,EAGA,EAAEC,GAAG;AACH,WAAO,KAAK,KAAK,KAAKA,CAAC;AAAA,EACzB;AACF;AAEAiC,EAAOgK,IAAS;AAAA,EACd,MAAA4B;AAAA,EACA,MAAAE;AAAA,EACA,QAAAC;AAAA,EACA,OAAAtE;AAAA,EACA,KAAAoD;AAAA,EACA,WAAAC;AACF,CAAC;AAEDpL,EAASsK,IAAS,SAAS;AC7K3B,MAAM4G,KAAQ;AAAA,EACZ,QAAQ;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AAAA,EACE,MAAM,CAAC,SAAS,WAAW,MAAM;AAAA,EACjC,QAAQ,SAAUlO,GAAGK,GAAG;AACtB,WAAOA,MAAM,UAAUL,IAAIA,IAAI,MAAMK;AAAA,EACvC;AACF;AAGC,CAAC,QAAQ,QAAQ,EAAE,QAAQ,SAAUhH,GAAG;AACvC,QAAM8U,IAAY,CAAA;AAClB,MAAIrU;AAEJ,EAAAqU,EAAU9U,CAAC,IAAI,SAAUyB,GAAG;AAC1B,QAAI,OAAOA,IAAM;AACf,aAAO,KAAK,KAAKzB,CAAC;AAEpB,QACE,OAAOyB,KAAM,YACbA,aAAa4G,KACbA,EAAM,MAAM5G,CAAC,KACbA,aAAawM;AAEb,WAAK,KAAKjO,GAAGyB,CAAC;AAAA;AAGd,WAAKhB,IAAIoU,GAAM7U,CAAC,EAAE,SAAS,GAAGS,KAAK,GAAGA;AACpC,QAAIgB,EAAEoT,GAAM7U,CAAC,EAAES,CAAC,CAAC,KAAK,QACpB,KAAK,KAAKoU,GAAM,OAAO7U,GAAG6U,GAAM7U,CAAC,EAAES,CAAC,CAAC,GAAGgB,EAAEoT,GAAM7U,CAAC,EAAES,CAAC,CAAC,CAAC;AAK5D,WAAO;AAAA,EACT,GAEAX,EAAgB,CAAC,WAAW,QAAQ,GAAGgV,CAAS;AAClD,CAAC;AAEDhV,EAAgB,CAAC,WAAW,QAAQ,GAAG;AAAA;AAAA,EAErC,QAAQ,SAAUiV,GAAKhN,GAAG3B,GAAGtF,GAAGiM,GAAGC,GAAG;AAEpC,WAAI+H,KAAO,OACF,IAAItJ,EAAO,IAAI,IAIjB,KAAK,KAAK,aAAa,IAAIA,EAAOsJ,GAAKhN,GAAG3B,GAAGtF,GAAGiM,GAAGC,CAAC,CAAC;AAAA,EAC9D;AAAA;AAAA,EAGA,QAAQ,SAAUgI,GAAO/H,GAAIC,GAAI;AAC/B,WAAO,KAAK,UAAU,EAAE,QAAQ8H,GAAO,IAAI/H,GAAI,IAAIC,EAAE,GAAI,EAAI;AAAA,EAC/D;AAAA;AAAA,EAGA,MAAM,SAAUnL,GAAGC,GAAGiL,GAAIC,GAAI;AAC5B,WAAO,UAAU,WAAW,KAAK,UAAU,WAAW,IAClD,KAAK,UAAU,EAAE,MAAMnL,GAAG,IAAIC,GAAG,IAAIiL,EAAE,GAAI,EAAI,IAC/C,KAAK,UAAU,EAAE,MAAM,CAAClL,GAAGC,CAAC,GAAG,IAAIiL,GAAI,IAAIC,EAAE,GAAI,EAAI;AAAA,EAC3D;AAAA,EAEA,OAAO,SAAUS,GAAKV,GAAIC,GAAI;AAC5B,WAAO,KAAK,UAAU,EAAE,OAAOS,GAAK,IAAIV,GAAI,IAAIC,EAAE,GAAI,EAAI;AAAA,EAC5D;AAAA;AAAA,EAGA,OAAO,SAAUnL,GAAGC,GAAGiL,GAAIC,GAAI;AAC7B,WAAO,UAAU,WAAW,KAAK,UAAU,WAAW,IAClD,KAAK,UAAU,EAAE,OAAOnL,GAAG,IAAIC,GAAG,IAAIiL,EAAE,GAAI,EAAI,IAChD,KAAK,UAAU,EAAE,OAAO,CAAClL,GAAGC,CAAC,GAAG,IAAIiL,GAAI,IAAIC,EAAE,GAAI,EAAI;AAAA,EAC5D;AAAA;AAAA,EAGA,WAAW,SAAUnL,GAAGC,GAAG;AACzB,WAAO,KAAK,UAAU,EAAE,WAAW,CAACD,GAAGC,CAAC,EAAC,GAAI,EAAI;AAAA,EACnD;AAAA;AAAA,EAGA,UAAU,SAAUD,GAAGC,GAAG;AACxB,WAAO,KAAK,UAAU,EAAE,UAAU,CAACD,GAAGC,CAAC,EAAC,GAAI,EAAI;AAAA,EAClD;AAAA;AAAA,EAGA,MAAM,SAAUiT,IAAY,QAAQvT,IAAS,UAAU;AACrD,WAAI,aAAa,QAAQuT,CAAS,MAAM,OACtCvT,IAASuT,GACTA,IAAY,SAGP,KAAK,UAAU,EAAE,MAAMA,GAAW,QAAQvT,EAAM,GAAI,EAAI;AAAA,EACjE;AAAA;AAAA,EAGA,SAAS,SAAUiR,GAAO;AACxB,WAAO,KAAK,KAAK,WAAWA,CAAK;AAAA,EACnC;AACF,CAAC;AAED7S,EAAgB,UAAU;AAAA;AAAA,EAExB,QAAQ,SAAUiC,GAAGC,IAAID,GAAG;AAE1B,YADc,KAAK,YAAY,MAAM,SACrB,mBACZ,KAAK,KAAK,KAAK,IAAIyQ,EAAUzQ,CAAC,CAAC,IAC/B,KAAK,GAAGA,CAAC,EAAE,GAAGC,CAAC;AAAA,EACrB;AACF,CAAC;AAEDlC,EAAgB,QAAQ;AAAA;AAAA,EAEtB,QAAQ,WAAY;AAClB,WAAO,KAAK,KAAK,eAAc;AAAA,EACjC;AAAA;AAAA,EAEA,SAAS,SAAUoV,GAAQ;AACzB,WAAO,IAAI5J,EAAM,KAAK,KAAK,iBAAiB4J,CAAM,CAAC;AAAA,EACrD;AACF,CAAC;AAEDpV,EAAgB,CAAC,WAAW,QAAQ,GAAG;AAAA;AAAA,EAErC,MAAM,SAAUkH,GAAGC,GAAG;AACpB,QAAI,OAAOD,KAAM,UAAU;AACzB,WAAKC,KAAKD,EAAG,MAAK,KAAKC,GAAGD,EAAEC,CAAC,CAAC;AAC9B,aAAO;AAAA,IACT;AAEA,WAAOD,MAAM,YACT,KAAK,QAAQC,CAAC,IACdD,MAAM,WACJ,KAAK,KAAK,eAAeC,CAAC,IAC1BD,MAAM,UACJA,MAAM,YACNA,MAAM,YACNA,MAAM,aACNA,MAAM,aACNA,MAAM,UACN,KAAK,KAAK,UAAUA,GAAGC,CAAC,IACxB,KAAK,KAAKD,GAAGC,CAAC;AAAA,EACxB;AACF,CAAC;AAGD,MAAMrH,KAAU;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,OAAO,SAAUmT,GAAMjB,GAAO;AAE9B,QAAM1N,IAAK,SAAU4I,GAAG;AACtB,WAAIA,MAAM,OACR,KAAK,IAAI8E,CAAK,IAEd,KAAK,GAAGA,GAAO9E,CAAC,GAEX;AAAA,EACT;AAEA,SAAA+F,EAAKjB,CAAK,IAAI1N,GACP2O;AACT,GAAG,CAAA,CAAE;AAELjT,EAAgB,WAAWF,EAAO;ACjM3B,SAASuV,KAAc;AAC5B,SAAO,KAAK,KAAK,aAAa,IAAI;AACpC;AAGO,SAASC,KAAY;AAwB1B,UAvBgB,KAAK,KAAK,WAAW,KAAK,IAEvC,MAAM9P,EAAU,EAChB,MAAM,GAAG,EAAE,EACX,IAAI,SAAU+P,GAAK;AAElB,UAAMC,IAAKD,EAAI,KAAI,EAAG,MAAM,GAAG;AAC/B,WAAO;AAAA,MACLC,EAAG,CAAC;AAAA,MACJA,EAAG,CAAC,EAAE,MAAMzP,EAAS,EAAE,IAAI,SAAUwP,GAAK;AACxC,eAAO,WAAWA,CAAG;AAAA,MACvB,CAAC;AAAA,IACT;AAAA,EACI,CAAC,EACA,QAAO,EAEP,OAAO,SAAUlI,GAAQoI,GAAW;AACnC,WAAIA,EAAU,CAAC,MAAM,WACZpI,EAAO,UAAU1B,EAAO,UAAU8J,EAAU,CAAC,CAAC,CAAC,IAEjDpI,EAAOoI,EAAU,CAAC,CAAC,EAAE,MAAMpI,GAAQoI,EAAU,CAAC,CAAC;AAAA,EACxD,GAAG,IAAI9J,EAAM,CAAE;AAGnB;AAGO,SAAS+J,GAAS1E,GAAQrQ,GAAG;AAClC,MAAI,SAASqQ,EAAQ,QAAO;AAE5B,MAAI5O,GAAc,KAAK,IAAI,EAAG,QAAO,KAAK,MAAM4O,GAAQrQ,CAAC;AAEzD,QAAMqO,IAAM,KAAK,UAAS,GACpB2G,IAAO3E,EAAO,UAAS,EAAG,QAAO;AAEvC,cAAK,MAAMA,GAAQrQ,CAAC,EAAE,YAAW,EAAG,UAAUgV,EAAK,SAAS3G,CAAG,CAAC,GAEzD;AACT;AAGO,SAAS4G,GAAO,GAAG;AACxB,SAAO,KAAK,SAAS,KAAK,KAAI,GAAI,CAAC;AACrC;AAGO,SAASH,GAAU9T,GAAGmL,GAAU;AAErC,MAAInL,KAAK,QAAQ,OAAOA,KAAM,UAAU;AACtC,UAAMkU,IAAa,IAAIlK,EAAO,IAAI,EAAE,UAAS;AAC7C,WAAOhK,KAAK,OAAOkU,IAAaA,EAAWlU,CAAC;AAAA,EAC9C;AAEA,EAAKgK,EAAO,aAAahK,CAAC,MAExBA,IAAI,EAAE,GAAGA,GAAG,QAAQD,GAAUC,GAAG,IAAI,EAAC;AAIxC,QAAMmU,IAAgBhJ,MAAa,KAAO,OAAOA,KAAY,IACvDjM,IAAS,IAAI8K,EAAOmK,CAAa,EAAE,UAAUnU,CAAC;AACpD,SAAO,KAAK,KAAK,aAAad,CAAM;AACtC;AAEAb,EAAgB,WAAW;AAAA,EACzB,aAAAqV;AAAA,EACA,WAAAC;AAAA,EACA,UAAAI;AAAA,EACA,QAAAE;AAAA,EACA,WAAAH;AACF,CAAC;AC/Ec,MAAMM,WAAkB5H,GAAQ;AAAA,EAC7C,UAAU;AACR,gBAAK,KAAK,WAAY;AACpB,UAAI,gBAAgB4H;AAClB,eAAO,KAAK,QAAO,EAAG,QAAO;AAAA,IAEjC,CAAC,GAEM;AAAA,EACT;AAAA,EAEA,QAAQ/E,IAAS,KAAK,OAAM,GAAIgF,IAAQhF,EAAO,MAAM,IAAI,GAAG;AAE1D,WAAAgF,IAAQA,MAAU,KAAKhF,EAAO,SAAQ,EAAG,SAASgF,GAElD,KAAK,KAAK,SAAUrV,GAAG8S,GAAU;AAE/B,aAAOA,EAASA,EAAS,SAAS9S,IAAI,CAAC,EAAE,SAASqQ,GAAQgF,CAAK;AAAA,IACjE,CAAC,GAEM,KAAK,OAAM;AAAA,EACpB;AACF;AAEAnS,EAASkS,IAAW,WAAW;ACxBhB,MAAME,WAAaF,GAAU;AAAA,EAC1C,YAAYrS,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,QAAQC,CAAI,GAAGmN,CAAK;AAAA,EACtC;AAAA,EAEA,UAAU;AACR,WAAO;AAAA,EACT;AAAA,EAEA,UAAU;AACR,WAAO;AAAA,EACT;AACF;AAEAhN,EAASoS,IAAM,MAAM;ACdN,MAAMC,WAAc/H,GAAQ;AAAA;AAE3CtK,EAASqS,IAAO,OAAO;ACFhB,SAASnJ,GAAGA,GAAI;AACrB,SAAO,KAAK,KAAK,MAAMA,CAAE;AAC3B;AAGO,SAASC,GAAGA,GAAI;AACrB,SAAO,KAAK,KAAK,MAAMA,CAAE;AAC3B;AAGO,SAAS/K,GAAEA,GAAG;AACnB,SAAOA,KAAK,OAAO,KAAK,GAAE,IAAK,KAAK,GAAE,IAAK,KAAK,GAAGA,IAAI,KAAK,GAAE,CAAE;AAClE;AAGO,SAASC,GAAEA,GAAG;AACnB,SAAOA,KAAK,OAAO,KAAK,GAAE,IAAK,KAAK,GAAE,IAAK,KAAK,GAAGA,IAAI,KAAK,GAAE,CAAE;AAClE;AAGO,SAASiL,GAAGlL,GAAG;AACpB,SAAO,KAAK,KAAK,MAAMA,CAAC;AAC1B;AAGO,SAASmL,GAAGlL,GAAG;AACpB,SAAO,KAAK,KAAK,MAAMA,CAAC;AAC1B;AAGO,SAASX,GAAMA,GAAO;AAC3B,SAAOA,KAAS,OAAO,KAAK,GAAE,IAAK,IAAI,KAAK,GAAG,IAAImR,EAAUnR,CAAK,EAAE,OAAO,CAAC,CAAC;AAC/E;AAGO,SAASC,GAAOA,GAAQ;AAC7B,SAAOA,KAAU,OACb,KAAK,GAAE,IAAK,IACZ,KAAK,GAAG,IAAIkR,EAAUlR,CAAM,EAAE,OAAO,CAAC,CAAC;AAC7C;;;;;;;;;;;;AC9Be,MAAM2U,WAAgBD,GAAM;AAAA,EACzC,YAAYxS,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,WAAWC,CAAI,GAAGmN,CAAK;AAAA,EACzC;AAAA,EAEA,KAAKtP,GAAOC,GAAQ;AAClB,UAAM6G,IAAIhH,GAAiB,MAAME,GAAOC,CAAM;AAE9C,WAAO,KAAK,GAAG,IAAIkR,EAAUrK,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,EAAE;AAAA,MAC/C,IAAIqK,EAAUrK,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,IACtC;AAAA,EACE;AACF;AAEAlE,EAAOgS,IAASC,EAAO;AAEvBpW,EAAgB,aAAa;AAAA;AAAA,EAE3B,SAASqE,EAAkB,SAAU9C,IAAQ,GAAGC,IAASD,GAAO;AAC9D,WAAO,KAAK,IAAI,IAAI4U,IAAS,EAAE,KAAK5U,GAAOC,CAAM,EAAE,KAAK,GAAG,CAAC;AAAA,EAC9D,CAAC;AACH,CAAC;AAEDqC,EAASsS,IAAS,SAAS;AC/B3B,MAAME,WAAiBhD,GAAI;AAAA,EACzB,YAAY3P,IAAOZ,EAAQ,SAAS,uBAAsB,GAAI;AAC5D,UAAMY,CAAI;AAAA,EACZ;AAAA;AAAA,EAGA,IAAI4Q,GAASC,GAAUnR,GAAI;AASzB,QARI,OAAOkR,KAAY,cACrBlR,IAAKmR,GACLA,IAAWD,GACXA,IAAU,OAKRA,KAAW,QAAQ,OAAOA,KAAY,YAAY;AACpD,YAAM9Q,IAAU,IAAI6P,GAAIlQ,GAAO,WAAWC,CAAE,CAAC;AAC7C,aAAAI,EAAQ,IAAI,KAAK,KAAK,UAAU,EAAI,CAAC,GAE9BA,EAAQ,IAAI,IAAOJ,CAAE;AAAA,IAC9B;AAGA,WAAO,MAAM,IAAIkR,GAAS,IAAOlR,CAAE;AAAA,EACrC;AACF;AAEAS,EAASwS,IAAU,UAAU;AC7BtB,SAASC,GAAKrU,GAAGC,GAAG;AACzB,UAAQ,KAAK,YAAY,MAAM,SAAS,mBACpC,KAAK,KAAK,EAAE,IAAI,IAAIwQ,EAAUzQ,CAAC,GAAG,IAAI,IAAIyQ,EAAUxQ,CAAC,EAAC,CAAE,IACxD,KAAK,KAAK,EAAE,IAAI,IAAIwQ,EAAUzQ,CAAC,GAAG,IAAI,IAAIyQ,EAAUxQ,CAAC,EAAC,CAAE;AAC9D;AAEO,SAASqU,GAAGtU,GAAGC,GAAG;AACvB,UAAQ,KAAK,YAAY,MAAM,SAAS,mBACpC,KAAK,KAAK,EAAE,IAAI,IAAIwQ,EAAUzQ,CAAC,GAAG,IAAI,IAAIyQ,EAAUxQ,CAAC,EAAC,CAAE,IACxD,KAAK,KAAK,EAAE,IAAI,IAAIwQ,EAAUzQ,CAAC,GAAG,IAAI,IAAIyQ,EAAUxQ,CAAC,EAAC,CAAE;AAC9D;;;;;;ACAe,MAAMsU,WAAiBT,GAAU;AAAA,EAC9C,YAAY/B,GAAMnD,GAAO;AACvB;AAAA,MACEpN,EAAUuQ,IAAO,YAAY,OAAOA,KAAS,WAAW,OAAOA,CAAI;AAAA,MACnEnD;AAAA,IACN;AAAA,EACE;AAAA;AAAA,EAGA,KAAK3J,GAAGe,GAAG3B,GAAG;AACZ,WAAIY,MAAM,gBAAaA,IAAI,sBACpB,MAAM,KAAKA,GAAGe,GAAG3B,CAAC;AAAA,EAC3B;AAAA,EAEA,OAAO;AACL,WAAO,IAAIiJ,EAAG;AAAA,EAChB;AAAA,EAEA,UAAU;AACR,WAAOuB,GAAS,gBAAgB,KAAK,GAAE,IAAK,GAAG;AAAA,EACjD;AAAA;AAAA,EAGA,WAAW;AACT,WAAO,KAAK,IAAG;AAAA,EACjB;AAAA;AAAA,EAGA,OAAOpQ,GAAO;AAEZ,gBAAK,MAAK,GAGN,OAAOA,KAAU,cACnBA,EAAM,KAAK,MAAM,IAAI,GAGhB;AAAA,EACT;AAAA;AAAA,EAGA,MAAM;AACJ,WAAO,UAAU,KAAK,OAAO;AAAA,EAC/B;AACF;AAEAyD,EAAOqS,IAAUC,EAAU;AAE3BzW,EAAgB;AAAA,EACd,WAAW;AAAA;AAAA,IAET,YAAYuE,GAAM;AAChB,aAAO,KAAK,OAAO,SAAS,GAAGA,CAAI;AAAA,IACrC;AAAA,EACJ;AAAA;AAAA,EAEE,MAAM;AAAA,IACJ,UAAUF,EAAkB,SAAU2P,GAAMtT,GAAO;AACjD,aAAO,KAAK,IAAI,IAAI8V,GAASxC,CAAI,CAAC,EAAE,OAAOtT,CAAK;AAAA,IAClD,CAAC;AAAA,EACL;AACA,CAAC;AAEDmD,EAAS2S,IAAU,UAAU;ACrEd,MAAME,WAAgBX,GAAU;AAAA;AAAA,EAE7C,YAAYrS,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,WAAWC,CAAI,GAAGmN,CAAK;AAAA,EACzC;AAAA;AAAA,EAGA,KAAK3J,GAAGe,GAAG3B,GAAG;AACZ,WAAIY,MAAM,gBAAaA,IAAI,qBACpB,MAAM,KAAKA,GAAGe,GAAG3B,CAAC;AAAA,EAC3B;AAAA,EAEA,OAAO;AACL,WAAO,IAAIiJ,EAAG;AAAA,EAChB;AAAA,EAEA,UAAU;AACR,WAAOuB,GAAS,gBAAgB,KAAK,GAAE,IAAK,GAAG;AAAA,EACjD;AAAA;AAAA,EAGA,WAAW;AACT,WAAO,KAAK,IAAG;AAAA,EACjB;AAAA;AAAA,EAGA,OAAOpQ,GAAO;AAEZ,gBAAK,MAAK,GAGN,OAAOA,KAAU,cACnBA,EAAM,KAAK,MAAM,IAAI,GAGhB;AAAA,EACT;AAAA;AAAA,EAGA,MAAM;AACJ,WAAO,UAAU,KAAK,OAAO;AAAA,EAC/B;AACF;AAEAV,EAAgB;AAAA,EACd,WAAW;AAAA;AAAA,IAET,WAAWuE,GAAM;AACf,aAAO,KAAK,OAAO,QAAQ,GAAGA,CAAI;AAAA,IACpC;AAAA,EACJ;AAAA,EACE,MAAM;AAAA,IACJ,SAASF,EAAkB,SAAU9C,GAAOC,GAAQd,GAAO;AACzD,aAAO,KAAK,IAAI,IAAIgW,GAAO,CAAE,EAAE,OAAOhW,CAAK,EAAE,KAAK;AAAA,QAChD,GAAG;AAAA,QACH,GAAG;AAAA,QACH,OAAOa;AAAA,QACP,QAAQC;AAAA,QACR,cAAc;AAAA,MACtB,CAAO;AAAA,IACH,CAAC;AAAA,EACL;AACA,CAAC;AAEDqC,EAAS6S,IAAS,SAAS;SC5DZ,cAAoBR,GAAM;AAAA,EACvC,YAAYxS,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,SAASC,CAAI,GAAGmN,CAAK;AAAA,EACvC;AAAA;AAAA,EAGA,KAAK8F,GAAKC,GAAU;AAClB,QAAI,CAACD,EAAK,QAAO;AAEjB,UAAME,IAAM,IAAI/T,EAAQ,OAAO,MAAK;AAEpC,WAAA4O;AAAA,MACEmF;AAAA,MACA;AAAA,MACA,SAAU5J,GAAG;AACX,cAAM5E,IAAI,KAAK,OAAOqO,EAAO;AAG7B,QAAI,KAAK,YAAY,KAAK,KAAK,OAAM,MAAO,KAC1C,KAAK,KAAKG,EAAI,OAAOA,EAAI,MAAM,GAG7BxO,aAAaqO,MAEXrO,EAAE,YAAY,KAAKA,EAAE,OAAM,MAAO,KACpCA,EAAE,KAAK,KAAK,MAAK,GAAI,KAAK,OAAM,CAAE,GAIlC,OAAOuO,KAAa,cACtBA,EAAS,KAAK,MAAM3J,CAAC;AAAA,MAEzB;AAAA,MACA;AAAA,IACN,GAEIyE,GAAGmF,GAAK,cAAc,WAAY;AAEhC,MAAA3E,GAAI2E,CAAG;AAAA,IACT,CAAC,GAEM,KAAK,KAAK,QAASA,EAAI,MAAMF,GAAM9T,EAAK;AAAA,EACjD;AACF;AAEAmQ,GAAiB,SAAU9M,GAAMQ,GAAK8N,GAAO;AAE3C,UAAItO,MAAS,UAAUA,MAAS,aAC1BJ,GAAQ,KAAKY,CAAG,MAClBA,IAAM8N,EAAM,KAAI,EAAG,KAAI,EAAG,MAAM9N,CAAG,IAInCA,aAAeoQ,OACjBpQ,IAAM8N,EACH,KAAI,EACJ,KAAI,EACJ,QAAQ,GAAG,GAAG,CAACuC,MAAY;AAC1B,IAAAA,EAAQ,IAAIrQ,CAAG;AAAA,EACjB,CAAC,IAGEA;AACT,CAAC;AAED1G,EAAgB;AAAA,EACd,WAAW;AAAA;AAAA,IAET,OAAOqE,EAAkB,SAAUqH,GAAQkL,GAAU;AACnD,aAAO,KAAK,IAAI,IAAIE,IAAO,EAAE,KAAK,GAAG,CAAC,EAAE,KAAKpL,GAAQkL,CAAQ;AAAA,IAC/D,CAAC;AAAA,EACL;AACA,CAAC;AAED/S,EAASiT,IAAO,OAAO;AC/ER,MAAME,WAAmBvE,GAAS;AAAA;AAAA,EAE/C,OAAO;AACL,QAAIwE,IAAO,QACPC,IAAO,QACPC,IAAO,OACPC,IAAO;AACX,gBAAK,QAAQ,SAAUxQ,GAAI;AACzB,MAAAqQ,IAAO,KAAK,IAAIrQ,EAAG,CAAC,GAAGqQ,CAAI,GAC3BC,IAAO,KAAK,IAAItQ,EAAG,CAAC,GAAGsQ,CAAI,GAC3BC,IAAO,KAAK,IAAIvQ,EAAG,CAAC,GAAGuQ,CAAI,GAC3BC,IAAO,KAAK,IAAIxQ,EAAG,CAAC,GAAGwQ,CAAI;AAAA,IAC7B,CAAC,GACM,IAAI7H,EAAI4H,GAAMC,GAAMH,IAAOE,GAAMD,IAAOE,CAAI;AAAA,EACrD;AAAA;AAAA,EAGA,KAAKnV,GAAGC,GAAG;AACT,UAAMT,IAAM,KAAK,KAAI;AAOrB,QAJAQ,KAAKR,EAAI,GACTS,KAAKT,EAAI,GAGL,CAAC,MAAMQ,CAAC,KAAK,CAAC,MAAMC,CAAC;AACvB,eAASvB,IAAI,KAAK,SAAS,GAAGA,KAAK,GAAGA;AACpC,aAAKA,CAAC,IAAI,CAAC,KAAKA,CAAC,EAAE,CAAC,IAAIsB,GAAG,KAAKtB,CAAC,EAAE,CAAC,IAAIuB,CAAC;AAI7C,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAMzB,IAAQ,CAAC,GAAG,CAAC,GAAG;AACpB,UAAM4W,IAAS,CAAA;AAGf,IAAI5W,aAAiB,QACnBA,IAAQ,MAAM,UAAU,OAAO,MAAM,CAAA,GAAIA,CAAK,IAI9CA,IAAQA,EAAM,KAAI,EAAG,MAAMsF,EAAS,EAAE,IAAI,UAAU,GAKlDtF,EAAM,SAAS,MAAM,KAAGA,EAAM,IAAG;AAGrC,aAASE,IAAI,GAAGgU,IAAMlU,EAAM,QAAQE,IAAIgU,GAAKhU,IAAIA,IAAI;AACnD,MAAA0W,EAAO,KAAK,CAAC5W,EAAME,CAAC,GAAGF,EAAME,IAAI,CAAC,CAAC,CAAC;AAGtC,WAAO0W;AAAA,EACT;AAAA;AAAA,EAGA,KAAK9V,GAAOC,GAAQ;AAClB,QAAIb;AACJ,UAAMc,IAAM,KAAK,KAAI;AAGrB,SAAKd,IAAI,KAAK,SAAS,GAAGA,KAAK,GAAGA;AAChC,MAAIc,EAAI,UACN,KAAKd,CAAC,EAAE,CAAC,KAAM,KAAKA,CAAC,EAAE,CAAC,IAAIc,EAAI,KAAKF,IAASE,EAAI,QAAQA,EAAI,IAC5DA,EAAI,WACN,KAAKd,CAAC,EAAE,CAAC,KAAM,KAAKA,CAAC,EAAE,CAAC,IAAIc,EAAI,KAAKD,IAAUC,EAAI,SAASA,EAAI;AAGpE,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,SAAS;AACP,WAAO;AAAA,MACL,IAAI,KAAK,CAAC,EAAE,CAAC;AAAA,MACb,IAAI,KAAK,CAAC,EAAE,CAAC;AAAA,MACb,IAAI,KAAK,CAAC,EAAE,CAAC;AAAA,MACb,IAAI,KAAK,CAAC,EAAE,CAAC;AAAA,IACnB;AAAA,EACE;AAAA;AAAA,EAGA,WAAW;AACT,UAAMhB,IAAQ,CAAA;AAEd,aAASE,IAAI,GAAGC,IAAK,KAAK,QAAQD,IAAIC,GAAID;AACxC,MAAAF,EAAM,KAAK,KAAKE,CAAC,EAAE,KAAK,GAAG,CAAC;AAG9B,WAAOF,EAAM,KAAK,GAAG;AAAA,EACvB;AAAA,EAEA,UAAUP,GAAG;AACX,WAAO,KAAK,QAAQ,WAAWA,CAAC;AAAA,EAClC;AAAA;AAAA,EAGA,WAAWA,GAAG;AACZ,IAAKyL,EAAO,aAAazL,CAAC,MACxBA,IAAI,IAAIyL,EAAOzL,CAAC;AAGlB,aAASS,IAAI,KAAK,QAAQA,OAAO;AAE/B,YAAM,CAACsB,GAAGC,CAAC,IAAI,KAAKvB,CAAC;AACrB,WAAKA,CAAC,EAAE,CAAC,IAAIT,EAAE,IAAI+B,IAAI/B,EAAE,IAAIgC,IAAIhC,EAAE,GACnC,KAAKS,CAAC,EAAE,CAAC,IAAIT,EAAE,IAAI+B,IAAI/B,EAAE,IAAIgC,IAAIhC,EAAE;AAAA,IACrC;AAEA,WAAO;AAAA,EACT;AACF;ACtHO,MAAMoX,KAAaN;AAGnB,SAAS/U,GAAEA,GAAG;AACnB,SAAOA,KAAK,OAAO,KAAK,KAAI,EAAG,IAAI,KAAK,KAAKA,GAAG,KAAK,KAAI,EAAG,CAAC;AAC/D;AAGO,SAASC,GAAEA,GAAG;AACnB,SAAOA,KAAK,OAAO,KAAK,KAAI,EAAG,IAAI,KAAK,KAAK,KAAK,KAAI,EAAG,GAAGA,CAAC;AAC/D;AAGO,SAASX,GAAMA,GAAO;AAC3B,QAAM0G,IAAI,KAAK,KAAI;AACnB,SAAO1G,KAAS,OAAO0G,EAAE,QAAQ,KAAK,KAAK1G,GAAO0G,EAAE,MAAM;AAC5D;AAGO,SAASzG,GAAOA,GAAQ;AAC7B,QAAMyG,IAAI,KAAK,KAAI;AACnB,SAAOzG,KAAU,OAAOyG,EAAE,SAAS,KAAK,KAAKA,EAAE,OAAOzG,CAAM;AAC9D;;;;;;;;;ACZe,MAAM+V,WAAarB,GAAM;AAAA;AAAA,EAEtC,YAAYxS,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,QAAQC,CAAI,GAAGmN,CAAK;AAAA,EACtC;AAAA;AAAA,EAGA,QAAQ;AACN,WAAO,IAAImG,GAAW;AAAA,MACpB,CAAC,KAAK,KAAK,IAAI,GAAG,KAAK,KAAK,IAAI,CAAC;AAAA,MACjC,CAAC,KAAK,KAAK,IAAI,GAAG,KAAK,KAAK,IAAI,CAAC;AAAA,IACvC,CAAK;AAAA,EACH;AAAA;AAAA,EAGA,KAAK/U,GAAGC,GAAG;AACT,WAAO,KAAK,KAAK,KAAK,MAAK,EAAG,KAAKD,GAAGC,CAAC,EAAE,OAAM,CAAE;AAAA,EACnD;AAAA;AAAA,EAGA,KAAKsV,GAAIC,GAAIC,GAAIC,GAAI;AACnB,WAAIH,KAAM,OACD,KAAK,MAAK,KACR,OAAOC,IAAO,MACvBD,IAAK,EAAE,IAAAA,GAAI,IAAAC,GAAI,IAAAC,GAAI,IAAAC,EAAE,IAErBH,IAAK,IAAIR,GAAWQ,CAAE,EAAE,OAAM,GAGzB,KAAK,KAAKA,CAAE;AAAA,EACrB;AAAA;AAAA,EAGA,KAAKjW,GAAOC,GAAQ;AAClB,UAAM6G,IAAIhH,GAAiB,MAAME,GAAOC,CAAM;AAC9C,WAAO,KAAK,KAAK,KAAK,MAAK,EAAG,KAAK6G,EAAE,OAAOA,EAAE,MAAM,EAAE,OAAM,CAAE;AAAA,EAChE;AACF;AAEAlE,EAAOoT,IAAMK,EAAO;AAEpB5X,EAAgB;AAAA,EACd,WAAW;AAAA;AAAA,IAET,MAAMqE,EAAkB,YAAaE,GAAM;AAGzC,aAAOgT,GAAK,UAAU,KAAK;AAAA,QACzB,KAAK,IAAI,IAAIA,IAAM;AAAA,QACnBhT,EAAK,CAAC,KAAK,OAAOA,IAAO,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,MAC5C;AAAA,IACI,CAAC;AAAA,EACL;AACA,CAAC;AAEDV,EAAS0T,IAAM,MAAM;AC/DN,MAAMM,WAAe9B,GAAU;AAAA;AAAA,EAE5C,YAAYrS,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,UAAUC,CAAI,GAAGmN,CAAK;AAAA,EACxC;AAAA;AAAA,EAGA,OAAOrP,GAAQ;AACb,WAAO,KAAK,KAAK,gBAAgBA,CAAM;AAAA,EACzC;AAAA,EAEA,OAAOsW,GAAQ;AACb,WAAO,KAAK,KAAK,UAAUA,CAAM;AAAA,EACnC;AAAA;AAAA,EAGA,IAAI7V,GAAGC,GAAG;AACR,WAAO,KAAK,KAAK,QAAQD,CAAC,EAAE,KAAK,QAAQC,CAAC;AAAA,EAC5C;AAAA;AAAA,EAGA,WAAW;AACT,WAAO,UAAU,KAAK,OAAO;AAAA,EAC/B;AAAA;AAAA,EAGA,OAAOxB,GAAO;AAEZ,gBAAK,MAAK,GAGN,OAAOA,KAAU,cACnBA,EAAM,KAAK,MAAM,IAAI,GAGhB;AAAA,EACT;AAAA;AAAA,EAGA,MAAMa,GAAO;AACX,WAAO,KAAK,KAAK,eAAeA,CAAK;AAAA,EACvC;AACF;AAEAvB,EAAgB;AAAA,EACd,WAAW;AAAA,IACT,UAAUuE,GAAM;AAEd,aAAO,KAAK,OAAO,OAAO,GAAGA,CAAI;AAAA,IACnC;AAAA,EACJ;AAAA,EACE,MAAM;AAAA;AAAA,IAEJ,QAAQF,EAAkB,SAAU9C,GAAOC,GAAQd,GAAO;AAExD,aAAO,KAAK,IAAI,IAAImX,GAAM,CAAE,EACzB,KAAKtW,GAAOC,CAAM,EAClB,IAAID,IAAQ,GAAGC,IAAS,CAAC,EACzB,QAAQ,GAAG,GAAGD,GAAOC,CAAM,EAC3B,KAAK,UAAU,MAAM,EACrB,OAAOd,CAAK;AAAA,IACjB,CAAC;AAAA,EACL;AAAA,EACE,QAAQ;AAAA;AAAA,IAEN,OAAOqX,GAAQxW,GAAOC,GAAQd,GAAO;AACnC,UAAIwF,IAAO,CAAC,QAAQ;AAGpB,aAAI6R,MAAW,SAAO7R,EAAK,KAAK6R,CAAM,GACtC7R,IAAOA,EAAK,KAAK,GAAG,GAGpB6R,IACE,UAAU,CAAC,aAAaF,KACpB,UAAU,CAAC,IACX,KAAK,KAAI,EAAG,OAAOtW,GAAOC,GAAQd,CAAK,GAEtC,KAAK,KAAKwF,GAAM6R,CAAM;AAAA,IAC/B;AAAA,EACJ;AACA,CAAC;AAEDlU,EAASgU,IAAQ,QAAQ;AC9EzB,SAASG,GAAiB1Q,GAAG4F,GAAG;AAC9B,SAAO,SAAU/F,GAAG;AAClB,WAAIA,KAAK,OAAa,KAAKG,CAAC,KAC5B,KAAKA,CAAC,IAAIH,GACN+F,KAAGA,EAAE,KAAK,IAAI,GACX;AAAA,EACT;AACF;AAEO,MAAM+K,KAAS;AAAA,EACpB,KAAK,SAAUC,GAAK;AAClB,WAAOA;AAAA,EACT;AAAA,EACA,MAAM,SAAUA,GAAK;AACnB,WAAO,CAAC,KAAK,IAAIA,IAAM,KAAK,EAAE,IAAI,IAAI;AAAA,EACxC;AAAA,EACA,KAAK,SAAUA,GAAK;AAClB,WAAO,KAAK,IAAKA,IAAM,KAAK,KAAM,CAAC;AAAA,EACrC;AAAA,EACA,KAAK,SAAUA,GAAK;AAClB,WAAO,CAAC,KAAK,IAAKA,IAAM,KAAK,KAAM,CAAC,IAAI;AAAA,EAC1C;AAAA,EACA,QAAQ,SAAUV,GAAIC,GAAIC,GAAIC,GAAI;AAEhC,WAAO,SAAU9Q,GAAG;AAClB,aAAIA,IAAI,IACF2Q,IAAK,IACCC,IAAKD,IAAM3Q,IACV6Q,IAAK,IACNC,IAAKD,IAAM7Q,IAEZ,IAEAA,IAAI,IACT6Q,IAAK,KACE,IAAIC,MAAO,IAAID,KAAO7Q,KAAK8Q,IAAKD,MAAO,IAAIA,KAC3CF,IAAK,KACL,IAAIC,MAAO,IAAID,KAAO3Q,KAAK4Q,IAAKD,MAAO,IAAIA,KAE7C,IAGF,IAAI3Q,KAAK,IAAIA,MAAM,IAAI4Q,IAAK,IAAI5Q,KAAK,KAAK,IAAIA,KAAK8Q,IAAK9Q,KAAK;AAAA,IAExE;AAAA,EACF;AAAA;AAAA,EAEA,OAAO,SAAUsR,GAAOC,IAAe,OAAO;AAE5C,IAAAA,IAAeA,EAAa,MAAM,GAAG,EAAE,QAAO,EAAG,CAAC;AAElD,QAAIC,IAAQF;AACZ,WAAIC,MAAiB,SACnB,EAAEC,IACOD,MAAiB,UAC1B,EAAEC,GAIG,CAACxR,GAAGyR,IAAa,OAAU;AAEhC,UAAIC,IAAO,KAAK,MAAM1R,IAAIsR,CAAK;AAC/B,YAAMK,IAAW3R,IAAI0R,IAAQ,MAAM;AAEnC,cAAIH,MAAiB,WAAWA,MAAiB,WAC/C,EAAEG,GAGAD,KAAcE,KAChB,EAAED,GAGA1R,KAAK,KAAK0R,IAAO,MACnBA,IAAO,IAGL1R,KAAK,KAAK0R,IAAOF,MACnBE,IAAOF,IAGFE,IAAOF;AAAA,IAChB;AAAA,EACF;AACF;AAEO,MAAMI,GAAQ;AAAA,EACnB,OAAO;AACL,WAAO;AAAA,EACT;AACF;AAOO,MAAMC,WAAaD,GAAQ;AAAA,EAChC,YAAYnU,IAAKkO,GAAS,MAAM;AAC9B,UAAK,GACL,KAAK,OAAOyF,GAAO3T,CAAE,KAAKA;AAAA,EAC5B;AAAA,EAEA,KAAKgS,GAAMC,GAAI2B,GAAK;AAClB,WAAI,OAAO5B,KAAS,WACX4B,IAAM,IAAI5B,IAAOC,IAEnBD,KAAQC,IAAKD,KAAQ,KAAK,KAAK4B,CAAG;AAAA,EAC3C;AACF;AAOO,MAAMS,WAAmBF,GAAQ;AAAA,EACtC,YAAYnU,GAAI;AACd,UAAK,GACL,KAAK,UAAUA;AAAA,EACjB;AAAA,EAEA,KAAKgC,GAAG;AACN,WAAOA,EAAE;AAAA,EACX;AAAA,EAEA,KAAKwI,GAAS8J,GAAQC,GAAIvS,GAAG;AAC3B,WAAO,KAAK,QAAQwI,GAAS8J,GAAQC,GAAIvS,CAAC;AAAA,EAC5C;AACF;AAEA,SAASwS,KAAc;AAErB,QAAMC,KAAY,KAAK,aAAa,OAAO,KACrCC,IAAY,KAAK,cAAc,GAG/BC,IAAM,OACNnQ,IAAK,KAAK,IACVoQ,IAAK,KAAK,IAAIF,IAAY,MAAMC,CAAG,GACnCE,IAAO,CAACD,IAAK,KAAK,KAAKpQ,IAAKA,IAAKoQ,IAAKA,CAAE,GACxCE,IAAK,OAAOD,IAAOJ;AAGzB,OAAK,IAAI,IAAII,IAAOC,GACpB,KAAK,IAAIA,IAAKA;AAChB;AAEO,MAAMC,WAAeV,GAAW;AAAA,EACrC,YAAYI,IAAW,KAAKC,IAAY,GAAG;AACzC,UAAK,GACL,KAAK,SAASD,CAAQ,EAAE,UAAUC,CAAS;AAAA,EAC7C;AAAA,EAEA,KAAKlK,GAAS8J,GAAQC,GAAIvS,GAAG;AAC3B,QAAI,OAAOwI,KAAY,SAAU,QAAOA;AAExC,QADAxI,EAAE,OAAOuS,MAAO,OACZA,MAAO,MAAU,QAAOD;AAC5B,QAAIC,MAAO,EAAG,QAAO/J;AAErB,IAAI+J,IAAK,QAAKA,IAAK,KAEnBA,KAAM;AAGN,UAAMS,IAAWhT,EAAE,YAAY,GAGzBiT,IAAe,CAAC,KAAK,IAAID,IAAW,KAAK,KAAKxK,IAAU8J,IACxDY,IAAc1K,IAAUwK,IAAWT,IAAMU,IAAeV,IAAKA,IAAM;AAGzE,WAAAvS,EAAE,WAAWgT,IAAWC,IAAeV,GAGvCvS,EAAE,OAAO,KAAK,IAAIsS,IAASY,CAAW,IAAI,KAAK,IAAIF,CAAQ,IAAI,MACxDhT,EAAE,OAAOsS,IAASY;AAAA,EAC3B;AACF;AAEArV,EAAOkV,IAAQ;AAAA,EACb,UAAUrB,GAAiB,aAAac,EAAW;AAAA,EACnD,WAAWd,GAAiB,cAAcc,EAAW;AACvD,CAAC;AAEM,MAAMW,WAAYd,GAAW;AAAA,EAClC,YAAYtQ,IAAI,KAAK1H,IAAI,MAAMK,IAAI,GAAG0Y,IAAS,KAAM;AACnD,UAAK,GACL,KAAK,EAAErR,CAAC,EAAE,EAAE1H,CAAC,EAAE,EAAEK,CAAC,EAAE,OAAO0Y,CAAM;AAAA,EACnC;AAAA,EAEA,KAAK5K,GAAS8J,GAAQC,GAAIvS,GAAG;AAC3B,QAAI,OAAOwI,KAAY,SAAU,QAAOA;AAGxC,QAFAxI,EAAE,OAAOuS,MAAO,OAEZA,MAAO,MAAU,QAAOD;AAC5B,QAAIC,MAAO,EAAG,QAAO/J;AAErB,UAAMzG,IAAIuQ,IAAS9J;AACnB,QAAInO,KAAK2F,EAAE,YAAY,KAAK+B,IAAIwQ;AAChC,UAAM7X,KAAKqH,KAAK/B,EAAE,SAAS,MAAMuS,GAC3Ba,IAAS,KAAK;AAGpB,WAAIA,MAAW,OACb/Y,IAAI,KAAK,IAAI,CAAC+Y,GAAQ,KAAK,IAAI/Y,GAAG+Y,CAAM,CAAC,IAG3CpT,EAAE,QAAQ+B,GACV/B,EAAE,WAAW3F,GAEb2F,EAAE,OAAO,KAAK,IAAI+B,CAAC,IAAI,MAEhB/B,EAAE,OAAOsS,IAAS9J,KAAW,KAAK,IAAIzG,IAAI,KAAK,IAAI1H,IAAI,KAAK,IAAIK;AAAA,EACzE;AACF;AAEAmD,EAAOsV,IAAK;AAAA,EACV,QAAQzB,GAAiB,SAAS;AAAA,EAClC,GAAGA,GAAiB,GAAG;AAAA,EACvB,GAAGA,GAAiB,GAAG;AAAA,EACvB,GAAGA,GAAiB,GAAG;AACzB,CAAC;ACnOD,MAAM2B,KAAoB;AAAA,EACxB,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL,GAEMC,KAAe;AAAA,EACnB,GAAG,SAAUtT,GAAG+B,GAAGwR,GAAI;AACrB,WAAAxR,EAAE,IAAIwR,EAAG,IAAIvT,EAAE,CAAC,GAChB+B,EAAE,IAAIwR,EAAG,IAAIvT,EAAE,CAAC,GAET,CAAC,KAAK+B,EAAE,GAAGA,EAAE,CAAC;AAAA,EACvB;AAAA,EACA,GAAG,SAAU/B,GAAG+B,GAAG;AACjB,WAAAA,EAAE,IAAI/B,EAAE,CAAC,GACT+B,EAAE,IAAI/B,EAAE,CAAC,GACF,CAAC,KAAKA,EAAE,CAAC,GAAGA,EAAE,CAAC,CAAC;AAAA,EACzB;AAAA,EACA,GAAG,SAAUA,GAAG+B,GAAG;AACjB,WAAAA,EAAE,IAAI/B,EAAE,CAAC,GACF,CAAC,KAAKA,EAAE,CAAC,CAAC;AAAA,EACnB;AAAA,EACA,GAAG,SAAUA,GAAG+B,GAAG;AACjB,WAAAA,EAAE,IAAI/B,EAAE,CAAC,GACF,CAAC,KAAKA,EAAE,CAAC,CAAC;AAAA,EACnB;AAAA,EACA,GAAG,SAAUA,GAAG+B,GAAG;AACjB,WAAAA,EAAE,IAAI/B,EAAE,CAAC,GACT+B,EAAE,IAAI/B,EAAE,CAAC,GACF,CAAC,KAAKA,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAGA,EAAE,CAAC,CAAC;AAAA,EACjD;AAAA,EACA,GAAG,SAAUA,GAAG+B,GAAG;AACjB,WAAAA,EAAE,IAAI/B,EAAE,CAAC,GACT+B,EAAE,IAAI/B,EAAE,CAAC,GACF,CAAC,KAAKA,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAGA,EAAE,CAAC,CAAC;AAAA,EACrC;AAAA,EACA,GAAG,SAAUA,GAAG+B,GAAG;AACjB,WAAAA,EAAE,IAAI/B,EAAE,CAAC,GACT+B,EAAE,IAAI/B,EAAE,CAAC,GACF,CAAC,KAAKA,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAGA,EAAE,CAAC,CAAC;AAAA,EACrC;AAAA,EACA,GAAG,SAAUA,GAAG+B,GAAG;AACjB,WAAAA,EAAE,IAAI/B,EAAE,CAAC,GACT+B,EAAE,IAAI/B,EAAE,CAAC,GACF,CAAC,KAAKA,EAAE,CAAC,GAAGA,EAAE,CAAC,CAAC;AAAA,EACzB;AAAA,EACA,GAAG,SAAUA,GAAG+B,GAAGwR,GAAI;AACrB,WAAAxR,EAAE,IAAIwR,EAAG,GACTxR,EAAE,IAAIwR,EAAG,GACF,CAAC,GAAG;AAAA,EACb;AAAA,EACA,GAAG,SAAUvT,GAAG+B,GAAG;AACjB,WAAAA,EAAE,IAAI/B,EAAE,CAAC,GACT+B,EAAE,IAAI/B,EAAE,CAAC,GACF,CAAC,KAAKA,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAGA,EAAE,CAAC,CAAC;AAAA,EACvD;AACF,GAEMwT,KAAa,aAAa,MAAM,EAAE;AAExC,SAAS,IAAI,GAAGlZ,IAAKkZ,GAAW,QAAQ,IAAIlZ,GAAI,EAAE;AAChD,EAAAgZ,GAAaE,GAAW,CAAC,CAAC,IAAK,yBAAUnZ,GAAG;AAC1C,WAAO,SAAU2F,GAAG+B,GAAGwR,GAAI;AACzB,UAAIlZ,MAAM,IAAK,CAAA2F,EAAE,CAAC,IAAIA,EAAE,CAAC,IAAI+B,EAAE;AAAA,eACtB1H,MAAM,IAAK,CAAA2F,EAAE,CAAC,IAAIA,EAAE,CAAC,IAAI+B,EAAE;AAAA,eAC3B1H,MAAM;AACb,QAAA2F,EAAE,CAAC,IAAIA,EAAE,CAAC,IAAI+B,EAAE,GAChB/B,EAAE,CAAC,IAAIA,EAAE,CAAC,IAAI+B,EAAE;AAAA;AAEhB,iBAASiK,IAAI,GAAGyH,IAAKzT,EAAE,QAAQgM,IAAIyH,GAAI,EAAEzH;AACvC,UAAAhM,EAAEgM,CAAC,IAAIhM,EAAEgM,CAAC,KAAKA,IAAI,IAAIjK,EAAE,IAAIA,EAAE;AAInC,aAAOuR,GAAajZ,CAAC,EAAE2F,GAAG+B,GAAGwR,CAAE;AAAA,IACjC;AAAA,EACF,EAAGC,GAAW,CAAC,EAAE,YAAW,CAAE;AAGhC,SAASE,GAAY7K,GAAQ;AAC3B,QAAM8K,IAAU9K,EAAO,QAAQ,CAAC;AAChC,SAAOyK,GAAaK,CAAO,EAAE9K,EAAO,QAAQ,MAAM,CAAC,GAAGA,EAAO,GAAGA,EAAO,EAAE;AAC3E;AAEA,SAAS+K,GAAgB/K,GAAQ;AAC/B,SACEA,EAAO,QAAQ,UACfA,EAAO,QAAQ,SAAS,MACtBwK,GAAkBxK,EAAO,QAAQ,CAAC,EAAE,YAAW,CAAE;AAEvD;AAEA,SAASgL,GAAgBhL,GAAQiL,GAAO;AACtC,EAAAjL,EAAO,YAAYkL,GAAelL,GAAQ,EAAK;AAC/C,QAAMmL,IAAatU,GAAa,KAAKoU,CAAK;AAE1C,MAAIE;AACF,IAAAnL,EAAO,UAAU,CAACiL,CAAK;AAAA,OAClB;AACL,UAAMG,IAAcpL,EAAO,aACrBqL,IAAQD,EAAY,YAAW,GAC/BE,IAAUF,MAAgBC;AAChC,IAAArL,EAAO,UAAU,CAACqL,MAAU,MAAOC,IAAU,MAAM,MAAOF,CAAW;AAAA,EACvE;AAEA,SAAApL,EAAO,YAAY,IACnBA,EAAO,cAAcA,EAAO,QAAQ,CAAC,GAE9BmL;AACT;AAEA,SAASD,GAAelL,GAAQuL,GAAU;AACxC,MAAI,CAACvL,EAAO,SAAU,OAAM,IAAI,MAAM,cAAc;AACpD,EAAAA,EAAO,UAAUA,EAAO,QAAQ,KAAK,WAAWA,EAAO,MAAM,CAAC,GAC9DA,EAAO,WAAWuL,GAClBvL,EAAO,SAAS,IAChBA,EAAO,YAAY,IACnBA,EAAO,cAAc,IAEjB+K,GAAgB/K,CAAM,KACxBwL,GAAgBxL,CAAM;AAE1B;AAEA,SAASwL,GAAgBxL,GAAQ;AAC/B,EAAAA,EAAO,YAAY,IACfA,EAAO,aACTA,EAAO,UAAU6K,GAAY7K,CAAM,IAErCA,EAAO,SAAS,KAAKA,EAAO,OAAO;AACrC;AAEA,SAASyL,GAAUzL,GAAQ;AACzB,MAAI,CAACA,EAAO,QAAQ,OAAQ,QAAO;AACnC,QAAM0L,IAAQ1L,EAAO,QAAQ,CAAC,EAAE,YAAW,MAAO,KAC5CiG,IAASjG,EAAO,QAAQ;AAE9B,SAAO0L,MAAUzF,MAAW,KAAKA,MAAW;AAC9C;AAEA,SAAS0F,GAAc3L,GAAQ;AAC7B,SAAOA,EAAO,UAAU,kBAAkB;AAC5C;AAEA,MAAM4L,KAAiB,oBAAI,IAAI,CAAC,KAAK,KAAK,KAAM;AAAA,GAAM,MAAM,IAAI,CAAC;AAC1D,SAASC,GAAWha,GAAGia,IAAa,IAAM;AAC/C,MAAIjF,IAAQ,GACRoE,IAAQ;AACZ,QAAMjL,IAAS;AAAA,IACb,SAAS,CAAA;AAAA,IACT,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,WAAW;AAAA,IACX,UAAU,CAAA;AAAA,IACV,WAAW;AAAA,IACX,aAAa;AAAA,IACb,UAAU8L;AAAA,IACV,IAAI,IAAIzP,EAAK;AAAA,IACb,GAAG,IAAIA,EAAK;AAAA,EAChB;AAEE,SAAS2D,EAAO,YAAYiL,GAASA,IAAQpZ,EAAE,OAAOgV,GAAO;AAC3D,QAAI,GAAC7G,EAAO,aACNgL,GAAgBhL,GAAQiL,CAAK,IAKnC;AAAA,UAAIA,MAAU,KAAK;AACjB,YAAIjL,EAAO,aAAaA,EAAO,aAAa;AAC1C,UAAAkL,GAAelL,GAAQ,EAAK,GAC5B,EAAE6G;AACF;AAAA,QACF;AACA,QAAA7G,EAAO,WAAW,IAClBA,EAAO,YAAY,IACnBA,EAAO,UAAUiL;AACjB;AAAA,MACF;AAEA,UAAI,CAAC,MAAM,SAASA,CAAK,CAAC,GAAG;AAC3B,YAAIjL,EAAO,WAAW,OAAOyL,GAAUzL,CAAM,GAAG;AAC9C,UAAAA,EAAO,WAAW,IAClBA,EAAO,SAASiL,GAChBC,GAAelL,GAAQ,EAAI;AAC3B;AAAA,QACF;AAEA,QAAAA,EAAO,WAAW,IAClBA,EAAO,UAAUiL;AACjB;AAAA,MACF;AAEA,UAAIW,GAAe,IAAIX,CAAK,GAAG;AAC7B,QAAIjL,EAAO,YACTkL,GAAelL,GAAQ,EAAK;AAE9B;AAAA,MACF;AAEA,UAAIiL,MAAU,OAAOA,MAAU,KAAK;AAClC,YAAIjL,EAAO,YAAY,CAAC2L,GAAc3L,CAAM,GAAG;AAC7C,UAAAkL,GAAelL,GAAQ,EAAK,GAC5B,EAAE6G;AACF;AAAA,QACF;AACA,QAAA7G,EAAO,UAAUiL,GACjBjL,EAAO,WAAW;AAClB;AAAA,MACF;AAEA,UAAIiL,EAAM,YAAW,MAAO,KAAK;AAC/B,QAAAjL,EAAO,UAAUiL,GACjBjL,EAAO,cAAc;AACrB;AAAA,MACF;AAEA,UAAInJ,GAAa,KAAKoU,CAAK,GAAG;AAC5B,YAAIjL,EAAO;AACT,UAAAkL,GAAelL,GAAQ,EAAK;AAAA,iBAClB+K,GAAgB/K,CAAM;AAGhC,UAAAwL,GAAgBxL,CAAM;AAAA;AAFtB,gBAAM,IAAI,MAAM,cAAc;AAIhC,UAAE6G;AAAA,MACJ;AAAA;AAGF,SAAI7G,EAAO,YACTkL,GAAelL,GAAQ,EAAK,GAG1BA,EAAO,aAAa+K,GAAgB/K,CAAM,KAC5CwL,GAAgBxL,CAAM,GAGjBA,EAAO;AAChB;ACpPA,SAAS+L,GAAchU,GAAG;AACxB,MAAIhG,IAAI;AACR,WAASP,IAAI,GAAGC,IAAKsG,EAAE,QAAQvG,IAAIC,GAAID;AACrC,IAAAO,KAAKgG,EAAEvG,CAAC,EAAE,CAAC,GAEPuG,EAAEvG,CAAC,EAAE,CAAC,KAAK,SACbO,KAAKgG,EAAEvG,CAAC,EAAE,CAAC,GAEPuG,EAAEvG,CAAC,EAAE,CAAC,KAAK,SACbO,KAAK,KACLA,KAAKgG,EAAEvG,CAAC,EAAE,CAAC,GAEPuG,EAAEvG,CAAC,EAAE,CAAC,KAAK,SACbO,KAAK,KACLA,KAAKgG,EAAEvG,CAAC,EAAE,CAAC,GACXO,KAAK,KACLA,KAAKgG,EAAEvG,CAAC,EAAE,CAAC,GAEPuG,EAAEvG,CAAC,EAAE,CAAC,KAAK,SACbO,KAAK,KACLA,KAAKgG,EAAEvG,CAAC,EAAE,CAAC,GACXO,KAAK,KACLA,KAAKgG,EAAEvG,CAAC,EAAE,CAAC,GAEPuG,EAAEvG,CAAC,EAAE,CAAC,KAAK,SACbO,KAAK,KACLA,KAAKgG,EAAEvG,CAAC,EAAE,CAAC;AAQvB,SAAOO,IAAI;AACb;AAEe,MAAMia,WAAkB1I,GAAS;AAAA;AAAA,EAE9C,OAAO;AACL,WAAAtD,GAAM,EAAG,KAAK,aAAa,KAAK,KAAK,SAAQ,CAAE,GACxC,IAAII,EAAIJ,GAAO,MAAM,KAAK,QAAO,CAAE;AAAA,EAC5C;AAAA;AAAA,EAGA,KAAKlN,GAAGC,GAAG;AAET,UAAMT,IAAM,KAAK,KAAI;AAMrB,QAHAQ,KAAKR,EAAI,GACTS,KAAKT,EAAI,GAEL,CAAC,MAAMQ,CAAC,KAAK,CAAC,MAAMC,CAAC;AAEvB,eAAS6G,GAAGpI,IAAI,KAAK,SAAS,GAAGA,KAAK,GAAGA;AACvC,QAAAoI,IAAI,KAAKpI,CAAC,EAAE,CAAC,GAEToI,MAAM,OAAOA,MAAM,OAAOA,MAAM,OAClC,KAAKpI,CAAC,EAAE,CAAC,KAAKsB,GACd,KAAKtB,CAAC,EAAE,CAAC,KAAKuB,KACL6G,MAAM,MACf,KAAKpI,CAAC,EAAE,CAAC,KAAKsB,IACL8G,MAAM,MACf,KAAKpI,CAAC,EAAE,CAAC,KAAKuB,IACL6G,MAAM,OAAOA,MAAM,OAAOA,MAAM,OACzC,KAAKpI,CAAC,EAAE,CAAC,KAAKsB,GACd,KAAKtB,CAAC,EAAE,CAAC,KAAKuB,GACd,KAAKvB,CAAC,EAAE,CAAC,KAAKsB,GACd,KAAKtB,CAAC,EAAE,CAAC,KAAKuB,GAEV6G,MAAM,QACR,KAAKpI,CAAC,EAAE,CAAC,KAAKsB,GACd,KAAKtB,CAAC,EAAE,CAAC,KAAKuB,MAEP6G,MAAM,QACf,KAAKpI,CAAC,EAAE,CAAC,KAAKsB,GACd,KAAKtB,CAAC,EAAE,CAAC,KAAKuB;AAKpB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAMlB,IAAI,QAAQ;AAChB,WAAI,MAAM,QAAQA,CAAC,MACjBA,IAAI,MAAM,UAAU,OAAO,MAAM,CAAA,GAAIA,CAAC,EAAE,SAAQ,IAG3Cga,GAAWha,CAAC;AAAA,EACrB;AAAA;AAAA,EAGA,KAAKO,GAAOC,GAAQ;AAElB,UAAMC,IAAM,KAAK,KAAI;AACrB,QAAId,GAAGoI;AAQP,SAJAtH,EAAI,QAAQA,EAAI,UAAU,IAAI,IAAIA,EAAI,OACtCA,EAAI,SAASA,EAAI,WAAW,IAAI,IAAIA,EAAI,QAGnCd,IAAI,KAAK,SAAS,GAAGA,KAAK,GAAGA;AAChC,MAAAoI,IAAI,KAAKpI,CAAC,EAAE,CAAC,GAEToI,MAAM,OAAOA,MAAM,OAAOA,MAAM,OAClC,KAAKpI,CAAC,EAAE,CAAC,KAAM,KAAKA,CAAC,EAAE,CAAC,IAAIc,EAAI,KAAKF,IAASE,EAAI,QAAQA,EAAI,GAC9D,KAAKd,CAAC,EAAE,CAAC,KAAM,KAAKA,CAAC,EAAE,CAAC,IAAIc,EAAI,KAAKD,IAAUC,EAAI,SAASA,EAAI,KACvDsH,MAAM,MACf,KAAKpI,CAAC,EAAE,CAAC,KAAM,KAAKA,CAAC,EAAE,CAAC,IAAIc,EAAI,KAAKF,IAASE,EAAI,QAAQA,EAAI,IACrDsH,MAAM,MACf,KAAKpI,CAAC,EAAE,CAAC,KAAM,KAAKA,CAAC,EAAE,CAAC,IAAIc,EAAI,KAAKD,IAAUC,EAAI,SAASA,EAAI,IACvDsH,MAAM,OAAOA,MAAM,OAAOA,MAAM,OACzC,KAAKpI,CAAC,EAAE,CAAC,KAAM,KAAKA,CAAC,EAAE,CAAC,IAAIc,EAAI,KAAKF,IAASE,EAAI,QAAQA,EAAI,GAC9D,KAAKd,CAAC,EAAE,CAAC,KAAM,KAAKA,CAAC,EAAE,CAAC,IAAIc,EAAI,KAAKD,IAAUC,EAAI,SAASA,EAAI,GAChE,KAAKd,CAAC,EAAE,CAAC,KAAM,KAAKA,CAAC,EAAE,CAAC,IAAIc,EAAI,KAAKF,IAASE,EAAI,QAAQA,EAAI,GAC9D,KAAKd,CAAC,EAAE,CAAC,KAAM,KAAKA,CAAC,EAAE,CAAC,IAAIc,EAAI,KAAKD,IAAUC,EAAI,SAASA,EAAI,GAE5DsH,MAAM,QACR,KAAKpI,CAAC,EAAE,CAAC,KAAM,KAAKA,CAAC,EAAE,CAAC,IAAIc,EAAI,KAAKF,IAASE,EAAI,QAAQA,EAAI,GAC9D,KAAKd,CAAC,EAAE,CAAC,KAAM,KAAKA,CAAC,EAAE,CAAC,IAAIc,EAAI,KAAKD,IAAUC,EAAI,SAASA,EAAI,MAEzDsH,MAAM,QAEf,KAAKpI,CAAC,EAAE,CAAC,IAAK,KAAKA,CAAC,EAAE,CAAC,IAAIY,IAASE,EAAI,OACxC,KAAKd,CAAC,EAAE,CAAC,IAAK,KAAKA,CAAC,EAAE,CAAC,IAAIa,IAAUC,EAAI,QAGzC,KAAKd,CAAC,EAAE,CAAC,KAAM,KAAKA,CAAC,EAAE,CAAC,IAAIc,EAAI,KAAKF,IAASE,EAAI,QAAQA,EAAI,GAC9D,KAAKd,CAAC,EAAE,CAAC,KAAM,KAAKA,CAAC,EAAE,CAAC,IAAIc,EAAI,KAAKD,IAAUC,EAAI,SAASA,EAAI;AAIpE,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,WAAW;AACT,WAAOyZ,GAAc,IAAI;AAAA,EAC3B;AACF;ACzIA,MAAME,KAAkB,CAACvI,MAAU;AACjC,QAAMmB,IAAO,OAAOnB;AAEpB,SAAImB,MAAS,WACJtB,IACEsB,MAAS,WACdzL,EAAM,QAAQsK,CAAK,IACdtK,IACExC,GAAU,KAAK8M,CAAK,IACtB7M,GAAa,KAAK6M,CAAK,IAAIsI,KAAY1I,KACrCrN,GAAc,KAAKyN,CAAK,IAC1BH,IAEA2I,KAEAC,GAAe,QAAQzI,EAAM,WAAW,IAAI,KAC9CA,EAAM,cACJ,MAAM,QAAQA,CAAK,IACrBJ,KACEuB,MAAS,WACXuH,KAEAF;AAEX;AAEe,MAAMG,GAAU;AAAA,EAC7B,YAAYC,GAAS;AACnB,SAAK,WAAWA,KAAW,IAAI/C,GAAK,GAAG,GAEvC,KAAK,QAAQ,MACb,KAAK,MAAM,MACX,KAAK,QAAQ,MACb,KAAK,WAAW,MAChB,KAAK,YAAY;AAAA,EACnB;AAAA,EAEA,GAAGR,GAAK;AACN,WAAO,KAAK,UAAU;AAAA,MACpB,KAAK;AAAA,MACL,KAAK;AAAA,MACLA;AAAA,MACA,KAAK;AAAA,MACL,KAAK;AAAA,IACX;AAAA,EACE;AAAA,EAEA,OAAO;AAOL,WANiB,KAAK,SAAS,IAAI,KAAK,SAAS,IAAI,EAAE,OAAO,SAC5DjF,GACAC,GACA;AACA,aAAOD,KAAQC;AAAA,IACjB,GAAG,EAAI;AAAA,EAET;AAAA,EAEA,KAAKxM,GAAK;AACR,WAAIA,KAAO,OACF,KAAK,SAGd,KAAK,QAAQ,KAAK,KAAKA,CAAG,GACnB;AAAA,EACT;AAAA,EAEA,QAAQ+U,GAAS;AACf,WAAIA,KAAW,OAAa,KAAK,YACjC,KAAK,WAAWA,GACT;AAAA,EACT;AAAA,EAEA,GAAG/U,GAAK;AACN,WAAIA,KAAO,OACF,KAAK,OAGd,KAAK,MAAM,KAAK,KAAKA,CAAG,GACjB;AAAA,EACT;AAAA,EAEA,KAAKsN,GAAM;AAET,WAAIA,KAAQ,OACH,KAAK,SAId,KAAK,QAAQA,GACN;AAAA,EACT;AAAA,EAEA,KAAKnB,GAAO;AACV,IAAK,KAAK,SACR,KAAK,KAAKuI,GAAgBvI,CAAK,CAAC;AAGlC,QAAIhS,IAAS,IAAI,KAAK,MAAMgS,CAAK;AACjC,WAAI,KAAK,UAAUtK,MACjB1H,IAAS,KAAK,MACVA,EAAO,KAAK,IAAI,CAAC,CAAC,EAAC,IACnB,KAAK,QACHA,EAAO,KAAK,MAAM,CAAC,CAAC,EAAC,IACrBA,IAGJ,KAAK,UAAU0a,OACjB1a,IAAS,KAAK,MACVA,EAAO,MAAM,KAAK,GAAG,IACrB,KAAK,QACHA,EAAO,MAAM,KAAK,KAAK,IACvBA,IAGRA,IAASA,EAAO,aAAY,GAE5B,KAAK,YAAY,KAAK,aAAa,IAAI,KAAK,MAAK,GACjD,KAAK,WACH,KAAK,YACL,MAAM,MAAM,MAAM,MAAMA,EAAO,MAAM,CAAC,EACnC,IAAI,MAAM,EACV,IAAI,SAAUc,GAAG;AAChB,aAAAA,EAAE,OAAO,IACFA;AAAA,IACT,CAAC,GACEd;AAAA,EACT;AACF;AAEO,MAAMwa,GAAa;AAAA,EACxB,eAAe9W,GAAM;AACnB,SAAK,KAAK,GAAGA,CAAI;AAAA,EACnB;AAAA,EAEA,KAAKmC,GAAK;AACR,WAAAA,IAAM,MAAM,QAAQA,CAAG,IAAIA,EAAI,CAAC,IAAIA,GACpC,KAAK,QAAQA,GACN;AAAA,EACT;AAAA,EAEA,UAAU;AACR,WAAO,CAAC,KAAK,KAAK;AAAA,EACpB;AAAA,EAEA,UAAU;AACR,WAAO,KAAK;AAAA,EACd;AACF;AAEO,MAAMgV,GAAa;AAAA,EACxB,eAAenX,GAAM;AACnB,SAAK,KAAK,GAAGA,CAAI;AAAA,EACnB;AAAA,EAEA,KAAKqM,GAAK;AACR,WAAI,MAAM,QAAQA,CAAG,MACnBA,IAAM;AAAA,MACJ,QAAQA,EAAI,CAAC;AAAA,MACb,QAAQA,EAAI,CAAC;AAAA,MACb,OAAOA,EAAI,CAAC;AAAA,MACZ,QAAQA,EAAI,CAAC;AAAA,MACb,YAAYA,EAAI,CAAC;AAAA,MACjB,YAAYA,EAAI,CAAC;AAAA,MACjB,SAASA,EAAI,CAAC;AAAA,MACd,SAASA,EAAI,CAAC;AAAA,IACtB,IAGI,OAAO,OAAO,MAAM8K,GAAa,UAAU9K,CAAG,GACvC;AAAA,EACT;AAAA,EAEA,UAAU;AACR,UAAMzJ,IAAI;AAEV,WAAO;AAAA,MACLA,EAAE;AAAA,MACFA,EAAE;AAAA,MACFA,EAAE;AAAA,MACFA,EAAE;AAAA,MACFA,EAAE;AAAA,MACFA,EAAE;AAAA,MACFA,EAAE;AAAA,MACFA,EAAE;AAAA,IACR;AAAA,EACE;AACF;AAEAuU,GAAa,WAAW;AAAA,EACtB,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,SAAS;AACX;AAEA,MAAMC,KAAY,CAACzU,GAAGe,MACbf,EAAE,CAAC,IAAIe,EAAE,CAAC,IAAI,KAAKf,EAAE,CAAC,IAAIe,EAAE,CAAC,IAAI,IAAI;AAGvC,MAAMsT,GAAU;AAAA,EACrB,eAAehX,GAAM;AACnB,SAAK,KAAK,GAAGA,CAAI;AAAA,EACnB;AAAA,EAEA,MAAMwJ,GAAO;AACX,UAAMtE,IAAS,KAAK;AACpB,aAAS9I,IAAI,GAAGC,IAAK6I,EAAO,QAAQ9I,IAAIC,GAAI,EAAED,GAAG;AAE/C,UAAI8I,EAAO9I,IAAI,CAAC,MAAMoN,EAAMpN,IAAI,CAAC,GAAG;AAClC,YAAI8I,EAAO9I,IAAI,CAAC,MAAM4H,KAASwF,EAAMpN,IAAI,CAAC,MAAM8I,EAAO9I,IAAI,CAAC,GAAG;AAC7D,gBAAMoH,IAAQgG,EAAMpN,IAAI,CAAC,GACnB8H,IAAQ,IAAIF,EAAM,KAAK,OAAO,OAAO5H,IAAI,GAAG,CAAC,CAAC,EACjDoH,CAAK,EAAC,EACN,QAAO;AACV,eAAK,OAAO,OAAOpH,IAAI,GAAG,GAAG,GAAG8H,CAAK;AAAA,QACvC;AAEA,QAAA9H,KAAK8I,EAAO9I,IAAI,CAAC,IAAI;AACrB;AAAA,MACF;AAEA,UAAI,CAACoN,EAAMpN,IAAI,CAAC;AACd,eAAO;AAKT,YAAMib,IAAgB,IAAI7N,EAAMpN,IAAI,CAAC,EAAC,EAAG,QAAO,GAG1Ckb,IAAWpS,EAAO9I,IAAI,CAAC,IAAI;AAEjC,MAAA8I,EAAO;AAAA,QACL9I;AAAA,QACAkb;AAAA,QACA9N,EAAMpN,CAAC;AAAA,QACPoN,EAAMpN,IAAI,CAAC;AAAA,QACXoN,EAAMpN,IAAI,CAAC;AAAA,QACX,GAAGib;AAAA,MACX,GAEMjb,KAAK8I,EAAO9I,IAAI,CAAC,IAAI;AAAA,IACvB;AACA,WAAO;AAAA,EACT;AAAA,EAEA,KAAKmb,GAAU;AAGb,QAFA,KAAK,SAAS,CAAA,GAEV,MAAM,QAAQA,CAAQ,GAAG;AAC3B,WAAK,SAASA,EAAS,MAAK;AAC5B;AAAA,IACF;AAEA,IAAAA,IAAWA,KAAY,CAAA;AACvB,UAAMC,IAAU,CAAA;AAEhB,eAAWpb,KAAKmb,GAAU;AACxB,YAAME,IAAOZ,GAAgBU,EAASnb,CAAC,CAAC,GAClC+F,IAAM,IAAIsV,EAAKF,EAASnb,CAAC,CAAC,EAAE,QAAO;AACzC,MAAAob,EAAQ,KAAK,CAACpb,GAAGqb,GAAMtV,EAAI,QAAQ,GAAGA,CAAG,CAAC;AAAA,IAC5C;AAEA,WAAAqV,EAAQ,KAAKJ,EAAS,GAEtB,KAAK,SAASI,EAAQ,OAAO,CAAC9I,GAAMC,MAASD,EAAK,OAAOC,CAAI,GAAG,CAAA,CAAE,GAC3D;AAAA,EACT;AAAA,EAEA,UAAU;AACR,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,UAAU;AACR,UAAMtC,IAAM,CAAA,GACNH,IAAM,KAAK;AAGjB,WAAOA,EAAI,UAAQ;AACjB,YAAMhO,IAAMgO,EAAI,MAAK,GACfuL,IAAOvL,EAAI,MAAK,GAChBwL,IAAMxL,EAAI,MAAK,GACfhH,IAASgH,EAAI,OAAO,GAAGwL,CAAG;AAChC,MAAArL,EAAInO,CAAG,IAAI,IAAIuZ,EAAKvS,CAAM;AAAA,IAC5B;AAEA,WAAOmH;AAAA,EACT;AACF;AAEA,MAAM0K,KAAiB,CAACD,IAAcK,IAAcH,EAAS;AAEtD,SAASW,GAAsBlI,IAAO,IAAI;AAC/C,EAAAsH,GAAe,KAAK,GAAG,GAAG,OAAOtH,CAAI,CAAC;AACxC;AAEO,SAASmI,KAAgB;AAC9B,EAAAhY,EAAOmX,IAAgB;AAAA,IACrB,GAAG5U,GAAK;AACN,aAAO,IAAI8U,GAAS,EACjB,KAAK,KAAK,WAAW,EACrB,KAAK,KAAK,SAAS,EACnB,GAAG9U,CAAG;AAAA,IACX;AAAA,IACA,UAAU+J,GAAK;AACb,kBAAK,KAAKA,CAAG,GACN;AAAA,IACT;AAAA,IACA,eAAe;AACb,aAAO,KAAK,QAAO;AAAA,IACrB;AAAA,IACA,MAAM6F,GAAMC,GAAI2B,GAAKuD,GAASW,GAAS;AACrC,YAAMC,IAAS,SAAU1b,GAAGqV,GAAO;AACjC,eAAOyF,EAAQ,KAAK9a,GAAG4V,EAAGP,CAAK,GAAGkC,GAAKkE,EAAQpG,CAAK,GAAGoG,CAAO;AAAA,MAChE;AAEA,aAAO,KAAK,UAAU9F,EAAK,IAAI+F,CAAM,CAAC;AAAA,IACxC;AAAA,EACJ,CAAG;AACH;ACzUe,MAAMC,WAAapG,GAAM;AAAA;AAAA,EAEtC,YAAYxS,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,QAAQC,CAAI,GAAGmN,CAAK;AAAA,EACtC;AAAA;AAAA,EAGA,QAAQ;AACN,WAAO,KAAK,WAAW,KAAK,SAAS,IAAIsK,GAAU,KAAK,KAAK,GAAG,CAAC;AAAA,EACnE;AAAA;AAAA,EAGA,QAAQ;AACN,kBAAO,KAAK,QACL;AAAA,EACT;AAAA;AAAA,EAGA,OAAO3Z,GAAQ;AACb,WAAOA,KAAU,OACb,KAAK,KAAI,EAAG,SACZ,KAAK,KAAK,KAAK,KAAI,EAAG,OAAOA,CAAM;AAAA,EACzC;AAAA;AAAA,EAGA,KAAKS,GAAGC,GAAG;AACT,WAAO,KAAK,KAAK,KAAK,KAAK,QAAQ,KAAKD,GAAGC,CAAC,CAAC;AAAA,EAC/C;AAAA;AAAA,EAGA,KAAKlB,GAAG;AACN,WAAOA,KAAK,OACR,KAAK,MAAK,IACV,KAAK,MAAK,EAAG;AAAA,MACX;AAAA,MACA,OAAOA,KAAM,WAAWA,IAAK,KAAK,SAAS,IAAIma,GAAUna,CAAC;AAAA,IACpE;AAAA,EACE;AAAA;AAAA,EAGA,KAAKO,GAAOC,GAAQ;AAClB,UAAM6G,IAAIhH,GAAiB,MAAME,GAAOC,CAAM;AAC9C,WAAO,KAAK,KAAK,KAAK,KAAK,QAAQ,KAAK6G,EAAE,OAAOA,EAAE,MAAM,CAAC;AAAA,EAC5D;AAAA;AAAA,EAGA,MAAM9G,GAAO;AACX,WAAOA,KAAS,OACZ,KAAK,KAAI,EAAG,QACZ,KAAK,KAAKA,GAAO,KAAK,KAAI,EAAG,MAAM;AAAA,EACzC;AAAA;AAAA,EAGA,EAAEU,GAAG;AACH,WAAOA,KAAK,OAAO,KAAK,KAAI,EAAG,IAAI,KAAK,KAAKA,GAAG,KAAK,KAAI,EAAG,CAAC;AAAA,EAC/D;AAAA;AAAA,EAGA,EAAEC,GAAG;AACH,WAAOA,KAAK,OAAO,KAAK,KAAI,EAAG,IAAI,KAAK,KAAK,KAAK,KAAI,EAAG,GAAGA,CAAC;AAAA,EAC/D;AACF;AAGAoa,GAAK,UAAU,aAAanB;AAG5Bnb,EAAgB;AAAA,EACd,WAAW;AAAA;AAAA,IAET,MAAMqE,EAAkB,SAAUrD,GAAG;AAEnC,aAAO,KAAK,IAAI,IAAIsb,GAAI,CAAE,EAAE,KAAKtb,KAAK,IAAIma,GAAS,CAAE;AAAA,IACvD,CAAC;AAAA,EACL;AACA,CAAC;AAEDtX,EAASyY,IAAM,MAAM;AC/Ed,SAAS7b,KAAQ;AACtB,SAAO,KAAK,WAAW,KAAK,SAAS,IAAIuW,GAAW,KAAK,KAAK,QAAQ,CAAC;AACzE;AAGO,SAASuF,KAAQ;AACtB,gBAAO,KAAK,QACL;AACT;AAGO,SAASC,GAAKva,GAAGC,GAAG;AACzB,SAAO,KAAK,KAAK,UAAU,KAAK,QAAQ,KAAKD,GAAGC,CAAC,CAAC;AACpD;AAGO,SAASua,GAAKpU,GAAG;AACtB,SAAOA,KAAK,OACR,KAAK,MAAK,IACV,KAAK,MAAK,EAAG;AAAA,IACX;AAAA,IACA,OAAOA,KAAM,WAAWA,IAAK,KAAK,SAAS,IAAI2O,GAAW3O,CAAC;AAAA,EACnE;AACA;AAGO,SAASqU,GAAKnb,GAAOC,GAAQ;AAClC,QAAM6G,IAAIhH,GAAiB,MAAME,GAAOC,CAAM;AAC9C,SAAO,KAAK,KAAK,UAAU,KAAK,QAAQ,KAAK6G,EAAE,OAAOA,EAAE,MAAM,CAAC;AACjE;;;;;;;;;ACrBe,MAAMsU,WAAgBzG,GAAM;AAAA;AAAA,EAEzC,YAAYxS,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,WAAWC,CAAI,GAAGmN,CAAK;AAAA,EACzC;AACF;AAEA7Q,EAAgB;AAAA,EACd,WAAW;AAAA;AAAA,IAET,SAASqE,EAAkB,SAAUgE,GAAG;AAEtC,aAAO,KAAK,IAAI,IAAIsU,GAAO,CAAE,EAAE,KAAKtU,KAAK,IAAI2O,GAAU,CAAE;AAAA,IAC3D,CAAC;AAAA,EACL;AACA,CAAC;AAED7S,EAAOwY,IAAS/E,EAAO;AACvBzT,EAAOwY,IAASC,EAAI;AACpB/Y,EAAS8Y,IAAS,SAAS;ACnBZ,MAAME,WAAiB3G,GAAM;AAAA;AAAA,EAE1C,YAAYxS,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,YAAYC,CAAI,GAAGmN,CAAK;AAAA,EAC1C;AACF;AAEA7Q,EAAgB;AAAA,EACd,WAAW;AAAA;AAAA,IAET,UAAUqE,EAAkB,SAAUgE,GAAG;AAEvC,aAAO,KAAK,IAAI,IAAIwU,GAAQ,CAAE,EAAE,KAAKxU,KAAK,IAAI2O,GAAU,CAAE;AAAA,IAC5D,CAAC;AAAA,EACL;AACA,CAAC;AAED7S,EAAO0Y,IAAUjF,EAAO;AACxBzT,EAAO0Y,IAAUD,EAAI;AACrB/Y,EAASgZ,IAAU,UAAU;ACrBd,MAAMC,WAAa5G,GAAM;AAAA;AAAA,EAEtC,YAAYxS,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,QAAQC,CAAI,GAAGmN,CAAK;AAAA,EACtC;AACF;AAEA1M,EAAO2Y,IAAM,EAAE,IAAA/P,IAAI,IAAAC,GAAE,CAAE;AAEvBhN,EAAgB;AAAA,EACd,WAAW;AAAA;AAAA,IAET,MAAMqE,EAAkB,SAAU9C,GAAOC,GAAQ;AAC/C,aAAO,KAAK,IAAI,IAAIsb,GAAI,CAAE,EAAE,KAAKvb,GAAOC,CAAM;AAAA,IAChD,CAAC;AAAA,EACL;AACA,CAAC;AAEDqC,EAASiZ,IAAM,MAAM;AC5BN,MAAMC,GAAM;AAAA,EACzB,cAAc;AACZ,SAAK,SAAS,MACd,KAAK,QAAQ;AAAA,EACf;AAAA;AAAA,EAGA,QAAQ;AACN,WAAO,KAAK,UAAU,KAAK,OAAO;AAAA,EACpC;AAAA;AAAA,EAGA,OAAO;AACL,WAAO,KAAK,SAAS,KAAK,MAAM;AAAA,EAClC;AAAA,EAEA,KAAKlK,GAAO;AAEV,UAAMmK,IACJ,OAAOnK,EAAM,OAAS,MAClBA,IACA,EAAE,OAAOA,GAAO,MAAM,MAAM,MAAM,KAAI;AAG5C,WAAI,KAAK,SACPmK,EAAK,OAAO,KAAK,OACjB,KAAK,MAAM,OAAOA,GAClB,KAAK,QAAQA,MAEb,KAAK,QAAQA,GACb,KAAK,SAASA,IAITA;AAAA,EACT;AAAA;AAAA,EAGA,OAAOA,GAAM;AAEX,IAAIA,EAAK,SAAMA,EAAK,KAAK,OAAOA,EAAK,OACjCA,EAAK,SAAMA,EAAK,KAAK,OAAOA,EAAK,OACjCA,MAAS,KAAK,UAAO,KAAK,QAAQA,EAAK,OACvCA,MAAS,KAAK,WAAQ,KAAK,SAASA,EAAK,OAG7CA,EAAK,OAAO,MACZA,EAAK,OAAO;AAAA,EACd;AAAA,EAEA,QAAQ;AAEN,UAAMC,IAAS,KAAK;AACpB,WAAKA,KAGL,KAAK,SAASA,EAAO,MACjB,KAAK,WAAQ,KAAK,OAAO,OAAO,OACpC,KAAK,QAAQ,KAAK,SAAS,KAAK,QAAQ,MACjCA,EAAO,SANM;AAAA,EAOtB;AACF;AC1DA,MAAMC,IAAW;AAAA,EACf,UAAU;AAAA,EACV,QAAQ,IAAIH,GAAK;AAAA,EACjB,UAAU,IAAIA,GAAK;AAAA,EACnB,YAAY,IAAIA,GAAK;AAAA,EACrB,OAAO,MAAMja,EAAQ,OAAO,eAAeA,EAAQ,OAAO;AAAA,EAC1D,YAAY,CAAA;AAAA,EAEZ,MAAMwB,GAAI;AAER,UAAMZ,IAAOwZ,EAAS,OAAO,KAAK,EAAE,KAAK5Y,EAAE,CAAE;AAG7C,WAAI4Y,EAAS,aAAa,SACxBA,EAAS,WAAWpa,EAAQ,OAAO,sBAAsBoa,EAAS,KAAK,IAIlExZ;AAAA,EACT;AAAA,EAEA,QAAQY,GAAI6Y,GAAO;AACjB,IAAAA,IAAQA,KAAS;AAGjB,UAAMC,IAAOF,EAAS,MAAK,EAAG,IAAG,IAAKC,GAGhCzZ,IAAOwZ,EAAS,SAAS,KAAK,EAAE,KAAK5Y,GAAI,MAAM8Y,EAAI,CAAE;AAG3D,WAAIF,EAAS,aAAa,SACxBA,EAAS,WAAWpa,EAAQ,OAAO,sBAAsBoa,EAAS,KAAK,IAGlExZ;AAAA,EACT;AAAA,EAEA,UAAUY,GAAI;AAEZ,UAAMZ,IAAOwZ,EAAS,WAAW,KAAK5Y,CAAE;AAExC,WAAI4Y,EAAS,aAAa,SACxBA,EAAS,WAAWpa,EAAQ,OAAO,sBAAsBoa,EAAS,KAAK,IAGlExZ;AAAA,EACT;AAAA,EAEA,YAAYA,GAAM;AAChB,IAAAA,KAAQ,QAAQwZ,EAAS,OAAO,OAAOxZ,CAAI;AAAA,EAC7C;AAAA,EAEA,aAAaA,GAAM;AACjB,IAAAA,KAAQ,QAAQwZ,EAAS,SAAS,OAAOxZ,CAAI;AAAA,EAC/C;AAAA,EAEA,gBAAgBA,GAAM;AACpB,IAAAA,KAAQ,QAAQwZ,EAAS,WAAW,OAAOxZ,CAAI;AAAA,EACjD;AAAA,EAEA,MAAM2Z,GAAK;AAGT,QAAIC,IAAc;AAClB,UAAMC,IAAcL,EAAS,SAAS,KAAI;AAC1C,YAAQI,IAAcJ,EAAS,SAAS,MAAK,OAEvCG,KAAOC,EAAY,OACrBA,EAAY,IAAG,IAEfJ,EAAS,SAAS,KAAKI,CAAW,GAIhCA,MAAgBC;AAApB;AAIF,QAAIC,IAAY;AAChB,UAAMC,IAAYP,EAAS,OAAO,KAAI;AACtC,WAAOM,MAAcC,MAAcD,IAAYN,EAAS,OAAO,MAAK;AAClE,MAAAM,EAAU,IAAIH,CAAG;AAGnB,QAAIK,IAAgB;AACpB,WAAQA,IAAgBR,EAAS,WAAW,MAAK;AAC/C,MAAAQ,EAAa;AAIf,IAAAR,EAAS,WACPA,EAAS,SAAS,MAAK,KAAMA,EAAS,OAAO,MAAK,IAC9Cpa,EAAQ,OAAO,sBAAsBoa,EAAS,KAAK,IACnD;AAAA,EACR;AACF,GC9FMS,KAAe,SAAUC,GAAY;AACzC,QAAMC,IAAQD,EAAW,OACnB7E,IAAW6E,EAAW,OAAO,SAAQ,GACrCE,IAAMD,IAAQ9E;AACpB,SAAO;AAAA,IACL,OAAO8E;AAAA,IACP,UAAU9E;AAAA,IACV,KAAK+E;AAAA,IACL,QAAQF,EAAW;AAAA,EACvB;AACA,GAEMG,KAAgB,WAAY;AAChC,QAAMC,IAAIlb,EAAQ;AAClB,UAAQkb,EAAE,eAAeA,EAAE,MAAM,IAAG;AACtC;AAEe,MAAMC,WAAiB5L,GAAY;AAAA;AAAA,EAEhD,YAAY6L,IAAaH,IAAe;AACtC,UAAK,GAEL,KAAK,cAAcG,GAGnB,KAAK,UAAS;AAAA,EAChB;AAAA,EAEA,SAAS;AACP,WAAO,CAAC,CAAC,KAAK;AAAA,EAChB;AAAA,EAEA,SAAS;AAEP,gBAAK,KAAK,KAAK,qBAAoB,IAAK,CAAC,GAClC,KAAK,MAAK;AAAA,EACnB;AAAA;AAAA,EAGA,aAAa;AACX,UAAMC,IAAiB,KAAK,kBAAiB,GACvCC,IAAeD,IAAiBA,EAAe,OAAO,SAAQ,IAAK;AAEzE,YADsBA,IAAiBA,EAAe,QAAQ,KAAK,SAC5CC;AAAA,EACzB;AAAA,EAEA,uBAAuB;AACrB,UAAMC,IAAW,KAAK,SAAS,IAAI,CAAC1d,MAAMA,EAAE,QAAQA,EAAE,OAAO,SAAQ,CAAE;AACvE,WAAO,KAAK,IAAI,GAAG,GAAG0d,CAAQ;AAAA,EAChC;AAAA,EAEA,oBAAoB;AAClB,WAAO,KAAK,kBAAkB,KAAK,aAAa;AAAA,EAClD;AAAA,EAEA,kBAAkBxK,GAAI;AACpB,WAAO,KAAK,SAAS,KAAK,WAAW,QAAQA,CAAE,CAAC,KAAK;AAAA,EACvD;AAAA,EAEA,QAAQ;AACN,gBAAK,UAAU,IACR,KAAK,UAAS;AAAA,EACvB;AAAA,EAEA,QAAQyK,GAAa;AACnB,WAAIA,KAAe,OAAa,KAAK,YACrC,KAAK,WAAWA,GACT;AAAA,EACT;AAAA,EAEA,OAAO;AAEL,gBAAK,UAAU,IACR,KAAK,WAAU,EAAG,UAAS;AAAA,EACpC;AAAA,EAEA,QAAQC,GAAK;AACX,UAAMC,IAAe,KAAK,MAAK;AAC/B,QAAID,KAAO,KAAM,QAAO,KAAK,MAAM,CAACC,CAAY;AAEhD,UAAMC,IAAW,KAAK,IAAID,CAAY;AACtC,WAAO,KAAK,MAAMD,IAAM,CAACE,IAAWA,CAAQ;AAAA,EAC9C;AAAA;AAAA,EAGA,SAASC,GAAQvB,GAAOwB,GAAM;AAC5B,QAAID,KAAU;AACZ,aAAO,KAAK,SAAS,IAAIf,EAAY;AAOvC,QAAIiB,IAAoB;AACxB,UAAMC,IAAU,KAAK,WAAU;AAI/B,QAHA1B,IAAQA,KAAS,GAGbwB,KAAQ,QAAQA,MAAS,UAAUA,MAAS;AAE9C,MAAAC,IAAoBC;AAAA,aACXF,MAAS,cAAcA,MAAS;AACzC,MAAAC,IAAoBzB,GACpBA,IAAQ;AAAA,aACCwB,MAAS;AAClB,MAAAC,IAAoB,KAAK;AAAA,aAChBD,MAAS,YAAY;AAC9B,YAAMf,IAAa,KAAK,kBAAkBc,EAAO,EAAE;AACnD,MAAId,MACFgB,IAAoBhB,EAAW,QAAQT,GACvCA,IAAQ;AAAA,IAEZ,WAAWwB,MAAS,aAAa;AAC/B,YAAMR,IAAiB,KAAK,kBAAiB;AAE7C,MAAAS,IADsBT,IAAiBA,EAAe,QAAQ,KAAK;AAAA,IAErE;AACE,YAAM,IAAI,MAAM,wCAAwC;AAI1D,IAAAO,EAAO,WAAU,GACjBA,EAAO,SAAS,IAAI;AAEpB,UAAMI,IAAUJ,EAAO,QAAO,GACxBd,IAAa;AAAA,MACjB,SAASkB,MAAY,OAAO,KAAK,WAAWA;AAAA,MAC5C,OAAOF,IAAoBzB;AAAA,MAC3B,QAAAuB;AAAA,IACN;AAEI,gBAAK,gBAAgBA,EAAO,IAE5B,KAAK,SAAS,KAAKd,CAAU,GAC7B,KAAK,SAAS,KAAK,CAAC1W,GAAGe,MAAMf,EAAE,QAAQe,EAAE,KAAK,GAC9C,KAAK,aAAa,KAAK,SAAS,IAAI,CAAC8W,MAASA,EAAK,OAAO,EAAE,GAE5D,KAAK,WAAU,EAAG,UAAS,GACpB;AAAA,EACT;AAAA,EAEA,KAAKlG,GAAI;AACP,WAAO,KAAK,KAAK,KAAK,QAAQA,CAAE;AAAA,EAClC;AAAA,EAEA,OAAOvU,GAAI;AACT,WAAIA,KAAM,OAAa,KAAK,eAC5B,KAAK,cAAcA,GACZ;AAAA,EACT;AAAA,EAEA,MAAM0a,GAAO;AACX,WAAIA,KAAS,OAAa,KAAK,UAC/B,KAAK,SAASA,GACP;AAAA,EACT;AAAA,EAEA,OAAO;AAEL,gBAAK,KAAK,CAAC,GACJ,KAAK,MAAK;AAAA,EACnB;AAAA,EAEA,KAAK5B,GAAM;AACT,WAAIA,KAAQ,OAAa,KAAK,SAC9B,KAAK,QAAQA,GACN,KAAK,UAAU,EAAI;AAAA,EAC5B;AAAA;AAAA,EAGA,WAAWsB,GAAQ;AACjB,UAAM1I,IAAQ,KAAK,WAAW,QAAQ0I,EAAO,EAAE;AAC/C,WAAI1I,IAAQ,IAAU,QAEtB,KAAK,SAAS,OAAOA,GAAO,CAAC,GAC7B,KAAK,WAAW,OAAOA,GAAO,CAAC,GAE/B0I,EAAO,SAAS,IAAI,GACb;AAAA,EACT;AAAA;AAAA,EAGA,aAAa;AACX,WAAK,KAAK,aACR,KAAK,kBAAkB,KAAK,YAAW,IAElC;AAAA,EACT;AAAA;AAAA,EAGA,UAAUO,IAAgB,IAAO;AAI/B,WAHA/B,EAAS,YAAY,KAAK,UAAU,GACpC,KAAK,aAAa,MAEd+B,IAAsB,KAAK,eAAc,IACzC,KAAK,UAAgB,QAEzB,KAAK,aAAa/B,EAAS,MAAM,KAAK,KAAK,GACpC;AAAA,EACT;AAAA,EAEA,QAAQ+B,IAAgB,IAAO;AAE7B,UAAM7B,IAAO,KAAK,YAAW;AAC7B,QAAI8B,IAAW9B,IAAO,KAAK;AAE3B,IAAI6B,MAAeC,IAAW;AAE9B,UAAMC,IAAS,KAAK,SAASD,KAAY,KAAK,QAAQ,KAAK;AAC3D,SAAK,kBAAkB9B,GAIlB6B,MAEH,KAAK,SAASE,GACd,KAAK,QAAQ,KAAK,QAAQ,IAAI,IAAI,KAAK,QAEzC,KAAK,gBAAgB,KAAK,OAC1B,KAAK,KAAK,QAAQ,KAAK,KAAK;AAa5B,aAAS7X,IAAI,KAAK,SAAS,QAAQA,OAAO;AAExC,YAAMsW,IAAa,KAAK,SAAStW,CAAC,GAC5BoX,IAASd,EAAW;AAQ1B,MAJkB,KAAK,QAAQA,EAAW,SAIzB,KACfc,EAAO,MAAK;AAAA,IAEhB;AAGA,QAAIU,IAAc;AAClB,aAASze,IAAI,GAAGgU,IAAM,KAAK,SAAS,QAAQhU,IAAIgU,GAAKhU,KAAK;AAExD,YAAMid,IAAa,KAAK,SAASjd,CAAC,GAC5B+d,IAASd,EAAW;AAC1B,UAAI/E,IAAKsG;AAIT,YAAME,IAAY,KAAK,QAAQzB,EAAW;AAG1C,UAAIyB,KAAa,GAAG;AAClB,QAAAD,IAAc;AACd;AAAA,MACF,MAAO,CAAIC,IAAYxG,MAErBA,IAAKwG;AAGP,UAAI,CAACX,EAAO,SAAU;AAKtB,MADiBA,EAAO,KAAK7F,CAAE,EAAE,OAItB+E,EAAW,YAAY,MAEhBc,EAAO,SAAQ,IAAKA,EAAO,KAAI,IAAK,KAAK,QAE3Cd,EAAW,UAAU,KAAK,UAEtCc,EAAO,WAAU,GACjB,EAAE/d,GACF,EAAEgU,KAVJyK,IAAc;AAAA,IAalB;AAIA,WACGA,KAAe,EAAE,KAAK,SAAS,KAAK,KAAK,UAAU,MACnD,KAAK,WAAW,UAAU,KAAK,SAAS,KAAK,KAAK,QAAQ,IAE3D,KAAK,UAAS,KAEd,KAAK,MAAK,GACV,KAAK,KAAK,UAAU,IAGf;AAAA,EACT;AAAA,EAEA,YAAY;AAIV,SAAK,aAAa,GAClB,KAAK,SAAS,GAGd,KAAK,WAAW,GAGhB,KAAK,aAAa,MAClB,KAAK,UAAU,IACf,KAAK,WAAW,CAAA,GAChB,KAAK,aAAa,CAAA,GAClB,KAAK,gBAAgB,IACrB,KAAK,QAAQ,GACb,KAAK,kBAAkB,GACvB,KAAK,gBAAgB,GAGrB,KAAK,QAAQ,KAAK,QAAQ,KAAK,MAAM,EAAK,GAC1C,KAAK,iBAAiB,KAAK,QAAQ,KAAK,MAAM,EAAI;AAAA,EACpD;AACF;AAEApf,EAAgB;AAAA,EACd,SAAS;AAAA,IACP,UAAU,SAAUwS,GAAU;AAC5B,aAAIA,KAAY,QACd,KAAK,YAAY,KAAK,aAAa,IAAIyL,GAAQ,GACxC,KAAK,cAEZ,KAAK,YAAYzL,GACV;AAAA,IAEX;AAAA,EACJ;AACA,CAAC;AC7Uc,MAAM8M,WAAejN,GAAY;AAAA,EAC9C,YAAYP,GAAS;AACnB,UAAK,GAGL,KAAK,KAAKwN,GAAO,MAGjBxN,IAAUA,KAAkBU,GAAS,UAGrCV,IAAU,OAAOA,KAAY,aAAa,IAAI6G,GAAW7G,CAAO,IAAIA,GAGpE,KAAK,WAAW,MAChB,KAAK,YAAY,MACjB,KAAK,OAAO,IACZ,KAAK,SAAS,CAAA,GAGd,KAAK,YAAY,OAAOA,KAAY,YAAYA,GAChD,KAAK,iBAAiBA,aAAmB6G,IACzC,KAAK,WAAW,KAAK,iBAAiB7G,IAAU,IAAI4G,GAAI,GAGxD,KAAK,WAAW,CAAA,GAGhB,KAAK,UAAU,IACf,KAAK,QAAQ,GACb,KAAK,YAAY,GAGjB,KAAK,WAAW,IAGhB,KAAK,aAAa,IAAI/M,EAAM,GAC5B,KAAK,cAAc,GAGnB,KAAK,gBAAgB,IACrB,KAAK,WAAW,IAChB,KAAK,aAAa,GAClB,KAAK,SAAS,IACd,KAAK,QAAQ,GACb,KAAK,SAAS,GAEd,KAAK,WAAW,MAGhB,KAAK,WAAW,KAAK,iBAAiB,KAAO;AAAA,EAC/C;AAAA,EAEA,OAAO,SAASoN,GAAUoE,GAAOwB,GAAM;AAErC,QAAIY,IAAQ,GACRC,IAAQ,IACRC,IAAO;AACX,WAAA1G,IAAWA,KAAYvG,GAAS,UAChC2K,IAAQA,KAAS3K,GAAS,OAC1BmM,IAAOA,KAAQ,QAGX,OAAO5F,KAAa,YAAY,EAAEA,aAAoBN,QACxD0E,IAAQpE,EAAS,SAASoE,GAC1BwB,IAAO5F,EAAS,QAAQ4F,GACxBa,IAAQzG,EAAS,SAASyG,GAC1BD,IAAQxG,EAAS,SAASwG,GAC1BE,IAAO1G,EAAS,QAAQ0G,GACxB1G,IAAWA,EAAS,YAAYvG,GAAS,WAGpC;AAAA,MACL,UAAUuG;AAAA,MACV,OAAOoE;AAAA,MACP,OAAOqC;AAAA,MACP,OAAOD;AAAA,MACP,MAAME;AAAA,MACN,MAAMd;AAAA,IACZ;AAAA,EACE;AAAA,EAEA,OAAOe,GAAS;AACd,WAAIA,KAAW,OAAa,KAAK,WACjC,KAAK,UAAUA,GACR;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAajK,GAAW;AACtB,gBAAK,WAAW,WAAWA,CAAS,GAC7B;AAAA,EACT;AAAA,EAEA,MAAMnR,GAAI;AACR,WAAO,KAAK,GAAG,YAAYA,CAAE;AAAA,EAC/B;AAAA,EAEA,QAAQyU,GAAUoE,GAAOwB,GAAM;AAC7B,UAAMhd,IAAI2d,GAAO,SAASvG,GAAUoE,GAAOwB,CAAI,GACzCD,IAAS,IAAIY,GAAO3d,EAAE,QAAQ;AACpC,WAAI,KAAK,aAAW+c,EAAO,SAAS,KAAK,SAAS,GAC9C,KAAK,YAAUA,EAAO,QAAQ,KAAK,QAAQ,GACxCA,EAAO,KAAK/c,CAAC,EAAE,SAASA,EAAE,OAAOA,EAAE,IAAI;AAAA,EAChD;AAAA,EAEA,iBAAiB;AACf,gBAAK,aAAa,IAAIgK,EAAM,GACrB;AAAA,EACT;AAAA;AAAA,EAGA,2BAA2B;AACzB,KACE,CAAC,KAAK,QACN,CAAC,KAAK,aACN,CAAC,KAAK,UAAU,WAAW,SAAS,KAAK,EAAE,OAE3C,KAAK,SAAS,KAAK,OAAO,OAAO,CAACqR,MACzB,CAACA,EAAK,WACd;AAAA,EAEL;AAAA,EAEA,MAAMG,GAAO;AACX,WAAO,KAAK,QAAQ,GAAGA,CAAK;AAAA,EAC9B;AAAA,EAEA,WAAW;AACT,WAAO,KAAK,UAAU,KAAK,QAAQ,KAAK,aAAa,KAAK;AAAA,EAC5D;AAAA,EAEA,OAAO7Y,GAAI;AACT,WAAO,KAAK,MAAM,MAAMA,CAAE;AAAA,EAC5B;AAAA,EAEA,KAAKA,GAAI;AACP,gBAAK,WAAW,IAAIoU,GAAKpU,CAAE,GACpB;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAQhD,GAAS;AACf,WAAIA,KAAW,OAAa,KAAK,YACjC,KAAK,WAAWA,GAChBA,EAAQ,eAAc,GACf;AAAA,EACT;AAAA,EAEA,SAAS;AACP,WAAO,KAAK,KAAK,KAAQ;AAAA,EAC3B;AAAA,EAEA,KAAKie,GAAOC,GAAOC,GAAM;AAEvB,WAAI,OAAOF,KAAU,aACnBC,IAAQD,EAAM,OACdE,IAAOF,EAAM,MACbA,IAAQA,EAAM,QAIhB,KAAK,SAASA,KAAS,OACvB,KAAK,SAASC,KAAS,IACvB,KAAK,QAAQC,KAAQ,GAGjB,KAAK,WAAW,OAClB,KAAK,SAAS,QAGT;AAAA,EACT;AAAA,EAEA,MAAMpX,GAAG;AACP,UAAMsX,IAAe,KAAK,YAAY,KAAK;AAC3C,QAAItX,KAAK,MAAM;AACb,YAAMuX,IAAY,KAAK,MAAM,KAAK,QAAQD,CAAY,GAEhDlb,KADe,KAAK,QAAQmb,IAAYD,KACd,KAAK;AACrC,aAAO,KAAK,IAAIC,IAAYnb,GAAU,KAAK,MAAM;AAAA,IACnD;AACA,UAAMob,IAAQ,KAAK,MAAMxX,CAAC,GACpByX,IAAUzX,IAAI,GACd+U,IAAOuC,IAAeE,IAAQ,KAAK,YAAYC;AACrD,WAAO,KAAK,KAAK1C,CAAI;AAAA,EACvB;AAAA,EAEA,QAAQkB,GAAa;AACnB,WAAIA,KAAe,OAAa,KAAK,YACrC,KAAK,WAAWA,GACT;AAAA,EACT;AAAA,EAEA,SAASjW,GAAG;AAEV,UAAMpG,IAAI,KAAK,OACTjB,IAAI,KAAK,WACTgd,IAAI,KAAK,OACTnX,IAAI,KAAK,QACT3F,IAAI,KAAK,QACTkG,IAAI,KAAK;AACf,QAAI3C;AAEJ,QAAI4D,KAAK,MAAM;AASb,YAAM6E,IAAI,SAAUjL,GAAG;AACrB,cAAM8d,IAAW7e,IAAI,KAAK,MAAOe,KAAK,KAAK+b,IAAIhd,OAAQgd,IAAIhd,EAAE,GACvDgf,IAAaD,KAAY,CAAC3Y,KAAO,CAAC2Y,KAAY3Y,GAC9C6Y,IACH,KAAK,IAAI,IAAID,CAAS,KAAK/d,KAAK+b,IAAIhd,MAAOA,IAAIgf;AAElD,eADgB,KAAK,IAAI,KAAK,IAAIC,GAAU,CAAC,GAAG,CAAC;AAAA,MAEnD,GAGMpB,IAAUhY,KAAKmX,IAAIhd,KAAKgd;AAC9B,aAAAvZ,IACExC,KAAK,IACD,KAAK,MAAMiL,EAAE,IAAI,CAAC,IAClBjL,IAAI4c,IACF3R,EAAEjL,CAAC,IACH,KAAK,MAAMiL,EAAE2R,IAAU,IAAI,CAAC,GAC7Bpa;AAAA,IACT;AAGA,UAAMmb,IAAY,KAAK,MAAM,KAAK,MAAK,CAAE,GACnCM,IAAehf,KAAK0e,IAAY,MAAM;AAE5C,WAAAnb,IAAWmb,KADOM,KAAgB,CAAC9Y,KAAOA,KAAK8Y,IACZ7X,IAAI,IAAIA,IACpC,KAAK,MAAM5D,CAAQ;AAAA,EAC5B;AAAA,EAEA,SAAS4D,GAAG;AACV,WAAIA,KAAK,OACA,KAAK,IAAI,GAAG,KAAK,QAAQ,KAAK,SAAQ,CAAE,IAE1C,KAAK,KAAKA,IAAI,KAAK,SAAQ,CAAE;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM8X,GAAQC,GAAOC,GAAYC,GAAa;AAC5C,gBAAK,OAAO,KAAK;AAAA,MACf,aAAaH,KAAU5N;AAAA,MACvB,QAAQ6N,KAAS7N;AAAA,MACjB,UAAU8N;AAAA,MACV,aAAaC;AAAA,MACb,aAAa;AAAA,MACb,UAAU;AAAA,IAChB,CAAK,GACgB,KAAK,SAAQ,KAClB,KAAK,SAAQ,EAAG,UAAS,GAC9B;AAAA,EACT;AAAA,EAEA,QAAQ;AACN,WAAI,KAAK,WAAiB,QAC1B,KAAK,KAAK,CAAC,GACX,KAAK,WAAW,IACT;AAAA,EACT;AAAA,EAEA,QAAQC,GAAS;AACf,gBAAK,WAAWA,KAAkB,CAAC,KAAK,UACjC;AAAA,EACT;AAAA,EAEA,SAAS/N,GAAU2K,GAAOwB,GAAM;AAS9B,QAPMnM,aAAoByL,OACxBU,IAAOxB,GACPA,IAAQ3K,GACRA,IAAW,KAAK,SAAQ,IAItB,CAACA;AACH,YAAM,MAAM,6CAA6C;AAI3D,WAAAA,EAAS,SAAS,MAAM2K,GAAOwB,CAAI,GAC5B;AAAA,EACT;AAAA,EAEA,KAAK9F,GAAI;AAEP,QAAI,CAAC,KAAK,QAAS,QAAO;AAG1B,IAAAA,IAAKA,KAAa,IAClB,KAAK,SAASA;AACd,UAAMpU,IAAW,KAAK,SAAQ,GAGxB+b,IAAU,KAAK,kBAAkB/b,KAAY,KAAK,SAAS;AACjE,SAAK,gBAAgBA;AAGrB,UAAMsU,IAAW,KAAK,SAAQ,GACxB0H,IAAc,KAAK,aAAa,KAAK,KAAK,QAAQ,GAClDC,IAAe,KAAK,YAAY3H,KAAY,KAAK,SAASA;AAEhE,SAAK,YAAY,KAAK,OAClB0H,KACF,KAAK,KAAK,SAAS,IAAI;AAMzB,UAAME,IAAc,KAAK;AACzB,SAAK,OAAO,CAACA,KAAe,CAACD,KAAgB,KAAK,SAAS3H,GAG3D,KAAK,WAAW;AAEhB,QAAI6H,IAAY;AAEhB,YAAIJ,KAAWG,OACb,KAAK,YAAYH,CAAO,GAGxB,KAAK,aAAa,IAAI7U,EAAM,GAC5BiV,IAAY,KAAK,KAAKD,IAAc9H,IAAKpU,CAAQ,GAEjD,KAAK,KAAK,QAAQ,IAAI,IAIxB,KAAK,OAAO,KAAK,QAASmc,KAAaD,GACnCD,KACF,KAAK,KAAK,YAAY,IAAI,GAErB;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,KAAKtD,GAAM;AACT,QAAIA,KAAQ;AACV,aAAO,KAAK;AAEd,UAAMvE,IAAKuE,IAAO,KAAK;AACvB,gBAAK,KAAKvE,CAAE,GACL;AAAA,EACT;AAAA,EAEA,SAASrG,GAAU;AAEjB,WAAI,OAAOA,IAAa,MAAoB,KAAK,aACjD,KAAK,YAAYA,GACV;AAAA,EACT;AAAA,EAEA,aAAa;AACX,UAAMA,IAAW,KAAK,SAAQ;AAC9B,WAAAA,KAAYA,EAAS,WAAW,IAAI,GAC7B;AAAA,EACT;AAAA;AAAA,EAGA,YAAYgO,GAAS;AAEnB,QAAI,GAACA,KAAW,CAAC,KAAK;AAGtB,eAAS7f,IAAI,GAAGgU,IAAM,KAAK,OAAO,QAAQhU,IAAIgU,GAAK,EAAEhU,GAAG;AAEtD,cAAMmO,IAAU,KAAK,OAAOnO,CAAC,GAGvBkgB,IAAU,KAAK,kBAAmB,CAAC/R,EAAQ,eAAe0R;AAChE,QAAAA,IAAU,CAAC1R,EAAQ,UAGf+R,KAAWL,MACb1R,EAAQ,YAAY,KAAK,IAAI,GAC7BA,EAAQ,cAAc;AAAA,MAE1B;AAAA,EACF;AAAA;AAAA,EAGA,iBAAiBgS,GAAQC,GAAS;AAYhC,QAXA,KAAK,SAASD,CAAM,IAAI;AAAA,MACtB,SAASC;AAAA,MACT,QAAQ,KAAK,OAAO,KAAK,OAAO,SAAS,CAAC;AAAA,IAChD,GAQQ,KAAK,gBAAgB;AACvB,YAAMvO,IAAW,KAAK,SAAQ;AAC9B,MAAAA,KAAYA,EAAS,KAAI;AAAA,IAC3B;AAAA,EACF;AAAA;AAAA;AAAA,EAIA,KAAKwO,GAAc;AAEjB,QAAIC,IAAc;AAClB,aAAStgB,IAAI,GAAGgU,IAAM,KAAK,OAAO,QAAQhU,IAAIgU,GAAK,EAAEhU,GAAG;AAEtD,YAAMmO,IAAU,KAAK,OAAOnO,CAAC,GAIvBigB,IAAY9R,EAAQ,OAAO,KAAK,MAAMkS,CAAY;AACxD,MAAAlS,EAAQ,WAAWA,EAAQ,YAAY8R,MAAc,IACrDK,IAAcA,KAAenS,EAAQ;AAAA,IACvC;AAGA,WAAOmS;AAAA,EACT;AAAA;AAAA,EAGA,aAAaH,GAAQlI,GAAQsI,GAAO;AAClC,QAAI,KAAK,SAASJ,CAAM,GAAG;AAEzB,UAAI,CAAC,KAAK,SAASA,CAAM,EAAE,OAAO,aAAa;AAC7C,cAAM9K,IAAQ,KAAK,OAAO,QAAQ,KAAK,SAAS8K,CAAM,EAAE,MAAM;AAC9D,oBAAK,OAAO,OAAO9K,GAAO,CAAC,GACpB;AAAA,MACT;AAIA,MAAI,KAAK,SAAS8K,CAAM,EAAE,OAAO,WAC/B,KAAK,SAASA,CAAM,EAAE,OAAO,SAAS,KAAK,MAAMlI,GAAQsI,CAAK,IAG9D,KAAK,SAASJ,CAAM,EAAE,QAAQ,GAAGlI,CAAM,GAGzC,KAAK,SAASkI,CAAM,EAAE,OAAO,WAAW;AACxC,YAAMtO,IAAW,KAAK,SAAQ;AAC9B,aAAAA,KAAYA,EAAS,KAAI,GAClB;AAAA,IACT;AACA,WAAO;AAAA,EACT;AACF;AAEA8M,GAAO,KAAK;AAEL,MAAM6B,GAAW;AAAA,EACtB,YAAY3b,IAAa,IAAImG,EAAM,GAAIkI,IAAK,IAAIuN,IAAO,IAAM;AAC3D,SAAK,aAAa5b,GAClB,KAAK,KAAKqO,GACV,KAAK,OAAOuN;AAAA,EACd;AAAA,EAEA,2BAA2B;AAAA,EAAC;AAC9B;AAEAjd,EAAO,CAACmb,IAAQ6B,EAAU,GAAG;AAAA,EAC3B,UAAUzC,GAAQ;AAChB,WAAO,IAAIyC;AAAA,MACTzC,EAAO,WAAW,UAAU,KAAK,UAAU;AAAA,MAC3CA,EAAO;AAAA,IACb;AAAA,EACE;AACF,CAAC;AAID,MAAM2C,KAAY,CAACpO,GAAMC,MAASD,EAAK,WAAWC,CAAI,GAChDoO,KAAqB,CAAC5C,MAAWA,EAAO;AAE9C,SAAS6C,KAAkB;AAGzB,QAAMC,IADU,KAAK,uBAAuB,QAEzC,IAAIF,EAAkB,EACtB,OAAOD,IAAW,IAAI1V,EAAM,CAAE;AAEjC,OAAK,UAAU6V,CAAY,GAE3B,KAAK,uBAAuB,MAAK,GAE7B,KAAK,uBAAuB,OAAM,MAAO,MAC3C,KAAK,WAAW;AAEpB;AAEO,MAAMC,GAAY;AAAA,EACvB,cAAc;AACZ,SAAK,UAAU,CAAA,GACf,KAAK,MAAM,CAAA;AAAA,EACb;AAAA,EAEA,IAAI/C,GAAQ;AACV,QAAI,KAAK,QAAQ,SAASA,CAAM,EAAG;AACnC,UAAM7K,IAAK6K,EAAO,KAAK;AAEvB,gBAAK,QAAQ,KAAKA,CAAM,GACxB,KAAK,IAAI,KAAK7K,CAAE,GAET;AAAA,EACT;AAAA,EAEA,YAAYA,GAAI;AACd,UAAM6N,IAAY,KAAK,IAAI,QAAQ7N,IAAK,CAAC,KAAK;AAC9C,gBAAK,IAAI,OAAO,GAAG6N,GAAW,CAAC,GAC/B,KAAK,QACF,OAAO,GAAGA,GAAW,IAAIP,GAAU,CAAE,EACrC,QAAQ,CAAC/Z,MAAMA,EAAE,yBAAwB,CAAE,GACvC;AAAA,EACT;AAAA,EAEA,KAAKyM,GAAI8N,GAAW;AAClB,UAAM3L,IAAQ,KAAK,IAAI,QAAQnC,IAAK,CAAC;AACrC,gBAAK,IAAI,OAAOmC,GAAO,GAAGnC,IAAK,CAAC,GAChC,KAAK,QAAQ,OAAOmC,GAAO,GAAG2L,CAAS,GAChC;AAAA,EACT;AAAA,EAEA,QAAQ9N,GAAI;AACV,WAAO,KAAK,QAAQ,KAAK,IAAI,QAAQA,IAAK,CAAC,CAAC;AAAA,EAC9C;AAAA,EAEA,SAAS;AACP,WAAO,KAAK,IAAI;AAAA,EAClB;AAAA,EAEA,QAAQ;AACN,QAAI+N,IAAa;AACjB,aAASjhB,IAAI,GAAGA,IAAI,KAAK,QAAQ,QAAQ,EAAEA,GAAG;AAC5C,YAAM+d,IAAS,KAAK,QAAQ/d,CAAC;AAY7B,UATEihB,KACAlD,EAAO,QACPkD,EAAW;AAAA,OAEV,CAAClD,EAAO,aACP,CAACA,EAAO,UAAU,WAAW,SAASA,EAAO,EAAE,OAChD,CAACkD,EAAW,aACX,CAACA,EAAW,UAAU,WAAW,SAASA,EAAW,EAAE,IAE5C;AAEb,aAAK,OAAOlD,EAAO,EAAE;AACrB,cAAMiD,IAAYjD,EAAO,UAAUkD,CAAU;AAC7C,aAAK,KAAKA,EAAW,IAAID,CAAS,GAClCC,IAAaD,GACb,EAAEhhB;AAAA,MACJ;AACE,QAAAihB,IAAalD;AAAA,IAEjB;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,OAAO7K,GAAI;AACT,UAAMmC,IAAQ,KAAK,IAAI,QAAQnC,IAAK,CAAC;AACrC,gBAAK,IAAI,OAAOmC,GAAO,CAAC,GACxB,KAAK,QAAQ,OAAOA,GAAO,CAAC,GACrB;AAAA,EACT;AACF;AAEAhW,EAAgB;AAAA,EACd,SAAS;AAAA,IACP,QAAQ+Y,GAAUoE,GAAOwB,GAAM;AAC7B,YAAMhd,IAAI2d,GAAO,SAASvG,GAAUoE,GAAOwB,CAAI,GACzCnM,IAAW,KAAK,SAAQ;AAC9B,aAAO,IAAI8M,GAAO3d,EAAE,QAAQ,EACzB,KAAKA,CAAC,EACN,QAAQ,IAAI,EACZ,SAAS6Q,EAAS,KAAI,CAAE,EACxB,SAAS7Q,EAAE,OAAOA,EAAE,IAAI;AAAA,IAC7B;AAAA,IAEA,MAAMkgB,GAAIlD,GAAM;AACd,aAAO,KAAK,QAAQ,GAAGkD,GAAIlD,CAAI;AAAA,IACjC;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA,6BAA6BmD,GAAe;AAC1C,WAAK,uBAAuB,YAAYA,EAAc,EAAE;AAAA,IAC1D;AAAA,IAEA,kBAAkBhT,GAAS;AACzB,aACE,KAAK,uBAAuB,QAIzB,OAAO,CAAC4P,MAAWA,EAAO,MAAM5P,EAAQ,EAAE,EAC1C,IAAIwS,EAAkB,EACtB,OAAOD,IAAW,IAAI1V,EAAM,CAAE;AAAA,IAErC;AAAA,IAEA,WAAW+S,GAAQ;AACjB,WAAK,uBAAuB,IAAIA,CAAM,GAKtCxB,EAAS,gBAAgB,KAAK,QAAQ,GACtC,KAAK,WAAWA,EAAS,UAAUqE,GAAgB,KAAK,IAAI,CAAC;AAAA,IAC/D;AAAA,IAEA,iBAAiB;AACf,MAAI,KAAK,YAAY,SACnB,KAAK,yBAAyB,IAAIE,GAAW,EAAG;AAAA,QAC9C,IAAIN,GAAW,IAAIxV,EAAO,IAAI,CAAC;AAAA,MACzC;AAAA,IAEI;AAAA,EACJ;AACA,CAAC;AAGD,MAAMoW,KAAa,CAAC7a,GAAGe,MAAMf,EAAE,OAAO,CAACjF,MAAM,CAACgG,EAAE,SAAShG,CAAC,CAAC;AAE3DkC,EAAOmb,IAAQ;AAAA,EACb,KAAKpY,GAAGC,GAAG;AACT,WAAO,KAAK,UAAU,QAAQD,GAAGC,CAAC;AAAA,EACpC;AAAA;AAAA,EAGA,IAAIjG,GAAGiG,GAAG;AACR,WAAO,KAAK,UAAU,OAAOjG,GAAGiG,CAAC;AAAA,EACnC;AAAA,EAEA,UAAU6M,GAAMgO,GAAatb,GAAK;AAChC,QAAI,OAAOsb,KAAgB;AACzB,aAAO,KAAK,UAAUhO,GAAM,EAAE,CAACgO,CAAW,GAAGtb,EAAG,CAAE;AAGpD,QAAImK,IAAQmR;AACZ,QAAI,KAAK,aAAahO,GAAMnD,CAAK,EAAG,QAAO;AAE3C,QAAIkQ,IAAU,IAAIvF,GAAU,KAAK,QAAQ,EAAE,GAAG3K,CAAK,GAC/CoR,IAAO,OAAO,KAAKpR,CAAK;AAE5B,gBAAK;AAAA,MACH,WAAY;AACV,QAAAkQ,IAAUA,EAAQ,KAAK,KAAK,UAAU/M,CAAI,EAAEiO,CAAI,CAAC;AAAA,MACnD;AAAA,MACA,SAAU/J,GAAK;AACb,oBAAK,QAAO,EAAGlE,CAAI,EAAE+M,EAAQ,GAAG7I,CAAG,EAAE,QAAO,CAAE,GACvC6I,EAAQ,KAAI;AAAA,MACrB;AAAA,MACA,SAAUmB,GAAY;AAEpB,cAAMC,IAAU,OAAO,KAAKD,CAAU,GAChCE,IAAcL,GAAWI,GAASF,CAAI;AAG5C,YAAIG,EAAY,QAAQ;AAEtB,gBAAMC,IAAiB,KAAK,QAAO,EAAGrO,CAAI,EAAEoO,CAAW,GAGjDE,IAAe,IAAI/G,GAAUwF,EAAQ,KAAI,CAAE,EAAE,QAAO;AAG1D,iBAAO,OAAOuB,GAAcD,CAAc,GAC1CtB,EAAQ,KAAKuB,CAAY;AAAA,QAC3B;AAGA,cAAMC,IAAa,IAAIhH,GAAUwF,EAAQ,GAAE,CAAE,EAAE,QAAO;AAGtD,eAAO,OAAOwB,GAAYL,CAAU,GAGpCnB,EAAQ,GAAGwB,CAAU,GAGrBN,IAAOE,GACPtR,IAAQqR;AAAA,MACV;AAAA,IACN,GAEI,KAAK,iBAAiBlO,GAAM+M,CAAO,GAC5B;AAAA,EACT;AAAA,EAEA,KAAK5Q,GAAOvE,GAAO;AACjB,QAAI,KAAK,aAAa,QAAQuE,GAAOvE,CAAK,EAAG,QAAO;AAEpD,QAAImV,IAAU,IAAIvF,GAAU,KAAK,QAAQ,EAAE,GAAG,IAAI9I,EAAUvC,CAAK,CAAC;AAElE,gBAAK;AAAA,MACH,WAAY;AACV,QAAA4Q,IAAUA,EAAQ,KAAK,KAAK,QAAO,EAAG,KAAI,CAAE;AAAA,MAC9C;AAAA,MACA,SAAU7I,GAAK;AACb,oBAAK,QAAO,EAAG,KAAK6I,EAAQ,GAAG7I,CAAG,GAAGtM,CAAK,GACnCmV,EAAQ,KAAI;AAAA,MACrB;AAAA,MACA,SAAUyB,GAAUC,GAAU;AAC5B,QAAA7W,IAAQ6W,GACR1B,EAAQ,GAAGyB,CAAQ;AAAA,MACrB;AAAA,IACN,GAEI,KAAK,iBAAiB,QAAQzB,CAAO,GAC9B;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,UAAUvb,GAAYsH,GAAU4V,GAAQ;AAGtC,QADA5V,IAAWtH,EAAW,YAAYsH,GAEhC,KAAK,kBACL,CAACA,KACD,KAAK,aAAa,aAAatH,CAAU;AAEzC,aAAO;AAIT,UAAMmd,IAAWhX,EAAO,aAAanG,CAAU;AAC/C,IAAAkd,IACEld,EAAW,UAAU,OACjBA,EAAW,SACXkd,KAEE,CAACC;AAGT,UAAM5B,IAAU,IAAIvF,GAAU,KAAK,QAAQ,EAAE;AAAA,MAC3CkH,IAAShH,KAAe/P;AAAAA,IAC9B;AAEI,QAAI/J,GACAN,GACAwN,GACA8T,GACAC;AAEJ,aAASC,IAAQ;AAEf,MAAAxhB,IAAUA,KAAW,KAAK,QAAO,GACjCM,IAASA,KAAUF,GAAU8D,GAAYlE,CAAO,GAEhDuhB,IAAiB,IAAIlX,EAAOmB,IAAW,SAAYxL,CAAO,GAG1DA,EAAQ,WAAW,IAAI,GAGlBwL,KACHxL,EAAQ,6BAA6B,IAAI;AAAA,IAE7C;AAEA,aAASyhB,EAAI7K,GAAK;AAGhB,MAAKpL,KAAU,KAAK,eAAc;AAElC,YAAM,EAAE,GAAA7K,GAAG,GAAAC,EAAC,IAAK,IAAIsJ,EAAM5J,CAAM,EAAE;AAAA,QACjCN,EAAQ,kBAAkB,IAAI;AAAA,MACtC;AAEM,UAAIsX,IAAS,IAAIjN,EAAO,EAAE,GAAGnG,GAAY,QAAQ,CAACvD,GAAGC,CAAC,EAAC,CAAE,GACrD2b,IAAQ,KAAK,kBAAkB/O,IAAUA,IAAU+T;AAEvD,UAAIH,GAAQ;AACV,QAAA9J,IAASA,EAAO,UAAU3W,GAAGC,CAAC,GAC9B2b,IAAQA,EAAM,UAAU5b,GAAGC,CAAC;AAG5B,cAAM8gB,IAAUpK,EAAO,QACjBqK,IAAWpF,EAAM,QAGjBqF,IAAgB,CAACF,IAAU,KAAKA,GAASA,IAAU,GAAG,GACtDG,IAAYD,EAAc,IAAI,CAAChc,MAAM,KAAK,IAAIA,IAAI+b,CAAQ,CAAC,GAC3DG,IAAW,KAAK,IAAI,GAAGD,CAAS,GAChCnN,IAAQmN,EAAU,QAAQC,CAAQ;AACxC,QAAAxK,EAAO,SAASsK,EAAclN,CAAK;AAAA,MACrC;AAEA,MAAIlJ,MAGG6V,MACH/J,EAAO,SAASpT,EAAW,UAAU,IAEnC,KAAK,kBAAkBod,MACzB/E,EAAM,SAAS+E,KAInB7B,EAAQ,KAAKlD,CAAK,GAClBkD,EAAQ,GAAGnI,CAAM;AAEjB,YAAMyK,IAAmBtC,EAAQ,GAAG7I,CAAG;AACvC,aAAA0K,IAAeS,EAAiB,QAChCvU,IAAU,IAAInD,EAAO0X,CAAgB,GAErC,KAAK,aAAavU,CAAO,GACzBxN,EAAQ,WAAW,IAAI,GAChByf,EAAQ,KAAI;AAAA,IACrB;AAEA,aAASuC,EAASC,GAAe;AAE/B,OACGA,EAAc,UAAU,UAAU,SAAQ,OAC1C/d,EAAW,UAAU,UAAU,SAAQ,MAExC5D,IAASF,GAAU6hB,GAAejiB,CAAO,IAI3CkE,IAAa,EAAE,GAAG+d,GAAe,QAAA3hB,EAAM;AAAA,IACzC;AAEA,gBAAK,MAAMkhB,GAAOC,GAAKO,GAAU,EAAI,GACrC,KAAK,kBAAkB,KAAK,iBAAiB,aAAavC,CAAO,GAC1D;AAAA,EACT;AAAA;AAAA,EAGA,EAAE9e,GAAG;AACH,WAAO,KAAK,aAAa,KAAKA,CAAC;AAAA,EACjC;AAAA;AAAA,EAGA,EAAEC,GAAG;AACH,WAAO,KAAK,aAAa,KAAKA,CAAC;AAAA,EACjC;AAAA,EAEA,GAAGD,GAAG;AACJ,WAAO,KAAK,aAAa,MAAMA,CAAC;AAAA,EAClC;AAAA,EAEA,GAAGC,GAAG;AACJ,WAAO,KAAK,aAAa,MAAMA,CAAC;AAAA,EAClC;AAAA,EAEA,GAAGD,IAAI,GAAG;AACR,WAAO,KAAK,kBAAkB,KAAKA,CAAC;AAAA,EACtC;AAAA,EAEA,GAAGC,IAAI,GAAG;AACR,WAAO,KAAK,kBAAkB,KAAKA,CAAC;AAAA,EACtC;AAAA,EAEA,MAAMD,GAAGC,GAAG;AACV,WAAO,KAAK,GAAGD,CAAC,EAAE,GAAGC,CAAC;AAAA,EACxB;AAAA,EAEA,kBAAkB4e,GAAQvK,GAAI;AAI5B,QAHAA,IAAK,IAAI7D,EAAU6D,CAAE,GAGjB,KAAK,aAAauK,GAAQvK,CAAE,EAAG,QAAO;AAG1C,UAAMwK,IAAU,IAAIvF,GAAU,KAAK,QAAQ,EAAE,GAAGjF,CAAE;AAClD,QAAID,IAAO;AACX,gBAAK;AAAA,MACH,WAAY;AACV,QAAAA,IAAO,KAAK,QAAO,EAAGwK,CAAM,EAAC,GAC7BC,EAAQ,KAAKzK,CAAI,GACjByK,EAAQ,GAAGzK,IAAOC,CAAE;AAAA,MACtB;AAAA,MACA,SAAU2B,GAAK;AACb,oBAAK,QAAO,EAAG4I,CAAM,EAAEC,EAAQ,GAAG7I,CAAG,CAAC,GAC/B6I,EAAQ,KAAI;AAAA,MACrB;AAAA,MACA,SAAUyC,GAAO;AACf,QAAAzC,EAAQ,GAAGzK,IAAO,IAAI5D,EAAU8Q,CAAK,CAAC;AAAA,MACxC;AAAA,IACN,GAGI,KAAK,iBAAiB1C,GAAQC,CAAO,GAC9B;AAAA,EACT;AAAA,EAEA,aAAaD,GAAQvK,GAAI;AAEvB,QAAI,KAAK,aAAauK,GAAQvK,CAAE,EAAG,QAAO;AAG1C,UAAMwK,IAAU,IAAIvF,GAAU,KAAK,QAAQ,EAAE,GAAGjF,CAAE;AAClD,gBAAK;AAAA,MACH,WAAY;AACV,QAAAwK,EAAQ,KAAK,KAAK,QAAO,EAAGD,CAAM,EAAC,CAAE;AAAA,MACvC;AAAA,MACA,SAAU5I,GAAK;AACb,oBAAK,QAAO,EAAG4I,CAAM,EAAEC,EAAQ,GAAG7I,CAAG,CAAC,GAC/B6I,EAAQ,KAAI;AAAA,MACrB;AAAA,IACN,GAGI,KAAK,iBAAiBD,GAAQC,CAAO,GAC9B;AAAA,EACT;AAAA,EAEA,aAAaD,GAAQjO,GAAO;AAC1B,WAAO,KAAK,aAAaiO,GAAQ,IAAIpO,EAAUG,CAAK,CAAC;AAAA,EACvD;AAAA;AAAA,EAGA,GAAG5Q,GAAG;AACJ,WAAO,KAAK,aAAa,MAAMA,CAAC;AAAA,EAClC;AAAA;AAAA,EAGA,GAAGC,GAAG;AACJ,WAAO,KAAK,aAAa,MAAMA,CAAC;AAAA,EAClC;AAAA;AAAA,EAGA,KAAKD,GAAGC,GAAG;AACT,WAAO,KAAK,EAAED,CAAC,EAAE,EAAEC,CAAC;AAAA,EACtB;AAAA,EAEA,MAAMD,GAAGC,GAAG;AACV,WAAO,KAAK,GAAGD,CAAC,EAAE,GAAGC,CAAC;AAAA,EACxB;AAAA;AAAA,EAGA,OAAOD,GAAGC,GAAG;AACX,WAAO,KAAK,GAAGD,CAAC,EAAE,GAAGC,CAAC;AAAA,EACxB;AAAA;AAAA,EAGA,KAAKX,GAAOC,GAAQ;AAElB,QAAIC;AAEJ,YAAI,CAACF,KAAS,CAACC,OACbC,IAAM,KAAK,SAAS,KAAI,IAGrBF,MACHA,IAASE,EAAI,QAAQA,EAAI,SAAUD,IAGhCA,MACHA,IAAUC,EAAI,SAASA,EAAI,QAASF,IAG/B,KAAK,MAAMA,CAAK,EAAE,OAAOC,CAAM;AAAA,EACxC;AAAA;AAAA,EAGA,MAAMD,GAAO;AACX,WAAO,KAAK,aAAa,SAASA,CAAK;AAAA,EACzC;AAAA;AAAA,EAGA,OAAOC,GAAQ;AACb,WAAO,KAAK,aAAa,UAAUA,CAAM;AAAA,EAC3C;AAAA;AAAA,EAGA,KAAK0F,GAAGe,GAAG3B,GAAGtF,GAAG;AAEf,QAAI,UAAU,WAAW;AACvB,aAAO,KAAK,KAAK,CAACkG,GAAGe,GAAG3B,GAAGtF,CAAC,CAAC;AAG/B,QAAI,KAAK,aAAa,QAAQkG,CAAC,EAAG,QAAO;AAEzC,UAAM6Z,IAAU,IAAIvF,GAAU,KAAK,QAAQ,EACxC,KAAK,KAAK,SAAS,UAAU,EAC7B,GAAGtU,CAAC;AAEP,gBAAK;AAAA,MACH,WAAY;AACV,QAAA6Z,EAAQ,KAAK,KAAK,SAAS,MAAK,CAAE;AAAA,MACpC;AAAA,MACA,SAAU7I,GAAK;AACb,oBAAK,SAAS,KAAK6I,EAAQ,GAAG7I,CAAG,CAAC,GAC3B6I,EAAQ,KAAI;AAAA,MACrB;AAAA,IACN,GAEI,KAAK,iBAAiB,QAAQA,CAAO,GAC9B;AAAA,EACT;AAAA;AAAA,EAGA,QAAQlO,GAAO;AACb,WAAO,KAAK,aAAa,WAAWA,CAAK;AAAA,EAC3C;AAAA;AAAA,EAGA,QAAQ5Q,GAAGC,GAAGX,GAAOC,GAAQ;AAC3B,WAAO,KAAK,aAAa,WAAW,IAAI+N,EAAItN,GAAGC,GAAGX,GAAOC,CAAM,CAAC;AAAA,EAClE;AAAA,EAEA,OAAOG,GAAG;AACR,WAAI,OAAOA,KAAM,WACR,KAAK,OAAO;AAAA,MACjB,QAAQ,UAAU,CAAC;AAAA,MACnB,OAAO,UAAU,CAAC;AAAA,MAClB,SAAS,UAAU,CAAC;AAAA,IAC5B,CAAO,KAGCA,EAAE,WAAW,QAAM,KAAK,KAAK,gBAAgBA,EAAE,OAAO,GACtDA,EAAE,SAAS,QAAM,KAAK,KAAK,cAAcA,EAAE,KAAK,GAChDA,EAAE,UAAU,QAAM,KAAK,KAAK,UAAUA,EAAE,MAAM,GAE3C;AAAA,EACT;AACF,CAAC;AAEDwC,EAAOmb,IAAQ,EAAE,IAAAvS,IAAI,IAAAC,IAAI,MAAAsJ,IAAM,IAAAC,GAAE,CAAE;AACnC1S,EAASyb,IAAQ,QAAQ;AChjCV,MAAMmE,WAAY1N,GAAU;AAAA,EACzC,YAAYrS,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,OAAOC,CAAI,GAAGmN,CAAK,GACnC,KAAK,UAAS;AAAA,EAChB;AAAA;AAAA,EAGA,OAAO;AACL,WAAK,KAAK,OAAM,IAETlN,GAAM,KAAK,KAAK,cAAc,MAAM,CAAC,KAAK,KAAK,IAAI,IAAIsS,GAAI,CAAE,IAFzC,KAAK,KAAI,EAAG,KAAI;AAAA,EAG7C;AAAA,EAEA,SAAS;AACP,WACE,CAAC,KAAK,KAAK,cACV,EAAE,KAAK,KAAK,sBAAsBnT,EAAQ,OAAO,eAChD,KAAK,KAAK,WAAW,aAAa;AAAA,EAExC;AAAA;AAAA,EAGA,YAAY;AACV,WAAK,KAAK,OAAM,IACT,KAAK,KAAK,EAAE,OAAOJ,IAAK,SAAS,MAAK,CAAE,EAAE;AAAA,MAC/C;AAAA,MACAG;AAAA,MACAD;AAAA,IACN,IAL+B,KAAK,KAAI,EAAG,UAAS;AAAA,EAMlD;AAAA,EAEA,kBAAkB;AAChB,WAAO,KAAK,KAAK,EAAE,OAAO,MAAM,SAAS,KAAI,CAAE,EAC5C,KAAK,eAAe,MAAMA,EAAK,EAC/B,KAAK,eAAe,MAAMA,EAAK;AAAA,EACpC;AAAA;AAAA;AAAA,EAIA,OAAO;AACL,WAAI,KAAK,OAAM,IAAW,OACnB,MAAM,KAAI;AAAA,EACnB;AACF;AAEA5C,EAAgB;AAAA,EACd,WAAW;AAAA;AAAA,IAET,QAAQqE,EAAkB,WAAY;AACpC,aAAO,KAAK,IAAI,IAAIof,GAAG,CAAE;AAAA,IAC3B,CAAC;AAAA,EACL;AACA,CAAC;AAED5f,EAAS4f,IAAK,OAAO,EAAI;SC9DV,cAAqB1N,GAAU;AAAA;AAAA,EAE5C,YAAYrS,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,UAAUC,CAAI,GAAGmN,CAAK;AAAA,EACxC;AACF;AAEA7Q,EAAgB;AAAA,EACd,WAAW;AAAA,IACT,QAAQqE,EAAkB,WAAY;AACpC,aAAO,KAAK,IAAI,IAAIqf,GAAM,CAAE;AAAA,IAC9B,CAAC;AAAA,EACL;AACA,CAAC;AAED7f,EAAS6f,IAAQ,QAAQ;AChBlB,SAASC,GAAMtP,GAAM;AAE1B,SAAI,KAAK,WAAW,MAClB,KAAK,MAAK,GAIZ,KAAK,KAAK,YAAYvR,EAAQ,SAAS,eAAeuR,CAAI,CAAC,GAEpD;AACT;AAGO,SAASe,KAAS;AACvB,SAAO,KAAK,KAAK,sBAAqB;AACxC;AAKO,SAASnT,GAAEA,GAAGR,IAAM,KAAK,KAAI,GAAI;AACtC,SAAIQ,KAAK,OACAR,EAAI,IAGN,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG,IAAIQ,IAAIR,EAAI,CAAC;AAClD;AAGO,SAASS,GAAEA,GAAGT,IAAM,KAAK,KAAI,GAAI;AACtC,SAAIS,KAAK,OACAT,EAAI,IAGN,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG,IAAIS,IAAIT,EAAI,CAAC;AAClD;AAEO,SAAS+a,GAAKva,GAAGC,GAAGT,IAAM,KAAK,KAAI,GAAI;AAC5C,SAAO,KAAK,EAAEQ,GAAGR,CAAG,EAAE,EAAES,GAAGT,CAAG;AAChC;AAGO,SAAS0L,GAAGlL,GAAGR,IAAM,KAAK,KAAI,GAAI;AACvC,SAAIQ,KAAK,OACAR,EAAI,KAGN,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG,IAAIQ,IAAIR,EAAI,EAAE;AACnD;AAGO,SAAS2L,GAAGlL,GAAGT,IAAM,KAAK,KAAI,GAAI;AACvC,SAAIS,KAAK,OACAT,EAAI,KAGN,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG,IAAIS,IAAIT,EAAI,EAAE;AACnD;AAEO,SAASmiB,GAAO3hB,GAAGC,GAAGT,IAAM,KAAK,KAAI,GAAI;AAC9C,SAAO,KAAK,GAAGQ,GAAGR,CAAG,EAAE,GAAGS,GAAGT,CAAG;AAClC;AAEO,SAASoiB,GAAG5hB,GAAG;AACpB,SAAO,KAAK,KAAK,KAAKA,CAAC;AACzB;AAEO,SAAS6hB,GAAG5hB,GAAG;AACpB,SAAO,KAAK,KAAK,KAAKA,CAAC;AACzB;AAEO,SAAS6hB,GAAM9hB,GAAGC,GAAG;AAC1B,SAAO,KAAK,GAAGD,CAAC,EAAE,GAAGC,CAAC;AACxB;AAGO,SAAS8hB,GAAMA,GAAO;AAC3B,cAAK,SAAS,CAAC,CAACA,GACT;AACT;;;;;;;;;;;;;;;;ACpEe,MAAMC,WAAa/N,GAAM;AAAA;AAAA,EAEtC,YAAYxS,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,QAAQC,CAAI,GAAGmN,CAAK,GAEpC,KAAK,IAAI,UAAU,KAAK,IAAI,WAAW,IAAI6B,EAAU,GAAG,GACxD,KAAK,WAAW,IAChB,KAAK,SAAS;AAAA,EAChB;AAAA;AAAA,EAGA,QAAQG,GAAO;AAEb,WAAIA,KAAS,OACJ,KAAK,IAAI,WAIlB,KAAK,IAAI,UAAU,IAAIH,EAAUG,CAAK,GAE/B,KAAK,QAAO;AAAA,EACrB;AAAA;AAAA,EAGA,QAAQqR,GAAS;AAOf,QALI,OAAOA,KAAY,cACrB,KAAK,WAAWA,IAId,KAAK,UAAU;AACjB,YAAMC,IAAO;AACb,UAAIC,IAAkB;AACtB,YAAMC,IAAU,KAAK,IAAI;AAEzB,WAAK,KAAK,SAAU1jB,GAAG;AACrB,YAAIyB,GAAc,KAAK,IAAI,EAAG;AAE9B,cAAMkiB,IAAWxhB,EAAQ,OACtB,iBAAiB,KAAK,IAAI,EAC1B,iBAAiB,WAAW,GAEzByK,IAAK8W,IAAU,IAAI3R,EAAU4R,CAAQ;AAE3C,QAAI,KAAK,IAAI,aACX,KAAK,KAAK,KAAKH,EAAK,KAAK,GAAG,CAAC,GAEzB,KAAK,KAAI,MAAO;AAAA,IAClBC,KAAmB7W,KAEnB,KAAK,KAAK,MAAM5M,IAAI4M,IAAK6W,IAAkB,CAAC,GAC5CA,IAAkB;AAAA,MAGxB,CAAC,GAED,KAAK,KAAK,SAAS;AAAA,IACrB;AAEA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,QAAQziB,GAAG;AACT,gBAAK,MAAMA,GACX,KAAK,IAAI,UAAU,IAAI+Q,EAAU/Q,EAAE,WAAW,GAAG,GAC1C;AAAA,EACT;AAAA,EAEA,iBAAiB;AACf,WAAAU,GAAe,MAAM,KAAK,KAAK,EAAE,SAAS,IAAG,CAAE,GACxC;AAAA,EACT;AAAA;AAAA,EAGA,KAAKgS,GAAM;AAET,QAAIA,MAAS,QAAW;AACtB,YAAMZ,IAAW,KAAK,KAAK;AAC3B,UAAI8Q,IAAY;AAChB,MAAAlQ,IAAO;AAEP,eAAS1T,IAAI,GAAGgU,IAAMlB,EAAS,QAAQ9S,IAAIgU,GAAK,EAAEhU,GAAG;AAEnD,YAAI8S,EAAS9S,CAAC,EAAE,aAAa,cAAcyB,GAAcqR,EAAS9S,CAAC,CAAC,GAAG;AACrE,UAAIA,MAAM,MAAG4jB,IAAY5jB,IAAI;AAC7B;AAAA,QACF;AAGA,QACEA,MAAM4jB,KACN9Q,EAAS9S,CAAC,EAAE,aAAa,KACzBgD,GAAM8P,EAAS9S,CAAC,CAAC,EAAE,IAAI,aAAa,OAEpC0T,KAAQ;AAAA,IAIVA,KAAQZ,EAAS9S,CAAC,EAAE;AAAA,MACtB;AAEA,aAAO0T;AAAA,IACT;AAKA,QAFA,KAAK,QAAQ,MAAM,EAAI,GAEnB,OAAOA,KAAS;AAElB,MAAAA,EAAK,KAAK,MAAM,IAAI;AAAA,SACf;AAEL,MAAAA,KAAQA,IAAO,IAAI,MAAM;AAAA,CAAI;AAG7B,eAAS/B,IAAI,GAAGyH,IAAK1F,EAAK,QAAQ/B,IAAIyH,GAAIzH;AACxC,aAAK,QAAQ+B,EAAK/B,CAAC,CAAC;AAAA,IAExB;AAGA,WAAO,KAAK,MAAM,EAAK,EAAE,QAAO;AAAA,EAClC;AACF;AAEAnO,EAAO8f,IAAMO,EAAQ;AAErBxkB,EAAgB;AAAA,EACd,WAAW;AAAA;AAAA,IAET,MAAMqE,EAAkB,SAAUgQ,IAAO,IAAI;AAC3C,aAAO,KAAK,IAAI,IAAI4P,GAAI,CAAE,EAAE,KAAK5P,CAAI;AAAA,IACvC,CAAC;AAAA;AAAA,IAGD,OAAOhQ,EAAkB,SAAUgQ,IAAO,IAAI;AAC5C,aAAO,KAAK,IAAI,IAAI4P,GAAI,CAAE,EAAE,MAAM5P,CAAI;AAAA,IACxC,CAAC;AAAA,EACL;AACA,CAAC;AAEDxQ,EAASogB,IAAM,MAAM;AChJN,MAAMQ,WAAcvO,GAAM;AAAA;AAAA,EAEvC,YAAYxS,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,SAASC,CAAI,GAAGmN,CAAK,GACrC,KAAK,SAAS;AAAA,EAChB;AAAA;AAAA,EAGA,GAAGvD,GAAI;AACL,WAAO,KAAK,KAAK,MAAMA,CAAE;AAAA,EAC3B;AAAA;AAAA,EAGA,GAAGC,GAAI;AACL,WAAO,KAAK,KAAK,MAAMA,CAAE;AAAA,EAC3B;AAAA;AAAA,EAGA,UAAU;AAER,SAAK,IAAI,WAAW;AAGpB,UAAM8G,IAAO,KAAK,OAAM;AAGxB,QAAI,EAAEA,aAAgB4P;AACpB,aAAO;AAGT,UAAMtjB,IAAI0T,EAAK,MAAM,IAAI,GAEnBiQ,IAAWxhB,EAAQ,OACtB,iBAAiB,KAAK,IAAI,EAC1B,iBAAiB,WAAW,GACzByK,IAAK8G,EAAK,IAAI,UAAU,IAAI3B,EAAU4R,CAAQ;AAGpD,WAAO,KAAK,GAAG3jB,IAAI4M,IAAK,CAAC,EAAE,KAAK,KAAK8G,EAAK,EAAC,CAAE;AAAA,EAC/C;AAAA;AAAA,EAGA,KAAKA,GAAM;AACT,WAAIA,KAAQ,OACH,KAAK,KAAK,eAAe,KAAK,IAAI,WAAW;AAAA,IAAO,OAEzD,OAAOA,KAAS,cAClB,KAAK,QAAQ,MAAM,EAAI,GACvBA,EAAK,KAAK,MAAM,IAAI,GACpB,KAAK,MAAM,EAAK,KAEhB,KAAK,MAAMA,CAAI,GAGV;AAAA,EACT;AACF;AAEAlQ,EAAOsgB,IAAOD,EAAQ;AAEtBxkB,EAAgB;AAAA,EACd,OAAO;AAAA,IACL,OAAOqE,EAAkB,SAAUgQ,IAAO,IAAI;AAC5C,YAAMqQ,IAAQ,IAAID,GAAK;AAGvB,aAAK,KAAK,UACR,KAAK,MAAK,GAIL,KAAK,IAAIC,CAAK,EAAE,KAAKrQ,CAAI;AAAA,IAClC,CAAC;AAAA,EACL;AAAA,EACE,MAAM;AAAA,IACJ,SAAS,SAAUA,IAAO,IAAI;AAC5B,aAAO,KAAK,MAAMA,CAAI,EAAE,QAAO;AAAA,IACjC;AAAA,EACJ;AACA,CAAC;AAEDxQ,EAAS4gB,IAAO,OAAO;ACnFR,MAAME,WAAezO,GAAM;AAAA,EACxC,YAAYxS,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,UAAUC,CAAI,GAAGmN,CAAK;AAAA,EACxC;AAAA,EAEA,OAAOzJ,GAAG;AACR,WAAO,KAAK,KAAK,KAAKA,CAAC;AAAA,EACzB;AAAA;AAAA,EAGA,GAAG2F,GAAI;AACL,WAAO,KAAK,KAAK,KAAKA,CAAE;AAAA,EAC1B;AAAA;AAAA,EAGA,GAAGC,GAAI;AACL,WAAO,KAAK,GAAGA,CAAE;AAAA,EACnB;AAAA,EAEA,KAAK0P,GAAM;AACT,WAAO,KAAK,OAAO,IAAIhK,EAAUgK,CAAI,EAAE,OAAO,CAAC,CAAC;AAAA,EAClD;AACF;AAEAvY,EAAOwgB,IAAQ,EAAA,GAAE1iB,IAAC,GAAEC,IAAC,IAAEiL,QAAIC,IAAE,OAAE7L,IAAK,QAAEC,GAAM,CAAE;AAE9CxB,EAAgB;AAAA,EACd,WAAW;AAAA;AAAA,IAET,QAAQqE,EAAkB,SAAUqY,IAAO,GAAG;AAC5C,aAAO,KAAK,IAAI,IAAIiI,GAAM,CAAE,EAAE,KAAKjI,CAAI,EAAE,KAAK,GAAG,CAAC;AAAA,IACpD,CAAC;AAAA,EACL;AACA,CAAC;AAED7Y,EAAS8gB,IAAQ,QAAQ;ACzCV,MAAMC,WAAiB7O,GAAU;AAAA,EAC9C,YAAYrS,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,YAAYC,CAAI,GAAGmN,CAAK;AAAA,EAC1C;AAAA;AAAA,EAGA,SAAS;AAEP,gBAAK,QAAO,EAAG,QAAQ,SAAUjK,GAAI;AACnC,MAAAA,EAAG,OAAM;AAAA,IACX,CAAC,GAGM,MAAM,OAAM;AAAA,EACrB;AAAA,EAEA,UAAU;AACR,WAAOkK,GAAS,qBAAqB,KAAK,GAAE,IAAK,GAAG;AAAA,EACtD;AACF;AAEA9Q,EAAgB;AAAA,EACd,WAAW;AAAA;AAAA,IAET,MAAMqE,EAAkB,WAAY;AAClC,aAAO,KAAK,KAAI,EAAG,IAAI,IAAIugB,GAAQ,CAAE;AAAA,IACvC,CAAC;AAAA,EACL;AAAA,EACE,SAAS;AAAA;AAAA,IAEP,UAAU;AACR,aAAO,KAAK,UAAU,WAAW;AAAA,IACnC;AAAA,IAEA,SAAStjB,GAAS;AAEhB,YAAMujB,IACJvjB,aAAmBsjB,KACftjB,IACA,KAAK,OAAM,EAAG,KAAI,EAAG,IAAIA,CAAO;AAGtC,aAAO,KAAK,KAAK,aAAa,UAAUujB,EAAQ,GAAE,IAAK,GAAG;AAAA,IAC5D;AAAA;AAAA,IAGA,SAAS;AACP,aAAO,KAAK,KAAK,aAAa,IAAI;AAAA,IACpC;AAAA,EACJ;AACA,CAAC;AAEDhhB,EAAS+gB,IAAU,UAAU;ACrDd,MAAME,WAAsB3W,GAAQ;AAAA,EACjD,YAAYzK,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,iBAAiBC,CAAI,GAAGmN,CAAK;AAAA,EAC/C;AACF;AAEA7Q,EAAgB;AAAA,EACd,WAAW;AAAA,IACT,eAAeqE,EAAkB,SAAU9C,GAAOC,GAAQ;AACxD,aAAO,KAAK,IAAI,IAAIsjB,GAAa,CAAE,EAAE,KAAKvjB,GAAOC,CAAM;AAAA,IACzD,CAAC;AAAA,EACL;AACA,CAAC;AAEDqC,EAASihB,IAAe,eAAe;ACZhC,SAASC,GAAMzX,GAAIC,GAAI;AAC5B,cAAK,SAAQ,EAAG,QAAQ,CAACyX,MAAU;AACjC,QAAIjV;AAIJ,QAAI;AAOF,MAAAA,IACEiV,EAAM,gBAAgBjiB,KAAY,gBAC9B,IAAIwM,EAAIyV,EAAM,KAAK,CAAC,KAAK,KAAK,SAAS,QAAQ,CAAC,CAAC,IACjDA,EAAM,KAAI;AAAA,IAClB,QAAY;AACV;AAAA,IACF;AAGA,UAAM9kB,IAAI,IAAIyL,EAAOqZ,CAAK,GAGpB3X,IAASnN,EAAE,UAAUoN,GAAIC,CAAE,EAAE,UAAUrN,EAAE,QAAO,CAAE,GAElDmI,IAAI,IAAImD,EAAMuE,EAAK,GAAGA,EAAK,CAAC,EAAE,UAAU1C,CAAM;AAEpD,IAAA2X,EAAM,KAAK3c,EAAE,GAAGA,EAAE,CAAC;AAAA,EACrB,CAAC,GAEM;AACT;AAEO,SAASiF,GAAGA,GAAI;AACrB,SAAO,KAAK,MAAMA,GAAI,CAAC;AACzB;AAEO,SAASC,GAAGA,GAAI;AACrB,SAAO,KAAK,MAAM,GAAGA,CAAE;AACzB;AAEO,SAAS/L,GAAOA,GAAQC,IAAM,KAAK,KAAI,GAAI;AAChD,SAAID,KAAU,OAAaC,EAAI,SACxB,KAAK,KAAKA,EAAI,OAAOD,GAAQC,CAAG;AACzC;AAEO,SAAS+a,GAAKva,IAAI,GAAGC,IAAI,GAAGT,IAAM,KAAK,QAAQ;AACpD,QAAM6L,IAAKrL,IAAIR,EAAI,GACb8L,IAAKrL,IAAIT,EAAI;AAEnB,SAAO,KAAK,MAAM6L,GAAIC,CAAE;AAC1B;AAEO,SAASmP,GAAKnb,GAAOC,GAAQC,IAAM,KAAK,KAAI,GAAI;AACrD,QAAM4G,IAAIhH,GAAiB,MAAME,GAAOC,GAAQC,CAAG,GAC7C4K,IAAShE,EAAE,QAAQ5G,EAAI,OACvB6K,IAASjE,EAAE,SAAS5G,EAAI;AAE9B,cAAK,SAAQ,EAAG,QAAQ,CAACujB,MAAU;AACjC,UAAMrjB,IAAI,IAAI6J,EAAM/J,CAAG,EAAE,UAAU,IAAIkK,EAAOqZ,CAAK,EAAE,QAAO,CAAE;AAC9D,IAAAA,EAAM,MAAM3Y,GAAQC,GAAQ3K,EAAE,GAAGA,EAAE,CAAC;AAAA,EACtC,CAAC,GAEM;AACT;AAEO,SAASJ,GAAMA,GAAOE,IAAM,KAAK,KAAI,GAAI;AAC9C,SAAIF,KAAS,OAAaE,EAAI,QACvB,KAAK,KAAKF,GAAOE,EAAI,QAAQA,CAAG;AACzC;AAEO,SAASQ,GAAEA,GAAGR,IAAM,KAAK,KAAI,GAAI;AACtC,SAAIQ,KAAK,OAAaR,EAAI,IACnB,KAAK,KAAKQ,GAAGR,EAAI,GAAGA,CAAG;AAChC;AAEO,SAASS,GAAEA,GAAGT,IAAM,KAAK,KAAI,GAAI;AACtC,SAAIS,KAAK,OAAaT,EAAI,IACnB,KAAK,KAAKA,EAAI,GAAGS,GAAGT,CAAG;AAChC;;;;;;;;;;;;;AC7Ee,MAAMwjB,WAAUlP,GAAU;AAAA,EACvC,YAAYrS,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,KAAKC,CAAI,GAAGmN,CAAK;AAAA,EACnC;AACF;AAEA1M,EAAO8gB,IAAGC,EAAiB;AAE3BllB,EAAgB;AAAA,EACd,WAAW;AAAA;AAAA,IAET,OAAOqE,EAAkB,WAAY;AACnC,aAAO,KAAK,IAAI,IAAI4gB,GAAC,CAAE;AAAA,IACzB,CAAC;AAAA,EACL;AACA,CAAC;AAEDphB,EAASohB,IAAG,GAAG;AChBA,MAAME,WAAUpP,GAAU;AAAA,EACvC,YAAYrS,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,KAAKC,CAAI,GAAGmN,CAAK;AAAA,EACnC;AAAA;AAAA,EAGA,OAAO+H,GAAQ;AACb,WAAO,KAAK,KAAK,UAAUA,CAAM;AAAA,EACnC;AAAA;AAAA,EAGA,GAAGjC,GAAK;AACN,WAAO,KAAK,KAAK,QAAQA,GAAK9T,EAAK;AAAA,EACrC;AACF;AAEAsB,EAAOghB,IAAGD,EAAiB;AAE3BllB,EAAgB;AAAA,EACd,WAAW;AAAA;AAAA,IAET,MAAMqE,EAAkB,SAAUsS,GAAK;AACrC,aAAO,KAAK,IAAI,IAAIwO,GAAC,CAAE,EAAE,GAAGxO,CAAG;AAAA,IACjC,CAAC;AAAA,EACL;AAAA,EACE,SAAS;AAAA,IACP,SAAS;AACP,YAAMyO,IAAO,KAAK,OAAM;AAExB,UAAI,CAACA,EAAM,QAAO;AAElB,YAAMpU,IAASoU,EAAK,OAAM;AAE1B,UAAI,CAACpU;AACH,eAAO,KAAK,OAAM;AAGpB,YAAMgF,IAAQhF,EAAO,MAAMoU,CAAI;AAC/B,aAAApU,EAAO,IAAI,MAAMgF,CAAK,GAEtBoP,EAAK,OAAM,GACJ;AAAA,IACT;AAAA,IACA,OAAOzO,GAAK;AAEV,UAAIyO,IAAO,KAAK,OAAM;AAEtB,aAAKA,MACHA,IAAO,IAAID,GAAC,GACZ,KAAK,KAAKC,CAAI,IAGZ,OAAOzO,KAAQ,aACjBA,EAAI,KAAKyO,GAAMA,CAAI,IAEnBA,EAAK,GAAGzO,CAAG,GAGN;AAAA,IACT;AAAA,IACA,SAAS;AACP,YAAMyO,IAAO,KAAK,OAAM;AACxB,aAAIA,KAAQA,EAAK,KAAK,SAAS,YAAW,MAAO,MACxCA,IAGF;AAAA,IACT;AAAA,EACJ;AACA,CAAC;AAEDvhB,EAASshB,IAAG,GAAG;AC7EA,MAAME,WAAatP,GAAU;AAAA;AAAA,EAE1C,YAAYrS,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,QAAQC,CAAI,GAAGmN,CAAK;AAAA,EACtC;AAAA;AAAA,EAGA,SAAS;AAEP,gBAAK,QAAO,EAAG,QAAQ,SAAUjK,GAAI;AACnC,MAAAA,EAAG,OAAM;AAAA,IACX,CAAC,GAGM,MAAM,OAAM;AAAA,EACrB;AAAA,EAEA,UAAU;AACR,WAAOkK,GAAS,gBAAgB,KAAK,GAAE,IAAK,GAAG;AAAA,EACjD;AACF;AAEA9Q,EAAgB;AAAA,EACd,WAAW;AAAA,IACT,MAAMqE,EAAkB,WAAY;AAClC,aAAO,KAAK,KAAI,EAAG,IAAI,IAAIghB,GAAI,CAAE;AAAA,IACnC,CAAC;AAAA,EACL;AAAA,EACE,SAAS;AAAA;AAAA,IAEP,SAAS;AACP,aAAO,KAAK,UAAU,MAAM;AAAA,IAC9B;AAAA,IAEA,SAAS/jB,GAAS;AAEhB,YAAMgkB,IACJhkB,aAAmB+jB,KAAO/jB,IAAU,KAAK,OAAM,EAAG,KAAI,EAAG,IAAIA,CAAO;AAGtE,aAAO,KAAK,KAAK,QAAQ,UAAUgkB,EAAO,GAAE,IAAK,GAAG;AAAA,IACtD;AAAA;AAAA,IAGA,SAAS;AACP,aAAO,KAAK,KAAK,QAAQ,IAAI;AAAA,IAC/B;AAAA,EACJ;AACA,CAAC;AAEDzhB,EAASwhB,IAAM,MAAM;AClDN,MAAME,WAAapX,GAAQ;AAAA,EACxC,YAAYzK,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,QAAQC,CAAI,GAAGmN,CAAK;AAAA,EACtC;AAAA;AAAA,EAGA,OAAOlP,GAAG;AACR,YAAI,OAAOA,KAAM,YAAYA,aAAa+Q,OACxC/Q,IAAI;AAAA,MACF,QAAQ,UAAU,CAAC;AAAA,MACnB,OAAO,UAAU,CAAC;AAAA,MAClB,SAAS,UAAU,CAAC;AAAA,IAC5B,IAIQA,EAAE,WAAW,QAAM,KAAK,KAAK,gBAAgBA,EAAE,OAAO,GACtDA,EAAE,SAAS,QAAM,KAAK,KAAK,cAAcA,EAAE,KAAK,GAChDA,EAAE,UAAU,QAAM,KAAK,KAAK,UAAU,IAAI+Q,EAAU/Q,EAAE,MAAM,CAAC,GAE1D;AAAA,EACT;AACF;AAEA3B,EAAgB;AAAA,EACd,UAAU;AAAA;AAAA,IAER,MAAM,SAAUwlB,GAAQ/c,GAAOgd,GAAS;AACtC,aAAO,KAAK,IAAI,IAAIF,GAAI,CAAE,EAAE,OAAOC,GAAQ/c,GAAOgd,CAAO;AAAA,IAC3D;AAAA,EACJ;AACA,CAAC;AAED5hB,EAAS0hB,IAAM,MAAM;ACjCrB,SAASG,GAAQ5R,GAAU6R,GAAM;AAC/B,MAAI,CAAC7R,EAAU,QAAO;AACtB,MAAI,CAAC6R,EAAM,QAAO7R;AAElB,MAAInN,IAAMmN,IAAW;AAErB,aAAWnT,KAAKglB;AACd,IAAAhf,KAAO1F,GAAYN,CAAC,IAAI,MAAMglB,EAAKhlB,CAAC,IAAI;AAG1C,SAAAgG,KAAO,KAEAA;AACT;AAEe,MAAMif,WAAczX,GAAQ;AAAA,EACzC,YAAYzK,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,SAASC,CAAI,GAAGmN,CAAK;AAAA,EACvC;AAAA,EAEA,QAAQmN,IAAI,IAAI;AACd,gBAAK,KAAK,eAAeA,GAClB;AAAA,EACT;AAAA,EAEA,KAAK/d,GAAM4lB,GAAK3d,IAAS,CAAA,GAAI;AAC3B,WAAO,KAAK,KAAK,cAAc;AAAA,MAC7B,YAAYjI;AAAA,MACZ,KAAK4lB;AAAA,MACL,GAAG3d;AAAA,IACT,CAAK;AAAA,EACH;AAAA,EAEA,KAAK4L,GAAUlD,GAAK;AAClB,WAAO,KAAK,QAAQ8U,GAAQ5R,GAAUlD,CAAG,CAAC;AAAA,EAC5C;AACF;AAEA5Q,EAAgB,OAAO;AAAA,EACrB,MAAM8T,GAAUlD,GAAK;AACnB,WAAO,KAAK,IAAI,IAAIgV,GAAK,CAAE,EAAE,KAAK9R,GAAUlD,CAAG;AAAA,EACjD;AAAA,EACA,SAAS3Q,GAAM4lB,GAAK3d,GAAQ;AAC1B,WAAO,KAAK,IAAI,IAAI0d,GAAK,CAAE,EAAE,KAAK3lB,GAAM4lB,GAAK3d,CAAM;AAAA,EACrD;AACF,CAAC;AAEDrE,EAAS+hB,IAAO,OAAO;AC5CR,MAAME,WAAiB7B,GAAK;AAAA;AAAA,EAEzC,YAAYvgB,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,YAAYC,CAAI,GAAGmN,CAAK;AAAA,EAC1C;AAAA;AAAA,EAGA,QAAQ;AACN,UAAMkV,IAAQ,KAAK,MAAK;AAExB,WAAOA,IAAQA,EAAM,UAAU;AAAA,EACjC;AAAA;AAAA,EAGA,KAAK/kB,GAAG;AACN,UAAM+kB,IAAQ,KAAK,MAAK;AACxB,QAAIC,IAAY;AAEhB,WAAID,MACFC,IAAYD,EAAM,KAAK/kB,CAAC,IAGnBA,KAAK,OAAOglB,IAAY;AAAA,EACjC;AAAA;AAAA,EAGA,QAAQ;AACN,WAAO,KAAK,UAAU,MAAM;AAAA,EAC9B;AACF;AAEAhmB,EAAgB;AAAA,EACd,WAAW;AAAA,IACT,UAAUqE,EAAkB,SAAUgQ,GAAMjF,GAAM;AAEhD,aAAMiF,aAAgB4P,OACpB5P,IAAO,KAAK,KAAKA,CAAI,IAGhBA,EAAK,KAAKjF,CAAI;AAAA,IACvB,CAAC;AAAA,EACL;AAAA,EACE,MAAM;AAAA;AAAA,IAEJ,MAAM/K,EAAkB,SAAU0hB,GAAOE,IAAc,IAAM;AAC3D,YAAMC,IAAW,IAAIJ,GAAQ;AAG7B,MAAMC,aAAiBzJ,OAErByJ,IAAQ,KAAK,KAAI,EAAG,KAAKA,CAAK,IAIhCG,EAAS,KAAK,QAAQ,MAAMH,GAAOljB,EAAK;AAGxC,UAAIa;AACJ,UAAIuiB;AACF,eAAQviB,IAAO,KAAK,KAAK;AACvB,UAAAwiB,EAAS,KAAK,YAAYxiB,CAAI;AAKlC,aAAO,KAAK,IAAIwiB,CAAQ;AAAA,IAC1B,CAAC;AAAA;AAAA,IAGD,WAAW;AACT,aAAO,KAAK,QAAQ,UAAU;AAAA,IAChC;AAAA,EACJ;AAAA,EACE,MAAM;AAAA;AAAA,IAEJ,MAAM7hB,EAAkB,SAAUgQ,GAAM;AAEtC,aAAMA,aAAgB4P,OACpB5P,IAAO,IAAI4P,GAAI,EAAG,MAAM,KAAK,OAAM,CAAE,EAAE,KAAK5P,CAAI,IAI3CA,EAAK,KAAK,IAAI;AAAA,IACvB,CAAC;AAAA,IAED,UAAU;AACR,aAAOvD,GAAS,cAAc,EAAE,OAAO,CAACpN,OAC9BA,EAAK,KAAK,MAAM,KAAK,IAAI,SAAS,KAAK,GAAE,CAAE,CACpD;AAAA,IAIH;AAAA,EACJ;AACA,CAAC;AAEDoiB,GAAS,UAAU,aAAa3K;AAChCtX,EAASiiB,IAAU,UAAU;ACpGd,MAAMK,WAAYjQ,GAAM;AAAA,EACrC,YAAYxS,GAAMmN,IAAQnN,GAAM;AAC9B,UAAMD,EAAU,OAAOC,CAAI,GAAGmN,CAAK;AAAA,EACrC;AAAA;AAAA,EAGA,IAAIvP,GAAS8kB,GAAM;AAEjB,WAAO,KAAK,KAAK,SAASA,KAAQ,MAAM,MAAM9kB,GAASuB,EAAK;AAAA,EAC9D;AACF;AAEA7C,EAAgB;AAAA,EACd,WAAW;AAAA;AAAA,IAET,KAAKqE,EAAkB,SAAU/C,GAAS8kB,GAAM;AAC9C,aAAO,KAAK,IAAI,IAAID,GAAG,CAAE,EAAE,IAAI7kB,GAAS8kB,CAAI;AAAA,IAC9C,CAAC;AAAA,EACL;AACA,CAAC;AAEDviB,EAASsiB,IAAK,KAAK;ACsCZ,MAAME,KAAMhjB;AAsEnBc,EAAO,CAACsf,IAAKC,IAAQ5M,IAAOJ,IAASmB,EAAM,GAAGxX,GAAc,SAAS,CAAC;AAEtE8D,EAAO,CAACoT,IAAMsF,IAAUF,IAASL,EAAI,GAAGjc,GAAc,QAAQ,CAAC;AAE/D8D,EAAO8f,IAAM5jB,GAAc,MAAM,CAAC;AAClC8D,EAAOmY,IAAMjc,GAAc,MAAM,CAAC;AAElC8D,EAAO8R,IAAM5V,GAAc,MAAM,CAAC;AAElC8D,EAAO,CAAC8f,IAAMQ,EAAK,GAAGpkB,GAAc,OAAO,CAAC;AAE5C8D,EAAO,CAAC2Y,IAAM3G,IAASK,IAAU8I,EAAM,GAAGjf,GAAc,QAAQ,CAAC;AAEjE8D,EAAOkO,IAAahS,GAAc,aAAa,CAAC;AAChD8D,EAAOkP,IAAKhT,GAAc,KAAK,CAAC;AAChC8D,EAAOgK,IAAS9N,GAAc,SAAS,CAAC;AACxC8D,EAAO+R,IAAO7V,GAAc,OAAO,CAAC;AACpC8D,EAAO,CAAC4R,IAAWM,EAAQ,GAAGhW,GAAc,WAAW,CAAC;AACxD8D,EAAOqS,IAAUnW,GAAc,UAAU,CAAC;AAE1C8D,EAAOmb,IAAQjf,GAAc,QAAQ,CAAC;AAEtCmQ,GAAK,OAAOlQ,GAAc,CAAE;AAE5B4b,GAAsB;AAAA,EACpBxJ;AAAA,EACAnK;AAAA,EACAgH;AAAA,EACA5D;AAAAA,EACA8G;AAAA,EACAuE;AAAA,EACAmE;AAAA,EACA3P;AACF,CAAC;AAED2Q,GAAa;ACvKb,MAAMmK,KAAqB,CAACrU,OACtBA,EAAG,mBACLA,IAAKA,EAAG,eAAe,CAAC,IAEnB,EAAE,GAAGA,EAAG,SAAS,GAAGA,EAAG,QAAO;AAIvC,MAAMsU,GAAY;AAAA,EAChB,YAAY3f,GAAI;AACd,IAAAA,EAAG,SAAS,cAAc,IAAI,GAC9B,KAAK,KAAKA,GAEV,KAAK,OAAO,KAAK,KAAK,KAAK,IAAI,GAC/B,KAAK,YAAY,KAAK,UAAU,KAAK,IAAI,GACzC,KAAK,UAAU,KAAK,QAAQ,KAAK,IAAI;AAAA,EACvC;AAAA;AAAA,EAGA,KAAK8Y,GAAS;AACZ,IAAIA,KACF,KAAK,GAAG,GAAG,kBAAkB,KAAK,SAAS,GAC3C,KAAK,GAAG,GAAG,mBAAmB,KAAK,WAAW,EAAE,SAAS,GAAK,CAAE,MAEhE,KAAK,GAAG,IAAI,gBAAgB,GAC5B,KAAK,GAAG,IAAI,iBAAiB;AAAA,EAEjC;AAAA;AAAA,EAGA,UAAUzN,GAAI;AACZ,UAAMuU,IAAU,CAACvU,EAAG,KAAK,QAAQ,OAAO;AAQxC,QALIuU,KAAWvU,EAAG,UAAU,KAAKA,EAAG,YAAY,KAM9C,KAAK,GAAG,SAAS,cAAc,EAAE,OAAOA,GAAI,SAAS,KAAI,CAAE,EACxD;AAEH;AAIF,IAAAA,EAAG,eAAc,GAGjBA,EAAG,gBAAe,GAIlB,KAAK,KAAK,EAAK,GAEf,KAAK,MAAM,KAAK,GAAG,KAAI,GACvB,KAAK,YAAY,KAAK,GAAG,MAAMqU,GAAmBrU,CAAE,CAAC;AAErD,UAAMwU,KAAaD,IAAU,cAAc,eAAe,SACpDE,KAAYF,IAAU,YAAY,cAAc;AAGtD,IAAA9U,GAAG,QAAQ+U,GAAW,KAAK,MAAM,MAAM,EAAE,SAAS,GAAK,CAAE,GACzD/U,GAAG,QAAQgV,GAAU,KAAK,SAAS,MAAM,EAAE,SAAS,GAAK,CAAE,GAG3D,KAAK,GAAG,KAAK,aAAa,EAAE,OAAOzU,GAAI,SAAS,MAAM,KAAK,KAAK,IAAG,CAAE;AAAA,EACvE;AAAA;AAAA,EAGA,KAAKA,GAAI;AACP,UAAM,EAAE,KAAAxQ,GAAK,WAAAklB,MAAc,MAErBC,IAAe,KAAK,GAAG,MAAMN,GAAmBrU,CAAE,CAAC,GACnD3E,IAAKsZ,EAAa,IAAID,EAAU,GAChCpZ,IAAKqZ,EAAa,IAAID,EAAU;AAEtC,QAAI,CAACrZ,KAAM,CAACC,EAAI,QAAO9L;AAEvB,UAAMQ,IAAIR,EAAI,IAAI6L,GACZpL,IAAIT,EAAI,IAAI8L;AAIlB,IAHA,KAAK,MAAM,IAAIgC,EAAItN,GAAGC,GAAGT,EAAI,GAAGA,EAAI,CAAC,GACrC,KAAK,YAAYmlB,GAGf,MAAK,GAAG,SAAS,YAAY;AAAA,MAC3B,OAAO3U;AAAA,MACP,SAAS;AAAA,MACT,KAAK,KAAK;AAAA,MACV,IAAA3E;AAAA,MACA,IAAAC;AAAA,IACR,CAAO,EAAE,oBAKL,KAAK,KAAKtL,GAAGC,CAAC;AAAA,EAChB;AAAA,EAEA,KAAKD,GAAGC,GAAG;AAIT,IAAI,KAAK,GAAG,SAAS,QACnB+iB,GAAE,UAAU,KAAK,KAAK,KAAK,IAAIhjB,GAAGC,CAAC,IAEnC,KAAK,GAAG,KAAKD,GAAGC,CAAC;AAAA,EAErB;AAAA,EAEA,QAAQ+P,GAAI;AAEV,SAAK,KAAKA,CAAE,GAGZ,KAAK,GAAG,KAAK,WAAW,EAAE,OAAOA,GAAI,SAAS,MAAM,KAAK,KAAK,IAAG,CAAE,GAGnEC,GAAI,QAAQ,gBAAgB,GAC5BA,GAAI,QAAQ,gBAAgB,GAC5BA,GAAI,QAAQ,cAAc,GAC1BA,GAAI,QAAQ,eAAe,GAG3B,KAAK,KAAK,EAAI;AAAA,EAChB;AACF;AAEA/N,EAAOgK,IAAS;AAAA,EACd,UAAU0Y,IAAS,IAAM;AAEvB,YADoB,KAAK,SAAS,YAAY,KAAK,IAAIN,GAAY,IAAI,GAC3D,KAAKM,CAAM,GAChB;AAAA,EACT;AACF,CAAC;AC7HD,IAAIC,KAAiB,SAAwB7U,GAAI;AAC/C,SAAOA,EAAG,WAAW,CAAC;AAAA,IACpB,SAASA,EAAG;AAAA,IACZ,SAASA,EAAG;AAAA,EAChB,CAAG;AACH;AAEA9N,EAAOsf,IAAK;AAAA,EACV,SAAS,SAAiB3R,GAAS;AACjC,QAAIiV,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAlT,IAAQ;AAIZ,QAFA,KAAK,IAAI,UAAU,GAEf1C,MAAY,GAAO,QAAO;AAC9B,IAAAA,KAAWiV,IAAWjV,MAAY,OAAOiV,IAAW,CAAA;AACpD,QAAIY,KAAcX,IAAsBlV,EAAQ,eAAe,OAAOkV,IAAsB,GACxFY,KAAWX,IAAmBnV,EAAQ,YAAY,OAAOmV,IAAmB,OAAO,WACnFY,KAAWX,IAAmBpV,EAAQ,YAAY,OAAOoV,IAAmB,OAAO,WACnFY,KAAeX,IAAqBrV,EAAQ,cAAc,OAAOqV,IAAqB,IACtFY,KAAeX,IAAqBtV,EAAQ,cAAc,OAAOsV,IAAqB,IACtFY,KAAaX,IAAmBvV,EAAQ,YAAY,OAAOuV,IAAmB,IAC9EY,KAAaX,IAAqBxV,EAAQ,cAAc,OAAOwV,IAAqB,GACpFY,KAAgBX,IAAwBzV,EAAQ,iBAAiB,OAAOyV,IAAwB,IAChGY,KAAWX,IAAmB1V,EAAQ,YAAY,OAAO0V,IAAmB,IAC5EY,KAAgCX,IAAwB3V,EAAQ,iCAAiC,OAAO2V,IAAwB,IAChIY,KAAkCX,IAAyB5V,EAAQ,mCAAmC,OAAO4V,IAAyB,IACtIY,GACAC,GACAC,IAAiB,IACjBC,IAAU,KAAK,QAAO,GAEtBC,IAAoB,SAA2BjnB,GAAK;AACtD,UAAI,CAAC0mB,EAAS,QAAO1mB;AACrB,UAAIknB,IAAMR,EAAQ,KACdS,IAAOT,EAAQ,MACfU,KAASV,EAAQ,QACjBW,KAAQX,EAAQ,OAEhBY,KAAavU,EAAM,KAAK,CAAC,SAAS,QAAQ,CAAC,GAC3CjT,KAAQwnB,GAAW,OACnBvnB,KAASunB,GAAW,QAEpBC,IAAsBxU,EAAM,KAAK,oBAAoB,SAKrDyU,KAAqB,GACrBC,KAAsB,GACtBC,KAAoB,GACpBC,KAAuB;AAE3B,UAAIJ,EAAoB,UAAUA,EAAoB,8BAA8B;AAClF,YAAIK,KAAiB9nB,KAAQC,IACzB8nB,KAAqBb,EAAQ,QAAQA,EAAQ;AAEjD,YAAIa,OAAuBD,IAAgB;AAEzC,cAAIE,KAASP,EAAoB,gBAAgBA,EAAoB,uBACjEQ,KAAcH,KAAiBC,KAAqB,UAAU,UAC9DG,KAAUD,OAAgB,SAC1BE,KAAmBH,MAAUE,MAAW,CAACF,MAAU,CAACE,IACpDE,KAAQD,KAAmBL,KAAiBC,KAAqBA,KAAqBD,IACtF7D,KAAS/jB,EAAI+nB,EAAW,IAAI/nB,EAAI+nB,EAAW,IAAIG;AAEnD,UAAID,KACEV,EAAoB,UAAUA,EAAoB,oCAAoCA,EAAoB,UAAUA,EAAoB,oCAAoCA,EAAoB,UAAUA,EAAoB,oCAChOC,KAAqBzD,KAAS,GAC9B0D,KAAsB,CAAC1D,KAAS,KACvBwD,EAAoB,UAAUA,EAAoB,oCAAoCA,EAAoB,UAAUA,EAAoB,oCAAoCA,EAAoB,UAAUA,EAAoB,mCACvOE,KAAsB,CAAC1D,MACdwD,EAAoB,UAAUA,EAAoB,oCAAoCA,EAAoB,UAAUA,EAAoB,oCAAoCA,EAAoB,UAAUA,EAAoB,sCACvOC,KAAqBzD,MAGnBwD,EAAoB,UAAUA,EAAoB,oCAAoCA,EAAoB,UAAUA,EAAoB,oCAAoCA,EAAoB,UAAUA,EAAoB,oCAChOG,KAAoB3D,KAAS,GAC7B4D,KAAuB,CAAC5D,KAAS,KACxBwD,EAAoB,UAAUA,EAAoB,oCAAoCA,EAAoB,UAAUA,EAAoB,oCAAoCA,EAAoB,UAAUA,EAAoB,mCACvOI,KAAuB,CAAC5D,MACfwD,EAAoB,UAAUA,EAAoB,oCAAoCA,EAAoB,UAAUA,EAAoB,oCAAoCA,EAAoB,UAAUA,EAAoB,sCACvOG,KAAoB3D;AAAA,QAG1B;AAAA,MACF;AASA,UAAIoE,KAAYnB,EAAQ,QAAQA,EAAQ,IAAIG,IAAOK,IAQ/CY,KAAapB,EAAQ,IAAIK,KAAQrnB,EAAI,QAAQynB,IAE7CY,KAAWrB,EAAQ,SAASA,EAAQ,IAAIE,IAAMQ,IAC9CY,KAActB,EAAQ,IAAII,KAASpnB,EAAI,SAAS2nB;AACpD,aAAA3nB,EAAI,IAAI,KAAK,IAAImoB,IAAW,KAAK,IAAIC,IAAYpoB,EAAI,CAAC,CAAC,GAEvDA,EAAI,IAAI,KAAK,IAAIqoB,IAAU,KAAK,IAAIC,IAAatoB,EAAI,CAAC,CAAC,GAEhDA;AAAA,IACT,GAEIuoB,IAAY,SAAmB/X,GAAI;AACrC,MAAAA,EAAG,eAAc;AAWjB,UAAIgY;AAEJ,cAAQhY,EAAG,WAAS;AAAA,QAClB,KAAK;AACH,UAAAgY,IAAwBhY,EAAG,SAASmW;AACpC;AAAA,QAEF,KAAK;AACH,UAAA6B,IAAwBhY,EAAG,SAASoW;AACpC;AAAA,QAEF;AAEE,UAAA4B,IAAwBhY,EAAG;AAC3B;AAAA,MACV;AAEM,UAAIiY,IAAM,KAAK,IAAI,IAAIvC,GAAY,KAAKsC,IAAwB,GAAG,IAAI,KAAK,KAAI,GAC5E5hB,KAAI,KAAK,MAAM4J,EAAG,SAASA,EAAG,OAAO;AAUzC,UARIiY,IAAMrC,MACRqC,IAAMrC,IAGJqC,IAAMtC,MACRsC,IAAMtC,IAGJ,KAAK,SAAS,QAAQ;AAAA,QACxB,OAAOsC;AAAA,QACP,OAAO7hB;AAAA,MACf,CAAO,EAAE;AACD,eAAO;AAKT,UAFA,KAAK,KAAK6hB,GAAK7hB,EAAC,GAEZ8f,GAAS;AACX,YAAI1mB,KAAMinB,EAAkB,KAAK,QAAO,CAAE;AAC1C,aAAK,QAAQjnB,EAAG;AAAA,MAClB;AAAA,IACF,GAEI0oB,IAAiB,SAASA,EAAelY,GAAI;AAG/C,UAFAsW,IAAczB,GAAe7U,CAAE,GAE3BsW,EAAY,SAAS,GAAG;AAC1B,QAAIP,KAAaE,KACfkC,GAAS,KAAK,MAAMnY,CAAE;AAGxB;AAAA,MACF;AAWA,MARI+V,KAAaE,KACfmC,GAAQ,KAAK,MAAMpY,CAAE,GAKvBA,EAAG,eAAc,GAEb,MAAK,SAAS,kBAAkB;AAAA,QAClC,OAAOA;AAAA,MACf,CAAO,EAAE,qBAIH,KAAK,IAAI,sBAAsBkY,CAAc,GAC7C3B,IAAiB,IACjB9W,GAAG,UAAU,qBAAqB4Y,IAAW,MAAM;AAAA,QACjD,SAAS;AAAA,MACjB,CAAO,GACD5Y,GAAG,UAAU,oBAAoB6Y,GAAe,MAAM;AAAA,QACpD,SAAS;AAAA,MACjB,CAAO;AAAA,IACH,GAEIA,IAAgB,SAASA,EAActY,GAAI;AAC7C,MAAAA,EAAG,eAAc;AACjB,UAAIuY,IAAiB1D,GAAe7U,CAAE;AAEtC,MAAIuY,EAAe,SAAS,MAI5BhC,IAAiB,IACjB,KAAK,SAAS,gBAAgB;AAAA,QAC5B,OAAOvW;AAAA,MACf,CAAO,GACDC,GAAI,UAAU,qBAAqBoY,EAAS,GAC5CpY,GAAI,UAAU,oBAAoBqY,CAAa,GAC/C,KAAK,GAAG,sBAAsBJ,CAAc,GAExCK,EAAe,UAAUxC,KAAaE,KACxCkC,GAAS,KAAK,MAAMnY,CAAE;AAAA,IAE1B,GAEIqY,KAAY,SAAmBrY,GAAI;AACrC,MAAAA,EAAG,eAAc;AACjB,UAAIuY,IAAiB1D,GAAe7U,CAAE,GAClC3B,IAAO,KAAK,QAEZma,KAAY,KAAK,KAAK,KAAK,IAAIlC,EAAY,CAAC,EAAE,UAAUA,EAAY,CAAC,EAAE,SAAS,CAAC,IAAI,KAAK,IAAIA,EAAY,CAAC,EAAE,UAAUA,EAAY,CAAC,EAAE,SAAS,CAAC,CAAC,GACjJmC,KAAe,KAAK,KAAK,KAAK,IAAIF,EAAe,CAAC,EAAE,UAAUA,EAAe,CAAC,EAAE,SAAS,CAAC,IAAI,KAAK,IAAIA,EAAe,CAAC,EAAE,UAAUA,EAAe,CAAC,EAAE,SAAS,CAAC,CAAC,GAChKja,KAAaka,KAAYC;AAE7B,OAAIpa,IAAOsX,KAAWrX,KAAa,KAAKD,IAAOuX,KAAWtX,KAAa,OACrEA,KAAa;AAGf,UAAIoa,KAAe;AAAA,QACjB,GAAGH,EAAe,CAAC,EAAE,UAAU,OAAOA,EAAe,CAAC,EAAE,UAAUA,EAAe,CAAC,EAAE;AAAA,QACpF,GAAGA,EAAe,CAAC,EAAE,UAAU,OAAOA,EAAe,CAAC,EAAE,UAAUA,EAAe,CAAC,EAAE;AAAA,MAC5F,GACUI,KAAY;AAAA,QACd,GAAGrC,EAAY,CAAC,EAAE,UAAU,OAAOA,EAAY,CAAC,EAAE,UAAUA,EAAY,CAAC,EAAE;AAAA,QAC3E,GAAGA,EAAY,CAAC,EAAE,UAAU,OAAOA,EAAY,CAAC,EAAE,UAAUA,EAAY,CAAC,EAAE;AAAA,MACnF,GACUlgB,IAAI,KAAK,MAAMsiB,GAAa,GAAGA,GAAa,CAAC,GAC7CE,KAAS,KAAK,MAAM,IAAIF,GAAa,IAAIC,GAAU,GAAG,IAAID,GAAa,IAAIC,GAAU,CAAC,GACtFnpB,KAAM,IAAI8N,EAAI,KAAK,QAAO,CAAE,EAAE,UAAU,IAAI5D,EAAM,EAAG,UAAU,CAACkf,GAAO,GAAG,CAACA,GAAO,CAAC,EAAE,MAAMta,IAAY,GAAG,CAAC,EAAE,UAAUlI,EAAE,GAAGA,EAAE,CAAC,CAAC;AACpI,MAAAqgB,EAAkBjnB,EAAG,GACrB,KAAK,QAAQA,EAAG,GAChB8mB,IAAciC,GACd,KAAK,SAAS,QAAQ;AAAA,QACpB,KAAK/oB;AAAA,QACL,OAAOopB;AAAA,MACf,CAAO;AAAA,IACH,GAEIT,KAAW,SAASA,EAASnY,GAAI;AACnC,UAAIuU,IAAUvU,EAAG,KAAK,QAAQ,OAAO,IAAI;AAEzC,MAAIuU,KAAWvU,EAAG,WAAWgW,KAAahW,EAAG,UAAUgW,IAAY,MAInEhW,EAAG,eAAc,GACjB,KAAK,IAAI,qBAAqBmY,CAAQ,GACtC7B,IAAczB,GAAe7U,CAAE,GAC3B,CAAAuW,MACJ,KAAK,SAAS,YAAY;AAAA,QACxB,OAAOvW;AAAA,MACf,CAAO,GACDqW,IAAQ;AAAA,QACN,GAAGC,EAAY,CAAC,EAAE;AAAA,QAClB,GAAGA,EAAY,CAAC,EAAE;AAAA,MAC1B,GACM7W,GAAG,UAAU,uCAAuCoZ,IAAS,MAAM;AAAA,QACjE,SAAS;AAAA,MACjB,CAAO,GACDpZ,GAAG,UAAU,oCAAoC2Y,IAAS,MAAM;AAAA,QAC9D,SAAS;AAAA,MACjB,CAAO;AAAA,IACH,GAEIA,KAAU,SAASA,EAAQpY,GAAI;AACjC,MAAAA,EAAG,eAAc,GACjBC,GAAI,UAAU,uCAAuC4Y,EAAO,GAC5D5Y,GAAI,UAAU,oCAAoCmY,CAAO,GACzD,KAAK,GAAG,qBAAqBD,EAAQ,GACrC,KAAK,SAAS,UAAU;AAAA,QACtB,OAAOnY;AAAA,MACf,CAAO;AAAA,IACH,GAEI6Y,KAAU,SAAiB7Y,GAAI;AACjC,MAAAA,EAAG,eAAc;AACjB,UAAIuY,IAAiB1D,GAAe7U,CAAE,GAClC8Y,IAAW;AAAA,QACb,GAAGP,EAAe,CAAC,EAAE;AAAA,QACrB,GAAGA,EAAe,CAAC,EAAE;AAAA,MAC7B,GACUQ,KAAK,KAAK,MAAMD,EAAS,GAAGA,EAAS,CAAC,GACtCE,KAAK,KAAK,MAAM3C,EAAM,GAAGA,EAAM,CAAC,GAChC4C,KAAS,CAACD,GAAG,IAAID,GAAG,GAAGC,GAAG,IAAID,GAAG,CAAC;AAEtC,UAAI,GAACE,GAAO,CAAC,KAAK,CAACA,GAAO,CAAC,IAI3B;AAAA,YAAIzpB,KAAM,IAAI8N,EAAI,KAAK,QAAO,CAAE,EAAE,UAAU,IAAI5D,EAAM,EAAG,UAAUuf,GAAO,CAAC,GAAGA,GAAO,CAAC,CAAC,CAAC;AAIxF,QAHA5C,IAAQyC,GACRrC,EAAkBjnB,EAAG,GAEjB,MAAK,SAAS,WAAW;AAAA,UAC3B,KAAKA;AAAA,UACL,OAAOwQ;AAAA,QACf,CAAO,EAAE,oBAIH,KAAK,QAAQxQ,EAAG;AAAA;AAAA,IAClB;AAEA,WAAIqmB,KACF,KAAK,GAAG,iBAAiBkC,GAAW,MAAM;AAAA,MACxC,SAAS;AAAA,IACjB,CAAO,GAGCjC,KACF,KAAK,GAAG,sBAAsBoC,GAAgB,MAAM;AAAA,MAClD,SAAS;AAAA,IACjB,CAAO,GAGCnC,KACF,KAAK,GAAG,qBAAqBoC,IAAU,MAAM;AAAA,MAC3C,SAAS;AAAA,IACjB,CAAO,GAGI;AAAA,EACT;AACF,CAAC;AC/WD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA,SAASe,GAAgBC,GAAWxkB,GAAIyQ,GAAQrB,IAAQ,MAAM;AAC5D,SAAO,SAAS/D,GAAI;AAClB,IAAAA,EAAG,eAAc,GACjBA,EAAG,gBAAe;AAClB,QAAIhQ,IAAIgQ,EAAG,SAASA,EAAG,QAAQ,CAAC,EAAE,OAC9B/P,IAAI+P,EAAG,SAASA,EAAG,QAAQ,CAAC,EAAE;AAClC,IAAArL,EAAG,KAAKwkB,GAAW,EAAE,GAAAnpB,GAAG,GAAAC,GAAG,OAAO+P,GAAI,OAAA+D,GAAO,QAAAqB,GAAQ;AAAA,EACvD;AACF;AACA,SAASgU,GAAe,CAACppB,GAAGC,CAAC,GAAG,EAAE,GAAAgF,GAAG,GAAAe,GAAG,GAAA3B,GAAG,GAAAtF,GAAG,GAAAiM,GAAG,GAAAC,EAAC,GAAI;AACpD,SAAO,CAACjL,IAAIiF,IAAIhF,IAAIoE,IAAI2G,GAAGhL,IAAIgG,IAAI/F,IAAIlB,IAAIkM,CAAC;AAC9C;AACA,MAAMoe,GAAc;AAAA,EAClB,YAAY1kB,GAAI;AACd,SAAK,KAAKA,GACVA,EAAG,SAAS,kBAAkB,IAAI,GAClC,KAAK,YAAY,IAAIqe,GAAC,GACtB,KAAK,QAAQ,CAAC,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,KAAK,GAC/D,KAAK,kBAAkB,KAAK,gBAAgB,KAAK,IAAI;AACrD,UAAMsG,IAAMxoB,GAAS;AACrB,SAAK,WAAW,IAAIwoB,EAAI,iBAAiB,KAAK,eAAe;AAAA,EAC/D;AAAA,EACA,KAAKzZ,GAAS;AACZ,SAAK,eAAeA,EAAQ,gBAAgB,KAAK,gBACjD,KAAK,YAAYA,EAAQ,aAAa,KAAK,aAC3C,KAAK,eAAeA,EAAQ,gBAAgB,KAAK,gBACjD,KAAK,YAAYA,EAAQ,aAAa,KAAK,aAC3C,KAAK,GAAG,KAAI,EAAG,IAAI,KAAK,SAAS,GACjC,KAAK,aAAY,GACjB,KAAK,gBAAe,GACpB,KAAK,oBAAmB,GACxB,KAAK,oBAAmB,GACxB,KAAK,qBAAoB,GACzB,KAAK,qBAAoB,GACzB,KAAK,SAAS,QAAQ,KAAK,GAAG,MAAM,EAAE,YAAY,IAAM;AAAA,EAC1D;AAAA,EACA,OAAOpL,GAAKoL,GAAS;AACnB,QAAI,CAACpL,GAAK;AACR,WAAK,UAAU,MAAK,EAAG,OAAM,GAC7B,KAAK,SAAS,WAAU;AACxB;AAAA,IACF;AACA,SAAK,KAAKoL,CAAO;AAAA,EACnB;AAAA,EACA,kBAAkB;AAChB,SAAK,UAAU,QAAQ,KAAK,YAAY,EAAE,SAAS,kBAAkB;AAAA,EACvE;AAAA,EACA,kBAAkB;AAChB,SAAK,UAAU,IAAI,CAAC,EAAE,KAAK,KAAK,YAAY;AAAA,EAC9C;AAAA,EACA,sBAAsB;AACpB,SAAK,aAAa,QAAQ,CAACzJ,GAAG2N,GAAOvF,MAAQ;AAC3C,YAAMxQ,IAAO,KAAK,MAAM+V,CAAK;AAC7B,WAAK,aAAa,KAAK,MAAM,KAAK,WAAW3N,GAAG2N,GAAOvF,GAAKxQ,CAAI,GAChE,KAAK,UAAU,IAAI+V,IAAQ,CAAC,EAAE,SAAS,yCAAyC/V,CAAI,EAAE,GAAG,4CAA4CkrB,GAAgBlrB,GAAM,KAAK,IAAI,KAAK,cAAc+V,CAAK,CAAC;AAAA,IAC/L,CAAC;AAAA,EACH;AAAA,EACA,eAAewV,GAAO;AACpB,IAAAA,EAAM,SAAQ;AAAA,EAChB;AAAA,EACA,eAAeC,GAAO7f,GAAOoK,GAAOvF,GAAK;AACvC,UAAMzL,IAASyL,EAAI,GAAGuF,IAAQ,CAAC,GACzBtR,IAAO+L,GAAKuF,IAAQ,KAAKvF,EAAI,MAAM,GACnCpI,IAAIuD,GACJ8f,IAAQ,CAACrjB,EAAE,CAAC,IAAIrD,EAAO,CAAC,GAAGqD,EAAE,CAAC,IAAIrD,EAAO,CAAC,CAAC,GAC3C2mB,IAAQ,CAACtjB,EAAE,CAAC,IAAI3D,EAAK,CAAC,GAAG2D,EAAE,CAAC,IAAI3D,EAAK,CAAC,CAAC,GACvCknB,IAAO,KAAK,KAAKF,EAAM,CAAC,IAAIA,EAAM,CAAC,IAAIA,EAAM,CAAC,IAAIA,EAAM,CAAC,CAAC,GAC1DG,IAAO,KAAK,KAAKF,EAAM,CAAC,IAAIA,EAAM,CAAC,IAAIA,EAAM,CAAC,IAAIA,EAAM,CAAC,CAAC,GAC1DG,IAAc,CAACJ,EAAM,CAAC,IAAIE,GAAMF,EAAM,CAAC,IAAIE,CAAI,GAC/CG,IAAc,CAACJ,EAAM,CAAC,IAAIE,GAAMF,EAAM,CAAC,IAAIE,CAAI,GAC/CG,IAAY,CAAC3jB,EAAE,CAAC,IAAIyjB,EAAY,CAAC,IAAI,IAAIzjB,EAAE,CAAC,IAAIyjB,EAAY,CAAC,IAAI,EAAE,GACnEG,IAAU,CAAC5jB,EAAE,CAAC,IAAI0jB,EAAY,CAAC,IAAI,IAAI1jB,EAAE,CAAC,IAAI0jB,EAAY,CAAC,IAAI,EAAE;AACvE,IAAAN,EAAM,KAAK,CAACO,GAAW3jB,GAAG4jB,CAAO,CAAC;AAAA,EACpC;AAAA,EACA,sBAAsB;AACpB,SAAK,aAAa,QAAQ,CAAC5jB,GAAG2N,GAAOvF,MAAQ;AAC3C,YAAMxQ,IAAO,KAAK,MAAM+V,CAAK;AAC7B,WAAK,aAAa,KAAK,MAAM,KAAK,UAAU,IAAIA,IAAQ,CAAC,GAAG3N,GAAG2N,GAAOvF,GAAKxQ,CAAI;AAAA,IACjF,CAAC;AAAA,EACH;AAAA,EACA,YAAYurB,GAAO;AACjB,IAAAA,EAAM,KAAI,GACVA,EAAM,OAAO,CAAC;AAAA,EAChB;AAAA,EACA,SAASvrB,GAAM;AACb,WAAO,KAAK,aAAa,KAAK,MAAM,QAAQA,CAAI,CAAC;AAAA,EACnD;AAAA,EACA,eAAeA,GAAM;AACnB,WAAO,KAAK,UAAU,IAAI,KAAK,MAAM,QAAQA,CAAI,IAAI,CAAC;AAAA,EACxD;AAAA,EACA,YAAYurB,GAAOU,GAAU;AAC3B,UAAMC,IAAW,KAAK,SAAS,GAAG;AAClC,IAAAX,EAAM,IAAI,CAAC,EAAE,KAAKW,EAAS,CAAC,GAAGA,EAAS,CAAC,GAAGD,EAAS,CAAC,GAAGA,EAAS,CAAC,CAAC,GACpEV,EAAM,IAAI,CAAC,EAAE,OAAOU,EAAS,CAAC,GAAGA,EAAS,CAAC,CAAC;AAAA,EAC9C;AAAA,EACA,uBAAuB;AACrB,UAAME,IAAS,KAAK,UAAU,MAAK,EAAG,SAAS,uBAAuB,EAAE,GAAG,4CAA4CjB,GAAgB,OAAO,KAAK,IAAI,KAAK,YAAY,CAAC;AACzK,SAAK,UAAU,KAAK,MAAMiB,CAAM;AAAA,EAClC;AAAA,EACA,uBAAuB;AACrB,UAAMZ,IAAQ,KAAK,UAAU,QAAQ,yBAAyB;AAC9D,SAAK,UAAUA,GAAO,KAAK,eAAe,KAAK,YAAY;AAAA,EAC7D;AAAA;AAAA,EAEA,eAAe;AACb,UAAMzb,IAAO,KAAK,GAAG,KAAI,GACnBsc,IAAsB,KAAK,GAAG,KAAI,EAAG,UAAS,EAAG,SAAQ,EAAG,UAAU,KAAK,GAAG,UAAS,CAAE;AAC/F,SAAK,eAAe,KAAK,gBAAgBtc,CAAI,EAAE,IAAI,CAAC1H,MAAMgjB,GAAehjB,GAAGgkB,CAAmB,CAAC,GAChG,KAAK,gBAAgBhB,GAAe,KAAK,iBAAiBtb,CAAI,GAAGsc,CAAmB;AAAA,EACtF;AAAA;AAAA,EAEA,gBAAgB,EAAE,GAAApqB,GAAG,IAAAyV,GAAI,GAAAxV,GAAG,IAAAyV,GAAI,IAAAxK,GAAI,IAAAC,MAAO,KAAK,GAAG,KAAI,GAAI;AACzD,WAAO;AAAA,MACL,CAACnL,GAAGC,CAAC;AAAA,MACL,CAACiL,GAAIjL,CAAC;AAAA,MACN,CAACwV,GAAIxV,CAAC;AAAA,MACN,CAACwV,GAAItK,CAAE;AAAA,MACP,CAACsK,GAAIC,CAAE;AAAA,MACP,CAACxK,GAAIwK,CAAE;AAAA,MACP,CAAC1V,GAAG0V,CAAE;AAAA,MACN,CAAC1V,GAAGmL,CAAE;AAAA,IACZ;AAAA,EACE;AAAA;AAAA,EAEA,iBAAiB,EAAE,GAAAlL,GAAG,IAAAiL,EAAE,IAAK,KAAK,GAAG,QAAQ;AAC3C,WAAO,CAACA,GAAIjL,IAAI,EAAE;AAAA,EACpB;AAAA,EACA,kBAAkB;AAChB,SAAK,aAAY,GACjB,KAAK,gBAAe,GACpB,KAAK,oBAAmB,GACxB,KAAK,qBAAoB;AAAA,EAC3B;AACF;AACA,MAAMoqB,GAAmB;AAAA,EACvB,YAAY1lB,GAAI;AACd,SAAK,KAAKA,GACVA,EAAG,SAAS,uBAAuB,IAAI,GACvC,KAAK,YAAY,IAAIqe,GAAC,GACtB,KAAK,QAAQ,CAAC,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,KAAK,GAC/D,KAAK,kBAAkB,KAAK,gBAAgB,KAAK,IAAI;AACrD,UAAMsG,IAAMxoB,GAAS;AACrB,SAAK,WAAW,IAAIwoB,EAAI,iBAAiB,KAAK,eAAe;AAAA,EAC/D;AAAA,EACA,KAAKzZ,GAAS;AACZ,SAAK,eAAeA,EAAQ,gBAAgB,KAAK,gBACjD,KAAK,eAAeA,EAAQ,gBAAgB,KAAK,gBACjD,KAAK,GAAG,KAAI,EAAG,IAAI,KAAK,SAAS,GACjC,KAAK,aAAY,GACjB,KAAK,gBAAe,GACpB,KAAK,mBAAkB,GACvB,KAAK,mBAAkB,GACvB,KAAK,SAAS,QAAQ,KAAK,GAAG,MAAM,EAAE,YAAY,IAAM;AAAA,EAC1D;AAAA,EACA,OAAOpL,GAAKoL,GAAS;AACnB,QAAI,CAACpL,GAAK;AACR,WAAK,UAAU,MAAK,EAAG,OAAM,GAC7B,KAAK,SAAS,WAAU;AACxB;AAAA,IACF;AACA,SAAK,KAAKoL,CAAO;AAAA,EACnB;AAAA,EACA,kBAAkB;AAChB,SAAK,UAAU,QAAQ,KAAK,MAAM,EAAE,SAAS,8BAA8B;AAAA,EAC7E;AAAA,EACA,kBAAkB;AAChB,SAAK,UAAU,IAAI,CAAC,EAAE,KAAK,KAAK,MAAM;AAAA,EACxC;AAAA,EACA,qBAAqB;AACnB,SAAK,OAAO,QAAQ,CAACzJ,GAAG2N,GAAOvF,MAAQ;AACrC,WAAK,aAAa,KAAK,MAAM,KAAK,WAAWpI,GAAG2N,GAAOvF,CAAG,GAC1D,KAAK,UAAU,IAAIuF,IAAQ,CAAC,EAAE,SAAS,yBAAyB,EAAE,GAAG,4CAA4CmV,GAAgB,SAAS,KAAK,IAAI,KAAK,QAAQnV,CAAK,CAAC;AAAA,IACxK,CAAC;AAAA,EACH;AAAA,EACA,eAAewV,GAAO;AACpB,IAAAA,EAAM,OAAO,CAAC;AAAA,EAChB;AAAA,EACA,eAAeC,GAAO7f,GAAO;AAC3B,IAAA6f,EAAM,OAAO7f,EAAM,CAAC,GAAGA,EAAM,CAAC,CAAC;AAAA,EACjC;AAAA,EACA,qBAAqB;AACnB,SAAK,OAAO,QAAQ,CAACvD,GAAG2N,GAAOvF,MAAQ;AACrC,WAAK,aAAa,KAAK,MAAM,KAAK,UAAU,IAAIuF,IAAQ,CAAC,GAAG3N,GAAG2N,GAAOvF,CAAG;AAAA,IAC3E,CAAC;AAAA,EACH;AAAA;AAAA,EAEA,eAAe;AACb,UAAM4b,IAAsB,KAAK,GAAG,KAAI,EAAG,UAAS,EAAG,SAAQ,EAAG,UAAU,KAAK,GAAG,UAAS,CAAE;AAC/F,SAAK,SAAS,KAAK,GAAG,MAAK,EAAG,IAAI,CAAChkB,MAAMgjB,GAAehjB,GAAGgkB,CAAmB,CAAC;AAAA,EACjF;AAAA,EACA,kBAAkB;AAChB,SAAK,aAAY,GACjB,KAAK,gBAAe,GACpB,KAAK,mBAAkB;AAAA,EACzB;AACF;AACA,MAAME,KAAc,CAACC,MACZ,SAAS9M,IAAU,IAAM5N,IAAU,CAAA,GAAI;AAC5C,EAAI,OAAO4N,KAAY,aACrB5N,IAAU4N,GACVA,IAAU;AAEZ,MAAI+M,IAAgB,KAAK,SAAS,MAAMD,EAAY,IAAI;AACxD,SAAKC,MACC/M,EAAQ,qBAAqB4L,MAC/BmB,IAAgB,IAAI/M,EAAQ,IAAI,GAChCA,IAAU,MAEV+M,IAAgB,IAAID,EAAY,IAAI,GAEtC,KAAK,SAAS,MAAMA,EAAY,MAAMC,CAAa,IAErDA,EAAc,OAAO/M,GAAS5N,CAAO,GAC9B;AACT;AAEF3N,EAAOgK,IAAS;AAAA,EACd,QAAQoe,GAAYjB,EAAa;AACnC,CAAC;AACDnnB,EAAO,CAACwY,IAASE,IAAUtF,EAAI,GAAG;AAAA,EAChC,aAAagV,GAAYD,EAAkB;AAC7C,CAAC;ACzOD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaA,MAAMhG,KAAqB,CAACrU,OACtBA,EAAG,mBACLA,IAAKA,EAAG,eAAe,CAAC,IAEnB,EAAE,GAAGA,EAAG,SAAS,GAAGA,EAAG,QAAO,IAEjCya,KAAmB,CAACrV,MAAW;AACnC,MAAIpV,IAAI,OACJC,IAAI,OACJwV,IAAK,QACLC,IAAK;AACT,WAAShX,IAAI,GAAGA,IAAI0W,EAAO,QAAQ1W,KAAK;AACtC,UAAM0H,IAAIgP,EAAO1W,CAAC;AAClB,IAAAsB,IAAI,KAAK,IAAIA,GAAGoG,EAAE,CAAC,CAAC,GACpBnG,IAAI,KAAK,IAAIA,GAAGmG,EAAE,CAAC,CAAC,GACpBqP,IAAK,KAAK,IAAIA,GAAIrP,EAAE,CAAC,CAAC,GACtBsP,IAAK,KAAK,IAAIA,GAAItP,EAAE,CAAC,CAAC;AAAA,EACxB;AACA,SAAO,IAAIkH,EAAItN,GAAGC,GAAGwV,IAAKzV,GAAG0V,IAAKzV,CAAC;AACrC;AACA,SAASyqB,GAASlrB,GAAKG,GAAQgrB,GAAO;AAOpC,QAAMC,IANS;AAAA,IACb,CAACprB,EAAI,GAAGA,EAAI,CAAC;AAAA,IACb,CAACA,EAAI,IAAIA,EAAI,OAAOA,EAAI,CAAC;AAAA,IACzB,CAACA,EAAI,IAAIA,EAAI,OAAOA,EAAI,IAAIA,EAAI,MAAM;AAAA,IACtC,CAACA,EAAI,GAAGA,EAAI,IAAIA,EAAI,MAAM;AAAA,EAC9B,EAC2B,IAAI,CAAC,CAACQ,GAAGC,CAAC,MAAM;AACvC,UAAM4qB,IAAc7qB,IAAIL,EAAO,CAAC,GAC1BmrB,IAAc7qB,IAAIN,EAAO,CAAC,GAC1BorB,IAAUF,IAAcF,GACxBK,IAAUF,IAAcH;AAC9B,WAAO,CAACI,IAAUprB,EAAO,CAAC,GAAGqrB,IAAUrrB,EAAO,CAAC,CAAC;AAAA,EAClD,CAAC;AACD,SAAO8qB,GAAiBG,CAAS;AACnC;AACA,MAAMK,GAAc;AAAA,EAClB,YAAYtmB,GAAI;AACd,SAAK,KAAKA,GACVA,EAAG,SAAS,kBAAkB,IAAI,GAClC,KAAK,kBAAkB,MACvB,KAAK,YAAY,IACjB,KAAK,YAAY,MACjB,KAAK,eAAe,KAAK,aAAa,KAAK,IAAI,GAC/C,KAAK,SAAS,KAAK,OAAO,KAAK,IAAI,GACnC,KAAK,YAAY,KAAK,UAAU,KAAK,IAAI,GACzC,KAAK,SAAS,KAAK,OAAO,KAAK,IAAI,GACnC,KAAK,YAAY,KAAK,UAAU,KAAK,IAAI;AAAA,EAC3C;AAAA,EACA,OAAOiM,GAAOf,GAAS;AAMrB,IALA,KAAK,sBAAsBA,EAAQ,uBAAuB,IAC1D,KAAK,eAAeA,EAAQ,gBAAgB,IAC5C,KAAK,OAAOA,EAAQ,QAAQ,GAC5B,KAAK,SAASA,EAAQ,UAAU,GAChC,KAAK,GAAG,IAAI,SAAS,GAChBe,MACL,KAAK,GAAG;AAAA,MACN;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACR;AAAA,MACM,KAAK;AAAA,IACX,GACQ,KAAK,cACH,KAAK,cAAc,QACrB,KAAK,OAAO,KAAK,SAAS,IACjB,KAAK,cAAc,UAC5B,KAAK,UAAU,KAAK,SAAS,IAE7B,KAAK,OAAO,KAAK,SAAS;AAAA,EAGhC;AAAA;AAAA,EAEA,aAAa5F,GAAG;AACd,SAAK,YAAYA,EAAE;AACnB,UAAM,EAAE,OAAA+E,GAAO,OAAAgE,GAAO,QAAAqB,EAAM,IAAKpK,EAAE,QAC7BuZ,IAAU,CAACxU,EAAM,KAAK,QAAQ,OAAO;AAI3C,QAHIwU,MAAYxU,EAAM,SAASA,EAAM,aAAa,KAG9C,KAAK,GAAG,SAAS,gBAAgB,EAAE,OAAO/E,GAAG,SAAS,KAAI,CAAE,EAAE;AAChE;AAEF,SAAK,MAAM,KAAK,GAAG,KAAI,GACvB,KAAK,aAAa,KAAK,GAAG,MAAMqZ,GAAmBtU,CAAK,CAAC,GACzD,KAAK,QAAQgE,GACb,KAAK,SAASqB,EAAO,MAAK;AAC1B,UAAMoP,KAAaD,IAAU,cAAc,eAAe,WACpDE,KAAYF,IAAU,YAAY,iCAAiC;AACzE,IAAIvZ,EAAE,SAAS,UACbyE,GAAG,QAAQ+U,GAAW,KAAK,SAAS,IAC3BxZ,EAAE,SAAS,QACpByE,GAAG,QAAQ+U,GAAW,KAAK,MAAM,IAEjC/U,GAAG,QAAQ+U,GAAW,KAAK,MAAM,GAEnC/U,GAAG,QAAQgV,GAAU,KAAK,SAAS;AAAA,EACrC;AAAA,EACA,OAAOzZ,GAAG;AACR,SAAK,YAAYA;AACjB,UAAMkgB,IAAW,KAAK,WAAW,KAAK,GAAG,MAAM7G,GAAmBrZ,CAAC,CAAC,CAAC;AACrE,QAAIK,IAAK6f,EAAS,IAAI,KAAK,WAAW,GAClC5f,IAAK4f,EAAS,IAAI,KAAK,WAAW;AACtC,IAAI,KAAK,uBAAuB,KAAK,iBACnC7f,KAAM,GACNC,KAAM;AAER,UAAMtL,IAAI,KAAK,IAAI,IAAIqL,GACjBpL,IAAI,KAAK,IAAI,IAAIqL,GACjBmK,IAAK,KAAK,IAAI,KAAKpK,GACnBqK,IAAK,KAAK,IAAI,KAAKpK;AACzB,QAAI9L,IAAM,IAAI8N,EAAI,KAAK,GAAG;AAmB1B,QAlBI,KAAK,UAAU,SAAS,GAAG,MAC7B9N,EAAI,IAAI,KAAK,IAAIQ,GAAG,KAAK,IAAI,EAAE,GAC/BR,EAAI,KAAK,KAAK,IAAIQ,GAAG,KAAK,IAAI,EAAE,IAE9B,KAAK,UAAU,SAAS,GAAG,MAC7BR,EAAI,IAAI,KAAK,IAAIiW,GAAI,KAAK,IAAI,CAAC,GAC/BjW,EAAI,KAAK,KAAK,IAAIiW,GAAI,KAAK,IAAI,CAAC,IAE9B,KAAK,UAAU,SAAS,GAAG,MAC7BjW,EAAI,IAAI,KAAK,IAAIS,GAAG,KAAK,IAAI,EAAE,GAC/BT,EAAI,KAAK,KAAK,IAAIS,GAAG,KAAK,IAAI,EAAE,IAE9B,KAAK,UAAU,SAAS,GAAG,MAC7BT,EAAI,IAAI,KAAK,IAAIkW,GAAI,KAAK,IAAI,CAAC,GAC/BlW,EAAI,KAAK,KAAK,IAAIkW,GAAI,KAAK,IAAI,CAAC,IAElClW,EAAI,QAAQA,EAAI,KAAKA,EAAI,GACzBA,EAAI,SAASA,EAAI,KAAKA,EAAI,GACtB,KAAK,qBAAqB;AAC5B,YAAM4K,IAAS5K,EAAI,QAAQ,KAAK,IAAI,OAC9B6K,IAAS7K,EAAI,SAAS,KAAK,IAAI,QAC/B2rB,IAAQ,CAAC,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,GAAG,GACnDxrB,KAAUwrB,EAAM,QAAQ,KAAK,SAAS,IAAI,KAAKA,EAAM,QACrDC,IAAgB,KAAK,eAAe,CAAC,KAAK,IAAI,IAAI,KAAK,IAAI,EAAE,IAAI,KAAK,OAAOzrB,CAAM;AACzF,UAAIgrB,IAAQ,KAAK,UAAU,SAAS,GAAG,KAAK,KAAK,UAAU,SAAS,GAAG,IAAItgB,IAASD;AACpF,MAAAugB,IAAQ,KAAK,UAAU,WAAW,IAAI,KAAK,IAAIvgB,GAAQC,CAAM,IAAIsgB,GACjEnrB,IAAMkrB,GAAS,KAAK,KAAKU,GAAeT,CAAK;AAAA,IAC/C;AACA,IAAI,KAAK,GAAG,SAAS,UAAU;AAAA,MAC7B,KAAK,IAAIrd,EAAI9N,CAAG;AAAA,MAChB,OAAO;AAAA,MACP,WAAW,KAAK;AAAA,MAChB,OAAOwL;AAAA,MACP,SAAS;AAAA,IACf,CAAK,EAAE,oBAGH,KAAK,GAAG,KAAKxL,EAAI,OAAOA,EAAI,MAAM,EAAE,KAAKA,EAAI,GAAGA,EAAI,CAAC;AAAA,EACvD;AAAA,EACA,UAAUwL,GAAG;AACX,SAAK,YAAYA;AACjB,UAAM,EAAE,GAAAhL,GAAG,GAAAC,EAAC,IAAK,KAAK,WAAW,KAAK,GAAG,MAAMokB,GAAmBrZ,CAAC,CAAC,CAAC,GAC/DqgB,IAAW,KAAK,GAAG,MAAK,EAAG,MAAK;AAEtC,IADAA,EAAS,KAAK,KAAK,IAAI,CAACrrB,GAAGC,CAAC,GACxB,MAAK,GAAG,SAAS,UAAU;AAAA,MAC7B,KAAKwqB,GAAiBY,CAAQ;AAAA,MAC9B,OAAO;AAAA,MACP,WAAW,KAAK;AAAA,MAChB,OAAOrgB;AAAA,MACP,SAAS;AAAA,IACf,CAAK,EAAE,oBAGH,KAAK,GAAG,KAAKqgB,CAAQ;AAAA,EACvB;AAAA,EACA,OAAOrgB,GAAG;AACR,SAAK,YAAYA;AACjB,UAAMsgB,IAAa,KAAK,YAClBJ,IAAW,KAAK,GAAG,MAAM7G,GAAmBrZ,CAAC,CAAC,GAC9C,EAAE,IAAAE,GAAI,IAAAC,EAAE,IAAK,KAAK,KAClBogB,IAAMD,EAAW,IAAIpgB,GACrBsgB,IAAMF,EAAW,IAAIngB,GACrBsgB,IAAMP,EAAS,IAAIhgB,GACnBwgB,IAAMR,EAAS,IAAI/f,GACnB9G,IAAI,KAAK,KAAKknB,IAAMA,IAAMC,IAAMA,CAAG,IAAI,KAAK,KAAKC,IAAMA,IAAMC,IAAMA,CAAG;AAC5E,QAAIrnB,MAAM;AACR;AAEF,QAAI4O,IAAQ,KAAK,MAAMsY,IAAME,IAAMD,IAAME,KAAOrnB,CAAC,IAAI,KAAK,KAAK;AAC/D,QAAI,CAAC4O,EAAO;AACZ,IAAIiY,EAAS,IAAII,EAAW,MAC1BrY,IAAQ,CAACA;AAEX,UAAM7H,IAAS,IAAI1B,EAAO,KAAK,EAAE,GAC3B,EAAE,GAAG9J,GAAI,GAAGC,EAAE,IAAK,IAAI0J,EAAM2B,GAAIC,CAAE,EAAE,WAAWC,CAAM,GACtD,EAAE,QAAAugB,EAAM,IAAKvgB,EAAO,UAAS,GAC7BwgB,IAAc,KAAK,YAAYD,IAAS1Y,CAAK,IAAI0Y;AACvD,IAAI,KAAK,GAAG,SAAS,UAAU;AAAA,MAC7B,KAAK,KAAK;AAAA,MACV,OAAOC;AAAA,MACP,WAAW,KAAK;AAAA,MAChB,OAAO5gB;AAAA,MACP,SAAS;AAAA,IACf,CAAK,EAAE,oBAGH,KAAK,GAAG,UAAUI,EAAO,QAAQwgB,GAAahsB,GAAIC,CAAE,CAAC;AAAA,EACvD;AAAA,EACA,UAAUmQ,GAAI;AACZ,IAAI,KAAK,cAAc,SAAS,KAAK,cAAc,WACjD,KAAK,OAAOA,CAAE,GAEhB,KAAK,YAAY,MACjB,KAAK,YAAY,IACjBC,GAAI,QAAQ,mCAAmC,GAC/CA,GAAI,QAAQ,gCAAgC;AAAA,EAC9C;AAAA,EACA,WAAWtG,GAAO;AAChB,WAAI,KAAK,SACPA,EAAM,IAAI,KAAK,MAAMA,EAAM,IAAI,KAAK,IAAI,IAAI,KAAK,MACjDA,EAAM,IAAI,KAAK,MAAMA,EAAM,IAAI,KAAK,IAAI,IAAI,KAAK,OAE5CA;AAAA,EACT;AAAA,EACA,YAAYsJ,GAAO;AACjB,WAAI,KAAK,WACPA,IAAQ,KAAK,MAAMA,IAAQ,KAAK,MAAM,IAAI,KAAK,SAE1CA;AAAA,EACT;AACF;AACA/Q,EAAOgK,IAAS;AAAA;AAAA,EAEd,QAAQ,SAASuR,IAAU,IAAM5N,IAAU,CAAA,GAAI;AAC7C,IAAI,OAAO4N,KAAY,aACrB5N,IAAU4N,GACVA,IAAU;AAEZ,QAAIoO,IAAgB,KAAK,SAAS,gBAAgB;AAClD,WAAKA,MACCpO,EAAQ,qBAAqBwN,MAC/BY,IAAgB,IAAIpO,EAAQ,IAAI,GAChCA,IAAU,MAEVoO,IAAgB,IAAIZ,GAAc,IAAI,GAExC,KAAK,SAAS,kBAAkBY,CAAa,IAE/CA,EAAc,OAAOpO,GAAS5N,CAAO,GAC9B;AAAA,EACT;AACF,CAAC;ACvMD,SAASic,GAAiBzsB,GAAS0sB,GAAQC,GAAQ;AACjD,MAAI;AAEF,UAAMC,IAAU5sB,EAAQ,KAAK,mBAAmBA,EAAQ,MAGlD2N,IAAY3N,EAAQ,KAAK,aAAY,GACrC6sB,IAAgBD,EAAQ,aAAY;AAE1C,QAAI,CAACjf,KAAa,CAACkf;AACjB,aAAO,CAACH,GAAQC,CAAM;AAIxB,UAAMG,IAAUnf,EAAU,IAAI+e,IAAS/e,EAAU,IAAIgf,IAAShf,EAAU,GAClEof,IAAUpf,EAAU,IAAI+e,IAAS/e,EAAU,IAAIgf,IAAShf,EAAU,GAGlEb,IAAM+f,EAAc,IAAIA,EAAc,IAAIA,EAAc,IAAIA,EAAc;AAChF,QAAI,KAAK,IAAI/f,CAAG,IAAI;AAClB,aAAO,CAAC4f,GAAQC,CAAM;AAGxB,UAAMK,IAAOH,EAAc,IAAI/f,GACzBmgB,IAAO,CAACJ,EAAc,IAAI/f,GAC1BogB,IAAO,CAACL,EAAc,IAAI/f,GAC1BqgB,IAAON,EAAc,IAAI/f,GACzBsgB,KAAQP,EAAc,IAAIA,EAAc,IAAIA,EAAc,IAAIA,EAAc,KAAK/f,GACjFugB,KAAQR,EAAc,IAAIA,EAAc,IAAIA,EAAc,IAAIA,EAAc,KAAK/f,GAEjFwgB,IAAON,IAAOF,IAAUI,IAAOH,IAAUK,GACzCG,IAAON,IAAOH,IAAUK,IAAOJ,IAAUM;AAE/C,WAAO,CAACC,GAAMC,CAAI;AAAA,EACpB,QAAY;AACV,WAAO,CAACb,GAAQC,CAAM;AAAA,EACxB;AACF;AAKA,SAASa,GAAiBxtB,GAASstB,GAAMC,GAAM;AAC7C,MAAI;AACF,UAAMX,IAAU5sB,EAAQ,KAAK,mBAAmBA,EAAQ,MAClD2N,IAAY3N,EAAQ,KAAK,aAAY,GACrC6sB,IAAgBD,EAAQ,aAAY;AAE1C,QAAI,CAACjf,KAAa,CAACkf;AACjB,aAAO,CAACS,GAAMC,CAAI;AAIpB,UAAMT,IAAUD,EAAc,IAAIS,IAAOT,EAAc,IAAIU,IAAOV,EAAc,GAC1EE,IAAUF,EAAc,IAAIS,IAAOT,EAAc,IAAIU,IAAOV,EAAc,GAG1E/f,IAAMa,EAAU,IAAIA,EAAU,IAAIA,EAAU,IAAIA,EAAU;AAChE,QAAI,KAAK,IAAIb,CAAG,IAAI;AAClB,aAAO,CAACwgB,GAAMC,CAAI;AAGpB,UAAMP,IAAOrf,EAAU,IAAIb,GACrBmgB,IAAO,CAACtf,EAAU,IAAIb,GACtBogB,IAAO,CAACvf,EAAU,IAAIb,GACtBqgB,IAAOxf,EAAU,IAAIb,GACrBsgB,KAAQzf,EAAU,IAAIA,EAAU,IAAIA,EAAU,IAAIA,EAAU,KAAKb,GACjEugB,KAAQ1f,EAAU,IAAIA,EAAU,IAAIA,EAAU,IAAIA,EAAU,KAAKb,GAEjE4f,IAASM,IAAOF,IAAUI,IAAOH,IAAUK,GAC3CT,IAASM,IAAOH,IAAUK,IAAOJ,IAAUM;AAEjD,WAAO,CAACX,GAAQC,CAAM;AAAA,EACxB,QAAY;AACV,WAAO,CAACW,GAAMC,CAAI;AAAA,EACpB;AACF;AAMA,SAASE,GAAiBztB,GAAS;AACjC,QAAMyO,IAAOzO,EAAQ,KAAI;AACzB,SAAOysB,GAAiBzsB,GAASyO,EAAK,IAAIA,EAAK,EAAE;AACnD;AAcA,SAASif,GAA0BvD,GAAOwD,GAAa;AACrD,MAAI;AACF,UAAMvrB,IAAO+nB,KAASA,EAAM;AAC5B,QAAIyD,IACFxrB,KAAQA,EAAK,iBAAiBA,EAAK,cAAc,uBAAuB;AAO1E,QAAI,CAACwrB,KAAUxrB,KAAQA,EAAK,kBAAkB;AAC5C,UAAIyrB,IAAW;AACf,MAAAzrB,EACG,iBAAiB,2CAA2C,EAC5D,QAAQ,CAAC0rB,MAAS;AACjB,YAAI,OAAOA,EAAK,kBAAmB;AACnC,cAAI;AACF,kBAAMnnB,IAAImnB,EAAK,QAAO,GAChBC,IAAOpnB,EAAE,QAAQA,EAAE;AACzB,YAAIonB,IAAOF,MACTA,IAAWE,GACXH,IAASE;AAAA,UAEb,QAAY;AAAA,UAEZ;AAAA,MACF,CAAC;AAAA,IACL;AACA,QAAI,CAACF,KAAU,OAAOA,EAAO,kBAAmB,WAAY,QAAO;AACnE,UAAMI,IAAQJ,EAAO,eAAc;AACnC,QAAI,CAACI,KAAS,CAAC,SAASA,CAAK,EAAG,QAAO;AAUvC,QAAIC,IAAUL,EAAO;AACrB,WAAOK,KAAWA,EAAQ,kBAAiB,CAAAA,IAAUA,EAAQ;AAC7D,UAAMC,IAAUN,EAAO,gBAAgBA,EAAO,aAAY,GACpDf,IAAgBoB,KAAWA,EAAQ,gBAAgBA,EAAQ,aAAY;AAC7E,QAAI,CAACA,KAAW,CAACC,KAAW,CAACrB,EAAe,QAAO;AACnD,UAAMsB,IAAUtB,EAAc,QAAO,GAC/BuB,IAAKH,EAAQ,eAAc,GAC3BI,IAAS,CAAC/gB,GAAIC,MAAO;AACzB,MAAA6gB,EAAG,IAAI9gB,GACP8gB,EAAG,IAAI7gB;AACP,YAAM+gB,IAAIF,EAAG,gBAAgBF,CAAO,EAAE,gBAAgBC,CAAO;AAC7D,aAAO,CAACG,EAAE,GAAGA,EAAE,CAAC;AAAA,IAClB,GAEM,CAACziB,GAAIC,CAAE,IAAI2hB,GAAiBtD,CAAK,GACjCoE,IAAOZ,EAAY,CAAC,IAAI9hB,GACxB2iB,IAAOb,EAAY,CAAC,IAAI7hB,GACxB2iB,IAAK,KAAK,KAAKF,IAAOA,IAAOC,IAAOA,CAAI,KAAK,GAC7CE,IAAKH,IAAOE,GACZE,IAAKH,IAAOC;AAElB,QAAIG,IAAO,MACPC,IAAY;AAMhB,UAAMC,IAAI;AACV,QAAIC,IAAUnB,EAAO;AACrB,QAAI,CAACmB,KAAWnB,EAAO,iBAAiBI,GAAO;AAC7C,MAAAe,IAAU,IAAI,MAAMD,CAAC;AACrB,eAASzvB,IAAI,GAAGA,IAAIyvB,GAAGzvB,KAAK;AAC1B,cAAM2vB,IAAKpB,EAAO,iBAAkBvuB,IAAIyvB,IAAKd,CAAK;AAClD,QAAAe,EAAQ1vB,CAAC,IAAI,CAAC2vB,EAAG,GAAGA,EAAG,CAAC;AAAA,MAC1B;AACA,MAAApB,EAAO,mBAAmBmB,GAC1BnB,EAAO,eAAeI;AAAA,IACxB;AACA,aAAS3uB,IAAI,GAAGA,IAAI0vB,EAAQ,QAAQ1vB,KAAK;AACvC,YAAM,CAAC4vB,GAAIC,CAAE,IAAIb,EAAOU,EAAQ1vB,CAAC,EAAE,CAAC,GAAG0vB,EAAQ1vB,CAAC,EAAE,CAAC,CAAC;AACpD,UAAI,CAAC,SAAS4vB,CAAE,KAAK,CAAC,SAASC,CAAE,EAAG;AACpC,YAAM/jB,IAAK8jB,IAAKpjB,GACVT,IAAK8jB,IAAKpjB,GACVqjB,IAAOhkB,IAAKujB,IAAKtjB,IAAKujB,GACtBS,IAAO,KAAK,IAAIjkB,IAAKwjB,IAAKvjB,IAAKsjB,CAAE,GACjCW,IAAQF,IAAOC,IAAO;AAC5B,MAAIC,IAAQR,MACVA,IAAYQ,GACZT,IAAO,CAACK,GAAIC,CAAE;AAAA,IAElB;AACA,WAAON;AAAA,EACT,QAAY;AACV,WAAO;AAAA,EACT;AACF;AAEA,SAASU,GAAsBnF,GAAOwD,GAAa;AAIjD,QAAM4B,IAAU7B,GAA0BvD,GAAOwD,CAAW;AAC5D,MAAI4B,KAAW,SAASA,EAAQ,CAAC,CAAC,KAAK,SAASA,EAAQ,CAAC,CAAC,GAAG;AAG3D,UAAMC,IAAKrF,EAAM,KAAI,GACf,CAACsF,GAAKC,CAAG,IAAIjD,GAAiBtC,GAAOqF,EAAG,IAAIA,EAAG,EAAE,GACjDG,IAAO,KAAK,IAAIH,EAAG,OAAOA,EAAG,QAAQ,CAAC,IAAI;AAChD,QAAI,KAAK,MAAMD,EAAQ,CAAC,IAAIE,GAAKF,EAAQ,CAAC,IAAIG,CAAG,KAAKC;AACpD,aAAOJ;AAAA,EAEX;AAEA,QAAM9gB,IAAO0b,EAAM,KAAI,GAGjB,CAACyF,GAAcC,CAAY,IAAIrC,GAAiBrD,GAAOwD,EAAY,CAAC,GAAGA,EAAY,CAAC,CAAC,GAGrFmC,IAAUrhB,EAAK,IACfshB,IAAUthB,EAAK,IACfzC,IAAK4jB,IAAeE,GACpB7jB,IAAK4jB,IAAeE,GACpBC,IAAW,KAAK,KAAKhkB,IAAKA,IAAKC,IAAKA,CAAE;AAG5C,MAAI+jB,MAAa;AACf,WAAOvD,GAAiBtC,GAAO2F,GAASC,CAAO;AAIjD,QAAMrB,IAAK1iB,IAAKgkB,GACVrB,IAAK1iB,IAAK+jB;AAGhB,MAAIC;AAEJ,MAAI9F,EAAM,SAAS,UAAU;AAC3B,UAAM+F,IAAS,WAAW/F,EAAM,KAAK,GAAG,CAAC,KAAK;AAC9C,IAAA8F,IAAiB,CAACH,IAAUI,IAASxB,GAAIqB,IAAUG,IAASvB,CAAE;AAAA,EAChE,WAAWxE,EAAM,SAAS,WAAW;AACnC,UAAM1e,IAAK,WAAW0e,EAAM,KAAK,IAAI,CAAC,KAAK,GACrCze,IAAK,WAAWye,EAAM,KAAK,IAAI,CAAC,KAAK,GACrCvW,IAAQ,KAAK,MAAM+a,GAAID,CAAE;AAC/B,IAAAuB,IAAiB;AAAA,MACfH,IAAUrkB,IAAK,KAAK,IAAImI,CAAK;AAAA,MAC7Bmc,IAAUrkB,IAAK,KAAK,IAAIkI,CAAK;AAAA,IACnC;AAAA,EACE,OAAO;AAEL,UAAM0T,IAAO7Y,EAAK,GACZ+Y,IAAQ/Y,EAAK,IAAIA,EAAK,OACtB4Y,IAAM5Y,EAAK,GACX8Y,IAAS9Y,EAAK,IAAIA,EAAK,QAEvB0hB,IAAgB,CAAA;AAEtB,QAAIzB,MAAO,GAAG;AACZ,YAAMnpB,KAAK+hB,IAAOwI,KAAWpB,GACvB9tB,IAAImvB,IAAUxqB,IAAIopB;AACxB,MAAI/tB,KAAKymB,KAAOzmB,KAAK2mB,KAAUhiB,IAAI,KACjC4qB,EAAc,KAAK,CAAC7I,GAAM1mB,GAAG2E,CAAC,CAAC;AAAA,IAEnC;AAEA,QAAImpB,MAAO,GAAG;AACZ,YAAMnpB,KAAKiiB,IAAQsI,KAAWpB,GACxB9tB,IAAImvB,IAAUxqB,IAAIopB;AACxB,MAAI/tB,KAAKymB,KAAOzmB,KAAK2mB,KAAUhiB,IAAI,KACjC4qB,EAAc,KAAK,CAAC3I,GAAO5mB,GAAG2E,CAAC,CAAC;AAAA,IAEpC;AAEA,QAAIopB,MAAO,GAAG;AACZ,YAAMppB,KAAK8hB,IAAM0I,KAAWpB,GACtBhuB,IAAImvB,IAAUvqB,IAAImpB;AACxB,MAAI/tB,KAAK2mB,KAAQ3mB,KAAK6mB,KAASjiB,IAAI,KACjC4qB,EAAc,KAAK,CAACxvB,GAAG0mB,GAAK9hB,CAAC,CAAC;AAAA,IAElC;AAEA,QAAIopB,MAAO,GAAG;AACZ,YAAMppB,KAAKgiB,IAASwI,KAAWpB,GACzBhuB,IAAImvB,IAAUvqB,IAAImpB;AACxB,MAAI/tB,KAAK2mB,KAAQ3mB,KAAK6mB,KAASjiB,IAAI,KACjC4qB,EAAc,KAAK,CAACxvB,GAAG4mB,GAAQhiB,CAAC,CAAC;AAAA,IAErC;AAEA,IAAI4qB,EAAc,SAAS,KACzBA,EAAc,KAAK,SAAUvqB,GAAGe,GAAG;AACjC,aAAOf,EAAE,CAAC,IAAIe,EAAE,CAAC;AAAA,IACnB,CAAC,GACDspB,IAAiB,CAACE,EAAc,CAAC,EAAE,CAAC,GAAGA,EAAc,CAAC,EAAE,CAAC,CAAC,KAE1DF,IAAiB,CAACH,GAASC,CAAO;AAAA,EAEtC;AAGA,QAAM,CAACK,GAAYC,CAAU,IAAI5D,GAAiBtC,GAAO8F,EAAe,CAAC,GAAGA,EAAe,CAAC,CAAC;AAE7F,SAAI,MAAMG,CAAU,KAAK,MAAMC,CAAU,KAAK,CAAC,SAASD,CAAU,KAAK,CAAC,SAASC,CAAU,IAClF5D,GAAiBtC,GAAO2F,GAASC,CAAO,IAG1C,CAACK,GAAYC,CAAU;AAChC;AAcA,SAASC,GAAmBnG,GAAOoG,GAAQ;AACzC,QAAM9hB,IAAO0b,EAAM,KAAI,GACjB7c,IAAKmB,EAAK,KAAK8hB,EAAO,KAAK,OAAOA,EAAO,IAAI,OAAO9hB,EAAK,OACzDlB,IAAKkB,EAAK,KAAK8hB,EAAO,KAAK,OAAOA,EAAO,IAAI,OAAO9hB,EAAK,QACzD,CAACwgB,GAAIC,CAAE,IAAIzC,GAAiBtC,GAAO7c,GAAIC,CAAE;AAC/C,SAAI,MAAM0hB,CAAE,KAAK,MAAMC,CAAE,KAAK,CAAC,SAASD,CAAE,KAAK,CAAC,SAASC,CAAE,IAClDzB,GAAiBtD,CAAK,IAExB,CAAC8E,GAAIC,CAAE;AAChB;AAWA,SAASsB,GAAarG,GAAOsG,GAAS;AACpC,MAAI;AACF,UAAMjB,IAAKrF,EAAM,KAAI;AACrB,QAAI,CAACqF,KAAM,CAACA,EAAG,SAAS,CAACA,EAAG,OAAQ,QAAO;AAC3C,UAAM,CAACliB,GAAIC,CAAE,IAAIigB,GAAiBrD,GAAOsG,EAAQ,CAAC,GAAGA,EAAQ,CAAC,CAAC,GACzDC,KAAMpjB,IAAKkiB,EAAG,KAAKA,EAAG,OACtBmB,KAAMpjB,IAAKiiB,EAAG,KAAKA,EAAG,QACtBoB,IAAKF,GACLG,IAAK,IAAIH,GACTnZ,IAAKoZ,GACLG,IAAK,IAAIH,GACT/xB,IAAI,KAAK,IAAIgyB,GAAIC,GAAItZ,GAAIuZ,CAAE;AACjC,QAAIC,IAAM,GACNC,IAAM;AACV,IAAIpyB,MAAMgyB,IAAIG,IAAM,KACXnyB,MAAMiyB,IAAIE,IAAM,IAChBnyB,MAAM2Y,IAAIyZ,IAAM,KACpBA,IAAM;AAEX,UAAMzY,IAAKkU,GAAiBtC,GAAOqF,EAAG,IAAIA,EAAG,EAAE,GACzC9F,IAAK+C,GAAiBtC,GAAOqF,EAAG,KAAKuB,GAAKvB,EAAG,KAAKwB,CAAG,GACrDC,IAAKvH,EAAG,CAAC,IAAInR,EAAG,CAAC,GACjB2Y,IAAKxH,EAAG,CAAC,IAAInR,EAAG,CAAC,GACjB4Y,IAAM,KAAK,MAAMF,GAAIC,CAAE;AAC7B,WAAMC,IAAM,OACL,CAACF,IAAKE,GAAKD,IAAKC,CAAG,IADE;AAAA,EAE9B,QAAY;AACV,WAAO;AAAA,EACT;AACF;AAEA,SAASC,GAA4BC,GAAK;AACxC,QAAMC,IAAO,CAAA;AAEb,MAAI,CAACD,EAAI,UAAU,CAACA,EAAI;AACtB,WAAO;AAAA,MACL,CAAC,KAAK,GAAG,CAAC;AAAA,MACV,CAAC,KAAK,IAAI,EAAE;AAAA,IAClB;AAIE,QAAME,IAAe9D,GAAiB4D,EAAI,MAAM,GAC1CG,IAAe/D,GAAiB4D,EAAI,MAAM;AAIhD,EAAIA,EAAI,eACNC,EAAK,SAAShB,GAAmBe,EAAI,QAAQA,EAAI,YAAY,IACpDA,EAAI,iBAAiB,WAC9BC,EAAK,SAASC,IAKdD,EAAK,SAAShC,GAAsB+B,EAAI,QAAQG,CAAY,GAG1DH,EAAI,eACNC,EAAK,SAAShB,GAAmBe,EAAI,QAAQA,EAAI,YAAY,IACpDA,EAAI,iBAAiB,WAC9BC,EAAK,SAASE,IAGdF,EAAK,SAAShC,GAAsB+B,EAAI,QAAQE,CAAY;AAG9D,QAAME,IAAMH,EAAK,QACXI,IAAMJ,EAAK;AAEjB,MAAIvb;AAEJ,MAAIsb,EAAI,SAAS,UAAU;AACzB,UAAMrlB,IAAK0lB,EAAI,CAAC,IAAID,EAAI,CAAC,GACnBxlB,IAAKylB,EAAI,CAAC,IAAID,EAAI,CAAC,GACnBzB,IAAW,KAAK,KAAKhkB,IAAKA,IAAKC,IAAKA,CAAE;AAE5C,QAAI+jB,IAAW;AACb,aAAO,CAAC,CAAC,KAAKyB,EAAI,CAAC,GAAGA,EAAI,CAAC,CAAC,GAAG,CAAC,KAAKC,EAAI,CAAC,GAAGA,EAAI,CAAC,CAAC,CAAC;AAOtD,UAAMC,IAAO,CAACV,GAAIC,GAAIU,GAAIC,MAAO;AAC/B,YAAMjzB,IAAI,KAAK,KAAKqyB,IAAKA,IAAKC,IAAKA,CAAE;AACrC,UAAItyB,IAAI,KAAQ,QAAO,CAACqyB,IAAKryB,GAAGsyB,IAAKtyB,CAAC;AACtC,YAAMkzB,IAAK,KAAK,KAAKF,IAAKA,IAAKC,IAAKA,CAAE,KAAK;AAC3C,aAAO,CAACD,IAAKE,GAAID,IAAKC,CAAE;AAAA,IAC1B,GAOMC,IAAOV,EAAI,gBACbb,GAAaa,EAAI,QAAQI,CAAG,KAC5BE,EAAKF,EAAI,CAAC,IAAIF,EAAa,CAAC,GAAGE,EAAI,CAAC,IAAIF,EAAa,CAAC,GAAGvlB,GAAIC,CAAE,GAE7D+lB,IAAOX,EAAI,gBACbb,GAAaa,EAAI,QAAQK,CAAG,KAC5BC,EAAKD,EAAI,CAAC,IAAIF,EAAa,CAAC,GAAGE,EAAI,CAAC,IAAIF,EAAa,CAAC,GAAG,CAACxlB,GAAI,CAACC,CAAE,GAK/DgmB,IACJ,OAAOZ,EAAI,iBAAkB,WAAWA,EAAI,gBAAgB,KACxDvG,IAAS,KAAK,IAAI,IAAIkF,KAAY,OAAOiC,IAAY,KAAK,GAE1DC,IAAM,CAACT,EAAI,CAAC,IAAIM,EAAK,CAAC,IAAIjH,GAAQ2G,EAAI,CAAC,IAAIM,EAAK,CAAC,IAAIjH,CAAM,GAC3DqH,IAAM,CAACT,EAAI,CAAC,IAAIM,EAAK,CAAC,IAAIlH,GAAQ4G,EAAI,CAAC,IAAIM,EAAK,CAAC,IAAIlH,CAAM;AAEjE,QAAIuG,EAAI,kBAAkB,aAAa;AAIrC,YAAMe,IAAM,EAAEF,EAAI,CAAC,IAAIC,EAAI,CAAC,KAAK,IAAID,EAAI,CAAC,IAAIC,EAAI,CAAC,KAAK,CAAC;AACzD,MAAApc,IAAS;AAAA,QACP,CAAC,KAAK0b,EAAI,CAAC,GAAGA,EAAI,CAAC,CAAC;AAAA,QACpB,CAAC,KAAKW,EAAI,CAAC,GAAGA,EAAI,CAAC,GAAGV,EAAI,CAAC,GAAGA,EAAI,CAAC,CAAC;AAAA,MAC5C;AAAA,IACI;AACE,MAAA3b,IAAS;AAAA,QACP,CAAC,KAAK0b,EAAI,CAAC,GAAGA,EAAI,CAAC,CAAC;AAAA,QACpB,CAAC,KAAKS,EAAI,CAAC,GAAGA,EAAI,CAAC,GAAGC,EAAI,CAAC,GAAGA,EAAI,CAAC,GAAGT,EAAI,CAAC,GAAGA,EAAI,CAAC,CAAC;AAAA,MAC5D;AAAA,EAEE,WAAWL,EAAI,SAAS,cAAc;AACpC,UAAMrlB,IAAK0lB,EAAI,CAAC,IAAID,EAAI,CAAC,GACnBxlB,IAAKylB,EAAI,CAAC,IAAID,EAAI,CAAC,GAEnBY,IAAeZ,EAAI,CAAC,IAAIF,EAAa,CAAC,GACtCe,IAAcb,EAAI,CAAC,IAAIF,EAAa,CAAC,GACrCgB,IAAeb,EAAI,CAAC,IAAIF,EAAa,CAAC,GACtCgB,IAAcd,EAAI,CAAC,IAAIF,EAAa,CAAC;AAE3C,QAAIiB,GAAMC;AAOV,UAAMC,IAAa;AACnB,QAAI,KAAK,IAAI3mB,CAAE,KAAK2mB,KAAc,KAAK,IAAI1mB,CAAE,IAAI0mB,GAAY;AAC3D,YAAM9mB,KAAM4lB,EAAI,CAAC,IAAIC,EAAI,CAAC,KAAK;AAC/B,MAAA3b,IAAS;AAAA,QACP,CAAC,KAAKlK,GAAI4lB,EAAI,CAAC,CAAC;AAAA,QAChB,CAAC,KAAK5lB,GAAI6lB,EAAI,CAAC,CAAC;AAAA,MACxB;AAAA,IACI,WAAW,KAAK,IAAIzlB,CAAE,KAAK0mB,KAAc,KAAK,IAAI3mB,CAAE,IAAI2mB,GAAY;AAClE,YAAM7mB,KAAM2lB,EAAI,CAAC,IAAIC,EAAI,CAAC,KAAK;AAC/B,MAAA3b,IAAS;AAAA,QACP,CAAC,KAAK0b,EAAI,CAAC,GAAG3lB,CAAE;AAAA,QAChB,CAAC,KAAK4lB,EAAI,CAAC,GAAG5lB,CAAE;AAAA,MACxB;AAAA,IACI,WAAW,KAAK,IAAIE,CAAE,IAAI,KAAK,IAAIC,CAAE;AACnC,UAAKomB,KAAgBE,KAAkB,CAACF,KAAgB,CAACE,GAAe;AACtE,cAAMrO,IAAS,KAAK,IAAImN,EAAI,aAAa,KAAK,IAAIplB,CAAE,IAAI,CAAC;AACzD,QAAAymB,IAAOjB,EAAI,CAAC,KAAKxlB,IAAK,IAAI,CAACiY,IAASA,IACpCnO,IAAS;AAAA,UACP,CAAC,KAAK0b,EAAI,CAAC,GAAGA,EAAI,CAAC,CAAC;AAAA,UACpB,CAAC,KAAKA,EAAI,CAAC,GAAGiB,CAAI;AAAA,UAClB,CAAC,KAAKhB,EAAI,CAAC,GAAGgB,CAAI;AAAA,UAClB,CAAC,KAAKhB,EAAI,CAAC,GAAGA,EAAI,CAAC,CAAC;AAAA,QAC9B;AAAA,MACM;AACE,QAAAe,IAAOhB,EAAI,CAAC,IAAIzlB,IAAK,GACrB+J,IAAS;AAAA,UACP,CAAC,KAAK0b,EAAI,CAAC,GAAGA,EAAI,CAAC,CAAC;AAAA,UACpB,CAAC,KAAKgB,GAAMhB,EAAI,CAAC,CAAC;AAAA,UAClB,CAAC,KAAKgB,GAAMf,EAAI,CAAC,CAAC;AAAA,UAClB,CAAC,KAAKA,EAAI,CAAC,GAAGA,EAAI,CAAC,CAAC;AAAA,QAC9B;AAAA,aAGWY,KAAeE,KAAiB,CAACF,KAAe,CAACE,GAAc;AAClE,YAAMtO,IAAS,KAAK,IAAImN,EAAI,aAAa,KAAK,IAAIrlB,CAAE,IAAI,CAAC;AACzD,MAAAymB,IAAOhB,EAAI,CAAC,KAAKzlB,IAAK,IAAI,CAACkY,IAASA,IACpCnO,IAAS;AAAA,QACP,CAAC,KAAK0b,EAAI,CAAC,GAAGA,EAAI,CAAC,CAAC;AAAA,QACpB,CAAC,KAAKgB,GAAMhB,EAAI,CAAC,CAAC;AAAA,QAClB,CAAC,KAAKgB,GAAMf,EAAI,CAAC,CAAC;AAAA,QAClB,CAAC,KAAKA,EAAI,CAAC,GAAGA,EAAI,CAAC,CAAC;AAAA,MAC9B;AAAA,IACM;AACE,MAAAgB,IAAOjB,EAAI,CAAC,IAAIxlB,IAAK,GACrB8J,IAAS;AAAA,QACP,CAAC,KAAK0b,EAAI,CAAC,GAAGA,EAAI,CAAC,CAAC;AAAA,QACpB,CAAC,KAAKA,EAAI,CAAC,GAAGiB,CAAI;AAAA,QAClB,CAAC,KAAKhB,EAAI,CAAC,GAAGgB,CAAI;AAAA,QAClB,CAAC,KAAKhB,EAAI,CAAC,GAAGA,EAAI,CAAC,CAAC;AAAA,MAC9B;AAAA,EAGE;AAEE,IAAA3b,IAAS;AAAA,MACP,CAAC,KAAK0b,EAAI,CAAC,GAAGA,EAAI,CAAC,CAAC;AAAA,MACpB,CAAC,KAAKC,EAAI,CAAC,GAAGA,EAAI,CAAC,CAAC;AAAA,IAC1B;AAKE,QAAMkB,IAAmBvB,EAAI,gBAAgBA,EAAI,aAAa;AAC9D,MAAIuB,KAAoB7c,KAAUA,EAAO,UAAU,KACpC,KAAK,MAAM2b,EAAI,CAAC,IAAID,EAAI,CAAC,GAAGC,EAAI,CAAC,IAAID,EAAI,CAAC,CAAC,IAC7CmB,IAAmB,KAAK;AACjC,UAAMC,IAAQ9c,EAAO,CAAC,GAChB3S,IAAO2S,EAAO,CAAC,GACf3J,IAAKymB,EAAMA,EAAM,SAAS,CAAC,GAC3BrmB,IAAKqmB,EAAMA,EAAM,SAAS,CAAC;AACjC,QAAIvnB,IAAKlI,EAAK,CAAC,IAAIgJ,GACfb,IAAKnI,EAAK,CAAC,IAAIoJ;AACnB,UAAM5N,IAAI,KAAK,MAAM0M,GAAIC,CAAE;AAC3B,IAAI3M,IAAI,SACN0M,KAAM1M,GACN2M,KAAM3M,GACNi0B,EAAMA,EAAM,SAAS,CAAC,IAAIzmB,IAAKd,IAAKsnB,GACpCC,EAAMA,EAAM,SAAS,CAAC,IAAIrmB,IAAKjB,IAAKqnB,IAChCxvB,EAAK,CAAC,MAAM,OAAOA,EAAK,CAAC,MAAM,SACjCA,EAAK,CAAC,KAAKkI,IAAKsnB,GAChBxvB,EAAK,CAAC,KAAKmI,IAAKqnB;AAAA,EAGtB;AAUF,QAAME,IAAKzB,EAAI,gBAAgBA,EAAI,aAAa;AAChD,MAAIyB,KAAM/c,KAAUA,EAAO,UAAU,KACtB,KAAK,MAAM2b,EAAI,CAAC,IAAID,EAAI,CAAC,GAAGC,EAAI,CAAC,IAAID,EAAI,CAAC,CAAC,IAC7CqB,IAAK,KAAK;AACnB,UAAMnhB,IAAOoE,EAAOA,EAAO,SAAS,CAAC,GAC/Bgd,IAAKphB,EAAKA,EAAK,SAAS,CAAC,GACzBqhB,IAAKrhB,EAAKA,EAAK,SAAS,CAAC;AAC/B,QAAIlG,GAAIC;AACR,QAAIiG,EAAK,CAAC,MAAM;AACd,MAAAlG,IAAKkG,EAAK,CAAC,GACXjG,IAAKiG,EAAK,CAAC;AAAA,SACN;AACL,YAAMtO,IAAO0S,EAAOA,EAAO,SAAS,CAAC;AACrC,MAAAtK,IAAKpI,EAAKA,EAAK,SAAS,CAAC,GACzBqI,IAAKrI,EAAKA,EAAK,SAAS,CAAC;AAAA,IAC3B;AACA,QAAIiI,IAAKynB,IAAKtnB,GACVF,IAAKynB,IAAKtnB;AACd,UAAM9M,IAAI,KAAK,MAAM0M,GAAIC,CAAE;AAC3B,IAAI3M,IAAI,SACN0M,KAAM1M,GACN2M,KAAM3M,GACN+S,EAAKA,EAAK,SAAS,CAAC,IAAIohB,IAAKznB,IAAKwnB,GAClCnhB,EAAKA,EAAK,SAAS,CAAC,IAAIqhB,IAAKznB,IAAKunB,GAG9BnhB,EAAK,CAAC,MAAM,QACdA,EAAK,CAAC,KAAKrG,IAAKwnB,GAChBnhB,EAAK,CAAC,KAAKpG,IAAKunB;AAAA,EAGtB;AAGF,SAAO/c;AACT;AC/pBA,SAASkd,GAAavgB,GAAMkB,GAAOsf,GAAUC,GAAaC,GAASjsB,GAAO;AACxE,MAAI,CAACuL,KAAQA,MAAS,OAAQ,QAAO;AAIrC,QAAM2gB,IAAa,KAAK,IADP,IACqBF,IAAc,IAAI,CAAC,GACnDG,IAAaD,GACbE,IAAcF,IAAa,KAE3BG,KACHN,IAAW,YAAY,aACxB,cACA,KAAK,OAAM,EAAG,SAAS,EAAE,EAAE,OAAO,GAAG,CAAC,GAClCO,IAAWL,EAAQ,KAAI,EAAG,OAAOE,GAAYC,CAAW;AAE9D,EAAAE,EAAS,KAAK;AAAA,IACZ,IAAID;AAAA,IACJ,SAAS,SAASF,IAAa,MAAMC;AAAA;AAAA;AAAA;AAAA,IAIrC,MAAML,IAAW,OAAOI,CAAU,IAAI;AAAA,IACtC,MAAMC,IAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOpB,aAAa;AAAA,IACb,aAAaD;AAAA;AAAA,IACb,cAAcC;AAAA,IACd,QAAQ;AAAA,EACZ,CAAG;AAGD,QAAMzlB,IAAO2lB,EAAS,KAAI,GACpBC,IAAaH,IAAc;AAEjC,SAAIL,IAEFplB,EAAK,KAAK;AAAA,IACR,GACE,SACA4lB,IACA,QACAJ,IACA,UACAA,IACA,MACAC,IACA;AAAA,EACR,CAAK,IAGDzlB,EAAK,KAAK;AAAA,IACR,GACE,eACAylB,IACA,QACAD,IACA,MACAI,IACA;AAAA,EACR,CAAK,GAGH5lB,EAAK,KAAK3G,CAAK,GAER;AAAA,IACL,SAASssB;AAAA,IACT,IAAID;AAAA,IACJ,MAAMH;AAAA,EACV;AACA;AAcA,SAASM,GAAUtC,GAAKuC,GAAcC,GAAcC,GAAkB;AACpE,SAAIA,MAAkBzC,EAAI,UAAUyC,IAKpCzC,EAAI,mBAAmBuC,KAAgB,QACvCvC,EAAI,mBAAmBwC,KAAgB,QAGnCxC,EAAI,iBACNA,EAAI,aAAa,QAAQ,OAAM,GAC/BA,EAAI,UAAU,KAAK,gBAAgB,IAAI,IAErCA,EAAI,iBACNA,EAAI,aAAa,QAAQ,OAAM,GAC/BA,EAAI,UAAU,KAAK,cAAc,IAAI,IAInCuC,KAAgBA,MAAiB,UACnCvC,EAAI,eAAe4B;AAAA,IACjBW;AAAA,IACA;AAAA,IACA;AAAA,IACAvC,EAAI;AAAA,IACJA,EAAI,WAAWyC;AAAA,IACfzC,EAAI;AAAA,EACV,GACIA,EAAI,UAAU,KAAK,gBAAgB,UAAUA,EAAI,aAAa,KAAK,GAAG,KAEtEA,EAAI,eAAe,MAIjBwC,KAAgBA,MAAiB,UACnCxC,EAAI,eAAe4B;AAAA,IACjBY;AAAA,IACA;AAAA,IACA;AAAA,IACAxC,EAAI;AAAA,IACJA,EAAI,WAAWyC;AAAA,IACfzC,EAAI;AAAA,EACV,GACIA,EAAI,UAAU,KAAK,cAAc,UAAUA,EAAI,aAAa,KAAK,GAAG,KAEpEA,EAAI,eAAe,MAGdA;AACT;AAaA,SAAS0C,GAAkB1C,GAAKuC,GAAcC,GAAc;AAC1D,SAAAxC,EAAI,mBAAmBuC,KAAgB,QACvCvC,EAAI,mBAAmBwC,KAAgB,QACvCF,GAAUtC,GAAKA,EAAI,kBAAkBA,EAAI,gBAAgB,GAClDA;AACT;AAYA,SAAS2C,GAAe3C,GAAKpxB,GAAO;AAClC,SAAAoxB,EAAI,cAAcpxB,KAAS,GAC3BoxB,EAAI,UAAU,KAAK,gBAAgBA,EAAI,WAAW,GAElDsC,GAAUtC,GAAKA,EAAI,kBAAkBA,EAAI,gBAAgB,GAClDA;AACT;AAYA,SAAS4C,GAAkB5C,GAAKlqB,GAAO;AACrC,EAAAkqB,EAAI,QAAQlqB,GACZkqB,EAAI,UAAU,OAAOlqB,CAAK,EAAE,KAAK,gBAAgBkqB,EAAI,WAAW,GAC5DA,EAAI,gBACNA,EAAI,aAAa,QAAQ,SAAQ,EAAG,QAAQ,SAAU3N,GAAO;AAC3D,IAAIA,EAAM,SAAS,UAAQA,EAAM,KAAKvc,CAAK;AAAA,EAC7C,CAAC,GAECkqB,EAAI,gBACNA,EAAI,aAAa,QAAQ,SAAQ,EAAG,QAAQ,SAAU3N,GAAO;AAC3D,IAAIA,EAAM,SAAS,UAAQA,EAAM,KAAKvc,CAAK;AAAA,EAC7C,CAAC;AAEL;ACpMA,SAAS+sB,GAAqB9xB,GAAM+xB,GAAU;AAC5C,MAAI;AACF,UAAM,CAAC7mB,GAAIC,CAAE,IAAIigB,GAAiBprB,GAAM+xB,EAAS,CAAC,GAAGA,EAAS,CAAC,CAAC,GAC1D3E,IAAKptB,EAAK,KAAI;AACpB,QAAI,CAACotB,KAAM,CAACA,EAAG,SAAS,CAACA,EAAG,OAAQ,QAAO;AAC3C,QAAIjN,IAAK,KAAK,IAAI,GAAG,KAAK,IAAI,IAAIjV,IAAKkiB,EAAG,KAAKA,EAAG,KAAK,CAAC,GACpDhN,IAAK,KAAK,IAAI,GAAG,KAAK,IAAI,IAAIjV,IAAKiiB,EAAG,KAAKA,EAAG,MAAM,CAAC;AACzD,UAAMoB,IAAKrO,GAAIsO,IAAK,IAAItO,GAAIhL,IAAKiL,GAAIsO,IAAK,IAAItO,GACxC5jB,IAAI,KAAK,IAAIgyB,GAAIC,GAAItZ,GAAIuZ,CAAE;AACjC,WAAIlyB,MAAMgyB,IAAIrO,IAAK,IACV3jB,MAAMiyB,IAAItO,IAAK,IACf3jB,MAAM2Y,IAAIiL,IAAK,IACnBA,IAAK,GACH,EAAE,GAAGD,GAAI,GAAGC,EAAE;AAAA,EACvB,QAAY;AACV,WAAO;AAAA,EACT;AACF;AAKA,SAAS4R,GAAUp0B,GAASq0B,GAAY;AACtC,SAAOr0B,KAAW,OAAOA,EAAQq0B,CAAU,KAAM;AACnD;AAaA,SAASC,GAAajD,GAAK6B,GAAU/vB,GAAU;AAC7C,MAAI,CAACkuB,EAAI,YAAa,QAAO;AAE7B,QAAMvG,IAASuG,EAAI,UAChB,OAAOA,EAAI,eAAe,CAAC,EAC3B,KAAK;AAAA,IACJ,IAAIluB,EAAS,CAAC;AAAA,IACd,IAAIA,EAAS,CAAC;AAAA,IACd,MAAMkuB,EAAI;AAAA,IACV,QAAQA,EAAI;AAAA,IACZ,gBAAgBA,EAAI;AAAA,IACpB,kBAAkB;AAAA,EACxB,CAAK,EACA,SAAS,kBAAkB,EAC3B,SAAS6B,IAAW,4BAA4B,yBAAyB;AAG5E,MAAI;AACF,IAAApI,EAAO,KAAK,MAAM,SAAS;AAAA,EAC7B,QAAY;AACV,IAAAA,EAAO,KAAK,aAAa,SAAS,cAAc;AAAA,EAClD;AAEA,QAAMyJ,IAAY;AAAA,IAChB,SAASzJ;AAAA,IACT,UAAUoI;AAAA,IACV,UAAU/vB;AAAA,IACV,YAAY;AAAA,IACZ,gBAAgB+vB,IAAW7B,EAAI,SAASA,EAAI;AAAA,EAChD;AAGE,SAAAmD,GAAgBnD,GAAKkD,CAAS,GAEvBA;AACT;AAWA,SAASC,GAAgBnD,GAAKkD,GAAW;AACvC,MAAIE,IAAa;AAIjB,MAAI,CAACL,GAAUG,EAAU,SAAS,WAAW,GAAG;AAC9C,YAAQ;AAAA,MACN;AAAA,IACN;AACI;AAAA,EACF;AAGA,EAAAA,EAAU,QAAQ,UAAS,GAG3BA,EAAU,QACP,GAAG,cAAc,SAAU7jB,GAAO;AAEjB,IAAC6jB,EAAU,QAAQ,GAAE,GAAIA,EAAU,QAAQ;AAG3D,QAAI;AACF,MAAAA,EAAU,QAAQ,KAAK,MAAM,SAAS;AAAA,IACxC,QAAa;AACX,MAAAA,EAAU,QAAQ,KAAK,aAAa,SAAS,kBAAkB;AAAA,IACjE;AAGA,IAAAA,EAAU,QAAQ,MAAK,GAGvBG,GAAarD,GAAKkD,CAAS;AAAA,EAC7B,CAAC,EACA,GAAG,YAAY,SAAU7jB,GAAO;AAE/B,UAAMikB,IAAa,CAACJ,EAAU,QAAQ,GAAE,GAAIA,EAAU,QAAQ,IAAI;AAClE,IAAAA,EAAU,WAAWI;AAKrB,UAAMC,IAAalkB,EAAM,OAAO;AAChC,IAAA+jB,IAAaI,GAAexD,GAAKuD,GAAYL,CAAS,GACtDO,GAAoBL,CAAU,GAE9BM,GAAuB1D,GAAKkD,GAAWI,GAAYF,CAAU;AAAA,EAC/D,CAAC,EACA,GAAG,WAAW,SAAU/jB,GAAO;AAE9B,QAAI;AACF,MAAA6jB,EAAU,QAAQ,KAAK,MAAM,SAAS;AAAA,IACxC,QAAa;AACX,MAAAA,EAAU,QAAQ,KAAK,aAAa,SAAS,cAAc;AAAA,IAC7D;AAQA,QALIlD,EAAI,aACN2D,GAA2B3D,EAAI,SAAS,GAItCoD;AACF,MAAAQ,GAAqB5D,GAAKkD,GAAWE,CAAU,GAC/CS,GAAwB;AAAA,SACnB;AAEL,YAAMC,IAAe,CAACZ,EAAU,QAAQ,GAAE,GAAIA,EAAU,QAAQ,IAAI,GAC9Da,IAAcC,GAAkBhE,GAAK8D,CAAY;AAGvD,MAAIZ,EAAU,WACZlD,EAAI,qBAAqB+D,IAEzB/D,EAAI,qBAAqB+D,GAI3BH,GAAqB5D,GAAKkD,GAAWa,CAAW;AAAA,IAClD;AAEA,IAAAX,IAAa;AAAA,EACf,CAAC;AACL;AAWA,SAASC,GAAarD,GAAKkD,GAAW;AACpC,EAAAA,EAAU,aAAa,IAGlBA,EAAU,mBACbA,EAAU,iBAAiBA,EAAU,WAAWlD,EAAI,SAASA,EAAI,SAI9DkD,EAAU,iBACbA,EAAU,eAAelD,EAAI;AAI/B,QAAMiE,IAAgBf,EAAU,WAAWlD,EAAI,SAASA,EAAI;AAC5D,EAAIiE,KAAiBA,EAAc,mBACjCA,EAAc,OAAM,GAGhBf,EAAU,WACZlD,EAAI,qBAAqB,OAEzBA,EAAI,qBAAqB,OAKzBkD,EAAU,WACZlD,EAAI,SAAS,OAEbA,EAAI,SAAS;AAEjB;AAYA,SAAS0D,GAAuB1D,GAAKkD,GAAWpxB,GAAUoyB,GAAY;AAEpE,QAAMC,IAAWjB,EAAU,gBAAgBlD,EAAI;AAM/C,MAAIoE,IAAc,MACdC,IAAgB;AACpB,EACEH,KACA,OAAOA,EAAW,QAAS,cAC3B,CAACA,EAAW,kBACZ,EAAEA,EAAW,YAAYA,EAAW,SAAS,kBAAkB,OAE/DG,IAAgBxB,GAAqBqB,GAAYpyB,CAAQ,GACrDuyB,MAAeD,IAAcF;AAInC,QAAMI,IAAc;AAAA,IAClB,MAAM,WAAY;AAChB,aAAO;AAAA,QACL,GAAGxyB,EAAS,CAAC,IAAI;AAAA,QACjB,GAAGA,EAAS,CAAC,IAAI;AAAA,QACjB,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,IAAIA,EAAS,CAAC;AAAA,QACd,IAAIA,EAAS,CAAC;AAAA,MACtB;AAAA,IACI;AAAA,IACA,MAAM;AAAA,MACJ,QAAQ,WAAY;AAClB,eAAO,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAC;AAAA,MAC7C;AAAA,IACN;AAAA,EACA,GAGQyyB,IAAiBvE,EAAI,QACrBwE,IAAiBxE,EAAI,QACrByE,IAAezE,EAAI,MACnB0E,IAAuB1E,EAAI,cAC3B2E,IAAuB3E,EAAI;AAEjC,MAAI;AAEF,IAAAA,EAAI,OAAOmE,GAEPjB,EAAU,YAERkB,KAEFpE,EAAI,SAASoE,GACbpE,EAAI,eAAeqE,MAEnBrE,EAAI,SAASsE,GACbtE,EAAI,eAAe,OAEhBA,EAAI,WAEPA,EAAI,SAAS;AAAA,MACX,MAAM,WAAY;AAChB,eAAO;AAAA,UACL,GAAGluB,EAAS,CAAC,IAAI;AAAA,UACjB,GAAGA,EAAS,CAAC,IAAI;AAAA,UACjB,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,IAAIA,EAAS,CAAC,IAAI;AAAA,UAClB,IAAIA,EAAS,CAAC;AAAA,QAC5B;AAAA,MACU;AAAA,MACA,MAAM;AAAA,QACJ,QAAQ,WAAY;AAClB,iBAAO,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAC;AAAA,QAC7C;AAAA,MACZ;AAAA,IACA,OAIUsyB,KAEFpE,EAAI,SAASoE,GACbpE,EAAI,eAAeqE,MAEnBrE,EAAI,SAASsE,GACbtE,EAAI,eAAe,OAEhBA,EAAI,WAEPA,EAAI,SAAS;AAAA,MACX,MAAM,WAAY;AAChB,eAAO;AAAA,UACL,GAAGluB,EAAS,CAAC,IAAI;AAAA,UACjB,GAAGA,EAAS,CAAC,IAAI;AAAA,UACjB,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,IAAIA,EAAS,CAAC,IAAI;AAAA,UAClB,IAAIA,EAAS,CAAC;AAAA,QAC5B;AAAA,MACU;AAAA,MACA,MAAM;AAAA,QACJ,QAAQ,WAAY;AAClB,iBAAO,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAC;AAAA,QAC7C;AAAA,MACZ;AAAA,IACA;AAKI,UAAM8yB,IAAW7E,GAA4BC,CAAG;AAGhD,IAAAA,EAAI,UAAU,KAAK4E,CAAQ,GAC3B5E,EAAI,QAAQ,KAAK4E,CAAQ;AAAA,EAC3B,UAAC;AAGC,IAAA5E,EAAI,SAASuE,GACbvE,EAAI,SAASwE,GACbxE,EAAI,OAAOyE,GACXzE,EAAI,eAAe0E,GACnB1E,EAAI,eAAe2E;AAAA,EACrB;AACF;AAaA,SAASE,GAAiBl2B,GAASsK,GAAO6rB,IAAY,IAAO;AAC3D,MAAI;AAEF,UAAMzoB,IAAM1N,EAAQ,KAAK,OAAM,GACzByO,IAAOzO,EAAQ,KAAI;AAEzB,IAAIm2B,KACF,QAAQ,IAAI,mBAAmB;AAAA,MAC7B,SAASn2B,EAAQ;AAAA,MACjB,OAAOsK;AAAA,MACP,MAAMmE;AAAA,MACN,KAAKf;AAAA,IACb,CAAO;AAIH,UAAMZ,IAAMY,EAAI,IAAIA,EAAI,IAAIA,EAAI,IAAIA,EAAI;AACxC,QAAI,KAAK,IAAIZ,CAAG,IAAI;AAElB,aAAIqpB,KACF,QAAQ,IAAI,iDAAiD,GAG7D7rB,EAAM,CAAC,KAAKmE,EAAK,KACjBnE,EAAM,CAAC,KAAKmE,EAAK,IAAIA,EAAK,SAC1BnE,EAAM,CAAC,KAAKmE,EAAK,KACjBnE,EAAM,CAAC,KAAKmE,EAAK,IAAIA,EAAK;AAK9B,UAAMue,IAAOtf,EAAI,IAAIZ,GACfmgB,IAAO,CAACvf,EAAI,IAAIZ,GAChBogB,IAAO,CAACxf,EAAI,IAAIZ,GAChBqgB,IAAOzf,EAAI,IAAIZ,GACfsgB,KAAQ1f,EAAI,IAAIA,EAAI,IAAIA,EAAI,IAAIA,EAAI,KAAKZ,GACzCugB,KAAQ3f,EAAI,IAAIA,EAAI,IAAIA,EAAI,IAAIA,EAAI,KAAKZ,GAGzC4f,IAASM,IAAO1iB,EAAM,CAAC,IAAI4iB,IAAO5iB,EAAM,CAAC,IAAI8iB,GAC7CT,IAASM,IAAO3iB,EAAM,CAAC,IAAI6iB,IAAO7iB,EAAM,CAAC,IAAI+iB;AAEnD,IAAI8I,KACF,QAAQ,IAAI,sBAAsB,EAAE,QAAAzJ,GAAQ,QAAAC,EAAM,CAAE;AAGtD,QAAIptB,IAAS;AAGb,QAAIS,EAAQ,SAAS,UAAU;AAC7B,YAAM6L,IAAK,WAAW7L,EAAQ,KAAK,IAAI,CAAC,KAAKyO,EAAK,IAC5C3C,IAAK,WAAW9L,EAAQ,KAAK,IAAI,CAAC,KAAKyO,EAAK,IAC5C3I,IAAI,WAAW9F,EAAQ,KAAK,GAAG,CAAC,KAAK,GACrCgM,IAAK0gB,IAAS7gB,GACdI,IAAK0gB,IAAS7gB;AACpB,MAAAvM,IAASyM,IAAKA,IAAKC,IAAKA,KAAMnG,IAAIA,GAC9BqwB,KACF,QAAQ,IAAI,gBAAgB;AAAA,QAC1B,IAAAtqB;AAAA,QACA,IAAAC;AAAA,QACA,GAAAhG;AAAA,QACA,IAAAkG;AAAA,QACA,IAAAC;AAAA,QACA,UAAU,KAAK,KAAKD,IAAKA,IAAKC,IAAKA,CAAE;AAAA,QACrC,QAAA1M;AAAA,MACV,CAAS;AAAA,IAEL,WAAWS,EAAQ,SAAS,WAAW;AACrC,YAAM6L,IAAK,WAAW7L,EAAQ,KAAK,IAAI,CAAC,KAAKyO,EAAK,IAC5C3C,IAAK,WAAW9L,EAAQ,KAAK,IAAI,CAAC,KAAKyO,EAAK,IAC5ChD,IAAK,WAAWzL,EAAQ,KAAK,IAAI,CAAC,KAAK,GACvC0L,IAAK,WAAW1L,EAAQ,KAAK,IAAI,CAAC,KAAK,GACvCgM,IAAK0gB,IAAS7gB,GACdI,IAAK0gB,IAAS7gB;AACpB,MAAAvM,IAAUyM,IAAKA,KAAOP,IAAKA,KAAOQ,IAAKA,KAAOP,IAAKA,MAAO,GACtDyqB,KACF,QAAQ,IAAI,iBAAiB,EAAE,IAAAtqB,GAAI,IAAAC,GAAI,IAAAL,GAAI,IAAAC,GAAI,IAAAM,GAAI,IAAAC,GAAI,QAAA1M,EAAM,CAAE;AAAA,IAEnE;AAEE,MAAAA,IACEmtB,KAAUje,EAAK,KACfie,KAAUje,EAAK,IAAIA,EAAK,SACxBke,KAAUle,EAAK,KACfke,KAAUle,EAAK,IAAIA,EAAK,QACtB0nB,KACF,QAAQ,IAAI,cAAc;AAAA,QACxB,QAAAzJ;AAAA,QACA,QAAAC;AAAA,QACA,OAAOle,EAAK;AAAA,QACZ,OAAOA,EAAK;AAAA,QACZ,WAAWA,EAAK;AAAA,QAChB,YAAYA,EAAK;AAAA,QACjB,QAAAlP;AAAA,MACV,CAAS;AAIL,WAAOA;AAAA,EACT,SAASoM,GAAG;AAEV,IAAIwqB,KACF,QAAQ,IAAI,0CAA0CxqB,CAAC;AAEzD,UAAM8C,IAAOzO,EAAQ,KAAI;AACzB,WACEsK,EAAM,CAAC,KAAKmE,EAAK,KACjBnE,EAAM,CAAC,KAAKmE,EAAK,IAAIA,EAAK,SAC1BnE,EAAM,CAAC,KAAKmE,EAAK,KACjBnE,EAAM,CAAC,KAAKmE,EAAK,IAAIA,EAAK;AAAA,EAE9B;AACF;AAYA,SAAS2nB,GAAiBp2B,GAASq2B,GAAW;AAC5C,MAAI;AACF,UAAM5nB,IAAOzO,EAAQ,KAAI,GACnB0N,IAAM1N,EAAQ,KAAK,OAAM,GAGzBs2B,IAAaD,EAAU,MAAK,EAAG,SAAS,gBAAgB,GAGxDE,IAAcD,EAAW,KAAK7nB,EAAK,OAAOA,EAAK,MAAM,EAAE,KAAK;AAAA,MAChE,GAAGA,EAAK;AAAA,MACR,GAAGA,EAAK;AAAA,MACR,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,gBAAgB;AAAA,MAChB,oBAAoB;AAAA,IAC1B,CAAK;AAGD,QAAIf,GAAK;AAeP,YAAMuoB,IAbU;AAAA,QACd,CAACxnB,EAAK,GAAGA,EAAK,CAAC;AAAA,QACf,CAACA,EAAK,IAAIA,EAAK,OAAOA,EAAK,CAAC;AAAA,QAC5B,CAACA,EAAK,IAAIA,EAAK,OAAOA,EAAK,IAAIA,EAAK,MAAM;AAAA,QAC1C,CAACA,EAAK,GAAGA,EAAK,IAAIA,EAAK,MAAM;AAAA,MACrC,EAEyC,IAAI,CAAC+nB,MAAW;AAAA,QACjD9oB,EAAI,IAAI8oB,EAAO,CAAC,IAAI9oB,EAAI,IAAI8oB,EAAO,CAAC,IAAI9oB,EAAI;AAAA,QAC5CA,EAAI,IAAI8oB,EAAO,CAAC,IAAI9oB,EAAI,IAAI8oB,EAAO,CAAC,IAAI9oB,EAAI;AAAA,MACpD,CAAO,EAKI;AAAA,QACC,CAAC8oB,GAAQn3B,OAAOA,MAAM,IAAI,MAAM,OAAOm3B,EAAO,CAAC,IAAI,MAAMA,EAAO,CAAC;AAAA,MAC7E,EACW,KAAK,GAAG,IAAI;AAEjB,MAAAF,EAAW,KAAKL,CAAQ,EAAE,KAAK;AAAA,QAC7B,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,gBAAgB;AAAA,QAChB,oBAAoB;AAAA,MAC5B,CAAO;AAAA,IACH;AAGA,QAAInG,GAASC;AACb,QAAI;AACF,MAAAD,IAAUpiB,EAAI,IAAIe,EAAK,KAAKf,EAAI,IAAIe,EAAK,KAAKf,EAAI,GAClDqiB,IAAUriB,EAAI,IAAIe,EAAK,KAAKf,EAAI,IAAIe,EAAK,KAAKf,EAAI;AAAA,IACpD,QAAY;AACV,MAAAoiB,IAAUrhB,EAAK,IACfshB,IAAUthB,EAAK;AAAA,IACjB;AAEA,WAAA6nB,EAAW,OAAO,CAAC,EAAE,KAAK;AAAA,MACxB,IAAIxG;AAAA,MACJ,IAAIC;AAAA,MACJ,MAAM;AAAA,IACZ,CAAK,GAEMuG;AAAA,EACT,SAAS,GAAG;AACV,mBAAQ,KAAK,0CAA0C,CAAC,GACjD;AAAA,EACT;AACF;AAUA,SAAStB,GAA2BqB,GAAW;AAC7C,MAAI;AAEF,IADsBA,EAAU,KAAK,iBAAiB,EACxC,QAAQ,CAAC/wB,MAAOA,EAAG,OAAM,CAAE;AAAA,EAC3C,SAASqG,GAAG;AACV,YAAQ,KAAK,2CAA2CA,CAAC;AAAA,EAC3D;AACF;AAaA,SAASkpB,GAAexD,GAAK1lB,GAAG4oB,GAAW;AACzC,QAAM4B,IAAY9E,EAAI,aAAa;AAGnC,EAAI8E,KACFnB,GAA2B3D,EAAI,SAAS;AAI1C,WAASoF,EAAiBJ,GAAW;AACnC,UAAMK,IAAS,CAAA;AAEf,aAASC,EAAkB32B,GAAS;AAElC,MAAI42B,EAAc52B,CAAO,KACvB02B,EAAO,KAAK12B,CAAO,GAIjBA,EAAQ,YAAY,OAAOA,EAAQ,YAAa,cAClDA,EAAQ,SAAQ,EAAG,QAAQ22B,CAAiB;AAAA,IAEhD;AAEA,WAAAA,EAAkBN,CAAS,GACpBK;AAAA,EACT;AAGA,WAASE,EAAc52B,GAAS;AAuB9B,QApBI,CADoB,CAAC,UAAU,QAAQ,WAAW,WAAW,MAAM,EAClD,SAASA,EAAQ,IAAI,KAKtCA,EAAQ,KAAK,eAAe,KAK5BA,EAAQ,YAAYA,EAAQ,SAAS,kBAAkB,KAKvDA,EAAQ,kBAKRA,EAAQ,YAAYA,EAAQ,SAAS,gBAAgB;AACvD,aAAO;AAIT,QAAIA,EAAQ,UAAU;AACpB,YAAM62B,IAAY72B,EAAQ,KAAK;AAC/B,UAAI62B,MAGAA,EAAU,SAAS,yBAAyB,KAC5CA,EAAU,SAAS,mBAAmB,KACtCA,EAAU,SAAS,qBAAqB,KAOxCA,EAAU,SAAS,0BAA0B,KAC7CA,EAAU,SAAS,mBAAmB,KACtCA,EAAU,SAAS,kBAAkB,KAOrCA,EAAU,SAAS,sBAAsB,KACzCA,EAAU,SAAS,WAAW,KAC9BA,EAAU,SAAS,YAAY;AAE/B,eAAO;AAAA,IAGb;AAGA,UAAMpoB,IAAOzO,EAAQ,KAAI;AACzB,QAAIyO,EAAK,QAAQ,MAAMA,EAAK,SAAS;AACnC,aAAO;AAQT,QAAI;AAEF,YAAMqoB,IADgB,OAAO,iBAAiB92B,EAAQ,IAAI,EAC7B;AAC7B,UACE82B,MAAW,eACXA,MAAW,eACXA,MAAW,eACXA,MAAW,eACXA,MAAW,eACXA,MAAW,eACXA,MAAW;AAEX,eAAO;AAAA,IAEX,QAAY;AAAA,IAEZ;AAGA,UAAMC,IAAY/2B,EAAQ,KAAK;AAC/B,QAAI+2B,MAEAA,EAAU,SACVA,EAAU,UACVA,EAAU,UACVA,EAAU;AAEV,aAAO;AAKX,QAAIrnB,IAAS1P,EAAQ,OAAM;AAC3B,WAAO0P,KAAUA,EAAO,SAAS,SAAO;AACtC,UAAIA,EAAO,UAAU;AACnB,cAAMsnB,IAAgBtnB,EAAO,KAAK;AAClC,YACEsnB,MACCA,EAAc,SAAS,kBAAkB,KACxCA,EAAc,SAAS,kBAAkB,KACzCA,EAAc,SAAS,iBAAiB;AAE1C,iBAAO;AAAA,MAEX;AAEA,YAAMC,IAAWvnB,EAAO,KAAK,IAAI;AACjC,UACEunB,MACCA,EAAS,SAAS,UAAU,KAC3BA,EAAS,SAAS,UAAU,KAC5BA,EAAS,SAAS,QAAQ;AAE5B,eAAO;AAET,MAAAvnB,IAASA,EAAO,OAAM;AAAA,IACxB;AAGA,UAAMwnB,IAAYl3B,EAAQ,KAAK,IAAI;AACnC,QACEk3B,MACCA,EAAU,SAAS,UAAU,KAC5BA,EAAU,SAAS,UAAU,KAC7BA,EAAU,SAAS,UAAU,KAC7BA,EAAU,SAAS,YAAY,KAC/BA,EAAU,SAAS,QAAQ,KAC3BA,EAAU,WAAW,MAAM;AAE7B,aAAO;AAIT,UAAMC,IAAOn3B,EAAQ,KAAK,MAAM,GAC1Bo3B,IAASp3B,EAAQ,KAAK,QAAQ;AAMpC,WALI,GAACm3B,KAAQ,CAACC,MAKVD,MAAS,iBAAiBA,MAAS,YAEjC,CAACC,KAAUA,MAAW,UAAUA,MAAW;AAAA,EAMnD;AAGA,QAAMnJ,IAAUoD,EAAI,UAAU,KAAI,GAG5BgG,IAAUpJ,EAAQ,KAAK,sBAAqB,GAC5CX,IAAO3hB,EAAE,UAAU0rB,EAAQ,MAC3B9J,IAAO5hB,EAAE,UAAU0rB,EAAQ;AAEjC,EAAIlB,KACF,QAAQ,IAAI,0BAA0B,EAAE,MAAA7I,GAAM,MAAAC,EAAI,CAAE;AAItD,QAAM+J,IAAeb,EAAiBxI,CAAO;AAE7C,EAAIkI,MACF,QAAQ,IAAI,wBAAwBmB,EAAa,MAAM,GACvDA,EAAa,QAAQ,CAACt3B,GAAS0U,MAAU;AACvC,YAAQ,IAAI,gBAAgBA,CAAK,KAAK;AAAA,MACpC,MAAM1U,EAAQ;AAAA,MACd,IAAIA,EAAQ,KAAK,IAAI;AAAA,MACrB,SAASA,EAAQ,KAAK,YAClB,MAAM,KAAKA,EAAQ,KAAK,SAAS,IACjC,CAAA;AAAA,MACJ,MAAMA,EAAQ,KAAK,MAAM;AAAA,MACzB,QAAQA,EAAQ,KAAK,QAAQ;AAAA,MAC7B,MAAMA,EAAQ,KAAI;AAAA,MAClB,SAASu3B,GAAkBlG,GAAKrxB,GAASu0B,CAAS;AAAA,IAC1D,CAAO;AAAA,EACH,CAAC,GAGD+C,EAAa,QAAQ,CAACt3B,MAAY;AAChC,IAAIu3B,GAAkBlG,GAAKrxB,GAASu0B,CAAS,KAC3C6B,GAAiBp2B,GAASqxB,EAAI,SAAS;AAAA,EAE3C,CAAC;AAIH,QAAMmG,IAAa,CAAA;AA4CnB,SA1CAF,EAAa,QAAQ,SAAUt3B,GAAS;AACtC,QAAIu3B,GAAkBlG,GAAKrxB,GAASu0B,CAAS;AAC3C,UAAI;AAIF,YAFkB2B,GAAiBl2B,GAAS,CAACstB,GAAMC,CAAI,GAAG4I,CAAS,GAEpD;AAGb,cAAIrG,GAASC;AACb,cAAI;AACF,kBAAMthB,IAAOzO,EAAQ,KAAI,GACnB0N,IAAM1N,EAAQ,KAAK,OAAM;AAC/B,YAAA8vB,IAAUpiB,EAAI,IAAIe,EAAK,KAAKf,EAAI,IAAIe,EAAK,KAAKf,EAAI,GAClDqiB,IAAUriB,EAAI,IAAIe,EAAK,KAAKf,EAAI,IAAIe,EAAK,KAAKf,EAAI;AAAA,UACpD,QAAY;AACV,kBAAMe,IAAOzO,EAAQ,KAAI;AACzB,YAAA8vB,IAAUrhB,EAAK,IACfshB,IAAUthB,EAAK;AAAA,UACjB;AAEA,gBAAMuhB,IAAW,KAAK;AAAA,YACpB,KAAK,IAAI1C,IAAOwC,GAAS,CAAC,IAAI,KAAK,IAAIvC,IAAOwC,GAAS,CAAC;AAAA,UACpE;AAEU,UAAIoG,KACF,QAAQ,IAAI,oBAAoB;AAAA,YAC9B,SAASn2B,EAAQ;AAAA,YACjB,UAAAgwB;AAAA,UACd,CAAa,GAGHwH,EAAW,KAAK,EAAE,SAASx3B,GAAS,UAAUgwB,GAAU;AAAA,QAC1D;AAAA,MACF,SAAS+C,GAAI;AAEX,gBAAQ,KAAK,2CAA2CA,CAAE;AAAA,MAC5D;AAAA,EAEJ,CAAC,GAGGyE,EAAW,SAAS,KACtBA,EAAW,KAAK,SAAU5xB,GAAGe,GAAG;AAC9B,WAAOf,EAAE,WAAWe,EAAE;AAAA,EACxB,CAAC,GACGwvB,KACF,QAAQ,IAAI,+BAA+BqB,EAAW,CAAC,CAAC,GAEnDA,EAAW,CAAC,EAAE,YAGnBrB,KACF,QAAQ,IAAI,sBAAsB,GAE7B;AACT;AAaA,SAASoB,GAAkBlG,GAAKrxB,GAASu0B,GAAW;AAclD,MAAI;AACF,QAAIkD,IAAMz3B,EAAQ;AAClB,WAAOy3B,KAAOA,EAAI,gBAAgB,CAACA,EAAI,aAAa,cAAc;AAChE,MAAAA,IAAMA,EAAI;AAEZ,QAAI,EAAEA,KAAOA,EAAI,gBAAgBA,EAAI,aAAa,cAAc;AAC9D,aAAO;AAAA,EAEX,QAAY;AACV,WAAO;AAAA,EACT;AASA,MANIz3B,EAAQ,KAAK,eAAe,KAG5BA,EAAQ,YAAYA,EAAQ,SAAS,kBAAkB,KAGvDA,EAAQ,eAAgB,QAAO;AAGnC,QAAM03B,IAAcnD,EAAU,WAAWlD,EAAI,SAASA,EAAI;AAC1D,SAAIrxB,MAAY03B;AAGlB;AAYA,SAASzC,GAAqB5D,GAAKkD,GAAWjd,GAAQ;AAIpD,MAAIqgB,IAAY;AAChB,MAAI;AACF,IAAAA,IAAY,EAAE,GAAGpD,EAAU,QAAQ,MAAM,GAAGA,EAAU,QAAQ,KAAI;AAAA,EACpE,QAAY;AAAA,EAEZ;AAGA,QAAMqD,IAAYrD,EAAU,WAAWlD,EAAI,SAASA,EAAI;AAyBxD,MAtBIuG,KAAaA,EAAU,mBACzBA,EAAU,OAAM,GAGZrD,EAAU,WACZlD,EAAI,qBAAqB,OAEzBA,EAAI,qBAAqB,OAKzBkD,EAAU,WACZlD,EAAI,SAAS/Z,IAEb+Z,EAAI,SAAS/Z,GAGfid,EAAU,aAAa,IAInB,CAACqD,KAAaA,MAActgB,GAAQ;AAEtC,QAAIugB;AACJ,IAAItD,EAAU,WACZsD,IAAiB,SAAUnnB,GAAO;AAChC,MAAA2gB,EAAI,OAAM;AAAA,IACZ,IAEAwG,IAAiB,SAAUnnB,GAAO;AAChC,MAAA2gB,EAAI,OAAM;AAAA,IACZ;AAIF,UAAMyG,IAAoBvD,EAAU,WAChC,0BACA,yBACEwD,IAAoB1G,EAAIyG,CAAiB;AAc/C,QAXIC,KAAqBH,MACvBA,EAAU,IAAI,YAAYG,CAAiB,GAC3CH,EAAU,IAAI,cAAcG,CAAiB,GAC7CH,EAAU,IAAI,aAAaG,CAAiB,GAC5CH,EAAU,IAAI,WAAWG,CAAiB,GAC1CH,EAAU,IAAI,UAAUG,CAAiB,GACzCH,EAAU,IAAI,UAAUG,CAAiB,GACzCH,EAAU,IAAI,aAAaG,CAAiB,IAI1CxD,EAAU,UAAU;AAEtB,UAAIqD,KAAaA,EAAU,MAAM;AAC/B,cAAMljB,IAAQkjB,EAAU,KAAK,QAAQvG,CAAG;AACxC,QAAI3c,IAAQ,MACVkjB,EAAU,KAAK,OAAOljB,GAAO,CAAC;AAAA,MAElC;AAEA,MAAA4C,EAAO,OAAOA,EAAO,QAAQ,CAAA,GACzBA,EAAO,KAAK,QAAQ+Z,CAAG,MAAM,MAC/B/Z,EAAO,KAAK,KAAK+Z,CAAG;AAAA,IAExB,OAAO;AAGL,UAAIuG,KAAaA,EAAU,YAAY;AACrC,cAAMljB,IAAQkjB,EAAU,WAAW,QAAQvG,CAAG;AAC9C,QAAI3c,IAAQ,MACVkjB,EAAU,WAAW,OAAOljB,GAAO,CAAC;AAAA,MAExC;AAEA,MAAA4C,EAAO,aAAaA,EAAO,cAAc,CAAA,GACrCA,EAAO,WAAW,QAAQ+Z,CAAG,MAAM,MACrC/Z,EAAO,WAAW,KAAK+Z,CAAG;AAAA,IAE9B;AAGA,IAAAA,EAAIyG,CAAiB,IAAID,GAGzBvgB,EAAO,GAAG,YAAYugB,CAAc,GACpCvgB,EAAO,GAAG,cAAcugB,CAAc,GACtCvgB,EAAO,GAAG,aAAaugB,CAAc,GACrCvgB,EAAO,GAAG,WAAWugB,CAAc,GACnCvgB,EAAO,GAAG,UAAUugB,CAAc,GAClCvgB,EAAO,GAAG,UAAUugB,CAAc,GAClCvgB,EAAO,GAAG,aAAaugB,CAAc;AAAA,EACvC;AAMA,MAHAxG,EAAI,OAAM,GAGNA,EAAI,UAAUA,EAAI,QAAQ;AAC5B,UAAM4E,IAAW7E,GAA4BC,CAAG;AAChD,QAAI4E,KAAYA,EAAS,UAAU,GAAG;AACpC,UAAI/d;AACJ,UAAIqc,EAAU;AAEZ,QAAArc,IAAc,CAAC+d,EAAS,CAAC,EAAE,CAAC,GAAGA,EAAS,CAAC,EAAE,CAAC,CAAC;AAAA,WACxC;AAEL,cAAMhd,IAAcgd,EAASA,EAAS,SAAS,CAAC;AAChD,QAAA/d,IAAc;AAAA,UACZe,EAAYA,EAAY,SAAS,CAAC;AAAA,UAClCA,EAAYA,EAAY,SAAS,CAAC;AAAA,QAC5C;AAAA,MACM;AAGA,MAAAsb,EAAU,WAAWrc,GACrBqc,EAAU,QAAQ,OAAOrc,EAAY,CAAC,GAAGA,EAAY,CAAC,CAAC;AAAA,IACzD;AAAA,EACF;AAKA,MAAI,OAAOmZ,EAAI,oBAAqB,YAAY;AAC9C,UAAM2G,IAAY,CAAC,CAAC1gB,EAAO;AAC3B,QAAI2gB,IAAe;AACnB,QAAI,CAACD;AACH,UAAI;AAGF,YAAI1yB,IAAKgS,EAAO,QAAQ;AACxB,eAAOhS,KAAMA,EAAG,gBAAgB,CAACA,EAAG,aAAa,cAAc;AAC7D,UAAAA,IAAKA,EAAG;AAEV,QAAA2yB,IACG3yB,KAAMA,EAAG,gBAAgBA,EAAG,aAAa,cAAc,KAAM;AAAA,MAClE,QAAY;AAAA,MAEZ;AAIF,QAAIgF,IAAQqtB;AACZ,QAAI,CAACrtB;AACH,UAAI;AACF,QAAAA,IAAQ,EAAE,GAAGgN,EAAO,GAAE,GAAI,GAAGA,EAAO,KAAI;AAAA,MAC1C,QAAY;AAAA,MAEZ;AAEF,IAAA+Z,EAAI,iBAAiB;AAAA,MACnB,OAAOkD,EAAU,WAAW,WAAW;AAAA,MACvC,cAAA0D;AAAA,MACA,WAAAD;AAAA,MACA,OAAA1tB;AAAA,IACN,CAAK;AAAA,EACH;AACF;AAGA,IAAI4tB,KAAuB;AAU3B,SAASpD,GAAoBxd,GAAQ;AAEnC,MAAIA,MAAW4gB;AAOf,QAFAhD,GAAwB,GAEpB5d,GAAQ;AACV,MAAA4gB,KAAuB5gB,GAGvBA,EAAO,kBAAkBA,EAAO,KAAK,QAAQ,GAC7CA,EAAO,uBAAuBA,EAAO,KAAK,cAAc,GACxDA,EAAO,2BAA2BA,EAAO,KAAK,kBAAkB,GAChEA,EAAO,yBAAyBA,EAAO,KAAK,gBAAgB,GAG5DA,EAAO,KAAK;AAAA,QACV,QAAQ;AAAA;AAAA,QACR,gBAAgB;AAAA;AAAA,QAChB,oBAAoB;AAAA;AAAA,QACpB,kBAAkB;AAAA;AAAA,MACxB,CAAK;AAGD,UAAI;AACF,cAAMnS,IAAQmS,EAAO,KAAK;AAK1B,YAJAnS,EAAM,mBAAmB,KACzBA,EAAM,YAAY,4CAGd,CAAC,SAAS,eAAe,4BAA4B,GAAG;AAC1D,gBAAMgzB,IAAa,SAAS,cAAc,OAAO;AACjD,UAAAA,EAAW,KAAK,8BAChBA,EAAW,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA,WAMzB,SAAS,KAAK,YAAYA,CAAU;AAAA,QACtC;AAAA,MACF,SAASpF,GAAI;AAEX,gBAAQ,KAAK,wCAAwCA,CAAE;AAAA,MACzD;AAAA,IACF;AACE,MAAAmF,KAAuB;AAE3B;AASA,SAAShD,KAA2B;AAElC,MACEgD,MACAA,GAAqB,oBAAoB,QACzC;AACA,IAAAA,GAAqB,KAAK;AAAA,MACxB,QAAQA,GAAqB;AAAA,MAC7B,gBAAgBA,GAAqB;AAAA,MACrC,oBAAoBA,GAAqB;AAAA,MACzC,kBAAkBA,GAAqB;AAAA,IAC7C,CAAK;AAGD,QAAI;AACF,YAAM/yB,IAAQ+yB,GAAqB,KAAK;AACxC,MAAA/yB,EAAM,YAAY,IAClBA,EAAM,mBAAmB;AAAA,IAC3B,QAAa;AAAA,IAEb;AAGA,WAAO+yB,GAAqB,iBAC5B,OAAOA,GAAqB,sBAC5B,OAAOA,GAAqB,0BAC5B,OAAOA,GAAqB;AAAA,EAC9B;AAEA,EAAAA,KAAuB;AACzB;AAYA,SAASE,GAAc/G,GAAK4E,GAAU;AACpC,MAAI,CAAC5E,EAAI,eAAe,CAAC4E,KAAYA,EAAS,SAAS,GAAG;AAExD,IAAI5E,EAAI,iBACNA,EAAI,aAAa,QAAQ,OAAM,GAC/BA,EAAI,eAAe,OAEjBA,EAAI,iBACNA,EAAI,aAAa,QAAQ,OAAM,GAC/BA,EAAI,eAAe;AAErB;AAAA,EACF;AAGA,QAAMpF,IAAa,CAACgK,EAAS,CAAC,EAAE,CAAC,GAAGA,EAAS,CAAC,EAAE,CAAC,CAAC,GAC5CoC,IAAUpC,EAASA,EAAS,SAAS,CAAC,GACtCpK,IAAW,CAACwM,EAAQA,EAAQ,SAAS,CAAC,GAAGA,EAAQA,EAAQ,SAAS,CAAC,CAAC;AAG1E,EAAKhH,EAAI,gBAGPA,EAAI,aAAa,QAAQ,KAAK;AAAA,IAC5B,IAAIpF,EAAW,CAAC;AAAA,IAChB,IAAIA,EAAW,CAAC;AAAA,EACtB,CAAK,GACDoF,EAAI,aAAa,WAAWpF,KAN5BoF,EAAI,eAAeiD,GAAajD,GAAK,IAAMpF,CAAU,GAUlDoF,EAAI,gBAGPA,EAAI,aAAa,QAAQ,KAAK;AAAA,IAC5B,IAAIxF,EAAS,CAAC;AAAA,IACd,IAAIA,EAAS,CAAC;AAAA,EACpB,CAAK,GACDwF,EAAI,aAAa,WAAWxF,KAN5BwF,EAAI,eAAeiD,GAAajD,GAAK,IAAOxF,CAAQ;AAQxD;AAYA,SAASwJ,GAAkBhE,GAAKluB,GAAU;AACxC,QAAMyK,IAAOyjB,EAAI,UACd,KAAK,IAAI,EAAE,EACX,KAAK;AAAA,IACJ,GAAGluB,EAAS,CAAC,IAAI;AAAA,IACjB,GAAGA,EAAS,CAAC,IAAI;AAAA,IACjB,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,kBAAkB;AAAA,EACxB,CAAK,EACA,SAAS,wBAAwB;AAGpC,SAAAyK,EAAK,iBAAiB,IAEfA;AACT;ACpxCA,SAASwmB,GAAUp0B,GAASq0B,GAAY;AACtC,SAAOr0B,KAAW,OAAOA,EAAQq0B,CAAU,KAAM;AACnD;AAYA,SAASiE,GAAgBjH,GAAKkH,GAAoB;AAEhD,EAAIA,EAAmB,WAAWA,EAAmB,YAAYlH,KAC/DmH,GAAkBD,EAAmB,OAAO,GAI9CA,EAAmB,UAAUlH,GAC7BA,EAAI,aAAa,IACjBA,EAAI,cAAc,IAClBA,EAAI,OAAM;AACZ;AAWA,SAASmH,GAAkBnH,GAAK;AAC9B,EAAAA,EAAI,aAAa,IACjBA,EAAI,cAAc,IAClBA,EAAI,OAAM;AACZ;AAYA,SAASoH,GAAgBpH,GAAKkH,GAAoB;AAChD,EAAIlH,EAAI,cACNmH,GAAkBnH,CAAG,GACjBkH,EAAmB,YAAYlH,MACjCkH,EAAmB,UAAU,SAG/BD,GAAgBjH,GAAKkH,CAAkB;AAE3C;AAYA,SAASG,GAAmBrH,GAAKkH,GAAoB;AAEnD,MAAII,IAAe;AACnB,QAAMC,IAAiB;AAEvB,WAASC,EAAgBnoB,GAAO;AAC9B,IAAAioB,IAAe,EAAE,GAAGjoB,EAAM,SAAS,GAAGA,EAAM,QAAO;AAAA,EACrD;AAEA,WAASooB,EAAcpoB,GAAO;AAC5B,QAAI,CAACioB,EAAc;AAGnB,UAAM3sB,IAAK0E,EAAM,UAAUioB,EAAa,GAClC1sB,IAAKyE,EAAM,UAAUioB,EAAa;AAIxC,IAHiB,KAAK,KAAK3sB,IAAKA,IAAKC,IAAKA,CAAE,IAG7B2sB,KAOT,OAAOvH,EAAI,eAAgB,cAC7BA,EAAI,YAAY3gB,CAAK,GAIzBioB,IAAe;AAAA,EACjB;AAGA,EAAAtH,EAAI,QAAQ,GAAG,aAAawH,CAAe,GAC3CxH,EAAI,QAAQ,GAAG,WAAWyH,CAAa,GACvCzH,EAAI,UAAU,GAAG,aAAawH,CAAe,GAC7CxH,EAAI,UAAU,GAAG,WAAWyH,CAAa;AAC3C;AAaA,SAASC,GAAuB1H,GAAKrxB,GAAS0S,GAAM;AAClD,EAAA2e,EAAIrxB,IAAU,QAAQ,IAAI0S,GAC1B2e,EAAI,OAAM;AACZ;AAYA,SAAS2H,GAAoB3H,GAAK1rB,GAAS;AACzC,SAAA0rB,EAAI,cAAc1rB,GAClB0rB,EAAI,OAAM,GACHA;AACT;AAWA,SAAS4H,GAAW5H,GAAK;AACvB,SAAO;AAAA,IACL,cAAcA,EAAI;AAAA,IAClB,cAAcA,EAAI;AAAA,EACtB;AACA;AAYA,SAAS6H,GAAkB7H,GAAKpxB,GAAO;AACrC,SAAAoxB,EAAI,iBAAiB,KAAK,IAAI,GAAGpxB,KAAS,EAAE,GAC5CoxB,EAAI,QAAQ,KAAK,gBAAgBA,EAAI,cAAc,GAC5CA;AACT;AAYA,SAAS8H,GAAa9H,GAAK+H,GAAW;AACpC,EAAIA,MACF/H,EAAI,UAAU,OAAM,GAChB+H,KAAa,aACf/H,EAAI,YAAYA,EAAI,UACjB,KAAI,EACJ,KAAK,iBAAiB,SAAS,EAC/B,KAAK,MAAM,EACX,OAAO,SAAS,EAChB,KAAK,gBAAgB,CAAC,GAEzBA,EAAI,UAAU,OAAOA,EAAI,KAAK,EAAE,KAAK,gBAAgBA,EAAI,WAAW,KAC/DA,EAAI,YAAY+H,GACvB/H,EAAI,OAAM;AAEd;AAYA,SAASgI,GAAQhI,GAAK3e,GAAM;AAC1B,EAAI,CAAC,YAAY,UAAU,YAAY,EAAE,QAAQA,CAAI,KAAK,MACpD2e,EAAI,QAAQ3e,MACd2e,EAAI,OAAO3e,GACX2e,EAAI,OAAM;AAGhB;AAYA,SAASiI,GAAajI,GAAKjT,GAAS;AAClC,SAAAiT,EAAI,YAAYjT,GAGhBiT,EAAI,QAAQ,KAAK;AAAA,IACf,QAAQA,EAAI,YAAY,YAAY;AAAA,IACpC,kBAAkBA,EAAI,YAAY,MAAM;AAAA,EAC5C,CAAG,GAEMA;AACT;AAWA,SAASkI,GAAgBlI,GAAK;AAC5B,SAAOiI,GAAajI,GAAK,CAACA,EAAI,SAAS;AACzC;AAYA,SAASmI,GAAenI,GAAK7gB,GAAS;AACpC,SAAAA,IAAUA,KAAW,CAAA,GAEjB4jB,GAAU/C,EAAI,QAAQ,QAAQ,IAChCA,EAAI,OAAO,OAAO7gB,CAAO,IAEzB,QAAQ;AAAA,IACN;AAAA,EACN,GAGM4jB,GAAU/C,EAAI,QAAQ,QAAQ,IAChCA,EAAI,OAAO,OAAO7gB,CAAO,IAEzB,QAAQ;AAAA,IACN;AAAA,EACN,GAGS6gB;AACT;AAYA,SAASoI,GAAcpI,GAAK7gB,GAAS;AAGnC,SAAI4jB,GAAU/C,EAAI,QAAQ,WAAW,IACnCA,EAAI,OAAO,cAGX,QAAQ;AAAA,IACN;AAAA,EACN,GAGM+C,GAAU/C,EAAI,QAAQ,WAAW,IACnCA,EAAI,OAAO,cAGX,QAAQ;AAAA,IACN;AAAA,EACN,GAGSA;AACT;AAMA,SAASqI,GAAcrI,GAAK7gB,GAAS;AACnC,SAAAA,IAAUA,KAAW,CAAA,GAEjB4jB,GAAU/C,EAAI,QAAQ,QAAQ,IAChCA,EAAI,OAAO,OAAO7gB,CAAO,IAGzB,QAAQ;AAAA,IACN;AAAA,EACN,GAGM4jB,GAAU/C,EAAI,QAAQ,QAAQ,IAChCA,EAAI,OAAO,OAAO7gB,CAAO,IAGzB,QAAQ;AAAA,IACN;AAAA,EACN,GAGS6gB;AACT;AAeA,SAASsI,GACPtI,GACAuI,GACAC,GACAC,GACAC,GACA;AAEA,SAAAH,IAAgBA,KAAiB,CAAA,GAEjCE,IAAgBA,KAAiB,CAAA,GAK7B1F,GAAU/C,EAAI,QAAQ,WAAW,KAAK+C,GAAU/C,EAAI,QAAQ,WAAW,GAEvE+C,GAAU/C,EAAI,QAAQ,QAAQ,KAAK+C,GAAU/C,EAAI,QAAQ,QAAQ,GAEjE+C,GAAU/C,EAAI,QAAQ,QAAQ,KAAK+C,GAAU/C,EAAI,QAAQ,QAAQ,GAKrEoI,GAAcpI,CAAgB,GAC9BmI,GAAenI,GAAKuI,CAAa,GACjCF,GAAcrI,GAAKyI,CAAa,GAazBzI;AACT;AC7ZA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkDA,IAAIgF,KAAY,MACZjD,KAAU;AAEd,MAAM4G,KAA2B,EAAE,SAAS,KAAI;AAoEhD,SAASC,GAAYzpB,GAAS0pB,GAAW;AACvC,QAAM7I,IAAM,CAAA;AAEZ,EAAI6I,MAAc,WAChBA,IAAY1pB,GACZA,IAAU,CAAA,IAGZ6lB,KAAY7lB,EAAQ,aAAa,KAAK,OAAM,KAAM6lB;AAClD,QAAM8D,IAAY;AAsBlB,MArBA/G,KAAU5iB,EAAQ,WAAW,KAAK,OAAM,KAAM4iB,IAG9C/B,EAAI,YAAYgF,IAGhBhF,EAAI,SAAS8I,GACb9I,EAAI,SAAS6I,GACb7I,EAAI,OAAO7gB,EAAQ,QAAQ,YAG3B6gB,EAAI,cAAc7gB,EAAQ,eAAe,GACzC6gB,EAAI,QAAQ7gB,EAAQ,SAAS,WAG7B6gB,EAAI,iBACF7gB,EAAQ,kBAAkB,KAAK,IAAI,IAAI6gB,EAAI,cAAc,CAAC,GAG5DA,EAAI,YAAY7gB,EAAQ,aAAa,IAEjCA,EAAQ,WAAW;AACrB,UAAM8G,IAASyN,GAAI;AAAA,MACjB,MAAMvU,EAAQ,UAAU,KAAK,aAAa,MAAM,EAAE,MAAM,CAAC;AAAA,IAC/D,EAAM,CAAC;AACH,QAAI8G,KAAUA,EAAO,QAAQ,QAAQ;AACnC,MAAA+Z,EAAI,YAAY7gB,EAAQ;AACxB,YAAM4pB,IAAU9iB,EAAO,MAAK;AAC5B,UACE,EAAE8iB,EAAQ,CAAC,KAAKA,EAAQ,CAAC,EAAE,CAAC,KAAK,QACjC,EAAEA,EAAQ,CAAC,KAAKA,EAAQ,CAAC,EAAE,CAAC,KAAK,MACjC;AACA,cAAMj6B,IAAMmX,EAAO,KAAI;AACvB,QAAA8iB,EAAQ;AAAA,UACN;AAAA,UACA;AAAA,UACA,CAAC,KAAKj6B,EAAI,IAAIA,EAAI,QAAQ,GAAGA,EAAI,CAAC;AAAA,UAClC,CAAC,KAAKA,EAAI,IAAIA,EAAI,QAAQ,GAAGA,EAAI,IAAIA,EAAI,MAAM;AAAA,QACzD,GACQmX,EAAO,KAAK8iB,CAAO;AAAA,MACrB;AACA,MAAA/I,EAAI,UAAU,SAAS/Z;AAAA,IACzB;AAAA,EACF;AAEA,EAAK+Z,EAAI,cACPA,EAAI,YAAYgF,GACb,KAAI,EACJ,KAAK,iBAAiB,SAAS,EAC/B,KAAK,MAAM,EACX,OAAOhF,EAAI,KAAK,EAChB,KAAK,gBAAgBA,EAAI,WAAW,IAIzCA,EAAI,UAAUgF,GAAU,KAAI,EAAG,KAAK;AAAA,IAClC,eAAe;AAAA,IACf,MAAM;AAAA,IACN,QAAQhF,EAAI,YAAY,YAAY;AAAA,IACpC,gBAAgBA,EAAI;AAAA,IACpB,kBAAkBA,EAAI,YAAY,MAAM;AAAA;AAAA,IACxC,kBAAkB;AAAA,EACtB,CAAG;AAGD,MAAI;AACF,IAAAA,EAAI,UAAU,KAAK,MAAM,SAAS,WAClCA,EAAI,QAAQ,KAAK,MAAM,SAAS;AAAA,EAClC,QAAY;AAEV,IAAAA,EAAI,UAAU,KAAK,aAAa,SAAS,iBAAiB,GAC1DA,EAAI,QAAQ,KAAK,aAAa,SAAS,iBAAiB;AAAA,EAC1D;AAGA,EAAAA,EAAI,QAAQ,KAAI,GAEhBA,EAAI,eAAe7gB,EAAQ,gBAAgB,YAC3C6gB,EAAI,eAAe7gB,EAAQ,gBAAgB,YAI3C6gB,EAAI,eAAe7gB,EAAQ,gBAAgB,MAC3C6gB,EAAI,eAAe7gB,EAAQ,gBAAgB,MAC3C6gB,EAAI,cAAc7gB,EAAQ,eAAe,IAIzC6gB,EAAI,gBACF,OAAO7gB,EAAQ,iBAAkB,WAAWA,EAAQ,gBAAgB,KAEtE6gB,EAAI,gBAAgB7gB,EAAQ,iBAAiB,SAG7C6gB,EAAI,mBAAmB7gB,EAAQ,gBAAgB,QAC/C6gB,EAAI,mBAAmB7gB,EAAQ,gBAAgBA,EAAQ,UAAU,WAGjE6gB,EAAI,cAAc7gB,EAAQ,eAAe,IACzC6gB,EAAI,eAAe7gB,EAAQ,gBAAgB,GAC3C6gB,EAAI,oBAAoB7gB,EAAQ,qBAAqB,GACrD6gB,EAAI,eAAe7gB,EAAQ,gBAAgB,WAC3C6gB,EAAI,aAAa7gB,EAAQ,cAAc,QACvC6gB,EAAI,aAAa,IAGjBA,EAAI,8BAA8B,SAAUgJ,GAAa;AACvD,WAAOjJ,GAA4BiJ,KAAehJ,CAAG;AAAA,EACvD,GAEA8I,EAAU,OAAOA,EAAU,QAAQ,CAAA,GACnCA,EAAU,KAAK,KAAK9I,CAAG,GAGvB6I,EAAU,aAAaA,EAAU,cAAc,CAAA,GAC/CA,EAAU,WAAW,KAAK7I,CAAG,GAU7BA,EAAI,SAAS,WAAY;AACvB,QAAIA,EAAI,UAAU,KAAK,eAAe,KAAK,WAAW;AACpD,YAAM4E,IAAW5E,EAAI,4BAA4BA,CAAG;AAGpD,UAAIiJ,IAAU;AACd,eAASj7B,IAAI,GAAGA,IAAI42B,EAAS,QAAQ52B;AACnC,iBAAS2R,IAAI,GAAGA,IAAIilB,EAAS52B,CAAC,EAAE,QAAQ2R;AACtC,WAAI,MAAMilB,EAAS52B,CAAC,EAAE2R,CAAC,CAAC,KAAK,CAAC,SAASilB,EAAS52B,CAAC,EAAE2R,CAAC,CAAC,OACnD,QAAQ;AAAA,YACN;AAAA,YACAilB,EAAS52B,CAAC,EAAE2R,CAAC;AAAA,YACb;AAAA,YACA,CAAC3R,GAAG2R,CAAC;AAAA,UACnB,GACYspB,IAAU;AAKhB,MAAIA,KACFjJ,EAAI,UAAU,KAAK4E,CAAQ,GAC3B5E,EAAI,QAAQ,KAAK4E,CAAQ,GACzBmC,GAAc/G,GAAK4E,CAAQ,GAEvB5E,EAAI,iBAAeA,EAAI,cAAa,KAExC,QAAQ,MAAM,wCAAwC;AAAA,IAE1D;AAAA,EACF,GAGAsC,GAAUtC,GAAKA,EAAI,kBAAkBA,EAAI,kBAAkB+B,EAAO,GAGlE/B,EAAI,eAAe,MACnBA,EAAI,eAAe,MAGnBA,EAAI,YAAY,SAAUuC,GAAcC,GAAcC,GAAkB;AACtE,WAAOH,GAAUtC,GAAKuC,GAAcC,GAAcC,CAAgB;AAAA,EACpE,GAEAzC,EAAI,oBAAoB,SAAUuC,GAAcC,GAAc;AAC5D,WAAOE,GAAkB1C,GAAKuC,GAAcC,CAAY;AAAA,EAC1D,GAMAxC,EAAI,gBAAgB,WAAY;AAC9B,QAAI,GAACA,EAAI,SAAS,CAACA,EAAI,aAAa,CAACA,EAAI,UAAU;AACnD,UAAI;AACF,cAAMrD,IAAQqD,EAAI,UAAU,KAAK,eAAc;AAC/C,YAAI,CAACrD,KAAS,CAAC,SAASA,CAAK,EAAG;AAChC,cAAMuM,IAAMlJ,EAAI,UAAU,KAAK,iBAAiBrD,IAAQ,CAAC;AAEzD,YADAqD,EAAI,MAAM,OAAOkJ,EAAI,GAAGA,EAAI,CAAC,GACzBlJ,EAAI,SAAS;AACf,gBAAM7B,IAAK6B,EAAI,MAAM,KAAI;AACzB,UAAAA,EAAI,QACD,KAAK7B,EAAG,QAAQ,IAAIA,EAAG,SAAS,CAAC,EACjC,OAAO+K,EAAI,GAAGA,EAAI,CAAC;AAAA,QACxB;AAAA,MACF,QAAY;AAAA,MAEZ;AAAA,EACF,GAEAlJ,EAAI,WAAW,SAAUte,GAAM;AAE7B,QADAse,EAAI,YAAYte,KAAQ,OAAO,KAAK,OAAOA,CAAI,GAC3C,CAACse,EAAI,WAAW;AAClB,MAAIA,EAAI,UACNA,EAAI,MAAM,OAAM,GAChBA,EAAI,QAAQ,OAEVA,EAAI,YACNA,EAAI,QAAQ,OAAM,GAClBA,EAAI,UAAU;AAEhB;AAAA,IACF;AACA,IAAKA,EAAI,QAgBPA,EAAI,MAAM,KAAKA,EAAI,SAAS,KAd5BA,EAAI,UAAUgF,GACX,KAAK,GAAG,CAAC,EACT,KAAK,EAAE,MAAM,WAAW,gBAAgB,MAAM,kBAAkB,OAAM,CAAE,EACxE,OAAO,CAAC,GACXhF,EAAI,QAAQgF,GACT,KAAKhF,EAAI,SAAS,EAClB,KAAK;AAAA,MACJ,aAAa;AAAA,MACb,eAAe;AAAA,MACf,MAAM;AAAA,MACN,eAAe;AAAA,MACf,kBAAkB;AAAA,IAC5B,CAAS,IAILA,EAAI,cAAa;AAAA,EACnB,GAEAA,EAAI,iBAAiB,SAAUpxB,GAAO;AACpC,WAAO+zB,GAAe3C,GAAKpxB,CAAK;AAAA,EAClC,GAEAoxB,EAAI,oBAAoB,SAAUlqB,GAAO;AACvC,WAAA8sB,GAAkB5C,GAAKlqB,CAAK,GACrBkqB;AAAA,EACT,GAMAA,EAAI,SAAS,WAAY;AACvB,UAAMmJ,IAAK,CAACl1B,MAAO;AACjB,UAAI;AACF,QAAAA,KAAMA,EAAG,UAAUA,EAAG,OAAM;AAAA,MAC9B,QAAY;AAAA,MAEZ;AAAA,IACF;AACA,WAAAk1B,EAAGnJ,EAAI,SAAS,GAChBmJ,EAAGnJ,EAAI,OAAO,GACdmJ,EAAGnJ,EAAI,gBAAgBA,EAAI,aAAa,OAAO,GAC/CmJ,EAAGnJ,EAAI,gBAAgBA,EAAI,aAAa,OAAO,GAC/CmJ,EAAGnJ,EAAI,YAAY,GACnBmJ,EAAGnJ,EAAI,YAAY,GACnBmJ,EAAGnJ,EAAI,kBAAkB,GACzBmJ,EAAGnJ,EAAI,kBAAkB,GACzBmJ,EAAGnJ,EAAI,KAAK,GACZmJ,EAAGnJ,EAAI,OAAO,GACPA;AAAA,EACT,GAKAA,EAAI,mBAAmB,SAAUoJ,GAAO;AACtC,UAAMtQ,IAAQsQ,MAAU,WAAWpJ,EAAI,SAASA,EAAI,QAC9C5kB,IAAQguB,MAAU,WAAWpJ,EAAI,SAASA,EAAI;AACpD,QAAI,CAAClH,KAAS,CAACA,EAAM,QAAQ,CAAC1d,EAAO,QAAO,EAAE,GAAG,KAAK,GAAG,IAAG;AAC5D,QAAI;AACF,YAAMiuB,IAAcjN,GAAiBhhB,CAAK,GACpCkuB,IAAOrL,GAAsBnF,GAAOuQ,CAAW,GAC/CE,IAAQpN,GAAiBrD,GAAOwQ,EAAK,CAAC,GAAGA,EAAK,CAAC,CAAC,GAChDnL,IAAKrF,EAAM,KAAI;AACrB,aAAI,CAACqF,EAAG,SAAS,CAACA,EAAG,SAAe,EAAE,GAAG,KAAK,GAAG,IAAG,IAC7C;AAAA,QACL,IAAIoL,EAAM,CAAC,IAAIpL,EAAG,KAAKA,EAAG;AAAA,QAC1B,IAAIoL,EAAM,CAAC,IAAIpL,EAAG,KAAKA,EAAG;AAAA,MAClC;AAAA,IACI,QAAY;AACV,aAAO,EAAE,GAAG,KAAK,GAAG,IAAG;AAAA,IACzB;AAAA,EACF,GAIA6B,EAAI,sBAAsB,SAAUoJ,GAAOlK,GAAQ;AACjD,WAAIkK,MAAU,WAAUpJ,EAAI,eAAed,KAAU,OAC5CkK,MAAU,aAAUpJ,EAAI,eAAed,KAAU,OAC1Dc,EAAI,OAAM,GACHA;AAAA,EACT,GAEAA,EAAI,gBAAgB,SAAU4E,GAAU;AACtC,IAAAmC,GAAc/G,GAAK4E,CAAQ;AAAA,EAC7B,GAEA5E,EAAI,kBAAkB,WAAY;AAChC,IAAAiH,GAAgBjH,GAAK2I,EAAwB;AAAA,EAC/C,GAEA3I,EAAI,oBAAoB,WAAY;AAClC,IAAAmH,GAAkBnH,CAAG,GACjB2I,GAAyB,YAAY3I,MACvC2I,GAAyB,UAAU;AAAA,EAEvC,GAEA3I,EAAI,kBAAkB,WAAY;AAChC,IAAAoH,GAAgBpH,GAAK2I,EAAwB;AAAA,EAC/C,GAEA3I,EAAI,yBAAyB,SAAUrxB,GAAS0S,GAAM;AACpD,IAAAqmB,GAAuB1H,GAAKrxB,GAAS0S,CAAI;AAAA,EAC3C,GAEA2e,EAAI,sBAAsB,SAAU1rB,GAAS;AAC3C,WAAOqzB,GAAoB3H,GAAK1rB,CAAO;AAAA,EACzC,GAEA0rB,EAAI,aAAa,WAAY;AAC3B,WAAO4H,GAAW5H,CAAG;AAAA,EACvB,GAEAA,EAAI,oBAAoB,SAAUpxB,GAAO;AACvC,WAAOi5B,GAAkB7H,GAAKpxB,CAAK;AAAA,EACrC,GAEAoxB,EAAI,eAAe,SAAU+H,GAAW;AACtC,IAAAD,GAAa9H,GAAK+H,CAAS;AAAA,EAC7B,GAEA/H,EAAI,UAAU,SAAU3e,GAAM;AAC5B,IAAA2mB,GAAQhI,GAAK3e,CAAI;AAAA,EACnB,GAEA2e,EAAI,eAAe,SAAUjT,GAAS;AACpC,WAAOkb,GAAajI,GAAKjT,CAAO;AAAA,EAClC,GAEAiT,EAAI,kBAAkB,WAAY;AAChC,WAAOkI,GAAgBlI,CAAG;AAAA,EAC5B,GAEAA,EAAI,iBAAiB,SAAU7gB,GAAS;AACtC,WAAOgpB,GAAenI,GAAK7gB,CAAO;AAAA,EACpC,GAEA6gB,EAAI,gBAAgB,SAAU7gB,GAAS;AACrC,WAAOipB,GAAcpI,CAAY;AAAA,EACnC,GAEAA,EAAI,gBAAgB,SAAU7gB,GAAS;AACrC,WAAOkpB,GAAcrI,GAAK7gB,CAAO;AAAA,EACnC,GAEA6gB,EAAI,kBAAkB,SAAUuI,GAAeC,GAAaC,GAAe;AACzE,WAAOH,GAAgBtI,GAAKuI,GAAeC,GAAaC,CAAa;AAAA,EACvE,GAGApB,GAAmBrH,CAA6B,GAEhDA,EAAI,OAAM;AAGV,WAASwJ,EAAgBnqB,GAAO;AAC9B,IAAA2gB,EAAI,OAAM;AAAA,EACZ;AAGA,WAASyJ,EAA0BpqB,GAAO;AAExC,IAAA2gB,EAAI,OAAM;AAAA,EACZ;AAEA,WAAS0J,EAA0BrqB,GAAO;AAExC,IAAA2gB,EAAI,OAAM;AAAA,EACZ;AAGA,SAAAA,EAAI,wBAAwByJ,GAC5BzJ,EAAI,wBAAwB0J,GAG5BZ,EAAU,GAAG,YAAYW,CAAyB,GAClDZ,EAAU,GAAG,YAAYa,CAAyB,GAGlDZ,EAAU,GAAG,cAAcW,CAAyB,GACpDX,EAAU,GAAG,aAAaW,CAAyB,GACnDX,EAAU,GAAG,WAAWW,CAAyB,GACjDZ,EAAU,GAAG,cAAca,CAAyB,GACpDb,EAAU,GAAG,aAAaa,CAAyB,GACnDb,EAAU,GAAG,WAAWa,CAAyB,GAGjDZ,EAAU,GAAG,UAAUW,CAAyB,GAChDZ,EAAU,GAAG,UAAUa,CAAyB,GAGhDZ,EAAU,GAAG,UAAUW,CAAyB,GAChDZ,EAAU,GAAG,UAAUa,CAAyB,GAGhDZ,EAAU,GAAG,aAAaW,CAAyB,GACnDZ,EAAU,GAAG,aAAaa,CAAyB,GAGnD1J,EAAI,kBAAkBwJ,GAGtB5G,GAAkB5C,GAAKA,EAAI,KAAK,GAEzBA;AACT;AAGAxuB,EAAOgK,IAAS;AAAA,EACd,aAAaotB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYb,+BAA+B,SAC7Be,GACA1jB,GACAsiB,GACAC,GACA;AACA,UAAMoB,IAAa,KAAK,YAAYD,GAAgB1jB,CAAM;AAC1D,WAAA2jB,EAAW,gBAAgBrB,GAAeC,CAAW,GAC9CoB;AAAA,EACT;AACF,CAAC;ACljBM,SAASC,GACd5wB,GACAjH,GACAD,GACgC;AAChC,QAAMwC,IAAI0E,GACJ7C,IAAI,CAAC7B,EAAE,CAAC,IAAIvC,EAAK,CAAC,GAAGuC,EAAE,CAAC,IAAIvC,EAAK,CAAC,CAAC,GACnCqE,IAAI,CAAC9B,EAAE,CAAC,IAAIxC,EAAK,CAAC,GAAGwC,EAAE,CAAC,IAAIxC,EAAK,CAAC,CAAC,GACnC,IAAI,KAAK,KAAKqE,EAAE,CAAC,IAAIA,EAAE,CAAC,IAAIA,EAAE,CAAC,IAAIA,EAAE,CAAC,CAAC,KAAK,GAC5CzC,IAAI,KAAK,KAAK0C,EAAE,CAAC,IAAIA,EAAE,CAAC,IAAIA,EAAE,CAAC,IAAIA,EAAE,CAAC,CAAC,KAAK,GAC5ChI,IAAI,CAAC+H,EAAE,CAAC,IAAI,GAAGA,EAAE,CAAC,IAAI,CAAC,GACvB6mB,IAAI,CAAC5mB,EAAE,CAAC,IAAI1C,GAAG0C,EAAE,CAAC,IAAI1C,CAAC,GACvB+B,IAAsB,CAACnB,EAAE,CAAC,IAAI,KAAKlG,EAAE,CAAC,GAAGkG,EAAE,CAAC,IAAI,KAAKlG,EAAE,CAAC,CAAC,GACzDy7B,IAAsB,CAACv1B,EAAE,CAAC,IAAI,KAAK0oB,EAAE,CAAC,GAAG1oB,EAAE,CAAC,IAAI,KAAK0oB,EAAE,CAAC,CAAC,GACzDnT,IAAgC,CAACpU,GAAGnB,GAAGu1B,CAAC;AAI9C,SAHehgB,EAAK;AAAA,IAClB,CAACigB,MAAO,OAAO,SAASA,EAAG,CAAC,CAAC,KAAK,OAAO,SAASA,EAAG,CAAC,CAAC;AAAA,EAAA,IAEzCjgB,IAAO;AACzB;AAaO,MAAMkgB,GAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBxB,YAAYj5B,GAAYoO,IAA+B,IAAI;AAhB3D,SAAQ,WAAoB,IAC5B,KAAQ,eAAe,IACvB,KAAQ,aAAa,IACrB,KAAQ,aAAa,IACrB,KAAQ,eAAoC,MAI5C,KAAQ,qBAAsD,MAS5D,KAAK,OAAOpO,GAGZ,KAAK,SAAUA,EAAa,gBAAgBA,EAAK,gBACjD,KAAK,UAAU;AAAA,MACb,eAAe;AAAA,MACf,eAAe;AAAA,MACf,qBAAqB;AAAA,MACrB,cAAc;AAAA,MACd,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,GAAGoO;AAAA,IAAA;AAAA,EAEP;AAAA;AAAA,EAGO,SAAS;AACd,QAAI,MAAK,UAKT;AAAA,UAFA,KAAK,SAAU,KAAK,KAAa,gBAAgB,KAAK,KAAK,gBAEvD,CAAC,KAAK,QAAQ;AAChB,gBAAQ,KAAK,iFAAiF,KAAK,MAAM,EAAE;AAC3G;AAAA,MACF;AAEA,UAAI;AAEF,cAAMxQ,IAAe,KAAK;AAG1B,QAAI,OAAOA,EAAQ,UAAW,cAC5BA,EAAQ,OAAO;AAAA,UACb,eAAe,KAAK,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAO5B,cAAc,CAAC8qB,GAAaxgB,GAAYoK,GAAeqB,MAAkB;AACvE,kBAAM1S,IAAO0S,GAAQrB,IAAQ,IAAIqB,EAAO,UAAUA,EAAO,MAAM,GACzD3S,IAAO2S,GAAQrB,IAAQ,KAAKqB,EAAO,MAAM,GACzCoF,IAAO+f,GAAwB5wB,GAAOjH,GAAMD,CAAI;AACtD,YAAI+X,KAAM2P,EAAO,KAAK3P,CAAI;AAAA,UAC5B;AAAA,QAAA,CACD,GAIC,KAAK,QAAQ,iBAAiB,OAAOnb,EAAQ,UAAW,cAC1DA,EAAQ,OAAO;AAAA,UACb,qBAAqB,KAAK,QAAQ;AAAA,UAClC,cAAc,KAAK,QAAQ;AAAA,UAC3B,MAAM,KAAK,QAAQ,QAAQ;AAAA,UAC3B,QAAQ,KAAK,QAAQ,UAAU;AAAA,QAAA,CAChC,GAIH,KAAK,iBAAA,GAGL,KAAK,kBAAA,GAEL,KAAK,WAAW;AAAA,MAClB,SAASs7B,GAAO;AACd,gBAAQ,KAAK,mCAAmCA,CAAK;AAAA,MACvD;AAAA;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,mBAAmB;AAEzB,0BAAsB,MAAM;AAC1B,UAAI;AACF,cAAMC,IAAU,KAAK,OAAO,MACtB35B,IAAO25B,EAAQ,mBAAmBA;AAKxC,QAHwB35B,EAAK;AAAA,UAC3B;AAAA,QAAA,EAEc,QAAQ,CAACuoB,MAAsB;AAC7C,UAAAA,EAAM,aAAa,QAAQ,MAAM,GACjCA,EAAM,aAAa,gBAAgB,GAAG,GACtCA,EAAM,aAAa,kBAAkB,MAAM,GAC1CA,EAAM,MAAc,OAAO,QAC3BA,EAAM,MAAc,cAAc,KACnCA,EAAM,MAAM,gBAAgB;AAAA,QAC9B,CAAC,GAEevoB,EAAK,iBAAiB,oBAAoB,EAClD,QAAQ,CAAC8F,MAAkB;AAIjC,UAAAA,EAAE,aAAa,gBAAgB,GAAG,GAClCA,EAAE,aAAa,UAAU,SAAS,GAClCA,EAAE,MAAM,gBAAgB;AAAA,QAC1B,CAAC;AAAA,MACH,SAASiE,GAAG;AACV,gBAAQ,KAAK,0DAA0DA,CAAC;AAAA,MAC1E;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAGO,UAAU;AACf,QAAK,KAAK;AAEV,UAAI;AACF,cAAM3L,IAAe,KAAK;AAG1B,QAAI,OAAOA,EAAQ,UAAW,cAC5BA,EAAQ,OAAO,EAAK,GAElB,OAAOA,EAAQ,UAAW,cAC5BA,EAAQ,OAAO,EAAK,GAGtB,KAAK,qBAAA,GACL,KAAK,WAAW;AAAA,MAClB,SAASs7B,GAAO;AACd,gBAAQ,KAAK,oCAAoCA,CAAK;AAAA,MACxD;AAAA,EACF;AAAA,EAEQ,oBAAoB;AAI1B,SAAK,OAAO,GAAG,6BAA6B,CAAC5qB,MAAe;AAC1D,YAAM8qB,IAAU9qB,EAAM,QAAQ,SACxB+qB,IAAe/qB,EAAM,QAAQ,OAAO,QAAQ;AAClD,MAAI8qB,MACFA,EAAQ,sBAAsB,GAC5B,KAAK,QAAQ,uBAAuBC,GAAc;AAAA,IAGxD,CAAC,GAGD,KAAK,OAAO,GAAG,kDAAkD,CAAC/qB,MAAe;AAE/E,MAAI,KAAK,qBAAqBA,EAAM,MAAM,MACpC,KAAK,KAAK,gCACZ,KAAK,KAAK,yBAAA,GAEZ,KAAK,eAAe,IACpB,KAAK,aAAa,IAClB,KAAK,aAAa;AAAA,IAEtB,CAAC,GAGD,KAAK,eAAe,MAAM;AACxB,UAAI,CAAC,KAAK,aAAc;AACxB,WAAK,eAAe,KAKf,KAAK,cAAc,KAAK,eAAe,KAAK,KAAK,uBACpD,KAAK,KAAK,oBAAA,GAEZ,KAAK,qBAAqB;AAC1B,YAAMgrB,IAAQ,KAAK,KAAK;AACxB,MAAI,KAAK,aACPA,GAAO,YAAY,iBAAiB;AAAA,QAClC,IAAI,KAAK,KAAK;AAAA,QACd,QAAQ,KAAK,KAAK,QAAQ;AAAA,QAC1B,OAAO,KAAK,KAAK,QAAQ;AAAA,QACzB,QAAQ,KAAK,KAAK,QAAQ;AAAA,MAAA,CAC3B,IACQ,KAAK,eACdA,GAAO,YAAY,iBAAiB;AAAA,QAClC,IAAI,KAAK,KAAK;AAAA,QACd,OAAO,KAAK,KAAK,QAAQ;AAAA,QACzB,QAAQ,KAAK,KAAK,QAAQ;AAAA,QAC1B,QAAQ,KAAK,KAAK,QAAQ;AAAA,QAC1B,YAAY,KAAK,KAAK,QAAQ;AAAA,MAAA,CAC/B,GAKD,sBAAsB,MAAM;AAC1B,YAAI;AACF,eAAK,KAAK,aAAA;AAAA,QACZ,QAAY;AAAA,QAEZ;AAAA,MACF,CAAC,IAEH,KAAK,aAAa,IAClB,KAAK,aAAa;AAAA,IACpB,GACA,OAAO,iBAAiB,aAAa,KAAK,YAAY,GACtD,OAAO,iBAAiB,YAAY,KAAK,YAAY,GAGrD,KAAK,OAAO,GAAG,UAAU,CAAChrB,MAAe;AAIvC,MAAI,KAAK,uBAAuB,SAC9B,KAAK,qBAAqB;AAAA,QACxB,GAAG,KAAK,KAAK,QAAQ,KAAK;AAAA,QAC1B,GAAG,KAAK,KAAK,QAAQ,KAAK;AAAA,MAAA,IAM9B,KAAK,eAAe,IAIhBA,EAAM,QAAQ,QAChB,KAAK,aAAa,KAGlB,OAAOA,EAAM,QAAQ,SAAU,YAC/BA,EAAM,OAAO,UAAU,MAEvB,KAAK,aAAa,KAGpB,KAAK,aAAaA,CAAK,GACvB,KAAK,QAAQ,WAAWA,CAAK,GAGzB,KAAK,KAAK,SAAS,KAAK,KAAK,MAAM,mBAAmB,SAAS,KAAK,IAAI,KAE1E,WAAW,MAAM;AACf,aAAK,KAAK,wBAAA;AAAA,MACZ,GAAG,EAAE,GAIP,KAAK,KAAK,OAAO,kBAAkB,KAAK,IAAI;AAAA,IAC9C,CAAC;AAAA,EACH;AAAA,EAEQ,qBAAqB4G,GAAsB;AACjD,QAAI,CAACA,KAAU,CAACA,EAAO,UAAW,QAAO;AAEzC,UAAMqkB,IAAgB;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGF,eAAWr5B,KAAaq5B;AACtB,UAAIrkB,EAAO,UAAU,SAAShV,CAAS;AACrC,eAAO;AAIX,WAAO;AAAA,EACT;AAAA,EAEQ,uBAAuB;AAC7B,SAAK,OAAO,IAAI,QAAQ,GACxB,KAAK,OAAO,IAAI,2BAA2B,GAC3C,KAAK,OAAO,IAAI,gDAAgD,GAC5D,KAAK,iBACP,OAAO,oBAAoB,aAAa,KAAK,YAAY,GACzD,OAAO,oBAAoB,YAAY,KAAK,YAAY,GACxD,KAAK,eAAe;AAAA,EAExB;AAAA,EAEQ,aAAaoO,GAAY;AAE/B,QAAIA,EAAM,UAAUA,EAAM,OAAO,KAAK;AACpC,YAAMvQ,IAAMuQ,EAAM,OAAO;AAGzB,WAAK,KAAK,QAAQ,QAAQvQ,EAAI,OAC9B,KAAK,KAAK,QAAQ,SAASA,EAAI;AAM/B,YAAMgK,IAAO,KAAK,sBAAsB;AAAA,QACtC,GAAG,KAAK,KAAK,QAAQ,KAAK;AAAA,QAC1B,GAAG,KAAK,KAAK,QAAQ,KAAK;AAAA,MAAA;AAE5B,WAAK,KAAK,QAAQ,IAAIA,EAAK,IAAIhK,EAAI,GACnC,KAAK,KAAK,QAAQ,IAAIgK,EAAK,IAAIhK,EAAI,GAGnC,KAAK,KAAK,QAAQA,EAAI,OAAOA,EAAI,MAAM,GAEvC,KAAK,KAAK,WAAA;AAMV,UAAI;AACF,aAAK,KAAK,UAAU,OAAO,WAAW;AAAA,MACxC,QAAY;AAAA,MAEZ;AAKA,UAAIuQ,EAAM,UAAU,OAAOA,EAAM,OAAO,SAAU,UAAU;AAC1D,cAAMkrB,IAAalrB,EAAM,OAAO;AAGhC,YAAImrB,IAAyB;AAC7B,YAAI;AAEF,UAAAA,IADwB,KAAK,OAAO,UAAA,GACM,UAAU;AAAA,QACtD,SAASlwB,GAAG;AACV,kBAAQ,KAAK,gEAAgEA,CAAC;AAAA,QAChF;AAGA,YAAImwB,IAA2B;AAC/B,YAAI;AAEF,UAAAA,IADuB,KAAK,KAAK,SAAS,UAAA,GACC,UAAU;AAAA,QACvD,SAASnwB,GAAG;AACV,kBAAQ,KAAK,0DAA0DA,CAAC;AAAA,QAC1E;AAGA,cAAMowB,IAAgBD,IAA2BD;AAWjD,YARK,KAAK,KAAK,QAAQ,WACrB,KAAK,KAAK,QAAQ,SAAS,EAAE,eAAe,EAAA,IAE9C,KAAK,KAAK,QAAQ,OAAO,gBAAgBE,GAMvC,KAAK,KAAK,eACV,OAAO,KAAK,KAAK,YAAY,UAAW,YACxC;AAEA,gBAAMttB,IAAO,KAAK,OAAO,KAAA;AACzB,eAAK,KAAK,YAAY,OAAOmtB,GAAYntB,EAAK,IAAIA,EAAK,EAAE;AAAA,QAC3D,WACE,KAAK,KAAK,aACV,OAAO,KAAK,KAAK,UAAU,UAAW,YACtC;AAEA,gBAAMA,IAAO,KAAK,OAAO,KAAA;AACzB,eAAK,KAAK,UAAU,OAAOmtB,GAAYntB,EAAK,IAAIA,EAAK,EAAE;AAAA,QACzD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEO,YAAqB;AAC1B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGO,UAAgB;AACrB,SAAK,QAAA,GACJ,KAAa,OAAO,MACrB,KAAK,SAAS;AAAA,EAChB;AAAA,EAEO,cAAc+B,GAAuC;AAC1D,SAAK,UAAU,EAAE,GAAG,KAAK,SAAS,GAAGA,EAAA,GAEjC,KAAK,aAEP,KAAK,QAAA,GACL,KAAK,OAAA;AAAA,EAET;AAAA,EAEO,UAAU;AAGf,IAAI,KAAK,aACP,KAAK,QAAA,GACL,KAAK,OAAA;AAAA,EAET;AACF;AChdI,OAAO,SAAW,QACnB,OAAe,MAAMuU;AAyCjB,MAAMiX,GAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAarB,YAAY55B,GAAYoO,IAA4B,IAAI;AATxD,SAAQ,kCAA2C,IAAA,GACnD,KAAQ,WAAoB,IAS1B,KAAK,OAAOpO,GACZ,KAAK,QAAQA,EAAK,OAClB,KAAK,UAAU;AAAA,MACb,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,kBAAkB;AAAA,MAClB,kBAAkB;AAAA;AAAA,MAGlB,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,MACb,cAAc;AAAA,MACd,cAAc;AAAA,MACd,cAAc;AAAA,MACd,cAAc;AAAA,MACd,aAAa;AAAA,MACb,aAAa;AAAA,MAEb,GAAGoO;AAAA,IAAA,GAGL,QAAQ,IAAI,+CAA+C,KAAK,KAAK,EAAE;AAAA,EACzE;AAAA;AAAA,EAGO,SAAS;AACd,QAAI,MAAK;AAET,UAAI;AACF,gBAAQ,IAAI,gDAAgD,KAAK,KAAK,EAAE,GAGlE,KAAK,KAAK,SAAiB,gBAC/B,QAAQ;AAAA,UACN;AAAA,QAAA,GAEF,QAAQ;AAAA,UACN;AAAA,QAAA,IAMJ,KAAK,iBAAA,GAEL,KAAK,WAAW,IAChB,QAAQ,IAAI,+CAA+C,KAAK,KAAK,EAAE;AAAA,MACzE,SAAS8qB,GAAO;AACd,gBAAQ,KAAK,gDAAgDA,CAAK;AAAA,MACpE;AAAA,EACF;AAAA;AAAA,EAGO,UAAU;AACf,QAAK,KAAK;AAEV,UAAI;AACF,gBAAQ;AAAA,UACN;AAAA,UACA,KAAK,KAAK;AAAA,QAAA,GAIZ,KAAK,cAAA,GAEL,KAAK,WAAW,IAChB,QAAQ,IAAI,gDAAgD,KAAK,KAAK,EAAE;AAAA,MAC1E,SAASA,GAAO;AACd,gBAAQ,KAAK,iDAAiDA,CAAK;AAAA,MACrE;AAAA,EACF;AAAA,EAEO,UAAgB;AACrB,SAAK,QAAA,GACL,KAAK,YAAY,MAAA;AAAA,EACnB;AAAA,EAEQ,mBAAmB;AAEzB,IAAK,KAAK,QAAQ,kBAEX,KAAK,MAAM,mBACd,KAAK,MAAM,iBAAiB,KAAK,MAAM,OAAO,MAAA,GAC9C,QAAQ,IAAI,iDAAiD,IAE/D,KAAK,QAAQ,gBAAgB,KAAK,MAAM,iBAGrC,KAAK,QAAQ,oBAEX,KAAK,MAAM,qBACd,KAAK,MAAM,mBAAmB,KAAK,MAAM,OAAO,MAAA,GAChD,QAAQ,IAAI,mDAAmD,IAEjE,KAAK,QAAQ,kBAAkB,KAAK,MAAM;AAAA,EAE9C;AAAA,EAEO,UACLW,GACAC,IAAyC,IACtB;AACnB,QAAI,CAAC,KAAK;AACR,qBAAQ;AAAA,QACN;AAAA,QACA,KAAK,KAAK;AAAA,MAAA,GAEL;AAGT,QAAI;AACF,cAAQ;AAAA,QACN;AAAA,QACA,KAAK,KAAK;AAAA,QACV;AAAA,QACAD,EAAW;AAAA,MAAA;AAMb,YAAME,IACHD,EAA0B,gBAC3B,GAAG,KAAK,KAAK,EAAE,KAAKD,EAAW,EAAE;AAGnC,UAAI,KAAK,YAAY,IAAIE,CAAY;AACnC,uBAAQ;AAAA,UACN;AAAA,UACAA;AAAA,QAAA,GAEK,KAAK,YAAY,IAAIA,CAAY;AAI1C,UAAI,CAAE,KAAK,KAAK,SAAiB;AAC/B,uBAAQ;AAAA,UACN;AAAA,QAAA,GAEK;AAKT,YAAMC,IAAKF,GACLG,IAAkC;AAAA,QACtC,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,QAAQ;AAAA,MAAA,GAEJC,IAAWF,EAAG,WAChBC,EAAQD,EAAG,QAAQ,KAAK,WACxB,KAAK,QAAQ,MACXG,IACJH,EAAG,mBAAmB,OAClBA,EAAG,kBACD,KAAK,QAAQ,gBAAgB,UAC7B,SACF,KAAK,QAAQ,cACbI,IACJJ,EAAG,kBAAkB,OACjBA,EAAG,iBACD,KAAK,QAAQ,gBAAgB,UAC7B,SACF,KAAK,QAAQ,cAGbK,IAAkB,KAAK,KAAK,SAAiB;AAAA,QACjD;AAAA,UACE,WAAW,KAAK,QAAQ;AAAA,UACxB,SAAS,KAAK,QAAQ;AAAA,UACtB,MAAMH;AAAA,UACN,OAAOF,EAAG,aAAa,KAAK,QAAQ;AAAA,UACpC,aAAaA,EAAG,aAAa,KAAK,QAAQ;AAAA,UAC1C,cAAc,KAAK,QAAQ;AAAA,UAC3B,cAAc,KAAK,QAAQ;AAAA,UAC3B,cAAAG;AAAA,UACA,cAAAC;AAAA,UACA,aAAa,KAAK,QAAQ;AAAA,UAC1B,aAAa,KAAK,QAAQ;AAAA,UAC1B,eAAeJ,EAAG;AAAA,UAClB,eAAgBA,EAAW;AAAA;AAAA,UAE3B,cAAcF,EAAkB;AAAA,UAChC,cAAcA,EAAkB;AAAA,QAAA;AAAA,QAElCD,EAAW;AAAA,MAAA;AAIb,UAAI,CAACQ;AACH,uBAAQ,MAAM,sDAAsD,GAC7D;AAIT,YAAMxB,IAAyB;AAAA,QAC7B,IAAIkB;AAAA,QACJ,QAAQ,KAAK;AAAA,QACb,QAAQF;AAAA,QACR,aAAaQ;AAAA,QACb,WAAWP,EAAkB,aAAa,KAAK,QAAQ;AAAA,QACvD,WAAWA,EAAkB,aAAa,KAAK,QAAQ;AAAA,QACvD,GAAGA;AAAA,MAAA;AAIL,MAAIjB,EAAW,aAAawB,EAAe,gBACzCA,EAAe,aAAaxB,EAAW,SAAS,GAElD,KAAK,oBAAoBwB,GAAgBxB,CAAU,GAE/CA,EAAW,SAASwB,EAAe,YACrCA,EAAe,SAASxB,EAAW,KAAK,GAI1C,KAAK,YAAY,IAAIkB,GAAclB,CAAU;AAK7C,UAAI;AACF,aAAK,MAAM,kBAAkB,QAAA;AAAA,MAC/B,QAAY;AAAA,MAEZ;AASA,UAJAwB,EAAe,mBAAmB,CAAChf,MACjC,KAAK,qBAAqBwd,GAAYxd,CAAI,GAGxCwe,EAAW,WAAW;AAGxB,cAAMS,IAAY,GAAGT,EAAW,EAAE,KAAKE,CAAY;AACnD,QAAAF,EAAW,UAAU,YAAY,IAAIS,GAAWzB,CAAU;AAAA,MAC5D;AAEA,qBAAQ,IAAI,2CAA2CkB,CAAY,GAKnEM,EAAe,cAAc,MAAM;AACjC,QAAI,KAAK,KAAK,OAAO,aAAA,KACrB,KAAK,YAAYxB,GAAYwB,GAAgBR,EAAW,EAAE;AAAA,MAC5D,GAKA,KAAK,iBAAiBQ,CAAc,GAGpC,KAAK,QAAQ,YAAYxB,CAAU,GAE5BA;AAAA,IACT,SAASK,GAAO;AACd,qBAAQ,MAAM,iDAAiDA,CAAK,GACpE,QAAQ;AAAA,QACN;AAAA,MAAA,GAEK;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,eACLhxB,GACAqyB,GACAT,IAAyC,CAAA,GACtB;AACnB,IAAK,KAAK,YAAU,KAAK,OAAA;AACzB,UAAM7F,IAAiB,KAAK,QAAQ,iBAAiB,KAAK,MAAM;AAChE,QAAI,CAACA,EAAW,QAAO;AACvB,UAAMuG,IAAUvG,EACb,KAAK,GAAG,CAAC,EACT,KAAK/rB,EAAM,IAAI,KAAKA,EAAM,IAAI,GAAG,EACjC,KAAK,MAAM,EACX,QAAQ,CAAC;AACX,IAAAsyB,EAAgB,iBAAiB;AAClC,UAAMC,IAAkB,EAAE,IAAIF,GAAS,UAAUC,GAAS,aAAa,GAAA,GACjEE,IAAO,KAAK,UAAUD,GAAYX,CAAiB;AACzD,WAAIY,MAAOA,EAAa,WAAWF,IAC5BE;AAAA,EACT;AAAA,EAEO,eAAeb,GAA0B;AAG9C,UAAM9xB,IAAO,GAAG,KAAK,KAAK,EAAE,KAAK8xB,EAAW,EAAE,IACxCc,IAAM,CAAC,GAAG,KAAK,YAAY,KAAA,CAAM,EAAE;AAAA,MACvC,CAACxqB,MAAOA,MAAOpI,KAAQoI,EAAG,WAAW,GAAGpI,CAAI,GAAG;AAAA,IAAA;AAEjD,QAAI4yB,EAAI,WAAW,EAAG,QAAO,KAAK,eAAe5yB,CAAI;AACrD,QAAI6yB,IAAK;AACT,eAAWzqB,KAAMwqB,EAAK,CAAAC,IAAK,KAAK,eAAezqB,CAAE,KAAKyqB;AACtD,WAAOA;AAAA,EACT;AAAA,EAEO,eAAeb,GAA+B;AACnD,QAAI;AACF,YAAMlB,IAAa,KAAK,YAAY,IAAIkB,CAAY;AACpD,UAAI,CAAClB;AACH,uBAAQ,KAAK,0CAA0CkB,CAAY,GAC5D;AAGT,cAAQ,IAAI,kCAAkCA,CAAY;AAK1D,UAAI;AACF,QAAIlB,EAAW,aAAa,SAC1BA,EAAW,YAAY,OAAA,KAEvBA,EAAW,aAAa,WAAW,SAAA,GACnCA,EAAW,aAAa,SAAS,SAAA,IAElCA,EAAmB,UAAU,SAAA;AAAA,MAChC,QAAY;AAAA,MAEZ;AAOA,UAJA,KAAK,YAAY,OAAOkB,CAAY,GAIhClB,EAAW,UAAUA,EAAW,OAAO,WAAW;AACpD,cAAMyB,IAAY,GAAGzB,EAAW,OAAO,EAAE,KAAKkB,CAAY;AAC1D,QAAAlB,EAAW,OAAO,UAAU,YAAY,OAAOyB,CAAS;AAAA,MAC1D;AAEA,qBAAQ,IAAI,8CAA8CP,CAAY,GAGtE,KAAK,QAAQ,eAAelB,CAAU,GAE/B;AAAA,IACT,SAASK,GAAO;AACd,qBAAQ,MAAM,0CAA0CA,CAAK,GACtD;AAAA,IACT;AAAA,EACF;AAAA,EAEO,gBAAsB;AAC3B,YAAQ;AAAA,MACN;AAAA,MACA,KAAK,KAAK;AAAA,IAAA;AAGZ,UAAM2B,IAAgB,MAAM,KAAK,KAAK,YAAY,MAAM;AACxD,eAAWd,KAAgBc;AACzB,WAAK,eAAed,CAAY;AAAA,EAEpC;AAAA,EAEO,iBAA+B;AACpC,WAAO,MAAM,KAAK,KAAK,YAAY,QAAQ;AAAA,EAC7C;AAAA,EAEO,cAAclE,GAAyC;AAC5D,UAAMkE,IAAe,GAAG,KAAK,KAAK,EAAE,KAAKlE,CAAY;AACrD,WAAO,KAAK,YAAY,IAAIkE,CAAY,KAAK;AAAA,EAC/C;AAAA,EAEO,iBACLA,GACAe,GACS;AACT,QAAI;AACF,YAAMjC,IAAa,KAAK,YAAY,IAAIkB,CAAY;AACpD,UAAI,CAAClB;AACH,uBAAQ;AAAA,UACN;AAAA,UACAkB;AAAA,QAAA,GAEK;AAIT,aAAO,OAAOlB,GAAYiC,CAAO;AAEjC,YAAMl4B,IAAIi2B,EAAW;AACrB,UAAIj2B,GAAG;AAeL,YAbIk4B,EAAQ,aAAa,QAAQl4B,EAAE,qBACjCA,EAAE,kBAAkBk4B,EAAQ,SAAS,GAEnCA,EAAQ,aAAa,QAAQl4B,EAAE,kBACjCA,EAAE,eAAek4B,EAAQ,SAAS,GAEpC,KAAK,oBAAoBl4B,GAAGi2B,CAAU,GAEjCiC,EAAgB,SAAS,QAAQl4B,EAAE,YACtCA,EAAE,SAAUk4B,EAAgB,KAAK,GAI9BA,EAAgB,YAAY,QAAQl4B,EAAE,SAAS;AAClD,gBAAM9F,IAA8B;AAAA,YAClC,QAAQ;AAAA,YACR,QAAQ;AAAA,YACR,YAAY;AAAA,YACZ,UAAU;AAAA,YACV,QAAQ;AAAA,UAAA;AAEV,UAAA8F,EAAE,QAAQ9F,EAAKg+B,EAAgB,QAAQ,KAAK,QAAQ;AAAA,QACtD;AAWA,YAVKA,EAAgB,iBAAiB,SAEpCl4B,EAAE,gBAAiBk4B,EAAgB,gBAEhCA,EAAgB,iBAAiB,SAEpCl4B,EAAE,gBAAiBk4B,EAAgB,eACnCl4B,EAAE,SAAA,IAIDk4B,EAAgB,mBAAmB,QACnCA,EAAgB,kBAAkB,MACnC;AACA,gBAAM3Y,IACF2Y,EAAgB,mBACjBjC,EAAmB,kBAChB,UACA,QACAkC,IACFD,EAAgB,kBACjBjC,EAAmB,kBACpB,KACI,UACA;AACN,UAAAj2B,EAAE,YAAYuf,GAAK4Y,CAAG;AAAA,QACxB;AAEA,QAAAn4B,EAAE,SAAA;AAAA,MACJ;AAEA,qBAAQ,IAAI,uCAAuCm3B,CAAY,GACxD;AAAA,IACT,SAASb,GAAO;AACd,qBAAQ,MAAM,iDAAiDA,CAAK,GAC7D;AAAA,IACT;AAAA,EACF;AAAA;AAAA,EAGQ,oBAAoBrB,GAAkBgB,GAA8B;AAC1E,UAAMmC,IAAOnD,GAAa;AAC1B,QAAKmD,GAAM,SACPnC,EAAW,eAAe,QAC5BmC,EAAK,KAAK,kBAAkBnC,EAAW,WAAW,GAEhDA,EAAW,eAAe,SAAW;AACvC,YAAMoC,IAAkC;AAAA,QACtC,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,MAAM;AAAA,QACN,QAAQ;AAAA,MAAA;AAEV,MAAAD,EAAK,KAAK,UAAUC,EAAQpC,EAAW,UAAU,KAAK,IAAI;AAAA,IAC5D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,oBACLhD,GACAwC,GACAlK,GACS;AACT,UAAM0K,IAAa,KAAK,YAAY,IAAI,GAAG,KAAK,KAAK,EAAE,KAAKhD,CAAY,EAAE;AAC1E,WAAKgD,KACDR,MAAU,WAAUQ,EAAW,eAAe1K,MAClC,eAAeA,GAC/B0K,EAAW,aAAa,sBAAsBR,GAAOlK,CAAM,GACpD,MAJiB;AAAA,EAK1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaQ,qBACN0K,GACAxd,GACM;AACN,UAAM,EAAE,OAAAgd,GAAO,cAAAxC,GAAc,WAAAD,GAAW,OAAA1tB,MAAUmT,GAC5C6f,IAAQ;AAAA,MACZ,WAAWrC,EAAW;AAAA,MACtB,WAAWA,EAAW;AAAA,MACtB,UAAWA,EAAmB;AAAA,MAC9B,eAAgBA,EAAmB;AAAA,MACnC,eAAgBA,EAAmB;AAAA,MACnC,iBAAkBA,EAAmB;AAAA,MACrC,gBAAiBA,EAAmB;AAAA,IAAA,GAQhCsC,KAAetC,EAAW,GAAG,MAAM,IAAI,EAAE,CAAC,KAAK,IAClD,KAAA,EACA,QAAQ,SAAS,EAAE;AAEtB,eAAW,MAAM;AACf,UAAI;AACF,YAAIR,MAAU,UAAU;AACtB,gBAAM/qB,IAAcurB,EAAW;AAC/B,cAAI,CAACvrB,GAAQ,cAAe;AAC5B,cAAIsoB,KAAa,CAACC,GAAc;AAE9B,gBAAI,CAAC3tB,EAAO;AACZ,YAAIizB,KAAa7tB,EAAO,cAAc,kBAAkBurB,EAAW,EAAE,GACrEvrB,EAAO,cAAc,uBAAuBpF,GAAOgzB,CAAK;AAAA,UAC1D,OAAO;AAGL,kBAAME,IAAU,KAAK,MAAM,MAAM,IAAIvF,CAAY;AACjD,gBAAI,CAACuF,EAAS;AACd,gBAAIA,EAAQ,OAAOD,GAAa;AAI9B,mBAAK,cAAc7tB,GAAQurB,EAAW,IAAIuC,GAAS,gBAAgBlzB,CAAK;AACxE;AAAA,YACF;AACA,YAAIizB,KAAa7tB,EAAO,cAAc,kBAAkBurB,EAAW,EAAE,GACrEvrB,EAAO,cAAc,eAAe8tB,GAASF,CAAK,GAClD,KAAK,cAAc5tB,GAAQ8tB,EAAQ,IAAIA,GAAS,gBAAgBlzB,CAAK;AAAA,UACvE;AAAA,QACF,OAAO;AAEL,cAAI0tB,KAAa,CAACC,EAAc;AAChC,gBAAMwF,IAAiBxC,EAAW,QAC5BvX,IAAauX,EAAW,QACxBuC,IAAU,KAAK,MAAM,MAAM,IAAIvF,CAAY;AACjD,cAAI,CAACuF,KAAW,CAAC9Z,KAAS,CAAC+Z,GAAW,cAAe;AACrD,cAAID,EAAQ,OAAOC,EAAU,IAAI;AAG/B,iBAAK,cAAcA,GAAW/Z,EAAM,IAAI8Z,GAAS,gBAAgBlzB,CAAK;AACtE;AAAA,UACF;AACA,UAAAmzB,EAAU,cAAc,kBAAkBxC,EAAW,EAAE,GACvDuC,EAAQ,eAAe,eAAe9Z,GAAO4Z,CAAK,GAElD,KAAK,cAAcE,GAAS9Z,EAAM,IAAI8Z,GAAS,gBAAgBlzB,CAAK;AAAA,QACtE;AAAA,MACF,SAASqB,GAAG;AACV,gBAAQ,KAAK,oDAAoDA,CAAC;AAAA,MACpE;AAAA,IACF,GAAG,CAAC;AAAA,EACN;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,cACN+xB,GACAC,GACAC,GACAnD,GACAnwB,GACM;AACN,QAAI;AACF,UAAI,CAACA,EAAO;AACZ,YAAMjK,IAAIu9B,GAAY,WAAW,CAAA;AACjC,UAAI,CAACv9B,EAAE,SAAS,CAACA,EAAE,OAAQ;AAC3B,YAAMw9B,IAAQ,CAACh4B,MAAc,KAAK,IAAI,GAAG,KAAK,IAAI,GAAGA,CAAC,CAAC;AAQvD,UAAIsF,IAAKb,EAAM,GACXc,IAAKd,EAAM;AACf,YAAMsJ,IAAQvT,EAAE,QAAQ,iBAAiB;AACzC,UAAIuT,GAAO;AACT,cAAM/H,KAAMxL,EAAE,KAAK,KAAKA,EAAE,QAAQ,GAC5ByL,KAAMzL,EAAE,KAAK,KAAKA,EAAE,SAAS,GAC7By9B,IAAO,CAAClqB,IAAQ,KAAK,KAAM,KAC3B5H,IAAKb,IAAKU,GACVI,IAAKb,IAAKU;AAChB,QAAAX,IAAKU,IAAKG,IAAK,KAAK,IAAI8xB,CAAG,IAAI7xB,IAAK,KAAK,IAAI6xB,CAAG,GAChD1yB,IAAKU,IAAKE,IAAK,KAAK,IAAI8xB,CAAG,IAAI7xB,IAAK,KAAK,IAAI6xB,CAAG;AAAA,MAClD;AACA,UAAIvb,IAAKsb,GAAO1yB,KAAM9K,EAAE,KAAK,MAAMA,EAAE,KAAK,GACtCmiB,IAAKqb,GAAOzyB,KAAM/K,EAAE,KAAK,MAAMA,EAAE,MAAM;AAM3C,YAAMuwB,IAAKrO,GACLsO,IAAK,IAAItO,GACThL,IAAKiL,GACLsO,IAAK,IAAItO,GACTub,IAAU,KAAK,IAAInN,GAAIC,GAAItZ,GAAIuZ,CAAE;AACvC,MAAIiN,MAAYnN,IAAIrO,IAAK,IAChBwb,MAAYlN,IAAItO,IAAK,IACrBwb,MAAYxmB,IAAIiL,IAAK,IACzBA,IAAK;AACV,YAAM+N,IAAS,EAAE,GAAGhO,GAAI,GAAGC,EAAA,GACrBwb,IAAON,GAAW,eAGlBO,IACJD,GAAM,cAAc,KAAK,CAACp4B,MAAWA,EAAE,OAAO+3B,CAAO,KACrDK,GAAM,cAAc,KAAK,CAACp4B,MAAWA,EAAE,YAAY+3B,CAAO;AAC5D,MAAIM,GAAO,OACTD,EAAK,kBAAkBC,EAAM,IAAIxD,GAAOlK,CAAM,GAI7CmN,EAAU,OAAe,YAAY,2BAA2B;AAAA,QAC/D,IAAIA,EAAU;AAAA,QACd,MAAMjD;AAAA,QACN,KAAKlK;AAAA,QACL,eAAe0N,EAAM;AAAA,MAAA,CACtB;AAAA,IAEL,QAAY;AAAA,IAEZ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,gBACL9B,GACA1B,GACArzB,GACiC;AACjC,UAAM6zB,IAAa,KAAK,YAAY,IAAIkB,CAAY;AACpD,QAAI,CAAClB,EAAY,QAAO;AACxB,UAAMj2B,IAASi2B,EAAW;AAC1B,QAAI7zB,MAAS,YAAY;AACvB,YAAMmpB,IAASvrB,GAAG,mBAAmBy1B,CAAK,KAAK,EAAE,GAAG,KAAK,GAAG,IAAA;AAC3D,aAAAQ,EAAmBR,IAAQ,QAAQ,IAAIlK,GACxCvrB,GAAG,sBAAsBy1B,GAAOlK,CAAM,GAC/BA;AAAA,IACT;AACC,WAAA0K,EAAmBR,IAAQ,QAAQ,IAAI,MACxCz1B,GAAG,sBAAsBy1B,GAAO,IAAI,GAC7B;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeQ,iBAAiBpJ,GAAgB;AACvC,UAAM6M,IAAY,MAChB,CAAC7M,EAAI,cAAc,SAASA,EAAI,cAAc,OAAO,EAAE;AAAA,MACrD,CAAC3pB,MAAWA,KAAKA,EAAE;AAAA,IAAA,GAEjBy2B,IAAS,CAACx4B,MAA2B;AACzC,MAAAu4B,EAAA,EAAY,QAAQ,CAACx2B,MAAW;AAC9B,QAAI/B,IAAS+B,EAAE,KAAK,UAAU,IAAI,4BAA4B,IAIrD,CAAC2pB,EAAI,kBAAkB,CAACA,EAAI,oBACnC3pB,EAAE,KAAK,UAAU,OAAO,4BAA4B;AAAA,MACxD,CAAC;AAAA,IACH;AAEA,IAAA2pB,EAAI,iBAAiB8M;AACrB,UAAMC,IAAiB,MACrBF,EAAA,EAAY,QAAQ,CAACx2B,MAAW;AAC9B,MAAIA,EAAE,iBACNA,EAAE,eAAe,IACjBA,EAAE,KAAK,cAAc,MAAMy2B,EAAO,EAAI,CAAC,GACvCz2B,EAAE,KAAK,cAAc,MAAMy2B,EAAO,EAAK,CAAC,GAExCz2B,EAAE,KAAK,aAAa,MAAM;AACxB,QAAA2pB,EAAI,mBAAmB,IACvB8M,EAAO,EAAI;AAAA,MACb,CAAC,GACDz2B,EAAE,KAAK,WAAW,MAAM;AACtB,QAAA2pB,EAAI,mBAAmB,IAClBA,EAAI,kBAAgB8M,EAAO,EAAK;AAAA,MACvC,CAAC;AAAA,IACH,CAAC;AACH,KAAC9M,EAAI,SAASA,EAAI,SAAS,EAAE,QAAQ,CAAC/rB,MAAY;AAChD,MAAAA,GAAI,KAAK,cAAc,MAAM;AAC3B,QAAA64B,EAAO,EAAI,GACXC,EAAA;AAAA,MACF,CAAC,GACD94B,GAAI,KAAK,cAAc,MAAM64B,EAAO,EAAK,CAAC;AAAA,IAC5C,CAAC;AAAA,EACH;AAAA,EAEQ,YAAYlD,GAAwB5J,GAAUgN,GAAwB;AAC5E,UAAM3C,IAAa,KAAK;AACxB,IAAAA,EAAM,eAAA;AACN,UAAM0B,IAAO/L,GAAK;AAClB,QAAIxlB,GAAYC;AAChB,QAAI;AACF,YAAM0jB,IAAK4N,EAAK,KAAA;AAChB,MAAAvxB,IAAK2jB,EAAG,IACR1jB,IAAK0jB,EAAG;AAAA,IACV,QAAY;AACV;AAAA,IACF;AACA,UAAM6G,IAAiBqF,EAAM,oBAAoBA,EAAM;AACvD,QAAI,CAACrF,EAAW;AAKhB,UAAMiI,IAAI,IACJC,IAAM,GAENC,IAAoE;AAAA,MACxE;AAAA,QACE,KAAK;AAAA,QACL,OAAO;AAAA,QACP,SAAS,MAAM;AACZ,eAAK,KAAa,eAAe,oBAAoBH,CAAQ,GAC9D3C,EAAM,eAAA;AAAA,QACR;AAAA,MAAA;AAAA,MAEF;AAAA,QACE,KAAK;AAAA,QACL,OAZY;AAAA,QAaZ,SAAS,MAAM;AACb,eAAK,aAAaT,GAAY5J,GAAKgN,CAAQ,GAC3C,KAAK,wBAAwBpD,GAAY5J,GAAKgN,CAAQ;AAAA,QACxD;AAAA,MAAA;AAAA,IACF,GAEIpuB,IAAIuuB,EAAM,QACVC,IAAQH,IAAI,IAAIC,GAChBG,IAASzuB,KAAKquB,IAAI,MAAMruB,IAAI,KAAKsuB,GACjCI,IAAS9yB,IAAK6yB,IAAS,IAAIJ,GAE3BM,IAAMvI,EAAU,MAAA,EAAQ,SAAS,UAAU,EAAE,SAAS,cAAc;AAC1E,IAAAuI,EACG,KAAKF,IAAS,IAAIJ,IAAI,IAAI,EAAE,EAC5B,QAAQA,IAAI,IAAI,MAAM,CAAC,EACvB,OAAOzyB,GAAIC,CAAE,EACb,KAAK,SAAS,EACd,OAAO,EAAE,OAAO,WAAW,OAAO,EAAA,CAAG;AACxC,UAAM+yB,IAAgB,KAAK,KAAa;AACxC,IAAAL,EAAM,QAAQ,CAACj5B,GAAGlG,MAAM;AACtB,YAAMy/B,IAAKH,IAASt/B,IAAIo/B,GAClBM,IAAMH,EAAI,QAAQ,SAAS,aAAar5B,EAAE,GAAG,EAAE;AACrD,MAAAw5B,EAAI,OAAOT,IAAI,CAAC,EAAE,OAAOQ,GAAIhzB,CAAE,EAAE,KAAK,SAAS,EAAE,KAAK,gBAAgB,IAAK,GAC3E+yB,EAAQ,eAAeE,GAAKx5B,EAAE,KAAKu5B,GAAIhzB,GAAIvG,EAAE,KAAK,GAClDw5B,EAAI,KAAK,kBAAkB,KAAK;AAChC,UAAI;AACF,QAAAA,EAAI,KAAK,MAAM,SAAS;AAAA,MAC1B,QAAY;AAAA,MAEZ;AACA,MAAAA,EAAI,GAAG,aAAa,CAACpzB,MAAWA,EAAE,mBAAmB,GACrDozB,EAAI,GAAG,SAAS,CAACpzB,MAAW;AAC1B,QAAAA,EAAE,kBAAA,GACFpG,EAAE,QAAA;AAAA,MACJ,CAAC;AAAA,IACH,CAAC,GACDq5B,EAAI,KAAK,kBAAkB,KAAK,GAChClD,EAAM,iBAAiBkD;AAIvB,QAAI;AACF,MAAAvN,EAAI,kBAAA,GACJqK,EAAM,yBAAyBrK,GAE/BA,EAAI,iBAAiB,IACrBA,EAAI,iBAAiB,EAAI;AAAA,IAC3B,QAAY;AAAA,IAEZ;AAEA,QAAI;AACF,MAAAqK,EAAM,kBAAkB,QAAA;AAAA,IAC1B,QAAY;AAAA,IAEZ;AAAA,EACF;AAAA,EAEQ,aAAaT,GAAwB5J,GAAUgN,GAAwB;AAC7E,UAAMhuB,IAAS,KAAK,KAAK,OAAO,SAAS;AACzC,QAAI,CAACA,GAAQ,oBAAqB;AAIlC,UAAM2tB,IAAa,KAAK,KAAa,eAC/BgB,IACJhB,GAAM,cAAc,KAAK,CAAC,MAAW,EAAE,YAAYK,CAAQ,KAC3DL,GAAM,iBAAiBK,CAAQ,KAC/BpD;AACF,IAAA5qB,EAAO,oBAAoB,KAAK,MAAM2uB,GAAa,CAACC,IAAY,OAAO;AAErE,UAAID,GAAa,MAAO,KAAK,KAAa;AACxC,mBAAW,CAACE,GAAM95B,CAAG,KAAK,OAAO,QAAQ65B,CAAI;AAC1C,eAAK,KAAa,cAAc;AAAA,YAC/BD,EAAY;AAAA,YACZE;AAAA,YACA95B;AAAA,UAAA;AAAA,IAIR,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,wBACN61B,GACA5J,GACAgN,GACM;AACN,UAAM3C,IAAa,KAAK;AAExB,IAAIA,EAAM,0BACRA,EAAM,uBAAuB,QAAQ,CAAC77B,MAAW;AAC/C,UAAI;AACF,QAAAA,EAAE,OAAA;AAAA,MACJ,QAAY;AAAA,MAEZ;AAAA,IACF,CAAC,GAEH67B,EAAM,yBAAyB,CAAA;AAE/B,UAAMyD,IAAgB9N,GAAK,WAAW;AACtC,QAAI,CAAC8N,KAAY,CAACA,EAAS,iBAAkB;AAC7C,QAAInR,IAAQ;AACZ,QAAI;AACF,MAAAA,IAAQmR,EAAS,eAAA;AAAA,IACnB,QAAY;AACV;AAAA,IACF;AACA,UAAM5mB,IAAK4mB,EAAS,iBAAiB,CAAC,GAChCzV,IAAKyV,EAAS,iBAAiBnR,CAAK,GAEpCgQ,IAAa,KAAK,KAAa,eAC/BC,IAAQD,GAAM,cAAc,KAAK,CAACp4B,MAAWA,EAAE,YAAYy4B,CAAQ;AACzE,QAAI,CAACJ,EAAO;AAKZ,UAAMmB,IAAW,CAACnvB,MAAW;AAC3B,YAAM5P,IAAI4P,GAAG,WAAW,CAAA;AACxB,aAAO,EAAE,IAAI5P,EAAE,KAAK,MAAMA,EAAE,SAAS,KAAK,GAAG,IAAIA,EAAE,KAAK,MAAMA,EAAE,UAAU,KAAK,EAAA;AAAA,IACjF,GACMg/B,IAAO,CAACt4B,GAAQ/B,MAAW,KAAK,MAAM+B,EAAE,IAAI/B,EAAE,GAAG+B,EAAE,IAAI/B,EAAE,CAAC,GAC1Ds6B,IAAOF,EAAS,KAAK,IAAI,GACzBG,IAAaF,EAAK9mB,GAAI+mB,CAAI,KAAKD,EAAK3V,GAAI4V,CAAI,GAC5CE,IAAQ,KAAK,IAAI,IAAIxR,IAAQ,IAAI,GACjCyR,IAAQN,EAAS,iBAAiBI,IAAaC,IAAQxR,IAAQwR,CAAK,GACpEE,IAAQP,EAAS,iBAAiBI,IAAavR,IAAQwR,IAAQA,CAAK,GAEpEnJ,IAAiBqF,EAAM,oBAAoBA,EAAM,QACjDiE,IAAU,WACVC,IAAM,WAENC,IAAa,CAACzE,GAASX,MAA+B;AAC1D,YAAMqF,IACJrF,MAAU,WAAW,CAAC,CAACwD,EAAM,eAAe,CAAC,CAACA,EAAM,cAChD92B,IAAQ24B,IAAWF,IAAMD,GACzB9/B,IAAIw2B,EACP,MAAA,EACA,SAAS,eAAe,EACxB,SAAS,iBAAiBoE,CAAK,EAAE,EACjC,SAASqF,IAAW,2BAA2B,wBAAwB;AAC1E,MAAAjgC,EAAE,OAAO,EAAE,EAAE,OAAOu7B,EAAG,GAAGA,EAAG,CAAC,EAAE,KAAK,SAAS,EAAE,OAAO,EAAE,OAAAj0B,GAAO,OAAO,KAAK,GAC5E60B,GAAU,aAAan8B,GAAGu7B,EAAG,GAAGA,EAAG,GAAGj0B,GAAO24B,CAAQ,GAGrDjgC,EAAE,OAAO,EAAE,EAAE,OAAOu7B,EAAG,GAAGA,EAAG,CAAC,EAAE,KAAK,SAAS,EAAE,KAAK,gBAAgB,IAAK,GAC1Ev7B,EAAE,KAAK,kBAAkB,KAAK;AAC9B,UAAI;AACF,QAAAA,EAAE,KAAK,MAAM,SAAS;AAAA,MACxB,QAAY;AAAA,MAEZ;AACA,MAAAA,EAAE,GAAG,aAAa,CAAC8L,MAAWA,EAAE,mBAAmB,GACnD9L,EAAE,GAAG,SAAS,CAAC8L,MAAW;AACxB,QAAAA,EAAE,kBAAA;AACF,cAAMuzB,IAAOzE,MAAU,WAAW,eAAe,cAC3Cr1B,IAAM06B,IAAW,aAAa;AACpC,YAAI;AACF,UAAA9B,EAAK,kBAAkBC,EAAM,IAAIiB,GAAM95B,CAAG;AAAA,QAC5C,QAAc;AAAA,QAEd;AAEA,YAAI;AACF,UAAAs2B,EAAM,YAAY,2BAA2B;AAAA,YAC3C,IAAI,KAAK,KAAK;AAAA,YACd,eAAeuC,EAAM;AAAA,YACrB,MAAAiB;AAAA,YACA,KAAA95B;AAAA,UAAA,CACD;AAAA,QACH,QAAc;AAAA,QAEd;AAEA,aAAK,wBAAwB61B,GAAY5J,GAAKgN,CAAQ;AAAA,MACxD,CAAC,GACD3C,EAAM,uBAAuB,KAAK77B,CAAC;AAAA,IACrC;AAEA,IAAAggC,EAAWJ,GAAO,QAAQ,GAC1BI,EAAWH,GAAO,QAAQ;AAC1B,QAAI;AACF,MAAAhE,EAAM,kBAAkB,QAAA;AAAA,IAC1B,QAAY;AAAA,IAEZ;AAAA,EACF;AAAA;AAAA,EAGA,OAAe,aACb77B,GACAgM,GACAC,GACA3E,GACA44B,GACM;AACN,UAAMngC,IAAI,EAAE,OAAAuH,GAAO,OAAO,KAAK,SAAS,SAAS,UAAU,QAAA;AAE3D,IAAAtH,EAAE,KAAK,IAAI,CAAC,EACT,OAAO,GAAG,EACV,KAAKgM,IAAK,KAAKC,IAAK,GAAG,EACvB,KAAK,MAAM,EACX,OAAOlM,CAAC,GAEPmgC,IACFlgC,EAAE;AAAA,MACA,KAAKgM,IAAK,GAAG,IAAIC,IAAK,GAAG;AAAA,IAAA,EAExB,KAAK,MAAM,EACX,OAAOlM,CAAC,IAEXC,EAAE,KAAK,KAAKgM,IAAK,GAAG,IAAIC,IAAK,GAAG,kCAAkC,EAC/D,KAAK,MAAM,EACX,OAAOlM,CAAC,GAGbC,EAAE,OAAO,GAAG,EAAE,OAAOgM,GAAIC,IAAK,CAAC,EAAE,KAAK3E,CAAK;AAAA,EAC7C;AAAA,EAEO,YAAqB;AAC1B,WAAO,KAAK;AAAA,EACd;AAAA,EAEO,cAAcqJ,GAAoC;AACvD,SAAK,UAAU,EAAE,GAAG,KAAK,SAAS,GAAGA,EAAA,GACrC,QAAQ,IAAI,6CAA6C,KAAK,KAAK,EAAE;AAAA,EACvE;AACF;AC1gCO,SAASwvB,GACd/I,GACA0G,GACAsC,GACa;AACb,SAAO;AAAA,IACL,IAAI,GAAGhJ,CAAQ,KAAK0G,CAAO;AAAA,IAC3B,UAAA1G;AAAA,IACA,SAAA0G;AAAA,IACA,WAAW;AAAA,IACX,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,eAAe;AAAA,IACf,eAAe;AAAA,IACf,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,GAAGsC;AAAA,EAAA;AAEP;;;;;ACzCO,MAAMC,GAAc;AAAA,EAwBzB,YAAY99B,GAAYoO,IAAgC,IAAI;AArB5D,SAAQ,+BAAyC,IAAA,GAmBjD,KAAQ,WAAoB,IAG1B,KAAK,OAAOpO,GACZ,KAAK,QAAQA,EAAK,OAClB,KAAK,WAAWoO,EAAQ,WAAW;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAlBA,IAAW,eAAiE;AAC1E,UAAMkrB,IAAS,KAAK,MAAc;AAClC,WAAO,MAAM,KAAK,KAAK,SAAS,QAAQ,EAAE,IAAI,CAAC91B,OAAO;AAAA,MACpD,GAAGA;AAAA,MACH,QACE81B,GAAO,OAAO,MAAM91B,EAAE,QAAQ,MAC7BA,EAAE,aAAa,KAAK,KAAK,KAAK,KAAK,OAAO;AAAA,MAC7C,OACE81B,GAAO,OAAO,MAAM91B,EAAE,OAAO,MAC5BA,EAAE,YAAY,KAAK,KAAK,KAAK,KAAK,OAAO;AAAA,IAAA,EAC5C;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeO,eACLu6B,GACAn/B,GACa;AACb,UAAMi9B,IAAQ+B,GAAyB,KAAK,KAAK,IAAIG,EAAU,IAAIn/B,CAAI;AAQvE,QAAI,CAACA,GAAM,MAAM,KAAK,SAAS,IAAIi9B,EAAM,EAAE,GAAG;AAC5C,UAAIhuB,IAAI;AACR,aAAO,KAAK,SAAS,IAAI,GAAGguB,EAAM,EAAE,IAAIhuB,CAAC,EAAE,IAAG,CAAAA;AAC9C,MAAAguB,EAAM,KAAK,GAAGA,EAAM,EAAE,IAAIhuB,CAAC;AAAA,IAC7B;AAGA,gBAAK,SAAS,IAAIguB,EAAM,IAAIA,CAAK,GAGjC,KAAK,kBAAkBA,GAAOkC,CAAS,GAGtC,KAAK,KAAa,OAAO,YAAY,mBAAmB,EAAE,GAAGlC,GAAO,GAErE,QAAQ;AAAA,MACN;AAAA,MACAA,EAAM;AAAA,MACN;AAAA,MACA,KAAK,KAAK;AAAA,MACV;AAAA,MACAkC,EAAU;AAAA,IAAA,GAGLlC;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKO,kBAAkBmC,GAAmC;AAI1D,UAAMC,IAAS,KAAK,SAAS,IAAID,CAAgB,GAC3CE,IAAUD,IACZ,CAACA,CAAM,IACP,MAAM,KAAK,KAAK,SAAS,OAAA,CAAQ,EAAE;AAAA,MACjC,CAACz6B,MAAMA,EAAE,YAAYw6B;AAAA,IAAA;AAG3B,QAAIE,EAAQ,WAAW;AACrB,qBAAQ;AAAA,QACN;AAAA,QACAF;AAAA,MAAA,GAEK;AAGT,eAAWnC,KAASqC;AAGlB,MAAI,KAAK,KAAK,aACZ,KAAK,KAAK,UAAU,eAAerC,EAAM,EAAE,GAE7C,KAAK,SAAS,OAAOA,EAAM,EAAE,GAC7B,QAAQ,IAAI,2CAA2CA,EAAM,EAAE,GAI9D,KAAK,KAAa,OAAO,YAAY,sBAAsB;AAAA,QAC1D,UAAU,KAAK,KAAK;AAAA,QACpB,SAASA,EAAM;AAAA,QACf,IAAIA,EAAM;AAAA,MAAA,CACX;AAEH,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKO,YAAkB;AACvB,UAAMlB,IAAM,MAAM,KAAK,KAAK,SAAS,MAAM;AAC3C,eAAWxqB,KAAMwqB;AAEf,WAAK,kBAAkBxqB,CAAE;AAAA,EAE7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,kBACLguB,GACArB,GACA95B,GACS;AACT,QAAI64B,IAAQ,KAAK,SAAS,IAAIsC,CAAa;AAC3C,QAAI,CAACtC;AACH,iBAAWr4B,KAAK,KAAK,SAAS,OAAA;AAC5B,YAAIA,EAAE,OAAO26B,GAAe;AAC1B,UAAAtC,IAAQr4B;AACR;AAAA,QACF;AAAA;AAGJ,QAAI,CAACq4B,EAAO,QAAO;AAKnB,UAAMuC,IAASvC,EAAM;AAIrB,QAAIiB,MAAS,gBAAgBA,MAAS,cAAc;AAClD,YAAMzE,IAAQyE,MAAS,eAAe,WAAW,UAC3C3O,IAAS,KAAK,KAAK,WAAW;AAAA,QAClCiQ;AAAA,QACA/F;AAAA,QACAr1B,MAAQ,aAAa,aAAa;AAAA,MAAA;AAEnC,aAAA64B,EAAcxD,IAAQ,QAAQ,IAAIlK,KAAU,MACtC;AAAA,IACT;AAIA,QAFC0N,EAAciB,CAAI,IAAI95B,GAEnB85B,MAAS,kBAAkBA,MAAS,gBAAgB;AACtD,YAAMzE,IAAQyE,MAAS,iBAAiB,WAAW;AAGlD,MAFkB,KAAK,KAAK,WAAW,iBAAA,EACrC,KAAK,CAACl6B,MAAWA,EAAE,OAAOw7B,CAAM,GACd,aAAa,sBAAsB/F,GAAOr1B,CAAG;AAAA,IACpE;AACE,WAAK,KAAK,WAAW,iBAAiBo7B,GAAQ,EAAE,CAACtB,CAAI,GAAG95B,GAAY;AAEtE,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKO,uBAAuB65B,GAAkC;AAC9D,eAAW,CAAC1sB,GAAI0rB,CAAK,KAAK,KAAK;AAC7B,aAAO,OAAOA,GAAOgB,CAAI,GAIrB,KAAK,KAAK,aACZ,KAAK,KAAK,UAAU,iBAAiBhB,EAAM,IAAI;AAAA,QAC7C,WAAWA,EAAM;AAAA,QACjB,WAAWA,EAAM;AAAA,QACjB,aAAaA,EAAM;AAAA,QACnB,YAAYA,EAAM;AAAA,MAAA,CACnB;AAAA,EAGP;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,UAAgB;AAIrB,YAAQ;AAAA,MACN;AAAA,MACA,KAAK,KAAK;AAAA,IAAA;AAAA,EAEd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,0BAAgC;AACrC,eAAW,CAAC1rB,GAAI0rB,CAAK,KAAK,KAAK;AAE7B,UADkB,KAAK,MAAM,MAAM,IAAIA,EAAM,OAAO,KACnC,KAAK,KAAK,WAAW;AAEpC,cAAMuC,IAAS,GAAG,KAAK,KAAK,EAAE,KAAKvC,EAAM,OAAO;AAChD,aAAK,KAAK,UAAU,iBAAiBuC,GAAQ;AAAA,UAC3C,WAAWvC,EAAM;AAAA,UACjB,WAAWA,EAAM;AAAA,UACjB,aAAaA,EAAM;AAAA,UACnB,YAAYA,EAAM;AAAA,QAAA,CACnB;AAAA,MACH;AAAA,EAEJ;AAAA;AAAA;AAAA,EAKO,kBAAiC;AACtC,WAAO,MAAM,KAAK,KAAK,SAAS,QAAQ;AAAA,EAC1C;AAAA;AAAA,EAGO,eAAeN,GAA0C;AAC9D,WAAO,KAAK,SAAS,IAAI,GAAG,KAAK,KAAK,EAAE,KAAKA,CAAO,EAAE;AAAA,EACxD;AAAA;AAAA,EAGO,iBAAiBprB,GAAqB;AAC3C,WAAO,KAAK,SAAS,IAAIA,CAAE;AAAA,EAC7B;AAAA;AAAA,EAGO,kBAA2B;AAChC,WAAO,KAAK,SAAS,OAAO;AAAA,EAC9B;AAAA;AAAA,EAGO,QAAgB;AACrB,WAAO,KAAK,SAAS;AAAA,EACvB;AAAA;AAAA;AAAA,EAKO,YAA6C;AAClD,WAAO;AAAA,MACL,cAAc,MAAM,KAAK,KAAK,SAAS,QAAQ;AAAA,IAAA;AAAA,EAEnD;AAAA;AAAA,EAIO,SAAe;AACpB,SAAK,WAAW;AAAA,EAClB;AAAA,EAEO,UAAgB;AACrB,SAAK,WAAW;AAAA,EAClB;AAAA,EAEO,YAAqB;AAC1B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGO,UAAgB;AACrB,SAAK,UAAA,GACL,KAAK,QAAA,GACL,KAAK,SAAS,MAAA,GACb,KAAa,OAAO,MACpB,KAAa,QAAQ;AAAA,EACxB;AAAA;AAAA,EAIQ,kBAAkB0rB,GAAoBkC,GAAsB;AAClE,QAAI,CAAC,KAAK,KAAK,UAAW;AAG1B,IAAK,KAAK,KAAK,UAAU,eACvB,KAAK,KAAK,UAAU,OAAA;AAGtB,UAAM7C,IAAa;AAAA;AAAA;AAAA;AAAA,MAIjB,cAAcW,EAAM;AAAA,MACpB,WAAWA,EAAM;AAAA,MACjB,WAAWA,EAAM;AAAA,MACjB,aAAaA,EAAM;AAAA,MACnB,YAAYA,EAAM;AAAA,MAClB,UAAWA,EAAc;AAAA,MACzB,eAAgBA,EAAc;AAAA,MAC9B,eAAgBA,EAAc;AAAA,MAC9B,iBAAkBA,EAAc;AAAA,MAChC,gBAAiBA,EAAc;AAAA,MAC/B,cAAeA,EAAc;AAAA,MAC7B,cAAeA,EAAc;AAAA,MAC7B,OAAQA,EAAc;AAAA,IAAA;AAIxB,QAAKA,EAAc,aAAa;AAC9B,WAAK,KAAK,UAAU;AAAA,QACjBA,EAAc;AAAA,QACfA,EAAM;AAAA,QACNX;AAAA,MAAA;AAEF;AAAA,IACF;AAEA,IAAK6C,KAGL,KAAK,KAAK,UAAU,UAAUA,GAAW7C,CAAK;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,uBACLhzB,GACAtJ,GACa;AACb,UAAM28B,IACH38B,GAAc,WACf,UAAU,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC,IAC7Ci9B,IAAQ+B,GAAyB,KAAK,KAAK,IAAIrC,GAAS;AAAA,MAC5D,GAAG38B;AAAA,MACH,SAAA28B;AAAA,MACA,aAAarzB;AAAA,IAAA,CACd;AACD,gBAAK,SAAS,IAAI2zB,EAAM,IAAIA,CAAK,GACjC,KAAK,kBAAkBA,GAAO,IAAI,GACjC,KAAK,KAAa,OAAO,YAAY,mBAAmB,EAAE,GAAGA,GAAO,GAC9DA;AAAA,EACT;AACF;AC/WO,MAAMwC,GAAO;AAAA,EAQlB,YAAYr+B,GAAY;AANxB,SAAQ,iBAAsB,MAC9B,KAAQ,WAAmB,IAC3B,KAAQ,YAAoB,GAC5B,KAAQ,aAAqB,GAC7B,KAAQ,sBAA+B,IAGrC,KAAK,OAAOA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,IACLiT,GACApV,GACAC,GACAwnB,IAA+B,IACzB;AACN,SAAK,WAAWrS,GAChB,KAAK,YAAYpV,KAAS,KAAK,KAAK,QAAQ,SAAS,KACrD,KAAK,aAAaC,KAAU,KAAK,KAAK,QAAQ,UAAU,IACxD,KAAK,sBAAsBwnB,GAG3B,KAAK,KAAK,QAAQ,QAAQrS,GAC1B,KAAK,KAAK,QAAQ,iBAAiB,KAAK,WACxC,KAAK,KAAK,QAAQ,kBAAkB,KAAK,YAEzC,KAAK,OAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA,EAKO,QAAc;AACnB,IAAI,KAAK,mBACP,KAAK,eAAe,OAAA,GACpB,KAAK,iBAAiB,OAGxB,KAAK,WAAW,IAChB,KAAK,KAAK,QAAQ,QAAQ;AAG1B,UAAM8U,IAAQ,KAAK,KAAK,eAAe,KAAK,KAAK;AACjD,IAAIA,KACFA,EAAM,KAAK,KAAK,KAAK,QAAQ,mBAAmB,SAAS;AAAA,EAE7D;AAAA;AAAA,EAGO,UAAgB;AACrB,SAAK,MAAA,GACJ,KAAa,OAAO;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKO,SAAe;AACpB,IAAI,KAAK,YACP,KAAK,OAAA;AAAA,EAET;AAAA;AAAA,EAGO,WAAoB;AACzB,WAAO,CAAC,CAAC,KAAK;AAAA,EAChB;AAAA;AAAA,EAIQ,SAAe;AACrB,UAAMA,IAAQ,KAAK,KAAK,eAAe,KAAK,KAAK;AACjD,QAAI,GAAC,KAAK,YAAY,CAACA;AAEvB,UAAI;AAEF,QAAI,KAAK,kBACP,KAAK,eAAe,OAAA;AAGtB,cAAMzN,IAAI,KAAK,KAAK,QAAQ,SAAS,KAC/BhV,IAAI,KAAK,KAAK,QAAQ,UAAU,IAGhC9F,IAAO,KAAK,KAAK,SAAS,KAAA;AAChC,YAAI,CAACA,EAAM;AAGX,YAAI8+B,IAAO9+B,EAAK,KAAA;AAGhB,aAAK,iBAAiB8+B,EACnB,QAAQhkB,GAAGhV,GAAG,CAACi5B,MAAa;AAC3B,UAAAA,EACG,MAAM,KAAK,QAAQ,EACnB,KAAKjkB,GAAGhV,CAAC,EACT,KAAK,uBAAuB,KAAK,sBAAsB,kBAAkB,gBAAgB;AAAA,QAC9F,CAAC,EACA,KAAK,gBAAgB,mBAAmB,EACxC,KAAK,SAAS,MAAM,EACpB,KAAK,UAAU,MAAM,GAGxByiB,EAAM,KAAK,KAAK,cAAc,GAE9B,QAAQ;AAAA,UACN;AAAA,UACA,KAAK,KAAK;AAAA,UACV;AAAA,UACA,KAAK;AAAA,QAAA;AAAA,MAET,SAASmR,GAAO;AACd,gBAAQ,MAAM,sCAAsCA,CAAK;AAAA,MAC3D;AAAA,EACF;AACF;AC9HA,MAAMsF,yBAA+B,IAAA,GAC/BC,yBAA+C,IAAA,GAG/CC,yBAAkB,IAAI;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAMM,SAASC,GAASC,GAAmC;AAE1D,QAAMC,IAAaD,EAAW,KAAA,GACxBE,IAAQD,EAAW,YAAA;AAQzB,MALIH,GAAY,IAAII,CAAK,KAKrBN,GAAY,IAAIM,CAAK;AACvB,WAAO,QAAQ,QAAA;AAIjB,MAAIL,GAAa,IAAIK,CAAK;AACxB,WAAOL,GAAa,IAAIK,CAAK;AAG/B,QAAMC,IAAU,IAAI,QAAc,CAACC,GAASC,MAAW;AACrD,QAAI,OAAO,WAAa,KAAa;AACnC,MAAAD,EAAA;AACA;AAAA,IACF;AAGA,UAAME,IAAcL,EAAW,MAAM,GAAG,EAAE,CAAC,EAAE,KAAA,EAAO,QAAQ,SAAS,EAAE;AAKvE,QAAI;AACF,UAAI,SAAS,OAAO,QAAQ,SAASK,CAAW,GAAG,GAAG;AACpD,QAAAV,GAAY,IAAIM,CAAK,GACrBE,EAAA;AACA;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAGA,UAAMtd,IAAO,SAAS,cAAc,MAAM;AAC1C,IAAAA,EAAK,MAAM,cACXA,EAAK,OAAO,4CAA4C;AAAA,MACtDwd;AAAA,IAAA,CACD,0CAEDxd,EAAK,SAAS,MAAM;AAClB,MAAA8c,GAAY,IAAIM,CAAK,GACrBL,GAAa,OAAOK,CAAK,GACzB,QAAQ,IAAI,4BAA4BI,CAAW,GACnDF,EAAA;AAAA,IACF,GAEAtd,EAAK,UAAU,MAAM;AACnB,MAAA+c,GAAa,OAAOK,CAAK,GACzB,QAAQ,KAAK,oCAAoCI,CAAW,GAE5DF,EAAA;AAAA,IACF,GAEA,SAAS,KAAK,YAAYtd,CAAI;AAAA,EAChC,CAAC;AAED,SAAA+c,GAAa,IAAIK,GAAOC,CAAO,GACxBA;AACT;AAKA,eAAsBI,GAAa7F,GAA2B;AAC5D,QAAM8F,wBAAY,IAAA,GAEZC,IAAQ/F,EAAM,OAAO,YAAY,CAAA;AACvC,aAAWt5B,KAAQq/B;AACjB,IAAIr/B,EAAK,SAAS,cAChBo/B,EAAM,IAAIp/B,EAAK,QAAQ,UAAU;AAIrC,QAAMs/B,IAAW,MAAM,KAAKF,CAAK,EAAE,IAAI,CAAC51B,MAAMm1B,GAASn1B,CAAC,CAAC;AACzD,QAAM,QAAQ,IAAI81B,CAAQ,GAE1B,QAAQ,IAAI,iCAAiC,MAAM,KAAKF,CAAK,CAAC;AAChE;AAGO,SAASG,GAAaX,GAA6B;AACxD,SAAOJ,GAAY,IAAII,EAAW,YAAA,EAAc,MAAM;AACxD;;;;;;;ACnHO,MAAMY,GAAO;AAAA,EAKlB,YAAYx/B,GAAY;AAHxB,SAAQ,iBAAiB,IACzB,KAAQ,YAA4C,MAGlD,KAAK,OAAOA;AAAA,EACd;AAAA;AAAA,EAGO,UAAgB;AACrB,IAAI,KAAK,kBAAgB,KAAK,aAAA,GAC7B,KAAa,OAAO;AAAA,EACvB;AAAA;AAAA,EAGO,kBAA2B;AAChC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYO,cAAoB;AACzB,UAAMA,IAAO,KAAK;AAClB,QAAI,KAAK,kBAAkB,CAACA,KAAQA,EAAK,UAAW;AACpD,UAAM8nB,IAAS9nB,EAAK,UAAkB;AACtC,QAAI,CAAC8nB,EAAO;AAEZ,UAAMxN,IAAIta,EAAK,QAAQ,SAAS,KAC1BsF,IAAItF,EAAK,QAAQ,UAAU,IAE3By/B,IAAK,SAAS;AAAA,MADN;AAAA,MAGZ;AAAA,IAAA;AAEF,IAAAA,EAAG,aAAa,KAAK,GAAG,GACxBA,EAAG,aAAa,KAAK,GAAG,GACxBA,EAAG,aAAa,SAAS,OAAOnlB,CAAC,CAAC,GAClCmlB,EAAG,aAAa,UAAU,OAAOn6B,CAAC,CAAC,GACnCm6B,EAAG,MAAM,WAAW;AAEpB,UAAMC,IAAM,SAAS,cAAc,KAAK;AACxC,IAAAA,EAAI,aAAa,mBAAmB,MAAM,GAC1CA,EAAI,YAAY,oBAChBA,EAAI,cAAc1/B,EAAK,QAAQ,QAAQ,IACvC0/B,EAAI,MAAM,UAAU;AAAA,MAClB,SAASplB,CAAC;AAAA,MACV,UAAUhV,CAAC;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,eAAetF,EAAK,QAAQ,cAAc,mBAAmB;AAAA,MAC7D,aAAaA,EAAK,QAAQ,YAAY,EAAE;AAAA,MACxC,SAASA,EAAK,QAAQ,aAAa,SAAS;AAAA,IAAA,EAC5C,KAAK,GAAG,GACVy/B,EAAG,YAAYC,CAAG,GAClB5X,EAAM,YAAY2X,CAAE,GACpB,KAAK,YAAYA,GACjB,KAAK,iBAAiB,IAErBz/B,EAAK,aAAqB,OAAA;AAE3B,UAAM2/B,IAAS,CAACC,MAAkB;AAChC,UAAI,CAAC,KAAK,eAAgB;AAC1B,WAAK,iBAAiB;AACtB,YAAMC,KAAWH,EAAI,aAAa,IAAI,QAAQ,QAAQ,EAAE;AACxD,UAAI;AACF,QAAAD,EAAG,OAAA;AAAA,MACL,QAAQ;AAAA,MAER;AAGA,UAFA,KAAK,YAAY,MAChBz/B,EAAK,aAAqB,OAAA,GACvB4/B,KAAQC,OAAa7/B,EAAK,QAAQ,QAAQ,KAAK;AACjD,cAAM8/B,IAAM;AAAA,UACV,MAAM;AAAA,UACN,MAAM,EAAE,IAAI9/B,EAAK,IAAI,MAAM6/B,EAAA;AAAA,QAAQ,GAE/BvG,IAAQt5B,EAAK,OACb+/B,IAASzG,GAAO;AACtB,QAAIyG,GAAQ,UAKVA,EAAO,OAAOD,CAAG,GACb,OAAOxG,EAAM,aAAc,aAC7BA,EAAM,UAAU,qBAAqBwG,EAAI,IAAI,IAE7CC,EAAO,OAAOD,CAAG,KAIlB9/B,EAAa,UAAU6/B,CAAO;AAAA,MAEnC;AAAA,IACF;AAEA,IAAAH,EAAI,iBAAiB,WAAW,CAACnxB,MAAO;AACtC,MAAAA,EAAG,gBAAA,GACCA,EAAG,QAAQ,WAAW,CAACA,EAAG,YAC5BA,EAAG,eAAA,GACHoxB,EAAO,EAAI,KACFpxB,EAAG,QAAQ,aACpBA,EAAG,eAAA,GACHoxB,EAAO,EAAK;AAAA,IAEhB,CAAC,GACDD,EAAI,iBAAiB,QAAQ,MAAMC,EAAO,EAAI,CAAC,GAG/C,WAAW,MAAM;AACf,UAAI;AACF,QAAAD,EAAI,MAAA;AACJ,cAAMM,IAAQ,SAAS,YAAA;AACvB,QAAAA,EAAM,mBAAmBN,CAAG;AAC5B,cAAMO,IAAM,OAAO,aAAA;AACnB,QAAAA,GAAK,gBAAA,GACLA,GAAK,SAASD,CAAK;AAAA,MACrB,QAAQ;AAAA,MAER;AAAA,IACF,GAAG,CAAC;AAAA,EACN;AAAA;AAAA,EAGO,eAAqB;AAC1B,QAAK,KAAK,gBACV;AAAA,WAAK,iBAAiB;AACtB,UAAI;AACF,aAAK,WAAW,OAAA;AAAA,MAClB,QAAQ;AAAA,MAER;AACA,WAAK,YAAY,MAChB,KAAK,MAAM,aAAqB,OAAA;AAAA;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAa,IACXrvB,GACAiQ,GACAge,GACAsB,GACAne,GACAoe,GACAC,GACe;AAEf,IAAIzvB,MAAS,WAAW,KAAK,KAAK,QAAQ,OAAOA,IAC7CiQ,MAAa,WAAW,KAAK,KAAK,QAAQ,WAAWA,IACrDsf,MAAc,WAAW,KAAK,KAAK,QAAQ,YAAYA,IACvDne,MAAY,WAAW,KAAK,KAAK,QAAQ,cAAcA,IACvDoe,MAAe,WAAW,KAAK,KAAK,QAAQ,aAAaA,IACzDC,MAAe,WAAW,KAAK,KAAK,QAAQ,aAAaA,IAGzDxB,MAAe,UAAaA,MAAe,KAAK,KAAK,QAAQ,eAC/D,KAAK,KAAK,QAAQ,aAAaA,GAC/B,MAAMD,GAASC,CAAU,IAI3B,KAAK,UAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA,EAKO,MAQL;AACA,WAAO;AAAA,MACL,MAAM,KAAK,KAAK,QAAQ,QAAQ;AAAA,MAChC,UAAU,KAAK,KAAK,QAAQ,YAAY;AAAA,MACxC,YAAY,KAAK,KAAK,QAAQ,cAAc;AAAA,MAC5C,WAAW,KAAK,KAAK,QAAQ,aAAa;AAAA,MAC1C,aAAa,KAAK,KAAK,QAAQ,eAAe;AAAA,MAC9C,YAAY,KAAK,KAAK,QAAQ,cAAc;AAAA,MAC5C,YAAY,KAAK,KAAK,QAAQ,cAAc;AAAA,IAAA;AAAA,EAEhD;AAAA;AAAA;AAAA;AAAA,EAKO,sBAAgD;AACrD,QAAI,CAAC,KAAK,KAAK;AACb,aAAO,EAAE,GAAG,GAAG,GAAG,EAAA;AAGpB,QAAI;AACF,YAAMyB,IAAW,KAAK,KAAK,YAAY,KAAA,GACjCC,IAAY,KAAK,KAAK,QAAQ,SAAS,KACvCC,IAAa,KAAK,KAAK,QAAQ,UAAU;AAE/C,aAAO;AAAA,QACL,IAAID,IAAYD,EAAS,SAAS;AAAA,QAClC,IAAIE,IAAaF,EAAS,UAAU;AAAA,MAAA;AAAA,IAExC,QAAQ;AACN,aAAO,EAAE,GAAG,GAAG,GAAG,EAAA;AAAA,IACpB;AAAA,EACF;AAAA;AAAA,EAIQ,YAAkB;AAExB,QAAI,CAAC,KAAK,KAAK,YAAa;AAE5B,UAAM,EAAE,MAAA1vB,GAAM,UAAAiQ,GAAU,YAAAge,GAAY,WAAAsB,GAAW,aAAAM,EAAA,IAC7C,KAAK,KAAK;AAGZ,SAAK,KAAK,YAAY,KAAK7vB,KAAQ,EAAE,GAGrC,KAAK,KAAK,YAAY,KAAK;AAAA,MACzB,QAAQiuB,KAAc;AAAA,MACtB,MAAMhe,KAAY;AAAA,MAClB,MAAMsf,KAAa;AAAA,MACnB,SAASM,KAAe;AAAA,IAAA,CACzB,GAGG,OAAO,KAAK,KAAK,cAAe,cAClC,KAAK,KAAK,WAAA,GAIR,KAAK,KAAK,OAAO,SAAS,8BAC5B,KAAK,WAAA;AAAA,EAET;AAAA,EAEQ,aAAmB;AACzB,QAAK,KAAK,KAAK;AAEf,UAAI;AACF,cAAMH,IAAW,KAAK,KAAK,YAAY,KAAA,GACjCI,IAAU,IAEVC,IAAWL,EAAS,QAAQI,IAAU,GACtCE,IAAYN,EAAS,SAASI,IAAU,GAExCG,IAAe,KAAK,KAAK,QAAQ,SAAS,KAC1CC,IAAgB,KAAK,KAAK,QAAQ,UAAU;AAGlD,YAAIH,IAAWE,KAAgBD,IAAYE,GAAe;AACxD,gBAAMC,IAAW,KAAK,IAAIF,GAAcF,CAAQ,GAC1CK,IAAY,KAAK,IAAIF,GAAeF,CAAS;AACnD,eAAK,KAAK,QAAQG,GAAUC,CAAS;AAAA,QACvC;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,EACF;AACF;AChSO,MAAMC,GAAM;AAAA,EAIjB,YAAYhhC,GAAY;AAFxB,SAAQ,WAAmC,MAGzC,KAAK,OAAOA,GAGRA,EAAK,QAAQ,MAAM,SACrB,KAAK,WAAW,EAAE,GAAGA,EAAK,QAAQ,KAAA;AAAA,EAEtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,IAAIihC,GAA8BC,IAAsB,IAAY;AACzE,SAAK,WAAW;AAAA,MACd,MAAM;AAAA,MACN,GAAGD;AAAA,IAAA,GAIL,KAAK,KAAK,QAAQ,OAAO,EAAE,GAAG,KAAK,SAAA,GAGnC,KAAK,KAAK,sBAAA,GAEV,QAAQ,IAAI,4BAA4B,KAAK,KAAK,IAAI,KAAK,QAAQ,GAG/DC,KAAc,KAAK,KAAK,OAAO,QAAQ,uBACzC,KAAK,KAAK,MAAM,OAAO,KAAK;AAAA,MAC1B,MAAM;AAAA,MACN,MAAM;AAAA,QACJ,IAAI,KAAK,KAAK;AAAA,QACd,MAAM,KAAK;AAAA,MAAA;AAAA,IACb,CACD;AAAA,EAEL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,MAAMA,IAAsB,IAAY;AAC7C,SAAK,WAAW,MAChB,KAAK,KAAK,QAAQ,OAAO,QAGzB,KAAK,KAAK,sBAAA,GAEV,QAAQ,IAAI,kCAAkC,KAAK,KAAK,EAAE,GAGtDA,KAAc,KAAK,KAAK,OAAO,QAAQ,uBACzC,KAAK,KAAK,MAAM,OAAO,KAAK;AAAA,MAC1B,MAAM;AAAA,MACN,MAAM,EAAE,IAAI,KAAK,KAAK,GAAA;AAAA,IAAG,CAC1B;AAAA,EAEL;AAAA;AAAA,EAGO,MAA8B;AACnC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGO,UAAmB;AACxB,WAAO,KAAK,UAAU,SAAS;AAAA,EACjC;AAAA;AAAA,EAGO,UAA8B;AACnC,WAAO,KAAK,UAAU;AAAA,EACxB;AAAA;AAAA,EAGO,WAAiB;AACtB,QAAK,KAAK;AAEV,cAAQ,KAAK,SAAS,MAAA;AAAA,QACpB,KAAK;AACH,UAAI,KAAK,SAAS,QAAQ,OAAO,SAAW,OAC1C,OAAO,KAAK,KAAK,SAAS,MAAM,QAAQ;AAE1C;AAAA,QACF,KAAK;AAAA,QACL,KAAK;AAEH,kBAAQ;AAAA,YACN;AAAA,YACA,KAAK,SAAS;AAAA,UAAA;AAEhB;AAAA,MAAA;AAAA,EAEN;AAAA;AAAA,EAGO,UAAgB;AACrB,IAAI,KAAK,YACP,KAAK,MAAM,EAAK,GAElB,KAAK,WAAW,MACf,KAAa,OAAO;AAAA,EACvB;AACF;ACzGA,MAAMC,KAAS;AAAA,uCAGTC,KAAe,IAAI;AAAA,EACvB,WAAWD,EAAM,wCAAwCA,EAAM,QAAQA,EAAM;AAAA,EAC7E;AACF,GACME,KAAc,IAAI;AAAA,EACtB,qCAAqCF,EAAM,QAAQA,EAAM;AAAA,EACzD;AACF,GACMG,KAAoB,IAAI;AAAA,EAC5B,YAAYH,EAAM,wCAAwCA,EAAM,QAAQA,EAAM;AAAA,EAC9E;AACF;AAGO,SAASI,GAAgBC,GAA2C;AACzE,MAAI,CAACA,EAAY,QAAO,CAAA;AACxB,MAAI,MAAM,QAAQA,CAAU,EAAG,QAAOA;AAEtC,QAAMC,IAAsC;AAAA,IAC1C,GAAG;AAAA,IAAG,GAAG;AAAA,IAAG,GAAG;AAAA,IAAG,GAAG;AAAA,IAAG,GAAG;AAAA,IAAG,GAAG;AAAA,IAAG,GAAG;AAAA,IAAG,GAAG;AAAA,IAAG,GAAG;AAAA,IAAG,GAAG;AAAA,IAAG,GAAG;AAAA,EAAA,GAE3D7iC,IAAkB,CAAA;AAExB,gBAAO4iC,CAAU,EAAE;AAAA,IACjBJ;AAAA,IACA,CAAC57B,GAAYjB,GAAW3B,MAAc;AACpC,YAAM4B,IAAmB,CAAA;AACzB,UAAIjI,IAAOgI,EAAE,YAAA;AAUb,UATA3B,EAAE,QAAQy+B,IAAa,CAACK,GAAcC,OAChCA,KAAOn9B,EAAO,KAAK,CAACm9B,CAAK,GACtB,GACR,GACGplC,MAAS,OAAOiI,EAAO,SAAS,MAClC5F,EAAK,KAAK,CAAC2F,GAAG,GAAGC,EAAO,OAAO,GAAG,CAAC,CAAC,CAAgB,GACpDjI,IAAO,KACPgI,IAAIA,MAAM,MAAM,MAAM,MAEpBhI,MAAS;AACX,QAAAqC,EAAK,KAAK,CAAC2F,GAAG,GAAGC,CAAM,CAAgB;AAAA;AAEvC,eAAOA,EAAO,UAAUi9B,EAAYllC,CAAI,MACtCqC,EAAK,KAAK,CAAC2F,GAAG,GAAGC,EAAO,OAAO,GAAGi9B,EAAYllC,CAAI,CAAC,CAAC,CAAgB,GAChE,EAACklC,EAAYllC,CAAI;AAArB;AAGJ,aAAO;AAAA,IACT;AAAA,EAAA,GAEKqC;AACT;AAGO,SAASgjC,GAAetf,GAA0C;AACvE,QAAMuf,IAAUN,GAAgBjf,CAAgB;AAChD,MAAI,CAACuf,EAAQ,OAAQ,QAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;AAExC,QAAMC,IAAiB,CAAA;AACvB,MAAIvjC,IAAI,GAAGC,IAAI,GAAGkI,IAAK,GAAGq7B,IAAK,GAAG5nB,IAAQ;AAE1C,EAAI0nB,EAAQ,CAAC,EAAE,CAAC,MAAM,QACpBtjC,IAAI,CAACsjC,EAAQ,CAAC,EAAE,CAAC,GACjBrjC,IAAI,CAACqjC,EAAQ,CAAC,EAAE,CAAC,GACjBn7B,IAAKnI,GACLwjC,IAAKvjC,GACL2b,KACA2nB,EAAI,CAAC,IAAI,CAAC,KAAKvjC,GAAGC,CAAC;AAGrB,WAASvB,IAAIkd,GAAOld,IAAI4kC,EAAQ,QAAQ5kC,KAAK;AAC3C,UAAMyG,IAAiB,CAAC,EAAE,GACpBs+B,IAAKH,EAAQ5kC,CAAC;AAEpB,QADA6kC,EAAI,KAAKp+B,CAAC,GACNs+B,EAAG,CAAC,MAAMA,EAAG,CAAC,EAAE;AAElB,cADAt+B,EAAE,CAAC,IAAIs+B,EAAG,CAAC,EAAE,YAAA,GACLt+B,EAAE,CAAC,GAAA;AAAA,QACT,KAAK;AACH,UAAAA,EAAE,CAAC,IAAIs+B,EAAG,CAAC,GAAat+B,EAAE,CAAC,IAAIs+B,EAAG,CAAC,GAAat+B,EAAE,CAAC,IAAIs+B,EAAG,CAAC,GAC3Dt+B,EAAE,CAAC,IAAIs+B,EAAG,CAAC,GAAat+B,EAAE,CAAC,IAAIs+B,EAAG,CAAC,GACnCt+B,EAAE,CAAC,IAAI,CAAEs+B,EAAG,CAAC,IAAezjC,GAAGmF,EAAE,CAAC,IAAI,CAAEs+B,EAAG,CAAC,IAAexjC;AAC3D;AAAA,QACF,KAAK;AACH,UAAAkF,EAAE,CAAC,IAAI,CAACs+B,EAAG,CAAC,IAAIxjC;AAChB;AAAA,QACF,KAAK;AACH,UAAAkF,EAAE,CAAC,IAAI,CAACs+B,EAAG,CAAC,IAAIzjC;AAChB;AAAA,QACF,KAAK;AACH,UAAAmI,IAAK,CAACs7B,EAAG,CAAC,IAAIzjC,GACdwjC,IAAK,CAACC,EAAG,CAAC,IAAIxjC,GACdkF,EAAE,CAAC,IAAIgD,GAAIhD,EAAE,CAAC,IAAIq+B;AAClB;AAAA,QACF;AACE,mBAASnzB,IAAI,GAAGA,IAAIozB,EAAG,QAAQpzB;AAC7B,YAAAlL,EAAEkL,CAAC,IAAI,CAAEozB,EAAGpzB,CAAC,KAAgBA,IAAI,IAAIrQ,IAAIC;AAAA,MAC3C;AAAA;AAGJ,eAASoF,IAAI,GAAGA,IAAIo+B,EAAG,QAAQp+B,IAAK,CAAAF,EAAEE,CAAC,IAAIo+B,EAAGp+B,CAAC;AAEjD,YAAQF,EAAE,CAAC,GAAA;AAAA,MACT,KAAK;AACH,QAAAnF,IAAImI,GAAIlI,IAAIujC;AACZ;AAAA,MACF,KAAK;AACH,QAAAxjC,IAAImF,EAAE,CAAC;AACP;AAAA,MACF,KAAK;AACH,QAAAlF,IAAIkF,EAAE,CAAC;AACP;AAAA,MACF,KAAK;AACH,QAAAgD,IAAKhD,EAAEA,EAAE,SAAS,CAAC,GACnBq+B,IAAKr+B,EAAEA,EAAE,SAAS,CAAC,GACnBnF,IAAImF,EAAEA,EAAE,SAAS,CAAC,GAClBlF,IAAIkF,EAAEA,EAAE,SAAS,CAAC;AAClB;AAAA,MACF;AACE,QAAAnF,IAAImF,EAAEA,EAAE,SAAS,CAAC,GAClBlF,IAAIkF,EAAEA,EAAE,SAAS,CAAC;AAAA,IAAA;AAAA,EAExB;AACA,SAAOo+B;AACT;AAIA,SAASG,GAAInuB,GAAYC,GAAYC,GAAYC,GAAsB;AACrE,SAAO,CAACH,GAAIC,GAAIC,GAAIC,GAAID,GAAIC,CAAE;AAChC;AAEA,SAASiuB,GAAIpuB,GAAYC,GAAYoM,GAAYC,GAAYpM,GAAYC,GAAsB;AAC7F,QAAMkuB,IAAM,oBAAOC,IAAM,IAAI;AAC7B,SAAO;AAAA,IACLD,IAAMruB,IAAKsuB,IAAMjiB;AAAA,IAAIgiB,IAAMpuB,IAAKquB,IAAMhiB;AAAA,IACtC+hB,IAAMnuB,IAAKouB,IAAMjiB;AAAA,IAAIgiB,IAAMluB,IAAKmuB,IAAMhiB;AAAA,IACtCpM;AAAA,IAAIC;AAAA,EAAA;AAER;AAEA,SAASiW,GAAO3rB,GAAWC,GAAWk9B,GAAuC;AAC3E,SAAO,EAAE,GAAGn9B,IAAI,KAAK,IAAIm9B,CAAG,IAAIl9B,IAAI,KAAK,IAAIk9B,CAAG,GAAG,GAAGn9B,IAAI,KAAK,IAAIm9B,CAAG,IAAIl9B,IAAI,KAAK,IAAIk9B,CAAG,EAAA;AAC5F;AAEA,SAAS2G,GACPvuB,GAAYC,GAAY1K,GAAYC,GAAYkI,GAChD8wB,GAAsBC,GAAmBvuB,GAAYC,GACrDuuB,GACU;AACV,QAAMC,IAAQ,KAAK,KAAK,MAAO,KACzB/G,IAAO,KAAK,KAAK,OAAQ,CAAClqB,KAAS;AACzC,MAAIswB,IAAgB,CAAA,GAChBY,GACAC,IAAK,GAAGC,IAAK,GAAGn5B,IAAK,GAAGC,IAAK;AAEjC,MAAK84B;AA6BH,IAAAG,IAAKH,EAAU,CAAC,GAAGI,IAAKJ,EAAU,CAAC,GAAG/4B,IAAK+4B,EAAU,CAAC,GAAG94B,IAAK84B,EAAU,CAAC;AAAA,OA7B3D;AACd,IAAAE,IAAKxY,GAAOpW,GAAIC,GAAI,CAAC2nB,CAAG,GACxB5nB,IAAK4uB,EAAG,GAAG3uB,IAAK2uB,EAAG,GACnBA,IAAKxY,GAAOlW,GAAIC,GAAI,CAACynB,CAAG,GACxB1nB,IAAK0uB,EAAG,GAAGzuB,IAAKyuB,EAAG;AACnB,UAAMnkC,KAAKuV,IAAKE,KAAM,GAChBxV,KAAKuV,IAAKE,KAAM;AACtB,QAAI3O,IAAK/G,IAAIA,KAAM8K,IAAKA,KAAO7K,IAAIA,KAAM8K,IAAKA;AAC9C,IAAIhE,IAAI,MACNA,IAAI,KAAK,KAAKA,CAAC,GACf+D,IAAK/D,IAAI+D,GACTC,IAAKhE,IAAIgE;AAEX,UAAMu5B,KAAMx5B,IAAKA,GAAIy5B,KAAMx5B,IAAKA,GAC1B1F,MACH0+B,MAAiBC,IAAY,KAAK,KACnC,KAAK,KAAK,KAAK,KAAKM,KAAMC,KAAMD,KAAMrkC,IAAIA,IAAIskC,KAAMvkC,IAAIA,MAAMskC,KAAMrkC,IAAIA,IAAIskC,KAAMvkC,IAAIA,EAAE,CAAC;AAC3F,IAAAkL,IAAM7F,KAAIyF,IAAK7K,IAAK8K,KAAMwK,IAAKE,KAAM,GACrCtK,IAAM9F,KAAI,CAAC0F,IAAK/K,IAAK8K,KAAM0K,IAAKE,KAAM,GACtC0uB,IAAK,KAAK,KAAK,SAAS5uB,IAAKrK,KAAMJ,GAAI,QAAQ,CAAC,CAAC,CAAC,GAClDs5B,IAAK,KAAK,KAAK,SAAS3uB,IAAKvK,KAAMJ,GAAI,QAAQ,CAAC,CAAC,CAAC,GAElDq5B,IAAK7uB,IAAKrK,IAAK,KAAK,KAAKk5B,IAAKA,GAC9BC,IAAK5uB,IAAKvK,IAAK,KAAK,KAAKm5B,IAAKA,GAC1BD,IAAK,MAAGA,IAAK,KAAK,KAAK,IAAIA,IAC3BC,IAAK,MAAGA,IAAK,KAAK,KAAK,IAAIA,IAC3BL,KAAaI,IAAKC,MAAID,KAAM,KAAK,KAAK,IACtC,CAACJ,KAAaK,IAAKD,MAAIC,KAAM,KAAK,KAAK;AAAA,EAC7C;AAIA,MAAIG,IAAKH,IAAKD;AACd,MAAI,KAAK,IAAII,CAAE,IAAIN,GAAM;AACvB,UAAMO,IAAQJ,GAAIK,IAAQjvB,GAAIkvB,IAAQjvB;AACtC,IAAA2uB,IAAKD,IAAKF,KAAQF,KAAaK,IAAKD,IAAK,IAAI,KAC7C3uB,IAAKvK,IAAKJ,IAAK,KAAK,IAAIu5B,CAAE,GAC1B3uB,IAAKvK,IAAKJ,IAAK,KAAK,IAAIs5B,CAAE,GAC1Bd,IAAMO,GAAIruB,GAAIC,GAAI5K,GAAIC,GAAIkI,GAAO,GAAG+wB,GAAWU,GAAOC,GAAO,CAACN,GAAII,GAAOv5B,GAAIC,CAAE,CAAC;AAAA,EAClF;AACA,EAAAq5B,IAAKH,IAAKD;AAEV,QAAMQ,IAAK,KAAK,IAAIR,CAAE,GAAGS,IAAK,KAAK,IAAIT,CAAE,GACnCU,IAAK,KAAK,IAAIT,CAAE,GAAGU,IAAK,KAAK,IAAIV,CAAE,GACnCz/B,IAAI,KAAK,IAAI4/B,IAAK,CAAC,GACnBQ,IAAM,IAAI,IAAKl6B,IAAKlG,GACpBqgC,IAAM,IAAI,IAAKl6B,IAAKnG,GACpBsgC,IAAK,CAAC3vB,GAAIC,CAAE,GACZ2vB,IAAK,CAAC5vB,IAAKyvB,IAAKH,GAAIrvB,IAAKyvB,IAAKL,CAAE,GAChCQ,IAAK,CAAC3vB,IAAKuvB,IAAKD,GAAIrvB,IAAKuvB,IAAKH,CAAE,GAChCO,IAAK,CAAC5vB,GAAIC,CAAE;AAIlB,MAHAyvB,EAAG,CAAC,IAAI,IAAID,EAAG,CAAC,IAAIC,EAAG,CAAC,GACxBA,EAAG,CAAC,IAAI,IAAID,EAAG,CAAC,IAAIC,EAAG,CAAC,GAEpBlB;AACF,WAAO,CAACkB,EAAG,CAAC,GAAGA,EAAG,CAAC,GAAGC,EAAG,CAAC,GAAGA,EAAG,CAAC,GAAGC,EAAG,CAAC,GAAGA,EAAG,CAAC,CAAC,EAAE,OAAO9B,CAAG;AAE9D,EAAAA,IAAM,CAAC4B,EAAG,CAAC,GAAGA,EAAG,CAAC,GAAGC,EAAG,CAAC,GAAGA,EAAG,CAAC,GAAGC,EAAG,CAAC,GAAGA,EAAG,CAAC,CAAC,EAAE,OAAO9B,CAAG;AAC3D,QAAM+B,IAAmB,CAAA;AACzB,WAAS5mC,IAAI,GAAGA,IAAI6kC,EAAI,QAAQ7kC;AAC9B,IAAA4mC,EAAO5mC,CAAC,IACNA,IAAI,IACAitB,GAAO4X,EAAI7kC,IAAI,CAAC,GAAG6kC,EAAI7kC,CAAC,GAAGy+B,CAAG,EAAE,IAChCxR,GAAO4X,EAAI7kC,CAAC,GAAG6kC,EAAI7kC,IAAI,CAAC,GAAGy+B,CAAG,EAAE;AAExC,SAAOmI;AACT;AAGO,SAASC,GAAWp4B,GAAqC;AAC9D,QAAM/G,IAAIi9B,GAAel2B,CAAI,GACvByB,IAAQ,EAAE,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,MAAuB,IAAI,KAAA,GAE/E42B,IAAc,CAACC,GAAkB1mC,GAAiB2mC,MAA8B;AAEpF,QAAI,CAACD,EAAK,QAAO,CAAC,KAAK1mC,EAAE,GAAGA,EAAE,GAAGA,EAAE,GAAGA,EAAE,GAAGA,EAAE,GAAGA,EAAE,CAAC;AAKnD,YAJI0mC,EAAI,CAAC,MAAM,OAAOA,EAAI,CAAC,MAAM,QAC/B1mC,EAAE,KAAK,MACPA,EAAE,KAAK,OAED0mC,EAAI,CAAC,GAAA;AAAA,MACX,KAAK;AACH,QAAA1mC,EAAE,IAAI0mC,EAAI,CAAC,GACX1mC,EAAE,IAAI0mC,EAAI,CAAC;AACX;AAAA,MACF,KAAK;AACH,eAAO,CAAC,KAAK,GAAG3B,GAAI/kC,EAAE,GAAGA,EAAE,GAAG,GAAI0mC,EAAI,MAAM,CAAC,CAA0E,CAAC;AAAA,MAC1H,KAAK,KAAK;AACR,YAAIv6B,GAAYC;AAChB,eAAIu6B,MAAS,OAAOA,MAAS,OAC3Bx6B,IAAKnM,EAAE,IAAI,IAAIA,EAAE,IACjBoM,IAAKpM,EAAE,IAAI,IAAIA,EAAE,OAEjBmM,IAAKnM,EAAE,GACPoM,IAAKpM,EAAE,IAEF,CAAC,KAAKmM,GAAIC,GAAI,GAAIs6B,EAAI,MAAM,CAAC,CAAc;AAAA,MACpD;AAAA,MACA,KAAK;AACH,eAAIC,MAAS,OAAOA,MAAS,OAC3B3mC,EAAE,KAAKA,EAAE,IAAI,IAAKA,EAAE,IACpBA,EAAE,KAAKA,EAAE,IAAI,IAAKA,EAAE,OAEpBA,EAAE,KAAKA,EAAE,GACTA,EAAE,KAAKA,EAAE,IAEJ,CAAC,KAAK,GAAG4kC,GAAI5kC,EAAE,GAAGA,EAAE,GAAGA,EAAE,IAAKA,EAAE,IAAK0mC,EAAI,CAAC,GAAaA,EAAI,CAAC,CAAW,CAAC;AAAA,MACjF,KAAK;AACH,eAAA1mC,EAAE,KAAK0mC,EAAI,CAAC,GACZ1mC,EAAE,KAAK0mC,EAAI,CAAC,GACL,CAAC,KAAK,GAAG9B,GAAI5kC,EAAE,GAAGA,EAAE,GAAG0mC,EAAI,CAAC,GAAaA,EAAI,CAAC,GAAaA,EAAI,CAAC,GAAaA,EAAI,CAAC,CAAW,CAAC;AAAA,MACvG,KAAK;AACH,eAAO,CAAC,KAAK,GAAG/B,GAAI3kC,EAAE,GAAGA,EAAE,GAAG0mC,EAAI,CAAC,GAAaA,EAAI,CAAC,CAAW,CAAC;AAAA,MACnE,KAAK;AACH,eAAO,CAAC,KAAK,GAAG/B,GAAI3kC,EAAE,GAAGA,EAAE,GAAG0mC,EAAI,CAAC,GAAa1mC,EAAE,CAAC,CAAC;AAAA,MACtD,KAAK;AACH,eAAO,CAAC,KAAK,GAAG2kC,GAAI3kC,EAAE,GAAGA,EAAE,GAAGA,EAAE,GAAG0mC,EAAI,CAAC,CAAW,CAAC;AAAA,MACtD,KAAK;AACH,eAAO,CAAC,KAAK,GAAG/B,GAAI3kC,EAAE,GAAGA,EAAE,GAAGA,EAAE,GAAGA,EAAE,CAAC,CAAC;AAAA,IAAA;AAE3C,WAAO0mC;AAAA,EACT,GAEME,IAAS,CAACC,GAAelnC,GAAWmnC,MAAoB;AAC5D,QAAID,EAAGlnC,CAAC,EAAE,SAAS,GAAG;AACpB,MAAAknC,EAAGlnC,CAAC,EAAE,MAAA;AACN,YAAMmI,IAAK++B,EAAGlnC,CAAC;AACf,aAAOmI,EAAG;AACRg/B,QAAAA,EAAMnnC,CAAC,IAAI,KACXknC,EAAG,OAAOlnC,KAAK,GAAG,CAAC,KAAK,GAAGmI,EAAG,OAAO,GAAG,CAAC,CAAC,CAAgB;AAE5D,MAAA++B,EAAG,OAAOlnC,GAAG,CAAC;AAAA,IAChB;AAAA,EACF,GAEMmnC,IAAkB,CAAA;AACxB,MAAIC,IAAS,IACTJ,IAAO;AAEX,WAAShnC,IAAI,GAAGA,IAAI0H,EAAE,QAAQ1H,KAAK;AACjC,IAAAonC,IAAS,IACL1/B,EAAE1H,CAAC,UAAY0H,EAAE1H,CAAC,EAAE,CAAC,IACrBonC,MAAW,QACbD,EAAMnnC,CAAC,IAAIonC,GACPpnC,MAAGgnC,IAAOG,EAAMnnC,IAAI,CAAC,KAE3B0H,EAAE1H,CAAC,IAAI8mC,EAAYp/B,EAAE1H,CAAC,GAAGkQ,GAAO82B,CAAI,GAChCG,EAAMnnC,CAAC,MAAM,OAAOonC,MAAW,QAAKD,EAAMnnC,CAAC,IAAI,MACnDinC,EAAOv/B,GAAG1H,GAAGmnC,CAAK;AAElB,UAAMJ,IAAMr/B,EAAE1H,CAAC,GACTqnC,IAASN,EAAI;AACnB,IAAA72B,EAAM,IAAI62B,EAAIM,IAAS,CAAC,GACxBn3B,EAAM,IAAI62B,EAAIM,IAAS,CAAC,GACxBn3B,EAAM,KAAK,WAAW62B,EAAIM,IAAS,CAAC,CAAQ,KAAKn3B,EAAM,GACvDA,EAAM,KAAK,WAAW62B,EAAIM,IAAS,CAAC,CAAQ,KAAKn3B,EAAM;AAAA,EACzD;AACA,SAAOxI;AACT;AAIA,SAAS4/B,GACPC,GAAaC,GAAaC,GAAaC,GACvCC,GAAaC,GAAaC,GAAaC,GACvC;AACA,QAAMC,IAAM,CAAC7hC,GAAW8hC,GAAYC,GAAYC,GAAYC,MAAe;AACzE,UAAMC,IAAK,IAAIliC;AACf,WAAOkiC,IAAKA,IAAKA,IAAKJ,IAAK,IAAII,IAAKA,IAAKliC,IAAI+hC,IAAK,IAAIG,IAAKliC,IAAIA,IAAIgiC,IAAKhiC,IAAIA,IAAIA,IAAIiiC;AAAA,EACtF,GAEME,IAAK,CAACd,GAAKM,CAAG,GACdS,IAAK,CAACd,GAAKM,CAAG,GAEdS,IAAQ,CAAC/jB,GAAWgkB,GAAWC,MAAwB;AAC3D,UAAMC,IAAgB,CAAA;AACtB,QAAI,KAAK,IAAIlkB,CAAC,IAAI;AAChB,UAAI,KAAK,IAAIgkB,CAAC,IAAI,OAAO;AACvB,cAAMtiC,IAAI,CAACuiC,IAAID;AACf,QAAItiC,IAAI,KAAKA,IAAI,KAAGwiC,EAAI,KAAKxiC,CAAC;AAAA,MAChC;AAAA,WACK;AACL,YAAMyiC,IAAOH,IAAIA,IAAI,IAAIhkB,IAAIikB;AAC7B,UAAIE,KAAQ,GAAG;AACb,cAAMC,IAAK,KAAK,KAAKD,CAAI,GACnBE,KAAM,CAACL,IAAII,MAAO,IAAIpkB,IACtBskB,KAAM,CAACN,IAAII,MAAO,IAAIpkB;AAC5B,QAAIqkB,IAAK,KAAKA,IAAK,KAAGH,EAAI,KAAKG,CAAE,GAC7BC,IAAK,KAAKA,IAAK,KAAGJ,EAAI,KAAKI,CAAE;AAAA,MACnC;AAAA,IACF;AACA,WAAOJ;AAAA,EACT,GAGMK,IAAS,CAACf,GAAYC,GAAYC,GAAYC,MAAyB;AAC3E,UAAM3jB,IAAI,KAAK2jB,IAAK,IAAID,IAAK,IAAID,IAAKD,IAChCQ,IAAI,KAAKN,IAAK,IAAID,IAAKD,IACvBS,IAAI,KAAKR,IAAKD;AACpB,WAAOO,EAAM/jB,GAAGgkB,GAAGC,CAAC;AAAA,EACtB;AAEA,SAAAM,EAAOxB,GAAKE,GAAKE,GAAKE,CAAG,EAAE,QAAQ,CAAC3hC,MAAMmiC,EAAG,KAAKN,EAAI7hC,GAAGqhC,GAAKE,GAAKE,GAAKE,CAAG,CAAC,CAAC,GAC7EkB,EAAOvB,GAAKE,GAAKE,GAAKE,CAAG,EAAE,QAAQ,CAAC5hC,MAAMoiC,EAAG,KAAKP,EAAI7hC,GAAGshC,GAAKE,GAAKE,GAAKE,CAAG,CAAC,CAAC,GAEtE;AAAA,IACL,KAAK,EAAE,GAAG,KAAK,IAAI,GAAGO,CAAE,GAAG,GAAG,KAAK,IAAI,GAAGC,CAAE,EAAA;AAAA,IAC5C,KAAK,EAAE,GAAG,KAAK,IAAI,GAAGD,CAAE,GAAG,GAAG,KAAK,IAAI,GAAGC,CAAE,EAAA;AAAA,EAAE;AAElD;AAcO,SAASU,GAASv6B,GAAoC;AAC3D,QAAM/G,IAAIm/B,GAAWp4B,CAAI;AACzB,MAAI,CAAC/G,EAAE;AACL,WAAO,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,GAAG,QAAQ,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,EAAA;AAErE,MAAIpG,IAAI,GAAGC,IAAI;AACf,QAAM0nC,IAAc,CAAA,GACdC,IAAc,CAAA;AACpB,aAAWnC,KAAOr/B;AAChB,QAAIq/B,EAAI,CAAC,MAAM;AACb,MAAAzlC,IAAIylC,EAAI,CAAC,GACTxlC,IAAIwlC,EAAI,CAAC,GACTkC,EAAE,KAAK3nC,CAAC,GACR4nC,EAAE,KAAK3nC,CAAC;AAAA,SACH;AACL,YAAM4nC,IAAM7B,GAAShmC,GAAGC,GAAG,GAAIwlC,EAAI,MAAM,CAAC,CAAkE;AAC5G,MAAAkC,EAAE,KAAKE,EAAI,IAAI,GAAGA,EAAI,IAAI,CAAC,GAC3BD,EAAE,KAAKC,EAAI,IAAI,GAAGA,EAAI,IAAI,CAAC,GAC3B7nC,IAAIylC,EAAI,CAAC,GACTxlC,IAAIwlC,EAAI,CAAC;AAAA,IACX;AAEF,QAAMqC,IAAO,KAAK,IAAI,GAAGH,CAAC,GACpBI,IAAO,KAAK,IAAI,GAAGH,CAAC,GACpBI,IAAO,KAAK,IAAI,GAAGL,CAAC,GACpBM,IAAO,KAAK,IAAI,GAAGL,CAAC,GACpBtoC,IAAQ0oC,IAAOF,GACfvoC,IAAS0oC,IAAOF;AACtB,SAAO;AAAA,IACL,GAAGD;AAAA,IAAM,GAAGC;AAAA,IAAM,IAAIC;AAAA,IAAM,IAAIC;AAAA,IAChC,OAAA3oC;AAAA,IAAO,QAAAC;AAAA,IACP,IAAIuoC,IAAOxoC,IAAQ;AAAA,IAAG,IAAIyoC,IAAOxoC,IAAS;AAAA,EAAA;AAE9C;AAKO,MAAMmK,GAAO;AAAA,EAGlB,YAAYzE,GAAYe,GAAY3B,GAAYtF,GAAYiM,GAAYC,GAAY;AAFpF,SAAA,IAAI,GAAG,KAAA,IAAI,GAAG,KAAA,IAAI,GAAG,KAAA,IAAI,GAAG,KAAA,IAAI,GAAG,KAAA,IAAI,GAGjChG,KAAK,SACP,KAAK,IAAI,CAACA,GAAG,KAAK,IAAI,CAACe,GAAI,KAAK,IAAI,CAAC3B,GACrC,KAAK,IAAI,CAACtF,GAAI,KAAK,IAAI,CAACiM,GAAI,KAAK,IAAI,CAACC;AAAA,EAE1C;AAAA,EAEA,IAAIhG,GAAWe,GAAW3B,GAAWtF,GAAWiM,GAAWC,GAAiB;AAC1E,UAAMhN,IAAgB;AAAA,MACpB,CAAC,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAAA,MACvB,CAAC,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAAA,MACvB,CAAC,GAAG,GAAG,CAAC;AAAA,IAAA,GAEJmN,IAAqB;AAAA,MACzB,CAACnG,GAAGZ,GAAG2G,CAAC;AAAA,MACR,CAAChF,GAAGjH,GAAGkM,CAAC;AAAA,MACR,CAAC,GAAG,GAAG,CAAC;AAAA,IAAA,GAEJm8B,IAAkB,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AACxD,aAASpnC,IAAI,GAAGA,IAAI,GAAGA;AACrB,eAASkoC,IAAK,GAAGA,IAAK,GAAGA,KAAM;AAC7B,YAAI3E,IAAM;AACV,iBAAS17B,IAAI,GAAGA,IAAI,GAAGA;AACrB,UAAA07B,KAAOtlC,EAAE+B,CAAC,EAAE6H,CAAC,IAAIuD,EAAOvD,CAAC,EAAEqgC,CAAE;AAE/B,QAAAd,EAAIpnC,CAAC,EAAEkoC,CAAE,IAAI3E;AAAA,MACf;AAEF,SAAK,IAAI6D,EAAI,CAAC,EAAE,CAAC,GAAG,KAAK,IAAIA,EAAI,CAAC,EAAE,CAAC,GAAG,KAAK,IAAIA,EAAI,CAAC,EAAE,CAAC,GACzD,KAAK,IAAIA,EAAI,CAAC,EAAE,CAAC,GAAG,KAAK,IAAIA,EAAI,CAAC,EAAE,CAAC,GAAG,KAAK,IAAIA,EAAI,CAAC,EAAE,CAAC;AAAA,EAC3D;AAAA,EAEA,UAAUpnC,GAAWC,GAAiB;AACpC,SAAK,IAAI,GAAG,GAAG,GAAG,GAAGD,GAAGC,CAAC;AAAA,EAC3B;AAAA,EAEA,MAAMD,GAAWC,GAAYiL,GAAaC,GAAmB;AAC3D,IAAIlL,KAAK,SAAMA,IAAID,KACfkL,KAAMC,MAAI,KAAK,IAAI,GAAG,GAAG,GAAG,GAAGD,KAAM,GAAGC,KAAM,CAAC,GACnD,KAAK,IAAInL,GAAG,GAAG,GAAGC,GAAG,GAAG,CAAC,IACrBiL,KAAMC,MAAI,KAAK,IAAI,GAAG,GAAG,GAAG,GAAG,EAAED,KAAM,IAAI,EAAEC,KAAM,EAAE;AAAA,EAC3D;AAAA,EAEA,OAAOlG,GAAWjF,GAAYC,GAAkB;AAC9C,IAAAgF,IAAKA,IAAI,KAAK,KAAM,KACpBjF,IAAIA,KAAK,GACTC,IAAIA,KAAK;AACT,UAAMyM,IAAM,CAAC,KAAK,IAAIzH,CAAC,EAAE,QAAQ,CAAC,GAC5B2B,IAAM,CAAC,KAAK,IAAI3B,CAAC,EAAE,QAAQ,CAAC;AAClC,SAAK,IAAIyH,GAAK9F,GAAK,CAACA,GAAK8F,GAAK1M,GAAGC,CAAC,GAClC,KAAK,IAAI,GAAG,GAAG,GAAG,GAAG,CAACD,GAAG,CAACC,CAAC;AAAA,EAC7B;AAAA,EAEA,EAAED,GAAWC,GAAmB;AAC9B,WAAOD,IAAI,KAAK,IAAIC,IAAI,KAAK,IAAI,KAAK;AAAA,EACxC;AAAA,EAEA,EAAED,GAAWC,GAAmB;AAC9B,WAAOD,IAAI,KAAK,IAAIC,IAAI,KAAK,IAAI,KAAK;AAAA,EACxC;AACF;AAGO,SAASkoC,GAAqBC,GAA6B;AAChE,MAAI,CAACA,EAAM,QAAO,CAAA;AAClB,MAAI,MAAM,QAAQA,CAAI,EAAG,QAAOA;AAChC,QAAM/nC,IAAc,CAAA;AACpB,gBAAO+nC,CAAI,EAAE,QAAQrF,IAAmB,CAACI,GAAcn9B,GAAW3B,MAAc;AAC9E,UAAM4B,IAAmB,CAAA;AACzB,WAAA5B,EAAE,QAAQy+B,IAAa,CAAC77B,GAAYm8B,OAC9BA,KAAOn9B,EAAO,KAAK,CAACm9B,CAAK,GACtB,GACR,GACD/iC,EAAK,KAAK,CAAC2F,GAAG,GAAGC,CAAM,CAAC,GACjB;AAAA,EACT,CAAC,GACM5F;AACT;AAQO,SAASgoC,GAAiBD,GAAct6B,GAAwB;AACrE,QAAMw6B,IAAQH,GAAqBC,CAAI,GACjCnqC,IAAI,IAAIyL,GAAA;AACd,aAAW9E,KAAK0jC,GAAO;AACrB,UAAMC,IAAO3jC,EAAE,QACToT,IAAU,OAAOpT,EAAE,CAAC,CAAC,EAAE,YAAA,GACvBu6B,IAAWv6B,EAAE,CAAC,MAAMoT,GACpBwwB,IAAQrJ,IAAW,IAAIz1B,GAAA,IAAW;AAExC,QAAIsO,MAAY,OAAOuwB,MAAS;AAC9B,UAAIpJ,GAAU;AACZ,cAAM5pB,IAAKizB,EAAO,EAAE,GAAG,CAAC,GAClBhzB,IAAKgzB,EAAO,EAAE,GAAG,CAAC;AACxB,QAAAvqC,EAAE,UAAU2G,EAAE,CAAC,IAAI2Q,GAAI3Q,EAAE,CAAC,IAAI4Q,CAAE;AAAA,MAClC;AACE,QAAAvX,EAAE,UAAU2G,EAAE,CAAC,GAAGA,EAAE,CAAC,CAAC;AAAA,aAEfoT,MAAY;AACrB,UAAIuwB,MAAS;AACX,QAAAtqC,EAAE,OAAO2G,EAAE,CAAC,GAAGkJ,EAAK,IAAIA,EAAK,QAAQ,GAAGA,EAAK,IAAIA,EAAK,SAAS,CAAC;AAAA,eACvDy6B,MAAS;AAClB,YAAIpJ,GAAU;AACZ,gBAAM1pB,IAAK+yB,EAAO,EAAE5jC,EAAE,CAAC,GAAGA,EAAE,CAAC,CAAC,GACxB8Q,IAAK8yB,EAAO,EAAE5jC,EAAE,CAAC,GAAGA,EAAE,CAAC,CAAC;AAC9B,UAAA3G,EAAE,OAAO2G,EAAE,CAAC,GAAG6Q,GAAIC,CAAE;AAAA,QACvB;AACE,UAAAzX,EAAE,OAAO2G,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAGA,EAAE,CAAC,CAAC;AAAA,eAGpBoT,MAAY;AACrB,UAAIuwB,MAAS,KAAKA,MAAS;AACzB,QAAAtqC,EAAE,MAAM2G,EAAE,CAAC,GAAGA,EAAE2jC,IAAO,CAAC,GAAGz6B,EAAK,IAAIA,EAAK,QAAQ,GAAGA,EAAK,IAAIA,EAAK,SAAS,CAAC;AAAA,eACnEy6B,MAAS;AAClB,YAAIpJ,GAAU;AACZ,gBAAM1pB,IAAK+yB,EAAO,EAAE5jC,EAAE,CAAC,GAAGA,EAAE,CAAC,CAAC,GACxB8Q,IAAK8yB,EAAO,EAAE5jC,EAAE,CAAC,GAAGA,EAAE,CAAC,CAAC;AAC9B,UAAA3G,EAAE,MAAM2G,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAG6Q,GAAIC,CAAE;AAAA,QAC5B;AACE,UAAAzX,EAAE,MAAM2G,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAGA,EAAE,CAAC,CAAC;AAAA,eAEvB2jC,MAAS;AAClB,YAAIpJ,GAAU;AACZ,gBAAM1pB,IAAK+yB,EAAO,EAAE5jC,EAAE,CAAC,GAAGA,EAAE,CAAC,CAAC,GACxB8Q,IAAK8yB,EAAO,EAAE5jC,EAAE,CAAC,GAAGA,EAAE,CAAC,CAAC;AAC9B,UAAA3G,EAAE,MAAM2G,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAG6Q,GAAIC,CAAE;AAAA,QAC5B;AACE,UAAAzX,EAAE,MAAM2G,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAGA,EAAE,CAAC,CAAC;AAAA,UAGpC,CAAWoT,MAAY,OAAOuwB,MAAS,KACrCtqC,EAAE,IAAI2G,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAGA,EAAE,CAAC,GAAGA,EAAE,CAAC,CAAC;AAAA,EAE5C;AACA,SAAO3G;AACT;AAGO,SAASwqC,GAAQt7B,GAAiB/B,GAA2B;AAClE,MAAI,CAACA,KAAU,CAAC+B,EAAM,QAAOA;AAC7B,QAAMo2B,IAAiB,CAAA;AACvB,WAAS7kC,IAAI,GAAGA,IAAIyO,EAAK,QAAQzO,KAAK;AACpC,UAAM+mC,IAAMt4B,EAAKzO,CAAC,GACZ0oC,IAAmB,CAAC3B,EAAI,CAAC,CAAC;AAChC,aAASp1B,IAAI,GAAGA,IAAIo1B,EAAI,QAAQp1B,KAAK,GAAG;AACtC,YAAMrQ,IAAIoL,EAAO,EAAEq6B,EAAIp1B,CAAC,GAAao1B,EAAIp1B,IAAI,CAAC,CAAW,GACnDpQ,IAAImL,EAAO,EAAEq6B,EAAIp1B,CAAC,GAAao1B,EAAIp1B,IAAI,CAAC,CAAW;AACzD,MAAA+2B,EAAI/2B,CAAC,IAAIrQ,GACTonC,EAAI/2B,IAAI,CAAC,IAAIpQ;AAAA,IACf;AACA,IAAAsjC,EAAI,KAAK6D,CAAG;AAAA,EACd;AACA,SAAO7D;AACT;AAMO,SAASmF,GAAcv7B,GAAci7B,GAAsB;AAChE,QAAMO,IAASpD,GAAWp4B,CAAI,GACxBW,IAAO45B,GAASiB,CAAM,GACtBv9B,IAASi9B,GAAiBD,GAAMt6B,CAAI;AAC1C,SAAO26B,GAAQE,GAAQv9B,CAAM,EAC1B,IAAI,CAACq6B,MAAQA,EAAI,CAAC,IAAKA,EAAI,MAAM,CAAC,EAAe,KAAK,GAAG,CAAC,EAC1D,KAAK,EAAE;AACZ;ACrlBO,SAASmD,GAAKz1B,IAAiB,IAAY;AAChD,QAAM01B,IACJ;AACF,MAAIjqC,IAAS;AACb,WAASF,IAAI,GAAGA,IAAIyU,GAAQzU;AAC1B,IAAAE,KAAUiqC,EAAM,OAAO,KAAK,MAAM,KAAK,OAAA,IAAWA,EAAM,MAAM,CAAC;AAEjE,SAAOjqC;AACT;AAOO,SAASkqC,GAAaC,GAAyC;AACpE,WAASC,EAAO3kC,GAAmB;AACjC,WAAO,SAASA,GAAG,EAAE,KAAK;AAAA,EAC5B;AACA,WAAS4kC,EAAQ5kC,GAAmB;AAClC,UAAMa,IAAI8jC,EAAO3kC,CAAC,IAAI;AACtB,WAAOa,KAAK,UAAUA,IAAI,QAAQ,KAAK,KAAKA,IAAI,SAAS,OAAO,GAAG;AAAA,EACrE;AACA,WAASgkC,EAAa9lC,GAAqB;AACzC,WACE,SAAS6lC,EAAQ7lC,EAAI,OAAO,GAAG,CAAC,CAAC,IACjC,SAAS6lC,EAAQ7lC,EAAI,OAAO,GAAG,CAAC,CAAC,IACjC,SAAS6lC,EAAQ7lC,EAAI,OAAO,EAAE,CAAC;AAAA,EAEnC;AACA,WAAS+lC,EAAYl+B,GAAWjF,GAAmB;AACjD,UAAMojC,IAAKF,EAAaj+B,CAAC,GACnBo+B,IAAKH,EAAaljC,CAAC;AACzB,YAAQ,KAAK,IAAIojC,GAAIC,CAAE,IAAI,SAAS,KAAK,IAAID,GAAIC,CAAE,IAAI;AAAA,EACzD;AACA,QAAMC,IAAgBH,EAAYJ,KAAY,QAAQ,SAAS,GACzDQ,IAAgBJ,EAAYJ,KAAY,QAAQ,SAAS;AAC/D,SAAOO,IAAgBC,IAAgB,YAAY;AACrD;AAOO,SAASC,GACdp3B,GACAq3B,IAAe,qBACoB;AACnC,QAAMC,IAAY,OAAOt3B,CAAI,EAAE,MAAM;AAAA,CAAI,GACnCu3B,IAAYF,EAAK,MAAM,GAAG,GAC1BG,IAAa,UACbvnB,IAAWsnB,IAAY,CAAC,GAAG,SAAS,IAAI,IAC1C,WAAWA,IAAY,CAAC,GAAG,QAAQ,QAAQ,EAAE,CAAC,IAC9C,IACEtJ,IAAasJ,GAAW,MAAM,CAAC,EAAE,KAAK,GAAG,EAAE,KAAA;AAEjD,MAAI,OAAO,WAAa;AACtB,WAAO;AAAA,MACL,OAAO,KAAK,IAAI,GAAGD,EAAU,IAAI,CAAC9kC,MAAMA,EAAE,MAAM,CAAC,IAAIyd,IAAW;AAAA,MAChE,QAAQqnB,EAAU,SAASrnB,IAAW,MAAM;AAAA,IAAA;AAIhD,QAAMwnB,IAAkB,SAAS,cAAc,QAAQ,GACjDC,IAAyB,CAAA,GACzBC,IAAa;AAUnB,MATAL,EAAU,QAAQ,CAAC9kC,MAAM;AACvB,UAAMuV,IAAU0vB,EAAgB,WAAW,IAAI;AAC/C,QAAI,CAAC1vB,EAAS;AACd,UAAM6vB,IAAqB3nB,IAAW0nB;AACtC,IAAA5vB,EAAQ,OAAO,GAAGyvB,CAAU,IAAII,CAAkB,MAAM3J,CAAU,IAClEyJ,EAAQ,KAAK3vB,EAAQ,YAAYvV,CAAC,CAAC;AAAA,EACrC,CAAC,GACDilC,EAAgB,OAAA,GAEZC,EAAQ,WAAW;AACrB,WAAO;AAAA,MACL,OAAO,KAAK,IAAI,GAAGJ,EAAU,IAAI,CAAC9kC,MAAMA,EAAE,MAAM,CAAC,IAAIyd,IAAW;AAAA,MAChE,QAAQqnB,EAAU,SAASrnB,IAAW,MAAM;AAAA,IAAA;AAIhD,MAAI9iB,IAAS;AACb,SAAAuqC,EAAQ,QAAQ,CAAC7rC,MAAM;AACrB,IAAAsB,MACItB,EAAU,2BAA2BokB,MACrCpkB,EAAU,4BAA4BokB,IAAW,OACnD;AAAA,EACJ,CAAC,GACM;AAAA,IACL,OAAO,KAAK,IAAI,GAAGynB,EAAQ,IAAI,CAAC7rC,MAAMA,EAAE,KAAK,CAAC;AAAA,IAC9C,QAAQsB,IAAS;AAAA,EAAA;AAErB;AAMO,SAAS0qC,GAAcC,GAAcC,GAAsB;AAChE,QAAMC,IAAM,CAAChnC,MAAwB;AACnC,UAAM2D,KAAK3D,KAAO,IAAI,QAAQ,KAAK,EAAE;AACrC,QAAI2D,EAAE,SAAS,EAAG,QAAO;AACzB,UAAMsjC,IAAO,CAAChmC,MAAc;AAC1B,YAAMa,IAAIb,IAAI;AACd,aAAOa,KAAK,UAAUA,IAAI,QAAQ,KAAK,KAAKA,IAAI,SAAS,OAAO,GAAG;AAAA,IACrE,GACMC,IAAIklC,EAAK,SAAStjC,EAAE,OAAO,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,GAC1C7H,IAAImrC,EAAK,SAAStjC,EAAE,OAAO,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,GAC1Cf,IAAIqkC,EAAK,SAAStjC,EAAE,OAAO,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC;AAChD,WAAO,SAAS5B,IAAI,SAASjG,IAAI,SAAS8G;AAAA,EAC5C,GACMskC,IAAKF,EAAIF,CAAI,GACbK,IAAKH,EAAID,CAAI;AACnB,UAAQ,KAAK,IAAIG,GAAIC,CAAE,IAAI,SAAS,KAAK,IAAID,GAAIC,CAAE,IAAI;AACzD;AAOO,SAASC,GAAQlM,GAStB;AACA,SAAKA,GAAM,OAGJoJ,GAASpJ,EAAK,IAAI,IAFhB,EAAE,GAAG,GAAG,GAAG,GAAG,IAAI,KAAK,IAAI,KAAK,OAAO,KAAK,QAAQ,KAAK,IAAI,IAAI,IAAI,GAAA;AAGhF;AAQO,SAASmM,GAAet9B,GAAcqG,GAA2B;AACtE,SAAOk1B,GAAcv7B,GAAMqG,CAAS;AACtC;AAKO,SAASk3B,GAAoBt4B,GAAcu4B,GAA2B;AAC3E,QAAMC,IAAQ,OAAOx4B,CAAI,EAAE,MAAM,IAAI,GAE/By4B,IADQ,OAAOz4B,CAAI,EAAE,MAAM,EAAE,EACR,SAASu4B,GAC9BG,IAAkB,CAAA;AACxB,MAAIC,IAAwB,CAAA,GACxBC,IAAe;AACnB,SAAAJ,EAAM,QAAQ,CAAC7uB,MAAM;AACnB,IAAAivB,KAAgBjvB,EAAE,QACdivB,IAAeH,KAAgBC,EAAM,WAAWH,IAAY,IAC9DI,EAAY,KAAKhvB,CAAC,KAElB+uB,EAAM,KAAKC,EAAY,KAAK,GAAG,CAAC,GAChCC,IAAejvB,EAAE,QACjBgvB,IAAc,CAAChvB,CAAC;AAAA,EAEpB,CAAC,GACGgvB,EAAY,SAAS,KACvBD,EAAM,KAAKC,EAAY,KAAK,GAAG,CAAC,GAE3BD,EAAM,KAAK;AAAA,CAAI;AACxB;AAGO,SAASG,GAAU5jC,GAAaD,GAAqB;AAC1D,SAAO,KAAK,MAAM,KAAK,OAAA,KAAYA,IAAMC,IAAM,EAAE,IAAIA;AACvD;AAMO,SAAS6jC,GACdC,GACAC,GACAC,GACAC,GACAvkB,IAA+B,IACI;AACnC,MAAI,CAACA;AACH,WAAO,EAAE,OAAOskB,GAAa,QAAQC,EAAA;AAGvC,QAAM5jB,IAAQ,KAAK;AAAA,IACjB2jB,IAAcF;AAAA,IACdG,IAAeF;AAAA,EAAA;AAGjB,SAAO;AAAA,IACL,OAAOD,IAAgBzjB;AAAA,IACvB,QAAQ0jB,IAAiB1jB;AAAA,EAAA;AAE7B;AAKO,SAAS6jB,GAAwBjN,GAGhC;AAEN,QAAM,EAAE,yBAAyBvc,MAAU,QAAQ,cAAc;AACjE,SAAOA,EAAMuc,EAAK,OAAOA,EAAK,WAAW;AAC3C;AAGO,SAASkN,GAAYl4B,GAAqB;AAC/C,SAAOA,EACJ,QAAQ,oBAAoB,EAAE,EAC9B,QAAQ,QAAQ,GAAG,EACnB,YAAA;AACL;AAGO,SAASm4B,GAAU98B,GAAmB;AAC3C,SAAOA,aAAe,eAAeA,aAAe;AACtD;AAGO,SAAShK,GAAGiN,GAAgC;AACjD,SAAI,OAAO,WAAa,MAAoB,OACrC,SAAS,eAAeA,CAAE;AACnC;AAGO,SAAS85B,KAAoB;AAClC,SAAI,OAAO,YAAc,MAAoB,KACtC,iCAAiC,KAAK,UAAU,SAAS;AAClE;AAGO,SAASC,KAAoB;AAClC,SAAI,OAAO,YAAc,MAAoB,KACtC,iEAAiE;AAAA,IACtE,UAAU;AAAA,EAAA;AAEd;AAGO,SAASC,GAAUC,GAAkB;AAC1C,EAAIA,MACFA,EAAI,eAAA,GACJA,EAAI,gBAAA;AAER;AAGO,SAASC,GAASt9B,GAAUiM,GAAqB;AACtD,QAAMsxB,IAAgB,CAAA;AACtB,WAASrtC,IAAI,GAAGA,IAAI8P,EAAI,QAAQ9P,KAAK+b;AACnC,IAAAsxB,EAAO,KAAKv9B,EAAI,MAAM9P,GAAGA,IAAI+b,CAAI,CAAC;AAEpC,SAAOsxB;AACT;;;;;;;;;;;;;;;;;;;;8CCxQMC,KAAO,0CAEPC,KAA8C;AAAA,EAClD,SAAS;AAAA,IACP,IAAI;AAAA,IACJ,OAAO,CAAC,QAAQ,MAAM;AAAA,IACtB,SAAS;AAAA,IACT,aAAa;AAAA,IACb,KAAK,8CAA8CD,EAAI;AAAA,EAAA;AAAA,EAEzD,aAAa;AAAA,IACX,IAAI;AAAA,IACJ,OAAO,CAAC,QAAQ,MAAM;AAAA,IACtB,SAAS;AAAA,IACT,aAAa;AAAA,IACb,KAAK,wDAAwDA,EAAI;AAAA,EAAA;AAAA,EAEnE,eAAe;AAAA,IACb,IAAI;AAAA,IACJ,OAAO,CAAC,QAAQ,MAAM;AAAA,IACtB,SAAS;AAAA,IACT,aAAa;AAAA,IACb,KAAK,4DAA4DA,EAAI;AAAA,EAAA;AAAA,EAEvE,UAAU;AAAA,IACR,IAAI;AAAA,IACJ,OAAO,CAAC,QAAQ,MAAM;AAAA,IACtB,SAAS;AAAA,IACT,aAAa;AAAA,IACb,KAAK,kDAAkDA,EAAI;AAAA,EAAA;AAAA,EAE7D,YAAY;AAAA,IACV,IAAI;AAAA,IACJ,OAAO,CAAC,QAAQ,MAAM;AAAA,IACtB,SAAS;AAAA,IACT,aAAa;AAAA,IACb,KAAK,sDAAsDA,EAAI;AAAA,EAAA;AAAA,EAEjE,aAAa;AAAA,IACX,IAAI;AAAA,IACJ,OAAO,CAAC,QAAQ,MAAM;AAAA,IACtB,SAAS;AAAA,IACT,aAAa;AAAA,IACb,KAAK;AAAA,EAAA;AAAA,EAEP,YAAY;AAAA,IACV,IAAI;AAAA,IACJ,OAAO,CAAC,QAAQ,MAAM;AAAA,IACtB,SAAS;AAAA,IACT,aAAa;AAAA,IACb,KAAK;AAAA,EAAA;AAAA,EAEP,YAAY;AAAA,IACV,IAAI;AAAA,IACJ,OAAO,CAAC,QAAQ,MAAM;AAAA,IACtB,SAAS;AAAA,IACT,aAAa;AAAA,IACb,KAAK;AAAA,EAAA;AAAA,EAEP,QAAQ;AAAA,IACN,IAAI;AAAA,IACJ,OAAO,CAAC,QAAQ,MAAM;AAAA,IACtB,SAAS;AAAA,IACT,aAAa;AAAA,IACb,KAAK;AAAA,EAAA;AAAA,EAEP,OAAO;AAAA,IACL,IAAI;AAAA,IACJ,OAAO,CAAC,QAAQ,MAAM;AAAA,IACtB,SAAS;AAAA,IACT,aAAa;AAAA,IACb,KAAK,0CAA0CA,EAAI;AAAA,EAAA;AAAA,EAErD,WAAW;AAAA,IACT,IAAI;AAAA,IACJ,OAAO,CAAC,QAAQ,MAAM;AAAA,IACtB,SAAS;AAAA,IACT,aAAa;AAAA,IACb,KAAK,kDAAkDA,EAAI;AAAA,EAAA;AAAA,EAE7D,MAAM;AAAA,IACJ,IAAI;AAAA,IACJ,OAAO,CAAC,QAAQ,MAAM;AAAA,IACtB,SAAS;AAAA,IACT,aAAa;AAAA,IACb,KAAK;AAAA,EAAA;AAAA,EAEP,SAAS;AAAA,IACP,IAAI;AAAA,IACJ,OAAO,CAAC,QAAQ,MAAM;AAAA,IACtB,SAAS;AAAA,IACT,aAAa;AAAA,IACb,KAAK;AAAA,EAAA;AAAA,EAEP,SAAS;AAAA,IACP,IAAI;AAAA,IACJ,OAAO,CAAC,MAAM;AAAA,IACd,SAAS;AAAA,IACT,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,KAAK;AAAA,EAAA;AAAA,EAEP,OAAO;AAAA,IACL,IAAI;AAAA,IACJ,OAAO,CAAC,MAAM;AAAA,IACd,SAAS;AAAA,IACT,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,KAAK;AAAA,EAAA;AAAA,EAEP,QAAQ;AAAA,IACN,IAAI;AAAA,IACJ,OAAO,CAAC,MAAM;AAAA,IACd,SAAS;AAAA,IACT,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,KAAK;AAAA,EAAA;AAET,GAEME,KAAU;AAET,SAASC,KAAuD;AACrE,SAAO,EAAE,GAAGF,GAAA;AACd;AAEA,SAASG,GAAepuC,GAAsB;AAC5C,SAAO,gBAAgBA,CAAI;AAC7B;AAEO,SAASquC,GAAuBhtC,GAAoB;AAEzD,QAAM0gC,IADO1gC,GAAS,OAAA,GACH,OAAA;AACnB,MAAI,CAAC0gC,KAAQA,EAAK,UAAU,2BAA2B,EAAG;AAC1D,QAAMv7B,IAAQu7B,EAAK,QAAQ,OAAO,EAAE,GAAG,0BAA0B;AACjE,EAAAv7B,EAAM,KAAK,QAAQ,UAAU,GAC7BA,EAAM,KAAK,cAAc0nC,KAAU,OAAO,OAAOD,EAAa,EAAE,IAAI,CAACK,MAAQA,EAAI,GAAG,EAAE,KAAK,EAAE;AAC/F;AAEO,SAASC,GAAeltC,GAAcrB,GAAuB;AAClE,MAAI,CAACqB,KAAW,CAAC4sC,GAAcjuC,CAAI,EAAG,QAAO;AAC7C,EAAAquC,GAAuBhtC,CAAO,GAC9BmtC,GAAiBntC,CAAO;AACxB,QAAMotC,IAAMptC,EAAQ;AAEpB,SAAIotC,MACIA,EAA2B,UAAA,GACjCA,EAAI,UAAU,IAAI,qBAAqBL,GAAepuC,CAAI,CAAC,IAEtD;AACT;AAEO,SAASwuC,GAAiBntC,GAAoB;AACnD,QAAMotC,IAAMptC,GAAS;AACrB,MAAKotC,GACL;AAAA,eAAWzuC,KAAQ,OAAO,KAAKiuC,EAAa,KAAO,UAAU,OAAOG,GAAepuC,CAAI,CAAC;AACxF,IAAAyuC,EAAI,UAAU,OAAO,mBAAmB;AAAA;AAC1C;AClJA,MAAMC,yBAAyC,IAAA;AAE/CA,GAAW,IAAI,cAAc;AAAA,EAC3B,MAAM;AAAA,EACN,OAAO,CAAC,QAAQ,QAAQ,SAAS,MAAM;AAAA,EACvC,OAAO,CAACrtC,MAAiB;AACvB,QAAI;AACF,MAAAA,EAAQ;AAAA,QACN;AAAA,QACA;AAAA,MAAA;AAAA,IAEJ,QAAQ;AAAA,IAER;AAAA,EACF;AAAA,EACA,QAAQ,CAACA,MAAiB;AACxB,QAAI;AACF,MAAAA,EAAQ,KAAK,UAAU,IAAI;AAAA,IAC7B,QAAQ;AAAA,IAAC;AAAA,EACX;AACF,CAAC;AAEDqtC,GAAW,IAAI,QAAQ;AAAA,EACrB,MAAM;AAAA,EACN,OAAO,CAAC,QAAQ,QAAQ,SAAS,MAAM;AAAA,EACvC,OAAO,CAACrtC,MAAiB;AACvB,QAAI;AACF,MAAAA,EAAQ,KAAK,UAAU,WAAW;AAAA,IACpC,QAAQ;AAAA,IAAC;AAAA,EACX;AAAA,EACA,QAAQ,CAACA,MAAiB;AACxB,QAAI;AACF,MAAAA,EAAQ,KAAK,UAAU,IAAI;AAAA,IAC7B,QAAQ;AAAA,IAAC;AAAA,EACX;AACF,CAAC;AAEDqtC,GAAW,IAAI,WAAW;AAAA,EACxB,MAAM;AAAA,EACN,OAAO,CAAC,QAAQ,MAAM;AAAA,EACtB,OAAO,CAACrtC,MAAiB;AACvB,QAAI;AAEF,YAAMstC,IAAattC,EAAQ,KAAK,QAAQ,GAClCutC,IAAkBvtC,EAAQ,KAAK,cAAc;AACnD,MAAAA,EAAQ,KAAK,mBAAmBstC,KAAc,MAAM,GACpDttC,EAAQ,KAAK,yBAAyButC,KAAmB,CAAC;AAI1D,YAAMpW,IAAOn3B,EAAQ,KAAK,MAAM,GAC1BwtC,IACJ,OAAOrW,KAAS,YAAY,sBAAsB,KAAKA,CAAI,IACvDsS,GAAatS,CAAI,IACjB;AACN,MAAAn3B,EAAQ,OAAO,EAAE,OAAOwtC,GAAc,OAAO,GAAG,GAM5CxtC,EAAQ,SAAS,UACnBA,EAAQ,KAAK,eAAe,QAAQ;AAAA,IAExC,QAAQ;AAAA,IAAC;AAAA,EACX;AAAA,EACA,QAAQ,CAACA,MAAiB;AACxB,QAAI;AAEF,MAAAA,EAAQ,OAAO;AAAA,QACb,OAAOA,EAAQ,KAAK,iBAAiB,KAAK;AAAA,QAC1C,OAAOA,EAAQ,KAAK,uBAAuB,KAAK;AAAA,MAAA,CACjD,GACDA,EAAQ,KAAK,eAAe,IAAI;AAAA,IAClC,QAAQ;AAAA,IAAC;AAAA,EACX;AACF,CAAC;AAIDqtC,GAAW,IAAI,cAAc;AAAA,EAC3B,MAAM;AAAA,EACN,OAAO,CAAC,QAAQ,QAAQ,SAAS,MAAM;AAAA,EACvC,OAAO,CAACrtC,MAAiB;AACvB,QAAI;AACF,MAAAA,EAAQ,KAAK,UAAU,wCAAwC;AAAA,IACjE,QAAQ;AAAA,IAAC;AAAA,EACX;AAAA,EACA,QAAQ,CAACA,MAAiB;AACxB,QAAI;AACF,MAAAA,EAAQ,KAAK,UAAU,IAAI;AAAA,IAC7B,QAAQ;AAAA,IAAC;AAAA,EACX;AACF,CAAC;AAKDqtC,GAAW,IAAI,UAAU;AAAA,EACvB,MAAM;AAAA,EACN,OAAO,CAAC,QAAQ,QAAQ,OAAO;AAAA,EAC/B,OAAO,CAACrtC,MAAiB;AACvB,QAAI;AAEF,YAAM0gC,IADO1gC,EAAQ,OAAA,GACF,OAAA;AACnB,UAAI0gC,KAAQ,CAACA,EAAK,UAAU,mBAAmB,GAAG;AAChD,cAAM90B,IAAI80B,EAAK,QAAQ,QAAQ,EAAE,GAAG,kBAAkB;AACtD,QAAA90B,EAAE,KAAK;AAAA,UACL,GAAG;AAAA,UACH,GAAG;AAAA,UACH,OAAO;AAAA,UACP,QAAQ;AAAA,QAAA,CACT,GACDA,EAAE,KAAK,YACL;AAAA,MAEJ;AACA,MAAA5L,EAAQ,KAAK,UAAU,wBAAwB;AAAA,IACjD,QAAQ;AAAA,IAAC;AAAA,EACX;AAAA,EACA,QAAQ,CAACA,MAAiB;AACxB,QAAI;AACF,MAAAA,EAAQ,KAAK,UAAU,IAAI;AAAA,IAC7B,QAAQ;AAAA,IAAC;AAAA,EACX;AACF,CAAC;AAIM,MAAMytC,GAAQ;AAAA,EAKnB,YAAYrrC,GAAY;AAHxB,SAAQ,oCAAiC,IAAA,GACzC,KAAQ,SAAkB,IAGxB,KAAK,OAAOA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,MACLsrC,GACAp2B,IAAmC,QAC7B;AACN,UAAM21B,IAAMI,GAAW,IAAIK,CAAU;AACrC,QAAI,CAACT,GAAK;AACR,cAAQ,KAAK,kCAAkCS,CAAU;AACzD;AAAA,IACF;AAEA,KAAIp2B,MAAW,UAAUA,MAAW,WAC9B,KAAK,KAAK,kBACZ21B,EAAI,MAAM,KAAK,KAAK,cAAc,IAIlC31B,MAAW,UAAUA,MAAW,WAC9B,KAAK,KAAK,eACZ21B,EAAI,MAAM,KAAK,KAAK,WAAW,GAInC,KAAK,cAAc,IAAIS,CAAU,GAG5B,KAAK,KAAK,QAAQ,YACrB,KAAK,KAAK,QAAQ,UAAU,CAAA,KAE1Bp2B,MAAW,UAAUA,MAAW,YAClC,KAAK,KAAK,QAAQ,QAAQ,OAAOo2B,KAE/Bp2B,MAAW,UAAUA,MAAW,YAClC,KAAK,KAAK,QAAQ,QAAQ,OAAOo2B,IAGnC,QAAQ;AAAA,MACN;AAAA,MACAA;AAAA,MACA;AAAA,MACA,KAAK,KAAK;AAAA,MACV;AAAA,MACAp2B;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA,EAKO,OAAOo2B,GAA0B;AACtC,UAAMT,IAAMI,GAAW,IAAIK,CAAU;AACrC,IAAKT,MAED,KAAK,KAAK,kBACZA,EAAI,OAAO,KAAK,KAAK,cAAc,GAEjC,KAAK,KAAK,eACZA,EAAI,OAAO,KAAK,KAAK,WAAW,GAGlC,KAAK,cAAc,OAAOS,CAAU;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKO,YAAkB;AACvB,eAAW/uC,KAAQ,KAAK;AACtB,WAAK,OAAOA,CAAI;AAElB,SAAK,cAAc,MAAA;AAAA,EACrB;AAAA;AAAA,EAGO,eACLgvC,GACAr2B,GACS;AACT,UAAMtX,IAAUsX,MAAW,SAAS,KAAK,KAAK,cAAc,KAAK,KAAK;AACtE,WAAK41B,GAAeltC,GAAS2tC,CAAa,KACrC,KAAK,KAAK,QAAQ,eAAY,KAAK,KAAK,QAAQ,aAAa,CAAA,IAClE,KAAK,KAAK,QAAQ,WAAWr2B,CAAM,IAAIq2B,GAChC,MAH6C;AAAA,EAItD;AAAA;AAAA,EAGO,gBAAgBr2B,GAA+B;AACpD,UAAMtX,IAAUsX,MAAW,SAAS,KAAK,KAAK,cAAc,KAAK,KAAK;AACtE,IAAA61B,GAAiBntC,CAAO,GACpB,KAAK,KAAK,QAAQ,oBAAiB,KAAK,QAAQ,WAAWsX,CAAM,IAAI;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA,EAKO,iBAAiB5R,GAAqB;AAE3C,QADA,KAAK,SAASA,GACVA;AAEF,iBAAW/G,KAAQ,KAAK,eAAe;AACrC,cAAMsuC,IAAMI,GAAW,IAAI1uC,CAAI;AAC/B,QAAIsuC,MACE,KAAK,KAAK,oBAAoB,OAAO,KAAK,KAAK,cAAc,GAC7D,KAAK,KAAK,iBAAiB,OAAO,KAAK,KAAK,WAAW;AAAA,MAE/D;AAAA;AAGA,iBAAWtuC,KAAQ,KAAK,eAAe;AACrC,cAAMsuC,IAAMI,GAAW,IAAI1uC,CAAI;AAC/B,QAAIsuC,MACE,KAAK,KAAK,oBAAoB,MAAM,KAAK,KAAK,cAAc,GAC5D,KAAK,KAAK,iBAAiB,MAAM,KAAK,KAAK,WAAW;AAAA,MAE9D;AAAA,EAEJ;AAAA;AAAA,EAGO,YAAsB;AAC3B,WAAO,MAAM,KAAK,KAAK,aAAa;AAAA,EACtC;AAAA;AAAA,EAGO,SAASS,GAA6B;AAC3C,WAAO,KAAK,cAAc,IAAIA,CAAU;AAAA,EAC1C;AAAA;AAAA,EAGO,UAAgB;AACrB,SAAK,UAAA,GACL,KAAK,cAAc,MAAA,GACnB,KAAK,SAAS,IACb,KAAa,OAAO;AAAA,EACvB;AACF;AAKO,SAASE,GAAeX,GAAsB;AACnD,EAAAI,GAAW,IAAIJ,EAAI,MAAMA,CAAG;AAC9B;AAGO,SAASY,KAA2B;AACzC,SAAO,MAAM,KAAKR,GAAW,KAAA,CAAM;AACrC;AAOO,SAASS,KAA2D;AACzE,QAAM/F,IAA2C,CAAA;AACjD,aAAW,CAACppC,GAAMsuC,CAAG,KAAKI;AACxB,IAAAtF,EAAIppC,CAAI,IAAI,EAAE,OAAOsuC,EAAI,SAAS,CAAC,QAAQ,MAAM,EAAA;AAEnD,SAAOlF;AACT;ACrTO,MAAMgG,GAAK;AAAA,EAMhB,YAAY3rC,GAAYoO,IAAuB,IAAI;AAFnD,SAAQ,SAAkB,IAGxB,KAAK,OAAOpO,GACZ,KAAK,QAAQA,EAAK,OAClB,KAAK,UAAU;AAAA,MACb,SAAS;AAAA,MACT,GAAGoO;AAAA,IAAA;AAAA,EAEP;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,OAAa;AAElB,QADI,CAAC,KAAK,QAAQ,WACd,KAAK,KAAK,QAAQ,cAAc,GAAO;AAG3C,UAAMw9B,IAAO,KAAK,eAAA;AAGlB,IAAI,KAAK,MAAM,QAAQ,QAAQ,mBAC7B,KAAK,SAAS,IACd,KAAK,MAAM,QAAQ,OAAO,gBAAgB,KAAK,MAAM,CAACzuC,MAAgB;AACpE,WAAK,SAAS,IACd,QAAQ,IAAI,+BAA+B,KAAK,KAAK,EAAE;AAAA,IACzD,CAAC,KAGD,KAAK,SAAS,IAGhB,QAAQ;AAAA,MACN;AAAA,MACA,KAAK,KAAK;AAAA,MACV;AAAA,MACAyuC;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA,EAGO,QAAc;AACnB,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA,EAGO,aAAsB;AAC3B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGO,iBAA2B;AAChC,UAAMA,IAAiB,CAAA,GACjB/O,IAAO,KAAK,KAAK;AAEvB,WAAIA,EAAK,iBAAiB,MAAO+O,EAAK,KAAK,OAAO,GAC9C/O,EAAK,gBAAgB,MAAO+O,EAAK,KAAK,MAAM,GAC5C/O,EAAK,iBAAiB,MAAO+O,EAAK,KAAK,OAAO,GAC9C/O,EAAK,iBAAiB,MAAO+O,EAAK,KAAK,OAAO,GAC9C/O,EAAK,kBAAkB,MAAO+O,EAAK,KAAK,QAAQ,GAChD/O,EAAK,cAAc,MAAO+O,EAAK,KAAK,IAAI,GAErCA;AAAA,EACT;AAAA;AAAA,EAGO,SAAe;AACpB,SAAK,QAAQ,UAAU;AAAA,EACzB;AAAA,EAEO,UAAgB;AACrB,SAAK,QAAQ,UAAU,IACvB,KAAK,MAAA;AAAA,EACP;AAAA,EAEO,YAAqB;AAC1B,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA;AAAA,EAGO,UAAgB;AACrB,SAAK,MAAA,GACL,KAAK,QAAQ,UAAU,IACtB,KAAa,OAAO,MACpB,KAAa,QAAQ;AAAA,EACxB;AACF;ACtFA,MAAMtX,wBAA2C,IAAA;AAGjDA,EAAO,IAAI,aAAa;AAAA,EACtB,MAAM;AAAA,EACN,cAAc;AAAA,EACd,eAAe;AAAA,EACf,SAAS;AACX,CAAC;AAGDA,EAAO,IAAI,oBAAoB;AAAA,EAC7B,MAAM;AAAA,EACN,cAAc;AAAA,EACd,eAAe;AAAA,EACf,aAAa;AAAA,EACb,SAAS;AACX,CAAC;AAGDA,EAAO,IAAI,WAAW;AAAA,EACpB,MAAM;AAAA,EACN,cAAc;AAAA,EACd,eAAe;AAAA,EACf,SAAS;AACX,CAAC;AAGDA,EAAO,IAAI,UAAU;AAAA,EACnB,MAAM;AAAA,EACN,cAAc;AAAA,EACd,eAAe;AAAA,EACf,SAAS;AACX,CAAC;AAGDA,EAAO,IAAI,QAAQ;AAAA,EACjB,MAAM;AAAA,EACN,cAAc;AAAA,EACd,eAAe;AAAA,EACf,SAAS;AACX,CAAC;AAGDA,EAAO,IAAI,YAAY;AAAA,EACrB,MAAM;AAAA,EACN,cAAc;AAAA,EACd,eAAe;AAAA,EACf,SAAS;AACX,CAAC;AAGDA,EAAO,IAAI,YAAY;AAAA,EACrB,MAAM;AAAA,EACN,cAAc;AAAA,EACd,eAAe;AAAA,EACf,SAAS;AACX,CAAC;AAGDA,EAAO,IAAI,WAAW;AAAA,EACpB,MAAM;AAAA,EACN,cAAc;AAAA,EACd,eAAe;AAAA,EACf,SAAS;AACX,CAAC;AAGDA,EAAO,IAAI,WAAW;AAAA,EACpB,MAAM;AAAA,EACN,cAAc;AAAA,EACd,eAAe;AAAA,EACf,SAAS;AACX,CAAC;AAGDA,EAAO,IAAI,aAAa;AAAA,EACtB,MAAM;AAAA,EACN,cAAc;AAAA,EACd,eAAe;AAAA,EACf,SAAS;AACX,CAAC;AAGDA,EAAO,IAAI,iBAAiB;AAAA,EAC1B,MAAM;AAAA,EACN,cAAc;AAAA,EACd,eAAe;AAAA,EACf,SAAS;AACX,CAAC;AAGDA,EAAO,IAAI,UAAU;AAAA,EACnB,MAAM;AAAA,EACN,cAAc;AAAA,EACd,eAAe;AAAA,EACf,SAAS;AACX,CAAC;AAGDA,EAAO,IAAI,UAAU;AAAA,EACnB,MAAM;AAAA,EACN,cAAc;AAAA,EACd,eAAe;AAAA,EACf,SAAS;AACX,CAAC;AAGDA,EAAO,IAAI,WAAW;AAAA,EACpB,MAAM;AAAA,EACN,cAAc;AAAA,EACd,eAAe;AAAA,EACf,SAAS;AACX,CAAC;AAKM,SAASuX,GAAStvC,GAA2C;AAClE,SAAO+3B,EAAO,IAAI/3B,EAAK,YAAA,CAAa;AACtC;AAGO,SAASuvC,GAASvvC,GAAuB;AAC9C,SAAO+3B,EAAO,IAAI/3B,EAAK,YAAA,CAAa;AACtC;AAGO,SAASwvC,GACdxvC,GACAyvC,GACM;AACN,EAAA1X,EAAO,IAAI/3B,EAAK,YAAA,GAAeyvC,CAAU;AAC3C;AAGO,SAASC,KAA0B;AACxC,SAAO,MAAM,KAAK3X,EAAO,KAAA,CAAM;AACjC;AAGO,SAAS4X,GAAc3vC,GAAuB;AAEnD,SADe,CAAC,aAAa,UAAU,SAAS,EAClC,SAASA,EAAK,YAAA,CAAa;AAC3C;AAWO,SAAS4vC,GACdpkB,GACAqkB,GAC6B;AAE7B,MAAIA,GAAY;AAEd,UAAMC,IAAQR,GAASO,CAAU;AACjC,QAAIC,EAAO,QAAOA;AAGlB,QAAID,EAAW,OAAO,WAAW,GAAG,KAAKA,EAAW,KAAA,EAAO,WAAW,GAAG;AACvE,aAAO;AAAA,QACL,MAAMA;AAAA,QACN,cAAc;AAAA,QACd,eAAe;AAAA,QACf,SAAS;AAAA;AAAA,MAAA;AAAA,EAGf;AAGA,MAAIrkB,GAAO;AACT,UAAMskB,IAAQR,GAAS9jB,CAAK;AAC5B,QAAIskB,EAAO,QAAOA;AAIlB,QAAItkB,EAAM,OAAO,WAAW,GAAG,KAAKA,EAAM,KAAA,EAAO,WAAW,GAAG;AAC7D,aAAO;AAAA,QACL,MAAMA;AAAA,QACN,cAAc;AAAA,QACd,eAAe;AAAA,QACf,SAAS;AAAA;AAAA,MAAA;AAAA,EAGf;AAGF;;;;;;;;;;AC3MO,SAASukB,GAAWC,GAA+C;AACxE,QAAMC,IAA0B,EAAE,GAAGD,EAAA;AAGrC,SAAIA,EAAG,SAAS,UAAaC,EAAG,MAAM,WACpCA,EAAG,IAAID,EAAG,MACV,OAAOC,EAAG,OAERD,EAAG,SAAS,UAAaC,EAAG,MAAM,WACpCA,EAAG,IAAID,EAAG,MACV,OAAOC,EAAG,OAIRD,EAAG,oBAAoB,UAAaC,EAAG,cAAc,WACvDA,EAAG,YAAYD,EAAG,iBAClB,OAAOC,EAAG,kBAIRD,EAAG,cAAc,UAAaC,EAAG,UAAU,WAC7CA,EAAG,QAAQC,GAAoBF,EAAG,SAAS,GAC3C,OAAOC,EAAG,YAIRD,EAAG,cAAc,UAAaC,EAAG,eAAe,WAClDA,EAAG,aAAaD,EAAG,WACnB,OAAOC,EAAG,YAIRD,EAAG,gBAAgB,WACrBC,EAAG,iBAAiBD,EAAG,aACvB,OAAOC,EAAG,cAGLA;AACT;AAGO,SAASE,EAAWF,GAA+C;AACxE,QAAMD,IAA0B,EAAE,GAAGC,EAAA;AAGrC,SAAAD,EAAG,OAAOC,EAAG,GACbD,EAAG,OAAOC,EAAG,GAGbD,EAAG,kBAAkBC,EAAG,WAGpBA,EAAG,UACLD,EAAG,YAAYC,EAAG,QAIhBA,EAAG,eACLD,EAAG,YAAYC,EAAG,aAGbD;AACT;AAKO,SAASI,GAAYJ,GAAgD;AAC1E,QAAMC,IAA0B,EAAE,GAAGD,EAAA;AAOrC,SAAIA,EAAG,iBAAiB,WACtBC,EAAG,WAAW;AAAA,IACZ,SAAS,CAAC,CAACD,EAAG;AAAA;AAAA;AAAA,IAGd,UAAU;AAAA,IACV,GAAIA,EAAG,iBACH,EAAE,OAAOA,EAAG,gBAAgB,QAAQA,EAAG,eAAA,IACvC,CAAA;AAAA,IACJ,GAAIA,EAAG,YAAY,CAAA;AAAA,EAAC,IAIjBC;AACT;AAGO,SAASI,GAAYJ,GAAgD;AAE1E,SADgC,EAAE,GAAGA,EAAA;AAEvC;AA2CO,SAASK,GAAkBN,GAAwC;AACxE,SAAO;AAAA,IACL,IAAIA,EAAG,MAAM,GAAGA,EAAG,QAAQ,KAAKA,EAAG,OAAO;AAAA,IAC1C,SAASA,EAAG;AAAA,IACZ,UAAUA,EAAG;AAAA,IACb,gBAAgBA,EAAG,kBAAkBA,EAAG,eAAe;AAAA,IACvD,WAAWA,EAAG,aAAa;AAAA,IAC3B,YAAYA,EAAG,cAAc;AAAA,IAC7B,aAAaA,EAAG,eAAe;AAAA,IAC/B,UAAUA,EAAG,YAAY;AAAA,IACzB,eAAeA,EAAG,iBAAiB;AAAA,IACnC,eAAeA,EAAG,iBAAiB;AAAA,IACnC,WAAWA,EAAG,aAAa;AAAA,IAC3B,iBAAiBA,EAAG,mBAAmB;AAAA,IACvC,gBAAgBA,EAAG,kBAAkB;AAAA,IACrC,aAAaA,EAAG,eAAe;AAAA,IAC/B,aAAaA,EAAG,eAAe;AAAA,IAC/B,cAAcA,EAAG,gBAAgB;AAAA,IACjC,cAAcA,EAAG,gBAAgB;AAAA,IACjC,OAAOA,EAAG,SAAS;AAAA,EAAA;AAEvB;AAGO,SAASO,GAAkBN,GAAwC;AACxE,SAAO;AAAA;AAAA;AAAA,IAGL,IAAIA,EAAG;AAAA,IACP,SAASA,EAAG;AAAA,IACZ,UAAUA,EAAG;AAAA,IACb,gBAAgBA,EAAG;AAAA,IACnB,WAAWA,EAAG;AAAA,IACd,YAAYA,EAAG;AAAA,IACf,aAAaA,EAAG;AAAA,IAChB,UAAUA,EAAG;AAAA,IACb,eAAeA,EAAG;AAAA,IAClB,eAAeA,EAAG;AAAA,IAClB,WAAWA,EAAG;AAAA,IACd,iBAAiBA,EAAG;AAAA,IACpB,gBAAgBA,EAAG;AAAA,IACnB,aAAaA,EAAG,eAAe;AAAA,IAC/B,aAAaA,EAAG,eAAe;AAAA,IAC/B,cAAcA,EAAG,gBAAgB;AAAA,IACjC,cAAcA,EAAG,gBAAgB;AAAA,IACjC,OAAOA,EAAG,SAAS;AAAA,EAAA;AAEvB;AAKA,SAASC,GAAoBM,GAA2B;AAkBtD,SAjBoC;AAAA,IAClC,MAAM;AAAA,IACN,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,WAAW;AAAA,IACX,UAAU;AAAA,IACV,UAAU;AAAA,IACV,eAAe;AAAA,IACf,SAAS;AAAA,IACT,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,EAAA,EAGCA,EAAU,YAAA,CAAa,KAAKA;AACzC;AAKO,SAASC,GAAkBC,GAAkB;AAClD,QAAMT,IAAU;AAAA,IACd,SAASG,GAAYM,EAAO,WAAW,CAAA,CAAE;AAAA,IACzC,OAAO,CAAA;AAAA,IACP,SAASA,EAAO,WAAW;AAAA,EAAA;AAG7B,SAAI,MAAM,QAAQA,EAAO,KAAK,MAC5BT,EAAG,QAAQS,EAAO,MAAM,IAAI,CAACC,MAAgB;AAC3C,UAAMC,IAAcb,GAAWY,EAAO,WAAW,CAAA,CAAE,GAC7CE,IAAqB,EAAE,cAAc,GAAC;AAE5C,WAAIF,EAAO,eAAe,iBACxBE,EAAc,eAAeF,EAAO,cAAc,aAAa;AAAA,MAC7D,CAAC1pC,MAAWqpC,GAAkBrpC,CAAC;AAAA,IAAA,IAI5B;AAAA,MACL,SAAS2pC;AAAA,MACT,eAAAC;AAAA,IAAA;AAAA,EAEJ,CAAC,IAGIZ;AACT;AAGO,SAASa,GAAkBC,GAAkB;AAClD,QAAMf,IAAU;AAAA,IACd,SAASK,GAAYU,EAAO,WAAW,CAAA,CAAE;AAAA,IACzC,OAAO,CAAA;AAAA,IACP,SAASA,EAAO,WAAW;AAAA,EAAA;AAG7B,SAAI,MAAM,QAAQA,EAAO,KAAK,MAC5Bf,EAAG,QAAQe,EAAO,MAAM,IAAI,CAACC,MAAgB;AAC3C,UAAMJ,IAAcT,EAAWa,EAAO,WAAW,CAAA,CAAE,GAC7CH,IAAqB,EAAE,cAAc,GAAC;AAE5C,WAAIG,EAAO,eAAe,iBACxBH,EAAc,eAAeG,EAAO,cAAc,aAAa;AAAA,MAC7D,CAAC/pC,MAAWspC,GAAkBtpC,CAAC;AAAA,IAAA,IAI5B;AAAA,MACL,SAAS2pC;AAAA,MACT,eAAAC;AAAA,IAAA;AAAA,EAEJ,CAAC,IAGIb;AACT;;;;;;;;;;;;ACjPO,SAASiB,GACdhiC,GACAiiC,GACArlC,IAAY,GACc;AAC1B,QAAM,EAAE,GAAA7J,GAAG,GAAAC,GAAG,OAAO8b,GAAG,QAAQhV,MAAMkG,GAChCkiC,IAAO,CAACnvC,GAAGA,IAAI+b,IAAI,GAAG/b,IAAI+b,CAAC,GAC3BqzB,IAAO,CAACnvC,GAAGA,IAAI8G,IAAI,GAAG9G,IAAI8G,CAAC;AACjC,MAAIsoC,IAAQrvC,GACRsvC,IAAQrvC,GACRsvC,IAAS1lC,GACT2lC,IAAS3lC;AACb,aAAWnK,KAAKwvC,GAAQ;AACtB,UAAMO,IAAU,CAAC/vC,EAAE,GAAGA,EAAE,IAAIA,EAAE,QAAQ,GAAGA,EAAE,IAAIA,EAAE,KAAK,GAChDgwC,IAAU,CAAChwC,EAAE,GAAGA,EAAE,IAAIA,EAAE,SAAS,GAAGA,EAAE,IAAIA,EAAE,MAAM;AACxD,eAAWyI,KAAMgnC;AACf,iBAAWQ,KAAMF,GAAS;AACxB,cAAM1wC,IAAI,KAAK,IAAIoJ,IAAKwnC,CAAE;AAC1B,QAAI5wC,IAAIwwC,MACNA,IAASxwC,GACTswC,IAAQrvC,KAAK2vC,IAAKxnC;AAAA,MAEtB;AAEF,eAAWq7B,KAAM4L;AACf,iBAAWQ,KAAMF,GAAS;AACxB,cAAM3wC,IAAI,KAAK,IAAIykC,IAAKoM,CAAE;AAC1B,QAAI7wC,IAAIywC,MACNA,IAASzwC,GACTuwC,IAAQrvC,KAAK2vC,IAAKpM;AAAA,MAEtB;AAAA,EAEJ;AACA,SAAO,EAAE,GAAG6L,GAAO,GAAGC,EAAA;AACxB;AA8JO,MAAMO,GAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0FhB,YAAYhgC,GAAsBkrB,GAAc;AA/DhD,SAAQ,oBAMJ,CAAA,GACJ,KAAQ,2BAAoC,IAI5C,KAAQ,uBAA6D,MACrE,KAAQ,qBAA8B,IAQtC,KAAQ,aAAsB,IAC9B,KAAQ,wBAAiC,IACzC,KAAQ,mBAAsE,MAC9E,KAAQ,kBAAmD,MAG3D,KAAQ,oBAAqD,MAG7D,KAAQ,qBAAkE,CAAA,GAI1E,KAAQ,iBAAiB,GAGzB,KAAQ,cAAuB,IAC/B,KAAQ,aAAsB,IAC9B,KAAQ,uBAA6D,MACrE,KAAQ,oBAA0D,MAClE,KAAQ,2BAAiE,MACzE,KAAQ,oBAA0D,MAuBhE,KAAK,KAAKlrB,EAAQ,MAAM,KAAK,WAAA,GAC7B,KAAK,QAAQkrB,GAEb,QAAQ,IAAI,kCAAkC,EAAE,IAAI,KAAK,IAAI,SAAAlrB,GAAS,GAGtE,KAAK,UAAU;AAAA,MACb,GAAG;AAAA,MACH,GAAG;AAAA,MACH,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,iBAAiB;AAAA,MACjB,aAAa;AAAA,MACb,aAAa;AAAA,MACb,WAAW;AAAA,MACX,UAAU;AAAA,MACV,OAAO;AAAA;AAAA;AAAA,MAGP,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,cAAc;AAAA,MACd,aAAa;AAAA,MACb,WAAW;AAAA,MACX,cAAc;AAAA,MACd,cAAc;AAAA,MACd,eAAe;AAAA,MACf,2BAA2B;AAAA,MAC3B,wBAAwB;AAAA,MACxB,4BAA4B;AAAA,MAC5B,0BAA0B;AAAA,MAC1B,WAAW;AAAA,MACX,cAAc;AAAA,MACd,QAAQ;AAAA,QACN,eAAe;AAAA,MAAA;AAAA,MAEjB,YAAY;AAAA,QACV,GAAG;AAAA,QACH,GAAG;AAAA,MAAA;AAAA,MAEL,cAAc;AAAA,QACZ,eAAe;AAAA,QACf,eAAe;AAAA,QACf,qBAAqB;AAAA,QACrB,cAAc;AAAA,QACd,MAAM;AAAA,QACN,QAAQ;AAAA,MAAA;AAAA,MAEV,GAAGA;AAAA,IAAA,GAGL,KAAK,QAAQ,IAAI,QAAc,CAAC4wB,GAASC,MAAW;AAClD,WAAK,gBAAgBD,GACrB,KAAK,eAAeC;AAAA,IACtB,CAAC,GAED,QAAQ,IAAI,uCAAuC,KAAK,EAAE,GAC1D,KAAK,YAAA;AAAA,EACP;AAAA,EAEQ,aAAqB;AAC3B,WAAO,UAAU,KAAK,SAAS,SAAS,EAAE,EAAE,OAAO,GAAG,CAAC;AAAA,EACzD;AAAA,EAEA,MAAc,cAAc;AAC1B,YAAQ,IAAI,uCAAuC,KAAK,EAAE;AAE1D,QAAI;AAEF,YAAMoP,IAAW,MAAM,KAAK,MAAM,iBAAA;AAClC,cAAQ,IAAI,gCAAgC,KAAK,IAAIA,CAAQ,GAE7D,KAAK,WAAWA,EAAS,MAAA,GAEzB,KAAK,SAAS,KAAK,gBAAgB,KAAK,EAAE,GAE1C,KAAK,SAAS,KAAK,aAAa,YAAY,GAAG,GAC/C,KAAK,SAAS,KAAK,aAAa,QAAQ,QAAQ,GAG5C,KAAK,SAAS,KAAK,eAAY,SAAS,KAAK,MAAM,SAAS,SAEhE,KAAK,0BAAA,GACL,QAAQ,IAAI,oCAAoC,KAAK,IAAI,KAAK,QAAQ,GAGtE,KAAK,aAAA;AAAA,IACP,SAASnV,GAAO;AACd,cAAQ,MAAM,wCAAwC,KAAK,IAAIA,CAAK,GACpE,KAAK,cAAc,IACnB,KAAK,aAAaA,CAAK;AAAA,IACzB;AAAA,EACF;AAAA,EAEQ,eAAe;AACrB,YAAQ,IAAI,wCAAwC,KAAK,EAAE;AAG3D,UAAMoV,IAAS,CAAC,CAAC,KAAK,QAAQ;AAiC9B,QAhCA,QAAQ,IAAI,wBAAwBA,GAAQ,OAAO,KAAK,EAAE,GAEtDA,MAEF,KAAK,QAAQ,kBAAkB,QAC/B,KAAK,QAAQ,cAAc,GAC3B,QAAQ,IAAI,+CAA+C,KAAK,EAAE,IAIpE,QAAQ,IAAI,kDAAkD,KAAK,EAAE,GACrE,KAAK,iBAAA,GAGAA,IAIH,QAAQ,IAAI,qDAAqD,KAAK,EAAE,KAHxE,QAAQ,IAAI,4CAA4C,KAAK,EAAE,GAC/D,KAAK,WAAA,IAMP,QAAQ;AAAA,MACN;AAAA,MACA,KAAK;AAAA,MACL;AAAA,MACA,KAAK,QAAQ;AAAA,MACb,KAAK,QAAQ;AAAA,IAAA,GAEf,KAAK,SAAS,KAAK,QAAQ,GAAI,KAAK,QAAQ,CAAE,GAG1C,KAAK,QAAQ,YAAY;AAC3B,YAAMh0B,IAAI,KAAK,QAAQ,OACjBhV,IAAI,KAAK,QAAQ,QAGjBipC,IAAO,KAAK,eAAuB,IAAA,KAAS,GAC5CC,IAAO,KAAK,eAAuB,IAAA,KAAS;AAGlD,WAAK,YAAY,KAAK,SAAS,OAAA,EAAS,KAAKl0B,GAAGhV,CAAC,EAAE,KAAKipC,GAAKC,CAAG,GAChE,KAAK,UAAU,IAAI,KAAK,QAAQ,UAAU,GAG1C,KAAK,uBAAuB,WAAW,MAAM;AAC3C,YAAI,KAAK,cAAc,CAAC,KAAK,UAAW;AACxC,cAAMC,IAAU,KAAK,UAAU,SAAA,EAAW,CAAC;AAC3C,YAAIA,GAAS;AAEX,cAAIrhB,IAAKqhB,EAAQ,KAAA;AACjB,kBAAQ,IAAI,6BAA6BrhB,GAAI,cAAc9S,GAAGhV,CAAC,IAG3D8nB,EAAG,SAAS,KAAKA,EAAG,UAAU,OAChCA,IAAK,KAAK,oBAAoB,KAAK,QAAQ,YAAa9S,GAAGhV,CAAC,GAC5D,QAAQ,IAAI,kCAAkC8nB,CAAE,IAG9CA,EAAG,QAAQ,KAAKA,EAAG,SAAS,KAE9B,KAAK,UAAU,QAAQA,EAAG,GAAGA,EAAG,GAAGA,EAAG,OAAOA,EAAG,MAAM,GAKtD,KAAK,UAAU,KAAK,aAAa,uBAAuB,MAAM,GAE9D,QAAQ;AAAA,YACN,2BAA2BA,EAAG,CAAC,KAAKA,EAAG,CAAC,KAAKA,EAAG,KAAK,KAAKA,EAAG,MAAM;AAAA,UAAA,MAGrE,QAAQ,IAAI,6DAA6D,GAEzE,KAAK,UAAU,QAAQ,GAAG,GAAG,IAAI,EAAE,GACnC,KAAK,UAAU,KAAK,aAAa,uBAAuB,MAAM;AAAA,QAElE;AAAA,MACF,GAAG,EAAE;AAAA,IACP;AAIA,UAAMshB,IAAmB,EAAE,GAAG,KAAK,QAAQ,aAAA;AAC3C,IAAI,KAAK,QAAQ,UAAU,aACzBA,EAAiB,sBAAsB,KAEzC,KAAK,eAAe,IAAIzV,GAAa,MAAMyV,CAAgB,GAG3D,KAAK,YAAY,IAAI9U,GAAU,MAAM,KAAK,QAAQ,SAAS,GAG3D,KAAK,gBAAgB,IAAIkE,GAAc,IAAI,GAG3C,KAAK,SAAS,IAAIO,GAAO,IAAI,GAG7B,KAAK,SAAS,IAAImB,GAAO,IAAI,GAG7B,KAAK,QAAQ,IAAIwB,GAAM,IAAI,GAG3B,KAAK,UAAU,IAAIqK,GAAQ,IAAI,GAG/B,KAAK,OAAO,IAAIM,GAAK,IAAI,GAGrB,KAAK,QAAQ,SACf,KAAK,OAAO;AAAA,MACV,KAAK,QAAQ;AAAA,MACb,KAAK,QAAQ;AAAA,MACb,KAAK,QAAQ;AAAA,IAAA,GAKb,KAAK,QAAQ,SAAS,QACxB,KAAK,QAAQ,MAAM,KAAK,QAAQ,QAAQ,MAAM,MAAM,GAElD,KAAK,QAAQ,SAAS,QACxB,KAAK,QAAQ,MAAM,KAAK,QAAQ,QAAQ,MAAM,MAAM,GAElD,KAAK,QAAQ,YAAY,QAC3B,KAAK,QAAQ,eAAe,KAAK,QAAQ,WAAW,MAAM,MAAM,GAE9D,KAAK,QAAQ,YAAY,QAC3B,KAAK,QAAQ,eAAe,KAAK,QAAQ,WAAW,MAAM,MAAM,GAI9D,KAAK,QAAQ,aAAa,CAAC,KAAK,QAAQ,YAC1C,KAAK,cAAA,GAIP,KAAK,uBAAA,GAGD,OAAO,KAAK,QAAQ,gBAAiB,cACvC,KAAK,QAAQ,aAAa,KAAK,UAAU,KAAK,OAAO,GAGlD2C,KACH,KAAK,kBAAA,GAIH,KAAK,QAAQ,QAAQ,iBACvB,KAAK,yBAAA,GAGP,QAAQ,IAAI,2CAA2C,KAAK,EAAE,GAG9D,KAAK,SAAS,KAAK,aAAa,cAAc,KAAK,QAAQ,QAAQ,cAAc;AAIjF,QAAI;AACD,WAAK,MAAc,kBAAkB,QAAA;AAAA,IACxC,QAAY;AAAA,IAEZ;AAGA,SAAK,oBAAA,GAGL,KAAK,cAAA;AAAA,EACP;AAAA,EAMO,sBAA4B;AACjC,QAAI;AACF,MAAI,KAAK,eACP,KAAK,WAAW,OAAA,GAChB,KAAK,aAAa;AAEpB,YAAM5sB,IAAY,KAAK,QAAQ;AAC/B,UAAI,CAACA,GAAM,QAAQ,CAACA,EAAK,KAAM;AAC/B,YAAMpH,IAAI,KAAK,QAAQ,SAAS,GAC1BhV,IAAI,KAAK,QAAQ,UAAU,GAC3B42B,IAAI;AAGV,UAAIzyB,IAAK6Q,IAAI4hB,IAAI,GACbxyB,IAAKwyB,IAAI;AACb,YAAMyS,IAAM,KAAK,QAAQ;AACzB,MAAI,KAAK,eAAe,KAAK,aAC3BllC,IAAK6Q,IAAI,MACT5Q,IAAKpE,IAAI,SACAqpC,MAAQ,YAAYA,MAAQ,eACrCllC,IAAK6Q,IAAI,MACT5Q,IAAKpE,IAAI;AAEX,YAAMspC,IAAQ,KAAK,SAAS,MAAA;AAC5B,MAAAA,EAAM,KAAK,aAAa,SAAS,iBAAiB,GAClDA,EAAM,KAAK,aAAa,SAAS,gBAAgB,GACjDA,EACG,OAAO1S,IAAI,CAAC,EACZ,KAAKzyB,IAAKyyB,GAAGxyB,IAAKwyB,CAAC,EACnB,KAAK,SAAS,EACd,OAAO,EAAE,OAAO,QAAQ,OAAO,KAAK;AAIvC,YAAM2S,IAAQ,SAAS,gBADZ,8BACgC,MAAM;AACjD,MAAAA,EAAM,aAAa,KAAK,OAAOplC,CAAE,CAAC,GAClColC,EAAM,aAAa,KAAK,OAAOnlC,CAAE,CAAC,GAClCmlC,EAAM,aAAa,eAAe,QAAQ,GAC1CA,EAAM,aAAa,qBAAqB,SAAS,GACjDA,EAAM,aAAa,eAAe,YAAY,GAC9CA,EAAM,aAAa,aAAa,IAAI,GACpCA,EAAM,aAAa,eAAe,MAAM,GACxCA,EAAM,aAAa,QAAQ,MAAM,GACjCA,EAAM,aAAa,kBAAkB,MAAM,GAC3CA,EAAM,cAAc,KACpBD,EAAM,KAAK,YAAYC,CAAK,GAC5BD,EAAM,GAAG,SAAS,CAACrlC,MAAW;AAC5B,QAAAA,EAAE,gBAAA,GACFA,EAAE,iBAAA,GACF,KAAK,OAAO,SAAA;AAAA,MACd,CAAC,GACD,KAAK,aAAaqlC;AAAA,IACpB,QAAY;AAAA,IAEZ;AAAA,EACF;AAAA,EAEQ,mBAAmB;AACzB,YAAQ;AAAA,MACN;AAAA,MACA,KAAK;AAAA,MACL;AAAA,MACA,KAAK,QAAQ;AAAA,IAAA;AAGf,UAAM;AAAA,MACJ,OAAA/wC;AAAA,MACA,QAAAC;AAAA,MACA,iBAAAgxC;AAAA,MACA,aAAAC;AAAA,MACA,aAAAC;AAAA,MACA,aAAAC;AAAA,MACA,eAAAC;AAAA,MACA,OAAAnnB;AAAA,MACA,YAAAqkB;AAAA,MACA,SAAArqB;AAAA,IAAA,IACE,KAAK,SAIHotB,IAAqF,EAAE,OAAOJ,GAAc,OAAOC,EAAA,GAEnHI,IAAO,KAAK,gBAAA;AAClB,IAAIA,MAAS,WACXD,EAAW,YAAYC,IAErBF,MAAkB,WACpBC,EAAW,UAAUD;AAIvB,UAAMG,IAAWlD,GAAiBpkB,GAAOqkB,CAAU;AAEnD,QAAIiD,GAAU;AAEZ,YAAMC,IAAS,KAAK,SACjB,SACA,KAAKzxC,GAAQC,CAAO;AAMvB,MADkB,OAAOsuC,KAAcrkB,KAAS,EAAE,EAAE,YAAA,MAClC,YAChBunB,EAAO,KAAK,aAAa,uBAAuB,MAAM;AAGxD,YAAM9jB,IAAS8jB,EACZ,KAAKD,EAAS,IAAI,EAClB,KAAKP,CAAgB,EACrB,OAAOK,CAAU;AAGpB,UAAI;AACF,cAAM/hB,IAAK5B,EAAO,KAAA;AAClB,QAAI4B,EAAG,QAAQ,KAAKA,EAAG,SAAS,IAC9BkiB,EAAO,QAAQliB,EAAG,GAAGA,EAAG,GAAGA,EAAG,OAAOA,EAAG,MAAM,IAE9CkiB,EAAO,QAAQD,EAAS,OAAO;AAAA,MAEnC,QAAQ;AACN,QAAAC,EAAO,QAAQD,EAAS,OAAO;AAAA,MACjC;AAEA,MAAIttB,MAAY,UACdyJ,EAAO,QAAQzJ,CAAO,GAKxB,KAAK,iBAAiButB,GAEtB,KAAK,cAAc9jB;AAGnB,UAAI;AACF,QAAAA,EAAO,KAAK,aAAa,6BAA6B,GAAG,GAIpD,KAAK,QAAQ,cAChBA,EAAO,KAAK,aAAa,mBAAmB,GAAG;AAAA,MAEnD,QAAY;AAAA,MAEZ;AAQA,UAAI;AACF,aAAK,eAAgB,KAAK,SACvB,KAAK3tB,GAAQC,CAAO,EACpB,KAAK,EAAE,OAAO,QAAQ,SAAS,EAAA,CAAG,EAClC,OAAO,EAAE,OAAO,GAAG,EACnB,KAAK,GAAG,CAAC,GACZ,KAAK,aAAa,KAAK,aAAa,qBAAqB,GAAG,GAC5D,KAAK,aAAa,KAAK,MAAM,gBAAgB;AAAA,MAC/C,QAAY;AAAA,MAEZ;AAAA,IACF,OAAO;AAIL,cADA,KAAK,cAAc,QACXiqB,GAAA;AAAA,QACN,KAAK,UAAU;AACb,gBAAM+F,IAAS,KAAK,IAAIjwB,GAAQC,CAAO,IAAI;AAC3C,eAAK,iBAAiB,KAAK,SACxB,OAAOgwB,IAAS,CAAC,EACjB,KAAKghB,CAAgB,EACrB,OAAOK,CAAU;AACpB;AAAA,QACF;AAAA,QACA,KAAK;AACH,eAAK,iBAAiB,KAAK,SACxB,QAAQtxC,GAAQC,CAAO,EACvB,KAAKgxC,CAAgB,EACrB,OAAOK,CAAU;AACpB;AAAA,QACF;AACE,eAAK,iBAAiB,KAAK,SACxB,KAAKtxC,GAAQC,CAAO,EACpB,KAAKgxC,CAAgB,EACrB,OAAOK,CAAU,EACjB,OAAO,CAAC;AACX;AAAA,MAAA;AAGJ,MAAIptB,MAAY,UACd,KAAK,eAAe,QAAQA,CAAO;AAAA,IAEvC;AAIA,IAAI+sB,KAAmB,OAAOA,CAAe,EAAE,SAAS,GAAG,KACzD,KAAK,eAAe,KAAK,eAAe,KAAK,gBAAgBA,CAAe,GAG9E,QAAQ;AAAA,MACN;AAAA,MACA,KAAK;AAAA,MACL;AAAA,MACA,KAAK;AAAA,IAAA;AAAA,EAET;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,SAAS/mB,GAAeqkB,GAA2B;AACxD,QAAI,CAAC,KAAK,YAAY,KAAK,UAAW;AACtC,UAAMmD,IACJ,CAAC,CAAC,KAAK,gBAAgB,KAAK,aAAa,UAAA;AAC3C,QAAI;AACF,MAAIA,KAAa,KAAK,aAAa,QAAA;AAAA,IACrC,QAAY;AAAA,IAEZ;AACA,QAAI;AACD,WAAK,gBAAwB,SAAA;AAAA,IAChC,QAAY;AAAA,IAEZ;AACA,SAAK,iBAAiB,QACtB,KAAK,cAAc;AACnB,QAAI;AACF,WAAK,cAAc,SAAA;AAAA,IACrB,QAAY;AAAA,IAEZ;AACA,SAAK,eAAe,QAEpB,KAAK,QAAQ,QAAQxnB,GAarB,KAAK,QAAQ,aAAaqkB,KAAcrkB,GAExC,KAAK,iBAAA;AAEL,QAAI;AACD,WAAK,gBAAwB,OAAA;AAAA,IAChC,QAAY;AAAA,IAEZ;AACA,QAAI;AACF,WAAK,WAAA;AAAA,IACP,QAAY;AAAA,IAEZ;AACA,SAAK,yBAAA;AAEL,QAAI;AACF,MAAIwnB,KAAa,KAAK,OAAO,8BAAA;AAAA,IAC/B,QAAY;AAAA,IAEZ;AAAA,EACF;AAAA,EAEQ,aAAa;AACnB,YAAQ,IAAI,qCAAqC,KAAK,EAAE;AAExD,UAAM,EAAE,MAAA5+B,GAAM,UAAAiQ,GAAU,YAAAge,GAAY,WAAAsB,GAAW,WAAAsP,GAAW,aAAAhP,MACxD,KAAK;AAEP,SAAK,cAAc,KAAK,SAAS,KAAK,KAAK,gBAAgB7vB,CAAK,CAAC,EAAE,KAAK;AAAA,MACtE,QAAQiuB;AAAA,MACR,MAAMhe;AAAA,MACN,MAAMsf;AAAA,MACN,SAASM;AAAA,IAAA,CACV,GAGD,KAAK,YAAY,KAAK;AAAA,MACpB,eAAe;AAAA,MACf,qBAAqB;AAAA,MACrB,cAAcgP,KAAa;AAAA,IAAA,CAC5B,GAED,QAAQ;AAAA,MACN;AAAA,MACA,KAAK;AAAA,MACL;AAAA,MACA,KAAK;AAAA,IAAA,GAEP,KAAK,WAAA,GACL,KAAK,gBAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,eAAqB;AAC1B,UAAMtsC,IAAU,KAAK,eAAe,KAAK;AACzC,IAAIA,GAAI,WAAW,KAAK,QAAQ,YAAY,UAC1CA,EAAG,QAAQ,KAAK,QAAQ,OAAO;AAAA,EAEnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,iBAAuB;AAC5B,QAAI,CAAC,KAAK,YAAa;AACvB,UAAM,EAAE,UAAA0d,GAAU,YAAAge,GAAY,WAAAsB,GAAW,WAAAsP,GAAW,aAAAhP,EAAA,IAClD,KAAK;AACP,SAAK,YAAY,KAAK;AAAA,MACpB,QAAQ5B;AAAA,MACR,MAAMhe;AAAA,MACN,MAAMsf;AAAA,MACN,SAASM;AAAA,IAAA,CACV,GACD,KAAK,YAAY,KAAK,cAAcgP,KAAa,IAAI,GAGjD,KAAK,QAAQ,QACf,KAAK,YAAY,KAAK,KAAK,gBAAgB,KAAK,QAAQ,IAAI,CAAC,GAE/D,KAAK,WAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,gBAAgBjxC,GAAWC,GAAqC;AACtE,UAAMgN,IAAO;AAAA,MACX,GAAAjN;AAAA,MACA,GAAAC;AAAA,MACA,OAAO,KAAK,QAAQ,SAAS;AAAA,MAC7B,QAAQ,KAAK,QAAQ,UAAU;AAAA,IAAA,GAE3BivC,IAAS,KAAK,MAAM,MAAM,SAC7B,OAAO,CAAC5/B,MAAYA,MAAM,IAAI,EAC9B,IAAI,CAACA,OAAa;AAAA,MACjB,GAAGA,EAAE,QAAQ,KAAK;AAAA,MAClB,GAAGA,EAAE,QAAQ,KAAK;AAAA,MAClB,OAAOA,EAAE,QAAQ,SAAS;AAAA,MAC1B,QAAQA,EAAE,QAAQ,UAAU;AAAA,IAAA,EAC5B;AACJ,WAAO2/B,GAAoBhiC,GAAMiiC,CAAM;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBQ,iBAAyB;AAC/B,UAAM1lB,IAAQ,OAAO,KAAK,QAAQ,SAAS,WAAW,EAAE,YAAA;AACxD,WAAIA,EAAM,SAAS,SAAS,IAAU,MAClCA,EAAM,SAAS,UAAU,IAAU,OACnCA,EAAM,SAAS,MAAM,IAAU,MAC/BA,EAAM,SAAS,SAAS,KAAKA,EAAM,SAAS,QAAQ,IAAU,OAC3D;AAAA,EACT;AAAA,EAEQ,gBAAgBpX,GAAsB;AAC5C,QAAI,CAACA,EAAM,QAAOA;AAClB,UAAM8+B,IAAW,KAAK;AAAA,MACpB;AAAA,OACC,KAAK,QAAQ,SAAS,OAAO,KAAK,mBAAmB;AAAA,IAAA,GAElD7uB,IAAW,KAAK,QAAQ,YAAY,IACpCge,IAAa,KAAK,QAAQ,cAAc;AAC9C,QAAI8Q,IAAW;AACf,QAAI;AAIF,MAAAA,KAFG,KAAa,mBACZ,KAAa,iBAAiB,SAAS,cAAc,QAAQ,IACpD,WAAW,IAAI,GACxBA,MAAKA,EAAI,OAAO,GAAG9uB,CAAQ,MAAMge,CAAU;AAAA,IACjD,QAAY;AACV,MAAA8Q,IAAM;AAAA,IACR;AACA,UAAMC,IAAU,CAACnyC,MACfkyC,IAAMA,EAAI,YAAYlyC,CAAC,EAAE,QAAQA,EAAE,SAASojB,IAAW,MACnD+kB,IAAgB,CAAA;AACtB,eAAWiK,KAAQ,OAAOj/B,CAAI,EAAE,MAAM;AAAA,CAAI,GAAG;AAC3C,YAAMw4B,IAAQyG,EAAK,MAAM,KAAK,EAAE,OAAO,OAAO;AAC9C,UAAI,CAACzG,EAAM,QAAQ;AACjB,QAAAxD,EAAI,KAAK,EAAE;AACX;AAAA,MACF;AACA,UAAI3K,IAAO;AACX,iBAAW6U,KAAQ1G,GAAO;AAGxB,YAAIwG,EAAQE,CAAI,IAAIJ,GAAU;AAC5B,UAAIzU,MACF2K,EAAI,KAAK3K,CAAI,GACbA,IAAO;AAET,cAAIqP,IAAQ;AACZ,qBAAWyF,KAAMD;AACf,YAAIxF,KAASsF,EAAQtF,IAAQyF,CAAE,IAAIL,KACjC9J,EAAI,KAAK0E,CAAK,GACdA,IAAQyF,KAERzF,KAASyF;AAGb,UAAA9U,IAAOqP;AACP;AAAA,QACF;AACA,cAAM0F,IAAO/U,IAAO,GAAGA,CAAI,IAAI6U,CAAI,KAAKA;AACxC,QAAI7U,KAAQ2U,EAAQI,CAAI,IAAIN,KAC1B9J,EAAI,KAAK3K,CAAI,GACbA,IAAO6U,KAEP7U,IAAO+U;AAAA,MAEX;AACA,MAAI/U,KAAM2K,EAAI,KAAK3K,CAAI;AAAA,IACzB;AACA,WAAO2K,EAAI,KAAK;AAAA,CAAI;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,kBAAwB;AAC9B,QAAI,CAAC,KAAK,eAAe,KAAK,UAAW;AACzC,QAAIqK,IAAa;AACjB,QAAI;AACF,MAAAA,IAAc,KAAK,YAAY,KAAa,UAAA,GAAa,UAAU;AAAA,IACrE,QAAY;AACV;AAAA,IACF;AACA,QAAI,CAACA,EAAY;AACjB,UAAMC,IAAS,KAAK,KAAKD,CAAU,IAAI;AACvC,IAAIC,KAAU,KAAK,QAAQ,UAAU,KAAK,KACxC,KAAK,QAAQ,KAAK,QAAQ,SAAS,KAAKA,CAAM;AAAA,EAElD;AAAA;AAAA,EAGO,aAAa;AAElB,QAAI,CAAC,KAAK,YAAa;AAEvB,UAAM,EAAE,OAAApyC,GAAO,QAAAC,GAAQ,YAAAqiC,GAAY,YAAAC,GAAY,YAAA8P,EAAA,IAAe,KAAK,SAG7DC,IAAU,KAAK,eAAuB,IAAA,KAAS,GAC/CC,IAAU,KAAK,eAAuB,IAAA,KAAS;AAIrD,QAAI7xC,IAAI4xC,IAAStyC,IAAS,KAAKqyC,GAAY,KAAK,IAC5C1xC,IAAI4xC,IAAStyC,IAAU,KAAKoyC,GAAY,KAAK;AAGjD,YAAQ/P,GAAA;AAAA,MACN,KAAK;AACH,QAAA5hC,IAAI4xC,IAAS,KAAKD,GAAY,KAAK,IACnC,KAAK,YAAY,KAAK,eAAe,OAAO;AAC5C;AAAA,MACF,KAAK;AACH,QAAA3xC,IAAI4xC,IAAStyC,IAAS,KAAKqyC,GAAY,KAAK,IAC5C,KAAK,YAAY,KAAK,eAAe,KAAK;AAC1C;AAAA,MACF;AACE,aAAK,YAAY,KAAK,eAAe,QAAQ;AAC7C;AAAA,IAAA;AAIJ,YAAQ9P,GAAA;AAAA,MACN,KAAK;AACH,QAAA5hC,IAAI4xC,IAAS,KAAKF,GAAY,KAAK,IACnC,KAAK,YAAY,KAAK,qBAAqB,SAAS;AACpD;AAAA,MACF,KAAK;AACH,QAAA1xC,IAAI4xC,IAAStyC,IAAU,KAAKoyC,GAAY,KAAK,IAC7C,KAAK,YAAY,KAAK,qBAAqB,MAAM;AACjD;AAAA,MACF;AACE,aAAK,YAAY,KAAK,qBAAqB,SAAS;AACpD;AAAA,IAAA;AAMJ,UAAMhH,IACJ,KAAK,YAAY,KAAK,mBAAmB,OAAO,GAAG,UAAU;AAC/D,QAAIA,IAAY,KAAK9I,MAAe,SAASA,MAAe,UAAU;AACpE,YAAMiQ,KAAc,KAAK,QAAQ,YAAY,MAAM;AACnD,MAAA7xC,MAAO0qC,IAAY,KAAKmH,IAAc;AAAA,IACxC;AAGA,SAAK,YAAY,KAAK,EAAE,GAAA9xC,GAAG,GAAAC,GAAG,GAM9B,KAAK,cAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,gBAAsB;AAC5B,QAAI,CAAC,KAAK,eAAe,KAAK,UAAW;AACzC,UAAM,IAAI,KAAK;AAEf,QAAI;AACF,QAAE,KAAK,aAAa,IAAI;AAAA,IAC1B,QAAY;AACV;AAAA,IACF;AACA,QAAI4uB;AACJ,QAAI;AACF,MAAAA,IAAM,EAAE,KAAa,QAAA;AAAA,IACvB,QAAY;AACV;AAAA,IACF;AACA,QAAI,CAACA,KAAMA,EAAG,SAAS,KAAKA,EAAG,UAAU,EAAG;AAI5C,UAAMgQ,IAAQ,KAAK,eAAA,GACbkT,KAAU,KAAK,QAAQ,SAAS,KAAKlT,IAAQ,IAC7CmT,KAAU,KAAK,QAAQ,UAAU,KAAKnT,IAAQ;AACpD,QAAIkT,KAAU,KAAKC,KAAU,EAAG;AAChC,QAAIrnB,IAAQ,KAAK,IAAIonB,IAASljB,EAAG,OAAOmjB,IAASnjB,EAAG,MAAM;AAC1D,QAAIlE,KAAS,MAAO;AACpB,IAAAA,IAAQ,KAAK,IAAIA,GAAO,GAAG;AAG3B,UAAMsnB,IAAMpjB,EAAG,IAAIA,EAAG,QAAQ,GACxBqjB,IAAMrjB,EAAG,IAAIA,EAAG,SAAS;AAC/B,QAAI;AACF,QAAE;AAAA,QACA;AAAA,QACA,aAAaojB,CAAG,IAAIC,CAAG,WAAWvnB,EAAM;AAAA,UACtC;AAAA,QAAA,CACD,eAAe,CAACsnB,CAAG,IAAI,CAACC,CAAG;AAAA,MAAA;AAAA,IAEhC,QAAY;AAAA,IAEZ;AAAA,EACF;AAAA,EAEQ,gBAAgB;AAErB,SAAK,SAAiB,UAAA,GAGvB,KAAK,SAAS,GAAG,kBAAkB,CAACniC,MAAe;AACjD,cAAQ,IAAI,+BAA+B,KAAK,EAAE,GAKlD,KAAK,QAAQ,EAAK;AAGlB,YAAMoiC,IAAsB,KAAK,MAAM,iBAAA,EAAmB,SAAS,IAAI,GAKjEC,IAAUriC,EAAM,QAAQ,SAASA,GACjCsiC,IACJD,GAAS,WAAWA,GAAS,WAAWA,GAAS;AAEnD,MAAKD,IAUH,QAAQ;AAAA,QACN;AAAA,QACA,KAAK;AAAA,MAAA,KAXP,QAAQ;AAAA,QACN;AAAA,QACA,KAAK;AAAA,QACL;AAAA,QACAE;AAAA,MAAA,GAGF,KAAK,MAAM,YAAY,CAAC,IAAI,GAAGA,CAAa,IAQ9C,KAAK,aAAa,IAClB,KAAK,wBAAwB,IAM7B,KAAK,sBAAA,GACL,KAAK,MAAM,mBAAA,EAAqB,QAAQ,CAAC/iC,MAAM;AAC7C,QAAIA,MAAM,QAAOA,EAAU,wBAAA;AAAA,MAC7B,CAAC;AAGD,YAAMkE,IAAY,KAAK,SAAS,UAAA;AAChC,WAAK,mBAAmB;AAAA,QACtB,YAAYA,EAAU,cAAc;AAAA,QACpC,YAAYA,EAAU,cAAc;AAAA,MAAA,GAMtC,KAAK,kBAAkB;AAAA,QACrB,GAAG,KAAK,QAAQ,KAAK;AAAA,QACrB,GAAG,KAAK,QAAQ,KAAK;AAAA,MAAA,GAKvB,KAAK,oBAAoB,KAAK,qBAAqBzD,CAAK,GAIxD,KAAK,qBAAqB,CAAA;AAC1B,UAAI;AACF,cAAMuiC,IAAmB,KAAK,MAAM,mBAAA,KAAwB,CAAA;AAC5D,YAAIA,EAAS,SAAS,KAAKA,EAAS,SAAS,IAAI;AAC/C,qBAAWxmC,KAASwmC;AAClB,YAAIxmC,MAAU,QACd,KAAK,mBAAmB,KAAK;AAAA,cAC3B,MAAMA;AAAA,cACN,GAAGA,EAAM,QAAQ,KAAK;AAAA,cACtB,GAAGA,EAAM,QAAQ,KAAK;AAAA,YAAA,CACvB;AAAA,MAGP,QAAY;AAAA,MAEZ;AACA,cAAQ,IAAI,0CAA0C,KAAK,kBAAkB,aAAa,KAAK,eAAe,GAI9G,KAAK,MAAM,wBAAwB,IAAI,GAEvC,KAAK,YAAA;AAAA,IACP,CAAC,GAED,KAAK,SAAS,GAAG,gBAAgB,CAACiE,MAAe;AAC/C,cAAQ,IAAI,6BAA6B,KAAK,EAAE;AAMhD,YAAMwiC,IAAM,KAAK,qBAAqBxiC,CAAK;AAC3C,UAAIwiC,KAAO,KAAK,qBAAqB,KAAK,iBAAiB;AACzD,cAAMlkC,IAAO,KAAK,MAAM,UAAA,KAAe,GACjCmkC,KAAOD,EAAI,IAAI,KAAK,kBAAkB,KAAKlkC,GAC3CokC,KAAOF,EAAI,IAAI,KAAK,kBAAkB,KAAKlkC;AACjD,aAAK,QAAQ,IAAI,KAAK,gBAAgB,IAAImkC,GAC1C,KAAK,QAAQ,IAAI,KAAK,gBAAgB,IAAIC;AAG1C,YAAIC,IAASF,GACTG,IAASF;AACb,cAAMG,IAAW,KAAK,MAAM,MAAM;AAAA,UAChC,KAAK,QAAQ;AAAA,UACb,KAAK,QAAQ;AAAA,QAAA;AASf,YAPIA,MACF,KAAK,QAAQ,IAAIA,EAAS,GAC1B,KAAK,QAAQ,IAAIA,EAAS,GAC1BF,IAASE,EAAS,IAAI,KAAK,gBAAgB,GAC3CD,IAASC,EAAS,IAAI,KAAK,gBAAgB,IAGzC,KAAK,MAAM,QAAQ,UAAU,eAAe;AAC9C,gBAAMC,IAAU,KAAK,gBAAgB,KAAK,QAAQ,GAAG,KAAK,QAAQ,CAAC;AACnE,eAAK,QAAQ,IAAIA,EAAQ,GACzB,KAAK,QAAQ,IAAIA,EAAQ,GACzBH,IAAS,KAAK,QAAQ,IAAI,KAAK,gBAAgB,GAC/CC,IAAS,KAAK,QAAQ,IAAI,KAAK,gBAAgB;AAAA,QACjD;AAEA,mBAAWG,KAAO,KAAK;AACrB,UAAAA,EAAI,KAAK,QAAQ,IAAIA,EAAI,IAAIJ,GAC7BI,EAAI,KAAK,QAAQ,IAAIA,EAAI,IAAIH,GAC7BG,EAAI,KAAK,yBAAA;AAAA,MAEb;AAGA,YAAMC,IAAgB,KAAK;AAC3B,WAAK,qBAAqB,CAAA;AAO1B,YAAMC,IAAW,KAAK,iBAChBC,IAAM,KACNC,IAAO,KAAK,QAAQ,KAAK,GACzBC,IAAO,KAAK,QAAQ,KAAK,GACzBC,IACJ,CAACJ,KACD,KAAK,IAAIE,IAAOF,EAAS,CAAC,IAAIC,KAC9B,KAAK,IAAIE,IAAOH,EAAS,CAAC,IAAIC,GAC1BI,IAAeN,EAAc;AAAA,QACjC,CAAC9zC,MACC,KAAK,KAAKA,EAAE,KAAK,QAAQ,KAAK,KAAKA,EAAE,CAAC,IAAIg0C,KAC1C,KAAK,KAAKh0C,EAAE,KAAK,QAAQ,KAAK,KAAKA,EAAE,CAAC,IAAIg0C;AAAA,MAAA,GAExCK,IAAgBF,KAAgBC;AAGtC,WAAK,mBAAmB,MACxB,KAAK,kBAAkB,MACvB,KAAK,oBAAoB,MAIzB,KAAK,yBAAA,GAKDC,KACF,KAAK,MAAM,YAAY,eAAe;AAAA,QACpC,aAAa;AAAA,UACXnF,EAAW,KAAK,OAAO;AAAA,UACvB,GAAG4E,EAAc,IAAI,CAAC9zC,MAAMkvC,EAAWlvC,EAAE,KAAK,OAAO,CAAC;AAAA,QAAA;AAAA,MACxD,CACD,GAIH,KAAK,oBAAoB,WAAW,MAAM;AACxC,YAAI,KAAK,WAAY;AACrB,aAAK,aAAa,IAGU,KAAK,MAC9B,iBAAA,EACA,SAAS,IAAI,KAUd,QAAQ;AAAA,UACN;AAAA,UACA,KAAK;AAAA,UACL;AAAA,QAAA,GAGF,KAAK,MAAM,4BAAA,MAbX,QAAQ;AAAA,UACN;AAAA,UACA,KAAK;AAAA,UACL;AAAA,QAAA,GAEF,KAAK,MAAM,YAAY,CAAC,IAAI,GAAG,EAAK,IAYtC,KAAK,MAAM,kBAAkB,IAAI,GAK7B,KAAK,sBAAoB,KAAK,sBAAA;AAAA,MACpC,GAAG,EAAE;AAAA,IACP,CAAC,GAOD,KAAK,SAAS,GAAG,iBAAiB,CAAC8Q,MAAe;AAChD,WAAK,aAAa;AAClB,YAAMwiC,IAAM,KAAK,qBAAqBxiC,CAAK;AAC3C,UAAIwiC,KAAO,KAAK,qBAAqB,KAAK,iBAAiB;AACzD,QAAAxiC,EAAM,iBAAA;AACN,cAAM1B,IAAO,KAAK,MAAM,UAAA,KAAe,GACjChD,KAAMknC,EAAI,IAAI,KAAK,kBAAkB,KAAKlkC,GAC1C/C,KAAMinC,EAAI,IAAI,KAAK,kBAAkB,KAAKlkC;AAChD,aAAK,QAAQ,IAAI,KAAK,gBAAgB,IAAIhD,GAC1C,KAAK,QAAQ,IAAI,KAAK,gBAAgB,IAAIC;AAK1C,YAAIioC,IAAQloC,GACRmoC,IAAQloC;AACZ,cAAMmoC,IAAU,KAAK,MAAM,MAAM;AAAA,UAC/B,KAAK,QAAQ;AAAA,UACb,KAAK,QAAQ;AAAA,QAAA;AASf,YAPIA,MACF,KAAK,QAAQ,IAAIA,EAAQ,GACzB,KAAK,QAAQ,IAAIA,EAAQ,GACzBF,IAAQE,EAAQ,IAAI,KAAK,gBAAgB,GACzCD,IAAQC,EAAQ,IAAI,KAAK,gBAAgB,IAGvC,KAAK,MAAM,QAAQ,UAAU,eAAe;AAC9C,gBAAMZ,IAAU,KAAK,gBAAgB,KAAK,QAAQ,GAAG,KAAK,QAAQ,CAAC;AACnE,eAAK,QAAQ,IAAIA,EAAQ,GACzB,KAAK,QAAQ,IAAIA,EAAQ,GACzBU,IAAQ,KAAK,QAAQ,IAAI,KAAK,gBAAgB,GAC9CC,IAAQ,KAAK,QAAQ,IAAI,KAAK,gBAAgB;AAAA,QAChD;AACA,aAAK,yBAAA;AAEL,mBAAWV,KAAO,KAAK;AACrB,UAAAA,EAAI,KAAK,QAAQ,IAAIA,EAAI,IAAIS,GAC7BT,EAAI,KAAK,QAAQ,IAAIA,EAAI,IAAIU,GAC7BV,EAAI,KAAK,yBAAA;AAIX,YAAI;AACD,eAAK,MAAc,kBAAkB,QAAA;AAAA,QACxC,QAAY;AAAA,QAEZ;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,qBAAqB/iC,GAA6C;AACxE,UAAM6T,IAAM7T,GAAO,QAAQ,SAASA;AACpC,QAAI,CAAC6T,EAAK,QAAO;AACjB,UAAM6W,IACJ7W,EAAI,UAAU,CAAC,KAAKA,EAAI,iBAAiB,CAAC,KAAKA;AACjD,WAAI,OAAO6W,EAAG,WAAY,YAAY,OAAOA,EAAG,WAAY,WACnD,EAAE,GAAGA,EAAG,SAAS,GAAGA,EAAG,QAAA,IAEzB;AAAA,EACT;AAAA,EAEO,SACLz6B,GACAC,GACA0U,GACAqB,GACAc,GACA;AACA,YAAQ;AAAA,MACN;AAAA,MACA,KAAK;AAAA,MACL;AAAA,MACA9W;AAAA,MACA;AAAA,MACAC;AAAA,MACA;AAAA,MACA6W;AAAA,IAAA;AAGF,UAAMknB,IAAS,KAAK,QAAQ,KAAKh+B,GAC3B0zC,IAAS,KAAK,QAAQ,KAAKzzC;AAWjC,QAVA,KAAK,QAAQ,IAAID,GACjB,KAAK,QAAQ,IAAIC,GAGf,CAAC,CAAC6W,KACFA,IAAW,KACX,OAAO,wBAA0B,OACjC,OAAO,cAAgB,QACtBknB,MAAWh+B,KAAK0zC,MAAWzzC,IAEd;AAOd,YAAM0zC,IAAK,YAAY,IAAA,GACjBr9B,IAAO,MAAM;AACjB,YAAI,KAAK,cAAc,CAAC,KAAK,SAAU;AACvC,cAAMlQ,IAAI,KAAK,IAAI,IAAI,YAAY,IAAA,IAAQutC,KAAO78B,CAAmB,GAE/D9L,IAAI5E,IAAI,MAAM,IAAIA,IAAIA,IAAI,IAAI,KAAK,IAAI,KAAKA,IAAI,GAAG,CAAC,IAAI;AAC9D,aAAK,QAAQ,IAAI43B,KAAUh+B,IAAIg+B,KAAUhzB,GACzC,KAAK,QAAQ,IAAI0oC,KAAUzzC,IAAIyzC,KAAU1oC,GACzC,KAAK,yBAAA,GACD5E,IAAI,IACN,sBAAsBkQ,CAAI,KAE1B,KAAK,QAAQ,IAAItW,GACjB,KAAK,QAAQ,IAAIC,GACjB,KAAK,yBAAA,GACD0U,KAAUA,EAAA;AAAA,MAElB;AACA,4BAAsB2B,CAAI;AAAA,IAC5B;AAEE,WAAK,yBAAA,GACD3B,KAAUA,EAAA;AAAA,EAElB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASO,QAAQkI,IAAU,IAAM;AAC7B,SAAK,SAAS,MAAA,GACVA,UAAc,MAAM,YAAY,iBAAiB,EAAE,IAAI,KAAK,IAAI;AAAA,EACtE;AAAA;AAAA,EAGO,OAAOA,IAAU,IAAM;AAC5B,SAAK,SAAS,KAAA,GACVA,UAAc,MAAM,YAAY,gBAAgB,EAAE,IAAI,KAAK,IAAI;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASO,gBACL+2B,GACAC,IAA4C,cACtC;AAEN,QADA,KAAK,kBAAA,GACD,CAACD,KAASA,IAAQ,KAAK,CAAC,KAAK,SAAU;AAC3C,UAAM73B,IAAI,KAAK,QAAQ,SAAS,KAC1BhV,IAAI,KAAK,QAAQ,UAAU,KAC3B5B,IAAI;AAKV,QAAI+F,IAAK6Q,IAAI,GACT5Q,IAAK;AACT,UAAMilC,IAAM;AAAA,MACV,KAAK,QAAQ,cAAc,KAAK,QAAQ,SAAS;AAAA,IAAA,EACjD,YAAA;AACF,IAAI,KAAK,aAEPllC,IAAK6Q,IAAI,MACT5Q,IAAKpE,IAAI,QACAqpC,MAAQ,YAAYA,MAAQ,aAErCllC,IAAK6Q,IAAI,MACT5Q,IAAKpE,IAAI,QAET,KAAK,eACLqpC,MAAQ,eACRA,MAAQ,uBAIRllC,IAAK6Q,IAAI,MACT5Q,IAAKpE,IAAI;AAEX,UAAMP,IACJqtC,MAAS,aACL,YACAA,MAAS,UACT,YACA,WACAxD,IAAQ,KAAK,SAAS,MAAA,EAAQ,SAAS,eAAe;AAC5D,IAAAA,EAAM,OAAOlrC,IAAI,CAAC,EAAE,OAAO+F,GAAIC,CAAE,EAAE,KAAK3E,CAAK,EAAE,OAAO;AAAA,MACpD,OAAO;AAAA,MACP,OAAO;AAAA,IAAA,CACR;AACD,UAAMstC,IAAQF,IAAQ,KAAK,QAAQ,OAAOA,CAAK;AAC/C,IAAAvD,EACG,KAAKyD,CAAK,EACV,KAAK;AAAA,MACJ,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,QAAQ;AAAA,IAAA,CACT,EACA,KAAK,SAAS,EACd,OAAO5oC,GAAIC,CAAE,EACb,KAAK,MAAM,QAAQ,GACtBklC,EAAM,KAAK,kBAAkB,MAAM,GAClC,KAAa,gBAAgBA,GAG7B,KAAa,qBAAqB,EAAE,OAAAuD,GAAO,MAAAC,EAAA;AAAA,EAC9C;AAAA;AAAA,EAGO,oBAA0B;AAC/B,UAAM7tC,IAAK,KAAa;AACxB,QAAIA,GAAG;AACL,UAAI;AACF,QAAAA,EAAE,OAAA;AAAA,MACJ,QAAQ;AAAA,MAER;AACC,WAAa,gBAAgB;AAAA,IAChC;AACC,SAAa,qBAAqB;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,SAAS;AAEd,IAAI,KAAK,kBAAkB,cACzB,KAAK,kBAAkB,UAAU,OAAA,GACjC,KAAK,kBAAkB,YAAY,SAGjC,KAAK,mBAAmB,cAC1B,KAAK,kBAAkB,UAAU,OAAA,GACjC,KAAK,kBAAkB,YAAY,SAKrC,KAAK,YAAA,GAEL,KAAK,SAAS,OAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,UAAgB;AACrB,SAAK,aAAa,IAGd,KAAK,yBAAyB,SAChC,aAAa,KAAK,oBAAoB,GACtC,KAAK,uBAAuB,OAE1B,KAAK,sBAAsB,SAC7B,aAAa,KAAK,iBAAiB,GACnC,KAAK,oBAAoB,OAEvB,KAAK,6BAA6B,SACpC,aAAa,KAAK,wBAAwB,GAC1C,KAAK,2BAA2B,OAE9B,KAAK,sBAAsB,SAC7B,aAAa,KAAK,iBAAiB,GACnC,KAAK,oBAAoB,OAIvB,KAAK,gBAAgB,KAAK,aAAa,eACzC,KAAK,aAAa,QAAA,GAEhB,KAAK,aAAc,KAAK,UAAkB,YAC5C,KAAK,UAAU,QAAA,GAEb,KAAK,kBACP,KAAK,cAAc,QAAA,GACnB,KAAK,cAAc,UAAA,IAIjB,KAAK,kBAAkB,cACzB,KAAK,kBAAkB,UAAU,OAAA,GACjC,KAAK,kBAAkB,YAAY,SAGjC,KAAK,mBAAmB,cAC1B,KAAK,kBAAkB,UAAU,OAAA,GACjC,KAAK,kBAAkB,YAAY,SAIrC,KAAK,SAAS,OAAA,GACd,KAAK,aAAa;AAAA,EACpB;AAAA;AAAA,EAGO,OAAO;AACZ,SAAK,SAAS,KAAA;AAAA,EAChB;AAAA;AAAA,EAGO,OAAO;AACZ,SAAK,SAAS,KAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,QAAQoM,GAAc;AAE3B,QAAI,CAAC,KAAK,YAAa;AAEvB,UAAM2hC,IAAU,KAAK,QAAQ,SAAS3hC;AACtC,SAAK,QAAQ,OAAOA,GACpB,KAAK,YAAY,KAAK,KAAK,gBAAgBA,CAAI,CAAC,GAChD,KAAK,WAAA,GACL,KAAK,gBAAA,GAEL,KAAK,SAAS,KAAK,aAAa,cAAcA,KAAQ,cAAc,GAChE2hC,KACF,KAAK,MAAM,YAAY,qBAAqB,EAAE,IAAI,KAAK,IAAI,MAAA3hC,GAAM;AAAA,EAErE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,QAAQ9S,GAAeC,GAAgB;AAC5C,QAAI,KAAK,QAAQ,UAAU,UAAU;AACnC,YAAMy0C,IAAW,KAAK,IAAI10C,GAAOC,CAAM;AACvC,MAAAD,IAAQ00C,GACRz0C,IAASy0C;AAAA,IACX;AAKA,QAJA,KAAK,QAAQ,QAAQ10C,GACrB,KAAK,QAAQ,SAASC,GAGlB,KAAK,0BAA0Bsb;AACjC,WAAK,eAAe,KAAKvb,GAAOC,CAAM;AAAA,aAC7B,KAAK,0BAA0BmjB,IAAQ;AAEhD,YAAMsxB,IAAW,KAAK,IAAI10C,GAAOC,CAAM;AACvC,WAAK,eAAe,KAAKy0C,GAAUA,CAAQ,GAE3C,KAAK,QAAQ,QAAQA,GACrB,KAAK,QAAQ,SAASA;AAAA,IACxB,WAAW,KAAK,0BAA0B9/B;AACxC,WAAK,eAAe,KAAK5U,GAAOC,CAAM;AAAA;AAGtC,UAAI;AACD,aAAK,eAAuB,OAAOD,GAAOC,CAAM;AAAA,MACnD,SAAS00C,GAAG;AACV,gBAAQ,KAAK,6DAA6DA,CAAC;AAAA,MAC7E;AAIF,QAAI,KAAK,WAAW;AAClB,YAAMjE,IAAO,KAAK,eAAuB,IAAA,KAAS,GAC5CC,IAAO,KAAK,eAAuB,IAAA,KAAS;AAGlD,WAAK,UAAU,KAAK3wC,GAAOC,CAAM,EAAE,KAAKywC,GAAKC,CAAG;AAAA,IAClD;AAIA,QAAI,KAAK;AACP,UAAI;AACF,aAAK,aAAa,KAAK3wC,GAAOC,CAAM;AAAA,MACtC,QAAY;AAAA,MAEZ;AAMF,IAAI,KAAK,eAAe,KAAK,QAAQ,QACnC,KAAK,YAAY,KAAK,KAAK,gBAAgB,KAAK,QAAQ,IAAI,CAAC,GAE/D,KAAK,WAAA,GAID,KAAK,cAAY,KAAK,oBAAA;AAG1B,UAAM20C,IAAO,KAAa;AAC1B,IAAIA,KAAK,KAAK,gBAAgBA,EAAI,OAAOA,EAAI,IAAI;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaQ,eAAevvC,GAAS6B,GAAsB;AACpD,QAAI,CAAC7B,GAAI,QAAQ,CAAC6B,EAAO;AACzB,UAAM2tC,IAAQ,OAAO3tC,CAAK,EAAE,MAAM,GAAG,EAAE,OAAO,OAAO;AACrD,QAAI2tC,EAAM,UAAU;AAClB,UAAI;AACF,cAAMC,IAAQ,KAAK,SAAiB,SAAS,UAAU,CAACpU,MAAa;AACnE,UAAAA,EAAI,KAAK,GAAGmU,EAAM,CAAC,CAAC,GACpBnU,EAAI,KAAK,GAAGmU,EAAMA,EAAM,SAAS,CAAC,CAAC;AAAA,QACrC,CAAC;AACD,QAAAxvC,EAAG,KAAKyvC,CAAI;AACZ;AAAA,MACF,QAAY;AAAA,MAEZ;AAEF,IAAAzvC,EAAG,KAAKwvC,EAAM,CAAC,KAAK3tC,CAAK;AAAA,EAC3B;AAAA,EAEO,UAAU+pC,GAA0BC,GAAsB;AAE/D,UAAM6D,IAAe,KAAK,eAAe,KAAK;AAC9C,QAAI9D,GAAiB;AACnB,WAAK,QAAQ,kBAAkBA,GAC/B,KAAK,eAAe8D,GAAS9D,CAAe;AAK5C,YAAM+D,IAAK,OAAO,KAAK,QAAQ,aAAa,EAAE,EAAE,YAAA,GAC1CC,IAAa;AAAA,QACjB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA,EACA,SAASD,CAAE,GAIPE,IAAc,KAAK,QAAQ,aAAa;AAC9C,UACED,KACA,KAAK,eACLhE,EAAgB,WAAW,GAAG,KAC9BtG,GAAcuK,GAAajE,CAAe,IAAI,GAC9C;AACA,cAAMkE,IAAQ3L,GAAayH,CAAe;AAC1C,aAAK,QAAQ,YAAYkE;AACzB,YAAI;AACF,eAAK,YAAY,KAAK,EAAE,MAAMA,GAAO;AAAA,QACvC,QAAY;AAAA,QAEZ;AAAA,MACF;AAAA,IACF;AAEA,IAAIjE,MACF,KAAK,QAAQ,cAAcA,GAC3B6D,EAAQ,OAAO,EAAE,OAAO7D,EAAA,CAAa,KAGnCD,KAAmBC,MAErB,KAAK,MAAM,YAAY,sBAAsB;AAAA,MAC3C,IAAI,KAAK;AAAA,MACT,OAAO,KAAK,QAAQ;AAAA,MACpB,aAAa,KAAK,QAAQ;AAAA,IAAA,CAC3B;AAAA,EAEL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,cAAoB;AAEzB,UAAMvjC,IAAY,KAAK,eAAe,KAAK;AAC3C,QAAI,CAACA,KAAQ,OAAOA,EAAK,UAAW,WAAY;AAChD,UAAM,EAAE,aAAAujC,GAAa,aAAAC,GAAa,eAAAE,EAAA,IAAkB,KAAK,SACnDC,IAKF,EAAE,WAAW,KAAK,kBAAgB;AACtC,IAAIJ,QAAwB,QAAQA,IAChCC,MAAgB,WAAWG,EAAW,QAAQH,IAC9CE,MAAkB,WAAWC,EAAW,UAAUD,IACtD1jC,EAAK,OAAO2jC,CAAU;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,kBAA0B;AAChC,UAAM,EAAE,aAAAF,GAAa,aAAAD,EAAA,IAAgB,KAAK,SACpC10B,IAAI00B,KAAe,GACnBI,IAAiC;AAAA,MACrC,KAAK,CAAC,GAAG,CAAC;AAAA,MACV,QAAQ,CAAC,GAAG,CAAC;AAAA,MACb,KAAK,CAAC,GAAG,CAAC;AAAA,MACV,QAAQ,CAAC,GAAG,CAAC;AAAA,MACb,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,MAClB,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,IAAA;AAEpB,WAAOH,KAAeG,EAAKH,CAAW,IAClCG,EAAKH,CAAW,EAAE,IAAI,CAACphC,MAAMA,IAAIyM,CAAC,EAAE,KAAK,GAAG,IAC5C;AAAA,EACN;AAAA;AAAA,EAGO,OAAO;AACZ,SAAK,QAAQ,WAAW,IACxB,KAAK,QAAQ,YAAY,IACpB,KAAK,SAAiB,aACxB,KAAK,SAAiB,UAAU,EAAK,GAGxC,KAAK,oBAAA;AAAA,EACP;AAAA;AAAA,EAGO,SAAS;AACd,SAAK,QAAQ,WAAW,IACxB,KAAK,QAAQ,YAAY,IACzB,KAAK,cAAA,GAEL,KAAK,mBAAA;AAAA,EACP;AAAA;AAAA;AAAA,EAIO,qBAAqB;AAE1B,YAAQ;AAAA,MACN;AAAA,MACA,KAAK;AAAA,MACL;AAAA,IAAA,GAEF,KAAK,MAAM,uBAAuB,IAAI;AAAA,EACxC;AAAA;AAAA,EAGO,sBAAsB;AAE3B,YAAQ;AAAA,MACN;AAAA,MACA,KAAK;AAAA,MACL;AAAA,IAAA,GAEF,KAAK,MAAM,wBAAwB,IAAI;AAAA,EACzC;AAAA;AAAA,EAGO,eAAe;AACpB,SAAK,aAAa,cAAc,EAAE,eAAe,IAAM;AAAA,EAEzD;AAAA;AAAA,EAGO,gBAAgB;AACrB,SAAK,aAAa,cAAc,EAAE,eAAe,IAAO;AAAA,EAE1D;AAAA;AAAA,EAGO,eAAe;AACpB,SAAK,aAAa,cAAc,EAAE,eAAe,IAAM;AAAA,EAEzD;AAAA;AAAA,EAGO,gBAAgB;AACrB,SAAK,aAAa,cAAc,EAAE,eAAe,IAAO;AAAA,EAE1D;AAAA,EAEO,wBAAiC;AACtC,WAAO,KAAK,aAAa,UAAA;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,YAAY9I,GAAe6D,GAAmB;AACnD,IAAK,KAAK,QAAQ,WAChB,KAAK,QAAQ,SAAS,EAAE,eAAe,EAAA;AAEzC,UAAM8E,IAAQ,KAAK,QAAQ,OAAO,iBAAiB;AAQnD,QANE,CAAC,CAAC9E,KACFA,IAAW,KACX,OAAO,wBAA0B,OACjC,OAAO,cAAgB,OACvB8E,MAAU3I,GAEI;AAGd,YAAM1L,IAAQ0L,IAAQ2I,GAChB+3B,IAAK,YAAY,IAAA,GACjBr9B,IAAO,MAAM;AACjB,YAAI,KAAK,cAAc,CAAC,KAAK,YAAY,CAAC,KAAK,QAAQ,OAAQ;AAC/D,cAAMlQ,IAAI,KAAK,IAAI,IAAI,YAAY,IAAA,IAAQutC,KAAO78B,CAAmB,GAC/D9L,IAAI5E,IAAI,MAAM,IAAIA,IAAIA,IAAI,IAAI,KAAK,IAAI,KAAKA,IAAI,GAAG,CAAC,IAAI;AAC9D,aAAK,QAAQ,OAAO,gBAAgBwV,IAAQrU,IAAQyD,GACpD,KAAK,yBAAA,GACD5E,IAAI,IACN,sBAAsBkQ,CAAI,KAE1B,KAAK,QAAQ,OAAO,gBAAgBrD,GACpC,KAAK,yBAAA;AAAA,MAET;AACA,4BAAsBqD,CAAI;AAAA,IAC5B;AACE,WAAK,QAAQ,OAAO,gBAAgBrD,GACpC,KAAK,yBAAA;AAAA,EAET;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,2BAA2B;AACjC,QAAI,CAAC,KAAK,SAAU;AACpB,UAAMjT,IAAI,KAAK,QAAQ,KAAK,GACtBC,IAAI,KAAK,QAAQ,KAAK,GACtB8b,IAAI,KAAK,QAAQ,SAAS,GAC1BhV,IAAI,KAAK,QAAQ,UAAU,GAC3BkM,IAAQ,KAAK,QAAQ,QAAQ,iBAAiB;AAUpD,QACE,OAAO,KAAK,SAAS,MAAM,mBAAoB,cAC/C,OAAO,KAAK,SAAS,QAAS;AAE9B,UAAI;AACF,aAAK,SAAS,KAAK,gBAAgB,WAAW;AAC9C,cAAM4b,IAAK,KAAK,SAAS,KAAA;AACzB,QAAIA,MAAO,KAAK,IAAIA,EAAG,CAAC,IAAI,QAAQ,KAAK,IAAIA,EAAG,CAAC,IAAI,SACnD,KAAK,SAAS,SAAA,EAAW,QAAQ,CAAC9L,MAAe;AAC/C,UAAI,OAAOA,GAAO,SAAU,cAAYA,EAAM,MAAM,CAAC8L,EAAG,GAAG,CAACA,EAAG,CAAC;AAAA,QAClE,CAAC;AAAA,MAEL,SAAS7jB,GAAG;AACV,gBAAQ,KAAK,2CAA2CA,CAAC;AAAA,MAC3D;AAUF,QAAI;AACF,YAAM0pC,IAAqB,CAAC/vC,MAAqB;AAC/C,YAAI,CAACA,GAAI,MAAM,gBAAiB,QAAO;AACvC,cAAMgwC,IAAK,OAAOhwC,EAAG,aAAc,aAAaA,EAAG,cAAc;AACjE,eAAIgwC,KAAM,KAAK,IAAIA,EAAG,UAAU,CAAC,IAAI,QACnChwC,EAAG,KAAK,gBAAgB,WAAW,GAC5B,MAEF;AAAA,MACT,GACMiwC,IAAeF,EAAmB,KAAK,WAAW;AACxD,MAAAA,EAAmB,KAAK,SAAS,GAC7BE,KAAgB,OAAO,KAAK,cAAe,cAC7C,KAAK,WAAA;AAAA,IAET,QAAY;AAAA,IAEZ;AAQA,UAAMhwC,IAAIqO,IACN,aAAajT,CAAC,IAAIC,CAAC,YAAYgT,CAAK,IAAI8I,IAAI,CAAC,IAAIhV,IAAI,CAAC,MACtD,aAAa/G,CAAC,IAAIC,CAAC;AACvB,SAAK,SAAS,KAAK,aAAa,aAAa2E,CAAC;AAQ9C,QAAI;AACF,WAAK,SAAS,OAAO,WAAW;AAAA,IAClC,QAAY;AAAA,IAEZ;AAMA,QAAI;AACF,OAAK,KAAK,MAAc,kBAAmB,KAAK,MAAc,2BAC3D,KAAK,MAAc,eAAA;AAAA,IAExB,QAAY;AAAA,IAEZ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWO,sBAAsB;AAC3B,UAAM0V,IAAQ,CAAC3V,MAAY;AACzB,UAAI;AACF,QAAIA,GAAI,MAAM,mBAAiBA,EAAG,KAAK,gBAAgB,WAAW;AAAA,MACpE,QAAY;AAAA,MAEZ;AAAA,IACF;AACA,IAAA2V,EAAM,KAAK,cAAc,GACzBA,EAAM,KAAK,WAAW,GACtBA,EAAM,KAAK,SAAS,GACpB,KAAK,yBAAA,GACD,KAAK,eAAa,KAAK,WAAA;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,cAAsB;AAK3B,QAAI,KAAK,QAAQ,QAAQ,kBAAkB,UAAa,KAAK,QAAQ,OAAO,kBAAkB;AAC5F,aAAO,KAAK,QAAQ,OAAO;AAO7B,QAAI,KAAK;AACP,UAAI;AACF,cAAMu6B,IAAkB,KAAK,SAAiB,UAAA;AAC9C,YAAIA,KAAkB,OAAOA,EAAe,SAAW,OAAeA,EAAe,WAAW;AAC9F,iBAAOA,EAAe;AAAA,MAE1B,SAAS7pC,GAAG;AACV,gBAAQ,KAAK,+DAA+DA,CAAC;AAAA,MAC/E;AAIF,QAAI,KAAK;AACP,UAAI;AACF,cAAMwI,IAAa,KAAK,eAAuB,UAAA;AAC/C,YAAIA,KAAa,OAAOA,EAAU,WAAa;AAC7C,iBAAOA,EAAU;AAEnB,YAAIA,KAAa,OAAOA,EAAU,SAAW;AAC3C,iBAAOA,EAAU;AAAA,MAErB,SAASxI,GAAG;AACV,gBAAQ,KAAK,qEAAqEA,CAAC;AAAA,MACrF;AAGF,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAIO,kBAAkB;AACvB,SAAK,UAAU,OAAA;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,+BAA+B8pC,GAAmC;AACvE,YAAQ;AAAA,MACN;AAAA,MACA,KAAK;AAAA,IAAA,GAIP,KAAK,UAAU,OAAA;AAGf,UAAMC,IAAW,KAAK;AACtB,QAAIA,KAAY,OAAOA,EAAS,eAAgB;AAO9C,UANA,QAAQ;AAAA,QACN;AAAA,QACA,KAAK;AAAA,MAAA,GAIHD;AAEF,YAAI;AAEF,gBAAME,IAAiBD,EAAS,YAAY,CAAA,GAAIA,CAAQ;AACxD,UACEC,KACA,OAAOA,EAAe,mBAAoB,cAE1C,QAAQ;AAAA,YACN;AAAA,YACA,KAAK;AAAA,UAAA,GAIP,KAAK,wBAAA,GAGLA,EAAe,gBAAA,GAGXA,EAAe,aAAaA,EAAe,UAAU,UACvDA,EAAe,UAAU,OAAA,KAG3B,QAAQ;AAAA,YACN;AAAA,YACA,KAAK;AAAA,UAAA;AAAA,QAGX,SAASra,GAAO;AACd,kBAAQ;AAAA,YACN;AAAA,YACAA;AAAA,UAAA;AAAA,QAEJ;AAAA;AAGF,cAAQ,IAAI,oDAAoD,KAAK,EAAE;AAAA,EAE3E;AAAA;AAAA,EAGO,mBAAmB;AACxB,SAAK,UAAU,QAAA;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcO,UAAUW,GAAiBC,GAAyB;AACzD,WAAO,KAAK,UAAU,UAAUD,GAAYC,CAAiB;AAAA,EAC/D;AAAA,EAEO,eAAeD,GAA0B;AAC9C,WAAO,KAAK,UAAU,eAAeA,CAAU;AAAA,EACjD;AAAA,EAEO,gBAAsB;AAC3B,SAAK,UAAU,cAAA;AAAA,EACjB;AAAA;AAAA,EAGO,iBAAiB;AACtB,WAAO,KAAK,UAAU,eAAA;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,cAAchE,GAAsB;AACzC,WAAO,KAAK,UAAU,cAAcA,CAAY;AAAA,EAClD;AAAA,EAEO,qBAA8B;AACnC,WAAO,KAAK,UAAU,UAAA;AAAA,EACxB;AAAA,EAEQ,oBAAoB;AAC1B,SAAK,WAAA;AAAA,EACP;AAAA,EAEQ,oBACN2d,GACA31C,GACAC,GACyD;AAEzD,UAAM21C,IAAeD,EAAW,MAAM,0BAA0B;AAChE,QAAIC,GAAc;AAChB,YAAMC,IAAgBD,EAAa,CAAC,EAAE,MAAM,KAAK,EAAE,IAAI,MAAM;AAC7D,UAAIC,EAAc,WAAW;AAC3B,eAAO;AAAA,UACL,GAAGA,EAAc,CAAC;AAAA,UAClB,GAAGA,EAAc,CAAC;AAAA,UAClB,OAAOA,EAAc,CAAC;AAAA,UACtB,QAAQA,EAAc,CAAC;AAAA,QAAA;AAAA,IAG7B;AAGA,UAAMC,IAAaH,EAAW,MAAM,wBAAwB,GACtDI,IAAcJ,EAAW,MAAM,yBAAyB;AAE9D,QAAIG,KAAcC,GAAa;AAC7B,YAAMC,IAAW,SAASF,EAAW,CAAC,CAAC,GACjCG,IAAY,SAASF,EAAY,CAAC,CAAC;AACzC,UAAI,CAAC,MAAMC,CAAQ,KAAK,CAAC,MAAMC,CAAS;AACtC,eAAO,EAAE,GAAG,GAAG,GAAG,GAAG,OAAOD,GAAU,QAAQC,EAAA;AAAA,IAElD;AAGA,WAAO,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,IAAI,QAAQ,GAAA;AAAA,EAC1C;AAAA;AAAA,EAGQ,yBAAyB;AAI/B,SAAK,SAAS,GAAG,YAAY,CAACxlC,MAAe;AAC3C,MAAI,KAAK,qBAAqBA,EAAM,MAAM,KAC1C,KAAK,sBAAA;AAAA,IACP,CAAC;AAGD,QAAIylC,IAAsD;AAC1D,UAAMC,IAAkB;AAExB,SAAK,SAAS,GAAG,eAAe,CAAC1lC,MAAe;AAE9C,UAAI,KAAK,qBAAqBA,EAAM,MAAM,GAAG;AAC3C,gBAAQ;AAAA,UACN;AAAA,QAAA;AAEF;AAAA,MACF;AAGA,MAAAylC,IAAqB;AAAA,QACnB,GAAGzlC,EAAM,WAAWA,EAAM,QAAQ,KAAK;AAAA,QACvC,GAAGA,EAAM,WAAWA,EAAM,QAAQ,KAAK;AAAA,MAAA;AAAA,IAE3C,CAAC,GAED,KAAK,SAAS,GAAG,aAAa,CAACA,MAAe;AAE5C,UAAI,KAAK,qBAAqBA,EAAM,MAAM,GAAG;AAC3C,gBAAQ;AAAA,UACN;AAAA,QAAA,GAEFylC,IAAqB;AACrB;AAAA,MACF;AAEA,UAAIA,GAAoB;AACtB,cAAME,IAAc;AAAA,UAClB,GAAG3lC,EAAM,WAAWA,EAAM,QAAQ,KAAK;AAAA,UACvC,GAAGA,EAAM,WAAWA,EAAM,QAAQ,KAAK;AAAA,QAAA;AAQzC,YALiB,KAAK;AAAA,UACpB,KAAK,IAAI2lC,EAAY,IAAIF,EAAmB,GAAG,CAAC,IAC9C,KAAK,IAAIE,EAAY,IAAIF,EAAmB,GAAG,CAAC;AAAA,QAAA,KAGpCC;AASd,cARA,QAAQ;AAAA,YACN;AAAA,YACA,KAAK;AAAA,UAAA,GAMH,KAAK,OAAO,UAAA,KAAe,KAAK,MAAM;AACxC,iBAAK,MAAM,SAAA;AAAA,eACN;AAEL,kBAAMpD,IACJtiC,EAAM,WAAWA,EAAM,WAAWA,EAAM;AAQ1C,iBAAK,MAAM,YAAY,CAAC,IAAI,GAAGsiC,CAAa;AAK5C,kBAAMj3B,IAAM,KAAK,IAAA;AACjB,YAAIA,IAAM,KAAK,iBAAiB,OAC9B,KAAK,iBAAiB,GACtB,KAAK,sBAAA,KAEL,KAAK,iBAAiBA;AAAA,UAE1B;AAGF,QAAAo6B,IAAqB;AAAA,MACvB;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,kBAAwB;AAC7B,UAAM9lC,IAAS,KAAK,MAAM,QAAQ;AAClC,IAAKA,GAAQ,wBACT,KAAK,MAAM,aAAA,KAAkB,KAAK,MAAM,qBACxC,KAAK,QAAQ,YACjBA,EAAO,oBAAoB,MAAM,CAAC4uB,IAAY,CAAA,MAAO;AACnD,WAAK,QAAQ;AAAA,QACXA,EAAK,QAAQ,KAAK,QAAQ,QAAQ;AAAA,QAClCA,EAAK;AAAA,QACLA,EAAK;AAAA,QACLA,EAAK,aAAaA,EAAK;AAAA,QACvBA,EAAK,eAAeA,EAAK;AAAA,QACzBA,EAAK;AAAA,QACLA,EAAK;AAAA,MAAA;AAAA,IAET,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASO,wBAA8B;AAGnC,UAAMvD,IAAa,KAAK,OAClB4a,IAAM,KAAK,QAAQ;AACzB,QACEA,KACA,OAAO5a,GAAO,cAAe,cAC7BA,EAAM,oBAAA,MAA0B4a,GAChC;AACA,MAAA5a,EAAM,WAAW4a,GAAK,IAAI;AAC1B;AAAA,IACF;AACA,IACE,CAAC,KAAK,QAAQ,aACd,CAAC,KAAK,aACN,CAAC,KAAK,QAAQ,YACd,CAAC,KAAK,MAAM,aAAA,KACZ,CAAC,KAAK,MAAM,qBACZ,OAAO,KAAK,QAAQ,eAAgB,aAEpC,KAAK,OAAO,YAAA,IAEZ,KAAK,gBAAA;AAAA,EAET;AAAA;AAAA,EAGQ,qBAAqBh/B,GAAsB;AACjD,QAAI,CAACA,KAAU,CAACA,EAAO,UAAW,QAAO;AAGzC,UAAMqkB,IAAgB;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAIF,eAAWr5B,KAAaq5B;AACtB,UAAIrkB,EAAO,UAAU,SAAShV,CAAS;AACrC,eAAO;AAKX,WACE,GAAAgV,EAAO,iBACNA,EAAO,aAAa,aAAa,KAChCA,EAAO,aAAa,aAAa,KACjCA,EAAO,aAAa,aAAa;AAAA,EAMvC;AAAA;AAAA;AAAA,EAIO,aAAa;AAClB,YAAQ,IAAI,kCAAkC,KAAK,EAAE;AAAA,EAEvD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASO,cAAoB;AACzB,QAAI,KAAK,QAAQ,cAAc,GAAO;AACtC,SAAK,YAAA;AACL,UAAMokB,IAAa,KAAK,OAClBrF,IAAiBqF,EAAM,oBAAoBA,EAAM;AACvD,QAAI,CAACrF,KAAa,CAAC,KAAK,SAAU;AAClC,QAAIxqB,GAAY0qC;AAChB,QAAI;AACF,YAAMC,IAAK,KAAK,SAAS,KAAK9a,EAAM,MAAM;AAC1C,MAAA7vB,IAAK2qC,EAAG,IAAIA,EAAG,QAAQ,GACvBD,IAAOC,EAAG;AAAA,IACZ,QAAY;AACV,MAAA3qC,KAAM,KAAK,QAAQ,KAAK,MAAM,KAAK,QAAQ,SAAS,KAAK,GACzD0qC,IAAO,KAAK,QAAQ,KAAK;AAAA,IAC3B;AAEA,UAAMjY,IAAI,IACJC,IAAM,GACNoB,IAAU,WACVnB,IAKD;AAAA,MACH,EAAE,KAAK,UAAU,OAAO,WAAW,SAAS,MAAM,KAAK,MAAM,WAAW,KAAK,EAAE,EAAA;AAAA;AAAA,MAE/E,EAAE,KAAK,QAAQ,OAAOmB,GAAS,SAAS,CAACh0B,MAAW,KAAK,iBAAiBA,CAAC,EAAA;AAAA,MAC3E,EAAE,KAAK,OAAO,OAAOg0B,GAAS,SAAS,MAAM,KAAK,MAAM,OAAA,EAAO;AAAA,IAAE,GAE7D1vB,IAAIuuB,EAAM,QACVC,IAAQH,IAAI,IAAIC,GAChBG,IAASzuB,KAAKquB,IAAI,MAAMruB,IAAI,KAAKsuB,GACjCI,IAAS9yB,IAAK6yB,IAAS,IAAIJ,GAK3BmY,IAAOF,KAAQjY,IAAI,KAAK,KAExBM,IAAMvI,EAAU,MAAA,EAAQ,SAAS,UAAU,EAAE,SAAS,cAAc;AAE1E,IAAAuI,EACG,KAAKF,IAAS,IAAIJ,IAAI,IAAI,EAAE,EAC5B,QAAQA,IAAI,IAAI,MAAM,CAAC,EACvB,OAAOzyB,GAAI4qC,CAAI,EACf,KAAK,SAAS,EACd,OAAO,EAAE,OAAO,WAAW,OAAO,EAAA,CAAG,GAExCjY,EAAM,QAAQ,CAACj5B,GAAGlG,MAAM;AACtB,YAAMy/B,IAAKH,IAASt/B,IAAIo/B,GAClBM,IAAMH,EAAI,QAAQ,SAAS,aAAar5B,EAAE,GAAG,EAAE;AAErD,MAAAw5B,EAAI,OAAOT,IAAI,CAAC,EAAE,OAAOQ,GAAI2X,CAAI,EAAE,KAAK,SAAS,EAAE,KAAK,gBAAgB,IAAK,GAC7EjG,GAAK,aAAazR,GAAKx5B,EAAE,KAAKu5B,GAAI2X,GAAMlxC,EAAE,KAAK,GAC/Cw5B,EAAI,KAAK,kBAAkB,KAAK;AAChC,UAAI;AACF,QAAAA,EAAI,KAAK,MAAM,SAAS;AAAA,MAC1B,QAAY;AAAA,MAEZ;AACA,MAAAA,EAAI,GAAG,aAAa,CAACpzB,MAAW;AAC9B,QAAAA,EAAE,kBAAA,GACEpG,EAAE,WAASA,EAAE,QAAQoG,CAAC;AAAA,MAC5B,CAAC,GACDozB,EAAI,GAAG,SAAS,CAACpzB,MAAW;AAC1B,QAAAA,EAAE,kBAAA,GACFpG,EAAE,UAAA;AAAA,MACJ,CAAC;AAAA,IACH,CAAC,GAEDq5B,EAAI,KAAK,kBAAkB,KAAK,GAChC,KAAK,WAAWA;AAChB,QAAI;AACF,MAAAlD,EAAM,kBAAkB,QAAA;AAAA,IAC1B,QAAY;AAAA,IAEZ;AAAA,EACF;AAAA;AAAA,EAGA,OAAc,aAAa77B,GAAQ20C,GAAc3oC,GAAYC,GAAY3E,GAAqB;AAC5F,UAAMvH,IAAI,EAAE,OAAAuH,GAAO,OAAO,KAAK,SAAS,SAAS,UAAU,QAAA;AAC3D,IAAIqtC,MAAS,YAEX30C,EAAE,KAAKgM,IAAK,GAAGC,IAAK,GAAGD,IAAK,GAAGC,IAAK,CAAC,EAAE,OAAOlM,CAAC,GAC/CC,EAAE,KAAKgM,IAAK,KAAKC,IAAK,GAAGD,IAAK,GAAGC,IAAK,GAAG,EAAE,OAAOlM,CAAC,GACnDC,EAAE,KAAKgM,IAAK,KAAKC,IAAK,GAAGD,IAAK,GAAGC,IAAK,GAAG,EAAE,OAAOlM,CAAC,GACnDC,EAAE,KAAKgM,IAAK,GAAGC,IAAK,KAAKD,IAAK,GAAGC,IAAK,GAAG,EAAE,OAAOlM,CAAC,GACnDC,EAAE,KAAK,KAAKgM,IAAK,GAAG,IAAIC,IAAK,CAAC,MAAMD,IAAK,GAAG,IAAIC,IAAK,GAAG,MAAMD,IAAK,GAAG,IAAIC,IAAK,GAAG,MAAMD,IAAK,GAAG,IAAIC,IAAK,CAAC,EAAE,EACzG,KAAK,MAAM,EACX,OAAOlM,CAAC,GACXC,EAAE,KAAKgM,IAAK,KAAKC,IAAK,GAAGD,IAAK,KAAKC,IAAK,CAAC,EAAE,OAAO,EAAE,OAAA3E,GAAO,OAAO,KAAK,SAAS,SAAS,GACzFtH,EAAE,KAAKgM,IAAK,KAAKC,IAAK,GAAGD,IAAK,KAAKC,IAAK,CAAC,EAAE,OAAO,EAAE,OAAA3E,GAAO,OAAO,KAAK,SAAS,SAAS,KAChFqtC,MAAS,UAElB30C,EAAE,KAAKgM,IAAK,GAAGC,IAAK,GAAGD,IAAK,GAAGC,IAAK,CAAC,EAAE,OAAOlM,CAAC,GAC/CC,EAAE,OAAO,GAAG,EAAE,OAAOgM,IAAK,KAAKC,IAAK,GAAG,EAAE,KAAK3E,CAAK,GACnDtH,EAAE,OAAO,GAAG,EAAE,OAAOgM,IAAK,KAAKC,IAAK,GAAG,EAAE,KAAK,SAAS,EAAE,OAAOlM,CAAC,KAGjEC,EAAE,KAAK,GAAG,EACP,KAAK,EAAE,MAAM,IAAI,QAAQ,UAAU,QAAQ,aAAA,CAAc,EACzD,KAAKsH,CAAK,EACV,OAAO0E,GAAIC,CAAE,EACb,KAAK,MAAM,QAAQ;AAAA,EAE1B;AAAA,EAEO,cAAoB;AACzB,QAAI,KAAK,UAAU;AACjB,UAAI;AACF,aAAK,SAAS,OAAA;AAAA,MAChB,QAAY;AAAA,MAEZ;AACA,WAAK,WAAW;AAAA,IAClB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,iBAAiB4qC,GAAuB;AAC7C,UAAMhb,IAAa,KAAK,OAClBib,IAAcjb,EAAM;AAG1B,QAFI,CAACib,KAEA,KAAa,iBAAkB;AACnC,SAAa,mBAAmB;AACjC,UAAMtgB,IAAiBqF,EAAM,oBAAoBib;AAGjD,QAAIvqC,GAAYI;AAChB,QAAI;AACF,YAAMgqC,IAAK,KAAK,SAAS,KAAKG,CAAM;AACpC,MAAAvqC,IAAKoqC,EAAG,IACRhqC,IAAKgqC,EAAG;AAAA,IACV,QAAY;AACV,MAAApqC,KAAM,KAAK,QAAQ,KAAK,MAAM,KAAK,QAAQ,SAAS,KAAK,GACzDI,KAAM,KAAK,QAAQ,KAAK,MAAM,KAAK,QAAQ,UAAU,KAAK;AAAA,IAC5D;AAEA,UAAM8kB,IAAO+E,EACV,KAAK,KAAKjqB,CAAE,IAAII,CAAE,MAAMJ,CAAE,IAAII,CAAE,EAAE,EAClC,KAAK,MAAM,EACX,OAAO,EAAE,OAAO,WAAW,OAAO,GAAG,WAAW,OAAO,SAAS,QAAA,CAAS,EACzE,SAAS,mBAAmB;AAC/B,IAAA8kB,EAAK,KAAK,kBAAkB,MAAM;AAElC,QAAIslB,IAAoB;AACxB,QAAI;AACF,MAAAA,IAAevgB,EAAU,OAAO,GAAG,GAAG,CAACsK,MAAa;AAClD,QAAAA,EAAI,KAAK,oBAAoB,EAAE,KAAK,SAAS,EAAE,KAAK,kBAAkB,MAAM;AAAA,MAC9E,CAAC,GACDiW,EAAa,IAAI,GAAG,GAAG,GACvBA,EAAa,KAAK,kBAAkB,MAAM,GACzCtlB,EAAa,OAAO,OAAOslB,CAAY;AAAA,IAC1C,QAAY;AAAA,IAEZ;AACA,QAAI;AACF,MAAAlb,EAAM,kBAAkB,QAAA;AAAA,IAC1B,QAAY;AAAA,IAEZ;AAEA,UAAM/J,IAAO,CAACV,GAAYC,GAAYU,GAAYC,MAAe;AAC/D,YAAMjzB,IAAI,KAAK,MAAMqyB,GAAIC,CAAE;AAC3B,UAAItyB,IAAI,KAAQ,QAAO,CAACqyB,IAAKryB,GAAGsyB,IAAKtyB,CAAC;AACtC,YAAMkzB,IAAK,KAAK,MAAMF,GAAIC,CAAE,KAAK;AACjC,aAAO,CAACD,IAAKE,GAAID,IAAKC,CAAE;AAAA,IAC1B,GAEM+kB,IAAY,CAACx2C,GAAQ8K,GAAYC,MAAe;AACpD,YAAMS,KAAMxL,EAAE,KAAK,MAAMA,EAAE,SAAS,KAAK,GACnCyL,KAAMzL,EAAE,KAAK,MAAMA,EAAE,UAAU,KAAK,GACpC2L,IAAKb,IAAKU,GACVI,IAAKb,IAAKU;AAChB,UAAI,KAAK,IAAIE,CAAE,IAAI,QAAS,KAAK,IAAIC,CAAE,IAAI,KAAO,QAAO,EAAEJ,GAAO,GAAGC,EAAA;AACrE,YAAMgrC,IAAM9qC,MAAO,KAAK3L,EAAE,SAAS,KAAK,IAAI,KAAK,IAAI2L,CAAE,IAAI,OACrD+qC,IAAM9qC,MAAO,KAAK5L,EAAE,UAAU,KAAK,IAAI,KAAK,IAAI4L,CAAE,IAAI,OACtD+qC,IAAK,KAAK,IAAIF,GAAKC,CAAG;AAC5B,aAAO,EAAE,GAAGlrC,IAAKG,IAAKgrC,GAAI,GAAGlrC,IAAKG,IAAK+qC,EAAA;AAAA,IACzC;AAEA,QAAIC,IAAe;AACnB,UAAMC,IAAa,MAAM;AACvB,UAAID,GAAS;AACX,YAAI;AACF,UAAIA,EAAQ,iBAAiB,UAC3BA,EAAQ,KAAK,gBAAgB,OAAO,UAAUA,EAAQ,YAAY,GAEpEA,EAAQ,KAAK,gBAAgB,OAAO;AAAA,YAClC,oBAAoB;AAAA,YACpB,kBAAkB;AAAA,UAAA,CACnB;AAAA,QACH,QAAY;AAAA,QAEZ;AACA,QAAAA,IAAU;AAAA,MACZ;AAAA,IACF,GAEME,IAAU,CAACC,GAAiBC,MAAoB;AACpD,UAAI;AACF,eAAOV,EAAO,MAAMS,GAASC,CAAO;AAAA,MACtC,QAAY;AACV,eAAO,EAAE,GAAGjrC,GAAI,GAAGI,EAAA;AAAA,MACrB;AAAA,IACF,GAEM8qC,IAAY,CAACF,GAAiBC,MAAiC;AAGnE,UAAIE;AACJ,UAAI;AACF,QAAAA,IAAcjmB,EAAK,KAAK,MAAM,SAC9BA,EAAK,KAAK,MAAM,UAAU;AAAA,MAC5B,QAAY;AAAA,MAEZ;AACA,YAAMhsB,IAAK,SAAS,iBAAiB8xC,GAASC,CAAO;AACrD,UAAI;AACF,QAAIE,MAAgB,WAAWjmB,EAAK,KAAK,MAAM,UAAUimB;AAAA,MAC3D,QAAY;AAAA,MAEZ;AAEA,YAAMhlC,IADKjN,GAAY,UAAU,gBAAgB,GACnC,eAAe,cAAc;AAC3C,UAAIiN,KAAMA,MAAO,KAAK,WAAWmpB,EAAM,OAAO,MAAMnpB,CAAE,KAAK;AAK3D,UAAI;AACF,cAAMkvB,IAAQ/F,EAAM,OAAO,YAAY,CAAA;AACvC,mBAAWzrB,KAAKwxB,GAAO;AACrB,cAAI,CAACxxB,KAAKA,EAAE,OAAO,KAAK,GAAI;AAC5B,gBAAM9P,IAAM,SACT,cAAc,+BAA+B8P,EAAE,EAAE,IAAI,GACpD,wBAAA,GAEEunC,IAAM;AACZ,cACEr3C,KACAi3C,KAAWj3C,EAAI,OAAOq3C,KACtBJ,KAAWj3C,EAAI,QAAQq3C,KACvBH,KAAWl3C,EAAI,MAAMq3C,KACrBH,KAAWl3C,EAAI,SAASq3C;AAExB,mBAAOvnC;AAAA,QAEX;AAAA,MACF,QAAY;AAAA,MAEZ;AACA,aAAO;AAAA,IACT,GAEMwnC,IAAS,CAAC9mC,MAAY;AAC1B,YAAM+L,IAAIy6B,EAAQxmC,EAAG,SAASA,EAAG,OAAO,GAClC2G,IAASggC,EAAU3mC,EAAG,SAASA,EAAG,OAAO;AAE/C,UAAI2G,KAAWA,EAAe,SAAS;AAGrC,cAAMrC,IAAMqC,EAAe,SACrBogC,KAAOziC,EAAG,KAAK,MAAMA,EAAG,SAAS,KAAK,GACtC0iC,KAAO1iC,EAAG,KAAK,MAAMA,EAAG,UAAU,KAAK,GAIvC2iC,IAAQ,CAACx1C,IAAWy1C,IAAU1sC,GAAYC,MAAe;AAC7D,cAAI;AACF,kBAAMvL,IAAIuC,MAAQA,GAAK;AACvB,gBAAIvC,GAAG;AACL,oBAAMmH,IAAIsoB,GAAsBzvB,GAAG,CAACsL,GAAIC,CAAE,CAAC;AAC3C,kBAAIpE,KAAK,SAASA,EAAE,CAAC,CAAC,KAAK,SAASA,EAAE,CAAC,CAAC;AACtC,uBAAO,EAAE,GAAGA,EAAE,CAAC,GAAG,GAAGA,EAAE,CAAC,EAAA;AAAA,YAC5B;AAAA,UACF,QAAY;AAAA,UAEZ;AACA,iBAAO6vC,EAAUgB,IAAK1sC,GAAIC,CAAE;AAAA,QAC9B,GACM0sC,IAAKF,EAAMtgC,GAAQrC,GAAI7I,GAAII,CAAE,GAC7B4hB,IAAKwpB,EAAM,MAAM,KAAK,SAASF,GAAKC,CAAG,GACvC3rC,IAAK8rC,EAAG,IAAI1pB,EAAG,GACfniB,IAAK6rC,EAAG,IAAI1pB,EAAG,GACfiR,IAAO,KAAK,MAAMrzB,GAAIC,CAAE,KAAK,GAC7B8lB,IAAOJ,EAAKvD,EAAG,IAAIhiB,GAAIgiB,EAAG,IAAI5hB,GAAIR,GAAIC,CAAE,GACxC+lB,IAAOL,EAAKmmB,EAAG,IAAIJ,GAAKI,EAAG,IAAIH,GAAK,CAAC3rC,GAAI,CAACC,CAAE,GAC5C6e,IAAS,KAAK,IAAI,IAAI,KAAK,IAAIuU,IAAO,MAAM,EAAE,CAAC,GAC/C0Y,IAAO3pB,EAAG,IAAI2D,EAAK,CAAC,IAAIjH,GACxBktB,IAAO5pB,EAAG,IAAI2D,EAAK,CAAC,IAAIjH,GACxBmtB,KAAOH,EAAG,IAAI9lB,EAAK,CAAC,IAAIlH,GACxBotB,KAAOJ,EAAG,IAAI9lB,EAAK,CAAC,IAAIlH;AAC9B,QAAAwG,EAAK;AAAA,UACH,KAAKlD,EAAG,CAAC,IAAIA,EAAG,CAAC,MAAM2pB,CAAI,IAAIC,CAAI,IAAIC,EAAI,IAAIC,EAAI,IAAIJ,EAAG,CAAC,IAAIA,EAAG,CAAC;AAAA,QAAA;AAAA,MAEvE;AAEE,QAAAxmB,EAAK,KAAK,KAAKllB,CAAE,IAAII,CAAE,MAAMkQ,EAAE,CAAC,IAAIA,EAAE,CAAC,EAAE;AAG3C,UAAIpF,OAAY2/B,GAAS,QAAQ,UAC/BC,EAAA,GACI5/B,KAAWA,EAAe,iBAAgB;AAC5C,cAAM6gC,IAAM7gC,EAAe;AAC3B,QAAA2/B,IAAU,EAAE,MAAM3/B,GAAQ,cAAc6gC,EAAG,KAAK,QAAQ,EAAA;AACxD,YAAI;AACF,UAAAA,EAAG,KAAK,EAAE,QAAQ,WAAW,oBAAoB,OAAO,kBAAkB,KAAK;AAAA,QACjF,QAAY;AAAA,QAEZ;AAAA,MACF;AAAA,IAEJ,GAEMC,IAAO,CAACznC,MAAY;AACxB,aAAO,oBAAoB,eAAe8mC,GAAQ,EAAI,GACtD,OAAO,oBAAoB,aAAaW,GAAM,EAAI,GACjD,KAAa,mBAAmB;AACjC,UAAI;AACF,QAAA9mB,EAAK,OAAA,GACLslB,GAAc,SAAA,GAEED,EAAO,KAAa;AAAA,UAClC;AAAA,QAAA,EAEK,QAAQ,CAACrxC,MAAgBA,EAAG,QAAQ;AAAA,MAC7C,QAAY;AAAA,MAEZ;AACA,YAAMgS,IAASggC,EAAU3mC,EAAG,SAASA,EAAG,OAAO;AAE/C,UADAumC,EAAA,GACI5/B,KAAUA,EAAO,OAAO,KAAK;AAC/B,YAAI;AAMF,cAAItW;AACJ,cAAI;AACF,kBAAM0b,IAAIy6B,EAAQxmC,EAAG,SAASA,EAAG,OAAO,GAClCsE,IAAMqC,EAAe,SACrBiL,IAAK,KAAK;AAAA,cACd;AAAA,cACA,KAAK,IAAI,IAAI7F,EAAE,KAAKzH,EAAG,KAAK,OAAOA,EAAG,SAAS,EAAE;AAAA,YAAA,GAE7CuN,IAAK,KAAK;AAAA,cACd;AAAA,cACA,KAAK,IAAI,IAAI9F,EAAE,KAAKzH,EAAG,KAAK,OAAOA,EAAG,UAAU,EAAE;AAAA,YAAA;AAQpD,gBADiB,KAAK,IAAIsN,GAAI,IAAIA,GAAIC,GAAI,IAAIA,CAAE,IACjC,MAAM;AAGnB,kBAAIpW,IAAKmW,GACP/V,IAAKgW;AACP,oBAAMoO,IAAKrO,GACTsO,IAAK,IAAItO,GACThL,IAAKiL,GACLsO,IAAK,IAAItO,GACL5jB,IAAI,KAAK,IAAIgyB,GAAIC,GAAItZ,GAAIuZ,CAAE;AACjC,cAAIlyB,MAAMgyB,IAAIxkB,IAAK,IACVxN,MAAMiyB,IAAIzkB,IAAK,IACfxN,MAAM2Y,IAAI/K,IAAK,IACnBA,IAAK,GACVxL,IAAO,EAAE,cAAc,EAAE,GAAGoL,GAAI,GAAGI,IAAG;AAAA,YACxC;AAAA,UAGF,QAAY;AAAA,UAEZ;AACA,eAAK,cAAc,eAAe8K,GAAQtW,CAAI;AAAA,QAChD,QAAY;AAAA,QAEZ;AAAA,eACS,CAACsW;AAGV,YAAI;AACF,gBAAM,IAAI6/B,EAAQxmC,EAAG,SAASA,EAAG,OAAO,GAIlCtQ,IAAI,KAAK,SACTm3C,IAAM,IACNa,IACJ,EAAE,MAAMh4C,EAAE,KAAK,KAAKm3C,KACpB,EAAE,MAAMn3C,EAAE,KAAK,MAAMA,EAAE,SAAS,KAAKm3C,KACrC,EAAE,MAAMn3C,EAAE,KAAK,KAAKm3C,KACpB,EAAE,MAAMn3C,EAAE,KAAK,MAAMA,EAAE,UAAU,KAAKm3C;AACxC,cAAI,CAAC9b,EAAM,aAAA,KAAkB,CAAC2c,GAAU;AAGtC,kBAAM7a,IAAU9B,EAAM,QAAQ;AAAA,cAC5B,GAAG,KAAK,MAAM,EAAE,IAAI,EAAM;AAAA,cAC1B,GAAG,KAAK,MAAM,EAAE,IAAI,EAAM;AAAA,cAC1B,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,MAAM;AAAA,YAAA,CACP;AACD,gBAAI8B,GAAS;AAGX,oBAAM8a,IAAU,MAAM;AACpB,oBAAI;AACF,uBAAK,cAAc,eAAe9a,CAAO;AAAA,gBAC3C,QAAY;AAAA,gBAEZ;AAAA,cACF;AACA,cAAKA,EAAgB,OAAO,OACzBA,EAAgB,MAAM,KAAK8a,CAAO,IAChCA,EAAA,GACL5c,EAAM,cAAc,CAAC8B,CAAO,CAAC;AAAA,YAC/B;AAAA,UACF;AAAA,QACF,QAAY;AAAA,QAEZ;AAAA,IAEJ;AAEA,WAAO,iBAAiB,eAAeia,GAAQ,EAAI,GACnD,OAAO,iBAAiB,aAAaW,GAAM,EAAI;AAAA,EACjD;AAAA;AAAA,EAGO,eAAe;AACpB,YAAQ,IAAI,oCAAoC,KAAK,EAAE;AAAA,EAEzD;AAAA;AAAA,EAGQ,0BAA0B;AAChC,QAAI,KAAK,kBAAkB,WAAW;AACpC,cAAQ;AAAA,QACN;AAAA,QACA,KAAK;AAAA,MAAA;AAEP;AAAA,IACF;AAEA,YAAQ;AAAA,MACN;AAAA,MACA,KAAK;AAAA,IAAA,GAKP,KAAK,kBAAkB,YAAY,KAAK,MAAM,OAAO,MAAA,GAIrD,KAAK,kBAAkB,UAAU;AAAA,MAAG;AAAA,MAAc,MAChD,KAAK,yBAAA;AAAA,IAAyB,GAEhC,KAAK,kBAAkB,UAAU;AAAA,MAAG;AAAA,MAAc,MAChD,KAAK,wBAAA;AAAA,IAAwB;AAG/B,UAAMG,IAAe,GACfC,IAAc,WACdC,IAAe,WACfC,IAAoB,GAGpBC,IAAY;AAAA,MAChB,KAAK,EAAE,GAAG,GAAG,GAAG,CAACJ,IAAe,EAAA;AAAA,MAChC,OAAO,EAAE,GAAGA,IAAe,GAAG,GAAG,EAAA;AAAA,MACjC,QAAQ,EAAE,GAAG,GAAG,GAAGA,IAAe,EAAA;AAAA,MAClC,MAAM,EAAE,GAAG,CAACA,IAAe,GAAG,GAAG,EAAA;AAAA,IAAE;AAGrC,WAAO,QAAQI,CAAS,EAAE,QAAQ,CAAC,CAAC9kC,GAAWqQ,CAAM,MAAM;AACzD,UAAI,CAAC,KAAK,kBAAkB,UAAW;AAEvC,YAAM4G,IAAS,KAAK,kBAAkB,UACnC,OAAOytB,IAAe,CAAC,EACvB,KAAKC,CAAW,EAChB,OAAO,EAAE,OAAOC,GAAc,OAAOC,EAAA,CAAmB,EACxD,SAAS,uCAAuC7kC,CAAS,EAAE;AAG9D,MAAAiX,EAAO,KAAK,MAAM,SAAS,WAG3B,KAAK,kBAAkBjX,CAAmC,IAAIiX,GAG9DA,EAAO;AAAA,QAAG;AAAA,QAAc,MACtB,KAAK;AAAA,UACHjX;AAAA,QAAA;AAAA,MACF,GAEFiX,EAAO,GAAG,cAAc,MAAM,KAAK,uBAAuB,GAG1DA,EAAO,GAAG,SAAS,CAACpa,MAAe;AACjC,QAAAA,EAAM,gBAAA,GACN,QAAQ;AAAA,UACN,6BAA6BmD,CAAS;AAAA,UACtC,KAAK;AAAA,QAAA,GAIP,KAAK;AAAA,UACHA;AAAA,QAAA;AAAA,MAEJ,CAAC,GAODiX,EAAO,GAAG,eAAe,CAACpa,MAAe;AACvC,YAAI,KAAK,OAAO,eAAgB;AAChC,QAAAA,EAAM,gBAAA;AACN,cAAMiuB,IAASjuB,EAAM,SACf2jC,IAAS3jC,EAAM;AACrB,YAAIkoC,IAAY;AAChB,cAAMC,IAAU,MAAM;AACpB,iBAAO,oBAAoB,eAAepB,GAAQ,EAAI,GACtD,OAAO,oBAAoB,aAAaW,GAAM,EAAI;AAAA,QACpD,GACMX,IAAS,CAAC9rC,MAAoB;AAClC,cAAI,CAAAitC,KACA,KAAK,MAAMjtC,EAAE,UAAUgzB,GAAQhzB,EAAE,UAAU0oC,CAAM,IAAI,GAAG;AAC1D,YAAAuE,IAAY,IACZC,EAAA;AAEA,kBAAMC,IAAU,CAACC,MAAc;AAC7B,cAAAA,EAAG,gBAAA,GACFjuB,EAAO,KAAa,oBAAoB,SAASguB,GAAS,EAAI;AAAA,YACjE;AACC,YAAAhuB,EAAO,KAAa,iBAAiB,SAASguB,GAAS,EAAI,GAC5D,KAAK,iBAAiBpoC,CAAK;AAAA,UAC7B;AAAA,QACF,GACM0nC,IAAO,MAAMS,EAAA;AACnB,eAAO,iBAAiB,eAAepB,GAAQ,EAAI,GACnD,OAAO,iBAAiB,aAAaW,GAAM,EAAI;AAAA,MACjD,CAAC;AAAA,IACH,CAAC,GAGG,KAAK,kBAAkB,aACzB,KAAK,kBAAkB,UAAU,KAAA,GAEnC,KAAK,gCAAA;AAAA,EACP;AAAA,EAEQ,kCAAkC;AACxC,QAAI,CAAC,KAAK,kBAAkB,aAAa,CAAC,KAAK;AAC7C;AAIF,UAAM3pC,IAAO,KAAK,eAAe,KAAA,GAG3BuqC,IAAY,KAAK,eAAuB,UAAA,GAExCjuB,IADc,KAAK,eAAuB,KAAA,EAAO,UAAA,EAChB,SAAA,EAAW,UAAUiuB,CAAQ,GAG9DjvB,IAAiB,CAAC,CAACppB,GAAGC,CAAC,GAAa,EAAE,GAAAgF,GAAG,GAAAe,GAAG,GAAA3B,GAAG,GAAAtF,GAAG,GAAAiM,GAAG,GAAAC,QAClD,CAACjL,IAAIiF,IAAIhF,IAAIoE,IAAI2G,GAAGhL,IAAIgG,IAAI/F,IAAIlB,IAAIkM,CAAC,GAGxCkkB,IAAUrhB,EAAK,IAAIA,EAAK,QAAQ,GAChCshB,IAAUthB,EAAK,IAAIA,EAAK,SAAS,GAGjCwqC,IAAY,IACZC,IAAa,IAGbC,IAAgB;AAAA,MACpB,KAAK,CAACrpB,GAASrhB,EAAK,IAAIwqC,CAAS;AAAA,MACjC,OAAO,CAACxqC,EAAK,IAAIA,EAAK,QAAQyqC,GAAYnpB,CAAO;AAAA,MACjD,QAAQ,CAACD,GAASrhB,EAAK,IAAIA,EAAK,SAASyqC,CAAU;AAAA,MACnD,MAAM,CAACzqC,EAAK,IAAIyqC,GAAYnpB,CAAO;AAAA,IAAA;AAIrC,WAAO,QAAQopB,CAAa,EAAE,QAAQ,CAAC,CAACtlC,GAAW+C,CAAG,MAAM;AAC1D,YAAMkU,IAAS,KAAK,kBAAkBjX,CAAuC;AAC7E,UAAIiX,GAAQ;AACV,cAAM,CAACsuB,GAAcC,CAAY,IAAItvB,EAAenT,GAAKmU,CAAmB;AAC5E,QAAAD,EAAO,OAAOsuB,GAAcC,CAAY;AAAA,MAC1C;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,4BAAkC;AACxC,IAAK,KAAK,aACV,KAAK,SAAS,GAAG,cAAc,MAAM,KAAK,0BAA0B,GACpE,KAAK,SAAS,GAAG,cAAc,MAAM,KAAK,yBAAyB;AAAA,EACrE;AAAA,EAEQ,2BAAiC;AACvC,IAAI,KAAK,OAAO,kBAMZ,KAAK,eACL,KAAK,yBACP,aAAa,KAAK,oBAAoB,GACtC,KAAK,uBAAuB,OAEzB,KAAK,4BAA0B,KAAK,sBAAA;AAAA,EAC3C;AAAA,EAEQ,0BAAgC;AACtC,IAAI,KAAK,uBACL,KAAK,wBAAsB,aAAa,KAAK,oBAAoB,GACrE,KAAK,uBAAuB,WAAW,MAAM;AAE3C,MADA,KAAK,uBAAuB,MACxB,OAAK,sBAAuB,KAAa,qBAC7C,KAAK,sBAAA;AAAA,IACP,GAAG,GAAG;AAAA,EACR;AAAA,EAEQ,wBAAwB;AAC9B,IAAK,KAAK,kBAAkB,aAC1B,KAAK,wBAAA,GAGP,QAAQ;AAAA,MACN;AAAA,MACA,KAAK;AAAA,IAAA,GAEP,KAAK,2BAA2B,IAC5B,KAAK,kBAAkB,aACzB,KAAK,kBAAkB,UAAU,KAAA,GAEnC,KAAK,gCAAA;AAAA,EACP;AAAA,EAEQ,wBAAwB;AAC9B,IAAK,KAAK,kBAAkB,cAE5B,QAAQ;AAAA,MACN;AAAA,MACA,KAAK;AAAA,IAAA,GAEP,KAAK,2BAA2B,IAC5B,KAAK,kBAAkB,aACzB,KAAK,kBAAkB,UAAU,KAAA,GAEnC,KAAK,sBAAA;AAAA,EACP;AAAA,EAEQ,sBACNxlC,GACA;AAEA,QAAI,KAAK,mBAAmB;AAC1B;AAGF,YAAQ;AAAA,MACN;AAAA,MACAA;AAAA,MACA;AAAA,MACA,KAAK;AAAA,IAAA,GAIP,KAAK,sBAAA;AAIL,UAAM48B,IAAW,KAAK,SAAS,KAAA;AAC/B,SAAK,oBAAoB;AAAA,MACvB,WAAWA,EAAS,MAAA,EAAQ,KAAK,kBAAkB,MAAM;AAAA,IAAA;AAG3D,UAAM/N,IAAY,KAAK,QAAQ,OACzBC,IAAa,KAAK,QAAQ,QAC1B2W,IAAU,IAGVC,IAAgB,KAAK,YAAA,GAKrB5qC,IAAQ,KAAK,eAAuB,KAAK,KAAK,eAAe,MAAM,GACnE6qC,IAAgB7qC,EAAK,IACrB8qC,IAAgB9qC,EAAK,IAGrBmc,IAAS,KAAK,kBAAkBjX,CAAS;AAC/C,QAAI,CAACiX,GAAQ;AACX,cAAQ,KAAK,4DAA4DjX,CAAS;AAClF;AAAA,IACF;AAGA,UAAM6lC,IAAa5uB,EAAO,KAAA,GACpB6uB,IAAe;AAAA,MACnB,GAAGD,EAAW,IAAIA,EAAW,QAAQ;AAAA,MACrC,GAAGA,EAAW,IAAIA,EAAW,SAAS;AAAA,IAAA,GAKlCnrB,IAAOorB,EAAa,IAAIH,GACxBhrB,IAAOmrB,EAAa,IAAIF,GACxBG,IAAY,KAAK,KAAKrrB,IAAOA,IAAOC,IAAOA,CAAI,GAG/CqrB,IAActrB,IAAOqrB,GACrBE,IAActrB,IAAOorB,GAGrBnrC,IAAO,KAAK,eAAe,KAAA,GAC3BsrC,IAActrC,EAAK,IAAIA,EAAK,QAAQ,GACpCurC,IAAcvrC,EAAK,IAAIA,EAAK,SAAS,GAErCuqC,IAAY,KAAK,eAAuB,UAAA,GAExCjuB,IADc,KAAK,eAAuB,KAAA,EAAO,UAAA,EAChB,SAAA,EAAW,UAAUiuB,CAAQ,GAG9DiB,IAAgBlvB,EAAoB,QAAA,GAGpCmvB,IAAWL,IAAcI,EAAc,IAAIH,IAAcG,EAAc,GACvEE,IAAWN,IAAcI,EAAc,IAAIH,IAAcG,EAAc;AAG7E,QAAIG,GAAWC;AACf,UAAMC,IAAO,KAAK,IAAIJ,CAAQ;AAG9B,IAFa,KAAK,IAAIC,CAAQ,IAEnBG,IAELH,IAAW,KAEbC,IAAYL,GACZM,IAAY5rC,EAAK,MAGjB2rC,IAAYL,GACZM,IAAY5rC,EAAK,IAAIA,EAAK,UAIxByrC,IAAW,KAEbE,IAAY3rC,EAAK,GACjB4rC,IAAYL,MAGZI,IAAY3rC,EAAK,IAAIA,EAAK,OAC1B4rC,IAAYL;AAKhB,UAAMjwB,IAAiB,CAAC,CAACppB,IAAGC,EAAC,GAAa,EAAE,GAAAgF,IAAG,GAAAe,GAAG,GAAA3B,IAAG,GAAAtF,IAAG,GAAAiM,IAAG,GAAAC,SAClD,CAACjL,KAAIiF,KAAIhF,KAAIoE,KAAI2G,IAAGhL,KAAIgG,IAAI/F,KAAIlB,KAAIkM,EAAC,GAGxC,CAACwkB,GAAYC,CAAU,IAAItG,EAAe,CAACqwB,GAAWC,CAAS,GAAGtvB,CAAmB,GAGrFwvB,KAAqB,KAAK;AAAA,MAC9B,KAAK,IAAInqB,IAAaopB,GAAe,CAAC,IAAI,KAAK,IAAInpB,IAAaopB,GAAe,CAAC;AAAA,IAAA,GAG5Ee,KAAsBD,IAItBE,KAAgBF,KAAqBjB,IAAUkB,IAE/CE,KAAalB,IAAgBK,IAAcY,IAC3CE,IAAalB,IAAgBK,IAAcW,IAC3CG,IAAWF,KAAahY,IAAY,GACpCmY,IAAWF,IAAahY,IAAa;AAG3C,QAAI,CAAC,KAAK,kBAAkB,WAAW;AACrC,cAAQ,KAAK,uDAAuD;AACpE;AAAA,IACF;AAGA,SAAK,kBAAkB,OAAO,KAAK;AAAA,MACjC,KAAK,kBAAkB;AAAA,MACvBiY;AAAA,MACAC;AAAA,MACAnY;AAAA,MACAC;AAAA,MACA4W;AAAA;AAAA,IAAA;AAOF,UAAMuB,KAD0BP,KAAqBjB,IACPM,GACxCmB,KAAW;AAAA,MACf,GAAGpB,EAAa,IAAIE,IAAciB;AAAA,MAClC,GAAGnB,EAAa,IAAIG,IAAcgB;AAAA,IAAA;AAIpC,SAAK,kBAAkB,YAAY,KAAK,kBAAkB,UACvD,KAAKnB,EAAa,GAAGA,EAAa,GAAGoB,GAAS,GAAGA,GAAS,CAAC,EAC3D,OAAO,EAAE,OAAO,WAAW,OAAO,GAAG,SAAS,IAAA,CAAK,EACnD,KAAK,kBAAkB,MAAM,GAGhC,KAAK;AAAA,MACH,KAAK,kBAAkB;AAAA,MACvBpB;AAAA,MACAoB;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEQ,mBACN1kB,GACA11B,GACAC,GACAX,GACAC,GACAq5C,IAAwB,GACnB;AACL,QAAI9jB;AACJ,UAAMulB,IAAY,KAAK,QAAQ,mBAAmB,WAC5CC,IAAc,WACd9nB,IAAc,GACdhP,IAAU,KAGV2L,IAAUnvB,IAAIV,IAAQ,GACtB8vB,IAAUnvB,IAAIV,IAAS;AAG7B,YAAQ,KAAK,QAAQ,OAAA;AAAA,MACnB,KAAK;AACH,cAAMgwB,IAAS,KAAK,IAAIjwB,GAAOC,CAAM,IAAI;AACzC,QAAAu1B,IAAcY,EACX,OAAOnG,IAAS,CAAC,EACjB,OAAOJ,GAASC,CAAO,EACvB,KAAKirB,CAAS,EACd,OAAO,EAAE,OAAOC,GAAa,OAAO9nB,EAAA,CAAa,EACjD,QAAQhP,CAAO,GACdo1B,MAAkB,KACpB9jB,EAAY,OAAO8jB,GAAezpB,GAASC,CAAO;AAEpD;AAAA,MAEF,KAAK;AACH,QAAA0F,IAAcY,EACX,QAAQp2B,GAAOC,CAAM,EACrB,OAAO4vB,GAASC,CAAO,EACvB,KAAKirB,CAAS,EACd,OAAO,EAAE,OAAOC,GAAa,OAAO9nB,EAAA,CAAa,EACjD,QAAQhP,CAAO,GACdo1B,MAAkB,KACpB9jB,EAAY,OAAO8jB,GAAezpB,GAASC,CAAO;AAEpD;AAAA,MAEF;AACE,YAAI,KAAK,QAAQ,YAAY;AAE3B,UAAA0F,IAAcY,EACX,KAAKp2B,GAAOC,CAAM,EAClB,KAAKS,GAAGC,CAAC,EACT,KAAK,MAAM,EACX,OAAO,EAAE,OAAOq6C,GAAa,OAAO9nB,EAAA,CAAa,EACjD,QAAQhP,CAAO,EACf,OAAO,CAAC;AAGX,gBAAM+2B,IAAa7kB,EAAU,OAAA,EAAS,KAAKp2B,GAAOC,CAAM,EAAE,KAAKS,GAAGC,CAAC;AACnE,UAAAs6C,EAAW,IAAI,KAAK,QAAQ,UAAU,GAGtC,KAAK,2BAA2B,WAAW,MAAM;AAC/C,gBAAI,KAAK,WAAY;AACrB,kBAAMrK,IAAUqK,EAAW,SAAA,EAAW,CAAC;AACvC,gBAAIrK,GAAS;AACX,kBAAIrhB,IAAKqhB,EAAQ,KAAA;AACjB,eAAIrhB,EAAG,SAAS,KAAKA,EAAG,UAAU,OAChCA,IAAK,KAAK;AAAA,gBACR,KAAK,QAAQ;AAAA,gBACbvvB;AAAA,gBACAC;AAAA,cAAA,IAIAsvB,EAAG,QAAQ,KAAKA,EAAG,SAAS,MAC9B0rB,EAAW,QAAQ1rB,EAAG,GAAGA,EAAG,GAAGA,EAAG,OAAOA,EAAG,MAAM,GAClD0rB,EAAW,KAAK,aAAa,uBAAuB,MAAM,IAI5DrK,EAAQ,KAAKmK,CAAS,EAAE,QAAQ72B,CAAO;AAAA,YACzC;AAAA,UACF,GAAG,CAAC,GAEJ+2B,EAAW,KAAK,kBAAkB,MAAM,GAGpC3B,MAAkB,MACpB9jB,EAAY,OAAO8jB,GAAezpB,GAASC,CAAO,GAClDmrB,EAAW,OAAO3B,GAAezpB,GAASC,CAAO;AAAA,QAErD;AAEE,UAAA0F,IAAcY,EACX,KAAKp2B,GAAOC,CAAM,EAClB,KAAKS,GAAGC,CAAC,EACT,KAAKo6C,CAAS,EACd,OAAO,EAAE,OAAOC,GAAa,OAAO9nB,EAAA,CAAa,EACjD,QAAQhP,CAAO,EACf,OAAO,CAAC,GAGPo1B,MAAkB,KACpB9jB,EAAY,OAAO8jB,GAAezpB,GAASC,CAAO;AAGtD;AAAA,IAAA;AAGJ,WAAO0F,EAAY,KAAK,kBAAkB,MAAM;AAAA,EAClD;AAAA,EAEQ,wBACNY,GACA9Z,GACAC,GACA;AAEA,UAAMxQ,IAAKwQ,EAAI,IAAID,EAAM,GACnBtQ,IAAKuQ,EAAI,IAAID,EAAM,GACnBzI,IAAS,KAAK,KAAK9H,IAAKA,IAAKC,IAAKA,CAAE;AAE1C,QAAI6H,MAAW,EAAG;AAGlB,UAAMqnC,IAAQnvC,IAAK8H,GACbsnC,IAAQnvC,IAAK6H,GAGbgnC,IAAc,IACdxnB,IAAa,GAGb+nB,IAAY7+B,EAAI,GAChB8+B,IAAY9+B,EAAI,GAGhB++B,IAAQF,IAAYF,IAAQL,GAC5BU,IAAQF,IAAYF,IAAQN,GAG5BW,IAAQ,CAACL,IAAQ9nB,GACjBooB,IAAQP,IAAQ7nB,GAGhBqoB,IAAc;AAAA,MAClB,CAACN,GAAWC,CAAS;AAAA,MACrB,CAACC,IAAQE,GAAOD,IAAQE,CAAK;AAAA,MAC7B,CAACH,IAAQE,GAAOD,IAAQE,CAAK;AAAA,MAC7B,CAACL,GAAWC,CAAS;AAAA,IAAA;AAIvB,IAAAjlB,EACG,QAAQslB,CAAW,EACnB,KAAK,SAAS,EACd,QAAQ,GAAG,EACX,KAAK,kBAAkB,MAAM;AAAA,EAClC;AAAA,EAEQ,wBAAwB;AAC9B,IAAI,KAAK,mBAAmB,cAC1B,KAAK,kBAAkB,UAAU,OAAA,GACjC,KAAK,oBAAoB;AAAA,EAE7B;AAAA;AAAA,EAGO,0BAA0B;AAgB/B,IAfA,QAAQ;AAAA,MACN;AAAA,MACA,KAAK;AAAA,IAAA,GAGP,KAAK,qBAAqB,IACtB,KAAK,yBACP,aAAa,KAAK,oBAAoB,GACtC,KAAK,uBAAuB,OAO1B,MAAK,cACT,KAAK,sBAAA;AAAA,EACP;AAAA;AAAA,EAGO,2BAA2B;AAChC,YAAQ;AAAA,MACN;AAAA,MACA,KAAK;AAAA,IAAA,GAEP,KAAK,qBAAqB,IAC1B,KAAK,sBAAA;AAAA,EACP;AAAA,EAEO,6BAAsC;AAC3C,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,iBACNltC,GACAoF,GAC0B;AAC1B,UAAMic,IAAUrhB,EAAK,IAAIA,EAAK,QAAQ,GAChCshB,IAAUthB,EAAK,IAAIA,EAAK,SAAS;AAGvC,YAAQoF,GAAA;AAAA,MACN,KAAK;AACH,eAAO,EAAE,GAAGic,GAAS,GAAGrhB,EAAK,EAAA;AAAA,MAC/B,KAAK;AACH,eAAO,EAAE,GAAGA,EAAK,IAAIA,EAAK,OAAO,GAAGshB,EAAA;AAAA,MACtC,KAAK;AACH,eAAO,EAAE,GAAGD,GAAS,GAAGrhB,EAAK,IAAIA,EAAK,OAAA;AAAA,MACxC,KAAK;AACH,eAAO,EAAE,GAAGA,EAAK,GAAG,GAAGshB,EAAA;AAAA,IAAQ;AAAA,EAErC;AAAA,EAEQ,oBACNlc,GACM;AACN,YAAQ;AAAA,MACN;AAAA,MACAA;AAAA,MACA;AAAA,MACA,KAAK;AAAA,IAAA;AAGP,QAAI;AAEF,YAAM6uB,IAAY,KAAK,QAAQ,OACzBC,IAAa,KAAK,QAAQ,QAC1B2W,IAAU,IAGVC,IAAgB,KAAK,YAAA,GACrBqC,IAAerC,IAAgB,KAAK,KAAM;AAGhD,UAAIhrB,IAAO,GAAGC,IAAO;AACrB,cAAQ3a,GAAA;AAAA,QACN,KAAK;AACH,UAAA0a,IAAO,GACPC,IAAO;AACP;AAAA,QACF,KAAK;AACH,UAAAD,IAAO,GACPC,IAAO;AACP;AAAA,QACF,KAAK;AACH,UAAAD,IAAO,GACPC,IAAO;AACP;AAAA,QACF,KAAK;AACH,UAAAD,IAAO,IACPC,IAAO;AACP;AAAA,MAAA;AAIJ,YAAMqrB,IAActrB,IAAO,KAAK,IAAIqtB,CAAW,IAAIptB,IAAO,KAAK,IAAIotB,CAAW,GACxE9B,IAAcvrB,IAAO,KAAK,IAAIqtB,CAAW,IAAIptB,IAAO,KAAK,IAAIotB,CAAW,GAGxEjtC,IAAQ,KAAK,eAAuB,KAAK,KAAK,eAAe,MAAM,GACnE6qC,IAAgB7qC,EAAK,IACrB8qC,IAAgB9qC,EAAK,IAKrBF,IAAO,KAAK,eAAe,KAAA,GAC3BsrC,IAActrC,EAAK,IAAIA,EAAK,QAAQ,GACpCurC,IAAcvrC,EAAK,IAAIA,EAAK,SAAS;AAG3C,UAAI2rC,GAAWC;AACf,cAAQxmC,GAAA;AAAA,QACN,KAAK;AACH,UAAAumC,IAAYL,GACZM,IAAY5rC,EAAK;AACjB;AAAA,QACF,KAAK;AACH,UAAA2rC,IAAY3rC,EAAK,IAAIA,EAAK,OAC1B4rC,IAAYL;AACZ;AAAA,QACF,KAAK;AACH,UAAAI,IAAYL,GACZM,IAAY5rC,EAAK,IAAIA,EAAK;AAC1B;AAAA,QACF,KAAK;AACH,UAAA2rC,IAAY3rC,EAAK,GACjB4rC,IAAYL;AACZ;AAAA,MAAA;AAIJ,YAAMhB,IAAY,KAAK,eAAuB,UAAA,GAExCjuB,IADc,KAAK,eAAuB,KAAA,EAAO,UAAA,EAChB,SAAA,EAAW,UAAUiuB,CAAQ,GAE9DjvB,IAAiB,CAAC,CAACppB,IAAGC,EAAC,GAAa,EAAE,GAAAgF,IAAG,GAAAe,IAAG,GAAA3B,GAAG,GAAAtF,GAAG,GAAAiM,GAAG,GAAAC,QAClD,CAACjL,KAAIiF,KAAIhF,KAAIoE,IAAI2G,GAAGhL,KAAIgG,KAAI/F,KAAIlB,IAAIkM,CAAC,GAGxC,CAACwkB,GAAYC,CAAU,IAAItG,EAAe,CAACqwB,GAAWC,CAAS,GAAGtvB,CAAmB,GAGrFwvB,IAAqB,KAAK;AAAA,QAC9B,KAAK,IAAInqB,IAAaopB,GAAe,CAAC,IAAI,KAAK,IAAInpB,IAAaopB,GAAe,CAAC;AAAA,MAAA,GAG5EoC,IAAsBtB,GAItBE,IAAgBF,IAAqBjB,IAAUuC,GAE/CnB,IAAalB,IAAgBK,IAAcY,GAC3CE,IAAalB,IAAgBK,IAAcW,GAC3CG,IAAWF,IAAahY,IAAY,GACpCmY,IAAWF,IAAahY,IAAa,GAGrCmZ,IAAiB,KAAK,iBAAiBlB,GAAUC,GAAUtB,CAAa,GAGxE/b,IAAU,KAAK,MAAM,QAAQse,CAAc;AAEjD,UAAI,CAACte,GAAS;AACZ,gBAAQ,MAAM,qDAAqD;AACnE;AAAA,MACF;AAEA,cAAQ;AAAA,QACN;AAAA,QACAA,EAAQ;AAAA,QACR;AAAA,QACAod;AAAA,QACAC;AAAA,MAAA,GAIF,KAAK,sBAAA,GAGL,KAAK,oBAAoB,WAAW,MAAM;AACxC,QAAK,KAAK,cAAY,KAAK,cAAcrd,CAAO;AAAA,MAClD,GAAG,GAAG;AAAA,IACR,SAASlC,GAAO;AACd,cAAQ;AAAA,QACN;AAAA,QACAA;AAAA,MAAA;AAAA,IAEJ;AAAA,EACF;AAAA,EAEQ,iBAAiB36B,GAAWC,GAAW24C,GAA6B;AAE1E,UAAMwC,IAAQ,UAAU,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,OAAO,GAAG,CAAC;AAuB9D,WApBqB;AAAA,MACnB,GAAG,KAAK;AAAA,MACR,IAAIA;AAAA,MACJ,GAAAp7C;AAAA,MACA,GAAAC;AAAA,MACA,MAAM,QAAQm7C,EAAM,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOjC,QAAQ;AAAA,QACN,gBACGxC,MAAkB,SACfA,IACA,KAAK,QAAQ,QAAQ,kBAAkB;AAAA,MAAA;AAAA,IAC/C;AAAA,EAIJ;AAAA,EAEQ,cAActd,GAAuB;AAO3C,QAAI,KAAK,eAAe;AAEtB,UAAI,KAAK,cAAc,iBAAiBA,EAAW,EAAE;AACnD;AAEF,WAAK,cAAc,eAAeA,CAAU;AAC5C;AAAA,IACF;AAGA,QAAI,CAAC,KAAK,WAAW;AACnB,cAAQ;AAAA,QACN;AAAA,QACA,KAAK;AAAA,MAAA;AAEP;AAAA,IACF;AACA,IAAK,KAAK,UAAU,eAAa,KAAK,UAAU,OAAA,GAChD,KAAK,UAAU,UAAUA,CAAU;AAAA,EACrC;AACF;AC5yHO,MAAM+f,GAAa;AAAA,EAIxB,YAAYtgB,GAAc;AAF1B,SAAQ,4BAA+B,IAAA,GAGrC,KAAK,QAAQA;AAAA,EACf;AAAA,EAEO,IAAIlrB,IAAgC,IAAU;AAOnD,QALKA,EAAQ,OACXA,EAAQ,KAAK,KAAK,WAAA,IAIhB,KAAK,MAAM,IAAIA,EAAQ,EAAE;AAC3B,qBAAQ,KAAK,iBAAiBA,EAAQ,EAAE,kBAAkB,GACnD,KAAK,MAAM,IAAIA,EAAQ,EAAE;AAIlC,UAAMpO,IAAO,IAAIouC,GAAKhgC,GAAwB,KAAK,KAAK;AAGxD,gBAAK,MAAM,IAAIpO,EAAK,IAAIA,CAAI,GAErBA;AAAA,EACT;AAAA,EAEO,OAAOmQ,GAAqB;AACjC,UAAMnQ,IAAO,KAAK,MAAM,IAAImQ,CAAE;AAC9B,QAAInQ,GAAM;AAIR,UAAI;AACD,QAAAA,EAAa,eAAe,YAAA;AAAA,MAC/B,QAAY;AAAA,MAEZ;AAEA,kBAAK,SAAS,QAAQ,CAACqK,MAAU;AAC/B,YAAIA,EAAM,OAAO8F;AACjB,cAAI;AACF,YAAK9F,EAAc,eAAe,iBAAiB8F,CAAE,KAClD9F,EAAc,cAAc,kBAAkB8F,CAAE;AAAA,UAErD,QAAY;AAAA,UAEZ;AAAA,MACF,CAAC,GACDnQ,EAAK,OAAA,GACL,KAAK,MAAM,OAAOmQ,CAAE,GACb;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EAEO,IAAIA,GAA8B;AACvC,WAAO,KAAK,MAAM,IAAIA,CAAE;AAAA,EAC1B;AAAA,EAEA,IAAW,WAAmB;AAC5B,WAAO,MAAM,KAAK,KAAK,MAAM,QAAQ;AAAA,EACvC;AAAA,EAEO,QAAc;AACnB,SAAK,SAAS,QAAQ,CAAAnQ,MAAQA,EAAK,QAAQ,GAC3C,KAAK,MAAM,MAAA;AAAA,EACb;AAAA;AAAA,EAGO,UAAgB;AACrB,SAAK,MAAA,GACJ,KAAa,QAAQ;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,UAAU65C,GAAkBzrC,IAAiC,IAAI;AACtE,UAAMxP,IAAOi7C,GAAa,QAAQA,KAAe,CAAA,GAG3CxkC,IACJjH,EAAQ,YAAY,MAASxP,EAAK,QAAQ,IACtC,IACAA,EAAK,OAAO,KAEZk7C,IAOD,CAAA;AACL,IAAI,MAAM,QAAQl7C,EAAK,KAAK,KAC1BA,EAAK,MAAM;AAAA,MAAQ,CAACiP,MAClBisC,EAAM,KAAK;AAAA,QACT,IAAIjsC,EAAE;AAAA,QACN,GAAGA,EAAE;AAAA,QACL,GAAGA,EAAE;AAAA,QACL,SAASA,EAAE;AAAA,QACX,YAAY,OAAO,UAAU,eAAe,KAAKA,GAAG,SAAS;AAAA,QAC7D,UAAUA,EAAE;AAAA,MAAA,CACb;AAAA,IAAA,GAGD,MAAM,QAAQjP,EAAK,WAAW,KAChCA,EAAK,YAAY;AAAA,MAAQ,CAACiP,MACxBisC,EAAM,KAAK;AAAA,QACT,IAAIjsC,EAAE;AAAA,QACN,GAAGA,EAAE,QAAQA,EAAE;AAAA,QACf,GAAGA,EAAE,QAAQA,EAAE;AAAA,QACf,SAASA,EAAE;AAAA,QACX,YAAY,OAAO,UAAU,eAAe,KAAKA,GAAG,SAAS;AAAA,QAC7D,UAAUA,EAAE;AAAA,MAAA,CACb;AAAA,IAAA,GAILisC,EAAM,QAAQ,CAACt9C,MAAM;AACnB,YAAMwD,IAAO,KAAK,IAAIxD,EAAE,EAAE;AAC1B,MAAKwD,MACD,OAAOxD,EAAE,KAAM,YAAY,OAAOA,EAAE,KAAM,YAC5CwD,EAAK,SAASxD,EAAE,GAAGA,EAAE,GAAG,QAAW,QAAW6Y,CAAQ,GAMpD7Y,EAAE,eACJwD,EAAK,QAAQ,UAAUxD,EAAE,WAAW,SAElCA,EAAE,aAAa,MAAQ,CAACwD,EAAK,QAAQ,WACvCA,EAAK,KAAA,IACIxD,EAAE,aAAa,MAASwD,EAAK,QAAQ,YAC9CA,EAAK,OAAA;AAAA,IAET,CAAC;AAAA,EACH;AAAA;AAAA,EAGO,gBAAgB+5C,GAAuB;AAC5C,UAAM,EAAE,UAAAllB,GAAU,SAAA0G,GAAS,aAAAhQ,EAAA,IAAgBwuB,KAAoB,CAAA,GACzDzsC,IAASunB,IAAW,KAAK,IAAIA,CAAQ,IAAI;AAC/C,QAAI,CAACvnB,GAAQ;AACX,cAAQ,KAAK,sDAAsDunB,CAAQ;AAC3E;AAAA,IACF;AAIA,UAAMmlB,IAAOD,EAAyB;AACtC,QAAIC;AACF,UAAK1sC,EAAe,eAAe,mBAAmB0sC,CAAG,EAAG;AAAA,eAClD1sC,EAAe,eAAe,iBAAiBiuB,CAAO;AAChE;AAIF,QAAIhQ,GAAa;AACd,MAAAje,EAAe,eAAe;AAAA,QAC7Bie;AAAA,QACAwuB;AAAA,MAAA;AAEF;AAAA,IACF;AAEA,UAAMz4B,IAAQia,IAAU,KAAK,IAAIA,CAAO,IAAI;AAC5C,QAAI,CAACja,GAAO;AACV,cAAQ;AAAA,QACN;AAAA,QACAuT;AAAA,QACA0G;AAAA,MAAA;AAEF;AAAA,IACF;AACC,IAAAjuB,EAAe,eAAe,eAAegU,GAAOy4B,CAAgB;AAAA,EACvE;AAAA;AAAA,EAGO,mBAAmBA,GAAuB;AAC/C,UAAM,EAAE,UAAAllB,GAAU,SAAA0G,GAAS,IAAAprB,EAAA,IAAO4pC,KAAoB,CAAA,GAChDzsC,IAASunB,IAAW,KAAK,IAAIA,CAAQ,IAAI;AAC/C,IAAI,CAACvnB,KAAW,CAACiuB,KAAW,CAACprB,KAG5B7C,EAAe,eAAe,kBAAkB6C,KAAMorB,CAAO;AAAA,EAChE;AAAA,EAEQ,aAAqB;AAC3B,WAAO,UAAU,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,OAAO,GAAG,CAAC,IAAI,MAAM,KAAK,IAAA;AAAA,EACxE;AAAA,EAEO,QAAgB;AACrB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEO,QAAQroB,GAAkD;AAC/D,SAAK,MAAM,QAAQA,CAAQ;AAAA,EAC7B;AAAA,EAEO,OAAO+mC,GAA4C;AACxD,WAAO,KAAK,SAAS,OAAOA,CAAS;AAAA,EACvC;AAAA,EAEO,KAAKA,GAAsD;AAChE,WAAO,KAAK,SAAS,KAAKA,CAAS;AAAA,EACrC;AACF;ACrKO,SAASC,GACd5gB,GACA+F,GACA8a,GACW;AAGX,QAAMC,KAFc/a,KAAS/F,EAAM,MAAM,UAEO;AAAA,IAAI,CAACt5B,MACnDq6C,GAAcr6C,CAAI;AAAA,EAAA;AAIpB,SAAIm6C,KACFC,EAAgB,QAAQ,CAACvsC,GAAGysC,MAAQ;AAClC,IAAAzsC,EAAE,QAAQ,qBAAqBysC;AAAA,EACjC,CAAC,GAGI;AAAA,IACL,SAASC,GAAsBjhB,EAAM,OAAO;AAAA,IAC5C,OAAO8gB;AAAA,IACP,SAAS9gB,EAAM,QAAQ,WAAW;AAAA,EAAA;AAEtC;AAWA,eAAsBkhB,GACpBC,GACAnhB,GACAohB,IAAoB,IACpBC,IAAoB,IACL;AACf,QAAM/7C,IACJ,OAAO67C,KAAS,WAAW,KAAK,MAAMA,CAAI,IAAIA;AAIhD,EAAAnhB,EAAM,mBAAA;AACN,MAAI;AACF,UAAMshB,GAAiBh8C,GAAM06B,GAAOohB,GAAUC,CAAQ;AAAA,EACxD,UAAA;AACE,IAAArhB,EAAM,iBAAA;AAAA,EACR;AACF;AAEA,eAAeshB,GACbh8C,GACA06B,GACAohB,GACAC,GACe;AAEf,MAAI/7C,EAAK,SAAS;AAChB,UAAMi8C,IAAoCj8C,EAAK;AAC/C,WAAO,OAAO06B,EAAM,SAASuhB,CAAS,GAGlCj8C,EAAK,YACP06B,EAAM,QAAQ,UAAU16B,EAAK,UAI/B06B,EAAM,sBAAA;AAAA,EACR;AAGA,MAAI,CAACohB,GAAU;AACb,IAAAphB,EAAM,MAAM,MAAA;AAKZ,QAAI;AACD,MAAAA,EAAc,gBAAgB,QAAA;AAAA,IACjC,QAAY;AAAA,IAEZ;AAAA,EACF;AAGA,QAAMwhB,wBAAc,IAAA;AAEpB,MAAI,MAAM,QAAQl8C,EAAK,KAAK,GAAG;AAC7B,eAAWm8C,KAAYn8C,EAAK,OAAO;AACjC,YAAMo8C,IAAWC,GAAuBF,EAAS,OAAO,GAGlDG,IAAW5hB,EAAM,MAAM,IAAI0hB,EAAS,EAAE;AAC5C,UAAIE;AAEF,eAAO,OAAOA,EAAS,SAASF,CAAQ,GACpCA,EAAS,MAAM,UAAaA,EAAS,MAAM,UAC7CE,EAAS,SAASF,EAAS,GAAGA,EAAS,CAAC,GAE1CF,EAAQ,IAAIE,EAAS,IAAKE,CAAQ;AAAA,WAC7B;AACL,cAAMl7C,IAAOs5B,EAAM,QAAQ0hB,CAAQ;AACnC,QAAIh7C,KACF86C,EAAQ,IAAI96C,EAAK,IAAIA,CAAI;AAAA,MAE7B;AAAA,IACF;AAGA,UAAMm7C,IAAiC,CAAA;AACvC,eAAWn7C,KAAQ86C,EAAQ;AACzB,MAAI96C,EAAK,SACPm7C,EAAc,KAAKn7C,EAAK,KAAK;AAGjC,IAAIm7C,EAAc,SAAS,KACzB,MAAM,QAAQ,IAAIA,CAAa;AAIjC,eAAWJ,KAAYn8C,EAAK,OAAO;AACjC,YAAMw8C,IAASL,EAAS,QAAQ,MAAMA,EAAS,QAAQ,SAAS,SAC5DzO,GAAWyO,EAAS,OAAO,EAAE,KAC7BA,EAAS,QAAQ;AAErB,UAAI,CAACK,EAAQ;AAEb,YAAMC,IAAaP,EAAQ,IAAIM,CAAgB,KAAK9hB,EAAM,MAAM,IAAI8hB,CAAgB;AACpF,UAAI,CAACC,EAAY;AAEjB,YAAMC,IAAeP,EAAS,eAAe;AAC7C,UAAI,GAAC,MAAM,QAAQO,CAAY,KAAKA,EAAa,WAAW;AAE5D,mBAAWC,KAAaD,GAAc;AACpC,gBAAMzf,IAAQgR,GAAkB0O,CAAS;AAGzC,cAAK1f,EAAc,eAAewf,GAAY,eAAe;AAC3D,YAAAA,EAAW,cAAc;AAAA,cACtBxf,EAAc;AAAA,cACfA;AAAA,YAAA;AAEF;AAAA,UACF;AAEA,gBAAMkC,IACJ+c,EAAQ,IAAIjf,EAAM,OAAO,KAAKvC,EAAM,MAAM,IAAIuC,EAAM,OAAO;AAE7D,cAAIkC,KAAasd;AAEf,gBAAIA,EAAW;AACb,cAAAA,EAAW,cAAc,eAAetd,GAAWlC,CAAK;AAAA;AAGxD,kBAAI;AACF,gBAAKwf,EAAW,UAAU,eACxBA,EAAW,UAAU,OAAA,GAEvBA,EAAW,UAAU,UAAUtd,GAAW;AAAA,kBACxC,WAAWlC,EAAM;AAAA,kBACjB,WAAWA,EAAM;AAAA,gBAAA,CAClB;AAAA,cACH,SAAStyB,GAAG;AACV,wBAAQ;AAAA,kBACN;AAAA,kBACAsyB,EAAM;AAAA,kBACN;AAAA,kBACAA,EAAM;AAAA,kBACNtyB;AAAA,gBAAA;AAAA,cAEJ;AAAA,QAGN;AAAA,IACF;AAAA,EACF;AAYA,MAAI,CAACoxC,KAAYrhB,EAAM,SAAS;AAC9B,UAAMkiB,IAAiB,MAAM;AAC3B,YAAM97C,IAAK45B,EAAM,OAAO,YAAY,CAAA;AACpC,UAAI,CAAC55B,EAAG,OAAQ,QAAO;AACvB,UAAI+T,IAAO,OACTF,IAAO;AACT,iBAAW1F,KAAKnO,GAAI;AAClB,cAAMnB,IAAIsP,EAAE,QAAQ,KAAK,GACnByM,IAAIzM,EAAE,QAAQ,SAAS;AAC7B,QAAA4F,IAAO,KAAK,IAAIA,GAAMlV,CAAC,GACvBgV,IAAO,KAAK,IAAIA,GAAMhV,IAAI+b,CAAC;AAAA,MAC7B;AACA,cAAQ7G,IAAOF,KAAQ;AAAA,IACzB,GACMkoC,IAAa,CAACC,MAAkB;AACpC,UAAKpiB,EAAc,WAAY;AAC/B,YAAM9tB,IAAO8tB,EAAM,SAAS,wBAAA,GACtBqiB,IAAQ,CAAC,CAACnwC,KAAQA,EAAK,QAAQ,KAAKA,EAAK,SAAS,GAClD6hB,IAAMmuB,EAAA;AACZ,UAAIG,KAAStuB,MAAQ,MAAM;AACzB,YAAI;AACF,UAAAiM,EAAM,aAAA;AAAA,QACR,QAAY;AAAA,QAEZ;AAIA,cAAMsiB,IAAKtiB,EAAM,QAAQ,UAAA;AAGzB,YADEsiB,KAAM,KAAK,IAAIA,EAAG,IAAIA,EAAG,QAAQ,IAAIvuB,CAAG,IAAIuuB,EAAG,QAAQ,GAC7C;AACV,UAAI,OAAO,wBAA0B,OACnC,sBAAsB,MAAM;AAC1B,gBAAI;AACF,cAAAtiB,EAAM,aAAA;AAAA,YACR,QAAY;AAAA,YAEZ;AAAA,UACF,CAAC;AAEH;AAAA,QACF;AAAA,MACF;AACA,MAAIoiB,IAAQ,MAAI,WAAW,MAAMD,EAAWC,IAAQ,CAAC,GAAG,EAAE;AAAA,IAC5D;AACA,IAAAD,EAAW,CAAC;AAAA,EACd;AACF;AAKO,SAASpB,GAAcr6C,GAAqB;AACjD,QAAM68B,IAAO6P,EAAW1sC,EAAK,OAAO;AAGpC,MAAIA,EAAK;AACP,QAAI;AACF,YAAMqM,IAAOrM,EAAK,SAAS,KAAA;AAC3B,MAAA68B,EAAK,OAAO78B,EAAK,QAAQ,KAAKqM,EAAK,GACnCwwB,EAAK,OAAO78B,EAAK,QAAQ,KAAKqM,EAAK;AAAA,IACrC,QAAY;AACV,MAAAwwB,EAAK,OAAO78B,EAAK,QAAQ,KAAK,GAC9B68B,EAAK,OAAO78B,EAAK,QAAQ,KAAK;AAAA,IAChC;AAIF,MAAIA,EAAK,aAAa;AACpB,UAAM67C,IAAW77C,EAAK,YAAA;AACtB,IAAI67C,MAAa,MACfhf,EAAK,SAAS,EAAE,eAAegf,EAAA;AAAA,EAEnC;AAGA,QAAMP,IAAsC,CAAA;AAE5C,MAAIt7C,EAAK,iBAAiB,OAAOA,EAAK,cAAc,aAAc,YAAY;AAC5E,UAAM87C,IAAU97C,EAAK,cAAc,UAAA;AACnC,IAAI87C,GAAS,gBACXR,EAAa;AAAA,MACX,GAAGQ,EAAQ,aAAa,IAAI,CAACt4C,MAAWspC,GAAkBtpC,CAAC,CAAC;AAAA,IAAA;AAAA,EAGlE,WAAWxD,EAAK,WAAW;AAEzB,UAAM+7C,IAAc/7C,EAAK,UAAU,eAAA;AACnC,eAAW06B,KAAQqhB;AAEjB,OAAIrhB,EAAK,WAAW16B,KAAQ06B,EAAK,QAAQ,OAAO16B,EAAK,OACnDs7C,EAAa,KAAK;AAAA,QAChB,SAAS5gB,EAAK,QAAQ,MAAMA,EAAK;AAAA,QACjC,UAAU16B,EAAK;AAAA,QACf,gBAAgB;AAAA,QAChB,WAAW06B,EAAK,aAAa;AAAA,QAC7B,YAAY;AAAA,QACZ,aAAa;AAAA,QACb,UAAU;AAAA,QACV,eAAe;AAAA,QACf,eAAe;AAAA,QACf,WAAWA,EAAK,aAAa;AAAA,MAAA,CAC9B;AAAA,EAGP;AAEA,SAAO;AAAA,IACL,SAASmC;AAAA,IACT,eAAe;AAAA,MACb,cAAAye;AAAA,IAAA;AAAA,EACF;AAEJ;AAGO,SAASL,GACde,GACsB;AACtB,SAAO1P,GAAW0P,CAAQ;AAC5B;AAKA,SAASzB,GAAsBnsC,GAA4C;AAEzE,QAAMu3B,IAA2B,CAAA,GAG3BpnB,IAAO;AAAA,IACX;AAAA,IAAM;AAAA,IAAQ;AAAA,IAAe;AAAA,IAAa;AAAA,IAAY;AAAA,IACtD;AAAA,IAAW;AAAA,IAAa;AAAA,IAAY;AAAA,IACpC;AAAA,IAA8B;AAAA,IAC9B;AAAA,IACA;AAAA,IAAgB;AAAA,IAAkB;AAAA,IAClC;AAAA,IAAY;AAAA,IAAgB;AAAA,IAAc;AAAA,IAC1C;AAAA,IAAY;AAAA,IAAc;AAAA,IAAa;AAAA,IACvC;AAAA,IAAmB;AAAA,IAAkB;AAAA,IACrC;AAAA,IAAsB;AAAA,IACtB;AAAA,IAAoB;AAAA,IACpB;AAAA,IAAc;AAAA,IACd;AAAA,IACA;AAAA,IAAc;AAAA,IACd;AAAA,IAAQ;AAAA,IAAoB;AAAA,IAAkB;AAAA,EAAA;AAGhD,aAAWxf,KAAOwf;AAChB,IAAKnQ,EAAgBrP,CAAG,MAAM,WAC5B4mC,EAAI5mC,CAAG,IAAKqP,EAAgBrP,CAAG;AAKnC,SAAIqP,EAAQ,aACVu3B,EAAI,WAAW,EAAE,GAAGv3B,EAAQ,SAAA,IAE1BA,EAAQ,mBACVu3B,EAAI,iBAAiB,EAAE,GAAGv3B,EAAQ,eAAA,IAG7Bu3B;AACT;AAgBO,SAASsW,GAAS3iB,GAAuB;AAC9C,SAAO4gB,GAAU5gB,CAAK;AACxB;;;;;;;;;AClaO,MAAM4iB,GAAQ;AAAA,EAGnB,YAAY5iB,GAAc;AACxB,SAAK,QAAQA;AAAA,EACf;AAAA;AAAA,EAGO,UAAgB;AACpB,SAAa,QAAQ;AAAA,EACxB;AAAA,EAEA,OAAOwG,GAAmB;AACxB,QAAI,KAAK,MAAM,QAAQ,UAAU;AAC/B,YAAMrzB,IAAQqzB,EAAI,KAAK;AACvB,MAAI,OAAOrzB,KAAU,YAAYA,IAAQ,KAEvC,KAAK,MAAM,SAAS,KAAKA,CAAK;AAAA,IAElC;AAAA,EACF;AAAA,EAEA,iBAAiBqzB,GAAmB;AAClC,UAAM9/B,IAAO,KAAK,MAAM,MAAM,IAAI8/B,EAAI,KAAK,EAAE;AAC7C,IAAI9/B,KACFA,EAAK;AAAA,MACH8/B,EAAI,KAAK,SAAS;AAAA,MAClBA,EAAI,KAAK,SAAS;AAAA,MAClB,MAAM;AAAA,MAAC;AAAA,MACPA,EAAI,KAAK;AAAA,MACTA,EAAI,KAAK,YAAY;AAAA,IAAA;AAAA,EAG3B;AAAA,EAEA,kBAAkBA,GAAmB;AACnC,UAAM9/B,IAAO,KAAK,MAAM,MAAM,IAAI8/B,EAAI,KAAK,EAAE;AAC7C,IAAI9/B,GAAM,SACRA,EAAK,MAAM,MAAM,EAAK;AAAA,EAE1B;AAAA,EAEA,gBAAgB8/B,GAAmB;AACjC,UAAM9/B,IAAO,KAAK,MAAM,MAAM,IAAI8/B,EAAI,KAAK,EAAE,GAIvCpe,IAAQoe,EAAI,MAAc;AAChC,IAAI9/B,GAAM,SAAS0hB,KACjB1hB,EAAK,MAAM,IAAI0hB,GAAM,EAAK;AAAA,EAE9B;AAAA,EAEA,eAAeoe,GAAmB;AAChC,UAAM9/B,IAAO,KAAK,MAAM,MAAM,IAAI8/B,EAAI,KAAK,EAAE;AAC7C,IAAI9/B,KACFA,EAAK,OAAA;AAAA,EAET;AAAA,EAEA,aAAa8/B,GAAmB;AAC9B,UAAM9/B,IAAO,KAAK,MAAM,MAAM,IAAI8/B,EAAI,KAAK,EAAE;AAC7C,IAAI9/B,KACFA,EAAK,KAAA;AAAA,EAET;AAAA,EAEA,sBAAsB8/B,GAAmB;AACvC,UAAM9/B,IAAO,KAAK,MAAM,MAAM,IAAI8/B,EAAI,KAAK,EAAE;AAC7C,IAAI9/B,KACF8/B,EAAI,KAAK,gBAAgB,QAAQ,CAACv7B,MAAW;AAC3C,MAAI,OAAOA,EAAE,SAAU,YACpBvE,EAAK,QAAgBuE,EAAE,IAAI,IAAIA,EAAE,MAAM,KACxC,OAAO,KAAKA,EAAE,KAAK,EAAE,QAAQ,CAACX,MAAM;AAClC,QAAIA,MAAM,UACP5D,EAAK,QAAgB4D,CAAC,IAAIW,EAAE,MAAMX,CAAC;AAAA,MAExC,CAAC,KAEA5D,EAAK,QAAgBuE,EAAE,IAAI,IAAIA,EAAE;AAAA,IAEtC,CAAC;AAAA,EAEL;AAAA,EAEA,aAAau7B,GAAmB;AAC9B,UAAM9/B,IAAO,KAAK,MAAM,MAAM,IAAI8/B,EAAI,KAAK,EAAE;AAC7C,IAAI9/B,KACFA,EAAK,OAAA;AAAA,EAET;AAAA,EAEA,cAAc8/B,GAAmB;AAC/B,UAAM9/B,IAAO,KAAK,MAAM,MAAM,IAAI8/B,EAAI,KAAK,EAAE;AAC7C,IAAI9/B,KACFA,EAAK,QAAA;AAAA,EAET;AAAA,EAEA,mBAAmB8/B,GAAmB;AACpC,UAAM9/B,IAAO,KAAK,MAAM,MAAM,IAAI8/B,EAAI,KAAK,EAAE;AAC7C,QAAI,CAAC9/B,EAAM;AACX,UAAM+nB,IAAS+X,EAAI,KAAa,SAAUA,EAAI,KAAa;AAE3D,WAAO,OAAO9/B,EAAK,SAAS8/B,EAAI,IAAI,GAChC/X,KACF/nB,EAAK,SAAS+nB,GAAQ+X,EAAI,KAAa,UAAU;AAAA,EAErD;AAAA,EAEA,YAAYA,GAAmB;AAC7B,QAAIA,EAAI,MAAM;AAEZ,cAAQ,IAAI,sBAAsBA,EAAI,IAAI;AAAA,aACjCA,EAAI,KAAK,MAAMA,EAAI,KAAK,WAAW,CAACA,EAAI,KAAK;AAGtD,MADmB,KAAK,MAAM,MAAM,IAAIA,EAAI,KAAK,EAAE,KAGjD,KAAK,MAAM,MAAM,IAAI;AAAA,QACnB,GAAGA,EAAI,KAAK;AAAA,QACZ,GAAGA,EAAI,KAAK,cAAc;AAAA,QAC1B,GAAGA,EAAI,KAAK,cAAc;AAAA,MAAA,CAC3B;AAAA,SAEE;AAGL,UAAIqc,IAAgBrc,EAAI,KAAK;AAC7B,MAAK,MAAM,QAAQqc,CAAa,MAC9BA,IAAgB,CAACA,CAAa,IAEhCA,EAAc,OAAO,OAAO,EAAE,QAAQ,CAACC,MAAe;AAEpD,QADe,KAAK,MAAM,MAAM,IAAIA,EAAM,EAAE,KAE1C,KAAK,MAAM,MAAM,IAAI9P,GAAW8P,CAAK,CAAQ;AAAA,MAEjD,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,mBAAmBtc,GAAmB;AACpC,UAAM9/B,IAAO,KAAK,MAAM,MAAM,IAAI8/B,EAAI,KAAK,EAAE;AAC7C,QAAI,CAAC9/B,GAAM,OAAQ;AAEnB,UAAMiT,IAAO6sB,EAAI,KAAa,OAAQA,EAAI,KAAa;AACvD,IAAI7sB,IACFjT,EAAK,OAAO,IAAIiT,GAAM6sB,EAAI,KAAa,GAAIA,EAAI,KAAa,CAAC,IAE7D9/B,EAAK,OAAO,MAAA;AAAA,EAEhB;AAAA,EAEA,cAAc8/B,GAAmB;AAC/B,SAAK,MAAM,MAAM,OAAOA,EAAI,KAAK,EAAE;AAAA,EACrC;AAAA,EAEA,cAAcA,GAAmB;AAC/B,UAAM9/B,IAAO,KAAK,MAAM,MAAM,IAAI8/B,EAAI,KAAK,EAAE;AAC7C,IAAI9/B,MACF,OAAO,OAAOA,EAAK,SAAS8/B,EAAI,IAAI,GACpC9/B,EAAK,QAAQ8/B,EAAI,KAAK,OAAOA,EAAI,KAAK,MAAM;AAAA,EAEhD;AAAA,EAEA,cAAcA,GAAmB;AAC/B,UAAM9/B,IAAO,KAAK,MAAM,MAAM,IAAI8/B,EAAI,KAAK,EAAE;AAC7C,QAAI9/B,GAAM;AACR,MAAI8/B,EAAI,KAAK,eAAe,WAC1B9/B,EAAK,QAAQ,aAAa8/B,EAAI,KAAK;AAErC,YAAMtuB,IACJsuB,EAAI,KAAK,QAAQ,iBAAiBA,EAAI,KAAK;AAC7C,MAAI,OAAOtuB,KAAU,YAGnBxR,EAAK,YAAYwR,GAAO,GAAG,GAEzBsuB,EAAI,KAAK,SAASA,EAAI,KAAK,UAC7B9/B,EAAK,QAAQ8/B,EAAI,KAAK,OAAOA,EAAI,KAAK,MAAM;AAAA,IAEhD;AAAA,EACF;AAAA,EAEA,mBAAmBA,GAAmB;AACpC,UAAM9/B,IAAO,KAAK,MAAM,MAAM,IAAI8/B,EAAI,KAAK,EAAE;AAC7C,IAAI9/B,MAEFA,EAAK;AAAA,MACH8/B,EAAI,KAAK,SAASA,EAAI,KAAK;AAAA,MAC3BA,EAAI,KAAK;AAAA,IAAA,GAEPA,EAAI,KAAK,YAAY,WACvB9/B,EAAK,QAAQ,UAAU8/B,EAAI,KAAK,SAChC9/B,EAAK,aAAA;AAAA,EAGX;AAAA,EAEA,kBAAkB8/B,GAAmB;AACnC,UAAM9/B,IAAO,KAAK,MAAM,MAAM,IAAI8/B,EAAI,KAAK,EAAE;AAC7C,IAAK9/B,MAGD8/B,EAAI,KAAK,aAAa,aAAgB,QAAQ,WAAWA,EAAI,KAAK,WAClEA,EAAI,KAAK,eAAe,aAAgB,QAAQ,aAAaA,EAAI,KAAK,aACtEA,EAAI,KAAK,cAAc,aAAgB,QAAQ,YAAYA,EAAI,KAAK,YACpEA,EAAI,KAAK,gBAAgB,aAAgB,QAAQ,cAAcA,EAAI,KAAK,cACxEA,EAAI,KAAK,eAAe,aAAgB,QAAQ,aAAaA,EAAI,KAAK,aACtEA,EAAI,KAAK,eAAe,aAAgB,QAAQ,aAAaA,EAAI,KAAK,aAEtEA,EAAI,KAAK,SAAS,YAAgB,QAAQA,EAAI,KAAK,IAAI,GAC3D9/B,EAAK,eAAA;AAAA,EACP;AAAA,EAEA,oBAAoB8/B,GAAmB;AACrC,UAAM9/B,IAAO,KAAK,MAAM,MAAM,IAAI8/B,EAAI,KAAK,EAAE;AAC7C,IAAI9/B,MAKFA,EAAK,QAAQ,KAAK,EAAE,GAAGA,EAAK,QAAQ,IAAI,GAAG8/B,EAAI,KAAK,GAAA;AAAA,EAExD;AAAA,EAEA,gBAAgBA,GAAmB;AACjC,SAAK,MAAM,MAAM,gBAAgBA,EAAI,IAAI;AAAA,EAC3C;AAAA,EAEA,mBAAmBA,GAAmB;AACpC,SAAK,MAAM,MAAM,mBAAmBA,EAAI,IAAI;AAAA,EAC9C;AAAA,EAEA,YAAYA,GAAmB;AAG7B,SAAK,MAAM,MAAM,UAAUA,CAAG;AAAA,EAChC;AAAA,EAEA,oBAAoBA,GAAmB;AACrC,UAAM9/B,IAAO,KAAK,MAAM,MAAM,IAAI8/B,EAAI,KAAK,EAAE;AAC7C,QAAI,CAAC9/B,GAAM,QAAS;AAEpB,UAAM5C,IAAU0iC,EAAI,KAAa;AACjC,QAAI,CAAC1iC,EAAQ;AACb,UAAM8X,IAAS9X,EAAO,UAAU,SAAS,SAAS,QAC5Ci/C,IAASnnC,MAAW,SAAS,SAAS;AAC5C,QAAI9X,EAAO,aAAa;AACtB,MAAA4C,EAAK,QAAQ,gBAAgBkV,CAAM,GAC/B9X,EAAO,MAAMA,EAAO,OAAO,UAAUA,EAAO,OAAO,UACrD4C,EAAK,QAAQ,eAAe5C,EAAO,IAAI8X,CAAM;AAE/C;AAAA,IACF;AACA,UAAMjU,IAAOjB,EAAK,QAAQ,UAAUq8C,CAAM;AAE1C,IAAIp7C,KAAMjB,EAAK,QAAQ,OAAOiB,CAAI,GAC9B7D,EAAO,KACT4C,EAAK,QAAQ,MAAM5C,EAAO,IAAI8X,CAAkC,IACvDlV,EAAK,QAAQ,YAEtBA,EAAK,QAAQ,QAAQq8C,CAAM,IAAI;AAAA,EAEnC;AAAA,EAEA,8BAA8Bvc,GAAmB;AAC/C,UAAM9/B,IAAO,KAAK,MAAM,MAAM,IAAI8/B,EAAI,KAAK,EAAE;AAC7C,QAAI,CAAC9/B,EAAM;AACX,UAAM,EAAE,MAAA88B,GAAM,KAAA95B,EAAA,IAAQ88B,EAAI;AAC1B,IAAIhD,MAAS,SAGT98B,EAAK,QAAgB88B,CAAI,IAAI95B,KAG3B88B,EAAI,KAAK,gBAAgB,aAAgB,QAAQ,cAAcA,EAAI,KAAK,cACxEA,EAAI,KAAK,gBAAgB,aAAgB,QAAQ,cAAcA,EAAI,KAAK,eAE9E9/B,EAAK,YAAA;AAAA,EACP;AAAA,EAEA,wBAAwB8/B,GAAmB;AAEzC,KADa,MAAM,QAAQA,EAAI,IAAI,IAAIA,EAAI,OAAO,CAACA,EAAI,IAAI,GACtD,QAAQ,CAACn7B,MAAW;AACvB,YAAM3E,IAAO,KAAK,MAAM,MAAM,IAAI2E,EAAE,EAAE;AACtC,MAAK3E,MAID2E,EAAE,iBAAiBA,EAAE,SAAS,UAAa3E,EAAK,gBAClDA,EAAK,cAAc,kBAAkB2E,EAAE,eAAeA,EAAE,MAAMA,EAAE,GAAG,IAC1DA,EAAE,WAEX,OAAO,OAAO3E,EAAK,SAAS2E,EAAE,OAAO;AAAA,IAEzC,CAAC;AAAA,EACH;AAAA,EAEA,kBAAkBm7B,GAAmB;AACnC,SAAK,MAAM,QAAQ,WAAWA,EAAI,MAAM;AAAA,EAC1C;AAAA,EAEA,aAAaA,GAAmB;AAC9B,QAAI,KAAK,MAAM,QAAQ,UAAU;AAC/B,YAAM,EAAE,MAAA5a,GAAM,KAAAD,EAAA,IAAQ6a,EAAI,QAAQ,CAAA;AAClC,MAAI,OAAO5a,KAAS,YAAY,OAAOD,KAAQ,YAC7C,KAAK,MAAM,IAAI,EAAE,GAAGC,GAAM,GAAGD,GAAK;AAAA,IAEtC;AAAA,EACF;AAAA,EAEA,oBAAoB6a,GAAmB;AACrC,UAAMwc,IAAQxc,EAAI,MAAM;AACxB,IAAIwc,GAAO,QAAK,KAAK,MAAM,QAAQ,UAAUA,EAAM,MAC/CA,KAEF,KAAK,MAAM,WAAWA,GAAQxc,EAAI,MAAc,aAAa;AAAA,EAEjE;AAAA,EAEA,yBAAyBA,GAAmB;AAC1C,IAAIA,EAAI,KAAK,cAAc,SACzB,KAAK,MAAM,QAAQ,aAAaA,EAAI,KAAK,aAEvCA,EAAI,KAAK,8CAA8C,SACzD,KAAK,MAAM,QAAQ,6CACjBA,EAAI,KAAK;AAAA,EAEf;AAAA,EAEA,+BAA+BA,GAAmB;AAChD,SAAK,MAAM,QAAQ,eAAgB,mBAAmBA,EAAI,KAAK,QAE/D,QAAQ,IAAI,8BAA8BA,EAAI,KAAK,MAAM;AAAA,EAC3D;AAAA,EAEA,8BAA8BA,GAAmB;AAC/C,QAAIA,EAAI,KAAK;AACX,WAAK,MAAM,QAAQ,eAAgB,kBAAkBA,EAAI,KAAK,GAAG,KACjE,KAAK,MAAM,QAAQ,eAAgB,iBAAiBA,EAAI,KAAK,GAAG,MAEhE,KAAK,MAAM,QAAQ,eAAgB,4BAA4B;AAAA,SAC1D;AACL,YAAMl9B,IAAI,KAAK,MAAM,QAAQ,gBAAgB,uBAAuB;AACpE,WAAK,MAAM,QAAQ,eAAgB,kBAAkBA,GACrD,KAAK,MAAM,QAAQ,eAAgB,kBAAkB,QACrD,KAAK,MAAM,QAAQ,eAAgB,mBAAmB;AAAA,IACxD;AAEA,SAAK,MAAM,oBAAA;AAAA,EACb;AAAA,EAEA,8BAA8Bk9B,GAAmB;AAC/C,UAAMyc,IAAK,KAAK,MAAM,QAAQ;AAC9B,IAAAA,EAAG,kBAAkBzc,EAAI,KAAK,OAC9Byc,EAAG,4BAA4Bzc,EAAI,KAAK,YACxCyc,EAAG,yBAAyBzc,EAAI,KAAK,cACrCyc,EAAG,2BAA2Bzc,EAAI,KAAK,gBACvCyc,EAAG,6BAA6Bzc,EAAI,KAAK,kBACzCyc,EAAG,kBAAkB,QACrBA,EAAG,mBAAmB,QAEtB,KAAK,MAAM,oBAAA;AAAA,EACb;AAAA,EAEA,mBAAmBzc,GAAmB;AACpC,SAAK,MAAM,QAAQ,mBAAmBA,EAAI,KAAK,OAC/C,KAAK,MAAM,MAAM,SAAS,QAAQ,CAAC9/B,MAAc;AAC/C,MAAAA,EAAK,QAAQ,YAAY8/B,EAAI,KAAK,OAC9B9/B,EAAK,eAAe,iBACtBA,EAAK,cAAc,aAAa,QAAQ,CAACwD,MAAW;AAClD,QAAAA,EAAE,YAAYs8B,EAAI,KAAK;AAAA,MACzB,CAAC,GACD9/B,EAAK,cAAc,wBAAA;AAAA,IAEvB,CAAC;AAAA,EACH;AAAA,EAEA,aAAa8/B,GAAmB;AAC9B,SAAK,MAAM,QAAQ,KAAK;AAAA,MACtB,GAAI,KAAK,MAAM,QAAQ,MAAM,CAAA;AAAA,MAC7B,GAAGA,EAAI;AAAA,IAAA;AAAA,EAEX;AAAA,EAEA,mBAAmBA,GAAmB;AACpC,SAAK,MAAM,QAAQ,OAAOA,EAAI,KAAK;AAAA,EACrC;AAAA,EAEA,0BAA0BA,GAAmB;AAC3C,SAAK,MAAM,QAAQ,cAAcA,EAAI,KAAK;AAAA,EAC5C;AAAA;AAAA,EAGA,MAAM,gBAAgBA,GAAmB;AACvC,UAAMmc,IAAWnc,EAAI,MAAM;AAC3B,IAAKmc,KACL,MAAMzB,GAAYyB,GAAU,KAAK,OAAO,IAAO,EAAI;AAAA,EACrD;AAAA,EAEA,uBAAuBnc,GAAmB;AACxC,SAAK,MAAM,QAAQ,SAAU,WAAWA,EAAI,KAAK,UAG7CA,EAAI,KAAK,WACX,KAAK,MAAM,MAAM,KAAA,IAEjB,KAAK,MAAM,MAAM,KAAA;AAAA,EAErB;AAAA,EAEA,0BAA0BA,GAAmB;AAC3C,SAAK,MAAM,QAAQ,cAAcA,EAAI,KAAK;AAAA,EAC5C;AAAA,EAEA,yCAAyCA,GAAmB;AAC1D,SAAK,MAAM,QAAQ,6BAA6BA,EAAI,KAAK;AAAA,EAC3D;AAAA,EAEA,sCAAsCA,GAAmB;AACvD,SAAK,MAAM,QAAQ,OAAOA,EAAI,KAAK,MACnC,KAAK,MAAM,QAAQ,mBAAmBA,EAAI,KAAK,kBAC/C,KAAK,MAAM,QAAQ,iBAAiBA,EAAI,KAAK;AAAA,EAC/C;AAAA,EAEA,uBAAuBA,GAAmB;AACxC,SAAK,MAAM,QAAQ,aAAaA,EAAI,KAAK;AAAA,EAC3C;AAAA,EAEA,4BAA4BA,GAAmB;AAC7C,SAAK,MAAM,QAAQ,SAAU,gBAAgBA,EAAI,KAAK;AAAA,EACxD;AAAA,EAEA,yBAAyBA,GAAmB;AAC1C,SAAK,MAAM,QAAQ,SAAU,aAAaA,EAAI,KAAK,YAEnD,KAAK,MAAM,MAAM,cAAc,EAAE,YAAY,CAAC,CAACA,EAAI,KAAK,YAAY;AAAA,EACtE;AAAA,EAEA,uBAAuBA,GAAmB;AACxC,SAAK,MAAM,QAAQ,WAAWA,EAAI,KAAK;AAAA,EACzC;AAAA,EAEA,qBAAqBA,GAAmB;AACtC,IAAIA,EAAI,KAAK,cAAc,SACzB,KAAK,MAAM,QAAQ,aAAaA,EAAI,KAAK,aAEvCA,EAAI,KAAK,iBAAiB,SAC5B,KAAK,MAAM,QAAQ,gBAAgBA,EAAI,KAAK;AAAA,EAEhD;AACF;AChbO,MAAM0c,GAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAanB,YAAYljB,GAAYlrB,IAA0B,IAAI;AATtD,SAAQ,YAAqB,IAC7B,KAAQ,oBAA2C,MAyFnD,KAAQ,gBAAkD,MAhFxD,KAAK,QAAQkrB,GACb,KAAK,SAASA,EAAM,QACpB,KAAK,UAAU;AAAA,MACb,SAAS;AAAA,MACT,SAAS;AAAA,MACT,WAAW;AAAA,MACX,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA,MAIX,WAAW;AAAA,MACX,cAAc;AAAA,MACd,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,SAAS;AAAA,MACT,8BAA8B;AAAA,MAC9B,gCAAgC;AAAA,MAChC,UAAU;AAAA;AAAA,MACV,kBAAkB;AAAA;AAAA,MAClB,cAAc;AAAA;AAAA,MACd,kBAAkB;AAAA,MAClB,GAAGlrB;AAAA,IAAA,GAGD,KAAK,QAAQ,WACf,KAAK,KAAA;AAAA,EAET;AAAA,EAEQ,OAAO;AACb,QAAI;AAIF,WAAK,OAAO,QAAQ;AAAA,QAClB,SAAS,KAAK,QAAQ;AAAA,QACtB,WAAW,KAAK,QAAQ;AAAA,QACxB,WAAW;AAAA,QACX,WAAW,KAAK,QAAQ;AAAA,QACxB,cAAc,KAAK,QAAQ;AAAA,QAC3B,SAAS,KAAK,QAAQ;AAAA,QACtB,YAAY,KAAK,QAAQ;AAAA,QACzB,SAAS,KAAK,QAAQ;AAAA,QACtB,SAAS,KAAK,QAAQ;AAAA,QACtB,8BAA8B,KAAK,QAAQ;AAAA,QAC3C,gCAAgC,KAAK,QAAQ;AAAA,QAC7C,UAAU,KAAK,QAAQ;AAAA,QACvB,kBAAkB,KAAK,QAAQ;AAAA,MAAA,CAChC,GAED,KAAK,mBAAA,GAEL,KAAK,YAAY,IAGb,KAAK,QAAQ,cACf,KAAK,OAAO,GAAG,YAAY,KAAK,QAAQ,UAAU,GAEhD,KAAK,QAAQ,SACf,KAAK,OAAO,GAAG,WAAW,KAAK,QAAQ,KAAK,GAE1C,KAAK,QAAQ,YACf,KAAK,OAAO,GAAG,UAAU,KAAK,QAAQ,QAAQ,GAE5C,KAAK,QAAQ,UACf,KAAK,OAAO,GAAG,QAAQ,KAAK,QAAQ,MAAM,GAIxC,KAAK,QAAQ,gBACf,KAAK,mBAAA,GAGP,QAAQ,IAAI,sDAAsD;AAAA,IACpE,SAAS8qB,GAAO;AACd,cAAQ,KAAK,kCAAkCA,CAAK;AAAA,IACtD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYQ,qBAA2B;AACjC,UAAMl5B,IAAO,KAAK,OAAO;AACzB,IAAI,CAACA,KAAQ,OAAOA,EAAK,oBAAqB,eAC9C,KAAK,gBAAgB,CAAC,MAAkB;AACtC,UAAI,CAAC,KAAK,UAAW;AACrB,QAAE,eAAA;AAEF,YAAM47C,IAAK,KAAK,OAAO,QAAA,GACjBpwC,IAAOxL,EAAK,sBAAA,GACZ+I,IAAKyC,EAAK,SAASowC,EAAG,OACtBa,IAAab,EAAG,QAAQ7yC;AAE9B,UAAI,EAAE,WAAW,EAAE,SAAS;AAI1B,cAAMyH,IAAS,KAAK,IAAI,CAAC,EAAE,SAAS,KAAM,GACpC5K,IAAM,KAAK,QAAQ,WAAW,KAC9BD,IAAM,KAAK,QAAQ,WAAW;AAEpC,YAAI+2C,IADY3zC,IAAK6yC,EAAG,QACAprC;AACxB,QAAAksC,IAAU,KAAK,IAAI92C,GAAK,KAAK,IAAID,GAAK+2C,CAAO,CAAC;AAC9C,cAAMC,IAAO5zC,IAAK2zC,GACZE,IAAQhB,EAAG,SAASA,EAAG,QAASe,GAEhCE,IAAM,EAAE,UAAUrxC,EAAK,MACvBsxC,IAAM,EAAE,UAAUtxC,EAAK,KACvBqhB,IAAK+uB,EAAG,IAAIiB,IAAMJ,GAClB3vB,IAAK8uB,EAAG,IAAIkB,KAAOlB,EAAG,SAASpwC,EAAK,UAAUixC,IAC9CnuB,IAAKzB,IAAMgwB,IAAM9zC,IAAM4zC,GACvBpuB,IAAKzB,IAAMgwB,KAAOtxC,EAAK,UAAUzC,KAAO6zC;AAC9C,aAAK,OAAO,QAAQtuB,GAAIC,GAAIouB,GAAMC,CAAI;AAAA,MACxC;AAEE,aAAK,OAAO;AAAA,UACVhB,EAAG,IAAI,EAAE,SAASa;AAAA,UAClBb,EAAG,IAAI,EAAE,SAASa;AAAA,UAClBb,EAAG;AAAA,UACHA,EAAG;AAAA,QAAA;AAKP,WAAK,QAAQ,QAAQ,CAAC,GACtB,KAAK,QAAQ,SAAS,CAAC;AAAA,IACzB,GACA57C,EAAK,iBAAiB,SAAS,KAAK,eAAe,EAAE,SAAS,IAAO;AAAA,EACvE;AAAA,EAEQ,qBAA2B;AAEjC,SAAK,oBAAoB,SAAS,cAAc,KAAK,GACrD,KAAK,kBAAkB,YAAY;AAGnC,UAAMe,IAAW,KAAK,QAAQ,oBAAoB;AAIlD,YAHA,KAAK,kBAAkB,MAAM,WAAW,YACxC,KAAK,kBAAkB,MAAM,SAAS,OAE9BA,GAAA;AAAA,MACN,KAAK;AACH,aAAK,kBAAkB,MAAM,MAAM,QACnC,KAAK,kBAAkB,MAAM,OAAO;AACpC;AAAA,MACF,KAAK;AACH,aAAK,kBAAkB,MAAM,MAAM,QACnC,KAAK,kBAAkB,MAAM,QAAQ;AACrC;AAAA,MACF,KAAK;AACH,aAAK,kBAAkB,MAAM,SAAS,QACtC,KAAK,kBAAkB,MAAM,OAAO;AACpC;AAAA,MACF,KAAK;AACH,aAAK,kBAAkB,MAAM,SAAS,QACtC,KAAK,kBAAkB,MAAM,QAAQ;AACrC;AAAA,IAAA;AAIJ,UAAMg8C,IAAY,SAAS,cAAc,QAAQ;AACjD,IAAAA,EAAU,cAAc,KACxBA,EAAU,QAAQ,WAClBA,EAAU,iBAAiB,SAAS,MAAM,KAAK,QAAQ,GACvD,KAAK,kBAAkB,YAAYA,CAAS;AAG5C,UAAMC,IAAa,SAAS,cAAc,QAAQ;AAClD,IAAAA,EAAW,cAAc,KACzBA,EAAW,QAAQ,YACnBA,EAAW,iBAAiB,SAAS,MAAM,KAAK,SAAS,GACzD,KAAK,kBAAkB,YAAYA,CAAU;AAG7C,UAAMC,IAAW,SAAS,cAAc,QAAQ;AAChD,IAAAA,EAAS,cAAc,KACvBA,EAAS,QAAQ,cACjBA,EAAS,iBAAiB,SAAS,MAAM,KAAK,OAAO,GACrD,KAAK,kBAAkB,YAAYA,CAAQ,GAG3C,KAAK,MAAM,QAAQ,YAAY,KAAK,iBAAiB;AAAA,EACvD;AAAA,EAEQ,qBAA2B;AACjC,IAAI,KAAK,qBAAqB,KAAK,kBAAkB,eACnD,KAAK,kBAAkB,WAAW,YAAY,KAAK,iBAAiB,GACpE,KAAK,oBAAoB;AAAA,EAE7B;AAAA,EAEO,SAAS;AACd,IAAK,KAAK,aACR,KAAK,KAAA,GAEP,KAAK,QAAQ,UAAU;AAAA,EACzB;AAAA,EAEO,UAAU;AACf,IAAI,KAAK,cACP,KAAK,OAAO,QAAQ,EAAK,GACzB,KAAK,YAAY,KAEnB,KAAK,QAAQ,UAAU;AAAA,EACzB;AAAA,EAEO,YAAY;AACjB,SAAK,QAAQ,UAAU,IACnB,KAAK,aACP,KAAK,OAAO,QAAQ,EAAE,GAAG,KAAK,cAAA,GAAiB,SAAS,IAAM;AAAA,EAElE;AAAA,EAEO,aAAa;AAClB,SAAK,QAAQ,UAAU,IACnB,KAAK,aACP,KAAK,OAAO,QAAQ,EAAE,GAAG,KAAK,cAAA,GAAiB,SAAS,IAAO;AAAA,EAEnE;AAAA,EAEO,aAAa;AAClB,SAAK,QAAQ,YAAY,IACzB,KAAK,QAAQ,YAAY,IACrB,KAAK,aACP,KAAK,OAAO,QAAQ,EAAE,GAAG,KAAK,cAAA,GAAiB,WAAW,IAAM,WAAW,GAAA,CAAM;AAAA,EAErF;AAAA,EAEO,cAAc;AACnB,SAAK,QAAQ,YAAY,IACzB,KAAK,QAAQ,YAAY,IACrB,KAAK,aACP,KAAK,OAAO,QAAQ,EAAE,GAAG,KAAK,cAAA,GAAiB,WAAW,IAAO,WAAW,GAAA,CAAO;AAAA,EAEvF;AAAA,EAEO,IAAI/0C,GAAiC;AAC1C,QAAI,KAAK,WAAW;AAElB,YAAM0zC,IAAK,KAAK,OAAO,QAAA;AAEvB,WAAK,OAAO,QAAQ1zC,EAAM,GAAGA,EAAM,GAAG0zC,EAAG,OAAOA,EAAG,MAAM;AAAA,IAC3D;AAAA,EACF;AAAA,EAEO,MAAM91C,GAAiC;AAC5C,QAAI,KAAK,WAAW;AAClB,YAAM81C,IAAK,KAAK,OAAO,QAAA;AACvB,WAAK,OAAO,QAAQA,EAAG,IAAI91C,EAAM,GAAG81C,EAAG,IAAI91C,EAAM,GAAG81C,EAAG,OAAOA,EAAG,MAAM;AAAA,IACzE;AAAA,EACF;AAAA,EAEO,KAAKnvC,GAAevE,GAAkC;AAC3D,IAAI,KAAK,cACHA,IACF,KAAK,OAAO,KAAKuE,GAAOvE,CAAK,IAE7B,KAAK,OAAO,KAAKuE,CAAK;AAAA,EAG5B;AAAA,EAEO,OAAO+D,GAAgB;AAC5B,QAAI,KAAK,WAAW;AAClB,YAAM0sC,IAAc,KAAK,QAAA;AACzB,WAAK,OAAO,KAAKA,IAAc1sC,CAAM;AAAA,IACvC;AAAA,EACF;AAAA;AAAA,EAGO,SAAS;AACd,QAAI,KAAK,WAAW;AAClB,YAAM0sC,IAAc,KAAK,QAAA;AACzB,WAAK,OAAO,KAAKA,IAAc,IAAI;AAAA,IACrC;AAAA,EACF;AAAA;AAAA,EAGO,UAAU;AACf,QAAI,KAAK,WAAW;AAClB,YAAMA,IAAc,KAAK,QAAA;AACzB,WAAK,OAAO,KAAKA,IAAc,GAAG;AAAA,IACpC;AAAA,EACF;AAAA,EAEO,YAAYzwC,GAAevE,GAAiC;AACjE,IAAI,KAAK,aACP,KAAK,OAAO,KAAKuE,GAAOvE,CAAK;AAAA,EAEjC;AAAA,EAEO,QAAQ;AACb,QAAI,CAAC,KAAK,UAAW;AAGrB,UAAMa,IAAK,KAAK,YAAA,GACV6yC,IAAK,KAAK,OAAO,QAAA,KAAa,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO7yC,EAAG,GAAG,QAAQA,EAAG,EAAA,GACpEU,KAAMmyC,EAAG,KAAK,MAAMA,EAAG,SAAS7yC,EAAG,KAAK,GACxCW,KAAMkyC,EAAG,KAAK,MAAMA,EAAG,UAAU7yC,EAAG,KAAK;AAC/C,SAAK,OAAO,QAAQU,IAAKV,EAAG,IAAI,GAAGW,IAAKX,EAAG,IAAI,GAAGA,EAAG,GAAGA,EAAG,CAAC,GAC5D,KAAK,IAAA;AAAA,EACP;AAAA;AAAA,EAGQ,cAAwC;AAE9C,UAAMyC,IADK,KAAK,OAAO,SACN,wBAAA;AACjB,WAAO;AAAA,MACL,GAAG,KAAK,IAAI,GAAG,KAAK,MAAMA,GAAM,SAAS,KAAK,OAAO,KAAK,eAAe,GAAG,CAAC;AAAA,MAC7E,GAAG,KAAK,IAAI,GAAG,KAAK,MAAMA,GAAM,UAAU,KAAK,OAAO,KAAK,gBAAgB,GAAG,CAAC;AAAA,IAAA;AAAA,EAEnF;AAAA,EAEO,YAAY;AACjB,IAAI,KAAK,aACP,KAAK,OAAO,KAAK,CAAC;AAAA,EAEtB;AAAA,EAEO,WAAW;AAChB,QAAI,KAAK,WAAW;AAClB,YAAMowC,IAAK,KAAK,OAAO,QAAA;AACvB,WAAK,OAAO,QAAQ,GAAG,GAAGA,EAAG,OAAOA,EAAG,MAAM;AAAA,IAC/C;AAAA,EACF;AAAA,EAEO,MAAM;AAEX,QAAI,CAAC,KAAK,UAAW;AAGrB,UAAMvc,IAAQ,KAAK,OAAO,OAAO;AACjC,QAAI,CAACA,KAASA,EAAM,WAAW,EAAG;AAElC,QAAI5rB,IAAO,OAAUC,IAAO,OAAUH,IAAO,QAAWC,IAAO;AAC/D,eAAWxT,KAAQq/B,GAAO;AACxB,YAAM9gC,IAAIyB,EAAK,QAAQ,KAAK,GACtBxB,IAAIwB,EAAK,QAAQ,KAAK,GACtBsa,IAAIta,EAAK,QAAQ,SAAS,KAC1BsF,IAAItF,EAAK,QAAQ,UAAU;AACjC,MAAAyT,IAAO,KAAK,IAAIA,GAAMlV,CAAC,GACvBmV,IAAO,KAAK,IAAIA,GAAMlV,CAAC,GACvB+U,IAAO,KAAK,IAAIA,GAAMhV,IAAI+b,CAAC,GAC3B9G,IAAO,KAAK,IAAIA,GAAMhV,IAAI8G,CAAC;AAAA,IAC7B;AAEA,QAAI,CAAC,SAASmO,CAAI,EAAG;AAErB,UAAM0pC,IAAe5pC,IAAOE,GACtB2pC,IAAgB5pC,IAAOE,GACvB+sB,IAAU,IAGV4c,IAAUF,IAAe1c,IAAU,GACnC6c,IAAWF,IAAgB3c,IAAU,GACrC13B,IAAK,KAAK,YAAA,GACVw0C,IAAkBx0C,EAAG,IAAIA,EAAG,GAC5By0C,IAAgBH,IAAUC;AAEhC,QAAIG,IAASJ,GAASK,IAASJ;AAC/B,IAAIE,IAAgBD,IAClBG,IAASD,IAASF,IAElBE,IAASC,IAASH,GAMhBE,IAAS10C,EAAG,MACd00C,IAAS10C,EAAG,GACZ20C,IAAS30C,EAAG;AAGd,UAAMU,IAAKgK,IAAO0pC,IAAe,GAC3BzzC,IAAKgK,IAAO0pC,IAAgB;AAClC,SAAK,OAAO;AAAA,MACV3zC,IAAKg0C,IAAS;AAAA,MACd/zC,IAAKg0C,IAAS;AAAA,MACdD;AAAA,MACAC;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEO,SAAS;AACd,QAAI,CAAC,KAAK,UAAW;AAIrB,UAAMre,IAAQ,KAAK,OAAO,OAAO,UAC3Buc,IAAK,KAAK,OAAO,QAAA;AACvB,QAAI,CAACvc,KAASA,EAAM,WAAW,EAAG;AAClC,QAAI5rB,IAAO,OAAUC,IAAO,OAAUH,IAAO,QAAWC,IAAO;AAC/D,eAAWxT,KAAQq/B,GAAO;AACxB,YAAM9gC,IAAIyB,EAAK,QAAQ,KAAK,GACtBxB,IAAIwB,EAAK,QAAQ,KAAK,GACtBsa,IAAIta,EAAK,QAAQ,SAAS,KAC1BsF,IAAItF,EAAK,QAAQ,UAAU;AACjC,MAAAyT,IAAO,KAAK,IAAIA,GAAMlV,CAAC,GAAGmV,IAAO,KAAK,IAAIA,GAAMlV,CAAC,GACjD+U,IAAO,KAAK,IAAIA,GAAMhV,IAAI+b,CAAC,GAAG9G,IAAO,KAAK,IAAIA,GAAMhV,IAAI8G,CAAC;AAAA,IAC3D;AACA,QAAI,CAAC,SAASmO,CAAI,EAAG;AACrB,UAAMhK,KAAMgK,IAAOF,KAAQ,GACrB7J,KAAMgK,IAAOF,KAAQ;AAC3B,SAAK,OAAO,QAAQ/J,IAAKmyC,EAAG,QAAQ,GAAGlyC,IAAKkyC,EAAG,SAAS,GAAGA,EAAG,OAAOA,EAAG,MAAM;AAAA,EAChF;AAAA;AAAA,EAGO,UAAkB;AACvB,QAAI,CAAC,KAAK,UAAW,QAAO;AAC5B,QAAI;AAEF,aAAQ,KAAK,OAAe,KAAA,KAAU;AAAA,IACxC,QAAY;AACV,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA,EAGO,SAAmC;AACxC,QAAI,CAAC,KAAK,UAAW,QAAO,EAAE,GAAG,GAAG,GAAG,EAAA;AACvC,QAAI;AACF,YAAMA,IAAK,KAAK,OAAO,QAAA;AACvB,aAAO,EAAE,GAAGA,EAAG,GAAG,GAAGA,EAAG,EAAA;AAAA,IAC1B,QAAY;AACV,aAAO,EAAE,GAAG,GAAG,GAAG,EAAA;AAAA,IACpB;AAAA,EACF;AAAA,EAEO,SAAS;AAAA,EAGhB;AAAA,EAEO,UAAU;AACf,IAAI,KAAK,iBAAiB,KAAK,OAAO,MAAM,wBAC1C,KAAK,OAAO,KAAK,oBAAoB,SAAS,KAAK,aAAa,GAChE,KAAK,gBAAgB,OAEnB,KAAK,cACP,KAAK,OAAO,QAAQ,EAAK,GAGzB,KAAK,OAAO,IAAI,UAAU,GAC1B,KAAK,OAAO,IAAI,SAAS,GACzB,KAAK,OAAO,IAAI,QAAQ,GACxB,KAAK,OAAO,IAAI,MAAM,GAGtB,KAAK,mBAAA,GAEL,KAAK,YAAY;AAAA,EAErB;AAAA;AAAA,EAGO,gBAAyB;AAC9B,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,gBAAgB;AACtB,WAAO;AAAA,MACL,SAAS,KAAK,QAAQ;AAAA,MACtB,WAAW,KAAK,QAAQ;AAAA,MACxB,WAAW,KAAK,QAAQ;AAAA,MACxB,WAAW,KAAK,QAAQ;AAAA,MACxB,cAAc,KAAK,QAAQ;AAAA,MAC3B,SAAS,KAAK,QAAQ;AAAA,MACtB,YAAY,KAAK,QAAQ;AAAA,MACzB,SAAS,KAAK,QAAQ;AAAA,MACtB,SAAS,KAAK,QAAQ;AAAA,MACtB,8BAA8B,KAAK,QAAQ;AAAA,MAC3C,gCAAgC,KAAK,QAAQ;AAAA,MAC7C,UAAU,KAAK,QAAQ;AAAA,MACvB,kBAAkB,KAAK,QAAQ;AAAA,IAAA;AAAA,EAEnC;AACF;AC3fO,MAAM+B,GAAS;AAAA,EAoBpB,YAAYrkB,GAAclrB,IAA2B,IAAI;AAjBzD,SAAQ,YAAmC,MAC3C,KAAQ,aAAyB,MACjC,KAAQ,oBAAiC,MACzC,KAAQ,iCAAuC,IAAA,GAC/C,KAAQ,WAAoB,IAC5B,KAAQ,aAAsB,IAC9B,KAAQ,QAAgB,KACxB,KAAQ,aAAqB,GAC7B,KAAQ,aAAqB,GAC7B,KAAQ,iBAAyB,GACjC,KAAQ,iBAAyB,GACjC,KAAQ,wBAA+C,MAGvD,KAAQ,iBAAmD,MAC3D,KAAQ,eAAiD,MAofzD,KAAQ,mBAAkC,MA+C1C,KAAQ,iBAAgC,MAuGxC,KAAQ,wBAAuC,MAvoB7C,KAAK,QAAQkrB,GACb,KAAK,UAAU;AAAA,MACb,SAAS;AAAA,MACT,UAAU;AAAA;AAAA,MACV,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,iBAAiB;AAAA,MACjB,eAAe;AAAA,MACf,qBAAqB;AAAA,MACrB,WAAW;AAAA,MACX,cAAc;AAAA,MACd,QAAQ;AAAA,MACR,kBAAkB;AAAA;AAAA,MAClB,GAAGlrB;AAAA,IAAA;AAAA,EAEP;AAAA,EAEO,SAAe;AACpB,IAAI,KAAK,aACT,KAAK,WAAW,IAEhB,KAAK,gBAAA,GACL,KAAK,iBAAA,GACL,KAAK,YAAA,GACL,KAAK,wBAAA,GACL,KAAK,oBAAA,GACL,KAAK,eAAA,GAGD,KAAK,QAAQ,oBACf,KAAK,mBAAA,GAGP,QAAQ,IAAI,kCAAkC;AAAA,EAChD;AAAA,EAEO,UAAgB;AACrB,IAAK,KAAK,aACV,KAAK,WAAW,IAEhB,KAAK,qBAAA,GACL,KAAK,mBAAA,GAED,KAAK,aAAa,KAAK,UAAU,cACnC,KAAK,UAAU,WAAW,YAAY,KAAK,SAAS,GAGtD,KAAK,YAAY,MACjB,KAAK,aAAa,MAClB,KAAK,oBAAoB,MACzB,KAAK,WAAW,MAAA,GAEhB,QAAQ,IAAI,mCAAmC;AAAA,EACjD;AAAA,EAEO,YAAqB;AAC1B,WAAO,KAAK;AAAA,EACd;AAAA,EAEO,UAAgB;AACrB,IAAK,KAAK,aAGV,KAAK,YAAA,GACL,KAAK,eAAA;AAAA,EACP;AAAA,EAEO,iBAAuB;AAC5B,QAAI,CAAC,KAAK,YAAY,CAAC,KAAK,qBAAqB,CAAC,KAAK,WAAY;AAEnE,UAAMwvC,IAAU,KAAK,MAAM;AAC3B,QAAI,CAACA,EAAS;AAGd,UAAMhxC,IAAOgxC,EAAQ,QAAA,KAAa,GAC5BC,IAAMD,EAAQ,OAAA,KAAY,EAAE,GAAG,GAAG,GAAG,EAAA,GAGrCE,IAAgB,KAAK,QAAQ,SAAU,KACvCC,IAAiB,KAAK,QAAQ,UAAW,KAGzCC,IAAS,KAAK,uBAAA,GAGdb,IAAe,KAAK,IAAIa,EAAO,OAAOA,EAAO,MAAM,CAAC,GACpDZ,IAAgB,KAAK,IAAIY,EAAO,OAAOA,EAAO,MAAM,CAAC,GAGrDvd,IAAU,KACVwd,IAAad,IAAe1c,IAAU,GACtCyd,IAAcd,IAAgB3c,IAAU;AAG9C,SAAK,QAAQ,KAAK;AAAA,MAChBqd,IAAgBG;AAAA,MAChBF,IAAiBG;AAAA,IAAA;AAInB,UAAMC,KACH,KAAK,MAAM,QAAQ,UAAU,iBAAiB,OAAOvxC,GAClDwxC,KACH,KAAK,MAAM,QAAQ,UAAU,kBAAkB,OAAOxxC,GAMnDyxC,KAAaR,EAAI,IAAIG,EAAO,OAAOvd,KAAW,KAAK,OACnD6d,KAAaT,EAAI,IAAIG,EAAO,OAAOvd,KAAW,KAAK,OACnD8d,IAAYJ,IAAe,KAAK,OAChCK,IAAYJ,IAAgB,KAAK;AAGvC,SAAK,kBAAkB,KAAKC,GAAWC,CAAS,GAChD,KAAK,kBAAkB,KAAK,KAAK,IAAIC,GAAW,EAAE,GAAG,KAAK,IAAIC,GAAW,EAAE,CAAC;AAAA,EAC9E;AAAA,EAEO,mBAAmBx+C,GAAkB;AAC1C,QAAI,CAAC,KAAK,SAAU;AAEpB,UAAM+nB,IAAQ,KAAK,WAAW,IAAI/nB,EAAK,EAAE;AACzC,QAAI,CAAC+nB,EAAO;AAGZ,UAAMi2B,IAAS,KAAK,uBAAA,GACdvd,IAAU,KAGVliC,KAAKyB,EAAK,QAAQ,IAAKg+C,EAAO,OAAOvd,KAAW,KAAK,OACrDjiC,KAAKwB,EAAK,QAAQ,IAAKg+C,EAAO,OAAOvd,KAAW,KAAK;AAE3D,SAAK,iBAAiB1Y,GAAcxpB,GAAGC,CAAC;AAGxC,UAAM8b,KAAKta,EAAK,QAAQ,SAAS,OAAO,KAAK,OACvCsF,KAAKtF,EAAK,QAAQ,UAAU,MAAM,KAAK;AAC7C,SAAK,mBAAmB+nB,GAAc/nB,GAAMzB,GAAGC,GAAG8b,GAAGhV,CAAC;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,mBACNyiB,GACA/nB,GACAzB,GACAC,GACA8b,GACAhV,GACM;AACN,UAAMkM,IAAQxR,EAAK,QAAQ,QAAQ,iBAAiB;AACpD,QAAI;AACF,MAAA+nB,EAAM,UAAU,EAAE,QAAQvW,GAAO,QAAQ,CAACjT,IAAI+b,IAAI,GAAG9b,IAAI8G,IAAI,CAAC,GAAG;AAAA,IACnE,QAAY;AAAA,IAEZ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,iBAAiByiB,GAAYxpB,GAAWC,GAAW6W,IAAW,KAAW;AAC/E,QAAI,OAAO,wBAA0B,KAAa;AAChD,UAAI;AACF,QAAA0S,EAAM,KAAKxpB,GAAGC,CAAC;AAAA,MACjB,QAAY;AAAA,MAEZ;AACA;AAAA,IACF;AACA,QAAIigD,IAAQlgD,GACRmgD,IAAQlgD;AACZ,QAAI;AACF,MAAAigD,IAAQ12B,EAAM,EAAA,GACd22B,IAAQ32B,EAAM,EAAA;AAAA,IAChB,QAAY;AAAA,IAEZ;AACA,QAAIA,EAAM;AACR,UAAI;AACF,6BAAqBA,EAAM,MAAM;AAAA,MACnC,QAAY;AAAA,MAEZ;AAEF,UAAM42B,IAAO,CAACx7C,MACZA,IAAI,MAAM,IAAIA,IAAIA,IAAI,IAAI,KAAK,IAAI,KAAKA,IAAI,GAAG,CAAC,IAAI;AACtD,QAAIy7C,IAAyB;AAC7B,UAAMC,IAAO,CAACllC,MAAgB;AAC5B,MAAIilC,MAAY,SAAMA,IAAUjlC;AAChC,YAAMhV,IAAI,KAAK,IAAI,IAAIgV,IAAMilC,KAAWvpC,CAAQ,GAC1C9L,IAAIo1C,EAAKh6C,CAAC;AAChB,UAAI;AACF,QAAAojB,EAAM,KAAK02B,KAASlgD,IAAIkgD,KAASl1C,GAAGm1C,KAASlgD,IAAIkgD,KAASn1C,CAAC;AAAA,MAC7D,QAAc;AAAA,MAEd;AACA,MAAI5E,IAAI,IAAGojB,EAAM,SAAS,sBAAsB82B,CAAI,MACzC,SAAS;AAAA,IACtB;AACA,IAAA92B,EAAM,SAAS,sBAAsB82B,CAAI;AAAA,EAC3C;AAAA,EAEO,aAAa7+C,GAAkB;AACpC,QAAI,CAAC,KAAK,YAAY,CAAC,KAAK,WAAY;AAExC,UAAMg+C,IAAS,KAAK,uBAAA,GACdvd,IAAU,KAEVliC,KAAKyB,EAAK,QAAQ,IAAKg+C,EAAO,OAAOvd,KAAW,KAAK,OACrDjiC,KAAKwB,EAAK,QAAQ,IAAKg+C,EAAO,OAAOvd,KAAW,KAAK,OACrDnmB,KAAKta,EAAK,QAAQ,SAAS,OAAO,KAAK,OACvCsF,KAAKtF,EAAK,QAAQ,UAAU,MAAM,KAAK;AAE7C,QAAI+nB;AACJ,QAAI/nB,EAAK,QAAQ,UAAU,UAAU;AACnC,YAAM8tB,IAAS,KAAK,IAAIxT,GAAGhV,CAAC,IAAI;AAChC,MAAAyiB,IAAQ,KAAK,WAAW,OAAO+F,IAAS,CAAC,EAAE,KAAKvvB,GAAGC,CAAC;AAAA,IACtD;AACE,MAAAupB,IAAQ,KAAK,WAAW,KAAKzN,GAAGhV,CAAC,EAAE,KAAK/G,GAAGC,CAAC;AAG9C,IAAAupB,EAAM,KAAK/nB,EAAK,QAAQ,mBAAmB,KAAK,QAAQ,SAAU,GAClE+nB,EAAM,OAAO,EAAE,OAAO,EAAA,CAAG,GAGzB,KAAK,mBAAmBA,GAAc/nB,GAAMzB,GAAGC,GAAG8b,GAAGhV,CAAC,GAEtD,KAAK,WAAW,IAAItF,EAAK,IAAI+nB,CAAK;AAGlC,QAAI;AACF,MAAAA,EAAM,QAAQ,CAAC,GACdA,EAAc,QAAQ,GAAG,EAAE,QAAQ,CAAC;AAAA,IACvC,QAAY;AAAA,IAEZ;AAGA,IAAI,KAAK,qBACP,KAAK,kBAAkB,MAAA;AAAA,EAE3B;AAAA,EAEO,gBAAgBqzB,GAAsB;AAC3C,UAAMrzB,IAAQ,KAAK,WAAW,IAAIqzB,CAAM;AACxC,QAAIrzB,GAAO;AAET,UAAI;AACF,QAAKA,EAAc,UAAQ,qBAAsBA,EAAc,MAAM,GACpEA,EACE,QAAQ,GAAG,EACX,QAAQ,CAAC,EACT,MAAM,MAAM;AACX,cAAI;AACF,YAAAA,EAAM,OAAA;AAAA,UACR,QAAY;AAAA,UAEZ;AAAA,QACF,CAAC;AAAA,MACL,QAAY;AACV,YAAI;AACF,UAAAA,EAAM,OAAA;AAAA,QACR,QAAc;AAAA,QAEd;AAAA,MACF;AACA,WAAK,WAAW,OAAOqzB,CAAM;AAAA,IAC/B;AAAA,EACF;AAAA,EAEQ,kBAAwB;AAC9B,SAAK,YAAY,SAAS,cAAc,KAAK,GAC7C,KAAK,UAAU,YAAY;AAG3B,UAAMr6C,IAAW,KAAK,QAAQ,YAAY,gBACpC+9C,IAAS,KAAK,QAAQ,UAAU;AAatC,YAXA,KAAK,UAAU,MAAM,WAAW,YAChC,KAAK,UAAU,MAAM,QAAQ,GAAG,KAAK,QAAQ,KAAK,MAClD,KAAK,UAAU,MAAM,SAAS,GAAG,KAAK,QAAQ,MAAM,MACpD,KAAK,UAAU,MAAM,kBAAkB,KAAK,QAAQ,iBACpD,KAAK,UAAU,MAAM,eAAe,GAAG,KAAK,QAAQ,YAAY,MAChE,KAAK,UAAU,MAAM,SAAS,kBAC9B,KAAK,UAAU,MAAM,YAAY,8BACjC,KAAK,UAAU,MAAM,WAAW,UAChC,KAAK,UAAU,MAAM,SAAS,OAGtB/9C,GAAA;AAAA,MACN,KAAK;AACH,aAAK,UAAU,MAAM,MAAM,GAAG+9C,CAAM,MACpC,KAAK,UAAU,MAAM,OAAO,GAAGA,CAAM;AACrC;AAAA,MACF,KAAK;AACH,aAAK,UAAU,MAAM,MAAM,GAAGA,CAAM,MACpC,KAAK,UAAU,MAAM,QAAQ,GAAGA,CAAM;AACtC;AAAA,MACF,KAAK;AACH,aAAK,UAAU,MAAM,SAAS,GAAGA,CAAM,MACvC,KAAK,UAAU,MAAM,OAAO,GAAGA,CAAM;AACrC;AAAA,MACF,KAAK;AAAA,MACL;AACE,aAAK,UAAU,MAAM,SAAS,GAAGA,CAAM,MACvC,KAAK,UAAU,MAAM,QAAQ,GAAGA,CAAM;AACtC;AAAA,IAAA;AAIJ,SAAK,MAAM,QAAQ,YAAY,KAAK,SAAS;AAAA,EAC/C;AAAA,EAEQ,mBAAyB;AAC/B,IAAK,KAAK,cAEV,KAAK,aAAan8B,GAAA,EACf,MAAM,KAAK,SAAS,EACpB,KAAK,KAAK,QAAQ,OAAQ,KAAK,QAAQ,MAAO,GAGjD,KAAK,WAAW,KAAK,KAAK,QAAQ,OAAQ,KAAK,QAAQ,MAAO,EAAE,KAAK,SAAS;AAAA,EAChF;AAAA,EAEQ,cAAoB;AAC1B,QAAI,CAAC,KAAK,WAAY;AAGtB,SAAK,WAAW,QAAQ,CAACoF,MAAUA,EAAM,QAAQ,GACjD,KAAK,WAAW,MAAA;AAGhB,UAAMi2B,IAAS,KAAK,uBAAA,GACdvd,IAAU,KACV0c,IAAe,KAAK,IAAIa,EAAO,OAAOA,EAAO,MAAM,CAAC,GACpDZ,IAAgB,KAAK,IAAIY,EAAO,OAAOA,EAAO,MAAM,CAAC,GACrDC,IAAad,IAAe1c,IAAU,GACtCyd,IAAcd,IAAgB3c,IAAU;AAE9C,SAAK,QAAQ,KAAK;AAAA,MAChB,KAAK,QAAQ,QAASwd;AAAA,MACtB,KAAK,QAAQ,SAAUC;AAAA,IAAA,GAIX,KAAK,MAAM,YAAA,EACnB,QAAQ,CAACl+C,MAAS;AACtB,YAAMzB,KAAKyB,EAAK,QAAQ,IAAKg+C,EAAO,OAAOvd,KAAW,KAAK,OACrDjiC,KAAKwB,EAAK,QAAQ,IAAKg+C,EAAO,OAAOvd,KAAW,KAAK,OACrDnmB,IAAI,KAAK,KAAKta,EAAK,QAAQ,SAAS,OAAO,KAAK,OAAO,CAAC,GACxDsF,IAAI,KAAK,KAAKtF,EAAK,QAAQ,UAAU,MAAM,KAAK,OAAO,CAAC;AAE9D,UAAI+nB;AACJ,UAAI/nB,EAAK,QAAQ,UAAU,UAAU;AACnC,cAAM8tB,IAAS,KAAK,IAAIxT,GAAGhV,CAAC,IAAI;AAChC,QAAAyiB,IAAQ,KAAK,WAAY,OAAO+F,IAAS,CAAC,EAAE,KAAKvvB,GAAGC,CAAC;AAAA,MACvD;AACE,QAAAupB,IAAQ,KAAK,WAAY,KAAKzN,GAAGhV,CAAC,EAAE,KAAK/G,GAAGC,CAAC;AAG/C,MAAAupB,EAAM,KAAK/nB,EAAK,QAAQ,mBAAmB,KAAK,QAAQ,SAAU,GAClE+nB,EAAM,OAAO,EAAE,OAAO,EAAA,CAAG;AAGzB,YAAMovB,IAAgBn3C,EAAK,QAAQ,QAAQ,iBAAiB;AAC5D,UAAIm3C,MAAkB,GAAG;AAEvB,cAAM1tC,IAAKlL,IAAI+b,IAAI,GACb5Q,IAAKlL,IAAI8G,IAAI;AAClB,QAAAyiB,EAAc,OAAOovB,GAAe1tC,GAAIC,CAAE;AAAA,MAC7C;AAEA,WAAK,WAAW,IAAI1J,EAAK,IAAI+nB,CAAK;AAAA,IACpC,CAAC;AAAA,EACH;AAAA,EAEQ,0BAAgC;AACtC,IAAK,KAAK,eAEV,KAAK,oBAAoB,KAAK,WAC3B,KAAK,IAAI,EAAE,EACX,KAAK,KAAK,QAAQ,aAAc,EAChC,OAAO,EAAE,OAAO,KAAK,QAAQ,qBAAsB,OAAO,EAAA,CAAG,EAC7D,IAAI,EAAE,QAAQ,OAAA,CAAQ,GAGzB,KAAK,kBAAkB,GAAG,aAAa,CAACxe,MAAa;AACnD,MAAAA,EAAE,eAAA,GACFA,EAAE,gBAAA;AAEF,YAAMipB,IAAajpB;AACnB,WAAK,aAAa,IAClB,KAAK,aAAaipB,EAAW,SAC7B,KAAK,aAAaA,EAAW;AAG7B,YAAMnmB,IAAO,KAAK,kBAAmB,KAAA;AACrC,WAAK,iBAAiBA,EAAK,GAC3B,KAAK,iBAAiBA,EAAK,GAG3B,KAAK,iBAAiB,KAAK,gBAAgB,KAAK,IAAI,GACpD,KAAK,eAAe,KAAK,cAAc,KAAK,IAAI,GAChD,SAAS,iBAAiB,aAAa,KAAK,cAAc,GAC1D,SAAS,iBAAiB,WAAW,KAAK,YAAY;AAAA,IACxD,CAAC,GAKD,KAAK,WAAW,GAAG,aAAa,CAAC9C,MAAa;AAC5C,YAAMw1C,IAAKx1C;AACX,UAAI;AACF,cAAM5E,IAAK,KAAK,WAAmB,MAAMo6C,EAAG,SAASA,EAAG,OAAO,GACzDC,IAAK,KAAK,mBAAmB,KAAA,EAAO,SAAS,IAC7CC,IAAK,KAAK,mBAAmB,KAAA,EAAO,UAAU,IAC9CjB,IAAS,KAAK,uBAAA,GACdvd,IAAU,KACVye,KAAQv6C,EAAE,IAAIq6C,IAAK,KAAK,KAAK,QAAQhB,EAAO,OAAOvd,GACnD0e,KAAQx6C,EAAE,IAAIs6C,IAAK,KAAK,KAAK,QAAQjB,EAAO,OAAOvd;AACzD,aAAK,MAAM,SAAS,IAAI,EAAE,GAAGye,GAAM,GAAGC,GAAM;AAAA,MAC9C,QAAc;AAAA,MAEd;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,gBAAgB51C,GAAqB;AAC3C,QAAI,CAAC,KAAK,cAAc,CAAC,KAAK,kBAAmB;AAEjD,UAAM61C,IAAS71C,EAAE,UAAU,KAAK,YAC1B81C,IAAS91C,EAAE,UAAU,KAAK,YAG1B+1C,IAAO,KAAK,iBAAiBF,GAC7BG,IAAO,KAAK,iBAAiBF;AACnC,SAAK,kBAAkB,KAAKC,GAAMC,CAAI;AAItC,UAAMvB,IAAS,KAAK,uBAAA,GACdvd,IAAU,KAKVye,IAAQI,IAAO,KAAK,QAAStB,EAAO,OAAOvd,GAC3C0e,IAAQI,IAAO,KAAK,QAASvB,EAAO,OAAOvd;AAEjD,SAAK,MAAM,SAAS,IAAI,EAAE,GAAGye,GAAM,GAAGC,GAAM;AAAA,EAC9C;AAAA,EAEQ,gBAAsB;AAC5B,SAAK,aAAa,IAGd,KAAK,mBACP,SAAS,oBAAoB,aAAa,KAAK,cAAc,GAC7D,KAAK,iBAAiB,OAEpB,KAAK,iBACP,SAAS,oBAAoB,WAAW,KAAK,YAAY,GACzD,KAAK,eAAe;AAAA,EAExB;AAAA,EAEQ,sBAA4B;AAElC,IAAI,KAAK,MAAM,WAEZ,KAAK,MAAM,OAAe,KAAK,iBAAiB,MAAM;AACrD,WAAK,eAAA;AAAA,IACP,CAAC,GAEA,KAAK,MAAM,OAAe,KAAK,oBAAoB,MAAM;AACxD,WAAK,eAAA;AAAA,IACP,CAAC,GAGA,KAAK,MAAM,OAAe,KAAK,mBAAmB,MAAM;AACvD,WAAK,eAAA;AAAA,IACP,CAAC,IAOH,KAAK,aAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASO,kBAAwB;AAE7B,IAAI,KAAK,qBAAqB,QAC5B,OAAO,aAAa,KAAK,gBAAgB,GAI3C,KAAK,mBAAmB,OAAO,WAAW,MAAM;AAC9C,WAAK,QAAA,GACL,KAAK,mBAAmB;AAAA,IAC1B,GAAG,GAAG;AAAA,EACR;AAAA,EAEQ,uBAA6B;AAGnC,IAAI,KAAK,mBACP,SAAS,oBAAoB,aAAa,KAAK,cAAc,GAC7D,KAAK,iBAAiB,OAEpB,KAAK,iBACP,SAAS,oBAAoB,WAAW,KAAK,YAAY,GACzD,KAAK,eAAe,OAEtB,KAAK,aAAa,IAGd,KAAK,MAAM,UACZ,KAAK,MAAM,OAAe,MAAM,WAAW,GAI1C,KAAK,qBAAqB,SAC5B,OAAO,aAAa,KAAK,gBAAgB,GACzC,KAAK,mBAAmB,OAG1B,KAAK,YAAA;AAAA,EACP;AAAA,EAIQ,eAAqB;AAE3B,SAAK,iBAAiB,OAAO,YAAY,MAAM;AAC7C,MAAI,KAAK,YACP,KAAK,eAAA;AAAA,IAET,GAAG,GAAG;AAAA,EACR;AAAA,EAEQ,cAAoB;AAC1B,IAAI,KAAK,mBAAmB,SAC1B,OAAO,cAAc,KAAK,cAAc,GACxC,KAAK,iBAAiB;AAAA,EAE1B;AAAA,EAEQ,qBAA2B;AACjC,QAAI,CAAC,KAAK,UAAW;AAGrB,SAAK,wBAAwB,SAAS,cAAc,KAAK,GACzD,KAAK,sBAAsB,YAAY,qCACvC,KAAK,sBAAsB,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAQpB,KAAK,QAAQ,YAAY,MAAM,KAAK,QAAQ,YAAY;AAAA;AAI/E,UAAMnC,IAAa,SAAS,cAAc,QAAQ;AAClD,IAAAA,EAAW,cAAc,KACzBA,EAAW,QAAQ,YACnBA,EAAW,MAAM,UAAU,KAAK,mBAAA,GAChCA,EAAW,iBAAiB,SAAS,MAAM,KAAK,MAAM,SAAS,SAAS,GACxE,KAAK,sBAAsB,YAAYA,CAAU;AAGjD,UAAMwC,IAAc,SAAS,cAAc,MAAM;AACjD,IAAAA,EAAY,KAAK,yBACjBA,EAAY,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAQ5BA,EAAY,cAAc,QAC1BA,EAAY,QAAQ,iBACpBA,EAAY,iBAAiB,SAAS,MAAM;AAC1C,WAAK,MAAM,SAAS,MAAA,GACpB,KAAK,kBAAA;AAAA,IACP,CAAC,GACD,KAAK,sBAAsB,YAAYA,CAAW;AAGlD,UAAMzC,IAAY,SAAS,cAAc,QAAQ;AACjD,IAAAA,EAAU,cAAc,KACxBA,EAAU,QAAQ,WAClBA,EAAU,MAAM,UAAU,KAAK,mBAAA,GAC/BA,EAAU,iBAAiB,SAAS,MAAM,KAAK,MAAM,SAAS,QAAQ,GACtE,KAAK,sBAAsB,YAAYA,CAAS,GAGhD,KAAK,UAAU,YAAY,KAAK,qBAAqB,GAGrD,KAAK,wBAAA;AAAA,EACP;AAAA,EAEQ,qBAA6B;AACnC,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeT;AAAA,EAEQ,oBAA0B;AAChC,UAAM0C,IAAU,KAAK,WAAW,cAAc,wBAAwB;AACtE,QAAIA,KAAW,KAAK,MAAM,SAAS;AACjC,YAAM7yC,IAAO,KAAK,MAAM,QAAQ,aAAa;AAC7C,MAAA6yC,EAAQ,cAAc,GAAG,KAAK,MAAM7yC,IAAO,GAAG,CAAC;AAAA,IACjD;AAAA,EACF;AAAA,EAIQ,0BAAgC;AAEtC,SAAK,wBAAwB,OAAO,YAAY,MAAM;AACpD,MAAI,KAAK,YACP,KAAK,kBAAA;AAAA,IAET,GAAG,GAAG;AAAA,EACR;AAAA,EAEQ,qBAA2B;AACjC,IAAI,KAAK,0BAA0B,SACjC,OAAO,cAAc,KAAK,qBAAqB,GAC/C,KAAK,wBAAwB,OAG3B,KAAK,yBAAyB,KAAK,sBAAsB,eAC3D,KAAK,sBAAsB,WAAW,YAAY,KAAK,qBAAqB,GAC5E,KAAK,wBAAwB;AAAA,EAEjC;AAAA,EAEQ,yBAKN;AACA,UAAMyyB,IAAQ,KAAK,MAAM,YAAA;AAEzB,QAAIA,EAAM,WAAW,GAAG;AAEtB,YAAMxhC,IAAQ,KAAK,MAAM,QAAQ,UAAU,iBAAiB,KACtDC,IAAS,KAAK,MAAM,QAAQ,UAAU,kBAAkB;AAC9D,aAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAMD,GAAO,MAAMC,EAAA;AAAA,IAChD;AAEA,QAAI2V,IAAO,OACPC,IAAO,OACPH,IAAO,QACPC,IAAO;AAEX,WAAA6rB,EAAM,QAAQ,CAACr/B,MAAS;AACtB,YAAMzB,IAAIyB,EAAK,QAAQ,KAAK,GACtBxB,IAAIwB,EAAK,QAAQ,KAAK,GACtBsa,IAAIta,EAAK,QAAQ,SAAS,KAC1B,IAAIA,EAAK,QAAQ,UAAU;AAEjC,MAAAyT,IAAO,KAAK,IAAIA,GAAMlV,CAAC,GACvBmV,IAAO,KAAK,IAAIA,GAAMlV,CAAC,GACvB+U,IAAO,KAAK,IAAIA,GAAMhV,IAAI+b,CAAC,GAC3B9G,IAAO,KAAK,IAAIA,GAAMhV,IAAI,CAAC;AAAA,IAC7B,CAAC,GAOM,EAAE,MAAAiV,GAAM,MAAAC,GAAM,MAAAH,GAAM,MAAAC,EAAA;AAAA,EAC7B;AACF;AC7tBO,MAAMksC,GAAS;AAAA,EAUpB,YAAYpmB,GAAYlrB,IAA2B,IAAI;AAPvD,SAAQ,YAAyB,CAAA,GACjC,KAAQ,YAAyB,CAAA,GACjC,KAAQ,gBAAqB,MAC7B,KAAQ,cAAuB,IAC/B,KAAQ,eAA8B,QAAQ,QAAA,GAC9C,KAAQ,kBAA0B,GAGhC,KAAK,QAAQkrB,GACb,KAAK,UAAU;AAAA,MACb,SAAS;AAAA,MACT,YAAY;AAAA;AAAA;AAAA,MAGZ,YAAY;AAAA,MACZ,GAAGlrB;AAAA,IAAA;AAAA,EAEP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,KAAKuxC,IAAgB,IAAa;AACvC,QAAI,GAAC,KAAK,QAAQ,WAAW,KAAK,cAElC;AAAA,UAAIA,GAAM;AACR,aAAK,aAAA;AACL;AAAA,MACF;AAGA,MAAI,KAAK,iBACP,aAAa,KAAK,aAAa,GAGjC,KAAK,gBAAgB,WAAW,MAAM;AAIpC,aAAK,gBAAgB,MACrB,KAAK,aAAA;AAAA,MACP,GAAG,KAAK,QAAQ,UAAU;AAAA;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,gBAAsB;AAC3B,IAAI,CAAC,KAAK,QAAQ,WAAW,KAAK,gBAG9B,KAAK,kBACP,aAAa,KAAK,aAAa,GAC/B,KAAK,gBAAgB,OAGvB,KAAK,aAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA,EAKO,OAAgB;AAIrB,QADI,KAAK,iBAAe,KAAK,cAAA,GACzB,KAAK,UAAU,UAAU;AAC3B,qBAAQ,IAAI,iCAAiC,GACtC;AAIT,UAAMv0C,IAAU,KAAK,UAAU,IAAA;AAC/B,SAAK,UAAU,KAAKA,CAAO;AAG3B,UAAMw0C,IAAW,KAAK,UAAU,KAAK,UAAU,SAAS,CAAC;AACzD,gBAAK,QAAQA,GAAU,MAAM,GAE7B,QAAQ;AAAA,MACN;AAAA,MACA,KAAK,UAAU;AAAA,MACf;AAAA,MACA,KAAK,UAAU;AAAA,IAAA,GAGV;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKO,OAAgB;AACrB,QAAI,KAAK,UAAU,WAAW;AAC5B,qBAAQ,IAAI,iCAAiC,GACtC;AAIT,UAAM5+C,IAAO,KAAK,UAAU,IAAA;AAG5B,gBAAK,UAAU,KAAKA,CAAI,GAGxB,KAAK,QAAQA,GAAM,MAAM,GAEzB,QAAQ;AAAA,MACN;AAAA,MACA,KAAK,UAAU;AAAA,MACf;AAAA,MACA,KAAK,UAAU;AAAA,IAAA,GAGV;AAAA,EACT;AAAA;AAAA,EAGO,UAAmB;AACxB,WAAO,KAAK,UAAU,SAAS;AAAA,EACjC;AAAA;AAAA,EAGO,UAAmB;AACxB,WAAO,KAAK,UAAU,SAAS;AAAA,EACjC;AAAA;AAAA,EAGO,QAAc;AACnB,SAAK,YAAY,CAAA,GACjB,KAAK,YAAY,CAAA,GACb,KAAK,iBACP,aAAa,KAAK,aAAa;AAAA,EAEnC;AAAA;AAAA,EAGO,UAAgB;AACrB,SAAK,MAAA,GACL,KAAK,cAAc,IAClB,KAAa,QAAQ;AAAA,EACxB;AAAA;AAAA,EAIQ,eAAqB;AAC3B,QAAIi7C;AACJ,QAAI;AACF,MAAAA,IAAW/B,GAAU,KAAK,KAAK;AAAA,IACjC,QAAY;AAEV;AAAA,IACF;AAGA,SAAK,YAAY,CAAA,GAGjB,KAAK,UAAU,KAAK+B,CAAQ,GAGxB,KAAK,UAAU,SAAS,KAAK,QAAQ,cACvC,KAAK,UAAU,MAAA,GAGjB,QAAQ;AAAA,MACN;AAAA,MACA,KAAK,UAAU;AAAA,IAAA;AAAA,EAEnB;AAAA,EAEQ,QAAQA,GAAqB4D,GAA+B;AAGlE,SAAK,mBAAmB,GACxB,KAAK,cAAc,IACnB,KAAK,eAAe,KAAK,aACtB,KAAK,YAAY;AAChB,YAAMrF,GAAYyB,GAAU,KAAK,OAAO,IAAO,EAAI;AAKnD,YAAM6D,IAAe,KAAK,UAAU7D,CAAQ;AAC5C,WAAK,MAAM,YAAY,mBAAmB;AAAA,QACxC,QAAA4D;AAAA,QACA,UAAUC;AAAA,MAAA,CACX,GAID,KAAK,MAAM,QAAQ,QAAQ,iBAAiB;AAAA,QAC1C,QAAAD;AAAA,QACA,SAAS,KAAK,MAAM,QAAQ;AAAA,QAC5B,UAAUC;AAAA,MAAA,CACX;AAAA,IACH,CAAC,EACA;AAAA,MAAM,CAACC,MACN,QAAQ,MAAM,kCAAkCA,CAAG;AAAA,IAAA,EAEpD,QAAQ,MAAM;AACb,WAAK,mBAAmB,GACpB,KAAK,oBAAoB,MAAG,KAAK,cAAc;AAAA,IACrD,CAAC;AAAA,EACL;AACF;ACpNO,MAAMC,GAAe;AAAA,EAW1B,YAAY1mB,GAAYlrB,IAAiC,IAAI;AAR7D,SAAQ,gBAAqB,MAC7B,KAAQ,aAA8C,MACtD,KAAQ,cAAuB,IAG/B,KAAQ,WAA+C,MACvD,KAAQ,SAA6C,MAGnD,KAAK,QAAQkrB,GACb,KAAK,UAAU;AAAA,MACb,SAAS;AAAA,MACT,gBAAgB;AAAA,MAChB,kBAAkB;AAAA,MAClB,GAAGlrB;AAAA,IAAA,GAGD,KAAK,QAAQ,WACf,KAAK,WAAA;AAAA,EAET;AAAA,EAEO,SAAe;AACpB,SAAK,QAAQ,UAAU,IACvB,KAAK,WAAA;AAAA,EACP;AAAA,EAEO,UAAgB;AACrB,SAAK,QAAQ,UAAU,IACvB,KAAK,aAAA,GACL,KAAK,gBAAA;AAAA,EACP;AAAA,EAEO,YAAqB;AAC1B,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA;AAAA,EAIQ,aAAmB;AACzB,UAAMmmC,IAAS,KAAK,MAAM;AAC1B,IAAKA,KAELA,EAAO,GAAG,2BAA2B,CAACjmC,MAAe;AACnD,UAAI,CAAC,KAAK,QAAQ,QAAS;AAG3B,YAAM4G,IAAS5G,EAAM;AAIrB,UAAI,EAFF4G,MAAWq/B,EAAO,QAAQr/B,GAAQ,YAAY,OAEjC;AAGf,YAAM8jB,IAAK,KAAK,YAAY1qB,CAAK;AACjC,MAAK0qB,MAEL,KAAK,aAAaA,GAClB,KAAK,cAAc,IAGnB,KAAK,gBAAgBub,EAClB,KAAK,GAAG,CAAC,EACT,KAAKvb,EAAG,GAAGA,EAAG,CAAC,EACf,KAAK;AAAA,QACJ,OAAO,KAAK,QAAQ;AAAA,QACpB,SAAS,KAAK,QAAQ;AAAA,MAAA,CACvB,EACA,OAAO;AAAA,QACN,OAAO,KAAK,QAAQ;AAAA,QACpB,OAAO;AAAA,QACP,WAAW;AAAA,MAAA,CACZ,EACA,KAAK,kBAAkB,MAAM,GAIhC,KAAK,WAAW,CAACzvB,MAAoB,KAAK,aAAaA,CAAC,GACxD,KAAK,SAAS,CAACA,MAAoB,KAAK,WAAWA,CAAC,GACpD,OAAO,iBAAiB,eAAe,KAAK,UAAU,EAAI,GAC1D,OAAO,iBAAiB,aAAa,KAAK,QAAQ,EAAI;AAAA,IACxD,CAAC;AAAA,EACH;AAAA,EAEQ,aAAa+E,GAA2B;AAC9C,QAAI,CAAC,KAAK,eAAe,CAAC,KAAK,cAAc,CAAC,KAAK,cAAe;AAClE,UAAM0qB,IAAK,KAAK,YAAY1qB,CAAK;AACjC,QAAI,CAAC0qB,EAAI;AACT,UAAMz6B,IAAI,KAAK,IAAI,KAAK,WAAW,GAAGy6B,EAAG,CAAC,GACpCx6B,IAAI,KAAK,IAAI,KAAK,WAAW,GAAGw6B,EAAG,CAAC,GACpC1e,IAAI,KAAK,IAAI0e,EAAG,IAAI,KAAK,WAAW,CAAC,GACrC1zB,IAAI,KAAK,IAAI0zB,EAAG,IAAI,KAAK,WAAW,CAAC;AAC3C,SAAK,cAAc,KAAKz6B,GAAGC,CAAC,EAAE,KAAK8b,GAAGhV,CAAC;AAAA,EACzC;AAAA,EAEQ,WAAWgJ,GAA2B;AAE5C,QADA,KAAK,qBAAA,GACD,CAAC,KAAK,eAAe,CAAC,KAAK,YAAY;AACzC,WAAK,gBAAA;AACL;AAAA,IACF;AACA,UAAM0qB,IAAK,KAAK,YAAY1qB,CAAK;AACjC,QAAI0qB,GAAI;AACN,YAAMz6B,IAAI,KAAK,IAAI,KAAK,WAAW,GAAGy6B,EAAG,CAAC,GACpCx6B,IAAI,KAAK,IAAI,KAAK,WAAW,GAAGw6B,EAAG,CAAC,GACpC1e,IAAI,KAAK,IAAI0e,EAAG,IAAI,KAAK,WAAW,CAAC,GACrC1zB,IAAI,KAAK,IAAI0zB,EAAG,IAAI,KAAK,WAAW,CAAC;AAC3C,MAAI1e,IAAI,KAAKhV,IAAI,KACf,KAAK,kBAAkB/G,GAAGC,GAAG8b,GAAGhV,GAAGgJ,EAAM,QAAQ;AAAA,IAErD;AACA,SAAK,gBAAA;AAAA,EACP;AAAA,EAEQ,uBAA6B;AACnC,IAAI,KAAK,aACP,OAAO,oBAAoB,eAAe,KAAK,UAAU,EAAI,GAC7D,KAAK,WAAW,OAEd,KAAK,WACP,OAAO,oBAAoB,aAAa,KAAK,QAAQ,EAAI,GACzD,KAAK,SAAS;AAAA,EAElB;AAAA,EAEQ,eAAqB;AAC3B,UAAMimC,IAAS,KAAK,MAAM;AAC1B,IAAKA,MAELA,EAAO,IAAI,yBAAyB,GACpC,KAAK,qBAAA;AAAA,EACP;AAAA,EAEQ,kBAAwB;AAC9B,SAAK,cAAc,IACnB,KAAK,aAAa,MACd,KAAK,kBACP,KAAK,cAAc,OAAA,GACnB,KAAK,gBAAgB;AAAA,EAEzB;AAAA;AAAA,EAIQ,kBACNh2C,GACAC,GACA8b,GACAhV,GACA26C,GACM;AACN,UAAMC,IAAqB,CAAA,GAErBC,IAAW,KAAK,MAAM,MAAM;AAClC,eAAWngD,KAAQmgD;AACjB,UAAI;AAIF,cAAMliD,IAAI+B,EAAK,SACTsuB,IAAKrwB,EAAE,KAAK,GACZswB,IAAKtwB,EAAE,KAAK,GACZmiD,IAAKniD,EAAE,SAAS,GAChBoiD,IAAKpiD,EAAE,UAAU;AACvB,QAAIqwB,IAAK/vB,IAAI+b,KAAKgU,IAAK8xB,IAAK7hD,KAAKgwB,IAAK/vB,IAAI8G,KAAKipB,IAAK8xB,IAAK7hD,KACvD0hD,EAAY,KAAKlgD,CAAI;AAAA,MAEzB,QAAQ;AAAA,MAER;AAGF,IAAIkgD,EAAY,SAAS,MACvB,KAAK,MAAM,YAAYA,GAAaD,CAAc,GAOjD,KAAK,MAAc,wBAAwB,KAAK,IAAA,GACjD,QAAQ;AAAA,MACN;AAAA,MACAC,EAAY;AAAA,MACZ;AAAA,IAAA;AAAA,EAGN;AAAA;AAAA,EAIQ,YAAY5xC,GAA6C;AAC/D,QAAI;AAEF,YAAM6qB,IADS,KAAK,MAAM,OACH,MACjBH,IAAKG,EAAQ,eAAA;AACnB,MAAAH,EAAG,IAAI1qB,EAAM,SACb0qB,EAAG,IAAI1qB,EAAM;AACb,YAAMgyC,IAAQtnB,EAAG,gBAAgBG,EAAQ,aAAA,EAAe,SAAS;AACjE,aAAO,EAAE,GAAGmnB,EAAM,GAAG,GAAGA,EAAM,EAAA;AAAA,IAChC,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA,EAKO,iBAAuB;AAC5B,UAAMzP,IAAW,KAAK,MAAM,iBAAA;AAC5B,eAAW7wC,KAAQ6wC;AACjB,WAAK,MAAM,WAAW7wC,EAAK,EAAE;AAE/B,SAAK,MAAM,eAAA;AAAA,EACb;AAAA;AAAA,EAGO,aAAa4J,GAAYC,GAAkB;AAChD,UAAMgnC,IAAW,KAAK,MAAM,iBAAA;AAC5B,eAAW7wC,KAAQ6wC,GAAU;AAC3B,YAAMtyC,KAAKyB,EAAK,QAAQ,KAAK,KAAK4J,GAC5BpL,KAAKwB,EAAK,QAAQ,KAAK,KAAK6J;AAClC,MAAA7J,EAAK,SAASzB,GAAGC,CAAC;AAAA,IACpB;AAAA,EACF;AACF;ACvOO,MAAM+hD,GAAK;AAAA,EAMhB,YAAYjnB,GAAYlrB,IAAuB,IAAI;AAHnD,SAAQ,YAAiB,MACzB,KAAQ,YAAqB,IAG3B,KAAK,QAAQkrB,GACb,KAAK,UAAU;AAAA,MACb,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW;AAAA,MACX,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,GAAGlrB;AAAA,IAAA;AAAA,EAEP;AAAA;AAAA,EAGO,OAAa;AAClB,IAAI,KAAK,cAET,KAAK,YAAY,IACjB,KAAK,OAAA;AAAA,EACP;AAAA;AAAA,EAGO,OAAa;AAClB,SAAK,YAAY,IACb,KAAK,cACP,KAAK,UAAU,OAAA,GACf,KAAK,YAAY;AAAA,EAErB;AAAA;AAAA,EAGO,UAAgB;AACrB,SAAK,KAAA;AAAA,EACP;AAAA;AAAA,EAGO,SAAe;AACpB,IAAI,KAAK,YACP,KAAK,KAAA,IAEL,KAAK,KAAA;AAAA,EAET;AAAA;AAAA,EAGO,UAAmB;AACxB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGO,UACL7P,GACAC,GAC0B;AAC1B,QAAI,CAAC,KAAK,QAAQ,WAAY,QAAO,EAAE,GAAAD,GAAG,GAAAC,EAAA;AAE1C,UAAMwa,IAAO,KAAK,QAAQ;AAC1B,WAAO;AAAA,MACL,GAAG,KAAK,MAAMza,IAAIya,CAAI,IAAIA;AAAA,MAC1B,GAAG,KAAK,MAAMxa,IAAIwa,CAAI,IAAIA;AAAA,IAAA;AAAA,EAE9B;AAAA;AAAA,EAGO,cAAc5K,GAAqC;AACxD,WAAO,OAAO,KAAK,SAASA,CAAO,GAC/B,KAAK,cACP,KAAK,KAAA,GACL,KAAK,KAAA;AAAA,EAET;AAAA;AAAA,EAIQ,SAAe;AACrB,QAAI,CAAC,KAAK,MAAM,OAAQ;AAGxB,IAAI,KAAK,aACP,KAAK,UAAU,OAAA;AAGjB,UAAMmmC,IAAS,KAAK,MAAM,QACpBxvB,IAAUwvB,EAAO,QAAA,GACjBv7B,IAAO,KAAK,QAAQ,UACpBjU,IAAQ,KAAK,QAAQ,WACrBgd,IAAU,KAAK,QAAQ,aAGvBwa,IAAS,KAAK,MAAMxX,EAAQ,IAAI/L,CAAI,IAAIA,IAAOA,IAAO,GACtDi5B,IAAS,KAAK,MAAMltB,EAAQ,IAAI/L,CAAI,IAAIA,IAAOA,IAAO,GACtDwnC,IAAOz7B,EAAQ,IAAIA,EAAQ,QAAQ/L,IAAO,GAC1CynC,IAAO17B,EAAQ,IAAIA,EAAQ,SAAS/L,IAAO;AAEjD,SAAK,YAAYu7B,EAAO,MAAA,EAAQ,KAAK,kBAAkB,MAAM;AAG7D,aAASh2C,IAAIg+B,GAAQh+B,KAAKiiD,GAAMjiD,KAAKya;AACnC,WAAK,UACF,KAAKza,GAAG0zC,GAAQ1zC,GAAGkiD,CAAI,EACvB,OAAO,EAAE,OAAA17C,GAAO,OAAO,KAAK,SAAAgd,GAAS;AAI1C,aAASvjB,IAAIyzC,GAAQzzC,KAAKiiD,GAAMjiD,KAAKwa;AACnC,WAAK,UACF,KAAKujB,GAAQ/9B,GAAGgiD,GAAMhiD,CAAC,EACvB,OAAO,EAAE,OAAAuG,GAAO,OAAO,KAAK,SAAAgd,GAAS;AAI1C,SAAK,UAAU,KAAA;AAAA,EACjB;AACF;AC9GO,MAAM2+B,GAAS;AAAA,EAcpB,YAAYpnB,GAAYlrB,IAA2B,IAAI;AAXvD,SAAQ,eAAoD,MAE5D,KAAQ,YAAmB,CAAA,GAE3B,KAAQ,iBAAwB,CAAA,GAGhC,KAAQ,aAAa,GAErB,KAAQ,aAAmD,MAGzD,KAAK,QAAQkrB,GACb,KAAK,UAAU;AAAA,MACb,SAAS;AAAA,MACT,eAAe;AAAA,MACf,GAAGlrB;AAAA,IAAA;AAAA,EAEP;AAAA;AAAA,EAGO,aAAmB;AACxB,IAAI,KAAK,iBAET,KAAK,eAAe,CAAC7E,MAAqB,KAAK,cAAcA,CAAC,GAC9D,SAAS,iBAAiB,WAAW,KAAK,YAAY,GACtD,QAAQ,IAAI,wCAAwC;AAAA,EACtD;AAAA;AAAA,EAGO,eAAqB;AAC1B,IAAI,KAAK,iBACP,SAAS,oBAAoB,WAAW,KAAK,YAAY,GACzD,KAAK,eAAe,MACpB,QAAQ,IAAI,yCAAyC;AAAA,EAEzD;AAAA;AAAA,EAGO,SAAe;AACpB,SAAK,QAAQ,UAAU;AAAA,EACzB;AAAA;AAAA,EAGO,UAAgB;AACrB,SAAK,QAAQ,UAAU;AAAA,EACzB;AAAA;AAAA,EAIQ,cAAcA,GAAwB;AAC5C,QAAI,CAAC,KAAK,QAAQ,QAAS;AAG3B,UAAM2L,IAAS3L,EAAE;AACjB,QACE2L,EAAO,YAAY,WACnBA,EAAO,YAAY,cACnBA,EAAO;AAEP;AAGF,UAAMyrC,IAAQp3C,EAAE,WAAWA,EAAE;AAE7B,YAAQA,EAAE,KAAA;AAAA,MACR,KAAK;AAAA,MACL,KAAK;AACH,aAAK,eAAeA,CAAC;AACrB;AAAA,MAEF,KAAK;AACH,QAAIo3C,KAASp3C,EAAE,WACb,KAAK,KAAKA,CAAC,IACFo3C,KACT,KAAK,KAAKp3C,CAAC;AAEb;AAAA,MAEF,KAAK;AACH,QAAIo3C,KACF,KAAK,KAAKp3C,CAAC;AAEb;AAAA,MAEF,KAAK;AACH,QAAIo3C,KACF,KAAK,UAAUp3C,CAAC;AAElB;AAAA,MAEF,KAAK;AACH,QAAIo3C,KACF,KAAK,aAAap3C,CAAC;AAErB;AAAA,MAEF,KAAK;AACH,QAAIo3C,KACF,KAAK,eAAep3C,CAAC;AAEvB;AAAA,MAEF,KAAK;AACH,QAAIo3C,KACF,KAAK,kBAAkBp3C,CAAC;AAE1B;AAAA,MAEF,KAAK;AAAA,MACL,KAAK;AACH,QAAIo3C,MACFp3C,EAAE,eAAA,GACEA,EAAE,WACJ,KAAK,MAAM,eAAA,IAEX,KAAK,MAAM,aAAA;AAGf;AAAA,MAEF,KAAK;AACH,QAAIo3C,KACF,KAAK,aAAap3C,CAAC;AAErB;AAAA,MAEF,KAAK;AACH,QAAIo3C,KACF,KAAK,WAAWp3C,CAAC;AAEnB;AAAA,MAEF,KAAK;AACH,aAAK,SAASA,CAAC;AACf;AAAA,MAEF,KAAK;AAEH,gBAAQ;AAAA,UACN;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAAA,GAcF,KAAK,MAAM,WAAW,gDAAgD;AACtE;AAAA,MAEF,KAAK;AAEH,aAAK,wBAAwBA,CAAC;AAC9B;AAAA,MAEF,KAAK;AAGH,YAAI,KAAK,wBAAwBA,CAAC,EAAG;AACrC,aAAK,cAAcA,CAAC;AACpB;AAAA,MAEF,KAAK;AAEH,aAAK,cAAcA,CAAC;AACpB;AAAA,MAEF,KAAK;AAGH;AAAA,MAEF,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACH,aAAK,eAAeA,CAAC;AACrB;AAAA,IAAA;AAAA,EAEN;AAAA,EAEQ,eAAeA,GAAwB;AAC7C,UAAMsnC,IAAW,KAAK,MAAM,iBAAA;AAC5B,QAAIA,EAAS,WAAW,KAIpB,OAAK,MAAM,aAAA,KAAkB,KAAK,MAAM,oBAE5C;AAAA,MAAAtnC,EAAE,eAAA;AACF,iBAAWvJ,KAAQ,CAAC,GAAG6wC,CAAQ;AAC7B,QAAI7wC,EAAK,SAAS,aAAa,CAAC,KAAK,MAAM,yBAG3C,KAAK,MAAM,WAAWA,EAAK,EAAE;AAE/B,WAAK,MAAM,eAAA;AAAA;AAAA,EACb;AAAA,EAEQ,KAAKuJ,GAAwB;AACnC,IAAAA,EAAE,eAAA,GACE,KAAK,MAAM,YACb,KAAK,MAAM,SAAS,KAAA;AAAA,EAExB;AAAA,EAEQ,KAAKA,GAAwB;AACnC,IAAAA,EAAE,eAAA,GACE,KAAK,MAAM,YACb,KAAK,MAAM,SAAS,KAAA;AAAA,EAExB;AAAA,EAEQ,UAAUA,GAAwB;AACxC,IAAAA,EAAE,eAAA;AACF,UAAM42C,IAAW,KAAK,MAAM,MAAM;AAClC,IAAIA,EAAS,SAAS,KACpB,KAAK,MAAM,YAAYA,GAAU,EAAK;AAAA,EAE1C;AAAA,EAEQ,SAAS52C,GAAwB;AAIvC,QAHAA,EAAE,eAAA,GAGE,KAAK,MAAM,uBAAuB;AACpC,WAAK,MAAM,YAAA;AACX;AAAA,IACF;AACA,SAAK,MAAM,eAAA;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,aAAavJ,GAAgB;AACnC,QAAI4gD,IAAY,CAAA;AAChB,QAAI;AACF,MAAAA,IAAO,KAAK,MAAM,KAAK,UAAU5gD,EAAK,WAAW,CAAA,CAAE,CAAC;AAAA,IACtD,QAAc;AACZ,MAAA4gD,IAAO,EAAE,GAAI5gD,EAAK,WAAW,CAAA,EAAC;AAAA,IAChC;AACA,UAAM6gD,IAAQD,EAAK;AACnB,kBAAOA,EAAK,IACZ,OAAOA,EAAK,wBACZ,OAAOA,EAAK,yBACZ,OAAOA,EAAK,cACZ,OAAOA,EAAK,eACRC,QAAY,UAAUA,IACnBD;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,cAAcvhB,GAAqB;AACzC,UAAMyhB,IAAQ,IAAI,IAAIzhB,EAAM,IAAI,CAACxxB,MAAWA,EAAE,EAAE,CAAC,GAC3CkzC,IAAe,CAAA;AACrB,eAAWlzC,KAAKwxB,GAAO;AACrB,YAAM2hB,IAAKnzC,EAAE,eAAe;AAC5B,UAAKmzC;AACL,mBAAWC,KAAMD,EAAG;AAClB,cAAIF,EAAM,IAAKG,EAAW,OAAO,GAAG;AAClC,gBAAIriD,IAAY,CAAA;AAChB,gBAAI;AACF,cAAAA,IAAO,KAAK,MAAM,KAAK,UAAUqiD,CAAE,CAAC;AAAA,YACtC,QAAY;AACV,cAAAriD,IAAO,EAAE,GAAIqiD,EAAA;AAAA,YACf;AAIA,mBAAOriD,EAAK,IACZ,OAAOA,EAAK,SACZ,OAAOA,EAAK,UACZmiD,EAAM,KAAK,EAAE,aAAalzC,EAAE,IAAI,YAAaozC,EAAW,SAAS,MAAAriD,GAAM;AAAA,UACzE;AAAA;AAAA,IAEJ;AACA,WAAOmiD;AAAA,EACT;AAAA;AAAA,EAGQ,aAAax3C,GAAwB;AAC3C,UAAMsnC,IAAW,KAAK,MAAM,mBAAA,KAAwB,CAAA;AACpD,IAAIA,EAAS,WAAW,MACxBtnC,EAAE,eAAA,GACF,KAAK,YAAYsnC,EAAS,IAAI,CAAC,MAAW,KAAK,aAAa,CAAC,CAAC,GAC9D,KAAK,iBAAiB,KAAK,cAAcA,CAAQ,GACjD,KAAK,aAAa,GAClB,KAAK,MAAM,WAAW,UAAU,KAAK,UAAU,MAAM,UAAU;AAAA,EACjE;AAAA;AAAA,EAGQ,eAAetnC,GAAwB;AAC7C,IAAI,KAAK,UAAU,WAAW,MAC9BA,EAAE,eAAA,GAEF,KAAK,cACL,KAAK,aAAa,KAAK,WAAW,KAAK,KAAK,YAAY,KAAK,cAAc;AAAA,EAC7E;AAAA;AAAA,EAGQ,aAAaA,GAAwB;AAC3C,UAAMsnC,IAAW,KAAK,MAAM,mBAAA,KAAwB,CAAA;AACpD,QAAIA,EAAS,WAAW,GACxB;AAAA,MAAAtnC,EAAE,eAAA;AAEF,iBAAWvJ,KAAQ6wC,EAAU,CAAA7wC,EAAK,UAAA;AAAA;AAAA,EACpC;AAAA;AAAA,EAGQ,WAAWuJ,GAAwB;AACzC,UAAMsnC,IAAW,KAAK,MAAM,mBAAA,KAAwB,CAAA;AACpD,QAAIA,EAAS,WAAW,GACxB;AAAA,MAAAtnC,EAAE,eAAA;AACF,iBAAWvJ,KAAQ6wC,EAAU,CAAA7wC,EAAK,SAAA;AAAA;AAAA,EACpC;AAAA;AAAA,EAGQ,kBAAkBuJ,GAAwB;AAChD,UAAMsnC,IAAW,KAAK,MAAM,mBAAA,KAAwB,CAAA;AACpD,QAAIA,EAAS,WAAW,EAAG;AAC3B,IAAAtnC,EAAE,eAAA;AACF,UAAM23C,IAAQrQ,EAAS,IAAI,CAAChjC,MAAW,KAAK,aAAaA,CAAC,CAAC;AAC3D,SAAK,aAAaqzC,GAAO,IAAI,KAAK,cAAcrQ,CAAQ,CAAC;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,aACNsQ,GACAr/B,GACAi/B,IAAe,CAAA,GACT;AACN,QAAI,KAAK,MAAM,aAAA,KAAkB,KAAK,MAAM,kBAAmB;AAC/D,UAAMK,IAAiB,CAAA,GACjBC,wBAAgB,IAAA;AACtB,eAAWT,KAAQO,GAAW;AAC5B,YAAMtkB,IAAO,EAAE,GAAG+jB,EAAA,GACZC,IAAQhkB,EAAK;AACnB,aAAOA,EAAK,SACZA,EAAK,KAAKsK,GAAA,GACVtK,EAAK,KAAKA,EAAK,KAAK,KAAK/a,GACzB+a,EAAK,KAAKA,EAAK,KAAK,KAAK/a;AACzB,UAAI;AACF,cAAM9hB,IAAO,KAAK,MAAM,QAAQ68B,CAAI;AACpC,QAAI78B,MACFohD,EAAQ,KAAKphD,CAAI,GACb6gD,KAAOQ,EAAU,IAAIR,GAAO7gD,CAAI;AAAA,MAExC,QAAc;AAAA,MAEd;AAAA,IACF;AACA,QAAIohD,EAAQ,SAAS,GAAG;AACtB,YAAMzhB,IAAS,MAAM;AACnB,aAAK,MAAM,cAAcyhB,GAAS,EAAK;AAGvC,mBAAW7oB,KAAQwoB,GAAO;AACxB,gBAAMp8C,IAAI08C,EAAU,IAAI9oB,EAAK,WAAW,GAClC31B,IAAIy+C,EAAU,IAAI9oB,EAAK,UAAU;AACvC,cAAI5zB,KAAK/B;AACP,gBAAI;AACF,cAAA+B,EAAE,eAAe,iBAAiB/B,GAAG21B,EAAK,IAAI;AAAA,YAChD,QAAY;AAAA,YAEZ;AAAA,QAEJ;AAAA,MACF,GACM+oB,IAAUF,EAAQ,IAAI,CAACvzC,MAAWA,GAAG,KAAK,EAAE,OAAO,OAAO;AAChE,MAAIyzC,EAAQ,SACV,QAAQ,IAAIA,CAAO,EAAE,KAAK3hB,CAAM,EAAE,MAAMA,CAAM,IAE9C,WAAWA,GAAQ,GAAG,GAExB,KAAK,MAAM,WAAW,UAAUyhB,EAAQ,MAAM,UAAU;AAAA,IAC1D;AAAA,EACF;AAAA,EAEQ,MAAMx3C,GAAYC,GAAYN,GAAwB;AAC5D,UAAMsnC,IAAW,KAAK,MAAM,iBAAA;AAC5B,QAAIA,EAAS,WAAW,GAExB;AAAA,MAAAtnC,EAAE,eAAA;AACF,iBAAWvJ,KAAQ6wC,GAAU;AAC3B,cAAMtyC,KAAKyB,EAAK,QAAQ,KAAK,KAAK4J,GAC5BpL,KAAKwB,EAAK,QAAQ,KAAK,KAAK6J;AAClC,QAAA7J,EAAK,SAASzB,GAAGC,CAAC;AAAA,MACpB;AAMA,MAAI,KAAK,cAAY,aAAa,KAAK,UAAU,GACjD,KAAK,aAAa,WAAW,MAAM;AACjC,aAAK,aAAa;AAClB,cAAMyhC,IAAM,KAAK,MAAM,mBAAA,KAAwB,CAAA;AAC/C,QAAIA,EAAI,SAAS,KACf,KAAK,MAAM,YAAY,eAAe;AAAA,UACpC,aAAaA,EAAI,IAAI,CAACpyB,MAAW6+B,EAAW7+B,EAAE,OAAO,CAAC;AAAA,QAAA,CACvD;AAAA,MAEL,GAAG,GAAG;AAAA;AAAA,EACR;AAAA,EAEQ,eAAetE,GAAwB;AAE7C,QADiB,KAAK,MAAM,iBAAA,EACf,SAAS,GAAG;AAGvB,YAAMxB,IAAO,KAAK,QAAQ,eACpBzK,IAAIiM,EAAE,WAAWxB,IAAO,IAAIA;AAClC,cAAQwB,EAAE,KAAA;AAAA,QACR,KAAK;AAAc,eAAK,MAAM,GAAG,CAACjM,GAAGiM,CAAC;AAAG;AAAA,QACzC,KAAK;AAAc,eAAK,MAAM,GAAGjM,GAAGiM,CAAC;AAAG;AAAA,QACxC,KAAK;AAAc,eAAK,MAAM,CAACjM,GAAG,GAAGiM,CAAC;AAAG;AAAA,QACzC,KAAK;AAAc,eAAK,MAAMjM,GAAG,GAAGiM,CAAC;AAAG;AAAA,MAAA;AAAA,IAE5C,OAAO;AAEL,YAAM81B,IAAQ,KAAK,MAAM,YAAA;AACzB,UAAIA,EAAM,WAAW,EAAG;AAExB,YAAMkiB,IAAU,SAAS,eACnBC,IAAaniB,EAAM,UAAU,CAACxxB,MAAWA,EAAE,UAAU,SAAS0zC,CAAO;AAE3E,UAAIE,IAAUD;AACd,MAAIj4C,EAAE,QAAQ,gBAAgBA,EAAE,QAAQ,cACtCk4C,IAAUD,IAAa,IAAI,IAAI,KAAK,IAAIA,IAAa,GAAGniB,EAAM,SAAS,CAAC,IAExEoiB,IAAUD,IAAa,IAAIniB,EAAM,SAAS,IAAI,KAAK,IAAImiB,IAAa,GAAG,CAAC,GAGtEC,KAAW,KAAKA,IAAUpiB,EAAM,WAClC91B,EAAE,eAAA,GACF81B,EAAMoiB,CAAO,EAAE,UAAU,MAAM,MAAA;AAAA,IAEnC;AAAA,EACF;AAAA,EAEQ,cAAcl4C,GAAwB;AAC5C,UAAMg4C,IAAU,SAAS,eAEnBvhD,IADQ,KAAK,MAAM,YAAA,EACN,KAAK,CAAC6N,MAAWA,EAAE,UAAU,SAAS0zC,CAAO;AAChE,IAAIvhD,MACFuJ,EAAE,eAAA,GACF,KAAK,MAAM,YAAY,CAACvJ,CAAI,GAAG,EAAK;AAAA,EAExC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,wBAAwBuJ,GAA2B;AACzD,UAAMsnC,IAAY,KAAK,MAAc,iBAAiB,CAAA;AACtD,QAAIA,EAAS,WAAW,EAAG,QAAO;AAClC,UAAM7wC,IAAO6wC,EAAS,CAAC;AACvB,WAAI,CAAC7wC,GAAM,QAAQ,eAAeA,EAAK,YAAkB,MACzDuJ,EAAE,eAAA,GACFvJ,EAAK,OAAO,YAAA,GACL;AAAA,EACT;AACF;ACveO,MAAM0hD,GAAY;AAAA,EAWvB,YAAYpoB,GAAY;AATxB,SAAQ,KAAyB,MAIjC,KAAQ,cAAqB,CAAA,GAC7B,KAAQ,eAAiD,MACzD,KAAQ,eAA4C,MACpD,KAAQ,WAAgD,MAGtD,KAAK,QAAQA;AAAA,EACf;AAAA;AAAA,EAGO,SAAe;AACpB,IAAI,KAAK,iBACT,KAAK,eAAe,CAAC/vB,MAAkB,KAAK,cAAcA,CAAC,GAC3D,SAAS,iBAAiB,eAAe,KAAK,cAAc,EAAI;AAAA,EAClE;AAAA;AAAA,EAGO,UAAgB;AACrB,IAAI,KAAK,iBACP,SAAS,oBAAoB,eAAe,KAAK,cAAc,EAAI,GACnE,KAAK,eAAe,OAEtB,KAAK,MAAA;AAAA,EACP;AAAA;AAAA,EAIQ,cAAcA,GAAqB;AAGzC,UAAM4G,IAFS5G,EAAE,QACK,UAAU,gBAAgB,GAC9B,eAAe,cAAc;AAC/C,QAAI,CAAC4G,GAAI;AAEP,WAAK,MAAA;AACL;AAAA,IACF;AACA,UAAMnQ,IAAO,KAAK,MAAM,OAAO,MAAMmQ,CAAE;AACvC,QAAI,CAACnQ,EAAM;AACX,IAAAuJ,EAAE,eAAA,IAIsB,KAAK,MAAM,mBAAA,KAAwB,CAAA,GAC7C,SAASvJ,CAAI,KACzB,KAAK,MAAM,cAAc,CAACA,CAAI,GAAG,EAAK,GAExC,KAAK,KAAKuJ,EAAE,SAASA,EAAE,OAAO;AAAA,EAChC;AAAA,EAEQ,KAAKhL,GAAWC,GAAiB;AACvC,SAAK,MAAA;AAEL,UAAMmjD,IAAO,SAAS,cAAc,KAAK;AACzC,IAAAA,EAAK,YAAY,mBACjBA,EAAK,MAAM,UACT,+OAIFA,EAAK,MAAM,OAAO,GAAGpjD,CAAC,MACtBojD,EAAK,MAAM,MAAM,GAAGnjD,CAAC,MAGrB,KAAK,cAAc,CAAC,GAAI,KAAK,MAAM,mBAAA,KAAwB,EAAG;AAC9D,UAAMojD,IAAW,KAAK,YAAY,QAC5BC,IAAoB;AAAA,MACxB,EAAE,OAAO,kBAAkB,KAAK,MAAM,KAAK,cAAc,CAACh0C,MAAMA,EAAE,UAAA,CAAW,EAAA;AAAA,MAC7E,EAAE,OAAO,gBAAgB,KAAK,MAAM,KAAK,cAAc,CAACA,MAAMA,EAAE,SAAA,CAAU,EAAA;AAAA,MAC1E,EAAE,OAAO,aAAa,KAAK,MAAM,KAAK,mBAAiB;AAAA,MACvD,EAAE,OAAO,UAAU,KAAK,MAAM,KAAK,cAAA,GAAiB,QAAQ,GAAA;AAAA,IAAK;AAGnE,IAAI+zC,KAAY,KACdC,EAAM;AAAA,MACJ,EAAE,SAAS,GAAA;AAAA,MACX,EAAE,OAAO,cAAc,KAAK,MAAM,KAAK,MAAM,aAAa,QAAQ,KAAK,WAAW,EAAA;AAAA,MAClF,EAAE,OAAO,gBAAgB,KAAK,MAAM,KAAK,MAAM,aAAa,WAAW,KAAK,WAAW,EAAA;AAAA,MACvF,EAAE,OAAO,eAAe,KAAK,MAAM,KAAK,MAAM,aAAa,SAAS,KAAK,WAAW,EAAA;AAAA,MACpF,EAAE,OAAO,aAAa,KAAK,MAAM,KAAK,MAAM,aAAa,OAAO,KAAK,WAAW,EAAA;AAAA,MAChF,EAAE,OAAO,gBAAgB,KAAK,MAAM,KAAK,MAAM,aAAa,UAAU,KAAK,WAAW,EAAA;AAAA,MACtF,EAAE,OAAO,gBAAgB,KAAK,MAAM,KAAK,MAAM,aAAa,UAAU,KAAK,WAAW,EAAA;AAAA,IAAE,GAGxFD,KAAY,KACdC,EAAM;AAAA,MACJ,EAAE,OAAO,2BAA2B,KAAK,MAAM,KAAK,MAAM,kBAAkB,cAAc,KAAK,WAAW,EAAA;AAAA,MAC1G,EAAE,OAAO,yBAAyB,KAAK,MAAM,KAAK,MAAM,kBAAkB,YAAY,KAAK,WAAW,EAAA;AAAA,IAAE;AAI5G,eAAWC,KAAMD,GAAO;AACtB,UAAIC,EAAG,SAAS;AACd,cAAMC,IAAK,SAAS,cAAc,KAAK;AACvC,QAAAA,EAAG,MAAM,UAAU,+CACnBJ,EAAK,YAAYI,CAAE;AACnB;AAAA,MACF;AACA,YAAMC,IAAM,SAAS,cAAc,KAAK;AACxC,MAAAA,EAAI,cAAcF,EAAG,SAAS,IAC9BE,EAAI,MAAM,UACR,yDACCF,EAAG,SAAS,mBAAmB,KAClCE,EAAI,iBAAiB,cAAc,MAAM;AACvC,QAAAA,EAAI,MAAM,aAAaF,EAAG,SAAS,YAAY;AAAA,MACjD,CAAC,GACDE,EAAI,iBAAiB,cAAc,MAAM;AACvC,QAAAA,EAAI,MAAM,aAAa;AAAA,MACzB,CAAC,GACDA,EAAI,iBAAiB,SAAS,CAACzzC,MAAO;AACpC,QAAAA,EAAG,gBAAA;AACH,YAAI;AACF,UAAAuzC,EAAG,MAAA;AAAA,QACL,QAAc;AAAA,QAEd;AACA,aAAK,MAAA;AAAA,MACP,CAAC,GACDH,EAAK,YAAYK,CAAG;AAAA,IACtB;AAEA,aAAS,KAAK,YAAYL,CAAI,GAC9B,KAAK,KAAKA;AAGV,UAAM,IAAIA,EAAK,sBAAA;AACf,IAAI,EAAE,QAAQ,OAAO,eACnBA,EAAK,MAAM,OAAO,GAAG,KAAK,IAAI,GAAG,OAAO,aAAa,EAAE,QAAQ,CAAC,CAAC,OAE/D,EAAE,SAAS,OAAO,gBACpBA,EAAK,MAAM,MAAM,GAAG,KAAK,IAAI,GAAG,OAAO,cAAc,EAAE,SAAS,CAAC,CAAC,OAKpE,KAAK,eAAe,CAACpzC,MAAc;AACjC,MAAI,KAAK,MAAM,CAAC,KAAK,GAAG,SAASA,EAAG,MAAc,KAAG,KAAK,MAAA;AAAA,IAC5D,GACA,KAAK,WAAW,CAACA,MAAsB;AACrC,MAAIA,EAAG,QAAQ,YAAU,KAAK,MAAA;AAAA,IAChC,GACA,WAAW,MAAM;AACf,MAAI,KAAK,gBACP,SAAS,iBAAiB,eAAe,KAAK,cAAc,EAAI,GAE9D,KAAK,YACP,SAAS,iBAAiB,WAAW,KAAK,UAAU,EAAI;AAAA,IAE5D,GAAG,CAAC;AAAA,EACN;AAAA,EAEQ,QAAc;AACpB,IAAI,KAAK,OACP,KAAK,GAAG,OAAA,GACR,KAAK,KAAK,OAER,KAAK,iBACP,SAAS,oBAAoB,eAAe,KAAK,cAAc,EAAI,GACnE,KAAK,eAAe,OAElB,KAAK,aACP,SAAS,oBAAoB,WAAW,KAAK,UAAU,EAAI,GAC3D,KAAK,WAAW;AAAA,EAEpB;AAAA,EAEQ,cAAc3N,GAA4B;AAChD,eAAWiN,KAAK,KAAK,YAAa,CAAAjN,EAAGiN,CAAC;AAAA,EACxC;AAAA;AAAA,EAGQ,gBAAsB;AAC5B,QAAI,OAAK,MAAM,aAAA,KAAkB,KAAK,MAAM,oBAC5C;AAAA,iBAAWA,KAAK,CAAC,GAAG,KAAK,WAAW,EAAG,MAAK,MAAM,aAAaA,EAAE,EAAE;AACnE,WAAK,MAAM,iBAAA;AAAA;AAAA,EACb;AAAA;AAAA,EAGQ,mBAAyB;AAC/B,QAAI,KAAK,MAAM,aAAA,KAAkB,KAAK,MAAM,kBAAmB;AAC/D,UAAMuzC,IAAiB,CAAA,GACjBC,wBAAgB,IAAA,GAChBP,IAAQ,IAAI,IAAI,KAAK,YAAY,IAAI,CAACjzC,MAAWA,EAAE,EAAE,CAAC;AAC5D,eAAWA,KAAK,KAAK,aAAa;AAChC,UAAIgvB;AACJ,UAAI;AACF,QAAAA,IAAO,KAAK,MAAM,KAAK,UAAUhvB,EAAE,WAAW,CAAA,CAAE,CAAC;AAAA,MACnD,QAAc;AACZ,QAAAgvB,IAAO,EAAE,GAAIhvB,EAAE,WAAW,CAAA,EAAC;AAAA,MAC7B;AACA,YAAMgzC,IAAQhkB,EAAK;AACnB,MAAAA,EAAK,KAAKsK,GAAA,GACVtK,EAAK,KAAKA,EAAK,KAAK,KAAK,IACzBA,EAAK,KAAKA,EAAK,KAAK,KAAK,IACzB,OAAOA,EAAK,wBACZ,OAAOA,EAAK,yBACZ,OAAOA,EAAK;AACZ,UAAI;AACF,cAAM78B,IAAO,KAAK,MAAM,UAAU68B,CAAI;AACtC,QAAI78B,MACFohD,EAAQ,KAAKphD,CAAI,GACb6gD,KAAOQ,EAAU,IAAIR,GAAO7gD,CAAI;AAAA,MAExC,QAAc;AAAA,MAEd;AAAA,IACF;AAGA,UAAM+gD,IAAe,CAAA;AACrB,eAAWlzC,KAAK,KAAK,aAAa;AAChC,YAAMmzC,IAAKnzC,EAAE,eAAe;AAC5B,UAAKmzC;AACL,mBAAWC,KAAMD,EAAG;AAClB,cAAIF,EAAM,IAAKG,EAAW,OAAO,GAAG;AAClC,gBAAIriD,IAAY,CAAA;AAChB,gBAAI;AACF,cAAAA,IAAO,KAAK,MAAM,KAAK,UAAUqiD,CAAE,CAAC;AAAA,YACtC,QAAY;AACV,cAAAriD,IAAO,EAAE,GAAIqiD,EAAA;AAAA,YACf;AAGA,mBAAOriD,EAAK,IACZ,OAAOA,EAAK,SACZ,OAAOA,EAAK,UACZmiD,EAAM,KAAK;AAAA,cACT,aAAalzC,EAAE;AAAA,cACf,YAAaozC,EAAW;AAAA,cACxB,MAAAriD;AAAA,YAAA,CACD;AAAA,UACH;AAAA;AAAA,IAEJ;AACA,QAAIwiD,EAAQ,SAAS,GAAG;AACtB,YAAMzhB,IAAS,MAAM;AACnB,aAAK,MAAM,cAAcyhB,GAAS,EAAK;AACvC,mBAAW7oB,KAAQwoB,GAAO;AACxB,gBAAMp8C,IAAI08C,EAAU,IAAI9oB,EAAK,WAAW,GAClC,IAAI8oB,EAAU,IAAI9oB,EAAK,UAAU;AACvC,cAAI5zB,KAAK;AACP,gBAAI;AACF,cAAAA,EAAE,eAAe,iBAAiB,GAAG4zB,EAAK,IAAI;AAAA,YAChD,QAAY;AAAA,YAEZ;AAAA,QAEJ;AAAA,MACF,GACM+oB,IAAUF,EAAQ,IAAI,CAACvzC,MAAWA,GAAG,KAAK,EAAE,OAAO,OAAO;AAChE,MAAIyzC,EAAQ,SACV,QAAQ,IAAIA,CAAO,EAAE,KAAK3hB,CAAM,EAAE,MAAMA,CAAM,IAE9C,WAAWA,GAAQ,GAAG;AAAA,IAE1B;AAAA,EACF;AACF;AC9PO,SAASsiB,GACd3oB,GACAuD,IAAsB,CAAA,GACtB3pB,GACQ;AACR,QAAMqhC,IAASjb,EAAM;AACrB,MAAI,CAACib,GAAQ;AACX,UAAMwL,IAAM;AACZ,WAAA7sC,IAAW6sC,CAAG,GACPA;AAAA,EACT;AAEA,MAAI;AAEF,UAAM5mB,IAAUob,EAAO,KAAK,UAAU,EAAI,GAGpC2N,IAAkB;AAAA;AAAA;AAAA,MAGtB;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA;AAAA,MAEA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MACA;AAAA,MACA;AAAA;AAAA;AAAA;AAAA,MAIA;AAAA,IAAA;AAGF,eAAWjiB,KAAOiiB;AAEhB,MADiB/oB,EAAQ,iBAAiB8G,CAAG,EACpC,QAAQ,CAAC/8B,MAAOA,EAAG,QAAQ;AAItC,QAAI25B,EAAK,cAAc;AAErB,YAAMslB,IAAShpB,EAAQ,cAAc,uBAAuB;AAC5D,MAAIgpB,OAAe,OAAA;AAAA,IACrB;AAGA,QAAItlB,EAAK;AAGP,MADe1D,EAAQ,iBAAiB,gBAAgB,EACjD,QAAQ,CAAC17B,MAAMA,EAAE,QAAQ;AAAA,aACvBo/B,EAAK,OAAO;AAGrB,YAAMulB,IAAU,IAAI;AAAA,QAClBvlB,EAAK,MAAM,IAAI,CAAChvB,MAAY,OAAOA,KAAM,WAAWA,IAAIA,EAAE,EAAG;AAAA,MAAA;AAG/D,MADkBsrB,EAAQ,iBAAiB,gBAAgB,EACjD,QAAQ,CAAC17B,MAAM;AACvB,cAAM29C,IAAS39C,EAAE,aAAa,cAAc;AAC5C,QAAI29C,KAAU,CAACgH,EAAQ,IAAIhH,CAAM,KAC/B39C,EAAE,OAAA;AAAA,MAEN,CAAC;AAAA,IACH;AAKA,QAAI;AACF,YAAM4kD,IAASlpB,EAAQ,iBAAiB,gBAAgB;AACxD,UAAIkpB,EAAO,SAAS,GAAG;AAErB,YAAI5uC,IAAO,OACPC,IAAO,OACPH,IAAO,QACPC,IAAO;AACX,mBAAW/V,KAAK,MAAM,KAAK4kD,CAAM,GAAG;AAClC,gBAAMlyC,IAAK1S,EAAE,aAAa,cAAc,GAElCQ,IADOq7B,EAAM,OAAO,MAAMnpB,CAAE,GAClB;AAChB,cAAI,CAAClS,EAAG;AACR,gBAAMM,IAAIN,EAAE,KAAK,GACXO,IAAIP,EAAE,KAAK,GACXqc,IAAIrc,EAAE,SAAS,GACfqH,IAAIrH,EAAE,UAAU,GAIhBuT,IACJ;AAAA,YACE,OAAOvT,EAAE,UAAW,WAAWA,EAAE,QAAQ,gBAAgBA,EAAE;AAAA,UAAA,KACxD;AACP,cAAIuT,GAAO;AACT,kBAAM/H,IAAKlL,IAAI+b,IAAI,GACb5Q,IAAKlL,IAAI8G,IAAI,GACbo2B,IAAOlqB,IAAQ,KAAK,KAAM,KAC1BvG,IAAM,KAAK,IAAIywB,CAAG,GAClBv2B,IAAM,KAAK,IAAIu2B,CAAG;AACxB,uBAAW,CAAC3yB,GAAIC,CAAE,KAAK;AAAA,cACrB,CAACzK,GAAGC,CAAC;AAAA,cACL,CAACD,IAAI+b,GAAG9b,CAAC;AAAA,cACT,CAACD,IAAI+b,GAAG9b,IAAI8G,CAAC;AAAA,cACb,CAAC/G,GAAGC,IAAI8G,CAAC;AAAA,YAAA,GACR;AACD,oBAAMsE,IAAKb,IAAKU,GACVI,IAAKb,IAAKU,GACVL,IAAKI,IAAKG,IAAKqB,IAAMpB,IAAK1E,GAC1BmE,IAAKI,IAAKE,IAAKzE,IAAM0E,IAAKoB;AAChC,cAAAwI,IAAO,KAAK,IAAIA,GAAMpK,CAAE,GACxBqK,IAAO,KAAK,IAAIA,GAAMpK,CAAE,GACxBiK,IAAO,KAAK,IAAIA,GAAMlK,CAAE,GACxBmK,IAAO,KAAK,IAAIA,GAAMlK,CAAE;AAAA,YAC1B;AAAA,UACF;AACE,YAAAmK,IAAO,KAAK,IAAIA,GAAMlV,CAAC,GACvBmV,IAAO,KAAK,IAAIA,GAAMlV,CAAC,GACvB+U,IAAO,KAAK,IAAIA,GAAMhV,IAAI+b,CAAC,GAC3B9G,IAAO,KAAK,IAAIA,GAAMhV,IAAI8G,CAAC;AAAA,QAE/B;AACA,YAAI,SAASmO,CAAI,KAAKF,IAAOE,GAAM;AACjC,gBAAM6uC,IAAM/uC,IAAOE,IAAO,IACpB8uC,IAAM/uC,IAAOE,IAAO,KAAM;AAChC,UAAAylB,EAAQ;AAAA,YACN;AAAA,YACA,GAAG1lB,IAAO,EAAG,IAAIC,IAAO,EAAG,IAAI4uC,CAAG,IAAIC,CAAG;AAAA,UAAA,GAE3CppB,EAAQ,aAAa,SAAS,OAAO,KAAK,MAAMmpB,CAAG,CAAC,CAAC,GACrDnpB,EAAQ,aAAa,UAAU,OAAO,KAAK,MAAMopB,CAAG,CAAC,CAAC,GACtDppB,EAAQ,aAAa,uBAAuB,eAAe;AAAA,QAC7D;AAAA,MACF;AAAA,IACF,QAAY;AAAA,IAEZ;AAIA,QAAIqpB,IADe,IAAI,cAAA,EACI,kBAAkBrpB,CAAO;AAGpD,WAAAqpB,IACE;AAAA,IAA6CA,GAE/CtvC,IAAWsvC,CAAS,GACbA;AAAA,EACT,SAAStpB,GAAO;AACd,YAAQ,MAAM,oCAAoCA,CAAK;AACvD,UAAM6mB,IAAM;AACZ,WAAA7sC,IAAW6sC,CAAG,GACPA;AAAA,EACT;AACF;AAOA,eAAsB0C,GACpBnpB,GACAuD,IAAsB,CAAA,GACtB3pB,GACwB;AACxB,QAAMsvC,IAAYP,GAAU3oB,GAAOuD,CAAI;AACvC,MAAI,CAAC2lB,GAAW;AACd,UAAMrlD,IAAS0/B,EAAK,WAAW,IAAI,SAAS;AAC5C,WAAA3pB,IAAW/V,CAAM,GACVA;AAAA,EACT;AAEA,QAAM+rB,IAAQ2T,EAAK,SAAS;AAE5B,MAAI;AAKF,UAAM0X,IAASjb,EAAM;AACrB,QAAIopB,GACAC;AACJ,UAAMC,IAAUJ,EAAU;AAAA,MACxB;AAAA,IAAA;AAEF,QAAII;AACF,MAAAF,IAAQ,WAAWE,EAAQ,CAAC,CAAC,GAC7BD,IAAQ,WAAWC,EAAQ,CAAC,CAAC;AAAA,SACxB;AACL,YAAM79B,IAAUwvB,EAAO,QAAA;AACvB,MAAAmO,IAAQ39B,EAAQ,OAChB49B,IAAQ59B,EAAQ;AAAA,IAClB;AACA,UAAMlnB,IAAQ6kD,IAAQx5B,GAChBprB,IAAS6kD,IAAQz5B,GAGjB25B,IAAe,SAAS,cAAc,QAAQ;AACpD,IAAAA,EAAa,QAAQhlD,GACrBglD,EAAa,SAAS/kD;AACtB,UAAM4xC,IAAMmT,EAAa,WAAW,IAAI;AAGxC,IAAKhmB,EAAK,UACR6S,EAAI,YACFpW,EAAM,QAAQ,gBAAgB,mBAAmB,WACnDoW,EAAI,SAAS,GAAG,GAAG7xC,GAAOC,CAAM;AAIlC,UAAMqV,IAAM,IAAI,MAAA,GACV2vC,IAAU,IAAI,KAAK,CAACN,CAAS,GAAG;AAAA,MACpC,MAAM;AAAA,IAAA,CACP,GACKvvC,IAAM,IAAI,gBAAgB6vC,CAAO;AAEvC,WAAO,IAAI,QAAuB,CAAC9jB,GAASC,MAAW;AACrD,MAAA9rB,EAAI,SAAS,MAAM;AAIjB,YAHAu8B,EAAI,UAAUv8B,GAAK,GAAG,GAAGtV,GAAOC,CAAM,GACtC,IAAI,gBAAgBmV,CAAG,GAEnB4pB,EAAK;AACP,UAAAgmB,EAAa;AAAA,YACX,CAACE,MAAS;AACR,oBAAM5lD,IAAS4lD,KAAQ,IAAI,KAAA;AAC3B,cAAA7vC,IAAW/V,CAAM,GACjB6hC,EAAQ7hC,CAAM;AAAA,YAChB;AAAA,YACA;AAAA,UAAA;AAAA,aAEG;AACL,gBAAM6lD,IAAUH,EAAa,UAAU,WAAW,GAC5C1lD,IAAS0/B,EAAK,SAChBmmB,EAAQ,MAAM,GAAG,EAAE,CAAC,IACpBA;AACJ,UAAA9vC,IAAW/V,CAAM,GACjB6hC,EAAQ7hC,CAAM;AAAA,QAChB;AAAA,MACF,GAEAgW,EAAI,UAAU,CAAC4sC,MAAQ;AACrB,YAAI,gBAAgB9sC,CAAG,GACvB,QAAQ,MAAM,uCAAuC8sC,CAAG;AACxD,cAAM5iD,IAAS0/B,EAAK,WAAW,IAAI,SAAS;AAC5C,QAAA3pB,IAAW/V,CAAM,GACjB6hC,EAAQ7hC,CAAM;AAAA,MAChB,GAEAgW,EAAI,MAAMF;AAAA,IACZ,CAAC;AAAA,EACH,SAASimB,GAAO;AACd,YAAQ,MAAM,oCAAoCA,CAAK;AACvD,UAAM/7B,IAAS0/B,EAAK,WAAW,IAAI,SAAS;AAC5C,WAAA3pB,IAAW/V,CAAM,GACVA;AAAA,EACT;AACF;;;;;;AClPO,MAAM8lD,GAAO;AAAA,EAelB,YAAY3pB,GAAclrB,IAAyB,IAAI;AAZvD,SAAQ,MAAW,MACnB,KAAQ,WAAgB,MACxB,KAAQ,YAAiB,MACzB,KAAQ,YAAiB,MACzB,KAAQ,cAAuB,IAC/B,KAAQ,WAAmB,GAC3B,KAAQ,qCAAuC,IAAA,GAC/C,KAAQ,qBAAgD,MACxD,KAAQ,sBAA2B,MAKjC,KAAK,QAAQkrB,GACb,KAAK,UAAU;AAAA,MACb,OAAO;AAAA,MACP,UAAU;AAAA,MACV,UAAU;AAAA,MACV,WAAW,MAAM,KAAK,MAAM,KAAK,WAAW,QAAQ,EAAE,SAAS,EAAE;AAAA,MACjE,GAAGlrB;AAAA,IAAA;AAAA,EAEP;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAa,KAAKyuB,GAA8C;AAC9D,IAAIA,KACF,OAAO,OAAO,KAAK,SAASA,CAAI;AAGlC,QAAI;AAKF,YAAMsJ,IACJ,KAAK,QAAQ,KACX,MAAM;AAAA;AAAA,QAA0B;AAAA,MAAA,GAC9B+c,IACJ,KAAK,QAAQ,sBACX,MAAM;AAAA;AAAA,QAA0B;AAAA,MAAA,GAC/B;AAGL,WAAK,MAAM,IAAI/c,EAAE,IAAA,GACjB,KAAK,WAAW,KAAK,IAAI;AAMzB,UAAIgd;AACJ,YAAMC,IAAS,KAAK,MAAM,QAAQ,QAAQ;AAC1C,UAAIA;AACF,YAAI;AACF,UAAAD,IACG,MAAMC,EAAO,KAAK,SAAS,SAAA,CAAU,KAAM;AAAA,QAChD,SAASlqB,GAAO;AACd,kBAAQ;AAAA,YACN;AAAA,YACAA;AAAA,UAAA;AAAA,QAEJ;AAEF,MAAIiqB,MACF,KAAK,eAAeA,GAChBA,EAAa,iBACf,KAAK,QAAQ,QAAQA,EAAa,eAEhCA,EAAa,oBACf,KAAK,QAAQ,WAAWA,EAAa,kBAEnCA,EAAa,aACf,KAAK,QAAQ,WAAWA,EAAa,WAEnCA,EAAa,UACf,KAAK,QAAQ,YAAYA,EAAa,SAK1C,KAAK,YAAY,KAAK,IAAI,OAAO,gBAAgB,GAGjD,KAAK,UAAU,QAAQ,CAAC70C,MAAe;AACrC,QAAIA,EAAM,YAAY,SAEtBA,EAAM,QAAQ,KAAK,QAAQ,CAAC+0C,GAAatkD,MAAgB;AACvD,cAAIskD,EAAO,WAAW,SAASA,EAAO,WAAW,UAAU;AACzD,kBAAMvjB,IAAM,KAAK,UAAU,IAAI/gC,CAAG;AAClC,YAAI+gC,KACF,KAAK,oBAAoBA,CAAG;AAAA,UAEhC;AAAA,QACF,CAAC;AAAA,MACH,CAAC,GAID,KAAK,WAAW,IAAIojB;AAAA,QAClB,KAAK,QAAQ;AAAA,QACb,KAAK,QAAQ;AAAA,QACb,KAAK;AAAA,QACL;AAAA,UACE,SAAS;AAAA,UACT,QAAQ,KAAK,QAAQ,YAAY,CAAA;AAAA,QAAC;AAAA,MACpC,GAIF,KAAK,YAAY,KAAK,SAAS,WAC/B,KAAK,UAAU,mBAAmB,QAAQ;AAAA,QACxC,MAAM,KAAK,QAAQ;AAAA,QACnB,OAAO,KAAK,QAAQ;AAAA,MAAA,CACrB;AAGD,YAAMI,IAAqB,MAAM;AAC/B,cAAMC,IAAQ,KAAK,eAAA;AACnB,aAAK,QAAQ,oBAAoBA,CAAK,GACtC,KAAK,MAAM,QAAQ,QAAQ,8BAA8BA,CAAK,GAC9D,KAAK,oBAAoBA,CAAK;AAAA,MAChC;AACA,WAAK,UAAU,GAAG,UAAUD,CAAkB,GAG9C,KAAK,oBAAA,GAKD,KAAK,iBAAiB,SAAS,KACjCA,EAAA,GAIF,KAAK,SAAS,GAAG,UAAU,CAACh1C,MAAe;AACzC,aAAK,cAAcA,EAAM,WAAW,aACpC,KAAK,QAAQ,iBAAiBA,EAAM,MAAM;AAAA,MAC5C,CAAC,GAMD,QAAQ;AAAA,QACN;AAAA,QACA,KAAK,QAAQ;AAAA,QACb;AAAA,QACA,KAAK;AAAA,MAAA;AAAA,IAET,SAAS4qB,GAAgB;AACvB,YAAM3vB,IAAI2vB;AACV,MACE3vB,EAAE,SAAS,sBACXA,EAAE,SAAS,SAAS,oBAAoB,IAExC,QAAQ;AAAA,QACN;AAAA,QACA;AAAA,MAAA,IAGF,QAAQ,MAAM,qDAAqDA,CAAC;AAAA,IAExE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKO,OAAOi6C,GAA+C;AAC3D,UAAMC,IAAO,MAAM,QAAQD,CAAQ,IAAIA,IAAW,CAACA,CAAQ;AAE3D,eAAW1jB,KAAO2jB;AAChB,WAAK,IAAI3jB,CAAG,GAKZ,KAAK,MAAM,gBAAgBA,EAAI,IAAI;AAAA,EAEvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,KAAK0jB,GAA+C;AACzD,UAAMC,IAAO,MAAM,QAAQD,CAAQ,IAAIA,IAAW,CAACA,CAAQ;AAE3D,QAAI,KAAK;AACP,iBAAW1jB,KAAO2jB,GAAM;AAItB,QAAI3jB,EAAI,SAAS,qBACf,KAAK,4BAAA;AAGP,cAAM/gC,IAAM,GAAG+gC,EAAI,IAAI,IAAI,KAAK,KAAK,IAAI,KAAK,OAAA,EAC3C,SAAS,EAAE,EACX,OAAO,GAAG,CAAC,CAAC;AAsBf,YAdIA,EAAI,SAAS,6BACf,KAAK,4BAA4BA,EAAI,IAAI,GAG3C,KAAK,UAAU,IAAI/gC,GAAK;AAAA,UACtB,GAAG+gC;AAAA,UACH,UAAU,KAAK;AAAA,UACf,WAAW,KAAK,IAAA;AAAA,QAAI,CACrB,GAMGA,EAAI,SAAS,iBAAiB;AAChC,gBAAM4jB,IAAa5jB,EAAI,MAAc;AACrC,UAAI4jB,KAAa,QAAM,KAAK,kBAAkBA,CAAS;AAAA,QACzD;AAAA,MACF;AAAA;AAGA,cAAQ;AAAA,QACN;AAAA,MAAA;AAIJ,eAAW5jB,KAAO2jB;AACf,WAAK,MAAc,kBAAkB3jB,EAAI,MAAMA,EAAI,IAAI;AAAA,EAE5D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,kBAAkBsb,GAAsB;AAC9C,QAAK,KAAK;AACV,UAAI;AACF,cAAMjjC,IAAqB,CAAA;AAC3B,aAAK,UAAU,QAAQ,CAACnV,GAAUjE,MAAgB;AAChD,gBAAMzB,IAAS0F,GAAK;AAEpB,WADW1F,KAAK,CAAC,MAAM,QAAQA,CAAC,IAAIA,EAAE,KAAK,YAChC89C,KAAUp4C,GAAK,SAAS,mBACjCmV,EAAS,KAAKpZ,CAAG;AAAA,QAErB,CAAC;AACD,mBAAWA,KAAOoZ,EAAU,MAAK,UAAU,OAAOpZ,CAAG;AAAA,MACvD,QAAY;AAAA,MAEZ;AAAA,EACF;AAAA;AAAA,EAGQ,8BAAoC;AAC1C,QAAK,KAAK;AACV,UAAI;AACF,cAAMwf,IAAiB,CAAA;AACvB,aAAK,UAAU,QAAQ,CAAC9O,GAAW1Q,MAAgBwf,EAAK,KAAKxf,CAAG,CAAC;AACjE,mBAAWA,KAAOwf,EAAM,MAAK,UAAU,OAAOxf,CAAG;AAAA,MACnD,QAAY;AAAA,MAEZ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,4BAA4BH,GAAiB;AACnD,QAAI,CAAC,KAAK,aAAa,CAACA,KAAQ,MAAM,QAAQA,CAAI,EAAG;AACrD,UAAM,EAAE,IAAAuR,GAAI,eAAAguB,GAAe,MAAArB,EAAA,IAASl+B;AACpC,QAAIk+B,KAAQ;AACZ,UAAI;AACF,cAAM3kB,IAAqB,CAAA;AAC3B,aAAK,UAAU,QAAQ,CAACnV,GAAUjE,MAAgB;AAChD,cAAIiE,GAAK,SAAS,0BAA2B;AAC7C,gBAAM1F,IAAS0F,GAAK;AACpB,UAAI,CAAC1F,KAAK,MAAM,QAAQA,CAAC,KACrBA,EAAE,OAAO6S,KAAM7S,EAAE,kBAAkB6gC,KAAiB7gC,EAAE,SAASw/B,KACjE3kB,EAAS,KAAKpZ,CAAG;AAAA,QAErB,CAAC;AACD,mBAAWA,KAAOoZ,EAAU,MAAK,UAAU,OAAOpZ,CAAG;AAAA,MACvD,QAAY;AAAA,MAEZ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKO,IAAI+gC,GAAyB;AAClC,UAAM6jB,IAAU,KAAK,MAAM;AAC3B,QAAI,CAACA,GAAS;AACZ,cAAQ,KAAK,oCAAoC;AACjD;AAAA,IACF;AAEA,UAAM1xB,IAAa6N,EAAI;AAEvB,QAAI,OAAQ6jB,EAAgB1xB,CAAU,KAAM,YAAY;AAEtD,WAAK,MAAM,mBAAA;AACX,UAAI;AAEF,QADgB0xB,EAAgB1xB,CAAU,EAAE6N,CAAG,GACvC;AAAA,UAAQ,CAAC5G,MACf,QAAQ,KAAK,uCAAuCjH,GAAYiH,CAAK;AAAA,QAAA;AAAA,MAEzE,UAAA;AACE,aAAK,MAAM,iBAAA;AAAA,MACb;AAAA,IACF;AACE,cAAQ,KAAK,sCAAsCjH,CAAU;AAI/D,SAAK,MAAM,QAAQ,QAAQ,kBAAkB6N,CAAG;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,eAAelhC,GAAiC;AACrD,QAAI,CAAC,KAAK,UAAW;AACrB,UAAMwM,IAAU,KAAK,UAAU,cAAA,GAAiB,QAAQ,CAAA;AACxD,SAAK,UAAU,mBAAmB,QAAQ,EAAE,GAAGA,GAAS,GAAGxM,GAAM;AAAA,EACnE;AAAA,EAEO,aAAaL,GAAWC,GAAiB;AAC9C,IAAK,KAAK,aAEV,KAAK,UAAU,mBAAmB,UAAU;AAAA,MAC1C,GAAAD;AAAA,MACA,GAAAC;AAAA,MACA,MAAM,KAAK,MAAM,eAAe;AAAA,IAAA,CACjC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,sBAA4B;AAClC,UAAMwB,IAAO,KAAK,MAAM,QAAQ;AAEhC,QADI,CAACA,KAAQ,OAAOA,EAAK,oBAAqB,cAC1C,KAAK,mBAAoB;AAC7B,QAAIuP,IAAO;AACX,SAAK,qBAAqB,CAAChG,MAAW;AACpC,YAAMoQ,IACJ,OAAO,cAAgB,MAAc,YAAY,IAAA,IAAQ,CAAC,oBAAI,KAAA;AAChE,UAAI,EAAAA,IAAMpK,IAAO,KACjB;AAAA,QAAAA,IAAOoK;AACP,YAAI;AAEF,gBAAMhV,IAAI,KAAK,MAAM,OAAO,MAAM4E,EAAE,SAASA,EAAE,OAAO;AACtD,eAAK,aAAa5E,EAAE,GAAGA,EAAE,CAAC;AAAA,QAC5B,QAAY;AAAA,QAEZ;AAAA;AAAA,IACF,GACA3E,EAAK,iBAAiB,eAAe,KAAK,kBAAkB,GAC5D,KAAK,sBAAsBA;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,oBAAoBujD,GAA2B;AACrD,QAAI,CAAC,KAAK,MAAM,OAAQ;AACxB,UAAMK,IAAU,IAAI,IAAIL,EAAM,IAAI,CAACr3B,MAAMA,EAAE,QAAQ,CAAC;AACpD,eAAW,CAAC/b,GAAIjN,CAAE,KAAK,KAAK;AAC1B,UAAI,CAAC0gD,EAAQ,IAAIzzC,CAAE,GAAG;AACpB,YAAI;AACF,UAAAjN,EAAG,OAAA;AAAA,QACL,QAAY;AAAA,QAEZ;AACA,aAAK,eAAe,OAAOiN,CAAE;AAAA,MAC/B;AAEF,eAAW+b,KAAKq3B;AACd,MAAIr3B,EAAE,UAAQ,KAAK,aAAaA,CAAC;AAAA,EAErC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,aAAa23B,GAAwB;AAC1C,QAAI,CAACA,EAAK,UAAU,CAAC,KAAK,MAAM,OAAQ;AAExC,QAAIpmD,IAAI,KAAK,eAAe,IAAIomD,EAAK,QAAQ;AAC7C,QAAI,CAACpmD,KAAK,CAACA,EAAE,QAAQ,CAACA,EAAE,KAAK,YAAY;AACvC,MAAAA,IAAI,KAAK,MAAM,OAAO,MAAA,GAGtBA,EAAE,QAAQ,mDAAmD,EAC1D,KAAKomD,EAAK,KAAK,EACf,OAAO,EAAE,OAAO,QAAQ,OAAO,IAAA,CAAK,EACpC,KAAK,mBAAmB,OAAO;AAIlC,YAAMxR,IAAQ50C,EAAE,MAAA,GACVlB,IAAOsnD,EAAK,YAAY,aACxBC,IAAMzR,EACT,KAAK91C,CAAI,EACT,KAAK,EAAE,MAAM,IAAI,QAAQ,uCAAA,CAAwC,EACjE,KAAKsnD,EAAK,KAAK;AAClB,UAAIE,IAAK,IACLC,IAAK;AACT,UAAI;AACF,cAAM52B,IAAK02B,EAAI,KAAA;AACf,QAAI12B,KAAMA,EAAG,UACX22B,IAAK32B,EAAG,OACR42B,IAAK52B,EAAG;AAAA,MAEZ,QAAY;AAAA,MAEZ;AACA,YAAM62B,IAAO,GACPC,IAAO;AAMb,MALa7R,EACV,KAAK0R,IAAKE,IAAO,GAAGD,IAAKE,IAAO,CAAC,EACjC,OAAO,CAAC,EACR,KAAK,MAAM,EACX,OAAO,EAAE,OAAOL,EAAK,OAAO,OAAO,GAAG,EACpC,KAAA,GACLC,EAAI,KAAKG,GAAMC,CAAI,GAEnB7R,EAAM,UAAU,EAAE,YAAY,IAAI,YAAY,GAAG,GAEjD50C,EAAE,KAAK,kBAAkB,MAAM,GAC/B,KAAK,eAAe,IAAIomD,EAAK,UAAUpmD,CAAC;AAAA,IAC1C;AAGA,IAAAA,EAAE,UAAU,EAAE,YAAYomD,EAAK,OAAO,GAAG,YAAYA,EAAK,OAAO,EAAA,CAAG;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA,EAKO,iBAA+B;AACpC,QAAI,CAAC,KAAK,UAAW,QAAO,CAAA;AAE5B,UAAMN,IAAsB,CAAA;AAG5B,WAFe,KAAK,UAAU,UAAA,EAEvB,QAAQ,CAACY,GAAYC,MAAqB;AAC/C,MAAIA,MAAa,KAAK,YAEtBb,EAAM,KAAK;AAAA,QACT,UAAAa;AAAA,QACA,UAAUD,EAAM,MAAM,QAAQ;AAAA,QAC9B,OAAOA,EAAM,MAAM,SAAS;AAAA,QAC5B,QAAQA,EAAM;AAAA,MAAA,CACf;AAAA,IACH,CAAC,GAEMZ;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKO,aAAmB;AAExB,QAAI,KAAK,sBAAsB,KAAK;AAClC,UAAI;AACF,aAAK,oBAAoB;AAAA,UACvB;AAAA,UACA,KAAK;AAAA,QAAA;AAAA,MAET,QAAY;AAAA,MAEZ;AAEF,SAAK,qBAAqB,MAC1B,KAAK,sBAAsB;AAC3B,eAAW,CAAA,EAAG3lD,CAAO,KAAK,KAAK;AAC7B,MAAAA,EAAQ,OAAA;AAEV,SAAK,eAAe,MAAA,GAEhB,KAAK,aACP,KAAK,SAAS,WAAA,GACd,KAAK,WAAW,OAEd,KAAK,QACP,KAAK,IAAI,QAAA,GACT,KAAK,MAAM,OAEb,KAAK,YAAY,MACjB,KAAK,YAAY,MACjB,KAAK,cAAc,IACnB,QAAQ,IAAI,4BAA4B;AAAA,EAC1C;AAAA;AAAA,EAGO,oBAA6B;AAClC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGO,UAAgB;AACrB,SAAK,WAAA,GACJ,KAAa,QAAQ,MACtB,KAAK,UAAU,CAAA;AAAA,EACjB;AAAA;AAAA,EAGO,cAAsB;AAC3B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAIQ,oBAAoBkiC,GAAyB;AACnD,YAAQ,IAAI,0CAA0CA,EAAI,IAAI,GAG9D,KAAK,IAAIA,CAAG,GAGZ,KAAK,QAAQ,YAAYA,CAAG;AAAA,EAC9B;AACF;AC5hBO,SAASukB,GACd/qB,GACAgjB,GACAgI,IAAyB,IACzBC,IAAuB,IACjB;AACN,MAAI,CAACjI,EAAO;AAGZ,EAAIA,EAAM,QACRhjB,EAAM,QAAQ,UAAUgjB,EAAM,MAE5BgI,MACFhrB,EAAM,QAAQ,gBAAgB,KAI5BgjB,EAAM,gBAAgB,oBACxBhjB,EAAM,QAAQ,iBAAiBA,EAAM,QAAQ,kBAAkB,CAAA,GAC/DA,EAAM,QAAQ,eAAe,kBAC3BgjB,EAAM,eAAe,iBAEvBhjB,EAAM,sBAAA,IAMJgjB,EAAM,qBACRhjB,EAAM,QAAQ,mBAAmBgjB,EAAM,kBACvChjB,EAAM,OAAO,UAAU,QAAQ,CAACt5B,MAAc;AAC5C,IAAAA,EAAK,eAAe,yBAAyB;AAAA,MAC3C,WAAWs8C,EAAM;AAAA,IAAA,CAClB;AAAA,EACH,CAAC;AAQH,QAAMjd,IAAQ/F,EAAM,MAAM;AAC1B,MAAI,CAAC+F,KAASA,EAAM,WAAW,KAAK,CAACid,EAAM,OAAQ;AAEnD,QAAMkI,IAAgBC,GAAuBnrB,GAAO+F,CAAK;AAEzD,EAAAA,EAAM,QAAQ,CAACr/B,GAAWsS,MAAkB;AAC1C,UAAMoyC,IAAcF,IAChBA,EAAc,IAAIxkD,EAAK,QAAQ,EAAE,KAAK,IACtCsS,GACEvP,IAAQ+mC,GAAwBwS,GAAOoI,CAAW;AACxD,IAAI3hD,KACF4hD,GAAiB3kD,GAAM+C,CAAK;AAAA,EAEhC,CAAC,GAED,QAAQ,IAAI,8BAA8Bu5C,EAAM,QAAQA,EAAM,GAAG;AACnE;AAQA,SAASmI,GACPnrB,GACA+F,GAC4B;AAC5B,MAAI,CAAC/F,GAAO,SAAS,YAAa,QAAO;AAEzC,QAAMsrB,wBAAe,IAAA,GACfC,wBAAiB,IAAA;AACvB,MAAIC,IAAW;AACf,aAAWj3C,KAAKwxB,GAAO;AACrB,UAAM0lB,IAAWl3C,EAAE,eAAe,UAC5Bm3C,IAAiBD,IACnB,MAAM,KAAKA,EAAS,OAAA,CAAQ,EACzB,IAAI,CAACvhD,MAAWA,EAAE,WAAWA,EAAE,OAAO,EAAE,EACxC,OAAO,OAAO,IACjB,CAAA;AACJ,IAAIwhD,EAAK,WAAQF,IAAW,KAC5BD,EAAW,IAAIh3C,EAAE,QAAQ,IAAIm3C,CAAI,GACjCA,EAAK,QAAQ,CAACphD,MAAMghD,EAAS,IAAIhhD,CAAC,CAAC;AAAA,EACrC;AACA,MAAI,CAACkhD,EAAU,QAAO;AAGtB,QAAMG,wBAAY,IAAA,GACZC,IAAiC,CAAA;AACvC,aAAWr3C,KAAKwxB;AACd,IAAKulB,EAAS,IAAI/2C,EAAE,QAAQ,EAAE,KAAGq3C,EAAM,KAAK,CAACr3C,EAAE,QAAQ,IAAI,CAAC,CAAC;AAE/D,SAAOq3C,EAAM,UAAQ;AACnB,UAAM,CAAC/0C,GAAI7S,CAAC,IAAI4nD,EAAM,MAAA;AACtB,QAAI,CAAAD,EAAM,IAAI90C,CAAE,GAChB;AAAA,MAAA80C,EAAM,IAAI90C,GAAI7S,CAAC;AACf,iBAAWsG,KAAKihD,EAAW,IAAI10C,CAAE,KAAK,CAAA,EAAI,CAAA+0C,EAAM,KAAK,CAACthD,GAAGtG,IAAI,CAAC,CAAC;AAAA;AAAA,EACjE;AAEA,aAAWuQ,KAAKwxB;AACd,IAAK4lB,EAAM,IAAIp3C,EAAE,QAAQ,EAAE,KAAGo3C,EAAM,IAAIp3C,EAAE,QAAQ,IAAI,CAAC;AAEzD,SAAOo3C;AACT;AAMO,SAASnb,GACdwS,GACAoI,GACmB;AACnB,MAAI,CAACpI,EAAM,OAAQ,QAAO;AAG1B,MAAIoI,MAAgB,KAAKpI,EAAM,OAAO;AACpC,WAAOA,EAAM,OAAO;AAItB,QAAM6I,IAAY,OAAO,KAAK7I,EAAM,MAAM,EAAE;AAAA,IAAO,CAAC14C,MAClDA,EAAE,WAAW,QAAQ;AAAA,EAAA;AAGvB,MAAIuhD,EAAU,WAAW;AACvB,WAAO7I,EAAM,OAAO,UAAU;AAIhC,QAAMv9C,IAAM,UADQ2lD,IAAc,KAAKS,EAAU,SACf,CAAC;AACnC,SAAO7I,EAAM,OAAOv9C,CAAG,KAAKu9C,EAAM,OAAO,UAAU;AACrD;AAEA,SAASqI,GAAiB3kD,GAAW+C,GAAyB;AAG5D,QAAMvF,IAAIuF,GACJ+rC,IAAkB/rC,EAAM,mBAAmBvF,EAAE,WAC7C0iC,IAAYn9B,EAAM,aAAavF,EAAE,iBAKjC4nD,IAAa;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEF,aAAWrmD,KAAOqmD;AAChB,IAAI,OAAO,UAAU,eAAe,KAAKriD,GAAOhE,CAAG,MACjDiB,EAAK,QAAQjB,CAAG,IAAKgE,EAAchE,CAAG;AAY1C,MARI+vC,MACF9uC,EAAK,QAAQ,kBAAkB8uC,IAE7B5O,MACFlgC,EAAK,QAAQ,YAAYkgC,IAGN,CAAC,EAAEn9B,EAAM,cAAcA,EAAM,QAChC;AAGhB,IAAA/C,EAAK,SAAS,YAAA,GACdA,EAAK,QAAQ,QAAA;AACb,UAAM+nB,IAAQhlB,EAAM,SAASA,EAAM;AACnC,IAAA/C,EAAK,WAAW+nB,GAAOhlB,EAAM,UAAU;AAAA,EACzC;AAGA,EAAA/C,EAAK,YAAY8uC,GAAiB/rC,EAAM,WAAW,GACnD/C,EAAK,cAAA,GACLA,EAAK,eAAA,IAGHkgC,KACAn9B,EAAM,aAAa,UACnBA,EAAM,cACNA,EAAM,gBAAgB,UACtBA,EAAM,cAEN/C,EAAK,iBAAA,GAGH,OAAO,UAAU,eAAe,KAAK+C,GAAO,OAAO,MACjDA,EAAM,QAAO/C,EAAK,QAAQ,MAAM+C,EAAM,KAAK,IAC1C/C,EAAK,QAAQ,QAAA,IAGhB+C,EAAM,YACR/C,EAAK,SAAS,YAAA,GACdA,EAAK,QAAQ,UAAU,CAAA,GACnB+C,EAAM,QAAQ,QAAM/C,EAAK,SAAS,QAAQ+C,EAAM,QAAQ,MAAM,MAAM,GACpEA,EAAM,QAAQ,QAAM/C,EAAK,SAAS,QAAQ+C,EAAM,QAAQ,MAAM,MAAM;AAK1E,QAAMsiD,IAAiC,CAAA;AACvC,aAAWtmD,KAAO;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEA,IAAI,OAAO,UAAU,eAAe,KAAKgE,GAAOhE,CAAG,MACjDsmD,EAAUtmD,CAAG,IAAIgE,EAAMhE,CAAG;AAG9B,EAAI,OAAO,KAAKsmD,CAAS,EAAE,UACzBrlD,EAAK,eAAe,yBAAyBqlD,CAAS;AAE1D;;;;;;AChRO,SAASC,GACdhsB,GACAisB,IAA4B,IAC5Bn9C,IAAoB,IACd;AACN,QAAMi3B,IAAQ/F,EAAM,MAAM;AAC1B,MAAI+F,EAAM,SAAS,EAAG;AAEtB,QAAMmmB,IAAgB;AACtB,MAAIC,IAAa,IACbC,IAAY;AAEhB,SAAOD,KAAcC,IAAYF,KAAe;AAC9C,IAAAC,IAAa,IACbC;AAEA,aAASzoD,IAAI,GAAGA,IAAIoiC,EAAM,QAAQpiC;AAChC,eAAS2R,IAAI3R,IAAI,GAAG2R,IAAIywB,EAAM,QAAQzwB,KAAK;AACzC,cAAMpL,IAAI67B,EAAMpiC,CAAC,GACXsH,IAAI86B,EAAMzwB,CAAC,GAEXuR,IAAK3c,EAAE,QAAQ,KAAK,GACpB4c,IAAK5c,EAAE,QAAQ,KAAK,GACpBktB,IAAKltB,EAAE,QAAQ,SAAS,KACxBmiD,IAAKniD,EAAE,QAAQ,UAAU,IAEzBk5B,IAAKn4B,EAAE,QAAQ,KAAK,GACpB4Z,IAAK5Z,EAAE,QAAQ,KAAK,GACpBqhD,IAAKrhD,EAAE,QAAQ,SAAS,KACxBshD,IAAKthD,EAAE,QAAQ,UAAU,IAGzBuhD,IAAW3lC,IAAKuc,IAAKkpB,IAAKx9C,KAAa+X,IAAKuQ,IAAKtoB,IAAYs0B,GAC7DqpB,IAAW3lC,IAAKjC,IAAK0nC,IAAKz9C,KAAagY,IAAKulC,IAAKv9C,IAAY+V;AAEnE,YAAI2nC,KAAYC,GAAU;AACxB,UAAAN,IAAa;AAGb,gBAAM77C,IAAMuW,IAAKuQ,IAAK,KAAMgM,IAAKkpB,IAAK,IAChC/7C,IAAMuW,IAAKulC,IAAK,KAAMxnC,IAAK0nC,IAAK,IAChC5oB,IAAO,KAAK,KAAKrzB,IAAKA,IAAKC,IAAKA,CAAE,KAAK,GAEvCm8C,IAASp8C,IAAKqzB,KAAS70B,IAAY,IACnC69C,IAASp8C,IAAKozB,KAAS70B,IAAY;AAEzC,UAAA5E,EAAE,SAAS2c,IAAK6lC,GAAO5lC,IAAK6lC,CAAK,GACjC1hD,EAAE,SAASm4B,IAAKspB,GAAO7nC,IAAK8nC,CAAK;AAAA,QACnC;AAAA,MACF;AAAA,EAEJ;AAEA,MAAIV,GAAkB;AAEpB,UAAM97C,IAAK41B,EAAM,OAAO,CAAC6mB,GAAar4C,MAAWq4C,KAAOr4C,EAAE,QAAQ,KAAK,IAAI,CAAC,IAAIwxB,EAAM,QAChF31B,IAAK21B,EAAM,OAAO,CAAC6mB,GAAar4C,MAAWq4C,KAAOr4C,EAAE,QAAQ,KAAK,IAAI,CAAC,IAAIwxB,EAAM;AAEtF,eAAWr/B,KAAQq/B,GAAO;AACxB,YAAM/Q,IAAKtuB,EAAK,QAAQ,KAAK,GACvBuuB,IAAKvuB,EAAK,QAAQ,KAAK,GACvB4J,IAAKH,IAAK6kB,GACVzkB,IAAKH,IAAK6kB;AAChB,MAAAvuB,EAAK,SAASsuB,IAAK1kB,IAAK,MAAM2kB,IAAK1kB,IAAK,IAAI;AAAA,IAC9C;AAAA,EACF;AAEA,UAAQ;AAAA,IACN;AAAA,IACA67C;AAAA,IACA;AAAA,EAAA;AAEJ;AAUO,SAASS,GACd7sB,GACAwgB,GACA5mC,GACAkzC,IAAuB,IACjB;AACN,QAAM/wC,IAAW+wC,IAAc,IAAI;AACnC,MAAIC,IAAY;AAEhB,aAAWvtC,KAAQghC,GAAO;AACxB,UAAM95C,IAAOs5B,EAAM,MAAM,IAAIxgB,EAAK,EAAE;AACpC,IAAI9Y,IACFA,EAAK,SAAS8Y,EAAK,GAAGA,EAAK,GAAG,MAAM;AAClC,MAAAutC,KACIA,KAAavM,EAAM,UAAU5mC,KAC/BA,EAAA;AAAA,IAEJ,GAAG,QAAWmC,CAAQ,IAEtBgxC;AAAA,EAEJ;AAEA,EAAIvM,EAAM,WAAW,KAAK5mC,KACxBA,EAAA;AAEJ;AAMO,SAASozC,GAAchtB,GAA0B;AACtD,SAAOA,EAAM,MAAM,SAAS,IAAI,CAACt5B,OAAe;AAAA,IAC9C,IAAIA,EAAK;AAAA,IACT,GAAGA,EAAK,QAAQ,KAAK;AAAA,IACrB,GAAGA,EAAK,QAAQ,KAAK;AAAA,EAAA,EACrB;AACJ;;;;;;;AC9HO,MAAMumD,GAAW;AAAA,EAQtB,YAAYjtB,GAAYlrB,IAA6B,IAAI;AALzD,SAAQ,YAAgC,MACxC,KAAQ,SAAkC,MAC1C,KAAQ,QAA4B,MACpC,KAAQ,cAAqD,MAG3D,KAAK,QAAQkrB,GACb,KAAK,UAAU;AAAA,MACb,SAAS;AAAA,MACT,UAAU;AAAA,MACV,SAAS;AAAA,MACT,SAAS;AAAA,MACT,GAAGlrB;AAAA,IAAA,GAGD,KAAK,QAAQ,WACf,KAAK,OAAA;AAAA,EAET;AAAA;AAAA,EAGO,OAAa;AAClB,IAAK,KAAK,aACR,KAAK,OAAA,GAEH,KAAK,cACP,KAAK,UAAU,MAAM,UAAU;AAAA,EAEnC;AAAA;AAAA,EAGO,OAAa;AAClB,IAAI,KAAK,cACP,KAAK,UAAU,MAAM,UAAU;AAAA,EAEnC;AAAA;AAAA,EAGO,UAAgB;AAErB,IAAI,KAAK,gBAAgB,SACvB,cAAc,KAAK,WAAW,GAC9B,KAAK,cAAc,OAEjB,KAAK,cACP,KAAK,UAAU,OAAA,GACf,KAAK,YAAY,MACjB,KAAK,SAAS,MACd,KAAK,QAAQ;AAAA,EAEjB;AAAA;AAAA,EAGO,SAAe;AACpB,QAAI,CAAC,KAAK,UAAU,CAAC,KAAK,MAAO;AACjC,UAAMxB,IAAO,KAAK,MAAM,UAAA,KAAe;AACvC,SAAK,OAAO,QAAQ,OAAOA,CAAI,GAC/B,KAAK,MAAM,cAAc,GAAG,KAAK,MAAMA,IAAO,GAAG,CAAC;AAAA,EACpD;AAAA;AAAA,EAIQ,SAAe;AACrB,QAAI,CAAC,KAAK,MAAM,QAAS;AAGzB,SAAK,MAAM,QAAQ,MAAM,WACvB,KAAK,MAAM,QAAQ,MAAM,YAAY,YAEvC,KAAK,YAAY,SAAS,cAAc,KAAK,GAC7C,KAAK,UAAU,YAAY;AAG3B,UAAM45C,IAAyC;AAAA,MAC7C,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,aAAa;AAAA,MACb,YAAY;AAAA,IAAA;AAGd,SAAK,UAAU,MAAM,UAAU;AAAA;AAAA,QAE3BA,EAAe,KAAK,QAAQ,QAAS,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAc1C,UAAMC,IAAU,SAAS,cAAc,QAAQ;AAC/C,IAAAA,EAAQ,cAAc,KACtBA,EAAQ,MAAM,UACZ,wFACFA,EAAQ,UAAU,MAAM,KAAK,MAAM,UAAA,GACnC,KAAK,UAAU,YAAYA,CAAO,GAGlC,KAAK,SAAS,SAAS,cAAc,OAAO,GAC5C,KAAK,OAAO,OAAO,SACnB,KAAK,OAAO,MAAM,OAAO,KAAK,QAAQ,OAAO,GAC7C,KAAK,OAAO,MAAM,OAAO,KAAK,QAAQ,OAAO,GAC7C,KAAK,OAAO,OAAO,OACnB,KAAK,OAAO,QAAQ,KACpB,KAAK,OAAO,MAAM,UAAU,kCAC5B,KAAK,OAAO,UAAU,MAAM;AAC1B,YAAMzjD,IAAM,WAAW,KAAK,OAAQ,KAAK;AACzC,WAAK,MAAM,OAAOA,CAAG,GACrB,KAAK,OAAA;AAAA,IACP,GACA,KAAK,UAAU,YAAY,KAAK,MAAM;AAGtC,UAAM0jD,IAAS,SAAS,cAAc,QAAQ;AAC9C,IAAAA,EAAO,cAAc,KACrBA,EAAO,MAAM,UACX,wFACFA,EAAO,UAAU,MAAM,KAAK,MAAM,SAAA,GAClC,KAAK,UAAU,YAAYA,CAAM,GAGjC,KAAK,QAAQ,SAAS,cAAc,MAAM,GAC1C,KAAK,MAAM,cAAc,QACzB,KAAK,MAAM,MAAM,UAAU,uCAC3B,KAAK,UAAU,YAAY,KAAK,KAAK;AAMrC,UAAMC,IAAM,SAAS,cAAc,QAAQ;AAC3C,IAAAA,EAAI,cAAc,KAClBA,EAAI,QAAQ,kBACZA,EAAI,aAAa,cAAc,cAAc,GAC7CA,EAAI,MAAM,UACR,sGACFA,EAAI,UAAU,MAAM,KAAK,MAAM,eAAA,GAC/B,KAAK,UAAU,aAAaA,GAAK,KAAK,UAAU,UAAU,GAE1D,KAAK,MAAM,QAAQ,YAAY,KAAK,SAAS,GAG7C,KAAK,cAAc,YAAY,MAAM,KAAK,OAAA,GAAU,GAAG;AAAA,EACzD;AACF;AC3JO,MAAMC,GAAa;AAAA,EAQxB,YAAYttB,GAAY;AANxB,SAAQ,QAA4B,CAAA,GACpC,KAAQ,cAAsB,IAC9B,KAAQ,WAAoB,IAE5B,KAAO,YAAoB,KAsN3B,KAAQ,WAA0B,MAnNhC,KAAK,QAAQA;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,cAAcuD,GAEE;AACrB,QAAIwC,IAAQ,KAAK,MAAM,MAAM;AAG7B,QAAIxC,GAAM,SAAS;AACjB,YAAMlC,IAAM,IAAI,IAAIkC,EAAK,OAAO;AAChC,MAAAwC,IAAQA,EAAM,OAAO,CAACxxB,MAAW8sB,EAAI,IAAI9sB,EAAE,EAAE,CAAC;AAAA,IAChD;AAGA,WAAAwxB,EAAM,KAAK,CAAC77B,GAAQe,MAAW;AAC7B,YAAMsiD,IAAKrjD,EAAE,QAAQ,oBACfsjD,IAAKviD,EAAE,QAAQ;AACrB,UAAIsiD,MAAO,UAAaC,MAAO,eAAkBD,IAAKC;AAGtD,YAAMj9C,KAAMrG,EAAE,QAAQ,KAAK,MAAMe,EAAE,QAAQ,KAAK;AAChD,aAAI,KAAK,IAAIsF,CAAE,IAAI,KAAWA,KACtBrG,EAAE,QAAQ,KAAK,MAAMe,EAAE,QAAQ,KAAK;AAAA,IAC9C,CAAC,GAED,KAAK,QAAQ86B,EAAM,IAAI,CAACr/B,GAAWsS,OAAmB;AAAA,MACpD,QAAQtS,EAAK;AAAA,MACb,OAAAsS;AAAA,IAAA,EACA,GAEK,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,4BAAiC;AAEtC,UAAM+sB,KADa,KAAK,MAAM,OAAO,YAAY,CAAA,GAC/B,OAAO,CAACxxB,MAAM,CAACA,EAAE,SAAS,UAAU;AAGtD,QAAI4F,IAAO,OACPC,IAAO,OACPH,IAAO,QACPC,IAAO;AACX,IAAA6rB,EAAM,QAAQ,CAACxxB,MAAM;AACnB,YAAM5P,IAAI4P,EAAE,WAAW,CAAA;AACvB,MAAA4F,IAAO,KAAK,IAAIA,GAAMxV,EAAE,KAAK,CAAC,GAC9ByV,IAAO,KAAK,IAAIA,GAAMzV,EAAE,KAAK,CAAC,GAC9BsV,IAAO,KAAK,IAAIA,IAAOtV,EAAE,KAAK,MAAMA,EAAE,SAAS,EAAE,GACjDuV,IAAO,KAAK,IAAIA,IAAOvV,EAAE,KAAK,MAAMA,EAAE,UAAU,EAAE;AAAA,IACpD,CAAC,GACI,SAASwV,CAAI,MAChBA,IAAO,GACPC,IAAO,GACPH,IAAO,GACPC,IAAO;AAET,UAAMY,IAAS,EAAE,MAAMX,GAAM,KAAKC,GAAM,OAAOH,IAAOE,GAAM,QAAQD,IAAOE,EAAA,GAErEqzC,IAAO,IAAI,IAAiB1nB,EAAM,IAAI,CAACxxB,MAAM,CAACA,EAAE,IAAIA,CAAC,CAAC,CAAC,GACvDm5C,IAAa,CAAChnD,OACjBA,EAAK,eAAe,gBAAgB,CAAA,GAClC,IAAI,CAACwD,MAAWA,EAAE,OAAO,EACzB,OAAO,CAAC2M,MAAe42C,EAAK,IAAI52C,CAAE,CAAC,GAClC82C,IAAe,CAACjnD,MACpBq/B,EAAM;AAAA,MAAK,CAAC,OACT,EAAE,eAAe,gBAAgB,CAAA,GAAI,KAAK,CAAC77B,MAAWA,EAAE,YAAYxD,EAAK,EAAE;AAAA,IAAA,GAG1EknD,wBAAgB,IAAA,GAChBC,IAAc,CAACnnD,MAAmB;AACtC,UAAIknD,EAAU,IAAIlnD,EAAK,EAAE,EAAG,QAAO;AACnC,MAAAknD,EAAU,IAAIlnD,EAAK,EAAE;AACrB,YAAM/B,IAAI+B,EAAK,WAAW,CAAA,GACpB+P,IAAWi3C,EAAWhnD,CAAI,EAC7B,IAAI,CAACmQ,MAAO42C,EAAK,IAAI52C,CAAE,CAAC,EACxB,OAAO,OAAO;AACjB,aAAO;AAAA,QACL,QAAQnQ,EAAK;AAAA,QACb,SAAS;AAAA,UACP,UAAU,KAAK,KAAK/B,EAAE,QAAQ,iBAAiB,CAAC;AAAA,UAChD,MAAM;AAAA,YACJ,GAAG,SAASA,EAAE,KAAK,KAAKmW,EAAO,MAAM,QAAQ,CAAC,CAAC;AAAA,YAC/C,GAAG,SAASnW,EAAE,KAAK,KAAKmW,EAAO,KAAK,QAAQ,CAAC,CAAC;AAAA,YAC9C,OAAO,QAAQnW,EAAE,SAAS,GAAG,QAAQ,CAAC,CAAC;AAAA,YACvC,QAAQ,QAAQA,EAAE,UAAU,GAAG,QAAQ,CAAC,CAAC;AAAA,UAAA;AAAA,QAC3C;AAAA,QAEF,aAAaA,EAAE,QAAQA,EAAE,eAAe;AAAA,QACxC,OAAOA,EAAE;AAAA,QACT,uBAAuB8R,EAAS;AAAA,QAChC,eAAeA,EAAS,IAAIo3C,CAAW,EAAE,OAAO,OAAO;AAAA,MAAA;AAAA,IAE3D,GAEMC,IAAY/nB,EAAM,OAAO,CAACxxB,MAAM,CAACo5C,EAAap5C,CAAC,CAAC;AACtD,WAAO;AAAA,MACL,oBAAoB,KAAK,KAAKuG,EAAO,MAAM;AAAA,MAC3C,mBAAmB,KAAK,KAAKA,EAAO,KAAK;AAAA,MACzC,OAAOgzC,EAAU,IAAID,CAAW,EAAE,OAAO,OAAO;AAAA,IAAA;AAAA,EAEpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,aAAaE,GAAuC;AACzD,UAAMC,IAAa,KAAK,MAAM,OAAO,YAAY,CAAA,GAC3CC,IAAS,IAAI,IAAID,EAAI,IAAI,CAACz5C,MAAMA,EAAE,EAAE,CAAC,GACrC25C,wBAAW,IAAA,GACXC,IAAoB,CAAA;AAC1B,YAACJ,KAAW,CAAA,GAAI,QAAQ,CAACl3C,MAAO;AAC9B,MAAIo3C,EAAO,IAAIp3C,CAAE,KAAK,CAACq3C,EAAK,IAAIr3C,CAAE,MAChCq3C,EAAK,IAAIr3C,CAAE,GACXs3C,EAAQ,KAAKt3C,CAAE;AAAA,IAEnB,CAAC,GAED,KAAK,cAAA,EAAgB,QAAQ,CAAC3S,MAAM;AAClC,MAAKgqD,EAAK,IAAIhqD,EAAE,MAAM,MACpBgqD,EAAK,IAAIhqD,EAAE,MAAM,GACjBiqD,EAAQ,KAAKjqD,EAAE,MAAM;AAAA,IAEzB,CAAC,GACD,KAAK,QAAQiqD,EAAQ,IAAI,CAACrM,GAAQ9oC,OAAW,EAAE,QAAA8oC,GAAQ,OAAA9oC,EAAA,EAAQ,GAC/D,KAAK,cAAc,IACZ,KAAK;AAAA,EACd;AAAA;AAAA,EAGO,QAAc;AACnB,IAAI,KAAK,MAAM,WAAW,KACxB,KAAK,cAAA,GAEP,KAAK,WAAW,IAChB,KAAK,cAAc,IACnB,KAAK,KAAA;AAAA,EACP;AAAA;AAAA,EAGO,OAAa;AAClB,SAAK,WAAW,IAChB,KAAK,cAAc;AAAA,EACrB;AAAA;AAAA,EAGO,OAAgB;AACrB,WAAI,KAAK,eAAe,KAAK,MAAM,SAAS,IAAU,MACtD,KAAK,eACL,KAAK,SAAS,KAAK,WAAW,GACvB;AAAA,EACT;AAAA;AAAA,EAGO,WAAoB;AACzB,WAAI,KAAK,eAAe,IAAU,MAClC,KAAK,eACL,KAAK,SAAS,KAAK,WAAW,GACvB;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,SAASA,GAAe+C,IAAmB,KAAW;AAC3D,QAAI/C,IAAQ,KAAKA,KAAS,KAAK,MAAM,OAAQ;AAE7C,SAAK,cAAcA;AACnB,UAAMuC,IAAO,KAAK,MAAMvC,CAAK,GACvBtS,IAAY,KAAK,MAAM,MAAM,IAAI6U,EAAK,MAAM;AAClD,QAAK7U;AAML,UAAI;AACF,cAAM,IAAIA,EAAK,WAAW,CAAA,GACpBsuB,KAAM,EAAE,KAAK,MAAM,EAAE,SAAS,KAAK,GACnCC,KAAM,EAAE,KAAK,MAAM,EAAE,UAAU,KAAK,GAGpCqtB,IADU,KAAK,MAAc,OACjB,QAAA,GACZ8L,IAAM,KAAK,MAAc,SAAS,eAAe,GACjD3D,IAAMnI,EAAG,QAAQ8L,IAAM,KAAK,WAC5B1D,IAAMpI,EAAG,SAAS8L,IAAM,KAAK,WAC7BxyC,IAAS,EAAE,GAAGoZ,IAAKy1B,IAAK,GAAG,GAAGx1B,IAAKy1B,IAAK,GAAG,OAAOD,GAAI,QAAQC,EAAA;AACpE,aAAK;AAAA,UACH,EAAE,GAAGpI,EAAG,GAAG,GAAGA,EAAG,GAAG,OAAOA,EAAG,OAAO,QAAQA,EAAG,OAAA;AAAA,UAChD1mC;AAAA,UACAG;AAAA,QAAA;AAAA,MAEJ,QAAQ;AAAA,MAER;AAAA,EAGF;AAAA;AAAA,EAKQ,eACNzC,GACAC,GACAwC,GACM;AACN,UAAMk/B,IAAU,KAAK,MAAc,QAC7BoT,IAAM,CAACppD,GAAWC,GAAW8b,GAAWhV,MAAc;AAC1D,UAAI;AACF,QAAAivC,EAAO,QAAQh2C,GAAGC,GAAG8b,GAAGhV,CAAC;AAAA,MAC3B,QAAQ;AAAA,MAER;AAAA,IACF;AACA,QAAI,KAAK,YAAY,MAAM;AACzB,UAAI;AACF,6BAAqB,KAAK,QAAQ;AAAA,MACpC,QAAQ;AAAA,MAER;AACA,WAAK,WAAW;AAAA,IAClB;AACA,QAAI,CAAC+P,KAAYA,KAAY,KAAK,OAAO,wBAA0B,KAAa;AAC9E,MAAAsyC,EAAI90C,EAAG,GAAGA,EAAG,GAAGA,EAAG,OAAOA,EAAG,MAAM;AACnC;AAAA,IACF;AACA,UAAM8rC,IAAO,CAACx7C,MACZA,IAAI,MAAM,IAAIA,IAAIA,IAAI,IAAI,KAAK,IAAI,KAAKA,IAAI,GAAG,CAAC,IAAI;AACtD,QAAIy7C,IAAyB;AAC7B,UAAMC,IAAO,CAACllC,MAAgB;AAC5B,MAAIilC,MAAY,SAAMA,IAAUjlC;AAChC,YAAMhV,IAAI,KAAK,IAAI,IAAIgV,IAAMilC,KAAWvpC,CAAQ,GAC1C9L,IAAIo1C,EAAKh6C,CAAC;AAChB,MAAAgjD;AAAA,QACE/0C,EAAK,KAAKC,EAAG,IAAID,EAAK,KAAKrJ;AAAA,QAC3BqJ,EAAK,KAAKC,EAAG,IAAID,EAAK,KAAKrJ;AAAA,QAC3BqJ,EAAK,SAASC,EAAG,QAAQD,EAAK,SAASrJ;AAAA,QACvCqJ,EAAK,UAAUC,EAAG,SAASD,EAAK,UAAUrJ;AAAA,MAAA,GAExC5E,IAAI,IAAG,KAAK,WAAW,sBAAsBk6C,CAAI,SAC3C,WAAW;AAAA,IACvB;AACA,SAAK,WAAW,sBAAsBA,CAAI;AAAA,EAC5C;AAAA;AAAA,EAGO,iBAAyB;AAC9B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGO,gBAAwB;AAC7B,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA;AAAA,EAGO,eAAwB;AAC7B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGO,UAAgB;AACrB,SAAK,KAAA,GACL,KAAK,QAAQ,CAAA,GACb,KAAK,cAAc,IAClB,KAAa,QAAQ;AAAA,EACxB;AACF;ACrIO,MAAM+I,KAAN,MAAMA,GAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiFjB,YAAYhqD,GAA+BwQ,IAAwB,IAAI;AAErE,QA1DF,KAAQ,gBAAwB,CAAA,GAChC,KAAQ,oBAAyB,MAOjC,KAAQ,iBAAgC,MACxC,KAAQ,wBAA+D,MACvE,KAAQ,aAAsB,IAC9B,KAAQ,kBAA2B,IACnC,KAAQ,qBAA8B,IACtC,KAAQ,gBAAyB,IACjC,KAAQ,aAA6B,CAAA,GACrC,KAAQ,qBAA2D,MACnE,KAAQ,yBAA+D,MACvE,KAAQ,uBAA6D,MACrE,KAAQ,cAAkC,MAC1C,KAAQ,kBAAyC,MAuC3C,OAAOxQ,KAAY,UAAU;AAC/B,YAAMiqD,IAAQ,SAAS,cAAcjqD,CAAO;AAC5C,UAAI,CAACiqD;AACH,cAAM,IAAI,MAAM,0BAA0BjqD,CAAO,aAAa;AAEhE,WAAK,UAAUiqD;AAAA,IACjB;AACE,WAAK,UAAUjqD;AAIjB,QAAI,OAAO,SAAW,KAAa;AACjC,YAAM0c,IAAI;AACV,MAAAA,EAAE,sBAAsBA,EAAE,uBAAuB,CAAA,GACjDA,EAAE,oBAAoB,KAAK,IAAI;AAAA,IACjC;AAGA,SAAK,UAAU;AAAA,MACb,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,MACV,aAAa;AAAA,MACb,4BAA4B;AAAA,MAC5B,UAAU;AAAA,QACR,eAAe;AAAA,QACf,gBAAgB;AAAA,QAChB,UAAU;AAAA,QACV,eAAe;AAAA,QACf,iBAAiB;AAAA,MAAA;AAAA,MAEnB,gBAAgB;AAAA,QACd,iBAAiB;AAAA,QACjB,2BAA2B;AAAA,QAC3B,wBAAwB;AAAA,QACxB,0BAA0B,CAAA;AAAA,QAC1B,4BAA4B;AAAA,QAC5B,iBAAiB;AAAA,QACjB,gBAAgB;AAAA,QAChB,kBAAkB;AAAA,QAClB,qBAAqB;AAAA,MAAA;AAAA,MAEvB,kBAAkB;AAAA,MAClB,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,4CAA4C;AAAA,MAC5C,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,MAAM,CAAA;AAAA,MACN,kBAAkB;AAAA,MAClB,gBAAgB;AAAA,MAChB,YAAY;AAAA,MACZ,IAAI,CAAA;AAAA,MACJ,SAAS;AAAA,QACP,SAAS;AAAA,QACT,SAAS;AAAA,QACT,WAAW;AAAA,QACX,WAAW;AAAA;AAAA,QACX,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,SAAS;AAAA,MAAA;AAAA,MAEX,GAAGlM;AAAA,IAAA,GAGL,KAAK,KAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAlGA,IAAW,UAGT;AACA,WAAO;AAAA,MACL,kBAAkBs9B,GAAA;AAAA,MAClB,qBAAqBhB,GAAA;AAAA,IAAuB;AAAA,EAEhD;AAAA,EA4FQ,OAAO;AAEb,SAAK,SAAS/nB,GAAA,EAAM,MAAM,KAAK,OAAO,GAGtC,KAAK,OAAO,KAAK,aAAa,QAAQ,KAAK,GAC3C,KAAK,OAAO,KAAK,aAAa,cAAc,KAAK,QAAQ,QAAQ,gBAAgB,GACjF,KAAK,OAAO,KAAK,aAAa,YAAY,GAAG,GAG7C,KAAK,cAAc,SAAS,cAAc,KAAK,GAC/C,KAAK,YAAY,aAAa,aAAa,QAAQ,GACnD,KAAK,YAAY,aAAa,eAAe,MAAM,GACnD,KAAK,YAAY,MAAM,UACrB,gIACF,KAAK,QAAQ,YAAY,KAAK,WAAW,GAMzC,KAAK,QAAQ,MAAM,WAAW,KAAK,QAAQ,MAAM,YAAY,UACzD,iBAAiB,KAAK,OAAO,EAAE,aAAa,aAC9C,KAAK,QAAQ,MAAM,WAAW;AAEhC,UAAMwW,IAAU,KAAK,OAAO;AAC5B,IAAIA,GAAS,UACXA,EAAQ,MAAM,QAAQ,QACtBA,EAAQ,MAAM,SAAS,QACvBA,EAAQ,MAAM,UAAU,UAE1BA,GAAS,kBAAkB,OAAO,GAClCA,GAAS,kBAAkB,QAAQ,GACnCA,GAAS,eAAe,uBAAuB,gBAAgB;AAK/D,UAAM3tB,IAAO,KAAK,QAAQ,sBAAA;AAC1B,SAAK,QAAQ,WAAW,KAAK,QAAQ,YAAY,CAAA;AAGjD,UAAMs8C,IACJ,KAAK,QAAQ,SAAS,iBAAiB,KAAK,MAAMt8C,EAAK,KAAK,KAAK,KAC7Du8C,IACJ,KAAK,QAAQ,SAAS,kBAAkB,KAAK,MAAMv8C,EAAK,MAAM,KAAK;AACrE,SAAK,QAAQ,SAAS,gBAAgBs8C,GACtC,KAAK,QAAQ,SAAS,iBAAiBC;AAMvC,UAAMC,IAAU,KAAK,QAAQ,SAAS,QAAQ,GACxCC,IAAU,KAAK,QAAQ,SAAS,OAAO;AAC7C,SAAK,OAAO,QAAQD,GAASC,GAASH,GAAIC,CAAE,GAI5C,KAAK,qBAAA,GAGL,KAAK,QAAQ,IAAInO,GAAa,IAAI,GAGlC,KAAK,UAAU,IAAIsC,GAAQ,IAAI,GAG/B,KAAK,oBAAA,GAGL,KAAK,uBAAA,GAGD,KAAK,QAAQ,UAAU,mBACzB,KAAK,yBAAA,GAIP,KAAK,UAAU,IAAIM,GAAQ,MAAM,KAAK,QAAQ,OAAO,GAGrD,KAAK,WAAW,IAAImB,GAAS,MAAM,KAAK,QAAQ,QAAQ,GACpD,KAAK,QAAQ,UAAU,YAEzB,KAAK,qBAAqB,WAAW,MAAM;AACzC,MAAK,KAAK,cAAY,KAAK,SAAS,OAAA;AAAA,IACtC,GAAG,GAAG,IAKR,KAAK,WAAW,IAAI+B,GAAS,MAAM;AAAA,MACjC,SAAS,KAAK,QAAQ,iBAAiB;AAAA,IAAA,CACxC,GACD,KAAK,SAAS,OAAO,EAAI,GAGzB,KAAK,iBAAiB,IAAIM,GAAe,MAAM;AAAA,MAC7C,SAAS,KAAK,QAAQ,oBAAoB;AAAA,IAAA,CAC3C,GAGD,KAAK,OAAO,IAAIO,GAAK,MAAM;AAAA,MACzB,SAAS,KAAK,QAAQ,UAAU,YAAY;AAAA,MAC5C,UAAU,KAAK,QAAQ,UAAU,YAAY;AAAA;AAAA,MAE7C,YAAY,KAAK,QAAQ,UAAU,cAAc;AAAA,IAAA,CAClD,GACG,KAAK,QAAQ,UAAU,YACzB,KAAK,KAAK,KAAA,GAIZ,KAAK,WAAW,IAAIG,GAAS,IAAI,GAC7B,KAAK,QAAQ,YAAY,MAC3B,KAAK,SAAS,WAAA,GAIhB,KAAK,cAAc,IAAIgB,GAAY,IAAI,GACnC,KAAK,QAAQ,YAAY,MAC3B,KAAK,YAAY,OAAA,GAInB,KAAK,SAAS,IAAIuB,GAAO,IAAI,GAG7B,KAAK,aAAa,IAAIsD,GAAW,MAAM;AAAA,MACrC,SAAS,KAAK,QAAQ,YAAY;AAAA,IAAA,CACnC,GAGD,KAAK,eAAe,IAAIK,GAAa,IAAI,GAGzC,KAAK,eAAA,GAGD,KAAK,QAAQ,UAAU,oBACzB,KAAK,yBAAyB,WAAW,MAAM;AAC7C,MAAK,KAAK,cAAY,KAAK,qBAAA;AAAA,IAC7B,GAAG,GAAG;AAAA,EAEV;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,UAAgB;AASrB,QARA,KAAK,aAAa,IAEd,KAAK,oBACP,KAAK,gBAAgB,WAAA,GACrB,KAAK,kBAAkB,OAIrB,OAAO,SAAW,KAAa;AACjC,YAAMtsC,IAAI;AACV,MAAI,MAAM,QAAQA,EAAE,mBAAmB,MACrCA,EAAE,sBAAsBA,EAAE,oBAAoB;AAAA,QAC5C,CAAC9c,MAAWA,MAAM;AAAA,MAAA;AAAA,IAGxB;AAGA,IAAI,KAAK,uBAAuB,SAC9B,aAAa,KAAK,kBAAkB,GACpC,KAAK,qBAAqB,OAExB,KAAK,2BAA2B,SAClC,aAAa,KAAK,sBAAsB,GACxC,KAAK,yBAAyB,OAE5B,KAAK,yBAAyB,SAChC,aAAa,KAAK,oBAAoB,GACtC,KAAK,uBAAuB,OAI1B,KAAK,0BAA0B,SACjC,cAAc,KAAK,qBAAqB,GACxC,KAAK,wBAAwB;AAI/B,UAAM0qD,IAAe,KAAK,QAAQ,cAAc,oBAAoB;AACpE,IAAIA,KACFA,EAAa,OAAA,GAIf,KAAK,OAAO,IAAI,OAAO,GAGnB,KAAK,WACP,KAAK,QAAQ,QAAA,GAEX,KAAK,YACP,KAAK,SAAS,QAAA,GAEZ,KAAK,cACP,KAAK,WAAW,QAAA,GAEd,KAAK,YACP,KAAK,SAAS,aAAA,GAEZ,KAAK,eACP,KAAK,YAAY,QAAA,GAEf,KAAK,kBACP,KAAK,eAAe,QAAA,GAElB,KAAK,YACP,KAAK,SAAS,MAAA,GAEZ,KAAK,UACP,KAAK,OAAO,WAAA,GAEV,KAAK,gBACP,KAAK,aAAa,KAAA,GAEhB,KAAK,QACP,KAAK,KAAK,KAAA,GAIR,KAAK,SACP,KAAK,MAAM,MAAA,GAIT,KAAK,UACP,KAAK,OAAO,OAAA,GAIV,KAAK,gBACP,KAAK,YAAY,OAAA,GACjB,KAAK,cAAc;AAAA,EAEvB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,SAASC,GAAmB;AACjC,IAAI,KAAK,gBAEP,KAAK,YAAY,cAAc,IAE/B,WAAW,MAAM;AAAE,MAAI,KAAK,gBAAa,KAAK,YAAY,cAAcA;AAAA,IAAK,GAAG,EAAE;AAAA,EAEtF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaO,gBAAgB73C,GAAc1R,IAA4B,IAAU;AACzE,QAAI,KAAK,mBAAmB,KAAK,WAAY;AAC7C,UAAMwpD,IAAK,KAAK,QAAQ,QAAQ;AAChC,QAAI,CAACA,EAAI;AACT,UAAMtoB,IAAoB,EAAE,MAAAxvB,GAAM,MAAA1R,EAAA;AAMlC,QALI,KAAK,QAAQ,aAAUkhC,EAAI,aAAa,KAAK,QAAQ,WAKrD,KAAK,eAAe;AACtB,WAAK,WAAW,KAAKA,CAAG;AACxB;AAAA,IACF;AAEA,QAAIyjB,IAAsB,CAAA;AAC1B,QAAI;AACF,MAAAA,IAAQ,KAAK,QAAQ,iBAAA,KAAsB,CAAA;AAAA,IAC7C,QAAQ;AAAA,IAER;AACA,QAAI;AAIF,MAHoB6E,EAAGtoB,GAAKyjB,CAAK,GAGzB;AAAA,QAAQ,CAACrqB,MACf,QAAQ,KAAK,uDAAuDA,CAAK;AAAA,MAAA;AAAA,IAE7E,SAASA,GAAO;AACd,cAAQ,KAAK,oDAAoDA,CAAK;AAAA,IACxE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASO,UAAU5oB,GAAc1R,IAA4B,IAAU;AACnE,IAAI,KAAK,mBAAmB,KAAK,eAC7B,OAAO,KAAK,QAAQ,QAAS,aAC/B,KAAK,OAAO,KAAK,EAAE,MAAA0R,GAAM,MAAA1R,GAAM,IAE/B,KAAK,gBAAgB0R,GAAM1R,CAAI,GAKjC,KAAK,cAAc0R,CAAI;AAAA,EACzB;AAAA;AAAA,EAGO,cAAcA,GAAoB;AACvC,IAAI,KAAK,YAAY,CAACs3C,GAAM,aAAa,IAAIt3C,CAAI,KAC/C,KAAK,SAAS,OAAA;AAAA,EAElB;AAAA;AAAA,EAkBO,aAAmB;AACxB,SAAK,gBAAgB;AAAA,EACvB;AAAA;AAAA,EAGO,aAAmB;AACxB,SAAK,gBAAgB;AACrB,UAAM+3C,IAAS,KAAK,WAAW,OAAO,CAAC;AACvC,eAAWvoB,KAAOuoB;AAChB,WAAK,gBAAgBvoB,EAAI,MAAMA,EAAI,IAAI;AAAA,EAE3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,sBAA4B;AACjC,UAAMyc,IAAK,KAAK,QAAQ;AACxB,QAAI,CAACA,KAAM,CAAC,KAAK,QAAS;AAE1B,UAAMr5C,IAAK,KAAK;AAEhB,QACEq5C,EAAG,6BACH,MAAM,QAAQA,EAAG,wBAAwB,KACzCA,EAAG,yBAAyB,SAAS,GACrC;AACA,YAAM+L,IAAS/L,EAAG,yBAAyB,KAAK,IAAI;AACpD,MAAAr5C,EAAG,MAAM,kBACPq5C,EAAG,2BAA2B,WAC1B,2BAA2B+L,CAAM,MACjC,mBAAmBA,CAAM;AAAA,IACjC,MAAA,CAAW/L,EAAG,mBACZr5C,EAAG,MAAM,kBAAkB,OAAOq5C,EAAG,eAAe,KAChDA,EAAG,mBAAgBr5C,EAAG,MAAM,iBAAiBq5C,EAAG,mBAEpDr5C,EAAG,MAAM,kBAAkB;AAG7B,IAAIq5C,EAAG,oBACLr5C,EAAG,MAAM,kBAAkBq5C,EAAG;AAAA,EAElC;AAAA;AAAA,EAGO,aAAsB;AAC3B,WAAO,CAAC,CAAC,KAAK,QAAQ,QAAQ,aAAA;AAAA,EAChC;AAAA;AAAA,EAGO,gBAAyB;AAC9B,WAAO,CAAC,CAAC,KAAK,QAAQ,QAAQ,gBAAA;AAAA,EAChC;AAAA;AAAA,EAGO,oBAA6B;AAClC,WAAO,CAAC,CAAC,KAAK,QAAQ,QAAQ,oBAAA;AAAA,EAChC;AAAA;AAAA,EAGO,mBAAyB;AAC9B,SAAK,kBAAkB;AAAA,EACzB;AAAA;AAAA,EAGO,iBAAuB;AAC5B,SAAK,kBAAkB;AAAA,EACzB;AAAA,EAEQ,2BAA2B;AAEjC,UAAMgM,IAAgB,KAAK,QAAQ,SAAS,OACtCC,IAAiB,KAAK,QAAQ,SAAS;AAG7C,IAAK,KAAK,QAAQ,YAChB,KAAK,QAAQ,UAAU,CAAA,IAGzB,KAAK,QAAQ,QAAQ,QAAQ,CAAC3K,MAAa;AACzC,WAAK,wBAAA,GACD0K,KACFA,EAAc1K,CAAG;AAAA,IAErB,GAEA,KAAK,QAAQ,QAAQ,SAAS,CAACjxC,MAAc;AAC3C,WAAK,wBAAA,GACD47C,KACFA,EAAe57C,CAAI;AAAA,IAEvB;AAGA,UAAM67C,IAAmB,KAAK,QAAQ,QAAQ;AAC9C,SAAK,QAAQ,QAAQ,WAAW,CAACre,MAAa;AAC5C,MAAIqe,KACFA,EAAiBre,CAAG;AAEtB,UAAI;AACF,cAAMyT,IAAM,KAAK,OAAA;AACjB,aAAK,UAAU,gBAAgB;AAAA,UAC7B,MAAMA,EAAI;AAAA,UACV,KAAKA,EAAI;AAAA,UACT,UAAU,EAAE,GAAGA,EAAI,GAAG,GAAGA,EAAI,EAAA;AAAA,UAC7B,QAAQ,KAAK,eAAA;AAAA,QAAe,CAC7B;AAAA,MACH,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,uBAAuB;AAG7B,QAAI,CAAE,KAAK,QAAgB,gBAAiB;AAC5C,YAAQ,IAAI,mDAAmD;AAG/D,UAAMqK,IAAe,SAAS,cAAc,KAAK;AACjD,IAAAA,EAAa,KAAK,qBAClBA,EAAa,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAgB7B,KAAK,QAAQ,MAAM,WAAW,KAAK,QAAQ,MAAM,YAAY,YAC7D,KAAK,QAAQ,YAAYA,CAAY,GAErC,QAAQ;AAAA,MACN;AAAA,IAAA,GAEF,QAAQ,IAAI,+BAA+BA,EAAa,MAAM,OAAO,GACrE,QAAQ,IAAI,gCAAgC,KAAK,OAAO,GAGxDA,EAAa,cAAc,0BAG3B,KAAK,wBAAA,GAGL,KAAK,uBAAA;AAAA,EACP;AAAA,EAEQ,yBAAyB;AAC/B,IAAI,KAAK,eACT,QAAQ,IAAI,0CAA0C,GAGtD,KAAK,wBAAwB,YAAY,MAAM;AAC7C,MAAK,KAAK,cAAY,KAAK,wBAAA;AAAA,IAC7B,GAAG,GAAG;AAAA,EACR;AAAA,EAEQ,0BAA0B;AAChC,UAAMA,IAAe,KAAK,QAAQ;AAAA,MAChC;AAAA,IAAA;AAEF,QAAI,CAACA,GAAc;AACjB,cAAQ,IAAI,yDAAyD;AACrE;AAAA,IACF;AAEA,QAAI;AAEF,UAAIrK,IAAM,EAAE,GAAG,GAAG,GAAG,EAAA,GACjBjxC,IAAO;AAEX,UAAI,KAAK,WAAW,KAAK,QAAQ;AAC/B,QAAAixC,IAAM,KAAK,OAAA,GACXjxC,IAAO,KAAK,QAAA,GACZ,QAAQ;AAAA,UACN;AAAA,UACAixC;AAAA,UACA;AAAA,UACAjxC;AAAA,QAAA;AAAA,WAEG;AAEL,cAAM87C,IAAU,KAAK,OAAO,QAAA;AAC5B,QAAA7K,IAAM,EAAE,GAAG6K,EAAQ,GAAG,GAAGA,EAAQ,EAAA,GAEjC97C,KADW,KAAK,QAAQ,sBAAA,EAAwB,SAAS87C,EAAQ,SACrDA,EAAQ,SAAS,GAC7B,QAAQ;AAAA,UACN;AAAA,UACA7K;AAAA,UACA;AAAA,UACAjxC;AAAA,QAAA;AAAA,MAEJ;AAEA,YAAMizB,IAAU,MAAM,KAAK,MAAMge,EAAI,CAAC,CAAC,QAAQ,KAAK;AAAA,QAClDA,EAAI;AAAA,MAAA,CACL,WAAWjxC,EAAK,QAAQ,CAAC,CAAC;AAC3B,MAAAs7C,EAAa,cAAcroB,GAGvB,KAAK,OAAA,IAAW,OAElB,QAAQ,IAAI,wCAAwCA,CAAO;AAAA,IAE/D,SAAS3G,GAAO;AACd,cAAQ,MAAM,4CAA4CA,CAAK,GAC/DgvB,EAAa,cAAc;AAAA,IAC7B;AAAA,EACF;AAAA,EAEQ,iBAAiB;AAAA,EAIzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBO,QAAQ95C,IAAgC,IAAI;AACjD,UAAMpO,IAAO,KAAK,MAAM,IAAIoO,CAAO;AAEnC,gBAAK,uBAAuB,WAAW,MAAM;AAC3C,MAAK,KAAK,cAAY,KAAK,kBAAA,GAC3B,KAAK,SAAS,eAAepO,EAAK,QAAQ,QAAQ,WAAW,EAAE;AAAA,IACjE,GAAG,GAAG,GACN,KAAK,UAAU,eAAe;AAAA,MAC5B,IAAIA,EAAK;AAAA,MACT,aAAa0sC,EAAW1sC,EAAK,OAAO;AAAA,IAAA,CACrC,GACMA;AAAA,EACT;AAAA;AAAA,EAGO,WAAWmQ,GAAY;AAC5B,UAAMnQ,IAAO,KAAK,MAAM,IAAImQ,CAAE,GACxBQ,IAAO3Q,GAAM,SAAS,QAAQ,aAC9B2oD,IAAY,CAAC,CAAC3oD,GAAM,SAAS;AAOnC,QAAIA,KAAQ,KAAK,cAAc,KAAK,CAAC6N,MAAMA,EAAE,OAAOsC,CAAE,GAAG;AACvD,UAAI;AACD,QAAAnQ,EAAa,cAAc,QAAA;AAAA,MAC9B,QAAY;AAAA,MAEZ;AACA,WAAK,gBAAgB,KAAK,cAAc,OAAO,CAAC6N,MAAMA,EAAE,OAAOsC,CAAE;AAAA,IACnE;AACA,UAAMhT,IAAS,KAAK,MAAM,OAAOgT,CAAE;AAEnC,gBAAK,kBAAA,GACL,KAAK,SAAS,iBAAiBQ,CAAI,EAAE,GACjCxT,KACF,KAAK,UAAU,iBAAiB,EAAE,IAAAgT,GAAI,WAAAw4C,GAAW,GAE5CxrD;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,kBAAkB6C,GAAmB;AAC1C,IAAI,KAAK,UAAU,eACjB,KAAK,SAAS,gBAAA;AAAA,EAElB;AAAA;AAAA,EAGO,QAAQmQ,GAAY;AACzB,WAAO,KAAK,MAAM,IAAIA,CAAE;AAAA,EAC1B;AAAA;AAAA,EAGO,cAAsB;AAC3B,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA;AAAA;AAAA,EAIO,cAAmB;AAExB,mBAAQ,IAAI,oDAAoD,GACzD,KAAK;AAAA,EACd;AAAA;AAAA;AAAA,EAIO,mBAAiC;AAEtC,mBAAQ;AAAA,MACN;AAAA,IAAA,GAEK,QAAQ,QAAQ,KAAK,MAAM;AAAA,EACpC;AAAA;AAAA;AAAA,EAIO,gBAAgB;AACrB,SAAK,QAAQ,OAAA;AAAA,EACf;AAAA;AAAA,EAGO,iBAAiB;AACtB,SAAK,QAAQ,QAAA;AAAA,EACf;AAAA;AAAA,EAGO,YAAY;AACjB,SAAK,QAAQ,UAAA;AAAA,EACf;AAAA;AAAA,EAGO,aAAa;AAClB,SAAK,QAAQ,WAAA;AAAA,EACf;AAAA;AAAA,EAGO,aAAa;AAClB,SAAK,QAAQ,WAAA;AAAA,EACf;AAAA;AAAA,EAGO,cAAc;AACnB,SAAK,QAAQ,YAAA;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,IAAIjI,GAAiC;AAC1C,SAAK,QAAQ,IAAIA,CAAK;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,MAAMpC,GAAiC;AAC5C,SAAK,QAAQ,MAAMA,CAAK;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,KAAK2G,GAAe;AACzB,SAAK,QAAQ,KAAKA,CAAK,GACvB,KAAK,SAAS,SAAS,KAAK,MAAMA,IAAQ,GAAG,CAAC,GAAG,GACjD,KAAK,UAAU,UAAU,EAAE,WAAWA,GAAO;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,OAAO+D,GAAgB;AAC5B,SAAK,QAAQ,OAAOA,CAAM;AAAA,EAC5B;AAAA;AAAA,EAGO,SAAS;AACd,SAAK,QAAQ,OAAA;AAAA,EACf;AAAA;AAAA,EAGO,UAAU;AACf,SAAK,QAAQ,QAAA;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,YAAY/D,GAAevE,GAAiC;AACjE,SAAK,QAAQ,YAAYuE,GAAOvE,CAAK;AAAA,EACvC;AAAA;AAAA,EAGO,eAAe;AACpB,SAAK,QAAQ,MAAA;AAAA,EACf;AAAA;AAAA,EAGO,YAAY;AACjB,SAAK,QAAQ,UAAA;AAAA,EACf;AAAA;AAAA,EAGO,WAAW;AAChB,SAAK,QAAQ,SAAA;AAAA,EACf;AAAA;AAAA,EAGO,eAAe;AACpB,SAAK,QAAQ,IAAA;AAAA,EACf;AAAA;AAAA,EAGO,gBAAgB;AACrB,SAAK,QAAQ,OAAA;AAAA,EACf;AAAA;AAAA,EAGO,UAAkB;AACvB,WAAO,KAAK,QAAQ,QAAA;AAAA,EACtB;AAAA;AAAA,EAGO,SAAmC;AACxC,WAAO,KAAK,QAAQ,OAAA;AAAA,EACtB;AAAA;AAAA,EAGO,gBAAgB;AACrB,SAAK,QAAQ,OAAA;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ,uBAA6B;AACnC,QAAI,OAAO,iBAAmB,IAAa;AAC3C,QAAI0gD,IAAQ,GACRC,IAAQ;AACZ,SAAK,kBAAkB,IAAI,eAAe,MAAM;AAC9C,UAAI,KAAK,WAAY;AACrB,YAAMr9C,IAAO,KAAK,QAAQ,sBAAA,GACpBs9C,IAAK,KAAK,IAAI,GAAG,KAAK,MAAMt9C,EAAK,KAAK,CAAC,GACvCu9C,IAAK,KAAK,IAAI,GAAG,KAAK,MAAMv9C,EAAK,MAAM,CAAC;AAC9C,UAAIs9C,MAAOF,KAASG,MAAOF,EAAO;AAElC,YAAMjN,IAAK,KAAK,OAAO,QAAA,GAGjBa,IAAab,EAAG,SAASgN,KAASE;AACxC,MAAAF,IAAQE,GACRD,IAAQE;AAER,YAAMt/C,IAAKmyC,EAAG,IAAIA,EAAG,QAAQ,GACvBlyC,IAAKkyC,EAAG,IAAIA,EAAG,SAAS,GACxBe,IAAOmM,IAAKrM,GACZG,IAAOmM,IAAKtM;AAClB,WAAK,OAAO,QAAQhzC,IAAKkzC,IAAO,GAAGjzC,IAAKkzC,IAAO,GAAGD,GAAMC,CAAI,GAC5D,KAAK,QAAQ,WAAW,KAAK,QAAQ,YAAY,CAAA,GACjD,KAAK,QAAQ,SAAS,gBAAgBkM,GACtC,KAAK,QAAQ,SAAS,iBAAiBC;AAAA,IACzC,CAAC,GACD,KAAK,gBAAgB,QAAQ,KAAK,OAAO;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,iBAML;AACA,UAAMzB,IAAM,KAAK,OAAO,YAAY,CAAA,GAC9B0B,IAAU,KAAK,QAAQ,YAAY,CAAA;AACzC,QAAInrD,IAAQmrD,EAAG,SAASA,EAAG,iBAAiB,KACxClrD,IAASkrD,EAAG,UAAUA,EAAG,kBAAkB,KAC3C9jC,IAAO,GACPD,IAAM,GACNgkC,IAAwC;AAE5C,QAAI3B,EAAI,SAAS,GAAG;AAElB,UAAI7zC,IAAO,OACPC,IAAO,OACPH,IAAO,QACPC,IAAO;AACX,MAAA8zC,EAAI,QAAQ,CAACz5C,MAAW;AACtB,cAAMtP,IAAIsP,EAAE,QAAQ,KAAK,GACnBrP,IAAIqP,EAAE,QAAQ,KAAK,GACnByM,IAAIzM,EAAE,QAAQ,SAAS,GACvBvI,IAAIuI,EAAE,QAAQ,UAAU;AAC9B,QAAA4F,IAAO,KAAK,IAAIA,GAAMlV,IAAI,EAAG,GAC7BmV,IAAO,KAAK,IAAIA,GAAMlV,IAAI,EAAG,GAC7B+U,IAAO,KAAK,IAAIA,GAAMhV,IAAI+b,IAAI,EAAG,GACjC9G,IAAO,KAAK,IAAIA,GAAMhV,IAAI8G,IAAI,EAAG;AAAA,MACnC,CAAC,GACD4f,IAAO,KAAK,IAAIzR,CAAI,GACpBwR,IAAM,KAAK,IAAIvR,CAAI,GACnB7V,IAAQ0V,IAAOE,GACf3V,IAAS0V,IAAOE,GACZ5V,IAASD,MAAOorD,IAAc;AAAA,IACpC;AAEA,WAAO,EAAE,aAAAA,GAAa,OAAAprD,GAAO,QAAAC,GAAQ,MAAAonB,GAAM,KAAAD,EAAA;AAAA,EAC7C;AAAA;AAAA,EAGQ,yBAAyB;AAE/B,SAAK,OAAO,GAAG,SAAS,CAAC3W,MAAe;AACtC,cAAQ;AAAA,QACN;AAAA,QACAA,EAAM;AAAA,QACN;AAAA,QACA,KAAK,OAAO;AAAA,MAAA;AAId,YAAM46C,IACJ56C,EAAM,WAAW,KAAK,OAAO,QAC5BA,EAAM,UAAUA,EAAM,OAAO,YAAY;AAM5C,UADwB,KAAK,IAAA,KAAU,KAAa,yBAAyB,KACvD,KAAK;AACxB,aAAa,wBAAwB;AACtC;AAAA,MACF;AAEA,MAAI46C,KACF,QAAQ,IAAI,mDAAmD,GAE/D,KAAK,iBAAiB,MACtB,KAAK,eAAA,GACL,KAAK,aAAA,GAEL,KAAK,QAAQ,QAAQ,kBAAkB56C,CAAK,KAE5C,QAAQ;AAAA,QACN;AAAA,MAAA;AAAA,IAGN,CAAC,GAQD,KAAK,OAAO,GAAG,YAAY,CAACA,MAAe;AAIzC,WAFEA,EAAM,WAAW,KAAK,OAAO,QAC5BA,EAAM,UAAUA,EAAM,OAAO,YAAY,UAExC,MAAK;AACT,YAAI;AACF,gBAAM66C,IAAQ,KAAK,OAAO,MAAM76C,EAAM,SAASA,EAAM,OAAO,GACtDgM,IAAI,KACJhV,IAAI,IACJtF,IAAO,KAAK,QAAQ;AAAA,YACxB,GAAG,KAAK,MAAMmpD,EAAM,IAAI7uC,IAAI,CAAC;AAAA,YAC7B,GAAG,KAAK,MAAM6uC,EAAM,IAAI7jD,IAAI,CAAC;AAAA,YAC7B,OAAOgV;AAAA,YACP,QAAQhV;AAAA,YACR,MAAM;AAAA,UAAA,CACP;AACD,eAAK,cAAc,CAACtF,CAAI,CAAC;AAAA,QAC3B,QAAY;AAAA,QAEZ;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBO,YAAYq/B,GAAe4gB,IAA0B,IAAO;AAejE,QAdA,QAAQ;AAAA,MACN;AAAA,MACA5gB,EAAM,IAAI,CAACxxB,MAAMA,EAAE,EAAE;AAAA,MACrB;AAAA,MACAoyC;AAAA,IAAA,GAIF,KAAK,aAAA,GAMD5gB,EAAM,WAAW,GAAG;AACtB,YAAM6U,IAAM,KAAK,aAAa7U,EAAM,CAAC,CAAC;AAItC,UAHI,KAAK,kBAAkB6U,MAAQ,KAAK,mBACtC,KAAK,iBAAiB,OAEpBA,KAAOA,MAAQ,KAAK,gBAAgB;AACtC,cAAMkV,IAAU,KAAK,gBAAgBlV,CAAG;AACxC,QAAIkV,EAAQ,SAAS,MAAG/pB,IAAQ+pB;AAAA,MAClC;AAAA,IACF;AAGA,IAAKnJ,KACH,KAAK,eAAA,GAIP5gB,EAAM,QAAQ,CAACr/B,MAAS;AACtB,MAAK,KAAK,cAAc,SAASA,CAAI,MACnC,KAAK,cAAc,KAAKA,CAAI,GAC5BA,EAAK,WAAA;AAAA,IAET,CAAC,GAGD,KAAK,4BAAA;AAGL,UAAMmyC,IAAQ,KAAK,cAAc;AACjC,IAAIA,MAAU,IACZ,KAAK,SAAS,mBAAmB,IACxBA,MAAU,IACnB,KAAK,SAAS,kBAAkB,KAAK,cAAc,CAAC,EAAE,QAAQ,QAAQ,WAAW,EAAE,IAEnF,KAAK,SAAS,GAAGA,CAAK,iBAAiB,GAIrCA,IAAQ,MACV,KAAK,qBAAqB,IAC1B,KAAK,QAAQ,QAAQ,mBAAmB,KAAK,cAAc,OAAO;AAAA,EAEtE;AAAA;AAAA;AAAA,EAIO,8BAA8B;AA2BnC,QA1BA,QAAQ;AAAA,MACN;AAAA,MACA,KAAK,cAAc;AAAA,MACnB;AAAA,IAAA,GAIF,KAAK,MAAM,SAAS,QAAQ,CAACnyC,MAAS;AACpC,MAAIA,EAAK,aAAa,gBACpBA,EAAK,aAAa,QAAA,GAClB,QAAQ,IAAI,8CAA8CA,EAAK,EAAE,IAI/DA,EAAK,iCACPA,EAAK,yBAAA,GACL,QAAQ,IAAI,mDAAmDA,EAAK,EAAE,IAIvEA,EAAa,cAAA;AAAA,IAChB,CAAC,GAGD,KAAK,yBAAA,GAED,KAAK,cAAc,WAAW,GAAG;AAEnC,cAAQ;AAAA,QACN;AAAA,MAAA;AAEF;AAAA,IACF;AAEA,QAAI,KAAK,cAAc,WAAW,GAAG;AAEnC,YAAMqpD,IAAe,KAAK,cAAc,CAAC;AACzC,MAAAA,EAAa,aAAa,OAAA,GAE1BA,EAAa,wBAAA,GAEZA,EAAqB,cAAA,GACtB,QAAQ;AAAA,QACN;AAAA,QACAA,EAAa;AAAA,MAAA;AAAA,IAEjB;AAGE,cAAQ;AAAA,QACN;AAAA,QACA,KAAK,cAAc;AAAA,QACnB;AAAA,MAAA,GAEF,KAAK,wBAAA;AAAA,EAET;AAAA;AAAA;AAAA,EAIO,uBAAuBrpD,GAAY;AAExC,IAAI,KAAK,cAAc,SAASA,CAAI,IAClC,QAAQ;AAAA,MACN;AAAA,MACAA,EAAK;AAAA,MACL;AAAA,IAAA,KAIF,QAAQ;AAAA,MACN;AAAA,MACAA,EAAK;AAAA,MACL;AAAA,IAAA,GAGF,KAAK,YAAY,CAACA,CAAI,GAAG,EAAK;AAAA,EAElC;AAAA;AAAA,EAGO,wBAAwBA,GAAY;AACzC,YAAQ;AAAA,MACN;AAAA,MACAA,EAAK;AAAA,MACL;AAAA,IAAA,GAGEA,EAAK,aAAa,eACpBA,EAAK,aAAa,QAAA,GAIhBA,EAAK,gCACPA,EAAK,yBAAA;AAAA,EAET;AAAA,EAEQ,2BAA2B;AACjC,YAAQ,IAAI,gDAAgD,GAG5D,KAAK,cAAc,QAAQ,CAACA,MAAS;AACnC,MAAAA,EAAK,oBAAA;AAAA,IACP,CAAC,GAGG,KAAK,sBACP,KAAK,kBAAkB,OAAA,GACvB,KAAK,oBAAoB;AAAA,EAE7B;AAAA,EAEQ,0BAA0B;AAChC,YAAQ,IAAI,0DAA0D,GAGlE,KAAK,qBACP,KAAK,kBAAkB,OAAA;AAIzB,UAAMspD,IAAY,KAAK,0BAAA;AAIvB,QACE,CAAC,CAACA,EAAU,GAAGA,EAAU,GAAGA,EAAU,OAAOA,EAAU,MAAM,EAAE;AAAA,MAC7D,OAAO;AAAA,IAAA,KAETA,EAAU,SAAS,KACnBA,EAAU,UAAU;AAEpB;AAIF,SAAK,oBAAoB,KAAK,OAAO,MAAA,GAIrC,KAAK,kBACF,KAAKA,EAAU,OAAOA,EAAU,MAAM,EACtC,KAAKA,EAAU,GAAGA,EAAU,CAAC,EAC7B,KAAK,aAAa,EAClB,OAAO,EAAE,OAAO,WAAW,OAAO,GAAG,WAAW,MAAA,CAAO,EACvD,KAAK,kBAAkB,MAAM,GAKd,KAAK,cAAc,KAAK,CAAC,MAAM,EAAE,QAAQ,QAAQ,KACnD,KAAK,qBAAqBA,CAAS;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWQ,qBAAqBA,GAKpB;AACP,UAAM7rD,IAAI,KAAK;AACf,QAAKA;AAGL,UAAI;AACJ,cAAMgM,IAAK6/C,EAAU,IAAIA,EAAU,QAAQ,GACrC5/C,IAAK4/C,EAAU,IAAIA,EAAU,SAAS,GAEtCC,IAAQD,EAAU,IADT;AAGf,QAAA7rD,EAAE,KAAKgM,GAAI6/C,EAAU,GAAG7/C,GAAI8/C,CAAK,EAC9B,OAAO,EAAE,OAAO,WAAW,OAAO,EAAA,CAAG,EACrC,KAAK,kBAAkB,MAAM;AAChC,cAAMC,IAAO/rD,EACV,OAAO,EAAE,EACT,OAAOgM,GAAI8/C,CAAK,EAChB,KAAK,SAAS,EACd,OAAO,EAAE,OAAO,WAAW,OAAO,GAAG,GAClCE,IAAY,CAAC7mD,MAAc;AAC/B,gBAAMM,IAAKsmD,EAAK;AAChB,UAAItmD,GAAI,UAAOA,EAAG,MAAM,SAASN;AAAA,QACnC;AACA,QAAA6mD,EAAU,MAAM,GAChBD,EAAK,KAAK,kBAAkB,KAAK;AAEjC,YAAIE,IAAW,IACXC,IAAa,GACbC,IAAQ,EAAE,GAAG,GAAG,GAAG,EAAA,GACnB3N,IAAoE,CAAA;AAExE,cAAM4N,IAAc,MAAM;AACxB,gBAAMrtD,IAAKiB,EAAE,KAAmC,aAAA;AAChD,iBAAKjB,IACE,EAAE,GAAGA,EAAE,IAAIiN,IAAKjN,EAAE,IAAIkN,IAAKlN,EAAE,GAAG,GAAGA,EAAE,IAAIiN,IAAKjN,EAAE,IAAIkN,IAAKlN,EAAE,EAAA,IADnD,EAAE,GAAG,GAAG,GAAG,EAAA;AAAA,QAE5B,GAEM64C,IAAS,CAAC9rC,MAAoB;AAClC,cAAI,CAACmgD,EAAU;AAEf,cAAII,KADQ,KAAK,MAAMvgD,EAAE,UAAUqgD,EAAM,GAAGrgD,EAAE,UAAUqgD,EAAM,CAAC,IACxCD,KAAc,MAAO,KAAK;AACjD,UAAIpgD,EAAE,aAAUugD,IAAW,KAAK,MAAMA,IAAW,EAAE,IAAI;AACvD,gBAAMpuB,IAAOouB,IAAW,KAAK,KAAM,KAC7B7+C,IAAM,KAAK,IAAIywB,CAAG,GAClBv2B,IAAM,KAAK,IAAIu2B,CAAG;AACxB,UAAAugB,EAAS,QAAQ,CAACz+C,MAAM;AACtB,kBAAMoM,IAAKpM,EAAE,KAAKiM,GACZI,IAAKrM,EAAE,KAAKkM,GACZqgD,IAAMtgD,IAAKG,IAAKqB,IAAMpB,IAAK1E,GAC3B6kD,IAAMtgD,IAAKE,IAAKzE,IAAM0E,IAAKoB,GAC3BqP,IAAI9c,EAAE,KAAK,QAAQ,SAAS,GAC5B8H,IAAI9H,EAAE,KAAK,QAAQ,UAAU,GAC7BysD,IAAOzsD,EAAE,KAAK,QAAQ,SAC1BA,EAAE,KAAK,QAAQ,UAAW,CAAA;AAC5B,YAAAysD,EAAI,gBAAgBzsD,EAAE,QAAQssD,GAC9BtsD,EAAE,KAAK,SAASusD,IAAMzvC,IAAI,GAAG0vC,IAAM1kD,IAAI,CAAC;AAAA,UAC1C,CAAC;AAAA,QACH,GAEM0wC,IAAO,MAAM;AACjB,UAAK0T,MACLA,IAAW,IACXD,EAAU,MAAM,GAChB,OAAO,oBAAoB,eAAepU,CAAM,GAChD,OAAO,oBAAoB,aAAaW,CAAI,GAC5C,KAAK,UAAU,eAAe;AAAA,YAC5B,aAAa,KAAK,cAAc,IAAI,CAACnoC,MAAM6+B,EAAW7+B,EAAE,OAAO,CAAC;AAAA,UAAA,CACjE,GAED,KAAK,4BAAA;AAAA,QACP;AAEA,QAAA27C,EAAK,GAAG,eAAe,CAACjgD,MAAW;AACjC,UAAAA,EAAE,iBAAA,GACFA,EAAE,kBAAA,GACFmgD,IAAW,IACXE,IAAQC,EAAA,GACRF,IAAa,KAAK,MAAMpgD,EAAE,UAAUqgD,EAAM,GAAGrgD,EAAE,UAAUqgD,EAAM,CAAC,GAChE3N,IAAW,KAAK,cAAc,IAAI,CAACpuC,OAAO;AAAA,YACxC,MAAMA;AAAA,YACN,KAAKA,EAAE,QAAQ,KAAK,MAAMA,EAAE,QAAQ,SAAS,KAAK;AAAA,YAClD,KAAKA,EAAE,QAAQ,KAAK,MAAMA,EAAE,QAAQ,UAAU,KAAK;AAAA,YACnD,OAAOA,EAAE,QAAQ,QAAQ,iBAAiB;AAAA,UAAA,EAC1C,GACF47C,EAAU,UAAU,GACpB,OAAO,iBAAiB,eAAepU,CAAM,GAC7C,OAAO,iBAAiB,aAAaW,CAAI;AAAA,QAC3C,CAAC;AAAA,MACD,QAAY;AAAA,MAEZ;AAAA,EACF;AAAA,EAEQ,4BAA4B;AAClC,QAAI,KAAK,cAAc,WAAW;AAChC,aAAO,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,KAAK,QAAQ,IAAA;AAG3C,QAAIviC,IAAO,OACTC,IAAO,OACPH,IAAO,QACPC,IAAO;AAST,gBAAK,cAAc,QAAQ,CAACxT,MAAS;AACnC,YAAMo0C,IAAK,KAAK,cAAcp0C,CAAI;AAClC,MAAAyT,IAAO,KAAK,IAAIA,GAAM2gC,EAAG,IAAI,GAC7B1gC,IAAO,KAAK,IAAIA,GAAM0gC,EAAG,IAAI,GAC7B7gC,IAAO,KAAK,IAAIA,GAAM6gC,EAAG,IAAI,GAC7B5gC,IAAO,KAAK,IAAIA,GAAM4gC,EAAG,IAAI;AAAA,IAC/B,CAAC,GAEM;AAAA,MACL,GAAG3gC;AAAA,MACH,GAAGC;AAAA,MACH,OAAOH,IAAOE;AAAA,MACd,QAAQD,IAAOE;AAAA,IAAA;AAAA,EAEnB;AAAA,EAEQ,kBACNw2C,GACAhiD,GACAoK,GACAqB,GACA;AAEA,IAAAu2C,EACG,OAAO,CAAC,EACR,KAAK,SAAS,EACd,OAAO,SAAS,EAChB,KAAK,gBAAgB,CAAC;AAAA,EAC3B;AAAA,EAEQ,kBACNxhC,GACAxgB,GACAoK,GACAqB,GACA;AAEA,IAAA+U,EAAO,OAAOxgB,EAAM,CAAC,GAAGA,EAAM,CAAC,CAAC;AAAA,EAClC;AAAA,EAEQ,kBAAkBoG,GAAY;AACpC,YAAQ,IAAI,uCAAuCA,CAAK;AAExD,UAAM,EAAE,KAAAvQ,MAAQuQ,EAAM,QAChB67C,IAAoB,KAAK,0BAAA,GAGzBxhD,IAAS5K,EAAI,QAAQosD,EAAkB,OACvCvhD,IAAS7K,EAAI,SAASosD,EAAkB;AAG9C,SAAK,cAAc,QAAQ,CAACnqD,MAAS;AACnC,YAAMoqD,IAAWpqD,EAAK,SAAS,KAAA,GAGzBqqD,KAAaD,EAAS,IAAID,EAAkB,KAAKxhD,GACjD2hD,KAAaF,EAAS,IAAID,EAAkB,KAAKvhD,GACjDk4B,IAAWspB,EAAS,QAAQzhD,GAC5Bo4B,IAAYqpB,EAAS,SAASxhD;AAGpC,MAAA5I,EAAK,QAAQ8gC,GAAUC,CAAS,GAChC/gC,EAAK,SAASjC,EAAI,IAAIssD,GAAWtsD,EAAI,IAAIusD,CAAS;AAAA,IACpD,CAAC;AAAA,EACH;AAAA,EAEQ,kBAAkBh8C,GAAY;AACpC,YAAQ,IAAI,uCAAuCA,CAAK;AAExD,UAAM,EAAE,OAAAkD,MAAUlD,EAAM,QAClBg7C,IAAY,KAAK,0BAAA;AACP,IAAAA,EAAU,IAAIA,EAAU,QAAQ,GAChCA,EAAU,IAAIA,EAAU,SAAS,GAGjD,KAAK,cAAc,QAAQ,CAACtpD,MAAS;AACnC,YAAMuqD,IAAkBvqD,EAAK,YAAA;AAC7B,MAAAA,EAAK,YAAYuqD,IAAkB/4C,CAAK;AAAA,IAI1C,CAAC;AAAA,EACH;AAAA;AAAA,EAGO,WAAWxR,GAAY;AAE5B,SAAK,YAAY,CAACA,CAAI,GAAG,EAAK;AAAA,EAChC;AAAA;AAAA,EAGO,aAAaA,GAAY;AAC9B,IAAI,KAAK,cAAc,SAASA,CAAI,MAClC,QAAQ,IAAI,qCAAqCA,EAAK,EAAE,GACxD,KAAK,gBAAgB,KAAK,cAAc,OAAO,CAAC6N,MAAMA,MAAM7N,CAAI,GAChEA,EAAK,aAAA,GAGD,KAAK,cAAc,WAAW,IAChC,KAAK,yBAAA,IAEL,KAAK,4BAAA;AAAA,EAGX;AAAA;AAAA;AAAA,EAIO,eAAqB;AAC1B,QAAI,KAAK,gBAAgB;AACvB,UAAI;AACF,aAAK,eAAe,OAAA;AAAA,MACtB,QAAY;AAAA,MAEZ;AACA,WAAK,iBAAiB;AAAA,IACxB;AACA,QAAI,KAAK,wBAAwB;AAC/B,UAAI;AAED,aAAK,uBAA+B,iBAAiB,IACrD,KAAK,uBAA+B,iBAAiB,EAAK,GAC3D,KAAK,uBAAuB,oBAAA;AAAA,MAC9B,QAAY;AAAA,MAEZ;AACA,WAAK,yBAAyB;AAAA,IAChC;AACA,IAAI,KAAK,2BACP,KAAK,uBAAuB,QAAQ,CAACvC,MAAM;AACzC,UAAI;AACF,QAAAA,EAAE,OAAA;AAAA,MACJ,QAAY;AAAA,MAEZ;AAAA,IACF,CAAC,GACD,KAAK,yBAAyB;AAAA,EAElC;AAAA,EAEO,iBAAiB;AACtB,YAAQ,IAAI,qCAAqC,GAGjD,KAAK,cAAc,QAAQ,CAACuC,MAAS;AACnC,MAAAA,EAAK,aAAA;AAAA,IACP,CAAC,GAGD,KAAK,gBAAgB,CAAA,GAGrB,KAAK,4BAAA,GAGD,KAAK,uBACP,KAAK,qBAAqB,IAC1B,KAAK,QAAQ,QAAQ,mBAAmB,CAAA,CAAE;AAAA,EAE9C;AAAA;AAAA,EAGO,mBAA2B;AAChC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA,EAIO,kBAA+B;AACpC,WAAO,KAAK,cAAc,SAAS,IAAI,KAAK,cAAc,CAAC,IAAI;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcQ,cAAcA,GAKpB;AACA,UAAM/B,IAAI+B,EAAK,SACTzB,IAAIN,EAAE,KAAK,GACXO,IAAIP,EAAE,KAAK,GACXqc,IAAIrc,EAAE,SAAS,GACfqH,IAAIrH,EAAE,UAAU,GAChBuT,IAAQvT,EAAE,QAAQ,iBAAiB;AACzC,QAAI,CAACuT,EAAO,QAAO,EAAE,MAAMjT,GAAG,MAAMC,GAAG,MAAMD,IAAI+b,GAAG,MAAM9b,IAAI8G,EAAA;AAC9D,UAAMklD,IAAMjsD,IAAI+b,IAAI,GACdmwC,IAAMjsD,IAAI8G,IAAI,GACdo2B,IAAOlqB,IAAQ,KAAK,KAAM,KAC1BvG,IAAM,KAAK,IAAIywB,CAAG,GAClBv2B,IAAM,KAAK,IAAIu2B,CAAG;AACxB,QAAIjoB,IAAO,OACPC,IAAO,OACPH,IAAO,QACPC,IAAO;AACX,UAAMk3C,IAAsB;AAAA,MAC1B,CAACnsD,GAAGC,CAAC;AAAA,MACL,CAACD,IAAI+b,GAAG9b,CAAC;AAAA,MACT,CAACD,IAAI+b,GAAG9b,IAAI8G,CAAC;AAAA,MACb,CAAC/G,GAAGC,IAAI8G,CAAC;AAAA,IAAA;AAEX,eAAW,CAACyD,GAAIC,CAAE,KAAK0hD,GAAS;AAC9B,YAAM9gD,IAAKb,IAAKyhD,GACV3gD,IAAKb,IAAKyhD,GACVphD,IAAKmhD,IAAM5gD,IAAKqB,IAAMpB,IAAK1E,GAC3BmE,IAAKmhD,IAAM7gD,IAAKzE,IAAM0E,IAAKoB;AACjC,MAAAwI,IAAO,KAAK,IAAIA,GAAMpK,CAAE,GACxBqK,IAAO,KAAK,IAAIA,GAAMpK,CAAE,GACxBiK,IAAO,KAAK,IAAIA,GAAMlK,CAAE,GACxBmK,IAAO,KAAK,IAAIA,GAAMlK,CAAE;AAAA,IAC1B;AACA,WAAO,EAAE,MAAAmK,GAAM,MAAAC,GAAM,MAAAH,GAAM,MAAAC,EAAA;AAAA,EAC7B;AAAA,EAEO,WAAWxO,GAAcq6B,GAAsB;AACpD,UAAMY,IAAMZ,KAAS,KAAK,iBAAA;AAC1B,QAAI,CAACY,KAAOA,EAAI,SAAS,EAAG;AAI5B,UAAM17B,IAAI07B,EAAI,IAAI,CAACpyB,MAAM;AACvB,YAAMumC,IAAK,KAAK,cAAcvmC,CAAC;AAC/B,aAAO;AAAA,QACL,GAAAA;AAAA,QACA,MAAMumC,EAAG;AAAA,QACT,MAAMA,EAAG;AAAA,QACT,MAAMA,EAAG;AAAA,QACT,MAAMA,EAAG;AAAA,QACT,KAAKA,EAAG,OAAOA,EAAG,QAAQ;AAAA,QAC1B,KAAKA,EAAG,OAAOA,EAAG,QAAQ;AAAA,QAC1B,IAAIvmC,EAAE,QAAQ,KAAK;AAAA,QACnB,IAAIA,EAAE,QAAQ,KAAK;AAAA,MAAA;AAAA,IAEvB,CAAC,GACK88C,IAAQ,KAAK,IAAI,GAAGpmD,EAAE,IAAI,CAACtG,MAAMA,EAAE,IAAI,CAAC,GACxC2sD,IAAQ,KAAK,IAAI,GAAGrmD,EAAE,IAAI,CAACtG,MAAMA,EAAE,IAAI,CAAC,GACxC4sD,IAAQ,KAAK,IAAI,GAAGtmD,EAAE,IAAI,CAACtG,MAAMA,EAAE,IAAI,CAAC,GACxC6sD,IAAQ,KAAK,IAAI,GAAGvmD,EAAE,IAAI,CAACtG,MAAMA,EAAE,IAAI,CAAC,GACxCuyC,KAAOma,IAAQC,KAAS,GACxBna,KAAOoa,IAAQC,KAAS;AAC9B,eAAW7sD,KAAKsG,GAAG;AACjB,UAAIhG,IAAIN,EAAE,IACNO,IAAIP,EAAE;AACV,cAAQ+G,GAAA;AAAA,QACN,KAAK;AAAQ,UAAAzG,IAAIN,EAAE,MAAM0sD,IAAQ1sD,EAAE;AAAO;AAAA,QAC1C,KAAK;AAAS,UAAAM,IAAIN,EAAE,MAAM2sD,IAAQ3sD,EAAE;AAAO;AAAA,QAC3C,KAAK;AAAW,UAAAM,IAAIN,EAAE,MAAMuyC,IAAMvyC,EAAE;AAAK;AAAA,QACzC,KAAK;AAAO,UAAAO,IAAIP,EAAE,MAAM4sD,IAAQ5sD,EAAE;AAAO;AAAA,QACzC,KAAK;AAAU,UAAAO,IAAIP,EAAE,MAAM6sD,IAAQ7sD,EAAE;AAAO;AAAA,QAC5C,KAAK;AAAU,UAAAO,IAAIP,EAAE,MAAMwyC,IAAMxyC,EAAE;AAAK;AAAA,QACxC;AAAS;AAAA,MAAA;AAEX,MAAAA,EAAE,EAAE,SAASM,GAAGC,CAAC;AAAA,IACnB;AACA,SAAK,UAAU,eAAe;AAAA,MAC5B,aAAayhC,EAAI,IAAI,CAACpyB,MAAM6+B,EAAW7+B,EAAE,OAAO,CAAC;AAAA,IAAA,CAClD,GAKD,KAAK,4BAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,gBAAgBtD,GAAc80B,GAAsB;AACzD,UAAMY,IAAMZ,KAAS,KAAK,iBAAA;AAC1B,QAAI,CAACY,KAAOA,EAAI,SAAS,EAAG;AAG5B,UAAM17B,IAAI07B,EAAI,IAAI,CAACpyB,MAAM;AACvB,YAAMumC,IAAK,KAAK,cAAcvmC,CAAC;AAC/B,aAAO;AAAA,QACL,GAAAA;AAAA,QACA,MAAMumC,EAAG;AAAA,QACT,MAAMA,EAAG;AAAA,QACT,MAAMA,EAAG;AAAA,QACT,MAAMA,EAAG;AAAA,QACT,GAAGA,EAAG,OAAOA,EAAG;AAAA,QAChB,GAAGA,EAAG,OAAOA,EAAG;AAAA,QAChB,IAAIvmC,EAAE,QAAQ,KAAK;AAAA,QACnB,IAAIA,EAAE,QAAQ,KAAK;AAAA,MAAA;AAAA,IAEvB,CAAC;AACD,QAAItD,MAAS,cAAc;AACzB,MAAAhG,EAAE,KAAK,CAACI,GAAGC,MAAMD,EAAE,OAAOC,EAAE,IAAI;AAChC,YAAMsgB,IAAO3gB,EAAE,CAAC,EAAE,MACZ6gB,IAAQ7gB,EAAEA,EAAE,SAAS,CAAC,EAAE,MACxB+3B,IAAS/3B,EAAE,OAAO,CAAC/G,GAAGS,MAAMT,IAAIS,EAAE,GAAG,CAAC,GACtC8sD,KAAO3lC,IAAQF,IAAOoX,MAAW/3B,EAAE,SAAS;AAClD,UAAImwB,IAASxP;AACb,iBAAWjnB,KAAKsG;AACd,QAAAtG,EAAE,EAAE,SAASA,EAAE,MAAMy2B,IAASz2B,EAAE,OAAOA,EAAE,EAAE,GAC3Cy2B,KAAUz2B,EAAE,IAAI8sD;AAAA,IAEpB,WAAWxgD,MAAS,YAAY;AAC9B,MAAAhG,EAAE,KAAK,CAACI,GAAGC,MAAMD,EAAE,OAAOC,EAAE,IAAI;AAChC,YAAMqgB,IAAM1gB,EAAE,CAAC,EAAE,MACX4gB,IAAS5gB,EAAEA,EAAE,SAAS,CAAC,EAAE,MACzBymD,IAASzmD,EAAE,OAAO,CAAC/G,GAAGS,MAAMT,IAAIS,EAAE,GAAG,CAAC,GACtC8sD,KAAO5lC,IAASF,IAAM+lC,MAAWzmD,EAAE,SAAS;AAClD,UAAImwB,IAASzP;AACb,iBAAWhnB,KAAKsG;AACd,QAAAtG,EAAE,EAAE,SAASA,EAAE,IAAIA,EAAE,MAAMy2B,IAASz2B,EAAE,KAAK,GAC3Cy2B,KAAUz2B,EAAE,IAAI8sD;AAAA,IAEpB;AACE;AAEF,SAAK,UAAU,eAAe;AAAA,MAC5B,aAAa9qB,EAAI,IAAI,CAACpyB,MAAM6+B,EAAW7+B,EAAE,OAAO,CAAC;AAAA,IAAA,CAClD,GAKD,KAAK,4BAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUO,gBAAgBo9C,GAA4C;AACjE,WAAKA,IACE,KAAK,MAAM,SAAS;AAAA,MACzB,CAACp9C,MAAOA,EAAE,QAAQ,YAAuBo9C;AAAA,IAAA,IAFtB,CAAA;AAAA,EAIvB;AAAA;AAAA,EAGO,aAAajrD,GAA2B;AAC7C,WAAQA,GAAM,SAAS,WAAsB;AAAA,EAC/C;AAAA;AAAA,EAGO,UAAUA,GAAqB;AACpC,WAAO,CAAC,CAAC,KAAK,aAAaA,CAAI;AAAA,EACjC;AAAA;AAAA,EAGO,oBAAmC;AACxC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,eAAeq/B,GAAuB;AAC5C,UAAMsG,wBAAU,IAAA;AAChB,WAAAtG,EAAM,QAAQ,CAAC,MAAM;AACnB,MAAAsG,EAAI,IAAI,EAAE,IAAI,CAAC;AACf,YAAMloC,IAAI,KAAK,aAAa,CAAC;AAC7B,MAAIA,KAAG,KAAK,gBAAgBA,CAAC,EAAE,QAAQ,CAACjB,MAAMmpC,EAAI,IAAInpC,EAAE,IAAIA,CAAC,CAAC;AAAA,IAChE,CAAC,GACM,CAAC,GAAGmpC,EAAI,QAAQ;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASO,WAAWtG,GAA+B;AAC/C,UAAMY,KAAOZ,KAAS,KAAK,iBAAA,GAAoB,MAAA;AAC/C,QAAIY,EAAI,SAAS,EAAG,QAAO;AAC3B,UAAMiU,IAAM,SAAS/M,GAAK,CAAC;AAC3B,WAAAlH,EAAI,QAAQ,CAACpyB,MAAM;AACjB,MAAAA,EAAE,QAAQ,UAAUqmC;AAAA,IACtB,CAAC,GACD,KAAK,iBAAiB,MACtB,KAAK,UAAU,eAAe;AAAA,MAC5B,aAAajU,EAAI,IAAI,CAACpyB,MAAM6+B,EAAW7+B,EAAE,OAAO,CAAC;AAAA,IAAA,CAClD,GAED,KAAK,YAAYoyB,CAAG,GACbiU;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,aAAa7U,GAAsB;AACxC,UAAMY,IAAMZ,KAAS,KAAK,iBAAA,GACpB6rB,wBAAW,IAAA;AAKjB,QAJAjrB,EAAI,QAAQ,CAACpyB,MAAM;AACjB,YAAMpQ,IAAI,KAAK,aAAaoQ,CAAC;AAC7B,MAAIpQ,KAAGytD,EAAK,IAAIztD,CAAC;AAAA,IACnB,CAAC,GACG,CAACytD,EAAK,KAAM;AAChB,UAAMC,IAAmB,CAAA;AACzB,IAAAD,EAAK,QAAQ,CAACztD,MAAM;AAClB,WAAK,gBAAgBA,CAAC,EAAE,QAAQ,CAACjB,MAAM;AACrC,QAAAA,EAAE,QAAQ,UAAU,QACpB2uD,EAAS,KAAK3uD,CAAC;AAAA,MACjB,CAAC;AAAA,IACH,CAAC,GACD,KAAK,iBAAiB,MACtB,KAAK,UAAU,eAAe;AAAA;AAAA;AAAA;AAAA,MAI5B,aAAa2uD,EAAS,IAAI,CAACt9C,OAAO;AAAA,QAChC,GAAG6+B,EAAW7+B,EAAE,OAAO;AAAA,QACvB,SAAS;AAAA,MAAA,EACT;AAAA,IAAA,CACH,GACD,KAAK,YAAYs9C,CAAQ;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,UAAU9rB,GAAsB;AACrC,UAAM+rB,IAAU,KAAK,eAAe/rB,KAAS,KAAK,kBAAkB;AACpE,IAAK+rB,EAAQ,WACbA,EAAQ,QAAQ,CAAC,MAAM,EAAE,MAAM,GAC/B,KAAK,UAAU,eAAe;AAAA,MAC5B,aAAaA,EAAQ,IAAI,CAAC,MAAM1e,EAAW,EAAE,OAAO,CAAC;AAAA,IAAA,CACtD,GACD,KAAK,4BAAA;AAAA,EACP;AAAA;AAAA,EAGO,YAAYrN,GAAsB;AACvC,UAAM+rB,IAAU,KAAK,eAAe/rB,KAAS,KAAK,kBAAkB;AACpE,IAAK+rB,EAAQ,WACbA,EAAQ,QAAQ,CAAC,MAAM,EAAE,QAAQ,GACjC,KAAK,UAAU,eAAe;AAAA,MAC5B,aAAaA,EAAQ,IAAI,CAAC,MAAM1e,EAAW,EAAE,OAAO,CAAC;AAAA,IAAA,CACtD,GACD,KAAK,4BAAA;AAAA,EACP;AAAA;AAAA,EAGO,kBAAkBrN,GAAyB;AAChD,UAAMl8B,IAAIk8B,KAAS,KAAK,iBAAA;AACxB,WAAOl8B,EAAE,SAAS,KAAKA,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,QAAQ,QAAQ;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,WAAW8nD,GAAiBI,GAAqB;AACtD,UAAMjC,IAAU,KAAK,gBAAgB6B,CAAO;AAC5C,IAAK7B,EAAQ,WACb,KAAK,iBAAiB6B,GACtB,KAAK,YAAY,CAACI,KAAUjC,EAAQ,SAASiC,CAAM,IAAIA,IAASjC,EAAQ,CAAC,CAAC,CAAC;AAAA,EAC7E;AAAA;AAAA,EAGO,YAAkB;AACvB,UAAMlV,IAAM,KAAK;AAEjB,QADA,KAAK,iBAAiB,MAClB,CAACA,EAAK;AACV,UAAMkV,IAAU,KAAK,gBAAgBlV,CAAG;AACxC,IAAIkV,EAAQ,UAAQ,KAAK,YAAYA,CAAO;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWO,WAAW/pB,GAAgB8a,GAAkC;AAClE,UAAMM,IAAOP,GAAU,MAAM7a,GAAO8a,CAAc;AAClD,WAAO,KAAK,UAAUM,CAAI;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAa,SACXA,GACAC,IAAoB,IACpBC,IAAoB,IACpB2Q,GACe;AACf,UAAM9Q,GAAYC,GAAM,MAAMC,GAAUC,CAAQ,GAEhD,KAAK,UAAU,QAAA,GACf,KAAK,UAAU,OAAO,EAAI;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,WAAsB;AAC3B,WAAO4Q,GAAa,IAAI;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,IACL1uB,GACA3pB,GACQ;AACR,WAAO+uC,GAAU,MAAMplB,GAAM3pB,CAAQ;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,IACX2pB,GACA3pB,GACwB;AACxB,WAAOuvC,GAAU,MAAM5lB,GAAM3pB,CAAQ;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,QAAQ2pB,GAA8C;AAC3D,WAAO,KAAK,IAAIA,CAAI;AAAA,EACtB;AAAA;AAAA;AAAA,EAKO,WACLyf,GACAgI,GACAC,GACM;AACN,IAAAF,GAAW,MAAM/H,GAAOgI,GAAeC,CAAW;AAAA,EACpD;AAAA;AAAA;AAAA,EAKO,qBACLgB,GACAn9C,GACM;AACN,IAAAk9C,GAAqB,MAAMC,GAAkBn9C,CAAS;AAAA,EACxD;AAAA;AAAA,EAGO,YACL0xC,GACAsO,GACAhC,GACM;AACNoF,IAAAA,GAAiB,MAAM1R,GAAOsO,GAAIhC,CAAW;AAAA,EAC/C;AAAA;AAAA,EAGO,gBAA8B;AACnC,WAAOE,GAAc,IAAI;AAAA,EAC3B;AAAA;AAAA;AAAA,EAKO,eAAqB;AAC1B,SAAK,MAAM,SAAS,QAAQ,CAACtmD,MAAe;AAC1C,MAAIA,EAAK,QAAQ,YAEf,QAAQ,IAAI,mCAAmCA,EAAK,EAAE;AAAA,IAE1D,CAAC;AAAA,EACH;AAAA;AAAA,EAGO,YAAkB;AACvB,YAAQ,IAAI,8BAA8B;AAAA,EAC5C;AAAA;AAAA;AAAA,EAKA,MAAa,eAA8B;AACzC,UAAMyrD,GAAqB,IAAI;AAAA,EACjC;AACF;AAxjDE7D,GAAwB,mCAAmB,IAAY;AAAA,EACrD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA,EAGA;AAAA,CACD;AA/eI,IAAM8D,KAAN9D;ACrJA,SAAS+D,GACdryB,GACAlrB,GACK;AA0BL,SAzBakrB,EAAM,QAAQ;AAAA,IACzB,MAAMlrB,EAAQ;AAAA,IACd,GAAGA,EAAQ,KAAK;AAAA,IAChB,GAAGA,EAAQ,KAAK;AAAA,IAChB,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,iBAAiB;AAAA,IACjB,aAAa;AAAA,IACb,aAAa;AAAA,IACb,WAAW;AAAA,IACX,UAAU;AAAA,IACV,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,aAAa;AAAA;AAAA;AAAA;AAAA,IAIb,eAAeA,EAAQ;AAAA,IACvB,kBAAkBA,EAAQ,aAAa,KAAK,IAAA;AAAA,EAAI,CACjD;AAGH;AAKO,SAASw9C,GACdtyB,GACA8hB,GACS;AACT,QAAMp7C,IAAOs5B,EAAM,MAAM,IAAI8hB,CAAM;AACnC,SAAI,CAACp7C,KAAQ,CAACA,EAAK,QAAQ,YAClB,KAEFs5B,EAAM,WAAW8hB,CAAM;AAChC;AAKO,SAASyQ,GAAYvyB,GAAmB;AAC7C,SAAOA,EAAM,MAAM,SAAS;AAAA,IAC1B,CAACzrB,MAAWA,EAAE,QAAQ,cAAc;AAAA,EAAA;AAExC;;;;;;;ACpCA,MAAM7N,GAAK;AAAA,EAsBT,YAAYoO,IAA+B,IAAI;AAC7C,SAAK,cAAc,EAAE,IAAI09C,GAAY,GAAQ,GAAG19C,EAAA,GAChD,KAAK,UAAU,IAAI,MAAM,KAAK,aAAa;AAAA,MACzC,KAAK,CAAC8G,GAAQ62C,GAAUC,MAAa;AACnC,YAAI,OAAOD,KAAa,YAAY,CAAC,KAAK;AACxC,iBAAO,QAAQ,IAAI72C,GAAQ62C,GAAUC,CAAQ;AAE/C,cAAMC,IAAOvf,EAAW,KAAK,GAAG,WAAW,CAAA,CAAE;AAC7C,eAAO,OAAO,UAAU,eAAe,KAAKuf,GAAMF,CAAQ,IACtDE,EAAKF,CAAQ,IACb,QAAQ,IAAI72C,GAAQ62C,GAAUC,CAAQ;AAAA,MAC5C;AAAA,MACA,KAAK,CAAC92C,GAAQ62C,GAAU58C,GAAO68C,MAAa;AAC1C,cAAME,IAAU,QAAQ,IAAIh3C,GAAQ62C,GAAU58C,GAAO68C,CAAQ;AAC7D,eAAIE,KAAW,OAAOH,KAAa,YAAY,KAAK,MAClD,OAAO,OAAO,KAAK,GAAG,SAASzf,GAAW,EAAE,CAACyf,CAAQ,GAAG58C,EAAA,CAAO,CAAC,GAE3D+8C;AAAA,MACT;AAAA,MACA,gBAAgB,CAACh3C,GAAQ62C,MAAa;AACpC,cAAMI,IAAU,QAAQ,eAAej3C,GAAQ62C,CAAQ;AACvD,YAAII,KAAW,OAAOJ,KAAa,YAAY,KAAK,IAAI;AACtD,gBAAMK,IACJ;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,iBAAiB;AAAA,YACjB,WAAW;AAAA,YACX,WAAW;AAAA,UAAA,EACXL,CAAQ,KAAKA;AACjB,iBAAQ,KAAK,GAAG,QAAgCK,CAAU;AAAA,QAC5D;AACA,eAAOD;AAAA,MACT;AAAA,MACA,SAAS,CAACj3C,MAAW;AACnB,YAAI,CAAC,KAAK,GAAI,QAAO,QAAQ,QAAQA,CAAM;AAC3C,cAAMm3C,IAAW,QAAQ,QAAQ3f,EAAW,KAAK,GAAG,WAAW,CAAA,CAAE,CAAC;AAClE,eAAO,MAAM,KAAK,oBAAI,IAAI,CAAC,GAAG,QAAQ,QAAQx3B,CAAM,GAAG,GAAGm3C,CAAQ,CAAC,CAAC;AAAA,MACtE;AAAA,MACA,0BAA0B,CAACn3C,GAAQ62C,MAAa;AAC9C,cAAM7Q,IAAW,QAAQ,yBAAyBhmC,GAAQ62C,CAAQ;AAClE,YAAI7Q,KAAY,CAAC,KAAK,MAAM,OAAO6Q,KAAa;AAC9C,iBAAO7Q;AAET,cAAM+Q,IAAOvf,EAAW,KAAK,GAAG,WAAW,CAAA,CAAE;AAC7C,YAAI,OAAO,UAAU,eAAe,KAAKuf,GAAMF,CAAQ;AACrD,iBAAO,EAAE,cAAc,IAAM,YAAY,IAAM,UAAU,GAAA;AAAA,MAG7D;AAAA,IAAA,CACD,GACD,KAAK,SAAS,IAAIO,GAAiB,IAAI,GACvC,KAAK,gBAAgB,IAAIC,GAAwB,IAAI;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,IACLC,GACApE,GACM;AAEN,UAAMl1C,IAAW,OAAOs5C,KAAc,aAAaA,IAAYpE,GACzDtgC,IAAQ,MAAM,QAAQ0kC,CAAS,IAAIA,IAAY,QAC/Cjf,IAAS,KAAK;AACpB,QAAI,CAACA,KAAU,CAACr6B,EAAU;AAC1B,UAAMmsB,IAAQvX,KAASA,EAAM,SAAS,IAAIA,IAAQ,CAACylB,EAAO,EAAE;AAC3D,IAAAA,EAAO,MAAc;AAAA,MACpB,EAAE,OAAAlO,GAAO,cAAc,IAAM,UAAU,GAAA;AAAA,MACvC,CAAC0jB,MAAc7vC,EAAS6vC,CAAI;AAAA,IAAA;AAAA,EAEhC;AAAA;AAAA,EAGO,IACLyJ,GACApE,GACM;AACN,UAAMl1C,IAAW,OAAOs5C,KAAc,aAAaA,IAAYpE,GACzDtgC,IAAQ,MAAM,QAAQ0kC,CAAS,IAAIA,IAAY,QAC/Cjf,IAAS,KAAK;AACpB,QAAI,CAACA,KAAU,CAACr6B,EAAU;AAC1B,UAAMmsB,IAAQvX,KAASA,EAAM,SAAS,IAAIA,IAAQ,CAACylB,EAAO,EAAE;AAC3D,IAAAA,EAAO,MAAc;AAAA,MAAI,EAAE,OAAAlO,GAAO,cAAc,GAAA;AAAA,MAAQ,CAACrgC,MACxDkU,EAASlU,CAAG;AAAA,IAAA;AAAA,EAEhB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,SAASytD,GAAcC,GAAuB;AACnD,UAAMlgB,IAAU,KAAK,IAEfmgB,IACJF,KAAU,OAAOA,KAAW,WACxB,EAAE,GAAGA,EAAO,GAAG,GAAGA,EAAO,EAAA,IACzB,OAAOA,KAAW,WAChB,EAAE,GAAGA,GAAQ,GAAGC,EAAA,IAChB;AAER,QAAI,CAAClgB;AACH,aAAImgB,MACF,KAAK,QAAQ,IAAIA,EAAS,GAC1B,KAAK,QAAQ,IAAIA,EAAS,IAErB;AAGT,QAAIA,KAAYA,EAAS,KAAK,QAAQA,EAAS,KAAK;AAClD,aAAAngB,EAAG,SAASmgB,EAAS,GAAGA,EAAS,CAAC,GAC3B;AAIT,QAAI;AAEF,YAAM/Q,IADcpP,EAAG,OAAe,QAAQ,MAC5B,eAAe,SAAS;AAC1C,UAAIoP,GAAI;AACN,cAAMj3C,IAAI,OAAOi3C,CAAE,EAChB,MAAM,QAAQ,EACd,IAAI,MAAM;AACb,YAAIj3C,EAAE,WAAW,KAAKA,EAAE,MAAM,CAACkJ,MAAM,CAAC,MAAMA,CAAC,CAAC,GAAG;AAC/C,gBAAMpE,IAAK9E,EAAE,CAAC,IAAIA,EAAE,CAAC,IAAI,GACnB+E,IAAK/E,EAAE,CAAC,IAAIA,EAAE,CAAC,IAAI,GACnB2V,IAAIkyB,EAAG,QAAQ,SAAS,GACxBlnC,IAAIknC,EAAG,QAAQ,UAAU;AAC/B,UAAAA,EAAG,SAAS/iC,IAAK6Q,IAAI,GAAG5Q,IAAKpE,IAAI,CAAC;AAAA,QACpC;AAAA,MACF;AAAA,IACF,QAAY;AAAA,IAEZ;AACA,WAAO;AAAA,EACT;AACF;AAOA,MAAMgnD,GAAiB;AAAA,EAIrB,YAAYM,GAAa;AACvB,SAAK,QAAQA;AAAA,EACf;AAAA,EAEO,IAAI/uD,GAAeC,GAAsB;AAC9C,SAAK,UAAU,EAAE,OAAAD,GAAO,QAAAC,EAAA,GACxB,KAAK,MAAM,QAAQ,QAAQD,GAC3B,KAAK,MAAM,QAAQ,SAASC,GAE5B,KAAK,MAAM,IAAI,QAAQD,GAAOC,CAAM;AAAA,EACtC;AAAA,EAEO,OAAa;AAClB,QAAI,CAAC,KAAK,WAAW,CAAC,KAAK,MAAM,GAAI;AACrC,UAAMyvC,IAAS,KAAK,MAAM;AAC1B,IAAAA,EAAO,QAAQ,KAAK,QAAQ,OAAO,KAAK,QAAQ,MAAM,GAErDA,EAAO,OAAe,kBAAkB,iBAAiB;AAAA,MACxD,IAAIA,EAAO;AAAA,MACX,OAAO,KAAK,QAAQ;AAAA,MACpB,QAAQ,KAAK,QAAQ;AAAA,MACrB,QAASA,EAAO,QAAgB;AAAA,MAChC,YAAaA,EAAO,QAAgB;AAAA,MACpC,eACGA,EAAe,eAAe,kBAAA,KAAuB,IACtD,IAAI,CAAC/pC,OAAY;AAAA,QACjB,UAAUA,EAAE;AAAA,QACZ,SAASA,EAAE;AAAA,QACX,UAAU;AAAA,MAAA,EACV;AAAA,IAAA,CACH,GACD,KAAK,UAAU;AAAA,EACjB;AACF;AAOA,MAAM+oD,GAAwB;AAAA,EAG5B,YAAYK,GAAa;AACvB,SAAK,QAAQA;AAAA,EACf;AAAA;AAAA,EAGO,eAAetrC,GAAsB1iB,GAA4B;AACtE,QAAI,CAAC,KAAK,MAAM;AACd,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAGJ,UAAMiuD,IAAUvrC,aAAiBthB,KAAOshB,EAAM,KAAKA;AACnD,QAAI,CAACurC;AACH,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAGJ,WAAQ,KAAK,MAAM,GAAW,eAAe,eAAeA,GAASjuD,CAAI;AAAA,EAC3E;AAAA;AAAA,EAGA,IAAW,eAA2C;AACpD,UAAM2uC,IAAS,KAAK,MAAM,IACpBuf,IAAc,KAAK,MAAM;AAC/B,WAAI,CAACvf,KAAU,CAACuf,IAAoB,CAAA,KAEjCvf,EAAe,eAAe,kBAAA,KAAwB,CAAA,GAC7C,IAAI,CAAC/pC,OAAY;AAAA,MAC3B,GAAGA;AAAA,MACH,QAAQspD,EAAY,MAAM,IAAItpD,EAAE,QAAQ;AAAA,MACxC,OAAOspD,EAAY,MAAM,IAAItpD,EAAE,OAAO;AAAA,IAAA,EACtC;AAAA,EACJ;AACF;AAOA,MAAMupD,GAAY;AAAA,EAIhB,YAAYH,GAAc;AAF1B,SAAQ,+BAAe,IAAA,GAGrB,KAAK,QAAQA;AAAA,EACf;AAAA,EAEA,IAAY,UAAiB;AAC3B,QAAI,CAAC,KAAK,MAAM;AACd,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAGJ,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA;AAAA,EAGO,IAAI/+C,GAAqC;AAC9C,UAAM/N,IAAU+N,aAAa7N,KAAO6N,IAAI,IAAI7N,GAAK6N,CAAC,GAC5Cm/C,IAAY1gB,GAAWxsC,EAAQ,OAAO,GAGtCytC,IAAS,KAAK,QAAQ,QAAQyf,CAAS;AAC7C,WAAAltD,EAAQ,KAAKytC,GACbztC,EAAQ,QAAQ,KAAK,OACrB,KAAK,SAAS,IAAIytC,EAAO,IAAIztC,CAAO,GAC7BA;AAAA,EACT;AAAA;AAAA,EAGO,SAASmtD,GAAiD;AAC/D,YAAQA,KAAQ,CAAA,GAAI,IAAI,CAACp/C,MAAM,KAAK,IAAIA,CAAC,CAAC;AAAA,EAC5C;AAAA;AAAA,EAGO,IAAIsC,GAA8B;AACvC,UAAMo9B,IAAS,KAAK,QAAQ,MAAM,IAAIp9B,CAAE;AACxC,QAAKo9B;AACL,aAAO,KAAK,KAAKA,CAAM;AAAA,EACzB;AAAA;AAAA,EAGA,IAAW,WAAmB;AAC5B,WAAO,KAAK,QAAQ,MAAM,SAAS,IAAI,CAAC1/B,MAAM,KAAK,KAAKA,CAAC,CAAC;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,gBAAqC;AAE1C,UAAMy5C,IADK,KAAK,QACD,MAAM,UACfhM,IAA2C,CAAA,GAC3Cjc,IAA6B,CAAA,GAC7B6tB,IAAsC,CAAA;AAE5C,WAAA5F,EAAI,QAAQ,CAACh5B,MAAY;AACvB,YAAMuO,IAAOvO,EAAG,WAAW,CAAA,GACrB6+B,IAASzgB,EAAW7P,CAAI;AAC9B,OAACvO,EAAG,eAAe,kBAAA,KAAuB,CAAA,GAAI,QAAQ,CAAC9qB,MAAW;AAChE,QAAA83C,EAAa,KAAK;AAAA,UAChB,UAAU93C,EAAE;AAAA,UACZ,SAASA,EAAE;AAAA,UACX,WAAWA,EAAE;AAAA,UACb,UAAUA,EAAE;AAAA,UACZ,eAAeA,EAAE;AAAA,UACjB,eAAeA,EAAE;AAAA,UACjB,aAAaA,EAAE;AAAA,UACf,iBAAiBA,EAAE;AAAA,UACnB,gBAAgBA,EAAE;AAAA,QAAA,CACnB;AAAA,MACH,CAAC,GACI67B,EAAM/Q,EAAG,EAAE,MACd+Q,EAAM/Q,EAAG,EAAE,IAAI;AAAA,QACb,OAAO,EAAEuO,EAAK,SAAS;AAAA,QACvB,QAAQ,EAAEA,EAAK,UAAU;AAAA,QACzB,OAAOswB,EAAO,aAAatwB,EAAK,SAAS;AAAA,QACzC,OAAOA,EAAK;AAAA,QACZ,WAAWswB,EAAO,mBAAmBtwB,EAAK;AAAA,QAC1C,MAAMA,EAAK;AAAA,QACX,SAASA,EAAK,WAAW;AAAA,MAAA;AAG7B,YAAMqX,IAAM,OAAOrX,EAAK,WAAW,MAAM;AACzC,MAAKqwB,EAAUhZ,CAAG,MAAGgZ,EAAUhZ,CAAG,IAAI,CAAA,IACtCgZ,EAAUhZ,CAAG,EAAE,KAAK5lB,EAAG,EAAE;AAAA,IAC3B,CAAC,GAEM;AAAA,MACL,YAAY,KAAK,MAAM,QAAQ;AAAA,MAC/B,cAAAgtB;AAAA,MACA,OAAAjc;AAAA,MACA,WAAW,OAAO,KAAKA,CAAK;AAAA,MAC5B,WAAA6tB;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,YACLE,GACAC,GACM;AACN,UAAM7gB,IAAK,KAAK,SACV8gB,IAAcF,GAAQ,eAAe,CAAA,GACrChF,IAAK,OAAOiF,KAAa,aAAaA,IAAW,QACjDxwB,IAAO,OAAOwwB,KAAa,WAAWA,IAAW,CAAA,GAEjDvT,IAAQ,OAAO,KAAKwT,CAAW,EAClC,OAAO,CAACn9C,MAAOq8B,EAAG,MAAM,IAAIr8B,CAAE,CAAC,EAC/B,IAAI,CAACA,OAAQ;AAAA,MACZ,IAAAA;AAAA,MACA,GAAG,WAAWm9C,EAAYn9C,CAAE,EAAE,CAAC;AAAA,MAC/B,GAAG,WAAWm9C,EAAYn9C,CAAE,EAAE,CAAC;AAAA,IAAA,EAC/B;AACJ,IAAAq8B,EAAG,YAAYsN,GAAOsO,CAAE,GACnBvrB,EAAK,cACR2P,EAAG,cAAA;AAAA,EAEP;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,gBACL3P,IAKI,IACiB;AACrB,UAAM2P,IAAK,KAAK,SACV+gB,IAAS,IAAI,KAAK1wB,EAAK,SAAS,CAAA,GAAI,IAAI,CAACrgC,MAAM,CAACA,EAAE,IAAIA,CAAC,CAAU,CAAC,GAClE4uD,IAAiBvuB,EAAK,QACxBA,EAAK,MAAM,IAAI,CAAChvB,MAAOA,aAAa7N,KAAO6N,EAAE,KAAKA,CAAE,EAAE,OAAO,OAAO,IACpEgvB,EAAK,QACFA,EAAK,MAAM,IAAI,CAACrgC,MAAMgwC,EAAG,MAAM,IAAIhwC,EAAE,EAAE,CAAC,EAAE,OAAO,OAAO,IACzDgwC,EAAG,MAAM;AAEf,WAAO;AAAA,MACL,KAAK3P,EAAK,OAAO;AAAA,MACjB,QAAQA,EAAK,UAAU;AAAA,MACvB,eAAeuuB,EAAQ,IAAI,CAAC98B,OAAa;AAAA,QACvC,IAAIA,EAAG;AAAA,QACP,cAAc,EAAE,GAAG,GAAG,GAAG,GAAG,WAAW,GAAA;AAAA,MAAG,EAC1C;AAAA,MACF,aAAa88B,EAAQ,IAAI,CAAC98B,MAAY;AACpC,cAAMxoB,IAAQynD,EAAO,IAAIj/B,EAAG,EAAE,GACxB6+B,IAASzgB,EAAWpe,EAAG,WAAW,CAAA,CAAE;AAC1C,eAAO;AAAA,UACL,IAAIA,EAAG;AAAA,UACP,YAAY6+B,EAAO;AAAA,UACnB,OAAOA,EAAO,QAAQ,MAAMrnD,GAAO,KAAK;AAAA,UACxC,OAAOqnD,EAAO,QAAQ,MAAMrnD,GAAO,KAAK;AAAA,QAAA;AAAA,MAE5C,CAAC;AAAA,MACD,cAAcslD,EAAQ;AAAA,QAAQ,CAAC98B,OAC5BA,EAAG,eAAe,kBAAA,KAAuB,CAAA,GAAI,IAAI,CAAC9qB,OAAY;AAAA,UAC7D,UAAUA,EAAE;AAAA,UACZ,SAASA,EAAE;AAAA,UACX,UAAU;AAAA,UACV,IAAIA,EAAE;AAAA,QAAA,EACN;AAAA,MAAA;AAAA,IACJ;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,KAAK+pC,GAAsB;AACjC,QAAIztC,IAAU,KAAK,SAAS,IAAIytC,EAAO,EAAE;AACzC,WAAKztC,MACHA,IAAU,IAAIE,GAAK,EAAE,GAAIutC,EAAO,SAAiC,GACjEztC,EAAQ,QAAQ,KAAKytC,EAAO,IAC5B,KAAK,SAAS,IAAIA,EAAO,IAAIztC,CAAO,IAKtCA,EAAQ,KAAKytC,GACbztC,EAAQ,QAAQ,KAAK,OACdA;AAAA,EACT;AACF;AAWA,MAAMw5B,GAAM;AAAA,EA+CV,YAAYlrB,IAA+B,IAAIH,IAAmB,CAAA,GAAI;AAftE,SAAO,sBAAsB,IAmB3B,KAAK,UAAU;AAAA,MACb,GAAGG;AAAA,MACH,IAAIA,EAAQ,MAAM09C,GAAY;AAAA,IAAK,GAErC,KAAK,SAAS79C,KAAU,CAAA,GACxB,KAAK,WAAW,KAAK,QAAQ,WAAW69C,GAAY,GACpD,KAAK,QAAQ,IAAIiB,GAAY,IAAI,GAEjC,KAAK,aAAa;AAAA,MAChB,qBAAqB,CAAC3E,MAAoB;AACxC,aAAK,YAAA,GAKL,KAAK,GAAI,aAAA,GACTA,IAAA;AAAA,MACF;AAAA,IAAA,GAGF,KAAK,SAAS;AAAA,MACZ,QAAQ,MAAM;AACZ,aAAK,YAAA;AACL,cAAMllD,IAAM,KAAK,GAAW;AAC5B,QAAIA,MACFA,EAAG,MAAM,kBAAkB,eAC3BA,EAAG,MAAM,kBAAkB;AAAA,MAE/B;AAAA,IAAA;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAhEA,IAAW,UAAkB;AAC3B,WACI,KAAK,IAAY,SAAS,WAC5B,KAAK;AAAA,EAET;AAAA,EAEA,IAAW,QAAQiM,GAAe;AAChC,SAAK,WAAWA,GACZ,KAAK,OACN,KAAK,GAAW,QAAQ,UAAUA;AAAA,EAEvC;AAAA;AAAA,EAcA,IAAW,eAAoB;AAC7B,WAAO,KAAK,IAAI;AAAA,EAClB;AAAA;AAAA,EAuCQ,mBAAgC;AACtC,UAAM8kB,IAAY,KAAK,QAAQ;AAC/B,QAAIA,KAAa,OAAOA,KAAc;AAEpC,aAAOA;AAET,QAAI,OAAOA,KAAc,YAAYA,EAAU,SAAS,GAAG;AAEzD,YAAM8yB,IAAO,SAAS,eAAe9yB,CAAS;AAC9C,UAAI8yB,EAAM,QAAOA;AACjB,YAAMyG,IAAa,SAAS,cAA2Bv5B,CAAS;AAChE,UAAIu5B,EAAY,QAAOA;AACvB,YAAM,IAAI;AAAA,QACR,+BAA+Bv5B,CAAS;AAAA,MAAA;AAAA,IAE5C;AACA,UAAM,IAAI,MAAM,gDAAgD;AAAA,EAClE;AAAA;AAAA,EAGA,MAAa,OAAsB;AACjC,UAAMr2B,IAAU,KAAK,iBAAA,GACfovD,IAAYrgB,GAAY,KAAK,OAAO;AAC1C,WAAOqgB,EAAU,WACb,KAAK,QAAQ,YAAY,WAC3BA,EAAU,UAAU,KAAK,WAI3BA,EAAU,SAAS,KAAK,QACxB,KAAK,KAAK,IAAItB,GAAM9tD,GAASovD,CAAS,GAEtC,MAAM,KAAK,GAAG,iBAAA,GAKT,KAAK,QAAQ,aAAU,KAAK,QAAQ,WAAW,CAAA;AACpD,UAAMS,IAAiC;AAAA,MACrC,GAAI,KAAK,QAAQ,SAAS,QAAQ,CAAA;AAAA,IAAC;AAoBrC,QAlBA,OAAO,eAAeA,GAAW,KAAK;AAAA,MACpC,YAAY;AAAA,MACZ,KAAK,MAAM;AACT,YAAI;AACF,iBAAO,KAAK,IAAI,QAAA,KAAa;AAAA,QAC/B,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IAAA,CACD,GACD,KAAK,QAAQ,SAAS,OAAOA,IAS1B,KAAK,QAAQ,sBAAsB,OACpC,KAAK,OAAO,qBACZ;AACA,YAAMjhB,IAAK,KAAK;AAChB,MAAAA,EAAG,aAAA,GACH,WAAW,MAAM;AAGf,SADEA,GAAI,QAAQ,KAAK,EAAE,UAAU,KAAK,QAAQ,GAAA,CAAI,KAAK,QAAQ,QAAA,GAE1D;AAAA,UAAM,CAACtT,MACN,QAAQ,KAAK,uCAAuCA,CAAK;AAAA,QAAA,EAE1D,QAAQ,MAAMsT,GAAI,cAAc;AAAA,MACrC,GAAG,GAAG;AAAA,IACR;AAEA,WAAO;AAAA,EACT;AAAA;AAAA,EAGO,aAAqB;AAC1B,gBAAK,YAAA,GACE,KAAK,GAAI,WAAA;AAAA,EAClB;AAAA;AAAA,EAGA,MAAa,SAASiO,GAA6B;AACjD,SAAK,YAAA,GACL,MAAM,KAAK,GAAI,SAASA,CAAI;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaO,UAAgB;AACrB,QAAI;AACF,WAAK,IAAI,QAAA;AAAA,IACX,QAAY;AAAA,IAEZ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,iBAML;AACA,gBAAK,YAAA,GACE,KAAK,GAAI,eAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAW,SAAS;AAClB,gBAAK,YAAA,GACG,KAAK,GAAW;AAAA,EAC1B;AAAA;AAAA,EAGA,IAAW,WAAW;AACpB,gBAAK,YAAA,GACG,KAAK,GAAW;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAW,UAGT;AACA,WAAO;AAAA,MACL,kBAAkB/O,GAAA;AAAA,MAClB,qBAAqBhB,GAAA;AAAA,IAAuB;AAAA,EAEhD;AAAA;AAAA,EAGA,IAAW,WAAW;AACpB,gBAAK,YAAA,GACG,KAAK,GAAW;AAAA,EAC1B;AAAA,EAEA,IAAW,WAAW;AACpB,gBAAK,YAAA,GACG,KAAK,GAAW;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYO,WAAWrL,GAA6C;AAC7D,gBAAK,YAAA,GACE,KAAK,GAAI,WAAW,KAAK,YAAYA,CAAK,CAAC;AAAA,EACpD;AAAA,EAEO,aAAaA,GAAoC;AACtD,SAAK,YAAA,GACL,KAAK,GAAI,aAAa,KAAK,YAAYA,CAAK,CAAC;AAAA,EAC/C;AAAA,EAEO,UAAUA,GAAoC;AACnD,SAAK,YAAA,GACL,KAAK,GAAI,UAAU,KAAK,YAAYA,CAAK,CAAC;AAAA,EAC5C;AAAA,EAEO,YAAYA,GAAoC;AACrD,SAAK,YAAA,GACL,KAAK,GAAI,YAAY,KAAK,YAAYA,CAAK,CAAC;AAAA,EAC9C;AAAA,EAEO,kBAAkBA,GAAuC;AAC9D,gBAAK,YAAA,GACE,KAAK,GAAI,kBAAkB,KAAK,YAAYA,CAAK,CAAC;AAAA,EAC3D;AAAA,EAEQ,YAAYA,GAAoD;AACtE,QAAKA;AACL,aAAOA,EACJ;AAAA,QAAI,CAACquB,MACJA,aAAqB1tD,KAAO0tD,EAAU,KAAKA;AAAA,MAAA,EAE5C,OAAO,CAACA,MAAmC,CAAC,CAACA,CAAS;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,QACLC,GACAC,GACAC,GACM;AACN,SAAK,YAAA;AACL,UAAMrhB,IAAK,KAAK;AAChB,IAAKohB,KACHphB,EAAG,MAAM,SAAS,QAAQ,CAAC3+B,MAAWA,EAAE,QAAQ,GAE7C8/C,MACH,KAAK,QAAQ,UAAU,IACvB,KAAK,QAAQ,YAAY,IACzBnhB,EAAG,iBAAA,GACCqhB,MACFrhB,EAAG,UAAU,UAAA,GACbA,EAAG,YAAY,UAAA;AAAA,EAGrB;AAAA;AAAA,EAGO,OAAOmhB,GAAuBC,GAA6B;AAChE,SAAK,YAAA;AACL,UAAMphB,IAAK,KAAK;AAChB,IAAKohB,KACHphB,EAAG,MAAM,SAAS,QAAQ,CAAC3+B,MAAW;AACpC,MAAKA,EAAE,SAAS,cAAY,SAAA;AAAA,IAC9B,CAAC,GAEE8/C,MACH,KAAK,QAAQ,UAAU,IACvB,KAAK,QAAQ,YAAY,IACzBnhB,EAAG,gBAAA;AAAA,EAEP;AAAA;AAAA,EAGO,IACL3P,GACA3pB,GACwB;AACxB,gBAAK,YAAA,GACE,KAAK,GAAI,IAAI2pB,GAAa3pB,CAAQ;AAAA,EAC3C;AAAA,EAEQ,cAAoB;AAC1B,QAAI,CAAC,KAAK;AACR,YAAM,IAAI,MAAM,wDAAwD;AAAA,EAE5E;AACF;AAQA,MAAM46C,KAAN,MAAMA,GAAK;AAAA,EAQT,YAAYC,GAAmB;AAC7B,SAAK,gBAAgBA,CAAW;AAAA,EAClC;AAAA,EAEO,gBAAgBA,GAAyB;AAC9C,UAAMvuD,IAAO,KAAK,YAAY,MACxBwuD,IAAaF,GAAK,iBAAiBtuD,CAAI;AAC7C,IAAIwuD,KACFA,EAAW,QAAQ,CAAC,EAAE,MAAAzxD,GAAM,QAAQ0xD,QAAa;AAC/C,MAAK,KAAK,YAAS,KAAK,UAAU,CAAA,IAClC,KAAK,QAAQ1xD,CAAI,IAAI,IAAI0xD,EAAOF,CAAW;AAAA,IAC7C,CAAC;AAAA,EAEL;AAAA,EAEA,OAAc,eAAeG,GAGpB;AACP,QAAI,CAACA,GAAS,QAAQ,CAACA,GAAS;AAC9B,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAGJ,UAAM1uD,IAAO,OAAO,eAAe0uD,EAAQ,MAAM,EAAE;AACnD,IAAKJ,GAAK,iBAAiBtuD,CAAI,MAC7BsuD,GAAK,iBAAiBtuD,CAAI,IAAI,CAAA,IAEhCsuD,GAAK,iBAAiBtuD,CAAI,IAAI,CAAC,GAAGsuD,GAAK,iBAAiBtuD,CAAI,GAAG0uD,CAAO;AAAA,EACxE;AACF;AArCEJ,GAAe,mBAGX,CAAA;AAJN,IAAM/lD,KAAN+lD;AA4CO,MAAMK,KAAW;AAAA,EACtB,OAAA70B;AAAA,EACA,MAAAt5B;AAAA,EACA,MAAA+H;AAAA,EACA,OAAOqmD;AACT;AC/uBO,SAASC,GAAWzwD,GAA+BwQ,IAAe,IAAI;AAC3E,SAAO,IAAIs9C,GAAM9tD,GAASwQ,CAAO;AACnC;AAGI,OAAO,SAAW,QACnB,OAAe,aAAaigD,IAC3B,OAAe,QAAQ3C,IACvB,OAAe,OAAOtd,IACtB,OAAe,UAAUoO,IACzB,OAAe,eAAevjB,IAC9B,OAAe,WAAW0kB,IAC1B,OAAe,YAAY/jB,IAC3B,OAAe,gBAAgB00B,IAC/B,OAAe,gBAAgBC,IAC/B,OAAe,eAAeC,IAC9B,OAAe,gBAAgB1wB,IAC/B,OAAe,aAAa2wB,IAC5B,OAAe,SAASpwB,IACxB,OAAe,SAASmB,IACxB,OAAe,WAAWkgB,IAC1B,OAAe,iBAAiBM,IAChC,OAAe,OAAOO,IACtB,OAAe,OAAO5U,IACtB,OAAe,WAAW+U,IAC1B,OAAe,cAAcgB,IAC7B,OAAe,UAAUrW,IACzB,OAAe,QAAQrK,IACvB,OAAe,SAAS0tB,IACxB,OAAe,SAASzL,IACxB,OAAe,QAAQ0L,IACvB,OAAe,SAASC,IACxB,OAAe,aAAarI,IAC5B,OAAe,WAAWsI,IAC1B,OAAe,eAAejI,IAC9B,OAAe,WAAW,OAAO,OAAO,CAAA,GAAIuH,IAAU,EAAE,QAAAW,IAAQ;","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76]}