@mxtommy/kip 4.8.4 → 4.8.5

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 (64) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/package.json +1 -1
  3. package/plugin/history-series.service.js +637 -0
  4. package/plugin/index.js +1322 -0
  5. package/plugin/kip-series-contract.js +31 -0
  6. package/plugin/openApi.json +855 -0
  7. package/plugin/sqlite-history-storage.service.js +1124 -0
  8. package/public/assets/help-docs/ais-radar.md +261 -0
  9. package/public/assets/help-docs/dashboards.md +1 -1
  10. package/public/assets/help-docs/menu.json +17 -2
  11. package/public/{chunk-Co2wVrD6.js → chunk-0ijGpqkR.js} +1 -1
  12. package/public/{chunk-JhFkJS7i.js → chunk-6MiGh2Ts.js} +1 -1
  13. package/public/{chunk-DIl1k00y.js → chunk-7QXXQf2h.js} +1 -1
  14. package/public/{chunk-CYYBxjrc.js → chunk-B4Wxwb2y.js} +1 -1
  15. package/public/{chunk-q9NoPvcx.js → chunk-BAVmyVwG.js} +1 -1
  16. package/public/{chunk-BfiyH3nV.js → chunk-BOlUTHo6.js} +1 -1
  17. package/public/{chunk-x7L6DXVK.js → chunk-BTv5PhTr.js} +1 -1
  18. package/public/{chunk-BeM64etA.js → chunk-BZG04c3j.js} +1 -1
  19. package/public/{chunk-0z3nIRXw.js → chunk-BaGEtCmz.js} +1 -1
  20. package/public/{chunk-otzyItXL.js → chunk-Bbyk4dOu.js} +1 -1
  21. package/public/{chunk-CCfhzpE8.js → chunk-Be5KcT7R.js} +1 -1
  22. package/public/{chunk-BFpzxIIT.js → chunk-Bp1YVCJL.js} +1 -1
  23. package/public/{chunk-CLs_NL1y.js → chunk-BwYOFdBA.js} +1 -1
  24. package/public/{chunk-D-_-GUVr.js → chunk-Bx77STup.js} +1 -1
  25. package/public/{chunk-COI6IBXH.js → chunk-ByC_hFSP.js} +1 -1
  26. package/public/{chunk-CIGP2YJm.js → chunk-ByFzHU1s.js} +1 -1
  27. package/public/{chunk-CXvWM_vF.js → chunk-BzH86te1.js} +1 -1
  28. package/public/{chunk-CxPx4NZv.js → chunk-C7ax8Sqz.js} +1 -1
  29. package/public/{chunk-CoCQ3DW2.js → chunk-C89yhdsn.js} +1 -1
  30. package/public/{chunk-BTOTKeBo.js → chunk-CJhkckXA.js} +1 -1
  31. package/public/{chunk-BUguZ7cK.js → chunk-CLIWxVhS.js} +1 -1
  32. package/public/{chunk-eQ1pa34Q.js → chunk-CQtqkz1Y.js} +1 -1
  33. package/public/{chunk-BIb-xYiS.js → chunk-CRy9Da7a.js} +1 -1
  34. package/public/{chunk-Do8wqING.js → chunk-CcaPRVAZ.js} +1 -1
  35. package/public/{chunk-BjINKQ03.js → chunk-CdNfAZ0G.js} +1 -1
  36. package/public/{chunk-CLTHuhlN.js → chunk-Cj0AJQ8U.js} +1 -1
  37. package/public/{chunk-B9nVBlGj.js → chunk-CkFpNfxN.js} +1 -1
  38. package/public/{chunk-B09jfNia.js → chunk-Cn9j0-tJ.js} +1 -1
  39. package/public/{chunk-_zRMMvCu.js → chunk-Co8V0LUu.js} +1 -1
  40. package/public/{chunk-ibauGmSP.js → chunk-CteyWXZ_.js} +1 -1
  41. package/public/{chunk-C6b8CVno.js → chunk-CuPmfpgh.js} +1 -1
  42. package/public/{chunk-DmkAKXR1.js → chunk-CwGTKplC.js} +1 -1
  43. package/public/{chunk-DPnbM-aB.js → chunk-CzEDfe2A.js} +1 -1
  44. package/public/{chunk-DUEKoZhd.js → chunk-D1Yncgg5.js} +1 -1
  45. package/public/{chunk-DTN-sa1K.js → chunk-D63LEt5t.js} +1 -1
  46. package/public/{chunk-BpcNrtxJ.js → chunk-DN39qO63.js} +1 -1
  47. package/public/{chunk-szQs8fiq.js → chunk-DNbLx4NZ.js} +1 -1
  48. package/public/{chunk-D1HYfaL_.js → chunk-DRPjASjZ.js} +1 -1
  49. package/public/{chunk-CyVRpGoJ.js → chunk-Dddd8rAh.js} +1 -1
  50. package/public/{chunk-C_OZJltF.js → chunk-DiDkZnhZ.js} +1 -1
  51. package/public/{chunk-CHAFm_nM.js → chunk-DonRL_4T.js} +1 -1
  52. package/public/{chunk-BJ-wyixK.js → chunk-DufX2AHa.js} +1 -1
  53. package/public/{chunk-07zHjmg-.js → chunk-DxS7HN4G.js} +1 -1
  54. package/public/{chunk-BLEZOsfR.js → chunk-Fy40z1B2.js} +1 -1
  55. package/public/{chunk-OeQDZKFO.js → chunk-MO2v041V.js} +1 -1
  56. package/public/{chunk-BuvyF0y5.js → chunk-MakCt36b.js} +1 -1
  57. package/public/{chunk-BZx964-p.js → chunk-TdI_E-cf.js} +1 -1
  58. package/public/{chunk-B0D54iJs.js → chunk-TneLdWrI.js} +1 -1
  59. package/public/{chunk-BN7A4g6c.js → chunk-YZWhRxa9.js} +1 -1
  60. package/public/{chunk-CQMVIDcp.js → chunk-_toW-rHA.js} +1 -1
  61. package/public/{chunk-B0eE4udE.js → chunk-tbyiK3Ur.js} +1 -1
  62. package/public/{chunk-D2953Rfp.js → chunk-urAQA4U_.js} +1 -1
  63. package/public/index.html +1 -1
  64. package/public/{main-YKDNK5VZ.js → main-F7NMHHV4.js} +4 -4
