{"version":3,"sources":["jsdelivr-header.js","/npm/@sudodevnull/datastar@0.19.9/src/lib/dom.ts","/npm/@sudodevnull/datastar@0.19.9/src/lib/external/preact-core.ts","/npm/@sudodevnull/datastar@0.19.9/src/lib/external/deepsignal.ts","/npm/@sudodevnull/datastar@0.19.9/src/lib/external/ts-merge-patch.ts","/npm/@sudodevnull/datastar@0.19.9/src/lib/types.ts","/npm/@sudodevnull/datastar@0.19.9/src/lib/plugins/core.ts","/npm/@sudodevnull/datastar@0.19.9/src/lib/engine.ts","/npm/@sudodevnull/datastar@0.19.9/src/lib/plugins/attributes.ts","/npm/@sudodevnull/datastar@0.19.9/src/lib/external/fetch-event-source.ts","/npm/@sudodevnull/datastar@0.19.9/src/lib/external/idiomorph.ts","/npm/@sudodevnull/datastar@0.19.9/src/lib/plugins/visibility.ts","/npm/@sudodevnull/datastar@0.19.9/src/lib/plugins/backend.ts","/npm/@sudodevnull/datastar@0.19.9/src/lib/plugins/helpers.ts","/npm/@sudodevnull/datastar@0.19.9/src/lib/index.ts"],"names":[],"mappings":"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","file":"/npm/@sudodevnull/datastar@0.19.9/dist/datastar.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.37.0.\n * Original file: /npm/@sudodevnull/datastar@0.19.9/dist/datastar.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","import { HTMLorSVGElement } from './types'\n\nexport function toHTMLorSVGElement(node: Node): HTMLorSVGElement | null {\n  if (!(node instanceof HTMLElement || node instanceof SVGElement)) {\n    return null\n  }\n  return node\n}\n","// From https://github.com/preactjs/signals/blob/main/packages/core/src/index.ts\n\nfunction cycleDetected(): never {\n  throw new Error('Cycle detected')\n}\nfunction mutationDetected(): never {\n  throw new Error('Computed cannot have side-effects')\n}\n\nconst identifier = Symbol.for('preact-signals')\n\n// Flags for Computed and Effect.\nconst RUNNING = 1 << 0\nconst NOTIFIED = 1 << 1\nconst OUTDATED = 1 << 2\nconst DISPOSED = 1 << 3\nconst HAS_ERROR = 1 << 4\nconst TRACKING = 1 << 5\n\n// A linked list node used to track dependencies (sources) and dependents (targets).\n// Also used to remember the source's last version number that the target saw.\ntype Node = {\n  // A source whose value the target depends on.\n  _source: Signal\n  _prevSource?: Node\n  _nextSource?: Node\n\n  // A target that depends on the source and should be notified when the source changes.\n  _target: Computed | Effect\n  _prevTarget?: Node\n  _nextTarget?: Node\n\n  // The version number of the source that target has last seen. We use version numbers\n  // instead of storing the source value, because source values can take arbitrary amount\n  // of memory, and computeds could hang on to them forever because they're lazily evaluated.\n  // Use the special value -1 to mark potentially unused but recyclable nodes.\n  _version: number\n\n  // Used to remember & roll back the source's previous `._node` value when entering &\n  // exiting a new evaluation context.\n  _rollbackNode?: Node\n}\n\nfunction startBatch() {\n  batchDepth++\n}\n\nfunction endBatch() {\n  if (batchDepth > 1) {\n    batchDepth--\n    return\n  }\n\n  let error: unknown\n  let hasError = false\n\n  while (batchedEffect !== undefined) {\n    let effect: Effect | undefined = batchedEffect\n    batchedEffect = undefined\n\n    batchIteration++\n\n    while (effect !== undefined) {\n      const next: Effect | undefined = effect._nextBatchedEffect\n      effect._nextBatchedEffect = undefined\n      effect._flags &= ~NOTIFIED\n\n      if (!(effect._flags & DISPOSED) && needsToRecompute(effect)) {\n        try {\n          effect._callback()\n        } catch (err) {\n          if (!hasError) {\n            error = err\n            hasError = true\n          }\n        }\n      }\n      effect = next\n    }\n  }\n  batchIteration = 0\n  batchDepth--\n\n  if (hasError) {\n    throw error\n  }\n}\n\nfunction batch<T>(callback: () => T): T {\n  if (batchDepth > 0) {\n    return callback()\n  }\n  /*@__INLINE__**/ startBatch()\n  try {\n    return callback()\n  } finally {\n    endBatch()\n  }\n}\n\n// Currently evaluated computed or effect.\nlet evalContext: Computed | Effect | undefined = undefined\n\nlet untrackedDepth = 0\n\nfunction untracked<T>(callback: () => T): T {\n  if (untrackedDepth > 0) {\n    return callback()\n  }\n  const prevContext = evalContext\n  evalContext = undefined\n  untrackedDepth++\n  try {\n    return callback()\n  } finally {\n    untrackedDepth--\n    evalContext = prevContext\n  }\n}\n\n// Effects collected into a batch.\nlet batchedEffect: Effect | undefined = undefined\nlet batchDepth = 0\nlet batchIteration = 0\n\n// A global version number for signals, used for fast-pathing repeated\n// computed.peek()/computed.value calls when nothing has changed globally.\nlet globalVersion = 0\n\nfunction addDependency(signal: Signal): Node | undefined {\n  if (evalContext === undefined) {\n    return undefined\n  }\n\n  let node = signal._node\n  if (node === undefined || node._target !== evalContext) {\n    /**\n     * `signal` is a new dependency. Create a new dependency node, and set it\n     * as the tail of the current context's dependency list. e.g:\n     *\n     * { A <-> B       }\n     *         ↑     ↑\n     *        tail  node (new)\n     *               ↓\n     * { A <-> B <-> C }\n     *               ↑\n     *              tail (evalContext._sources)\n     */\n    node = {\n      _version: 0,\n      _source: signal,\n      _prevSource: evalContext._sources,\n      _nextSource: undefined,\n      _target: evalContext,\n      _prevTarget: undefined,\n      _nextTarget: undefined,\n      _rollbackNode: node,\n    }\n\n    if (evalContext._sources !== undefined) {\n      evalContext._sources._nextSource = node\n    }\n    evalContext._sources = node\n    signal._node = node\n\n    // Subscribe to change notifications from this dependency if we're in an effect\n    // OR evaluating a computed signal that in turn has subscribers.\n    if (evalContext._flags & TRACKING) {\n      signal._subscribe(node)\n    }\n    return node\n  } else if (node._version === -1) {\n    // `signal` is an existing dependency from a previous evaluation. Reuse it.\n    node._version = 0\n\n    /**\n     * If `node` is not already the current tail of the dependency list (i.e.\n     * there is a next node in the list), then make the `node` the new tail. e.g:\n     *\n     * { A <-> B <-> C <-> D }\n     *         ↑           ↑\n     *        node   ┌─── tail (evalContext._sources)\n     *         └─────│─────┐\n     *               ↓     ↓\n     * { A <-> C <-> D <-> B }\n     *                     ↑\n     *                    tail (evalContext._sources)\n     */\n    if (node._nextSource !== undefined) {\n      node._nextSource._prevSource = node._prevSource\n\n      if (node._prevSource !== undefined) {\n        node._prevSource._nextSource = node._nextSource\n      }\n\n      node._prevSource = evalContext._sources\n      node._nextSource = undefined\n\n      evalContext._sources!._nextSource = node\n      evalContext._sources = node\n    }\n\n    // We can assume that the currently evaluated effect / computed signal is already\n    // subscribed to change notifications from `signal` if needed.\n    return node\n  }\n  return undefined\n}\n\n// @ts-ignore internal Signal is viewed as a function\ndeclare class Signal<T = any> {\n  /** @internal */\n  _value: unknown\n\n  /**\n   * @internal\n   * Version numbers should always be >= 0, because the special value -1 is used\n   * by Nodes to signify potentially unused but recyclable nodes.\n   */\n  _version: number\n\n  /** @internal */\n  _node?: Node\n\n  /** @internal */\n  _targets?: Node\n\n  constructor(value?: T)\n\n  /** @internal */\n  _refresh(): boolean\n\n  /** @internal */\n  _subscribe(node: Node): void\n\n  /** @internal */\n  _unsubscribe(node: Node): void\n\n  subscribe(fn: (value: T) => void): () => void\n\n  valueOf(): T\n\n  toString(): string\n\n  toJSON(): T\n\n  peek(): T\n\n  brand: typeof identifier\n\n  get value(): T\n  set value(value: T)\n}\n\n/** @internal */\n// @ts-ignore internal Signal is viewed as function\nfunction Signal(this: Signal, value?: unknown) {\n  this._value = value\n  this._version = 0\n  this._node = undefined\n  this._targets = undefined\n}\n\nSignal.prototype.brand = identifier\n\nSignal.prototype._refresh = function () {\n  return true\n}\n\nSignal.prototype._subscribe = function (node) {\n  if (this._targets !== node && node._prevTarget === undefined) {\n    node._nextTarget = this._targets\n    if (this._targets !== undefined) {\n      this._targets._prevTarget = node\n    }\n    this._targets = node\n  }\n}\n\nSignal.prototype._unsubscribe = function (node) {\n  // Only run the unsubscribe step if the signal has any subscribers to begin with.\n  if (this._targets !== undefined) {\n    const prev = node._prevTarget\n    const next = node._nextTarget\n    if (prev !== undefined) {\n      prev._nextTarget = next\n      node._prevTarget = undefined\n    }\n    if (next !== undefined) {\n      next._prevTarget = prev\n      node._nextTarget = undefined\n    }\n    if (node === this._targets) {\n      this._targets = next\n    }\n  }\n}\n\nSignal.prototype.subscribe = function (fn) {\n  const signal = this\n  return effect(function (this: Effect) {\n    const value = signal.value\n    const flag = this._flags & TRACKING\n    this._flags &= ~TRACKING\n    try {\n      fn(value)\n    } finally {\n      this._flags |= flag\n    }\n  })\n}\n\nSignal.prototype.valueOf = function () {\n  return this.value\n}\n\nSignal.prototype.toString = function () {\n  return this.value + ''\n}\n\nSignal.prototype.toJSON = function () {\n  return this.value\n}\n\nSignal.prototype.peek = function () {\n  return this._value\n}\n\nObject.defineProperty(Signal.prototype, 'value', {\n  get() {\n    const node = addDependency(this)\n    if (node !== undefined) {\n      node._version = this._version\n    }\n    return this._value\n  },\n  set(this: Signal, value) {\n    if (evalContext instanceof Computed) {\n      mutationDetected()\n    }\n\n    if (value !== this._value) {\n      if (batchIteration > 100) {\n        cycleDetected()\n      }\n\n      this._value = value\n      this._version++\n      globalVersion++\n\n      /**@__INLINE__*/ startBatch()\n      try {\n        for (let node = this._targets; node !== undefined; node = node._nextTarget) {\n          node._target._notify()\n        }\n      } finally {\n        endBatch()\n      }\n    }\n  },\n})\n\nfunction signal<T>(value: T): Signal<T> {\n  return new Signal(value)\n}\n\nfunction needsToRecompute(target: Computed | Effect): boolean {\n  // Check the dependencies for changed values. The dependency list is already\n  // in order of use. Therefore if multiple dependencies have changed values, only\n  // the first used dependency is re-evaluated at this point.\n  for (let node = target._sources; node !== undefined; node = node._nextSource) {\n    // If there's a new version of the dependency before or after refreshing,\n    // or the dependency has something blocking it from refreshing at all (e.g. a\n    // dependency cycle), then we need to recompute.\n    if (\n      node._source._version !== node._version ||\n      !node._source._refresh() ||\n      node._source._version !== node._version\n    ) {\n      return true\n    }\n  }\n  // If none of the dependencies have changed values since last recompute then\n  // there's no need to recompute.\n  return false\n}\n\nfunction prepareSources(target: Computed | Effect) {\n  /**\n   * 1. Mark all current sources as re-usable nodes (version: -1)\n   * 2. Set a rollback node if the current node is being used in a different context\n   * 3. Point 'target._sources' to the tail of the doubly-linked list, e.g:\n   *\n   *    { undefined <- A <-> B <-> C -> undefined }\n   *                   ↑           ↑\n   *                   │           └──────┐\n   * target._sources = A; (node is head)  │\n   *                   ↓                  │\n   * target._sources = C; (node is tail) ─┘\n   */\n  for (let node = target._sources; node !== undefined; node = node._nextSource) {\n    const rollbackNode = node._source._node\n    if (rollbackNode !== undefined) {\n      node._rollbackNode = rollbackNode\n    }\n    node._source._node = node\n    node._version = -1\n\n    if (node._nextSource === undefined) {\n      target._sources = node\n      break\n    }\n  }\n}\n\nfunction cleanupSources(target: Computed | Effect) {\n  let node = target._sources\n  let head = undefined\n\n  /**\n   * At this point 'target._sources' points to the tail of the doubly-linked list.\n   * It contains all existing sources + new sources in order of use.\n   * Iterate backwards until we find the head node while dropping old dependencies.\n   */\n  while (node !== undefined) {\n    const prev = node._prevSource\n\n    /**\n     * The node was not re-used, unsubscribe from its change notifications and remove itself\n     * from the doubly-linked list. e.g:\n     *\n     * { A <-> B <-> C }\n     *         ↓\n     *    { A <-> C }\n     */\n    if (node._version === -1) {\n      node._source._unsubscribe(node)\n\n      if (prev !== undefined) {\n        prev._nextSource = node._nextSource\n      }\n      if (node._nextSource !== undefined) {\n        node._nextSource._prevSource = prev\n      }\n    } else {\n      /**\n       * The new head is the last node seen which wasn't removed/unsubscribed\n       * from the doubly-linked list. e.g:\n       *\n       * { A <-> B <-> C }\n       *   ↑     ↑     ↑\n       *   │     │     └ head = node\n       *   │     └ head = node\n       *   └ head = node\n       */\n      head = node\n    }\n\n    node._source._node = node._rollbackNode\n    if (node._rollbackNode !== undefined) {\n      node._rollbackNode = undefined\n    }\n\n    node = prev\n  }\n\n  target._sources = head\n}\n\ndeclare class Computed<T = any> extends Signal<T> {\n  _compute: () => T\n  _sources?: Node\n  _globalVersion: number\n  _flags: number\n\n  constructor(compute: () => T)\n\n  _notify(): void\n  get value(): T\n}\n\nfunction Computed(this: Computed, compute: () => unknown) {\n  Signal.call(this, undefined)\n\n  this._compute = compute\n  this._sources = undefined\n  this._globalVersion = globalVersion - 1\n  this._flags = OUTDATED\n}\n\nComputed.prototype = new Signal() as Computed\n\nComputed.prototype._refresh = function () {\n  this._flags &= ~NOTIFIED\n\n  if (this._flags & RUNNING) {\n    return false\n  }\n\n  // If this computed signal has subscribed to updates from its dependencies\n  // (TRACKING flag set) and none of them have notified about changes (OUTDATED\n  // flag not set), then the computed value can't have changed.\n  if ((this._flags & (OUTDATED | TRACKING)) === TRACKING) {\n    return true\n  }\n  this._flags &= ~OUTDATED\n\n  if (this._globalVersion === globalVersion) {\n    return true\n  }\n  this._globalVersion = globalVersion\n\n  // Mark this computed signal running before checking the dependencies for value\n  // changes, so that the RUNNING flag can be used to notice cyclical dependencies.\n  this._flags |= RUNNING\n  if (this._version > 0 && !needsToRecompute(this)) {\n    this._flags &= ~RUNNING\n    return true\n  }\n\n  const prevContext = evalContext\n  try {\n    prepareSources(this)\n    evalContext = this\n    const value = this._compute()\n    if (this._flags & HAS_ERROR || this._value !== value || this._version === 0) {\n      this._value = value\n      this._flags &= ~HAS_ERROR\n      this._version++\n    }\n  } catch (err) {\n    this._value = err\n    this._flags |= HAS_ERROR\n    this._version++\n  }\n  evalContext = prevContext\n  cleanupSources(this)\n  this._flags &= ~RUNNING\n  return true\n}\n\nComputed.prototype._subscribe = function (node) {\n  if (this._targets === undefined) {\n    this._flags |= OUTDATED | TRACKING\n\n    // A computed signal subscribes lazily to its dependencies when the it\n    // gets its first subscriber.\n    for (let node = this._sources; node !== undefined; node = node._nextSource) {\n      node._source._subscribe(node)\n    }\n  }\n  Signal.prototype._subscribe.call(this, node)\n}\n\nComputed.prototype._unsubscribe = function (node) {\n  // Only run the unsubscribe step if the computed signal has any subscribers.\n  if (this._targets !== undefined) {\n    Signal.prototype._unsubscribe.call(this, node)\n\n    // Computed signal unsubscribes from its dependencies when it loses its last subscriber.\n    // This makes it possible for unreferences subgraphs of computed signals to get garbage collected.\n    if (this._targets === undefined) {\n      this._flags &= ~TRACKING\n\n      for (let node = this._sources; node !== undefined; node = node._nextSource) {\n        node._source._unsubscribe(node)\n      }\n    }\n  }\n}\n\nComputed.prototype._notify = function () {\n  if (!(this._flags & NOTIFIED)) {\n    this._flags |= OUTDATED | NOTIFIED\n\n    for (let node = this._targets; node !== undefined; node = node._nextTarget) {\n      node._target._notify()\n    }\n  }\n}\n\nComputed.prototype.peek = function () {\n  if (!this._refresh()) {\n    cycleDetected()\n  }\n  if (this._flags & HAS_ERROR) {\n    throw this._value\n  }\n  return this._value\n}\n\nObject.defineProperty(Computed.prototype, 'value', {\n  get() {\n    if (this._flags & RUNNING) {\n      cycleDetected()\n    }\n    const node = addDependency(this)\n    this._refresh()\n    if (node !== undefined) {\n      node._version = this._version\n    }\n    if (this._flags & HAS_ERROR) {\n      throw this._value\n    }\n    return this._value\n  },\n})\n\ninterface ReadonlySignal<T = any> extends Signal<T> {\n  readonly value: T\n}\n\nfunction computed<T>(compute: () => T): ReadonlySignal<T> {\n  return new Computed(compute)\n}\n\nfunction cleanupEffect(effect: Effect) {\n  const cleanup = effect._cleanup\n  effect._cleanup = undefined\n\n  if (typeof cleanup === 'function') {\n    /*@__INLINE__**/ startBatch()\n\n    // Run cleanup functions always outside of any context.\n    const prevContext = evalContext\n    evalContext = undefined\n    try {\n      cleanup()\n    } catch (err) {\n      effect._flags &= ~RUNNING\n      effect._flags |= DISPOSED\n      disposeEffect(effect)\n      throw err\n    } finally {\n      evalContext = prevContext\n      endBatch()\n    }\n  }\n}\n\nfunction disposeEffect(effect: Effect) {\n  for (let node = effect._sources; node !== undefined; node = node._nextSource) {\n    node._source._unsubscribe(node)\n  }\n  effect._compute = undefined\n  effect._sources = undefined\n\n  cleanupEffect(effect)\n}\n\nfunction endEffect(this: Effect, prevContext?: Computed | Effect) {\n  if (evalContext !== this) {\n    throw new Error('Out-of-order effect')\n  }\n  cleanupSources(this)\n  evalContext = prevContext\n\n  this._flags &= ~RUNNING\n  if (this._flags & DISPOSED) {\n    disposeEffect(this)\n  }\n  endBatch()\n}\n\ntype EffectCleanup = () => unknown\ndeclare class Effect {\n  _compute?: () => unknown | EffectCleanup\n  _cleanup?: () => unknown\n  _sources?: Node\n  _nextBatchedEffect?: Effect\n  _flags: number\n\n  constructor(compute: () => unknown | EffectCleanup)\n\n  _callback(): void\n  _start(): () => void\n  _notify(): void\n  _dispose(): void\n}\n\nfunction Effect(this: Effect, compute: () => unknown | EffectCleanup) {\n  this._compute = compute\n  this._cleanup = undefined\n  this._sources = undefined\n  this._nextBatchedEffect = undefined\n  this._flags = TRACKING\n}\n\nEffect.prototype._callback = function () {\n  const finish = this._start()\n  try {\n    if (this._flags & DISPOSED) return\n    if (this._compute === undefined) return\n\n    const cleanup = this._compute()\n    if (typeof cleanup === 'function') {\n      this._cleanup = cleanup as EffectCleanup\n    }\n  } finally {\n    finish()\n  }\n}\n\nEffect.prototype._start = function () {\n  if (this._flags & RUNNING) {\n    cycleDetected()\n  }\n  this._flags |= RUNNING\n  this._flags &= ~DISPOSED\n  cleanupEffect(this)\n  prepareSources(this)\n\n  /*@__INLINE__**/ startBatch()\n  const prevContext = evalContext\n  evalContext = this\n  return endEffect.bind(this, prevContext)\n}\n\nEffect.prototype._notify = function () {\n  if (!(this._flags & NOTIFIED)) {\n    this._flags |= NOTIFIED\n    this._nextBatchedEffect = batchedEffect\n    batchedEffect = this\n  }\n}\n\nEffect.prototype._dispose = function () {\n  this._flags |= DISPOSED\n\n  if (!(this._flags & RUNNING)) {\n    disposeEffect(this)\n  }\n}\n\nfunction effect(compute: () => unknown | EffectCleanup): () => void {\n  const effect = new Effect(compute)\n  try {\n    effect._callback()\n  } catch (err) {\n    effect._dispose()\n    throw err\n  }\n  // Return a bound function instead of a wrapper like `() => effect._dispose()`,\n  // because bound functions seem to be just as fast and take up a lot less memory.\n  return effect._dispose.bind(effect)\n}\n\nexport { Signal, batch, computed, effect, signal, untracked }\nexport type { ReadonlySignal }\n","// From https://github.com/EthanStandel/deepsignal/blob/main/packages/core/src/core.ts\nimport { Signal, batch, signal } from './preact-core'\n\nexport type AtomicState =\n  | Array<unknown>\n  | ((...args: unknown[]) => unknown)\n  | string\n  | boolean\n  | number\n  | bigint\n  | symbol\n  | undefined\n  | null\n\nexport type DeepState = {\n  [key: string]: (() => unknown) | AtomicState | DeepState\n}\n\nexport type ReadOnlyDeep<T> = {\n  readonly [P in keyof T]: ReadOnlyDeep<T[P]>\n}\n\nexport interface DeepSignalAccessors<T extends DeepState> {\n  value: ReadOnlyDeep<T>\n  peek: () => ReadOnlyDeep<T>\n}\n\nexport type DeepSignalType<T extends DeepState> = DeepSignalAccessors<T> & {\n  [K in keyof T]: T[K] extends AtomicState ? Signal<T[K]> : T[K] extends DeepState ? DeepSignalType<T[K]> : Signal<T[K]>\n}\n\nexport class DeepSignal<T extends DeepState> implements DeepSignalAccessors<T> {\n  get value(): ReadOnlyDeep<T> {\n    return getValue(this as DeepSignalType<T>)\n  }\n\n  set value(payload: ReadOnlyDeep<T>) {\n    batch(() => setValue(this as DeepSignalType<T>, payload))\n  }\n\n  peek(): ReadOnlyDeep<T> {\n    return getValue(this as DeepSignalType<T>, { peek: true })\n  }\n}\n\nexport const deepSignal = <T extends DeepState>(initialValue: T): DeepSignalType<T> =>\n  Object.assign(\n    new DeepSignal(),\n    Object.entries(initialValue).reduce(\n      (acc, [key, value]) => {\n        if (['value', 'peek'].some((iKey) => iKey === key)) {\n          throw new Error(`${key} is a reserved property name`)\n        } else if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n          acc[key] = signal(value)\n        } else {\n          acc[key] = deepSignal(value)\n        }\n        return acc\n      },\n      {} as { [key: string]: unknown },\n    ),\n  ) as DeepSignalType<T>\n\nconst setValue = <U extends DeepState, T extends DeepSignalType<U>>(deepSignal: T, payload: U): void =>\n  Object.keys(payload).forEach((key: keyof U) => (deepSignal[key].value = payload[key]))\n\nconst getValue = <U extends DeepState, T extends DeepSignalType<U>>(\n  deepSignal: T,\n  { peek = false }: { peek?: boolean } = {},\n): ReadOnlyDeep<U> =>\n  Object.entries(deepSignal).reduce(\n    (acc, [key, value]) => {\n      if (value instanceof Signal) {\n        acc[key] = peek ? value.peek() : value.value\n      } else if (value instanceof DeepSignal) {\n        acc[key] = getValue(value as DeepSignalType<DeepState>, { peek })\n      }\n      return acc\n    },\n    {} as { [key: string]: unknown },\n  ) as ReadOnlyDeep<U>\n","// From https://github.com/riagominota/ts-merge-patch/blob/main/src/index.ts\n\ntype mpObj<T> = { [k in keyof T | string | number | symbol]: any }\nexport function apply<L, R>(target: mpObj<L>, patchItem: mpObj<R>): Partial<L> & Partial<R>\nexport function apply<L, R>(target: mpObj<L>, patchItem: mpObj<R>): R\nexport function apply<L, R>(target: mpObj<L>, patchItem: mpObj<R>): {}\nexport function apply<L, R>(target: mpObj<L>, patchItem: null): null\nexport function apply<L, R>(target: mpObj<L>, patchItem: string): string\nexport function apply<L, R>(target: mpObj<L>, patchItem: number): number\nexport function apply<L, R>(target: mpObj<L>, patchItem: undefined): undefined\nexport function apply<L, R>(target: mpObj<L>, patchItem: R[]): R[]\n\nexport function apply(target: any, patchItem: any): any {\n  /**\n   * If the patch is anything other than an object,\n   * the result will always be to replace\n   * the entire target with the entire patch.\n   */\n  if (typeof patchItem !== 'object' || Array.isArray(patchItem) || !patchItem) {\n    return patchItem //return new instance of variable\n  }\n\n  if (typeof patchItem === 'object' && patchItem.toJSON !== undefined && typeof patchItem.toJSON === 'function') {\n    return patchItem.toJSON()\n  }\n  /** Also, it is not possible to\n   * patch part of a target that is not an object,\n   * such as to replace just some of the values in an array.\n   */\n  let targetResult = target\n  if (typeof target !== 'object') {\n    //Target is empty/not an object, so basically becomes patch, minus any null valued sections (becomes {} + patch)\n    targetResult = { ...patchItem }\n  }\n\n  Object.keys(patchItem).forEach((k) => {\n    if (!targetResult.hasOwnProperty(k)) targetResult[k] = patchItem[k] //This ensure the key exists and TS can't throw a wobbly over an undefined key\n    if (patchItem[k] === null) {\n      delete targetResult[k]\n    } else {\n      targetResult[k] = apply(targetResult[k], patchItem[k])\n    }\n  })\n  return targetResult\n}\n","import { DeepState } from './external/deepsignal'\nimport { ReadonlySignal, Signal } from './external/preact-core'\n\nexport type HTMLorSVGElement = Element & (HTMLElement | SVGElement)\n\nexport type DatastarPlugin = {}\n\nexport type ExpressionFunction = (ctx: AttributeContext, ...args: any) => any\nexport type Reactivity = {\n  signal: <T>(value: T) => Signal<T>\n  computed: <T>(fn: () => T) => ReadonlySignal<T>\n  effect: (cb: () => void) => OnRemovalFn\n}\n\nexport type AttributeContext = {\n  store: () => any\n  mergeStore: (store: DeepState) => void\n  upsertIfMissingFromStore: (path: string, value: any) => void\n  removeFromStore: (...paths: string[]) => void\n  applyPlugins: (target: Element) => void\n  walkSignals: (cb: (name: string, signal: Signal<any>) => void) => void\n  cleanupElementRemovals: (el: Element) => void\n  actions: Readonly<Actions>\n  reactivity: Reactivity\n  el: Readonly<HTMLorSVGElement>\n  key: Readonly<string>\n  rawKey: Readonly<string>\n  rawExpression: Readonly<string>\n  expression: Readonly<string>\n  expressionFn: ExpressionFunction\n  modifiers: Map<string, string[]>\n  sendDatastarEvent: SendDatastarEvent\n}\n\nexport type SendDatastarEvent = (\n  category: 'core' | 'plugin',\n  subcategory: string,\n  type: string,\n  target: Element | Document | Window | string,\n  message: string,\n  opts: CustomEventInit,\n) => void\n\nexport type InitContext = {\n  store: any\n  mergeStore: (store: DeepState) => void\n  actions: Readonly<Actions>\n  reactivity: Reactivity\n}\n\nexport type OnRemovalFn = () => void\nexport type AttributePlugin = {\n  prefix: string // The prefix of the `data-${prefix}` attribute\n  requiredPluginPrefixes?: Iterable<string> // If not provided, no plugins are required\n  onGlobalInit?: (ctx: InitContext) => void // Called once on registration of the plugin\n  onLoad: (ctx: AttributeContext) => OnRemovalFn | void // Return a function to be called on removal\n  allowedModifiers?: Set<string> // If not provided, all modifiers are allowed\n  mustHaveEmptyExpression?: boolean // The contents of the data-* attribute must be empty\n  mustNotEmptyExpression?: boolean // The contents of the data-* attribute must not be empty\n  mustHaveEmptyKey?: boolean // The key of the data-* attribute must be empty after the prefix\n  mustNotEmptyKey?: boolean // The key of the data-* attribute must not be empty after the prefix\n  allowedTagRegexps?: Set<string> // If not provided, all tags are allowed\n  disallowedTags?: Set<string> // If not provided, no tags are disallowed\n  preprocessors?: {\n    pre?: Preprocessor[]\n    post?: Preprocessor[]\n  }\n  removeNewLines?: boolean // If true, the expression is not split by commas\n  bypassExpressionFunctionCreation?: (ctx: AttributeContext) => boolean // If true, the expression function is not created\n  argumentNames?: Readonly<string[]> // The names of the arguments passed to the expression function\n}\n\nexport type RegexpGroups = Record<string, string>\nexport type Preprocessor = {\n  regexp: RegExp\n  replacer: (groups: RegexpGroups) => string\n}\n\nexport type Action = (ctx: AttributeContext, ...args: any[]) => any\nexport type Actions = Record<string, Action>\n\nexport const datastarEventName = 'datastar-event'\nexport interface DatastarEvent {\n  time: Date\n  category: 'core' | 'plugin'\n  subcategory: string\n  type: string\n  target: string\n  message: string\n}\n","import { DATASTAR_STR } from '../engine'\nimport {\n  AttributeContext,\n  AttributePlugin,\n  DatastarEvent,\n  datastarEventName,\n  Preprocessor,\n  RegexpGroups,\n} from '../types'\n\nconst validJSIdentifier = `[a-zA-Z_$]+`\nconst validNestedJSIdentifier = validJSIdentifier + `[0-9a-zA-Z_$.]*`\nfunction wholePrefixSuffix(rune: string, prefix: string, suffix: string, nestable = true) {\n  const identifier = nestable ? validNestedJSIdentifier : validJSIdentifier\n  return new RegExp(`(?<whole>\\\\${rune}(?<${prefix}>${identifier})${suffix})`, `g`)\n}\n\n// Replacing $signal with ctx.store.signal.value`\nconst SignalProcessor: Preprocessor = {\n  regexp: wholePrefixSuffix('$', 'signal', '(?<method>\\\\([^\\\\)]*\\\\))?'),\n  replacer: (groups: RegexpGroups) => {\n    const { signal, method } = groups\n    const prefix = `ctx.store()`\n    if (!method?.length) {\n      return `${prefix}.${signal}.value`\n    }\n    const parts = signal.split('.')\n    const methodName = parts.pop()\n    const nestedSignal = parts.join('.')\n    return `${prefix}.${nestedSignal}.value.${methodName}${method}`\n  },\n}\n\n// Replacing $$action(args) with ctx.actions.action(ctx, args)\nconst ActionProcessor: Preprocessor = {\n  regexp: wholePrefixSuffix('$\\\\$', 'action', '(?<call>\\\\((?<args>.*)\\\\))?'),\n  replacer: ({ action, args }: RegexpGroups) => {\n    const withCtx = [`ctx`]\n    if (args) {\n      withCtx.push(...args.split(',').map((x) => x.trim()))\n    }\n    const argsJoined = withCtx.join(',')\n    return `ctx.actions.${action}(${argsJoined})`\n  },\n}\n\n// Replacing ~foo with ctx.refs.foo\nconst RefProcessor: Preprocessor = {\n  regexp: wholePrefixSuffix('~', 'ref', '', false),\n  replacer({ ref }: RegexpGroups) {\n    return `document.querySelector(ctx.store()._dsPlugins.refs.${ref})`\n  },\n}\n\nexport const CorePreprocessors: Preprocessor[] = [ActionProcessor, SignalProcessor, RefProcessor]\n\n// Setup the global store\nconst StoreAttributePlugin: AttributePlugin = {\n  prefix: 'store',\n  removeNewLines: true,\n  preprocessors: {\n    pre: [\n      {\n        regexp: /(?<whole>.+)/g,\n        replacer: (groups: RegexpGroups) => {\n          const { whole } = groups\n          return `Object.assign({...ctx.store()}, ${whole})`\n        },\n      },\n    ],\n  },\n  allowedModifiers: new Set(['local', 'session', 'ifmissing']),\n  onLoad: (ctx: AttributeContext) => {\n    let lastCachedMarshalled = ``\n    const localFn = ((_: CustomEvent<DatastarEvent>) => {\n      const s = ctx.store()\n      const marshalledStore = JSON.stringify(s)\n\n      if (marshalledStore !== lastCachedMarshalled) {\n        window.localStorage.setItem(DATASTAR_STR, marshalledStore)\n        lastCachedMarshalled = marshalledStore\n      }\n    }) as EventListener\n    const hasLocal = ctx.modifiers.has('local')\n    if (hasLocal) {\n      window.addEventListener(datastarEventName, localFn)\n      const marshalledStore = window.localStorage.getItem(DATASTAR_STR) || '{}'\n      const store = JSON.parse(marshalledStore)\n      ctx.mergeStore(store)\n    }\n\n    const hasSession = ctx.modifiers.has('session')\n    const sessionFn = ((_: CustomEvent<DatastarEvent>) => {\n      const s = ctx.store()\n      const marshalledStore = JSON.stringify(s)\n      window.sessionStorage.setItem(DATASTAR_STR, marshalledStore)\n    }) as EventListener\n    if (hasSession) {\n      window.addEventListener(datastarEventName, sessionFn)\n      const marshalledStore = window.sessionStorage.getItem(DATASTAR_STR) || '{}'\n      const store = JSON.parse(marshalledStore)\n      ctx.mergeStore(store)\n    }\n\n    const possibleMergeStore = ctx.expressionFn(ctx)\n    const actualMergeStore = storeFromPossibleContents(ctx.store(), possibleMergeStore, ctx.modifiers.has('ifmissing'))\n    ctx.mergeStore(actualMergeStore)\n\n    delete ctx.el.dataset[ctx.rawKey]\n\n    return () => {\n      if (hasLocal) {\n        window.removeEventListener(datastarEventName, localFn)\n      }\n\n      if (hasSession) {\n        window.removeEventListener(datastarEventName, sessionFn)\n      }\n    }\n  },\n}\n\nconst ComputedPlugin: AttributePlugin = {\n  prefix: 'computed',\n  mustNotEmptyKey: true,\n  onLoad: (ctx: AttributeContext) => {\n    const store = ctx.store()\n    store[ctx.key] = ctx.reactivity.computed(() => {\n      return ctx.expressionFn(ctx)\n    })\n\n    return () => {\n      const store = ctx.store()\n      delete store[ctx.key]\n    }\n  },\n}\n\n// Sets the value of the element\nconst RefPlugin: AttributePlugin = {\n  prefix: 'ref',\n  mustHaveEmptyKey: true,\n  mustNotEmptyExpression: true,\n  bypassExpressionFunctionCreation: () => true,\n  onLoad: (ctx: AttributeContext) => {\n    ctx.upsertIfMissingFromStore('_dsPlugins.refs', {})\n    const { el, expression } = ctx\n    const s = ctx.store()\n\n    const revised = {\n      _dsPlugins: {\n        refs: {\n          ...s._dsPlugins.refs.value,\n          [expression]: elemToSelector(el),\n        },\n      },\n    }\n    ctx.mergeStore(revised)\n\n    return () => {\n      const s = ctx.store()\n      const revised = { ...s._dsPlugins.refs.value }\n      delete revised[expression]\n      s._dsPlugins.refs = revised\n    }\n  },\n}\n\nexport const CorePlugins: AttributePlugin[] = [StoreAttributePlugin, ComputedPlugin, RefPlugin]\nexport function elemToSelector(elm: Element | Window | Document | string | null) {\n  if (!elm) return 'null'\n  if (typeof elm === 'string') return elm\n  if (elm instanceof Window) return 'Window'\n  if (elm instanceof Document) return 'Document'\n\n  if (elm.tagName === 'BODY') return 'BODY'\n  const names = []\n  while (elm.parentElement && elm.tagName !== 'BODY') {\n    if (elm.id) {\n      names.unshift('#' + elm.getAttribute('id')) // getAttribute, because `elm.id` could also return a child element with name \"id\"\n      break // Because ID should be unique, no more is needed. Remove the break, if you always want a full path.\n    } else {\n      let c = 1,\n        e = elm\n      for (; e.previousElementSibling; e = e.previousElementSibling, c++);\n      names.unshift(elm.tagName + ':nth-child(' + c + ')')\n    }\n    elm = elm.parentElement\n  }\n  return names.join('>')\n}\n\nexport function storeFromPossibleContents(currentStore: any, contents: any, hasIfMissing: boolean) {\n  const actual: any = {}\n\n  if (!hasIfMissing) {\n    Object.assign(actual, contents)\n  } else {\n    for (const key in contents) {\n      const currentValue = currentStore[key]?.value\n      if (currentValue === undefined || currentValue === null) {\n        actual[key] = contents[key]\n      }\n    }\n  }\n\n  return actual\n}\n","import { sendDatastarEvent } from '.'\nimport { toHTMLorSVGElement } from './dom'\nimport { DeepSignal, deepSignal, DeepState } from './external/deepsignal'\nimport { computed, effect, Signal, signal } from './external/preact-core'\nimport { apply } from './external/ts-merge-patch'\nimport { CorePlugins, CorePreprocessors } from './plugins/core'\nimport {\n  Actions,\n  AttributeContext,\n  AttributePlugin,\n  ExpressionFunction,\n  HTMLorSVGElement,\n  OnRemovalFn,\n  Preprocessor,\n  Reactivity,\n} from './types'\n\nexport const DATASTAR_STR = 'datastar'\nexport const DATASTAR_CLASS_PREFIX = `${DATASTAR_STR}-`\n\nexport class Datastar {\n  plugins: AttributePlugin[] = []\n  store: DeepSignal<any> = deepSignal({ _dsPlugins: {} })\n  actions: Actions = {}\n  refs: Record<string, HTMLElement> = {}\n  reactivity: Reactivity = {\n    signal,\n    computed,\n    effect,\n  }\n  parentID = ''\n  missingIDNext = 0\n  removals = new Map<Element, { id: string; set: Set<OnRemovalFn> }>()\n  mergeRemovals = new Array<OnRemovalFn>()\n\n  constructor(actions: Actions = {}, ...plugins: AttributePlugin[]) {\n    this.actions = Object.assign(this.actions, actions)\n    plugins = [...CorePlugins, ...plugins]\n    if (!plugins.length) throw new Error('No plugins provided')\n\n    const allPluginPrefixes = new Set<string>()\n    for (const p of plugins) {\n      if (p.requiredPluginPrefixes) {\n        for (const requiredPluginType of p.requiredPluginPrefixes) {\n          if (!allPluginPrefixes.has(requiredPluginType)) {\n            throw new Error(`${p.prefix} requires ${requiredPluginType}`)\n          }\n        }\n      }\n\n      this.plugins.push(p)\n      allPluginPrefixes.add(p.prefix)\n    }\n  }\n\n  run() {\n    const observer = new MutationObserver((_mutationList, _observer) => {\n      sendDatastarEvent('core', 'dom', 'mutation', document.body, document.body.outerHTML)\n    })\n\n    // Start observing the target node for configured mutations\n    observer.observe(document.body, {\n      attributes: true,\n      childList: true,\n      subtree: true,\n    })\n\n    this.plugins.forEach((p) => {\n      if (p.onGlobalInit) {\n        p.onGlobalInit({\n          actions: this.actions,\n          reactivity: this.reactivity,\n          mergeStore: this.mergeStore.bind(this),\n          store: this.store,\n        })\n        sendDatastarEvent('core', 'plugins', 'registration', 'BODY', `On prefix ${p.prefix}`)\n      }\n    })\n\n    this.applyPlugins(document.body)\n  }\n\n  private cleanupElementRemovals(element: Element) {\n    const removalSet = this.removals.get(element)\n    if (removalSet) {\n      for (const removal of removalSet.set) {\n        removal()\n      }\n      this.removals.delete(element)\n    }\n  }\n\n  private mergeStore<T extends object>(patchStore: T) {\n    this.mergeRemovals.forEach((removal) => removal())\n    this.mergeRemovals = this.mergeRemovals.slice(0)\n\n    const revisedStore = apply(this.store.value, patchStore) as DeepState\n    this.store = deepSignal(revisedStore)\n    this.mergeRemovals.push(\n      this.reactivity.effect(() => {\n        sendDatastarEvent('core', 'store', 'merged', 'STORE', JSON.stringify(this.store.value))\n      }),\n    )\n  }\n\n  private removeFromStore(...keys: string[]) {\n    const revisedStore = { ...this.store.value }\n    for (const key of keys) {\n      const parts = key.split('.')\n      let currentID = parts[0]\n      let subStore = revisedStore\n      for (let i = 1; i < parts.length; i++) {\n        const part = parts[i]\n        if (!subStore[currentID]) {\n          subStore[currentID] = {}\n        }\n        subStore = subStore[currentID]\n        currentID = part\n      }\n      delete subStore[currentID]\n    }\n    this.store = deepSignal(revisedStore)\n    this.applyPlugins(document.body)\n  }\n\n  private upsertIfMissingFromStore(path: string, value: any) {\n    const parts = path.split('.')\n    let subStore = this.store as any\n    for (let i = 0; i < parts.length - 1; i++) {\n      const part = parts[i]\n      if (!subStore[part]) {\n        subStore[part] = {}\n      }\n      subStore = subStore[part]\n    }\n    const last = parts[parts.length - 1]\n    if (!!subStore[last]) return\n    subStore[last] = this.reactivity.signal(value)\n    sendDatastarEvent('core', 'store', 'upsert', path, value)\n  }\n\n  signalByName<T>(name: string) {\n    return (this.store as any)[name] as Signal<T>\n  }\n\n  private applyPlugins(rootElement: Element) {\n    const appliedProcessors = new Set<Preprocessor>()\n\n    this.plugins.forEach((p, pi) => {\n      this.walkDownDOM(rootElement, (el) => {\n        if (!pi) this.cleanupElementRemovals(el)\n\n        for (const rawKey in el.dataset) {\n          const rawExpression = el.dataset[rawKey] || ''\n          let expression = rawExpression\n\n          if (!rawKey.startsWith(p.prefix)) continue\n\n          if (el.id.length === 0) {\n            el.id = `ds-${this.parentID}-${this.missingIDNext++}`\n          }\n\n          appliedProcessors.clear()\n\n          if (p.allowedTagRegexps) {\n            const lowerCaseTag = el.tagName.toLowerCase()\n            const allowed = [...p.allowedTagRegexps].some((r) => lowerCaseTag.match(r))\n            if (!allowed) {\n              throw new Error(\n                `'${el.tagName}' not allowed for '${rawKey}', allowed ${[\n                  [...p.allowedTagRegexps].map((t) => `'${t}'`),\n                ].join(', ')}`,\n              )\n            }\n            // console.log(`Tag '${el.tagName}' is allowed for plugin '${dsKey}'`)\n          }\n\n          let keyRaw = rawKey.slice(p.prefix.length)\n          let [key, ...modifiersWithArgsArr] = keyRaw.split('.')\n          if (p.mustHaveEmptyKey && key.length > 0) {\n            throw new Error(`'${rawKey}' must have empty key`)\n          }\n          if (p.mustNotEmptyKey && key.length === 0) {\n            throw new Error(`'${rawKey}' must have non-empty key`)\n          }\n          if (key.length) {\n            key = key[0].toLowerCase() + key.slice(1)\n          }\n\n          const modifiersArr = modifiersWithArgsArr.map((m) => {\n            const [label, ...args] = m.split('_')\n            return { label, args }\n          })\n          if (p.allowedModifiers) {\n            for (const modifier of modifiersArr) {\n              if (!p.allowedModifiers.has(modifier.label)) {\n                throw new Error(`'${modifier.label}' is not allowed`)\n              }\n            }\n          }\n          const modifiers = new Map<string, string[]>()\n          for (const modifier of modifiersArr) {\n            modifiers.set(modifier.label, modifier.args)\n          }\n\n          if (p.mustHaveEmptyExpression && expression.length) {\n            throw new Error(`'${rawKey}' must have empty expression`)\n          }\n          if (p.mustNotEmptyExpression && !expression.length) {\n            throw new Error(`'${rawKey}' must have non-empty expression`)\n          }\n\n          const splitRegex = /;|\\n/\n\n          if (p.removeNewLines) {\n            expression = expression\n              .split('\\n')\n              .map((p) => p.trim())\n              .join(' ')\n          }\n\n          const processors = [...(p.preprocessors?.pre || []), ...CorePreprocessors, ...(p.preprocessors?.post || [])]\n          for (const processor of processors) {\n            if (appliedProcessors.has(processor)) continue\n            appliedProcessors.add(processor)\n\n            const expressionParts = expression.split(splitRegex)\n            const revisedParts: string[] = []\n\n            expressionParts.forEach((exp) => {\n              let revised = exp\n              const matches = [...revised.matchAll(processor.regexp)]\n              if (matches.length) {\n                for (const match of matches) {\n                  if (!match.groups) continue\n                  const { groups } = match\n                  const { whole } = groups\n                  revised = revised.replace(whole, processor.replacer(groups))\n                }\n              }\n              revisedParts.push(revised)\n            })\n            // })\n\n            expression = revisedParts.join('; ')\n          }\n\n          const ctx: AttributeContext = {\n            store: () => this.store,\n            mergeStore: this.mergeStore.bind(this),\n            upsertIfMissingFromStore: this.upsertIfMissingFromStore.bind(this),\n            removeFromStore: this.removeFromStore.bind(this),\n            applyPlugins: this.applyPlugins.bind(this),\n            cleanupElementRemovals: this.cleanupElementRemovals.bind(this),\n            walkSignals: this.walkSignals.bind(this),\n            actions: this.actions,\n            reactivity: this.reactivity,\n            el,\n            rawKey,\n            key,\n            rawExpression,\n            expression,\n            expressionFn: () => {\n              throw new Error('Expression function not created')\n            },\n            modifiers,\n            sendDatastarEvent,\n          }\n\n          if (!p.bypassExpressionFunctionCreation?.(ctx) && !p.mustHaveEmptyExpression && expression.length) {\n            const statements = expression\n              .split(splitRegex)\n              .map((s) => s.trim())\n              .filter((s) => s.length)\n            statements[statements.length - 1] = `return ${statements[statements.length - 1]}`\n            const joined = statements.map((s) => `  ${s}`).join(';\\n')\n            const fnContent = `\ntry {\n  const _datastarExpression = () => {\n${joined}\n  }\n  const _datastarReturnVal = _datastarExpression()\n  ctx.sendDatastarEvent('core', 'attributes', 'expr_eval', ctx.el, '${rawKey} equals ' + JSON.stringify(_datastarReturnVal))\n  return _datastarReturnVal\n} catch (e) {\n const msg = \\`\nError evaluating Datastar expression:\n${joined.replaceAll('`', '\\\\`')}\n\nError: \\${e.message}\n\nCheck if the expression is valid before raising an issue.\n\\`.trim()\n ctx.sendDatastarEvent('core', 'attributes', 'expr_eval_err', ctx.el, msg)\n console.error(msg)\n debugger\n}\n            `\n\n            /*sendDatastarEvent(\n              'core',\n              'attributes',\n              'expr_construction',\n              ctx.el,\n              `${rawKey}=\"${rawExpression}\" becomes: ${joined}`,\n            )*/\n            try {\n              const argumentNames = p.argumentNames || []\n              const fn = new Function('ctx', ...argumentNames, fnContent) as ExpressionFunction\n              ctx.expressionFn = fn\n            } catch (e) {\n              const err = new Error(`Error creating expression function for '${fnContent}', error: ${e}`)\n              sendDatastarEvent('core', 'attributes', 'expr_construction_err', ctx.el, String(err))\n              console.error(err)\n              debugger\n            }\n          }\n\n          const removal = p.onLoad(ctx)\n          if (removal) {\n            if (!this.removals.has(el)) {\n              this.removals.set(el, { id: el.id, set: new Set() })\n            }\n            this.removals.get(el)!.set.add(removal)\n          }\n        }\n      })\n    })\n  }\n\n  private walkSignalsStore(store: any, callback: (name: string, signal: Signal<any>) => void) {\n    const keys = Object.keys(store)\n    for (let i = 0; i < keys.length; i++) {\n      const key = keys[i]\n      const value = store[key]\n      const isSignal = value instanceof Signal\n      const hasChildren = typeof value === 'object' && Object.keys(value).length > 0\n\n      if (isSignal) {\n        callback(key, value)\n        continue\n      }\n\n      if (!hasChildren) continue\n\n      this.walkSignalsStore(value, callback)\n    }\n  }\n\n  private walkSignals(callback: (name: string, signal: Signal<any>) => void) {\n    this.walkSignalsStore(this.store, callback)\n  }\n\n  private walkDownDOM(element: Element | null, callback: (el: HTMLorSVGElement) => void, siblingOffset = 0) {\n    if (!element) return\n    const el = toHTMLorSVGElement(element)\n    if (!el) return\n\n    callback(el)\n\n    siblingOffset = 0\n    element = element.firstElementChild\n    while (element) {\n      this.walkDownDOM(element, callback, siblingOffset++)\n      element = element.nextElementSibling\n    }\n  }\n}\n","import { sendDatastarEvent } from '..'\nimport { Actions, AttributeContext, AttributePlugin, RegexpGroups } from '../types'\n\nconst kebabize = (str: string) => str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, ($, ofs) => (ofs ? '-' : '') + $.toLowerCase())\n\n// Sets the value of the element\nexport const BindAttributePlugin: AttributePlugin = {\n  prefix: 'bind',\n  mustNotEmptyKey: true,\n  mustNotEmptyExpression: true,\n\n  onLoad: (ctx: AttributeContext) => {\n    return ctx.reactivity.effect(async () => {\n      const key = kebabize(ctx.key)\n      const value = ctx.expressionFn(ctx)\n      let v: string\n      if (typeof value === 'string') {\n        v = value\n      } else {\n        v = JSON.stringify(value)\n      }\n      if (!v || v === 'false' || v === 'null' || v === 'undefined') {\n        ctx.el.removeAttribute(key)\n      } else {\n        ctx.el.setAttribute(key, v)\n      }\n    })\n  },\n}\n\nconst dataURIRegex = /^data:(?<mime>[^;]+);base64,(?<contents>.*)$/\nconst updateModelEvents = ['change', 'input', 'keydown']\n\n// Sets the value of the element\nexport const TwoWayBindingModelPlugin: AttributePlugin = {\n  prefix: 'model',\n  mustHaveEmptyKey: true,\n  preprocessors: {\n    post: [\n      {\n        regexp: /(?<whole>.+)/g,\n        replacer: (groups: RegexpGroups) => {\n          const { whole } = groups\n          return `ctx.store().${whole}`\n        },\n      },\n    ],\n  },\n  // bypassExpressionFunctionCreation: () => true,\n  onLoad: (ctx: AttributeContext) => {\n    const { el, expression } = ctx\n    const signal = ctx.expressionFn(ctx)\n    const tnl = el.tagName.toLowerCase()\n\n    if (expression.startsWith('ctx.store().ctx.store()')) {\n      throw new Error(`Model attribute on #${el.id} must have a signal name, you probably prefixed with $ by accident`)\n    }\n\n    const isInput = tnl.includes('input')\n    const type = el.getAttribute('type')\n    const isCheckbox = tnl.includes('checkbox') || (isInput && type === 'checkbox')\n    const isSelect = tnl.includes('select')\n    const isRadio = tnl.includes('radio') || (isInput && type === 'radio')\n    const isFile = isInput && type === 'file'\n\n    const signalName = expression.replaceAll('ctx.store().', '')\n    if (isRadio) {\n      const name = el.getAttribute('name')\n      if (!name?.length) {\n        el.setAttribute('name', signalName)\n      }\n    }\n\n    const setInputFromSignal = () => {\n      if (!signal) {\n        throw new Error(`Signal ${signalName} not found`)\n      }\n      const hasValue = 'value' in el\n      const v = signal.value\n      if (isCheckbox || isRadio) {\n        const input = el as HTMLInputElement\n        if (isCheckbox) {\n          input.checked = v\n        } else if (isRadio) {\n          // evaluate the value as string to handle any type casting\n          // automatically since the attribute has to be a string anyways\n          input.checked = `${v}` === input.value\n        }\n      } else if (isFile) {\n        // File input reading from a signal is not supported yet\n      } else if (isSelect) {\n        const select = el as HTMLSelectElement\n        if (select.multiple) {\n          const v = signal.value\n          Array.from(select.options).forEach((opt) => {\n            if (opt?.disabled) return\n            opt.selected = v.includes(opt.value)\n          })\n        } else {\n          select.value = `${v}`\n        }\n      } else if (hasValue) {\n        el.value = `${v}`\n      } else {\n        el.setAttribute('value', `${v}`)\n      }\n    }\n    const cleanupSetInputFromSignal = ctx.reactivity.effect(setInputFromSignal)\n\n    const setSignalFromInput = async () => {\n      if (isFile) {\n        const files = [...((el as HTMLInputElement)?.files || [])],\n          allContents: string[] = [],\n          allMimes: string[] = [],\n          allNames: string[] = []\n\n        await Promise.all(\n          files.map((f) => {\n            return new Promise<void>((resolve) => {\n              const reader = new FileReader()\n              reader.onload = () => {\n                if (typeof reader.result !== 'string') {\n                  throw new Error(`Invalid result type: ${typeof reader.result}`)\n                }\n                const match = reader.result.match(dataURIRegex)\n                if (!match?.groups) {\n                  throw new Error(`Invalid data URI: ${reader.result}`)\n                }\n                allContents.push(match.groups.contents)\n                allMimes.push(match.groups.mime)\n                allNames.push(f.name)\n              }\n              reader.onloadend = () => resolve(void 0)\n              reader.readAsDataURL(f)\n            })\n          }),\n        )\n\n        signal.value = allContents\n        const s = ctx.store()\n        const mimeName = `${signalName}Mimes`,\n          nameName = `${signalName}Names`\n        if (mimeName in s) {\n          s[`${mimeName}`].value = allMimes\n        }\n        if (nameName in s) {\n          s[`${nameName}`].value = allNames\n        }\n        return\n      }\n\n      const current = signal.value\n      const input = (el as HTMLInputElement) || (el as HTMLElement)\n\n      if (typeof current === 'number') {\n        signal.value = Number(input.value || input.getAttribute('value'))\n      } else if (typeof current === 'string') {\n        signal.value = input.value || input.getAttribute('value') || ''\n      } else if (typeof current === 'boolean') {\n        if (isCheckbox) {\n          signal.value = input.checked || input.getAttribute('checked') === 'true'\n        } else {\n          signal.value = Boolean(input.value || input.getAttribute('value'))\n        }\n      } else if (typeof current === 'undefined') {\n      } else if (typeof current === 'bigint') {\n        signal.value = BigInt(input.value || input.getAttribute('value') || '0')\n      } else if (Array.isArray(current)) {\n        // check if the input is a select element\n        if (isSelect) {\n          const select = el as HTMLSelectElement\n          const selectedOptions = [...select.selectedOptions]\n          const selectedValues = selectedOptions.map((opt) => opt.value)\n          signal.value = selectedValues\n        } else {\n          signal.value = JSON.parse(input.value).split(',')\n        }\n        console.log(input.value)\n      } else {\n        console.log(typeof current)\n        throw new Error(`Unsupported type ${typeof current} for signal ${signalName}`)\n      }\n    }\n\n    const parts = el.tagName.split('-')\n    const isCustomElement = parts.length > 1\n    if (isCustomElement) {\n      const customElementPrefix = parts[0].toLowerCase()\n      updateModelEvents.forEach((eventType) => {\n        updateModelEvents.push(`${customElementPrefix}-${eventType}`)\n      })\n    }\n\n    updateModelEvents.forEach((eventType) => el.addEventListener(eventType, setSignalFromInput))\n\n    return () => {\n      cleanupSetInputFromSignal()\n      updateModelEvents.forEach((event) => el.removeEventListener(event, setSignalFromInput))\n    }\n  },\n}\n\n// Sets the textContent of the element\nexport const TextPlugin: AttributePlugin = {\n  prefix: 'text',\n  mustHaveEmptyKey: true,\n\n  onLoad: (ctx: AttributeContext) => {\n    const { el, expressionFn } = ctx\n    if (!(el instanceof HTMLElement)) {\n      throw new Error('Element is not HTMLElement')\n    }\n    return ctx.reactivity.effect(() => {\n      const res = expressionFn(ctx)\n      el.textContent = `${res}`\n    })\n  },\n}\n\nlet lastStoreMarshalled = ''\n\nconst knownOnModifiers = new Set(['window', 'once', 'passive', 'capture', 'debounce', 'throttle', 'remote', 'outside'])\n\n// Sets the event listener of the element\nexport const EventPlugin: AttributePlugin = {\n  prefix: 'on',\n  mustNotEmptyKey: true,\n  mustNotEmptyExpression: true,\n  argumentNames: ['evt'],\n  onLoad: (ctx: AttributeContext) => {\n    const { el, key, expressionFn } = ctx\n\n    let target: Element | Window | Document = ctx.el\n    if (ctx.modifiers.get('window')) {\n      target = window\n    }\n\n    let callback = (evt?: Event) => {\n      sendDatastarEvent('plugin', 'event', key, target, 'triggered')\n      expressionFn(ctx, evt)\n    }\n\n    const debounceArgs = ctx.modifiers.get('debounce')\n    if (debounceArgs) {\n      const wait = argsToMs(debounceArgs)\n      const leading = argsHas(debounceArgs, 'leading', false)\n      const trailing = argsHas(debounceArgs, 'noTrail', true)\n      callback = debounce(callback, wait, leading, trailing)\n    }\n\n    const throttleArgs = ctx.modifiers.get('throttle')\n    if (throttleArgs) {\n      const wait = argsToMs(throttleArgs)\n      const leading = argsHas(throttleArgs, 'noLead', true)\n      const trailing = argsHas(throttleArgs, 'noTrail', false)\n      callback = throttle(callback, wait, leading, trailing)\n    }\n\n    const evtListOpts: AddEventListenerOptions = {\n      capture: true,\n      passive: false,\n      once: false,\n    }\n    if (!ctx.modifiers.has('capture')) evtListOpts.capture = false\n    if (ctx.modifiers.has('passive')) evtListOpts.passive = true\n    if (ctx.modifiers.has('once')) evtListOpts.once = true\n\n    const unknownModifierKeys = [...ctx.modifiers.keys()].filter((key) => !knownOnModifiers.has(key))\n\n    unknownModifierKeys.forEach((attrName) => {\n      const eventValues = ctx.modifiers.get(attrName) || []\n      const cb = callback\n      const revisedCallback = () => {\n        const evt = event as any\n        const attr = evt[attrName]\n        let valid: boolean\n\n        if (typeof attr === 'function') {\n          valid = attr(...eventValues)\n        } else if (typeof attr === 'boolean') {\n          valid = attr\n        } else if (typeof attr === 'string') {\n          const lowerAttr = attr.toLowerCase().trim()\n          const expr = eventValues.join('').toLowerCase().trim()\n          valid = lowerAttr === expr\n        } else {\n          const msg = `Invalid value for ${attrName} modifier on ${key} on ${el}`\n          console.error(msg)\n          debugger\n          throw new Error(msg)\n        }\n\n        if (valid) {\n          cb(evt)\n        }\n      }\n      callback = revisedCallback\n    })\n\n    const eventName = kebabize(key).toLowerCase()\n    switch (eventName) {\n      case 'load':\n        callback()\n        delete ctx.el.dataset.onLoad\n        return () => {}\n\n      case 'raf':\n        let rafId: number | undefined\n        const raf = () => {\n          callback()\n          rafId = requestAnimationFrame(raf)\n        }\n        rafId = requestAnimationFrame(raf)\n\n        return () => {\n          if (rafId) cancelAnimationFrame(rafId)\n        }\n\n      case 'store-change':\n        return ctx.reactivity.effect(() => {\n          const store = ctx.store()\n          let storeValue = store.value\n          if (ctx.modifiers.has('remote')) {\n            storeValue = remoteSignals(storeValue)\n          }\n          const current = JSON.stringify(storeValue)\n          if (lastStoreMarshalled !== current) {\n            lastStoreMarshalled = current\n            callback()\n          }\n        })\n\n      default:\n        const testOutside = ctx.modifiers.has('outside')\n        if (testOutside) {\n          target = document\n          const cb = callback\n          let called = false\n          const targetOutsideCallback = (e?: Event) => {\n            const targetHTML = e?.target as HTMLElement\n            if (!targetHTML) return\n            const isEl = el.id === targetHTML.id\n            if (isEl && called) {\n              called = false\n            }\n            if (!isEl && !called) {\n              cb(e)\n              called = true\n            }\n          }\n          callback = targetOutsideCallback\n        }\n\n        target.addEventListener(eventName, callback, evtListOpts)\n        return () => {\n          // console.log(`Removing event listener for ${eventName} on ${el}`)\n          target.removeEventListener(eventName, callback)\n        }\n    }\n  },\n}\n\nexport function remoteSignals(obj: Object): Object {\n  const res: Record<string, any> = {}\n\n  for (const [k, v] of Object.entries(obj)) {\n    if (k.startsWith('_')) {\n      continue\n    } else if (typeof v === 'object' && !Array.isArray(v)) {\n      res[k] = remoteSignals(v) // recurse\n    } else {\n      res[k] = v\n    }\n  }\n\n  return res\n}\n\nexport const ClassPlugin: AttributePlugin = {\n  prefix: 'class',\n  mustHaveEmptyKey: true,\n  mustNotEmptyExpression: true,\n\n  onLoad: (ctx: AttributeContext) => {\n    return ctx.reactivity.effect(() => {\n      const classes: Object = ctx.expressionFn(ctx)\n      for (const [k, v] of Object.entries(classes)) {\n        if (v) {\n          ctx.el.classList.add(k)\n        } else {\n          ctx.el.classList.remove(k)\n        }\n      }\n\n      return () => {\n        ctx.el.classList.remove(...Object.keys(classes))\n      }\n    })\n  },\n}\n\nexport const AttributePlugins: AttributePlugin[] = [\n  BindAttributePlugin,\n  TwoWayBindingModelPlugin,\n  TextPlugin,\n  EventPlugin,\n  ClassPlugin,\n]\n\nexport const AttributeActions: Actions = {\n  remote: async (ctx: AttributeContext) => {\n    return remoteSignals(ctx.store().value)\n  },\n}\n\nexport function argsToMs(args: string[] | undefined) {\n  if (!args || args?.length === 0) return 0\n\n  for (const arg of args) {\n    if (arg.endsWith('ms')) {\n      return Number(arg.replace('ms', ''))\n    } else if (arg.endsWith('s')) {\n      return Number(arg.replace('s', '')) * 1000\n    }\n\n    try {\n      return parseFloat(arg)\n    } catch (e) {}\n  }\n\n  return 0\n}\n\nexport function argsHas(args: string[] | undefined, arg: string, defaultValue = false) {\n  if (!args) return false\n  return args.includes(arg) || defaultValue\n}\n\ntype TimerHandler = (...args: any[]) => void\n\nfunction debounce(callback: TimerHandler, wait: number, leading = false, trailing = true): TimerHandler {\n  let timer: NodeJS.Timeout | undefined\n\n  const resetTimer = () => timer && clearTimeout(timer)\n\n  return function wrapper(...args: any[]) {\n    resetTimer()\n\n    if (leading && !timer) {\n      callback(...args)\n    }\n\n    timer = setTimeout(() => {\n      if (trailing) {\n        callback(...args)\n      }\n      resetTimer()\n    }, wait)\n  }\n}\n\nfunction throttle(callback: TimerHandler, wait: number, leading = true, trailing = false): TimerHandler {\n  let waiting = false\n\n  return function wrapper(...args: any[]) {\n    if (waiting) return\n\n    if (leading) {\n      callback(...args)\n    }\n\n    waiting = true\n    setTimeout(() => {\n      waiting = false\n      if (trailing) {\n        callback(...args)\n      }\n    }, wait)\n  }\n}\n","// From https://github.com/Azure/fetch-event-source\n\nexport interface FetchEventSourceInit extends RequestInit {\n  /**\n   * The request headers. FetchEventSource only supports the Record<string,string> format.\n   */\n  headers?: Record<string, string>\n\n  /**\n   * Called when a response is received. Use this to validate that the response\n   * actually matches what you expect (and throw if it doesn't.) If not provided,\n   * will default to a basic validation to ensure the content-type is text/event-stream.\n   */\n  onopen?: (response: Response) => Promise<void>\n\n  /**\n   * Called when a message is received. NOTE: Unlike the default browser\n   * EventSource.onmessage, this callback is called for _all_ events,\n   * even ones with a custom `event` field.\n   */\n  onmessage?: (ev: EventSourceMessage) => void\n\n  /**\n   * Called when a response finishes. If you don't expect the server to kill\n   * the connection, you can throw an exception here and retry using onerror.\n   */\n  onclose?: () => void\n\n  /**\n   * Called when there is any error making the request / processing messages /\n   * handling callbacks etc. Use this to control the retry strategy: if the\n   * error is fatal, rethrow the error inside the callback to stop the entire\n   * operation. Otherwise, you can return an interval (in milliseconds) after\n   * which the request will automatically retry (with the last-event-id).\n   * If this callback is not specified, or it returns undefined, fetchEventSource\n   * will treat every error as retriable and will try again after 1 second.\n   */\n  onerror?: (err: any) => number | null | undefined | void\n\n  /**\n   * If true, will keep the request open even if the document is hidden.\n   * By default, fetchEventSource will close the request and reopen it\n   * automatically when the document becomes visible again.\n   */\n  openWhenHidden?: boolean\n}\n\nexport function fetchEventSource(\n  url: URL,\n  {\n    signal: inputSignal,\n    headers: inputHeaders,\n    onopen: inputOnOpen,\n    onmessage,\n    onclose,\n    onerror,\n    openWhenHidden,\n    ...rest\n  }: FetchEventSourceInit,\n) {\n  return new Promise<void>((resolve, reject) => {\n    let retries = 0\n\n    // make a copy of the input headers since we may modify it below:\n    const headers = { ...inputHeaders }\n    if (!headers.accept) {\n      headers.accept = EventStreamContentType\n    }\n\n    let curRequestController: AbortController\n    function onVisibilityChange() {\n      curRequestController.abort() // close existing request on every visibility change\n      if (!document.hidden) {\n        create() // page is now visible again, recreate request.\n      }\n    }\n\n    if (!openWhenHidden) {\n      document.addEventListener('visibilitychange', onVisibilityChange)\n    }\n\n    let retryInterval = DefaultRetryInterval\n    let retryTimer = 0\n    function dispose() {\n      document.removeEventListener('visibilitychange', onVisibilityChange)\n      window.clearTimeout(retryTimer)\n      curRequestController.abort()\n    }\n\n    // if the incoming signal aborts, dispose resources and resolve:\n    inputSignal?.addEventListener('abort', () => {\n      dispose()\n      resolve() // don't waste time constructing/logging errors\n    })\n    const onopen = inputOnOpen ?? defaultOnOpen\n    async function create() {\n      curRequestController = new AbortController()\n      try {\n        const response = await fetch(url, {\n          ...rest,\n          headers,\n          signal: curRequestController.signal,\n        })\n\n        await onopen(response)\n\n        await getBytes(\n          response.body!,\n          getLines(\n            getMessages(\n              (id) => {\n                if (id) {\n                  // store the id and send it back on the next retry:\n                  headers[LastEventId] = id\n                } else {\n                  // don't send the last-event-id header anymore:\n                  delete headers[LastEventId]\n                }\n              },\n              (retry) => {\n                retryInterval = retry\n              },\n              onmessage,\n            ),\n          ),\n        )\n\n        onclose?.()\n        dispose()\n        resolve()\n      } catch (err) {\n        if (!curRequestController.signal.aborted) {\n          // if we haven't aborted the request ourselves:\n          try {\n            // check if we need to retry:\n            const interval: any = onerror?.(err) ?? retryInterval\n            window.clearTimeout(retryTimer)\n            retryTimer = window.setTimeout(create, interval)\n            retryInterval *= 1.5 // exponential backoff\n            retryInterval = Math.min(retryInterval, MaxRetryInterval)\n\n            retries++\n            if (retries >= MaxRetryCount) {\n              // we should not retry anymore:\n              dispose()\n              reject(new Error(`Max retries hit, check your server or network connection.`))\n            } else {\n              console.error(`Error fetching event source, retrying in ${interval}ms`)\n            }\n          } catch (innerErr) {\n            // we should not retry anymore:\n            dispose()\n            reject(innerErr)\n          }\n        }\n      }\n    }\n\n    retryInterval = DefaultRetryInterval\n\n    create()\n  })\n}\n\n/**\n * Represents a message sent in an event stream\n * https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format\n */\nexport interface EventSourceMessage {\n  /** The event ID to set the EventSource object's last event ID value. */\n  id: string\n  /** A string identifying the type of event described. */\n  event: string\n  /** The event data */\n  data: string\n  /** The reconnection interval (in milliseconds) to wait before retrying the connection */\n  retry?: number\n}\n\nconst EventStreamContentType = 'text/event-stream'\nconst DefaultRetryInterval = 100\nconst MaxRetryInterval = 10000\nconst MaxRetryCount = 10\nconst LastEventId = 'last-event-id'\nconst enum ControlChars {\n  NewLine = 10,\n  CarriageReturn = 13,\n  Space = 32,\n  Colon = 58,\n}\n\nfunction defaultOnOpen(response: Response) {\n  const contentType = response.headers.get('content-type')\n  if (!contentType?.startsWith(EventStreamContentType)) {\n    throw new Error(`Expected content-type to be ${EventStreamContentType}, Actual: ${contentType}`)\n  }\n}\n\n/**\n * Converts a ReadableStream into a callback pattern.\n * @param stream The input ReadableStream.\n * @param onChunk A function that will be called on each new byte chunk in the stream.\n * @returns {Promise<void>} A promise that will be resolved when the stream closes.\n */\nasync function getBytes(stream: ReadableStream<Uint8Array>, onChunk: (arr: Uint8Array) => void) {\n  const reader = stream.getReader()\n  while (true) {\n    const result = await reader.read()\n    if (result.done) {\n      break\n    }\n    onChunk(result.value)\n  }\n}\n\n/**\n * Parses arbitary byte chunks into EventSource line buffers.\n * Each line should be of the format \"field: value\" and ends with \\r, \\n, or \\r\\n.\n * @param onLine A function that will be called on each new EventSource line.\n * @returns A function that should be called for each incoming byte chunk.\n */\nfunction getLines(onLine: (line: Uint8Array, fieldLength: number) => void) {\n  let buffer: Uint8Array | undefined\n  let position: number // current read position\n  let fieldLength: number // length of the `field` portion of the line\n  let discardTrailingNewline = false\n\n  // return a function that can process each incoming byte chunk:\n  return function onChunk(arr: Uint8Array) {\n    if (buffer === undefined) {\n      buffer = arr\n      position = 0\n      fieldLength = -1\n    } else {\n      // we're still parsing the old line. Append the new bytes into buffer:\n      buffer = concat(buffer, arr)\n    }\n\n    const bufLength = buffer.length\n    let lineStart = 0 // index where the current line starts\n    while (position < bufLength) {\n      if (discardTrailingNewline) {\n        if (buffer[position] === ControlChars.NewLine) {\n          lineStart = ++position // skip to next char\n        }\n\n        discardTrailingNewline = false\n      }\n\n      // start looking forward till the end of line:\n      let lineEnd = -1 // index of the \\r or \\n char\n      for (; position < bufLength && lineEnd === -1; ++position) {\n        switch (buffer[position]) {\n          case ControlChars.Colon:\n            if (fieldLength === -1) {\n              // first colon in line\n              fieldLength = position - lineStart\n            }\n            break\n          // @ts-ignore:7029 \\r case below should fallthrough to \\n:\n          case ControlChars.CarriageReturn:\n            discardTrailingNewline = true\n          case ControlChars.NewLine:\n            lineEnd = position\n            break\n        }\n      }\n\n      if (lineEnd === -1) {\n        // We reached the end of the buffer but the line hasn't ended.\n        // Wait for the next arr and then continue parsing:\n        break\n      }\n\n      // we've reached the line end, send it out:\n      onLine(buffer.subarray(lineStart, lineEnd), fieldLength)\n      lineStart = position // we're now on the next line\n      fieldLength = -1\n    }\n\n    if (lineStart === bufLength) {\n      buffer = undefined // we've finished reading it\n    } else if (lineStart !== 0) {\n      // Create a new view into buffer beginning at lineStart so we don't\n      // need to copy over the previous lines when we get the new arr:\n      buffer = buffer.subarray(lineStart)\n      position -= lineStart\n    }\n  }\n}\n\n/**\n * Parses line buffers into EventSourceMessages.\n * @param onId A function that will be called on each `id` field.\n * @param onRetry A function that will be called on each `retry` field.\n * @param onMessage A function that will be called on each message.\n * @returns A function that should be called for each incoming line buffer.\n */\nfunction getMessages(\n  onId: (id: string) => void,\n  onRetry: (retry: number) => void,\n  onMessage?: (msg: EventSourceMessage) => void,\n) {\n  let message = newMessage()\n  const decoder = new TextDecoder()\n\n  // return a function that can process each incoming line buffer:\n  return function onLine(line: Uint8Array, fieldLength: number) {\n    if (line.length === 0) {\n      // empty line denotes end of message. Trigger the callback and start a new message:\n      onMessage?.(message)\n      message = newMessage()\n    } else if (fieldLength > 0) {\n      // exclude comments and lines with no values\n      // line is of format \"<field>:<value>\" or \"<field>: <value>\"\n      // https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation\n      const field = decoder.decode(line.subarray(0, fieldLength))\n      const valueOffset = fieldLength + (line[fieldLength + 1] === ControlChars.Space ? 2 : 1)\n      const value = decoder.decode(line.subarray(valueOffset))\n\n      switch (field) {\n        case 'data':\n          // if this message already has data, append the new value to the old.\n          // otherwise, just set to the new value:\n          message.data = message.data ? message.data + '\\n' + value : value // otherwise,\n          break\n        case 'event':\n          message.event = value\n          break\n        case 'id':\n          onId((message.id = value))\n          break\n        case 'retry':\n          const retry = parseInt(value, 10)\n          if (!isNaN(retry)) {\n            // per spec, ignore non-integers\n            onRetry((message.retry = retry))\n          }\n          break\n      }\n    }\n  }\n}\n\nfunction concat(a: Uint8Array, b: Uint8Array) {\n  const res = new Uint8Array(a.length + b.length)\n  res.set(a)\n  res.set(b, a.length)\n  return res\n}\n\nfunction newMessage(): EventSourceMessage {\n  // data, event, and id must be initialized to empty strings:\n  // https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation\n  // retry should be initialized to undefined so we return a consistent shape\n  // to the js engine all the time: https://mathiasbynens.be/notes/shapes-ics#takeaways\n  return {\n    data: '',\n    event: '',\n    id: '',\n    retry: undefined,\n  }\n}\n","const generatedByIdiomorphId = new WeakSet()\n\n//=============================================================================\n// Core Morphing Algorithm - morph, morphNormalizedContent, morphOldNodeTo, morphChildren\n//=============================================================================\nexport function idiomorph(oldNode: Document | Element, newContent: string | Element, config = {}) {\n  if (oldNode instanceof Document) {\n    oldNode = oldNode.documentElement\n  }\n\n  let parsedContent: Element\n  if (typeof newContent === 'string') {\n    parsedContent = parseContent(newContent) as Element\n  } else {\n    parsedContent = newContent\n  }\n\n  const normalizedContent = normalizeContent(parsedContent)\n  const ctx = createMorphContext(oldNode, normalizedContent, config)\n\n  return morphNormalizedContent(oldNode, normalizedContent, ctx)\n}\n\nfunction morphNormalizedContent(oldNode: Element, normalizedNewContent: Element, ctx: any) {\n  if (ctx.head.block) {\n    const oldHead = oldNode.querySelector('head')\n    const newHead = normalizedNewContent.querySelector('head')\n    if (oldHead && newHead) {\n      const promises = handleHeadElement(newHead, oldHead, ctx)\n      // when head promises resolve, call morph again, ignoring the head tag\n      Promise.all(promises).then(() => {\n        morphNormalizedContent(\n          oldNode,\n          normalizedNewContent,\n          Object.assign(ctx, {\n            head: {\n              block: false,\n              ignore: true,\n            },\n          }),\n        )\n      })\n      return\n    }\n  }\n\n  if (ctx.morphStyle === 'innerHTML') {\n    // innerHTML, so we are only updating the children\n    morphChildren(normalizedNewContent, oldNode, ctx)\n    return oldNode.children\n  } else if (ctx.morphStyle === 'outerHTML' || ctx.morphStyle == null) {\n    // otherwise find the best element match in the new content, morph that, and merge its siblings\n    // into either side of the best match\n    const bestMatch = findBestNodeMatch(normalizedNewContent, oldNode, ctx)\n    if (!bestMatch) {\n      throw new Error('Could not find best match')\n    }\n\n    // stash the siblings that will need to be inserted on either side of the best match\n    const previousSibling = bestMatch?.previousSibling as Element\n    const nextSibling = bestMatch?.nextSibling as Element\n\n    // morph it\n    const morphedNode = morphOldNodeTo(oldNode, bestMatch, ctx)\n\n    if (bestMatch) {\n      // if there was a best match, merge the siblings in too and return the\n      // whole bunch\n      return insertSiblings(previousSibling, morphedNode, nextSibling)\n    } else {\n      // otherwise nothing was added to the DOM\n      return []\n    }\n  } else {\n    throw 'Do not understand how to morph style ' + ctx.morphStyle\n  }\n}\n\n/**\n * @param oldNode root node to merge content into\n * @param newContent new content to merge\n * @param ctx the merge context\n * @returns {Element} the element that ended up in the DOM\n */\nfunction morphOldNodeTo(oldNode: Element, newContent: Element, ctx: any) {\n  if (ctx.ignoreActive && oldNode === document.activeElement) {\n    // don't morph focused element\n  } else if (newContent == null) {\n    if (ctx.callbacks.beforeNodeRemoved(oldNode) === false) return\n\n    oldNode.remove()\n    ctx.callbacks.afterNodeRemoved(oldNode)\n    return\n  } else if (!isSoftMatch(oldNode, newContent)) {\n    if (ctx.callbacks.beforeNodeRemoved(oldNode) === false) return\n    if (ctx.callbacks.beforeNodeAdded(newContent) === false) return\n\n    if (!oldNode.parentElement) {\n      throw new Error('oldNode has no parentElement')\n    }\n    oldNode.parentElement.replaceChild(newContent, oldNode)\n    ctx.callbacks.afterNodeAdded(newContent)\n    ctx.callbacks.afterNodeRemoved(oldNode)\n    return newContent\n  } else {\n    if (ctx.callbacks.beforeNodeMorphed(oldNode, newContent) === false) return\n\n    if (oldNode instanceof HTMLHeadElement && ctx.head.ignore) {\n      // ignore the head element\n    } else if (\n      newContent instanceof HTMLHeadElement &&\n      oldNode instanceof HTMLHeadElement &&\n      ctx.head.style !== 'morph'\n    ) {\n      handleHeadElement(newContent, oldNode, ctx)\n    } else {\n      syncNodeFrom(newContent, oldNode)\n      morphChildren(newContent, oldNode, ctx)\n    }\n    ctx.callbacks.afterNodeMorphed(oldNode, newContent)\n    return oldNode\n  }\n}\n\n/**\n * This is the core algorithm for matching up children.  The idea is to use id sets to try to match up\n * nodes as faithfully as possible.  We greedily match, which allows us to keep the algorithm fast, but\n * by using id sets, we are able to better match up with content deeper in the DOM.\n *\n * Basic algorithm is, for each node in the new content:\n *\n * - if we have reached the end of the old parent, append the new content\n * - if the new content has an id set match with the current insertion point, morph\n * - search for an id set match\n * - if id set match found, morph\n * - otherwise search for a \"soft\" match\n * - if a soft match is found, morph\n * - otherwise, prepend the new node before the current insertion point\n *\n * The two search algorithms terminate if competing node matches appear to outweigh what can be achieved\n * with the current node.  See findIdSetMatch() and findSoftMatch() for details.\n *\n * @param {Element} newParent the parent element of the new content\n * @param {Element } oldParent the old content that we are merging the new content into\n * @param ctx the merge context\n */\nfunction morphChildren(newParent: Element, oldParent: Element, ctx: any) {\n  let nextNewChild = newParent.firstChild as Element | null\n  let insertionPoint = oldParent.firstChild as Element | null\n  let newChild\n\n  // run through all the new content\n  while (nextNewChild) {\n    newChild = nextNewChild\n    nextNewChild = newChild.nextSibling as Element | null\n\n    // if we are at the end of the exiting parent's children, just append\n    if (insertionPoint == null) {\n      if (ctx.callbacks.beforeNodeAdded(newChild) === false) return\n\n      oldParent.appendChild(newChild)\n      ctx.callbacks.afterNodeAdded(newChild)\n      removeIdsFromConsideration(ctx, newChild)\n      continue\n    }\n\n    // if the current node has an id set match then morph\n    if (isIdSetMatch(newChild, insertionPoint, ctx)) {\n      morphOldNodeTo(insertionPoint, newChild, ctx)\n      insertionPoint = insertionPoint.nextSibling as Element | null\n      removeIdsFromConsideration(ctx, newChild)\n      continue\n    }\n\n    // otherwise search forward in the existing old children for an id set match\n    let idSetMatch = findIdSetMatch(newParent, oldParent, newChild, insertionPoint, ctx)\n\n    // if we found a potential match, remove the nodes until that point and morph\n    if (idSetMatch) {\n      insertionPoint = removeNodesBetween(insertionPoint, idSetMatch, ctx)\n      morphOldNodeTo(idSetMatch, newChild, ctx)\n      removeIdsFromConsideration(ctx, newChild)\n      continue\n    }\n\n    // no id set match found, so scan forward for a soft match for the current node\n    let softMatch = findSoftMatch(newParent, newChild, insertionPoint, ctx)\n\n    // if we found a soft match for the current node, morph\n    if (softMatch) {\n      insertionPoint = removeNodesBetween(insertionPoint, softMatch, ctx)\n      morphOldNodeTo(softMatch, newChild, ctx)\n      removeIdsFromConsideration(ctx, newChild)\n      continue\n    }\n\n    // abandon all hope of morphing, just insert the new child before the insertion point\n    // and move on\n    if (ctx.callbacks.beforeNodeAdded(newChild) === false) return\n\n    oldParent.insertBefore(newChild, insertionPoint)\n    ctx.callbacks.afterNodeAdded(newChild)\n    removeIdsFromConsideration(ctx, newChild)\n  }\n\n  // remove any remaining old nodes that didn't match up with new content\n  while (insertionPoint !== null) {\n    let tempNode = insertionPoint\n    insertionPoint = insertionPoint.nextSibling as Element | null\n    removeNode(tempNode, ctx)\n  }\n}\n\n//=============================================================================\n// Attribute Syncing Code\n//=============================================================================\n\n/**\n * syncs a given node with another node, copying over all attributes and\n * inner element state from the 'from' node to the 'to' node\n *\n * @param {Element} from the element to copy attributes & state from\n * @param {Element} to the element to copy attributes & state to\n */\nfunction syncNodeFrom(from: Element, to: Element) {\n  let type = from.nodeType\n\n  // if is an element type, sync the attributes from the\n  // new node into the new node\n  if (type === 1 /* element type */) {\n    for (const fromAttribute of from.attributes) {\n      const toAttribute = to.getAttribute(fromAttribute.name)\n      if (toAttribute !== fromAttribute.value) {\n        to.setAttribute(fromAttribute.name, fromAttribute.value)\n      }\n    }\n    for (const toAttribute of to.attributes) {\n      if (!from.hasAttribute(toAttribute.name)) {\n        to.removeAttribute(toAttribute.name)\n      }\n    }\n  }\n\n  // sync text nodes\n  if (type === Node.COMMENT_NODE || type === Node.TEXT_NODE) {\n    if (to.nodeValue !== from.nodeValue) {\n      to.nodeValue = from.nodeValue\n    }\n  }\n\n  // NB: many bothans died to bring us information:\n  //\n  // https://github.com/patrick-steele-idem/morphdom/blob/master/src/specialElHandlers.js\n  // https://github.com/choojs/nanomorph/blob/master/lib/morph.jsL113\n\n  // sync input value\n  if (from instanceof HTMLInputElement && to instanceof HTMLInputElement && from.type !== 'file') {\n    to.value = from.value || ''\n    syncAttribute(from, to, 'value')\n\n    // sync boolean attributes\n    syncAttribute(from, to, 'checked')\n    syncAttribute(from, to, 'disabled')\n  } else if (from instanceof HTMLOptionElement) {\n    syncAttribute(from, to, 'selected')\n  } else if (from instanceof HTMLTextAreaElement && to instanceof HTMLTextAreaElement) {\n    const fromValue = from.value\n    const toValue = to.value\n    if (fromValue !== toValue) {\n      to.value = fromValue\n    }\n    if (to.firstChild && to.firstChild.nodeValue !== fromValue) {\n      to.firstChild.nodeValue = fromValue\n    }\n  }\n}\n\nfunction syncAttribute(from: Element, to: Element, attributeName: string) {\n  const fAttr = from.getAttribute(attributeName)\n  const tAttr = to.getAttribute(attributeName)\n\n  if (fAttr !== tAttr) {\n    if (fAttr) {\n      to.setAttribute(attributeName, fAttr)\n    } else {\n      to.removeAttribute(attributeName)\n    }\n  }\n}\n\n//=============================================================================\n// the HEAD tag can be handled specially, either w/ a 'merge' or 'append' style\n//=============================================================================\nfunction handleHeadElement(newHeadTag: HTMLHeadElement, currentHead: HTMLHeadElement, ctx: any) {\n  const added = []\n  const removed = []\n  const preserved = []\n  const nodesToAppend = []\n\n  const headMergeStyle = ctx.head.style\n\n  // put all new head elements into a Map, by their outerHTML\n  const srcToNewHeadNodes = new Map()\n  for (const newHeadChild of newHeadTag.children) {\n    srcToNewHeadNodes.set(newHeadChild.outerHTML, newHeadChild)\n  }\n\n  // for each elt in the current head\n  for (const currentHeadElt of currentHead.children) {\n    // If the current head element is in the map\n    let inNewContent = srcToNewHeadNodes.has(currentHeadElt.outerHTML)\n    let isReAppended = ctx.head.shouldReAppend(currentHeadElt)\n    let isPreserved = ctx.head.shouldPreserve(currentHeadElt)\n    if (inNewContent || isPreserved) {\n      if (isReAppended) {\n        // remove the current version and let the new version replace it and re-execute\n        removed.push(currentHeadElt)\n      } else {\n        // this element already exists and should not be re-appended, so remove it from\n        // the new content map, preserving it in the DOM\n        srcToNewHeadNodes.delete(currentHeadElt.outerHTML)\n        preserved.push(currentHeadElt)\n      }\n    } else {\n      if (headMergeStyle === 'append') {\n        // we are appending and this existing element is not new content\n        // so if and only if it is marked for re-append do we do anything\n        if (isReAppended) {\n          removed.push(currentHeadElt)\n          nodesToAppend.push(currentHeadElt)\n        }\n      } else {\n        // if this is a merge, we remove this content since it is not in the new head\n        if (ctx.head.shouldRemove(currentHeadElt) !== false) {\n          removed.push(currentHeadElt)\n        }\n      }\n    }\n  }\n\n  // Push the remaining new head elements in the Map into the\n  // nodes to append to the head tag\n  nodesToAppend.push(...srcToNewHeadNodes.values())\n  // console.log('to append: ', nodesToAppend)\n\n  const promises = []\n  for (const newNode of nodesToAppend) {\n    // console.log('adding: ', newNode)\n    const newElt = document.createRange().createContextualFragment(newNode.outerHTML).firstChild as Element | null\n    if (!newElt) {\n      throw new Error('could not create new element from: ' + newNode.outerHTML)\n    }\n    // console.log(newElt)\n    if (!!ctx.callbacks.beforeNodeAdded(newElt)) {\n      if (newElt.hasAttribute('href') || newElt.hasAttribute('src')) {\n        let resolver: (value: unknown) => void\n        const promise = new Promise((resolve) => {\n          resolver = resolve\n        })\n        newElt.addEventListener('load', function () {\n          resolver(undefined)\n        })\n        promises.push(promise)\n      }\n      currentHead.appendChild(newElt)\n      ctx.callbacks.afterNodeAdded(newElt)\n      added.push(newElt)\n    }\n  }\n\n  // remove all removed elements, after we have appended the new elements to avoid\n  // additional network requests for things like style sheets\n  for (const removedElement of removed) {\n    if (ctx.callbacks.beforeNodeRemoved(removedElement) !== false) {\n      currentHead.removeChild(removedElement)\n      ctx.callbacks.afterNodeRemoved(removedElement)\n    }\n  }\n\n  ctx.head.afterHeadMorphed(currentHead, {\n    added: added,\n    kept: preserved,\n    removed: removed,\n  })\n  return promises\n}\n\n//=============================================================================\n// Misc\n//=============================================================================\nfunction noOp() {}\n\nfunction createMorphContext(oldNode: Element, newContent: Element, config: any) {\n  return {\n    target: oldNode,\n    newContent: newContent,\n    config: config,\n    morphStyle: config.morphStyle,\n    ignoreActive: config.ignoreActive,\n    idMap: createIdMap(oldNode, newContent),\n    deadIds: new Set(),\n    callbacks: Object.assign(\n      {\n        beforeNodeAdded: noOp,\n        afterNodeAdded: noOp,\n        beforeNodeMorphed: noOp,\n        afterNodeMorphed: noOp,\n        beforeNodeRemoved: noOp,\n        afterNodeRemoved: noOp,\n      },\n      config.callbacks,\n    ),\n    head: Object.assign(\n      {\n        style: 'merge',\n        shouldPreserve: (elt: Element) => elt.getAttribute('im-preserve') === 'true',\n        shouldReAppend: (elt: Element) => elt.getAttribute('im-re-append') === 'true',\n        shouldRemove: noOp,\n        afterHeadMorphed: noOp,\n      },\n      config.head,\n    ),\n  }\n}\n\nfunction isIdSetMatch(node1: Element, node2: Element, ctx: any) {\n  if (!node1 || !node2) return false\n\n  if (node1.nodeType === node2.nodeType && node1.tagName === node2.tagName) {\n    if (node1?.id?.length && node1.id === node2.id) return true\n\n    return getIdIntersectionCount(ctx, node1, node2) > 0\n  }\n  return false\n}\n\nfunction isSoftMatch(node1: Element, node2: Element) {\n  if (!node1 || !node2) return false\n\n  return node1.nodeType === node2.nodeType && node1.tagName === node2.tagName\n}\n\nfunction removeNodesBetween(startInclusive: Element, endExclusive: Element, ctx: any) {\n  while (startInclusive !== endExclusive) {\n    const tempNode = startInclusive\n    startInclusive = startInclusive?.nextSibling as Element\n    if (!tempNode) {\n      throw new Error('tempNode is null')\n    }\n    removeNode(tempNode, ctx)\n  }\n  removeIdsFromConsideration(ctx, endExclusive)\n  return endExclusive.nextSibling as Element | null\n}\n\n//=============================================================================\n// Scans forward from the insertionPoint in the old parent looking for a potential id match\n// for the newChild.  We stop if we find a potential id match for the new child OR\n// if the number of potential id matches we are discarding is greater than the\n// potential id matches for the new child\n//=============================================================================\nfunction findIdSetMatch(newContent: Element, oldParent: Element, newChild: Element, insertionPoint: Element, ctx: any) {\n  // max id matches we are willing to discard in our search\n  const newChildPotentialIdCount = getIdIntersectionCount(ctx, newChild, oldParent)\n\n  let potentialMatch: Element | null = null\n\n  // only search forward if there is a possibility of an id match\n  if (newChildPotentialIdCount > 0) {\n    potentialMatch = insertionPoint\n    // if there is a possibility of an id match, scan forward\n    // keep track of the potential id match count we are discarding (the\n    // newChildPotentialIdCount must be greater than this to make it likely\n    // worth it)\n    let otherMatchCount = 0\n    while (potentialMatch != null) {\n      // If we have an id match, return the current potential match\n      if (isIdSetMatch(newChild, potentialMatch, ctx)) {\n        return potentialMatch\n      }\n\n      // computer the other potential matches of this new content\n      otherMatchCount += getIdIntersectionCount(ctx, potentialMatch, newContent)\n      if (otherMatchCount > newChildPotentialIdCount) {\n        // if we have more potential id matches in _other_ content, we\n        // do not have a good candidate for an id match, so return null\n        return null\n      }\n\n      // advanced to the next old content child\n      potentialMatch = potentialMatch.nextSibling as Element | null\n    }\n  }\n  return potentialMatch\n}\n\n//=============================================================================\n// Scans forward from the insertionPoint in the old parent looking for a potential soft match\n// for the newChild.  We stop if we find a potential soft match for the new child OR\n// if we find a potential id match in the old parents children OR if we find two\n// potential soft matches for the next two pieces of new content\n//=============================================================================\nfunction findSoftMatch(newContent: Element, newChild: Element, insertionPoint: Element, ctx: any) {\n  let potentialSoftMatch = insertionPoint as Element | null\n  let nextSibling = newChild.nextSibling as Element | null\n\n  let siblingSoftMatchCount = 0\n\n  while (potentialSoftMatch && nextSibling) {\n    if (getIdIntersectionCount(ctx, potentialSoftMatch, newContent) > 0) {\n      // the current potential soft match has a potential id set match with the remaining new\n      // content so bail out of looking\n      return null\n    }\n\n    // if we have a soft match with the current node, return it\n    if (isSoftMatch(newChild, potentialSoftMatch)) {\n      return potentialSoftMatch\n    }\n\n    if (isSoftMatch(nextSibling, potentialSoftMatch)) {\n      // the next new node has a soft match with this node, so\n      // increment the count of future soft matches\n      siblingSoftMatchCount++\n      nextSibling = nextSibling.nextSibling as Element | null\n\n      // If there are two future soft matches, bail to allow the siblings to soft match\n      // so that we don't consume future soft matches for the sake of the current node\n      if (siblingSoftMatchCount >= 2) {\n        return null\n      }\n    }\n\n    // advanced to the next old content child\n    potentialSoftMatch = potentialSoftMatch.nextSibling as Element | null\n  }\n\n  return potentialSoftMatch\n}\n\nconst parser = new DOMParser()\nfunction parseContent(newContent: string) {\n  // remove svgs to avoid false-positive matches on head, etc.\n  const contentWithSvgsRemoved = newContent.replace(/<svg(\\s[^>]*>|>)([\\s\\S]*?)<\\/svg>/gim, '')\n\n  // if the newContent contains a html, head or body tag, we can simply parse it w/o wrapping\n  if (\n    contentWithSvgsRemoved.match(/<\\/html>/) ||\n    contentWithSvgsRemoved.match(/<\\/head>/) ||\n    contentWithSvgsRemoved.match(/<\\/body>/)\n  ) {\n    const content = parser.parseFromString(newContent, 'text/html')\n    // if it is a full HTML document, return the document itself as the parent container\n    if (contentWithSvgsRemoved.match(/<\\/html>/)) {\n      generatedByIdiomorphId.add(content)\n      return content\n    } else {\n      // otherwise return the html element as the parent container\n      let Element = content.firstChild\n      if (Element) {\n        generatedByIdiomorphId.add(Element)\n        return Element as Element\n      } else {\n        return null\n      }\n    }\n  } else {\n    // if it is partial HTML, wrap it in a template tag to provide a parent element and also to help\n    // deal with touchy tags like tr, tbody, etc.\n    const responseDoc = parser.parseFromString(`<body><template>${newContent}</template></body>`, 'text/html')\n    const content = responseDoc.body.querySelector('template')?.content\n    if (!content) {\n      throw new Error('content is null')\n    }\n    generatedByIdiomorphId.add(content)\n    return content\n  }\n}\n\nfunction normalizeContent(newContent: Element) {\n  if (newContent == null) {\n    // noinspection UnnecessaryLocalVariableJS\n    const dummyParent = document.createElement('div')\n    return dummyParent\n  } else if (generatedByIdiomorphId.has(newContent)) {\n    // the template tag created by idiomorph parsing can serve as a dummy parent\n    return newContent\n  } else if (newContent instanceof Node) {\n    // a single node is added as a child to a dummy parent\n    const dummyParent = document.createElement('div')\n    dummyParent.append(newContent)\n    return dummyParent\n  } else {\n    // all nodes in the array or Element collection are consolidated under\n    // a single dummy parent element\n    const dummyParent = document.createElement('div')\n    for (const elt of [...newContent]) {\n      dummyParent.append(elt)\n    }\n    return dummyParent\n  }\n}\n\nfunction insertSiblings(previousSibling?: Element, morphedNode?: Element, nextSibling?: Element) {\n  const stack = []\n  const added = []\n  while (previousSibling) {\n    stack.push(previousSibling)\n    previousSibling = previousSibling.previousSibling as Element\n  }\n  while (stack.length > 0) {\n    const node = stack.pop()!\n    added.push(node) // push added preceding siblings on in order and insert\n    morphedNode?.parentElement?.insertBefore(node, morphedNode)\n  }\n  added.push(morphedNode)\n  while (nextSibling) {\n    stack.push(nextSibling)\n    added.push(nextSibling) // here we are going in order, so push on as we scan, rather than add\n    nextSibling = nextSibling.nextSibling as Element\n  }\n  while (stack.length) {\n    morphedNode?.parentElement?.insertBefore(stack.pop()!, morphedNode.nextSibling)\n  }\n  return added\n}\n\nfunction findBestNodeMatch(newContent: Element, oldNode: Element, ctx: any) {\n  let currentElement = newContent.firstChild as Element | null\n  let bestElement = currentElement\n  let score = 0\n  while (currentElement) {\n    let newScore = scoreElement(currentElement, oldNode, ctx)\n    if (newScore > score) {\n      bestElement = currentElement\n      score = newScore\n    }\n    currentElement = currentElement.nextSibling as Element | null\n  }\n  return bestElement\n}\n\nfunction scoreElement(node1: Element, node2: Element, ctx: any) {\n  if (isSoftMatch(node1, node2)) {\n    return 0.5 + getIdIntersectionCount(ctx, node1, node2)\n  }\n  return 0\n}\n\nfunction removeNode(tempNode: Element, ctx: any) {\n  removeIdsFromConsideration(ctx, tempNode)\n  if (ctx.callbacks.beforeNodeRemoved(tempNode) === false) return\n\n  tempNode.remove()\n  ctx.callbacks.afterNodeRemoved(tempNode)\n}\n\n//=============================================================================\n// ID Set Functions\n//=============================================================================\n\nfunction isIdInConsideration(ctx: any, id: string) {\n  return !ctx.deadIds.has(id)\n}\n\nfunction idIsWithinNode(ctx: any, id: string, targetNode: Element) {\n  return ctx.idMap.get(targetNode)?.has(id) || false\n}\n\nfunction removeIdsFromConsideration(ctx: any, node: Element) {\n  const idSet = ctx.idMap.get(node)\n  if (!idSet) return\n  for (const id of idSet) {\n    ctx.deadIds.add(id)\n  }\n}\n\nfunction getIdIntersectionCount(ctx: any, node1: Element, node2: Element) {\n  const sourceSet = ctx.idMap.get(node1)\n  if (!sourceSet) return 0\n\n  let matchCount = 0\n  for (const id of sourceSet) {\n    // a potential match is an id in the source and potentialIdsSet, but\n    // that has not already been merged into the DOM\n    if (isIdInConsideration(ctx, id) && idIsWithinNode(ctx, id, node2)) {\n      ++matchCount\n    }\n  }\n  return matchCount\n}\n\n/**\n * A bottom up algorithm that finds all elements with ids inside of the node\n * argument and populates id sets for those nodes and all their parents, generating\n * a set of ids contained within all nodes for the entire hierarchy in the DOM\n *\n * @param node {Element}\n * @param {Map<Node, Set<String>>} idMap\n */\nfunction populateIdMapForNode(node: Element, idMap: Map<Element, Set<string>>) {\n  const nodeParent = node.parentElement\n  // find all elements with an id property\n  const idElements = node.querySelectorAll('[id]')\n  for (const elt of idElements) {\n    let current = elt as Element | null\n    // walk up the parent hierarchy of that element, adding the id\n    // of element to the parent's id set\n    while (current !== nodeParent && !!current) {\n      let idSet = idMap.get(current)\n      // if the id set doesn't exist, create it and insert it in the  map\n      if (idSet == null) {\n        idSet = new Set()\n        idMap.set(current, idSet)\n      }\n      idSet.add(elt.id)\n      current = current.parentElement\n    }\n  }\n}\n\n/**\n * This function computes a map of nodes to all ids contained within that node (inclusive of the\n * node).  This map can be used to ask if two nodes have intersecting sets of ids, which allows\n * for a looser definition of \"matching\" than tradition id matching, and allows child nodes\n * to contribute to a parent nodes matching.\n *\n * @param {Element} oldContent  the old content that will be morphed\n * @param {Element} newContent  the new content to morph to\n * @returns {Map<Node, Set<String>>} a map of nodes to id sets for the\n */\nfunction createIdMap(oldContent: Element, newContent: Element) {\n  const idMap = new Map()\n  populateIdMapForNode(oldContent, idMap)\n  populateIdMapForNode(newContent, idMap)\n  return idMap\n}\n","import { argsToMs, DATASTAR_CLASS_PREFIX } from '..'\nimport { toHTMLorSVGElement } from '../dom'\nimport { AttributeContext, AttributePlugin } from '../types'\n\nconst DISPLAY = 'display'\nconst NONE = 'none'\nconst IMPORTANT = 'important'\nconst DURATION = 'duration'\n\nconst SHOW = 'show'\nconst SHOW_CLASS = `${DATASTAR_CLASS_PREFIX}showing`\nconst HIDE_CLASS = `${DATASTAR_CLASS_PREFIX}hiding`\nconst SHOW_DURATION_TRANSITION_STYLE = `${DATASTAR_CLASS_PREFIX}show-transition-style`\n\n// Sets the display of the element\nexport const ShowPlugin: AttributePlugin = {\n  prefix: SHOW,\n  allowedModifiers: new Set([IMPORTANT, DURATION]),\n\n  onLoad: (ctx: AttributeContext) => {\n    const { el, modifiers, expressionFn, reactivity } = ctx\n\n    const isImportant = modifiers.has(IMPORTANT)\n    const priority = isImportant ? IMPORTANT : undefined\n\n    let showFn, hideFn\n\n    const durationArgs = ctx.modifiers.get(DURATION)\n    if (durationArgs) {\n      let style = document.getElementById(SHOW_DURATION_TRANSITION_STYLE)\n      if (!style) {\n        style = document.createElement('style')\n        style.id = SHOW_DURATION_TRANSITION_STYLE\n        document.head.appendChild(style)\n        const durationMs = argsToMs(durationArgs) || '300'\n        style.innerHTML = `\n          .${SHOW_CLASS} {\n            visibility: visible;\n            transition: opacity ${durationMs}ms linear;\n          }\n          .${HIDE_CLASS} {\n            visibility: hidden;\n            transition: visibility 0s ${durationMs}ms, opacity ${durationMs}ms linear;\n          }\n        `\n      }\n\n      const transitionEndHandler = (classNameToRemove: string) => (event: Event) => {\n        if (event.target === el) {\n          el.classList.remove(classNameToRemove)\n          el.removeEventListener('transitionend', transitionEndHandler(classNameToRemove))\n        }\n      }\n\n      showFn = () => {\n        el.addEventListener('transitionend', transitionEndHandler(SHOW_CLASS))\n        el.classList.add(SHOW_CLASS)\n        requestAnimationFrame(() => {\n          el.style.setProperty('opacity', '1', priority)\n        })\n      }\n\n      hideFn = () => {\n        el.addEventListener('transitionend', transitionEndHandler(HIDE_CLASS))\n        el.classList.add(HIDE_CLASS)\n        requestAnimationFrame(() => {\n          el.style.setProperty('opacity', '0', priority)\n        })\n      }\n    } else {\n      showFn = () => {\n        if (el.style.length === 1 && el.style.display === NONE) {\n          el.style.removeProperty(DISPLAY)\n        } else {\n          el.style.setProperty(DISPLAY, '', priority)\n        }\n      }\n\n      hideFn = () => {\n        el.style.setProperty(DISPLAY, NONE, priority)\n      }\n    }\n\n    return reactivity.effect(async () => {\n      const expressionEvaluated = await expressionFn(ctx)\n      const shouldShow = !!expressionEvaluated\n\n      if (shouldShow) {\n        showFn()\n      } else {\n        hideFn()\n      }\n    })\n  },\n}\n\nconst INTERSECTS = 'intersects'\nconst ONCE = 'once'\nconst HALF = 'half'\nconst FULL = 'full'\n\n// Run expression when element intersects with viewport\nexport const IntersectionPlugin: AttributePlugin = {\n  prefix: INTERSECTS,\n  allowedModifiers: new Set([ONCE, HALF, FULL]),\n  mustHaveEmptyKey: true,\n  onLoad: (ctx: AttributeContext) => {\n    const { modifiers } = ctx\n    const options = { threshold: 0 }\n    if (modifiers.has(FULL)) options.threshold = 1\n    else if (modifiers.has(HALF)) options.threshold = 0.5\n\n    const observer = new IntersectionObserver((entries) => {\n      entries.forEach((entry) => {\n        if (entry.isIntersecting) {\n          ctx.expressionFn(ctx)\n          if (modifiers.has(ONCE)) {\n            observer.disconnect()\n            delete ctx.el.dataset[ctx.rawKey]\n          }\n        }\n      })\n    }, options)\n\n    observer.observe(ctx.el)\n    return () => observer.disconnect()\n  },\n}\n\nconst PREPEND = 'prepend'\nconst APPEND = 'append'\nconst teleportParentErr = new Error('Target element must have a parent if using prepend or append')\n// Teleports the element to another element\nexport const TeleportPlugin: AttributePlugin = {\n  prefix: 'teleport',\n  allowedModifiers: new Set([PREPEND, APPEND]),\n  allowedTagRegexps: new Set(['template']),\n  bypassExpressionFunctionCreation: () => true,\n  onLoad: (ctx: AttributeContext) => {\n    const { el, modifiers, expression } = ctx\n    if (!(el instanceof HTMLTemplateElement)) {\n      throw new Error(`el must be a template element`)\n    }\n\n    const target = document.querySelector(expression)\n    if (!target) {\n      throw new Error(`Target element not found: ${expression}`)\n    }\n\n    if (!el.content) {\n      throw new Error('Template element must have content')\n    }\n\n    const n = el.content.cloneNode(true)\n    const nEl = toHTMLorSVGElement(n as Element)\n    if (nEl?.firstElementChild) {\n      throw new Error('Empty template')\n    }\n\n    if (modifiers.has(PREPEND)) {\n      if (!target.parentNode) throw teleportParentErr\n      target.parentNode.insertBefore(n, target)\n    } else if (modifiers.has(APPEND)) {\n      if (!target.parentNode) throw teleportParentErr\n      target.parentNode.insertBefore(n, target.nextSibling)\n    } else {\n      target.appendChild(n)\n    }\n  },\n}\n\n// Scrolls the element into view\nexport const ScrollIntoViewPlugin: AttributePlugin = {\n  prefix: 'scrollIntoView',\n  mustHaveEmptyKey: true,\n  mustHaveEmptyExpression: true,\n  allowedModifiers: new Set([\n    'smooth',\n    'instant',\n    'auto',\n    'hstart',\n    'hcenter',\n    'hend',\n    'hnearest',\n    'vstart',\n    'vcenter',\n    'vend',\n    'vnearest',\n    'focus',\n  ]),\n\n  onLoad: ({ el, modifiers, rawKey }: AttributeContext) => {\n    if (!el.tabIndex) el.setAttribute('tabindex', '0')\n    const opts: ScrollIntoViewOptions = {\n      behavior: 'smooth',\n      block: 'center',\n      inline: 'center',\n    }\n    if (modifiers.has('smooth')) opts.behavior = 'smooth'\n    if (modifiers.has('instant')) opts.behavior = 'instant'\n    if (modifiers.has('auto')) opts.behavior = 'auto'\n    if (modifiers.has('hstart')) opts.inline = 'start'\n    if (modifiers.has('hcenter')) opts.inline = 'center'\n    if (modifiers.has('hend')) opts.inline = 'end'\n    if (modifiers.has('hnearest')) opts.inline = 'nearest'\n    if (modifiers.has('vstart')) opts.block = 'start'\n    if (modifiers.has('vcenter')) opts.block = 'center'\n    if (modifiers.has('vend')) opts.block = 'end'\n    if (modifiers.has('vnearest')) opts.block = 'nearest'\n\n    scrollIntoView(el, opts, modifiers.has('focus'))\n    delete el.dataset[rawKey]\n    return () => {}\n  },\n}\n\nexport interface DocumentSupportingViewTransitionAPI {\n  startViewTransition(updateCallback: () => Promise<void> | void): ViewTransition\n}\n\nexport interface ViewTransition {\n  finished: Promise<void>\n  ready: Promise<void>\n  updateCallbackDone: Promise<void>\n  skipTransition(): void\n}\n\nexport interface CSSStyleDeclaration {\n  viewTransitionName: string\n}\n\nexport const docWithViewTransitionAPI = document as unknown as DocumentSupportingViewTransitionAPI\nexport const supportsViewTransitions = !!docWithViewTransitionAPI.startViewTransition\n\n// Setup view transition api\nexport const ViewTransitionPlugin: AttributePlugin = {\n  prefix: 'viewTransition',\n  onGlobalInit() {\n    let hasViewTransitionMeta = false\n    document.head.childNodes.forEach((node) => {\n      if (node instanceof HTMLMetaElement && node.name === 'view-transition') {\n        hasViewTransitionMeta = true\n      }\n    })\n\n    if (!hasViewTransitionMeta) {\n      const meta = document.createElement('meta')\n      meta.name = 'view-transition'\n      meta.content = 'same-origin'\n      document.head.appendChild(meta)\n    }\n  },\n  onLoad: (ctx) => {\n    if (!supportsViewTransitions) {\n      console.error('Browser does not support view transitions')\n      return\n    }\n\n    return ctx.reactivity.effect(() => {\n      const { el, expressionFn } = ctx\n      let name = expressionFn(ctx)\n      if (!name) return\n\n      const elVTASTyle = el.style as unknown as CSSStyleDeclaration\n      elVTASTyle.viewTransitionName = name\n    })\n  },\n}\n\nexport const VisibilityPlugins: AttributePlugin[] = [\n  ShowPlugin,\n  IntersectionPlugin,\n  TeleportPlugin,\n  ScrollIntoViewPlugin,\n  ViewTransitionPlugin,\n]\n\nexport const VisibilityActions = {\n  scroll: async (\n    _: AttributeContext,\n    selector: string,\n    opts: {\n      behavior: 'smooth' | 'instant' | 'auto' // smooth is default\n      vertical: 'start' | 'center' | 'end' | 'nearest' // center is default\n      horizontal: 'start' | 'center' | 'end' | 'nearest' // center is default\n      shouldFocus: boolean\n    },\n  ) => {\n    const allOpts = Object.assign(\n      { behavior: 'smooth', vertical: 'center', horizontal: 'center', shouldFocus: true },\n      opts,\n    )\n    const el = document.querySelector(selector)\n    scrollIntoView(el as HTMLElement, allOpts)\n  },\n}\n\nfunction scrollIntoView(el: HTMLElement | SVGElement, opts: ScrollIntoViewOptions, shouldFocus = true) {\n  if (!(el instanceof HTMLElement || el instanceof SVGElement)) {\n    throw new Error('Element not found')\n  }\n  if (!el.tabIndex) el.setAttribute('tabindex', '0')\n\n  el.scrollIntoView(opts)\n  if (shouldFocus) el.focus()\n}\n","import { sendDatastarEvent, storeFromPossibleContents } from '../.'\nimport { DATASTAR_CLASS_PREFIX, DATASTAR_STR } from '../engine'\nimport { fetchEventSource, FetchEventSourceInit } from '../external/fetch-event-source'\nimport { idiomorph } from '../external/idiomorph'\nimport { Signal } from '../external/preact-core'\nimport { Actions, AttributeContext, AttributePlugin, ExpressionFunction, RegexpGroups } from '../types'\nimport { remoteSignals } from './attributes'\nimport { docWithViewTransitionAPI, supportsViewTransitions } from './visibility'\n\nconst DEFAULT_SETTLE_TIME = 500\nconst DEFAULT_USE_VIEW_TRANSITION = true\nconst DEFAULT_MERGE: FragmentMergeOption = 'morph'\n\nconst CONTENT_TYPE = 'Content-Type'\nconst DATASTAR_REQUEST = `${DATASTAR_STR}-request`\nconst APPLICATION_JSON = 'application/json'\nconst TRUE_STRING = 'true'\nconst EVENT_FRAGMENT = `${DATASTAR_CLASS_PREFIX}fragment`\nconst EVENT_SIGNAL = `${DATASTAR_CLASS_PREFIX}signal`\nconst EVENT_DELETE = `${DATASTAR_CLASS_PREFIX}delete`\nconst EVENT_REDIRECT = `${DATASTAR_CLASS_PREFIX}redirect`\nconst EVENT_CONSOLE = `${DATASTAR_CLASS_PREFIX}console`\n\nconst INDICATOR_CLASS = `${DATASTAR_CLASS_PREFIX}indicator`\nconst INDICATOR_LOADING_CLASS = `${INDICATOR_CLASS}-loading`\nconst SETTLING_CLASS = `${DATASTAR_CLASS_PREFIX}settling`\nconst SWAPPING_CLASS = `${DATASTAR_CLASS_PREFIX}swapping`\nconst SELECTOR_SELF_SELECTOR = 'self'\n\nconst GET = 'get',\n  POST = 'post',\n  PUT = 'put',\n  PATCH = 'patch',\n  DELETE = 'delete'\n\nconst FragmentMergeOptions = {\n  MorphElement: 'morph',\n  InnerElement: 'inner',\n  OuterElement: 'outer',\n  PrependElement: 'prepend',\n  AppendElement: 'append',\n  BeforeElement: 'before',\n  AfterElement: 'after',\n  UpsertAttributes: 'upsert_attributes',\n} as const\ntype FragmentMergeOption = (typeof FragmentMergeOptions)[keyof typeof FragmentMergeOptions]\n\ntype IndicatorReference = { el: HTMLElement; count: number }\n\n// Sets the fetch indicator selector\nexport const FetchIndicatorPlugin: AttributePlugin = {\n  prefix: 'fetchIndicator',\n  mustHaveEmptyKey: true,\n  mustNotEmptyExpression: true,\n  onGlobalInit: () => {\n    const style = document.createElement('style')\n    style.innerHTML = `\n.${INDICATOR_CLASS}{\n opacity:0;\n transition: opacity 300ms ease-out;\n}\n.${INDICATOR_LOADING_CLASS} {\n opacity:1;\n transition: opacity 300ms ease-in;\n}\n`\n    document.head.appendChild(style)\n  },\n  onLoad: (ctx) => {\n    return ctx.reactivity.effect(() => {\n      ctx.upsertIfMissingFromStore('_dsPlugins.fetch.indicatorElements', {})\n      ctx.upsertIfMissingFromStore('_dsPlugins.fetch.indicatorsVisible', [])\n      const c = ctx.reactivity.computed(() => `${ctx.expressionFn(ctx)}`)\n      const s = ctx.store()\n\n      const indicators = document.querySelectorAll(c.value)\n      if (indicators.length === 0) {\n        throw new Error(`No indicator found`)\n      }\n      indicators.forEach((indicator) => {\n        indicator.classList.add(INDICATOR_CLASS)\n      })\n\n      s._dsPlugins.fetch.indicatorElements[ctx.el.id] = ctx.reactivity.signal(indicators)\n\n      return () => {\n        delete s._dsPlugins.fetch.indicatorElements[ctx.el.id]\n      }\n    })\n  },\n}\n\nexport const HeadersPlugin: AttributePlugin = {\n  prefix: 'header',\n  mustNotEmptyKey: true,\n  mustNotEmptyExpression: true,\n  preprocessors: {\n    post: [\n      {\n        regexp: /(?<whole>.+)/g,\n        replacer: (groups: RegexpGroups) => {\n          const { whole } = groups\n          return `'${whole}'`\n        },\n      },\n    ],\n  },\n  onLoad: (ctx) => {\n    ctx.upsertIfMissingFromStore('_dsPlugins.fetch.headers', {})\n    const key = ctx.key.replace(/([a-z](?=[A-Z]))/g, '$1-').toUpperCase()\n    const value = ctx.expressionFn(ctx)\n    ctx.store()._dsPlugins.fetch.headers[key] = value\n    return () => {\n      delete ctx.store()._dsPlugins.fetch.headers[key]\n    }\n  },\n}\n\nexport const BackendPlugins: AttributePlugin[] = [FetchIndicatorPlugin, HeadersPlugin]\n\nasync function fetcher(method: string, urlExpression: string, ctx: AttributeContext, onlyRemote = true) {\n  const store = ctx.store()\n\n  if (!urlExpression) {\n    throw new Error(`No signal for ${method} on ${urlExpression}`)\n  }\n\n  let storeValue = { ...store.value }\n  if (onlyRemote) storeValue = remoteSignals(storeValue)\n  const storeJSON = JSON.stringify(storeValue)\n\n  const loadingTarget = ctx.el as HTMLElement\n\n  sendDatastarEvent(\n    'plugin',\n    'backend',\n    'fetch_start',\n    loadingTarget,\n    JSON.stringify({ method, urlExpression, onlyRemote, storeJSON }),\n  )\n  const indicatorElements: HTMLElement[] = store?._dsPlugins?.fetch?.indicatorElements\n    ? store._dsPlugins.fetch.indicatorElements[loadingTarget.id]?.value || []\n    : []\n  const indicatorsVisible: Signal<IndicatorReference[]> | undefined = store?._dsPlugins.fetch?.indicatorsVisible\n  if (!!indicatorElements?.forEach) {\n    indicatorElements.forEach((indicator) => {\n      if (!indicator || !indicatorsVisible) return\n      const indicatorVisibleIndex = indicatorsVisible.value.findIndex((indicatorVisible) => {\n        if (!indicatorVisible) return false\n        return indicator.isSameNode(indicatorVisible.el)\n      })\n      if (indicatorVisibleIndex > -1) {\n        const indicatorVisible = indicatorsVisible.value[indicatorVisibleIndex]\n        const indicatorsVisibleNew = [...indicatorsVisible.value]\n        delete indicatorsVisibleNew[indicatorVisibleIndex]\n        indicatorsVisible.value = [\n          ...indicatorsVisibleNew.filter((ind) => {\n            return !!ind\n          }),\n          { el: indicator, count: indicatorVisible.count + 1 },\n        ]\n      } else {\n        indicator.classList.remove(INDICATOR_CLASS)\n        indicator.classList.add(INDICATOR_LOADING_CLASS)\n        indicatorsVisible.value = [\n          ...indicatorsVisible.value,\n          {\n            el: indicator,\n            count: 1,\n          },\n        ]\n      }\n    })\n  }\n\n  const url = new URL(urlExpression, window.location.origin)\n  method = method.toUpperCase()\n  const req: FetchEventSourceInit = {\n    method,\n    headers: {\n      [CONTENT_TYPE]: APPLICATION_JSON,\n      [DATASTAR_REQUEST]: TRUE_STRING,\n    },\n    onmessage: (evt) => {\n      if (!evt.event) return\n      else if (!evt.event.startsWith(DATASTAR_CLASS_PREFIX)) {\n        console.log(`Unknown event: ${evt.event}`)\n        debugger\n      }\n\n      switch (evt.event) {\n        case EVENT_FRAGMENT:\n          const lines = evt.data.trim().split('\\n')\n          const knownEventTypes = ['selector', 'merge', 'settle', 'fragment', 'vt']\n\n          let fragment = '',\n            merge = DEFAULT_MERGE,\n            settleTime = DEFAULT_SETTLE_TIME,\n            useViewTransition = DEFAULT_USE_VIEW_TRANSITION,\n            exists = false,\n            selector = '',\n            currentDatatype = ''\n\n          for (let i = 0; i < lines.length; i++) {\n            let line = lines[i]\n            if (!line?.length) continue\n\n            const firstWord = line.split(' ', 1)[0]\n            const isDatatype = knownEventTypes.includes(firstWord)\n            const isNewDatatype = isDatatype && firstWord !== currentDatatype\n            if (isNewDatatype) {\n              currentDatatype = firstWord\n              line = line.slice(firstWord.length + 1)\n\n              switch (currentDatatype) {\n                case 'selector':\n                  selector = line\n                  break\n                case 'merge':\n                  merge = line as FragmentMergeOption\n                  exists = Object.values(FragmentMergeOptions).includes(merge)\n                  if (!exists) {\n                    throw new Error(`Unknown merge option: ${merge}`)\n                  }\n                  break\n                case 'settle':\n                  settleTime = parseInt(line)\n                  break\n                case 'fragment':\n                  break\n                case 'vt':\n                  useViewTransition = line === 'true'\n                  break\n                default:\n                  throw new Error(`Unknown data type`)\n              }\n            }\n\n            if (currentDatatype === 'fragment') fragment += line + '\\n'\n          }\n\n          if (!fragment?.length) fragment = '<div></div>'\n          mergeHTMLFragment(ctx, selector, merge, fragment, settleTime, useViewTransition)\n          sendDatastarEvent(\n            'plugin',\n            'backend',\n            'merge',\n            selector,\n            JSON.stringify({ fragment, settleTime, useViewTransition }),\n          )\n\n          break\n\n        case EVENT_SIGNAL:\n          let onlyIfMissing = false\n          let storeToMerge = ''\n\n          const signalLines = evt.data.trim().split('\\n')\n          for (let i = 0; i < signalLines.length; i++) {\n            const line = signalLines[i]\n            const [signalType, ...signalRest] = line.split(' ')\n            const signalLine = signalRest.join(' ')\n            switch (signalType) {\n              case 'onlyIfMissing':\n                onlyIfMissing = signalLine.trim() === 'true'\n                break\n              case 'store':\n                storeToMerge += `${signalLine}\\n`\n                break\n              default:\n                throw new Error(`Unknown signal type: ${signalType}`)\n            }\n          }\n\n          const fnContents = ` return Object.assign({...ctx.store()}, ${storeToMerge})`\n          try {\n            const fn = new Function('ctx', fnContents) as ExpressionFunction\n            const possibleMergeStore = fn(ctx)\n            const actualMergeStore = storeFromPossibleContents(ctx.store(), possibleMergeStore, onlyIfMissing)\n            ctx.mergeStore(actualMergeStore)\n            ctx.applyPlugins(document.body)\n          } catch (e) {\n            console.log(fnContents)\n            console.error(e)\n            debugger\n          }\n          break\n\n        case EVENT_DELETE:\n          const [deletePrefix, ...deleteRest] = evt.data.trim().split(' ')\n\n          switch (deletePrefix) {\n            case 'selector':\n              const deleteSelector = deleteRest.join(' ')\n              const deleteTargets = document.querySelectorAll(deleteSelector)\n              deleteTargets.forEach((target) => target.remove())\n              break\n            case 'paths':\n              const paths = deleteRest.join(' ').split(' ')\n              ctx.removeFromStore(...paths)\n              break\n            default:\n              throw new Error(`Unknown delete prefix: ${deletePrefix}`)\n          }\n          break\n\n        case EVENT_REDIRECT:\n          const [redirectSelector, ...redirectRest] = evt.data.trim().split(' ')\n          if (redirectSelector !== 'url') {\n            throw new Error(`Unknown redirect selector: ${redirectSelector}`)\n          }\n          const redirectTarget = redirectRest.join(' ')\n          sendDatastarEvent('plugin', 'backend', 'redirect', 'WINDOW', redirectTarget)\n          window.location.href = redirectTarget\n          break\n\n        case EVENT_CONSOLE:\n          const [consoleMode, ...consoleRest] = evt.data.trim().split(' ')\n          const consoleMessage = consoleRest.join(' ')\n          switch (consoleMode) {\n            case 'debug':\n            case 'error':\n            case 'info':\n            case 'group':\n            case 'groupEnd':\n            case 'log':\n            case 'warn':\n              console[consoleMode](consoleMessage)\n              break\n            default:\n              throw new Error(`Unknown console mode: '${consoleMode}', message: '${consoleMessage}'`)\n          }\n      }\n    },\n    onerror: (evt) => {\n      console.error(evt)\n    },\n    onclose: () => {\n      try {\n        const store = ctx.store()\n        const indicatorsVisible: Signal<IndicatorReference[]> = store?._dsPlugins?.fetch?.indicatorsVisible || []\n        const indicatorElements: HTMLElement[] = store?._dsPlugins?.fetch?.indicatorElements\n          ? store._dsPlugins.fetch.indicatorElements[loadingTarget.id]?.value || []\n          : []\n        const indicatorCleanupPromises: Promise<() => void>[] = []\n        if (indicatorElements?.forEach) {\n          indicatorElements.forEach((indicator) => {\n            if (!indicator || !indicatorsVisible) return\n            const indicatorsVisibleNew = indicatorsVisible.value\n            const indicatorVisibleIndex = indicatorsVisibleNew.findIndex((indicatorVisible) => {\n              if (!indicatorVisible) return false\n              return indicator.isSameNode(indicatorVisible.el)\n            })\n            const indicatorVisible = indicatorsVisibleNew[indicatorVisibleIndex]\n            if (!indicatorVisible) return\n            if (indicatorVisible.count < 2) {\n              indicatorCleanupPromises.push(\n                new Promise(() =>\n                  setTimeout(() => {\n                    indicator.classList.remove(INDICATOR_LOADING_CLASS)\n                    indicator.classList.add(INDICATOR_CLASS)\n                  }, 300),\n                ),\n              )\n              delete indicatorsVisibleNew[indicatorVisibleIndex]\n            } else if (indicatorVisibleIndex > -1) {\n              indicatorsVisibleNew[indicatorVisibleIndex].count = indicatorsVisibleNew[indicatorVisibleIndex].count - 1\n            }\n            indicatorsVisible.value = indicatorsVisibleNew.filter((ind) => {\n              return !!ind\n            })\n          })\n        }\n\n        Promise.all(indicatorCleanupPromises)\n      } catch (e) {\n        console.error(e)\n        debugger\n      } finally {\n        sendDatastarEvent('plugin', 'backend', 'fetch_end', loadingTarget, JSON.stringify({ method, urlExpression }))\n      }\n    },\n  }\n\n  if (method === 'GET') {\n    const queryParams = new URLSearchParams(url.search)\n    queryParams.append('datastar', storeJSON)\n    url.search = queryParams.toString()\n  } else {\n    req.body = storeJSON\n  }\n\n  const headers = store?._dsPlugins?.fetch?.headers || {}\n  if (req.headers) {\n    for (const [key, value] of Object.entries(headers)) {\n      if (key.startsWith('_')) continue\n      req.headers[key] = `${value}`\n    }\n  }\n\n  fetchEventSource(url, req)\n}\n\nconst fragContainer = document.createElement('template')\nexport function mergeHTMLFragment(\n  ctx: AttributeContext,\n  selector: string,\n  merge: FragmentMergeOption,\n  fragmentsRaw: string,\n  settleTime: number,\n  useViewTransition: boolean,\n) {\n  const { el } = ctx\n\n  fragContainer.innerHTML = fragmentsRaw.trim()\n  const frags = [...fragContainer.content.children]\n  frags.forEach((frag) => {\n    if (!(frag instanceof Element)) {\n      throw new Error(`No fragment found`)\n    }\n    const applyToTargets = (capturedTargets: Element[]) => {\n      for (const initialTarget of capturedTargets) {\n        initialTarget.classList.add(SWAPPING_CLASS)\n        const originalHTML = initialTarget.outerHTML\n        let modifiedTarget = initialTarget\n        switch (merge) {\n          case FragmentMergeOptions.MorphElement:\n            const result = idiomorph(modifiedTarget, frag, {\n              callbacks: {\n                beforeNodeRemoved: (oldNode: Element, _: Element) => {\n                  ctx.cleanupElementRemovals(oldNode)\n                  return true\n                },\n              },\n            })\n            if (!result?.length) {\n              throw new Error(`No morph result`)\n            }\n            const first = result[0] as Element\n            modifiedTarget = first\n            break\n          case FragmentMergeOptions.InnerElement:\n            // Replace the contents of the target element with the response\n            modifiedTarget.innerHTML = frag.innerHTML\n            break\n          case FragmentMergeOptions.OuterElement:\n            // Replace the entire target element with the response\n            modifiedTarget.replaceWith(frag)\n            break\n          case FragmentMergeOptions.PrependElement:\n            modifiedTarget.prepend(frag) //  Insert the response before the first child of the target element\n            break\n          case FragmentMergeOptions.AppendElement:\n            modifiedTarget.append(frag) //  Insert the response after the last child of the target element\n            break\n          case FragmentMergeOptions.BeforeElement:\n            modifiedTarget.before(frag) //  Insert the response before the target element\n            break\n          case FragmentMergeOptions.AfterElement:\n            modifiedTarget.after(frag) //  Insert the response after the target element\n            break\n          case FragmentMergeOptions.UpsertAttributes:\n            //  Upsert the attributes of the target element\n            frag.getAttributeNames().forEach((attrName) => {\n              const value = frag.getAttribute(attrName)!\n              modifiedTarget.setAttribute(attrName, value)\n            })\n            break\n          default:\n            throw new Error(`Unknown merge type: ${merge}`)\n        }\n        ctx.cleanupElementRemovals(modifiedTarget)\n        modifiedTarget.classList.add(SWAPPING_CLASS)\n\n        ctx.applyPlugins(document.body)\n\n        setTimeout(() => {\n          initialTarget.classList.remove(SWAPPING_CLASS)\n          modifiedTarget.classList.remove(SWAPPING_CLASS)\n        }, settleTime)\n\n        const revisedHTML = modifiedTarget.outerHTML\n\n        if (originalHTML !== revisedHTML) {\n          modifiedTarget.classList.add(SETTLING_CLASS)\n          setTimeout(() => {\n            modifiedTarget.classList.remove(SETTLING_CLASS)\n          }, settleTime)\n        }\n      }\n    }\n\n    const useElAsTarget = selector === SELECTOR_SELF_SELECTOR\n\n    let targets: Iterable<Element>\n    if (useElAsTarget) {\n      targets = [el]\n    } else {\n      const selectorOrID = selector || `#${frag.getAttribute('id')}`\n      targets = document.querySelectorAll(selectorOrID) || []\n      if (!!!targets) {\n        throw new Error(`No targets found for ${selectorOrID}`)\n      }\n    }\n    const allTargets = [...targets]\n    if (!allTargets.length) throw new Error(`No targets found for ${selector}`)\n\n    if (supportsViewTransitions && useViewTransition) {\n      docWithViewTransitionAPI.startViewTransition(() => applyToTargets(allTargets))\n    } else {\n      applyToTargets(allTargets)\n    }\n  })\n}\n\nexport const BackendActions: Actions = [GET, POST, PUT, PATCH, DELETE].reduce(\n  (acc, method) => {\n    acc[method] = (ctx, urlExpression, onlyRemoteRaw) => {\n      const onlyRemotes = ['true', true, undefined].includes(onlyRemoteRaw)\n      fetcher(method, urlExpression, ctx, onlyRemotes)\n    }\n    return acc\n  },\n  {\n    isFetching: (ctx: AttributeContext, selector: string) => {\n      const indicators = [...document.querySelectorAll(selector)]\n      const store = ctx.store()\n      const indicatorsVisible: IndicatorReference[] = store?._dsPlugins?.fetch.indicatorsVisible?.value || []\n      if (!!!indicators.length) return false\n\n      return indicators.some((indicator) => {\n        return indicatorsVisible\n          .filter((val) => !!val)\n          .some((indicatorVisible) => {\n            return indicatorVisible.el.isSameNode(indicator) && indicatorVisible.count > 0\n          })\n      })\n    },\n  } as Actions,\n)\n","import { Actions, AttributeContext } from '..'\n\nconst fit = (_: AttributeContext, v: number, oldMin: number, oldMax: number, newMin: number, newMax: number) => {\n  return ((v - oldMin) / (oldMax - oldMin)) * (newMax - newMin) + newMin\n}\n\nconst fitInt = (ctx: AttributeContext, v: number, oldMin: number, oldMax: number, newMin: number, newMax: number) => {\n  return Math.round(fit(ctx, v, oldMin, oldMax, newMin, newMax))\n}\n\nconst clampFit = (_: AttributeContext, v: number, oldMin: number, oldMax: number, newMin: number, newMax: number) => {\n  return Math.max(newMin, Math.min(newMax, fit(_, v, oldMin, oldMax, newMin, newMax)))\n}\n\nconst clampFitInt = (\n  _: AttributeContext,\n  v: number,\n  oldMin: number,\n  oldMax: number,\n  newMin: number,\n  newMax: number,\n) => {\n  return Math.round(clampFit(_, v, oldMin, oldMax, newMin, newMax))\n}\n\nexport const HelperActions: Actions = {\n  setAll: (ctx, regexp, newValue) => {\n    const re = new RegExp(regexp)\n    ctx.walkSignals((name, signal) => re.test(name) && (signal.value = newValue))\n  },\n  toggleAll: (ctx, regexp) => {\n    const re = new RegExp(regexp)\n    ctx.walkSignals((name, signal) => re.test(name) && (signal.value = !signal.value))\n  },\n  clipboard: (_, text) => {\n    if (!navigator.clipboard) throw new Error('Clipboard API not available')\n    navigator.clipboard.writeText(text)\n  },\n  fit,\n  fitInt,\n  clampFit,\n  clampFitInt,\n}\n","export * from './engine'\nexport * from './dom'\nexport * from './plugins'\nexport * from './types'\n\nimport { version } from '../../package.json'\nimport { Datastar } from './engine'\nimport {\n  AttributeActions,\n  AttributePlugins,\n  BackendActions,\n  BackendPlugins,\n  VisibilityActions,\n  VisibilityPlugins,\n} from './plugins'\nimport { HelperActions } from './plugins/helpers'\nimport { elemToSelector } from './plugins/core'\nimport { Actions, AttributePlugin, DatastarEvent, datastarEventName, SendDatastarEvent } from './types'\n\nexport { apply } from './external/ts-merge-patch'\n\nexport function runDatastarWith(actions: Actions = {}, ...plugins: AttributePlugin[]) {\n  const ds = new Datastar(actions, ...plugins)\n  ds.run()\n  return ds\n}\n\nexport function runDatastarWithAllPlugins(addedActions: Actions = {}, ...addedPlugins: AttributePlugin[]) {\n  const actions: Actions = Object.assign(\n    {},\n    HelperActions,\n    AttributeActions,\n    BackendActions,\n    VisibilityActions,\n    addedActions,\n  )\n  const allPlugins = [...BackendPlugins, ...VisibilityPlugins, ...AttributePlugins, ...addedPlugins]\n  return runDatastarWith(actions, ...allPlugins)\n}\n\nconst datastarDefaultEventOptions: CustomEventInit = {\n  bubbles: true,\n  cancelable: true,\n  composed: true,\n}\n\nconst winAny = window as any\n\nexport const sendDatastarEvent = ((\n  category: 'core' | 'plugin',\n  subcategory: string,\n  type: string,\n  target: Element | Document | Window | string,\n  message: string,\n  opts: CustomEventInit = datastarDefaultEventOptions,\n) => {\n  winAny.dispatchEvent(\n    new CustomEvent<DatastarEvent>(\n      datastarEventName,\n      Object.assign(\n        {\n          detail: {\n            time: new Date(),\n            category,\n            subcategory,\n            type,\n            target: elemToSelector(target),\n            message,\n          },\n        },\n        opts,\n      ),\n    ),\n  )\n}) satisfies SendDatastarEvent\n\n// Timeeout allows inspector to attach to all elements before sending the event\nif (!winAny.ds) {\n  setTimeout(() => {\n    sendDatastarEvent('core', 'init', 'start', document.body, `Datastar v${version} loading`)\n\n    const start = performance.now()\n    winAny.ds = runDatastarWithAllPlugins()\n    const end = performance.now()\n\n    sendDatastarEvent(\n      'core',\n      'init',\n      'end',\n      document.body,\n      `Datastar v${version} loaded and attached to all DOM elements in ${(end - start).toFixed(2)}ms`,\n    )\n\n    // define classes needed by the inspector\n    const style = document.createElement('style')\n    style.innerHTML = `\n.datastar-inspector-highlight {\n border: 2px solid blue;\n}\n`\n    document.head.appendChild(style)\n\n    // listen for messages from the inspector\n    window.addEventListener('datastar-inspector-event', (evt) => {\n      if ('detail' in evt && typeof evt.detail === 'object' && evt.detail) {\n        const { detail } = evt\n        if ('script' in detail && typeof detail.script === 'string') {\n          try {\n            const func = new Function(detail.script)\n            func()\n          } catch (e: unknown) {\n            console.error(e)\n          }\n        }\n      }\n    })\n  }, 0)\n}\n"]}