@aippy/runtime 0.2.5-dev.1 โ†’ 0.2.6

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.
@@ -1,72 +1,24 @@
1
- import { hasNativeBridge } from '../core/native-bridge';
2
1
  import { SensorData, MotionData, OrientationData } from './types';
3
- export { hasNativeBridge };
4
- /**
5
- * Check if device motion is supported
6
- */
7
2
  export declare function isMotionSupported(): boolean;
8
- /**
9
- * Check if device orientation is supported
10
- */
11
3
  export declare function isOrientationSupported(): boolean;
12
- /**
13
- * Request permission for motion sensors (iOS 13+)
14
- * @returns Promise<boolean> - true if permission granted
15
- */
4
+ export declare function hasNativeBridge(): boolean;
5
+ /** Request motion sensor permission (iOS 13+) */
16
6
  export declare function requestMotionPermission(): Promise<boolean>;
17
- /**
18
- * Watch device motion changes with full motion data
19
- * Automatically uses native bridge if available, otherwise falls back to Web API
20
- *
21
- * @param callback - Function to call with motion data
22
- * @param autoRequestPermission - Automatically request permission on iOS (default: true, only for Web API)
23
- * @returns Cleanup function to stop watching
24
- */
7
+ /** Watch device motion (auto selects native bridge or Web API) */
25
8
  export declare function watchMotion(callback: (data: MotionData) => void, autoRequestPermission?: boolean): () => void;
26
- /**
27
- * Watch device orientation changes
28
- * @param callback - Function to call with orientation data
29
- * @returns Cleanup function to stop watching
30
- */
9
+ /** Watch device orientation changes */
31
10
  export declare function watchOrientation(callback: (data: OrientationData) => void): () => void;
32
- /**
33
- * Legacy SensorsAPI class for backward compatibility
34
- * @deprecated Use watchMotion() and watchOrientation() functions instead
35
- */
11
+ /** @deprecated Use watchMotion() and watchOrientation() instead */
36
12
  export declare class SensorsAPI {
37
- /**
38
- * Check if device orientation is supported
39
- */
40
13
  isOrientationSupported(): boolean;
41
- /**
42
- * Check if device motion is supported
43
- */
44
14
  isMotionSupported(): boolean;
45
- /**
46
- * Get device orientation data
47
- */
48
15
  getOrientation(): Promise<SensorData>;
49
- /**
50
- * Watch device orientation changes
51
- * @deprecated Use watchOrientation() function instead
52
- */
16
+ /** @deprecated Use watchOrientation() instead */
53
17
  watchOrientation(callback: (data: SensorData) => void): () => void;
54
- /**
55
- * Get device motion data
56
- */
57
18
  getMotion(): Promise<SensorData>;
58
- /**
59
- * Watch device motion changes
60
- * @deprecated Use watchMotion() function instead
61
- */
19
+ /** @deprecated Use watchMotion() instead */
62
20
  watchMotion(callback: (data: SensorData) => void): () => void;
63
- /**
64
- * Request permission for motion sensors (iOS 13+)
65
- */
66
21
  requestPermission(): Promise<boolean>;
67
22
  }
68
- /**
69
- * Sensors API instance (for backward compatibility)
70
- * @deprecated Use watchMotion() and watchOrientation() functions instead
71
- */
23
+ /** @deprecated Use watchMotion() and watchOrientation() instead */
72
24
  export declare const sensors: SensorsAPI;
