@smartnet360/svelte-components 0.0.57 → 0.0.58

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.
Files changed (44) hide show
  1. package/dist/map-v2/core/components/ViewportSync.svelte +79 -0
  2. package/dist/map-v2/core/components/ViewportSync.svelte.d.ts +8 -0
  3. package/dist/map-v2/core/index.d.ts +2 -0
  4. package/dist/map-v2/core/index.js +3 -0
  5. package/dist/map-v2/core/stores/viewportStore.svelte.d.ts +51 -0
  6. package/dist/map-v2/core/stores/viewportStore.svelte.js +120 -0
  7. package/dist/map-v2/demo/DemoMap.svelte +30 -3
  8. package/dist/map-v2/demo/demo-cells.d.ts +12 -0
  9. package/dist/map-v2/demo/demo-cells.js +114 -0
  10. package/dist/map-v2/demo/index.d.ts +1 -0
  11. package/dist/map-v2/demo/index.js +1 -0
  12. package/dist/map-v2/features/cells/constants/colors.d.ts +7 -0
  13. package/dist/map-v2/features/cells/constants/colors.js +21 -0
  14. package/dist/map-v2/features/cells/constants/radiusMultipliers.d.ts +8 -0
  15. package/dist/map-v2/features/cells/constants/radiusMultipliers.js +22 -0
  16. package/dist/map-v2/features/cells/constants/statusStyles.d.ts +7 -0
  17. package/dist/map-v2/features/cells/constants/statusStyles.js +49 -0
  18. package/dist/map-v2/features/cells/constants/zIndex.d.ts +14 -0
  19. package/dist/map-v2/features/cells/constants/zIndex.js +28 -0
  20. package/dist/map-v2/features/cells/controls/CellFilterControl.svelte +242 -0
  21. package/dist/map-v2/features/cells/controls/CellFilterControl.svelte.d.ts +14 -0
  22. package/dist/map-v2/features/cells/controls/CellStyleControl.svelte +139 -0
  23. package/dist/map-v2/features/cells/controls/CellStyleControl.svelte.d.ts +14 -0
  24. package/dist/map-v2/features/cells/index.d.ts +20 -0
  25. package/dist/map-v2/features/cells/index.js +24 -0
  26. package/dist/map-v2/features/cells/layers/CellsLayer.svelte +195 -0
  27. package/dist/map-v2/features/cells/layers/CellsLayer.svelte.d.ts +10 -0
  28. package/dist/map-v2/features/cells/stores/cellStoreContext.svelte.d.ts +46 -0
  29. package/dist/map-v2/features/cells/stores/cellStoreContext.svelte.js +137 -0
  30. package/dist/map-v2/features/cells/types.d.ts +99 -0
  31. package/dist/map-v2/features/cells/types.js +12 -0
  32. package/dist/map-v2/features/cells/utils/arcGeometry.d.ts +36 -0
  33. package/dist/map-v2/features/cells/utils/arcGeometry.js +55 -0
  34. package/dist/map-v2/features/cells/utils/cellGeoJSON.d.ts +22 -0
  35. package/dist/map-v2/features/cells/utils/cellGeoJSON.js +81 -0
  36. package/dist/map-v2/features/cells/utils/cellTree.d.ts +25 -0
  37. package/dist/map-v2/features/cells/utils/cellTree.js +226 -0
  38. package/dist/map-v2/features/cells/utils/techBandParser.d.ts +11 -0
  39. package/dist/map-v2/features/cells/utils/techBandParser.js +17 -0
  40. package/dist/map-v2/features/cells/utils/zoomScaling.d.ts +42 -0
  41. package/dist/map-v2/features/cells/utils/zoomScaling.js +53 -0
  42. package/dist/map-v2/index.d.ts +3 -2
  43. package/dist/map-v2/index.js +6 -2
  44. package/package.json +1 -1
