@elizaos/plugin-facewear 2.0.3-beta.5 → 2.0.3-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/display-text.d.ts +4 -0
- package/dist/actions/display-text.d.ts.map +1 -0
- package/dist/actions/display-text.js +90 -0
- package/dist/actions/display-text.js.map +1 -0
- package/dist/actions/facewear-connect.d.ts +3 -0
- package/dist/actions/facewear-connect.d.ts.map +1 -0
- package/dist/actions/facewear-connect.js +70 -0
- package/dist/actions/facewear-connect.js.map +1 -0
- package/dist/actions/facewear-control.d.ts +4 -0
- package/dist/actions/facewear-control.d.ts.map +1 -0
- package/dist/actions/facewear-control.js +627 -0
- package/dist/actions/facewear-control.js.map +1 -0
- package/dist/actions/facewear-debug.d.ts +3 -0
- package/dist/actions/facewear-debug.d.ts.map +1 -0
- package/dist/actions/facewear-debug.js +62 -0
- package/dist/actions/facewear-debug.js.map +1 -0
- package/dist/actions/facewear-status.d.ts +4 -0
- package/dist/actions/facewear-status.d.ts.map +1 -0
- package/dist/actions/facewear-status.js +66 -0
- package/dist/actions/facewear-status.js.map +1 -0
- package/dist/actions/microphone.d.ts +4 -0
- package/dist/actions/microphone.d.ts.map +1 -0
- package/dist/actions/microphone.js +63 -0
- package/dist/actions/microphone.js.map +1 -0
- package/dist/actions/view-actions.d.ts +23 -0
- package/dist/actions/view-actions.d.ts.map +1 -0
- package/dist/actions/view-actions.js +314 -0
- package/dist/actions/view-actions.js.map +1 -0
- package/dist/actions/vision-query.d.ts +4 -0
- package/dist/actions/vision-query.d.ts.map +1 -0
- package/dist/actions/vision-query.js +41 -0
- package/dist/actions/vision-query.js.map +1 -0
- package/dist/actions/xr-view-actions.d.ts +14 -0
- package/dist/actions/xr-view-actions.d.ts.map +1 -0
- package/dist/actions/xr-view-actions.js +29 -0
- package/dist/actions/xr-view-actions.js.map +1 -0
- package/dist/components/FacewearSpatialView.d.ts +50 -0
- package/dist/components/FacewearSpatialView.d.ts.map +1 -0
- package/dist/components/FacewearSpatialView.js +129 -0
- package/dist/components/FacewearSpatialView.js.map +1 -0
- package/dist/components/FacewearView.d.ts +17 -0
- package/dist/components/FacewearView.d.ts.map +1 -0
- package/dist/components/FacewearView.js +88 -0
- package/dist/components/FacewearView.js.map +1 -0
- package/dist/components/SmartglassesPanelView.d.ts +22 -0
- package/dist/components/SmartglassesPanelView.d.ts.map +1 -0
- package/dist/components/SmartglassesPanelView.js +140 -0
- package/dist/components/SmartglassesPanelView.js.map +1 -0
- package/dist/components/SmartglassesSpatialView.d.ts +46 -0
- package/dist/components/SmartglassesSpatialView.d.ts.map +1 -0
- package/dist/components/SmartglassesSpatialView.js +240 -0
- package/dist/components/SmartglassesSpatialView.js.map +1 -0
- package/dist/components/facewear-profiles.d.ts +27 -0
- package/dist/components/facewear-profiles.d.ts.map +1 -0
- package/dist/components/facewear-profiles.js +40 -0
- package/dist/components/facewear-profiles.js.map +1 -0
- package/dist/devices/apple-vision-pro.d.ts +7 -0
- package/dist/devices/apple-vision-pro.d.ts.map +1 -0
- package/dist/devices/apple-vision-pro.js +21 -0
- package/dist/devices/apple-vision-pro.js.map +1 -0
- package/dist/devices/even-realities.d.ts +7 -0
- package/dist/devices/even-realities.d.ts.map +1 -0
- package/dist/devices/even-realities.js +13 -0
- package/dist/devices/even-realities.js.map +1 -0
- package/dist/devices/meta-quest.d.ts +5 -0
- package/dist/devices/meta-quest.d.ts.map +1 -0
- package/dist/devices/meta-quest.js +21 -0
- package/dist/devices/meta-quest.js.map +1 -0
- package/dist/devices/registry.d.ts +19 -0
- package/dist/devices/registry.d.ts.map +1 -0
- package/dist/devices/registry.js +96 -0
- package/dist/devices/registry.js.map +1 -0
- package/dist/devices/xreal.d.ts +7 -0
- package/dist/devices/xreal.d.ts.map +1 -0
- package/dist/devices/xreal.js +19 -0
- package/dist/devices/xreal.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +260 -0
- package/dist/index.js.map +1 -0
- package/dist/protocol/smartglasses.d.ts +306 -0
- package/dist/protocol/smartglasses.d.ts.map +1 -0
- package/dist/protocol/smartglasses.js +1485 -0
- package/dist/protocol/smartglasses.js.map +1 -0
- package/dist/protocol/xr.d.ts +137 -0
- package/dist/protocol/xr.d.ts.map +1 -0
- package/dist/protocol/xr.js +18 -0
- package/dist/protocol/xr.js.map +1 -0
- package/dist/providers/facewear-context.d.ts +3 -0
- package/dist/providers/facewear-context.d.ts.map +1 -0
- package/dist/providers/facewear-context.js +59 -0
- package/dist/providers/facewear-context.js.map +1 -0
- package/dist/providers/smartglasses-status.d.ts +3 -0
- package/dist/providers/smartglasses-status.d.ts.map +1 -0
- package/dist/providers/smartglasses-status.js +33 -0
- package/dist/providers/smartglasses-status.js.map +1 -0
- package/dist/register-terminal-view.d.ts +21 -0
- package/dist/register-terminal-view.d.ts.map +1 -0
- package/dist/register-terminal-view.js +70 -0
- package/dist/register-terminal-view.js.map +1 -0
- package/dist/register.d.ts +8 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +116 -0
- package/dist/register.js.map +1 -0
- package/dist/routes/connect.d.ts +3 -0
- package/dist/routes/connect.d.ts.map +1 -0
- package/dist/routes/connect.js +86 -0
- package/dist/routes/connect.js.map +1 -0
- package/dist/routes/device-config.d.ts +5 -0
- package/dist/routes/device-config.d.ts.map +1 -0
- package/dist/routes/device-config.js +56 -0
- package/dist/routes/device-config.js.map +1 -0
- package/dist/routes/simulator-route.d.ts +8 -0
- package/dist/routes/simulator-route.d.ts.map +1 -0
- package/dist/routes/simulator-route.js +32 -0
- package/dist/routes/simulator-route.js.map +1 -0
- package/dist/routes/status.d.ts +3 -0
- package/dist/routes/status.d.ts.map +1 -0
- package/dist/routes/status.js +34 -0
- package/dist/routes/status.js.map +1 -0
- package/dist/routes/view-host.d.ts +24 -0
- package/dist/routes/view-host.d.ts.map +1 -0
- package/dist/routes/view-host.js +339 -0
- package/dist/routes/view-host.js.map +1 -0
- package/dist/routes/views.d.ts +8 -0
- package/dist/routes/views.d.ts.map +1 -0
- package/dist/routes/views.js +31 -0
- package/dist/routes/views.js.map +1 -0
- package/dist/services/audio-pipeline.d.ts +20 -0
- package/dist/services/audio-pipeline.d.ts.map +1 -0
- package/dist/services/audio-pipeline.js +87 -0
- package/dist/services/audio-pipeline.js.map +1 -0
- package/dist/services/facewear-service.d.ts +26 -0
- package/dist/services/facewear-service.d.ts.map +1 -0
- package/dist/services/facewear-service.js +45 -0
- package/dist/services/facewear-service.js.map +1 -0
- package/dist/services/smartglasses-service.d.ts +244 -0
- package/dist/services/smartglasses-service.d.ts.map +1 -0
- package/dist/services/smartglasses-service.js +821 -0
- package/dist/services/smartglasses-service.js.map +1 -0
- package/dist/services/vision-pipeline.d.ts +16 -0
- package/dist/services/vision-pipeline.d.ts.map +1 -0
- package/dist/services/vision-pipeline.js +39 -0
- package/dist/services/vision-pipeline.js.map +1 -0
- package/dist/services/xr-session-service.d.ts +54 -0
- package/dist/services/xr-session-service.d.ts.map +1 -0
- package/dist/services/xr-session-service.js +345 -0
- package/dist/services/xr-session-service.js.map +1 -0
- package/dist/status-format.d.ts +15 -0
- package/dist/status-format.d.ts.map +1 -0
- package/dist/status-format.js +89 -0
- package/dist/status-format.js.map +1 -0
- package/dist/transport/even-bridge.d.ts +69 -0
- package/dist/transport/even-bridge.d.ts.map +1 -0
- package/dist/transport/even-bridge.js +510 -0
- package/dist/transport/even-bridge.js.map +1 -0
- package/dist/transport/mock.d.ts +42 -0
- package/dist/transport/mock.d.ts.map +1 -0
- package/dist/transport/mock.js +124 -0
- package/dist/transport/mock.js.map +1 -0
- package/dist/transport/noble.d.ts +62 -0
- package/dist/transport/noble.d.ts.map +1 -0
- package/dist/transport/noble.js +256 -0
- package/dist/transport/noble.js.map +1 -0
- package/dist/transport/types.d.ts +36 -0
- package/dist/transport/types.d.ts.map +1 -0
- package/dist/transport/types.js +1 -0
- package/dist/transport/types.js.map +1 -0
- package/dist/transport/web-bluetooth.d.ts +58 -0
- package/dist/transport/web-bluetooth.d.ts.map +1 -0
- package/dist/transport/web-bluetooth.js +164 -0
- package/dist/transport/web-bluetooth.js.map +1 -0
- package/dist/ui/FacewearAppView.d.ts +4 -0
- package/dist/ui/FacewearAppView.d.ts.map +1 -0
- package/dist/ui/FacewearAppView.js +257 -0
- package/dist/ui/FacewearAppView.js.map +1 -0
- package/dist/ui/SmartglassesView.d.ts +10 -0
- package/dist/ui/SmartglassesView.d.ts.map +1 -0
- package/dist/ui/SmartglassesView.helpers.d.ts +104 -0
- package/dist/ui/SmartglassesView.helpers.d.ts.map +1 -0
- package/dist/ui/SmartglassesView.helpers.js +261 -0
- package/dist/ui/SmartglassesView.helpers.js.map +1 -0
- package/dist/ui/SmartglassesView.js +1189 -0
- package/dist/ui/SmartglassesView.js.map +1 -0
- package/dist/ui/facewear-view-bundle.d.ts +5 -0
- package/dist/ui/facewear-view-bundle.d.ts.map +1 -0
- package/dist/ui/facewear-view-bundle.js +17 -0
- package/dist/ui/facewear-view-bundle.js.map +1 -0
- package/dist/views/bundle.js +2950 -0
- package/dist/views/bundle.js.map +1 -0
- package/package.json +5 -5
|
@@ -0,0 +1,1485 @@
|
|
|
1
|
+
const EVEN_G1_UART = {
|
|
2
|
+
service: "6e400001-b5a3-f393-e0a9-e50e24dcca9e",
|
|
3
|
+
tx: "6e400002-b5a3-f393-e0a9-e50e24dcca9e",
|
|
4
|
+
rx: "6e400003-b5a3-f393-e0a9-e50e24dcca9e"
|
|
5
|
+
};
|
|
6
|
+
var G1Command = /* @__PURE__ */ ((G1Command2) => {
|
|
7
|
+
G1Command2[G1Command2["StartAi"] = 245] = "StartAi";
|
|
8
|
+
G1Command2[G1Command2["OpenMic"] = 14] = "OpenMic";
|
|
9
|
+
G1Command2[G1Command2["ReceiveMicData"] = 241] = "ReceiveMicData";
|
|
10
|
+
G1Command2[G1Command2["Init"] = 77] = "Init";
|
|
11
|
+
G1Command2[G1Command2["RightInit"] = 244] = "RightInit";
|
|
12
|
+
G1Command2[G1Command2["Heartbeat"] = 37] = "Heartbeat";
|
|
13
|
+
G1Command2[G1Command2["Battery"] = 44] = "Battery";
|
|
14
|
+
G1Command2[G1Command2["SendResult"] = 78] = "SendResult";
|
|
15
|
+
G1Command2[G1Command2["QuickNote"] = 33] = "QuickNote";
|
|
16
|
+
G1Command2[G1Command2["Dashboard"] = 34] = "Dashboard";
|
|
17
|
+
G1Command2[G1Command2["Notification"] = 75] = "Notification";
|
|
18
|
+
G1Command2[G1Command2["DashboardContent"] = 6] = "DashboardContent";
|
|
19
|
+
G1Command2[G1Command2["Navigation"] = 10] = "Navigation";
|
|
20
|
+
G1Command2[G1Command2["TranslateSetup"] = 57] = "TranslateSetup";
|
|
21
|
+
G1Command2[G1Command2["TranslateStart"] = 80] = "TranslateStart";
|
|
22
|
+
G1Command2[G1Command2["TranslateLanguages"] = 28] = "TranslateLanguages";
|
|
23
|
+
G1Command2[G1Command2["TranslateOriginalText"] = 15] = "TranslateOriginalText";
|
|
24
|
+
G1Command2[G1Command2["TranslateTranslatedText"] = 13] = "TranslateTranslatedText";
|
|
25
|
+
G1Command2[G1Command2["AppWhitelist"] = 4] = "AppWhitelist";
|
|
26
|
+
G1Command2[G1Command2["ExitFunction"] = 24] = "ExitFunction";
|
|
27
|
+
G1Command2[G1Command2["SilentMode"] = 3] = "SilentMode";
|
|
28
|
+
G1Command2[G1Command2["Brightness"] = 1] = "Brightness";
|
|
29
|
+
G1Command2[G1Command2["DashboardPosition"] = 38] = "DashboardPosition";
|
|
30
|
+
G1Command2[G1Command2["HeadUpAngle"] = 11] = "HeadUpAngle";
|
|
31
|
+
G1Command2[G1Command2["GlassesWear"] = 39] = "GlassesWear";
|
|
32
|
+
G1Command2[G1Command2["BmpData"] = 21] = "BmpData";
|
|
33
|
+
G1Command2[G1Command2["BmpCrc"] = 22] = "BmpCrc";
|
|
34
|
+
G1Command2[G1Command2["BmpEnd"] = 32] = "BmpEnd";
|
|
35
|
+
G1Command2[G1Command2["Note"] = 30] = "Note";
|
|
36
|
+
G1Command2[G1Command2["GetSerial"] = 52] = "GetSerial";
|
|
37
|
+
return G1Command2;
|
|
38
|
+
})(G1Command || {});
|
|
39
|
+
var G1DashboardLayout = /* @__PURE__ */ ((G1DashboardLayout2) => {
|
|
40
|
+
G1DashboardLayout2["Full"] = "full";
|
|
41
|
+
G1DashboardLayout2["Dual"] = "dual";
|
|
42
|
+
G1DashboardLayout2["Minimal"] = "minimal";
|
|
43
|
+
return G1DashboardLayout2;
|
|
44
|
+
})(G1DashboardLayout || {});
|
|
45
|
+
var G1WeatherIcon = /* @__PURE__ */ ((G1WeatherIcon2) => {
|
|
46
|
+
G1WeatherIcon2[G1WeatherIcon2["Nothing"] = 0] = "Nothing";
|
|
47
|
+
G1WeatherIcon2[G1WeatherIcon2["Night"] = 1] = "Night";
|
|
48
|
+
G1WeatherIcon2[G1WeatherIcon2["Clouds"] = 2] = "Clouds";
|
|
49
|
+
G1WeatherIcon2[G1WeatherIcon2["Drizzle"] = 3] = "Drizzle";
|
|
50
|
+
G1WeatherIcon2[G1WeatherIcon2["HeavyDrizzle"] = 4] = "HeavyDrizzle";
|
|
51
|
+
G1WeatherIcon2[G1WeatherIcon2["Rain"] = 5] = "Rain";
|
|
52
|
+
G1WeatherIcon2[G1WeatherIcon2["HeavyRain"] = 6] = "HeavyRain";
|
|
53
|
+
G1WeatherIcon2[G1WeatherIcon2["Thunder"] = 7] = "Thunder";
|
|
54
|
+
G1WeatherIcon2[G1WeatherIcon2["Thunderstorm"] = 8] = "Thunderstorm";
|
|
55
|
+
G1WeatherIcon2[G1WeatherIcon2["Snow"] = 9] = "Snow";
|
|
56
|
+
G1WeatherIcon2[G1WeatherIcon2["Mist"] = 10] = "Mist";
|
|
57
|
+
G1WeatherIcon2[G1WeatherIcon2["Fog"] = 11] = "Fog";
|
|
58
|
+
G1WeatherIcon2[G1WeatherIcon2["Sand"] = 12] = "Sand";
|
|
59
|
+
G1WeatherIcon2[G1WeatherIcon2["Squalls"] = 13] = "Squalls";
|
|
60
|
+
G1WeatherIcon2[G1WeatherIcon2["Tornado"] = 14] = "Tornado";
|
|
61
|
+
G1WeatherIcon2[G1WeatherIcon2["FreezingRain"] = 15] = "FreezingRain";
|
|
62
|
+
G1WeatherIcon2[G1WeatherIcon2["Sunny"] = 16] = "Sunny";
|
|
63
|
+
return G1WeatherIcon2;
|
|
64
|
+
})(G1WeatherIcon || {});
|
|
65
|
+
var G1TemperatureUnit = /* @__PURE__ */ ((G1TemperatureUnit2) => {
|
|
66
|
+
G1TemperatureUnit2["Celsius"] = "celsius";
|
|
67
|
+
G1TemperatureUnit2["Fahrenheit"] = "fahrenheit";
|
|
68
|
+
return G1TemperatureUnit2;
|
|
69
|
+
})(G1TemperatureUnit || {});
|
|
70
|
+
var G1TimeFormat = /* @__PURE__ */ ((G1TimeFormat2) => {
|
|
71
|
+
G1TimeFormat2["TwentyFourHour"] = "24h";
|
|
72
|
+
G1TimeFormat2["TwelveHour"] = "12h";
|
|
73
|
+
return G1TimeFormat2;
|
|
74
|
+
})(G1TimeFormat || {});
|
|
75
|
+
var G1NavigationTurn = /* @__PURE__ */ ((G1NavigationTurn2) => {
|
|
76
|
+
G1NavigationTurn2[G1NavigationTurn2["StraightDot"] = 1] = "StraightDot";
|
|
77
|
+
G1NavigationTurn2[G1NavigationTurn2["Straight"] = 2] = "Straight";
|
|
78
|
+
G1NavigationTurn2[G1NavigationTurn2["Right"] = 3] = "Right";
|
|
79
|
+
G1NavigationTurn2[G1NavigationTurn2["Left"] = 4] = "Left";
|
|
80
|
+
G1NavigationTurn2[G1NavigationTurn2["SlightRight"] = 5] = "SlightRight";
|
|
81
|
+
G1NavigationTurn2[G1NavigationTurn2["SlightLeft"] = 6] = "SlightLeft";
|
|
82
|
+
G1NavigationTurn2[G1NavigationTurn2["StrongRight"] = 7] = "StrongRight";
|
|
83
|
+
G1NavigationTurn2[G1NavigationTurn2["StrongLeft"] = 8] = "StrongLeft";
|
|
84
|
+
G1NavigationTurn2[G1NavigationTurn2["UTurnLeft"] = 9] = "UTurnLeft";
|
|
85
|
+
G1NavigationTurn2[G1NavigationTurn2["UTurnRight"] = 10] = "UTurnRight";
|
|
86
|
+
G1NavigationTurn2[G1NavigationTurn2["Merge"] = 11] = "Merge";
|
|
87
|
+
G1NavigationTurn2[G1NavigationTurn2["SlightRightAtFork"] = 34] = "SlightRightAtFork";
|
|
88
|
+
G1NavigationTurn2[G1NavigationTurn2["SlightLeftAtFork"] = 35] = "SlightLeftAtFork";
|
|
89
|
+
return G1NavigationTurn2;
|
|
90
|
+
})(G1NavigationTurn || {});
|
|
91
|
+
var G1TranslateLanguage = /* @__PURE__ */ ((G1TranslateLanguage2) => {
|
|
92
|
+
G1TranslateLanguage2[G1TranslateLanguage2["Chinese"] = 1] = "Chinese";
|
|
93
|
+
G1TranslateLanguage2[G1TranslateLanguage2["English"] = 2] = "English";
|
|
94
|
+
G1TranslateLanguage2[G1TranslateLanguage2["French"] = 5] = "French";
|
|
95
|
+
G1TranslateLanguage2[G1TranslateLanguage2["Dutch"] = 9] = "Dutch";
|
|
96
|
+
return G1TranslateLanguage2;
|
|
97
|
+
})(G1TranslateLanguage || {});
|
|
98
|
+
var G1SubCommand = /* @__PURE__ */ ((G1SubCommand2) => {
|
|
99
|
+
G1SubCommand2[G1SubCommand2["Exit"] = 0] = "Exit";
|
|
100
|
+
G1SubCommand2[G1SubCommand2["PageControl"] = 1] = "PageControl";
|
|
101
|
+
G1SubCommand2[G1SubCommand2["Start"] = 23] = "Start";
|
|
102
|
+
G1SubCommand2[G1SubCommand2["Stop"] = 24] = "Stop";
|
|
103
|
+
return G1SubCommand2;
|
|
104
|
+
})(G1SubCommand || {});
|
|
105
|
+
var G1MicStatus = /* @__PURE__ */ ((G1MicStatus2) => {
|
|
106
|
+
G1MicStatus2[G1MicStatus2["Disable"] = 0] = "Disable";
|
|
107
|
+
G1MicStatus2[G1MicStatus2["Enable"] = 1] = "Enable";
|
|
108
|
+
return G1MicStatus2;
|
|
109
|
+
})(G1MicStatus || {});
|
|
110
|
+
var G1ResponseStatus = /* @__PURE__ */ ((G1ResponseStatus2) => {
|
|
111
|
+
G1ResponseStatus2[G1ResponseStatus2["Success"] = 201] = "Success";
|
|
112
|
+
G1ResponseStatus2[G1ResponseStatus2["Failure"] = 202] = "Failure";
|
|
113
|
+
return G1ResponseStatus2;
|
|
114
|
+
})(G1ResponseStatus || {});
|
|
115
|
+
var G1ScreenAction = /* @__PURE__ */ ((G1ScreenAction2) => {
|
|
116
|
+
G1ScreenAction2[G1ScreenAction2["NewContent"] = 1] = "NewContent";
|
|
117
|
+
return G1ScreenAction2;
|
|
118
|
+
})(G1ScreenAction || {});
|
|
119
|
+
var G1AiStatus = /* @__PURE__ */ ((G1AiStatus2) => {
|
|
120
|
+
G1AiStatus2[G1AiStatus2["Displaying"] = 48] = "Displaying";
|
|
121
|
+
G1AiStatus2[G1AiStatus2["DisplayComplete"] = 64] = "DisplayComplete";
|
|
122
|
+
G1AiStatus2[G1AiStatus2["ManualMode"] = 80] = "ManualMode";
|
|
123
|
+
G1AiStatus2[G1AiStatus2["NetworkError"] = 96] = "NetworkError";
|
|
124
|
+
return G1AiStatus2;
|
|
125
|
+
})(G1AiStatus || {});
|
|
126
|
+
var G1TextStatus = /* @__PURE__ */ ((G1TextStatus2) => {
|
|
127
|
+
G1TextStatus2[G1TextStatus2["TextShow"] = 112] = "TextShow";
|
|
128
|
+
return G1TextStatus2;
|
|
129
|
+
})(G1TextStatus || {});
|
|
130
|
+
var G1SilentModeStatus = /* @__PURE__ */ ((G1SilentModeStatus2) => {
|
|
131
|
+
G1SilentModeStatus2[G1SilentModeStatus2["Off"] = 10] = "Off";
|
|
132
|
+
G1SilentModeStatus2[G1SilentModeStatus2["On"] = 12] = "On";
|
|
133
|
+
return G1SilentModeStatus2;
|
|
134
|
+
})(G1SilentModeStatus || {});
|
|
135
|
+
var G1DashboardState = /* @__PURE__ */ ((G1DashboardState2) => {
|
|
136
|
+
G1DashboardState2[G1DashboardState2["Off"] = 0] = "Off";
|
|
137
|
+
G1DashboardState2[G1DashboardState2["On"] = 1] = "On";
|
|
138
|
+
return G1DashboardState2;
|
|
139
|
+
})(G1DashboardState || {});
|
|
140
|
+
var G1GlassesWearStatus = /* @__PURE__ */ ((G1GlassesWearStatus2) => {
|
|
141
|
+
G1GlassesWearStatus2[G1GlassesWearStatus2["Off"] = 0] = "Off";
|
|
142
|
+
G1GlassesWearStatus2[G1GlassesWearStatus2["On"] = 1] = "On";
|
|
143
|
+
return G1GlassesWearStatus2;
|
|
144
|
+
})(G1GlassesWearStatus || {});
|
|
145
|
+
var G1VoiceNoteSubCommand = /* @__PURE__ */ ((G1VoiceNoteSubCommand2) => {
|
|
146
|
+
G1VoiceNoteSubCommand2[G1VoiceNoteSubCommand2["RequestAudioInfo"] = 1] = "RequestAudioInfo";
|
|
147
|
+
G1VoiceNoteSubCommand2[G1VoiceNoteSubCommand2["RequestAudioData"] = 2] = "RequestAudioData";
|
|
148
|
+
G1VoiceNoteSubCommand2[G1VoiceNoteSubCommand2["DeleteAudioStream"] = 4] = "DeleteAudioStream";
|
|
149
|
+
G1VoiceNoteSubCommand2[G1VoiceNoteSubCommand2["DeleteAll"] = 5] = "DeleteAll";
|
|
150
|
+
return G1VoiceNoteSubCommand2;
|
|
151
|
+
})(G1VoiceNoteSubCommand || {});
|
|
152
|
+
var G1InteractionCode = /* @__PURE__ */ ((G1InteractionCode2) => {
|
|
153
|
+
G1InteractionCode2[G1InteractionCode2["DoubleTap"] = 0] = "DoubleTap";
|
|
154
|
+
G1InteractionCode2[G1InteractionCode2["SingleTap"] = 1] = "SingleTap";
|
|
155
|
+
G1InteractionCode2[G1InteractionCode2["LongPress"] = 23] = "LongPress";
|
|
156
|
+
G1InteractionCode2[G1InteractionCode2["StopAiRecording"] = 24] = "StopAiRecording";
|
|
157
|
+
G1InteractionCode2[G1InteractionCode2["SilentModeOn"] = 4] = "SilentModeOn";
|
|
158
|
+
G1InteractionCode2[G1InteractionCode2["SilentModeOff"] = 5] = "SilentModeOff";
|
|
159
|
+
G1InteractionCode2[G1InteractionCode2["OpenDashboardStart"] = 2] = "OpenDashboardStart";
|
|
160
|
+
G1InteractionCode2[G1InteractionCode2["CloseDashboardStart"] = 3] = "CloseDashboardStart";
|
|
161
|
+
G1InteractionCode2[G1InteractionCode2["OpenDashboardConfirm"] = 30] = "OpenDashboardConfirm";
|
|
162
|
+
G1InteractionCode2[G1InteractionCode2["CloseDashboardConfirm"] = 31] = "CloseDashboardConfirm";
|
|
163
|
+
return G1InteractionCode2;
|
|
164
|
+
})(G1InteractionCode || {});
|
|
165
|
+
function microphoneActionForInteractionEvent(event) {
|
|
166
|
+
if (event.type !== "state") return null;
|
|
167
|
+
if (event.label === "single_tap" || event.label === "long_press") {
|
|
168
|
+
return "enable";
|
|
169
|
+
}
|
|
170
|
+
if (event.label === "double_tap" || event.label === "stop_ai_recording") {
|
|
171
|
+
return "disable";
|
|
172
|
+
}
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
const G1_DISPLAY = {
|
|
176
|
+
displayWidthPx: 576,
|
|
177
|
+
charsPerLine: 40,
|
|
178
|
+
linesPerPage: 5,
|
|
179
|
+
maxTextLength: 40 * 5,
|
|
180
|
+
maxPayloadBytes: 191
|
|
181
|
+
};
|
|
182
|
+
const G1_GLYPH_WIDTHS = new Map(
|
|
183
|
+
Object.entries({
|
|
184
|
+
" ": 2,
|
|
185
|
+
"!": 1,
|
|
186
|
+
'"': 2,
|
|
187
|
+
"#": 6,
|
|
188
|
+
$: 5,
|
|
189
|
+
"%": 6,
|
|
190
|
+
"&": 7,
|
|
191
|
+
"'": 1,
|
|
192
|
+
"(": 2,
|
|
193
|
+
")": 2,
|
|
194
|
+
"*": 3,
|
|
195
|
+
"+": 4,
|
|
196
|
+
",": 1,
|
|
197
|
+
"-": 4,
|
|
198
|
+
".": 1,
|
|
199
|
+
"/": 3,
|
|
200
|
+
"0": 5,
|
|
201
|
+
"1": 3,
|
|
202
|
+
"2": 5,
|
|
203
|
+
"3": 5,
|
|
204
|
+
"4": 5,
|
|
205
|
+
"5": 5,
|
|
206
|
+
"6": 5,
|
|
207
|
+
"7": 5,
|
|
208
|
+
"8": 5,
|
|
209
|
+
"9": 5,
|
|
210
|
+
":": 1,
|
|
211
|
+
";": 1,
|
|
212
|
+
"<": 4,
|
|
213
|
+
"=": 4,
|
|
214
|
+
">": 4,
|
|
215
|
+
"?": 5,
|
|
216
|
+
"@": 7,
|
|
217
|
+
A: 6,
|
|
218
|
+
B: 5,
|
|
219
|
+
C: 5,
|
|
220
|
+
D: 5,
|
|
221
|
+
E: 4,
|
|
222
|
+
F: 4,
|
|
223
|
+
G: 5,
|
|
224
|
+
H: 5,
|
|
225
|
+
I: 2,
|
|
226
|
+
J: 3,
|
|
227
|
+
K: 5,
|
|
228
|
+
L: 4,
|
|
229
|
+
M: 7,
|
|
230
|
+
N: 5,
|
|
231
|
+
O: 5,
|
|
232
|
+
P: 5,
|
|
233
|
+
Q: 5,
|
|
234
|
+
R: 5,
|
|
235
|
+
S: 5,
|
|
236
|
+
T: 5,
|
|
237
|
+
U: 5,
|
|
238
|
+
V: 6,
|
|
239
|
+
W: 7,
|
|
240
|
+
X: 6,
|
|
241
|
+
Y: 6,
|
|
242
|
+
Z: 5,
|
|
243
|
+
"[": 2,
|
|
244
|
+
"\\": 3,
|
|
245
|
+
"]": 2,
|
|
246
|
+
"^": 4,
|
|
247
|
+
_: 3,
|
|
248
|
+
"`": 2,
|
|
249
|
+
a: 5,
|
|
250
|
+
b: 4,
|
|
251
|
+
c: 4,
|
|
252
|
+
d: 4,
|
|
253
|
+
e: 4,
|
|
254
|
+
f: 4,
|
|
255
|
+
g: 4,
|
|
256
|
+
h: 4,
|
|
257
|
+
i: 1,
|
|
258
|
+
j: 2,
|
|
259
|
+
k: 4,
|
|
260
|
+
l: 1,
|
|
261
|
+
m: 7,
|
|
262
|
+
n: 4,
|
|
263
|
+
o: 4,
|
|
264
|
+
p: 4,
|
|
265
|
+
q: 4,
|
|
266
|
+
r: 3,
|
|
267
|
+
s: 4,
|
|
268
|
+
t: 3,
|
|
269
|
+
u: 5,
|
|
270
|
+
v: 5,
|
|
271
|
+
w: 7,
|
|
272
|
+
x: 5,
|
|
273
|
+
y: 5,
|
|
274
|
+
z: 4,
|
|
275
|
+
"{": 3,
|
|
276
|
+
"|": 1,
|
|
277
|
+
"}": 3,
|
|
278
|
+
"~": 7
|
|
279
|
+
})
|
|
280
|
+
);
|
|
281
|
+
const G1_BMP = {
|
|
282
|
+
width: 576,
|
|
283
|
+
height: 136,
|
|
284
|
+
bitsPerPixel: 1
|
|
285
|
+
};
|
|
286
|
+
const INTERACTION_LABELS = /* @__PURE__ */ new Map([
|
|
287
|
+
[0 /* DoubleTap */, "double_tap"],
|
|
288
|
+
[1 /* SingleTap */, "single_tap"],
|
|
289
|
+
[23 /* LongPress */, "long_press"],
|
|
290
|
+
[24 /* StopAiRecording */, "stop_ai_recording"],
|
|
291
|
+
[4 /* SilentModeOn */, "silent_mode_on"],
|
|
292
|
+
[5 /* SilentModeOff */, "silent_mode_off"],
|
|
293
|
+
[2 /* OpenDashboardStart */, "open_dashboard_start"],
|
|
294
|
+
[3 /* CloseDashboardStart */, "close_dashboard_start"],
|
|
295
|
+
[30 /* OpenDashboardConfirm */, "open_dashboard_confirm"],
|
|
296
|
+
[31 /* CloseDashboardConfirm */, "close_dashboard_confirm"]
|
|
297
|
+
]);
|
|
298
|
+
const PHYSICAL_LABELS = /* @__PURE__ */ new Map([
|
|
299
|
+
[6, "wearing"],
|
|
300
|
+
[7, "transitioning"],
|
|
301
|
+
[8, "cradle_open"],
|
|
302
|
+
[9, "charged_in_cradle"],
|
|
303
|
+
[11, "cradle_closed"]
|
|
304
|
+
]);
|
|
305
|
+
const BATTERY_LABELS = /* @__PURE__ */ new Map([
|
|
306
|
+
[9, "glasses_fully_charged"],
|
|
307
|
+
[14, "cradle_charging_cable_changed"],
|
|
308
|
+
[15, "cradle_fully_charged"]
|
|
309
|
+
]);
|
|
310
|
+
const DEVICE_LABELS = /* @__PURE__ */ new Map([
|
|
311
|
+
[10, "device_unknown_0a"],
|
|
312
|
+
[17, "connected"],
|
|
313
|
+
[18, "device_unknown_12"],
|
|
314
|
+
[20, "device_unknown_14"],
|
|
315
|
+
[21, "device_unknown_15"]
|
|
316
|
+
]);
|
|
317
|
+
function classifyStateCode(code) {
|
|
318
|
+
if (code === void 0) return null;
|
|
319
|
+
const interaction = INTERACTION_LABELS.get(code);
|
|
320
|
+
if (interaction)
|
|
321
|
+
return { category: "interaction", label: interaction, name: interaction };
|
|
322
|
+
const physical = PHYSICAL_LABELS.get(code);
|
|
323
|
+
if (physical)
|
|
324
|
+
return { category: "physical", label: physical, name: physical };
|
|
325
|
+
const battery = BATTERY_LABELS.get(code);
|
|
326
|
+
if (battery) return { category: "battery", label: battery, name: battery };
|
|
327
|
+
const device = DEVICE_LABELS.get(code);
|
|
328
|
+
if (device) return { category: "device", label: device, name: device };
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
function measureG1DisplayText(text) {
|
|
332
|
+
let width = 0;
|
|
333
|
+
for (const char of text) width += measureG1DisplayChar(char);
|
|
334
|
+
return width;
|
|
335
|
+
}
|
|
336
|
+
function measureG1DisplayChar(char) {
|
|
337
|
+
const codePoint = char.codePointAt(0) ?? 0;
|
|
338
|
+
if (isKorean(codePoint)) return 24;
|
|
339
|
+
if (isCjk(codePoint) || isHiragana(codePoint) || isKatakana(codePoint))
|
|
340
|
+
return 18;
|
|
341
|
+
if (isCyrillic(codePoint)) return 18;
|
|
342
|
+
const glyphWidth = G1_GLYPH_WIDTHS.get(char);
|
|
343
|
+
return glyphWidth === void 0 ? 16 : (glyphWidth + 1) * 2;
|
|
344
|
+
}
|
|
345
|
+
function isCjk(codePoint) {
|
|
346
|
+
return codePoint >= 13312 && codePoint <= 19903 || codePoint >= 19968 && codePoint <= 40959 || codePoint >= 63744 && codePoint <= 64255;
|
|
347
|
+
}
|
|
348
|
+
function isHiragana(codePoint) {
|
|
349
|
+
return codePoint >= 12352 && codePoint <= 12447;
|
|
350
|
+
}
|
|
351
|
+
function isKatakana(codePoint) {
|
|
352
|
+
return codePoint >= 12448 && codePoint <= 12543;
|
|
353
|
+
}
|
|
354
|
+
function isKorean(codePoint) {
|
|
355
|
+
return codePoint >= 44032 && codePoint <= 55215;
|
|
356
|
+
}
|
|
357
|
+
function isCyrillic(codePoint) {
|
|
358
|
+
return codePoint >= 1024 && codePoint <= 1279;
|
|
359
|
+
}
|
|
360
|
+
function fitsG1DisplayLine(text, maxWidthPx) {
|
|
361
|
+
return measureG1DisplayText(text) <= maxWidthPx;
|
|
362
|
+
}
|
|
363
|
+
function formatDisplayLines(text, options = {}) {
|
|
364
|
+
const charsPerLine = typeof options === "number" ? options : options.charsPerLine;
|
|
365
|
+
const maxWidthPx = typeof options === "number" ? void 0 : options.maxWidthPx ?? G1_DISPLAY.displayWidthPx;
|
|
366
|
+
if (charsPerLine !== void 0)
|
|
367
|
+
return formatDisplayLinesByCharacters(text, charsPerLine);
|
|
368
|
+
return formatDisplayLinesByPixels(
|
|
369
|
+
text,
|
|
370
|
+
maxWidthPx ?? G1_DISPLAY.displayWidthPx
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
function formatDisplayLinesByCharacters(text, charsPerLine) {
|
|
374
|
+
const lines = [];
|
|
375
|
+
for (const paragraph of text.split(/\r?\n/).map((p) => p.trim()).filter(Boolean)) {
|
|
376
|
+
let rest = paragraph;
|
|
377
|
+
while (rest.length > charsPerLine) {
|
|
378
|
+
let splitAt = rest.lastIndexOf(" ", charsPerLine);
|
|
379
|
+
if (splitAt < 1) splitAt = charsPerLine;
|
|
380
|
+
lines.push(rest.slice(0, splitAt).trimEnd());
|
|
381
|
+
rest = rest.slice(splitAt).trimStart();
|
|
382
|
+
}
|
|
383
|
+
if (rest) lines.push(rest);
|
|
384
|
+
}
|
|
385
|
+
return lines.length ? lines : [""];
|
|
386
|
+
}
|
|
387
|
+
function formatDisplayLinesByPixels(text, maxWidthPx) {
|
|
388
|
+
const lines = [];
|
|
389
|
+
for (const paragraph of text.split(/\r?\n/)) {
|
|
390
|
+
const trimmed = paragraph.trim();
|
|
391
|
+
if (!trimmed) {
|
|
392
|
+
if (lines.length > 0) lines.push("");
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
lines.push(...wrapDisplayParagraphByPixels(trimmed, maxWidthPx));
|
|
396
|
+
}
|
|
397
|
+
return lines.length ? lines : [""];
|
|
398
|
+
}
|
|
399
|
+
function wrapDisplayParagraphByPixels(paragraph, maxWidthPx) {
|
|
400
|
+
if (fitsG1DisplayLine(paragraph, maxWidthPx)) return [paragraph];
|
|
401
|
+
const lines = [];
|
|
402
|
+
let current = "";
|
|
403
|
+
for (const word of paragraph.split(/\s+/).filter(Boolean)) {
|
|
404
|
+
const candidate = current ? `${current} ${word}` : word;
|
|
405
|
+
if (fitsG1DisplayLine(candidate, maxWidthPx)) {
|
|
406
|
+
current = candidate;
|
|
407
|
+
continue;
|
|
408
|
+
}
|
|
409
|
+
if (current) {
|
|
410
|
+
lines.push(current);
|
|
411
|
+
current = "";
|
|
412
|
+
}
|
|
413
|
+
const wordLines = breakDisplayTokenByPixels(word, maxWidthPx);
|
|
414
|
+
lines.push(...wordLines.slice(0, -1));
|
|
415
|
+
current = wordLines.at(-1) ?? "";
|
|
416
|
+
}
|
|
417
|
+
if (current) lines.push(current);
|
|
418
|
+
return lines;
|
|
419
|
+
}
|
|
420
|
+
function breakDisplayTokenByPixels(token, maxWidthPx) {
|
|
421
|
+
const lines = [];
|
|
422
|
+
let current = "";
|
|
423
|
+
for (const char of Array.from(token)) {
|
|
424
|
+
const candidate = current + char;
|
|
425
|
+
if (fitsG1DisplayLine(candidate, maxWidthPx)) {
|
|
426
|
+
current = candidate;
|
|
427
|
+
continue;
|
|
428
|
+
}
|
|
429
|
+
if (current) lines.push(current);
|
|
430
|
+
current = char;
|
|
431
|
+
}
|
|
432
|
+
if (current) lines.push(current);
|
|
433
|
+
return lines.length ? lines : [""];
|
|
434
|
+
}
|
|
435
|
+
function paginateDisplayText(text, options = {}) {
|
|
436
|
+
const charsPerLine = options.charsPerLine ?? G1_DISPLAY.charsPerLine;
|
|
437
|
+
const linesPerPage = options.linesPerPage ?? G1_DISPLAY.linesPerPage;
|
|
438
|
+
const lines = formatDisplayLines(
|
|
439
|
+
text,
|
|
440
|
+
options.charsPerLine === void 0 ? { maxWidthPx: G1_DISPLAY.displayWidthPx } : { charsPerLine }
|
|
441
|
+
);
|
|
442
|
+
const maxPages = Math.max(1, Math.ceil(lines.length / linesPerPage));
|
|
443
|
+
const pages = [];
|
|
444
|
+
for (let pageIndex = 0; pageIndex < maxPages; pageIndex++) {
|
|
445
|
+
const pageLines = lines.slice(
|
|
446
|
+
pageIndex * linesPerPage,
|
|
447
|
+
(pageIndex + 1) * linesPerPage
|
|
448
|
+
);
|
|
449
|
+
const missing = linesPerPage - pageLines.length;
|
|
450
|
+
if (missing > 0) {
|
|
451
|
+
const before = Math.floor(missing / 2);
|
|
452
|
+
const after = missing - before;
|
|
453
|
+
pageLines.unshift(...Array.from({ length: before }, () => ""));
|
|
454
|
+
pageLines.push(...Array.from({ length: after }, () => ""));
|
|
455
|
+
}
|
|
456
|
+
pages.push({
|
|
457
|
+
pageNumber: pageIndex + 1,
|
|
458
|
+
maxPages,
|
|
459
|
+
text: pageLines.join("\n"),
|
|
460
|
+
screenStatus: pageIndex === maxPages - 1 ? 64 /* DisplayComplete */ : 48 /* Displaying */ | 1 /* NewContent */
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
return pages;
|
|
464
|
+
}
|
|
465
|
+
function encodeTextPacket(page, seq = 0) {
|
|
466
|
+
const data = new TextEncoder().encode(page.text);
|
|
467
|
+
if (data.byteLength > G1_DISPLAY.maxPayloadBytes) {
|
|
468
|
+
throw new RangeError(
|
|
469
|
+
`G1 display payload is ${data.byteLength} bytes; use encodeTextPackets for payloads over ${G1_DISPLAY.maxPayloadBytes} bytes`
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
return encodeTextPacketChunk(page, data, seq, 1, 0);
|
|
473
|
+
}
|
|
474
|
+
function encodeTextPackets(page, seq = 0) {
|
|
475
|
+
const chunks = splitUtf8Chunks(page.text, G1_DISPLAY.maxPayloadBytes);
|
|
476
|
+
const totalPackages = chunks.length;
|
|
477
|
+
const packets = [];
|
|
478
|
+
let charPosition = 0;
|
|
479
|
+
for (const [currentPackage, chunk] of chunks.entries()) {
|
|
480
|
+
packets.push(
|
|
481
|
+
encodeTextPacketChunk(
|
|
482
|
+
page,
|
|
483
|
+
chunk,
|
|
484
|
+
seq,
|
|
485
|
+
totalPackages,
|
|
486
|
+
currentPackage,
|
|
487
|
+
charPosition
|
|
488
|
+
)
|
|
489
|
+
);
|
|
490
|
+
charPosition += chunk.length;
|
|
491
|
+
}
|
|
492
|
+
return packets;
|
|
493
|
+
}
|
|
494
|
+
function splitUtf8Chunks(text, maxBytes) {
|
|
495
|
+
const encoder = new TextEncoder();
|
|
496
|
+
if (text.length === 0) return [new Uint8Array()];
|
|
497
|
+
const chunks = [];
|
|
498
|
+
let current = "";
|
|
499
|
+
for (const char of text) {
|
|
500
|
+
const next = current + char;
|
|
501
|
+
const nextBytes = encoder.encode(next);
|
|
502
|
+
if (nextBytes.byteLength > maxBytes && current) {
|
|
503
|
+
chunks.push(encoder.encode(current));
|
|
504
|
+
current = char;
|
|
505
|
+
continue;
|
|
506
|
+
}
|
|
507
|
+
if (nextBytes.byteLength > maxBytes) {
|
|
508
|
+
throw new RangeError(
|
|
509
|
+
`Single UTF-8 character exceeds G1 display packet payload limit of ${maxBytes} bytes`
|
|
510
|
+
);
|
|
511
|
+
}
|
|
512
|
+
current = next;
|
|
513
|
+
}
|
|
514
|
+
if (current || chunks.length === 0) chunks.push(encoder.encode(current));
|
|
515
|
+
return chunks;
|
|
516
|
+
}
|
|
517
|
+
function encodeTextPacketChunk(page, data, seq, totalPackages, currentPackage, charPosition = 0) {
|
|
518
|
+
const packet = new Uint8Array(9 + data.length);
|
|
519
|
+
packet.set([
|
|
520
|
+
78 /* SendResult */,
|
|
521
|
+
seq & 255,
|
|
522
|
+
totalPackages & 255,
|
|
523
|
+
currentPackage & 255,
|
|
524
|
+
page.screenStatus & 255,
|
|
525
|
+
charPosition >>> 8 & 255,
|
|
526
|
+
charPosition & 255,
|
|
527
|
+
page.pageNumber & 255,
|
|
528
|
+
page.maxPages & 255
|
|
529
|
+
]);
|
|
530
|
+
packet.set(data, 9);
|
|
531
|
+
return packet;
|
|
532
|
+
}
|
|
533
|
+
function encodeMicCommand(enabled) {
|
|
534
|
+
return Uint8Array.from([
|
|
535
|
+
14 /* OpenMic */,
|
|
536
|
+
enabled ? 1 /* Enable */ : 0 /* Disable */
|
|
537
|
+
]);
|
|
538
|
+
}
|
|
539
|
+
function encodeHeartbeat(seq) {
|
|
540
|
+
const s = seq & 255;
|
|
541
|
+
return Uint8Array.from([37 /* Heartbeat */, 6, 0, s, 4, s]);
|
|
542
|
+
}
|
|
543
|
+
function encodeBatteryStatusRequest() {
|
|
544
|
+
return Uint8Array.from([44 /* Battery */, 1]);
|
|
545
|
+
}
|
|
546
|
+
function encodeConnectionReady(side, mode = "lens-specific") {
|
|
547
|
+
return Uint8Array.from([
|
|
548
|
+
mode === "android-f4" ? 244 /* RightInit */ : mode === "official" || side === "left" ? 77 /* Init */ : 244 /* RightInit */,
|
|
549
|
+
1
|
|
550
|
+
]);
|
|
551
|
+
}
|
|
552
|
+
function encodeStartAi(subcommand, param = new Uint8Array()) {
|
|
553
|
+
const packet = new Uint8Array(2 + param.length);
|
|
554
|
+
packet.set([245 /* StartAi */, subcommand]);
|
|
555
|
+
packet.set(param, 2);
|
|
556
|
+
return packet;
|
|
557
|
+
}
|
|
558
|
+
function encodeExitFunction() {
|
|
559
|
+
return Uint8Array.from([24 /* ExitFunction */]);
|
|
560
|
+
}
|
|
561
|
+
function encodeGetSerial() {
|
|
562
|
+
return Uint8Array.from([52 /* GetSerial */]);
|
|
563
|
+
}
|
|
564
|
+
function encodeClearScreen() {
|
|
565
|
+
return Uint8Array.from([
|
|
566
|
+
245 /* StartAi */,
|
|
567
|
+
24 /* Stop */,
|
|
568
|
+
0,
|
|
569
|
+
0,
|
|
570
|
+
0
|
|
571
|
+
]);
|
|
572
|
+
}
|
|
573
|
+
function encodeSilentMode(enabled) {
|
|
574
|
+
return Uint8Array.from([
|
|
575
|
+
3 /* SilentMode */,
|
|
576
|
+
enabled ? 12 /* On */ : 10 /* Off */,
|
|
577
|
+
0
|
|
578
|
+
]);
|
|
579
|
+
}
|
|
580
|
+
function encodeBrightness(level, auto = false) {
|
|
581
|
+
if (!Number.isInteger(level) || level < 0 || level > 41) {
|
|
582
|
+
throw new RangeError(
|
|
583
|
+
"Brightness level must be an integer between 0 and 0x29"
|
|
584
|
+
);
|
|
585
|
+
}
|
|
586
|
+
return Uint8Array.from([
|
|
587
|
+
1 /* Brightness */,
|
|
588
|
+
level & 255,
|
|
589
|
+
auto ? 1 : 0
|
|
590
|
+
]);
|
|
591
|
+
}
|
|
592
|
+
function encodeDashboard(state, position = 0) {
|
|
593
|
+
if (!Number.isInteger(position) || position < 0 || position > 8) {
|
|
594
|
+
throw new RangeError(
|
|
595
|
+
"Dashboard position must be an integer between 0 and 8"
|
|
596
|
+
);
|
|
597
|
+
}
|
|
598
|
+
const stateValue = typeof state === "boolean" ? state ? 1 /* On */ : 0 /* Off */ : state;
|
|
599
|
+
return Uint8Array.from([
|
|
600
|
+
38 /* DashboardPosition */,
|
|
601
|
+
7,
|
|
602
|
+
0,
|
|
603
|
+
1,
|
|
604
|
+
2,
|
|
605
|
+
stateValue,
|
|
606
|
+
position & 255
|
|
607
|
+
]);
|
|
608
|
+
}
|
|
609
|
+
function encodeDashboardPosition(height, depth, seqId = 1) {
|
|
610
|
+
if (!Number.isInteger(height) || height < 0 || height > 8) {
|
|
611
|
+
throw new RangeError("Dashboard height must be an integer between 0 and 8");
|
|
612
|
+
}
|
|
613
|
+
if (!Number.isInteger(depth) || depth < 1 || depth > 9) {
|
|
614
|
+
throw new RangeError("Dashboard depth must be an integer between 1 and 9");
|
|
615
|
+
}
|
|
616
|
+
return Uint8Array.from([
|
|
617
|
+
38 /* DashboardPosition */,
|
|
618
|
+
8,
|
|
619
|
+
0,
|
|
620
|
+
seqId & 255,
|
|
621
|
+
2,
|
|
622
|
+
1,
|
|
623
|
+
height & 255,
|
|
624
|
+
depth & 255
|
|
625
|
+
]);
|
|
626
|
+
}
|
|
627
|
+
function encodeDashboardLayout(layout) {
|
|
628
|
+
const layoutBytes = layout === "full" /* Full */ ? [8, 6, 0, 0] : layout === "dual" /* Dual */ ? [30, 6, 1, 0] : [49, 6, 2, 0];
|
|
629
|
+
return Uint8Array.from([
|
|
630
|
+
6 /* DashboardContent */,
|
|
631
|
+
7,
|
|
632
|
+
0,
|
|
633
|
+
...layoutBytes
|
|
634
|
+
]);
|
|
635
|
+
}
|
|
636
|
+
function encodeDashboardCalendarItem(payload) {
|
|
637
|
+
const name = new TextEncoder().encode(payload.name);
|
|
638
|
+
const time = new TextEncoder().encode(payload.time);
|
|
639
|
+
const location = new TextEncoder().encode(payload.location);
|
|
640
|
+
for (const [field, bytes] of [
|
|
641
|
+
["name", name],
|
|
642
|
+
["time", time],
|
|
643
|
+
["location", location]
|
|
644
|
+
]) {
|
|
645
|
+
if (bytes.length > 255)
|
|
646
|
+
throw new RangeError(
|
|
647
|
+
`Dashboard calendar ${field} must be at most 255 bytes`
|
|
648
|
+
);
|
|
649
|
+
}
|
|
650
|
+
const prefix = [
|
|
651
|
+
0,
|
|
652
|
+
109,
|
|
653
|
+
3,
|
|
654
|
+
1,
|
|
655
|
+
0,
|
|
656
|
+
1,
|
|
657
|
+
0,
|
|
658
|
+
0,
|
|
659
|
+
0,
|
|
660
|
+
3,
|
|
661
|
+
1
|
|
662
|
+
];
|
|
663
|
+
const body = new Uint8Array(
|
|
664
|
+
prefix.length + 6 + name.length + time.length + location.length
|
|
665
|
+
);
|
|
666
|
+
let offset = 0;
|
|
667
|
+
body.set(prefix, offset);
|
|
668
|
+
offset += prefix.length;
|
|
669
|
+
body.set([1, name.length], offset);
|
|
670
|
+
offset += 2;
|
|
671
|
+
body.set(name, offset);
|
|
672
|
+
offset += name.length;
|
|
673
|
+
body.set([2, time.length], offset);
|
|
674
|
+
offset += 2;
|
|
675
|
+
body.set(time, offset);
|
|
676
|
+
offset += time.length;
|
|
677
|
+
body.set([3, location.length], offset);
|
|
678
|
+
offset += 2;
|
|
679
|
+
body.set(location, offset);
|
|
680
|
+
return Uint8Array.from([
|
|
681
|
+
6 /* DashboardContent */,
|
|
682
|
+
body.length + 2 & 255,
|
|
683
|
+
...body
|
|
684
|
+
]);
|
|
685
|
+
}
|
|
686
|
+
function encodeDashboardTimeWeather(payload) {
|
|
687
|
+
if (!Number.isInteger(payload.temperatureInCelsius) || payload.temperatureInCelsius < -128 || payload.temperatureInCelsius > 127) {
|
|
688
|
+
throw new RangeError("Dashboard temperature must fit in signed 8 bits");
|
|
689
|
+
}
|
|
690
|
+
const seqId = payload.seqId ?? 0;
|
|
691
|
+
const timestampMs = payload.timestampMs ?? Date.now();
|
|
692
|
+
const timezoneOffsetSeconds = payload.timezoneOffsetSeconds ?? -new Date(timestampMs).getTimezoneOffset() * 60;
|
|
693
|
+
const localMs = timestampMs + timezoneOffsetSeconds * 1e3;
|
|
694
|
+
const out = new Uint8Array(21);
|
|
695
|
+
const view = new DataView(out.buffer);
|
|
696
|
+
out.set([6 /* DashboardContent */, 21, 0, seqId & 255, 1]);
|
|
697
|
+
view.setUint32(5, Math.floor(localMs / 1e3), true);
|
|
698
|
+
view.setBigUint64(9, BigInt(Math.trunc(localMs)), true);
|
|
699
|
+
out[17] = (payload.weatherIcon ?? 0 /* Nothing */) & 255;
|
|
700
|
+
out[18] = payload.temperatureInCelsius & 255;
|
|
701
|
+
out[19] = payload.temperatureUnit === "fahrenheit" /* Fahrenheit */ ? 1 : 0;
|
|
702
|
+
out[20] = payload.timeFormat === "12h" /* TwelveHour */ ? 1 : 0;
|
|
703
|
+
return out;
|
|
704
|
+
}
|
|
705
|
+
function encodeHeadUpAngle(angle) {
|
|
706
|
+
if (!Number.isInteger(angle) || angle < 0 || angle > 60) {
|
|
707
|
+
throw new RangeError(
|
|
708
|
+
"Head-up display angle must be an integer between 0 and 60"
|
|
709
|
+
);
|
|
710
|
+
}
|
|
711
|
+
return Uint8Array.from([11 /* HeadUpAngle */, angle & 255, 1]);
|
|
712
|
+
}
|
|
713
|
+
function encodeG1Setup(payload) {
|
|
714
|
+
const text = typeof payload === "string" ? payload : JSON.stringify(payload);
|
|
715
|
+
const data = new TextEncoder().encode(text);
|
|
716
|
+
const maxPayload = 176;
|
|
717
|
+
const totalPackets = Math.max(1, Math.ceil(data.byteLength / maxPayload));
|
|
718
|
+
const packets = [];
|
|
719
|
+
for (let index = 0; index < totalPackets; index++) {
|
|
720
|
+
const chunk = data.slice(index * maxPayload, (index + 1) * maxPayload);
|
|
721
|
+
const packet = new Uint8Array(3 + chunk.length);
|
|
722
|
+
packet.set([4 /* AppWhitelist */, totalPackets & 255, index & 255]);
|
|
723
|
+
packet.set(chunk, 3);
|
|
724
|
+
packets.push(packet);
|
|
725
|
+
}
|
|
726
|
+
return packets;
|
|
727
|
+
}
|
|
728
|
+
function encodeNavigationInit(seqId) {
|
|
729
|
+
return Uint8Array.from([
|
|
730
|
+
10 /* Navigation */,
|
|
731
|
+
6,
|
|
732
|
+
0,
|
|
733
|
+
seqId & 255,
|
|
734
|
+
0,
|
|
735
|
+
1
|
|
736
|
+
]);
|
|
737
|
+
}
|
|
738
|
+
function encodeNavigationDirections(payload) {
|
|
739
|
+
const encoder = new TextEncoder();
|
|
740
|
+
const totalDuration = encoder.encode(payload.totalDuration);
|
|
741
|
+
const totalDistance = encoder.encode(payload.totalDistance);
|
|
742
|
+
const direction = encoder.encode(payload.direction);
|
|
743
|
+
const distance = encoder.encode(payload.distance);
|
|
744
|
+
const speed = encoder.encode(payload.speed);
|
|
745
|
+
const customX = payload.customX ?? [0, 0];
|
|
746
|
+
const body = new Uint8Array(
|
|
747
|
+
8 + totalDuration.length + totalDistance.length + direction.length + distance.length + speed.length + 5
|
|
748
|
+
);
|
|
749
|
+
let offset = 0;
|
|
750
|
+
body.set(
|
|
751
|
+
[
|
|
752
|
+
0,
|
|
753
|
+
payload.seqId & 255,
|
|
754
|
+
1,
|
|
755
|
+
payload.directionTurn & 255,
|
|
756
|
+
customX[0] ?? 0,
|
|
757
|
+
customX[1] ?? 0,
|
|
758
|
+
payload.customY ?? 0,
|
|
759
|
+
0
|
|
760
|
+
],
|
|
761
|
+
offset
|
|
762
|
+
);
|
|
763
|
+
offset += 8;
|
|
764
|
+
for (const bytes of [
|
|
765
|
+
totalDuration,
|
|
766
|
+
totalDistance,
|
|
767
|
+
direction,
|
|
768
|
+
distance,
|
|
769
|
+
speed
|
|
770
|
+
]) {
|
|
771
|
+
body.set(bytes, offset);
|
|
772
|
+
offset += bytes.length;
|
|
773
|
+
body[offset++] = 0;
|
|
774
|
+
}
|
|
775
|
+
return Uint8Array.from([
|
|
776
|
+
10 /* Navigation */,
|
|
777
|
+
body.length + 2 & 255,
|
|
778
|
+
...body
|
|
779
|
+
]);
|
|
780
|
+
}
|
|
781
|
+
function encodeNavigationPrimaryImage(image, overlay, seqId = 0) {
|
|
782
|
+
validateBitPlanes(image, overlay, 136 * 136, "primary navigation image");
|
|
783
|
+
return encodeNavigationImagePackets(
|
|
784
|
+
runLengthEncodeBits([...Array.from(image), ...Array.from(overlay)]),
|
|
785
|
+
2,
|
|
786
|
+
seqId,
|
|
787
|
+
false
|
|
788
|
+
);
|
|
789
|
+
}
|
|
790
|
+
function encodeNavigationSecondaryImage(image, overlay, seqId = 0) {
|
|
791
|
+
validateBitPlanes(image, overlay, 488 * 136, "secondary navigation image");
|
|
792
|
+
return encodeNavigationImagePackets(
|
|
793
|
+
[...Array.from(image), ...Array.from(overlay)],
|
|
794
|
+
3,
|
|
795
|
+
seqId,
|
|
796
|
+
true
|
|
797
|
+
);
|
|
798
|
+
}
|
|
799
|
+
function encodeNavigationPoller(seqId, pollerSeqId) {
|
|
800
|
+
return Uint8Array.from([
|
|
801
|
+
10 /* Navigation */,
|
|
802
|
+
6,
|
|
803
|
+
0,
|
|
804
|
+
seqId & 255,
|
|
805
|
+
4,
|
|
806
|
+
pollerSeqId & 255
|
|
807
|
+
]);
|
|
808
|
+
}
|
|
809
|
+
function encodeNavigationEnd(seqId) {
|
|
810
|
+
return Uint8Array.from([
|
|
811
|
+
10 /* Navigation */,
|
|
812
|
+
6,
|
|
813
|
+
0,
|
|
814
|
+
seqId & 255,
|
|
815
|
+
5,
|
|
816
|
+
1
|
|
817
|
+
]);
|
|
818
|
+
}
|
|
819
|
+
function encodeTranslateSetup() {
|
|
820
|
+
return Uint8Array.from([57 /* TranslateSetup */, 5, 0, 0, 19]);
|
|
821
|
+
}
|
|
822
|
+
function encodeTranslateStart() {
|
|
823
|
+
return Uint8Array.from([
|
|
824
|
+
80 /* TranslateStart */,
|
|
825
|
+
6,
|
|
826
|
+
0,
|
|
827
|
+
0,
|
|
828
|
+
1,
|
|
829
|
+
1
|
|
830
|
+
]);
|
|
831
|
+
}
|
|
832
|
+
function encodeTranslateLanguages(fromLanguage, toLanguage) {
|
|
833
|
+
return Uint8Array.from([
|
|
834
|
+
28 /* TranslateLanguages */,
|
|
835
|
+
0,
|
|
836
|
+
fromLanguage & 255,
|
|
837
|
+
toLanguage & 255
|
|
838
|
+
]);
|
|
839
|
+
}
|
|
840
|
+
function encodeTranslateText(kind, text, syncId) {
|
|
841
|
+
const encoded = new TextEncoder().encode(text);
|
|
842
|
+
const command = kind === "original" ? 15 /* TranslateOriginalText */ : 13 /* TranslateTranslatedText */;
|
|
843
|
+
return Uint8Array.from([
|
|
844
|
+
command,
|
|
845
|
+
syncId & 255,
|
|
846
|
+
1,
|
|
847
|
+
0,
|
|
848
|
+
0,
|
|
849
|
+
0,
|
|
850
|
+
text ? 32 : 0,
|
|
851
|
+
13,
|
|
852
|
+
...encoded
|
|
853
|
+
]);
|
|
854
|
+
}
|
|
855
|
+
function encodeGlassesWear(enabled) {
|
|
856
|
+
return Uint8Array.from([
|
|
857
|
+
39 /* GlassesWear */,
|
|
858
|
+
enabled ? 1 /* On */ : 0 /* Off */
|
|
859
|
+
]);
|
|
860
|
+
}
|
|
861
|
+
function encodeAppWhitelist(whitelist) {
|
|
862
|
+
const text = typeof whitelist === "string" ? whitelist : JSON.stringify(whitelist);
|
|
863
|
+
const data = new TextEncoder().encode(text);
|
|
864
|
+
const maxPayload = 177;
|
|
865
|
+
const totalPackets = Math.max(1, Math.ceil(data.byteLength / maxPayload));
|
|
866
|
+
const packets = [];
|
|
867
|
+
for (let seq = 0; seq < totalPackets; seq++) {
|
|
868
|
+
const start = seq * maxPayload;
|
|
869
|
+
const chunk = data.slice(start, start + maxPayload);
|
|
870
|
+
const packet = new Uint8Array(3 + chunk.length);
|
|
871
|
+
packet.set([4 /* AppWhitelist */, totalPackets & 255, seq & 255]);
|
|
872
|
+
packet.set(chunk, 3);
|
|
873
|
+
packets.push(packet);
|
|
874
|
+
}
|
|
875
|
+
return packets;
|
|
876
|
+
}
|
|
877
|
+
function encodeNoteDelete(noteNumber) {
|
|
878
|
+
validateNoteNumber(noteNumber);
|
|
879
|
+
return Uint8Array.from([
|
|
880
|
+
30 /* Note */,
|
|
881
|
+
16,
|
|
882
|
+
0,
|
|
883
|
+
224,
|
|
884
|
+
3,
|
|
885
|
+
1,
|
|
886
|
+
0,
|
|
887
|
+
1,
|
|
888
|
+
0,
|
|
889
|
+
noteNumber,
|
|
890
|
+
0,
|
|
891
|
+
1,
|
|
892
|
+
0,
|
|
893
|
+
1,
|
|
894
|
+
0,
|
|
895
|
+
0
|
|
896
|
+
]);
|
|
897
|
+
}
|
|
898
|
+
function encodeNoteAdd(noteNumber, title, text, version = Date.now()) {
|
|
899
|
+
validateNoteNumber(noteNumber);
|
|
900
|
+
const titleBytes = new TextEncoder().encode(title);
|
|
901
|
+
const textBytes = new TextEncoder().encode(text);
|
|
902
|
+
if (titleBytes.length > 255 || textBytes.length > 255) {
|
|
903
|
+
throw new RangeError(
|
|
904
|
+
"G1 note title and text must each encode to at most 255 bytes"
|
|
905
|
+
);
|
|
906
|
+
}
|
|
907
|
+
const fixed = Uint8Array.from([3, 1, 0, 1, 0]);
|
|
908
|
+
const payloadLength = 1 + 1 + fixed.length + 1 + 1 + 1 + titleBytes.length + 1 + 1 + textBytes.length + 2;
|
|
909
|
+
const out = new Uint8Array(
|
|
910
|
+
4 + fixed.length + 3 + titleBytes.length + 2 + textBytes.length
|
|
911
|
+
);
|
|
912
|
+
let offset = 0;
|
|
913
|
+
out.set(
|
|
914
|
+
[
|
|
915
|
+
30 /* Note */,
|
|
916
|
+
payloadLength & 255,
|
|
917
|
+
0,
|
|
918
|
+
Math.floor(version / 1e3) & 255
|
|
919
|
+
],
|
|
920
|
+
offset
|
|
921
|
+
);
|
|
922
|
+
offset += 4;
|
|
923
|
+
out.set(fixed, offset);
|
|
924
|
+
offset += fixed.length;
|
|
925
|
+
out.set([noteNumber, 1, titleBytes.length & 255], offset);
|
|
926
|
+
offset += 3;
|
|
927
|
+
out.set(titleBytes, offset);
|
|
928
|
+
offset += titleBytes.length;
|
|
929
|
+
out.set([textBytes.length & 255, 0], offset);
|
|
930
|
+
offset += 2;
|
|
931
|
+
out.set(textBytes, offset);
|
|
932
|
+
return out;
|
|
933
|
+
}
|
|
934
|
+
function encodeVoiceNoteFetch(noteIndex, syncId) {
|
|
935
|
+
validateVoiceNoteIndex(noteIndex);
|
|
936
|
+
return Uint8Array.from([
|
|
937
|
+
30 /* Note */,
|
|
938
|
+
6,
|
|
939
|
+
0,
|
|
940
|
+
syncId & 255,
|
|
941
|
+
2 /* RequestAudioData */,
|
|
942
|
+
noteIndex & 255
|
|
943
|
+
]);
|
|
944
|
+
}
|
|
945
|
+
function encodeVoiceNoteList(syncId) {
|
|
946
|
+
return Uint8Array.from([
|
|
947
|
+
30 /* Note */,
|
|
948
|
+
6,
|
|
949
|
+
0,
|
|
950
|
+
syncId & 255,
|
|
951
|
+
1 /* RequestAudioInfo */,
|
|
952
|
+
0
|
|
953
|
+
]);
|
|
954
|
+
}
|
|
955
|
+
function encodeVoiceNoteDelete(noteIndex, syncId) {
|
|
956
|
+
validateVoiceNoteIndex(noteIndex);
|
|
957
|
+
return Uint8Array.from([
|
|
958
|
+
30 /* Note */,
|
|
959
|
+
6,
|
|
960
|
+
0,
|
|
961
|
+
syncId & 255,
|
|
962
|
+
4 /* DeleteAudioStream */,
|
|
963
|
+
noteIndex & 255
|
|
964
|
+
]);
|
|
965
|
+
}
|
|
966
|
+
function encodeVoiceNoteDeleteAll(syncId) {
|
|
967
|
+
return Uint8Array.from([
|
|
968
|
+
30 /* Note */,
|
|
969
|
+
6,
|
|
970
|
+
0,
|
|
971
|
+
syncId & 255,
|
|
972
|
+
5 /* DeleteAll */,
|
|
973
|
+
0
|
|
974
|
+
]);
|
|
975
|
+
}
|
|
976
|
+
function encodeNotification(payload) {
|
|
977
|
+
const nowSeconds = Math.floor(Date.now() / 1e3);
|
|
978
|
+
const model = {
|
|
979
|
+
ncs_notification: {
|
|
980
|
+
msg_id: payload.msgId ?? nowSeconds,
|
|
981
|
+
type: payload.type ?? 1,
|
|
982
|
+
app_identifier: payload.appIdentifier,
|
|
983
|
+
title: payload.title,
|
|
984
|
+
subtitle: payload.subtitle ?? "",
|
|
985
|
+
message: payload.message,
|
|
986
|
+
time_s: payload.timeS ?? nowSeconds,
|
|
987
|
+
date: payload.date ?? new Date((payload.timeS ?? nowSeconds) * 1e3).toISOString().slice(0, 19).replace("T", " "),
|
|
988
|
+
display_name: payload.displayName ?? payload.appIdentifier
|
|
989
|
+
},
|
|
990
|
+
type: "Add"
|
|
991
|
+
};
|
|
992
|
+
const bytes = new TextEncoder().encode(JSON.stringify(model));
|
|
993
|
+
const chunkSize = 176;
|
|
994
|
+
const chunks = [];
|
|
995
|
+
const total = Math.max(1, Math.ceil(bytes.length / chunkSize));
|
|
996
|
+
const packetMessageId = (payload.msgId ?? 0) & 255;
|
|
997
|
+
for (let index = 0; index < total; index++) {
|
|
998
|
+
const chunk = bytes.slice(index * chunkSize, (index + 1) * chunkSize);
|
|
999
|
+
const packet = new Uint8Array(4 + chunk.length);
|
|
1000
|
+
packet.set([
|
|
1001
|
+
75 /* Notification */,
|
|
1002
|
+
packetMessageId,
|
|
1003
|
+
total & 255,
|
|
1004
|
+
index & 255
|
|
1005
|
+
]);
|
|
1006
|
+
packet.set(chunk, 4);
|
|
1007
|
+
chunks.push(packet);
|
|
1008
|
+
}
|
|
1009
|
+
return chunks;
|
|
1010
|
+
}
|
|
1011
|
+
function encodeBmpTransfer(imageData) {
|
|
1012
|
+
const packets = [];
|
|
1013
|
+
const packetSize = 194;
|
|
1014
|
+
for (let offset = 0, seq = 0; offset < imageData.length; offset += packetSize, seq++) {
|
|
1015
|
+
const chunk = imageData.slice(offset, offset + packetSize);
|
|
1016
|
+
const prefix = seq === 0 ? [21 /* BmpData */, seq & 255, 0, 28, 0, 0] : [21 /* BmpData */, seq & 255];
|
|
1017
|
+
const packet = new Uint8Array(prefix.length + chunk.length);
|
|
1018
|
+
packet.set(prefix);
|
|
1019
|
+
packet.set(chunk, prefix.length);
|
|
1020
|
+
packets.push(packet);
|
|
1021
|
+
}
|
|
1022
|
+
packets.push(Uint8Array.from([32 /* BmpEnd */, 13, 14]));
|
|
1023
|
+
const crcInput = new Uint8Array(4 + imageData.length);
|
|
1024
|
+
crcInput.set([0, 28, 0, 0]);
|
|
1025
|
+
crcInput.set(imageData, 4);
|
|
1026
|
+
const crc = crc32(crcInput);
|
|
1027
|
+
packets.push(
|
|
1028
|
+
Uint8Array.from([
|
|
1029
|
+
22 /* BmpCrc */,
|
|
1030
|
+
crc >>> 24 & 255,
|
|
1031
|
+
crc >>> 16 & 255,
|
|
1032
|
+
crc >>> 8 & 255,
|
|
1033
|
+
crc & 255
|
|
1034
|
+
])
|
|
1035
|
+
);
|
|
1036
|
+
return packets;
|
|
1037
|
+
}
|
|
1038
|
+
function encodeG1MonochromeBmp(pixels, options = {}) {
|
|
1039
|
+
const width = options.width ?? G1_BMP.width;
|
|
1040
|
+
const height = options.height ?? G1_BMP.height;
|
|
1041
|
+
const threshold = options.threshold ?? 128;
|
|
1042
|
+
if (!Number.isInteger(width) || width <= 0) {
|
|
1043
|
+
throw new RangeError("BMP width must be a positive integer");
|
|
1044
|
+
}
|
|
1045
|
+
if (!Number.isInteger(height) || height <= 0) {
|
|
1046
|
+
throw new RangeError("BMP height must be a positive integer");
|
|
1047
|
+
}
|
|
1048
|
+
const expectedPixels = width * height;
|
|
1049
|
+
if (pixels.length !== expectedPixels) {
|
|
1050
|
+
throw new RangeError(
|
|
1051
|
+
`Expected ${expectedPixels} monochrome pixels, got ${pixels.length}`
|
|
1052
|
+
);
|
|
1053
|
+
}
|
|
1054
|
+
const rowStride = Math.ceil(width / 32) * 4;
|
|
1055
|
+
const pixelDataSize = rowStride * height;
|
|
1056
|
+
const pixelOffset = 14 + 40 + 8;
|
|
1057
|
+
const fileSize = pixelOffset + pixelDataSize;
|
|
1058
|
+
const out = new Uint8Array(fileSize);
|
|
1059
|
+
const view = new DataView(out.buffer);
|
|
1060
|
+
out.set([66, 77], 0);
|
|
1061
|
+
view.setUint32(2, fileSize, true);
|
|
1062
|
+
view.setUint32(10, pixelOffset, true);
|
|
1063
|
+
view.setUint32(14, 40, true);
|
|
1064
|
+
view.setInt32(18, width, true);
|
|
1065
|
+
view.setInt32(22, height, true);
|
|
1066
|
+
view.setUint16(26, 1, true);
|
|
1067
|
+
view.setUint16(28, 1, true);
|
|
1068
|
+
view.setUint32(34, pixelDataSize, true);
|
|
1069
|
+
view.setUint32(46, 2, true);
|
|
1070
|
+
view.setUint32(50, 2, true);
|
|
1071
|
+
out.set([0, 0, 0, 0, 255, 255, 255, 0], 54);
|
|
1072
|
+
for (let y = 0; y < height; y++) {
|
|
1073
|
+
const sourceY = height - 1 - y;
|
|
1074
|
+
const rowOffset = pixelOffset + y * rowStride;
|
|
1075
|
+
for (let x = 0; x < width; x++) {
|
|
1076
|
+
const source = pixels[sourceY * width + x] ?? 0;
|
|
1077
|
+
if (source < threshold) continue;
|
|
1078
|
+
out[rowOffset + (x >> 3)] |= 128 >> (x & 7);
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
return out;
|
|
1082
|
+
}
|
|
1083
|
+
function parseG1Notification(side, data) {
|
|
1084
|
+
const command = data[0];
|
|
1085
|
+
if (command === 245 /* StartAi */) {
|
|
1086
|
+
const code = data[1];
|
|
1087
|
+
const state = classifyStateCode(code);
|
|
1088
|
+
return {
|
|
1089
|
+
side,
|
|
1090
|
+
raw: data,
|
|
1091
|
+
type: "state",
|
|
1092
|
+
code,
|
|
1093
|
+
label: state?.label ?? `unknown_0x${code?.toString(16)}`,
|
|
1094
|
+
stateCategory: state?.category,
|
|
1095
|
+
stateName: state?.name
|
|
1096
|
+
};
|
|
1097
|
+
}
|
|
1098
|
+
if (command === 14 /* OpenMic */) {
|
|
1099
|
+
const responseStatus = data.length >= 3 ? data[1] : void 0;
|
|
1100
|
+
const requested = data[data.length - 1];
|
|
1101
|
+
const responseOk = responseStatus === void 0 || responseStatus === 201 /* Success */;
|
|
1102
|
+
const micRequested = requested === 1 /* Enable */;
|
|
1103
|
+
return {
|
|
1104
|
+
side,
|
|
1105
|
+
raw: data,
|
|
1106
|
+
type: "mic-response",
|
|
1107
|
+
micEnabled: responseOk ? micRequested : !micRequested,
|
|
1108
|
+
micRequested,
|
|
1109
|
+
responseStatus,
|
|
1110
|
+
responseOk,
|
|
1111
|
+
code: requested,
|
|
1112
|
+
label: responseOk && micRequested ? "mic_enabled" : responseOk ? "mic_disabled" : "mic_failed"
|
|
1113
|
+
};
|
|
1114
|
+
}
|
|
1115
|
+
if (command === 241 /* ReceiveMicData */) {
|
|
1116
|
+
return {
|
|
1117
|
+
side,
|
|
1118
|
+
raw: data,
|
|
1119
|
+
type: "mic-data",
|
|
1120
|
+
sequence: data[1],
|
|
1121
|
+
audioData: data.slice(2),
|
|
1122
|
+
audioEncoding: "lc3",
|
|
1123
|
+
label: "mic_data"
|
|
1124
|
+
};
|
|
1125
|
+
}
|
|
1126
|
+
if (command === 77 /* Init */ || command === 244 /* RightInit */) {
|
|
1127
|
+
return {
|
|
1128
|
+
side,
|
|
1129
|
+
raw: data,
|
|
1130
|
+
type: "init",
|
|
1131
|
+
code: data[1],
|
|
1132
|
+
label: command === 244 /* RightInit */ ? "right_init" : "init"
|
|
1133
|
+
};
|
|
1134
|
+
}
|
|
1135
|
+
if (command === 78 /* SendResult */) {
|
|
1136
|
+
return parseDisplayResult(side, data);
|
|
1137
|
+
}
|
|
1138
|
+
if (command === 75 /* Notification */) {
|
|
1139
|
+
return parseNotificationChunk(side, data);
|
|
1140
|
+
}
|
|
1141
|
+
if (command === 33 /* QuickNote */) {
|
|
1142
|
+
return parseVoiceNoteList(side, data);
|
|
1143
|
+
}
|
|
1144
|
+
if (command === 30 /* Note */ && data.length >= 11 && data[4] === 2 /* RequestAudioData */) {
|
|
1145
|
+
const totalPackets = readUint16LE(data, 5);
|
|
1146
|
+
const currentPacket = readUint16LE(data, 7);
|
|
1147
|
+
const noteIndex = Math.max(0, (data[9] ?? 1) - 1);
|
|
1148
|
+
return {
|
|
1149
|
+
side,
|
|
1150
|
+
raw: data,
|
|
1151
|
+
type: "voice-note-audio",
|
|
1152
|
+
syncId: data[3],
|
|
1153
|
+
subcommand: data[4],
|
|
1154
|
+
totalPackets,
|
|
1155
|
+
currentPacket,
|
|
1156
|
+
noteIndex,
|
|
1157
|
+
sequence: currentPacket,
|
|
1158
|
+
audioData: data.slice(10),
|
|
1159
|
+
audioEncoding: "lc3",
|
|
1160
|
+
label: "voice_note_audio"
|
|
1161
|
+
};
|
|
1162
|
+
}
|
|
1163
|
+
if (command === 34 /* Dashboard */) {
|
|
1164
|
+
const code = data[1];
|
|
1165
|
+
return {
|
|
1166
|
+
side,
|
|
1167
|
+
raw: data,
|
|
1168
|
+
type: "dashboard",
|
|
1169
|
+
code,
|
|
1170
|
+
label: `dashboard_0x${code?.toString(16).padStart(2, "0")}`
|
|
1171
|
+
};
|
|
1172
|
+
}
|
|
1173
|
+
if (command === 52 /* GetSerial */) {
|
|
1174
|
+
const serialNumber = new TextDecoder().decode(data.slice(2, 18)).replace(/\0+$/g, "");
|
|
1175
|
+
return {
|
|
1176
|
+
side,
|
|
1177
|
+
raw: data,
|
|
1178
|
+
type: "serial",
|
|
1179
|
+
code: data[1],
|
|
1180
|
+
responseStatus: data[1],
|
|
1181
|
+
responseOk: data[1] === void 0 || data[1] === 201 /* Success */,
|
|
1182
|
+
serialNumber,
|
|
1183
|
+
label: "serial_number"
|
|
1184
|
+
};
|
|
1185
|
+
}
|
|
1186
|
+
if (command === 37 /* Heartbeat */) {
|
|
1187
|
+
return { side, raw: data, type: "heartbeat", label: "heartbeat" };
|
|
1188
|
+
}
|
|
1189
|
+
if (command === 44 /* Battery */) {
|
|
1190
|
+
return parseBatteryStatus(side, data);
|
|
1191
|
+
}
|
|
1192
|
+
if (command === 3) {
|
|
1193
|
+
return {
|
|
1194
|
+
side,
|
|
1195
|
+
raw: data,
|
|
1196
|
+
type: "response",
|
|
1197
|
+
code: data[1],
|
|
1198
|
+
label: "response"
|
|
1199
|
+
};
|
|
1200
|
+
}
|
|
1201
|
+
if (command === 4) {
|
|
1202
|
+
return {
|
|
1203
|
+
side,
|
|
1204
|
+
raw: data,
|
|
1205
|
+
type: "error",
|
|
1206
|
+
code: data[1],
|
|
1207
|
+
label: `error_0x${data[1]?.toString(16).padStart(2, "0")}`
|
|
1208
|
+
};
|
|
1209
|
+
}
|
|
1210
|
+
return {
|
|
1211
|
+
side,
|
|
1212
|
+
raw: data,
|
|
1213
|
+
type: "unknown",
|
|
1214
|
+
code: command,
|
|
1215
|
+
label: `unknown_0x${command?.toString(16)}`
|
|
1216
|
+
};
|
|
1217
|
+
}
|
|
1218
|
+
function parseBatteryStatus(side, data) {
|
|
1219
|
+
if (data.length < 6 || data[1] !== 102) {
|
|
1220
|
+
return {
|
|
1221
|
+
side,
|
|
1222
|
+
raw: data,
|
|
1223
|
+
type: "battery-status",
|
|
1224
|
+
responseStatus: data[1],
|
|
1225
|
+
responseOk: false,
|
|
1226
|
+
label: "battery_status_invalid"
|
|
1227
|
+
};
|
|
1228
|
+
}
|
|
1229
|
+
return {
|
|
1230
|
+
side,
|
|
1231
|
+
raw: data,
|
|
1232
|
+
type: "battery-status",
|
|
1233
|
+
responseStatus: data[1],
|
|
1234
|
+
responseOk: true,
|
|
1235
|
+
batteryPercent: data[2],
|
|
1236
|
+
batteryFlags: data[3],
|
|
1237
|
+
batteryVoltageMv: ((data[5] ?? 0) << 8 | (data[4] ?? 0)) / 10,
|
|
1238
|
+
label: "battery_status"
|
|
1239
|
+
};
|
|
1240
|
+
}
|
|
1241
|
+
function parseDisplayResult(side, data) {
|
|
1242
|
+
if (data.length < 9) {
|
|
1243
|
+
return {
|
|
1244
|
+
side,
|
|
1245
|
+
raw: data,
|
|
1246
|
+
type: "display-result",
|
|
1247
|
+
label: "display_result_invalid"
|
|
1248
|
+
};
|
|
1249
|
+
}
|
|
1250
|
+
const textBytes = data.slice(9);
|
|
1251
|
+
return {
|
|
1252
|
+
side,
|
|
1253
|
+
raw: data,
|
|
1254
|
+
type: "display-result",
|
|
1255
|
+
displaySeq: data[1],
|
|
1256
|
+
totalPackages: data[2],
|
|
1257
|
+
currentPackage: data[3],
|
|
1258
|
+
screenStatus: data[4],
|
|
1259
|
+
charPosition: readUint16BE(data, 5),
|
|
1260
|
+
pageNumber: data[7],
|
|
1261
|
+
maxPages: data[8],
|
|
1262
|
+
text: new TextDecoder().decode(textBytes),
|
|
1263
|
+
label: "display_result"
|
|
1264
|
+
};
|
|
1265
|
+
}
|
|
1266
|
+
function parseNotificationChunk(side, data) {
|
|
1267
|
+
if (data.length < 4) {
|
|
1268
|
+
return {
|
|
1269
|
+
side,
|
|
1270
|
+
raw: data,
|
|
1271
|
+
type: "notification",
|
|
1272
|
+
label: "notification_invalid"
|
|
1273
|
+
};
|
|
1274
|
+
}
|
|
1275
|
+
const notificationChunk = data.slice(4);
|
|
1276
|
+
return {
|
|
1277
|
+
side,
|
|
1278
|
+
raw: data,
|
|
1279
|
+
type: "notification",
|
|
1280
|
+
notificationId: data[1],
|
|
1281
|
+
totalPackages: data[2],
|
|
1282
|
+
currentPackage: data[3],
|
|
1283
|
+
notificationChunk,
|
|
1284
|
+
text: new TextDecoder().decode(notificationChunk),
|
|
1285
|
+
label: "notification"
|
|
1286
|
+
};
|
|
1287
|
+
}
|
|
1288
|
+
function parseVoiceNoteList(side, data) {
|
|
1289
|
+
const length = readUint16LE(data, 1);
|
|
1290
|
+
const syncId = data[3];
|
|
1291
|
+
const subcommand = data[4];
|
|
1292
|
+
if (data.length < 6 || subcommand !== 1 /* RequestAudioInfo */) {
|
|
1293
|
+
return {
|
|
1294
|
+
side,
|
|
1295
|
+
raw: data,
|
|
1296
|
+
type: "voice-note-list",
|
|
1297
|
+
syncId,
|
|
1298
|
+
subcommand,
|
|
1299
|
+
voiceNotes: [],
|
|
1300
|
+
label: "voice_note_list_invalid"
|
|
1301
|
+
};
|
|
1302
|
+
}
|
|
1303
|
+
const noteCount = data[5] ?? 0;
|
|
1304
|
+
const expectedLength = 6 + noteCount * 9;
|
|
1305
|
+
const boundedLength = Math.min(data.length, Math.max(length, expectedLength));
|
|
1306
|
+
const voiceNotes = [];
|
|
1307
|
+
for (let offset = 6; offset + 8 < boundedLength && voiceNotes.length < noteCount; offset += 9) {
|
|
1308
|
+
voiceNotes.push({
|
|
1309
|
+
index: data[offset],
|
|
1310
|
+
timestamp: readUint32LE(data, offset + 1),
|
|
1311
|
+
crc: readUint32LE(data, offset + 5)
|
|
1312
|
+
});
|
|
1313
|
+
}
|
|
1314
|
+
return {
|
|
1315
|
+
side,
|
|
1316
|
+
raw: data,
|
|
1317
|
+
type: "voice-note-list",
|
|
1318
|
+
syncId,
|
|
1319
|
+
subcommand,
|
|
1320
|
+
voiceNotes,
|
|
1321
|
+
label: "voice_note_list"
|
|
1322
|
+
};
|
|
1323
|
+
}
|
|
1324
|
+
function pcm16ToFloat32(bytes) {
|
|
1325
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
1326
|
+
const out = new Float32Array(Math.floor(bytes.byteLength / 2));
|
|
1327
|
+
for (let i = 0; i < out.length; i++)
|
|
1328
|
+
out[i] = view.getInt16(i * 2, true) / 32768;
|
|
1329
|
+
return out;
|
|
1330
|
+
}
|
|
1331
|
+
function validateNoteNumber(noteNumber) {
|
|
1332
|
+
if (!Number.isInteger(noteNumber) || noteNumber < 1 || noteNumber > 4) {
|
|
1333
|
+
throw new RangeError("Note number must be an integer between 1 and 4");
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
function validateVoiceNoteIndex(noteIndex) {
|
|
1337
|
+
if (!Number.isInteger(noteIndex) || noteIndex < 0 || noteIndex > 255) {
|
|
1338
|
+
throw new RangeError(
|
|
1339
|
+
"G1 voice note index must be an integer from 0 to 255"
|
|
1340
|
+
);
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
function validateBitPlanes(image, overlay, expectedLength, label) {
|
|
1344
|
+
if (image.length !== expectedLength || overlay.length !== expectedLength) {
|
|
1345
|
+
throw new RangeError(
|
|
1346
|
+
`Expected ${expectedLength} bits for ${label} and overlay`
|
|
1347
|
+
);
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
function runLengthEncodeBits(data) {
|
|
1351
|
+
if (data.length === 0) return [];
|
|
1352
|
+
const encoded = [];
|
|
1353
|
+
let current = data[0] ? 1 : 0;
|
|
1354
|
+
let count = 1;
|
|
1355
|
+
for (let index = 1; index < data.length; index++) {
|
|
1356
|
+
const bit = data[index] ? 1 : 0;
|
|
1357
|
+
if (bit === current && count < 255) {
|
|
1358
|
+
count += 1;
|
|
1359
|
+
continue;
|
|
1360
|
+
}
|
|
1361
|
+
encoded.push(count, current);
|
|
1362
|
+
current = bit;
|
|
1363
|
+
count = 1;
|
|
1364
|
+
}
|
|
1365
|
+
encoded.push(count, current);
|
|
1366
|
+
return encoded;
|
|
1367
|
+
}
|
|
1368
|
+
function encodeNavigationImagePackets(bytes, partType, startSeqId, includeExtraZero) {
|
|
1369
|
+
const maxPayload = 185;
|
|
1370
|
+
const packetCount = Math.max(1, Math.ceil(bytes.length / maxPayload));
|
|
1371
|
+
const packets = [];
|
|
1372
|
+
let seqId = startSeqId & 255;
|
|
1373
|
+
for (let index = 0; index < packetCount; index++) {
|
|
1374
|
+
const chunk = bytes.slice(index * maxPayload, (index + 1) * maxPayload);
|
|
1375
|
+
const part = [
|
|
1376
|
+
0,
|
|
1377
|
+
seqId,
|
|
1378
|
+
partType,
|
|
1379
|
+
packetCount & 255,
|
|
1380
|
+
0,
|
|
1381
|
+
index + 1 & 255,
|
|
1382
|
+
0,
|
|
1383
|
+
...includeExtraZero ? [0] : [],
|
|
1384
|
+
...chunk.map((byte) => byte & 255)
|
|
1385
|
+
];
|
|
1386
|
+
packets.push(
|
|
1387
|
+
Uint8Array.from([
|
|
1388
|
+
10 /* Navigation */,
|
|
1389
|
+
part.length + 2 & 255,
|
|
1390
|
+
...part
|
|
1391
|
+
])
|
|
1392
|
+
);
|
|
1393
|
+
seqId = seqId + 1 & 255;
|
|
1394
|
+
}
|
|
1395
|
+
return packets;
|
|
1396
|
+
}
|
|
1397
|
+
function readUint16LE(data, offset) {
|
|
1398
|
+
return (data[offset] ?? 0) | (data[offset + 1] ?? 0) << 8;
|
|
1399
|
+
}
|
|
1400
|
+
function readUint16BE(data, offset) {
|
|
1401
|
+
return (data[offset] ?? 0) << 8 | (data[offset + 1] ?? 0);
|
|
1402
|
+
}
|
|
1403
|
+
function readUint32LE(data, offset) {
|
|
1404
|
+
return ((data[offset] ?? 0) | (data[offset + 1] ?? 0) << 8 | (data[offset + 2] ?? 0) << 16 | (data[offset + 3] ?? 0) << 24) >>> 0;
|
|
1405
|
+
}
|
|
1406
|
+
function crc32(bytes) {
|
|
1407
|
+
let crc = 4294967295;
|
|
1408
|
+
for (const byte of bytes) {
|
|
1409
|
+
crc ^= byte;
|
|
1410
|
+
for (let bit = 0; bit < 8; bit++) {
|
|
1411
|
+
crc = crc & 1 ? crc >>> 1 ^ 3988292384 : crc >>> 1;
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
return (crc ^ 4294967295) >>> 0;
|
|
1415
|
+
}
|
|
1416
|
+
export {
|
|
1417
|
+
EVEN_G1_UART,
|
|
1418
|
+
G1AiStatus,
|
|
1419
|
+
G1Command,
|
|
1420
|
+
G1DashboardLayout,
|
|
1421
|
+
G1DashboardState,
|
|
1422
|
+
G1GlassesWearStatus,
|
|
1423
|
+
G1InteractionCode,
|
|
1424
|
+
G1MicStatus,
|
|
1425
|
+
G1NavigationTurn,
|
|
1426
|
+
G1ResponseStatus,
|
|
1427
|
+
G1ScreenAction,
|
|
1428
|
+
G1SilentModeStatus,
|
|
1429
|
+
G1SubCommand,
|
|
1430
|
+
G1TemperatureUnit,
|
|
1431
|
+
G1TextStatus,
|
|
1432
|
+
G1TimeFormat,
|
|
1433
|
+
G1TranslateLanguage,
|
|
1434
|
+
G1VoiceNoteSubCommand,
|
|
1435
|
+
G1WeatherIcon,
|
|
1436
|
+
G1_BMP,
|
|
1437
|
+
G1_DISPLAY,
|
|
1438
|
+
encodeAppWhitelist,
|
|
1439
|
+
encodeBatteryStatusRequest,
|
|
1440
|
+
encodeBmpTransfer,
|
|
1441
|
+
encodeBrightness,
|
|
1442
|
+
encodeClearScreen,
|
|
1443
|
+
encodeConnectionReady,
|
|
1444
|
+
encodeDashboard,
|
|
1445
|
+
encodeDashboardCalendarItem,
|
|
1446
|
+
encodeDashboardLayout,
|
|
1447
|
+
encodeDashboardPosition,
|
|
1448
|
+
encodeDashboardTimeWeather,
|
|
1449
|
+
encodeExitFunction,
|
|
1450
|
+
encodeG1MonochromeBmp,
|
|
1451
|
+
encodeG1Setup,
|
|
1452
|
+
encodeGetSerial,
|
|
1453
|
+
encodeGlassesWear,
|
|
1454
|
+
encodeHeadUpAngle,
|
|
1455
|
+
encodeHeartbeat,
|
|
1456
|
+
encodeMicCommand,
|
|
1457
|
+
encodeNavigationDirections,
|
|
1458
|
+
encodeNavigationEnd,
|
|
1459
|
+
encodeNavigationInit,
|
|
1460
|
+
encodeNavigationPoller,
|
|
1461
|
+
encodeNavigationPrimaryImage,
|
|
1462
|
+
encodeNavigationSecondaryImage,
|
|
1463
|
+
encodeNoteAdd,
|
|
1464
|
+
encodeNoteDelete,
|
|
1465
|
+
encodeNotification,
|
|
1466
|
+
encodeSilentMode,
|
|
1467
|
+
encodeStartAi,
|
|
1468
|
+
encodeTextPacket,
|
|
1469
|
+
encodeTextPackets,
|
|
1470
|
+
encodeTranslateLanguages,
|
|
1471
|
+
encodeTranslateSetup,
|
|
1472
|
+
encodeTranslateStart,
|
|
1473
|
+
encodeTranslateText,
|
|
1474
|
+
encodeVoiceNoteDelete,
|
|
1475
|
+
encodeVoiceNoteDeleteAll,
|
|
1476
|
+
encodeVoiceNoteFetch,
|
|
1477
|
+
encodeVoiceNoteList,
|
|
1478
|
+
formatDisplayLines,
|
|
1479
|
+
measureG1DisplayText,
|
|
1480
|
+
microphoneActionForInteractionEvent,
|
|
1481
|
+
paginateDisplayText,
|
|
1482
|
+
parseG1Notification,
|
|
1483
|
+
pcm16ToFloat32
|
|
1484
|
+
};
|
|
1485
|
+
//# sourceMappingURL=smartglasses.js.map
|