diff --git a/README.md b/README.md
index 5da2f6d..44da5ff 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,7 @@ This project is a fork of [lit-google-map](https://github.com/arkadiuszwojcik/li
- update dependencies and keep current with Dependabot
- add `zoom_changed`, `center_changed`, and `view_changed` events
- move to [AdvancedMarkerElement](https://developers.google.com/maps/documentation/javascript/advanced-markers/migration)
+- add location button control for centering map on user's current location
## Table of contents
@@ -23,6 +24,8 @@ This project is a fork of [lit-google-map](https://github.com/arkadiuszwojcik/li
[Polygon shape element attributes](#Polygon-shape-element-attributes)
+[Location button control](#Location-button-control)
+
[How to build](#How-to-build)
[License](#License)
@@ -208,6 +211,51 @@ Example:
```
+## Location button control
+
+The location button control adds a native-looking button to the map that centers the map on the user's current location using the browser's Geolocation API.
+
+**Note:** Geolocation requires HTTPS (or localhost for development).
+
+### Location button attributes
+
+- '_position_' - Control position on map (default: 'RIGHT_BOTTOM')
+ - Valid values: 'TOP_LEFT', 'TOP_CENTER', 'TOP_RIGHT', 'LEFT_TOP', 'LEFT_CENTER', 'LEFT_BOTTOM', 'RIGHT_TOP', 'RIGHT_CENTER', 'RIGHT_BOTTOM', 'BOTTOM_LEFT', 'BOTTOM_CENTER', 'BOTTOM_RIGHT'
+- '_label_' - Accessible label for screen readers (default: 'My Location')
+- '_disabled_' - Disable the button (default: false)
+
+### Location button events
+
+- '_location-requested_' - Fired when button is clicked and location request begins
+- '_location-found_' - Fired when location is successfully obtained
+ - Detail: `{lat: number, lng: number}`
+- '_location-error_' - Fired when geolocation fails
+ - Detail: `{code: number, message: string}`
+
+### Example
+
+Basic usage:
+
+```html
+
+
+
+
+```
+
+With custom position:
+
+```html
+
+
+
+
+```
+
## How to build
Before build install all required packages:
diff --git a/dist/lit-google-map.bundle.js b/dist/lit-google-map.bundle.js
index e671e52..55eddfd 100644
--- a/dist/lit-google-map.bundle.js
+++ b/dist/lit-google-map.bundle.js
@@ -163,6 +163,7 @@ var LitGoogleMap = (function (exports) {
});
this.updateMarkers();
this.updateShapes();
+ this.updateControls();
}
getMapOptions() {
return {
@@ -257,6 +258,15 @@ var LitGoogleMap = (function (exports) {
s.attachToMap(this.map);
}
}
+ updateControls() {
+ const controlsSelector = this.shadowRoot.getElementById("controls-selector");
+ if (!controlsSelector)
+ return;
+ this.controls = controlsSelector.items;
+ for (const c of this.controls) {
+ c.changeMap(this.map);
+ }
+ }
fitToMarkersChanged(retryAttempt = 0) {
if (this.map && this.fitToMarkers && this.markers.length > 0) {
const latLngBounds = new google.maps.LatLngBounds();
@@ -316,6 +326,13 @@ var LitGoogleMap = (function (exports) {
>
+
+
+
`;
}
@@ -471,6 +488,210 @@ var LitGoogleMap = (function (exports) {
t("lit-google-map-circle")
], exports.LitGoogleMapCircle);
+ exports.LitGoogleMapLocationButton = class LitGoogleMapLocationButton extends i {
+ constructor() {
+ super(...arguments);
+ this.position = "RIGHT_BOTTOM";
+ this.label = "My Location";
+ this.disabled = false;
+ this.map = null;
+ this.controlDiv = null;
+ this.controlButton = null;
+ this.isRequesting = false;
+ }
+ changeMap(newMap) {
+ this.map = newMap;
+ this.mapChanged();
+ }
+ mapChanged() {
+ if (this.controlDiv && this.map) {
+ this.controlDiv = null;
+ this.controlButton = null;
+ }
+ if (this.map && this.map instanceof google.maps.Map) {
+ this.mapReady();
+ }
+ }
+ mapReady() {
+ this.controlDiv = this.createControlButton();
+ const controlPosition = google.maps.ControlPosition[this.position];
+ if (controlPosition !== undefined) {
+ this.map.controls[controlPosition].push(this.controlDiv);
+ }
+ }
+ createControlButton() {
+ const controlDiv = document.createElement("div");
+ controlDiv.style.margin = "10px";
+ const controlButton = document.createElement("button");
+ controlButton.type = "button";
+ controlButton.title = this.label;
+ controlButton.setAttribute("aria-label", this.label);
+ controlButton.innerHTML = `
+
+ `;
+ Object.assign(controlButton.style, {
+ backgroundColor: "#fff",
+ border: "0",
+ borderRadius: "2px",
+ boxShadow: "0 1px 4px rgba(0,0,0,0.3)",
+ cursor: "pointer",
+ padding: "10px",
+ display: "flex",
+ alignItems: "center",
+ justifyContent: "center",
+ width: "40px",
+ height: "40px",
+ color: "#666",
+ });
+ controlButton.addEventListener("mouseenter", () => {
+ if (!this.disabled && !this.isRequesting) {
+ controlButton.style.backgroundColor = "#f8f8f8";
+ }
+ });
+ controlButton.addEventListener("mouseleave", () => {
+ if (!this.disabled && !this.isRequesting) {
+ controlButton.style.backgroundColor = "#fff";
+ }
+ });
+ controlButton.addEventListener("click", () => {
+ if (!this.disabled && !this.isRequesting) {
+ this.handleLocationRequest();
+ }
+ });
+ this.controlButton = controlButton;
+ controlDiv.appendChild(controlButton);
+ return controlDiv;
+ }
+ async handleLocationRequest() {
+ if (!navigator.geolocation) {
+ this.dispatchEvent(new CustomEvent("location-error", {
+ detail: {
+ code: -1,
+ message: "Geolocation is not supported by your browser",
+ },
+ bubbles: true,
+ composed: true,
+ }));
+ return;
+ }
+ this.isRequesting = true;
+ this.setLoadingState(true);
+ this.dispatchEvent(new CustomEvent("location-requested", {
+ bubbles: true,
+ composed: true,
+ }));
+ try {
+ const position = await this.getCurrentPosition();
+ const lat = position.coords.latitude;
+ const lng = position.coords.longitude;
+ this.map.setCenter({ lat, lng });
+ this.map.setZoom(14);
+ this.dispatchEvent(new CustomEvent("location-found", {
+ detail: { lat, lng },
+ bubbles: true,
+ composed: true,
+ }));
+ }
+ catch (error) {
+ let message = "Unable to retrieve your location";
+ let code = -1;
+ if (error instanceof GeolocationPositionError) {
+ code = error.code;
+ if (error.code === error.PERMISSION_DENIED) {
+ message =
+ "Location access denied. Please enable location permissions.";
+ }
+ else if (error.code === error.TIMEOUT) {
+ message = "Location request timed out. Please try again.";
+ }
+ else if (error.code === error.POSITION_UNAVAILABLE) {
+ message = "Location information is unavailable.";
+ }
+ }
+ this.dispatchEvent(new CustomEvent("location-error", {
+ detail: { code, message },
+ bubbles: true,
+ composed: true,
+ }));
+ }
+ finally {
+ this.isRequesting = false;
+ this.setLoadingState(false);
+ }
+ }
+ getCurrentPosition() {
+ return new Promise((resolve, reject) => {
+ navigator.geolocation.getCurrentPosition(resolve, reject, {
+ timeout: 10000,
+ enableHighAccuracy: true,
+ });
+ });
+ }
+ setLoadingState(loading) {
+ if (!this.controlButton)
+ return;
+ if (loading) {
+ this.controlButton.style.backgroundColor = "#f0f0f0";
+ this.controlButton.style.cursor = "wait";
+ const svg = this.controlButton.querySelector("svg");
+ if (svg) {
+ svg.style.animation = "spin 1s linear infinite";
+ const style = document.createElement("style");
+ style.textContent = `
+ @keyframes spin {
+ from { transform: rotate(0deg); }
+ to { transform: rotate(360deg); }
+ }
+ `;
+ if (!document.querySelector("style[data-location-button-spin]")) {
+ style.setAttribute("data-location-button-spin", "true");
+ document.head.appendChild(style);
+ }
+ }
+ }
+ else {
+ this.controlButton.style.backgroundColor = "#fff";
+ this.controlButton.style.cursor = "pointer";
+ const svg = this.controlButton.querySelector("svg");
+ if (svg) {
+ svg.style.animation = "";
+ }
+ }
+ }
+ attributeChangedCallback(name, oldval, newval) {
+ super.attributeChangedCallback(name, oldval, newval);
+ if (name === "disabled" && this.controlButton) {
+ if (this.disabled) {
+ this.controlButton.style.backgroundColor = "#f0f0f0";
+ this.controlButton.style.cursor = "not-allowed";
+ this.controlButton.style.opacity = "0.6";
+ }
+ else {
+ this.controlButton.style.backgroundColor = "#fff";
+ this.controlButton.style.cursor = "pointer";
+ this.controlButton.style.opacity = "1";
+ }
+ }
+ }
+ };
+ __decorate([
+ n({ type: String, reflect: true }),
+ __metadata("design:type", Object)
+ ], exports.LitGoogleMapLocationButton.prototype, "position", void 0);
+ __decorate([
+ n({ type: String, reflect: true }),
+ __metadata("design:type", Object)
+ ], exports.LitGoogleMapLocationButton.prototype, "label", void 0);
+ __decorate([
+ n({ type: Boolean, reflect: true }),
+ __metadata("design:type", Object)
+ ], exports.LitGoogleMapLocationButton.prototype, "disabled", void 0);
+ exports.LitGoogleMapLocationButton = __decorate([
+ t("lit-google-map-location-button")
+ ], exports.LitGoogleMapLocationButton);
+
exports.LitGoogleMapMarker = class LitGoogleMapMarker extends i {
constructor() {
super(...arguments);
diff --git a/dist/lit-google-map.bundle.min.js b/dist/lit-google-map.bundle.min.js
index d86a060..32364dd 100644
--- a/dist/lit-google-map.bundle.min.js
+++ b/dist/lit-google-map.bundle.min.js
@@ -9,18 +9,18 @@ const s=globalThis,o=s.ShadowRoot&&(void 0===s.ShadyCSS||s.ShadyCSS.nativeShadow
* @license
* Copyright 2017 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
- */,{is:h,defineProperty:p,getOwnPropertyDescriptor:c,getOwnPropertyNames:d,getOwnPropertySymbols:u,getPrototypeOf:g}=Object,m=globalThis,y=m.trustedTypes,b=y?y.emptyScript:"",f=m.reactiveElementPolyfillSupport,v=(t,e)=>t,$={toAttribute(t,e){switch(e){case Boolean:t=t?b:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,e){let i=t;switch(e){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t)}catch(t){i=null}}return i}},_=(t,e)=>!h(t,e),k={attribute:!0,type:String,converter:$,reflect:!1,useDefault:!1,hasChanged:_};Symbol.metadata??=Symbol("metadata"),m.litPropertyMetadata??=new WeakMap;let C=class extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,e=k){if(e.state&&(e.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((e=Object.create(e)).wrapped=!0),this.elementProperties.set(t,e),!e.noAccessor){const i=Symbol(),s=this.getPropertyDescriptor(t,i,e);void 0!==s&&p(this.prototype,t,s)}}static getPropertyDescriptor(t,e,i){const{get:s,set:o}=c(this.prototype,t)??{get(){return this[e]},set(t){this[e]=t}};return{get:s,set(e){const r=s?.call(this);o?.call(this,e),this.requestUpdate(t,r,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??k}static _$Ei(){if(this.hasOwnProperty(v("elementProperties")))return;const t=g(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(v("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(v("properties"))){const t=this.properties,e=[...d(t),...u(t)];for(const i of e)this.createProperty(i,t[i])}const t=this[Symbol.metadata];if(null!==t){const e=litPropertyMetadata.get(t);if(void 0!==e)for(const[t,i]of e)this.elementProperties.set(t,i)}this._$Eh=new Map;for(const[t,e]of this.elementProperties){const i=this._$Eu(t,e);void 0!==i&&this._$Eh.set(i,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(t){const e=[];if(Array.isArray(t)){const i=new Set(t.flat(1/0).reverse());for(const t of i)e.unshift(l(t))}else void 0!==t&&e.push(l(t));return e}static _$Eu(t,e){const i=e.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise((t=>this.enableUpdating=t)),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach((t=>t(this)))}addController(t){(this._$EO??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){const t=new Map,e=this.constructor.elementProperties;for(const i of e.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t)}createRenderRoot(){const t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return((t,e)=>{if(o)t.adoptedStyleSheets=e.map((t=>t instanceof CSSStyleSheet?t:t.styleSheet));else for(const i of e){const e=document.createElement("style"),o=s.litNonce;void 0!==o&&e.setAttribute("nonce",o),e.textContent=i.cssText,t.appendChild(e)}})(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach((t=>t.hostConnected?.()))}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach((t=>t.hostDisconnected?.()))}attributeChangedCallback(t,e,i){this._$AK(t,i)}_$ET(t,e){const i=this.constructor.elementProperties.get(t),s=this.constructor._$Eu(t,i);if(void 0!==s&&!0===i.reflect){const o=(void 0!==i.converter?.toAttribute?i.converter:$).toAttribute(e,i.type);this._$Em=t,null==o?this.removeAttribute(s):this.setAttribute(s,o),this._$Em=null}}_$AK(t,e){const i=this.constructor,s=i._$Eh.get(t);if(void 0!==s&&this._$Em!==s){const t=i.getPropertyOptions(s),o="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:$;this._$Em=s,this[s]=o.fromAttribute(e,t.type)??this._$Ej?.get(s)??null,this._$Em=null}}requestUpdate(t,e,i){if(void 0!==t){const s=this.constructor,o=this[t];if(i??=s.getPropertyOptions(t),!((i.hasChanged??_)(o,e)||i.useDefault&&i.reflect&&o===this._$Ej?.get(t)&&!this.hasAttribute(s._$Eu(t,i))))return;this.C(t,e,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(t,e,{useDefault:i,reflect:s,wrapped:o},r){i&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,r??e??this[t]),!0!==o||void 0!==r)||(this._$AL.has(t)||(this.hasUpdated||i||(e=void 0),this._$AL.set(t,e)),!0===s&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,e]of this._$Ep)this[t]=e;this._$Ep=void 0}const t=this.constructor.elementProperties;if(t.size>0)for(const[e,i]of t){const{wrapped:t}=i,s=this[e];!0!==t||this._$AL.has(e)||void 0===s||this.C(e,void 0,i,s)}}let t=!1;const e=this._$AL;try{t=this.shouldUpdate(e),t?(this.willUpdate(e),this._$EO?.forEach((t=>t.hostUpdate?.())),this.update(e)):this._$EM()}catch(e){throw t=!1,this._$EM(),e}t&&this._$AE(e)}willUpdate(t){}_$AE(t){this._$EO?.forEach((t=>t.hostUpdated?.())),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach((t=>this._$ET(t,this[t]))),this._$EM()}updated(t){}firstUpdated(t){}};C.elementStyles=[],C.shadowRootOptions={mode:"open"},C[v("elementProperties")]=new Map,C[v("finalized")]=new Map,f?.({ReactiveElement:C}),(m.reactiveElementVersions??=[]).push("2.1.0");
+ */,{is:h,defineProperty:c,getOwnPropertyDescriptor:p,getOwnPropertyNames:d,getOwnPropertySymbols:u,getPrototypeOf:g}=Object,m=globalThis,y=m.trustedTypes,b=y?y.emptyScript:"",f=m.reactiveElementPolyfillSupport,v=(t,e)=>t,$={toAttribute(t,e){switch(e){case Boolean:t=t?b:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,e){let i=t;switch(e){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t)}catch(t){i=null}}return i}},C=(t,e)=>!h(t,e),_={attribute:!0,type:String,converter:$,reflect:!1,useDefault:!1,hasChanged:C};Symbol.metadata??=Symbol("metadata"),m.litPropertyMetadata??=new WeakMap;let k=class extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,e=_){if(e.state&&(e.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((e=Object.create(e)).wrapped=!0),this.elementProperties.set(t,e),!e.noAccessor){const i=Symbol(),s=this.getPropertyDescriptor(t,i,e);void 0!==s&&c(this.prototype,t,s)}}static getPropertyDescriptor(t,e,i){const{get:s,set:o}=p(this.prototype,t)??{get(){return this[e]},set(t){this[e]=t}};return{get:s,set(e){const r=s?.call(this);o?.call(this,e),this.requestUpdate(t,r,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??_}static _$Ei(){if(this.hasOwnProperty(v("elementProperties")))return;const t=g(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(v("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(v("properties"))){const t=this.properties,e=[...d(t),...u(t)];for(const i of e)this.createProperty(i,t[i])}const t=this[Symbol.metadata];if(null!==t){const e=litPropertyMetadata.get(t);if(void 0!==e)for(const[t,i]of e)this.elementProperties.set(t,i)}this._$Eh=new Map;for(const[t,e]of this.elementProperties){const i=this._$Eu(t,e);void 0!==i&&this._$Eh.set(i,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(t){const e=[];if(Array.isArray(t)){const i=new Set(t.flat(1/0).reverse());for(const t of i)e.unshift(l(t))}else void 0!==t&&e.push(l(t));return e}static _$Eu(t,e){const i=e.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise((t=>this.enableUpdating=t)),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach((t=>t(this)))}addController(t){(this._$EO??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){const t=new Map,e=this.constructor.elementProperties;for(const i of e.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t)}createRenderRoot(){const t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return((t,e)=>{if(o)t.adoptedStyleSheets=e.map((t=>t instanceof CSSStyleSheet?t:t.styleSheet));else for(const i of e){const e=document.createElement("style"),o=s.litNonce;void 0!==o&&e.setAttribute("nonce",o),e.textContent=i.cssText,t.appendChild(e)}})(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach((t=>t.hostConnected?.()))}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach((t=>t.hostDisconnected?.()))}attributeChangedCallback(t,e,i){this._$AK(t,i)}_$ET(t,e){const i=this.constructor.elementProperties.get(t),s=this.constructor._$Eu(t,i);if(void 0!==s&&!0===i.reflect){const o=(void 0!==i.converter?.toAttribute?i.converter:$).toAttribute(e,i.type);this._$Em=t,null==o?this.removeAttribute(s):this.setAttribute(s,o),this._$Em=null}}_$AK(t,e){const i=this.constructor,s=i._$Eh.get(t);if(void 0!==s&&this._$Em!==s){const t=i.getPropertyOptions(s),o="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:$;this._$Em=s,this[s]=o.fromAttribute(e,t.type)??this._$Ej?.get(s)??null,this._$Em=null}}requestUpdate(t,e,i){if(void 0!==t){const s=this.constructor,o=this[t];if(i??=s.getPropertyOptions(t),!((i.hasChanged??C)(o,e)||i.useDefault&&i.reflect&&o===this._$Ej?.get(t)&&!this.hasAttribute(s._$Eu(t,i))))return;this.C(t,e,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(t,e,{useDefault:i,reflect:s,wrapped:o},r){i&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,r??e??this[t]),!0!==o||void 0!==r)||(this._$AL.has(t)||(this.hasUpdated||i||(e=void 0),this._$AL.set(t,e)),!0===s&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,e]of this._$Ep)this[t]=e;this._$Ep=void 0}const t=this.constructor.elementProperties;if(t.size>0)for(const[e,i]of t){const{wrapped:t}=i,s=this[e];!0!==t||this._$AL.has(e)||void 0===s||this.C(e,void 0,i,s)}}let t=!1;const e=this._$AL;try{t=this.shouldUpdate(e),t?(this.willUpdate(e),this._$EO?.forEach((t=>t.hostUpdate?.())),this.update(e)):this._$EM()}catch(e){throw t=!1,this._$EM(),e}t&&this._$AE(e)}willUpdate(t){}_$AE(t){this._$EO?.forEach((t=>t.hostUpdated?.())),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach((t=>this._$ET(t,this[t]))),this._$EM()}updated(t){}firstUpdated(t){}};k.elementStyles=[],k.shadowRootOptions={mode:"open"},k[v("elementProperties")]=new Map,k[v("finalized")]=new Map,f?.({ReactiveElement:k}),(m.reactiveElementVersions??=[]).push("2.1.0");
/**
* @license
* Copyright 2017 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/
-const A=globalThis,M=A.trustedTypes,E=M?M.createPolicy("lit-html",{createHTML:t=>t}):void 0,L="$lit$",S=`lit$${Math.random().toFixed(9).slice(2)}$`,O="?"+S,w=`<${O}>`,P=document,x=()=>P.createComment(""),N=t=>null===t||"object"!=typeof t&&"function"!=typeof t,I=Array.isArray,G="[ \t\n\f\r]",j=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,T=/-->/g,U=/>/g,R=RegExp(`>|${G}(?:([^\\s"'>=/]+)(${G}*=${G}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),H=/'/g,z=/"/g,B=/^(?:script|style|textarea|title)$/i,D=(t=>(e,...i)=>({_$litType$:t,strings:e,values:i}))(1),W=Symbol.for("lit-noChange"),q=Symbol.for("lit-nothing"),F=new WeakMap,V=P.createTreeWalker(P,129);function K(t,e){if(!I(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==E?E.createHTML(e):e}const J=(t,e)=>{const i=t.length-1,s=[];let o,r=2===e?"":3===e?"":"")),s]};class Z{constructor({strings:t,_$litType$:e},i){let s;this.parts=[];let o=0,r=0;const n=t.length-1,a=this.parts,[l,h]=J(t,e);if(this.el=Z.createElement(l,i),V.currentNode=this.el.content,2===e||3===e){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes)}for(;null!==(s=V.nextNode())&&a.length0){s.textContent=M?M.emptyScript:"";for(let i=0;iI(t)||"function"==typeof t?.[Symbol.iterator])(t)?this.k(t):this._(t)}O(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}T(t){this._$AH!==t&&(this._$AR(),this._$AH=this.O(t))}_(t){this._$AH!==q&&N(this._$AH)?this._$AA.nextSibling.data=t:this.T(P.createTextNode(t)),this._$AH=t}$(t){const{values:e,_$litType$:i}=t,s="number"==typeof i?this._$AC(t):(void 0===i.el&&(i.el=Z.createElement(K(i.h,i.h[0]),this.options)),i);if(this._$AH?._$AD===s)this._$AH.p(e);else{const t=new X(s,this),i=t.u(this.options);t.p(e),this.T(i),this._$AH=t}}_$AC(t){let e=F.get(t.strings);return void 0===e&&F.set(t.strings,e=new Z(t)),e}k(t){I(this._$AH)||(this._$AH=[],this._$AR());const e=this._$AH;let i,s=0;for(const o of t)s===e.length?e.push(i=new Y(this.O(x()),this.O(x()),this,this.options)):i=e[s],i._$AI(o),s++;s2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=q}_$AI(t,e=this,i,s){const o=this.strings;let r=!1;if(void 0===o)t=Q(this,t,e,0),r=!N(t)||t!==this._$AH&&t!==W,r&&(this._$AH=t);else{const s=t;let n,a;for(t=o[0],n=0;nt}):void 0,E="$lit$",S=`lit$${Math.random().toFixed(9).slice(2)}$`,w="?"+S,O=`<${w}>`,x=document,P=()=>x.createComment(""),I=t=>null===t||"object"!=typeof t&&"function"!=typeof t,N=Array.isArray,G="[ \t\n\f\r]",T=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,R=/-->/g,j=/>/g,U=RegExp(`>|${G}(?:([^\\s"'>=/]+)(${G}*=${G}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),B=/'/g,H=/"/g,z=/^(?:script|style|textarea|title)$/i,D=(t=>(e,...i)=>({_$litType$:t,strings:e,values:i}))(1),q=Symbol.for("lit-noChange"),W=Symbol.for("lit-nothing"),V=new WeakMap,F=x.createTreeWalker(x,129);function K(t,e){if(!N(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==A?A.createHTML(e):e}const Z=(t,e)=>{const i=t.length-1,s=[];let o,r=2===e?"":3===e?"":"")),s]};class J{constructor({strings:t,_$litType$:e},i){let s;this.parts=[];let o=0,r=0;const n=t.length-1,a=this.parts,[l,h]=Z(t,e);if(this.el=J.createElement(l,i),F.currentNode=this.el.content,2===e||3===e){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes)}for(;null!==(s=F.nextNode())&&a.length0){s.textContent=L?L.emptyScript:"";for(let i=0;iN(t)||"function"==typeof t?.[Symbol.iterator])(t)?this.k(t):this._(t)}O(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}T(t){this._$AH!==t&&(this._$AR(),this._$AH=this.O(t))}_(t){this._$AH!==W&&I(this._$AH)?this._$AA.nextSibling.data=t:this.T(x.createTextNode(t)),this._$AH=t}$(t){const{values:e,_$litType$:i}=t,s="number"==typeof i?this._$AC(t):(void 0===i.el&&(i.el=J.createElement(K(i.h,i.h[0]),this.options)),i);if(this._$AH?._$AD===s)this._$AH.p(e);else{const t=new X(s,this),i=t.u(this.options);t.p(e),this.T(i),this._$AH=t}}_$AC(t){let e=V.get(t.strings);return void 0===e&&V.set(t.strings,e=new J(t)),e}k(t){N(this._$AH)||(this._$AH=[],this._$AR());const e=this._$AH;let i,s=0;for(const o of t)s===e.length?e.push(i=new Y(this.O(P()),this.O(P()),this,this.options)):i=e[s],i._$AI(o),s++;s2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=W}_$AI(t,e=this,i,s){const o=this.strings;let r=!1;if(void 0===o)t=Q(this,t,e,0),r=!I(t)||t!==this._$AH&&t!==q,r&&(this._$AH=t);else{const s=t;let n,a;for(t=o[0],n=0;n{const s=i?.renderBefore??e;let o=s._$litPart$;if(void 0===o){const t=i?.renderBefore??null;s._$litPart$=o=new Y(e.insertBefore(x(),t),t,void 0,i??{})}return o._$AI(t),o})(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return W}}at._$litElement$=!0,at.finalized=!0,nt.litElementHydrateSupport?.({LitElement:at});const lt=nt.litElementPolyfillSupport;lt?.({LitElement:at}),(nt.litElementVersions??=[]).push("4.2.0");
+ */class at extends k{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){const e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=((t,e,i)=>{const s=i?.renderBefore??e;let o=s._$litPart$;if(void 0===o){const t=i?.renderBefore??null;s._$litPart$=o=new Y(e.insertBefore(P(),t),t,void 0,i??{})}return o._$AI(t),o})(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return q}}at._$litElement$=!0,at.finalized=!0,nt.litElementHydrateSupport?.({LitElement:at});const lt=nt.litElementPolyfillSupport;lt?.({LitElement:at}),(nt.litElementVersions??=[]).push("4.2.0");
/**
* @license
* Copyright 2017 Google LLC
@@ -31,7 +31,7 @@ const ht=t=>(e,i)=>{void 0!==i?i.addInitializer((()=>{customElements.define(t,e)
* @license
* Copyright 2017 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
- */,pt={attribute:!0,type:String,converter:$,reflect:!1,hasChanged:_},ct=(t=pt,e,i)=>{const{kind:s,metadata:o}=i;let r=globalThis.litPropertyMetadata.get(o);if(void 0===r&&globalThis.litPropertyMetadata.set(o,r=new Map),"setter"===s&&((t=Object.create(t)).wrapped=!0),r.set(i.name,t),"accessor"===s){const{name:s}=i;return{set(i){const o=e.get.call(this);e.set.call(this,i),this.requestUpdate(s,o,t)},init(e){return void 0!==e&&this.C(s,void 0,t,e),e}}}if("setter"===s){const{name:s}=i;return function(i){const o=this[s];e.call(this,i),this.requestUpdate(s,o,t)}}throw Error("Unsupported decorator location: "+s)};function dt(t){return(e,i)=>"object"==typeof i?ct(t,e,i):((t,e,i)=>{const s=e.hasOwnProperty(i);return e.constructor.createProperty(i,t),s?Object.getOwnPropertyDescriptor(e,i):void 0})(t,e,i)}t.LitGoogleMap=class extends at{constructor(){super(...arguments),this.apiKey="",this.version="3.48",this.styles={},this.zoom=8,this.fitToMarkers=!1,this.mapType="roadmap",this.centerLatitude=-34.397,this.centerLongitude=150.644,this.language="",this.mapId="DEMO_MAP_ID",this.map=null}attributeChangedCallback(t,e,i){super.attributeChangedCallback(t,e,i),this.map&&e!==i&&null!==i&&("center-latitude"===t||"center-longitude"===t?this.map.setCenter({lat:this.centerLatitude,lng:this.centerLongitude}):"zoom"===t&&this.map.setZoom(this.zoom))}dispatchViewChanged(){this.dispatchEvent(new CustomEvent("view_changed",{detail:{center:this.map.getCenter().toJSON(),zoom:this.map.getZoom()},bubbles:!0,composed:!0}))}initGMap(){if(null!=this.map)return;const t=this.shadowRoot.getElementById("api");null!=t&&!0===t.libraryLoaded&&(this.map=new google.maps.Map(this.shadowRoot.getElementById("map"),this.getMapOptions()),this.map.addListener("bounds_changed",(()=>{this.dispatchEvent(new CustomEvent("bounds_changed",{detail:this.map.getBounds().toJSON(),bubbles:!0,composed:!0}))})),this.map.addListener("tilesloaded",(()=>{this.dispatchEvent(new CustomEvent("tilesloaded",{detail:this.map.getBounds().toJSON(),bubbles:!0,composed:!0}))})),this.map.addListener("center_changed",(()=>{this.dispatchEvent(new CustomEvent("center_changed",{detail:this.map.getCenter().toJSON(),bubbles:!0,composed:!0})),this.dispatchViewChanged()})),this.map.addListener("zoom_changed",(()=>{this.dispatchEvent(new CustomEvent("zoom_changed",{detail:{zoom:this.map.getZoom()},bubbles:!0,composed:!0})),this.dispatchViewChanged()})),this.map.addListener("click",(t=>{"placeId"in t&&(t.stop(),this.dispatchEvent(new CustomEvent("place_click",{detail:{placeId:t.placeId},bubbles:!0,composed:!0})))})),this.updateMarkers(),this.updateShapes())}getMapOptions(){return{zoom:this.zoom,center:{lat:this.centerLatitude,lng:this.centerLongitude},mapTypeId:this.mapType,styles:this.styles,mapId:this.mapId}}mapApiLoaded(){this.initGMap()}connectedCallback(){super.connectedCallback(),this.initGMap()}updated(t){super.updated(t),this.map?((t.has("centerLatitude")||t.has("centerLongitude"))&&(t.get("centerLatitude"),t.get("centerLongitude"),this.map.setCenter({lat:this.centerLatitude,lng:this.centerLongitude})),t.has("zoom")&&(t.get("zoom"),this.map.setZoom(this.zoom))):console.log("Map not initialized yet, skipping update")}attachChildrenToMap(t){if(this.map)for(const e of t)e.changeMap(this.map)}detachChildrenFromMap(t){if(this.map)for(const e of t)e.changeMap(null)}observeMarkers(){this.markerObserverSet||(this.addEventListener("selector-items-changed",(()=>{this.updateMarkers()})),this.markerObserverSet=!0)}updateMarkers(){var t;this.observeMarkers();const e=this.shadowRoot.getElementById("markers-selector");if(!e)return;const i=e.items;if(this.markers&&i.length===this.markers.length){const t=i.filter((t=>this.markers&&-1===this.markers.indexOf(t)));if(0===t.length)return}const s=this.checkBoundsChanged(this.markers,i),o=(null===(t=this.markers)||void 0===t?void 0:t.filter((t=>-1===i.indexOf(t))))||[];this.detachChildrenFromMap(o),this.markers=i,this.attachChildrenToMap(this.markers),this.fitToMarkers&&s&&this.fitToMarkersChanged()}updateShapes(){const t=this.shadowRoot.getElementById("shapes-selector");if(t){this.shapes=t.items;for(const t of this.shapes)t.attachToMap(this.map)}}fitToMarkersChanged(t=0){if(this.map&&this.fitToMarkers&&this.markers.length>0){const e=new google.maps.LatLngBounds;for(const t of this.markers)e.extend(new google.maps.LatLng(t.latitude,t.longitude));const i=this.getBoundingClientRect();if(0===i.width||0===i.height){console.log("Invalid DOM width or height for lit-google-map");return void setTimeout((()=>{this.fitToMarkersChanged(t+1)}),2**t*100)}this.markers.length>1&&this.map.fitBounds(e,0),this.map.setCenter(e.getCenter())}}checkBoundsChanged(t,e){const i=e.filter((e=>!t||!t.includes(e))),s=null==t?void 0:t.filter((t=>!e||!e.includes(t)));return i.length>0||s.length>0}deselectMarker(t){}deselectShape(t){}render(){return D`
+ */,ct={attribute:!0,type:String,converter:$,reflect:!1,hasChanged:C},pt=(t=ct,e,i)=>{const{kind:s,metadata:o}=i;let r=globalThis.litPropertyMetadata.get(o);if(void 0===r&&globalThis.litPropertyMetadata.set(o,r=new Map),"setter"===s&&((t=Object.create(t)).wrapped=!0),r.set(i.name,t),"accessor"===s){const{name:s}=i;return{set(i){const o=e.get.call(this);e.set.call(this,i),this.requestUpdate(s,o,t)},init(e){return void 0!==e&&this.C(s,void 0,t,e),e}}}if("setter"===s){const{name:s}=i;return function(i){const o=this[s];e.call(this,i),this.requestUpdate(s,o,t)}}throw Error("Unsupported decorator location: "+s)};function dt(t){return(e,i)=>"object"==typeof i?pt(t,e,i):((t,e,i)=>{const s=e.hasOwnProperty(i);return e.constructor.createProperty(i,t),s?Object.getOwnPropertyDescriptor(e,i):void 0})(t,e,i)}t.LitGoogleMap=class extends at{constructor(){super(...arguments),this.apiKey="",this.version="3.48",this.styles={},this.zoom=8,this.fitToMarkers=!1,this.mapType="roadmap",this.centerLatitude=-34.397,this.centerLongitude=150.644,this.language="",this.mapId="DEMO_MAP_ID",this.map=null}attributeChangedCallback(t,e,i){super.attributeChangedCallback(t,e,i),this.map&&e!==i&&null!==i&&("center-latitude"===t||"center-longitude"===t?this.map.setCenter({lat:this.centerLatitude,lng:this.centerLongitude}):"zoom"===t&&this.map.setZoom(this.zoom))}dispatchViewChanged(){this.dispatchEvent(new CustomEvent("view_changed",{detail:{center:this.map.getCenter().toJSON(),zoom:this.map.getZoom()},bubbles:!0,composed:!0}))}initGMap(){if(null!=this.map)return;const t=this.shadowRoot.getElementById("api");null!=t&&!0===t.libraryLoaded&&(this.map=new google.maps.Map(this.shadowRoot.getElementById("map"),this.getMapOptions()),this.map.addListener("bounds_changed",(()=>{this.dispatchEvent(new CustomEvent("bounds_changed",{detail:this.map.getBounds().toJSON(),bubbles:!0,composed:!0}))})),this.map.addListener("tilesloaded",(()=>{this.dispatchEvent(new CustomEvent("tilesloaded",{detail:this.map.getBounds().toJSON(),bubbles:!0,composed:!0}))})),this.map.addListener("center_changed",(()=>{this.dispatchEvent(new CustomEvent("center_changed",{detail:this.map.getCenter().toJSON(),bubbles:!0,composed:!0})),this.dispatchViewChanged()})),this.map.addListener("zoom_changed",(()=>{this.dispatchEvent(new CustomEvent("zoom_changed",{detail:{zoom:this.map.getZoom()},bubbles:!0,composed:!0})),this.dispatchViewChanged()})),this.map.addListener("click",(t=>{"placeId"in t&&(t.stop(),this.dispatchEvent(new CustomEvent("place_click",{detail:{placeId:t.placeId},bubbles:!0,composed:!0})))})),this.updateMarkers(),this.updateShapes(),this.updateControls())}getMapOptions(){return{zoom:this.zoom,center:{lat:this.centerLatitude,lng:this.centerLongitude},mapTypeId:this.mapType,styles:this.styles,mapId:this.mapId}}mapApiLoaded(){this.initGMap()}connectedCallback(){super.connectedCallback(),this.initGMap()}updated(t){super.updated(t),this.map?((t.has("centerLatitude")||t.has("centerLongitude"))&&(t.get("centerLatitude"),t.get("centerLongitude"),this.map.setCenter({lat:this.centerLatitude,lng:this.centerLongitude})),t.has("zoom")&&(t.get("zoom"),this.map.setZoom(this.zoom))):console.log("Map not initialized yet, skipping update")}attachChildrenToMap(t){if(this.map)for(const e of t)e.changeMap(this.map)}detachChildrenFromMap(t){if(this.map)for(const e of t)e.changeMap(null)}observeMarkers(){this.markerObserverSet||(this.addEventListener("selector-items-changed",(()=>{this.updateMarkers()})),this.markerObserverSet=!0)}updateMarkers(){var t;this.observeMarkers();const e=this.shadowRoot.getElementById("markers-selector");if(!e)return;const i=e.items;if(this.markers&&i.length===this.markers.length){const t=i.filter((t=>this.markers&&-1===this.markers.indexOf(t)));if(0===t.length)return}const s=this.checkBoundsChanged(this.markers,i),o=(null===(t=this.markers)||void 0===t?void 0:t.filter((t=>-1===i.indexOf(t))))||[];this.detachChildrenFromMap(o),this.markers=i,this.attachChildrenToMap(this.markers),this.fitToMarkers&&s&&this.fitToMarkersChanged()}updateShapes(){const t=this.shadowRoot.getElementById("shapes-selector");if(t){this.shapes=t.items;for(const t of this.shapes)t.attachToMap(this.map)}}updateControls(){const t=this.shadowRoot.getElementById("controls-selector");if(t){this.controls=t.items;for(const t of this.controls)t.changeMap(this.map)}}fitToMarkersChanged(t=0){if(this.map&&this.fitToMarkers&&this.markers.length>0){const e=new google.maps.LatLngBounds;for(const t of this.markers)e.extend(new google.maps.LatLng(t.latitude,t.longitude));const i=this.getBoundingClientRect();if(0===i.width||0===i.height){console.log("Invalid DOM width or height for lit-google-map");return void setTimeout((()=>{this.fitToMarkersChanged(t+1)}),2**t*100)}this.markers.length>1&&this.map.fitBounds(e,0),this.map.setCenter(e.getCenter())}}checkBoundsChanged(t,e){const i=e.filter((e=>!t||!t.includes(e))),s=null==t?void 0:t.filter((t=>!e||!e.includes(t)));return i.length>0||s.length>0}deselectMarker(t){}deselectShape(t){}render(){return D`
(e,i)=>{void 0!==i?i.addInitializer((()=>{customElements.define(t,e)
>
+
+
+
`}},t.LitGoogleMap.styles=((t,...e)=>{const i=1===t.length?t[0]:e.reduce(((e,i,s)=>e+(t=>{if(!0===t._$cssResult$)return t.cssText;if("number"==typeof t)return t;throw Error("Value passed to 'css' function must be a 'css' function result: "+t+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(i)+t[s+1]),t[0]);return new a(i,t,r)})`
#map {
width: 100%;
height: 100%;
}
- `,e([dt({type:String,attribute:"api-key"}),i("design:type",Object)],t.LitGoogleMap.prototype,"apiKey",void 0),e([dt({type:String}),i("design:type",Object)],t.LitGoogleMap.prototype,"version",void 0),e([dt({type:Object}),i("design:type",Object)],t.LitGoogleMap.prototype,"styles",void 0),e([dt({type:Number}),i("design:type",Object)],t.LitGoogleMap.prototype,"zoom",void 0),e([dt({type:Boolean,attribute:"fit-to-markers"}),i("design:type",Object)],t.LitGoogleMap.prototype,"fitToMarkers",void 0),e([dt({type:String,attribute:"map-type"}),i("design:type",Object)],t.LitGoogleMap.prototype,"mapType",void 0),e([dt({type:Number,attribute:"center-latitude"}),i("design:type",Object)],t.LitGoogleMap.prototype,"centerLatitude",void 0),e([dt({type:Number,attribute:"center-longitude"}),i("design:type",Object)],t.LitGoogleMap.prototype,"centerLongitude",void 0),e([dt({type:String}),i("design:type",Object)],t.LitGoogleMap.prototype,"language",void 0),e([dt({type:String,attribute:"map-id"}),i("design:type",Object)],t.LitGoogleMap.prototype,"mapId",void 0),t.LitGoogleMap=e([ht("lit-google-map")],t.LitGoogleMap),t.LitGoogleMapCircle=class extends at{constructor(){super(...arguments),this.centerLatitude=-34.397,this.centerLongitude=150.644,this.radius=1e5,this.fillColor="#FF0000",this.fillOpacity=.35,this.strokeColor="#FF0000",this.strokeOpacity=.8,this.strokeWeight=2,this.map=null,this.circle=null}attributeChangedCallback(t,e,i){var s;switch(super.attributeChangedCallback(t,e,i),t){case"center-latitude":case"center-longitude":this.updateCenter();break;case"radius":null===(s=this.circle)||void 0===s||s.setRadius(this.radius)}}updateCenter(){var t;null===(t=this.circle)||void 0===t||t.setCenter(new google.maps.LatLng(this.centerLatitude,this.centerLongitude))}attachToMap(t){this.map=t,this.mapChanged()}mapChanged(){this.circle&&(this.circle.setMap(null),google.maps.event.clearInstanceListeners(this.circle)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.circle=new google.maps.Circle({map:this.map,strokeColor:this.strokeColor,strokeOpacity:this.strokeOpacity,strokeWeight:this.strokeWeight,fillColor:this.fillColor,fillOpacity:this.fillOpacity,center:{lat:this.centerLatitude,lng:this.centerLongitude},radius:this.radius})}},e([dt({type:Number,attribute:"center-latitude"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"centerLatitude",void 0),e([dt({type:Number,attribute:"center-longitude"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"centerLongitude",void 0),e([dt({type:Number}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"radius",void 0),e([dt({type:String,attribute:"fill-color"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"fillColor",void 0),e([dt({type:Number,attribute:"fill-opacity"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"fillOpacity",void 0),e([dt({type:String,attribute:"stroke-color"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"strokeColor",void 0),e([dt({type:Number,attribute:"stroke-opacity"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"strokeOpacity",void 0),e([dt({type:Number,attribute:"stroke-weight"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"strokeWeight",void 0),t.LitGoogleMapCircle=e([ht("lit-google-map-circle")],t.LitGoogleMapCircle),t.LitGoogleMapMarker=class extends at{constructor(){super(...arguments),this.latitude=0,this.longitude=0,this.zIndex=0,this.open=!1,this.id=null,this.glyph=null,this.glyphColor=null,this.background=null,this.borderColor=null,this.scale=null,this.map=null,this.marker=null,this.pin=null}attributeChangedCallback(t,e,i){switch(super.attributeChangedCallback(t,e,i),t){case"open":this.openChanged();break;case"latitude":case"longitude":this.updatePosition();break;case"glyph":this.pin&&(this.pin.glyph=this.glyph);break;case"glyphColor":this.pin&&(this.pin.glyphColor=this.glyphColor);break;case"background":this.pin&&(this.pin.background=this.background);break;case"borderColor":this.pin&&(this.pin.borderColor=this.borderColor);break;case"scale":this.pin&&(this.pin.scale=this.scale);break;case"z-index":this.marker&&(this.marker.zIndex=this.zIndex)}}openChanged(){this.info&&(this.open?(this.info.open(this.map,this.marker),this.dispatchEvent(new CustomEvent("google-map-marker-open",{bubbles:!0}))):(this.info.close(),this.dispatchEvent(new CustomEvent("google-map-marker-close",{bubbles:!0}))))}updatePosition(){this.marker&&(this.marker.position=new google.maps.LatLng(this.latitude,this.longitude))}changeMap(t){this.map=t,this.mapChanged()}mapChanged(){this.marker&&(this.marker.map=null,google.maps.event.clearInstanceListeners(this.marker)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.pin=new google.maps.marker.PinElement({glyph:this.glyph,glyphColor:this.glyphColor,background:this.background,borderColor:this.borderColor,scale:this.scale}),this.marker=new google.maps.marker.AdvancedMarkerElement({map:this.map,position:{lat:this.latitude,lng:this.longitude},content:this.pin.element,zIndex:this.zIndex,gmpClickable:!0}),this.marker.element.addEventListener("mouseover",(()=>{this.dispatchEvent(new CustomEvent("mouseover",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.marker.element.addEventListener("mouseout",(()=>{this.dispatchEvent(new CustomEvent("mouseout",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.marker.addListener("click",(()=>{this.dispatchEvent(new CustomEvent("click",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.contentChanged()}contentChanged(){this.contentObserver&&this.contentObserver.disconnect(),this.contentObserver=new MutationObserver(this.contentChanged.bind(this)),this.contentObserver.observe(this,{childList:!0,subtree:!0});const t=this.innerHTML.trim();t?(this.info||(this.info=new google.maps.InfoWindow,this.openInfoHandler=google.maps.event.addListener(this.marker,"click",function(){this.open=!0}.bind(this)),this.closeInfoHandler=google.maps.event.addListener(this.info,"closeclick",function(){this.open=!1}.bind(this))),this.info.setContent(t)):this.info&&(google.maps.event.removeListener(this.openInfoHandler),google.maps.event.removeListener(this.closeInfoHandler),this.info=null)}},e([dt({type:Number,reflect:!0}),i("design:type",Object)],t.LitGoogleMapMarker.prototype,"latitude",void 0),e([dt({type:Number,reflect:!0}),i("design:type",Object)],t.LitGoogleMapMarker.prototype,"longitude",void 0),e([dt({type:Number,reflect:!0,attribute:"z-index"}),i("design:type",Object)],t.LitGoogleMapMarker.prototype,"zIndex",void 0),e([dt({type:Boolean,reflect:!0}),i("design:type",Object)],t.LitGoogleMapMarker.prototype,"open",void 0),e([dt({type:String,reflect:!0}),i("design:type",String)],t.LitGoogleMapMarker.prototype,"id",void 0),e([dt({type:String,reflect:!0}),i("design:type",String)],t.LitGoogleMapMarker.prototype,"glyph",void 0),e([dt({type:String,reflect:!0}),i("design:type",String)],t.LitGoogleMapMarker.prototype,"glyphColor",void 0),e([dt({type:String,reflect:!0}),i("design:type",String)],t.LitGoogleMapMarker.prototype,"background",void 0),e([dt({type:String,reflect:!0}),i("design:type",String)],t.LitGoogleMapMarker.prototype,"borderColor",void 0),e([dt({type:Number,reflect:!0}),i("design:type",Number)],t.LitGoogleMapMarker.prototype,"scale",void 0),t.LitGoogleMapMarker=e([ht("lit-google-map-marker")],t.LitGoogleMapMarker),t.LitGoogleMapPolygon=class extends at{constructor(){super(...arguments),this.paths=[],this.fillColor="#FF0000",this.fillOpacity=.35,this.strokeColor="#FF0000",this.strokeOpacity=.8,this.strokeWeight=2,this.map=null,this.polygon=null}attachToMap(t){this.map=t,this.mapChanged()}mapChanged(){this.polygon&&(this.polygon.setMap(null),google.maps.event.clearInstanceListeners(this.polygon)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.polygon=new google.maps.Polygon({map:this.map,strokeColor:this.strokeColor,strokeOpacity:this.strokeOpacity,strokeWeight:this.strokeWeight,fillColor:this.fillColor,fillOpacity:this.fillOpacity,paths:this.paths})}},e([dt({type:Array}),i("design:type",Array)],t.LitGoogleMapPolygon.prototype,"paths",void 0),e([dt({type:String,attribute:"fill-color"}),i("design:type",Object)],t.LitGoogleMapPolygon.prototype,"fillColor",void 0),e([dt({type:Number,attribute:"fill-opacity"}),i("design:type",Object)],t.LitGoogleMapPolygon.prototype,"fillOpacity",void 0),e([dt({type:String,attribute:"stroke-color"}),i("design:type",Object)],t.LitGoogleMapPolygon.prototype,"strokeColor",void 0),e([dt({type:Number,attribute:"stroke-opacity"}),i("design:type",Object)],t.LitGoogleMapPolygon.prototype,"strokeOpacity",void 0),e([dt({type:Number,attribute:"stroke-weight"}),i("design:type",Object)],t.LitGoogleMapPolygon.prototype,"strokeWeight",void 0),t.LitGoogleMapPolygon=e([ht("lit-google-map-polygon")],t.LitGoogleMapPolygon);class ut{constructor(){this.apiMap={}}require(t,e,i){const s=this.nameFromUrl(t);this.apiMap[s]||(this.apiMap[s]=new gt(s,t,i)),this.apiMap[s].requestNotify(e)}static getInstance(){return ut.instance||(ut.instance=new ut),ut.instance}nameFromUrl(t){return`${t.replace(/[:/%?&.=\-,]/g,"_")}_api`}}class gt{constructor(t,e,i){this.callbackMacro="%%callback%%",this.loaded=!1,this.script=null,this.notifiers=[];let s=e,o=i;if(!o){if(!(s.indexOf(this.callbackMacro)>=0))return void console.error("ScriptLoader class: a %%callback%% parameter is required in libraryUrl");o=`${t}_loaded`,s=s.replace(this.callbackMacro,o)}this.callbackName=o,window[this.callbackName]=this.success.bind(this),this.addScript(s)}addScript(t){const e=document.createElement("script");e.src=t,e.onerror=this.handleError.bind(this);const i=document.querySelector("script")||document.body;i.parentNode.insertBefore(e,i),this.script=e}removeScript(){this.script.parentNode&&this.script.parentNode.removeChild(this.script),this.script=null}handleError(t){this.error=new Error("Library failed to load"),this.notifyAll(),this.cleanup()}success(...t){this.loaded=!0,this.result=t,this.notifyAll(),this.cleanup()}cleanup(){delete window[this.callbackName]}notifyAll(){this.notifiers.forEach(function(t){t(this.error,this.result)}.bind(this)),this.notifiers=[]}requestNotify(t){this.loaded||this.error?t(this.error,this.result):this.notifiers.push(t)}}class mt extends at{constructor(){super(...arguments),this.libraryLoaded=!1,this.libraryErrorMessage=null,this.isReady=!1}get callbackName(){return null}libraryUrlChanged(){this.isReady&&null!=this.libraryUrl&&this.loadLibrary()}libraryLoadCallback(t,e){t?(console.warn("Library load failed:",t.message),this.libraryErrorMessage=t.message):(this.libraryErrorMessage=null,this.libraryLoaded=!0,null!=this.notifyEvent&&this.dispatchEvent(new CustomEvent(this.notifyEvent,{detail:e,composed:!0})))}loadLibrary(){ut.getInstance().require(this.libraryUrl,this.libraryLoadCallback.bind(this),this.callbackName)}connectedCallback(){super.connectedCallback(),this.isReady=!0,null!=this.libraryUrl&&this.loadLibrary()}}t.LitGoogleMapsApi=class extends mt{constructor(){super(...arguments),this.apiKey="",this.clientId="",this.mapsUrl="https://maps.googleapis.com/maps/api/js?callback=%%callback%%",this.version="3.39",this.language="",this.mapId=""}get libraryUrl(){return this.computeUrl(this.mapsUrl,this.version,this.apiKey,this.clientId,this.language,this.mapId)}get notifyEvent(){return"api-load"}computeUrl(t,e,i,s,o,r){let n=`${t}&v=${e}`;if(n+="&libraries=drawing,geometry,places,visualization,marker",i&&!s&&(n+=`&key=${i}`),s&&(n+=`&client=${s}`),!i&&!s){const t="No Google Maps API Key or Client ID specified. See https://developers.google.com/maps/documentation/javascript/get-api-key for instructions to get started with a key or client id.";console.warn(t)}return o&&(n+=`&language=${o}`),r&&(n+=`&map_ids=${r}`),n}},e([dt({type:String,attribute:"api-key"}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"apiKey",void 0),e([dt({type:String,attribute:"client-id"}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"clientId",void 0),e([dt({type:String,attribute:"maps-url"}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"mapsUrl",void 0),e([dt({type:String}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"version",void 0),e([dt({type:String}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"language",void 0),e([dt({type:String,attribute:"map-id"}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"mapId",void 0),t.LitGoogleMapsApi=e([ht("lit-google-maps-api")],t.LitGoogleMapsApi);class yt{constructor(t){this.multi=!1,this.selection=[],this.selectCallback=t}get(){return this.multi?this.selection.slice():this.selection[0]}clear(t){for(const e of this.selection.slice())(!t||t.indexOf(e)<0)&&this.setItemSelected(e,!1)}isSelected(t){return this.selection.indexOf(t)>=0}setItemSelected(t,e){if(null!=t&&e!==this.isSelected(t)){if(e)this.selection.push(t);else{const e=this.selection.indexOf(t);e>=0&&this.selection.splice(e,1)}this.selectCallback&&this.selectCallback(t,e)}}select(t){this.multi?this.toggle(t):this.get()!==t&&(this.setItemSelected(this.get(),!1),this.setItemSelected(t,!0))}toggle(t){this.setItemSelected(t,!this.isSelected(t))}}return t.LitSelector=class extends at{constructor(){super(...arguments),this.activateEvent="tap",this.selectedAttribute=null,this.selected=null,this._selection=new yt(((t,e)=>this.applySelection(t,e))),this._items=[]}get items(){return this._items}connectedCallback(){super.connectedCallback(),this.addEventListener("slotchange",(t=>{t.stopPropagation(),this.updateItems(),this.dispatchEvent(new CustomEvent("selector-items-changed",{detail:{},composed:!0}))})),this.addListener(this.activateEvent)}disconnectedCallback(){super.disconnectedCallback(),this.removeListener(this.activateEvent)}attributeChangedCallback(t,e,i){if(super.attributeChangedCallback(t,e,i),"selected"===t)this.updateSelected()}applySelection(t,e){this.selectedAttribute&&t instanceof Element&&e!==t.hasAttribute(this.selectedAttribute)&&t.toggleAttribute(this.selectedAttribute)}updateItems(){var t;const e=this.querySelector("slot");this._items=null!==(t=null==e?void 0:e.assignedNodes())&&void 0!==t?t:[]}addListener(t){this.addEventListener(t,(t=>this.activateHandler(t)))}removeListener(t){this.removeEventListener(t,(t=>this.activateHandler(t)))}activateHandler(t){let e=t.target;const i=this.items;for(;e&&e!==this;){const t=i.indexOf(e);if(t>=0){const i=this.indexToValue(t);return void this.itemActivate(i,e)}e=e.parentNode}}itemActivate(t,e){this.dispatchEvent(new CustomEvent("selector-item-activate",{detail:{selected:t,item:e},composed:!0,cancelable:!0}))&&this.select(t)}select(t){this.selected=t}updateSelected(){this.selectSelected(this.selected)}selectSelected(t){if(!this._items)return;const e=this.valueToItem(this.selected);e?this._selection.select(e):this._selection.clear()}valueToItem(t){return null==t?null:this._items[this.valueToIndex(t)]}valueToIndex(t){return Number(t)}indexToValue(t){return t}indexOf(t){return this._items?this._items.indexOf(t):-1}},e([dt({type:String,attribute:"activate-event"}),i("design:type",Object)],t.LitSelector.prototype,"activateEvent",void 0),e([dt({type:String,attribute:"selected-attribute"}),i("design:type",String)],t.LitSelector.prototype,"selectedAttribute",void 0),e([dt({type:Number,reflect:!0}),i("design:type",Object)],t.LitSelector.prototype,"selected",void 0),t.LitSelector=e([ht("lit-selector")],t.LitSelector),t}({});
+ `,e([dt({type:String,attribute:"api-key"}),i("design:type",Object)],t.LitGoogleMap.prototype,"apiKey",void 0),e([dt({type:String}),i("design:type",Object)],t.LitGoogleMap.prototype,"version",void 0),e([dt({type:Object}),i("design:type",Object)],t.LitGoogleMap.prototype,"styles",void 0),e([dt({type:Number}),i("design:type",Object)],t.LitGoogleMap.prototype,"zoom",void 0),e([dt({type:Boolean,attribute:"fit-to-markers"}),i("design:type",Object)],t.LitGoogleMap.prototype,"fitToMarkers",void 0),e([dt({type:String,attribute:"map-type"}),i("design:type",Object)],t.LitGoogleMap.prototype,"mapType",void 0),e([dt({type:Number,attribute:"center-latitude"}),i("design:type",Object)],t.LitGoogleMap.prototype,"centerLatitude",void 0),e([dt({type:Number,attribute:"center-longitude"}),i("design:type",Object)],t.LitGoogleMap.prototype,"centerLongitude",void 0),e([dt({type:String}),i("design:type",Object)],t.LitGoogleMap.prototype,"language",void 0),e([dt({type:String,attribute:"map-id"}),i("design:type",Object)],t.LitGoogleMap.prototype,"mapId",void 0),t.LitGoogleMap=e([ht("lit-google-map")],t.LitGoogleMap),t.LitGoogleMapCircle=class extends at{constructor(){super(...arguments),this.centerLatitude=-34.397,this.centerLongitude=150.644,this.radius=1e5,this.fillColor="#FF0000",this.fillOpacity=.35,this.strokeColor="#FF0000",this.strokeOpacity=.8,this.strokeWeight=2,this.map=null,this.circle=null}attributeChangedCallback(t,e,i){var s;switch(super.attributeChangedCallback(t,e,i),t){case"center-latitude":case"center-longitude":this.updateCenter();break;case"radius":null===(s=this.circle)||void 0===s||s.setRadius(this.radius)}}updateCenter(){var t;null===(t=this.circle)||void 0===t||t.setCenter(new google.maps.LatLng(this.centerLatitude,this.centerLongitude))}attachToMap(t){this.map=t,this.mapChanged()}mapChanged(){this.circle&&(this.circle.setMap(null),google.maps.event.clearInstanceListeners(this.circle)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.circle=new google.maps.Circle({map:this.map,strokeColor:this.strokeColor,strokeOpacity:this.strokeOpacity,strokeWeight:this.strokeWeight,fillColor:this.fillColor,fillOpacity:this.fillOpacity,center:{lat:this.centerLatitude,lng:this.centerLongitude},radius:this.radius})}},e([dt({type:Number,attribute:"center-latitude"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"centerLatitude",void 0),e([dt({type:Number,attribute:"center-longitude"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"centerLongitude",void 0),e([dt({type:Number}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"radius",void 0),e([dt({type:String,attribute:"fill-color"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"fillColor",void 0),e([dt({type:Number,attribute:"fill-opacity"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"fillOpacity",void 0),e([dt({type:String,attribute:"stroke-color"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"strokeColor",void 0),e([dt({type:Number,attribute:"stroke-opacity"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"strokeOpacity",void 0),e([dt({type:Number,attribute:"stroke-weight"}),i("design:type",Object)],t.LitGoogleMapCircle.prototype,"strokeWeight",void 0),t.LitGoogleMapCircle=e([ht("lit-google-map-circle")],t.LitGoogleMapCircle),t.LitGoogleMapLocationButton=class extends at{constructor(){super(...arguments),this.position="RIGHT_BOTTOM",this.label="My Location",this.disabled=!1,this.map=null,this.controlDiv=null,this.controlButton=null,this.isRequesting=!1}changeMap(t){this.map=t,this.mapChanged()}mapChanged(){this.controlDiv&&this.map&&(this.controlDiv=null,this.controlButton=null),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.controlDiv=this.createControlButton();const t=google.maps.ControlPosition[this.position];void 0!==t&&this.map.controls[t].push(this.controlDiv)}createControlButton(){const t=document.createElement("div");t.style.margin="10px";const e=document.createElement("button");return e.type="button",e.title=this.label,e.setAttribute("aria-label",this.label),e.innerHTML='\n \n ',Object.assign(e.style,{backgroundColor:"#fff",border:"0",borderRadius:"2px",boxShadow:"0 1px 4px rgba(0,0,0,0.3)",cursor:"pointer",padding:"10px",display:"flex",alignItems:"center",justifyContent:"center",width:"40px",height:"40px",color:"#666"}),e.addEventListener("mouseenter",(()=>{this.disabled||this.isRequesting||(e.style.backgroundColor="#f8f8f8")})),e.addEventListener("mouseleave",(()=>{this.disabled||this.isRequesting||(e.style.backgroundColor="#fff")})),e.addEventListener("click",(()=>{this.disabled||this.isRequesting||this.handleLocationRequest()})),this.controlButton=e,t.appendChild(e),t}async handleLocationRequest(){if(navigator.geolocation){this.isRequesting=!0,this.setLoadingState(!0),this.dispatchEvent(new CustomEvent("location-requested",{bubbles:!0,composed:!0}));try{const t=await this.getCurrentPosition(),e=t.coords.latitude,i=t.coords.longitude;this.map.setCenter({lat:e,lng:i}),this.map.setZoom(14),this.dispatchEvent(new CustomEvent("location-found",{detail:{lat:e,lng:i},bubbles:!0,composed:!0}))}catch(t){let e="Unable to retrieve your location",i=-1;t instanceof GeolocationPositionError&&(i=t.code,t.code===t.PERMISSION_DENIED?e="Location access denied. Please enable location permissions.":t.code===t.TIMEOUT?e="Location request timed out. Please try again.":t.code===t.POSITION_UNAVAILABLE&&(e="Location information is unavailable.")),this.dispatchEvent(new CustomEvent("location-error",{detail:{code:i,message:e},bubbles:!0,composed:!0}))}finally{this.isRequesting=!1,this.setLoadingState(!1)}}else this.dispatchEvent(new CustomEvent("location-error",{detail:{code:-1,message:"Geolocation is not supported by your browser"},bubbles:!0,composed:!0}))}getCurrentPosition(){return new Promise(((t,e)=>{navigator.geolocation.getCurrentPosition(t,e,{timeout:1e4,enableHighAccuracy:!0})}))}setLoadingState(t){if(this.controlButton)if(t){this.controlButton.style.backgroundColor="#f0f0f0",this.controlButton.style.cursor="wait";const t=this.controlButton.querySelector("svg");if(t){t.style.animation="spin 1s linear infinite";const e=document.createElement("style");e.textContent="\n @keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n ",document.querySelector("style[data-location-button-spin]")||(e.setAttribute("data-location-button-spin","true"),document.head.appendChild(e))}}else{this.controlButton.style.backgroundColor="#fff",this.controlButton.style.cursor="pointer";const t=this.controlButton.querySelector("svg");t&&(t.style.animation="")}}attributeChangedCallback(t,e,i){super.attributeChangedCallback(t,e,i),"disabled"===t&&this.controlButton&&(this.disabled?(this.controlButton.style.backgroundColor="#f0f0f0",this.controlButton.style.cursor="not-allowed",this.controlButton.style.opacity="0.6"):(this.controlButton.style.backgroundColor="#fff",this.controlButton.style.cursor="pointer",this.controlButton.style.opacity="1"))}},e([dt({type:String,reflect:!0}),i("design:type",Object)],t.LitGoogleMapLocationButton.prototype,"position",void 0),e([dt({type:String,reflect:!0}),i("design:type",Object)],t.LitGoogleMapLocationButton.prototype,"label",void 0),e([dt({type:Boolean,reflect:!0}),i("design:type",Object)],t.LitGoogleMapLocationButton.prototype,"disabled",void 0),t.LitGoogleMapLocationButton=e([ht("lit-google-map-location-button")],t.LitGoogleMapLocationButton),t.LitGoogleMapMarker=class extends at{constructor(){super(...arguments),this.latitude=0,this.longitude=0,this.zIndex=0,this.open=!1,this.id=null,this.glyph=null,this.glyphColor=null,this.background=null,this.borderColor=null,this.scale=null,this.map=null,this.marker=null,this.pin=null}attributeChangedCallback(t,e,i){switch(super.attributeChangedCallback(t,e,i),t){case"open":this.openChanged();break;case"latitude":case"longitude":this.updatePosition();break;case"glyph":this.pin&&(this.pin.glyph=this.glyph);break;case"glyphColor":this.pin&&(this.pin.glyphColor=this.glyphColor);break;case"background":this.pin&&(this.pin.background=this.background);break;case"borderColor":this.pin&&(this.pin.borderColor=this.borderColor);break;case"scale":this.pin&&(this.pin.scale=this.scale);break;case"z-index":this.marker&&(this.marker.zIndex=this.zIndex)}}openChanged(){this.info&&(this.open?(this.info.open(this.map,this.marker),this.dispatchEvent(new CustomEvent("google-map-marker-open",{bubbles:!0}))):(this.info.close(),this.dispatchEvent(new CustomEvent("google-map-marker-close",{bubbles:!0}))))}updatePosition(){this.marker&&(this.marker.position=new google.maps.LatLng(this.latitude,this.longitude))}changeMap(t){this.map=t,this.mapChanged()}mapChanged(){this.marker&&(this.marker.map=null,google.maps.event.clearInstanceListeners(this.marker)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.pin=new google.maps.marker.PinElement({glyph:this.glyph,glyphColor:this.glyphColor,background:this.background,borderColor:this.borderColor,scale:this.scale}),this.marker=new google.maps.marker.AdvancedMarkerElement({map:this.map,position:{lat:this.latitude,lng:this.longitude},content:this.pin.element,zIndex:this.zIndex,gmpClickable:!0}),this.marker.element.addEventListener("mouseover",(()=>{this.dispatchEvent(new CustomEvent("mouseover",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.marker.element.addEventListener("mouseout",(()=>{this.dispatchEvent(new CustomEvent("mouseout",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.marker.addListener("click",(()=>{this.dispatchEvent(new CustomEvent("click",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.contentChanged()}contentChanged(){this.contentObserver&&this.contentObserver.disconnect(),this.contentObserver=new MutationObserver(this.contentChanged.bind(this)),this.contentObserver.observe(this,{childList:!0,subtree:!0});const t=this.innerHTML.trim();t?(this.info||(this.info=new google.maps.InfoWindow,this.openInfoHandler=google.maps.event.addListener(this.marker,"click",function(){this.open=!0}.bind(this)),this.closeInfoHandler=google.maps.event.addListener(this.info,"closeclick",function(){this.open=!1}.bind(this))),this.info.setContent(t)):this.info&&(google.maps.event.removeListener(this.openInfoHandler),google.maps.event.removeListener(this.closeInfoHandler),this.info=null)}},e([dt({type:Number,reflect:!0}),i("design:type",Object)],t.LitGoogleMapMarker.prototype,"latitude",void 0),e([dt({type:Number,reflect:!0}),i("design:type",Object)],t.LitGoogleMapMarker.prototype,"longitude",void 0),e([dt({type:Number,reflect:!0,attribute:"z-index"}),i("design:type",Object)],t.LitGoogleMapMarker.prototype,"zIndex",void 0),e([dt({type:Boolean,reflect:!0}),i("design:type",Object)],t.LitGoogleMapMarker.prototype,"open",void 0),e([dt({type:String,reflect:!0}),i("design:type",String)],t.LitGoogleMapMarker.prototype,"id",void 0),e([dt({type:String,reflect:!0}),i("design:type",String)],t.LitGoogleMapMarker.prototype,"glyph",void 0),e([dt({type:String,reflect:!0}),i("design:type",String)],t.LitGoogleMapMarker.prototype,"glyphColor",void 0),e([dt({type:String,reflect:!0}),i("design:type",String)],t.LitGoogleMapMarker.prototype,"background",void 0),e([dt({type:String,reflect:!0}),i("design:type",String)],t.LitGoogleMapMarker.prototype,"borderColor",void 0),e([dt({type:Number,reflect:!0}),i("design:type",Number)],t.LitGoogleMapMarker.prototype,"scale",void 0),t.LitGoogleMapMarker=e([ht("lit-google-map-marker")],t.LitGoogleMapMarker),t.LitGoogleMapPolygon=class extends at{constructor(){super(...arguments),this.paths=[],this.fillColor="#FF0000",this.fillOpacity=.35,this.strokeColor="#FF0000",this.strokeOpacity=.8,this.strokeWeight=2,this.map=null,this.polygon=null}attachToMap(t){this.map=t,this.mapChanged()}mapChanged(){this.polygon&&(this.polygon.setMap(null),google.maps.event.clearInstanceListeners(this.polygon)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.polygon=new google.maps.Polygon({map:this.map,strokeColor:this.strokeColor,strokeOpacity:this.strokeOpacity,strokeWeight:this.strokeWeight,fillColor:this.fillColor,fillOpacity:this.fillOpacity,paths:this.paths})}},e([dt({type:Array}),i("design:type",Array)],t.LitGoogleMapPolygon.prototype,"paths",void 0),e([dt({type:String,attribute:"fill-color"}),i("design:type",Object)],t.LitGoogleMapPolygon.prototype,"fillColor",void 0),e([dt({type:Number,attribute:"fill-opacity"}),i("design:type",Object)],t.LitGoogleMapPolygon.prototype,"fillOpacity",void 0),e([dt({type:String,attribute:"stroke-color"}),i("design:type",Object)],t.LitGoogleMapPolygon.prototype,"strokeColor",void 0),e([dt({type:Number,attribute:"stroke-opacity"}),i("design:type",Object)],t.LitGoogleMapPolygon.prototype,"strokeOpacity",void 0),e([dt({type:Number,attribute:"stroke-weight"}),i("design:type",Object)],t.LitGoogleMapPolygon.prototype,"strokeWeight",void 0),t.LitGoogleMapPolygon=e([ht("lit-google-map-polygon")],t.LitGoogleMapPolygon);class ut{constructor(){this.apiMap={}}require(t,e,i){const s=this.nameFromUrl(t);this.apiMap[s]||(this.apiMap[s]=new gt(s,t,i)),this.apiMap[s].requestNotify(e)}static getInstance(){return ut.instance||(ut.instance=new ut),ut.instance}nameFromUrl(t){return`${t.replace(/[:/%?&.=\-,]/g,"_")}_api`}}class gt{constructor(t,e,i){this.callbackMacro="%%callback%%",this.loaded=!1,this.script=null,this.notifiers=[];let s=e,o=i;if(!o){if(!(s.indexOf(this.callbackMacro)>=0))return void console.error("ScriptLoader class: a %%callback%% parameter is required in libraryUrl");o=`${t}_loaded`,s=s.replace(this.callbackMacro,o)}this.callbackName=o,window[this.callbackName]=this.success.bind(this),this.addScript(s)}addScript(t){const e=document.createElement("script");e.src=t,e.onerror=this.handleError.bind(this);const i=document.querySelector("script")||document.body;i.parentNode.insertBefore(e,i),this.script=e}removeScript(){this.script.parentNode&&this.script.parentNode.removeChild(this.script),this.script=null}handleError(t){this.error=new Error("Library failed to load"),this.notifyAll(),this.cleanup()}success(...t){this.loaded=!0,this.result=t,this.notifyAll(),this.cleanup()}cleanup(){delete window[this.callbackName]}notifyAll(){this.notifiers.forEach(function(t){t(this.error,this.result)}.bind(this)),this.notifiers=[]}requestNotify(t){this.loaded||this.error?t(this.error,this.result):this.notifiers.push(t)}}class mt extends at{constructor(){super(...arguments),this.libraryLoaded=!1,this.libraryErrorMessage=null,this.isReady=!1}get callbackName(){return null}libraryUrlChanged(){this.isReady&&null!=this.libraryUrl&&this.loadLibrary()}libraryLoadCallback(t,e){t?(console.warn("Library load failed:",t.message),this.libraryErrorMessage=t.message):(this.libraryErrorMessage=null,this.libraryLoaded=!0,null!=this.notifyEvent&&this.dispatchEvent(new CustomEvent(this.notifyEvent,{detail:e,composed:!0})))}loadLibrary(){ut.getInstance().require(this.libraryUrl,this.libraryLoadCallback.bind(this),this.callbackName)}connectedCallback(){super.connectedCallback(),this.isReady=!0,null!=this.libraryUrl&&this.loadLibrary()}}t.LitGoogleMapsApi=class extends mt{constructor(){super(...arguments),this.apiKey="",this.clientId="",this.mapsUrl="https://maps.googleapis.com/maps/api/js?callback=%%callback%%",this.version="3.39",this.language="",this.mapId=""}get libraryUrl(){return this.computeUrl(this.mapsUrl,this.version,this.apiKey,this.clientId,this.language,this.mapId)}get notifyEvent(){return"api-load"}computeUrl(t,e,i,s,o,r){let n=`${t}&v=${e}`;if(n+="&libraries=drawing,geometry,places,visualization,marker",i&&!s&&(n+=`&key=${i}`),s&&(n+=`&client=${s}`),!i&&!s){const t="No Google Maps API Key or Client ID specified. See https://developers.google.com/maps/documentation/javascript/get-api-key for instructions to get started with a key or client id.";console.warn(t)}return o&&(n+=`&language=${o}`),r&&(n+=`&map_ids=${r}`),n}},e([dt({type:String,attribute:"api-key"}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"apiKey",void 0),e([dt({type:String,attribute:"client-id"}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"clientId",void 0),e([dt({type:String,attribute:"maps-url"}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"mapsUrl",void 0),e([dt({type:String}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"version",void 0),e([dt({type:String}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"language",void 0),e([dt({type:String,attribute:"map-id"}),i("design:type",Object)],t.LitGoogleMapsApi.prototype,"mapId",void 0),t.LitGoogleMapsApi=e([ht("lit-google-maps-api")],t.LitGoogleMapsApi);class yt{constructor(t){this.multi=!1,this.selection=[],this.selectCallback=t}get(){return this.multi?this.selection.slice():this.selection[0]}clear(t){for(const e of this.selection.slice())(!t||t.indexOf(e)<0)&&this.setItemSelected(e,!1)}isSelected(t){return this.selection.indexOf(t)>=0}setItemSelected(t,e){if(null!=t&&e!==this.isSelected(t)){if(e)this.selection.push(t);else{const e=this.selection.indexOf(t);e>=0&&this.selection.splice(e,1)}this.selectCallback&&this.selectCallback(t,e)}}select(t){this.multi?this.toggle(t):this.get()!==t&&(this.setItemSelected(this.get(),!1),this.setItemSelected(t,!0))}toggle(t){this.setItemSelected(t,!this.isSelected(t))}}return t.LitSelector=class extends at{constructor(){super(...arguments),this.activateEvent="tap",this.selectedAttribute=null,this.selected=null,this._selection=new yt(((t,e)=>this.applySelection(t,e))),this._items=[]}get items(){return this._items}connectedCallback(){super.connectedCallback(),this.addEventListener("slotchange",(t=>{t.stopPropagation(),this.updateItems(),this.dispatchEvent(new CustomEvent("selector-items-changed",{detail:{},composed:!0}))})),this.addListener(this.activateEvent)}disconnectedCallback(){super.disconnectedCallback(),this.removeListener(this.activateEvent)}attributeChangedCallback(t,e,i){if(super.attributeChangedCallback(t,e,i),"selected"===t)this.updateSelected()}applySelection(t,e){this.selectedAttribute&&t instanceof Element&&e!==t.hasAttribute(this.selectedAttribute)&&t.toggleAttribute(this.selectedAttribute)}updateItems(){var t;const e=this.querySelector("slot");this._items=null!==(t=null==e?void 0:e.assignedNodes())&&void 0!==t?t:[]}addListener(t){this.addEventListener(t,(t=>this.activateHandler(t)))}removeListener(t){this.removeEventListener(t,(t=>this.activateHandler(t)))}activateHandler(t){let e=t.target;const i=this.items;for(;e&&e!==this;){const t=i.indexOf(e);if(t>=0){const i=this.indexToValue(t);return void this.itemActivate(i,e)}e=e.parentNode}}itemActivate(t,e){this.dispatchEvent(new CustomEvent("selector-item-activate",{detail:{selected:t,item:e},composed:!0,cancelable:!0}))&&this.select(t)}select(t){this.selected=t}updateSelected(){this.selectSelected(this.selected)}selectSelected(t){if(!this._items)return;const e=this.valueToItem(this.selected);e?this._selection.select(e):this._selection.clear()}valueToItem(t){return null==t?null:this._items[this.valueToIndex(t)]}valueToIndex(t){return Number(t)}indexToValue(t){return t}indexOf(t){return this._items?this._items.indexOf(t):-1}},e([dt({type:String,attribute:"activate-event"}),i("design:type",Object)],t.LitSelector.prototype,"activateEvent",void 0),e([dt({type:String,attribute:"selected-attribute"}),i("design:type",String)],t.LitSelector.prototype,"selectedAttribute",void 0),e([dt({type:Number,reflect:!0}),i("design:type",Object)],t.LitSelector.prototype,"selected",void 0),t.LitSelector=e([ht("lit-selector")],t.LitSelector),t}({});
diff --git a/dist/lit-google-map.esm.js b/dist/lit-google-map.esm.js
index 1141b9b..f7431e2 100644
--- a/dist/lit-google-map.esm.js
+++ b/dist/lit-google-map.esm.js
@@ -92,6 +92,7 @@ let LitGoogleMap = class LitGoogleMap extends LitElement {
});
this.updateMarkers();
this.updateShapes();
+ this.updateControls();
}
getMapOptions() {
return {
@@ -186,6 +187,15 @@ let LitGoogleMap = class LitGoogleMap extends LitElement {
s.attachToMap(this.map);
}
}
+ updateControls() {
+ const controlsSelector = this.shadowRoot.getElementById("controls-selector");
+ if (!controlsSelector)
+ return;
+ this.controls = controlsSelector.items;
+ for (const c of this.controls) {
+ c.changeMap(this.map);
+ }
+ }
fitToMarkersChanged(retryAttempt = 0) {
if (this.map && this.fitToMarkers && this.markers.length > 0) {
const latLngBounds = new google.maps.LatLngBounds();
@@ -245,6 +255,13 @@ let LitGoogleMap = class LitGoogleMap extends LitElement {
>
+
+
+
`;
}
@@ -400,6 +417,210 @@ LitGoogleMapCircle = __decorate([
customElement("lit-google-map-circle")
], LitGoogleMapCircle);
+let LitGoogleMapLocationButton = class LitGoogleMapLocationButton extends LitElement {
+ constructor() {
+ super(...arguments);
+ this.position = "RIGHT_BOTTOM";
+ this.label = "My Location";
+ this.disabled = false;
+ this.map = null;
+ this.controlDiv = null;
+ this.controlButton = null;
+ this.isRequesting = false;
+ }
+ changeMap(newMap) {
+ this.map = newMap;
+ this.mapChanged();
+ }
+ mapChanged() {
+ if (this.controlDiv && this.map) {
+ this.controlDiv = null;
+ this.controlButton = null;
+ }
+ if (this.map && this.map instanceof google.maps.Map) {
+ this.mapReady();
+ }
+ }
+ mapReady() {
+ this.controlDiv = this.createControlButton();
+ const controlPosition = google.maps.ControlPosition[this.position];
+ if (controlPosition !== undefined) {
+ this.map.controls[controlPosition].push(this.controlDiv);
+ }
+ }
+ createControlButton() {
+ const controlDiv = document.createElement("div");
+ controlDiv.style.margin = "10px";
+ const controlButton = document.createElement("button");
+ controlButton.type = "button";
+ controlButton.title = this.label;
+ controlButton.setAttribute("aria-label", this.label);
+ controlButton.innerHTML = `
+
+ `;
+ Object.assign(controlButton.style, {
+ backgroundColor: "#fff",
+ border: "0",
+ borderRadius: "2px",
+ boxShadow: "0 1px 4px rgba(0,0,0,0.3)",
+ cursor: "pointer",
+ padding: "10px",
+ display: "flex",
+ alignItems: "center",
+ justifyContent: "center",
+ width: "40px",
+ height: "40px",
+ color: "#666",
+ });
+ controlButton.addEventListener("mouseenter", () => {
+ if (!this.disabled && !this.isRequesting) {
+ controlButton.style.backgroundColor = "#f8f8f8";
+ }
+ });
+ controlButton.addEventListener("mouseleave", () => {
+ if (!this.disabled && !this.isRequesting) {
+ controlButton.style.backgroundColor = "#fff";
+ }
+ });
+ controlButton.addEventListener("click", () => {
+ if (!this.disabled && !this.isRequesting) {
+ this.handleLocationRequest();
+ }
+ });
+ this.controlButton = controlButton;
+ controlDiv.appendChild(controlButton);
+ return controlDiv;
+ }
+ async handleLocationRequest() {
+ if (!navigator.geolocation) {
+ this.dispatchEvent(new CustomEvent("location-error", {
+ detail: {
+ code: -1,
+ message: "Geolocation is not supported by your browser",
+ },
+ bubbles: true,
+ composed: true,
+ }));
+ return;
+ }
+ this.isRequesting = true;
+ this.setLoadingState(true);
+ this.dispatchEvent(new CustomEvent("location-requested", {
+ bubbles: true,
+ composed: true,
+ }));
+ try {
+ const position = await this.getCurrentPosition();
+ const lat = position.coords.latitude;
+ const lng = position.coords.longitude;
+ this.map.setCenter({ lat, lng });
+ this.map.setZoom(14);
+ this.dispatchEvent(new CustomEvent("location-found", {
+ detail: { lat, lng },
+ bubbles: true,
+ composed: true,
+ }));
+ }
+ catch (error) {
+ let message = "Unable to retrieve your location";
+ let code = -1;
+ if (error instanceof GeolocationPositionError) {
+ code = error.code;
+ if (error.code === error.PERMISSION_DENIED) {
+ message =
+ "Location access denied. Please enable location permissions.";
+ }
+ else if (error.code === error.TIMEOUT) {
+ message = "Location request timed out. Please try again.";
+ }
+ else if (error.code === error.POSITION_UNAVAILABLE) {
+ message = "Location information is unavailable.";
+ }
+ }
+ this.dispatchEvent(new CustomEvent("location-error", {
+ detail: { code, message },
+ bubbles: true,
+ composed: true,
+ }));
+ }
+ finally {
+ this.isRequesting = false;
+ this.setLoadingState(false);
+ }
+ }
+ getCurrentPosition() {
+ return new Promise((resolve, reject) => {
+ navigator.geolocation.getCurrentPosition(resolve, reject, {
+ timeout: 10000,
+ enableHighAccuracy: true,
+ });
+ });
+ }
+ setLoadingState(loading) {
+ if (!this.controlButton)
+ return;
+ if (loading) {
+ this.controlButton.style.backgroundColor = "#f0f0f0";
+ this.controlButton.style.cursor = "wait";
+ const svg = this.controlButton.querySelector("svg");
+ if (svg) {
+ svg.style.animation = "spin 1s linear infinite";
+ const style = document.createElement("style");
+ style.textContent = `
+ @keyframes spin {
+ from { transform: rotate(0deg); }
+ to { transform: rotate(360deg); }
+ }
+ `;
+ if (!document.querySelector("style[data-location-button-spin]")) {
+ style.setAttribute("data-location-button-spin", "true");
+ document.head.appendChild(style);
+ }
+ }
+ }
+ else {
+ this.controlButton.style.backgroundColor = "#fff";
+ this.controlButton.style.cursor = "pointer";
+ const svg = this.controlButton.querySelector("svg");
+ if (svg) {
+ svg.style.animation = "";
+ }
+ }
+ }
+ attributeChangedCallback(name, oldval, newval) {
+ super.attributeChangedCallback(name, oldval, newval);
+ if (name === "disabled" && this.controlButton) {
+ if (this.disabled) {
+ this.controlButton.style.backgroundColor = "#f0f0f0";
+ this.controlButton.style.cursor = "not-allowed";
+ this.controlButton.style.opacity = "0.6";
+ }
+ else {
+ this.controlButton.style.backgroundColor = "#fff";
+ this.controlButton.style.cursor = "pointer";
+ this.controlButton.style.opacity = "1";
+ }
+ }
+ }
+};
+__decorate([
+ property({ type: String, reflect: true }),
+ __metadata("design:type", Object)
+], LitGoogleMapLocationButton.prototype, "position", void 0);
+__decorate([
+ property({ type: String, reflect: true }),
+ __metadata("design:type", Object)
+], LitGoogleMapLocationButton.prototype, "label", void 0);
+__decorate([
+ property({ type: Boolean, reflect: true }),
+ __metadata("design:type", Object)
+], LitGoogleMapLocationButton.prototype, "disabled", void 0);
+LitGoogleMapLocationButton = __decorate([
+ customElement("lit-google-map-location-button")
+], LitGoogleMapLocationButton);
+
let LitGoogleMapMarker = class LitGoogleMapMarker extends LitElement {
constructor() {
super(...arguments);
@@ -1040,4 +1261,4 @@ LitSelector = __decorate([
customElement("lit-selector")
], LitSelector);
-export { LitGoogleMap, LitGoogleMapCircle, LitGoogleMapMarker, LitGoogleMapPolygon, LitGoogleMapsApi, LitSelector };
+export { LitGoogleMap, LitGoogleMapCircle, LitGoogleMapLocationButton, LitGoogleMapMarker, LitGoogleMapPolygon, LitGoogleMapsApi, LitSelector };
diff --git a/dist/lit-google-map.esm.min.js b/dist/lit-google-map.esm.min.js
index f9edbe7..01a396d 100644
--- a/dist/lit-google-map.esm.min.js
+++ b/dist/lit-google-map.esm.min.js
@@ -1,4 +1,4 @@
-import{__decorate as t,__metadata as e}from"tslib";import{css as i,LitElement as s,html as o}from"lit";import{property as a,customElement as r}from"lit/decorators.js";let n=class extends s{constructor(){super(...arguments),this.apiKey="",this.version="3.48",this.styles={},this.zoom=8,this.fitToMarkers=!1,this.mapType="roadmap",this.centerLatitude=-34.397,this.centerLongitude=150.644,this.language="",this.mapId="DEMO_MAP_ID",this.map=null}attributeChangedCallback(t,e,i){super.attributeChangedCallback(t,e,i),this.map&&e!==i&&null!==i&&("center-latitude"===t||"center-longitude"===t?this.map.setCenter({lat:this.centerLatitude,lng:this.centerLongitude}):"zoom"===t&&this.map.setZoom(this.zoom))}dispatchViewChanged(){this.dispatchEvent(new CustomEvent("view_changed",{detail:{center:this.map.getCenter().toJSON(),zoom:this.map.getZoom()},bubbles:!0,composed:!0}))}initGMap(){if(null!=this.map)return;const t=this.shadowRoot.getElementById("api");null!=t&&!0===t.libraryLoaded&&(this.map=new google.maps.Map(this.shadowRoot.getElementById("map"),this.getMapOptions()),this.map.addListener("bounds_changed",(()=>{this.dispatchEvent(new CustomEvent("bounds_changed",{detail:this.map.getBounds().toJSON(),bubbles:!0,composed:!0}))})),this.map.addListener("tilesloaded",(()=>{this.dispatchEvent(new CustomEvent("tilesloaded",{detail:this.map.getBounds().toJSON(),bubbles:!0,composed:!0}))})),this.map.addListener("center_changed",(()=>{this.dispatchEvent(new CustomEvent("center_changed",{detail:this.map.getCenter().toJSON(),bubbles:!0,composed:!0})),this.dispatchViewChanged()})),this.map.addListener("zoom_changed",(()=>{this.dispatchEvent(new CustomEvent("zoom_changed",{detail:{zoom:this.map.getZoom()},bubbles:!0,composed:!0})),this.dispatchViewChanged()})),this.map.addListener("click",(t=>{"placeId"in t&&(t.stop(),this.dispatchEvent(new CustomEvent("place_click",{detail:{placeId:t.placeId},bubbles:!0,composed:!0})))})),this.updateMarkers(),this.updateShapes())}getMapOptions(){return{zoom:this.zoom,center:{lat:this.centerLatitude,lng:this.centerLongitude},mapTypeId:this.mapType,styles:this.styles,mapId:this.mapId}}mapApiLoaded(){this.initGMap()}connectedCallback(){super.connectedCallback(),this.initGMap()}updated(t){super.updated(t),this.map?((t.has("centerLatitude")||t.has("centerLongitude"))&&(t.get("centerLatitude"),t.get("centerLongitude"),this.map.setCenter({lat:this.centerLatitude,lng:this.centerLongitude})),t.has("zoom")&&(t.get("zoom"),this.map.setZoom(this.zoom))):console.log("Map not initialized yet, skipping update")}attachChildrenToMap(t){if(this.map)for(const e of t)e.changeMap(this.map)}detachChildrenFromMap(t){if(this.map)for(const e of t)e.changeMap(null)}observeMarkers(){this.markerObserverSet||(this.addEventListener("selector-items-changed",(()=>{this.updateMarkers()})),this.markerObserverSet=!0)}updateMarkers(){var t;this.observeMarkers();const e=this.shadowRoot.getElementById("markers-selector");if(!e)return;const i=e.items;if(this.markers&&i.length===this.markers.length){if(0===i.filter((t=>this.markers&&-1===this.markers.indexOf(t))).length)return}const s=this.checkBoundsChanged(this.markers,i),o=(null===(t=this.markers)||void 0===t?void 0:t.filter((t=>-1===i.indexOf(t))))||[];this.detachChildrenFromMap(o),this.markers=i,this.attachChildrenToMap(this.markers),this.fitToMarkers&&s&&this.fitToMarkersChanged()}updateShapes(){const t=this.shadowRoot.getElementById("shapes-selector");if(t){this.shapes=t.items;for(const t of this.shapes)t.attachToMap(this.map)}}fitToMarkersChanged(t=0){if(this.map&&this.fitToMarkers&&this.markers.length>0){const e=new google.maps.LatLngBounds;for(const t of this.markers)e.extend(new google.maps.LatLng(t.latitude,t.longitude));const i=this.getBoundingClientRect();if(0===i.width||0===i.height){console.log("Invalid DOM width or height for lit-google-map");return void setTimeout((()=>{this.fitToMarkersChanged(t+1)}),2**t*100)}this.markers.length>1&&this.map.fitBounds(e,0),this.map.setCenter(e.getCenter())}}checkBoundsChanged(t,e){const i=e.filter((e=>!t||!t.includes(e))),s=null==t?void 0:t.filter((t=>!e||!e.includes(t)));return i.length>0||s.length>0}deselectMarker(t){}deselectShape(t){}render(){return o`
+import{__decorate as t,__metadata as e}from"tslib";import{css as i,LitElement as s,html as o}from"lit";import{property as a,customElement as n}from"lit/decorators.js";let r=class extends s{constructor(){super(...arguments),this.apiKey="",this.version="3.48",this.styles={},this.zoom=8,this.fitToMarkers=!1,this.mapType="roadmap",this.centerLatitude=-34.397,this.centerLongitude=150.644,this.language="",this.mapId="DEMO_MAP_ID",this.map=null}attributeChangedCallback(t,e,i){super.attributeChangedCallback(t,e,i),this.map&&e!==i&&null!==i&&("center-latitude"===t||"center-longitude"===t?this.map.setCenter({lat:this.centerLatitude,lng:this.centerLongitude}):"zoom"===t&&this.map.setZoom(this.zoom))}dispatchViewChanged(){this.dispatchEvent(new CustomEvent("view_changed",{detail:{center:this.map.getCenter().toJSON(),zoom:this.map.getZoom()},bubbles:!0,composed:!0}))}initGMap(){if(null!=this.map)return;const t=this.shadowRoot.getElementById("api");null!=t&&!0===t.libraryLoaded&&(this.map=new google.maps.Map(this.shadowRoot.getElementById("map"),this.getMapOptions()),this.map.addListener("bounds_changed",(()=>{this.dispatchEvent(new CustomEvent("bounds_changed",{detail:this.map.getBounds().toJSON(),bubbles:!0,composed:!0}))})),this.map.addListener("tilesloaded",(()=>{this.dispatchEvent(new CustomEvent("tilesloaded",{detail:this.map.getBounds().toJSON(),bubbles:!0,composed:!0}))})),this.map.addListener("center_changed",(()=>{this.dispatchEvent(new CustomEvent("center_changed",{detail:this.map.getCenter().toJSON(),bubbles:!0,composed:!0})),this.dispatchViewChanged()})),this.map.addListener("zoom_changed",(()=>{this.dispatchEvent(new CustomEvent("zoom_changed",{detail:{zoom:this.map.getZoom()},bubbles:!0,composed:!0})),this.dispatchViewChanged()})),this.map.addListener("click",(t=>{"placeId"in t&&(t.stop(),this.dispatchEvent(new CustomEvent("place_click",{detail:{placeId:t.placeId},bubbles:!0,composed:!0})))})),this.updateMarkers(),this.updateShapes(),this.updateControls())}getMapOptions(){return{zoom:this.zoom,center:{lat:this.centerLatitude,lng:this.centerLongitude},mapTypeId:this.mapType,styles:this.styles,mapId:this.mapId}}mapApiLoaded(){this.initGMap()}connectedCallback(){super.connectedCallback(),this.initGMap()}updated(t){super.updated(t),this.map?((t.has("centerLatitude")||t.has("centerLongitude"))&&(t.get("centerLatitude"),t.get("centerLongitude"),this.map.setCenter({lat:this.centerLatitude,lng:this.centerLongitude})),t.has("zoom")&&(t.get("zoom"),this.map.setZoom(this.zoom))):console.log("Map not initialized yet, skipping update")}attachChildrenToMap(t){if(this.map)for(const e of t)e.changeMap(this.map)}detachChildrenFromMap(t){if(this.map)for(const e of t)e.changeMap(null)}observeMarkers(){this.markerObserverSet||(this.addEventListener("selector-items-changed",(()=>{this.updateMarkers()})),this.markerObserverSet=!0)}updateMarkers(){var t;this.observeMarkers();const e=this.shadowRoot.getElementById("markers-selector");if(!e)return;const i=e.items;if(this.markers&&i.length===this.markers.length){if(0===i.filter((t=>this.markers&&-1===this.markers.indexOf(t))).length)return}const s=this.checkBoundsChanged(this.markers,i),o=(null===(t=this.markers)||void 0===t?void 0:t.filter((t=>-1===i.indexOf(t))))||[];this.detachChildrenFromMap(o),this.markers=i,this.attachChildrenToMap(this.markers),this.fitToMarkers&&s&&this.fitToMarkersChanged()}updateShapes(){const t=this.shadowRoot.getElementById("shapes-selector");if(t){this.shapes=t.items;for(const t of this.shapes)t.attachToMap(this.map)}}updateControls(){const t=this.shadowRoot.getElementById("controls-selector");if(t){this.controls=t.items;for(const t of this.controls)t.changeMap(this.map)}}fitToMarkersChanged(t=0){if(this.map&&this.fitToMarkers&&this.markers.length>0){const e=new google.maps.LatLngBounds;for(const t of this.markers)e.extend(new google.maps.LatLng(t.latitude,t.longitude));const i=this.getBoundingClientRect();if(0===i.width||0===i.height){console.log("Invalid DOM width or height for lit-google-map");return void setTimeout((()=>{this.fitToMarkersChanged(t+1)}),2**t*100)}this.markers.length>1&&this.map.fitBounds(e,0),this.map.setCenter(e.getCenter())}}checkBoundsChanged(t,e){const i=e.filter((e=>!t||!t.includes(e))),s=null==t?void 0:t.filter((t=>!e||!e.includes(t)));return i.length>0||s.length>0}deselectMarker(t){}deselectShape(t){}render(){return o`
+
+
+
- `}};n.styles=i`
+ `}};r.styles=i`
#map {
width: 100%;
height: 100%;
}
- `,t([a({type:String,attribute:"api-key"}),e("design:type",Object)],n.prototype,"apiKey",void 0),t([a({type:String}),e("design:type",Object)],n.prototype,"version",void 0),t([a({type:Object}),e("design:type",Object)],n.prototype,"styles",void 0),t([a({type:Number}),e("design:type",Object)],n.prototype,"zoom",void 0),t([a({type:Boolean,attribute:"fit-to-markers"}),e("design:type",Object)],n.prototype,"fitToMarkers",void 0),t([a({type:String,attribute:"map-type"}),e("design:type",Object)],n.prototype,"mapType",void 0),t([a({type:Number,attribute:"center-latitude"}),e("design:type",Object)],n.prototype,"centerLatitude",void 0),t([a({type:Number,attribute:"center-longitude"}),e("design:type",Object)],n.prototype,"centerLongitude",void 0),t([a({type:String}),e("design:type",Object)],n.prototype,"language",void 0),t([a({type:String,attribute:"map-id"}),e("design:type",Object)],n.prototype,"mapId",void 0),n=t([r("lit-google-map")],n);let l=class extends s{constructor(){super(...arguments),this.centerLatitude=-34.397,this.centerLongitude=150.644,this.radius=1e5,this.fillColor="#FF0000",this.fillOpacity=.35,this.strokeColor="#FF0000",this.strokeOpacity=.8,this.strokeWeight=2,this.map=null,this.circle=null}attributeChangedCallback(t,e,i){var s;switch(super.attributeChangedCallback(t,e,i),t){case"center-latitude":case"center-longitude":this.updateCenter();break;case"radius":null===(s=this.circle)||void 0===s||s.setRadius(this.radius)}}updateCenter(){var t;null===(t=this.circle)||void 0===t||t.setCenter(new google.maps.LatLng(this.centerLatitude,this.centerLongitude))}attachToMap(t){this.map=t,this.mapChanged()}mapChanged(){this.circle&&(this.circle.setMap(null),google.maps.event.clearInstanceListeners(this.circle)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.circle=new google.maps.Circle({map:this.map,strokeColor:this.strokeColor,strokeOpacity:this.strokeOpacity,strokeWeight:this.strokeWeight,fillColor:this.fillColor,fillOpacity:this.fillOpacity,center:{lat:this.centerLatitude,lng:this.centerLongitude},radius:this.radius})}};t([a({type:Number,attribute:"center-latitude"}),e("design:type",Object)],l.prototype,"centerLatitude",void 0),t([a({type:Number,attribute:"center-longitude"}),e("design:type",Object)],l.prototype,"centerLongitude",void 0),t([a({type:Number}),e("design:type",Object)],l.prototype,"radius",void 0),t([a({type:String,attribute:"fill-color"}),e("design:type",Object)],l.prototype,"fillColor",void 0),t([a({type:Number,attribute:"fill-opacity"}),e("design:type",Object)],l.prototype,"fillOpacity",void 0),t([a({type:String,attribute:"stroke-color"}),e("design:type",Object)],l.prototype,"strokeColor",void 0),t([a({type:Number,attribute:"stroke-opacity"}),e("design:type",Object)],l.prototype,"strokeOpacity",void 0),t([a({type:Number,attribute:"stroke-weight"}),e("design:type",Object)],l.prototype,"strokeWeight",void 0),l=t([r("lit-google-map-circle")],l);let p=class extends s{constructor(){super(...arguments),this.latitude=0,this.longitude=0,this.zIndex=0,this.open=!1,this.id=null,this.glyph=null,this.glyphColor=null,this.background=null,this.borderColor=null,this.scale=null,this.map=null,this.marker=null,this.pin=null}attributeChangedCallback(t,e,i){switch(super.attributeChangedCallback(t,e,i),t){case"open":this.openChanged();break;case"latitude":case"longitude":this.updatePosition();break;case"glyph":this.pin&&(this.pin.glyph=this.glyph);break;case"glyphColor":this.pin&&(this.pin.glyphColor=this.glyphColor);break;case"background":this.pin&&(this.pin.background=this.background);break;case"borderColor":this.pin&&(this.pin.borderColor=this.borderColor);break;case"scale":this.pin&&(this.pin.scale=this.scale);break;case"z-index":this.marker&&(this.marker.zIndex=this.zIndex)}}openChanged(){this.info&&(this.open?(this.info.open(this.map,this.marker),this.dispatchEvent(new CustomEvent("google-map-marker-open",{bubbles:!0}))):(this.info.close(),this.dispatchEvent(new CustomEvent("google-map-marker-close",{bubbles:!0}))))}updatePosition(){this.marker&&(this.marker.position=new google.maps.LatLng(this.latitude,this.longitude))}changeMap(t){this.map=t,this.mapChanged()}mapChanged(){this.marker&&(this.marker.map=null,google.maps.event.clearInstanceListeners(this.marker)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.pin=new google.maps.marker.PinElement({glyph:this.glyph,glyphColor:this.glyphColor,background:this.background,borderColor:this.borderColor,scale:this.scale}),this.marker=new google.maps.marker.AdvancedMarkerElement({map:this.map,position:{lat:this.latitude,lng:this.longitude},content:this.pin.element,zIndex:this.zIndex,gmpClickable:!0}),this.marker.element.addEventListener("mouseover",(()=>{this.dispatchEvent(new CustomEvent("mouseover",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.marker.element.addEventListener("mouseout",(()=>{this.dispatchEvent(new CustomEvent("mouseout",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.marker.addListener("click",(()=>{this.dispatchEvent(new CustomEvent("click",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.contentChanged()}contentChanged(){this.contentObserver&&this.contentObserver.disconnect(),this.contentObserver=new MutationObserver(this.contentChanged.bind(this)),this.contentObserver.observe(this,{childList:!0,subtree:!0});const t=this.innerHTML.trim();t?(this.info||(this.info=new google.maps.InfoWindow,this.openInfoHandler=google.maps.event.addListener(this.marker,"click",function(){this.open=!0}.bind(this)),this.closeInfoHandler=google.maps.event.addListener(this.info,"closeclick",function(){this.open=!1}.bind(this))),this.info.setContent(t)):this.info&&(google.maps.event.removeListener(this.openInfoHandler),google.maps.event.removeListener(this.closeInfoHandler),this.info=null)}};t([a({type:Number,reflect:!0}),e("design:type",Object)],p.prototype,"latitude",void 0),t([a({type:Number,reflect:!0}),e("design:type",Object)],p.prototype,"longitude",void 0),t([a({type:Number,reflect:!0,attribute:"z-index"}),e("design:type",Object)],p.prototype,"zIndex",void 0),t([a({type:Boolean,reflect:!0}),e("design:type",Object)],p.prototype,"open",void 0),t([a({type:String,reflect:!0}),e("design:type",String)],p.prototype,"id",void 0),t([a({type:String,reflect:!0}),e("design:type",String)],p.prototype,"glyph",void 0),t([a({type:String,reflect:!0}),e("design:type",String)],p.prototype,"glyphColor",void 0),t([a({type:String,reflect:!0}),e("design:type",String)],p.prototype,"background",void 0),t([a({type:String,reflect:!0}),e("design:type",String)],p.prototype,"borderColor",void 0),t([a({type:Number,reflect:!0}),e("design:type",Number)],p.prototype,"scale",void 0),p=t([r("lit-google-map-marker")],p);let h=class extends s{constructor(){super(...arguments),this.paths=[],this.fillColor="#FF0000",this.fillOpacity=.35,this.strokeColor="#FF0000",this.strokeOpacity=.8,this.strokeWeight=2,this.map=null,this.polygon=null}attachToMap(t){this.map=t,this.mapChanged()}mapChanged(){this.polygon&&(this.polygon.setMap(null),google.maps.event.clearInstanceListeners(this.polygon)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.polygon=new google.maps.Polygon({map:this.map,strokeColor:this.strokeColor,strokeOpacity:this.strokeOpacity,strokeWeight:this.strokeWeight,fillColor:this.fillColor,fillOpacity:this.fillOpacity,paths:this.paths})}};t([a({type:Array}),e("design:type",Array)],h.prototype,"paths",void 0),t([a({type:String,attribute:"fill-color"}),e("design:type",Object)],h.prototype,"fillColor",void 0),t([a({type:Number,attribute:"fill-opacity"}),e("design:type",Object)],h.prototype,"fillOpacity",void 0),t([a({type:String,attribute:"stroke-color"}),e("design:type",Object)],h.prototype,"strokeColor",void 0),t([a({type:Number,attribute:"stroke-opacity"}),e("design:type",Object)],h.prototype,"strokeOpacity",void 0),t([a({type:Number,attribute:"stroke-weight"}),e("design:type",Object)],h.prototype,"strokeWeight",void 0),h=t([r("lit-google-map-polygon")],h);class c{constructor(){this.apiMap={}}require(t,e,i){const s=this.nameFromUrl(t);this.apiMap[s]||(this.apiMap[s]=new d(s,t,i)),this.apiMap[s].requestNotify(e)}static getInstance(){return c.instance||(c.instance=new c),c.instance}nameFromUrl(t){return`${t.replace(/[:/%?&.=\-,]/g,"_")}_api`}}class d{constructor(t,e,i){this.callbackMacro="%%callback%%",this.loaded=!1,this.script=null,this.notifiers=[];let s=e,o=i;if(!o){if(!(s.indexOf(this.callbackMacro)>=0))return void console.error("ScriptLoader class: a %%callback%% parameter is required in libraryUrl");o=`${t}_loaded`,s=s.replace(this.callbackMacro,o)}this.callbackName=o,window[this.callbackName]=this.success.bind(this),this.addScript(s)}addScript(t){const e=document.createElement("script");e.src=t,e.onerror=this.handleError.bind(this);const i=document.querySelector("script")||document.body;i.parentNode.insertBefore(e,i),this.script=e}removeScript(){this.script.parentNode&&this.script.parentNode.removeChild(this.script),this.script=null}handleError(t){this.error=new Error("Library failed to load"),this.notifyAll(),this.cleanup()}success(...t){this.loaded=!0,this.result=t,this.notifyAll(),this.cleanup()}cleanup(){delete window[this.callbackName]}notifyAll(){this.notifiers.forEach(function(t){t(this.error,this.result)}.bind(this)),this.notifiers=[]}requestNotify(t){this.loaded||this.error?t(this.error,this.result):this.notifiers.push(t)}}class g extends s{constructor(){super(...arguments),this.libraryLoaded=!1,this.libraryErrorMessage=null,this.isReady=!1}get callbackName(){return null}libraryUrlChanged(){this.isReady&&null!=this.libraryUrl&&this.loadLibrary()}libraryLoadCallback(t,e){t?(console.warn("Library load failed:",t.message),this.libraryErrorMessage=t.message):(this.libraryErrorMessage=null,this.libraryLoaded=!0,null!=this.notifyEvent&&this.dispatchEvent(new CustomEvent(this.notifyEvent,{detail:e,composed:!0})))}loadLibrary(){c.getInstance().require(this.libraryUrl,this.libraryLoadCallback.bind(this),this.callbackName)}connectedCallback(){super.connectedCallback(),this.isReady=!0,null!=this.libraryUrl&&this.loadLibrary()}}let u=class extends g{constructor(){super(...arguments),this.apiKey="",this.clientId="",this.mapsUrl="https://maps.googleapis.com/maps/api/js?callback=%%callback%%",this.version="3.39",this.language="",this.mapId=""}get libraryUrl(){return this.computeUrl(this.mapsUrl,this.version,this.apiKey,this.clientId,this.language,this.mapId)}get notifyEvent(){return"api-load"}computeUrl(t,e,i,s,o,a){let r=`${t}&v=${e}`;if(r+="&libraries=drawing,geometry,places,visualization,marker",i&&!s&&(r+=`&key=${i}`),s&&(r+=`&client=${s}`),!i&&!s){const t="No Google Maps API Key or Client ID specified. See https://developers.google.com/maps/documentation/javascript/get-api-key for instructions to get started with a key or client id.";console.warn(t)}return o&&(r+=`&language=${o}`),a&&(r+=`&map_ids=${a}`),r}};t([a({type:String,attribute:"api-key"}),e("design:type",Object)],u.prototype,"apiKey",void 0),t([a({type:String,attribute:"client-id"}),e("design:type",Object)],u.prototype,"clientId",void 0),t([a({type:String,attribute:"maps-url"}),e("design:type",Object)],u.prototype,"mapsUrl",void 0),t([a({type:String}),e("design:type",Object)],u.prototype,"version",void 0),t([a({type:String}),e("design:type",Object)],u.prototype,"language",void 0),t([a({type:String,attribute:"map-id"}),e("design:type",Object)],u.prototype,"mapId",void 0),u=t([r("lit-google-maps-api")],u);class m{constructor(t){this.multi=!1,this.selection=[],this.selectCallback=t}get(){return this.multi?this.selection.slice():this.selection[0]}clear(t){for(const e of this.selection.slice())(!t||t.indexOf(e)<0)&&this.setItemSelected(e,!1)}isSelected(t){return this.selection.indexOf(t)>=0}setItemSelected(t,e){if(null!=t&&e!==this.isSelected(t)){if(e)this.selection.push(t);else{const e=this.selection.indexOf(t);e>=0&&this.selection.splice(e,1)}this.selectCallback&&this.selectCallback(t,e)}}select(t){this.multi?this.toggle(t):this.get()!==t&&(this.setItemSelected(this.get(),!1),this.setItemSelected(t,!0))}toggle(t){this.setItemSelected(t,!this.isSelected(t))}}let y=class extends s{constructor(){super(...arguments),this.activateEvent="tap",this.selectedAttribute=null,this.selected=null,this._selection=new m(((t,e)=>this.applySelection(t,e))),this._items=[]}get items(){return this._items}connectedCallback(){super.connectedCallback(),this.addEventListener("slotchange",(t=>{t.stopPropagation(),this.updateItems(),this.dispatchEvent(new CustomEvent("selector-items-changed",{detail:{},composed:!0}))})),this.addListener(this.activateEvent)}disconnectedCallback(){super.disconnectedCallback(),this.removeListener(this.activateEvent)}attributeChangedCallback(t,e,i){if(super.attributeChangedCallback(t,e,i),"selected"===t)this.updateSelected()}applySelection(t,e){this.selectedAttribute&&t instanceof Element&&e!==t.hasAttribute(this.selectedAttribute)&&t.toggleAttribute(this.selectedAttribute)}updateItems(){var t;const e=this.querySelector("slot");this._items=null!==(t=null==e?void 0:e.assignedNodes())&&void 0!==t?t:[]}addListener(t){this.addEventListener(t,(t=>this.activateHandler(t)))}removeListener(t){this.removeEventListener(t,(t=>this.activateHandler(t)))}activateHandler(t){let e=t.target;const i=this.items;for(;e&&e!==this;){const t=i.indexOf(e);if(t>=0){const i=this.indexToValue(t);return void this.itemActivate(i,e)}e=e.parentNode}}itemActivate(t,e){this.dispatchEvent(new CustomEvent("selector-item-activate",{detail:{selected:t,item:e},composed:!0,cancelable:!0}))&&this.select(t)}select(t){this.selected=t}updateSelected(){this.selectSelected(this.selected)}selectSelected(t){if(!this._items)return;const e=this.valueToItem(this.selected);e?this._selection.select(e):this._selection.clear()}valueToItem(t){return null==t?null:this._items[this.valueToIndex(t)]}valueToIndex(t){return Number(t)}indexToValue(t){return t}indexOf(t){return this._items?this._items.indexOf(t):-1}};t([a({type:String,attribute:"activate-event"}),e("design:type",Object)],y.prototype,"activateEvent",void 0),t([a({type:String,attribute:"selected-attribute"}),e("design:type",String)],y.prototype,"selectedAttribute",void 0),t([a({type:Number,reflect:!0}),e("design:type",Object)],y.prototype,"selected",void 0),y=t([r("lit-selector")],y);export{n as LitGoogleMap,l as LitGoogleMapCircle,p as LitGoogleMapMarker,h as LitGoogleMapPolygon,u as LitGoogleMapsApi,y as LitSelector};
+ `,t([a({type:String,attribute:"api-key"}),e("design:type",Object)],r.prototype,"apiKey",void 0),t([a({type:String}),e("design:type",Object)],r.prototype,"version",void 0),t([a({type:Object}),e("design:type",Object)],r.prototype,"styles",void 0),t([a({type:Number}),e("design:type",Object)],r.prototype,"zoom",void 0),t([a({type:Boolean,attribute:"fit-to-markers"}),e("design:type",Object)],r.prototype,"fitToMarkers",void 0),t([a({type:String,attribute:"map-type"}),e("design:type",Object)],r.prototype,"mapType",void 0),t([a({type:Number,attribute:"center-latitude"}),e("design:type",Object)],r.prototype,"centerLatitude",void 0),t([a({type:Number,attribute:"center-longitude"}),e("design:type",Object)],r.prototype,"centerLongitude",void 0),t([a({type:String}),e("design:type",Object)],r.prototype,"language",void 0),t([a({type:String,attribute:"map-id"}),e("design:type",Object)],r.prototype,"mapId",void 0),r=t([n("lit-google-map")],r);let l=class extends s{constructor(){super(...arguments),this.centerLatitude=-34.397,this.centerLongitude=150.644,this.radius=1e5,this.fillColor="#FF0000",this.fillOpacity=.35,this.strokeColor="#FF0000",this.strokeOpacity=.8,this.strokeWeight=2,this.map=null,this.circle=null}attributeChangedCallback(t,e,i){var s;switch(super.attributeChangedCallback(t,e,i),t){case"center-latitude":case"center-longitude":this.updateCenter();break;case"radius":null===(s=this.circle)||void 0===s||s.setRadius(this.radius)}}updateCenter(){var t;null===(t=this.circle)||void 0===t||t.setCenter(new google.maps.LatLng(this.centerLatitude,this.centerLongitude))}attachToMap(t){this.map=t,this.mapChanged()}mapChanged(){this.circle&&(this.circle.setMap(null),google.maps.event.clearInstanceListeners(this.circle)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.circle=new google.maps.Circle({map:this.map,strokeColor:this.strokeColor,strokeOpacity:this.strokeOpacity,strokeWeight:this.strokeWeight,fillColor:this.fillColor,fillOpacity:this.fillOpacity,center:{lat:this.centerLatitude,lng:this.centerLongitude},radius:this.radius})}};t([a({type:Number,attribute:"center-latitude"}),e("design:type",Object)],l.prototype,"centerLatitude",void 0),t([a({type:Number,attribute:"center-longitude"}),e("design:type",Object)],l.prototype,"centerLongitude",void 0),t([a({type:Number}),e("design:type",Object)],l.prototype,"radius",void 0),t([a({type:String,attribute:"fill-color"}),e("design:type",Object)],l.prototype,"fillColor",void 0),t([a({type:Number,attribute:"fill-opacity"}),e("design:type",Object)],l.prototype,"fillOpacity",void 0),t([a({type:String,attribute:"stroke-color"}),e("design:type",Object)],l.prototype,"strokeColor",void 0),t([a({type:Number,attribute:"stroke-opacity"}),e("design:type",Object)],l.prototype,"strokeOpacity",void 0),t([a({type:Number,attribute:"stroke-weight"}),e("design:type",Object)],l.prototype,"strokeWeight",void 0),l=t([n("lit-google-map-circle")],l);let c=class extends s{constructor(){super(...arguments),this.position="RIGHT_BOTTOM",this.label="My Location",this.disabled=!1,this.map=null,this.controlDiv=null,this.controlButton=null,this.isRequesting=!1}changeMap(t){this.map=t,this.mapChanged()}mapChanged(){this.controlDiv&&this.map&&(this.controlDiv=null,this.controlButton=null),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.controlDiv=this.createControlButton();const t=google.maps.ControlPosition[this.position];void 0!==t&&this.map.controls[t].push(this.controlDiv)}createControlButton(){const t=document.createElement("div");t.style.margin="10px";const e=document.createElement("button");return e.type="button",e.title=this.label,e.setAttribute("aria-label",this.label),e.innerHTML='\n \n ',Object.assign(e.style,{backgroundColor:"#fff",border:"0",borderRadius:"2px",boxShadow:"0 1px 4px rgba(0,0,0,0.3)",cursor:"pointer",padding:"10px",display:"flex",alignItems:"center",justifyContent:"center",width:"40px",height:"40px",color:"#666"}),e.addEventListener("mouseenter",(()=>{this.disabled||this.isRequesting||(e.style.backgroundColor="#f8f8f8")})),e.addEventListener("mouseleave",(()=>{this.disabled||this.isRequesting||(e.style.backgroundColor="#fff")})),e.addEventListener("click",(()=>{this.disabled||this.isRequesting||this.handleLocationRequest()})),this.controlButton=e,t.appendChild(e),t}async handleLocationRequest(){if(navigator.geolocation){this.isRequesting=!0,this.setLoadingState(!0),this.dispatchEvent(new CustomEvent("location-requested",{bubbles:!0,composed:!0}));try{const t=await this.getCurrentPosition(),e=t.coords.latitude,i=t.coords.longitude;this.map.setCenter({lat:e,lng:i}),this.map.setZoom(14),this.dispatchEvent(new CustomEvent("location-found",{detail:{lat:e,lng:i},bubbles:!0,composed:!0}))}catch(t){let e="Unable to retrieve your location",i=-1;t instanceof GeolocationPositionError&&(i=t.code,t.code===t.PERMISSION_DENIED?e="Location access denied. Please enable location permissions.":t.code===t.TIMEOUT?e="Location request timed out. Please try again.":t.code===t.POSITION_UNAVAILABLE&&(e="Location information is unavailable.")),this.dispatchEvent(new CustomEvent("location-error",{detail:{code:i,message:e},bubbles:!0,composed:!0}))}finally{this.isRequesting=!1,this.setLoadingState(!1)}}else this.dispatchEvent(new CustomEvent("location-error",{detail:{code:-1,message:"Geolocation is not supported by your browser"},bubbles:!0,composed:!0}))}getCurrentPosition(){return new Promise(((t,e)=>{navigator.geolocation.getCurrentPosition(t,e,{timeout:1e4,enableHighAccuracy:!0})}))}setLoadingState(t){if(this.controlButton)if(t){this.controlButton.style.backgroundColor="#f0f0f0",this.controlButton.style.cursor="wait";const t=this.controlButton.querySelector("svg");if(t){t.style.animation="spin 1s linear infinite";const e=document.createElement("style");e.textContent="\n @keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n ",document.querySelector("style[data-location-button-spin]")||(e.setAttribute("data-location-button-spin","true"),document.head.appendChild(e))}}else{this.controlButton.style.backgroundColor="#fff",this.controlButton.style.cursor="pointer";const t=this.controlButton.querySelector("svg");t&&(t.style.animation="")}}attributeChangedCallback(t,e,i){super.attributeChangedCallback(t,e,i),"disabled"===t&&this.controlButton&&(this.disabled?(this.controlButton.style.backgroundColor="#f0f0f0",this.controlButton.style.cursor="not-allowed",this.controlButton.style.opacity="0.6"):(this.controlButton.style.backgroundColor="#fff",this.controlButton.style.cursor="pointer",this.controlButton.style.opacity="1"))}};t([a({type:String,reflect:!0}),e("design:type",Object)],c.prototype,"position",void 0),t([a({type:String,reflect:!0}),e("design:type",Object)],c.prototype,"label",void 0),t([a({type:Boolean,reflect:!0}),e("design:type",Object)],c.prototype,"disabled",void 0),c=t([n("lit-google-map-location-button")],c);let h=class extends s{constructor(){super(...arguments),this.latitude=0,this.longitude=0,this.zIndex=0,this.open=!1,this.id=null,this.glyph=null,this.glyphColor=null,this.background=null,this.borderColor=null,this.scale=null,this.map=null,this.marker=null,this.pin=null}attributeChangedCallback(t,e,i){switch(super.attributeChangedCallback(t,e,i),t){case"open":this.openChanged();break;case"latitude":case"longitude":this.updatePosition();break;case"glyph":this.pin&&(this.pin.glyph=this.glyph);break;case"glyphColor":this.pin&&(this.pin.glyphColor=this.glyphColor);break;case"background":this.pin&&(this.pin.background=this.background);break;case"borderColor":this.pin&&(this.pin.borderColor=this.borderColor);break;case"scale":this.pin&&(this.pin.scale=this.scale);break;case"z-index":this.marker&&(this.marker.zIndex=this.zIndex)}}openChanged(){this.info&&(this.open?(this.info.open(this.map,this.marker),this.dispatchEvent(new CustomEvent("google-map-marker-open",{bubbles:!0}))):(this.info.close(),this.dispatchEvent(new CustomEvent("google-map-marker-close",{bubbles:!0}))))}updatePosition(){this.marker&&(this.marker.position=new google.maps.LatLng(this.latitude,this.longitude))}changeMap(t){this.map=t,this.mapChanged()}mapChanged(){this.marker&&(this.marker.map=null,google.maps.event.clearInstanceListeners(this.marker)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.pin=new google.maps.marker.PinElement({glyph:this.glyph,glyphColor:this.glyphColor,background:this.background,borderColor:this.borderColor,scale:this.scale}),this.marker=new google.maps.marker.AdvancedMarkerElement({map:this.map,position:{lat:this.latitude,lng:this.longitude},content:this.pin.element,zIndex:this.zIndex,gmpClickable:!0}),this.marker.element.addEventListener("mouseover",(()=>{this.dispatchEvent(new CustomEvent("mouseover",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.marker.element.addEventListener("mouseout",(()=>{this.dispatchEvent(new CustomEvent("mouseout",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.marker.addListener("click",(()=>{this.dispatchEvent(new CustomEvent("click",{detail:{id:this.id},bubbles:!0,composed:!0}))})),this.contentChanged()}contentChanged(){this.contentObserver&&this.contentObserver.disconnect(),this.contentObserver=new MutationObserver(this.contentChanged.bind(this)),this.contentObserver.observe(this,{childList:!0,subtree:!0});const t=this.innerHTML.trim();t?(this.info||(this.info=new google.maps.InfoWindow,this.openInfoHandler=google.maps.event.addListener(this.marker,"click",function(){this.open=!0}.bind(this)),this.closeInfoHandler=google.maps.event.addListener(this.info,"closeclick",function(){this.open=!1}.bind(this))),this.info.setContent(t)):this.info&&(google.maps.event.removeListener(this.openInfoHandler),google.maps.event.removeListener(this.closeInfoHandler),this.info=null)}};t([a({type:Number,reflect:!0}),e("design:type",Object)],h.prototype,"latitude",void 0),t([a({type:Number,reflect:!0}),e("design:type",Object)],h.prototype,"longitude",void 0),t([a({type:Number,reflect:!0,attribute:"z-index"}),e("design:type",Object)],h.prototype,"zIndex",void 0),t([a({type:Boolean,reflect:!0}),e("design:type",Object)],h.prototype,"open",void 0),t([a({type:String,reflect:!0}),e("design:type",String)],h.prototype,"id",void 0),t([a({type:String,reflect:!0}),e("design:type",String)],h.prototype,"glyph",void 0),t([a({type:String,reflect:!0}),e("design:type",String)],h.prototype,"glyphColor",void 0),t([a({type:String,reflect:!0}),e("design:type",String)],h.prototype,"background",void 0),t([a({type:String,reflect:!0}),e("design:type",String)],h.prototype,"borderColor",void 0),t([a({type:Number,reflect:!0}),e("design:type",Number)],h.prototype,"scale",void 0),h=t([n("lit-google-map-marker")],h);let p=class extends s{constructor(){super(...arguments),this.paths=[],this.fillColor="#FF0000",this.fillOpacity=.35,this.strokeColor="#FF0000",this.strokeOpacity=.8,this.strokeWeight=2,this.map=null,this.polygon=null}attachToMap(t){this.map=t,this.mapChanged()}mapChanged(){this.polygon&&(this.polygon.setMap(null),google.maps.event.clearInstanceListeners(this.polygon)),this.map&&this.map instanceof google.maps.Map&&this.mapReady()}mapReady(){this.polygon=new google.maps.Polygon({map:this.map,strokeColor:this.strokeColor,strokeOpacity:this.strokeOpacity,strokeWeight:this.strokeWeight,fillColor:this.fillColor,fillOpacity:this.fillOpacity,paths:this.paths})}};t([a({type:Array}),e("design:type",Array)],p.prototype,"paths",void 0),t([a({type:String,attribute:"fill-color"}),e("design:type",Object)],p.prototype,"fillColor",void 0),t([a({type:Number,attribute:"fill-opacity"}),e("design:type",Object)],p.prototype,"fillOpacity",void 0),t([a({type:String,attribute:"stroke-color"}),e("design:type",Object)],p.prototype,"strokeColor",void 0),t([a({type:Number,attribute:"stroke-opacity"}),e("design:type",Object)],p.prototype,"strokeOpacity",void 0),t([a({type:Number,attribute:"stroke-weight"}),e("design:type",Object)],p.prototype,"strokeWeight",void 0),p=t([n("lit-google-map-polygon")],p);class d{constructor(){this.apiMap={}}require(t,e,i){const s=this.nameFromUrl(t);this.apiMap[s]||(this.apiMap[s]=new u(s,t,i)),this.apiMap[s].requestNotify(e)}static getInstance(){return d.instance||(d.instance=new d),d.instance}nameFromUrl(t){return`${t.replace(/[:/%?&.=\-,]/g,"_")}_api`}}class u{constructor(t,e,i){this.callbackMacro="%%callback%%",this.loaded=!1,this.script=null,this.notifiers=[];let s=e,o=i;if(!o){if(!(s.indexOf(this.callbackMacro)>=0))return void console.error("ScriptLoader class: a %%callback%% parameter is required in libraryUrl");o=`${t}_loaded`,s=s.replace(this.callbackMacro,o)}this.callbackName=o,window[this.callbackName]=this.success.bind(this),this.addScript(s)}addScript(t){const e=document.createElement("script");e.src=t,e.onerror=this.handleError.bind(this);const i=document.querySelector("script")||document.body;i.parentNode.insertBefore(e,i),this.script=e}removeScript(){this.script.parentNode&&this.script.parentNode.removeChild(this.script),this.script=null}handleError(t){this.error=new Error("Library failed to load"),this.notifyAll(),this.cleanup()}success(...t){this.loaded=!0,this.result=t,this.notifyAll(),this.cleanup()}cleanup(){delete window[this.callbackName]}notifyAll(){this.notifiers.forEach(function(t){t(this.error,this.result)}.bind(this)),this.notifiers=[]}requestNotify(t){this.loaded||this.error?t(this.error,this.result):this.notifiers.push(t)}}class g extends s{constructor(){super(...arguments),this.libraryLoaded=!1,this.libraryErrorMessage=null,this.isReady=!1}get callbackName(){return null}libraryUrlChanged(){this.isReady&&null!=this.libraryUrl&&this.loadLibrary()}libraryLoadCallback(t,e){t?(console.warn("Library load failed:",t.message),this.libraryErrorMessage=t.message):(this.libraryErrorMessage=null,this.libraryLoaded=!0,null!=this.notifyEvent&&this.dispatchEvent(new CustomEvent(this.notifyEvent,{detail:e,composed:!0})))}loadLibrary(){d.getInstance().require(this.libraryUrl,this.libraryLoadCallback.bind(this),this.callbackName)}connectedCallback(){super.connectedCallback(),this.isReady=!0,null!=this.libraryUrl&&this.loadLibrary()}}let m=class extends g{constructor(){super(...arguments),this.apiKey="",this.clientId="",this.mapsUrl="https://maps.googleapis.com/maps/api/js?callback=%%callback%%",this.version="3.39",this.language="",this.mapId=""}get libraryUrl(){return this.computeUrl(this.mapsUrl,this.version,this.apiKey,this.clientId,this.language,this.mapId)}get notifyEvent(){return"api-load"}computeUrl(t,e,i,s,o,a){let n=`${t}&v=${e}`;if(n+="&libraries=drawing,geometry,places,visualization,marker",i&&!s&&(n+=`&key=${i}`),s&&(n+=`&client=${s}`),!i&&!s){const t="No Google Maps API Key or Client ID specified. See https://developers.google.com/maps/documentation/javascript/get-api-key for instructions to get started with a key or client id.";console.warn(t)}return o&&(n+=`&language=${o}`),a&&(n+=`&map_ids=${a}`),n}};t([a({type:String,attribute:"api-key"}),e("design:type",Object)],m.prototype,"apiKey",void 0),t([a({type:String,attribute:"client-id"}),e("design:type",Object)],m.prototype,"clientId",void 0),t([a({type:String,attribute:"maps-url"}),e("design:type",Object)],m.prototype,"mapsUrl",void 0),t([a({type:String}),e("design:type",Object)],m.prototype,"version",void 0),t([a({type:String}),e("design:type",Object)],m.prototype,"language",void 0),t([a({type:String,attribute:"map-id"}),e("design:type",Object)],m.prototype,"mapId",void 0),m=t([n("lit-google-maps-api")],m);class y{constructor(t){this.multi=!1,this.selection=[],this.selectCallback=t}get(){return this.multi?this.selection.slice():this.selection[0]}clear(t){for(const e of this.selection.slice())(!t||t.indexOf(e)<0)&&this.setItemSelected(e,!1)}isSelected(t){return this.selection.indexOf(t)>=0}setItemSelected(t,e){if(null!=t&&e!==this.isSelected(t)){if(e)this.selection.push(t);else{const e=this.selection.indexOf(t);e>=0&&this.selection.splice(e,1)}this.selectCallback&&this.selectCallback(t,e)}}select(t){this.multi?this.toggle(t):this.get()!==t&&(this.setItemSelected(this.get(),!1),this.setItemSelected(t,!0))}toggle(t){this.setItemSelected(t,!this.isSelected(t))}}let b=class extends s{constructor(){super(...arguments),this.activateEvent="tap",this.selectedAttribute=null,this.selected=null,this._selection=new y(((t,e)=>this.applySelection(t,e))),this._items=[]}get items(){return this._items}connectedCallback(){super.connectedCallback(),this.addEventListener("slotchange",(t=>{t.stopPropagation(),this.updateItems(),this.dispatchEvent(new CustomEvent("selector-items-changed",{detail:{},composed:!0}))})),this.addListener(this.activateEvent)}disconnectedCallback(){super.disconnectedCallback(),this.removeListener(this.activateEvent)}attributeChangedCallback(t,e,i){if(super.attributeChangedCallback(t,e,i),"selected"===t)this.updateSelected()}applySelection(t,e){this.selectedAttribute&&t instanceof Element&&e!==t.hasAttribute(this.selectedAttribute)&&t.toggleAttribute(this.selectedAttribute)}updateItems(){var t;const e=this.querySelector("slot");this._items=null!==(t=null==e?void 0:e.assignedNodes())&&void 0!==t?t:[]}addListener(t){this.addEventListener(t,(t=>this.activateHandler(t)))}removeListener(t){this.removeEventListener(t,(t=>this.activateHandler(t)))}activateHandler(t){let e=t.target;const i=this.items;for(;e&&e!==this;){const t=i.indexOf(e);if(t>=0){const i=this.indexToValue(t);return void this.itemActivate(i,e)}e=e.parentNode}}itemActivate(t,e){this.dispatchEvent(new CustomEvent("selector-item-activate",{detail:{selected:t,item:e},composed:!0,cancelable:!0}))&&this.select(t)}select(t){this.selected=t}updateSelected(){this.selectSelected(this.selected)}selectSelected(t){if(!this._items)return;const e=this.valueToItem(this.selected);e?this._selection.select(e):this._selection.clear()}valueToItem(t){return null==t?null:this._items[this.valueToIndex(t)]}valueToIndex(t){return Number(t)}indexToValue(t){return t}indexOf(t){return this._items?this._items.indexOf(t):-1}};t([a({type:String,attribute:"activate-event"}),e("design:type",Object)],b.prototype,"activateEvent",void 0),t([a({type:String,attribute:"selected-attribute"}),e("design:type",String)],b.prototype,"selectedAttribute",void 0),t([a({type:Number,reflect:!0}),e("design:type",Object)],b.prototype,"selected",void 0),b=t([n("lit-selector")],b);export{r as LitGoogleMap,l as LitGoogleMapCircle,c as LitGoogleMapLocationButton,h as LitGoogleMapMarker,p as LitGoogleMapPolygon,m as LitGoogleMapsApi,b as LitSelector};
diff --git a/package.json b/package.json
index 00ad72f..1e76411 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "lit-google-map",
- "version": "0.0.4",
+ "version": "0.0.5",
"description": "Google Maps web components based on Lit v2",
"private": false,
"license": "MIT",
diff --git a/src/index.ts b/src/index.ts
index f7f36ca..61d1e4e 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,5 +1,6 @@
export { LitGoogleMap } from "./lit-google-map";
export { LitGoogleMapCircle } from "./lit-google-map-circle";
+export { LitGoogleMapLocationButton } from "./lit-google-map-location-button";
export { LitGoogleMapMarker } from "./lit-google-map-marker";
export { LitGoogleMapPolygon } from "./lit-google-map-polygon";
export { LitGoogleMapsApi } from "./lit-google-maps-api";
diff --git a/src/lit-google-map-location-button.ts b/src/lit-google-map-location-button.ts
new file mode 100644
index 0000000..872bcc6
--- /dev/null
+++ b/src/lit-google-map-location-button.ts
@@ -0,0 +1,238 @@
+import { LitElement } from "lit";
+import { customElement, property } from "lit/decorators.js";
+
+@customElement("lit-google-map-location-button")
+export class LitGoogleMapLocationButton extends LitElement {
+ @property({ type: String, reflect: true })
+ position = "RIGHT_BOTTOM";
+
+ @property({ type: String, reflect: true })
+ label = "My Location";
+
+ @property({ type: Boolean, reflect: true })
+ disabled = false;
+
+ map: google.maps.Map = null;
+ controlDiv: HTMLDivElement = null;
+ controlButton: HTMLButtonElement = null;
+ isRequesting = false;
+
+ changeMap(newMap: google.maps.Map) {
+ this.map = newMap;
+ this.mapChanged();
+ }
+
+ mapChanged() {
+ // Remove existing control if map changed
+ if (this.controlDiv && this.map) {
+ // Cannot directly remove from controls array, so we'll just create new one
+ this.controlDiv = null;
+ this.controlButton = null;
+ }
+
+ if (this.map && this.map instanceof google.maps.Map) {
+ this.mapReady();
+ }
+ }
+
+ mapReady() {
+ this.controlDiv = this.createControlButton();
+
+ // Map position string to ControlPosition enum
+ const controlPosition =
+ google.maps.ControlPosition[
+ this.position as keyof typeof google.maps.ControlPosition
+ ];
+
+ if (controlPosition !== undefined) {
+ this.map.controls[controlPosition].push(this.controlDiv);
+ }
+ }
+
+ createControlButton(): HTMLDivElement {
+ const controlDiv = document.createElement("div");
+ controlDiv.style.margin = "10px";
+
+ const controlButton = document.createElement("button");
+ controlButton.type = "button";
+ controlButton.title = this.label;
+ controlButton.setAttribute("aria-label", this.label);
+
+ // Create location icon using SVG
+ controlButton.innerHTML = `
+
+ `;
+
+ // Apply Google Maps control styling
+ Object.assign(controlButton.style, {
+ backgroundColor: "#fff",
+ border: "0",
+ borderRadius: "2px",
+ boxShadow: "0 1px 4px rgba(0,0,0,0.3)",
+ cursor: "pointer",
+ padding: "10px",
+ display: "flex",
+ alignItems: "center",
+ justifyContent: "center",
+ width: "40px",
+ height: "40px",
+ color: "#666",
+ });
+
+ // Hover effects
+ controlButton.addEventListener("mouseenter", () => {
+ if (!this.disabled && !this.isRequesting) {
+ controlButton.style.backgroundColor = "#f8f8f8";
+ }
+ });
+
+ controlButton.addEventListener("mouseleave", () => {
+ if (!this.disabled && !this.isRequesting) {
+ controlButton.style.backgroundColor = "#fff";
+ }
+ });
+
+ // Click handler
+ controlButton.addEventListener("click", () => {
+ if (!this.disabled && !this.isRequesting) {
+ this.handleLocationRequest();
+ }
+ });
+
+ this.controlButton = controlButton;
+ controlDiv.appendChild(controlButton);
+
+ return controlDiv;
+ }
+
+ async handleLocationRequest() {
+ if (!navigator.geolocation) {
+ this.dispatchEvent(
+ new CustomEvent("location-error", {
+ detail: {
+ code: -1,
+ message: "Geolocation is not supported by your browser",
+ },
+ bubbles: true,
+ composed: true,
+ }),
+ );
+ return;
+ }
+
+ // Set loading state
+ this.isRequesting = true;
+ this.setLoadingState(true);
+
+ this.dispatchEvent(
+ new CustomEvent("location-requested", {
+ bubbles: true,
+ composed: true,
+ }),
+ );
+
+ try {
+ const position = await this.getCurrentPosition();
+ const lat = position.coords.latitude;
+ const lng = position.coords.longitude;
+
+ // Center the map
+ this.map.setCenter({ lat, lng });
+ this.map.setZoom(14);
+
+ this.dispatchEvent(
+ new CustomEvent("location-found", {
+ detail: { lat, lng },
+ bubbles: true,
+ composed: true,
+ }),
+ );
+ } catch (error) {
+ let message = "Unable to retrieve your location";
+ let code = -1;
+
+ if (error instanceof GeolocationPositionError) {
+ code = error.code;
+ if (error.code === error.PERMISSION_DENIED) {
+ message =
+ "Location access denied. Please enable location permissions.";
+ } else if (error.code === error.TIMEOUT) {
+ message = "Location request timed out. Please try again.";
+ } else if (error.code === error.POSITION_UNAVAILABLE) {
+ message = "Location information is unavailable.";
+ }
+ }
+
+ this.dispatchEvent(
+ new CustomEvent("location-error", {
+ detail: { code, message },
+ bubbles: true,
+ composed: true,
+ }),
+ );
+ } finally {
+ this.isRequesting = false;
+ this.setLoadingState(false);
+ }
+ }
+
+ getCurrentPosition(): Promise {
+ return new Promise((resolve, reject) => {
+ navigator.geolocation.getCurrentPosition(resolve, reject, {
+ timeout: 10000,
+ enableHighAccuracy: true,
+ });
+ });
+ }
+
+ setLoadingState(loading: boolean) {
+ if (!this.controlButton) return;
+
+ if (loading) {
+ this.controlButton.style.backgroundColor = "#f0f0f0";
+ this.controlButton.style.cursor = "wait";
+ // Add spinning animation
+ const svg = this.controlButton.querySelector("svg");
+ if (svg) {
+ svg.style.animation = "spin 1s linear infinite";
+ // Add keyframes if not already present
+ const style = document.createElement("style");
+ style.textContent = `
+ @keyframes spin {
+ from { transform: rotate(0deg); }
+ to { transform: rotate(360deg); }
+ }
+ `;
+ if (!document.querySelector("style[data-location-button-spin]")) {
+ style.setAttribute("data-location-button-spin", "true");
+ document.head.appendChild(style);
+ }
+ }
+ } else {
+ this.controlButton.style.backgroundColor = "#fff";
+ this.controlButton.style.cursor = "pointer";
+ const svg = this.controlButton.querySelector("svg");
+ if (svg) {
+ svg.style.animation = "";
+ }
+ }
+ }
+
+ attributeChangedCallback(name: string, oldval: string, newval: string) {
+ super.attributeChangedCallback(name, oldval, newval);
+
+ if (name === "disabled" && this.controlButton) {
+ if (this.disabled) {
+ this.controlButton.style.backgroundColor = "#f0f0f0";
+ this.controlButton.style.cursor = "not-allowed";
+ this.controlButton.style.opacity = "0.6";
+ } else {
+ this.controlButton.style.backgroundColor = "#fff";
+ this.controlButton.style.cursor = "pointer";
+ this.controlButton.style.opacity = "1";
+ }
+ }
+ }
+}
diff --git a/src/lit-google-map.ts b/src/lit-google-map.ts
index ae193fb..7f7f7a0 100644
--- a/src/lit-google-map.ts
+++ b/src/lit-google-map.ts
@@ -1,5 +1,6 @@
import { css, html, LitElement } from "lit";
import { customElement, property } from "lit/decorators.js";
+import type { LitGoogleMapLocationButton } from "./lit-google-map-location-button";
import type { LitGoogleMapMarker } from "./lit-google-map-marker";
import type { LitGoogleMapsApi } from "./lit-google-maps-api";
import type { LitSelector } from "./lit-selector";
@@ -61,6 +62,7 @@ export class LitGoogleMap extends LitElement {
markers: Array;
shapes: Array;
+ controls: Array;
markerObserverSet: boolean;
@@ -175,6 +177,7 @@ export class LitGoogleMap extends LitElement {
this.updateMarkers();
this.updateShapes();
+ this.updateControls();
}
getMapOptions(): google.maps.MapOptions {
@@ -298,6 +301,19 @@ export class LitGoogleMap extends LitElement {
}
}
+ updateControls() {
+ const controlsSelector = this.shadowRoot.getElementById(
+ "controls-selector",
+ ) as LitSelector;
+ if (!controlsSelector) return;
+
+ this.controls = controlsSelector.items;
+
+ for (const c of this.controls) {
+ (c as LitGoogleMapLocationButton).changeMap(this.map);
+ }
+ }
+
fitToMarkersChanged(retryAttempt = 0) {
if (this.map && this.fitToMarkers && this.markers.length > 0) {
const latLngBounds = new google.maps.LatLngBounds();
@@ -381,6 +397,13 @@ export class LitGoogleMap extends LitElement {
>
+
+
+
`;
}