diff --git a/src/app.module.ts b/src/app.module.ts index 7eefed9..b42ec50 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -15,6 +15,10 @@ import { EmdFeeTypeModule } from './tables/emd-fee-type/emd-fee-type.module'; import { TenderModule } from './transactions/tender/tender.module'; import { TenderDocModule } from './tables/tender-documents/tender-doc.module'; import { DocumentTypeModule } from './tables/document-type/document-type.module'; +import { CoversLovModule } from './tables/covers-lov/covers-lov.module'; +import { FileFormatLovModule } from './tables/file-format-lov/file-format-lov.module'; +import { CoversMasterModule } from './tables/covers-master/covers-master.module'; + @@ -35,8 +39,9 @@ import { DocumentTypeModule } from './tables/document-type/document-type.module' TenderModule, TenderDocModule, DocumentTypeModule, - - + CoversLovModule, + FileFormatLovModule, + CoversMasterModule ], }) export class AppModule { } diff --git a/src/dto/cover-type.dto.ts b/src/dto/cover-type.dto.ts new file mode 100644 index 0000000..97b5cf1 --- /dev/null +++ b/src/dto/cover-type.dto.ts @@ -0,0 +1,6 @@ +export class coverTypeDto{ + + id:number + + coverType:string +} \ No newline at end of file diff --git a/src/dto/document-type.dto.ts b/src/dto/document-type.dto.ts index edb4c90..7ae5fad 100644 --- a/src/dto/document-type.dto.ts +++ b/src/dto/document-type.dto.ts @@ -2,4 +2,6 @@ export class DocumentTypeDto{ id:number; documentType:string; + + docCategory:string } \ No newline at end of file diff --git a/src/dto/file-format-lov.dto.ts b/src/dto/file-format-lov.dto.ts new file mode 100644 index 0000000..7cc8ea4 --- /dev/null +++ b/src/dto/file-format-lov.dto.ts @@ -0,0 +1,5 @@ +export class FileFormatLovDto{ + id:number; + + fileFormat:string; +} \ No newline at end of file diff --git a/src/dto/tender-document.dto.ts b/src/dto/tender-document.dto.ts index 59c3cae..c62bb2f 100644 --- a/src/dto/tender-document.dto.ts +++ b/src/dto/tender-document.dto.ts @@ -1,14 +1,14 @@ export class TenderDocumentDto{ - tender_id:string; + tenderId:string; - doc_name:string; + docName:string; description:string; - doc_type:string; + docType:string; - doc_size:number; + documentSize:number; - doc_category:string + documentCategory:string; } \ No newline at end of file diff --git a/src/file-upload/file-upload.controller.ts b/src/file-upload/file-upload.controller.ts index fa7c609..59b1843 100644 --- a/src/file-upload/file-upload.controller.ts +++ b/src/file-upload/file-upload.controller.ts @@ -88,6 +88,37 @@ export class FileUploadController { } + @Post('drawings/:id') + @UseInterceptors(FileInterceptor('file', { + storage: diskStorage({ + // destination: './uploads/cars', + destination: (req, res, cb) => { + // console.log(req); + + const filePath: string = './uploads/Drawings/'+req.params.id; + createFolders(filePath); + return cb(null, filePath); + }, + filename: (req, file, cb) => { + console.log('===here===file upload=='); + const randomName = Array(32).fill(null).map(() => (Math.round(Math.random() * 16)).toString(16)).join(''); + return cb(null, `${randomName}${extname(file.originalname)}`); + } + }) + })) + drawings(@UploadedFile() file) { + if (!file) { + return { error: 'No file uploaded.' }; + } + //To return the size of the document in kb + const fileSizeKB = Math.ceil(file.size / 1024); + return { fileName: file.filename, filePath: file.path, fileSizeKB }; + } + + + + + @Get('Bank-Documents/:id/:imgpath') getBankDocuments( @Param('imgpath') image: string, @@ -132,9 +163,11 @@ export class FileUploadController { if (!fs.existsSync(folderPath)) { res.status(404).send({ error: 'File not found' }); return; - } - - const zipFileName = id + '.zip'; + } + + //Uncomment when we want tender id as the zip file name + //const zipFileName = id + '.zip'; + const zipFileName = 'tenderDocuments.zip'; const zipPath = path.join('./uploads/BankDocuments', zipFileName); // Create a new archive @@ -174,5 +207,63 @@ export class FileUploadController { }); -} + } + + + + @Get('Drawings-Arc/:id') + async getDrawingsAsZip( + @Param('id') id: string, + @Res() res, + @Req() req, + ) { + const folderPath = path.join('./uploads/Drawings', id); + if (!fs.existsSync(folderPath)) { + res.status(404).send({ error: 'File not found' }); + return; + } + + //Uncomment when we want tender id as the zip file name + //const zipFileName = id + '.zip'; + const zipFileName = 'Drawings.zip'; + const zipPath = path.join('./uploads/Drawings', zipFileName); + + // Create a new archive + const archive = archiver('zip', { + zlib: { level: 9 } // Set compression level (optional) + }); + + // Create a write stream to the zip file + const output = fs.createWriteStream(zipPath); + + // Pipe the archive to the write stream + archive.pipe(output); + + // Add the entire folder to the archive + archive.directory(folderPath, id); + + // Finalize the archive + await archive.finalize(); + + // Set the appropriate headers for downloading the zip file + res.attachment(zipFileName); + res.setHeader('Content-Type', 'application/zip'); + + // Stream the zip file to the response + const readStream = fs.createReadStream(zipPath); + readStream.pipe(res); + + // Remove the temporary zip file once it's streamed + readStream.on('end', () => { + fs.unlinkSync(zipPath); + }); + + // Handle any errors that occur during the archiving process + archive.on('error', function (err) { + console.log(err); + res.status(500).send({ error: 'Failed to create the zip file' }); + }); + + + } } \ No newline at end of file diff --git a/src/framework/beans/pcd-transaction.controller.ts b/src/framework/beans/pcd-transaction.controller.ts index b4f0b2d..54bf7e2 100644 --- a/src/framework/beans/pcd-transaction.controller.ts +++ b/src/framework/beans/pcd-transaction.controller.ts @@ -22,12 +22,14 @@ export class PcdTransactionController { return await this.service.findOne(filter, id); } - @UseGuards(AuthGuard()) + @Post() async createOne(@Body() body: T, ): Promise { return await this.service.createOne(body,); } + + @Delete('/:id') async delete(@Query() filter: FindManyOptions,@Param('id') id: string , ): Promise { return await this.service.deleteOne(filter,id, ); diff --git a/src/tables/covers-lov/covers-lov.controller.ts b/src/tables/covers-lov/covers-lov.controller.ts new file mode 100644 index 0000000..041d343 --- /dev/null +++ b/src/tables/covers-lov/covers-lov.controller.ts @@ -0,0 +1,15 @@ +import { Controller } from '@nestjs/common'; +import { coverTypeDto } from 'src/dto/cover-type.dto'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { CoversLovService } from './covers-lov.service'; + +@Controller('covers-lov') +export class CoversLovController extends PcdFormGridController{ + + constructor( + private coversLovService: CoversLovService + ) { + super(coversLovService); + } + +} diff --git a/src/tables/covers-lov/covers-lov.entity.ts b/src/tables/covers-lov/covers-lov.entity.ts new file mode 100644 index 0000000..d49241d --- /dev/null +++ b/src/tables/covers-lov/covers-lov.entity.ts @@ -0,0 +1,21 @@ +import { PcdBaseDto } from "src/framework/custom/pcd-dto.custom"; +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { Column, Entity, PrimaryGeneratedColumn } from "typeorm"; + +@Entity('covers-lov') +export class CoversLov extends PcdBaseEntity{ + + @PrimaryGeneratedColumn({ + name:"id" + }) + id:number + + @Column({ + name:"covertype", + type:"varchar", + length:500, + nullable:true + }) + coverType:string + +} diff --git a/src/tables/covers-lov/covers-lov.module.ts b/src/tables/covers-lov/covers-lov.module.ts new file mode 100644 index 0000000..69d1cbc --- /dev/null +++ b/src/tables/covers-lov/covers-lov.module.ts @@ -0,0 +1,15 @@ +import { Module } from '@nestjs/common'; +import { CoversLovController } from './covers-lov.controller'; +import { CoversLovService } from './covers-lov.service'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { AuthModule } from 'src/auth/auth.module'; +import { CoversLovRepository } from './covers-lov.repository'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([CoversLovRepository]), + ], + controllers: [CoversLovController], + providers: [CoversLovService] +}) +export class CoversLovModule {} diff --git a/src/tables/covers-lov/covers-lov.repository.ts b/src/tables/covers-lov/covers-lov.repository.ts new file mode 100644 index 0000000..e0c29e3 --- /dev/null +++ b/src/tables/covers-lov/covers-lov.repository.ts @@ -0,0 +1,7 @@ +import { EntityRepository, Repository } from "typeorm"; +import { CoversLov } from "./covers-lov.entity"; + +@EntityRepository(CoversLov) +export class CoversLovRepository extends Repository{ + +} \ No newline at end of file diff --git a/src/tables/covers-lov/covers-lov.service.ts b/src/tables/covers-lov/covers-lov.service.ts new file mode 100644 index 0000000..4d27518 --- /dev/null +++ b/src/tables/covers-lov/covers-lov.service.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@nestjs/common'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { CoversLov } from './covers-lov.entity'; +import { InjectRepository } from '@nestjs/typeorm'; +import { CoversLovRepository } from './covers-lov.repository'; + +@Injectable() +export class CoversLovService extends PcdFormGridService{ + + constructor( + @InjectRepository(CoversLovRepository) + private coversLovRepository: CoversLovRepository, + ) { + super(coversLovRepository); + } + +} diff --git a/src/tables/covers-master/covers-master.controller.ts b/src/tables/covers-master/covers-master.controller.ts new file mode 100644 index 0000000..147cb28 --- /dev/null +++ b/src/tables/covers-master/covers-master.controller.ts @@ -0,0 +1,4 @@ +import { Controller } from '@nestjs/common'; + +@Controller('covers-master') +export class CoversMasterController {} diff --git a/src/tables/imp-doc/imp-doc.entity.ts b/src/tables/covers-master/covers-master.entity.ts similarity index 73% rename from src/tables/imp-doc/imp-doc.entity.ts rename to src/tables/covers-master/covers-master.entity.ts index fef8931..debf310 100644 --- a/src/tables/imp-doc/imp-doc.entity.ts +++ b/src/tables/covers-master/covers-master.entity.ts @@ -2,8 +2,8 @@ import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; import { TenderMaster } from "src/tables/tender-master/tender-master.entity"; import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from "typeorm"; -@Entity('imp-doc') -export class ImportantDoc extends PcdBaseEntity{ +@Entity('cover-doc-master') +export class CoverDoc extends PcdBaseEntity{ @PrimaryColumn({ name:"id" @@ -17,26 +17,19 @@ export class ImportantDoc extends PcdBaseEntity{ }) tenderId:number @Column({ - name:"category", + name:"cover_type", type:"varchar", length:500, nullable:true }) - category:string + coverType:string @Column({ - name:"sub_category", + name:"desc", type:"varchar", length:500, nullable:true }) - subCategory:string - @Column({ - name:"sub_category_desc", - type:"varchar", - length:500, - nullable:true - }) - subCategoryDesc:string + Description:string @Column({ name:"file_format", @@ -46,7 +39,7 @@ export class ImportantDoc extends PcdBaseEntity{ }) fileFormat:string - @ManyToOne(() => TenderMaster,(tenderMaster)=> tenderMaster.importantDoc) + @ManyToOne(() => TenderMaster,(tenderMaster)=> tenderMaster.coverDoc) @JoinColumn([{ name: "tender_id", referencedColumnName: "id" }]) tenderIdD:TenderMaster diff --git a/src/tables/covers-master/covers-master.module.ts b/src/tables/covers-master/covers-master.module.ts new file mode 100644 index 0000000..e765426 --- /dev/null +++ b/src/tables/covers-master/covers-master.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { CoversMasterService } from './covers-master.service'; +import { CoversMasterController } from './covers-master.controller'; + +@Module({ + providers: [CoversMasterService], + controllers: [CoversMasterController] +}) +export class CoversMasterModule {} diff --git a/src/tables/covers-master/covers-master.repository.ts b/src/tables/covers-master/covers-master.repository.ts new file mode 100644 index 0000000..a1700c2 --- /dev/null +++ b/src/tables/covers-master/covers-master.repository.ts @@ -0,0 +1,7 @@ +import { EntityRepository, Repository } from "typeorm"; +import { CoverDoc } from "./covers-master.entity"; + +@EntityRepository(CoverDoc) +export class importantDocRepository extends Repository{ + +} \ No newline at end of file diff --git a/src/tables/covers-master/covers-master.service.ts b/src/tables/covers-master/covers-master.service.ts new file mode 100644 index 0000000..0b55e99 --- /dev/null +++ b/src/tables/covers-master/covers-master.service.ts @@ -0,0 +1,4 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class CoversMasterService {} diff --git a/src/tables/document-type/document-type.entity.ts b/src/tables/document-type/document-type.entity.ts index 11f0715..502bc63 100644 --- a/src/tables/document-type/document-type.entity.ts +++ b/src/tables/document-type/document-type.entity.ts @@ -18,6 +18,14 @@ export class DocumentType extends PcdBaseEntity{ documentType:string + @Column({ + name:"doc_category", + type:"varchar", + nullable:true + }) + docCategory:string + + @OneToMany(() => TenderDoc, (tenderDoc) => tenderDoc.documentTypeD ) tenderDoc:TenderDoc[] } \ No newline at end of file diff --git a/src/tables/file-format-lov/file-format-lov.controller.ts b/src/tables/file-format-lov/file-format-lov.controller.ts new file mode 100644 index 0000000..19dacaa --- /dev/null +++ b/src/tables/file-format-lov/file-format-lov.controller.ts @@ -0,0 +1,17 @@ +import { Controller } from '@nestjs/common'; +import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; +import { FileFormatRepository } from './file-format-lov.repository'; +import { FileFormatLovDto } from 'src/dto/file-format-lov.dto'; +import { FileFormatLovService } from './file-format-lov.service'; + +@Controller('file-format-lov') +export class FileFormatLovController extends PcdFormGridController{ + + constructor( + private fileFormatLovService: FileFormatLovService + ) { + super(fileFormatLovService); + } + +} + diff --git a/src/tables/file-format-lov/file-format-lov.entity.ts b/src/tables/file-format-lov/file-format-lov.entity.ts new file mode 100644 index 0000000..b1193af --- /dev/null +++ b/src/tables/file-format-lov/file-format-lov.entity.ts @@ -0,0 +1,18 @@ +import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; +import { Column, Entity, PrimaryGeneratedColumn } from "typeorm"; + +@Entity('file-format') +export class FileFormat extends PcdBaseEntity{ + @PrimaryGeneratedColumn({ + name:"id" + }) + id:number + + @Column({ + name:"file_format", + type:"varchar", + length:500, + nullable:true + }) + fileFormat:string +} \ No newline at end of file diff --git a/src/tables/file-format-lov/file-format-lov.module.ts b/src/tables/file-format-lov/file-format-lov.module.ts new file mode 100644 index 0000000..65ce7c1 --- /dev/null +++ b/src/tables/file-format-lov/file-format-lov.module.ts @@ -0,0 +1,16 @@ +import { Module } from '@nestjs/common'; +import { FileFormatLovService } from './file-format-lov.service'; +import { FileFormatLovController } from './file-format-lov.controller'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { FileFormatRepository } from './file-format-lov.repository'; +import { AuthModule } from 'src/auth/auth.module'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([FileFormatRepository]), + + ], + providers: [FileFormatLovService], + controllers: [FileFormatLovController] +}) +export class FileFormatLovModule {} diff --git a/src/tables/file-format-lov/file-format-lov.repository.ts b/src/tables/file-format-lov/file-format-lov.repository.ts new file mode 100644 index 0000000..d7f91e5 --- /dev/null +++ b/src/tables/file-format-lov/file-format-lov.repository.ts @@ -0,0 +1,7 @@ +import { EntityRepository, Repository } from "typeorm"; +import { FileFormat } from "./file-format-lov.entity"; + +@EntityRepository(FileFormat) +export class FileFormatRepository extends Repository{ + +} \ No newline at end of file diff --git a/src/tables/file-format-lov/file-format-lov.service.ts b/src/tables/file-format-lov/file-format-lov.service.ts new file mode 100644 index 0000000..9c5c01e --- /dev/null +++ b/src/tables/file-format-lov/file-format-lov.service.ts @@ -0,0 +1,18 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { FileFormatLovDto } from 'src/dto/file-format-lov.dto'; +import { PcdFormGridService } from 'src/framework/beans/pcd-form-grid.service'; +import { FileFormatRepository } from './file-format-lov.repository'; + +@Injectable() +export class FileFormatLovService extends PcdFormGridService{ + + constructor( + @InjectRepository(FileFormatRepository) + private fileFormatRepository: FileFormatRepository, + ) { + super(fileFormatRepository); + } + +} + diff --git a/src/tables/imp-doc/imp-doc.repository.ts b/src/tables/imp-doc/imp-doc.repository.ts deleted file mode 100644 index 61795c9..0000000 --- a/src/tables/imp-doc/imp-doc.repository.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { EntityRepository, Repository } from "typeorm"; -import { ImportantDoc } from "./imp-doc.entity"; - -@EntityRepository(ImportantDoc) -export class importantDocRepository extends Repository{ - -} \ No newline at end of file diff --git a/src/tables/payment-instrument/payment-ins.entity.ts b/src/tables/payment-instrument/payment-ins.entity.ts index d1975e1..ff754cd 100644 --- a/src/tables/payment-instrument/payment-ins.entity.ts +++ b/src/tables/payment-instrument/payment-ins.entity.ts @@ -23,7 +23,7 @@ export class paymentInstrument extends PcdBaseEntity{ }) tenderId:number - @ManyToOne(() => TenderMaster,(tenderMaster)=> tenderMaster.importantDoc) + @ManyToOne(() => TenderMaster,(tenderMaster)=> tenderMaster.coverDoc) @JoinColumn([{ name: "tender_id", referencedColumnName: "id" }]) tenderIdD:TenderMaster diff --git a/src/tables/tender-documents/tender-doc.controller.ts b/src/tables/tender-documents/tender-doc.controller.ts index 6ec22ec..9fedfee 100644 --- a/src/tables/tender-documents/tender-doc.controller.ts +++ b/src/tables/tender-documents/tender-doc.controller.ts @@ -4,7 +4,7 @@ import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.control import { TenderDocService } from './tender-doc.service'; import { AuthGuard } from '@nestjs/passport'; -@UseGuards(AuthGuard()) + @Controller('tender-doc') export class TenderDocController extends PcdFormGridController{ diff --git a/src/tables/tender-documents/tender-doc.entity.ts b/src/tables/tender-documents/tender-doc.entity.ts index 679a862..d9532a9 100644 --- a/src/tables/tender-documents/tender-doc.entity.ts +++ b/src/tables/tender-documents/tender-doc.entity.ts @@ -44,11 +44,11 @@ export class TenderDoc extends PcdBaseEntity{ documentSize:number; @Column({ - name:"tender_category", + name:"doc_category", type:"varchar", nullable:true }) -tenderCategory:string +docCategory:string @ManyToOne(() => TenderMaster,(tenderMaster)=> tenderMaster.TenderDoc) @JoinColumn([{ name: "tender_id", referencedColumnName: "id" }]) diff --git a/src/tables/tender-documents/tender-doc.module.ts b/src/tables/tender-documents/tender-doc.module.ts index 130933c..3213f83 100644 --- a/src/tables/tender-documents/tender-doc.module.ts +++ b/src/tables/tender-documents/tender-doc.module.ts @@ -8,7 +8,6 @@ import { AuthModule } from 'src/auth/auth.module'; @Module({ imports: [ TypeOrmModule.forFeature([tenderDocRepository]), - AuthModule ], providers: [TenderDocService], controllers: [TenderDocController] diff --git a/src/tables/tender-master/tender-details.controller.ts b/src/tables/tender-master/tender-details.controller.ts index d4c3e83..85524de 100644 --- a/src/tables/tender-master/tender-details.controller.ts +++ b/src/tables/tender-master/tender-details.controller.ts @@ -1,9 +1,9 @@ import { Controller,Get, Param,UseGuards} from '@nestjs/common'; import { TenderDetailsService } from './tender-details.service'; import { PcdFormGridController } from 'src/framework/beans/pcd-form-grid.controller'; -import { TenderMaster } from './tender-master.entity'; + import { TenderDetailDto } from 'src/dto/tender-master.dto'; -import { AuthGuard } from '@nestjs/passport'; + @Controller('tender-details') diff --git a/src/tables/tender-master/tender-master.entity.ts b/src/tables/tender-master/tender-master.entity.ts index 6d3985b..67a8d4a 100644 --- a/src/tables/tender-master/tender-master.entity.ts +++ b/src/tables/tender-master/tender-master.entity.ts @@ -1,5 +1,4 @@ import { PcdBaseEntity } from "src/framework/custom/pcd-entity.custom"; -import { ImportantDoc } from "src/tables/imp-doc/imp-doc.entity"; import { paymentInstrument } from "src/tables/payment-instrument/payment-ins.entity"; import { EmdFeeType } from "src/tables/emd-fee-type/emd-fee-type.entity"; import { FormOfContract } from "src/tables/form-of-contract/form-of-contract.entity"; @@ -9,6 +8,7 @@ import { TenderCategory } from "src/tables/tender-category/tender-category.entit import { TenderType } from "src/tables/tender-type/tender-type.entity"; import { TenderDoc } from "src/tables/tender-documents/tender-doc.entity"; import { Column, Entity, JoinColumn, ManyToOne, OneToMany, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm"; +import { CoverDoc } from "../covers-master/covers-master.entity"; @Entity('tender_master') export class TenderMaster extends PcdBaseEntity{ @@ -358,8 +358,8 @@ export class TenderMaster extends PcdBaseEntity{ activeYn:string - @OneToMany(() => ImportantDoc, (importantDoc) => importantDoc.tenderIdD ) - importantDoc:ImportantDoc[] + @OneToMany(() => CoverDoc, (coverDoc) => coverDoc.tenderIdD ) + coverDoc:CoverDoc[] @OneToMany(() => paymentInstrument, (paymentInstrument) => paymentInstrument.tenderIdD ) paymentInstrument:paymentInstrument[] diff --git a/src/transactions/tender/tender.controller.ts b/src/transactions/tender/tender.controller.ts index e569981..7e9360a 100644 --- a/src/transactions/tender/tender.controller.ts +++ b/src/transactions/tender/tender.controller.ts @@ -4,7 +4,7 @@ import { PcdTransactionController } from 'src/framework/beans/pcd-transaction.co import { TenderService } from './tender.service'; import { AuthGuard } from '@nestjs/passport'; -@UseGuards(AuthGuard()) + @Controller('tender') export class TenderController extends PcdTransactionController { constructor( diff --git a/src/transactions/tender/tender.module.ts b/src/transactions/tender/tender.module.ts index 06dbaf7..67cbe08 100644 --- a/src/transactions/tender/tender.module.ts +++ b/src/transactions/tender/tender.module.ts @@ -8,7 +8,6 @@ import { AuthModule } from 'src/auth/auth.module'; @Module({ imports: [ TypeOrmModule.forFeature([TenderMasterRepository]), - AuthModule ], controllers: [TenderController], providers: [TenderService]