{"version":3,"file":"useTimelineKeyboard.mjs","names":[],"sources":["../../../src/hooks/selection/useTimelineKeyboard.ts"],"sourcesContent":["import type {\n  TimelineKeyboardCommand,\n  TimelineKeyboardPlatform,\n  TimelineKeyBinding,\n  TimelineKeyboardBindings,\n  TimelineKeyboardEventLike,\n  TimelineKeyboardBindingOptions,\n  TimelineKeyboardCommandResult,\n  TimelineKeyboardOptions,\n  UseTimelineKeyboardResult,\n} from '#react/hooks/selection/timelineKeyboardModel';\nimport { useTimelineEngine } from '#react/hooks/core/useTimelineEngine';\nimport { createTimelinePlaybackCommands } from '#react/hooks/playback/createTimelinePlaybackCommands';\nimport { createTimelineMarkersCommands } from '#react/hooks/markers/createTimelineMarkersCommands';\nimport { runTimelineCommand } from '#react/hooks/core/runTimelineCommand';\nimport { timelineCommandFail, timelineCommandOk } from '@techsquidtv/canvas-timeline-core';\nimport { resolveTimecodeFrameRate } from '@techsquidtv/canvas-timeline-utils';\nimport type { TimecodeFrameRate } from '@techsquidtv/canvas-timeline-utils';\nimport React, { useCallback, useMemo } from 'react';\nconst timelineKeyboardCommandOrder = [\n  'togglePlayback',\n  'stepBackward',\n  'stepForward',\n  'setInPoint',\n  'setOutPoint',\n  'clearInOutPoints',\n  'addMarker',\n  'seekToNextMarker',\n  'seekToPreviousMarker',\n  'toggleSnapping',\n  'zoomIn',\n  'zoomOut',\n] as const satisfies readonly TimelineKeyboardCommand[];\n\n/** Minimal keyboard preset: playback only. */\nexport const minimalTimelineKeyboardBindings = {\n  /** Toggle timeline playback with the spacebar. */\n  togglePlayback: [{ key: 'Space' }],\n} as const satisfies TimelineKeyboardBindings;\n\n/** Professional editor preset bindings that do not depend on frame rate or platform. */\nexport const professionalEditorTimelineKeyboardBindings = {\n  /** Toggle timeline playback with the spacebar. */\n  togglePlayback: [{ key: 'Space' }],\n  /** Mark the current playhead time as the In point. */\n  setInPoint: [{ key: 'I' }],\n  /** Mark the current playhead time as the Out point. */\n  setOutPoint: [{ key: 'O' }],\n  /** Add a marker at the current playhead time. */\n  addMarker: [{ key: 'M' }],\n  /** Jump to the next marker. */\n  seekToNextMarker: [{ key: 'M', shiftKey: true }],\n  /** Toggle magnetic snapping. */\n  toggleSnapping: [{ key: 'S' }],\n  /** Zoom the timeline viewport in. */\n  zoomIn: [{ key: '=' }],\n  /** Zoom the timeline viewport out. */\n  zoomOut: [{ key: '-' }],\n} as const satisfies TimelineKeyboardBindings;\n\nfunction normalizeKey(key: string) {\n  if (key === 'Space' || key === 'Spacebar') {\n    return ' ';\n  }\n\n  return key.length === 1 ? key.toLowerCase() : key;\n}\n\nfunction bindingMatchesEvent(binding: TimelineKeyBinding, event: TimelineKeyboardEventLike) {\n  return (\n    normalizeKey(binding.key) === normalizeKey(event.key) &&\n    Boolean(binding.altKey) === Boolean(event.altKey) &&\n    Boolean(binding.ctrlKey) === Boolean(event.ctrlKey) &&\n    Boolean(binding.metaKey) === Boolean(event.metaKey) &&\n    Boolean(binding.shiftKey) === Boolean(event.shiftKey)\n  );\n}\n\nfunction getCurrentKeyboardPlatform(): TimelineKeyboardPlatform {\n  if (typeof navigator === 'undefined') {\n    return 'other';\n  }\n\n  const platform = navigator.platform.toLowerCase();\n  if (platform.includes('mac') || platform.includes('iphone') || platform.includes('ipad')) {\n    return 'mac';\n  }\n  if (platform.includes('win')) {\n    return 'windows';\n  }\n  if (platform.includes('linux')) {\n    return 'linux';\n  }\n\n  return 'other';\n}\n\nfunction getPlatformBindings(platform: TimelineKeyboardPlatform): TimelineKeyboardBindings {\n  if (platform === 'mac') {\n    return {\n      clearInOutPoints: [{ key: 'X', altKey: true }],\n      seekToPreviousMarker: [{ key: 'M', metaKey: true, shiftKey: true }],\n    };\n  }\n\n  return {\n    clearInOutPoints: [{ key: 'X', ctrlKey: true, shiftKey: true }],\n    seekToPreviousMarker: [{ key: 'M', ctrlKey: true, shiftKey: true }],\n  };\n}\n\nfunction hasFrameRate(frameRate: TimecodeFrameRate | undefined) {\n  return frameRate !== undefined;\n}\n\n/**\n * Creates the built-in keyboard binding map for a preset.\n *\n * @param options - Preset, frame rate, and platform used to derive bindings.\n * @returns Shortcut bindings for the requested preset.\n */\nexport function createTimelineKeyboardBindings(\n  options: TimelineKeyboardBindingOptions = {}\n): TimelineKeyboardBindings {\n  const preset = options.preset ?? 'professionalEditor';\n\n  if (preset === 'minimal') {\n    return minimalTimelineKeyboardBindings;\n  }\n\n  return {\n    ...professionalEditorTimelineKeyboardBindings,\n    ...(hasFrameRate(options.frameRate)\n      ? {\n          stepBackward: [{ key: 'ArrowLeft' }],\n          stepForward: [{ key: 'ArrowRight' }],\n        }\n      : {}),\n    ...getPlatformBindings(options.platform ?? getCurrentKeyboardPlatform()),\n  };\n}\n\n/**\n * Resolves a keyboard event to the first matching command in stable command order.\n *\n * @param event - Keyboard event fields to match.\n * @param bindings - Command bindings to search.\n * @returns The matched command, or `null` when no binding applies.\n */\nexport function getTimelineKeyboardCommand(\n  event: TimelineKeyboardEventLike,\n  bindings: TimelineKeyboardBindings\n): TimelineKeyboardCommand | null {\n  if (event.key === 'Tab') {\n    return null;\n  }\n\n  for (const command of timelineKeyboardCommandOrder) {\n    const commandBindings = bindings[command];\n    if (commandBindings?.some((binding) => bindingMatchesEvent(binding, event))) {\n      return command;\n    }\n  }\n\n  return null;\n}\n\nfunction isElementTarget(target: EventTarget | null): target is Element {\n  return typeof Element !== 'undefined' && target instanceof Element;\n}\n\nconst timelineKeyboardIgnoredRoleSelectors = [\n  'button',\n  'checkbox',\n  'combobox',\n  'listbox',\n  'menuitem',\n  'option',\n  'radio',\n  'slider',\n  'spinbutton',\n  'switch',\n  'tab',\n  'textbox',\n] as const;\n\nconst timelineKeyboardIgnoredSelector = [\n  'input',\n  'textarea',\n  'select',\n  'button',\n  'a[href]',\n  '[contenteditable]:not([contenteditable=\"false\"])',\n  '[data-timeline-keyboard-ignore]',\n  ...timelineKeyboardIgnoredRoleSelectors.map((role) => `[role~=\"${role}\"]`),\n].join(',');\n\nfunction isTimelineKeyboardIgnoredTarget(target: EventTarget | null) {\n  if (!isElementTarget(target)) {\n    return false;\n  }\n\n  return Boolean(target.closest(timelineKeyboardIgnoredSelector));\n}\n\nfunction scopeContainsActiveElement(scope: HTMLElement) {\n  const activeElement = scope.ownerDocument.activeElement;\n  return activeElement !== null && scope.contains(activeElement);\n}\n\n/**\n * Provides focus-scoped timeline keyboard shortcuts.\n *\n * The hook never installs global listeners. It handles shortcuts only from the\n * element that spreads `scopeProps` or one of that element's descendants.\n * Commands read current engine state without subscribing to document or viewport updates.\n * Use `commandHandlers.togglePlayback` to compose media-aware transport.\n *\n * @example\n * ```tsx\n * const keyboard = useTimelineKeyboard({\n *   commandHandlers: { togglePlayback: () => media.playing ? media.pause() : media.play() },\n * });\n * return <div {...keyboard.scopeProps}>Timeline surface</div>;\n * ```\n *\n * @param options - Keyboard preset, custom bindings, frame rate, and event handling options.\n * @returns Current bindings, scope props, a shortcut matcher, and a command executor.\n */\nexport function useTimelineKeyboard(\n  options: TimelineKeyboardOptions = {}\n): UseTimelineKeyboardResult {\n  const {\n    bindings: optionBindings,\n    commandHandlers,\n    onCommandResult,\n    onCommandError,\n    disabled = false,\n    frameRate,\n    frameStepCount = 1,\n    label,\n    platform,\n    preset = 'professionalEditor',\n    preventDefault = true,\n    stopPropagation = false,\n    zoomStepRatio = 1.2,\n  } = options;\n  const engine = useTimelineEngine();\n  const playback = useMemo(() => createTimelinePlaybackCommands(engine), [engine]);\n  const markers = useMemo(() => createTimelineMarkersCommands(engine), [engine]);\n\n  const bindings = useMemo(\n    () =>\n      optionBindings === false\n        ? {}\n        : (optionBindings ??\n          createTimelineKeyboardBindings({\n            frameRate,\n            platform,\n            preset,\n          })),\n    [frameRate, optionBindings, platform, preset]\n  );\n\n  const getCommandForEvent = useCallback(\n    (event: TimelineKeyboardEventLike) => getTimelineKeyboardCommand(event, bindings),\n    [bindings]\n  );\n\n  const stepByFrames = useCallback(\n    (direction: -1 | 1) =>\n      runTimelineCommand(() => {\n        if (frameRate === undefined) {\n          return timelineCommandFail('unsupported', 'A frame rate is required for frame stepping.');\n        }\n        if (!Number.isSafeInteger(frameStepCount) || frameStepCount < 1) {\n          return timelineCommandFail('invalid-input', 'frameStepCount must be a positive integer.');\n        }\n        const amountSeconds = frameStepCount / resolveTimecodeFrameRate(frameRate);\n        return direction > 0\n          ? playback.stepForward(amountSeconds)\n          : playback.stepBackward(amountSeconds);\n      }),\n    [frameRate, frameStepCount, playback]\n  );\n\n  const executeCommand = useCallback(\n    (\n      command: TimelineKeyboardCommand\n    ): TimelineKeyboardCommandResult | Promise<TimelineKeyboardCommandResult> => {\n      const handler = commandHandlers?.[command];\n      if (handler) {\n        return handler();\n      }\n      switch (command) {\n        case 'togglePlayback':\n          return playback.togglePlayback();\n        case 'stepBackward':\n          return stepByFrames(-1);\n        case 'stepForward':\n          return stepByFrames(1);\n        case 'setInPoint':\n          return playback.setInPoint();\n        case 'setOutPoint':\n          return playback.setOutPoint();\n        case 'clearInOutPoints':\n          return playback.clearInOutPoints();\n        case 'addMarker':\n          return markers.addMarkerAtPlayhead();\n        case 'seekToNextMarker':\n          return markers.seekToNextMarker();\n        case 'seekToPreviousMarker':\n          return markers.seekToPreviousMarker();\n        case 'toggleSnapping':\n          return runTimelineCommand(() => {\n            engine.setSnappingEnabled(!engine.getState().snapEnabled);\n            return timelineCommandOk();\n          });\n        case 'zoomIn':\n        case 'zoomOut':\n          return runTimelineCommand(() => {\n            if (!Number.isFinite(zoomStepRatio) || zoomStepRatio <= 0) {\n              return timelineCommandFail(\n                'invalid-input',\n                'zoomStepRatio must be positive and finite.'\n              );\n            }\n            engine.setZoomScale(\n              command === 'zoomIn'\n                ? engine.zoomScale * zoomStepRatio\n                : engine.zoomScale / zoomStepRatio\n            );\n            engine.settle();\n            return timelineCommandOk();\n          });\n      }\n    },\n    [commandHandlers, engine, markers, playback, stepByFrames, zoomStepRatio]\n  );\n\n  const handleKeyDown = useCallback(\n    (event: React.KeyboardEvent<HTMLDivElement>) => {\n      if (\n        disabled ||\n        optionBindings === false ||\n        event.defaultPrevented ||\n        event.key === 'Tab' ||\n        !scopeContainsActiveElement(event.currentTarget) ||\n        isTimelineKeyboardIgnoredTarget(event.target)\n      ) {\n        return;\n      }\n\n      const command = getCommandForEvent(event);\n      if (command === null) {\n        return;\n      }\n\n      if (preventDefault) {\n        event.preventDefault();\n      }\n      if (stopPropagation) {\n        event.stopPropagation();\n      }\n\n      if (command === 'togglePlayback' && event.repeat) {\n        return;\n      }\n\n      const reportFailure = (cause: unknown) => {\n        const error = cause instanceof Error ? cause : new Error(String(cause));\n        if (onCommandError) {\n          onCommandError(error, command);\n        } else if (typeof globalThis.reportError === 'function') {\n          globalThis.reportError(error);\n        } else {\n          console.error(error);\n        }\n      };\n      try {\n        void Promise.resolve(executeCommand(command))\n          .then((result) => onCommandResult?.(command, result))\n          .catch(reportFailure);\n      } catch (cause) {\n        reportFailure(cause);\n      }\n    },\n    [\n      disabled,\n      executeCommand,\n      getCommandForEvent,\n      onCommandResult,\n      onCommandError,\n      optionBindings,\n      preventDefault,\n      stopPropagation,\n    ]\n  );\n\n  const scopeProps = useMemo<React.HTMLAttributes<HTMLDivElement>>(\n    () => ({\n      role: 'group',\n      tabIndex: disabled ? undefined : 0,\n      'aria-label': label ?? 'Timeline keyboard shortcuts',\n      onKeyDown: handleKeyDown,\n    }),\n    [disabled, handleKeyDown, label]\n  );\n\n  return useMemo(\n    () => ({\n      bindings,\n      scopeProps,\n      getCommandForEvent,\n      executeCommand,\n    }),\n    [bindings, getCommandForEvent, scopeProps, executeCommand]\n  );\n}\n"],"mappings":";;;;;;;;AAmBA,MAAM,+BAA+B;CACnC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;AAGA,MAAa,kCAAkC;;AAE7C,gBAAgB,CAAC,EAAE,KAAK,QAAQ,CAAC,EACnC;;AAGA,MAAa,6CAA6C;;CAExD,gBAAgB,CAAC,EAAE,KAAK,QAAQ,CAAC;;CAEjC,YAAY,CAAC,EAAE,KAAK,IAAI,CAAC;;CAEzB,aAAa,CAAC,EAAE,KAAK,IAAI,CAAC;;CAE1B,WAAW,CAAC,EAAE,KAAK,IAAI,CAAC;;CAExB,kBAAkB,CAAC;EAAE,KAAK;EAAK,UAAU;CAAK,CAAC;;CAE/C,gBAAgB,CAAC,EAAE,KAAK,IAAI,CAAC;;CAE7B,QAAQ,CAAC,EAAE,KAAK,IAAI,CAAC;;CAErB,SAAS,CAAC,EAAE,KAAK,IAAI,CAAC;AACxB;AAEA,SAAS,aAAa,KAAa;CACjC,IAAI,QAAQ,WAAW,QAAQ,YAC7B,OAAO;CAGT,OAAO,IAAI,WAAW,IAAI,IAAI,YAAY,IAAI;AAChD;AAEA,SAAS,oBAAoB,SAA6B,OAAkC;CAC1F,OACE,aAAa,QAAQ,GAAG,MAAM,aAAa,MAAM,GAAG,KACpD,QAAQ,QAAQ,MAAM,MAAM,QAAQ,MAAM,MAAM,KAChD,QAAQ,QAAQ,OAAO,MAAM,QAAQ,MAAM,OAAO,KAClD,QAAQ,QAAQ,OAAO,MAAM,QAAQ,MAAM,OAAO,KAClD,QAAQ,QAAQ,QAAQ,MAAM,QAAQ,MAAM,QAAQ;AAExD;AAEA,SAAS,6BAAuD;CAC9D,IAAI,OAAO,cAAc,aACvB,OAAO;CAGT,MAAM,WAAW,UAAU,SAAS,YAAY;CAChD,IAAI,SAAS,SAAS,KAAK,KAAK,SAAS,SAAS,QAAQ,KAAK,SAAS,SAAS,MAAM,GACrF,OAAO;CAET,IAAI,SAAS,SAAS,KAAK,GACzB,OAAO;CAET,IAAI,SAAS,SAAS,OAAO,GAC3B,OAAO;CAGT,OAAO;AACT;AAEA,SAAS,oBAAoB,UAA8D;CACzF,IAAI,aAAa,OACf,OAAO;EACL,kBAAkB,CAAC;GAAE,KAAK;GAAK,QAAQ;EAAK,CAAC;EAC7C,sBAAsB,CAAC;GAAE,KAAK;GAAK,SAAS;GAAM,UAAU;EAAK,CAAC;CACpE;CAGF,OAAO;EACL,kBAAkB,CAAC;GAAE,KAAK;GAAK,SAAS;GAAM,UAAU;EAAK,CAAC;EAC9D,sBAAsB,CAAC;GAAE,KAAK;GAAK,SAAS;GAAM,UAAU;EAAK,CAAC;CACpE;AACF;AAEA,SAAS,aAAa,WAA0C;CAC9D,OAAO,cAAc,KAAA;AACvB;;;;;;;AAQA,SAAgB,+BACd,UAA0C,CAAC,GACjB;CAG1B,KAFe,QAAQ,UAAU,0BAElB,WACb,OAAO;CAGT,OAAO;EACL,GAAG;EACH,GAAI,aAAa,QAAQ,SAAS,IAC9B;GACE,cAAc,CAAC,EAAE,KAAK,YAAY,CAAC;GACnC,aAAa,CAAC,EAAE,KAAK,aAAa,CAAC;EACrC,IACA,CAAC;EACL,GAAG,oBAAoB,QAAQ,YAAY,2BAA2B,CAAC;CACzE;AACF;;;;;;;;AASA,SAAgB,2BACd,OACA,UACgC;CAChC,IAAI,MAAM,QAAQ,OAChB,OAAO;CAGT,KAAK,MAAM,WAAW,8BAEpB,IADwB,SAAS,QACd,EAAE,MAAM,YAAY,oBAAoB,SAAS,KAAK,CAAC,GACxE,OAAO;CAIX,OAAO;AACT;AAEA,SAAS,gBAAgB,QAA+C;CACtE,OAAO,OAAO,YAAY,eAAe,kBAAkB;AAC7D;AAiBA,MAAM,kCAAkC;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACA,GAAG;EAtBH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CAWsC,CAAC,CAAC,KAAK,SAAS,WAAW,KAAK,GAAG;AAC3E,CAAC,CAAC,KAAK,GAAG;AAEV,SAAS,gCAAgC,QAA4B;CACnE,IAAI,CAAC,gBAAgB,MAAM,GACzB,OAAO;CAGT,OAAO,QAAQ,OAAO,QAAQ,+BAA+B,CAAC;AAChE;AAEA,SAAS,2BAA2B,OAAoB;CACtD,MAAM,gBAAgB,MAAM,cAAc;CAC1C,OAAO,kBAAkB,QAAQ,MAAM,SAAS,aAAa;AAC/D;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,oBACd,UAAmC,CAAC,GACT;CAC3B,MAAM,EACJ,UAAU,gBACV,iBACA,iBACA,gBACA,WAAW,OACX,WACA,iBAAiB,GACjB,OACA,UACA,SAAS,sBACT,iBAAiB,MACjB,kBAAkB,OAClB,gBAAgB,QACd;CACJ,MAAM,SAAS,kBAAkB;CACjC,MAAM,WAAW,cAAc,+BAA+B,MAAM,GAAG,CAAC,MAAM,CAAC;CAC/E,MAAM,UAAU,cAAc,8BAA8B,MAAM,GAAG,CAAC,MAAM,CAAC;CAE7E,MAAM,WAAW,cAEb,mBAAmB,QACf,CAAC,IACA,kBACD,+BAA+B;EAC7B;EACA;EACA;CACF,CAAC,GACP;EAAC;EAAW;EAAgB;EAAU;CAAM,CAC9C;CAEA,MAAM,qBAAqB,aACxB,UAAqC,2BAA2B,OAAO,QAAQ,GAChF,CAAC,QAAQ,CACX;CAEA,MAAM,eAAe,aAClB,cACC,yBAAyB;EACvB,IAAI,cAAc,KAAA,GAChB,OAAO,oBAAoB,eAAe,8CAA8C;EAE1F,IAAI,CAAC,OAAO,cAAc,cAAc,KAAK,iBAAiB,GAC5D,OAAO,oBAAoB,iBAAiB,4CAA4C;EAE1F,MAAM,gBAAgB,iBAAiB,yBAAyB,SAAS;EACzE,OAAO,YAAY,IACf,SAAS,YAAY,aAAa,IAClC,SAAS,aAAa,aAAa;CACzC,CAAC,GACH;EAAC;EAAW;EAAgB;CAAQ,CACtC;CAEA,MAAM,iBAAiB,aAEnB,YAC2E;EAC3E,MAAM,UAAU,kBAAkB;EAClC,IAAI,SACF,OAAO,QAAQ;EAEjB,QAAQ,SAAR;GACE,KAAK,kBACH,OAAO,SAAS,eAAe;GACjC,KAAK,gBACH,OAAO,aAAa,EAAE;GACxB,KAAK,eACH,OAAO,aAAa,CAAC;GACvB,KAAK,cACH,OAAO,SAAS,WAAW;GAC7B,KAAK,eACH,OAAO,SAAS,YAAY;GAC9B,KAAK,oBACH,OAAO,SAAS,iBAAiB;GACnC,KAAK,aACH,OAAO,QAAQ,oBAAoB;GACrC,KAAK,oBACH,OAAO,QAAQ,iBAAiB;GAClC,KAAK,wBACH,OAAO,QAAQ,qBAAqB;GACtC,KAAK,kBACH,OAAO,yBAAyB;IAC9B,OAAO,mBAAmB,CAAC,OAAO,SAAS,CAAC,CAAC,WAAW;IACxD,OAAO,kBAAkB;GAC3B,CAAC;GACH,KAAK;GACL,KAAK,WACH,OAAO,yBAAyB;IAC9B,IAAI,CAAC,OAAO,SAAS,aAAa,KAAK,iBAAiB,GACtD,OAAO,oBACL,iBACA,4CACF;IAEF,OAAO,aACL,YAAY,WACR,OAAO,YAAY,gBACnB,OAAO,YAAY,aACzB;IACA,OAAO,OAAO;IACd,OAAO,kBAAkB;GAC3B,CAAC;EACL;CACF,GACA;EAAC;EAAiB;EAAQ;EAAS;EAAU;EAAc;CAAa,CAC1E;CAEA,MAAM,gBAAgB,aACnB,UAA+C;EAC9C,IACE,YACA,mBAAmB,SACnB,MAAM,oBACN,MAAM,QAAQ,SACd,CAAC,2BAA2B,MAAM,aAAa,KAC/C,gCAAgC,MAAM,MAAM,GAE5C;EAGF,MAAM,UAAU,mBAAmB,KAAK;EACxC,IAAI,YAAY,MACd;EAGF,IAAI,gBACF,MAAM,eAAe;EAEvB,IAAI,iBACF,MAAM,gBAAgB;EAGxB,IAAI,YAAY,oBAAoB,MAAM,QACxC;EAGF,MAAM,iBAAiB,UAAmB;GACxC,MAAM,QAAQ,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;GACtE,IAAI,gBACF,eAAe,OAAO,OAAO;QACxB,IAAI,OAAO,WAAW,gBAAgB,YAC3C,WAAW,YAAY,KAAK;QAE5B,QAAQ,MAAM,KAAK;EAEvB;EACA,IAAI;GACF,QAAa,QAAQ,eAAe,OAAO,CAAC,CAAC,CAC1C,MAAM,WAAW,kBAAkB,SAAS,MAAM,CAAC,CAAC,CACpD,MAAM,aAAa;EACxB,SAAS,OAAO;GACd,cAAc,KAAK;EACrB;CACF,GACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CACF;CAEA,MAAM,aAAa,eACV;EACL,MAAM;EACN,UAAU,WAAW,KAAA,IAAY;EACjC,cAAc,SAAS;EACvB,WAAW;CACb,IACA;EAAC;EAAU;EAAe;CAAK,CACjC;CAEA,OAAO,eACE;EACL;EACA;EACA;EACA;CACF,IACA;EAAC;EAAU;EAAoB;EAAY;CAAc,CAC3D;AACF"}