{"version":3,"file":"places-autocomplete.umd.cjs","names":["#containerId","#pacEl","#googleMapsApiKey","#googleMapsApiVersion","#options","#defaultOptions","#defaultClasses","#onDataCallback","#onErrorCallback","#request","#defaultRequestParams","#debouncedMakeAcRequest","#inputElement","#cache","#ul","#ariaStatus","#fetchFields","#defaultFetchFields","#container","#kbdEscape","#kbdUp","#kbdDown","#allSuggestions","#currentSuggestion","#getSimilarity"],"sources":["../constants.js","../PlacesAutocomplete.js"],"sourcesContent":["export const ITINERARY_CATEGORIES = {\n  // --- TRANSPORT & AUTO ---\n  car_rental: \"Automotive\",\n  car_dealer: \"Automotive\",\n  gas_station: \"Automotive\",\n  electric_vehicle_charging_station: \"Automotive\",\n  parking: \"Automotive\",\n  airport: \"Airport\",\n  bus_station: \"Transport\",\n  train_station: \"Train Station\",\n  subway_station: \"Subway Station\",\n  taxi_stand: \"Transport\",\n  ferry_terminal: \"Transport\",\n\n  // --- DINING & NIGHTLIFE ---\n  restaurant: \"Food and Drink\",\n  cafe: \"Food and Drink\",\n  coffee_shop: \"Food and Drink\",\n  bar: \"Food and Drink\",\n  pub: \"Food and Drink\",\n  night_club: \"Food and Drink\",\n  bakery: \"Food and Drink\",\n  fast_food_restaurant: \"Food and Drink\",\n  ice_cream_shop: \"Food and Drink\",\n  pizza_restaurant: \"Food and Drink\",\n  steak_house: \"Food and Drink\",\n  sushi_restaurant: \"Food and Drink\",\n\n  // --- LODGING ---\n  hotel: \"Lodging\",\n  hostel: \"Lodging\",\n  motel: \"Lodging\",\n  resort_hotel: \"Lodging\",\n  bed_and_breakfast: \"Lodging\",\n  campground: \"Lodging\",\n  rv_park: \"Lodging\",\n  lodging: \"Lodging\",\n  cottage: \"Lodging\",\n  inn: \"Lodging\",\n  guest_house: \"Lodging\",\n\n  // --- SIGHTSEEING & CULTURE ---\n  tourist_attraction: \"Sightseeing\",\n  museum: \"Sightseeing\",\n  art_gallery: \"Sightseeing\",\n  cultural_landmark: \"Sightseeing\",\n  historical_landmark: \"Sightseeing\",\n  monument: \"Sightseeing\",\n  performing_arts_theater: \"Sightseeing\",\n  aquarium: \"Sightseeing\",\n  zoo: \"Sightseeing\",\n  visitor_center: \"Sightseeing\",\n  town_square: \"Sightseeing\",\n  landmark: \"Sightseeing\",\n  place_of_worship: \"Sightseeing\",\n\n  // --- RECREATION & PARKS ---\n  park: \"Recreation\",\n  national_park: \"Recreation\",\n  state_park: \"Recreation\",\n  beach: \"Recreation\",\n  hiking_area: \"Recreation\",\n  amusement_park: \"Recreation\",\n  water_park: \"Recreation\",\n  botanical_garden: \"Recreation\",\n  golf_course: \"Recreation\",\n  gym: \"Recreation\",\n  natural_feature: \"Recreation\",\n\n  // --- SHOPPING ---\n  shopping_mall: \"Shopping\",\n  supermarket: \"Shopping\",\n  grocery_store: \"Shopping\",\n  clothing_store: \"Shopping\",\n  electronics_store: \"Shopping\",\n  souvenir_shop: \"Shopping\",\n  gift_shop: \"Shopping\",\n  duty_free_store: \"Shopping\",\n\n  // --- ESSENTIAL SERVICES ---\n  hospital: \"Health\",\n  pharmacy: \"Health\",\n  atm: \"Finance\",\n  bank: \"Finance\",\n  post_office: \"Services\",\n  police: \"Services\",\n\n  // --- GEOGRAPHICAL ---\n  neighborhood: \"Geographical\",\n  sublocality: \"Geographical\",\n\n  // --- NAVIGATION ---\n  route: \"Navigation\",\n  street_address: \"Navigation\",\n  intersection: \"Navigation\",\n\n  // -- CITY --\n  locality: \"City\",\n  administrative_area_level_4: \"City\",\n  country: \"Country\",\n  administrative_area_level_1: \"City\",\n  administrative_area_level_2: \"City\",\n  administrative_area_level_3: \"City\",\n  administrative_area_level_5: \"City\",\n  sublocality_level_1: \"Neighborhood\",\n  sublocality_level_2: \"Neighborhood\",\n  sublocality_level_3: \"Neighborhood\",\n  sublocality_level_4: \"Neighborhood\",\n  sublocality_level_5: \"Neighborhood\",\n\n  // --- DEFAULT ---\n  default: \"Default\",\n};\n\nexport const ITINERARY_SVG_ICONS = {\n  Distance:\n    '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" style=\"display:inline-block\"; viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-route-icon lucide-route\"><circle cx=\"6\" cy=\"19\" r=\"3\"/><path d=\"M9 19h8.5a3.5 3.5 0 0 0 0-7h-11a3.5 3.5 0 0 1 0-7H15\"/><circle cx=\"18\" cy=\"5\" r=\"3\"/></svg>',\n\n  Automotive: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"  style=\"display:inline-block\"; viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 16 10s-1.3-1.4-2.2-2.3c-.5-.4-1.1-.7-1.8-.7H5c-.6 0-1.1.4-1.4.9l-1.4 2.9A3.7 3.7 0 0 0 2 12v4c0 .6.4 1 1 1h2\"/><circle cx=\"7\" cy=\"17\" r=\"2\"/><path d=\"M9 17h6\"/><circle cx=\"17\" cy=\"17\" r=\"2\"/></svg>`,\n\n  Transport: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"  style=\"display:inline-block\"; viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M17.8 19.2 16 11l3.5-3.5C21 6 21.5 4 21 3c-1-.5-3 0-4.5 1.5L13 8 4.8 6.2c-.5-.1-.9.1-1.1.5l-.3.5c-.2.5-.1 1 .3 1.3L9 12l-2 3H4l-1 1 3 2 2 3 1-1v-3l3-2 3.5 5.3c.3.4.8.5 1.3.3l.5-.2c.4-.3.6-.7.5-1.2z\"/></svg>`,\n\n  \"Food and Drink\": `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"  style=\"display:inline-block\"; viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 2v7c0 1.1.9 2 2 2h4a2 2 0 0 0 2-2V2\"/><path d=\"M7 2v20\"/><path d=\"M21 15V2v0a5 5 0 0 0-5 5v6c0 1.1.9 2 2 2h3Zm0 0v7\"/></svg>`,\n\n  Lodging: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"  style=\"display:inline-block\"; viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M2 4v16\"/><path d=\"M2 8h18a2 2 0 0 1 2 2v10\"/><path d=\"M2 17h20\"/><path d=\"M6 8v9\"/></svg>`,\n\n  Sightseeing: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"  style=\"display:inline-block\"; viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-binoculars-icon lucide-binoculars\"><path d=\"M10 10h4\"/><path d=\"M19 7V4a1 1 0 0 0-1-1h-2a1 1 0 0 0-1 1v3\"/><path d=\"M20 21a2 2 0 0 0 2-2v-3.851c0-1.39-2-2.962-2-4.829V8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v11a2 2 0 0 0 2 2z\"/><path d=\"M 22 16 L 2 16\"/><path d=\"M4 21a2 2 0 0 1-2-2v-3.851c0-1.39 2-2.962 2-4.829V8a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v11a2 2 0 0 1-2 2z\"/><path d=\"M9 7V4a1 1 0 0 0-1-1H6a1 1 0 0 0-1 1v3\"/></svg>`,\n\n  Recreation: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"  style=\"display:inline-block\"; viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-kayak-icon lucide-kayak\"><path d=\"M18 17a1 1 0 0 0-1 1v1a2 2 0 1 0 2-2z\"/><path d=\"M20.97 3.61a.45.45 0 0 0-.58-.58C10.2 6.6 6.6 10.2 3.03 20.39a.45.45 0 0 0 .58.58C13.8 17.4 17.4 13.8 20.97 3.61\"/><path d=\"m6.707 6.707 10.586 10.586\"/><path d=\"M7 5a2 2 0 1 0-2 2h1a1 1 0 0 0 1-1z\"/></svg>`,\n\n  Shopping: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"  style=\"display:inline-block\"; viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z\"/><path d=\"M3 6h18\"/><path d=\"M16 10a4 4 0 0 1-8 0\"/></svg>`,\n\n  Health: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"  style=\"display:inline-block\"; viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 7v4\"/><path d=\"M14 21v-3a2 2 0 0 0-4 0v3\"/><path d=\"M14 9h-4\"/><path d=\"M18 11h2a2 2 0 0 1 2 2v6a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-9a2 2 0 0 1 2-2h2\"/><path d=\"M18 21V5a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v16\"/></svg>`,\n\n  Finance: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"  style=\"display:inline-block\"; viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect width=\"20\" height=\"14\" x=\"2\" y=\"5\" rx=\"2\"/><line x1=\"2\" y1=\"10\" x2=\"22\" y2=\"10\"/></svg>`,\n\n  Geographical: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"  style=\"display:inline-block\"; viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m20 20-6-10.6c-.4-.7-1.5-.7-1.9 0L6 20\"/><path d=\"M7 16h10\"/><path d=\"M12 4a8 8 0 0 1 8 8v2a2 2 0 0 1-2 2h-1\"/><path d=\"M7 16H6a2 2 0 0 1-2-2v-2a8 8 0 0 1 8-8\"/></svg>`,\n\n  Navigation: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"  style=\"display:inline-block\"; viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-navigation-icon lucide-navigation\"><polygon points=\"3 11 22 2 13 21 11 13 3 11\"/></svg>`,\n\n  City: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"  style=\"display:inline-block\"; viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-building2-icon lucide-building-2\"><path d=\"M10 12h4\"/><path d=\"M10 8h4\"/><path d=\"M14 21v-3a2 2 0 0 0-4 0v3\"/><path d=\"M6 10H4a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-2\"/><path d=\"M6 21V5a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v16\"/></svg>`,\n\n  District: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"  style=\"display:inline-block\"; viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-land-plot-icon lucide-land-plot\"><path d=\"m12 8 6-3-6-3v10\"/><path d=\"m8 11.99-5.5 3.14a1 1 0 0 0 0 1.74l8.5 4.86a2 2 0 0 0 2 0l8.5-4.86a1 1 0 0 0 0-1.74L16 12\"/><path d=\"m6.49 12.85 11.02 6.3\"/><path d=\"M17.51 12.85 6.5 19.15\"/></svg>`,\n\n  Airport: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"  style=\"display:inline-block\"; viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-plane-icon lucide-plane\"><path d=\"M17.8 19.2 16 11l3.5-3.5C21 6 21.5 4 21 3c-1-.5-3 0-4.5 1.5L13 8 4.8 6.2c-.5-.1-.9.1-1.1.5l-.3.5c-.2.5-.1 1 .3 1.3L9 12l-2 3H4l-1 1 3 2 2 3 1-1v-3l3-2 3.5 5.3c.3.4.8.5 1.3.3l.5-.2c.4-.3.6-.7.5-1.2z\"/></svg>`,\n\n  \"Subway Station\": `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"  style=\"display:inline-block\"; viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-subway-icon lucide-subway\"><path d=\"M12 22a10 10 0 0 0 10-10V8l-5-5H7L2 8v4a10 10 0 0 0 10 10Z\"/><path d=\"M12 22V8\"/><path d=\"M7 13h10\"/><path d=\"M7 17h10\"/></svg>`,\n\n  \"Train Station\": `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\"  style=\"display:inline-block\"; viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-train-icon lucide-train\"><path d=\"M2 10h20\"/><path d=\"M2 10a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-5Z\"/><circle cx=\"7\" cy=\"15\" r=\"2\"/><circle cx=\"17\" cy=\"15\" r=\"2\"/></svg>`,\n\n  Default: `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" style=\"display:inline-block\";  viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z\"/><circle cx=\"12\" cy=\"10\" r=\"3\"/></svg>`,\n};\n","import \"./places-autocomplete.css\";\nimport { ITINERARY_CATEGORIES, ITINERARY_SVG_ICONS } from \"./constants.js\";\n\n/**\n * A flexible and customisable Places Autocomplete widget powered by the Google Maps Places API.\n *\n * Features:\n * - Dynamic Google Maps API loading\n * - Debounced input for optimized API requests\n * - Keyboard navigation (Arrow keys, Enter, Escape)\n * - Session token management for cost-effective API usage\n * - Customizable styling and behavior\n *\n * @author Alexander Pechkarev <alexpechkarev@gmail.com>\n * @license MIT\n */\nexport class PlacesAutocomplete {\n  // --- Private Properties (using # or _ prefix by convention) ---\n  #containerId; // Container ID where the autocomplete widget will be rendered.\n  #pacEl;\n  #googleMapsApiKey;\n  #googleMapsApiVersion;\n  #options;\n  #request;\n  #inputElement;\n  #container;\n  #ul;\n  #ariaStatus; // For screen reader announcements\n  #cache = new Map(); // Simple cache for suggestions\n  #kbdEscape;\n  #kbdUp;\n  #kbdDown;\n  #allSuggestions = [];\n  #currentSuggestion = -1;\n  #onDataCallback; // For user-provided data callback\n  #onErrorCallback; // For user-provided error callback\n  #debouncedMakeAcRequest; // Declare without initializing here\n  #defaultOptions = {\n    // Default options for the autocomplete widget.\n    autofocus: false, // Automatically focus the input on load.\n    autocomplete: \"off\", // HTML autocomplete attribute for the input.\n    placeholder: \"Start typing your address ...\", // Placeholder text for the input.\n    distance: false, // Show distance in suggestions (requires origin in request).\n    distance_units: \"km\", // Units for distance ('km' or 'miles').\n    label: \"\", // Optional label text above the input.\n    debounce: 100, // Debounce delay (ms) for API requests.\n    clear_input: false, // Clear input .\n    debug: false, // Enable debug mode (not implemented in this version).\n    response_type: \"json\", // Return format: 'json' for JSON object, 'place' for Google Maps Place instance.\n    show_place_type: false, // Display place type icons.\n    sort_by_distance: false, // Sort suggestions by distance (requires distance option enabled).\n  };\n  #defaultClasses = {\n    // CSS classes for various parts of the widget.\n    section: \"pac-section\", // Outer section container.\n    container: \"pac-container\", // Main container div.\n    icon_container: \"pac-icon-container\", // Container for the search icon.\n    icon: '<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"pac-w-5 pac-h-5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"11\" cy=\"11\" r=\"8\" /><path d=\"m21 21-4.3-4.3\" /></svg>', // SVG for the search icon.\n    input: \"pac-input\", // Input field.\n    kbd_container: \"pac-kbd-container\", // Container for keyboard hints.\n    kbd_escape: \"pac-kbd-escape\", // Escape key hint.\n    kbd_up: \"pac-kbd-up\", // Up arrow key hint.\n    kbd_down: \"pac-kbd-down\", // Down arrow key hint.\n    kbd_active: \"pac-kbd-active\", // Class for active keyboard hint.\n    ul: \"pac-ul\", // Suggestions list (ul).\n    li: \"pac-li\", // Suggestion item (li).\n    li_current: \"pac-li-current\", // Class for the currently selected suggestion item.\n    li_button: \"pac-li-button\", // Link element within a suggestion item.\n    li_button_current: \"pac-li-button-current\", // Class for the link in the currently selected suggestion item.\n    li_div_container: \"pac-li-div-container\", // Container div within the suggestion link.\n    li_div_p_container: \"pac-li-div-p-container\",\n    li_div_one: \"pac-li-div-one\", // First inner div (for place name).\n    li_div_one_p: \"pac-li-div-one-p\", // Paragraph for the place name.\n    map_icon_svg: \"pac-map-icon-svg\",\n    map_pin_icon:\n      '<path d=\"M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0\"/><circle cx=\"12\" cy=\"10\" r=\"3\"/>',\n    li_div_one_p_secondaryText: \"pac-li-div-one-p-secondaryText\",\n    li_div_two: \"pac-li-div-two\", // Second inner div (for distance).\n    li_div_two_p: \"pac-li-div-two-p\", // Paragraph for the distance.\n    li_div_two_p_place_type: \"pac-li-div-two-p-place_type\", // Container for place type display.\n    li_div_two_p_place_type_item: \"pac-li-div-two-p-place_type-item\", // Wrapper for individual options within the place type container.\n    li_div_two_p_place_type_icon: \"pac-li-div-two-p-place_type-icon\", // The place type icon element.\n    li_div_two_p_place_type_label: \"pac-li-div-two-p-place_type-label\", // The place type label text.\n    highlight: \"pac-highlight\", // Class for highlighting matched text in suggestions.\n  };\n  #defaultRequestParams = {\n    // Default parameters for the autocomplete request.\n    input: \"\", // Initial input value (empty).\n    includedRegionCodes: [\"GB\"], // Default region codes to include in suggestions.\n    language: \"en-gb\",\n    // region: \"GB\",\n  };\n  #fetchFields = [\"formattedAddress\", \"addressComponents\"];\n  #defaultFetchFields = [\"formattedAddress\", \"addressComponents\"]; // Fields to fetch for the selected place (can be extended).\n\n  /**\n   * Class constructor for PacAutocomplete.\n   * Initializes the autocomplete widget with the provided configuration.\n   * @param {Object} config - Configuration object for the autocomplete widget.\n   * @param {string} config.containerId - ID of the container element for the widget.\n   * @param {string} config.googleMapsApiKey - Google Maps API key.\n   * @param {string} [config.googleMapsApiVersion] - Version of the Google Maps API to use (default: \"weekly\").\n   * @param {Object} [config.options] - Additional options for the widget (e.g., classes, callbacks).\n   * @param {Object} [config.requestParams] - Parameters for the autocomplete request (e.g., input, region).\n   * @param {*} config\n   */\n  constructor(config) {\n    if (!config || !config.containerId || !config.googleMapsApiKey) {\n      throw new Error(\n        \"PacAutocomplete: Missing required configuration (containerId, googleMapsApiKey).\",\n      );\n    }\n\n    this.#containerId = config.containerId; // Store the configuration object\n    this.#pacEl = document.getElementById(config.containerId);\n    if (!this.#pacEl) {\n      throw new Error(\n        `PacAutocomplete: Container element with ID \"${config.containerId}\" not found.`,\n      );\n    }\n\n    this.#googleMapsApiKey = config.googleMapsApiKey;\n    this.#googleMapsApiVersion = config.googleMapsApiVersion || \"weekly\";\n\n    // Merge user options with defaults\n    this.#options = {\n      ...this.#defaultOptions, // Default options\n      ...config.options, // User-defined options override defaults\n    };\n    // Ensure classes are deeply merged if user provides partial classes\n    if (config.options && config.options.classes) {\n      this.#options.classes = {\n        ...this.#defaultClasses,\n        ...config.options.classes,\n      };\n    } else {\n      this.#options.classes = this.#defaultClasses; // Use default classes if none provided\n    }\n\n    if (this.#options.debug) {\n      console.log(\"___debug constructor options:\");\n      console.log(this.#options);\n    }\n\n    if (config.fetchFields && Array.isArray(config.fetchFields)) {\n      this._setFetchFields(config.fetchFields); // Set fetch fields from user config\n    }\n\n    // Set default response and error callbacks if not provided\n    this.#onDataCallback =\n      config.onResponse ||\n      ((place) => {\n        console.info(\"---------Default onResponse not provided---------\");\n        console.info(\"Selected Place:\", JSON.stringify(place, null, 2));\n      });\n    this.#onErrorCallback =\n      config.onError ||\n      ((error) => {\n        console.error(\"---------Default onError not provided---------\");\n        console.error(\"PAC Error:\", error);\n      });\n\n    if (config.requestParams && Object.keys(config.requestParams).length > 0) {\n      this.#request = {\n        ...this.#defaultRequestParams,\n        ...config.requestParams,\n      };\n    } else {\n      this.#request = { ...this.#defaultRequestParams }; // Use defaults if no requestParams provided\n    }\n\n    if (this.#options.debug) {\n      console.log(\"___debug constructor requestParams:\", this.#request);\n    }\n\n    this._initialiseDebouncedRequest(); // Initialize the debounced request function\n\n    this._init(); // Underscore prefix for internal initialization method\n  }\n\n  // --- Private Initialization Method ---\n  async _init() {\n    try {\n      // check if google maps api is already loaded\n      if (typeof google === \"undefined\" || !google.maps) {\n        // Load the Google Maps API dynamically\n        await this._loadGoogleMapsApi({\n          key: this.#googleMapsApiKey,\n          v: this.#googleMapsApiVersion,\n        });\n      }\n      this._createPACStructure();\n      await this._initializeAutocomplete();\n    } catch (error) {\n      this.#onErrorCallback(error);\n    }\n  }\n\n  /**\n   * Initializes the debounced request function for fetching autocomplete suggestions.\n   * This function is called on initialization and when options are updated.\n   *\n   * @private\n   */\n  _initialiseDebouncedRequest() {\n    this.#debouncedMakeAcRequest = this._debounce(async () => {\n      const query = this.#inputElement?.value;\n      if (!query) {\n        this._reset();\n        if (this.#inputElement)\n          this.#inputElement.setAttribute(\"aria-expanded\", \"false\");\n        return;\n      }\n\n      // Create a cache key that includes the origin if distance is enabled\n      // This prevents stale distance data when the user moves\n      const originPart =\n        this.#options.distance && this.#request.origin\n          ? `-${JSON.stringify(this.#request.origin)}`\n          : \"\";\n      const cacheKey = `${query}${originPart}`;\n\n      if (this.#cache.has(cacheKey)) {\n        await this._renderSuggestions(this.#cache.get(cacheKey));\n        return;\n      }\n\n      // Debug warning for missing origin\n      if (\n        this.#options.distance &&\n        !this.#request.origin &&\n        this.#options.debug\n      ) {\n        console.warn(\n          \"PlacesAutocomplete: 'distance' option is enabled but no 'origin' is provided in requestParams. Distances will be null.\",\n        );\n      }\n\n      this.#request.input = query;\n\n      try {\n        const { suggestions } =\n          // eslint-disable-next-line no-undef\n          await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions(\n            this.#request,\n          );\n\n        // Cache and display suggestions\n        if (suggestions && suggestions.length > 0) {\n          // Sort by distance if option enabled\n          if (this.#options.sort_by_distance && this.#options.distance) {\n            suggestions.sort((a, b) => {\n              const distA =\n                a.placePrediction?.distanceMeters ??\n                a.distanceMeters ??\n                Infinity;\n              const distB =\n                b.placePrediction?.distanceMeters ??\n                b.distanceMeters ??\n                Infinity;\n              return distA - distB;\n            });\n          }\n\n          this.#cache.set(cacheKey, suggestions);\n          await this._renderSuggestions(suggestions);\n        } else {\n          // No suggestions found\n          this._reset(); // Clear any old suggestions\n          this.#inputElement.setAttribute(\"aria-expanded\", \"false\");\n          this._announceStatus(\"No suggestions found.\");\n        }\n      } catch (error) {\n        this.#onErrorCallback(error);\n        this._reset();\n      }\n    }, this.#options.debounce); // Default debounce to 100ms if not set\n  }\n\n  /**\n   * Renders the suggestions list.\n   * @private\n   */\n  async _renderSuggestions(suggestions) {\n    const suggestionElements = await Promise.all(\n      this._createSuggestionElements(suggestions),\n    );\n    this.#ul.replaceChildren(...suggestionElements);\n    this.#ul.style.display = \"block\";\n    this.#inputElement.setAttribute(\"aria-expanded\", \"true\");\n    this._announceStatus(`${suggestions.length} suggestions found.`);\n  }\n\n  /**\n   * Announces a message to screen readers using aria-live.\n   * @private\n   */\n  _announceStatus(message) {\n    if (this.#ariaStatus) {\n      this.#ariaStatus.textContent = message;\n    }\n  }\n\n  /**\n   * Sets the fields to fetch for the selected place.\n   * @param {Array<string>} fields - The fields to fetch.\n   */\n  _setFetchFields(fields) {\n    if (Array.isArray(fields) && fields.length > 0) {\n      this.#fetchFields = [\n        ...new Set([...this.#defaultFetchFields, ...fields]),\n      ].filter((e) => e); // Ensure unique and non-empty fields\n    }\n  }\n\n  /**\n   * Creates a debounced version of a function.\n   *\n   * @private\n   * @param {Function} func - The function to debounce\n   * @param {number} wait - Delay in milliseconds\n   * @returns {Function} Debounced function\n   */\n  _debounce(func, wait) {\n    let timeout = null;\n    return function executedFunction(...args) {\n      const later = () => {\n        timeout = null;\n        func(...args); // Call original function\n      };\n      if (timeout !== null) {\n        clearTimeout(timeout); // Clear the previous timeout\n      }\n      timeout = setTimeout(later, wait ?? 100); // Set the new timeout\n    };\n  }\n  /**\n   * Formats a distance value from meters to the specified unit.\n   *\n   * @private\n   * @param {number|null|undefined} distance - Distance in meters\n   * @param {('km'|'miles')} units - Target unit for conversion\n   * @returns {string|null} Formatted distance string or null if invalid\n   */\n  _formatDistance(distance, units) {\n    if (!this.#options.distance) {\n      return null;\n    }\n\n    if (typeof distance !== \"number\") {\n      return null;\n    }\n    let value;\n    let unitLabel;\n    if (units === \"km\") {\n      value = (distance / 1000).toFixed(2);\n      unitLabel = \"km\";\n    } else {\n      // Default to miles if not 'km'\n      value = (distance / 1609.34).toFixed(2);\n      unitLabel = \"miles\";\n    }\n    // Avoid showing \".00\"\n    value = value.replace(/\\.00$/, \"\");\n    return `${value} ${unitLabel}`;\n  }\n\n  /**\n   * Dynamically loads the Google Maps JavaScript API using the importLibrary method.\n   * This is the standard approach recommended by Google.\n   * @see https://developers.google.com/maps/documentation/javascript/load-maps-js-api\n   * @param {object} g - Configuration object for the API loader (key, v, libraries, etc.).\n   */\n  async _loadGoogleMapsApi(g) {\n    var h, // Promise tracking API load\n      a, // Script element\n      k, // Loop variable for config keys\n      p = \"The Google Maps JavaScript API\", // Error message prefix\n      c = \"google\", // Global namespace\n      l = \"importLibrary\", // Loader function name\n      q = \"__ib__\", // Internal callback name\n      m = document, // Document reference\n      b = window; // Window reference\n    b = b[c] || (b[c] = {}); // Ensure google namespace exists\n    var d = b.maps || (b.maps = {}), // Ensure google.maps namespace exists\n      r = new Set(), // Set to track requested libraries\n      e = new URLSearchParams(), // URL parameters for the API script\n      u = () =>\n        // Function to initiate API loading (if not already started)\n        h ||\n        // eslint-disable-next-line no-async-promise-executor\n        (h = new Promise(async (f, n) => {\n          // Create script element (done async to potentially wait for nonce)\n          // await (a = m.createElement('script')); // Original Google code had await here, might not be needed\n          a = m.createElement(\"script\"); // Create script tag\n          e.set(\"libraries\", [...r].join(\",\")); // Add accumulated libraries\n          // Add other parameters from the config object 'g'\n          for (k in g)\n            e.set(\n              k.replace(/[A-Z]/g, (t) => \"_\" + t[0].toLowerCase()), // Convert camelCase to snake_case\n              g[k],\n            );\n          e.set(\"callback\", c + \".maps.\" + q); // Set the internal callback function name\n          a.src = `https://maps.${c}apis.com/maps/api/js?` + e; // Construct the API URL\n          d[q] = f; // Assign the promise resolver to the callback name on google.maps\n          // Error handling for script loading failure\n          a.onerror = () =>\n            (h = n(\n              new Error(\n                `${p} could not load. Check your API key and network connection.`,\n              ),\n            )); // Use onerror for load failures\n          // Nonce for Content Security Policy\n          a.nonce = m.querySelector(\"script[nonce]\")?.nonce || \"\";\n          m.head.append(a); // Append the script to the document head\n        }));\n    // Define or reuse the importLibrary function on google.maps\n    // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n    d[l]\n      ? console.warn(p + \" only loads once. Ignoring:\", g) // Warn if called again\n      : (d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n))); // The actual importLibrary implementation\n  }\n\n  // --- UI Creation ---\n  _createPACStructure() {\n    const section = document.createElement(\"section\");\n    section.className = this.#options.classes.section;\n\n    // Main container\n    this.#container = document.createElement(\"div\");\n    this.#container.className = this.#options.classes.container;\n    this.#container.setAttribute(\"id\", this.#containerId + \"-div\");\n    section.appendChild(this.#container);\n\n    // Live region for a11y status updates\n    this.#ariaStatus = document.createElement(\"div\");\n    this.#ariaStatus.setAttribute(\"aria-live\", \"polite\");\n    this.#ariaStatus.setAttribute(\"role\", \"status\");\n    this.#ariaStatus.className = \"pac-sr-only\"; // Screen reader only\n    this.#container.appendChild(this.#ariaStatus);\n\n    // Icon\n    const iconContainer = document.createElement(\"div\");\n    iconContainer.className = this.#options.classes.icon_container;\n    this.#container.appendChild(iconContainer);\n    const icon = document.createElement(\"div\");\n    icon.innerHTML = this.#options.classes.icon;\n    iconContainer.appendChild(icon.firstElementChild); // Append the actual SVG element\n\n    // Input field\n    this.#inputElement = document.createElement(\"input\");\n    this.#inputElement.id = this.#containerId + \"-input\"; // Assign ID for label association\n    this.#inputElement.type = \"text\";\n    this.#inputElement.name = \"search\"; // Consider making name configurable\n    this.#inputElement.placeholder = this.#options.placeholder;\n    this.#inputElement.autocomplete = this.#options.autocomplete;\n    this.#inputElement.className = this.#options.classes.input;\n    this.#inputElement.setAttribute(\"role\", \"combobox\");\n    this.#inputElement.setAttribute(\"aria-autocomplete\", \"list\");\n    this.#inputElement.setAttribute(\"aria-expanded\", \"false\"); // Will be updated dynamically\n    this.#inputElement.setAttribute(\"aria-controls\", \"pacSuggestions\"); // Links to the suggestions list\n    this.#inputElement.setAttribute(\"aria-activedescendant\", \"\"); // Will be updated dynamically\n\n    if (this.#options.autofocus) {\n      this.#inputElement.autofocus = true;\n    }\n    if (this.#options.label) {\n      const label = document.createElement(\"label\");\n      label.htmlFor = this.#inputElement.id; // Correctly link label to input by ID\n      label.textContent = this.#options.label;\n      // Add label classes if needed from opts.classes\n      section.prepend(label); // Append label before input or adjust structure\n    }\n    this.#container.appendChild(this.#inputElement);\n\n    // Keyboard hints container\n    const kbdContainer = document.createElement(\"div\");\n    kbdContainer.className = this.#options.classes.kbd_container;\n    this.#kbdEscape = document.createElement(\"kbd\");\n    this.#kbdEscape.className = this.#options.classes.kbd_escape;\n    this.#kbdEscape.textContent = \"Esc\";\n    kbdContainer.appendChild(this.#kbdEscape);\n    this.#kbdUp = document.createElement(\"kbd\");\n    this.#kbdUp.className = this.#options.classes.kbd_up;\n    this.#kbdUp.innerHTML = \"&#8593;\"; // Up arrow HTML entity\n    kbdContainer.appendChild(this.#kbdUp);\n    this.#kbdDown = document.createElement(\"kbd\");\n    this.#kbdDown.className = this.#options.classes.kbd_down;\n    this.#kbdDown.innerHTML = \"&#8595;\"; // Down arrow HTML entity\n    kbdContainer.appendChild(this.#kbdDown);\n    this.#container.appendChild(kbdContainer);\n\n    // Suggestions list (initially hidden)\n    this.#ul = document.createElement(\"ul\");\n    this.#ul.id = \"pacSuggestions\"; // Must match aria-controls\n    this.#ul.className = this.#options.classes.ul;\n    this.#ul.style.display = \"none\";\n    this.#ul.setAttribute(\"role\", \"listbox\");\n    this.#ul.setAttribute(\"aria-labelledby\", this.#inputElement.id); // Link listbox to input for accessibility\n    this.#container.appendChild(this.#ul);\n\n    // Event Delegation for suggestion selection\n    this.#ul.addEventListener(\"click\", (e) => {\n      // IMPORTANT - to prevent the click event from bubbling up to the input and causing it to form submission if the input is inside a form. This is a common issue when using buttons inside forms.\n      e.preventDefault();\n      const li = e.target.closest(\"li\");\n      if (li && this.#ul.contains(li)) {\n        const index = Array.from(this.#ul.children).indexOf(li);\n        if (index !== -1 && this.#allSuggestions[index]) {\n          this._onPlaceSelected(this.#allSuggestions[index].place);\n        }\n      }\n    });\n\n    this.#pacEl.appendChild(section);\n    section.addEventListener(\"keydown\", this._onKeyDown.bind(this)); // Bind 'this'\n  }\n\n  /**\n   * Attaches event listeners to the input element for handling user input.\n   * This includes debounced input handling, focus/blur events, and keyboard navigation.\n   */\n  _attachedEventListeners() {\n    this.#inputElement.addEventListener(\"input\", this.#debouncedMakeAcRequest);\n    // Add focus/blur listeners if needed to manage suggestion visibility\n    this.#inputElement.addEventListener(\"blur\", () => {\n      // Delay hiding suggestions to allow click events on them\n      setTimeout(() => {\n        if (this.#ul && !this.#ul.contains(document.activeElement)) {\n          // Check if focus moved outside suggestions\n          this.#ul.style.display = \"none\";\n          this.#inputElement.setAttribute(\"aria-expanded\", \"false\");\n        }\n      }, 200); // Adjust delay as needed\n    });\n    this.#inputElement.addEventListener(\"focus\", () => {\n      // Potentially show suggestions again if input has value\n      if (this.#inputElement.value && this.#allSuggestions.length > 0) {\n        this.#ul.style.display = \"block\";\n        this.#inputElement.setAttribute(\"aria-expanded\", \"true\");\n      }\n    });\n  }\n\n  _detachEventListeners() {\n    // Remove event listeners, remove elements from DOM\n    if (this.#inputElement) {\n      this.#inputElement.removeEventListener(\n        \"input\",\n        this.#debouncedMakeAcRequest,\n      );\n      // remove other listeners\n    }\n    if (this.#pacEl && this.#container) {\n      this.#pacEl.removeChild(this.#container.parentElement); // remove the whole section\n    }\n  }\n\n  /**\n   * Initializes the core autocomplete functionality after the API is loaded.\n   * Imports necessary libraries and sets up the input event listener.\n   */\n  async _initializeAutocomplete() {\n    try {\n      // Ensure the 'places' library is available via the dynamic loader\n      // eslint-disable-next-line no-undef\n      await google.maps.importLibrary(\"places\");\n      // console.log('Places library imported successfully.'); // For debugging\n\n      // Initial token generation\n      this._refreshToken();\n\n      // Attach the debounced request function to the input element's 'input' event\n      if (this.#inputElement) {\n        this._attachedEventListeners();\n      } else {\n        this.#onErrorCallback(\n          new Error(\"Input element not found during initialization.\"),\n        );\n      }\n    } catch (error) {\n      console.error(\"Error initializing Google Places Autocomplete:\", error);\n      // eslint-disable-next-line no-undef\n      this.#onErrorCallback(\n        new Error(\"Google Maps Places library not available.\"),\n      );\n    }\n  }\n\n  /**\n   * Resets the autocomplete input field, clears suggestions, and optionally refreshes the session token.\n   * @param {boolean} [refresh=false] - Whether to refresh the Google Places session token.\n   */\n  _reset(refresh = false, placeData = null) {\n    this.#currentSuggestion = -1;\n\n    /**\n     * If the input element exists and clear_input is false, set its value to the formatted address\n     * from placeData. Otherwise, clear the input value.\n     * This allows the user to keep the input value if they selected a place,\n     * but still allows clearing it if clear_input is true or placeData is not provided.\n     * @type {HTMLInputElement}\n     * @property {string} value - The value of the input element.\n     * @property {boolean} clear_input - Whether to clear the input value after selection.\n     * @property {Object} placeData - The data of the selected place, containing formattedAddress.\n     */\n    if (\n      this.#inputElement &&\n      this.#options.clear_input == false &&\n      placeData &&\n      placeData.formattedAddress\n    ) {\n      this.#inputElement.value = placeData.formattedAddress; // Set input value to formatted address\n    } else if (this.#inputElement) {\n      this.#inputElement.value = \"\";\n    }\n\n    if (this.#inputElement) {\n      this.#inputElement.setAttribute(\"aria-expanded\", \"false\");\n      this.#inputElement.setAttribute(\"aria-activedescendant\", \"\"); // Clear aria-activedescendant\n      this.#inputElement.blur();\n    }\n\n    this.#allSuggestions = [];\n    this.#currentSuggestion = -1;\n    if (this.#ul) {\n      this.#ul.innerHTML = \"\"; // Clear existing suggestions\n      this.#ul.style.display = \"none\";\n    }\n    if (refresh) {\n      this._refreshToken();\n    }\n  }\n  /**\n   * Removes the 'current' highlighting classes from all suggestion list items (li) and their links (a).\n   */\n  _resetLiClasses() {\n    if (!this.#ul) return;\n    Array.from(this.#ul.children).forEach((li) => {\n      this.#options.classes.li_current\n        .split(\" \")\n        .forEach((cl) => li.classList.remove(cl));\n      const link = li.querySelector(\"button\");\n      if (link) {\n        this.#options.classes.li_button_current\n          .split(\" \")\n          .forEach((cl) => link.classList.remove(cl));\n      }\n    });\n  }\n\n  /**\n   * Handles keyboard events (ArrowDown, ArrowUp, Enter, Escape) for navigating\n   * and selecting suggestions or closing the list.\n   * @param {KeyboardEvent} e - The keyboard event object.\n   */\n  _onKeyDown(e) {\n    this._resetLiClasses(); // Reset classes on any key press within the suggestions\n\n    if (e.key === \"Escape\") {\n      e.preventDefault();\n      // Visual feedback for key press\n      this.#options.classes.kbd_active\n        .split(\" \")\n        .forEach((cl) => this.#kbdEscape?.classList.add(cl));\n      setTimeout(\n        () =>\n          this.#options.classes.kbd_active\n            .split(\" \")\n            .forEach((cl) => this.#kbdEscape?.classList.remove(cl)),\n        300,\n      );\n\n      this._reset(true); // Reset search input and results, refresh token\n    }\n\n    if (\n      !this.#allSuggestions.length ||\n      !this.#ul ||\n      this.#ul.style.display === \"none\"\n    )\n      return;\n\n    if (e.key === \"ArrowDown\") {\n      e.preventDefault(); // Prevent cursor movement in input\n      this.#currentSuggestion = Math.min(\n        this.#currentSuggestion + 1,\n        this.#allSuggestions.length - 1,\n      );\n      this._highlightSuggestion();\n    } else if (e.key === \"ArrowUp\") {\n      e.preventDefault(); // Prevent cursor movement in input\n      this.#currentSuggestion = Math.max(this.#currentSuggestion - 1, 0); // Stay at 0 if already there\n      this._highlightSuggestion();\n    } else if (e.key === \"Home\") {\n      e.preventDefault();\n      this.#currentSuggestion = 0;\n      this._highlightSuggestion();\n    } else if (e.key === \"End\") {\n      e.preventDefault();\n      this.#currentSuggestion = this.#allSuggestions.length - 1;\n      this._highlightSuggestion();\n    } else if (e.key === \"Enter\") {\n      e.preventDefault(); // Prevent form submission if applicable\n      if (\n        this.#currentSuggestion >= 0 &&\n        this.#currentSuggestion < this.#allSuggestions.length\n      ) {\n        this._onPlaceSelected(\n          this.#allSuggestions[this.#currentSuggestion].place,\n        );\n        // Reset is handled within onPlaceSelected via reset(true)\n      }\n    }\n  }\n\n  /**\n   * Highlights the current suggestion in the UI.\n   * @private\n   */\n  _highlightSuggestion() {\n    if (this.#currentSuggestion < 0) return;\n\n    const currentLi = this.#ul.children.item(this.#currentSuggestion);\n    if (currentLi) {\n      const currentButton = currentLi.querySelector(\"button\");\n      this.#options.classes.li_current\n        .split(\" \")\n        .forEach((cl) => currentLi.classList.add(cl));\n      if (currentButton) {\n        this.#options.classes.li_button_current\n          .split(\" \")\n          .forEach((cl) => currentButton.classList.add(cl));\n      }\n      currentLi.scrollIntoView({ block: \"nearest\" }); // Ensure visible\n      this.#inputElement.setAttribute(\"aria-activedescendant\", currentLi.id); // Update aria-activedescendant\n\n      // Visual feedback for key press\n      const kbd = this.#currentSuggestion === 0 ? this.#kbdUp : this.#kbdDown;\n      this.#options.classes.kbd_active\n        .split(\" \")\n        .forEach((cl) => kbd?.classList.add(cl));\n      setTimeout(\n        () =>\n          this.#options.classes.kbd_active\n            .split(\" \")\n            .forEach((cl) => kbd?.classList.remove(cl)),\n        300,\n      );\n    }\n  }\n\n  // Helper function to find a specific address component\n  _getAddressComponent(response, type) {\n    return (\n      response.addressComponents?.find((c) => c.types.includes(type))\n        ?.longText || \"\"\n    );\n  }\n\n  /**\n   * Creates a button element for a suggestion item.\n   * @returns {HTMLButtonElement} The created button element.\n   */\n  _createButtonElement(index) {\n    const button = document.createElement(\"button\");\n    button.tabIndex = index + 1;\n    button.className = this.#options.classes.li_button; // block w-full flex justify-between\n    return button;\n  }\n\n  /**\n   * Creates a div container for suggestion item.\n   * @returns {HTMLDivElement} The created div container element.\n   */\n  _createDivElement(className) {\n    // create div elements pac-li-div-container\n    const divContainer = document.createElement(\"div\");\n    if (className) {\n      divContainer.className = className;\n    }\n    return divContainer;\n  }\n\n  /**\n   * Creates an SVG element representing a map pin icon.\n   * @returns {SVGSVGElement} The created SVG element.\n   */\n  _createMapPinIconElement() {\n    const svgIcon = document.createElementNS(\n      \"http://www.w3.org/2000/svg\",\n      \"svg\",\n    );\n    svgIcon.setAttribute(\"xmlns\", \"http://www.w3.org/2000/svg\");\n    svgIcon.setAttribute(\"width\", \"24\");\n    svgIcon.setAttribute(\"height\", \"24\");\n    svgIcon.setAttribute(\"viewBox\", \"0 0 24 24\");\n    svgIcon.setAttribute(\"fill\", \"none\");\n    svgIcon.setAttribute(\"stroke\", \"currentColor\");\n    svgIcon.setAttribute(\"stroke-width\", \"2\");\n    svgIcon.setAttribute(\"stroke-linecap\", \"round\");\n    svgIcon.setAttribute(\"stroke-linejoin\", \"round\");\n    svgIcon.setAttribute(\"class\", this.#options.classes.map_icon_svg);\n    // insert map pin icon path\n    svgIcon.innerHTML = this.#options.classes.map_pin_icon;\n    return svgIcon;\n  }\n\n  /**\n   * Creates a paragraph (P) element with an optional class name.\n   * @param {string} className\n   * @returns {HTMLParagraphElement}\n   */\n  _createPElement(className) {\n    const p = document.createElement(\"p\");\n    if (className) {\n      p.className = className;\n    }\n    return p;\n  }\n  /**\n   * Creates an array of list item (LI) elements for the suggestions dropdown.\n   * Each LI contains a link (A) with the place prediction details and distance.\n   * Handles highlighting the matched parts of the suggestion text.\n   * @param {Array<google.maps.places.AutocompleteSuggestion>} suggestions - Array of suggestion objects from the API.\n   * @returns {Array<HTMLLIElement>} An array of LI elements to be added to the suggestions UL.\n   */\n  _createSuggestionElements(suggestions) {\n    this.#allSuggestions = []; // Reset before populating\n    // Map suggestions to LI elements\n    return suggestions.map(async (suggestion, index) => {\n      // Fetch place details for each suggestion\n      let place = suggestion.placePrediction.toPlace();\n\n      const li = document.createElement(\"li\");\n      li.id = `option-${index + 1}`;\n      li.className = this.#options.classes.li;\n      li.setAttribute(\"role\", \"option\");\n\n      // create button element\n      const button = this._createButtonElement(index);\n\n      // create div elements pac-li-div-container\n      const divContainer = this._createDivElement(\n        this.#options.classes.li_div_container,\n      );\n\n      // create li div one element - place name\n      const liDivOne = this._createDivElement(this.#options.classes.li_div_one);\n      const liDivTwo = this._createDivElement(this.#options.classes.li_div_two);\n      // create map pin icon element\n      const mapPinIcon = this._createMapPinIconElement();\n      // append map pin icon to liDivOne\n      liDivOne.appendChild(mapPinIcon);\n\n      // create div p container\n      const divPContainer = this._createDivElement(\n        this.#options.classes.li_div_p_container,\n      );\n      // append div p container to liDivOne\n      liDivOne.appendChild(divPContainer);\n\n      // create p element - place name\n      const pOne = this._createPElement(this.#options.classes.li_div_one_p);\n      // create p element - secondary text\n      const pTwo = this._createPElement(\n        this.#options.classes.li_div_one_p_secondaryText,\n      );\n      // create p element - distance\n      // Try to get distanceMeters from placePrediction or directly from suggestion\n      const distanceMeters =\n        suggestion.placePrediction?.distanceMeters ?? suggestion.distanceMeters;\n      const distanceValue = this._formatDistance(\n        distanceMeters,\n        this.#options.distance_units ?? \"km\",\n      );\n\n      // append p element to div p container\n      divPContainer.appendChild(pOne);\n      divPContainer.appendChild(pTwo);\n\n      // Add place type display and/or distance if enabled\n      this._renderSuggestionMeta(liDivTwo, suggestion, distanceValue);\n\n      // append liDivOne to divContainer\n      divContainer.appendChild(liDivOne);\n      divContainer.appendChild(liDivTwo);\n      // append divContainer to button\n      button.appendChild(divContainer);\n      // append button to li\n      li.appendChild(button);\n\n      this._renderHighlightText(pOne, suggestion.placePrediction.mainText);\n\n      // set secondary text if available\n      const secondaryText =\n        suggestion.placePrediction?.secondaryText?.text ?? \"\";\n\n      if (secondaryText) {\n        pTwo.textContent = secondaryText;\n      }\n\n      this.#allSuggestions.push({\n        id: index + 1,\n        place: place,\n        mainText: suggestion.placePrediction.mainText.text,\n        secondaryText: secondaryText,\n        description: suggestion.placePrediction.toString(),\n      });\n\n      return li;\n    });\n  }\n\n  /**\n   * Renders meta information (place type, distance) for a suggestion.\n   * @private\n   */\n  _renderSuggestionMeta(container, suggestion, distanceValue) {\n    if (this.#options.show_place_type || this.#options.distance) {\n      const metaContainer = this._createDivElement(\n        this.#options.classes.li_div_two_p_place_type,\n      );\n\n      // Place Type display\n      if (\n        this.#options.show_place_type &&\n        Array.isArray(suggestion.placePrediction?.types) &&\n        suggestion.placePrediction.types.length > 0\n      ) {\n        const placeTypeWrapper = this._createDivElement(\n          this.#options.classes.li_div_two_p_place_type_item,\n        );\n\n        const placeTypeIcon = this._createPElement(\n          this.#options.classes.li_div_two_p_place_type_icon,\n        );\n\n        const placeTypeLabel = this._createPElement(\n          this.#options.classes.li_div_two_p_place_type_label,\n        );\n\n        // Look through the array until we find a type we actually recognize\n        const matchedType = suggestion.placePrediction.types.find(\n          (type) => typeof type === \"string\" && type in ITINERARY_CATEGORIES,\n        );\n\n        placeTypeLabel.textContent = matchedType\n          ? ITINERARY_CATEGORIES[matchedType]\n          : \"Default\";\n\n        placeTypeIcon.innerHTML =\n          ITINERARY_SVG_ICONS[placeTypeLabel.textContent] ||\n          ITINERARY_SVG_ICONS[\"Default\"];\n\n        placeTypeWrapper.appendChild(placeTypeIcon);\n        placeTypeWrapper.appendChild(placeTypeLabel);\n        metaContainer.appendChild(placeTypeWrapper);\n      }\n\n      // Distance display\n      if (this.#options.distance) {\n        const distanceWrapper = this._createDivElement(\n          this.#options.classes.li_div_two_p_place_type_item,\n        );\n\n        const distanceIcon = this._createPElement(\n          this.#options.classes.li_div_two_p_place_type_icon,\n        );\n        distanceIcon.innerHTML = ITINERARY_SVG_ICONS[\"Distance\"];\n\n        const pThree = this._createPElement(this.#options.classes.li_div_two_p);\n        pThree.textContent = distanceValue ?? \"-\";\n\n        distanceWrapper.appendChild(distanceIcon);\n        distanceWrapper.appendChild(pThree);\n        metaContainer.appendChild(distanceWrapper);\n      }\n\n      if (metaContainer.hasChildNodes()) {\n        container.appendChild(metaContainer);\n      }\n    }\n  }\n\n  /**\n   * Renders highlighted text for a suggestion.\n   * @private\n   */\n  _renderHighlightText(element, predictionText) {\n    const originalText = predictionText.text;\n    const matches = predictionText.matches;\n    let lastIndex = 0;\n\n    matches.sort((a, b) => a.startOffset - b.startOffset);\n\n    const outerSpan = document.createElement(\"span\");\n    const innerSpan = document.createElement(\"span\");\n    innerSpan.classList = this.#options.classes.highlight ?? \"font-bold\";\n\n    for (const match of matches) {\n      outerSpan.textContent += originalText.substring(\n        lastIndex,\n        match.startOffset,\n      );\n      if (match.startOffset > 0) {\n        const prevChar = originalText.charAt(match.startOffset - 1);\n        if (prevChar === \" \") {\n          innerSpan.textContent += \" \";\n        }\n      }\n      innerSpan.textContent += originalText.substring(\n        match.startOffset,\n        match.endOffset,\n      );\n      lastIndex = match.endOffset;\n    }\n\n    outerSpan.appendChild(innerSpan);\n    outerSpan.appendChild(\n      document.createTextNode(originalText.substring(lastIndex)),\n    );\n    element.appendChild(outerSpan);\n  }\n\n  /**\n   * Handles the selection of a place. Fetches required fields\n   * (displayName, formattedAddress, addressComponents) and calls the\n   * user-defined `onPacData` callback.\n   * @param {google.maps.places.Place} place - The selected Place object.\n   */\n  async _onPlaceSelected(place) {\n    let data = null;\n    try {\n      // Fetch necessary details for the selected place\n      await place.fetchFields({\n        fields: this.#fetchFields, //[\"displayName\", \"formattedAddress\", \"addressComponents\"], // Add more fields as needed\n      });\n      // Call the user-provided callback with the place data\n      // Handle response_type option\n      if (this.#options.response_type === \"place\") {\n        data = place; // Return the Place instance\n        this.#onDataCallback(place);\n      } else {\n        // eslint-disable-next-line no-undef\n        data = place.toJSON(); // Convert to plain JSON object (default)\n        this.#onDataCallback(data);\n      }\n    } catch (error) {\n      console.error(\"Error fetching place details:\", error);\n      // eslint-disable-next-line no-undef\n      this.#onErrorCallback(error);\n    } finally {\n      // Reset the input and suggestions regardless of success/error\n      this._reset(true, data); // Refresh token after selection\n    }\n  }\n\n  /**\n   * Creates a new Google Places Autocomplete Session Token.\n   * This should be called before starting a new series of autocomplete requests.\n   */\n  _refreshToken() {\n    try {\n      // eslint-disable-next-line no-undef\n      this.#request.sessionToken =\n        new google.maps.places.AutocompleteSessionToken();\n    } catch (error) {\n      console.error(\"Error creating session token:\", error);\n      // eslint-disable-next-line no-undef\n      this.#onErrorCallback(error);\n    }\n  }\n\n  /**\n   * Sets the fields to be fetched for the selected place.\n   * This allows you to specify which details you want to retrieve\n   * when a place is selected, such as displayName, formattedAddress,\n   * addressComponents, etc.\n   * @param {Array<string>} fields - Array of field names to fetch.\n   */\n  setFetchFields(fields) {\n    this._setFetchFields(fields);\n  }\n  /**\n   * Gets the current fields that will be fetched for the selected place.\n   * This is useful for understanding what details will be available\n   * when a place is selected, such as displayName, formattedAddress,\n   * addressComponents, etc.\n   * @returns {Array<string>} The current fetch fields.\n   */\n  getFetchFields() {\n    return this.#fetchFields;\n  }\n\n  /**\n   * Sets the request parameters for the Places Autocomplete instance.\n   * This method allows you to update the request parameters dynamically,\n   * such as the input value, region codes, language, etc.\n   * It merges the provided parameters with the default request parameters,\n   * allowing you to override specific values while keeping the defaults intact.\n   * This is useful for updating the search criteria without needing to recreate the instance.\n   * @param {*} params\n   */\n  setRequestParams(params) {\n    if (\n      typeof params === \"object\" &&\n      !Array.isArray(params) &&\n      params !== null\n    ) {\n      // if params.input is provided, set it to the input element\n      if (params.input && typeof params.input === \"string\") {\n        this.#inputElement.value = params.input; // Set input value if provided\n      }\n      // Merge provided params with default request parameters\n      // This allows overriding specific request parameters while keeping defaults\n      this.#request = {\n        ...this.#defaultRequestParams,\n        ...params,\n      };\n    }\n  }\n\n  /**\n   * Returns the current request parameters used by the Places Autocomplete instance.\n   * This includes the input value, included region codes, language, and other settings.\n   * It is useful for debugging or when you need to know the current search criteria.\n   * @returns {Object} The current request parameters.\n   */\n  getRequestParams() {\n    return this.#request;\n  }\n\n  /**\n   * Sets the options for the Places Autocomplete instance.\n   * This method allows you to change the appearance and behavior of the autocomplete widget,\n   * such as classes, placeholder text, debounce time, etc.\n   * It merges the provided options with the default options, allowing you to override specific values\n   * while keeping the defaults intact.\n   * This is useful for updating the widget's configuration without needing to recreate the instance.\n   * @param {*} options\n   */\n  setOptions(options) {\n    if (\n      typeof options === \"object\" &&\n      !Array.isArray(options) &&\n      options !== null\n    ) {\n      this._detachEventListeners(); // Detach event listeners\n\n      // // Ensure classes are deeply merged if user provides partial classes\n      const tmpClasses = options.classes || {};\n      delete options.classes; // Remove classes from options to avoid overwriting\n\n      // Merge provided options with default options\n      // This allows overriding specific options while keeping defaults\n      this.#options = {\n        ...this.#defaultOptions,\n        ...options,\n      };\n\n      // Merge classes with defaults\n      // This allows overriding specific classes while keeping defaults\n      if (\n        tmpClasses &&\n        typeof tmpClasses === \"object\" &&\n        Object.keys(tmpClasses).length > 0\n      ) {\n        this.#options.classes = {\n          ...this.#defaultClasses,\n          ...tmpClasses,\n        };\n      } else {\n        this.#options.classes = { ...this.#defaultClasses }; // Use defaults if no classes provided\n      }\n\n      this._initialiseDebouncedRequest(); // Reinitialize the debounced request function\n      this._createPACStructure(); // Recreate the structure with new options\n      // Reattach the input event listener to the input element\n      // This is necessary to ensure the new input element is ready for events\n      if (this.#inputElement) {\n        this._attachedEventListeners();\n      } // Reinitialize the autocomplete functionality\n    }\n  }\n\n  /**\n   * Gets the current options used by the Places Autocomplete instance.\n   * @returns {Object} The current options.\n   */\n  getOptions() {\n    /**\n     * Returns the current options used by the Places Autocomplete instance.\n     * This includes classes, placeholder text, debounce time, and other settings.\n     * It is useful for debugging or when you need to know the current configuration of the widget.\n     * @returns {Object} The current options.\n     */\n    return this.#options;\n  }\n\n  /**\n   * Sets the input value by reverse geocoding coordinates.\n   * Performs reverse geocoding to convert lat/lng to a place, then triggers onResponse.\n   * Requires the Geocoding API to be enabled in your Google Cloud Console project.\n   * @param {number} latitude - Latitude coordinate\n   * @param {number} longitude - Longitude coordinate\n   * @returns {Promise<void>}\n   */\n  async setInputValue(latitude, longitude) {\n    try {\n      // Import the geocoding library\n      const { Geocoder } = await google.maps.importLibrary(\"geocoding\");\n      const geocoder = new Geocoder();\n\n      // Perform reverse geocoding\n      const response = await geocoder.geocode({\n        location: { lat: latitude, lng: longitude },\n      });\n\n      if (response.results && response.results.length > 0) {\n        const placeId = response.results[0].place_id;\n        const place = new google.maps.places.Place({ id: placeId });\n\n        // Fetch the configured fields\n        await place.fetchFields({ fields: this.#fetchFields });\n\n        // Update input field if clear_input is false\n        if (!this.#options.clear_input && place.formattedAddress) {\n          this.#inputElement.value = place.formattedAddress;\n        }\n\n        // Trigger the callback with appropriate response type\n        if (this.#options.response_type === \"place\") {\n          this.#onDataCallback(place);\n        } else {\n          this.#onDataCallback(place.toJSON());\n        }\n      } else {\n        throw new Error(\"No results found for the provided coordinates\");\n      }\n    } catch (error) {\n      console.error(\"Error in setInputValue:\", error);\n      this.#onErrorCallback(error);\n    }\n  }\n\n  // Helper method to calculate text similarity (Overlap Coefficient)\n  #getSimilarity(str1, str2) {\n    // Normalize strings: lowercase, remove non-alphanumeric chars, normalize spaces\n    const normalize = (str) =>\n      str\n        .toLowerCase()\n        .replace(/[^a-z0-9]/g, \" \")\n        .replace(/\\s+/g, \" \")\n        .trim();\n\n    const clean1 = normalize(str1);\n    const clean2 = normalize(str2);\n\n    if (clean1 === clean2) return 1.0;\n    if (clean1.length < 2 || clean2.length < 2) return 0.0;\n\n    const getBigrams = (str) => {\n      const bigrams = [];\n      for (let i = 0; i < str.length - 1; i++) {\n        bigrams.push(str.substring(i, i + 2));\n      }\n      return bigrams;\n    };\n\n    const bigrams1 = getBigrams(clean1);\n    const bigrams2 = getBigrams(clean2);\n\n    // Store original lengths for the math equation\n    const len1 = bigrams1.length;\n    const len2 = bigrams2.length;\n\n    let intersection = 0;\n    for (const bigram of bigrams1) {\n      const index = bigrams2.indexOf(bigram);\n      if (index > -1) {\n        intersection++;\n        // Nullify instead of splicing to preserve performance and prevent index shifting\n        bigrams2[index] = null;\n      }\n    }\n\n    // THE FIX: Use Overlap Coefficient instead of Dice's\n    // Formula: intersection / min(|A|, |B|)\n    return intersection / Math.min(len1, len2);\n  }\n\n  /**\n   * Programmatically resolve an AI suggestion string using Places API (New).\n   * @param {string} searchQuery - The highly specific query (e.g. \"Colosseum, Rome, Italy\")\n   * @returns {Promise<boolean>} - Returns true on success, false on failure\n   */\n  async addFromAiSuggestion(searchQuery) {\n    try {\n      const { Place } = await google.maps.importLibrary(\"places\");\n\n      const request = {\n        textQuery: searchQuery,\n        language: this.#options.language,\n        region: this.#options.region,\n        locationRestriction: this.#options.location_restriction,\n        // ADDED formattedAddress to the fields array\n        fields: [\"id\", \"displayName\", \"formattedAddress\"],\n      };\n\n      const { places } = await Place.searchByText(request);\n\n      if (places && places.length > 0) {\n        let bestPlace = places[0];\n        let highestSimilarity = 0;\n\n        for (const p of places) {\n          const name = p.displayName?.text || \"\";\n          const address = p.formattedAddress || \"\";\n\n          // Combine name and address to match the specificity of the AI query\n          const fullPlaceString = `${name} ${address}`;\n\n          const similarity = this.#getSimilarity(searchQuery, fullPlaceString);\n\n          if (similarity > highestSimilarity) {\n            highestSimilarity = similarity;\n            bestPlace = p;\n          }\n        }\n\n        // 0.35 is usually a very safe threshold for normalized bigrams\n        if (highestSimilarity > 0.35) {\n          // Map back to the expected payload for your existing Autocomplete flow\n          this._onPlaceSelected(bestPlace);\n          return true; // Success\n        } else {\n          console.warn(\"Similarity too low to auto-add. Threshold failed.\");\n          return false; // Failed threshold\n        }\n      } else {\n        console.warn(\"AI Suggestion returned no results from Google Maps.\");\n        return false; // API returned empty\n      }\n    } catch (error) {\n      console.error(\"Error resolving AI Suggestion: \", error);\n      return false; // Fatal error\n    }\n  }\n  /**\n   * Clears the autocomplete input field and suggestions list.\n   * This method resets the state of the autocomplete widget,\n   * allowing the user to start a new search without any previous input or suggestions.\n   * It also refreshes the Google Places session token to ensure a new session.\n   * @returns {void}\n   */\n  clear() {\n    this.#cache.clear();\n    this._reset(true);\n  }\n\n  /**\n   * Sets focus on the autocomplete input field.\n   * This method allows programmatic control of the input focus,\n   * useful for improving user experience and accessibility.\n   * @returns {void}\n   */\n  focus() {\n    if (this.#inputElement) {\n      this.#inputElement.focus();\n    }\n  }\n\n  /**\n   * Destroys the PacAutocomplete instance.\n   * Removes event listeners, clears the DOM, and nullifies properties.\n   * This method should be called when the autocomplete widget is no longer needed.\n   * It ensures that all resources are cleaned up to prevent memory leaks.\n   * @returns {void}\n   */\n  destroy() {\n    // Remove event listeners, remove elements from DOM\n    this._detachEventListeners(); // Detach event listeners\n    // Nullify properties\n    this.#containerId = null;\n    this.#pacEl = null;\n    this.#googleMapsApiKey = null;\n    this.#googleMapsApiVersion = null;\n    this.#options = null;\n    this.#request = null;\n    this.#inputElement = null;\n    this.#container = null;\n    this.#ul = null;\n    this.#ariaStatus = null;\n    this.#cache = null;\n    this.#kbdEscape = null;\n    this.#kbdUp = null;\n    this.#kbdDown = null;\n    this.#allSuggestions = null;\n    this.#currentSuggestion = -1;\n    this.#onDataCallback = null;\n    this.#onErrorCallback = null;\n    this.#debouncedMakeAcRequest = null;\n  }\n}\n"],"mappings":"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"}