@aippy/runtime 0.2.4-dev.9 → 0.2.5-dev.0
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/core/index.js +1 -1
- package/dist/device/index.js +270 -288
- package/dist/device/sensors.d.ts +7 -57
- package/dist/device/types.d.ts +20 -1
- package/dist/leaderboard/index.js +22 -18
- package/dist/leaderboard/types.d.ts +2 -0
- package/package.json +1 -1
package/dist/core/index.js
CHANGED
package/dist/device/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
var L = Object.defineProperty;
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { c
|
|
5
|
-
class
|
|
2
|
+
var T = (n, t, e) => t in n ? L(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
|
|
3
|
+
var S = (n, t, e) => T(n, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
+
import { c, b as k } from "../runtime-DjBdOttl.js";
|
|
5
|
+
class D {
|
|
6
6
|
constructor() {
|
|
7
|
-
|
|
7
|
+
S(this, "stream", null);
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
10
10
|
* Check if camera is supported
|
|
@@ -15,21 +15,21 @@ class _ {
|
|
|
15
15
|
/**
|
|
16
16
|
* Get camera stream
|
|
17
17
|
*/
|
|
18
|
-
async getStream(
|
|
18
|
+
async getStream(t = {}) {
|
|
19
19
|
if (!this.isSupported())
|
|
20
|
-
throw
|
|
20
|
+
throw c("Camera API is not supported", "NOT_SUPPORTED");
|
|
21
21
|
try {
|
|
22
|
-
const
|
|
22
|
+
const e = {
|
|
23
23
|
video: {
|
|
24
|
-
width:
|
|
25
|
-
height:
|
|
26
|
-
facingMode:
|
|
24
|
+
width: t.width,
|
|
25
|
+
height: t.height,
|
|
26
|
+
facingMode: t.facingMode || "environment"
|
|
27
27
|
}
|
|
28
28
|
};
|
|
29
|
-
return this.stream = await navigator.mediaDevices.getUserMedia(
|
|
30
|
-
} catch (
|
|
31
|
-
throw
|
|
32
|
-
`Failed to access camera: ${
|
|
29
|
+
return this.stream = await navigator.mediaDevices.getUserMedia(e), this.stream;
|
|
30
|
+
} catch (e) {
|
|
31
|
+
throw c(
|
|
32
|
+
`Failed to access camera: ${e instanceof Error ? e.message : "Unknown error"}`,
|
|
33
33
|
"PERMISSION_DENIED"
|
|
34
34
|
);
|
|
35
35
|
}
|
|
@@ -37,30 +37,30 @@ class _ {
|
|
|
37
37
|
/**
|
|
38
38
|
* Capture photo from stream
|
|
39
39
|
*/
|
|
40
|
-
async capturePhoto(
|
|
40
|
+
async capturePhoto(t = {}) {
|
|
41
41
|
if (!this.stream)
|
|
42
|
-
throw
|
|
42
|
+
throw c("No camera stream available", "NOT_SUPPORTED");
|
|
43
43
|
try {
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
if (!
|
|
48
|
-
throw
|
|
49
|
-
|
|
50
|
-
const r =
|
|
51
|
-
|
|
44
|
+
const e = document.createElement("video");
|
|
45
|
+
e.srcObject = this.stream, e.play();
|
|
46
|
+
const i = document.createElement("canvas"), o = i.getContext("2d");
|
|
47
|
+
if (!o)
|
|
48
|
+
throw c("Failed to get canvas context", "UNKNOWN_ERROR");
|
|
49
|
+
i.width = t.width || e.videoWidth, i.height = t.height || e.videoHeight, o.drawImage(e, 0, 0, i.width, i.height);
|
|
50
|
+
const r = t.format || "jpeg", s = t.quality === "high" ? 0.9 : t.quality === "medium" ? 0.7 : 0.5, a = await new Promise((u, m) => {
|
|
51
|
+
i.toBlob((l) => {
|
|
52
52
|
l ? u(l) : m(new Error("Failed to create blob"));
|
|
53
|
-
}, `image/${r}`,
|
|
54
|
-
}), d =
|
|
53
|
+
}, `image/${r}`, s);
|
|
54
|
+
}), d = i.toDataURL(`image/${r}`, s);
|
|
55
55
|
return {
|
|
56
56
|
blob: a,
|
|
57
57
|
dataUrl: d,
|
|
58
|
-
width:
|
|
59
|
-
height:
|
|
58
|
+
width: i.width,
|
|
59
|
+
height: i.height
|
|
60
60
|
};
|
|
61
|
-
} catch (
|
|
62
|
-
throw
|
|
63
|
-
`Failed to capture photo: ${
|
|
61
|
+
} catch (e) {
|
|
62
|
+
throw c(
|
|
63
|
+
`Failed to capture photo: ${e instanceof Error ? e.message : "Unknown error"}`,
|
|
64
64
|
"UNKNOWN_ERROR"
|
|
65
65
|
);
|
|
66
66
|
}
|
|
@@ -69,11 +69,11 @@ class _ {
|
|
|
69
69
|
* Stop camera stream
|
|
70
70
|
*/
|
|
71
71
|
stopStream() {
|
|
72
|
-
this.stream && (this.stream.getTracks().forEach((
|
|
72
|
+
this.stream && (this.stream.getTracks().forEach((t) => t.stop()), this.stream = null);
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
|
-
const
|
|
76
|
-
class
|
|
75
|
+
const H = new D();
|
|
76
|
+
class x {
|
|
77
77
|
/**
|
|
78
78
|
* Check if geolocation is supported
|
|
79
79
|
*/
|
|
@@ -83,18 +83,18 @@ class F {
|
|
|
83
83
|
/**
|
|
84
84
|
* Get current position
|
|
85
85
|
*/
|
|
86
|
-
async getCurrentPosition(
|
|
86
|
+
async getCurrentPosition(t = {}) {
|
|
87
87
|
if (!this.isSupported())
|
|
88
|
-
throw
|
|
89
|
-
return new Promise((
|
|
90
|
-
const
|
|
91
|
-
enableHighAccuracy:
|
|
92
|
-
timeout:
|
|
93
|
-
maximumAge:
|
|
88
|
+
throw c("Geolocation API is not supported", "NOT_SUPPORTED");
|
|
89
|
+
return new Promise((e, i) => {
|
|
90
|
+
const o = {
|
|
91
|
+
enableHighAccuracy: t.enableHighAccuracy ?? !0,
|
|
92
|
+
timeout: t.timeout ?? 1e4,
|
|
93
|
+
maximumAge: t.maximumAge ?? 6e4
|
|
94
94
|
};
|
|
95
95
|
navigator.geolocation.getCurrentPosition(
|
|
96
96
|
(r) => {
|
|
97
|
-
const
|
|
97
|
+
const s = {
|
|
98
98
|
latitude: r.coords.latitude,
|
|
99
99
|
longitude: r.coords.longitude,
|
|
100
100
|
accuracy: r.coords.accuracy,
|
|
@@ -104,13 +104,13 @@ class F {
|
|
|
104
104
|
speed: r.coords.speed ?? void 0,
|
|
105
105
|
timestamp: r.timestamp
|
|
106
106
|
};
|
|
107
|
-
|
|
107
|
+
e(s);
|
|
108
108
|
},
|
|
109
109
|
(r) => {
|
|
110
|
-
let
|
|
110
|
+
let s = "UNKNOWN_ERROR", a = "Unknown geolocation error";
|
|
111
111
|
switch (r.code) {
|
|
112
112
|
case r.PERMISSION_DENIED:
|
|
113
|
-
|
|
113
|
+
s = "PERMISSION_DENIED", a = "Geolocation permission denied";
|
|
114
114
|
break;
|
|
115
115
|
case r.POSITION_UNAVAILABLE:
|
|
116
116
|
a = "Position unavailable";
|
|
@@ -119,163 +119,157 @@ class F {
|
|
|
119
119
|
a = "Geolocation timeout";
|
|
120
120
|
break;
|
|
121
121
|
}
|
|
122
|
-
|
|
122
|
+
i(c(a, s));
|
|
123
123
|
},
|
|
124
|
-
|
|
124
|
+
o
|
|
125
125
|
);
|
|
126
126
|
});
|
|
127
127
|
}
|
|
128
128
|
/**
|
|
129
129
|
* Watch position changes
|
|
130
130
|
*/
|
|
131
|
-
watchPosition(
|
|
131
|
+
watchPosition(t, e = {}) {
|
|
132
132
|
if (!this.isSupported())
|
|
133
|
-
throw
|
|
134
|
-
const
|
|
135
|
-
enableHighAccuracy:
|
|
136
|
-
timeout:
|
|
137
|
-
maximumAge:
|
|
133
|
+
throw c("Geolocation API is not supported", "NOT_SUPPORTED");
|
|
134
|
+
const i = {
|
|
135
|
+
enableHighAccuracy: e.enableHighAccuracy ?? !0,
|
|
136
|
+
timeout: e.timeout ?? 1e4,
|
|
137
|
+
maximumAge: e.maximumAge ?? 6e4
|
|
138
138
|
};
|
|
139
139
|
return navigator.geolocation.watchPosition(
|
|
140
|
-
(
|
|
140
|
+
(o) => {
|
|
141
141
|
const r = {
|
|
142
|
-
latitude:
|
|
143
|
-
longitude:
|
|
144
|
-
accuracy:
|
|
145
|
-
altitude:
|
|
146
|
-
altitudeAccuracy:
|
|
147
|
-
heading:
|
|
148
|
-
speed:
|
|
149
|
-
timestamp:
|
|
142
|
+
latitude: o.coords.latitude,
|
|
143
|
+
longitude: o.coords.longitude,
|
|
144
|
+
accuracy: o.coords.accuracy,
|
|
145
|
+
altitude: o.coords.altitude ?? void 0,
|
|
146
|
+
altitudeAccuracy: o.coords.altitudeAccuracy ?? void 0,
|
|
147
|
+
heading: o.coords.heading ?? void 0,
|
|
148
|
+
speed: o.coords.speed ?? void 0,
|
|
149
|
+
timestamp: o.timestamp
|
|
150
150
|
};
|
|
151
|
-
|
|
151
|
+
t(r);
|
|
152
152
|
},
|
|
153
|
-
(
|
|
154
|
-
console.error("Geolocation watch error:",
|
|
153
|
+
(o) => {
|
|
154
|
+
console.error("Geolocation watch error:", o);
|
|
155
155
|
},
|
|
156
|
-
|
|
156
|
+
i
|
|
157
157
|
);
|
|
158
158
|
}
|
|
159
159
|
/**
|
|
160
160
|
* Clear position watch
|
|
161
161
|
*/
|
|
162
|
-
clearWatch(
|
|
163
|
-
navigator.geolocation.clearWatch(
|
|
162
|
+
clearWatch(t) {
|
|
163
|
+
navigator.geolocation.clearWatch(t);
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
|
-
const
|
|
167
|
-
function
|
|
166
|
+
const C = new x();
|
|
167
|
+
function E() {
|
|
168
168
|
return "DeviceMotionEvent" in window;
|
|
169
169
|
}
|
|
170
|
-
function
|
|
170
|
+
function N() {
|
|
171
171
|
return "DeviceOrientationEvent" in window;
|
|
172
172
|
}
|
|
173
|
-
function
|
|
174
|
-
const n = typeof window < "u",
|
|
173
|
+
function R() {
|
|
174
|
+
const n = typeof window < "u", t = n && !!window.webkit, e = t && !!window.webkit?.messageHandlers, i = e && !!window.webkit?.messageHandlers?.aippyListener;
|
|
175
175
|
return console.log("🔍 [Aippy Sensors] hasNativeBridge check:", {
|
|
176
176
|
hasWindow: n,
|
|
177
|
-
hasWebkit:
|
|
178
|
-
hasMessageHandlers:
|
|
179
|
-
hasAippyListener:
|
|
180
|
-
result:
|
|
181
|
-
}),
|
|
177
|
+
hasWebkit: t,
|
|
178
|
+
hasMessageHandlers: e,
|
|
179
|
+
hasAippyListener: i,
|
|
180
|
+
result: i
|
|
181
|
+
}), i;
|
|
182
182
|
}
|
|
183
|
-
function
|
|
183
|
+
function I() {
|
|
184
184
|
return typeof window < "u" && typeof window.orientation < "u" ? window.orientation : typeof window < "u" && window.screen?.orientation?.angle !== void 0 ? window.screen.orientation.angle : 0;
|
|
185
185
|
}
|
|
186
|
-
function
|
|
187
|
-
switch (
|
|
186
|
+
function P(n, t, e) {
|
|
187
|
+
switch (e) {
|
|
188
188
|
case 0:
|
|
189
|
-
return [n,
|
|
189
|
+
return [n, -t];
|
|
190
190
|
case 180:
|
|
191
|
-
return [-n,
|
|
191
|
+
return [-n, t];
|
|
192
192
|
case 90:
|
|
193
|
-
return [
|
|
193
|
+
return [-t, n];
|
|
194
194
|
case -90:
|
|
195
|
-
return [
|
|
195
|
+
return [t, -n];
|
|
196
196
|
default:
|
|
197
|
-
return [n,
|
|
197
|
+
return [n, -t];
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
|
-
async function
|
|
201
|
-
if (console.log("🔐 [Aippy Sensors] requestMotionPermission called"),
|
|
200
|
+
async function b() {
|
|
201
|
+
if (console.log("🔐 [Aippy Sensors] requestMotionPermission called"), R())
|
|
202
202
|
return console.log("✅ [Aippy Sensors] Native bridge available, skipping permission request"), !0;
|
|
203
|
-
if (!
|
|
203
|
+
if (!E())
|
|
204
204
|
return console.warn("❌ [Aippy Sensors] Device motion not supported"), !1;
|
|
205
205
|
const n = typeof DeviceMotionEvent < "u" && typeof DeviceMotionEvent.requestPermission == "function";
|
|
206
206
|
if (console.log("🔍 [Aippy Sensors] Permission API available:", n), n)
|
|
207
207
|
try {
|
|
208
208
|
console.log("🙏 [Aippy Sensors] Requesting device motion permission...");
|
|
209
|
-
const
|
|
210
|
-
return console.log("📋 [Aippy Sensors] Permission result:",
|
|
211
|
-
} catch (
|
|
212
|
-
return console.warn("❌ [Aippy Sensors] Permission request failed:",
|
|
209
|
+
const t = await DeviceMotionEvent.requestPermission();
|
|
210
|
+
return console.log("📋 [Aippy Sensors] Permission result:", t), t === "granted";
|
|
211
|
+
} catch (t) {
|
|
212
|
+
return console.warn("❌ [Aippy Sensors] Permission request failed:", t), !1;
|
|
213
213
|
}
|
|
214
214
|
return console.log("✅ [Aippy Sensors] No permission needed (granted by default)"), !0;
|
|
215
215
|
}
|
|
216
|
-
function
|
|
216
|
+
function F(n) {
|
|
217
217
|
console.log("🔧 [Aippy Sensors] watchMotionNative - Setting up native bridge listener");
|
|
218
|
-
const
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
},
|
|
226
|
-
acceleration: {
|
|
227
|
-
x: h,
|
|
228
|
-
y: v,
|
|
229
|
-
z: u
|
|
230
|
-
// Z轴不受屏幕旋转影响
|
|
231
|
-
},
|
|
218
|
+
const t = k.addMotionListener((e) => {
|
|
219
|
+
const i = I(), o = e.gravity?.x ?? 0, r = e.gravity?.y ?? 0, s = e.gravity?.z ?? 0, a = e.userAcceleration?.x ?? 0, d = e.userAcceleration?.y ?? 0, u = e.userAcceleration?.z ?? 0, [m, l] = P(o, r, i), [y, v] = P(a, d, i), g = e.attitude && typeof e.attitude.yaw == "number" && typeof e.attitude.pitch == "number" && typeof e.attitude.roll == "number";
|
|
220
|
+
let w = 0;
|
|
221
|
+
g && (w = e.attitude.yaw * (180 / Math.PI), w < 0 && (w += 360));
|
|
222
|
+
const f = {
|
|
223
|
+
gravity: { x: m, y: l, z: s },
|
|
224
|
+
acceleration: { x: y, y: v, z: u },
|
|
232
225
|
accelerationIncludingGravity: {
|
|
233
|
-
x:
|
|
234
|
-
y:
|
|
235
|
-
z:
|
|
226
|
+
x: m + y,
|
|
227
|
+
y: l + v,
|
|
228
|
+
z: s + u
|
|
236
229
|
},
|
|
237
230
|
rotation: {
|
|
238
|
-
alpha:
|
|
239
|
-
beta:
|
|
240
|
-
gamma:
|
|
231
|
+
alpha: g ? w : (e.rotationRate?.z ?? 0) * (180 / Math.PI),
|
|
232
|
+
beta: (e.rotationRate?.x ?? 0) * (180 / Math.PI),
|
|
233
|
+
gamma: (e.rotationRate?.y ?? 0) * (180 / Math.PI)
|
|
241
234
|
},
|
|
235
|
+
attitude: g ? {
|
|
236
|
+
yaw: w,
|
|
237
|
+
pitch: e.attitude.pitch * (180 / Math.PI),
|
|
238
|
+
roll: e.attitude.roll * (180 / Math.PI),
|
|
239
|
+
quaternion: e.attitude.quaternion ? {
|
|
240
|
+
x: e.attitude.quaternion.x,
|
|
241
|
+
y: e.attitude.quaternion.y,
|
|
242
|
+
z: e.attitude.quaternion.z,
|
|
243
|
+
w: e.attitude.quaternion.w
|
|
244
|
+
} : void 0
|
|
245
|
+
} : void 0,
|
|
242
246
|
timestamp: Date.now()
|
|
243
247
|
};
|
|
244
|
-
n(
|
|
248
|
+
n(f);
|
|
245
249
|
});
|
|
246
|
-
return console.log("✅ [Aippy Sensors] watchMotionNative - Listener setup complete"),
|
|
250
|
+
return console.log("✅ [Aippy Sensors] watchMotionNative - Listener setup complete"), t;
|
|
247
251
|
}
|
|
248
|
-
function
|
|
249
|
-
if (!
|
|
250
|
-
throw
|
|
251
|
-
let
|
|
252
|
-
const
|
|
253
|
-
if (!
|
|
254
|
-
const d =
|
|
252
|
+
function M(n, t = !0) {
|
|
253
|
+
if (!E())
|
|
254
|
+
throw c("Device motion API is not supported", "NOT_SUPPORTED");
|
|
255
|
+
let e = !1, i = null;
|
|
256
|
+
const o = (a) => {
|
|
257
|
+
if (!e) return;
|
|
258
|
+
const d = I();
|
|
255
259
|
let u, m, l;
|
|
256
260
|
if (a.acceleration) {
|
|
257
|
-
const
|
|
258
|
-
u = (
|
|
261
|
+
const p = a.accelerationIncludingGravity, h = a.acceleration;
|
|
262
|
+
u = (p?.x ?? 0) - (h?.x ?? 0), m = (p?.y ?? 0) - (h?.y ?? 0), l = (p?.z ?? 0) - (h?.z ?? 0);
|
|
259
263
|
} else {
|
|
260
|
-
const
|
|
261
|
-
u = (
|
|
264
|
+
const p = a.accelerationIncludingGravity, h = 9.8;
|
|
265
|
+
u = (p?.x ?? 0) / h, m = (p?.y ?? 0) / h, l = (p?.z ?? 0) / h;
|
|
262
266
|
}
|
|
263
|
-
const
|
|
264
|
-
gravity: {
|
|
265
|
-
|
|
266
|
-
y: N,
|
|
267
|
-
z: l
|
|
268
|
-
// Z轴不受屏幕旋转影响
|
|
269
|
-
},
|
|
270
|
-
acceleration: {
|
|
271
|
-
x: O,
|
|
272
|
-
y: S,
|
|
273
|
-
z: g
|
|
274
|
-
// Z轴不受屏幕旋转影响
|
|
275
|
-
},
|
|
267
|
+
const y = a.acceleration?.x ?? 0, v = a.acceleration?.y ?? 0, g = a.acceleration?.z ?? 0, [w, f] = P(u, m, d), [O, A] = P(y, v, d), U = {
|
|
268
|
+
gravity: { x: w, y: f, z: l },
|
|
269
|
+
acceleration: { x: O, y: A, z: g },
|
|
276
270
|
accelerationIncludingGravity: {
|
|
277
|
-
x:
|
|
278
|
-
y:
|
|
271
|
+
x: w + O,
|
|
272
|
+
y: f + A,
|
|
279
273
|
z: l + g
|
|
280
274
|
},
|
|
281
275
|
rotation: {
|
|
@@ -285,144 +279,132 @@ function G(n, e = !0) {
|
|
|
285
279
|
},
|
|
286
280
|
timestamp: Date.now()
|
|
287
281
|
};
|
|
288
|
-
n(
|
|
282
|
+
n(U);
|
|
289
283
|
}, r = async () => {
|
|
290
|
-
|
|
284
|
+
t && !await b() || (e = !0, window.addEventListener("devicemotion", o));
|
|
291
285
|
};
|
|
292
286
|
return (async () => {
|
|
293
|
-
if (typeof DeviceMotionEvent < "u" && typeof DeviceMotionEvent.requestPermission == "function" &&
|
|
287
|
+
if (typeof DeviceMotionEvent < "u" && typeof DeviceMotionEvent.requestPermission == "function" && t) {
|
|
294
288
|
const d = async () => {
|
|
295
|
-
|
|
289
|
+
i = null, await r();
|
|
296
290
|
};
|
|
297
|
-
window.addEventListener("click", d, { once: !0 }), window.addEventListener("touchstart", d, { once: !0 }),
|
|
291
|
+
window.addEventListener("click", d, { once: !0 }), window.addEventListener("touchstart", d, { once: !0 }), i = () => {
|
|
298
292
|
window.removeEventListener("click", d), window.removeEventListener("touchstart", d);
|
|
299
293
|
};
|
|
300
294
|
} else
|
|
301
295
|
await r();
|
|
302
296
|
})(), () => {
|
|
303
|
-
|
|
297
|
+
e = !1, window.removeEventListener("devicemotion", o), i && (i(), i = null);
|
|
304
298
|
};
|
|
305
299
|
}
|
|
306
|
-
function
|
|
307
|
-
|
|
308
|
-
|
|
300
|
+
function _(n, t, e = 500) {
|
|
301
|
+
let i = !1, o = null;
|
|
302
|
+
const r = F((a) => {
|
|
303
|
+
i || (i = !0, clearTimeout(s)), n(a);
|
|
304
|
+
}), s = setTimeout(() => {
|
|
305
|
+
i || (console.warn("[Aippy Sensors] No native data, falling back to Web API"), r(), o = M(n, t));
|
|
306
|
+
}, e);
|
|
307
|
+
return () => {
|
|
308
|
+
clearTimeout(s), r(), o?.();
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
function K(n, t = !0) {
|
|
312
|
+
return R() ? _(n, t) : M(n, t);
|
|
309
313
|
}
|
|
310
|
-
function
|
|
311
|
-
if (!
|
|
312
|
-
throw
|
|
313
|
-
const
|
|
314
|
-
|
|
315
|
-
alpha:
|
|
316
|
-
beta:
|
|
317
|
-
gamma:
|
|
314
|
+
function X(n) {
|
|
315
|
+
if (!N())
|
|
316
|
+
throw c("Device orientation API is not supported", "NOT_SUPPORTED");
|
|
317
|
+
const t = (e) => {
|
|
318
|
+
n({
|
|
319
|
+
alpha: e.alpha ?? 0,
|
|
320
|
+
beta: e.beta ?? 0,
|
|
321
|
+
gamma: e.gamma ?? 0,
|
|
318
322
|
timestamp: Date.now()
|
|
319
|
-
};
|
|
320
|
-
n(o);
|
|
323
|
+
});
|
|
321
324
|
};
|
|
322
|
-
return window.addEventListener("deviceorientation",
|
|
323
|
-
window.removeEventListener("deviceorientation",
|
|
325
|
+
return window.addEventListener("deviceorientation", t), () => {
|
|
326
|
+
window.removeEventListener("deviceorientation", t);
|
|
324
327
|
};
|
|
325
328
|
}
|
|
326
329
|
class z {
|
|
327
|
-
/**
|
|
328
|
-
* Check if device orientation is supported
|
|
329
|
-
*/
|
|
330
330
|
isOrientationSupported() {
|
|
331
|
-
return
|
|
331
|
+
return N();
|
|
332
332
|
}
|
|
333
|
-
/**
|
|
334
|
-
* Check if device motion is supported
|
|
335
|
-
*/
|
|
336
333
|
isMotionSupported() {
|
|
337
|
-
return
|
|
334
|
+
return E();
|
|
338
335
|
}
|
|
339
|
-
/**
|
|
340
|
-
* Get device orientation data
|
|
341
|
-
*/
|
|
342
336
|
async getOrientation() {
|
|
343
337
|
if (!this.isOrientationSupported())
|
|
344
|
-
throw
|
|
345
|
-
return new Promise((
|
|
346
|
-
const
|
|
347
|
-
window.removeEventListener("deviceorientation",
|
|
348
|
-
x:
|
|
349
|
-
y:
|
|
350
|
-
z:
|
|
338
|
+
throw c("Device orientation API is not supported", "NOT_SUPPORTED");
|
|
339
|
+
return new Promise((t, e) => {
|
|
340
|
+
const i = (o) => {
|
|
341
|
+
window.removeEventListener("deviceorientation", i), t({
|
|
342
|
+
x: o.alpha ?? 0,
|
|
343
|
+
y: o.beta ?? 0,
|
|
344
|
+
z: o.gamma ?? 0,
|
|
351
345
|
timestamp: Date.now()
|
|
352
346
|
});
|
|
353
347
|
};
|
|
354
|
-
window.addEventListener("deviceorientation",
|
|
355
|
-
window.removeEventListener("deviceorientation",
|
|
348
|
+
window.addEventListener("deviceorientation", i), setTimeout(() => {
|
|
349
|
+
window.removeEventListener("deviceorientation", i), e(c("Device orientation timeout", "UNKNOWN_ERROR"));
|
|
356
350
|
}, 5e3);
|
|
357
351
|
});
|
|
358
352
|
}
|
|
359
|
-
/**
|
|
360
|
-
|
|
361
|
-
* @deprecated Use watchOrientation() function instead
|
|
362
|
-
*/
|
|
363
|
-
watchOrientation(e) {
|
|
353
|
+
/** @deprecated Use watchOrientation() instead */
|
|
354
|
+
watchOrientation(t) {
|
|
364
355
|
if (!this.isOrientationSupported())
|
|
365
|
-
throw
|
|
366
|
-
const
|
|
367
|
-
|
|
368
|
-
x:
|
|
369
|
-
y:
|
|
370
|
-
z:
|
|
356
|
+
throw c("Device orientation API is not supported", "NOT_SUPPORTED");
|
|
357
|
+
const e = (i) => {
|
|
358
|
+
t({
|
|
359
|
+
x: i.alpha ?? 0,
|
|
360
|
+
y: i.beta ?? 0,
|
|
361
|
+
z: i.gamma ?? 0,
|
|
371
362
|
timestamp: Date.now()
|
|
372
363
|
});
|
|
373
364
|
};
|
|
374
|
-
return window.addEventListener("deviceorientation",
|
|
375
|
-
window.removeEventListener("deviceorientation",
|
|
365
|
+
return window.addEventListener("deviceorientation", e), () => {
|
|
366
|
+
window.removeEventListener("deviceorientation", e);
|
|
376
367
|
};
|
|
377
368
|
}
|
|
378
|
-
/**
|
|
379
|
-
* Get device motion data
|
|
380
|
-
*/
|
|
381
369
|
async getMotion() {
|
|
382
370
|
if (!this.isMotionSupported())
|
|
383
|
-
throw
|
|
384
|
-
return new Promise((
|
|
385
|
-
const
|
|
386
|
-
window.removeEventListener("devicemotion",
|
|
387
|
-
x:
|
|
388
|
-
y:
|
|
389
|
-
z:
|
|
371
|
+
throw c("Device motion API is not supported", "NOT_SUPPORTED");
|
|
372
|
+
return new Promise((t, e) => {
|
|
373
|
+
const i = (o) => {
|
|
374
|
+
window.removeEventListener("devicemotion", i), t({
|
|
375
|
+
x: o.acceleration?.x ?? 0,
|
|
376
|
+
y: o.acceleration?.y ?? 0,
|
|
377
|
+
z: o.acceleration?.z ?? 0,
|
|
390
378
|
timestamp: Date.now()
|
|
391
379
|
});
|
|
392
380
|
};
|
|
393
|
-
window.addEventListener("devicemotion",
|
|
394
|
-
window.removeEventListener("devicemotion",
|
|
381
|
+
window.addEventListener("devicemotion", i), setTimeout(() => {
|
|
382
|
+
window.removeEventListener("devicemotion", i), e(c("Device motion timeout", "UNKNOWN_ERROR"));
|
|
395
383
|
}, 5e3);
|
|
396
384
|
});
|
|
397
385
|
}
|
|
398
|
-
/**
|
|
399
|
-
|
|
400
|
-
* @deprecated Use watchMotion() function instead
|
|
401
|
-
*/
|
|
402
|
-
watchMotion(e) {
|
|
386
|
+
/** @deprecated Use watchMotion() instead */
|
|
387
|
+
watchMotion(t) {
|
|
403
388
|
if (!this.isMotionSupported())
|
|
404
|
-
throw
|
|
405
|
-
const
|
|
406
|
-
|
|
407
|
-
x:
|
|
408
|
-
y:
|
|
409
|
-
z:
|
|
389
|
+
throw c("Device motion API is not supported", "NOT_SUPPORTED");
|
|
390
|
+
const e = (i) => {
|
|
391
|
+
t({
|
|
392
|
+
x: i.acceleration?.x ?? 0,
|
|
393
|
+
y: i.acceleration?.y ?? 0,
|
|
394
|
+
z: i.acceleration?.z ?? 0,
|
|
410
395
|
timestamp: Date.now()
|
|
411
396
|
});
|
|
412
397
|
};
|
|
413
|
-
return window.addEventListener("devicemotion",
|
|
414
|
-
window.removeEventListener("devicemotion",
|
|
398
|
+
return window.addEventListener("devicemotion", e), () => {
|
|
399
|
+
window.removeEventListener("devicemotion", e);
|
|
415
400
|
};
|
|
416
401
|
}
|
|
417
|
-
/**
|
|
418
|
-
* Request permission for motion sensors (iOS 13+)
|
|
419
|
-
*/
|
|
420
402
|
async requestPermission() {
|
|
421
|
-
return
|
|
403
|
+
return b();
|
|
422
404
|
}
|
|
423
405
|
}
|
|
424
|
-
const
|
|
425
|
-
class
|
|
406
|
+
const Y = new z();
|
|
407
|
+
class G {
|
|
426
408
|
/**
|
|
427
409
|
* Check if file system access is supported
|
|
428
410
|
*/
|
|
@@ -438,28 +420,28 @@ class W {
|
|
|
438
420
|
/**
|
|
439
421
|
* Open file picker (modern API)
|
|
440
422
|
*/
|
|
441
|
-
async openFilePicker(
|
|
423
|
+
async openFilePicker(t = {}) {
|
|
442
424
|
if (!this.isSupported())
|
|
443
|
-
throw
|
|
425
|
+
throw c("File System Access API is not supported", "NOT_SUPPORTED");
|
|
444
426
|
try {
|
|
445
|
-
const
|
|
446
|
-
types:
|
|
427
|
+
const e = {
|
|
428
|
+
types: t.accept ? [{
|
|
447
429
|
description: "Files",
|
|
448
430
|
accept: Object.fromEntries(
|
|
449
|
-
|
|
431
|
+
t.accept.map((r) => [r, [r]])
|
|
450
432
|
)
|
|
451
433
|
}] : void 0,
|
|
452
|
-
multiple:
|
|
453
|
-
},
|
|
454
|
-
|
|
434
|
+
multiple: t.multiple ?? !1
|
|
435
|
+
}, i = await window.showOpenFilePicker(e), o = await Promise.all(
|
|
436
|
+
i.map(async (r) => r.getFile())
|
|
455
437
|
);
|
|
456
438
|
return {
|
|
457
|
-
files:
|
|
458
|
-
paths:
|
|
439
|
+
files: o,
|
|
440
|
+
paths: o.map((r) => r.name)
|
|
459
441
|
};
|
|
460
|
-
} catch (
|
|
461
|
-
throw
|
|
462
|
-
`Failed to open file picker: ${
|
|
442
|
+
} catch (e) {
|
|
443
|
+
throw e instanceof Error && e.name === "AbortError" ? c("File picker was cancelled", "PERMISSION_DENIED") : c(
|
|
444
|
+
`Failed to open file picker: ${e instanceof Error ? e.message : "Unknown error"}`,
|
|
463
445
|
"PERMISSION_DENIED"
|
|
464
446
|
);
|
|
465
447
|
}
|
|
@@ -467,38 +449,38 @@ class W {
|
|
|
467
449
|
/**
|
|
468
450
|
* Open file picker (legacy fallback)
|
|
469
451
|
*/
|
|
470
|
-
async openFilePickerLegacy(
|
|
452
|
+
async openFilePickerLegacy(t = {}) {
|
|
471
453
|
if (!this.isLegacySupported())
|
|
472
|
-
throw
|
|
473
|
-
return new Promise((
|
|
474
|
-
const
|
|
475
|
-
|
|
476
|
-
const
|
|
477
|
-
|
|
454
|
+
throw c("File input is not supported", "NOT_SUPPORTED");
|
|
455
|
+
return new Promise((e, i) => {
|
|
456
|
+
const o = document.createElement("input");
|
|
457
|
+
o.type = "file", o.multiple = t.multiple ?? !1, o.accept = t.accept?.join(",") ?? "", o.onchange = (r) => {
|
|
458
|
+
const s = r.target, a = Array.from(s.files || []);
|
|
459
|
+
e({
|
|
478
460
|
files: a,
|
|
479
461
|
paths: a.map((d) => d.name)
|
|
480
462
|
});
|
|
481
|
-
},
|
|
482
|
-
|
|
483
|
-
},
|
|
463
|
+
}, o.oncancel = () => {
|
|
464
|
+
i(c("File picker was cancelled", "PERMISSION_DENIED"));
|
|
465
|
+
}, o.click();
|
|
484
466
|
});
|
|
485
467
|
}
|
|
486
468
|
/**
|
|
487
469
|
* Open file picker with fallback
|
|
488
470
|
*/
|
|
489
|
-
async openFile(
|
|
490
|
-
return this.isSupported() ? await this.openFilePicker(
|
|
471
|
+
async openFile(t = {}) {
|
|
472
|
+
return this.isSupported() ? await this.openFilePicker(t) : await this.openFilePickerLegacy(t);
|
|
491
473
|
}
|
|
492
474
|
/**
|
|
493
475
|
* Save file
|
|
494
476
|
*/
|
|
495
|
-
async saveFile(
|
|
477
|
+
async saveFile(t, e) {
|
|
496
478
|
try {
|
|
497
|
-
const
|
|
498
|
-
|
|
499
|
-
} catch (
|
|
500
|
-
throw
|
|
501
|
-
`Failed to save file: ${
|
|
479
|
+
const i = URL.createObjectURL(t), o = document.createElement("a");
|
|
480
|
+
o.href = i, o.download = e, document.body.appendChild(o), o.click(), document.body.removeChild(o), URL.revokeObjectURL(i);
|
|
481
|
+
} catch (i) {
|
|
482
|
+
throw c(
|
|
483
|
+
`Failed to save file: ${i instanceof Error ? i.message : "Unknown error"}`,
|
|
502
484
|
"UNKNOWN_ERROR"
|
|
503
485
|
);
|
|
504
486
|
}
|
|
@@ -506,51 +488,51 @@ class W {
|
|
|
506
488
|
/**
|
|
507
489
|
* Read file as text
|
|
508
490
|
*/
|
|
509
|
-
async readAsText(
|
|
510
|
-
return new Promise((
|
|
511
|
-
const
|
|
512
|
-
|
|
491
|
+
async readAsText(t) {
|
|
492
|
+
return new Promise((e, i) => {
|
|
493
|
+
const o = new FileReader();
|
|
494
|
+
o.onload = () => e(o.result), o.onerror = () => i(c("Failed to read file", "UNKNOWN_ERROR")), o.readAsText(t);
|
|
513
495
|
});
|
|
514
496
|
}
|
|
515
497
|
/**
|
|
516
498
|
* Read file as data URL
|
|
517
499
|
*/
|
|
518
|
-
async readAsDataURL(
|
|
519
|
-
return new Promise((
|
|
520
|
-
const
|
|
521
|
-
|
|
500
|
+
async readAsDataURL(t) {
|
|
501
|
+
return new Promise((e, i) => {
|
|
502
|
+
const o = new FileReader();
|
|
503
|
+
o.onload = () => e(o.result), o.onerror = () => i(c("Failed to read file", "UNKNOWN_ERROR")), o.readAsDataURL(t);
|
|
522
504
|
});
|
|
523
505
|
}
|
|
524
506
|
}
|
|
525
|
-
const
|
|
526
|
-
function
|
|
527
|
-
return new Promise((
|
|
507
|
+
const j = new G();
|
|
508
|
+
function $(n) {
|
|
509
|
+
return new Promise((t) => {
|
|
528
510
|
if ("vibrate" in navigator)
|
|
529
|
-
navigator.vibrate(n),
|
|
511
|
+
navigator.vibrate(n), t();
|
|
530
512
|
else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.aippyListener) {
|
|
531
|
-
const
|
|
513
|
+
const e = {
|
|
532
514
|
command: "navigator.vibrate",
|
|
533
515
|
parameters: n
|
|
534
516
|
};
|
|
535
|
-
window.webkit.messageHandlers.aippyListener.postMessage(
|
|
517
|
+
window.webkit.messageHandlers.aippyListener.postMessage(e), t();
|
|
536
518
|
} else
|
|
537
|
-
console.warn("Vibration not supported in this environment"),
|
|
519
|
+
console.warn("Vibration not supported in this environment"), t();
|
|
538
520
|
});
|
|
539
521
|
}
|
|
540
522
|
export {
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
523
|
+
D as CameraAPI,
|
|
524
|
+
G as FileSystemAPI,
|
|
525
|
+
x as GeolocationAPI,
|
|
544
526
|
z as SensorsAPI,
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
527
|
+
H as camera,
|
|
528
|
+
j as fileSystem,
|
|
529
|
+
C as geolocation,
|
|
530
|
+
R as hasNativeBridge,
|
|
531
|
+
E as isMotionSupported,
|
|
532
|
+
N as isOrientationSupported,
|
|
533
|
+
b as requestMotionPermission,
|
|
534
|
+
Y as sensors,
|
|
535
|
+
$ as vibrate,
|
|
536
|
+
K as watchMotion,
|
|
537
|
+
X as watchOrientation
|
|
556
538
|
};
|
package/dist/device/sensors.d.ts
CHANGED
|
@@ -1,74 +1,24 @@
|
|
|
1
1
|
import { SensorData, MotionData, OrientationData } from './types';
|
|
2
|
-
/**
|
|
3
|
-
* Check if device motion is supported
|
|
4
|
-
*/
|
|
5
2
|
export declare function isMotionSupported(): boolean;
|
|
6
|
-
/**
|
|
7
|
-
* Check if device orientation is supported
|
|
8
|
-
*/
|
|
9
3
|
export declare function isOrientationSupported(): boolean;
|
|
10
|
-
/**
|
|
11
|
-
* Check if native bridge is available
|
|
12
|
-
*/
|
|
13
4
|
export declare function hasNativeBridge(): boolean;
|
|
14
|
-
/**
|
|
15
|
-
* Request permission for motion sensors (iOS 13+)
|
|
16
|
-
* @returns Promise<boolean> - true if permission granted
|
|
17
|
-
*/
|
|
5
|
+
/** Request motion sensor permission (iOS 13+) */
|
|
18
6
|
export declare function requestMotionPermission(): Promise<boolean>;
|
|
19
|
-
/**
|
|
20
|
-
* Watch device motion changes with full motion data
|
|
21
|
-
* Automatically uses native bridge if available, otherwise falls back to Web API
|
|
22
|
-
*
|
|
23
|
-
* @param callback - Function to call with motion data
|
|
24
|
-
* @param autoRequestPermission - Automatically request permission on iOS (default: true, only for Web API)
|
|
25
|
-
* @returns Cleanup function to stop watching
|
|
26
|
-
*/
|
|
7
|
+
/** Watch device motion (auto selects native bridge or Web API) */
|
|
27
8
|
export declare function watchMotion(callback: (data: MotionData) => void, autoRequestPermission?: boolean): () => void;
|
|
28
|
-
/**
|
|
29
|
-
* Watch device orientation changes
|
|
30
|
-
* @param callback - Function to call with orientation data
|
|
31
|
-
* @returns Cleanup function to stop watching
|
|
32
|
-
*/
|
|
9
|
+
/** Watch device orientation changes */
|
|
33
10
|
export declare function watchOrientation(callback: (data: OrientationData) => void): () => void;
|
|
34
|
-
/**
|
|
35
|
-
* Legacy SensorsAPI class for backward compatibility
|
|
36
|
-
* @deprecated Use watchMotion() and watchOrientation() functions instead
|
|
37
|
-
*/
|
|
11
|
+
/** @deprecated Use watchMotion() and watchOrientation() instead */
|
|
38
12
|
export declare class SensorsAPI {
|
|
39
|
-
/**
|
|
40
|
-
* Check if device orientation is supported
|
|
41
|
-
*/
|
|
42
13
|
isOrientationSupported(): boolean;
|
|
43
|
-
/**
|
|
44
|
-
* Check if device motion is supported
|
|
45
|
-
*/
|
|
46
14
|
isMotionSupported(): boolean;
|
|
47
|
-
/**
|
|
48
|
-
* Get device orientation data
|
|
49
|
-
*/
|
|
50
15
|
getOrientation(): Promise<SensorData>;
|
|
51
|
-
/**
|
|
52
|
-
* Watch device orientation changes
|
|
53
|
-
* @deprecated Use watchOrientation() function instead
|
|
54
|
-
*/
|
|
16
|
+
/** @deprecated Use watchOrientation() instead */
|
|
55
17
|
watchOrientation(callback: (data: SensorData) => void): () => void;
|
|
56
|
-
/**
|
|
57
|
-
* Get device motion data
|
|
58
|
-
*/
|
|
59
18
|
getMotion(): Promise<SensorData>;
|
|
60
|
-
/**
|
|
61
|
-
* Watch device motion changes
|
|
62
|
-
* @deprecated Use watchMotion() function instead
|
|
63
|
-
*/
|
|
19
|
+
/** @deprecated Use watchMotion() instead */
|
|
64
20
|
watchMotion(callback: (data: SensorData) => void): () => void;
|
|
65
|
-
/**
|
|
66
|
-
* Request permission for motion sensors (iOS 13+)
|
|
67
|
-
*/
|
|
68
21
|
requestPermission(): Promise<boolean>;
|
|
69
22
|
}
|
|
70
|
-
/**
|
|
71
|
-
* Sensors API instance (for backward compatibility)
|
|
72
|
-
* @deprecated Use watchMotion() and watchOrientation() functions instead
|
|
73
|
-
*/
|
|
23
|
+
/** @deprecated Use watchMotion() and watchOrientation() instead */
|
|
74
24
|
export declare const sensors: SensorsAPI;
|
package/dist/device/types.d.ts
CHANGED
|
@@ -77,12 +77,31 @@ export interface MotionData {
|
|
|
77
77
|
y: number;
|
|
78
78
|
z: number;
|
|
79
79
|
};
|
|
80
|
-
/** Rotation rate (deg/s) */
|
|
80
|
+
/** Rotation rate (deg/s) - Angular velocity */
|
|
81
81
|
rotation: {
|
|
82
82
|
alpha: number;
|
|
83
83
|
beta: number;
|
|
84
84
|
gamma: number;
|
|
85
85
|
};
|
|
86
|
+
/**
|
|
87
|
+
* Device attitude/orientation (degrees) - Absolute orientation
|
|
88
|
+
* Available when iOS native bridge provides CMDeviceMotion.attitude data
|
|
89
|
+
*/
|
|
90
|
+
attitude?: {
|
|
91
|
+
/** Rotation around Z axis (0-360°) - Compass heading */
|
|
92
|
+
yaw: number;
|
|
93
|
+
/** Rotation around X axis - Forward/backward tilt */
|
|
94
|
+
pitch: number;
|
|
95
|
+
/** Rotation around Y axis - Left/right tilt */
|
|
96
|
+
roll: number;
|
|
97
|
+
/** Quaternion representation (optional) */
|
|
98
|
+
quaternion?: {
|
|
99
|
+
x: number;
|
|
100
|
+
y: number;
|
|
101
|
+
z: number;
|
|
102
|
+
w: number;
|
|
103
|
+
};
|
|
104
|
+
};
|
|
86
105
|
/** Timestamp */
|
|
87
106
|
timestamp: number;
|
|
88
107
|
}
|
|
@@ -1,42 +1,46 @@
|
|
|
1
1
|
function r(e, o) {
|
|
2
2
|
try {
|
|
3
3
|
if (window.parent && window.parent !== window) {
|
|
4
|
-
const
|
|
4
|
+
const a = {
|
|
5
5
|
__aippyGame: !0,
|
|
6
6
|
payload: e
|
|
7
7
|
};
|
|
8
|
-
window.parent.postMessage(
|
|
8
|
+
window.parent.postMessage(a, "*");
|
|
9
9
|
}
|
|
10
|
-
const
|
|
11
|
-
|
|
10
|
+
const n = window.webkit?.messageHandlers?.aippyListener;
|
|
11
|
+
n && n.postMessage({
|
|
12
12
|
command: o,
|
|
13
13
|
parameters: JSON.stringify(e)
|
|
14
14
|
});
|
|
15
|
-
} catch (
|
|
16
|
-
console.warn("[Aippy Leaderboard] Failed to send game event:",
|
|
15
|
+
} catch (n) {
|
|
16
|
+
console.warn("[Aippy Leaderboard] Failed to send game event:", n);
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
function t(e) {
|
|
20
|
-
|
|
20
|
+
const o = {
|
|
21
21
|
type: "score",
|
|
22
|
-
score: e
|
|
23
|
-
|
|
22
|
+
score: e,
|
|
23
|
+
url: window.location.href
|
|
24
|
+
};
|
|
25
|
+
r(o, "leaderboard.reportScore"), console.log(`[Aippy Leaderboard] Score reported: ${e}, URL: ${window.location.href}`);
|
|
24
26
|
}
|
|
25
|
-
function
|
|
26
|
-
|
|
27
|
+
function d(e) {
|
|
28
|
+
const o = {
|
|
27
29
|
type: "score",
|
|
28
|
-
score: e
|
|
29
|
-
|
|
30
|
+
score: e,
|
|
31
|
+
url: window.location.href
|
|
32
|
+
};
|
|
33
|
+
r(o, "leaderboard.updateScore"), console.log(`[Aippy Leaderboard] Score updated: ${e}, URL: ${window.location.href}`);
|
|
30
34
|
}
|
|
31
|
-
function
|
|
32
|
-
const
|
|
35
|
+
function i(e, o) {
|
|
36
|
+
const n = {
|
|
33
37
|
type: e,
|
|
34
38
|
...o
|
|
35
39
|
};
|
|
36
|
-
r(
|
|
40
|
+
r(n, "leaderboard.event"), console.log(`[Aippy Leaderboard] Event sent: ${e}`, o);
|
|
37
41
|
}
|
|
38
42
|
export {
|
|
39
43
|
t as reportScore,
|
|
40
|
-
|
|
41
|
-
|
|
44
|
+
i as sendEvent,
|
|
45
|
+
d as updateScore
|
|
42
46
|
};
|
|
@@ -9,6 +9,8 @@ export interface ScorePayload {
|
|
|
9
9
|
type: 'score';
|
|
10
10
|
/** The score value */
|
|
11
11
|
score: number;
|
|
12
|
+
/** The URL of the current H5 application */
|
|
13
|
+
url?: string;
|
|
12
14
|
/** Score unit (e.g., 'points', 'coins') */
|
|
13
15
|
unit?: string;
|
|
14
16
|
/** Whether bigger score is better for leaderboard ranking */
|