@@ -0,0 +1,261 @@
1
+ ## AIS Radar Widget
2
+
3
+ > **WARNING - FOR SITUATIONAL AWARENESS ONLY**
4
+ > AIS widget data (including collision risk and target information) can be delayed, incomplete, incorrect, or unavailable.
5
+ > This feature provides **no safety guarantee** and must be used **at your own risk**.
6
+ > It is **not** a replacement for proper seamanship, safe navigation practices, collision regulations, visual/radar watchkeeping, or prudent decision making.
7
+
8
+ The AIS Radar widget shows nearby AIS targets around your own-ship position using range rings, target icons, motion vectors, and target details.
9
+
10
+ This page explains:
11
+ - Widget buttons and what they do
12
+ - Widget options and filters
13
+ - Target icon colors, styles and state behaviors
14
+ - Full target icon catalog
15
+
16
+ ## Data Requirements
17
+
18
+ > AIS data must be available in the Signal K server for the widget to function correctly. This usually means using compatible AIS hardware receiver or connecting to a Virtual AIS service over the internet with a Server Connection of type WebSocket.
19
+
20
+ If the KIP Connection option does not include `Subscribe to remote source message such as AIS and DSC targets.`, the widget warns that AIS data is disabled and asks you to enable remote source subscription in Settings / Options.
21
+
22
+ The Derived Data plugin must be installed, enabled and it's Traffic section options must be configured with attention to provide collision risk information.
23
+
24
+ ## Buttons And Actions
25
+
26
+ ### On-widget buttons
27
+
28
+ | Button | Location | What it does |
29
+ |---|---|---|
30
+ | View mode toggle | Top-right | Switches between Course Up and North Up view orientation. |
31
+ | Range + | Right side | Zooms in by selecting a smaller range ring index. |
32
+ | Range - | Right side | Zooms out by selecting a larger range ring index. |
33
+ | Filter list | Top-left | Opens target filtering menu (category and vessel-type filters). |
34
+ | Collision shortcut | Left side under filter | Toggles Show only collision-risk targets mode when risk data is available. |
35
+
36
+ > Collision-risk shortcut button visibility depends on incoming closest-approach data. If no target provides collisionRiskRating, the collision quick-filter button is not shown.
37
+
38
+ ### Target interaction
39
+
40
+ | Action | Result |
41
+ |---|---|
42
+ | Tap or click one visible target | Opens target detail dialog directly. |
43
+ | Tap or click where multiple targets overlap | Opens a target picker menu so you can select which target to inspect. |
44
+ | Tap or click background | Clears selection and closes target menu. |
45
+
46
+ ### Target detail dialog
47
+
48
+ The dialog includes information based on target type such as: COG, SOG, HDG, ROT, CPA/TCPA, destination, IDs, position, off-position and freshness
49
+
50
+ ## How To Read Radar Targets
51
+
52
+ ---
53
+
54
+ Most AIS users will want to understand this first: each target combines a base icon and extra visual cues.
55
+
56
+ 1. **Icon shape** tells you what kind of target it is.
57
+ 2. **State look** tells you if data is fresh and reliable.
58
+ 3. **Risk glow** tells you if attention is needed now.
59
+ 4. **Motion vector** tells you where the target is going.
60
+
61
+ ### Target states explanation
62
+
63
+ Supported statuses:
64
+ - Confirmed
65
+ - Unconfirmed
66
+ - Lost
67
+ - Remove
68
+
69
+ What that means on screen:
70
+ - **Confirmed**: normal target look.
71
+ - **Unconfirmed**: same icon shape, but looks faded/lower confidence.
72
+ - **Lost**: same icon shape, also shown as faded/lower confidence.
73
+ - **Remove**: target disappears from the radar.
74
+
75
+ Important behavior note:
76
+ - **Lost** uses the same visual styling family as **unconfirmed**.
77
+
78
+ ### State cue rules (opacity)
79
+
80
+ - **Unconfirmed or lost**: icon appears faded (have less opacity than confirmed targets).
81
+ - **Confirmed**: icon appears solid.
82
+
83
+ ### Risk cue rules (glow)
84
+
85
+ Collision risk glow appears only on **moving, confirmed** targets:
86
+ - **Red glow**: higher risk
87
+ - **Yellow glow**: lower risk
88
+ - **No glow**: no current risk emphasis
89
+
90
+ ### Anchored or moored nav state (transparent / no fill color)
91
+
92
+ Anchored/moored targets are shown as **stationary vessel targets**.
93
+
94
+ Important:
95
+ - There is **no special anchor badge/icon** added on top of the vessel symbol.
96
+
97
+ What to look for:
98
+ - The vessel icon is still present (normal vessel type icon).
99
+ - When a vessel is **confirmed** and reports **anchored/moored** state, the icon fill color is rendered **transparent** (the icon only has an outline).
100
+ - It usually has **no motion vector**.
101
+ - It typically has **no collision glow** unless movement/risk data says otherwise.
102
+
103
+ Important limitation:
104
+ - Anchored/moored is a **reported nav state**. Some vessels do not report it consistently, some never do.
105
+ - A vessel can be operationally moored/anchored but still appear as a normal confirmed vessel if that state is not transmitted.
106
+ - Anchored/moored nav state is commonly reported by commercial vessels (cargo, tanker, passenger ship), but it is not typical for other types of vessels.
107
+
108
+
109
+ How to interpret in practice:
110
+ - If nav state is missing, use movement clues: a persistent no/very short vector and stable position usually suggest moored/anchored behavior.
111
+
112
+ ### Own-ship vector rules
113
+
114
+ Own ship shows an orange dashed vector when own COG and SOG are available and own-ship icon display is enabled.
115
+
116
+ ## Widget Options
117
+
118
+ ---
119
+
120
+ After you understand the visual cues above, use these options to tune what you see.
121
+
122
+ The widget is configured in the Options dialog under the Display and Filter tabs.
123
+
124
+ ### Display and range options
125
+
126
+ | Option | Values | Effect |
127
+ |---|---|---|
128
+ | View Mode | North Up, Course Up | Controls map orientation and target rotation behavior. |
129
+ | Fully Visible Rings Range | 1, 3, 6, 12, 24, 48 miles | Sets active range index for ring scale. |
130
+ | Show own ship icon | On or Off | Shows or hides the own-ship center icon. |
131
+
132
+ ### Vector and target visibility options
133
+
134
+ | Option | Values | Effect |
135
+ |---|---|---|
136
+ | Plot target COG vector | On or Off | Draws target motion vectors for moving vessel-like targets. |
137
+ | COG plot length (minutes) | Numeric | Sets projection length for motion vectors (of Plot target COG vector). |
138
+ | Show unconfirmed targets | On or Off | Includes or hides unconfirmed targets. |
139
+ | Show lost targets | On or Off | Includes or hides lost targets. |
140
+
141
+ ### Filter tab options
142
+
143
+ | Filter | Effect |
144
+ |---|---|
145
+ | Anchored/Moored | Hides stationary vessel-like targets (anchored or moored). |
146
+ | All AtoN | Hides all aids-to-navigation targets. |
147
+ | All but SAR | Hides every target except SAR targets. |
148
+ | All Vessels | Hides all vessel-like targets. |
149
+ | Vessel Type list | Hides selected vessel icon categories only. |
150
+
151
+ ### Runtime quick filter note
152
+
153
+ The collision quick-filter button toggles a noCollisionRisk runtime filter in the widget. This option is intentionally runtime-only in the widget UI and is not exposed as a checkbox in the Filter tab.
154
+
155
+ ## Full Target Icon Catalog
156
+
157
+ ---
158
+
159
+ ### Icon Selection Rules
160
+
161
+ Icon selection uses target type and AIS metadata:
162
+ - Vessel and SAR: selected from AIS ship type range mapping
163
+ - AtoN: selected from AtoN type id mapping (cardinal, lateral, special, danger/safe, other)
164
+ - Basestation: dedicated basestation icon
165
+ - Distress beacons: MMSI prefixes map to SART, MOB, EPIRB beacon icons
166
+
167
+ Distress beacon MMSI prefixes:
168
+ - 970 -> SART icon
169
+ - 972 -> MOB icon
170
+ - 974 -> EPIRB icon
171
+
172
+ ### Vessel icons
173
+
174
+
175
+ | Key | Preview | Typical use |
176
+ |---|---|---|
177
+ | vessel/fishing | ![vessel fishing](assets/svg/vessel/fishing.svg) | AIS ship type 30 |
178
+ | vessel/diving | ![vessel diving](assets/svg/vessel/diving-ops.svg) | AIS ship type 34 |
179
+ | vessel/military | ![vessel military](assets/svg/vessel/military-ops.svg) | AIS ship type 35 |
180
+ | vessel/sailing | ![vessel sailing](assets/svg/vessel/sailing.svg) | AIS ship type 36 |
181
+ | vessel/pleasurecraft | ![vessel pleasurecraft](assets/svg/vessel/pleasurecraft.svg) | AIS ship type 37 |
182
+ | vessel/highspeed | ![vessel highspeed](assets/svg/vessel/highspeed.svg) | AIS ship type 20-29, 40-49 |
183
+ | vessel/pilot | ![vessel pilot](assets/svg/vessel/pilot.svg) | AIS ship type 50 |
184
+ | vessel/sar | ![vessel sar](assets/svg/vessel/sar.svg) | SAR (Search And Rescue) target type and AIS ship type 51 |
185
+ | vessel/tug | ![vessel tug](assets/svg/vessel/tug.svg) | AIS ship type 31-33, 52-54, 58-59 |
186
+ | vessel/law | ![vessel law](assets/svg/vessel/law-enforcement.svg) | AIS ship type 55 |
187
+ | vessel/passenger | ![vessel passenger](assets/svg/vessel/passenger.svg) | AIS ship type 60-69 |
188
+ | vessel/cargo | ![vessel cargo](assets/svg/vessel/cargo.svg) | AIS ship type 70-79 |
189
+ | vessel/tanker | ![vessel tanker](assets/svg/vessel/tanker.svg) | AIS ship type 80-89 |
190
+ | vessel/other | ![vessel other](assets/svg/vessel/other.svg) | Generic fallback and multiple reserved ship-type ranges |
191
+ | vessel/unknown | ![vessel unknown](assets/svg/vessel/unknown.svg) | Unknown vessel fallback by type |
192
+ | vessel/spare | ![vessel spare](assets/svg/vessel/other.svg) | Spare category in filter set (shares other.svg) |
193
+
194
+ ### Aid to Navigation (AtoN) icons
195
+
196
+ #### Cardinal
197
+
198
+ | Key | Preview | Description |
199
+ |---|---|---|
200
+ | aton/north-beacon | ![aton north beacon](assets/svg/AtoN/cardinal/north_beacon.svg) | Cardinal north beacon target. |
201
+ | aton/north-mark | ![aton north mark](assets/svg/AtoN/cardinal/north_mark.svg) | Cardinal north mark target. |
202
+ | aton/east-beacon | ![aton east beacon](assets/svg/AtoN/cardinal/east_beacon.svg) | Cardinal east beacon target. |
203
+ | aton/east-mark | ![aton east mark](assets/svg/AtoN/cardinal/east_mark.svg) | Cardinal east mark target. |
204
+ | aton/south-beacon | ![aton south beacon](assets/svg/AtoN/cardinal/south_beacon.svg) | Cardinal south beacon target. |
205
+ | aton/south-mark | ![aton south mark](assets/svg/AtoN/cardinal/south_mark.svg) | Cardinal south mark target. |
206
+ | aton/west-beacon | ![aton west beacon](assets/svg/AtoN/cardinal/west_beacon.svg) | Cardinal west beacon target. |
207
+ | aton/west-mark | ![aton west mark](assets/svg/AtoN/cardinal/west_mark.svg) | Cardinal west mark target. |
208
+
209
+ #### Lateral
210
+
211
+ | Key | Preview | Description |
212
+ |---|---|---|
213
+ | aton/port-beacon | ![aton port beacon](assets/svg/AtoN/lateral/port_beacon.svg) | Port-hand lateral beacon target. |
214
+ | aton/port-mark | ![aton port mark](assets/svg/AtoN/lateral/port_mark.svg) | Port-hand lateral mark target. |
215
+ | aton/starboard-beacon | ![aton starboard beacon](assets/svg/AtoN/lateral/starboard_beacon.svg) | Starboard-hand lateral beacon target. |
216
+ | aton/starboard-mark | ![aton starboard mark](assets/svg/AtoN/lateral/starboard_mark.svg) | Starboard-hand lateral mark target. |
217
+ | aton/port-preferred-beacon | ![aton port preferred beacon](assets/svg/AtoN/lateral/port_prefered_beacon.svg) | Preferred-channel-to-port beacon target. |
218
+ | aton/port-preferred-mark | ![aton port preferred mark](assets/svg/AtoN/lateral/port_prefered_mark.svg) | Preferred-channel-to-port mark target. |
219
+ | aton/starboard-preferred-beacon | ![aton starboard preferred beacon](assets/svg/AtoN/lateral/starboard_prefered_beacon.svg) | Preferred-channel-to-starboard beacon target. |
220
+ | aton/starboard-preferred-mark | ![aton starboard preferred mark](assets/svg/AtoN/lateral/starboard_prefered_mark.svg) | Preferred-channel-to-starboard mark target. |
221
+
222
+ #### Special and danger/safe
223
+
224
+ | Key | Preview | Description |
225
+ |---|---|---|
226
+ | aton/special-beacon | ![aton special beacon](assets/svg/AtoN/special/special_beacon.svg) | Special-purpose beacon target. |
227
+ | aton/special-mark | ![aton special mark](assets/svg/AtoN/special/special_mark.svg) | Special-purpose mark target. |
228
+ | aton/isolateddanger-beacon | ![aton isolated danger beacon](assets/svg/AtoN/dangerSafe/isolateddanger_beacon.svg) | Isolated danger beacon target. |
229
+ | aton/isolateddanger-mark | ![aton isolated danger mark](assets/svg/AtoN/dangerSafe/isolateddanger_mark.svg) | Isolated danger mark target. |
230
+ | aton/safewater-beacon | ![aton safewater beacon](assets/svg/AtoN/dangerSafe/safewater_beacon_.svg) | Safe-water beacon target. |
231
+ | aton/safewater-mark | ![aton safewater mark](assets/svg/AtoN/dangerSafe/safewater_mark.svg) | Safe-water mark target. |
232
+
233
+ #### Other and infrastructure
234
+
235
+ | Key | Preview | Description |
236
+ |---|---|---|
237
+ | aton/other | ![aton other](assets/svg/AtoN/other/aton.svg) | Generic AtoN fallback target. |
238
+ | aton/basestation | ![aton basestation](assets/svg/AtoN/other/basestation.svg) | Shore basestation target symbol. |
239
+ | aton/unknown | ![aton unknown](assets/svg/AtoN/other/unknown.svg) | Unknown AtoN fallback target. |
240
+
241
+ ### Distress beacon icons
242
+
243
+ | Key | Preview | MMSI prefix | Description |
244
+ |---|---|---|---|
245
+ | beacon/sart | ![beacon sart](assets/svg/sar-distress-device/sart-eprib-mob.svg) | 970 | Search and rescue transponder beacon target. |
246
+ | beacon/mob | ![beacon mob](assets/svg/sar-distress-device/sart-eprib-mob.svg) | 972 | Man overboard beacon target. |
247
+ | beacon/epirb | ![beacon epirb](assets/svg/sar-distress-device/sart-eprib-mob.svg) | 974 | Emergency position-indicating beacon target. |
248
+
249
+ ### Own-ship icon
250
+
251
+ The center own-ship icon uses its own dedicated asset and is not part of remote target classification.
252
+
253
+ | Key | Preview |
254
+ |---|---|
255
+ | vessel/self | ![vessel self](assets/svg/vessel/self.svg) |
256
+
257
+ ## See Also
258
+
259
+ - [Managing Dashboards](#/help/dashboards.md)
260
+ - [Data Inspector](#/help/datainspector.md)
261
+ - [Chartplotter Mode](#/help/chartplotter.md)
@@ -87,7 +87,7 @@ KIP widgets turn Signal K data into readable visuals and controls. Available wid
87
87
  - **Freeboard-SK** – Adds the Freeboard-SK chart plotter as a widget with automatic sign-in.
88
88
  - **Autopilot Head** – Typical autopilot controls for compatible Signal K Autopilot devices.
89
89
  - **Realtime Data Chart** – Visualizes data on a real-time chart with actuals, averages, and min/max.
90
- - **AIS Radar**: Display AIS targets with range rings, interactive target details, and quick zoom and filtering controls.
90
+ - **AIS Radar**: Display AIS targets with range rings, interactive target details, and quick zoom and filtering controls. See [AIS Radar Widget](#/help/ais-radar.md).
91
91
  - **Embed Webpage Viewer** – Embeds external web apps (Grafana, Node-RED, etc.) into your dashboard.
92
92
  - **Racesteer** – Race steering display fusing polar performance data with live conditions for optimal tactics.
93
93
  - **Racer - Start Line Insight** – Set and adjust start line ends, see distance, favored end, and line bias; integrates with Freeboard SK.
@@ -2,11 +2,26 @@
2
2
  { "title": "The basics", "file": "welcome.md" },
3
3
  { "title": "Login & Configurations", "file": "configuration.md" },
4
4
  { "title": "Dashboards and Layout", "file": "dashboards.md" },
5
- { "title": "Data Inspector", "file": "datainspector.md" },
6
- { "title": "Chartplotter Mode", "file": "chartplotter.md" },
5
+ {
6
+ "title": "Widgets",
7
+ "items": [
8
+ {
9
+ "title": "AIS Radar",
10
+ "file": "ais-radar.md"
11
+ }
12
+ ]
13
+ },
14
+ {
15
+ "title": "Chartplotter Mode",
16
+ "file": "chartplotter.md"
17
+ },
7
18
  { "title": "Zones, Notifications and Highlights", "file": "zones.md" },
8
19
  { "title": "Digital Switching and PUT", "file": "putcontrols.md" },
9
20
  { "title": "Historical Widget Data", "file": "time-series.md" },
21
+ {
22
+ "title": "Data Inspector",
23
+ "file": "datainspector.md"
24
+ },
10
25
  {
11
26
  "title": "Integrations",
12
27
  "items": [
@@ -1 +1 @@
1
- import {a as a$1}from'./chunk-ibauGmSP.js';import {d1 as Hj,w,du as p,a as G,H as Dr,$ as $j,v as vt,F as Fa,dn as ge,J as JD,_ as _w,cp as Uh,M as Mw,e as EE,d as ig,f as eg,K as Kw,g as qw,b_ as Gh,ci as dl,T as TT,cj as fl,dP as pp}from'./main-YKDNK5VZ.js';var W=["plainIframe"];function M(n,e){if(n&1&&Uh(0,"iframe",1,0),n&2){let t=qw();Gh("src",t.widgetUrl(),pp);}}function N(n,e){n&1&&(dl(0,"div",2)(1,"h2"),TT(2,"Empty or bad URL"),fl(),dl(3,"p"),TT(4," IMPORTANT: cross-domain security rules (CORS) apply to this widget. "),fl(),dl(5,"p"),TT(6,"Typically, you can load Grafana graphs, Signal K apps or other related tools. "),fl()());}var O=class n{id=Hj.required();type=Hj.required();theme=Hj.required();runtime=w(p);_dashboard=w(G);_sanitizer=w(Dr);static DEFAULT_CONFIG={widgetUrl:void 0,allowInput:false};iframe=$j.required("plainIframe");widgetUrl=vt(null);displayTransparentOverlay=vt("block");constructor(){Fa(()=>{let e=this.runtime.options(),t=this._dashboard.isDashboardStatic();e&&ge(()=>{t?this.displayTransparentOverlay.set(e.allowInput?"none":"block"):this.displayTransparentOverlay.set("block");});}),Fa(()=>{let e=this.runtime.options()?.widgetUrl;this.widgetUrl.set(this.resolveUrl(e));}),window.addEventListener("message",this.handleIframeGesture);}ngAfterViewInit(){if(this.iframe()){this.iframe().nativeElement.onload=()=>this.injectSwipeScript();try{let e=this.iframe().nativeElement.contentDocument;e&&(e.readyState==="complete"||e.readyState==="interactive")&&this.injectSwipeScript();}catch(e){}}}ngOnDestroy(){window.removeEventListener("message",this.handleIframeGesture),this.iframe()&&(this.iframe().nativeElement.onload=null);try{let e=this.iframe()?.nativeElement.contentDocument;if(e){let t=`kip-gesture-inject-${this.id()}`,i=e.getElementById(t);i&&i.parentNode&&i.parentNode.removeChild(i);}}catch(e){}}handleIframeGesture=e=>{if(!e.data)return;let t=e.data?.eventData?.instanceId||e.data?.keyEventData?.instanceId;if(!(!t||t!==this.id())){if(e.data.gesture)switch(e.data.gesture){case "swipeup":this._dashboard.navigateToPreviousDashboard();break;case "swipedown":this._dashboard.navigateToNextDashboard();break;case "swipeleft":{let i=new Event("openLeftSidenav",{bubbles:true,cancelable:true});window.document.dispatchEvent(i);break}case "swiperight":{let i=new Event("openRightSidenav",{bubbles:true,cancelable:true});window.document.dispatchEvent(i);break}}if(e.data.type==="keydown"&&e.data.keyEventData){let{key:i,ctrlKey:l,shiftKey:r}=e.data.keyEventData,x=new KeyboardEvent("keydown",{key:i,ctrlKey:l,shiftKey:r,bubbles:true,cancelable:true});document.dispatchEvent(x);}}};injectSwipeScript(){let e=this.iframe().nativeElement.contentWindow,t=this.iframe().nativeElement.contentDocument;if(!t||!e){console.error("[WidgetIframe] Iframe contentDocument or contentWindow is undefined. Possible cross-origin issue or iframe not fully loaded.");return}try{let i=`kip-gesture-inject-${this.id()}`;if(t.getElementById(i))return;let l=a$1({instanceId:this.id()}),r=t.createElement("script");r.id=i,r.textContent=l,t.body.appendChild(r);}catch(i){console.warn("[WidgetIframe] Failed to inject swipe script into iframe:",i);}}isValidProtocol(e){try{let t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"}catch(t){return console.warn(`[Embed Widget] Invalid Url: ${e}, Error: ${t}`),false}}resolveUrl(e){if(!e)return null;try{let t=new URL(e,window.location.origin);return this.isValidProtocol(t.href)?this._sanitizer.bypassSecurityTrustResourceUrl(t.href):null}catch(t){return console.warn(`[Embed Widget] Can't resolve Url: ${e}, Error: ${t}`),null}}static \u0275fac=function(t){return new(t||n)};static \u0275cmp=JD({type:n,selectors:[["widget-iframe"]],viewQuery:function(t,i){t&1&&eg(i.iframe,W,5),t&2&&Kw();},inputs:{id:[1,"id"],type:[1,"type"],theme:[1,"theme"]},decls:3,vars:3,consts:[["plainIframe",""],["width","100%","height","100%","frameborder","0",1,"widgetIframe",3,"src"],[2,"padding","15px"],[1,"widgetOverlay"]],template:function(t,i){t&1&&(_w(0,M,2,1,"iframe",1)(1,N,7,0,"div",2),Uh(2,"div",3)),t&2&&(Mw(i.widgetUrl()?0:1),EE(2),ig("display",i.displayTransparentOverlay()));},styles:["[_nghost-%COMP%]{overflow:hidden}.widgetIframe[_ngcontent-%COMP%]{background-color:#fff;border-radius:var(--mat-card-elevated-container-shape, var(--mat-sys-corner-medium))}.widgetOverlay[_ngcontent-%COMP%]{position:absolute;width:100%;height:100%;right:0;bottom:0;color:transparent}"]})};export{O as WidgetIframeComponent};
1
+ import {a as a$1}from'./chunk-CteyWXZ_.js';import {d1 as Hj,w,du as p,a as G,H as Dr,$ as $j,v as vt,F as Fa,dn as ge,J as JD,_ as _w,cp as Uh,M as Mw,e as EE,d as ig,f as eg,K as Kw,g as qw,b_ as Gh,ci as dl,T as TT,cj as fl,dP as pp}from'./main-F7NMHHV4.js';var W=["plainIframe"];function M(n,e){if(n&1&&Uh(0,"iframe",1,0),n&2){let t=qw();Gh("src",t.widgetUrl(),pp);}}function N(n,e){n&1&&(dl(0,"div",2)(1,"h2"),TT(2,"Empty or bad URL"),fl(),dl(3,"p"),TT(4," IMPORTANT: cross-domain security rules (CORS) apply to this widget. "),fl(),dl(5,"p"),TT(6,"Typically, you can load Grafana graphs, Signal K apps or other related tools. "),fl()());}var O=class n{id=Hj.required();type=Hj.required();theme=Hj.required();runtime=w(p);_dashboard=w(G);_sanitizer=w(Dr);static DEFAULT_CONFIG={widgetUrl:void 0,allowInput:false};iframe=$j.required("plainIframe");widgetUrl=vt(null);displayTransparentOverlay=vt("block");constructor(){Fa(()=>{let e=this.runtime.options(),t=this._dashboard.isDashboardStatic();e&&ge(()=>{t?this.displayTransparentOverlay.set(e.allowInput?"none":"block"):this.displayTransparentOverlay.set("block");});}),Fa(()=>{let e=this.runtime.options()?.widgetUrl;this.widgetUrl.set(this.resolveUrl(e));}),window.addEventListener("message",this.handleIframeGesture);}ngAfterViewInit(){if(this.iframe()){this.iframe().nativeElement.onload=()=>this.injectSwipeScript();try{let e=this.iframe().nativeElement.contentDocument;e&&(e.readyState==="complete"||e.readyState==="interactive")&&this.injectSwipeScript();}catch(e){}}}ngOnDestroy(){window.removeEventListener("message",this.handleIframeGesture),this.iframe()&&(this.iframe().nativeElement.onload=null);try{let e=this.iframe()?.nativeElement.contentDocument;if(e){let t=`kip-gesture-inject-${this.id()}`,i=e.getElementById(t);i&&i.parentNode&&i.parentNode.removeChild(i);}}catch(e){}}handleIframeGesture=e=>{if(!e.data)return;let t=e.data?.eventData?.instanceId||e.data?.keyEventData?.instanceId;if(!(!t||t!==this.id())){if(e.data.gesture)switch(e.data.gesture){case "swipeup":this._dashboard.navigateToPreviousDashboard();break;case "swipedown":this._dashboard.navigateToNextDashboard();break;case "swipeleft":{let i=new Event("openLeftSidenav",{bubbles:true,cancelable:true});window.document.dispatchEvent(i);break}case "swiperight":{let i=new Event("openRightSidenav",{bubbles:true,cancelable:true});window.document.dispatchEvent(i);break}}if(e.data.type==="keydown"&&e.data.keyEventData){let{key:i,ctrlKey:l,shiftKey:r}=e.data.keyEventData,x=new KeyboardEvent("keydown",{key:i,ctrlKey:l,shiftKey:r,bubbles:true,cancelable:true});document.dispatchEvent(x);}}};injectSwipeScript(){let e=this.iframe().nativeElement.contentWindow,t=this.iframe().nativeElement.contentDocument;if(!t||!e){console.error("[WidgetIframe] Iframe contentDocument or contentWindow is undefined. Possible cross-origin issue or iframe not fully loaded.");return}try{let i=`kip-gesture-inject-${this.id()}`;if(t.getElementById(i))return;let l=a$1({instanceId:this.id()}),r=t.createElement("script");r.id=i,r.textContent=l,t.body.appendChild(r);}catch(i){console.warn("[WidgetIframe] Failed to inject swipe script into iframe:",i);}}isValidProtocol(e){try{let t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"}catch(t){return console.warn(`[Embed Widget] Invalid Url: ${e}, Error: ${t}`),false}}resolveUrl(e){if(!e)return null;try{let t=new URL(e,window.location.origin);return this.isValidProtocol(t.href)?this._sanitizer.bypassSecurityTrustResourceUrl(t.href):null}catch(t){return console.warn(`[Embed Widget] Can't resolve Url: ${e}, Error: ${t}`),null}}static \u0275fac=function(t){return new(t||n)};static \u0275cmp=JD({type:n,selectors:[["widget-iframe"]],viewQuery:function(t,i){t&1&&eg(i.iframe,W,5),t&2&&Kw();},inputs:{id:[1,"id"],type:[1,"type"],theme:[1,"theme"]},decls:3,vars:3,consts:[["plainIframe",""],["width","100%","height","100%","frameborder","0",1,"widgetIframe",3,"src"],[2,"padding","15px"],[1,"widgetOverlay"]],template:function(t,i){t&1&&(_w(0,M,2,1,"iframe",1)(1,N,7,0,"div",2),Uh(2,"div",3)),t&2&&(Mw(i.widgetUrl()?0:1),EE(2),ig("display",i.displayTransparentOverlay()));},styles:["[_nghost-%COMP%]{overflow:hidden}.widgetIframe[_ngcontent-%COMP%]{background-color:#fff;border-radius:var(--mat-card-elevated-container-shape, var(--mat-sys-corner-medium))}.widgetOverlay[_ngcontent-%COMP%]{position:absolute;width:100%;height:100%;right:0;bottom:0;color:transparent}"]})};export{O as WidgetIframeComponent};
@@ -1 +1 @@
1
- import {d1 as Hj,w,a as G,G as Gi,J as JD,bh as xp,bP as si,P as Pi,_ as _w,u as ul,e as EE,M as Mw,T as TT,h as Fw,c as $h,k as Qh,l as ud,g as qw,m as dd}from'./main-YKDNK5VZ.js';function y(n,k){if(n&1){let r=Fw();Pi(0,"h3"),TT(1,"Getting Started"),ul(),Pi(2,"p"),TT(3,"Welcome to KIP! Here are some basic gestures to help you navigate the application. Access the "),Pi(4,"a",1),TT(5,"KIP Help"),ul(),TT(6," documentation to learn more about KIP."),ul(),Pi(7,"table",2)(8,"thead")(9,"tr")(10,"th"),TT(11,"Actions"),ul(),Pi(12,"th"),TT(13,"Touch"),ul(),Pi(14,"th"),TT(15,"Mouse"),ul(),Pi(16,"th"),TT(17,"Keyboard Shortcuts"),ul()()(),Pi(18,"tbody")(19,"tr")(20,"td"),TT(21,"Open Actions menu"),ul(),Pi(22,"td"),TT(23,"Swipe left"),ul(),Pi(24,"td"),TT(25,"Click, drag left, and release"),ul(),Pi(26,"td")(27,"kbd"),TT(28,"Shift"),ul(),TT(29," + "),Pi(30,"kbd"),TT(31,"Ctrl"),ul(),TT(32," + "),Pi(33,"kbd",3),TT(34,"\u2190"),ul(),TT(35," (Left Arrow)"),ul()(),Pi(36,"tr")(37,"td"),TT(38,"Open Notification menu"),ul(),Pi(39,"td"),TT(40,"Swipe right"),ul(),Pi(41,"td"),TT(42,"Click, drag right, and release"),ul(),Pi(43,"td")(44,"kbd"),TT(45,"Shift"),ul(),TT(46," + "),Pi(47,"kbd"),TT(48,"Ctrl"),ul(),TT(49," + "),Pi(50,"kbd",3),TT(51,"\u2192"),ul(),TT(52," (Right Arrow)"),ul()(),Pi(53,"tr")(54,"td"),TT(55,"Cycle through dashboards"),ul(),Pi(56,"td"),TT(57,"Swipe up/down"),ul(),Pi(58,"td"),TT(59,"Click, drag up/down, and release"),ul(),Pi(60,"td")(61,"kbd"),TT(62,"Shift"),ul(),TT(63," + "),Pi(64,"kbd"),TT(65,"Ctrl"),ul(),TT(66," + "),Pi(67,"kbd",3),TT(68,"\u2191"),ul(),TT(69,"/"),Pi(70,"kbd",3),TT(71,"\u2193"),ul(),TT(72," (Up/Down Arrow)"),ul()(),Pi(73,"tr")(74,"td"),TT(75,"Toggle Fullscreen"),ul(),Pi(76,"td"),TT(77,"N/A"),ul(),Pi(78,"td"),TT(79,"N/A"),ul(),Pi(80,"td")(81,"kbd"),TT(82,"Shift"),ul(),TT(83," + "),Pi(84,"kbd"),TT(85,"Ctrl"),ul(),TT(86," + "),Pi(87,"kbd"),TT(88,"F"),ul()()(),Pi(89,"tr")(90,"td"),TT(91,"Toggle Night mode"),ul(),Pi(92,"td"),TT(93,"N/A"),ul(),Pi(94,"td"),TT(95,"N/A"),ul(),Pi(96,"td")(97,"kbd"),TT(98,"Shift"),ul(),TT(99," + "),Pi(100,"kbd"),TT(101,"Ctrl"),ul(),TT(102," + "),Pi(103,"kbd"),TT(104,"N"),ul()()(),Pi(105,"tr")(106,"td"),TT(107,"Toggle dashboard edit mode"),ul(),Pi(108,"td"),TT(109,"N/A"),ul(),Pi(110,"td"),TT(111,"N/A"),ul(),Pi(112,"td")(113,"kbd"),TT(114,"Shift"),ul(),TT(115," + "),Pi(116,"kbd"),TT(117,"Ctrl"),ul(),TT(118," + "),Pi(119,"kbd"),TT(120,"E"),ul()()()()(),Pi(121,"i"),TT(122,"Note that the words Touch and Tap are synonymous with mouse Click."),ul(),$h(123,"br")(124,"br"),Pi(125,"h3"),TT(126,"Login to Signal K"),ul(),Pi(127,"p"),TT(128," The first step is to configure Signal K server authentication ("),Pi(129,"i"),TT(130,"a pre-existing Signal K server username and password is required"),ul(),TT(131,"). Go to KIP's Connectivity options, toggle "),Pi(132,"strong"),TT(133,"Login to server"),ul(),TT(134,", enter your Signal K credentials and click "),Pi(135,"strong"),TT(136,"Sign in"),ul(),TT(137,". Once completed, click the upper right X button to get back to this dashboard ("),Pi(138,"a",4),TT(139,"Connectivity options"),ul(),TT(140,"). "),ul(),Pi(141,"ul")(142,"li"),TT(143," If you don\u2019t have a Signal K account, ask your captain or access the Signal K Admin Settings / Users page and create a user. "),ul(),Pi(144,"li"),TT(145," If you see an error, double-check your username and password, and make sure your device is on the same network as your Signal K server. "),ul()(),Pi(146,"h3"),TT(147,"Option 1: Load Demonstration Dashboards"),ul(),Pi(148,"p"),TT(149," Try the sample dashboards using data from your server: "),$h(150,"br"),Pi(151,"button",5),Qh("click",function(){ud(r);let l=qw();return dd(l.loadDemoConfig())}),TT(152,"Load Demo"),ul()(),Pi(153,"h3"),TT(154,"Option 2: Create Your Own Layout"),ul(),Pi(155,"p"),TT(156,' The text you are reading is actually a widget that fills half of the dashboard. The screen is split in halves at the middle. This mode is called Chartplotter mode. It can later be turned off in Settings / Options / Display. Dashboards are "Locked" by default to prevent accidental modifications. To edit a dashboard, swipe left and hit the bottom unlock menu button. Note that you can add and manage dashboards using the Settings button from the Actions menu. '),ul(),Pi(157,"p")(158,"strong"),TT(159,"Try editing the Dashboard now to receive further instructions!"),ul()();}}function v(n,k){n&1&&(Pi(0,"h2"),TT(1,"Changing Layouts"),ul(),TT(2," Follow these simple steps to learn how to change your dashboard layout: "),Pi(3,"ol")(4,"li"),TT(5,"Resize this Tutorial widget using the now visible dashed borders or corners arrows. Resize it so it does not take up all the screen. You need free space in your dashboard to add more widgets. You can delete this Tutorial widget later when you are done with the instructions."),ul(),Pi(6,"li"),TT(7,"Touch & Hold or Click & Hold in an empty area to open the Add Widget selection panel."),ul(),Pi(8,"li"),TT(9,"Choose a widget from the selection panel to add it to the dashboard."),ul()(),Pi(10,"h3"),TT(11,"Possible widget operations"),ul(),Pi(12,"ul")(13,"li")(14,"strong"),TT(15,"Touch and drag"),ul(),TT(16," to move widgets"),ul(),Pi(17,"li")(18,"strong"),TT(19,"Drag corners and sides"),ul(),TT(20," to resize widgets"),ul(),Pi(21,"li")(22,"strong"),TT(23,"Double Tap"),ul(),TT(24," on a widget to configure it"),ul(),Pi(25,"li")(26,"strong"),TT(27,"Press and Hold"),ul(),TT(28," on a widget to delete or duplicate widgets"),ul()(),Pi(29,"h2"),TT(30,"Exiting dashboard edit mode"),ul(),Pi(31,"p"),TT(32,"Use the Save or Cancel buttons in the lower right corner to either persist your changes or revert changes."),ul(),Pi(33,"h2"),TT(34,"Adding more dashboards"),ul(),Pi(35,"p"),TT(36,"Swipe left and hit the Dashboards button. From this page you can add, rename, order, delete, and duplicate entire dashboards."),ul());}var N=(()=>{class n{id=Hj.required();type=Hj.required();theme=Hj.required();static DEFAULT_CONFIG={filterSelfPaths:true};dashboard=w(G);settings=w(Gi);loadDemoConfig(){this.settings.loadDemoConfig();}static \u0275fac=function(o){return new(o||n)};static \u0275cmp=JD({type:n,selectors:[["widget-tutorial"]],inputs:{id:[1,"id"],type:[1,"type"],theme:[1,"theme"]},decls:3,vars:1,consts:[[1,"tutorial-container"],["routerLink","/help"],[1,"nav-table"],[2,"font-size","x-large"],["routerLink","/options"],["mat-flat-button","",2,"margin-left","15px",3,"click"]],template:function(o,l){o&1&&(Pi(0,"div",0),_w(1,y,160,0)(2,v,37,0),ul()),o&2&&(EE(),Mw(l.dashboard.isDashboardStatic()?1:2));},dependencies:[xp,si],styles:[".tutorial-container[_ngcontent-%COMP%]{position:absolute;top:0;left:0;display:block;height:100%;width:100%;overflow-y:auto}.tutorial-container[_ngcontent-%COMP%]{padding:0 15px}.nav-table[_ngcontent-%COMP%]{width:100%;border-collapse:collapse;margin-bottom:2em}.nav-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%], .nav-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%]{border:1px solid #bbb;padding:.5em 1em;text-align:center}.nav-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%]{background:#ddd;color:#222;font-weight:700}.nav-table[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:nth-child(2n){background:#242424}.warning[_ngcontent-%COMP%]{color:#b71c1c}.button-group[_ngcontent-%COMP%]{margin-top:2em;display:flex;gap:20px}a[_ngcontent-%COMP%]:visited, a[_ngcontent-%COMP%]:link{color:var(--kip-blue-color)}"]})}return n})();export{N as WidgetTutorialComponent};
1
+ import {d1 as Hj,w,a as G,G as Gi,J as JD,bh as xp,bP as si,P as Pi,_ as _w,u as ul,e as EE,M as Mw,T as TT,h as Fw,c as $h,k as Qh,l as ud,g as qw,m as dd}from'./main-F7NMHHV4.js';function y(n,k){if(n&1){let r=Fw();Pi(0,"h3"),TT(1,"Getting Started"),ul(),Pi(2,"p"),TT(3,"Welcome to KIP! Here are some basic gestures to help you navigate the application. Access the "),Pi(4,"a",1),TT(5,"KIP Help"),ul(),TT(6," documentation to learn more about KIP."),ul(),Pi(7,"table",2)(8,"thead")(9,"tr")(10,"th"),TT(11,"Actions"),ul(),Pi(12,"th"),TT(13,"Touch"),ul(),Pi(14,"th"),TT(15,"Mouse"),ul(),Pi(16,"th"),TT(17,"Keyboard Shortcuts"),ul()()(),Pi(18,"tbody")(19,"tr")(20,"td"),TT(21,"Open Actions menu"),ul(),Pi(22,"td"),TT(23,"Swipe left"),ul(),Pi(24,"td"),TT(25,"Click, drag left, and release"),ul(),Pi(26,"td")(27,"kbd"),TT(28,"Shift"),ul(),TT(29," + "),Pi(30,"kbd"),TT(31,"Ctrl"),ul(),TT(32," + "),Pi(33,"kbd",3),TT(34,"\u2190"),ul(),TT(35," (Left Arrow)"),ul()(),Pi(36,"tr")(37,"td"),TT(38,"Open Notification menu"),ul(),Pi(39,"td"),TT(40,"Swipe right"),ul(),Pi(41,"td"),TT(42,"Click, drag right, and release"),ul(),Pi(43,"td")(44,"kbd"),TT(45,"Shift"),ul(),TT(46," + "),Pi(47,"kbd"),TT(48,"Ctrl"),ul(),TT(49," + "),Pi(50,"kbd",3),TT(51,"\u2192"),ul(),TT(52," (Right Arrow)"),ul()(),Pi(53,"tr")(54,"td"),TT(55,"Cycle through dashboards"),ul(),Pi(56,"td"),TT(57,"Swipe up/down"),ul(),Pi(58,"td"),TT(59,"Click, drag up/down, and release"),ul(),Pi(60,"td")(61,"kbd"),TT(62,"Shift"),ul(),TT(63," + "),Pi(64,"kbd"),TT(65,"Ctrl"),ul(),TT(66," + "),Pi(67,"kbd",3),TT(68,"\u2191"),ul(),TT(69,"/"),Pi(70,"kbd",3),TT(71,"\u2193"),ul(),TT(72," (Up/Down Arrow)"),ul()(),Pi(73,"tr")(74,"td"),TT(75,"Toggle Fullscreen"),ul(),Pi(76,"td"),TT(77,"N/A"),ul(),Pi(78,"td"),TT(79,"N/A"),ul(),Pi(80,"td")(81,"kbd"),TT(82,"Shift"),ul(),TT(83," + "),Pi(84,"kbd"),TT(85,"Ctrl"),ul(),TT(86," + "),Pi(87,"kbd"),TT(88,"F"),ul()()(),Pi(89,"tr")(90,"td"),TT(91,"Toggle Night mode"),ul(),Pi(92,"td"),TT(93,"N/A"),ul(),Pi(94,"td"),TT(95,"N/A"),ul(),Pi(96,"td")(97,"kbd"),TT(98,"Shift"),ul(),TT(99," + "),Pi(100,"kbd"),TT(101,"Ctrl"),ul(),TT(102," + "),Pi(103,"kbd"),TT(104,"N"),ul()()(),Pi(105,"tr")(106,"td"),TT(107,"Toggle dashboard edit mode"),ul(),Pi(108,"td"),TT(109,"N/A"),ul(),Pi(110,"td"),TT(111,"N/A"),ul(),Pi(112,"td")(113,"kbd"),TT(114,"Shift"),ul(),TT(115," + "),Pi(116,"kbd"),TT(117,"Ctrl"),ul(),TT(118," + "),Pi(119,"kbd"),TT(120,"E"),ul()()()()(),Pi(121,"i"),TT(122,"Note that the words Touch and Tap are synonymous with mouse Click."),ul(),$h(123,"br")(124,"br"),Pi(125,"h3"),TT(126,"Login to Signal K"),ul(),Pi(127,"p"),TT(128," The first step is to configure Signal K server authentication ("),Pi(129,"i"),TT(130,"a pre-existing Signal K server username and password is required"),ul(),TT(131,"). Go to KIP's Connectivity options, toggle "),Pi(132,"strong"),TT(133,"Login to server"),ul(),TT(134,", enter your Signal K credentials and click "),Pi(135,"strong"),TT(136,"Sign in"),ul(),TT(137,". Once completed, click the upper right X button to get back to this dashboard ("),Pi(138,"a",4),TT(139,"Connectivity options"),ul(),TT(140,"). "),ul(),Pi(141,"ul")(142,"li"),TT(143," If you don\u2019t have a Signal K account, ask your captain or access the Signal K Admin Settings / Users page and create a user. "),ul(),Pi(144,"li"),TT(145," If you see an error, double-check your username and password, and make sure your device is on the same network as your Signal K server. "),ul()(),Pi(146,"h3"),TT(147,"Option 1: Load Demonstration Dashboards"),ul(),Pi(148,"p"),TT(149," Try the sample dashboards using data from your server: "),$h(150,"br"),Pi(151,"button",5),Qh("click",function(){ud(r);let l=qw();return dd(l.loadDemoConfig())}),TT(152,"Load Demo"),ul()(),Pi(153,"h3"),TT(154,"Option 2: Create Your Own Layout"),ul(),Pi(155,"p"),TT(156,' The text you are reading is actually a widget that fills half of the dashboard. The screen is split in halves at the middle. This mode is called Chartplotter mode. It can later be turned off in Settings / Options / Display. Dashboards are "Locked" by default to prevent accidental modifications. To edit a dashboard, swipe left and hit the bottom unlock menu button. Note that you can add and manage dashboards using the Settings button from the Actions menu. '),ul(),Pi(157,"p")(158,"strong"),TT(159,"Try editing the Dashboard now to receive further instructions!"),ul()();}}function v(n,k){n&1&&(Pi(0,"h2"),TT(1,"Changing Layouts"),ul(),TT(2," Follow these simple steps to learn how to change your dashboard layout: "),Pi(3,"ol")(4,"li"),TT(5,"Resize this Tutorial widget using the now visible dashed borders or corners arrows. Resize it so it does not take up all the screen. You need free space in your dashboard to add more widgets. You can delete this Tutorial widget later when you are done with the instructions."),ul(),Pi(6,"li"),TT(7,"Touch & Hold or Click & Hold in an empty area to open the Add Widget selection panel."),ul(),Pi(8,"li"),TT(9,"Choose a widget from the selection panel to add it to the dashboard."),ul()(),Pi(10,"h3"),TT(11,"Possible widget operations"),ul(),Pi(12,"ul")(13,"li")(14,"strong"),TT(15,"Touch and drag"),ul(),TT(16," to move widgets"),ul(),Pi(17,"li")(18,"strong"),TT(19,"Drag corners and sides"),ul(),TT(20," to resize widgets"),ul(),Pi(21,"li")(22,"strong"),TT(23,"Double Tap"),ul(),TT(24," on a widget to configure it"),ul(),Pi(25,"li")(26,"strong"),TT(27,"Press and Hold"),ul(),TT(28," on a widget to delete or duplicate widgets"),ul()(),Pi(29,"h2"),TT(30,"Exiting dashboard edit mode"),ul(),Pi(31,"p"),TT(32,"Use the Save or Cancel buttons in the lower right corner to either persist your changes or revert changes."),ul(),Pi(33,"h2"),TT(34,"Adding more dashboards"),ul(),Pi(35,"p"),TT(36,"Swipe left and hit the Dashboards button. From this page you can add, rename, order, delete, and duplicate entire dashboards."),ul());}var N=(()=>{class n{id=Hj.required();type=Hj.required();theme=Hj.required();static DEFAULT_CONFIG={filterSelfPaths:true};dashboard=w(G);settings=w(Gi);loadDemoConfig(){this.settings.loadDemoConfig();}static \u0275fac=function(o){return new(o||n)};static \u0275cmp=JD({type:n,selectors:[["widget-tutorial"]],inputs:{id:[1,"id"],type:[1,"type"],theme:[1,"theme"]},decls:3,vars:1,consts:[[1,"tutorial-container"],["routerLink","/help"],[1,"nav-table"],[2,"font-size","x-large"],["routerLink","/options"],["mat-flat-button","",2,"margin-left","15px",3,"click"]],template:function(o,l){o&1&&(Pi(0,"div",0),_w(1,y,160,0)(2,v,37,0),ul()),o&2&&(EE(),Mw(l.dashboard.isDashboardStatic()?1:2));},dependencies:[xp,si],styles:[".tutorial-container[_ngcontent-%COMP%]{position:absolute;top:0;left:0;display:block;height:100%;width:100%;overflow-y:auto}.tutorial-container[_ngcontent-%COMP%]{padding:0 15px}.nav-table[_ngcontent-%COMP%]{width:100%;border-collapse:collapse;margin-bottom:2em}.nav-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%], .nav-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%]{border:1px solid #bbb;padding:.5em 1em;text-align:center}.nav-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%]{background:#ddd;color:#222;font-weight:700}.nav-table[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:nth-child(2n){background:#242424}.warning[_ngcontent-%COMP%]{color:#b71c1c}.button-group[_ngcontent-%COMP%]{margin-top:2em;display:flex;gap:20px}a[_ngcontent-%COMP%]:visited, a[_ngcontent-%COMP%]:link{color:var(--kip-blue-color)}"]})}return n})();export{N as WidgetTutorialComponent};
@@ -1 +1 @@
1
- import {WidgetFreeboardskComponent as ae}from'./chunk-CYYBxjrc.js';import {$ as $j,w,G as Gi,a as G$1,i as ir,v as vt,D as Dt,W as Wp,E as Em,F as Fa,J as JD,Q as Qn,z as za,q as qo,O as Op,R as Rp,y as yt,b as wt,P as Pi,_ as _w,c as $h,u as ul,d as ig,B as Bh,j as jT,e as EE,M as Mw,s as sg,f as eg,K as Kw,g as qw,h as Fw,k as Qh,l as ud,m as dd}from'./main-YKDNK5VZ.js';import'./chunk-ibauGmSP.js';var G=["panel"],Q=(i,f)=>[i,f];function j(i,f){if(i&1&&$h(0,"div",7),i&2){let t=qw();ig("transform",t.ghostTransform());}}function H(i,f){if(i&1){let t=Fw();Pi(0,"div",8),Qh("pointerdown",function(n){ud(t);let o=qw();return dd(o.startResize(n))}),Pi(1,"button",9),Qh("pointerdown",function(n){ud(t);let o=qw();return dd(o.startResize(n))}),$h(2,"mat-icon",10),ul()();}}var pt=(()=>{class i{panelEl=$j.required("panel");_settings=w(Gi);_dashboard=w(G$1);breakpointObserver=w(ir);side=vt(this._settings.getSplitShellSide());panelRatio=vt(this._settings.getSplitShellWidth());originalPanelRatio=null;panelWidth=vt(0);panelCollapsed=Dt(()=>{let t=this._dashboard.dashboards(),e=this._dashboard.activeDashboard();return e==null||e<0?false:!!t[e]?.collapseSplitShell});_fskShellSwipeDisabled=Wp(this._settings.getSplitShellSwipeDisabledAsO(),{initialValue:false});fskShellSwipeDisabled=Dt(()=>this._fskShellSwipeDisabled()??false);handset$=this.breakpointObserver.observe(Em.HandsetPortrait);handset=Wp(this.handset$,{initialValue:{matches:false,breakpoints:{}}});freeboardWidgetStub={uuid:"persistent-freeboard-shell",type:"widget-freeboardsk",config:{}};chartplotterModeInPortrait=Dt(()=>this.handset().matches&&!this.panelCollapsed());canResize=Dt(()=>!this._dashboard.isDashboardStatic()&&!this.panelCollapsed());resizing=false;startX=0;startW=0;boundMove=t=>this.onMove(t);boundUp=()=>this.onUp();static MIN_DELTA_PX=1;ghostActive=vt(false);ghostTransform=vt("");ghostWidth=0;recomputeWidth=()=>{let t=this.panelEl()?.nativeElement.parentElement;if(!t)return;let e=t.clientWidth;this.panelWidth.set(Math.round(e*this.panelRatio()));};constructor(){window.addEventListener("resize",this.recomputeWidth,{passive:true}),queueMicrotask(this.recomputeWidth),Fa(()=>{this.chartplotterModeInPortrait(),this.panelRatio(),this.recomputeWidth(),setTimeout(()=>window.dispatchEvent(new Event("resize")),0);}),Fa(()=>{let t=this._dashboard.isDashboardStatic();t||this.originalPanelRatio===null&&(this.originalPanelRatio=this.panelRatio()),t&&this.originalPanelRatio;}),Fa(()=>{if(this._dashboard.layoutEditSaved(),this.originalPanelRatio!==null){let t=this.panelRatio();this._settings.setSplitShellWidth(t),this.originalPanelRatio=null;}}),Fa(()=>{if(this._dashboard.layoutEditCanceled(),this.originalPanelRatio!==null){let t=this.originalPanelRatio;this.panelRatio.set(t),queueMicrotask(()=>this.recomputeWidth()),this.originalPanelRatio=null;}});}startResize(t){this.canResize()&&(this.resizing=true,this.startX=t.clientX,this.startW=this.panelWidth(),this.ghostWidth=this.startW,this.ghostActive.set(true),this.updateGhostTransform(this.startW),t.target.setPointerCapture(t.pointerId),window.addEventListener("pointermove",this.boundMove,{passive:true}),window.addEventListener("pointerup",this.boundUp,{passive:true}));}onMove(t){if(!this.resizing)return;let e=this.side()==="left"?t.clientX-this.startX:this.startX-t.clientX,o=this.panelEl()?.nativeElement.parentElement?.clientWidth??1,p=this.startW+e,_=o*.1,$=o*.9,v=Math.min($,Math.max(_,p));Math.abs(v-this.ghostWidth)<i.MIN_DELTA_PX||(this.ghostWidth=v,this.updateGhostTransform(v));}onUp(){if(!this.resizing)return;this.resizing=false,window.removeEventListener("pointermove",this.boundMove),window.removeEventListener("pointerup",this.boundUp);let t=this.ghostWidth;this.ghostActive.set(false);let e=this.panelEl();e&&!this.panelCollapsed()&&(e.nativeElement.style.width=t+"px"),this.panelWidth.set(t);let o=this.panelEl()?.nativeElement.parentElement?.clientWidth??t,p=o?t/o:.3,_=this.panelRatio();Math.abs(p-_)>5e-4&&this.panelRatio.set(p);}updateGhostTransform(t){this.side()==="left"?this.ghostTransform.set(`translateX(${t}px)`):this.ghostTransform.set(`translateX(-${t}px)`);}ngOnDestroy(){window.removeEventListener("resize",this.recomputeWidth),this.resizing&&(window.removeEventListener("pointermove",this.boundMove),window.removeEventListener("pointerup",this.boundUp));}static \u0275fac=function(e){return new(e||i)};static \u0275cmp=JD({type:i,selectors:[["split-shell"]],viewQuery:function(e,n){e&1&&eg(n.panelEl,G,5),e&2&&Kw();},decls:8,vars:18,consts:[["panel",""],[1,"split-root",3,"ngClass"],[1,"resize-ghost",3,"transform"],[1,"fsk-shell"],["role","separator","aria-label","Resize Freeboard chartplotter panel","aria-orientation","vertical",1,"drag-handle"],[1,"fsk-iframe",3,"type","id","swipeDisabled","disableWidgetShell"],[1,"dash-container"],[1,"resize-ghost"],["role","separator","aria-label","Resize Freeboard chartplotter panel","aria-orientation","vertical",1,"drag-handle",3,"pointerdown"],["mat-mini-fab","","tabindex","-1","aria-hidden","true",1,"drag-fab",3,"pointerdown"],["fontIcon","drag_indicator"]],template:function(e,n){e&1&&(Pi(0,"div",1),_w(1,j,1,2,"div",2),Pi(2,"div",3,0),_w(4,H,3,0,"div",4),$h(5,"widget-freeboardsk",5),ul(),Pi(6,"div",6),$h(7,"dashboard"),ul()()),e&2&&(ig("--panel-ratio",n.panelRatio()),Bh("ngClass",jT(15,Q,n.side()==="left"?"side-left":"side-right",n.chartplotterModeInPortrait()?"portrait-column":"")),EE(),Mw(n.ghostActive()?1:-1),EE(),ig("width",n.chartplotterModeInPortrait()?null:n.panelWidth(),"px"),sg("collapsed",n.panelCollapsed())("drag-disabled",!n.canResize()),EE(2),Mw(n.canResize()?4:-1),EE(),Bh("type",n.freeboardWidgetStub.type)("id",n.freeboardWidgetStub.uuid)("swipeDisabled",n.fskShellSwipeDisabled())("disableWidgetShell",true));},dependencies:[Qn,za,ae,qo,Op,Rp,yt,wt],styles:[".split-root[_ngcontent-%COMP%]{position:relative;width:100%;height:100%;display:flex;overflow:hidden}.split-root.side-left[_ngcontent-%COMP%]{flex-direction:row}.split-root.side-right[_ngcontent-%COMP%]{flex-direction:row-reverse}.split-root.portrait-column[_ngcontent-%COMP%]{flex-direction:column}.split-root.portrait-column[_ngcontent-%COMP%] .fsk-shell[_ngcontent-%COMP%], .split-root.portrait-column[_ngcontent-%COMP%] .dash-container[_ngcontent-%COMP%]{width:100%!important;min-height:0}.split-root.portrait-column[_ngcontent-%COMP%] .fsk-shell[_ngcontent-%COMP%]{flex:0 0 calc(var(--panel-ratio, .3) * 100%)}.split-root.portrait-column[_ngcontent-%COMP%] .dash-container[_ngcontent-%COMP%]{flex:1 1 auto;min-height:0;overflow:hidden}.split-root.side-left.portrait-column[_ngcontent-%COMP%] .dash-container[_ngcontent-%COMP%]{order:2}.split-root.side-left.portrait-column[_ngcontent-%COMP%] .fsk-shell[_ngcontent-%COMP%]{order:1}.split-root.side-right.portrait-column[_ngcontent-%COMP%] .fsk-shell[_ngcontent-%COMP%]{order:2}.split-root.side-right.portrait-column[_ngcontent-%COMP%] .dash-container[_ngcontent-%COMP%]{order:1}.split-root.portrait-column[_ngcontent-%COMP%] .fsk-shell.collapsed[_ngcontent-%COMP%]{flex:0 0 0!important}.split-root.portrait-column[_ngcontent-%COMP%] .drag-handle[_ngcontent-%COMP%], .split-root.portrait-column[_ngcontent-%COMP%] .resize-ghost[_ngcontent-%COMP%]{display:none}.fsk-shell[_ngcontent-%COMP%]{position:relative;height:100%;display:flex;flex-direction:column;background:var(--mat-sys-surface-container, #111);transition:width .2s ease}.fsk-shell.collapsed[_ngcontent-%COMP%]{width:1px!important;visibility:hidden;opacity:0;pointer-events:none}.fsk-iframe[_ngcontent-%COMP%]{flex:1 1 auto;min-width:0}.dash-container[_ngcontent-%COMP%]{flex:1 1 auto;min-width:0;height:100%}.drag-handle[_ngcontent-%COMP%]{position:absolute;top:0;bottom:0;width:3px;cursor:col-resize;background:var(--mat-sys-inverse-primary);z-index:5}.drag-handle[_ngcontent-%COMP%] .drag-fab[_ngcontent-%COMP%]{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:28px;height:28px;min-width:28px;cursor:col-resize;pointer-events:auto}.drag-handle[_ngcontent-%COMP%] .drag-fab[_ngcontent-%COMP%] mat-icon[_ngcontent-%COMP%]{font-size:20px;width:20px;height:20px;line-height:20px}.side-left[_ngcontent-%COMP%] .drag-handle[_ngcontent-%COMP%]{right:-2px}.side-right[_ngcontent-%COMP%] .drag-handle[_ngcontent-%COMP%]{left:-2px}.drag-handle[_ngcontent-%COMP%]:hover{background:var(--mat-sys-error-container)}.side-left[_ngcontent-%COMP%] .collapse-toggle[_ngcontent-%COMP%]{left:.25rem}.side-right[_ngcontent-%COMP%] .collapse-toggle[_ngcontent-%COMP%]{right:.25rem}.fsk-shell.drag-disabled[_ngcontent-%COMP%] .drag-handle[_ngcontent-%COMP%]{cursor:not-allowed;opacity:.4}.resize-ghost[_ngcontent-%COMP%]{position:absolute;top:0;bottom:0;width:2px;background:var(--mat-sys-error-container);opacity:.9;pointer-events:none;z-index:30;will-change:transform;transition:none}.side-left[_ngcontent-%COMP%] .resize-ghost[_ngcontent-%COMP%]{left:0}.side-right[_ngcontent-%COMP%] .resize-ghost[_ngcontent-%COMP%]{right:0}"]})}return i})();export{pt as SplitShellComponent};
1
+ import {WidgetFreeboardskComponent as ae}from'./chunk-B4Wxwb2y.js';import {$ as $j,w,G as Gi,a as G$1,i as ir,v as vt,D as Dt,W as Wp,E as Em,F as Fa,J as JD,Q as Qn,z as za,q as qo,O as Op,R as Rp,y as yt,b as wt,P as Pi,_ as _w,c as $h,u as ul,d as ig,B as Bh,j as jT,e as EE,M as Mw,s as sg,f as eg,K as Kw,g as qw,h as Fw,k as Qh,l as ud,m as dd}from'./main-F7NMHHV4.js';import'./chunk-CteyWXZ_.js';var G=["panel"],Q=(i,f)=>[i,f];function j(i,f){if(i&1&&$h(0,"div",7),i&2){let t=qw();ig("transform",t.ghostTransform());}}function H(i,f){if(i&1){let t=Fw();Pi(0,"div",8),Qh("pointerdown",function(n){ud(t);let o=qw();return dd(o.startResize(n))}),Pi(1,"button",9),Qh("pointerdown",function(n){ud(t);let o=qw();return dd(o.startResize(n))}),$h(2,"mat-icon",10),ul()();}}var pt=(()=>{class i{panelEl=$j.required("panel");_settings=w(Gi);_dashboard=w(G$1);breakpointObserver=w(ir);side=vt(this._settings.getSplitShellSide());panelRatio=vt(this._settings.getSplitShellWidth());originalPanelRatio=null;panelWidth=vt(0);panelCollapsed=Dt(()=>{let t=this._dashboard.dashboards(),e=this._dashboard.activeDashboard();return e==null||e<0?false:!!t[e]?.collapseSplitShell});_fskShellSwipeDisabled=Wp(this._settings.getSplitShellSwipeDisabledAsO(),{initialValue:false});fskShellSwipeDisabled=Dt(()=>this._fskShellSwipeDisabled()??false);handset$=this.breakpointObserver.observe(Em.HandsetPortrait);handset=Wp(this.handset$,{initialValue:{matches:false,breakpoints:{}}});freeboardWidgetStub={uuid:"persistent-freeboard-shell",type:"widget-freeboardsk",config:{}};chartplotterModeInPortrait=Dt(()=>this.handset().matches&&!this.panelCollapsed());canResize=Dt(()=>!this._dashboard.isDashboardStatic()&&!this.panelCollapsed());resizing=false;startX=0;startW=0;boundMove=t=>this.onMove(t);boundUp=()=>this.onUp();static MIN_DELTA_PX=1;ghostActive=vt(false);ghostTransform=vt("");ghostWidth=0;recomputeWidth=()=>{let t=this.panelEl()?.nativeElement.parentElement;if(!t)return;let e=t.clientWidth;this.panelWidth.set(Math.round(e*this.panelRatio()));};constructor(){window.addEventListener("resize",this.recomputeWidth,{passive:true}),queueMicrotask(this.recomputeWidth),Fa(()=>{this.chartplotterModeInPortrait(),this.panelRatio(),this.recomputeWidth(),setTimeout(()=>window.dispatchEvent(new Event("resize")),0);}),Fa(()=>{let t=this._dashboard.isDashboardStatic();t||this.originalPanelRatio===null&&(this.originalPanelRatio=this.panelRatio()),t&&this.originalPanelRatio;}),Fa(()=>{if(this._dashboard.layoutEditSaved(),this.originalPanelRatio!==null){let t=this.panelRatio();this._settings.setSplitShellWidth(t),this.originalPanelRatio=null;}}),Fa(()=>{if(this._dashboard.layoutEditCanceled(),this.originalPanelRatio!==null){let t=this.originalPanelRatio;this.panelRatio.set(t),queueMicrotask(()=>this.recomputeWidth()),this.originalPanelRatio=null;}});}startResize(t){this.canResize()&&(this.resizing=true,this.startX=t.clientX,this.startW=this.panelWidth(),this.ghostWidth=this.startW,this.ghostActive.set(true),this.updateGhostTransform(this.startW),t.target.setPointerCapture(t.pointerId),window.addEventListener("pointermove",this.boundMove,{passive:true}),window.addEventListener("pointerup",this.boundUp,{passive:true}));}onMove(t){if(!this.resizing)return;let e=this.side()==="left"?t.clientX-this.startX:this.startX-t.clientX,o=this.panelEl()?.nativeElement.parentElement?.clientWidth??1,p=this.startW+e,_=o*.1,$=o*.9,v=Math.min($,Math.max(_,p));Math.abs(v-this.ghostWidth)<i.MIN_DELTA_PX||(this.ghostWidth=v,this.updateGhostTransform(v));}onUp(){if(!this.resizing)return;this.resizing=false,window.removeEventListener("pointermove",this.boundMove),window.removeEventListener("pointerup",this.boundUp);let t=this.ghostWidth;this.ghostActive.set(false);let e=this.panelEl();e&&!this.panelCollapsed()&&(e.nativeElement.style.width=t+"px"),this.panelWidth.set(t);let o=this.panelEl()?.nativeElement.parentElement?.clientWidth??t,p=o?t/o:.3,_=this.panelRatio();Math.abs(p-_)>5e-4&&this.panelRatio.set(p);}updateGhostTransform(t){this.side()==="left"?this.ghostTransform.set(`translateX(${t}px)`):this.ghostTransform.set(`translateX(-${t}px)`);}ngOnDestroy(){window.removeEventListener("resize",this.recomputeWidth),this.resizing&&(window.removeEventListener("pointermove",this.boundMove),window.removeEventListener("pointerup",this.boundUp));}static \u0275fac=function(e){return new(e||i)};static \u0275cmp=JD({type:i,selectors:[["split-shell"]],viewQuery:function(e,n){e&1&&eg(n.panelEl,G,5),e&2&&Kw();},decls:8,vars:18,consts:[["panel",""],[1,"split-root",3,"ngClass"],[1,"resize-ghost",3,"transform"],[1,"fsk-shell"],["role","separator","aria-label","Resize Freeboard chartplotter panel","aria-orientation","vertical",1,"drag-handle"],[1,"fsk-iframe",3,"type","id","swipeDisabled","disableWidgetShell"],[1,"dash-container"],[1,"resize-ghost"],["role","separator","aria-label","Resize Freeboard chartplotter panel","aria-orientation","vertical",1,"drag-handle",3,"pointerdown"],["mat-mini-fab","","tabindex","-1","aria-hidden","true",1,"drag-fab",3,"pointerdown"],["fontIcon","drag_indicator"]],template:function(e,n){e&1&&(Pi(0,"div",1),_w(1,j,1,2,"div",2),Pi(2,"div",3,0),_w(4,H,3,0,"div",4),$h(5,"widget-freeboardsk",5),ul(),Pi(6,"div",6),$h(7,"dashboard"),ul()()),e&2&&(ig("--panel-ratio",n.panelRatio()),Bh("ngClass",jT(15,Q,n.side()==="left"?"side-left":"side-right",n.chartplotterModeInPortrait()?"portrait-column":"")),EE(),Mw(n.ghostActive()?1:-1),EE(),ig("width",n.chartplotterModeInPortrait()?null:n.panelWidth(),"px"),sg("collapsed",n.panelCollapsed())("drag-disabled",!n.canResize()),EE(2),Mw(n.canResize()?4:-1),EE(),Bh("type",n.freeboardWidgetStub.type)("id",n.freeboardWidgetStub.uuid)("swipeDisabled",n.fskShellSwipeDisabled())("disableWidgetShell",true));},dependencies:[Qn,za,ae,qo,Op,Rp,yt,wt],styles:[".split-root[_ngcontent-%COMP%]{position:relative;width:100%;height:100%;display:flex;overflow:hidden}.split-root.side-left[_ngcontent-%COMP%]{flex-direction:row}.split-root.side-right[_ngcontent-%COMP%]{flex-direction:row-reverse}.split-root.portrait-column[_ngcontent-%COMP%]{flex-direction:column}.split-root.portrait-column[_ngcontent-%COMP%] .fsk-shell[_ngcontent-%COMP%], .split-root.portrait-column[_ngcontent-%COMP%] .dash-container[_ngcontent-%COMP%]{width:100%!important;min-height:0}.split-root.portrait-column[_ngcontent-%COMP%] .fsk-shell[_ngcontent-%COMP%]{flex:0 0 calc(var(--panel-ratio, .3) * 100%)}.split-root.portrait-column[_ngcontent-%COMP%] .dash-container[_ngcontent-%COMP%]{flex:1 1 auto;min-height:0;overflow:hidden}.split-root.side-left.portrait-column[_ngcontent-%COMP%] .dash-container[_ngcontent-%COMP%]{order:2}.split-root.side-left.portrait-column[_ngcontent-%COMP%] .fsk-shell[_ngcontent-%COMP%]{order:1}.split-root.side-right.portrait-column[_ngcontent-%COMP%] .fsk-shell[_ngcontent-%COMP%]{order:2}.split-root.side-right.portrait-column[_ngcontent-%COMP%] .dash-container[_ngcontent-%COMP%]{order:1}.split-root.portrait-column[_ngcontent-%COMP%] .fsk-shell.collapsed[_ngcontent-%COMP%]{flex:0 0 0!important}.split-root.portrait-column[_ngcontent-%COMP%] .drag-handle[_ngcontent-%COMP%], .split-root.portrait-column[_ngcontent-%COMP%] .resize-ghost[_ngcontent-%COMP%]{display:none}.fsk-shell[_ngcontent-%COMP%]{position:relative;height:100%;display:flex;flex-direction:column;background:var(--mat-sys-surface-container, #111);transition:width .2s ease}.fsk-shell.collapsed[_ngcontent-%COMP%]{width:1px!important;visibility:hidden;opacity:0;pointer-events:none}.fsk-iframe[_ngcontent-%COMP%]{flex:1 1 auto;min-width:0}.dash-container[_ngcontent-%COMP%]{flex:1 1 auto;min-width:0;height:100%}.drag-handle[_ngcontent-%COMP%]{position:absolute;top:0;bottom:0;width:3px;cursor:col-resize;background:var(--mat-sys-inverse-primary);z-index:5}.drag-handle[_ngcontent-%COMP%] .drag-fab[_ngcontent-%COMP%]{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:28px;height:28px;min-width:28px;cursor:col-resize;pointer-events:auto}.drag-handle[_ngcontent-%COMP%] .drag-fab[_ngcontent-%COMP%] mat-icon[_ngcontent-%COMP%]{font-size:20px;width:20px;height:20px;line-height:20px}.side-left[_ngcontent-%COMP%] .drag-handle[_ngcontent-%COMP%]{right:-2px}.side-right[_ngcontent-%COMP%] .drag-handle[_ngcontent-%COMP%]{left:-2px}.drag-handle[_ngcontent-%COMP%]:hover{background:var(--mat-sys-error-container)}.side-left[_ngcontent-%COMP%] .collapse-toggle[_ngcontent-%COMP%]{left:.25rem}.side-right[_ngcontent-%COMP%] .collapse-toggle[_ngcontent-%COMP%]{right:.25rem}.fsk-shell.drag-disabled[_ngcontent-%COMP%] .drag-handle[_ngcontent-%COMP%]{cursor:not-allowed;opacity:.4}.resize-ghost[_ngcontent-%COMP%]{position:absolute;top:0;bottom:0;width:2px;background:var(--mat-sys-error-container);opacity:.9;pointer-events:none;z-index:30;will-change:transform;transition:none}.side-left[_ngcontent-%COMP%] .resize-ghost[_ngcontent-%COMP%]{left:0}.side-right[_ngcontent-%COMP%] .resize-ghost[_ngcontent-%COMP%]{right:0}"]})}return i})();export{pt as SplitShellComponent};
@@ -1 +1 @@
1
- import {a as a$1}from'./chunk-ibauGmSP.js';import {d1 as Hj,w,du as p,G as Gi,N,aX as He,a as G,$ as $j,W as Wp,F as Fa,dn as ge,J as JD,_ as _w,M as Mw,f as eg,K as Kw,H as Dr,eb as rw,cp as Uh,bD as HT,g as qw,b_ as Gh,bE as $T,ci as dl,cj as fl,e as EE,dP as pp}from'./main-YKDNK5VZ.js';var R=(()=>{class n{sanitizer=w(Dr);transform(e){return this.sanitizer.bypassSecurityTrustResourceUrl(e)}static \u0275fac=function(t){return new(t||n)};static \u0275pipe=rw({name:"safe",type:n,pure:true})}return n})();var $=["freeboardSkIframe"];function z(n,v){if(n&1&&(Uh(0,"iframe",1,0),HT(2,"safe")),n&2){let e=qw();Gh("src",$T(2,1,e.widgetUrlSafe),pp);}}function A(n,v){n&1&&Uh(0,"div",4);}function B(n,v){if(n&1&&(dl(0,"div",2),Uh(1,"iframe",3,0),HT(3,"safe"),_w(4,A,1,0,"div",4),fl()),n&2){let e=qw();EE(),Gh("src",$T(3,2,e.widgetUrlSafe),pp),EE(3),Mw(e.dashboard.isDashboardStatic()?-1:4);}}var ae=(()=>{class n{id=Hj();type=Hj();theme=Hj();disableWidgetShell=Hj(false);swipeDisabled=Hj(false);runtime=w(p,{optional:true});appSettings=w(Gi);app=w(N);auth=w(He);dashboard=w(G);iframe=$j.required("freeboardSkIframe");authToken=Wp(this.auth.authToken$,{initialValue:null});viewReady=false;iframeLoaded=false;widgetUrl=null;widgetUrlSafe="";static DEFAULT_CONFIG={};constructor(){window.addEventListener("message",this.handleIframeGesture),Fa(()=>{let e=this.authToken();ge(()=>{let t=e?.token,i=this.appSettings.signalkUrl?.url;this.widgetUrl=i?t?`${i}/@signalk/freeboard-sk/?token=${t}`:`${i}/@signalk/freeboard-sk/`:null,this.widgetUrlSafe=this.widgetUrl??"";});}),Fa(()=>{let e=this.app.isNightMode();ge(()=>{!this.iframeLoaded||!this.viewReady||this.appSettings.getRedNightMode()&&this.sendMessage({commands:{nightModeEnable:e}});});});}ngAfterViewInit(){this.viewReady=true;try{this.iframe().nativeElement.onload=()=>{this.iframeLoaded=!0,this.sendMessage({settings:{autoNightMode:!1}}),this.injectSwipeScript();};}catch(e){}}sendMessage(e,t="*"){let i=this.iframe()?.nativeElement?.contentWindow;i&&this.iframeLoaded&&i.postMessage(e,t);}injectSwipeScript(){if(this.swipeDisabled())return;let e=this.iframe().nativeElement.contentWindow,t=this.iframe().nativeElement.contentDocument;if(!t||!e){console.error("[FSK Widget] Iframe contentDocument or contentWindow is undefined.");return}try{let i=`kip-gesture-inject-${this.id()}`;if(t.getElementById(i))return;let s=a$1({instanceId:this.id()}),r=t.createElement("script");r.id=i,r.textContent=s,t.body.appendChild(r);}catch(i){console.warn("[FSK Widget] Failed to inject swipe script into iframe:",i);}}handleIframeGesture=e=>{if(!e.data||!this.viewReady)return;let t=null;try{t=this.iframe()?.nativeElement?.contentWindow??null;}catch(r){t=null;}if(!t||e.source!==t)return;let i=this.getExpectedIframeOrigin();if(i&&e.origin!==i)return;let s=this.id();if(e.data.gesture&&e.data.eventData?.instanceId===s)switch(e.data.gesture){case "swipeup":this.dashboard.isDashboardStatic()&&this.dashboard.navigateToPreviousDashboard();break;case "swipedown":this.dashboard.isDashboardStatic()&&this.dashboard.navigateToNextDashboard();break;case "swipeleft":window.document.dispatchEvent(new Event("openLeftSidenav",{bubbles:true,cancelable:true}));break;case "swiperight":window.document.dispatchEvent(new Event("openRightSidenav",{bubbles:true,cancelable:true}));break}if(e.data.type==="keydown"&&e.data.keyEventData?.instanceId===s){let{key:r,ctrlKey:L,shiftKey:O}=e.data.keyEventData,P=new KeyboardEvent("keydown",{key:r,ctrlKey:L,shiftKey:O,bubbles:true,cancelable:true});document.dispatchEvent(P);}};getExpectedIframeOrigin(){let e=this.widgetUrl||this.appSettings.signalkUrl?.url;if(!e)return null;try{return new URL(e).origin}catch(t){return null}}ngOnDestroy(){if(window.removeEventListener("message",this.handleIframeGesture),this.iframe){try{this.iframe().nativeElement.onload=null;}catch(e){}try{let e=this.iframe()?.nativeElement.contentDocument;if(e){let t=`kip-gesture-inject-${this.id()}`,i=e.getElementById(t);i&&i.parentNode&&i.parentNode.removeChild(i);}}catch(e){}}}static \u0275fac=function(t){return new(t||n)};static \u0275cmp=JD({type:n,selectors:[["widget-freeboardsk"]],viewQuery:function(t,i){t&1&&eg(i.iframe,$,5),t&2&&Kw();},inputs:{id:[1,"id"],type:[1,"type"],theme:[1,"theme"],disableWidgetShell:[1,"disableWidgetShell"],swipeDisabled:[1,"swipeDisabled"]},decls:2,vars:1,consts:[["freeboardSkIframe",""],["width","100%","height","100%","frameborder","0","sandbox","allow-same-origin allow-scripts allow-forms",1,"freeboardsk-iframe","no-shell",3,"src"],[1,"widget-shell",2,"overflow","clip","position","relative","width","100%","height","100%"],["width","100%","height","100%","frameborder","0","sandbox","allow-same-origin allow-scripts allow-forms",1,"freeboardsk-iframe",3,"src"],[1,"widgetOverlay"]],template:function(t,i){t&1&&_w(0,z,3,3,"iframe",1)(1,B,5,4,"div",2),t&2&&Mw(i.disableWidgetShell()?0:1);},dependencies:[R],styles:[".widgetOverlay[_ngcontent-%COMP%]{position:absolute;width:100%;height:100%;right:0;bottom:0;color:transparent}"]})}return n})();export{ae as WidgetFreeboardskComponent};
1
+ import {a as a$1}from'./chunk-CteyWXZ_.js';import {d1 as Hj,w,du as p,G as Gi,N,aX as He,a as G,$ as $j,W as Wp,F as Fa,dn as ge,J as JD,_ as _w,M as Mw,f as eg,K as Kw,H as Dr,eb as rw,cp as Uh,bD as HT,g as qw,b_ as Gh,bE as $T,ci as dl,cj as fl,e as EE,dP as pp}from'./main-F7NMHHV4.js';var R=(()=>{class n{sanitizer=w(Dr);transform(e){return this.sanitizer.bypassSecurityTrustResourceUrl(e)}static \u0275fac=function(t){return new(t||n)};static \u0275pipe=rw({name:"safe",type:n,pure:true})}return n})();var $=["freeboardSkIframe"];function z(n,v){if(n&1&&(Uh(0,"iframe",1,0),HT(2,"safe")),n&2){let e=qw();Gh("src",$T(2,1,e.widgetUrlSafe),pp);}}function A(n,v){n&1&&Uh(0,"div",4);}function B(n,v){if(n&1&&(dl(0,"div",2),Uh(1,"iframe",3,0),HT(3,"safe"),_w(4,A,1,0,"div",4),fl()),n&2){let e=qw();EE(),Gh("src",$T(3,2,e.widgetUrlSafe),pp),EE(3),Mw(e.dashboard.isDashboardStatic()?-1:4);}}var ae=(()=>{class n{id=Hj();type=Hj();theme=Hj();disableWidgetShell=Hj(false);swipeDisabled=Hj(false);runtime=w(p,{optional:true});appSettings=w(Gi);app=w(N);auth=w(He);dashboard=w(G);iframe=$j.required("freeboardSkIframe");authToken=Wp(this.auth.authToken$,{initialValue:null});viewReady=false;iframeLoaded=false;widgetUrl=null;widgetUrlSafe="";static DEFAULT_CONFIG={};constructor(){window.addEventListener("message",this.handleIframeGesture),Fa(()=>{let e=this.authToken();ge(()=>{let t=e?.token,i=this.appSettings.signalkUrl?.url;this.widgetUrl=i?t?`${i}/@signalk/freeboard-sk/?token=${t}`:`${i}/@signalk/freeboard-sk/`:null,this.widgetUrlSafe=this.widgetUrl??"";});}),Fa(()=>{let e=this.app.isNightMode();ge(()=>{!this.iframeLoaded||!this.viewReady||this.appSettings.getRedNightMode()&&this.sendMessage({commands:{nightModeEnable:e}});});});}ngAfterViewInit(){this.viewReady=true;try{this.iframe().nativeElement.onload=()=>{this.iframeLoaded=!0,this.sendMessage({settings:{autoNightMode:!1}}),this.injectSwipeScript();};}catch(e){}}sendMessage(e,t="*"){let i=this.iframe()?.nativeElement?.contentWindow;i&&this.iframeLoaded&&i.postMessage(e,t);}injectSwipeScript(){if(this.swipeDisabled())return;let e=this.iframe().nativeElement.contentWindow,t=this.iframe().nativeElement.contentDocument;if(!t||!e){console.error("[FSK Widget] Iframe contentDocument or contentWindow is undefined.");return}try{let i=`kip-gesture-inject-${this.id()}`;if(t.getElementById(i))return;let s=a$1({instanceId:this.id()}),r=t.createElement("script");r.id=i,r.textContent=s,t.body.appendChild(r);}catch(i){console.warn("[FSK Widget] Failed to inject swipe script into iframe:",i);}}handleIframeGesture=e=>{if(!e.data||!this.viewReady)return;let t=null;try{t=this.iframe()?.nativeElement?.contentWindow??null;}catch(r){t=null;}if(!t||e.source!==t)return;let i=this.getExpectedIframeOrigin();if(i&&e.origin!==i)return;let s=this.id();if(e.data.gesture&&e.data.eventData?.instanceId===s)switch(e.data.gesture){case "swipeup":this.dashboard.isDashboardStatic()&&this.dashboard.navigateToPreviousDashboard();break;case "swipedown":this.dashboard.isDashboardStatic()&&this.dashboard.navigateToNextDashboard();break;case "swipeleft":window.document.dispatchEvent(new Event("openLeftSidenav",{bubbles:true,cancelable:true}));break;case "swiperight":window.document.dispatchEvent(new Event("openRightSidenav",{bubbles:true,cancelable:true}));break}if(e.data.type==="keydown"&&e.data.keyEventData?.instanceId===s){let{key:r,ctrlKey:L,shiftKey:O}=e.data.keyEventData,P=new KeyboardEvent("keydown",{key:r,ctrlKey:L,shiftKey:O,bubbles:true,cancelable:true});document.dispatchEvent(P);}};getExpectedIframeOrigin(){let e=this.widgetUrl||this.appSettings.signalkUrl?.url;if(!e)return null;try{return new URL(e).origin}catch(t){return null}}ngOnDestroy(){if(window.removeEventListener("message",this.handleIframeGesture),this.iframe){try{this.iframe().nativeElement.onload=null;}catch(e){}try{let e=this.iframe()?.nativeElement.contentDocument;if(e){let t=`kip-gesture-inject-${this.id()}`,i=e.getElementById(t);i&&i.parentNode&&i.parentNode.removeChild(i);}}catch(e){}}}static \u0275fac=function(t){return new(t||n)};static \u0275cmp=JD({type:n,selectors:[["widget-freeboardsk"]],viewQuery:function(t,i){t&1&&eg(i.iframe,$,5),t&2&&Kw();},inputs:{id:[1,"id"],type:[1,"type"],theme:[1,"theme"],disableWidgetShell:[1,"disableWidgetShell"],swipeDisabled:[1,"swipeDisabled"]},decls:2,vars:1,consts:[["freeboardSkIframe",""],["width","100%","height","100%","frameborder","0","sandbox","allow-same-origin allow-scripts allow-forms",1,"freeboardsk-iframe","no-shell",3,"src"],[1,"widget-shell",2,"overflow","clip","position","relative","width","100%","height","100%"],["width","100%","height","100%","frameborder","0","sandbox","allow-same-origin allow-scripts allow-forms",1,"freeboardsk-iframe",3,"src"],[1,"widgetOverlay"]],template:function(t,i){t&1&&_w(0,z,3,3,"iframe",1)(1,B,5,4,"div",2),t&2&&Mw(i.disableWidgetShell()?0:1);},dependencies:[R],styles:[".widgetOverlay[_ngcontent-%COMP%]{position:absolute;width:100%;height:100%;right:0;bottom:0;color:transparent}"]})}return n})();export{ae as WidgetFreeboardskComponent};