@proveanything/smartlinks-auth-ui 0.3.0 → 0.3.1

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.
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+ import type { SmartlinksFrameProps } from '../../types/iframeMessages';
3
+ /**
4
+ * SmartlinksFrame - Parent-side iframe wrapper for embedding SmartLinks microapps.
5
+ *
6
+ * This component handles all bidirectional communication with the embedded iframe:
7
+ * - API proxy requests (with optional caching)
8
+ * - Authentication state synchronization (when inside AuthProvider)
9
+ * - Deep linking / route changes
10
+ * - Resize management
11
+ * - File upload proxying
12
+ *
13
+ * Can be used with or without AuthProvider - authentication is optional.
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * // With authentication
18
+ * <AuthProvider collectionId="my-collection">
19
+ * <SmartlinksFrame
20
+ * collectionId="my-collection"
21
+ * appId="warranty-app"
22
+ * appUrl="https://warranty.lovable.app"
23
+ * collection={collectionData}
24
+ * />
25
+ * </AuthProvider>
26
+ *
27
+ * // Without authentication (public/anonymous access)
28
+ * <SmartlinksFrame
29
+ * collectionId="my-collection"
30
+ * appId="info-app"
31
+ * appUrl="https://info-app.lovable.app"
32
+ * />
33
+ * ```
34
+ */
35
+ export declare const SmartlinksFrame: React.FC<SmartlinksFrameProps>;
36
+ //# sourceMappingURL=SmartlinksFrame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SmartlinksFrame.d.ts","sourceRoot":"","sources":["../../../src/components/SmartlinksFrame/SmartlinksFrame.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAI3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAKvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAsJ1D,CAAC"}
@@ -0,0 +1,7 @@
1
+ export { SmartlinksFrame } from './SmartlinksFrame';
2
+ export { useAdminDetection } from './useAdminDetection';
3
+ export { useIframeResize } from './useIframeResize';
4
+ export { useIframeMessages } from './useIframeMessages';
5
+ export type { SmartlinksFrameProps } from '../../types/iframeMessages';
6
+ export type { IframeResizeOptions } from './useIframeResize';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/SmartlinksFrame/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { AuthUser } from '../../types';
2
+ /**
3
+ * Hook to detect if the current user is an admin of the collection or proof.
4
+ *
5
+ * Admin status is determined by checking if the user's UID exists in the
6
+ * `roles` object of either the collection or proof.
7
+ *
8
+ * @param collection - Collection object with optional roles
9
+ * @param proof - Proof object with optional roles
10
+ * @param user - Current authenticated user
11
+ * @returns boolean indicating admin status
12
+ */
13
+ export declare function useAdminDetection(collection?: Record<string, any>, proof?: Record<string, any>, user?: AuthUser | null): boolean;
14
+ //# sourceMappingURL=useAdminDetection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAdminDetection.d.ts","sourceRoot":"","sources":["../../../src/components/SmartlinksFrame/useAdminDetection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAChC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,GACrB,OAAO,CAgBT"}
@@ -0,0 +1,27 @@
1
+ import type { AuthUser } from '../../types';
2
+ import type { CachedData } from '../../types/iframeMessages';
3
+ export interface IframeMessageOptions {
4
+ collectionId: string;
5
+ productId?: string;
6
+ proofId?: string;
7
+ cachedData: CachedData;
8
+ login?: (token: string, user: AuthUser, accountData?: Record<string, any>, isNewUser?: boolean, expiresAt?: number) => Promise<void>;
9
+ logout?: () => Promise<void>;
10
+ onRouteChange?: (path: string, state: Record<string, string>) => void;
11
+ onError?: (error: Error) => void;
12
+ }
13
+ /**
14
+ * Hook to handle all iframe postMessage communication.
15
+ *
16
+ * Handles:
17
+ * - Route changes (deep linking)
18
+ * - API proxy requests
19
+ * - Auth messages (login/logout)
20
+ * - File uploads (chunked)
21
+ * - Redirects
22
+ *
23
+ * @param iframeRef - Ref to the iframe element
24
+ * @param options - Configuration and callbacks
25
+ */
26
+ export declare function useIframeMessages(iframeRef: React.RefObject<HTMLIFrameElement>, options: IframeMessageOptions): void;
27
+ //# sourceMappingURL=useIframeMessages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useIframeMessages.d.ts","sourceRoot":"","sources":["../../../src/components/SmartlinksFrame/useIframeMessages.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAQV,UAAU,EACX,MAAM,4BAA4B,CAAC;AAepC,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IAEvB,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrI,MAAM,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IACtE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AASD;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,iBAAiB,CAAC,EAC7C,OAAO,EAAE,oBAAoB,GAC5B,IAAI,CAiaN"}
@@ -0,0 +1,18 @@
1
+ export interface IframeResizeOptions {
2
+ autoResize?: boolean;
3
+ minHeight?: number;
4
+ maxHeight?: number;
5
+ }
6
+ /**
7
+ * Hook to handle iframe height management.
8
+ *
9
+ * Supports two modes:
10
+ * 1. Viewport-based: Calculates height based on iframe position and viewport
11
+ * 2. Content-based: Listens for smartlinks:resize messages from the iframe
12
+ *
13
+ * @param iframeRef - Ref to the iframe element
14
+ * @param options - Resize configuration options
15
+ * @returns Current calculated height in pixels
16
+ */
17
+ export declare function useIframeResize(iframeRef: React.RefObject<HTMLIFrameElement>, options?: IframeResizeOptions): number;
18
+ //# sourceMappingURL=useIframeResize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useIframeResize.d.ts","sourceRoot":"","sources":["../../../src/components/SmartlinksFrame/useIframeResize.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,iBAAiB,CAAC,EAC7C,OAAO,GAAE,mBAAwB,GAChC,MAAM,CAqFR"}
@@ -30,7 +30,8 @@ interface AuthContextValue {
30
30
  onAuthStateChange: (callback: AuthStateChangeCallback) => () => void;
31
31
  retryVerification: () => Promise<boolean>;
32
32
  }