@@ -0,0 +1,79 @@
1
+ <script lang="ts">
2
+ /**
3
+ * ViewportSync - Synchronizes map viewport changes with ViewportStore
4
+ *
5
+ * This component:
6
+ * - Gets map instance from MapboxProvider context
7
+ * - Listens to moveend/zoomend events
8
+ * - Updates viewport store when map moves/zooms
9
+ * - Handles cleanup on unmount
10
+ *
11
+ * Usage:
12
+ * ```svelte
13
+ * <MapboxProvider center={viewport.center} zoom={viewport.zoom}>
14
+ * <ViewportSync store={viewport} />
15
+ * <!-- other layers and controls -->
16
+ * </MapboxProvider>
17
+ * ```
18
+ */
19
+ import { getContext, onDestroy } from 'svelte';
20
+ import type { MapStore } from '../types';
21
+ import type { ViewportStore } from '../stores/viewportStore.svelte';
22
+ import { MAP_CONTEXT_KEY } from '../types';
23
+
24
+ interface Props {
25
+ /** Viewport store to sync with */
26
+ store: ViewportStore;
27
+ }
28
+
29
+ let { store }: Props = $props();
30
+
31
+ const mapStore = getContext<MapStore>(MAP_CONTEXT_KEY);
32
+ let map = $derived($mapStore);
33
+
34
+ // Track event listener cleanup functions
35
+ let cleanupFunctions: Array<() => void> = [];
36
+
37
+ // Sync map viewport to store on move/zoom end
38
+ $effect(() => {
39
+ if (!map) return;
40
+
41
+ // Handler to update store with current map viewport
42
+ const handleViewportChange = () => {
43
+ const center = map.getCenter();
44
+ const zoom = map.getZoom();
45
+ const bearing = map.getBearing();
46
+ const pitch = map.getPitch();
47
+
48
+ // Bulk update for efficiency
49
+ store.updateViewport({
50
+ center: [center.lng, center.lat],
51
+ zoom,
52
+ bearing,
53
+ pitch
54
+ });
55
+ };
56
+
57
+ // Listen to moveend (fires after pan, zoom, rotate, pitch)
58
+ map.on('moveend', handleViewportChange);
59
+
60
+ // Store cleanup function
61
+ cleanupFunctions.push(() => {
62
+ map?.off('moveend', handleViewportChange);
63
+ });
64
+
65
+ // Cleanup when effect re-runs or component unmounts
66
+ return () => {
67
+ cleanupFunctions.forEach(cleanup => cleanup());
68
+ cleanupFunctions = [];
69
+ };
70
+ });
71
+
72
+ onDestroy(() => {
73
+ // Final cleanup on unmount
74
+ cleanupFunctions.forEach(cleanup => cleanup());
75
+ cleanupFunctions = [];
76
+ });
77
+ </script>
78
+
79
+ <!-- This component doesn't render anything, it's just for side effects -->
@@ -0,0 +1,8 @@
1
+ import type { ViewportStore } from '../stores/viewportStore.svelte';
2
+ interface Props {
3
+ /** Viewport store to sync with */
4
+ store: ViewportStore;
5
+ }
6
+ declare const ViewportSync: import("svelte").Component<Props, {}, "">;
7
+ type ViewportSync = ReturnType<typeof ViewportSync>;
8
+ export default ViewportSync;
@@ -6,6 +6,8 @@
6
6
  export type { MapStore } from './types';
7
7
  export { MAP_CONTEXT_KEY } from './types';
8
8
  export { default as MapboxProvider } from './providers/MapboxProvider.svelte';
9
+ export { default as ViewportSync } from './components/ViewportSync.svelte';
9
10
  export { default as MapStyleControl } from './controls/MapStyleControl.svelte';
10
11
  export { createMapStore } from './stores/mapStore';
12
+ export { createViewportStore, type ViewportStore, type ViewportState } from './stores/viewportStore.svelte';
11
13
  export { useMapbox, tryUseMapbox } from './hooks/useMapbox';
@@ -6,9 +6,12 @@
6
6
  export { MAP_CONTEXT_KEY } from './types';
