pi-kiosk-shared 2.1.79 → 2.1.82

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/index.d.ts CHANGED
@@ -47,6 +47,7 @@ export * from './checkout/sessionMetadataV3.js';
47
47
  export * from './checkout/sessionMetadataV4.js';
48
48
  export * from './catalogImagePresentation.js';
49
49
  export * from './CatalogImagePlaceholder.js';
50
+ export * from './tenant/tenantPathResolution.js';
50
51
  export { PERMISSION_DOMAIN_LABELS, PERMISSION_LEVEL_LABELS, getPermissionDomainLabel, getPermissionLevelLabel, } from './permissions/permissionLabels.js';
51
52
  export { expandCapabilitiesForClientCheck, grantImpliesTarget, hasEffectiveCapability, hasAnyEffectiveCapability, ADMIN_USERS_MANAGE_BRIDGE_SOURCES, ADMIN_USERS_MANAGE_BRIDGE_TARGETS, BRIDGE_PARITY_FIXTURE_GRANTS, BRIDGE_PARITY_FIXTURE_EXPECTED_TARGETS, } from './permissions/effectiveCapabilities.js';
52
53
  export type { PermissionLevel } from './permissions/permissionLabels.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,cAAc,YAAY,CAAC;AAC3B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yCAAyC,CAAC;AACxD,OAAO,EACL,wCAAwC,EACxC,yCAAyC,GAC1C,MAAM,yCAAyC,CAAC;AACjD,cAAc,oBAAoB,CAAC;AACnC,cAAc,oCAAoC,CAAC;AACnD,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,qCAAqC,CAAC;AACpD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,iCAAiC,CAAC;AAChD,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iCAAiC,CAAC;AAChD,cAAc,mCAAmC,CAAC;AAClD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uCAAuC,CAAC;AACtD,cAAc,wBAAwB,CAAC;AACvC,cAAc,iCAAiC,CAAC;AAChD,cAAc,iCAAiC,CAAC;AAChD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8BAA8B,CAAC;AAC7C,OAAO,EACL,wBAAwB,EACxB,uBAAuB,EACvB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,gCAAgC,EAChC,kBAAkB,EAClB,sBAAsB,EACtB,yBAAyB,EACzB,iCAAiC,EACjC,iCAAiC,EACjC,4BAA4B,EAC5B,sCAAsC,GACvC,MAAM,wCAAwC,CAAC;AAChD,YAAY,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,cAAc,YAAY,CAAC;AAC3B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yCAAyC,CAAC;AACxD,OAAO,EACL,wCAAwC,EACxC,yCAAyC,GAC1C,MAAM,yCAAyC,CAAC;AACjD,cAAc,oBAAoB,CAAC;AACnC,cAAc,oCAAoC,CAAC;AACnD,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,qCAAqC,CAAC;AACpD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,iCAAiC,CAAC;AAChD,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iCAAiC,CAAC;AAChD,cAAc,mCAAmC,CAAC;AAClD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uCAAuC,CAAC;AACtD,cAAc,wBAAwB,CAAC;AACvC,cAAc,iCAAiC,CAAC;AAChD,cAAc,iCAAiC,CAAC;AAChD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kCAAkC,CAAC;AACjD,OAAO,EACL,wBAAwB,EACxB,uBAAuB,EACvB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,gCAAgC,EAChC,kBAAkB,EAClB,sBAAsB,EACtB,yBAAyB,EACzB,iCAAiC,EACjC,iCAAiC,EACjC,4BAA4B,EAC5B,sCAAsC,GACvC,MAAM,wCAAwC,CAAC;AAChD,YAAY,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC"}
package/dist/index.js CHANGED
@@ -47,6 +47,7 @@ export * from './checkout/sessionMetadataV3.js';
47
47
  export * from './checkout/sessionMetadataV4.js';
48
48
  export * from './catalogImagePresentation.js';
49
49
  export * from './CatalogImagePlaceholder.js';
50
+ export * from './tenant/tenantPathResolution.js';
50
51
  export { PERMISSION_DOMAIN_LABELS, PERMISSION_LEVEL_LABELS, getPermissionDomainLabel, getPermissionLevelLabel, } from './permissions/permissionLabels.js';
