{"version":3,"file":"gallery-Cxmcgvdr.js","sources":["../../../packs/frontend/components/SubNav.vue","../../../packs/frontend/utils/gallery/isEqual.ts","../../../packs/frontend/composables/useFilter.ts","../../../packs/frontend/pages/gallery.vue"],"sourcesContent":["\n\n\n\n\n\n\n","function isPrimitive(\n value: unknown\n): value is string | number | boolean | null | undefined {\n return (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\" ||\n value === null ||\n value === undefined\n );\n}\n\nfunction isObject(value: unknown): value is Record {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isEqual(obj1: T, obj2: T): boolean {\n if (obj1 === obj2) return true;\n\n if (isPrimitive(obj1) || isPrimitive(obj2)) {\n return obj1 === obj2;\n }\n\n if (Array.isArray(obj1) && Array.isArray(obj2)) {\n return (\n obj1.length === obj2.length &&\n obj1.every((value, index) => isEqual(value, obj2[index]))\n );\n }\n\n if (isObject(obj1) && isObject(obj2)) {\n const keys1 = Object.keys(obj1);\n const keys2 = Object.keys(obj2);\n\n if (keys1.length !== keys2.length) return false;\n\n for (const key of keys1) {\n if (!keys2.includes(key) || !isEqual(obj1[key], obj2[key])) {\n return false;\n }\n }\n\n return true;\n }\n\n return false;\n}\n\nexport { isEqual };\n","import { FilterParamsBase } from \"@/types/filter.types\";\nimport { ensureArray } from \"@/utils/gallery/ensureArray\";\nimport { isEqual } from \"@/utils/gallery/isEqual\";\nimport debounce from \"lodash.debounce\";\nimport { computed, onBeforeUnmount, ref, UnwrapRef, watch } from \"vue\";\nimport { LocationQueryValue, useRoute, useRouter } from \"vue-router\";\n\nconst URL_UPDATE_DEBOUNCE = 500;\n\nconst germanSearchUtils = {\n toAscii: (str: string): string =>\n str\n .replace(/ä/g, \"ae\")\n .replace(/ö/g, \"oe\")\n .replace(/ü/g, \"ue\")\n .replace(/ß/g, \"ss\")\n .replace(/Ä/g, \"Ae\")\n .replace(/Ö/g, \"Oe\")\n .replace(/Ü/g, \"Ue\"),\n\n normalizeSpacing: (str: string): string => str.replace(/\\s+/g, \" \").trim(),\n\n createSearchParams: (query: string) => {\n const normalized = germanSearchUtils.normalizeSpacing(query);\n return {\n query: normalized,\n queryAscii: germanSearchUtils.toAscii(normalized),\n };\n },\n};\n\nconst safeDecodeURIComponent = (value: string): string => {\n try {\n return decodeURIComponent(value);\n } catch (e) {\n console.warn(\"Failed to decode URL parameter:\", value);\n return value;\n }\n};\n\nexport interface FilterOptions {\n defaultParams: T;\n urlUpdateDebounceTime?: number;\n normalizeSearch?: boolean;\n onSearch?: (params: T) => void;\n}\n\nexport const useFilter = (\n options: FilterOptions\n) => {\n const router = useRouter();\n const route = useRoute();\n\n const urlDebounce = options.urlUpdateDebounceTime || URL_UPDATE_DEBOUNCE;\n\n const isLoading = ref(false);\n const error = ref(null);\n\n const initializeParams = (): T => {\n const initialParams = { ...options.defaultParams };\n Object.keys(initialParams).forEach((key) => {\n if (key in route.query) {\n const routeValue = route.query[key];\n if (Array.isArray(initialParams[key as keyof T])) {\n (initialParams[key as keyof T] as unknown[]) = ensureArray(\n routeValue as string[]\n ).map((value) => safeDecodeURIComponent(String(value)));\n } else if (typeof initialParams[key as keyof T] === \"number\") {\n (initialParams[key as keyof T] as unknown) =\n Number(routeValue) || initialParams[key as keyof T];\n } else {\n (initialParams[key as keyof T] as unknown) = safeDecodeURIComponent(\n String(routeValue)\n );\n }\n }\n });\n\n return initialParams;\n };\n\n const initialParams = ref({ ...options.defaultParams });\n const params = ref(initializeParams());\n\n const hasActiveFilters = computed(() => {\n return Object.keys(params.value).some((key) => {\n if (key === \"page\" || key === \"limit\") return false;\n return !isEqual(\n (params.value as T)[key as keyof T],\n (initialParams.value as T)[key as keyof T]\n );\n });\n });\n\n // Watch for params changes to trigger search\n watch(\n () => params.value,\n (newParams) => {\n if (options.onSearch) {\n options.onSearch(newParams);\n }\n },\n { deep: true, immediate: true }\n );\n\n const updateUrl = async () => {\n const queryParams: Record = {};\n\n try {\n for (const [key, value] of Object.entries(params.value as T)) {\n if (value !== null && value !== undefined && value !== \"\") {\n if (typeof value === \"string\" && value.trim() !== \"\") {\n queryParams[key] = safeDecodeURIComponent(value);\n } else if (Array.isArray(value) && value.length > 0) {\n queryParams[key] = value.map((v) =>\n safeDecodeURIComponent(String(v))\n );\n } else if (typeof value !== \"string\" && !Array.isArray(value)) {\n queryParams[key] = String(value);\n }\n }\n }\n\n await router.replace({ query: queryParams });\n error.value = null;\n } catch (e) {\n console.error(\"Error updating URL:\", e);\n error.value = \"Failed to update filters\";\n }\n };\n\n const debouncedUpdateUrl = debounce(updateUrl, urlDebounce);\n\n const updateFilter = async (key: K, value: T[K]) => {\n params.value = { ...(params.value as T), [key]: value } as UnwrapRef;\n debouncedUpdateUrl();\n };\n\n const groupParamsUpdate = (selectedValues: Partial) => {\n params.value = {\n ...params.value,\n ...selectedValues,\n page: 1,\n } as UnwrapRef;\n debouncedUpdateUrl();\n };\n\n const resetFilters = () => {\n params.value = { ...options.defaultParams } as UnwrapRef;\n debouncedUpdateUrl();\n };\n\n const search = (query: string) => {\n params.value = { ...(params.value as T), query, page: 1 } as UnwrapRef;\n debouncedUpdateUrl();\n };\n\n // Watch for route changes\n watch(\n () => route.query,\n () => {\n const queryKeys = Object.keys(route.query);\n const newParams = { ...options.defaultParams } as Record<\n string,\n string | LocationQueryValue[]\n >;\n\n queryKeys.forEach((key) => {\n if (key in newParams) {\n const queryValue = route.query[key];\n if (!queryValue) return;\n newParams[key] = safeDecodeURIComponent(String(queryValue));\n }\n });\n\n params.value = newParams as UnwrapRef;\n },\n { deep: true }\n );\n\n onBeforeUnmount(() => {\n debouncedUpdateUrl.cancel();\n });\n\n return {\n hasActiveFilters,\n params,\n isLoading,\n error,\n groupParamsUpdate,\n updateUrl: debouncedUpdateUrl,\n updateFilter,\n resetFilters,\n search,\n utils: germanSearchUtils,\n };\n};\n","\n\n\n"],"names":["__default__","defineComponent","isExternalLink","to","isPrimitive","value","isObject","isEqual","obj1","obj2","index","keys1","keys2","key","URL_UPDATE_DEBOUNCE","germanSearchUtils","str","query","normalized","safeDecodeURIComponent","useFilter","options","router","useRouter","route","useRoute","urlDebounce","isLoading","ref","error","initializeParams","initialParams","routeValue","ensureArray","params","hasActiveFilters","computed","watch","newParams","debouncedUpdateUrl","debounce","queryParams","v","e","updateFilter","groupParamsUpdate","selectedValues","resetFilters","search","queryKeys","queryValue","onBeforeUnmount","useI18n","userStore","useUserStore","subNavItems","international","defaultParams","defaultParamsToIgnore","currentFilterableRoute","categories","useGalleryCategories","handleSearchInput","handleSubmit","handleFilterChange","data","handleResetFilters","placeholderText"],"mappings":"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"}