7
7
  // Providers
8
8
  export { default as MapboxProvider } from './providers/MapboxProvider.svelte';
9
+ // Components
10
+ export { default as ViewportSync } from './components/ViewportSync.svelte';
9
11
  // Controls
10
12
  export { default as MapStyleControl } from './controls/MapStyleControl.svelte';
11
13
  // Stores
12
14
  export { createMapStore } from './stores/mapStore';
15
+ export { createViewportStore } from './stores/viewportStore.svelte';
13
16
  // Hooks
14
17
  export { useMapbox, tryUseMapbox } from './hooks/useMapbox';
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Viewport Store - Manages and persists map viewport state (center, zoom, pitch, bearing)
3
+ *
4
+ * Features:
5
+ * - Reactive state using Svelte 5 runes
6
+ * - Auto-persists to localStorage via $effect
7
+ * - Namespace isolation for multiple map instances
8
+ * - Provides getters/setters for direct binding
9
+ *
10
+ * Usage:
11
+ * ```svelte
12
+ * const viewport = createViewportStore('my-map', {
13
+ * center: [-122.4194, 37.7749],
14
+ * zoom: 12
15
+ * });
16
+ *
17
+ * <MapboxProvider center={viewport.center} zoom={viewport.zoom}>
18
+ * <ViewportSync store={viewport} />
19
+ * </MapboxProvider>
20
+ * ```
21
+ */
22
+ export interface ViewportState {
23
+ /** Map center [lng, lat] */
24
+ center: [number, number];
25
+ /** Zoom level */
26
+ zoom: number;
27
+ /** Map bearing (rotation) in degrees */
28
+ bearing: number;
29
+ /** Map pitch (tilt) in degrees */
30
+ pitch: number;
31
+ }
32
+ export interface ViewportStore {
33
+ readonly center: [number, number];
34
+ readonly zoom: number;
35
+ readonly bearing: number;
36
+ readonly pitch: number;
37
+ setCenter(center: [number, number]): void;
38
+ setZoom(zoom: number): void;
39
+ setBearing(bearing: number): void;
40
+ setPitch(pitch: number): void;
41
+ updateViewport(state: Partial<ViewportState>): void;
42
+ reset(): void;
43
+ }
44
+ /**
45
+ * Create a viewport store with persistence
46
+ *
47
+ * @param namespace - Unique identifier for localStorage key
48
+ * @param defaults - Default viewport values (used if no saved state exists)
49
+ * @returns ViewportStore instance
50
+ */
51
+ export declare function createViewportStore(namespace: string, defaults?: Partial<ViewportState>): ViewportStore;
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Viewport Store - Manages and persists map viewport state (center, zoom, pitch, bearing)
3
+ *
4
+ * Features:
5
+ * - Reactive state using Svelte 5 runes
6
+ * - Auto-persists to localStorage via $effect
7
+ * - Namespace isolation for multiple map instances
8
+ * - Provides getters/setters for direct binding
9
+ *
10
+ * Usage:
11
+ * ```svelte
12
+ * const viewport = createViewportStore('my-map', {
13
+ * center: [-122.4194, 37.7749],
14
+ * zoom: 12
15
+ * });
16
+ *
17
+ * <MapboxProvider center={viewport.center} zoom={viewport.zoom}>
18
+ * <ViewportSync store={viewport} />
19
+ * </MapboxProvider>
20
+ * ```
21
+ */
22
+ const DEFAULT_STATE = {
23
+ center: [0, 0],
24
+ zoom: 2,
25
+ bearing: 0,
26
+ pitch: 0
27
+ };
28
+ /**
29
+ * Load viewport state from localStorage
30
+ */
31
+ function loadViewportState(namespace, defaults) {
32
+ if (typeof window === 'undefined') {
33
+ return { ...DEFAULT_STATE, ...defaults };
34
+ }
35
+ try {
36
+ const key = `${namespace}:viewport`;
37
+ const stored = localStorage.getItem(key);
38
+ if (stored) {
39
+ const parsed = JSON.parse(stored);
40
+ return {
41
+ center: parsed.center || defaults.center || DEFAULT_STATE.center,
42
+ zoom: parsed.zoom ?? defaults.zoom ?? DEFAULT_STATE.zoom,
43
+ bearing: parsed.bearing ?? defaults.bearing ?? DEFAULT_STATE.bearing,
44
+ pitch: parsed.pitch ?? defaults.pitch ?? DEFAULT_STATE.pitch
45
+ };
46
+ }
47
+ }
48
+ catch (error) {
49
+ console.warn('Failed to load viewport state:', error);
50
+ }
51
+ return { ...DEFAULT_STATE, ...defaults };
52
+ }
53
+ /**
54
+ * Save viewport state to localStorage
55
+ */
56
+ function saveViewportState(namespace, state) {
57
+ if (typeof window === 'undefined')
58
+ return;
59
+ try {
60
+ const key = `${namespace}:viewport`;
61
+ localStorage.setItem(key, JSON.stringify(state));
62
+ }
63
+ catch (error) {
64
+ console.warn('Failed to save viewport state:', error);
65
+ }
66
+ }
67
+ /**
68
+ * Create a viewport store with persistence
69
+ *
70
+ * @param namespace - Unique identifier for localStorage key
71
+ * @param defaults - Default viewport values (used if no saved state exists)
72
+ * @returns ViewportStore instance
73
+ */
74
+ export function createViewportStore(namespace, defaults = {}) {
75
+ // Load initial state
76
+ let state = $state(loadViewportState(namespace, defaults));
77
+ // Auto-save to localStorage on any change
78
+ $effect(() => {
79
+ saveViewportState(namespace, state);
80
+ });
81
+ return {
82
+ // Getters
83
+ get center() { return state.center; },
84
+ get zoom() { return state.zoom; },
85
+ get bearing() { return state.bearing; },
86
+ get pitch() { return state.pitch; },
87
+ // Setters
88
+ setCenter(center) {
89
+ state.center = center;
90
+ },
91
+ setZoom(zoom) {
92
+ state.zoom = zoom;
93
+ },
94
+ setBearing(bearing) {
95
+ state.bearing = bearing;
96
+ },
97
+ setPitch(pitch) {
98
+ state.pitch = pitch;
99
+ },
100
+ // Bulk update (more efficient than individual setters)
101
+ updateViewport(updates) {
102
+ if (updates.center !== undefined)
103
+ state.center = updates.center;
104
+ if (updates.zoom !== undefined)
105
+ state.zoom = updates.zoom;
106
+ if (updates.bearing !== undefined)
107
+ state.bearing = updates.bearing;
108
+ if (updates.pitch !== undefined)
109
+ state.pitch = updates.pitch;
110
+ },
111
+ // Reset to defaults
112
+ reset() {
113
+ const resetState = { ...DEFAULT_STATE, ...defaults };
114
+ state.center = resetState.center;
115
+ state.zoom = resetState.zoom;
116
+ state.bearing = resetState.bearing;
117
+ state.pitch = resetState.pitch;
118
+ }
119
+ };
120
+ }
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  /**
3
- * DemoMap - Complete demo of map-v2 site feature
3
+ * DemoMap - Complete demo of map-v2 site and cell features
4
4
  *
5
5
  * Demonstrates:
6
6
  * - Simplified MapboxProvider with automatic initialization
@@ -8,14 +8,24 @@
8
8
  * - SitesLayer rendering sites from store
9
9
  * - SiteFilterControl for hierarchical filtering
10
10
  * - SiteSizeSlider for visual property adjustment
11
+ * - CellsLayer rendering cells with arc geometries
12
+ * - CellFilterControl with dynamic hierarchical grouping
13
+ * - CellStyleControl for cell visual settings
11
14
  */
