{"version":3,"file":"index.a1d968e2.js","sources":["../../vite/dynamic-import-polyfill","../../src/utils/Strings.ts","../../src/state/State.ts","../../src/utils/Analytics.ts","../../src/routing/Router.ts","../../src/storage/DB.ts","../../src/utils/Messaging.ts","../../src/utils/ServiceWorkers.ts","../../src/vmd-app.component.ts","../../src/components/vmd-tranche-age-selector.component.ts","../../src/components/vmd-departement-selector.component.ts","../../src/utils/Dates.ts","../../src/components/vmd-appointment-card.component.ts","../../src/components/vmd-appointment-metadata.component.ts","../../src/components/vmd-commune-selector.component.ts","../../src/components/vmd-selector.component.ts","../../src/components/vmd-button-switch.component.ts","../../src/views/vmd-home.view.ts","../../src/distance.ts","../../src/utils/Departements.ts","../../src/utils/Capabilities.ts","../../src/utils/Arrays.ts","../../src/views/vmd-rdv.view.ts","../../src/utils/Schedulers.ts","../../src/views/vmd-lieux.view.ts","../../src/views/vmd-apropos.view.ts"],"sourcesContent":["const p = function polyfill(modulePath = '.', importFunctionName = '__import__') {\n try {\n self[importFunctionName] = new Function('u', `return import(u)`);\n }\n catch (error) {\n const baseURL = new URL(modulePath, location);\n const cleanup = (script) => {\n URL.revokeObjectURL(script.src);\n script.remove();\n };\n self[importFunctionName] = (url) => new Promise((resolve, reject) => {\n const absURL = new URL(url, baseURL);\n // If the module has already been imported, resolve immediately.\n if (self[importFunctionName].moduleMap[absURL]) {\n return resolve(self[importFunctionName].moduleMap[absURL]);\n }\n const moduleBlob = new Blob([\n `import * as m from '${absURL}';`,\n `${importFunctionName}.moduleMap['${absURL}']=m;`\n ], { type: 'text/javascript' });\n const script = Object.assign(document.createElement('script'), {\n type: 'module',\n src: URL.createObjectURL(moduleBlob),\n onerror() {\n reject(new Error(`Failed to import: ${url}`));\n cleanup(script);\n },\n onload() {\n resolve(self[importFunctionName].moduleMap[absURL]);\n cleanup(script);\n }\n });\n document.head.appendChild(script);\n });\n self[importFunctionName].moduleMap = {};\n }\n};__VITE_IS_MODERN__&&p(\"/134-merge/assets/\");","\n\nexport class Strings {\n public static padLeft(value: number, size: number, filler: string) {\n const padSize = size - (\"\"+value).length;\n let pad = '';\n for(var i=0; i1)?pluralForm:'';\n }\n\n static toNormalizedPhoneNumber(phoneNumber: string|undefined) {\n if(phoneNumber === undefined) {\n return undefined;\n }\n\n let normalizedPhoneNumber = phoneNumber!;\n const formatInternational = normalizedPhoneNumber.indexOf(\"+\") === 0;\n // Removing non-chars\n normalizedPhoneNumber = normalizedPhoneNumber.replace(/[\\.\\s]/gi, \"\");\n if(formatInternational) {\n normalizedPhoneNumber = `0${normalizedPhoneNumber.substring(normalizedPhoneNumber.length - 9, normalizedPhoneNumber.length)}`\n }\n\n normalizedPhoneNumber = [\n normalizedPhoneNumber[0], normalizedPhoneNumber[1], \" \",\n normalizedPhoneNumber[2], normalizedPhoneNumber[3], \" \",\n normalizedPhoneNumber[4], normalizedPhoneNumber[5], \" \",\n normalizedPhoneNumber[6], normalizedPhoneNumber[7], \" \",\n normalizedPhoneNumber[8], normalizedPhoneNumber[9]\n ].join(\"\");\n\n return normalizedPhoneNumber;\n }\n\n public static toReadableURLPathValue(value: string) {\n return value.toLowerCase()\n .replace(/[-\\s']/gi, \"_\")\n .replace(/[èéëêêéè]/gi, \"e\")\n .replace(/[áàâäãåâà]/gi, \"a\")\n .replace(/[çç]/gi, \"c\")\n .replace(/[íìîï]/gi, \"i\")\n .replace(/[ñ]/gi, \"n\")\n .replace(/[óòôöõô]/gi, \"o\")\n .replace(/[úùûüûù]/gi, \"u\")\n .replace(/[œ]/gi, \"oe\");\n }\n\n public static toFullTextSearchableString(value: string) {\n // /!\\ important note : this is important to have the same implementation of toFullTextSearchableString()\n // function here, than the one used in communes-import.js tooling\n return value.toLowerCase()\n .replace(/[-\\s']/gi, \"_\")\n .replace(/[èéëêêéè]/gi, \"e\")\n .replace(/[áàâäãåâà]/gi, \"a\")\n .replace(/[çç]/gi, \"c\")\n .replace(/[íìîï]/gi, \"i\")\n .replace(/[ñ]/gi, \"n\")\n .replace(/[óòôöõô]/gi, \"o\")\n .replace(/[úùûüûù]/gi, \"u\")\n .replace(/[œ]/gi, \"oe\");\n }\n}\n","import {ISODateString, WeekDay} from \"../utils/Dates\";\nimport {Strings} from \"../utils/Strings\";\n\nexport type CodeTrancheAge = 'plus75ans';\nexport type TrancheAge = {\n codeTrancheAge: CodeTrancheAge;\n libelle: string;\n};\nexport const TRANCHES_AGE: Map = new Map([\n ['plus75ans', { codeTrancheAge: 'plus75ans', libelle: \"Plus de 75 ans\" }]\n]);\n\nexport type CodeTriCentre = 'date' | 'distance';\nexport type TriCentre = {\n codeTriCentre: CodeTriCentre;\n libelle: string;\n};\nexport const TRIS_CENTRE: Map = new Map([\n ['distance', { codeTriCentre: 'distance', libelle: \"Au plus proche\" }],\n ['date', { codeTriCentre: 'date', libelle: \"Disponible au plus vite\" }],\n]);\n\nconst USE_RAW_GITHUB = false\nconst VMD_BASE_URL = USE_RAW_GITHUB\n ? \"https://raw.githubusercontent.com/CovidTrackerFr/vitemadose/data-auto/data/output\"\n : \"https://vitemadose.gitlab.io/vitemadose\"\n\n\nexport type Plateforme = {\n // Should be the same than PLATEFORMES' key\n code: string;\n logo: string;\n nom: string;\n // Should we do promotion of this plateform ? for example on home screen ?\n // (typically, it may be not a good idea to promote the platform while JSON is not producing data for it yet)\n promoted: boolean;\n website: string;\n // Used for specific styling on logos, see for example _searchAppointment.scss\n styleCode: string;\n};\nexport const PLATEFORMES: Record = {\n 'Doctolib': { code: 'Doctolib', logo: 'logo_doctolib.png', nom: 'Doctolib', promoted: true, website: 'https://www.doctolib.fr/', styleCode: '_doctolib'},\n 'Maiia': { code: 'Maiia', logo: 'logo_maiia.png', nom: 'Maiia', promoted: true, website: 'https://www.maiia.com/', styleCode: '_maiia'},\n 'Ordoclic': { code: 'Ordoclic', logo: 'logo_ordoclic.png', nom: 'Ordoclic', promoted: true, website: 'https://covid-pharma.fr/', styleCode: '_ordoclic'},\n 'Keldoc': { code: 'Keldoc', logo: 'logo_keldoc.png', nom: 'Keldoc', promoted: true, website: 'https://www.keldoc.com/', styleCode: '_keldoc'},\n 'Pandalab': { code: 'Pandalab', logo: 'logo_pandalab.png', nom: 'Pandalab', promoted: false, website: 'https://masante.pandalab.eu/welcome', styleCode: '_pandalab'},\n 'Mapharma': { code: 'Mapharma', logo: 'logo_mapharma.png', nom: 'Mapharma', promoted: true, website: 'https://mapharma.net/login', styleCode: '_mapharma'},\n // Beware: if you add a new plateform, don't forget to update 'hardcoded' (indexable) content\n // in index.html page, referencing the list of supported plateforms\n};\n\nexport type CodeDepartement = string;\nexport type Departement = {\n code_departement: CodeDepartement;\n nom_departement: string;\n code_region: number;\n nom_region: string;\n};\n// Permet de convertir un nom de departement en un chemin d'url correct (remplacement des caractères\n// non valides comme les accents ou les espaces)\nexport const libelleUrlPathDuDepartement = (departement: Departement) => {\n return Strings.toReadableURLPathValue(departement.nom_departement);\n}\n\nexport type TypeLieu = 'vaccination-center'|'drugstore'|'general-practitioner';\nexport const TYPES_LIEUX: {[k in TypeLieu]: string} = {\n \"vaccination-center\": 'Centre de vaccination',\n \"drugstore\": 'Pharmacie',\n \"general-practitioner\": 'Médecin généraliste',\n};\nexport type BusinessHours = Record;\nexport type Lieu = {\n appointment_count: number;\n departement: CodeDepartement;\n location: Coordinates,\n nom: string;\n url: string;\n gid: string;\n appointment_by_phone_only: boolean;\n plateforme: string;\n prochain_rdv: ISODateString|null;\n metadata: {\n address: string;\n phone_number: string|undefined;\n business_hours: BusinessHours|undefined\n },\n type: TypeLieu;\n vaccine_type: string\n};\n\nexport function sameLieu(l1: Lieu, l2: Lieu) {\n // TODO: do a better matching ? (based on an id on lieu ?)\n return l1.nom === l2.nom;\n}\n\nfunction transformLieu(rawLieu: any): Lieu {\n return {\n ...rawLieu,\n appointment_count: rawLieu.appointment_count || 0,\n metadata: {\n ...rawLieu.metadata,\n address: (typeof rawLieu.metadata.address === 'string')?\n rawLieu.metadata.address\n :[\n rawLieu.metadata.address.adr_num,\n rawLieu.metadata.address.adr_voie,\n rawLieu.metadata.address.com_cp,\n rawLieu.metadata.address.com_nom\n ].filter(val => !!val).join(\" \"),\n },\n vaccine_type: rawLieu.vaccine_type?((rawLieu.vaccine_type.length===undefined?[rawLieu.vaccine_type]:rawLieu.vaccine_type)).join(\", \"):undefined\n };\n}\nexport type Coordinates = { latitude: number, longitude: number }\n\nexport type LieuxParDepartement = {\n lieuxDisponibles: Lieu[];\n lieuxIndisponibles: Lieu[];\n codeDepartements: CodeDepartement[];\n derniereMiseAJour: ISODateString;\n};\nexport type LieuxParDepartements = Map;\n\nexport type LieuAffichableAvecDistance = Lieu & { disponible: boolean, distance: number|undefined };\nexport type LieuxAvecDistanceParDepartement = {\n lieuxAffichables: LieuAffichableAvecDistance[];\n codeDepartements: CodeDepartement[];\n derniereMiseAJour: ISODateString;\n};\nexport function typeActionPour(lieuAffichable: LieuAffichableAvecDistance): 'actif-via-plateforme'|'inactif-via-plateforme'|'actif-via-tel'|'inactif' {\n const phoneOnly = lieuAffichable.appointment_by_phone_only && lieuAffichable.metadata.phone_number;\n if(phoneOnly) { // Phone only may have url, but we should ignore it !\n return 'actif-via-tel';\n } else if(lieuAffichable && lieuAffichable.appointment_count !== 0){\n return 'actif-via-plateforme';\n } else if(lieuAffichable && lieuAffichable.appointment_count === 0){\n return 'inactif-via-plateforme';\n } else {\n return 'inactif';\n }\n}\n\nfunction convertDepartementForSort(codeDepartement: CodeDepartement) {\n switch(codeDepartement) {\n case '2A': return '20A';\n case '2B': return '20B';\n default: return codeDepartement;\n }\n}\n\nexport type StatLieu = {disponibles: number, total: number, creneaux: number};\nexport type StatLieuGlobale = StatLieu & { proportion: number };\nexport type StatsLieuParDepartement = Record\nexport type StatsLieu = {\n parDepartements: StatsLieuParDepartement;\n global: StatLieuGlobale;\n}\n\nexport type CommunesParAutocomplete = Map;\nexport type Commune = {\n code: string;\n codePostal: string;\n nom: string;\n codeDepartement: string;\n latitude: number|undefined;\n longitude: number|undefined;\n};\n// Permet de convertir un nom de departement en un chemin d'url correct (remplacement des caractères\n// non valides comme les accents ou les espaces)\nexport const libelleUrlPathDeCommune = (commune: Commune) => {\n return Strings.toReadableURLPathValue(commune.nom);\n}\n\nexport class State {\n public static current = new State();\n\n private static DEPARTEMENT_VIDE: Departement = {\n code_departement: \"\",\n code_region: 0,\n nom_departement: \"\",\n nom_region: \"\"\n };\n\n private static COMMUNE_VIDE: Commune = {\n code: \"\",\n codeDepartement: \"\",\n codePostal: \"\",\n latitude: undefined,\n longitude: undefined,\n nom: \"\"\n };\n\n private constructor() {\n }\n\n private _lieuxParDepartement: LieuxParDepartements = new Map();\n async lieuxPour(codeDepartement: CodeDepartement, avoidCache: boolean = false): Promise {\n if(this._lieuxParDepartement.has(codeDepartement) && !avoidCache) {\n return Promise.resolve(this._lieuxParDepartement.get(codeDepartement)!);\n } else {\n const resp = await fetch(`${VMD_BASE_URL}/${codeDepartement}.json`)\n const results = await resp.json()\n const lieuxParDepartement = {\n lieuxDisponibles: results.centres_disponibles.map(transformLieu),\n lieuxIndisponibles: results.centres_indisponibles.map(transformLieu),\n codeDepartements: [codeDepartement],\n derniereMiseAJour: results.last_updated\n };\n this._lieuxParDepartement.set(codeDepartement, lieuxParDepartement);\n return lieuxParDepartement;\n }\n }\n\n private _departementsDiponibles: Departement[]|undefined = undefined;\n async departementsDisponibles(): Promise {\n if(this._departementsDiponibles !== undefined) {\n return Promise.resolve(this._departementsDiponibles);\n } else {\n const resp = await fetch(`${VMD_BASE_URL}/departements.json`)\n const departements: Departement[] = await resp.json()\n\n this._departementsDiponibles = departements;\n this._departementsDiponibles.sort((d1, d2) => convertDepartementForSort(d1.code_departement).localeCompare(convertDepartementForSort(d2.code_departement)));\n return departements;\n }\n }\n\n async chercheDepartementParCode(code: string): Promise {\n let deps = await this.departementsDisponibles();\n return deps.find(dep => dep.code_departement === code) || State.DEPARTEMENT_VIDE;\n }\n\n private _communeAutocompleteTriggers: string[]|undefined = undefined;\n async communeAutocompleteTriggers(basePath: string): Promise {\n if(this._communeAutocompleteTriggers !== undefined) {\n return Promise.resolve(this._communeAutocompleteTriggers)\n } else {\n const autocompletes = await fetch(`${basePath}autocompletes.json`).then(resp => resp.json());\n\n this._communeAutocompleteTriggers = autocompletes;\n return autocompletes;\n }\n }\n\n private _communesParAutocomplete: CommunesParAutocomplete = new Map();\n async communesPourAutocomplete(basePath: string, autocomplete: string): Promise {\n if(this._communesParAutocomplete.has(autocomplete)) {\n return this._communesParAutocomplete.get(autocomplete)!;\n } else {\n const communes = await fetch(`${basePath}autocomplete-cache/${autocomplete}.json`)\n .then(resp => resp.json())\n .then(communesResult => communesResult.communes.map((c: any) => {\n const commune: Commune = {\n code: c.c,\n codePostal: c.z,\n nom: c.n,\n codeDepartement: c.d,\n longitude: c.g?Number(c.g.split(\",\")[0]):undefined,\n latitude: c.g?Number(c.g.split(\",\")[1]):undefined,\n };\n return commune;\n }));\n\n this._communesParAutocomplete.set(autocomplete, communes);\n return communes;\n }\n }\n\n async chercheCommuneParCode(basePath: string, codePostal: string, codeCommune: string): Promise {\n let triggers = await this.communeAutocompleteTriggers(basePath);\n let trigger = triggers.find(trigger => codePostal.startsWith(trigger));\n if (trigger) {\n let communes = await this.communesPourAutocomplete(basePath, trigger);\n return communes.find(commune => commune.code === codeCommune) || State.COMMUNE_VIDE;\n } else {\n return Promise.resolve(State.COMMUNE_VIDE);\n }\n }\n\n private _statsLieu: StatsLieu|undefined = undefined;\n async statsLieux(): Promise {\n if(this._statsLieu !== undefined) {\n return Promise.resolve(this._statsLieu);\n } else {\n const resp = await fetch(`${VMD_BASE_URL}/stats.json`)\n const statsParDepartements: Record = await resp.json()\n\n const statsLieu = {\n parDepartements: Object.entries(statsParDepartements)\n .filter(([dpt, stats]: [CodeDepartement|\"tout_departement\", StatLieu]) => dpt !== 'tout_departement')\n .reduce((statsParDept, [dpt, stats]: [CodeDepartement, StatLieu]) => {\n statsParDepartements[dpt] = stats;\n return statsParDepartements;\n }, {} as StatsLieuParDepartement),\n global: {\n ...statsParDepartements['tout_departement'],\n proportion: Math.round(statsParDepartements['tout_departement'].disponibles * 10000 / statsParDepartements['tout_departement'].total)/100\n }\n };\n this._statsLieu = statsLieu;\n return statsLieu;\n }\n }\n\n public static currentEnv(): 'dev'|'prod' {\n return window.location.hostname === \"vitemadose.covidtracker.fr\"?'prod':'dev';\n }\n}\n","import {\n CodeDepartement, CodeTriCentre,\n Commune,\n Lieu,\n LieuxAvecDistanceParDepartement, typeActionPour,\n} from \"../state/State\";\n\n\ntype PushBaseParams = Record & {event: string};\n\ndeclare global {\n interface Window {\n dataLayer: {\n push: (params: PushBaseParams) => void;\n };\n }\n}\n\nexport class Analytics {\n public static readonly INSTANCE = new Analytics();\n\n protected constructor() {\n }\n\n navigationSurNouvellePage(nomPage: string) {\n window.dataLayer.push({\n 'event': 'change_screen',\n 'site_name' : 'vite_ma_dose',\n 'page_type' : nomPage\n });\n }\n\n clickSurRdv(lieu: Lieu) {\n window.dataLayer.push({\n 'event': 'rdv_click',\n 'rdv_departement' : lieu.departement,\n 'rdv_platorm' : lieu.plateforme,\n 'rdv_platform' : lieu.plateforme,\n 'rdv_name': lieu.nom,\n 'rdv_location_type' : lieu.type,\n 'rdv_vaccine' : lieu.vaccine_type,\n 'rdv_filter_type' : undefined\n });\n }\n\n clickSurVerifRdv(lieu: Lieu) {\n window.dataLayer.push({\n 'event': 'rdv_verify',\n 'rdv_departement' : lieu.departement,\n 'rdv_platorm' : lieu.plateforme,\n 'rdv_platform' : lieu.plateforme,\n 'rdv_name': lieu.nom,\n 'rdv_location_type' : lieu.type,\n 'rdv_vaccine' : lieu.vaccine_type,\n 'rdv_filter_type' : undefined\n });\n }\n\n rechercheLieuEffectuee(codeDepartement: CodeDepartement, commune: Commune|undefined, resultats: LieuxAvecDistanceParDepartement|undefined) {\n window.dataLayer.push({\n 'event': commune?'search_by_commune':'search_by_departement',\n 'search_departement': codeDepartement,\n 'search_commune' : commune?`${commune.codePostal} - ${commune.nom} (${commune.code})`:undefined,\n // kept for legacy reasons\n 'search_nb_doses' : resultats?resultats.lieuxAffichables.reduce((totalDoses, lieu) => totalDoses+lieu.appointment_count, 0):undefined,\n 'search_nb_appointments' : resultats?resultats.lieuxAffichables.reduce((totalDoses, lieu) => totalDoses+lieu.appointment_count, 0):undefined,\n 'search_nb_lieu_vaccination' : resultats?resultats.lieuxAffichables\n .filter(l => typeActionPour(l) === 'actif-via-plateforme' || typeActionPour(l) === 'actif-via-tel')\n .length:undefined,\n 'search_nb_lieu_vaccination_inactive' : resultats?resultats.lieuxAffichables\n .filter(l => typeActionPour(l) === 'inactif')\n .length:undefined,\n 'search_filter_type': (this as any).critèreDeTri || 'date'\n });\n }\n\n critereTriCentresMisAJour(triCentre: CodeTriCentre) {\n window.dataLayer.push({\n 'event': 'sort_change',\n 'sort_changed_to' : triCentre,\n });\n }\n\n}\n","import page from \"page\";\nimport { TemplateResult } from \"lit-html\";\nimport {html} from \"lit-element\";\nimport {CodeTriCentre, State} from \"../state/State\";\nimport {Analytics} from \"../utils/Analytics\";\n\nexport type SlottedTemplateResultFactory = (subViewSlot: TemplateResult) => TemplateResult;\n\nexport type ViewChangedCallback = (templateResultCreator: SlottedTemplateResultFactory, path: string) => void;\nexport type ViewChangedCallbackCleaner = Function;\nexport type TitleProvider = (pathParams: Record) => Promise;\n\ntype RouteDeclaration = {\n pathPattern: string|string[];\n analyticsViewName: string;\n viewContent: (pathParams: Record) => Promise|SlottedTemplateResultFactory;\n pageTitleProvider?: TitleProvider;\n};\n\nclass Routing {\n public static readonly INSTANCE = new Routing();\n\n private static readonly DEFAULT_TITLE = 'Vite Ma Dose : trouvez un créneau de vaccination COVID-19';\n private static readonly DEFAULT_TITLE_PROMISE: TitleProvider =\n () => Promise.resolve(Routing.DEFAULT_TITLE);\n\n private _viewChangeCallbacks: ViewChangedCallback[] = [];\n\n private currentTemplateResultCreator: SlottedTemplateResultFactory|undefined = undefined;\n private currentPath: string|undefined = undefined;\n\n public get basePath() {\n return import.meta.env.BASE_URL;\n }\n\n installRoutes(callback?: ViewChangedCallback): ViewChangedCallbackCleaner|undefined {\n const callbackCleaner = callback?this.onViewChanged(callback):undefined;\n\n page.redirect(`${this.basePath}home`, `/`);\n page.redirect(`${this.basePath}index.html`, `/`);\n\n this.declareRoutes({\n pathPattern: `/`, analyticsViewName: 'home',\n viewContent: (params) => (subViewSlot) =>\n html`${subViewSlot}`\n });\n this.declareRoutes({\n pathPattern: [\n // Legacy URLs with tranche age inside ... used only for old URLs referenced by Google\n `/centres-vaccination-covid-dpt:codeDpt-:nomDpt/age-:trancheAge/`,\n `/centres-vaccination-covid-dpt:codeDpt-:nomDpt/ville-:codeVille-:nomVille/age-:trancheAge/`,\n // Proper URL really used\n `/centres-vaccination-covid-dpt:codeDpt-:nomDpt`\n ], analyticsViewName: 'search_results_by_department',\n viewContent: (params) => (subViewSlot) =>\n html`${subViewSlot}`,\n pageTitleProvider: (params) =>\n State.current.chercheDepartementParCode(params[`codeDpt`])\n .then(nomDpt => `Vaccination COVID-19 en ${nomDpt.nom_departement} ${params[`codeDpt`]}`)\n });\n this.declareRoutes({\n pathPattern: `/centres-vaccination-covid-dpt:codeDpt-:nomDpt/commune:codeCommune-:codePostal-:nomCommune/en-triant-par-:codeTriCentre`,\n analyticsViewName: 'search_results_by_city',\n viewContent: (params) => (subViewSlot) =>\n html`\n ${subViewSlot}\n `,\n pageTitleProvider: (params) =>\n State.current.chercheCommuneParCode(Router.basePath, params['codePostal'], params['codeCommune'])\n .then(commune => `Vaccination COVID-19 à ${commune.nom} ${commune.codePostal}`)\n });\n this.declareRoutes({\n pathPattern: `/centres`, analyticsViewName: 'centres',\n viewContent: (params) => (subViewSlot) =>\n html`${subViewSlot}`\n });\n this.declareRoutes({\n pathPattern: `/apropos`, analyticsViewName: 'a_propos',\n viewContent: (params) => (subViewSlot) =>\n html`${subViewSlot}`\n });\n\n page(`*`, (context) => this._notFoundRoute(context));\n page();\n\n return callbackCleaner;\n }\n\n private declareRoutes(routeDeclaration: RouteDeclaration) {\n const paths: string[] = (typeof routeDeclaration.pathPattern === 'string') ? [routeDeclaration.pathPattern] : routeDeclaration.pathPattern;\n paths.forEach(path => {\n this._declareRoute(path, routeDeclaration.analyticsViewName, routeDeclaration.viewContent, routeDeclaration.pageTitleProvider || Routing.DEFAULT_TITLE_PROMISE);\n });\n }\n\n private _declareRoute(path: string, pageName: string, viewComponentCreator: (pathParams: Record) => Promise|SlottedTemplateResultFactory,\n titlePromise = Routing.DEFAULT_TITLE_PROMISE) {\n page(`${this.basePath}${path.substring(path[0]==='/'?1:0)}`, (context) => {\n const slottedViewComponentFactoryResult = viewComponentCreator(context.params);\n\n Promise.all([\n ((slottedViewComponentFactoryResult instanceof Promise)?\n slottedViewComponentFactoryResult\n :\n Promise.resolve(slottedViewComponentFactoryResult)),\n titlePromise(context.params).catch(() => Routing.DEFAULT_TITLE)\n ]).then(([slottedViewTemplateFactory, title]) => {\n this.currentPath = path;\n this.currentTemplateResultCreator = slottedViewTemplateFactory;\n\n document.title = title;\n\n this._viewChangeCallbacks.forEach(callback => callback(slottedViewTemplateFactory, path));\n\n Analytics.INSTANCE.navigationSurNouvellePage(pageName);\n })\n });\n }\n\n onViewChanged(callback: ViewChangedCallback): ViewChangedCallbackCleaner {\n this._viewChangeCallbacks.push(callback);\n return () => {\n const idx = this._viewChangeCallbacks.findIndex(registeredCallback => registeredCallback === callback);\n this._viewChangeCallbacks.splice(idx, 1);\n }\n }\n\n private _notFoundRoute(context: PageJS.Context) {\n console.error(`Route not found : ${context.path} ! Redirecting to home...`);\n this.navigateToHome();\n }\n\n public navigateToRendezVousAvecDepartement(codeDepartement: string, pathLibelleDepartement: string) {\n page(`${this.basePath}centres-vaccination-covid-dpt${codeDepartement}-${pathLibelleDepartement}`);\n }\n\n public navigateToRendezVousAvecCommune(codeTriCentre: CodeTriCentre, codeDepartement: string, pathLibelleDepartement: string, codeCommune: string, codePostal: string, pathLibelleCommune: string) {\n page(`${this.basePath}centres-vaccination-covid-dpt${codeDepartement}-${pathLibelleDepartement}/commune${codeCommune}-${codePostal}-${pathLibelleCommune}/en-triant-par-${codeTriCentre}`);\n }\n\n navigateToHome() {\n page(`${this.basePath}`);\n }\n\n navigateToUrlIfPossible(url: string) {\n if(url) {\n window.open(url, '_blank')\n }\n }\n}\n\nexport const Router = Routing.INSTANCE;\n","import {IDBPDatabase, openDB} from \"idb\";\nimport {Commune, Departement, Lieu, LieuAffichableAvecDistance, sameLieu} from \"../state/State\";\n\n\nexport type Subscription = {\n ts: number;\n departement: Departement;\n commune?: Commune;\n lieu: LieuAffichableAvecDistance;\n notificationUrl : string;\n};\n\nexport class DB {\n\n public static readonly INSTANCE = new DB();\n\n private db: IDBPDatabase|undefined = undefined;\n\n private constructor() {\n }\n\n public async initialize(): Promise {\n this.db = await openDB('vite-ma-dose', 2, {\n upgrade(db, oldVersion, newVersion, transaction) {\n if(oldVersion < 1) {\n db.createObjectStore('subscriptions', { keyPath: 'ts' })\n }\n if(oldVersion < 2) {\n db.createObjectStore('debug', {keyPath: 'name'})\n }\n },\n blocked() {\n console.error(\"openDB blocked\")\n },\n blocking() {\n console.warn(\"Blocking openDB\")\n },\n terminated() {\n console.info(\"Terminated openDB\")\n },\n });\n }\n\n async subscribeToCenterAppointments(subscription: Subscription) {\n if(!this.db) {\n throw new Error(\"DB not initialized !\");\n }\n\n const id = await this.db.transaction([\"subscriptions\"], \"readwrite\").objectStore(\"subscriptions\").add(subscription);\n console.info(`Created subscription with id ${id}`);\n }\n\n async fetchAllSubscriptions(): Promise {\n if(!this.db) {\n throw new Error(\"DB not initialized !\");\n }\n\n return await this.db.transaction([\"subscriptions\"]).objectStore(\"subscriptions\").getAll();\n }\n\n async unsubscribeToCenterAppointments(lieu: Lieu) {\n if(!this.db) {\n throw new Error(\"DB not initialized !\");\n }\n\n const subscriptions = await this.fetchAllSubscriptions();\n const subscriptionToDelete = await subscriptions.find(s => sameLieu(s.lieu, lieu))\n if(subscriptionToDelete) {\n await this.db.transaction([\"subscriptions\"], \"readwrite\").objectStore(\"subscriptions\").delete(subscriptionToDelete.ts);\n }\n }\n\n async switchDebugMode() {\n if(!this.db) {\n throw new Error(\"DB not initialized !\");\n }\n\n const debugs = await this.db.transaction([\"debug\"]).objectStore(\"debug\").getAll()\n const debugStoreExists = (debugs.length!==0);\n\n if(debugStoreExists) {\n await this.db.transaction([\"debug\"], \"readwrite\").objectStore(\"debug\").delete(debugs[0].name);\n alert(\"Switched to debugMode=disabled\")\n } else {\n await this.db.transaction([\"debug\"], \"readwrite\").objectStore(\"debug\").add({name: 'enabled'});\n alert(\"Switched to debugMode=enabled\")\n }\n }\n}\n","import {Subscription} from \"../storage/DB\";\n\nexport class Messaging {\n public static readonly INSTANCE = new Messaging();\n\n private constructor() {\n }\n\n async ensureStarted(): Promise {\n return new Promise(async (resolve) => {\n // const env = State.currentEnv();\n // const fbConfig = await fetch(`${Router.basePath}firebase-config-${env}`).then(resp => resp.json())\n // firebase.initializeApp(fbConfig.app);\n\n resolve();\n })\n }\n\n async subscribeTo(subscriptions: Subscription[]) {\n await navigator.serviceWorker.controller!.postMessage({\n type: 'SUBSCRIPTIONS_ADDED',\n subscriptionTopics: subscriptions.map(s => `department_${s.departement.code_departement}_center_${s.lieu.gid}`)\n });\n }\n\n async unsubscribeFrom(subscriptions: Subscription[]) {\n await navigator.serviceWorker.controller!.postMessage({\n type: 'SUBSCRIPTIONS_REMOVED',\n subscriptionTopics: subscriptions.map(s => `department_${s.departement.code_departement}_center_${s.lieu.gid}`)\n });\n }\n}\n","import {Router} from \"../routing/Router\";\nimport {DB} from \"../storage/DB\";\nimport {Messaging} from \"./Messaging\";\n\nexport class ServiceWorkers {\n\n public static readonly INSTANCE = new ServiceWorkers();\n\n private messageChannel = new MessageChannel();\n\n private constructor() {\n }\n\n async startup() {\n // Registering background synchronization\n if (!navigator.serviceWorker){\n console.info(\"Service Worker not supported\")\n return false;\n }\n\n // Waiting for 'load' event to start service worker registration\n // see https://developers.google.com/web/fundamentals/primers/service-workers/registration#improving_the_boilerplate\n await new Promise((resolve, reject) => window.addEventListener('load', resolve));\n\n const serviceWorkerRegistration = await navigator.serviceWorker.register(`${Router.basePath}sw.js`);\n\n navigator.serviceWorker.addEventListener('controllerchange', () => {\n console.log(\"controllerchange called !\");\n });\n\n // Cases :\n // - navigator.serviceWorker.controller is undefined : this occurs the first time the sw is installed\n // in that case, we should look for updatefound + statechange=activated events to resolve controller\n // - navigator.serviceWorker.controller is defined, we should play with is, but don't forget to register a\n // controller change event in case a new version of the sw is deployed\n\n const swInitializer = await new Promise<{controller: ServiceWorker, updated: boolean}>((resolve, reject) => {\n if(navigator.serviceWorker.controller) {\n resolve({controller: navigator.serviceWorker.controller, updated: false});\n }\n\n serviceWorkerRegistration.addEventListener('updatefound', () => {\n const newWorker = serviceWorkerRegistration.installing!;\n newWorker.addEventListener('statechange', (event) => {\n if(newWorker.state === 'activated') {\n resolve({ controller: navigator.serviceWorker.controller!, updated: true});\n }\n })\n });\n })\n\n swInitializer.controller.postMessage({\n type: 'INIT_PORT'\n }, [this.messageChannel.port2])\n this.messageChannel.port1.onmessage = function (event) {\n console.log(event.data.payload);\n }\n\n // If at least 1 subscription defined, ensuring that firebase messaging is still granted\n const allSubscriptions = await DB.INSTANCE.fetchAllSubscriptions()\n if(allSubscriptions.length) {\n await Promise.all([\n Messaging.INSTANCE.ensureStarted(),\n PushNotifications.INSTANCE.ensureGranted()\n ])\n }\n\n return true;\n }\n}\n\ntype PushNotificationGrantResult = 'granted'|'denied'|'not_available';\nexport class PushNotifications {\n\n public static readonly INSTANCE = new PushNotifications();\n\n private constructor() {\n }\n\n public async ensureGranted(): Promise<{granted:true}|{granted:false,type:'not_granted',status:string}|{granted:false,type:'error',error:any}> {\n return new Promise(async (resolve) => {\n try {\n const result = await PushNotifications.askPermission();\n\n\n if(result === 'granted'){\n resolve({ granted: true });\n } else {\n resolve({ granted: false, type: 'not_granted', status: result });\n }\n } catch(e) {\n resolve({ granted: false, type: 'error', error: e });\n }\n })\n }\n\n currentStatus(): \"missing-capability\"|\"granted\"|\"denied\"|\"available-but-unknown\"|\"unexpected-unknown\" {\n if(!Notification) {\n return \"missing-capability\";\n }\n\n if(Notification.permission === \"granted\") {\n return \"granted\";\n } else if(Notification.permission === \"denied\") {\n return \"denied\";\n } else if(Notification.permission === \"default\") {\n return \"available-but-unknown\";\n }\n\n return \"unexpected-unknown\";\n }\n\n private static async askPermission(): Promise {\n if(!Notification) {\n console.info(\"Notification not supported !\")\n return 'not_available';\n }\n\n const permissionResult = await new Promise((resolve, reject) => {\n const permissionResult = Notification.requestPermission((result) => resolve(result));\n if (permissionResult) {\n permissionResult.then(resolve, reject);\n }\n });\n\n if (permissionResult !== 'granted') {\n console.error(`We weren't granted permission.`)\n return 'denied';\n }\n return 'granted';\n }\n}\n","import {LitElement, html, customElement, property, css, unsafeCSS} from 'lit-element';\nimport {Router, SlottedTemplateResultFactory} from \"./routing/Router\";\nimport globalCss from './styles/global.scss'\nimport {TemplateResult} from \"lit-html\";\nimport {ServiceWorkers} from \"./utils/ServiceWorkers\";\nimport {DB} from \"./storage/DB\";\n\n@customElement('vmd-app')\nexport class VmdAppComponent extends LitElement {\n\n //language=css\n static styles = [\n css`${unsafeCSS(globalCss)}`,\n css`\n .appLogo {}\n .appLogo._phone {\n max-width: 25vw;\n }\n `\n ];\n\n @property({type: Object, attribute: false}) viewTemplateResult: SlottedTemplateResultFactory|undefined = undefined;\n\n constructor() {\n super();\n\n Router.installRoutes((viewTemplateResult, path) => {\n this.viewTemplateResult = viewTemplateResult;\n })\n\n DB.INSTANCE.initialize().then(() => {\n ServiceWorkers.INSTANCE.startup();\n })\n }\n\n render() {\n return html`\n
\n
\n
Router.navigateToHome()}\">\n \"Trouvez\n \"Trouvez\n
\n
\n
\n
\n À propos\n
\n \n
\n
\n
\n
\n \n ${this.viewTemplateResult?this.viewTemplateResult(html`\n \n \n \n `):html``}\n \n \n `;\n }\n\n private debugCounter = 0;\n tryDebug() {\n this.debugCounter++;\n if(this.debugCounter%5 === 0) {\n console.log(\"Debug mode switch detection triggered !\");\n DB.INSTANCE.switchDebugMode();\n }\n }\n\n connectedCallback() {\n super.connectedCallback();\n // console.log(\"connected callback\")\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n // console.log(\"disconnected callback\")\n }\n}\n","import {css, customElement, html, LitElement, property, unsafeCSS} from \"lit-element\";\nimport globalCss from \"../styles/global.scss\";\nimport {CodeTrancheAge, TrancheAge} from \"../state/State\";\n\nexport type TrancheAgeSelectionne = { trancheAge: TrancheAge|undefined };\n\n@customElement('vmd-tranche-age-selector')\nexport class VmdTrancheAgeSelectorComponent extends LitElement {\n\n //language=css\n static styles = [\n css`${unsafeCSS(globalCss)}`,\n css`\n :host {\n display: block;\n }\n `\n ];\n\n @property({type: String}) codeTrancheAgeSelectionne: CodeTrancheAge|\"\" = \"\";\n @property({type: Map, attribute: false}) tranchesAge: Map = new Map();\n\n constructor() {\n super();\n }\n\n render() {\n return html`\n \n `;\n }\n\n trancheAgeSelectionne(event: Event) {\n this.codeTrancheAgeSelectionne = (event.currentTarget as HTMLSelectElement).value as CodeTrancheAge|\"\";\n this.dispatchEvent(new CustomEvent('tranche-age-changed', {\n detail: {\n trancheAge: (this.codeTrancheAgeSelectionne === \"\")?undefined:this.tranchesAge.get(this.codeTrancheAgeSelectionne)\n }\n }));\n }\n\n connectedCallback() {\n super.connectedCallback();\n // console.log(\"connected callback\")\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n // console.log(\"disconnected callback\")\n }\n}\n","import {LitElement, html, customElement, property, css, unsafeCSS} from 'lit-element'\nimport {repeat} from \"lit-html/directives/repeat\";\nimport globalCss from \"../styles/global.scss\";\nimport {CodeDepartement, Departement} from \"../state/State\";\n\nexport type DepartementSelected = { departement: Departement|undefined };\n\n@customElement('vmd-departement-selector')\nexport class VmdDepartementSelectorComponent extends LitElement {\n\n //language=css\n static styles = [\n css`${unsafeCSS(globalCss)}`,\n css`\n :host {\n display: block;\n }\n `\n ];\n\n @property({type: String}) codeDepartementSelectionne: CodeDepartement|undefined = undefined;\n @property({type: Array, attribute: false}) departementsDisponibles: Departement[] = [];\n\n render() {\n return html`\n \n `;\n }\n\n departementSelectionne(event: Event) {\n this.codeDepartementSelectionne = (event.currentTarget as HTMLSelectElement).value;\n this.dispatchEvent(new CustomEvent('departement-changed', {\n detail: {\n departement: this.departementsDisponibles.find(dept => dept.code_departement === this.codeDepartementSelectionne)\n }\n }));\n }\n\n connectedCallback() {\n super.connectedCallback();\n // console.log(\"connected callback\")\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n // console.log(\"disconnected callback\")\n }\n}\n","import {Strings} from \"./Strings\";\n\nexport type ISODateString = string;\n\nconst FR_WEEK_DAYS: Record = {\n 0: 'Dimanche', 1: 'Lundi', 2: 'Mardi', 3: 'Mercredi',\n 4: 'Jeudi', 5: 'Vendredi', 6: 'Samedi'\n};\nconst FR_MONTHES: Record = {\n 0: 'Janvier', 1: 'Février', 2: 'Mars', 3: 'Avril', 4: 'Mai', 5: 'Juin',\n 6: 'Juillet', 7: 'Août', 8: 'Septembre', 9: 'Octobre', 10: 'Novembre', 11: 'Décembre',\n};\n\nexport type Duration = {\n days: number;\n totalHours: number;\n hours: number;\n totalMinutes: number;\n minutes: number;\n totalSeconds: number;\n seconds: number;\n totalMillis: number;\n millis: number;\n};\n\nexport type WeekDay = \"lundi\"|\"mardi\"|\"mercredi\"|\"jeudi\"|\"vendredi\"|\"samedi\"|\"dimanche\";\nexport const WEEK_DAYS_DESCRIPTORS: { [k in WeekDay]: { index: number, shortName: string } } = {\n \"lundi\": { index: 0, shortName: \"Lu\" },\n \"mardi\": { index: 1, shortName: \"Ma\" },\n \"mercredi\": { index: 2, shortName: \"Me\" },\n \"jeudi\": { index: 3, shortName: \"Je\" },\n \"vendredi\": { index: 4, shortName: \"Ve\" },\n \"samedi\": { index: 5, shortName: \"Sa\" },\n \"dimanche\": { index: 6, shortName: \"Di\" },\n};\nexport const WEEK_DAYS: WeekDay[] = Object.entries(WEEK_DAYS_DESCRIPTORS).reduce((weekdays, [weekday, desc]) => {\n weekdays[desc.index] = weekday as WeekDay;\n return weekdays;\n}, Array(7).fill(null) as WeekDay[])\n\n// TODO: Replace this with Luxon or momentjs once the requirements are evolving\n// At the moment, no need to embed a multi Kb lib just for this\nexport class Dates {\n\n public static parseISO(isoDateStr: ISODateString|null|undefined): Date|undefined {\n if(!isoDateStr) {\n return undefined;\n }\n\n const ts = Date.parse(isoDateStr);\n return (isNaN(ts))?undefined:new Date(ts);\n }\n\n public static formatToFRDateTime(date: Date) {\n return `\n ${FR_WEEK_DAYS[date.getDay()]} ${date.getDate()} ${FR_MONTHES[date.getMonth()]}\n à ${Strings.padLeft(date.getHours(), 2, '0')}:${Strings.padLeft(date.getMinutes(), 2, '0')}\n `;\n }\n\n public static isoToFRDatetime(isoDateStr: ISODateString|null|undefined): string|undefined {\n const date = Dates.parseISO(isoDateStr);\n return date?Dates.formatToFRDateTime(date):undefined;\n }\n\n public static formatDurationFromNow(isoDate: ISODateString) {\n const date = this.parseISO(isoDate);\n const durationFromNow = date?Dates.durationFromNow(date):undefined;\n return durationFromNow?Dates.formatDuration(durationFromNow):undefined;\n }\n\n public static durationFromNow(date: Date) {\n return Dates.durationBetween(date, new Date());\n }\n\n public static durationBetween(date1: Date, date2: Date) {\n const totalMillis = Math.abs(date1.getTime() - date2.getTime());\n const millis = totalMillis % 1000;\n const totalSeconds = (totalMillis - millis)/(1000);\n const seconds = ((totalMillis - millis)/1000)%60;\n const totalMinutes = (totalMillis - millis - seconds*1000)/(60*1000)\n const minutes = ((totalMillis - millis - seconds*1000)/(60*1000))%60;\n const totalHours = (totalMillis - millis - seconds*1000 - minutes*60*1000)/(60*60*1000)\n const hours = ((totalMillis - millis - seconds*1000 - minutes*60*1000)/(60*60*1000))%24;\n const days = ((totalMillis - millis - seconds*1000 - minutes*60*1000 - hours*60*60*1000)/(24*60*60*1000));\n return { days, totalHours, hours, totalMinutes, minutes, totalSeconds, seconds, totalMillis, millis };\n }\n\n private static showValue(value: number, unit: string, pluralForm: string = 's', skipPlural: boolean = false) {\n return (value === 0?'':value+unit+(skipPlural?'':Strings.plural(value, pluralForm)));\n }\n\n public static formatDuration(durationFromNow: Duration): string {\n if (durationFromNow.totalMinutes === 0) {\n return 'quelques instants';\n } else if(durationFromNow.totalHours === 0) {\n return `${Dates.showValue(durationFromNow.minutes, ' minute')}`;\n } else if(durationFromNow.totalHours <= 6) {\n return `${Dates.showValue(durationFromNow.hours, ' heure')} ${Dates.showValue(durationFromNow.minutes, ' minute')}`;\n } else if(durationFromNow.days === 0) {\n return `${Dates.showValue(durationFromNow.hours, ' heure')}`;\n } else if(durationFromNow.days < 3) {\n return `${Dates.showValue(durationFromNow.days, ' jour')} ${Dates.showValue(durationFromNow.hours, ' heure')}`;\n } else {\n return `${Dates.showValue(durationFromNow.days, ' jour')}`;\n }\n }\n}\n","import {css, customElement, html, LitElement, property, unsafeCSS} from 'lit-element';\nimport {classMap} from \"lit-html/directives/class-map\";\nimport {\n Lieu,\n LieuAffichableAvecDistance,\n Plateforme,\n PLATEFORMES,\n typeActionPour,\n TYPES_LIEUX\n} from \"../state/State\";\nimport {Router} from \"../routing/Router\";\nimport {Dates} from \"../utils/Dates\";\nimport appointmentCardCss from \"./vmd-appointment-card.component.scss\";\nimport globalCss from \"../styles/global.scss\";\nimport {Strings} from \"../utils/Strings\";\nimport {CapabilityEligibility} from \"../utils/Capabilities\";\nimport {TemplateResult} from \"lit-html\";\n\ntype LieuCliqueContext = {lieu: LieuAffichableAvecDistance};\nexport type LieuCliqueCustomEvent = CustomEvent;\n\nexport type ActionAbonnement = \"unsubscribe\"|\"subscribe\";\nexport type AbonnementCliqueContext = LieuCliqueContext & {action: ActionAbonnement};\nexport type AbonnementCliqueCustomEvent = CustomEvent;\n\n@customElement('vmd-appointment-card')\nexport class VmdAppointmentCardComponent extends LitElement {\n\n //language=css\n static styles = [\n css`${unsafeCSS(globalCss)}`,\n css`${unsafeCSS(appointmentCardCss)}`,\n css`\n `\n ];\n\n @property({type: Object, attribute: false}) lieu!: LieuAffichableAvecDistance;\n @property({type: String, attribute: false}) locationWatchEligibility: CapabilityEligibility = \"not-eligible\";\n @property({type: Boolean, attribute: false}) watching!: boolean;\n\n constructor() {\n super();\n }\n\n prendreRdv() {\n this.dispatchEvent(new CustomEvent('prise-rdv-cliquee', {\n detail: { lieu: this.lieu }\n }));\n }\n\n verifierRdv() {\n this.dispatchEvent(new CustomEvent('verification-rdv-cliquee', {\n detail: { lieu: this.lieu }\n }));\n }\n\n render() {\n const plateforme: Plateforme|undefined = PLATEFORMES[this.lieu.plateforme];\n let distance: string|undefined;\n if (this.lieu.distance && this.lieu.distance >= 10) {\n distance = this.lieu.distance.toFixed(0)\n } else if (this.lieu.distance) {\n distance = this.lieu.distance.toFixed(1)\n }\n\n let cardConfig: {cardLink:(content: TemplateResult) => TemplateResult, estCliquable: boolean, disabledBG: boolean, actions: TemplateResult|undefined, libelleDateAbsente: string };\n let typeLieu = typeActionPour(this.lieu);\n if(typeLieu === 'actif-via-plateforme' || typeLieu === 'inactif-via-plateforme') {\n let specificCardConfig: { disabledBG: boolean, libelleDateAbsente: string, libelleBouton: string, typeBouton: 'btn-info'|'btn-primary', onclick: ()=>void, additionalActions: TemplateResult|undefined };\n if(typeLieu === 'inactif-via-plateforme') {\n specificCardConfig = {\n disabledBG: true,\n libelleDateAbsente: 'Aucun rendez-vous',\n libelleBouton: 'Vérifier le centre de vaccination',\n typeBouton: 'btn-info',\n onclick: () => this.verifierRdv(),\n additionalActions: html`\n \n `\n };\n } else {\n specificCardConfig = {\n disabledBG: false,\n libelleDateAbsente: 'Date inconnue',\n libelleBouton: 'Prendre rendez-vous',\n typeBouton: 'btn-primary',\n onclick: () => this.prendreRdv(),\n additionalActions: undefined\n };\n }\n cardConfig = {\n estCliquable: true,\n disabledBG: specificCardConfig.disabledBG,\n libelleDateAbsente: specificCardConfig.libelleDateAbsente,\n cardLink: (content) =>\n html` { specificCardConfig.onclick(); e.preventDefault(); } }\">${content}`,\n actions: html`\n e.preventDefault()}\" \n class=\"btn btn-lg ${classMap({ 'btn-primary': specificCardConfig.typeBouton==='btn-primary', 'btn-info': specificCardConfig.typeBouton==='btn-info' })}\">\n ${specificCardConfig.libelleBouton}\n \n ${specificCardConfig.additionalActions || html``}\n
\n
\n ${this.lieu.appointment_count.toLocaleString()} créneau${Strings.plural(this.lieu.appointment_count, \"x\")}\n
\n ${this.lieu.plateforme?html`\n |\n
\n ${plateforme?html`\n \n `:html`\n ${this.lieu.plateforme}\n `}\n
\n `:html``}\n
\n `\n };\n } else if(typeLieu === 'actif-via-tel') {\n cardConfig = {\n estCliquable: true,\n disabledBG: false,\n libelleDateAbsente: 'Réservation tél uniquement',\n cardLink: (content) => html`\n \n ${content}\n `,\n actions: html`\n \n Appeler le ${Strings.toNormalizedPhoneNumber(this.lieu.metadata.phone_number)}\n \n `\n };\n } else if(typeLieu === 'inactif') {\n cardConfig = {\n estCliquable: false,\n disabledBG: true,\n libelleDateAbsente: 'Aucun rendez-vous',\n cardLink: (content) => content,\n actions: undefined\n };\n } else {\n throw new Error(`Unsupported typeLieu : ${typeLieu}`)\n }\n\n return cardConfig.cardLink(html`\n
\n
\n
\n
\n
\n ${this.lieu.prochain_rdv?Dates.isoToFRDatetime(this.lieu.prochain_rdv):cardConfig.libelleDateAbsente}\n ${distance ? `- ${distance} km` : ''}\n
\n
\n \n
\n ${this.lieu.nom}\n
\n ${this.lieu.metadata.address}\n
\n
\n \n \n { e.stopImmediatePropagation(); }}\">\n ${Strings.toNormalizedPhoneNumber(this.lieu.metadata.phone_number)}\n \n \n \n \n ${TYPES_LIEUX[this.lieu.type]}\n \n \n ${this.lieu.vaccine_type}\n \n
\n
\n\n ${cardConfig.actions?html`\n
\n ${cardConfig.actions}\n
\n `:html``}\n
\n
\n
\n `);\n }\n\n changeSubscription() {\n this.dispatchEvent(new CustomEvent('abonnement-clique', {\n detail: {\n lieu: this.lieu,\n action: this.watching?'unsubscribe':'subscribe'\n }\n }));\n }\n\n connectedCallback() {\n super.connectedCallback();\n // console.log(\"connected callback\")\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n // console.log(\"disconnected callback\")\n }\n}\n","import {LitElement, html, customElement, property, css, unsafeCSS} from 'lit-element';\nimport {classMap} from \"lit-html/directives/class-map\";\nimport globalCss from \"../styles/global.scss\";\n\nexport type MetadataWidthType = 'full-width'|'fit-to-content'|'3col-equally-distributed'\nconst METADATA_WIDTH_CLASSES: {[type in MetadataWidthType]: string} = {\n 'full-width': '',\n 'fit-to-content': 'col-md-auto',\n '3col-equally-distributed': 'col-md'\n};\n\n\n@customElement('vmd-appointment-metadata')\nexport class VmdAppointmentMetadataComponent extends LitElement {\n\n //language=css\n static styles = [\n css`${unsafeCSS(globalCss)}`,\n css`\n `\n ];\n\n @property({type: Boolean, attribute: false}) displayed: boolean = true;\n @property({type: String}) widthType: MetadataWidthType|undefined = undefined;\n @property({type: String}) icon: string|undefined = undefined;\n @property({type: Boolean, attribute: false}) centerIconVertically: boolean = true;\n\n constructor() {\n super();\n }\n\n render() {\n if(!this.widthType) {\n console.error(\"No widthType defined on vmd-appointment-metadata component !\")\n return html``\n }\n\n return html`\n
\n \n

\n \n

\n
\n `;\n }\n\n connectedCallback() {\n super.connectedCallback();\n\n this.classList.add(\"col-24\");\n if(this.widthType && METADATA_WIDTH_CLASSES[this.widthType]) {\n this.classList.add(METADATA_WIDTH_CLASSES[this.widthType])\n }\n\n if(!this.displayed) {\n this.style.display = 'none';\n }\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n // console.log(\"disconnected callback\")\n }\n}\n","import {\n css,\n customElement,\n html,\n internalProperty,\n LitElement,\n property,\n unsafeCSS\n} from 'lit-element';\nimport {classMap} from \"lit-html/directives/class-map\";\nimport {Commune, Departement} from \"../state/State\";\nimport {repeat} from \"lit-html/directives/repeat\";\nimport communeSelectorCss from \"./vmd-commune-selector.component.scss\";\nimport globalCss from \"../styles/global.scss\";\nimport {Strings} from \"../utils/Strings\";\nimport {TemplateResult} from \"lit-html\";\nimport {DirectiveFn} from \"lit-html/lib/directive\";\n\n\nexport type AutocompleteTriggered = { value: string };\nexport type CommuneSelected = { commune: Commune };\nexport type DepartementSelected = { departement: Departement };\n\n@customElement('vmd-commune-selector')\nexport class VmdCommuneSelectorComponent extends LitElement {\n\n //language=css\n static styles = [\n css`${unsafeCSS(globalCss)}`,\n css`${unsafeCSS(communeSelectorCss)}`,\n css`\n `\n ];\n\n @property({type: String}) codeCommuneSelectionne: string | undefined = undefined;\n\n @internalProperty() inputHasFocus: boolean = false;\n @property({type: Boolean, attribute: false}) inputModeFixedToText = true;\n @property({type: String, attribute: false}) inputMode: 'numeric'|'text' = 'numeric';\n\n @property({type: Array, attribute: false}) autocompleteTriggers: Set|undefined;\n @internalProperty() recuperationCommunesEnCours: boolean = false;\n @property({type: Array, attribute: false}) set communesDisponibles(cd: Commune[]|undefined) {\n if(cd !== this._communesDisponibles) {\n this._communesDisponibles = cd;\n this.filtrerCommunesAffichees();\n this.requestUpdate('communesDisponibles');\n this.requestUpdate('communesAffichees');\n }\n }\n get communesDisponibles(): Commune[]|undefined{ return this._communesDisponibles; }\n private _communesDisponibles: Commune[]|undefined = undefined;\n\n @internalProperty() communesAffichees: Commune[]|undefined = undefined;\n @internalProperty() filter: string = \"\";\n\n private filterMatchingAutocomplete: string|undefined = undefined;\n\n get showDropdown() {\n return this.inputHasFocus\n && this.filter\n // This one is done because otherwise we would start showing some departments matching\n // first digit, and this would encourage search by department (whereas search by commune\n // is by far better)\n && this.filter.length >= 2\n && ((this.inputMode === 'text' && !this.dropDownVide())\n || this.inputMode === 'numeric');\n }\n\n get communeSelectionnee(): Commune | undefined {\n let communesDisponibles = this.communesDisponibles;\n if(this.codeCommuneSelectionne && communesDisponibles) {\n return communesDisponibles.find(c => c.code === this.codeCommuneSelectionne);\n }\n return undefined;\n }\n\n protected aucuneCommuneAffichee(): boolean {\n return !this.communesAffichees || !this.communesAffichees.length;\n }\n\n protected dropDownVide(): boolean {\n return this.aucuneCommuneAffichee();\n }\n\n private filtrerCommunesAffichees() {\n // /!\\ important note : this is important to have the same implementation of toFullTextSearchableString()\n // function here, than the one used in communes-import.js tooling\n const fullTextSearchableQuery = Strings.toFullTextSearchableString(this.filter)\n\n this.communesAffichees = this.communesDisponibles?this.communesDisponibles.filter(commune => {\n const fullTextSearchableNomCommune = Strings.toFullTextSearchableString(commune.nom)\n\n return commune.codePostal.indexOf(fullTextSearchableQuery) === 0\n || fullTextSearchableNomCommune.indexOf(fullTextSearchableQuery) !== -1;\n }).filter((_, index) => index < 50):undefined;\n }\n\n constructor() {\n super();\n }\n\n valueChanged(event: Event) {\n // Retrieving current filter\n this.filter = (event.currentTarget as HTMLInputElement).value;\n\n // If we previously matched an autocomplete filter previously, checking that what we matched\n // is still at the 'start' of current filter\n // This is intended to detected start of filter string modifications which would invalidate\n // the current autocompleteFilter\n if(this.filterMatchingAutocomplete && this.filter.indexOf(this.filterMatchingAutocomplete) !== 0) {\n this.filterMatchingAutocomplete = undefined;\n }\n\n if(this.filter && this.autocompleteTriggers) {\n // Checking every possible substrings of this.filter\n // For exemple, if this.filter = \"abcdef\", we're testing \"a\", then \"ab\", then \"abc\" etc..\n // against this.autocompleteTriggeres, to see if one matches\n // And if one matches, comparing if this is the same than for previous this.filter's value\n // If it didn't changed, then we only have to refresh filtered communes with the new this.filter value\n // If it changed, then we need to raise a new autocomplete-triggered event, so that\n // communesDisponibles is updated with a new autocomplete key\n const filterMatchedAnAutocomplete = this.filter.split('').some((_, filterSizeAttempt) => {\n let filterAttempt = this.filter.substring(0, this.filter.length - filterSizeAttempt);\n const searchableFilterAttempt = Strings.toFullTextSearchableString(filterAttempt);\n if(this.autocompleteTriggers!.has(searchableFilterAttempt)) {\n if(filterAttempt === this.filterMatchingAutocomplete) {\n this.filtrerCommunesAffichees();\n } else {\n this.filterMatchingAutocomplete = filterAttempt;\n this.dispatchEvent(new CustomEvent('autocomplete-triggered', {\n detail: {\n value: searchableFilterAttempt\n }\n }));\n }\n return true;\n }\n return false;\n });\n\n // In the case we didn't changed any autocomplete trigger yet (typically, when we entered a\n // too-short this.filter), then we ensure that communesDisponibles are left empty\n if(!filterMatchedAnAutocomplete) {\n this.communesDisponibles = [];\n }\n }\n }\n\n communeSelected(commune: Commune) {\n this.filter = `${commune.codePostal} - ${commune.nom}`;\n this.communesDisponibles = [];\n\n this.dispatchEvent(new CustomEvent('on-commune-selected', {\n detail: {\n commune\n }\n }));\n }\n\n hideDropdownWhenInputHasNotFocus() {\n // That's a hacky workaround because I don't know how to handle this more cleanly..\n // The problem is linked to .autocomplete's @focusout and .switch-to-text's @click\n // It appears that when we click the .switch-to-text
  • tag, .autocomplete's @focusout\n // event is triggered first (strangely far before than .switch-to-text's @click)\n // If we would directly update this.inputHasFocus, I don't know how, but it looks like\n // rendering would happen before .switch-to-text's @click is triggered, thus removing it from\n // the DOM and totally disabling its event capture (thus, not triggering the click handler at all)\n // By adding the setTimeout with a proper duration (note that 50ms wouldn't be enough.. it would\n // still remove the
  • from the DOM prior to it being clicked), we ensure that the @click\n // will be triggered on .switch-to-text first, _then_ the .autocomplete's @focusout will\n // be trigerred\n setTimeout(() => {\n this.inputHasFocus = (this.shadowRoot!.querySelector(\"input\") === this.shadowRoot!.activeElement);\n }, 300);\n }\n\n render() {\n return html`\n
    \n { this.inputHasFocus = true; }}\"\n @focusout=\"${this.hideDropdownWhenInputHasNotFocus}\"\n @keyup=\"${this.valueChanged}\" .value=\"${this.filter}\"\n inputmode=\"${this.inputMode}\" placeholder=\"${this.inputModeFixedToText?'Commune, Code postal, Département...':this.inputMode==='numeric'?'Saisissez un code postal':'Saisissez un nom de commune'}\" \n />\n ${this.filter?html`\n \n `:html``}\n ${this.inputModeFixedToText?html``:html`\n \n `}\n ${this.recuperationCommunesEnCours?html`\n
    \n
    \n `:html``}\n ${this.showDropdown?html`\n
      \n ${(this.inputMode==='numeric' && this.aucuneCommuneAffichee())?html`\n
    • { this.inputMode='text'; this.shadowRoot!.querySelector(\"input\")!.focus(); }}\">Je ne connais pas le code postal
    • \n `:html``}\n ${this.renderListItems()}\n
    \n `:html``}\n
    \n `;\n }\n\n renderListItems(): TemplateResult|DirectiveFn {\n return repeat(this.communesAffichees || [], (c) => `comm_${c.codePostal}__${c.nom}`, ((commune, index) => {\n return html`
  • this.communeSelected(commune)}\">${commune.codePostal} - ${commune.nom}
  • `\n }));\n }\n\n connectedCallback() {\n super.connectedCallback();\n\n if(this.inputModeFixedToText) {\n this.inputMode = 'text';\n }\n // console.log(\"connected callback\")\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n // console.log(\"disconnected callback\")\n }\n\n fillCommune(commune: Commune | undefined, autoCompleteCodePostal: string) {\n this.filter = `${commune?commune.codePostal:\"???\"} - ${commune?commune.nom:\"???\"}`;\n this.filterMatchingAutocomplete = autoCompleteCodePostal;\n }\n}\n\n\ntype DepartementRecherchable = Departement & {\n fullTextSearchableNom: string;\n fullTextSearchableCodeDepartement: string;\n};\n\n@customElement('vmd-commune-or-departement-selector')\nexport class VmdCommuneOrDepartmentSelectorComponent extends VmdCommuneSelectorComponent {\n @property({type: Array, attribute: false}) set departementsDisponibles(dpts: Departement[]) {\n this.departementsCherchables = dpts.map(d => ({...d,\n fullTextSearchableCodeDepartement: Strings.toFullTextSearchableString(d.code_departement),\n fullTextSearchableNom: Strings.toFullTextSearchableString(d.nom_departement)\n }));\n }\n @internalProperty() departementsCherchables: DepartementRecherchable[] = [];\n\n @property({type: Array, attribute: false}) departementsAffiches: Departement[] = [];\n\n departementSelectionne(dpt: Departement) {\n this.filter = `${dpt.code_departement} - ${dpt.nom_departement}`;\n this.communesDisponibles = [];\n this.departementsAffiches = [];\n\n this.dispatchEvent(new CustomEvent('on-departement-selected', {\n detail: {\n departement: dpt\n }\n }));\n }\n\n valueChanged(event: Event) {\n super.valueChanged(event);\n\n this.filtrerDepartementsAffichees();\n }\n\n protected dropDownVide(): boolean {\n return this.aucuneCommuneAffichee() && !this.departementsAffiches.length;\n }\n\n private filtrerDepartementsAffichees() {\n const fullTextSearchableQuery = Strings.toFullTextSearchableString(this.filter)\n\n this.departementsAffiches = this.departementsCherchables.filter(dpt => {\n return dpt.fullTextSearchableCodeDepartement.indexOf(fullTextSearchableQuery) === 0\n || dpt.fullTextSearchableNom.indexOf(fullTextSearchableQuery) !== -1;\n });\n }\n\n renderListItems(): TemplateResult|DirectiveFn {\n return html`\n ${repeat(this.departementsAffiches || [], (d) => `dept_${d.code_departement}__${d.nom_departement}`, ((dpt, index) => {\n return html`
  • this.departementSelectionne(dpt)}\">${dpt.code_departement} - ${dpt.nom_departement}
  • `\n }))}\n ${super.renderListItems()}\n `;\n }\n\n fillDepartement(departement: Departement | undefined) {\n this.filter = `${departement?departement.code_departement:'???'} - ${departement?departement.nom_departement:'???'}`\n // this.filterMatchingAutocomplete = autoCompleteCodePostal;\n }\n}\n","import {css, customElement, html, LitElement, property, unsafeCSS} from \"lit-element\";\nimport globalCss from \"../styles/global.scss\";\nimport {repeat} from \"lit-html/directives/repeat\";\n\nexport type ValueStrCustomEvent = CustomEvent<{value: T}>;\n\nexport type Option = {\n code: string;\n libelle: string;\n};\n\n@customElement('vmd-selector')\nexport class VmdSelectorComponent extends LitElement {\n\n //language=css\n static styles = [\n css`${unsafeCSS(globalCss)}`,\n css`\n :host {\n display: block;\n }\n `\n ];\n\n @property({type: String}) additionnalDefaultLabel: string|undefined = undefined;\n\n @property({type: String}) codeSelectionne: string|\"\" = \"\";\n @property({type: Array, attribute: false}) options: Option[] = [];\n\n constructor() {\n super();\n }\n\n render() {\n return html`\n \n `;\n }\n\n valeurSelectionnee(event: Event) {\n this.codeSelectionne = (event.currentTarget as HTMLSelectElement).value as string|\"\";\n this.dispatchEvent(new CustomEvent<{value: string|undefined}>('changed'!, {\n detail: {\n value: (this.codeSelectionne === \"\")?undefined:this.options.find(o => o.code === this.codeSelectionne)!.code\n }\n }));\n }\n\n connectedCallback() {\n super.connectedCallback();\n // console.log(\"connected callback\")\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n // console.log(\"disconnected callback\")\n }\n}\n","import {css, customElement, html, LitElement, property, unsafeCSS} from \"lit-element\";\nimport globalCss from \"../styles/global.scss\";\nimport buttonSwitchCss from \"./vmd-button-switch.component.scss\";\nimport {repeat} from \"lit-html/directives/repeat\";\nimport {classMap} from \"lit-html/directives/class-map\";\n\nexport type ValueStrCustomEvent = CustomEvent<{value: T}>;\n\nexport type Option = {\n code: string;\n libelle: string;\n};\n\n@customElement('vmd-button-switch')\nexport class VmdButtonSwitchComponent extends LitElement {\n\n //language=css\n static styles = [\n css`${unsafeCSS(globalCss)}`,\n css`${unsafeCSS(buttonSwitchCss)}`,\n css`\n :host {\n display: block;\n }\n `\n ];\n\n @property({type: String}) codeSelectionne: string|\"\" = \"\";\n @property({type: Array, attribute: false}) options: Option[] = [];\n\n constructor() {\n super();\n }\n\n render() {\n return html`\n
    \n ${repeat(this.options, option => option.code, option => html`\n \n `)}\n
    \n `;\n }\n\n valeurSelectionnee(codeSelectionne: string) {\n this.codeSelectionne = codeSelectionne;\n this.dispatchEvent(new CustomEvent<{value: string|undefined}>('changed'!, {\n detail: {\n value: (this.codeSelectionne === \"\")?undefined:codeSelectionne\n }\n }));\n }\n\n connectedCallback() {\n super.connectedCallback();\n // console.log(\"connected callback\")\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n // console.log(\"disconnected callback\")\n }\n}\n","import {css, customElement, html, LitElement, property, unsafeCSS} from 'lit-element';\nimport {Router} from \"../routing/Router\";\nimport globalCss from \"../styles/global.scss\";\nimport homeViewCss from \"./vmd-home.view.scss\";\nimport {\n Commune,\n Departement,\n libelleUrlPathDeCommune,\n libelleUrlPathDuDepartement,\n PLATEFORMES,\n State,\n StatsLieu,\n} from \"../state/State\";\nimport {\n AutocompleteTriggered,\n CommuneSelected,\n DepartementSelected\n} from \"../components/vmd-commune-selector.component\";\n\n@customElement('vmd-home')\nexport class VmdHomeView extends LitElement {\n\n //language=css\n static styles = [\n css`${unsafeCSS(globalCss)}`,\n css`${unsafeCSS(homeViewCss)}`,\n css`\n :host {\n display: block;\n }\n `\n ];\n\n @property({type: Array, attribute: false}) communesAutocomplete: Set|undefined = undefined;\n @property({type: Array, attribute: false}) recuperationCommunesEnCours: boolean = false;\n @property({type: Array, attribute: false}) communesDisponibles: Commune[]|undefined = undefined;\n @property({type: Array, attribute: false}) statsLieu: StatsLieu|undefined = undefined;\n\n private departementsDisponibles: Departement[]|undefined = [];\n private communeSelectionee: Commune|undefined = undefined;\n private departementSelectione: Departement|undefined = undefined;\n\n rechercherRdv() {\n if(this.departementSelectione) {\n Router.navigateToRendezVousAvecDepartement(this.departementSelectione.code_departement, libelleUrlPathDuDepartement(this.departementSelectione));\n return;\n }\n\n const departement = this.departementsDisponibles?this.departementsDisponibles.find(dpt => dpt.code_departement === this.communeSelectionee!.codeDepartement):undefined;\n if(!departement) {\n console.error(`Can't find departement matching code ${this.communeSelectionee!.codeDepartement}`)\n return;\n }\n\n Router.navigateToRendezVousAvecCommune(\n 'distance',\n departement.code_departement,\n libelleUrlPathDuDepartement(departement),\n this.communeSelectionee!.code, this.communeSelectionee!.codePostal,\n libelleUrlPathDeCommune(this.communeSelectionee!)\n )\n }\n\n async communeAutocompleteTriggered(event: CustomEvent) {\n this.recuperationCommunesEnCours = true;\n this.communesDisponibles = await State.current.communesPourAutocomplete(Router.basePath, event.detail.value);\n this.recuperationCommunesEnCours = false;\n this.requestUpdate('communesDisponibles')\n }\n\n communeSelected(commune: Commune) {\n this.communeSelectionee = commune;\n this.rechercherRdv();\n }\n\n departementSelected(departement: Departement) {\n this.departementSelectione = departement;\n this.rechercherRdv();\n }\n\n render() {\n return html`\n
    \n
    \n \n
    \n\n
    \n
    \n \n
    \n ) => this.communeSelected(event.detail.commune)}\"\n @on-departement-selected=\"${(event: CustomEvent) => this.departementSelected(event.detail.departement)}\"\n .departementsDisponibles=\"${this.departementsDisponibles}\"\n .autocompleteTriggers=\"${this.communesAutocomplete}\"\n .communesDisponibles=\"${this.communesDisponibles}\"\n .recuperationCommunesEnCours=\"${this.recuperationCommunesEnCours}\"\n >\n \n
    \n
    \n
    \n
    \n\n
    \n
    Trouvez vos rendez-vous avec
    \n\n
    \n ${Object.values(PLATEFORMES).filter(p => p.promoted).map(plateforme => {\n return html`\n
    \n \n
    \n `\n })}\n
    \n
    \n\n
    \n\n
    \n
    \n
    \n
    \n
    \n

    VaccinTracker

    \n \n

    \n Combien de personnes ont été vaccinées ? Combien de premières injections ? Quel pourcentage de seconde injection ? Suivez la campagne vaccinale en France sur Vaccintracker.\n

    \n
    \n\n \n
    \n
    \n
    \n
    \n
    \n

    Carte des centres de vaccination contre la Covid-19

    \n \n

    \n Trouvez un centre de vaccination contre la Covid-19 proche de chez vous, consultez les centres pour savoir s’il y a des rendez-vous\n

    \n
    \n\n \n
    \n
    \n
    \n\n
    \n
    \n
    \n
    \n \n
    ${this.statsLieu?this.statsLieu.global.disponibles.toLocaleString():\"\"}
    \n

    Lieux de vaccination ayant des disponibilités

    \n
    \n
    \n \n
    ${this.statsLieu?this.statsLieu.global.total.toLocaleString():\"\"}
    \n

    Lieux de vaccination supportés

    \n
    \n
    \n \n
    ${this.statsLieu?this.statsLieu.global.creneaux.toLocaleString():\"\"}
    \n

    \n Créneaux de vaccination disponibles dans les prochaines semaines\n

    \n Ce nombre ne correspond pas au nombre de doses disponibles\n
    \n
    \n
    \n
    \n
    \n\n \n `;\n }\n\n async connectedCallback() {\n super.connectedCallback();\n\n const [ departementsDisponibles, statsLieu, autocompletes ] = await Promise.all([\n State.current.departementsDisponibles(),\n State.current.statsLieux(),\n State.current.communeAutocompleteTriggers(Router.basePath)\n ])\n this.departementsDisponibles = departementsDisponibles;\n this.statsLieu = statsLieu;\n this.communesAutocomplete = new Set(autocompletes);\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n // console.log(\"disconnected callback\")\n }\n}\n","import { Coordinates } from './state/State'\n\nexport default function distanceEntreDeuxPoints({ latitude: lat1, longitude: lon1 }: Coordinates, { latitude: lat2, longitude: lon2 }: Coordinates) {\n var R = 6371; // Radius of the earth in km\n var dLat = deg2rad(lat2-lat1); // deg2rad below\n var dLon = deg2rad(lon2-lon1);\n var a =\n Math.sin(dLat/2) * Math.sin(dLat/2) +\n Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *\n Math.sin(dLon/2) * Math.sin(dLon/2)\n ;\n var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));\n var kilometers = R * c; // Distance in km\n return kilometers;\n}\n\nfunction deg2rad(deg: number) {\n return deg * (Math.PI/180)\n}\n","import {CodeDepartement} from \"../state/State\";\n\n\nexport const DEPARTEMENTS_LIMITROPHES: Record = {\n \"01\": [\"38\",\"73\",\"74\",\"39\",\"71\",\"69\",],\n \"02\": [\"59\",\"80\",\"60\",\"77\",\"51\",\"08\",],\n \"03\": [\"42\",\"71\",\"58\",\"18\",\"23\",\"63\",],\n \"04\": [\"83\",\"06\",\"05\",\"26\",\"84\",\"13\",],\n \"05\": [\"04\",\"26\",\"38\",\"73\",],\n \"06\": [\"83\",\"04\",],\n \"07\": [\"48\",\"30\",\"84\",\"26\",\"38\",\"69\",\"43\",],\n \"08\": [\"55\",\"51\",\"02\",\"59\",],\n \"09\": [\"31\",\"11\",\"66\",],\n \"10\": [\"89\",\"21\",\"52\",\"51\",\"77\",],\n \"11\": [\"09\",\"31\",\"81\",\"34\",],\n \"12\": [\"34\",\"30\",\"48\",\"15\",\"46\",\"82\",\"81\",],\n \"13\": [\"30\",\"84\",\"83\",],\n \"14\": [\"27\",\"61\",\"50\",],\n \"15\": [\"48\",\"43\",\"63\",\"19\",\"46\",\"12\",],\n \"16\": [\"17\",\"79\",\"86\",\"87\",\"24\",],\n \"17\": [\"85\",\"79\",\"16\",\"33\",],\n \"18\": [\"36\",\"41\",\"45\",\"89\",\"58\",\"03\",\"23\",],\n \"19\": [\"23\",\"87\",\"24\",\"46\",\"15\",\"63\",],\n \"2A\": [\"2B\",],\n \"2B\": [\"2A\",],\n \"21\": [\"10\",\"89\",\"58\",\"71\",\"39\",\"70\",\"52\",],\n \"22\": [\"29\",\"56\",\"35\",],\n \"23\": [\"87\",\"19\",\"63\",\"03\",\"18\",\"36\",],\n \"24\": [\"17\",\"16\",\"87\",\"19\",\"46\",\"47\",\"33\",],\n \"25\": [\"39\",\"70\",\"90\",],\n \"26\": [\"84\",\"04\",\"05\",\"38\",\"69\",\"07\",],\n \"27\": [\"76\",\"60\",\"95\",\"78\",\"28\",\"61\",\"14\",],\n \"28\": [\"27\",\"78\",\"91\",\"45\",\"41\",\"72\",\"61\",],\n \"29\": [\"22\",\"56\",],\n \"30\": [\"34\",\"12\",\"48\",\"07\",\"26\",\"84\",\"13\",],\n \"31\": [\"65\",\"32\",\"82\",\"81\",\"11\",\"09\",],\n \"32\": [\"31\",\"65\",\"64\",\"40\",\"47\",\"82\",],\n \"33\": [\"17\",\"24\",\"47\",\"40\",],\n \"34\": [\"11\",\"81\",\"12\",\"30\",],\n \"35\": [\"50\",\"53\",\"49\",\"44\",\"56\",\"22\",],\n \"36\": [\"37\",\"41\",\"18\",\"23\",\"87\",\"86\",],\n \"37\": [\"41\",\"36\",\"86\",\"49\",\"72\",],\n \"38\": [\"05\",\"73\",\"01\",\"69\",\"07\",\"26\",\"05\",],\n \"39\": [\"01\",\"71\",\"21\",\"70\",\"25\",],\n \"40\": [\"33\",\"47\",\"32\",\"64\",],\n \"41\": [\"72\",\"37\",\"36\",\"18\",\"45\",\"28\",],\n \"42\": [\"43\",\"69\",\"71\",\"03\",\"63\",],\n \"43\": [\"48\",\"07\",\"69\",\"42\",\"63\",\"15\",],\n \"44\": [\"56\",\"35\",\"53\",\"49\",\"85\",],\n \"45\": [\"91\",\"77\",\"28\",\"41\",\"18\",\"58\",\"89\",],\n \"46\": [\"15\",\"19\",\"24\",\"47\",\"82\",\"12\",],\n \"47\": [\"33\",\"40\",\"32\",\"82\",\"46\",\"24\",],\n \"48\": [\"12\",\"30\",\"07\",\"43\",\"15\",],\n \"49\": [\"44\",\"53\",\"72\",\"37\",\"86\",\"79\",\"85\",],\n \"50\": [\"14\",\"61\",\"53\",\"35\",],\n \"51\": [\"02\",\"77\",\"10\",\"52\",\"55\",\"08\",],\n \"52\": [\"21\",\"70\",\"88\",\"55\",\"51\",\"10\",],\n \"53\": [\"49\",\"72\",\"61\",\"50\",\"35\",\"44\",],\n \"54\": [\"57\",\"67\",\"88\",\"55\",],\n \"55\": [\"54\",\"88\",\"52\",\"51\",\"08\",],\n \"56\": [\"29\",\"22\",\"35\",\"44\",],\n \"57\": [\"67\",\"88\",\"54\",],\n \"58\": [\"03\",\"71\",\"21\",\"89\",\"45\",\"18\",],\n \"59\": [\"02\",\"80\",\"62\",\"08\",],\n \"60\": [\"02\",\"80\",\"76\",\"27\",\"95\",\"77\",],\n \"61\": [\"14\",\"27\",\"28\",\"72\",\"53\",\"50\",],\n \"62\": [\"80\",\"59\",\"02\",],\n \"63\": [\"15\",\"43\",\"42\",\"03\",\"23\",\"19\",],\n \"64\": [\"40\",\"32\",\"65\",],\n \"65\": [\"64\",\"32\",\"31\",],\n \"66\": [\"09\",\"11\",],\n \"67\": [\"68\",\"88\",\"54\",\"57\",],\n \"68\": [\"90\",\"70\",\"88\",\"67\",],\n \"69\": [\"01\",\"71\",\"42\",\"43\",\"07\",\"26\",\"38\",],\n \"70\": [\"21\",\"39\",\"25\",\"90\",\"88\",\"52\",],\n \"71\": [\"03\",\"42\",\"69\",\"01\",\"39\",\"21\",\"58\",],\n \"72\": [\"28\",\"61\",\"53\",\"49\",\"37\",\"41\",],\n \"73\": [\"74\",\"01\",\"38\",\"05\",],\n \"74\": [\"73\",\"01\",],\n \"75\": [\"92\",\"93\",\"94\",],\n \"76\": [\"80\",\"60\",\"27\",],\n \"77\": [\"89\",\"10\",\"51\",\"02\",\"60\",\"93\",\"91\",\"45\",],\n \"78\": [\"95\",\"27\",\"28\",\"91\",\"92\",],\n \"79\": [\"17\",\"85\",\"49\",\"86\",\"16\",],\n \"80\": [\"62\",\"59\",\"02\",\"60\",\"76\",],\n \"81\": [\"11\",\"34\",\"12\",\"82\",\"31\",],\n \"82\": [\"32\",\"31\",\"81\",\"12\",\"46\",\"47\",],\n \"83\": [\"13\",\"84\",\"04\",\"06\",],\n \"84\": [\"13\",\"04\",\"26\",\"07\",\"30\",],\n \"85\": [\"44\",\"49\",\"79\",\"17\",],\n \"86\": [\"36\",\"37\",\"49\",\"79\",\"16\",\"87\",],\n \"87\": [\"23\",\"19\",\"24\",\"16\",\"86\",],\n \"88\": [\"70\",\"90\",\"68\",\"67\",\"57\",\"54\",\"55\",\"52\",],\n \"89\": [\"58\",\"21\",\"10\",\"77\",\"45\",],\n \"90\": [\"25\",\"70\",\"88\",\"68\",],\n \"91\": [\"45\",\"28\",\"77\",\"78\",\"92\",\"94\",],\n \"92\": [\"75\",\"95\",\"78\",\"93\",],\n \"93\": [\"92\",\"95\",\"94\",\"77\",],\n \"94\": [\"77\",\"75\",\"92\",\"93\",\"91\",],\n \"95\": [\"78\",\"27\",\"60\",\"93\",\"92\",],\n \"971\": [],\n \"972\": [],\n \"973\": [],\n \"974\": [],\n \"976\": [],\n};\n","import {PushNotifications} from \"./ServiceWorkers\";\n\nexport type CapabilityEligibility = \"not-eligible\"|\"eligible-but-denied\"|\"eligible\";\n\nexport class Capabilities {\n public static readonly INSTANCE = new Capabilities();\n\n private constructor() {\n }\n\n currentDeviceIsEligibleToLocationWatch(): CapabilityEligibility {\n let pushNotificationStatus = PushNotifications.INSTANCE.currentStatus();\n if(!navigator.serviceWorker\n || pushNotificationStatus === 'missing-capability'\n || pushNotificationStatus === 'unexpected-unknown'\n ) {\n return \"not-eligible\";\n }\n\n if(pushNotificationStatus === 'denied') {\n return \"eligible-but-denied\";\n }\n\n if(pushNotificationStatus === 'granted' || pushNotificationStatus === 'available-but-unknown') {\n return 'eligible';\n }\n\n throw new Error(\"Unexpected case in currentDeviceIsEligibleToLocationWatch()\");\n }\n}\n","\n\n\nexport class ArrayBuilder {\n constructor(private array: T[]) {\n }\n\n concat(array: T[]) {\n this.array = this.array.concat(array);\n return this;\n }\n\n map(mapper: (start: T, index?: number, array?: T[]) => R) {\n return new ArrayBuilder(this.array.map(mapper));\n }\n\n filter(predicate: (v: T, index: number) => boolean) {\n this.array = this.array.filter(predicate);\n return this;\n }\n\n sort(comparator: (v1: T, v2: T) => number) {\n this.array.sort(comparator);\n return this;\n }\n\n sortBy(sortableDataExtractor: (v: T) => string) {\n return this.sort((v1: T, v2: T) => sortableDataExtractor(v1).localeCompare(sortableDataExtractor(v2)));\n }\n\n build() {\n return this.array;\n }\n\n public static from(array: T[]) {\n return new ArrayBuilder(array);\n }\n}\n","import {css, customElement, html, LitElement, property, unsafeCSS} from 'lit-element';\nimport {repeat} from \"lit-html/directives/repeat\";\nimport {styleMap} from \"lit-html/directives/style-map\";\nimport globalCss from \"../styles/global.scss\";\nimport {Router} from \"../routing/Router\";\nimport rdvViewCss from \"./vmd-rdv.view.scss\";\nimport distanceEntreDeuxPoints from \"../distance\"\nimport {\n CodeDepartement,\n CodeTriCentre,\n Commune,\n Departement,\n libelleUrlPathDeCommune,\n libelleUrlPathDuDepartement,\n Lieu,\n LieuAffichableAvecDistance, LieuxAvecDistanceParDepartement,\n LieuxParDepartement, sameLieu,\n State,\n TRIS_CENTRE\n} from \"../state/State\";\nimport {Dates} from \"../utils/Dates\";\nimport {Strings} from \"../utils/Strings\";\nimport {\n AutocompleteTriggered,\n CommuneSelected,\n DepartementSelected,\n VmdCommuneOrDepartmentSelectorComponent,\n VmdCommuneSelectorComponent\n} from \"../components/vmd-commune-selector.component\";\nimport {DEPARTEMENTS_LIMITROPHES} from \"../utils/Departements\";\nimport {ValueStrCustomEvent} from \"../components/vmd-selector.component\";\nimport {TemplateResult} from \"lit-html\";\nimport {Analytics} from \"../utils/Analytics\";\nimport {\n AbonnementCliqueCustomEvent, ActionAbonnement,\n LieuCliqueCustomEvent\n} from \"../components/vmd-appointment-card.component\";\nimport {DB, Subscription} from \"../storage/DB\";\nimport {Capabilities, CapabilityEligibility} from \"../utils/Capabilities\";\nimport {setDebouncedInterval} from \"../utils/Schedulers\";\nimport {ArrayBuilder} from \"../utils/Arrays\";\nimport {Messaging} from \"../utils/Messaging\";\nimport {PushNotifications} from \"../utils/ServiceWorkers\";\n\nconst MAX_DISTANCE_CENTRE_IN_KM = 100;\n\nexport abstract class AbstractVmdRdvView extends LitElement {\n\n //language=css\n static styles = [\n css`${unsafeCSS(globalCss)}`,\n css`${unsafeCSS(rdvViewCss)}`,\n css`\n `\n ];\n\n @property({type: String}) codeDepartementSelectionne: CodeDepartement | undefined = undefined;\n\n @property({type: Array, attribute: false}) communesAutocomplete: Set|undefined = undefined;\n @property({type: Array, attribute: false}) recuperationCommunesEnCours: boolean = false;\n\n @property({type: Array, attribute: false}) communesDisponibles: Commune[]|undefined = undefined;\n @property({type: Array, attribute: false}) departementsDisponibles: Departement[] = [];\n\n @property({type: Array, attribute: false}) lieuxParDepartementAffiches: LieuxAvecDistanceParDepartement | undefined = undefined;\n @property({type: Boolean, attribute: false}) searchInProgress: boolean = false;\n @property({type: Boolean, attribute: false}) miseAJourDisponible: boolean = false;\n\n @property({type: Array, attribute: false}) abonnements: Subscription[] = [];\n @property({type: String, attribute: false}) locationWatchEligibility: CapabilityEligibility = \"not-eligible\";\n protected refreshAbonnementsIntervalId: number|undefined = undefined;\n\n protected derniereCommuneSelectionnee: Commune|undefined = undefined;\n protected lieuBackgroundRefreshIntervalId: number|undefined = undefined;\n\n\n get communeSelectionnee(): Commune|undefined {\n if(this.derniereCommuneSelectionnee) {\n return this.derniereCommuneSelectionnee;\n }\n\n // Calling a non-getter as getter overriden methods don't seem to be able to call\n // super.departementSelectionne\n return this.getCommuneSelectionnee();\n }\n\n get departementSelectionne(): Departement|undefined {\n // Calling a non-getter as getter overriden methods don't seem to be able to call\n // super.departementSelectionne\n return this.getDepartementSelectionne();\n }\n\n resetCommuneSelectionneeTo(commune: Commune|undefined) {\n this.derniereCommuneSelectionnee = commune;\n }\n\n protected getDepartementSelectionne(): Departement|undefined {\n if(this.codeDepartementSelectionne && this.departementsDisponibles) {\n return this.departementsDisponibles.find(d => this.codeDepartementSelectionne === d.code_departement);\n }\n\n return undefined;\n }\n\n protected getCodeCommuneSelectionne(): string|undefined {\n if(!this.communeSelectionnee) {\n return undefined;\n }\n return this.communeSelectionnee.code;\n }\n\n protected getCommuneSelectionnee(): Commune|undefined {\n return undefined;\n }\n\n get totalCreneaux() {\n if (!this.lieuxParDepartementAffiches) {\n return 0;\n }\n return this.lieuxParDepartementAffiches\n .lieuxAffichables\n .reduce((total, lieu) => total+lieu.appointment_count, 0);\n }\n\n async communeAutocompleteTriggered(autocomplete: string) {\n this.recuperationCommunesEnCours = true;\n this.communesDisponibles = await State.current.communesPourAutocomplete(Router.basePath, autocomplete);\n this.recuperationCommunesEnCours = false;\n this.requestUpdate('communesDisponibles')\n }\n\n async communeSelected(commune: Commune, triggerNavigation: boolean): Promise {\n if(!this.communeSelectionnee) {\n this.derniereCommuneSelectionnee = commune;\n\n const departement = this.departementsDisponibles.find(d => d.code_departement === commune.codeDepartement);\n Router.navigateToRendezVousAvecCommune('distance',\n commune.codeDepartement,\n libelleUrlPathDuDepartement(departement!),\n commune.code,\n commune.codePostal,\n libelleUrlPathDeCommune(commune)\n );\n return;\n }\n\n if(this.communeSelectionnee.code !== commune.code || this.codeDepartementSelectionne !== commune.codeDepartement) {\n this.codeDepartementSelectionne = commune.codeDepartement;\n this.resetCommuneSelectionneeTo(commune);\n\n if(triggerNavigation) {\n this.refreshPageWhenValidParams();\n }\n }\n\n return Promise.resolve();\n }\n\n async departementSelected(departement: Departement, triggerNavigation: boolean): Promise {\n if(this.communeSelectionnee) {\n Router.navigateToRendezVousAvecDepartement(departement.code_departement, libelleUrlPathDuDepartement(departement));\n return;\n }\n\n if(departement.code_departement !== this.codeDepartementSelectionne) {\n this.codeDepartementSelectionne = departement.code_departement;\n\n if(triggerNavigation) {\n this.refreshPageWhenValidParams();\n }\n }\n\n return Promise.resolve();\n }\n\n render() {\n const lieuxDisponibles = (this.lieuxParDepartementAffiches && this.lieuxParDepartementAffiches.lieuxAffichables)?\n this.lieuxParDepartementAffiches.lieuxAffichables.filter(l => l.disponible)\n :[];\n\n return html`\n
    \n
    \n \n
    \n ) => this.communeAutocompleteTriggered(event.detail.value)}\"\n @on-commune-selected=\"${(event: CustomEvent) => this.communeSelected(event.detail.commune, true)}\"\n @on-departement-selected=\"${(event: CustomEvent) => this.departementSelected(event.detail.departement, true)}\"\n codeCommuneSelectionne=\"${this.getCodeCommuneSelectionne()}\"\n .departementsDisponibles=\"${this.departementsDisponibles}\"\n .autocompleteTriggers=\"${this.communesAutocomplete}\"\n .communesDisponibles=\"${this.communesDisponibles}\"\n .recuperationCommunesEnCours=\"${this.recuperationCommunesEnCours}\"\n >\n \n
    \n
    \n ${this.renderAdditionnalSearchCriteria()}\n
    \n\n
    \n\n ${this.searchInProgress?html`\n
    \n
    \n
    \n
    \n `:html`\n

    \n ${this.totalCreneaux.toLocaleString()} créneau${Strings.plural(this.totalCreneaux, \"x\")} de vaccination trouvé${Strings.plural(this.totalCreneaux)}\n ${this.libelleLieuSelectionne()}\n
    \n ${(this.lieuxParDepartementAffiches && this.lieuxParDepartementAffiches.derniereMiseAJour) ?\n html`\n \n Dernière mise à jour : il y a\n ${Dates.formatDurationFromNow(this.lieuxParDepartementAffiches!.derniereMiseAJour)}\n ${this.miseAJourDisponible?html`\n \n `:html``}\n `\n : html``}\n

    \n\n
    \n
    \n ${lieuxDisponibles.length ? html`\n

    \n \n \n ${lieuxDisponibles.length} Lieu${Strings.plural(lieuxDisponibles.length, 'x')} de vaccination avec des disponibilités\n \n

    \n ` : html`\n

    \n \n \n Aucun créneau de vaccination trouvé\n \n

    \n
    \n Nous n’avons pas trouvé de rendez-vous de vaccination Covid-19 \n sur les plateformes de réservation. Nous vous recommandons toutefois de vérifier manuellement \n les rendez-vous de vaccination auprès des sites qui gèrent la réservation de créneau de vaccination. \n Pour ce faire, cliquez sur le bouton “vérifier le centre de vaccination”.\n
    \n `}\n \n ${repeat(this.lieuxParDepartementAffiches?this.lieuxParDepartementAffiches.lieuxAffichables:[], (c => `${c.departement}||${c.nom}||${c.plateforme}}`), (lieu, index) => {\n return html` this.prendreRdv(event.detail.lieu)}\"\n @verification-rdv-cliquee=\"${(event: LieuCliqueCustomEvent) => this.verifierRdv(event.detail.lieu)}\"\n @abonnement-clique=\"${(event: AbonnementCliqueCustomEvent) => this.changerAbonnementAuLieu(event.detail.lieu, event.detail.action) }\"\n >`;\n })}\n
    \n `}\n `;\n }\n\n async changerAbonnementAuLieu(lieu: LieuAffichableAvecDistance, action: ActionAbonnement) {\n const outcome = await PushNotifications.INSTANCE.ensureGranted();\n if(outcome.granted) {\n const subscription = {\n ts: Date.now(),\n departement: this.departementSelectionne!,\n commune: this.communeSelectionnee,\n lieu: lieu,\n notificationUrl: window.location.href\n };\n\n if(action === 'subscribe') {\n await DB.INSTANCE.subscribeToCenterAppointments(subscription);\n await Messaging.INSTANCE.subscribeTo([ subscription ])\n await this.refreshAbonnements();\n } else if(action === 'unsubscribe') {\n await DB.INSTANCE.unsubscribeToCenterAppointments(lieu);\n await Messaging.INSTANCE.unsubscribeFrom([ subscription ])\n await this.refreshAbonnements();\n }\n }\n }\n\n onCommuneAutocompleteLoaded(autocompletes: Set): Promise {\n return Promise.resolve();\n }\n\n async onceStartupPromiseResolved() {\n // to be overriden\n }\n\n async connectedCallback() {\n super.connectedCallback();\n\n await Promise.all([\n State.current.departementsDisponibles(),\n State.current.communeAutocompleteTriggers(Router.basePath)\n ]).then(async ([departementsDisponibles, autocompletes]: [Departement[], string[]]) => {\n this.departementsDisponibles = departementsDisponibles;\n\n this.communesAutocomplete = new Set(autocompletes);\n await this.onCommuneAutocompleteLoaded(this.communesAutocomplete);\n });\n\n await this.onceStartupPromiseResolved();\n\n await this.refreshAbonnements();\n this.locationWatchEligibility = Capabilities.INSTANCE.currentDeviceIsEligibleToLocationWatch();\n this.refreshAbonnementsIntervalId = setInterval(async() => {\n this.locationWatchEligibility = Capabilities.INSTANCE.currentDeviceIsEligibleToLocationWatch();\n await this.refreshAbonnements();\n }, 60000);\n\n await this.refreshLieux();\n\n this.lieuBackgroundRefreshIntervalId = setDebouncedInterval(async () => {\n if(this.codeDepartementSelectionne) {\n const derniereMiseAJour = this.lieuxParDepartementAffiches?this.lieuxParDepartementAffiches.derniereMiseAJour:undefined;\n const lieuxAJourPourDepartement = await State.current.lieuxPour(this.codeDepartementSelectionne, true)\n this.miseAJourDisponible = (derniereMiseAJour !== lieuxAJourPourDepartement.derniereMiseAJour);\n\n // Used only to refresh derniereMiseAJour's displayed relative time\n await this.requestUpdate();\n }\n }, 45000);\n }\n\n async refreshAbonnements() {\n this.abonnements = await DB.INSTANCE.fetchAllSubscriptions();\n }\n\n abonnementSur(lieu: Lieu) {\n return !!this.abonnements.find(a => sameLieu(a.lieu, lieu));\n }\n\n preventRafraichissementLieux(): boolean {\n // overridable\n return false;\n }\n\n codeDepartementAdditionnels(codeDepartementSelectionne: CodeDepartement): CodeDepartement[] {\n // overridable\n return [];\n }\n\n async refreshLieux() {\n if(this.codeDepartementSelectionne && !this.preventRafraichissementLieux()) {\n try {\n this.searchInProgress = true;\n const [lieuxDepartement, ...lieuxDepartementsLimitrophes] = await Promise.all([\n State.current.lieuxPour(this.codeDepartementSelectionne),\n ...this.codeDepartementAdditionnels(this.codeDepartementSelectionne).map(dept => State.current.lieuxPour(dept))\n ]);\n\n const lieuxParDepartement = [lieuxDepartement].concat(lieuxDepartementsLimitrophes).reduce((mergedLieuxParDepartement, lieuxParDepartement) => ({\n codeDepartements: mergedLieuxParDepartement.codeDepartements.concat(lieuxParDepartement.codeDepartements),\n derniereMiseAJour: mergedLieuxParDepartement.derniereMiseAJour,\n lieuxDisponibles: mergedLieuxParDepartement.lieuxDisponibles.concat(lieuxParDepartement.lieuxDisponibles),\n lieuxIndisponibles: mergedLieuxParDepartement.lieuxIndisponibles.concat(lieuxParDepartement.lieuxIndisponibles),\n }), {\n codeDepartements: [],\n derniereMiseAJour: lieuxDepartement.derniereMiseAJour,\n lieuxDisponibles: [],\n lieuxIndisponibles: []\n } as LieuxParDepartement);\n\n this.lieuxParDepartementAffiches = this.afficherLieuxParDepartement(lieuxParDepartement);\n\n Analytics.INSTANCE.rechercheLieuEffectuee(\n this.codeDepartementSelectionne,\n this.communeSelectionnee,\n this.lieuxParDepartementAffiches);\n } finally {\n this.searchInProgress = false;\n }\n } else {\n this.lieuxParDepartementAffiches = undefined;\n }\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n\n clearInterval(this.refreshAbonnementsIntervalId);\n\n if(this.lieuBackgroundRefreshIntervalId) {\n clearInterval(this.lieuBackgroundRefreshIntervalId);\n this.lieuBackgroundRefreshIntervalId = undefined;\n }\n }\n\n _onRefreshPageWhenValidParams(): \"return\"|\"continue\" {\n // To be overriden\n\n return \"continue\";\n }\n\n protected refreshPageWhenValidParams() {\n this.refreshLieux();\n\n if(this._onRefreshPageWhenValidParams() === 'return') {\n return;\n }\n\n if (this.codeDepartementSelectionne) {\n Router.navigateToRendezVousAvecDepartement(this.codeDepartementSelectionne, libelleUrlPathDuDepartement(this.departementSelectionne!));\n }\n }\n\n private prendreRdv(lieu: Lieu) {\n if(lieu.url) {\n Analytics.INSTANCE.clickSurRdv(lieu);\n }\n Router.navigateToUrlIfPossible(lieu.url);\n }\n\n private verifierRdv(lieu: Lieu) {\n if(lieu.url) {\n Analytics.INSTANCE.clickSurVerifRdv(lieu);\n }\n Router.navigateToUrlIfPossible(lieu.url);\n }\n\n renderAdditionnalSearchCriteria(): TemplateResult {\n return html``;\n }\n\n protected extraireFormuleDeTri(lieu: LieuAffichableAvecDistance, tri: CodeTriCentre) {\n if(tri === 'date') {\n let firstLevelSort;\n if(lieu.appointment_by_phone_only && lieu.metadata.phone_number) {\n firstLevelSort = 2;\n } else if(lieu.url) {\n firstLevelSort = lieu.appointment_count !== 0 ? (lieu.prochain_rdv!==null? 0:1):3;\n } else {\n firstLevelSort = 4;\n }\n return `${firstLevelSort}__${Strings.padLeft(Date.parse(lieu.prochain_rdv!) || 0, 15, '0')}`;\n } else if(tri === 'distance') {\n let firstLevelSort;\n\n // Considering only 2 kind of sorting sections :\n // - the one with (potentially) available appointments (with url, or appointment by phone only)\n // - the one with unavailable appointments (without url, or with 0 available appointments)\n if(lieu.appointment_by_phone_only && lieu.metadata.phone_number) {\n firstLevelSort = 0;\n } else if(lieu.url) {\n firstLevelSort = lieu.appointment_count !== 0 ? 0:1;\n } else {\n firstLevelSort = 1;\n }\n\n return `${firstLevelSort}__${Strings.padLeft(Math.round(lieu.distance!*1000), 8, '0')}`;\n } else {\n throw new Error(`Unsupported tri : ${tri}`);\n }\n }\n\n abstract libelleLieuSelectionne(): TemplateResult;\n abstract afficherLieuxParDepartement(lieuxParDepartement: LieuxParDepartement): LieuxAvecDistanceParDepartement;\n}\n\n@customElement('vmd-rdv-par-commune')\nexport class VmdRdvParCommuneView extends AbstractVmdRdvView {\n @property({type: String}) codeCommuneSelectionne: string | undefined = undefined;\n @property({type: String}) codePostalSelectionne: string | undefined = undefined;\n\n @property({type: String}) critèreDeTri: 'date' | 'distance' = 'distance'\n\n preventRafraichissementLieux() {\n return !this.communeSelectionnee;\n }\n\n codeDepartementAdditionnels(codeDepartementSelectionne: CodeDepartement) {\n return DEPARTEMENTS_LIMITROPHES[codeDepartementSelectionne];\n }\n\n protected getDepartementSelectionne(): Departement|undefined {\n let communeSelectionnee = this.communeSelectionnee;\n if(communeSelectionnee && this.departementsDisponibles) {\n return this.departementsDisponibles.find(d => communeSelectionnee!.codeDepartement === d.code_departement);\n }\n\n return super.getDepartementSelectionne();\n }\n\n _onRefreshPageWhenValidParams() {\n // To be overriden\n if(this.departementSelectionne && this.communeSelectionnee && this.codePostalSelectionne) {\n Router.navigateToRendezVousAvecCommune(this.critèreDeTri, this.departementSelectionne.code_departement, libelleUrlPathDuDepartement(this.departementSelectionne), this.communeSelectionnee.code, this.communeSelectionnee.codePostal, libelleUrlPathDeCommune(this.communeSelectionnee));\n return 'return';\n }\n\n return 'continue';\n }\n\n\n libelleLieuSelectionne(): TemplateResult {\n return html`\n autour de\n ${this.communeSelectionnee?`${this.communeSelectionnee.nom} (${this.communeSelectionnee.codePostal})`:\"???\"}\n \n `\n }\n\n async onCommuneAutocompleteLoaded(autocompletes: Set): Promise {\n if(this.codePostalSelectionne && this.codeCommuneSelectionne) {\n let codePostalSelectionne = this.codePostalSelectionne;\n await this.refreshBasedOnCodePostalSelectionne(autocompletes, codePostalSelectionne);\n }\n }\n\n private async refreshBasedOnCodePostalSelectionne(autocompletes: Set, codePostalSelectionne: string) {\n const autoCompleteCodePostal = this.getAutoCompleteCodePostal(autocompletes, codePostalSelectionne);\n if (!autoCompleteCodePostal) {\n console.error(`Can't find autocomplete matching codepostal ${codePostalSelectionne}`);\n return autocompletes;\n }\n\n await this.updateCommunesDisponiblesBasedOnAutocomplete(autoCompleteCodePostal);\n\n const communeSelectionnee = this.getCommuneSelectionnee();\n if (communeSelectionnee) {\n this.fillCommuneInSelector(communeSelectionnee, autoCompleteCodePostal);\n await this.communeSelected(communeSelectionnee, false);\n }\n\n return autocompletes;\n }\n\n private getAutoCompleteCodePostal(autocompletes: Set, codePostalSelectionne: string) {\n return codePostalSelectionne.split('')\n .map((_, index) => codePostalSelectionne!.substring(0, index + 1))\n .find(autoCompleteAttempt => autocompletes.has(autoCompleteAttempt));\n }\n\n private async updateCommunesDisponiblesBasedOnAutocomplete(autoCompleteCodePostal: string) {\n this.recuperationCommunesEnCours = true;\n this.communesDisponibles = await State.current.communesPourAutocomplete(Router.basePath, autoCompleteCodePostal)\n this.recuperationCommunesEnCours = false;\n }\n\n private fillCommuneInSelector(communeSelectionnee: Commune, autoCompleteCodePostal: string) {\n const component = (this.shadowRoot!.querySelector(\"vmd-commune-or-departement-selector\") as VmdCommuneSelectorComponent)\n component.fillCommune(communeSelectionnee, autoCompleteCodePostal);\n }\n\n protected getCommuneSelectionnee(): Commune|undefined {\n if(!this.codeCommuneSelectionne || !this.communesDisponibles) {\n return undefined;\n }\n return this.communesDisponibles.find(c => c.code === this.codeCommuneSelectionne && c.codePostal === this.codePostalSelectionne);\n }\n\n resetCommuneSelectionneeTo(commune: Commune|undefined) {\n super.resetCommuneSelectionneeTo(commune);\n this.codeCommuneSelectionne = commune?commune.code:undefined;\n this.codePostalSelectionne = commune?commune.codePostal:undefined;\n }\n\n afficherLieuxParDepartement(lieuxParDepartement: LieuxParDepartement): LieuxAvecDistanceParDepartement {\n const origin = (this.communeSelectionnee!.latitude && this.communeSelectionnee!.longitude)?\n {longitude:this.communeSelectionnee!.longitude, latitude: this.communeSelectionnee!.latitude}:undefined;\n const distanceAvec = origin?\n (lieu: Lieu) => (lieu.location ? distanceEntreDeuxPoints(origin, lieu.location) : Infinity)\n :(lieu: Lieu) => undefined;\n\n const { lieuxDisponibles, lieuxIndisponibles } = {\n lieuxDisponibles: lieuxParDepartement?lieuxParDepartement.lieuxDisponibles:[],\n lieuxIndisponibles: lieuxParDepartement?lieuxParDepartement.lieuxIndisponibles:[],\n };\n\n return {\n ...lieuxParDepartement,\n lieuxAffichables: ArrayBuilder.from([...lieuxDisponibles].map(l => ({...l, disponible: true})))\n .concat([...lieuxIndisponibles].map(l => ({...l, disponible: false})))\n .map(l => ({...l, distance: distanceAvec(l) }))\n .filter(l => !l.distance || l.distance < MAX_DISTANCE_CENTRE_IN_KM)\n .sortBy(l => this.extraireFormuleDeTri(l, this.critèreDeTri))\n .build()\n };\n }\n\n critereTriUpdated(triCentre: CodeTriCentre) {\n this.critèreDeTri = triCentre;\n\n Analytics.INSTANCE.critereTriCentresMisAJour(triCentre);\n\n this.refreshPageWhenValidParams();\n }\n\n renderAdditionnalSearchCriteria(): TemplateResult {\n return html`\n
    \n \n
    \n ({code: tc.codeTriCentre, libelle: tc.libelle }))}\"\n @changed=\"${(event: ValueStrCustomEvent) => this.critereTriUpdated(event.detail.value)}\">\n \n
    \n
    \n `;\n }\n}\n\n@customElement('vmd-rdv-par-departement')\nexport class VmdRdvParDepartementView extends AbstractVmdRdvView {\n\n async onceStartupPromiseResolved() {\n if(this.codeDepartementSelectionne) {\n const departementSelectionne = this.departementsDisponibles.find(d => d.code_departement === this.codeDepartementSelectionne);\n if (departementSelectionne) {\n const component = (this.shadowRoot!.querySelector(\"vmd-commune-or-departement-selector\") as VmdCommuneOrDepartmentSelectorComponent)\n component.fillDepartement(departementSelectionne);\n\n await this.departementSelected(departementSelectionne, false);\n }\n }\n }\n\n libelleLieuSelectionne(): TemplateResult {\n return html`\n pour\n ${this.departementSelectionne?`${this.departementSelectionne.nom_departement} (${this.departementSelectionne.code_departement})`:\"???\"}\n \n `\n }\n\n afficherLieuxParDepartement(lieuxParDepartement: LieuxParDepartement): LieuxAvecDistanceParDepartement {\n const { lieuxDisponibles, lieuxIndisponibles } = {\n lieuxDisponibles: lieuxParDepartement?lieuxParDepartement.lieuxDisponibles:[],\n lieuxIndisponibles: lieuxParDepartement?lieuxParDepartement.lieuxIndisponibles:[],\n };\n\n return {\n ...lieuxParDepartement,\n lieuxAffichables: ArrayBuilder.from([...lieuxDisponibles].map(l => ({...l, disponible: true})))\n .concat([...lieuxIndisponibles].map(l => ({...l, disponible: false})))\n .map(l => ({...l, distance: undefined }))\n .sortBy(l => this.extraireFormuleDeTri(l, 'date'))\n .build()\n };\n }\n}\n","\n\nexport const setDebouncedInterval = function(handler: Function, duration?: number, ...args: any[]) {\n let ongoingHandler = false;\n return setInterval(async () => {\n if(ongoingHandler) {\n console.warn(\"Skipped setDebouncedInterval()'s handler as ongoing already\");\n return;\n }\n try {\n ongoingHandler = true;\n await handler(...args);\n } finally {\n ongoingHandler = false;\n }\n }, duration);\n}\n","import {css, customElement, html, LitElement, unsafeCSS} from 'lit-element';\nimport globalCss from \"../styles/global.scss\";\nimport {Icon, map, marker, tileLayer} from 'leaflet'\nimport leafletCss from 'leaflet/dist/leaflet.css';\nimport leafletMarkerCss from 'leaflet.markercluster/dist/MarkerCluster.Default.css';\n// @ts-ignore\nimport {MarkerClusterGroup} from 'leaflet.markercluster'\nimport {Router} from \"../routing/Router\";\n\n// Code imported (and refactored a little bit)\n// from https://github.com/rozierguillaume/covidtracker-tools/blob/main/src/ViteMaDose/carteCentres.html\n\ntype Lieu = {\n nom: string;\n longitude: number;\n latitude: number;\n reservation: string;\n date_ouverture: string;\n rdv_tel: string;\n modalites: string;\n adresse: string;\n maj: string;\n};\n\n@customElement('vmd-lieux')\nexport class VmdLieuxView extends LitElement {\n\n //language=css\n static styles = [\n css`${unsafeCSS(globalCss)}`,\n css`${unsafeCSS(leafletCss)}`,\n css`${unsafeCSS(leafletMarkerCss)}`,\n css`\n :host {\n display: block;\n }\n #mapid { height: 180px; }\n `\n ];\n\n render() {\n return html`\n

    Carte des centres de vaccination contre la Covid-19

    \n \n \n\n
    \n `;\n }\n\n connectedCallback() {\n super.connectedCallback();\n\n this.requestUpdate().then(() => this.loadMap());\n }\n\n private loadMap() {\n const mymap = map(this.shadowRoot!.querySelector(\"#mapid\") as HTMLElement).setView([46.505, 3], 6);\n const url=\"https://www.data.gouv.fr/fr/datasets/r/5cb21a85-b0b0-4a65-a249-806a040ec372\"\n\n let request = fetch(url)\n .then(response => response.arrayBuffer())\n .then(buffer => {\n const decoder = new TextDecoder();\n const csv = decoder.decode(buffer);\n const data_array = VmdLieuxView.CSVToArray(csv, \";\");\n\n const lieux: Lieu[] = data_array.slice(1, data_array.length-1).map((value: string[], idx) => ({\n longitude: Number(value[10]),\n latitude: Number(value[11]),\n nom: value[1],\n reservation: value[34],\n date_ouverture: value[33],\n rdv_tel: value[35],\n modalites: value[37],\n adresse: value[5] + \" \" + value[6] + \", \" + value[7] + \" \" + value[9],\n maj: value[22].slice(0, 16),\n }))\n\n const markers = VmdLieuxView.creer_pins(lieux);\n mymap.addLayer(markers);\n })\n .catch(function () {\n // this.dataError = true;\n console.log(\"error1\")\n });\n\n tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {\n maxZoom: 19,\n attribution: '© OpenStreetMap contributors'\n }).addTo(mymap);\n }\n\n // ref: http://stackoverflow.com/a/1293163/2343\n // This will parse a delimited string into an array of\n // arrays. The default delimiter is the comma, but this\n // can be overriden in the second argument.\n private static CSVToArray(strData: string, strDelimiter: string ): string[][]{\n // Check to see if the delimiter is defined. If not,\n // then default to comma.\n strDelimiter = (strDelimiter || \",\");\n\n // Create a regular expression to parse the CSV values.\n let objPattern = new RegExp(\n (\n // Delimiters.\n \"(\\\\\" + strDelimiter + \"|\\\\r?\\\\n|\\\\r|^)\" +\n\n // Quoted fields.\n \"(?:\\\"([^\\\"]*(?:\\\"\\\"[^\\\"]*)*)\\\"|\" +\n\n // Standard fields.\n \"([^\\\"\\\\\" + strDelimiter + \"\\\\r\\\\n]*))\"\n ),\n \"gi\"\n );\n\n\n // Create an array to hold our data. Give the array\n // a default empty first row.\n let arrData = [[]] as string[][];\n\n // Create an array to hold our individual pattern\n // matching groups.\n let arrMatches = null;\n\n\n // Keep looping over the regular expression matches\n // until we can no longer find a match.\n while (arrMatches = objPattern.exec( strData )){\n\n // Get the delimiter that was found.\n let strMatchedDelimiter = arrMatches[ 1 ];\n\n // Check to see if the given delimiter has a length\n // (is not the start of string) and if it matches\n // field delimiter. If id does not, then we know\n // that this delimiter is a row delimiter.\n if (\n strMatchedDelimiter.length &&\n strMatchedDelimiter !== strDelimiter\n ){\n\n // Since we have reached a new row of data,\n // add an empty row to our data array.\n arrData.push( [] );\n\n }\n\n let strMatchedValue;\n\n // Now that we have our delimiter out of the way,\n // let's check to see which kind of value we\n // captured (quoted or unquoted).\n if (arrMatches[ 2 ]){\n\n // We found a quoted value. When we capture\n // this value, unescape any double quotes.\n strMatchedValue = arrMatches[ 2 ].replace(\n new RegExp( \"\\\"\\\"\", \"g\" ),\n \"\\\"\"\n );\n\n } else {\n\n // We found a non-quoted value.\n strMatchedValue = arrMatches[ 3 ];\n\n }\n\n\n // Now that we have our value string, let's add\n // it to the data array.\n arrData[ arrData.length - 1 ].push( strMatchedValue );\n }\n\n // Return the parsed data.\n return arrData;\n }\n\n private static creer_pins(lieux: Lieu[]){\n const markers = lieux.reduce((markers: MarkerClusterGroup, lieu, idx)=>{\n let reservation_str = \"\"\n if (typeof lieu.reservation != 'undefined'){\n if (lieu.reservation.indexOf(\"http\") === 0){\n reservation_str = `${lieu.reservation}`\n }\n } else {\n reservation_str = lieu.reservation;\n }\n\n var string_popup = `\n ${lieu.nom}\n
    \n Adresse : ${lieu.adresse}
    Réservation : ${reservation_str}\n
    \n Tél : ${lieu.rdv_tel}\n
    \n Date d'ouverture : ${lieu.date_ouverture}
    Modalités : ${lieu.modalites}\n
    \n Mise à jour : ${lieu.maj}\n `;\n var newMarker = marker([lieu.longitude, lieu.latitude], {\n icon: new Icon.Default({imagePath: `${Router.basePath}assets/images/png/`})\n }).bindPopup(string_popup) //.addTo(this.mymap);\n newMarker.on('click', function(e: any) {\n // @ts-ignore\n this.openPopup();\n });\n markers.addLayer(newMarker);\n\n return markers;\n }, new MarkerClusterGroup({ disableClusteringAtZoom: 9 }));\n return markers;\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n // console.log(\"disconnected callback\")\n }\n}\n","import {LitElement, html, customElement, property, css} from 'lit-element';\nimport {classMap} from \"lit-html/directives/class-map\";\n\n@customElement('vmd-apropos')\nexport class VmdAproposComponent extends LitElement {\n\n //language=css\n static styles = [\n css`\n `\n ];\n\n constructor() {\n super();\n }\n\n render() {\n return html`\n \n `;\n }\n\n connectedCallback() {\n super.connectedCallback();\n // console.log(\"connected callback\")\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n // console.log(\"disconnected callback\")\n }\n}\n"],"names":["modulePath","importFunctionName","Function","error","baseURL","URL","location","cleanup","script","revokeObjectURL","src","remove","url","Promise","resolve","reject","absURL","self","moduleMap","moduleBlob","Blob","type","Object","assign","document","createElement","createObjectURL","[object Object]","Error","head","appendChild","p","value","size","filler","padSize","length","pad","i","pluralForm","phoneNumber","normalizedPhoneNumber","formatInternational","indexOf","replace","substring","join","toLowerCase","TRIS_CENTRE","Map","codeTriCentre","libelle","VMD_BASE_URL","PLATEFORMES","Doctolib","code","logo","nom","promoted","website","styleCode","Maiia","Ordoclic","Keldoc","Pandalab","Mapharma","libelleUrlPathDuDepartement","departement","Strings","toReadableURLPathValue","nom_departement","TYPES_LIEUX","vaccination-center","drugstore","general-practitioner","l1","l2","rawLieu","__assign","appointment_count","metadata","address","adr_num","adr_voie","com_cp","com_nom","filter","val","vaccine_type","lieuAffichable","appointment_by_phone_only","phone_number","codeDepartement","libelleUrlPathDeCommune","commune","avoidCache","this","_lieuxParDepartement","has","get","resp","fetch","results","json","lieuxParDepartement","lieuxDisponibles","centres_disponibles","map","transformLieu","lieuxIndisponibles","centres_indisponibles","codeDepartements","derniereMiseAJour","last_updated","set","_departementsDiponibles","departements","sort","d1","d2","convertDepartementForSort","code_departement","localeCompare","departementsDisponibles","find","dep","_State","DEPARTEMENT_VIDE","basePath","_communeAutocompleteTriggers","autocompletes","then","autocomplete","_communesParAutocomplete","communes","communesResult","c","codePostal","z","n","d","longitude","g","Number","split","latitude","codeCommune","trigger","communeAutocompleteTriggers","startsWith","trigger2","communesPourAutocomplete","COMMUNE_VIDE","_statsLieu","statsParDepartements","statsLieu","parDepartements","entries","dpt","stats","reduce","statsParDept","global","proportion","Math","round","disponibles","total","window","hostname","State","current","code_region","nom_region","nomPage","dataLayer","push","event","site_name","page_type","lieu","rdv_departement","rdv_platorm","plateforme","rdv_platform","rdv_name","rdv_location_type","rdv_vaccine","rdv_filter_type","resultats","search_departement","search_commune","search_nb_doses","lieuxAffichables","totalDoses","search_nb_appointments","search_nb_lieu_vaccination","typeActionPour","l","search_nb_lieu_vaccination_inactive","search_filter_type","critèreDeTri","triCentre","sort_changed_to","Analytics","INSTANCE","_Analytics","callback","callbackCleaner","onViewChanged","redirect","declareRoutes","pathPattern","analyticsViewName","viewContent","params","subViewSlot","html","pageTitleProvider","chercheDepartementParCode","nomDpt","chercheCommuneParCode","Router","context","_notFoundRoute","routeDeclaration","forEach","_declareRoute","path","_Routing","DEFAULT_TITLE_PROMISE","pageName","viewComponentCreator","titlePromise","slottedViewComponentFactoryResult","all","catch","DEFAULT_TITLE","slottedViewTemplateFactory","title","currentPath","currentTemplateResultCreator","_viewChangeCallbacks","navigationSurNouvellePage","idx","findIndex","registeredCallback","splice","navigateToHome","pathLibelleDepartement","pathLibelleCommune","open","Routing","db","openDB","oldVersion","newVersion","transaction","createObjectStore","keyPath","warn","info","subscription","id","objectStore","add","getAll","subscriptions","fetchAllSubscriptions","subscriptionToDelete","sameLieu","s","delete","ts","debugs","name","DB","_DB","async","navigator","serviceWorker","controller","postMessage","subscriptionTopics","gid","Messaging","_Messaging","MessageChannel","addEventListener","serviceWorkerRegistration","register","log","updated","newWorker","installing","state","messageChannel","port2","port1","onmessage","data","payload","ensureStarted","PushNotifications","ensureGranted","ServiceWorkers","_ServiceWorkers","result","_PushNotifications","askPermission","granted","status","e","Notification","permission","permissionResult2","requestPermission","LitElement","installRoutes","viewTemplateResult","initialize","startup","tryDebug","debugCounter","switchDebugMode","connectedCallback","disconnectedCallback","VmdAppComponent","styles","css","unsafeCSS","globalCss","__decorate","property","attribute","prototype","customElement","trancheAgeSelectionne","codeTrancheAgeSelectionne","Array","from","tranchesAge","values","trancheAge","codeTrancheAge","currentTarget","dispatchEvent","CustomEvent","detail","VmdTrancheAgeSelectorComponent","String","departementSelectionne","codeDepartementSelectionne","repeat","dept","VmdDepartementSelectorComponent","FR_WEEK_DAYS","0","1","2","3","4","5","6","FR_MONTHES","7","8","9","10","11","lundi","index","shortName","mardi","mercredi","jeudi","vendredi","samedi","dimanche","weekdays","weekday","desc","fill","isoDateStr","Date","parse","isNaN","date","getDay","getDate","getMonth","padLeft","getHours","getMinutes","Dates","parseISO","formatToFRDateTime","isoDate","durationFromNow","formatDuration","durationBetween","date1","date2","totalMillis","abs","getTime","millis","seconds","minutes","hours","days","totalHours","totalMinutes","totalSeconds","unit","skipPlural","plural","showValue","distance","cardConfig","toFixed","typeLieu","specificCardConfig","disabledBG","libelleDateAbsente","libelleBouton","typeBouton","onclick","verifierRdv","additionalActions","locationWatchEligibility","classMap","disabled","changeSubscription","preventDefault","stopPropagation","watching","prendreRdv","estCliquable","cardLink","content","actions","btn-primary","btn-info","toLocaleString","toNormalizedPhoneNumber","clickable","bg-disabled","prochain_rdv","isoToFRDatetime","stopImmediatePropagation","action","VmdAppointmentCardComponent","Boolean","METADATA_WIDTH_CLASSES","full-width","fit-to-content","3col-equally-distributed","widthType","align-items-center","centerIconVertically","icon","classList","displayed","style","display","VmdAppointmentMetadataComponent","cd","_communesDisponibles","filtrerCommunesAffichees","requestUpdate","inputHasFocus","inputMode","dropDownVide","communesDisponibles","codeCommuneSelectionne","communesAffichees","aucuneCommuneAffichee","fullTextSearchableQuery","toFullTextSearchableString","fullTextSearchableNomCommune","_","filterMatchingAutocomplete","autocompleteTriggers","some","filterSizeAttempt","filterAttempt","searchableFilterAttempt","shadowRoot","querySelector","activeElement","_open","showDropdown","_withButton","inputModeFixedToText","hideDropdownWhenInputHasNotFocus","valueChanged","focus","recuperationCommunesEnCours","renderListItems","communeSelected","autoCompleteCodePostal","VmdCommuneSelectorComponent","internalProperty","dpts","departementsCherchables","fullTextSearchableCodeDepartement","fullTextSearchableNom","departementsAffiches","filtrerDepartementsAffichees","super","VmdCommuneOrDepartmentSelectorComponent","valeurSelectionnee","additionnalDefaultLabel","codeSelectionne","options","option","o","VmdSelectorComponent","active","VmdButtonSwitchComponent","departementSelectione","navigateToRendezVousAvecDepartement","communeSelectionee","navigateToRendezVousAvecCommune","rechercherRdv","communeAutocompleteTriggered","departementSelected","communesAutocomplete","p2","creneaux","statsLieux","Set","VmdHomeView","deg","PI","DEPARTEMENTS_LIMITROPHES","01","02","03","04","05","06","07","08","09","12","13","14","15","16","17","18","19","2A","2B","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40","41","42","43","44","45","46","47","48","49","50","51","52","53","54","55","56","57","58","59","60","61","62","63","64","65","66","67","68","69","70","71","72","73","74","75","76","77","78","79","80","81","82","83","84","85","86","87","88","89","90","91","92","93","94","95","971","972","973","974","976","pushNotificationStatus","currentStatus","Capabilities","_Capabilities","array","concat","mapper","ArrayBuilder","predicate","comparator","sortableDataExtractor","v1","v2","derniereCommuneSelectionnee","getCommuneSelectionnee","getDepartementSelectionne","communeSelectionnee","lieuxParDepartementAffiches","triggerNavigation","resetCommuneSelectionneeTo","refreshPageWhenValidParams","disponible","getCodeCommuneSelectionne","renderAdditionnalSearchCriteria","searchInProgress","styleMap","totalCreneaux","libelleLieuSelectionne","formatDurationFromNow","miseAJourDisponible","refreshLieux","abonnementSur","changerAbonnementAuLieu","now","notificationUrl","href","subscribeToCenterAppointments","subscribeTo","refreshAbonnements","unsubscribeToCenterAppointments","unsubscribeFrom","onCommuneAutocompleteLoaded","onceStartupPromiseResolved","currentDeviceIsEligibleToLocationWatch","refreshAbonnementsIntervalId","setInterval","lieuBackgroundRefreshIntervalId","handler","duration","args","ongoingHandler","setDebouncedInterval","lieuxAJourPourDepartement","lieuxPour","abonnements","a","preventRafraichissementLieux","lieuxDepartement","lieuxDepartementsLimitrophes","codeDepartementAdditionnels","mergedLieuxParDepartement","lieuxParDepartement2","afficherLieuxParDepartement","rechercheLieuEffectuee","_onRefreshPageWhenValidParams","clickSurRdv","navigateToUrlIfPossible","clickSurVerifRdv","tri","firstLevelSort","AbstractVmdRdvView","codePostalSelectionne","refreshBasedOnCodePostalSelectionne","getAutoCompleteCodePostal","updateCommunesDisponiblesBasedOnAutocomplete","fillCommuneInSelector","autoCompleteAttempt","fillCommune","origin","distanceAvec","lat1","lon1","lat2","lon2","dLat","deg2rad","dLon","sin","cos","atan2","sqrt","distanceEntreDeuxPoints","Infinity","sortBy","extraireFormuleDeTri","build","critereTriCentresMisAJour","tc","critereTriUpdated","VmdRdvParCommuneView","fillDepartement","VmdRdvParDepartementView","loadMap","mymap","setView","response","arrayBuffer","csv","TextDecoder","decode","buffer","data_array","VmdLieuxView","CSVToArray","lieux","slice","reservation","date_ouverture","rdv_tel","modalites","adresse","maj","markers","creer_pins","addLayer","maxZoom","attribution","addTo","strData","strDelimiter","objPattern","RegExp","arrData","arrMatches","exec","strMatchedValue","strMatchedDelimiter","markers2","reservation_str","string_popup","newMarker","marker","Icon","Default","imagePath","bindPopup","on","openPopup","MarkerClusterGroup","disableClusteringAtZoom","VmdAproposComponent"],"mappings":"kdAAU,SAAkBA,EAAa,IAAKC,EAAqB,uBAEtDA,GAAsB,IAAIC,SAAS,IAAK,0BAE1CC,SACGC,EAAU,IAAIC,IAAIL,EAAYM,UAC9BC,EAAWC,QACTC,gBAAgBD,EAAOE,OACpBC,eAENV,GAAuBW,GAAQ,IAAIC,SAAQ,CAACC,EAASC,WAChDC,EAAS,IAAIX,IAAIO,EAAKR,MAExBa,KAAKhB,GAAoBiB,UAAUF,UAC5BF,EAAQG,KAAKhB,GAAoBiB,UAAUF,UAEhDG,EAAa,IAAIC,KAAK,CACxB,uBAAuBJ,MACvB,GAAGf,gBAAiCe,UACrC,CAAEK,KAAM,oBACLb,EAASc,OAAOC,OAAOC,SAASC,cAAc,UAAW,CAC3DJ,KAAM,SACNX,IAAKL,IAAIqB,gBAAgBP,GACzBQ,YACW,IAAIC,MAAM,qBAAqBhB,QAC9BJ,IAEZmB,WACYV,KAAKhB,GAAoBiB,UAAUF,MACnCR,eAGPqB,KAAKC,YAAYtB,WAEzBP,GAAoBiB,UAAY,IAEvBa,CAAE,6nzNCjCEC,EAAeC,EAAcC,SACzCC,EAAUF,MAAWD,GAAOI,WAC9BC,EAAM,WACFC,EAAE,EAAGA,EAAEH,EAASG,GAAKJ,EAAOE,UAAiBF,SAC9CG,EAAIL,gBAGMA,EAA8BO,EAAqB,YAC5DP,GAASA,EAAM,EAAGO,EAAW,kCAGVC,WACR,IAAhBA,aAICC,EAAwBD,QACtBE,EAA6D,IAAvCD,EAAsBE,QAAQ,cAElCF,EAAsBG,QAAQ,WAAY,IAC/DF,MACyB,IAAID,EAAsBI,UAAUJ,EAAsBL,OAAS,EAAGK,EAAsBL,aAGhG,CACpBK,EAAsB,GAAIA,EAAsB,GAAI,IACpDA,EAAsB,GAAIA,EAAsB,GAAI,IACpDA,EAAsB,GAAIA,EAAsB,GAAI,IACpDA,EAAsB,GAAIA,EAAsB,GAAI,IACpDA,EAAsB,GAAIA,EAAsB,IAClDK,KAAK,IAEAL,gCAG0BT,UAC1BA,EAAMe,cACRH,QAAQ,WAAY,KACpBA,QAAQ,cAAe,KACvBA,QAAQ,eAAgB,KACxBA,QAAQ,SAAU,KAClBA,QAAQ,WAAY,KACpBA,QAAQ,QAAS,KACjBA,QAAQ,aAAc,KACtBA,QAAQ,aAAc,KACtBA,QAAQ,QAAS,wCAGeZ,UAG9BA,EAAMe,cACRH,QAAQ,WAAY,KACpBA,QAAQ,cAAe,KACvBA,QAAQ,eAAgB,KACxBA,QAAQ,SAAU,KAClBA,QAAQ,WAAY,KACpBA,QAAQ,QAAS,KACjBA,QAAQ,aAAc,KACtBA,QAAQ,aAAc,KACtBA,QAAQ,QAAS,aC9CjBI,EAA6C,IAAIC,IAAI,CAC9D,CAAC,WAAY,CAAEC,cAAe,WAAYC,QAAS,mBACnD,CAAC,OAAQ,CAAED,cAAe,OAAQC,QAAS,8BAIzCC,EAEF,0CAeSC,EAA0C,CACnDC,SAAY,CAAEC,KAAM,WAAYC,KAAM,oBAAqBC,IAAK,WAAYC,UAAU,EAAOC,QAAS,2BAAuCC,UAAW,aACxJC,MAAY,CAAEN,KAAM,QAAYC,KAAM,iBAAqBC,IAAK,QAAYC,UAAU,EAAOC,QAAS,yBAAuCC,UAAW,UACxJE,SAAY,CAAEP,KAAM,WAAYC,KAAM,oBAAqBC,IAAK,WAAYC,UAAU,EAAOC,QAAS,2BAAuCC,UAAW,aACxJG,OAAY,CAAER,KAAM,SAAYC,KAAM,kBAAqBC,IAAK,SAAYC,UAAU,EAAOC,QAAS,0BAAuCC,UAAW,WACxJI,SAAY,CAAET,KAAM,WAAYC,KAAM,oBAAqBC,IAAK,WAAYC,UAAU,EAAOC,QAAS,sCAAuCC,UAAW,aACxJK,SAAY,CAAEV,KAAM,WAAYC,KAAM,oBAAqBC,IAAK,WAAYC,UAAU,EAAOC,QAAS,6BAAuCC,UAAW,cAc/IM,EAA+BC,GACjCC,EAAQC,uBAAuBF,EAAYG,iBAIzCC,EAAyC,CAClDC,qBAAsB,wBACtBC,UAAa,YACbC,uBAAwB,kCAsBHC,EAAUC,UAExBD,EAAGlB,MAAQmB,EAAGnB,IAGzB,WAAuBoB,UACZC,OACAD,GADA,CAEHE,kBAAmBF,EAAQE,mBAAqB,EAChDC,SAAUF,OACHD,EAAQG,UADL,CAENC,QAA8C,iBAA7BJ,EAAQG,SAASC,QAC9BJ,EAAQG,SAASC,QAChB,CACGJ,EAAQG,SAASC,QAAQC,QACzBL,EAAQG,SAASC,QAAQE,SACzBN,EAAQG,SAASC,QAAQG,OACzBP,EAAQG,SAASC,QAAQI,SAC3BC,aAAgBC,IAAKzC,KAAK,OAEpC0C,aAAcX,EAAQW,mBAA6C,MAAtBA,aAAapD,OAAmB,CAACyC,EAAQW,cAAcX,EAAQW,cAAe1C,KAAK,WAAM,eAmB/G2C,UACTA,EAAeC,2BAA6BD,EAAeT,SAASW,aAE3E,gBACDF,GAAuD,IAArCA,EAAeV,kBAChC,uBACDU,GAAuD,IAArCA,EAAeV,kBAChC,yBAEA,UAIf,WAAmCa,UACxBA,OACE,WAAa,UACb,WAAa,qBACFA,SAuBXC,EAA2BC,GAC7B1B,EAAQC,uBAAuByB,EAAQrC,aAsBtC9B,wCAG6C,IAAIsB,sCAkBE,yCAmBA,gCAYC,IAAIA,yBAmCtB,kBAnF1B2C,EAAkCG,GAAsB,MACjEC,KAAKC,qBAAqBC,IAAIN,KAAqBG,SAC3ClF,QAAQC,QAAQkF,KAAKC,qBAAqBE,IAAIP,IAClD,OACGQ,QAAaC,MAAM,GAAGjD,KAAgBwC,UACtCU,QAAgBF,EAAKG,OACrBC,EAAsB,CACxBC,iBAAkBH,EAAQI,oBAAoBC,IAAIC,GAClDC,mBAAoBP,EAAQQ,sBAAsBH,IAAIC,GACtDG,iBAAkB,CAACnB,GACnBoB,kBAAmBV,EAAQW,0BAE1BhB,qBAAqBiB,IAAItB,EAAiBY,GACxCA,2CAMyB,IAAjCR,KAAKmB,+BACGtG,QAAQC,QAAQkF,KAAKmB,yBACzB,OACGf,QAAaC,MAAM,GAAGjD,uBACtBgE,QAAoChB,EAAKG,mBAE1CY,wBAA0BC,OAC1BD,wBAAwBE,MAAK,CAACC,EAAIC,IAAOC,EAA0BF,EAAGG,kBAAkBC,cAAcF,EAA0BD,EAAGE,qBACjIL,mCAIiB7D,gBACXyC,KAAK2B,2BACVC,SAAYC,EAAIJ,mBAAqBlE,KAASuE,EAAMC,mDAIlCC,WACW,IAAtChC,KAAKiC,oCACGpH,QAAQC,QAAQkF,KAAKiC,8BACzB,OACGC,QAAsB7B,MAAM,GAAG2B,uBAA8BG,SAAa/B,EAAKG,qBAEhF0B,6BAA+BC,EAC7BA,kCAKgBF,EAAkBI,MAC1CpC,KAAKqC,yBAAyBnC,IAAIkC,UAC1BpC,KAAKqC,yBAAyBlC,IAAIiC,GACtC,OACGE,QAAiBjC,MAAM,GAAG2B,uBAA8BI,UACzDD,SAAa/B,EAAKG,SAClB4B,SAAuBI,EAAeD,SAAS3B,KAAK6B,IACxB,CACrBjF,KAAMiF,EAAEA,EACRC,WAAYD,EAAEE,EACdjF,IAAK+E,EAAEG,EACP/C,gBAAiB4C,EAAEI,EACnBC,UAAWL,EAAEM,EAAEC,OAAOP,EAAEM,EAAEE,MAAM,KAAK,SAAI,EACzCC,SAAUT,EAAEM,EAAEC,OAAOP,EAAEM,EAAEE,MAAM,KAAK,SAAI,oBAK/CX,yBAAyBnB,IAAIkB,EAAcE,GACzCA,+BAIaN,EAAkBS,EAAoBS,OAE1DC,SADiBnD,KAAKoD,4BAA4BpB,IAC/BJ,SAAgBa,EAAWY,WAAWC,QACzDH,EAAS,cACYnD,KAAKuD,yBAAyBvB,EAAUmB,IAC7CvB,SAAgB9B,EAAQvC,OAAS2F,KAAgBpB,EAAM0B,oBAEhE3I,QAAQC,QAAQgH,EAAM0B,yCAMV,IAApBxD,KAAKyD,kBACG5I,QAAQC,QAAQkF,KAAKyD,YACzB,OACGrD,QAAaC,MAAM,GAAGjD,gBACtBsG,QAAmFtD,EAAKG,OAExFoD,EAAY,CACdC,gBAAiBtI,OAAOuI,QAAQH,GAC3BpE,QAAO,EAAEwE,EAAKC,KAAmE,qBAARD,IACzEE,QAAO,CAACC,GAAeH,EAAKC,QACJD,GAAOC,EACrBL,IACR,IACPQ,OAAQpF,OACD4E,oBADC,CAEJS,WAAYC,KAAKC,MAA6D,IAAvDX,mBAAyCY,YAAsBZ,mBAAyCa,OAAO,mBAGzId,WAAaE,EACXA,6BAKyB,+BAA7Ba,OAAOlK,SAASmK,SAA0C,OAAO,gBAnI9DC,EAAAC,QAAU,IAAI7C,EADzB4C,EAGY3C,iBAAgC,CAC3CN,iBAAkB,GAClBmD,YAAa,EACbtG,gBAAiB,GACjBuG,WAAY,IAPbH,EAUYlB,aAAwB,CACnCjG,KAAM,GACNqC,gBAAiB,GACjB6C,WAAY,GACZQ,cAAU,EACVJ,eAAW,EACXpF,IAAK,IC3KN,cAGO9B,eAGVA,0BAA0BmJ,UACfC,UAAUC,KAAK,CAClBC,MAAS,gBACTC,UAAc,eACdC,UAAcL,IAItBnJ,YAAYyJ,UACDL,UAAUC,KAAK,CAClBC,MAAS,YACTI,gBAAoBD,EAAKjH,YACzBmH,YAAgBF,EAAKG,WACrBC,aAAiBJ,EAAKG,WACtBE,SAAYL,EAAK3H,IACjBiI,kBAAsBN,EAAK/J,KAC3BsK,YAAgBP,EAAK5F,aACrBoG,qBAAoB,IAI5BjK,iBAAiByJ,UACNL,UAAUC,KAAK,CAClBC,MAAS,aACTI,gBAAoBD,EAAKjH,YACzBmH,YAAgBF,EAAKG,WACrBC,aAAiBJ,EAAKG,WACtBE,SAAYL,EAAK3H,IACjBiI,kBAAsBN,EAAK/J,KAC3BsK,YAAgBP,EAAK5F,aACrBoG,qBAAoB,IAI5BjK,uBAAuBiE,EAAkCE,EAA4B+F,UAC1Ed,UAAUC,KAAK,CAClBC,MAASnF,EAAQ,oBAAoB,wBACrCgG,mBAAsBlG,EACtBmG,eAAmBjG,EAAQ,GAAGA,EAAQ2C,gBAAgB3C,EAAQrC,QAAQqC,EAAQvC,aAAQ,EAEtFyI,gBAAoBH,EAAUA,EAAUI,iBAAiBjC,QAAO,CAACkC,EAAYd,IAASc,EAAWd,EAAKrG,mBAAmB,QAAG,EAC5HoH,uBAA2BN,EAAUA,EAAUI,iBAAiBjC,QAAO,CAACkC,EAAYd,IAASc,EAAWd,EAAKrG,mBAAmB,QAAG,EACnIqH,2BAA+BP,EAAUA,EAAUI,iBAC9C3G,WAAkC,yBAAtB+G,EAAeC,IAAuD,kBAAtBD,EAAeC,KAC3ElK,YAAO,EACZmK,oCAAwCV,EAAUA,EAAUI,iBACvD3G,WAAkC,YAAtB+G,EAAeC,KAC3BlK,YAAO,EACZoK,mBAAuBxG,KAAayG,cAAgB,SAI5D9K,0BAA0B+K,UACf3B,UAAUC,KAAK,CAClBC,MAAS,cACT0B,gBAAoBD,cA5DLE,EAAAC,SAAW,IAAIC,ECA1C,cAAAnL,wCAO0D,0CAEyB,wBACvC,uBAG7B,cAGXA,cAAcoL,SACJC,EAAkBD,EAAS/G,KAAKiH,cAAcF,QAAU,WAEzDG,SAAS,GAAGlH,KAAKgC,eAAgB,OACjCkF,SAAS,GAAGlH,KAAKgC,qBAAsB,UAEvCmF,cAAc,CACfC,YAAa,IAAKC,kBAAmB,OACrCC,YAAcC,GAAYC,GACtBC,cAAiBD,sBAEpBL,cAAc,CACfC,YAAa,CAET,kEACA,6FAEA,kDACDC,kBAAmB,+BACtBC,YAAcC,GAAYC,GACtBC,yDAA4DF,cAAsBC,8BACtFE,kBAAoBH,GAChB7C,EAAMC,QAAQgD,0BAA0BJ,WACnCpF,SAAe,2BAA2ByF,EAAOtJ,mBAAmBiJ,qBAE5EJ,cAAc,CACfC,YAAa,0HACbC,kBAAmB,yBACnBC,YAAcC,GAAYC,GACtBC;8CAC8BF;6CACDA;oCACTA;oBAChBC;wCAERE,kBAAoBH,GAChB7C,EAAMC,QAAQkD,sBAAsBC,EAAO9F,SAAUuF,aAAsBA,eACtEpF,SAAgB,0BAA0BrC,EAAQrC,OAAOqC,EAAQ2C,sBAEzE0E,cAAc,CACfC,YAAa,WAAYC,kBAAmB,UAC5CC,YAAcC,GAAYC,GACtBC,eAAkBD,uBAErBL,cAAc,CACfC,YAAa,WAAYC,kBAAmB,WAC5CC,YAAcC,GAAYC,GACtBC,iBAAoBD,sBAGvB,KAAMO,GAAY/H,KAAKgI,eAAeD,SAGpCf,EAGHrL,cAAcsM,IAC+C,iBAAjCA,EAAiBb,YAA4B,CAACa,EAAiBb,aAAea,EAAiBb,aACzHc,kBACGC,cAAcC,EAAMH,EAAiBZ,kBAAmBY,EAAiBX,YAAaW,EAAiBP,mBAAqBW,EAAQC,0BAIzI3M,cAAcyM,EAAcG,EAAkBC,EACjCC,EAAeJ,EAAQC,yBACnC,GAAGtI,KAAKgC,WAAWoG,EAAKvL,UAAoB,MAAVuL,EAAK,GAAS,EAAE,MAAOL,UACpDW,EAAoCF,EAAqBT,EAAQR,gBAE/DoB,IAAI,CACND,aAA6C7N,QAC3C6N,EAEA7N,QAAQC,QAAQ4N,GACpBD,EAAaV,EAAQR,QAAQqB,OAAM,IAAMP,EAAQQ,kBAClD1G,MAAK,EAAE2G,EAA4BC,WAC7BC,YAAcZ,OACda,6BAA+BH,WAE3BC,MAAQA,OAEZG,qBAAqBhB,YAAoBnB,EAAS+B,EAA4BV,OAEzEvB,SAASsC,0BAA0BZ,SAKzD5M,cAAcoL,eACLmC,qBAAqBlE,KAAK+B,GACxB,WACGqC,EAAMpJ,KAAKkJ,qBAAqBG,cAAgCC,IAAuBvC,SACxFmC,qBAAqBK,OAAOH,EAAK,IAItCzN,eAAeoM,WACX5N,MAAM,qBAAqB4N,EAAQK,sCACtCoB,iBAGF7N,oCAAoCiE,EAAyB6J,KAC3D,GAAGzJ,KAAKgC,wCAAwCpC,KAAmB6J,KAGrE9N,gCAAgCuB,EAA8B0C,EAAyB6J,EAAgCvG,EAAqBT,EAAoBiH,KAC9J,GAAG1J,KAAKgC,wCAAwCpC,KAAmB6J,YAAiCvG,KAAeT,KAAciH,mBAAoCxM,KAG9KvB,mBACS,GAAGqE,KAAKgC,YAGjBrG,wBAAwBf,GACjBA,UACQ+O,KAAK/O,EAAK,YAlI7B,QAC2BgP,EAAA/C,SAAW,IAAIwB,EAD1CuB,EAG4Bf,cAAgB,4DAH5Ce,EAI4BtB,sBACpB,IAAMzN,QAAQC,QAAQuN,EAAQQ,qBAkIzBf,EAAS8B,EAAQ/C,iBCxIlBlL,2BAF6B,0BAM5BkO,SAAWC,EAAO,eAAgB,EAAG,CACtCnO,QAAQkO,EAAIE,EAAYC,EAAYC,GAC7BF,EAAa,KACTG,kBAAkB,gBAAiB,CAAEC,QAAS,OAElDJ,EAAa,KACTG,kBAAkB,QAAS,CAACC,QAAS,UAGhDxO,kBACYxB,MAAM,mBAElBwB,mBACYyO,KAAK,oBAEjBzO,qBACY0O,KAAK,4DAKWC,OAC5BtK,KAAK6J,SACC,IAAIjO,MAAM,8BAGd2O,QAAWvK,KAAK6J,GAAGI,YAAY,CAAC,iBAAkB,aAAaO,YAAY,iBAAiBC,IAAIH,WAC9FD,KAAK,gCAAgCE,uCAIzCvK,KAAK6J,SACC,IAAIjO,MAAM,qCAGPoE,KAAK6J,GAAGI,YAAY,CAAC,kBAAkBO,YAAY,iBAAiBE,+CAG/CtF,OAC9BpF,KAAK6J,SACC,IAAIjO,MAAM,8BAGd+O,QAAsB3K,KAAK4K,wBAC3BC,QAA6BF,EAAc/I,SAAUkJ,EAASC,EAAE3F,KAAMA,KACzEyF,SACO7K,KAAK6J,GAAGI,YAAY,CAAC,iBAAkB,aAAaO,YAAY,iBAAiBQ,OAAOH,EAAqBI,gCAKnHjL,KAAK6J,SACC,IAAIjO,MAAM,8BAGdsP,QAAelL,KAAK6J,GAAGI,YAAY,CAAC,UAAUO,YAAY,SAASE,SAC/B,IAAhBQ,EAAO9O,cAGvB4D,KAAK6J,GAAGI,YAAY,CAAC,SAAU,aAAaO,YAAY,SAASQ,OAAOE,EAAO,GAAGC,YAClF,0CAEAnL,KAAK6J,GAAGI,YAAY,CAAC,SAAU,aAAaO,YAAY,SAASC,IAAI,CAACU,KAAM,kBAC5E,4CAvESC,EAAAvE,SAAW,IAAIwE,ECZnC,cAGK1P,4CAIG,IAAId,SAAQyQ,MAAOxQ,6BASZ6P,SACRY,UAAUC,cAAcC,WAAYC,YAAY,CAClDrQ,KAAM,sBACNsQ,mBAAoBhB,EAAchK,QAAS,cAAcoK,EAAE5M,YAAYsD,2BAA2BsJ,EAAE3F,KAAKwG,gCAI3FjB,SACZY,UAAUC,cAAcC,WAAYC,YAAY,CAClDrQ,KAAM,wBACNsQ,mBAAoBhB,EAAchK,QAAS,cAAcoK,EAAE5M,YAAYsD,2BAA2BsJ,EAAE3F,KAAKwG,oBAzB1FC,EAAAhF,SAAW,IAAIiF,ECCnC,cAMKnQ,kCAFiB,IAAIoQ,mCAOpBR,UAAUC,6BACHnB,KAAK,iCACN,QAKL,IAAIxP,SAAQ,CAACC,EAASC,IAAWyJ,OAAOwH,iBAAiB,OAAQlR,WAEjEmR,QAAkCV,UAAUC,cAAcU,SAAS,GAAGpE,EAAO9F,2BAEzEwJ,cAAcQ,iBAAiB,oBAAoB,aACjDG,IAAI,uCASY,IAAItR,SAAuD,CAACC,EAASC,KAC1FwQ,UAAUC,cAAcC,cACf,CAACA,WAAYF,UAAUC,cAAcC,WAAYW,SAAS,MAG5CJ,iBAAiB,eAAe,WAChDK,EAAYJ,EAA0BK,aAClCN,iBAAiB,eAAgB/G,IAChB,cAApBoH,EAAUE,SACD,CAAEd,WAAYF,UAAUC,cAAcC,WAAaW,SAAS,cAMtEX,WAAWC,YAAY,CACjCrQ,KAAM,aACP,CAAC2E,KAAKwM,eAAeC,aACnBD,eAAeE,MAAMC,UAAY,SAAU1H,WACpCkH,IAAIlH,EAAM2H,KAAKC,uBAIIzB,EAAGvE,SAAS+D,yBACvBxO,cACVvB,QAAQ8N,IAAI,CACdkD,EAAUhF,SAASiG,gBACnBC,EAAkBlG,SAASmG,mBAI5B,YA7DYC,EAAApG,SAAW,IAAIqG,EAkEnC,cAIKvR,4CAIG,IAAId,SAAQyQ,MAAOxQ,cAEZqS,QAAeC,EAAkBC,kBAGzB,YAAXF,EACS,CAAEG,SAAS,GAEX,CAAEA,SAAS,EAAOjS,KAAM,cAAekS,OAAQJ,UAEvDK,KACI,CAAEF,SAAS,EAAOjS,KAAM,QAASlB,MAAOqT,QAK5D7R,uBACQ8R,aAI2B,YAA5BA,aAAaC,WACL,UAC2B,WAA5BD,aAAaC,WACZ,SAC2B,YAA5BD,aAAaC,WACZ,wBAGJ,qBAXI,sDAePD,4BACQpD,KAAK,gCACN,sBAUc,kBAPM,IAAIxP,SAAQ,CAACC,EAASC,WAC3C4S,EAAmBF,aAAaG,mBAAmBT,GAAWrS,EAAQqS,KACxEQ,KACiBxL,KAAKrH,EAASC,eAK3BZ,MAAM,kCACP,UAEJ,oBAvDY4S,EAAAlG,SAAW,IAAIuG,sNClELS,EAejClS,mDAFyG,oBA+DlF,IA1DZmS,eAAc,CAACC,EAAoB3F,UACjC2F,mBAAqBA,OAG3BlH,SAASmH,aAAa7L,MAAK,OACX0E,SAASoH,aAIhCtS,gBACW8L;;;4EAG6D,IAAMK,EAAO0B;oCACrD1B,EAAO9F;oCACP8F,EAAO9F;;;;;2CAKA8F,EAAO9F;;;;;;;;;;cAUpChC,KAAK+N,mBAAmB/N,KAAK+N,mBAAmBtG;;;;eAI/CA;;;;oCAIqB,IAAMzH,KAAKkO;;;;;;;;;;;;;;;;;UAqB3CvS,gBACSwS,eACFnO,KAAKmO,aAAa,GAAM,YACfhC,IAAI,6CACTtF,SAASuH,mBAIpBzS,0BACU0S,oBAIV1S,6BACU2S,yBA3FPC,EAGIC,OAAS,CACZC,IAAMC,EAAUC,KAChBF;;;;;WAQwCG,GAA3CC,EAAS,CAACxT,KAAMC,OAAQwT,WAAW,KAAQP,EAAAQ,kCAbzCR,KADNS,EAAc,YACRT,wNCD6CV,EAehDlS,qDAHyE,oBACe,IAAIsB,IAM5FtB,gBACW8L;kEACmDzH,KAAKiP;4CACQ,KAAnCjP,KAAKkP;gBACjCC,MAAMC,KAAKpP,KAAKqP,YAAYC,UAAU3O,QAC7B8G;uCACc8H,EAAWC,8BAA8BxP,KAAKkP,4BAA8BK,EAAWC,mBAAmBD,EAAWpS;;;UAOxJxB,sBAAsBsJ,QACbiK,0BAA6BjK,EAAMwK,cAAoCzT,WACvE0T,cAAc,IAAIC,YAAmC,sBAAuB,CAC7EC,OAAQ,CACJL,WAAgD,KAAnCvP,KAAKkP,+BAAkC,EAAUlP,KAAKqP,YAAYlP,IAAIH,KAAKkP,+BAKpGvT,0BACU0S,oBAIV1S,6BACU2S,yBA/CPuB,GAGIrB,OAAS,CACZC,IAAMC,EAAUC,KAChBF;;;;WAOsBG,GAAzBC,EAAS,CAACxT,KAAMyU,UAASD,GAAAd,yCACeH,GAAxCC,EAAS,CAACxT,KAAM4B,IAAK6R,WAAW,KAAQe,GAAAd,2BAbtCc,MADNb,EAAc,6BACRa,8NCC8ChC,EAA9ClS,uEAY+E,+BACE,GAEpFA,gBACW8L;kEACmDzH,KAAK+P;6CAC1B/P,KAAKgQ;gBAClCC,EAAOjQ,KAAK2B,yBAA0BuO,GAASA,EAAKzO,mBAAmByO,GAChEzI;mCACYyI,EAAKzO;uCACDzB,KAAKgQ,6BAA+BE,EAAKzO;sBAC1DyO,EAAKzO,sBAAsByO,EAAK5R;;;UAOlD3C,uBAAuBsJ,QACd+K,2BAA8B/K,EAAMwK,cAAoCzT,WACxE0T,cAAc,IAAIC,YAAiC,sBAAuB,CAC3EC,OAAQ,CACJzR,YAAa6B,KAAK2B,wBAAwBC,SAAasO,EAAKzO,mBAAqBzB,KAAKgQ,iCAKlGrU,0BACU0S,oBAIV1S,6BACU2S,yBA7CP6B,GAGI3B,OAAS,CACZC,IAAMC,EAAUC,KAChBF;;;;WAOsBG,IAAzBC,EAAS,CAACxT,KAAMyU,UAASK,GAAApB,0CACiBH,IAA1CC,EAAS,CAACxT,KAAM8T,MAAOL,WAAW,KAAQqB,GAAApB,uCAbxCoB,OADNnB,EAAc,6BACRmB,ICJP,MAAMC,GAAsC,CACxCC,EAAG,WAAYC,EAAG,QAASC,EAAG,QAASC,EAAG,WAC1CC,EAAG,QAASC,EAAG,WAAYC,EAAG,UAE5BC,GAAqC,CACvCP,EAAG,UAAWC,EAAG,UAAWC,EAAG,OAAQC,EAAG,QAASC,EAAG,MAAOC,EAAG,OAChEC,EAAG,UAAWE,EAAG,OAAQC,EAAG,YAAaC,EAAG,UAAWC,GAAI,WAAYC,GAAI,YAyB3C3V,OAAOuI,QAToD,CAC3FqN,MAAS,CAAEC,MAAO,EAAGC,UAAW,MAChCC,MAAS,CAAEF,MAAO,EAAGC,UAAW,MAChCE,SAAY,CAAEH,MAAO,EAAGC,UAAW,MACnCG,MAAS,CAAEJ,MAAO,EAAGC,UAAW,MAChCI,SAAY,CAAEL,MAAO,EAAGC,UAAW,MACnCK,OAAU,CAAEN,MAAO,EAAGC,UAAW,MACjCM,SAAY,CAAEP,MAAO,EAAGC,UAAW,QAEmCpN,QAAO,CAAC2N,GAAWC,EAASC,QACzFA,EAAKV,OAASS,EAChBD,IACRxC,MAAM,GAAG2C,KAAK,gCAMUC,OACfA,eAIE9G,EAAK+G,KAAKC,MAAMF,UACdG,MAAMjH,QAAK,EAAU,IAAI+G,KAAK/G,6BAGTkH,SACtB,iBACD/B,GAAa+B,EAAKC,aAAaD,EAAKE,aAAazB,GAAWuB,EAAKG,8BAC/DlU,EAAQmU,QAAQJ,EAAKK,WAAY,EAAG,QAAQpU,EAAQmU,QAAQJ,EAAKM,aAAc,EAAG,wCAIhEV,SACpBI,EAAOO,GAAMC,SAASZ,UACrBI,EAAKO,GAAME,mBAAmBT,QAAM,+BAGXU,SAC1BV,EAAOnS,KAAK2S,SAASE,GACrBC,EAAkBX,EAAKO,GAAMI,gBAAgBX,QAAM,SAClDW,EAAgBJ,GAAMK,eAAeD,QAAiB,yBAGnCX,UACnBO,GAAMM,gBAAgBb,EAAM,IAAIH,6BAGbiB,EAAaC,SACjCC,EAAc/O,KAAKgP,IAAIH,EAAMI,UAAYH,EAAMG,WAC/CC,EAASH,EAAc,IAEvBI,KAA0BD,GAAQ,IAAM,GAExCE,KAA0BF,EAAiB,IAARC,OAAyB,GAE5DE,KAAwBH,EAAiB,IAARC,EAAuB,GAARC,EAAW,UAAoB,SAE9E,CAAEE,QADoBJ,EAAiB,IAARC,EAAuB,GAARC,EAAW,IAAa,GAANC,EAAS,GAAG,WACpEE,cAHmBL,EAAiB,IAARC,EAAuB,GAARC,EAAW,UAG1CC,MAAAA,EAAOG,gBALEN,EAAiB,IAARC,OAKGC,QAAAA,EAASK,gBAPrBP,GAAS,IAO0BC,QAAAA,EAASJ,YAAAA,EAAaG,OAAAA,oBAGxEtX,EAAe8X,EAAcvX,EAAqB,IAAKwX,GAAsB,UAChF,IAAV/X,EAAY,GAAGA,EAAM8X,KAAiB,GAAG1V,EAAQ4V,OAAOhY,EAAOO,0BAG9CuW,UACY,IAAjCA,EAAgBc,aACT,oBAC8B,IAA/Bd,EAAgBa,WACf,GAAGjB,GAAMuB,UAAUnB,EAAgBU,QAAS,aAC7CV,EAAgBa,YAAc,EAC7B,GAAGjB,GAAMuB,UAAUnB,EAAgBW,MAAO,aAAaf,GAAMuB,UAAUnB,EAAgBU,QAAS,aACxE,IAAzBV,EAAgBY,KACf,GAAGhB,GAAMuB,UAAUnB,EAAgBW,MAAO,YAC3CX,EAAgBY,KAAO,EACtB,GAAGhB,GAAMuB,UAAUnB,EAAgBY,KAAM,YAAYhB,GAAMuB,UAAUnB,EAAgBW,MAAO,YAE5F,GAAGf,GAAMuB,UAAUnB,EAAgBY,KAAM,sOC9EX7F,EAc7ClS,oDAH8F,eAO9FA,kBACS+T,cAAc,IAAIC,YAA+B,oBAAqB,CACvEC,OAAQ,CAAExK,KAAMpF,KAAKoF,SAI7BzJ,mBACS+T,cAAc,IAAIC,YAA+B,2BAA4B,CAC9EC,OAAQ,CAAExK,KAAMpF,KAAKoF,SAI7BzJ,eACc4J,EAAmClI,EAAY2C,KAAKoF,KAAKG,gBAC3D2O,EAOAC,EANAnU,KAAKoF,KAAK8O,UAAYlU,KAAKoF,KAAK8O,UAAY,KACnClU,KAAKoF,KAAK8O,SAASE,QAAQ,GAC7BpU,KAAKoF,KAAK8O,aACRlU,KAAKoF,KAAK8O,SAASE,QAAQ,QAIpCC,EAAWhO,EAAerG,KAAKoF,SACnB,yBAAbiP,GAAoD,2BAAbA,EAAuC,KACzEC,IACY,2BAAbD,EACsB,CACjBE,YAAY,EACZC,mBAAoB,oBACpBC,cAAe,oCACfC,WAAY,WACZC,QAAS,IAAM3U,KAAK4U,cACpBC,kBAAmBpN;;6BAElB,CAAC,WAAY,uBAAuB9K,QAAQqD,KAAK8U,0BAAgCrN;2DAC/CsN,EAAS,CAACC,SAA0C,wBAAhChV,KAAK8U;8CACrCtH,SAAoByH,uBAAwBC,mBAAoBC;4BACnFnV,KAAKoV,SAAS3N;;;4BAGdA;;;;;wBAKJA;;2BAKiB,CACjB8M,YAAY,EACZC,mBAAoB,gBACpBC,cAAe,sBACfC,WAAY,cACZC,QAAS,IAAM3U,KAAKqV,aACpBR,uBAAmB,KAGd,CACTS,cAAc,EACdf,WAAYD,EAAmBC,WAC/BC,mBAAoBF,EAAmBE,mBACvCe,SAAWC,GACP/N,wBAA4B+F,MAAkCmH,YAAaO,sBAAyBM,QACxGC,QAAShO;4CACgB+F,GAAaA,EAAE0H;6CACfH,EAAS,CAAEW,cAA+C,gBAAhCpB,EAAmBI,WAA4BiB,WAA4C,aAAhCrB,EAAmBI;0BAC3HJ,EAAmBG;;wBAErBH,EAAmBO,mBAAqBpN;;;4BAGpCzH,KAAKoF,KAAKrG,kBAAkB6W,2BAA2BxX,EAAQ4V,OAAOhU,KAAKoF,KAAKrG,kBAAmB;;0BAErGiB,KAAKoF,KAAKG,WAAWkC;;;8BAGjBlC,EAAWkC;0DACiBlC,EAAW3H,mBAAmBkK,EAAO9F,6BAA6BuD,EAAW/H,qCAAqC+H,EAAW9H;8BACzJgK;8BACAzH,KAAKoF,KAAKG;;;0BAGdkC;;+BAIS,kBAAb4M,IACO,CACTiB,cAAc,EACdf,YAAY,EACZC,mBAAoB,6BACpBe,SAAWC,GAAY/N;yCACFzH,KAAKoF,KAAKpG,SAASW;8BAC9B6V;gCAEVC,QAAShO;yCACYzH,KAAKoF,KAAKpG,SAASW;yCACnBvB,EAAQyX,wBAAwB7V,KAAKoF,KAAKpG,SAASW;;mCAIzD,YAAb0U,QASA,IAAIzY,MAAM,0BAA0ByY,OAR7B,CACTiB,cAAc,EACdf,YAAY,EACZC,mBAAoB,oBACpBe,SAAWC,GAAYA,EACvBC,aAAS,UAMVtB,EAAWoB,SAAS9N;kDACWsN,EAAS,CAACe,UAAW3B,EAAWmB,aAAcS,cAAe5B,EAAWI;0BAChGJ,EAAWmB,aAAetV,KAAKoF,KAAKxK,IAAM;;;;;gCAKpCoF,KAAKoF,KAAK4Q,aAAatD,GAAMuD,gBAAgBjW,KAAKoF,KAAK4Q,cAAc7B,EAAWK;wDACxDN,EAAW,KAAKA,OAAgB;;;;;oEAKpBlU,KAAKoF,KAAK3H;;wCAEtCuC,KAAKoF,KAAKpG,SAASC;;;8IAGmFe,KAAKoF,KAAKpG,SAASW;;mDAE9GK,KAAKoF,KAAKpG,SAASW;iDACpB6N,MAAiB0I;0CACzB9X,EAAQyX,wBAAwB7V,KAAKoF,KAAKpG,SAASW;;;;;uDAKtCpB,EAAYyB,KAAKoF,KAAK/J;;uIAE0D2E,KAAKoF,KAAK5F;uDAC1FQ,KAAKoF,KAAK5F;;;;;0BAKvC2U,EAAWsB,QAAQhO;;4BAEjB0M,EAAWsB;;0BAEbhO;;;;eAOtB9L,0BACS+T,cAAc,IAAIC,YAAqC,oBAAqB,CAC7EC,OAAQ,CACJxK,KAAMpF,KAAKoF,KACX+Q,OAAQnW,KAAKoV,SAAS,cAAc,gBAKhDzZ,0BACU0S,oBAIV1S,6BACU2S,yBAlMP8H,GAGI5H,OAAS,CACZC,IAAMC,EAAUC,KAChBF,IAAMC,uiCACND;WAIwCG,IAA3CC,EAAS,CAACxT,KAAMC,OAAQwT,WAAW,KAAQsH,GAAArH,oBACAH,IAA3CC,EAAS,CAACxT,KAAMyU,OAAQhB,WAAW,KAAQsH,GAAArH,wCACCH,IAA5CC,EAAS,CAACxT,KAAMgb,QAASvH,WAAW,KAAQsH,GAAArH,wBAZ1CqH,OADNpH,EAAc,yBACRoH,yMCrBP,MAAME,GAAgE,CAClEC,aAAc,GACdC,iBAAkB,cAClBC,2BAA4B,+BAKqB5I,EAcjDlS,sCALkE,sBACC,iBAChB,6BAC0B,EAM7EA,gBACQqE,KAAK0W,UAKFjP;8BACesN,EAAS,CAAC4B,uBAAuB3W,KAAK4W;+BACrC5W,KAAK6W;;;;;mBANhB1c,MAAM,gEACPsN,KAaf9L,0BACU0S,yBAEDyI,UAAUrM,IAAI,UAChBzK,KAAK0W,WAAaJ,GAAuBtW,KAAK0W,iBACxCI,UAAUrM,IAAI6L,GAAuBtW,KAAK0W,YAG/C1W,KAAK+W,iBACAC,MAAMC,QAAU,QAI7Btb,6BACU2S,yBAhDP4I,GAGI1I,OAAS,CACZC,IAAMC,EAAUC,KAChBF;WAIyCG,IAA5CC,EAAS,CAACxT,KAAMgb,QAASvH,WAAW,KAAQoI,GAAAnI,yBACnBH,IAAzBC,EAAS,CAACxT,KAAMyU,UAASoH,GAAAnI,yBACAH,IAAzBC,EAAS,CAACxT,KAAMyU,UAASoH,GAAAnI,oBACmBH,IAA5CC,EAAS,CAACxT,KAAMgb,QAASvH,WAAW,KAAQoI,GAAAnI,oCAZ1CmI,OADNlI,EAAc,6BACRkI,8NCW0CrJ,EA0E7ClS,uDAhEuE,sBAE1B,6BACuB,iBACM,4CAGf,iCAUP,8BAES,cACxB,wCAEkB,0BAdYwb,GAC5DA,IAAOnX,KAAKoX,4BACNA,qBAAuBD,OACvBE,gCACAC,cAAc,4BACdA,cAAc,uDAG4BtX,KAAKoX,+CASjDpX,KAAKuX,eACLvX,KAAKV,QAILU,KAAKV,OAAOlD,QAAU,IACD,cAAdob,YAAyBxX,KAAKyX,gBACd,YAAnBzX,KAAKwX,yCAIZE,EAAsB1X,KAAK0X,uBAC5B1X,KAAK2X,wBAA0BD,SACvBA,EAAoB9V,SAAUY,EAAEjF,OAASyC,KAAK2X,yBAKnDhc,+BACEqE,KAAK4X,oBAAsB5X,KAAK4X,kBAAkBxb,OAGpDT,sBACCqE,KAAK6X,wBAGRlc,iCAGEmc,EAA0B1Z,EAAQ2Z,2BAA2B/X,KAAKV,aAEnEsY,kBAAoB5X,KAAK0X,oBAAoB1X,KAAK0X,oBAAoBpY,kBACjE0Y,EAA+B5Z,EAAQ2Z,2BAA2BjY,EAAQrC,YAEjB,IAAxDqC,EAAQ2C,WAAW9F,QAAQmb,SAC3BE,EAA6Brb,QAAQmb,MAC7CxY,QAAO,CAAC2Y,EAAG9G,IAAUA,EAAQ,UAAI,EAOxCxV,aAAasJ,WAEJ3F,OAAU2F,EAAMwK,cAAmCzT,MAMrDgE,KAAKkY,4BAAuF,IAAzDlY,KAAKV,OAAO3C,QAAQqD,KAAKkY,mCACtDA,gCAA6B,GAGnClY,KAAKV,QAAUU,KAAKmY,qBAAsB,CAQLnY,KAAKV,OAAO0D,MAAM,IAAIoV,MAAK,CAACH,EAAGI,SAC3DC,EAAgBtY,KAAKV,OAAOzC,UAAU,EAAGmD,KAAKV,OAAOlD,OAASic,SAC5DE,EAA0Bna,EAAQ2Z,2BAA2BO,WAChEtY,KAAKmY,qBAAsBjY,IAAIqY,KAC3BD,IAAkBtY,KAAKkY,gCACjBb,iCAEAa,2BAA6BI,OAC7B5I,cAAc,IAAIC,YAAmC,yBAA0B,CAChFC,OAAQ,CACJ5T,MAAOuc,QAIZ,aAQNb,oBAAsB,KAKvC/b,gBAAgBmE,QACPR,OAAS,GAAGQ,EAAQ2C,gBAAgB3C,EAAQrC,WAC5Cia,oBAAsB,QAEtBhI,cAAc,IAAIC,YAA6B,sBAAuB,CACvEC,OAAQ,CACJ9P,QAAAA,MAKZnE,+CAYe,UACF4b,cAAiBvX,KAAKwY,WAAYC,cAAc,WAAazY,KAAKwY,WAAYE,gBACpF,KAGP/c,gBACW8L;qCACsBsN,EAAS,CAAC4D,MAAS3Y,KAAK4Y,aAAcC,YAAe7Y,KAAKV,SAAWU,KAAK8Y;;+BAEhF,UAAavB,eAAgB;gCAC5BvX,KAAK+Y;6BACR/Y,KAAKgZ,yBAAyBhZ,KAAKV;gCAChCU,KAAKwX,2BAA2BxX,KAAK8Y,qBAAqB,uCAAwD,YAAjB9Y,KAAKwX,UAAsB,2BAA2B;;cAEzKxX,KAAKV,OAAOmI;0DACgC,UAAanI,OAAS,QAASkZ,WAAYC,cAAc,SAAUQ;cAC/GxR;cACAzH,KAAK8Y,qBAAqBrR,IAAOA;wDAC0B,YAAjBzH,KAAKwX,UAAsB/P,OAAUA;;cAE/EzH,KAAKkZ,4BAA4BzR;;;cAGjCA;cACAzH,KAAK4Y,aAAanR;;kBAEI,YAAjBzH,KAAKwX,WAAyBxX,KAAK6X,wBAAyBpQ;yEACN,UAAa+P,UAAU,YAAagB,WAAYC,cAAc,SAAUQ;kBAC/HxR;kBACAzH,KAAKmZ;;gBAEP1R;;UAKZ9L,yBACWsU,EAAOjQ,KAAK4X,mBAAqB,IAAKpV,GAAM,QAAQA,EAAEC,eAAeD,EAAE/E,QAAQ,CAACqC,EAASqR,IACrF1J,4CAA+C,IAAMzH,KAAKoZ,gBAAgBtZ,6BAAmCA,EAAQ2C,uBAAuB3C,EAAQrC,aAInK9B,0BACU0S,oBAEHrO,KAAK8Y,4BACCtB,UAAY,QAKzB7b,6BACU2S,uBAIV3S,YAAYmE,EAA8BuZ,QACjC/Z,OAAS,GAAGQ,EAAQA,EAAQ2C,WAAW,WAAW3C,EAAQA,EAAQrC,IAAI,aACtEya,2BAA6BmB,IA9MnCC,GAGI9K,OAAS,CACZC,IAAMC,EAAUC,KAChBF,IAAMC,q6FACND;WAIsBG,IAAzBC,EAAS,CAACxT,KAAMyU,UAASwJ,GAAAvK,sCAENH,IAAnB2K,KAAmBD,GAAAvK,6BACyBH,IAA5CC,EAAS,CAACxT,KAAMgb,QAASvH,WAAW,KAAQwK,GAAAvK,oCACDH,IAA3CC,EAAS,CAACxT,KAAMyU,OAAQhB,WAAW,KAAQwK,GAAAvK,yBAEDH,IAA1CC,EAAS,CAACxT,KAAM8T,MAAOL,WAAW,KAAQwK,GAAAvK,oCACvBH,IAAnB2K,KAAmBD,GAAAvK,2CAC2BH,IAA9CC,EAAS,CAACxT,KAAM8T,MAAOL,WAAW,KAAYwK,GAAAvK,mCAW3BH,IAAnB2K,KAAmBD,GAAAvK,iCACAH,IAAnB2K,KAAmBD,GAAAvK,sBA9BjBuK,OADNtK,EAAc,yBACRsK,yBAyNsDA,GAAtD3d,+DAOsE,6BAEQ,+BARV6d,QAC9DC,wBAA0BD,EAAK7Y,eAAciC,IAC9C8W,kCAAmCtb,EAAQ2Z,2BAA2BnV,EAAEnB,kBACxEkY,sBAAuBvb,EAAQ2Z,2BAA2BnV,EAAEtE,qBAOpE3C,uBAAuBmI,QACdxE,OAAS,GAAGwE,EAAIrC,sBAAsBqC,EAAIxF,uBAC1CoZ,oBAAsB,QACtBkC,qBAAuB,QAEvBlK,cAAc,IAAIC,YAAiC,0BAA2B,CAC/EC,OAAQ,CACJzR,YAAa2F,MAKzBnI,aAAasJ,SACH+T,aAAa/T,QAEd4U,+BAGCle,sBACCqE,KAAK6X,0BAA4B7X,KAAK4Z,qBAAqBxd,OAG9DT,qCACEmc,EAA0B1Z,EAAQ2Z,2BAA2B/X,KAAKV,aAEnEsa,qBAAuB5Z,KAAKyZ,wBAAwBna,WAC6B,IAA3EwE,EAAI4V,kCAAkC/c,QAAQmb,SAC9ChU,EAAI6V,sBAAsBhd,QAAQmb,KAIjDnc,yBACW8L;cACDwI,EAAOjQ,KAAK4Z,sBAAwB,IAAKhX,GAAM,QAAQA,EAAEnB,qBAAqBmB,EAAEtE,oBAAoB,CAACwF,EAAKqN,IACjG1J,4CAA+C,IAAMzH,KAAK+P,uBAAuBjM,qCAAuCA,EAAIrC,6BAA6BqC,EAAIxF;cAEtKwb,MAAMX;UAIhBxd,gBAAgBwC,QACPmB,OAAS,GAAGnB,EAAYA,EAAYsD,iBAAiB,WAAWtD,EAAYA,EAAYG,gBAAgB,UAnDlEsQ,IAA9CC,EAAS,CAACxT,KAAM8T,MAAOL,WAAW,KAAYiL,GAAAhL,uCAM3BH,IAAnB2K,KAAmBQ,GAAAhL,uCAEuBH,IAA1CC,EAAS,CAACxT,KAAM8T,MAAOL,WAAW,KAAQiL,GAAAhL,oCATxCgL,OADN/K,EAAc,wCACR+K,8NCrOmClM,EAiBtClS,wDALsE,uBAEf,gBACQ,GAM/DA,gBACW8L;kEACmDzH,KAAKga;gBACvDha,KAAKia,wBAAwBxS;4CACwB,KAAzBzH,KAAKka,6BAAoCla,KAAKia;gBAC1ExS;gBACAwI,EAAOjQ,KAAKma,YAAmBC,EAAO7c,UAAgBkK;uCAC/B2S,EAAO7c,oBAAoByC,KAAKka,kBAAoBE,EAAO7c,SAAS6c,EAAOjd;;;UAM9GxB,mBAAmBsJ,QACViV,gBAAmBjV,EAAMwK,cAAoCzT,WAC7D0T,cAAc,IAAIC,YAAuC,UAAY,CACtEC,OAAQ,CACJ5T,MAAiC,KAAzBgE,KAAKka,qBAAwB,EAAUla,KAAKma,QAAQvY,SAAUyY,EAAE9c,OAASyC,KAAKka,kBAAkB3c,SAKpH5B,0BACU0S,oBAIV1S,6BACU2S,yBAjDPgM,GAGI9L,OAAS,CACZC,IAAMC,EAAUC,KAChBF;;;;WAOsBG,IAAzBC,EAAS,CAACxT,KAAMyU,UAASwK,GAAAvL,uCAEAH,IAAzBC,EAAS,CAACxT,KAAMyU,UAASwK,GAAAvL,+BACiBH,IAA1CC,EAAS,CAACxT,KAAM8T,MAAOL,WAAW,KAAQwL,GAAAvL,uBAfxCuL,OADNtL,EAAc,iBACRsL,8NCEuCzM,EAgB1ClS,2CAHuD,gBACQ,GAM/DA,gBACW8L;;gBAECwI,EAAOjQ,KAAKma,YAAmBC,EAAO7c,UAAgBkK;;wCAE9BsN,EAAS,CAAEwF,OAAUH,EAAO7c,OAAOyC,KAAKka;kCAC9C,IAAMla,KAAKga,mBAAmBI,EAAO7c;oBACnD6c,EAAOjd;;;;UAOvBxB,mBAAmBue,QACVA,gBAAkBA,OAClBxK,cAAc,IAAIC,YAAuC,UAAY,CACtEC,OAAQ,CACJ5T,MAAiC,KAAzBgE,KAAKka,qBAAwB,EAAUA,MAK3Dve,0BACU0S,oBAIV1S,6BACU2S,yBAjDPkM,GAGIhM,OAAS,CACZC,IAAMC,EAAUC,KAChBF,IAAMC,ipBACND;;;;WAOsBG,IAAzBC,EAAS,CAACxT,KAAMyU,UAAS0K,GAAAzL,+BACiBH,IAA1CC,EAAS,CAACxT,KAAM8T,MAAOL,WAAW,KAAQ0L,GAAAzL,uBAdxCyL,OADNxL,EAAc,sBACRwL,8NCM0B3M,EAA1BlS,iEAasF,oCACP,gCACI,sBACV,+BAEjB,gCACX,kCACO,EAEvDA,mBACOqE,KAAKya,oCACGC,oCAAoC1a,KAAKya,sBAAsBhZ,iBAAkBvD,EAA4B8B,KAAKya,8BAIvHtc,EAAc6B,KAAK2B,wBAAwB3B,KAAK2B,wBAAwBC,SAAYkC,EAAIrC,mBAAqBzB,KAAK2a,mBAAoB/a,uBAAiB,EACzJzB,IAKGyc,gCACH,WACAzc,EAAYsD,iBACZvD,EAA4BC,GAC5B6B,KAAK2a,mBAAoBpd,KAAMyC,KAAK2a,mBAAoBlY,WACxD5C,EAAwBG,KAAK2a,6BATrBxgB,MAAM,wCAAwC6F,KAAK2a,mBAAoB/a,sDAapDqF,QAC1BiU,6BAA8B,OAC9BxB,0BAA4BhT,EAAMC,QAAQpB,yBAAyBuE,EAAO9F,SAAUiD,EAAM2K,OAAO5T,YACjGkd,6BAA8B,OAC9B5B,cAAc,uBAGvB3b,gBAAgBmE,QACP6a,mBAAqB7a,OACrB+a,gBAGTlf,oBAAoBwC,QACXsc,sBAAwBtc,OACxB0c,gBAGTlf,gBACW8L;;;;;;;;;;;;;6DAa8CzH,KAAK8a;0DACP7V,GAAwCjF,KAAKoZ,gBAAgBnU,EAAM2K,OAAO9P;8DACtEmF,GAA4CjF,KAAK+a,oBAAoB9V,EAAM2K,OAAOzR;8DACnF6B,KAAK2B;2DACR3B,KAAKgb;0DACNhb,KAAK0X;kEACG1X,KAAKkZ;;;;;;;;;;;;oBAYnD5d,OAAOgU,OAAOjS,GAAaiC,WAAY2b,EAAEvd,WAAUiD,QAC1C8G;;uDAE0BlC,EAAW3H,mBAAmBkK,EAAO9F,6BAA6BuD,EAAW/H,sCAAsC+H,EAAW9H;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+CA0CtIqK,EAAO9F;;;;;;;;;;;;;;uDAcChC,KAAK2D,UAAU3D,KAAK2D,UAAUO,OAAOI,YAAYsR,iBAAiB;;;;;uDAKlE5V,KAAK2D,UAAU3D,KAAK2D,UAAUO,OAAOK,MAAMqR,iBAAiB;;;;;uDAK5D5V,KAAK2D,UAAU3D,KAAK2D,UAAUO,OAAOgX,SAAStF,iBAAiB;;;;;;;;;;;;0CAgBxGvH,0BAEE1M,EAAyBgC,EAAWzB,SAAwBrH,QAAQ8N,IAAI,CAC5EjE,EAAMC,QAAQhD,0BACd+C,EAAMC,QAAQwW,aACdzW,EAAMC,QAAQvB,4BAA4B0E,EAAO9F,iBAEhDL,wBAA0BA,OAC1BgC,UAAYA,OACZqX,qBAAuB,IAAII,IAAIlZ,GAGxCvG,6BACU2S,yBA9LP+M,GAGI7M,OAAS,CACZC,IAAMC,EAAUC,KAChBF,IAAMC,0vEACND;;;;WAOuCG,IAA1CC,EAAS,CAACxT,KAAM8T,MAAOL,WAAW,KAAQuM,GAAAtM,oCACAH,IAA1CC,EAAS,CAACxT,KAAM8T,MAAOL,WAAW,KAAQuM,GAAAtM,2CACAH,IAA1CC,EAAS,CAACxT,KAAM8T,MAAOL,WAAW,KAAQuM,GAAAtM,mCACAH,IAA1CC,EAAS,CAACxT,KAAM8T,MAAOL,WAAW,KAAQuM,GAAAtM,yBAhBxCsM,OADNrM,EAAc,aACRqM,ICJP,YAAiBC,UACRA,QAAYC,GAAG,WCdXC,GAAuE,CAChFC,KAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,KAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,KAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,KAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,KAAM,CAAC,KAAK,KAAK,KAAK,MACtBC,KAAM,CAAC,KAAK,MACZC,KAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MACrCC,KAAM,CAAC,KAAK,KAAK,KAAK,MACtBC,KAAM,CAAC,KAAK,KAAK,MACjBjL,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,MAC3BC,GAAM,CAAC,KAAK,KAAK,KAAK,MACtBiL,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MACrCC,GAAM,CAAC,KAAK,KAAK,MACjBC,GAAM,CAAC,KAAK,KAAK,MACjBC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,MAC3BC,GAAM,CAAC,KAAK,KAAK,KAAK,MACtBC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MACrCC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,KAAM,CAAC,MACPC,KAAM,CAAC,MACPC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MACrCC,GAAM,CAAC,KAAK,KAAK,MACjBC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MACrCC,GAAM,CAAC,KAAK,KAAK,MACjBC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MACrCC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MACrCC,GAAM,CAAC,KAAK,MACZC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MACrCC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,GAAM,CAAC,KAAK,KAAK,KAAK,MACtBC,GAAM,CAAC,KAAK,KAAK,KAAK,MACtBC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,MAC3BC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MACrCC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,MAC3BC,GAAM,CAAC,KAAK,KAAK,KAAK,MACtBC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,MAC3BC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,MAC3BC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MACrCC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,MAC3BC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MACrCC,GAAM,CAAC,KAAK,KAAK,KAAK,MACtBC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,GAAM,CAAC,KAAK,KAAK,KAAK,MACtBC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,MAC3BC,GAAM,CAAC,KAAK,KAAK,KAAK,MACtBC,GAAM,CAAC,KAAK,KAAK,MACjBC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,GAAM,CAAC,KAAK,KAAK,KAAK,MACtBC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,GAAM,CAAC,KAAK,KAAK,MACjBC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,GAAM,CAAC,KAAK,KAAK,MACjBC,GAAM,CAAC,KAAK,KAAK,MACjBC,GAAM,CAAC,KAAK,MACZC,GAAM,CAAC,KAAK,KAAK,KAAK,MACtBC,GAAM,CAAC,KAAK,KAAK,KAAK,MACtBC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MACrCC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MACrCC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,GAAM,CAAC,KAAK,KAAK,KAAK,MACtBC,GAAM,CAAC,KAAK,MACZC,GAAM,CAAC,KAAK,KAAK,MACjBC,GAAM,CAAC,KAAK,KAAK,MACjBC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MAC1CC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,MAC3BC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,MAC3BC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,MAC3BC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,MAC3BC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,GAAM,CAAC,KAAK,KAAK,KAAK,MACtBC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,MAC3BC,GAAM,CAAC,KAAK,KAAK,KAAK,MACtBC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,MAC3BC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MAC1CC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,MAC3BC,GAAM,CAAC,KAAK,KAAK,KAAK,MACtBC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,MAChCC,GAAM,CAAC,KAAK,KAAK,KAAK,MACtBC,GAAM,CAAC,KAAK,KAAK,KAAK,MACtBC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,MAC3BC,GAAM,CAAC,KAAK,KAAK,KAAK,KAAK,MAC3BC,IAAO,GACPC,IAAO,GACPC,IAAO,GACPC,IAAO,GACPC,IAAO,aCjGChmB,eAGRA,6CACQimB,EAAyB7U,EAAkBlG,SAASgb,oBACpDtW,UAAUC,eACoB,uBAA3BoW,GAC2B,uBAA3BA,QAEI,kBAGmB,WAA3BA,QACQ,yBAGmB,YAA3BA,GAAmE,0BAA3BA,QAChC,iBAGL,IAAIhmB,MAAM,2EAtBGkmB,GAAAjb,SAAW,IAAIkb,YCDtCpmB,YAAoBqmB,gBAGpBrmB,OAAOqmB,eACEA,MAAQhiB,KAAKgiB,MAAMC,OAAOD,GACxBhiB,KAGXrE,IAAOumB,UACI,IAAIC,GAAgBniB,KAAKgiB,MAAMrhB,IAAIuhB,IAG9CvmB,OAAOymB,eACEJ,MAAQhiB,KAAKgiB,MAAM1iB,OAAO8iB,GACxBpiB,KAGXrE,KAAK0mB,eACIL,MAAM3gB,KAAKghB,GACTriB,KAGXrE,OAAO2mB,UACItiB,KAAKqB,MAAK,CAACkhB,EAAOC,IAAUF,EAAsBC,GAAI7gB,cAAc4gB,EAAsBE,MAGrG7mB,eACWqE,KAAKgiB,kBAGMA,UACX,IAAIG,GAAgBH,0NCWcnU,EAA1ClS,uEAUiF,iCAEK,oCACP,gCAEI,+BACF,yCAEkC,yBAC7C,4BACG,mBAEH,iCACqB,sDACnC,wCAEA,4CACG,mCAIvDqE,KAAKyiB,4BACGziB,KAAKyiB,4BAKTziB,KAAK0iB,6DAML1iB,KAAK2iB,4BAGhBhnB,2BAA2BmE,QAClB2iB,4BAA8B3iB,EAG7BnE,+BACHqE,KAAKgQ,4BAA8BhQ,KAAK2B,+BAChC3B,KAAK2B,wBAAwBC,SAAU5B,KAAKgQ,6BAA+BpN,EAAEnB,mBAMlF9F,+BACFqE,KAAK4iB,2BAGF5iB,KAAK4iB,oBAAoBrlB,KAG1B5B,qDAKDqE,KAAK6iB,4BAGH7iB,KAAK6iB,4BACP5c,iBACAjC,QAAO,CAACO,EAAOa,IAASb,EAAMa,EAAKrG,mBAAmB,GAJhD,qCAOoBqD,QAC1B8W,6BAA8B,OAC9BxB,0BAA4BhT,EAAMC,QAAQpB,yBAAyBuE,EAAO9F,SAAUI,QACpF8W,6BAA8B,OAC9B5B,cAAc,6CAGDxX,EAAkBgjB,MAChC9iB,KAAK4iB,2BAcN5iB,KAAK4iB,oBAAoBrlB,OAASuC,EAAQvC,MAAQyC,KAAKgQ,6BAA+BlQ,EAAQF,uBACxFoQ,2BAA6BlQ,EAAQF,qBACrCmjB,2BAA2BjjB,GAE7BgjB,QACME,8BAINnoB,QAAQC,gBAtBN2nB,4BAA8B3iB,QAE7B3B,EAAc6B,KAAK2B,wBAAwBC,SAAUgB,EAAEnB,mBAAqB3B,EAAQF,oBACnFgb,gCAAgC,WACnC9a,EAAQF,gBACR1B,EAA4BC,GAC5B2B,EAAQvC,KACRuC,EAAQ2C,WACR5C,EAAwBC,+BAiBV3B,EAA0B2kB,OAC7C9iB,KAAK4iB,2BAKLzkB,EAAYsD,mBAAqBzB,KAAKgQ,kCAChCA,2BAA6B7R,EAAYsD,iBAE3CqhB,QACME,8BAINnoB,QAAQC,YAZJ4f,oCAAoCvc,EAAYsD,iBAAkBvD,EAA4BC,IAe7GxC,eACU8E,EAAoBT,KAAK6iB,6BAA+B7iB,KAAK6iB,4BAA4B5c,iBAC3FjG,KAAK6iB,4BAA4B5c,iBAAiB3G,WAAYgH,EAAE2c,aAC/D,UAEExb;;;;;;;;yDAQ2CxC,GAA8CjF,KAAK8a,6BAA6B7V,EAAM2K,OAAO5T;sDAChGiJ,GAAwCjF,KAAKoZ,gBAAgBnU,EAAM2K,OAAO9P,SAAS;0DAC/EmF,GAA4CjF,KAAK+a,oBAAoB9V,EAAM2K,OAAOzR,aAAa;wDAClG6B,KAAKkjB;0DACHljB,KAAK2B;uDACR3B,KAAKgb;sDACNhb,KAAK0X;8DACG1X,KAAKkZ;;;;;kBAKjDlZ,KAAKmjB;;;;;cAKTnjB,KAAKojB,iBAAiB3b;;;;;cAKtBA;8DACgD4b,EAAS,CAACpM,QAAUjX,KAAKgQ,2BAA8B,QAAU;oBAC3GhQ,KAAKsjB,cAAc1N,2BAA2BxX,EAAQ4V,OAAOhU,KAAKsjB,cAAe,6BAA6BllB,EAAQ4V,OAAOhU,KAAKsjB;oBAClItjB,KAAKujB;;oBAEJvjB,KAAK6iB,6BAA+B7iB,KAAK6iB,4BAA4B7hB,kBACpEyG;;;0BAGIiL,GAAM8Q,sBAAsBxjB,KAAK6iB,4BAA6B7hB;0BAC9DhB,KAAKyjB,oBAAoBhc;oEACiB,UAAaic,oBAAqBD,qBAAsB;0BAClGhc;+BAEFA;;;;;sBAKFhH,EAAiBrE,OAASqL;;;;kCAIdhH,EAAiBrE,cAAcgC,EAAQ4V,OAAOvT,EAAiBrE,OAAQ;;;sBAGjFqL;;;;;;;;;;;;;;;sBAeFwI,EAAOjQ,KAAK6iB,4BAA4B7iB,KAAK6iB,4BAA4B5c,iBAAiB,OAAU,GAAGzD,EAAErE,gBAAgBqE,EAAE/E,QAAQ+E,EAAE+C,gBAAgB,CAACH,EAAM+L,IACnJ1J;mDACoB0J;qCACd/L;yDACoBpF,KAAK8U;yCACrB9U,KAAK2jB,cAAcve;kDACTH,GAAiCjF,KAAKqV,WAAWpQ,EAAM2K,OAAOxK;yDACvDH,GAAkCjF,KAAK4U,YAAY3P,EAAM2K,OAAOxK;kDACvEH,GAAuCjF,KAAK4jB,wBAAwB3e,EAAM2K,OAAOxK,KAAMH,EAAM2K,OAAOuG;;;;wCAQrH/Q,EAAkC+Q,aACtCpJ,EAAkBlG,SAASmG,iBACtCM,QAAS,OACVhD,EAAe,CACjBW,GAAI+G,KAAK6R,MACT1lB,YAAa6B,KAAK+P,uBAClBjQ,QAASE,KAAK4iB,oBACdxd,KAAAA,EACA0e,gBAAiBtf,OAAOlK,SAASypB,MAGvB,cAAX5N,SACO/K,EAAGvE,SAASmd,8BAA8B1Z,SAC1CuB,EAAUhF,SAASod,YAAY,CAAE3Z,UACjCtK,KAAKkkB,sBACM,gBAAX/N,UACA/K,EAAGvE,SAASsd,gCAAgC/e,SAC5CyG,EAAUhF,SAASud,gBAAgB,CAAE9Z,UACrCtK,KAAKkkB,uBAKvBvoB,4BAA4BuG,UACjBrH,QAAQC,8EAQTuT,0BAEAxT,QAAQ8N,IAAI,CACdjE,EAAMC,QAAQhD,0BACd+C,EAAMC,QAAQvB,4BAA4B0E,EAAO9F,YAClDG,MAAKmJ,OAAQ3J,EAAyBO,WAChCP,wBAA0BA,OAE1BqZ,qBAAuB,IAAII,IAAIlZ,SAC9BlC,KAAKqkB,4BAA4BrkB,KAAKgb,+BAG1Chb,KAAKskB,mCAELtkB,KAAKkkB,0BACNpP,yBAA2BgN,GAAajb,SAAS0d,8CACjDC,6BAA+BC,aAAYnZ,eACvCwJ,yBAA2BgN,GAAajb,SAAS0d,+CAChDvkB,KAAKkkB,uBACZ,WAEGlkB,KAAK0jB,oBAENgB,gCChUuB,SAASC,EAAmBC,KAAsBC,OAC9EC,GAAiB,SACdL,aAAYnZ,aACZwZ,UACS1a,KAAK,2EAII,QACXua,KAAWE,cAEA,KAEtBD,GDmTwCG,EAAqBzZ,aACrDtL,KAAKgQ,2BAA4B,OAC1BhP,EAAoBhB,KAAK6iB,4BAA4B7iB,KAAK6iB,4BAA4B7hB,uBAAkB,EACxGgkB,QAAkCtgB,EAAMC,QAAQsgB,UAAUjlB,KAAKgQ,4BAA4B,QAC5FyT,oBAAuBziB,IAAsBgkB,EAA0BhkB,wBAGtEhB,KAAKsX,mBAEhB,sCAIE4N,kBAAoB9Z,EAAGvE,SAAS+D,wBAGzCjP,cAAcyJ,WACDpF,KAAKklB,YAAYtjB,SAAUkJ,EAASqa,EAAE/f,KAAMA,KAGzDzJ,sCAEW,EAGXA,4BAA4BqU,SAEjB,2BAIJhQ,KAAKgQ,6BAA+BhQ,KAAKolB,wCAE/BhC,kBAAmB,QACjBiC,KAAqBC,SAAsCzqB,QAAQ8N,IAAI,CAC1EjE,EAAMC,QAAQsgB,UAAUjlB,KAAKgQ,+BAC1BhQ,KAAKulB,4BAA4BvlB,KAAKgQ,4BAA4BrP,QAAY+D,EAAMC,QAAQsgB,UAAU/U,OAGvG1P,EAAsB,CAAC6kB,GAAkBpD,OAAOqD,GAA8BthB,QAAO,CAACwhB,EAA2BC,MACnH1kB,iBAAkBykB,EAA0BzkB,iBAAiBkhB,OAAOwD,EAAoB1kB,kBACxFC,kBAAmBwkB,EAA0BxkB,kBAC7CP,iBAAkB+kB,EAA0B/kB,iBAAiBwhB,OAAOwD,EAAoBhlB,kBACxFI,mBAAoB2kB,EAA0B3kB,mBAAmBohB,OAAOwD,EAAoB5kB,uBAC5F,CACAE,iBAAkB,GAClBC,kBAAmBqkB,EAAiBrkB,kBACpCP,iBAAkB,GAClBI,mBAAoB,UAGnBgiB,4BAA8B7iB,KAAK0lB,4BAA4BllB,KAE1DqG,SAAS8e,uBACf3lB,KAAKgQ,2BACLhQ,KAAK4iB,oBACL5iB,KAAK6iB,0CAEJO,kBAAmB,YAGvBP,iCAA8B,EAI3ClnB,6BACU2S,qCAEQtO,KAAKwkB,8BAEhBxkB,KAAK0kB,gDACU1kB,KAAK0kB,sCACdA,qCAAkC,GAI/C/oB,sCAGW,WAGDA,kCACD+nB,eAEuC,WAAzC1jB,KAAK4lB,iCAIJ5lB,KAAKgQ,8BACE0K,oCAAoC1a,KAAKgQ,2BAA4B9R,EAA4B8B,KAAK+P,yBAI7GpU,WAAWyJ,GACZA,EAAKxK,OACMiM,SAASgf,YAAYzgB,KAE5B0gB,wBAAwB1gB,EAAKxK,KAGhCe,YAAYyJ,GACbA,EAAKxK,OACMiM,SAASkf,iBAAiB3gB,KAEjC0gB,wBAAwB1gB,EAAKxK,KAGxCe,yCACW8L,IAGD9L,qBAAqByJ,EAAkC4gB,MAClD,SAARA,EAAgB,KACXC,WACD7gB,EAAK1F,2BAA6B0F,EAAKpG,SAASW,aAC9B,EACXyF,EAAKxK,IACiC,IAA3BwK,EAAKrG,kBAA+C,OAApBqG,EAAK4Q,aAAqB,EAAE,EAAG,EAE/D,EAEd,GAAGiQ,MAAmB7nB,EAAQmU,QAAQP,KAAKC,MAAM7M,EAAK4Q,eAAkB,EAAG,GAAI,UACxE,aAARgQ,EAAoB,KACtBC,WAKD7gB,EAAK1F,2BAA6B0F,EAAKpG,SAASW,cAEzCyF,EAAKxK,KACiC,IAA3BwK,EAAKrG,kBAFL,EAIA,EAGd,GAAGknB,MAAmB7nB,EAAQmU,QAAQnO,KAAKC,MAAqB,IAAfe,EAAK8O,UAAiB,EAAG,aAE3E,IAAItY,MAAM,qBAAqBoqB,MA/Z1CE,GAGI1X,OAAS,CACZC,IAAMC,EAAUC,KAChBF,IAAMC,q/DACND;WAIsBG,IAAzBC,EAAS,CAACxT,KAAMyU,UAASoW,GAAAnX,0CAEiBH,IAA1CC,EAAS,CAACxT,KAAM8T,MAAOL,WAAW,KAAQoX,GAAAnX,oCACAH,IAA1CC,EAAS,CAACxT,KAAM8T,MAAOL,WAAW,KAAQoX,GAAAnX,2CAEAH,IAA1CC,EAAS,CAACxT,KAAM8T,MAAOL,WAAW,KAAQoX,GAAAnX,mCACAH,IAA1CC,EAAS,CAACxT,KAAM8T,MAAOL,WAAW,KAAQoX,GAAAnX,uCAEAH,IAA1CC,EAAS,CAACxT,KAAM8T,MAAOL,WAAW,KAAQoX,GAAAnX,2CACEH,IAA5CC,EAAS,CAACxT,KAAMgb,QAASvH,WAAW,KAAQoX,GAAAnX,gCACAH,IAA5CC,EAAS,CAACxT,KAAMgb,QAASvH,WAAW,KAAQoX,GAAAnX,mCAEFH,IAA1CC,EAAS,CAACxT,KAAM8T,MAAOL,WAAW,KAAQoX,GAAAnX,2BACCH,IAA3CC,EAAS,CAACxT,KAAMyU,OAAQhB,WAAW,KAAQoX,GAAAnX,6DAiZNmX,GAAnCvqB,mEACoE,kCACD,oBAER,WAE9DA,sCACYqE,KAAK4iB,oBAGjBjnB,4BAA4BqU,UACjBwL,GAAyBxL,GAG1BrU,gCACFinB,EAAsB5iB,KAAK4iB,2BAC5BA,GAAuB5iB,KAAK2B,wBACpB3B,KAAK2B,wBAAwBC,SAAUghB,EAAqBhjB,kBAAoBgD,EAAEnB,mBAGtFqY,MAAM6I,4BAGjBhnB,uCAEOqE,KAAK+P,wBAA0B/P,KAAK4iB,qBAAuB5iB,KAAKmmB,yBACxDvL,gCAAgC5a,KAAKyG,aAAczG,KAAK+P,uBAAuBtO,iBAAkBvD,EAA4B8B,KAAK+P,wBAAyB/P,KAAK4iB,oBAAoBrlB,KAAMyC,KAAK4iB,oBAAoBngB,WAAY5C,EAAwBG,KAAK4iB,sBAC5P,UAGJ,WAIXjnB,gCACW8L;;kCAEmBzH,KAAK4iB,oBAAoB,GAAG5iB,KAAK4iB,oBAAoBnlB,QAAQuC,KAAK4iB,oBAAoBngB,cAAc;;4CAKhGP,MAC3BlC,KAAKmmB,uBAAyBnmB,KAAK2X,uBAAwB,KACtDwO,EAAwBnmB,KAAKmmB,4BAC3BnmB,KAAKomB,oCAAoClkB,EAAeikB,8CAIpBjkB,EAA4BikB,SACpE9M,EAAyBrZ,KAAKqmB,0BAA0BnkB,EAAeikB,OACxE9M,iBACOlf,MAAM,+CAA+CgsB,KACtDjkB,QAGLlC,KAAKsmB,6CAA6CjN,SAElDuJ,EAAsB5iB,KAAK0iB,gCAC7BE,SACK2D,sBAAsB3D,EAAqBvJ,SAC1CrZ,KAAKoZ,gBAAgBwJ,GAAqB,IAG7C1gB,EAGHvG,0BAA0BuG,EAA4BikB,UACnDA,EAAsBnjB,MAAM,IAC9BrC,KAAI,CAACsX,EAAG9G,IAAUgV,EAAuBtpB,UAAU,EAAGsU,EAAQ,KAC9DvP,SAA4BM,EAAchC,IAAIsmB,wDAGInN,QAClDH,6BAA8B,OAC9BxB,0BAA4BhT,EAAMC,QAAQpB,yBAAyBuE,EAAO9F,SAAUqX,QACpFH,6BAA8B,EAG/Bvd,sBAAsBinB,EAA8BvJ,GACrCrZ,KAAKwY,WAAYC,cAAc,uCACxCgO,YAAY7D,EAAqBvJ,GAGrC1d,4BACFqE,KAAK2X,wBAA2B3X,KAAK0X,2BAGlC1X,KAAK0X,oBAAoB9V,SAAUY,EAAEjF,OAASyC,KAAK2X,wBAA0BnV,EAAEC,aAAezC,KAAKmmB,wBAG9GxqB,2BAA2BmE,SACjBijB,2BAA2BjjB,QAC5B6X,uBAAyB7X,EAAQA,EAAQvC,UAAK,OAC9C4oB,sBAAwBrmB,EAAQA,EAAQ2C,gBAAW,EAG5D9G,4BAA4B6E,SAClBkmB,EAAU1mB,KAAK4iB,oBAAqB3f,UAAYjD,KAAK4iB,oBAAqB/f,UAC5E,CAACA,UAAU7C,KAAK4iB,oBAAqB/f,UAAWI,SAAUjD,KAAK4iB,oBAAqB3f,eAAU,EAC5F0jB,EAAeD,EAChBthB,GAAgBA,EAAK9K,mBJzjBgB2I,SAAU2jB,EAAM/jB,UAAWgkB,IAAuB5jB,SAAU6jB,EAAMjkB,UAAWkkB,QAEzHC,EAAOC,GAAQH,EAAKF,GACpBM,EAAOD,GAAQF,EAAKF,GACpB1B,EACF/gB,KAAK+iB,IAAIH,EAAK,GAAK5iB,KAAK+iB,IAAIH,EAAK,GACjC5iB,KAAKgjB,IAAIH,GAAQL,IAASxiB,KAAKgjB,IAAIH,GAAQH,IAC3C1iB,KAAK+iB,IAAID,EAAK,GAAK9iB,KAAK+iB,IAAID,EAAK,UAE3B,EAAI9iB,KAAKijB,MAAMjjB,KAAKkjB,KAAKnC,GAAI/gB,KAAKkjB,KAAK,EAAEnC,IARzC,KIwjBmCoC,CAAwBb,EAAQthB,EAAK9K,UAAYktB,EAAAA,EAChFpiB,OAEA3E,iBAAEA,qBAAkBI,GAAuB,CAC7CJ,iBAAkBD,EAAoBA,EAAoBC,iBAAiB,GAC3EI,mBAAoBL,EAAoBA,EAAoBK,mBAAmB,WAG5E/B,OACA0B,GADA,CAEHyF,iBAAkBkc,GAAa/S,KAAK,IAAI3O,GAAkBE,eAAc2F,IAAG2c,YAAY,OAClFhB,OAAO,IAAIphB,GAAoBF,eAAc2F,IAAG2c,YAAY,OAC5DtiB,eAAc2F,IAAG4N,SAAUyS,EAAargB,OACxChH,YAAagH,EAAE4N,UAAY5N,EAAE4N,SA5hBZ,MA6hBjBuT,WAAYznB,KAAK0nB,qBAAqBphB,EAAGtG,KAAKyG,gBAC9CkhB,UAIbhsB,kBAAkB+K,QACTD,aAAeC,IAEVG,SAAS+gB,0BAA0BlhB,QAExCsc,6BAGTrnB,yCACW8L;;;;;;;wCAOyBzH,KAAKyG;iCACZ0I,MAAMC,KAAKpS,EAAYsS,UAAU3O,UAAYpD,KAAMsqB,EAAG3qB,cAAeC,QAAS0qB,EAAG1qB;iCAChF8H,GAA8CjF,KAAK8nB,kBAAkB7iB,EAAM2K,OAAO5T;;;;YAzItF4S,IAAzBC,EAAS,CAACxT,KAAMyU,UAASiY,GAAAhZ,sCACAH,IAAzBC,EAAS,CAACxT,KAAMyU,UAASiY,GAAAhZ,qCAEAH,IAAzBC,EAAS,CAACxT,KAAMyU,UAASiY,GAAAhZ,4BAJvBgZ,OADN/Y,EAAc,wBACR+Y,yBAmJuC7B,yCAGnClmB,KAAKgQ,2BAA4B,OAC1BD,EAAyB/P,KAAK2B,wBAAwBC,SAAUgB,EAAEnB,mBAAqBzB,KAAKgQ,gCAC9FD,EAAwB,CACL/P,KAAKwY,WAAYC,cAAc,uCACxCuP,gBAAgBjY,SAEpB/P,KAAK+a,oBAAoBhL,GAAwB,KAKnEpU,gCACW8L;;kCAEmBzH,KAAK+P,uBAAuB,GAAG/P,KAAK+P,uBAAuBzR,oBAAoB0B,KAAK+P,uBAAuBtO,oBAAoB;;UAK7J9F,4BAA4B6E,SAClBC,iBAAEA,qBAAkBI,GAAuB,CAC7CJ,iBAAkBD,EAAoBA,EAAoBC,iBAAiB,GAC3EI,mBAAoBL,EAAoBA,EAAoBK,mBAAmB,WAG5E/B,OACA0B,GADA,CAEHyF,iBAAkBkc,GAAa/S,KAAK,IAAI3O,GAAkBE,eAAc2F,IAAG2c,YAAY,OAClFhB,OAAO,IAAIphB,GAAoBF,eAAc2F,IAAG2c,YAAY,OAC5DtiB,eAAc2F,IAAG4N,cAAU,MAC3BuT,WAAYznB,KAAK0nB,qBAAqBphB,EAAG,UACzCqhB,YAlCVM,OADNjZ,EAAc,4BACRiZ,yFEhlB2Bpa,EAe9BlS,gBACW8L;;;;;;UASX9L,0BACU0S,yBAEDiJ,gBAAgBnV,MAAK,IAAMnC,KAAKkoB,YAGjCvsB,gBACEwsB,EAAQxnB,MAAIX,KAAKwY,WAAYC,cAAc,WAA0B2P,QAAQ,CAAC,OAAQ,GAAI,SACtF,+EAGLjmB,SAAiBkmB,EAASC,gBAC1BnmB,gBAESomB,GADU,IAAIC,aACAC,OAAOC,GACrBC,EAAaC,GAAaC,WAAWN,EAAK,KAE1CO,EAAgBH,EAAWI,MAAM,EAAGJ,EAAWvsB,OAAO,GAAGuE,KAAI,CAAC3E,EAAiBoN,MACjFvG,UAAWE,OAAO/G,EAAM,KACxBiH,SAAUF,OAAO/G,EAAM,KACvByB,IAAKzB,EAAM,GACXgtB,YAAahtB,EAAM,IACnBitB,eAAgBjtB,EAAM,IACtBktB,QAASltB,EAAM,IACfmtB,UAAWntB,EAAM,IACjBotB,QAASptB,EAAM,GAAK,IAAMA,EAAM,GAAK,KAAOA,EAAM,GAAK,IAAMA,EAAM,GACnEqtB,IAAKrtB,EAAM,IAAI+sB,MAAM,EAAG,QAGtBO,EAAUV,GAAaW,WAAWT,KAClCU,SAASF,MAElB1gB,OAAM,mBAEKuD,IAAI,yBAGV,qDAAsD,CAC5Dsd,QAAS,GACTC,YAAa,4FACdC,MAAMxB,qBAOayB,EAAiBC,KAGvBA,GAAgB,QAG5BC,EAAa,IAAIC,OAGb,MAAQF,EAAe,iDAMXA,EAAe,aAE/B,MAMAG,EAAU,CAAC,IAIXC,EAAa,UAKVA,EAAaH,EAAWI,KAAMN,IAAU,KAoBvCO,EAjBAC,EAAsBH,EAAY,GAOlCG,EAAoBhuB,QACpBguB,IAAwBP,KAKhB7kB,KAAM,MASdilB,EAAY,GAIMA,EAAY,GAAIrtB,QAC9B,IAAImtB,OAAQ,KAAQ,KACpB,KAMcE,EAAY,KAOzBD,EAAQ5tB,OAAS,GAAI4I,KAAMmlB,UAIjCH,oBAGelB,UACNA,EAAM9kB,QAAO,CAACqmB,EAA6BjlB,EAAMgE,SACzDkhB,EAAkB,QACS,IAApBllB,EAAK4jB,YAC6B,IAArC5jB,EAAK4jB,YAAYrsB,QAAQ,YACP,YAAYyI,EAAK4jB,gBAAgB5jB,EAAK4jB,qBAG1C5jB,EAAK4jB,gBAGvBuB,EAAe,oDACkBnlB,EAAK3H,sEAEnB2H,EAAKgkB,mCAAmCkB,sEAE/BllB,EAAK8jB,YAAY9jB,EAAK8jB,gFAEtB9jB,EAAK6jB,wCAAwC7jB,EAAK+jB,yEAEvD/jB,EAAKikB,oBAE5BmB,EAAYC,SAAO,CAACrlB,EAAKvC,UAAWuC,EAAKnC,UAAW,CACpD4T,KAAM,IAAI6T,OAAKC,QAAQ,CAACC,UAAW,GAAG9iB,EAAO9F,iCAC9C6oB,UAAUN,YACHO,GAAG,SAAS,SAAStd,QAEtBud,iBAEDvB,SAASgB,GAEVH,IACR,IAAIW,qBAAmB,CAAEC,wBAAyB,KAIzDtvB,6BACU2S,yBAhMPsa,GAGIpa,OAAS,CACZC,IAAMC,EAAUC,KAChBF,IAAMC,w4mBACND,IAAMC,q+CACND;;;;;WAPDma,wIADN5Z,EAAc,cACR4Z,yFCrBkC/a,EAQrClS,sBAIAA,gBACW8L;;UAKX9L,0BACU0S,oBAIV1S,6BACU2S,yBAxBP4c,GAGI1c,OAAS,CACZC;WAJDyc,wIADNlc,EAAc,gBACRkc"}