{"version":3,"file":"viselect.umd.cjs","names":[],"sources":["../src/EventEmitter.ts","../src/utils/css.ts","../src/utils/domRect.ts","../src/utils/frames.ts","../src/utils/intersects.ts","../src/utils/browser.ts","../src/utils/arrayify.ts","../src/utils/events.ts","../src/utils/selectAll.ts","../src/utils/matchesTrigger.ts","../src/index.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\ntype AnyFunction = (...args: any[]) => any;\ntype EventMap = Record<string, AnyFunction>;\n\nexport class EventTarget<Events extends EventMap> {\n  private readonly _listeners = new Map<keyof Events, Set<AnyFunction>>();\n\n  public addEventListener<K extends keyof Events>(event: K, cb: Events[K]): this {\n    const set = this._listeners.get(event) ?? new Set();\n    this._listeners.set(event, set);\n    set.add(cb as AnyFunction);\n    return this;\n  }\n\n  public removeEventListener<K extends keyof Events>(event: K, cb: Events[K]): this {\n    this._listeners.get(event)?.delete(cb as AnyFunction);\n    return this;\n  }\n\n  public dispatchEvent<K extends keyof Events>(event: K, ...data: Parameters<Events[K]>): boolean {\n    let ok = true;\n    for (const cb of this._listeners.get(event) ?? []) {\n      ok = cb(...data) !== false && ok;\n    }\n\n    return ok;\n  }\n\n  public unbindAllListeners(): void {\n    this._listeners.clear();\n  }\n\n  // Let's also support on, off and emit like node\n  public on = this.addEventListener;\n  public off = this.removeEventListener;\n  public emit = this.dispatchEvent;\n}\n","const unitify = (val: string | number, unit = 'px'): string => {\n  return typeof val === 'number' ? val + unit : val;\n};\n\n/**\n * Add css to a DOM-Element or returns the current\n * value of a property.\n *\n * @param el The Element.\n * @param attr The attribute or an object which holds css key-properties.\n * @param val The value for a single attribute.\n * @returns {*}\n */\nexport const css = (\n  { style }: HTMLElement,\n  attr: Partial<Record<keyof CSSStyleDeclaration, string | number>> | string,\n  val?: string | number\n): void => {\n  if (typeof attr === 'object') {\n    for (const [key, value] of Object.entries(attr)) {\n      if (value !== undefined) {\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        style[key as any] = unitify(value);\n      }\n    }\n  } else if (val !== undefined) {\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    style[attr as any] = unitify(val);\n  }\n};\n","// Polyfill for DOMRect as happy-dom and jsdom don't support it\nexport const domRect = (x = 0, y = 0, width = 0, height = 0): DOMRect => {\n  const rect = { x, y, width, height, top: y, left: x, right: x + width, bottom: y + height };\n  const toJSON = () => JSON.stringify(rect);\n  return { ...rect, toJSON };\n};\n","/* eslint-disable @typescript-eslint/no-explicit-any */\ntype AnyFunction = (...args: any[]) => void;\n\nexport interface Frames<F extends AnyFunction = AnyFunction> {\n  next(...args: Parameters<F>): void;\n\n  cancel(): void;\n}\n\nexport const frames = <F extends AnyFunction>(fn: F): Frames<F> => {\n  let previousArgs: Parameters<F>;\n  let frameId = -1;\n  let lock = false;\n\n  return {\n    next: (...args: Parameters<F>): void => {\n      previousArgs = args;\n\n      if (!lock) {\n        lock = true;\n        frameId = requestAnimationFrame(() => {\n          fn(...previousArgs);\n          lock = false;\n        });\n      }\n    },\n    cancel: () => {\n      cancelAnimationFrame(frameId);\n      lock = false;\n    }\n  };\n};\n","export type Intersection = 'center' | 'cover' | 'touch';\n\n/**\n * Check if two DOM-Elements intersects each other.\n * @param a BoundingClientRect of the first element.\n * @param b BoundingClientRect of the second element.\n * @param mode Options are center, cover or touch.\n * @returns {boolean} If both elements intersects each other.\n */\nexport const intersects = (a: DOMRect, b: DOMRect, mode: Intersection = 'touch'): boolean => {\n  switch (mode) {\n    case 'center': {\n      const bxc = b.left + b.width / 2;\n      const byc = b.top + b.height / 2;\n\n      return bxc >= a.left && bxc <= a.right && byc >= a.top && byc <= a.bottom;\n    }\n    case 'cover': {\n      return b.left >= a.left && b.top >= a.top && b.right <= a.right && b.bottom <= a.bottom;\n    }\n    case 'touch': {\n      return a.right >= b.left && a.left <= b.right && a.bottom >= b.top && a.top <= b.bottom;\n    }\n  }\n};\n","// Determines if the device's primary input supports touch\n// See this article: https://css-tricks.com/touch-devices-not-judged-size/\nexport const isTouchDevice = (): boolean => matchMedia('(hover: none), (pointer: coarse)').matches;\n\n// Determines if the browser is safari\nexport const isSafariBrowser = (): boolean => 'safari' in window;\n","// Turns a value into an array if it's not already an array\nexport const arrayify = <T>(value: T | T[]): T[] => (Array.isArray(value) ? value : [value]);\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { arrayify } from './arrayify';\n\ntype Method = 'addEventListener' | 'removeEventListener';\ntype AnyFunction = (...arg: any) => any;\n\nconst eventListener =\n  (method: Method) =>\n  (\n    items: (EventTarget | undefined) | (EventTarget | undefined)[],\n    events: string | string[],\n    fn: AnyFunction,\n    options = {}\n  ) => {\n    // Normalize array\n    if (items instanceof HTMLCollection || items instanceof NodeList) {\n      items = Array.from(items);\n    }\n\n    events = arrayify(events);\n    items = arrayify(items);\n\n    for (const el of items) {\n      if (el) {\n        for (const ev of events) {\n          el[method](ev, fn as EventListener, { capture: false, ...options });\n        }\n      }\n    }\n  };\n\n/**\n * Add event(s) to element(s).\n * @param elements DOM-Elements\n * @param events Event names\n * @param fn Callback\n * @param options Optional options\n * @return Array passed arguments\n */\nexport const on = eventListener('addEventListener');\n\n/**\n * Remove event(s) from element(s).\n * @param elements DOM-Elements\n * @param events Event names\n * @param fn Callback\n * @param options Optional options\n * @return Array passed arguments\n */\nexport const off = eventListener('removeEventListener');\n\n/**\n * Simplifies a touch / mouse-event\n * @param evt\n */\nexport const simplifyEvent = (\n  evt: any\n): {\n  target: HTMLElement;\n  x: number;\n  y: number;\n} => {\n  const { clientX, clientY, target } = evt.touches?.[0] ?? evt;\n  return { x: clientX, y: clientY, target };\n};\n","import { arrayify } from './arrayify';\n\nexport type SelectAllSelectors = (string | Element)[] | string | Element;\n\n/**\n * Takes a selector (or array of selectors) and returns the matched nodes.\n * @param selector The selector or an Array of selectors.\n * @param doc\n * @returns {Array} Array of DOM-Nodes.\n */\nexport const selectAll = (selector: SelectAllSelectors, doc: Document = document): Element[] =>\n  arrayify(selector)\n    .map((item) =>\n      typeof item === 'string' ? Array.from(doc.querySelectorAll(item)) : item instanceof Element ? item : null\n    )\n    .flat()\n    .filter(Boolean) as Element[];\n","// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button#value\nexport type MouseButton =\n  | 0 // Main\n  | 1 // Auxiliary\n  | 2 // Secondary\n  | 3 // Fourth\n  | 4; // Fifth\n\nexport type Modifier = 'ctrl' | 'alt' | 'shift';\n\nexport type MouseButtonWithModifiers = {\n  button: MouseButton;\n  modifiers: Modifier[];\n};\n\nexport type Trigger = MouseButton | MouseButtonWithModifiers;\n\n/**\n * Determines whether a MouseEvent should execute until completion depending on\n * which button and modifier(s) are active for the MouseEvent.\n * The Event will execute to completion if ANY of the triggers \"matches\"\n * @param event MouseEvent that should be checked\n * @param triggers A list of Triggers that signify that the event should execute until completion\n * @returns Whether the MouseEvent should execute until completion\n */\nexport const matchesTrigger = (event: MouseEvent, triggers: Trigger[]): boolean =>\n  triggers.some((trigger) => {\n    // The trigger requires only a specific button to be pressed\n    if (typeof trigger === 'number') {\n      return event.button === trigger;\n    }\n\n    // The trigger requires a specific button to be pressed AND some modifiers\n    if (typeof trigger === 'object') {\n      if (trigger.button !== event.button) {\n        return false;\n      }\n\n      return trigger.modifiers.every((modifier) => {\n        switch (modifier) {\n          case 'alt':\n            return event.altKey;\n          case 'ctrl':\n            return event.ctrlKey || event.metaKey;\n          case 'shift':\n            return event.shiftKey;\n        }\n      });\n    }\n\n    return false;\n  });\n","import { EventTarget } from './EventEmitter';\nimport type {\n  AreaLocation,\n  Coordinates,\n  ScrollEvent,\n  SelectionEvents,\n  SelectionOptions,\n  SelectionStore\n} from './types';\nimport type { PartialSelectionOptions } from './types';\nimport { css } from './utils/css';\nimport { domRect } from './utils/domRect';\nimport type { Frames } from './utils/frames';\nimport { frames } from './utils/frames';\nimport { intersects } from './utils/intersects';\nimport { isSafariBrowser, isTouchDevice } from './utils/browser';\nimport { on, off, simplifyEvent } from './utils/events';\nimport type { SelectAllSelectors } from './utils/selectAll';\nimport { selectAll } from './utils/selectAll';\nimport { matchesTrigger } from './utils/matchesTrigger';\n\n// Re-export types\nexport * from './types';\n\n// Some var shorting for better compression and readability\nconst { abs, max, min, ceil } = Math;\n\nconst makeSelectionStore = (stored: Element[] = []): SelectionStore => ({\n  stored,\n  selected: [],\n  touched: [],\n  changed: { added: [], removed: [] }\n});\n\nexport default class SelectionArea extends EventTarget<SelectionEvents> {\n  public static version = VERSION;\n\n  // Options\n  private readonly _options: SelectionOptions;\n\n  // Selection store\n  private _selection: SelectionStore = makeSelectionStore();\n\n  // Area element and clipping element\n  private readonly _area: HTMLElement;\n  private readonly _clippingElement: HTMLElement;\n\n  // Target container (element) and boundary (cached)\n  private _targetElement?: Element;\n  private _targetBoundary?: Element;\n  private _targetBoundaryScrolled = true;\n  private _targetRect?: DOMRect;\n  private _selectables: Element[] = [];\n  private _latestElement?: Element;\n\n  // Dynamically constructed area rect\n  private _areaLocation: AreaLocation = { y1: 0, x2: 0, y2: 0, x1: 0 };\n  private _areaRect = domRect();\n\n  // If a single click is being performed, it's a single-click until the user dragged the mouse\n  private _singleClick = true;\n  private _frame: Frames;\n\n  // Required data for scrolling\n  private _scrollAvailable = true;\n  private _scrollingActive = false;\n  private _scrollSpeed: Coordinates = { x: 0, y: 0 };\n  private _scrollDelta: Coordinates = { x: 0, y: 0 };\n\n  // Required for keydown scrolling\n  private _lastMousePosition = { x: 0, y: 0 };\n\n  constructor(opt: PartialSelectionOptions) {\n    super();\n\n    this._options = {\n      selectionAreaClass: opt.selectionAreaClass ?? 'selection-area',\n      selectionContainerClass: opt.selectionContainerClass ?? undefined,\n      selectables: opt.selectables ?? [],\n      document: opt.document ?? window.document,\n      startAreas: opt.startAreas ?? ['html'],\n      boundaries: opt.boundaries ?? ['html'],\n      container: opt.container ?? 'body',\n\n      behaviour: {\n        overlap: opt.behaviour?.overlap ?? 'invert',\n        intersect: opt.behaviour?.intersect ?? 'touch',\n        triggers: opt.behaviour?.triggers ?? [0],\n        startThreshold: opt.behaviour?.startThreshold\n          ? typeof opt.behaviour.startThreshold === 'number'\n            ? opt.behaviour.startThreshold\n            : { x: 10, y: 10, ...opt.behaviour.startThreshold }\n          : { x: 10, y: 10 },\n        scrolling: {\n          speedDivider: opt.behaviour?.scrolling?.speedDivider ?? 10,\n          manualSpeed: opt.behaviour?.scrolling?.manualSpeed ?? 750,\n          startScrollMargins: {\n            x: opt.behaviour?.scrolling?.startScrollMargins?.x ?? 0,\n            y: opt.behaviour?.scrolling?.startScrollMargins?.y ?? 0\n          }\n        }\n      },\n\n      features: {\n        range: opt.features?.range ?? true,\n        touch: opt.features?.touch ?? true,\n        deselectOnBlur: opt.features?.deselectOnBlur ?? false,\n        singleTap: {\n          allow: opt.features?.singleTap?.allow ?? true,\n          intersect: opt.features?.singleTap?.intersect ?? 'native'\n        }\n      }\n    };\n\n    // Bind locale functions to instance\n    /* eslint-disable @typescript-eslint/no-explicit-any */\n    for (const key of Object.getOwnPropertyNames(Object.getPrototypeOf(this))) {\n      if (typeof (this as any)[key] === 'function') {\n        (this as any)[key] = (this as any)[key].bind(this);\n      }\n    }\n\n    const { document, selectionAreaClass, selectionContainerClass } = this._options;\n    this._area = document.createElement('div');\n    this._clippingElement = document.createElement('div');\n    this._clippingElement.appendChild(this._area);\n\n    this._area.classList.add(selectionAreaClass);\n\n    if (selectionContainerClass) {\n      this._clippingElement.classList.add(selectionContainerClass);\n    }\n\n    css(this._area, {\n      willChange: 'top, left, bottom, right, width, height',\n      top: 0,\n      left: 0,\n      position: 'fixed'\n    });\n\n    css(this._clippingElement, {\n      overflow: 'hidden',\n      position: 'fixed',\n      transform: 'translate3d(0, 0, 0)', // https://stackoverflow.com/a/38268846\n      pointerEvents: 'none',\n      zIndex: '1'\n    });\n\n    this._frame = frames((evt: MouseEvent | TouchEvent) => {\n      this._recalculateSelectionAreaRect();\n      this._updateElementSelection();\n      this._emitEvent('move', evt);\n      this._redrawSelectionArea();\n    });\n\n    this.enable();\n  }\n\n  _toggleStartEvents(activate = true): void {\n    const { document, features } = this._options;\n    const fn = activate ? on : off;\n\n    fn(document, 'mousedown', this._onTapStart);\n\n    if (features.touch) {\n      fn(document, 'touchstart', this._onTapStart, { passive: false });\n    }\n  }\n\n  _onTapStart(evt: MouseEvent | TouchEvent, silent = false): void {\n    const { x, y, target } = simplifyEvent(evt);\n    const { document, startAreas, boundaries, features, behaviour } = this._options;\n    const targetBoundingClientRect = target.getBoundingClientRect();\n\n    if (evt instanceof MouseEvent && !matchesTrigger(evt, behaviour.triggers)) {\n      return;\n    }\n\n    // Find start-areas and boundaries\n    const resolvedStartAreas = selectAll(startAreas, document);\n    const resolvedBoundaries = selectAll(boundaries, document);\n\n    // Check in which container the user currently acts\n    this._targetElement = resolvedBoundaries.find((el) =>\n      intersects(el.getBoundingClientRect(), targetBoundingClientRect)\n    );\n\n    // Check if the area starts in one of the start areas / boundaries\n    const evtPath = evt.composedPath();\n    const targetStartArea = resolvedStartAreas.find((el) => evtPath.includes(el));\n    this._targetBoundary = resolvedBoundaries.find((el) => evtPath.includes(el));\n\n    if (!this._targetElement || !targetStartArea || !this._targetBoundary) {\n      return;\n    }\n\n    if (!silent && this._emitEvent('beforestart', evt) === false) {\n      return;\n    }\n\n    this._areaLocation = { x1: x, y1: y, x2: 0, y2: 0 };\n\n    // Lock scrolling in the target container\n    const scrollElement = document.scrollingElement ?? document.body;\n    this._scrollDelta = { x: scrollElement.scrollLeft, y: scrollElement.scrollTop };\n\n    // To detect single-click\n    this._singleClick = true;\n    this.clearSelection(false, true);\n\n    on(document, ['touchmove', 'mousemove'], this._delayedTapMove, { passive: false });\n    on(document, ['mouseup', 'touchcancel', 'touchend'], this._onTapStop);\n    on(document, 'scroll', this._onScroll);\n\n    if (features.deselectOnBlur) {\n      this._targetBoundaryScrolled = false;\n      on(this._targetBoundary, 'scroll', this._onStartAreaScroll);\n    }\n  }\n\n  _onSingleTap(evt: MouseEvent | TouchEvent): void {\n    const {\n      singleTap: { intersect },\n      range\n    } = this._options.features;\n    const e = simplifyEvent(evt);\n    let target;\n\n    if (intersect === 'native') {\n      target = e.target;\n    } else if (intersect === 'touch') {\n      this.resolveSelectables();\n\n      const { x, y } = e;\n      target = this._selectables.find((v) => {\n        const { right, left, top, bottom } = v.getBoundingClientRect();\n        return x < right && x > left && y < bottom && y > top;\n      });\n    }\n\n    if (!target) {\n      return;\n    }\n\n    /**\n     * Resolve selectables again.\n     * If the user started in a scrollable area, they will be reduced\n     * to the current area. Prevent the exclusion of these if a range-selection\n     * gets performed.\n     */\n    this.resolveSelectables();\n\n    // Traverse dom upwards to check if the target is selectable\n    while (!this._selectables.includes(target)) {\n      if (target.parentElement) {\n        target = target.parentElement;\n      } else {\n        if (!this._targetBoundaryScrolled) {\n          this.clearSelection();\n        }\n\n        return;\n      }\n    }\n\n    // Grab the current store first in case it gets set back\n    const { stored } = this._selection;\n    this._emitEvent('start', evt);\n\n    if (evt.shiftKey && range && this._latestElement) {\n      const reference = this._latestElement;\n\n      // Resolve the correct range\n      const [preceding, following] =\n        reference.compareDocumentPosition(target) & 4 ? [target, reference] : [reference, target];\n\n      const rangeItems = [\n        ...this._selectables.filter(\n          (el) => el.compareDocumentPosition(preceding) & 4 && el.compareDocumentPosition(following) & 2\n        ),\n        preceding,\n        following\n      ];\n\n      this.select(rangeItems);\n      this._latestElement = reference; // the latestElement is by default cleared in .select()\n    } else if (\n      stored.includes(target) &&\n      (stored.length === 1 || evt.ctrlKey || stored.every((v) => this._selection.stored.includes(v)))\n    ) {\n      this.deselect(target);\n    } else {\n      this.select(target);\n      this._latestElement = target;\n    }\n  }\n\n  _delayedTapMove(evt: MouseEvent | TouchEvent): void {\n    const {\n      container,\n      document,\n      behaviour: { startThreshold }\n    } = this._options;\n    const { x1, y1 } = this._areaLocation; // Coordinates of the first \"tap\"\n    const { x, y } = simplifyEvent(evt);\n\n    // Check the pixel threshold\n    if (\n      // Single number for both coordinates\n      (typeof startThreshold === 'number' && abs(x + y - (x1 + y1)) >= startThreshold) ||\n      // Different x and y threshold\n      (typeof startThreshold === 'object' && abs(x - x1) >= (startThreshold as Coordinates).x) ||\n      abs(y - y1) >= (startThreshold as Coordinates).y\n    ) {\n      off(document, ['mousemove', 'touchmove'], this._delayedTapMove, { passive: false });\n\n      if (this._emitEvent('beforedrag', evt) === false) {\n        off(document, ['mouseup', 'touchcancel', 'touchend'], this._onTapStop);\n        return;\n      }\n\n      on(document, ['mousemove', 'touchmove'], this._onTapMove, { passive: false });\n\n      // Make area element visible\n      css(this._area, 'display', 'block');\n\n      // Append selection-area to the dom\n      selectAll(container, document)[0].appendChild(this._clippingElement);\n\n      this.resolveSelectables();\n\n      // An action is recognized as single-select until the user performed a multi-selection\n      this._singleClick = false;\n\n      // Just saving the boundaries of this container for later\n      this._targetRect = this._targetElement!.getBoundingClientRect();\n\n      // Find a container and check if it's scrollable\n      this._scrollAvailable =\n        this._targetElement!.scrollHeight !== this._targetElement!.clientHeight ||\n        this._targetElement!.scrollWidth !== this._targetElement!.clientWidth;\n\n      if (this._scrollAvailable) {\n        // Detect mouse scrolling\n        on(this._targetElement, 'wheel', this._wheelScroll, { passive: false });\n\n        // Detect keyboard scrolling\n        on(this._options.document, 'keydown', this._keyboardScroll, { passive: false });\n\n        /**\n         * The selection-area will also cover another element\n         * out of the current scrollable parent. So find all elements\n         * that are in the current scrollable element. Now these are\n         * the only selectables instead of all.\n         */\n        this._selectables = this._selectables.filter((s) => this._targetElement!.contains(s));\n      }\n\n      // Re-setup selection area and fire event\n      this._setupSelectionArea();\n      this._emitEvent('start', evt);\n      this._onTapMove(evt);\n    }\n\n    this._handleMoveEvent(evt);\n  }\n\n  _setupSelectionArea(): void {\n    const { _clippingElement, _targetElement, _area } = this;\n    const tr = (this._targetRect = _targetElement!.getBoundingClientRect());\n\n    if (this._scrollAvailable) {\n      /**\n       * To clip the area, the selection area has a parent\n       * which has exactly the same dimensions as the scrollable element.\n       * Now if the area exceeds these boundaries, it will be cropped.\n       */\n      css(_clippingElement, {\n        top: tr.top,\n        left: tr.left,\n        width: tr.width,\n        height: tr.height\n      });\n\n      /**\n       * The area element is relative to the clipping element,\n       * but when this is moved or transformed, we need to correct\n       * the positions via a negative margin.\n       */\n      css(_area, {\n        marginTop: -tr.top,\n        marginLeft: -tr.left\n      });\n    } else {\n      // \"Reset\" styles\n      css(_clippingElement, {\n        top: 0,\n        left: 0,\n        width: '100%',\n        height: '100%'\n      });\n\n      css(_area, {\n        marginTop: 0,\n        marginLeft: 0\n      });\n    }\n  }\n\n  _onTapMove(evt: MouseEvent | TouchEvent): void {\n    const { _scrollSpeed, _areaLocation, _options, _frame } = this;\n    const { speedDivider } = _options.behaviour.scrolling;\n    const _targetElement = this._targetElement as Element;\n\n    const { x, y } = simplifyEvent(evt);\n    _areaLocation.x2 = x;\n    _areaLocation.y2 = y;\n\n    this._lastMousePosition.x = x;\n    this._lastMousePosition.y = y;\n\n    if (this._scrollAvailable && !this._scrollingActive && (_scrollSpeed.y || _scrollSpeed.x)) {\n      // Continuous scrolling\n      this._scrollingActive = true;\n\n      // Store scroll positions to calculate deltas between frames.\n      let lastScrollTop = _targetElement.scrollTop;\n      let lastScrollLeft = _targetElement.scrollLeft;\n\n      const scroll = () => {\n        if (!this._scrollingActive) {\n          return;\n        }\n\n        if (_scrollSpeed.y) {\n          _targetElement.scrollTop += ceil(_scrollSpeed.y / speedDivider);\n        }\n\n        if (_scrollSpeed.x) {\n          _targetElement.scrollLeft += ceil(_scrollSpeed.x / speedDivider);\n        }\n\n        // Measure the actual scroll delta since the last frame.\n        const deltaY = _targetElement.scrollTop - lastScrollTop;\n        const deltaX = _targetElement.scrollLeft - lastScrollLeft;\n\n        // Compensate the selection area's origin by the actual scroll delta.\n        _areaLocation.y1 -= deltaY;\n        _areaLocation.x1 -= deltaX;\n\n        // Store the current scroll position for the next frame's calculation.\n        lastScrollTop = _targetElement.scrollTop;\n        lastScrollLeft = _targetElement.scrollLeft;\n\n        /**\n         * We changed the start coordinates -> redraw the selection-area\n         * We changed the dimensions of the area element -> re-calc selected elements\n         * The selected elements array has been changed -> fire event\n         */\n        _frame.next(evt);\n\n        // Keep scrolling even if the user stops to move his pointer\n        if (_scrollSpeed.x || _scrollSpeed.y) {\n          requestAnimationFrame(scroll);\n        } else {\n          this._scrollingActive = false;\n        }\n      };\n\n      requestAnimationFrame(scroll);\n    } else if (!this._scrollingActive) {\n      /**\n       * Perform redrawing only if scrolling is not active.\n       * If scrolling is active, this area is getting re-dragged by the\n       * anonymize scroll function.\n       */\n      _frame.next(evt);\n    }\n\n    this._handleMoveEvent(evt);\n  }\n\n  _handleMoveEvent(evt: MouseEvent | TouchEvent) {\n    const { features } = this._options;\n\n    /**\n     * - Prevent auto-refresh for when pulling down on touch devices.\n     * - Prevent auto-scroll by the browser when on safari, and scrolling is handled by this library.\n     */\n    if ((features.touch && isTouchDevice()) || (this._scrollAvailable && isSafariBrowser())) {\n      evt.preventDefault(); // Prevent swipe-down refresh\n    }\n  }\n\n  _onScroll(): void {\n    const {\n      _scrollDelta,\n      _options: { document }\n    } = this;\n    const { scrollTop, scrollLeft } = document.scrollingElement ?? document.body;\n\n    // Adjust area start location\n    this._areaLocation.x1 += _scrollDelta.x - scrollLeft;\n    this._areaLocation.y1 += _scrollDelta.y - scrollTop;\n    _scrollDelta.x = scrollLeft;\n    _scrollDelta.y = scrollTop;\n\n    // The area needs to be set back as the target-container has changed in its position\n    this._setupSelectionArea();\n    this._frame.next(null);\n  }\n\n  _onStartAreaScroll(): void {\n    this._targetBoundaryScrolled = true;\n    off(this._targetElement, 'scroll', this._onStartAreaScroll);\n  }\n\n  _wheelScroll(evt: ScrollEvent): void {\n    const { manualSpeed } = this._options.behaviour.scrolling;\n\n    // Consistent scrolling speed on all browsers\n    const deltaY = evt.deltaY ? (evt.deltaY > 0 ? 1 : -1) : 0;\n    const deltaX = evt.deltaX ? (evt.deltaX > 0 ? 1 : -1) : 0;\n    this._scrollSpeed.y += deltaY * manualSpeed;\n    this._scrollSpeed.x += deltaX * manualSpeed;\n    this._onTapMove(evt);\n\n    // Prevent default scrolling behavior, e.g. page scrolling\n    evt.preventDefault();\n  }\n\n  _keyboardScroll(evt: KeyboardEvent): void {\n    const { manualSpeed } = this._options.behaviour.scrolling;\n\n    const deltaX = evt.key === 'ArrowLeft' ? -1 : evt.key === 'ArrowRight' ? 1 : 0;\n    const deltaY = evt.key === 'ArrowUp' ? -1 : evt.key === 'ArrowDown' ? 1 : 0;\n\n    this._scrollSpeed.x += Math.sign(deltaX) * manualSpeed;\n    this._scrollSpeed.y += Math.sign(deltaY) * manualSpeed;\n\n    evt.preventDefault();\n\n    this._onTapMove({\n      clientX: this._lastMousePosition.x,\n      clientY: this._lastMousePosition.y,\n      preventDefault: () => void 0\n    } as ScrollEvent);\n  }\n\n  _recalculateSelectionAreaRect(): void {\n    const { _scrollSpeed, _areaLocation, _targetElement, _options } = this;\n    const { scrollTop, scrollHeight, clientHeight, scrollLeft, scrollWidth, clientWidth } = _targetElement as Element;\n    const _targetRect = this._targetRect as DOMRect;\n\n    const { x1, y1 } = _areaLocation;\n    let { x2, y2 } = _areaLocation;\n\n    const {\n      behaviour: {\n        scrolling: { startScrollMargins }\n      }\n    } = _options;\n\n    if (x2 < _targetRect.left + startScrollMargins.x) {\n      _scrollSpeed.x = scrollLeft ? -abs(_targetRect.left - x2 + startScrollMargins.x) : 0;\n      x2 = x2 < _targetRect.left ? _targetRect.left : x2;\n    } else if (x2 > _targetRect.right - startScrollMargins.x) {\n      _scrollSpeed.x =\n        scrollWidth - scrollLeft - clientWidth\n          ? abs(_targetRect.left + _targetRect.width - x2 - startScrollMargins.x)\n          : 0;\n      x2 = x2 > _targetRect.right ? _targetRect.right : x2;\n    } else {\n      _scrollSpeed.x = 0;\n    }\n\n    if (y2 < _targetRect.top + startScrollMargins.y) {\n      _scrollSpeed.y = scrollTop ? -abs(_targetRect.top - y2 + startScrollMargins.y) : 0;\n      y2 = y2 < _targetRect.top ? _targetRect.top : y2;\n    } else if (y2 > _targetRect.bottom - startScrollMargins.y) {\n      _scrollSpeed.y =\n        scrollHeight - scrollTop - clientHeight\n          ? abs(_targetRect.top + _targetRect.height - y2 - startScrollMargins.y)\n          : 0;\n      y2 = y2 > _targetRect.bottom ? _targetRect.bottom : y2;\n    } else {\n      _scrollSpeed.y = 0;\n    }\n\n    const x3 = min(x1, x2);\n    const y3 = min(y1, y2);\n    const x4 = max(x1, x2);\n    const y4 = max(y1, y2);\n\n    this._areaRect = domRect(x3, y3, x4 - x3, y4 - y3);\n  }\n\n  _redrawSelectionArea(): void {\n    const { x, y, width, height } = this._areaRect;\n    const { style } = this._area;\n\n    // Using transform will make the area's borders look blurry\n    style.left = `${x}px`;\n    style.top = `${y}px`;\n    style.width = `${width}px`;\n    style.height = `${height}px`;\n  }\n\n  _onTapStop(evt: MouseEvent | TouchEvent | null, silent: boolean): void {\n    const { document, features } = this._options;\n    const { _singleClick } = this;\n\n    // Remove event handlers\n    off(this._targetElement, 'scroll', this._onStartAreaScroll);\n    off(document, ['mousemove', 'touchmove'], this._delayedTapMove);\n    off(document, ['touchmove', 'mousemove'], this._onTapMove);\n    off(document, ['mouseup', 'touchcancel', 'touchend'], this._onTapStop);\n    off(document, 'scroll', this._onScroll);\n\n    // Keep selection until the next time\n    this._keepSelection();\n\n    if (evt && _singleClick && features.singleTap.allow) {\n      this._onSingleTap(evt);\n    } else if (!_singleClick && !silent) {\n      this._updateElementSelection();\n      this._emitEvent('stop', evt);\n    }\n\n    this._scrollSpeed.x = 0;\n    this._scrollSpeed.y = 0;\n\n    // Unbind mouse scrolling listener\n    off(this._targetElement, 'wheel', this._wheelScroll, { passive: true });\n\n    // Unbind keyboard scrolling listener\n    off(this._options.document, 'keydown', this._keyboardScroll, { passive: true });\n\n    // Remove selection-area from dom\n    this._clippingElement.remove();\n\n    // Cancel current frame\n    this._frame?.cancel();\n\n    // Hide selection area\n    css(this._area, 'display', 'none');\n  }\n\n  _updateElementSelection(): void {\n    const { _selectables, _options, _selection, _areaRect } = this;\n    const { stored, selected, touched } = _selection;\n    const { intersect, overlap } = _options.behaviour;\n\n    const invert = overlap === 'invert';\n    const newlyTouched: Element[] = [];\n    const added: Element[] = [];\n    const removed: Element[] = [];\n\n    // Find newly selected elements\n    for (let i = 0; i < _selectables.length; i++) {\n      const node = _selectables[i];\n\n      // Check if the area intersects an element\n      if (intersects(_areaRect, node.getBoundingClientRect(), intersect)) {\n        // Check if the element wasn't present in the last selection.\n        if (!selected.includes(node)) {\n          // Check if the user wants to invert the selection for already selected elements\n          if (invert && stored.includes(node)) {\n            removed.push(node);\n            continue;\n          } else if (overlap === 'drop' && stored.includes(node)) {\n            touched.push(node);\n            newlyTouched.push(node);\n            continue;\n          } else {\n            added.push(node);\n          }\n        } else if (stored.includes(node) && !touched.includes(node)) {\n          touched.push(node);\n        }\n\n        newlyTouched.push(node);\n      }\n    }\n\n    // Re-select elements which were previously stored\n    if (invert) {\n      added.push(...stored.filter((v) => !selected.includes(v)));\n    }\n\n    // Check which elements where removed since last selection\n    const keep = overlap === 'keep';\n    for (let i = 0; i < selected.length; i++) {\n      const node = selected[i];\n\n      if (\n        !newlyTouched.includes(node) &&\n        !(\n          // Check if the user wants to keep previously selected elements, e.g.,\n          // not make them part of the current selection as soon as they're touched.\n          keep && stored.includes(node)\n        )\n      ) {\n        removed.push(node);\n      }\n    }\n\n    _selection.selected = newlyTouched;\n    _selection.changed = { added, removed };\n\n    // Prevent range selection when selection an area.\n    this._latestElement = undefined;\n  }\n\n  _emitEvent(name: keyof SelectionEvents, evt: MouseEvent | TouchEvent | null): unknown {\n    return this.emit(name, {\n      event: evt,\n      store: this._selection,\n      selection: this\n    });\n  }\n\n  _keepSelection(): void {\n    const { _options, _selection } = this;\n    const { selected, changed, touched, stored } = _selection;\n    const addedElements = selected.filter((el) => !stored.includes(el));\n\n    switch (_options.behaviour.overlap) {\n      case 'drop': {\n        _selection.stored = [\n          ...addedElements,\n          ...stored.filter((el) => !touched.includes(el)) // Elements not touched\n        ];\n        break;\n      }\n      case 'invert': {\n        _selection.stored = [\n          ...addedElements,\n          ...stored.filter((el) => !changed.removed.includes(el)) // Elements not removed from selection\n        ];\n        break;\n      }\n      case 'keep': {\n        _selection.stored = [\n          ...stored,\n          ...selected.filter((el) => !stored.includes(el)) // Newly added\n        ];\n        break;\n      }\n    }\n  }\n\n  /**\n   * Manually triggers the start of a selection\n   * @param evt A MouseEvent / TouchEvent-like object\n   * @param silent If beforestart should be fired\n   */\n  trigger(evt: MouseEvent | TouchEvent, silent = true): void {\n    this._onTapStart(evt, silent);\n  }\n\n  /**\n   * Can be used if during a selection elements have been added\n   * Will update everything that can be selected\n   */\n  resolveSelectables(): void {\n    this._selectables = selectAll(this._options.selectables, this._options.document);\n  }\n\n  /**\n   * Same as deselecting, but for all elements currently selected\n   * @param includeStored If the store should also get cleared\n   * @param quiet If move / stop events should be fired\n   */\n  clearSelection(includeStored = true, quiet = false): void {\n    const { selected, stored, changed } = this._selection;\n\n    changed.added = [];\n    changed.removed.push(...selected, ...(includeStored ? stored : []));\n\n    // Fire event\n    if (!quiet) {\n      this._emitEvent('move', null);\n      this._emitEvent('stop', null);\n    }\n\n    // Reset state\n    this._selection = makeSelectionStore(includeStored ? [] : stored);\n  }\n\n  /**\n   * @returns {Array} Selected elements\n   */\n  getSelection(): Element[] {\n    return this._selection.stored;\n  }\n\n  /**\n   * @returns {HTMLElement} The selection area element\n   */\n  getSelectionArea(): HTMLElement {\n    return this._area;\n  }\n\n  /**\n   * @returns {Element[]} Available selectable elements for current selection\n   */\n  getSelectables(): Element[] {\n    return this._selectables;\n  }\n\n  /**\n   * Set the location of the selection area\n   * @param location A partial AreaLocation object\n   */\n  setAreaLocation(location: Partial<AreaLocation>) {\n    Object.assign(this._areaLocation, location);\n    this._redrawSelectionArea();\n  }\n\n  /**\n   * @returns {AreaLocation} The current location of the selection area\n   */\n  getAreaLocation(): AreaLocation {\n    return this._areaLocation;\n  }\n\n  /**\n   * Cancel the current selection process, pass true to fire a stop event after cancel\n   * @param keepEvent If a stop event should be fired\n   */\n  cancel(keepEvent = false): void {\n    this._onTapStop(null, !keepEvent);\n  }\n\n  /**\n   * Unbinds all events and removes the area-element.\n   */\n  destroy(): void {\n    this.cancel();\n    this.disable();\n    this._clippingElement.remove();\n    super.unbindAllListeners();\n  }\n\n  /**\n   * Enable selecting elements\n   */\n  enable = this._toggleStartEvents;\n\n  /**\n   * Disable selecting elements\n   */\n  disable = this._toggleStartEvents.bind(this, false);\n\n  /**\n   * Adds elements to the selection\n   * @param query CSS Query, can be an array of queries\n   * @param quiet If this should not trigger the move event\n   */\n  select(query: SelectAllSelectors, quiet = false): Element[] {\n    const { changed, selected, stored } = this._selection;\n    const elements = selectAll(query, this._options.document).filter(\n      (el, index, all) => !selected.includes(el) && !stored.includes(el) && all.indexOf(el) === index\n    );\n\n    // Update element lists\n    stored.push(...elements);\n    selected.push(...elements);\n    changed.added.push(...elements);\n    changed.removed = [];\n\n    // We don't know which element was \"selected\" first, so clear it\n    this._latestElement = undefined;\n\n    // Fire event\n    if (!quiet) {\n      this._emitEvent('move', null);\n      this._emitEvent('stop', null);\n    }\n\n    return elements;\n  }\n\n  /**\n   * Removes a particular element from the selection\n   * @param query CSS Query, can be an array of queries\n   * @param quiet If this should not trigger the move event\n   */\n  deselect(query: SelectAllSelectors, quiet = false) {\n    const { selected, stored, changed } = this._selection;\n\n    const elements = selectAll(query, this._options.document).filter(\n      (el) => selected.includes(el) || stored.includes(el)\n    );\n\n    this._selection.stored = stored.filter((el) => !elements.includes(el));\n    this._selection.selected = selected.filter((el) => !elements.includes(el));\n    this._selection.changed.added = [];\n    this._selection.changed.removed.push(...elements.filter((el) => !changed.removed.includes(el)));\n\n    // We don't know which element was \"selected\" first, so clear it\n    this._latestElement = undefined;\n\n    // Fire event\n    if (!quiet) {\n      this._emitEvent('move', null);\n      this._emitEvent('stop', null);\n    }\n  }\n}\n"],"mappings":"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"}