12
15
  import MapboxProvider from '../core/providers/MapboxProvider.svelte';
13
16
  import MapStyleControl from '../core/controls/MapStyleControl.svelte';
17
+ import ViewportSync from '../core/components/ViewportSync.svelte';
14
18
  import SitesLayer from '../features/sites/layers/SitesLayer.svelte';
15
19
  import SiteFilterControl from '../features/sites/controls/SiteFilterControl.svelte';
16
20
  import SiteSizeSlider from '../features/sites/controls/SiteSizeSlider.svelte';
21
+ import CellsLayer from '../features/cells/layers/CellsLayer.svelte';
22
+ import CellFilterControl from '../features/cells/controls/CellFilterControl.svelte';
23
+ import CellStyleControl from '../features/cells/controls/CellStyleControl.svelte';
17
24
  import { createSiteStoreContext } from '../features/sites/stores/siteStoreContext.svelte';
25
+ import { createCellStoreContext } from '../features/cells/stores/cellStoreContext.svelte';
26
+ import { createViewportStore } from '../core/stores/viewportStore.svelte';
18
27
  import { demoSites } from './demo-data';
28
+ import { demoCells } from './demo-cells';
19
29
 
20
30
  interface Props {
21
31
  /** Mapbox access token */
@@ -32,26 +42,43 @@
32
42
  zoom = 12
33
43
  }: Props = $props();