33
+ export declare const AuthContext: React.Context<AuthContextValue | undefined>;
34
+ export type { AuthContextValue };
33
35
  export declare const AuthProvider: React.FC<AuthProviderProps>;
34
36
  export declare const useAuth: () => AuthContextValue;
35
- export {};
36
37
  //# sourceMappingURL=AuthContext.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AuthContext.d.ts","sourceRoot":"","sources":["../../src/context/AuthContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8E,MAAM,OAAO,CAAC;AAGnG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAGjE,OAAO,KAAK,EAAE,QAAQ,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAErF,UAAU,gBAAgB;IACxB,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IACxC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IACxC,eAAe,EAAE,OAAO,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IAGnB,OAAO,EAAE,eAAe,GAAG,IAAI,CAAC;IAChC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,CAAC,YAAY,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IACxE,yBAAyB,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IAG3F,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpI,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,QAAQ,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACvC,YAAY,EAAE,MAAM,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC5F,YAAY,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,UAAU,EAAE,CAAC,YAAY,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IACrE,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IACnD,iBAAiB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,iBAAiB,EAAE,CAAC,QAAQ,EAAE,uBAAuB,KAAK,MAAM,IAAI,CAAC;IACrE,iBAAiB,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3C;AAID,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAi7BpD,CAAC;AAEF,eAAO,MAAM,OAAO,QAAO,gBAM1B,CAAC"}
1
+ {"version":3,"file":"AuthContext.d.ts","sourceRoot":"","sources":["../../src/context/AuthContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8E,MAAM,OAAO,CAAC;AAGnG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAGjE,OAAO,KAAK,EAAE,QAAQ,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAErF,UAAU,gBAAgB;IACxB,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IACxC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IACxC,eAAe,EAAE,OAAO,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IAGnB,OAAO,EAAE,eAAe,GAAG,IAAI,CAAC;IAChC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,CAAC,YAAY,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IACxE,yBAAyB,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IAG3F,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpI,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,QAAQ,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACvC,YAAY,EAAE,MAAM,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC5F,YAAY,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,UAAU,EAAE,CAAC,YAAY,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IACrE,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IACnD,iBAAiB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,iBAAiB,EAAE,CAAC,QAAQ,EAAE,uBAAuB,KAAK,MAAM,IAAI,CAAC;IACrE,iBAAiB,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3C;AAGD,eAAO,MAAM,WAAW,6CAAyD,CAAC;AAGlF,YAAY,EAAE,gBAAgB,EAAE,CAAC;AAEjC,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAi7BpD,CAAC;AAEF,eAAO,MAAM,OAAO,QAAO,gBAM1B,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export { SmartlinksAuthUI } from './components/SmartlinksAuthUI';
2
2
  export { AccountManagement } from './components/AccountManagement';
3
+ export { SmartlinksFrame, useAdminDetection, useIframeResize, useIframeMessages, } from './components/SmartlinksFrame';
4
+ export type { SmartlinksFrameProps, IframeResizeOptions, } from './components/SmartlinksFrame';
3
5
  export { AuthProvider, useAuth } from './context/AuthContext';
4
6
  export { ProtectedRoute } from './components/ProtectedRoute';
5
7
  export { tokenStorage } from './utils/tokenStorage';
@@ -8,6 +10,7 @@ export { getDefaultAuthKitId, setDefaultAuthKitId } from './utils/defaultAuthKit
8
10
  export { getFriendlyErrorMessage, isConflictError, isAuthError, isRateLimitError, isServerError, getErrorStatusCode, getErrorCode } from './utils/errorHandling';
9
11
  export { SchemaFieldRenderer, getEditableFields, getRegistrationFields, sortFieldsByPlacement } from './components/SchemaFieldRenderer';
10
12
  export type { SchemaField, ContactSchema, RegistrationFieldConfig } from './components/SchemaFieldRenderer';
13
+ export type { RouteChangeMessage, SmartlinksIframeMessage, ProxyRequest, ProxyResponse, CachedData, } from './types/iframeMessages';
11
14
  export type * from './types';
12
15
  export type { AuthLogger, SignupProminence, RedirectReason } from './types';
13
16
  export { SmartlinksAuthUI as FirebaseAuthUI } from './components/SmartlinksAuthUI';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAGnE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGpD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAG3D,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAGlF,OAAO,EACL,uBAAuB,EACvB,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,YAAY,EACb,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACxI,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAG5G,mBAAmB,SAAS,CAAC;AAC7B,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG5E,OAAO,EAAE,gBAAgB,IAAI,cAAc,EAAE,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAGnE,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,iBAAiB,GAClB,MAAM,8BAA8B,CAAC;AACtC,YAAY,EACV,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGpD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAG3D,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAGlF,OAAO,EACL,uBAAuB,EACvB,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,YAAY,EACb,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACxI,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAG5G,YAAY,EACV,kBAAkB,EAClB,uBAAuB,EACvB,YAAY,EACZ,aAAa,EACb,UAAU,GACX,MAAM,wBAAwB,CAAC;AAGhC,mBAAmB,SAAS,CAAC;AAC7B,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG5E,OAAO,EAAE,gBAAgB,IAAI,cAAc,EAAE,MAAM,+BAA+B,CAAC"}