@gui-chat-plugin/google-map 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vue.js CHANGED
@@ -1,553 +1,432 @@
1
- import { samples as ae, pluginCore as le } from "./core.js";
2
- import { TOOL_DEFINITION as Je, TOOL_NAME as We, executeMap as Xe } from "./core.js";
3
- import { defineComponent as j, ref as p, computed as k, watch as ie, onMounted as ce, onUnmounted as ue, createElementBlock as c, openBlock as u, createElementVNode as s, createCommentVNode as y, toDisplayString as m, Fragment as U, renderList as B, createTextVNode as $, normalizeClass as T } from "vue";
4
- const de = { class: "w-full h-full bg-white flex flex-col relative" }, ge = { class: "p-4 border-b border-gray-200" }, me = { class: "text-xl font-bold text-gray-800" }, ve = {
5
- key: 0,
6
- class: "text-gray-600 text-sm"
7
- }, fe = { class: "flex-1 min-h-0 flex" }, pe = { class: "flex-1 relative" }, ye = {
8
- key: 1,
9
- class: "w-full h-full flex items-center justify-center bg-gray-100"
10
- }, he = { class: "text-center p-8" }, we = ["href"], be = {
11
- key: 2,
12
- class: "absolute inset-0 bg-white bg-opacity-75 flex items-center justify-center"
13
- }, xe = {
14
- key: 3,
15
- class: "absolute bottom-4 left-4 right-4 bg-red-100 border border-red-300 text-red-700 px-4 py-3 rounded"
16
- }, _e = {
17
- key: 4,
18
- class: "absolute top-4 right-4 flex flex-col gap-1"
19
- }, ke = {
20
- key: 0,
21
- class: "w-80 border-l border-gray-200 overflow-y-auto"
22
- }, Me = {
23
- key: 0,
24
- class: "p-4"
25
- }, Ce = { class: "space-y-3" }, Le = ["onClick"], De = { class: "font-medium text-gray-800" }, Re = { class: "text-sm text-gray-600 mt-1" }, Ee = {
26
- key: 0,
27
- class: "flex items-center mt-1"
28
- }, Pe = { class: "text-sm text-gray-600" }, Ie = {
29
- key: 0,
30
- class: "text-gray-400"
31
- }, Se = {
32
- key: 1,
33
- class: "p-4"
34
- }, Ze = { class: "bg-blue-50 rounded-lg p-3 mb-4" }, Ne = { class: "text-lg font-medium text-gray-800" }, $e = { class: "text-gray-600" }, Te = { class: "text-sm text-gray-600 mb-3" }, Ae = { class: "space-y-2" }, Oe = ["onClick"], ze = { class: "text-gray-800" }, Fe = { class: "text-gray-500 mt-1" }, Ve = /* @__PURE__ */ j({
35
- __name: "View",
36
- props: {
37
- selectedResult: {},
38
- googleMapKey: {},
39
- onUpdateResult: { type: Function }
40
- },
41
- setup(D) {
42
- const g = D, C = p(null), n = p(null), b = p(/* @__PURE__ */ new Map()), R = p(null), M = p(null), r = p(null);
43
- let _, E;
44
- const S = p(!1), P = p(null), L = p([]), h = p(null), Z = p(null), I = p(15), Q = k(() => {
45
- const e = g.selectedResult?.data?.action;
46
- return {
47
- showLocation: "Map Location",
48
- setCenter: "Map View",
49
- setZoom: "Map View",
50
- addMarker: "Map Marker",
51
- clearMarkers: "Map",
52
- findPlaces: "Place Search",
53
- getDirections: "Directions"
54
- }[e || "showLocation"] || "Map";
55
- }), A = k(() => {
56
- const e = g.selectedResult?.data;
57
- if (!e) return "";
58
- switch (e.action) {
59
- case "showLocation":
60
- case "setCenter":
61
- case "addMarker":
62
- return z(e.location);
63
- case "setZoom":
64
- return `Zoom level: ${e.zoom}`;
65
- case "findPlaces":
66
- return e.searchQuery || e.placeType || "";
67
- case "getDirections":
68
- return `${e.origin} ${e.destination}`;
69
- default:
70
- return "";
71
- }
72
- }), H = k(() => L.value.length > 0 || h.value !== null), O = k(() => {
73
- const e = g.selectedResult?.data;
74
- if (!e?.location) return "";
75
- const t = z(e.location);
76
- return `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(t)}`;
77
- }), z = (e) => e ? typeof e == "string" ? e : `${e.lat}, ${e.lng}` : "", J = (e) => new DOMParser().parseFromString(e, "text/html").body.textContent || "", W = () => {
78
- const e = [];
79
- return b.value.forEach((t, o) => {
80
- const a = t.position;
81
- if (a) {
82
- const i = typeof a.lat == "function" ? a.lat() : a.lat, v = typeof a.lng == "function" ? a.lng() : a.lng;
83
- e.push({
84
- id: o,
85
- position: { lat: i, lng: v },
86
- title: t.title || void 0
87
- });
88
- }
89
- }), e;
90
- }, w = (e, t, o) => {
91
- if (!g.onUpdateResult) return;
92
- const i = {
93
- action: g.selectedResult?.data?.action || "showLocation",
94
- success: e,
95
- center: Z.value || void 0,
96
- zoom: I.value,
97
- markers: W(),
98
- ...o
99
- };
100
- t && (i.error = t), g.onUpdateResult(i);
101
- }, X = () => new Promise((e, t) => {
102
- if (typeof google < "u" && google.maps && typeof google.maps.importLibrary == "function") {
103
- e();
104
- return;
105
- }
106
- const o = document.querySelector(
107
- 'script[src*="maps.googleapis.com"]'
108
- ), a = 1e4, i = 50, v = (l) => {
109
- typeof google < "u" && google.maps && typeof google.maps.importLibrary == "function" ? e() : Date.now() - l > a ? t(new Error("Timeout waiting for Google Maps to load")) : setTimeout(() => v(l), i);
110
- };
111
- if (o) {
112
- v(Date.now());
113
- return;
114
- }
115
- const d = document.createElement("script");
116
- d.src = `https://maps.googleapis.com/maps/api/js?key=${g.googleMapKey}&loading=async`, d.async = !0, d.defer = !0, d.onload = () => v(Date.now()), d.onerror = () => t(new Error("Failed to load Google Maps")), document.head.appendChild(d);
117
- }), Y = async () => {
118
- if (!(!C.value || !g.googleMapKey) && !n.value)
119
- try {
120
- await X();
121
- const e = await google.maps.importLibrary(
122
- "marker"
123
- ), t = await google.maps.importLibrary(
124
- "places"
125
- );
126
- _ = e.AdvancedMarkerElement, E = t.Place;
127
- const o = { lat: 35.6812, lng: 139.7671 };
128
- n.value = new google.maps.Map(C.value, {
129
- center: o,
130
- zoom: I.value,
131
- mapTypeControl: !0,
132
- streetViewControl: !0,
133
- fullscreenControl: !0,
134
- // DEMO_MAP_ID is Google's demo ID. For production, create your own at:
135
- // https://console.cloud.google.com/google/maps-apis/studio/maps
136
- mapId: "DEMO_MAP_ID"
137
- }), r.value = new google.maps.Geocoder(), R.value = new google.maps.DirectionsService(), M.value = new google.maps.DirectionsRenderer(), M.value.setMap(n.value), n.value.addListener("center_changed", () => {
138
- const a = n.value?.getCenter();
139
- a && (Z.value = { lat: a.lat(), lng: a.lng() });
140
- }), n.value.addListener("zoom_changed", () => {
141
- I.value = n.value?.getZoom() || 15;
142
- }), g.selectedResult?.data && await K(g.selectedResult.data);
143
- } catch (e) {
144
- P.value = e instanceof Error ? e.message : "Failed to initialize map";
145
- }
146
- }, F = async (e) => typeof e != "string" ? e : r.value ? new Promise((t) => {
147
- r.value.geocode(
148
- { address: e },
149
- (o, a) => {
150
- if (a === "OK" && o && o[0]) {
151
- const i = o[0].geometry.location;
152
- t({ lat: i.lat(), lng: i.lng() });
153
- } else
154
- t(null);
155
- }
156
- );
157
- }) : null, N = (e, t, o, a) => {
158
- let i;
159
- if (a) {
160
- const d = document.createElement("div");
161
- d.className = "marker-label", d.style.cssText = "background: #4285f4; color: white; padding: 4px 8px; border-radius: 4px; font-weight: bold; font-size: 12px;", d.textContent = a, i = d;
162
- }
163
- const v = new _({
164
- position: e,
165
- map: n.value,
166
- title: o,
167
- content: i
168
- });
169
- return b.value.set(t, v), v;
170
- }, V = () => {
171
- b.value.forEach((e) => {
172
- e.map = null;
173
- }), b.value.clear();
174
- }, K = async (e) => {
175
- if (n.value) {
176
- S.value = !0, P.value = null;
177
- try {
178
- switch (e.action) {
179
- case "showLocation":
180
- case "setCenter": {
181
- if (!e.location)
182
- throw new Error("Location is required");
183
- const t = await F(e.location);
184
- if (!t)
185
- throw new Error("Could not find location");
186
- if (n.value.setCenter(t), Z.value = t, e.action === "showLocation") {
187
- const o = `location_${Date.now()}`;
188
- N(
189
- t,
190
- o,
191
- typeof e.location == "string" ? e.location : void 0
192
- );
193
- }
194
- w(!0);
195
- break;
196
- }
197
- case "setZoom": {
198
- const t = e.zoom || 15;
199
- n.value.setZoom(t), I.value = t, w(!0);
200
- break;
201
- }
202
- case "addMarker": {
203
- if (!e.location)
204
- throw new Error("Location is required for marker");
205
- const t = await F(e.location);
206
- if (!t)
207
- throw new Error("Could not find location for marker");
208
- const o = e.marker?.id || `marker_${Date.now()}`;
209
- N(t, o, e.marker?.title, e.marker?.label), w(!0);
210
- break;
211
- }
212
- case "clearMarkers": {
213
- V(), M.value?.setDirections({
214
- routes: [],
215
- request: {}
216
- }), L.value = [], h.value = null, w(!0);
217
- break;
218
- }
219
- case "findPlaces": {
220
- await ee(e.searchQuery, e.placeType);
221
- break;
222
- }
223
- case "getDirections": {
224
- if (!e.origin || !e.destination)
225
- throw new Error("Origin and destination are required");
226
- await te(
227
- e.origin,
228
- e.destination,
229
- e.travelMode || "DRIVING"
230
- );
231
- break;
232
- }
233
- }
234
- } catch (t) {
235
- const o = t instanceof Error ? t.message : "An error occurred";
236
- P.value = o, w(!1, o);
237
- } finally {
238
- S.value = !1;
239
- }
240
- }
241
- }, ee = async (e, t) => {
242
- if (!n.value || !E) return;
243
- const o = n.value.getCenter();
244
- if (o)
245
- try {
246
- const a = {
247
- textQuery: e || t || "",
248
- locationBias: {
249
- center: { lat: o.lat(), lng: o.lng() },
250
- radius: 5e3
251
- },
252
- fields: ["id", "displayName", "formattedAddress", "location", "rating", "userRatingCount", "types", "regularOpeningHours"],
253
- maxResultCount: 10
254
- };
255
- t && !e && (a.includedType = t);
256
- const { places: i } = await E.searchByText(a);
257
- if (i && i.length > 0) {
258
- [...b.value.keys()].filter(
259
- (l) => l.startsWith("place_")
260
- ).forEach((l) => {
261
- const x = b.value.get(l);
262
- x && (x.map = null, b.value.delete(l));
263
- });
264
- const d = i.map(
265
- (l, x) => {
266
- const f = l.location, G = f ? { lat: f.lat(), lng: f.lng() } : { lat: 0, lng: 0 };
267
- return f && N(
268
- G,
269
- `place_${l.id}`,
270
- l.displayName || void 0,
271
- String(x + 1)
272
- ), {
273
- placeId: l.id || "",
274
- name: l.displayName || "",
275
- address: l.formattedAddress || "",
276
- location: G,
277
- rating: l.rating ?? void 0,
278
- userRatingsTotal: l.userRatingCount ?? void 0,
279
- types: l.types,
280
- // Note: isOpen() requires async call, omitting for now
281
- openNow: void 0
282
- };
283
- }
284
- );
285
- if (L.value = d, h.value = null, d.length > 0) {
286
- const l = new google.maps.LatLngBounds();
287
- d.forEach((x) => {
288
- l.extend(x.location);
289
- }), n.value?.fitBounds(l);
290
- }
291
- w(!0, void 0, { places: d });
292
- } else
293
- w(!1, "No places found");
294
- } catch {
295
- w(!1, "No places found");
296
- }
297
- }, te = async (e, t, o) => {
298
- if (!R.value || !M.value) return;
299
- const a = {
300
- origin: e,
301
- destination: t,
302
- travelMode: o
303
- };
304
- return new Promise((i) => {
305
- R.value.route(
306
- a,
307
- (v, d) => {
308
- if (d === google.maps.DirectionsStatus.OK && v) {
309
- M.value.setDirections(v);
310
- const l = v.routes[0]?.legs[0];
311
- if (l) {
312
- const x = {
313
- summary: v.routes[0].summary || "",
314
- distance: l.distance?.text || "",
315
- duration: l.duration?.text || "",
316
- startAddress: l.start_address || "",
317
- endAddress: l.end_address || "",
318
- steps: l.steps?.map((f) => ({
319
- instruction: f.instructions || "",
320
- distance: f.distance?.text || "",
321
- duration: f.duration?.text || "",
322
- travelMode: f.travel_mode || "",
323
- startLocation: f.start_location ? {
324
- lat: f.start_location.lat(),
325
- lng: f.start_location.lng()
326
- } : void 0,
327
- endLocation: f.end_location ? {
328
- lat: f.end_location.lat(),
329
- lng: f.end_location.lng()
330
- } : void 0
331
- })) || [],
332
- polyline: v.routes[0].overview_polyline || ""
333
- };
334
- h.value = x, L.value = [], w(!0, void 0, { route: x });
335
- }
336
- } else
337
- w(!1, "Could not find directions");
338
- i();
339
- }
340
- );
341
- });
342
- }, oe = (e) => {
343
- n.value && (n.value.setCenter(e.location), n.value.setZoom(17));
344
- }, ne = (e) => {
345
- if (!n.value) return;
346
- const t = e.startLocation || e.endLocation;
347
- t && (n.value.setCenter(t), n.value.setZoom(18));
348
- }, se = () => {
349
- if (!n.value) return;
350
- const e = n.value.getZoom() || 15;
351
- e < 21 && n.value.setZoom(e + 1);
352
- }, re = () => {
353
- if (!n.value) return;
354
- const e = n.value.getZoom() || 15;
355
- e > 1 && n.value.setZoom(e - 1);
356
- };
357
- let q = null;
358
- return ie(
359
- () => g.selectedResult?.data,
360
- async (e) => {
361
- if (e && n.value) {
362
- const t = JSON.stringify(e);
363
- if (t === q) return;
364
- q = t, await K(e);
365
- }
366
- }
367
- ), ce(() => {
368
- g.googleMapKey && Y();
369
- }), ue(() => {
370
- V();
371
- }), (e, t) => (u(), c("div", de, [
372
- s("div", ge, [
373
- s("h2", me, m(Q.value), 1),
374
- A.value ? (u(), c("p", ve, m(A.value), 1)) : y("", !0)
375
- ]),
376
- s("div", fe, [
377
- s("div", pe, [
378
- D.googleMapKey ? (u(), c("div", {
379
- key: 0,
380
- ref_key: "mapContainer",
381
- ref: C,
382
- class: "w-full h-full"
383
- }, null, 512)) : (u(), c("div", ye, [
384
- s("div", he, [
385
- t[0] || (t[0] = s("div", { class: "text-gray-500 mb-4" }, "Google Maps API key not configured", -1)),
386
- O.value ? (u(), c("a", {
387
- key: 0,
388
- href: O.value,
389
- target: "_blank",
390
- class: "inline-block px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors"
391
- }, " Open in Google Maps ", 8, we)) : y("", !0)
392
- ])
393
- ])),
394
- S.value ? (u(), c("div", be, [...t[1] || (t[1] = [
395
- s("div", { class: "text-gray-600" }, "Loading...", -1)
396
- ])])) : y("", !0),
397
- P.value ? (u(), c("div", xe, m(P.value), 1)) : y("", !0),
398
- D.googleMapKey && n.value ? (u(), c("div", _e, [
399
- s("button", {
400
- onClick: se,
401
- class: "w-8 h-8 bg-white border border-gray-300 rounded shadow text-lg font-bold text-gray-700 hover:bg-gray-100 flex items-center justify-center",
402
- title: "Zoom in"
403
- }, " + "),
404
- s("button", {
405
- onClick: re,
406
- class: "w-8 h-8 bg-white border border-gray-300 rounded shadow text-lg font-bold text-gray-700 hover:bg-gray-100 flex items-center justify-center",
407
- title: "Zoom out"
408
- }, "")
409
- ])) : y("", !0)
410
- ]),
411
- H.value ? (u(), c("div", ke, [
412
- L.value.length > 0 ? (u(), c("div", Me, [
413
- t[3] || (t[3] = s("h3", { class: "font-semibold text-gray-800 mb-3" }, "Search Results", -1)),
414
- s("div", Ce, [
415
- (u(!0), c(U, null, B(L.value, (o) => (u(), c("div", {
416
- key: o.placeId,
417
- class: "p-3 bg-gray-50 rounded-lg cursor-pointer hover:bg-gray-100 transition-colors",
418
- onClick: (a) => oe(o)
419
- }, [
420
- s("div", De, m(o.name), 1),
421
- s("div", Re, m(o.address), 1),
422
- o.rating ? (u(), c("div", Ee, [
423
- t[2] || (t[2] = s("span", { class: "text-yellow-500 mr-1" }, "", -1)),
424
- s("span", Pe, [
425
- $(m(o.rating.toFixed(1)) + " ", 1),
426
- o.userRatingsTotal ? (u(), c("span", Ie, " (" + m(o.userRatingsTotal) + ") ", 1)) : y("", !0)
427
- ])
428
- ])) : y("", !0),
429
- o.openNow !== void 0 ? (u(), c("div", {
430
- key: 1,
431
- class: T([o.openNow ? "text-green-600" : "text-red-600", "text-sm mt-1"])
432
- }, m(o.openNow ? "Open now" : "Closed"), 3)) : y("", !0)
433
- ], 8, Le))), 128))
434
- ])
435
- ])) : y("", !0),
436
- h.value ? (u(), c("div", Se, [
437
- t[6] || (t[6] = s("h3", { class: "font-semibold text-gray-800 mb-3" }, "Directions", -1)),
438
- s("div", Ze, [
439
- s("div", Ne, m(h.value.distance), 1),
440
- s("div", $e, m(h.value.duration), 1)
441
- ]),
442
- s("div", Te, [
443
- s("div", null, [
444
- t[4] || (t[4] = s("strong", null, "From:", -1)),
445
- $(" " + m(h.value.startAddress), 1)
446
- ]),
447
- s("div", null, [
448
- t[5] || (t[5] = s("strong", null, "To:", -1)),
449
- $(" " + m(h.value.endAddress), 1)
450
- ])
451
- ]),
452
- s("div", Ae, [
453
- (u(!0), c(U, null, B(h.value.steps, (o, a) => (u(), c("div", {
454
- key: a,
455
- class: "p-2 bg-gray-50 rounded text-sm cursor-pointer hover:bg-blue-50 transition-colors",
456
- onClick: (i) => ne(o)
457
- }, [
458
- s("div", ze, m(J(o.instruction)), 1),
459
- s("div", Fe, m(o.distance) + " · " + m(o.duration), 1)
460
- ], 8, Oe))), 128))
461
- ])
462
- ])) : y("", !0)
463
- ])) : y("", !0)
464
- ])
465
- ]));
466
- }
467
- }), Ke = { class: "text-xs text-gray-600 mt-1 truncate" }, qe = /* @__PURE__ */ j({
468
- __name: "Preview",
469
- props: {
470
- result: {}
471
- },
472
- setup(D) {
473
- const g = D, C = (r) => r ? typeof r == "string" ? r : `${r.lat.toFixed(4)}, ${r.lng.toFixed(4)}` : "", n = k(() => {
474
- const r = g.result.data?.action;
475
- return {
476
- showLocation: "Map Location",
477
- setCenter: "Center Map",
478
- setZoom: "Zoom",
479
- addMarker: "Add Marker",
480
- clearMarkers: "Clear Markers",
481
- findPlaces: "Place Search",
482
- getDirections: "Directions"
483
- }[r || "showLocation"] || "Map";
484
- }), b = k(() => {
485
- const r = g.result.data;
486
- if (!r) return "";
487
- switch (r.action) {
488
- case "showLocation":
489
- case "setCenter":
490
- case "addMarker":
491
- return C(r.location);
492
- case "setZoom":
493
- return `Level ${r.zoom}`;
494
- case "clearMarkers":
495
- return "All markers cleared";
496
- case "findPlaces":
497
- return r.searchQuery || r.placeType || "Search";
498
- case "getDirections": {
499
- const _ = typeof r.origin == "string" ? r.origin : "Start", E = typeof r.destination == "string" ? r.destination : "End";
500
- return `${_} → ${E}`;
501
- }
502
- default:
503
- return C(r.location);
504
- }
505
- }), R = k(() => {
506
- const r = g.result.data?.action;
507
- return {
508
- showLocation: "bg-blue-50",
509
- setCenter: "bg-blue-50",
510
- setZoom: "bg-purple-50",
511
- addMarker: "bg-green-50",
512
- clearMarkers: "bg-gray-50",
513
- findPlaces: "bg-yellow-50",
514
- getDirections: "bg-orange-50"
515
- }[r || "showLocation"] || "bg-blue-50";
516
- }), M = k(() => {
517
- const r = g.result.data?.action;
518
- return {
519
- showLocation: "text-blue-600",
520
- setCenter: "text-blue-600",
521
- setZoom: "text-purple-600",
522
- addMarker: "text-green-600",
523
- clearMarkers: "text-gray-600",
524
- findPlaces: "text-yellow-700",
525
- getDirections: "text-orange-600"
526
- }[r || "showLocation"] || "text-blue-600";
527
- });
528
- return (r, _) => (u(), c("div", {
529
- class: T(["text-center p-4 rounded", R.value])
530
- }, [
531
- s("div", {
532
- class: T(["font-medium", M.value])
533
- }, m(n.value), 3),
534
- s("div", Ke, m(b.value), 1)
535
- ], 2));
536
- }
537
- }), Ge = {
538
- ...le,
539
- viewComponent: Ve,
540
- previewComponent: qe,
541
- samples: ae
542
- }, je = { plugin: Ge };
543
- export {
544
- qe as Preview,
545
- Je as TOOL_DEFINITION,
546
- We as TOOL_NAME,
547
- Ve as View,
548
- je as default,
549
- Xe as executeMap,
550
- Ge as plugin,
551
- le as pluginCore,
552
- ae as samples
553
- };
1
+ import { i as e, n as t, o as n, s as r, t as i } from "./samples-CH-C0Bol.js";
2
+ import { Fragment as a, computed as o, createCommentVNode as s, createElementBlock as c, createElementVNode as l, createTextVNode as u, defineComponent as d, normalizeClass as f, onMounted as p, onUnmounted as m, openBlock as h, ref as g, renderList as _, toDisplayString as v, watch as y } from "vue";
3
+ //#region src/vue/View.vue?vue&type=script&setup=true&lang.ts
4
+ var b = { class: "w-full h-full bg-white flex flex-col relative" }, x = { class: "p-4 border-b border-gray-200" }, ee = { class: "text-xl font-bold text-gray-800" }, te = {
5
+ key: 0,
6
+ class: "text-gray-600 text-sm"
7
+ }, ne = { class: "flex-1 min-h-0 flex" }, re = { class: "flex-1 relative" }, ie = {
8
+ key: 1,
9
+ class: "w-full h-full flex items-center justify-center bg-gray-100"
10
+ }, ae = { class: "text-center p-8" }, oe = ["href"], se = {
11
+ key: 2,
12
+ class: "absolute inset-0 bg-white bg-opacity-75 flex items-center justify-center"
13
+ }, ce = {
14
+ key: 3,
15
+ class: "absolute bottom-4 left-4 right-4 bg-red-100 border border-red-300 text-red-700 px-4 py-3 rounded"
16
+ }, le = {
17
+ key: 4,
18
+ class: "absolute top-4 right-4 flex flex-col gap-1"
19
+ }, ue = {
20
+ key: 0,
21
+ class: "w-80 border-l border-gray-200 overflow-y-auto"
22
+ }, de = {
23
+ key: 0,
24
+ class: "p-4"
25
+ }, fe = { class: "space-y-3" }, pe = ["onClick"], me = { class: "font-medium text-gray-800" }, he = { class: "text-sm text-gray-600 mt-1" }, S = {
26
+ key: 0,
27
+ class: "flex items-center mt-1"
28
+ }, C = { class: "text-sm text-gray-600" }, w = {
29
+ key: 0,
30
+ class: "text-gray-400"
31
+ }, T = {
32
+ key: 1,
33
+ class: "p-4"
34
+ }, E = { class: "bg-blue-50 rounded-lg p-3 mb-4" }, D = { class: "text-lg font-medium text-gray-800" }, O = { class: "text-gray-600" }, k = { class: "text-sm text-gray-600 mb-3" }, A = { class: "space-y-2" }, j = ["onClick"], M = { class: "text-gray-800" }, N = { class: "text-gray-500 mt-1" }, P = /* @__PURE__ */ d({
35
+ __name: "View",
36
+ props: {
37
+ selectedResult: {},
38
+ googleMapKey: {},
39
+ onUpdateResult: { type: Function }
40
+ },
41
+ setup(e) {
42
+ let t = e, n = g(null), r = g(null), i = g(/* @__PURE__ */ new Map()), d = g(null), P = g(null), F = g(null), I, L, R = g(!1), z = g(null), B = g([]), V = g(null), H = g(null), U = g(15), ge = o(() => ({
43
+ showLocation: "Map Location",
44
+ setCenter: "Map View",
45
+ setZoom: "Map View",
46
+ addMarker: "Map Marker",
47
+ clearMarkers: "Map",
48
+ findPlaces: "Place Search",
49
+ getDirections: "Directions"
50
+ })[t.selectedResult?.data?.action || "showLocation"] || "Map"), W = o(() => {
51
+ let e = t.selectedResult?.data;
52
+ if (!e) return "";
53
+ switch (e.action) {
54
+ case "showLocation":
55
+ case "setCenter":
56
+ case "addMarker": return K(e.location);
57
+ case "setZoom": return `Zoom level: ${e.zoom}`;
58
+ case "findPlaces": return e.searchQuery || e.placeType || "";
59
+ case "getDirections": return `${e.origin} → ${e.destination}`;
60
+ default: return "";
61
+ }
62
+ }), _e = o(() => B.value.length > 0 || V.value !== null), G = o(() => {
63
+ let e = t.selectedResult?.data;
64
+ if (!e?.location) return "";
65
+ let n = K(e.location);
66
+ return `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(n)}`;
67
+ }), K = (e) => e ? typeof e == "string" ? e : `${e.lat}, ${e.lng}` : "", ve = (e) => new DOMParser().parseFromString(e, "text/html").body.textContent || "", ye = () => {
68
+ let e = [];
69
+ return i.value.forEach((t, n) => {
70
+ let r = t.position;
71
+ if (r) {
72
+ let i = typeof r.lat == "function" ? r.lat() : r.lat, a = typeof r.lng == "function" ? r.lng() : r.lng;
73
+ e.push({
74
+ id: n,
75
+ position: {
76
+ lat: i,
77
+ lng: a
78
+ },
79
+ title: t.title || void 0
80
+ });
81
+ }
82
+ }), e;
83
+ }, q = (e, n, r) => {
84
+ if (!t.onUpdateResult) return;
85
+ let i = {
86
+ action: t.selectedResult?.data?.action || "showLocation",
87
+ success: e,
88
+ center: H.value || void 0,
89
+ zoom: U.value,
90
+ markers: ye(),
91
+ ...r
92
+ };
93
+ n && (i.error = n), t.onUpdateResult(i);
94
+ }, be = () => new Promise((e, n) => {
95
+ if (typeof google < "u" && google.maps && typeof google.maps.importLibrary == "function") {
96
+ e();
97
+ return;
98
+ }
99
+ let r = document.querySelector("script[src*=\"maps.googleapis.com\"]"), i = (t) => {
100
+ typeof google < "u" && google.maps && typeof google.maps.importLibrary == "function" ? e() : Date.now() - t > 1e4 ? n(/* @__PURE__ */ Error("Timeout waiting for Google Maps to load")) : setTimeout(() => i(t), 50);
101
+ };
102
+ if (r) {
103
+ i(Date.now());
104
+ return;
105
+ }
106
+ let a = document.createElement("script");
107
+ a.src = `https://maps.googleapis.com/maps/api/js?key=${t.googleMapKey}&loading=async`, a.async = !0, a.defer = !0, a.onload = () => i(Date.now()), a.onerror = () => n(/* @__PURE__ */ Error("Failed to load Google Maps")), document.head.appendChild(a);
108
+ }), xe = async () => {
109
+ if (!(!n.value || !t.googleMapKey) && !r.value) try {
110
+ await be();
111
+ let e = await google.maps.importLibrary("marker"), i = await google.maps.importLibrary("places");
112
+ I = e.AdvancedMarkerElement, L = i.Place, r.value = new google.maps.Map(n.value, {
113
+ center: {
114
+ lat: 35.6812,
115
+ lng: 139.7671
116
+ },
117
+ zoom: U.value,
118
+ mapTypeControl: !0,
119
+ streetViewControl: !0,
120
+ fullscreenControl: !0,
121
+ mapId: "DEMO_MAP_ID"
122
+ }), F.value = new google.maps.Geocoder(), d.value = new google.maps.DirectionsService(), P.value = new google.maps.DirectionsRenderer(), P.value.setMap(r.value), r.value.addListener("center_changed", () => {
123
+ let e = r.value?.getCenter();
124
+ e && (H.value = {
125
+ lat: e.lat(),
126
+ lng: e.lng()
127
+ });
128
+ }), r.value.addListener("zoom_changed", () => {
129
+ U.value = r.value?.getZoom() || 15;
130
+ }), t.selectedResult?.data && await Z(t.selectedResult.data);
131
+ } catch (e) {
132
+ z.value = e instanceof Error ? e.message : "Failed to initialize map";
133
+ }
134
+ }, J = async (e) => typeof e == "string" ? F.value ? new Promise((t) => {
135
+ F.value.geocode({ address: e }, (e, n) => {
136
+ if (n === "OK" && e && e[0]) {
137
+ let n = e[0].geometry.location;
138
+ t({
139
+ lat: n.lat(),
140
+ lng: n.lng()
141
+ });
142
+ } else t(null);
143
+ });
144
+ }) : null : e, Y = (e, t, n, a) => {
145
+ let o;
146
+ if (a) {
147
+ let e = document.createElement("div");
148
+ e.className = "marker-label", e.style.cssText = "background: #4285f4; color: white; padding: 4px 8px; border-radius: 4px; font-weight: bold; font-size: 12px;", e.textContent = a, o = e;
149
+ }
150
+ let s = new I({
151
+ position: e,
152
+ map: r.value,
153
+ title: n,
154
+ content: o
155
+ });
156
+ return i.value.set(t, s), s;
157
+ }, X = () => {
158
+ i.value.forEach((e) => {
159
+ e.map = null;
160
+ }), i.value.clear();
161
+ }, Z = async (e) => {
162
+ if (r.value) {
163
+ R.value = !0, z.value = null;
164
+ try {
165
+ switch (e.action) {
166
+ case "showLocation":
167
+ case "setCenter": {
168
+ if (!e.location) throw Error("Location is required");
169
+ let t = await J(e.location);
170
+ if (!t) throw Error("Could not find location");
171
+ r.value.setCenter(t), H.value = t, e.action === "showLocation" && Y(t, `location_${Date.now()}`, typeof e.location == "string" ? e.location : void 0), q(!0);
172
+ break;
173
+ }
174
+ case "setZoom": {
175
+ let t = e.zoom || 15;
176
+ r.value.setZoom(t), U.value = t, q(!0);
177
+ break;
178
+ }
179
+ case "addMarker": {
180
+ if (!e.location) throw Error("Location is required for marker");
181
+ let t = await J(e.location);
182
+ if (!t) throw Error("Could not find location for marker");
183
+ Y(t, e.marker?.id || `marker_${Date.now()}`, e.marker?.title, e.marker?.label), q(!0);
184
+ break;
185
+ }
186
+ case "clearMarkers":
187
+ X(), P.value?.setDirections({
188
+ routes: [],
189
+ request: {}
190
+ }), B.value = [], V.value = null, q(!0);
191
+ break;
192
+ case "findPlaces":
193
+ await Se(e.searchQuery, e.placeType);
194
+ break;
195
+ case "getDirections":
196
+ if (!e.origin || !e.destination) throw Error("Origin and destination are required");
197
+ await Ce(e.origin, e.destination, e.travelMode || "DRIVING");
198
+ break;
199
+ }
200
+ } catch (e) {
201
+ let t = e instanceof Error ? e.message : "An error occurred";
202
+ z.value = t, q(!1, t);
203
+ } finally {
204
+ R.value = !1;
205
+ }
206
+ }
207
+ }, Se = async (e, t) => {
208
+ if (!r.value || !L) return;
209
+ let n = r.value.getCenter();
210
+ if (n) try {
211
+ let a = {
212
+ textQuery: e || t || "",
213
+ locationBias: {
214
+ center: {
215
+ lat: n.lat(),
216
+ lng: n.lng()
217
+ },
218
+ radius: 5e3
219
+ },
220
+ fields: [
221
+ "id",
222
+ "displayName",
223
+ "formattedAddress",
224
+ "location",
225
+ "rating",
226
+ "userRatingCount",
227
+ "types",
228
+ "regularOpeningHours"
229
+ ],
230
+ maxResultCount: 10
231
+ };
232
+ t && !e && (a.includedType = t);
233
+ let { places: o } = await L.searchByText(a);
234
+ if (o && o.length > 0) {
235
+ [...i.value.keys()].filter((e) => e.startsWith("place_")).forEach((e) => {
236
+ let t = i.value.get(e);
237
+ t && (t.map = null, i.value.delete(e));
238
+ });
239
+ let e = o.map((e, t) => {
240
+ let n = e.location, r = n ? {
241
+ lat: n.lat(),
242
+ lng: n.lng()
243
+ } : {
244
+ lat: 0,
245
+ lng: 0
246
+ };
247
+ return n && Y(r, `place_${e.id}`, e.displayName || void 0, String(t + 1)), {
248
+ placeId: e.id || "",
249
+ name: e.displayName || "",
250
+ address: e.formattedAddress || "",
251
+ location: r,
252
+ rating: e.rating ?? void 0,
253
+ userRatingsTotal: e.userRatingCount ?? void 0,
254
+ types: e.types,
255
+ openNow: void 0
256
+ };
257
+ });
258
+ if (B.value = e, V.value = null, e.length > 0) {
259
+ let t = new google.maps.LatLngBounds();
260
+ e.forEach((e) => {
261
+ t.extend(e.location);
262
+ }), r.value?.fitBounds(t);
263
+ }
264
+ q(!0, void 0, { places: e });
265
+ } else q(!1, "No places found");
266
+ } catch {
267
+ q(!1, "No places found");
268
+ }
269
+ }, Ce = async (e, t, n) => {
270
+ if (!d.value || !P.value) return;
271
+ let r = {
272
+ origin: e,
273
+ destination: t,
274
+ travelMode: n
275
+ };
276
+ return new Promise((e) => {
277
+ d.value.route(r, (t, n) => {
278
+ if (n === google.maps.DirectionsStatus.OK && t) {
279
+ P.value.setDirections(t);
280
+ let e = t.routes[0]?.legs[0];
281
+ if (e) {
282
+ let n = {
283
+ summary: t.routes[0].summary || "",
284
+ distance: e.distance?.text || "",
285
+ duration: e.duration?.text || "",
286
+ startAddress: e.start_address || "",
287
+ endAddress: e.end_address || "",
288
+ steps: e.steps?.map((e) => ({
289
+ instruction: e.instructions || "",
290
+ distance: e.distance?.text || "",
291
+ duration: e.duration?.text || "",
292
+ travelMode: e.travel_mode || "",
293
+ startLocation: e.start_location ? {
294
+ lat: e.start_location.lat(),
295
+ lng: e.start_location.lng()
296
+ } : void 0,
297
+ endLocation: e.end_location ? {
298
+ lat: e.end_location.lat(),
299
+ lng: e.end_location.lng()
300
+ } : void 0
301
+ })) || [],
302
+ polyline: t.routes[0].overview_polyline || ""
303
+ };
304
+ V.value = n, B.value = [], q(!0, void 0, { route: n });
305
+ }
306
+ } else q(!1, "Could not find directions");
307
+ e();
308
+ });
309
+ });
310
+ }, we = (e) => {
311
+ r.value && (r.value.setCenter(e.location), r.value.setZoom(17));
312
+ }, Q = (e) => {
313
+ if (!r.value) return;
314
+ let t = e.startLocation || e.endLocation;
315
+ t && (r.value.setCenter(t), r.value.setZoom(18));
316
+ }, Te = () => {
317
+ if (!r.value) return;
318
+ let e = r.value.getZoom() || 15;
319
+ e < 21 && r.value.setZoom(e + 1);
320
+ }, Ee = () => {
321
+ if (!r.value) return;
322
+ let e = r.value.getZoom() || 15;
323
+ e > 1 && r.value.setZoom(e - 1);
324
+ }, $ = null;
325
+ return y(() => t.selectedResult?.data, async (e) => {
326
+ if (e && r.value) {
327
+ let t = JSON.stringify(e);
328
+ if (t === $) return;
329
+ $ = t, await Z(e);
330
+ }
331
+ }), p(() => {
332
+ t.googleMapKey && xe();
333
+ }), m(() => {
334
+ X();
335
+ }), (t, i) => (h(), c("div", b, [l("div", x, [l("h2", ee, v(ge.value), 1), W.value ? (h(), c("p", te, v(W.value), 1)) : s("", !0)]), l("div", ne, [l("div", re, [
336
+ e.googleMapKey ? (h(), c("div", {
337
+ key: 0,
338
+ ref_key: "mapContainer",
339
+ ref: n,
340
+ class: "w-full h-full"
341
+ }, null, 512)) : (h(), c("div", ie, [l("div", ae, [i[0] ||= l("div", { class: "text-gray-500 mb-4" }, "Google Maps API key not configured", -1), G.value ? (h(), c("a", {
342
+ key: 0,
343
+ href: G.value,
344
+ target: "_blank",
345
+ class: "inline-block px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors"
346
+ }, " Open in Google Maps ", 8, oe)) : s("", !0)])])),
347
+ R.value ? (h(), c("div", se, [...i[1] ||= [l("div", { class: "text-gray-600" }, "Loading...", -1)]])) : s("", !0),
348
+ z.value ? (h(), c("div", ce, v(z.value), 1)) : s("", !0),
349
+ e.googleMapKey && r.value ? (h(), c("div", le, [l("button", {
350
+ onClick: Te,
351
+ class: "w-8 h-8 bg-white border border-gray-300 rounded shadow text-lg font-bold text-gray-700 hover:bg-gray-100 flex items-center justify-center",
352
+ title: "Zoom in"
353
+ }, " + "), l("button", {
354
+ onClick: Ee,
355
+ class: "w-8 h-8 bg-white border border-gray-300 rounded shadow text-lg font-bold text-gray-700 hover:bg-gray-100 flex items-center justify-center",
356
+ title: "Zoom out"
357
+ }, " ")])) : s("", !0)
358
+ ]), _e.value ? (h(), c("div", ue, [B.value.length > 0 ? (h(), c("div", de, [i[3] ||= l("h3", { class: "font-semibold text-gray-800 mb-3" }, "Search Results", -1), l("div", fe, [(h(!0), c(a, null, _(B.value, (e) => (h(), c("div", {
359
+ key: e.placeId,
360
+ class: "p-3 bg-gray-50 rounded-lg cursor-pointer hover:bg-gray-100 transition-colors",
361
+ onClick: (t) => we(e)
362
+ }, [
363
+ l("div", me, v(e.name), 1),
364
+ l("div", he, v(e.address), 1),
365
+ e.rating ? (h(), c("div", S, [i[2] ||= l("span", { class: "text-yellow-500 mr-1" }, "★", -1), l("span", C, [u(v(e.rating.toFixed(1)) + " ", 1), e.userRatingsTotal ? (h(), c("span", w, " (" + v(e.userRatingsTotal) + ") ", 1)) : s("", !0)])])) : s("", !0),
366
+ e.openNow === void 0 ? s("", !0) : (h(), c("div", {
367
+ key: 1,
368
+ class: f([e.openNow ? "text-green-600" : "text-red-600", "text-sm mt-1"])
369
+ }, v(e.openNow ? "Open now" : "Closed"), 3))
370
+ ], 8, pe))), 128))])])) : s("", !0), V.value ? (h(), c("div", T, [
371
+ i[6] ||= l("h3", { class: "font-semibold text-gray-800 mb-3" }, "Directions", -1),
372
+ l("div", E, [l("div", D, v(V.value.distance), 1), l("div", O, v(V.value.duration), 1)]),
373
+ l("div", k, [l("div", null, [i[4] ||= l("strong", null, "From:", -1), u(" " + v(V.value.startAddress), 1)]), l("div", null, [i[5] ||= l("strong", null, "To:", -1), u(" " + v(V.value.endAddress), 1)])]),
374
+ l("div", A, [(h(!0), c(a, null, _(V.value.steps, (e, t) => (h(), c("div", {
375
+ key: t,
376
+ class: "p-2 bg-gray-50 rounded text-sm cursor-pointer hover:bg-blue-50 transition-colors",
377
+ onClick: (t) => Q(e)
378
+ }, [l("div", M, v(ve(e.instruction)), 1), l("div", N, v(e.distance) + " · " + v(e.duration), 1)], 8, j))), 128))])
379
+ ])) : s("", !0)])) : s("", !0)])]));
380
+ }
381
+ }), F = { class: "text-xs text-gray-600 mt-1 truncate" }, I = /* @__PURE__ */ d({
382
+ __name: "Preview",
383
+ props: { result: {} },
384
+ setup(e) {
385
+ let t = e, n = (e) => e ? typeof e == "string" ? e : `${e.lat.toFixed(4)}, ${e.lng.toFixed(4)}` : "", r = o(() => ({
386
+ showLocation: "Map Location",
387
+ setCenter: "Center Map",
388
+ setZoom: "Zoom",
389
+ addMarker: "Add Marker",
390
+ clearMarkers: "Clear Markers",
391
+ findPlaces: "Place Search",
392
+ getDirections: "Directions"
393
+ })[t.result.data?.action || "showLocation"] || "Map"), i = o(() => {
394
+ let e = t.result.data;
395
+ if (!e) return "";
396
+ switch (e.action) {
397
+ case "showLocation":
398
+ case "setCenter":
399
+ case "addMarker": return n(e.location);
400
+ case "setZoom": return `Level ${e.zoom}`;
401
+ case "clearMarkers": return "All markers cleared";
402
+ case "findPlaces": return e.searchQuery || e.placeType || "Search";
403
+ case "getDirections": return `${typeof e.origin == "string" ? e.origin : "Start"} → ${typeof e.destination == "string" ? e.destination : "End"}`;
404
+ default: return n(e.location);
405
+ }
406
+ }), a = o(() => ({
407
+ showLocation: "bg-blue-50",
408
+ setCenter: "bg-blue-50",
409
+ setZoom: "bg-purple-50",
410
+ addMarker: "bg-green-50",
411
+ clearMarkers: "bg-gray-50",
412
+ findPlaces: "bg-yellow-50",
413
+ getDirections: "bg-orange-50"
414
+ })[t.result.data?.action || "showLocation"] || "bg-blue-50"), s = o(() => ({
415
+ showLocation: "text-blue-600",
416
+ setCenter: "text-blue-600",
417
+ setZoom: "text-purple-600",
418
+ addMarker: "text-green-600",
419
+ clearMarkers: "text-gray-600",
420
+ findPlaces: "text-yellow-700",
421
+ getDirections: "text-orange-600"
422
+ })[t.result.data?.action || "showLocation"] || "text-blue-600");
423
+ return (e, t) => (h(), c("div", { class: f(["text-center p-4 rounded", a.value]) }, [l("div", { class: f(["font-medium", s.value]) }, v(r.value), 3), l("div", F, v(i.value), 1)], 2));
424
+ }
425
+ }), L = {
426
+ ...e,
427
+ viewComponent: P,
428
+ previewComponent: I,
429
+ samples: i
430
+ }, R = { plugin: L };
431
+ //#endregion
432
+ export { I as Preview, n as TOOL_DEFINITION, r as TOOL_NAME, P as View, R as default, t as executeMap, L as plugin, e as pluginCore, i as samples };