34
44
 
45
+ // Create viewport store with persistence (uses defaults as fallback)
46
+ const viewport = createViewportStore('demo-map', { center, zoom });
47
+
35
48
  // Create site store with demo data
36
49
  const siteStore = createSiteStoreContext(demoSites);
37
- console.log(siteStore)
50
+
51
+ // Create cell store with demo data
52
+ const cellStore = createCellStoreContext(demoCells);
38
53
 
39
54
  </script>
40
55
 
41
56
  <!-- // controls={['navigation', 'scale']} -->
42
57
  <div class="demo-map-container">
43
- <MapboxProvider {accessToken} {center} {zoom}>
58
+ <MapboxProvider {accessToken} center={viewport.center} zoom={viewport.zoom} bearing={viewport.bearing} pitch={viewport.pitch}>
59
+ <!-- Sync map viewport changes to store (with localStorage persistence) -->
60
+ <ViewportSync store={viewport} />
61
+
44
62
  <!-- Site layer - renders circles from store -->
45
63
  <SitesLayer store={siteStore} namespace="demo-sites" />
46
64
 
65
+ <!-- Cell layer - renders arc sectors from store -->
66
+ <CellsLayer store={cellStore} namespace="demo-cells" />
67
+
47
68
  <!-- Map style control - switch between map styles -->
48
69
  <MapStyleControl position="top-right" initiallyCollapsed={true} namespace="demo-map" />
49
70
 
50
71
  <!-- Site filter control - updates store.filteredSites -->
51
72
  <SiteFilterControl store={siteStore} position="top-left" title="Site Filter" />
52
73
 
74
+ <!-- Cell filter control - dynamic hierarchical filtering -->
75
+ <CellFilterControl store={cellStore} position="top-left" title="Cell Filter" initiallyCollapsed={true} />
76
+
53
77
  <!-- Site size control - updates store visual properties -->
54
78
  <SiteSizeSlider store={siteStore} position="bottom-right" title="Site Display" />
79
+
80
+ <!-- Cell style control - visual settings for cells -->
81
+ <CellStyleControl store={cellStore} position="bottom-left" title="Cell Display" initiallyCollapsed={true} />
55
82
  </MapboxProvider>
56
83
  </div>
