@dataclouder/nest-storage 0.0.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/index.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export * from './nest-storage.module';
2
+ export * from './models/cloud.model';
3
+ export * from './services/cloud-storage.service';
4
+ export * from './services/minio-storage.service';
package/index.js ADDED
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./nest-storage.module"), exports);
18
+ __exportStar(require("./models/cloud.model"), exports);
19
+ __exportStar(require("./services/cloud-storage.service"), exports);
20
+ __exportStar(require("./services/minio-storage.service"), exports);
21
+ //# sourceMappingURL=index.js.map
package/index.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/nest-storage/src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,wDAAsC;AAEtC,uDAAqC;AAErC,mEAAiD;AACjD,mEAAiD"}
@@ -0,0 +1,20 @@
1
+ import { IAuditable } from '@dataclouder/nest-core';
2
+ export interface BasicStorage {
3
+ url: string;
4
+ }
5
+ export interface CloudStorage extends BasicStorage {
6
+ path?: string;
7
+ bucket?: string;
8
+ }
9
+ export interface AudioStorage extends CloudStorage {
10
+ voice?: string;
11
+ transcription?: any;
12
+ }
13
+ export interface FileStorage extends BasicStorage {
14
+ name?: string;
15
+ size?: number;
16
+ type?: string;
17
+ }
18
+ export interface CloudFileStorage extends FileStorage, CloudStorage {
19
+ auditable: IAuditable;
20
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=cloud.model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud.model.js","sourceRoot":"","sources":["../../../../../libs/nest-storage/src/models/cloud.model.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export declare class NestStorageModule {
2
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.NestStorageModule = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const cloud_storage_service_1 = require("./services/cloud-storage.service");
12
+ const minio_storage_service_1 = require("./services/minio-storage.service");
13
+ let NestStorageModule = class NestStorageModule {
14
+ };
15
+ exports.NestStorageModule = NestStorageModule;
16
+ exports.NestStorageModule = NestStorageModule = __decorate([
17
+ (0, common_1.Module)({
18
+ providers: [cloud_storage_service_1.CloudStorageService, minio_storage_service_1.MinioStorageService],
19
+ exports: [cloud_storage_service_1.CloudStorageService, minio_storage_service_1.MinioStorageService],
20
+ })
21
+ ], NestStorageModule);
22
+ //# sourceMappingURL=nest-storage.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nest-storage.module.js","sourceRoot":"","sources":["../../../../libs/nest-storage/src/nest-storage.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,4EAAuE;AACvE,4EAAuE;AAMhE,IAAM,iBAAiB,GAAvB,MAAM,iBAAiB;CAAG,CAAA;AAApB,8CAAiB;4BAAjB,iBAAiB;IAJ7B,IAAA,eAAM,EAAC;QACN,SAAS,EAAE,CAAC,2CAAmB,EAAE,2CAAmB,CAAC;QACrD,OAAO,EAAE,CAAC,2CAAmB,EAAE,2CAAmB,CAAC;KACpD,CAAC;GACW,iBAAiB,CAAG"}
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@dataclouder/nest-storage",
3
+ "version": "0.0.2",
4
+ "description": "NestJS library for storage services",
5
+ "main": "index.js",
6
+ "types": "index.d.ts",
7
+ "files": [
8
+ "**/*.js",
9
+ "**/*.d.ts",
10
+ "**/*.js.map"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsc -p tsconfig.lib.json",
14
+ "clean": "rm -rf dist",
15
+ "publish:npm": "npm run build && npm version patch && npm publish"
16
+ },
17
+ "keywords": [
18
+ "nestjs",
19
+ "library",
20
+ "storage",
21
+ "minio",
22
+ "gcs"
23
+ ],
24
+ "author": "dataclouder",
25
+ "license": "MIT",
26
+ "peerDependencies": {
27
+ "@nestjs/common": ">=11.0.0",
28
+ "@nestjs/core": ">=11.0.0",
29
+ "rxjs": ">=7.0.0"
30
+ },
31
+ "publishConfig": {
32
+ "access": "public"
33
+ }
34
+ }
@@ -0,0 +1,31 @@
1
+ import { BasicStorage, CloudFileStorage } from '../models/cloud.model';
2
+ export interface UploadWebpImageOptions {
3
+ bucketName?: string;
4
+ fileName: string;
5
+ imageBuffer: Buffer;
6
+ resizeWidth?: number;
7
+ contentType?: string;
8
+ metadata?: {
9
+ [key: string]: any;
10
+ };
11
+ }
12
+ export declare class CloudStorageService {
13
+ private storage;
14
+ constructor();
15
+ uploadFile(bucketName: string, fileName: string, fileBuffer: Buffer, contentType?: string): Promise<any>;
16
+ uploadWebpImage(options: UploadWebpImageOptions): Promise<Partial<CloudFileStorage>>;
17
+ uploadFileAndMakePublic(bucketName: string, fileName: string, fileBuffer: Buffer, contentType?: string, metadata?: {
18
+ [key: string]: any;
19
+ }): Promise<Partial<CloudFileStorage>>;
20
+ deleteStorageFile(bucketName: string, fileName: string): Promise<any>;
21
+ removeAllStorageFilesPresentInObject(obj: any): Promise<any>;
22
+ removeAllStorageFilesByUrl(obj: any): Promise<any>;
23
+ private extractBucketAndPathFromUrl;
24
+ private findAllObjectsWithUrls;
25
+ findAllObjectsWithPaths(obj: any): any[];
26
+ extractPath(file: BasicStorage): string | undefined;
27
+ getFile(bucketName: string, fileName: string): Promise<Buffer>;
28
+ generateSignedUrl(bucketName: string, fileName: string, expiresInMinutes?: number): Promise<string>;
29
+ listFiles(bucketName: string, prefix?: string): Promise<any[]>;
30
+ fileExists(bucketName: string, fileName: string): Promise<boolean>;
31
+ }
@@ -0,0 +1,242 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.CloudStorageService = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const storage_1 = require("@google-cloud/storage");
15
+ const sharp = require("sharp");
16
+ const FIREBASE_STORAGE_URL_REGEX = /https:\/\/firebasestorage\.googleapis\.com\/v0\/b\/([^/]+)\/o\/([^?]+)/;
17
+ const GOOGLE_STORAGE_URL_REGEX = /https:\/\/storage\.googleapis\.com\/([^/]+)\/(.+)/;
18
+ let CloudStorageService = class CloudStorageService {
19
+ storage;
20
+ constructor() {
21
+ this.storage = new storage_1.Storage();
22
+ }
23
+ async uploadFile(bucketName, fileName, fileBuffer, contentType) {
24
+ const bucket = this.storage.bucket(bucketName);
25
+ const file = bucket.file(fileName);
26
+ const options = contentType ? { contentType } : undefined;
27
+ return new Promise((resolve, reject) => {
28
+ const stream = file.createWriteStream(options);
29
+ stream.on('error', (err) => {
30
+ reject(err);
31
+ });
32
+ stream.on('finish', async () => {
33
+ console.log(`gs://${bucketName}/${fileName} uploaded successfully`);
34
+ resolve({
35
+ success: true,
36
+ fileName,
37
+ path: `gs://${bucketName}/${fileName}`,
38
+ });
39
+ });
40
+ stream.end(fileBuffer);
41
+ });
42
+ }
43
+ async uploadWebpImage(options) {
44
+ const { bucketName: providedBucketName, fileName, imageBuffer, resizeWidth = 1000, contentType = 'image/webp', metadata, } = options;
45
+ const bucketToUse = providedBucketName || process.env.STORAGE_BUCKET;
46
+ if (!bucketToUse) {
47
+ throw new Error('Bucket name must be provided either in options or as STORAGE_BUCKET environment variable.');
48
+ }
49
+ const webpBuffer = await sharp(imageBuffer)
50
+ .resize(resizeWidth)
51
+ .webp({ quality: 85 })
52
+ .toBuffer();
53
+ const result = await this.uploadFileAndMakePublic(bucketToUse, fileName, webpBuffer, contentType, metadata);
54
+ return result;
55
+ }
56
+ async uploadFileAndMakePublic(bucketName, fileName, fileBuffer, contentType, metadata) {
57
+ const bucket = this.storage.bucket(bucketName);
58
+ const file = bucket.file(fileName);
59
+ if (metadata) {
60
+ await file.setMetadata({ metadata });
61
+ }
62
+ return new Promise((resolve, reject) => {
63
+ const stream = file.createWriteStream(contentType ? { contentType } : undefined);
64
+ stream.on('error', (err) => {
65
+ reject(err);
66
+ });
67
+ stream.on('finish', async () => {
68
+ try {
69
+ await file.makePublic();
70
+ console.log(`gs://${bucketName}/${fileName} uploaded and made public`);
71
+ resolve({
72
+ bucket: bucketName,
73
+ path: file.name,
74
+ url: file.publicUrl(),
75
+ });
76
+ }
77
+ catch (makePublicError) {
78
+ reject(makePublicError);
79
+ }
80
+ });
81
+ stream.end(fileBuffer);
82
+ });
83
+ }
84
+ async deleteStorageFile(bucketName, fileName) {
85
+ const _results = await this.storage.bucket(bucketName).file(fileName).delete();
86
+ console.log(`gs://${bucketName}/${fileName} deleted`);
87
+ return _results;
88
+ }
89
+ async removeAllStorageFilesPresentInObject(obj) {
90
+ const pathsObjects = this.findAllObjectsWithPaths(obj);
91
+ console.log('Removing items from storage: ', pathsObjects.length);
92
+ const promises = pathsObjects.map((obj) => this.deleteStorageFile(obj.bucket, obj.path));
93
+ try {
94
+ return await Promise.all(promises);
95
+ }
96
+ catch (error) {
97
+ console.error('Error removing items from storage: ', error);
98
+ return null;
99
+ }
100
+ }
101
+ async removeAllStorageFilesByUrl(obj) {
102
+ const urlObjects = this.findAllObjectsWithUrls(obj);
103
+ console.log(`Removing ${urlObjects.length} items from storage by URL`);
104
+ const promises = urlObjects
105
+ .map((obj) => {
106
+ const extracted = this.extractBucketAndPathFromUrl(obj.url);
107
+ if (extracted) {
108
+ console.log(`Deleting ${extracted.bucket}/${extracted.path}...`);
109
+ return this.deleteStorageFile(extracted.bucket, extracted.path);
110
+ }
111
+ else {
112
+ console.log(`❌ Check URL format posible bug: Failed to extract bucket and path from URL: ${obj.url}`);
113
+ }
114
+ return null;
115
+ })
116
+ .filter((p) => p !== null);
117
+ try {
118
+ return await Promise.all(promises);
119
+ }
120
+ catch (error) {
121
+ console.error('Error removing items from storage by URL: ', error);
122
+ return null;
123
+ }
124
+ }
125
+ extractBucketAndPathFromUrl(url) {
126
+ if (!url)
127
+ return null;
128
+ let match = url.match(FIREBASE_STORAGE_URL_REGEX);
129
+ if (match && match[1] && match[2]) {
130
+ try {
131
+ const bucket = match[1];
132
+ const path = decodeURIComponent(match[2]);
133
+ return { bucket, path };
134
+ }
135
+ catch (e) {
136
+ console.error(`Failed to decode URI component for path: '${match[2]}'`, e);
137
+ return { bucket: match[1], path: match[2] };
138
+ }
139
+ }
140
+ match = url.match(GOOGLE_STORAGE_URL_REGEX);
141
+ if (match && match[1] && match[2]) {
142
+ const bucket = match[1];
143
+ const path = match[2].split('?')[0];
144
+ return { bucket, path };
145
+ }
146
+ return null;
147
+ }
148
+ findAllObjectsWithUrls(obj) {
149
+ if (!obj)
150
+ return [];
151
+ const objectsWithUrls = [];
152
+ const search = (current) => {
153
+ if (!current || typeof current !== 'object')
154
+ return;
155
+ if (current.url && typeof current.url === 'string') {
156
+ objectsWithUrls.push(current);
157
+ }
158
+ if (Array.isArray(current)) {
159
+ current.forEach((item) => search(item));
160
+ }
161
+ else {
162
+ Object.values(current).forEach((value) => search(value));
163
+ }
164
+ };
165
+ search(obj);
166
+ return objectsWithUrls;
167
+ }
168
+ findAllObjectsWithPaths(obj) {
169
+ if (!obj)
170
+ return [];
171
+ const objectsWithPaths = [];
172
+ const search = (current) => {
173
+ if (!current || typeof current !== 'object')
174
+ return;
175
+ if (current.path && typeof current.path === 'string') {
176
+ objectsWithPaths.push(current);
177
+ }
178
+ if (Array.isArray(current)) {
179
+ current.forEach((item) => search(item));
180
+ }
181
+ else {
182
+ Object.values(current).forEach((value) => search(value));
183
+ }
184
+ };
185
+ search(obj);
186
+ return objectsWithPaths;
187
+ }
188
+ extractPath(file) {
189
+ if (file && file?.url) {
190
+ const match = file.url.match(FIREBASE_STORAGE_URL_REGEX);
191
+ if (match && match[2]) {
192
+ try {
193
+ return decodeURIComponent(match[2]);
194
+ }
195
+ catch (e) {
196
+ console.error(`Failed to decode URI component for path: '${match[2]}'`, e);
197
+ return match[2];
198
+ }
199
+ }
200
+ return undefined;
201
+ }
202
+ else {
203
+ return undefined;
204
+ }
205
+ }
206
+ async getFile(bucketName, fileName) {
207
+ const file = this.storage.bucket(bucketName).file(fileName);
208
+ const [fileContent] = await file.download();
209
+ return fileContent;
210
+ }
211
+ async generateSignedUrl(bucketName, fileName, expiresInMinutes = 15) {
212
+ const options = {
213
+ version: 'v4',
214
+ action: 'read',
215
+ expires: Date.now() + expiresInMinutes * 60 * 1000,
216
+ };
217
+ const [url] = await this.storage.bucket(bucketName).file(fileName).getSignedUrl(options);
218
+ return url;
219
+ }
220
+ async listFiles(bucketName, prefix) {
221
+ const options = prefix ? { prefix } : undefined;
222
+ const [files] = await this.storage.bucket(bucketName).getFiles(options);
223
+ return files.map((file) => ({
224
+ name: file.name,
225
+ size: file.metadata.size,
226
+ contentType: file.metadata.contentType,
227
+ updated: file.metadata.updated,
228
+ timeCreated: file.metadata.timeCreated,
229
+ }));
230
+ }
231
+ async fileExists(bucketName, fileName) {
232
+ const file = this.storage.bucket(bucketName).file(fileName);
233
+ const [exists] = await file.exists();
234
+ return exists;
235
+ }
236
+ };
237
+ exports.CloudStorageService = CloudStorageService;
238
+ exports.CloudStorageService = CloudStorageService = __decorate([
239
+ (0, common_1.Injectable)(),
240
+ __metadata("design:paramtypes", [])
241
+ ], CloudStorageService);
242
+ //# sourceMappingURL=cloud-storage.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud-storage.service.js","sourceRoot":"","sources":["../../../../../libs/nest-storage/src/services/cloud-storage.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { CloudFileStorage } from '../models/cloud.model';
2
+ export declare class MinioStorageService {
3
+ private minioClient;
4
+ constructor();
5
+ uploadFile(bucketName: string, fileName: string, fileBuffer: Buffer, contentType?: string): Promise<Partial<CloudFileStorage>>;
6
+ getFile(bucketName: string, fileName: string): Promise<Buffer>;
7
+ generatePresignedUrl(bucketName: string, fileName: string, expires?: number): Promise<string>;
8
+ deleteFile(bucketName: string, fileName: string): Promise<void>;
9
+ }
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.MinioStorageService = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const Minio = require("minio");
15
+ let MinioStorageService = class MinioStorageService {
16
+ minioClient;
17
+ constructor() {
18
+ this.minioClient = new Minio.Client({
19
+ endPoint: '192.168.2.5',
20
+ port: 9010,
21
+ useSSL: false,
22
+ accessKey: 'AFMfm8K37rTAtSwG2jGJ',
23
+ secretKey: 'ssJW1Qw6sMPT3C7uAjgMDtcYuYIFL2wT9kqraGMU',
24
+ });
25
+ }
26
+ async uploadFile(bucketName, fileName, fileBuffer, contentType) {
27
+ const metaData = contentType ? { 'Content-Type': contentType } : {};
28
+ try {
29
+ const bucketExists = await this.minioClient.bucketExists(bucketName);
30
+ if (!bucketExists) {
31
+ await this.minioClient.makeBucket(bucketName);
32
+ console.log(`Bucket ${bucketName} created successfully.`);
33
+ }
34
+ await this.minioClient.putObject(bucketName, fileName, fileBuffer, fileBuffer.length, metaData);
35
+ const stat = await this.minioClient.statObject(bucketName, fileName);
36
+ console.log(`File ${fileName} uploaded successfully to bucket ${bucketName}. ETag: ${stat.etag}`);
37
+ const url = `http://192.168.2.5:9010/${bucketName}/${fileName}`;
38
+ return {
39
+ bucket: bucketName,
40
+ path: fileName,
41
+ url: url,
42
+ };
43
+ }
44
+ catch (err) {
45
+ console.error('Error uploading file to MinIO:', err);
46
+ throw err;
47
+ }
48
+ }
49
+ async getFile(bucketName, fileName) {
50
+ try {
51
+ const dataStream = await this.minioClient.getObject(bucketName, fileName);
52
+ const chunks = [];
53
+ return new Promise((resolve, reject) => {
54
+ dataStream.on('data', (chunk) => {
55
+ chunks.push(Buffer.from(chunk));
56
+ });
57
+ dataStream.on('error', (err) => {
58
+ reject(err);
59
+ });
60
+ dataStream.on('end', () => {
61
+ resolve(Buffer.concat(chunks));
62
+ });
63
+ });
64
+ }
65
+ catch (err) {
66
+ console.error('Error retrieving file from MinIO:', err);
67
+ throw err;
68
+ }
69
+ }
70
+ async generatePresignedUrl(bucketName, fileName, expires = 60 * 60 * 24 * 7) {
71
+ try {
72
+ const presignedUrl = await this.minioClient.presignedGetObject(bucketName, fileName, expires);
73
+ console.log(`Generated presigned URL for ${fileName}: ${presignedUrl}`);
74
+ return presignedUrl;
75
+ }
76
+ catch (err) {
77
+ console.error('Error generating presigned URL:', err);
78
+ throw err;
79
+ }
80
+ }
81
+ async deleteFile(bucketName, fileName) {
82
+ try {
83
+ await this.minioClient.removeObject(bucketName, fileName);
84
+ console.log(`File ${fileName} deleted successfully from bucket ${bucketName}.`);
85
+ }
86
+ catch (err) {
87
+ console.error('Error deleting file from MinIO:', err);
88
+ throw err;
89
+ }
90
+ }
91
+ };
92
+ exports.MinioStorageService = MinioStorageService;
93
+ exports.MinioStorageService = MinioStorageService = __decorate([
94
+ (0, common_1.Injectable)(),
95
+ __metadata("design:paramtypes", [])
96
+ ], MinioStorageService);
97
+ //# sourceMappingURL=minio-storage.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"minio-storage.service.js","sourceRoot":"","sources":["../../../../../libs/nest-storage/src/services/minio-storage.service.ts"],"names":[],"mappings":"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"}