@deck.gl/widgets 9.2.0 → 9.2.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/compass-widget.js +1 -1
- package/dist/compass-widget.js.map +1 -1
- package/dist/context-menu-widget.js +1 -1
- package/dist/context-menu-widget.js.map +1 -1
- package/dist/dist.dev.js +34 -51
- package/dist/fps-widget.js +1 -1
- package/dist/fps-widget.js.map +1 -1
- package/dist/fullscreen-widget.js +1 -1
- package/dist/fullscreen-widget.js.map +1 -1
- package/dist/geocoder-widget.js +1 -1
- package/dist/geocoder-widget.js.map +1 -1
- package/dist/gimbal-widget.js +1 -1
- package/dist/gimbal-widget.js.map +1 -1
- package/dist/index.cjs +17 -17
- package/dist/index.cjs.map +2 -2
- package/dist/info-widget.js +1 -1
- package/dist/info-widget.js.map +1 -1
- package/dist/loading-widget.js +1 -1
- package/dist/loading-widget.js.map +1 -1
- package/dist/reset-view-widget.js +1 -1
- package/dist/reset-view-widget.js.map +1 -1
- package/dist/scale-widget.js +1 -1
- package/dist/scale-widget.js.map +1 -1
- package/dist/screenshot-widget.js +1 -1
- package/dist/screenshot-widget.js.map +1 -1
- package/dist/splitter-widget.js +1 -1
- package/dist/splitter-widget.js.map +1 -1
- package/dist/stats-widget.js +1 -1
- package/dist/stats-widget.js.map +1 -1
- package/dist/theme-widget.js +1 -1
- package/dist/theme-widget.js.map +1 -1
- package/dist/timeline-widget.js +1 -1
- package/dist/timeline-widget.js.map +1 -1
- package/dist/view-selector-widget.js +1 -1
- package/dist/view-selector-widget.js.map +1 -1
- package/dist/zoom-widget.js +1 -1
- package/dist/zoom-widget.js.map +1 -1
- package/dist.min.js +2 -2
- package/package.json +4 -4
- package/src/compass-widget.tsx +1 -1
- package/src/context-menu-widget.tsx +1 -1
- package/src/fps-widget.tsx +1 -1
- package/src/fullscreen-widget.tsx +1 -1
- package/src/geocoder-widget.tsx +1 -1
- package/src/gimbal-widget.tsx +1 -1
- package/src/info-widget.tsx +1 -1
- package/src/loading-widget.tsx +1 -1
- package/src/reset-view-widget.tsx +1 -1
- package/src/scale-widget.tsx +1 -1
- package/src/screenshot-widget.tsx +1 -1
- package/src/splitter-widget.tsx +1 -1
- package/src/stats-widget.tsx +1 -1
- package/src/theme-widget.tsx +1 -1
- package/src/timeline-widget.tsx +1 -1
- package/src/view-selector-widget.tsx +1 -1
- package/src/zoom-widget.tsx +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts", "../src/zoom-widget.tsx", "../src/lib/components/button-group.tsx", "../src/lib/components/grouped-icon-button.tsx", "../src/reset-view-widget.tsx", "../src/lib/components/icon-button.tsx", "../src/gimbal-widget.tsx", "../src/compass-widget.tsx", "../src/scale-widget.tsx", "../src/geocoder-widget.tsx", "../src/lib/components/dropdown-menu.tsx", "../src/lib/geocode/geocoder-history.ts", "../src/lib/geocode/geocoders.ts", "../src/fullscreen-widget.tsx", "../src/splitter-widget.tsx", "../src/view-selector-widget.tsx", "../src/lib/components/icon-menu.tsx", "../src/info-widget.tsx", "../src/context-menu-widget.tsx", "../src/lib/components/simple-menu.tsx", "../src/timeline-widget.tsx", "../src/screenshot-widget.tsx", "../src/theme-widget.tsx", "../src/themes.ts", "../src/loading-widget.tsx", "../src/fps-widget.tsx", "../src/stats-widget.tsx"],
|
|
4
|
-
"sourcesContent": ["// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// Navigation widgets\nexport {ZoomWidget} from './zoom-widget';\nexport {ResetViewWidget} from './reset-view-widget';\nexport {GimbalWidget} from './gimbal-widget';\n\n// Geospatial widgets\nexport {CompassWidget} from './compass-widget';\nexport {ScaleWidget as _ScaleWidget} from './scale-widget';\nexport {GeocoderWidget as _GeocoderWidget} from './geocoder-widget';\n\n// View widgets\nexport {FullscreenWidget} from './fullscreen-widget';\nexport {SplitterWidget as _SplitterWidget} from './splitter-widget';\nexport {ViewSelectorWidget as _ViewSelectorWidget} from './view-selector-widget';\n\n// Information widgets\nexport {InfoWidget as _InfoWidget} from './info-widget';\nexport {ContextMenuWidget as _ContextMenuWidget} from './context-menu-widget';\n\n// Control widgets\nexport {TimelineWidget as _TimelineWidget} from './timeline-widget';\n\n// Utility widgets\nexport {ScreenshotWidget} from './screenshot-widget';\nexport {ThemeWidget as _ThemeWidget} from './theme-widget';\nexport {LoadingWidget as _LoadingWidget} from './loading-widget';\nexport {FpsWidget as _FpsWidget} from './fps-widget';\nexport {StatsWidget as _StatsWidget} from './stats-widget';\n\nexport type {FullscreenWidgetProps} from './fullscreen-widget';\nexport type {CompassWidgetProps} from './compass-widget';\nexport type {ZoomWidgetProps} from './zoom-widget';\nexport type {ScreenshotWidgetProps} from './screenshot-widget';\nexport type {ResetViewWidgetProps} from './reset-view-widget';\nexport type {GeocoderWidgetProps} from './geocoder-widget';\nexport type {LoadingWidgetProps} from './loading-widget';\nexport type {FpsWidgetProps} from './fps-widget';\nexport type {ScaleWidgetProps} from './scale-widget';\nexport type {ThemeWidgetProps} from './theme-widget';\nexport type {InfoWidgetProps} from './info-widget';\nexport type {StatsWidgetProps} from './stats-widget';\nexport type {ContextMenuWidgetProps} from './context-menu-widget';\nexport type {SplitterWidgetProps} from './splitter-widget';\nexport type {TimelineWidgetProps} from './timeline-widget';\nexport type {ViewSelectorWidgetProps} from './view-selector-widget';\nexport type {GimbalWidgetProps} from './gimbal-widget';\n\nexport {LightTheme, DarkTheme, LightGlassTheme, DarkGlassTheme} from './themes';\nexport type {DeckWidgetTheme} from './themes';\n\n// Experimental preact components\nexport {ButtonGroup as _ButtonGroup, type ButtonGroupProps} from './lib/components/button-group';\nexport {IconButton as _IconButton, type IconButtonProps} from './lib/components/icon-button';\nexport {\n GroupedIconButton as _GroupedIconButton,\n type GroupedIconButtonProps\n} from './lib/components/grouped-icon-button';\nexport {\n DropdownMenu as _DropdownMenu,\n type DropdownMenuProps\n} from './lib/components/dropdown-menu';\nexport {SimpleMenu as _SimpleMenu, type SimpleMenuProps} from './lib/components/simple-menu';\nexport {IconMenu as _IconMenu, type IconMenuProps} from './lib/components/icon-menu';\n\n// Experimental geocoders. May be removed, use at your own risk!\nexport {type Geocoder} from './lib/geocode/geocoder';\nexport {\n GoogleGeocoder as _GoogleGeocoder,\n MapboxGeocoder as _MapboxGeocoder,\n OpenCageGeocoder as _OpenCageGeocoder,\n CoordinatesGeocoder as _CoordinatesGeocoder,\n CurrentLocationGeocoder as _CurrentLocationGeocoder\n} from './lib/geocode/geocoders';\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget, FlyToInterpolator, LinearInterpolator} from '@deck.gl/core';\nimport type {Viewport, WidgetProps, WidgetPlacement} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {ButtonGroup} from './lib/components/button-group';\nimport {GroupedIconButton} from './lib/components/grouped-icon-button';\n\nexport type ZoomWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Button orientation. */\n orientation?: 'vertical' | 'horizontal';\n /** Tooltip message on zoom in button. */\n zoomInLabel?: string;\n /** Tooltip message on zoom out button. */\n zoomOutLabel?: string;\n /** Zoom transition duration in ms. 0 disables the transition */\n transitionDuration?: number;\n};\n\nexport class ZoomWidget extends Widget<ZoomWidgetProps> {\n static defaultProps: Required<ZoomWidgetProps> = {\n ...Widget.defaultProps,\n id: 'zoom',\n placement: 'top-left',\n orientation: 'vertical',\n transitionDuration: 200,\n zoomInLabel: 'Zoom In',\n zoomOutLabel: 'Zoom Out',\n viewId: null\n };\n\n className = 'deck-widget-zoom';\n placement: WidgetPlacement = 'top-left';\n viewports: {[id: string]: Viewport} = {};\n\n constructor(props: ZoomWidgetProps = {}) {\n super(props, ZoomWidget.defaultProps);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<ZoomWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const ui = (\n <ButtonGroup orientation={this.props.orientation}>\n <GroupedIconButton\n onClick={() => this.handleZoomIn()}\n label={this.props.zoomInLabel}\n className=\"deck-widget-zoom-in\"\n />\n <GroupedIconButton\n onClick={() => this.handleZoomOut()}\n label={this.props.zoomOutLabel}\n className=\"deck-widget-zoom-out\"\n />\n </ButtonGroup>\n );\n render(ui, rootElement);\n }\n\n onViewportChange(viewport: Viewport) {\n this.viewports[viewport.id] = viewport;\n }\n\n handleZoom(viewport: Viewport, nextZoom: number) {\n const viewId = this.viewId || viewport?.id || 'default-view';\n const nextViewState: Record<string, unknown> = {\n ...viewport,\n zoom: nextZoom\n };\n if (this.props.transitionDuration > 0) {\n nextViewState.transitionDuration = this.props.transitionDuration;\n nextViewState.transitionInterpolator =\n 'latitude' in nextViewState\n ? new FlyToInterpolator()\n : new LinearInterpolator({\n transitionProps: ['zoom']\n });\n }\n this.setViewState(viewId, nextViewState);\n }\n\n handleZoomIn() {\n for (const viewport of Object.values(this.viewports)) {\n this.handleZoom(viewport, viewport.zoom + 1);\n }\n }\n\n handleZoomOut() {\n for (const viewport of Object.values(this.viewports)) {\n this.handleZoom(viewport, viewport.zoom - 1);\n }\n }\n\n /** @todo - move to deck or widget manager */\n private setViewState(viewId: string, viewState: Record<string, unknown>): void {\n // @ts-ignore Using private method temporary until there's a public one\n this.deck._onViewStateChange({viewId, viewState, interactionState: {}});\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ComponentChildren} from 'preact';\n\nexport type ButtonGroupProps = {\n children: ComponentChildren;\n orientation: 'vertical' | 'horizontal';\n};\n\n/** Renders a group of buttons with Widget CSS */\nexport const ButtonGroup = (props: ButtonGroupProps) => {\n const {children, orientation = 'horizontal'} = props;\n return <div className={`deck-widget-button-group ${orientation}`}>{children}</div>;\n};\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ComponentChildren, JSX} from 'preact';\n\nexport type GroupedIconButtonProps = {\n className?: string;\n label?: string;\n onClick?: JSX.MouseEventHandler<HTMLButtonElement>;\n children?: ComponentChildren;\n};\n\n/** Renders an icon button as part of a ButtonGroup */\nexport const GroupedIconButton = (props: GroupedIconButtonProps) => {\n const {className = '', label, onClick, children} = props;\n return (\n <button\n className={`deck-widget-icon-button ${className}`}\n type=\"button\"\n onClick={onClick}\n title={label}\n >\n {children ? children : <div className=\"deck-widget-icon\" />}\n </button>\n );\n};\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport type {ViewStateMap, ViewOrViews} from '@deck.gl/core/src/lib/view-manager';\nimport {render} from 'preact';\nimport {Widget} from '@deck.gl/core';\nimport {IconButton} from './lib/components/icon-button';\n\n/** Properties for the ResetViewWidget */\nexport type ResetViewWidgetProps<ViewsT extends ViewOrViews = null> = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** Tooltip message */\n label?: string;\n /** The initial view state to reset the view to. Defaults to deck.props.initialViewState */\n initialViewState?: ViewStateMap<ViewsT>;\n /** View to interact with. Required when using multiple views. */\n viewId?: string | null;\n};\n\n/**\n * A button widget that resets the view state of deck to an initial state.\n */\nexport class ResetViewWidget<ViewsT extends ViewOrViews = null> extends Widget<\n ResetViewWidgetProps<ViewsT>,\n ViewsT\n> {\n static defaultProps: Required<ResetViewWidgetProps> = {\n ...Widget.defaultProps,\n id: 'reset-view',\n placement: 'top-left',\n label: 'Reset View',\n initialViewState: undefined!,\n viewId: null\n };\n\n className = 'deck-widget-reset-view';\n placement: WidgetPlacement = 'top-left';\n\n constructor(props: ResetViewWidgetProps<ViewsT> = {}) {\n super(props, ResetViewWidget.defaultProps as Required<ResetViewWidgetProps<ViewsT>>);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<ResetViewWidgetProps<ViewsT>>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n render(\n <IconButton\n className=\"deck-widget-reset-focus\"\n label={this.props.label}\n onClick={this.handleClick.bind(this)}\n />,\n rootElement\n );\n }\n\n handleClick() {\n const initialViewState = this.props.initialViewState || this.deck?.props.initialViewState;\n this.setViewState(initialViewState);\n }\n\n setViewState(viewState?: ViewStateMap<ViewsT>) {\n const viewId = (this.props.viewId || 'default-view') as unknown as string;\n const nextViewState = {\n ...(viewId !== 'default-view' ? viewState?.[viewId] : viewState)\n // only works for geospatial?\n // transitionDuration: this.props.transitionDuration,\n // transitionInterpolator: new FlyToInterpolator()\n };\n // @ts-ignore Using private method temporary until there's a public one\n this.deck._onViewStateChange({viewId, viewState: nextViewState, interactionState: {}});\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ComponentChildren, JSX} from 'preact';\n\nexport type IconButtonProps = {\n className?: string;\n label?: string;\n onClick?: JSX.MouseEventHandler<HTMLButtonElement>;\n children?: ComponentChildren;\n};\n\n/** Renders a button component with widget CSS */\nexport const IconButton = (props: IconButtonProps) => {\n const {className = '', label, onClick, children} = props;\n return (\n <div className=\"deck-widget-button\">\n <button\n className={`deck-widget-icon-button ${className}`}\n type=\"button\"\n onClick={onClick}\n title={label}\n >\n {children ? children : <div className=\"deck-widget-icon\" />}\n </button>\n </div>\n );\n};\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget, LinearInterpolator} from '@deck.gl/core';\nimport type {Viewport, WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\n\nexport type GimbalWidgetProps = WidgetProps & {\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Tooltip message. */\n label?: string;\n /** Width of gimbal lines. */\n strokeWidth?: number;\n /** Transition duration in ms when resetting rotation. */\n transitionDuration?: number;\n};\n\nexport class GimbalWidget extends Widget<GimbalWidgetProps> {\n static defaultProps: Required<GimbalWidgetProps> = {\n ...Widget.defaultProps,\n id: 'gimbal',\n placement: 'top-left',\n viewId: null,\n label: 'Gimbal',\n strokeWidth: 1.5,\n transitionDuration: 200\n };\n\n className = 'deck-widget-gimbal';\n placement: WidgetPlacement = 'top-left';\n viewports: {[id: string]: Viewport} = {};\n\n constructor(props: GimbalWidgetProps = {}) {\n super(props, GimbalWidget.defaultProps);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<GimbalWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const viewId = this.viewId || Object.values(this.viewports)[0]?.id || 'default-view';\n const widgetViewport = this.viewports[viewId];\n const {rotationOrbit, rotationX} = this.getNormalizedRotation(widgetViewport);\n // Note - we use CSS 3D transforms instead of SVG 2D transforms\n const ui = (\n <div className=\"deck-widget-button\" style={{perspective: 100, pointerEvents: 'auto'}}>\n <button\n type=\"button\"\n onClick={() => {\n for (const viewport of Object.values(this.viewports)) {\n this.resetOrbitView(viewport);\n }\n }}\n title={this.props.label}\n style={{position: 'relative', width: 26, height: 26}}\n >\n {/* Outer ring */}\n <svg\n className=\"gimbal-outer-ring\"\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 26 26\"\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n transform: `rotateY(${rotationOrbit}deg)`\n }}\n >\n <circle\n cx=\"13\"\n cy=\"13\"\n r=\"10\"\n stroke=\"var(--icon-gimbal-outer-color, rgb(68, 92, 204))\"\n strokeWidth={this.props.strokeWidth}\n fill=\"none\"\n />\n </svg>\n\n {/* Inner ring */}\n <svg\n className=\"gimbal-inner-ring\"\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 26 26\"\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n transform: `rotateX(${rotationX}deg)`\n }}\n >\n <circle\n cx=\"13\"\n cy=\"13\"\n r=\"7\"\n stroke=\"var(--icon-gimbal-inner-color, rgb(240, 92, 68))\"\n strokeWidth={this.props.strokeWidth}\n fill=\"none\"\n />\n </svg>\n </button>\n </div>\n );\n\n render(ui, rootElement);\n }\n\n onViewportChange(viewport: Viewport) {\n this.viewports[viewport.id] = viewport;\n this.updateHTML();\n }\n\n resetOrbitView(viewport?: Viewport) {\n const viewId = this.getViewId(viewport);\n const viewState = this.getViewState(viewId);\n if ('rotationOrbit' in viewState || 'rotationX' in viewState) {\n const nextViewState = {\n ...viewState,\n rotationOrbit: 0,\n rotationX: 0,\n transitionDuration: this.props.transitionDuration,\n transitionInterpolator: new LinearInterpolator({\n transitionProps: ['rotationOrbit', 'rotationX']\n })\n };\n // @ts-ignore Using private method temporary until there's a public one\n this.deck._onViewStateChange({viewId, viewState: nextViewState, interactionState: {}});\n }\n }\n\n getNormalizedRotation(viewport?: Viewport): {rotationOrbit: number; rotationX: number} {\n const viewState = this.getViewState(this.getViewId(viewport));\n const [rz, rx] = this.getRotation(viewState);\n const rotationOrbit = normalizeAndClampAngle(rz);\n const rotationX = normalizeAndClampAngle(rx);\n return {rotationOrbit, rotationX};\n }\n\n getRotation(viewState?: any): [number, number] {\n if (viewState && ('rotationOrbit' in viewState || 'rotationX' in viewState)) {\n return [-(viewState.rotationOrbit || 0), viewState.rotationX || 0];\n }\n return [0, 0];\n }\n\n // Move to Widget/WidgetManager?\n\n getViewId(viewport?: Viewport) {\n const viewId = this.viewId || viewport?.id || 'OrbitView';\n return viewId;\n }\n\n getViewState(viewId: string) {\n const viewManager = this.getViewManager();\n const viewState = (viewId && viewManager.getViewState(viewId)) || viewManager.viewState;\n return viewState;\n }\n\n getViewManager() {\n // @ts-expect-error protected\n const viewManager = this.deck?.viewManager;\n if (!viewManager) {\n throw new Error('wigdet must be added to a deck instance');\n }\n return viewManager;\n }\n}\n\nfunction normalizeAndClampAngle(angle: number): number {\n // Bring angle into [-180, 180]\n let normalized = ((((angle + 180) % 360) + 360) % 360) - 180;\n\n // Avoid rotating the gimbal rings to close to 90 degrees as they will visually disappear\n const AVOID_ANGLE_DELTA = 10;\n const distanceFrom90 = normalized - 90;\n if (Math.abs(distanceFrom90) < AVOID_ANGLE_DELTA) {\n if (distanceFrom90 < AVOID_ANGLE_DELTA) {\n normalized = 90 + AVOID_ANGLE_DELTA;\n } else if (distanceFrom90 > -AVOID_ANGLE_DELTA) {\n normalized = 90 - AVOID_ANGLE_DELTA;\n }\n }\n // Clamp to [-80, 80]\n return normalized; // Math.max(-80, Math.min(80, normalized));\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget, FlyToInterpolator, WebMercatorViewport, _GlobeViewport} from '@deck.gl/core';\nimport type {Viewport, WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\n\nexport type CompassWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Tooltip message. */\n label?: string;\n /** Bearing and pitch reset transition duration in ms. */\n transitionDuration?: number;\n};\n\nexport class CompassWidget extends Widget<CompassWidgetProps> {\n static defaultProps: Required<CompassWidgetProps> = {\n ...Widget.defaultProps,\n id: 'compass',\n placement: 'top-left',\n viewId: null,\n label: 'Reset Compass',\n transitionDuration: 200\n };\n\n className = 'deck-widget-compass';\n placement: WidgetPlacement = 'top-left';\n viewports: {[id: string]: Viewport} = {};\n\n constructor(props: CompassWidgetProps = {}) {\n super(props, CompassWidget.defaultProps);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<CompassWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const viewId = this.viewId || Object.values(this.viewports)[0]?.id || 'default-view';\n const widgetViewport = this.viewports[viewId];\n const [rz, rx] = this.getRotation(widgetViewport);\n\n const ui = (\n <div className=\"deck-widget-button\" style={{perspective: 100}}>\n <button\n type=\"button\"\n onClick={() => {\n for (const viewport of Object.values(this.viewports)) {\n this.handleCompassReset(viewport);\n }\n }}\n title={this.props.label}\n style={{transform: `rotateX(${rx}deg)`}}\n >\n <svg fill=\"none\" width=\"100%\" height=\"100%\" viewBox=\"0 0 26 26\">\n <g transform={`rotate(${rz},13,13)`}>\n <path\n d=\"M10 13.0001L12.9999 5L15.9997 13.0001H10Z\"\n fill=\"var(--icon-compass-north-color, rgb(240, 92, 68))\"\n />\n <path\n d=\"M16.0002 12.9999L13.0004 21L10.0005 12.9999H16.0002Z\"\n fill=\"var(--icon-compass-south-color, rgb(204, 204, 204))\"\n />\n </g>\n </svg>\n </button>\n </div>\n );\n\n render(ui, rootElement);\n }\n\n onViewportChange(viewport: Viewport) {\n // no need to update if viewport is the same\n if (!viewport.equals(this.viewports[viewport.id])) {\n this.viewports[viewport.id] = viewport;\n this.updateHTML();\n }\n }\n\n getRotation(viewport?: Viewport) {\n if (viewport instanceof WebMercatorViewport) {\n return [-viewport.bearing, viewport.pitch];\n } else if (viewport instanceof _GlobeViewport) {\n return [0, Math.max(-80, Math.min(80, viewport.latitude))];\n }\n return [0, 0];\n }\n\n handleCompassReset(viewport: Viewport) {\n const viewId = this.viewId || viewport.id || 'default-view';\n if (viewport instanceof WebMercatorViewport) {\n const nextViewState = {\n ...viewport,\n bearing: 0,\n ...(this.getRotation(viewport)[0] === 0 ? {pitch: 0} : {}),\n transitionDuration: this.props.transitionDuration,\n transitionInterpolator: new FlyToInterpolator()\n };\n // @ts-ignore Using private method temporary until there's a public one\n this.deck._onViewStateChange({viewId, viewState: nextViewState, interactionState: {}});\n }\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {WidgetPlacement, Viewport, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {Widget} from '@deck.gl/core';\n\nexport type ScaleWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'bottom-left'. */\n placement?: WidgetPlacement;\n /** Label for the scale widget */\n label?: string;\n /** View to attach to and interact with. Required when using multiple views */\n viewId?: string | null;\n};\n\n/**\n * A scale widget that displays a Google Maps\u2013like scale indicator.\n * Instead of text inside a div, this widget renders an SVG that contains a horizontal line\n * with two vertical tick marks (extending upward from the line only) and a pretty distance label\n * positioned to the left of the line. The horizontal line\u2019s length is computed from a \u201Cnice\u201D\n * candidate distance (e.g. 200, 500, 1000 m, etc.) so that its pixel width is between 100 and 200.\n */\nexport class ScaleWidget extends Widget<ScaleWidgetProps> {\n static defaultProps: Required<ScaleWidgetProps> = {\n ...Widget.defaultProps,\n id: 'scale',\n placement: 'bottom-left',\n label: 'Scale',\n viewId: null\n };\n\n className = 'deck-widget-scale';\n placement: WidgetPlacement = 'bottom-left';\n\n // The pixel width of the scale line (computed from a candidate distance)\n scaleWidth: number = 10;\n // The candidate distance (in meters) corresponding to the scale line length.\n scaleValue: number = 0;\n // The formatted distance label (e.g. \"200 m\" or \"1.0 km\")\n scaleText: string = '';\n\n constructor(props: ScaleWidgetProps = {}) {\n super(props, ScaleWidget.defaultProps);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<ScaleWidgetProps>): void {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n // Reserve space for the text label (to the left of the horizontal line)\n const lineOffsetX = 50;\n // Overall SVG width includes the left offset plus the computed scale line width.\n const svgWidth = lineOffsetX + this.scaleWidth;\n const tickHeight = 10; // vertical tick extends upward by 10 pixels from the horizontal line\n render(\n <svg\n className=\"deck-widget-scale\"\n width={svgWidth}\n height={30}\n style={{overflow: 'visible', background: 'transparent'}}\n onClick={this.handleClick.bind(this)}\n >\n {/* Pretty distance label positioned to the left of the horizontal line */}\n <text\n x={lineOffsetX + 5}\n y=\"10\"\n textAnchor=\"end\"\n alignmentBaseline=\"middle\"\n style={{fontSize: '16px', fill: 'black', fontWeight: 'bold', fontFamily: 'sans-serif'}}\n >\n {this.scaleText}\n </text>\n {/* Horizontal line */}\n <line\n x1={lineOffsetX}\n y1=\"15\"\n x2={lineOffsetX + this.scaleWidth}\n y2=\"15\"\n stroke=\"black\"\n strokeWidth=\"6\"\n />\n {/* Left vertical tick (extending upward from the horizontal line) */}\n <line\n x1={lineOffsetX}\n y1=\"15\"\n x2={lineOffsetX}\n y2={15 - tickHeight}\n stroke=\"black\"\n strokeWidth=\"6\"\n />\n {/* Right vertical tick (extending upward from the horizontal line) */}\n <line\n x1={lineOffsetX + this.scaleWidth}\n y1=\"15\"\n x2={lineOffsetX + this.scaleWidth}\n y2={15 - tickHeight}\n stroke=\"black\"\n strokeWidth=\"6\"\n />\n </svg>,\n rootElement\n );\n }\n\n onViewportChange(viewport: Viewport): void {\n // Only handle geospatial viewports (which contain latitude)\n if (!('latitude' in viewport)) return;\n\n const {latitude, zoom} = viewport as {latitude: number; zoom: number};\n const metersPerPixel = getMetersPerPixel(latitude, zoom);\n const {candidate, candidatePixels} = computeScaleCandidate(metersPerPixel);\n\n this.scaleValue = candidate;\n this.scaleWidth = candidatePixels;\n // Format the candidate distance for display (using km if >= 1000 m)\n if (candidate >= 1000) {\n this.scaleText = `${(candidate / 1000).toFixed(1)} km`;\n } else {\n this.scaleText = `${candidate} m`;\n }\n this.updateHTML();\n }\n\n handleClick(): void {}\n}\n\n/**\n * Compute the meters per pixel at a given latitude and zoom level.\n *\n * @param latitude - The current latitude.\n * @param zoom - The current zoom level.\n * @returns The number of meters per pixel.\n */\nfunction getMetersPerPixel(latitude: number, zoom: number): number {\n const earthCircumference = 40075016.686;\n return (earthCircumference * Math.cos((latitude * Math.PI) / 180)) / Math.pow(2, zoom + 8);\n}\n\n/**\n * Compute a \"nice\" scale candidate such that the scale bar width in pixels is between 100 and 200.\n * The candidate distance (in meters) will be one of a set of round numbers (100, 200, 500, 1000, 2000, 5000, etc.).\n *\n * @param metersPerPixel - The number of meters per pixel at the current zoom/latitude.\n * @returns An object containing the candidate distance and its width in pixels.\n */\nfunction computeScaleCandidate(metersPerPixel: number): {\n candidate: number;\n candidatePixels: number;\n} {\n const minPixels = 100;\n const maxPixels = 200;\n const targetPixels = (minPixels + maxPixels) / 2;\n const targetDistance = targetPixels * metersPerPixel;\n\n const exponent = Math.floor(Math.log10(targetDistance));\n const base = Math.pow(10, exponent);\n const multipliers = [1, 2, 5];\n\n let candidate = multipliers[0] * base;\n let candidatePixels = candidate / metersPerPixel;\n\n for (let i = 0; i < multipliers.length; i++) {\n const currentCandidate = multipliers[i] * base;\n const currentPixels = currentCandidate / metersPerPixel;\n if (currentPixels >= minPixels && currentPixels <= maxPixels) {\n candidate = currentCandidate;\n candidatePixels = currentPixels;\n break;\n }\n if (currentPixels > maxPixels) {\n candidate = i > 0 ? multipliers[i - 1] * base : currentCandidate;\n candidatePixels = candidate / metersPerPixel;\n break;\n }\n if (i === multipliers.length - 1 && currentPixels < minPixels) {\n candidate = multipliers[0] * base * 10;\n candidatePixels = candidate / metersPerPixel;\n }\n }\n return {candidate, candidatePixels};\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget} from '@deck.gl/core';\nimport type {WidgetPlacement, Viewport, WidgetProps} from '@deck.gl/core';\nimport {FlyToInterpolator, LinearInterpolator} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {DropdownMenu} from './lib/components/dropdown-menu';\nimport {type Geocoder} from './lib/geocode/geocoder';\nimport {GeocoderHistory} from './lib/geocode/geocoder-history';\nimport {\n GoogleGeocoder,\n MapboxGeocoder,\n OpenCageGeocoder,\n CoordinatesGeocoder,\n CurrentLocationGeocoder\n} from './lib/geocode/geocoders';\n\n/** @todo - is the the best we can do? */\ntype ViewState = Record<string, unknown>;\n\nconst CURRENT_LOCATION = 'current';\n\n/** Properties for the GeocoderWidget */\nexport type GeocoderWidgetProps = WidgetProps & {\n viewId?: string | null;\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** Tooltip message */\n label?: string;\n /** View state reset transition duration in ms. 0 disables the transition */\n transitionDuration?: number;\n /** Geocoding service selector, for declarative usage */\n geocoder?: 'google' | 'mapbox' | 'opencage' | 'coordinates' | 'custom';\n /** Custom geocoding service (Used when geocoder = 'custom') */\n customGeocoder?: Geocoder;\n /** API key used for geocoding services */\n apiKey?: string;\n /** Whether to use geolocation @note Experimental*/\n _geolocation?: boolean;\n};\n\n/**\n * A widget that display a text box that lets user type in a location\n * and a button that moves the view to that location.\n * @todo For now only supports coordinates, Could be extended with location service integrations.\n */\nexport class GeocoderWidget extends Widget<GeocoderWidgetProps> {\n static defaultProps: Required<GeocoderWidgetProps> = {\n ...Widget.defaultProps,\n id: 'geocoder',\n viewId: null,\n placement: 'top-left',\n label: 'Geocoder',\n transitionDuration: 200,\n geocoder: 'coordinates',\n customGeocoder: CoordinatesGeocoder,\n apiKey: '',\n _geolocation: false\n };\n\n className = 'deck-widget-geocoder';\n placement: WidgetPlacement = 'top-left';\n\n geocodeHistory = new GeocoderHistory({});\n addressText: string = '';\n geocoder: Geocoder = CoordinatesGeocoder;\n\n constructor(props: GeocoderWidgetProps = {}) {\n super(props, GeocoderWidget.defaultProps);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<GeocoderWidgetProps>): void {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n this.geocoder = getGeocoder(this.props);\n if (this.geocoder.requiresApiKey && !this.props.apiKey) {\n throw new Error(`API key is required for the ${this.geocoder.name} geocoder`);\n }\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const menuItems = this.props._geolocation\n ? [CURRENT_LOCATION, ...this.geocodeHistory.addressHistory]\n : [...this.geocodeHistory.addressHistory];\n render(\n <div\n className=\"deck-widget-geocoder\"\n style={{\n pointerEvents: 'auto',\n display: 'flex',\n alignItems: 'center',\n flexWrap: 'wrap' // Allows wrapping on smaller screens\n }}\n >\n <input\n type=\"text\"\n placeholder={this.geocoder.placeholderLocation ?? 'Enter address or location'}\n value={this.geocodeHistory.addressText}\n // @ts-expect-error event type\n onInput={e => this.setInput(e.target?.value || '')}\n onKeyPress={this.handleKeyPress}\n style={{\n flex: '1 1 auto',\n minWidth: '200px',\n margin: 0,\n padding: '8px',\n boxSizing: 'border-box'\n }}\n />\n <DropdownMenu\n menuItems={menuItems}\n onSelect={this.handleSelect}\n style={{\n margin: 2,\n padding: '4px 2px',\n boxSizing: 'border-box'\n }}\n />\n {this.geocodeHistory.errorText && (\n <div className=\"error\">{this.geocodeHistory.errorText}</div>\n )}\n </div>,\n rootElement\n );\n }\n\n setInput = (text: string) => {\n this.addressText = text;\n };\n\n handleKeyPress = e => {\n if (e.key === 'Enter') {\n this.handleSubmit();\n }\n };\n\n handleSelect = (address: string) => {\n this.setInput(address);\n this.handleSubmit();\n };\n\n /** Sync wrapper for async geocode() */\n handleSubmit = () => {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.geocode(this.addressText);\n };\n\n /** Perform geocoding */\n geocode: (address: string) => Promise<void> = async address => {\n const useGeolocation = this.props._geolocation && address === CURRENT_LOCATION;\n const geocoder = useGeolocation ? CurrentLocationGeocoder : this.geocoder;\n const coordinates = await this.geocodeHistory.geocode(\n geocoder,\n this.addressText,\n this.props.apiKey\n );\n if (coordinates) {\n this.setViewState(coordinates);\n }\n };\n\n // TODO - MOVE TO WIDGETIMPL?\n setViewState(viewState: ViewState) {\n const viewId = this.props.viewId || (viewState?.id as string) || 'default-view';\n const viewport = this.viewports[viewId] || {};\n const nextViewState: ViewState = {\n ...viewport,\n ...viewState\n };\n if (this.props.transitionDuration > 0) {\n nextViewState.transitionDuration = this.props.transitionDuration;\n nextViewState.transitionInterpolator =\n 'latitude' in nextViewState ? new FlyToInterpolator() : new LinearInterpolator();\n }\n\n // @ts-ignore Using private method temporary until there's a public one\n this.deck._onViewStateChange({viewId, viewState: nextViewState, interactionState: {}});\n }\n\n onViewportChange(viewport: Viewport) {\n this.viewports[viewport.id] = viewport;\n }\n\n viewports: Record<string, Viewport> = {};\n}\n\nfunction getGeocoder(props: {geocoder?: string; customGeocoder?: Geocoder}): Geocoder {\n switch (props.geocoder) {\n case 'google':\n return GoogleGeocoder;\n case 'mapbox':\n return MapboxGeocoder;\n case 'opencage':\n return OpenCageGeocoder;\n case 'coordinates':\n return CoordinatesGeocoder;\n case 'custom':\n if (!props.customGeocoder) {\n throw new Error('Custom geocoder is not defined');\n }\n return props.customGeocoder;\n default:\n throw new Error(`Unknown geocoder: ${props.geocoder}`);\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {type JSX} from 'preact';\nimport {useState, useRef, useEffect} from 'preact/hooks';\n\nexport type DropdownMenuProps = {\n menuItems: string[];\n onSelect: (value: string) => void;\n style?: JSX.CSSProperties;\n};\n\nexport const DropdownMenu = (props: DropdownMenuProps) => {\n const [isOpen, setIsOpen] = useState(false);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n const toggleDropdown = () => setIsOpen(!isOpen);\n\n const handleClickOutside = (event: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n }\n };\n\n useEffect(() => {\n document.addEventListener('mousedown', handleClickOutside);\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n };\n }, []);\n\n const handleSelect = (value: string) => {\n props.onSelect(value);\n setIsOpen(false);\n };\n\n return (\n <div\n className=\"dropdown-container\"\n ref={dropdownRef}\n style={{\n position: 'relative',\n display: 'inline-block',\n ...props.style\n }}\n >\n <button\n onClick={toggleDropdown}\n style={{\n width: '30px',\n height: '30px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n border: '1px solid #ccc',\n borderRadius: '4px',\n background: '#fff',\n cursor: 'pointer',\n padding: 0\n }}\n >\n \u25BC\n </button>\n {isOpen && (\n <ul\n style={{\n position: 'absolute',\n top: '100%',\n right: '100%',\n background: '#fff',\n border: '1px solid #ccc',\n borderRadius: '4px',\n listStyle: 'none',\n padding: '4px 0',\n margin: 0,\n zIndex: 1000,\n minWidth: '200px'\n }}\n >\n {props.menuItems.map(item => (\n <li\n key={item}\n onClick={() => handleSelect(item)}\n style={{\n padding: '4px 8px',\n cursor: 'pointer',\n whiteSpace: 'nowrap'\n }}\n >\n {item}\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n};\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {type Geocoder} from './geocoder';\n\nconst CURRENT_LOCATION = 'current';\nconst LOCAL_STORAGE_KEY = 'deck-geocoder-history';\n\nexport type GeocoderHistoryProps = {\n maxEntries?: number;\n};\n\n/**\n * An internal, experimental helper class for storing a list of locations in local storage.\n * @todo Remove the UI related state.\n */\nexport class GeocoderHistory {\n props: Required<GeocoderHistoryProps>;\n addressText = '';\n errorText = '';\n addressHistory: string[] = [];\n\n constructor(props: GeocoderHistoryProps) {\n this.props = {maxEntries: 5, ...props};\n this.addressHistory = this.loadPreviousAddresses();\n }\n\n /** PErform geocoding */\n async geocode(geocoder: Geocoder, address: string, apiKey: string) {\n this.errorText = '';\n this.addressText = address;\n try {\n const coordinates = await geocoder.geocode(address, apiKey);\n if (coordinates) {\n this.storeAddress(this.addressText);\n return coordinates;\n }\n this.errorText = 'Invalid address';\n } catch (error) {\n this.errorText = `${(error as Error).message}`;\n }\n return null;\n }\n\n loadPreviousAddresses(): string[] {\n try {\n const stored = window.localStorage.getItem(LOCAL_STORAGE_KEY);\n const list = stored && JSON.parse(stored);\n const addresses = Array.isArray(list)\n ? list.filter((v): v is string => typeof v === 'string')\n : [];\n return addresses;\n } catch {\n // ignore\n }\n return [];\n }\n\n storeAddress(address: string) {\n const cleaned = address.trim();\n if (!cleaned || cleaned === CURRENT_LOCATION) {\n return;\n }\n const deduped = [cleaned, ...this.addressHistory.filter(a => a !== cleaned)];\n this.addressHistory = deduped.slice(0, this.props.maxEntries);\n try {\n window.localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(this.addressHistory));\n } catch {\n // ignore\n }\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {type Geocoder} from './geocoder';\n\nconst GOOGLE_URL = 'https://maps.googleapis.com/maps/api/geocode/json';\nconst MAPBOX_URL = 'https://api.mapbox.com/geocoding/v5/mapbox.places';\nconst OPENCAGE_API_URL = 'https://api.opencagedata.com/geocode/v1/json';\n\n/**\n * A geocoder that uses the google geocoding service\n * @note Requires an API key from Google\n * @see https://developers.google.com/maps/documentation/geocoding/get-api-key\n */\nexport const GoogleGeocoder = {\n name: 'google',\n requiresApiKey: true,\n async geocode(\n address: string,\n apiKey: string\n ): Promise<{longitude: number; latitude: number} | null> {\n const encodedAddress = encodeURIComponent(address);\n const json = await fetchJson(`${GOOGLE_URL}?address=${encodedAddress}&key=${apiKey}`);\n\n switch (json.status) {\n case 'OK':\n const loc = json.results.length > 0 && json.results[0].geometry.location;\n return loc ? {longitude: loc.lng, latitude: loc.lat} : null;\n default:\n throw new Error(`Google Geocoder failed: ${json.status}`);\n }\n }\n} as const satisfies Geocoder;\n\n/**\n * A geocoder that uses the google geocoding service\n * @note Requires an API key from Mapbox\n * @see https://docs.mapbox.com/api/search/geocoding/\n */\nexport const MapboxGeocoder = {\n name: 'google',\n requiresApiKey: true,\n async geocode(\n address: string,\n apiKey: string\n ): Promise<{longitude: number; latitude: number} | null> {\n const encodedAddress = encodeURIComponent(address);\n const json = await fetchJson(`${MAPBOX_URL}/${encodedAddress}.json?access_token=${apiKey}`);\n\n if (Array.isArray(json.features) && json.features.length > 0) {\n const center = json.features[0].center;\n if (Array.isArray(center) && center.length >= 2) {\n return {longitude: center[0], latitude: center[1]};\n }\n }\n return null;\n }\n} as const satisfies Geocoder;\n\n/**\n * A geocoder that uses the google geocoding service\n * @note Requires an API key from OpenCageData\n * @see https://opencagedata.com/api\n */\nexport const OpenCageGeocoder = {\n name: 'opencage',\n requiresApiKey: true,\n async geocode(\n address: string,\n key: string\n ): Promise<{longitude: number; latitude: number} | null> {\n const encodedAddress = encodeURIComponent(address);\n const data = await fetchJson(`${OPENCAGE_API_URL}?q=${encodedAddress}&key=${key}`);\n if (Array.isArray(data.results) && data.results.length > 0) {\n const geometry = data.results[0].geometry;\n return {longitude: geometry.lng, latitude: geometry.lat};\n }\n return null;\n }\n} as const satisfies Geocoder;\n\n/**\n * A geocoder adapter that wraps the browser's geolocation API. Always returns the user's current location.\n * @note Not technically a geocoder, but a geolocation service that provides a source of locations.\n * @note The user must allow location access for this to work.\n */\nexport const CurrentLocationGeocoder = {\n name: 'current',\n requiresApiKey: false,\n /** Attempt to call browsers geolocation API */\n async geocode(): Promise<{longitude: number; latitude: number} | null> {\n if (!navigator.geolocation) {\n throw new Error('Geolocation not supported');\n }\n return new Promise((resolve, reject) => {\n navigator.geolocation.getCurrentPosition(\n /** @see https://developer.mozilla.org/docs/Web/API/GeolocationPosition */\n (position: GeolocationPosition) => {\n const {longitude, latitude} = position.coords;\n resolve({longitude, latitude});\n },\n /** @see https://developer.mozilla.org/docs/Web/API/GeolocationPositionError */\n (error: GeolocationPositionError) => reject(new Error(error.message))\n );\n });\n }\n} as const satisfies Geocoder;\n\n/** Fetch JSON, catching HTTP errors */\nasync function fetchJson(url: string): Promise<any> {\n let response: Response;\n try {\n response = await fetch(url);\n } catch (error) {\n // Annoyingly, fetch reports some errors (e.g. CORS) using excpetions, not response.ok\n throw new Error(`CORS error? ${error}. ${url}: `);\n }\n if (!response.ok) {\n throw new Error(`${response.statusText}. ${url}: `);\n }\n const data = await response.json();\n if (!data) {\n throw new Error(`No data returned. ${url}`);\n }\n return data;\n}\n\n/**\n * Parse a coordinate string.\n * Supports comma- or semicolon-separated values.\n * Heuristically determines which value is longitude and which is latitude.\n */\nexport const CoordinatesGeocoder = {\n name: 'coordinates',\n requiresApiKey: false,\n placeholderLocation: `-122.45, 37.8 or 37\u00B048'N, 122\u00B027'W`,\n async geocode(address: string): Promise<{longitude: number; latitude: number} | null> {\n return parseCoordinates(address) || null;\n }\n} as const satisfies Geocoder;\n\n/**\n * Parse an input string for coordinates.\n * Supports comma- or semicolon-separated values.\n * Heuristically determines which value is longitude and which is latitude.\n */\nfunction parseCoordinates(input) {\n input = input.trim();\n const parts = input.split(/[,;]/).map(p => p.trim());\n if (parts.length < 2) return null;\n const first = parseCoordinatePart(parts[0]);\n const second = parseCoordinatePart(parts[1]);\n if (first === null || second === null) return null;\n // Use a heuristic:\n // If one number exceeds 90 in absolute value, it's likely a longitude.\n if (Math.abs(first) > 90 && Math.abs(second) <= 90) {\n return {longitude: first, latitude: second};\n } else if (Math.abs(second) > 90 && Math.abs(first) <= 90) {\n return {longitude: second, latitude: first};\n }\n // If both are <= 90, assume order: latitude, longitude.\n return {latitude: first, longitude: second};\n}\n\n/**\n * Parse a single coordinate part (which may be in decimal or DMS format).\n */\nfunction parseCoordinatePart(s: string): number | null {\n s = s.trim();\n // If the string contains a degree symbol or similar markers, use DMS parsing.\n if (s.includes('\u00B0') || s.includes(\"'\") || s.includes('\"')) {\n const value = dmsToDecimal(s);\n return isNaN(value) ? null : value;\n }\n // Otherwise, check for a cardinal letter and remove it.\n let sign = 1;\n if (/[SW]/i.test(s)) sign = -1;\n s = s.replace(/[NSEW]/gi, '');\n const value = parseFloat(s);\n return isNaN(value) ? null : sign * value;\n}\n\n/** Convert a DMS string (e.g. \"37\u00B048'00\\\"N\") to decimal degrees. */\nfunction dmsToDecimal(s: string): number {\n // A simple regex to extract degrees, minutes, seconds and direction.\n const regex = /(\\d+)[\u00B0d]\\s*(\\d+)?['\u2032m]?\\s*(\\d+(?:\\.\\d+)?)?[\\\"\u2033s]?\\s*([NSEW])?/i;\n const match = s.match(regex);\n if (!match) return NaN;\n const degrees = parseFloat(match[1]) || 0;\n const minutes = parseFloat(match[2]) || 0;\n const seconds = parseFloat(match[3]) || 0;\n const direction = match[4] || '';\n let dec = degrees + minutes / 60 + seconds / 3600;\n if (/[SW]/i.test(direction)) {\n dec = -dec;\n }\n return dec;\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/* global document */\nimport {log, Widget, type WidgetProps, type WidgetPlacement} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {IconButton} from './lib/components/icon-button';\n\n/* eslint-enable max-len */\n\nexport type FullscreenWidgetProps = WidgetProps & {\n id?: string;\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Tooltip message when out of fullscreen. */\n enterLabel?: string;\n /** Tooltip message when fullscreen. */\n exitLabel?: string;\n /**\n * A compatible DOM element which should be made full screen. By default, the map container element will be made full screen.\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullScreen#Compatible_elements\n */\n container?: HTMLElement;\n};\n\nexport class FullscreenWidget extends Widget<FullscreenWidgetProps> {\n static defaultProps: Required<FullscreenWidgetProps> = {\n ...Widget.defaultProps,\n id: 'fullscreen',\n placement: 'top-left',\n viewId: null,\n enterLabel: 'Enter Fullscreen',\n exitLabel: 'Exit Fullscreen',\n container: undefined!\n };\n\n className = 'deck-widget-fullscreen';\n placement: WidgetPlacement = 'top-left';\n fullscreen: boolean = false;\n\n constructor(props: FullscreenWidgetProps = {}) {\n super(props, FullscreenWidget.defaultProps);\n this.setProps(this.props);\n }\n\n onAdd(): void {\n document.addEventListener('fullscreenchange', this.onFullscreenChange.bind(this));\n }\n\n onRemove() {\n document.removeEventListener('fullscreenchange', this.onFullscreenChange.bind(this));\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n render(\n <IconButton\n onClick={() => {\n this.handleClick().catch(err => log.error(err)());\n }}\n label={this.fullscreen ? this.props.exitLabel : this.props.enterLabel}\n className={this.fullscreen ? 'deck-widget-fullscreen-exit' : 'deck-widget-fullscreen-enter'}\n />,\n rootElement\n );\n }\n\n setProps(props: Partial<FullscreenWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n getContainer() {\n return this.props.container || this.deck?.getCanvas()?.parentElement;\n }\n\n onFullscreenChange() {\n const prevFullscreen = this.fullscreen;\n const fullscreen = document.fullscreenElement === this.getContainer();\n if (prevFullscreen !== fullscreen) {\n this.fullscreen = !this.fullscreen;\n }\n this.updateHTML();\n }\n\n async handleClick() {\n if (this.fullscreen) {\n await this.exitFullscreen();\n } else {\n await this.requestFullscreen();\n }\n this.updateHTML();\n }\n\n async requestFullscreen() {\n const container = this.getContainer();\n if (container?.requestFullscreen) {\n await container.requestFullscreen({navigationUI: 'hide'});\n } else {\n this.togglePseudoFullscreen();\n }\n }\n\n async exitFullscreen() {\n if (document.exitFullscreen) {\n await document.exitFullscreen();\n } else {\n this.togglePseudoFullscreen();\n }\n }\n\n togglePseudoFullscreen() {\n this.getContainer()?.classList.toggle('deck-pseudo-fullscreen');\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {h, render} from 'preact';\nimport {useState, useRef} from 'preact/hooks';\nimport {Widget, type WidgetProps} from '@deck.gl/core';\n\n/** Properties for the SplitterWidget */\nexport type SplitterWidgetProps = WidgetProps & {\n /** The view id for the first (resizable) view */\n viewId1: string;\n /** The view id for the second view */\n viewId2: string;\n /** Orientation of the splitter: vertical (default) or horizontal */\n orientation?: 'vertical' | 'horizontal';\n /** The initial split percentage (0 to 1) for the first view, default 0.5 */\n initialSplit?: number;\n /** Callback invoked when the splitter is dragged with the new split value */\n onChange?: (newSplit: number) => void;\n /** Callback invoked when dragging starts */\n onDragStart?: () => void;\n /** Callback invoked when dragging ends */\n onDragEnd?: () => void;\n};\n\n/**\n * A draggable splitter widget that appears as a vertical or horizontal line\n * across the deck.gl canvas. It positions itself based on the split percentage\n * of the first view and provides callbacks when dragged.\n */\nexport class SplitterWidget extends Widget<SplitterWidgetProps> {\n static defaultProps: Required<SplitterWidgetProps> = {\n ...Widget.defaultProps,\n id: 'splitter-widget',\n viewId1: '',\n viewId2: '',\n orientation: 'vertical',\n initialSplit: 0.5,\n onChange: () => {},\n onDragStart: () => {},\n onDragEnd: () => {}\n };\n\n className = 'deck-widget-splitter';\n placement = 'fill' as const;\n\n constructor(props: SplitterWidgetProps) {\n super(props, SplitterWidget.defaultProps);\n }\n\n setProps(props: Partial<SplitterWidgetProps>) {\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n // Ensure the widget container fills the deck.gl canvas.\n // TODO - Move styling to CSS\n rootElement.style.position = 'absolute';\n rootElement.style.top = '0';\n rootElement.style.left = '0';\n rootElement.style.width = '100%';\n rootElement.style.height = '100%';\n rootElement.style.margin = '0px';\n\n render(\n <Splitter\n orientation={this.props.orientation}\n initialSplit={this.props.initialSplit}\n onChange={this.props.onChange}\n onDragStart={this.props.onDragStart}\n onDragEnd={this.props.onDragEnd}\n />,\n rootElement\n );\n }\n}\n\n/**\n * A functional component that renders a draggable splitter line.\n * It computes its position based on the provided split percentage and\n * updates it during mouse drag events.\n */\nfunction Splitter({\n orientation,\n initialSplit,\n onChange,\n onDragStart,\n onDragEnd\n}: {\n orientation: 'vertical' | 'horizontal';\n initialSplit: number;\n onChange?: (newSplit: number) => void;\n onDragStart?: () => void;\n onDragEnd?: () => void;\n}) {\n const [split, setSplit] = useState(initialSplit);\n const dragging = useRef(false);\n const containerRef = useRef<HTMLDivElement>(null);\n\n const handleDragStart = (event: MouseEvent) => {\n dragging.current = true;\n onDragStart?.();\n document.addEventListener('mousemove', handleDragging);\n document.addEventListener('mouseup', handleDragEnd);\n event.preventDefault();\n };\n\n const handleDragging = (event: MouseEvent) => {\n if (!dragging.current || !containerRef.current) return;\n const rect = containerRef.current.getBoundingClientRect();\n let newSplit: number;\n if (orientation === 'vertical') {\n newSplit = (event.clientX - rect.left) / rect.width;\n } else {\n newSplit = (event.clientY - rect.top) / rect.height;\n }\n // Clamp newSplit between 5% and 95%\n newSplit = Math.min(Math.max(newSplit, 0.05), 0.95);\n setSplit(newSplit);\n onChange?.(newSplit);\n };\n\n const handleDragEnd = (event: MouseEvent) => {\n if (!dragging.current) return;\n dragging.current = false;\n onDragEnd?.();\n document.removeEventListener('mousemove', handleDragging);\n document.removeEventListener('mouseup', handleDragEnd);\n };\n\n // The splitter line style based on orientation and the current split percentage.\n const splitterStyle: h.JSX.CSSProperties =\n orientation === 'vertical'\n ? {\n position: 'absolute',\n top: 0,\n bottom: 0,\n left: `${split * 100}%`,\n width: '4px',\n cursor: 'col-resize',\n background: '#ccc',\n zIndex: 10,\n pointerEvents: 'auto',\n boxShadow: 'inset -1px 0 0 white, inset 1px 0 0 white'\n }\n : {\n position: 'absolute',\n left: 0,\n right: 0,\n top: `${split * 100}%`,\n height: '4px',\n cursor: 'row-resize',\n background: '#ccc',\n zIndex: 10,\n pointerEvents: 'auto',\n boxShadow: 'inset -1px 0 0 white, inset 1px 0 0 white'\n };\n\n // Container style to fill the entire deck.gl canvas.\n const containerStyle: h.JSX.CSSProperties = {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0\n };\n\n return (\n <div ref={containerRef} style={containerStyle}>\n <div\n style={splitterStyle}\n onMouseDown={handleDragStart as h.JSX.MouseEventHandler<HTMLElement>} // Use the appropriate Preact event type.\n />\n </div>\n );\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {render, JSX} from 'preact';\nimport {Widget, type WidgetProps, type WidgetPlacement} from '@deck.gl/core';\nimport {IconMenu} from './lib/components/icon-menu';\n\n/** The available view modes */\nexport type ViewMode = 'single' | 'split-horizontal' | 'split-vertical';\n\n/** Properties for the ViewSelectorWidget */\nexport type ViewSelectorWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Tooltip label */\n label?: string;\n /** The initial view mode. Defaults to 'single'. */\n initialViewMode?: ViewMode;\n /** Callback invoked when the view mode changes */\n onViewModeChange?: (mode: ViewMode) => void;\n};\n\n/**\n * A widget that renders a popup menu for selecting a view mode.\n * It displays a button with the current view mode icon. Clicking the button\n * toggles a popup that shows three icons for:\n * - Single view\n * - Two views, split horizontally\n * - Two views, split vertically\n */\nexport class ViewSelectorWidget extends Widget<ViewSelectorWidgetProps> {\n static defaultProps: Required<ViewSelectorWidgetProps> = {\n ...Widget.defaultProps,\n id: 'view-selector',\n placement: 'top-left',\n viewId: null,\n label: 'Split View',\n initialViewMode: 'single',\n onViewModeChange: () => {}\n };\n\n className = 'deck-widget-view-selector';\n placement: WidgetPlacement = 'top-left';\n viewMode: ViewMode;\n\n constructor(props: ViewSelectorWidgetProps = {}) {\n super(props, ViewSelectorWidget.defaultProps);\n this.viewMode = this.props.initialViewMode;\n this.setProps(this.props);\n }\n\n setProps(props: Partial<ViewSelectorWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement) {\n render(\n <IconMenu<ViewMode>\n className=\"deck-widget-view-selector\"\n menuItems={MENU_ITEMS.map(item => ({\n ...item,\n icon: item.icon()\n }))}\n initialItem={this.props.initialViewMode}\n onItemSelected={this.handleSelectMode}\n />,\n rootElement\n );\n }\n\n handleSelectMode = (viewMode: ViewMode) => {\n this.viewMode = viewMode;\n this.updateHTML();\n this.props.onViewModeChange(viewMode);\n };\n}\n\nconst ICON_STYLE = {width: '24px', height: '24px'};\n\n// JSX wrapped in a function to fix deck's Node tests\nconst ICONS: Record<ViewMode, () => JSX.Element> = {\n single: () => (\n <svg width=\"24\" height=\"24\" style={ICON_STYLE}>\n <rect\n x=\"4\"\n y=\"4\"\n width=\"16\"\n height=\"16\"\n stroke=\"var(--button-icon-hover, rgb(24, 24, 26))\"\n fill=\"none\"\n strokeWidth=\"2\"\n />\n </svg>\n ),\n 'split-horizontal': () => (\n <svg width=\"24\" height=\"24\" style={ICON_STYLE}>\n <rect\n x=\"4\"\n y=\"4\"\n width=\"16\"\n height=\"7\"\n stroke=\"var(--button-icon-hover, rgb(24, 24, 26))\"\n fill=\"none\"\n strokeWidth=\"2\"\n />\n <rect\n x=\"4\"\n y=\"13\"\n width=\"16\"\n height=\"7\"\n stroke=\"var(--button-icon-hover, rgb(24, 24, 26))\"\n fill=\"none\"\n strokeWidth=\"2\"\n />\n </svg>\n ),\n 'split-vertical': () => (\n <svg width=\"24\" height=\"24\" style={ICON_STYLE}>\n <rect\n x=\"4\"\n y=\"4\"\n width=\"7\"\n height=\"16\"\n stroke=\"var(--button-icon-hover, rgb(24, 24, 26))\"\n fill=\"none\"\n strokeWidth=\"2\"\n />\n <rect\n x=\"13\"\n y=\"4\"\n width=\"7\"\n height=\"16\"\n stroke=\"var(--button-icon-hover, rgb(24, 24, 26))\"\n fill=\"none\"\n strokeWidth=\"2\"\n />\n </svg>\n )\n};\n\n// Define menu items for the popup menu.\nconst MENU_ITEMS: Array<{value: ViewMode; icon: () => JSX.Element; label: string}> = [\n {value: 'single', icon: ICONS.single, label: 'Single View'},\n {value: 'split-horizontal', icon: ICONS['split-horizontal'], label: 'Split Horizontal'},\n {value: 'split-vertical', icon: ICONS['split-vertical'], label: 'Split Vertical'}\n];\n", "import type {JSX} from 'preact';\nimport {useState, useRef, useEffect} from 'preact/hooks';\nimport {IconButton} from './icon-button';\nimport {ButtonGroup} from './button-group';\nimport {GroupedIconButton} from './grouped-icon-button';\n\nexport type IconMenuProps<KeyType = string> = {\n className: string;\n icon?: JSX.Element;\n label?: string;\n menuItems: {value: KeyType; icon: JSX.Element; label: string}[];\n initialItem: KeyType;\n onItemSelected: (item: KeyType) => void;\n};\n\n/** A component that renders an icon popup menu */\nexport function IconMenu<KeyType extends string>(props: IconMenuProps<KeyType>) {\n const [menuOpen, setMenuOpen] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Close the menu when clicking outside.\n const handleClickOutside = (event: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\n setMenuOpen(false);\n }\n };\n\n useEffect(() => {\n document.addEventListener('mousedown', handleClickOutside);\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n };\n }, [containerRef]);\n\n const [selectedItem, setSelectedItem] = useState<KeyType>(props.initialItem);\n\n const handleSelectItem = (item: KeyType) => {\n setSelectedItem(item);\n setMenuOpen(false);\n props.onItemSelected(item);\n };\n\n const handleButtonClick = () => setMenuOpen(!menuOpen);\n\n const selectedMenuItem = props.menuItems.find(item => item.value === selectedItem);\n const label = props.label || selectedMenuItem?.label || '';\n const icon = (props.icon || selectedMenuItem?.icon)!;\n\n return (\n <div style={{position: 'relative', display: 'inline-block'}} ref={containerRef}>\n <IconButton className={props.className} label={label} onClick={handleButtonClick}>\n {icon}\n </IconButton>\n {menuOpen && (\n <div className=\"deck-widget-icon-menu\">\n <ButtonGroup orientation=\"vertical\">\n {props.menuItems.map(item => (\n <GroupedIconButton\n key={item.value}\n label={item.label}\n onClick={() => handleSelectItem(item.value)}\n >\n {item.icon}\n </GroupedIconButton>\n ))}\n </ButtonGroup>\n </div>\n )}\n </div>\n );\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget} from '@deck.gl/core';\nimport type {Deck, PickingInfo, Viewport, WidgetProps} from '@deck.gl/core';\nimport {render, JSX} from 'preact';\n\nexport type InfoWidgetProps = WidgetProps & {\n /** View to attach to and interact with. Required when using multiple views */\n viewId?: string | null;\n /** Determines the interaction mode of the widget */\n mode: 'click' | 'hover' | 'static';\n /** Function to generate the popup contents from the selected element */\n getTooltip?: (info: PickingInfo, widget: InfoWidget) => InfoWidgetProps | null;\n /** Position at which to place popup (clicked point: [longitude, latitude]) */\n position: [number, number];\n /** Text content of popup */\n text?: string;\n /** Visibility of info widget */\n visible?: boolean;\n /** Minimum offset (in pixels) to keep the popup away from the canvas edges. */\n minOffset?: number;\n /** Callback triggered when the widget is clicked. */\n onClick?: (widget: InfoWidget, info: PickingInfo) => boolean;\n};\n\nexport class InfoWidget extends Widget<InfoWidgetProps> {\n static defaultProps: Required<InfoWidgetProps> = {\n ...Widget.defaultProps,\n id: 'info',\n position: [0, 0],\n text: '',\n visible: false,\n minOffset: 0,\n viewId: null,\n mode: 'hover',\n getTooltip: undefined!,\n onClick: undefined!\n };\n\n className = 'deck-widget-info';\n placement = 'fill' as const;\n viewport?: Viewport;\n\n constructor(props: InfoWidgetProps) {\n super(props, InfoWidget.defaultProps);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<InfoWidgetProps>) {\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onCreateRootElement(): HTMLDivElement {\n const element = super.onCreateRootElement();\n const style = {margin: '0px', top: '0px', left: '0px', position: 'absolute'};\n Object.entries(style).forEach(([key, value]) => element.style.setProperty(key, value));\n return element;\n }\n\n onViewportChange(viewport) {\n this.viewport = viewport;\n this.updateHTML();\n }\n\n onHover(info: PickingInfo): void {\n if (this.props.mode === 'hover' && this.props.getTooltip) {\n const tooltip = this.props.getTooltip(info, this);\n // hover tooltips should show over static and click infos\n this.setProps({\n visible: tooltip !== null,\n ...tooltip,\n style: {zIndex: '1', ...tooltip?.style}\n });\n }\n }\n\n onClick(info: PickingInfo): boolean {\n if (this.props.mode === 'click' && this.props.getTooltip) {\n const tooltip = this.props.getTooltip(info, this);\n this.setProps({\n visible: tooltip !== null,\n ...tooltip\n });\n return tooltip !== null;\n }\n\n // Original behavior\n return this.props.onClick?.(this, info) || false;\n }\n\n onAdd({deck, viewId}: {deck: Deck<any>; viewId: string | null}) {\n this.deck = deck;\n if (!viewId) {\n this.viewport = deck.getViewports()[0];\n } else {\n this.viewport = deck.getViewports().find(viewport => viewport.id === viewId);\n }\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n if (!this.viewport) {\n return;\n }\n const [longitude, latitude] = this.props.position;\n // Project the clicked geographic coordinate to canvas (x, y)\n const [x, y] = this.viewport.project([longitude, latitude]);\n\n const minOffset = this.props.minOffset || 0;\n const gap = 10; // gap between clicked point and popup box\n const arrowHeight = 8; // height of the triangle arrow\n const arrowWidth = 16; // full width of the arrow\n\n // Decide vertical orientation.\n // If the clicked point is in the bottom half, place the popup above the point.\n const isAbove = y > this.viewport.height / 2;\n const background = (this.props.style && this.props.style.background) || 'rgba(255,255,255,0.9)';\n\n // Render the popup container with a content box and a placeholder for the arrow.\n // The container is positioned absolutely (initially at 0,0) and will be repositioned after measuring.\n const ui = this.props.visible ? (\n <div className=\"popup-container\" style={{position: 'absolute', left: 0, top: 0}}>\n <div\n className=\"popup-content\"\n style={{\n background,\n padding: '10px',\n position: 'relative',\n // Include any additional styles\n ...(this.props.style as JSX.CSSProperties)\n }}\n >\n {this.props.text}\n </div>\n <div className=\"popup-arrow\" style={{position: 'absolute', width: '0px', height: '0px'}} />\n </div>\n ) : null;\n render(ui, rootElement);\n\n // After rendering, measure the content and adjust positioning so that:\n // - The popup (with its arrow) does not cover the clicked point.\n // - The arrow's tip points to the clicked point.\n // - The popup remains within the canvas bounds, with minOffset.\n // eslint-disable-next-line max-statements, complexity\n requestAnimationFrame(() => {\n if (!this.props.visible || !rootElement.firstChild || !this.viewport) return;\n\n const container = rootElement.firstChild as HTMLElement;\n const contentEl = container.querySelector('.popup-content') as HTMLElement;\n const arrowEl = container.querySelector('.popup-arrow') as HTMLElement;\n if (!contentEl || !arrowEl) return;\n const contentRect = contentEl.getBoundingClientRect();\n const popupWidth = contentRect.width;\n const popupHeight = contentRect.height;\n\n // Compute ideal horizontal position: center the popup on the clicked x\n let computedLeft = x - popupWidth / 2;\n // Compute vertical position based on orientation:\n // If the popup is above, position its bottom edge (minus arrow & gap) at the clicked y.\n // Otherwise, position its top edge (plus arrow & gap) at the clicked y.\n let computedTop;\n if (isAbove) {\n computedTop = y - gap - arrowHeight - popupHeight;\n } else {\n computedTop = y + gap + arrowHeight;\n }\n\n // Ensure the popup (content) stays within horizontal bounds of the canvas\n if (computedLeft < minOffset) {\n computedLeft = minOffset;\n }\n if (computedLeft + popupWidth > this.viewport.width - minOffset) {\n computedLeft = this.viewport.width - minOffset - popupWidth;\n }\n\n // Ensure the vertical position (including the arrow) stays within canvas bounds.\n if (isAbove) {\n if (computedTop < minOffset) {\n computedTop = minOffset;\n }\n } else if (computedTop + popupHeight + arrowHeight > this.viewport.height - minOffset) {\n computedTop = this.viewport.height - minOffset - popupHeight - arrowHeight;\n }\n\n // Update container position (remove any transform and set left/top explicitly)\n container.style.left = `${computedLeft}px`;\n container.style.top = `${computedTop}px`;\n container.style.transform = '';\n\n // Compute arrow's horizontal offset relative to the container.\n // We want the arrow's tip to align with the clicked point.\n let arrowLeft = x - computedLeft - arrowWidth / 2;\n // Optionally constrain arrowLeft so it stays within the popup's width.\n arrowLeft = Math.max(arrowLeft, 0);\n arrowLeft = Math.min(arrowLeft, popupWidth - arrowWidth);\n\n // Update arrow element's style based on orientation.\n if (isAbove) {\n // Popup is above the clicked point so arrow appears at the bottom of the popup.\n arrowEl.style.left = `${arrowLeft}px`;\n arrowEl.style.bottom = `-${arrowHeight}px`;\n arrowEl.style.top = '';\n arrowEl.style.borderLeft = `${arrowWidth / 2}px solid transparent`;\n arrowEl.style.borderRight = `${arrowWidth / 2}px solid transparent`;\n arrowEl.style.borderTop = `${arrowHeight}px solid ${background}`;\n arrowEl.style.borderBottom = '';\n } else {\n // Popup is below the clicked point so arrow appears at the top.\n arrowEl.style.left = `${arrowLeft}px`;\n arrowEl.style.top = `-${arrowHeight}px`;\n arrowEl.style.bottom = '';\n arrowEl.style.borderLeft = `${arrowWidth / 2}px solid transparent`;\n arrowEl.style.borderRight = `${arrowWidth / 2}px solid transparent`;\n arrowEl.style.borderBottom = `${arrowHeight}px solid ${background}`;\n arrowEl.style.borderTop = '';\n }\n });\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/* global document */\nimport {Widget} from '@deck.gl/core';\nimport type {Deck, PickingInfo, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {SimpleMenu} from './lib/components/simple-menu';\n\n/** The standard, modern way is to use event.button === 2, where button is the standardized property (0 = left, 1 = middle, 2 = right). */\nconst MOUSE_BUTTON_RIGHT = 2;\n/** A name for the legacy MouseEvent.which value that corresponds to the right-mouse button. In older browsers, the check is: if (event.which === 3) */\nconst MOUSE_WHICH_RIGHT = 3;\n\nexport type ContextWidgetMenuItem = {\n label: string;\n key: string;\n};\n\nexport type ContextMenuWidgetProps = WidgetProps & {\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Controls visibility of the context menu */\n visible?: boolean;\n /** Screen position at which to place the menu */\n position: {x: number; y: number};\n /** Items to render */\n menuItems: ContextWidgetMenuItem[];\n /** Provide menu items for the menu given the picked object */\n getMenuItems: (info: PickingInfo, widget: ContextMenuWidget) => ContextWidgetMenuItem[] | null;\n /** Callback with the selected item */\n onMenuItemSelected?: (key: string, pickInfo: PickingInfo | null) => void;\n};\n\nexport class ContextMenuWidget extends Widget<ContextMenuWidgetProps> {\n static defaultProps: Required<ContextMenuWidgetProps> = {\n ...Widget.defaultProps,\n id: 'context',\n viewId: null,\n visible: false,\n position: {x: 0, y: 0},\n getMenuItems: undefined!,\n menuItems: [],\n // eslint-disable-next-line no-console\n onMenuItemSelected: (key, pickInfo) => console.log('Context menu item selected:', key, pickInfo)\n };\n\n className = 'deck-widget-context-menu';\n placement = 'fill' as const;\n\n pickInfo: PickingInfo | null = null;\n\n constructor(props: ContextMenuWidgetProps) {\n super(props, ContextMenuWidget.defaultProps);\n this.pickInfo = null;\n this.setProps(this.props);\n }\n\n onAdd({deck}: {deck: Deck<any>}): HTMLDivElement {\n const element = document.createElement('div');\n element.classList.add('deck-widget', 'deck-widget-context-menu');\n const style = {\n margin: '0px',\n top: '0px',\n left: '0px',\n position: 'absolute',\n pointerEvents: 'auto'\n };\n Object.entries(style).forEach(([key, value]) => element.style.setProperty(key, value));\n\n deck.getCanvas()?.addEventListener('click', () => this.hide());\n deck.getCanvas()?.addEventListener('contextmenu', event => this.handleContextMenu(event));\n return element;\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const {visible, position, menuItems} = this.props;\n\n const ui =\n visible && menuItems.length ? (\n <SimpleMenu\n menuItems={menuItems}\n onItemSelected={key => this.props.onMenuItemSelected(key, this.pickInfo)}\n position={position}\n style={{pointerEvents: 'auto'}}\n />\n ) : null;\n render(ui, rootElement);\n }\n\n handleContextMenu(srcEvent: MouseEvent): boolean {\n if (\n srcEvent &&\n (srcEvent.button === MOUSE_BUTTON_RIGHT || srcEvent.which === MOUSE_WHICH_RIGHT)\n ) {\n this.pickInfo =\n this.deck?.pickObject({\n x: srcEvent.clientX,\n y: srcEvent.clientY\n }) || null;\n const menuItems = (this.pickInfo && this.props.getMenuItems?.(this.pickInfo, this)) || [];\n const visible = menuItems.length > 0;\n this.setProps({\n visible,\n position: {x: srcEvent.clientX, y: srcEvent.clientY},\n menuItems\n });\n this.updateHTML();\n srcEvent.preventDefault();\n return visible;\n }\n\n return false;\n }\n\n hide(): void {\n this.setProps({visible: false});\n }\n}\n", "import type {JSX} from 'preact';\n\nconst MENU_STYLE: JSX.CSSProperties = {\n position: 'absolute',\n top: '100%',\n left: 0,\n background: 'white',\n border: '1px solid #ccc',\n borderRadius: '4px',\n marginTop: 'var(--menu-gap, 4px)',\n zIndex: 100\n};\n\nconst MENU_ITEM_STYLE: JSX.CSSProperties = {\n background: 'white',\n border: 'none',\n padding: '4px',\n cursor: 'pointer',\n pointerEvents: 'auto'\n};\n\nexport type SimpleMenuProps = {\n menuItems: {key: string; label: string}[];\n onItemSelected: (key: string) => void;\n position: {x: number; y: number};\n style?: JSX.CSSProperties;\n};\n\n/** Renders a simple dropdown menu at an arbitrary position */\nexport const SimpleMenu = (props: SimpleMenuProps) => {\n const {menuItems, onItemSelected, position, style} = props;\n const styleOverride: JSX.CSSProperties = {\n ...MENU_STYLE,\n ...style,\n left: `${position.x}px`,\n top: `${position.y}px`\n };\n\n return (\n <div style={styleOverride}>\n {menuItems.map(({key, label}) => (\n <button\n key={key}\n style={{...MENU_ITEM_STYLE, display: 'block'}}\n onClick={_ => onItemSelected(key)}\n >\n {label}\n </button>\n ))}\n </div>\n );\n};\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget, type WidgetPlacement, type WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {IconButton} from './lib/components/icon-button';\n\nexport type TimelineWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'bottom-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Slider timeRange [min, max]. */\n timeRange?: [number, number];\n /** Slider step. */\n step?: number;\n /** Initial slider value. */\n initialTime?: number;\n /** Callback when value changes. */\n onTimeChange?: (value: number) => void;\n /** Play interval in milliseconds. */\n playInterval?: number;\n};\n\nexport class TimelineWidget extends Widget<TimelineWidgetProps> {\n id = 'timeline';\n className = 'deck-widget-timeline';\n placement: WidgetPlacement = 'bottom-left';\n\n private playing = false;\n private timerId: number | null = null;\n currentTime: number;\n\n static defaultProps: Required<TimelineWidgetProps> = {\n ...Widget.defaultProps,\n id: 'timeline',\n placement: 'bottom-left',\n viewId: null,\n timeRange: [0, 100],\n step: 1,\n initialTime: undefined!,\n onTimeChange: () => {},\n playInterval: 1000\n };\n\n constructor(props: TimelineWidgetProps = {}) {\n super(props, TimelineWidget.defaultProps);\n this.currentTime = this.props.initialTime ?? this.props.timeRange[0];\n this.setProps(this.props);\n }\n\n setProps(props: Partial<TimelineWidgetProps>): void {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onAdd(): void {\n this.playing = false;\n this.timerId = null;\n }\n\n onRemove(): void {\n this.stop();\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n render(\n <div style={{display: 'flex', alignItems: 'center', pointerEvents: 'auto'}}>\n <IconButton label={this.playing ? 'Pause' : 'Play'} onClick={this.handlePlayPause}>\n <div className=\"text\">{this.playing ? '\u23F8' : '\u25B6'}</div>\n </IconButton>\n <input\n type=\"range\"\n className=\"timeline-slider\"\n min={this.props.timeRange[0]}\n max={this.props.timeRange[1]}\n step={this.props.step}\n value={this.currentTime}\n onInput={this.handleSliderChange}\n />\n </div>,\n rootElement\n );\n }\n\n private handlePlayPause = (): void => {\n if (this.playing) {\n this.stop();\n } else {\n this.start();\n }\n };\n\n private handleSliderChange = (e: Event): void => {\n const input = e.target as HTMLInputElement;\n const val = Number(input.value);\n this.currentTime = val;\n this.props.onTimeChange(val);\n this.updateHTML();\n };\n\n private start(): void {\n this.playing = true;\n this.updateHTML();\n this.tick();\n }\n\n private stop(): void {\n this.playing = false;\n if (this.timerId !== null) {\n window.clearTimeout(this.timerId);\n this.timerId = null;\n }\n this.updateHTML();\n }\n\n private tick = (): void => {\n const [min, max] = this.props.timeRange;\n let next = this.currentTime + this.props.step;\n if (next > max) {\n next = min;\n }\n this.currentTime = next;\n this.props.onTimeChange(next);\n this.updateHTML();\n if (this.playing) {\n this.timerId = window.setTimeout(this.tick, this.props.playInterval);\n }\n };\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/* global document */\nimport type {WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {Widget} from '@deck.gl/core';\nimport {IconButton} from './lib/components/icon-button';\n\n/** Properties for the ScreenshotWidget */\nexport type ScreenshotWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Tooltip message */\n label?: string;\n /** Filename to save to */\n filename?: string;\n /** Image format */\n imageFormat?: 'image/png' | 'image/jpeg';\n /** Callback, if defined user overrides the capture logic */\n onCapture?: (widget: ScreenshotWidget) => void;\n};\n\n/**\n * A button widget that captures a screenshot of the current canvas and downloads it as a (png) file.\n * @note only captures canvas contents, not HTML DOM or CSS styles\n */\nexport class ScreenshotWidget extends Widget<ScreenshotWidgetProps> {\n static defaultProps: Required<ScreenshotWidgetProps> = {\n ...Widget.defaultProps,\n id: 'screenshot',\n placement: 'top-left',\n viewId: null,\n label: 'Screenshot',\n filename: 'screenshot.png',\n imageFormat: 'image/png',\n onCapture: undefined!\n };\n\n className = 'deck-widget-screenshot';\n placement: WidgetPlacement = 'top-left';\n\n constructor(props: ScreenshotWidgetProps = {}) {\n super(props, ScreenshotWidget.defaultProps);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<ScreenshotWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n render(\n <IconButton\n className=\"deck-widget-camera\"\n label={this.props.label}\n onClick={this.handleClick.bind(this)}\n />,\n rootElement\n );\n }\n\n handleClick() {\n // Allow user to override the capture logic\n if (this.props.onCapture) {\n this.props.onCapture(this);\n return;\n }\n const dataURL = this.captureScreenToDataURL(this.props.imageFormat);\n if (dataURL) {\n this.downloadDataURL(dataURL, this.props.filename);\n }\n }\n\n /** @note only captures canvas contents, not HTML DOM or CSS styles */\n captureScreenToDataURL(imageFormat: string): string | undefined {\n const canvas = this.deck?.getCanvas();\n return canvas?.toDataURL(imageFormat);\n }\n\n /** Download a data URL */\n downloadDataURL(dataURL: string, filename: string): void {\n const link = document.createElement('a');\n link.href = dataURL;\n link.download = filename;\n link.click();\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {log, _deepEqual as deepEqual, _applyStyles as applyStyles} from '@deck.gl/core';\nimport {Widget, type WidgetProps, type WidgetPlacement} from '@deck.gl/core';\nimport {render} from 'preact';\n// import {useCallback} from 'preact/hooks';\nimport {IconButton} from './lib/components/icon-button';\nimport type {DeckWidgetTheme} from './themes';\nimport {LightGlassTheme, DarkGlassTheme} from './themes';\n\nexport type ThemeWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Tooltip message when dark mode is selected. */\n lightModeLabel?: string;\n /** Styles for light mode theme */\n lightModeTheme?: DeckWidgetTheme;\n /** Tooltip message when light mode is selected. */\n darkModeLabel?: string;\n /** Styles for dark mode theme */\n darkModeTheme?: DeckWidgetTheme;\n /** Initial theme mode. 'auto' reads the browser default setting */\n initialThemeMode?: 'auto' | 'light' | 'dark';\n};\n\nexport class ThemeWidget extends Widget<ThemeWidgetProps> {\n static defaultProps: Required<ThemeWidgetProps> = {\n ...Widget.defaultProps,\n id: 'theme',\n placement: 'top-left',\n viewId: null,\n lightModeLabel: 'Light Mode',\n lightModeTheme: LightGlassTheme,\n darkModeLabel: 'Dark Mode',\n darkModeTheme: DarkGlassTheme,\n initialThemeMode: 'auto'\n };\n\n className = 'deck-widget-theme';\n placement: WidgetPlacement = 'top-left';\n themeMode: 'light' | 'dark' = 'dark';\n\n constructor(props: ThemeWidgetProps = {}) {\n super(props, ThemeWidget.defaultProps);\n this.themeMode = this._getInitialThemeMode();\n this.setProps(this.props);\n }\n\n // eslint-disable-next-line complexity\n setProps(props: Partial<ThemeWidgetProps>) {\n const {lightModeTheme, darkModeTheme} = this.props;\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n\n switch (this.themeMode) {\n case 'light':\n if (props.lightModeTheme && !deepEqual(props.lightModeTheme, lightModeTheme, 1)) {\n this._setThemeMode('light');\n }\n break;\n case 'dark':\n if (props.darkModeTheme && !deepEqual(props.darkModeTheme, darkModeTheme, 1)) {\n this._setThemeMode('dark');\n }\n break;\n default:\n log.warn(`Invalid theme mode ${this.themeMode}`)();\n }\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const {lightModeLabel, darkModeLabel} = this.props;\n // const onClick = useCallback(this._handleClick.bind(this), [this._handleClick]);\n\n render(\n <IconButton\n onClick={this._handleClick.bind(this)}\n label={this.themeMode === 'dark' ? darkModeLabel : lightModeLabel}\n className={this.themeMode === 'dark' ? 'deck-widget-moon' : 'deck-widget-sun'}\n />,\n rootElement\n );\n }\n\n onAdd() {\n // Note: theme styling is applied in here onAdd() once DOM element is created\n this._setThemeMode(this.themeMode);\n }\n\n _handleClick() {\n const newThemeMode = this.themeMode === 'dark' ? 'light' : 'dark';\n this._setThemeMode(newThemeMode);\n }\n\n _setThemeMode(themeMode: 'light' | 'dark') {\n this.themeMode = themeMode;\n const container = this.rootElement?.closest<HTMLDivElement>('.deck-widget-container');\n if (container) {\n const themeStyle =\n themeMode === 'dark' ? this.props.darkModeTheme : this.props.lightModeTheme;\n applyStyles(container, themeStyle);\n\n const label =\n this.themeMode === 'dark' ? this.props.darkModeLabel : this.props.lightModeLabel;\n log.log(1, `Switched theme to ${label}`, themeStyle)();\n\n this.updateHTML();\n }\n }\n\n /** Read browser preference */\n _getInitialThemeMode(): 'light' | 'dark' {\n const {initialThemeMode} = this.props;\n return initialThemeMode === 'auto'\n ? window.matchMedia('(prefers-color-scheme: dark)').matches\n ? 'dark'\n : 'light'\n : initialThemeMode;\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/**\n * A Deck Theme is a set of CSS variables that control CSS styling of the official widgets.\n */\nexport type DeckWidgetTheme = {\n // layout\n '--widget-margin'?: string;\n // button and button group\n '--button-size'?: string;\n '--button-corner-radius'?: string;\n '--button-background'?: string;\n '--button-stroke'?: string;\n '--button-inner-stroke'?: string;\n '--button-shadow'?: string;\n '--button-backdrop-filter'?: string;\n '--button-icon-idle'?: string;\n '--button-icon-hover'?: string;\n '--button-text'?: string;\n // inter-icon color\n '--icon-compass-north-color'?: string;\n '--icon-compass-south-color'?: string;\n // menu\n '--menu-gap'?: string;\n};\n\nexport const LightTheme = {\n '--widget-margin': '12px',\n '--button-size': '28px',\n '--button-corner-radius': '8px',\n '--button-background': '#fff',\n '--button-stroke': 'rgba(255, 255, 255, 0.3)',\n '--button-inner-stroke': 'unset',\n '--button-shadow': '0px 0px 8px 0px rgba(0, 0, 0, 0.25)',\n '--button-backdrop-filter': 'unset',\n '--button-icon-idle': 'rgba(97, 97, 102, 1)',\n '--button-icon-hover': 'rgba(24, 24, 26, 1)',\n '--button-text': 'rgb(24, 24, 26, 1)',\n '--icon-compass-north-color': 'rgb(240, 92, 68)',\n '--icon-compass-south-color': 'rgb(204, 204, 204)',\n '--menu-gap': '4px'\n} as const satisfies Required<DeckWidgetTheme>;\n\nexport const DarkTheme = {\n '--widget-margin': '12px',\n '--button-size': '28px',\n '--button-corner-radius': '8px',\n '--button-background': 'rgba(18, 18, 20, 1)',\n '--button-stroke': 'rgba(18, 18, 20, 0.30)',\n '--button-inner-stroke': 'unset',\n '--button-shadow': '0px 0px 8px 0px rgba(0, 0, 0, 0.25)',\n '--button-backdrop-filter': 'unset',\n '--button-icon-idle': 'rgba(158, 157, 168, 1)',\n '--button-icon-hover': 'rgba(215, 214, 229, 1)',\n '--button-text': 'rgb(215, 214, 229, 1)',\n '--icon-compass-north-color': 'rgb(240, 92, 68)',\n '--icon-compass-south-color': 'rgb(200, 199, 209)',\n '--menu-gap': '4px'\n} as const satisfies Required<DeckWidgetTheme>;\n\nexport const LightGlassTheme = {\n '--widget-margin': '12px',\n '--button-size': '28px',\n '--button-corner-radius': '8px',\n '--button-background': 'rgba(255, 255, 255, 0.6)',\n '--button-stroke': 'rgba(255, 255, 255, 0.3)',\n '--button-inner-stroke': '1px solid rgba(255, 255, 255, 0.6)',\n '--button-shadow':\n '0px 0px 8px 0px rgba(0, 0, 0, 0.25), 0px 0px 8px 0px rgba(0, 0, 0, 0.1) inset',\n '--button-backdrop-filter': 'blur(4px)',\n '--button-icon-idle': 'rgba(97, 97, 102, 1)',\n '--button-icon-hover': 'rgba(24, 24, 26, 1)',\n '--button-text': 'rgb(24, 24, 26, 1)',\n '--icon-compass-north-color': 'rgb(240, 92, 68)',\n '--icon-compass-south-color': 'rgb(204, 204, 204)',\n '--menu-gap': '4px'\n} as const satisfies Required<DeckWidgetTheme>;\n\nexport const DarkGlassTheme = {\n '--widget-margin': '12px',\n '--button-size': '28px',\n '--button-corner-radius': '8px',\n '--button-background': 'rgba(18, 18, 20, 0.75)',\n '--button-stroke': 'rgba(18, 18, 20, 0.30)',\n '--button-inner-stroke': '1px solid rgba(18, 18, 20, 0.75)',\n '--button-shadow':\n '0px 0px 8px 0px rgba(0, 0, 0, 0.25), 0px 0px 8px 0px rgba(0, 0, 0, 0.1) inset',\n '--button-backdrop-filter': 'blur(4px)',\n '--button-icon-idle': 'rgba(158, 157, 168, 1)',\n '--button-icon-hover': 'rgba(215, 214, 229, 1)',\n '--button-text': 'rgb(215, 214, 229, 1)',\n '--icon-compass-north-color': 'rgb(240, 92, 68)',\n '--icon-compass-south-color': 'rgb(200, 199, 209)',\n '--menu-gap': '4px'\n} as const satisfies Required<DeckWidgetTheme>;\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {WidgetPlacement, Layer, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {Widget} from '@deck.gl/core';\nimport {IconButton} from './lib/components/icon-button';\n\n/** Properties for the LoadingWidget */\nexport type LoadingWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views */\n viewId?: string | null;\n /** Tooltip message when loading */\n label?: string;\n};\n\n/**\n * A non-interactive widget that shows a loading spinner if any layers are loading data\n */\nexport class LoadingWidget extends Widget<LoadingWidgetProps> {\n static defaultProps: Required<LoadingWidgetProps> = {\n ...Widget.defaultProps,\n id: 'loading',\n placement: 'top-left',\n viewId: null,\n label: 'Loading layer data'\n };\n\n className = 'deck-widget-loading';\n placement: WidgetPlacement = 'top-left';\n loading = true;\n\n constructor(props: LoadingWidgetProps = {}) {\n super(props, LoadingWidget.defaultProps);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<LoadingWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n render(\n // TODO(ibgreen) - this should not be a button, but styling is so nested that it is easier to reuse this component.\n this.loading && (\n <IconButton\n className=\"deck-widget-spinner\"\n label={this.props.label}\n onClick={this.handleClick.bind(this)}\n />\n ),\n rootElement\n );\n }\n\n onRedraw({layers}: {layers: Layer[]}): void {\n const loading = layers.some(layer => !layer.isLoaded);\n if (loading !== this.loading) {\n this.loading = loading;\n this.updateHTML();\n }\n }\n\n // TODO(ibgreen) - this should not be a button, see above.\n handleClick() {}\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget} from '@deck.gl/core';\nimport {render} from 'preact';\nimport type {WidgetPlacement, Deck, WidgetProps} from '@deck.gl/core';\nimport {IconButton} from './lib/components/icon-button';\n\n/** Properties for the FpsWidget. */\nexport type FpsWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n};\n\n/**\n * Displays the average frames per second reported by the Deck instance.\n */\nexport class FpsWidget extends Widget<FpsWidgetProps> {\n static defaultProps: Required<FpsWidgetProps> = {\n ...Widget.defaultProps,\n id: 'fps',\n placement: 'top-left',\n viewId: null\n };\n\n className = 'deck-widget-fps';\n placement: WidgetPlacement = 'top-left';\n\n private _lastFps: number = -1;\n\n constructor(props: FpsWidgetProps = {}) {\n super(props, FpsWidget.defaultProps);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<FpsWidgetProps>): void {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onAdd({}: {deck: Deck<any>; viewId: string | null}): void {\n this._lastFps = this._getFps();\n requestAnimationFrame(() => this._animate());\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const fps = this._getFps();\n render(\n <IconButton>\n <div className=\"text\">\n FPS\n <br />\n {fps}\n </div>\n </IconButton>,\n rootElement\n );\n }\n\n _animate(): void {\n const fps = this._getFps();\n if (this._lastFps !== fps) {\n this._lastFps = fps;\n this.updateHTML();\n }\n requestAnimationFrame(() => this._animate());\n }\n\n _getFps(): number {\n // @ts-expect-error protected\n return Math.round(this.deck?.metrics.fps ?? 0);\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget, type WidgetPlacement, type WidgetProps} from '@deck.gl/core';\nimport {luma} from '@luma.gl/core';\nimport {render} from 'preact';\nimport type {Stats, Stat} from '@probe.gl/stats';\n\nconst RIGHT_ARROW = '\\u25b6';\nconst DOWN_ARROW = '\\u2b07';\n\nconst DEFAULT_COUNT_FORMATTER = (stat: Stat): string => `${stat.name}: ${stat.count}`;\n\nfunction formatTime(time: number): string {\n return time < 1000 ? `${time.toFixed(2)}ms` : `${(time / 1000).toFixed(2)}s`;\n}\n\nfunction formatMemory(bytes: number): string {\n const mb = bytes / 1e6;\n return `${mb.toFixed(1)} MB`;\n}\n\nexport const DEFAULT_FORMATTERS: Record<string, (stat: Stat) => string> = {\n count: DEFAULT_COUNT_FORMATTER,\n averageTime: (stat: Stat) => `${stat.name}: ${formatTime(stat.getAverageTime())}`,\n totalTime: (stat: Stat) => `${stat.name}: ${formatTime(stat.time)}`,\n fps: (stat: Stat) => `${stat.name}: ${Math.round(stat.getHz())}fps`,\n memory: (stat: Stat) => `${stat.name}: ${formatMemory(stat.count)}`\n};\n\nexport type StatsWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Type of stats to display. */\n type?: 'deck' | 'luma' | 'device' | 'custom';\n /** Stats object to visualize. */\n stats?: Stats;\n /** Title shown in the header of the pop-up. Defaults to stats.id. */\n title?: string;\n /** How many redraws to wait between updates. */\n framesPerUpdate?: number;\n /** Custom formatters for stat values. */\n formatters?: Record<string, string | ((stat: Stat) => string)>;\n /** Whether to reset particular stats after each update. */\n resetOnUpdate?: Record<string, boolean>;\n};\n\n/** Displays probe.gl stats in a floating pop-up. */\nexport class StatsWidget extends Widget<StatsWidgetProps> {\n static defaultProps: Required<StatsWidgetProps> = {\n ...Widget.defaultProps,\n type: 'deck',\n placement: 'top-left',\n viewId: null,\n stats: undefined!,\n title: 'Stats',\n framesPerUpdate: 1,\n formatters: {},\n resetOnUpdate: {},\n id: 'stats'\n };\n\n className = 'deck-widget-stats';\n placement = 'top-left' as WidgetPlacement;\n\n private _counter = 0;\n private _formatters: Record<string, (stat: Stat) => string>;\n private _resetOnUpdate: Record<string, boolean>;\n collapsed: boolean = true;\n _stats: Stats;\n\n constructor(props: StatsWidgetProps = {}) {\n super(props, StatsWidget.defaultProps);\n this._formatters = {...DEFAULT_FORMATTERS};\n this._resetOnUpdate = {...this.props.resetOnUpdate};\n this._stats = this.props.stats;\n this.setProps(props);\n }\n\n setProps(props: Partial<StatsWidgetProps>): void {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n this._stats = this._getStats();\n if (props.formatters) {\n for (const name in props.formatters) {\n const f = props.formatters[name];\n this._formatters[name] =\n typeof f === 'string' ? DEFAULT_FORMATTERS[f] || DEFAULT_COUNT_FORMATTER : f;\n }\n }\n if (props.resetOnUpdate) {\n this._resetOnUpdate = {...props.resetOnUpdate};\n }\n super.setProps(props);\n }\n\n onAdd(): void {\n this._stats = this._getStats();\n this.updateHTML();\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const stats = this._stats;\n const collapsed = this.collapsed;\n const title = this.props.title || stats?.id || 'Stats';\n const items: JSX.Element[] = [];\n\n if (!collapsed && stats) {\n stats.forEach(stat => {\n const lines = this._getLines(stat);\n if (this._resetOnUpdate && this._resetOnUpdate[stat.name]) {\n stat.reset();\n }\n lines.forEach((line, i) => {\n items.push(\n <div key={`${stat.name}-${i}`} style={{whiteSpace: 'pre'}}>\n {line}\n </div>\n );\n });\n });\n }\n\n render(\n <div className=\"deck-widget-stats-container\" style={{cursor: 'default'}}>\n <div\n className=\"deck-widget-stats-header\"\n style={{cursor: 'pointer', pointerEvents: 'auto'}}\n onClick={this._toggleCollapsed}\n >\n {collapsed ? RIGHT_ARROW : DOWN_ARROW} {title}\n </div>\n {!collapsed && <div className=\"deck-widget-stats-content\">{items}</div>}\n </div>,\n rootElement\n );\n }\n\n onRedraw(): void {\n const framesPerUpdate = Math.max(1, this.props.framesPerUpdate || 1);\n if (this._counter++ % framesPerUpdate === 0) {\n this._stats = this._getStats();\n this.updateHTML();\n }\n }\n\n protected _getStats(): Stats {\n switch (this.props.type) {\n case 'deck':\n // @ts-expect-error stats is protected\n return this.deck?.stats;\n case 'luma':\n return Array.from(luma.stats.stats.values())[0];\n case 'device':\n // @ts-expect-error is protected\n const device = this.deck?.device;\n const stats = device?.statsManager.stats.values();\n return stats ? Array.from(stats)[0] : undefined;\n case 'custom':\n return this.props.stats;\n default:\n throw new Error(`Unknown stats type: ${this.props.type}`);\n }\n }\n\n protected _toggleCollapsed = (): void => {\n this.collapsed = !this.collapsed;\n this.updateHTML();\n };\n\n protected _getLines(stat: Stat): string[] {\n const formatter =\n this._formatters[stat.name] || this._formatters[stat.type || ''] || DEFAULT_COUNT_FORMATTER;\n return formatter(stat).split('\\n');\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// Navigation widgets\nexport {ZoomWidget} from './zoom-widget';\nexport {ResetViewWidget} from './reset-view-widget';\nexport {GimbalWidget} from './gimbal-widget';\n\n// Geospatial widgets\nexport {CompassWidget} from './compass-widget';\nexport {ScaleWidget as _ScaleWidget} from './scale-widget';\nexport {GeocoderWidget as _GeocoderWidget} from './geocoder-widget';\n\n// View widgets\nexport {FullscreenWidget} from './fullscreen-widget';\nexport {SplitterWidget as _SplitterWidget} from './splitter-widget';\nexport {ViewSelectorWidget as _ViewSelectorWidget} from './view-selector-widget';\n\n// Information widgets\nexport {InfoWidget as _InfoWidget} from './info-widget';\nexport {ContextMenuWidget as _ContextMenuWidget} from './context-menu-widget';\n\n// Control widgets\nexport {TimelineWidget as _TimelineWidget} from './timeline-widget';\n\n// Utility widgets\nexport {ScreenshotWidget} from './screenshot-widget';\nexport {ThemeWidget as _ThemeWidget} from './theme-widget';\nexport {LoadingWidget as _LoadingWidget} from './loading-widget';\nexport {FpsWidget as _FpsWidget} from './fps-widget';\nexport {StatsWidget as _StatsWidget} from './stats-widget';\n\nexport type {FullscreenWidgetProps} from './fullscreen-widget';\nexport type {CompassWidgetProps} from './compass-widget';\nexport type {ZoomWidgetProps} from './zoom-widget';\nexport type {ScreenshotWidgetProps} from './screenshot-widget';\nexport type {ResetViewWidgetProps} from './reset-view-widget';\nexport type {GeocoderWidgetProps} from './geocoder-widget';\nexport type {LoadingWidgetProps} from './loading-widget';\nexport type {FpsWidgetProps} from './fps-widget';\nexport type {ScaleWidgetProps} from './scale-widget';\nexport type {ThemeWidgetProps} from './theme-widget';\nexport type {InfoWidgetProps} from './info-widget';\nexport type {StatsWidgetProps} from './stats-widget';\nexport type {ContextMenuWidgetProps} from './context-menu-widget';\nexport type {SplitterWidgetProps} from './splitter-widget';\nexport type {TimelineWidgetProps} from './timeline-widget';\nexport type {ViewSelectorWidgetProps} from './view-selector-widget';\nexport type {GimbalWidgetProps} from './gimbal-widget';\n\nexport {LightTheme, DarkTheme, LightGlassTheme, DarkGlassTheme} from './themes';\nexport type {DeckWidgetTheme} from './themes';\n\n// Experimental preact components\nexport {ButtonGroup as _ButtonGroup, type ButtonGroupProps} from './lib/components/button-group';\nexport {IconButton as _IconButton, type IconButtonProps} from './lib/components/icon-button';\nexport {\n GroupedIconButton as _GroupedIconButton,\n type GroupedIconButtonProps\n} from './lib/components/grouped-icon-button';\nexport {\n DropdownMenu as _DropdownMenu,\n type DropdownMenuProps\n} from './lib/components/dropdown-menu';\nexport {SimpleMenu as _SimpleMenu, type SimpleMenuProps} from './lib/components/simple-menu';\nexport {IconMenu as _IconMenu, type IconMenuProps} from './lib/components/icon-menu';\n\n// Experimental geocoders. May be removed, use at your own risk!\nexport {type Geocoder} from './lib/geocode/geocoder';\nexport {\n GoogleGeocoder as _GoogleGeocoder,\n MapboxGeocoder as _MapboxGeocoder,\n OpenCageGeocoder as _OpenCageGeocoder,\n CoordinatesGeocoder as _CoordinatesGeocoder,\n CurrentLocationGeocoder as _CurrentLocationGeocoder\n} from './lib/geocode/geocoders';\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget, FlyToInterpolator, LinearInterpolator} from '@deck.gl/core';\nimport type {Viewport, WidgetProps, WidgetPlacement} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {ButtonGroup} from './lib/components/button-group';\nimport {GroupedIconButton} from './lib/components/grouped-icon-button';\n\nexport type ZoomWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Button orientation. */\n orientation?: 'vertical' | 'horizontal';\n /** Tooltip message on zoom in button. */\n zoomInLabel?: string;\n /** Tooltip message on zoom out button. */\n zoomOutLabel?: string;\n /** Zoom transition duration in ms. 0 disables the transition */\n transitionDuration?: number;\n};\n\nexport class ZoomWidget extends Widget<ZoomWidgetProps> {\n static defaultProps: Required<ZoomWidgetProps> = {\n ...Widget.defaultProps,\n id: 'zoom',\n placement: 'top-left',\n orientation: 'vertical',\n transitionDuration: 200,\n zoomInLabel: 'Zoom In',\n zoomOutLabel: 'Zoom Out',\n viewId: null\n };\n\n className = 'deck-widget-zoom';\n placement: WidgetPlacement = 'top-left';\n viewports: {[id: string]: Viewport} = {};\n\n constructor(props: ZoomWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<ZoomWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const ui = (\n <ButtonGroup orientation={this.props.orientation}>\n <GroupedIconButton\n onClick={() => this.handleZoomIn()}\n label={this.props.zoomInLabel}\n className=\"deck-widget-zoom-in\"\n />\n <GroupedIconButton\n onClick={() => this.handleZoomOut()}\n label={this.props.zoomOutLabel}\n className=\"deck-widget-zoom-out\"\n />\n </ButtonGroup>\n );\n render(ui, rootElement);\n }\n\n onViewportChange(viewport: Viewport) {\n this.viewports[viewport.id] = viewport;\n }\n\n handleZoom(viewport: Viewport, nextZoom: number) {\n const viewId = this.viewId || viewport?.id || 'default-view';\n const nextViewState: Record<string, unknown> = {\n ...viewport,\n zoom: nextZoom\n };\n if (this.props.transitionDuration > 0) {\n nextViewState.transitionDuration = this.props.transitionDuration;\n nextViewState.transitionInterpolator =\n 'latitude' in nextViewState\n ? new FlyToInterpolator()\n : new LinearInterpolator({\n transitionProps: ['zoom']\n });\n }\n this.setViewState(viewId, nextViewState);\n }\n\n handleZoomIn() {\n for (const viewport of Object.values(this.viewports)) {\n this.handleZoom(viewport, viewport.zoom + 1);\n }\n }\n\n handleZoomOut() {\n for (const viewport of Object.values(this.viewports)) {\n this.handleZoom(viewport, viewport.zoom - 1);\n }\n }\n\n /** @todo - move to deck or widget manager */\n private setViewState(viewId: string, viewState: Record<string, unknown>): void {\n // @ts-ignore Using private method temporary until there's a public one\n this.deck._onViewStateChange({viewId, viewState, interactionState: {}});\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ComponentChildren} from 'preact';\n\nexport type ButtonGroupProps = {\n children: ComponentChildren;\n orientation: 'vertical' | 'horizontal';\n};\n\n/** Renders a group of buttons with Widget CSS */\nexport const ButtonGroup = (props: ButtonGroupProps) => {\n const {children, orientation = 'horizontal'} = props;\n return <div className={`deck-widget-button-group ${orientation}`}>{children}</div>;\n};\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ComponentChildren, JSX} from 'preact';\n\nexport type GroupedIconButtonProps = {\n className?: string;\n label?: string;\n onClick?: JSX.MouseEventHandler<HTMLButtonElement>;\n children?: ComponentChildren;\n};\n\n/** Renders an icon button as part of a ButtonGroup */\nexport const GroupedIconButton = (props: GroupedIconButtonProps) => {\n const {className = '', label, onClick, children} = props;\n return (\n <button\n className={`deck-widget-icon-button ${className}`}\n type=\"button\"\n onClick={onClick}\n title={label}\n >\n {children ? children : <div className=\"deck-widget-icon\" />}\n </button>\n );\n};\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport type {ViewStateMap, ViewOrViews} from '@deck.gl/core/src/lib/view-manager';\nimport {render} from 'preact';\nimport {Widget} from '@deck.gl/core';\nimport {IconButton} from './lib/components/icon-button';\n\n/** Properties for the ResetViewWidget */\nexport type ResetViewWidgetProps<ViewsT extends ViewOrViews = null> = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** Tooltip message */\n label?: string;\n /** The initial view state to reset the view to. Defaults to deck.props.initialViewState */\n initialViewState?: ViewStateMap<ViewsT>;\n /** View to interact with. Required when using multiple views. */\n viewId?: string | null;\n};\n\n/**\n * A button widget that resets the view state of deck to an initial state.\n */\nexport class ResetViewWidget<ViewsT extends ViewOrViews = null> extends Widget<\n ResetViewWidgetProps<ViewsT>,\n ViewsT\n> {\n static defaultProps: Required<ResetViewWidgetProps> = {\n ...Widget.defaultProps,\n id: 'reset-view',\n placement: 'top-left',\n label: 'Reset View',\n initialViewState: undefined!,\n viewId: null\n };\n\n className = 'deck-widget-reset-view';\n placement: WidgetPlacement = 'top-left';\n\n constructor(props: ResetViewWidgetProps<ViewsT> = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<ResetViewWidgetProps<ViewsT>>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n render(\n <IconButton\n className=\"deck-widget-reset-focus\"\n label={this.props.label}\n onClick={this.handleClick.bind(this)}\n />,\n rootElement\n );\n }\n\n handleClick() {\n const initialViewState = this.props.initialViewState || this.deck?.props.initialViewState;\n this.setViewState(initialViewState);\n }\n\n setViewState(viewState?: ViewStateMap<ViewsT>) {\n const viewId = (this.props.viewId || 'default-view') as unknown as string;\n const nextViewState = {\n ...(viewId !== 'default-view' ? viewState?.[viewId] : viewState)\n // only works for geospatial?\n // transitionDuration: this.props.transitionDuration,\n // transitionInterpolator: new FlyToInterpolator()\n };\n // @ts-ignore Using private method temporary until there's a public one\n this.deck._onViewStateChange({viewId, viewState: nextViewState, interactionState: {}});\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {ComponentChildren, JSX} from 'preact';\n\nexport type IconButtonProps = {\n className?: string;\n label?: string;\n onClick?: JSX.MouseEventHandler<HTMLButtonElement>;\n children?: ComponentChildren;\n};\n\n/** Renders a button component with widget CSS */\nexport const IconButton = (props: IconButtonProps) => {\n const {className = '', label, onClick, children} = props;\n return (\n <div className=\"deck-widget-button\">\n <button\n className={`deck-widget-icon-button ${className}`}\n type=\"button\"\n onClick={onClick}\n title={label}\n >\n {children ? children : <div className=\"deck-widget-icon\" />}\n </button>\n </div>\n );\n};\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget, LinearInterpolator} from '@deck.gl/core';\nimport type {Viewport, WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\n\nexport type GimbalWidgetProps = WidgetProps & {\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Tooltip message. */\n label?: string;\n /** Width of gimbal lines. */\n strokeWidth?: number;\n /** Transition duration in ms when resetting rotation. */\n transitionDuration?: number;\n};\n\nexport class GimbalWidget extends Widget<GimbalWidgetProps> {\n static defaultProps: Required<GimbalWidgetProps> = {\n ...Widget.defaultProps,\n id: 'gimbal',\n placement: 'top-left',\n viewId: null,\n label: 'Gimbal',\n strokeWidth: 1.5,\n transitionDuration: 200\n };\n\n className = 'deck-widget-gimbal';\n placement: WidgetPlacement = 'top-left';\n viewports: {[id: string]: Viewport} = {};\n\n constructor(props: GimbalWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<GimbalWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const viewId = this.viewId || Object.values(this.viewports)[0]?.id || 'default-view';\n const widgetViewport = this.viewports[viewId];\n const {rotationOrbit, rotationX} = this.getNormalizedRotation(widgetViewport);\n // Note - we use CSS 3D transforms instead of SVG 2D transforms\n const ui = (\n <div className=\"deck-widget-button\" style={{perspective: 100, pointerEvents: 'auto'}}>\n <button\n type=\"button\"\n onClick={() => {\n for (const viewport of Object.values(this.viewports)) {\n this.resetOrbitView(viewport);\n }\n }}\n title={this.props.label}\n style={{position: 'relative', width: 26, height: 26}}\n >\n {/* Outer ring */}\n <svg\n className=\"gimbal-outer-ring\"\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 26 26\"\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n transform: `rotateY(${rotationOrbit}deg)`\n }}\n >\n <circle\n cx=\"13\"\n cy=\"13\"\n r=\"10\"\n stroke=\"var(--icon-gimbal-outer-color, rgb(68, 92, 204))\"\n strokeWidth={this.props.strokeWidth}\n fill=\"none\"\n />\n </svg>\n\n {/* Inner ring */}\n <svg\n className=\"gimbal-inner-ring\"\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 26 26\"\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n transform: `rotateX(${rotationX}deg)`\n }}\n >\n <circle\n cx=\"13\"\n cy=\"13\"\n r=\"7\"\n stroke=\"var(--icon-gimbal-inner-color, rgb(240, 92, 68))\"\n strokeWidth={this.props.strokeWidth}\n fill=\"none\"\n />\n </svg>\n </button>\n </div>\n );\n\n render(ui, rootElement);\n }\n\n onViewportChange(viewport: Viewport) {\n this.viewports[viewport.id] = viewport;\n this.updateHTML();\n }\n\n resetOrbitView(viewport?: Viewport) {\n const viewId = this.getViewId(viewport);\n const viewState = this.getViewState(viewId);\n if ('rotationOrbit' in viewState || 'rotationX' in viewState) {\n const nextViewState = {\n ...viewState,\n rotationOrbit: 0,\n rotationX: 0,\n transitionDuration: this.props.transitionDuration,\n transitionInterpolator: new LinearInterpolator({\n transitionProps: ['rotationOrbit', 'rotationX']\n })\n };\n // @ts-ignore Using private method temporary until there's a public one\n this.deck._onViewStateChange({viewId, viewState: nextViewState, interactionState: {}});\n }\n }\n\n getNormalizedRotation(viewport?: Viewport): {rotationOrbit: number; rotationX: number} {\n const viewState = this.getViewState(this.getViewId(viewport));\n const [rz, rx] = this.getRotation(viewState);\n const rotationOrbit = normalizeAndClampAngle(rz);\n const rotationX = normalizeAndClampAngle(rx);\n return {rotationOrbit, rotationX};\n }\n\n getRotation(viewState?: any): [number, number] {\n if (viewState && ('rotationOrbit' in viewState || 'rotationX' in viewState)) {\n return [-(viewState.rotationOrbit || 0), viewState.rotationX || 0];\n }\n return [0, 0];\n }\n\n // Move to Widget/WidgetManager?\n\n getViewId(viewport?: Viewport) {\n const viewId = this.viewId || viewport?.id || 'OrbitView';\n return viewId;\n }\n\n getViewState(viewId: string) {\n const viewManager = this.getViewManager();\n const viewState = (viewId && viewManager.getViewState(viewId)) || viewManager.viewState;\n return viewState;\n }\n\n getViewManager() {\n // @ts-expect-error protected\n const viewManager = this.deck?.viewManager;\n if (!viewManager) {\n throw new Error('wigdet must be added to a deck instance');\n }\n return viewManager;\n }\n}\n\nfunction normalizeAndClampAngle(angle: number): number {\n // Bring angle into [-180, 180]\n let normalized = ((((angle + 180) % 360) + 360) % 360) - 180;\n\n // Avoid rotating the gimbal rings to close to 90 degrees as they will visually disappear\n const AVOID_ANGLE_DELTA = 10;\n const distanceFrom90 = normalized - 90;\n if (Math.abs(distanceFrom90) < AVOID_ANGLE_DELTA) {\n if (distanceFrom90 < AVOID_ANGLE_DELTA) {\n normalized = 90 + AVOID_ANGLE_DELTA;\n } else if (distanceFrom90 > -AVOID_ANGLE_DELTA) {\n normalized = 90 - AVOID_ANGLE_DELTA;\n }\n }\n // Clamp to [-80, 80]\n return normalized; // Math.max(-80, Math.min(80, normalized));\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget, FlyToInterpolator, WebMercatorViewport, _GlobeViewport} from '@deck.gl/core';\nimport type {Viewport, WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\n\nexport type CompassWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Tooltip message. */\n label?: string;\n /** Bearing and pitch reset transition duration in ms. */\n transitionDuration?: number;\n};\n\nexport class CompassWidget extends Widget<CompassWidgetProps> {\n static defaultProps: Required<CompassWidgetProps> = {\n ...Widget.defaultProps,\n id: 'compass',\n placement: 'top-left',\n viewId: null,\n label: 'Reset Compass',\n transitionDuration: 200\n };\n\n className = 'deck-widget-compass';\n placement: WidgetPlacement = 'top-left';\n viewports: {[id: string]: Viewport} = {};\n\n constructor(props: CompassWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<CompassWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const viewId = this.viewId || Object.values(this.viewports)[0]?.id || 'default-view';\n const widgetViewport = this.viewports[viewId];\n const [rz, rx] = this.getRotation(widgetViewport);\n\n const ui = (\n <div className=\"deck-widget-button\" style={{perspective: 100}}>\n <button\n type=\"button\"\n onClick={() => {\n for (const viewport of Object.values(this.viewports)) {\n this.handleCompassReset(viewport);\n }\n }}\n title={this.props.label}\n style={{transform: `rotateX(${rx}deg)`}}\n >\n <svg fill=\"none\" width=\"100%\" height=\"100%\" viewBox=\"0 0 26 26\">\n <g transform={`rotate(${rz},13,13)`}>\n <path\n d=\"M10 13.0001L12.9999 5L15.9997 13.0001H10Z\"\n fill=\"var(--icon-compass-north-color, rgb(240, 92, 68))\"\n />\n <path\n d=\"M16.0002 12.9999L13.0004 21L10.0005 12.9999H16.0002Z\"\n fill=\"var(--icon-compass-south-color, rgb(204, 204, 204))\"\n />\n </g>\n </svg>\n </button>\n </div>\n );\n\n render(ui, rootElement);\n }\n\n onViewportChange(viewport: Viewport) {\n // no need to update if viewport is the same\n if (!viewport.equals(this.viewports[viewport.id])) {\n this.viewports[viewport.id] = viewport;\n this.updateHTML();\n }\n }\n\n getRotation(viewport?: Viewport) {\n if (viewport instanceof WebMercatorViewport) {\n return [-viewport.bearing, viewport.pitch];\n } else if (viewport instanceof _GlobeViewport) {\n return [0, Math.max(-80, Math.min(80, viewport.latitude))];\n }\n return [0, 0];\n }\n\n handleCompassReset(viewport: Viewport) {\n const viewId = this.viewId || viewport.id || 'default-view';\n if (viewport instanceof WebMercatorViewport) {\n const nextViewState = {\n ...viewport,\n bearing: 0,\n ...(this.getRotation(viewport)[0] === 0 ? {pitch: 0} : {}),\n transitionDuration: this.props.transitionDuration,\n transitionInterpolator: new FlyToInterpolator()\n };\n // @ts-ignore Using private method temporary until there's a public one\n this.deck._onViewStateChange({viewId, viewState: nextViewState, interactionState: {}});\n }\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {WidgetPlacement, Viewport, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {Widget} from '@deck.gl/core';\n\nexport type ScaleWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'bottom-left'. */\n placement?: WidgetPlacement;\n /** Label for the scale widget */\n label?: string;\n /** View to attach to and interact with. Required when using multiple views */\n viewId?: string | null;\n};\n\n/**\n * A scale widget that displays a Google Maps\u2013like scale indicator.\n * Instead of text inside a div, this widget renders an SVG that contains a horizontal line\n * with two vertical tick marks (extending upward from the line only) and a pretty distance label\n * positioned to the left of the line. The horizontal line\u2019s length is computed from a \u201Cnice\u201D\n * candidate distance (e.g. 200, 500, 1000 m, etc.) so that its pixel width is between 100 and 200.\n */\nexport class ScaleWidget extends Widget<ScaleWidgetProps> {\n static defaultProps: Required<ScaleWidgetProps> = {\n ...Widget.defaultProps,\n id: 'scale',\n placement: 'bottom-left',\n label: 'Scale',\n viewId: null\n };\n\n className = 'deck-widget-scale';\n placement: WidgetPlacement = 'bottom-left';\n\n // The pixel width of the scale line (computed from a candidate distance)\n scaleWidth: number = 10;\n // The candidate distance (in meters) corresponding to the scale line length.\n scaleValue: number = 0;\n // The formatted distance label (e.g. \"200 m\" or \"1.0 km\")\n scaleText: string = '';\n\n constructor(props: ScaleWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<ScaleWidgetProps>): void {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n // Reserve space for the text label (to the left of the horizontal line)\n const lineOffsetX = 50;\n // Overall SVG width includes the left offset plus the computed scale line width.\n const svgWidth = lineOffsetX + this.scaleWidth;\n const tickHeight = 10; // vertical tick extends upward by 10 pixels from the horizontal line\n render(\n <svg\n className=\"deck-widget-scale\"\n width={svgWidth}\n height={30}\n style={{overflow: 'visible', background: 'transparent'}}\n onClick={this.handleClick.bind(this)}\n >\n {/* Pretty distance label positioned to the left of the horizontal line */}\n <text\n x={lineOffsetX + 5}\n y=\"10\"\n textAnchor=\"end\"\n alignmentBaseline=\"middle\"\n style={{fontSize: '16px', fill: 'black', fontWeight: 'bold', fontFamily: 'sans-serif'}}\n >\n {this.scaleText}\n </text>\n {/* Horizontal line */}\n <line\n x1={lineOffsetX}\n y1=\"15\"\n x2={lineOffsetX + this.scaleWidth}\n y2=\"15\"\n stroke=\"black\"\n strokeWidth=\"6\"\n />\n {/* Left vertical tick (extending upward from the horizontal line) */}\n <line\n x1={lineOffsetX}\n y1=\"15\"\n x2={lineOffsetX}\n y2={15 - tickHeight}\n stroke=\"black\"\n strokeWidth=\"6\"\n />\n {/* Right vertical tick (extending upward from the horizontal line) */}\n <line\n x1={lineOffsetX + this.scaleWidth}\n y1=\"15\"\n x2={lineOffsetX + this.scaleWidth}\n y2={15 - tickHeight}\n stroke=\"black\"\n strokeWidth=\"6\"\n />\n </svg>,\n rootElement\n );\n }\n\n onViewportChange(viewport: Viewport): void {\n // Only handle geospatial viewports (which contain latitude)\n if (!('latitude' in viewport)) return;\n\n const {latitude, zoom} = viewport as {latitude: number; zoom: number};\n const metersPerPixel = getMetersPerPixel(latitude, zoom);\n const {candidate, candidatePixels} = computeScaleCandidate(metersPerPixel);\n\n this.scaleValue = candidate;\n this.scaleWidth = candidatePixels;\n // Format the candidate distance for display (using km if >= 1000 m)\n if (candidate >= 1000) {\n this.scaleText = `${(candidate / 1000).toFixed(1)} km`;\n } else {\n this.scaleText = `${candidate} m`;\n }\n this.updateHTML();\n }\n\n handleClick(): void {}\n}\n\n/**\n * Compute the meters per pixel at a given latitude and zoom level.\n *\n * @param latitude - The current latitude.\n * @param zoom - The current zoom level.\n * @returns The number of meters per pixel.\n */\nfunction getMetersPerPixel(latitude: number, zoom: number): number {\n const earthCircumference = 40075016.686;\n return (earthCircumference * Math.cos((latitude * Math.PI) / 180)) / Math.pow(2, zoom + 8);\n}\n\n/**\n * Compute a \"nice\" scale candidate such that the scale bar width in pixels is between 100 and 200.\n * The candidate distance (in meters) will be one of a set of round numbers (100, 200, 500, 1000, 2000, 5000, etc.).\n *\n * @param metersPerPixel - The number of meters per pixel at the current zoom/latitude.\n * @returns An object containing the candidate distance and its width in pixels.\n */\nfunction computeScaleCandidate(metersPerPixel: number): {\n candidate: number;\n candidatePixels: number;\n} {\n const minPixels = 100;\n const maxPixels = 200;\n const targetPixels = (minPixels + maxPixels) / 2;\n const targetDistance = targetPixels * metersPerPixel;\n\n const exponent = Math.floor(Math.log10(targetDistance));\n const base = Math.pow(10, exponent);\n const multipliers = [1, 2, 5];\n\n let candidate = multipliers[0] * base;\n let candidatePixels = candidate / metersPerPixel;\n\n for (let i = 0; i < multipliers.length; i++) {\n const currentCandidate = multipliers[i] * base;\n const currentPixels = currentCandidate / metersPerPixel;\n if (currentPixels >= minPixels && currentPixels <= maxPixels) {\n candidate = currentCandidate;\n candidatePixels = currentPixels;\n break;\n }\n if (currentPixels > maxPixels) {\n candidate = i > 0 ? multipliers[i - 1] * base : currentCandidate;\n candidatePixels = candidate / metersPerPixel;\n break;\n }\n if (i === multipliers.length - 1 && currentPixels < minPixels) {\n candidate = multipliers[0] * base * 10;\n candidatePixels = candidate / metersPerPixel;\n }\n }\n return {candidate, candidatePixels};\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget} from '@deck.gl/core';\nimport type {WidgetPlacement, Viewport, WidgetProps} from '@deck.gl/core';\nimport {FlyToInterpolator, LinearInterpolator} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {DropdownMenu} from './lib/components/dropdown-menu';\nimport {type Geocoder} from './lib/geocode/geocoder';\nimport {GeocoderHistory} from './lib/geocode/geocoder-history';\nimport {\n GoogleGeocoder,\n MapboxGeocoder,\n OpenCageGeocoder,\n CoordinatesGeocoder,\n CurrentLocationGeocoder\n} from './lib/geocode/geocoders';\n\n/** @todo - is the the best we can do? */\ntype ViewState = Record<string, unknown>;\n\nconst CURRENT_LOCATION = 'current';\n\n/** Properties for the GeocoderWidget */\nexport type GeocoderWidgetProps = WidgetProps & {\n viewId?: string | null;\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** Tooltip message */\n label?: string;\n /** View state reset transition duration in ms. 0 disables the transition */\n transitionDuration?: number;\n /** Geocoding service selector, for declarative usage */\n geocoder?: 'google' | 'mapbox' | 'opencage' | 'coordinates' | 'custom';\n /** Custom geocoding service (Used when geocoder = 'custom') */\n customGeocoder?: Geocoder;\n /** API key used for geocoding services */\n apiKey?: string;\n /** Whether to use geolocation @note Experimental*/\n _geolocation?: boolean;\n};\n\n/**\n * A widget that display a text box that lets user type in a location\n * and a button that moves the view to that location.\n * @todo For now only supports coordinates, Could be extended with location service integrations.\n */\nexport class GeocoderWidget extends Widget<GeocoderWidgetProps> {\n static defaultProps: Required<GeocoderWidgetProps> = {\n ...Widget.defaultProps,\n id: 'geocoder',\n viewId: null,\n placement: 'top-left',\n label: 'Geocoder',\n transitionDuration: 200,\n geocoder: 'coordinates',\n customGeocoder: CoordinatesGeocoder,\n apiKey: '',\n _geolocation: false\n };\n\n className = 'deck-widget-geocoder';\n placement: WidgetPlacement = 'top-left';\n\n geocodeHistory = new GeocoderHistory({});\n addressText: string = '';\n geocoder: Geocoder = CoordinatesGeocoder;\n\n constructor(props: GeocoderWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<GeocoderWidgetProps>): void {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n this.geocoder = getGeocoder(this.props);\n if (this.geocoder.requiresApiKey && !this.props.apiKey) {\n throw new Error(`API key is required for the ${this.geocoder.name} geocoder`);\n }\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const menuItems = this.props._geolocation\n ? [CURRENT_LOCATION, ...this.geocodeHistory.addressHistory]\n : [...this.geocodeHistory.addressHistory];\n render(\n <div\n className=\"deck-widget-geocoder\"\n style={{\n pointerEvents: 'auto',\n display: 'flex',\n alignItems: 'center',\n flexWrap: 'wrap' // Allows wrapping on smaller screens\n }}\n >\n <input\n type=\"text\"\n placeholder={this.geocoder.placeholderLocation ?? 'Enter address or location'}\n value={this.geocodeHistory.addressText}\n // @ts-expect-error event type\n onInput={e => this.setInput(e.target?.value || '')}\n onKeyPress={this.handleKeyPress}\n style={{\n flex: '1 1 auto',\n minWidth: '200px',\n margin: 0,\n padding: '8px',\n boxSizing: 'border-box'\n }}\n />\n <DropdownMenu\n menuItems={menuItems}\n onSelect={this.handleSelect}\n style={{\n margin: 2,\n padding: '4px 2px',\n boxSizing: 'border-box'\n }}\n />\n {this.geocodeHistory.errorText && (\n <div className=\"error\">{this.geocodeHistory.errorText}</div>\n )}\n </div>,\n rootElement\n );\n }\n\n setInput = (text: string) => {\n this.addressText = text;\n };\n\n handleKeyPress = e => {\n if (e.key === 'Enter') {\n this.handleSubmit();\n }\n };\n\n handleSelect = (address: string) => {\n this.setInput(address);\n this.handleSubmit();\n };\n\n /** Sync wrapper for async geocode() */\n handleSubmit = () => {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.geocode(this.addressText);\n };\n\n /** Perform geocoding */\n geocode: (address: string) => Promise<void> = async address => {\n const useGeolocation = this.props._geolocation && address === CURRENT_LOCATION;\n const geocoder = useGeolocation ? CurrentLocationGeocoder : this.geocoder;\n const coordinates = await this.geocodeHistory.geocode(\n geocoder,\n this.addressText,\n this.props.apiKey\n );\n if (coordinates) {\n this.setViewState(coordinates);\n }\n };\n\n // TODO - MOVE TO WIDGETIMPL?\n setViewState(viewState: ViewState) {\n const viewId = this.props.viewId || (viewState?.id as string) || 'default-view';\n const viewport = this.viewports[viewId] || {};\n const nextViewState: ViewState = {\n ...viewport,\n ...viewState\n };\n if (this.props.transitionDuration > 0) {\n nextViewState.transitionDuration = this.props.transitionDuration;\n nextViewState.transitionInterpolator =\n 'latitude' in nextViewState ? new FlyToInterpolator() : new LinearInterpolator();\n }\n\n // @ts-ignore Using private method temporary until there's a public one\n this.deck._onViewStateChange({viewId, viewState: nextViewState, interactionState: {}});\n }\n\n onViewportChange(viewport: Viewport) {\n this.viewports[viewport.id] = viewport;\n }\n\n viewports: Record<string, Viewport> = {};\n}\n\nfunction getGeocoder(props: {geocoder?: string; customGeocoder?: Geocoder}): Geocoder {\n switch (props.geocoder) {\n case 'google':\n return GoogleGeocoder;\n case 'mapbox':\n return MapboxGeocoder;\n case 'opencage':\n return OpenCageGeocoder;\n case 'coordinates':\n return CoordinatesGeocoder;\n case 'custom':\n if (!props.customGeocoder) {\n throw new Error('Custom geocoder is not defined');\n }\n return props.customGeocoder;\n default:\n throw new Error(`Unknown geocoder: ${props.geocoder}`);\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {type JSX} from 'preact';\nimport {useState, useRef, useEffect} from 'preact/hooks';\n\nexport type DropdownMenuProps = {\n menuItems: string[];\n onSelect: (value: string) => void;\n style?: JSX.CSSProperties;\n};\n\nexport const DropdownMenu = (props: DropdownMenuProps) => {\n const [isOpen, setIsOpen] = useState(false);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n const toggleDropdown = () => setIsOpen(!isOpen);\n\n const handleClickOutside = (event: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n }\n };\n\n useEffect(() => {\n document.addEventListener('mousedown', handleClickOutside);\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n };\n }, []);\n\n const handleSelect = (value: string) => {\n props.onSelect(value);\n setIsOpen(false);\n };\n\n return (\n <div\n className=\"dropdown-container\"\n ref={dropdownRef}\n style={{\n position: 'relative',\n display: 'inline-block',\n ...props.style\n }}\n >\n <button\n onClick={toggleDropdown}\n style={{\n width: '30px',\n height: '30px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n border: '1px solid #ccc',\n borderRadius: '4px',\n background: '#fff',\n cursor: 'pointer',\n padding: 0\n }}\n >\n \u25BC\n </button>\n {isOpen && (\n <ul\n style={{\n position: 'absolute',\n top: '100%',\n right: '100%',\n background: '#fff',\n border: '1px solid #ccc',\n borderRadius: '4px',\n listStyle: 'none',\n padding: '4px 0',\n margin: 0,\n zIndex: 1000,\n minWidth: '200px'\n }}\n >\n {props.menuItems.map(item => (\n <li\n key={item}\n onClick={() => handleSelect(item)}\n style={{\n padding: '4px 8px',\n cursor: 'pointer',\n whiteSpace: 'nowrap'\n }}\n >\n {item}\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n};\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {type Geocoder} from './geocoder';\n\nconst CURRENT_LOCATION = 'current';\nconst LOCAL_STORAGE_KEY = 'deck-geocoder-history';\n\nexport type GeocoderHistoryProps = {\n maxEntries?: number;\n};\n\n/**\n * An internal, experimental helper class for storing a list of locations in local storage.\n * @todo Remove the UI related state.\n */\nexport class GeocoderHistory {\n props: Required<GeocoderHistoryProps>;\n addressText = '';\n errorText = '';\n addressHistory: string[] = [];\n\n constructor(props: GeocoderHistoryProps) {\n this.props = {maxEntries: 5, ...props};\n this.addressHistory = this.loadPreviousAddresses();\n }\n\n /** PErform geocoding */\n async geocode(geocoder: Geocoder, address: string, apiKey: string) {\n this.errorText = '';\n this.addressText = address;\n try {\n const coordinates = await geocoder.geocode(address, apiKey);\n if (coordinates) {\n this.storeAddress(this.addressText);\n return coordinates;\n }\n this.errorText = 'Invalid address';\n } catch (error) {\n this.errorText = `${(error as Error).message}`;\n }\n return null;\n }\n\n loadPreviousAddresses(): string[] {\n try {\n const stored = window.localStorage.getItem(LOCAL_STORAGE_KEY);\n const list = stored && JSON.parse(stored);\n const addresses = Array.isArray(list)\n ? list.filter((v): v is string => typeof v === 'string')\n : [];\n return addresses;\n } catch {\n // ignore\n }\n return [];\n }\n\n storeAddress(address: string) {\n const cleaned = address.trim();\n if (!cleaned || cleaned === CURRENT_LOCATION) {\n return;\n }\n const deduped = [cleaned, ...this.addressHistory.filter(a => a !== cleaned)];\n this.addressHistory = deduped.slice(0, this.props.maxEntries);\n try {\n window.localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(this.addressHistory));\n } catch {\n // ignore\n }\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {type Geocoder} from './geocoder';\n\nconst GOOGLE_URL = 'https://maps.googleapis.com/maps/api/geocode/json';\nconst MAPBOX_URL = 'https://api.mapbox.com/geocoding/v5/mapbox.places';\nconst OPENCAGE_API_URL = 'https://api.opencagedata.com/geocode/v1/json';\n\n/**\n * A geocoder that uses the google geocoding service\n * @note Requires an API key from Google\n * @see https://developers.google.com/maps/documentation/geocoding/get-api-key\n */\nexport const GoogleGeocoder = {\n name: 'google',\n requiresApiKey: true,\n async geocode(\n address: string,\n apiKey: string\n ): Promise<{longitude: number; latitude: number} | null> {\n const encodedAddress = encodeURIComponent(address);\n const json = await fetchJson(`${GOOGLE_URL}?address=${encodedAddress}&key=${apiKey}`);\n\n switch (json.status) {\n case 'OK':\n const loc = json.results.length > 0 && json.results[0].geometry.location;\n return loc ? {longitude: loc.lng, latitude: loc.lat} : null;\n default:\n throw new Error(`Google Geocoder failed: ${json.status}`);\n }\n }\n} as const satisfies Geocoder;\n\n/**\n * A geocoder that uses the google geocoding service\n * @note Requires an API key from Mapbox\n * @see https://docs.mapbox.com/api/search/geocoding/\n */\nexport const MapboxGeocoder = {\n name: 'google',\n requiresApiKey: true,\n async geocode(\n address: string,\n apiKey: string\n ): Promise<{longitude: number; latitude: number} | null> {\n const encodedAddress = encodeURIComponent(address);\n const json = await fetchJson(`${MAPBOX_URL}/${encodedAddress}.json?access_token=${apiKey}`);\n\n if (Array.isArray(json.features) && json.features.length > 0) {\n const center = json.features[0].center;\n if (Array.isArray(center) && center.length >= 2) {\n return {longitude: center[0], latitude: center[1]};\n }\n }\n return null;\n }\n} as const satisfies Geocoder;\n\n/**\n * A geocoder that uses the google geocoding service\n * @note Requires an API key from OpenCageData\n * @see https://opencagedata.com/api\n */\nexport const OpenCageGeocoder = {\n name: 'opencage',\n requiresApiKey: true,\n async geocode(\n address: string,\n key: string\n ): Promise<{longitude: number; latitude: number} | null> {\n const encodedAddress = encodeURIComponent(address);\n const data = await fetchJson(`${OPENCAGE_API_URL}?q=${encodedAddress}&key=${key}`);\n if (Array.isArray(data.results) && data.results.length > 0) {\n const geometry = data.results[0].geometry;\n return {longitude: geometry.lng, latitude: geometry.lat};\n }\n return null;\n }\n} as const satisfies Geocoder;\n\n/**\n * A geocoder adapter that wraps the browser's geolocation API. Always returns the user's current location.\n * @note Not technically a geocoder, but a geolocation service that provides a source of locations.\n * @note The user must allow location access for this to work.\n */\nexport const CurrentLocationGeocoder = {\n name: 'current',\n requiresApiKey: false,\n /** Attempt to call browsers geolocation API */\n async geocode(): Promise<{longitude: number; latitude: number} | null> {\n if (!navigator.geolocation) {\n throw new Error('Geolocation not supported');\n }\n return new Promise((resolve, reject) => {\n navigator.geolocation.getCurrentPosition(\n /** @see https://developer.mozilla.org/docs/Web/API/GeolocationPosition */\n (position: GeolocationPosition) => {\n const {longitude, latitude} = position.coords;\n resolve({longitude, latitude});\n },\n /** @see https://developer.mozilla.org/docs/Web/API/GeolocationPositionError */\n (error: GeolocationPositionError) => reject(new Error(error.message))\n );\n });\n }\n} as const satisfies Geocoder;\n\n/** Fetch JSON, catching HTTP errors */\nasync function fetchJson(url: string): Promise<any> {\n let response: Response;\n try {\n response = await fetch(url);\n } catch (error) {\n // Annoyingly, fetch reports some errors (e.g. CORS) using excpetions, not response.ok\n throw new Error(`CORS error? ${error}. ${url}: `);\n }\n if (!response.ok) {\n throw new Error(`${response.statusText}. ${url}: `);\n }\n const data = await response.json();\n if (!data) {\n throw new Error(`No data returned. ${url}`);\n }\n return data;\n}\n\n/**\n * Parse a coordinate string.\n * Supports comma- or semicolon-separated values.\n * Heuristically determines which value is longitude and which is latitude.\n */\nexport const CoordinatesGeocoder = {\n name: 'coordinates',\n requiresApiKey: false,\n placeholderLocation: `-122.45, 37.8 or 37\u00B048'N, 122\u00B027'W`,\n async geocode(address: string): Promise<{longitude: number; latitude: number} | null> {\n return parseCoordinates(address) || null;\n }\n} as const satisfies Geocoder;\n\n/**\n * Parse an input string for coordinates.\n * Supports comma- or semicolon-separated values.\n * Heuristically determines which value is longitude and which is latitude.\n */\nfunction parseCoordinates(input) {\n input = input.trim();\n const parts = input.split(/[,;]/).map(p => p.trim());\n if (parts.length < 2) return null;\n const first = parseCoordinatePart(parts[0]);\n const second = parseCoordinatePart(parts[1]);\n if (first === null || second === null) return null;\n // Use a heuristic:\n // If one number exceeds 90 in absolute value, it's likely a longitude.\n if (Math.abs(first) > 90 && Math.abs(second) <= 90) {\n return {longitude: first, latitude: second};\n } else if (Math.abs(second) > 90 && Math.abs(first) <= 90) {\n return {longitude: second, latitude: first};\n }\n // If both are <= 90, assume order: latitude, longitude.\n return {latitude: first, longitude: second};\n}\n\n/**\n * Parse a single coordinate part (which may be in decimal or DMS format).\n */\nfunction parseCoordinatePart(s: string): number | null {\n s = s.trim();\n // If the string contains a degree symbol or similar markers, use DMS parsing.\n if (s.includes('\u00B0') || s.includes(\"'\") || s.includes('\"')) {\n const value = dmsToDecimal(s);\n return isNaN(value) ? null : value;\n }\n // Otherwise, check for a cardinal letter and remove it.\n let sign = 1;\n if (/[SW]/i.test(s)) sign = -1;\n s = s.replace(/[NSEW]/gi, '');\n const value = parseFloat(s);\n return isNaN(value) ? null : sign * value;\n}\n\n/** Convert a DMS string (e.g. \"37\u00B048'00\\\"N\") to decimal degrees. */\nfunction dmsToDecimal(s: string): number {\n // A simple regex to extract degrees, minutes, seconds and direction.\n const regex = /(\\d+)[\u00B0d]\\s*(\\d+)?['\u2032m]?\\s*(\\d+(?:\\.\\d+)?)?[\\\"\u2033s]?\\s*([NSEW])?/i;\n const match = s.match(regex);\n if (!match) return NaN;\n const degrees = parseFloat(match[1]) || 0;\n const minutes = parseFloat(match[2]) || 0;\n const seconds = parseFloat(match[3]) || 0;\n const direction = match[4] || '';\n let dec = degrees + minutes / 60 + seconds / 3600;\n if (/[SW]/i.test(direction)) {\n dec = -dec;\n }\n return dec;\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/* global document */\nimport {log, Widget, type WidgetProps, type WidgetPlacement} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {IconButton} from './lib/components/icon-button';\n\n/* eslint-enable max-len */\n\nexport type FullscreenWidgetProps = WidgetProps & {\n id?: string;\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Tooltip message when out of fullscreen. */\n enterLabel?: string;\n /** Tooltip message when fullscreen. */\n exitLabel?: string;\n /**\n * A compatible DOM element which should be made full screen. By default, the map container element will be made full screen.\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullScreen#Compatible_elements\n */\n container?: HTMLElement;\n};\n\nexport class FullscreenWidget extends Widget<FullscreenWidgetProps> {\n static defaultProps: Required<FullscreenWidgetProps> = {\n ...Widget.defaultProps,\n id: 'fullscreen',\n placement: 'top-left',\n viewId: null,\n enterLabel: 'Enter Fullscreen',\n exitLabel: 'Exit Fullscreen',\n container: undefined!\n };\n\n className = 'deck-widget-fullscreen';\n placement: WidgetPlacement = 'top-left';\n fullscreen: boolean = false;\n\n constructor(props: FullscreenWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n onAdd(): void {\n document.addEventListener('fullscreenchange', this.onFullscreenChange.bind(this));\n }\n\n onRemove() {\n document.removeEventListener('fullscreenchange', this.onFullscreenChange.bind(this));\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n render(\n <IconButton\n onClick={() => {\n this.handleClick().catch(err => log.error(err)());\n }}\n label={this.fullscreen ? this.props.exitLabel : this.props.enterLabel}\n className={this.fullscreen ? 'deck-widget-fullscreen-exit' : 'deck-widget-fullscreen-enter'}\n />,\n rootElement\n );\n }\n\n setProps(props: Partial<FullscreenWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n getContainer() {\n return this.props.container || this.deck?.getCanvas()?.parentElement;\n }\n\n onFullscreenChange() {\n const prevFullscreen = this.fullscreen;\n const fullscreen = document.fullscreenElement === this.getContainer();\n if (prevFullscreen !== fullscreen) {\n this.fullscreen = !this.fullscreen;\n }\n this.updateHTML();\n }\n\n async handleClick() {\n if (this.fullscreen) {\n await this.exitFullscreen();\n } else {\n await this.requestFullscreen();\n }\n this.updateHTML();\n }\n\n async requestFullscreen() {\n const container = this.getContainer();\n if (container?.requestFullscreen) {\n await container.requestFullscreen({navigationUI: 'hide'});\n } else {\n this.togglePseudoFullscreen();\n }\n }\n\n async exitFullscreen() {\n if (document.exitFullscreen) {\n await document.exitFullscreen();\n } else {\n this.togglePseudoFullscreen();\n }\n }\n\n togglePseudoFullscreen() {\n this.getContainer()?.classList.toggle('deck-pseudo-fullscreen');\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {h, render} from 'preact';\nimport {useState, useRef} from 'preact/hooks';\nimport {Widget, type WidgetProps} from '@deck.gl/core';\n\n/** Properties for the SplitterWidget */\nexport type SplitterWidgetProps = WidgetProps & {\n /** The view id for the first (resizable) view */\n viewId1: string;\n /** The view id for the second view */\n viewId2: string;\n /** Orientation of the splitter: vertical (default) or horizontal */\n orientation?: 'vertical' | 'horizontal';\n /** The initial split percentage (0 to 1) for the first view, default 0.5 */\n initialSplit?: number;\n /** Callback invoked when the splitter is dragged with the new split value */\n onChange?: (newSplit: number) => void;\n /** Callback invoked when dragging starts */\n onDragStart?: () => void;\n /** Callback invoked when dragging ends */\n onDragEnd?: () => void;\n};\n\n/**\n * A draggable splitter widget that appears as a vertical or horizontal line\n * across the deck.gl canvas. It positions itself based on the split percentage\n * of the first view and provides callbacks when dragged.\n */\nexport class SplitterWidget extends Widget<SplitterWidgetProps> {\n static defaultProps: Required<SplitterWidgetProps> = {\n ...Widget.defaultProps,\n id: 'splitter-widget',\n viewId1: '',\n viewId2: '',\n orientation: 'vertical',\n initialSplit: 0.5,\n onChange: () => {},\n onDragStart: () => {},\n onDragEnd: () => {}\n };\n\n className = 'deck-widget-splitter';\n placement = 'fill' as const;\n\n constructor(props: SplitterWidgetProps) {\n super(props);\n }\n\n setProps(props: Partial<SplitterWidgetProps>) {\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n // Ensure the widget container fills the deck.gl canvas.\n // TODO - Move styling to CSS\n rootElement.style.position = 'absolute';\n rootElement.style.top = '0';\n rootElement.style.left = '0';\n rootElement.style.width = '100%';\n rootElement.style.height = '100%';\n rootElement.style.margin = '0px';\n\n render(\n <Splitter\n orientation={this.props.orientation}\n initialSplit={this.props.initialSplit}\n onChange={this.props.onChange}\n onDragStart={this.props.onDragStart}\n onDragEnd={this.props.onDragEnd}\n />,\n rootElement\n );\n }\n}\n\n/**\n * A functional component that renders a draggable splitter line.\n * It computes its position based on the provided split percentage and\n * updates it during mouse drag events.\n */\nfunction Splitter({\n orientation,\n initialSplit,\n onChange,\n onDragStart,\n onDragEnd\n}: {\n orientation: 'vertical' | 'horizontal';\n initialSplit: number;\n onChange?: (newSplit: number) => void;\n onDragStart?: () => void;\n onDragEnd?: () => void;\n}) {\n const [split, setSplit] = useState(initialSplit);\n const dragging = useRef(false);\n const containerRef = useRef<HTMLDivElement>(null);\n\n const handleDragStart = (event: MouseEvent) => {\n dragging.current = true;\n onDragStart?.();\n document.addEventListener('mousemove', handleDragging);\n document.addEventListener('mouseup', handleDragEnd);\n event.preventDefault();\n };\n\n const handleDragging = (event: MouseEvent) => {\n if (!dragging.current || !containerRef.current) return;\n const rect = containerRef.current.getBoundingClientRect();\n let newSplit: number;\n if (orientation === 'vertical') {\n newSplit = (event.clientX - rect.left) / rect.width;\n } else {\n newSplit = (event.clientY - rect.top) / rect.height;\n }\n // Clamp newSplit between 5% and 95%\n newSplit = Math.min(Math.max(newSplit, 0.05), 0.95);\n setSplit(newSplit);\n onChange?.(newSplit);\n };\n\n const handleDragEnd = (event: MouseEvent) => {\n if (!dragging.current) return;\n dragging.current = false;\n onDragEnd?.();\n document.removeEventListener('mousemove', handleDragging);\n document.removeEventListener('mouseup', handleDragEnd);\n };\n\n // The splitter line style based on orientation and the current split percentage.\n const splitterStyle: h.JSX.CSSProperties =\n orientation === 'vertical'\n ? {\n position: 'absolute',\n top: 0,\n bottom: 0,\n left: `${split * 100}%`,\n width: '4px',\n cursor: 'col-resize',\n background: '#ccc',\n zIndex: 10,\n pointerEvents: 'auto',\n boxShadow: 'inset -1px 0 0 white, inset 1px 0 0 white'\n }\n : {\n position: 'absolute',\n left: 0,\n right: 0,\n top: `${split * 100}%`,\n height: '4px',\n cursor: 'row-resize',\n background: '#ccc',\n zIndex: 10,\n pointerEvents: 'auto',\n boxShadow: 'inset -1px 0 0 white, inset 1px 0 0 white'\n };\n\n // Container style to fill the entire deck.gl canvas.\n const containerStyle: h.JSX.CSSProperties = {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0\n };\n\n return (\n <div ref={containerRef} style={containerStyle}>\n <div\n style={splitterStyle}\n onMouseDown={handleDragStart as h.JSX.MouseEventHandler<HTMLElement>} // Use the appropriate Preact event type.\n />\n </div>\n );\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {render, JSX} from 'preact';\nimport {Widget, type WidgetProps, type WidgetPlacement} from '@deck.gl/core';\nimport {IconMenu} from './lib/components/icon-menu';\n\n/** The available view modes */\nexport type ViewMode = 'single' | 'split-horizontal' | 'split-vertical';\n\n/** Properties for the ViewSelectorWidget */\nexport type ViewSelectorWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Tooltip label */\n label?: string;\n /** The initial view mode. Defaults to 'single'. */\n initialViewMode?: ViewMode;\n /** Callback invoked when the view mode changes */\n onViewModeChange?: (mode: ViewMode) => void;\n};\n\n/**\n * A widget that renders a popup menu for selecting a view mode.\n * It displays a button with the current view mode icon. Clicking the button\n * toggles a popup that shows three icons for:\n * - Single view\n * - Two views, split horizontally\n * - Two views, split vertically\n */\nexport class ViewSelectorWidget extends Widget<ViewSelectorWidgetProps> {\n static defaultProps: Required<ViewSelectorWidgetProps> = {\n ...Widget.defaultProps,\n id: 'view-selector',\n placement: 'top-left',\n viewId: null,\n label: 'Split View',\n initialViewMode: 'single',\n onViewModeChange: () => {}\n };\n\n className = 'deck-widget-view-selector';\n placement: WidgetPlacement = 'top-left';\n viewMode: ViewMode;\n\n constructor(props: ViewSelectorWidgetProps = {}) {\n super(props);\n this.viewMode = this.props.initialViewMode;\n this.setProps(this.props);\n }\n\n setProps(props: Partial<ViewSelectorWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement) {\n render(\n <IconMenu<ViewMode>\n className=\"deck-widget-view-selector\"\n menuItems={MENU_ITEMS.map(item => ({\n ...item,\n icon: item.icon()\n }))}\n initialItem={this.props.initialViewMode}\n onItemSelected={this.handleSelectMode}\n />,\n rootElement\n );\n }\n\n handleSelectMode = (viewMode: ViewMode) => {\n this.viewMode = viewMode;\n this.updateHTML();\n this.props.onViewModeChange(viewMode);\n };\n}\n\nconst ICON_STYLE = {width: '24px', height: '24px'};\n\n// JSX wrapped in a function to fix deck's Node tests\nconst ICONS: Record<ViewMode, () => JSX.Element> = {\n single: () => (\n <svg width=\"24\" height=\"24\" style={ICON_STYLE}>\n <rect\n x=\"4\"\n y=\"4\"\n width=\"16\"\n height=\"16\"\n stroke=\"var(--button-icon-hover, rgb(24, 24, 26))\"\n fill=\"none\"\n strokeWidth=\"2\"\n />\n </svg>\n ),\n 'split-horizontal': () => (\n <svg width=\"24\" height=\"24\" style={ICON_STYLE}>\n <rect\n x=\"4\"\n y=\"4\"\n width=\"16\"\n height=\"7\"\n stroke=\"var(--button-icon-hover, rgb(24, 24, 26))\"\n fill=\"none\"\n strokeWidth=\"2\"\n />\n <rect\n x=\"4\"\n y=\"13\"\n width=\"16\"\n height=\"7\"\n stroke=\"var(--button-icon-hover, rgb(24, 24, 26))\"\n fill=\"none\"\n strokeWidth=\"2\"\n />\n </svg>\n ),\n 'split-vertical': () => (\n <svg width=\"24\" height=\"24\" style={ICON_STYLE}>\n <rect\n x=\"4\"\n y=\"4\"\n width=\"7\"\n height=\"16\"\n stroke=\"var(--button-icon-hover, rgb(24, 24, 26))\"\n fill=\"none\"\n strokeWidth=\"2\"\n />\n <rect\n x=\"13\"\n y=\"4\"\n width=\"7\"\n height=\"16\"\n stroke=\"var(--button-icon-hover, rgb(24, 24, 26))\"\n fill=\"none\"\n strokeWidth=\"2\"\n />\n </svg>\n )\n};\n\n// Define menu items for the popup menu.\nconst MENU_ITEMS: Array<{value: ViewMode; icon: () => JSX.Element; label: string}> = [\n {value: 'single', icon: ICONS.single, label: 'Single View'},\n {value: 'split-horizontal', icon: ICONS['split-horizontal'], label: 'Split Horizontal'},\n {value: 'split-vertical', icon: ICONS['split-vertical'], label: 'Split Vertical'}\n];\n", "import type {JSX} from 'preact';\nimport {useState, useRef, useEffect} from 'preact/hooks';\nimport {IconButton} from './icon-button';\nimport {ButtonGroup} from './button-group';\nimport {GroupedIconButton} from './grouped-icon-button';\n\nexport type IconMenuProps<KeyType = string> = {\n className: string;\n icon?: JSX.Element;\n label?: string;\n menuItems: {value: KeyType; icon: JSX.Element; label: string}[];\n initialItem: KeyType;\n onItemSelected: (item: KeyType) => void;\n};\n\n/** A component that renders an icon popup menu */\nexport function IconMenu<KeyType extends string>(props: IconMenuProps<KeyType>) {\n const [menuOpen, setMenuOpen] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Close the menu when clicking outside.\n const handleClickOutside = (event: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\n setMenuOpen(false);\n }\n };\n\n useEffect(() => {\n document.addEventListener('mousedown', handleClickOutside);\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n };\n }, [containerRef]);\n\n const [selectedItem, setSelectedItem] = useState<KeyType>(props.initialItem);\n\n const handleSelectItem = (item: KeyType) => {\n setSelectedItem(item);\n setMenuOpen(false);\n props.onItemSelected(item);\n };\n\n const handleButtonClick = () => setMenuOpen(!menuOpen);\n\n const selectedMenuItem = props.menuItems.find(item => item.value === selectedItem);\n const label = props.label || selectedMenuItem?.label || '';\n const icon = (props.icon || selectedMenuItem?.icon)!;\n\n return (\n <div style={{position: 'relative', display: 'inline-block'}} ref={containerRef}>\n <IconButton className={props.className} label={label} onClick={handleButtonClick}>\n {icon}\n </IconButton>\n {menuOpen && (\n <div className=\"deck-widget-icon-menu\">\n <ButtonGroup orientation=\"vertical\">\n {props.menuItems.map(item => (\n <GroupedIconButton\n key={item.value}\n label={item.label}\n onClick={() => handleSelectItem(item.value)}\n >\n {item.icon}\n </GroupedIconButton>\n ))}\n </ButtonGroup>\n </div>\n )}\n </div>\n );\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget} from '@deck.gl/core';\nimport type {Deck, PickingInfo, Viewport, WidgetProps} from '@deck.gl/core';\nimport {render, JSX} from 'preact';\n\nexport type InfoWidgetProps = WidgetProps & {\n /** View to attach to and interact with. Required when using multiple views */\n viewId?: string | null;\n /** Determines the interaction mode of the widget */\n mode: 'click' | 'hover' | 'static';\n /** Function to generate the popup contents from the selected element */\n getTooltip?: (info: PickingInfo, widget: InfoWidget) => InfoWidgetProps | null;\n /** Position at which to place popup (clicked point: [longitude, latitude]) */\n position: [number, number];\n /** Text content of popup */\n text?: string;\n /** Visibility of info widget */\n visible?: boolean;\n /** Minimum offset (in pixels) to keep the popup away from the canvas edges. */\n minOffset?: number;\n /** Callback triggered when the widget is clicked. */\n onClick?: (widget: InfoWidget, info: PickingInfo) => boolean;\n};\n\nexport class InfoWidget extends Widget<InfoWidgetProps> {\n static defaultProps: Required<InfoWidgetProps> = {\n ...Widget.defaultProps,\n id: 'info',\n position: [0, 0],\n text: '',\n visible: false,\n minOffset: 0,\n viewId: null,\n mode: 'hover',\n getTooltip: undefined!,\n onClick: undefined!\n };\n\n className = 'deck-widget-info';\n placement = 'fill' as const;\n viewport?: Viewport;\n\n constructor(props: InfoWidgetProps) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<InfoWidgetProps>) {\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onCreateRootElement(): HTMLDivElement {\n const element = super.onCreateRootElement();\n const style = {margin: '0px', top: '0px', left: '0px', position: 'absolute'};\n Object.entries(style).forEach(([key, value]) => element.style.setProperty(key, value));\n return element;\n }\n\n onViewportChange(viewport) {\n this.viewport = viewport;\n this.updateHTML();\n }\n\n onHover(info: PickingInfo): void {\n if (this.props.mode === 'hover' && this.props.getTooltip) {\n const tooltip = this.props.getTooltip(info, this);\n // hover tooltips should show over static and click infos\n this.setProps({\n visible: tooltip !== null,\n ...tooltip,\n style: {zIndex: '1', ...tooltip?.style}\n });\n }\n }\n\n onClick(info: PickingInfo): boolean {\n if (this.props.mode === 'click' && this.props.getTooltip) {\n const tooltip = this.props.getTooltip(info, this);\n this.setProps({\n visible: tooltip !== null,\n ...tooltip\n });\n return tooltip !== null;\n }\n\n // Original behavior\n return this.props.onClick?.(this, info) || false;\n }\n\n onAdd({deck, viewId}: {deck: Deck<any>; viewId: string | null}) {\n this.deck = deck;\n if (!viewId) {\n this.viewport = deck.getViewports()[0];\n } else {\n this.viewport = deck.getViewports().find(viewport => viewport.id === viewId);\n }\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n if (!this.viewport) {\n return;\n }\n const [longitude, latitude] = this.props.position;\n // Project the clicked geographic coordinate to canvas (x, y)\n const [x, y] = this.viewport.project([longitude, latitude]);\n\n const minOffset = this.props.minOffset || 0;\n const gap = 10; // gap between clicked point and popup box\n const arrowHeight = 8; // height of the triangle arrow\n const arrowWidth = 16; // full width of the arrow\n\n // Decide vertical orientation.\n // If the clicked point is in the bottom half, place the popup above the point.\n const isAbove = y > this.viewport.height / 2;\n const background = (this.props.style && this.props.style.background) || 'rgba(255,255,255,0.9)';\n\n // Render the popup container with a content box and a placeholder for the arrow.\n // The container is positioned absolutely (initially at 0,0) and will be repositioned after measuring.\n const ui = this.props.visible ? (\n <div className=\"popup-container\" style={{position: 'absolute', left: 0, top: 0}}>\n <div\n className=\"popup-content\"\n style={{\n background,\n padding: '10px',\n position: 'relative',\n // Include any additional styles\n ...(this.props.style as JSX.CSSProperties)\n }}\n >\n {this.props.text}\n </div>\n <div className=\"popup-arrow\" style={{position: 'absolute', width: '0px', height: '0px'}} />\n </div>\n ) : null;\n render(ui, rootElement);\n\n // After rendering, measure the content and adjust positioning so that:\n // - The popup (with its arrow) does not cover the clicked point.\n // - The arrow's tip points to the clicked point.\n // - The popup remains within the canvas bounds, with minOffset.\n // eslint-disable-next-line max-statements, complexity\n requestAnimationFrame(() => {\n if (!this.props.visible || !rootElement.firstChild || !this.viewport) return;\n\n const container = rootElement.firstChild as HTMLElement;\n const contentEl = container.querySelector('.popup-content') as HTMLElement;\n const arrowEl = container.querySelector('.popup-arrow') as HTMLElement;\n if (!contentEl || !arrowEl) return;\n const contentRect = contentEl.getBoundingClientRect();\n const popupWidth = contentRect.width;\n const popupHeight = contentRect.height;\n\n // Compute ideal horizontal position: center the popup on the clicked x\n let computedLeft = x - popupWidth / 2;\n // Compute vertical position based on orientation:\n // If the popup is above, position its bottom edge (minus arrow & gap) at the clicked y.\n // Otherwise, position its top edge (plus arrow & gap) at the clicked y.\n let computedTop;\n if (isAbove) {\n computedTop = y - gap - arrowHeight - popupHeight;\n } else {\n computedTop = y + gap + arrowHeight;\n }\n\n // Ensure the popup (content) stays within horizontal bounds of the canvas\n if (computedLeft < minOffset) {\n computedLeft = minOffset;\n }\n if (computedLeft + popupWidth > this.viewport.width - minOffset) {\n computedLeft = this.viewport.width - minOffset - popupWidth;\n }\n\n // Ensure the vertical position (including the arrow) stays within canvas bounds.\n if (isAbove) {\n if (computedTop < minOffset) {\n computedTop = minOffset;\n }\n } else if (computedTop + popupHeight + arrowHeight > this.viewport.height - minOffset) {\n computedTop = this.viewport.height - minOffset - popupHeight - arrowHeight;\n }\n\n // Update container position (remove any transform and set left/top explicitly)\n container.style.left = `${computedLeft}px`;\n container.style.top = `${computedTop}px`;\n container.style.transform = '';\n\n // Compute arrow's horizontal offset relative to the container.\n // We want the arrow's tip to align with the clicked point.\n let arrowLeft = x - computedLeft - arrowWidth / 2;\n // Optionally constrain arrowLeft so it stays within the popup's width.\n arrowLeft = Math.max(arrowLeft, 0);\n arrowLeft = Math.min(arrowLeft, popupWidth - arrowWidth);\n\n // Update arrow element's style based on orientation.\n if (isAbove) {\n // Popup is above the clicked point so arrow appears at the bottom of the popup.\n arrowEl.style.left = `${arrowLeft}px`;\n arrowEl.style.bottom = `-${arrowHeight}px`;\n arrowEl.style.top = '';\n arrowEl.style.borderLeft = `${arrowWidth / 2}px solid transparent`;\n arrowEl.style.borderRight = `${arrowWidth / 2}px solid transparent`;\n arrowEl.style.borderTop = `${arrowHeight}px solid ${background}`;\n arrowEl.style.borderBottom = '';\n } else {\n // Popup is below the clicked point so arrow appears at the top.\n arrowEl.style.left = `${arrowLeft}px`;\n arrowEl.style.top = `-${arrowHeight}px`;\n arrowEl.style.bottom = '';\n arrowEl.style.borderLeft = `${arrowWidth / 2}px solid transparent`;\n arrowEl.style.borderRight = `${arrowWidth / 2}px solid transparent`;\n arrowEl.style.borderBottom = `${arrowHeight}px solid ${background}`;\n arrowEl.style.borderTop = '';\n }\n });\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/* global document */\nimport {Widget} from '@deck.gl/core';\nimport type {Deck, PickingInfo, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {SimpleMenu} from './lib/components/simple-menu';\n\n/** The standard, modern way is to use event.button === 2, where button is the standardized property (0 = left, 1 = middle, 2 = right). */\nconst MOUSE_BUTTON_RIGHT = 2;\n/** A name for the legacy MouseEvent.which value that corresponds to the right-mouse button. In older browsers, the check is: if (event.which === 3) */\nconst MOUSE_WHICH_RIGHT = 3;\n\nexport type ContextWidgetMenuItem = {\n label: string;\n key: string;\n};\n\nexport type ContextMenuWidgetProps = WidgetProps & {\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Controls visibility of the context menu */\n visible?: boolean;\n /** Screen position at which to place the menu */\n position: {x: number; y: number};\n /** Items to render */\n menuItems: ContextWidgetMenuItem[];\n /** Provide menu items for the menu given the picked object */\n getMenuItems: (info: PickingInfo, widget: ContextMenuWidget) => ContextWidgetMenuItem[] | null;\n /** Callback with the selected item */\n onMenuItemSelected?: (key: string, pickInfo: PickingInfo | null) => void;\n};\n\nexport class ContextMenuWidget extends Widget<ContextMenuWidgetProps> {\n static defaultProps: Required<ContextMenuWidgetProps> = {\n ...Widget.defaultProps,\n id: 'context',\n viewId: null,\n visible: false,\n position: {x: 0, y: 0},\n getMenuItems: undefined!,\n menuItems: [],\n // eslint-disable-next-line no-console\n onMenuItemSelected: (key, pickInfo) => console.log('Context menu item selected:', key, pickInfo)\n };\n\n className = 'deck-widget-context-menu';\n placement = 'fill' as const;\n\n pickInfo: PickingInfo | null = null;\n\n constructor(props: ContextMenuWidgetProps) {\n super(props);\n this.pickInfo = null;\n this.setProps(this.props);\n }\n\n onAdd({deck}: {deck: Deck<any>}): HTMLDivElement {\n const element = document.createElement('div');\n element.classList.add('deck-widget', 'deck-widget-context-menu');\n const style = {\n margin: '0px',\n top: '0px',\n left: '0px',\n position: 'absolute',\n pointerEvents: 'auto'\n };\n Object.entries(style).forEach(([key, value]) => element.style.setProperty(key, value));\n\n deck.getCanvas()?.addEventListener('click', () => this.hide());\n deck.getCanvas()?.addEventListener('contextmenu', event => this.handleContextMenu(event));\n return element;\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const {visible, position, menuItems} = this.props;\n\n const ui =\n visible && menuItems.length ? (\n <SimpleMenu\n menuItems={menuItems}\n onItemSelected={key => this.props.onMenuItemSelected(key, this.pickInfo)}\n position={position}\n style={{pointerEvents: 'auto'}}\n />\n ) : null;\n render(ui, rootElement);\n }\n\n handleContextMenu(srcEvent: MouseEvent): boolean {\n if (\n srcEvent &&\n (srcEvent.button === MOUSE_BUTTON_RIGHT || srcEvent.which === MOUSE_WHICH_RIGHT)\n ) {\n this.pickInfo =\n this.deck?.pickObject({\n x: srcEvent.clientX,\n y: srcEvent.clientY\n }) || null;\n const menuItems = (this.pickInfo && this.props.getMenuItems?.(this.pickInfo, this)) || [];\n const visible = menuItems.length > 0;\n this.setProps({\n visible,\n position: {x: srcEvent.clientX, y: srcEvent.clientY},\n menuItems\n });\n this.updateHTML();\n srcEvent.preventDefault();\n return visible;\n }\n\n return false;\n }\n\n hide(): void {\n this.setProps({visible: false});\n }\n}\n", "import type {JSX} from 'preact';\n\nconst MENU_STYLE: JSX.CSSProperties = {\n position: 'absolute',\n top: '100%',\n left: 0,\n background: 'white',\n border: '1px solid #ccc',\n borderRadius: '4px',\n marginTop: 'var(--menu-gap, 4px)',\n zIndex: 100\n};\n\nconst MENU_ITEM_STYLE: JSX.CSSProperties = {\n background: 'white',\n border: 'none',\n padding: '4px',\n cursor: 'pointer',\n pointerEvents: 'auto'\n};\n\nexport type SimpleMenuProps = {\n menuItems: {key: string; label: string}[];\n onItemSelected: (key: string) => void;\n position: {x: number; y: number};\n style?: JSX.CSSProperties;\n};\n\n/** Renders a simple dropdown menu at an arbitrary position */\nexport const SimpleMenu = (props: SimpleMenuProps) => {\n const {menuItems, onItemSelected, position, style} = props;\n const styleOverride: JSX.CSSProperties = {\n ...MENU_STYLE,\n ...style,\n left: `${position.x}px`,\n top: `${position.y}px`\n };\n\n return (\n <div style={styleOverride}>\n {menuItems.map(({key, label}) => (\n <button\n key={key}\n style={{...MENU_ITEM_STYLE, display: 'block'}}\n onClick={_ => onItemSelected(key)}\n >\n {label}\n </button>\n ))}\n </div>\n );\n};\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget, type WidgetPlacement, type WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {IconButton} from './lib/components/icon-button';\n\nexport type TimelineWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'bottom-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Slider timeRange [min, max]. */\n timeRange?: [number, number];\n /** Slider step. */\n step?: number;\n /** Initial slider value. */\n initialTime?: number;\n /** Callback when value changes. */\n onTimeChange?: (value: number) => void;\n /** Play interval in milliseconds. */\n playInterval?: number;\n};\n\nexport class TimelineWidget extends Widget<TimelineWidgetProps> {\n id = 'timeline';\n className = 'deck-widget-timeline';\n placement: WidgetPlacement = 'bottom-left';\n\n private playing = false;\n private timerId: number | null = null;\n currentTime: number;\n\n static defaultProps: Required<TimelineWidgetProps> = {\n ...Widget.defaultProps,\n id: 'timeline',\n placement: 'bottom-left',\n viewId: null,\n timeRange: [0, 100],\n step: 1,\n initialTime: undefined!,\n onTimeChange: () => {},\n playInterval: 1000\n };\n\n constructor(props: TimelineWidgetProps = {}) {\n super(props);\n this.currentTime = this.props.initialTime ?? this.props.timeRange[0];\n this.setProps(this.props);\n }\n\n setProps(props: Partial<TimelineWidgetProps>): void {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onAdd(): void {\n this.playing = false;\n this.timerId = null;\n }\n\n onRemove(): void {\n this.stop();\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n render(\n <div style={{display: 'flex', alignItems: 'center', pointerEvents: 'auto'}}>\n <IconButton label={this.playing ? 'Pause' : 'Play'} onClick={this.handlePlayPause}>\n <div className=\"text\">{this.playing ? '\u23F8' : '\u25B6'}</div>\n </IconButton>\n <input\n type=\"range\"\n className=\"timeline-slider\"\n min={this.props.timeRange[0]}\n max={this.props.timeRange[1]}\n step={this.props.step}\n value={this.currentTime}\n onInput={this.handleSliderChange}\n />\n </div>,\n rootElement\n );\n }\n\n private handlePlayPause = (): void => {\n if (this.playing) {\n this.stop();\n } else {\n this.start();\n }\n };\n\n private handleSliderChange = (e: Event): void => {\n const input = e.target as HTMLInputElement;\n const val = Number(input.value);\n this.currentTime = val;\n this.props.onTimeChange(val);\n this.updateHTML();\n };\n\n private start(): void {\n this.playing = true;\n this.updateHTML();\n this.tick();\n }\n\n private stop(): void {\n this.playing = false;\n if (this.timerId !== null) {\n window.clearTimeout(this.timerId);\n this.timerId = null;\n }\n this.updateHTML();\n }\n\n private tick = (): void => {\n const [min, max] = this.props.timeRange;\n let next = this.currentTime + this.props.step;\n if (next > max) {\n next = min;\n }\n this.currentTime = next;\n this.props.onTimeChange(next);\n this.updateHTML();\n if (this.playing) {\n this.timerId = window.setTimeout(this.tick, this.props.playInterval);\n }\n };\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/* global document */\nimport type {WidgetPlacement, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {Widget} from '@deck.gl/core';\nimport {IconButton} from './lib/components/icon-button';\n\n/** Properties for the ScreenshotWidget */\nexport type ScreenshotWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Tooltip message */\n label?: string;\n /** Filename to save to */\n filename?: string;\n /** Image format */\n imageFormat?: 'image/png' | 'image/jpeg';\n /** Callback, if defined user overrides the capture logic */\n onCapture?: (widget: ScreenshotWidget) => void;\n};\n\n/**\n * A button widget that captures a screenshot of the current canvas and downloads it as a (png) file.\n * @note only captures canvas contents, not HTML DOM or CSS styles\n */\nexport class ScreenshotWidget extends Widget<ScreenshotWidgetProps> {\n static defaultProps: Required<ScreenshotWidgetProps> = {\n ...Widget.defaultProps,\n id: 'screenshot',\n placement: 'top-left',\n viewId: null,\n label: 'Screenshot',\n filename: 'screenshot.png',\n imageFormat: 'image/png',\n onCapture: undefined!\n };\n\n className = 'deck-widget-screenshot';\n placement: WidgetPlacement = 'top-left';\n\n constructor(props: ScreenshotWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<ScreenshotWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n render(\n <IconButton\n className=\"deck-widget-camera\"\n label={this.props.label}\n onClick={this.handleClick.bind(this)}\n />,\n rootElement\n );\n }\n\n handleClick() {\n // Allow user to override the capture logic\n if (this.props.onCapture) {\n this.props.onCapture(this);\n return;\n }\n const dataURL = this.captureScreenToDataURL(this.props.imageFormat);\n if (dataURL) {\n this.downloadDataURL(dataURL, this.props.filename);\n }\n }\n\n /** @note only captures canvas contents, not HTML DOM or CSS styles */\n captureScreenToDataURL(imageFormat: string): string | undefined {\n const canvas = this.deck?.getCanvas();\n return canvas?.toDataURL(imageFormat);\n }\n\n /** Download a data URL */\n downloadDataURL(dataURL: string, filename: string): void {\n const link = document.createElement('a');\n link.href = dataURL;\n link.download = filename;\n link.click();\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {log, _deepEqual as deepEqual, _applyStyles as applyStyles} from '@deck.gl/core';\nimport {Widget, type WidgetProps, type WidgetPlacement} from '@deck.gl/core';\nimport {render} from 'preact';\n// import {useCallback} from 'preact/hooks';\nimport {IconButton} from './lib/components/icon-button';\nimport type {DeckWidgetTheme} from './themes';\nimport {LightGlassTheme, DarkGlassTheme} from './themes';\n\nexport type ThemeWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Tooltip message when dark mode is selected. */\n lightModeLabel?: string;\n /** Styles for light mode theme */\n lightModeTheme?: DeckWidgetTheme;\n /** Tooltip message when light mode is selected. */\n darkModeLabel?: string;\n /** Styles for dark mode theme */\n darkModeTheme?: DeckWidgetTheme;\n /** Initial theme mode. 'auto' reads the browser default setting */\n initialThemeMode?: 'auto' | 'light' | 'dark';\n};\n\nexport class ThemeWidget extends Widget<ThemeWidgetProps> {\n static defaultProps: Required<ThemeWidgetProps> = {\n ...Widget.defaultProps,\n id: 'theme',\n placement: 'top-left',\n viewId: null,\n lightModeLabel: 'Light Mode',\n lightModeTheme: LightGlassTheme,\n darkModeLabel: 'Dark Mode',\n darkModeTheme: DarkGlassTheme,\n initialThemeMode: 'auto'\n };\n\n className = 'deck-widget-theme';\n placement: WidgetPlacement = 'top-left';\n themeMode: 'light' | 'dark' = 'dark';\n\n constructor(props: ThemeWidgetProps = {}) {\n super(props);\n this.themeMode = this._getInitialThemeMode();\n this.setProps(this.props);\n }\n\n // eslint-disable-next-line complexity\n setProps(props: Partial<ThemeWidgetProps>) {\n const {lightModeTheme, darkModeTheme} = this.props;\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n\n switch (this.themeMode) {\n case 'light':\n if (props.lightModeTheme && !deepEqual(props.lightModeTheme, lightModeTheme, 1)) {\n this._setThemeMode('light');\n }\n break;\n case 'dark':\n if (props.darkModeTheme && !deepEqual(props.darkModeTheme, darkModeTheme, 1)) {\n this._setThemeMode('dark');\n }\n break;\n default:\n log.warn(`Invalid theme mode ${this.themeMode}`)();\n }\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const {lightModeLabel, darkModeLabel} = this.props;\n // const onClick = useCallback(this._handleClick.bind(this), [this._handleClick]);\n\n render(\n <IconButton\n onClick={this._handleClick.bind(this)}\n label={this.themeMode === 'dark' ? darkModeLabel : lightModeLabel}\n className={this.themeMode === 'dark' ? 'deck-widget-moon' : 'deck-widget-sun'}\n />,\n rootElement\n );\n }\n\n onAdd() {\n // Note: theme styling is applied in here onAdd() once DOM element is created\n this._setThemeMode(this.themeMode);\n }\n\n _handleClick() {\n const newThemeMode = this.themeMode === 'dark' ? 'light' : 'dark';\n this._setThemeMode(newThemeMode);\n }\n\n _setThemeMode(themeMode: 'light' | 'dark') {\n this.themeMode = themeMode;\n const container = this.rootElement?.closest<HTMLDivElement>('.deck-widget-container');\n if (container) {\n const themeStyle =\n themeMode === 'dark' ? this.props.darkModeTheme : this.props.lightModeTheme;\n applyStyles(container, themeStyle);\n\n const label =\n this.themeMode === 'dark' ? this.props.darkModeLabel : this.props.lightModeLabel;\n log.log(1, `Switched theme to ${label}`, themeStyle)();\n\n this.updateHTML();\n }\n }\n\n /** Read browser preference */\n _getInitialThemeMode(): 'light' | 'dark' {\n const {initialThemeMode} = this.props;\n return initialThemeMode === 'auto'\n ? window.matchMedia('(prefers-color-scheme: dark)').matches\n ? 'dark'\n : 'light'\n : initialThemeMode;\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/**\n * A Deck Theme is a set of CSS variables that control CSS styling of the official widgets.\n */\nexport type DeckWidgetTheme = {\n // layout\n '--widget-margin'?: string;\n // button and button group\n '--button-size'?: string;\n '--button-corner-radius'?: string;\n '--button-background'?: string;\n '--button-stroke'?: string;\n '--button-inner-stroke'?: string;\n '--button-shadow'?: string;\n '--button-backdrop-filter'?: string;\n '--button-icon-idle'?: string;\n '--button-icon-hover'?: string;\n '--button-text'?: string;\n // inter-icon color\n '--icon-compass-north-color'?: string;\n '--icon-compass-south-color'?: string;\n // menu\n '--menu-gap'?: string;\n};\n\nexport const LightTheme = {\n '--widget-margin': '12px',\n '--button-size': '28px',\n '--button-corner-radius': '8px',\n '--button-background': '#fff',\n '--button-stroke': 'rgba(255, 255, 255, 0.3)',\n '--button-inner-stroke': 'unset',\n '--button-shadow': '0px 0px 8px 0px rgba(0, 0, 0, 0.25)',\n '--button-backdrop-filter': 'unset',\n '--button-icon-idle': 'rgba(97, 97, 102, 1)',\n '--button-icon-hover': 'rgba(24, 24, 26, 1)',\n '--button-text': 'rgb(24, 24, 26, 1)',\n '--icon-compass-north-color': 'rgb(240, 92, 68)',\n '--icon-compass-south-color': 'rgb(204, 204, 204)',\n '--menu-gap': '4px'\n} as const satisfies Required<DeckWidgetTheme>;\n\nexport const DarkTheme = {\n '--widget-margin': '12px',\n '--button-size': '28px',\n '--button-corner-radius': '8px',\n '--button-background': 'rgba(18, 18, 20, 1)',\n '--button-stroke': 'rgba(18, 18, 20, 0.30)',\n '--button-inner-stroke': 'unset',\n '--button-shadow': '0px 0px 8px 0px rgba(0, 0, 0, 0.25)',\n '--button-backdrop-filter': 'unset',\n '--button-icon-idle': 'rgba(158, 157, 168, 1)',\n '--button-icon-hover': 'rgba(215, 214, 229, 1)',\n '--button-text': 'rgb(215, 214, 229, 1)',\n '--icon-compass-north-color': 'rgb(240, 92, 68)',\n '--icon-compass-south-color': 'rgb(200, 199, 209)',\n '--menu-gap': '4px'\n} as const satisfies Required<DeckWidgetTheme>;\n\nexport const LightGlassTheme = {\n '--widget-margin': '12px',\n '--button-size': '28px',\n '--button-corner-radius': '8px',\n '--button-background': 'rgba(255, 255, 255, 0.6)',\n '--button-stroke': 'rgba(255, 255, 255, 0.3)',\n '--button-inner-stroke': '1px solid rgba(255, 255, 255, 0.6)',\n '--button-shadow':\n '0px 0px 8px 0px rgba(0, 0, 0, 0.25), 0px 0px 8px 0px rgba(0, 0, 0, 0.1) inset',\n '--button-backdrop-filter': 'blur(4px)',\n '--button-icon-idle': 'rgba(97, 97, 102, 1)',\n '--button-icon-hover': 'rgba(24, 24, 26, 1)',\n '--button-text': 'rgb(24, 24, 26, 1)',\n '--icon-compass-north-color': 'rgb(240, 92, 68)',\n '--icon-compass-south-color': 'rgb(204, 204, 204)',\n '--menu-gap': '4px'\n} as const satisfies Required<DeckWidgetTheme>;\n\nexport const DarkGlassTheme = {\n '--widget-margin': '12px',\n '--button-size': '28px',\n '--button-corner-radius': '8px',\n '--button-background': 'rgba(18, 18, 20, 0.75)',\n '--button-stroke': 'rgba(18, 18, 20, 0.30)',\n '--button-inner-stroke': '1px solid rgba(18, 18, 20, 0.75)',\n '--button-shadow':\n '0px 0px 8px 0px rgba(0, 0, 0, 0.25), 0px 0px 8px 0px rgba(0, 0, 0, 0.1) inset',\n '--button-backdrop-filter': 'blur(4px)',\n '--button-icon-idle': 'rgba(158, 157, 168, 1)',\n '--button-icon-hover': 'rgba(215, 214, 229, 1)',\n '--button-text': 'rgb(215, 214, 229, 1)',\n '--icon-compass-north-color': 'rgb(240, 92, 68)',\n '--icon-compass-south-color': 'rgb(200, 199, 209)',\n '--menu-gap': '4px'\n} as const satisfies Required<DeckWidgetTheme>;\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {WidgetPlacement, Layer, WidgetProps} from '@deck.gl/core';\nimport {render} from 'preact';\nimport {Widget} from '@deck.gl/core';\nimport {IconButton} from './lib/components/icon-button';\n\n/** Properties for the LoadingWidget */\nexport type LoadingWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views */\n viewId?: string | null;\n /** Tooltip message when loading */\n label?: string;\n};\n\n/**\n * A non-interactive widget that shows a loading spinner if any layers are loading data\n */\nexport class LoadingWidget extends Widget<LoadingWidgetProps> {\n static defaultProps: Required<LoadingWidgetProps> = {\n ...Widget.defaultProps,\n id: 'loading',\n placement: 'top-left',\n viewId: null,\n label: 'Loading layer data'\n };\n\n className = 'deck-widget-loading';\n placement: WidgetPlacement = 'top-left';\n loading = true;\n\n constructor(props: LoadingWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<LoadingWidgetProps>) {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n render(\n // TODO(ibgreen) - this should not be a button, but styling is so nested that it is easier to reuse this component.\n this.loading && (\n <IconButton\n className=\"deck-widget-spinner\"\n label={this.props.label}\n onClick={this.handleClick.bind(this)}\n />\n ),\n rootElement\n );\n }\n\n onRedraw({layers}: {layers: Layer[]}): void {\n const loading = layers.some(layer => !layer.isLoaded);\n if (loading !== this.loading) {\n this.loading = loading;\n this.updateHTML();\n }\n }\n\n // TODO(ibgreen) - this should not be a button, see above.\n handleClick() {}\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget} from '@deck.gl/core';\nimport {render} from 'preact';\nimport type {WidgetPlacement, Deck, WidgetProps} from '@deck.gl/core';\nimport {IconButton} from './lib/components/icon-button';\n\n/** Properties for the FpsWidget. */\nexport type FpsWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n};\n\n/**\n * Displays the average frames per second reported by the Deck instance.\n */\nexport class FpsWidget extends Widget<FpsWidgetProps> {\n static defaultProps: Required<FpsWidgetProps> = {\n ...Widget.defaultProps,\n id: 'fps',\n placement: 'top-left',\n viewId: null\n };\n\n className = 'deck-widget-fps';\n placement: WidgetPlacement = 'top-left';\n\n private _lastFps: number = -1;\n\n constructor(props: FpsWidgetProps = {}) {\n super(props);\n this.setProps(this.props);\n }\n\n setProps(props: Partial<FpsWidgetProps>): void {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n super.setProps(props);\n }\n\n onAdd({}: {deck: Deck<any>; viewId: string | null}): void {\n this._lastFps = this._getFps();\n requestAnimationFrame(() => this._animate());\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const fps = this._getFps();\n render(\n <IconButton>\n <div className=\"text\">\n FPS\n <br />\n {fps}\n </div>\n </IconButton>,\n rootElement\n );\n }\n\n _animate(): void {\n const fps = this._getFps();\n if (this._lastFps !== fps) {\n this._lastFps = fps;\n this.updateHTML();\n }\n requestAnimationFrame(() => this._animate());\n }\n\n _getFps(): number {\n // @ts-expect-error protected\n return Math.round(this.deck?.metrics.fps ?? 0);\n }\n}\n", "// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Widget, type WidgetPlacement, type WidgetProps} from '@deck.gl/core';\nimport {luma} from '@luma.gl/core';\nimport {render} from 'preact';\nimport type {Stats, Stat} from '@probe.gl/stats';\n\nconst RIGHT_ARROW = '\\u25b6';\nconst DOWN_ARROW = '\\u2b07';\n\nconst DEFAULT_COUNT_FORMATTER = (stat: Stat): string => `${stat.name}: ${stat.count}`;\n\nfunction formatTime(time: number): string {\n return time < 1000 ? `${time.toFixed(2)}ms` : `${(time / 1000).toFixed(2)}s`;\n}\n\nfunction formatMemory(bytes: number): string {\n const mb = bytes / 1e6;\n return `${mb.toFixed(1)} MB`;\n}\n\nexport const DEFAULT_FORMATTERS: Record<string, (stat: Stat) => string> = {\n count: DEFAULT_COUNT_FORMATTER,\n averageTime: (stat: Stat) => `${stat.name}: ${formatTime(stat.getAverageTime())}`,\n totalTime: (stat: Stat) => `${stat.name}: ${formatTime(stat.time)}`,\n fps: (stat: Stat) => `${stat.name}: ${Math.round(stat.getHz())}fps`,\n memory: (stat: Stat) => `${stat.name}: ${formatMemory(stat.count)}`\n};\n\nexport type StatsWidgetProps = WidgetProps & {\n /** Widget positioning within the view. Default 'top-left'. */\n placement?: WidgetPlacement;\n /** View to attach to and interact with. Required when using multiple views. */\n viewId?: string | null;\n /** Type of stats to display. */\n type?: 'deck' | 'luma' | 'device' | 'custom';\n /** Stats object to visualize. */\n stats?: Stats;\n /** Title shown in the header of the pop-up. Defaults to stats.id. */\n title?: string;\n /** How many redraws to wait between updates. */\n framesPerUpdate?: number;\n /** Custom formatters for stat values. */\n formatters?: Record<string, string | ((stat: Stat) => string)>;\n /** Whether to reset particular stats after each update. */\n resetOnUpdate?: Record<string, boolean>;\n};\n\n/** Displays probe.gl stats in a floating pop-up. */\nexport class StatsWidget extends Widget<StatsWidgetProps> {\n static defaultProps: Required<StatsWidgetProps> = {\n ...Widget.defaultProps,\n type: 'deck',\n placement: 'top-left',\n viewId: null,\n stats: undefined!,\n title: 'Stats',\n framesPerUpdate: 1,\n formatters: {},\n resetOnUpdate: {},\n id: 'stats'\n };\n\n className = 'deck-widget-stats';\n placement = 'top-left' as WidgetPlacement;\n\n private _counter = 0;\n private _formatters: Record<string, (stat: Stat) => string>;\n private _resetOnUpdate: Record<string, boolean>;\n collapsed: boolean = true;\n _stats: Stats;\n\n constructor(props: StatsWidgetProps = {}) {\n super(props);\n this._formatters = {...DEFAULT_FORMATTERS};\n this._resetOnUpdate = {...this.props.resetOnUpdate};\n this._stats = this.props.stats;\n this.setProps(props);\n }\n\n setProps(props: Partial<StatsWidgetProps>): void {\n this.placement = props.placement ?? this.placement;\n this.viewId = props.viewId ?? this.viewId;\n this._stats = this._getStats();\n if (props.formatters) {\n for (const name in props.formatters) {\n const f = props.formatters[name];\n this._formatters[name] =\n typeof f === 'string' ? DEFAULT_FORMATTERS[f] || DEFAULT_COUNT_FORMATTER : f;\n }\n }\n if (props.resetOnUpdate) {\n this._resetOnUpdate = {...props.resetOnUpdate};\n }\n super.setProps(props);\n }\n\n onAdd(): void {\n this._stats = this._getStats();\n this.updateHTML();\n }\n\n onRenderHTML(rootElement: HTMLElement): void {\n const stats = this._stats;\n const collapsed = this.collapsed;\n const title = this.props.title || stats?.id || 'Stats';\n const items: JSX.Element[] = [];\n\n if (!collapsed && stats) {\n stats.forEach(stat => {\n const lines = this._getLines(stat);\n if (this._resetOnUpdate && this._resetOnUpdate[stat.name]) {\n stat.reset();\n }\n lines.forEach((line, i) => {\n items.push(\n <div key={`${stat.name}-${i}`} style={{whiteSpace: 'pre'}}>\n {line}\n </div>\n );\n });\n });\n }\n\n render(\n <div className=\"deck-widget-stats-container\" style={{cursor: 'default'}}>\n <div\n className=\"deck-widget-stats-header\"\n style={{cursor: 'pointer', pointerEvents: 'auto'}}\n onClick={this._toggleCollapsed}\n >\n {collapsed ? RIGHT_ARROW : DOWN_ARROW} {title}\n </div>\n {!collapsed && <div className=\"deck-widget-stats-content\">{items}</div>}\n </div>,\n rootElement\n );\n }\n\n onRedraw(): void {\n const framesPerUpdate = Math.max(1, this.props.framesPerUpdate || 1);\n if (this._counter++ % framesPerUpdate === 0) {\n this._stats = this._getStats();\n this.updateHTML();\n }\n }\n\n protected _getStats(): Stats {\n switch (this.props.type) {\n case 'deck':\n // @ts-expect-error stats is protected\n return this.deck?.stats;\n case 'luma':\n return Array.from(luma.stats.stats.values())[0];\n case 'device':\n // @ts-expect-error is protected\n const device = this.deck?.device;\n const stats = device?.statsManager.stats.values();\n return stats ? Array.from(stats)[0] : undefined;\n case 'custom':\n return this.props.stats;\n default:\n throw new Error(`Unknown stats type: ${this.props.type}`);\n }\n }\n\n protected _toggleCollapsed = (): void => {\n this.collapsed = !this.collapsed;\n this.updateHTML();\n };\n\n protected _getLines(stat: Stat): string[] {\n const formatter =\n this._formatters[stat.name] || this._formatters[stat.type || ''] || DEFAULT_COUNT_FORMATTER;\n return formatter(stat).split('\\n');\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["_jsx", "_jsx", "_jsxs", "_jsx", "import_preact", "import_core", "_jsx", "_jsx", "import_core", "import_preact", "_jsx", "_jsxs", "import_core", "import_preact", "_jsx", "_jsxs", "import_preact", "import_core", "_jsxs", "_jsx", "import_core", "import_preact", "_jsxs", "_jsx", "value", "CURRENT_LOCATION", "_jsxs", "_jsx", "import_core", "import_preact", "_jsx", "import_preact", "import_hooks", "import_core", "_jsx", "import_preact", "import_core", "import_hooks", "_jsxs", "_jsx", "_jsx", "_jsxs", "import_core", "import_preact", "_jsxs", "_jsx", "import_core", "import_preact", "_jsx", "_jsx", "import_core", "import_preact", "_jsxs", "_jsx", "import_preact", "import_core", "_jsx", "import_core", "import_preact", "deepEqual", "_jsx", "applyStyles", "import_preact", "import_core", "_jsx", "import_core", "import_preact", "_jsx", "_jsxs", "import_core", "import_preact", "_jsx", "_jsxs"]
|
|
7
7
|
}
|