57
84
 
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Demo Cell Data
3
+ *
4
+ * 1 site with 3 sectors (azimuths: 0°, 120°, 240°)
5
+ * Each sector has 12 cells (all tech-band combinations)
6
+ * Total: 36 cells
7
+ */
8
+ import type { Cell } from '../features/cells/types';
9
+ /**
10
+ * Generate demo cells: 3 sectors × 12 tech-bands = 36 cells
11
+ */
12
+ export declare const demoCells: Cell[];
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Demo Cell Data
3
+ *
4
+ * 1 site with 3 sectors (azimuths: 0°, 120°, 240°)
5
+ * Each sector has 12 cells (all tech-band combinations)
6
+ * Total: 36 cells
7
+ */
8
+ // Site location: San Francisco
9
+ const SITE_LAT = 37.7749;
10
+ const SITE_LNG = -122.4194;
11
+ const SITE_ID = 'DEMO-SITE-001';
12
+ // Standard beamwidth for sectors
13
+ const BEAMWIDTH = 65;
14
+ // Cell tech-band definitions with proper fband format
15
+ const TECH_BANDS = [
16
+ // 2G bands
17
+ { tech: '2G', band: '900', fband: 'GSM900' },
18
+ { tech: '2G', band: '1800', fband: 'GSM1800' },
19
+ // 4G bands
20
+ { tech: '4G', band: '700', fband: 'LTE700' },
21
+ { tech: '4G', band: '800', fband: 'LTE800' },
22
+ { tech: '4G', band: '900', fband: 'LTE900' },
23
+ { tech: '4G', band: '1800', fband: 'LTE1800' },
24
+ { tech: '4G', band: '2100', fband: 'LTE2100' },
25
+ { tech: '4G', band: '2600', fband: 'LTE2600' },
26
+ // 5G bands
27
+ { tech: '5G', band: '700', fband: '5G-700' },
28
+ { tech: '5G', band: '2100', fband: '5G-2100' },
29
+ { tech: '5G', band: '3500', fband: '5G-3500' }
30
+ ];
31
+ // Three sector azimuths
32
+ const AZIMUTHS = [0, 120, 240];
33
+ // Status rotation for variety
34
+ const STATUSES = [
35
+ 'On_Air',
36
+ 'On_Air',
37
+ 'On_Air',
38
+ 'On_Air',
39
+ 'On_Air_UNDER_CONSTRUCTION',
40
+ 'On_Air_Locked',
41
+ 'RF_Plan_Ready',
42
+ 'RF_Plan_Ready',
43
+ 'Re-Planned_RF_Plan_Ready',
44
+ 'Tavlati_RF_Plan_Ready',
45
+ 'On_Air',
46
+ 'On_Air'
47
+ ];
48
+ /**
49
+ * Generate demo cells: 3 sectors × 12 tech-bands = 36 cells
50
+ */
51
+ export const demoCells = [];
52
+ let cellCounter = 1;
53
+ AZIMUTHS.forEach((azimuth, sectorIndex) => {
54
+ TECH_BANDS.forEach((techBand, techIndex) => {
55
+ const cellId = `CELL-${String(cellCounter).padStart(3, '0')}`;
56
+ const status = STATUSES[techIndex];
57
+ demoCells.push({
58
+ // Core properties
59
+ id: cellId,
60
+ txId: `TX-${String(cellCounter).padStart(3, '0')}`,
61
+ cellID: cellId,
62
+ cellID2G: techBand.tech === '2G' ? cellId : '',
63
+ cellName: `Demo Cell ${techBand.tech} ${techBand.band} - Sector ${sectorIndex + 1}`,
64
+ siteId: SITE_ID,
65
+ tech: techBand.tech,
66
+ fband: techBand.fband,
67
+ frq: techBand.band,
68
+ type: 'MACRO',
69
+ status: status,
70
+ onAirDate: '2024-01-15',
71
+ // 2G specific
72
+ bcch: techBand.tech === '2G' ? 100 + techIndex : 0,
73
+ ctrlid: techBand.tech === '2G' ? `CTRL-${cellId}` : '',
74
+ // 4G specific
75
+ dlEarfn: techBand.tech === '4G' ? 6200 + techIndex * 100 : 0,
76
+ // Physical properties
77
+ antenna: 'DEMO-ANTENNA-MODEL',
78
+ azimuth: azimuth,
79
+ height: 30, // 30 meters antenna height
80
+ electricalTilt: '3',
81
+ beamwidth: BEAMWIDTH,
82
+ latitude: SITE_LAT,
83
+ longitude: SITE_LNG,
84
+ dx: 0,
85
+ dy: 0,
86
+ siteLatitude: SITE_LAT,
87
+ siteLongitude: SITE_LNG,
88
+ // Planning
89
+ comment: `Demo ${techBand.tech} ${techBand.band} cell at azimuth ${azimuth}°`,
90
+ planner: 'Demo User',
91
+ // Atoll properties
92
+ atollETP: 43.0,
93
+ atollPW: 20.0,
94
+ atollRS: 500.0 + (techBand.band === '700' ? 200 : 0), // Lower freq = longer range
95
+ atollBW: parseFloat(techBand.band) / 100, // Simplified bandwidth
96
+ // Network properties
97
+ cellId3: `${cellId}-3G`,
98
+ nwtP1: 20,
99
+ nwtP2: 40,
100
+ pci1: (cellCounter % 504), // Physical Cell ID for LTE
101
+ nwtRS: 450.0,
102
+ nwtBW: 10.0,
103
+ // Other
104
+ other: {
105
+ demoCell: true,
106
+ sector: sectorIndex + 1,
107
+ techBandKey: `${techBand.tech}_${techBand.band}`
108
+ },
109
+ customSubgroup: `Sector-${sectorIndex + 1}`
110
+ });
111
+ cellCounter++;
112
+ });
113
+ });
114
+ console.log(`Generated ${demoCells.length} demo cells across ${AZIMUTHS.length} sectors`);
@@ -5,3 +5,4 @@
5
5
  */
