entropic-bond 1.50.0 → 1.50.2
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/lib/auth/auth-mock.d.ts +22 -0
- package/lib/auth/auth-mock.spec.d.ts +1 -0
- package/lib/auth/auth.d.ts +131 -0
- package/lib/auth/user-auth-types.d.ts +19 -0
- package/lib/cloud-functions/cloud-functions-mock.d.ts +11 -0
- package/lib/cloud-functions/cloud-functions-mock.spec.d.ts +1 -0
- package/lib/cloud-functions/cloud-functions.d.ts +19 -0
- package/lib/cloud-storage/cloud-storage.d.ts +24 -0
- package/lib/cloud-storage/cloud-storage.spec.d.ts +1 -0
- package/lib/cloud-storage/mock-cloud-storage.d.ts +20 -0
- package/lib/cloud-storage/stored-file.d.ts +39 -0
- package/lib/entropic-bond.js +1667 -0
- package/lib/entropic-bond.umd.cjs +7 -0
- package/lib/index.d.ts +19 -0
- package/lib/observable/observable.d.ts +52 -0
- package/lib/observable/observable.spec.d.ts +1 -0
- package/lib/persistent/entropic-component.d.ts +76 -0
- package/lib/persistent/entropic-component.spec.d.ts +1 -0
- package/lib/persistent/persistent.d.ts +281 -0
- package/lib/persistent/persistent.spec.d.ts +67 -0
- package/lib/server-auth/server-auth-mock.d.ts +12 -0
- package/lib/server-auth/server-auth-mock.spec.d.ts +1 -0
- package/lib/server-auth/server-auth.d.ts +24 -0
- package/lib/store/data-source.d.ts +137 -0
- package/lib/store/json-data-source.d.ts +68 -0
- package/lib/store/json-data-source.spec.d.ts +1 -0
- package/lib/store/mocks/test-user.d.ts +49 -0
- package/lib/store/model.d.ts +238 -0
- package/lib/store/model.spec.d.ts +1 -0
- package/lib/store/store.d.ts +62 -0
- package/lib/store/store.spec.d.ts +1 -0
- package/lib/types/utility-types.d.ts +45 -0
- package/lib/types/utility-types.spec.d.ts +1 -0
- package/lib/utils/test-utils/test-person.d.ts +33 -0
- package/{src/utils/utils.ts → lib/utils/utils.d.ts} +10 -34
- package/lib/utils/utils.spec.d.ts +1 -0
- package/package.json +7 -4
- package/.github/workflows/release.yml +0 -26
- package/CHANGELOG.md +0 -1151
- package/docs/.nojekyll +0 -1
- package/docs/README.md +0 -94
- package/docs/classes/Auth.md +0 -391
- package/docs/classes/AuthMock.md +0 -278
- package/docs/classes/AuthService.md +0 -188
- package/docs/classes/CloudFunctions.md +0 -123
- package/docs/classes/CloudFunctionsMock.md +0 -97
- package/docs/classes/CloudStorage.md +0 -215
- package/docs/classes/DataSource.md +0 -248
- package/docs/classes/EntropicComponent.md +0 -666
- package/docs/classes/JsonDataSource.md +0 -328
- package/docs/classes/MockCloudStorage.md +0 -279
- package/docs/classes/Model.md +0 -274
- package/docs/classes/Observable.md +0 -120
- package/docs/classes/Persistent.md +0 -420
- package/docs/classes/ServerAuth.md +0 -211
- package/docs/classes/ServerAuthMock.md +0 -176
- package/docs/classes/ServerAuthService.md +0 -130
- package/docs/classes/Store.md +0 -218
- package/docs/classes/StoredFile.md +0 -636
- package/docs/enums/StoredFileEvent.md +0 -41
- package/docs/interfaces/AuthError.md +0 -30
- package/docs/interfaces/CloudFunctionsService.md +0 -69
- package/docs/interfaces/Collection.md +0 -13
- package/docs/interfaces/CustomCredentials.md +0 -7
- package/docs/interfaces/DocumentReference.md +0 -49
- package/docs/interfaces/JsonRawData.md +0 -7
- package/docs/interfaces/SignData.md +0 -63
- package/docs/interfaces/StoreParams.md +0 -52
- package/docs/interfaces/StoredFileChange.md +0 -41
- package/docs/interfaces/UploadControl.md +0 -90
- package/docs/interfaces/UserCredentials.md +0 -113
- package/docs/interfaces/Values.md +0 -17
- package/docs/modules.md +0 -1273
- package/src/auth/auth-mock.spec.ts +0 -168
- package/src/auth/auth-mock.ts +0 -129
- package/src/auth/auth.ts +0 -185
- package/src/auth/user-auth-types.ts +0 -21
- package/src/cloud-functions/cloud-functions-mock.spec.ts +0 -136
- package/src/cloud-functions/cloud-functions-mock.ts +0 -23
- package/src/cloud-functions/cloud-functions.ts +0 -83
- package/src/cloud-storage/cloud-storage.spec.ts +0 -207
- package/src/cloud-storage/cloud-storage.ts +0 -60
- package/src/cloud-storage/mock-cloud-storage.ts +0 -72
- package/src/cloud-storage/stored-file.ts +0 -102
- package/src/index.ts +0 -19
- package/src/observable/observable.spec.ts +0 -105
- package/src/observable/observable.ts +0 -67
- package/src/persistent/entropic-component.spec.ts +0 -143
- package/src/persistent/entropic-component.ts +0 -135
- package/src/persistent/persistent.spec.ts +0 -828
- package/src/persistent/persistent.ts +0 -650
- package/src/server-auth/server-auth-mock.spec.ts +0 -53
- package/src/server-auth/server-auth-mock.ts +0 -45
- package/src/server-auth/server-auth.ts +0 -49
- package/src/store/data-source.ts +0 -186
- package/src/store/json-data-source.spec.ts +0 -100
- package/src/store/json-data-source.ts +0 -256
- package/src/store/mocks/mock-data.json +0 -155
- package/src/store/mocks/test-user.ts +0 -122
- package/src/store/model.spec.ts +0 -659
- package/src/store/model.ts +0 -462
- package/src/store/store.spec.ts +0 -30
- package/src/store/store.ts +0 -113
- package/src/types/utility-types.spec.ts +0 -117
- package/src/types/utility-types.ts +0 -116
- package/src/utils/test-utils/test-person.ts +0 -44
- package/src/utils/utils.spec.ts +0 -95
- package/tsconfig-build.json +0 -7
- package/tsconfig-cjs.json +0 -9
- package/tsconfig.json +0 -33
- package/vite.config.ts +0 -22
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Collection } from '../types/utility-types';
|
|
2
|
+
import { AuthService } from "./auth";
|
|
3
|
+
import { UserCredentials, SignData, AuthProvider } from "./user-auth-types";
|
|
4
|
+
export declare class AuthMock extends AuthService {
|
|
5
|
+
signUp<T extends {}>(signData: SignData): Promise<UserCredentials<T>>;
|
|
6
|
+
login<T extends {}>(signData: SignData): Promise<UserCredentials<T>>;
|
|
7
|
+
onAuthStateChange<T extends {}>(onChange: (userCredentials: UserCredentials<T>) => void): void;
|
|
8
|
+
logout(): Promise<void>;
|
|
9
|
+
resetEmailPassword(email: string): Promise<void>;
|
|
10
|
+
resendVerificationEmail(email: string, _password: string, _verificationLink: string): Promise<void>;
|
|
11
|
+
refreshToken(): Promise<void>;
|
|
12
|
+
linkAdditionalProvider(provider: AuthProvider): Promise<unknown>;
|
|
13
|
+
unlinkProvider(provider: AuthProvider): Promise<unknown>;
|
|
14
|
+
flush(): Promise<void>;
|
|
15
|
+
fakeRegisteredUser<T extends {}>(userCredentials: UserCredentials<T>): this;
|
|
16
|
+
get fakeRegisteredUsers(): Collection<UserCredentials<{}>>;
|
|
17
|
+
private userCredentials;
|
|
18
|
+
private pendingPromises;
|
|
19
|
+
private _loggedUser;
|
|
20
|
+
private notifyChange;
|
|
21
|
+
private _fakeRegisteredUsers;
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { AuthProvider, SignData, UserCredentials } from "./user-auth-types";
|
|
2
|
+
/**
|
|
3
|
+
* The AuthService class is an abstract class that defines the interface of an authentication service.
|
|
4
|
+
* You should derive from this class to implement your own authentication service.
|
|
5
|
+
*/
|
|
6
|
+
export declare abstract class AuthService {
|
|
7
|
+
abstract signUp<T extends {}>(signData: SignData): Promise<UserCredentials<T>>;
|
|
8
|
+
abstract login<T extends {}>(signData: SignData): Promise<UserCredentials<T>>;
|
|
9
|
+
abstract logout(): Promise<void>;
|
|
10
|
+
abstract resetEmailPassword(email: string): Promise<void>;
|
|
11
|
+
abstract refreshToken(): Promise<void>;
|
|
12
|
+
abstract linkAdditionalProvider(provider: AuthProvider): Promise<unknown>;
|
|
13
|
+
abstract unlinkProvider(provider: AuthProvider): Promise<unknown>;
|
|
14
|
+
abstract onAuthStateChange<T extends {}>(onChange: (userCredentials: UserCredentials<T> | undefined) => void): void;
|
|
15
|
+
abstract resendVerificationEmail(email: string, password: string, verificationLink: string): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
export type AuthErrorCode = 'wrongPassword' | 'popupClosedByUser' | 'userNotFound' | 'invalidEmail' | 'missingPassword' | 'missingEmail';
|
|
18
|
+
export interface AuthError {
|
|
19
|
+
code: AuthErrorCode;
|
|
20
|
+
message: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Types the callback to accept a user credentials object
|
|
24
|
+
*/
|
|
25
|
+
export type ResovedCallback<T extends {}> = (credentials: UserCredentials<T>) => void;
|
|
26
|
+
export type RejectedCallback = (reason: AuthError) => void;
|
|
27
|
+
/**
|
|
28
|
+
* The Auth class is a singleton that provides a unified interface to the authentication service.
|
|
29
|
+
* You should register an authentication service by using `Auth.useAuthService`
|
|
30
|
+
* method before using the Auth class.
|
|
31
|
+
*/
|
|
32
|
+
export declare class Auth extends AuthService {
|
|
33
|
+
static error: {
|
|
34
|
+
shouldBeRegistered: string;
|
|
35
|
+
};
|
|
36
|
+
protected constructor();
|
|
37
|
+
/**
|
|
38
|
+
* Registers an authentication service to be used by the Auth class.
|
|
39
|
+
* You need to register an authentication service before using the Auth class.
|
|
40
|
+
* @param authService the authentication service to be used by the Auth class
|
|
41
|
+
*/
|
|
42
|
+
static useAuthService(authService: AuthService): void;
|
|
43
|
+
/**
|
|
44
|
+
* The instance of the Auth class
|
|
45
|
+
* @returns the authentication service
|
|
46
|
+
*/
|
|
47
|
+
static get instance(): Auth;
|
|
48
|
+
/**
|
|
49
|
+
* Signs up a new user
|
|
50
|
+
* @param singData the data to be used to sign up the user
|
|
51
|
+
* @returns a promise that resolves to the user credentials
|
|
52
|
+
* @example
|
|
53
|
+
* // Sign up a new user with email and password
|
|
54
|
+
* Auth.instance.signUp({ authProvider: 'email', email: 'john@test.com', password: '123456' })
|
|
55
|
+
* // Sign up a new user with a Google account
|
|
56
|
+
* Auth.instance.signUp({ authProvider: 'google'})
|
|
57
|
+
*/
|
|
58
|
+
signUp<T extends {}>(singData: SignData): Promise<UserCredentials<T>>;
|
|
59
|
+
/**
|
|
60
|
+
* Logs in an existing user
|
|
61
|
+
* @param singData the data to be used to log in the user
|
|
62
|
+
* @returns a promise that resolves to the user credentials
|
|
63
|
+
* @example
|
|
64
|
+
* // Log in an existing user with email and password
|
|
65
|
+
* Auth.instance.login({ authProvider: 'email', email: 'john@test.com', password: '123456' })
|
|
66
|
+
* // Log in an existing user with a Google account
|
|
67
|
+
* Auth.instance.login({ authProvider: 'google'})
|
|
68
|
+
*/
|
|
69
|
+
login<T extends {}>(singData: SignData): Promise<UserCredentials<T>>;
|
|
70
|
+
/**
|
|
71
|
+
* Logs out the current user
|
|
72
|
+
* @returns a promise that resolves when the user is logged out
|
|
73
|
+
*/
|
|
74
|
+
logout(): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Resets the password associated with the email.
|
|
77
|
+
* @param email the email address of the user to reset the password
|
|
78
|
+
* @returns a promise that resolves when the process is done
|
|
79
|
+
*/
|
|
80
|
+
resetEmailPassword(email: string): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Resends the email verification to the user.
|
|
83
|
+
* @returns a promise that resolves when the process is done
|
|
84
|
+
*/
|
|
85
|
+
resendVerificationEmail(email: string, password: string, verificationLink: string): Promise<void>;
|
|
86
|
+
refreshToken(): Promise<void>;
|
|
87
|
+
/**
|
|
88
|
+
* Adds a listener to be called when the authentication state changes.
|
|
89
|
+
* @param onChange the listener to be called when the authentication state changes.
|
|
90
|
+
* The listener is called with the user credentials as a parameter.
|
|
91
|
+
* If the user is logged out, the listener is called with `undefined` as a parameter.
|
|
92
|
+
* @returns a function to remove the listener
|
|
93
|
+
* @example
|
|
94
|
+
* // Add a listener to be called when the authentication state changes
|
|
95
|
+
* const removeListener = Auth.instance.onAuthStateChange( userCredentials => {
|
|
96
|
+
* if ( userCredentials ) {
|
|
97
|
+
* // The user is logged in
|
|
98
|
+
* } else {
|
|
99
|
+
* // The user is logged out
|
|
100
|
+
* }
|
|
101
|
+
* })
|
|
102
|
+
*/
|
|
103
|
+
onAuthStateChange<T extends {}>(onChange: (userCredentials: UserCredentials<T>) => void): import("../observable/observable").Unsubscriber;
|
|
104
|
+
/**
|
|
105
|
+
* Removes a listener that was added by `onAuthStateChange` method.
|
|
106
|
+
* @param onChange the listener to be removed
|
|
107
|
+
*/
|
|
108
|
+
removeAuthStateChange<T extends {}>(onChange: (userCredentials: UserCredentials<T>) => void): void;
|
|
109
|
+
/**
|
|
110
|
+
* Links an additional authentication provider to the authenticated user.
|
|
111
|
+
* @param provider the provider to be linked
|
|
112
|
+
* @returns a promise that resolves when the process is done
|
|
113
|
+
* @example
|
|
114
|
+
* // Link a Google account to the auth service
|
|
115
|
+
* Auth.instance.linkAdditionalProvider({ authProvider: 'google' })
|
|
116
|
+
*/
|
|
117
|
+
linkAdditionalProvider(provider: AuthProvider): Promise<unknown>;
|
|
118
|
+
/**
|
|
119
|
+
* Unlinks an authentication provider from the authenticated user.
|
|
120
|
+
* @param provider the provider to be unlinked
|
|
121
|
+
* @returns a promise that resolves when the process is done
|
|
122
|
+
* @example
|
|
123
|
+
* // Unlink the Google account from the auth service
|
|
124
|
+
* Auth.instance.unlinkProvider({ authProvider: 'google' })
|
|
125
|
+
*/
|
|
126
|
+
unlinkProvider(provider: AuthProvider): Promise<unknown>;
|
|
127
|
+
private authStateChanged;
|
|
128
|
+
private static _instance;
|
|
129
|
+
private static _authService;
|
|
130
|
+
private _onAuthStateChange;
|
|
131
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface UserCredentials<T extends {} = {}> {
|
|
2
|
+
id: string;
|
|
3
|
+
email: string;
|
|
4
|
+
name?: string;
|
|
5
|
+
pictureUrl?: string;
|
|
6
|
+
phoneNumber?: string;
|
|
7
|
+
emailVerified?: boolean;
|
|
8
|
+
customData?: T;
|
|
9
|
+
lastLogin?: number;
|
|
10
|
+
creationDate?: number;
|
|
11
|
+
}
|
|
12
|
+
export type AuthProvider = 'email' | 'facebook' | 'google' | 'twitter';
|
|
13
|
+
export interface SignData {
|
|
14
|
+
authProvider: AuthProvider;
|
|
15
|
+
email?: string;
|
|
16
|
+
password?: string;
|
|
17
|
+
name?: string;
|
|
18
|
+
verificationLink?: string;
|
|
19
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { CloudFunction, CloudFunctionsService } from './cloud-functions';
|
|
2
|
+
interface FunctionCollection {
|
|
3
|
+
[key: string]: CloudFunction<any, any>;
|
|
4
|
+
}
|
|
5
|
+
export declare class CloudFunctionsMock implements CloudFunctionsService {
|
|
6
|
+
constructor(registeredFunctions: FunctionCollection);
|
|
7
|
+
retrieveFunction<P, R>(cloudFunction: string): CloudFunction<P, R>;
|
|
8
|
+
callFunction<P, R>(func: CloudFunction<P, R>, params: P): Promise<R>;
|
|
9
|
+
private _registeredFunctions;
|
|
10
|
+
}
|
|
11
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type CloudFunction<P, R> = (param?: P) => Promise<R>;
|
|
2
|
+
export interface CloudFunctionsService {
|
|
3
|
+
retrieveFunction<P, R>(cloudFunction: string): CloudFunction<P, R>;
|
|
4
|
+
callFunction<P, R>(func: CloudFunction<P, R>, params: P): Promise<R>;
|
|
5
|
+
}
|
|
6
|
+
export declare class CloudFunctions {
|
|
7
|
+
private constructor();
|
|
8
|
+
static error: {
|
|
9
|
+
shouldBeRegistered: string;
|
|
10
|
+
};
|
|
11
|
+
static useCloudFunctionsService(cloudFunctionsService: CloudFunctionsService): void;
|
|
12
|
+
static get instance(): CloudFunctions;
|
|
13
|
+
getRawFunction<P, R>(cloudFunction: string): CloudFunction<P, R>;
|
|
14
|
+
getFunction<P, R = void>(cloudFunction: string): CloudFunction<P, R>;
|
|
15
|
+
private processParam;
|
|
16
|
+
private processResult;
|
|
17
|
+
private static _cloudFunctionsService;
|
|
18
|
+
private static _instance;
|
|
19
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type UploadProgress = (uploadedBytes: number, fileSize: number) => void;
|
|
2
|
+
type CloudStorageFactory = () => CloudStorage;
|
|
3
|
+
export interface UploadControl {
|
|
4
|
+
pause: () => void;
|
|
5
|
+
resume: () => void;
|
|
6
|
+
cancel: () => void;
|
|
7
|
+
onProgress: (callback: UploadProgress) => void;
|
|
8
|
+
}
|
|
9
|
+
export type StorableData = File | Blob | Uint8Array | ArrayBuffer;
|
|
10
|
+
export declare abstract class CloudStorage {
|
|
11
|
+
abstract save(id: string, data: StorableData, progress?: UploadProgress): Promise<string>;
|
|
12
|
+
abstract getUrl(reference: string): Promise<string>;
|
|
13
|
+
abstract uploadControl(): UploadControl;
|
|
14
|
+
abstract delete(reference: string): Promise<void>;
|
|
15
|
+
static registerCloudStorage(cloudStorageProviderName: string, factory: CloudStorageFactory): void;
|
|
16
|
+
static createInstance(providerName: string): CloudStorage;
|
|
17
|
+
get className(): string;
|
|
18
|
+
static useCloudStorage(provider: CloudStorage): void;
|
|
19
|
+
static get defaultCloudStorage(): CloudStorage;
|
|
20
|
+
static _defaultCloudStorage: CloudStorage;
|
|
21
|
+
private static _cloudStorageFactoryMap;
|
|
22
|
+
}
|
|
23
|
+
export declare function registerCloudStorage(cloudStorageProviderName: string, factory: CloudStorageFactory): (constructor: Function) => void;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { CloudStorage, StorableData, UploadControl } from './cloud-storage';
|
|
2
|
+
export declare class MockCloudStorage extends CloudStorage {
|
|
3
|
+
constructor(pathToMockFiles?: string);
|
|
4
|
+
/**
|
|
5
|
+
* Introduce a delay in the execution of operations to simulate a real data source
|
|
6
|
+
* @param miliSeconds the number of milliseconds to delay the execution of operations
|
|
7
|
+
* @returns a chainable reference to this object
|
|
8
|
+
*/
|
|
9
|
+
simulateDelay(miliSeconds: number): this;
|
|
10
|
+
private resolveWithDelay;
|
|
11
|
+
save(id: string, data: StorableData): Promise<string>;
|
|
12
|
+
uploadControl(): UploadControl;
|
|
13
|
+
getUrl(reference: string): Promise<string>;
|
|
14
|
+
delete(reference: string): Promise<void>;
|
|
15
|
+
private _simulateDelay;
|
|
16
|
+
private _pendingPromises;
|
|
17
|
+
private _onProgress;
|
|
18
|
+
private _pathToMockFiles;
|
|
19
|
+
mockFileSystem: {};
|
|
20
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Callback } from '../observable/observable';
|
|
2
|
+
import { Persistent } from '../persistent/persistent';
|
|
3
|
+
import { CloudStorage, StorableData, UploadControl, UploadProgress } from './cloud-storage';
|
|
4
|
+
export declare enum StoredFileEvent {
|
|
5
|
+
stored = 0,
|
|
6
|
+
pendingDataSet = 1,
|
|
7
|
+
deleted = 2
|
|
8
|
+
}
|
|
9
|
+
export interface StoredFileChange {
|
|
10
|
+
event: StoredFileEvent;
|
|
11
|
+
pendingData?: StorableData;
|
|
12
|
+
storedFile: StoredFile;
|
|
13
|
+
}
|
|
14
|
+
export interface StoreParams {
|
|
15
|
+
data?: StorableData;
|
|
16
|
+
fileName?: string;
|
|
17
|
+
progress?: UploadProgress;
|
|
18
|
+
cloudStorageProvider?: CloudStorage;
|
|
19
|
+
}
|
|
20
|
+
export declare class StoredFile extends Persistent {
|
|
21
|
+
save({ data, fileName, progress, cloudStorageProvider }?: StoreParams): Promise<void>;
|
|
22
|
+
uploadControl(): UploadControl;
|
|
23
|
+
delete(): Promise<void>;
|
|
24
|
+
set provider(value: CloudStorage);
|
|
25
|
+
get provider(): CloudStorage;
|
|
26
|
+
get url(): string | undefined;
|
|
27
|
+
get mimeType(): string | undefined;
|
|
28
|
+
setDataToStore(data: StorableData): this;
|
|
29
|
+
get originalFileName(): string | undefined;
|
|
30
|
+
onChange(listenerCallback: Callback<StoredFileChange>): import("../observable/observable").Unsubscriber;
|
|
31
|
+
private _reference;
|
|
32
|
+
private _url;
|
|
33
|
+
private _cloudStorageProviderName;
|
|
34
|
+
private _originalFileName;
|
|
35
|
+
private _mimeType;
|
|
36
|
+
private _provider;
|
|
37
|
+
private _pendingData;
|
|
38
|
+
private _onChange;
|
|
39
|
+
}
|