{"version":3,"file":"GetFindAdvisors-BV9Iv6qS.js","sources":["../../node_modules/@heroicons/vue/outline/esm/LocationMarkerIcon.js","../../src/components/find-an-advisor/index/ProfileCard.vue","../../src/components/find-an-advisor/index/SearchFields.vue","../../src/components/find-an-advisor/index/FilterTags.vue","../../src/components/find-an-advisor/Index.vue","../../src/pages/GetFindAdvisors.ts"],"sourcesContent":["import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from \"vue\"\n\nexport default function render(_ctx, _cache) {\n return (_openBlock(), _createBlock(\"svg\", {\n xmlns: \"http://www.w3.org/2000/svg\",\n fill: \"none\",\n viewBox: \"0 0 24 24\",\n \"stroke-width\": \"2\",\n stroke: \"currentColor\",\n \"aria-hidden\": \"true\"\n }, [\n _createVNode(\"path\", {\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n d: \"M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z\"\n }),\n _createVNode(\"path\", {\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n d: \"M15 11a3 3 0 11-6 0 3 3 0 016 0z\"\n })\n ]))\n}","<script setup lang=\"ts\">\nimport { toRef } from \"vue\"\nimport { FindAnAdvisorProfile } from \"@/types/profile\"\nimport { useFindAnAdvisorProfile } from \"@/composables/advisor-profile\"\nimport Prose from \"@/components/shared/Prose.vue\"\nimport Card from \"@/components/shared/Card.vue\"\nimport ProfileImage from \"@/components/shared/ProfileImage.vue\"\nimport Border from \"@/components/shared/Border.vue\"\n\nconst props = defineProps<{ profile: FindAnAdvisorProfile }>()\nconst profile = toRef(props, \"profile\")\n\nconst { idealClientsList, profileImageURL } = useFindAnAdvisorProfile(\n props.profile\n)\n</script>\n\n<template>\n <Card>\n <a :href=\"`/find-an-advisor/${profile.slug}`\" class=\"group\">\n <div class=\"flex flex-col min-h-full\">\n <article class=\"mb-3\">\n <header>\n <div class=\"flex gap-4\">\n <div class=\"shrink-0 w-24\">\n <ProfileImage :src=\"profileImageURL\" />\n </div>\n\n <div>\n <h1\n class=\"text-2xl leading-6 font-extrabold font-display text-xy-black\"\n >\n {{ profile.name }}\n </h1>\n <h2\n class=\"text-base leading-tight font-normal text-neutral-600\"\n >\n {{ profile.firmName }}\n </h2>\n\n <div v-if=\"profile.designations\" class=\"mt-1.5\">\n <ul class=\"flex flex-wrap -mx-0.5\">\n <li\n v-for=\"designation in profile.designations\"\n :key=\"designation\"\n class=\"mx-0.5 mb-0.5\"\n >\n <span class=\"xy-badge-blue\">{{ designation }}</span>\n </li>\n </ul>\n </div>\n </div>\n </div>\n </header>\n\n <div class=\"mt-3 space-y-3\">\n <div v-if=\"idealClientsList\" class=\"inline-flex\">\n <h3 class=\"sr-only\">Ideal Clients</h3>\n <div>\n <ul class=\"flex flex-wrap -mx-0.5\">\n <li\n v-for=\"client in idealClientsList\"\n :key=\"client.value\"\n class=\"mx-0.5 leading-5\"\n >\n <span\n class=\"text-sm font-medium tracking-wide text-neutral-600\"\n >\n <span class=\"text-xy-green\">•</span>\n {{ client.value }}\n </span>\n </li>\n </ul>\n </div>\n </div>\n\n <Border size=\"short\" />\n\n <Prose size=\"sm\">\n <p class=\"line-clamp-6 text-neutral-700\">\n {{ profile.bioShort }}\n </p>\n </Prose>\n </div>\n </article>\n\n <div class=\"mt-auto\">\n <a\n class=\"xy-btn-secondary\"\n :href=\"`/find-an-advisor/${profile.slug}`\"\n >\n Advisor Profile →\n </a>\n </div>\n </div>\n </a>\n </Card>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, ref } from \"vue\"\nimport {\n BaseInput,\n FieldsetLegend,\n MultiCheckboxes,\n debounceFn,\n} from \"@xy-planning-network/trees\"\nimport { recordToMultiselectOptions } from \"@/composables/forms\"\nimport { SearchFindAnAdvisorProfileParams } from \"@/types/profile\"\nimport Accordion from \"@/components/shared/Accordion/Accordion.vue\"\n\nconst props = defineProps<{\n niches: Record<string, string[]>\n}>()\n\nconst searchParams = defineModel<SearchFindAnAdvisorProfileParams>(\"params\", {\n required: true,\n})\n\n// Lazyily update the search input.\nconst searchFilter = ref(\"\")\nconst lazySearchFilter = debounceFn((inputVal: string) => {\n searchFilter.value = inputVal.trim()\n}, 350)\n\n/**\n * nicheOptions computes the available niche groups and options\n * to display. When the search filter is not in use all options are available\n * and their panel states are mapped to the panelStates ref which tracks user history\n * of the panel state.\n *\n * When the search filter is in use, unmatched niches are removed and empty groups are hidden.\n * Any remaining groups will automatically have their panel set to an open state.\n */\nconst nicheOptions = computed(() => {\n let niches = props.niches\n\n if (searchFilter.value) {\n niches = Object.entries(props.niches).reduce(\n (filtered, [cat, niches]) => {\n const nichesMatches = niches.filter((n) =>\n n.toLowerCase().includes(searchFilter.value.toLowerCase())\n )\n\n if (nichesMatches.length > 0) {\n filtered[cat] = nichesMatches\n }\n\n return filtered\n },\n {} as Record<string, string[]>\n )\n }\n\n return recordToMultiselectOptions(niches).map((nicheGroup) => {\n const groupActive = nicheGroup.options.reduce((active, option) => {\n if (searchParams.value.niches?.includes(option.value)) {\n active = true\n }\n return active\n }, false)\n\n return {\n ...nicheGroup,\n open: searchFilter.value ? true : groupActive,\n }\n })\n})\n</script>\n\n<template>\n <div class=\"pb-6\">\n <div class=\"border-b border-gray-100 pb-5 mb-2.5\">\n <BaseInput\n :model-value=\"searchFilter\"\n type=\"text\"\n label=\"Search Advisor Specialties\"\n placeholder=\"Filter all specialties by keyword\"\n @update:model-value=\"lazySearchFilter\"\n />\n </div>\n\n <div\n v-if=\"nicheOptions.length === 0\"\n class=\"font-semibold text-sm text-center\"\n >\n No results. Adjust your filter for more options.\n </div>\n\n <!--\n NOTE(spk): by setting a key that includes the searchFilter value, \n we can ensure a render cycle that will reset the panels open state.\n This may or may not be desireable, let user feedback determine what to do.\n -->\n <div\n v-for=\"group in nicheOptions\"\n :key=\"`${group.label}-${searchFilter}`\"\n class=\"py-3\"\n >\n <Accordion :open=\"group.open\" layout=\"seamless\">\n <template #toggle>\n <FieldsetLegend :label=\"group.label\" :for=\"group.label\" />\n </template>\n\n <template #panel>\n <div class=\"p-3\">\n <MultiCheckboxes\n :id=\"`#${group.label}`\"\n v-model=\"searchParams.niches\"\n :options=\"group.options\"\n />\n </div>\n </template>\n </Accordion>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { SearchFindAnAdvisorProfileParams } from \"@/types/profile\"\nimport DismissableBadge from \"@/components/shared/DismissableBadge.vue\"\nimport { useFilterTags } from \"@/composables/filter-tags\"\n\nconst searchParams = defineModel<SearchFindAnAdvisorProfileParams>(\"params\", {\n required: true,\n})\n\nconst filterTags = useFilterTags(searchParams, {\n q: null,\n lat: null,\n long: null,\n state: null,\n location: null, // NOTE(spk): since location is displayed in an input in the main search UI, let's ignore it for now.\n niches: (v) => v,\n})\n</script>\n\n<template>\n <div v-if=\"filterTags.length > 0\" class=\"mt-5 flex justify-start gap-3\">\n <div class=\"h5 shrink-0\">Filters:</div>\n <div class=\"flex-1 flex flex-wrap gap-x-2.5 gap-y-2.5\">\n <DismissableBadge\n v-for=\"(filter, idx) in filterTags\"\n :key=\"idx\"\n :label=\"filter.label\"\n @dismiss=\"filter.remove\"\n />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport {\n computed,\n nextTick,\n onBeforeMount,\n onMounted,\n ref,\n useTemplateRef,\n watch,\n} from \"vue\"\nimport {\n AdjustmentsIcon as AdjustmentsIcon,\n LocationMarkerIcon as LocationIcon,\n SearchIcon as SearchIcon,\n ExclamationIcon as NoResultsIcon,\n ThumbDownIcon as ErrorIcon,\n} from \"@heroicons/vue/outline\"\nimport {\n BaseInput,\n InputLabel,\n Paginator,\n Slideover,\n TrailsRespPaged,\n XYSpinner,\n debounceFn,\n useBaseAPIGet,\n useUrlSearchParams,\n} from \"@xy-planning-network/trees\"\nimport AppLayout from \"@/components/find-an-advisor/shared/AppLayout.vue\"\nimport Card from \"@/components/shared/Card.vue\"\nimport GrayGridBG from \"@/assets/gray-grid.webp\"\nimport ProfileCard from \"@/components/find-an-advisor/index/ProfileCard.vue\"\nimport GradientBG from \"@/assets/gradient-blueberry.webp\"\nimport {\n FindAnAdvisorProfile,\n SearchFindAnAdvisorProfileParams,\n} from \"@/types/profile\"\nimport Border from \"@/components/shared/Border.vue\"\nimport InitialProps from \"@/types/root\"\nimport type { Pagination } from \"@xy-planning-network/trees\"\nimport TransitionGroupFadeDown from \"@/components/shared/TransitionGroupFadeDown.vue\"\nimport CircleIcon from \"@/components/shared/CircleIcon.vue\"\nimport type { Coordinates } from \"@/types/location\"\nimport GooglePlacesField from \"@/components/shared/GooglePlacesField.vue\"\nimport { router } from \"@/routes\"\nimport SearchFields from \"@/components/find-an-advisor/index/SearchFields.vue\"\nimport FilterTags from \"@/components/find-an-advisor/index/FilterTags.vue\"\n\nconst props = defineProps<{\n initialParams: SearchFindAnAdvisorProfileParams\n initialProps: InitialProps\n niches: Record<string, string[]>\n}>()\n\nconst { result, error, isLoading, execute, hasFetched } = useBaseAPIGet<\n TrailsRespPaged<FindAnAdvisorProfile>\n>(router.FindAdvisors(), {\n skipLoader: true,\n withDelay: 650,\n})\n\nconst profiles = computed((): FindAnAdvisorProfile[] => {\n if (result.value && result.value.data.items) {\n return result.value.data.items\n }\n\n return []\n})\n\nconst pagination = ref<Pagination>({\n page: 1,\n perPage: 12, // keep the grid balanced\n totalItems: 0,\n totalPages: 0,\n})\n\nconst showFilters = ref(false)\n\n// useUrlSearchParams updates the searchParams values on window.location.search\nconst searchParams = useUrlSearchParams(props.initialParams)\n\n// debounce the search input field to avoid mutating the query string too early.\nconst debounceSearchInput = debounceFn((inputVal: string) => {\n searchParams.value.q = inputVal\n}, 550)\n\nconst coords = ref<Coordinates>({\n lat: searchParams.value.lat || null,\n long: searchParams.value.long || null,\n})\n\n// keep the coordinates updated in the browser search params\nconst updateCoordsParams = (coords: Coordinates) => {\n searchParams.value.lat = coords.lat || null\n searchParams.value.long = coords.long || null\n}\n\nconst fetchData = () => {\n const params = {\n ...searchParams.value,\n page: pagination.value.page,\n perPage: pagination.value.perPage,\n\n // NOTE: latitude and longitude values of 0 are valid geographic coordinates, but\n // neither value will not provide a meaningful result in our use case so 0's are set on the coords\n // lat, long key's when a location is not set. (Without strict null checks, setting them to null\n // doesn't offer any additional type protection). To avoid sending 0,0 coordinates to the server\n // which may view them as valid.\n lat: searchParams.value.lat || null,\n long: searchParams.value.long || null,\n }\n\n return execute(params).then((r) => {\n pagination.value = {\n page: r.data.page,\n perPage: r.data.perPage,\n totalItems: r.data.totalItems,\n totalPages: r.data.totalPages,\n }\n })\n}\n\n// scoll to and focus primary input from \"start your search\" button\nconst searchInputRef = useTemplateRef(\"searchInput\")\nconst startSearch = () => {\n nextTick(() => {\n document.getElementById(\"search\").scrollIntoView({ behavior: \"smooth\" })\n setTimeout(() => searchInputRef.value.input.focus(), 650)\n })\n}\n\n// update search results as inputs change\n// NOTE: watching only the search params prevents a race condition where fetchData\n// can be called again when pagination is updated from a result\nwatch(searchParams, fetchData, { deep: true })\n\n// kick off initial search request - marking if initial data is available\nonBeforeMount(fetchData)\n\n// send the user straight to the search area if they are returning with a query string\nonMounted(() => {\n if (\n searchParams.value.q != \"\" ||\n searchParams.value.niches?.length > 0 ||\n searchParams.value.location !== \"\"\n ) {\n startSearch()\n }\n})\n</script>\n\n<template>\n <AppLayout :on-faa-btn-click=\"startSearch\">\n <!--Header-->\n <div\n class=\"faa-block py-28 bg-gradient-to-r from-blue-700 to-blue-500 text-white relative\"\n >\n <div\n class=\"bg-scroll bg-cover bg-center absolute inset-0 z-0\"\n :style=\"`background-image: url(${GradientBG});`\"\n />\n <div class=\"container max-w-3xl relative z-10\">\n <div class=\"font-extrabold font-display text-white space-y-6\">\n <h1 class=\"font-extrabold space-y-1\">\n <div class=\"text-base leading-4 uppercase\">Find Your</div>\n <div class=\"text-4xl leading-9 sm:text-5xl xl:text-6xl\">\n Ideal Financial Advisor\n </div>\n </h1>\n <h3\n class=\"font-extrabold text-xl leading-6 sm:text-2xl sm:leading-7 xl:text-3xl 2xl:leading-9 text-gray-50\"\n >\n By niche, specialty, or keyword <br />\n Keep it local or connect remotely\n </h3>\n </div>\n\n <Border size=\"wide\" class=\"mb-10 mt-8\" />\n\n <div class=\"flex flex-col gap-6 sm:flex-row sm:items-center\">\n <button class=\"faa-btn-outline-inverse\" @click=\"startSearch\">\n Start Your Search\n </button>\n </div>\n </div>\n </div>\n\n <!--Search Block-->\n <div id=\"search\" class=\"faa-block pt-16 pb-20 relative\">\n <div\n class=\"bg-neutral-100 bg-scroll bg-center bg-repeat inset-0 absolute opacity-50\"\n :style=\"`background-image: url(${GrayGridBG});`\"\n aria-hidden=\"true\"\n />\n <div class=\"container max-w-screen-xl relative\">\n <!-- Search Fields -->\n <div class=\"mb-12\">\n <Card>\n <h3\n class=\"font-extrabold font-display text-2xl leading-6 md:text-3xl md:leading-7 text-xy-black\"\n >\n Start Your Advisor Search\n </h3>\n <Border size=\"short\" class=\"mt-4 mb-8\" />\n <div\n class=\"grid grid-cols-1 gap-y-3 md:grid-cols-7 md:gap-x-5 xl:gap-x-8 items-center\"\n >\n <div class=\"col-span-3\">\n <div class=\"flex items-center gap-x-2\">\n <div class=\"shrink-0\">\n <div class=\"md:hidden\">\n <CircleIcon\n :icon=\"SearchIcon\"\n size=\"small\"\n bg-color=\"bg-neutral-100\"\n icon-color=\"text-neutral-500\"\n />\n </div>\n <div class=\"hidden md:block\">\n <CircleIcon\n :icon=\"SearchIcon\"\n size=\"normal\"\n bg-color=\"bg-neutral-100\"\n icon-color=\"text-neutral-500\"\n />\n </div>\n </div>\n <div class=\"flex-1\">\n <InputLabel\n id=\"search-label\"\n class=\"sr-only\"\n for=\"search\"\n label=\"Find an Advisor\"\n />\n\n <BaseInput\n id=\"search-input\"\n ref=\"searchInput\"\n :model-value=\"searchParams.q\"\n type=\"text\"\n placeholder=\"Search for an Advisor\"\n aria-labelledby=\"search-label\"\n @update:model-value=\"debounceSearchInput\"\n />\n </div>\n </div>\n </div>\n <div class=\"col-span-3\">\n <div class=\"flex items-center gap-x-2\">\n <div class=\"shrink-0\">\n <div class=\"md:hidden\">\n <CircleIcon\n :icon=\"LocationIcon\"\n size=\"small\"\n bg-color=\"bg-neutral-100\"\n icon-color=\"text-neutral-500\"\n />\n </div>\n <div class=\"hidden md:block\">\n <CircleIcon\n :icon=\"LocationIcon\"\n size=\"normal\"\n bg-color=\"bg-neutral-100\"\n icon-color=\"text-neutral-500\"\n />\n </div>\n </div>\n <div class=\"flex-1\">\n <GooglePlacesField\n v-model:location=\"searchParams.location\"\n v-model:state=\"searchParams.state\"\n v-model:coords=\"coords\"\n placeholder=\"Enter a city, state, or zip code (optional)\"\n @update:coords=\"updateCoordsParams\"\n />\n </div>\n </div>\n </div>\n <div>\n <button\n class=\"xy-btn inline-flex shrink-0 space-x-1 items-center\"\n @click=\"showFilters = true\"\n >\n <AdjustmentsIcon class=\"h-5 w-5\" />\n <span>Filters</span>\n </button>\n </div>\n </div>\n\n <!-- Filter Tags -->\n <FilterTags v-model:params=\"searchParams\" />\n </Card>\n </div>\n\n <!--Search content-->\n <div class=\"relative min-h-[18rem]\">\n <TransitionGroupFadeDown>\n <!-- Profile list -->\n <div\n v-if=\"isLoading\"\n key=\"spinner\"\n class=\"absolute z-10 top-0 left-0 w-full h-full flex items-center justify-center\"\n >\n <XYSpinner>Loading</XYSpinner>\n </div>\n\n <!--Error Notice-->\n <div v-else-if=\"hasFetched && error\" key=\"error\">\n <div class=\"mx-auto max-w-xl\">\n <Card>\n <div\n class=\"flex items-center justify-between space-x-5 text-xy-black\"\n >\n <h4 class=\"font-display font-extrabold text-xl leading-5\">\n Whoops! Something's gone haywire.\n </h4>\n <div class=\"shrink-0 ml-auto\" aria-hidden=\"true\">\n <CircleIcon\n :icon=\"ErrorIcon\"\n bg-color=\"bg-red-50\"\n icon-color=\"text-red-400\"\n />\n </div>\n </div>\n <Border size=\"short\" class=\"mt-5 mb-6\" />\n <p>\n This is unusual and we've probably already been alerted to\n it, but if you continue to see this message please\n <a\n href=\"mailto:membership@xyplanningnetwork.com?subject=Find an Advisor search error\"\n class=\"xy-link\"\n >let us know</a\n >.\n </p>\n </Card>\n </div>\n </div>\n\n <!--No Matches-->\n <div\n v-else-if=\"hasFetched && profiles.length === 0\"\n key=\"not-found\"\n >\n <div class=\"mx-auto max-w-xl\">\n <Card>\n <div\n class=\"flex items-center justify-between space-x-5 text-xy-black\"\n >\n <h4 class=\"font-display font-extrabold text-xl leading-5\">\n We didn't find any Advisors that match your search\n criteria.\n </h4>\n <div class=\"shrink-0 ml-auto\" aria-hidden=\"true\">\n <CircleIcon\n :icon=\"NoResultsIcon\"\n bg-color=\"bg-orange-50\"\n icon-color=\"text-orange-400\"\n />\n </div>\n </div>\n <Border size=\"short\" class=\"mt-5 mb-6\" />\n <p>\n <b>Pro Tip:</b> Many XYPN Advisors are available to work\n with clients virtually. Start your search off with a single\n specialty, niche, or keyword that's important to you and\n refine the results from there.\n </p>\n </Card>\n </div>\n </div>\n\n <!--Profile Cards-->\n <div v-else-if=\"profiles.length > 0\" key=\"profiles\">\n <ul class=\"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6\">\n <li\n v-for=\"profile in profiles\"\n :key=\"profile.slug\"\n class=\"grid grid-cols-1\"\n >\n <ProfileCard :profile=\"profile\" />\n </li>\n </ul>\n </div>\n\n <!--Pagination-->\n <div\n v-if=\"hasFetched && !isLoading && profiles.length > 0\"\n key=\"pages\"\n class=\"mt-12\"\n >\n <Card>\n <div class=\"pb-2.5\">\n <Paginator\n v-model=\"pagination\"\n @update:model-value=\"fetchData\"\n />\n </div>\n </Card>\n </div>\n </TransitionGroupFadeDown>\n </div>\n </div>\n <!--search filters slideover used for narrow layouts-->\n <Slideover\n v-model=\"showFilters\"\n header=\"Narrow Your Search\"\n description=\"Find an advisor who serves you\"\n class=\"z-50\"\n >\n <div class=\"relative h-full flex flex-col\">\n <SearchFields v-model:params=\"searchParams\" :niches=\"niches\" />\n <!--Actions-->\n <div\n class=\"sticky inset-x-0 bottom-0 mt-auto py-6 px-3 bg-white border-t border-gray-100 z-50\"\n >\n <div class=\"flex items-center justify-between gap-x-2 -mx-2\">\n <button class=\"xy-btn flex-1\" @click=\"showFilters = false\">\n View\n </button>\n <!-- TODO(dlk): do we want to clear location & search bar searches? -->\n <a class=\"flex-1 xy-btn-neutral\" href=\"/find-an-advisor\">\n Clear All\n </a>\n </div>\n </div>\n </div>\n </Slideover>\n </div>\n </AppLayout>\n</template>\n","import Main from \"../components/find-an-advisor/Index.vue\"\nimport init from \"../root_init\"\ninit(Main)\n"],"names":["render","_ctx","_cache","_openBlock","_createBlock","_createVNode","props","__props","profile","toRef","idealClientsList","profileImageURL","useFindAnAdvisorProfile","searchParams","_useModel","searchFilter","ref","lazySearchFilter","debounceFn","inputVal","nicheOptions","computed","niches","filtered","cat","nichesMatches","n","recordToMultiselectOptions","nicheGroup","groupActive","active","option","_a","filterTags","useFilterTags","v","result","error","isLoading","execute","hasFetched","useBaseAPIGet","router","profiles","pagination","showFilters","useUrlSearchParams","debounceSearchInput","coords","updateCoordsParams","fetchData","params","r","searchInputRef","useTemplateRef","startSearch","nextTick","watch","onBeforeMount","onMounted","init","Main"],"mappings":"i9CAEe,SAASA,EAAOC,EAAMC,EAAQ,CAC3C,OAAQC,EAAU,EAAIC,EAAa,MAAO,CACxC,MAAO,6BACP,KAAM,OACN,QAAS,YACT,eAAgB,IAChB,OAAQ,eACR,cAAe,MACnB,EAAK,CACDC,EAAa,OAAQ,CACnB,iBAAkB,QAClB,kBAAmB,QACnB,EAAG,oFACT,CAAK,EACDA,EAAa,OAAQ,CACnB,iBAAkB,QAClB,kBAAmB,QACnB,EAAG,kCACJ,CAAA,CACL,CAAG,CACH,qoBCbA,MAAMC,EAAQC,EACRC,EAAUC,EAAMH,EAAO,SAAS,EAEhC,CAAE,iBAAAI,EAAkB,gBAAAC,CAAA,EAAoBC,GAC5CN,EAAM,OACR,4vCCFA,MAAMA,EAAQC,EAIRM,EAAeC,EAA6CP,EAAC,QAElE,EAGKQ,EAAeC,EAAI,EAAE,EACrBC,EAAmBC,EAAYC,GAAqB,CAC3CJ,EAAA,MAAQI,EAAS,KAAK,GAClC,GAAG,EAWAC,EAAeC,EAAS,IAAM,CAClC,IAAIC,EAAShB,EAAM,OAEnB,OAAIS,EAAa,QACfO,EAAS,OAAO,QAAQhB,EAAM,MAAM,EAAE,OACpC,CAACiB,EAAU,CAACC,EAAKF,CAAM,IAAM,CAC3B,MAAMG,EAAgBH,EAAO,OAAQI,GACnCA,EAAE,YAAA,EAAc,SAASX,EAAa,MAAM,YAAa,CAAA,CAC3D,EAEI,OAAAU,EAAc,OAAS,IACzBF,EAASC,CAAG,EAAIC,GAGXF,CACT,EACA,CAAA,CACF,GAGKI,GAA2BL,CAAM,EAAE,IAAKM,GAAe,CAC5D,MAAMC,EAAcD,EAAW,QAAQ,OAAO,CAACE,EAAQC,IAAW,OAChE,OAAIC,EAAAnB,EAAa,MAAM,SAAnB,MAAAmB,EAA2B,SAASD,EAAO,SACpCD,EAAA,IAEJA,GACN,EAAK,EAED,MAAA,CACL,GAAGF,EACH,KAAMb,EAAa,MAAQ,GAAOc,CACpC,CAAA,CACD,CAAA,CACF,s9BC/DK,MAAAhB,EAAeC,EAA6CP,EAAC,QAElE,EAEK0B,EAAaC,GAAcrB,EAAc,CAC7C,EAAG,KACH,IAAK,KACL,KAAM,KACN,MAAO,KACP,SAAU,KACV,OAASsB,GAAMA,CAAA,CAChB,qxDCgCD,MAAM7B,EAAQC,EAMR,CAAE,OAAA6B,EAAQ,MAAAC,EAAO,UAAAC,EAAW,QAAAC,EAAS,WAAAC,GAAeC,EAExDC,EAAO,eAAgB,CACvB,WAAY,GACZ,UAAW,GAAA,CACZ,EAEKC,EAAWtB,EAAS,IACpBe,EAAO,OAASA,EAAO,MAAM,KAAK,MAC7BA,EAAO,MAAM,KAAK,MAGpB,CAAC,CACT,EAEKQ,EAAa5B,EAAgB,CACjC,KAAM,EACN,QAAS,GACT,WAAY,EACZ,WAAY,CAAA,CACb,EAEK6B,EAAc7B,EAAI,EAAK,EAGvBH,EAAeiC,GAAmBxC,EAAM,aAAa,EAGrDyC,EAAsB7B,EAAYC,GAAqB,CAC3DN,EAAa,MAAM,EAAIM,GACtB,GAAG,EAEA6B,EAAShC,EAAiB,CAC9B,IAAKH,EAAa,MAAM,KAAO,KAC/B,KAAMA,EAAa,MAAM,MAAQ,IAAA,CAClC,EAGKoC,EAAsBD,GAAwB,CACrCnC,EAAA,MAAM,IAAMmC,EAAO,KAAO,KAC1BnC,EAAA,MAAM,KAAOmC,EAAO,MAAQ,IAC3C,EAEME,EAAY,IAAM,CACtB,MAAMC,EAAS,CACb,GAAGtC,EAAa,MAChB,KAAM+B,EAAW,MAAM,KACvB,QAASA,EAAW,MAAM,QAO1B,IAAK/B,EAAa,MAAM,KAAO,KAC/B,KAAMA,EAAa,MAAM,MAAQ,IACnC,EAEA,OAAO0B,EAAQY,CAAM,EAAE,KAAMC,GAAM,CACjCR,EAAW,MAAQ,CACjB,KAAMQ,EAAE,KAAK,KACb,QAASA,EAAE,KAAK,QAChB,WAAYA,EAAE,KAAK,WACnB,WAAYA,EAAE,KAAK,UACrB,CAAA,CACD,CACH,EAGMC,EAAiBC,GAAe,aAAa,EAC7CC,EAAc,IAAM,CACxBC,GAAS,IAAM,CACb,SAAS,eAAe,QAAQ,EAAE,eAAe,CAAE,SAAU,SAAU,EACvE,WAAW,IAAMH,EAAe,MAAM,MAAM,QAAS,GAAG,CAAA,CACzD,CACH,EAKA,OAAAI,GAAM5C,EAAcqC,EAAW,CAAE,KAAM,GAAM,EAG7CQ,GAAcR,CAAS,EAGvBS,GAAU,IAAM,QAEZ9C,EAAa,MAAM,GAAK,MACxBmB,EAAAnB,EAAa,MAAM,SAAnB,YAAAmB,EAA2B,QAAS,GACpCnB,EAAa,MAAM,WAAa,KAEpB0C,EAAA,CACd,CACD,+iKClJDK,EAAKC,EAAI","x_google_ignoreList":[0]}