6
6
  export { default as DemoMap } from './DemoMap.svelte';
7
7
  export { demoSites } from './demo-data';
8
+ export { demoCells } from './demo-cells';
@@ -7,3 +7,4 @@
7
7
  export { default as DemoMap } from './DemoMap.svelte';
8
8
  // Demo data
9
9
  export { demoSites } from './demo-data';
10
+ export { demoCells } from './demo-cells';
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Technology-Band Color Mappings
3
+ *
4
+ * Defines fill colors for each technology-band combination
5
+ */
6
+ import type { TechnologyBandKey } from '../types';
7
+ export declare const TECHNOLOGY_BAND_COLORS: Record<TechnologyBandKey, string>;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Technology-Band Color Mappings
3
+ *
4
+ * Defines fill colors for each technology-band combination
5
+ */
6
+ export const TECHNOLOGY_BAND_COLORS = {
7
+ // 2G bands
8
+ '2G_900': '#ffcc99',
9
+ '2G_1800': '#ff9a2e',
10
+ // 4G bands
11
+ '4G_700': '#ffcfff',
12
+ '4G_800': '#ff90ff',
13
+ '4G_900': '#ff66cc',
14
+ '4G_1800': '#ff33cc',
15
+ '4G_2100': '#ccae09',
16
+ '4G_2600': '#903399',
17
+ // 5G bands
18
+ '5G_700': '#00ff00',
19
+ '5G_2100': '#00cc66',
20
+ '5G_3500': '#009933'
21
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Radius Multipliers by Technology-Band
3
+ *
4
+ * Lower frequency = larger coverage area
5
+ * Higher frequency = smaller coverage area
6
+ */
7
+ import type { TechnologyBandKey } from '../types';
8
+ export declare const RADIUS_MULTIPLIER: Record<TechnologyBandKey, number>;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Radius Multipliers by Technology-Band
3
+ *
4
+ * Lower frequency = larger coverage area
5
+ * Higher frequency = smaller coverage area
6
+ */
7
+ export const RADIUS_MULTIPLIER = {
8
+ // 2G bands
9
+ '2G_900': 1.2,
10
+ '2G_1800': 1.0,
11
+ // 4G bands
12
+ '4G_700': 1.5,
13
+ '4G_800': 1.4,
14
+ '4G_900': 1.1,
15
+ '4G_1800': 0.9,
16
+ '4G_2100': 0.8,
17
+ '4G_2600': 0.6,
18
+ // 5G bands
19
+ '5G_700': 1.4,
20
+ '5G_2100': 0.7,
21
+ '5G_3500': 0.5
22
+ };
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Default Status Styles
3
+ *
4
+ * Visual styling for cell sector borders based on status
5
+ */
6
+ import type { CellStatus, CellStatusStyle } from '../types';
7
+ export declare const DEFAULT_STATUS_STYLES: Record<CellStatus, CellStatusStyle>;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Default Status Styles
3
+ *
4
+ * Visual styling for cell sector borders based on status
5
+ */
6
+ export const DEFAULT_STATUS_STYLES = {
7
+ On_Air: {
8
+ lineType: 'solid',
9
+ lineWidth: 2,
10
+ lineColor: '#000000',
11
+ opacity: 1.0,
12
+ dashArray: []
13
+ },
14
+ On_Air_UNDER_CONSTRUCTION: {
15
+ lineType: 'solid',
16
+ lineWidth: 2,
17
+ lineColor: '#FFA500',
18
+ opacity: 0.8,
19
+ dashArray: []
20
+ },
21
+ On_Air_Locked: {
22
+ lineType: 'solid',
23
+ lineWidth: 2,
24
+ lineColor: '#FF0000',
25
+ opacity: 0.9,
26
+ dashArray: []
27
+ },
28
+ RF_Plan_Ready: {
29
+ lineType: 'dashed',
30
+ lineWidth: 2,
31
+ lineColor: '#666666',
32
+ opacity: 0.6,
33
+ dashArray: [5, 5]
34
+ },
35
+ 'Re-Planned_RF_Plan_Ready': {
36
+ lineType: 'dashed',
37
+ lineWidth: 2,
38
+ lineColor: '#888888',
39
+ opacity: 0.5,
40
+ dashArray: [5, 5]
41
+ },
42
+ Tavlati_RF_Plan_Ready: {
43
+ lineType: 'dotted',
44
+ lineWidth: 1,
45
+ lineColor: '#AAAAAA',
46
+ opacity: 0.4,
47
+ dashArray: [2, 4]
48
+ }
49
+ };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Z-Index Layer Ordering by Technology-Band
3
+ *
4
+ * Controls which sectors appear on top when overlapping
5
+ * Higher frequency bands typically rendered on top
6
+ */
7
+ import type { TechnologyBandKey } from '../types';
8
+ export declare const Z_INDEX_BY_BAND: Record<TechnologyBandKey, number>;
9
+ /**
10
+ * Base Z-Index for Mapbox layer ordering
11
+ * Cells should render below sites but above base map features
12
+ */
13
+ export declare const CELL_FILL_Z_INDEX = 100;
14
+ export declare const CELL_LINE_Z_INDEX = 101;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Z-Index Layer Ordering by Technology-Band
3
+ *
4
+ * Controls which sectors appear on top when overlapping
5
+ * Higher frequency bands typically rendered on top
6
+ */
7
+ export const Z_INDEX_BY_BAND = {
8
+ // 2G bands
9
+ '2G_900': 5,
10
+ '2G_1800': 4,
11
+ // 4G bands
12
+ '4G_700': 2,
13
+ '4G_800': 3,
14
+ '4G_900': 4,
15
+ '4G_1800': 8,
16
+ '4G_2100': 9,
17
+ '4G_2600': 11,
18
+ // 5G bands
19
+ '5G_700': 9,
20
+ '5G_2100': 10,
21
+ '5G_3500': 12
22
+ };
23
+ /**
24
+ * Base Z-Index for Mapbox layer ordering
25
+ * Cells should render below sites but above base map features
26
+ */
27
+ export const CELL_FILL_Z_INDEX = 100;
28
+ export const CELL_LINE_Z_INDEX = 101;