@@ -1,101 +1,55 @@
1
- import { DEFAULT_CONFIG as r, SDK_NAME as s, VERSION as o, getConfigFromEnv as t, getVersionInfo as i, mergeConfig as n } from "../core/index.js";
2
- import { A as m, E as d, c as u } from "../errors-CDEBaBxB.js";
3
- import { A as C, C as c, R as E, a as l, p as A } from "../runtime-CmoG3v2m.js";
4
- import { CameraAPI as I, FileSystemAPI as U, GeolocationAPI as S, SensorsAPI as T, camera as P, fileSystem as y, geolocation as h, isMotionSupported as _, isOrientationSupported as O, requestMotionPermission as D, sensors as x, vibrate as R, watchMotion as k, watchOrientation as M } from "../device/index.js";
5
- import { c as F, a as N, P as L, b as B, p as v, d as w } from "../pwa-8DGmPqLV.js";
6
- import { a as H, b as j } from "../useTweaks-QxMRmg7i.js";
7
- import { c as Q, a as V, b as J, i as z, p as K, u as W } from "../useAudioContext-CNQQSTab.js";
8
- import { reportScore as X, sendEvent as Z, updateScore as $ } from "../leaderboard/index.js";
9
- import { D as ae, i as re, j as se, h as oe, U as te, f as ie, g as ne, k as pe, a as me, b as de, c as ue, e as fe, d as Ce, m as ce, l as Ee, n as le, p as Ae } from "../errors-D29z-Qus.js";
10
- import { f as Ie, b as Ue, h as Se, l as Te, j as Pe, g as ye, k as he, e as _e, i as Oe, c as De, d as xe, r as Re, s as ke, a as Me, t as be } from "../bridge-DdAH4txB.js";
11
- import { e as Ne, f as Le, g as Be, a as ve, u as we, b as Ge, d as He, c as je, h as qe } from "../userSessionInfo-CBk9ywXi.js";
12
- import { h as Ve } from "../native-bridge-JAmH-zTN.js";
1
+ import { DEFAULT_CONFIG as o, SDK_NAME as t, VERSION as r, getConfigFromEnv as i, getVersionInfo as s, mergeConfig as n } from "../core/index.js";
2
+ import { a as m, A as c, C as d, E as f, R as u, b as l, c as A, p as S } from "../runtime-DjBdOttl.js";
3
+ import { CameraAPI as C, FileSystemAPI as R, GeolocationAPI as x, SensorsAPI as M, camera as P, fileSystem as I, geolocation as g, hasNativeBridge as y, isMotionSupported as O, isOrientationSupported as b, requestMotionPermission as v, sensors as D, vibrate as h, watchMotion as w, watchOrientation as F } from "../device/index.js";
4
+ import { c as T, a as V, P as _, b as k, p as G, d as H } from "../pwa-8DGmPqLV.js";
5
+ import { a as q, b as B } from "../useTweaks-QxMRmg7i.js";
6
+ import { c as L, a as W, b as j, i as z, p as J, u as Q } from "../useAudioContext-CNQQSTab.js";
7
+ import { reportScore as Y, sendEvent as Z, updateScore as $ } from "../leaderboard/index.js";
13
8
  export {
14
- C as AippyRuntime,
15
- m as AippyRuntimeError,
16
- I as CameraAPI,
17
- c as Cancellable,
18
- ae as DEFAULT_BASE_URL,
19
- re as DEFAULT_CHAT_MODEL,
20
- se as DEFAULT_CHAT_SYSTEM,
21
- r as DEFAULT_CONFIG,
22
- oe as DEFAULT_UI_BASE_URL,
23
- d as ERROR_CODES,
24
- U as FileSystemAPI,
25
- S as GeolocationAPI,
26
- F as PWAUtils,
27
- N as PerformanceMonitor,
28
- L as PlatformDetector,
29
- E as ReceiveChannel,
30
- s as SDK_NAME,
31
- T as SensorsAPI,
32
- te as UI_CHAT_ENDPOINT,
33
- ie as UI_COMPLETION_ENDPOINT,
34
- ne as UI_OBJECT_ENDPOINT,
35
- o as VERSION,
36
- pe as abortedError,
37
- me as aippy,
38
- de as aippyChatConfig,
39
- ue as aippyCompletionConfig,
40
- fe as aippyObjectBaseConfig,
41
- Ce as aippyObjectConfig,
9
+ m as AippyRuntime,
10
+ c as AippyRuntimeError,
11
+ C as CameraAPI,
12
+ d as Cancellable,
13
+ o as DEFAULT_CONFIG,
14
+ f as ERROR_CODES,
15
+ R as FileSystemAPI,
16
+ x as GeolocationAPI,
17
+ T as PWAUtils,
18
+ V as PerformanceMonitor,
19
+ _ as PlatformDetector,
20
+ u as ReceiveChannel,
21
+ t as SDK_NAME,
22
+ M as SensorsAPI,
23
+ r as VERSION,
42
24
  l as aippyRuntime,
43
- H as aippyTweaks,
44
- j as aippyTweaksRuntime,
45
- Ie as autoRequestCredentials,
25
+ q as aippyTweaks,
26
+ B as aippyTweaksRuntime,
46
27
  P as camera,
47
- Ne as clearProfileCache,
48
- u as createError,
49
- Q as createHiddenMediaElement,
50
- V as createHiddenVideoElement,
51
- Le as fetchUserProfile,
52
- y as fileSystem,
53
- h as geolocation,
54
- Ue as getAuthToken,
55
- Se as getAuthTokenAsync,
56
- Te as getCachedCredentials,
57
- t as getConfigFromEnv,
58
- Be as getCurrentUserId,
59
- Pe as getCurrentUserIdAsync,
60
- ye as getUserSdkConfig,
61
- i as getVersionInfo,
62
- he as hasCredentials,
63
- Ve as hasNativeBridge,
64
- _e as initUserBridge,
65
- Oe as initUserSdk,
66
- J as isIOSDevice,
67
- De as isInIframe,
28
+ A as createError,
29
+ L as createHiddenMediaElement,
30
+ W as createHiddenVideoElement,
31
+ I as fileSystem,
32
+ g as geolocation,
33
+ i as getConfigFromEnv,
34
+ s as getVersionInfo,
35
+ y as hasNativeBridge,
36
+ j as isIOSDevice,
68
37
  z as isMediaStreamAudioSupported,
69
- _ as isMotionSupported,
70
- O as isOrientationSupported,
38
+ O as isMotionSupported,
39
+ b as isOrientationSupported,
71
40
  n as mergeConfig,
72
- ce as missingTokenError,
73
- Ee as networkError,
74
- le as normalizeError,
75
- Ae as parseError,
76
- K as patchAudioContext,
77
- B as performanceMonitor,
78
- v as platform,
79
- A as processMotionData,
80
- w as pwa,
81
- X as reportScore,
82
- xe as requestCredentialsFromParent,
83
- Re as requestCredentialsFromiOS,
84
- D as requestMotionPermission,
41
+ J as patchAudioContext,
42
+ k as performanceMonitor,
43
+ G as platform,
44
+ S as processMotionData,
45
+ H as pwa,
46
+ Y as reportScore,
47
+ v as requestMotionPermission,
85
48
  Z as sendEvent,
86
- x as sensors,
87
- ke as setAuthToken,
88
- Me as setCurrentUserId,
89
- be as tryGetCredentialsFromParentStorage,
49
+ D as sensors,
90
50
  $ as updateScore,
91
- W as useAudioContext,
92
- ve as useAuthToken,
93
- we as useCurrentUserId,
94
- Ge as useGetCurrentUserProfileQuery,
95
- He as useGetJoinedUserProfilesQuery,
96
- je as useGetUserProfileByIdQuery,
97
- qe as userSessionInfo,
98
- R as vibrate,
99
- k as watchMotion,
100
- M as watchOrientation
51
+ Q as useAudioContext,
52
+ h as vibrate,
53
+ w as watchMotion,
54
+ F as watchOrientation
101
55
  };