51
52
  export { expandCapabilitiesForClientCheck, grantImpliesTarget, hasEffectiveCapability, hasAnyEffectiveCapability, ADMIN_USERS_MANAGE_BRIDGE_SOURCES, ADMIN_USERS_MANAGE_BRIDGE_TARGETS, BRIDGE_PARITY_FIXTURE_GRANTS, BRIDGE_PARITY_FIXTURE_EXPECTED_TARGETS, } from './permissions/effectiveCapabilities.js';
52
53
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,cAAc,YAAY,CAAC;AAC3B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yCAAyC,CAAC;AACxD,OAAO,EACL,wCAAwC,EACxC,yCAAyC,GAC1C,MAAM,yCAAyC,CAAC;AACjD,cAAc,oBAAoB,CAAC;AACnC,cAAc,oCAAoC,CAAC;AACnD,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,qCAAqC,CAAC;AACpD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,iCAAiC,CAAC;AAChD,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iCAAiC,CAAC;AAChD,cAAc,mCAAmC,CAAC;AAClD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uCAAuC,CAAC;AACtD,cAAc,wBAAwB,CAAC;AACvC,cAAc,iCAAiC,CAAC;AAChD,cAAc,iCAAiC,CAAC;AAChD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8BAA8B,CAAC;AAC7C,OAAO,EACL,wBAAwB,EACxB,uBAAuB,EACvB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,gCAAgC,EAChC,kBAAkB,EAClB,sBAAsB,EACtB,yBAAyB,EACzB,iCAAiC,EACjC,iCAAiC,EACjC,4BAA4B,EAC5B,sCAAsC,GACvC,MAAM,wCAAwC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,cAAc,YAAY,CAAC;AAC3B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yCAAyC,CAAC;AACxD,OAAO,EACL,wCAAwC,EACxC,yCAAyC,GAC1C,MAAM,yCAAyC,CAAC;AACjD,cAAc,oBAAoB,CAAC;AACnC,cAAc,oCAAoC,CAAC;AACnD,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,qCAAqC,CAAC;AACpD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,iCAAiC,CAAC;AAChD,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iCAAiC,CAAC;AAChD,cAAc,mCAAmC,CAAC;AAClD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uCAAuC,CAAC;AACtD,cAAc,wBAAwB,CAAC;AACvC,cAAc,iCAAiC,CAAC;AAChD,cAAc,iCAAiC,CAAC;AAChD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kCAAkC,CAAC;AACjD,OAAO,EACL,wBAAwB,EACxB,uBAAuB,EACvB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,gCAAgC,EAChC,kBAAkB,EAClB,sBAAsB,EACtB,yBAAyB,EACzB,iCAAiC,EACjC,iCAAiC,EACjC,4BAA4B,EAC5B,sCAAsC,GACvC,MAAM,wCAAwC,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * URL-first tenant code resolution for admin, kiosk, and customer PWAs.
3
+ *
4
+ * Tenant code is always the first path segment: `/{tenantCode}/...`
5
+ * Never fall back to `default`, `test`, or the authenticated user's home tenant.
6
+ */
7
+ /** First-segment path prefixes that are routes, not tenant codes. */
8
+ export declare const NON_TENANT_PATH_SEGMENTS: Set<string>;
9
+ export declare class TenantPathResolutionError extends Error {
10
+ constructor(message: string);
11
+ }
12
+ export declare function getTenantCodeFromPath(pathname: string): string | null;
13
+ export declare function resolveBrowserPathname(pathname?: string): string;
14
+ export declare function requireTenantCodeFromPath(pathname?: string): string;
15
+ /** React Router `:tenant` param — throws instead of falling back to default/test. */
16
+ export declare function coerceRouteTenantCode(tenantCode: string | undefined): string;
17
+ export declare function isDevDashboardApiEndpoint(endpoint: string): boolean;
18
+ export declare function withTenantInApiPath(endpoint: string, tenantCode: string): string;
19
+ //# sourceMappingURL=tenantPathResolution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenantPathResolution.d.ts","sourceRoot":"","sources":["../../src/tenant/tenantPathResolution.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,qEAAqE;AACrE,eAAO,MAAM,wBAAwB,aAAmC,CAAC;AAEzE,qBAAa,yBAA0B,SAAQ,KAAK;gBACtC,OAAO,EAAE,MAAM;CAI5B;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAarE;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAQhE;AAED,wBAAgB,yBAAyB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CASnE;AAED,qFAAqF;AACrF,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAM5E;AAED,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAShF"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * URL-first tenant code resolution for admin, kiosk, and customer PWAs.
3
+ *
4
+ * Tenant code is always the first path segment: `/{tenantCode}/...`
5
+ * Never fall back to `default`, `test`, or the authenticated user's home tenant.
6
+ */
7
+ /** First-segment path prefixes that are routes, not tenant codes. */
8
+ export const NON_TENANT_PATH_SEGMENTS = new Set(['admin', 'dev', 'api']);
9
+ export class TenantPathResolutionError extends Error {
10
+ constructor(message) {
11
+ super(message);
12
+ this.name = 'TenantPathResolutionError';
13
+ }
14
+ }
15
+ export function getTenantCodeFromPath(pathname) {
16
+ const segments = pathname.split('/').filter((segment) => segment.length > 0);
17
+ if (segments.length === 0) {
18
+ return null;
19
+ }
20
+ const first = segments[0];
21
+ if (!first) {
22
+ return null;
23
+ }
24
+ if (NON_TENANT_PATH_SEGMENTS.has(first.toLowerCase())) {
25
+ return null;
26
+ }
27
+ return first;
28
+ }
29
+ export function resolveBrowserPathname(pathname) {
30
+ if (pathname !== undefined) {
31
+ return pathname;
32
+ }
33
+ if (typeof window !== 'undefined' && typeof window.location?.pathname === 'string') {
34
+ return window.location.pathname;
35
+ }
36
+ return '/';
37
+ }
38
+ export function requireTenantCodeFromPath(pathname) {
39
+ const path = resolveBrowserPathname(pathname);
40
+ const code = getTenantCodeFromPath(path);
41
+ if (!code) {
42
+ throw new TenantPathResolutionError(`Tenant code missing from URL path "${path}". Use /{tenantCode}/... (e.g. /railway-cafe/admin or /railway-cafe/1).`);
43
+ }
44
+ return code;
45
+ }
46
+ /** React Router `:tenant` param — throws instead of falling back to default/test. */
47
+ export function coerceRouteTenantCode(tenantCode) {
48
+ const trimmed = tenantCode?.trim();
49
+ if (!trimmed) {
50
+ throw new TenantPathResolutionError('Missing :tenant route parameter');
51
+ }
52
+ return trimmed;
53
+ }
54
+ export function isDevDashboardApiEndpoint(endpoint) {
55
+ return endpoint.startsWith('/api/dev/') || endpoint.startsWith('/api/v1/dev/');
56
+ }
57
+ export function withTenantInApiPath(endpoint, tenantCode) {
58
+ const trimmed = tenantCode.trim();
59
+ if (!trimmed) {
60
+ throw new TenantPathResolutionError('Tenant code is required for API path');
61
+ }
62
+ if (!endpoint.startsWith('/api/')) {
63
+ return endpoint;
64
+ }
65
+ return `/api/${encodeURIComponent(trimmed)}${endpoint.slice(4)}`;
66
+ }
67
+ //# sourceMappingURL=tenantPathResolution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenantPathResolution.js","sourceRoot":"","sources":["../../src/tenant/tenantPathResolution.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,qEAAqE;AACrE,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAEzE,MAAM,OAAO,yBAA0B,SAAQ,KAAK;IAClD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;IAC1C,CAAC;CACF;AAED,MAAM,UAAU,qBAAqB,CAAC,QAAgB;IACpD,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC7E,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,wBAAwB,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;QACtD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,QAAiB;IACtD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,MAAM,CAAC,QAAQ,EAAE,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACnF,OAAO,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAClC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,QAAiB;IACzD,MAAM,IAAI,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;IACzC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,yBAAyB,CACjC,sCAAsC,IAAI,yEAAyE,CACpH,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,qBAAqB,CAAC,UAA8B;IAClE,MAAM,OAAO,GAAG,UAAU,EAAE,IAAI,EAAE,CAAC;IACnC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,yBAAyB,CAAC,iCAAiC,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,QAAgB;IACxD,OAAO,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,QAAgB,EAAE,UAAkB;IACtE,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC;IAClC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,yBAAyB,CAAC,sCAAsC,CAAC,CAAC;IAC9E,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAClC,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO,QAAQ,kBAAkB,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AACnE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-kiosk-shared",
3
- "version": "2.1.79",
3
+ "version": "2.1.82",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "description": "Shared types, API contracts, and error classes for Pi Kiosk system",