{
  "version": 3,
  "sources": ["../../src/observe/index.ts", "../../node_modules/distilt/shim-node-cjs.js", "../../src/internal/util.ts"],
  "sourcesContent": ["/**\n * [[include:src/observe/README.md]]\n *\n * @packageDocumentation\n * @module twind/observe\n */\n\nimport type { TW } from 'twind'\nimport { tw as defaultTW } from 'twind'\nimport { ensureMaxSize } from '../internal/util'\n\nexport * from 'twind'\n\n/**\n * Options for {@link createObserver}.\n */\nexport interface ShimConfiguration {\n  /**\n   * Custom {@link twind.tw | tw} instance to use (default: {@link twind.tw}).\n   */\n  tw?: TW\n}\n\n/** Provides the ability to watch for changes being made to the DOM tree. */\nexport interface TwindObserver {\n  /**\n   * Stops observer from observing any mutations.\n   */\n  disconnect(): TwindObserver\n\n  /**\n   * Observe an additional element.\n   */\n  observe(target: Node): TwindObserver\n}\n\nconst caches = new WeakMap<TW, Map<string, string>>()\n\nconst getCache = (tw: TW): Map<string, string> => {\n  let rulesToClassCache = caches.get(tw)\n\n  if (!rulesToClassCache) {\n    rulesToClassCache = new Map<string, string>()\n    caches.set(tw, rulesToClassCache)\n  }\n\n  return rulesToClassCache\n}\n\nconst uniq = <T>(value: T, index: number, values: T[]) => values.indexOf(value) == index\n\n/**\n * Creates a new {@link TwindObserver}.\n *\n * @param options to use\n */\nexport const createObserver = ({ tw = defaultTW }: ShimConfiguration = {}): TwindObserver => {\n  if (typeof MutationObserver == 'function') {\n    const rulesToClassCache = getCache(tw)\n\n    const handleMutation = ({ target, addedNodes }: MinimalMutationRecord): void => {\n      // Not using target.classList.value (not supported in all browsers) or target.class (this is an SVGAnimatedString for svg)\n      const rules = (target as Element).getAttribute?.('class')\n\n      if (rules) {\n        let className = rulesToClassCache.get(rules)\n\n        if (!className) {\n          className = tw(rules).split(/ +/g).filter(uniq).join(' ')\n\n          // Remember the generated class name\n          rulesToClassCache.set(rules, className)\n          rulesToClassCache.set(className, className)\n\n          // Ensure the cache does not grow unlimited\n          ensureMaxSize(rulesToClassCache, 30000)\n        }\n\n        if (rules !== className) {\n          // Not using `target.className = ...` as that is read-only for SVGElements\n          // eslint-disable-next-line @typescript-eslint/no-extra-semi\n          ;(target as Element).setAttribute('class', className)\n        }\n      }\n\n      for (let index = addedNodes.length; index--; ) {\n        const node = addedNodes[index]\n\n        handleMutations([\n          {\n            target: node,\n            addedNodes: (node as Element).children || [],\n          },\n        ])\n      }\n    }\n\n    const handleMutations = (mutations: MinimalMutationRecord[]): void => {\n      mutations.forEach(handleMutation)\n\n      // handle any still-pending mutations\n      mutations = observer.takeRecords()\n      if (mutations) mutations.forEach(handleMutation)\n    }\n\n    const observer = new MutationObserver(handleMutations)\n\n    return {\n      observe(target) {\n        handleMutations([{ target, addedNodes: [target] }])\n\n        observer.observe(target, {\n          attributes: true,\n          attributeFilter: ['class'],\n          subtree: true,\n          childList: true,\n        })\n\n        return this\n      },\n\n      disconnect() {\n        observer.disconnect()\n        return this\n      },\n    }\n  }\n\n  // Non-browser-like environment – return a no-op implementation\n  return {\n    observe() {\n      return this\n    },\n\n    disconnect() {\n      return this\n    },\n  }\n}\n\n/**\n * Creates a new {@link TwindObserver} and {@link TwindObserver.observe | start observing} the passed target element.\n * @param this to bind\n * @param target to shim\n * @param config to use\n */\nexport function observe(\n  this: ShimConfiguration | undefined | void,\n  target: Node,\n  config: ShimConfiguration | undefined | void = typeof this == 'function' ? undefined : this,\n): TwindObserver {\n  return createObserver(config as ShimConfiguration | undefined).observe(target)\n}\n\n/**\n * Simplified MutationRecord which allows us to pass an\n * ArrayLike (compatible with Array and NodeList) `addedNodes` and\n * omit other properties we are not interested in.\n */\ninterface MinimalMutationRecord {\n  readonly addedNodes: ArrayLike<Node>\n  readonly target: Node\n}\n", "import { pathToFileURL } from 'url'\n\nexport const shim_import_meta_url = /*#__PURE__*/ pathToFileURL(__filename)\n", "import type {\n  Context,\n  Hasher,\n  Falsy,\n  MaybeThunk,\n  CSSRules,\n  ThemeScreen,\n  ThemeScreenValue,\n  CSSRuleValue,\n} from '../types'\n\ninterface Includes {\n  (value: string, search: string): boolean\n  <T>(value: readonly T[], search: T): boolean\n}\n\nexport const includes: Includes = (value: string | readonly unknown[], search: unknown) =>\n  // eslint-disable-next-line no-implicit-coercion\n  !!~(value as string).indexOf(search as string)\n\nexport const join = (parts: readonly string[], separator = '-'): string => parts.join(separator)\n\nexport const joinTruthy = (parts: readonly (string | Falsy)[], separator?: string): string =>\n  join(parts.filter(Boolean) as string[], separator)\n\nexport const tail = <T extends string | readonly unknown[]>(array: T, startIndex = 1): T =>\n  array.slice(startIndex) as T\n\nexport const identity = <T>(value: T): T => value\n\nexport const noop = (): void => {\n  /* no-op */\n}\n\nexport const capitalize = <T extends string>(value: T): Capitalize<T> =>\n  (value[0].toUpperCase() + tail(value)) as Capitalize<T>\n\nexport const hyphenate = (value: string): string => value.replace(/[A-Z]/g, '-$&').toLowerCase()\n\nexport const evalThunk = <T>(value: MaybeThunk<T>, context: Context): T => {\n  while (typeof value == 'function') {\n    value = (value as (context: Context) => T)(context)\n  }\n\n  return value\n}\n\nexport const ensureMaxSize = <K, V>(map: Map<K, V>, max: number): void => {\n  // Ensure the cache does not grow unlimited\n  if (map.size > max) {\n    map.delete(map.keys().next().value)\n  }\n}\n\n// string, number or Array => a property with a value\nexport const isCSSProperty = (key: string, value: CSSRuleValue): boolean =>\n  !includes('@:&', key[0]) && (includes('rg', (typeof value)[5]) || Array.isArray(value))\n\nexport const merge = (target: CSSRules, source: CSSRules, context: Context): CSSRules =>\n  source\n    ? Object.keys(source).reduce((target, key) => {\n        const value = evalThunk(source[key], context)\n\n        if (isCSSProperty(key, value)) {\n          // hyphenate target key only if key is property like (\\w-)\n          target[hyphenate(key)] = value\n        } else {\n          // Keep all @font-face, @import, @global, @apply as is\n          target[key] =\n            key[0] == '@' && includes('figa', key[1])\n              ? ((target[key] || []) as CSSRules[]).concat(value as CSSRules)\n              : merge((target[key] || {}) as CSSRules, value as CSSRules, context)\n        }\n\n        return target\n      }, target)\n    : target\n\nexport const escape =\n  (typeof CSS !== 'undefined' && CSS.escape) ||\n  // Simplified: escaping only special characters\n  // Needed for NodeJS and Edge <79 (https://caniuse.com/mdn-api_css_escape)\n  ((className: string): string =>\n    className\n      // Simplifed escape testing only for chars that we know happen to be in tailwind directives\n      .replace(/[!\"'`*+.,;:\\\\/<=>?@#$%&^|~()[\\]{}]/g, '\\\\$&')\n      // If the character is the first character and is in the range [0-9] (2xl, ...)\n      // https://drafts.csswg.org/cssom/#escape-a-character-as-code-point\n      .replace(/^\\d/, '\\\\3$& '))\n\nexport const buildMediaQuery = (screen: ThemeScreen): string => {\n  if (!Array.isArray(screen)) {\n    screen = [screen as ThemeScreenValue]\n  }\n\n  return (\n    '@media ' +\n    join(\n      (screen as ThemeScreenValue[]).map((screen) => {\n        if (typeof screen == 'string') {\n          screen = { min: screen }\n        }\n\n        return (\n          (screen as { raw?: string }).raw ||\n          join(\n            Object.keys(screen).map(\n              (feature) => `(${feature}-width:${(screen as Record<string, string>)[feature]})`,\n            ),\n            ' and ',\n          )\n        )\n      }),\n      ',',\n    )\n  )\n}\n\n// Based on https://stackoverflow.com/a/52171480\nexport const cyrb32: Hasher = (value: string): string => {\n  // eslint-disable-next-line no-var\n  for (var h = 9, index = value.length; index--; ) {\n    h = Math.imul(h ^ value.charCodeAt(index), 0x5f356495)\n  }\n\n  return 'tw-' + ((h ^ (h >>> 9)) >>> 0).toString(36)\n}\n\n/**\n * Find the array index of where to add an element to keep it sorted.\n *\n * @returns The insertion index\n */\nexport const sortedInsertionIndex = (array: readonly number[], element: number): number => {\n  // Find position by binary search\n  // eslint-disable-next-line no-var\n  for (var low = 0, high = array.length; low < high; ) {\n    const pivot = (high + low) >> 1\n\n    // Less-Then-Equal to add new equal element after all existing equal elements (stable sort)\n    if (array[pivot] <= element) {\n      low = pivot + 1\n    } else {\n      high = pivot\n    }\n  }\n\n  return high\n}\n"],
  "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,iBAA8B;AAEvB,IAAM,uBAAqC,8CAAc;;;ADMhE,mBAAgC;;;AEuCzB,IAAM,gBAAgB,CAAO,KAAgB,QAAsB;AAExE,MAAI,IAAI,OAAO,KAAK;AAClB,QAAI,OAAO,IAAI,OAAO,OAAO;AAAA;AAAA;AA4B1B,IAAM,SACV,OAAO,QAAQ,eAAe,IAAI,UAGlC,EAAC,cACA,UAEG,QAAQ,uCAAuC,QAG/C,QAAQ,OAAO;;;AF7EtB,sBAAc;AAyBd,IAAM,SAAS,IAAI;AAEnB,IAAM,WAAW,CAAC,OAAgC;AAChD,MAAI,oBAAoB,OAAO,IAAI;AAEnC,MAAI,CAAC,mBAAmB;AACtB,wBAAoB,IAAI;AACxB,WAAO,IAAI,IAAI;AAAA;AAGjB,SAAO;AAAA;AAGT,IAAM,OAAO,CAAI,OAAU,OAAe,WAAgB,OAAO,QAAQ,UAAU;AAO5E,IAAM,iBAAiB,CAAC,CAAE,KAAK,mBAAiC,OAAsB;AAC3F,MAAI,OAAO,oBAAoB,YAAY;AACzC,UAAM,oBAAoB,SAAS;AAEnC,UAAM,iBAAiB,CAAC,CAAE,QAAQ,gBAA8C;AA5DpF;AA8DM,YAAM,QAAS,aAAmB,iBAAnB,gCAAkC;AAEjD,UAAI,OAAO;AACT,YAAI,YAAY,kBAAkB,IAAI;AAEtC,YAAI,CAAC,WAAW;AACd,sBAAY,GAAG,OAAO,MAAM,OAAO,OAAO,MAAM,KAAK;AAGrD,4BAAkB,IAAI,OAAO;AAC7B,4BAAkB,IAAI,WAAW;AAGjC,wBAAc,mBAAmB;AAAA;AAGnC,YAAI,UAAU,WAAW;AAGvB;AAAC,UAAC,OAAmB,aAAa,SAAS;AAAA;AAAA;AAI/C,eAAS,QAAQ,WAAW,QAAQ,WAAW;AAC7C,cAAM,OAAO,WAAW;AAExB,wBAAgB;AAAA,UACd;AAAA,YACE,QAAQ;AAAA,YACR,YAAa,KAAiB,YAAY;AAAA;AAAA;AAAA;AAAA;AAMlD,UAAM,kBAAkB,CAAC,cAA6C;AACpE,gBAAU,QAAQ;AAGlB,kBAAY,SAAS;AACrB,UAAI;AAAW,kBAAU,QAAQ;AAAA;AAGnC,UAAM,WAAW,IAAI,iBAAiB;AAEtC,WAAO;AAAA,MACL,QAAQ,QAAQ;AACd,wBAAgB,CAAC,CAAE,QAAQ,YAAY,CAAC;AAExC,iBAAS,QAAQ,QAAQ;AAAA,UACvB,YAAY;AAAA,UACZ,iBAAiB,CAAC;AAAA,UAClB,SAAS;AAAA,UACT,WAAW;AAAA;AAGb,eAAO;AAAA;AAAA,MAGT,aAAa;AACX,iBAAS;AACT,eAAO;AAAA;AAAA;AAAA;AAMb,SAAO;AAAA,IACL,UAAU;AACR,aAAO;AAAA;AAAA,IAGT,aAAa;AACX,aAAO;AAAA;AAAA;AAAA;AAWN,iBAEL,QACA,SAA+C,OAAO,QAAQ,aAAa,SAAY,MACxE;AACf,SAAO,eAAe,QAAyC,QAAQ;AAAA;",
  "names": []
}
