@dumbmatter/idb 8.0.0 → 8.0.3
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/README.md +1 -1
- package/build/entry.d.ts +36 -27
- package/build/index.cjs +1 -3
- package/build/index.js +1 -1
- package/build/util.d.ts +2 -2
- package/build/wrap-idb-value.d.ts +2 -2
- package/package.json +21 -17
package/README.md
CHANGED
package/build/entry.d.ts
CHANGED
|
@@ -58,14 +58,14 @@ export interface DeleteDBCallbacks {
|
|
|
58
58
|
*/
|
|
59
59
|
export declare function deleteDB(name: string, { blocked }?: DeleteDBCallbacks): Promise<void>;
|
|
60
60
|
export { unwrap, wrap } from './wrap-idb-value.js';
|
|
61
|
-
|
|
61
|
+
type KeyToKeyNoIndex<T> = {
|
|
62
62
|
[K in keyof T]: string extends K ? never : number extends K ? never : K;
|
|
63
63
|
};
|
|
64
|
-
|
|
64
|
+
type ValuesOf<T> = T extends {
|
|
65
65
|
[K in keyof T]: infer U;
|
|
66
66
|
} ? U : never;
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
type KnownKeys<T> = ValuesOf<KeyToKeyNoIndex<T>>;
|
|
68
|
+
type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
|
|
69
69
|
export interface DBSchema {
|
|
70
70
|
[s: string]: DBSchemaValue;
|
|
71
71
|
}
|
|
@@ -83,38 +83,38 @@ interface DBSchemaValue {
|
|
|
83
83
|
*
|
|
84
84
|
* @template DBTypes DB schema type, or unknown if the DB isn't typed.
|
|
85
85
|
*/
|
|
86
|
-
export
|
|
86
|
+
export type StoreNames<DBTypes extends DBSchema | unknown> = DBTypes extends DBSchema ? KnownKeys<DBTypes> : string;
|
|
87
87
|
/**
|
|
88
88
|
* Extract database value types from the DB schema type.
|
|
89
89
|
*
|
|
90
90
|
* @template DBTypes DB schema type, or unknown if the DB isn't typed.
|
|
91
91
|
* @template StoreName Names of the object stores to get the types of.
|
|
92
92
|
*/
|
|
93
|
-
export
|
|
94
|
-
|
|
93
|
+
export type StoreValue<DBTypes extends DBSchema | unknown, StoreName extends StoreNames<DBTypes>> = DBTypes extends DBSchema ? DBTypes[StoreName]['value'] : any;
|
|
94
|
+
type KeyPathToNestedObject<S extends string> = S extends `${infer T}.${infer U}` ? {
|
|
95
95
|
[Key in T]: KeyPathToNestedObject<U>;
|
|
96
96
|
} : S;
|
|
97
|
-
|
|
97
|
+
type OptionalNested<Type, PathToKey> = PathToKey extends object ? Omit<Type, keyof PathToKey> & {
|
|
98
98
|
[Key in Extract<keyof PathToKey, keyof Type>]: OptionalNested<Type[Key], PathToKey[Key]>;
|
|
99
99
|
} : PathToKey extends keyof Type ? Omit<Type, PathToKey> & {
|
|
100
100
|
[Key in PathToKey]?: Type[Key];
|
|
101
101
|
} : never;
|
|
102
|
-
|
|
103
|
-
export
|
|
102
|
+
type ValueWithOptionalKeyPath<Value extends unknown, KeyPath extends string> = OptionalNested<Value, KeyPathToNestedObject<KeyPath>>;
|
|
103
|
+
export type StoreValueWithOptionalKey<DBTypes extends DBSchema | unknown, StoreName extends StoreNames<DBTypes>> = DBTypes extends DBSchema ? DBTypes[StoreName]['autoIncrementKeyPath'] extends string ? (ValueWithOptionalKeyPath<DBTypes[StoreName]['value'], DBTypes[StoreName]['autoIncrementKeyPath']>) : StoreValue<DBTypes, StoreName> : any;
|
|
104
104
|
/**
|
|
105
105
|
* Extract database key types from the DB schema type.
|
|
106
106
|
*
|
|
107
107
|
* @template DBTypes DB schema type, or unknown if the DB isn't typed.
|
|
108
108
|
* @template StoreName Names of the object stores to get the types of.
|
|
109
109
|
*/
|
|
110
|
-
export
|
|
110
|
+
export type StoreKey<DBTypes extends DBSchema | unknown, StoreName extends StoreNames<DBTypes>> = DBTypes extends DBSchema ? DBTypes[StoreName]['key'] : IDBValidKey;
|
|
111
111
|
/**
|
|
112
112
|
* Extract the names of indexes in certain object stores from the DB schema type.
|
|
113
113
|
*
|
|
114
114
|
* @template DBTypes DB schema type, or unknown if the DB isn't typed.
|
|
115
115
|
* @template StoreName Names of the object stores to get the types of.
|
|
116
116
|
*/
|
|
117
|
-
export
|
|
117
|
+
export type IndexNames<DBTypes extends DBSchema | unknown, StoreName extends StoreNames<DBTypes>> = DBTypes extends DBSchema ? keyof DBTypes[StoreName]['indexes'] & string : string;
|
|
118
118
|
/**
|
|
119
119
|
* Extract the types of indexes in certain object stores from the DB schema type.
|
|
120
120
|
*
|
|
@@ -122,10 +122,13 @@ export declare type IndexNames<DBTypes extends DBSchema | unknown, StoreName ext
|
|
|
122
122
|
* @template StoreName Names of the object stores to get the types of.
|
|
123
123
|
* @template IndexName Names of the indexes to get the types of.
|
|
124
124
|
*/
|
|
125
|
-
export
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
125
|
+
export type IndexKey<DBTypes extends DBSchema | unknown, StoreName extends StoreNames<DBTypes>, IndexName extends IndexNames<DBTypes, StoreName>> = DBTypes extends DBSchema ? IndexName extends keyof DBTypes[StoreName]['indexes'] ? DBTypes[StoreName]['indexes'][IndexName] : IDBValidKey : IDBValidKey;
|
|
126
|
+
type CursorSource<DBTypes extends DBSchema | unknown, TxStores extends ArrayLike<StoreNames<DBTypes>>, StoreName extends StoreNames<DBTypes>, IndexName extends IndexNames<DBTypes, StoreName> | unknown, Mode extends IDBTransactionMode = 'readonly'> = IndexName extends IndexNames<DBTypes, StoreName> ? IDBPIndex<DBTypes, TxStores, StoreName, IndexName, Mode> : IDBPObjectStore<DBTypes, TxStores, StoreName, Mode>;
|
|
127
|
+
type CursorKey<DBTypes extends DBSchema | unknown, StoreName extends StoreNames<DBTypes>, IndexName extends IndexNames<DBTypes, StoreName> | unknown> = IndexName extends IndexNames<DBTypes, StoreName> ? IndexKey<DBTypes, StoreName, IndexName> : StoreKey<DBTypes, StoreName>;
|
|
128
|
+
type IDBPDatabaseExtends = Omit<IDBDatabase, 'createObjectStore' | 'deleteObjectStore' | 'transaction' | 'objectStoreNames'>;
|
|
129
|
+
export type DOMStringListSymbolIteratorType = DOMStringList extends {
|
|
130
|
+
[Symbol.iterator](): infer R;
|
|
131
|
+
} ? R : IterableIterator<string>;
|
|
129
132
|
/**
|
|
130
133
|
* A variation of DOMStringList with precise string types
|
|
131
134
|
*/
|
|
@@ -133,7 +136,11 @@ export interface TypedDOMStringList<T extends string> extends DOMStringList {
|
|
|
133
136
|
contains(string: T): boolean;
|
|
134
137
|
item(index: number): T | null;
|
|
135
138
|
[index: number]: T;
|
|
136
|
-
|
|
139
|
+
/**
|
|
140
|
+
* To resolve https://github.com/jakearchibald/idb/issues/327,
|
|
141
|
+
* and for compatibility with TypeScript >= 5.6 with ArrayIterator.
|
|
142
|
+
*/
|
|
143
|
+
[Symbol.iterator](): IterableIterator<string> extends DOMStringListSymbolIteratorType ? IterableIterator<T> : DOMStringListSymbolIteratorType & Iterator<T>;
|
|
137
144
|
}
|
|
138
145
|
interface IDBTransactionOptions {
|
|
139
146
|
/**
|
|
@@ -156,10 +163,12 @@ export interface IDBPDatabase<DBTypes extends DBSchema | unknown = unknown> exte
|
|
|
156
163
|
*
|
|
157
164
|
* Throws a "InvalidStateError" DOMException if not called within an upgrade transaction.
|
|
158
165
|
*/
|
|
159
|
-
createObjectStore<Name extends StoreNames<DBTypes>>(name: Name,
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
166
|
+
createObjectStore<Name extends StoreNames<DBTypes>>(name: Name, ...args: DBTypes extends DBSchema ? DBTypes[Name]['autoIncrementKeyPath'] extends string ? [
|
|
167
|
+
optionalParameters: (IDBObjectStoreParameters & {
|
|
168
|
+
autoIncrement: true;
|
|
169
|
+
keyPath: DBTypes[Name]['autoIncrementKeyPath'];
|
|
170
|
+
})
|
|
171
|
+
] : [optionalParameters?: IDBObjectStoreParameters] : [optionalParameters?: IDBObjectStoreParameters]): IDBPObjectStore<DBTypes, ArrayLike<StoreNames<DBTypes>>, Name, 'versionchange'>;
|
|
163
172
|
/**
|
|
164
173
|
* Deletes the object store with the given name.
|
|
165
174
|
*
|
|
@@ -338,7 +347,7 @@ export interface IDBPDatabase<DBTypes extends DBSchema | unknown = unknown> exte
|
|
|
338
347
|
*/
|
|
339
348
|
put<Name extends StoreNames<DBTypes>>(storeName: Name, value: StoreValueWithOptionalKey<DBTypes, Name>, key?: StoreKey<DBTypes, Name> | IDBKeyRange): Promise<StoreKey<DBTypes, Name>>;
|
|
340
349
|
}
|
|
341
|
-
|
|
350
|
+
type IDBPTransactionExtends = Omit<IDBTransaction, 'db' | 'objectStore' | 'objectStoreNames'>;
|
|
342
351
|
export interface IDBPTransaction<DBTypes extends DBSchema | unknown = unknown, TxStores extends ArrayLike<StoreNames<DBTypes>> = ArrayLike<StoreNames<DBTypes>>, Mode extends IDBTransactionMode = 'readonly'> extends IDBPTransactionExtends {
|
|
343
352
|
/**
|
|
344
353
|
* The transaction's mode.
|
|
@@ -365,7 +374,7 @@ export interface IDBPTransaction<DBTypes extends DBSchema | unknown = unknown, T
|
|
|
365
374
|
*/
|
|
366
375
|
objectStore<StoreName extends TxStores[number]>(name: StoreName): IDBPObjectStore<DBTypes, TxStores, StoreName, Mode>;
|
|
367
376
|
}
|
|
368
|
-
|
|
377
|
+
type IDBPObjectStoreExtends = Omit<IDBObjectStore, 'transaction' | 'add' | 'clear' | 'count' | 'createIndex' | 'delete' | 'get' | 'getAll' | 'getAllKeys' | 'getKey' | 'index' | 'openCursor' | 'openKeyCursor' | 'put' | 'indexNames'>;
|
|
369
378
|
export interface IDBPObjectStore<DBTypes extends DBSchema | unknown = unknown, TxStores extends ArrayLike<StoreNames<DBTypes>> = ArrayLike<StoreNames<DBTypes>>, StoreName extends StoreNames<DBTypes> = StoreNames<DBTypes>, Mode extends IDBTransactionMode = 'readonly'> extends IDBPObjectStoreExtends {
|
|
370
379
|
/**
|
|
371
380
|
* The names of indexes in the store.
|
|
@@ -465,7 +474,7 @@ export interface IDBPObjectStore<DBTypes extends DBSchema | unknown = unknown, T
|
|
|
465
474
|
*/
|
|
466
475
|
iterate(query?: StoreKey<DBTypes, StoreName> | IDBKeyRange | null, direction?: IDBCursorDirection): AsyncIterableIterator<IDBPCursorWithValueIteratorValue<DBTypes, TxStores, StoreName, unknown, Mode>>;
|
|
467
476
|
}
|
|
468
|
-
|
|
477
|
+
type IDBPIndexExtends = Omit<IDBIndex, 'objectStore' | 'count' | 'get' | 'getAll' | 'getAllKeys' | 'getKey' | 'openCursor' | 'openKeyCursor'>;
|
|
469
478
|
export interface IDBPIndex<DBTypes extends DBSchema | unknown = unknown, TxStores extends ArrayLike<StoreNames<DBTypes>> = ArrayLike<StoreNames<DBTypes>>, StoreName extends StoreNames<DBTypes> = StoreNames<DBTypes>, IndexName extends IndexNames<DBTypes, StoreName> = IndexNames<DBTypes, StoreName>, Mode extends IDBTransactionMode = 'readonly'> extends IDBPIndexExtends {
|
|
470
479
|
/**
|
|
471
480
|
* The IDBObjectStore the index belongs to.
|
|
@@ -533,7 +542,7 @@ export interface IDBPIndex<DBTypes extends DBSchema | unknown = unknown, TxStore
|
|
|
533
542
|
*/
|
|
534
543
|
iterate(query?: IndexKey<DBTypes, StoreName, IndexName> | IDBKeyRange | null, direction?: IDBCursorDirection): AsyncIterableIterator<IDBPCursorWithValueIteratorValue<DBTypes, TxStores, StoreName, IndexName, Mode>>;
|
|
535
544
|
}
|
|
536
|
-
|
|
545
|
+
type IDBPCursorExtends = Omit<IDBCursor, 'key' | 'primaryKey' | 'source' | 'advance' | 'continue' | 'continuePrimaryKey' | 'delete' | 'update'>;
|
|
537
546
|
export interface IDBPCursor<DBTypes extends DBSchema | unknown = unknown, TxStores extends ArrayLike<StoreNames<DBTypes>> = ArrayLike<StoreNames<DBTypes>>, StoreName extends StoreNames<DBTypes> = StoreNames<DBTypes>, IndexName extends IndexNames<DBTypes, StoreName> | unknown = unknown, Mode extends IDBTransactionMode = 'readonly'> extends IDBPCursorExtends {
|
|
538
547
|
/**
|
|
539
548
|
* The key of the current index or object store item.
|
|
@@ -585,7 +594,7 @@ export interface IDBPCursor<DBTypes extends DBSchema | unknown = unknown, TxStor
|
|
|
585
594
|
*/
|
|
586
595
|
[Symbol.asyncIterator](): AsyncIterableIterator<IDBPCursorIteratorValue<DBTypes, TxStores, StoreName, IndexName, Mode>>;
|
|
587
596
|
}
|
|
588
|
-
|
|
597
|
+
type IDBPCursorIteratorValueExtends<DBTypes extends DBSchema | unknown = unknown, TxStores extends ArrayLike<StoreNames<DBTypes>> = ArrayLike<StoreNames<DBTypes>>, StoreName extends StoreNames<DBTypes> = StoreNames<DBTypes>, IndexName extends IndexNames<DBTypes, StoreName> | unknown = unknown, Mode extends IDBTransactionMode = 'readonly'> = Omit<IDBPCursor<DBTypes, TxStores, StoreName, IndexName, Mode>, 'advance' | 'continue' | 'continuePrimaryKey'>;
|
|
589
598
|
export interface IDBPCursorIteratorValue<DBTypes extends DBSchema | unknown = unknown, TxStores extends ArrayLike<StoreNames<DBTypes>> = ArrayLike<StoreNames<DBTypes>>, StoreName extends StoreNames<DBTypes> = StoreNames<DBTypes>, IndexName extends IndexNames<DBTypes, StoreName> | unknown = unknown, Mode extends IDBTransactionMode = 'readonly'> extends IDBPCursorIteratorValueExtends<DBTypes, TxStores, StoreName, IndexName, Mode> {
|
|
590
599
|
/**
|
|
591
600
|
* Advances the cursor a given number of records.
|
|
@@ -617,7 +626,7 @@ export interface IDBPCursorWithValue<DBTypes extends DBSchema | unknown = unknow
|
|
|
617
626
|
*/
|
|
618
627
|
[Symbol.asyncIterator](): AsyncIterableIterator<IDBPCursorWithValueIteratorValue<DBTypes, TxStores, StoreName, IndexName, Mode>>;
|
|
619
628
|
}
|
|
620
|
-
|
|
629
|
+
type IDBPCursorWithValueIteratorValueExtends<DBTypes extends DBSchema | unknown = unknown, TxStores extends ArrayLike<StoreNames<DBTypes>> = ArrayLike<StoreNames<DBTypes>>, StoreName extends StoreNames<DBTypes> = StoreNames<DBTypes>, IndexName extends IndexNames<DBTypes, StoreName> | unknown = unknown, Mode extends IDBTransactionMode = 'readonly'> = Omit<IDBPCursorWithValue<DBTypes, TxStores, StoreName, IndexName, Mode>, 'advance' | 'continue' | 'continuePrimaryKey'>;
|
|
621
630
|
export interface IDBPCursorWithValueIteratorValue<DBTypes extends DBSchema | unknown = unknown, TxStores extends ArrayLike<StoreNames<DBTypes>> = ArrayLike<StoreNames<DBTypes>>, StoreName extends StoreNames<DBTypes> = StoreNames<DBTypes>, IndexName extends IndexNames<DBTypes, StoreName> | unknown = unknown, Mode extends IDBTransactionMode = 'readonly'> extends IDBPCursorWithValueIteratorValueExtends<DBTypes, TxStores, StoreName, IndexName, Mode> {
|
|
622
631
|
/**
|
|
623
632
|
* Advances the cursor a given number of records.
|
package/build/index.cjs
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
3
|
const instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);
|
|
6
4
|
|
|
7
5
|
let idbProxyableTypes;
|
|
@@ -46,7 +44,7 @@ function promisifyRequest(request) {
|
|
|
46
44
|
request.addEventListener('success', success);
|
|
47
45
|
request.addEventListener('error', error);
|
|
48
46
|
});
|
|
49
|
-
// This mapping exists in reverseTransformCache but doesn't
|
|
47
|
+
// This mapping exists in reverseTransformCache but doesn't exist in transformCache. This
|
|
50
48
|
// is because we create many promises from a single IDBRequest.
|
|
51
49
|
reverseTransformCache.set(promise, request);
|
|
52
50
|
return promise;
|
package/build/index.js
CHANGED
|
@@ -42,7 +42,7 @@ function promisifyRequest(request) {
|
|
|
42
42
|
request.addEventListener('success', success);
|
|
43
43
|
request.addEventListener('error', error);
|
|
44
44
|
});
|
|
45
|
-
// This mapping exists in reverseTransformCache but doesn't
|
|
45
|
+
// This mapping exists in reverseTransformCache but doesn't exist in transformCache. This
|
|
46
46
|
// is because we create many promises from a single IDBRequest.
|
|
47
47
|
reverseTransformCache.set(promise, request);
|
|
48
48
|
return promise;
|
package/build/util.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
1
|
+
export type Constructor = new (...args: any[]) => any;
|
|
2
|
+
export type Func = (...args: any[]) => any;
|
|
3
3
|
export declare const instanceOfAny: (object: any, constructors: Constructor[]) => boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IDBPCursor, IDBPCursorWithValue, IDBPDatabase, IDBPIndex, IDBPObjectStore, IDBPTransaction } from './entry.js';
|
|
2
|
-
export declare const reverseTransformCache: WeakMap<
|
|
2
|
+
export declare const reverseTransformCache: WeakMap<WeakKey, any>;
|
|
3
3
|
export declare function replaceTraps(callback: (currentTraps: ProxyHandler<any>) => ProxyHandler<any>): void;
|
|
4
4
|
/**
|
|
5
5
|
* Enhance an IDB object with helpers.
|
|
@@ -22,7 +22,7 @@ export declare function wrap<T>(value: IDBRequest<T>): Promise<T>;
|
|
|
22
22
|
interface Unwrap {
|
|
23
23
|
(value: IDBPCursorWithValue<any, any, any, any, any>): IDBCursorWithValue;
|
|
24
24
|
(value: IDBPCursor<any, any, any, any, any>): IDBCursor;
|
|
25
|
-
(value: IDBPDatabase): IDBDatabase;
|
|
25
|
+
(value: IDBPDatabase<any>): IDBDatabase;
|
|
26
26
|
(value: IDBPIndex<any, any, any, any, any>): IDBIndex;
|
|
27
27
|
(value: IDBPObjectStore<any, any, any, any>): IDBObjectStore;
|
|
28
28
|
(value: IDBPTransaction<any, any, any>): IDBTransaction;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dumbmatter/idb",
|
|
3
|
-
"version": "8.0.
|
|
3
|
+
"version": "8.0.3",
|
|
4
4
|
"description": "A small wrapper that makes IndexedDB usable",
|
|
5
5
|
"main": "./build/index.cjs",
|
|
6
6
|
"module": "./build/index.js",
|
|
@@ -22,31 +22,35 @@
|
|
|
22
22
|
],
|
|
23
23
|
"type": "module",
|
|
24
24
|
"scripts": {
|
|
25
|
-
"build": "PRODUCTION=1 rollup -c && node --experimental-modules lib/size-report.mjs",
|
|
25
|
+
"build": "cross-env PRODUCTION=1 rollup -c && node --experimental-modules lib/size-report.mjs",
|
|
26
26
|
"dev": "rollup -c --watch",
|
|
27
27
|
"prepack": "npm run build"
|
|
28
28
|
},
|
|
29
29
|
"repository": {
|
|
30
30
|
"type": "git",
|
|
31
|
-
"url": "git://github.com/
|
|
31
|
+
"url": "git://github.com/dumbmatter/idb.git"
|
|
32
32
|
},
|
|
33
33
|
"author": "Jake Archibald",
|
|
34
34
|
"license": "ISC",
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@rollup/plugin-commonjs": "^
|
|
37
|
-
"@rollup/plugin-node-resolve": "^
|
|
38
|
-
"@
|
|
39
|
-
"@
|
|
40
|
-
"@types/
|
|
41
|
-
"
|
|
36
|
+
"@rollup/plugin-commonjs": "^28.0.3",
|
|
37
|
+
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
38
|
+
"@rollup/plugin-terser": "^0.4.4",
|
|
39
|
+
"@rollup/plugin-typescript": "^12.1.2",
|
|
40
|
+
"@types/chai": "^5.2.2",
|
|
41
|
+
"@types/estree": "^1.0.7",
|
|
42
|
+
"@types/mocha": "^10.0.10",
|
|
43
|
+
"@types/node": "^22.15.14",
|
|
44
|
+
"chai": "^5.2.0",
|
|
42
45
|
"conditional-type-checks": "^1.0.6",
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"rollup
|
|
50
|
-
"
|
|
46
|
+
"cross-env": "^7.0.3",
|
|
47
|
+
"del": "^8.0.0",
|
|
48
|
+
"filesize": "^10.1.6",
|
|
49
|
+
"glob": "^11.0.2",
|
|
50
|
+
"mocha": "^11.2.2",
|
|
51
|
+
"prettier": "^3.5.3",
|
|
52
|
+
"rollup": "^4.40.2",
|
|
53
|
+
"tslib": "^2.8.1",
|
|
54
|
+
"typescript": "^5.8.3"
|
|
51
55
|
}
|
|
52
56
|
}
|