@illinois-grad/grad-vue 2.3.4 → 2.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/GModal.vue.d.ts +4 -0
- package/dist/components/GPopover.vue.d.ts +2 -2
- package/dist/compose/useOverlayStack.d.ts +10 -0
- package/dist/grad-vue.css +1 -1
- package/dist/grad-vue.js +1 -1
- package/dist/{main-DEKKtASV.js → main-DmtFFIij.js} +991 -972
- package/dist/main-DmtFFIij.js.map +1 -0
- package/dist/plugin.js +1 -1
- package/package.json +1 -1
- package/dist/main-DEKKtASV.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main-DmtFFIij.js","sources":["../src/components/GButton.vue","../src/compose/useFormField.ts","../src/components/form/GFormErrorMessages.vue","../src/components/GTextInput.vue","../src/compose/useOverlayStack.ts","../../../node_modules/@vueuse/shared/dist/index.js","../../../node_modules/@vueuse/integrations/dist/useFocusTrap-lXZ_YG-8.js","../src/compose/useOverlayFocus.ts","../src/compose/useOverlayEscape.ts","../src/compose/popoverPosition.ts","../src/components/GPopover.vue","../src/components/GSelectButton.vue","../src/components/GProgress.vue","../src/components/GAlertDialog.vue","../src/components/GSelect.vue","../src/components/GSearch.vue","../src/components/GAppHeader.vue","../src/components/GSidebar.vue","../src/components/GSidebarMenu.vue","../src/directives/v-gtooltip.ts","../src/components/GClipboard.vue","../src/components/GHistoryScroller.vue","../src/components/GThreeWayToggle.vue","../src/components/table/GTableBody.vue","../src/compose/useFiltering.ts","../src/components/GTable.vue","../src/components/table/GTablePagination.vue","../src/components/GModal.vue","../src/components/GHamburgerMenu.vue","../src/components/GDetailList.vue","../src/components/detail-list/GDetailListItem.vue","../src/components/GOverlay.vue","../src/components/term/GTermSelectorControl.vue","../src/components/GTermSelector.vue","../src/components/GUserMenu.vue","../src/components/GCurrencyInput.vue","../src/components/GEmailInput.vue","../src/components/GDateInput.vue","../src/components/GDateRangeInput.vue","../src/compose/useForm.ts","../src/components/GForm.vue","../src/components/GSubmitButton.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * The element or component can be set with the `component` prop, so it can be\n * a link or `router-link` component from vue-router. For example:\n *\n * ```vue-html\n * <GButton component=\"router-link\" to=\"/some-route\">\n * Click me\n * </GButton>\n * ```\n *\n * Note that grad-vue doesn't include vue-router as a dependency.\n *\n * **Icons** can be added with either the `icon` prop or a named slot `icon`:\n * - Use the `icon` prop to pass an icon class string, e.g., \"fa-solid fa-plus\".\n * - If using the `icon` prop, the icon will be rendered as a span with the `aria-hidden` attribute set to `true`.\n * - Use a named slot `icon` to provide custom icon content.\n * - If both `icon` prop and named slot `icon` are provided, the named slot takes precedence.\n */\nimport { computed, useAttrs } from \"vue\";\n\ninterface Props {\n /**\n * Button size\n */\n size?: \"small\" | \"medium\" | \"large\";\n /**\n * Button color theme\n */\n theme?: \"primary\" | \"secondary\" | \"accent\" | \"danger\" | \"none\";\n /**\n * Use outlined style\n */\n outlined?: boolean;\n /**\n * Use text style\n */\n text?: boolean;\n\n to?: string | Record<string, any>;\n component?: string;\n\n // Optional icon classes to render an icon span before the label.\n // Example: \"fa-solid fa-plus\" or \"material-symbols:add\".\n // If a named slot `icon` is provided, it takes precedence over this prop.\n icon?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n size: \"medium\",\n theme: \"primary\",\n outlined: false,\n text: false,\n to: undefined,\n component: undefined,\n icon: undefined,\n});\n\nconst slots = defineSlots<{\n default(): any;\n icon?: () => any;\n}>();\n\ndefineEmits([\n \"click\",\n \"focus\",\n \"blur\",\n \"keydown\",\n \"keyup\",\n \"mousedown\",\n \"mouseup\",\n \"mouseenter\",\n \"mouseleave\",\n]);\nconst attrs = useAttrs();\n\nconst classes = computed(() => [\n \"g-btn\",\n `g-btn--${props.size}`,\n `g-btn--${props.theme}`,\n {\n \"g-btn--outlined\": props.outlined,\n \"g-btn--text\": props.text,\n \"g-btn--primary\": props.theme === \"primary\",\n \"g-btn--accent\": props.theme === \"accent\",\n \"g-btn-has-text\": props.text,\n \"g-btn-has-icon-class\": props.icon,\n \"g-btn-has-icon-svg\": !!slots.icon,\n },\n]);\n</script>\n\n<template>\n <component\n :is=\"props.component ? props.component : 'button'\"\n v-bind=\"attrs\"\n :to=\"props.to\"\n :class=\"classes\"\n :type=\"props.to ? undefined : 'button'\"\n @click=\"$emit('click', $event)\"\n @focus=\"$emit('focus', $event)\"\n @blur=\"$emit('blur', $event)\"\n @keydown=\"$emit('keydown', $event)\"\n @keyup=\"$emit('keyup', $event)\"\n @mousedown=\"$emit('mousedown', $event)\"\n @mouseup=\"$emit('mouseup', $event)\"\n @mouseenter=\"$emit('mouseenter', $event)\"\n @mouseleave=\"$emit('mouseleave', $event)\"\n >\n <template v-if=\"icon || slots.icon\">\n <span class=\"g-btn--icon\">\n <slot v-if=\"slots.icon\" name=\"icon\" />\n <span v-else :class=\"icon + ' g-btn--icon-span'\" aria-hidden=\"true\"></span>\n </span>\n <span class=\"g-btn--label\">\n <slot />\n </span>\n </template>\n <template v-else>\n <slot />\n </template>\n </component>\n</template>\n\n<style>\n.g-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-family: var(--il-font-sans);\n font-weight: 700;\n font-size: 19px;\n line-height: 20px;\n border: 2px solid var(--ilw-color--background);\n background: var(--ilw-color--background);\n color: var(--ilw-color--heading);\n cursor: pointer;\n padding: 12px 20px;\n border-radius: var(--g-border-radius-m);\n text-decoration: none;\n\n &:hover {\n color: var(--ilw-color--background);\n background: var(--ilw-color--heading);\n border-color: var(--ilw-color--background);\n text-decoration: underline;\n }\n\n &:active {\n background: var(--ilw-color--heading-link-hover);\n color: var(--ilw-color--heading);\n }\n\n &:focus-visible {\n border-color: var(--ilw-color--focus--outline);\n color: var(--ilw-color--focus--text);\n background: var(--ilw-color--focus--background);\n }\n}\n\n\n.g-btn--small {\n font-size: 14px;\n padding: 6px 10px 7px;\n\n --g-accent-500: var(--il-altgeld);\n}\n\n.g-btn--large {\n font-size: 21px;\n line-height: 24px;\n padding: 16px 24px;\n}\n\n.g-btn-has-icon-class, .g-btn-has-icon-svg {\n gap: 2px;\n padding: 6px 20px 6px 6px;\n\n &.g-btn--small {\n padding: 0 14px 1px 0;\n }\n &.g-btn--large {\n padding: 12px 24px 12px 10px;\n }\n\n &:hover {\n text-decoration: none;\n\n .g-btn--label {\n text-decoration: underline;\n }\n }\n}\n\n.g-btn--icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n overflow: hidden;\n text-decoration: none;\n\n span.g-btn--icon-span {\n max-width: 100%;\n max-height: 100%;\n }\n}\n\n.g-btn--label {\n display: block;\n}\n\n/* Visually balance leading icon by slightly reducing left offset */\n.g-btn > .g-btn--icon:first-child {\n margin-left: -0.1em;\n}\n\n.g-btn--icon > svg,\n.g-btn--icon > img {\n width: 1em;\n height: 1em;\n display: block;\n flex: 0 0 auto;\n}\n\n.g-btn--primary {\n --ilw-color--background: var(--g-primary-500);\n --ilw-color--heading: var(--g-primary-text);\n}\n.g-btn--accent {\n --ilw-color--background: var(--g-accent-500);\n --ilw-color--heading: var(--g-surface-0);\n}\n\n.g-btn--danger {\n --ilw-color--background: var(--g-danger-500);\n --ilw-color--heading: var(--g-danger-text);\n}\n\n.g-btn--secondary {\n --ilw-color--background: var(--g-surface-700);\n --ilw-color--heading: var(--g-surface-100);\n --ilw-color--heading-link-hover: var(--g-surface-900);\n}\n\n.g-btn--outlined {\n color: var(--ilw-color--background);\n background: var(--ilw-color--heading);\n border-color: var(--ilw-color--background);\n\n &:hover {\n background: var(--ilw-color--background);\n color: var(--ilw-color--heading);\n }\n &:active {\n background: var(--ilw-color--heading-link-hover);\n color: var(--ilw-color--heading);\n }\n &:focus-visible {\n border-color: var(--ilw-color--focus--outline);\n color: var(--ilw-color--focus--text);\n background: var(--ilw-color--focus--background);\n }\n}\n\n.g-btn--text {\n background: none;\n border: none;\n color: var(--ilw-color--background);\n padding: 0.25em 0.5em; /* lighter padding using ems for consistency */\n &:hover {\n color: var(--ilw-color--heading-link-hover);\n text-decoration: underline;\n }\n &:active {\n background: var(--ilw-color--heading-link-hover);\n color: var(--ilw-color--heading);\n }\n &:focus-visible {\n border-color: var(--ilw-color--focus--outline);\n color: var(--ilw-color--focus--text);\n background: var(--ilw-color--focus--background);\n }\n}\n</style>\n","import { ref, Ref, computed, inject, onMounted, onBeforeUnmount, ComputedRef } from \"vue\";\nimport { UseFormReturn } from \"./useForm\";\n\nexport interface UseFormFieldOptions {\n /**\n * The name of the field (required for form registration)\n */\n name?: string;\n /**\n * The model value ref to register with the form\n */\n value: Ref<any>;\n /**\n * Error messages from props (optional) - should be a reactive reference\n */\n errors?: Ref<string[]> | ComputedRef<string[]>;\n}\n\nexport interface UseFormFieldReturn {\n /**\n * Combined filtered errors array\n */\n displayErrors: Ref<string[]>;\n /**\n * Whether the field has any errors\n */\n hasErrors: Ref<boolean>;\n}\n\n/**\n * Composable to handle form field registration and error management.\n */\nexport function useFormField(options: UseFormFieldOptions): UseFormFieldReturn {\n const form = inject<UseFormReturn | null>(\"form\", null);\n\n const displayErrors = computed(() => {\n const allErrors: string[] = [];\n \n // Add prop errors (now reactive)\n if (options.errors) {\n allErrors.push(...options.errors.value.filter(Boolean));\n }\n return allErrors;\n });\n\n const hasErrors = computed(() => displayErrors.value.length > 0);\n\n // Register field with form if name is provided\n const name = options.name;\n if (form && name) {\n onMounted(() => {\n // Note: FormField interface requires name field for consistency,\n // even though it's also used as the registration key\n form.registerField(name, {\n name: name,\n value: options.value,\n errors: displayErrors,\n });\n });\n\n onBeforeUnmount(() => {\n if (options.name) {\n form.unregisterField(options.name);\n }\n });\n }\n\n return {\n displayErrors,\n hasErrors\n };\n}\n","<script setup lang=\"ts\">\n/**\n * Internal component for displaying form field error messages.\n * This component is used by form input components to display validation errors\n * in a consistent way across all form fields.\n */\ninterface Props {\n /**\n * Array of error messages to display\n */\n errors: string[];\n /**\n * ID for the error container (used for aria-describedby)\n */\n id: string;\n}\n\ndefineProps<Props>();\n</script>\n\n<template>\n <div\n v-if=\"errors.length > 0\"\n class=\"g-form-error-messages\"\n :id=\"id\"\n role=\"alert\"\n >\n <div\n v-for=\"(errorMsg, index) in errors\"\n :key=\"index\"\n class=\"g-form-error-message\"\n >\n <svg class=\"g-form-error-icon\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 640\">\n <!--!Font Awesome Free v7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.-->\n <path\n fill=\"currentColor\"\n d=\"M320 64C334.7 64 348.2 72.1 355.2 85L571.2 485C577.9 497.4 577.6 512.4 570.4 524.5C563.2 536.6 550.1 544 536 544L104 544C89.9 544 76.8 536.6 69.6 524.5C62.4 512.4 62.1 497.4 68.8 485L284.8 85C291.8 72.1 305.3 64 320 64zM320 416C302.3 416 288 430.3 288 448C288 465.7 302.3 480 320 480C337.7 480 352 465.7 352 448C352 430.3 337.7 416 320 416zM320 224C301.8 224 287.3 239.5 288.6 257.7L296 361.7C296.9 374.2 307.4 384 319.9 384C332.5 384 342.9 374.3 343.8 361.7L351.2 257.7C352.5 239.5 338.1 224 319.8 224z\"\n />\n </svg>\n {{ errorMsg }}\n </div>\n </div>\n</template>\n\n<style scoped>\n.g-form-error-messages {\n display: flex;\n flex-direction: column;\n gap: 0.25em;\n margin-top: 0.25em;\n}\n\n.g-form-error-message {\n background: var(--g-surface-0);\n color: var(--g-danger-600);\n padding: 0.25em 0.5em;\n}\n\n.g-form-error-icon {\n height: 1.2em;\n padding: 0.2em 0;\n display: inline;\n margin: 0 0.2em 0 0;\n vertical-align: middle;\n}\n</style>\n","<script lang=\"ts\" setup>\n/**\n * A text input with styling for a label, instructions, and error messages.\n *\n * If `label` is omitted, an accessible label must be provided some other way.\n * All non-prop attributes are passed through to the input element, including\n * `id`.\n * \n * Errors are provided as an array of strings or computed values.\n * Multiple errors will all be displayed.\n */\n\nimport { ref, useAttrs, useId, watch, toRef } from \"vue\";\nimport { useFormField } from \"../compose/useFormField.ts\";\nimport GFormErrorMessages from \"./form/GFormErrorMessages.vue\";\ndefineOptions({\n inheritAttrs: false,\n});\n\ntype Props = {\n /**\n * Label\n */\n label?: string; // Demo: Example Label\n /**\n * Placeholder text\n */\n placeholder?: string;\n /**\n * Disabled\n */\n disabled?: boolean;\n\n // Error messages array (supports multiple validation errors)\n errors?: string[];\n /**\n * Instructions\n */\n instructions?: string;\n /**\n * Prefix text (displayed before input)\n */\n prefix?: string;\n /**\n * Suffix text (displayed after input)\n */\n suffix?: string;\n /**\n * Debounce in milliseconds\n */\n debounce?: number;\n\n // Name for form registration\n name?: string;\n};\n\nconst props = withDefaults(defineProps<Props>(), {\n label: undefined,\n instructions: \"\",\n placeholder: \"\",\n disabled: false,\n errors: () => [],\n prefix: \"\",\n suffix: \"\",\n debounce: 100,\n name: undefined,\n});\nconst model = defineModel<string | null>({ type: String });\n\nconst id = useId();\n\n// Use form field composable for form registration and error handling\nconst { displayErrors, hasErrors } = useFormField({\n name: props.name,\n value: model,\n errors: toRef(props, 'errors'),\n});\n\nconst emit = defineEmits<{\n change: [\n {\n was: string | null | undefined;\n to: string | null;\n },\n ];\n}>();\n\nconst lastInputValue = ref<string | null>(model.value ?? \"\");\nlet inputTimer: ReturnType<typeof setTimeout> | null = null;\n\nfunction emitChangeIfNeeded(val: string | null) {\n if (val !== model.value) {\n const prev = model.value;\n model.value = val;\n emit(\"change\", {\n was: prev,\n to: val,\n });\n }\n}\n\nfunction onInput(e: Event) {\n const value = (e.target as HTMLInputElement).value;\n lastInputValue.value = value;\n if (inputTimer) {\n clearTimeout(inputTimer);\n }\n inputTimer = setTimeout(() => {\n emitChangeIfNeeded(lastInputValue.value);\n inputTimer = null;\n }, props.debounce);\n}\n\nfunction onBlur(e: FocusEvent) {\n if (inputTimer) {\n clearTimeout(inputTimer);\n inputTimer = null;\n }\n emitChangeIfNeeded((e.target as HTMLInputElement).value);\n}\n\nfunction onPaste(e: ClipboardEvent) {\n if (inputTimer) {\n clearTimeout(inputTimer);\n inputTimer = null;\n }\n // Wait for paste to update value\n setTimeout(() => {\n const value = (e.target as HTMLInputElement).value;\n emitChangeIfNeeded(value);\n }, 0);\n}\n\nfunction onKeydown(e: KeyboardEvent) {\n if (e.key === \"PageUp\" || e.key === \"PageDown\") {\n if (inputTimer) {\n clearTimeout(inputTimer);\n inputTimer = null;\n }\n emitChangeIfNeeded((e.target as HTMLInputElement).value);\n }\n if (e.key === \"Enter\") {\n emitChangeIfNeeded((e.target as HTMLInputElement).value);\n }\n}\n</script>\n\n<template>\n <div\n class=\"g-text-input-wrap\"\n :class=\"{ 'g-text-input-has-error': hasErrors }\"\n >\n <label\n v-if=\"props.label\"\n :for=\"($attrs.id as string) || id\"\n class=\"g-text-input-label\"\n >{{ props.label }}</label\n >\n <div\n v-if=\"$slots.instructions || instructions\"\n :id=\"'instructions-' + id\"\n class=\"g-text-input-instructions\"\n >\n <slot name=\"instructions\">{{ instructions }}</slot>\n </div>\n <div :class=\"[{\n 'g-text-input-field-wrapper': true,\n }, `g-text-input-field-wrapper--${name || 'nameless'}`]\">\n <span v-if=\"props.prefix\" class=\"g-text-input-prefix\">{{\n props.prefix\n }}</span>\n <input\n :value=\"model\"\n :placeholder=\"props.placeholder\"\n :disabled=\"props.disabled\"\n @input=\"onInput\"\n @blur=\"onBlur\"\n @paste=\"onPaste\"\n @keydown=\"onKeydown\"\n type=\"text\"\n class=\"g-text-input\"\n v-bind=\"{\n ...$attrs,\n id: ($attrs.id as string) || id,\n 'aria-describedby':\n $slots.instructions || instructions\n ? 'instructions-' + id\n : undefined,\n 'aria-errormessage': hasErrors\n ? 'error-message-' + id\n : undefined,\n }\"\n :aria-invalid=\"hasErrors ? 'true' : 'false'\"\n />\n <span v-if=\"props.suffix\" class=\"g-text-input-suffix\">{{\n props.suffix\n }}</span>\n </div>\n <GFormErrorMessages\n :errors=\"displayErrors\"\n :id=\"'error-message-' + id\"\n />\n </div>\n</template>\n\n<style scoped>\n.g-text-input-wrap {\n position: relative;\n display: flex;\n flex-direction: column;\n}\n.g-text-input-label {\n margin-bottom: 0.5em;\n font-size: 1.25em;\n}\n.g-text-input-instructions {\n margin: 0 0 0.75em 0.5em;\n color: var(--g-surface-800);\n}\n.g-text-input-field-wrapper {\n display: flex;\n align-items: center;\n border: 2px solid var(--g-primary-500);\n border-radius: 4px;\n background: var(--g-surface-0);\n overflow: hidden;\n}\n.g-text-input-prefix,\n.g-text-input-suffix {\n padding: 0.5em;\n background: var(--g-surface-100);\n color: var(--g-surface-700);\n white-space: nowrap;\n font-family: var(--il-font-sans);\n}\n.g-text-input {\n width: 100%;\n padding: 0.5em;\n font-size: 1em;\n border: none;\n border-radius: 0;\n background: transparent;\n color: var(--g-surface-950);\n font-family: var(--il-font-sans);\n}\n.g-text-input:focus {\n outline: none;\n}\n.g-text-input-has-error {\n .g-text-input-field-wrapper {\n border-color: var(--g-danger-600);\n background: var(--g-danger-100);\n }\n}\n.g-text-input:disabled {\n background: transparent;\n color: var(--g-surface-700);\n}\n.g-text-input-field-wrapper:has(.g-text-input:disabled) {\n background: var(--g-surface-100);\n}\n</style>\n","import { computed, onBeforeUnmount, Ref, ref, useId } from \"vue\";\n\nconst OVERLAY_Z_INDEX_BASE = 100;\nconst MODAL_Z_INDEX_BASE = 200;\nconst DEFAULT_TOOLTIP_Z_INDEX = 102;\n\nexport type OverlayStack = {\n push: () => void;\n pop: () => void;\n isTop: Ref<boolean>;\n zIndex: Ref<number>;\n}\n\n// add _g_state to window typescript type\ndeclare global {\n interface Window {\n _g_overlay_stack_state: {\n stack: Ref<string[]>;\n modalStack: Ref<string[]>;\n scrollLockStack: Ref<string[]>;\n updateBodyScrollLock: () => void;\n };\n }\n}\n\nfunction setupStackState() {\n if (!window._g_overlay_stack_state) {\n window._g_overlay_stack_state = {\n stack: ref<string[]>([]),\n modalStack: ref<string[]>([]),\n scrollLockStack: ref<string[]>([]),\n updateBodyScrollLock() {\n if (typeof document !== \"undefined\") {\n if (scrollLockStack.value.length > 0) {\n // Account for possible vertical scrollbar reducing viewport width\n const scrollbarWidth =\n window.innerWidth -\n document.documentElement.clientWidth;\n document.body.classList.add(\"g-scroll-lock\");\n document.body.style.paddingRight = `${scrollbarWidth}px`;\n document.body.style.setProperty('--g-scrollbar-width', `${scrollbarWidth}px`);\n } else {\n document.body.style.paddingRight = `0`;\n document.body.classList.remove(\"g-scroll-lock\");\n document.body.style.removeProperty('--g-scrollbar-width');\n }\n }\n },\n };\n }\n\n const { stack, modalStack, scrollLockStack, updateBodyScrollLock } =\n window._g_overlay_stack_state;\n\n return { stack, modalStack, scrollLockStack, updateBodyScrollLock };\n}\n\nexport function useOverlayStack(id: string, modal = false, lockScroll = false): OverlayStack {\n if (!document) {\n return {} as any;\n }\n\n const { stack, modalStack, scrollLockStack, updateBodyScrollLock } =\n setupStackState();\n\n const stackRef = modal ? modalStack : stack;\n function push() {\n stackRef.value.push(id);\n if (lockScroll && !scrollLockStack.value.includes(id)) {\n scrollLockStack.value.push(id);\n updateBodyScrollLock();\n }\n }\n function pop() {\n const idx = stackRef.value.lastIndexOf(id);\n if (idx !== -1) {\n stackRef.value.splice(idx, 1);\n }\n const lockIdx = scrollLockStack.value.lastIndexOf(id);\n if (lockIdx !== -1) {\n scrollLockStack.value.splice(lockIdx, 1);\n updateBodyScrollLock();\n }\n }\n const isTop = computed(() => {\n if (!modal && modalStack.value.length > 0) {\n return false;\n }\n return (\n stackRef.value.length > 0 &&\n stackRef.value[stackRef.value.length - 1] === id\n );\n });\n const zIndex = computed(() => {\n const pos = stackRef.value.indexOf(id);\n return pos === -1 ? 0 : (modal ? MODAL_Z_INDEX_BASE : OVERLAY_Z_INDEX_BASE) + pos;\n });\n\n onBeforeUnmount(pop);\n\n return { push, pop, isTop, zIndex };\n}\n\nexport type OverlayStackState = {\n hasModal: Ref<boolean>;\n hasOverlay: Ref<boolean>;\n hasScrollLock: Ref<boolean>;\n};\n\nexport function useOverlayStackState(): OverlayStackState {\n if (!document) {\n return {} as any;\n }\n\n const { stack, modalStack, scrollLockStack, updateBodyScrollLock } =\n setupStackState();\n\n const hasModal = computed(() => modalStack.value.length > 0);\n const hasOverlay = computed(\n () => stack.value.length > 0 || modalStack.value.length > 0,\n );\n const hasScrollLock = computed(() => {\n return scrollLockStack.value.length > 0;\n });\n return { hasModal, hasOverlay, hasScrollLock };\n}\n\n/**\n * Returns a z-index value that is above all currently open overlays.\n * Uses the same base values as useOverlayStack: 100 + pos for non-modal,\n * 200 + pos for modal. Falls back to DEFAULT_TOOLTIP_Z_INDEX when no\n * overlays are open.\n *\n * This function can be called outside of a Vue component setup context,\n * which makes it suitable for use in Vue directives.\n */\nexport function getTopZIndex(): number {\n if (typeof window === \"undefined\" || !window._g_overlay_stack_state) {\n return DEFAULT_TOOLTIP_Z_INDEX;\n }\n const { stack, modalStack } = window._g_overlay_stack_state;\n let max = 0;\n stack.value.forEach((_, idx) => {\n max = Math.max(max, OVERLAY_Z_INDEX_BASE + idx);\n });\n modalStack.value.forEach((_, idx) => {\n max = Math.max(max, MODAL_Z_INDEX_BASE + idx);\n });\n return max > 0 ? max + 1 : DEFAULT_TOOLTIP_Z_INDEX;\n}\n","import { computed, customRef, effectScope, getCurrentInstance, getCurrentScope, hasInjectionContext, inject, isReactive, isRef, nextTick, onBeforeMount, onBeforeUnmount, onMounted, onScopeDispose, onUnmounted, provide, reactive, readonly, ref, shallowReadonly, shallowRef, toRef as toRef$1, toRefs as toRefs$1, toValue, unref, watch, watchEffect } from \"vue\";\n\n//#region computedEager/index.ts\n/**\n*\n* @deprecated This function will be removed in future version.\n*\n* Note: If you are using Vue 3.4+, you can straight use computed instead.\n* Because in Vue 3.4+, if computed new value does not change,\n* computed, effect, watch, watchEffect, render dependencies will not be triggered.\n* refer: https://github.com/vuejs/core/pull/5912\n*\n* @param fn effect function\n* @param options WatchOptionsBase\n* @returns readonly shallowRef\n*/\nfunction computedEager(fn, options) {\n\tvar _options$flush;\n\tconst result = shallowRef();\n\twatchEffect(() => {\n\t\tresult.value = fn();\n\t}, {\n\t\t...options,\n\t\tflush: (_options$flush = options === null || options === void 0 ? void 0 : options.flush) !== null && _options$flush !== void 0 ? _options$flush : \"sync\"\n\t});\n\treturn readonly(result);\n}\n/** @deprecated use `computedEager` instead */\nconst eagerComputed = computedEager;\n\n//#endregion\n//#region computedWithControl/index.ts\n/**\n* Explicitly define the deps of computed.\n*\n* @param source\n* @param fn\n*/\nfunction computedWithControl(source, fn, options = {}) {\n\tlet v = void 0;\n\tlet track;\n\tlet trigger;\n\tlet dirty = true;\n\tconst update = () => {\n\t\tdirty = true;\n\t\ttrigger();\n\t};\n\twatch(source, update, {\n\t\tflush: \"sync\",\n\t\t...options\n\t});\n\tconst get$1 = typeof fn === \"function\" ? fn : fn.get;\n\tconst set$1 = typeof fn === \"function\" ? void 0 : fn.set;\n\tconst result = customRef((_track, _trigger) => {\n\t\ttrack = _track;\n\t\ttrigger = _trigger;\n\t\treturn {\n\t\t\tget() {\n\t\t\t\tif (dirty) {\n\t\t\t\t\tv = get$1(v);\n\t\t\t\t\tdirty = false;\n\t\t\t\t}\n\t\t\t\ttrack();\n\t\t\t\treturn v;\n\t\t\t},\n\t\t\tset(v$1) {\n\t\t\t\tset$1 === null || set$1 === void 0 || set$1(v$1);\n\t\t\t}\n\t\t};\n\t});\n\tresult.trigger = update;\n\treturn result;\n}\n/** @deprecated use `computedWithControl` instead */\nconst controlledComputed = computedWithControl;\n\n//#endregion\n//#region tryOnScopeDispose/index.ts\n/**\n* Call onScopeDispose() if it's inside an effect scope lifecycle, if not, do nothing\n*\n* @param fn\n*/\nfunction tryOnScopeDispose(fn, failSilently) {\n\tif (getCurrentScope()) {\n\t\tonScopeDispose(fn, failSilently);\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n//#endregion\n//#region createEventHook/index.ts\n/**\n* Utility for creating event hooks\n*\n* @see https://vueuse.org/createEventHook\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction createEventHook() {\n\tconst fns = /* @__PURE__ */ new Set();\n\tconst off = (fn) => {\n\t\tfns.delete(fn);\n\t};\n\tconst clear = () => {\n\t\tfns.clear();\n\t};\n\tconst on = (fn) => {\n\t\tfns.add(fn);\n\t\tconst offFn = () => off(fn);\n\t\ttryOnScopeDispose(offFn);\n\t\treturn { off: offFn };\n\t};\n\tconst trigger = (...args) => {\n\t\treturn Promise.all(Array.from(fns).map((fn) => fn(...args)));\n\t};\n\treturn {\n\t\ton,\n\t\toff,\n\t\ttrigger,\n\t\tclear\n\t};\n}\n\n//#endregion\n//#region createGlobalState/index.ts\n/**\n* Keep states in the global scope to be reusable across Vue instances.\n*\n* @see https://vueuse.org/createGlobalState\n* @param stateFactory A factory function to create the state\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction createGlobalState(stateFactory) {\n\tlet initialized = false;\n\tlet state;\n\tconst scope = effectScope(true);\n\treturn ((...args) => {\n\t\tif (!initialized) {\n\t\t\tstate = scope.run(() => stateFactory(...args));\n\t\t\tinitialized = true;\n\t\t}\n\t\treturn state;\n\t});\n}\n\n//#endregion\n//#region provideLocal/map.ts\nconst localProvidedStateMap = /* @__PURE__ */ new WeakMap();\n\n//#endregion\n//#region injectLocal/index.ts\n/**\n* On the basis of `inject`, it is allowed to directly call inject to obtain the value after call provide in the same component.\n*\n* @example\n* ```ts\n* injectLocal('MyInjectionKey', 1)\n* const injectedValue = injectLocal('MyInjectionKey') // injectedValue === 1\n* ```\n*\n* @__NO_SIDE_EFFECTS__\n*/\nconst injectLocal = (...args) => {\n\tvar _getCurrentInstance;\n\tconst key = args[0];\n\tconst instance = (_getCurrentInstance = getCurrentInstance()) === null || _getCurrentInstance === void 0 ? void 0 : _getCurrentInstance.proxy;\n\tconst owner = instance !== null && instance !== void 0 ? instance : getCurrentScope();\n\tif (owner == null && !hasInjectionContext()) throw new Error(\"injectLocal must be called in setup\");\n\tif (owner && localProvidedStateMap.has(owner) && key in localProvidedStateMap.get(owner)) return localProvidedStateMap.get(owner)[key];\n\treturn inject(...args);\n};\n\n//#endregion\n//#region provideLocal/index.ts\n/**\n* On the basis of `provide`, it is allowed to directly call inject to obtain the value after call provide in the same component.\n*\n* @example\n* ```ts\n* provideLocal('MyInjectionKey', 1)\n* const injectedValue = injectLocal('MyInjectionKey') // injectedValue === 1\n* ```\n*/\nfunction provideLocal(key, value) {\n\tvar _getCurrentInstance;\n\tconst instance = (_getCurrentInstance = getCurrentInstance()) === null || _getCurrentInstance === void 0 ? void 0 : _getCurrentInstance.proxy;\n\tconst owner = instance !== null && instance !== void 0 ? instance : getCurrentScope();\n\tif (owner == null) throw new Error(\"provideLocal must be called in setup\");\n\tif (!localProvidedStateMap.has(owner)) localProvidedStateMap.set(owner, Object.create(null));\n\tconst localProvidedState = localProvidedStateMap.get(owner);\n\tlocalProvidedState[key] = value;\n\treturn provide(key, value);\n}\n\n//#endregion\n//#region createInjectionState/index.ts\n/**\n* Create global state that can be injected into components.\n*\n* @see https://vueuse.org/createInjectionState\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction createInjectionState(composable, options) {\n\tconst key = (options === null || options === void 0 ? void 0 : options.injectionKey) || Symbol(composable.name || \"InjectionState\");\n\tconst defaultValue = options === null || options === void 0 ? void 0 : options.defaultValue;\n\tconst useProvidingState = (...args) => {\n\t\tconst state = composable(...args);\n\t\tprovideLocal(key, state);\n\t\treturn state;\n\t};\n\tconst useInjectedState = () => injectLocal(key, defaultValue);\n\treturn [useProvidingState, useInjectedState];\n}\n\n//#endregion\n//#region createRef/index.ts\n/**\n* Returns a `deepRef` or `shallowRef` depending on the `deep` param.\n*\n* @example createRef(1) // ShallowRef<number>\n* @example createRef(1, false) // ShallowRef<number>\n* @example createRef(1, true) // Ref<number>\n* @example createRef(\"string\") // ShallowRef<string>\n* @example createRef<\"A\"|\"B\">(\"A\", true) // Ref<\"A\"|\"B\">\n*\n* @param value\n* @param deep\n* @returns the `deepRef` or `shallowRef`\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction createRef(value, deep) {\n\tif (deep === true) return ref(value);\n\telse return shallowRef(value);\n}\n\n//#endregion\n//#region utils/is.ts\nconst isClient = typeof window !== \"undefined\" && typeof document !== \"undefined\";\nconst isWorker = typeof WorkerGlobalScope !== \"undefined\" && globalThis instanceof WorkerGlobalScope;\nconst isDef = (val) => typeof val !== \"undefined\";\nconst notNullish = (val) => val != null;\nconst assert = (condition, ...infos) => {\n\tif (!condition) console.warn(...infos);\n};\nconst toString = Object.prototype.toString;\nconst isObject = (val) => toString.call(val) === \"[object Object]\";\nconst now = () => Date.now();\nconst timestamp = () => +Date.now();\nconst clamp = (n, min, max) => Math.min(max, Math.max(min, n));\nconst noop = () => {};\nconst rand = (min, max) => {\n\tmin = Math.ceil(min);\n\tmax = Math.floor(max);\n\treturn Math.floor(Math.random() * (max - min + 1)) + min;\n};\nconst hasOwn = (val, key) => Object.prototype.hasOwnProperty.call(val, key);\nconst isIOS = /* @__PURE__ */ getIsIOS();\nfunction getIsIOS() {\n\tvar _window, _window2, _window3;\n\treturn isClient && !!((_window = window) === null || _window === void 0 || (_window = _window.navigator) === null || _window === void 0 ? void 0 : _window.userAgent) && (/iP(?:ad|hone|od)/.test(window.navigator.userAgent) || ((_window2 = window) === null || _window2 === void 0 || (_window2 = _window2.navigator) === null || _window2 === void 0 ? void 0 : _window2.maxTouchPoints) > 2 && /iPad|Macintosh/.test((_window3 = window) === null || _window3 === void 0 ? void 0 : _window3.navigator.userAgent));\n}\n\n//#endregion\n//#region toRef/index.ts\nfunction toRef(...args) {\n\tif (args.length !== 1) return toRef$1(...args);\n\tconst r = args[0];\n\treturn typeof r === \"function\" ? readonly(customRef(() => ({\n\t\tget: r,\n\t\tset: noop\n\t}))) : ref(r);\n}\n\n//#endregion\n//#region utils/filters.ts\n/**\n* @internal\n*/\nfunction createFilterWrapper(filter, fn) {\n\tfunction wrapper(...args) {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tPromise.resolve(filter(() => fn.apply(this, args), {\n\t\t\t\tfn,\n\t\t\t\tthisArg: this,\n\t\t\t\targs\n\t\t\t})).then(resolve).catch(reject);\n\t\t});\n\t}\n\treturn wrapper;\n}\nconst bypassFilter = (invoke$1) => {\n\treturn invoke$1();\n};\n/**\n* Create an EventFilter that debounce the events\n*/\nfunction debounceFilter(ms, options = {}) {\n\tlet timer;\n\tlet maxTimer;\n\tlet lastRejector = noop;\n\tconst _clearTimeout = (timer$1) => {\n\t\tclearTimeout(timer$1);\n\t\tlastRejector();\n\t\tlastRejector = noop;\n\t};\n\tlet lastInvoker;\n\tconst filter = (invoke$1) => {\n\t\tconst duration = toValue(ms);\n\t\tconst maxDuration = toValue(options.maxWait);\n\t\tif (timer) _clearTimeout(timer);\n\t\tif (duration <= 0 || maxDuration !== void 0 && maxDuration <= 0) {\n\t\t\tif (maxTimer) {\n\t\t\t\t_clearTimeout(maxTimer);\n\t\t\t\tmaxTimer = void 0;\n\t\t\t}\n\t\t\treturn Promise.resolve(invoke$1());\n\t\t}\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tlastRejector = options.rejectOnCancel ? reject : resolve;\n\t\t\tlastInvoker = invoke$1;\n\t\t\tif (maxDuration && !maxTimer) maxTimer = setTimeout(() => {\n\t\t\t\tif (timer) _clearTimeout(timer);\n\t\t\t\tmaxTimer = void 0;\n\t\t\t\tresolve(lastInvoker());\n\t\t\t}, maxDuration);\n\t\t\ttimer = setTimeout(() => {\n\t\t\t\tif (maxTimer) _clearTimeout(maxTimer);\n\t\t\t\tmaxTimer = void 0;\n\t\t\t\tresolve(invoke$1());\n\t\t\t}, duration);\n\t\t});\n\t};\n\treturn filter;\n}\nfunction throttleFilter(...args) {\n\tlet lastExec = 0;\n\tlet timer;\n\tlet isLeading = true;\n\tlet lastRejector = noop;\n\tlet lastValue;\n\tlet ms;\n\tlet trailing;\n\tlet leading;\n\tlet rejectOnCancel;\n\tif (!isRef(args[0]) && typeof args[0] === \"object\") ({delay: ms, trailing = true, leading = true, rejectOnCancel = false} = args[0]);\n\telse [ms, trailing = true, leading = true, rejectOnCancel = false] = args;\n\tconst clear = () => {\n\t\tif (timer) {\n\t\t\tclearTimeout(timer);\n\t\t\ttimer = void 0;\n\t\t\tlastRejector();\n\t\t\tlastRejector = noop;\n\t\t}\n\t};\n\tconst filter = (_invoke) => {\n\t\tconst duration = toValue(ms);\n\t\tconst elapsed = Date.now() - lastExec;\n\t\tconst invoke$1 = () => {\n\t\t\treturn lastValue = _invoke();\n\t\t};\n\t\tclear();\n\t\tif (duration <= 0) {\n\t\t\tlastExec = Date.now();\n\t\t\treturn invoke$1();\n\t\t}\n\t\tif (elapsed > duration) {\n\t\t\tlastExec = Date.now();\n\t\t\tif (leading || !isLeading) invoke$1();\n\t\t} else if (trailing) lastValue = new Promise((resolve, reject) => {\n\t\t\tlastRejector = rejectOnCancel ? reject : resolve;\n\t\t\ttimer = setTimeout(() => {\n\t\t\t\tlastExec = Date.now();\n\t\t\t\tisLeading = true;\n\t\t\t\tresolve(invoke$1());\n\t\t\t\tclear();\n\t\t\t}, Math.max(0, duration - elapsed));\n\t\t});\n\t\tif (!leading && !timer) timer = setTimeout(() => isLeading = true, duration);\n\t\tisLeading = false;\n\t\treturn lastValue;\n\t};\n\treturn filter;\n}\n/**\n* EventFilter that gives extra controls to pause and resume the filter\n*\n* @param extendFilter Extra filter to apply when the PausableFilter is active, default to none\n* @param options Options to configure the filter\n*/\nfunction pausableFilter(extendFilter = bypassFilter, options = {}) {\n\tconst { initialState = \"active\" } = options;\n\tconst isActive = toRef(initialState === \"active\");\n\tfunction pause() {\n\t\tisActive.value = false;\n\t}\n\tfunction resume() {\n\t\tisActive.value = true;\n\t}\n\tconst eventFilter = (...args) => {\n\t\tif (isActive.value) extendFilter(...args);\n\t};\n\treturn {\n\t\tisActive: readonly(isActive),\n\t\tpause,\n\t\tresume,\n\t\teventFilter\n\t};\n}\n\n//#endregion\n//#region utils/general.ts\nfunction promiseTimeout(ms, throwOnTimeout = false, reason = \"Timeout\") {\n\treturn new Promise((resolve, reject) => {\n\t\tif (throwOnTimeout) setTimeout(() => reject(reason), ms);\n\t\telse setTimeout(resolve, ms);\n\t});\n}\nfunction identity(arg) {\n\treturn arg;\n}\n/**\n* Create singleton promise function\n*\n* @example\n* ```\n* const promise = createSingletonPromise(async () => { ... })\n*\n* await promise()\n* await promise() // all of them will be bind to a single promise instance\n* await promise() // and be resolved together\n* ```\n*/\nfunction createSingletonPromise(fn) {\n\tlet _promise;\n\tfunction wrapper() {\n\t\tif (!_promise) _promise = fn();\n\t\treturn _promise;\n\t}\n\twrapper.reset = async () => {\n\t\tconst _prev = _promise;\n\t\t_promise = void 0;\n\t\tif (_prev) await _prev;\n\t};\n\treturn wrapper;\n}\nfunction invoke(fn) {\n\treturn fn();\n}\nfunction containsProp(obj, ...props) {\n\treturn props.some((k) => k in obj);\n}\nfunction increaseWithUnit(target, delta) {\n\tvar _target$match;\n\tif (typeof target === \"number\") return target + delta;\n\tconst value = ((_target$match = target.match(/^-?\\d+\\.?\\d*/)) === null || _target$match === void 0 ? void 0 : _target$match[0]) || \"\";\n\tconst unit = target.slice(value.length);\n\tconst result = Number.parseFloat(value) + delta;\n\tif (Number.isNaN(result)) return target;\n\treturn result + unit;\n}\n/**\n* Get a px value for SSR use, do not rely on this method outside of SSR as REM unit is assumed at 16px, which might not be the case on the client\n*/\nfunction pxValue(px) {\n\treturn px.endsWith(\"rem\") ? Number.parseFloat(px) * 16 : Number.parseFloat(px);\n}\n/**\n* Create a new subset object by giving keys\n*/\nfunction objectPick(obj, keys, omitUndefined = false) {\n\treturn keys.reduce((n, k) => {\n\t\tif (k in obj) {\n\t\t\tif (!omitUndefined || obj[k] !== void 0) n[k] = obj[k];\n\t\t}\n\t\treturn n;\n\t}, {});\n}\n/**\n* Create a new subset object by omit giving keys\n*/\nfunction objectOmit(obj, keys, omitUndefined = false) {\n\treturn Object.fromEntries(Object.entries(obj).filter(([key, value]) => {\n\t\treturn (!omitUndefined || value !== void 0) && !keys.includes(key);\n\t}));\n}\nfunction objectEntries(obj) {\n\treturn Object.entries(obj);\n}\nfunction toArray(value) {\n\treturn Array.isArray(value) ? value : [value];\n}\n\n//#endregion\n//#region utils/port.ts\nfunction cacheStringFunction(fn) {\n\tconst cache = Object.create(null);\n\treturn ((str) => {\n\t\treturn cache[str] || (cache[str] = fn(str));\n\t});\n}\nconst hyphenateRE = /\\B([A-Z])/g;\nconst hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, \"-$1\").toLowerCase());\nconst camelizeRE = /-(\\w)/g;\nconst camelize = cacheStringFunction((str) => {\n\treturn str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : \"\");\n});\n\n//#endregion\n//#region utils/vue.ts\nfunction getLifeCycleTarget(target) {\n\treturn target || getCurrentInstance();\n}\n\n//#endregion\n//#region createSharedComposable/index.ts\n/**\n* Make a composable function usable with multiple Vue instances.\n*\n* @see https://vueuse.org/createSharedComposable\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction createSharedComposable(composable) {\n\tif (!isClient) return composable;\n\tlet subscribers = 0;\n\tlet state;\n\tlet scope;\n\tconst dispose = () => {\n\t\tsubscribers -= 1;\n\t\tif (scope && subscribers <= 0) {\n\t\t\tscope.stop();\n\t\t\tstate = void 0;\n\t\t\tscope = void 0;\n\t\t}\n\t};\n\treturn ((...args) => {\n\t\tsubscribers += 1;\n\t\tif (!scope) {\n\t\t\tscope = effectScope(true);\n\t\t\tstate = scope.run(() => composable(...args));\n\t\t}\n\t\ttryOnScopeDispose(dispose);\n\t\treturn state;\n\t});\n}\n\n//#endregion\n//#region extendRef/index.ts\nfunction extendRef(ref$1, extend, { enumerable = false, unwrap = true } = {}) {\n\tfor (const [key, value] of Object.entries(extend)) {\n\t\tif (key === \"value\") continue;\n\t\tif (isRef(value) && unwrap) Object.defineProperty(ref$1, key, {\n\t\t\tget() {\n\t\t\t\treturn value.value;\n\t\t\t},\n\t\t\tset(v) {\n\t\t\t\tvalue.value = v;\n\t\t\t},\n\t\t\tenumerable\n\t\t});\n\t\telse Object.defineProperty(ref$1, key, {\n\t\t\tvalue,\n\t\t\tenumerable\n\t\t});\n\t}\n\treturn ref$1;\n}\n\n//#endregion\n//#region get/index.ts\nfunction get(obj, key) {\n\tif (key == null) return unref(obj);\n\treturn unref(obj)[key];\n}\n\n//#endregion\n//#region isDefined/index.ts\nfunction isDefined(v) {\n\treturn unref(v) != null;\n}\n\n//#endregion\n//#region makeDestructurable/index.ts\n/* @__NO_SIDE_EFFECTS__ */\nfunction makeDestructurable(obj, arr) {\n\tif (typeof Symbol !== \"undefined\") {\n\t\tconst clone = { ...obj };\n\t\tObject.defineProperty(clone, Symbol.iterator, {\n\t\t\tenumerable: false,\n\t\t\tvalue() {\n\t\t\t\tlet index = 0;\n\t\t\t\treturn { next: () => ({\n\t\t\t\t\tvalue: arr[index++],\n\t\t\t\t\tdone: index > arr.length\n\t\t\t\t}) };\n\t\t\t}\n\t\t});\n\t\treturn clone;\n\t} else return Object.assign([...arr], obj);\n}\n\n//#endregion\n//#region reactify/index.ts\n/**\n* Converts plain function into a reactive function.\n* The converted function accepts refs as it's arguments\n* and returns a ComputedRef, with proper typing.\n*\n* @param fn - Source function\n* @param options - Options\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction reactify(fn, options) {\n\tconst unrefFn = (options === null || options === void 0 ? void 0 : options.computedGetter) === false ? unref : toValue;\n\treturn function(...args) {\n\t\treturn computed(() => fn.apply(this, args.map((i) => unrefFn(i))));\n\t};\n}\n/** @deprecated use `reactify` instead */\nconst createReactiveFn = reactify;\n\n//#endregion\n//#region reactifyObject/index.ts\n/**\n* Apply `reactify` to an object\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction reactifyObject(obj, optionsOrKeys = {}) {\n\tlet keys = [];\n\tlet options;\n\tif (Array.isArray(optionsOrKeys)) keys = optionsOrKeys;\n\telse {\n\t\toptions = optionsOrKeys;\n\t\tconst { includeOwnProperties = true } = optionsOrKeys;\n\t\tkeys.push(...Object.keys(obj));\n\t\tif (includeOwnProperties) keys.push(...Object.getOwnPropertyNames(obj));\n\t}\n\treturn Object.fromEntries(keys.map((key) => {\n\t\tconst value = obj[key];\n\t\treturn [key, typeof value === \"function\" ? reactify(value.bind(obj), options) : value];\n\t}));\n}\n\n//#endregion\n//#region toReactive/index.ts\n/**\n* Converts ref to reactive.\n*\n* @see https://vueuse.org/toReactive\n* @param objectRef A ref of object\n*/\nfunction toReactive(objectRef) {\n\tif (!isRef(objectRef)) return reactive(objectRef);\n\treturn reactive(new Proxy({}, {\n\t\tget(_, p, receiver) {\n\t\t\treturn unref(Reflect.get(objectRef.value, p, receiver));\n\t\t},\n\t\tset(_, p, value) {\n\t\t\tif (isRef(objectRef.value[p]) && !isRef(value)) objectRef.value[p].value = value;\n\t\t\telse objectRef.value[p] = value;\n\t\t\treturn true;\n\t\t},\n\t\tdeleteProperty(_, p) {\n\t\t\treturn Reflect.deleteProperty(objectRef.value, p);\n\t\t},\n\t\thas(_, p) {\n\t\t\treturn Reflect.has(objectRef.value, p);\n\t\t},\n\t\townKeys() {\n\t\t\treturn Object.keys(objectRef.value);\n\t\t},\n\t\tgetOwnPropertyDescriptor() {\n\t\t\treturn {\n\t\t\t\tenumerable: true,\n\t\t\t\tconfigurable: true\n\t\t\t};\n\t\t}\n\t}));\n}\n\n//#endregion\n//#region reactiveComputed/index.ts\n/**\n* Computed reactive object.\n*/\nfunction reactiveComputed(fn) {\n\treturn toReactive(computed(fn));\n}\n\n//#endregion\n//#region reactiveOmit/index.ts\n/**\n* Reactively omit fields from a reactive object\n*\n* @see https://vueuse.org/reactiveOmit\n*/\nfunction reactiveOmit(obj, ...keys) {\n\tconst flatKeys = keys.flat();\n\tconst predicate = flatKeys[0];\n\treturn reactiveComputed(() => typeof predicate === \"function\" ? Object.fromEntries(Object.entries(toRefs$1(obj)).filter(([k, v]) => !predicate(toValue(v), k))) : Object.fromEntries(Object.entries(toRefs$1(obj)).filter((e) => !flatKeys.includes(e[0]))));\n}\n\n//#endregion\n//#region reactivePick/index.ts\n/**\n* Reactively pick fields from a reactive object\n*\n* @see https://vueuse.org/reactivePick\n*/\nfunction reactivePick(obj, ...keys) {\n\tconst flatKeys = keys.flat();\n\tconst predicate = flatKeys[0];\n\treturn reactiveComputed(() => typeof predicate === \"function\" ? Object.fromEntries(Object.entries(toRefs$1(obj)).filter(([k, v]) => predicate(toValue(v), k))) : Object.fromEntries(flatKeys.map((k) => [k, toRef(obj, k)])));\n}\n\n//#endregion\n//#region refAutoReset/index.ts\n/**\n* Create a ref which will be reset to the default value after some time.\n*\n* @see https://vueuse.org/refAutoReset\n* @param defaultValue The value which will be set.\n* @param afterMs A zero-or-greater delay in milliseconds.\n*/\nfunction refAutoReset(defaultValue, afterMs = 1e4) {\n\treturn customRef((track, trigger) => {\n\t\tlet value = toValue(defaultValue);\n\t\tlet timer;\n\t\tconst resetAfter = () => setTimeout(() => {\n\t\t\tvalue = toValue(defaultValue);\n\t\t\ttrigger();\n\t\t}, toValue(afterMs));\n\t\ttryOnScopeDispose(() => {\n\t\t\tclearTimeout(timer);\n\t\t});\n\t\treturn {\n\t\t\tget() {\n\t\t\t\ttrack();\n\t\t\t\treturn value;\n\t\t\t},\n\t\t\tset(newValue) {\n\t\t\t\tvalue = newValue;\n\t\t\t\ttrigger();\n\t\t\t\tclearTimeout(timer);\n\t\t\t\ttimer = resetAfter();\n\t\t\t}\n\t\t};\n\t});\n}\n/** @deprecated use `refAutoReset` instead */\nconst autoResetRef = refAutoReset;\n\n//#endregion\n//#region useDebounceFn/index.ts\n/**\n* Debounce execution of a function.\n*\n* @see https://vueuse.org/useDebounceFn\n* @param fn A function to be executed after delay milliseconds debounced.\n* @param ms A zero-or-greater delay in milliseconds. For event callbacks, values around 100 or 250 (or even higher) are most useful.\n* @param options Options\n*\n* @return A new, debounce, function.\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction useDebounceFn(fn, ms = 200, options = {}) {\n\treturn createFilterWrapper(debounceFilter(ms, options), fn);\n}\n\n//#endregion\n//#region refDebounced/index.ts\n/**\n* Debounce updates of a ref.\n*\n* @return A new debounced ref.\n*/\nfunction refDebounced(value, ms = 200, options = {}) {\n\tconst debounced = ref(toValue(value));\n\tconst updater = useDebounceFn(() => {\n\t\tdebounced.value = value.value;\n\t}, ms, options);\n\twatch(value, () => updater());\n\treturn shallowReadonly(debounced);\n}\n/** @deprecated use `refDebounced` instead */\nconst debouncedRef = refDebounced;\n/** @deprecated use `refDebounced` instead */\nconst useDebounce = refDebounced;\n\n//#endregion\n//#region refDefault/index.ts\n/**\n* Apply default value to a ref.\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction refDefault(source, defaultValue) {\n\treturn computed({\n\t\tget() {\n\t\t\tvar _source$value;\n\t\t\treturn (_source$value = source.value) !== null && _source$value !== void 0 ? _source$value : defaultValue;\n\t\t},\n\t\tset(value) {\n\t\t\tsource.value = value;\n\t\t}\n\t});\n}\n\n//#endregion\n//#region refManualReset/index.ts\n/**\n* Create a ref with manual reset functionality.\n*\n* @see https://vueuse.org/refManualReset\n* @param defaultValue The value which will be set.\n*/\nfunction refManualReset(defaultValue) {\n\tlet value = toValue(defaultValue);\n\tlet trigger;\n\tconst reset = () => {\n\t\tvalue = toValue(defaultValue);\n\t\ttrigger();\n\t};\n\tconst refValue = customRef((track, _trigger) => {\n\t\ttrigger = _trigger;\n\t\treturn {\n\t\t\tget() {\n\t\t\t\ttrack();\n\t\t\t\treturn value;\n\t\t\t},\n\t\t\tset(newValue) {\n\t\t\t\tvalue = newValue;\n\t\t\t\ttrigger();\n\t\t\t}\n\t\t};\n\t});\n\trefValue.reset = reset;\n\treturn refValue;\n}\n\n//#endregion\n//#region useThrottleFn/index.ts\n/**\n* Throttle execution of a function. Especially useful for rate limiting\n* execution of handlers on events like resize and scroll.\n*\n* @param fn A function to be executed after delay milliseconds. The `this` context and all arguments are passed through, as-is,\n* to `callback` when the throttled-function is executed.\n* @param ms A zero-or-greater delay in milliseconds. For event callbacks, values around 100 or 250 (or even higher) are most useful.\n* (default value: 200)\n*\n* @param [trailing] if true, call fn again after the time is up (default value: false)\n*\n* @param [leading] if true, call fn on the leading edge of the ms timeout (default value: true)\n*\n* @param [rejectOnCancel] if true, reject the last call if it's been cancel (default value: false)\n*\n* @return A new, throttled, function.\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction useThrottleFn(fn, ms = 200, trailing = false, leading = true, rejectOnCancel = false) {\n\treturn createFilterWrapper(throttleFilter(ms, trailing, leading, rejectOnCancel), fn);\n}\n\n//#endregion\n//#region refThrottled/index.ts\n/**\n* Throttle execution of a function. Especially useful for rate limiting\n* execution of handlers on events like resize and scroll.\n*\n* @param value Ref value to be watched with throttle effect\n* @param delay A zero-or-greater delay in milliseconds. For event callbacks, values around 100 or 250 (or even higher) are most useful.\n* @param trailing if true, update the value again after the delay time is up\n* @param leading if true, update the value on the leading edge of the ms timeout\n*/\nfunction refThrottled(value, delay = 200, trailing = true, leading = true) {\n\tif (delay <= 0) return value;\n\tconst throttled = ref(toValue(value));\n\tconst updater = useThrottleFn(() => {\n\t\tthrottled.value = value.value;\n\t}, delay, trailing, leading);\n\twatch(value, () => updater());\n\treturn throttled;\n}\n/** @deprecated use `refThrottled` instead */\nconst throttledRef = refThrottled;\n/** @deprecated use `refThrottled` instead */\nconst useThrottle = refThrottled;\n\n//#endregion\n//#region refWithControl/index.ts\n/**\n* Fine-grained controls over ref and its reactivity.\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction refWithControl(initial, options = {}) {\n\tlet source = initial;\n\tlet track;\n\tlet trigger;\n\tconst ref$1 = customRef((_track, _trigger) => {\n\t\ttrack = _track;\n\t\ttrigger = _trigger;\n\t\treturn {\n\t\t\tget() {\n\t\t\t\treturn get$1();\n\t\t\t},\n\t\t\tset(v) {\n\t\t\t\tset$1(v);\n\t\t\t}\n\t\t};\n\t});\n\tfunction get$1(tracking = true) {\n\t\tif (tracking) track();\n\t\treturn source;\n\t}\n\tfunction set$1(value, triggering = true) {\n\t\tvar _options$onBeforeChan, _options$onChanged;\n\t\tif (value === source) return;\n\t\tconst old = source;\n\t\tif (((_options$onBeforeChan = options.onBeforeChange) === null || _options$onBeforeChan === void 0 ? void 0 : _options$onBeforeChan.call(options, value, old)) === false) return;\n\t\tsource = value;\n\t\t(_options$onChanged = options.onChanged) === null || _options$onChanged === void 0 || _options$onChanged.call(options, value, old);\n\t\tif (triggering) trigger();\n\t}\n\t/**\n\t* Get the value without tracked in the reactivity system\n\t*/\n\tconst untrackedGet = () => get$1(false);\n\t/**\n\t* Set the value without triggering the reactivity system\n\t*/\n\tconst silentSet = (v) => set$1(v, false);\n\t/**\n\t* Get the value without tracked in the reactivity system.\n\t*\n\t* Alias for `untrackedGet()`\n\t*/\n\tconst peek = () => get$1(false);\n\t/**\n\t* Set the value without triggering the reactivity system\n\t*\n\t* Alias for `silentSet(v)`\n\t*/\n\tconst lay = (v) => set$1(v, false);\n\treturn extendRef(ref$1, {\n\t\tget: get$1,\n\t\tset: set$1,\n\t\tuntrackedGet,\n\t\tsilentSet,\n\t\tpeek,\n\t\tlay\n\t}, { enumerable: true });\n}\n/** @deprecated use `refWithControl` instead */\nconst controlledRef = refWithControl;\n\n//#endregion\n//#region set/index.ts\n/**\n* Shorthand for `ref.value = x`\n*/\nfunction set(...args) {\n\tif (args.length === 2) {\n\t\tconst [ref$1, value] = args;\n\t\tref$1.value = value;\n\t}\n\tif (args.length === 3) {\n\t\tconst [target, key, value] = args;\n\t\ttarget[key] = value;\n\t}\n}\n\n//#endregion\n//#region watchWithFilter/index.ts\nfunction watchWithFilter(source, cb, options = {}) {\n\tconst { eventFilter = bypassFilter,...watchOptions } = options;\n\treturn watch(source, createFilterWrapper(eventFilter, cb), watchOptions);\n}\n\n//#endregion\n//#region watchPausable/index.ts\n/** @deprecated Use Vue's built-in `watch` instead. This function will be removed in future version. */\nfunction watchPausable(source, cb, options = {}) {\n\tconst { eventFilter: filter, initialState = \"active\",...watchOptions } = options;\n\tconst { eventFilter, pause, resume, isActive } = pausableFilter(filter, { initialState });\n\treturn {\n\t\tstop: watchWithFilter(source, cb, {\n\t\t\t...watchOptions,\n\t\t\teventFilter\n\t\t}),\n\t\tpause,\n\t\tresume,\n\t\tisActive\n\t};\n}\n/** @deprecated Use Vue's built-in `watch` instead. This function will be removed in future version. */\nconst pausableWatch = watchPausable;\n\n//#endregion\n//#region syncRef/index.ts\n/**\n* Two-way refs synchronization.\n* From the set theory perspective to restrict the option's type\n* Check in the following order:\n* 1. L = R\n* 2. L ∩ R ≠ ∅\n* 3. L ⊆ R\n* 4. L ∩ R = ∅\n*/\nfunction syncRef(left, right, ...[options]) {\n\tconst { flush = \"sync\", deep = false, immediate = true, direction = \"both\", transform = {} } = options || {};\n\tconst watchers = [];\n\tconst transformLTR = \"ltr\" in transform && transform.ltr || ((v) => v);\n\tconst transformRTL = \"rtl\" in transform && transform.rtl || ((v) => v);\n\tif (direction === \"both\" || direction === \"ltr\") watchers.push(watchPausable(left, (newValue) => {\n\t\twatchers.forEach((w) => w.pause());\n\t\tright.value = transformLTR(newValue);\n\t\twatchers.forEach((w) => w.resume());\n\t}, {\n\t\tflush,\n\t\tdeep,\n\t\timmediate\n\t}));\n\tif (direction === \"both\" || direction === \"rtl\") watchers.push(watchPausable(right, (newValue) => {\n\t\twatchers.forEach((w) => w.pause());\n\t\tleft.value = transformRTL(newValue);\n\t\twatchers.forEach((w) => w.resume());\n\t}, {\n\t\tflush,\n\t\tdeep,\n\t\timmediate\n\t}));\n\tconst stop = () => {\n\t\twatchers.forEach((w) => w.stop());\n\t};\n\treturn stop;\n}\n\n//#endregion\n//#region syncRefs/index.ts\n/**\n* Keep target ref(s) in sync with the source ref\n*\n* @param source source ref\n* @param targets\n*/\nfunction syncRefs(source, targets, options = {}) {\n\tconst { flush = \"sync\", deep = false, immediate = true } = options;\n\tconst targetsArray = toArray(targets);\n\treturn watch(source, (newValue) => targetsArray.forEach((target) => target.value = newValue), {\n\t\tflush,\n\t\tdeep,\n\t\timmediate\n\t});\n}\n\n//#endregion\n//#region toRefs/index.ts\n/**\n* Extended `toRefs` that also accepts refs of an object.\n*\n* @see https://vueuse.org/toRefs\n* @param objectRef A ref or normal object or array.\n* @param options Options\n*/\nfunction toRefs(objectRef, options = {}) {\n\tif (!isRef(objectRef)) return toRefs$1(objectRef);\n\tconst result = Array.isArray(objectRef.value) ? Array.from({ length: objectRef.value.length }) : {};\n\tfor (const key in objectRef.value) result[key] = customRef(() => ({\n\t\tget() {\n\t\t\treturn objectRef.value[key];\n\t\t},\n\t\tset(v) {\n\t\t\tvar _toValue;\n\t\t\tif ((_toValue = toValue(options.replaceRef)) !== null && _toValue !== void 0 ? _toValue : true) if (Array.isArray(objectRef.value)) {\n\t\t\t\tconst copy = [...objectRef.value];\n\t\t\t\tcopy[key] = v;\n\t\t\t\tobjectRef.value = copy;\n\t\t\t} else {\n\t\t\t\tconst newObject = {\n\t\t\t\t\t...objectRef.value,\n\t\t\t\t\t[key]: v\n\t\t\t\t};\n\t\t\t\tObject.setPrototypeOf(newObject, Object.getPrototypeOf(objectRef.value));\n\t\t\t\tobjectRef.value = newObject;\n\t\t\t}\n\t\t\telse objectRef.value[key] = v;\n\t\t}\n\t}));\n\treturn result;\n}\n\n//#endregion\n//#region tryOnBeforeMount/index.ts\n/**\n* Call onBeforeMount() if it's inside a component lifecycle, if not, just call the function\n*\n* @param fn\n* @param sync if set to false, it will run in the nextTick() of Vue\n* @param target\n*/\nfunction tryOnBeforeMount(fn, sync = true, target) {\n\tif (getLifeCycleTarget(target)) onBeforeMount(fn, target);\n\telse if (sync) fn();\n\telse nextTick(fn);\n}\n\n//#endregion\n//#region tryOnBeforeUnmount/index.ts\n/**\n* Call onBeforeUnmount() if it's inside a component lifecycle, if not, do nothing\n*\n* @param fn\n* @param target\n*/\nfunction tryOnBeforeUnmount(fn, target) {\n\tif (getLifeCycleTarget(target)) onBeforeUnmount(fn, target);\n}\n\n//#endregion\n//#region tryOnMounted/index.ts\n/**\n* Call onMounted() if it's inside a component lifecycle, if not, just call the function\n*\n* @param fn\n* @param sync if set to false, it will run in the nextTick() of Vue\n* @param target\n*/\nfunction tryOnMounted(fn, sync = true, target) {\n\tif (getLifeCycleTarget(target)) onMounted(fn, target);\n\telse if (sync) fn();\n\telse nextTick(fn);\n}\n\n//#endregion\n//#region tryOnUnmounted/index.ts\n/**\n* Call onUnmounted() if it's inside a component lifecycle, if not, do nothing\n*\n* @param fn\n* @param target\n*/\nfunction tryOnUnmounted(fn, target) {\n\tif (getLifeCycleTarget(target)) onUnmounted(fn, target);\n}\n\n//#endregion\n//#region until/index.ts\nfunction createUntil(r, isNot = false) {\n\tfunction toMatch(condition, { flush = \"sync\", deep = false, timeout, throwOnTimeout } = {}) {\n\t\tlet stop = null;\n\t\tconst promises = [new Promise((resolve) => {\n\t\t\tstop = watch(r, (v) => {\n\t\t\t\tif (condition(v) !== isNot) {\n\t\t\t\t\tif (stop) stop();\n\t\t\t\t\telse nextTick(() => stop === null || stop === void 0 ? void 0 : stop());\n\t\t\t\t\tresolve(v);\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tflush,\n\t\t\t\tdeep,\n\t\t\t\timmediate: true\n\t\t\t});\n\t\t})];\n\t\tif (timeout != null) promises.push(promiseTimeout(timeout, throwOnTimeout).then(() => toValue(r)).finally(() => stop === null || stop === void 0 ? void 0 : stop()));\n\t\treturn Promise.race(promises);\n\t}\n\tfunction toBe(value, options) {\n\t\tif (!isRef(value)) return toMatch((v) => v === value, options);\n\t\tconst { flush = \"sync\", deep = false, timeout, throwOnTimeout } = options !== null && options !== void 0 ? options : {};\n\t\tlet stop = null;\n\t\tconst promises = [new Promise((resolve) => {\n\t\t\tstop = watch([r, value], ([v1, v2]) => {\n\t\t\t\tif (isNot !== (v1 === v2)) {\n\t\t\t\t\tif (stop) stop();\n\t\t\t\t\telse nextTick(() => stop === null || stop === void 0 ? void 0 : stop());\n\t\t\t\t\tresolve(v1);\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tflush,\n\t\t\t\tdeep,\n\t\t\t\timmediate: true\n\t\t\t});\n\t\t})];\n\t\tif (timeout != null) promises.push(promiseTimeout(timeout, throwOnTimeout).then(() => toValue(r)).finally(() => {\n\t\t\tstop === null || stop === void 0 || stop();\n\t\t\treturn toValue(r);\n\t\t}));\n\t\treturn Promise.race(promises);\n\t}\n\tfunction toBeTruthy(options) {\n\t\treturn toMatch((v) => Boolean(v), options);\n\t}\n\tfunction toBeNull(options) {\n\t\treturn toBe(null, options);\n\t}\n\tfunction toBeUndefined(options) {\n\t\treturn toBe(void 0, options);\n\t}\n\tfunction toBeNaN(options) {\n\t\treturn toMatch(Number.isNaN, options);\n\t}\n\tfunction toContains(value, options) {\n\t\treturn toMatch((v) => {\n\t\t\tconst array = Array.from(v);\n\t\t\treturn array.includes(value) || array.includes(toValue(value));\n\t\t}, options);\n\t}\n\tfunction changed(options) {\n\t\treturn changedTimes(1, options);\n\t}\n\tfunction changedTimes(n = 1, options) {\n\t\tlet count = -1;\n\t\treturn toMatch(() => {\n\t\t\tcount += 1;\n\t\t\treturn count >= n;\n\t\t}, options);\n\t}\n\tif (Array.isArray(toValue(r))) return {\n\t\ttoMatch,\n\t\ttoContains,\n\t\tchanged,\n\t\tchangedTimes,\n\t\tget not() {\n\t\t\treturn createUntil(r, !isNot);\n\t\t}\n\t};\n\telse return {\n\t\ttoMatch,\n\t\ttoBe,\n\t\ttoBeTruthy,\n\t\ttoBeNull,\n\t\ttoBeNaN,\n\t\ttoBeUndefined,\n\t\tchanged,\n\t\tchangedTimes,\n\t\tget not() {\n\t\t\treturn createUntil(r, !isNot);\n\t\t}\n\t};\n}\nfunction until(r) {\n\treturn createUntil(r);\n}\n\n//#endregion\n//#region useArrayDifference/index.ts\nfunction defaultComparator(value, othVal) {\n\treturn value === othVal;\n}\n/**\n* Reactive get array difference of two array\n* @see https://vueuse.org/useArrayDifference\n* @returns - the difference of two array\n* @param args\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction useArrayDifference(...args) {\n\tvar _args$, _args$2;\n\tconst list = args[0];\n\tconst values = args[1];\n\tlet compareFn = (_args$ = args[2]) !== null && _args$ !== void 0 ? _args$ : defaultComparator;\n\tconst { symmetric = false } = (_args$2 = args[3]) !== null && _args$2 !== void 0 ? _args$2 : {};\n\tif (typeof compareFn === \"string\") {\n\t\tconst key = compareFn;\n\t\tcompareFn = (value, othVal) => value[key] === othVal[key];\n\t}\n\tconst diff1 = computed(() => toValue(list).filter((x) => toValue(values).findIndex((y) => compareFn(x, y)) === -1));\n\tif (symmetric) {\n\t\tconst diff2 = computed(() => toValue(values).filter((x) => toValue(list).findIndex((y) => compareFn(x, y)) === -1));\n\t\treturn computed(() => symmetric ? [...toValue(diff1), ...toValue(diff2)] : toValue(diff1));\n\t} else return diff1;\n}\n\n//#endregion\n//#region useArrayEvery/index.ts\n/**\n* Reactive `Array.every`\n*\n* @see https://vueuse.org/useArrayEvery\n* @param list - the array was called upon.\n* @param fn - a function to test each element.\n*\n* @returns **true** if the `fn` function returns a **truthy** value for every element from the array. Otherwise, **false**.\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction useArrayEvery(list, fn) {\n\treturn computed(() => toValue(list).every((element, index, array) => fn(toValue(element), index, array)));\n}\n\n//#endregion\n//#region useArrayFilter/index.ts\n/**\n* Reactive `Array.filter`\n*\n* @see https://vueuse.org/useArrayFilter\n* @param list - the array was called upon.\n* @param fn - a function that is called for every element of the given `list`. Each time `fn` executes, the returned value is added to the new array.\n*\n* @returns a shallow copy of a portion of the given array, filtered down to just the elements from the given array that pass the test implemented by the provided function. If no elements pass the test, an empty array will be returned.\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction useArrayFilter(list, fn) {\n\treturn computed(() => toValue(list).map((i) => toValue(i)).filter(fn));\n}\n\n//#endregion\n//#region useArrayFind/index.ts\n/**\n* Reactive `Array.find`\n*\n* @see https://vueuse.org/useArrayFind\n* @param list - the array was called upon.\n* @param fn - a function to test each element.\n*\n* @returns the first element in the array that satisfies the provided testing function. Otherwise, undefined is returned.\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction useArrayFind(list, fn) {\n\treturn computed(() => toValue(toValue(list).find((element, index, array) => fn(toValue(element), index, array))));\n}\n\n//#endregion\n//#region useArrayFindIndex/index.ts\n/**\n* Reactive `Array.findIndex`\n*\n* @see https://vueuse.org/useArrayFindIndex\n* @param list - the array was called upon.\n* @param fn - a function to test each element.\n*\n* @returns the index of the first element in the array that passes the test. Otherwise, \"-1\".\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction useArrayFindIndex(list, fn) {\n\treturn computed(() => toValue(list).findIndex((element, index, array) => fn(toValue(element), index, array)));\n}\n\n//#endregion\n//#region useArrayFindLast/index.ts\nfunction findLast(arr, cb) {\n\tlet index = arr.length;\n\twhile (index-- > 0) if (cb(arr[index], index, arr)) return arr[index];\n}\n/**\n* Reactive `Array.findLast`\n*\n* @see https://vueuse.org/useArrayFindLast\n* @param list - the array was called upon.\n* @param fn - a function to test each element.\n*\n* @returns the last element in the array that satisfies the provided testing function. Otherwise, undefined is returned.\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction useArrayFindLast(list, fn) {\n\treturn computed(() => toValue(!Array.prototype.findLast ? findLast(toValue(list), (element, index, array) => fn(toValue(element), index, array)) : toValue(list).findLast((element, index, array) => fn(toValue(element), index, array))));\n}\n\n//#endregion\n//#region useArrayIncludes/index.ts\nfunction isArrayIncludesOptions(obj) {\n\treturn isObject(obj) && containsProp(obj, \"formIndex\", \"comparator\");\n}\n/**\n* Reactive `Array.includes`\n*\n* @see https://vueuse.org/useArrayIncludes\n*\n* @returns true if the `value` is found in the array. Otherwise, false.\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction useArrayIncludes(...args) {\n\tvar _comparator;\n\tconst list = args[0];\n\tconst value = args[1];\n\tlet comparator = args[2];\n\tlet formIndex = 0;\n\tif (isArrayIncludesOptions(comparator)) {\n\t\tvar _comparator$fromIndex;\n\t\tformIndex = (_comparator$fromIndex = comparator.fromIndex) !== null && _comparator$fromIndex !== void 0 ? _comparator$fromIndex : 0;\n\t\tcomparator = comparator.comparator;\n\t}\n\tif (typeof comparator === \"string\") {\n\t\tconst key = comparator;\n\t\tcomparator = (element, value$1) => element[key] === toValue(value$1);\n\t}\n\tcomparator = (_comparator = comparator) !== null && _comparator !== void 0 ? _comparator : ((element, value$1) => element === toValue(value$1));\n\treturn computed(() => toValue(list).slice(formIndex).some((element, index, array) => comparator(toValue(element), toValue(value), index, toValue(array))));\n}\n\n//#endregion\n//#region useArrayJoin/index.ts\n/**\n* Reactive `Array.join`\n*\n* @see https://vueuse.org/useArrayJoin\n* @param list - the array was called upon.\n* @param separator - a string to separate each pair of adjacent elements of the array. If omitted, the array elements are separated with a comma (\",\").\n*\n* @returns a string with all array elements joined. If arr.length is 0, the empty string is returned.\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction useArrayJoin(list, separator) {\n\treturn computed(() => toValue(list).map((i) => toValue(i)).join(toValue(separator)));\n}\n\n//#endregion\n//#region useArrayMap/index.ts\n/**\n* Reactive `Array.map`\n*\n* @see https://vueuse.org/useArrayMap\n* @param list - the array was called upon.\n* @param fn - a function that is called for every element of the given `list`. Each time `fn` executes, the returned value is added to the new array.\n*\n* @returns a new array with each element being the result of the callback function.\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction useArrayMap(list, fn) {\n\treturn computed(() => toValue(list).map((i) => toValue(i)).map(fn));\n}\n\n//#endregion\n//#region useArrayReduce/index.ts\n/**\n* Reactive `Array.reduce`\n*\n* @see https://vueuse.org/useArrayReduce\n* @param list - the array was called upon.\n* @param reducer - a \"reducer\" function.\n* @param args\n*\n* @returns the value that results from running the \"reducer\" callback function to completion over the entire array.\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction useArrayReduce(list, reducer, ...args) {\n\tconst reduceCallback = (sum, value, index) => reducer(toValue(sum), toValue(value), index);\n\treturn computed(() => {\n\t\tconst resolved = toValue(list);\n\t\treturn args.length ? resolved.reduce(reduceCallback, typeof args[0] === \"function\" ? toValue(args[0]()) : toValue(args[0])) : resolved.reduce(reduceCallback);\n\t});\n}\n\n//#endregion\n//#region useArraySome/index.ts\n/**\n* Reactive `Array.some`\n*\n* @see https://vueuse.org/useArraySome\n* @param list - the array was called upon.\n* @param fn - a function to test each element.\n*\n* @returns **true** if the `fn` function returns a **truthy** value for any element from the array. Otherwise, **false**.\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction useArraySome(list, fn) {\n\treturn computed(() => toValue(list).some((element, index, array) => fn(toValue(element), index, array)));\n}\n\n//#endregion\n//#region useArrayUnique/index.ts\nfunction uniq(array) {\n\treturn Array.from(new Set(array));\n}\nfunction uniqueElementsBy(array, fn) {\n\treturn array.reduce((acc, v) => {\n\t\tif (!acc.some((x) => fn(v, x, array))) acc.push(v);\n\t\treturn acc;\n\t}, []);\n}\n/**\n* reactive unique array\n* @see https://vueuse.org/useArrayUnique\n* @param list - the array was called upon.\n* @param compareFn\n* @returns A computed ref that returns a unique array of items.\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction useArrayUnique(list, compareFn) {\n\treturn computed(() => {\n\t\tconst resolvedList = toValue(list).map((element) => toValue(element));\n\t\treturn compareFn ? uniqueElementsBy(resolvedList, compareFn) : uniq(resolvedList);\n\t});\n}\n\n//#endregion\n//#region useCounter/index.ts\n/**\n* Basic counter with utility functions.\n*\n* @see https://vueuse.org/useCounter\n* @param [initialValue]\n* @param options\n*/\nfunction useCounter(initialValue = 0, options = {}) {\n\tlet _initialValue = unref(initialValue);\n\tconst count = shallowRef(initialValue);\n\tconst { max = Number.POSITIVE_INFINITY, min = Number.NEGATIVE_INFINITY } = options;\n\tconst inc = (delta = 1) => count.value = Math.max(Math.min(max, count.value + delta), min);\n\tconst dec = (delta = 1) => count.value = Math.min(Math.max(min, count.value - delta), max);\n\tconst get$1 = () => count.value;\n\tconst set$1 = (val) => count.value = Math.max(min, Math.min(max, val));\n\tconst reset = (val = _initialValue) => {\n\t\t_initialValue = val;\n\t\treturn set$1(val);\n\t};\n\treturn {\n\t\tcount: shallowReadonly(count),\n\t\tinc,\n\t\tdec,\n\t\tget: get$1,\n\t\tset: set$1,\n\t\treset\n\t};\n}\n\n//#endregion\n//#region useDateFormat/index.ts\nconst REGEX_PARSE = /^(\\d{4})[-/]?(\\d{1,2})?[-/]?(\\d{0,2})[T\\s]*(\\d{1,2})?:?(\\d{1,2})?:?(\\d{1,2})?[.:]?(\\d+)?$/i;\nconst REGEX_FORMAT = /[YMDHhms]o|\\[([^\\]]+)\\]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a{1,2}|A{1,2}|m{1,2}|s{1,2}|Z{1,2}|z{1,4}|SSS/g;\nfunction defaultMeridiem(hours, minutes, isLowercase, hasPeriod) {\n\tlet m = hours < 12 ? \"AM\" : \"PM\";\n\tif (hasPeriod) m = m.split(\"\").reduce((acc, curr) => acc += `${curr}.`, \"\");\n\treturn isLowercase ? m.toLowerCase() : m;\n}\nfunction formatOrdinal(num) {\n\tconst suffixes = [\n\t\t\"th\",\n\t\t\"st\",\n\t\t\"nd\",\n\t\t\"rd\"\n\t];\n\tconst v = num % 100;\n\treturn num + (suffixes[(v - 20) % 10] || suffixes[v] || suffixes[0]);\n}\nfunction formatDate(date, formatStr, options = {}) {\n\tvar _options$customMeridi;\n\tconst years = date.getFullYear();\n\tconst month = date.getMonth();\n\tconst days = date.getDate();\n\tconst hours = date.getHours();\n\tconst minutes = date.getMinutes();\n\tconst seconds = date.getSeconds();\n\tconst milliseconds = date.getMilliseconds();\n\tconst day = date.getDay();\n\tconst meridiem = (_options$customMeridi = options.customMeridiem) !== null && _options$customMeridi !== void 0 ? _options$customMeridi : defaultMeridiem;\n\tconst stripTimeZone = (dateString) => {\n\t\tvar _dateString$split$;\n\t\treturn (_dateString$split$ = dateString.split(\" \")[1]) !== null && _dateString$split$ !== void 0 ? _dateString$split$ : \"\";\n\t};\n\tconst matches = {\n\t\tYo: () => formatOrdinal(years),\n\t\tYY: () => String(years).slice(-2),\n\t\tYYYY: () => years,\n\t\tM: () => month + 1,\n\t\tMo: () => formatOrdinal(month + 1),\n\t\tMM: () => `${month + 1}`.padStart(2, \"0\"),\n\t\tMMM: () => date.toLocaleDateString(toValue(options.locales), { month: \"short\" }),\n\t\tMMMM: () => date.toLocaleDateString(toValue(options.locales), { month: \"long\" }),\n\t\tD: () => String(days),\n\t\tDo: () => formatOrdinal(days),\n\t\tDD: () => `${days}`.padStart(2, \"0\"),\n\t\tH: () => String(hours),\n\t\tHo: () => formatOrdinal(hours),\n\t\tHH: () => `${hours}`.padStart(2, \"0\"),\n\t\th: () => `${hours % 12 || 12}`.padStart(1, \"0\"),\n\t\tho: () => formatOrdinal(hours % 12 || 12),\n\t\thh: () => `${hours % 12 || 12}`.padStart(2, \"0\"),\n\t\tm: () => String(minutes),\n\t\tmo: () => formatOrdinal(minutes),\n\t\tmm: () => `${minutes}`.padStart(2, \"0\"),\n\t\ts: () => String(seconds),\n\t\tso: () => formatOrdinal(seconds),\n\t\tss: () => `${seconds}`.padStart(2, \"0\"),\n\t\tSSS: () => `${milliseconds}`.padStart(3, \"0\"),\n\t\td: () => day,\n\t\tdd: () => date.toLocaleDateString(toValue(options.locales), { weekday: \"narrow\" }),\n\t\tddd: () => date.toLocaleDateString(toValue(options.locales), { weekday: \"short\" }),\n\t\tdddd: () => date.toLocaleDateString(toValue(options.locales), { weekday: \"long\" }),\n\t\tA: () => meridiem(hours, minutes),\n\t\tAA: () => meridiem(hours, minutes, false, true),\n\t\ta: () => meridiem(hours, minutes, true),\n\t\taa: () => meridiem(hours, minutes, true, true),\n\t\tz: () => stripTimeZone(date.toLocaleDateString(toValue(options.locales), { timeZoneName: \"shortOffset\" })),\n\t\tzz: () => stripTimeZone(date.toLocaleDateString(toValue(options.locales), { timeZoneName: \"shortOffset\" })),\n\t\tzzz: () => stripTimeZone(date.toLocaleDateString(toValue(options.locales), { timeZoneName: \"shortOffset\" })),\n\t\tzzzz: () => stripTimeZone(date.toLocaleDateString(toValue(options.locales), { timeZoneName: \"longOffset\" }))\n\t};\n\treturn formatStr.replace(REGEX_FORMAT, (match, $1) => {\n\t\tvar _ref, _matches$match;\n\t\treturn (_ref = $1 !== null && $1 !== void 0 ? $1 : (_matches$match = matches[match]) === null || _matches$match === void 0 ? void 0 : _matches$match.call(matches)) !== null && _ref !== void 0 ? _ref : match;\n\t});\n}\nfunction normalizeDate(date) {\n\tif (date === null) return /* @__PURE__ */ new Date(NaN);\n\tif (date === void 0) return /* @__PURE__ */ new Date();\n\tif (date instanceof Date) return new Date(date);\n\tif (typeof date === \"string\" && !/Z$/i.test(date)) {\n\t\tconst d = date.match(REGEX_PARSE);\n\t\tif (d) {\n\t\t\tconst m = d[2] - 1 || 0;\n\t\t\tconst ms = (d[7] || \"0\").substring(0, 3);\n\t\t\treturn new Date(d[1], m, d[3] || 1, d[4] || 0, d[5] || 0, d[6] || 0, ms);\n\t\t}\n\t}\n\treturn new Date(date);\n}\n/**\n* Get the formatted date according to the string of tokens passed in.\n*\n* @see https://vueuse.org/useDateFormat\n* @param date - The date to format, can either be a `Date` object, a timestamp, or a string\n* @param formatStr - The combination of tokens to format the date\n* @param options - UseDateFormatOptions\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction useDateFormat(date, formatStr = \"HH:mm:ss\", options = {}) {\n\treturn computed(() => formatDate(normalizeDate(toValue(date)), toValue(formatStr), options));\n}\n\n//#endregion\n//#region useIntervalFn/index.ts\n/**\n* Wrapper for `setInterval` with controls\n*\n* @see https://vueuse.org/useIntervalFn\n* @param cb\n* @param interval\n* @param options\n*/\nfunction useIntervalFn(cb, interval = 1e3, options = {}) {\n\tconst { immediate = true, immediateCallback = false } = options;\n\tlet timer = null;\n\tconst isActive = shallowRef(false);\n\tfunction clean() {\n\t\tif (timer) {\n\t\t\tclearInterval(timer);\n\t\t\ttimer = null;\n\t\t}\n\t}\n\tfunction pause() {\n\t\tisActive.value = false;\n\t\tclean();\n\t}\n\tfunction resume() {\n\t\tconst intervalValue = toValue(interval);\n\t\tif (intervalValue <= 0) return;\n\t\tisActive.value = true;\n\t\tif (immediateCallback) cb();\n\t\tclean();\n\t\tif (isActive.value) timer = setInterval(cb, intervalValue);\n\t}\n\tif (immediate && isClient) resume();\n\tif (isRef(interval) || typeof interval === \"function\") tryOnScopeDispose(watch(interval, () => {\n\t\tif (isActive.value && isClient) resume();\n\t}));\n\ttryOnScopeDispose(pause);\n\treturn {\n\t\tisActive: shallowReadonly(isActive),\n\t\tpause,\n\t\tresume\n\t};\n}\n\n//#endregion\n//#region useInterval/index.ts\nfunction useInterval(interval = 1e3, options = {}) {\n\tconst { controls: exposeControls = false, immediate = true, callback } = options;\n\tconst counter = shallowRef(0);\n\tconst update = () => counter.value += 1;\n\tconst reset = () => {\n\t\tcounter.value = 0;\n\t};\n\tconst controls = useIntervalFn(callback ? () => {\n\t\tupdate();\n\t\tcallback(counter.value);\n\t} : update, interval, { immediate });\n\tif (exposeControls) return {\n\t\tcounter: shallowReadonly(counter),\n\t\treset,\n\t\t...controls\n\t};\n\telse return shallowReadonly(counter);\n}\n\n//#endregion\n//#region useLastChanged/index.ts\nfunction useLastChanged(source, options = {}) {\n\tvar _options$initialValue;\n\tconst ms = shallowRef((_options$initialValue = options.initialValue) !== null && _options$initialValue !== void 0 ? _options$initialValue : null);\n\twatch(source, () => ms.value = timestamp(), options);\n\treturn shallowReadonly(ms);\n}\n\n//#endregion\n//#region useTimeoutFn/index.ts\n/**\n* Wrapper for `setTimeout` with controls.\n*\n* @param cb\n* @param interval\n* @param options\n*/\nfunction useTimeoutFn(cb, interval, options = {}) {\n\tconst { immediate = true, immediateCallback = false } = options;\n\tconst isPending = shallowRef(false);\n\tlet timer;\n\tfunction clear() {\n\t\tif (timer) {\n\t\t\tclearTimeout(timer);\n\t\t\ttimer = void 0;\n\t\t}\n\t}\n\tfunction stop() {\n\t\tisPending.value = false;\n\t\tclear();\n\t}\n\tfunction start(...args) {\n\t\tif (immediateCallback) cb();\n\t\tclear();\n\t\tisPending.value = true;\n\t\ttimer = setTimeout(() => {\n\t\t\tisPending.value = false;\n\t\t\ttimer = void 0;\n\t\t\tcb(...args);\n\t\t}, toValue(interval));\n\t}\n\tif (immediate) {\n\t\tisPending.value = true;\n\t\tif (isClient) start();\n\t}\n\ttryOnScopeDispose(stop);\n\treturn {\n\t\tisPending: shallowReadonly(isPending),\n\t\tstart,\n\t\tstop\n\t};\n}\n\n//#endregion\n//#region useTimeout/index.ts\nfunction useTimeout(interval = 1e3, options = {}) {\n\tconst { controls: exposeControls = false, callback } = options;\n\tconst controls = useTimeoutFn(callback !== null && callback !== void 0 ? callback : noop, interval, options);\n\tconst ready = computed(() => !controls.isPending.value);\n\tif (exposeControls) return {\n\t\tready,\n\t\t...controls\n\t};\n\telse return ready;\n}\n\n//#endregion\n//#region useToNumber/index.ts\n/**\n* Reactively convert a string ref to number.\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction useToNumber(value, options = {}) {\n\tconst { method = \"parseFloat\", radix, nanToZero } = options;\n\treturn computed(() => {\n\t\tlet resolved = toValue(value);\n\t\tif (typeof method === \"function\") resolved = method(resolved);\n\t\telse if (typeof resolved === \"string\") resolved = Number[method](resolved, radix);\n\t\tif (nanToZero && Number.isNaN(resolved)) resolved = 0;\n\t\treturn resolved;\n\t});\n}\n\n//#endregion\n//#region useToString/index.ts\n/**\n* Reactively convert a ref to string.\n*\n* @see https://vueuse.org/useToString\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction useToString(value) {\n\treturn computed(() => `${toValue(value)}`);\n}\n\n//#endregion\n//#region useToggle/index.ts\n/**\n* A boolean ref with a toggler\n*\n* @see https://vueuse.org/useToggle\n* @param [initialValue]\n* @param options\n*\n* @__NO_SIDE_EFFECTS__\n*/\nfunction useToggle(initialValue = false, options = {}) {\n\tconst { truthyValue = true, falsyValue = false } = options;\n\tconst valueIsRef = isRef(initialValue);\n\tconst _value = shallowRef(initialValue);\n\tfunction toggle(value) {\n\t\tif (arguments.length) {\n\t\t\t_value.value = value;\n\t\t\treturn _value.value;\n\t\t} else {\n\t\t\tconst truthy = toValue(truthyValue);\n\t\t\t_value.value = _value.value === truthy ? toValue(falsyValue) : truthy;\n\t\t\treturn _value.value;\n\t\t}\n\t}\n\tif (valueIsRef) return toggle;\n\telse return [_value, toggle];\n}\n\n//#endregion\n//#region watchArray/index.ts\n/**\n* Watch for an array with additions and removals.\n*\n* @see https://vueuse.org/watchArray\n*/\nfunction watchArray(source, cb, options) {\n\tlet oldList = (options === null || options === void 0 ? void 0 : options.immediate) ? [] : [...typeof source === \"function\" ? source() : Array.isArray(source) ? source : toValue(source)];\n\treturn watch(source, (newList, _, onCleanup) => {\n\t\tconst oldListRemains = Array.from({ length: oldList.length });\n\t\tconst added = [];\n\t\tfor (const obj of newList) {\n\t\t\tlet found = false;\n\t\t\tfor (let i = 0; i < oldList.length; i++) if (!oldListRemains[i] && obj === oldList[i]) {\n\t\t\t\toldListRemains[i] = true;\n\t\t\t\tfound = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!found) added.push(obj);\n\t\t}\n\t\tconst removed = oldList.filter((_$1, i) => !oldListRemains[i]);\n\t\tcb(newList, oldList, added, removed, onCleanup);\n\t\toldList = [...newList];\n\t}, options);\n}\n\n//#endregion\n//#region watchAtMost/index.ts\nfunction watchAtMost(source, cb, options) {\n\tconst { count,...watchOptions } = options;\n\tconst current = shallowRef(0);\n\tconst { stop, resume, pause } = watchWithFilter(source, (...args) => {\n\t\tcurrent.value += 1;\n\t\tif (current.value >= toValue(count)) nextTick(() => stop());\n\t\tcb(...args);\n\t}, watchOptions);\n\treturn {\n\t\tcount: current,\n\t\tstop,\n\t\tresume,\n\t\tpause\n\t};\n}\n\n//#endregion\n//#region watchDebounced/index.ts\nfunction watchDebounced(source, cb, options = {}) {\n\tconst { debounce = 0, maxWait = void 0,...watchOptions } = options;\n\treturn watchWithFilter(source, cb, {\n\t\t...watchOptions,\n\t\teventFilter: debounceFilter(debounce, { maxWait })\n\t});\n}\n/** @deprecated use `watchDebounced` instead */\nconst debouncedWatch = watchDebounced;\n\n//#endregion\n//#region watchDeep/index.ts\n/**\n* Shorthand for watching value with {deep: true}\n*\n* @see https://vueuse.org/watchDeep\n*/\nfunction watchDeep(source, cb, options) {\n\treturn watch(source, cb, {\n\t\t...options,\n\t\tdeep: true\n\t});\n}\n\n//#endregion\n//#region watchIgnorable/index.ts\nfunction watchIgnorable(source, cb, options = {}) {\n\tconst { eventFilter = bypassFilter,...watchOptions } = options;\n\tconst filteredCb = createFilterWrapper(eventFilter, cb);\n\tlet ignoreUpdates;\n\tlet ignorePrevAsyncUpdates;\n\tlet stop;\n\tif (watchOptions.flush === \"sync\") {\n\t\tlet ignore = false;\n\t\tignorePrevAsyncUpdates = () => {};\n\t\tignoreUpdates = (updater) => {\n\t\t\tignore = true;\n\t\t\tupdater();\n\t\t\tignore = false;\n\t\t};\n\t\tstop = watch(source, (...args) => {\n\t\t\tif (!ignore) filteredCb(...args);\n\t\t}, watchOptions);\n\t} else {\n\t\tconst disposables = [];\n\t\tlet ignoreCounter = 0;\n\t\tlet syncCounter = 0;\n\t\tignorePrevAsyncUpdates = () => {\n\t\t\tignoreCounter = syncCounter;\n\t\t};\n\t\tdisposables.push(watch(source, () => {\n\t\t\tsyncCounter++;\n\t\t}, {\n\t\t\t...watchOptions,\n\t\t\tflush: \"sync\"\n\t\t}));\n\t\tignoreUpdates = (updater) => {\n\t\t\tconst syncCounterPrev = syncCounter;\n\t\t\tupdater();\n\t\t\tignoreCounter += syncCounter - syncCounterPrev;\n\t\t};\n\t\tdisposables.push(watch(source, (...args) => {\n\t\t\tconst ignore = ignoreCounter > 0 && ignoreCounter === syncCounter;\n\t\t\tignoreCounter = 0;\n\t\t\tsyncCounter = 0;\n\t\t\tif (ignore) return;\n\t\t\tfilteredCb(...args);\n\t\t}, watchOptions));\n\t\tstop = () => {\n\t\t\tdisposables.forEach((fn) => fn());\n\t\t};\n\t}\n\treturn {\n\t\tstop,\n\t\tignoreUpdates,\n\t\tignorePrevAsyncUpdates\n\t};\n}\n/** @deprecated use `watchIgnorable` instead */\nconst ignorableWatch = watchIgnorable;\n\n//#endregion\n//#region watchImmediate/index.ts\n/**\n* Shorthand for watching value with {immediate: true}\n*\n* @see https://vueuse.org/watchImmediate\n*/\nfunction watchImmediate(source, cb, options) {\n\treturn watch(source, cb, {\n\t\t...options,\n\t\timmediate: true\n\t});\n}\n\n//#endregion\n//#region watchOnce/index.ts\n/**\n* Shorthand for watching value with { once: true }\n*\n* @see https://vueuse.org/watchOnce\n*/\nfunction watchOnce(source, cb, options) {\n\treturn watch(source, cb, {\n\t\t...options,\n\t\tonce: true\n\t});\n}\n\n//#endregion\n//#region watchThrottled/index.ts\nfunction watchThrottled(source, cb, options = {}) {\n\tconst { throttle = 0, trailing = true, leading = true,...watchOptions } = options;\n\treturn watchWithFilter(source, cb, {\n\t\t...watchOptions,\n\t\teventFilter: throttleFilter(throttle, trailing, leading)\n\t});\n}\n/** @deprecated use `watchThrottled` instead */\nconst throttledWatch = watchThrottled;\n\n//#endregion\n//#region watchTriggerable/index.ts\nfunction watchTriggerable(source, cb, options = {}) {\n\tlet cleanupFn;\n\tfunction onEffect() {\n\t\tif (!cleanupFn) return;\n\t\tconst fn = cleanupFn;\n\t\tcleanupFn = void 0;\n\t\tfn();\n\t}\n\t/** Register the function `cleanupFn` */\n\tfunction onCleanup(callback) {\n\t\tcleanupFn = callback;\n\t}\n\tconst _cb = (value, oldValue) => {\n\t\tonEffect();\n\t\treturn cb(value, oldValue, onCleanup);\n\t};\n\tconst res = watchIgnorable(source, _cb, options);\n\tconst { ignoreUpdates } = res;\n\tconst trigger = () => {\n\t\tlet res$1;\n\t\tignoreUpdates(() => {\n\t\t\tres$1 = _cb(getWatchSources(source), getOldValue(source));\n\t\t});\n\t\treturn res$1;\n\t};\n\treturn {\n\t\t...res,\n\t\ttrigger\n\t};\n}\nfunction getWatchSources(sources) {\n\tif (isReactive(sources)) return sources;\n\tif (Array.isArray(sources)) return sources.map((item) => toValue(item));\n\treturn toValue(sources);\n}\nfunction getOldValue(source) {\n\treturn Array.isArray(source) ? source.map(() => void 0) : void 0;\n}\n\n//#endregion\n//#region whenever/index.ts\n/**\n* Shorthand for watching value to be truthy\n*\n* @see https://vueuse.org/whenever\n*/\nfunction whenever(source, cb, options) {\n\tconst stop = watch(source, (v, ov, onInvalidate) => {\n\t\tif (v) {\n\t\t\tif (options === null || options === void 0 ? void 0 : options.once) nextTick(() => stop());\n\t\t\tcb(v, ov, onInvalidate);\n\t\t}\n\t}, {\n\t\t...options,\n\t\tonce: false\n\t});\n\treturn stop;\n}\n\n//#endregion\nexport { assert, autoResetRef, bypassFilter, camelize, clamp, computedEager, computedWithControl, containsProp, controlledComputed, controlledRef, createEventHook, createFilterWrapper, createGlobalState, createInjectionState, createReactiveFn, createRef, createSharedComposable, createSingletonPromise, debounceFilter, debouncedRef, debouncedWatch, eagerComputed, extendRef, formatDate, get, getLifeCycleTarget, hasOwn, hyphenate, identity, ignorableWatch, increaseWithUnit, injectLocal, invoke, isClient, isDef, isDefined, isIOS, isObject, isWorker, makeDestructurable, noop, normalizeDate, notNullish, now, objectEntries, objectOmit, objectPick, pausableFilter, pausableWatch, promiseTimeout, provideLocal, pxValue, rand, reactify, reactifyObject, reactiveComputed, reactiveOmit, reactivePick, refAutoReset, refDebounced, refDefault, refManualReset, refThrottled, refWithControl, set, syncRef, syncRefs, throttleFilter, throttledRef, throttledWatch, timestamp, toArray, toReactive, toRef, toRefs, tryOnBeforeMount, tryOnBeforeUnmount, tryOnMounted, tryOnScopeDispose, tryOnUnmounted, until, useArrayDifference, useArrayEvery, useArrayFilter, useArrayFind, useArrayFindIndex, useArrayFindLast, useArrayIncludes, useArrayJoin, useArrayMap, useArrayReduce, useArraySome, useArrayUnique, useCounter, useDateFormat, useDebounce, useDebounceFn, useInterval, useIntervalFn, useLastChanged, useThrottle, useThrottleFn, useTimeout, useTimeoutFn, useToNumber, useToString, useToggle, watchArray, watchAtMost, watchDebounced, watchDeep, watchIgnorable, watchImmediate, watchOnce, watchPausable, watchThrottled, watchTriggerable, watchWithFilter, whenever };","import { notNullish } from \"@vueuse/shared\";\nimport { computed, shallowRef, toValue, watch } from \"vue\";\nimport { toArray, tryOnScopeDispose as tryOnScopeDispose$1, unrefElement } from \"@vueuse/core\";\nimport { createFocusTrap } from \"focus-trap\";\n\n//#region useFocusTrap/index.ts\n/**\n* Reactive focus-trap\n*\n* @see https://vueuse.org/useFocusTrap\n*/\nfunction useFocusTrap(target, options = {}) {\n\tlet trap;\n\tconst { immediate,...focusTrapOptions } = options;\n\tconst hasFocus = shallowRef(false);\n\tconst isPaused = shallowRef(false);\n\tconst activate = (opts) => trap && trap.activate(opts);\n\tconst deactivate = (opts) => trap && trap.deactivate(opts);\n\tconst pause = () => {\n\t\tif (trap) {\n\t\t\ttrap.pause();\n\t\t\tisPaused.value = true;\n\t\t}\n\t};\n\tconst unpause = () => {\n\t\tif (trap) {\n\t\t\ttrap.unpause();\n\t\t\tisPaused.value = false;\n\t\t}\n\t};\n\twatch(computed(() => {\n\t\treturn toArray(toValue(target)).map((el) => {\n\t\t\tconst _el = toValue(el);\n\t\t\treturn typeof _el === \"string\" ? _el : unrefElement(_el);\n\t\t}).filter(notNullish);\n\t}), (els) => {\n\t\tif (!els.length) return;\n\t\tif (!trap) {\n\t\t\ttrap = createFocusTrap(els, {\n\t\t\t\t...focusTrapOptions,\n\t\t\t\tonActivate() {\n\t\t\t\t\thasFocus.value = true;\n\t\t\t\t\tif (options.onActivate) options.onActivate();\n\t\t\t\t},\n\t\t\t\tonDeactivate() {\n\t\t\t\t\thasFocus.value = false;\n\t\t\t\t\tif (options.onDeactivate) options.onDeactivate();\n\t\t\t\t}\n\t\t\t});\n\t\t\tif (immediate) activate();\n\t\t} else {\n\t\t\tconst isActive = trap === null || trap === void 0 ? void 0 : trap.active;\n\t\t\ttrap === null || trap === void 0 || trap.updateContainerElements(els);\n\t\t\tif (!isActive && immediate) activate();\n\t\t}\n\t}, { flush: \"post\" });\n\ttryOnScopeDispose$1(() => deactivate());\n\treturn {\n\t\thasFocus,\n\t\tisPaused,\n\t\tactivate,\n\t\tdeactivate,\n\t\tpause,\n\t\tunpause\n\t};\n}\n\n//#endregion\nexport { useFocusTrap as t };","import { nextTick, Ref, ref, watch } from \"vue\";\nimport { useFocusTrap } from \"@vueuse/integrations/useFocusTrap\";\n\nexport function useOverlayFocus(\n element: Ref<HTMLElement | null>,\n isTop: Ref<boolean>,\n clickOutsideDeactivates = false,\n) {\n const unpausing = ref(false);\n\n const { activate, deactivate, pause, unpause } = useFocusTrap(element, {\n immediate: true,\n clickOutsideDeactivates,\n initialFocus: () => {\n if (unpausing.value) {\n return false;\n }\n const focus = element.value?.querySelector(\"[popover-focus]\");\n if (focus) {\n return focus as HTMLElement;\n }\n const h2 = element.value?.querySelector(\"h2\");\n if (h2) {\n return h2 as HTMLElement;\n }\n const selected = element.value?.querySelector(\n \"[aria-selected='true']\",\n );\n if (selected) {\n return selected as HTMLElement;\n }\n },\n onPostPause: () => (unpausing.value = true),\n onPostUnpause: () => {\n nextTick(() => {\n unpausing.value = false;\n }).catch((err) => {\n console.error(err);\n });\n },\n });\n\n watch(isTop, (top) => {\n if (top) {\n // If the overlay is open immediately on mount, this can\n // fail if we don't wait for the next tick because there are no\n // focusable elements yet.\n nextTick(() => {\n unpause();\n }).catch((err) => {\n console.error(err);\n });\n } else {\n pause();\n }\n });\n\n return { activate, deactivate, pause, unpause };\n}\n","import { nextTick, onBeforeUnmount, onMounted, Ref } from \"vue\";\n\nexport function useOverlayEscape(\n containers: Ref<Element | null>[],\n isTop: Ref<boolean>,\n open: Ref<boolean>,\n hide: () => void,\n pop: () => void,\n) {\n function onDocumentClick(e: MouseEvent) {\n for (const ref of containers) {\n if (ref.value?.contains(e.target as Node)) {\n return;\n }\n }\n hide();\n }\n\n function onDocumentKeydown(e: KeyboardEvent) {\n if (e.key === \"Escape\" && open.value) {\n if (isTop.value) {\n e.preventDefault();\n nextTick(hide).catch((err) => {\n console.error(err);\n })\n }\n }\n }\n\n onMounted(() => {\n document.addEventListener(\"mousedown\", onDocumentClick);\n document.addEventListener(\"keydown\", onDocumentKeydown);\n });\n onBeforeUnmount(() => {\n document.removeEventListener(\"mousedown\", onDocumentClick);\n document.removeEventListener(\"keydown\", onDocumentKeydown);\n pop();\n });\n}\n","/**\n * Calculates the position for a popover based on the anchor element's position,\n * the popover's dimensions, and the viewport dimensions.\n *\n * @param anchorRect\n * @param popoverRect\n * @param viewportRect\n * @param options Optional config: { gap?: number, margin?: number }\n */\nexport function calculatePopoverPosition(\n anchorRect: DOMRect,\n popoverRect: DOMRect,\n viewportRect: DOMRect,\n options?: { gap?: number; margin?: number; preferAbove?: boolean },\n): { top: number; left: number; xOffset: number; placedAbove: boolean; overlay: boolean } {\n const gap = options?.gap ?? 8;\n const margin = options?.margin ?? 16;\n const preferAbove = options?.preferAbove ?? false;\n\n // Prefer below, but go above if not enough space\n let placedAbove = false;\n let overlay = false;\n let top: number;\n if (preferAbove) {\n if (anchorRect.top - popoverRect.height - gap > viewportRect.top + margin) {\n // Place above\n top = anchorRect.top - popoverRect.height - gap;\n placedAbove = true;\n } else if (anchorRect.bottom + popoverRect.height + gap <= viewportRect.bottom - margin) {\n // Place below if not enough room above\n top = anchorRect.bottom + gap;\n } else {\n // Not enough room above or below, overlay on anchor, margin from top\n top = viewportRect.top + margin;\n overlay = true;\n }\n } else {\n if (\n anchorRect.bottom + popoverRect.height + gap > viewportRect.bottom - margin &&\n anchorRect.top - popoverRect.height - gap > viewportRect.top + margin\n ) {\n // Place above\n top = anchorRect.top - popoverRect.height - gap;\n placedAbove = true;\n } else if (\n anchorRect.bottom + popoverRect.height + gap > viewportRect.bottom - margin &&\n anchorRect.top - popoverRect.height - gap <= viewportRect.top + margin\n ) {\n // Not enough room above or below, overlay on anchor, margin from top\n top = viewportRect.top + margin;\n overlay = true;\n } else {\n // Place below\n top = anchorRect.bottom + gap;\n }\n }\n\n // Center horizontally by default\n let left = anchorRect.left + (anchorRect.width - popoverRect.width) / 2;\n // Clamp to viewport\n if (left < viewportRect.left + margin) {\n left = viewportRect.left + margin;\n }\n if (left + popoverRect.width > viewportRect.right - margin) {\n left = viewportRect.right - popoverRect.width - margin;\n }\n // Final safety clamp (if popover is wider than viewport)\n if (left < viewportRect.left + margin) {\n left = viewportRect.left + margin;\n }\n\n // Calculate X offset from centered position (for arrow)\n const centeredLeft = anchorRect.left + (anchorRect.width - popoverRect.width) / 2;\n const xOffset = left - centeredLeft;\n\n return { top, left, xOffset, placedAbove, overlay };\n}\n","<script setup lang=\"ts\">\n/**\n * Popover that appears next to or over a trigger element, staying visible\n * in the viewport as much as possible.\n *\n * **Slot** `trigger` must have an interactive element for which\n * the only interaction is to open the popover. The trigger element is also used\n * for `aria-labelledby`. The trigger is passed a prop `toggle` which is a function\n * that toggles the popover's open state.\n *\n * **Slot** `default` is the content of the popover.\n *\n * Example:\n *\n * ```vue-html\n * <GPopover>\n * <template #trigger=\"{ toggle }\">\n * <GButton @click=\"toggle\">\n * Can Popovers' Popovers have Popovers?\n * </GButton>\n * </template>\n * <div>Even if they can, should they?</div>\n * </GPopover>\n * ```\n */\n\nimport {\n nextTick,\n onBeforeUnmount,\n ref,\n useId,\n useTemplateRef,\n watch,\n} from \"vue\";\nimport { useOverlayStack } from \"../compose/useOverlayStack.ts\";\nimport { useOverlayFocus } from \"../compose/useOverlayFocus.ts\";\nimport { useOverlayEscape } from \"../compose/useOverlayEscape.ts\";\nimport { calculatePopoverPosition } from \"../compose/popoverPosition.ts\";\n\ninterface Props {\n /**\n * Render without padding\n */\n minimal?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n minimal: false,\n});\nconst emit = defineEmits([\"show\", \"hide\"]);\nconst open = defineModel<boolean>({ default: false });\n\nconst triggerRef = useTemplateRef<HTMLElement | null>(\"triggerRef\");\nconst popoverRef = useTemplateRef<HTMLElement | null>(\"popoverRef\");\n\nconst id = useId();\nconst { push, pop, isTop, zIndex } = useOverlayStack(id, true);\nconst { activate, deactivate } = useOverlayFocus(popoverRef, isTop, true);\nuseOverlayEscape([popoverRef, triggerRef], isTop, open, hide, pop);\n\nwatch(open, (val) => {\n if (val) {\n nextTick(() => {\n nextTick(() => activate());\n });\n push();\n emit(\"show\");\n } else {\n deactivate();\n pop();\n emit(\"hide\");\n }\n});\n\nfunction show() {\n open.value = true;\n}\n\nfunction hide() {\n open.value = false;\n}\n\nfunction toggle() {\n open.value = !open.value;\n}\n\nconst popoverPosition = ref<Record<string, any>>({ top: 0, left: 0 });\nconst arrowPosition = ref<Record<string, any>>({ left: \"50%\" });\nconst popoverAbove = ref(false);\nconst popoverOverlay = ref(false);\nlet resizeObserver: ResizeObserver | null = null;\n\nfunction updatePopoverPosition() {\n if (!triggerRef.value || !popoverRef.value) {\n return;\n }\n const triggerRect = triggerRef.value.getBoundingClientRect();\n const popoverRect = popoverRef.value.getBoundingClientRect();\n // Account for possible vertical scrollbar reducing viewport width\n const scrollbarWidth =\n window.innerWidth - document.documentElement.clientWidth;\n const viewportWidth = window.innerWidth - scrollbarWidth;\n const viewportRect = new DOMRect(0, 0, viewportWidth, window.innerHeight);\n\n const { top, left, xOffset, placedAbove, overlay } =\n calculatePopoverPosition(triggerRect, popoverRect, viewportRect, {\n gap: props.minimal ? 0 : 8,\n });\n popoverPosition.value = { top, left };\n arrowPosition.value = {\n left: `${popoverRect.width / 2 - xOffset}px`,\n top: placedAbove ? \"auto\" : undefined,\n bottom: placedAbove ? \"-8px\" : undefined,\n };\n popoverAbove.value = placedAbove;\n popoverOverlay.value = overlay;\n}\n\nwatch(open, (val) => {\n if (val) {\n nextTick(() => {\n updatePopoverPosition();\n window.addEventListener(\"resize\", updatePopoverPosition);\n if (popoverRef.value) {\n if (resizeObserver) {\n resizeObserver.disconnect();\n }\n resizeObserver = new ResizeObserver(() =>\n updatePopoverPosition(),\n );\n resizeObserver.observe(popoverRef.value);\n }\n });\n } else {\n window.removeEventListener(\"resize\", updatePopoverPosition);\n if (resizeObserver) {\n resizeObserver.disconnect();\n }\n }\n});\n\nonBeforeUnmount(() => {\n window.removeEventListener(\"resize\", updatePopoverPosition);\n if (resizeObserver) {\n resizeObserver.disconnect();\n }\n});\n\n</script>\n\n<template>\n <div class=\"g-popover-wrap\">\n <div ref=\"triggerRef\" class=\"g-popover-trigger\" :id=\"`${id}-trigger`\">\n <slot name=\"trigger\" :toggle=\"toggle\"></slot>\n </div>\n <Teleport to=\"#modal-root\">\n <transition name=\"g-popover-expand\" appear>\n <div\n v-if=\"open\"\n ref=\"popoverRef\"\n :class=\"{\n 'g-popover': true,\n 'g-popover-above': popoverAbove,\n 'g-popover-below': !popoverAbove,\n 'g-popover-minimal': minimal,\n }\"\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-labelledby=\"`${id}-trigger`\"\n :style=\"{\n top: popoverPosition.top + 'px',\n left: popoverPosition.left + 'px',\n zIndex,\n }\"\n >\n <div\n v-if=\"!popoverOverlay && !minimal\"\n class=\"g-popover-arrow\"\n :class=\"{ 'g-popover-arrow-above': popoverAbove }\"\n :style=\"arrowPosition\"\n aria-hidden=\"true\"\n ></div>\n <slot></slot>\n <button\n v-if=\"!minimal\"\n class=\"g-popover-close\"\n type=\"button\"\n aria-label=\"Close popover\"\n @click=\"hide\"\n >\n <svg\n class=\"g-popover-close-icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 51.26 51.26\"\n aria-hidden=\"true\"\n >\n <path\n fill=\"currentColor\"\n d=\"m37.84 32.94-7.63-7.63 7.63-7.63a3.24 3.24 0 0 0-4.58-4.58l-7.63 7.63L18 13.1a3.24 3.24 0 0 0-4.58 4.58L21 25.31l-7.62 7.63A3.24 3.24 0 1 0 18 37.52l7.63-7.63 7.63 7.63a3.24 3.24 0 0 0 4.58-4.58Z\"\n />\n </svg>\n </button>\n </div>\n </transition>\n </Teleport>\n </div>\n</template>\n\n<style>\n.g-popover {\n h2 {\n font-size: 1.25rem;\n margin: 0 0 0.75rem 0;\n }\n p {\n margin: 0 0 0.5rem 0;\n }\n}\n.g-popover-trigger {\n display: inline-block;\n}\n</style>\n\n<style scoped>\n.g-popover {\n position: fixed;\n z-index: 1000;\n background: var(--g-surface-0);\n border: 1px solid var(--g-surface-200);\n color: var(--g-surface-900);\n font-weight: normal;\n font-size: 1rem;\n border-radius: 4px;\n box-shadow: var(--il-shadow);\n padding: 1.5rem 1rem 1rem;\n min-width: 200px;\n max-width: 500px;\n top: 0;\n left: 0;\n text-align: left;\n}\n.g-popover.g-popover-minimal {\n padding: 0;\n min-width: 0;\n}\n\n.g-popover-arrow {\n box-sizing: border-box;\n position: absolute;\n top: -8px;\n width: 20px;\n height: 8px;\n left: 50%;\n transform: translateX(-50%);\n pointer-events: none;\n z-index: 1;\n}\n\n.g-popover-arrow::after {\n box-sizing: border-box;\n content: \"\";\n display: block;\n margin: 0 auto;\n width: 16px;\n height: 8px;\n background: transparent;\n border-left: 8px solid transparent;\n border-right: 8px solid transparent;\n border-bottom: 8px solid white;\n /* Add border for the arrow */\n position: relative;\n z-index: 2;\n}\n\n.g-popover-arrow::before {\n box-sizing: border-box;\n content: \"\";\n display: block;\n position: absolute;\n top: -1px;\n left: 1px;\n width: 18px;\n height: 9px;\n border-left: 8px solid transparent;\n border-right: 8px solid transparent;\n border-bottom: 8px solid var(--g-surface-200, #ccc);\n z-index: 1;\n}\n\n.g-popover-arrow-above {\n transform: translateX(-50%) rotate(180deg);\n}\n.g-popover-close {\n position: absolute;\n display: block;\n top: 1px;\n right: 1px;\n border: none;\n padding: 0.25rem 0.25rem;\n border-radius: 7px;\n background: transparent;\n cursor: pointer;\n\n &:hover {\n background: var(--g-primary-500);\n color: var(--g-surface-0);\n }\n &:focus-visible {\n background: var(--ilw-color--focus--background);\n color: var(--ilw-color--focus--text);\n }\n\n .g-popover-close-icon {\n width: 1.25rem;\n height: 1.25rem;\n }\n}\n\n.g-popover-expand-enter-active,\n.g-popover-expand-leave-active {\n transition:\n opacity 0.18s cubic-bezier(0.4, 0, 0.2, 1),\n transform 0.18s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.g-popover-expand-enter-from,\n.g-popover-expand-leave-to {\n opacity: 0;\n transform: scale(0.95);\n}\n\n.g-popover-expand-enter-to,\n.g-popover-expand-leave-from {\n opacity: 1;\n transform: scale(1);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .g-popover-expand-enter-active,\n .g-popover-expand-leave-active {\n transition: none !important;\n }\n}\n</style>\n","<script setup lang=\"ts\">\n/**\n * This component is just a radio button group with special styling.\n *\n * Use the `options` prop to provide a list of choices. Each option can\n * be a string or an object with `label` and `value` properties.\n *\n * In addition to `v-model`, a `change` event is emitted when the\n * option changes from user interaction.\n */\nimport { computed, useId, toRef } from \"vue\";\nimport { useFormField } from \"../compose/useFormField.ts\";\nimport GFormErrorMessages from \"./form/GFormErrorMessages.vue\";\n\ninterface OptionType {\n label: string;\n value: string | number;\n}\n\ninterface Props {\n options: Array<string | OptionType>;\n /**\n * Accessible label\n */\n label: string; // Demo: Select Option\n /**\n * Size\n */\n size?: \"small\" | \"medium\" | \"large\";\n // Name for form registration\n name?: string;\n /**\n * Disabled\n */\n disabled?: boolean;\n\n // Error messages array (supports multiple validation errors)\n errors?: string[];\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n size: \"medium\",\n name: undefined,\n disabled: false,\n errors: () => [],\n});\n\nconst emit = defineEmits([\"change\"]);\nconst model = defineModel<string | number>({default: () => \"\"});\n\nconst baseId = useId();\n\n// Use form field composable for form registration and error handling\nconst { displayErrors, hasErrors } = useFormField({\n name: props.name,\n value: model,\n errors: toRef(props, 'errors'),\n});\n\nconst normalizedOptions = computed(() => {\n return props.options.map((opt) => {\n if (typeof opt === \"string\") {\n return { label: opt, value: opt };\n } else {\n return opt;\n }\n });\n});\n\nconst groupClasses = computed(() => [\n \"g-select-btn-group\",\n `g-select-btn-group--${props.size}`,\n]);\n\nconst getBtnClasses = (selected: boolean) => [\n \"g-select-btn\",\n selected ? \"g-select-btn--selected\" : \"\",\n { \"g-select-btn--disabled\": props.disabled },\n];\n\nfunction onChange(val: string | number) {\n if (!props.disabled && val !== model.value) {\n model.value = val;\n emit(\"change\", val);\n }\n}\n</script>\n\n<template>\n <fieldset :class=\"groupClasses\" :disabled=\"props.disabled\">\n <legend class=\"g-select-btn-legend\">{{ props.label }}</legend>\n <div class=\"g-select-btn-wrapper\" :class=\"{ 'g-select-btn-has-error': hasErrors }\">\n <div class=\"g-select-btn-row\">\n <template\n v-for=\"(option, idx) in normalizedOptions\"\n :key=\"option.value\"\n >\n <input\n class=\"g-select-btn-radio\"\n type=\"radio\"\n :id=\"`${baseId}-${option.value}`\"\n :name=\"props.name || baseId\"\n :value=\"option.value\"\n :checked=\"option.value === model\"\n :disabled=\"props.disabled\"\n @change=\"onChange(option.value)\"\n />\n <label\n :for=\"`${baseId}-${option.value}`\"\n :class=\"getBtnClasses(option.value === model)\"\n >\n {{ option.label }}\n </label>\n </template>\n </div>\n <GFormErrorMessages\n :errors=\"displayErrors\"\n :id=\"'error-message-' + baseId\"\n />\n </div>\n </fieldset>\n</template>\n\n<style scoped>\n.g-select-btn-group {\n border: none;\n margin: 0;\n padding: 0;\n min-width: 0;\n border-radius: 4px;\n}\n\n.g-select-btn-legend {\n position: static;\n display: block;\n margin: 0 0 0.5rem 0;\n padding: 0;\n font-weight: 700;\n color: var(--g-surface-900);\n}\n\n.g-select-btn-row {\n display: flex;\n align-items: stretch;\n border-radius: var(--g-border-radius-m);\n}\n\n.g-select-btn-row:has(:focus-visible) {\n outline: 2px solid var(--g-primary-500);\n outline-offset: 2px;\n background: var(--ilw-color--focus--background);\n box-shadow: 0 0 0 2px var(--ilw-color--focus--background);\n}\n\n.g-select-btn-group--small {\n font-size: 0.875rem;\n}\n\n.g-select-btn-group--medium {\n font-size: 1rem;\n}\n\n.g-select-btn-group--large {\n font-size: 1.125rem;\n}\n\n.g-select-btn-radio {\n position: absolute;\n opacity: 0;\n pointer-events: none;\n width: 0;\n height: 0;\n margin: 0;\n}\n\n.g-select-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 2px solid var(--g-primary-500);\n border-left-width: 1px;\n border-right-width: 1px;\n background: var(--g-surface-0);\n color: var(--g-primary-500);\n font-weight: 700;\n padding: 0.5em;\n cursor: pointer;\n outline: none;\n &:hover {\n text-decoration: underline;\n }\n}\n.g-select-btn--selected {\n background: var(--g-primary-500);\n color: var(--g-surface-0);\n}\n.g-select-btn:first-of-type {\n border-top-left-radius: var(--g-border-radius-m);\n border-bottom-left-radius: var(--g-border-radius-m);\n border-left-width: 2px;\n}\n.g-select-btn:last-of-type {\n border-top-right-radius: var(--g-border-radius-m);\n border-bottom-right-radius: var(--g-border-radius-m);\n border-right-width: 2px;\n}\n\n.g-select-btn-has-error .g-select-btn-row {\n border: 2px solid var(--g-danger-600);\n border-radius: var(--g-border-radius-m);\n}\n\n.g-select-btn-has-error .g-select-btn {\n background: var(--g-danger-100);\n}\n</style>\n","<script setup lang=\"ts\">\n/**\n * A component that can show progress from 1 to 100 or an indeterminate spinner.\n * If a value is omitted, the progress will be indeterminate.\n *\n * If no `label` is specified, the default accessible label will be \"Loading\".\n *\n * If a value is provided, the element will have the ARIA role `progressbar`\n * with the appropriate ARIA value attributes.\n *\n * If no value is provided, the element will have the ARIA role `status`.\n *\n * > [!NOTE]\n * > This element announces to assistive technologies, so make sure to\n * > limit its use to cases where that's appropriate.\n */\nimport { computed } from \"vue\";\n\ntype Props = {\n /**\n * Accessible label\n */\n label?: string;\n /**\n * Progress 1-100 or blank\n */\n value?: number;\n /**\n * Progress circle size\n */\n size?: \"tiny\" | \"small\" | \"medium\" | \"large\";\n};\n\nconst props = withDefaults(defineProps<Props>(), {\n size: \"medium\",\n value: undefined,\n label: \"Loading\",\n});\n\nconst isDeterminate = computed(\n () =>\n props.value &&\n props.value >= 1 &&\n props.value <= 100,\n);\nconst radius = computed(() => {\n switch (props.size) {\n case \"tiny\":\n return 9;\n case \"small\":\n return 12;\n case \"large\":\n return 24;\n default:\n return 18;\n }\n});\nconst stroke = 4;\nconst circumference = computed(() => 2 * Math.PI * radius.value);\nconst progress = computed(() =>\n isDeterminate.value ? (props.value! / 100) * circumference.value : 0,\n);\n\nconst ariaProps = computed(() =>\n isDeterminate.value\n ? {\n role: \"progressbar\",\n \"aria-valuenow\": props.value,\n \"aria-valuemin\": 1,\n \"aria-valuemax\": 100,\n \"aria-label\": props.label,\n }\n : {\n \"role\": \"status\",\n \"aria-label\": props.label },\n);\n</script>\n\n<template>\n <span class=\"g-progress\" v-bind=\"ariaProps\">\n <svg\n :width=\"radius * 2 + stroke\"\n :height=\"radius * 2 + stroke\"\n :class=\"[\n 'g-progress__svg',\n {\n 'g-progress--determinate': isDeterminate,\n 'g-progress--indeterminate': !isDeterminate,\n },\n ]\"\n focusable=\"false\"\n aria-hidden=\"true\"\n >\n <circle\n class=\"g-progress__track\"\n :cx=\"radius + stroke / 2\"\n :cy=\"radius + stroke / 2\"\n :r=\"radius\"\n :stroke-width=\"stroke\"\n fill=\"none\"\n />\n <circle\n v-if=\"isDeterminate\"\n class=\"g-progress__value\"\n :cx=\"radius + stroke / 2\"\n :cy=\"radius + stroke / 2\"\n :r=\"radius\"\n :stroke-width=\"stroke\"\n fill=\"none\"\n :stroke-dasharray=\"circumference\"\n :stroke-dashoffset=\"circumference - progress\"\n style=\"transform: rotate(-90deg); transform-origin: center\"\n />\n <circle\n v-else\n class=\"g-progress__spinner\"\n :cx=\"radius + stroke / 2\"\n :cy=\"radius + stroke / 2\"\n :r=\"radius\"\n :stroke-width=\"stroke\"\n fill=\"none\"\n />\n </svg>\n </span>\n</template>\n\n<style scoped>\n.g-progress {\n display: inline-block;\n vertical-align: middle;\n}\n\n.g-progress__svg {\n display: block;\n}\n.g-progress__track {\n stroke: var(--g-surface-200);\n}\n.g-progress__value {\n stroke: var(--g-primary-500);\n transition: stroke-dashoffset 0.2s linear;\n}\n.g-progress__spinner {\n animation: g-progress-spin 1s linear infinite;\n transform-box: fill-box;\n transform-origin: center;\n}\n.g-progress__spinner {\n stroke: var(--g-primary-500);\n stroke-dasharray: 40 80;\n}\n@media (prefers-reduced-motion: reduce) {\n .g-progress__spinner {\n animation: g-progress-spin-blink 1s both infinite;\n }\n}\n@keyframes g-progress-spin {\n 100% {\n transform: rotate(360deg);\n }\n}\n@keyframes g-progress-spin-blink {\n 0%,\n 100% {\n opacity: 0;\n }\n 50% {\n opacity: 1;\n }\n}\n</style>\n","<script setup lang=\"ts\">\n/**\n * Alert dialog for confirming or canceling actions.\n *\n * Clicking on the outside or pressing the escape key will close the dialog\n * and that counts as canceling.\n *\n * > [!IMPORTANT]\n * >\n * > The surrounding page **must** have an element with the id `modal-root`,\n * > this dialog will be teleported to it, so it can properly be over all\n * > other content. The `modal-root` should be somewhere near the end of the\n * > page structure.\n *\n * **Slot** `default` is used as the content of the alert, and also becomes\n * the ARIA description of the alert.\n */\n\nimport { onBeforeMount, onMounted, ref, useId } from \"vue\";\nimport { useOverlayStack } from \"../compose/useOverlayStack.ts\";\nimport { useOverlayFocus } from \"../compose/useOverlayFocus.ts\";\nimport { useOverlayEscape } from \"../compose/useOverlayEscape.ts\";\nimport GButton from \"./GButton.vue\";\n\ninterface Props {\n /**\n * Dialog label\n */\n label?: string;\n /**\n * Accept button text\n */\n buttonText?: string;\n /**\n * Accept button color\n */\n buttonColor?: \"primary\" | \"secondary\" | \"danger\";\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n label: \"Confirmation\",\n buttonText: \"Continue\",\n buttonColor: \"primary\",\n});\n\nconst emit = defineEmits([\"cancel\", \"confirm\"]);\n\nconst dialog = ref<HTMLElement | null>(null);\nconst open = ref(true);\n\nconst id = useId();\nconst { pop, push, isTop, zIndex } = useOverlayStack(id, true, true);\n\nconst { deactivate, activate } = useOverlayFocus(dialog, isTop);\n\nfunction close() {\n emit(\"cancel\");\n}\n\nuseOverlayEscape([dialog], isTop, open, close, pop);\n\nonMounted(() => {\n push();\n activate();\n});\n\nonBeforeMount(() => {\n pop();\n deactivate();\n});\n</script>\n\n<template>\n <Teleport to=\"#modal-root\">\n <Transition name=\"g-fade\" appear>\n <div\n :id=\"'alertdialog-' + id\"\n class=\"g-alertdialog\"\n role=\"alertdialog\"\n aria-modal=\"true\"\n :aria-labelledby=\"'alertdialog-label-' + id\"\n :aria-describedby=\"'alertdialog-description-' + id\"\n ref=\"dialog\"\n :style=\"{ zIndex }\"\n >\n <div class=\"g-alertdialog-inner\">\n <h2\n :id=\"'alertdialog-label-' + id\"\n class=\"g-alertdialog-label\"\n >\n {{ props.label }}\n </h2>\n <div\n :id=\"'alertdialog-description-' + id\"\n class=\"g-alertdialog-content\"\n >\n <slot />\n </div>\n <div class=\"g-alertdialog-actions\">\n <GButton outlined @click=\"emit('cancel')\"\n >Cancel</GButton\n >\n <GButton\n :theme=\"props.buttonColor\"\n @click=\"emit('confirm')\"\n >{{ props.buttonText }}</GButton\n >\n </div>\n </div>\n </div>\n </Transition>\n </Teleport>\n</template>\n\n<style scoped>\n.g-alertdialog {\n position: fixed;\n left: 50vw;\n top: 50vh;\n transform: translate(-50%, -50%);\n max-width: 400px;\n min-width: 300px;\n height: auto;\n max-height: 90vh;\n overflow-y: auto;\n background: var(--g-surface-50);\n border-top: 8px solid var(--g-accent-500);\n padding: 2rem;\n box-shadow:\n 0 0 2px rgba(0, 0, 0, 0.4),\n 0 10px 20px rgba(0, 0, 0, 0.1);\n}\n.g-alertdialog-label {\n font-family: var(--il-font-heading);\n font-size: 2rem;\n margin-top: 0;\n color: var(--g-primary-500);\n}\n.g-alertdialog-content {\n margin-top: 1rem;\n font-size: 1.125rem;\n color: var(--g-surface-900);\n}\n.g-alertdialog-actions {\n margin-top: 2rem;\n display: flex;\n justify-content: flex-end;\n gap: 1rem;\n}\n\n.fade-enter-active,\n.fade-leave-active {\n transition: opacity 0.2s ease;\n}\n\n.fade-enter-from,\n.fade-leave-to {\n opacity: 0;\n}\n</style>\n","<script setup lang=\"ts\">\n/**\n * By default, this component behaves like a normal select element with\n * custom styling.\n *\n * The component can be marked `searchable` to enable search functionality.\n * This turns it into a text input that filters the options. Filtering is\n * done with a simple lower-case string search.\n *\n * The `options` prop can be an array of strings or objects with `label`\n * and `value` properties.\n */\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref, useId, watch, toRef } from \"vue\";\nimport { useOverlayStack } from \"../compose/useOverlayStack.ts\";\nimport { useFormField } from \"../compose/useFormField.ts\";\nimport GFormErrorMessages from \"./form/GFormErrorMessages.vue\";\n\ninterface OptionType {\n label: string;\n value: string | number;\n}\n\ninterface Props {\n // List of options to choose from\n options: Array<string | OptionType>;\n /**\n * Accessible label\n */\n label: string; // Demo: Select Option\n /**\n * Hide the label visually\n */\n hiddenLabel?: boolean;\n /**\n * Placeholder\n *\n * Only used if the component is searchable.\n */\n placeholder?: string;\n /**\n * Disabled\n */\n disabled?: boolean;\n\n // Name for form registration\n name?: string;\n /**\n * Searchable\n */\n searchable?: boolean;\n /**\n * Show clear button\n */\n clearButton?: boolean;\n /**\n * Compact\n */\n compact?: boolean;\n\n // Error messages array (supports multiple validation errors)\n errors?: string[];\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n disabled: false,\n name: undefined,\n searchable: false,\n compact: false,\n errors: () => [],\n});\nconst emit = defineEmits([\"change\"]);\nconst model = defineModel<string | number | null>();\n\nconst baseId = useId();\nconst comboRef = ref<HTMLElement | null>(null);\nconst listboxRef = ref<HTMLElement | null>(null);\nconst open = ref(false);\nconst activeIndex = ref(0);\nconst ignoreBlur = ref(false);\nconst ignoreFocus = ref(false);\nconst { push, pop, isTop } = useOverlayStack(baseId);\n\n// Use form field composable for form registration and error handling\nconst { displayErrors, hasErrors } = useFormField({\n name: props.name,\n value: model,\n errors: toRef(props, 'errors'),\n});\n\nconst menuPlacement = ref<\"below\" | \"above\">(\"below\");\nconst menuMaxHeight = ref<number | null>(null);\n\nconst menuStyle = computed(() => {\n const style: Record<string, string> = {};\n if (menuMaxHeight.value !== null) {\n style.maxHeight = `${menuMaxHeight.value}px`;\n }\n if (menuPlacement.value === \"above\") {\n style.top = \"auto\";\n style.bottom = \"100%\";\n } else {\n style.top = \"100%\";\n style.bottom = \"auto\";\n }\n return style;\n});\n\nfunction updateMenuPlacement() {\n if (!open.value) {\n return;\n }\n if (!comboRef.value) {\n return;\n }\n\n const rect = comboRef.value.getBoundingClientRect();\n const spaceBelow = window.innerHeight - rect.bottom;\n const spaceAbove = rect.top;\n const listboxFullHeight = listboxRef.value?.scrollHeight ?? 200;\n const minSpaceToOpenBelow = Math.min(200, listboxFullHeight);\n const gap = 8;\n\n if (spaceBelow >= minSpaceToOpenBelow) {\n menuPlacement.value = \"below\";\n menuMaxHeight.value = Math.max(0, Math.floor(spaceBelow - gap));\n return;\n }\n\n if (spaceBelow < minSpaceToOpenBelow && spaceAbove > spaceBelow) {\n menuPlacement.value = \"above\";\n menuMaxHeight.value = Math.max(0, Math.floor(spaceAbove - gap));\n return;\n }\n\n menuPlacement.value = \"below\";\n menuMaxHeight.value = Math.max(0, Math.floor(spaceBelow - gap));\n}\n\nlet removeWindowListeners: (() => void) | null = null;\n\nfunction addWindowListeners() {\n if (removeWindowListeners) {\n return;\n }\n const onChange = () => {\n updateMenuPlacement();\n };\n window.addEventListener(\"resize\", onChange, { passive: true });\n window.addEventListener(\"scroll\", onChange, {\n passive: true,\n capture: true,\n });\n removeWindowListeners = () => {\n window.removeEventListener(\"resize\", onChange);\n window.removeEventListener(\"scroll\", onChange, true);\n removeWindowListeners = null;\n };\n}\n\nfunction removeListeners() {\n if (!removeWindowListeners) {\n return;\n }\n removeWindowListeners();\n}\n\nconst normalizedOptions = computed(() => {\n return props.options.map((opt) => {\n if (typeof opt === \"string\") {\n return { label: opt, value: opt };\n } else {\n return opt;\n }\n });\n});\n\nconst searchQuery = ref(\"\");\n\nconst filteredOptions = computed(() => {\n if (!props.searchable || !open.value || !searchQuery.value) {\n return normalizedOptions.value;\n }\n const q = searchQuery.value.toLowerCase();\n return normalizedOptions.value.filter((opt) =>\n opt.label.toLowerCase().includes(q),\n );\n});\n\nconst selectedIndex = computed(() => {\n return filteredOptions.value.findIndex((opt) => opt.value === model.value);\n});\n\nwatch(\n () => model.value,\n (val) => {\n const idx = filteredOptions.value.findIndex((opt) => opt.value === val);\n if (idx !== -1) {\n activeIndex.value = idx;\n }\n },\n);\n\n// Watch for open state to manage overlay stack\nwatch(open, (val) => {\n if (val) {\n push();\n } else {\n pop();\n }\n});\n\nwatch(open, (val) => {\n if (val) {\n addWindowListeners();\n nextTick(() => {\n updateMenuPlacement();\n });\n } else {\n removeListeners();\n menuPlacement.value = \"below\";\n menuMaxHeight.value = null;\n }\n});\n\nfunction openMenu() {\n if (props.disabled) {\n return;\n }\n open.value = true;\n nextTick(() => {\n updateMenuPlacement();\n });\n if (props.searchable) {\n searchQuery.value = \"\";\n // If a value is selected, highlight it in filtered list\n const idx = filteredOptions.value.findIndex(\n (opt) => opt.value === model.value,\n );\n activeIndex.value = idx !== -1 ? idx : 0;\n nextTick(() => {\n if (comboInputRef.value) {\n comboInputRef.value.focus();\n }\n });\n }\n}\n\nfunction closeMenu() {\n open.value = false;\n if (props.searchable) {\n searchQuery.value = \"\";\n }\n}\n\nonBeforeUnmount(() => {\n removeListeners();\n});\n\nconst comboInputRef = ref<HTMLInputElement | null>(null);\n\nfunction onComboFocus(e: FocusEvent) {\n if (props.disabled) {\n return;\n }\n if (props.searchable) {\n if (ignoreFocus.value) {\n ignoreFocus.value = false;\n return;\n }\n openMenu();\n }\n}\n\nfunction onComboInput(e: Event) {\n if (!props.searchable) return;\n // If closed and user types, open and start search\n if (!open.value) {\n openMenu();\n }\n searchQuery.value = (e.target as HTMLInputElement).value;\n // Always highlight the first filtered option, or selected if present\n const idx = filteredOptions.value.findIndex(\n (opt) => opt.value === model.value,\n );\n activeIndex.value = idx !== -1 ? idx : 0;\n}\n\nfunction onComboBlur(e: FocusEvent) {\n // Prevent closing if focus moves to the dropdown menu (e.g. scrollbar interaction)\n const relatedTarget = e.relatedTarget as HTMLElement | null;\n if (ignoreBlur.value) {\n ignoreBlur.value = false;\n return;\n }\n if (\n relatedTarget &&\n listboxRef.value &&\n listboxRef.value.contains(relatedTarget)\n ) {\n // Focus moved inside the dropdown, don't close\n return;\n }\n if (props.searchable) {\n searchQuery.value = \"\";\n }\n closeMenu();\n}\n\nfunction selectOption(idx: number) {\n const opt = filteredOptions.value[idx];\n if (opt && opt.value !== model.value) {\n model.value = opt.value;\n emit(\"change\", opt.value);\n }\n ignoreFocus.value = true;\n closeMenu();\n // We want to ignore the focus just briefly so it doesn't re-open\n setTimeout(() => {\n ignoreFocus.value = false;\n }, 100);\n}\n\nfunction onComboClick() {\n if (props.disabled) {\n return;\n }\n if (!open.value) {\n openMenu();\n } else {\n closeMenu();\n }\n}\n\nfunction onComboKeydown(e: KeyboardEvent) {\n if (props.disabled) {\n return;\n }\n const max = filteredOptions.value.length - 1;\n if (!open.value && [\"ArrowDown\", \"ArrowUp\", \"Enter\", \" \"].includes(e.key)) {\n e.preventDefault();\n openMenu();\n return;\n }\n switch (e.key) {\n case \"ArrowDown\":\n e.preventDefault();\n if (!open.value) {\n openMenu();\n } else {\n activeIndex.value = Math.min(max, activeIndex.value + 1);\n scrollOptionIntoView();\n }\n break;\n case \"ArrowUp\":\n e.preventDefault();\n if (!open.value) {\n openMenu();\n } else {\n activeIndex.value = Math.max(0, activeIndex.value - 1);\n scrollOptionIntoView();\n }\n break;\n case \"Home\":\n e.preventDefault();\n activeIndex.value = 0;\n scrollOptionIntoView();\n break;\n case \"End\":\n e.preventDefault();\n activeIndex.value = max;\n scrollOptionIntoView();\n break;\n case \"Enter\":\n case \" \":\n e.preventDefault();\n if (open.value) {\n selectOption(activeIndex.value);\n } else {\n openMenu();\n }\n break;\n case \"Escape\":\n if (isTop.value) {\n e.preventDefault();\n setTimeout(() => {\n closeMenu();\n }, 0);\n }\n break;\n }\n}\n\nfunction onOptionClick(idx: number) {\n selectOption(idx);\n}\n\nfunction onOptionMouseDown() {\n ignoreBlur.value = true;\n}\n\nfunction scrollOptionIntoView() {\n nextTick(() => {\n const el = document.getElementById(\n `${baseId}-option-${activeIndex.value}`,\n );\n if (el) {\n el.scrollIntoView({ block: \"nearest\" });\n }\n });\n}\n\nconst showClearButton = computed(() => {\n return (\n props.clearButton &&\n model.value !== null &&\n model.value !== undefined &&\n !props.disabled\n );\n});\n\nfunction clearValue() {\n if (!props.disabled) {\n model.value = null;\n emit(\"change\", null);\n if (props.searchable) {\n searchQuery.value = \"\";\n }\n }\n}\n\nonBeforeUnmount(() => {\n pop();\n});\n</script>\n\n<template>\n <div\n class=\"g-select-root g-select-combo\"\n :class=\"{ 'g-select-open': open, 'g-select-compact': compact, 'g-select-has-error': hasErrors }\"\n >\n <div\n v-if=\"!hiddenLabel\"\n :id=\"baseId + '-label'\"\n class=\"g-select-combo-label g-select-label\"\n >\n {{ props.label }}\n </div>\n <div class=\"g-select-input-wrap\">\n <div\n v-if=\"props.searchable\"\n class=\"g-select-combo-input g-select-control\"\n :id=\"baseId\"\n >\n <input\n ref=\"comboRef\"\n type=\"text\"\n name=\"comboInput\"\n class=\"g-select-search-input\"\n :class=\"{ 'g-select-clearable': clearButton }\"\n :value=\"\n open\n ? searchQuery\n : normalizedOptions[selectedIndex]\n ? normalizedOptions[selectedIndex].label\n : ''\n \"\n :placeholder=\"open ? '' : placeholder\"\n :disabled=\"props.disabled\"\n @focus=\"onComboFocus\"\n @input=\"onComboInput\"\n @keydown=\"onComboKeydown\"\n @blur=\"onComboBlur\"\n :aria-autocomplete=\"'list'\"\n :aria-controls=\"baseId + '-listbox'\"\n :aria-expanded=\"open ? 'true' : 'false'\"\n aria-haspopup=\"listbox\"\n :aria-activedescendant=\"\n open ? baseId + '-option-' + activeIndex : undefined\n \"\n v-bind=\"\n hiddenLabel\n ? { 'aria-label': props.label }\n : { 'aria-labelledby': baseId + '-label' }\n \"\n role=\"combobox\"\n autocomplete=\"off\"\n />\n <button\n v-if=\"showClearButton\"\n type=\"button\"\n class=\"g-select-clear-btn\"\n @click=\"clearValue\"\n >\n <svg\n role=\"img\"\n aria-label=\"Clear Selection\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 51.26 51.26\"\n width=\"1.125em\"\n >\n <path\n fill=\"currentColor\"\n d=\"m37.84 32.94-7.63-7.63 7.63-7.63a3.24 3.24 0 0 0-4.58-4.58l-7.63 7.63L18 13.1a3.24 3.24 0 0 0-4.58 4.58L21 25.31l-7.62 7.63A3.24 3.24 0 1 0 18 37.52l7.63-7.63 7.63 7.63a3.24 3.24 0 0 0 4.58-4.58Z\"\n />\n </svg>\n </button>\n\n <svg\n class=\"g-select-caret\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 51.26 51.26\"\n aria-hidden=\"true\"\n width=\"1.125em\"\n >\n <!--!Font Awesome Free v7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.-->\n <path\n fill=\"currentColor\"\n d=\"M38.75 24.13a1.36 1.36 0 0 1 0 2.36l-12.44 7.18-12.43 7.18a1.36 1.36 0 0 1-2.05-1.18V11a1.36 1.36 0 0 1 2.05-1.18L26.31 17Z\"\n />\n </svg>\n </div>\n <div\n v-else\n ref=\"comboRef\"\n :id=\"baseId\"\n class=\"g-select-combo-button g-select-control\"\n :class=\"{ 'g-select-clearable': clearButton }\"\n role=\"combobox\"\n :aria-controls=\"baseId + '-listbox'\"\n :aria-expanded=\"open ? 'true' : 'false'\"\n aria-haspopup=\"listbox\"\n v-bind=\"\n hiddenLabel\n ? { 'aria-label': props.label }\n : { 'aria-labelledby': baseId + '-label' }\n \"\n :aria-activedescendant=\"\n open ? baseId + '-option-' + activeIndex : undefined\n \"\n tabindex=\"0\"\n @click=\"onComboClick\"\n @keydown=\"onComboKeydown\"\n @focus=\"onComboFocus\"\n @blur=\"onComboBlur\"\n >\n {{\n normalizedOptions[selectedIndex]\n ? normalizedOptions[selectedIndex].label\n : \"\"\n }}\n <button\n v-if=\"showClearButton\"\n type=\"button\"\n class=\"g-select-clear-btn\"\n @click.stop=\"clearValue\"\n >\n <svg\n role=\"img\"\n aria-label=\"Clear Selection\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 51.26 51.26\"\n width=\"1.125em\"\n >\n <path\n fill=\"currentColor\"\n d=\"m37.84 32.94-7.63-7.63 7.63-7.63a3.24 3.24 0 0 0-4.58-4.58l-7.63 7.63L18 13.1a3.24 3.24 0 0 0-4.58 4.58L21 25.31l-7.62 7.63A3.24 3.24 0 1 0 18 37.52l7.63-7.63 7.63 7.63a3.24 3.24 0 0 0 4.58-4.58Z\"\n />\n </svg>\n </button>\n\n <svg\n class=\"g-select-caret\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 51.26 51.26\"\n aria-hidden=\"true\"\n width=\"1.125em\"\n >\n <!--!Font Awesome Free v7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.-->\n <path\n fill=\"currentColor\"\n d=\"M38.75 24.13a1.36 1.36 0 0 1 0 2.36l-12.44 7.18-12.43 7.18a1.36 1.36 0 0 1-2.05-1.18V11a1.36 1.36 0 0 1 2.05-1.18L26.31 17Z\"\n />\n </svg>\n </div>\n <div\n v-show=\"open\"\n ref=\"listboxRef\"\n class=\"g-select-combo-menu g-select-list\"\n :class=\"{\n 'g-select-combo-menu--above': menuPlacement === 'above',\n }\"\n :style=\"menuStyle\"\n role=\"listbox\"\n :id=\"baseId + '-listbox'\"\n v-bind=\"\n hiddenLabel\n ? { 'aria-label': props.label }\n : { 'aria-labelledby': baseId + '-label' }\n \"\n tabindex=\"-1\"\n >\n <template v-if=\"filteredOptions.length > 0\">\n <div\n v-for=\"(option, idx) in filteredOptions\"\n :key=\"option.value\"\n :id=\"baseId + '-option-' + idx\"\n class=\"g-select-combo-option g-select-option\"\n :class=\"{\n 'g-select-option-current': idx === activeIndex,\n 'ilw-theme-blue': option.value === model,\n }\"\n role=\"option\"\n :aria-selected=\"\n option.value === model ? 'true' : 'false'\n \"\n @mousedown=\"onOptionMouseDown\"\n @click=\"onOptionClick(idx)\"\n >\n <slot\n name=\"option\"\n :option=\"option\"\n :selected=\"option.value === model\"\n :index=\"idx\"\n >\n {{ option.label }}\n </slot>\n </div>\n </template>\n <template v-else>\n <div\n aria-live=\"polite\"\n class=\"g-select-combo-option g-select-option g-select-no-results\"\n >\n No results found.\n </div>\n </template>\n </div>\n </div>\n <GFormErrorMessages\n :errors=\"displayErrors\"\n :id=\"'error-message-' + baseId\"\n />\n </div>\n</template>\n\n<style scoped>\n.g-select-root {\n position: relative;\n font-size: 1rem;\n}\n\n.g-select-label {\n font-weight: 700;\n color: var(--g-surface-900);\n margin-bottom: 0.5em;\n}\n\n.g-select-input-wrap {\n position: relative;\n}\n\n.g-select-control {\n line-height: 1.5;\n cursor: pointer;\n background: var(--g-surface-0);\n color: var(--g-surface-900);\n border: 2px solid var(--g-primary-500);\n border-radius: var(--g-border-radius-m);\n text-align: left;\n position: relative;\n\n &:focus-visible {\n background: var(--g-info-200);\n color: var(--g-primary-500);\n }\n\n &:has(:focus-visible) {\n outline: 2px solid var(--g-primary-500);\n outline-offset: 1px;\n box-shadow: 0 0 0 2px var(--g-info-200);\n }\n\n &:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n}\n\n.g-select-combo-button {\n}\n\n.g-select-caret {\n position: absolute;\n right: 0.5em;\n line-height: 1.5em;\n top: calc(50% - 0.55em);\n color: var(--g-accent-700);\n pointer-events: none;\n\n transform: rotate(90deg);\n}\n\n.g-select-open .g-select-caret {\n transform: rotate(-90deg);\n}\n\n.g-select-combo-menu {\n background-color: var(--g-surface-0);\n border: 2px solid var(--g-surface-700);\n border-radius: 0 0 var(--g-border-radius-m) var(--g-border-radius-m);\n box-sizing: border-box;\n box-shadow:\n 0 4px 4px rgba(0, 0, 0, 0.2),\n 0 1px 0 1px rgba(0, 0, 0, 0.18);\n max-height: 50vh;\n overflow-y: auto;\n left: 0;\n position: absolute;\n top: 100%;\n width: 100%;\n z-index: 1000;\n display: none;\n}\n\n.g-select-combo-menu--above {\n border-radius: var(--g-border-radius-m) var(--g-border-radius-m) 0 0;\n}\n\n.g-select-open .g-select-combo-menu {\n display: block;\n}\n\n.g-select-combo-option {\n padding: 0.5em 0.5em;\n cursor: pointer;\n background: var(--g-surface-0);\n color: var(--g-surface-900);\n border: 2px solid transparent;\n\n &:hover {\n text-decoration: underline;\n color: var(--g-accent-700);\n border-color: var(--g-accent-700);\n }\n}\n\n.g-select-option-current {\n background: var(--g-primary-500);\n color: var(--g-primary-text);\n\n &:hover {\n color: var(--g-primary-text);\n }\n}\n\n.g-select-search-input {\n box-sizing: border-box;\n display: block;\n width: 100%;\n font-family: var(--il-font-sans);\n border: none;\n box-sizing: border-box;\n text-overflow: ellipsis;\n font-size: 1em;\n\n &.g-select-clearable {\n padding-right: 3.5em; /* Space for clear button */\n }\n}\n\n.g-select-search-input,\n.g-select-combo-button {\n padding: 0.25em 2em 0.25em 0.75em;\n line-height: 1.875em;\n box-sizing: border-box;\n}\n.g-select-combo-button {\n /* Padding + line height + padding + border */\n min-height: calc(0.25em + 1.875em + 0.25em + 4px);\n min-width: 8rem;\n}\n\n.g-select-compact {\n font-size: 0.875rem;\n}\n\n.g-select-search-input,\n.g-select-combo-button {\n &.g-select-clearable {\n padding-right: 3em; /* Space for clear button */\n }\n}\n\n.g-select-no-results {\n padding: 0.25em 1em;\n text-align: center;\n color: var(--g-surface-900);\n font-style: italic;\n}\n\n.g-select-clear-btn {\n position: absolute;\n right: 1.25em;\n top: calc(50% - 1.15em);\n background: none;\n border: none;\n color: var(--g-accent-700);\n font-size: 1.25em;\n cursor: pointer;\n padding: 0.6em 0.3em 0.4em;\n line-height: 1;\n\n &:hover {\n color: var(--g-accent-700);\n }\n &:focus {\n background: var(--g-info-200);\n color: var(--g-primary-500);\n }\n}\n\n.g-select-has-error .g-select-control {\n border-color: var(--g-danger-600);\n background: var(--g-danger-100);\n}\n</style>\n","<script\n setup\n lang=\"ts\"\n generic=\"\n T extends {\n id: string | number;\n title: string;\n }\n \"\n>\n/**\n * A combobox-style search that shows a list of results as an auto\n * complete dropdown.\n *\n * The component doesn't perform any real searching. It emits events\n * that can be used to trigger searches, and then the results are\n * passed back to the component.\n *\n * **Events**:\n *\n * - `submit` event is emitted when a search should be performed.\n * - `select` event is submitted when a user makes a selection\n * in the dropdown.\n *\n * > [!NOTE]\n * > The `v-model` value should *not* be used to trigger a search,\n * > but it can be used to get the current user input.\n *\n * **Props**:\n *\n * - `results` will be rendered in the dropdown. There are two options:\n * - Pass an array of objects that extend `{ id: string | number; title: string; }`.\n * - Pass an array of `GSearchGroup<T>` objects, where the `items` property extends the above type.\n * In this case the results are grouped.\n * - `auto` makes search submit on user input. Defaults to `true`.\n * if `false`, submission happens on Enter or clicking the search button.\n * - `loading` shows a loading indicator. Use if the search may take longer.\n *\n * **Slot**: `option` customizes how an option is rendered.\n * It receives the current item as `option`.\n *\n * **Slot**: `group` customizes the group label for each group.\n *\n * Here is a minimal implementation:\n *\n * ```vue\n * <script setup lang=\"ts\">\n * interface SearchResult {\n * id: string;\n * title: string;\n * }\n *\n * const searchData = ref<SearchResult[]>([\n * { id: \"1\", title: \"The Quick Fox\" },\n * { id: \"2\", title: \"The Lazy Dog\" },\n * { id: \"3\", title: \"The Brown Bear\" },\n * ]);\n * const searchResults = ref<SearchResult[]>([]);\n *\n * function submit(query: string) {\n * searchResults.value = searchData.value.filter((result) =>\n * result.title.toLowerCase().includes(query.toLowerCase()),\n * );\n * }\n * function selected(item: SearchResult) {\n * console.log(\"Selected:\", item);\n * }\n * </script>\n * <template>\n * <GSearch\n * :results=\"searchResults\"\n * @submit=\"submit\"\n * @select=\"selected\">\n * </GSearch>\n * </template>\n * ```\n */\nimport { computed, nextTick, ref, useId, watch } from \"vue\";\nimport { useDebounceFn, useFocusWithin } from \"@vueuse/core\";\nimport GProgress from \"./GProgress.vue\";\n\nexport interface GSearchGroup<R> {\n type: string;\n label: string;\n items: R[];\n}\n\ntype Props = {\n results: GSearchGroup<T>[] | T[];\n /**\n * Placeholder\n */\n placeholder?: string;\n /**\n * Accessible label\n */\n label?: string;\n /**\n * Automatic search\n */\n auto?: boolean;\n /**\n * Show search loading indicator\n */\n loading?: boolean;\n};\n\nconst modelValue = defineModel<string | null>({ default: () => \"\" });\n\nconst props = withDefaults(defineProps<Props>(), {\n placeholder: \"Search...\",\n label: \"Search\",\n auto: true\n});\nconst emit = defineEmits([\"select\", \"submit\"]);\n\nconst inputRef = ref<HTMLInputElement | null>(null);\nconst listboxRef = ref<HTMLDivElement | null>(null);\nconst closed = ref(true);\nconst activeIndex = ref<number>(-1);\nconst flatResults = computed(() => {\n if (\n Array.isArray(props.results) &&\n props.results.length &&\n \"items\" in props.results[0]\n ) {\n // Grouped results\n return (props.results as GSearchGroup<T>[]).flatMap((g) => g.items);\n } else {\n return props.results as T[];\n }\n});\nconst resultCount = computed(() => flatResults.value.length);\n\nfunction onInput(ev: Event) {\n const value = (ev.target as HTMLInputElement).value;\n modelValue.value = value;\n if (props.auto && value.length > 1) {\n closed.value = false;\n }\n}\n\nfunction scrollOptionIntoView() {\n nextTick(() => {\n const el = listboxRef.value?.querySelector('[aria-selected=\"true\"]');\n if (el) {\n el.scrollIntoView({ block: \"nearest\" });\n }\n });\n}\n\nconst { focused } = useFocusWithin(inputRef);\n\nfunction onKeydown(ev: KeyboardEvent) {\n const altKey = ev.altKey;\n if (ev.key === \"ArrowDown\") {\n if (!resultCount.value) {\n return;\n }\n ev.preventDefault();\n closed.value = false;\n if (!altKey) {\n activeIndex.value = (activeIndex.value + 1) % resultCount.value;\n scrollOptionIntoView();\n }\n } else if (ev.key === \"ArrowUp\") {\n if (!resultCount.value) {\n return;\n }\n ev.preventDefault();\n closed.value = false;\n activeIndex.value =\n (activeIndex.value - 1 + resultCount.value) % resultCount.value;\n scrollOptionIntoView();\n } else if (ev.key === \"Enter\") {\n if (closed.value) {\n // Don't debounce on enter\n emit(\"submit\", modelValue.value);\n closed.value = false;\n ev.preventDefault();\n } else {\n selectResult(flatResults.value[activeIndex.value]);\n }\n } else if (ev.key === \"Escape\") {\n if (!resultCount.value) {\n return;\n }\n ev.preventDefault();\n if (!expanded.value) {\n modelValue.value = \"\";\n }\n closed.value = true;\n activeIndex.value = -1;\n }\n\n if ([\"Backspace\", \"Delete\", \"Clear\", \"Undo\"].includes(ev.key)) {\n closed.value = true;\n }\n}\n\nfunction selectResult(result: T | null) {\n emit(\"select\", result);\n modelValue.value = \"\";\n closed.value = true;\n activeIndex.value = -1;\n}\n\nconst isLoading = computed(() => {\n return !!props.loading;\n});\n\nconst expanded = computed(() => {\n return focused.value && !closed.value;\n});\n\nconst submit = useDebounceFn(() => {\n emit(\"submit\", modelValue.value);\n}, 300);\n\nwatch(\n () => modelValue.value,\n (val) => {\n if (!val) {\n activeIndex.value = -1;\n } else if (props.auto) {\n // Auto-submit on input change with debounce\n submit();\n }\n },\n);\nconst id = useId();\n</script>\n\n<template>\n <div class=\"g-search\" role=\"search\" :aria-label=\"props.label\">\n <form class=\"g-search-form\" @submit.prevent=\"selectResult(null)\">\n <input\n ref=\"inputRef\"\n class=\"g-search-input\"\n name=\"search\"\n type=\"search\"\n :placeholder=\"props.placeholder\"\n :value=\"modelValue\"\n @input=\"onInput\"\n @keydown=\"onKeydown\"\n role=\"combobox\"\n :aria-expanded=\"expanded\"\n aria-autocomplete=\"list\"\n :aria-controls=\"`${id}-list`\"\n :aria-activedescendant=\"\n activeIndex >= 0\n ? 'g-search-option-' + flatResults[activeIndex].id\n : undefined\n \"\n />\n <button\n type=\"submit\"\n class=\"g-search-submit\"\n aria-label=\"Submit search\"\n @keydown=\"onKeydown\"\n >\n <template v-if=\"isLoading\">\n <GProgress size=\"tiny\" />\n </template>\n <svg\n role=\"img\"\n aria-label=\"Search\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 51.26 51.26\"\n >\n <path\n fill=\"currentColor\"\n d=\"M30 9.76A14.05 14.05 0 1 0 28.3 31l11.3 13a3.34 3.34 0 0 0 4.72-4.72L31.44 27.86A14.05 14.05 0 0 0 30 9.76ZM27.27 27a10.26 10.26 0 1 1 0-14.5 10.25 10.25 0 0 1 0 14.5Z\"\n />\n </svg>\n </button>\n </form>\n <div v-if=\"expanded\" class=\"g-search-dropdown\">\n <div aria-live=\"polite\" class=\"g-search-result-count\">\n <template v-if=\"!isLoading\">\n {{ resultCount }} result{{\n resultCount === 1 ? \"\" : \"s\"\n }}</template\n >\n </div>\n <div\n role=\"listbox\"\n :id=\"`${id}-list`\"\n ref=\"listboxRef\"\n aria-label=\"Search results\"\n >\n <template v-if=\"resultCount > 0 && 'items' in props.results[0]\">\n <template\n v-for=\"(\n group, gIdx\n ) in props.results as GSearchGroup<T>[]\"\n :key=\"group.type\"\n >\n <div\n class=\"g-search-group\"\n role=\"group\"\n :aria-label=\"group.label\"\n >\n <slot name=\"group\" :group=\"group\">\n <div class=\"g-search-group-label\">\n {{ group.label }}\n </div>\n </slot>\n <div\n v-for=\"(item, idx) in group.items\"\n :key=\"item.id\"\n :id=\"'g-search-option-' + item.id\"\n class=\"g-search-option\"\n :class=\"{\n 'g-search-option-active':\n flatResults[activeIndex] &&\n flatResults[activeIndex].id === item.id,\n }\"\n role=\"option\"\n @mousedown.prevent=\"selectResult(item)\"\n :aria-selected=\"\n flatResults[activeIndex] &&\n flatResults[activeIndex].id === item.id\n \"\n >\n <slot name=\"option\" :option=\"item\">\n {{ item.title }}\n </slot>\n </div>\n </div>\n </template>\n </template>\n <template v-else-if=\"resultCount > 0\">\n <div\n v-for=\"(item, idx) in flatResults\"\n :key=\"item.id\"\n :id=\"'g-search-option-' + item.id\"\n class=\"g-search-option\"\n :class=\"{\n 'g-search-option-active': activeIndex === idx,\n }\"\n role=\"option\"\n @mousedown.prevent=\"selectResult(item)\"\n :aria-selected=\"activeIndex === idx\"\n >\n <slot name=\"option\" :option=\"item\">\n {{ item.title }}\n </slot>\n </div>\n </template>\n </div>\n </div>\n </div>\n</template>\n\n<style>\n.g-search {\n position: relative;\n min-width: 200px;\n width: 100%;\n}\n\n.g-search-form {\n display: flex;\n align-items: stretch;\n}\n\n.g-search-input {\n width: 100%;\n padding: 0.5rem 1rem;\n line-height: 1.33rem;\n font-size: 1rem;\n background: var(--g-surface-0);\n color: var(--g-surface-900);\n border: 2px solid var(--g-primary-500);\n border-right-width: 1px;\n border-top-left-radius: var(--g-border-radius-m);\n border-bottom-left-radius: var(--g-border-radius-m);\n &:focus {\n outline: 2px solid var(--g-primary-500);\n outline-offset: 2px;\n box-shadow: 0 0 0 2px var(--g-info-200);\n }\n}\n\n.g-search-submit {\n box-sizing: border-box;\n background: var(--g-surface-0);\n color: var(--g-accent-700);\n border: 2px solid var(--g-primary-500);\n border-left-width: 1px;\n border-top-right-radius: var(--g-border-radius-m);\n border-bottom-right-radius: var(--g-border-radius-m);\n padding: 0.2rem 0.5rem;\n font-size: 1rem;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 44px;\n &:focus {\n color: var(--ilw-color--focus--text);\n background: var(--ilw-color--focus--background);\n }\n}\n\n.g-search-dropdown {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n background: var(--g-surface-0);\n border: 2px solid var(--g-surface-200);\n z-index: 10;\n max-height: 80vh;\n overflow-y: auto;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);\n}\n\n.g-search-result-count {\n height: 28px;\n padding: 0.2rem 1rem;\n font-size: 0.95rem;\n color: var(--g-surface-900);\n background: var(--g-surface-100);\n}\n\n.g-search-group {\n}\n\n.g-search-group-label {\n font-weight: bold;\n padding: 0.5rem 1rem 0.25rem 1rem;\n color: var(--g-surface-900);\n background: var(--g-surface-100);\n}\n\n.g-search-option {\n padding: 0.3rem 0.8rem;\n cursor: pointer;\n background: var(--g-surface-0);\n color: var(--g-surface-900);\n border: 2px solid transparent;\n\n &:hover {\n text-decoration: underline;\n }\n}\n\n.g-search-option.g-search-option-active {\n background: var(--g-info-200);\n color: var(--g-primary-500);\n border: 2px solid var(--g-primary-500);\n}\n\n.fa-spin {\n color: var(--g-primary-300);\n}\n\n@media (max-width: 960px) {\n .g-search {\n min-width: 150px;\n }\n}\n</style>\n","<script setup lang=\"ts\">\n/**\n * This is a minimal header meant for web apps where a full Illinois\n * brand header would be too large.\n *\n * **Slot** `left` allows replacing the link element in the top-left corner.\n *\n * **Slot** `title` is to the right of the logo.\n *\n * **Slot** `app-controls` is the remaining area to the right.\n */\n\ntype Props = {\n illinois?: boolean;\n /**\n * Top-left corner text\n *\n * You can customize this text element with the \"left\" slot.\n */\n brand?: string;\n};\n\nconst props = withDefaults(defineProps<Props>(), {\n illinois: false,\n brand: \"GRAD\",\n});\n</script>\n\n<template>\n <header\n :class=\"{\n 'g-app-header': true,\n }\"\n >\n <div class=\"g-app-header__background\">\n <div class=\"g-app-header__background-pattern\"></div>\n <div class=\"g-app-header__background-gradient\"></div>\n </div>\n <div class=\"g-app-header__brand\">\n <slot name=\"left\">\n <a class=\"g-app-header__brand-text\" href=\"/\">{{ brand }}</a>\n </slot>\n </div>\n <div v-if=\"illinois\" class=\"g-app-header__block-i-container\">\n <svg\n class=\"g-app-header__block-i\"\n role=\"img\"\n width=\"55\"\n viewBox=\"0 0 55 79\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <!-- NO LICENSE GRANTED for this logo, must have the right to use it -->\n <title>Block I logo</title>\n <path\n class=\"g-app-header__block-i-outline\"\n d=\"M54.2 21.1V0H0v21.1h12v36.1H0v21.1h54.2V57.2h-12V21.1z\"\n ></path>\n <path\n class=\"g-app-header__block-i-fill\"\n d=\"M42.1 18.1h9V3H3v15h9c1.7 0 3 1.3 3 3v36.1c0 1.7-1.3 3-3 3H3v15h48.1v-15h-9c-1.7 0-3-1.3-3-3v-36c0-1.7 1.4-3 3-3z\"\n ></path>\n </svg>\n </div>\n <slot v-else name=\"icon\"></slot>\n <div class=\"g-app-header__title\">\n <slot name=\"title\"></slot>\n </div>\n <div class=\"g-app-header__app-controls-wrap\">\n <slot name=\"app-controls\" class=\"g-app-header__app-controls\"></slot>\n </div>\n </header>\n</template>\n\n<style>\nhtml {\n scroll-padding-top: 70px;\n}\n\n:root {\n --g-toolbar-height: 56px;\n}\n.g-app-header {\n .g-app-header__title {\n display: flex;\n align-items: center;\n margin-left: 20px;\n flex: 1;\n }\n\n .g-app-header__title > * {\n font-size: 20px;\n font-family: \"Source Sans\";\n font-style: normal;\n line-height: 30px;\n color: var(--g-primary-500);\n margin: 0;\n }\n\n .g-app-header__app-controls-wrap {\n margin-right: 20px;\n }\n}\n\n.app-name {\n color: var(--g-primary-500);\n font-size: 1.25rem;\n font-family: \"Source Sans\";\n font-style: normal;\n font-weight: 700;\n line-height: 1.875rem;\n margin: 0 10px 0 20px;\n text-decoration: none;\n\n a {\n color: var(--g-primary-500);\n\n &:hover {\n text-decoration: underline;\n color: var(--g-accent-700);\n }\n }\n\n @media screen and (max-width: 640px) {\n display: none;\n }\n}\na.app-name {\n &:hover {\n text-decoration: underline;\n color: var(--g-accent-700);\n }\n}\n</style>\n\n<style scoped>\n.g-app-header {\n box-sizing: border-box;\n background-color: var(--g-surface-100);\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n /*noinspection CssUnresolvedCustomProperty*/\n padding-right: var(--g-scrollbar-width, 0px);\n display: flex;\n align-items: center;\n z-index: 2;\n height: var(--g-toolbar-height);\n border-bottom: 2px solid var(--g-accent-500);\n box-shadow:\n 0px 1px 2px 0px rgba(0, 0, 0, 0.25),\n 0px 1px 10px 5px rgba(0, 0, 0, 0.08);\n}\n\n.g-app-header__background {\n position: absolute;\n z-index: -1;\n top: 0;\n left: 0;\n bottom: 0;\n width: 470px;\n\n @media screen and (max-width: 640px) {\n width: 80%;\n }\n}\n\n.g-app-header__background-pattern {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n background-image: url('data:image/svg+xml,<%3Fxml version=\"1.0\" encoding=\"UTF-8\"%3F><svg id=\"White\" height=\"60\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 712.9248 669.165\"><defs><linearGradient id=\"linear-gradient\" x1=\"-7196.9772\" y1=\"-1811.3069\" x2=\"-7204.2\" y2=\"-2284.4046\" gradientTransform=\"translate(13629.8481 -2798.015) scale(2.0465 -1)\" gradientUnits=\"userSpaceOnUse\"><stop offset=\"0\" stop-color=\"%23c8c6c7\"/><stop offset=\".9807\" stop-color=\"%23fff\"/></linearGradient><linearGradient id=\"linear-gradient-2\" x1=\"-7196.9771\" y1=\"-1558.6549\" x2=\"-7204.2\" y2=\"-2031.7526\" gradientTransform=\"translate(13808.4999 -2366.711) scale(2.0465 -1)\" xlink:href=\"%23linear-gradient\"/><linearGradient id=\"linear-gradient-3\" x1=\"-7196.9771\" y1=\"-1306.0029\" x2=\"-7204.1999\" y2=\"-1779.1006\" gradientTransform=\"translate(13987.1517 -1935.4069) scale(2.0465 -1)\" xlink:href=\"%23linear-gradient\"/><linearGradient id=\"linear-gradient-4\" x1=\"-7196.977\" y1=\"-1053.3509\" x2=\"-7204.1999\" y2=\"-1526.4486\" gradientTransform=\"translate(14165.8035 -1504.1028) scale(2.0465 -1)\" xlink:href=\"%23linear-gradient\"/><linearGradient id=\"linear-gradient-5\" x1=\"-7196.977\" y1=\"-800.6988\" x2=\"-7204.1999\" y2=\"-1273.7966\" gradientTransform=\"translate(14344.4553 -1072.7988) scale(2.0465 -1)\" xlink:href=\"%23linear-gradient\"/><linearGradient id=\"linear-gradient-6\" x1=\"-7196.9769\" y1=\"-548.0468\" x2=\"-7204.1998\" y2=\"-1021.1445\" gradientTransform=\"translate(14523.1071 -641.4947) scale(2.0465 -1)\" xlink:href=\"%23linear-gradient\"/><linearGradient id=\"linear-gradient-7\" x1=\"-7199.49\" y1=\"-295.3714\" x2=\"-7206.7129\" y2=\"-768.4691\" gradientTransform=\"translate(14710.5552 -213.7874) scale(2.0465 -1)\" xlink:href=\"%23linear-gradient\"/><linearGradient id=\"linear-gradient-8\" x1=\"-7199.49\" y1=\"-42.7194\" x2=\"-7206.7128\" y2=\"-515.8171\" gradientTransform=\"translate(14889.207 217.5166) scale(2.0465 -1)\" xlink:href=\"%23linear-gradient\"/><linearGradient id=\"linear-gradient-9\" x1=\"-7199.4899\" y1=\"209.9326\" x2=\"-7206.7128\" y2=\"-263.1651\" gradientTransform=\"translate(15067.8588 648.8207) scale(2.0465 -1)\" xlink:href=\"%23linear-gradient\"/><linearGradient id=\"linear-gradient-10\" x1=\"-7199.4899\" y1=\"462.5846\" x2=\"-7206.7128\" y2=\"-10.5131\" gradientTransform=\"translate(15246.5106 1080.1248) scale(2.0465 -1)\" xlink:href=\"%23linear-gradient\"/><linearGradient id=\"linear-gradient-11\" x1=\"-7199.4898\" y1=\"715.2367\" x2=\"-7206.7127\" y2=\"242.1389\" gradientTransform=\"translate(15425.1624 1511.4288) scale(2.0465 -1)\" xlink:href=\"%23linear-gradient\"/><linearGradient id=\"linear-gradient-12\" x1=\"-7199.4898\" y1=\"967.8887\" x2=\"-7206.7127\" y2=\"494.791\" gradientTransform=\"translate(15603.8142 1942.7329) scale(2.0465 -1)\" xlink:href=\"%23linear-gradient\"/></defs><g clip-path=\"url(%23clippath)\"><g><rect x=\"-2546.6738\" y=\"-978.5334\" width=\"2887.3541\" height=\"252.652\" transform=\"translate(-2485.5349 -674.873) rotate(135)\" fill=\"url(%23linear-gradient)\"/><rect x=\"-2368.0219\" y=\"-799.8814\" width=\"2887.3541\" height=\"252.652\" transform=\"translate(-2054.231 -496.2207) rotate(135)\" fill=\"url(%23linear-gradient-2)\"/><rect x=\"-2189.37\" y=\"-621.2293\" width=\"2887.3541\" height=\"252.652\" transform=\"translate(-1622.9271 -317.5685) rotate(135)\" fill=\"url(%23linear-gradient-3)\"/><rect x=\"-2010.7182\" y=\"-442.5773\" width=\"2887.3541\" height=\"252.652\" transform=\"translate(-1191.6232 -138.9163) rotate(135)\" fill=\"url(%23linear-gradient-4)\"/><rect x=\"-1832.0663\" y=\"-263.9253\" width=\"2887.3541\" height=\"252.652\" transform=\"translate(-760.3193 39.736) rotate(135)\" fill=\"url(%23linear-gradient-5)\"/><rect x=\"-1653.4144\" y=\"-85.2732\" width=\"2887.3541\" height=\"252.652\" transform=\"translate(-329.0155 218.3882) rotate(135)\" fill=\"url(%23linear-gradient-6)\"/><rect x=\"-1471.1093\" y=\"89.7587\" width=\"2887.3541\" height=\"252.652\" transform=\"translate(105.9651 388.2772) rotate(135)\" fill=\"url(%23linear-gradient-7)\"/><rect x=\"-1292.4575\" y=\"268.4107\" width=\"2887.3541\" height=\"252.652\" transform=\"translate(537.269 566.9294) rotate(135)\" fill=\"url(%23linear-gradient-8)\"/><rect x=\"-1113.8056\" y=\"447.0628\" width=\"2887.3541\" height=\"252.652\" transform=\"translate(968.5728 745.5817) rotate(135)\" fill=\"url(%23linear-gradient-9)\"/><rect x=\"-935.1537\" y=\"625.7148\" width=\"2887.3541\" height=\"252.652\" transform=\"translate(1399.8767 924.2339) rotate(135)\" fill=\"url(%23linear-gradient-10)\"/><rect x=\"-756.5019\" y=\"804.3669\" width=\"2887.3541\" height=\"252.652\" transform=\"translate(1831.1806 1102.8862) rotate(135)\" fill=\"url(%23linear-gradient-11)\"/><rect x=\"-577.85\" y=\"983.0189\" width=\"2887.3541\" height=\"252.652\" transform=\"translate(2262.4845 1281.5384) rotate(135)\" fill=\"url(%23linear-gradient-12)\"/></g></g></svg>');\n background-repeat: repeat;\n opacity: 0.5;\n}\n\n.darkmode {\n .g-app-header__background-pattern {\n background-image: url('data:image/svg+xml,<%3Fxml version=\"1.0\" encoding=\"UTF-8\"%3F><svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 712.9248 669.165\"><defs><linearGradient id=\"linear-gradient\" x1=\"-1489.8977\" y1=\"3840.7045\" x2=\"-1497.1206\" y2=\"3367.6068\" gradientTransform=\"translate(-3080.7102 -3500.1236) rotate(-180) scale(2.0465 -1)\" gradientUnits=\"userSpaceOnUse\"><stop offset=\"0\" stop-color=\"%2313294b\"/><stop offset=\"1\" stop-color=\"%230071ce\"/></linearGradient><linearGradient id=\"linear-gradient-2\" x1=\"-1489.8977\" y1=\"4093.3564\" x2=\"-1497.1204\" y2=\"3620.2586\" gradientTransform=\"translate(-2902.0583 -3574.1233) rotate(-180) scale(2.0465 -1)\" gradientUnits=\"userSpaceOnUse\"><stop offset=\"0\" stop-color=\"%2313294b\"/><stop offset=\"1\" stop-color=\"%230071ce\"/></linearGradient><linearGradient id=\"linear-gradient-3\" x1=\"-1489.8976\" y1=\"4346.0085\" x2=\"-1497.1205\" y2=\"3872.9108\" gradientTransform=\"translate(-2723.4065 -3648.1232) rotate(-180) scale(2.0465 -1)\" gradientUnits=\"userSpaceOnUse\"><stop offset=\"0\" stop-color=\"%2313294b\"/><stop offset=\"1\" stop-color=\"%230071ce\"/></linearGradient><linearGradient id=\"linear-gradient-4\" x1=\"-1489.8976\" y1=\"4598.6606\" x2=\"-1497.1205\" y2=\"4125.5627\" gradientTransform=\"translate(-2544.7544 -3722.123) rotate(-180) scale(2.0465 -1)\" gradientUnits=\"userSpaceOnUse\"><stop offset=\"0\" stop-color=\"%2313294b\"/><stop offset=\"1\" stop-color=\"%230071ce\"/></linearGradient></defs><g id=\"Blue\"><g clip-path=\"url(%23clippath)\"><g><rect x=\"-1471.1094\" y=\"79.7585\" width=\"2887.354\" height=\"252.652\" transform=\"translate(-153.7585 40.9631) rotate(-45)\" fill=\"url(%23linear-gradient)\"/><rect x=\"-1292.4576\" y=\"258.4107\" width=\"2887.354\" height=\"252.652\" transform=\"translate(-227.7588 219.615) rotate(-45)\" fill=\"url(%23linear-gradient-2)\"/><rect x=\"-1113.8058\" y=\"437.0627\" width=\"2887.354\" height=\"252.652\" transform=\"translate(-301.759 398.2669) rotate(-45)\" fill=\"url(%23linear-gradient-3)\"/><rect x=\"-935.1538\" y=\"615.715\" width=\"2887.354\" height=\"252.652\" transform=\"translate(-375.7592 576.919) rotate(-45)\" fill=\"url(%23linear-gradient-4)\"/><rect x=\"-756.5019\" y=\"794.367\" width=\"2887.354\" height=\"252.652\" transform=\"translate(-449.7594 755.5709) rotate(-45)\" fill=\"url(%23linear-gradient-5)\"/><rect x=\"-577.8503\" y=\"973.0192\" width=\"2887.3541\" height=\"252.652\" transform=\"translate(-523.7597 934.2227) rotate(-45)\" fill=\"url(%23linear-gradient-6)\"/></g></g></g></svg>');\n }\n\n .g-app-header__block-i-container {\n background: var(--il-orange);\n }\n\n .g-app-header__block-i-fill {\n fill: var(--il-blue);\n }\n}\n\n.g-app-header__background-gradient {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n background: linear-gradient(\n 90deg,\n transparent -15.89%,\n var(--g-surface-100) 95.85%\n );\n}\n\n.g-app-header__brand {\n min-width: 1rem;\n margin-top: 2px;\n\n &:deep(a) {\n text-decoration: none;\n padding: 10px 15px;\n font-family: var(--il-font-montserrat);\n letter-spacing: 0.98px;\n font-size: 14px;\n font-style: normal;\n font-weight: 800;\n color: var(--g-primary-300);\n\n &:hover {\n text-decoration: underline;\n color: var(--g-primary-500);\n }\n\n @media screen and (max-width: 740px) {\n display: none;\n }\n }\n}\n\n.g-app-header__block-i-container {\n height: calc(var(--g-toolbar-height) + 3px);\n box-sizing: border-box;\n margin-top: 6px;\n box-shadow:\n 0px 0px 1px 1px rgba(0, 0, 0, 0.08),\n 2px 1px 10px 0px rgba(0, 0, 0, 0.35);\n}\n\n.g-app-header__app-controls {\n flex: 1;\n display: flex;\n justify-content: flex-end;\n padding: 0 10px;\n gap: 10px;\n}\n.g-app-header__block-i-container {\n background-color: var(--il-blue);\n min-width: 40px;\n padding: 8px 10px;\n\n .g-app-header__block-i {\n display: block;\n width: 24px;\n }\n\n .g-app-header__block-i-outline {\n fill: #fff;\n }\n\n .g-app-header__block-i-fill {\n fill: var(--il-orange);\n }\n}\n</style>\n","<script setup lang=\"ts\">\n/**\n * A simple sidebar that's fixed to the left side of the viewport.\n *\n * This includes the CSS for the `fixed` position and sizing, so the element\n * should be fairly high in the DOM tree.\n *\n * If neither `top-offset` nor `top-offset-var` are defined, the sidebar will be\n * offset by `var(--g-toolbar-height)`. If there is no toolbar, just pass\n * `0` as the `top-offset`.\n *\n * The sidebar can be made collapsible by providing the `sidebar` injected\n * object from `useSidebar`. See the [Hamburger Menu Documentation](#use-sidebar)\n * for details.\n */\nimport { computed, inject, useId } from \"vue\";\nimport { useSidebar } from \"../compose/useSidebar.ts\";\n\ninterface Props {\n /**\n * Custom background color\n */\n backgroundColor?: string;\n /**\n * Custom background image\n */\n backgroundImage?: string; // Demo: none\n /**\n * Sidebar theme\n */\n theme?: \"light\" | \"dark\";\n // Offset from the top of the viewport\n topOffset?: string;\n // Top offset variable to use instead of topOffset\n topOffsetVar?: string;\n /**\n * Width\n *\n * Width of the sidebar\n */\n width?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n backgroundColor: \"\",\n backgroundImage: \"none\",\n theme: \"dark\",\n width: \"300px\",\n topOffset: \"\",\n topOffsetVar: \"\",\n});\n\nconst sidebar = inject<ReturnType<typeof useSidebar>>(\n \"sidebar\",\n // This isn't required, so the default value just avoids compiler warnings\n () => undefined as any,\n true,\n);\n\nconst bgImage = computed(() => {\n if (props.backgroundImage) {\n return props.backgroundImage;\n }\n if (props.theme === \"light\") {\n return \"none\";\n }\n return \"url('https://gradcdn.blob.core.windows.net/public/sidebar-bg2.jpg')\";\n});\n\nconst bgColor = computed(() => {\n if (props.backgroundColor) {\n return props.backgroundColor;\n }\n if (props.theme === \"light\") {\n return \"#f9f9f9\";\n }\n return \"#030913\";\n});\n\nconst topOff = computed(() => {\n if (props.topOffsetVar) {\n return `var(${props.topOffsetVar})`;\n }\n return props.topOffset ? props.topOffset : \"var(--g-toolbar-height)\";\n});\n\nconst fallbackId = useId();\n\nfunction handleEscapeKey(event: KeyboardEvent) {\n if (event.key === \"Escape\") {\n if (sidebar?.isCollapsible?.value && sidebar?.open?.value) {\n sidebar.open.value = false;\n document.getElementById(`${sidebar.id}-hamburger`)?.focus();\n }\n }\n}\n</script>\n\n<template>\n <div\n ref=\"sidebar-ref\"\n :id=\"`${sidebar?.id ?? fallbackId}-sidebar`\"\n class=\"g-sidebar\"\n :class=\"[\n `g-sidebar__${theme}`,\n {\n 'g-sidebar--collapsible': sidebar?.isCollapsible?.value,\n 'g-sidebar--closed':\n !sidebar?.open?.value && sidebar?.isCollapsible?.value,\n 'g-sidebar--open':\n sidebar?.open?.value && sidebar?.isCollapsible?.value,\n },\n ]\"\n :style=\"{\n backgroundImage: bgImage,\n backgroundColor: bgColor,\n '--g-sidebar-top-offset': topOff,\n '--g-sidebar-width': width ?? '300px',\n width: 'var(--g-sidebar-width)',\n }\"\n @keydown=\"handleEscapeKey\"\n >\n <slot></slot>\n </div>\n</template>\n\n<style scoped>\n.g-sidebar {\n box-sizing: border-box;\n background-size: cover;\n background-position: top;\n position: fixed;\n left: 0;\n /*noinspection CssUnresolvedCustomProperty*/\n top: var(--g-sidebar-top-offset);\n bottom: 0;\n /*noinspection CssUnresolvedCustomProperty*/\n width: var(--g-sidebar-width, 300px);\n overflow-y: auto;\n}\n.g-sidebar--open {\n transition: opacity 0.1s ease-out;\n opacity: 1;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .g-sidebar--open {\n transition: none;\n }\n}\n\n.g-sidebar--closed {\n display: none;\n}\n.g-sidebar--collapsible {\n height: 100vh;\n top: 0;\n z-index: 198;\n box-shadow:\n 0 2px 10px rgba(0, 0, 0, 0.1),\n 0 0 10px rgba(0, 0, 0, 0.1);\n}\n@starting-style {\n .g-sidebar {\n opacity: 0;\n }\n}\n</style>\n","<script setup lang=\"ts\">\n/**\n * A sidebar menu component for use with `GSidebar`. Displays a title and\n * a list of links.\n *\n * This component also supports showing active links for in-page navigation.\n *\n * **Props**:\n *\n * - `items` with a list of `MenuItem` objects. The objects should have:\n * - `label` for the link text\n * - `href` or `to` for the destination. If `to` is used, the links will\n * be rendered as `router-link` for vue-router.\n * - `spy` to enable tracking active links for in-page navigation\n * - `offset` to adjust the active link tracking position\n * - `theme` to set the menu theme\n *\n * For tracking the active link, the `spy` prop must be set to `true` and\n * a `v-model` must be provided that has the ID of the target element (without #).\n *\n * The composable function `useActiveLinkContent` can be used to track active links.\n * It takes the following parameters:\n *\n * - `Ref<HTMLElement>` Children of this element will be observed\n * - `number` Offset from the top of the window to consider not visible\n * - `Ref<string>` Ref to store the active element ID\n *\n * The direct children of the element must all have an ID to properly work with\n * in-page navigation, and the matching menu item's `href` should be set to\n * `#<id>`.\n *\n * Here's a minimal example of a page using `useActiveLinkContent`:\n *\n * ```vue\n * <script setup lang=\"ts\">\n * import { computed, onMounted, ref, useTemplateRef } from \"vue\";\n * import { useActiveLinkContent } from \"@illinois-grad/grad-vue\";\n *\n * const activeId = ref<string>(\"\");\n * const main = useTemplateRef(\"main\");\n * // onMounted is for Nuxt compatibility\n * onMounted(() => {\n * useActiveLinkContent(main, 70, activeId);\n * });\n * </script>\n *\n * <template>\n * <GSidebar>\n * <GSidebarMenu\n * :items=\"[\n * { label: 'Buttons', href: '#buttons' },\n * { label: 'More Buttons', href: '#more-buttons' }\n * ]\"\n * v-model=\"activeId\"\n * />\n * </GSidebar>\n * <main class=\"main\" ref=\"main\">\n * <section id=\"buttons\">\n * <h2>Buttons</h2>\n * <p>Some buttons</p>\n * </section>\n * <section id=\"more-buttons\">\n * <h2>More Buttons</h2>\n * <p>Some more buttons</p>\n * </section>\n * </main>\n * </template>\n * ```\n */\n\nimport {\n computed,\n getCurrentInstance,\n nextTick,\n onMounted,\n useId,\n useTemplateRef,\n watch,\n} from \"vue\";\n\ntype MenuItem = {\n label: string;\n href?: string;\n to?: string;\n};\n\ninterface Props {\n /**\n * Title and accessible name\n */\n title?: string; // Demo: Sidebar Menu\n items: MenuItem[];\n // Offset for tracking active position to account for toolbars\n offset?: number;\n // Track active position for in-page links\n spy?: boolean;\n /**\n * Sidebar theme\n */\n theme?: \"light\" | \"dark\";\n /**\n * Use compact layout\n */\n compact?: boolean;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n offset: 70,\n spy: true,\n theme: \"light\",\n compact: false,\n});\n\nconst activeId = defineModel<string | null>({ default: null, type: String });\n\nconst activeLink = computed(() => {\n if (props.spy && activeId.value) {\n return \"#\" + activeId.value;\n }\n return null;\n});\n\nconst content = useTemplateRef(\"content\");\n\nonMounted(() => {\n watch(\n activeId,\n () => {\n nextTick(() => {\n const activeItem = content.value?.querySelector<HTMLElement>(\n `.g-sidebar-menu__is-active`,\n );\n if (activeItem) {\n activeItem.scrollIntoView({ block: \"nearest\" });\n }\n });\n },\n { immediate: true },\n );\n});\n\n// Detect vue-router without adding it as a dependency\nconst instance = getCurrentInstance();\nconst RouterLinkComp = computed<any | null>(() => {\n const comp = instance?.appContext?.components?.RouterLink as\n | any\n | undefined;\n return comp ?? null;\n});\n\nfunction onLinkClick(e: MouseEvent, item: MenuItem) {\n // Only handle in-page hash links here\n if (!item.href || !item.href.startsWith(\"#\")) {\n return;\n }\n\n const id = item.href.slice(1);\n const el = document\n .getElementById(id)\n ?.querySelector<HTMLElement>(\"h2, h3, h4, h5\");\n if (!el) {\n return;\n }\n e.preventDefault();\n el.setAttribute(\"tabindex\", \"-1\");\n el.focus();\n el.scrollIntoView({ block: \"start\" });\n\n history.replaceState(null, \"\", item.href);\n}\n\nconst id = useId();\n</script>\n\n<template>\n <nav\n class=\"g-sidebar-menu\"\n :class=\"[\n `g-sidebar-menu__${props.theme}`,\n { 'g-sidebar-menu--compact': props.compact },\n ]\"\n v-bind=\"{\n 'aria-labelledby': title ? id : undefined,\n 'aria-label': title ? undefined : 'Sidebar Menu',\n }\"\n >\n <h2 v-if=\"title\" :id=\"id\" class=\"g-sidebar-menu__title\">{{ title }}</h2>\n <div class=\"g-sidebar-menu__divider\"></div>\n <div class=\"g-sidebar-menu__content\" ref=\"content\">\n <ul class=\"g-sidebar-menu__list\">\n <li\n v-for=\"item in items\"\n :key=\"item.href || item.to\"\n class=\"g-sidebar-menu__item\"\n ref=\"listItems\"\n >\n <!-- Prefer RouterLink when available and item uses 'to' -->\n <component\n v-if=\"item.to && RouterLinkComp\"\n :is=\"RouterLinkComp\"\n class=\"g-sidebar-menu__link\"\n :to=\"item.to\"\n >\n {{ item.label }}\n </component>\n <a\n v-else\n class=\"g-sidebar-menu__link\"\n :href=\"item.href || item.to || '#'\"\n :class=\"{\n 'g-sidebar-menu__is-active':\n activeLink === (item.href || ''),\n }\"\n :aria-current=\"\n activeLink === (item.href || '')\n ? 'location'\n : undefined\n \"\n @click=\"(e) => onLinkClick(e, item)\"\n >\n {{ item.label }}\n </a>\n </li>\n </ul>\n </div>\n </nav>\n</template>\n\n<style scoped>\n.g-sidebar-menu {\n box-sizing: border-box;\n padding-top: 2rem;\n color: var(--g-surface-0);\n display: flex;\n flex-direction: column;\n}\n.g-sidebar-menu__title {\n margin: 2rem 2rem 0.5rem;\n font-size: 2rem;\n font-family: var(--il-font-heading);\n color: var(--g-surface-0);\n}\n.g-sidebar-menu__divider {\n margin-left: 2rem;\n margin-top: 2px;\n height: 4px;\n width: 60px;\n flex: 0 0 4px;\n background: var(--g-accent-500);\n}\n.g-sidebar-menu__content {\n margin: 0 0 0;\n}\n.g-sidebar-menu__list {\n list-style: none;\n margin: 1rem 0 0;\n padding: 0;\n}\n.g-sidebar-menu__item {\n display: block;\n margin: 0;\n}\n.g-sidebar-menu__link {\n display: block;\n padding: 0.5rem calc(2rem - 8px);\n border-left: 8px solid transparent;\n color: var(--g-surface-0);\n text-decoration: none;\n font-size: 1.25rem;\n font-weight: bold;\n\n &:hover {\n text-decoration: underline;\n color: var(--g-accent-500);\n }\n\n &.g-sidebar-menu__is-active {\n background: var(--g-primary-500);\n border-left: 8px solid var(--g-accent-500);\n }\n\n &:focus {\n background: var(--ilw-color--focus--background);\n color: var(--ilw-color--focus--text);\n }\n}\n.g-sidebar-menu--compact {\n .g-sidebar-menu__link {\n padding: 0.1rem calc(2rem - 8px);\n font-size: 1.125rem;\n font-weight: 700;\n }\n}\n\n.g-sidebar-menu__light {\n background: var(--g-surface-50);\n\n .g-sidebar-menu__title,\n .g-sidebar-menu__link {\n color: var(--g-primary-500);\n }\n\n .g-sidebar-menu__link {\n &:hover {\n color: var(--g-accent-700);\n }\n\n &.g-sidebar-menu__is-active {\n background: var(--g-accent-500);\n color: var(--g-surface-0);\n border-left: 8px solid var(--g-primary-500);\n }\n\n &:focus {\n background: var(--ilw-color--focus--background);\n color: var(--ilw-color--focus--text);\n }\n }\n}\n</style>\n","import type { Directive, DirectiveBinding } from \"vue\";\nimport { ref, watchEffect } from \"vue\";\nimport { calculatePopoverPosition } from \"../compose/popoverPosition.ts\";\nimport { getTopZIndex } from \"../compose/useOverlayStack.ts\";\n\nlet tooltipIdCounter = 1;\n\n/**\n * Create the tooltip HTML element.\n * @param text Text content.\n * @param id ID for aria-describedby to point to this tooltip.\n */\nfunction createTooltipEl(text: string, id: string) {\n const tooltip = document.createElement(\"div\");\n tooltip.className = \"v-gtooltip\";\n tooltip.textContent = text;\n tooltip.setAttribute(\"role\", \"tooltip\");\n tooltip.setAttribute(\"id\", id);\n return tooltip;\n}\n\n/**\n * Show the tooltip at the correct position based on the element's position.\n *\n * @param el The interactive element that the tooltip is attached to.\n * @param tooltip The tooltip HTML element.\n */\nfunction showTooltip(el: HTMLElement, tooltip: HTMLElement) {\n const anchorRect = el.getBoundingClientRect();\n const popoverRect = tooltip.getBoundingClientRect();\n // Use (0, 0) as origin since getBoundingClientRect() and position: fixed\n // both use viewport-relative coordinates.\n const viewportRect = new DOMRect(0, 0, window.innerWidth, window.innerHeight);\n const { top, left, placedAbove } = calculatePopoverPosition(anchorRect, popoverRect, viewportRect, {\n gap: 8,\n margin: 8,\n preferAbove: true,\n });\n // Calculate arrow position as a percentage\n const anchorCenter = anchorRect.left + anchorRect.width / 2;\n const tooltipLeft = left;\n const arrowX = ((anchorCenter - tooltipLeft) / popoverRect.width) * 100;\n tooltip.style.setProperty(\"--v-gtooltip-arrow-x\", `${arrowX}%`);\n tooltip.classList.remove(\"v-gtooltip-bottom\");\n if (!placedAbove) {\n tooltip.classList.add(\"v-gtooltip-bottom\");\n }\n tooltip.style.left = `${left}px`;\n tooltip.style.top = `${top}px`;\n tooltip.style.zIndex = `${getTopZIndex()}`;\n tooltip.style.opacity = \"1\";\n}\n\n/**\n * The opacity is set to 0 to fade the tooltip out.\n * @param tooltip\n */\nfunction hideTooltip(tooltip: HTMLElement) {\n tooltip.style.opacity = \"0\";\n}\n\nexport type VGtooltipDirective = Directive<HTMLElement, string>;\n\nconst VGtooltip: VGtooltipDirective = {\n mounted(el: HTMLElement, binding: DirectiveBinding) {\n const tooltip = ref<HTMLElement | null>(null);\n const isHovered = ref(false);\n const isFocused = ref(false);\n const tooltipText = ref(binding.value);\n let resizeObserver: ResizeObserver | null = null;\n // Generate unique id for tooltip\n let tooltipId: string;\n if (el.getAttribute(\"aria-describedby\")) {\n tooltipId = el.getAttribute(\"aria-describedby\")!;\n } else {\n tooltipId = `v-gtooltip-${++tooltipIdCounter}`;\n // Set aria-describedby on the element\n el.setAttribute(\"aria-describedby\", tooltipId);\n }\n\n const ensureTooltip = () => {\n if (!tooltip.value) {\n tooltip.value = createTooltipEl(tooltipText.value, tooltipId);\n // Append to #modal-root (with document.body fallback) so the tooltip\n // shares the same DOM container as GModal and GPopover. This ensures\n // consistent z-index stacking context and avoids CSS transform issues\n // when the trigger is inside a transformed ancestor (e.g., GModal uses\n // transform: translate(-50%, -50%) for centering).\n // Accessibility: DOM order does not affect tooltip accessibility. Screen\n // readers follow the aria-describedby reference to find tooltip content\n // regardless of where the element sits in the DOM. Tooltips never receive\n // keyboard focus, so appending here does not disrupt tab order.\n const modalRoot = document.getElementById(\"modal-root\");\n (modalRoot ?? document.body).appendChild(tooltip.value);\n // Observe tooltip size changes to reposition\n resizeObserver = new ResizeObserver(() => {\n if (tooltip.value && (isHovered.value || isFocused.value)) {\n showTooltip(el, tooltip.value);\n }\n });\n resizeObserver.observe(tooltip.value);\n }\n };\n\n watchEffect(() => {\n if (tooltip.value) {\n tooltip.value.textContent = tooltipText.value;\n }\n });\n\n // Watch for changes in hover and focus states,\n // and show/hide the tooltip accordingly\n watchEffect(() => {\n if (isHovered.value || isFocused.value) {\n ensureTooltip();\n if (tooltip.value) {\n showTooltip(el, tooltip.value);\n }\n } else {\n if (tooltip.value) {\n hideTooltip(tooltip.value);\n\n setTimeout(() => {\n // After the fade out, emit an event in case the user needs\n // to perform any cleanup\n el.dispatchEvent(new CustomEvent(\"tooltip-hide\"));\n }, 150);\n }\n }\n });\n\n const onMouseEnter = () => {\n isHovered.value = true;\n };\n const onMouseLeave = () => {\n isHovered.value = false;\n };\n const onFocus = () => {\n isFocused.value = true;\n };\n const onBlur = () => {\n isFocused.value = false;\n };\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\" || e.key === \"Esc\") {\n isHovered.value = false;\n isFocused.value = false;\n }\n };\n\n el.addEventListener(\"mouseenter\", onMouseEnter);\n el.addEventListener(\"mouseleave\", onMouseLeave);\n el.addEventListener(\"focus\", onFocus);\n el.addEventListener(\"blur\", onBlur);\n el.addEventListener(\"keydown\", onKeyDown);\n\n ensureTooltip();\n\n // Since this is a directive, we need to store the variables on the element\n (el as any)._v_gtooltip = {\n onMouseEnter,\n onMouseLeave,\n onFocus,\n onBlur,\n onKeyDown,\n tooltip,\n tooltipText,\n isHovered,\n isFocused,\n resizeObserver,\n tooltipId,\n };\n },\n updated(el: HTMLElement, binding: DirectiveBinding) {\n const data = (el as any)._v_gtooltip;\n if (data && data.tooltipText) {\n data.tooltipText.value = binding.value;\n }\n },\n unmounted(el: HTMLElement) {\n const data = (el as any)._v_gtooltip;\n if (data && data.tooltip && data.tooltip.value) {\n if (data.resizeObserver) {\n data.resizeObserver.disconnect();\n }\n data.tooltip.value.remove();\n data.tooltip.value = null;\n }\n el.removeEventListener(\"mouseenter\", data.onMouseEnter);\n el.removeEventListener(\"mouseleave\", data.onMouseLeave);\n el.removeEventListener(\"focus\", data.onFocus);\n el.removeEventListener(\"blur\", data.onBlur);\n el.removeEventListener(\"keydown\", data.onKeyDown);\n // Remove aria-describedby\n el.removeAttribute(\"aria-describedby\");\n },\n};\n\nexport default VGtooltip;\n","<script setup lang=\"ts\">\n/**\n * Displays text with a clipboard button that copies the text to the clipboard.\n * The text can be hidden in cases where it's already displayed differently.\n *\n * If for some reason the user's browser doesn't support a clipboard,\n * the tooltip will indicate that when they try to copy.\n */\n\nimport { useClipboard } from \"@vueuse/core\";\nimport { ref } from \"vue\";\nimport VGtooltip from \"../directives/v-gtooltip.ts\";\n\ninterface Props {\n /**\n * Text\n */\n text: string; // Demo: This is some text to get copied\n\n /**\n * Hide the visible text\n */\n hideText?: boolean;\n\n /**\n * Copy button label\n */\n copyLabel?: string;\n}\n\nconst props = defineProps<Props>();\n\nconst vGtooltip = VGtooltip;\n\nconst { text, copy, copied, isSupported } = useClipboard({\n source: props.text,\n});\n\nconst tooltip = ref<string>(props.copyLabel ?? \"Copy to clipboard\");\n\nconst handleCopy = () => {\n if (isSupported.value) {\n copy();\n tooltip.value = \"Copied\";\n } else {\n tooltip.value = \"Copy not supported\";\n }\n};\nconst handleTooltipHide = () => {\n tooltip.value = props.copyLabel ?? \"Copy to clipboard\";\n};\n</script>\n\n<template>\n <div class=\"g-clipboard-text\">\n <template v-if=\"!hideText\">{{ props.text }}</template>\n\n <button\n type=\"button\"\n aria-label=\"Copy\"\n @click=\"handleCopy\"\n v-gtooltip=\"tooltip\"\n @tooltip-hide=\"handleTooltipHide\"\n class=\"g-clipboard-text-button\"\n >\n <svg\n class=\"g-clipboard-svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 640 640\"\n height=\"1.125rem\"\n role=\"none presentation\"\n >\n <!--!Font Awesome Free v7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.-->\n <path\n fill=\"currentColor\"\n d=\"M480 400L288 400C279.2 400 272 392.8 272 384L272 128C272 119.2 279.2 112 288 112L421.5 112C425.7 112 429.8 113.7 432.8 116.7L491.3 175.2C494.3 178.2 496 182.3 496 186.5L496 384C496 392.8 488.8 400 480 400zM288 448L480 448C515.3 448 544 419.3 544 384L544 186.5C544 169.5 537.3 153.2 525.3 141.2L466.7 82.7C454.7 70.7 438.5 64 421.5 64L288 64C252.7 64 224 92.7 224 128L224 384C224 419.3 252.7 448 288 448zM160 192C124.7 192 96 220.7 96 256L96 512C96 547.3 124.7 576 160 576L352 576C387.3 576 416 547.3 416 512L416 496L368 496L368 512C368 520.8 360.8 528 352 528L160 528C151.2 528 144 520.8 144 512L144 256C144 247.2 151.2 240 160 240L176 240L176 192L160 192z\"\n />\n </svg>\n </button>\n </div>\n</template>\n\n<style scoped>\n.g-clipboard-text-button {\n display: inline-flex;\n align-items: center;\n margin-left: 0.5rem;\n cursor: pointer;\n color: var(--g-surface-0);\n background: var(--g-primary-500);\n border: 1px solid var(--g-primary-500);\n border-radius: 4px;\n padding: 0.4rem;\n font-size: 14px;\n\n .g-clipboard-svg {\n display: block;\n }\n\n &:hover {\n color: var(--g-primary-500);\n background: var(--g-surface-0);\n }\n\n &:focus {\n color: var(--g-primary-500);\n background: var(--g-info-200);\n }\n\n :deep(span) {\n display: block;\n }\n}\n</style>\n","<script lang=\"ts\" setup generic=\"T extends { id: string | number }\">\n/**\n * A scroller that is used for content that's typically shown like a chat log,\n * meaning it starts at the bottom, and you scroll up for older entries.\n *\n * The scroller automatically starts at the bottom. When scrolled up, a button\n * appears that jumps to the bottom. This button is also the first focusable\n * element for accessibility.\n *\n * If the `label` is provided, the scroller will have the ARIA `role=\"log\"` and\n * the label as the `aria-label`.\n *\n * **Slot** `default` is what will be rendered for each entry in the\n * `entries`. For example:\n *\n * ```vue-html\n * <GHistoryScroller\n * v-bind=\"props\"\n * :entries=\"historyEntries\"\n * class=\"history-scroller\">\n * <template #default=\"{ entry }\">\n * <div class=\"history-entry\">\n * This is history for: {{ entry.id }}\n * </div>\n * </template>\n * </GHistoryScroller>\n * ```\n */\n\nimport { computed, nextTick, onMounted, ref, watch } from \"vue\";\nimport { useResizeObserver } from \"@vueuse/core\";\nimport GButton from \"./GButton.vue\";\n\ntype Props = {\n /**\n * Accessible label\n */\n label?: string; // Demo: History\n entries: T[];\n};\n\nconst props = withDefaults(defineProps<Props>(), {\n entries: () => [],\n});\n\nconst scrollerRef = ref<HTMLElement | null>(null);\nconst contentRef = ref<HTMLElement | null>(null);\nconst isAtBottom = ref(true);\nconst isAtTop = ref(true);\n\nasync function scrollToBottom({ focusLast = false } = {}) {\n if (scrollerRef.value) {\n scrollerRef.value.scrollTop = scrollerRef.value.scrollHeight;\n }\n if (focusLast) {\n if (contentRef.value) {\n const items = contentRef.value.querySelectorAll(\".g-history-entry\");\n if (items.length > 0) {\n const last = items[items.length - 1] as HTMLElement;\n await nextTick();\n last.focus();\n }\n }\n }\n}\n\nfunction handleScroll() {\n if (!scrollerRef.value) return;\n const { scrollTop, scrollHeight, clientHeight } = scrollerRef.value;\n // Consider within 2px of bottom/top as \"at bottom/top\"\n isAtBottom.value = scrollTop + clientHeight >= scrollHeight - 2;\n isAtTop.value = scrollTop <= 2;\n}\n\nonMounted(() => {\n nextTick(scrollToBottom);\n});\n\n// Use VueUse's useResizeObserver for scroller and content\nuseResizeObserver(scrollerRef, () => {\n if (isAtBottom.value) {\n scrollToBottom();\n }\n});\nuseResizeObserver(contentRef, () => {\n if (isAtBottom.value) {\n scrollToBottom();\n }\n});\n\nwatch(\n () => props.entries,\n async () => {\n // Only scroll if at bottom\n if (isAtBottom.value) {\n await nextTick();\n scrollToBottom();\n }\n },\n);\n\nconst reversedEntries = computed(() => [...props.entries].reverse());\n</script>\n\n<template>\n <div class=\"g-history-scroller-wrapper\">\n <div\n v-if=\"!isAtTop\"\n class=\"g-history-shadow g-history-shadow--top\"\n aria-hidden=\"true\"\n ></div>\n <div\n v-if=\"!isAtBottom\"\n class=\"g-history-shadow g-history-shadow--bottom\"\n aria-hidden=\"true\"\n ></div>\n <div\n ref=\"scrollerRef\"\n class=\"g-history-scroller\"\n :role=\"label ? 'log' : undefined\"\n :aria-label=\"label\"\n @scroll=\"handleScroll\"\n >\n <GButton\n class=\"g-scroll-to-bottom-btn\"\n :class=\"{ 'scroll-to-bottom-btn--hidden': isAtBottom }\"\n size=\"small\"\n type=\"button\"\n @click=\"() => scrollToBottom({ focusLast: true })\"\n aria-label=\"Jump to Latest\"\n >\n <svg\n aria-hidden=\"true\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 640 640\"\n height=\"1.25rem\"\n >\n <!--!Font Awesome Free v7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.-->\n <path\n fill=\"currentColor\"\n d=\"M303.5 569C312.9 578.4 328.1 578.4 337.4 569L505.4 401C514.8 391.6 514.8 376.4 505.4 367.1C496 357.8 480.8 357.7 471.5 367.1L344.5 494.1L344.5 88C344.5 74.7 333.8 64 320.5 64C307.2 64 296.5 74.7 296.5 88L296.5 494.1L169.5 367.1C160.1 357.7 144.9 357.7 135.6 367.1C126.3 376.5 126.2 391.7 135.6 401L303.6 569z\"\n />\n </svg>\n </GButton>\n <div role=\"list\" ref=\"contentRef\" class=\"g-history-list\">\n <div\n v-for=\"entry in reversedEntries\"\n role=\"listitem\"\n :key=\"entry.id\"\n class=\"g-history-entry\"\n tabindex=\"-1\"\n >\n <slot :entry=\"entry\" />\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.g-history-scroller-wrapper {\n position: relative;\n}\n.g-history-list {\n padding: 1rem;\n margin: 0;\n list-style: none;\n position: relative;\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n.g-history-scroller {\n overflow-y: auto;\n height: 100%;\n width: 100%;\n}\n.g-history-entry {\n margin: 0;\n padding: 0;\n}\n.g-scroll-to-bottom-btn {\n position: absolute;\n right: 2rem;\n bottom: 2rem;\n z-index: 100;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n.scroll-to-bottom-btn--hidden {\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.2s;\n}\n.scroll-to-bottom-btn--hidden:focus {\n opacity: 1;\n pointer-events: auto;\n}\n\n.g-history-shadow {\n position: absolute;\n left: 0;\n right: 0;\n height: 2rem;\n pointer-events: none;\n position: absolute;\n}\n.g-history-shadow--top {\n top: 0;\n background: linear-gradient(\n to bottom,\n rgba(0, 0, 0, 0.12),\n rgba(0, 0, 0, 0)\n );\n}\n.g-history-shadow--bottom {\n bottom: 0;\n background: linear-gradient(to top, rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0));\n}\n</style>\n","<script setup lang=\"ts\">\n/**\n * This component acts like a radio button group condensed into a compact\n * element with the goal of making it easy to go over many of them at once.\n *\n * In addition to the arrow keys changing the selected value, special key\n * bindings exist for 'y' and 'n' to set yes and no respectively.\n *\n * A `describedby` prop can be passed with an ID to an element to be used as\n * the `aria-describedby` for the group element.\n *\n * When the value changes, `v-model` is updated. A `change` event is also emitted\n * if the value changed from user interaction.\n *\n * Slots:\n * - `label`: Custom label content. Defaults to `label` prop if not provided.\n */\nimport { ref, computed, watch, useId } from \"vue\";\n\ninterface Props {\n /**\n * Accessible label\n */\n label: string; // Demo: Three-way toggle\n\n // ID of an element that describes the input\n describedby?: string;\n\n /**\n * Error message\n */\n error?: string;\n\n /**\n * Disabled\n */\n disabled?: boolean;\n}\n\nconst props = defineProps<Props>();\nconst model = defineModel<boolean | null>({default: () => null});\n\nconst emit = defineEmits([\"change\"]);\n\nfunction change(val: boolean | null) {\n const prev = model.value;\n model.value = val;\n if (val !== prev) {\n emit(\"change\", {\n was: prev,\n to: val,\n });\n }\n}\n\nfunction onChange(val: boolean | null) {\n if (props.disabled) {\n return;\n }\n if (model.value === val) {\n change(null);\n } else {\n change(val);\n }\n}\n\nfunction onClickLabel(val: boolean) {\n if (props.disabled) {\n return;\n }\n if (model.value === val) {\n change(null);\n }\n}\n\nconst id = useId();\nconst radioName = computed(() => `g-three-way-toggle-${id}`);\n\nconst leftId = useId();\nconst centerId = useId();\nconst rightId = useId();\n\nconst thumbPosition = computed(() => {\n if (model.value === false) {\n return \"g-left\";\n } else if (model.value === true) {\n return \"g-right\";\n } else {\n return \"g-center\";\n }\n});\n\nfunction onLabelKeydown(e: KeyboardEvent) {\n if (props.disabled) {\n return;\n }\n if (e.key === \"n\" || e.key === \"N\") {\n change(false);\n e.preventDefault();\n } else if (e.key === \"y\" || e.key === \"Y\") {\n change(true);\n e.preventDefault();\n }\n}\n</script>\n\n<template>\n <div class=\"g-three-way-toggle-wrapper\">\n <div class=\"g-three-way-toggle-control\">\n <span class=\"g-label\" :id=\"id\">\n <slot name=\"label\">\n {{ label }}\n </slot>\n </span>\n <fieldset\n class=\"g-three-way-toggle\"\n :class=\"{ 'g-has-error': error }\"\n role=\"radiogroup\"\n :aria-labelledby=\"id\"\n :aria-describedby=\"describedby\"\n :disabled=\"disabled\"\n :aria-invalid=\"error ? 'true' : undefined\"\n :aria-errormessage=\"error ? id + '-error' : undefined\"\n >\n <div\n class=\"g-toggle-track\"\n :class=\"[thumbPosition, { 'g-disabled': disabled }]\"\n >\n <span\n class=\"g-toggle-thumb\"\n :class=\"thumbPosition\"\n aria-hidden=\"true\"\n >\n <span v-if=\"model === false\">NO</span>\n <span v-else-if=\"model === true\">YES</span>\n <span v-else></span>\n </span>\n <label\n :for=\"leftId\"\n class=\"g-toggle-option g-left\"\n @click=\"onClickLabel(false)\"\n @keydown=\"onLabelKeydown\"\n >\n <input\n type=\"radio\"\n :id=\"leftId\"\n :name=\"radioName\"\n :checked=\"model === false\"\n value=\"false\"\n :disabled=\"disabled\"\n @change=\"onChange(false)\"\n /><span class=\"ilw-sr-only\">No</span>\n </label>\n <label\n :for=\"centerId\"\n class=\"g-toggle-option g-center\"\n @keydown=\"onLabelKeydown\"\n >\n <input\n type=\"radio\"\n :id=\"centerId\"\n :name=\"radioName\"\n :checked=\"model === null\"\n :disabled=\"disabled\"\n @change=\"onChange(null)\"\n /><span class=\"ilw-sr-only\">Unset</span>\n </label>\n <label\n :for=\"rightId\"\n class=\"g-toggle-option g-right\"\n @click=\"onClickLabel(true)\"\n @keydown=\"onLabelKeydown\"\n >\n <input\n type=\"radio\"\n :id=\"rightId\"\n :name=\"radioName\"\n value=\"true\"\n :checked=\"model === true\"\n :disabled=\"disabled\"\n @change=\"onChange(true)\"\n /><span class=\"ilw-sr-only\">Yes</span>\n </label>\n </div>\n </fieldset>\n </div>\n <div\n v-if=\"error\"\n :id=\"`${id}-error`\"\n class=\"g-form-error\"\n role=\"alert\"\n aria-atomic=\"true\"\n >\n {{ error }}\n </div>\n </div>\n</template>\n\n<style scoped>\n.g-three-way-toggle-control {\n display: flex;\n margin-bottom: 4px;\n column-gap: 8px;\n\n .g-label {\n flex: 1;\n font-weight: 600;\n font-size: 0.875rem;\n line-height: 1;\n align-self: center;\n display: block;\n }\n}\n\n.g-three-way-toggle {\n border: none;\n padding: 0;\n margin: 0;\n width: 50px;\n background: none;\n border-radius: 12px;\n\n &:focus-within {\n outline: 2px solid var(--il-blue);\n outline-offset: 2px;\n box-shadow: 0 0 0 2px var(--g-info-200);\n }\n}\n\n.g-toggle-track {\n display: flex;\n position: relative;\n background: var(--g-surface-700);\n border-radius: 14px;\n height: 24px;\n width: 100%;\n min-width: 50px;\n box-sizing: border-box;\n font-family: var(--il-font-sans);\n\n &.g-left {\n background: var(--il-industrial);\n }\n &.g-right {\n background: var(--il-prairie);\n }\n &.g-disabled {\n pointer-events: none;\n background: var(--g-surface-400);\n }\n}\n\n.g-toggle-thumb {\n position: absolute;\n top: 2px;\n width: 20px;\n height: 20px;\n background: var(--g-surface-100);\n border-radius: 50%;\n left: 2px;\n z-index: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n color: var(--g-surface-0);\n font-weight: 700;\n transition:\n left 0.1s ease-in-out,\n background-color 0.1s ease-in-out;\n letter-spacing: -0.5px;\n &.g-left {\n color: var(--il-industrial);\n }\n &.g-right {\n color: var(--il-prairie);\n letter-spacing: -1.5px;\n }\n}\n.g-toggle-track.g-left .g-toggle-thumb {\n left: 2px;\n}\n.g-toggle-track.g-center .g-toggle-thumb {\n left: calc(50% - 10px);\n}\n.g-toggle-track.g-right .g-toggle-thumb {\n left: calc(100% - 20px - 2px);\n}\n\n@media (prefers-reduced-motion: reduce) {\n .g-toggle-thumb {\n transition: none;\n }\n}\n\n.g-toggle-option {\n flex: 1 1 0;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n &.g-center {\n flex: 0 0 1%;\n }\n}\n.g-toggle-option input[type=\"radio\"] {\n position: absolute;\n opacity: 0;\n width: 100%;\n height: 100%;\n left: 0;\n top: 0;\n margin: 0;\n cursor: pointer;\n z-index: 2;\n}\n\n.g-has-error {\n .g-toggle-track {\n background: var(--g-danger-500);\n }\n}\n.g-form-error {\n color: var(--g-danger-600);\n font-size: 0.875rem;\n font-weight: bold;\n}\n</style>\n","<script setup lang=\"ts\" generic=\"T extends TableRow, C extends TableColumn<T>\">\nimport { computed, ref, type VNode } from \"vue\";\nimport { TableColumn, TableRow } from \"./TableColumn.ts\";\nimport { UseTableChangesReturn } from \"../../compose/useTableChanges.ts\";\n\ntype Props = {\n data: T[];\n groupBy?: keyof T;\n columns: C[];\n groupRender?: (groupValue: any, row: T) => VNode;\n rowClickable?: boolean;\n rowClass?: (row: T) => string | string[] | undefined;\n startIndex: number;\n bulkSelectionEnabled?: boolean;\n selectedRows?: string[];\n tableId: string;\n changeTracker?: UseTableChangesReturn<T>;\n};\n\nconst props = defineProps<Props>();\n\nconst emit = defineEmits<{\n (e: \"row-click\", link: string): void;\n (e: \"toggle-row\", rowKey: string, shiftKey: boolean): void;\n (e: \"cell-change\", payload: { row: T; column: C; value: any }): void;\n}>();\n\n\nfunction handleMouseDown(event: MouseEvent, rowKey: string) {\n // Prevent text selection when shift-clicking for bulk selection\n // Only if bulk selection is enabled and shift is held and we're not on an input\n if (\n props.bulkSelectionEnabled &&\n event.shiftKey &&\n !(event.target as HTMLElement).closest(\"a,button,[tabindex],input\")\n ) {\n event.preventDefault();\n }\n}\n\nfunction handleRowClick(event: MouseEvent, rowKey: string) {\n if (!props.rowClickable && !props.bulkSelectionEnabled) {\n return; // Do nothing if rows are not clickable\n }\n // Only trigger if not clicking on a link or button directly\n if ((event.target as HTMLElement).closest(\"a,button,[tabindex],input\")) {\n return;\n }\n const row = (event.target as HTMLElement).closest(\n \"tr\",\n ) as HTMLTableRowElement;\n if (row) {\n if (props.bulkSelectionEnabled) {\n let checkbox = row.querySelector(\n \"input[type=checkbox]\",\n ) as HTMLInputElement | null;\n if (checkbox) {\n // Trigger the checkbox change with shift key info\n handleCheckboxChange(rowKey, event.shiftKey);\n }\n } else if (props.rowClickable) {\n const firstLink = row.querySelector(\"a[href]\");\n const link = firstLink?.getAttribute(\"href\");\n if (link) {\n emit(\"row-click\", link);\n }\n }\n }\n}\n\nfunction isRowSelected(rowKey: string): boolean {\n return props.selectedRows?.includes(rowKey) ?? false;\n}\n\nfunction handleCheckboxChange(rowKey: string, shiftKey: boolean = false) {\n emit(\"toggle-row\", rowKey, shiftKey);\n}\n\nfunction handleCellChange(event: Event, row: T, col: C) {\n const target = event.target as unknown as\n | HTMLInputElement\n | HTMLSelectElement;\n const value = target.value;\n emit(\"cell-change\", { row, column: col, value });\n}\n\nfunction buildAriaLabelledBy(row: T, col: C): string {\n const columnHeaderId = `${props.tableId}-th-${String(col.key)}`;\n\n // If labelKey is specified, add the label cell ID\n if (col.editable?.labelKey) {\n const labelCellId = `${props.tableId}-td-${row.key}-${col.editable.labelKey}`;\n return `${labelCellId} ${columnHeaderId} `;\n }\n\n return columnHeaderId;\n}\n\nconst labelCellColumn = computed(() => {\n for (const col of props.columns) {\n if (col.editable?.labelKey) {\n return col.editable.labelKey;\n }\n }\n return undefined;\n }\n);\n\nfunction shouldAddCellId(col: C): boolean {\n // Check if this column is used as a label for any editable column\n return col.key === labelCellColumn.value;\n}\n\nfunction hasCellChange(row: T, col: C): boolean {\n if (!props.changeTracker) return false;\n return props.changeTracker.hasChange(row.key, col.key);\n}\n\nfunction hasCellError(row: T, col: C): boolean {\n if (!props.changeTracker) return false;\n return props.changeTracker.hasError(row.key, col.key);\n}\nfunction getCellError(row: T, col: C): string | undefined {\n if (!props.changeTracker) return undefined;\n return props.changeTracker.getError(row.key, col.key);\n}\n\n</script>\n\n<template>\n <tbody ref=\"tableBodyRef\" class=\"efficient-table-body\">\n <template v-for=\"(row, idx) in data\" :key=\"row.key\">\n <tr\n v-if=\"\n groupBy &&\n (idx === 0 || row[groupBy] !== data[idx - 1][groupBy])\n \"\n :aria-rowindex=\"startIndex + idx + 2\"\n >\n <td\n v-if=\"bulkSelectionEnabled\"\n class=\"table-group-checkbox\"\n ></td>\n <td :colspan=\"columns.length\" class=\"table-group-row\">\n <template v-if=\"groupRender\">\n <component :is=\"groupRender(row[groupBy], row)\" />\n </template>\n <template v-else>\n {{ row[groupBy] }}\n </template>\n </td>\n </tr>\n\n <tr\n :class=\"[\n 'efficient-table-row',\n {\n 'row-striped': idx % 2 === 1,\n 'row-clickable': rowClickable || bulkSelectionEnabled,\n },\n rowClass ? rowClass(row) : undefined,\n ]\"\n :aria-rowindex=\"startIndex + idx + 2\"\n @mousedown=\"handleMouseDown($event, row.key)\"\n @click=\"handleRowClick($event, row.key)\"\n >\n <td v-if=\"bulkSelectionEnabled\" class=\"td-checkbox\" @click.stop>\n <input\n type=\"checkbox\"\n :checked=\"isRowSelected(row.key)\"\n @click=\"(e) => handleCheckboxChange(row.key, e.shiftKey)\"\n :aria-label=\"`Select row ${row.key}`\"\n :name=\"`row-${row.key}-checkbox`\"\n class=\"g-bulk-select-checkbox\"\n />\n </td>\n\n <td\n v-for=\"col in columns\"\n :key=\"col.key\"\n :id=\"\n shouldAddCellId(col)\n ? `${tableId}-td-${row.key}-${String(col.key)}`\n : undefined\n \"\n :class=\"[\n col.editable ? 'editable-td' : '',\n hasCellChange(row, col) ? 'g-cell-changed' : '',\n hasCellError(row, col) ? 'g-cell-error' : '',\n typeof col.tdClass === 'function'\n ? col.tdClass(row)\n : col.tdClass,\n ]\"\n >\n <div v-if=\"col.editable\" class=\"editable-cell\">\n <span v-if=\"col.editable.prefix\" class=\"cell-prefix\">{{\n col.editable.prefix\n }}</span>\n <select\n v-if=\"col.editable.type === 'select'\"\n :value=\"row[col.key]\"\n @change=\"handleCellChange($event, row, col)\"\n :aria-labelledby=\"buildAriaLabelledBy(row, col)\"\n :aria-invalid=\"hasCellError(row, col)\"\n :name=\"`row-${row.key}-${String(col.key)}-select`\"\n class=\"editable-input editable-select\"\n >\n <option\n v-for=\"option in col.editable.options\"\n :key=\"option.value\"\n :value=\"option.value\"\n >\n {{ option.label }}\n </option>\n </select>\n <input\n v-else\n :value=\"row[col.key]\"\n v-bind=\"col.editable.inputAttributes\"\n @input=\"handleCellChange($event, row, col)\"\n :aria-labelledby=\"buildAriaLabelledBy(row, col)\"\n :aria-invalid=\"hasCellError(row, col)\"\n :aria-errormessage=\"hasCellError(row, col) ? `${tableId}-error-${row.key}-${String(col.key)}` : undefined\"\n :name=\"`row-${row.key}-${String(col.key)}-input`\"\n class=\"editable-input\"\n :style=\"{\n paddingLeft: col.editable.prefix\n ? '1.5rem'\n : undefined,\n paddingRight: col.editable.suffix\n ? '2rem'\n : undefined,\n }\"\n />\n <span v-if=\"col.editable.suffix\" class=\"cell-suffix\">{{\n col.editable.suffix\n }}</span>\n </div>\n <component v-else-if=\"col.display\" :is=\"col.display(row)\" />\n <template v-else>{{ row[col.key] }}</template>\n <div v-if=\"hasCellError(row, col)\" role=\"alert\" class=\"g-cell-error-message\" :id=\"`${tableId}-error-${row.key}-${String(col.key)}`\">\n {{ getCellError(row, col) }}\n </div>\n </td>\n </tr>\n </template>\n </tbody>\n</template>\n\n<style>\n.efficient-table-body {\n th,\n td {\n padding: 0.4rem 0.2rem;\n }\n\n td.editable-td {\n padding: 0;\n border-right: 1px solid var(--g-surface-300);\n border-bottom: 1px solid var(--g-surface-300);\n }\n\n /* Add left border to first editable cell or after non-editable cell */\n td.editable-td:first-child,\n td:not(.editable-td) + td.editable-td {\n border-left: 1px solid var(--g-surface-300);\n }\n\n /* Add top border to editable cells in first row */\n tr:first-child td.editable-td {\n border-top: 1px solid var(--g-surface-300);\n }\n\n .table-group-row {\n font-weight: 600;\n background: var(--g-surface-0);\n padding: 1rem;\n font-size: 1.25rem;\n border-bottom: 1px solid var(--g-accent-500);\n }\n\n .table-group-checkbox {\n width: 50px;\n background: var(--g-surface-0);\n }\n\n .td-checkbox {\n width: 50px;\n text-align: center;\n padding: 0.4rem;\n }\n\n .g-bulk-select-checkbox {\n width: 20px;\n height: 20px;\n cursor: pointer;\n accent-color: var(--g-primary-500);\n }\n}\n\n.row-striped {\n background-color: var(--g-surface-100);\n}\n\n.efficient-table-row.row-clickable {\n cursor: pointer;\n}\n\n.efficient-table-row.row-clickable:hover {\n background-color: var(--ilw-color--focus--background);\n}\n\n.efficient-table-row.row-clickable:hover td,\n.efficient-table-row.row-clickable:hover a,\n.efficient-table-row.row-clickable:hover span,\n.efficient-table-row.row-clickable:hover strong {\n text-decoration: underline;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .efficient-table-row.row-clickable,\n .efficient-table-row.row-clickable:hover {\n transition: none !important;\n }\n}\n\n.editable-cell {\n position: relative;\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.editable-input {\n width: 100%;\n padding: 0.4rem 0.5rem 0.4rem 0.75rem;\n border: none;\n border-radius: 0;\n font-size: 1rem;\n font-family: var(--il-font-sans);\n background: transparent;\n box-sizing: border-box;\n}\n\n.editable-input:focus {\n outline: 2px solid var(--g-primary-500);\n outline-offset: -2px;\n background: var(--g-surface-0);\n}\n\n.editable-select {\n cursor: pointer;\n}\n\n.cell-prefix,\n.cell-suffix {\n position: absolute;\n font-size: 1rem;\n color: var(--g-surface-600);\n pointer-events: none;\n top: 50%;\n transform: translateY(-50%);\n}\n\n.cell-prefix {\n left: 0.5rem;\n}\n\n.cell-suffix {\n right: 0.5rem;\n}\n\n/* Highlight cells that have been changed by the user */\n.g-cell-changed {\n background: rgba(101, 199, 255, 0.29);\n}\n\n/* Highlight cells with errors */\n.g-cell-error {\n background: var(--g-danger-100);\n position: relative;\n}\n\n.g-cell-error-message {\n background: var(--g-danger-500);\n color: var(--g-surface-0);\n font-size: 0.875rem;\n padding: 0.25rem 0.5rem;\n}\n\n.g-cell-error .editable-input[aria-invalid=\"true\"]:focus {\n outline-color: var(--g-danger-500);\n}\n</style>\n","import {\n computed,\n Reactive,\n reactive,\n ref,\n type Ref,\n toRaw,\n toValue,\n unref,\n watch,\n} from \"vue\";\n\nexport type FilterLocationQueryValueRaw = string | number;\n\n/**\n * Query representation for filtering, compatible with vue-router\n */\nexport type FilterLocationQuery = {\n [p: string]:\n | string\n | null\n | number\n | undefined\n | FilterLocationQueryValueRaw[];\n};\n\nexport interface FilteringOptions {\n syncWith?: Ref<{\n [p: string]: string | null | (string | null)[] | undefined;\n }>;\n}\n\n/**\n * Represents a type that defines a set of filters for a given record type.\n * The keys are based on the record, and the values are possible values\n * for a filter.\n */\nexport type FiltersForRecord<\n T extends object,\n F extends { [K in keyof T]?: any },\n> = {\n [K in keyof T]?: T[K] extends string | number | boolean | undefined | null\n ? T[K] | string | string[]\n : T[K] extends string[] | number[]\n ? T[K][]\n : never;\n};\n\n/**\n * Represents the return type of a composition function used for handling\n * filtering logic in a data structure.\n */\nexport interface UseFilteringReturn<\n T extends Record<string, any> = Record<string, any>,\n F extends { [K in keyof T]?: any } = Record<keyof T, any>,\n> {\n filters: Reactive<F>;\n isFiltered: Ref<boolean>;\n clearFilters: () => void;\n filteredColumns: Ref<Partial<Record<keyof T, boolean>>>;\n}\n\n/**\n * Returns the value if it's not empty, or undefined if it's empty.\n */\nexport function emptyAsUndefined<\n T extends\n | string\n | number\n | boolean\n | string[]\n | number[]\n | undefined\n | null,\n>(value: T) {\n if (Array.isArray(value)) {\n if (value.length === 0) {\n return undefined;\n }\n }\n if (value === null || value === false || value === \"\") {\n return undefined;\n }\n return value;\n}\n\nexport function filterOmitEmpty<T extends object>(value: T): Partial<T> {\n return Object.fromEntries(\n Object.entries(value).filter(([k, v]) => {\n return v && (!Array.isArray(v) || v.length > 0);\n }),\n ) as Partial<T>;\n}\n\n/**\n * Return a value as an array if it's not already one, or\n * undefined if it's undefined.\n */\nexport function asArray<T>(value: T | T[]): NonNullable<T>[] | undefined {\n if (value === undefined || value === null) {\n return undefined;\n }\n if (Array.isArray(value)) {\n // Exclude null and undefined from array\n return value.filter(\n (v) => v !== null && v !== undefined,\n ) as NonNullable<T>[];\n }\n return [value];\n}\n\n/**\n * Converts filter criteria into a format suitable for use as a query object\n * in vue-router.\n */\nexport function filterAsQuery<\n T extends Record<string, any>,\n F extends { [K in keyof T]?: any } = Record<keyof T, any>,\n>(filters: FiltersForRecord<T, F>): FilterLocationQuery {\n let query: FilterLocationQuery = {};\n for (let [key, value] of Object.entries(toRaw(filters))) {\n if (Array.isArray(value)) {\n if (value.length > 0) {\n query[key] = value;\n }\n } else if (value === true) {\n query[key] = \"true\";\n } else {\n query[key] = value || undefined;\n }\n }\n return query;\n}\n\n/**\n * Converts an object of filters into a query parameters object for API calls.\n *\n * Transforms the values into strings or arrays of strings. Excludes fields with undefined,\n * null, empty string, or false values. Supports single values and arrays.\n */\nexport function filtersToQueryParams<T extends Record<string, any>>(\n filters: T,\n): Record<keyof T, string | string[]> {\n const query: Record<string, string | string[]> = {};\n Object.keys(filters).forEach((key) => {\n const value = filters[key];\n if (\n value !== undefined &&\n value !== null &&\n value !== \"\" &&\n value !== false\n ) {\n if (Array.isArray(value)) {\n if (value.length > 0) {\n query[key] = value.map((v) => String(v));\n }\n } else {\n query[key] = String(value);\n }\n }\n });\n return query as Record<keyof T, string | string[]>;\n}\n\n/**\n * Provides a mechanism to manage and synchronize filterable data with given filters and options.\n *\n * @param filters An object that defines the filters applicable to the data record.\n * @param options Configuration options for filtering, such as synchronization.\n * @return Returns an object that can be used with GTable.\n */\nexport function useFiltering<\n T extends Record<string, any> = Record<string, any>,\n F extends { [K in keyof T]?: any } = Record<keyof T, any>,\n>(filters: F, options: FilteringOptions = {}): UseFilteringReturn<T, F> {\n const values = reactive<T>(\n Object.fromEntries(\n Object.entries(filters).map(([key, val]) => [key, val]),\n ) as any,\n );\n const syncWith = options.syncWith;\n\n if (syncWith) {\n if (syncWith.value) {\n const queryParams = toValue(syncWith);\n Object.keys(filters).forEach((key) => {\n if (queryParams[key] !== undefined) {\n // Handle arrays as a comma-separated string\n const val = queryParams[key];\n if (typeof val === \"string\") {\n if (val.includes(\",\")) {\n values[key] = val.split(\",\");\n } else {\n values[key] = val;\n }\n }\n }\n });\n }\n\n watch(\n values,\n (newValues) => {\n syncWith.value = filtersToQueryParams(newValues);\n },\n { deep: true },\n );\n }\n\n const isFiltered = computed(() => {\n for (const key of Object.keys(filters)) {\n if (!!emptyAsUndefined(values[key])) {\n return true;\n }\n }\n return false;\n });\n\n const clearFilters = () => {\n Object.keys(values).forEach((key) => {\n values[key] = undefined;\n });\n };\n\n const filteredColumns = computed(() => {\n const result: Record<string, boolean> = {};\n for (const key of Object.keys(filters)) {\n result[key] = !!emptyAsUndefined(values[key]);\n }\n return result as Record<keyof T, boolean>;\n });\n\n return {\n filters: values as any,\n isFiltered,\n clearFilters,\n filteredColumns,\n };\n}\n","<script setup lang=\"ts\" generic=\"T extends TableRow, C extends TableColumn<T>\">\n/**\n * A data table component with support for grouping, sorting, filtering, and pagination.\n *\n * A heavy focus has been on performance. The table body doesn't use any\n * Vue components, it's pure render functions. We've used it with\n * 4000 rows and 14 columns loaded without issues.\n *\n * This is a bit complicated to use, so an example has been omitted here.\n * Instead, look at the source for this demo: [GTable Demo Source](https://github.com/graduatecollege/grad-vue/blob/main/demo/components/demo/GTableDemo.vue).\n *\n * Here are some of the key points.\n *\n * Table content is provided with:\n * - `columns` configuration using the `TableColumn` type.\n * - At minimum the configuration must include `key` for which field of the data\n * objects to use, and `label` for the column header.\n * - `sortable: true` makes the column sortable.\n * - `filter` can be used to provide a `TableColumnFilter` configuration.\n * - `display` accepts a custom render function for the column data.\n * - `trClass` and `tdClass` can be used to provide custom classes for table rows and cells.\n * - `data` array with objects containing fields for the columns.\n *\n * Rows can be made clickable with `row-clickable`. In this case, one of the\n * cells must contain a link. Clicking a row will emit a `row-click` event\n * with the link `href` from the first link in the row.\n *\n * Grouping can be enabled by passing a column key to `groupBy`.\n */\nimport GTableBody from \"./table/GTableBody.vue\";\nimport GPopover from \"./GPopover.vue\";\nimport { TableColumn, TableRow } from \"./table/TableColumn.ts\";\nimport {\n computed,\n onMounted,\n ref,\n toRaw,\n useId,\n useSlots,\n useTemplateRef,\n VNode,\n watch,\n} from \"vue\";\nimport GSelect from \"./GSelect.vue\";\nimport { useFiltering, UseFilteringReturn } from \"../compose/useFiltering.ts\";\nimport {\n CellChangePayload,\n UseTableChangesReturn,\n} from \"../compose/useTableChanges.ts\";\nimport GButton from \"./GButton.vue\";\n\nexport interface BulkAction {\n /**\n * Action identifier\n */\n id: string;\n /**\n * Action label\n */\n label: string;\n /**\n * Action theme/color\n */\n theme?: \"primary\" | \"secondary\" | \"accent\" | \"danger\";\n}\n\ntype Props = {\n /**\n * Accessible label\n */\n label: string; // Demo: Colleges\n data: T[];\n columns: C[];\n resultCount?: number;\n groupBy?: keyof T;\n filtering?: UseFilteringReturn<any>;\n groupRender?: (groupValue: any, row: T) => VNode;\n rowClickable?: boolean;\n rowClass?: (row: T) => string | string[] | undefined;\n startIndex: number;\n /**\n * Enable bulk selection with checkboxes\n */\n bulkSelectionEnabled?: boolean;\n // Array of actions to show in the sticky toolbar when rows are selected\n bulkActions?: BulkAction[];\n\n // Optional change tracker for editable tables\n // Pass a composable from useTableChanges() to track user edits\n changeTracker?: UseTableChangesReturn<T>;\n\n /**\n * Explicitly show the pagination bar even if the slot is empty\n */\n showPagination?: boolean;\n};\n\nconst sortField = defineModel<keyof T>(\"sortField\");\nconst sortOrder = defineModel<1 | -1>(\"sortOrder\");\nconst filter = defineModel<Partial<Record<keyof T, any>>>(\"filter\", {\n default: () => ({}),\n});\nconst selectedRows = defineModel<string[]>(\"selectedRows\", {\n default: () => [],\n});\n\nconst props = withDefaults(defineProps<Props>(), {\n bulkSelectionEnabled: false,\n bulkActions: () => [],\n showPagination: false,\n});\n\nconst emit = defineEmits<{\n (e: \"row-click\", link: string): void;\n (e: \"bulk-action\", actionId: string, selectedKeys: string[]): void;\n (e: \"cell-change\", payload: CellChangePayload<T>): void;\n}>();\n\nfunction onSort(col: TableColumn<T>) {\n if (!col.sortable) {\n return;\n }\n if (sortField.value === col.key) {\n if (sortOrder.value === 1) {\n sortOrder.value = -1;\n } else if (sortOrder.value === -1) {\n sortField.value = undefined as any;\n sortOrder.value = 1;\n }\n } else {\n sortField.value = col.key;\n sortOrder.value = 1;\n }\n}\n\nlet filtering: UseFilteringReturn<any> = props.filtering!;\n\nif (!filtering) {\n filtering = useFiltering({}) as any;\n}\n\nconst { filters, filteredColumns, isFiltered, clearFilters } = filtering;\n\n// Bulk selection logic\nconst allRowKeys = computed(() => props.data.map((row) => row.key));\nconst selectedRowsOnPage = computed(() => {\n return selectedRows.value.filter((key) => allRowKeys.value.includes(key));\n});\nconst allSelected = computed(() => {\n if (!props.bulkSelectionEnabled || props.data.length === 0) {\n return false;\n }\n return selectedRowsOnPage.value.length === allRowKeys.value.length;\n});\nconst someSelected = computed(() => {\n if (!props.bulkSelectionEnabled || props.data.length === 0) {\n return false;\n }\n return (\n selectedRowsOnPage.value.length > 0 &&\n selectedRowsOnPage.value.length < allRowKeys.value.length\n );\n});\n\nconst lastClickedRowKey = ref<string | null>(null);\n\nfunction toggleAllRows() {\n if (allSelected.value) {\n // Deselect all rows on current page\n selectedRows.value = selectedRows.value.filter(\n (key) => !allRowKeys.value.includes(key),\n );\n } else {\n // Select all rows on current page\n const newSelected = new Set(selectedRows.value);\n allRowKeys.value.forEach((key) => newSelected.add(key));\n selectedRows.value = Array.from(newSelected);\n }\n}\n\nfunction toggleRow(rowKey: string, shiftKey: boolean = false) {\n if (shiftKey && lastClickedRowKey.value) {\n // Handle shift-click range selection\n const lastIndex = allRowKeys.value.indexOf(lastClickedRowKey.value);\n const currentIndex = allRowKeys.value.indexOf(rowKey);\n\n if (lastIndex !== -1 && currentIndex !== -1) {\n const start = Math.min(lastIndex, currentIndex);\n const end = Math.max(lastIndex, currentIndex);\n const rowsInRange = allRowKeys.value.slice(start, end + 1);\n\n // Select all rows in the range\n const newSelected = new Set(selectedRows.value);\n rowsInRange.forEach((key) => newSelected.add(key));\n selectedRows.value = Array.from(newSelected);\n }\n } else {\n // Normal toggle behavior\n if (selectedRows.value.includes(rowKey)) {\n selectedRows.value = selectedRows.value.filter(\n (key) => key !== rowKey,\n );\n } else {\n selectedRows.value = [...selectedRows.value, rowKey];\n }\n }\n\n // Update last clicked row\n lastClickedRowKey.value = rowKey;\n}\n\nfunction clickRow(link: string) {\n emit(\"row-click\", link);\n}\n\nfunction handleBulkAction(actionId: string) {\n emit(\"bulk-action\", actionId, selectedRows.value);\n}\n\nfunction handleCellChange(change: { row: T; column: C; value: any }) {\n // Update the reactive data\n // Convert the value to the appropriate type based on input attributes\n let convertedValue: any = change.value;\n const columnKey = change.column.key;\n const previousValue = toRaw(change.row[columnKey]);\n if (change.column.editable?.inputAttributes?.type === \"number\") {\n convertedValue = change.value === \"\" ? null : Number(change.value);\n }\n change.row[columnKey] = convertedValue;\n\n const payload: CellChangePayload<T> = {\n row: change.row,\n column: change.column,\n value: convertedValue,\n previousValue,\n };\n\n emit(\"cell-change\", payload);\n}\n\nconst id = useId();\nconst slots = useSlots();\n\nconst shouldShowPagination = computed(() => {\n // Show if explicitly requested via prop\n if (props.showPagination) {\n return true;\n }\n // Show if the pagination slot has content\n return !!slots.pagination;\n});\n\nconst shouldShowControls = computed(() => {\n // Show if filters are active (clear filters button is visible)\n if (isFiltered.value) {\n return true;\n }\n // Show if pagination should be shown\n if (shouldShowPagination.value) {\n return true;\n }\n // Otherwise hide the entire controls bar\n return false;\n});\n\nonMounted(() => {\n if (props.rowClickable && props.bulkSelectionEnabled) {\n console.warn(\n \"GTable: rowClickable and bulkSelectionEnabled cannot be used together. rowClickable will be ignored.\",\n );\n }\n for (const col of props.columns) {\n if (col.editable && col.display) {\n console.warn(\n `GTable: Column \"${String(col.key)}\" has both 'editable' and 'display' configured. 'display' will be ignored.`,\n );\n }\n if (col.filter && col.filter.type === \"multi-select\") {\n if (!Array.isArray(filter.value[col.key])) {\n let val = filter.value[col.key];\n filter.value[col.key] = val ? [val] : [];\n }\n }\n }\n});\n\nwatch(\n () => props.columns,\n (newColumns) => {\n for (const col of newColumns) {\n if (col.filter && col.filter.type === \"multi-select\") {\n if (!Array.isArray(filter.value[col.key])) {\n let val = filter.value[col.key];\n filter.value[col.key] = val ? [val] : [];\n }\n }\n }\n },\n { immediate: true },\n);\n</script>\n\n<template>\n <div class=\"g-table-outer-wrap\">\n <div v-if=\"shouldShowControls\" class=\"g-table-controls\">\n <div class=\"g-clear-filters-wrap\">\n <GButton\n v-if=\"isFiltered\"\n outlined\n size=\"small\"\n class=\"clear-filters\"\n @click=\"clearFilters\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 51.26 51.26\"\n height=\"1em\"\n aria-hidden=\"true\"\n >\n <path\n fill=\"currentColor\"\n d=\"m37.84 32.94-7.63-7.63 7.63-7.63a3.24 3.24 0 0 0-4.58-4.58l-7.63 7.63L18 13.1a3.24 3.24 0 0 0-4.58 4.58L21 25.31l-7.62 7.63A3.24 3.24 0 1 0 18 37.52l7.63-7.63 7.63 7.63a3.24 3.24 0 0 0 4.58-4.58Z\"\n />\n </svg>\n <span class=\"g-clear-filters-text\"> Clear Filters </span>\n </GButton>\n </div>\n <div v-if=\"shouldShowPagination\" class=\"pagination\">\n <slot name=\"pagination\"></slot>\n </div>\n <span class=\"g-result-count\"\n >{{ props.resultCount || data.length }} results</span\n >\n </div>\n <table\n class=\"g-table\"\n ref=\"tableRef\"\n :aria-label=\"label\"\n :aria-rowcount=\"props.resultCount || data.length\"\n >\n <thead class=\"g-table-head\">\n <tr aria-rowindex=\"1\">\n <th\n v-if=\"bulkSelectionEnabled\"\n scope=\"col\"\n class=\"g-th g-th-checkbox\"\n >\n <input\n type=\"checkbox\"\n :checked=\"allSelected\"\n :indeterminate=\"someSelected\"\n @change=\"toggleAllRows\"\n :aria-label=\"\n allSelected\n ? 'Deselect all rows'\n : 'Select all rows'\n \"\n class=\"g-bulk-select-checkbox\"\n />\n </th>\n <th\n v-for=\"col in columns\"\n :key=\"col.key\"\n :id=\"`${id}-th-${String(col.key)}`\"\n :aria-sort=\"\n sortField === col.key\n ? sortOrder === 1\n ? 'ascending'\n : 'descending'\n : 'none'\n \"\n :class=\"[\n 'g-th',\n { sorted: sortField === col.key },\n { filtered: filteredColumns[col.key] },\n ]\"\n scope=\"col\"\n >\n <div class=\"th-inner\">\n <button\n v-if=\"col.sortable\"\n type=\"button\"\n class=\"g-column-head\"\n @click=\"onSort(col)\"\n >\n {{ col.label }}\n <span\n v-if=\"sortField === col.key\"\n class=\"sort-indicator\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 640 640\"\n height=\"1.5em\"\n role=\"img\"\n :aria-label=\"\n sortOrder === 1\n ? 'Sorted ascending'\n : 'Sorted descending'\n \"\n :style=\"{\n transform: `rotate(${sortOrder === 1 ? 0 : 180}deg)`,\n }\"\n >\n <!--!Font Awesome Free v7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.-->\n <path\n fill=\"currentColor\"\n d=\"M300.3 199.2C312.9 188.9 331.4 189.7 343.1 201.4L471.1 329.4C480.3 338.6 483 352.3 478 364.3C473 376.3 461.4 384 448.5 384L192.5 384C179.6 384 167.9 376.2 162.9 364.2C157.9 352.2 160.7 338.5 169.9 329.4L297.9 201.4L300.3 199.2z\"\n />\n </svg>\n </span>\n </button>\n <span v-else class=\"g-column-head\">{{\n col.label\n }}</span>\n <GPopover v-if=\"col.filter\">\n <template #trigger=\"{ toggle }\">\n <button\n @click.stop=\"toggle\"\n :aria-label=\"\n filteredColumns[col.key]\n ? 'Column Filtered'\n : 'Filter Column'\n \"\n class=\"g-filter-btn\"\n :class=\"{\n 'g-active':\n filteredColumns[col.key],\n }\"\n type=\"button\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 640 640\"\n height=\"1.5em\"\n aria-hidden=\"true\"\n >\n <!--!Font Awesome Free v7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.-->\n <path\n fill=\"currentColor\"\n d=\"M96 128C83.1 128 71.4 135.8 66.4 147.8C61.4 159.8 64.2 173.5 73.4 182.6L256 365.3L256 480C256 488.5 259.4 496.6 265.4 502.6L329.4 566.6C338.6 575.8 352.3 578.5 364.3 573.5C376.3 568.5 384 556.9 384 544L384 365.3L566.6 182.7C575.8 173.5 578.5 159.8 573.5 147.8C568.5 135.8 556.9 128 544 128L96 128z\"\n />\n </svg>\n </button>\n </template>\n <GSelect\n v-if=\"col.filter.type === 'select'\"\n v-model=\"filter[col.key]\"\n :options=\"col.filter.options\"\n class=\"g-filter-select\"\n label=\"Filter select\"\n searchable\n clear-button\n />\n <div v-else-if=\"col.filter.type === 'toggle'\">\n <div class=\"g-filter-toggle\">\n <input\n type=\"checkbox\"\n v-model=\"filter[col.key]\"\n :id=\"`${id}-filter-${String(col.key)}`\"\n :aria-describedby=\"\n col.filter.description\n ? `${id}-filter-description-${String(col.key)}`\n : undefined\n \"\n />\n <label\n :for=\"`${id}-filter-${String(col.key)}`\"\n >{{ col.filter.label }}</label\n >\n <span\n class=\"g-filter-description\"\n v-if=\"col.filter.description\"\n :id=\"`${id}-filter-description-${String(col.key)}`\"\n >\n {{ col.filter.description }}\n </span>\n </div>\n </div>\n <fieldset\n v-else-if=\"\n col.filter.type === 'multi-select'\n \"\n class=\"g-multi-select\"\n >\n <legend class=\"g-multi-select-legend\">\n Include values\n </legend>\n <div\n v-for=\"opt in col.filter.options\"\n :key=\"opt.value\"\n >\n <input\n type=\"checkbox\"\n v-model=\"filter[col.key]\"\n :id=\"`filter-${String(col.key)}-${opt.value}`\"\n :value=\"opt.value\"\n name=\"filter-multiselect\"\n />\n <label\n :for=\"`filter-${String(col.key)}-${opt.value}`\"\n >{{ opt.label }}</label\n >\n </div>\n <GButton\n class=\"clear-multiselect-btn\"\n theme=\"accent\"\n size=\"small\"\n @click=\"filter[col.key] = []\"\n v-if=\"\n filter[col.key] &&\n filter[col.key].length\n \"\n >\n Clear\n </GButton>\n </fieldset>\n </GPopover>\n </div>\n </th>\n </tr>\n </thead>\n <!-- @vue-generic {T, C} -->\n <GTableBody\n :data=\"data\"\n :columns=\"columns\"\n :group-by=\"groupBy\"\n :group-render=\"groupRender\"\n :row-clickable=\"rowClickable\"\n :row-class=\"rowClass as any\"\n :start-index=\"startIndex\"\n :bulk-selection-enabled=\"bulkSelectionEnabled\"\n :selected-rows=\"selectedRows\"\n :table-id=\"id\"\n :change-tracker=\"changeTracker\"\n @row-click=\"clickRow\"\n @toggle-row=\"toggleRow\"\n @cell-change=\"handleCellChange\"\n />\n </table>\n <div\n v-if=\"bulkSelectionEnabled && selectedRows.length > 0\"\n class=\"g-bulk-actions-toolbar\"\n >\n <span class=\"g-selected-count\"\n >{{ selectedRows.length }} row{{\n selectedRows.length === 1 ? \"\" : \"s\"\n }}\n selected</span\n >\n <ul class=\"g-bulk-actions\">\n <li v-for=\"action in bulkActions\" :key=\"action.id\">\n <GButton\n :theme=\"action.theme || 'accent'\"\n @click=\"handleBulkAction(action.id)\"\n size=\"small\"\n >\n {{ action.label }} {{ selectedRows.length }} row{{\n selectedRows.length === 1 ? \"\" : \"s\"\n }}\n </GButton>\n </li>\n </ul>\n </div>\n </div>\n</template>\n\n<style scoped>\n.g-table-outer-wrap {\n}\n\n.g-table-controls {\n height: 40px;\n position: sticky;\n display: flex;\n top: 0;\n left: 0;\n padding: 2px 6px;\n}\n\n.g-table-head {\n background: var(--g-surface-0);\n position: sticky;\n top: 40px;\n z-index: 1;\n}\n\n.g-th {\n text-align: left;\n padding: 0.5rem 0.2rem;\n border: 0;\n border-bottom: 2px solid var(--g-surface-900);\n background: var(--g-surface-0);\n\n &.sorted {\n color: var(--ilw-color--link-hover);\n }\n\n &.filtered {\n .g-filter-btn {\n color: var(--ilw-color--link-hover);\n }\n }\n\n .th-inner {\n display: flex;\n align-items: center;\n }\n}\n\n.g-column-head {\n color: currentColor;\n position: relative;\n border: none;\n font-weight: 700;\n font-family: var(--il-font-sans);\n font-size: 1rem;\n line-height: 1.3;\n white-space: nowrap;\n padding-left: 4px;\n background: var(--g-surface-0);\n\n .sort-indicator {\n position: absolute;\n bottom: -1.1em;\n left: calc(50% - 0.7em);\n }\n}\n\nth:first-of-type .g-column-head {\n padding-left: 0;\n}\n\nbutton.g-column-head {\n cursor: pointer;\n height: 2rem;\n}\n\nbutton.g-column-head:hover {\n text-decoration: underline;\n color: var(--ilw-color--link-hover);\n}\n\n.g-table {\n border-spacing: 0;\n min-width: 100%;\n}\n\n.g-filter-btn {\n border: none;\n background: transparent;\n border-radius: 50%;\n width: 2rem;\n height: 2rem;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n\n &:hover {\n background: var(--g-primary-500);\n color: var(--g-primary-text);\n }\n\n &:focus {\n background: var(--ilw-color--focus--background);\n color: var(--ilw-color--focus--text);\n }\n\n &.g-active {\n border: 2px solid var(--ilw-color--link-hover);\n }\n}\n\n.g-clear-filters-text {\n white-space: nowrap;\n}\n\n@media screen and (max-width: 600px) {\n .g-clear-filters-text {\n opacity: 0;\n width: 1px;\n height: 1px;\n overflow: hidden;\n }\n}\n\n.g-filter-select {\n min-width: 200px;\n}\n\n.g-table-controls {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 1.5rem;\n padding: 0.2rem 1rem;\n background: var(--g-surface-150);\n\n .g-result-count {\n font-size: 1rem;\n line-height: 1.2;\n }\n}\n\n.g-multi-select {\n border: none;\n padding: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n\n .clear-multiselect-btn {\n margin-top: 0.5rem;\n }\n\n legend {\n font-size: 1.125rem;\n font-weight: bold;\n margin-bottom: 0.5rem;\n }\n\n div {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n\n &:has(:focus-visible) {\n outline: 2px solid var(--g-primary-500);\n }\n }\n\n input {\n width: 24px;\n height: 24px;\n accent-color: var(--g-primary-500);\n display: block;\n }\n\n label {\n font-size: 1.125rem;\n flex: 1;\n }\n}\n\n.g-multi-select-legend {\n margin: 0;\n padding: 0;\n font-size: 1rem;\n line-height: 1.2;\n}\n\n.g-filter-toggle {\n display: grid;\n grid-template-areas:\n \"label input\"\n \"description description\";\n\n grid-template-columns: auto 1fr;\n align-items: center;\n gap: 0.5rem;\n\n input {\n width: 24px;\n height: 24px;\n }\n\n label {\n font-size: 1.125rem;\n font-weight: bold;\n }\n\n .g-filter-description {\n grid-area: description;\n }\n}\n\n.g-clear-filters-wrap,\n.g-result-count {\n}\n\n/* Bulk selection styles */\n.g-th-checkbox {\n width: 50px;\n text-align: center;\n}\n\n.g-bulk-select-checkbox {\n width: 20px;\n height: 20px;\n cursor: pointer;\n accent-color: var(--g-primary-500);\n}\n\n.g-bulk-actions-toolbar {\n position: sticky;\n bottom: 0;\n left: 0;\n right: 0;\n background: var(--g-primary-500);\n color: var(--g-primary-text);\n padding: 0.75rem 1rem;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 1rem;\n box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.15);\n z-index: 1;\n\n ul {\n display: flex;\n gap: 1rem;\n list-style: none;\n padding: 0;\n margin: 0;\n }\n\n li {\n margin: 0;\n }\n}\n\n.g-selected-count {\n font-weight: 600;\n font-size: 1rem;\n}\n\n.g-bulk-actions {\n display: flex;\n gap: 0.5rem;\n align-items: center;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nconst props = defineProps<{\n start: number;\n pageSize: number;\n total: number;\n pageSizes?: number[];\n}>();\n\nconst totalPages = computed(() => {\n return Math.max(1, Math.ceil(props.total / props.pageSize));\n});\n\nconst startModel = defineModel<number>(\"start\");\nconst pageSizeModel = defineModel<number>(\"pageSize\");\n\nconst startVal = computed(() => startModel.value ?? props.start);\nconst pageSizeVal = computed(() => pageSizeModel.value ?? props.pageSize);\n\nconst startDisplay = computed(() => {\n if (props.total === 0) {\n return 0;\n }\n return startVal.value + 1;\n});\n\nconst end = computed(() => {\n if (props.total === 0) {\n return 0;\n }\n return Math.min(startVal.value + pageSizeVal.value, props.total);\n});\n\nconst currentPage = computed(() => {\n return Math.floor(startVal.value / pageSizeVal.value) + 1;\n});\n\nfunction goToPage(p: number) {\n if (p < 1 || p > totalPages.value) {\n return;\n }\n startModel.value = (p - 1) * pageSizeVal.value;\n}\n\nfunction onPageSizeChange(e: Event) {\n pageSizeModel.value = parseInt((e.target as HTMLSelectElement).value, 10);\n}\n</script>\n\n<template>\n <nav class=\"g-pagination\" aria-label=\"Pagination\">\n <button\n class=\"first-page g-pagination-button\"\n :disabled=\"currentPage === 1\"\n @click=\"goToPage(1)\"\n >\n <svg\n role=\"img\"\n aria-label=\"First Page\"\n height=\"2em\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"2em\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <!-- MIT License https://github.com/tabler/tabler-icons -->\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M11 7l-5 5l5 5\" />\n <path d=\"M17 7l-5 5l5 5\" />\n </svg>\n </button>\n <button\n class=\"prev-page g-pagination-button\"\n :disabled=\"currentPage === 1\"\n @click=\"goToPage(currentPage - 1)\"\n >\n <svg\n role=\"img\"\n aria-label=\"Previous Page\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"2em\"\n height=\"2em\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <!-- MIT License https://github.com/tabler/tabler-icons -->\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M15 6l-6 6l6 6\" />\n </svg>\n </button>\n <span class=\"page-range\"> {{ startDisplay }} to {{ end }} </span>\n <button\n class=\"next-page g-pagination-button\"\n :disabled=\"currentPage === totalPages\"\n @click=\"goToPage(currentPage + 1)\"\n >\n <svg\n role=\"img\"\n aria-label=\"Next Page\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"2em\"\n height=\"2em\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <!-- MIT License https://github.com/tabler/tabler-icons -->\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M9 6l6 6l-6 6\" />\n </svg>\n </button>\n <button\n class=\"last-page g-pagination-button\"\n :disabled=\"currentPage === totalPages\"\n @click=\"goToPage(totalPages)\"\n >\n <svg\n role=\"img\"\n aria-label=\"Last Page\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"2em\"\n height=\"2em\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <!-- MIT License https://github.com/tabler/tabler-icons -->\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M7 7l5 5l-5 5\" />\n <path d=\"M13 7l5 5l-5 5\" />\n </svg>\n </button>\n <select\n id=\"page-size-select\"\n class=\"page-size-select\"\n :value=\"pageSizeModel\"\n @change=\"onPageSizeChange\"\n >\n <option\n v-for=\"size in props.pageSizes || [10, 25, 50, 100]\"\n :key=\"size\"\n :value=\"size\"\n >\n {{ size }}\n </option>\n </select>\n <label class=\"page-size-label\" for=\"page-size-select\">per page</label>\n </nav>\n</template>\n\n<style scoped>\n.g-pagination {\n display: flex;\n align-items: center;\n gap: 0.1rem;\n font-size: 1rem;\n\n .g-pagination-button {\n background: transparent;\n border: none;\n color: var(--g-surface-900);\n padding: 0.2rem 0.4rem;\n border-radius: 4px;\n cursor: pointer;\n\n &:not(:disabled) {\n &:hover {\n background: var(--g-primary-500);\n color: var(--g-primary-text);\n }\n\n &:focus {\n background: var(--ilw-color--focus--background);\n color: var(--ilw-color--focus--text);\n }\n }\n }\n}\n.g-pagination button:disabled {\n cursor: auto;\n color: var(--g-surface-600);\n}\n.g-pagination .page-range {\n min-width: 3rem;\n text-align: center;\n}\n\n.g-pagination .page-size-select {\n margin-left: 1rem;\n margin-right: 0.5rem;\n padding: 0.2em 0.5em 0.2em 0.5em;\n border-radius: 0.2em;\n border: 2px solid var(--g-primary-500);\n background: var(--g-surface-0);\n color: var(--g-surface-900);\n cursor: pointer;\n font-size: 1rem;\n font-family: var(--il-font-sans);\n}\n.g-pagination .page-size-select:hover {\n}\n.g-pagination .page-size-select:focus {\n background: var(--ilw-color--focus--background);\n color: var(--ilw-color--focus--text);\n}\n.page-size-label {\n line-height: 1.2;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .g-pagination .page-size-select {\n transition: none;\n }\n}\n</style>\n","<script setup lang=\"ts\">\n/**\n * Generic modal component.\n *\n * Clicking on the outside or pressing the escape key will close the modal.\n *\n * > [!IMPORTANT]\n * >\n * > The surrounding page **must** have an element with the id `modal-root`,\n * > this modal will be teleported to it, so it can properly be over all\n * > other content. The `modal-root` should be somewhere near the end of the\n * > page structure.\n *\n * **Props**:\n *\n * - `label`: Modal accessible label.\n * - `describedby`: Element ID to pass to aria-describedby. Use this if there's\n * specific important text to describe the modal.\n * - `hiddenLabel`: Hide label visually. It will still be used as `aria-label`.\n * - `size`: Modal size\n *\n * **Slot** `default` is used as the content of the modal.\n *\n * When the modal is opened, focus is placed on the H2 label element. This\n * can be overridden by providing a `popover-focus` attribute on an element\n * inside the modal.\n *\n * Adding a dimming overlay behind modals can be done by placing `GOverlay`\n * at the end of the page structure.\n *\n * > [!WARNING]\n * > There are some shenanigans in the modal and overlay implementation in order\n * > to support Nuxt without including it as a dependency. Specifically, the refs\n * > to store the state of the overlay stack is added to `window._g_overlay_stack_state`\n * > when `document` is defined. That makes it only load in the client.\n */\n\nimport {\n computed,\n onBeforeMount,\n onMounted,\n ref,\n useId,\n useTemplateRef,\n} from \"vue\";\nimport { useOverlayStack } from \"../compose/useOverlayStack.ts\";\nimport { useOverlayFocus } from \"../compose/useOverlayFocus.ts\";\nimport { useOverlayEscape } from \"../compose/useOverlayEscape.ts\";\n\ninterface Props {\n /**\n * Modal label\n */\n label: string; // Demo: Basic Modal\n /**\n * ID for aria-describedby\n */\n describedby?: string;\n /**\n * Hide label\n */\n hiddenLabel?: boolean;\n /**\n * Modal size\n */\n size?: \"small\" | \"medium\" | \"large\" | \"full\";\n /**\n * Modal classes\n */\n classes?: string | string[];\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n describedby: undefined,\n hiddenLabel: false,\n size: \"medium\",\n});\n\nconst emit = defineEmits([\"close\"]);\n\nconst dialog = useTemplateRef(\"dialog\");\nconst open = ref(true);\n\nconst id = useId();\nconst { pop, push, isTop, zIndex } = useOverlayStack(id, true, true);\n\nconst { deactivate, activate } = useOverlayFocus(dialog, isTop);\n\nfunction close() {\n emit(\"close\");\n}\n\nuseOverlayEscape([dialog], isTop, open, close, pop);\n\nonMounted(() => {\n push();\n activate();\n});\n\nonBeforeMount(() => {\n pop();\n deactivate();\n});\n\nconst useClasses = computed(() => {\n let modalClasses = [`g-modal--${props.size}`];\n if (props.classes) {\n modalClasses = modalClasses.concat(Array.isArray(props.classes) ? props.classes : [props.classes]);\n }\n return modalClasses;\n});\n</script>\n\n<template>\n <Teleport to=\"#modal-root\">\n <Transition name=\"g-fade\" appear>\n <div\n :id=\"'modal-' + id\"\n class=\"g-modal\"\n :class=\"useClasses\"\n role=\"dialog\"\n aria-modal=\"true\"\n v-bind=\"{\n 'aria-labelledby': !hiddenLabel\n ? 'modal-label-' + id\n : undefined,\n 'aria-label': hiddenLabel ? label : undefined,\n 'aria-describedby': describedby ? describedby : undefined,\n }\"\n ref=\"dialog\"\n :style=\"{ zIndex }\"\n >\n <div class=\"g-modal-inner\">\n <div class=\"g-modal-header\">\n <h2\n v-if=\"!hiddenLabel\"\n :id=\"'modal-label-' + id\"\n class=\"g-modal-label\"\n tabindex=\"-1\"\n >\n {{ label }}\n </h2>\n <button\n class=\"g-modal-close\"\n @click=\"close\"\n aria-label=\"Close\"\n >\n <svg\n viewBox=\"0 0 24 24\"\n width=\"24\"\n height=\"24\"\n aria-hidden=\"true\"\n >\n <path\n fill=\"currentColor\"\n d=\"M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z\"\n />\n </svg>\n </button>\n </div>\n <div\n :id=\"'modal-description-' + id\"\n class=\"g-modal-content\"\n >\n <slot />\n </div>\n </div>\n </div>\n </Transition>\n </Teleport>\n</template>\n\n<style scoped>\n.g-modal {\n position: fixed;\n left: 50vw;\n top: 50vh;\n transform: translate(-50%, -50%);\n height: auto;\n max-height: 90vh;\n overflow-y: auto;\n background: var(--g-surface-50);\n border-top: 8px solid var(--g-accent-500);\n padding: 2rem;\n box-sizing: border-box;\n box-shadow:\n 0 0 2px rgba(0, 0, 0, 0.4),\n 0 10px 20px rgba(0, 0, 0, 0.1);\n}\n.g-modal--small {\n width: 400px;\n max-width: 90vw;\n}\n.g-modal--medium {\n width: 600px;\n max-width: 90vw;\n}\n.g-modal--large {\n width: 900px;\n max-width: 90vw;\n}\n.g-modal--full {\n width: 100vw;\n height: 100vh;\n max-width: none;\n max-height: none;\n border-top: none;\n}\n.g-modal-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n}\n.g-modal-label {\n font-family: var(--il-font-heading);\n font-size: 2rem;\n margin-top: 0;\n color: var(--g-primary-500);\n}\n.g-modal-close {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 0.5rem;\n margin: -1.25rem -1rem -1rem 1rem;\n color: var(--g-surface-600);\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n &:hover {\n background: var(--g-primary-500);\n color: var(--g-primary-text);\n }\n &:focus {\n background: var(--ilw-color--focus--background);\n color: var(--ilw-color--focus--text);\n }\n}\n</style>\n","<script setup lang=\"ts\">\n/**\n * A hamburger menu button that toggles a sidebar, intended for the\n * GAppHeader and GSidebar components.\n *\n * <span id=\"use-sidebar\">Use with the `useSidebar`</span> composable function\n * that takes care of passing state between the different components.\n *\n * Here's an example, this could be your App.vue or a layout file:\n *\n * ```vue\n * <script setup lang=\"ts\">\n * import { computed, h, onMounted, provide, ref, useTemplateRef } from \"vue\";\n * import { useSidebar } from \"../src/compose/useSidebar\";\n *\n * const sidebar = useSidebar();\n * provide(\"sidebar\", sidebar);\n *\n * // Or optionally a custom breakpoint\n * // const sidebar = useSidebar(\"(max-width: 600px)\");\n * </script>\n * ```\n *\n * As long as GHamburgerMenu and GSidebar are descendants of the component that\n * provides the sidebar, they will be able to communicate with each other.\n *\n * > [!NOTE]\n * > This button hides itself automatically according to the useSidebar media query.\n */\n\nimport { useSidebar } from \"../compose/useSidebar.ts\";\nimport { inject, useId } from \"vue\";\n\ninterface Props {\n /**\n * Accessible label\n */\n label?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n label: \"Main Navigation\",\n});\n\nconst sidebar = inject<ReturnType<typeof useSidebar>>(\"sidebar\")!;\n\nconst emit = defineEmits<{\n toggle: [];\n}>();\n\nfunction toggle() {\n emit(\"toggle\");\n sidebar?.toggle();\n}\n\n// Close menu on escape\nfunction handleEscapeKey(event: KeyboardEvent) {\n if (event.key === \"Escape\") {\n if (sidebar?.open?.value) {\n sidebar.open.value = false;\n }\n }\n}\n\nconst fallbackId = useId();\n</script>\n<template>\n <button\n :id=\"`${sidebar?.id ?? fallbackId}-hamburger`\"\n class=\"g-hamburger-button\"\n :class=\"{\n 'g-hamburger-button--open': sidebar?.open?.value,\n 'g-hamburger-button--collapsible': sidebar?.isCollapsible?.value\n }\"\n @click=\"toggle\"\n @keydown=\"handleEscapeKey\"\n :aria-expanded=\"sidebar?.open?.value ? 'true' : 'false'\"\n :aria-label=\"label\"\n :aria-controls=\"sidebar ? `${sidebar.id}-sidebar` : undefined\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 51.26 51.26\">\n <g fill=\"currentColor\">\n <path\n d=\"M11.6 16.52h28.06a3.24 3.24 0 1 0 0-6.48H11.6a3.24 3.24 0 0 0 0 6.48ZM39.66 22.07H11.6a3.24 3.24 0 0 0 0 6.48h28.06a3.24 3.24 0 1 0 0-6.48ZM39.66 34.1H11.6a3.24 3.24 0 0 0 0 6.48h28.06a3.24 3.24 0 1 0 0-6.48Z\"\n />\n </g>\n </svg>\n </button>\n</template>\n\n<style>\n.g-hamburger-button {\n svg {\n width: 1.6rem;\n }\n}\n</style>\n\n<style scoped>\n.g-hamburger-button {\n width: 34px;\n height: 34px;\n padding: 0;\n display: none;\n justify-content: center;\n align-items: center;\n text-decoration: none;\n border: 2px solid var(--g-primary-500);\n background: var(--g-primary-500);\n color: var(--g-primary-text);\n border-radius: 4px;\n cursor: pointer;\n\n &:hover {\n background: var(--g-primary-text);\n color: var(--g-primary-500);\n }\n &:active {\n background: var(--g-accent-500);\n color: var(--g-primary-text);\n }\n &:focus-visible {\n color: var(--ilw-color--focus--text);\n background: var(--ilw-color--focus--background);\n }\n}\n.g-hamburger-button--collapsible {\n display: flex;\n}\n</style>","<script setup lang=\"ts\">\n/**\n * This component is used with the `GDetailListItem` component to display\n * a list of key-value pairs in a grid or vertical layout.\n *\n * For example:\n *\n * ```vue-html\n * <GDetailList>\n * <GDetailListItem label=\"Name\">John Doe</GDetailListItem>\n * <GDetailListItem label=\"Age\">30</GDetailListItem>\n * <GDetailListItem label=\"City\">New York</GDetailListItem>\n * </GDetailList>\n * ```\n */\ninterface Props {\n /**\n * Layout style for the items.\n */\n variant?: \"grid\" | \"vertical\";\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n variant: \"grid\",\n});\n</script>\n\n<template>\n <dl\n class=\"g-detail-list\"\n :class=\"`g-detail-list--${props.variant}`\"\n >\n <slot />\n </dl>\n</template>\n\n<style scoped>\n.g-detail-list {\n margin: 0;\n}\n\n.g-detail-list--grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(var(--g-detail-list-item-min-width, 10rem), var(--g-detail-list-item-max-width, 1fr)));\n column-gap: 2.5rem;\n row-gap: 1.5rem;\n}\n\n.g-detail-list--grid :deep(.g-detail-list-item) {\n display: flex;\n flex-direction: column;\n gap: 0.375rem;\n}\n\n.g-detail-list--grid :deep(.g-detail-list-item__label) {\n font-size: 0.875rem;\n padding-bottom: 0.375rem;\n border-bottom: 2px solid var(--g-accent-500);\n}\n\n.g-detail-list--vertical {\n display: flex;\n flex-direction: column;\n}\n\n.g-detail-list--vertical :deep(.g-detail-list-item) {\n display: grid;\n grid-template-columns: minmax(0, 12rem) minmax(0, 1fr);\n column-gap: 1rem;\n row-gap: 0.25rem;\n padding: 0.75rem 0;\n border-bottom: 1px solid var(--g-surface-200);\n}\n\n.g-detail-list--vertical :deep(.g-detail-list-item:last-child) {\n border-bottom: none;\n}\n\n.g-detail-list--vertical :deep(.g-detail-list-item__label) {\n font-size: 1rem;\n align-self: start;\n}\n\n.g-detail-list--vertical :deep(.g-detail-list-item__value) {\n justify-self: end;\n text-align: right;\n}\n</style>\n","<script setup lang=\"ts\">\ninterface Props {\n /**\n * Label shown for the item.\n */\n label: string;\n}\n\ndefineProps<Props>();\n</script>\n\n<template>\n <div class=\"g-detail-list-item\">\n <dt class=\"g-detail-list-item__label\">\n <slot name=\"label\">{{ label }}</slot>\n </dt>\n <dd class=\"g-detail-list-item__value\">\n <slot />\n </dd>\n </div>\n</template>\n\n<style>\n.g-detail-list-item {\n margin: 0;\n}\n\n.g-detail-list-item__label {\n margin: 0;\n font-weight: 700;\n color: var(--g-primary-500);\n}\n\n.g-detail-list-item__value {\n margin: 0;\n}\n</style>\n","<script setup lang=\"ts\">\n/**\n * Client-side overlay for behind modal dialogs.\n */\nimport { useOverlayStackState } from \"../compose/useOverlayStack.ts\";\n\ninterface Props {\n\n}\n\nconst { hasScrollLock } = useOverlayStackState();\n</script>\n\n<template>\n <Transition name=\"g-fade\">\n <div v-if=\"hasScrollLock\" class=\"g-scroll-lock-overlay\"></div>\n </Transition>\n</template>\n\n<style>\n@layer override {\n body.g-scroll-lock {\n overflow: hidden;\n }\n\n .g-scroll-lock-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.25);\n z-index: 199;\n }\n}\n</style>\n","<script setup lang=\"ts\">/**\n * Prebuilt GSelect and GSelectButton components that can be used to\n * select a term.\n */\nimport GSelect from \"../GSelect.vue\";\nimport GSelectButton from \"../GSelectButton.vue\";\n\ninterface Props {\n /**\n * List of possible term years. Defaults to [\"2026\"].\n */\n termYears?: string[];\n /**\n * List of possible term names. Defaults to [\"Spring\", \"Summer\", \"Fall\"].\n */\n termNames?: string[];\n\n /**\n * Label for year select. Defaults to \"Select Year\".\n */\n yearLabel?: string;\n\n /**\n * Label for period select. Defaults to \"Term\".\n */\n periodLabel?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n termYears: () => [\"2026\"],\n termNames: () => [\"Spring\", \"Summer\", \"Fall\"],\n yearLabel: \"Select Year\",\n periodLabel: \"Term\",\n});\n\nconst term = defineModel<{year: string, name: string}>({\n default: () => ({year: \"2026\", name: \"Spring\"}),\n});\n</script>\n\n<template>\n <div class=\"popover-content\">\n <div class=\"year-dropdown\">\n <GSelect\n v-model=\"term.year\"\n :options=\"termYears\"\n :label=\"yearLabel\"\n />\n </div>\n <div class=\"month-selector\">\n <GSelectButton\n v-model=\"term.name\"\n :options=\"termNames\"\n :allow-empty=\"false\"\n :label=\"periodLabel\"\n />\n </div>\n </div>\n</template>\n\n<style scoped>\n.year-dropdown {\n display: flex;\n justify-content: left;\n margin: 1rem 0;\n}\n</style>\n","<script setup lang=\"ts\">\n/**\n * A button that shows the selected term. Clicking it opens a popover\n * that allows jumping to a different term.\n */\nimport GTermSelectorControl from \"./term/GTermSelectorControl.vue\";\nimport GButton from \"./GButton.vue\";\nimport GPopover from \"./GPopover.vue\";\n\ninterface Props {\n /**\n * Title for the popover.\n */\n title?: string; // Demo: Period Selection\n\n /**\n * Label for year select.\n */\n yearLabel?: string; // Demo: Select Year\n\n /**\n * Label for period select.\n */\n periodLabel?: string; // Demo: Term\n\n // list of possible term years\n termYears?: string[];\n\n // list of possible term names\n termNames?: string[];\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n title: \"Period Selection\",\n termYears: () => [\"2026\"],\n termNames: () => [\"Spring\", \"Summer\", \"Fall\"],\n});\n\nconst term = defineModel<{year: string, name: string}>({\n default: () => ({year: \"2026\", name: \"Spring\"}),\n});\n</script>\n\n<template>\n <div class=\"g-term-selector\">\n <GPopover>\n <template #trigger=\"{ toggle }\">\n <GButton class=\"g-term-selector-button\" theme=\"none\" outlined @click=\"toggle\">\n <span class=\"g-calendar-icon\">\n <svg role=\"none presentation\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 640\"><!--!Font Awesome Free v7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d=\"M224 64C206.3 64 192 78.3 192 96L192 128L160 128C124.7 128 96 156.7 96 192L96 240L544 240L544 192C544 156.7 515.3 128 480 128L448 128L448 96C448 78.3 433.7 64 416 64C398.3 64 384 78.3 384 96L384 128L256 128L256 96C256 78.3 241.7 64 224 64zM96 288L96 480C96 515.3 124.7 544 160 544L480 544C515.3 544 544 515.3 544 480L544 288L96 288z\"/></svg>\n </span>\n <span class=\"g-term-label\"> {{ term?.name }} {{ term?.year }} </span>\n <span class=\"g-caret\">\n <svg role=\"none presentation\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 640\"><!--!Font Awesome Free v7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d=\"M300.3 440.8C312.9 451 331.4 450.3 343.1 438.6L471.1 310.6C480.3 301.4 483 287.7 478 275.7C473 263.7 461.4 256 448.5 256L192.5 256C179.6 256 167.9 263.8 162.9 275.8C157.9 287.8 160.7 301.5 169.9 310.6L297.9 438.6L300.3 440.8z\"/></svg>\n </span>\n </GButton>\n </template>\n <h2 class=\"popover-title\" tabindex=\"-1\">{{ title}}</h2>\n <GTermSelectorControl v-bind=\"$props\" />\n </GPopover>\n </div>\n</template>\n\n<style scoped>\n\n.popover-title {\n font-size: 1rem;\n display: block;\n margin: -1.5rem -1rem 0;\n padding: 0.5rem 1rem;\n background: var(--g-surface-50);\n font-weight: 600;\n color: var(--g-accent-700);\n text-align: center;\n}\n.g-term-selector .g-term-selector-button {\n background: var(--g-surface-0);\n color: var(--g-primary-500);\n border-color: var(--g-primary-500);\n height: 2.35rem;\n padding: 0 8px 0 0;\n text-decoration: none;\n font-size: 1rem;\n\n .g-calendar-icon {\n background: var(--g-primary-500);\n color: var(--g-surface-0);\n display: flex;\n align-items: center;\n\n padding: 0 10px;\n height: 100%;\n\n svg {\n width: 1.5rem;\n fill: currentColor;\n stroke: currentColor;\n }\n }\n\n &:hover .g-term-label {\n text-decoration: underline;\n }\n\n &:focus-visible {\n background: var(--ilw-color--focus--background);\n color: var(--ilw-color--focus--text);\n }\n\n .g-caret {\n pointer-events: none;\n color: var(--ilw-color--link-hover);\n width: 20px;\n }\n}\n\n\n.g-term-label {\n width: 120px;\n padding-top: 2px;\n @media screen and (max-width: 1000px) {\n width: 70px;\n }\n}\n</style>\n","<script setup lang=\"ts\">\n/**\n * User menu component for toolbars. Displays a button with the user's initials\n * inside a colored circle. When clicked, it opens a popover with the user's\n * email and a menu for account-related links.\n *\n * **Slots**:\n * - `default` contains menu items (links or buttons) that will be wrapped in\n * an unordered list for accessibility.\n *\n * **Props**:\n * - `initials` - User's initials to display in the avatar\n * - `email` - User's email to display in the popover\n * - `color` - Background color for the avatar (should be deterministic)\n * - `label` - Accessible label for the menu button. The initial will be prepended to this for the full label.\n *\n * Example:\n *\n * ```vue-html\n * <GUserMenu\n * initials=\"J\"\n * email=\"j@example.com\"\n * color=\"#4A90E2\"\n * >\n * <router-link to=\"/profile\">Profile</router-link>\n * <a href=\"/settings\">Settings</a>\n * <button @click=\"handleLogout\">Logout</button>\n * </GUserMenu>\n * ```\n */\n\nimport { getCurrentInstance, ref, useId, useSlots, useTemplateRef } from \"vue\";\nimport GPopover from \"./GPopover.vue\";\n\ninterface Props {\n /**\n * User initial(s)\n */\n initials: string; // Demo: J\n /**\n * User email\n */\n email: string; // Demo: j@example.org\n /**\n * Background color\n */\n color?: string;\n /**\n * Accessible label\n */\n label?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n label: \"User menu\",\n color: \"var(--g-surface-700)\",\n});\n\nconst id = useId();\nconst emailHeadingId = `${id}-email`;\nconst open = ref(false);\n\n// Get the heading ref to focus it when the popover opens\nconst emailHeading = useTemplateRef<HTMLElement>(\"emailHeading\");\n\n// Detect vue-router without adding it as a dependency\nconst instance = getCurrentInstance();\nconst RouterLinkComp = instance?.appContext?.components?.RouterLink as\n | any\n | undefined;\n\nconst slots = defineSlots<{\n default(): any\n}>();\n\n</script>\n\n<template>\n <div class=\"g-user-menu\">\n <GPopover v-model=\"open\" minimal>\n <template #trigger=\"{ toggle }\">\n <button\n class=\"g-user-menu__avatar\"\n :style=\"{ backgroundColor: color }\"\n :aria-label=\"initials + ' - ' + label\"\n :aria-expanded=\"open\"\n aria-haspopup=\"menu\"\n @click=\"toggle\"\n >\n {{ initials }}\n </button>\n </template>\n <div class=\"g-user-menu__popover\">\n <h2\n :id=\"emailHeadingId\"\n ref=\"emailHeading\"\n class=\"g-user-menu__email\"\n tabindex=\"-1\"\n >\n {{ email }}\n </h2>\n <nav class=\"g-user-menu__nav\" :aria-labelledby=\"emailHeadingId\">\n <ul class=\"g-user-menu__list\">\n <li v-for=\"(link, index) in slots.default()\" :key=\"index\">\n <component :is=\"link\"></component>\n </li>\n </ul>\n </nav>\n </div>\n </GPopover>\n </div>\n</template>\n\n<style scoped>\n.g-user-menu {\n display: inline-block;\n}\n\n.g-user-menu__avatar {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n border: none;\n color: var(--g-surface-0);\n font-weight: 700;\n font-size: 1rem;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition:\n transform 0.2s,\n box-shadow 0.2s;\n outline-color: var(--g-primary-500);\n}\n\n.g-user-menu__avatar:hover {\n text-decoration: underline;\n}\n\n.g-user-menu__avatar:focus-visible {\n background-color: var(--ilw-color--focus--background) !important;\n color: var(--ilw-color--focus--text) !important;\n}\n\n.g-user-menu__popover {\n min-width: 200px;\n}\n\n.g-user-menu__email {\n margin: 0.75rem 1rem 0.25rem;\n font-size: 1rem;\n font-weight: normal;\n color: var(--g-primary-500);\n word-break: break-word;\n}\n\n.g-user-menu__nav {\n margin: 0;\n}\n\n.g-user-menu__list {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n gap: 0;\n}\n\n.g-user-menu__list :deep(a),\n.g-user-menu__list :deep(button) {\n display: block;\n padding: 0.75rem 1rem;\n box-sizing: border-box;\n color: var(--g-primary-500);\n text-decoration: none;\n border: none;\n background: none;\n font-size: 1rem;\n font-weight: 600;\n font-family: var(--il-font-sans);\n text-align: left;\n cursor: pointer;\n}\n\n.g-user-menu__list :deep(a:hover),\n.g-user-menu__list :deep(button:hover) {\n color: var(--g-accent-700);\n text-decoration: underline;\n}\n\n.g-user-menu__list :deep(a:focus),\n.g-user-menu__list :deep(button:focus) {\n background: var(--ilw-color--focus--background);\n color: var(--ilw-color--focus--text);\n}\n\n.g-user-menu__list :deep(a:active),\n.g-user-menu__list :deep(button:active) {\n background-color: var(--g-accent-700);\n color: var(--g-surface-0);\n}\n</style>\n","<script setup lang=\"ts\">\n/**\n * A currency input component for US dollars.\n * \n * This component is a wrapper around a text input with a prefix and\n * appropriate input type for currency values.\n */\nimport GTextInput from \"./GTextInput.vue\";\n\ntype Props = {\n /**\n * Label\n */\n label?: string;\n /**\n * Placeholder text\n */\n placeholder?: string;\n /**\n * Disabled\n */\n disabled?: boolean;\n\n // Error messages array (supports multiple validation errors)\n errors?: string[];\n /**\n * Instructions\n */\n instructions?: string;\n // Name for form registration\n name?: string;\n};\n\nconst props = withDefaults(defineProps<Props>(), {\n label: undefined,\n instructions: \"\",\n placeholder: \"\",\n disabled: false,\n errors: () => [],\n name: undefined,\n});\n\nconst model = defineModel<string | null>({ type: String });\n</script>\n\n<template>\n <GTextInput\n v-model=\"model\"\n :name=\"props.name\"\n :label=\"props.label\"\n :placeholder=\"props.placeholder\"\n :disabled=\"props.disabled\"\n :errors=\"props.errors\"\n :instructions=\"props.instructions\"\n prefix=\"$\"\n type=\"number\"\n step=\"0.01\"\n min=\"0\"\n v-bind=\"$attrs\"\n />\n</template>\n\n<style scoped>\n/* No additional styles needed, using GTextInput styles */\n</style>\n","<script setup lang=\"ts\">\n/**\n * An email input component.\n * \n * This component is a wrapper around GTextInput with type=\"email\" for\n * proper email validation and mobile keyboard optimization.\n */\nimport GTextInput from \"./GTextInput.vue\";\n\ntype Props = {\n /**\n * Label\n */\n label?: string;\n /**\n * Placeholder text\n */\n placeholder?: string;\n /**\n * Disabled\n */\n disabled?: boolean;\n\n // Error messages array (supports multiple validation errors)\n errors?: string[];\n /**\n * Instructions\n */\n instructions?: string;\n // Name for form registration\n name?: string;\n};\n\nconst props = withDefaults(defineProps<Props>(), {\n label: undefined,\n instructions: \"\",\n placeholder: \"\",\n disabled: false,\n errors: () => [],\n name: undefined,\n});\n\nconst model = defineModel<string | null>({ type: String });\n</script>\n\n<template>\n <GTextInput\n v-model=\"model\"\n :name=\"name\"\n :label=\"label\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :errors=\"errors\"\n :instructions=\"instructions\"\n type=\"email\"\n v-bind=\"$attrs\"\n />\n</template>\n\n<style scoped>\n/* No additional styles needed, using GTextInput styles */\n</style>\n","<script setup lang=\"ts\">\n/**\n * A date input component.\n * \n * This component is a wrapper around GTextInput with type=\"date\" for\n * proper date selection using the browser's native date picker.\n */\nimport GTextInput from \"./GTextInput.vue\";\n\ntype Props = {\n /**\n * Label\n */\n label?: string;\n /**\n * Placeholder text\n */\n placeholder?: string;\n /**\n * Disabled\n */\n disabled?: boolean;\n\n // Error messages array (supports multiple validation errors)\n errors?: string[];\n /**\n * Instructions\n */\n instructions?: string;\n // Name for form registration\n name?: string;\n};\n\nconst props = withDefaults(defineProps<Props>(), {\n label: undefined,\n instructions: \"\",\n placeholder: \"\",\n disabled: false,\n errors: () => [],\n name: undefined,\n});\n\nconst model = defineModel<string | null>({ type: String });\n</script>\n\n<template>\n <GTextInput\n v-model=\"model\"\n :name=\"props.name\"\n :label=\"props.label\"\n :placeholder=\"props.placeholder\"\n :disabled=\"props.disabled\"\n :errors=\"props.errors\"\n :instructions=\"props.instructions\"\n type=\"date\"\n v-bind=\"$attrs\"\n />\n</template>\n\n<style scoped>\n/* No additional styles needed, using GTextInput styles */\n</style>\n","<script setup lang=\"ts\">\n/**\n * A date range input component with start and end dates.\n * \n * This component uses two GDateInput components laid out horizontally\n * to allow selecting a date range.\n */\nimport { ref, watch, toRef } from \"vue\";\nimport GDateInput from \"./GDateInput.vue\";\nimport { useFormField } from \"../compose/useFormField.ts\";\n\ntype Props = {\n /**\n * Label for the component\n */\n label?: string;\n /**\n * Label for the start date input\n */\n startLabel?: string;\n /**\n * Label for the end date input\n */\n endLabel?: string;\n /**\n * Disabled\n */\n disabled?: boolean;\n\n // Error messages array (supports multiple validation errors)\n errors?: string[];\n /**\n * Instructions\n */\n instructions?: string;\n // Name for form registration\n name?: string;\n};\n\nconst props = withDefaults(defineProps<Props>(), {\n label: undefined,\n startLabel: \"Start Date\",\n endLabel: \"End Date\",\n instructions: \"\",\n disabled: false,\n errors: () => [],\n name: undefined,\n});\n\ntype DateRange = {\n start: string | null;\n end: string | null;\n};\n\nconst model = defineModel<DateRange>({\n default: () => ({ start: null, end: null }),\n});\n\nconst startDate = ref<string | null>(model.value.start || null);\nconst endDate = ref<string | null>(model.value.end || null);\n\n// Use form field composable for form registration and error handling\nconst { displayErrors } = useFormField({\n name: props.name,\n value: model,\n errors: toRef(props, 'errors'),\n});\n\nwatch([startDate, endDate], () => {\n model.value = {\n start: startDate.value,\n end: endDate.value,\n };\n});\n\nwatch(\n model,\n (newValue) => {\n if (newValue.start !== startDate.value) {\n startDate.value = newValue.start;\n }\n if (newValue.end !== endDate.value) {\n endDate.value = newValue.end;\n }\n },\n { deep: true }\n);\n</script>\n\n<template>\n <div class=\"g-date-range-input\">\n <div v-if=\"props.label\" class=\"g-date-range-input__label\">\n {{ props.label }}\n </div>\n <div\n v-if=\"props.instructions\"\n class=\"g-date-range-input__instructions\"\n >\n {{ props.instructions }}\n </div>\n <div class=\"g-date-range-input__fields\">\n <GDateInput\n v-model=\"startDate\"\n :label=\"props.startLabel\"\n :disabled=\"props.disabled\"\n class=\"g-date-range-input__field\"\n />\n <GDateInput\n v-model=\"endDate\"\n :label=\"props.endLabel\"\n :disabled=\"props.disabled\"\n class=\"g-date-range-input__field\"\n />\n </div>\n <div v-if=\"displayErrors.length > 0\" class=\"g-date-range-input__errors\" role=\"alert\">\n <div\n v-for=\"(errorMsg, index) in displayErrors\"\n :key=\"index\"\n class=\"g-date-range-input__error\"\n >\n {{ errorMsg }}\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.g-date-range-input {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.g-date-range-input__label {\n font-size: 1.25em;\n font-weight: 600;\n}\n\n.g-date-range-input__instructions {\n margin: 0 0 0.25em 0.5em;\n color: var(--g-surface-800);\n}\n\n.g-date-range-input__fields {\n display: flex;\n flex-direction: row;\n gap: 1rem;\n align-items: flex-start;\n}\n\n.g-date-range-input__field {\n flex: 1;\n min-width: 0;\n}\n\n.g-date-range-input__errors {\n display: flex;\n flex-direction: column;\n gap: 0.25em;\n}\n\n.g-date-range-input__error {\n background: var(--g-surface-0);\n color: var(--g-danger-600);\n padding: 0.25em 0.5em;\n}\n</style>\n","import { ref, Ref, computed, ComputedRef, shallowReactive } from \"vue\";\n\nexport interface FormField {\n name: string;\n value: Ref<any>;\n errors: Ref<string[]> | ComputedRef<string[]>;\n}\n\nexport interface UseFormReturn {\n fields: Record<string, FormField>;\n values: Ref<Record<string, any>>;\n errors: Ref<Record<string, string[]>>;\n isSubmitting: Ref<boolean>;\n hasErrors: Ref<boolean>;\n registerField: (name: string, field: FormField) => void;\n unregisterField: (name: string) => void;\n submit: (handler: (values: Record<string, any>) => Promise<void> | void) => Promise<void>;\n}\n\n/**\n * Composable to manage form state and link form inputs together.\n * Uses reactive state pattern - errors are provided as reactive props to input components.\n */\nexport function useForm(): UseFormReturn {\n const fields: Record<string, FormField> = shallowReactive({});\n const isSubmitting = ref(false);\n\n const values = computed(() => {\n const vals: Record<string, any> = {};\n Object.entries(fields).forEach(([name, field]) => {\n if (field && field.value) {\n vals[name] = field.value.value;\n }\n });\n return vals;\n });\n\n const errors = computed(() => {\n const errs: Record<string, string[]> = {};\n Object.entries(fields).forEach(([name, field]) => {\n const errorValue = field.errors.value;\n if (errorValue && errorValue.length > 0) {\n errs[name] = errorValue;\n }\n });\n return errs;\n });\n\n const hasErrors = computed(() => {\n return Object.keys(errors.value).length > 0;\n });\n\n function registerField(name: string, field: FormField) {\n fields[name] = field;\n }\n\n function unregisterField(name: string) {\n delete fields[name];\n }\n\n async function submit(handler: (values: Record<string, any>) => Promise<void> | void) {\n if (isSubmitting.value) {\n return;\n }\n isSubmitting.value = true;\n try {\n await handler(values.value);\n } finally {\n isSubmitting.value = false;\n }\n }\n\n return {\n fields,\n values,\n errors,\n isSubmitting,\n hasErrors,\n registerField,\n unregisterField,\n submit,\n };\n}\n","<script lang=\"ts\" setup>\n/**\n * A form wrapper component that automatically manages form state and\n * connects to child input components.\n *\n * Child input components that have a `name` prop will automatically\n * register with the form, and their values will be tracked in the form model.\n *\n * ### Features\n *\n * - Automatic value tracking for child input components with the `name` prop\n * - Reactive error handling by providing a computed list of errors\n * - Optionally manage your own form state in a parent component by providing a\n * `form` injection\n *\n * ### Basic example\n *\n * ```vue-html\n * <GForm v-model=\"formData\" @submit=\"handleSubmit\">\n * <template #default=\"{ isSubmitting, hasErrors }\">\n * <GTextInput name=\"firstName\" label=\"First Name\" :errors=\"firstNameErrors\" />\n * <GSubmitButton :disabled=\"hasErrors\">Submit</GSubmitButton>\n * </template>\n * </GForm>\n * ```\n */\n\nimport { provide, watch, inject, computed } from \"vue\";\nimport { useForm, UseFormReturn } from \"../compose/useForm.ts\";\n\ninterface Props {\n /**\n * Action URL (optional, for native form submission)\n */\n action?: string;\n /**\n * HTTP method (optional, for native form submission)\n */\n method?: string;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n action: undefined,\n method: \"post\",\n});\n\nconst model = defineModel<Record<string, any>>({ default: () => ({}) });\n\nconst emit = defineEmits<{\n submit: [values: Record<string, any>];\n}>();\n\n// Check if a form is already injected from a parent\nconst parentForm = inject<UseFormReturn | null>(\"form\", null);\n\n// Only create a new form if one wasn't already provided\nconst form = parentForm || useForm();\n\n// Only provide the form if we created it (not if we're using a parent's form)\nif (!parentForm) {\n provide(\"form\", form);\n}\n\n// Sync form values to model\nwatch(\n () => form.values.value,\n (newValues) => {\n model.value = { ...newValues };\n },\n { deep: true },\n);\n\n// Initialize fields from model value\nwatch(\n () => model.value,\n (newModel) => {\n if (newModel) {\n Object.entries(newModel).forEach(([name, value]) => {\n const field = form.fields[name];\n if (field && field.value.value !== value) {\n field.value.value = value;\n }\n });\n }\n },\n { deep: true, immediate: true },\n);\n\nasync function handleSubmit(e: Event) {\n e.preventDefault();\n await form.submit(async (values) => {\n emit(\"submit\", values);\n });\n}\n\n</script>\n\n<template>\n <form\n @submit=\"handleSubmit\"\n :action=\"props.action\"\n :method=\"props.method\"\n class=\"g-form\"\n novalidate\n >\n <slot\n :isSubmitting=\"form.isSubmitting.value\"\n :hasErrors=\"form.hasErrors.value\"\n :values=\"form.values.value\"\n :errors=\"form.errors.value\"\n ></slot>\n </form>\n</template>\n\n<style scoped>\n.g-form {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n</style>\n","<script lang=\"ts\" setup>\n/**\n * A submit button that integrates with GForm.\n *\n * When used inside a GForm, the button will automatically:\n * - Show a loading state during form submission\n * - Be disabled when specified\n *\n * @example\n * <GForm v-model=\"formData\" @submit=\"handleSubmit\">\n * <GTextInput name=\"email\" label=\"Email\" />\n * <GSubmitButton>Submit</GSubmitButton>\n * </GForm>\n */\n\nimport { inject, computed } from \"vue\";\nimport { UseFormReturn } from \"../compose/useForm.ts\";\nimport GButton from \"./GButton.vue\";\n\ninterface Props {\n /**\n * Disabled state\n */\n disabled?: boolean;\n /**\n * Loading text to show during submission\n */\n loadingText?: string;\n /**\n * Variant\n */\n variant?: \"primary\" | \"secondary\" | \"danger\";\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n disabled: false,\n loadingText: \"Submitting...\",\n variant: \"primary\",\n});\n\nconst form = inject<UseFormReturn | null>(\"form\", null);\n\nconst isDisabled = computed(() => {\n return props.disabled || (form?.isSubmitting.value ?? false);\n});\n\nconst isSubmitting = computed(() => {\n return form?.isSubmitting.value ?? false;\n});\n</script>\n\n<template>\n <GButton\n type=\"submit\"\n :disabled=\"isDisabled\"\n :variant=\"props.variant\"\n class=\"g-submit-button\"\n >\n <template v-if=\"isSubmitting\">{{ props.loadingText }}</template>\n <slot v-else>Submit</slot>\n </GButton>\n</template>\n\n<style scoped>\n.g-submit-button {\n align-self: flex-start;\n}\n</style>\n"],"names":["props","__props","slots","_useSlots","attrs","useAttrs","classes","computed","_createBlock","_resolveDynamicComponent","_mergeProps","_unref","_cache","$event","$emit","_createElementBlock","_Fragment","_createElementVNode","_hoisted_1","_renderSlot","_ctx","_hoisted_2","useFormField","options","form","inject","displayErrors","allErrors","hasErrors","name","onMounted","onBeforeUnmount","_openBlock","_renderList","errorMsg","index","_createTextVNode","model","_useModel","id","useId","toRef","emit","__emit","lastInputValue","ref","inputTimer","emitChangeIfNeeded","val","prev","onInput","e","value","onBlur","onPaste","onKeydown","_normalizeClass","$attrs","_toDisplayString","$slots","_hoisted_3","_hoisted_5","_createVNode","GFormErrorMessages","OVERLAY_Z_INDEX_BASE","MODAL_Z_INDEX_BASE","DEFAULT_TOOLTIP_Z_INDEX","setupStackState","scrollLockStack","scrollbarWidth","stack","modalStack","updateBodyScrollLock","useOverlayStack","modal","lockScroll","stackRef","push","pop","idx","lockIdx","isTop","zIndex","pos","useOverlayStackState","hasModal","hasOverlay","hasScrollLock","getTopZIndex","max","_","notNullish","useFocusTrap","target","trap","immediate","focusTrapOptions","hasFocus","shallowRef","isPaused","activate","opts","deactivate","pause","unpause","watch","toArray","toValue","el","_el","unrefElement","els","createFocusTrap","isActive","tryOnScopeDispose$1","useOverlayFocus","element","clickOutsideDeactivates","unpausing","focus","h2","selected","nextTick","err","top","useOverlayEscape","containers","open","hide","onDocumentClick","onDocumentKeydown","calculatePopoverPosition","anchorRect","popoverRect","viewportRect","gap","margin","preferAbove","placedAbove","overlay","left","centeredLeft","xOffset","triggerRef","useTemplateRef","popoverRef","toggle","popoverPosition","arrowPosition","popoverAbove","popoverOverlay","resizeObserver","updatePopoverPosition","triggerRect","viewportWidth","_Teleport","_Transition","_normalizeStyle","baseId","normalizedOptions","opt","groupClasses","getBtnClasses","onChange","option","stroke","isDeterminate","radius","circumference","progress","ariaProps","dialog","close","onBeforeMount","GButton","comboRef","listboxRef","activeIndex","ignoreBlur","ignoreFocus","menuPlacement","menuMaxHeight","menuStyle","style","updateMenuPlacement","rect","spaceBelow","spaceAbove","listboxFullHeight","minSpaceToOpenBelow","removeWindowListeners","addWindowListeners","removeListeners","searchQuery","filteredOptions","q","selectedIndex","openMenu","comboInputRef","closeMenu","onComboFocus","onComboInput","onComboBlur","relatedTarget","selectOption","onComboClick","onComboKeydown","scrollOptionIntoView","onOptionClick","onOptionMouseDown","showClearButton","clearValue","_withDirectives","_hoisted_8","modelValue","inputRef","closed","flatResults","g","resultCount","ev","focused","useFocusWithin","altKey","selectResult","expanded","result","isLoading","submit","useDebounceFn","GProgress","_hoisted_4","group","gIdx","_hoisted_7","item","_withModifiers","_hoisted_6","sidebar","bgImage","bgColor","topOff","fallbackId","handleEscapeKey","event","activeId","activeLink","content","activeItem","instance","getCurrentInstance","RouterLinkComp","onLinkClick","tooltipIdCounter","createTooltipEl","text","tooltip","showTooltip","arrowX","hideTooltip","VGtooltip","binding","isHovered","isFocused","tooltipText","tooltipId","ensureTooltip","watchEffect","onMouseEnter","onMouseLeave","onFocus","onKeyDown","data","vGtooltip","copy","copied","isSupported","useClipboard","handleCopy","handleTooltipHide","scrollerRef","contentRef","isAtBottom","isAtTop","scrollToBottom","focusLast","items","last","handleScroll","scrollTop","scrollHeight","clientHeight","useResizeObserver","reversedEntries","entry","change","onClickLabel","radioName","leftId","centerId","rightId","thumbPosition","onLabelKeydown","_hoisted_14","handleMouseDown","rowKey","handleRowClick","row","handleCheckboxChange","link","isRowSelected","shiftKey","handleCellChange","col","buildAriaLabelledBy","columnHeaderId","labelCellColumn","shouldAddCellId","hasCellChange","hasCellError","getCellError","_hoisted_9","_hoisted_11","_hoisted_13","emptyAsUndefined","filterOmitEmpty","k","v","asArray","filterAsQuery","filters","query","key","toRaw","filtersToQueryParams","useFiltering","values","reactive","syncWith","queryParams","newValues","isFiltered","clearFilters","filteredColumns","sortField","sortOrder","filter","selectedRows","onSort","filtering","allRowKeys","selectedRowsOnPage","allSelected","someSelected","lastClickedRowKey","toggleAllRows","newSelected","toggleRow","lastIndex","currentIndex","start","end","rowsInRange","clickRow","handleBulkAction","actionId","convertedValue","columnKey","previousValue","payload","useSlots","shouldShowPagination","shouldShowControls","newColumns","_hoisted_12","_hoisted_16","GPopover","_withCtx","GSelect","_hoisted_18","_hoisted_19","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_25","GTableBody","_hoisted_26","_hoisted_27","_hoisted_28","action","totalPages","startModel","pageSizeModel","startVal","pageSizeVal","startDisplay","currentPage","goToPage","p","onPageSizeChange","size","useClasses","modalClasses","term","GSelectButton","GTermSelectorControl","$props","emailHeadingId","emailHeading","GTextInput","startDate","endDate","newValue","GDateInput","useForm","fields","shallowReactive","isSubmitting","vals","field","errors","errs","errorValue","registerField","unregisterField","handler","parentForm","provide","newModel","handleSubmit","isDisabled"],"mappings":"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","x_google_ignoreList":[5,6]}
|