package/dist/index.d.ts CHANGED
@@ -4,5 +4,3 @@ export * from './utils';
4
4
  export * from './tweaks';
5
5
  export * from './audio';
6
6
  export * from './leaderboard';
7
- export * from './ai';
8
- export * from './user';
@@ -1,42 +1,46 @@
1
1
  function r(e, o) {
2
2
  try {
3
3
  if (window.parent && window.parent !== window) {
4
- const n = {
4
+ const a = {
5
5
  __aippyGame: !0,
6
6
  payload: e
7
7
  };
8
- window.parent.postMessage(n, "*");
8
+ window.parent.postMessage(a, "*");
9
9
  }
10
- const a = window.webkit?.messageHandlers?.aippyListener;
11
- a && a.postMessage({
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 (a) {
16
- console.warn("[Aippy Leaderboard] Failed to send game event:", a);
15
+ } catch (n) {
16
+ console.warn("[Aippy Leaderboard] Failed to send game event:", n);
17
17
  }
18
18
  }
19
19
  function t(e) {
20
- r({
20
+ const o = {
21
21
  type: "score",
22
- score: e
23
- }, "leaderboard.reportScore"), console.log(`[Aippy Leaderboard] Score reported: ${e}`);
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 p(e) {
26
- r({
27
+ function d(e) {
28
+ const o = {
27
29
  type: "score",
28
- score: e
29
- }, "leaderboard.updateScore"), console.log(`[Aippy Leaderboard] Score updated: ${e}`);
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 d(e, o) {
32
- const a = {
35
+ function i(e, o) {
36
+ const n = {
33
37
  type: e,
34
38
  ...o
35
39
  };
36
- r(a, "leaderboard.event"), console.log(`[Aippy Leaderboard] Event sent: ${e}`, o);
40
+ r(n, "leaderboard.event"), console.log(`[Aippy Leaderboard] Event sent: ${e}`, o);
37
41
  }
38
42
  export {
39
43
  t as reportScore,
40
- d as sendEvent,
41
- p as updateScore
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 */
@@ -1,6 +1,24 @@
1
1
  var u = Object.defineProperty;
2
- var m = (o, e, t) => e in o ? u(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
3
- var r = (o, e, t) => m(o, typeof e != "symbol" ? e + "" : e, t);
2
+ var m = (o, e, n) => e in o ? u(o, e, { enumerable: !0, configurable: !0, writable: !0, value: n }) : o[e] = n;
3
+ var r = (o, e, n) => m(o, typeof e != "symbol" ? e + "" : e, n);
4
+ class d extends Error {
5
+ constructor(n, i = "AIPPY_ERROR", t) {
6
+ super(n);
7
+ r(this, "code");
8
+ r(this, "context");
9
+ this.name = "AippyRuntimeError", this.code = i, this.context = t;
10
+ }
11
+ }
12
+ const R = {
13
+ NOT_SUPPORTED: "NOT_SUPPORTED",
14
+ PERMISSION_DENIED: "PERMISSION_DENIED",
15
+ INVALID_CONFIG: "INVALID_CONFIG",
16
+ NETWORK_ERROR: "NETWORK_ERROR",
17
+ UNKNOWN_ERROR: "UNKNOWN_ERROR"
18
+ };
19
+ function g(o, e = "UNKNOWN_ERROR", n) {
20
+ return new d(o, R[e], n);
21
+ }
4
22
  class a {
5
23
  constructor(e) {
6
24
  r(this, "cancelled", !1);
@@ -13,28 +31,28 @@ class a {
13
31
  return this.cancelled;
14
32
  }
15
33
  }
16
- class d {
34
+ class f {
17
35
  constructor() {
18
36
  r(this, "listeners", /* @__PURE__ */ new Map());
19
37
  }
20
- addEventListener(e, t) {
21
- this.listeners.has(e) || this.listeners.set(e, []), this.listeners.get(e).push(t);
38
+ addEventListener(e, n) {
39
+ this.listeners.has(e) || this.listeners.set(e, []), this.listeners.get(e).push(n);
22
40
  }
23
- removeEventListener(e, t) {
41
+ removeEventListener(e, n) {
24
42
  const i = this.listeners.get(e);
25
43
  if (i) {
26
- const n = i.indexOf(t);
27
- n > -1 && i.splice(n, 1);
44
+ const t = i.indexOf(n);
45
+ t > -1 && i.splice(t, 1);
28
46
  }
29
47
  }
30
- emit(e, t) {
48
+ emit(e, n) {
31
49
  const i = this.listeners.get(e);
32
- i && i.forEach((n) => n(t));
50
+ i && i.forEach((t) => t(n));
33
51
  }
34
52
  }
35
- class f {
53
+ class y {
36
54
  constructor() {
37
- r(this, "emitter", new d());
55
+ r(this, "emitter", new f());
38
56
  }
39
57
  /**
40
58
  * Emit a message to subscribers
@@ -45,9 +63,9 @@ class f {
45
63
  /**
46
64
  * Subscribe to messages on a specific endpoint
47
65
  */
48
- subscribe(e, t) {
49
- const i = (n) => {
50
- t(n);
66
+ subscribe(e, n) {
67
+ const i = (t) => {
68
+ n(t);
51
69
  };
52
70
  return this.emitter.addEventListener(e, i), new a(() => {
53
71
  this.emitter.removeEventListener(e, i);
@@ -56,16 +74,16 @@ class f {
56
74
  /**
57
75
  * Subscribe to a single message (auto-unsubscribe after first message)
58
76
  */
59
- once(e, t) {
60
- const i = this.subscribe(e, (n) => {
61
- i.cancel(), t(n);
77
+ once(e, n) {
78
+ const i = this.subscribe(e, (t) => {
79
+ i.cancel(), n(t);
62
80
  });
63
81
  return i;
64
82
  }
65
83
  }
66
- class y {
84
+ class h {
67
85
  constructor() {
68
- r(this, "receiveChannel", new f());
86
+ r(this, "receiveChannel", new y());
69
87
  r(this, "seq", 0);
70
88
  r(this, "motionListeners", []);
71
89
  r(this, "noListenersWarned", !1);
@@ -98,9 +116,9 @@ class y {
98
116
  isTweaksMessage(e) {
99
117
  if (typeof e != "object" || e === null || "endpoint" in e || "payload" in e)
100
118
  return !1;
101
- const t = Object.keys(e);
102
- return t.length === 0 ? !1 : t.some((n) => {
103
- const c = e[n];
119
+ const n = Object.keys(e);
120
+ return n.length === 0 ? !1 : n.some((t) => {
121
+ const c = e[t];
104
122
  return typeof c == "object" && c !== null && "value" in c;
105
123
  });
106
124
  }
@@ -111,18 +129,18 @@ class y {
111
129
  * @param callback - Callback to handle received data
112
130
  * @returns Cancellable subscription
113
131
  */
114
- createSubscription(e, t, i) {
115
- const n = (this.seq++).toString(), c = {
116
- command: t.command,
132
+ createSubscription(e, n, i) {
133
+ const t = (this.seq++).toString(), c = {
134
+ command: n.command,
117
135
  parameters: {
118
- type: t.type,
136
+ type: n.type,
119
137
  action: "subscribe",
120
- endpoint: n
138
+ endpoint: t
121
139
  }
122
140
  };
123
141
  console.log("๐Ÿ“จ [Aippy Runtime] Creating subscription with message:", JSON.stringify(c, null, 2));
124
- const p = this.receiveChannel.subscribe(n, (s) => {
125
- if (console.log(`๐Ÿ“ฌ [Aippy Runtime] Received data on endpoint ${n}:`, s), s.error !== void 0) {
142
+ const l = this.receiveChannel.subscribe(t, (s) => {
143
+ if (console.log(`๐Ÿ“ฌ [Aippy Runtime] Received data on endpoint ${t}:`, s), s.error !== void 0) {
126
144
  console.warn("โš ๏ธ [Aippy Runtime] Received error, skipping:", s.error);
127
145
  return;
128
146
  }
@@ -134,14 +152,14 @@ class y {
134
152
  console.error("โŒ [Aippy Runtime] Failed to send postMessage:", s);
135
153
  }
136
154
  return new a(() => {
137
- console.log(`๐Ÿ”Œ [Aippy Runtime] Unsubscribing from endpoint ${n}`), p.cancel();
155
+ console.log(`๐Ÿ”Œ [Aippy Runtime] Unsubscribing from endpoint ${t}`), l.cancel();
138
156
  try {
139
157
  const s = {
140
- command: t.command,
158
+ command: n.command,
141
159
  parameters: {
142
- type: t.type,
160
+ type: n.type,
143
161
  action: "unsubscribe",
144
- endpoint: n
162
+ endpoint: t
145
163
  }
146
164
  };
147
165
  e.postMessage(s), console.log("โœ… [Aippy Runtime] Unsubscribe message sent:", s);
@@ -157,27 +175,27 @@ class y {
157
175
  */
158
176
  addMotionListener(e) {
159
177
  console.log("๐ŸŽฌ [Aippy Runtime] addMotionListener called"), this.motionListeners.push(e), console.log(`๐Ÿ“ [Aippy Runtime] Total motion listeners: ${this.motionListeners.length}`);
160
- const t = window.webkit?.messageHandlers?.aippyListener;
161
- if (!t)
178
+ const n = window.webkit?.messageHandlers?.aippyListener;
179
+ if (!n)
162
180
  return console.warn("โš ๏ธ [Aippy Runtime] No webkit message handler found, using fallback mode"), () => {
163
- const n = this.motionListeners.indexOf(e);
164
- n > -1 && this.motionListeners.splice(n, 1);
181
+ const t = this.motionListeners.indexOf(e);
182
+ t > -1 && this.motionListeners.splice(t, 1);
165
183
  };
166
184
  console.log("โœ… [Aippy Runtime] Webkit handler found, creating subscription");
167
185
  const i = this.createSubscription(
168
- t,
186
+ n,
169
187
  {
170
188
  command: "navigator.motion",
171
189
  type: "motion"
172
190
  },
173
- (n) => {
174
- console.log("๐Ÿ“ฅ [Aippy Runtime] Received motion data from native:", n), n.motion && e(n.motion);
191
+ (t) => {
192
+ console.log("๐Ÿ“ฅ [Aippy Runtime] Received motion data from native:", t), t.motion && e(t.motion);
175
193
  }
176
194
  );
177
195
  return () => {
178
196
  console.log("๐Ÿงน [Aippy Runtime] Cleaning up motion listener"), i.cancel();
179
- const n = this.motionListeners.indexOf(e);
180
- n > -1 && this.motionListeners.splice(n, 1);
197
+ const t = this.motionListeners.indexOf(e);
198
+ t > -1 && this.motionListeners.splice(t, 1);
181
199
  };
182
200
  }
183
201
  /**
@@ -190,17 +208,17 @@ class y {
190
208
  this.noListenersWarned || (console.warn("โš ๏ธ [Aippy Runtime] No motion listeners to broadcast to"), this.noListenersWarned = !0);
191
209
  return;
192
210
  }
193
- const t = e.motion || e;
211
+ const n = e.motion || e;
194
212
  this.motionListeners.forEach((i) => {
195
213
  try {
196
- i(t);
197
- } catch (n) {
198
- console.error("โš ๏ธ [Aippy Runtime] Error in motion listener:", n);
214
+ i(n);
215
+ } catch (t) {
216
+ console.error("โš ๏ธ [Aippy Runtime] Error in motion listener:", t);
199
217
  }
200
218
  });
201
219
  }
202
220
  }
203
- function h(o) {
221
+ function w(o) {
204
222
  if (!o || typeof o != "object") {
205
223
  console.warn("โš ๏ธ [Aippy Runtime] Invalid motion data type:", typeof o);
206
224
  return;
@@ -209,14 +227,17 @@ function h(o) {
209
227
  console.warn("โš ๏ธ [Aippy Runtime] Motion data missing valid motion field");
210
228
  return;
211
229
  }
212
- l.broadcastMotionData(o);
230
+ p.broadcastMotionData(o);
213
231
  }
214
- const l = new y();
215
- typeof window < "u" && (window.aippyRuntime = l, window.processMotionData = h);
232
+ const p = new h();
233
+ typeof window < "u" && (window.aippyRuntime = p, window.processMotionData = w);
216
234
  export {
217
- y as A,
235
+ d as A,
218
236
  a as C,
219
- f as R,
220
- l as a,
221
- h as p
237
+ R as E,
238
+ y as R,
239
+ h as a,
240
+ p as b,
241
+ g as c,
242
+ w as p
222
243
  };