From df3020012d1915b7f632cb30ec4149644265cde5 Mon Sep 17 00:00:00 2001 From: admin Date: Sun, 29 Mar 2026 21:02:40 +0700 Subject: [PATCH] 690329:2102 Fixing refactor Correspondence GPT-5.3-Codex #03 --- ...119442391-1908b04cd11e739233ee8977de00dc57 | Bin 71015 -> 71085 bytes ...rvicespec_1aae7357448442e3b9dacb210cb1a80b | 561 +++++++++++ ...espec_1aae7357448442e3b9dacb210cb1a80b.map | 1 + ...ceservice_515ab3b98834c28ddef79ca635837252 | 893 ++++++++++++++++++ ...rvice_515ab3b98834c28ddef79ca635837252.map | 1 + ...rvicespec_6f5b0f75b3fc4347fc2d2eb89f0249fa | 561 +++++++++++ ...espec_6f5b0f75b3fc4347fc2d2eb89f0249fa.map | 1 + ...rvicespec_f7c1f1e06b95bcf8310dffb265941ee4 | 561 +++++++++++ ...espec_f7c1f1e06b95bcf8310dffb265941ee4.map | 1 + ...cac696b99-da39a3ee5e6b4b0d3255bfef95601890 | 2 +- .../correspondence.service.spec.ts | 6 +- 11 files changed, 2584 insertions(+), 4 deletions(-) create mode 100644 backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/1a/correspondenceservicespec_1aae7357448442e3b9dacb210cb1a80b create mode 100644 backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/1a/correspondenceservicespec_1aae7357448442e3b9dacb210cb1a80b.map create mode 100644 backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/51/correspondenceservice_515ab3b98834c28ddef79ca635837252 create mode 100644 backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/51/correspondenceservice_515ab3b98834c28ddef79ca635837252.map create mode 100644 backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/6f/correspondenceservicespec_6f5b0f75b3fc4347fc2d2eb89f0249fa create mode 100644 backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/6f/correspondenceservicespec_6f5b0f75b3fc4347fc2d2eb89f0249fa.map create mode 100644 backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/f7/correspondenceservicespec_f7c1f1e06b95bcf8310dffb265941ee4 create mode 100644 backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/f7/correspondenceservicespec_f7c1f1e06b95bcf8310dffb265941ee4.map diff --git a/backend/src/.jest-cache/haste-map-60cab15b743c6776f41d29bcac696b99-0ca4a1d6e3dfec1d63b61b0119442391-1908b04cd11e739233ee8977de00dc57 b/backend/src/.jest-cache/haste-map-60cab15b743c6776f41d29bcac696b99-0ca4a1d6e3dfec1d63b61b0119442391-1908b04cd11e739233ee8977de00dc57 index cf5c0f131d48e7bb3b5139715fea3cfed677fe2a..ec1cc2d09af66b899634801dc44fe00c89e35901 100644 GIT binary patch delta 1073 zcmX|;eN5DK9LM?m?z-c54{#40cW`%bAcIsCh$ZyEK-7&>7uY&uSv<^;M47OjCKdJ| z!qUmrTlb?7A4;mlSmeh%1-US!*%ovJIW}a%YDIww^k58%?hyI!`~K|pe(&@Bynp#r z-r6E>ld1V*O(L;OeU^AYJ4E;+bQ@Yib8uOok7`2+!VG07GZx@SLoKcuzd@;9&n}&T z@RD_xU${8a^t6B%ERkplJI0OXVHsYun|RuKkT7O5K^N8N9~?qUR1L);CEAWXj;)*= zZ723P&JtQthQ(#QAaPGtN0`^&z$jeB< zx09-HM^8f2U3O?dzQp?cY@`{w6g&GeY%=s7Qlc=`!s7ZUBagc50*>4;AT(dWnNOS{ zioux6%%=Rh^ux?Mh6wkr$xaByVqU4Fj9D&xLSaPuUc$aL^ z-?i-j={PNI)GH78x$V7mLg1^?b&*1N{mHk8w|r<4`0A-z85cEswb*kzoCJ?Bc}pRv9WU?&K8DD&oP5NrY!QYZtV3 z?Wnt4NGaHsVMcA|yNjf(b1!_}2cSz0!Ec{yvCBKnd0i_BPkuRzjXg1#yBdn*bS;K- zTJFB`GEoNly-9F8)o3^uf)##bI?IB#ugvhKDY>G%jIjSo443rO1#^C1gMe#&Hi&(> zIM{2$%|Ve({W*m0!4GIXrhRc3A2c9(Z7`qsK0)A;AKq5t(y$3fMxMoiaS>aGHIR=y z&r>6|5PxqXPE5XuQJ08{Uo~(~h*&kbo7SPLC@i4((OaPczPMeAwA*F4?mt=Ul*kWG z?Ip-(4kNYPi1X8V_O5{rMyT zhZj_uqU9PtNyM3jOg1b;C?&l}<$)!oqe@yCUaW8i#RfTr$AV5T)4q7AT18n>jglgy z$Y8qT4=$F%JXs3bMAAkT86>wzUrRm}ZI`?Oxm`uidE(WSL=-12s3~09siiUu#_0p~ zNc9@(MExaED$tP8)2k(`AZ^gm1=P=o*xjs?NJrWJii(>p9)q3=19kb|(tSp%k}3`K Piu9+RB0LR7`i}kwxpuNF delta 1055 zcmYk4e@xVM7{__Ocir*rfcr^zaK8{N#{$98EF}tR4$p$rl$eM{7f5if5Nfs3{6o^g zD%v~!v}r%sXf_#!J>r2tfJ7T}!4+jR2E**v76Ous8O-Z@+`0Mr>+}40?fw2d&!??b z{pT5VyGq9yF)hR@T^jLN>^NarzZtFiZJc0EA>_10$IWRFh}Rdt+}rQ5Y3Eb$z)WDfudD9!x^gDKqD! zXOJp$brjdEJ*TsUf%XpR#2p~_{ht+pAKz$IX_PiiawZJjRvgUIWBwtnb8TI1nCU+< zbNmj|fAZImNC4Z4!y?l;E>%bbfx$#}=DEyVT+~IJy~8QNT`zNDv3Mk+-L&N{v$NA7 z?UANy>J^K(#Whu=t^e+}u1le|+b6e5VT&oK5%=-v@pTgK{Nw}TrRJk5{^Qel3B6r1 zH-6p`n;J14o{VSKpxD)WePy+^>93XfUV5>t?&Sk3uiXGW+i=hMov7p2dDnTnif8>6 z!sK-smHt;)>dGKWS4LvT@I@~QFYblD`z`eKI@Y>rku6;H7o|4k{O@pl=vZoN|3j?)9H z5F9e#?7K1i<&ZBL9H_>>R~$$fP2jB~UJ2PZWn_M5M$@>=Pkz6dC=Yp;?V%9uKbR2w zFq(a1Yb4}ec0`f~89y~>abofq3Z{+7n9^axWGTC*9C66rA!B6b5H`*<(t4bG!GdRI zWUjidmvD2g2<3BcLOo}|#JtSjc^@HvzZroAHEI@~#^{Yktp3N!KQ8Rjpz~HWEVmkz zp~#%}UmL-*yayFa@%Uw_1iBuX+n4htQ+PAahxhCGBF!V=YH-!c?`aNNxFBfL(!-#S zEdIBnX%iuiWig?l)Cl-l1PnZ&fJvQMAy5P~WEZtsS`_6P+AkXJC6l-!)3-vcqsmZN z>G$a*5tq;{5VxO7zgwpU2ndvY3A3RBsn*aa+ diff --git a/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/1a/correspondenceservicespec_1aae7357448442e3b9dacb210cb1a80b b/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/1a/correspondenceservicespec_1aae7357448442e3b9dacb210cb1a80b new file mode 100644 index 0000000..6acc9b7 --- /dev/null +++ b/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/1a/correspondenceservicespec_1aae7357448442e3b9dacb210cb1a80b @@ -0,0 +1,561 @@ +5e93064e47ed99149ccafc22180a99ec +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const testing_1 = require("@nestjs/testing"); +const typeorm_1 = require("@nestjs/typeorm"); +const typeorm_2 = require("typeorm"); +const correspondence_service_1 = require("./correspondence.service"); +const correspondence_entity_1 = require("./entities/correspondence.entity"); +const correspondence_revision_entity_1 = require("./entities/correspondence-revision.entity"); +const correspondence_type_entity_1 = require("./entities/correspondence-type.entity"); +const correspondence_status_entity_1 = require("./entities/correspondence-status.entity"); +const correspondence_reference_entity_1 = require("./entities/correspondence-reference.entity"); +const correspondence_tag_entity_1 = require("./entities/correspondence-tag.entity"); +const organization_entity_1 = require("../organization/entities/organization.entity"); +const correspondence_recipient_entity_1 = require("./entities/correspondence-recipient.entity"); +const document_numbering_service_1 = require("../document-numbering/services/document-numbering.service"); +const json_schema_service_1 = require("../json-schema/json-schema.service"); +const workflow_engine_service_1 = require("../workflow-engine/workflow-engine.service"); +const user_service_1 = require("../user/user.service"); +const search_service_1 = require("../search/search.service"); +const file_storage_service_1 = require("../../common/file-storage/file-storage.service"); +const uuid_resolver_service_1 = require("../../common/services/uuid-resolver.service"); +const notification_service_1 = require("../notification/notification.service"); +describe('CorrespondenceService', () => { + let service; + let numberingService; + let correspondenceRepo; + let revisionRepo; + let testingModule; + let _dataSource; + const createMockRepository = () => ({ + find: jest.fn(), + findOne: jest.fn(), + create: jest.fn(), + save: jest.fn(), + update: jest.fn(), + delete: jest.fn(), + softDelete: jest.fn(), + createQueryBuilder: jest.fn(() => ({ + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + andWhere: jest.fn().mockReturnThis(), + orderBy: jest.fn().mockReturnThis(), + skip: jest.fn().mockReturnThis(), + take: jest.fn().mockReturnThis(), + getOne: jest.fn().mockResolvedValue(null), + getMany: jest.fn().mockResolvedValue([]), + getManyAndCount: jest.fn().mockResolvedValue([[], 0]), + })), + }); + const mockDataSource = { + createQueryRunner: jest.fn(() => ({ + connect: jest.fn(), + startTransaction: jest.fn(), + commitTransaction: jest.fn(), + rollbackTransaction: jest.fn(), + release: jest.fn(), + manager: { + create: jest.fn(), + save: jest.fn(), + findOne: jest.fn(), + }, + })), + getRepository: jest.fn(() => createMockRepository()), + manager: { + findOne: jest.fn(), + }, + }; + beforeEach(async () => { + testingModule = await testing_1.Test.createTestingModule({ + providers: [ + correspondence_service_1.CorrespondenceService, + { + provide: (0, typeorm_1.getRepositoryToken)(correspondence_entity_1.Correspondence), + useValue: createMockRepository(), + }, + { + provide: (0, typeorm_1.getRepositoryToken)(correspondence_revision_entity_1.CorrespondenceRevision), + useValue: createMockRepository(), + }, + { + provide: (0, typeorm_1.getRepositoryToken)(correspondence_type_entity_1.CorrespondenceType), + useValue: createMockRepository(), + }, + { + provide: (0, typeorm_1.getRepositoryToken)(correspondence_status_entity_1.CorrespondenceStatus), + useValue: createMockRepository(), + }, + { + provide: (0, typeorm_1.getRepositoryToken)(correspondence_reference_entity_1.CorrespondenceReference), + useValue: createMockRepository(), + }, + { + provide: (0, typeorm_1.getRepositoryToken)(correspondence_tag_entity_1.CorrespondenceTag), + useValue: createMockRepository(), + }, + { + provide: (0, typeorm_1.getRepositoryToken)(organization_entity_1.Organization), + useValue: createMockRepository(), + }, + { + provide: (0, typeorm_1.getRepositoryToken)(correspondence_recipient_entity_1.CorrespondenceRecipient), + useValue: createMockRepository(), + }, + { + provide: document_numbering_service_1.DocumentNumberingService, + useValue: { + generateNextNumber: jest.fn(), + updateNumberForDraft: jest.fn(), + previewNextNumber: jest.fn(), + }, + }, + { + provide: json_schema_service_1.JsonSchemaService, + useValue: { validate: jest.fn() }, + }, + { + provide: workflow_engine_service_1.WorkflowEngineService, + useValue: { createInstance: jest.fn() }, + }, + { + provide: user_service_1.UserService, + useValue: { + findOne: jest.fn(), + getUserPermissions: jest.fn().mockResolvedValue([]), + }, + }, + { + provide: typeorm_2.DataSource, + useValue: mockDataSource, + }, + { + provide: search_service_1.SearchService, + useValue: { indexDocument: jest.fn() }, + }, + { + provide: file_storage_service_1.FileStorageService, + useValue: { commit: jest.fn().mockResolvedValue([]) }, + }, + { + provide: uuid_resolver_service_1.UuidResolverService, + useValue: { + resolveProjectId: jest.fn().mockResolvedValue(1), + resolveOrganizationId: jest.fn().mockResolvedValue(1), + }, + }, + { + provide: notification_service_1.NotificationService, + useValue: { send: jest.fn().mockResolvedValue(undefined) }, + }, + ], + }).compile(); + service = testingModule.get(correspondence_service_1.CorrespondenceService); + numberingService = testingModule.get(document_numbering_service_1.DocumentNumberingService); + correspondenceRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_entity_1.Correspondence)); + revisionRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_revision_entity_1.CorrespondenceRevision)); + _dataSource = testingModule.get(typeorm_2.DataSource); + }); + it('should be defined', () => { + expect(service).toBeDefined(); + }); + describe('update', () => { + it('should NOT regenerate number if critical fields unchanged', async () => { + const mockUser = { id: 1, primaryOrganizationId: 10 }; + const mockRevision = { + id: 100, + correspondenceId: 1, + isCurrent: true, + statusId: 5, + }; + jest + .spyOn(revisionRepo, 'findOne') + .mockResolvedValue(mockRevision); + const mockCorr = { + id: 1, + projectId: 1, + correspondenceTypeId: 2, + disciplineId: 3, + originatorId: 10, + correspondenceNumber: 'OLD-NUM', + recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }], + }; + jest + .spyOn(correspondenceRepo, 'findOne') + .mockResolvedValue(mockCorr); + const updateDto = { + projectId: 1, + disciplineId: 3, + }; + await service.update(1, updateDto, mockUser); + expect(numberingService.updateNumberForDraft).not.toHaveBeenCalled(); + }); + it('should regenerate number if Project ID changes', async () => { + const mockUser = { id: 1, primaryOrganizationId: 10 }; + const mockRevision = { + id: 100, + correspondenceId: 1, + isCurrent: true, + statusId: 5, + }; + jest + .spyOn(revisionRepo, 'findOne') + .mockResolvedValue(mockRevision); + const mockCorr = { + id: 1, + projectId: 1, + correspondenceTypeId: 2, + disciplineId: 3, + originatorId: 10, + correspondenceNumber: 'OLD-NUM', + recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }], + }; + jest + .spyOn(correspondenceRepo, 'findOne') + .mockResolvedValue(mockCorr); + const updateDto = { + projectId: 2, + }; + const uuidResolver = testingModule.get(uuid_resolver_service_1.UuidResolverService); + uuidResolver.resolveProjectId.mockResolvedValue(2); + await service.update(1, updateDto, mockUser); + expect(numberingService.updateNumberForDraft).toHaveBeenCalled(); + }); + it('should regenerate number if Document Type changes', async () => { + const mockUser = { id: 1, primaryOrganizationId: 10 }; + const mockRevision = { + id: 100, + correspondenceId: 1, + isCurrent: true, + statusId: 5, + }; + jest + .spyOn(revisionRepo, 'findOne') + .mockResolvedValue(mockRevision); + const mockCorr = { + id: 1, + projectId: 1, + correspondenceTypeId: 2, + disciplineId: 3, + originatorId: 10, + correspondenceNumber: 'OLD-NUM', + recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }], + }; + jest + .spyOn(correspondenceRepo, 'findOne') + .mockResolvedValue(mockCorr); + const updateDto = { + typeId: 999, + }; + const typeRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_type_entity_1.CorrespondenceType)); + typeRepo.findOne.mockResolvedValue({ + id: 999, + typeCode: 'NEW-TYPE', + }); + await service.update(1, updateDto, mockUser); + expect(numberingService.updateNumberForDraft).toHaveBeenCalled(); + }); + it('should regenerate number if Recipient Organization changes', async () => { + const mockUser = { id: 1, primaryOrganizationId: 10 }; + const mockRevision = { + id: 100, + correspondenceId: 1, + isCurrent: true, + statusId: 5, + }; + jest + .spyOn(revisionRepo, 'findOne') + .mockResolvedValue(mockRevision); + const mockCorr = { + id: 1, + projectId: 1, + correspondenceTypeId: 2, + disciplineId: 3, + originatorId: 10, + correspondenceNumber: 'OLD-NUM', + recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }], + }; + jest + .spyOn(correspondenceRepo, 'findOne') + .mockResolvedValue(mockCorr); + // Access DataSource manager for mocking + mockDataSource.manager.findOne.mockResolvedValue({ + id: 88, + organizationCode: 'NEW-ORG', + }); + const updateDto = { + recipients: [{ type: 'TO', organizationId: 88 }], + }; + await service.update(1, updateDto, mockUser); + expect(numberingService.updateNumberForDraft).toHaveBeenCalled(); + }); + }); + describe('create', () => { + it('should allow system.manage_all user without primaryOrganizationId when originatorId is provided', async () => { + const mockUser = { + user_id: 1, + primaryOrganizationId: null, + }; + const createDto = { + projectId: 'project-uuid', + typeId: 1, + subject: 'Test Subject', + originatorId: 'originator-uuid', + recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }], + }; + const userService = testingModule.get(user_service_1.UserService); + const typeRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_type_entity_1.CorrespondenceType)); + const statusRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_status_entity_1.CorrespondenceStatus)); + const uuidResolver = testingModule.get(uuid_resolver_service_1.UuidResolverService); + userService.findOne.mockResolvedValue({ + user_id: 1, + primaryOrganizationId: null, + }); + userService.getUserPermissions.mockResolvedValue([ + 'system.manage_all', + ]); + uuidResolver.resolveProjectId.mockResolvedValue(100); + uuidResolver.resolveOrganizationId.mockImplementation((value) => { + if (value === 'originator-uuid') + return 10; + if (value === 'recipient-uuid') + return 20; + return 0; + }); + typeRepo.findOne.mockResolvedValue({ + id: 1, + typeCode: 'LTR', + }); + statusRepo.findOne.mockResolvedValue({ + id: 1, + statusCode: 'DRAFT', + }); + numberingService.generateNextNumber.mockResolvedValue({ + number: 'DOC-001', + }); + mockDataSource.manager.findOne + .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' }) + .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' }); + const queryRunner = { + connect: jest.fn(), + startTransaction: jest.fn(), + commitTransaction: jest.fn(), + rollbackTransaction: jest.fn(), + release: jest.fn(), + manager: { + create: jest.fn((_entity, payload) => payload), + save: jest + .fn() + .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' }) + .mockResolvedValueOnce({ id: 1000 }) + .mockResolvedValueOnce([]), + findOne: jest.fn(), + }, + }; + mockDataSource.createQueryRunner.mockReturnValue(queryRunner); + await service.create(createDto, mockUser); + expect(queryRunner.manager.create).toHaveBeenCalledWith(correspondence_entity_1.Correspondence, expect.objectContaining({ originatorId: 10 })); + }); + it('should set revisionLabel to "A" for RFA type', async () => { + const mockUser = { + user_id: 1, + primaryOrganizationId: 10, + }; + const createDto = { + projectId: 'project-uuid', + typeId: 1, + subject: 'Test Subject', + recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }], + }; + const typeRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_type_entity_1.CorrespondenceType)); + const statusRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_status_entity_1.CorrespondenceStatus)); + const uuidResolver = testingModule.get(uuid_resolver_service_1.UuidResolverService); + uuidResolver.resolveProjectId.mockResolvedValue(100); + uuidResolver.resolveOrganizationId.mockResolvedValue(20); + typeRepo.findOne.mockResolvedValue({ + id: 1, + typeCode: 'RFA', + }); + statusRepo.findOne.mockResolvedValue({ + id: 1, + statusCode: 'DRAFT', + }); + numberingService.generateNextNumber.mockResolvedValue({ + number: 'DOC-001', + }); + mockDataSource.manager.findOne + .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' }) + .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' }); + const queryRunner = { + connect: jest.fn(), + startTransaction: jest.fn(), + commitTransaction: jest.fn(), + rollbackTransaction: jest.fn(), + release: jest.fn(), + manager: { + create: jest.fn((_entity, payload) => payload), + save: jest + .fn() + .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' }) + .mockResolvedValueOnce({ id: 1000 }) + .mockResolvedValueOnce([]), + findOne: jest.fn(), + }, + }; + mockDataSource.createQueryRunner.mockReturnValue(queryRunner); + await service.create(createDto, mockUser); + expect(queryRunner.manager.create).toHaveBeenCalledWith(correspondence_revision_entity_1.CorrespondenceRevision, expect.objectContaining({ revisionLabel: 'A' })); + }); + it('should set revisionLabel to "A" for RFI type', async () => { + const mockUser = { + user_id: 1, + primaryOrganizationId: 10, + }; + const createDto = { + projectId: 'project-uuid', + typeId: 1, + subject: 'Test Subject', + recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }], + }; + const typeRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_type_entity_1.CorrespondenceType)); + const statusRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_status_entity_1.CorrespondenceStatus)); + const uuidResolver = testingModule.get(uuid_resolver_service_1.UuidResolverService); + uuidResolver.resolveProjectId.mockResolvedValue(100); + uuidResolver.resolveOrganizationId.mockResolvedValue(20); + typeRepo.findOne.mockResolvedValue({ + id: 1, + typeCode: 'RFI', + }); + statusRepo.findOne.mockResolvedValue({ + id: 1, + statusCode: 'DRAFT', + }); + numberingService.generateNextNumber.mockResolvedValue({ + number: 'DOC-001', + }); + mockDataSource.manager.findOne + .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' }) + .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' }); + const queryRunner = { + connect: jest.fn(), + startTransaction: jest.fn(), + commitTransaction: jest.fn(), + rollbackTransaction: jest.fn(), + release: jest.fn(), + manager: { + create: jest.fn((_entity, payload) => payload), + save: jest + .fn() + .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' }) + .mockResolvedValueOnce({ id: 1000 }) + .mockResolvedValueOnce([]), + findOne: jest.fn(), + }, + }; + mockDataSource.createQueryRunner.mockReturnValue(queryRunner); + await service.create(createDto, mockUser); + expect(queryRunner.manager.create).toHaveBeenCalledWith(correspondence_revision_entity_1.CorrespondenceRevision, expect.objectContaining({ revisionLabel: 'A' })); + }); + it('should set revisionLabel to null for LETTER type', async () => { + const mockUser = { + user_id: 1, + primaryOrganizationId: 10, + }; + const createDto = { + projectId: 'project-uuid', + typeId: 1, + subject: 'Test Subject', + recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }], + }; + const typeRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_type_entity_1.CorrespondenceType)); + const statusRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_status_entity_1.CorrespondenceStatus)); + const uuidResolver = testingModule.get(uuid_resolver_service_1.UuidResolverService); + uuidResolver.resolveProjectId.mockResolvedValue(100); + uuidResolver.resolveOrganizationId.mockResolvedValue(20); + typeRepo.findOne.mockResolvedValue({ + id: 1, + typeCode: 'LETTER', + }); + statusRepo.findOne.mockResolvedValue({ + id: 1, + statusCode: 'DRAFT', + }); + numberingService.generateNextNumber.mockResolvedValue({ + number: 'DOC-001', + }); + mockDataSource.manager.findOne + .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' }) + .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' }); + const queryRunner = { + connect: jest.fn(), + startTransaction: jest.fn(), + commitTransaction: jest.fn(), + rollbackTransaction: jest.fn(), + release: jest.fn(), + manager: { + create: jest.fn((_entity, payload) => payload), + save: jest + .fn() + .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' }) + .mockResolvedValueOnce({ id: 1000 }) + .mockResolvedValueOnce([]), + findOne: jest.fn(), + }, + }; + mockDataSource.createQueryRunner.mockReturnValue(queryRunner); + await service.create(createDto, mockUser); + expect(queryRunner.manager.create).toHaveBeenCalledWith(correspondence_revision_entity_1.CorrespondenceRevision, expect.objectContaining({ revisionLabel: undefined })); + }); + it('should set revisionLabel to null for MEMO type', async () => { + const mockUser = { + user_id: 1, + primaryOrganizationId: 10, + }; + const createDto = { + projectId: 'project-uuid', + typeId: 1, + subject: 'Test Subject', + recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }], + }; + const typeRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_type_entity_1.CorrespondenceType)); + const statusRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_status_entity_1.CorrespondenceStatus)); + const uuidResolver = testingModule.get(uuid_resolver_service_1.UuidResolverService); + uuidResolver.resolveProjectId.mockResolvedValue(100); + uuidResolver.resolveOrganizationId.mockResolvedValue(20); + typeRepo.findOne.mockResolvedValue({ + id: 1, + typeCode: 'MEMO', + }); + statusRepo.findOne.mockResolvedValue({ + id: 1, + statusCode: 'DRAFT', + }); + numberingService.generateNextNumber.mockResolvedValue({ + number: 'DOC-001', + }); + mockDataSource.manager.findOne + .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' }) + .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' }); + const queryRunner = { + connect: jest.fn(), + startTransaction: jest.fn(), + commitTransaction: jest.fn(), + rollbackTransaction: jest.fn(), + release: jest.fn(), + manager: { + create: jest.fn((_entity, payload) => payload), + save: jest + .fn() + .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' }) + .mockResolvedValueOnce({ id: 1000 }) + .mockResolvedValueOnce([]), + findOne: jest.fn(), + }, + }; + mockDataSource.createQueryRunner.mockReturnValue(queryRunner); + await service.create(createDto, mockUser); + expect(queryRunner.manager.create).toHaveBeenCalledWith(correspondence_revision_entity_1.CorrespondenceRevision, expect.objectContaining({ revisionLabel: null })); + }); + }); +}); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJmaWxlIjoiRTpcXG5wLWRtc1xcbGNicDNcXGJhY2tlbmRcXHNyY1xcbW9kdWxlc1xcY29ycmVzcG9uZGVuY2VcXGNvcnJlc3BvbmRlbmNlLnNlcnZpY2Uuc3BlYy50cyIsIm1hcHBpbmdzIjoiOztBQUFBLDZDQUFzRDtBQUN0RCw2Q0FBcUQ7QUFDckQscUNBQWlEO0FBQ2pELHFFQUFpRTtBQUNqRSw0RUFBa0U7QUFDbEUsOEZBQW1GO0FBQ25GLHNGQUEyRTtBQUMzRSwwRkFBK0U7QUFDL0UsZ0dBQXFGO0FBQ3JGLG9GQUF5RTtBQUN6RSxzRkFBNEU7QUFDNUUsZ0dBQXFGO0FBQ3JGLDBHQUFxRztBQUNyRyw0RUFBdUU7QUFDdkUsd0ZBQW1GO0FBQ25GLHVEQUFtRDtBQUNuRCw2REFBeUQ7QUFDekQseUZBQW9GO0FBQ3BGLHVGQUFrRjtBQUNsRiwrRUFBMkU7QUFLM0UsUUFBUSxDQUFDLHVCQUF1QixFQUFFLEdBQUcsRUFBRTtJQUNyQyxJQUFJLE9BQThCLENBQUM7SUFDbkMsSUFBSSxnQkFBMEMsQ0FBQztJQUMvQyxJQUFJLGtCQUE4QyxDQUFDO0lBQ25ELElBQUksWUFBZ0QsQ0FBQztJQUNyRCxJQUFJLGFBQTRCLENBQUM7SUFDakMsSUFBSSxXQUF1QixDQUFDO0lBRTVCLE1BQU0sb0JBQW9CLEdBQUcsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUNsQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRTtRQUNmLE9BQU8sRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFFO1FBQ2xCLE1BQU0sRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFFO1FBQ2pCLElBQUksRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFFO1FBQ2YsTUFBTSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUU7UUFDakIsTUFBTSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUU7UUFDakIsVUFBVSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUU7UUFDckIsa0JBQWtCLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQ2pD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QUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxvQkFBb0IsQ0FDckQsdURBQXNCLEVBQ3RCLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUNqRCxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIkU6XFxucC1kbXNcXGxjYnAzXFxiYWNrZW5kXFxzcmNcXG1vZHVsZXNcXGNvcnJlc3BvbmRlbmNlXFxjb3JyZXNwb25kZW5jZS5zZXJ2aWNlLnNwZWMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVGVzdCwgVGVzdGluZ01vZHVsZSB9IGZyb20gJ0BuZXN0anMvdGVzdGluZyc7XHJcbmltcG9ydCB7IGdldFJlcG9zaXRvcnlUb2tlbiB9IGZyb20gJ0BuZXN0anMvdHlwZW9ybSc7XHJcbmltcG9ydCB7IERhdGFTb3VyY2UsIFJlcG9zaXRvcnkgfSBmcm9tICd0eXBlb3JtJztcclxuaW1wb3J0IHsgQ29ycmVzcG9uZGVuY2VTZXJ2aWNlIH0gZnJvbSAnLi9jb3JyZXNwb25kZW5jZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgQ29ycmVzcG9uZGVuY2UgfSBmcm9tICcuL2VudGl0aWVzL2NvcnJlc3BvbmRlbmNlLmVudGl0eSc7XHJcbmltcG9ydCB7IENvcnJlc3BvbmRlbmNlUmV2aXNpb24gfSBmcm9tICcuL2VudGl0aWVzL2NvcnJlc3BvbmRlbmNlLXJldmlzaW9uLmVudGl0eSc7XHJcbmltcG9ydCB7IENvcnJlc3BvbmRlbmNlVHlwZSB9IGZyb20gJy4vZW50aXRpZXMvY29ycmVzcG9uZGVuY2UtdHlwZS5lbnRpdHknO1xyXG5pbXBvcnQgeyBDb3JyZXNwb25kZW5jZVN0YXR1cyB9IGZyb20gJy4vZW50aXRpZXMvY29ycmVzcG9uZGVuY2Utc3RhdHVzLmVudGl0eSc7XHJcbmltcG9ydCB7IENvcnJlc3BvbmRlbmNlUmVmZXJlbmNlIH0gZnJvbSAnLi9lbnRpdGllcy9jb3JyZXNwb25kZW5jZS1yZWZlcmVuY2UuZW50aXR5JztcclxuaW1wb3J0IHsgQ29ycmVzcG9uZGVuY2VUYWcgfSBmcm9tICcuL2VudGl0aWVzL2NvcnJlc3BvbmRlbmNlLXRhZy5lbnRpdHknO1xyXG5pbXBvcnQgeyBPcmdhbml6YXRpb24gfSBmcm9tICcuLi9vcmdhbml6YXRpb24vZW50aXRpZXMvb3JnYW5pemF0aW9uLmVudGl0eSc7XHJcbmltcG9ydCB7IENvcnJlc3BvbmRlbmNlUmVjaXBpZW50IH0gZnJvbSAnLi9lbnRpdGllcy9jb3JyZXNwb25kZW5jZS1yZWNpcGllbnQuZW50aXR5JztcclxuaW1wb3J0IHsgRG9jdW1lbnROdW1iZXJpbmdTZXJ2aWNlIH0gZnJvbSAnLi4vZG9jdW1lbnQtbnVtYmVyaW5nL3NlcnZpY2VzL2RvY3VtZW50LW51bWJlcmluZy5zZXJ2aWNlJztcclxuaW1wb3J0IHsgSnNvblNjaGVtYVNlcnZpY2UgfSBmcm9tICcuLi9qc29uLXNjaGVtYS9qc29uLXNjaGVtYS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgV29ya2Zsb3dFbmdpbmVTZXJ2aWNlIH0gZnJvbSAnLi4vd29ya2Zsb3ctZW5naW5lL3dvcmtmbG93LWVuZ2luZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgVXNlclNlcnZpY2UgfSBmcm9tICcuLi91c2VyL3VzZXIuc2VydmljZSc7XHJcbmltcG9ydCB7IFNlYXJjaFNlcnZpY2UgfSBmcm9tICcuLi9zZWFyY2gvc2VhcmNoLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBGaWxlU3RvcmFnZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9jb21tb24vZmlsZS1zdG9yYWdlL2ZpbGUtc3RvcmFnZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgVXVpZFJlc29sdmVyU2VydmljZSB9IGZyb20gJy4uLy4uL2NvbW1vbi9zZXJ2aWNlcy91dWlkLXJlc29sdmVyLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBOb3RpZmljYXRpb25TZXJ2aWNlIH0gZnJvbSAnLi4vbm90aWZpY2F0aW9uL25vdGlmaWNhdGlvbi5zZXJ2aWNlJztcclxuaW1wb3J0IHsgVXBkYXRlQ29ycmVzcG9uZGVuY2VEdG8gfSBmcm9tICcuL2R0by91cGRhdGUtY29ycmVzcG9uZGVuY2UuZHRvJztcclxuaW1wb3J0IHsgQ3JlYXRlQ29ycmVzcG9uZGVuY2VEdG8gfSBmcm9tICcuL2R0by9jcmVhdGUtY29ycmVzcG9uZGVuY2UuZHRvJztcclxuaW1wb3J0IHsgVXNlciB9IGZyb20gJy4uL3VzZXIvZW50aXRpZXMvdXNlci5lbnRpdHknO1xyXG5cclxuZGVzY3JpYmUoJ0NvcnJlc3BvbmRlbmNlU2VydmljZScsICgpID0+IHtcclxuICBsZXQgc2VydmljZTogQ29ycmVzcG9uZGVuY2VTZXJ2aWNlO1xyXG4gIGxldCBudW1iZXJpbmdTZXJ2aWNlOiBEb2N1bWVudE51bWJlcmluZ1NlcnZpY2U7XHJcbiAgbGV0IGNvcnJlc3BvbmRlbmNlUmVwbzogUmVwb3NpdG9yeTxDb3JyZXNwb25kZW5jZT47XHJcbiAgbGV0IHJldmlzaW9uUmVwbzogUmVwb3NpdG9yeTxDb3JyZXNwb25kZW5jZVJldmlzaW9uPjtcclxuICBsZXQgdGVzdGluZ01vZHVsZTogVGVzdGluZ01vZHVsZTtcclxuICBsZXQgX2RhdGFTb3VyY2U6IERhdGFTb3VyY2U7XHJcblxyXG4gIGNvbnN0IGNyZWF0ZU1vY2tSZXBvc2l0b3J5ID0gKCkgPT4gKHtcclxuICAgIGZpbmQ6IGplc3QuZm4oKSxcclxuICAgIGZpbmRPbmU6IGplc3QuZm4oKSxcclxuICAgIGNyZWF0ZTogamVzdC5mbigpLFxyXG4gICAgc2F2ZTogamVzdC5mbigpLFxyXG4gICAgdXBkYXRlOiBqZXN0LmZuKCksXHJcbiAgICBkZWxldGU6IGplc3QuZm4oKSxcclxuICAgIHNvZnREZWxldGU6IGplc3QuZm4oKSxcclxuICAgIGNyZWF0ZVF1ZXJ5QnVpbGRlcjogamVzdC5mbigoKSA9PiAoe1xyXG4gICAgICBsZWZ0Sm9pbkFuZFNlbGVjdDogamVzdC5mbigpLm1vY2tSZXR1cm5UaGlzKCksXHJcbiAgICAgIHdoZXJlOiBqZXN0LmZuKCkubW9ja1JldHVyblRoaXMoKSxcclxuICAgICAgYW5kV2hlcmU6IGplc3QuZm4oKS5tb2NrUmV0dXJuVGhpcygpLFxyXG4gICAgICBvcmRlckJ5OiBqZXN0LmZuKCkubW9ja1JldHVyblRoaXMoKSxcclxuICAgICAgc2tpcDogamVzdC5mbigpLm1vY2tSZXR1cm5UaGlzKCksXHJcbiAgICAgIHRha2U6IGplc3QuZm4oKS5tb2NrUmV0dXJuVGhpcygpLFxyXG4gICAgICBnZXRPbmU6IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZShudWxsKSxcclxuICAgICAgZ2V0TWFueTogamVzdC5mbigpLm1vY2tSZXNvbHZlZFZhbHVlKFtdKSxcclxuICAgICAgZ2V0TWFueUFuZENvdW50OiBqZXN0LmZuKCkubW9ja1Jlc29sdmVkVmFsdWUoW1tdLCAwXSksXHJcbiAgICB9KSksXHJcbiAgfSk7XHJcblxyXG4gIGNvbnN0IG1vY2tEYXRhU291cmNlID0ge1xyXG4gICAgY3JlYXRlUXVlcnlSdW5uZXI6IGplc3QuZm4oKCkgPT4gKHtcclxuICAgICAgY29ubmVjdDogamVzdC5mbigpLFxyXG4gICAgICBzdGFydFRyYW5zYWN0aW9uOiBqZXN0LmZuKCksXHJcbiAgICAgIGNvbW1pdFRyYW5zYWN0aW9uOiBqZXN0LmZuKCksXHJcbiAgICAgIHJvbGxiYWNrVHJhbnNhY3Rpb246IGplc3QuZm4oKSxcclxuICAgICAgcmVsZWFzZTogamVzdC5mbigpLFxyXG4gICAgICBtYW5hZ2VyOiB7XHJcbiAgICAgICAgY3JlYXRlOiBqZXN0LmZuKCksXHJcbiAgICAgICAgc2F2ZTogamVzdC5mbigpLFxyXG4gICAgICAgIGZpbmRPbmU6IGplc3QuZm4oKSxcclxuICAgICAgfSxcclxuICAgIH0pKSxcclxuICAgIGdldFJlcG9zaXRvcnk6IGplc3QuZm4oKCkgPT4gY3JlYXRlTW9ja1JlcG9zaXRvcnkoKSksXHJcbiAgICBtYW5hZ2VyOiB7XHJcbiAgICAgIGZpbmRPbmU6IGplc3QuZm4oKSxcclxuICAgIH0sXHJcbiAgfTtcclxuXHJcbiAgYmVmb3JlRWFjaChhc3luYyAoKSA9PiB7XHJcbiAgICB0ZXN0aW5nTW9kdWxlID0gYXdhaXQgVGVzdC5jcmVhdGVUZXN0aW5nTW9kdWxlKHtcclxuICAgICAgcHJvdmlkZXJzOiBbXHJcbiAgICAgICAgQ29ycmVzcG9uZGVuY2VTZXJ2aWNlLFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IGdldFJlcG9zaXRvcnlUb2tlbihDb3JyZXNwb25kZW5jZSksXHJcbiAgICAgICAgICB1c2VWYWx1ZTogY3JlYXRlTW9ja1JlcG9zaXRvcnkoKSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IGdldFJlcG9zaXRvcnlUb2tlbihDb3JyZXNwb25kZW5jZVJldmlzaW9uKSxcclxuICAgICAgICAgIHVzZVZhbHVlOiBjcmVhdGVNb2NrUmVwb3NpdG9yeSgpLFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgcHJvdmlkZTogZ2V0UmVwb3NpdG9yeVRva2VuKENvcnJlc3BvbmRlbmNlVHlwZSksXHJcbiAgICAgICAgICB1c2VWYWx1ZTogY3JlYXRlTW9ja1JlcG9zaXRvcnkoKSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IGdldFJlcG9zaXRvcnlUb2tlbihDb3JyZXNwb25kZW5jZVN0YXR1cyksXHJcbiAgICAgICAgICB1c2VWYWx1ZTogY3JlYXRlTW9ja1JlcG9zaXRvcnkoKSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IGdldFJlcG9zaXRvcnlUb2tlbihDb3JyZXNwb25kZW5jZVJlZmVyZW5jZSksXHJcbiAgICAgICAgICB1c2VWYWx1ZTogY3JlYXRlTW9ja1JlcG9zaXRvcnkoKSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IGdldFJlcG9zaXRvcnlUb2tlbihDb3JyZXNwb25kZW5jZVRhZyksXHJcbiAgICAgICAgICB1c2VWYWx1ZTogY3JlYXRlTW9ja1JlcG9zaXRvcnkoKSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IGdldFJlcG9zaXRvcnlUb2tlbihPcmdhbml6YXRpb24pLFxyXG4gICAgICAgICAgdXNlVmFsdWU6IGNyZWF0ZU1vY2tSZXBvc2l0b3J5KCksXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBwcm92aWRlOiBnZXRSZXBvc2l0b3J5VG9rZW4oQ29ycmVzcG9uZGVuY2VSZWNpcGllbnQpLFxyXG4gICAgICAgICAgdXNlVmFsdWU6IGNyZWF0ZU1vY2tSZXBvc2l0b3J5KCksXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBwcm92aWRlOiBEb2N1bWVudE51bWJlcmluZ1NlcnZpY2UsXHJcbiAgICAgICAgICB1c2VWYWx1ZToge1xyXG4gICAgICAgICAgICBnZW5lcmF0ZU5leHROdW1iZXI6IGplc3QuZm4oKSxcclxuICAgICAgICAgICAgdXBkYXRlTnVtYmVyRm9yRHJhZnQ6IGplc3QuZm4oKSxcclxuICAgICAgICAgICAgcHJldmlld05leHROdW1iZXI6IGplc3QuZm4oKSxcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBwcm92aWRlOiBKc29uU2NoZW1hU2VydmljZSxcclxuICAgICAgICAgIHVzZVZhbHVlOiB7IHZhbGlkYXRlOiBqZXN0LmZuKCkgfSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IFdvcmtmbG93RW5naW5lU2VydmljZSxcclxuICAgICAgICAgIHVzZVZhbHVlOiB7IGNyZWF0ZUluc3RhbmNlOiBqZXN0LmZuKCkgfSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IFVzZXJTZXJ2aWNlLFxyXG4gICAgICAgICAgdXNlVmFsdWU6IHtcclxuICAgICAgICAgICAgZmluZE9uZTogamVzdC5mbigpLFxyXG4gICAgICAgICAgICBnZXRVc2VyUGVybWlzc2lvbnM6IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZShbXSksXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgcHJvdmlkZTogRGF0YVNvdXJjZSxcclxuICAgICAgICAgIHVzZVZhbHVlOiBtb2NrRGF0YVNvdXJjZSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IFNlYXJjaFNlcnZpY2UsXHJcbiAgICAgICAgICB1c2VWYWx1ZTogeyBpbmRleERvY3VtZW50OiBqZXN0LmZuKCkgfSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IEZpbGVTdG9yYWdlU2VydmljZSxcclxuICAgICAgICAgIHVzZVZhbHVlOiB7IGNvbW1pdDogamVzdC5mbigpLm1vY2tSZXNvbHZlZFZhbHVlKFtdKSB9LFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgcHJvdmlkZTogVXVpZFJlc29sdmVyU2VydmljZSxcclxuICAgICAgICAgIHVzZVZhbHVlOiB7XHJcbiAgICAgICAgICAgIHJlc29sdmVQcm9qZWN0SWQ6IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZSgxKSxcclxuICAgICAgICAgICAgcmVzb2x2ZU9yZ2FuaXphdGlvbklkOiBqZXN0LmZuKCkubW9ja1Jlc29sdmVkVmFsdWUoMSksXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgcHJvdmlkZTogTm90aWZpY2F0aW9uU2VydmljZSxcclxuICAgICAgICAgIHVzZVZhbHVlOiB7IHNlbmQ6IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZSh1bmRlZmluZWQpIH0sXHJcbiAgICAgICAgfSxcclxuICAgICAgXSxcclxuICAgIH0pLmNvbXBpbGUoKTtcclxuXHJcbiAgICBzZXJ2aWNlID0gdGVzdGluZ01vZHVsZS5nZXQ8Q29ycmVzcG9uZGVuY2VTZXJ2aWNlPihDb3JyZXNwb25kZW5jZVNlcnZpY2UpO1xyXG4gICAgbnVtYmVyaW5nU2VydmljZSA9IHRlc3RpbmdNb2R1bGUuZ2V0PERvY3VtZW50TnVtYmVyaW5nU2VydmljZT4oXHJcbiAgICAgIERvY3VtZW50TnVtYmVyaW5nU2VydmljZVxyXG4gICAgKTtcclxuICAgIGNvcnJlc3BvbmRlbmNlUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2U+PihcclxuICAgICAgZ2V0UmVwb3NpdG9yeVRva2VuKENvcnJlc3BvbmRlbmNlKVxyXG4gICAgKTtcclxuICAgIHJldmlzaW9uUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2VSZXZpc2lvbj4+KFxyXG4gICAgICBnZXRSZXBvc2l0b3J5VG9rZW4oQ29ycmVzcG9uZGVuY2VSZXZpc2lvbilcclxuICAgICk7XHJcbiAgICBfZGF0YVNvdXJjZSA9IHRlc3RpbmdNb2R1bGUuZ2V0PERhdGFTb3VyY2U+KERhdGFTb3VyY2UpO1xyXG4gIH0pO1xyXG5cclxuICBpdCgnc2hvdWxkIGJlIGRlZmluZWQnLCAoKSA9PiB7XHJcbiAgICBleHBlY3Qoc2VydmljZSkudG9CZURlZmluZWQoKTtcclxuICB9KTtcclxuXHJcbiAgZGVzY3JpYmUoJ3VwZGF0ZScsICgpID0+IHtcclxuICAgIGl0KCdzaG91bGQgTk9UIHJlZ2VuZXJhdGUgbnVtYmVyIGlmIGNyaXRpY2FsIGZpZWxkcyB1bmNoYW5nZWQnLCBhc3luYyAoKSA9PiB7XHJcbiAgICAgIGNvbnN0IG1vY2tVc2VyID0geyBpZDogMSwgcHJpbWFyeU9yZ2FuaXphdGlvbklkOiAxMCB9IGFzIHVua25vd24gYXMgVXNlcjtcclxuICAgICAgY29uc3QgbW9ja1JldmlzaW9uID0ge1xyXG4gICAgICAgIGlkOiAxMDAsXHJcbiAgICAgICAgY29ycmVzcG9uZGVuY2VJZDogMSxcclxuICAgICAgICBpc0N1cnJlbnQ6IHRydWUsXHJcbiAgICAgICAgc3RhdHVzSWQ6IDUsXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBqZXN0XHJcbiAgICAgICAgLnNweU9uKHJldmlzaW9uUmVwbywgJ2ZpbmRPbmUnKVxyXG4gICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZShtb2NrUmV2aXNpb24gYXMgdW5rbm93biBhcyBDb3JyZXNwb25kZW5jZVJldmlzaW9uKTtcclxuXHJcbiAgICAgIGNvbnN0IG1vY2tDb3JyID0ge1xyXG4gICAgICAgIGlkOiAxLFxyXG4gICAgICAgIHByb2plY3RJZDogMSxcclxuICAgICAgICBjb3JyZXNwb25kZW5jZVR5cGVJZDogMixcclxuICAgICAgICBkaXNjaXBsaW5lSWQ6IDMsXHJcbiAgICAgICAgb3JpZ2luYXRvcklkOiAxMCxcclxuICAgICAgICBjb3JyZXNwb25kZW5jZU51bWJlcjogJ09MRC1OVU0nLFxyXG4gICAgICAgIHJlY2lwaWVudHM6IFt7IHJlY2lwaWVudFR5cGU6ICdUTycsIHJlY2lwaWVudE9yZ2FuaXphdGlvbklkOiA5OSB9XSxcclxuICAgICAgfTtcclxuICAgICAgamVzdFxyXG4gICAgICAgIC5zcHlPbihjb3JyZXNwb25kZW5jZVJlcG8sICdmaW5kT25lJylcclxuICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWUobW9ja0NvcnIgYXMgdW5rbm93biBhcyBDb3JyZXNwb25kZW5jZSk7XHJcblxyXG4gICAgICBjb25zdCB1cGRhdGVEdG86IFVwZGF0ZUNvcnJlc3BvbmRlbmNlRHRvID0ge1xyXG4gICAgICAgIHByb2plY3RJZDogMSxcclxuICAgICAgICBkaXNjaXBsaW5lSWQ6IDMsXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBhd2FpdCBzZXJ2aWNlLnVwZGF0ZSgxLCB1cGRhdGVEdG8sIG1vY2tVc2VyKTtcclxuXHJcbiAgICAgIGV4cGVjdChcclxuICAgICAgICBudW1iZXJpbmdTZXJ2aWNlLnVwZGF0ZU51bWJlckZvckRyYWZ0IGFzIGplc3QuTW9ja1xyXG4gICAgICApLm5vdC50b0hhdmVCZWVuQ2FsbGVkKCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBpdCgnc2hvdWxkIHJlZ2VuZXJhdGUgbnVtYmVyIGlmIFByb2plY3QgSUQgY2hhbmdlcycsIGFzeW5jICgpID0+IHtcclxuICAgICAgY29uc3QgbW9ja1VzZXIgPSB7IGlkOiAxLCBwcmltYXJ5T3JnYW5pemF0aW9uSWQ6IDEwIH0gYXMgdW5rbm93biBhcyBVc2VyO1xyXG4gICAgICBjb25zdCBtb2NrUmV2aXNpb24gPSB7XHJcbiAgICAgICAgaWQ6IDEwMCxcclxuICAgICAgICBjb3JyZXNwb25kZW5jZUlkOiAxLFxyXG4gICAgICAgIGlzQ3VycmVudDogdHJ1ZSxcclxuICAgICAgICBzdGF0dXNJZDogNSxcclxuICAgICAgfTtcclxuICAgICAgamVzdFxyXG4gICAgICAgIC5zcHlPbihyZXZpc2lvblJlcG8sICdmaW5kT25lJylcclxuICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWUobW9ja1JldmlzaW9uIGFzIHVua25vd24gYXMgQ29ycmVzcG9uZGVuY2VSZXZpc2lvbik7XHJcblxyXG4gICAgICBjb25zdCBtb2NrQ29yciA9IHtcclxuICAgICAgICBpZDogMSxcclxuICAgICAgICBwcm9qZWN0SWQ6IDEsXHJcbiAgICAgICAgY29ycmVzcG9uZGVuY2VUeXBlSWQ6IDIsXHJcbiAgICAgICAgZGlzY2lwbGluZUlkOiAzLFxyXG4gICAgICAgIG9yaWdpbmF0b3JJZDogMTAsXHJcbiAgICAgICAgY29ycmVzcG9uZGVuY2VOdW1iZXI6ICdPTEQtTlVNJyxcclxuICAgICAgICByZWNpcGllbnRzOiBbeyByZWNpcGllbnRUeXBlOiAnVE8nLCByZWNpcGllbnRPcmdhbml6YXRpb25JZDogOTkgfV0sXHJcbiAgICAgIH07XHJcbiAgICAgIGplc3RcclxuICAgICAgICAuc3B5T24oY29ycmVzcG9uZGVuY2VSZXBvLCAnZmluZE9uZScpXHJcbiAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlKG1vY2tDb3JyIGFzIHVua25vd24gYXMgQ29ycmVzcG9uZGVuY2UpO1xyXG5cclxuICAgICAgY29uc3QgdXBkYXRlRHRvOiBVcGRhdGVDb3JyZXNwb25kZW5jZUR0byA9IHtcclxuICAgICAgICBwcm9qZWN0SWQ6IDIsXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBjb25zdCB1dWlkUmVzb2x2ZXIgPVxyXG4gICAgICAgIHRlc3RpbmdNb2R1bGUuZ2V0PFV1aWRSZXNvbHZlclNlcnZpY2U+KFV1aWRSZXNvbHZlclNlcnZpY2UpO1xyXG4gICAgICAodXVpZFJlc29sdmVyLnJlc29sdmVQcm9qZWN0SWQgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSgyKTtcclxuXHJcbiAgICAgIGF3YWl0IHNlcnZpY2UudXBkYXRlKDEsIHVwZGF0ZUR0bywgbW9ja1VzZXIpO1xyXG5cclxuICAgICAgZXhwZWN0KFxyXG4gICAgICAgIG51bWJlcmluZ1NlcnZpY2UudXBkYXRlTnVtYmVyRm9yRHJhZnQgYXMgamVzdC5Nb2NrXHJcbiAgICAgICkudG9IYXZlQmVlbkNhbGxlZCgpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgaXQoJ3Nob3VsZCByZWdlbmVyYXRlIG51bWJlciBpZiBEb2N1bWVudCBUeXBlIGNoYW5nZXMnLCBhc3luYyAoKSA9PiB7XHJcbiAgICAgIGNvbnN0IG1vY2tVc2VyID0geyBpZDogMSwgcHJpbWFyeU9yZ2FuaXphdGlvbklkOiAxMCB9IGFzIHVua25vd24gYXMgVXNlcjtcclxuICAgICAgY29uc3QgbW9ja1JldmlzaW9uID0ge1xyXG4gICAgICAgIGlkOiAxMDAsXHJcbiAgICAgICAgY29ycmVzcG9uZGVuY2VJZDogMSxcclxuICAgICAgICBpc0N1cnJlbnQ6IHRydWUsXHJcbiAgICAgICAgc3RhdHVzSWQ6IDUsXHJcbiAgICAgIH07XHJcbiAgICAgIGplc3RcclxuICAgICAgICAuc3B5T24ocmV2aXNpb25SZXBvLCAnZmluZE9uZScpXHJcbiAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlKG1vY2tSZXZpc2lvbiBhcyB1bmtub3duIGFzIENvcnJlc3BvbmRlbmNlUmV2aXNpb24pO1xyXG5cclxuICAgICAgY29uc3QgbW9ja0NvcnIgPSB7XHJcbiAgICAgICAgaWQ6IDEsXHJcbiAgICAgICAgcHJvamVjdElkOiAxLFxyXG4gICAgICAgIGNvcnJlc3BvbmRlbmNlVHlwZUlkOiAyLFxyXG4gICAgICAgIGRpc2NpcGxpbmVJZDogMyxcclxuICAgICAgICBvcmlnaW5hdG9ySWQ6IDEwLFxyXG4gICAgICAgIGNvcnJlc3BvbmRlbmNlTnVtYmVyOiAnT0xELU5VTScsXHJcbiAgICAgICAgcmVjaXBpZW50czogW3sgcmVjaXBpZW50VHlwZTogJ1RPJywgcmVjaXBpZW50T3JnYW5pemF0aW9uSWQ6IDk5IH1dLFxyXG4gICAgICB9O1xyXG4gICAgICBqZXN0XHJcbiAgICAgICAgLnNweU9uKGNvcnJlc3BvbmRlbmNlUmVwbywgJ2ZpbmRPbmUnKVxyXG4gICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZShtb2NrQ29yciBhcyB1bmtub3duIGFzIENvcnJlc3BvbmRlbmNlKTtcclxuXHJcbiAgICAgIGNvbnN0IHVwZGF0ZUR0bzogVXBkYXRlQ29ycmVzcG9uZGVuY2VEdG8gPSB7XHJcbiAgICAgICAgdHlwZUlkOiA5OTksXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBjb25zdCB0eXBlUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2VUeXBlPj4oXHJcbiAgICAgICAgZ2V0UmVwb3NpdG9yeVRva2VuKENvcnJlc3BvbmRlbmNlVHlwZSlcclxuICAgICAgKTtcclxuICAgICAgKHR5cGVSZXBvLmZpbmRPbmUgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgaWQ6IDk5OSxcclxuICAgICAgICB0eXBlQ29kZTogJ05FVy1UWVBFJyxcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBhd2FpdCBzZXJ2aWNlLnVwZGF0ZSgxLCB1cGRhdGVEdG8sIG1vY2tVc2VyKTtcclxuXHJcbiAgICAgIGV4cGVjdChcclxuICAgICAgICBudW1iZXJpbmdTZXJ2aWNlLnVwZGF0ZU51bWJlckZvckRyYWZ0IGFzIGplc3QuTW9ja1xyXG4gICAgICApLnRvSGF2ZUJlZW5DYWxsZWQoKTtcclxuICAgIH0pO1xyXG5cclxuICAgIGl0KCdzaG91bGQgcmVnZW5lcmF0ZSBudW1iZXIgaWYgUmVjaXBpZW50IE9yZ2FuaXphdGlvbiBjaGFuZ2VzJywgYXN5bmMgKCkgPT4ge1xyXG4gICAgICBjb25zdCBtb2NrVXNlciA9IHsgaWQ6IDEsIHByaW1hcnlPcmdhbml6YXRpb25JZDogMTAgfSBhcyB1bmtub3duIGFzIFVzZXI7XHJcbiAgICAgIGNvbnN0IG1vY2tSZXZpc2lvbiA9IHtcclxuICAgICAgICBpZDogMTAwLFxyXG4gICAgICAgIGNvcnJlc3BvbmRlbmNlSWQ6IDEsXHJcbiAgICAgICAgaXNDdXJyZW50OiB0cnVlLFxyXG4gICAgICAgIHN0YXR1c0lkOiA1LFxyXG4gICAgICB9O1xyXG4gICAgICBqZXN0XHJcbiAgICAgICAgLnNweU9uKHJldmlzaW9uUmVwbywgJ2ZpbmRPbmUnKVxyXG4gICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZShtb2NrUmV2aXNpb24gYXMgdW5rbm93biBhcyBDb3JyZXNwb25kZW5jZVJldmlzaW9uKTtcclxuXHJcbiAgICAgIGNvbnN0IG1vY2tDb3JyID0ge1xyXG4gICAgICAgIGlkOiAxLFxyXG4gICAgICAgIHByb2plY3RJZDogMSxcclxuICAgICAgICBjb3JyZXNwb25kZW5jZVR5cGVJZDogMixcclxuICAgICAgICBkaXNjaXBsaW5lSWQ6IDMsXHJcbiAgICAgICAgb3JpZ2luYXRvcklkOiAxMCxcclxuICAgICAgICBjb3JyZXNwb25kZW5jZU51bWJlcjogJ09MRC1OVU0nLFxyXG4gICAgICAgIHJlY2lwaWVudHM6IFt7IHJlY2lwaWVudFR5cGU6ICdUTycsIHJlY2lwaWVudE9yZ2FuaXphdGlvbklkOiA5OSB9XSxcclxuICAgICAgfTtcclxuICAgICAgamVzdFxyXG4gICAgICAgIC5zcHlPbihjb3JyZXNwb25kZW5jZVJlcG8sICdmaW5kT25lJylcclxuICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWUobW9ja0NvcnIgYXMgdW5rbm93biBhcyBDb3JyZXNwb25kZW5jZSk7XHJcblxyXG4gICAgICAvLyBBY2Nlc3MgRGF0YVNvdXJjZSBtYW5hZ2VyIGZvciBtb2NraW5nXHJcbiAgICAgIG1vY2tEYXRhU291cmNlLm1hbmFnZXIuZmluZE9uZS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgaWQ6IDg4LFxyXG4gICAgICAgIG9yZ2FuaXphdGlvbkNvZGU6ICdORVctT1JHJyxcclxuICAgICAgfSBhcyB1bmtub3duIGFzIE9yZ2FuaXphdGlvbik7XHJcblxyXG4gICAgICBjb25zdCB1cGRhdGVEdG86IFVwZGF0ZUNvcnJlc3BvbmRlbmNlRHRvID0ge1xyXG4gICAgICAgIHJlY2lwaWVudHM6IFt7IHR5cGU6ICdUTycsIG9yZ2FuaXphdGlvbklkOiA4OCB9XSxcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGF3YWl0IHNlcnZpY2UudXBkYXRlKDEsIHVwZGF0ZUR0bywgbW9ja1VzZXIpO1xyXG5cclxuICAgICAgZXhwZWN0KFxyXG4gICAgICAgIG51bWJlcmluZ1NlcnZpY2UudXBkYXRlTnVtYmVyRm9yRHJhZnQgYXMgamVzdC5Nb2NrXHJcbiAgICAgICkudG9IYXZlQmVlbkNhbGxlZCgpO1xyXG4gICAgfSk7XHJcbiAgfSk7XHJcblxyXG4gIGRlc2NyaWJlKCdjcmVhdGUnLCAoKSA9PiB7XHJcbiAgICBpdCgnc2hvdWxkIGFsbG93IHN5c3RlbS5tYW5hZ2VfYWxsIHVzZXIgd2l0aG91dCBwcmltYXJ5T3JnYW5pemF0aW9uSWQgd2hlbiBvcmlnaW5hdG9ySWQgaXMgcHJvdmlkZWQnLCBhc3luYyAoKSA9PiB7XHJcbiAgICAgIGNvbnN0IG1vY2tVc2VyID0ge1xyXG4gICAgICAgIHVzZXJfaWQ6IDEsXHJcbiAgICAgICAgcHJpbWFyeU9yZ2FuaXphdGlvbklkOiBudWxsLFxyXG4gICAgICB9IGFzIHVua25vd24gYXMgVXNlcjtcclxuXHJcbiAgICAgIGNvbnN0IGNyZWF0ZUR0bzogQ3JlYXRlQ29ycmVzcG9uZGVuY2VEdG8gPSB7XHJcbiAgICAgICAgcHJvamVjdElkOiAncHJvamVjdC11dWlkJyxcclxuICAgICAgICB0eXBlSWQ6IDEsXHJcbiAgICAgICAgc3ViamVjdDogJ1Rlc3QgU3ViamVjdCcsXHJcbiAgICAgICAgb3JpZ2luYXRvcklkOiAnb3JpZ2luYXRvci11dWlkJyxcclxuICAgICAgICByZWNpcGllbnRzOiBbeyBvcmdhbml6YXRpb25JZDogJ3JlY2lwaWVudC11dWlkJywgdHlwZTogJ1RPJyB9XSxcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGNvbnN0IHVzZXJTZXJ2aWNlID0gdGVzdGluZ01vZHVsZS5nZXQ8VXNlclNlcnZpY2U+KFVzZXJTZXJ2aWNlKTtcclxuICAgICAgY29uc3QgdHlwZVJlcG8gPSB0ZXN0aW5nTW9kdWxlLmdldDxSZXBvc2l0b3J5PENvcnJlc3BvbmRlbmNlVHlwZT4+KFxyXG4gICAgICAgIGdldFJlcG9zaXRvcnlUb2tlbihDb3JyZXNwb25kZW5jZVR5cGUpXHJcbiAgICAgICk7XHJcbiAgICAgIGNvbnN0IHN0YXR1c1JlcG8gPSB0ZXN0aW5nTW9kdWxlLmdldDxSZXBvc2l0b3J5PENvcnJlc3BvbmRlbmNlU3RhdHVzPj4oXHJcbiAgICAgICAgZ2V0UmVwb3NpdG9yeVRva2VuKENvcnJlc3BvbmRlbmNlU3RhdHVzKVxyXG4gICAgICApO1xyXG4gICAgICBjb25zdCB1dWlkUmVzb2x2ZXIgPVxyXG4gICAgICAgIHRlc3RpbmdNb2R1bGUuZ2V0PFV1aWRSZXNvbHZlclNlcnZpY2U+KFV1aWRSZXNvbHZlclNlcnZpY2UpO1xyXG5cclxuICAgICAgKHVzZXJTZXJ2aWNlLmZpbmRPbmUgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgdXNlcl9pZDogMSxcclxuICAgICAgICBwcmltYXJ5T3JnYW5pemF0aW9uSWQ6IG51bGwsXHJcbiAgICAgIH0pO1xyXG4gICAgICAodXNlclNlcnZpY2UuZ2V0VXNlclBlcm1pc3Npb25zIGFzIGplc3QuTW9jaykubW9ja1Jlc29sdmVkVmFsdWUoW1xyXG4gICAgICAgICdzeXN0ZW0ubWFuYWdlX2FsbCcsXHJcbiAgICAgIF0pO1xyXG5cclxuICAgICAgKHV1aWRSZXNvbHZlci5yZXNvbHZlUHJvamVjdElkIGFzIGplc3QuTW9jaykubW9ja1Jlc29sdmVkVmFsdWUoMTAwKTtcclxuICAgICAgKHV1aWRSZXNvbHZlci5yZXNvbHZlT3JnYW5pemF0aW9uSWQgYXMgamVzdC5Nb2NrKS5tb2NrSW1wbGVtZW50YXRpb24oXHJcbiAgICAgICAgKHZhbHVlOiBudW1iZXIgfCBzdHJpbmcpID0+IHtcclxuICAgICAgICAgIGlmICh2YWx1ZSA9PT0gJ29yaWdpbmF0b3ItdXVpZCcpIHJldHVybiAxMDtcclxuICAgICAgICAgIGlmICh2YWx1ZSA9PT0gJ3JlY2lwaWVudC11dWlkJykgcmV0dXJuIDIwO1xyXG4gICAgICAgICAgcmV0dXJuIDA7XHJcbiAgICAgICAgfVxyXG4gICAgICApO1xyXG5cclxuICAgICAgKHR5cGVSZXBvLmZpbmRPbmUgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgaWQ6IDEsXHJcbiAgICAgICAgdHlwZUNvZGU6ICdMVFInLFxyXG4gICAgICB9KTtcclxuICAgICAgKHN0YXR1c1JlcG8uZmluZE9uZSBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKHtcclxuICAgICAgICBpZDogMSxcclxuICAgICAgICBzdGF0dXNDb2RlOiAnRFJBRlQnLFxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIChudW1iZXJpbmdTZXJ2aWNlLmdlbmVyYXRlTmV4dE51bWJlciBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKHtcclxuICAgICAgICBudW1iZXI6ICdET0MtMDAxJyxcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBtb2NrRGF0YVNvdXJjZS5tYW5hZ2VyLmZpbmRPbmVcclxuICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKHsgaWQ6IDEwLCBvcmdhbml6YXRpb25Db2RlOiAnT1JHJyB9KVxyXG4gICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoeyBpZDogMjAsIG9yZ2FuaXphdGlvbkNvZGU6ICdSRUMnIH0pO1xyXG5cclxuICAgICAgY29uc3QgcXVlcnlSdW5uZXIgPSB7XHJcbiAgICAgICAgY29ubmVjdDogamVzdC5mbigpLFxyXG4gICAgICAgIHN0YXJ0VHJhbnNhY3Rpb246IGplc3QuZm4oKSxcclxuICAgICAgICBjb21taXRUcmFuc2FjdGlvbjogamVzdC5mbigpLFxyXG4gICAgICAgIHJvbGxiYWNrVHJhbnNhY3Rpb246IGplc3QuZm4oKSxcclxuICAgICAgICByZWxlYXNlOiBqZXN0LmZuKCksXHJcbiAgICAgICAgbWFuYWdlcjoge1xyXG4gICAgICAgICAgY3JlYXRlOiBqZXN0LmZuKFxyXG4gICAgICAgICAgICAoX2VudGl0eTogdW5rbm93biwgcGF5bG9hZDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IHBheWxvYWRcclxuICAgICAgICAgICksXHJcbiAgICAgICAgICBzYXZlOiBqZXN0XHJcbiAgICAgICAgICAgIC5mbigpXHJcbiAgICAgICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoeyBpZDogOTk5LCBwdWJsaWNJZDogJ2NvcnItdXVpZCcgfSlcclxuICAgICAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7IGlkOiAxMDAwIH0pXHJcbiAgICAgICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoW10pLFxyXG4gICAgICAgICAgZmluZE9uZTogamVzdC5mbigpLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH07XHJcblxyXG4gICAgICAobW9ja0RhdGFTb3VyY2UuY3JlYXRlUXVlcnlSdW5uZXIgYXMgamVzdC5Nb2NrKS5tb2NrUmV0dXJuVmFsdWUoXHJcbiAgICAgICAgcXVlcnlSdW5uZXJcclxuICAgICAgKTtcclxuXHJcbiAgICAgIGF3YWl0IHNlcnZpY2UuY3JlYXRlKGNyZWF0ZUR0bywgbW9ja1VzZXIpO1xyXG5cclxuICAgICAgZXhwZWN0KHF1ZXJ5UnVubmVyLm1hbmFnZXIuY3JlYXRlKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcclxuICAgICAgICBDb3JyZXNwb25kZW5jZSxcclxuICAgICAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7IG9yaWdpbmF0b3JJZDogMTAgfSlcclxuICAgICAgKTtcclxuICAgIH0pO1xyXG5cclxuICAgIGl0KCdzaG91bGQgc2V0IHJldmlzaW9uTGFiZWwgdG8gXCJBXCIgZm9yIFJGQSB0eXBlJywgYXN5bmMgKCkgPT4ge1xyXG4gICAgICBjb25zdCBtb2NrVXNlciA9IHtcclxuICAgICAgICB1c2VyX2lkOiAxLFxyXG4gICAgICAgIHByaW1hcnlPcmdhbml6YXRpb25JZDogMTAsXHJcbiAgICAgIH0gYXMgdW5rbm93biBhcyBVc2VyO1xyXG5cclxuICAgICAgY29uc3QgY3JlYXRlRHRvOiBDcmVhdGVDb3JyZXNwb25kZW5jZUR0byA9IHtcclxuICAgICAgICBwcm9qZWN0SWQ6ICdwcm9qZWN0LXV1aWQnLFxyXG4gICAgICAgIHR5cGVJZDogMSxcclxuICAgICAgICBzdWJqZWN0OiAnVGVzdCBTdWJqZWN0JyxcclxuICAgICAgICByZWNpcGllbnRzOiBbeyBvcmdhbml6YXRpb25JZDogJ3JlY2lwaWVudC11dWlkJywgdHlwZTogJ1RPJyB9XSxcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGNvbnN0IHR5cGVSZXBvID0gdGVzdGluZ01vZHVsZS5nZXQ8UmVwb3NpdG9yeTxDb3JyZXNwb25kZW5jZVR5cGU+PihcclxuICAgICAgICBnZXRSZXBvc2l0b3J5VG9rZW4oQ29ycmVzcG9uZGVuY2VUeXBlKVxyXG4gICAgICApO1xyXG4gICAgICBjb25zdCBzdGF0dXNSZXBvID0gdGVzdGluZ01vZHVsZS5nZXQ8UmVwb3NpdG9yeTxDb3JyZXNwb25kZW5jZVN0YXR1cz4+KFxyXG4gICAgICAgIGdldFJlcG9zaXRvcnlUb2tlbihDb3JyZXNwb25kZW5jZVN0YXR1cylcclxuICAgICAgKTtcclxuICAgICAgY29uc3QgdXVpZFJlc29sdmVyID1cclxuICAgICAgICB0ZXN0aW5nTW9kdWxlLmdldDxVdWlkUmVzb2x2ZXJTZXJ2aWNlPihVdWlkUmVzb2x2ZXJTZXJ2aWNlKTtcclxuXHJcbiAgICAgICh1dWlkUmVzb2x2ZXIucmVzb2x2ZVByb2plY3RJZCBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKDEwMCk7XHJcbiAgICAgICh1dWlkUmVzb2x2ZXIucmVzb2x2ZU9yZ2FuaXphdGlvbklkIGFzIGplc3QuTW9jaykubW9ja1Jlc29sdmVkVmFsdWUoMjApO1xyXG5cclxuICAgICAgKHR5cGVSZXBvLmZpbmRPbmUgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgaWQ6IDEsXHJcbiAgICAgICAgdHlwZUNvZGU6ICdSRkEnLFxyXG4gICAgICB9KTtcclxuICAgICAgKHN0YXR1c1JlcG8uZmluZE9uZSBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKHtcclxuICAgICAgICBpZDogMSxcclxuICAgICAgICBzdGF0dXNDb2RlOiAnRFJBRlQnLFxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIChudW1iZXJpbmdTZXJ2aWNlLmdlbmVyYXRlTmV4dE51bWJlciBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKHtcclxuICAgICAgICBudW1iZXI6ICdET0MtMDAxJyxcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBtb2NrRGF0YVNvdXJjZS5tYW5hZ2VyLmZpbmRPbmVcclxuICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKHsgaWQ6IDEwLCBvcmdhbml6YXRpb25Db2RlOiAnT1JHJyB9KVxyXG4gICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoeyBpZDogMjAsIG9yZ2FuaXphdGlvbkNvZGU6ICdSRUMnIH0pO1xyXG5cclxuICAgICAgY29uc3QgcXVlcnlSdW5uZXIgPSB7XHJcbiAgICAgICAgY29ubmVjdDogamVzdC5mbigpLFxyXG4gICAgICAgIHN0YXJ0VHJhbnNhY3Rpb246IGplc3QuZm4oKSxcclxuICAgICAgICBjb21taXRUcmFuc2FjdGlvbjogamVzdC5mbigpLFxyXG4gICAgICAgIHJvbGxiYWNrVHJhbnNhY3Rpb246IGplc3QuZm4oKSxcclxuICAgICAgICByZWxlYXNlOiBqZXN0LmZuKCksXHJcbiAgICAgICAgbWFuYWdlcjoge1xyXG4gICAgICAgICAgY3JlYXRlOiBqZXN0LmZuKFxyXG4gICAgICAgICAgICAoX2VudGl0eTogdW5rbm93biwgcGF5bG9hZDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IHBheWxvYWRcclxuICAgICAgICAgICksXHJcbiAgICAgICAgICBzYXZlOiBqZXN0XHJcbiAgICAgICAgICAgIC5mbigpXHJcbiAgICAgICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoeyBpZDogOTk5LCBwdWJsaWNJZDogJ2NvcnItdXVpZCcgfSlcclxuICAgICAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7IGlkOiAxMDAwIH0pXHJcbiAgICAgICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoW10pLFxyXG4gICAgICAgICAgZmluZE9uZTogamVzdC5mbigpLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH07XHJcblxyXG4gICAgICAobW9ja0RhdGFTb3VyY2UuY3JlYXRlUXVlcnlSdW5uZXIgYXMgamVzdC5Nb2NrKS5tb2NrUmV0dXJuVmFsdWUoXHJcbiAgICAgICAgcXVlcnlSdW5uZXJcclxuICAgICAgKTtcclxuXHJcbiAgICAgIGF3YWl0IHNlcnZpY2UuY3JlYXRlKGNyZWF0ZUR0bywgbW9ja1VzZXIpO1xyXG5cclxuICAgICAgZXhwZWN0KHF1ZXJ5UnVubmVyLm1hbmFnZXIuY3JlYXRlKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcclxuICAgICAgICBDb3JyZXNwb25kZW5jZVJldmlzaW9uLFxyXG4gICAgICAgIGV4cGVjdC5vYmplY3RDb250YWluaW5nKHsgcmV2aXNpb25MYWJlbDogJ0EnIH0pXHJcbiAgICAgICk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBpdCgnc2hvdWxkIHNldCByZXZpc2lvbkxhYmVsIHRvIFwiQVwiIGZvciBSRkkgdHlwZScsIGFzeW5jICgpID0+IHtcclxuICAgICAgY29uc3QgbW9ja1VzZXIgPSB7XHJcbiAgICAgICAgdXNlcl9pZDogMSxcclxuICAgICAgICBwcmltYXJ5T3JnYW5pemF0aW9uSWQ6IDEwLFxyXG4gICAgICB9IGFzIHVua25vd24gYXMgVXNlcjtcclxuXHJcbiAgICAgIGNvbnN0IGNyZWF0ZUR0bzogQ3JlYXRlQ29ycmVzcG9uZGVuY2VEdG8gPSB7XHJcbiAgICAgICAgcHJvamVjdElkOiAncHJvamVjdC11dWlkJyxcclxuICAgICAgICB0eXBlSWQ6IDEsXHJcbiAgICAgICAgc3ViamVjdDogJ1Rlc3QgU3ViamVjdCcsXHJcbiAgICAgICAgcmVjaXBpZW50czogW3sgb3JnYW5pemF0aW9uSWQ6ICdyZWNpcGllbnQtdXVpZCcsIHR5cGU6ICdUTycgfV0sXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBjb25zdCB0eXBlUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2VUeXBlPj4oXHJcbiAgICAgICAgZ2V0UmVwb3NpdG9yeVRva2VuKENvcnJlc3BvbmRlbmNlVHlwZSlcclxuICAgICAgKTtcclxuICAgICAgY29uc3Qgc3RhdHVzUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2VTdGF0dXM+PihcclxuICAgICAgICBnZXRSZXBvc2l0b3J5VG9rZW4oQ29ycmVzcG9uZGVuY2VTdGF0dXMpXHJcbiAgICAgICk7XHJcbiAgICAgIGNvbnN0IHV1aWRSZXNvbHZlciA9XHJcbiAgICAgICAgdGVzdGluZ01vZHVsZS5nZXQ8VXVpZFJlc29sdmVyU2VydmljZT4oVXVpZFJlc29sdmVyU2VydmljZSk7XHJcblxyXG4gICAgICAodXVpZFJlc29sdmVyLnJlc29sdmVQcm9qZWN0SWQgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSgxMDApO1xyXG4gICAgICAodXVpZFJlc29sdmVyLnJlc29sdmVPcmdhbml6YXRpb25JZCBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKDIwKTtcclxuXHJcbiAgICAgICh0eXBlUmVwby5maW5kT25lIGFzIGplc3QuTW9jaykubW9ja1Jlc29sdmVkVmFsdWUoe1xyXG4gICAgICAgIGlkOiAxLFxyXG4gICAgICAgIHR5cGVDb2RlOiAnUkZJJyxcclxuICAgICAgfSk7XHJcbiAgICAgIChzdGF0dXNSZXBvLmZpbmRPbmUgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgaWQ6IDEsXHJcbiAgICAgICAgc3RhdHVzQ29kZTogJ0RSQUZUJyxcclxuICAgICAgfSk7XHJcblxyXG4gICAgICAobnVtYmVyaW5nU2VydmljZS5nZW5lcmF0ZU5leHROdW1iZXIgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgbnVtYmVyOiAnRE9DLTAwMScsXHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgbW9ja0RhdGFTb3VyY2UubWFuYWdlci5maW5kT25lXHJcbiAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7IGlkOiAxMCwgb3JnYW5pemF0aW9uQ29kZTogJ09SRycgfSlcclxuICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKHsgaWQ6IDIwLCBvcmdhbml6YXRpb25Db2RlOiAnUkVDJyB9KTtcclxuXHJcbiAgICAgIGNvbnN0IHF1ZXJ5UnVubmVyID0ge1xyXG4gICAgICAgIGNvbm5lY3Q6IGplc3QuZm4oKSxcclxuICAgICAgICBzdGFydFRyYW5zYWN0aW9uOiBqZXN0LmZuKCksXHJcbiAgICAgICAgY29tbWl0VHJhbnNhY3Rpb246IGplc3QuZm4oKSxcclxuICAgICAgICByb2xsYmFja1RyYW5zYWN0aW9uOiBqZXN0LmZuKCksXHJcbiAgICAgICAgcmVsZWFzZTogamVzdC5mbigpLFxyXG4gICAgICAgIG1hbmFnZXI6IHtcclxuICAgICAgICAgIGNyZWF0ZTogamVzdC5mbihcclxuICAgICAgICAgICAgKF9lbnRpdHk6IHVua25vd24sIHBheWxvYWQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PiBwYXlsb2FkXHJcbiAgICAgICAgICApLFxyXG4gICAgICAgICAgc2F2ZTogamVzdFxyXG4gICAgICAgICAgICAuZm4oKVxyXG4gICAgICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKHsgaWQ6IDk5OSwgcHVibGljSWQ6ICdjb3JyLXV1aWQnIH0pXHJcbiAgICAgICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoeyBpZDogMTAwMCB9KVxyXG4gICAgICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKFtdKSxcclxuICAgICAgICAgIGZpbmRPbmU6IGplc3QuZm4oKSxcclxuICAgICAgICB9LFxyXG4gICAgICB9O1xyXG5cclxuICAgICAgKG1vY2tEYXRhU291cmNlLmNyZWF0ZVF1ZXJ5UnVubmVyIGFzIGplc3QuTW9jaykubW9ja1JldHVyblZhbHVlKFxyXG4gICAgICAgIHF1ZXJ5UnVubmVyXHJcbiAgICAgICk7XHJcblxyXG4gICAgICBhd2FpdCBzZXJ2aWNlLmNyZWF0ZShjcmVhdGVEdG8sIG1vY2tVc2VyKTtcclxuXHJcbiAgICAgIGV4cGVjdChxdWVyeVJ1bm5lci5tYW5hZ2VyLmNyZWF0ZSkudG9IYXZlQmVlbkNhbGxlZFdpdGgoXHJcbiAgICAgICAgQ29ycmVzcG9uZGVuY2VSZXZpc2lvbixcclxuICAgICAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7IHJldmlzaW9uTGFiZWw6ICdBJyB9KVxyXG4gICAgICApO1xyXG4gICAgfSk7XHJcblxyXG4gICAgaXQoJ3Nob3VsZCBzZXQgcmV2aXNpb25MYWJlbCB0byBudWxsIGZvciBMRVRURVIgdHlwZScsIGFzeW5jICgpID0+IHtcclxuICAgICAgY29uc3QgbW9ja1VzZXIgPSB7XHJcbiAgICAgICAgdXNlcl9pZDogMSxcclxuICAgICAgICBwcmltYXJ5T3JnYW5pemF0aW9uSWQ6IDEwLFxyXG4gICAgICB9IGFzIHVua25vd24gYXMgVXNlcjtcclxuXHJcbiAgICAgIGNvbnN0IGNyZWF0ZUR0bzogQ3JlYXRlQ29ycmVzcG9uZGVuY2VEdG8gPSB7XHJcbiAgICAgICAgcHJvamVjdElkOiAncHJvamVjdC11dWlkJyxcclxuICAgICAgICB0eXBlSWQ6IDEsXHJcbiAgICAgICAgc3ViamVjdDogJ1Rlc3QgU3ViamVjdCcsXHJcbiAgICAgICAgcmVjaXBpZW50czogW3sgb3JnYW5pemF0aW9uSWQ6ICdyZWNpcGllbnQtdXVpZCcsIHR5cGU6ICdUTycgfV0sXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBjb25zdCB0eXBlUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2VUeXBlPj4oXHJcbiAgICAgICAgZ2V0UmVwb3NpdG9yeVRva2VuKENvcnJlc3BvbmRlbmNlVHlwZSlcclxuICAgICAgKTtcclxuICAgICAgY29uc3Qgc3RhdHVzUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2VTdGF0dXM+PihcclxuICAgICAgICBnZXRSZXBvc2l0b3J5VG9rZW4oQ29ycmVzcG9uZGVuY2VTdGF0dXMpXHJcbiAgICAgICk7XHJcbiAgICAgIGNvbnN0IHV1aWRSZXNvbHZlciA9XHJcbiAgICAgICAgdGVzdGluZ01vZHVsZS5nZXQ8VXVpZFJlc29sdmVyU2VydmljZT4oVXVpZFJlc29sdmVyU2VydmljZSk7XHJcblxyXG4gICAgICAodXVpZFJlc29sdmVyLnJlc29sdmVQcm9qZWN0SWQgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSgxMDApO1xyXG4gICAgICAodXVpZFJlc29sdmVyLnJlc29sdmVPcmdhbml6YXRpb25JZCBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKDIwKTtcclxuXHJcbiAgICAgICh0eXBlUmVwby5maW5kT25lIGFzIGplc3QuTW9jaykubW9ja1Jlc29sdmVkVmFsdWUoe1xyXG4gICAgICAgIGlkOiAxLFxyXG4gICAgICAgIHR5cGVDb2RlOiAnTEVUVEVSJyxcclxuICAgICAgfSk7XHJcbiAgICAgIChzdGF0dXNSZXBvLmZpbmRPbmUgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgaWQ6IDEsXHJcbiAgICAgICAgc3RhdHVzQ29kZTogJ0RSQUZUJyxcclxuICAgICAgfSk7XHJcblxyXG4gICAgICAobnVtYmVyaW5nU2VydmljZS5nZW5lcmF0ZU5leHROdW1iZXIgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgbnVtYmVyOiAnRE9DLTAwMScsXHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgbW9ja0RhdGFTb3VyY2UubWFuYWdlci5maW5kT25lXHJcbiAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7IGlkOiAxMCwgb3JnYW5pemF0aW9uQ29kZTogJ09SRycgfSlcclxuICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKHsgaWQ6IDIwLCBvcmdhbml6YXRpb25Db2RlOiAnUkVDJyB9KTtcclxuXHJcbiAgICAgIGNvbnN0IHF1ZXJ5UnVubmVyID0ge1xyXG4gICAgICAgIGNvbm5lY3Q6IGplc3QuZm4oKSxcclxuICAgICAgICBzdGFydFRyYW5zYWN0aW9uOiBqZXN0LmZuKCksXHJcbiAgICAgICAgY29tbWl0VHJhbnNhY3Rpb246IGplc3QuZm4oKSxcclxuICAgICAgICByb2xsYmFja1RyYW5zYWN0aW9uOiBqZXN0LmZuKCksXHJcbiAgICAgICAgcmVsZWFzZTogamVzdC5mbigpLFxyXG4gICAgICAgIG1hbmFnZXI6IHtcclxuICAgICAgICAgIGNyZWF0ZTogamVzdC5mbihcclxuICAgICAgICAgICAgKF9lbnRpdHk6IHVua25vd24sIHBheWxvYWQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PiBwYXlsb2FkXHJcbiAgICAgICAgICApLFxyXG4gICAgICAgICAgc2F2ZTogamVzdFxyXG4gICAgICAgICAgICAuZm4oKVxyXG4gICAgICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKHsgaWQ6IDk5OSwgcHVibGljSWQ6ICdjb3JyLXV1aWQnIH0pXHJcbiAgICAgICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoeyBpZDogMTAwMCB9KVxyXG4gICAgICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKFtdKSxcclxuICAgICAgICAgIGZpbmRPbmU6IGplc3QuZm4oKSxcclxuICAgICAgICB9LFxyXG4gICAgICB9O1xyXG5cclxuICAgICAgKG1vY2tEYXRhU291cmNlLmNyZWF0ZVF1ZXJ5UnVubmVyIGFzIGplc3QuTW9jaykubW9ja1JldHVyblZhbHVlKFxyXG4gICAgICAgIHF1ZXJ5UnVubmVyXHJcbiAgICAgICk7XHJcblxyXG4gICAgICBhd2FpdCBzZXJ2aWNlLmNyZWF0ZShjcmVhdGVEdG8sIG1vY2tVc2VyKTtcclxuXHJcbiAgICAgIGV4cGVjdChxdWVyeVJ1bm5lci5tYW5hZ2VyLmNyZWF0ZSkudG9IYXZlQmVlbkNhbGxlZFdpdGgoXHJcbiAgICAgICAgQ29ycmVzcG9uZGVuY2VSZXZpc2lvbixcclxuICAgICAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7IHJldmlzaW9uTGFiZWw6IHVuZGVmaW5lZCB9KVxyXG4gICAgICApO1xyXG4gICAgfSk7XHJcblxyXG4gICAgaXQoJ3Nob3VsZCBzZXQgcmV2aXNpb25MYWJlbCB0byBudWxsIGZvciBNRU1PIHR5cGUnLCBhc3luYyAoKSA9PiB7XHJcbiAgICAgIGNvbnN0IG1vY2tVc2VyID0ge1xyXG4gICAgICAgIHVzZXJfaWQ6IDEsXHJcbiAgICAgICAgcHJpbWFyeU9yZ2FuaXphdGlvbklkOiAxMCxcclxuICAgICAgfSBhcyB1bmtub3duIGFzIFVzZXI7XHJcblxyXG4gICAgICBjb25zdCBjcmVhdGVEdG86IENyZWF0ZUNvcnJlc3BvbmRlbmNlRHRvID0ge1xyXG4gICAgICAgIHByb2plY3RJZDogJ3Byb2plY3QtdXVpZCcsXHJcbiAgICAgICAgdHlwZUlkOiAxLFxyXG4gICAgICAgIHN1YmplY3Q6ICdUZXN0IFN1YmplY3QnLFxyXG4gICAgICAgIHJlY2lwaWVudHM6IFt7IG9yZ2FuaXphdGlvbklkOiAncmVjaXBpZW50LXV1aWQnLCB0eXBlOiAnVE8nIH1dLFxyXG4gICAgICB9O1xyXG5cclxuICAgICAgY29uc3QgdHlwZVJlcG8gPSB0ZXN0aW5nTW9kdWxlLmdldDxSZXBvc2l0b3J5PENvcnJlc3BvbmRlbmNlVHlwZT4+KFxyXG4gICAgICAgIGdldFJlcG9zaXRvcnlUb2tlbihDb3JyZXNwb25kZW5jZVR5cGUpXHJcbiAgICAgICk7XHJcbiAgICAgIGNvbnN0IHN0YXR1c1JlcG8gPSB0ZXN0aW5nTW9kdWxlLmdldDxSZXBvc2l0b3J5PENvcnJlc3BvbmRlbmNlU3RhdHVzPj4oXHJcbiAgICAgICAgZ2V0UmVwb3NpdG9yeVRva2VuKENvcnJlc3BvbmRlbmNlU3RhdHVzKVxyXG4gICAgICApO1xyXG4gICAgICBjb25zdCB1dWlkUmVzb2x2ZXIgPVxyXG4gICAgICAgIHRlc3RpbmdNb2R1bGUuZ2V0PFV1aWRSZXNvbHZlclNlcnZpY2U+KFV1aWRSZXNvbHZlclNlcnZpY2UpO1xyXG5cclxuICAgICAgKHV1aWRSZXNvbHZlci5yZXNvbHZlUHJvamVjdElkIGFzIGplc3QuTW9jaykubW9ja1Jlc29sdmVkVmFsdWUoMTAwKTtcclxuICAgICAgKHV1aWRSZXNvbHZlci5yZXNvbHZlT3JnYW5pemF0aW9uSWQgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSgyMCk7XHJcblxyXG4gICAgICAodHlwZVJlcG8uZmluZE9uZSBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKHtcclxuICAgICAgICBpZDogMSxcclxuICAgICAgICB0eXBlQ29kZTogJ01FTU8nLFxyXG4gICAgICB9KTtcclxuICAgICAgKHN0YXR1c1JlcG8uZmluZE9uZSBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKHtcclxuICAgICAgICBpZDogMSxcclxuICAgICAgICBzdGF0dXNDb2RlOiAnRFJBRlQnLFxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIChudW1iZXJpbmdTZXJ2aWNlLmdlbmVyYXRlTmV4dE51bWJlciBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKHtcclxuICAgICAgICBudW1iZXI6ICdET0MtMDAxJyxcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBtb2NrRGF0YVNvdXJjZS5tYW5hZ2VyLmZpbmRPbmVcclxuICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKHsgaWQ6IDEwLCBvcmdhbml6YXRpb25Db2RlOiAnT1JHJyB9KVxyXG4gICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoeyBpZDogMjAsIG9yZ2FuaXphdGlvbkNvZGU6ICdSRUMnIH0pO1xyXG5cclxuICAgICAgY29uc3QgcXVlcnlSdW5uZXIgPSB7XHJcbiAgICAgICAgY29ubmVjdDogamVzdC5mbigpLFxyXG4gICAgICAgIHN0YXJ0VHJhbnNhY3Rpb246IGplc3QuZm4oKSxcclxuICAgICAgICBjb21taXRUcmFuc2FjdGlvbjogamVzdC5mbigpLFxyXG4gICAgICAgIHJvbGxiYWNrVHJhbnNhY3Rpb246IGplc3QuZm4oKSxcclxuICAgICAgICByZWxlYXNlOiBqZXN0LmZuKCksXHJcbiAgICAgICAgbWFuYWdlcjoge1xyXG4gICAgICAgICAgY3JlYXRlOiBqZXN0LmZuKFxyXG4gICAgICAgICAgICAoX2VudGl0eTogdW5rbm93biwgcGF5bG9hZDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IHBheWxvYWRcclxuICAgICAgICAgICksXHJcbiAgICAgICAgICBzYXZlOiBqZXN0XHJcbiAgICAgICAgICAgIC5mbigpXHJcbiAgICAgICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoeyBpZDogOTk5LCBwdWJsaWNJZDogJ2NvcnItdXVpZCcgfSlcclxuICAgICAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7IGlkOiAxMDAwIH0pXHJcbiAgICAgICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoW10pLFxyXG4gICAgICAgICAgZmluZE9uZTogamVzdC5mbigpLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH07XHJcblxyXG4gICAgICAobW9ja0RhdGFTb3VyY2UuY3JlYXRlUXVlcnlSdW5uZXIgYXMgamVzdC5Nb2NrKS5tb2NrUmV0dXJuVmFsdWUoXHJcbiAgICAgICAgcXVlcnlSdW5uZXJcclxuICAgICAgKTtcclxuXHJcbiAgICAgIGF3YWl0IHNlcnZpY2UuY3JlYXRlKGNyZWF0ZUR0bywgbW9ja1VzZXIpO1xyXG5cclxuICAgICAgZXhwZWN0KHF1ZXJ5UnVubmVyLm1hbmFnZXIuY3JlYXRlKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcclxuICAgICAgICBDb3JyZXNwb25kZW5jZVJldmlzaW9uLFxyXG4gICAgICAgIGV4cGVjdC5vYmplY3RDb250YWluaW5nKHsgcmV2aXNpb25MYWJlbDogbnVsbCB9KVxyXG4gICAgICApO1xyXG4gICAgfSk7XHJcbiAgfSk7XHJcbn0pO1xyXG4iXSwidmVyc2lvbiI6M30= \ No newline at end of file diff --git a/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/1a/correspondenceservicespec_1aae7357448442e3b9dacb210cb1a80b.map b/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/1a/correspondenceservicespec_1aae7357448442e3b9dacb210cb1a80b.map new file mode 100644 index 0000000..5afe305 --- /dev/null +++ b/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/1a/correspondenceservicespec_1aae7357448442e3b9dacb210cb1a80b.map @@ -0,0 +1 @@ +{"file":"E:\\np-dms\\lcbp3\\backend\\src\\modules\\correspondence\\correspondence.service.spec.ts","mappings":"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","names":[],"sources":["E:\\np-dms\\lcbp3\\backend\\src\\modules\\correspondence\\correspondence.service.spec.ts"],"sourcesContent":["import { Test, TestingModule } from '@nestjs/testing';\r\nimport { getRepositoryToken } from '@nestjs/typeorm';\r\nimport { DataSource, Repository } from 'typeorm';\r\nimport { CorrespondenceService } from './correspondence.service';\r\nimport { Correspondence } from './entities/correspondence.entity';\r\nimport { CorrespondenceRevision } from './entities/correspondence-revision.entity';\r\nimport { CorrespondenceType } from './entities/correspondence-type.entity';\r\nimport { CorrespondenceStatus } from './entities/correspondence-status.entity';\r\nimport { CorrespondenceReference } from './entities/correspondence-reference.entity';\r\nimport { CorrespondenceTag } from './entities/correspondence-tag.entity';\r\nimport { Organization } from '../organization/entities/organization.entity';\r\nimport { CorrespondenceRecipient } from './entities/correspondence-recipient.entity';\r\nimport { DocumentNumberingService } from '../document-numbering/services/document-numbering.service';\r\nimport { JsonSchemaService } from '../json-schema/json-schema.service';\r\nimport { WorkflowEngineService } from '../workflow-engine/workflow-engine.service';\r\nimport { UserService } from '../user/user.service';\r\nimport { SearchService } from '../search/search.service';\r\nimport { FileStorageService } from '../../common/file-storage/file-storage.service';\r\nimport { UuidResolverService } from '../../common/services/uuid-resolver.service';\r\nimport { NotificationService } from '../notification/notification.service';\r\nimport { UpdateCorrespondenceDto } from './dto/update-correspondence.dto';\r\nimport { CreateCorrespondenceDto } from './dto/create-correspondence.dto';\r\nimport { User } from '../user/entities/user.entity';\r\n\r\ndescribe('CorrespondenceService', () => {\r\n let service: CorrespondenceService;\r\n let numberingService: DocumentNumberingService;\r\n let correspondenceRepo: Repository;\r\n let revisionRepo: Repository;\r\n let testingModule: TestingModule;\r\n let _dataSource: DataSource;\r\n\r\n const createMockRepository = () => ({\r\n find: jest.fn(),\r\n findOne: jest.fn(),\r\n create: jest.fn(),\r\n save: jest.fn(),\r\n update: jest.fn(),\r\n delete: jest.fn(),\r\n softDelete: jest.fn(),\r\n createQueryBuilder: jest.fn(() => ({\r\n leftJoinAndSelect: jest.fn().mockReturnThis(),\r\n where: jest.fn().mockReturnThis(),\r\n andWhere: jest.fn().mockReturnThis(),\r\n orderBy: jest.fn().mockReturnThis(),\r\n skip: jest.fn().mockReturnThis(),\r\n take: jest.fn().mockReturnThis(),\r\n getOne: jest.fn().mockResolvedValue(null),\r\n getMany: jest.fn().mockResolvedValue([]),\r\n getManyAndCount: jest.fn().mockResolvedValue([[], 0]),\r\n })),\r\n });\r\n\r\n const mockDataSource = {\r\n createQueryRunner: jest.fn(() => ({\r\n connect: jest.fn(),\r\n startTransaction: jest.fn(),\r\n commitTransaction: jest.fn(),\r\n rollbackTransaction: jest.fn(),\r\n release: jest.fn(),\r\n manager: {\r\n create: jest.fn(),\r\n save: jest.fn(),\r\n findOne: jest.fn(),\r\n },\r\n })),\r\n getRepository: jest.fn(() => createMockRepository()),\r\n manager: {\r\n findOne: jest.fn(),\r\n },\r\n };\r\n\r\n beforeEach(async () => {\r\n testingModule = await Test.createTestingModule({\r\n providers: [\r\n CorrespondenceService,\r\n {\r\n provide: getRepositoryToken(Correspondence),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: getRepositoryToken(CorrespondenceRevision),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: getRepositoryToken(CorrespondenceType),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: getRepositoryToken(CorrespondenceStatus),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: getRepositoryToken(CorrespondenceReference),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: getRepositoryToken(CorrespondenceTag),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: getRepositoryToken(Organization),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: getRepositoryToken(CorrespondenceRecipient),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: DocumentNumberingService,\r\n useValue: {\r\n generateNextNumber: jest.fn(),\r\n updateNumberForDraft: jest.fn(),\r\n previewNextNumber: jest.fn(),\r\n },\r\n },\r\n {\r\n provide: JsonSchemaService,\r\n useValue: { validate: jest.fn() },\r\n },\r\n {\r\n provide: WorkflowEngineService,\r\n useValue: { createInstance: jest.fn() },\r\n },\r\n {\r\n provide: UserService,\r\n useValue: {\r\n findOne: jest.fn(),\r\n getUserPermissions: jest.fn().mockResolvedValue([]),\r\n },\r\n },\r\n {\r\n provide: DataSource,\r\n useValue: mockDataSource,\r\n },\r\n {\r\n provide: SearchService,\r\n useValue: { indexDocument: jest.fn() },\r\n },\r\n {\r\n provide: FileStorageService,\r\n useValue: { commit: jest.fn().mockResolvedValue([]) },\r\n },\r\n {\r\n provide: UuidResolverService,\r\n useValue: {\r\n resolveProjectId: jest.fn().mockResolvedValue(1),\r\n resolveOrganizationId: jest.fn().mockResolvedValue(1),\r\n },\r\n },\r\n {\r\n provide: NotificationService,\r\n useValue: { send: jest.fn().mockResolvedValue(undefined) },\r\n },\r\n ],\r\n }).compile();\r\n\r\n service = testingModule.get(CorrespondenceService);\r\n numberingService = testingModule.get(\r\n DocumentNumberingService\r\n );\r\n correspondenceRepo = testingModule.get>(\r\n getRepositoryToken(Correspondence)\r\n );\r\n revisionRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceRevision)\r\n );\r\n _dataSource = testingModule.get(DataSource);\r\n });\r\n\r\n it('should be defined', () => {\r\n expect(service).toBeDefined();\r\n });\r\n\r\n describe('update', () => {\r\n it('should NOT regenerate number if critical fields unchanged', async () => {\r\n const mockUser = { id: 1, primaryOrganizationId: 10 } as unknown as User;\r\n const mockRevision = {\r\n id: 100,\r\n correspondenceId: 1,\r\n isCurrent: true,\r\n statusId: 5,\r\n };\r\n\r\n jest\r\n .spyOn(revisionRepo, 'findOne')\r\n .mockResolvedValue(mockRevision as unknown as CorrespondenceRevision);\r\n\r\n const mockCorr = {\r\n id: 1,\r\n projectId: 1,\r\n correspondenceTypeId: 2,\r\n disciplineId: 3,\r\n originatorId: 10,\r\n correspondenceNumber: 'OLD-NUM',\r\n recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }],\r\n };\r\n jest\r\n .spyOn(correspondenceRepo, 'findOne')\r\n .mockResolvedValue(mockCorr as unknown as Correspondence);\r\n\r\n const updateDto: UpdateCorrespondenceDto = {\r\n projectId: 1,\r\n disciplineId: 3,\r\n };\r\n\r\n await service.update(1, updateDto, mockUser);\r\n\r\n expect(\r\n numberingService.updateNumberForDraft as jest.Mock\r\n ).not.toHaveBeenCalled();\r\n });\r\n\r\n it('should regenerate number if Project ID changes', async () => {\r\n const mockUser = { id: 1, primaryOrganizationId: 10 } as unknown as User;\r\n const mockRevision = {\r\n id: 100,\r\n correspondenceId: 1,\r\n isCurrent: true,\r\n statusId: 5,\r\n };\r\n jest\r\n .spyOn(revisionRepo, 'findOne')\r\n .mockResolvedValue(mockRevision as unknown as CorrespondenceRevision);\r\n\r\n const mockCorr = {\r\n id: 1,\r\n projectId: 1,\r\n correspondenceTypeId: 2,\r\n disciplineId: 3,\r\n originatorId: 10,\r\n correspondenceNumber: 'OLD-NUM',\r\n recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }],\r\n };\r\n jest\r\n .spyOn(correspondenceRepo, 'findOne')\r\n .mockResolvedValue(mockCorr as unknown as Correspondence);\r\n\r\n const updateDto: UpdateCorrespondenceDto = {\r\n projectId: 2,\r\n };\r\n\r\n const uuidResolver =\r\n testingModule.get(UuidResolverService);\r\n (uuidResolver.resolveProjectId as jest.Mock).mockResolvedValue(2);\r\n\r\n await service.update(1, updateDto, mockUser);\r\n\r\n expect(\r\n numberingService.updateNumberForDraft as jest.Mock\r\n ).toHaveBeenCalled();\r\n });\r\n\r\n it('should regenerate number if Document Type changes', async () => {\r\n const mockUser = { id: 1, primaryOrganizationId: 10 } as unknown as User;\r\n const mockRevision = {\r\n id: 100,\r\n correspondenceId: 1,\r\n isCurrent: true,\r\n statusId: 5,\r\n };\r\n jest\r\n .spyOn(revisionRepo, 'findOne')\r\n .mockResolvedValue(mockRevision as unknown as CorrespondenceRevision);\r\n\r\n const mockCorr = {\r\n id: 1,\r\n projectId: 1,\r\n correspondenceTypeId: 2,\r\n disciplineId: 3,\r\n originatorId: 10,\r\n correspondenceNumber: 'OLD-NUM',\r\n recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }],\r\n };\r\n jest\r\n .spyOn(correspondenceRepo, 'findOne')\r\n .mockResolvedValue(mockCorr as unknown as Correspondence);\r\n\r\n const updateDto: UpdateCorrespondenceDto = {\r\n typeId: 999,\r\n };\r\n\r\n const typeRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceType)\r\n );\r\n (typeRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 999,\r\n typeCode: 'NEW-TYPE',\r\n });\r\n\r\n await service.update(1, updateDto, mockUser);\r\n\r\n expect(\r\n numberingService.updateNumberForDraft as jest.Mock\r\n ).toHaveBeenCalled();\r\n });\r\n\r\n it('should regenerate number if Recipient Organization changes', async () => {\r\n const mockUser = { id: 1, primaryOrganizationId: 10 } as unknown as User;\r\n const mockRevision = {\r\n id: 100,\r\n correspondenceId: 1,\r\n isCurrent: true,\r\n statusId: 5,\r\n };\r\n jest\r\n .spyOn(revisionRepo, 'findOne')\r\n .mockResolvedValue(mockRevision as unknown as CorrespondenceRevision);\r\n\r\n const mockCorr = {\r\n id: 1,\r\n projectId: 1,\r\n correspondenceTypeId: 2,\r\n disciplineId: 3,\r\n originatorId: 10,\r\n correspondenceNumber: 'OLD-NUM',\r\n recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }],\r\n };\r\n jest\r\n .spyOn(correspondenceRepo, 'findOne')\r\n .mockResolvedValue(mockCorr as unknown as Correspondence);\r\n\r\n // Access DataSource manager for mocking\r\n mockDataSource.manager.findOne.mockResolvedValue({\r\n id: 88,\r\n organizationCode: 'NEW-ORG',\r\n } as unknown as Organization);\r\n\r\n const updateDto: UpdateCorrespondenceDto = {\r\n recipients: [{ type: 'TO', organizationId: 88 }],\r\n };\r\n\r\n await service.update(1, updateDto, mockUser);\r\n\r\n expect(\r\n numberingService.updateNumberForDraft as jest.Mock\r\n ).toHaveBeenCalled();\r\n });\r\n });\r\n\r\n describe('create', () => {\r\n it('should allow system.manage_all user without primaryOrganizationId when originatorId is provided', async () => {\r\n const mockUser = {\r\n user_id: 1,\r\n primaryOrganizationId: null,\r\n } as unknown as User;\r\n\r\n const createDto: CreateCorrespondenceDto = {\r\n projectId: 'project-uuid',\r\n typeId: 1,\r\n subject: 'Test Subject',\r\n originatorId: 'originator-uuid',\r\n recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }],\r\n };\r\n\r\n const userService = testingModule.get(UserService);\r\n const typeRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceType)\r\n );\r\n const statusRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceStatus)\r\n );\r\n const uuidResolver =\r\n testingModule.get(UuidResolverService);\r\n\r\n (userService.findOne as jest.Mock).mockResolvedValue({\r\n user_id: 1,\r\n primaryOrganizationId: null,\r\n });\r\n (userService.getUserPermissions as jest.Mock).mockResolvedValue([\r\n 'system.manage_all',\r\n ]);\r\n\r\n (uuidResolver.resolveProjectId as jest.Mock).mockResolvedValue(100);\r\n (uuidResolver.resolveOrganizationId as jest.Mock).mockImplementation(\r\n (value: number | string) => {\r\n if (value === 'originator-uuid') return 10;\r\n if (value === 'recipient-uuid') return 20;\r\n return 0;\r\n }\r\n );\r\n\r\n (typeRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n typeCode: 'LTR',\r\n });\r\n (statusRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n statusCode: 'DRAFT',\r\n });\r\n\r\n (numberingService.generateNextNumber as jest.Mock).mockResolvedValue({\r\n number: 'DOC-001',\r\n });\r\n\r\n mockDataSource.manager.findOne\r\n .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' })\r\n .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' });\r\n\r\n const queryRunner = {\r\n connect: jest.fn(),\r\n startTransaction: jest.fn(),\r\n commitTransaction: jest.fn(),\r\n rollbackTransaction: jest.fn(),\r\n release: jest.fn(),\r\n manager: {\r\n create: jest.fn(\r\n (_entity: unknown, payload: Record) => payload\r\n ),\r\n save: jest\r\n .fn()\r\n .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' })\r\n .mockResolvedValueOnce({ id: 1000 })\r\n .mockResolvedValueOnce([]),\r\n findOne: jest.fn(),\r\n },\r\n };\r\n\r\n (mockDataSource.createQueryRunner as jest.Mock).mockReturnValue(\r\n queryRunner\r\n );\r\n\r\n await service.create(createDto, mockUser);\r\n\r\n expect(queryRunner.manager.create).toHaveBeenCalledWith(\r\n Correspondence,\r\n expect.objectContaining({ originatorId: 10 })\r\n );\r\n });\r\n\r\n it('should set revisionLabel to \"A\" for RFA type', async () => {\r\n const mockUser = {\r\n user_id: 1,\r\n primaryOrganizationId: 10,\r\n } as unknown as User;\r\n\r\n const createDto: CreateCorrespondenceDto = {\r\n projectId: 'project-uuid',\r\n typeId: 1,\r\n subject: 'Test Subject',\r\n recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }],\r\n };\r\n\r\n const typeRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceType)\r\n );\r\n const statusRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceStatus)\r\n );\r\n const uuidResolver =\r\n testingModule.get(UuidResolverService);\r\n\r\n (uuidResolver.resolveProjectId as jest.Mock).mockResolvedValue(100);\r\n (uuidResolver.resolveOrganizationId as jest.Mock).mockResolvedValue(20);\r\n\r\n (typeRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n typeCode: 'RFA',\r\n });\r\n (statusRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n statusCode: 'DRAFT',\r\n });\r\n\r\n (numberingService.generateNextNumber as jest.Mock).mockResolvedValue({\r\n number: 'DOC-001',\r\n });\r\n\r\n mockDataSource.manager.findOne\r\n .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' })\r\n .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' });\r\n\r\n const queryRunner = {\r\n connect: jest.fn(),\r\n startTransaction: jest.fn(),\r\n commitTransaction: jest.fn(),\r\n rollbackTransaction: jest.fn(),\r\n release: jest.fn(),\r\n manager: {\r\n create: jest.fn(\r\n (_entity: unknown, payload: Record) => payload\r\n ),\r\n save: jest\r\n .fn()\r\n .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' })\r\n .mockResolvedValueOnce({ id: 1000 })\r\n .mockResolvedValueOnce([]),\r\n findOne: jest.fn(),\r\n },\r\n };\r\n\r\n (mockDataSource.createQueryRunner as jest.Mock).mockReturnValue(\r\n queryRunner\r\n );\r\n\r\n await service.create(createDto, mockUser);\r\n\r\n expect(queryRunner.manager.create).toHaveBeenCalledWith(\r\n CorrespondenceRevision,\r\n expect.objectContaining({ revisionLabel: 'A' })\r\n );\r\n });\r\n\r\n it('should set revisionLabel to \"A\" for RFI type', async () => {\r\n const mockUser = {\r\n user_id: 1,\r\n primaryOrganizationId: 10,\r\n } as unknown as User;\r\n\r\n const createDto: CreateCorrespondenceDto = {\r\n projectId: 'project-uuid',\r\n typeId: 1,\r\n subject: 'Test Subject',\r\n recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }],\r\n };\r\n\r\n const typeRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceType)\r\n );\r\n const statusRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceStatus)\r\n );\r\n const uuidResolver =\r\n testingModule.get(UuidResolverService);\r\n\r\n (uuidResolver.resolveProjectId as jest.Mock).mockResolvedValue(100);\r\n (uuidResolver.resolveOrganizationId as jest.Mock).mockResolvedValue(20);\r\n\r\n (typeRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n typeCode: 'RFI',\r\n });\r\n (statusRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n statusCode: 'DRAFT',\r\n });\r\n\r\n (numberingService.generateNextNumber as jest.Mock).mockResolvedValue({\r\n number: 'DOC-001',\r\n });\r\n\r\n mockDataSource.manager.findOne\r\n .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' })\r\n .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' });\r\n\r\n const queryRunner = {\r\n connect: jest.fn(),\r\n startTransaction: jest.fn(),\r\n commitTransaction: jest.fn(),\r\n rollbackTransaction: jest.fn(),\r\n release: jest.fn(),\r\n manager: {\r\n create: jest.fn(\r\n (_entity: unknown, payload: Record) => payload\r\n ),\r\n save: jest\r\n .fn()\r\n .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' })\r\n .mockResolvedValueOnce({ id: 1000 })\r\n .mockResolvedValueOnce([]),\r\n findOne: jest.fn(),\r\n },\r\n };\r\n\r\n (mockDataSource.createQueryRunner as jest.Mock).mockReturnValue(\r\n queryRunner\r\n );\r\n\r\n await service.create(createDto, mockUser);\r\n\r\n expect(queryRunner.manager.create).toHaveBeenCalledWith(\r\n CorrespondenceRevision,\r\n expect.objectContaining({ revisionLabel: 'A' })\r\n );\r\n });\r\n\r\n it('should set revisionLabel to null for LETTER type', async () => {\r\n const mockUser = {\r\n user_id: 1,\r\n primaryOrganizationId: 10,\r\n } as unknown as User;\r\n\r\n const createDto: CreateCorrespondenceDto = {\r\n projectId: 'project-uuid',\r\n typeId: 1,\r\n subject: 'Test Subject',\r\n recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }],\r\n };\r\n\r\n const typeRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceType)\r\n );\r\n const statusRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceStatus)\r\n );\r\n const uuidResolver =\r\n testingModule.get(UuidResolverService);\r\n\r\n (uuidResolver.resolveProjectId as jest.Mock).mockResolvedValue(100);\r\n (uuidResolver.resolveOrganizationId as jest.Mock).mockResolvedValue(20);\r\n\r\n (typeRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n typeCode: 'LETTER',\r\n });\r\n (statusRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n statusCode: 'DRAFT',\r\n });\r\n\r\n (numberingService.generateNextNumber as jest.Mock).mockResolvedValue({\r\n number: 'DOC-001',\r\n });\r\n\r\n mockDataSource.manager.findOne\r\n .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' })\r\n .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' });\r\n\r\n const queryRunner = {\r\n connect: jest.fn(),\r\n startTransaction: jest.fn(),\r\n commitTransaction: jest.fn(),\r\n rollbackTransaction: jest.fn(),\r\n release: jest.fn(),\r\n manager: {\r\n create: jest.fn(\r\n (_entity: unknown, payload: Record) => payload\r\n ),\r\n save: jest\r\n .fn()\r\n .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' })\r\n .mockResolvedValueOnce({ id: 1000 })\r\n .mockResolvedValueOnce([]),\r\n findOne: jest.fn(),\r\n },\r\n };\r\n\r\n (mockDataSource.createQueryRunner as jest.Mock).mockReturnValue(\r\n queryRunner\r\n );\r\n\r\n await service.create(createDto, mockUser);\r\n\r\n expect(queryRunner.manager.create).toHaveBeenCalledWith(\r\n CorrespondenceRevision,\r\n expect.objectContaining({ revisionLabel: undefined })\r\n );\r\n });\r\n\r\n it('should set revisionLabel to null for MEMO type', async () => {\r\n const mockUser = {\r\n user_id: 1,\r\n primaryOrganizationId: 10,\r\n } as unknown as User;\r\n\r\n const createDto: CreateCorrespondenceDto = {\r\n projectId: 'project-uuid',\r\n typeId: 1,\r\n subject: 'Test Subject',\r\n recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }],\r\n };\r\n\r\n const typeRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceType)\r\n );\r\n const statusRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceStatus)\r\n );\r\n const uuidResolver =\r\n testingModule.get(UuidResolverService);\r\n\r\n (uuidResolver.resolveProjectId as jest.Mock).mockResolvedValue(100);\r\n (uuidResolver.resolveOrganizationId as jest.Mock).mockResolvedValue(20);\r\n\r\n (typeRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n typeCode: 'MEMO',\r\n });\r\n (statusRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n statusCode: 'DRAFT',\r\n });\r\n\r\n (numberingService.generateNextNumber as jest.Mock).mockResolvedValue({\r\n number: 'DOC-001',\r\n });\r\n\r\n mockDataSource.manager.findOne\r\n .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' })\r\n .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' });\r\n\r\n const queryRunner = {\r\n connect: jest.fn(),\r\n startTransaction: jest.fn(),\r\n commitTransaction: jest.fn(),\r\n rollbackTransaction: jest.fn(),\r\n release: jest.fn(),\r\n manager: {\r\n create: jest.fn(\r\n (_entity: unknown, payload: Record) => payload\r\n ),\r\n save: jest\r\n .fn()\r\n .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' })\r\n .mockResolvedValueOnce({ id: 1000 })\r\n .mockResolvedValueOnce([]),\r\n findOne: jest.fn(),\r\n },\r\n };\r\n\r\n (mockDataSource.createQueryRunner as jest.Mock).mockReturnValue(\r\n queryRunner\r\n );\r\n\r\n await service.create(createDto, mockUser);\r\n\r\n expect(queryRunner.manager.create).toHaveBeenCalledWith(\r\n CorrespondenceRevision,\r\n expect.objectContaining({ revisionLabel: null })\r\n );\r\n });\r\n });\r\n});\r\n"],"version":3} \ No newline at end of file diff --git a/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/51/correspondenceservice_515ab3b98834c28ddef79ca635837252 b/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/51/correspondenceservice_515ab3b98834c28ddef79ca635837252 new file mode 100644 index 0000000..a97da49 --- /dev/null +++ b/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/51/correspondenceservice_515ab3b98834c28ddef79ca635837252 @@ -0,0 +1,893 @@ +0503e316da84ffb60d9e8eb6e557def9 +"use strict"; +// File: src/modules/correspondence/correspondence.service.ts +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + 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; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var __param = (this && this.__param) || function (paramIndex, decorator) { + return function (target, key) { decorator(target, key, paramIndex); } +}; +var CorrespondenceService_1; +var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.CorrespondenceService = void 0; +const common_1 = require("@nestjs/common"); +const typeorm_1 = require("@nestjs/typeorm"); +const typeorm_2 = require("typeorm"); +// Entities +const correspondence_entity_1 = require("./entities/correspondence.entity"); +const correspondence_revision_entity_1 = require("./entities/correspondence-revision.entity"); +const correspondence_type_entity_1 = require("./entities/correspondence-type.entity"); +const correspondence_status_entity_1 = require("./entities/correspondence-status.entity"); +const correspondence_reference_entity_1 = require("./entities/correspondence-reference.entity"); +const correspondence_recipient_entity_1 = require("./entities/correspondence-recipient.entity"); +const correspondence_tag_entity_1 = require("./entities/correspondence-tag.entity"); +const tag_entity_1 = require("../master/entities/tag.entity"); +const organization_entity_1 = require("../organization/entities/organization.entity"); +// Services +const document_numbering_service_1 = require("../document-numbering/services/document-numbering.service"); +const json_schema_service_1 = require("../json-schema/json-schema.service"); +const workflow_engine_service_1 = require("../workflow-engine/workflow-engine.service"); +const user_service_1 = require("../user/user.service"); +const search_service_1 = require("../search/search.service"); +const file_storage_service_1 = require("../../common/file-storage/file-storage.service"); +const uuid_resolver_service_1 = require("../../common/services/uuid-resolver.service"); +const notification_service_1 = require("../notification/notification.service"); +let CorrespondenceService = CorrespondenceService_1 = class CorrespondenceService { + async hasSystemManageAllPermission(userId) { + const permissions = await this.userService.getUserPermissions(userId); + return permissions.includes('system.manage_all'); + } + /** + * Business Rule: Revision Label Strategy + * - RFA, RFI: Use alphabet starting with 'A' (A, B, C...) + * - Other types (LETTER, MEMO, etc.): Use numeric (null for first, then 1, 2, 3...) + */ + getInitialRevisionLabel(typeCode) { + const alphabetTypes = ['RFA', 'RFI']; + if (alphabetTypes.includes(typeCode.toUpperCase())) { + return 'A'; // Alphabet for RFA, RFI + } + return undefined; // Numeric (no label for revision 0) + } + constructor(correspondenceRepo, revisionRepo, typeRepo, statusRepo, referenceRepo, tagRepo, numberingService, jsonSchemaService, workflowEngine, userService, dataSource, searchService, fileStorageService, uuidResolver, notificationService) { + this.correspondenceRepo = correspondenceRepo; + this.revisionRepo = revisionRepo; + this.typeRepo = typeRepo; + this.statusRepo = statusRepo; + this.referenceRepo = referenceRepo; + this.tagRepo = tagRepo; + this.numberingService = numberingService; + this.jsonSchemaService = jsonSchemaService; + this.workflowEngine = workflowEngine; + this.userService = userService; + this.dataSource = dataSource; + this.searchService = searchService; + this.fileStorageService = fileStorageService; + this.uuidResolver = uuidResolver; + this.notificationService = notificationService; + this.logger = new common_1.Logger(CorrespondenceService_1.name); + } + /** + * Business Rule Validation: EC-CORR-003 - Correspondence to Self + * Prevent external correspondence to same organization + */ + async validateCorrespondenceRecipients(createDto, user) { + // Get user's organization + let userOrgId = user.primaryOrganizationId; + if (!userOrgId) { + const fullUser = await this.userService.findOne(user.user_id); + if (fullUser) { + userOrgId = fullUser.primaryOrganizationId; + } + } + if (!userOrgId) { + if (createDto.originatorId) { + const canManageAll = await this.hasSystemManageAllPermission(user.user_id); + if (canManageAll) { + userOrgId = await this.uuidResolver.resolveOrganizationId(createDto.originatorId); + } + } + if (!userOrgId) { + throw new common_1.BadRequestException('User must belong to an organization to create documents'); + } + } + // For impersonation, use the specified originator + const originatorOrgId = createDto.originatorId + ? await this.uuidResolver.resolveOrganizationId(createDto.originatorId) + : userOrgId; + // Check if it's internal communication + if (createDto.isInternal) { + // Internal communications should use Circulation instead + throw new common_1.BadRequestException('Internal communications should use Circulation Sheet instead of Correspondence'); + } + // Validate recipients + if (!createDto.recipients || createDto.recipients.length === 0) { + throw new common_1.BadRequestException('At least one recipient (TO or CC) is required'); + } + const toRecipients = createDto.recipients.filter((r) => r.type === 'TO'); + const ccRecipients = createDto.recipients.filter((r) => r.type === 'CC'); + if (toRecipients.length === 0 && ccRecipients.length === 0) { + throw new common_1.BadRequestException('At least one TO or CC recipient is required'); + } + // Check for same organization correspondence + for (const recipient of createDto.recipients) { + const recipientOrgId = await this.uuidResolver.resolveOrganizationId(recipient.organizationId); + if (recipientOrgId === originatorOrgId) { + throw new common_1.BadRequestException('Cannot send correspondence to your own organization. Use Circulation Sheet for internal communication.'); + } + } + } + async create(createDto, user) { + // Business Rule Validation: EC-CORR-003 - Correspondence to Self + await this.validateCorrespondenceRecipients(createDto, user); + // ADR-019: Resolve UUID references to internal INT IDs + const resolvedProjectId = await this.uuidResolver.resolveProjectId(createDto.projectId); + const resolvedOriginatorId = createDto.originatorId + ? await this.uuidResolver.resolveOrganizationId(createDto.originatorId) + : undefined; + const resolvedRecipients = createDto.recipients + ? await Promise.all(createDto.recipients.map(async (r) => ({ + organizationId: await this.uuidResolver.resolveOrganizationId(r.organizationId), + type: r.type, + }))) + : undefined; + const type = await this.typeRepo.findOne({ + where: { id: createDto.typeId }, + }); + if (!type) + throw new common_1.NotFoundException('Document Type not found'); + const statusDraft = await this.statusRepo.findOne({ + where: { statusCode: 'DRAFT' }, + }); + if (!statusDraft) { + throw new common_1.InternalServerErrorException('Status DRAFT not found in Master Data'); + } + let userOrgId = user.primaryOrganizationId; + if (!userOrgId) { + const fullUser = await this.userService.findOne(user.user_id); + if (fullUser) { + userOrgId = fullUser.primaryOrganizationId; + } + } + // Impersonation Logic + if (resolvedOriginatorId && resolvedOriginatorId !== userOrgId) { + const canManageAll = await this.hasSystemManageAllPermission(user.user_id); + if (!canManageAll) { + throw new common_1.ForbiddenException('You do not have permission to create documents on behalf of other organizations.'); + } + userOrgId = resolvedOriginatorId; + } + if (!userOrgId) { + throw new common_1.BadRequestException('User must belong to an organization to create documents'); + } + if (createDto.details) { + try { + await this.jsonSchemaService.validate(type.typeCode, createDto.details); + } + catch (error) { + this.logger.warn(`Schema validation warning for ${type.typeCode}: ${error.message}`); + } + } + const queryRunner = this.dataSource.createQueryRunner(); + await queryRunner.connect(); + await queryRunner.startTransaction(); + try { + // [Fix #6] Fetch real ORG Code from Organization entity + const originatorOrg = await this.dataSource.manager.findOne(organization_entity_1.Organization, { + where: { id: userOrgId }, + }); + const orgCode = originatorOrg?.organizationCode ?? 'UNK'; + // [v1.5.1] Extract recipient organization from recipients array (Primary TO) + const toRecipient = resolvedRecipients?.find((r) => r.type === 'TO'); + const recipientOrganizationId = toRecipient?.organizationId; + let recipientCode = ''; + if (recipientOrganizationId) { + const recOrg = await this.dataSource.manager.findOne(organization_entity_1.Organization, { + where: { id: recipientOrganizationId }, + }); + if (recOrg) + recipientCode = recOrg.organizationCode; + } + const docNumber = await this.numberingService.generateNextNumber({ + projectId: resolvedProjectId, + originatorOrganizationId: userOrgId, + typeId: createDto.typeId, + disciplineId: createDto.disciplineId, + subTypeId: createDto.subTypeId, + recipientOrganizationId, // [v1.5.1] Pass recipient for document number format + year: new Date().getFullYear(), + customTokens: { + TYPE_CODE: type.typeCode, + ORG_CODE: orgCode, + RECIPIENT_CODE: recipientCode, + REC_CODE: recipientCode, + }, + }); + const correspondence = queryRunner.manager.create(correspondence_entity_1.Correspondence, { + correspondenceNumber: docNumber.number, + correspondenceTypeId: createDto.typeId, + disciplineId: createDto.disciplineId, + projectId: resolvedProjectId, + originatorId: userOrgId, + isInternal: createDto.isInternal || false, + createdBy: user.user_id, + }); + const savedCorr = await queryRunner.manager.save(correspondence); + const revision = queryRunner.manager.create(correspondence_revision_entity_1.CorrespondenceRevision, { + correspondenceId: savedCorr.id, + revisionNumber: 0, + revisionLabel: this.getInitialRevisionLabel(type.typeCode), + isCurrent: true, + statusId: statusDraft.id, + subject: createDto.subject, + body: createDto.body, + remarks: createDto.remarks, + dueDate: createDto.dueDate ? new Date(createDto.dueDate) : undefined, + documentDate: createDto.documentDate + ? new Date(createDto.documentDate) + : undefined, + issuedDate: createDto.issuedDate + ? new Date(createDto.issuedDate) + : undefined, + receivedDate: createDto.receivedDate + ? new Date(createDto.receivedDate) + : undefined, + description: createDto.description, + details: createDto.details, + createdBy: user.user_id, + schemaVersion: 1, + }); + await queryRunner.manager.save(revision); + // Save Recipients (using resolved INT IDs) + if (resolvedRecipients && resolvedRecipients.length > 0) { + const recipients = resolvedRecipients.map((r) => queryRunner.manager.create(correspondence_recipient_entity_1.CorrespondenceRecipient, { + correspondenceId: savedCorr.id, + recipientOrganizationId: r.organizationId, + recipientType: r.type, + })); + await queryRunner.manager.save(recipients); + } + // Commit attachments from Temp → Permanent (Two-Phase Storage) + if (createDto.attachmentTempIds?.length) { + const issueDate = createDto.issuedDate + ? new Date(createDto.issuedDate) + : createDto.documentDate + ? new Date(createDto.documentDate) + : undefined; + await this.fileStorageService.commit(createDto.attachmentTempIds, { + issueDate, + documentType: 'Correspondence', + }); + } + await queryRunner.commitTransaction(); + // Start Workflow Instance (non-blocking) + try { + const workflowCode = `CORRESPONDENCE_${type.typeCode}`; + await this.workflowEngine.createInstance(workflowCode, 'correspondence', savedCorr.id.toString(), { + projectId: resolvedProjectId, + originatorId: userOrgId, + disciplineId: createDto.disciplineId, + initiatorId: user.user_id, + }); + } + catch (error) { + this.logger.warn(`Workflow not started for ${docNumber.number} (Code: CORRESPONDENCE_${type.typeCode}): ${error.message}`); + } + // Fire-and-forget search indexing (non-blocking, void intentional) + void this.searchService.indexDocument({ + id: savedCorr.id, + publicId: savedCorr.publicId, + type: 'correspondence', + docNumber: docNumber.number, + title: createDto.subject, + description: createDto.description, + status: 'DRAFT', + projectId: resolvedProjectId, + createdAt: new Date(), + }); + return { + ...savedCorr, + currentRevision: revision, + }; + } + catch (err) { + await queryRunner.rollbackTransaction(); + this.logger.error(`Failed to create correspondence: ${err.message}`); + throw err; + } + finally { + await queryRunner.release(); + } + } + async findAll(searchDto = {}) { + const { search, typeId, projectId, statusId, status, page = 1, limit = 10, } = searchDto; + const skip = (page - 1) * limit; + // Change: Query from Revision Repo + const query = this.revisionRepo + .createQueryBuilder('rev') + .leftJoinAndSelect('rev.correspondence', 'corr') + .leftJoinAndSelect('corr.type', 'type') + .leftJoinAndSelect('corr.project', 'project') + .leftJoinAndSelect('corr.originator', 'org') + .leftJoinAndSelect('rev.status', 'status'); + // Filter by Revision Status + const revStatus = searchDto.revisionStatus || 'CURRENT'; + if (revStatus === 'CURRENT') { + query.where('rev.isCurrent = :isCurrent', { isCurrent: true }); + } + else if (revStatus === 'OLD') { + query.where('rev.isCurrent = :isCurrent', { isCurrent: false }); + } + // If 'ALL', no filter needed on isCurrent + if (projectId) { + query.andWhere('corr.projectId = :projectId', { projectId }); + } + if (typeId) { + query.andWhere('corr.correspondenceTypeId = :typeId', { typeId }); + } + if (statusId) { + query.andWhere('rev.statusId = :statusId', { statusId }); + } + if (status) { + query.andWhere('status.statusCode = :status', { status }); + } + if (search) { + query.andWhere('(corr.correspondenceNumber LIKE :search OR rev.subject LIKE :search)', { search: `%${search}%` }); + } + // Default Sort: Latest Created + query.orderBy('rev.createdAt', 'DESC').skip(skip).take(limit); + const [items, total] = await query.getManyAndCount(); + return { + data: items, + meta: { + total, + page, + limit, + totalPages: Math.ceil(total / limit), + }, + }; + } + async findOne(id) { + const correspondence = await this.correspondenceRepo.findOne({ + where: { id }, + relations: [ + 'revisions', + 'revisions.status', + 'type', + 'project', + 'originator', + 'recipients', + 'recipients.recipientOrganization', // [v1.5.1] Fixed relation name + ], + }); + if (!correspondence) { + throw new common_1.NotFoundException(`Correspondence with ID ${id} not found`); + } + return correspondence; + } + async findOneByUuid(publicId) { + const correspondence = await this.correspondenceRepo.findOne({ + where: { publicId }, + relations: [ + 'revisions', + 'revisions.status', + 'type', + 'project', + 'originator', + 'recipients', + 'recipients.recipientOrganization', + ], + }); + if (!correspondence) { + throw new common_1.NotFoundException(`Correspondence with UUID ${publicId} not found`); + } + return correspondence; + } + async addReference(id, dto) { + const source = await this.correspondenceRepo.findOne({ where: { id } }); + // ADR-019: Resolve target publicId → internal INT id + const target = await this.correspondenceRepo.findOne({ + where: { publicId: dto.targetUuid }, + }); + if (!source || !target) { + throw new common_1.NotFoundException('Source or Target correspondence not found'); + } + if (source.id === target.id) { + throw new common_1.BadRequestException('Cannot reference self'); + } + const exists = await this.referenceRepo.findOne({ + where: { + sourceId: id, + targetId: target.id, + }, + }); + if (exists) { + return exists; + } + const ref = this.referenceRepo.create({ + sourceId: id, + targetId: target.id, + }); + return this.referenceRepo.save(ref); + } + async removeReference(id, targetId) { + const result = await this.referenceRepo.delete({ + sourceId: id, + targetId: targetId, + }); + if (result.affected === 0) { + throw new common_1.NotFoundException('Reference not found'); + } + } + async getTags(id) { + const rows = await this.tagRepo.find({ + where: { correspondenceId: id }, + relations: ['tag'], + }); + return rows.map((r) => r.tag).filter(Boolean); + } + async addTag(id, tagId) { + const correspondence = await this.correspondenceRepo.findOne({ + where: { id }, + }); + if (!correspondence) { + throw new common_1.NotFoundException(`Correspondence ${id} not found`); + } + const tag = await this.dataSource.manager.findOne(tag_entity_1.Tag, { + where: { id: tagId }, + }); + if (!tag) { + throw new common_1.NotFoundException(`Tag ${tagId} not found`); + } + const exists = await this.tagRepo.findOne({ + where: { correspondenceId: id, tagId }, + }); + if (exists) + return exists; + const row = this.tagRepo.create({ correspondenceId: id, tagId }); + return this.tagRepo.save(row); + } + async removeTag(id, tagId) { + const result = await this.tagRepo.delete({ correspondenceId: id, tagId }); + if (result.affected === 0) { + throw new common_1.NotFoundException('Tag assignment not found'); + } + } + async getReferences(id) { + const outgoing = await this.referenceRepo.find({ + where: { sourceId: id }, + relations: ['target', 'target.type'], + }); + const incoming = await this.referenceRepo.find({ + where: { targetId: id }, + relations: ['source', 'source.type'], + }); + return { outgoing, incoming }; + } + async update(id, updateDto, user) { + // 1. Find Current Revision + const revision = await this.revisionRepo.findOne({ + where: { + correspondenceId: id, + isCurrent: true, + }, + relations: ['correspondence'], + }); + if (!revision) { + throw new common_1.NotFoundException(`Current revision for correspondence ${id} not found`); + } + // 2. Check Permission + if (revision.statusId) { + const status = await this.statusRepo.findOne({ + where: { id: revision.statusId }, + }); + if (status && status.statusCode !== 'DRAFT') { + throw new common_1.BadRequestException('Only DRAFT documents can be updated'); + } + } + // ADR-019: Resolve UUID references in update DTO + const updResolvedProjectId = updateDto.projectId + ? await this.uuidResolver.resolveProjectId(updateDto.projectId) + : undefined; + const updResolvedOriginatorId = updateDto.originatorId + ? await this.uuidResolver.resolveOrganizationId(updateDto.originatorId) + : undefined; + const updResolvedRecipients = updateDto.recipients + ? await Promise.all(updateDto.recipients.map(async (r) => ({ + organizationId: await this.uuidResolver.resolveOrganizationId(r.organizationId), + type: r.type, + }))) + : undefined; + // 3. Update Correspondence Entity if needed + const correspondenceUpdate = {}; + if (updateDto.disciplineId) + correspondenceUpdate.disciplineId = updateDto.disciplineId; + if (updResolvedProjectId) + correspondenceUpdate.projectId = updResolvedProjectId; + if (updResolvedOriginatorId) + correspondenceUpdate.originatorId = updResolvedOriginatorId; + if (Object.keys(correspondenceUpdate).length > 0) { + await this.correspondenceRepo.update(id, correspondenceUpdate); + } + // 4. Update Revision Entity + const revisionUpdate = {}; + if (updateDto.subject) + revisionUpdate.subject = updateDto.subject; + if (updateDto.body) + revisionUpdate.body = updateDto.body; + if (updateDto.remarks) + revisionUpdate.remarks = updateDto.remarks; + // Format Date correctly if string + if (updateDto.dueDate) + revisionUpdate.dueDate = new Date(updateDto.dueDate); + if (updateDto.documentDate) + revisionUpdate.documentDate = new Date(updateDto.documentDate); + if (updateDto.issuedDate) + revisionUpdate.issuedDate = new Date(updateDto.issuedDate); + if (updateDto.receivedDate) + revisionUpdate.receivedDate = new Date(updateDto.receivedDate); + if (updateDto.description) + revisionUpdate.description = updateDto.description; + if (updateDto.details) + revisionUpdate.details = updateDto.details; + if (Object.keys(revisionUpdate).length > 0) { + await this.revisionRepo.update(revision.id, revisionUpdate); + } + // 4.5 Commit new attachments from Temp → Permanent (Two-Phase Storage) + if (updateDto.attachmentTempIds?.length) { + const issueDate = updateDto.issuedDate + ? new Date(updateDto.issuedDate) + : updateDto.documentDate + ? new Date(updateDto.documentDate) + : revision.issuedDate || revision.documentDate || undefined; + await this.fileStorageService.commit(updateDto.attachmentTempIds, { + issueDate: issueDate ? new Date(issueDate) : undefined, + documentType: 'Correspondence', + }); + } + // 5. Update Recipients if provided + if (updResolvedRecipients) { + const recipientRepo = this.dataSource.getRepository(correspondence_recipient_entity_1.CorrespondenceRecipient); + await recipientRepo.delete({ correspondenceId: id }); + const newRecipients = updResolvedRecipients.map((r) => recipientRepo.create({ + correspondenceId: id, + recipientOrganizationId: r.organizationId, + recipientType: r.type, + })); + await recipientRepo.save(newRecipients); + } + // 6. Regenerate Document Number if structural fields changed (Recipient, Discipline, Type, Project) + // AND it is a DRAFT. + // Fetch fresh data for context and comparison + const currentCorr = await this.correspondenceRepo.findOne({ + where: { id }, + relations: ['type', 'recipients', 'recipients.recipientOrganization'], + }); + if (currentCorr) { + const currentToRecipient = currentCorr.recipients?.find((r) => r.recipientType === 'TO'); + const currentRecipientId = currentToRecipient?.recipientOrganizationId; + // Check for ACTUAL value changes + const isProjectChanged = updResolvedProjectId !== undefined && + updResolvedProjectId !== currentCorr.projectId; + const isOriginatorChanged = updResolvedOriginatorId !== undefined && + updResolvedOriginatorId !== currentCorr.originatorId; + const isDisciplineChanged = updateDto.disciplineId !== undefined && + updateDto.disciplineId !== currentCorr.disciplineId; + const isTypeChanged = updateDto.typeId !== undefined && + updateDto.typeId !== currentCorr.correspondenceTypeId; + let isRecipientChanged = false; + let newRecipientId; + if (updResolvedRecipients) { + const newToRecipient = updResolvedRecipients.find((r) => r.type === 'TO'); + newRecipientId = newToRecipient?.organizationId; + if (newRecipientId !== currentRecipientId) { + isRecipientChanged = true; + } + } + if (isProjectChanged || + isDisciplineChanged || + isTypeChanged || + isRecipientChanged || + isOriginatorChanged) { + const targetRecipientId = isRecipientChanged + ? newRecipientId + : currentRecipientId; + // Resolve Recipient Code for the NEW context + let recipientCode = ''; + if (targetRecipientId) { + const recOrg = await this.dataSource.manager.findOne(organization_entity_1.Organization, { + where: { id: targetRecipientId }, + }); + if (recOrg) + recipientCode = recOrg.organizationCode; + } + // [Fix #6] Fetch real ORG Code from originator organization + const originatorOrgForUpdate = await this.dataSource.manager.findOne(organization_entity_1.Organization, { + where: { + id: updResolvedOriginatorId ?? currentCorr.originatorId ?? 0, + }, + }); + const orgCode = originatorOrgForUpdate?.organizationCode ?? 'UNK'; + // Prepare Contexts + const oldCtx = { + projectId: currentCorr.projectId, + originatorOrganizationId: currentCorr.originatorId ?? 0, + typeId: currentCorr.correspondenceTypeId, + disciplineId: currentCorr.disciplineId, + recipientOrganizationId: currentRecipientId, + year: new Date().getFullYear(), + }; + const newCtx = { + projectId: updResolvedProjectId ?? currentCorr.projectId, + originatorOrganizationId: updResolvedOriginatorId ?? currentCorr.originatorId ?? 0, + typeId: updateDto.typeId ?? currentCorr.correspondenceTypeId, + disciplineId: updateDto.disciplineId ?? currentCorr.disciplineId, + recipientOrganizationId: targetRecipientId, + year: new Date().getFullYear(), + userId: user.user_id, // Pass User ID for Audit + customTokens: { + TYPE_CODE: currentCorr.type?.typeCode || '', + ORG_CODE: orgCode, + RECIPIENT_CODE: recipientCode, + REC_CODE: recipientCode, + }, + }; + // If Type Changed, need NEW Type Code + if (isTypeChanged) { + const newType = await this.typeRepo.findOne({ + where: { id: newCtx.typeId }, + }); + if (newType) + newCtx.customTokens.TYPE_CODE = newType.typeCode; + } + const newDocNumber = await this.numberingService.updateNumberForDraft(currentCorr.correspondenceNumber, oldCtx, newCtx); + await this.correspondenceRepo.update(id, { + correspondenceNumber: newDocNumber, + }); + } + } + const updated = await this.findOne(id); + // Re-index updated document in Elasticsearch (fire-and-forget) + void this.searchService.indexDocument({ + id: updated.id, + publicId: updated.publicId, + type: 'correspondence', + docNumber: updated.correspondenceNumber, + title: updateDto.subject ?? updated.revisions?.[0]?.subject, + description: updateDto.description ?? updated.revisions?.[0]?.description, + status: 'DRAFT', + projectId: updated.projectId, + createdAt: updated.createdAt, + }); + return updated; + } + async previewDocumentNumber(createDto, user) { + // ADR-019: Resolve UUID references + const previewProjectId = await this.uuidResolver.resolveProjectId(createDto.projectId); + const previewOriginatorId = createDto.originatorId + ? await this.uuidResolver.resolveOrganizationId(createDto.originatorId) + : undefined; + const previewRecipients = createDto.recipients + ? await Promise.all(createDto.recipients.map(async (r) => ({ + organizationId: await this.uuidResolver.resolveOrganizationId(r.organizationId), + type: r.type, + }))) + : undefined; + const type = await this.typeRepo.findOne({ + where: { id: createDto.typeId }, + }); + if (!type) + throw new common_1.NotFoundException('Document Type not found'); + let userOrgId = user.primaryOrganizationId; + if (!userOrgId) { + const fullUser = await this.userService.findOne(user.user_id); + if (fullUser) + userOrgId = fullUser.primaryOrganizationId; + } + if (previewOriginatorId && previewOriginatorId !== userOrgId) { + // Allow impersonation for preview + userOrgId = previewOriginatorId; + } + // Extract recipient from recipients array + const toRecipient = previewRecipients?.find((r) => r.type === 'TO'); + const recipientOrganizationId = toRecipient?.organizationId; + let recipientCode = ''; + if (recipientOrganizationId) { + const recOrg = await this.dataSource.manager.findOne(organization_entity_1.Organization, { + where: { id: recipientOrganizationId }, + }); + if (recOrg) + recipientCode = recOrg.organizationCode; + } + return this.numberingService.previewNumber({ + projectId: previewProjectId, + originatorOrganizationId: userOrgId, + typeId: createDto.typeId, + disciplineId: createDto.disciplineId, + subTypeId: createDto.subTypeId, + recipientOrganizationId, + year: new Date().getFullYear(), + customTokens: { + TYPE_CODE: type.typeCode, + RECIPIENT_CODE: recipientCode, + REC_CODE: recipientCode, + }, + }); + } + /** + * Business Rule Implementation: EC-CORR-001 - Cancel Correspondence with Downstream Circulation + * Cancel correspondence and handle related circulations + */ + async cancel(publicId, reason, user) { + const correspondence = await this.findOneByUuid(publicId); + // Check if user has permission to cancel (Org Admin or Superadmin only) + const permissions = await this.userService.getUserPermissions(user.user_id); + const canCancel = permissions.includes('correspondence.cancel') || + permissions.includes('system.manage_all'); + if (!canCancel) { + throw new common_1.ForbiddenException('Only administrators can cancel correspondences'); + } + // Check if there are any active circulations + const circulationRepo = this.dataSource.getRepository('Circulation'); + const activeCirculations = await circulationRepo.find({ + where: { + correspondenceId: correspondence.id, + status: 'OPEN', + }, + }); + const warningMessage = activeCirculations.length > 0 + ? `There are ${activeCirculations.length} active circulation(s) for this correspondence. Canceling will force close all related circulations.` + : ''; + // Get the current revision to update status + const currentRevision = await this.revisionRepo.findOne({ + where: { + correspondenceId: correspondence.id, + isCurrent: true, + }, + }); + if (!currentRevision) { + throw new common_1.NotFoundException('Current revision not found'); + } + // Get cancelled status + const cancelledStatus = await this.statusRepo.findOne({ + where: { statusCode: 'CANCELLED' }, + }); + if (!cancelledStatus) { + throw new common_1.InternalServerErrorException('CANCELLED status not found'); + } + const queryRunner = this.dataSource.createQueryRunner(); + await queryRunner.connect(); + await queryRunner.startTransaction(); + try { + // Update correspondence revision status to CANCELLED + await queryRunner.manager.update(correspondence_revision_entity_1.CorrespondenceRevision, currentRevision.id, { + statusId: cancelledStatus.id, + remarks: `Cancelled: ${reason}`, + }); + // Force close all active circulations + if (activeCirculations.length > 0) { + await queryRunner.manager.update('Circulation', { + correspondenceId: correspondence.id, + status: 'OPEN', + }, { + status: 'FORCE_CLOSED', + closedAt: new Date(), + closedBy: user.user_id, + closeReason: `Correspondence cancelled: ${reason}`, + }); + } + await queryRunner.commitTransaction(); + // Re-index cancelled status in Elasticsearch (fire-and-forget) + void this.searchService.indexDocument({ + id: correspondence.id, + publicId: correspondence.publicId, + type: 'correspondence', + docNumber: correspondence.correspondenceNumber, + title: currentRevision.subject, + status: 'CANCELLED', + projectId: correspondence.projectId, + createdAt: correspondence.createdAt, + }); + // Notify originator's doc-control user about cancellation (fire-and-forget) + if (correspondence.originatorId) { + void this.userService + .findDocControlIdByOrg(correspondence.originatorId) + .then((targetUserId) => { + if (targetUserId) { + void this.notificationService.send({ + userId: targetUserId, + title: 'Correspondence Cancelled', + message: `${correspondence.correspondenceNumber} — ${currentRevision.subject} has been cancelled. Reason: ${reason}`, + type: 'EMAIL', + entityType: 'correspondence', + entityId: correspondence.id, + link: `/correspondences/${correspondence.publicId}`, + }); + } + }) + .catch((err) => this.logger.warn(`Cancel notification failed: ${err.message}`)); + } + return { + success: true, + message: warningMessage || 'Correspondence cancelled successfully', + activeCirculationsCount: activeCirculations.length, + }; + } + catch (error) { + await queryRunner.rollbackTransaction(); + this.logger.error(`Failed to cancel correspondence: ${error.message}`); + throw error; + } + finally { + await queryRunner.release(); + } + } + async bulkCancel(publicIds, reason, user) { + const succeeded = []; + const failed = []; + for (const publicId of publicIds) { + try { + await this.cancel(publicId, reason, user); + succeeded.push(publicId); + } + catch { + failed.push(publicId); + } + } + return { succeeded, failed }; + } + async exportCsv(searchDto) { + const { data } = await this.findAll(searchDto); + const header = [ + 'Document No.', + 'Rev', + 'Subject', + 'Type', + 'Status', + 'Project', + 'From', + 'Due Date', + 'Created At', + ]; + const rows = data.map((rev) => { + const corr = rev.correspondence ?? rev; + return [ + this.escapeCsv(corr.correspondenceNumber ?? ''), + this.escapeCsv(rev.revisionLabel ?? String(rev.revisionNumber ?? 0)), + this.escapeCsv(rev.subject ?? ''), + this.escapeCsv(corr.type?.typeCode ?? ''), + this.escapeCsv(rev.status?.statusCode ?? ''), + this.escapeCsv(corr.project?.projectCode ?? ''), + this.escapeCsv(corr.originator?.organizationCode ?? ''), + rev.dueDate ? new Date(rev.dueDate).toISOString().split('T')[0] : '', + new Date(rev.createdAt).toISOString().split('T')[0], + ].join(','); + }); + return [header.join(','), ...rows].join('\n'); + } + escapeCsv(value) { + if (value.includes(',') || value.includes('"') || value.includes('\n')) { + return `"${value.replace(/"/g, '""')}"`; + } + return value; + } +}; +exports.CorrespondenceService = CorrespondenceService; +exports.CorrespondenceService = CorrespondenceService = CorrespondenceService_1 = __decorate([ + (0, common_1.Injectable)(), + __param(0, (0, typeorm_1.InjectRepository)(correspondence_entity_1.Correspondence)), + __param(1, (0, typeorm_1.InjectRepository)(correspondence_revision_entity_1.CorrespondenceRevision)), + __param(2, (0, typeorm_1.InjectRepository)(correspondence_type_entity_1.CorrespondenceType)), + __param(3, (0, typeorm_1.InjectRepository)(correspondence_status_entity_1.CorrespondenceStatus)), + __param(4, (0, typeorm_1.InjectRepository)(correspondence_reference_entity_1.CorrespondenceReference)), + __param(5, (0, typeorm_1.InjectRepository)(correspondence_tag_entity_1.CorrespondenceTag)), + __metadata("design:paramtypes", [typeof (_a = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _a : Object, typeof (_b = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _b : Object, typeof (_c = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _c : Object, typeof (_d = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _d : Object, typeof (_e = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _e : Object, typeof (_f = typeof typeorm_2.Repository !== "undefined" && typeorm_2.Repository) === "function" ? _f : Object, typeof (_g = typeof document_numbering_service_1.DocumentNumberingService !== "undefined" && document_numbering_service_1.DocumentNumberingService) === "function" ? _g : Object, typeof (_h = typeof json_schema_service_1.JsonSchemaService !== "undefined" && json_schema_service_1.JsonSchemaService) === "function" ? _h : Object, typeof (_j = typeof workflow_engine_service_1.WorkflowEngineService !== "undefined" && workflow_engine_service_1.WorkflowEngineService) === "function" ? _j : Object, typeof (_k = typeof user_service_1.UserService !== "undefined" && user_service_1.UserService) === "function" ? _k : Object, typeof (_l = typeof typeorm_2.DataSource !== "undefined" && typeorm_2.DataSource) === "function" ? _l : Object, typeof (_m = typeof search_service_1.SearchService !== "undefined" && search_service_1.SearchService) === "function" ? _m : Object, typeof (_o = typeof file_storage_service_1.FileStorageService !== "undefined" && file_storage_service_1.FileStorageService) === "function" ? _o : Object, typeof (_p = typeof uuid_resolver_service_1.UuidResolverService !== "undefined" && uuid_resolver_service_1.UuidResolverService) === "function" ? _p : Object, typeof (_q = typeof notification_service_1.NotificationService !== "undefined" && notification_service_1.NotificationService) === "function" ? _q : Object]) +], CorrespondenceService); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJmaWxlIjoiRTpcXG5wLWRtc1xcbGNicDNcXGJhY2tlbmRcXHNyY1xcbW9kdWxlc1xcY29ycmVzcG9uZGVuY2VcXGNvcnJlc3BvbmRlbmNlLnNlcnZpY2UudHMiLCJtYXBwaW5ncyI6IjtBQUFBLDZEQUE2RDs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFN0QsMkNBT3dCO0FBQ3hCLDZDQUFtRDtBQUNuRCxxQ0FBaUQ7QUFFakQsV0FBVztBQUNYLDRFQUFrRTtBQUNsRSw4RkFBbUY7QUFDbkYsc0ZBQTJFO0FBQzNFLDBGQUErRTtBQUMvRSxnR0FBcUY7QUFDckYsZ0dBQXFGO0FBQ3JGLG9GQUF5RTtBQUN6RSw4REFBb0Q7QUFFcEQsc0ZBQTRFO0FBUTVFLFdBQVc7QUFDWCwwR0FBcUc7QUFDckcsNEVBQXVFO0FBQ3ZFLHdGQUFtRjtBQUNuRix1REFBbUQ7QUFDbkQsNkRBQXlEO0FBQ3pELHlGQUFvRjtBQUNwRix1RkFBa0Y7QUFDbEYsK0VBQTJFO0FBVXBFLElBQU0scUJBQXFCLDZCQUEzQixNQUFNLHFCQUFxQjtJQUd4QixLQUFLLENBQUMsNEJBQTRCLENBQUMsTUFBYztRQUN2RCxNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdEUsT0FBTyxXQUFXLENBQUMsUUFBUSxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFDbkQsQ0FBQztJQUVEOzs7O09BSUc7SUFDSyx1QkFBdUIsQ0FBQyxRQUFnQjtRQUM5QyxNQUFNLGFBQWEsR0FBRyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNyQyxJQUFJLGFBQWEsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLFdBQVcsRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUNuRCxPQUFPLEdBQUcsQ0FBQyxDQUFDLHdCQUF3QjtRQUN0QyxDQUFDO1FBQ0QsT0FBTyxTQUFTLENBQUMsQ0FBQyxvQ0FBb0M7SUFDeEQsQ0FBQztJQUVELFlBRUUsa0JBQXNELEVBRXRELFlBQXdELEVBRXhELFFBQWdELEVB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QUFDLENBQUE7SUFFaEMsV0FBQSxJQUFBLDBCQUFnQixFQUFDLHVEQUFzQixDQUFDLENBQUE7SUFFeEMsV0FBQSxJQUFBLDBCQUFnQixFQUFDLCtDQUFrQixDQUFDLENBQUE7SUFFcEMsV0FBQSxJQUFBLDBCQUFnQixFQUFDLG1EQUFvQixDQUFDLENBQUE7SUFFdEMsV0FBQSxJQUFBLDBCQUFnQixFQUFDLHlEQUF1QixDQUFDLENBQUE7SUFFekMsV0FBQSxJQUFBLDBCQUFnQixFQUFDLDZDQUFpQixDQUFDLENBQUE7eURBVFIsb0JBQVUsb0JBQVYsb0JBQVUsb0RBRWhCLG9CQUFVLG9CQUFWLG9CQUFVLG9EQUVkLG9CQUFVLG9CQUFWLG9CQUFVLG9EQUVSLG9CQUFVLG9CQUFWLG9CQUFVLG9EQUVQLG9CQUFVLG9CQUFWLG9CQUFVLG9EQUVoQixvQkFBVSxvQkFBVixvQkFBVSxvREFDRCxxREFBd0Isb0JBQXhCLHFEQUF3QixvREFDdkIsdUNBQWlCLG9CQUFqQix1Q0FBaUIsb0RBQ3BCLCtDQUFxQixvQkFBckIsK0NBQXFCLG9EQUN4QiwwQkFBVyxvQkFBWCwwQkFBVyxvREFDWixvQkFBVSxvQkFBVixvQkFBVSxvREFDUCw4QkFBYSxvQkFBYiw4QkFBYSxvREFDUix5Q0FBa0Isb0JBQWxCLHlDQUFrQixvREFDeEIsMkNBQW1CLG9CQUFuQiwyQ0FBbUIsb0RBQ1osMENBQW1CLG9CQUFuQiwwQ0FBbUI7R0ExQ3ZDLHFCQUFxQixDQWtqQ2pDIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIkU6XFxucC1kbXNcXGxjYnAzXFxiYWNrZW5kXFxzcmNcXG1vZHVsZXNcXGNvcnJlc3BvbmRlbmNlXFxjb3JyZXNwb25kZW5jZS5zZXJ2aWNlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIEZpbGU6IHNyYy9tb2R1bGVzL2NvcnJlc3BvbmRlbmNlL2NvcnJlc3BvbmRlbmNlLnNlcnZpY2UudHNcclxuXHJcbmltcG9ydCB7XHJcbiAgSW5qZWN0YWJsZSxcclxuICBOb3RGb3VuZEV4Y2VwdGlvbixcclxuICBCYWRSZXF1ZXN0RXhjZXB0aW9uLFxyXG4gIEludGVybmFsU2VydmVyRXJyb3JFeGNlcHRpb24sXHJcbiAgRm9yYmlkZGVuRXhjZXB0aW9uLFxyXG4gIExvZ2dlcixcclxufSBmcm9tICdAbmVzdGpzL2NvbW1vbic7XHJcbmltcG9ydCB7IEluamVjdFJlcG9zaXRvcnkgfSBmcm9tICdAbmVzdGpzL3R5cGVvcm0nO1xyXG5pbXBvcnQgeyBSZXBvc2l0b3J5LCBEYXRhU291cmNlIH0gZnJvbSAndHlwZW9ybSc7XHJcblxyXG4vLyBFbnRpdGllc1xyXG5pbXBvcnQgeyBDb3JyZXNwb25kZW5jZSB9IGZyb20gJy4vZW50aXRpZXMvY29ycmVzcG9uZGVuY2UuZW50aXR5JztcclxuaW1wb3J0IHsgQ29ycmVzcG9uZGVuY2VSZXZpc2lvbiB9IGZyb20gJy4vZW50aXRpZXMvY29ycmVzcG9uZGVuY2UtcmV2aXNpb24uZW50aXR5JztcclxuaW1wb3J0IHsgQ29ycmVzcG9uZGVuY2VUeXBlIH0gZnJvbSAnLi9lbnRpdGllcy9jb3JyZXNwb25kZW5jZS10eXBlLmVudGl0eSc7XHJcbmltcG9ydCB7IENvcnJlc3BvbmRlbmNlU3RhdHVzIH0gZnJvbSAnLi9lbnRpdGllcy9jb3JyZXNwb25kZW5jZS1zdGF0dXMuZW50aXR5JztcclxuaW1wb3J0IHsgQ29ycmVzcG9uZGVuY2VSZWZlcmVuY2UgfSBmcm9tICcuL2VudGl0aWVzL2NvcnJlc3BvbmRlbmNlLXJlZmVyZW5jZS5lbnRpdHknO1xyXG5pbXBvcnQgeyBDb3JyZXNwb25kZW5jZVJlY2lwaWVudCB9IGZyb20gJy4vZW50aXRpZXMvY29ycmVzcG9uZGVuY2UtcmVjaXBpZW50LmVudGl0eSc7XHJcbmltcG9ydCB7IENvcnJlc3BvbmRlbmNlVGFnIH0gZnJvbSAnLi9lbnRpdGllcy9jb3JyZXNwb25kZW5jZS10YWcuZW50aXR5JztcclxuaW1wb3J0IHsgVGFnIH0gZnJvbSAnLi4vbWFzdGVyL2VudGl0aWVzL3RhZy5lbnRpdHknO1xyXG5pbXBvcnQgeyBVc2VyIH0gZnJvbSAnLi4vdXNlci9lbnRpdGllcy91c2VyLmVudGl0eSc7XHJcbmltcG9ydCB7IE9yZ2FuaXphdGlvbiB9IGZyb20gJy4uL29yZ2FuaXphdGlvbi9lbnRpdGllcy9vcmdhbml6YXRpb24uZW50aXR5JztcclxuXHJcbi8vIERUT3NcclxuaW1wb3J0IHsgQ3JlYXRlQ29ycmVzcG9uZGVuY2VEdG8gfSBmcm9tICcuL2R0by9jcmVhdGUtY29ycmVzcG9uZGVuY2UuZHRvJztcclxuaW1wb3J0IHsgVXBkYXRlQ29ycmVzcG9uZGVuY2VEdG8gfSBmcm9tICcuL2R0by91cGRhdGUtY29ycmVzcG9uZGVuY2UuZHRvJztcclxuaW1wb3J0IHsgQWRkUmVmZXJlbmNlRHRvIH0gZnJvbSAnLi9kdG8vYWRkLXJlZmVyZW5jZS5kdG8nO1xyXG5pbXBvcnQgeyBTZWFyY2hDb3JyZXNwb25kZW5jZUR0byB9IGZyb20gJy4vZHRvL3NlYXJjaC1jb3JyZXNwb25kZW5jZS5kdG8nO1xyXG5cclxuLy8gU2VydmljZXNcclxuaW1wb3J0IHsgRG9jdW1lbnROdW1iZXJpbmdTZXJ2aWNlIH0gZnJvbSAnLi4vZG9jdW1lbnQtbnVtYmVyaW5nL3NlcnZpY2VzL2RvY3VtZW50LW51bWJlcmluZy5zZXJ2aWNlJztcclxuaW1wb3J0IHsgSnNvblNjaGVtYVNlcnZpY2UgfSBmcm9tICcuLi9qc29uLXNjaGVtYS9qc29uLXNjaGVtYS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgV29ya2Zsb3dFbmdpbmVTZXJ2aWNlIH0gZnJvbSAnLi4vd29ya2Zsb3ctZW5naW5lL3dvcmtmbG93LWVuZ2luZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgVXNlclNlcnZpY2UgfSBmcm9tICcuLi91c2VyL3VzZXIuc2VydmljZSc7XHJcbmltcG9ydCB7IFNlYXJjaFNlcnZpY2UgfSBmcm9tICcuLi9zZWFyY2gvc2VhcmNoLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBGaWxlU3RvcmFnZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9jb21tb24vZmlsZS1zdG9yYWdlL2ZpbGUtc3RvcmFnZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgVXVpZFJlc29sdmVyU2VydmljZSB9IGZyb20gJy4uLy4uL2NvbW1vbi9zZXJ2aWNlcy91dWlkLXJlc29sdmVyLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBOb3RpZmljYXRpb25TZXJ2aWNlIH0gZnJvbSAnLi4vbm90aWZpY2F0aW9uL25vdGlmaWNhdGlvbi5zZXJ2aWNlJztcclxuXHJcbi8qKlxyXG4gKiBDb3JyZXNwb25kZW5jZVNlcnZpY2UgLSBEb2N1bWVudCBtYW5hZ2VtZW50IChDUlVEKVxyXG4gKi9cclxuaW50ZXJmYWNlIFJlc29sdmVkUmVjaXBpZW50IHtcclxuICBvcmdhbml6YXRpb25JZDogbnVtYmVyO1xyXG4gIHR5cGU6ICdUTycgfCAnQ0MnO1xyXG59XHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIENvcnJlc3BvbmRlbmNlU2VydmljZSB7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBsb2dnZXIgPSBuZXcgTG9nZ2VyKENvcnJlc3BvbmRlbmNlU2VydmljZS5uYW1lKTtcclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBoYXNTeXN0ZW1NYW5hZ2VBbGxQZXJtaXNzaW9uKHVzZXJJZDogbnVtYmVyKTogUHJvbWlzZTxib29sZWFuPiB7XHJcbiAgICBjb25zdCBwZXJtaXNzaW9ucyA9IGF3YWl0IHRoaXMudXNlclNlcnZpY2UuZ2V0VXNlclBlcm1pc3Npb25zKHVzZXJJZCk7XHJcbiAgICByZXR1cm4gcGVybWlzc2lvbnMuaW5jbHVkZXMoJ3N5c3RlbS5tYW5hZ2VfYWxsJyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBCdXNpbmVzcyBSdWxlOiBSZXZpc2lvbiBMYWJlbCBTdHJhdGVneVxyXG4gICAqIC0gUkZBLCBSRkk6IFVzZSBhbHBoYWJldCBzdGFydGluZyB3aXRoICdBJyAoQSwgQiwgQy4uLilcclxuICAgKiAtIE90aGVyIHR5cGVzIChMRVRURVIsIE1FTU8sIGV0Yy4pOiBVc2UgbnVtZXJpYyAobnVsbCBmb3IgZmlyc3QsIHRoZW4gMSwgMiwgMy4uLilcclxuICAgKi9cclxuICBwcml2YXRlIGdldEluaXRpYWxSZXZpc2lvbkxhYmVsKHR5cGVDb2RlOiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xyXG4gICAgY29uc3QgYWxwaGFiZXRUeXBlcyA9IFsnUkZBJywgJ1JGSSddO1xyXG4gICAgaWYgKGFscGhhYmV0VHlwZXMuaW5jbHVkZXModHlwZUNvZGUudG9VcHBlckNhc2UoKSkpIHtcclxuICAgICAgcmV0dXJuICdBJzsgLy8gQWxwaGFiZXQgZm9yIFJGQSwgUkZJXHJcbiAgICB9XHJcbiAgICByZXR1cm4gdW5kZWZpbmVkOyAvLyBOdW1lcmljIChubyBsYWJlbCBmb3IgcmV2aXNpb24gMClcclxuICB9XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgQEluamVjdFJlcG9zaXRvcnkoQ29ycmVzcG9uZGVuY2UpXHJcbiAgICBwcml2YXRlIGNvcnJlc3BvbmRlbmNlUmVwbzogUmVwb3NpdG9yeTxDb3JyZXNwb25kZW5jZT4sXHJcbiAgICBASW5qZWN0UmVwb3NpdG9yeShDb3JyZXNwb25kZW5jZVJldmlzaW9uKVxyXG4gICAgcHJpdmF0ZSByZXZpc2lvblJlcG86IFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2VSZXZpc2lvbj4sXHJcbiAgICBASW5qZWN0UmVwb3NpdG9yeShDb3JyZXNwb25kZW5jZVR5cGUpXHJcbiAgICBwcml2YXRlIHR5cGVSZXBvOiBSZXBvc2l0b3J5PENvcnJlc3BvbmRlbmNlVHlwZT4sXHJcbiAgICBASW5qZWN0UmVwb3NpdG9yeShDb3JyZXNwb25kZW5jZVN0YXR1cylcclxuICAgIHByaXZhdGUgc3RhdHVzUmVwbzogUmVwb3NpdG9yeTxDb3JyZXNwb25kZW5jZVN0YXR1cz4sXHJcbiAgICBASW5qZWN0UmVwb3NpdG9yeShDb3JyZXNwb25kZW5jZVJlZmVyZW5jZSlcclxuICAgIHByaXZhdGUgcmVmZXJlbmNlUmVwbzogUmVwb3NpdG9yeTxDb3JyZXNwb25kZW5jZVJlZmVyZW5jZT4sXHJcbiAgICBASW5qZWN0UmVwb3NpdG9yeShDb3JyZXNwb25kZW5jZVRhZylcclxuICAgIHByaXZhdGUgdGFnUmVwbzogUmVwb3NpdG9yeTxDb3JyZXNwb25kZW5jZVRhZz4sXHJcbiAgICBwcml2YXRlIG51bWJlcmluZ1NlcnZpY2U6IERvY3VtZW50TnVtYmVyaW5nU2VydmljZSxcclxuICAgIHByaXZhdGUganNvblNjaGVtYVNlcnZpY2U6IEpzb25TY2hlbWFTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSB3b3JrZmxvd0VuZ2luZTogV29ya2Zsb3dFbmdpbmVTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSB1c2VyU2VydmljZTogVXNlclNlcnZpY2UsXHJcbiAgICBwcml2YXRlIGRhdGFTb3VyY2U6IERhdGFTb3VyY2UsXHJcbiAgICBwcml2YXRlIHNlYXJjaFNlcnZpY2U6IFNlYXJjaFNlcnZpY2UsXHJcbiAgICBwcml2YXRlIGZpbGVTdG9yYWdlU2VydmljZTogRmlsZVN0b3JhZ2VTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSB1dWlkUmVzb2x2ZXI6IFV1aWRSZXNvbHZlclNlcnZpY2UsXHJcbiAgICBwcml2YXRlIG5vdGlmaWNhdGlvblNlcnZpY2U6IE5vdGlmaWNhdGlvblNlcnZpY2VcclxuICApIHt9XHJcblxyXG4gIC8qKlxyXG4gICAqIEJ1c2luZXNzIFJ1bGUgVmFsaWRhdGlvbjogRUMtQ09SUi0wMDMgLSBDb3JyZXNwb25kZW5jZSB0byBTZWxmXHJcbiAgICogUHJldmVudCBleHRlcm5hbCBjb3JyZXNwb25kZW5jZSB0byBzYW1lIG9yZ2FuaXphdGlvblxyXG4gICAqL1xyXG4gIHByaXZhdGUgYXN5bmMgdmFsaWRhdGVDb3JyZXNwb25kZW5jZVJlY2lwaWVudHMoXHJcbiAgICBjcmVhdGVEdG86IENyZWF0ZUNvcnJlc3BvbmRlbmNlRHRvLFxyXG4gICAgdXNlcjogVXNlclxyXG4gICk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgLy8gR2V0IHVzZXIncyBvcmdhbml6YXRpb25cclxuICAgIGxldCB1c2VyT3JnSWQgPSB1c2VyLnByaW1hcnlPcmdhbml6YXRpb25JZDtcclxuICAgIGlmICghdXNlck9yZ0lkKSB7XHJcbiAgICAgIGNvbnN0IGZ1bGxVc2VyID0gYXdhaXQgdGhpcy51c2VyU2VydmljZS5maW5kT25lKHVzZXIudXNlcl9pZCk7XHJcbiAgICAgIGlmIChmdWxsVXNlcikge1xyXG4gICAgICAgIHVzZXJPcmdJZCA9IGZ1bGxVc2VyLnByaW1hcnlPcmdhbml6YXRpb25JZDtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmICghdXNlck9yZ0lkKSB7XHJcbiAgICAgIGlmIChjcmVhdGVEdG8ub3JpZ2luYXRvcklkKSB7XHJcbiAgICAgICAgY29uc3QgY2FuTWFuYWdlQWxsID0gYXdhaXQgdGhpcy5oYXNTeXN0ZW1NYW5hZ2VBbGxQZXJtaXNzaW9uKFxyXG4gICAgICAgICAgdXNlci51c2VyX2lkXHJcbiAgICAgICAgKTtcclxuICAgICAgICBpZiAoY2FuTWFuYWdlQWxsKSB7XHJcbiAgICAgICAgICB1c2VyT3JnSWQgPSBhd2FpdCB0aGlzLnV1aWRSZXNvbHZlci5yZXNvbHZlT3JnYW5pemF0aW9uSWQoXHJcbiAgICAgICAgICAgIGNyZWF0ZUR0by5vcmlnaW5hdG9ySWRcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoIXVzZXJPcmdJZCkge1xyXG4gICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFxyXG4gICAgICAgICAgJ1VzZXIgbXVzdCBiZWxvbmcgdG8gYW4gb3JnYW5pemF0aW9uIHRvIGNyZWF0ZSBkb2N1bWVudHMnXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIEZvciBpbXBlcnNvbmF0aW9uLCB1c2UgdGhlIHNwZWNpZmllZCBvcmlnaW5hdG9yXHJcbiAgICBjb25zdCBvcmlnaW5hdG9yT3JnSWQgPSBjcmVhdGVEdG8ub3JpZ2luYXRvcklkXHJcbiAgICAgID8gYXdhaXQgdGhpcy51dWlkUmVzb2x2ZXIucmVzb2x2ZU9yZ2FuaXphdGlvbklkKGNyZWF0ZUR0by5vcmlnaW5hdG9ySWQpXHJcbiAgICAgIDogdXNlck9yZ0lkO1xyXG5cclxuICAgIC8vIENoZWNrIGlmIGl0J3MgaW50ZXJuYWwgY29tbXVuaWNhdGlvblxyXG4gICAgaWYgKGNyZWF0ZUR0by5pc0ludGVybmFsKSB7XHJcbiAgICAgIC8vIEludGVybmFsIGNvbW11bmljYXRpb25zIHNob3VsZCB1c2UgQ2lyY3VsYXRpb24gaW5zdGVhZFxyXG4gICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihcclxuICAgICAgICAnSW50ZXJuYWwgY29tbXVuaWNhdGlvbnMgc2hvdWxkIHVzZSBDaXJjdWxhdGlvbiBTaGVldCBpbnN0ZWFkIG9mIENvcnJlc3BvbmRlbmNlJ1xyXG4gICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFZhbGlkYXRlIHJlY2lwaWVudHNcclxuICAgIGlmICghY3JlYXRlRHRvLnJlY2lwaWVudHMgfHwgY3JlYXRlRHRvLnJlY2lwaWVudHMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFxyXG4gICAgICAgICdBdCBsZWFzdCBvbmUgcmVjaXBpZW50IChUTyBvciBDQykgaXMgcmVxdWlyZWQnXHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdG9SZWNpcGllbnRzID0gY3JlYXRlRHRvLnJlY2lwaWVudHMuZmlsdGVyKChyKSA9PiByLnR5cGUgPT09ICdUTycpO1xyXG4gICAgY29uc3QgY2NSZWNpcGllbnRzID0gY3JlYXRlRHRvLnJlY2lwaWVudHMuZmlsdGVyKChyKSA9PiByLnR5cGUgPT09ICdDQycpO1xyXG5cclxuICAgIGlmICh0b1JlY2lwaWVudHMubGVuZ3RoID09PSAwICYmIGNjUmVjaXBpZW50cy5sZW5ndGggPT09IDApIHtcclxuICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24oXHJcbiAgICAgICAgJ0F0IGxlYXN0IG9uZSBUTyBvciBDQyByZWNpcGllbnQgaXMgcmVxdWlyZWQnXHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ2hlY2sgZm9yIHNhbWUgb3JnYW5pemF0aW9uIGNvcnJlc3BvbmRlbmNlXHJcbiAgICBmb3IgKGNvbnN0IHJlY2lwaWVudCBvZiBjcmVhdGVEdG8ucmVjaXBpZW50cykge1xyXG4gICAgICBjb25zdCByZWNpcGllbnRPcmdJZCA9IGF3YWl0IHRoaXMudXVpZFJlc29sdmVyLnJlc29sdmVPcmdhbml6YXRpb25JZChcclxuICAgICAgICByZWNpcGllbnQub3JnYW5pemF0aW9uSWRcclxuICAgICAgKTtcclxuXHJcbiAgICAgIGlmIChyZWNpcGllbnRPcmdJZCA9PT0gb3JpZ2luYXRvck9yZ0lkKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24oXHJcbiAgICAgICAgICAnQ2Fubm90IHNlbmQgY29ycmVzcG9uZGVuY2UgdG8geW91ciBvd24gb3JnYW5pemF0aW9uLiBVc2UgQ2lyY3VsYXRpb24gU2hlZXQgZm9yIGludGVybmFsIGNvbW11bmljYXRpb24uJ1xyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIGFzeW5jIGNyZWF0ZShjcmVhdGVEdG86IENyZWF0ZUNvcnJlc3BvbmRlbmNlRHRvLCB1c2VyOiBVc2VyKSB7XHJcbiAgICAvLyBCdXNpbmVzcyBSdWxlIFZhbGlkYXRpb246IEVDLUNPUlItMDAzIC0gQ29ycmVzcG9uZGVuY2UgdG8gU2VsZlxyXG4gICAgYXdhaXQgdGhpcy52YWxpZGF0ZUNvcnJlc3BvbmRlbmNlUmVjaXBpZW50cyhjcmVhdGVEdG8sIHVzZXIpO1xyXG4gICAgLy8gQURSLTAxOTogUmVzb2x2ZSBVVUlEIHJlZmVyZW5jZXMgdG8gaW50ZXJuYWwgSU5UIElEc1xyXG4gICAgY29uc3QgcmVzb2x2ZWRQcm9qZWN0SWQgPSBhd2FpdCB0aGlzLnV1aWRSZXNvbHZlci5yZXNvbHZlUHJvamVjdElkKFxyXG4gICAgICBjcmVhdGVEdG8ucHJvamVjdElkXHJcbiAgICApO1xyXG4gICAgY29uc3QgcmVzb2x2ZWRPcmlnaW5hdG9ySWQgPSBjcmVhdGVEdG8ub3JpZ2luYXRvcklkXHJcbiAgICAgID8gYXdhaXQgdGhpcy51dWlkUmVzb2x2ZXIucmVzb2x2ZU9yZ2FuaXphdGlvbklkKGNyZWF0ZUR0by5vcmlnaW5hdG9ySWQpXHJcbiAgICAgIDogdW5kZWZpbmVkO1xyXG4gICAgY29uc3QgcmVzb2x2ZWRSZWNpcGllbnRzID0gY3JlYXRlRHRvLnJlY2lwaWVudHNcclxuICAgICAgPyBhd2FpdCBQcm9taXNlLmFsbChcclxuICAgICAgICAgIGNyZWF0ZUR0by5yZWNpcGllbnRzLm1hcChcclxuICAgICAgICAgICAgYXN5bmMgKHIpOiBQcm9taXNlPFJlc29sdmVkUmVjaXBpZW50PiA9PiAoe1xyXG4gICAgICAgICAgICAgIG9yZ2FuaXphdGlvbklkOiBhd2FpdCB0aGlzLnV1aWRSZXNvbHZlci5yZXNvbHZlT3JnYW5pemF0aW9uSWQoXHJcbiAgICAgICAgICAgICAgICByLm9yZ2FuaXphdGlvbklkXHJcbiAgICAgICAgICAgICAgKSxcclxuICAgICAgICAgICAgICB0eXBlOiByLnR5cGUsXHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICApXHJcbiAgICAgICAgKVxyXG4gICAgICA6IHVuZGVmaW5lZDtcclxuICAgIGNvbnN0IHR5cGUgPSBhd2FpdCB0aGlzLnR5cGVSZXBvLmZpbmRPbmUoe1xyXG4gICAgICB3aGVyZTogeyBpZDogY3JlYXRlRHRvLnR5cGVJZCB9LFxyXG4gICAgfSk7XHJcbiAgICBpZiAoIXR5cGUpIHRocm93IG5ldyBOb3RGb3VuZEV4Y2VwdGlvbignRG9jdW1lbnQgVHlwZSBub3QgZm91bmQnKTtcclxuXHJcbiAgICBjb25zdCBzdGF0dXNEcmFmdCA9IGF3YWl0IHRoaXMuc3RhdHVzUmVwby5maW5kT25lKHtcclxuICAgICAgd2hlcmU6IHsgc3RhdHVzQ29kZTogJ0RSQUZUJyB9LFxyXG4gICAgfSk7XHJcbiAgICBpZiAoIXN0YXR1c0RyYWZ0KSB7XHJcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbFNlcnZlckVycm9yRXhjZXB0aW9uKFxyXG4gICAgICAgICdTdGF0dXMgRFJBRlQgbm90IGZvdW5kIGluIE1hc3RlciBEYXRhJ1xyXG4gICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIGxldCB1c2VyT3JnSWQgPSB1c2VyLnByaW1hcnlPcmdhbml6YXRpb25JZDtcclxuXHJcbiAgICBpZiAoIXVzZXJPcmdJZCkge1xyXG4gICAgICBjb25zdCBmdWxsVXNlciA9IGF3YWl0IHRoaXMudXNlclNlcnZpY2UuZmluZE9uZSh1c2VyLnVzZXJfaWQpO1xyXG4gICAgICBpZiAoZnVsbFVzZXIpIHtcclxuICAgICAgICB1c2VyT3JnSWQgPSBmdWxsVXNlci5wcmltYXJ5T3JnYW5pemF0aW9uSWQ7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBJbXBlcnNvbmF0aW9uIExvZ2ljXHJcbiAgICBpZiAocmVzb2x2ZWRPcmlnaW5hdG9ySWQgJiYgcmVzb2x2ZWRPcmlnaW5hdG9ySWQgIT09IHVzZXJPcmdJZCkge1xyXG4gICAgICBjb25zdCBjYW5NYW5hZ2VBbGwgPSBhd2FpdCB0aGlzLmhhc1N5c3RlbU1hbmFnZUFsbFBlcm1pc3Npb24oXHJcbiAgICAgICAgdXNlci51c2VyX2lkXHJcbiAgICAgICk7XHJcbiAgICAgIGlmICghY2FuTWFuYWdlQWxsKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEZvcmJpZGRlbkV4Y2VwdGlvbihcclxuICAgICAgICAgICdZb3UgZG8gbm90IGhhdmUgcGVybWlzc2lvbiB0byBjcmVhdGUgZG9jdW1lbnRzIG9uIGJlaGFsZiBvZiBvdGhlciBvcmdhbml6YXRpb25zLidcclxuICAgICAgICApO1xyXG4gICAgICB9XHJcbiAgICAgIHVzZXJPcmdJZCA9IHJlc29sdmVkT3JpZ2luYXRvcklkO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghdXNlck9yZ0lkKSB7XHJcbiAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFxyXG4gICAgICAgICdVc2VyIG11c3QgYmVsb25nIHRvIGFuIG9yZ2FuaXphdGlvbiB0byBjcmVhdGUgZG9jdW1lbnRzJ1xyXG4gICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChjcmVhdGVEdG8uZGV0YWlscykge1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGF3YWl0IHRoaXMuanNvblNjaGVtYVNlcnZpY2UudmFsaWRhdGUodHlwZS50eXBlQ29kZSwgY3JlYXRlRHRvLmRldGFpbHMpO1xyXG4gICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xyXG4gICAgICAgIHRoaXMubG9nZ2VyLndhcm4oXHJcbiAgICAgICAgICBgU2NoZW1hIHZhbGlkYXRpb24gd2FybmluZyBmb3IgJHt0eXBlLnR5cGVDb2RlfTogJHsoZXJyb3IgYXMgRXJyb3IpLm1lc3NhZ2V9YFxyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBxdWVyeVJ1bm5lciA9IHRoaXMuZGF0YVNvdXJjZS5jcmVhdGVRdWVyeVJ1bm5lcigpO1xyXG4gICAgYXdhaXQgcXVlcnlSdW5uZXIuY29ubmVjdCgpO1xyXG4gICAgYXdhaXQgcXVlcnlSdW5uZXIuc3RhcnRUcmFuc2FjdGlvbigpO1xyXG5cclxuICAgIHRyeSB7XHJcbiAgICAgIC8vIFtGaXggIzZdIEZldGNoIHJlYWwgT1JHIENvZGUgZnJvbSBPcmdhbml6YXRpb24gZW50aXR5XHJcbiAgICAgIGNvbnN0IG9yaWdpbmF0b3JPcmcgPSBhd2FpdCB0aGlzLmRhdGFTb3VyY2UubWFuYWdlci5maW5kT25lKFxyXG4gICAgICAgIE9yZ2FuaXphdGlvbixcclxuICAgICAgICB7XHJcbiAgICAgICAgICB3aGVyZTogeyBpZDogdXNlck9yZ0lkIH0sXHJcbiAgICAgICAgfVxyXG4gICAgICApO1xyXG4gICAgICBjb25zdCBvcmdDb2RlID0gb3JpZ2luYXRvck9yZz8ub3JnYW5pemF0aW9uQ29kZSA/PyAnVU5LJztcclxuXHJcbiAgICAgIC8vIFt2MS41LjFdIEV4dHJhY3QgcmVjaXBpZW50IG9yZ2FuaXphdGlvbiBmcm9tIHJlY2lwaWVudHMgYXJyYXkgKFByaW1hcnkgVE8pXHJcbiAgICAgIGNvbnN0IHRvUmVjaXBpZW50ID0gcmVzb2x2ZWRSZWNpcGllbnRzPy5maW5kKChyKSA9PiByLnR5cGUgPT09ICdUTycpO1xyXG4gICAgICBjb25zdCByZWNpcGllbnRPcmdhbml6YXRpb25JZCA9IHRvUmVjaXBpZW50Py5vcmdhbml6YXRpb25JZDtcclxuXHJcbiAgICAgIGxldCByZWNpcGllbnRDb2RlID0gJyc7XHJcbiAgICAgIGlmIChyZWNpcGllbnRPcmdhbml6YXRpb25JZCkge1xyXG4gICAgICAgIGNvbnN0IHJlY09yZyA9IGF3YWl0IHRoaXMuZGF0YVNvdXJjZS5tYW5hZ2VyLmZpbmRPbmUoT3JnYW5pemF0aW9uLCB7XHJcbiAgICAgICAgICB3aGVyZTogeyBpZDogcmVjaXBpZW50T3JnYW5pemF0aW9uSWQgfSxcclxuICAgICAgICB9KTtcclxuICAgICAgICBpZiAocmVjT3JnKSByZWNpcGllbnRDb2RlID0gcmVjT3JnLm9yZ2FuaXphdGlvbkNvZGU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnN0IGRvY051bWJlciA9IGF3YWl0IHRoaXMubnVtYmVyaW5nU2VydmljZS5nZW5lcmF0ZU5leHROdW1iZXIoe1xyXG4gICAgICAgIHByb2plY3RJZDogcmVzb2x2ZWRQcm9qZWN0SWQsXHJcbiAgICAgICAgb3JpZ2luYXRvck9yZ2FuaXphdGlvbklkOiB1c2VyT3JnSWQsXHJcbiAgICAgICAgdHlwZUlkOiBjcmVhdGVEdG8udHlwZUlkLFxyXG4gICAgICAgIGRpc2NpcGxpbmVJZDogY3JlYXRlRHRvLmRpc2NpcGxpbmVJZCxcclxuICAgICAgICBzdWJUeXBlSWQ6IGNyZWF0ZUR0by5zdWJUeXBlSWQsXHJcbiAgICAgICAgcmVjaXBpZW50T3JnYW5pemF0aW9uSWQsIC8vIFt2MS41LjFdIFBhc3MgcmVjaXBpZW50IGZvciBkb2N1bWVudCBudW1iZXIgZm9ybWF0XHJcbiAgICAgICAgeWVhcjogbmV3IERhdGUoKS5nZXRGdWxsWWVhcigpLFxyXG4gICAgICAgIGN1c3RvbVRva2Vuczoge1xyXG4gICAgICAgICAgVFlQRV9DT0RFOiB0eXBlLnR5cGVDb2RlLFxyXG4gICAgICAgICAgT1JHX0NPREU6IG9yZ0NvZGUsXHJcbiAgICAgICAgICBSRUNJUElFTlRfQ09ERTogcmVjaXBpZW50Q29kZSxcclxuICAgICAgICAgIFJFQ19DT0RFOiByZWNpcGllbnRDb2RlLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgY29uc3QgY29ycmVzcG9uZGVuY2UgPSBxdWVyeVJ1bm5lci5tYW5hZ2VyLmNyZWF0ZShDb3JyZXNwb25kZW5jZSwge1xyXG4gICAgICAgIGNvcnJlc3BvbmRlbmNlTnVtYmVyOiBkb2NOdW1iZXIubnVtYmVyLFxyXG4gICAgICAgIGNvcnJlc3BvbmRlbmNlVHlwZUlkOiBjcmVhdGVEdG8udHlwZUlkLFxyXG4gICAgICAgIGRpc2NpcGxpbmVJZDogY3JlYXRlRHRvLmRpc2NpcGxpbmVJZCxcclxuICAgICAgICBwcm9qZWN0SWQ6IHJlc29sdmVkUHJvamVjdElkLFxyXG4gICAgICAgIG9yaWdpbmF0b3JJZDogdXNlck9yZ0lkLFxyXG4gICAgICAgIGlzSW50ZXJuYWw6IGNyZWF0ZUR0by5pc0ludGVybmFsIHx8IGZhbHNlLFxyXG4gICAgICAgIGNyZWF0ZWRCeTogdXNlci51c2VyX2lkLFxyXG4gICAgICB9KTtcclxuICAgICAgY29uc3Qgc2F2ZWRDb3JyID0gYXdhaXQgcXVlcnlSdW5uZXIubWFuYWdlci5zYXZlKGNvcnJlc3BvbmRlbmNlKTtcclxuXHJcbiAgICAgIGNvbnN0IHJldmlzaW9uID0gcXVlcnlSdW5uZXIubWFuYWdlci5jcmVhdGUoQ29ycmVzcG9uZGVuY2VSZXZpc2lvbiwge1xyXG4gICAgICAgIGNvcnJlc3BvbmRlbmNlSWQ6IHNhdmVkQ29yci5pZCxcclxuICAgICAgICByZXZpc2lvbk51bWJlcjogMCxcclxuICAgICAgICByZXZpc2lvbkxhYmVsOiB0aGlzLmdldEluaXRpYWxSZXZpc2lvbkxhYmVsKHR5cGUudHlwZUNvZGUpLFxyXG4gICAgICAgIGlzQ3VycmVudDogdHJ1ZSxcclxuICAgICAgICBzdGF0dXNJZDogc3RhdHVzRHJhZnQuaWQsXHJcbiAgICAgICAgc3ViamVjdDogY3JlYXRlRHRvLnN1YmplY3QsXHJcbiAgICAgICAgYm9keTogY3JlYXRlRHRvLmJvZHksXHJcbiAgICAgICAgcmVtYXJrczogY3JlYXRlRHRvLnJlbWFya3MsXHJcbiAgICAgICAgZHVlRGF0ZTogY3JlYXRlRHRvLmR1ZURhdGUgPyBuZXcgRGF0ZShjcmVhdGVEdG8uZHVlRGF0ZSkgOiB1bmRlZmluZWQsXHJcbiAgICAgICAgZG9jdW1lbnREYXRlOiBjcmVhdGVEdG8uZG9jdW1lbnREYXRlXHJcbiAgICAgICAgICA/IG5ldyBEYXRlKGNyZWF0ZUR0by5kb2N1bWVudERhdGUpXHJcbiAgICAgICAgICA6IHVuZGVmaW5lZCxcclxuICAgICAgICBpc3N1ZWREYXRlOiBjcmVhdGVEdG8uaXNzdWVkRGF0ZVxyXG4gICAgICAgICAgPyBuZXcgRGF0ZShjcmVhdGVEdG8uaXNzdWVkRGF0ZSlcclxuICAgICAgICAgIDogdW5kZWZpbmVkLFxyXG4gICAgICAgIHJlY2VpdmVkRGF0ZTogY3JlYXRlRHRvLnJlY2VpdmVkRGF0ZVxyXG4gICAgICAgICAgPyBuZXcgRGF0ZShjcmVhdGVEdG8ucmVjZWl2ZWREYXRlKVxyXG4gICAgICAgICAgOiB1bmRlZmluZWQsXHJcbiAgICAgICAgZGVzY3JpcHRpb246IGNyZWF0ZUR0by5kZXNjcmlwdGlvbixcclxuICAgICAgICBkZXRhaWxzOiBjcmVhdGVEdG8uZGV0YWlscyxcclxuICAgICAgICBjcmVhdGVkQnk6IHVzZXIudXNlcl9pZCxcclxuICAgICAgICBzY2hlbWFWZXJzaW9uOiAxLFxyXG4gICAgICB9KTtcclxuICAgICAgYXdhaXQgcXVlcnlSdW5uZXIubWFuYWdlci5zYXZlKHJldmlzaW9uKTtcclxuXHJcbiAgICAgIC8vIFNhdmUgUmVjaXBpZW50cyAodXNpbmcgcmVzb2x2ZWQgSU5UIElEcylcclxuICAgICAgaWYgKHJlc29sdmVkUmVjaXBpZW50cyAmJiByZXNvbHZlZFJlY2lwaWVudHMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIGNvbnN0IHJlY2lwaWVudHMgPSByZXNvbHZlZFJlY2lwaWVudHMubWFwKChyKSA9PlxyXG4gICAgICAgICAgcXVlcnlSdW5uZXIubWFuYWdlci5jcmVhdGUoQ29ycmVzcG9uZGVuY2VSZWNpcGllbnQsIHtcclxuICAgICAgICAgICAgY29ycmVzcG9uZGVuY2VJZDogc2F2ZWRDb3JyLmlkLFxyXG4gICAgICAgICAgICByZWNpcGllbnRPcmdhbml6YXRpb25JZDogci5vcmdhbml6YXRpb25JZCxcclxuICAgICAgICAgICAgcmVjaXBpZW50VHlwZTogci50eXBlLFxyXG4gICAgICAgICAgfSlcclxuICAgICAgICApO1xyXG4gICAgICAgIGF3YWl0IHF1ZXJ5UnVubmVyLm1hbmFnZXIuc2F2ZShyZWNpcGllbnRzKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gQ29tbWl0IGF0dGFjaG1lbnRzIGZyb20gVGVtcCDihpIgUGVybWFuZW50IChUd28tUGhhc2UgU3RvcmFnZSlcclxuICAgICAgaWYgKGNyZWF0ZUR0by5hdHRhY2htZW50VGVtcElkcz8ubGVuZ3RoKSB7XHJcbiAgICAgICAgY29uc3QgaXNzdWVEYXRlID0gY3JlYXRlRHRvLmlzc3VlZERhdGVcclxuICAgICAgICAgID8gbmV3IERhdGUoY3JlYXRlRHRvLmlzc3VlZERhdGUpXHJcbiAgICAgICAgICA6IGNyZWF0ZUR0by5kb2N1bWVudERhdGVcclxuICAgICAgICAgICAgPyBuZXcgRGF0ZShjcmVhdGVEdG8uZG9jdW1lbnREYXRlKVxyXG4gICAgICAgICAgICA6IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgICAgYXdhaXQgdGhpcy5maWxlU3RvcmFnZVNlcnZpY2UuY29tbWl0KGNyZWF0ZUR0by5hdHRhY2htZW50VGVtcElkcywge1xyXG4gICAgICAgICAgaXNzdWVEYXRlLFxyXG4gICAgICAgICAgZG9jdW1lbnRUeXBlOiAnQ29ycmVzcG9uZGVuY2UnLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBhd2FpdCBxdWVyeVJ1bm5lci5jb21taXRUcmFuc2FjdGlvbigpO1xyXG5cclxuICAgICAgLy8gU3RhcnQgV29ya2Zsb3cgSW5zdGFuY2UgKG5vbi1ibG9ja2luZylcclxuICAgICAgdHJ5IHtcclxuICAgICAgICBjb25zdCB3b3JrZmxvd0NvZGUgPSBgQ09SUkVTUE9OREVOQ0VfJHt0eXBlLnR5cGVDb2RlfWA7XHJcbiAgICAgICAgYXdhaXQgdGhpcy53b3JrZmxvd0VuZ2luZS5jcmVhdGVJbnN0YW5jZShcclxuICAgICAgICAgIHdvcmtmbG93Q29kZSxcclxuICAgICAgICAgICdjb3JyZXNwb25kZW5jZScsXHJcbiAgICAgICAgICBzYXZlZENvcnIuaWQudG9TdHJpbmcoKSxcclxuICAgICAgICAgIHtcclxuICAgICAgICAgICAgcHJvamVjdElkOiByZXNvbHZlZFByb2plY3RJZCxcclxuICAgICAgICAgICAgb3JpZ2luYXRvcklkOiB1c2VyT3JnSWQsXHJcbiAgICAgICAgICAgIGRpc2NpcGxpbmVJZDogY3JlYXRlRHRvLmRpc2NpcGxpbmVJZCxcclxuICAgICAgICAgICAgaW5pdGlhdG9ySWQ6IHVzZXIudXNlcl9pZCxcclxuICAgICAgICAgIH0gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj5cclxuICAgICAgICApO1xyXG4gICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xyXG4gICAgICAgIHRoaXMubG9nZ2VyLndhcm4oXHJcbiAgICAgICAgICBgV29ya2Zsb3cgbm90IHN0YXJ0ZWQgZm9yICR7ZG9jTnVtYmVyLm51bWJlcn0gKENvZGU6IENPUlJFU1BPTkRFTkNFXyR7dHlwZS50eXBlQ29kZX0pOiAkeyhlcnJvciBhcyBFcnJvcikubWVzc2FnZX1gXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gRmlyZS1hbmQtZm9yZ2V0IHNlYXJjaCBpbmRleGluZyAobm9uLWJsb2NraW5nLCB2b2lkIGludGVudGlvbmFsKVxyXG4gICAgICB2b2lkIHRoaXMuc2VhcmNoU2VydmljZS5pbmRleERvY3VtZW50KHtcclxuICAgICAgICBpZDogc2F2ZWRDb3JyLmlkLFxyXG4gICAgICAgIHB1YmxpY0lkOiBzYXZlZENvcnIucHVibGljSWQsXHJcbiAgICAgICAgdHlwZTogJ2NvcnJlc3BvbmRlbmNlJyxcclxuICAgICAgICBkb2NOdW1iZXI6IGRvY051bWJlci5udW1iZXIsXHJcbiAgICAgICAgdGl0bGU6IGNyZWF0ZUR0by5zdWJqZWN0LFxyXG4gICAgICAgIGRlc2NyaXB0aW9uOiBjcmVhdGVEdG8uZGVzY3JpcHRpb24sXHJcbiAgICAgICAgc3RhdHVzOiAnRFJBRlQnLFxyXG4gICAgICAgIHByb2plY3RJZDogcmVzb2x2ZWRQcm9qZWN0SWQsXHJcbiAgICAgICAgY3JlYXRlZEF0OiBuZXcgRGF0ZSgpLFxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgLi4uc2F2ZWRDb3JyLFxyXG4gICAgICAgIGN1cnJlbnRSZXZpc2lvbjogcmV2aXNpb24sXHJcbiAgICAgIH07XHJcbiAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgYXdhaXQgcXVlcnlSdW5uZXIucm9sbGJhY2tUcmFuc2FjdGlvbigpO1xyXG4gICAgICB0aGlzLmxvZ2dlci5lcnJvcihcclxuICAgICAgICBgRmFpbGVkIHRvIGNyZWF0ZSBjb3JyZXNwb25kZW5jZTogJHsoZXJyIGFzIEVycm9yKS5tZXNzYWdlfWBcclxuICAgICAgKTtcclxuICAgICAgdGhyb3cgZXJyO1xyXG4gICAgfSBmaW5hbGx5IHtcclxuICAgICAgYXdhaXQgcXVlcnlSdW5uZXIucmVsZWFzZSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgYXN5bmMgZmluZEFsbChzZWFyY2hEdG86IFNlYXJjaENvcnJlc3BvbmRlbmNlRHRvID0ge30pIHtcclxuICAgIGNvbnN0IHtcclxuICAgICAgc2VhcmNoLFxyXG4gICAgICB0eXBlSWQsXHJcbiAgICAgIHByb2plY3RJZCxcclxuICAgICAgc3RhdHVzSWQsXHJcbiAgICAgIHN0YXR1cyxcclxuICAgICAgcGFnZSA9IDEsXHJcbiAgICAgIGxpbWl0ID0gMTAsXHJcbiAgICB9ID0gc2VhcmNoRHRvO1xyXG4gICAgY29uc3Qgc2tpcCA9IChwYWdlIC0gMSkgKiBsaW1pdDtcclxuXHJcbiAgICAvLyBDaGFuZ2U6IFF1ZXJ5IGZyb20gUmV2aXNpb24gUmVwb1xyXG4gICAgY29uc3QgcXVlcnkgPSB0aGlzLnJldmlzaW9uUmVwb1xyXG4gICAgICAuY3JlYXRlUXVlcnlCdWlsZGVyKCdyZXYnKVxyXG4gICAgICAubGVmdEpvaW5BbmRTZWxlY3QoJ3Jldi5jb3JyZXNwb25kZW5jZScsICdjb3JyJylcclxuICAgICAgLmxlZnRKb2luQW5kU2VsZWN0KCdjb3JyLnR5cGUnLCAndHlwZScpXHJcbiAgICAgIC5sZWZ0Sm9pbkFuZFNlbGVjdCgnY29yci5wcm9qZWN0JywgJ3Byb2plY3QnKVxyXG4gICAgICAubGVmdEpvaW5BbmRTZWxlY3QoJ2NvcnIub3JpZ2luYXRvcicsICdvcmcnKVxyXG4gICAgICAubGVmdEpvaW5BbmRTZWxlY3QoJ3Jldi5zdGF0dXMnLCAnc3RhdHVzJyk7XHJcblxyXG4gICAgLy8gRmlsdGVyIGJ5IFJldmlzaW9uIFN0YXR1c1xyXG4gICAgY29uc3QgcmV2U3RhdHVzID0gc2VhcmNoRHRvLnJldmlzaW9uU3RhdHVzIHx8ICdDVVJSRU5UJztcclxuXHJcbiAgICBpZiAocmV2U3RhdHVzID09PSAnQ1VSUkVOVCcpIHtcclxuICAgICAgcXVlcnkud2hlcmUoJ3Jldi5pc0N1cnJlbnQgPSA6aXNDdXJyZW50JywgeyBpc0N1cnJlbnQ6IHRydWUgfSk7XHJcbiAgICB9IGVsc2UgaWYgKHJldlN0YXR1cyA9PT0gJ09MRCcpIHtcclxuICAgICAgcXVlcnkud2hlcmUoJ3Jldi5pc0N1cnJlbnQgPSA6aXNDdXJyZW50JywgeyBpc0N1cnJlbnQ6IGZhbHNlIH0pO1xyXG4gICAgfVxyXG4gICAgLy8gSWYgJ0FMTCcsIG5vIGZpbHRlciBuZWVkZWQgb24gaXNDdXJyZW50XHJcblxyXG4gICAgaWYgKHByb2plY3RJZCkge1xyXG4gICAgICBxdWVyeS5hbmRXaGVyZSgnY29yci5wcm9qZWN0SWQgPSA6cHJvamVjdElkJywgeyBwcm9qZWN0SWQgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGVJZCkge1xyXG4gICAgICBxdWVyeS5hbmRXaGVyZSgnY29yci5jb3JyZXNwb25kZW5jZVR5cGVJZCA9IDp0eXBlSWQnLCB7IHR5cGVJZCB9KTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoc3RhdHVzSWQpIHtcclxuICAgICAgcXVlcnkuYW5kV2hlcmUoJ3Jldi5zdGF0dXNJZCA9IDpzdGF0dXNJZCcsIHsgc3RhdHVzSWQgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHN0YXR1cykge1xyXG4gICAgICBxdWVyeS5hbmRXaGVyZSgnc3RhdHVzLnN0YXR1c0NvZGUgPSA6c3RhdHVzJywgeyBzdGF0dXMgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHNlYXJjaCkge1xyXG4gICAgICBxdWVyeS5hbmRXaGVyZShcclxuICAgICAgICAnKGNvcnIuY29ycmVzcG9uZGVuY2VOdW1iZXIgTElLRSA6c2VhcmNoIE9SIHJldi5zdWJqZWN0IExJS0UgOnNlYXJjaCknLFxyXG4gICAgICAgIHsgc2VhcmNoOiBgJSR7c2VhcmNofSVgIH1cclxuICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBEZWZhdWx0IFNvcnQ6IExhdGVzdCBDcmVhdGVkXHJcbiAgICBxdWVyeS5vcmRlckJ5KCdyZXYuY3JlYXRlZEF0JywgJ0RFU0MnKS5za2lwKHNraXApLnRha2UobGltaXQpO1xyXG5cclxuICAgIGNvbnN0IFtpdGVtcywgdG90YWxdID0gYXdhaXQgcXVlcnkuZ2V0TWFueUFuZENvdW50KCk7XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgZGF0YTogaXRlbXMsXHJcbiAgICAgIG1ldGE6IHtcclxuICAgICAgICB0b3RhbCxcclxuICAgICAgICBwYWdlLFxyXG4gICAgICAgIGxpbWl0LFxyXG4gICAgICAgIHRvdGFsUGFnZXM6IE1hdGguY2VpbCh0b3RhbCAvIGxpbWl0KSxcclxuICAgICAgfSxcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBhc3luYyBmaW5kT25lKGlkOiBudW1iZXIpIHtcclxuICAgIGNvbnN0IGNvcnJlc3BvbmRlbmNlID0gYXdhaXQgdGhpcy5jb3JyZXNwb25kZW5jZVJlcG8uZmluZE9uZSh7XHJcbiAgICAgIHdoZXJlOiB7IGlkIH0sXHJcbiAgICAgIHJlbGF0aW9uczogW1xyXG4gICAgICAgICdyZXZpc2lvbnMnLFxyXG4gICAgICAgICdyZXZpc2lvbnMuc3RhdHVzJyxcclxuICAgICAgICAndHlwZScsXHJcbiAgICAgICAgJ3Byb2plY3QnLFxyXG4gICAgICAgICdvcmlnaW5hdG9yJyxcclxuICAgICAgICAncmVjaXBpZW50cycsXHJcbiAgICAgICAgJ3JlY2lwaWVudHMucmVjaXBpZW50T3JnYW5pemF0aW9uJywgLy8gW3YxLjUuMV0gRml4ZWQgcmVsYXRpb24gbmFtZVxyXG4gICAgICBdLFxyXG4gICAgfSk7XHJcblxyXG4gICAgaWYgKCFjb3JyZXNwb25kZW5jZSkge1xyXG4gICAgICB0aHJvdyBuZXcgTm90Rm91bmRFeGNlcHRpb24oYENvcnJlc3BvbmRlbmNlIHdpdGggSUQgJHtpZH0gbm90IGZvdW5kYCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gY29ycmVzcG9uZGVuY2U7XHJcbiAgfVxyXG5cclxuICBhc3luYyBmaW5kT25lQnlVdWlkKHB1YmxpY0lkOiBzdHJpbmcpIHtcclxuICAgIGNvbnN0IGNvcnJlc3BvbmRlbmNlID0gYXdhaXQgdGhpcy5jb3JyZXNwb25kZW5jZVJlcG8uZmluZE9uZSh7XHJcbiAgICAgIHdoZXJlOiB7IHB1YmxpY0lkIH0sXHJcbiAgICAgIHJlbGF0aW9uczogW1xyXG4gICAgICAgICdyZXZpc2lvbnMnLFxyXG4gICAgICAgICdyZXZpc2lvbnMuc3RhdHVzJyxcclxuICAgICAgICAndHlwZScsXHJcbiAgICAgICAgJ3Byb2plY3QnLFxyXG4gICAgICAgICdvcmlnaW5hdG9yJyxcclxuICAgICAgICAncmVjaXBpZW50cycsXHJcbiAgICAgICAgJ3JlY2lwaWVudHMucmVjaXBpZW50T3JnYW5pemF0aW9uJyxcclxuICAgICAgXSxcclxuICAgIH0pO1xyXG5cclxuICAgIGlmICghY29ycmVzcG9uZGVuY2UpIHtcclxuICAgICAgdGhyb3cgbmV3IE5vdEZvdW5kRXhjZXB0aW9uKFxyXG4gICAgICAgIGBDb3JyZXNwb25kZW5jZSB3aXRoIFVVSUQgJHtwdWJsaWNJZH0gbm90IGZvdW5kYFxyXG4gICAgICApO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGNvcnJlc3BvbmRlbmNlO1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgYWRkUmVmZXJlbmNlKGlkOiBudW1iZXIsIGR0bzogQWRkUmVmZXJlbmNlRHRvKSB7XHJcbiAgICBjb25zdCBzb3VyY2UgPSBhd2FpdCB0aGlzLmNvcnJlc3BvbmRlbmNlUmVwby5maW5kT25lKHsgd2hlcmU6IHsgaWQgfSB9KTtcclxuICAgIC8vIEFEUi0wMTk6IFJlc29sdmUgdGFyZ2V0IHB1YmxpY0lkIOKGkiBpbnRlcm5hbCBJTlQgaWRcclxuICAgIGNvbnN0IHRhcmdldCA9IGF3YWl0IHRoaXMuY29ycmVzcG9uZGVuY2VSZXBvLmZpbmRPbmUoe1xyXG4gICAgICB3aGVyZTogeyBwdWJsaWNJZDogZHRvLnRhcmdldFV1aWQgfSxcclxuICAgIH0pO1xyXG5cclxuICAgIGlmICghc291cmNlIHx8ICF0YXJnZXQpIHtcclxuICAgICAgdGhyb3cgbmV3IE5vdEZvdW5kRXhjZXB0aW9uKCdTb3VyY2Ugb3IgVGFyZ2V0IGNvcnJlc3BvbmRlbmNlIG5vdCBmb3VuZCcpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChzb3VyY2UuaWQgPT09IHRhcmdldC5pZCkge1xyXG4gICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbignQ2Fubm90IHJlZmVyZW5jZSBzZWxmJyk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgZXhpc3RzID0gYXdhaXQgdGhpcy5yZWZlcmVuY2VSZXBvLmZpbmRPbmUoe1xyXG4gICAgICB3aGVyZToge1xyXG4gICAgICAgIHNvdXJjZUlkOiBpZCxcclxuICAgICAgICB0YXJnZXRJZDogdGFyZ2V0LmlkLFxyXG4gICAgICB9LFxyXG4gICAgfSk7XHJcblxyXG4gICAgaWYgKGV4aXN0cykge1xyXG4gICAgICByZXR1cm4gZXhpc3RzO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHJlZiA9IHRoaXMucmVmZXJlbmNlUmVwby5jcmVhdGUoe1xyXG4gICAgICBzb3VyY2VJZDogaWQsXHJcbiAgICAgIHRhcmdldElkOiB0YXJnZXQuaWQsXHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gdGhpcy5yZWZlcmVuY2VSZXBvLnNhdmUocmVmKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIHJlbW92ZVJlZmVyZW5jZShpZDogbnVtYmVyLCB0YXJnZXRJZDogbnVtYmVyKSB7XHJcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnJlZmVyZW5jZVJlcG8uZGVsZXRlKHtcclxuICAgICAgc291cmNlSWQ6IGlkLFxyXG4gICAgICB0YXJnZXRJZDogdGFyZ2V0SWQsXHJcbiAgICB9KTtcclxuXHJcbiAgICBpZiAocmVzdWx0LmFmZmVjdGVkID09PSAwKSB7XHJcbiAgICAgIHRocm93IG5ldyBOb3RGb3VuZEV4Y2VwdGlvbignUmVmZXJlbmNlIG5vdCBmb3VuZCcpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgYXN5bmMgZ2V0VGFncyhpZDogbnVtYmVyKSB7XHJcbiAgICBjb25zdCByb3dzID0gYXdhaXQgdGhpcy50YWdSZXBvLmZpbmQoe1xyXG4gICAgICB3aGVyZTogeyBjb3JyZXNwb25kZW5jZUlkOiBpZCB9LFxyXG4gICAgICByZWxhdGlvbnM6IFsndGFnJ10sXHJcbiAgICB9KTtcclxuICAgIHJldHVybiByb3dzLm1hcCgocikgPT4gci50YWcpLmZpbHRlcihCb29sZWFuKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGFkZFRhZyhpZDogbnVtYmVyLCB0YWdJZDogbnVtYmVyKSB7XHJcbiAgICBjb25zdCBjb3JyZXNwb25kZW5jZSA9IGF3YWl0IHRoaXMuY29ycmVzcG9uZGVuY2VSZXBvLmZpbmRPbmUoe1xyXG4gICAgICB3aGVyZTogeyBpZCB9LFxyXG4gICAgfSk7XHJcbiAgICBpZiAoIWNvcnJlc3BvbmRlbmNlKSB7XHJcbiAgICAgIHRocm93IG5ldyBOb3RGb3VuZEV4Y2VwdGlvbihgQ29ycmVzcG9uZGVuY2UgJHtpZH0gbm90IGZvdW5kYCk7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgdGFnID0gYXdhaXQgdGhpcy5kYXRhU291cmNlLm1hbmFnZXIuZmluZE9uZShUYWcsIHtcclxuICAgICAgd2hlcmU6IHsgaWQ6IHRhZ0lkIH0sXHJcbiAgICB9KTtcclxuICAgIGlmICghdGFnKSB7XHJcbiAgICAgIHRocm93IG5ldyBOb3RGb3VuZEV4Y2VwdGlvbihgVGFnICR7dGFnSWR9IG5vdCBmb3VuZGApO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGV4aXN0cyA9IGF3YWl0IHRoaXMudGFnUmVwby5maW5kT25lKHtcclxuICAgICAgd2hlcmU6IHsgY29ycmVzcG9uZGVuY2VJZDogaWQsIHRhZ0lkIH0sXHJcbiAgICB9KTtcclxuICAgIGlmIChleGlzdHMpIHJldHVybiBleGlzdHM7XHJcblxyXG4gICAgY29uc3Qgcm93ID0gdGhpcy50YWdSZXBvLmNyZWF0ZSh7IGNvcnJlc3BvbmRlbmNlSWQ6IGlkLCB0YWdJZCB9KTtcclxuICAgIHJldHVybiB0aGlzLnRhZ1JlcG8uc2F2ZShyb3cpO1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgcmVtb3ZlVGFnKGlkOiBudW1iZXIsIHRhZ0lkOiBudW1iZXIpIHtcclxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMudGFnUmVwby5kZWxldGUoeyBjb3JyZXNwb25kZW5jZUlkOiBpZCwgdGFnSWQgfSk7XHJcbiAgICBpZiAocmVzdWx0LmFmZmVjdGVkID09PSAwKSB7XHJcbiAgICAgIHRocm93IG5ldyBOb3RGb3VuZEV4Y2VwdGlvbignVGFnIGFzc2lnbm1lbnQgbm90IGZvdW5kJyk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBhc3luYyBnZXRSZWZlcmVuY2VzKGlkOiBudW1iZXIpIHtcclxuICAgIGNvbnN0IG91dGdvaW5nID0gYXdhaXQgdGhpcy5yZWZlcmVuY2VSZXBvLmZpbmQoe1xyXG4gICAgICB3aGVyZTogeyBzb3VyY2VJZDogaWQgfSxcclxuICAgICAgcmVsYXRpb25zOiBbJ3RhcmdldCcsICd0YXJnZXQudHlwZSddLFxyXG4gICAgfSk7XHJcblxyXG4gICAgY29uc3QgaW5jb21pbmcgPSBhd2FpdCB0aGlzLnJlZmVyZW5jZVJlcG8uZmluZCh7XHJcbiAgICAgIHdoZXJlOiB7IHRhcmdldElkOiBpZCB9LFxyXG4gICAgICByZWxhdGlvbnM6IFsnc291cmNlJywgJ3NvdXJjZS50eXBlJ10sXHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4geyBvdXRnb2luZywgaW5jb21pbmcgfTtcclxuICB9XHJcblxyXG4gIGFzeW5jIHVwZGF0ZShpZDogbnVtYmVyLCB1cGRhdGVEdG86IFVwZGF0ZUNvcnJlc3BvbmRlbmNlRHRvLCB1c2VyOiBVc2VyKSB7XHJcbiAgICAvLyAxLiBGaW5kIEN1cnJlbnQgUmV2aXNpb25cclxuICAgIGNvbnN0IHJldmlzaW9uID0gYXdhaXQgdGhpcy5yZXZpc2lvblJlcG8uZmluZE9uZSh7XHJcbiAgICAgIHdoZXJlOiB7XHJcbiAgICAgICAgY29ycmVzcG9uZGVuY2VJZDogaWQsXHJcbiAgICAgICAgaXNDdXJyZW50OiB0cnVlLFxyXG4gICAgICB9LFxyXG4gICAgICByZWxhdGlvbnM6IFsnY29ycmVzcG9uZGVuY2UnXSxcclxuICAgIH0pO1xyXG5cclxuICAgIGlmICghcmV2aXNpb24pIHtcclxuICAgICAgdGhyb3cgbmV3IE5vdEZvdW5kRXhjZXB0aW9uKFxyXG4gICAgICAgIGBDdXJyZW50IHJldmlzaW9uIGZvciBjb3JyZXNwb25kZW5jZSAke2lkfSBub3QgZm91bmRgXHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gMi4gQ2hlY2sgUGVybWlzc2lvblxyXG4gICAgaWYgKHJldmlzaW9uLnN0YXR1c0lkKSB7XHJcbiAgICAgIGNvbnN0IHN0YXR1cyA9IGF3YWl0IHRoaXMuc3RhdHVzUmVwby5maW5kT25lKHtcclxuICAgICAgICB3aGVyZTogeyBpZDogcmV2aXNpb24uc3RhdHVzSWQgfSxcclxuICAgICAgfSk7XHJcbiAgICAgIGlmIChzdGF0dXMgJiYgc3RhdHVzLnN0YXR1c0NvZGUgIT09ICdEUkFGVCcpIHtcclxuICAgICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbignT25seSBEUkFGVCBkb2N1bWVudHMgY2FuIGJlIHVwZGF0ZWQnKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIEFEUi0wMTk6IFJlc29sdmUgVVVJRCByZWZlcmVuY2VzIGluIHVwZGF0ZSBEVE9cclxuICAgIGNvbnN0IHVwZFJlc29sdmVkUHJvamVjdElkID0gdXBkYXRlRHRvLnByb2plY3RJZFxyXG4gICAgICA/IGF3YWl0IHRoaXMudXVpZFJlc29sdmVyLnJlc29sdmVQcm9qZWN0SWQodXBkYXRlRHRvLnByb2plY3RJZClcclxuICAgICAgOiB1bmRlZmluZWQ7XHJcbiAgICBjb25zdCB1cGRSZXNvbHZlZE9yaWdpbmF0b3JJZCA9IHVwZGF0ZUR0by5vcmlnaW5hdG9ySWRcclxuICAgICAgPyBhd2FpdCB0aGlzLnV1aWRSZXNvbHZlci5yZXNvbHZlT3JnYW5pemF0aW9uSWQodXBkYXRlRHRvLm9yaWdpbmF0b3JJZClcclxuICAgICAgOiB1bmRlZmluZWQ7XHJcbiAgICBjb25zdCB1cGRSZXNvbHZlZFJlY2lwaWVudHMgPSB1cGRhdGVEdG8ucmVjaXBpZW50c1xyXG4gICAgICA/IGF3YWl0IFByb21pc2UuYWxsKFxyXG4gICAgICAgICAgdXBkYXRlRHRvLnJlY2lwaWVudHMubWFwKFxyXG4gICAgICAgICAgICBhc3luYyAocik6IFByb21pc2U8UmVzb2x2ZWRSZWNpcGllbnQ+ID0+ICh7XHJcbiAgICAgICAgICAgICAgb3JnYW5pemF0aW9uSWQ6IGF3YWl0IHRoaXMudXVpZFJlc29sdmVyLnJlc29sdmVPcmdhbml6YXRpb25JZChcclxuICAgICAgICAgICAgICAgIHIub3JnYW5pemF0aW9uSWRcclxuICAgICAgICAgICAgICApLFxyXG4gICAgICAgICAgICAgIHR5cGU6IHIudHlwZSxcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgIClcclxuICAgICAgICApXHJcbiAgICAgIDogdW5kZWZpbmVkO1xyXG5cclxuICAgIC8vIDMuIFVwZGF0ZSBDb3JyZXNwb25kZW5jZSBFbnRpdHkgaWYgbmVlZGVkXHJcbiAgICBjb25zdCBjb3JyZXNwb25kZW5jZVVwZGF0ZTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcclxuICAgIGlmICh1cGRhdGVEdG8uZGlzY2lwbGluZUlkKVxyXG4gICAgICBjb3JyZXNwb25kZW5jZVVwZGF0ZS5kaXNjaXBsaW5lSWQgPSB1cGRhdGVEdG8uZGlzY2lwbGluZUlkO1xyXG4gICAgaWYgKHVwZFJlc29sdmVkUHJvamVjdElkKVxyXG4gICAgICBjb3JyZXNwb25kZW5jZVVwZGF0ZS5wcm9qZWN0SWQgPSB1cGRSZXNvbHZlZFByb2plY3RJZDtcclxuICAgIGlmICh1cGRSZXNvbHZlZE9yaWdpbmF0b3JJZClcclxuICAgICAgY29ycmVzcG9uZGVuY2VVcGRhdGUub3JpZ2luYXRvcklkID0gdXBkUmVzb2x2ZWRPcmlnaW5hdG9ySWQ7XHJcblxyXG4gICAgaWYgKE9iamVjdC5rZXlzKGNvcnJlc3BvbmRlbmNlVXBkYXRlKS5sZW5ndGggPiAwKSB7XHJcbiAgICAgIGF3YWl0IHRoaXMuY29ycmVzcG9uZGVuY2VSZXBvLnVwZGF0ZShpZCwgY29ycmVzcG9uZGVuY2VVcGRhdGUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIDQuIFVwZGF0ZSBSZXZpc2lvbiBFbnRpdHlcclxuICAgIGNvbnN0IHJldmlzaW9uVXBkYXRlOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9O1xyXG4gICAgaWYgKHVwZGF0ZUR0by5zdWJqZWN0KSByZXZpc2lvblVwZGF0ZS5zdWJqZWN0ID0gdXBkYXRlRHRvLnN1YmplY3Q7XHJcbiAgICBpZiAodXBkYXRlRHRvLmJvZHkpIHJldmlzaW9uVXBkYXRlLmJvZHkgPSB1cGRhdGVEdG8uYm9keTtcclxuICAgIGlmICh1cGRhdGVEdG8ucmVtYXJrcykgcmV2aXNpb25VcGRhdGUucmVtYXJrcyA9IHVwZGF0ZUR0by5yZW1hcmtzO1xyXG4gICAgLy8gRm9ybWF0IERhdGUgY29ycmVjdGx5IGlmIHN0cmluZ1xyXG4gICAgaWYgKHVwZGF0ZUR0by5kdWVEYXRlKSByZXZpc2lvblVwZGF0ZS5kdWVEYXRlID0gbmV3IERhdGUodXBkYXRlRHRvLmR1ZURhdGUpO1xyXG4gICAgaWYgKHVwZGF0ZUR0by5kb2N1bWVudERhdGUpXHJcbiAgICAgIHJldmlzaW9uVXBkYXRlLmRvY3VtZW50RGF0ZSA9IG5ldyBEYXRlKHVwZGF0ZUR0by5kb2N1bWVudERhdGUpO1xyXG4gICAgaWYgKHVwZGF0ZUR0by5pc3N1ZWREYXRlKVxyXG4gICAgICByZXZpc2lvblVwZGF0ZS5pc3N1ZWREYXRlID0gbmV3IERhdGUodXBkYXRlRHRvLmlzc3VlZERhdGUpO1xyXG4gICAgaWYgKHVwZGF0ZUR0by5yZWNlaXZlZERhdGUpXHJcbiAgICAgIHJldmlzaW9uVXBkYXRlLnJlY2VpdmVkRGF0ZSA9IG5ldyBEYXRlKHVwZGF0ZUR0by5yZWNlaXZlZERhdGUpO1xyXG4gICAgaWYgKHVwZGF0ZUR0by5kZXNjcmlwdGlvbilcclxuICAgICAgcmV2aXNpb25VcGRhdGUuZGVzY3JpcHRpb24gPSB1cGRhdGVEdG8uZGVzY3JpcHRpb247XHJcbiAgICBpZiAodXBkYXRlRHRvLmRldGFpbHMpIHJldmlzaW9uVXBkYXRlLmRldGFpbHMgPSB1cGRhdGVEdG8uZGV0YWlscztcclxuXHJcbiAgICBpZiAoT2JqZWN0LmtleXMocmV2aXNpb25VcGRhdGUpLmxlbmd0aCA+IDApIHtcclxuICAgICAgYXdhaXQgdGhpcy5yZXZpc2lvblJlcG8udXBkYXRlKHJldmlzaW9uLmlkLCByZXZpc2lvblVwZGF0ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gNC41IENvbW1pdCBuZXcgYXR0YWNobWVudHMgZnJvbSBUZW1wIOKGkiBQZXJtYW5lbnQgKFR3by1QaGFzZSBTdG9yYWdlKVxyXG4gICAgaWYgKHVwZGF0ZUR0by5hdHRhY2htZW50VGVtcElkcz8ubGVuZ3RoKSB7XHJcbiAgICAgIGNvbnN0IGlzc3VlRGF0ZSA9IHVwZGF0ZUR0by5pc3N1ZWREYXRlXHJcbiAgICAgICAgPyBuZXcgRGF0ZSh1cGRhdGVEdG8uaXNzdWVkRGF0ZSlcclxuICAgICAgICA6IHVwZGF0ZUR0by5kb2N1bWVudERhdGVcclxuICAgICAgICAgID8gbmV3IERhdGUodXBkYXRlRHRvLmRvY3VtZW50RGF0ZSlcclxuICAgICAgICAgIDogcmV2aXNpb24uaXNzdWVkRGF0ZSB8fCByZXZpc2lvbi5kb2N1bWVudERhdGUgfHwgdW5kZWZpbmVkO1xyXG5cclxuICAgICAgYXdhaXQgdGhpcy5maWxlU3RvcmFnZVNlcnZpY2UuY29tbWl0KHVwZGF0ZUR0by5hdHRhY2htZW50VGVtcElkcywge1xyXG4gICAgICAgIGlzc3VlRGF0ZTogaXNzdWVEYXRlID8gbmV3IERhdGUoaXNzdWVEYXRlKSA6IHVuZGVmaW5lZCxcclxuICAgICAgICBkb2N1bWVudFR5cGU6ICdDb3JyZXNwb25kZW5jZScsXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIDUuIFVwZGF0ZSBSZWNpcGllbnRzIGlmIHByb3ZpZGVkXHJcbiAgICBpZiAodXBkUmVzb2x2ZWRSZWNpcGllbnRzKSB7XHJcbiAgICAgIGNvbnN0IHJlY2lwaWVudFJlcG8gPSB0aGlzLmRhdGFTb3VyY2UuZ2V0UmVwb3NpdG9yeShcclxuICAgICAgICBDb3JyZXNwb25kZW5jZVJlY2lwaWVudFxyXG4gICAgICApO1xyXG4gICAgICBhd2FpdCByZWNpcGllbnRSZXBvLmRlbGV0ZSh7IGNvcnJlc3BvbmRlbmNlSWQ6IGlkIH0pO1xyXG5cclxuICAgICAgY29uc3QgbmV3UmVjaXBpZW50cyA9IHVwZFJlc29sdmVkUmVjaXBpZW50cy5tYXAoKHIpID0+XHJcbiAgICAgICAgcmVjaXBpZW50UmVwby5jcmVhdGUoe1xyXG4gICAgICAgICAgY29ycmVzcG9uZGVuY2VJZDogaWQsXHJcbiAgICAgICAgICByZWNpcGllbnRPcmdhbml6YXRpb25JZDogci5vcmdhbml6YXRpb25JZCxcclxuICAgICAgICAgIHJlY2lwaWVudFR5cGU6IHIudHlwZSxcclxuICAgICAgICB9KVxyXG4gICAgICApO1xyXG4gICAgICBhd2FpdCByZWNpcGllbnRSZXBvLnNhdmUobmV3UmVjaXBpZW50cyk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gNi4gUmVnZW5lcmF0ZSBEb2N1bWVudCBOdW1iZXIgaWYgc3RydWN0dXJhbCBmaWVsZHMgY2hhbmdlZCAoUmVjaXBpZW50LCBEaXNjaXBsaW5lLCBUeXBlLCBQcm9qZWN0KVxyXG4gICAgLy8gQU5EIGl0IGlzIGEgRFJBRlQuXHJcblxyXG4gICAgLy8gRmV0Y2ggZnJlc2ggZGF0YSBmb3IgY29udGV4dCBhbmQgY29tcGFyaXNvblxyXG4gICAgY29uc3QgY3VycmVudENvcnIgPSBhd2FpdCB0aGlzLmNvcnJlc3BvbmRlbmNlUmVwby5maW5kT25lKHtcclxuICAgICAgd2hlcmU6IHsgaWQgfSxcclxuICAgICAgcmVsYXRpb25zOiBbJ3R5cGUnLCAncmVjaXBpZW50cycsICdyZWNpcGllbnRzLnJlY2lwaWVudE9yZ2FuaXphdGlvbiddLFxyXG4gICAgfSk7XHJcblxyXG4gICAgaWYgKGN1cnJlbnRDb3JyKSB7XHJcbiAgICAgIGNvbnN0IGN1cnJlbnRUb1JlY2lwaWVudCA9IGN1cnJlbnRDb3JyLnJlY2lwaWVudHM/LmZpbmQoXHJcbiAgICAgICAgKHIpID0+IHIucmVjaXBpZW50VHlwZSA9PT0gJ1RPJ1xyXG4gICAgICApO1xyXG4gICAgICBjb25zdCBjdXJyZW50UmVjaXBpZW50SWQgPSBjdXJyZW50VG9SZWNpcGllbnQ/LnJlY2lwaWVudE9yZ2FuaXphdGlvbklkO1xyXG5cclxuICAgICAgLy8gQ2hlY2sgZm9yIEFDVFVBTCB2YWx1ZSBjaGFuZ2VzXHJcbiAgICAgIGNvbnN0IGlzUHJvamVjdENoYW5nZWQgPVxyXG4gICAgICAgIHVwZFJlc29sdmVkUHJvamVjdElkICE9PSB1bmRlZmluZWQgJiZcclxuICAgICAgICB1cGRSZXNvbHZlZFByb2plY3RJZCAhPT0gY3VycmVudENvcnIucHJvamVjdElkO1xyXG4gICAgICBjb25zdCBpc09yaWdpbmF0b3JDaGFuZ2VkID1cclxuICAgICAgICB1cGRSZXNvbHZlZE9yaWdpbmF0b3JJZCAhPT0gdW5kZWZpbmVkICYmXHJcbiAgICAgICAgdXBkUmVzb2x2ZWRPcmlnaW5hdG9ySWQgIT09IGN1cnJlbnRDb3JyLm9yaWdpbmF0b3JJZDtcclxuICAgICAgY29uc3QgaXNEaXNjaXBsaW5lQ2hhbmdlZCA9XHJcbiAgICAgICAgdXBkYXRlRHRvLmRpc2NpcGxpbmVJZCAhPT0gdW5kZWZpbmVkICYmXHJcbiAgICAgICAgdXBkYXRlRHRvLmRpc2NpcGxpbmVJZCAhPT0gY3VycmVudENvcnIuZGlzY2lwbGluZUlkO1xyXG4gICAgICBjb25zdCBpc1R5cGVDaGFuZ2VkID1cclxuICAgICAgICB1cGRhdGVEdG8udHlwZUlkICE9PSB1bmRlZmluZWQgJiZcclxuICAgICAgICB1cGRhdGVEdG8udHlwZUlkICE9PSBjdXJyZW50Q29yci5jb3JyZXNwb25kZW5jZVR5cGVJZDtcclxuXHJcbiAgICAgIGxldCBpc1JlY2lwaWVudENoYW5nZWQgPSBmYWxzZTtcclxuICAgICAgbGV0IG5ld1JlY2lwaWVudElkOiBudW1iZXIgfCB1bmRlZmluZWQ7XHJcblxyXG4gICAgICBpZiAodXBkUmVzb2x2ZWRSZWNpcGllbnRzKSB7XHJcbiAgICAgICAgY29uc3QgbmV3VG9SZWNpcGllbnQgPSB1cGRSZXNvbHZlZFJlY2lwaWVudHMuZmluZChcclxuICAgICAgICAgIChyKSA9PiByLnR5cGUgPT09ICdUTydcclxuICAgICAgICApO1xyXG4gICAgICAgIG5ld1JlY2lwaWVudElkID0gbmV3VG9SZWNpcGllbnQ/Lm9yZ2FuaXphdGlvbklkO1xyXG5cclxuICAgICAgICBpZiAobmV3UmVjaXBpZW50SWQgIT09IGN1cnJlbnRSZWNpcGllbnRJZCkge1xyXG4gICAgICAgICAgaXNSZWNpcGllbnRDaGFuZ2VkID0gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChcclxuICAgICAgICBpc1Byb2plY3RDaGFuZ2VkIHx8XHJcbiAgICAgICAgaXNEaXNjaXBsaW5lQ2hhbmdlZCB8fFxyXG4gICAgICAgIGlzVHlwZUNoYW5nZWQgfHxcclxuICAgICAgICBpc1JlY2lwaWVudENoYW5nZWQgfHxcclxuICAgICAgICBpc09yaWdpbmF0b3JDaGFuZ2VkXHJcbiAgICAgICkge1xyXG4gICAgICAgIGNvbnN0IHRhcmdldFJlY2lwaWVudElkID0gaXNSZWNpcGllbnRDaGFuZ2VkXHJcbiAgICAgICAgICA/IG5ld1JlY2lwaWVudElkXHJcbiAgICAgICAgICA6IGN1cnJlbnRSZWNpcGllbnRJZDtcclxuXHJcbiAgICAgICAgLy8gUmVzb2x2ZSBSZWNpcGllbnQgQ29kZSBmb3IgdGhlIE5FVyBjb250ZXh0XHJcbiAgICAgICAgbGV0IHJlY2lwaWVudENvZGUgPSAnJztcclxuICAgICAgICBpZiAodGFyZ2V0UmVjaXBpZW50SWQpIHtcclxuICAgICAgICAgIGNvbnN0IHJlY09yZyA9IGF3YWl0IHRoaXMuZGF0YVNvdXJjZS5tYW5hZ2VyLmZpbmRPbmUoT3JnYW5pemF0aW9uLCB7XHJcbiAgICAgICAgICAgIHdoZXJlOiB7IGlkOiB0YXJnZXRSZWNpcGllbnRJZCB9LFxyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgICBpZiAocmVjT3JnKSByZWNpcGllbnRDb2RlID0gcmVjT3JnLm9yZ2FuaXphdGlvbkNvZGU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBbRml4ICM2XSBGZXRjaCByZWFsIE9SRyBDb2RlIGZyb20gb3JpZ2luYXRvciBvcmdhbml6YXRpb25cclxuICAgICAgICBjb25zdCBvcmlnaW5hdG9yT3JnRm9yVXBkYXRlID0gYXdhaXQgdGhpcy5kYXRhU291cmNlLm1hbmFnZXIuZmluZE9uZShcclxuICAgICAgICAgIE9yZ2FuaXphdGlvbixcclxuICAgICAgICAgIHtcclxuICAgICAgICAgICAgd2hlcmU6IHtcclxuICAgICAgICAgICAgICBpZDogdXBkUmVzb2x2ZWRPcmlnaW5hdG9ySWQgPz8gY3VycmVudENvcnIub3JpZ2luYXRvcklkID8/IDAsXHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgKTtcclxuICAgICAgICBjb25zdCBvcmdDb2RlID0gb3JpZ2luYXRvck9yZ0ZvclVwZGF0ZT8ub3JnYW5pemF0aW9uQ29kZSA/PyAnVU5LJztcclxuXHJcbiAgICAgICAgLy8gUHJlcGFyZSBDb250ZXh0c1xyXG4gICAgICAgIGNvbnN0IG9sZEN0eCA9IHtcclxuICAgICAgICAgIHByb2plY3RJZDogY3VycmVudENvcnIucHJvamVjdElkLFxyXG4gICAgICAgICAgb3JpZ2luYXRvck9yZ2FuaXphdGlvbklkOiBjdXJyZW50Q29yci5vcmlnaW5hdG9ySWQgPz8gMCxcclxuICAgICAgICAgIHR5cGVJZDogY3VycmVudENvcnIuY29ycmVzcG9uZGVuY2VUeXBlSWQsXHJcbiAgICAgICAgICBkaXNjaXBsaW5lSWQ6IGN1cnJlbnRDb3JyLmRpc2NpcGxpbmVJZCxcclxuICAgICAgICAgIHJlY2lwaWVudE9yZ2FuaXphdGlvbklkOiBjdXJyZW50UmVjaXBpZW50SWQsXHJcbiAgICAgICAgICB5ZWFyOiBuZXcgRGF0ZSgpLmdldEZ1bGxZZWFyKCksXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgY29uc3QgbmV3Q3R4ID0ge1xyXG4gICAgICAgICAgcHJvamVjdElkOiB1cGRSZXNvbHZlZFByb2plY3RJZCA/PyBjdXJyZW50Q29yci5wcm9qZWN0SWQsXHJcbiAgICAgICAgICBvcmlnaW5hdG9yT3JnYW5pemF0aW9uSWQ6XHJcbiAgICAgICAgICAgIHVwZFJlc29sdmVkT3JpZ2luYXRvcklkID8/IGN1cnJlbnRDb3JyLm9yaWdpbmF0b3JJZCA/PyAwLFxyXG4gICAgICAgICAgdHlwZUlkOiB1cGRhdGVEdG8udHlwZUlkID8/IGN1cnJlbnRDb3JyLmNvcnJlc3BvbmRlbmNlVHlwZUlkLFxyXG4gICAgICAgICAgZGlzY2lwbGluZUlkOiB1cGRhdGVEdG8uZGlzY2lwbGluZUlkID8/IGN1cnJlbnRDb3JyLmRpc2NpcGxpbmVJZCxcclxuICAgICAgICAgIHJlY2lwaWVudE9yZ2FuaXphdGlvbklkOiB0YXJnZXRSZWNpcGllbnRJZCxcclxuICAgICAgICAgIHllYXI6IG5ldyBEYXRlKCkuZ2V0RnVsbFllYXIoKSxcclxuICAgICAgICAgIHVzZXJJZDogdXNlci51c2VyX2lkLCAvLyBQYXNzIFVzZXIgSUQgZm9yIEF1ZGl0XHJcbiAgICAgICAgICBjdXN0b21Ub2tlbnM6IHtcclxuICAgICAgICAgICAgVFlQRV9DT0RFOiBjdXJyZW50Q29yci50eXBlPy50eXBlQ29kZSB8fCAnJyxcclxuICAgICAgICAgICAgT1JHX0NPREU6IG9yZ0NvZGUsXHJcbiAgICAgICAgICAgIFJFQ0lQSUVOVF9DT0RFOiByZWNpcGllbnRDb2RlLFxyXG4gICAgICAgICAgICBSRUNfQ09ERTogcmVjaXBpZW50Q29kZSxcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLy8gSWYgVHlwZSBDaGFuZ2VkLCBuZWVkIE5FVyBUeXBlIENvZGVcclxuICAgICAgICBpZiAoaXNUeXBlQ2hhbmdlZCkge1xyXG4gICAgICAgICAgY29uc3QgbmV3VHlwZSA9IGF3YWl0IHRoaXMudHlwZVJlcG8uZmluZE9uZSh7XHJcbiAgICAgICAgICAgIHdoZXJlOiB7IGlkOiBuZXdDdHgudHlwZUlkIH0sXHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICAgIGlmIChuZXdUeXBlKSBuZXdDdHguY3VzdG9tVG9rZW5zLlRZUEVfQ09ERSA9IG5ld1R5cGUudHlwZUNvZGU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBuZXdEb2NOdW1iZXIgPSBhd2FpdCB0aGlzLm51bWJlcmluZ1NlcnZpY2UudXBkYXRlTnVtYmVyRm9yRHJhZnQoXHJcbiAgICAgICAgICBjdXJyZW50Q29yci5jb3JyZXNwb25kZW5jZU51bWJlcixcclxuICAgICAgICAgIG9sZEN0eCxcclxuICAgICAgICAgIG5ld0N0eFxyXG4gICAgICAgICk7XHJcblxyXG4gICAgICAgIGF3YWl0IHRoaXMuY29ycmVzcG9uZGVuY2VSZXBvLnVwZGF0ZShpZCwge1xyXG4gICAgICAgICAgY29ycmVzcG9uZGVuY2VOdW1iZXI6IG5ld0RvY051bWJlcixcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHVwZGF0ZWQgPSBhd2FpdCB0aGlzLmZpbmRPbmUoaWQpO1xyXG5cclxuICAgIC8vIFJlLWluZGV4IHVwZGF0ZWQgZG9jdW1lbnQgaW4gRWxhc3RpY3NlYXJjaCAoZmlyZS1hbmQtZm9yZ2V0KVxyXG4gICAgdm9pZCB0aGlzLnNlYXJjaFNlcnZpY2UuaW5kZXhEb2N1bWVudCh7XHJcbiAgICAgIGlkOiB1cGRhdGVkLmlkLFxyXG4gICAgICBwdWJsaWNJZDogdXBkYXRlZC5wdWJsaWNJZCxcclxuICAgICAgdHlwZTogJ2NvcnJlc3BvbmRlbmNlJyxcclxuICAgICAgZG9jTnVtYmVyOiB1cGRhdGVkLmNvcnJlc3BvbmRlbmNlTnVtYmVyLFxyXG4gICAgICB0aXRsZTogdXBkYXRlRHRvLnN1YmplY3QgPz8gdXBkYXRlZC5yZXZpc2lvbnM/LlswXT8uc3ViamVjdCxcclxuICAgICAgZGVzY3JpcHRpb246IHVwZGF0ZUR0by5kZXNjcmlwdGlvbiA/PyB1cGRhdGVkLnJldmlzaW9ucz8uWzBdPy5kZXNjcmlwdGlvbixcclxuICAgICAgc3RhdHVzOiAnRFJBRlQnLFxyXG4gICAgICBwcm9qZWN0SWQ6IHVwZGF0ZWQucHJvamVjdElkLFxyXG4gICAgICBjcmVhdGVkQXQ6IHVwZGF0ZWQuY3JlYXRlZEF0LFxyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIHVwZGF0ZWQ7XHJcbiAgfVxyXG5cclxuICBhc3luYyBwcmV2aWV3RG9jdW1lbnROdW1iZXIoY3JlYXRlRHRvOiBDcmVhdGVDb3JyZXNwb25kZW5jZUR0bywgdXNlcjogVXNlcikge1xyXG4gICAgLy8gQURSLTAxOTogUmVzb2x2ZSBVVUlEIHJlZmVyZW5jZXNcclxuICAgIGNvbnN0IHByZXZpZXdQcm9qZWN0SWQgPSBhd2FpdCB0aGlzLnV1aWRSZXNvbHZlci5yZXNvbHZlUHJvamVjdElkKFxyXG4gICAgICBjcmVhdGVEdG8ucHJvamVjdElkXHJcbiAgICApO1xyXG4gICAgY29uc3QgcHJldmlld09yaWdpbmF0b3JJZCA9IGNyZWF0ZUR0by5vcmlnaW5hdG9ySWRcclxuICAgICAgPyBhd2FpdCB0aGlzLnV1aWRSZXNvbHZlci5yZXNvbHZlT3JnYW5pemF0aW9uSWQoY3JlYXRlRHRvLm9yaWdpbmF0b3JJZClcclxuICAgICAgOiB1bmRlZmluZWQ7XHJcbiAgICBjb25zdCBwcmV2aWV3UmVjaXBpZW50cyA9IGNyZWF0ZUR0by5yZWNpcGllbnRzXHJcbiAgICAgID8gYXdhaXQgUHJvbWlzZS5hbGwoXHJcbiAgICAgICAgICBjcmVhdGVEdG8ucmVjaXBpZW50cy5tYXAoXHJcbiAgICAgICAgICAgIGFzeW5jIChyKTogUHJvbWlzZTxSZXNvbHZlZFJlY2lwaWVudD4gPT4gKHtcclxuICAgICAgICAgICAgICBvcmdhbml6YXRpb25JZDogYXdhaXQgdGhpcy51dWlkUmVzb2x2ZXIucmVzb2x2ZU9yZ2FuaXphdGlvbklkKFxyXG4gICAgICAgICAgICAgICAgci5vcmdhbml6YXRpb25JZFxyXG4gICAgICAgICAgICAgICksXHJcbiAgICAgICAgICAgICAgdHlwZTogci50eXBlLFxyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgKVxyXG4gICAgICAgIClcclxuICAgICAgOiB1bmRlZmluZWQ7XHJcblxyXG4gICAgY29uc3QgdHlwZSA9IGF3YWl0IHRoaXMudHlwZVJlcG8uZmluZE9uZSh7XHJcbiAgICAgIHdoZXJlOiB7IGlkOiBjcmVhdGVEdG8udHlwZUlkIH0sXHJcbiAgICB9KTtcclxuICAgIGlmICghdHlwZSkgdGhyb3cgbmV3IE5vdEZvdW5kRXhjZXB0aW9uKCdEb2N1bWVudCBUeXBlIG5vdCBmb3VuZCcpO1xyXG5cclxuICAgIGxldCB1c2VyT3JnSWQgPSB1c2VyLnByaW1hcnlPcmdhbml6YXRpb25JZDtcclxuICAgIGlmICghdXNlck9yZ0lkKSB7XHJcbiAgICAgIGNvbnN0IGZ1bGxVc2VyID0gYXdhaXQgdGhpcy51c2VyU2VydmljZS5maW5kT25lKHVzZXIudXNlcl9pZCk7XHJcbiAgICAgIGlmIChmdWxsVXNlcikgdXNlck9yZ0lkID0gZnVsbFVzZXIucHJpbWFyeU9yZ2FuaXphdGlvbklkO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChwcmV2aWV3T3JpZ2luYXRvcklkICYmIHByZXZpZXdPcmlnaW5hdG9ySWQgIT09IHVzZXJPcmdJZCkge1xyXG4gICAgICAvLyBBbGxvdyBpbXBlcnNvbmF0aW9uIGZvciBwcmV2aWV3XHJcbiAgICAgIHVzZXJPcmdJZCA9IHByZXZpZXdPcmlnaW5hdG9ySWQ7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gRXh0cmFjdCByZWNpcGllbnQgZnJvbSByZWNpcGllbnRzIGFycmF5XHJcbiAgICBjb25zdCB0b1JlY2lwaWVudCA9IHByZXZpZXdSZWNpcGllbnRzPy5maW5kKChyKSA9PiByLnR5cGUgPT09ICdUTycpO1xyXG4gICAgY29uc3QgcmVjaXBpZW50T3JnYW5pemF0aW9uSWQgPSB0b1JlY2lwaWVudD8ub3JnYW5pemF0aW9uSWQ7XHJcblxyXG4gICAgbGV0IHJlY2lwaWVudENvZGUgPSAnJztcclxuICAgIGlmIChyZWNpcGllbnRPcmdhbml6YXRpb25JZCkge1xyXG4gICAgICBjb25zdCByZWNPcmcgPSBhd2FpdCB0aGlzLmRhdGFTb3VyY2UubWFuYWdlci5maW5kT25lKE9yZ2FuaXphdGlvbiwge1xyXG4gICAgICAgIHdoZXJlOiB7IGlkOiByZWNpcGllbnRPcmdhbml6YXRpb25JZCB9LFxyXG4gICAgICB9KTtcclxuICAgICAgaWYgKHJlY09yZykgcmVjaXBpZW50Q29kZSA9IHJlY09yZy5vcmdhbml6YXRpb25Db2RlO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzLm51bWJlcmluZ1NlcnZpY2UucHJldmlld051bWJlcih7XHJcbiAgICAgIHByb2plY3RJZDogcHJldmlld1Byb2plY3RJZCxcclxuICAgICAgb3JpZ2luYXRvck9yZ2FuaXphdGlvbklkOiB1c2VyT3JnSWQhLFxyXG4gICAgICB0eXBlSWQ6IGNyZWF0ZUR0by50eXBlSWQsXHJcbiAgICAgIGRpc2NpcGxpbmVJZDogY3JlYXRlRHRvLmRpc2NpcGxpbmVJZCxcclxuICAgICAgc3ViVHlwZUlkOiBjcmVhdGVEdG8uc3ViVHlwZUlkLFxyXG4gICAgICByZWNpcGllbnRPcmdhbml6YXRpb25JZCxcclxuICAgICAgeWVhcjogbmV3IERhdGUoKS5nZXRGdWxsWWVhcigpLFxyXG4gICAgICBjdXN0b21Ub2tlbnM6IHtcclxuICAgICAgICBUWVBFX0NPREU6IHR5cGUudHlwZUNvZGUsXHJcbiAgICAgICAgUkVDSVBJRU5UX0NPREU6IHJlY2lwaWVudENvZGUsXHJcbiAgICAgICAgUkVDX0NPREU6IHJlY2lwaWVudENvZGUsXHJcbiAgICAgIH0sXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEJ1c2luZXNzIFJ1bGUgSW1wbGVtZW50YXRpb246IEVDLUNPUlItMDAxIC0gQ2FuY2VsIENvcnJlc3BvbmRlbmNlIHdpdGggRG93bnN0cmVhbSBDaXJjdWxhdGlvblxyXG4gICAqIENhbmNlbCBjb3JyZXNwb25kZW5jZSBhbmQgaGFuZGxlIHJlbGF0ZWQgY2lyY3VsYXRpb25zXHJcbiAgICovXHJcbiAgYXN5bmMgY2FuY2VsKHB1YmxpY0lkOiBzdHJpbmcsIHJlYXNvbjogc3RyaW5nLCB1c2VyOiBVc2VyKSB7XHJcbiAgICBjb25zdCBjb3JyZXNwb25kZW5jZSA9IGF3YWl0IHRoaXMuZmluZE9uZUJ5VXVpZChwdWJsaWNJZCk7XHJcblxyXG4gICAgLy8gQ2hlY2sgaWYgdXNlciBoYXMgcGVybWlzc2lvbiB0byBjYW5jZWwgKE9yZyBBZG1pbiBvciBTdXBlcmFkbWluIG9ubHkpXHJcbiAgICBjb25zdCBwZXJtaXNzaW9ucyA9IGF3YWl0IHRoaXMudXNlclNlcnZpY2UuZ2V0VXNlclBlcm1pc3Npb25zKHVzZXIudXNlcl9pZCk7XHJcbiAgICBjb25zdCBjYW5DYW5jZWwgPVxyXG4gICAgICBwZXJtaXNzaW9ucy5pbmNsdWRlcygnY29ycmVzcG9uZGVuY2UuY2FuY2VsJykgfHxcclxuICAgICAgcGVybWlzc2lvbnMuaW5jbHVkZXMoJ3N5c3RlbS5tYW5hZ2VfYWxsJyk7XHJcblxyXG4gICAgaWYgKCFjYW5DYW5jZWwpIHtcclxuICAgICAgdGhyb3cgbmV3IEZvcmJpZGRlbkV4Y2VwdGlvbihcclxuICAgICAgICAnT25seSBhZG1pbmlzdHJhdG9ycyBjYW4gY2FuY2VsIGNvcnJlc3BvbmRlbmNlcydcclxuICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBDaGVjayBpZiB0aGVyZSBhcmUgYW55IGFjdGl2ZSBjaXJjdWxhdGlvbnNcclxuICAgIGNvbnN0IGNpcmN1bGF0aW9uUmVwbyA9IHRoaXMuZGF0YVNvdXJjZS5nZXRSZXBvc2l0b3J5KCdDaXJjdWxhdGlvbicpO1xyXG4gICAgY29uc3QgYWN0aXZlQ2lyY3VsYXRpb25zID0gYXdhaXQgY2lyY3VsYXRpb25SZXBvLmZpbmQoe1xyXG4gICAgICB3aGVyZToge1xyXG4gICAgICAgIGNvcnJlc3BvbmRlbmNlSWQ6IGNvcnJlc3BvbmRlbmNlLmlkLFxyXG4gICAgICAgIHN0YXR1czogJ09QRU4nLFxyXG4gICAgICB9LFxyXG4gICAgfSk7XHJcblxyXG4gICAgY29uc3Qgd2FybmluZ01lc3NhZ2UgPVxyXG4gICAgICBhY3RpdmVDaXJjdWxhdGlvbnMubGVuZ3RoID4gMFxyXG4gICAgICAgID8gYFRoZXJlIGFyZSAke2FjdGl2ZUNpcmN1bGF0aW9ucy5sZW5ndGh9IGFjdGl2ZSBjaXJjdWxhdGlvbihzKSBmb3IgdGhpcyBjb3JyZXNwb25kZW5jZS4gQ2FuY2VsaW5nIHdpbGwgZm9yY2UgY2xvc2UgYWxsIHJlbGF0ZWQgY2lyY3VsYXRpb25zLmBcclxuICAgICAgICA6ICcnO1xyXG5cclxuICAgIC8vIEdldCB0aGUgY3VycmVudCByZXZpc2lvbiB0byB1cGRhdGUgc3RhdHVzXHJcbiAgICBjb25zdCBjdXJyZW50UmV2aXNpb24gPSBhd2FpdCB0aGlzLnJldmlzaW9uUmVwby5maW5kT25lKHtcclxuICAgICAgd2hlcmU6IHtcclxuICAgICAgICBjb3JyZXNwb25kZW5jZUlkOiBjb3JyZXNwb25kZW5jZS5pZCxcclxuICAgICAgICBpc0N1cnJlbnQ6IHRydWUsXHJcbiAgICAgIH0sXHJcbiAgICB9KTtcclxuXHJcbiAgICBpZiAoIWN1cnJlbnRSZXZpc2lvbikge1xyXG4gICAgICB0aHJvdyBuZXcgTm90Rm91bmRFeGNlcHRpb24oJ0N1cnJlbnQgcmV2aXNpb24gbm90IGZvdW5kJyk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gR2V0IGNhbmNlbGxlZCBzdGF0dXNcclxuICAgIGNvbnN0IGNhbmNlbGxlZFN0YXR1cyA9IGF3YWl0IHRoaXMuc3RhdHVzUmVwby5maW5kT25lKHtcclxuICAgICAgd2hlcmU6IHsgc3RhdHVzQ29kZTogJ0NBTkNFTExFRCcgfSxcclxuICAgIH0pO1xyXG5cclxuICAgIGlmICghY2FuY2VsbGVkU3RhdHVzKSB7XHJcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbFNlcnZlckVycm9yRXhjZXB0aW9uKCdDQU5DRUxMRUQgc3RhdHVzIG5vdCBmb3VuZCcpO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHF1ZXJ5UnVubmVyID0gdGhpcy5kYXRhU291cmNlLmNyZWF0ZVF1ZXJ5UnVubmVyKCk7XHJcbiAgICBhd2FpdCBxdWVyeVJ1bm5lci5jb25uZWN0KCk7XHJcbiAgICBhd2FpdCBxdWVyeVJ1bm5lci5zdGFydFRyYW5zYWN0aW9uKCk7XHJcblxyXG4gICAgdHJ5IHtcclxuICAgICAgLy8gVXBkYXRlIGNvcnJlc3BvbmRlbmNlIHJldmlzaW9uIHN0YXR1cyB0byBDQU5DRUxMRURcclxuICAgICAgYXdhaXQgcXVlcnlSdW5uZXIubWFuYWdlci51cGRhdGUoXHJcbiAgICAgICAgQ29ycmVzcG9uZGVuY2VSZXZpc2lvbixcclxuICAgICAgICBjdXJyZW50UmV2aXNpb24uaWQsXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgc3RhdHVzSWQ6IGNhbmNlbGxlZFN0YXR1cy5pZCxcclxuICAgICAgICAgIHJlbWFya3M6IGBDYW5jZWxsZWQ6ICR7cmVhc29ufWAsXHJcbiAgICAgICAgfVxyXG4gICAgICApO1xyXG5cclxuICAgICAgLy8gRm9yY2UgY2xvc2UgYWxsIGFjdGl2ZSBjaXJjdWxhdGlvbnNcclxuICAgICAgaWYgKGFjdGl2ZUNpcmN1bGF0aW9ucy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgYXdhaXQgcXVlcnlSdW5uZXIubWFuYWdlci51cGRhdGUoXHJcbiAgICAgICAgICAnQ2lyY3VsYXRpb24nLFxyXG4gICAgICAgICAge1xyXG4gICAgICAgICAgICBjb3JyZXNwb25kZW5jZUlkOiBjb3JyZXNwb25kZW5jZS5pZCxcclxuICAgICAgICAgICAgc3RhdHVzOiAnT1BFTicsXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgICAge1xyXG4gICAgICAgICAgICBzdGF0dXM6ICdGT1JDRV9DTE9TRUQnLFxyXG4gICAgICAgICAgICBjbG9zZWRBdDogbmV3IERhdGUoKSxcclxuICAgICAgICAgICAgY2xvc2VkQnk6IHVzZXIudXNlcl9pZCxcclxuICAgICAgICAgICAgY2xvc2VSZWFzb246IGBDb3JyZXNwb25kZW5jZSBjYW5jZWxsZWQ6ICR7cmVhc29ufWAsXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgYXdhaXQgcXVlcnlSdW5uZXIuY29tbWl0VHJhbnNhY3Rpb24oKTtcclxuXHJcbiAgICAgIC8vIFJlLWluZGV4IGNhbmNlbGxlZCBzdGF0dXMgaW4gRWxhc3RpY3NlYXJjaCAoZmlyZS1hbmQtZm9yZ2V0KVxyXG4gICAgICB2b2lkIHRoaXMuc2VhcmNoU2VydmljZS5pbmRleERvY3VtZW50KHtcclxuICAgICAgICBpZDogY29ycmVzcG9uZGVuY2UuaWQsXHJcbiAgICAgICAgcHVibGljSWQ6IGNvcnJlc3BvbmRlbmNlLnB1YmxpY0lkLFxyXG4gICAgICAgIHR5cGU6ICdjb3JyZXNwb25kZW5jZScsXHJcbiAgICAgICAgZG9jTnVtYmVyOiBjb3JyZXNwb25kZW5jZS5jb3JyZXNwb25kZW5jZU51bWJlcixcclxuICAgICAgICB0aXRsZTogY3VycmVudFJldmlzaW9uLnN1YmplY3QsXHJcbiAgICAgICAgc3RhdHVzOiAnQ0FOQ0VMTEVEJyxcclxuICAgICAgICBwcm9qZWN0SWQ6IGNvcnJlc3BvbmRlbmNlLnByb2plY3RJZCxcclxuICAgICAgICBjcmVhdGVkQXQ6IGNvcnJlc3BvbmRlbmNlLmNyZWF0ZWRBdCxcclxuICAgICAgfSk7XHJcblxyXG4gICAgICAvLyBOb3RpZnkgb3JpZ2luYXRvcidzIGRvYy1jb250cm9sIHVzZXIgYWJvdXQgY2FuY2VsbGF0aW9uIChmaXJlLWFuZC1mb3JnZXQpXHJcbiAgICAgIGlmIChjb3JyZXNwb25kZW5jZS5vcmlnaW5hdG9ySWQpIHtcclxuICAgICAgICB2b2lkIHRoaXMudXNlclNlcnZpY2VcclxuICAgICAgICAgIC5maW5kRG9jQ29udHJvbElkQnlPcmcoY29ycmVzcG9uZGVuY2Uub3JpZ2luYXRvcklkKVxyXG4gICAgICAgICAgLnRoZW4oKHRhcmdldFVzZXJJZCkgPT4ge1xyXG4gICAgICAgICAgICBpZiAodGFyZ2V0VXNlcklkKSB7XHJcbiAgICAgICAgICAgICAgdm9pZCB0aGlzLm5vdGlmaWNhdGlvblNlcnZpY2Uuc2VuZCh7XHJcbiAgICAgICAgICAgICAgICB1c2VySWQ6IHRhcmdldFVzZXJJZCxcclxuICAgICAgICAgICAgICAgIHRpdGxlOiAnQ29ycmVzcG9uZGVuY2UgQ2FuY2VsbGVkJyxcclxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGAke2NvcnJlc3BvbmRlbmNlLmNvcnJlc3BvbmRlbmNlTnVtYmVyfSDigJQgJHtjdXJyZW50UmV2aXNpb24uc3ViamVjdH0gaGFzIGJlZW4gY2FuY2VsbGVkLiBSZWFzb246ICR7cmVhc29ufWAsXHJcbiAgICAgICAgICAgICAgICB0eXBlOiAnRU1BSUwnLFxyXG4gICAgICAgICAgICAgICAgZW50aXR5VHlwZTogJ2NvcnJlc3BvbmRlbmNlJyxcclxuICAgICAgICAgICAgICAgIGVudGl0eUlkOiBjb3JyZXNwb25kZW5jZS5pZCxcclxuICAgICAgICAgICAgICAgIGxpbms6IGAvY29ycmVzcG9uZGVuY2VzLyR7Y29ycmVzcG9uZGVuY2UucHVibGljSWR9YCxcclxuICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSlcclxuICAgICAgICAgIC5jYXRjaCgoZXJyOiBFcnJvcikgPT5cclxuICAgICAgICAgICAgdGhpcy5sb2dnZXIud2FybihgQ2FuY2VsIG5vdGlmaWNhdGlvbiBmYWlsZWQ6ICR7ZXJyLm1lc3NhZ2V9YClcclxuICAgICAgICAgICk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgc3VjY2VzczogdHJ1ZSxcclxuICAgICAgICBtZXNzYWdlOiB3YXJuaW5nTWVzc2FnZSB8fCAnQ29ycmVzcG9uZGVuY2UgY2FuY2VsbGVkIHN1Y2Nlc3NmdWxseScsXHJcbiAgICAgICAgYWN0aXZlQ2lyY3VsYXRpb25zQ291bnQ6IGFjdGl2ZUNpcmN1bGF0aW9ucy5sZW5ndGgsXHJcbiAgICAgIH07XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICBhd2FpdCBxdWVyeVJ1bm5lci5yb2xsYmFja1RyYW5zYWN0aW9uKCk7XHJcbiAgICAgIHRoaXMubG9nZ2VyLmVycm9yKFxyXG4gICAgICAgIGBGYWlsZWQgdG8gY2FuY2VsIGNvcnJlc3BvbmRlbmNlOiAkeyhlcnJvciBhcyBFcnJvcikubWVzc2FnZX1gXHJcbiAgICAgICk7XHJcbiAgICAgIHRocm93IGVycm9yO1xyXG4gICAgfSBmaW5hbGx5IHtcclxuICAgICAgYXdhaXQgcXVlcnlSdW5uZXIucmVsZWFzZSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgYXN5bmMgYnVsa0NhbmNlbChcclxuICAgIHB1YmxpY0lkczogc3RyaW5nW10sXHJcbiAgICByZWFzb246IHN0cmluZyxcclxuICAgIHVzZXI6IFVzZXJcclxuICApOiBQcm9taXNlPHsgc3VjY2VlZGVkOiBzdHJpbmdbXTsgZmFpbGVkOiBzdHJpbmdbXSB9PiB7XHJcbiAgICBjb25zdCBzdWNjZWVkZWQ6IHN0cmluZ1tdID0gW107XHJcbiAgICBjb25zdCBmYWlsZWQ6IHN0cmluZ1tdID0gW107XHJcblxyXG4gICAgZm9yIChjb25zdCBwdWJsaWNJZCBvZiBwdWJsaWNJZHMpIHtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICBhd2FpdCB0aGlzLmNhbmNlbChwdWJsaWNJZCwgcmVhc29uLCB1c2VyKTtcclxuICAgICAgICBzdWNjZWVkZWQucHVzaChwdWJsaWNJZCk7XHJcbiAgICAgIH0gY2F0Y2gge1xyXG4gICAgICAgIGZhaWxlZC5wdXNoKHB1YmxpY0lkKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB7IHN1Y2NlZWRlZCwgZmFpbGVkIH07XHJcbiAgfVxyXG5cclxuICBhc3luYyBleHBvcnRDc3Yoc2VhcmNoRHRvOiBTZWFyY2hDb3JyZXNwb25kZW5jZUR0byk6IFByb21pc2U8c3RyaW5nPiB7XHJcbiAgICBjb25zdCB7IGRhdGEgfSA9IGF3YWl0IHRoaXMuZmluZEFsbChzZWFyY2hEdG8pO1xyXG5cclxuICAgIGNvbnN0IGhlYWRlciA9IFtcclxuICAgICAgJ0RvY3VtZW50IE5vLicsXHJcbiAgICAgICdSZXYnLFxyXG4gICAgICAnU3ViamVjdCcsXHJcbiAgICAgICdUeXBlJyxcclxuICAgICAgJ1N0YXR1cycsXHJcbiAgICAgICdQcm9qZWN0JyxcclxuICAgICAgJ0Zyb20nLFxyXG4gICAgICAnRHVlIERhdGUnLFxyXG4gICAgICAnQ3JlYXRlZCBBdCcsXHJcbiAgICBdO1xyXG4gICAgY29uc3Qgcm93cyA9IGRhdGEubWFwKChyZXYpID0+IHtcclxuICAgICAgY29uc3QgY29yciA9IHJldi5jb3JyZXNwb25kZW5jZSA/PyAocmV2IGFzIHVua25vd24gYXMgQ29ycmVzcG9uZGVuY2UpO1xyXG4gICAgICByZXR1cm4gW1xyXG4gICAgICAgIHRoaXMuZXNjYXBlQ3N2KGNvcnIuY29ycmVzcG9uZGVuY2VOdW1iZXIgPz8gJycpLFxyXG4gICAgICAgIHRoaXMuZXNjYXBlQ3N2KHJldi5yZXZpc2lvbkxhYmVsID8/IFN0cmluZyhyZXYucmV2aXNpb25OdW1iZXIgPz8gMCkpLFxyXG4gICAgICAgIHRoaXMuZXNjYXBlQ3N2KHJldi5zdWJqZWN0ID8/ICcnKSxcclxuICAgICAgICB0aGlzLmVzY2FwZUNzdihjb3JyLnR5cGU/LnR5cGVDb2RlID8/ICcnKSxcclxuICAgICAgICB0aGlzLmVzY2FwZUNzdihyZXYuc3RhdHVzPy5zdGF0dXNDb2RlID8/ICcnKSxcclxuICAgICAgICB0aGlzLmVzY2FwZUNzdihjb3JyLnByb2plY3Q/LnByb2plY3RDb2RlID8/ICcnKSxcclxuICAgICAgICB0aGlzLmVzY2FwZUNzdihjb3JyLm9yaWdpbmF0b3I/Lm9yZ2FuaXphdGlvbkNvZGUgPz8gJycpLFxyXG4gICAgICAgIHJldi5kdWVEYXRlID8gbmV3IERhdGUocmV2LmR1ZURhdGUpLnRvSVNPU3RyaW5nKCkuc3BsaXQoJ1QnKVswXSA6ICcnLFxyXG4gICAgICAgIG5ldyBEYXRlKHJldi5jcmVhdGVkQXQpLnRvSVNPU3RyaW5nKCkuc3BsaXQoJ1QnKVswXSxcclxuICAgICAgXS5qb2luKCcsJyk7XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gW2hlYWRlci5qb2luKCcsJyksIC4uLnJvd3NdLmpvaW4oJ1xcbicpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBlc2NhcGVDc3YodmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICBpZiAodmFsdWUuaW5jbHVkZXMoJywnKSB8fCB2YWx1ZS5pbmNsdWRlcygnXCInKSB8fCB2YWx1ZS5pbmNsdWRlcygnXFxuJykpIHtcclxuICAgICAgcmV0dXJuIGBcIiR7dmFsdWUucmVwbGFjZSgvXCIvZywgJ1wiXCInKX1cImA7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdmFsdWU7XHJcbiAgfVxyXG59XHJcbiJdLCJ2ZXJzaW9uIjozfQ== \ No newline at end of file diff --git a/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/51/correspondenceservice_515ab3b98834c28ddef79ca635837252.map b/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/51/correspondenceservice_515ab3b98834c28ddef79ca635837252.map new file mode 100644 index 0000000..efc9ace --- /dev/null +++ b/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/51/correspondenceservice_515ab3b98834c28ddef79ca635837252.map @@ -0,0 +1 @@ +{"file":"E:\\np-dms\\lcbp3\\backend\\src\\modules\\correspondence\\correspondence.service.ts","mappings":"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","names":[],"sources":["E:\\np-dms\\lcbp3\\backend\\src\\modules\\correspondence\\correspondence.service.ts"],"sourcesContent":["// File: src/modules/correspondence/correspondence.service.ts\r\n\r\nimport {\r\n Injectable,\r\n NotFoundException,\r\n BadRequestException,\r\n InternalServerErrorException,\r\n ForbiddenException,\r\n Logger,\r\n} from '@nestjs/common';\r\nimport { InjectRepository } from '@nestjs/typeorm';\r\nimport { Repository, DataSource } from 'typeorm';\r\n\r\n// Entities\r\nimport { Correspondence } from './entities/correspondence.entity';\r\nimport { CorrespondenceRevision } from './entities/correspondence-revision.entity';\r\nimport { CorrespondenceType } from './entities/correspondence-type.entity';\r\nimport { CorrespondenceStatus } from './entities/correspondence-status.entity';\r\nimport { CorrespondenceReference } from './entities/correspondence-reference.entity';\r\nimport { CorrespondenceRecipient } from './entities/correspondence-recipient.entity';\r\nimport { CorrespondenceTag } from './entities/correspondence-tag.entity';\r\nimport { Tag } from '../master/entities/tag.entity';\r\nimport { User } from '../user/entities/user.entity';\r\nimport { Organization } from '../organization/entities/organization.entity';\r\n\r\n// DTOs\r\nimport { CreateCorrespondenceDto } from './dto/create-correspondence.dto';\r\nimport { UpdateCorrespondenceDto } from './dto/update-correspondence.dto';\r\nimport { AddReferenceDto } from './dto/add-reference.dto';\r\nimport { SearchCorrespondenceDto } from './dto/search-correspondence.dto';\r\n\r\n// Services\r\nimport { DocumentNumberingService } from '../document-numbering/services/document-numbering.service';\r\nimport { JsonSchemaService } from '../json-schema/json-schema.service';\r\nimport { WorkflowEngineService } from '../workflow-engine/workflow-engine.service';\r\nimport { UserService } from '../user/user.service';\r\nimport { SearchService } from '../search/search.service';\r\nimport { FileStorageService } from '../../common/file-storage/file-storage.service';\r\nimport { UuidResolverService } from '../../common/services/uuid-resolver.service';\r\nimport { NotificationService } from '../notification/notification.service';\r\n\r\n/**\r\n * CorrespondenceService - Document management (CRUD)\r\n */\r\ninterface ResolvedRecipient {\r\n organizationId: number;\r\n type: 'TO' | 'CC';\r\n}\r\n@Injectable()\r\nexport class CorrespondenceService {\r\n private readonly logger = new Logger(CorrespondenceService.name);\r\n\r\n private async hasSystemManageAllPermission(userId: number): Promise {\r\n const permissions = await this.userService.getUserPermissions(userId);\r\n return permissions.includes('system.manage_all');\r\n }\r\n\r\n /**\r\n * Business Rule: Revision Label Strategy\r\n * - RFA, RFI: Use alphabet starting with 'A' (A, B, C...)\r\n * - Other types (LETTER, MEMO, etc.): Use numeric (null for first, then 1, 2, 3...)\r\n */\r\n private getInitialRevisionLabel(typeCode: string): string | undefined {\r\n const alphabetTypes = ['RFA', 'RFI'];\r\n if (alphabetTypes.includes(typeCode.toUpperCase())) {\r\n return 'A'; // Alphabet for RFA, RFI\r\n }\r\n return undefined; // Numeric (no label for revision 0)\r\n }\r\n\r\n constructor(\r\n @InjectRepository(Correspondence)\r\n private correspondenceRepo: Repository,\r\n @InjectRepository(CorrespondenceRevision)\r\n private revisionRepo: Repository,\r\n @InjectRepository(CorrespondenceType)\r\n private typeRepo: Repository,\r\n @InjectRepository(CorrespondenceStatus)\r\n private statusRepo: Repository,\r\n @InjectRepository(CorrespondenceReference)\r\n private referenceRepo: Repository,\r\n @InjectRepository(CorrespondenceTag)\r\n private tagRepo: Repository,\r\n private numberingService: DocumentNumberingService,\r\n private jsonSchemaService: JsonSchemaService,\r\n private workflowEngine: WorkflowEngineService,\r\n private userService: UserService,\r\n private dataSource: DataSource,\r\n private searchService: SearchService,\r\n private fileStorageService: FileStorageService,\r\n private uuidResolver: UuidResolverService,\r\n private notificationService: NotificationService\r\n ) {}\r\n\r\n /**\r\n * Business Rule Validation: EC-CORR-003 - Correspondence to Self\r\n * Prevent external correspondence to same organization\r\n */\r\n private async validateCorrespondenceRecipients(\r\n createDto: CreateCorrespondenceDto,\r\n user: User\r\n ): Promise {\r\n // Get user's organization\r\n let userOrgId = user.primaryOrganizationId;\r\n if (!userOrgId) {\r\n const fullUser = await this.userService.findOne(user.user_id);\r\n if (fullUser) {\r\n userOrgId = fullUser.primaryOrganizationId;\r\n }\r\n }\r\n\r\n if (!userOrgId) {\r\n if (createDto.originatorId) {\r\n const canManageAll = await this.hasSystemManageAllPermission(\r\n user.user_id\r\n );\r\n if (canManageAll) {\r\n userOrgId = await this.uuidResolver.resolveOrganizationId(\r\n createDto.originatorId\r\n );\r\n }\r\n }\r\n\r\n if (!userOrgId) {\r\n throw new BadRequestException(\r\n 'User must belong to an organization to create documents'\r\n );\r\n }\r\n }\r\n\r\n // For impersonation, use the specified originator\r\n const originatorOrgId = createDto.originatorId\r\n ? await this.uuidResolver.resolveOrganizationId(createDto.originatorId)\r\n : userOrgId;\r\n\r\n // Check if it's internal communication\r\n if (createDto.isInternal) {\r\n // Internal communications should use Circulation instead\r\n throw new BadRequestException(\r\n 'Internal communications should use Circulation Sheet instead of Correspondence'\r\n );\r\n }\r\n\r\n // Validate recipients\r\n if (!createDto.recipients || createDto.recipients.length === 0) {\r\n throw new BadRequestException(\r\n 'At least one recipient (TO or CC) is required'\r\n );\r\n }\r\n\r\n const toRecipients = createDto.recipients.filter((r) => r.type === 'TO');\r\n const ccRecipients = createDto.recipients.filter((r) => r.type === 'CC');\r\n\r\n if (toRecipients.length === 0 && ccRecipients.length === 0) {\r\n throw new BadRequestException(\r\n 'At least one TO or CC recipient is required'\r\n );\r\n }\r\n\r\n // Check for same organization correspondence\r\n for (const recipient of createDto.recipients) {\r\n const recipientOrgId = await this.uuidResolver.resolveOrganizationId(\r\n recipient.organizationId\r\n );\r\n\r\n if (recipientOrgId === originatorOrgId) {\r\n throw new BadRequestException(\r\n 'Cannot send correspondence to your own organization. Use Circulation Sheet for internal communication.'\r\n );\r\n }\r\n }\r\n }\r\n\r\n async create(createDto: CreateCorrespondenceDto, user: User) {\r\n // Business Rule Validation: EC-CORR-003 - Correspondence to Self\r\n await this.validateCorrespondenceRecipients(createDto, user);\r\n // ADR-019: Resolve UUID references to internal INT IDs\r\n const resolvedProjectId = await this.uuidResolver.resolveProjectId(\r\n createDto.projectId\r\n );\r\n const resolvedOriginatorId = createDto.originatorId\r\n ? await this.uuidResolver.resolveOrganizationId(createDto.originatorId)\r\n : undefined;\r\n const resolvedRecipients = createDto.recipients\r\n ? await Promise.all(\r\n createDto.recipients.map(\r\n async (r): Promise => ({\r\n organizationId: await this.uuidResolver.resolveOrganizationId(\r\n r.organizationId\r\n ),\r\n type: r.type,\r\n })\r\n )\r\n )\r\n : undefined;\r\n const type = await this.typeRepo.findOne({\r\n where: { id: createDto.typeId },\r\n });\r\n if (!type) throw new NotFoundException('Document Type not found');\r\n\r\n const statusDraft = await this.statusRepo.findOne({\r\n where: { statusCode: 'DRAFT' },\r\n });\r\n if (!statusDraft) {\r\n throw new InternalServerErrorException(\r\n 'Status DRAFT not found in Master Data'\r\n );\r\n }\r\n\r\n let userOrgId = user.primaryOrganizationId;\r\n\r\n if (!userOrgId) {\r\n const fullUser = await this.userService.findOne(user.user_id);\r\n if (fullUser) {\r\n userOrgId = fullUser.primaryOrganizationId;\r\n }\r\n }\r\n\r\n // Impersonation Logic\r\n if (resolvedOriginatorId && resolvedOriginatorId !== userOrgId) {\r\n const canManageAll = await this.hasSystemManageAllPermission(\r\n user.user_id\r\n );\r\n if (!canManageAll) {\r\n throw new ForbiddenException(\r\n 'You do not have permission to create documents on behalf of other organizations.'\r\n );\r\n }\r\n userOrgId = resolvedOriginatorId;\r\n }\r\n\r\n if (!userOrgId) {\r\n throw new BadRequestException(\r\n 'User must belong to an organization to create documents'\r\n );\r\n }\r\n\r\n if (createDto.details) {\r\n try {\r\n await this.jsonSchemaService.validate(type.typeCode, createDto.details);\r\n } catch (error: unknown) {\r\n this.logger.warn(\r\n `Schema validation warning for ${type.typeCode}: ${(error as Error).message}`\r\n );\r\n }\r\n }\r\n\r\n const queryRunner = this.dataSource.createQueryRunner();\r\n await queryRunner.connect();\r\n await queryRunner.startTransaction();\r\n\r\n try {\r\n // [Fix #6] Fetch real ORG Code from Organization entity\r\n const originatorOrg = await this.dataSource.manager.findOne(\r\n Organization,\r\n {\r\n where: { id: userOrgId },\r\n }\r\n );\r\n const orgCode = originatorOrg?.organizationCode ?? 'UNK';\r\n\r\n // [v1.5.1] Extract recipient organization from recipients array (Primary TO)\r\n const toRecipient = resolvedRecipients?.find((r) => r.type === 'TO');\r\n const recipientOrganizationId = toRecipient?.organizationId;\r\n\r\n let recipientCode = '';\r\n if (recipientOrganizationId) {\r\n const recOrg = await this.dataSource.manager.findOne(Organization, {\r\n where: { id: recipientOrganizationId },\r\n });\r\n if (recOrg) recipientCode = recOrg.organizationCode;\r\n }\r\n\r\n const docNumber = await this.numberingService.generateNextNumber({\r\n projectId: resolvedProjectId,\r\n originatorOrganizationId: userOrgId,\r\n typeId: createDto.typeId,\r\n disciplineId: createDto.disciplineId,\r\n subTypeId: createDto.subTypeId,\r\n recipientOrganizationId, // [v1.5.1] Pass recipient for document number format\r\n year: new Date().getFullYear(),\r\n customTokens: {\r\n TYPE_CODE: type.typeCode,\r\n ORG_CODE: orgCode,\r\n RECIPIENT_CODE: recipientCode,\r\n REC_CODE: recipientCode,\r\n },\r\n });\r\n\r\n const correspondence = queryRunner.manager.create(Correspondence, {\r\n correspondenceNumber: docNumber.number,\r\n correspondenceTypeId: createDto.typeId,\r\n disciplineId: createDto.disciplineId,\r\n projectId: resolvedProjectId,\r\n originatorId: userOrgId,\r\n isInternal: createDto.isInternal || false,\r\n createdBy: user.user_id,\r\n });\r\n const savedCorr = await queryRunner.manager.save(correspondence);\r\n\r\n const revision = queryRunner.manager.create(CorrespondenceRevision, {\r\n correspondenceId: savedCorr.id,\r\n revisionNumber: 0,\r\n revisionLabel: this.getInitialRevisionLabel(type.typeCode),\r\n isCurrent: true,\r\n statusId: statusDraft.id,\r\n subject: createDto.subject,\r\n body: createDto.body,\r\n remarks: createDto.remarks,\r\n dueDate: createDto.dueDate ? new Date(createDto.dueDate) : undefined,\r\n documentDate: createDto.documentDate\r\n ? new Date(createDto.documentDate)\r\n : undefined,\r\n issuedDate: createDto.issuedDate\r\n ? new Date(createDto.issuedDate)\r\n : undefined,\r\n receivedDate: createDto.receivedDate\r\n ? new Date(createDto.receivedDate)\r\n : undefined,\r\n description: createDto.description,\r\n details: createDto.details,\r\n createdBy: user.user_id,\r\n schemaVersion: 1,\r\n });\r\n await queryRunner.manager.save(revision);\r\n\r\n // Save Recipients (using resolved INT IDs)\r\n if (resolvedRecipients && resolvedRecipients.length > 0) {\r\n const recipients = resolvedRecipients.map((r) =>\r\n queryRunner.manager.create(CorrespondenceRecipient, {\r\n correspondenceId: savedCorr.id,\r\n recipientOrganizationId: r.organizationId,\r\n recipientType: r.type,\r\n })\r\n );\r\n await queryRunner.manager.save(recipients);\r\n }\r\n\r\n // Commit attachments from Temp → Permanent (Two-Phase Storage)\r\n if (createDto.attachmentTempIds?.length) {\r\n const issueDate = createDto.issuedDate\r\n ? new Date(createDto.issuedDate)\r\n : createDto.documentDate\r\n ? new Date(createDto.documentDate)\r\n : undefined;\r\n\r\n await this.fileStorageService.commit(createDto.attachmentTempIds, {\r\n issueDate,\r\n documentType: 'Correspondence',\r\n });\r\n }\r\n\r\n await queryRunner.commitTransaction();\r\n\r\n // Start Workflow Instance (non-blocking)\r\n try {\r\n const workflowCode = `CORRESPONDENCE_${type.typeCode}`;\r\n await this.workflowEngine.createInstance(\r\n workflowCode,\r\n 'correspondence',\r\n savedCorr.id.toString(),\r\n {\r\n projectId: resolvedProjectId,\r\n originatorId: userOrgId,\r\n disciplineId: createDto.disciplineId,\r\n initiatorId: user.user_id,\r\n } as Record\r\n );\r\n } catch (error: unknown) {\r\n this.logger.warn(\r\n `Workflow not started for ${docNumber.number} (Code: CORRESPONDENCE_${type.typeCode}): ${(error as Error).message}`\r\n );\r\n }\r\n\r\n // Fire-and-forget search indexing (non-blocking, void intentional)\r\n void this.searchService.indexDocument({\r\n id: savedCorr.id,\r\n publicId: savedCorr.publicId,\r\n type: 'correspondence',\r\n docNumber: docNumber.number,\r\n title: createDto.subject,\r\n description: createDto.description,\r\n status: 'DRAFT',\r\n projectId: resolvedProjectId,\r\n createdAt: new Date(),\r\n });\r\n\r\n return {\r\n ...savedCorr,\r\n currentRevision: revision,\r\n };\r\n } catch (err) {\r\n await queryRunner.rollbackTransaction();\r\n this.logger.error(\r\n `Failed to create correspondence: ${(err as Error).message}`\r\n );\r\n throw err;\r\n } finally {\r\n await queryRunner.release();\r\n }\r\n }\r\n\r\n async findAll(searchDto: SearchCorrespondenceDto = {}) {\r\n const {\r\n search,\r\n typeId,\r\n projectId,\r\n statusId,\r\n status,\r\n page = 1,\r\n limit = 10,\r\n } = searchDto;\r\n const skip = (page - 1) * limit;\r\n\r\n // Change: Query from Revision Repo\r\n const query = this.revisionRepo\r\n .createQueryBuilder('rev')\r\n .leftJoinAndSelect('rev.correspondence', 'corr')\r\n .leftJoinAndSelect('corr.type', 'type')\r\n .leftJoinAndSelect('corr.project', 'project')\r\n .leftJoinAndSelect('corr.originator', 'org')\r\n .leftJoinAndSelect('rev.status', 'status');\r\n\r\n // Filter by Revision Status\r\n const revStatus = searchDto.revisionStatus || 'CURRENT';\r\n\r\n if (revStatus === 'CURRENT') {\r\n query.where('rev.isCurrent = :isCurrent', { isCurrent: true });\r\n } else if (revStatus === 'OLD') {\r\n query.where('rev.isCurrent = :isCurrent', { isCurrent: false });\r\n }\r\n // If 'ALL', no filter needed on isCurrent\r\n\r\n if (projectId) {\r\n query.andWhere('corr.projectId = :projectId', { projectId });\r\n }\r\n\r\n if (typeId) {\r\n query.andWhere('corr.correspondenceTypeId = :typeId', { typeId });\r\n }\r\n\r\n if (statusId) {\r\n query.andWhere('rev.statusId = :statusId', { statusId });\r\n }\r\n\r\n if (status) {\r\n query.andWhere('status.statusCode = :status', { status });\r\n }\r\n\r\n if (search) {\r\n query.andWhere(\r\n '(corr.correspondenceNumber LIKE :search OR rev.subject LIKE :search)',\r\n { search: `%${search}%` }\r\n );\r\n }\r\n\r\n // Default Sort: Latest Created\r\n query.orderBy('rev.createdAt', 'DESC').skip(skip).take(limit);\r\n\r\n const [items, total] = await query.getManyAndCount();\r\n\r\n return {\r\n data: items,\r\n meta: {\r\n total,\r\n page,\r\n limit,\r\n totalPages: Math.ceil(total / limit),\r\n },\r\n };\r\n }\r\n\r\n async findOne(id: number) {\r\n const correspondence = await this.correspondenceRepo.findOne({\r\n where: { id },\r\n relations: [\r\n 'revisions',\r\n 'revisions.status',\r\n 'type',\r\n 'project',\r\n 'originator',\r\n 'recipients',\r\n 'recipients.recipientOrganization', // [v1.5.1] Fixed relation name\r\n ],\r\n });\r\n\r\n if (!correspondence) {\r\n throw new NotFoundException(`Correspondence with ID ${id} not found`);\r\n }\r\n return correspondence;\r\n }\r\n\r\n async findOneByUuid(publicId: string) {\r\n const correspondence = await this.correspondenceRepo.findOne({\r\n where: { publicId },\r\n relations: [\r\n 'revisions',\r\n 'revisions.status',\r\n 'type',\r\n 'project',\r\n 'originator',\r\n 'recipients',\r\n 'recipients.recipientOrganization',\r\n ],\r\n });\r\n\r\n if (!correspondence) {\r\n throw new NotFoundException(\r\n `Correspondence with UUID ${publicId} not found`\r\n );\r\n }\r\n return correspondence;\r\n }\r\n\r\n async addReference(id: number, dto: AddReferenceDto) {\r\n const source = await this.correspondenceRepo.findOne({ where: { id } });\r\n // ADR-019: Resolve target publicId → internal INT id\r\n const target = await this.correspondenceRepo.findOne({\r\n where: { publicId: dto.targetUuid },\r\n });\r\n\r\n if (!source || !target) {\r\n throw new NotFoundException('Source or Target correspondence not found');\r\n }\r\n\r\n if (source.id === target.id) {\r\n throw new BadRequestException('Cannot reference self');\r\n }\r\n\r\n const exists = await this.referenceRepo.findOne({\r\n where: {\r\n sourceId: id,\r\n targetId: target.id,\r\n },\r\n });\r\n\r\n if (exists) {\r\n return exists;\r\n }\r\n\r\n const ref = this.referenceRepo.create({\r\n sourceId: id,\r\n targetId: target.id,\r\n });\r\n\r\n return this.referenceRepo.save(ref);\r\n }\r\n\r\n async removeReference(id: number, targetId: number) {\r\n const result = await this.referenceRepo.delete({\r\n sourceId: id,\r\n targetId: targetId,\r\n });\r\n\r\n if (result.affected === 0) {\r\n throw new NotFoundException('Reference not found');\r\n }\r\n }\r\n\r\n async getTags(id: number) {\r\n const rows = await this.tagRepo.find({\r\n where: { correspondenceId: id },\r\n relations: ['tag'],\r\n });\r\n return rows.map((r) => r.tag).filter(Boolean);\r\n }\r\n\r\n async addTag(id: number, tagId: number) {\r\n const correspondence = await this.correspondenceRepo.findOne({\r\n where: { id },\r\n });\r\n if (!correspondence) {\r\n throw new NotFoundException(`Correspondence ${id} not found`);\r\n }\r\n\r\n const tag = await this.dataSource.manager.findOne(Tag, {\r\n where: { id: tagId },\r\n });\r\n if (!tag) {\r\n throw new NotFoundException(`Tag ${tagId} not found`);\r\n }\r\n\r\n const exists = await this.tagRepo.findOne({\r\n where: { correspondenceId: id, tagId },\r\n });\r\n if (exists) return exists;\r\n\r\n const row = this.tagRepo.create({ correspondenceId: id, tagId });\r\n return this.tagRepo.save(row);\r\n }\r\n\r\n async removeTag(id: number, tagId: number) {\r\n const result = await this.tagRepo.delete({ correspondenceId: id, tagId });\r\n if (result.affected === 0) {\r\n throw new NotFoundException('Tag assignment not found');\r\n }\r\n }\r\n\r\n async getReferences(id: number) {\r\n const outgoing = await this.referenceRepo.find({\r\n where: { sourceId: id },\r\n relations: ['target', 'target.type'],\r\n });\r\n\r\n const incoming = await this.referenceRepo.find({\r\n where: { targetId: id },\r\n relations: ['source', 'source.type'],\r\n });\r\n\r\n return { outgoing, incoming };\r\n }\r\n\r\n async update(id: number, updateDto: UpdateCorrespondenceDto, user: User) {\r\n // 1. Find Current Revision\r\n const revision = await this.revisionRepo.findOne({\r\n where: {\r\n correspondenceId: id,\r\n isCurrent: true,\r\n },\r\n relations: ['correspondence'],\r\n });\r\n\r\n if (!revision) {\r\n throw new NotFoundException(\r\n `Current revision for correspondence ${id} not found`\r\n );\r\n }\r\n\r\n // 2. Check Permission\r\n if (revision.statusId) {\r\n const status = await this.statusRepo.findOne({\r\n where: { id: revision.statusId },\r\n });\r\n if (status && status.statusCode !== 'DRAFT') {\r\n throw new BadRequestException('Only DRAFT documents can be updated');\r\n }\r\n }\r\n\r\n // ADR-019: Resolve UUID references in update DTO\r\n const updResolvedProjectId = updateDto.projectId\r\n ? await this.uuidResolver.resolveProjectId(updateDto.projectId)\r\n : undefined;\r\n const updResolvedOriginatorId = updateDto.originatorId\r\n ? await this.uuidResolver.resolveOrganizationId(updateDto.originatorId)\r\n : undefined;\r\n const updResolvedRecipients = updateDto.recipients\r\n ? await Promise.all(\r\n updateDto.recipients.map(\r\n async (r): Promise => ({\r\n organizationId: await this.uuidResolver.resolveOrganizationId(\r\n r.organizationId\r\n ),\r\n type: r.type,\r\n })\r\n )\r\n )\r\n : undefined;\r\n\r\n // 3. Update Correspondence Entity if needed\r\n const correspondenceUpdate: Record = {};\r\n if (updateDto.disciplineId)\r\n correspondenceUpdate.disciplineId = updateDto.disciplineId;\r\n if (updResolvedProjectId)\r\n correspondenceUpdate.projectId = updResolvedProjectId;\r\n if (updResolvedOriginatorId)\r\n correspondenceUpdate.originatorId = updResolvedOriginatorId;\r\n\r\n if (Object.keys(correspondenceUpdate).length > 0) {\r\n await this.correspondenceRepo.update(id, correspondenceUpdate);\r\n }\r\n\r\n // 4. Update Revision Entity\r\n const revisionUpdate: Record = {};\r\n if (updateDto.subject) revisionUpdate.subject = updateDto.subject;\r\n if (updateDto.body) revisionUpdate.body = updateDto.body;\r\n if (updateDto.remarks) revisionUpdate.remarks = updateDto.remarks;\r\n // Format Date correctly if string\r\n if (updateDto.dueDate) revisionUpdate.dueDate = new Date(updateDto.dueDate);\r\n if (updateDto.documentDate)\r\n revisionUpdate.documentDate = new Date(updateDto.documentDate);\r\n if (updateDto.issuedDate)\r\n revisionUpdate.issuedDate = new Date(updateDto.issuedDate);\r\n if (updateDto.receivedDate)\r\n revisionUpdate.receivedDate = new Date(updateDto.receivedDate);\r\n if (updateDto.description)\r\n revisionUpdate.description = updateDto.description;\r\n if (updateDto.details) revisionUpdate.details = updateDto.details;\r\n\r\n if (Object.keys(revisionUpdate).length > 0) {\r\n await this.revisionRepo.update(revision.id, revisionUpdate);\r\n }\r\n\r\n // 4.5 Commit new attachments from Temp → Permanent (Two-Phase Storage)\r\n if (updateDto.attachmentTempIds?.length) {\r\n const issueDate = updateDto.issuedDate\r\n ? new Date(updateDto.issuedDate)\r\n : updateDto.documentDate\r\n ? new Date(updateDto.documentDate)\r\n : revision.issuedDate || revision.documentDate || undefined;\r\n\r\n await this.fileStorageService.commit(updateDto.attachmentTempIds, {\r\n issueDate: issueDate ? new Date(issueDate) : undefined,\r\n documentType: 'Correspondence',\r\n });\r\n }\r\n\r\n // 5. Update Recipients if provided\r\n if (updResolvedRecipients) {\r\n const recipientRepo = this.dataSource.getRepository(\r\n CorrespondenceRecipient\r\n );\r\n await recipientRepo.delete({ correspondenceId: id });\r\n\r\n const newRecipients = updResolvedRecipients.map((r) =>\r\n recipientRepo.create({\r\n correspondenceId: id,\r\n recipientOrganizationId: r.organizationId,\r\n recipientType: r.type,\r\n })\r\n );\r\n await recipientRepo.save(newRecipients);\r\n }\r\n\r\n // 6. Regenerate Document Number if structural fields changed (Recipient, Discipline, Type, Project)\r\n // AND it is a DRAFT.\r\n\r\n // Fetch fresh data for context and comparison\r\n const currentCorr = await this.correspondenceRepo.findOne({\r\n where: { id },\r\n relations: ['type', 'recipients', 'recipients.recipientOrganization'],\r\n });\r\n\r\n if (currentCorr) {\r\n const currentToRecipient = currentCorr.recipients?.find(\r\n (r) => r.recipientType === 'TO'\r\n );\r\n const currentRecipientId = currentToRecipient?.recipientOrganizationId;\r\n\r\n // Check for ACTUAL value changes\r\n const isProjectChanged =\r\n updResolvedProjectId !== undefined &&\r\n updResolvedProjectId !== currentCorr.projectId;\r\n const isOriginatorChanged =\r\n updResolvedOriginatorId !== undefined &&\r\n updResolvedOriginatorId !== currentCorr.originatorId;\r\n const isDisciplineChanged =\r\n updateDto.disciplineId !== undefined &&\r\n updateDto.disciplineId !== currentCorr.disciplineId;\r\n const isTypeChanged =\r\n updateDto.typeId !== undefined &&\r\n updateDto.typeId !== currentCorr.correspondenceTypeId;\r\n\r\n let isRecipientChanged = false;\r\n let newRecipientId: number | undefined;\r\n\r\n if (updResolvedRecipients) {\r\n const newToRecipient = updResolvedRecipients.find(\r\n (r) => r.type === 'TO'\r\n );\r\n newRecipientId = newToRecipient?.organizationId;\r\n\r\n if (newRecipientId !== currentRecipientId) {\r\n isRecipientChanged = true;\r\n }\r\n }\r\n\r\n if (\r\n isProjectChanged ||\r\n isDisciplineChanged ||\r\n isTypeChanged ||\r\n isRecipientChanged ||\r\n isOriginatorChanged\r\n ) {\r\n const targetRecipientId = isRecipientChanged\r\n ? newRecipientId\r\n : currentRecipientId;\r\n\r\n // Resolve Recipient Code for the NEW context\r\n let recipientCode = '';\r\n if (targetRecipientId) {\r\n const recOrg = await this.dataSource.manager.findOne(Organization, {\r\n where: { id: targetRecipientId },\r\n });\r\n if (recOrg) recipientCode = recOrg.organizationCode;\r\n }\r\n\r\n // [Fix #6] Fetch real ORG Code from originator organization\r\n const originatorOrgForUpdate = await this.dataSource.manager.findOne(\r\n Organization,\r\n {\r\n where: {\r\n id: updResolvedOriginatorId ?? currentCorr.originatorId ?? 0,\r\n },\r\n }\r\n );\r\n const orgCode = originatorOrgForUpdate?.organizationCode ?? 'UNK';\r\n\r\n // Prepare Contexts\r\n const oldCtx = {\r\n projectId: currentCorr.projectId,\r\n originatorOrganizationId: currentCorr.originatorId ?? 0,\r\n typeId: currentCorr.correspondenceTypeId,\r\n disciplineId: currentCorr.disciplineId,\r\n recipientOrganizationId: currentRecipientId,\r\n year: new Date().getFullYear(),\r\n };\r\n\r\n const newCtx = {\r\n projectId: updResolvedProjectId ?? currentCorr.projectId,\r\n originatorOrganizationId:\r\n updResolvedOriginatorId ?? currentCorr.originatorId ?? 0,\r\n typeId: updateDto.typeId ?? currentCorr.correspondenceTypeId,\r\n disciplineId: updateDto.disciplineId ?? currentCorr.disciplineId,\r\n recipientOrganizationId: targetRecipientId,\r\n year: new Date().getFullYear(),\r\n userId: user.user_id, // Pass User ID for Audit\r\n customTokens: {\r\n TYPE_CODE: currentCorr.type?.typeCode || '',\r\n ORG_CODE: orgCode,\r\n RECIPIENT_CODE: recipientCode,\r\n REC_CODE: recipientCode,\r\n },\r\n };\r\n\r\n // If Type Changed, need NEW Type Code\r\n if (isTypeChanged) {\r\n const newType = await this.typeRepo.findOne({\r\n where: { id: newCtx.typeId },\r\n });\r\n if (newType) newCtx.customTokens.TYPE_CODE = newType.typeCode;\r\n }\r\n\r\n const newDocNumber = await this.numberingService.updateNumberForDraft(\r\n currentCorr.correspondenceNumber,\r\n oldCtx,\r\n newCtx\r\n );\r\n\r\n await this.correspondenceRepo.update(id, {\r\n correspondenceNumber: newDocNumber,\r\n });\r\n }\r\n }\r\n\r\n const updated = await this.findOne(id);\r\n\r\n // Re-index updated document in Elasticsearch (fire-and-forget)\r\n void this.searchService.indexDocument({\r\n id: updated.id,\r\n publicId: updated.publicId,\r\n type: 'correspondence',\r\n docNumber: updated.correspondenceNumber,\r\n title: updateDto.subject ?? updated.revisions?.[0]?.subject,\r\n description: updateDto.description ?? updated.revisions?.[0]?.description,\r\n status: 'DRAFT',\r\n projectId: updated.projectId,\r\n createdAt: updated.createdAt,\r\n });\r\n\r\n return updated;\r\n }\r\n\r\n async previewDocumentNumber(createDto: CreateCorrespondenceDto, user: User) {\r\n // ADR-019: Resolve UUID references\r\n const previewProjectId = await this.uuidResolver.resolveProjectId(\r\n createDto.projectId\r\n );\r\n const previewOriginatorId = createDto.originatorId\r\n ? await this.uuidResolver.resolveOrganizationId(createDto.originatorId)\r\n : undefined;\r\n const previewRecipients = createDto.recipients\r\n ? await Promise.all(\r\n createDto.recipients.map(\r\n async (r): Promise => ({\r\n organizationId: await this.uuidResolver.resolveOrganizationId(\r\n r.organizationId\r\n ),\r\n type: r.type,\r\n })\r\n )\r\n )\r\n : undefined;\r\n\r\n const type = await this.typeRepo.findOne({\r\n where: { id: createDto.typeId },\r\n });\r\n if (!type) throw new NotFoundException('Document Type not found');\r\n\r\n let userOrgId = user.primaryOrganizationId;\r\n if (!userOrgId) {\r\n const fullUser = await this.userService.findOne(user.user_id);\r\n if (fullUser) userOrgId = fullUser.primaryOrganizationId;\r\n }\r\n\r\n if (previewOriginatorId && previewOriginatorId !== userOrgId) {\r\n // Allow impersonation for preview\r\n userOrgId = previewOriginatorId;\r\n }\r\n\r\n // Extract recipient from recipients array\r\n const toRecipient = previewRecipients?.find((r) => r.type === 'TO');\r\n const recipientOrganizationId = toRecipient?.organizationId;\r\n\r\n let recipientCode = '';\r\n if (recipientOrganizationId) {\r\n const recOrg = await this.dataSource.manager.findOne(Organization, {\r\n where: { id: recipientOrganizationId },\r\n });\r\n if (recOrg) recipientCode = recOrg.organizationCode;\r\n }\r\n\r\n return this.numberingService.previewNumber({\r\n projectId: previewProjectId,\r\n originatorOrganizationId: userOrgId!,\r\n typeId: createDto.typeId,\r\n disciplineId: createDto.disciplineId,\r\n subTypeId: createDto.subTypeId,\r\n recipientOrganizationId,\r\n year: new Date().getFullYear(),\r\n customTokens: {\r\n TYPE_CODE: type.typeCode,\r\n RECIPIENT_CODE: recipientCode,\r\n REC_CODE: recipientCode,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Business Rule Implementation: EC-CORR-001 - Cancel Correspondence with Downstream Circulation\r\n * Cancel correspondence and handle related circulations\r\n */\r\n async cancel(publicId: string, reason: string, user: User) {\r\n const correspondence = await this.findOneByUuid(publicId);\r\n\r\n // Check if user has permission to cancel (Org Admin or Superadmin only)\r\n const permissions = await this.userService.getUserPermissions(user.user_id);\r\n const canCancel =\r\n permissions.includes('correspondence.cancel') ||\r\n permissions.includes('system.manage_all');\r\n\r\n if (!canCancel) {\r\n throw new ForbiddenException(\r\n 'Only administrators can cancel correspondences'\r\n );\r\n }\r\n\r\n // Check if there are any active circulations\r\n const circulationRepo = this.dataSource.getRepository('Circulation');\r\n const activeCirculations = await circulationRepo.find({\r\n where: {\r\n correspondenceId: correspondence.id,\r\n status: 'OPEN',\r\n },\r\n });\r\n\r\n const warningMessage =\r\n activeCirculations.length > 0\r\n ? `There are ${activeCirculations.length} active circulation(s) for this correspondence. Canceling will force close all related circulations.`\r\n : '';\r\n\r\n // Get the current revision to update status\r\n const currentRevision = await this.revisionRepo.findOne({\r\n where: {\r\n correspondenceId: correspondence.id,\r\n isCurrent: true,\r\n },\r\n });\r\n\r\n if (!currentRevision) {\r\n throw new NotFoundException('Current revision not found');\r\n }\r\n\r\n // Get cancelled status\r\n const cancelledStatus = await this.statusRepo.findOne({\r\n where: { statusCode: 'CANCELLED' },\r\n });\r\n\r\n if (!cancelledStatus) {\r\n throw new InternalServerErrorException('CANCELLED status not found');\r\n }\r\n\r\n const queryRunner = this.dataSource.createQueryRunner();\r\n await queryRunner.connect();\r\n await queryRunner.startTransaction();\r\n\r\n try {\r\n // Update correspondence revision status to CANCELLED\r\n await queryRunner.manager.update(\r\n CorrespondenceRevision,\r\n currentRevision.id,\r\n {\r\n statusId: cancelledStatus.id,\r\n remarks: `Cancelled: ${reason}`,\r\n }\r\n );\r\n\r\n // Force close all active circulations\r\n if (activeCirculations.length > 0) {\r\n await queryRunner.manager.update(\r\n 'Circulation',\r\n {\r\n correspondenceId: correspondence.id,\r\n status: 'OPEN',\r\n },\r\n {\r\n status: 'FORCE_CLOSED',\r\n closedAt: new Date(),\r\n closedBy: user.user_id,\r\n closeReason: `Correspondence cancelled: ${reason}`,\r\n }\r\n );\r\n }\r\n\r\n await queryRunner.commitTransaction();\r\n\r\n // Re-index cancelled status in Elasticsearch (fire-and-forget)\r\n void this.searchService.indexDocument({\r\n id: correspondence.id,\r\n publicId: correspondence.publicId,\r\n type: 'correspondence',\r\n docNumber: correspondence.correspondenceNumber,\r\n title: currentRevision.subject,\r\n status: 'CANCELLED',\r\n projectId: correspondence.projectId,\r\n createdAt: correspondence.createdAt,\r\n });\r\n\r\n // Notify originator's doc-control user about cancellation (fire-and-forget)\r\n if (correspondence.originatorId) {\r\n void this.userService\r\n .findDocControlIdByOrg(correspondence.originatorId)\r\n .then((targetUserId) => {\r\n if (targetUserId) {\r\n void this.notificationService.send({\r\n userId: targetUserId,\r\n title: 'Correspondence Cancelled',\r\n message: `${correspondence.correspondenceNumber} — ${currentRevision.subject} has been cancelled. Reason: ${reason}`,\r\n type: 'EMAIL',\r\n entityType: 'correspondence',\r\n entityId: correspondence.id,\r\n link: `/correspondences/${correspondence.publicId}`,\r\n });\r\n }\r\n })\r\n .catch((err: Error) =>\r\n this.logger.warn(`Cancel notification failed: ${err.message}`)\r\n );\r\n }\r\n\r\n return {\r\n success: true,\r\n message: warningMessage || 'Correspondence cancelled successfully',\r\n activeCirculationsCount: activeCirculations.length,\r\n };\r\n } catch (error) {\r\n await queryRunner.rollbackTransaction();\r\n this.logger.error(\r\n `Failed to cancel correspondence: ${(error as Error).message}`\r\n );\r\n throw error;\r\n } finally {\r\n await queryRunner.release();\r\n }\r\n }\r\n\r\n async bulkCancel(\r\n publicIds: string[],\r\n reason: string,\r\n user: User\r\n ): Promise<{ succeeded: string[]; failed: string[] }> {\r\n const succeeded: string[] = [];\r\n const failed: string[] = [];\r\n\r\n for (const publicId of publicIds) {\r\n try {\r\n await this.cancel(publicId, reason, user);\r\n succeeded.push(publicId);\r\n } catch {\r\n failed.push(publicId);\r\n }\r\n }\r\n\r\n return { succeeded, failed };\r\n }\r\n\r\n async exportCsv(searchDto: SearchCorrespondenceDto): Promise {\r\n const { data } = await this.findAll(searchDto);\r\n\r\n const header = [\r\n 'Document No.',\r\n 'Rev',\r\n 'Subject',\r\n 'Type',\r\n 'Status',\r\n 'Project',\r\n 'From',\r\n 'Due Date',\r\n 'Created At',\r\n ];\r\n const rows = data.map((rev) => {\r\n const corr = rev.correspondence ?? (rev as unknown as Correspondence);\r\n return [\r\n this.escapeCsv(corr.correspondenceNumber ?? ''),\r\n this.escapeCsv(rev.revisionLabel ?? String(rev.revisionNumber ?? 0)),\r\n this.escapeCsv(rev.subject ?? ''),\r\n this.escapeCsv(corr.type?.typeCode ?? ''),\r\n this.escapeCsv(rev.status?.statusCode ?? ''),\r\n this.escapeCsv(corr.project?.projectCode ?? ''),\r\n this.escapeCsv(corr.originator?.organizationCode ?? ''),\r\n rev.dueDate ? new Date(rev.dueDate).toISOString().split('T')[0] : '',\r\n new Date(rev.createdAt).toISOString().split('T')[0],\r\n ].join(',');\r\n });\r\n\r\n return [header.join(','), ...rows].join('\\n');\r\n }\r\n\r\n private escapeCsv(value: string): string {\r\n if (value.includes(',') || value.includes('\"') || value.includes('\\n')) {\r\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\r\n }\r\n return value;\r\n }\r\n}\r\n"],"version":3} \ No newline at end of file diff --git a/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/6f/correspondenceservicespec_6f5b0f75b3fc4347fc2d2eb89f0249fa b/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/6f/correspondenceservicespec_6f5b0f75b3fc4347fc2d2eb89f0249fa new file mode 100644 index 0000000..7081198 --- /dev/null +++ b/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/6f/correspondenceservicespec_6f5b0f75b3fc4347fc2d2eb89f0249fa @@ -0,0 +1,561 @@ +23ed3615f11546daaa1755fd74e9c758 +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const testing_1 = require("@nestjs/testing"); +const typeorm_1 = require("@nestjs/typeorm"); +const typeorm_2 = require("typeorm"); +const correspondence_service_1 = require("./correspondence.service"); +const correspondence_entity_1 = require("./entities/correspondence.entity"); +const correspondence_revision_entity_1 = require("./entities/correspondence-revision.entity"); +const correspondence_type_entity_1 = require("./entities/correspondence-type.entity"); +const correspondence_status_entity_1 = require("./entities/correspondence-status.entity"); +const correspondence_reference_entity_1 = require("./entities/correspondence-reference.entity"); +const correspondence_tag_entity_1 = require("./entities/correspondence-tag.entity"); +const organization_entity_1 = require("../organization/entities/organization.entity"); +const correspondence_recipient_entity_1 = require("./entities/correspondence-recipient.entity"); +const document_numbering_service_1 = require("../document-numbering/services/document-numbering.service"); +const json_schema_service_1 = require("../json-schema/json-schema.service"); +const workflow_engine_service_1 = require("../workflow-engine/workflow-engine.service"); +const user_service_1 = require("../user/user.service"); +const search_service_1 = require("../search/search.service"); +const file_storage_service_1 = require("../../common/file-storage/file-storage.service"); +const uuid_resolver_service_1 = require("../../common/services/uuid-resolver.service"); +const notification_service_1 = require("../notification/notification.service"); +describe('CorrespondenceService', () => { + let service; + let numberingService; + let correspondenceRepo; + let revisionRepo; + let testingModule; + let _dataSource; + const createMockRepository = () => ({ + find: jest.fn(), + findOne: jest.fn(), + create: jest.fn(), + save: jest.fn(), + update: jest.fn(), + delete: jest.fn(), + softDelete: jest.fn(), + createQueryBuilder: jest.fn(() => ({ + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + andWhere: jest.fn().mockReturnThis(), + orderBy: jest.fn().mockReturnThis(), + skip: jest.fn().mockReturnThis(), + take: jest.fn().mockReturnThis(), + getOne: jest.fn().mockResolvedValue(null), + getMany: jest.fn().mockResolvedValue([]), + getManyAndCount: jest.fn().mockResolvedValue([[], 0]), + })), + }); + const mockDataSource = { + createQueryRunner: jest.fn(() => ({ + connect: jest.fn(), + startTransaction: jest.fn(), + commitTransaction: jest.fn(), + rollbackTransaction: jest.fn(), + release: jest.fn(), + manager: { + create: jest.fn(), + save: jest.fn(), + findOne: jest.fn(), + }, + })), + getRepository: jest.fn(() => createMockRepository()), + manager: { + findOne: jest.fn(), + }, + }; + beforeEach(async () => { + testingModule = await testing_1.Test.createTestingModule({ + providers: [ + correspondence_service_1.CorrespondenceService, + { + provide: (0, typeorm_1.getRepositoryToken)(correspondence_entity_1.Correspondence), + useValue: createMockRepository(), + }, + { + provide: (0, typeorm_1.getRepositoryToken)(correspondence_revision_entity_1.CorrespondenceRevision), + useValue: createMockRepository(), + }, + { + provide: (0, typeorm_1.getRepositoryToken)(correspondence_type_entity_1.CorrespondenceType), + useValue: createMockRepository(), + }, + { + provide: (0, typeorm_1.getRepositoryToken)(correspondence_status_entity_1.CorrespondenceStatus), + useValue: createMockRepository(), + }, + { + provide: (0, typeorm_1.getRepositoryToken)(correspondence_reference_entity_1.CorrespondenceReference), + useValue: createMockRepository(), + }, + { + provide: (0, typeorm_1.getRepositoryToken)(correspondence_tag_entity_1.CorrespondenceTag), + useValue: createMockRepository(), + }, + { + provide: (0, typeorm_1.getRepositoryToken)(organization_entity_1.Organization), + useValue: createMockRepository(), + }, + { + provide: (0, typeorm_1.getRepositoryToken)(correspondence_recipient_entity_1.CorrespondenceRecipient), + useValue: createMockRepository(), + }, + { + provide: document_numbering_service_1.DocumentNumberingService, + useValue: { + generateNextNumber: jest.fn(), + updateNumberForDraft: jest.fn(), + previewNextNumber: jest.fn(), + }, + }, + { + provide: json_schema_service_1.JsonSchemaService, + useValue: { validate: jest.fn() }, + }, + { + provide: workflow_engine_service_1.WorkflowEngineService, + useValue: { createInstance: jest.fn() }, + }, + { + provide: user_service_1.UserService, + useValue: { + findOne: jest.fn(), + getUserPermissions: jest.fn().mockResolvedValue([]), + }, + }, + { + provide: typeorm_2.DataSource, + useValue: mockDataSource, + }, + { + provide: search_service_1.SearchService, + useValue: { indexDocument: jest.fn() }, + }, + { + provide: file_storage_service_1.FileStorageService, + useValue: { commit: jest.fn().mockResolvedValue([]) }, + }, + { + provide: uuid_resolver_service_1.UuidResolverService, + useValue: { + resolveProjectId: jest.fn().mockResolvedValue(1), + resolveOrganizationId: jest.fn().mockResolvedValue(1), + }, + }, + { + provide: notification_service_1.NotificationService, + useValue: { send: jest.fn().mockResolvedValue(undefined) }, + }, + ], + }).compile(); + service = testingModule.get(correspondence_service_1.CorrespondenceService); + numberingService = testingModule.get(document_numbering_service_1.DocumentNumberingService); + correspondenceRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_entity_1.Correspondence)); + revisionRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_revision_entity_1.CorrespondenceRevision)); + _dataSource = testingModule.get(typeorm_2.DataSource); + }); + it('should be defined', () => { + expect(service).toBeDefined(); + }); + describe('update', () => { + it('should NOT regenerate number if critical fields unchanged', async () => { + const mockUser = { id: 1, primaryOrganizationId: 10 }; + const mockRevision = { + id: 100, + correspondenceId: 1, + isCurrent: true, + statusId: 5, + }; + jest + .spyOn(revisionRepo, 'findOne') + .mockResolvedValue(mockRevision); + const mockCorr = { + id: 1, + projectId: 1, + correspondenceTypeId: 2, + disciplineId: 3, + originatorId: 10, + correspondenceNumber: 'OLD-NUM', + recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }], + }; + jest + .spyOn(correspondenceRepo, 'findOne') + .mockResolvedValue(mockCorr); + const updateDto = { + projectId: 1, + disciplineId: 3, + }; + await service.update(1, updateDto, mockUser); + expect(numberingService.updateNumberForDraft).not.toHaveBeenCalled(); + }); + it('should regenerate number if Project ID changes', async () => { + const mockUser = { id: 1, primaryOrganizationId: 10 }; + const mockRevision = { + id: 100, + correspondenceId: 1, + isCurrent: true, + statusId: 5, + }; + jest + .spyOn(revisionRepo, 'findOne') + .mockResolvedValue(mockRevision); + const mockCorr = { + id: 1, + projectId: 1, + correspondenceTypeId: 2, + disciplineId: 3, + originatorId: 10, + correspondenceNumber: 'OLD-NUM', + recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }], + }; + jest + .spyOn(correspondenceRepo, 'findOne') + .mockResolvedValue(mockCorr); + const updateDto = { + projectId: 2, + }; + const uuidResolver = testingModule.get(uuid_resolver_service_1.UuidResolverService); + uuidResolver.resolveProjectId.mockResolvedValue(2); + await service.update(1, updateDto, mockUser); + expect(numberingService.updateNumberForDraft).toHaveBeenCalled(); + }); + it('should regenerate number if Document Type changes', async () => { + const mockUser = { id: 1, primaryOrganizationId: 10 }; + const mockRevision = { + id: 100, + correspondenceId: 1, + isCurrent: true, + statusId: 5, + }; + jest + .spyOn(revisionRepo, 'findOne') + .mockResolvedValue(mockRevision); + const mockCorr = { + id: 1, + projectId: 1, + correspondenceTypeId: 2, + disciplineId: 3, + originatorId: 10, + correspondenceNumber: 'OLD-NUM', + recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }], + }; + jest + .spyOn(correspondenceRepo, 'findOne') + .mockResolvedValue(mockCorr); + const updateDto = { + typeId: 999, + }; + const typeRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_type_entity_1.CorrespondenceType)); + typeRepo.findOne.mockResolvedValue({ + id: 999, + typeCode: 'NEW-TYPE', + }); + await service.update(1, updateDto, mockUser); + expect(numberingService.updateNumberForDraft).toHaveBeenCalled(); + }); + it('should regenerate number if Recipient Organization changes', async () => { + const mockUser = { id: 1, primaryOrganizationId: 10 }; + const mockRevision = { + id: 100, + correspondenceId: 1, + isCurrent: true, + statusId: 5, + }; + jest + .spyOn(revisionRepo, 'findOne') + .mockResolvedValue(mockRevision); + const mockCorr = { + id: 1, + projectId: 1, + correspondenceTypeId: 2, + disciplineId: 3, + originatorId: 10, + correspondenceNumber: 'OLD-NUM', + recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }], + }; + jest + .spyOn(correspondenceRepo, 'findOne') + .mockResolvedValue(mockCorr); + // Access DataSource manager for mocking + mockDataSource.manager.findOne.mockResolvedValue({ + id: 88, + organizationCode: 'NEW-ORG', + }); + const updateDto = { + recipients: [{ type: 'TO', organizationId: 88 }], + }; + await service.update(1, updateDto, mockUser); + expect(numberingService.updateNumberForDraft).toHaveBeenCalled(); + }); + }); + describe('create', () => { + it('should allow system.manage_all user without primaryOrganizationId when originatorId is provided', async () => { + const mockUser = { + user_id: 1, + primaryOrganizationId: null, + }; + const createDto = { + projectId: 'project-uuid', + typeId: 1, + subject: 'Test Subject', + originatorId: 'originator-uuid', + recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }], + }; + const userService = testingModule.get(user_service_1.UserService); + const typeRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_type_entity_1.CorrespondenceType)); + const statusRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_status_entity_1.CorrespondenceStatus)); + const uuidResolver = testingModule.get(uuid_resolver_service_1.UuidResolverService); + userService.findOne.mockResolvedValue({ + user_id: 1, + primaryOrganizationId: null, + }); + userService.getUserPermissions.mockResolvedValue([ + 'system.manage_all', + ]); + uuidResolver.resolveProjectId.mockResolvedValue(100); + uuidResolver.resolveOrganizationId.mockImplementation((value) => { + if (value === 'originator-uuid') + return 10; + if (value === 'recipient-uuid') + return 20; + return 0; + }); + typeRepo.findOne.mockResolvedValue({ + id: 1, + typeCode: 'LTR', + }); + statusRepo.findOne.mockResolvedValue({ + id: 1, + statusCode: 'DRAFT', + }); + numberingService.generateNextNumber.mockResolvedValue({ + number: 'DOC-001', + }); + mockDataSource.manager.findOne + .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' }) + .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' }); + const queryRunner = { + connect: jest.fn(), + startTransaction: jest.fn(), + commitTransaction: jest.fn(), + rollbackTransaction: jest.fn(), + release: jest.fn(), + manager: { + create: jest.fn((_entity, payload) => payload), + save: jest + .fn() + .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' }) + .mockResolvedValueOnce({ id: 1000 }) + .mockResolvedValueOnce([]), + findOne: jest.fn(), + }, + }; + mockDataSource.createQueryRunner.mockReturnValue(queryRunner); + await service.create(createDto, mockUser); + expect(queryRunner.manager.create).toHaveBeenCalledWith(correspondence_entity_1.Correspondence, expect.objectContaining({ originatorId: 10 })); + }); + it('should set revisionLabel to "A" for RFA type', async () => { + const mockUser = { + user_id: 1, + primaryOrganizationId: 10, + }; + const createDto = { + projectId: 'project-uuid', + typeId: 1, + subject: 'Test Subject', + recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }], + }; + const typeRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_type_entity_1.CorrespondenceType)); + const statusRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_status_entity_1.CorrespondenceStatus)); + const uuidResolver = testingModule.get(uuid_resolver_service_1.UuidResolverService); + uuidResolver.resolveProjectId.mockResolvedValue(100); + uuidResolver.resolveOrganizationId.mockResolvedValue(20); + typeRepo.findOne.mockResolvedValue({ + id: 1, + typeCode: 'RFA', + }); + statusRepo.findOne.mockResolvedValue({ + id: 1, + statusCode: 'DRAFT', + }); + numberingService.generateNextNumber.mockResolvedValue({ + number: 'DOC-001', + }); + mockDataSource.manager.findOne + .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' }) + .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' }); + const queryRunner = { + connect: jest.fn(), + startTransaction: jest.fn(), + commitTransaction: jest.fn(), + rollbackTransaction: jest.fn(), + release: jest.fn(), + manager: { + create: jest.fn((_entity, payload) => payload), + save: jest + .fn() + .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' }) + .mockResolvedValueOnce({ id: 1000 }) + .mockResolvedValueOnce([]), + findOne: jest.fn(), + }, + }; + mockDataSource.createQueryRunner.mockReturnValue(queryRunner); + await service.create(createDto, mockUser); + expect(queryRunner.manager.create).toHaveBeenCalledWith(correspondence_revision_entity_1.CorrespondenceRevision, expect.objectContaining({ revisionLabel: 'A' })); + }); + it('should set revisionLabel to "A" for RFI type', async () => { + const mockUser = { + user_id: 1, + primaryOrganizationId: 10, + }; + const createDto = { + projectId: 'project-uuid', + typeId: 1, + subject: 'Test Subject', + recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }], + }; + const typeRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_type_entity_1.CorrespondenceType)); + const statusRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_status_entity_1.CorrespondenceStatus)); + const uuidResolver = testingModule.get(uuid_resolver_service_1.UuidResolverService); + uuidResolver.resolveProjectId.mockResolvedValue(100); + uuidResolver.resolveOrganizationId.mockResolvedValue(20); + typeRepo.findOne.mockResolvedValue({ + id: 1, + typeCode: 'RFI', + }); + statusRepo.findOne.mockResolvedValue({ + id: 1, + statusCode: 'DRAFT', + }); + numberingService.generateNextNumber.mockResolvedValue({ + number: 'DOC-001', + }); + mockDataSource.manager.findOne + .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' }) + .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' }); + const queryRunner = { + connect: jest.fn(), + startTransaction: jest.fn(), + commitTransaction: jest.fn(), + rollbackTransaction: jest.fn(), + release: jest.fn(), + manager: { + create: jest.fn((_entity, payload) => payload), + save: jest + .fn() + .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' }) + .mockResolvedValueOnce({ id: 1000 }) + .mockResolvedValueOnce([]), + findOne: jest.fn(), + }, + }; + mockDataSource.createQueryRunner.mockReturnValue(queryRunner); + await service.create(createDto, mockUser); + expect(queryRunner.manager.create).toHaveBeenCalledWith(correspondence_revision_entity_1.CorrespondenceRevision, expect.objectContaining({ revisionLabel: 'A' })); + }); + it('should set revisionLabel to null for LETTER type', async () => { + const mockUser = { + user_id: 1, + primaryOrganizationId: 10, + }; + const createDto = { + projectId: 'project-uuid', + typeId: 1, + subject: 'Test Subject', + recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }], + }; + const typeRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_type_entity_1.CorrespondenceType)); + const statusRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_status_entity_1.CorrespondenceStatus)); + const uuidResolver = testingModule.get(uuid_resolver_service_1.UuidResolverService); + uuidResolver.resolveProjectId.mockResolvedValue(100); + uuidResolver.resolveOrganizationId.mockResolvedValue(20); + typeRepo.findOne.mockResolvedValue({ + id: 1, + typeCode: 'LETTER', + }); + statusRepo.findOne.mockResolvedValue({ + id: 1, + statusCode: 'DRAFT', + }); + numberingService.generateNextNumber.mockResolvedValue({ + number: 'DOC-001', + }); + mockDataSource.manager.findOne + .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' }) + .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' }); + const queryRunner = { + connect: jest.fn(), + startTransaction: jest.fn(), + commitTransaction: jest.fn(), + rollbackTransaction: jest.fn(), + release: jest.fn(), + manager: { + create: jest.fn((_entity, payload) => payload), + save: jest + .fn() + .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' }) + .mockResolvedValueOnce({ id: 1000 }) + .mockResolvedValueOnce([]), + findOne: jest.fn(), + }, + }; + mockDataSource.createQueryRunner.mockReturnValue(queryRunner); + await service.create(createDto, mockUser); + expect(queryRunner.manager.create).toHaveBeenCalledWith(correspondence_revision_entity_1.CorrespondenceRevision, expect.objectContaining({ revisionLabel: undefined })); + }); + it('should set revisionLabel to undefined for MEMO type', async () => { + const mockUser = { + user_id: 1, + primaryOrganizationId: 10, + }; + const createDto = { + projectId: 'project-uuid', + typeId: 1, + subject: 'Test Subject', + recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }], + }; + const typeRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_type_entity_1.CorrespondenceType)); + const statusRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_status_entity_1.CorrespondenceStatus)); + const uuidResolver = testingModule.get(uuid_resolver_service_1.UuidResolverService); + uuidResolver.resolveProjectId.mockResolvedValue(100); + uuidResolver.resolveOrganizationId.mockResolvedValue(20); + typeRepo.findOne.mockResolvedValue({ + id: 1, + typeCode: 'MEMO', + }); + statusRepo.findOne.mockResolvedValue({ + id: 1, + statusCode: 'DRAFT', + }); + numberingService.generateNextNumber.mockResolvedValue({ + number: 'DOC-001', + }); + mockDataSource.manager.findOne + .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' }) + .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' }); + const queryRunner = { + connect: jest.fn(), + startTransaction: jest.fn(), + commitTransaction: jest.fn(), + rollbackTransaction: jest.fn(), + release: jest.fn(), + manager: { + create: jest.fn((_entity, payload) => payload), + save: jest + .fn() + .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' }) + .mockResolvedValueOnce({ id: 1000 }) + .mockResolvedValueOnce([]), + findOne: jest.fn(), + }, + }; + mockDataSource.createQueryRunner.mockReturnValue(queryRunner); + await service.create(createDto, mockUser); + expect(queryRunner.manager.create).toHaveBeenCalledWith(correspondence_revision_entity_1.CorrespondenceRevision, expect.objectContaining({ revisionLabel: undefined })); + }); + }); +}); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJmaWxlIjoiRTpcXG5wLWRtc1xcbGNicDNcXGJhY2tlbmRcXHNyY1xcbW9kdWxlc1xcY29ycmVzcG9uZGVuY2VcXGNvcnJlc3BvbmRlbmNlLnNlcnZpY2Uuc3BlYy50cyIsIm1hcHBpbmdzIjoiOztBQUFBLDZDQUFzRDtBQUN0RCw2Q0FBcUQ7QUFDckQscUNBQWlEO0FBQ2pELHFFQUFpRTtBQUNqRSw0RUFBa0U7QUFDbEUsOEZBQW1GO0FBQ25GLHNGQUEyRTtBQUMzRSwwRkFBK0U7QUFDL0UsZ0dBQXFGO0FBQ3JGLG9GQUF5RTtBQUN6RSxzRkFBNEU7QUFDNUUsZ0dBQXFGO0FBQ3JGLDBHQUFxRztBQUNyRyw0RUFBdUU7QUFDdkUsd0ZBQW1GO0FBQ25GLHVEQUFtRDtBQUNuRCw2REFBeUQ7QUFDekQseUZBQW9GO0FBQ3BGLHVGQUFrRjtBQUNsRiwrRUFBMkU7QUFLM0UsUUFBUSxDQUFDLHVCQUF1QixFQUFFLEdBQUcsRUFBRTtJQUNyQyxJQUFJLE9BQThCLENBQUM7SUFDbkMsSUFBSSxnQkFBMEMsQ0FBQztJQUMvQyxJQUFJLGtCQUE4QyxDQUFDO0lBQ25ELElBQUksWUFBZ0QsQ0FBQztJQUNyRCxJQUFJLGFBQTRCLENBQUM7SUFDakMsSUFBSSxXQUF1QixDQUFDO0lBRTVCLE1BQU0sb0JBQW9CLEdBQUcsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUNsQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRTtRQUNmLE9BQU8sRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFFO1FBQ2xCLE1BQU0sRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFFO1FBQ2pCLElBQUksRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFFO1FBQ2YsTUFBTSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUU7UUFDakIsTUFBTSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUU7UUFDakIsVUFBVSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUU7UUFDckIsa0JBQWtCLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQ2pD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QUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxvQkFBb0IsQ0FDckQsdURBQXNCLEVBQ3RCLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUN0RCxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIkU6XFxucC1kbXNcXGxjYnAzXFxiYWNrZW5kXFxzcmNcXG1vZHVsZXNcXGNvcnJlc3BvbmRlbmNlXFxjb3JyZXNwb25kZW5jZS5zZXJ2aWNlLnNwZWMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVGVzdCwgVGVzdGluZ01vZHVsZSB9IGZyb20gJ0BuZXN0anMvdGVzdGluZyc7XHJcbmltcG9ydCB7IGdldFJlcG9zaXRvcnlUb2tlbiB9IGZyb20gJ0BuZXN0anMvdHlwZW9ybSc7XHJcbmltcG9ydCB7IERhdGFTb3VyY2UsIFJlcG9zaXRvcnkgfSBmcm9tICd0eXBlb3JtJztcclxuaW1wb3J0IHsgQ29ycmVzcG9uZGVuY2VTZXJ2aWNlIH0gZnJvbSAnLi9jb3JyZXNwb25kZW5jZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgQ29ycmVzcG9uZGVuY2UgfSBmcm9tICcuL2VudGl0aWVzL2NvcnJlc3BvbmRlbmNlLmVudGl0eSc7XHJcbmltcG9ydCB7IENvcnJlc3BvbmRlbmNlUmV2aXNpb24gfSBmcm9tICcuL2VudGl0aWVzL2NvcnJlc3BvbmRlbmNlLXJldmlzaW9uLmVudGl0eSc7XHJcbmltcG9ydCB7IENvcnJlc3BvbmRlbmNlVHlwZSB9IGZyb20gJy4vZW50aXRpZXMvY29ycmVzcG9uZGVuY2UtdHlwZS5lbnRpdHknO1xyXG5pbXBvcnQgeyBDb3JyZXNwb25kZW5jZVN0YXR1cyB9IGZyb20gJy4vZW50aXRpZXMvY29ycmVzcG9uZGVuY2Utc3RhdHVzLmVudGl0eSc7XHJcbmltcG9ydCB7IENvcnJlc3BvbmRlbmNlUmVmZXJlbmNlIH0gZnJvbSAnLi9lbnRpdGllcy9jb3JyZXNwb25kZW5jZS1yZWZlcmVuY2UuZW50aXR5JztcclxuaW1wb3J0IHsgQ29ycmVzcG9uZGVuY2VUYWcgfSBmcm9tICcuL2VudGl0aWVzL2NvcnJlc3BvbmRlbmNlLXRhZy5lbnRpdHknO1xyXG5pbXBvcnQgeyBPcmdhbml6YXRpb24gfSBmcm9tICcuLi9vcmdhbml6YXRpb24vZW50aXRpZXMvb3JnYW5pemF0aW9uLmVudGl0eSc7XHJcbmltcG9ydCB7IENvcnJlc3BvbmRlbmNlUmVjaXBpZW50IH0gZnJvbSAnLi9lbnRpdGllcy9jb3JyZXNwb25kZW5jZS1yZWNpcGllbnQuZW50aXR5JztcclxuaW1wb3J0IHsgRG9jdW1lbnROdW1iZXJpbmdTZXJ2aWNlIH0gZnJvbSAnLi4vZG9jdW1lbnQtbnVtYmVyaW5nL3NlcnZpY2VzL2RvY3VtZW50LW51bWJlcmluZy5zZXJ2aWNlJztcclxuaW1wb3J0IHsgSnNvblNjaGVtYVNlcnZpY2UgfSBmcm9tICcuLi9qc29uLXNjaGVtYS9qc29uLXNjaGVtYS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgV29ya2Zsb3dFbmdpbmVTZXJ2aWNlIH0gZnJvbSAnLi4vd29ya2Zsb3ctZW5naW5lL3dvcmtmbG93LWVuZ2luZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgVXNlclNlcnZpY2UgfSBmcm9tICcuLi91c2VyL3VzZXIuc2VydmljZSc7XHJcbmltcG9ydCB7IFNlYXJjaFNlcnZpY2UgfSBmcm9tICcuLi9zZWFyY2gvc2VhcmNoLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBGaWxlU3RvcmFnZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9jb21tb24vZmlsZS1zdG9yYWdlL2ZpbGUtc3RvcmFnZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgVXVpZFJlc29sdmVyU2VydmljZSB9IGZyb20gJy4uLy4uL2NvbW1vbi9zZXJ2aWNlcy91dWlkLXJlc29sdmVyLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBOb3RpZmljYXRpb25TZXJ2aWNlIH0gZnJvbSAnLi4vbm90aWZpY2F0aW9uL25vdGlmaWNhdGlvbi5zZXJ2aWNlJztcclxuaW1wb3J0IHsgVXBkYXRlQ29ycmVzcG9uZGVuY2VEdG8gfSBmcm9tICcuL2R0by91cGRhdGUtY29ycmVzcG9uZGVuY2UuZHRvJztcclxuaW1wb3J0IHsgQ3JlYXRlQ29ycmVzcG9uZGVuY2VEdG8gfSBmcm9tICcuL2R0by9jcmVhdGUtY29ycmVzcG9uZGVuY2UuZHRvJztcclxuaW1wb3J0IHsgVXNlciB9IGZyb20gJy4uL3VzZXIvZW50aXRpZXMvdXNlci5lbnRpdHknO1xyXG5cclxuZGVzY3JpYmUoJ0NvcnJlc3BvbmRlbmNlU2VydmljZScsICgpID0+IHtcclxuICBsZXQgc2VydmljZTogQ29ycmVzcG9uZGVuY2VTZXJ2aWNlO1xyXG4gIGxldCBudW1iZXJpbmdTZXJ2aWNlOiBEb2N1bWVudE51bWJlcmluZ1NlcnZpY2U7XHJcbiAgbGV0IGNvcnJlc3BvbmRlbmNlUmVwbzogUmVwb3NpdG9yeTxDb3JyZXNwb25kZW5jZT47XHJcbiAgbGV0IHJldmlzaW9uUmVwbzogUmVwb3NpdG9yeTxDb3JyZXNwb25kZW5jZVJldmlzaW9uPjtcclxuICBsZXQgdGVzdGluZ01vZHVsZTogVGVzdGluZ01vZHVsZTtcclxuICBsZXQgX2RhdGFTb3VyY2U6IERhdGFTb3VyY2U7XHJcblxyXG4gIGNvbnN0IGNyZWF0ZU1vY2tSZXBvc2l0b3J5ID0gKCkgPT4gKHtcclxuICAgIGZpbmQ6IGplc3QuZm4oKSxcclxuICAgIGZpbmRPbmU6IGplc3QuZm4oKSxcclxuICAgIGNyZWF0ZTogamVzdC5mbigpLFxyXG4gICAgc2F2ZTogamVzdC5mbigpLFxyXG4gICAgdXBkYXRlOiBqZXN0LmZuKCksXHJcbiAgICBkZWxldGU6IGplc3QuZm4oKSxcclxuICAgIHNvZnREZWxldGU6IGplc3QuZm4oKSxcclxuICAgIGNyZWF0ZVF1ZXJ5QnVpbGRlcjogamVzdC5mbigoKSA9PiAoe1xyXG4gICAgICBsZWZ0Sm9pbkFuZFNlbGVjdDogamVzdC5mbigpLm1vY2tSZXR1cm5UaGlzKCksXHJcbiAgICAgIHdoZXJlOiBqZXN0LmZuKCkubW9ja1JldHVyblRoaXMoKSxcclxuICAgICAgYW5kV2hlcmU6IGplc3QuZm4oKS5tb2NrUmV0dXJuVGhpcygpLFxyXG4gICAgICBvcmRlckJ5OiBqZXN0LmZuKCkubW9ja1JldHVyblRoaXMoKSxcclxuICAgICAgc2tpcDogamVzdC5mbigpLm1vY2tSZXR1cm5UaGlzKCksXHJcbiAgICAgIHRha2U6IGplc3QuZm4oKS5tb2NrUmV0dXJuVGhpcygpLFxyXG4gICAgICBnZXRPbmU6IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZShudWxsKSxcclxuICAgICAgZ2V0TWFueTogamVzdC5mbigpLm1vY2tSZXNvbHZlZFZhbHVlKFtdKSxcclxuICAgICAgZ2V0TWFueUFuZENvdW50OiBqZXN0LmZuKCkubW9ja1Jlc29sdmVkVmFsdWUoW1tdLCAwXSksXHJcbiAgICB9KSksXHJcbiAgfSk7XHJcblxyXG4gIGNvbnN0IG1vY2tEYXRhU291cmNlID0ge1xyXG4gICAgY3JlYXRlUXVlcnlSdW5uZXI6IGplc3QuZm4oKCkgPT4gKHtcclxuICAgICAgY29ubmVjdDogamVzdC5mbigpLFxyXG4gICAgICBzdGFydFRyYW5zYWN0aW9uOiBqZXN0LmZuKCksXHJcbiAgICAgIGNvbW1pdFRyYW5zYWN0aW9uOiBqZXN0LmZuKCksXHJcbiAgICAgIHJvbGxiYWNrVHJhbnNhY3Rpb246IGplc3QuZm4oKSxcclxuICAgICAgcmVsZWFzZTogamVzdC5mbigpLFxyXG4gICAgICBtYW5hZ2VyOiB7XHJcbiAgICAgICAgY3JlYXRlOiBqZXN0LmZuKCksXHJcbiAgICAgICAgc2F2ZTogamVzdC5mbigpLFxyXG4gICAgICAgIGZpbmRPbmU6IGplc3QuZm4oKSxcclxuICAgICAgfSxcclxuICAgIH0pKSxcclxuICAgIGdldFJlcG9zaXRvcnk6IGplc3QuZm4oKCkgPT4gY3JlYXRlTW9ja1JlcG9zaXRvcnkoKSksXHJcbiAgICBtYW5hZ2VyOiB7XHJcbiAgICAgIGZpbmRPbmU6IGplc3QuZm4oKSxcclxuICAgIH0sXHJcbiAgfTtcclxuXHJcbiAgYmVmb3JlRWFjaChhc3luYyAoKSA9PiB7XHJcbiAgICB0ZXN0aW5nTW9kdWxlID0gYXdhaXQgVGVzdC5jcmVhdGVUZXN0aW5nTW9kdWxlKHtcclxuICAgICAgcHJvdmlkZXJzOiBbXHJcbiAgICAgICAgQ29ycmVzcG9uZGVuY2VTZXJ2aWNlLFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IGdldFJlcG9zaXRvcnlUb2tlbihDb3JyZXNwb25kZW5jZSksXHJcbiAgICAgICAgICB1c2VWYWx1ZTogY3JlYXRlTW9ja1JlcG9zaXRvcnkoKSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IGdldFJlcG9zaXRvcnlUb2tlbihDb3JyZXNwb25kZW5jZVJldmlzaW9uKSxcclxuICAgICAgICAgIHVzZVZhbHVlOiBjcmVhdGVNb2NrUmVwb3NpdG9yeSgpLFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgcHJvdmlkZTogZ2V0UmVwb3NpdG9yeVRva2VuKENvcnJlc3BvbmRlbmNlVHlwZSksXHJcbiAgICAgICAgICB1c2VWYWx1ZTogY3JlYXRlTW9ja1JlcG9zaXRvcnkoKSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IGdldFJlcG9zaXRvcnlUb2tlbihDb3JyZXNwb25kZW5jZVN0YXR1cyksXHJcbiAgICAgICAgICB1c2VWYWx1ZTogY3JlYXRlTW9ja1JlcG9zaXRvcnkoKSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IGdldFJlcG9zaXRvcnlUb2tlbihDb3JyZXNwb25kZW5jZVJlZmVyZW5jZSksXHJcbiAgICAgICAgICB1c2VWYWx1ZTogY3JlYXRlTW9ja1JlcG9zaXRvcnkoKSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IGdldFJlcG9zaXRvcnlUb2tlbihDb3JyZXNwb25kZW5jZVRhZyksXHJcbiAgICAgICAgICB1c2VWYWx1ZTogY3JlYXRlTW9ja1JlcG9zaXRvcnkoKSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IGdldFJlcG9zaXRvcnlUb2tlbihPcmdhbml6YXRpb24pLFxyXG4gICAgICAgICAgdXNlVmFsdWU6IGNyZWF0ZU1vY2tSZXBvc2l0b3J5KCksXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBwcm92aWRlOiBnZXRSZXBvc2l0b3J5VG9rZW4oQ29ycmVzcG9uZGVuY2VSZWNpcGllbnQpLFxyXG4gICAgICAgICAgdXNlVmFsdWU6IGNyZWF0ZU1vY2tSZXBvc2l0b3J5KCksXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBwcm92aWRlOiBEb2N1bWVudE51bWJlcmluZ1NlcnZpY2UsXHJcbiAgICAgICAgICB1c2VWYWx1ZToge1xyXG4gICAgICAgICAgICBnZW5lcmF0ZU5leHROdW1iZXI6IGplc3QuZm4oKSxcclxuICAgICAgICAgICAgdXBkYXRlTnVtYmVyRm9yRHJhZnQ6IGplc3QuZm4oKSxcclxuICAgICAgICAgICAgcHJldmlld05leHROdW1iZXI6IGplc3QuZm4oKSxcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBwcm92aWRlOiBKc29uU2NoZW1hU2VydmljZSxcclxuICAgICAgICAgIHVzZVZhbHVlOiB7IHZhbGlkYXRlOiBqZXN0LmZuKCkgfSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IFdvcmtmbG93RW5naW5lU2VydmljZSxcclxuICAgICAgICAgIHVzZVZhbHVlOiB7IGNyZWF0ZUluc3RhbmNlOiBqZXN0LmZuKCkgfSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IFVzZXJTZXJ2aWNlLFxyXG4gICAgICAgICAgdXNlVmFsdWU6IHtcclxuICAgICAgICAgICAgZmluZE9uZTogamVzdC5mbigpLFxyXG4gICAgICAgICAgICBnZXRVc2VyUGVybWlzc2lvbnM6IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZShbXSksXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgcHJvdmlkZTogRGF0YVNvdXJjZSxcclxuICAgICAgICAgIHVzZVZhbHVlOiBtb2NrRGF0YVNvdXJjZSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IFNlYXJjaFNlcnZpY2UsXHJcbiAgICAgICAgICB1c2VWYWx1ZTogeyBpbmRleERvY3VtZW50OiBqZXN0LmZuKCkgfSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IEZpbGVTdG9yYWdlU2VydmljZSxcclxuICAgICAgICAgIHVzZVZhbHVlOiB7IGNvbW1pdDogamVzdC5mbigpLm1vY2tSZXNvbHZlZFZhbHVlKFtdKSB9LFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgcHJvdmlkZTogVXVpZFJlc29sdmVyU2VydmljZSxcclxuICAgICAgICAgIHVzZVZhbHVlOiB7XHJcbiAgICAgICAgICAgIHJlc29sdmVQcm9qZWN0SWQ6IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZSgxKSxcclxuICAgICAgICAgICAgcmVzb2x2ZU9yZ2FuaXphdGlvbklkOiBqZXN0LmZuKCkubW9ja1Jlc29sdmVkVmFsdWUoMSksXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgcHJvdmlkZTogTm90aWZpY2F0aW9uU2VydmljZSxcclxuICAgICAgICAgIHVzZVZhbHVlOiB7IHNlbmQ6IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZSh1bmRlZmluZWQpIH0sXHJcbiAgICAgICAgfSxcclxuICAgICAgXSxcclxuICAgIH0pLmNvbXBpbGUoKTtcclxuXHJcbiAgICBzZXJ2aWNlID0gdGVzdGluZ01vZHVsZS5nZXQ8Q29ycmVzcG9uZGVuY2VTZXJ2aWNlPihDb3JyZXNwb25kZW5jZVNlcnZpY2UpO1xyXG4gICAgbnVtYmVyaW5nU2VydmljZSA9IHRlc3RpbmdNb2R1bGUuZ2V0PERvY3VtZW50TnVtYmVyaW5nU2VydmljZT4oXHJcbiAgICAgIERvY3VtZW50TnVtYmVyaW5nU2VydmljZVxyXG4gICAgKTtcclxuICAgIGNvcnJlc3BvbmRlbmNlUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2U+PihcclxuICAgICAgZ2V0UmVwb3NpdG9yeVRva2VuKENvcnJlc3BvbmRlbmNlKVxyXG4gICAgKTtcclxuICAgIHJldmlzaW9uUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2VSZXZpc2lvbj4+KFxyXG4gICAgICBnZXRSZXBvc2l0b3J5VG9rZW4oQ29ycmVzcG9uZGVuY2VSZXZpc2lvbilcclxuICAgICk7XHJcbiAgICBfZGF0YVNvdXJjZSA9IHRlc3RpbmdNb2R1bGUuZ2V0PERhdGFTb3VyY2U+KERhdGFTb3VyY2UpO1xyXG4gIH0pO1xyXG5cclxuICBpdCgnc2hvdWxkIGJlIGRlZmluZWQnLCAoKSA9PiB7XHJcbiAgICBleHBlY3Qoc2VydmljZSkudG9CZURlZmluZWQoKTtcclxuICB9KTtcclxuXHJcbiAgZGVzY3JpYmUoJ3VwZGF0ZScsICgpID0+IHtcclxuICAgIGl0KCdzaG91bGQgTk9UIHJlZ2VuZXJhdGUgbnVtYmVyIGlmIGNyaXRpY2FsIGZpZWxkcyB1bmNoYW5nZWQnLCBhc3luYyAoKSA9PiB7XHJcbiAgICAgIGNvbnN0IG1vY2tVc2VyID0geyBpZDogMSwgcHJpbWFyeU9yZ2FuaXphdGlvbklkOiAxMCB9IGFzIHVua25vd24gYXMgVXNlcjtcclxuICAgICAgY29uc3QgbW9ja1JldmlzaW9uID0ge1xyXG4gICAgICAgIGlkOiAxMDAsXHJcbiAgICAgICAgY29ycmVzcG9uZGVuY2VJZDogMSxcclxuICAgICAgICBpc0N1cnJlbnQ6IHRydWUsXHJcbiAgICAgICAgc3RhdHVzSWQ6IDUsXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBqZXN0XHJcbiAgICAgICAgLnNweU9uKHJldmlzaW9uUmVwbywgJ2ZpbmRPbmUnKVxyXG4gICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZShtb2NrUmV2aXNpb24gYXMgdW5rbm93biBhcyBDb3JyZXNwb25kZW5jZVJldmlzaW9uKTtcclxuXHJcbiAgICAgIGNvbnN0IG1vY2tDb3JyID0ge1xyXG4gICAgICAgIGlkOiAxLFxyXG4gICAgICAgIHByb2plY3RJZDogMSxcclxuICAgICAgICBjb3JyZXNwb25kZW5jZVR5cGVJZDogMixcclxuICAgICAgICBkaXNjaXBsaW5lSWQ6IDMsXHJcbiAgICAgICAgb3JpZ2luYXRvcklkOiAxMCxcclxuICAgICAgICBjb3JyZXNwb25kZW5jZU51bWJlcjogJ09MRC1OVU0nLFxyXG4gICAgICAgIHJlY2lwaWVudHM6IFt7IHJlY2lwaWVudFR5cGU6ICdUTycsIHJlY2lwaWVudE9yZ2FuaXphdGlvbklkOiA5OSB9XSxcclxuICAgICAgfTtcclxuICAgICAgamVzdFxyXG4gICAgICAgIC5zcHlPbihjb3JyZXNwb25kZW5jZVJlcG8sICdmaW5kT25lJylcclxuICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWUobW9ja0NvcnIgYXMgdW5rbm93biBhcyBDb3JyZXNwb25kZW5jZSk7XHJcblxyXG4gICAgICBjb25zdCB1cGRhdGVEdG86IFVwZGF0ZUNvcnJlc3BvbmRlbmNlRHRvID0ge1xyXG4gICAgICAgIHByb2plY3RJZDogMSxcclxuICAgICAgICBkaXNjaXBsaW5lSWQ6IDMsXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBhd2FpdCBzZXJ2aWNlLnVwZGF0ZSgxLCB1cGRhdGVEdG8sIG1vY2tVc2VyKTtcclxuXHJcbiAgICAgIGV4cGVjdChcclxuICAgICAgICBudW1iZXJpbmdTZXJ2aWNlLnVwZGF0ZU51bWJlckZvckRyYWZ0IGFzIGplc3QuTW9ja1xyXG4gICAgICApLm5vdC50b0hhdmVCZWVuQ2FsbGVkKCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBpdCgnc2hvdWxkIHJlZ2VuZXJhdGUgbnVtYmVyIGlmIFByb2plY3QgSUQgY2hhbmdlcycsIGFzeW5jICgpID0+IHtcclxuICAgICAgY29uc3QgbW9ja1VzZXIgPSB7IGlkOiAxLCBwcmltYXJ5T3JnYW5pemF0aW9uSWQ6IDEwIH0gYXMgdW5rbm93biBhcyBVc2VyO1xyXG4gICAgICBjb25zdCBtb2NrUmV2aXNpb24gPSB7XHJcbiAgICAgICAgaWQ6IDEwMCxcclxuICAgICAgICBjb3JyZXNwb25kZW5jZUlkOiAxLFxyXG4gICAgICAgIGlzQ3VycmVudDogdHJ1ZSxcclxuICAgICAgICBzdGF0dXNJZDogNSxcclxuICAgICAgfTtcclxuICAgICAgamVzdFxyXG4gICAgICAgIC5zcHlPbihyZXZpc2lvblJlcG8sICdmaW5kT25lJylcclxuICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWUobW9ja1JldmlzaW9uIGFzIHVua25vd24gYXMgQ29ycmVzcG9uZGVuY2VSZXZpc2lvbik7XHJcblxyXG4gICAgICBjb25zdCBtb2NrQ29yciA9IHtcclxuICAgICAgICBpZDogMSxcclxuICAgICAgICBwcm9qZWN0SWQ6IDEsXHJcbiAgICAgICAgY29ycmVzcG9uZGVuY2VUeXBlSWQ6IDIsXHJcbiAgICAgICAgZGlzY2lwbGluZUlkOiAzLFxyXG4gICAgICAgIG9yaWdpbmF0b3JJZDogMTAsXHJcbiAgICAgICAgY29ycmVzcG9uZGVuY2VOdW1iZXI6ICdPTEQtTlVNJyxcclxuICAgICAgICByZWNpcGllbnRzOiBbeyByZWNpcGllbnRUeXBlOiAnVE8nLCByZWNpcGllbnRPcmdhbml6YXRpb25JZDogOTkgfV0sXHJcbiAgICAgIH07XHJcbiAgICAgIGplc3RcclxuICAgICAgICAuc3B5T24oY29ycmVzcG9uZGVuY2VSZXBvLCAnZmluZE9uZScpXHJcbiAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlKG1vY2tDb3JyIGFzIHVua25vd24gYXMgQ29ycmVzcG9uZGVuY2UpO1xyXG5cclxuICAgICAgY29uc3QgdXBkYXRlRHRvOiBVcGRhdGVDb3JyZXNwb25kZW5jZUR0byA9IHtcclxuICAgICAgICBwcm9qZWN0SWQ6IDIsXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBjb25zdCB1dWlkUmVzb2x2ZXIgPVxyXG4gICAgICAgIHRlc3RpbmdNb2R1bGUuZ2V0PFV1aWRSZXNvbHZlclNlcnZpY2U+KFV1aWRSZXNvbHZlclNlcnZpY2UpO1xyXG4gICAgICAodXVpZFJlc29sdmVyLnJlc29sdmVQcm9qZWN0SWQgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSgyKTtcclxuXHJcbiAgICAgIGF3YWl0IHNlcnZpY2UudXBkYXRlKDEsIHVwZGF0ZUR0bywgbW9ja1VzZXIpO1xyXG5cclxuICAgICAgZXhwZWN0KFxyXG4gICAgICAgIG51bWJlcmluZ1NlcnZpY2UudXBkYXRlTnVtYmVyRm9yRHJhZnQgYXMgamVzdC5Nb2NrXHJcbiAgICAgICkudG9IYXZlQmVlbkNhbGxlZCgpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgaXQoJ3Nob3VsZCByZWdlbmVyYXRlIG51bWJlciBpZiBEb2N1bWVudCBUeXBlIGNoYW5nZXMnLCBhc3luYyAoKSA9PiB7XHJcbiAgICAgIGNvbnN0IG1vY2tVc2VyID0geyBpZDogMSwgcHJpbWFyeU9yZ2FuaXphdGlvbklkOiAxMCB9IGFzIHVua25vd24gYXMgVXNlcjtcclxuICAgICAgY29uc3QgbW9ja1JldmlzaW9uID0ge1xyXG4gICAgICAgIGlkOiAxMDAsXHJcbiAgICAgICAgY29ycmVzcG9uZGVuY2VJZDogMSxcclxuICAgICAgICBpc0N1cnJlbnQ6IHRydWUsXHJcbiAgICAgICAgc3RhdHVzSWQ6IDUsXHJcbiAgICAgIH07XHJcbiAgICAgIGplc3RcclxuICAgICAgICAuc3B5T24ocmV2aXNpb25SZXBvLCAnZmluZE9uZScpXHJcbiAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlKG1vY2tSZXZpc2lvbiBhcyB1bmtub3duIGFzIENvcnJlc3BvbmRlbmNlUmV2aXNpb24pO1xyXG5cclxuICAgICAgY29uc3QgbW9ja0NvcnIgPSB7XHJcbiAgICAgICAgaWQ6IDEsXHJcbiAgICAgICAgcHJvamVjdElkOiAxLFxyXG4gICAgICAgIGNvcnJlc3BvbmRlbmNlVHlwZUlkOiAyLFxyXG4gICAgICAgIGRpc2NpcGxpbmVJZDogMyxcclxuICAgICAgICBvcmlnaW5hdG9ySWQ6IDEwLFxyXG4gICAgICAgIGNvcnJlc3BvbmRlbmNlTnVtYmVyOiAnT0xELU5VTScsXHJcbiAgICAgICAgcmVjaXBpZW50czogW3sgcmVjaXBpZW50VHlwZTogJ1RPJywgcmVjaXBpZW50T3JnYW5pemF0aW9uSWQ6IDk5IH1dLFxyXG4gICAgICB9O1xyXG4gICAgICBqZXN0XHJcbiAgICAgICAgLnNweU9uKGNvcnJlc3BvbmRlbmNlUmVwbywgJ2ZpbmRPbmUnKVxyXG4gICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZShtb2NrQ29yciBhcyB1bmtub3duIGFzIENvcnJlc3BvbmRlbmNlKTtcclxuXHJcbiAgICAgIGNvbnN0IHVwZGF0ZUR0bzogVXBkYXRlQ29ycmVzcG9uZGVuY2VEdG8gPSB7XHJcbiAgICAgICAgdHlwZUlkOiA5OTksXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBjb25zdCB0eXBlUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2VUeXBlPj4oXHJcbiAgICAgICAgZ2V0UmVwb3NpdG9yeVRva2VuKENvcnJlc3BvbmRlbmNlVHlwZSlcclxuICAgICAgKTtcclxuICAgICAgKHR5cGVSZXBvLmZpbmRPbmUgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgaWQ6IDk5OSxcclxuICAgICAgICB0eXBlQ29kZTogJ05FVy1UWVBFJyxcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBhd2FpdCBzZXJ2aWNlLnVwZGF0ZSgxLCB1cGRhdGVEdG8sIG1vY2tVc2VyKTtcclxuXHJcbiAgICAgIGV4cGVjdChcclxuICAgICAgICBudW1iZXJpbmdTZXJ2aWNlLnVwZGF0ZU51bWJlckZvckRyYWZ0IGFzIGplc3QuTW9ja1xyXG4gICAgICApLnRvSGF2ZUJlZW5DYWxsZWQoKTtcclxuICAgIH0pO1xyXG5cclxuICAgIGl0KCdzaG91bGQgcmVnZW5lcmF0ZSBudW1iZXIgaWYgUmVjaXBpZW50IE9yZ2FuaXphdGlvbiBjaGFuZ2VzJywgYXN5bmMgKCkgPT4ge1xyXG4gICAgICBjb25zdCBtb2NrVXNlciA9IHsgaWQ6IDEsIHByaW1hcnlPcmdhbml6YXRpb25JZDogMTAgfSBhcyB1bmtub3duIGFzIFVzZXI7XHJcbiAgICAgIGNvbnN0IG1vY2tSZXZpc2lvbiA9IHtcclxuICAgICAgICBpZDogMTAwLFxyXG4gICAgICAgIGNvcnJlc3BvbmRlbmNlSWQ6IDEsXHJcbiAgICAgICAgaXNDdXJyZW50OiB0cnVlLFxyXG4gICAgICAgIHN0YXR1c0lkOiA1LFxyXG4gICAgICB9O1xyXG4gICAgICBqZXN0XHJcbiAgICAgICAgLnNweU9uKHJldmlzaW9uUmVwbywgJ2ZpbmRPbmUnKVxyXG4gICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZShtb2NrUmV2aXNpb24gYXMgdW5rbm93biBhcyBDb3JyZXNwb25kZW5jZVJldmlzaW9uKTtcclxuXHJcbiAgICAgIGNvbnN0IG1vY2tDb3JyID0ge1xyXG4gICAgICAgIGlkOiAxLFxyXG4gICAgICAgIHByb2plY3RJZDogMSxcclxuICAgICAgICBjb3JyZXNwb25kZW5jZVR5cGVJZDogMixcclxuICAgICAgICBkaXNjaXBsaW5lSWQ6IDMsXHJcbiAgICAgICAgb3JpZ2luYXRvcklkOiAxMCxcclxuICAgICAgICBjb3JyZXNwb25kZW5jZU51bWJlcjogJ09MRC1OVU0nLFxyXG4gICAgICAgIHJlY2lwaWVudHM6IFt7IHJlY2lwaWVudFR5cGU6ICdUTycsIHJlY2lwaWVudE9yZ2FuaXphdGlvbklkOiA5OSB9XSxcclxuICAgICAgfTtcclxuICAgICAgamVzdFxyXG4gICAgICAgIC5zcHlPbihjb3JyZXNwb25kZW5jZVJlcG8sICdmaW5kT25lJylcclxuICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWUobW9ja0NvcnIgYXMgdW5rbm93biBhcyBDb3JyZXNwb25kZW5jZSk7XHJcblxyXG4gICAgICAvLyBBY2Nlc3MgRGF0YVNvdXJjZSBtYW5hZ2VyIGZvciBtb2NraW5nXHJcbiAgICAgIG1vY2tEYXRhU291cmNlLm1hbmFnZXIuZmluZE9uZS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgaWQ6IDg4LFxyXG4gICAgICAgIG9yZ2FuaXphdGlvbkNvZGU6ICdORVctT1JHJyxcclxuICAgICAgfSBhcyB1bmtub3duIGFzIE9yZ2FuaXphdGlvbik7XHJcblxyXG4gICAgICBjb25zdCB1cGRhdGVEdG86IFVwZGF0ZUNvcnJlc3BvbmRlbmNlRHRvID0ge1xyXG4gICAgICAgIHJlY2lwaWVudHM6IFt7IHR5cGU6ICdUTycsIG9yZ2FuaXphdGlvbklkOiA4OCB9XSxcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGF3YWl0IHNlcnZpY2UudXBkYXRlKDEsIHVwZGF0ZUR0bywgbW9ja1VzZXIpO1xyXG5cclxuICAgICAgZXhwZWN0KFxyXG4gICAgICAgIG51bWJlcmluZ1NlcnZpY2UudXBkYXRlTnVtYmVyRm9yRHJhZnQgYXMgamVzdC5Nb2NrXHJcbiAgICAgICkudG9IYXZlQmVlbkNhbGxlZCgpO1xyXG4gICAgfSk7XHJcbiAgfSk7XHJcblxyXG4gIGRlc2NyaWJlKCdjcmVhdGUnLCAoKSA9PiB7XHJcbiAgICBpdCgnc2hvdWxkIGFsbG93IHN5c3RlbS5tYW5hZ2VfYWxsIHVzZXIgd2l0aG91dCBwcmltYXJ5T3JnYW5pemF0aW9uSWQgd2hlbiBvcmlnaW5hdG9ySWQgaXMgcHJvdmlkZWQnLCBhc3luYyAoKSA9PiB7XHJcbiAgICAgIGNvbnN0IG1vY2tVc2VyID0ge1xyXG4gICAgICAgIHVzZXJfaWQ6IDEsXHJcbiAgICAgICAgcHJpbWFyeU9yZ2FuaXphdGlvbklkOiBudWxsLFxyXG4gICAgICB9IGFzIHVua25vd24gYXMgVXNlcjtcclxuXHJcbiAgICAgIGNvbnN0IGNyZWF0ZUR0bzogQ3JlYXRlQ29ycmVzcG9uZGVuY2VEdG8gPSB7XHJcbiAgICAgICAgcHJvamVjdElkOiAncHJvamVjdC11dWlkJyxcclxuICAgICAgICB0eXBlSWQ6IDEsXHJcbiAgICAgICAgc3ViamVjdDogJ1Rlc3QgU3ViamVjdCcsXHJcbiAgICAgICAgb3JpZ2luYXRvcklkOiAnb3JpZ2luYXRvci11dWlkJyxcclxuICAgICAgICByZWNpcGllbnRzOiBbeyBvcmdhbml6YXRpb25JZDogJ3JlY2lwaWVudC11dWlkJywgdHlwZTogJ1RPJyB9XSxcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGNvbnN0IHVzZXJTZXJ2aWNlID0gdGVzdGluZ01vZHVsZS5nZXQ8VXNlclNlcnZpY2U+KFVzZXJTZXJ2aWNlKTtcclxuICAgICAgY29uc3QgdHlwZVJlcG8gPSB0ZXN0aW5nTW9kdWxlLmdldDxSZXBvc2l0b3J5PENvcnJlc3BvbmRlbmNlVHlwZT4+KFxyXG4gICAgICAgIGdldFJlcG9zaXRvcnlUb2tlbihDb3JyZXNwb25kZW5jZVR5cGUpXHJcbiAgICAgICk7XHJcbiAgICAgIGNvbnN0IHN0YXR1c1JlcG8gPSB0ZXN0aW5nTW9kdWxlLmdldDxSZXBvc2l0b3J5PENvcnJlc3BvbmRlbmNlU3RhdHVzPj4oXHJcbiAgICAgICAgZ2V0UmVwb3NpdG9yeVRva2VuKENvcnJlc3BvbmRlbmNlU3RhdHVzKVxyXG4gICAgICApO1xyXG4gICAgICBjb25zdCB1dWlkUmVzb2x2ZXIgPVxyXG4gICAgICAgIHRlc3RpbmdNb2R1bGUuZ2V0PFV1aWRSZXNvbHZlclNlcnZpY2U+KFV1aWRSZXNvbHZlclNlcnZpY2UpO1xyXG5cclxuICAgICAgKHVzZXJTZXJ2aWNlLmZpbmRPbmUgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgdXNlcl9pZDogMSxcclxuICAgICAgICBwcmltYXJ5T3JnYW5pemF0aW9uSWQ6IG51bGwsXHJcbiAgICAgIH0pO1xyXG4gICAgICAodXNlclNlcnZpY2UuZ2V0VXNlclBlcm1pc3Npb25zIGFzIGplc3QuTW9jaykubW9ja1Jlc29sdmVkVmFsdWUoW1xyXG4gICAgICAgICdzeXN0ZW0ubWFuYWdlX2FsbCcsXHJcbiAgICAgIF0pO1xyXG5cclxuICAgICAgKHV1aWRSZXNvbHZlci5yZXNvbHZlUHJvamVjdElkIGFzIGplc3QuTW9jaykubW9ja1Jlc29sdmVkVmFsdWUoMTAwKTtcclxuICAgICAgKHV1aWRSZXNvbHZlci5yZXNvbHZlT3JnYW5pemF0aW9uSWQgYXMgamVzdC5Nb2NrKS5tb2NrSW1wbGVtZW50YXRpb24oXHJcbiAgICAgICAgKHZhbHVlOiBudW1iZXIgfCBzdHJpbmcpID0+IHtcclxuICAgICAgICAgIGlmICh2YWx1ZSA9PT0gJ29yaWdpbmF0b3ItdXVpZCcpIHJldHVybiAxMDtcclxuICAgICAgICAgIGlmICh2YWx1ZSA9PT0gJ3JlY2lwaWVudC11dWlkJykgcmV0dXJuIDIwO1xyXG4gICAgICAgICAgcmV0dXJuIDA7XHJcbiAgICAgICAgfVxyXG4gICAgICApO1xyXG5cclxuICAgICAgKHR5cGVSZXBvLmZpbmRPbmUgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgaWQ6IDEsXHJcbiAgICAgICAgdHlwZUNvZGU6ICdMVFInLFxyXG4gICAgICB9KTtcclxuICAgICAgKHN0YXR1c1JlcG8uZmluZE9uZSBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKHtcclxuICAgICAgICBpZDogMSxcclxuICAgICAgICBzdGF0dXNDb2RlOiAnRFJBRlQnLFxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIChudW1iZXJpbmdTZXJ2aWNlLmdlbmVyYXRlTmV4dE51bWJlciBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKHtcclxuICAgICAgICBudW1iZXI6ICdET0MtMDAxJyxcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBtb2NrRGF0YVNvdXJjZS5tYW5hZ2VyLmZpbmRPbmVcclxuICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKHsgaWQ6IDEwLCBvcmdhbml6YXRpb25Db2RlOiAnT1JHJyB9KVxyXG4gICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoeyBpZDogMjAsIG9yZ2FuaXphdGlvbkNvZGU6ICdSRUMnIH0pO1xyXG5cclxuICAgICAgY29uc3QgcXVlcnlSdW5uZXIgPSB7XHJcbiAgICAgICAgY29ubmVjdDogamVzdC5mbigpLFxyXG4gICAgICAgIHN0YXJ0VHJhbnNhY3Rpb246IGplc3QuZm4oKSxcclxuICAgICAgICBjb21taXRUcmFuc2FjdGlvbjogamVzdC5mbigpLFxyXG4gICAgICAgIHJvbGxiYWNrVHJhbnNhY3Rpb246IGplc3QuZm4oKSxcclxuICAgICAgICByZWxlYXNlOiBqZXN0LmZuKCksXHJcbiAgICAgICAgbWFuYWdlcjoge1xyXG4gICAgICAgICAgY3JlYXRlOiBqZXN0LmZuKFxyXG4gICAgICAgICAgICAoX2VudGl0eTogdW5rbm93biwgcGF5bG9hZDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IHBheWxvYWRcclxuICAgICAgICAgICksXHJcbiAgICAgICAgICBzYXZlOiBqZXN0XHJcbiAgICAgICAgICAgIC5mbigpXHJcbiAgICAgICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoeyBpZDogOTk5LCBwdWJsaWNJZDogJ2NvcnItdXVpZCcgfSlcclxuICAgICAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7IGlkOiAxMDAwIH0pXHJcbiAgICAgICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoW10pLFxyXG4gICAgICAgICAgZmluZE9uZTogamVzdC5mbigpLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH07XHJcblxyXG4gICAgICAobW9ja0RhdGFTb3VyY2UuY3JlYXRlUXVlcnlSdW5uZXIgYXMgamVzdC5Nb2NrKS5tb2NrUmV0dXJuVmFsdWUoXHJcbiAgICAgICAgcXVlcnlSdW5uZXJcclxuICAgICAgKTtcclxuXHJcbiAgICAgIGF3YWl0IHNlcnZpY2UuY3JlYXRlKGNyZWF0ZUR0bywgbW9ja1VzZXIpO1xyXG5cclxuICAgICAgZXhwZWN0KHF1ZXJ5UnVubmVyLm1hbmFnZXIuY3JlYXRlKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcclxuICAgICAgICBDb3JyZXNwb25kZW5jZSxcclxuICAgICAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7IG9yaWdpbmF0b3JJZDogMTAgfSlcclxuICAgICAgKTtcclxuICAgIH0pO1xyXG5cclxuICAgIGl0KCdzaG91bGQgc2V0IHJldmlzaW9uTGFiZWwgdG8gXCJBXCIgZm9yIFJGQSB0eXBlJywgYXN5bmMgKCkgPT4ge1xyXG4gICAgICBjb25zdCBtb2NrVXNlciA9IHtcclxuICAgICAgICB1c2VyX2lkOiAxLFxyXG4gICAgICAgIHByaW1hcnlPcmdhbml6YXRpb25JZDogMTAsXHJcbiAgICAgIH0gYXMgdW5rbm93biBhcyBVc2VyO1xyXG5cclxuICAgICAgY29uc3QgY3JlYXRlRHRvOiBDcmVhdGVDb3JyZXNwb25kZW5jZUR0byA9IHtcclxuICAgICAgICBwcm9qZWN0SWQ6ICdwcm9qZWN0LXV1aWQnLFxyXG4gICAgICAgIHR5cGVJZDogMSxcclxuICAgICAgICBzdWJqZWN0OiAnVGVzdCBTdWJqZWN0JyxcclxuICAgICAgICByZWNpcGllbnRzOiBbeyBvcmdhbml6YXRpb25JZDogJ3JlY2lwaWVudC11dWlkJywgdHlwZTogJ1RPJyB9XSxcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGNvbnN0IHR5cGVSZXBvID0gdGVzdGluZ01vZHVsZS5nZXQ8UmVwb3NpdG9yeTxDb3JyZXNwb25kZW5jZVR5cGU+PihcclxuICAgICAgICBnZXRSZXBvc2l0b3J5VG9rZW4oQ29ycmVzcG9uZGVuY2VUeXBlKVxyXG4gICAgICApO1xyXG4gICAgICBjb25zdCBzdGF0dXNSZXBvID0gdGVzdGluZ01vZHVsZS5nZXQ8UmVwb3NpdG9yeTxDb3JyZXNwb25kZW5jZVN0YXR1cz4+KFxyXG4gICAgICAgIGdldFJlcG9zaXRvcnlUb2tlbihDb3JyZXNwb25kZW5jZVN0YXR1cylcclxuICAgICAgKTtcclxuICAgICAgY29uc3QgdXVpZFJlc29sdmVyID1cclxuICAgICAgICB0ZXN0aW5nTW9kdWxlLmdldDxVdWlkUmVzb2x2ZXJTZXJ2aWNlPihVdWlkUmVzb2x2ZXJTZXJ2aWNlKTtcclxuXHJcbiAgICAgICh1dWlkUmVzb2x2ZXIucmVzb2x2ZVByb2plY3RJZCBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKDEwMCk7XHJcbiAgICAgICh1dWlkUmVzb2x2ZXIucmVzb2x2ZU9yZ2FuaXphdGlvbklkIGFzIGplc3QuTW9jaykubW9ja1Jlc29sdmVkVmFsdWUoMjApO1xyXG5cclxuICAgICAgKHR5cGVSZXBvLmZpbmRPbmUgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgaWQ6IDEsXHJcbiAgICAgICAgdHlwZUNvZGU6ICdSRkEnLFxyXG4gICAgICB9KTtcclxuICAgICAgKHN0YXR1c1JlcG8uZmluZE9uZSBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKHtcclxuICAgICAgICBpZDogMSxcclxuICAgICAgICBzdGF0dXNDb2RlOiAnRFJBRlQnLFxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIChudW1iZXJpbmdTZXJ2aWNlLmdlbmVyYXRlTmV4dE51bWJlciBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKHtcclxuICAgICAgICBudW1iZXI6ICdET0MtMDAxJyxcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBtb2NrRGF0YVNvdXJjZS5tYW5hZ2VyLmZpbmRPbmVcclxuICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKHsgaWQ6IDEwLCBvcmdhbml6YXRpb25Db2RlOiAnT1JHJyB9KVxyXG4gICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoeyBpZDogMjAsIG9yZ2FuaXphdGlvbkNvZGU6ICdSRUMnIH0pO1xyXG5cclxuICAgICAgY29uc3QgcXVlcnlSdW5uZXIgPSB7XHJcbiAgICAgICAgY29ubmVjdDogamVzdC5mbigpLFxyXG4gICAgICAgIHN0YXJ0VHJhbnNhY3Rpb246IGplc3QuZm4oKSxcclxuICAgICAgICBjb21taXRUcmFuc2FjdGlvbjogamVzdC5mbigpLFxyXG4gICAgICAgIHJvbGxiYWNrVHJhbnNhY3Rpb246IGplc3QuZm4oKSxcclxuICAgICAgICByZWxlYXNlOiBqZXN0LmZuKCksXHJcbiAgICAgICAgbWFuYWdlcjoge1xyXG4gICAgICAgICAgY3JlYXRlOiBqZXN0LmZuKFxyXG4gICAgICAgICAgICAoX2VudGl0eTogdW5rbm93biwgcGF5bG9hZDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IHBheWxvYWRcclxuICAgICAgICAgICksXHJcbiAgICAgICAgICBzYXZlOiBqZXN0XHJcbiAgICAgICAgICAgIC5mbigpXHJcbiAgICAgICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoeyBpZDogOTk5LCBwdWJsaWNJZDogJ2NvcnItdXVpZCcgfSlcclxuICAgICAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7IGlkOiAxMDAwIH0pXHJcbiAgICAgICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoW10pLFxyXG4gICAgICAgICAgZmluZE9uZTogamVzdC5mbigpLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH07XHJcblxyXG4gICAgICAobW9ja0RhdGFTb3VyY2UuY3JlYXRlUXVlcnlSdW5uZXIgYXMgamVzdC5Nb2NrKS5tb2NrUmV0dXJuVmFsdWUoXHJcbiAgICAgICAgcXVlcnlSdW5uZXJcclxuICAgICAgKTtcclxuXHJcbiAgICAgIGF3YWl0IHNlcnZpY2UuY3JlYXRlKGNyZWF0ZUR0bywgbW9ja1VzZXIpO1xyXG5cclxuICAgICAgZXhwZWN0KHF1ZXJ5UnVubmVyLm1hbmFnZXIuY3JlYXRlKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcclxuICAgICAgICBDb3JyZXNwb25kZW5jZVJldmlzaW9uLFxyXG4gICAgICAgIGV4cGVjdC5vYmplY3RDb250YWluaW5nKHsgcmV2aXNpb25MYWJlbDogJ0EnIH0pXHJcbiAgICAgICk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBpdCgnc2hvdWxkIHNldCByZXZpc2lvbkxhYmVsIHRvIFwiQVwiIGZvciBSRkkgdHlwZScsIGFzeW5jICgpID0+IHtcclxuICAgICAgY29uc3QgbW9ja1VzZXIgPSB7XHJcbiAgICAgICAgdXNlcl9pZDogMSxcclxuICAgICAgICBwcmltYXJ5T3JnYW5pemF0aW9uSWQ6IDEwLFxyXG4gICAgICB9IGFzIHVua25vd24gYXMgVXNlcjtcclxuXHJcbiAgICAgIGNvbnN0IGNyZWF0ZUR0bzogQ3JlYXRlQ29ycmVzcG9uZGVuY2VEdG8gPSB7XHJcbiAgICAgICAgcHJvamVjdElkOiAncHJvamVjdC11dWlkJyxcclxuICAgICAgICB0eXBlSWQ6IDEsXHJcbiAgICAgICAgc3ViamVjdDogJ1Rlc3QgU3ViamVjdCcsXHJcbiAgICAgICAgcmVjaXBpZW50czogW3sgb3JnYW5pemF0aW9uSWQ6ICdyZWNpcGllbnQtdXVpZCcsIHR5cGU6ICdUTycgfV0sXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBjb25zdCB0eXBlUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2VUeXBlPj4oXHJcbiAgICAgICAgZ2V0UmVwb3NpdG9yeVRva2VuKENvcnJlc3BvbmRlbmNlVHlwZSlcclxuICAgICAgKTtcclxuICAgICAgY29uc3Qgc3RhdHVzUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2VTdGF0dXM+PihcclxuICAgICAgICBnZXRSZXBvc2l0b3J5VG9rZW4oQ29ycmVzcG9uZGVuY2VTdGF0dXMpXHJcbiAgICAgICk7XHJcbiAgICAgIGNvbnN0IHV1aWRSZXNvbHZlciA9XHJcbiAgICAgICAgdGVzdGluZ01vZHVsZS5nZXQ8VXVpZFJlc29sdmVyU2VydmljZT4oVXVpZFJlc29sdmVyU2VydmljZSk7XHJcblxyXG4gICAgICAodXVpZFJlc29sdmVyLnJlc29sdmVQcm9qZWN0SWQgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSgxMDApO1xyXG4gICAgICAodXVpZFJlc29sdmVyLnJlc29sdmVPcmdhbml6YXRpb25JZCBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKDIwKTtcclxuXHJcbiAgICAgICh0eXBlUmVwby5maW5kT25lIGFzIGplc3QuTW9jaykubW9ja1Jlc29sdmVkVmFsdWUoe1xyXG4gICAgICAgIGlkOiAxLFxyXG4gICAgICAgIHR5cGVDb2RlOiAnUkZJJyxcclxuICAgICAgfSk7XHJcbiAgICAgIChzdGF0dXNSZXBvLmZpbmRPbmUgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgaWQ6IDEsXHJcbiAgICAgICAgc3RhdHVzQ29kZTogJ0RSQUZUJyxcclxuICAgICAgfSk7XHJcblxyXG4gICAgICAobnVtYmVyaW5nU2VydmljZS5nZW5lcmF0ZU5leHROdW1iZXIgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgbnVtYmVyOiAnRE9DLTAwMScsXHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgbW9ja0RhdGFTb3VyY2UubWFuYWdlci5maW5kT25lXHJcbiAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7IGlkOiAxMCwgb3JnYW5pemF0aW9uQ29kZTogJ09SRycgfSlcclxuICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKHsgaWQ6IDIwLCBvcmdhbml6YXRpb25Db2RlOiAnUkVDJyB9KTtcclxuXHJcbiAgICAgIGNvbnN0IHF1ZXJ5UnVubmVyID0ge1xyXG4gICAgICAgIGNvbm5lY3Q6IGplc3QuZm4oKSxcclxuICAgICAgICBzdGFydFRyYW5zYWN0aW9uOiBqZXN0LmZuKCksXHJcbiAgICAgICAgY29tbWl0VHJhbnNhY3Rpb246IGplc3QuZm4oKSxcclxuICAgICAgICByb2xsYmFja1RyYW5zYWN0aW9uOiBqZXN0LmZuKCksXHJcbiAgICAgICAgcmVsZWFzZTogamVzdC5mbigpLFxyXG4gICAgICAgIG1hbmFnZXI6IHtcclxuICAgICAgICAgIGNyZWF0ZTogamVzdC5mbihcclxuICAgICAgICAgICAgKF9lbnRpdHk6IHVua25vd24sIHBheWxvYWQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PiBwYXlsb2FkXHJcbiAgICAgICAgICApLFxyXG4gICAgICAgICAgc2F2ZTogamVzdFxyXG4gICAgICAgICAgICAuZm4oKVxyXG4gICAgICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKHsgaWQ6IDk5OSwgcHVibGljSWQ6ICdjb3JyLXV1aWQnIH0pXHJcbiAgICAgICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoeyBpZDogMTAwMCB9KVxyXG4gICAgICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKFtdKSxcclxuICAgICAgICAgIGZpbmRPbmU6IGplc3QuZm4oKSxcclxuICAgICAgICB9LFxyXG4gICAgICB9O1xyXG5cclxuICAgICAgKG1vY2tEYXRhU291cmNlLmNyZWF0ZVF1ZXJ5UnVubmVyIGFzIGplc3QuTW9jaykubW9ja1JldHVyblZhbHVlKFxyXG4gICAgICAgIHF1ZXJ5UnVubmVyXHJcbiAgICAgICk7XHJcblxyXG4gICAgICBhd2FpdCBzZXJ2aWNlLmNyZWF0ZShjcmVhdGVEdG8sIG1vY2tVc2VyKTtcclxuXHJcbiAgICAgIGV4cGVjdChxdWVyeVJ1bm5lci5tYW5hZ2VyLmNyZWF0ZSkudG9IYXZlQmVlbkNhbGxlZFdpdGgoXHJcbiAgICAgICAgQ29ycmVzcG9uZGVuY2VSZXZpc2lvbixcclxuICAgICAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7IHJldmlzaW9uTGFiZWw6ICdBJyB9KVxyXG4gICAgICApO1xyXG4gICAgfSk7XHJcblxyXG4gICAgaXQoJ3Nob3VsZCBzZXQgcmV2aXNpb25MYWJlbCB0byBudWxsIGZvciBMRVRURVIgdHlwZScsIGFzeW5jICgpID0+IHtcclxuICAgICAgY29uc3QgbW9ja1VzZXIgPSB7XHJcbiAgICAgICAgdXNlcl9pZDogMSxcclxuICAgICAgICBwcmltYXJ5T3JnYW5pemF0aW9uSWQ6IDEwLFxyXG4gICAgICB9IGFzIHVua25vd24gYXMgVXNlcjtcclxuXHJcbiAgICAgIGNvbnN0IGNyZWF0ZUR0bzogQ3JlYXRlQ29ycmVzcG9uZGVuY2VEdG8gPSB7XHJcbiAgICAgICAgcHJvamVjdElkOiAncHJvamVjdC11dWlkJyxcclxuICAgICAgICB0eXBlSWQ6IDEsXHJcbiAgICAgICAgc3ViamVjdDogJ1Rlc3QgU3ViamVjdCcsXHJcbiAgICAgICAgcmVjaXBpZW50czogW3sgb3JnYW5pemF0aW9uSWQ6ICdyZWNpcGllbnQtdXVpZCcsIHR5cGU6ICdUTycgfV0sXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBjb25zdCB0eXBlUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2VUeXBlPj4oXHJcbiAgICAgICAgZ2V0UmVwb3NpdG9yeVRva2VuKENvcnJlc3BvbmRlbmNlVHlwZSlcclxuICAgICAgKTtcclxuICAgICAgY29uc3Qgc3RhdHVzUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2VTdGF0dXM+PihcclxuICAgICAgICBnZXRSZXBvc2l0b3J5VG9rZW4oQ29ycmVzcG9uZGVuY2VTdGF0dXMpXHJcbiAgICAgICk7XHJcbiAgICAgIGNvbnN0IHV1aWRSZXNvbHZlciA9XHJcbiAgICAgICAgdGVzdGluZ01vZHVsZS5nZXQ8VXVpZFJlc29sdmVyU2VydmljZT4oVXVpZFJlc29sdmVyU2VydmljZSk7XHJcblxyXG4gICAgICAodXVpZFJlc29sdmVyLnJlc29sdmVQcm9qZWN0SWQgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSgxMDApO1xyXG4gICAgICAodXVpZFJlc29sdmVyLnJlc29sdmVPcmdhbml6YXRpb25JZCBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKDIwKTtcclxuXHJcbiAgICAgICh0eXBlUmVwby5maW5kT25lIGFzIGplc3QuTW9jaykubW9ja1Jlc29sdmVkVmFsdWUoe1xyXG4gICAgICAgIGlkOiAxLFxyXG4gICAgICAgIHR5cGVDb2RlOiAnTEVUVEVSJyxcclxuICAgICAgfSk7XHJcbiAgICAgIChzdGF0dXNSZXBvLmZpbmRPbmUgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgaWQ6IDEsXHJcbiAgICAgICAgc3RhdHVzQ29kZTogJ0RSQUZUJyxcclxuICAgICAgfSk7XHJcblxyXG4gICAgICAobnVtYmVyaW5nU2VydmljZS5nZW5lcmF0ZU5leHROdW1iZXIgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgbnVtYmVyOiAnRE9DLTAwMScsXHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgbW9ja0RhdGFTb3VyY2UubWFuYWdlci5maW5kT25lXHJcbiAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7IGlkOiAxMCwgb3JnYW5pemF0aW9uQ29kZTogJ09SRycgfSlcclxuICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKHsgaWQ6IDIwLCBvcmdhbml6YXRpb25Db2RlOiAnUkVDJyB9KTtcclxuXHJcbiAgICAgIGNvbnN0IHF1ZXJ5UnVubmVyID0ge1xyXG4gICAgICAgIGNvbm5lY3Q6IGplc3QuZm4oKSxcclxuICAgICAgICBzdGFydFRyYW5zYWN0aW9uOiBqZXN0LmZuKCksXHJcbiAgICAgICAgY29tbWl0VHJhbnNhY3Rpb246IGplc3QuZm4oKSxcclxuICAgICAgICByb2xsYmFja1RyYW5zYWN0aW9uOiBqZXN0LmZuKCksXHJcbiAgICAgICAgcmVsZWFzZTogamVzdC5mbigpLFxyXG4gICAgICAgIG1hbmFnZXI6IHtcclxuICAgICAgICAgIGNyZWF0ZTogamVzdC5mbihcclxuICAgICAgICAgICAgKF9lbnRpdHk6IHVua25vd24sIHBheWxvYWQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PiBwYXlsb2FkXHJcbiAgICAgICAgICApLFxyXG4gICAgICAgICAgc2F2ZTogamVzdFxyXG4gICAgICAgICAgICAuZm4oKVxyXG4gICAgICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKHsgaWQ6IDk5OSwgcHVibGljSWQ6ICdjb3JyLXV1aWQnIH0pXHJcbiAgICAgICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoeyBpZDogMTAwMCB9KVxyXG4gICAgICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKFtdKSxcclxuICAgICAgICAgIGZpbmRPbmU6IGplc3QuZm4oKSxcclxuICAgICAgICB9LFxyXG4gICAgICB9O1xyXG5cclxuICAgICAgKG1vY2tEYXRhU291cmNlLmNyZWF0ZVF1ZXJ5UnVubmVyIGFzIGplc3QuTW9jaykubW9ja1JldHVyblZhbHVlKFxyXG4gICAgICAgIHF1ZXJ5UnVubmVyXHJcbiAgICAgICk7XHJcblxyXG4gICAgICBhd2FpdCBzZXJ2aWNlLmNyZWF0ZShjcmVhdGVEdG8sIG1vY2tVc2VyKTtcclxuXHJcbiAgICAgIGV4cGVjdChxdWVyeVJ1bm5lci5tYW5hZ2VyLmNyZWF0ZSkudG9IYXZlQmVlbkNhbGxlZFdpdGgoXHJcbiAgICAgICAgQ29ycmVzcG9uZGVuY2VSZXZpc2lvbixcclxuICAgICAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7IHJldmlzaW9uTGFiZWw6IHVuZGVmaW5lZCB9KVxyXG4gICAgICApO1xyXG4gICAgfSk7XHJcblxyXG4gICAgaXQoJ3Nob3VsZCBzZXQgcmV2aXNpb25MYWJlbCB0byB1bmRlZmluZWQgZm9yIE1FTU8gdHlwZScsIGFzeW5jICgpID0+IHtcclxuICAgICAgY29uc3QgbW9ja1VzZXIgPSB7XHJcbiAgICAgICAgdXNlcl9pZDogMSxcclxuICAgICAgICBwcmltYXJ5T3JnYW5pemF0aW9uSWQ6IDEwLFxyXG4gICAgICB9IGFzIHVua25vd24gYXMgVXNlcjtcclxuXHJcbiAgICAgIGNvbnN0IGNyZWF0ZUR0bzogQ3JlYXRlQ29ycmVzcG9uZGVuY2VEdG8gPSB7XHJcbiAgICAgICAgcHJvamVjdElkOiAncHJvamVjdC11dWlkJyxcclxuICAgICAgICB0eXBlSWQ6IDEsXHJcbiAgICAgICAgc3ViamVjdDogJ1Rlc3QgU3ViamVjdCcsXHJcbiAgICAgICAgcmVjaXBpZW50czogW3sgb3JnYW5pemF0aW9uSWQ6ICdyZWNpcGllbnQtdXVpZCcsIHR5cGU6ICdUTycgfV0sXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBjb25zdCB0eXBlUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2VUeXBlPj4oXHJcbiAgICAgICAgZ2V0UmVwb3NpdG9yeVRva2VuKENvcnJlc3BvbmRlbmNlVHlwZSlcclxuICAgICAgKTtcclxuICAgICAgY29uc3Qgc3RhdHVzUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2VTdGF0dXM+PihcclxuICAgICAgICBnZXRSZXBvc2l0b3J5VG9rZW4oQ29ycmVzcG9uZGVuY2VTdGF0dXMpXHJcbiAgICAgICk7XHJcbiAgICAgIGNvbnN0IHV1aWRSZXNvbHZlciA9XHJcbiAgICAgICAgdGVzdGluZ01vZHVsZS5nZXQ8VXVpZFJlc29sdmVyU2VydmljZT4oVXVpZFJlc29sdmVyU2VydmljZSk7XHJcblxyXG4gICAgICAodXVpZFJlc29sdmVyLnJlc29sdmVQcm9qZWN0SWQgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSgxMDApO1xyXG4gICAgICAodXVpZFJlc29sdmVyLnJlc29sdmVPcmdhbml6YXRpb25JZCBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKDIwKTtcclxuXHJcbiAgICAgICh0eXBlUmVwby5maW5kT25lIGFzIGplc3QuTW9jaykubW9ja1Jlc29sdmVkVmFsdWUoe1xyXG4gICAgICAgIGlkOiAxLFxyXG4gICAgICAgIHR5cGVDb2RlOiAnTUVNTycsXHJcbiAgICAgIH0pO1xyXG4gICAgICAoc3RhdHVzUmVwby5maW5kT25lIGFzIGplc3QuTW9jaykubW9ja1Jlc29sdmVkVmFsdWUoe1xyXG4gICAgICAgIGlkOiAxLFxyXG4gICAgICAgIHN0YXR1c0NvZGU6ICdEUkFGVCcsXHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgKG51bWJlcmluZ1NlcnZpY2UuZ2VuZXJhdGVOZXh0TnVtYmVyIGFzIGplc3QuTW9jaykubW9ja1Jlc29sdmVkVmFsdWUoe1xyXG4gICAgICAgIG51bWJlcjogJ0RPQy0wMDEnLFxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIG1vY2tEYXRhU291cmNlLm1hbmFnZXIuZmluZE9uZVxyXG4gICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoeyBpZDogMTAsIG9yZ2FuaXphdGlvbkNvZGU6ICdPUkcnIH0pXHJcbiAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7IGlkOiAyMCwgb3JnYW5pemF0aW9uQ29kZTogJ1JFQycgfSk7XHJcblxyXG4gICAgICBjb25zdCBxdWVyeVJ1bm5lciA9IHtcclxuICAgICAgICBjb25uZWN0OiBqZXN0LmZuKCksXHJcbiAgICAgICAgc3RhcnRUcmFuc2FjdGlvbjogamVzdC5mbigpLFxyXG4gICAgICAgIGNvbW1pdFRyYW5zYWN0aW9uOiBqZXN0LmZuKCksXHJcbiAgICAgICAgcm9sbGJhY2tUcmFuc2FjdGlvbjogamVzdC5mbigpLFxyXG4gICAgICAgIHJlbGVhc2U6IGplc3QuZm4oKSxcclxuICAgICAgICBtYW5hZ2VyOiB7XHJcbiAgICAgICAgICBjcmVhdGU6IGplc3QuZm4oXHJcbiAgICAgICAgICAgIChfZW50aXR5OiB1bmtub3duLCBwYXlsb2FkOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgPT4gcGF5bG9hZFxyXG4gICAgICAgICAgKSxcclxuICAgICAgICAgIHNhdmU6IGplc3RcclxuICAgICAgICAgICAgLmZuKClcclxuICAgICAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7IGlkOiA5OTksIHB1YmxpY0lkOiAnY29yci11dWlkJyB9KVxyXG4gICAgICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKHsgaWQ6IDEwMDAgfSlcclxuICAgICAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlT25jZShbXSksXHJcbiAgICAgICAgICBmaW5kT25lOiBqZXN0LmZuKCksXHJcbiAgICAgICAgfSxcclxuICAgICAgfTtcclxuXHJcbiAgICAgIChtb2NrRGF0YVNvdXJjZS5jcmVhdGVRdWVyeVJ1bm5lciBhcyBqZXN0Lk1vY2spLm1vY2tSZXR1cm5WYWx1ZShcclxuICAgICAgICBxdWVyeVJ1bm5lclxyXG4gICAgICApO1xyXG5cclxuICAgICAgYXdhaXQgc2VydmljZS5jcmVhdGUoY3JlYXRlRHRvLCBtb2NrVXNlcik7XHJcblxyXG4gICAgICBleHBlY3QocXVlcnlSdW5uZXIubWFuYWdlci5jcmVhdGUpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxyXG4gICAgICAgIENvcnJlc3BvbmRlbmNlUmV2aXNpb24sXHJcbiAgICAgICAgZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoeyByZXZpc2lvbkxhYmVsOiB1bmRlZmluZWQgfSlcclxuICAgICAgKTtcclxuICAgIH0pO1xyXG4gIH0pO1xyXG59KTtcclxuIl0sInZlcnNpb24iOjN9 \ No newline at end of file diff --git a/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/6f/correspondenceservicespec_6f5b0f75b3fc4347fc2d2eb89f0249fa.map b/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/6f/correspondenceservicespec_6f5b0f75b3fc4347fc2d2eb89f0249fa.map new file mode 100644 index 0000000..d714fc1 --- /dev/null +++ b/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/6f/correspondenceservicespec_6f5b0f75b3fc4347fc2d2eb89f0249fa.map @@ -0,0 +1 @@ +{"file":"E:\\np-dms\\lcbp3\\backend\\src\\modules\\correspondence\\correspondence.service.spec.ts","mappings":"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","names":[],"sources":["E:\\np-dms\\lcbp3\\backend\\src\\modules\\correspondence\\correspondence.service.spec.ts"],"sourcesContent":["import { Test, TestingModule } from '@nestjs/testing';\r\nimport { getRepositoryToken } from '@nestjs/typeorm';\r\nimport { DataSource, Repository } from 'typeorm';\r\nimport { CorrespondenceService } from './correspondence.service';\r\nimport { Correspondence } from './entities/correspondence.entity';\r\nimport { CorrespondenceRevision } from './entities/correspondence-revision.entity';\r\nimport { CorrespondenceType } from './entities/correspondence-type.entity';\r\nimport { CorrespondenceStatus } from './entities/correspondence-status.entity';\r\nimport { CorrespondenceReference } from './entities/correspondence-reference.entity';\r\nimport { CorrespondenceTag } from './entities/correspondence-tag.entity';\r\nimport { Organization } from '../organization/entities/organization.entity';\r\nimport { CorrespondenceRecipient } from './entities/correspondence-recipient.entity';\r\nimport { DocumentNumberingService } from '../document-numbering/services/document-numbering.service';\r\nimport { JsonSchemaService } from '../json-schema/json-schema.service';\r\nimport { WorkflowEngineService } from '../workflow-engine/workflow-engine.service';\r\nimport { UserService } from '../user/user.service';\r\nimport { SearchService } from '../search/search.service';\r\nimport { FileStorageService } from '../../common/file-storage/file-storage.service';\r\nimport { UuidResolverService } from '../../common/services/uuid-resolver.service';\r\nimport { NotificationService } from '../notification/notification.service';\r\nimport { UpdateCorrespondenceDto } from './dto/update-correspondence.dto';\r\nimport { CreateCorrespondenceDto } from './dto/create-correspondence.dto';\r\nimport { User } from '../user/entities/user.entity';\r\n\r\ndescribe('CorrespondenceService', () => {\r\n let service: CorrespondenceService;\r\n let numberingService: DocumentNumberingService;\r\n let correspondenceRepo: Repository;\r\n let revisionRepo: Repository;\r\n let testingModule: TestingModule;\r\n let _dataSource: DataSource;\r\n\r\n const createMockRepository = () => ({\r\n find: jest.fn(),\r\n findOne: jest.fn(),\r\n create: jest.fn(),\r\n save: jest.fn(),\r\n update: jest.fn(),\r\n delete: jest.fn(),\r\n softDelete: jest.fn(),\r\n createQueryBuilder: jest.fn(() => ({\r\n leftJoinAndSelect: jest.fn().mockReturnThis(),\r\n where: jest.fn().mockReturnThis(),\r\n andWhere: jest.fn().mockReturnThis(),\r\n orderBy: jest.fn().mockReturnThis(),\r\n skip: jest.fn().mockReturnThis(),\r\n take: jest.fn().mockReturnThis(),\r\n getOne: jest.fn().mockResolvedValue(null),\r\n getMany: jest.fn().mockResolvedValue([]),\r\n getManyAndCount: jest.fn().mockResolvedValue([[], 0]),\r\n })),\r\n });\r\n\r\n const mockDataSource = {\r\n createQueryRunner: jest.fn(() => ({\r\n connect: jest.fn(),\r\n startTransaction: jest.fn(),\r\n commitTransaction: jest.fn(),\r\n rollbackTransaction: jest.fn(),\r\n release: jest.fn(),\r\n manager: {\r\n create: jest.fn(),\r\n save: jest.fn(),\r\n findOne: jest.fn(),\r\n },\r\n })),\r\n getRepository: jest.fn(() => createMockRepository()),\r\n manager: {\r\n findOne: jest.fn(),\r\n },\r\n };\r\n\r\n beforeEach(async () => {\r\n testingModule = await Test.createTestingModule({\r\n providers: [\r\n CorrespondenceService,\r\n {\r\n provide: getRepositoryToken(Correspondence),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: getRepositoryToken(CorrespondenceRevision),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: getRepositoryToken(CorrespondenceType),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: getRepositoryToken(CorrespondenceStatus),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: getRepositoryToken(CorrespondenceReference),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: getRepositoryToken(CorrespondenceTag),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: getRepositoryToken(Organization),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: getRepositoryToken(CorrespondenceRecipient),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: DocumentNumberingService,\r\n useValue: {\r\n generateNextNumber: jest.fn(),\r\n updateNumberForDraft: jest.fn(),\r\n previewNextNumber: jest.fn(),\r\n },\r\n },\r\n {\r\n provide: JsonSchemaService,\r\n useValue: { validate: jest.fn() },\r\n },\r\n {\r\n provide: WorkflowEngineService,\r\n useValue: { createInstance: jest.fn() },\r\n },\r\n {\r\n provide: UserService,\r\n useValue: {\r\n findOne: jest.fn(),\r\n getUserPermissions: jest.fn().mockResolvedValue([]),\r\n },\r\n },\r\n {\r\n provide: DataSource,\r\n useValue: mockDataSource,\r\n },\r\n {\r\n provide: SearchService,\r\n useValue: { indexDocument: jest.fn() },\r\n },\r\n {\r\n provide: FileStorageService,\r\n useValue: { commit: jest.fn().mockResolvedValue([]) },\r\n },\r\n {\r\n provide: UuidResolverService,\r\n useValue: {\r\n resolveProjectId: jest.fn().mockResolvedValue(1),\r\n resolveOrganizationId: jest.fn().mockResolvedValue(1),\r\n },\r\n },\r\n {\r\n provide: NotificationService,\r\n useValue: { send: jest.fn().mockResolvedValue(undefined) },\r\n },\r\n ],\r\n }).compile();\r\n\r\n service = testingModule.get(CorrespondenceService);\r\n numberingService = testingModule.get(\r\n DocumentNumberingService\r\n );\r\n correspondenceRepo = testingModule.get>(\r\n getRepositoryToken(Correspondence)\r\n );\r\n revisionRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceRevision)\r\n );\r\n _dataSource = testingModule.get(DataSource);\r\n });\r\n\r\n it('should be defined', () => {\r\n expect(service).toBeDefined();\r\n });\r\n\r\n describe('update', () => {\r\n it('should NOT regenerate number if critical fields unchanged', async () => {\r\n const mockUser = { id: 1, primaryOrganizationId: 10 } as unknown as User;\r\n const mockRevision = {\r\n id: 100,\r\n correspondenceId: 1,\r\n isCurrent: true,\r\n statusId: 5,\r\n };\r\n\r\n jest\r\n .spyOn(revisionRepo, 'findOne')\r\n .mockResolvedValue(mockRevision as unknown as CorrespondenceRevision);\r\n\r\n const mockCorr = {\r\n id: 1,\r\n projectId: 1,\r\n correspondenceTypeId: 2,\r\n disciplineId: 3,\r\n originatorId: 10,\r\n correspondenceNumber: 'OLD-NUM',\r\n recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }],\r\n };\r\n jest\r\n .spyOn(correspondenceRepo, 'findOne')\r\n .mockResolvedValue(mockCorr as unknown as Correspondence);\r\n\r\n const updateDto: UpdateCorrespondenceDto = {\r\n projectId: 1,\r\n disciplineId: 3,\r\n };\r\n\r\n await service.update(1, updateDto, mockUser);\r\n\r\n expect(\r\n numberingService.updateNumberForDraft as jest.Mock\r\n ).not.toHaveBeenCalled();\r\n });\r\n\r\n it('should regenerate number if Project ID changes', async () => {\r\n const mockUser = { id: 1, primaryOrganizationId: 10 } as unknown as User;\r\n const mockRevision = {\r\n id: 100,\r\n correspondenceId: 1,\r\n isCurrent: true,\r\n statusId: 5,\r\n };\r\n jest\r\n .spyOn(revisionRepo, 'findOne')\r\n .mockResolvedValue(mockRevision as unknown as CorrespondenceRevision);\r\n\r\n const mockCorr = {\r\n id: 1,\r\n projectId: 1,\r\n correspondenceTypeId: 2,\r\n disciplineId: 3,\r\n originatorId: 10,\r\n correspondenceNumber: 'OLD-NUM',\r\n recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }],\r\n };\r\n jest\r\n .spyOn(correspondenceRepo, 'findOne')\r\n .mockResolvedValue(mockCorr as unknown as Correspondence);\r\n\r\n const updateDto: UpdateCorrespondenceDto = {\r\n projectId: 2,\r\n };\r\n\r\n const uuidResolver =\r\n testingModule.get(UuidResolverService);\r\n (uuidResolver.resolveProjectId as jest.Mock).mockResolvedValue(2);\r\n\r\n await service.update(1, updateDto, mockUser);\r\n\r\n expect(\r\n numberingService.updateNumberForDraft as jest.Mock\r\n ).toHaveBeenCalled();\r\n });\r\n\r\n it('should regenerate number if Document Type changes', async () => {\r\n const mockUser = { id: 1, primaryOrganizationId: 10 } as unknown as User;\r\n const mockRevision = {\r\n id: 100,\r\n correspondenceId: 1,\r\n isCurrent: true,\r\n statusId: 5,\r\n };\r\n jest\r\n .spyOn(revisionRepo, 'findOne')\r\n .mockResolvedValue(mockRevision as unknown as CorrespondenceRevision);\r\n\r\n const mockCorr = {\r\n id: 1,\r\n projectId: 1,\r\n correspondenceTypeId: 2,\r\n disciplineId: 3,\r\n originatorId: 10,\r\n correspondenceNumber: 'OLD-NUM',\r\n recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }],\r\n };\r\n jest\r\n .spyOn(correspondenceRepo, 'findOne')\r\n .mockResolvedValue(mockCorr as unknown as Correspondence);\r\n\r\n const updateDto: UpdateCorrespondenceDto = {\r\n typeId: 999,\r\n };\r\n\r\n const typeRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceType)\r\n );\r\n (typeRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 999,\r\n typeCode: 'NEW-TYPE',\r\n });\r\n\r\n await service.update(1, updateDto, mockUser);\r\n\r\n expect(\r\n numberingService.updateNumberForDraft as jest.Mock\r\n ).toHaveBeenCalled();\r\n });\r\n\r\n it('should regenerate number if Recipient Organization changes', async () => {\r\n const mockUser = { id: 1, primaryOrganizationId: 10 } as unknown as User;\r\n const mockRevision = {\r\n id: 100,\r\n correspondenceId: 1,\r\n isCurrent: true,\r\n statusId: 5,\r\n };\r\n jest\r\n .spyOn(revisionRepo, 'findOne')\r\n .mockResolvedValue(mockRevision as unknown as CorrespondenceRevision);\r\n\r\n const mockCorr = {\r\n id: 1,\r\n projectId: 1,\r\n correspondenceTypeId: 2,\r\n disciplineId: 3,\r\n originatorId: 10,\r\n correspondenceNumber: 'OLD-NUM',\r\n recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }],\r\n };\r\n jest\r\n .spyOn(correspondenceRepo, 'findOne')\r\n .mockResolvedValue(mockCorr as unknown as Correspondence);\r\n\r\n // Access DataSource manager for mocking\r\n mockDataSource.manager.findOne.mockResolvedValue({\r\n id: 88,\r\n organizationCode: 'NEW-ORG',\r\n } as unknown as Organization);\r\n\r\n const updateDto: UpdateCorrespondenceDto = {\r\n recipients: [{ type: 'TO', organizationId: 88 }],\r\n };\r\n\r\n await service.update(1, updateDto, mockUser);\r\n\r\n expect(\r\n numberingService.updateNumberForDraft as jest.Mock\r\n ).toHaveBeenCalled();\r\n });\r\n });\r\n\r\n describe('create', () => {\r\n it('should allow system.manage_all user without primaryOrganizationId when originatorId is provided', async () => {\r\n const mockUser = {\r\n user_id: 1,\r\n primaryOrganizationId: null,\r\n } as unknown as User;\r\n\r\n const createDto: CreateCorrespondenceDto = {\r\n projectId: 'project-uuid',\r\n typeId: 1,\r\n subject: 'Test Subject',\r\n originatorId: 'originator-uuid',\r\n recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }],\r\n };\r\n\r\n const userService = testingModule.get(UserService);\r\n const typeRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceType)\r\n );\r\n const statusRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceStatus)\r\n );\r\n const uuidResolver =\r\n testingModule.get(UuidResolverService);\r\n\r\n (userService.findOne as jest.Mock).mockResolvedValue({\r\n user_id: 1,\r\n primaryOrganizationId: null,\r\n });\r\n (userService.getUserPermissions as jest.Mock).mockResolvedValue([\r\n 'system.manage_all',\r\n ]);\r\n\r\n (uuidResolver.resolveProjectId as jest.Mock).mockResolvedValue(100);\r\n (uuidResolver.resolveOrganizationId as jest.Mock).mockImplementation(\r\n (value: number | string) => {\r\n if (value === 'originator-uuid') return 10;\r\n if (value === 'recipient-uuid') return 20;\r\n return 0;\r\n }\r\n );\r\n\r\n (typeRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n typeCode: 'LTR',\r\n });\r\n (statusRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n statusCode: 'DRAFT',\r\n });\r\n\r\n (numberingService.generateNextNumber as jest.Mock).mockResolvedValue({\r\n number: 'DOC-001',\r\n });\r\n\r\n mockDataSource.manager.findOne\r\n .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' })\r\n .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' });\r\n\r\n const queryRunner = {\r\n connect: jest.fn(),\r\n startTransaction: jest.fn(),\r\n commitTransaction: jest.fn(),\r\n rollbackTransaction: jest.fn(),\r\n release: jest.fn(),\r\n manager: {\r\n create: jest.fn(\r\n (_entity: unknown, payload: Record) => payload\r\n ),\r\n save: jest\r\n .fn()\r\n .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' })\r\n .mockResolvedValueOnce({ id: 1000 })\r\n .mockResolvedValueOnce([]),\r\n findOne: jest.fn(),\r\n },\r\n };\r\n\r\n (mockDataSource.createQueryRunner as jest.Mock).mockReturnValue(\r\n queryRunner\r\n );\r\n\r\n await service.create(createDto, mockUser);\r\n\r\n expect(queryRunner.manager.create).toHaveBeenCalledWith(\r\n Correspondence,\r\n expect.objectContaining({ originatorId: 10 })\r\n );\r\n });\r\n\r\n it('should set revisionLabel to \"A\" for RFA type', async () => {\r\n const mockUser = {\r\n user_id: 1,\r\n primaryOrganizationId: 10,\r\n } as unknown as User;\r\n\r\n const createDto: CreateCorrespondenceDto = {\r\n projectId: 'project-uuid',\r\n typeId: 1,\r\n subject: 'Test Subject',\r\n recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }],\r\n };\r\n\r\n const typeRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceType)\r\n );\r\n const statusRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceStatus)\r\n );\r\n const uuidResolver =\r\n testingModule.get(UuidResolverService);\r\n\r\n (uuidResolver.resolveProjectId as jest.Mock).mockResolvedValue(100);\r\n (uuidResolver.resolveOrganizationId as jest.Mock).mockResolvedValue(20);\r\n\r\n (typeRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n typeCode: 'RFA',\r\n });\r\n (statusRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n statusCode: 'DRAFT',\r\n });\r\n\r\n (numberingService.generateNextNumber as jest.Mock).mockResolvedValue({\r\n number: 'DOC-001',\r\n });\r\n\r\n mockDataSource.manager.findOne\r\n .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' })\r\n .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' });\r\n\r\n const queryRunner = {\r\n connect: jest.fn(),\r\n startTransaction: jest.fn(),\r\n commitTransaction: jest.fn(),\r\n rollbackTransaction: jest.fn(),\r\n release: jest.fn(),\r\n manager: {\r\n create: jest.fn(\r\n (_entity: unknown, payload: Record) => payload\r\n ),\r\n save: jest\r\n .fn()\r\n .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' })\r\n .mockResolvedValueOnce({ id: 1000 })\r\n .mockResolvedValueOnce([]),\r\n findOne: jest.fn(),\r\n },\r\n };\r\n\r\n (mockDataSource.createQueryRunner as jest.Mock).mockReturnValue(\r\n queryRunner\r\n );\r\n\r\n await service.create(createDto, mockUser);\r\n\r\n expect(queryRunner.manager.create).toHaveBeenCalledWith(\r\n CorrespondenceRevision,\r\n expect.objectContaining({ revisionLabel: 'A' })\r\n );\r\n });\r\n\r\n it('should set revisionLabel to \"A\" for RFI type', async () => {\r\n const mockUser = {\r\n user_id: 1,\r\n primaryOrganizationId: 10,\r\n } as unknown as User;\r\n\r\n const createDto: CreateCorrespondenceDto = {\r\n projectId: 'project-uuid',\r\n typeId: 1,\r\n subject: 'Test Subject',\r\n recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }],\r\n };\r\n\r\n const typeRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceType)\r\n );\r\n const statusRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceStatus)\r\n );\r\n const uuidResolver =\r\n testingModule.get(UuidResolverService);\r\n\r\n (uuidResolver.resolveProjectId as jest.Mock).mockResolvedValue(100);\r\n (uuidResolver.resolveOrganizationId as jest.Mock).mockResolvedValue(20);\r\n\r\n (typeRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n typeCode: 'RFI',\r\n });\r\n (statusRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n statusCode: 'DRAFT',\r\n });\r\n\r\n (numberingService.generateNextNumber as jest.Mock).mockResolvedValue({\r\n number: 'DOC-001',\r\n });\r\n\r\n mockDataSource.manager.findOne\r\n .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' })\r\n .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' });\r\n\r\n const queryRunner = {\r\n connect: jest.fn(),\r\n startTransaction: jest.fn(),\r\n commitTransaction: jest.fn(),\r\n rollbackTransaction: jest.fn(),\r\n release: jest.fn(),\r\n manager: {\r\n create: jest.fn(\r\n (_entity: unknown, payload: Record) => payload\r\n ),\r\n save: jest\r\n .fn()\r\n .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' })\r\n .mockResolvedValueOnce({ id: 1000 })\r\n .mockResolvedValueOnce([]),\r\n findOne: jest.fn(),\r\n },\r\n };\r\n\r\n (mockDataSource.createQueryRunner as jest.Mock).mockReturnValue(\r\n queryRunner\r\n );\r\n\r\n await service.create(createDto, mockUser);\r\n\r\n expect(queryRunner.manager.create).toHaveBeenCalledWith(\r\n CorrespondenceRevision,\r\n expect.objectContaining({ revisionLabel: 'A' })\r\n );\r\n });\r\n\r\n it('should set revisionLabel to null for LETTER type', async () => {\r\n const mockUser = {\r\n user_id: 1,\r\n primaryOrganizationId: 10,\r\n } as unknown as User;\r\n\r\n const createDto: CreateCorrespondenceDto = {\r\n projectId: 'project-uuid',\r\n typeId: 1,\r\n subject: 'Test Subject',\r\n recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }],\r\n };\r\n\r\n const typeRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceType)\r\n );\r\n const statusRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceStatus)\r\n );\r\n const uuidResolver =\r\n testingModule.get(UuidResolverService);\r\n\r\n (uuidResolver.resolveProjectId as jest.Mock).mockResolvedValue(100);\r\n (uuidResolver.resolveOrganizationId as jest.Mock).mockResolvedValue(20);\r\n\r\n (typeRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n typeCode: 'LETTER',\r\n });\r\n (statusRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n statusCode: 'DRAFT',\r\n });\r\n\r\n (numberingService.generateNextNumber as jest.Mock).mockResolvedValue({\r\n number: 'DOC-001',\r\n });\r\n\r\n mockDataSource.manager.findOne\r\n .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' })\r\n .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' });\r\n\r\n const queryRunner = {\r\n connect: jest.fn(),\r\n startTransaction: jest.fn(),\r\n commitTransaction: jest.fn(),\r\n rollbackTransaction: jest.fn(),\r\n release: jest.fn(),\r\n manager: {\r\n create: jest.fn(\r\n (_entity: unknown, payload: Record) => payload\r\n ),\r\n save: jest\r\n .fn()\r\n .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' })\r\n .mockResolvedValueOnce({ id: 1000 })\r\n .mockResolvedValueOnce([]),\r\n findOne: jest.fn(),\r\n },\r\n };\r\n\r\n (mockDataSource.createQueryRunner as jest.Mock).mockReturnValue(\r\n queryRunner\r\n );\r\n\r\n await service.create(createDto, mockUser);\r\n\r\n expect(queryRunner.manager.create).toHaveBeenCalledWith(\r\n CorrespondenceRevision,\r\n expect.objectContaining({ revisionLabel: undefined })\r\n );\r\n });\r\n\r\n it('should set revisionLabel to undefined for MEMO type', async () => {\r\n const mockUser = {\r\n user_id: 1,\r\n primaryOrganizationId: 10,\r\n } as unknown as User;\r\n\r\n const createDto: CreateCorrespondenceDto = {\r\n projectId: 'project-uuid',\r\n typeId: 1,\r\n subject: 'Test Subject',\r\n recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }],\r\n };\r\n\r\n const typeRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceType)\r\n );\r\n const statusRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceStatus)\r\n );\r\n const uuidResolver =\r\n testingModule.get(UuidResolverService);\r\n\r\n (uuidResolver.resolveProjectId as jest.Mock).mockResolvedValue(100);\r\n (uuidResolver.resolveOrganizationId as jest.Mock).mockResolvedValue(20);\r\n\r\n (typeRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n typeCode: 'MEMO',\r\n });\r\n (statusRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n statusCode: 'DRAFT',\r\n });\r\n\r\n (numberingService.generateNextNumber as jest.Mock).mockResolvedValue({\r\n number: 'DOC-001',\r\n });\r\n\r\n mockDataSource.manager.findOne\r\n .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' })\r\n .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' });\r\n\r\n const queryRunner = {\r\n connect: jest.fn(),\r\n startTransaction: jest.fn(),\r\n commitTransaction: jest.fn(),\r\n rollbackTransaction: jest.fn(),\r\n release: jest.fn(),\r\n manager: {\r\n create: jest.fn(\r\n (_entity: unknown, payload: Record) => payload\r\n ),\r\n save: jest\r\n .fn()\r\n .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' })\r\n .mockResolvedValueOnce({ id: 1000 })\r\n .mockResolvedValueOnce([]),\r\n findOne: jest.fn(),\r\n },\r\n };\r\n\r\n (mockDataSource.createQueryRunner as jest.Mock).mockReturnValue(\r\n queryRunner\r\n );\r\n\r\n await service.create(createDto, mockUser);\r\n\r\n expect(queryRunner.manager.create).toHaveBeenCalledWith(\r\n CorrespondenceRevision,\r\n expect.objectContaining({ revisionLabel: undefined })\r\n );\r\n });\r\n });\r\n});\r\n"],"version":3} \ No newline at end of file diff --git a/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/f7/correspondenceservicespec_f7c1f1e06b95bcf8310dffb265941ee4 b/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/f7/correspondenceservicespec_f7c1f1e06b95bcf8310dffb265941ee4 new file mode 100644 index 0000000..7081198 --- /dev/null +++ b/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/f7/correspondenceservicespec_f7c1f1e06b95bcf8310dffb265941ee4 @@ -0,0 +1,561 @@ +23ed3615f11546daaa1755fd74e9c758 +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const testing_1 = require("@nestjs/testing"); +const typeorm_1 = require("@nestjs/typeorm"); +const typeorm_2 = require("typeorm"); +const correspondence_service_1 = require("./correspondence.service"); +const correspondence_entity_1 = require("./entities/correspondence.entity"); +const correspondence_revision_entity_1 = require("./entities/correspondence-revision.entity"); +const correspondence_type_entity_1 = require("./entities/correspondence-type.entity"); +const correspondence_status_entity_1 = require("./entities/correspondence-status.entity"); +const correspondence_reference_entity_1 = require("./entities/correspondence-reference.entity"); +const correspondence_tag_entity_1 = require("./entities/correspondence-tag.entity"); +const organization_entity_1 = require("../organization/entities/organization.entity"); +const correspondence_recipient_entity_1 = require("./entities/correspondence-recipient.entity"); +const document_numbering_service_1 = require("../document-numbering/services/document-numbering.service"); +const json_schema_service_1 = require("../json-schema/json-schema.service"); +const workflow_engine_service_1 = require("../workflow-engine/workflow-engine.service"); +const user_service_1 = require("../user/user.service"); +const search_service_1 = require("../search/search.service"); +const file_storage_service_1 = require("../../common/file-storage/file-storage.service"); +const uuid_resolver_service_1 = require("../../common/services/uuid-resolver.service"); +const notification_service_1 = require("../notification/notification.service"); +describe('CorrespondenceService', () => { + let service; + let numberingService; + let correspondenceRepo; + let revisionRepo; + let testingModule; + let _dataSource; + const createMockRepository = () => ({ + find: jest.fn(), + findOne: jest.fn(), + create: jest.fn(), + save: jest.fn(), + update: jest.fn(), + delete: jest.fn(), + softDelete: jest.fn(), + createQueryBuilder: jest.fn(() => ({ + leftJoinAndSelect: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + andWhere: jest.fn().mockReturnThis(), + orderBy: jest.fn().mockReturnThis(), + skip: jest.fn().mockReturnThis(), + take: jest.fn().mockReturnThis(), + getOne: jest.fn().mockResolvedValue(null), + getMany: jest.fn().mockResolvedValue([]), + getManyAndCount: jest.fn().mockResolvedValue([[], 0]), + })), + }); + const mockDataSource = { + createQueryRunner: jest.fn(() => ({ + connect: jest.fn(), + startTransaction: jest.fn(), + commitTransaction: jest.fn(), + rollbackTransaction: jest.fn(), + release: jest.fn(), + manager: { + create: jest.fn(), + save: jest.fn(), + findOne: jest.fn(), + }, + })), + getRepository: jest.fn(() => createMockRepository()), + manager: { + findOne: jest.fn(), + }, + }; + beforeEach(async () => { + testingModule = await testing_1.Test.createTestingModule({ + providers: [ + correspondence_service_1.CorrespondenceService, + { + provide: (0, typeorm_1.getRepositoryToken)(correspondence_entity_1.Correspondence), + useValue: createMockRepository(), + }, + { + provide: (0, typeorm_1.getRepositoryToken)(correspondence_revision_entity_1.CorrespondenceRevision), + useValue: createMockRepository(), + }, + { + provide: (0, typeorm_1.getRepositoryToken)(correspondence_type_entity_1.CorrespondenceType), + useValue: createMockRepository(), + }, + { + provide: (0, typeorm_1.getRepositoryToken)(correspondence_status_entity_1.CorrespondenceStatus), + useValue: createMockRepository(), + }, + { + provide: (0, typeorm_1.getRepositoryToken)(correspondence_reference_entity_1.CorrespondenceReference), + useValue: createMockRepository(), + }, + { + provide: (0, typeorm_1.getRepositoryToken)(correspondence_tag_entity_1.CorrespondenceTag), + useValue: createMockRepository(), + }, + { + provide: (0, typeorm_1.getRepositoryToken)(organization_entity_1.Organization), + useValue: createMockRepository(), + }, + { + provide: (0, typeorm_1.getRepositoryToken)(correspondence_recipient_entity_1.CorrespondenceRecipient), + useValue: createMockRepository(), + }, + { + provide: document_numbering_service_1.DocumentNumberingService, + useValue: { + generateNextNumber: jest.fn(), + updateNumberForDraft: jest.fn(), + previewNextNumber: jest.fn(), + }, + }, + { + provide: json_schema_service_1.JsonSchemaService, + useValue: { validate: jest.fn() }, + }, + { + provide: workflow_engine_service_1.WorkflowEngineService, + useValue: { createInstance: jest.fn() }, + }, + { + provide: user_service_1.UserService, + useValue: { + findOne: jest.fn(), + getUserPermissions: jest.fn().mockResolvedValue([]), + }, + }, + { + provide: typeorm_2.DataSource, + useValue: mockDataSource, + }, + { + provide: search_service_1.SearchService, + useValue: { indexDocument: jest.fn() }, + }, + { + provide: file_storage_service_1.FileStorageService, + useValue: { commit: jest.fn().mockResolvedValue([]) }, + }, + { + provide: uuid_resolver_service_1.UuidResolverService, + useValue: { + resolveProjectId: jest.fn().mockResolvedValue(1), + resolveOrganizationId: jest.fn().mockResolvedValue(1), + }, + }, + { + provide: notification_service_1.NotificationService, + useValue: { send: jest.fn().mockResolvedValue(undefined) }, + }, + ], + }).compile(); + service = testingModule.get(correspondence_service_1.CorrespondenceService); + numberingService = testingModule.get(document_numbering_service_1.DocumentNumberingService); + correspondenceRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_entity_1.Correspondence)); + revisionRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_revision_entity_1.CorrespondenceRevision)); + _dataSource = testingModule.get(typeorm_2.DataSource); + }); + it('should be defined', () => { + expect(service).toBeDefined(); + }); + describe('update', () => { + it('should NOT regenerate number if critical fields unchanged', async () => { + const mockUser = { id: 1, primaryOrganizationId: 10 }; + const mockRevision = { + id: 100, + correspondenceId: 1, + isCurrent: true, + statusId: 5, + }; + jest + .spyOn(revisionRepo, 'findOne') + .mockResolvedValue(mockRevision); + const mockCorr = { + id: 1, + projectId: 1, + correspondenceTypeId: 2, + disciplineId: 3, + originatorId: 10, + correspondenceNumber: 'OLD-NUM', + recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }], + }; + jest + .spyOn(correspondenceRepo, 'findOne') + .mockResolvedValue(mockCorr); + const updateDto = { + projectId: 1, + disciplineId: 3, + }; + await service.update(1, updateDto, mockUser); + expect(numberingService.updateNumberForDraft).not.toHaveBeenCalled(); + }); + it('should regenerate number if Project ID changes', async () => { + const mockUser = { id: 1, primaryOrganizationId: 10 }; + const mockRevision = { + id: 100, + correspondenceId: 1, + isCurrent: true, + statusId: 5, + }; + jest + .spyOn(revisionRepo, 'findOne') + .mockResolvedValue(mockRevision); + const mockCorr = { + id: 1, + projectId: 1, + correspondenceTypeId: 2, + disciplineId: 3, + originatorId: 10, + correspondenceNumber: 'OLD-NUM', + recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }], + }; + jest + .spyOn(correspondenceRepo, 'findOne') + .mockResolvedValue(mockCorr); + const updateDto = { + projectId: 2, + }; + const uuidResolver = testingModule.get(uuid_resolver_service_1.UuidResolverService); + uuidResolver.resolveProjectId.mockResolvedValue(2); + await service.update(1, updateDto, mockUser); + expect(numberingService.updateNumberForDraft).toHaveBeenCalled(); + }); + it('should regenerate number if Document Type changes', async () => { + const mockUser = { id: 1, primaryOrganizationId: 10 }; + const mockRevision = { + id: 100, + correspondenceId: 1, + isCurrent: true, + statusId: 5, + }; + jest + .spyOn(revisionRepo, 'findOne') + .mockResolvedValue(mockRevision); + const mockCorr = { + id: 1, + projectId: 1, + correspondenceTypeId: 2, + disciplineId: 3, + originatorId: 10, + correspondenceNumber: 'OLD-NUM', + recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }], + }; + jest + .spyOn(correspondenceRepo, 'findOne') + .mockResolvedValue(mockCorr); + const updateDto = { + typeId: 999, + }; + const typeRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_type_entity_1.CorrespondenceType)); + typeRepo.findOne.mockResolvedValue({ + id: 999, + typeCode: 'NEW-TYPE', + }); + await service.update(1, updateDto, mockUser); + expect(numberingService.updateNumberForDraft).toHaveBeenCalled(); + }); + it('should regenerate number if Recipient Organization changes', async () => { + const mockUser = { id: 1, primaryOrganizationId: 10 }; + const mockRevision = { + id: 100, + correspondenceId: 1, + isCurrent: true, + statusId: 5, + }; + jest + .spyOn(revisionRepo, 'findOne') + .mockResolvedValue(mockRevision); + const mockCorr = { + id: 1, + projectId: 1, + correspondenceTypeId: 2, + disciplineId: 3, + originatorId: 10, + correspondenceNumber: 'OLD-NUM', + recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }], + }; + jest + .spyOn(correspondenceRepo, 'findOne') + .mockResolvedValue(mockCorr); + // Access DataSource manager for mocking + mockDataSource.manager.findOne.mockResolvedValue({ + id: 88, + organizationCode: 'NEW-ORG', + }); + const updateDto = { + recipients: [{ type: 'TO', organizationId: 88 }], + }; + await service.update(1, updateDto, mockUser); + expect(numberingService.updateNumberForDraft).toHaveBeenCalled(); + }); + }); + describe('create', () => { + it('should allow system.manage_all user without primaryOrganizationId when originatorId is provided', async () => { + const mockUser = { + user_id: 1, + primaryOrganizationId: null, + }; + const createDto = { + projectId: 'project-uuid', + typeId: 1, + subject: 'Test Subject', + originatorId: 'originator-uuid', + recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }], + }; + const userService = testingModule.get(user_service_1.UserService); + const typeRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_type_entity_1.CorrespondenceType)); + const statusRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_status_entity_1.CorrespondenceStatus)); + const uuidResolver = testingModule.get(uuid_resolver_service_1.UuidResolverService); + userService.findOne.mockResolvedValue({ + user_id: 1, + primaryOrganizationId: null, + }); + userService.getUserPermissions.mockResolvedValue([ + 'system.manage_all', + ]); + uuidResolver.resolveProjectId.mockResolvedValue(100); + uuidResolver.resolveOrganizationId.mockImplementation((value) => { + if (value === 'originator-uuid') + return 10; + if (value === 'recipient-uuid') + return 20; + return 0; + }); + typeRepo.findOne.mockResolvedValue({ + id: 1, + typeCode: 'LTR', + }); + statusRepo.findOne.mockResolvedValue({ + id: 1, + statusCode: 'DRAFT', + }); + numberingService.generateNextNumber.mockResolvedValue({ + number: 'DOC-001', + }); + mockDataSource.manager.findOne + .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' }) + .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' }); + const queryRunner = { + connect: jest.fn(), + startTransaction: jest.fn(), + commitTransaction: jest.fn(), + rollbackTransaction: jest.fn(), + release: jest.fn(), + manager: { + create: jest.fn((_entity, payload) => payload), + save: jest + .fn() + .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' }) + .mockResolvedValueOnce({ id: 1000 }) + .mockResolvedValueOnce([]), + findOne: jest.fn(), + }, + }; + mockDataSource.createQueryRunner.mockReturnValue(queryRunner); + await service.create(createDto, mockUser); + expect(queryRunner.manager.create).toHaveBeenCalledWith(correspondence_entity_1.Correspondence, expect.objectContaining({ originatorId: 10 })); + }); + it('should set revisionLabel to "A" for RFA type', async () => { + const mockUser = { + user_id: 1, + primaryOrganizationId: 10, + }; + const createDto = { + projectId: 'project-uuid', + typeId: 1, + subject: 'Test Subject', + recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }], + }; + const typeRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_type_entity_1.CorrespondenceType)); + const statusRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_status_entity_1.CorrespondenceStatus)); + const uuidResolver = testingModule.get(uuid_resolver_service_1.UuidResolverService); + uuidResolver.resolveProjectId.mockResolvedValue(100); + uuidResolver.resolveOrganizationId.mockResolvedValue(20); + typeRepo.findOne.mockResolvedValue({ + id: 1, + typeCode: 'RFA', + }); + statusRepo.findOne.mockResolvedValue({ + id: 1, + statusCode: 'DRAFT', + }); + numberingService.generateNextNumber.mockResolvedValue({ + number: 'DOC-001', + }); + mockDataSource.manager.findOne + .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' }) + .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' }); + const queryRunner = { + connect: jest.fn(), + startTransaction: jest.fn(), + commitTransaction: jest.fn(), + rollbackTransaction: jest.fn(), + release: jest.fn(), + manager: { + create: jest.fn((_entity, payload) => payload), + save: jest + .fn() + .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' }) + .mockResolvedValueOnce({ id: 1000 }) + .mockResolvedValueOnce([]), + findOne: jest.fn(), + }, + }; + mockDataSource.createQueryRunner.mockReturnValue(queryRunner); + await service.create(createDto, mockUser); + expect(queryRunner.manager.create).toHaveBeenCalledWith(correspondence_revision_entity_1.CorrespondenceRevision, expect.objectContaining({ revisionLabel: 'A' })); + }); + it('should set revisionLabel to "A" for RFI type', async () => { + const mockUser = { + user_id: 1, + primaryOrganizationId: 10, + }; + const createDto = { + projectId: 'project-uuid', + typeId: 1, + subject: 'Test Subject', + recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }], + }; + const typeRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_type_entity_1.CorrespondenceType)); + const statusRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_status_entity_1.CorrespondenceStatus)); + const uuidResolver = testingModule.get(uuid_resolver_service_1.UuidResolverService); + uuidResolver.resolveProjectId.mockResolvedValue(100); + uuidResolver.resolveOrganizationId.mockResolvedValue(20); + typeRepo.findOne.mockResolvedValue({ + id: 1, + typeCode: 'RFI', + }); + statusRepo.findOne.mockResolvedValue({ + id: 1, + statusCode: 'DRAFT', + }); + numberingService.generateNextNumber.mockResolvedValue({ + number: 'DOC-001', + }); + mockDataSource.manager.findOne + .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' }) + .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' }); + const queryRunner = { + connect: jest.fn(), + startTransaction: jest.fn(), + commitTransaction: jest.fn(), + rollbackTransaction: jest.fn(), + release: jest.fn(), + manager: { + create: jest.fn((_entity, payload) => payload), + save: jest + .fn() + .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' }) + .mockResolvedValueOnce({ id: 1000 }) + .mockResolvedValueOnce([]), + findOne: jest.fn(), + }, + }; + mockDataSource.createQueryRunner.mockReturnValue(queryRunner); + await service.create(createDto, mockUser); + expect(queryRunner.manager.create).toHaveBeenCalledWith(correspondence_revision_entity_1.CorrespondenceRevision, expect.objectContaining({ revisionLabel: 'A' })); + }); + it('should set revisionLabel to null for LETTER type', async () => { + const mockUser = { + user_id: 1, + primaryOrganizationId: 10, + }; + const createDto = { + projectId: 'project-uuid', + typeId: 1, + subject: 'Test Subject', + recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }], + }; + const typeRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_type_entity_1.CorrespondenceType)); + const statusRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_status_entity_1.CorrespondenceStatus)); + const uuidResolver = testingModule.get(uuid_resolver_service_1.UuidResolverService); + uuidResolver.resolveProjectId.mockResolvedValue(100); + uuidResolver.resolveOrganizationId.mockResolvedValue(20); + typeRepo.findOne.mockResolvedValue({ + id: 1, + typeCode: 'LETTER', + }); + statusRepo.findOne.mockResolvedValue({ + id: 1, + statusCode: 'DRAFT', + }); + numberingService.generateNextNumber.mockResolvedValue({ + number: 'DOC-001', + }); + mockDataSource.manager.findOne + .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' }) + .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' }); + const queryRunner = { + connect: jest.fn(), + startTransaction: jest.fn(), + commitTransaction: jest.fn(), + rollbackTransaction: jest.fn(), + release: jest.fn(), + manager: { + create: jest.fn((_entity, payload) => payload), + save: jest + .fn() + .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' }) + .mockResolvedValueOnce({ id: 1000 }) + .mockResolvedValueOnce([]), + findOne: jest.fn(), + }, + }; + mockDataSource.createQueryRunner.mockReturnValue(queryRunner); + await service.create(createDto, mockUser); + expect(queryRunner.manager.create).toHaveBeenCalledWith(correspondence_revision_entity_1.CorrespondenceRevision, expect.objectContaining({ revisionLabel: undefined })); + }); + it('should set revisionLabel to undefined for MEMO type', async () => { + const mockUser = { + user_id: 1, + primaryOrganizationId: 10, + }; + const createDto = { + projectId: 'project-uuid', + typeId: 1, + subject: 'Test Subject', + recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }], + }; + const typeRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_type_entity_1.CorrespondenceType)); + const statusRepo = testingModule.get((0, typeorm_1.getRepositoryToken)(correspondence_status_entity_1.CorrespondenceStatus)); + const uuidResolver = testingModule.get(uuid_resolver_service_1.UuidResolverService); + uuidResolver.resolveProjectId.mockResolvedValue(100); + uuidResolver.resolveOrganizationId.mockResolvedValue(20); + typeRepo.findOne.mockResolvedValue({ + id: 1, + typeCode: 'MEMO', + }); + statusRepo.findOne.mockResolvedValue({ + id: 1, + statusCode: 'DRAFT', + }); + numberingService.generateNextNumber.mockResolvedValue({ + number: 'DOC-001', + }); + mockDataSource.manager.findOne + .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' }) + .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' }); + const queryRunner = { + connect: jest.fn(), + startTransaction: jest.fn(), + commitTransaction: jest.fn(), + rollbackTransaction: jest.fn(), + release: jest.fn(), + manager: { + create: jest.fn((_entity, payload) => payload), + save: jest + .fn() + .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' }) + .mockResolvedValueOnce({ id: 1000 }) + .mockResolvedValueOnce([]), + findOne: jest.fn(), + }, + }; + mockDataSource.createQueryRunner.mockReturnValue(queryRunner); + await service.create(createDto, mockUser); + expect(queryRunner.manager.create).toHaveBeenCalledWith(correspondence_revision_entity_1.CorrespondenceRevision, expect.objectContaining({ revisionLabel: undefined })); + }); + }); +}); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJmaWxlIjoiRTpcXG5wLWRtc1xcbGNicDNcXGJhY2tlbmRcXHNyY1xcbW9kdWxlc1xcY29ycmVzcG9uZGVuY2VcXGNvcnJlc3BvbmRlbmNlLnNlcnZpY2Uuc3BlYy50cyIsIm1hcHBpbmdzIjoiOztBQUFBLDZDQUFzRDtBQUN0RCw2Q0FBcUQ7QUFDckQscUNBQWlEO0FBQ2pELHFFQUFpRTtBQUNqRSw0RUFBa0U7QUFDbEUsOEZBQW1GO0FBQ25GLHNGQUEyRTtBQUMzRSwwRkFBK0U7QUFDL0UsZ0dBQXFGO0FBQ3JGLG9GQUF5RTtBQUN6RSxzRkFBNEU7QUFDNUUsZ0dBQXFGO0FBQ3JGLDBHQUFxRztBQUNyRyw0RUFBdUU7QUFDdkUsd0ZBQW1GO0FBQ25GLHVEQUFtRDtBQUNuRCw2REFBeUQ7QUFDekQseUZBQW9GO0FBQ3BGLHVGQUFrRjtBQUNsRiwrRUFBMkU7QUFLM0UsUUFBUSxDQUFDLHVCQUF1QixFQUFFLEdBQUcsRUFBRTtJQUNyQyxJQUFJLE9BQThCLENBQUM7SUFDbkMsSUFBSSxnQkFBMEMsQ0FBQztJQUMvQyxJQUFJLGtCQUE4QyxDQUFDO0lBQ25ELElBQUksWUFBZ0QsQ0FBQztJQUNyRCxJQUFJLGFBQTRCLENBQUM7SUFDakMsSUFBSSxXQUF1QixDQUFDO0lBRTVCLE1BQU0sb0JBQW9CLEdBQUcsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUNsQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRTtRQUNmLE9BQU8sRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFFO1FBQ2xCLE1BQU0sRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFFO1FBQ2pCLElBQUksRUFBRSxJQUFJLENBQUMsRUFBRSxFQUFFO1FBQ2YsTUFBTSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUU7UUFDakIsTUFBTSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUU7UUFDakIsVUFBVSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUU7UUFDckIsa0JBQWtCLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQ2pD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QUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxvQkFBb0IsQ0FDckQsdURBQXNCLEVBQ3RCLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUN0RCxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIkU6XFxucC1kbXNcXGxjYnAzXFxiYWNrZW5kXFxzcmNcXG1vZHVsZXNcXGNvcnJlc3BvbmRlbmNlXFxjb3JyZXNwb25kZW5jZS5zZXJ2aWNlLnNwZWMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVGVzdCwgVGVzdGluZ01vZHVsZSB9IGZyb20gJ0BuZXN0anMvdGVzdGluZyc7XHJcbmltcG9ydCB7IGdldFJlcG9zaXRvcnlUb2tlbiB9IGZyb20gJ0BuZXN0anMvdHlwZW9ybSc7XHJcbmltcG9ydCB7IERhdGFTb3VyY2UsIFJlcG9zaXRvcnkgfSBmcm9tICd0eXBlb3JtJztcclxuaW1wb3J0IHsgQ29ycmVzcG9uZGVuY2VTZXJ2aWNlIH0gZnJvbSAnLi9jb3JyZXNwb25kZW5jZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgQ29ycmVzcG9uZGVuY2UgfSBmcm9tICcuL2VudGl0aWVzL2NvcnJlc3BvbmRlbmNlLmVudGl0eSc7XHJcbmltcG9ydCB7IENvcnJlc3BvbmRlbmNlUmV2aXNpb24gfSBmcm9tICcuL2VudGl0aWVzL2NvcnJlc3BvbmRlbmNlLXJldmlzaW9uLmVudGl0eSc7XHJcbmltcG9ydCB7IENvcnJlc3BvbmRlbmNlVHlwZSB9IGZyb20gJy4vZW50aXRpZXMvY29ycmVzcG9uZGVuY2UtdHlwZS5lbnRpdHknO1xyXG5pbXBvcnQgeyBDb3JyZXNwb25kZW5jZVN0YXR1cyB9IGZyb20gJy4vZW50aXRpZXMvY29ycmVzcG9uZGVuY2Utc3RhdHVzLmVudGl0eSc7XHJcbmltcG9ydCB7IENvcnJlc3BvbmRlbmNlUmVmZXJlbmNlIH0gZnJvbSAnLi9lbnRpdGllcy9jb3JyZXNwb25kZW5jZS1yZWZlcmVuY2UuZW50aXR5JztcclxuaW1wb3J0IHsgQ29ycmVzcG9uZGVuY2VUYWcgfSBmcm9tICcuL2VudGl0aWVzL2NvcnJlc3BvbmRlbmNlLXRhZy5lbnRpdHknO1xyXG5pbXBvcnQgeyBPcmdhbml6YXRpb24gfSBmcm9tICcuLi9vcmdhbml6YXRpb24vZW50aXRpZXMvb3JnYW5pemF0aW9uLmVudGl0eSc7XHJcbmltcG9ydCB7IENvcnJlc3BvbmRlbmNlUmVjaXBpZW50IH0gZnJvbSAnLi9lbnRpdGllcy9jb3JyZXNwb25kZW5jZS1yZWNpcGllbnQuZW50aXR5JztcclxuaW1wb3J0IHsgRG9jdW1lbnROdW1iZXJpbmdTZXJ2aWNlIH0gZnJvbSAnLi4vZG9jdW1lbnQtbnVtYmVyaW5nL3NlcnZpY2VzL2RvY3VtZW50LW51bWJlcmluZy5zZXJ2aWNlJztcclxuaW1wb3J0IHsgSnNvblNjaGVtYVNlcnZpY2UgfSBmcm9tICcuLi9qc29uLXNjaGVtYS9qc29uLXNjaGVtYS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgV29ya2Zsb3dFbmdpbmVTZXJ2aWNlIH0gZnJvbSAnLi4vd29ya2Zsb3ctZW5naW5lL3dvcmtmbG93LWVuZ2luZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgVXNlclNlcnZpY2UgfSBmcm9tICcuLi91c2VyL3VzZXIuc2VydmljZSc7XHJcbmltcG9ydCB7IFNlYXJjaFNlcnZpY2UgfSBmcm9tICcuLi9zZWFyY2gvc2VhcmNoLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBGaWxlU3RvcmFnZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9jb21tb24vZmlsZS1zdG9yYWdlL2ZpbGUtc3RvcmFnZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgVXVpZFJlc29sdmVyU2VydmljZSB9IGZyb20gJy4uLy4uL2NvbW1vbi9zZXJ2aWNlcy91dWlkLXJlc29sdmVyLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBOb3RpZmljYXRpb25TZXJ2aWNlIH0gZnJvbSAnLi4vbm90aWZpY2F0aW9uL25vdGlmaWNhdGlvbi5zZXJ2aWNlJztcclxuaW1wb3J0IHsgVXBkYXRlQ29ycmVzcG9uZGVuY2VEdG8gfSBmcm9tICcuL2R0by91cGRhdGUtY29ycmVzcG9uZGVuY2UuZHRvJztcclxuaW1wb3J0IHsgQ3JlYXRlQ29ycmVzcG9uZGVuY2VEdG8gfSBmcm9tICcuL2R0by9jcmVhdGUtY29ycmVzcG9uZGVuY2UuZHRvJztcclxuaW1wb3J0IHsgVXNlciB9IGZyb20gJy4uL3VzZXIvZW50aXRpZXMvdXNlci5lbnRpdHknO1xyXG5cclxuZGVzY3JpYmUoJ0NvcnJlc3BvbmRlbmNlU2VydmljZScsICgpID0+IHtcclxuICBsZXQgc2VydmljZTogQ29ycmVzcG9uZGVuY2VTZXJ2aWNlO1xyXG4gIGxldCBudW1iZXJpbmdTZXJ2aWNlOiBEb2N1bWVudE51bWJlcmluZ1NlcnZpY2U7XHJcbiAgbGV0IGNvcnJlc3BvbmRlbmNlUmVwbzogUmVwb3NpdG9yeTxDb3JyZXNwb25kZW5jZT47XHJcbiAgbGV0IHJldmlzaW9uUmVwbzogUmVwb3NpdG9yeTxDb3JyZXNwb25kZW5jZVJldmlzaW9uPjtcclxuICBsZXQgdGVzdGluZ01vZHVsZTogVGVzdGluZ01vZHVsZTtcclxuICBsZXQgX2RhdGFTb3VyY2U6IERhdGFTb3VyY2U7XHJcblxyXG4gIGNvbnN0IGNyZWF0ZU1vY2tSZXBvc2l0b3J5ID0gKCkgPT4gKHtcclxuICAgIGZpbmQ6IGplc3QuZm4oKSxcclxuICAgIGZpbmRPbmU6IGplc3QuZm4oKSxcclxuICAgIGNyZWF0ZTogamVzdC5mbigpLFxyXG4gICAgc2F2ZTogamVzdC5mbigpLFxyXG4gICAgdXBkYXRlOiBqZXN0LmZuKCksXHJcbiAgICBkZWxldGU6IGplc3QuZm4oKSxcclxuICAgIHNvZnREZWxldGU6IGplc3QuZm4oKSxcclxuICAgIGNyZWF0ZVF1ZXJ5QnVpbGRlcjogamVzdC5mbigoKSA9PiAoe1xyXG4gICAgICBsZWZ0Sm9pbkFuZFNlbGVjdDogamVzdC5mbigpLm1vY2tSZXR1cm5UaGlzKCksXHJcbiAgICAgIHdoZXJlOiBqZXN0LmZuKCkubW9ja1JldHVyblRoaXMoKSxcclxuICAgICAgYW5kV2hlcmU6IGplc3QuZm4oKS5tb2NrUmV0dXJuVGhpcygpLFxyXG4gICAgICBvcmRlckJ5OiBqZXN0LmZuKCkubW9ja1JldHVyblRoaXMoKSxcclxuICAgICAgc2tpcDogamVzdC5mbigpLm1vY2tSZXR1cm5UaGlzKCksXHJcbiAgICAgIHRha2U6IGplc3QuZm4oKS5tb2NrUmV0dXJuVGhpcygpLFxyXG4gICAgICBnZXRPbmU6IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZShudWxsKSxcclxuICAgICAgZ2V0TWFueTogamVzdC5mbigpLm1vY2tSZXNvbHZlZFZhbHVlKFtdKSxcclxuICAgICAgZ2V0TWFueUFuZENvdW50OiBqZXN0LmZuKCkubW9ja1Jlc29sdmVkVmFsdWUoW1tdLCAwXSksXHJcbiAgICB9KSksXHJcbiAgfSk7XHJcblxyXG4gIGNvbnN0IG1vY2tEYXRhU291cmNlID0ge1xyXG4gICAgY3JlYXRlUXVlcnlSdW5uZXI6IGplc3QuZm4oKCkgPT4gKHtcclxuICAgICAgY29ubmVjdDogamVzdC5mbigpLFxyXG4gICAgICBzdGFydFRyYW5zYWN0aW9uOiBqZXN0LmZuKCksXHJcbiAgICAgIGNvbW1pdFRyYW5zYWN0aW9uOiBqZXN0LmZuKCksXHJcbiAgICAgIHJvbGxiYWNrVHJhbnNhY3Rpb246IGplc3QuZm4oKSxcclxuICAgICAgcmVsZWFzZTogamVzdC5mbigpLFxyXG4gICAgICBtYW5hZ2VyOiB7XHJcbiAgICAgICAgY3JlYXRlOiBqZXN0LmZuKCksXHJcbiAgICAgICAgc2F2ZTogamVzdC5mbigpLFxyXG4gICAgICAgIGZpbmRPbmU6IGplc3QuZm4oKSxcclxuICAgICAgfSxcclxuICAgIH0pKSxcclxuICAgIGdldFJlcG9zaXRvcnk6IGplc3QuZm4oKCkgPT4gY3JlYXRlTW9ja1JlcG9zaXRvcnkoKSksXHJcbiAgICBtYW5hZ2VyOiB7XHJcbiAgICAgIGZpbmRPbmU6IGplc3QuZm4oKSxcclxuICAgIH0sXHJcbiAgfTtcclxuXHJcbiAgYmVmb3JlRWFjaChhc3luYyAoKSA9PiB7XHJcbiAgICB0ZXN0aW5nTW9kdWxlID0gYXdhaXQgVGVzdC5jcmVhdGVUZXN0aW5nTW9kdWxlKHtcclxuICAgICAgcHJvdmlkZXJzOiBbXHJcbiAgICAgICAgQ29ycmVzcG9uZGVuY2VTZXJ2aWNlLFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IGdldFJlcG9zaXRvcnlUb2tlbihDb3JyZXNwb25kZW5jZSksXHJcbiAgICAgICAgICB1c2VWYWx1ZTogY3JlYXRlTW9ja1JlcG9zaXRvcnkoKSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IGdldFJlcG9zaXRvcnlUb2tlbihDb3JyZXNwb25kZW5jZVJldmlzaW9uKSxcclxuICAgICAgICAgIHVzZVZhbHVlOiBjcmVhdGVNb2NrUmVwb3NpdG9yeSgpLFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgcHJvdmlkZTogZ2V0UmVwb3NpdG9yeVRva2VuKENvcnJlc3BvbmRlbmNlVHlwZSksXHJcbiAgICAgICAgICB1c2VWYWx1ZTogY3JlYXRlTW9ja1JlcG9zaXRvcnkoKSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IGdldFJlcG9zaXRvcnlUb2tlbihDb3JyZXNwb25kZW5jZVN0YXR1cyksXHJcbiAgICAgICAgICB1c2VWYWx1ZTogY3JlYXRlTW9ja1JlcG9zaXRvcnkoKSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IGdldFJlcG9zaXRvcnlUb2tlbihDb3JyZXNwb25kZW5jZVJlZmVyZW5jZSksXHJcbiAgICAgICAgICB1c2VWYWx1ZTogY3JlYXRlTW9ja1JlcG9zaXRvcnkoKSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IGdldFJlcG9zaXRvcnlUb2tlbihDb3JyZXNwb25kZW5jZVRhZyksXHJcbiAgICAgICAgICB1c2VWYWx1ZTogY3JlYXRlTW9ja1JlcG9zaXRvcnkoKSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IGdldFJlcG9zaXRvcnlUb2tlbihPcmdhbml6YXRpb24pLFxyXG4gICAgICAgICAgdXNlVmFsdWU6IGNyZWF0ZU1vY2tSZXBvc2l0b3J5KCksXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBwcm92aWRlOiBnZXRSZXBvc2l0b3J5VG9rZW4oQ29ycmVzcG9uZGVuY2VSZWNpcGllbnQpLFxyXG4gICAgICAgICAgdXNlVmFsdWU6IGNyZWF0ZU1vY2tSZXBvc2l0b3J5KCksXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBwcm92aWRlOiBEb2N1bWVudE51bWJlcmluZ1NlcnZpY2UsXHJcbiAgICAgICAgICB1c2VWYWx1ZToge1xyXG4gICAgICAgICAgICBnZW5lcmF0ZU5leHROdW1iZXI6IGplc3QuZm4oKSxcclxuICAgICAgICAgICAgdXBkYXRlTnVtYmVyRm9yRHJhZnQ6IGplc3QuZm4oKSxcclxuICAgICAgICAgICAgcHJldmlld05leHROdW1iZXI6IGplc3QuZm4oKSxcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBwcm92aWRlOiBKc29uU2NoZW1hU2VydmljZSxcclxuICAgICAgICAgIHVzZVZhbHVlOiB7IHZhbGlkYXRlOiBqZXN0LmZuKCkgfSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IFdvcmtmbG93RW5naW5lU2VydmljZSxcclxuICAgICAgICAgIHVzZVZhbHVlOiB7IGNyZWF0ZUluc3RhbmNlOiBqZXN0LmZuKCkgfSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IFVzZXJTZXJ2aWNlLFxyXG4gICAgICAgICAgdXNlVmFsdWU6IHtcclxuICAgICAgICAgICAgZmluZE9uZTogamVzdC5mbigpLFxyXG4gICAgICAgICAgICBnZXRVc2VyUGVybWlzc2lvbnM6IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZShbXSksXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgcHJvdmlkZTogRGF0YVNvdXJjZSxcclxuICAgICAgICAgIHVzZVZhbHVlOiBtb2NrRGF0YVNvdXJjZSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IFNlYXJjaFNlcnZpY2UsXHJcbiAgICAgICAgICB1c2VWYWx1ZTogeyBpbmRleERvY3VtZW50OiBqZXN0LmZuKCkgfSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHByb3ZpZGU6IEZpbGVTdG9yYWdlU2VydmljZSxcclxuICAgICAgICAgIHVzZVZhbHVlOiB7IGNvbW1pdDogamVzdC5mbigpLm1vY2tSZXNvbHZlZFZhbHVlKFtdKSB9LFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgcHJvdmlkZTogVXVpZFJlc29sdmVyU2VydmljZSxcclxuICAgICAgICAgIHVzZVZhbHVlOiB7XHJcbiAgICAgICAgICAgIHJlc29sdmVQcm9qZWN0SWQ6IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZSgxKSxcclxuICAgICAgICAgICAgcmVzb2x2ZU9yZ2FuaXphdGlvbklkOiBqZXN0LmZuKCkubW9ja1Jlc29sdmVkVmFsdWUoMSksXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgcHJvdmlkZTogTm90aWZpY2F0aW9uU2VydmljZSxcclxuICAgICAgICAgIHVzZVZhbHVlOiB7IHNlbmQ6IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZSh1bmRlZmluZWQpIH0sXHJcbiAgICAgICAgfSxcclxuICAgICAgXSxcclxuICAgIH0pLmNvbXBpbGUoKTtcclxuXHJcbiAgICBzZXJ2aWNlID0gdGVzdGluZ01vZHVsZS5nZXQ8Q29ycmVzcG9uZGVuY2VTZXJ2aWNlPihDb3JyZXNwb25kZW5jZVNlcnZpY2UpO1xyXG4gICAgbnVtYmVyaW5nU2VydmljZSA9IHRlc3RpbmdNb2R1bGUuZ2V0PERvY3VtZW50TnVtYmVyaW5nU2VydmljZT4oXHJcbiAgICAgIERvY3VtZW50TnVtYmVyaW5nU2VydmljZVxyXG4gICAgKTtcclxuICAgIGNvcnJlc3BvbmRlbmNlUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2U+PihcclxuICAgICAgZ2V0UmVwb3NpdG9yeVRva2VuKENvcnJlc3BvbmRlbmNlKVxyXG4gICAgKTtcclxuICAgIHJldmlzaW9uUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2VSZXZpc2lvbj4+KFxyXG4gICAgICBnZXRSZXBvc2l0b3J5VG9rZW4oQ29ycmVzcG9uZGVuY2VSZXZpc2lvbilcclxuICAgICk7XHJcbiAgICBfZGF0YVNvdXJjZSA9IHRlc3RpbmdNb2R1bGUuZ2V0PERhdGFTb3VyY2U+KERhdGFTb3VyY2UpO1xyXG4gIH0pO1xyXG5cclxuICBpdCgnc2hvdWxkIGJlIGRlZmluZWQnLCAoKSA9PiB7XHJcbiAgICBleHBlY3Qoc2VydmljZSkudG9CZURlZmluZWQoKTtcclxuICB9KTtcclxuXHJcbiAgZGVzY3JpYmUoJ3VwZGF0ZScsICgpID0+IHtcclxuICAgIGl0KCdzaG91bGQgTk9UIHJlZ2VuZXJhdGUgbnVtYmVyIGlmIGNyaXRpY2FsIGZpZWxkcyB1bmNoYW5nZWQnLCBhc3luYyAoKSA9PiB7XHJcbiAgICAgIGNvbnN0IG1vY2tVc2VyID0geyBpZDogMSwgcHJpbWFyeU9yZ2FuaXphdGlvbklkOiAxMCB9IGFzIHVua25vd24gYXMgVXNlcjtcclxuICAgICAgY29uc3QgbW9ja1JldmlzaW9uID0ge1xyXG4gICAgICAgIGlkOiAxMDAsXHJcbiAgICAgICAgY29ycmVzcG9uZGVuY2VJZDogMSxcclxuICAgICAgICBpc0N1cnJlbnQ6IHRydWUsXHJcbiAgICAgICAgc3RhdHVzSWQ6IDUsXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBqZXN0XHJcbiAgICAgICAgLnNweU9uKHJldmlzaW9uUmVwbywgJ2ZpbmRPbmUnKVxyXG4gICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZShtb2NrUmV2aXNpb24gYXMgdW5rbm93biBhcyBDb3JyZXNwb25kZW5jZVJldmlzaW9uKTtcclxuXHJcbiAgICAgIGNvbnN0IG1vY2tDb3JyID0ge1xyXG4gICAgICAgIGlkOiAxLFxyXG4gICAgICAgIHByb2plY3RJZDogMSxcclxuICAgICAgICBjb3JyZXNwb25kZW5jZVR5cGVJZDogMixcclxuICAgICAgICBkaXNjaXBsaW5lSWQ6IDMsXHJcbiAgICAgICAgb3JpZ2luYXRvcklkOiAxMCxcclxuICAgICAgICBjb3JyZXNwb25kZW5jZU51bWJlcjogJ09MRC1OVU0nLFxyXG4gICAgICAgIHJlY2lwaWVudHM6IFt7IHJlY2lwaWVudFR5cGU6ICdUTycsIHJlY2lwaWVudE9yZ2FuaXphdGlvbklkOiA5OSB9XSxcclxuICAgICAgfTtcclxuICAgICAgamVzdFxyXG4gICAgICAgIC5zcHlPbihjb3JyZXNwb25kZW5jZVJlcG8sICdmaW5kT25lJylcclxuICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWUobW9ja0NvcnIgYXMgdW5rbm93biBhcyBDb3JyZXNwb25kZW5jZSk7XHJcblxyXG4gICAgICBjb25zdCB1cGRhdGVEdG86IFVwZGF0ZUNvcnJlc3BvbmRlbmNlRHRvID0ge1xyXG4gICAgICAgIHByb2plY3RJZDogMSxcclxuICAgICAgICBkaXNjaXBsaW5lSWQ6IDMsXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBhd2FpdCBzZXJ2aWNlLnVwZGF0ZSgxLCB1cGRhdGVEdG8sIG1vY2tVc2VyKTtcclxuXHJcbiAgICAgIGV4cGVjdChcclxuICAgICAgICBudW1iZXJpbmdTZXJ2aWNlLnVwZGF0ZU51bWJlckZvckRyYWZ0IGFzIGplc3QuTW9ja1xyXG4gICAgICApLm5vdC50b0hhdmVCZWVuQ2FsbGVkKCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBpdCgnc2hvdWxkIHJlZ2VuZXJhdGUgbnVtYmVyIGlmIFByb2plY3QgSUQgY2hhbmdlcycsIGFzeW5jICgpID0+IHtcclxuICAgICAgY29uc3QgbW9ja1VzZXIgPSB7IGlkOiAxLCBwcmltYXJ5T3JnYW5pemF0aW9uSWQ6IDEwIH0gYXMgdW5rbm93biBhcyBVc2VyO1xyXG4gICAgICBjb25zdCBtb2NrUmV2aXNpb24gPSB7XHJcbiAgICAgICAgaWQ6IDEwMCxcclxuICAgICAgICBjb3JyZXNwb25kZW5jZUlkOiAxLFxyXG4gICAgICAgIGlzQ3VycmVudDogdHJ1ZSxcclxuICAgICAgICBzdGF0dXNJZDogNSxcclxuICAgICAgfTtcclxuICAgICAgamVzdFxyXG4gICAgICAgIC5zcHlPbihyZXZpc2lvblJlcG8sICdmaW5kT25lJylcclxuICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWUobW9ja1JldmlzaW9uIGFzIHVua25vd24gYXMgQ29ycmVzcG9uZGVuY2VSZXZpc2lvbik7XHJcblxyXG4gICAgICBjb25zdCBtb2NrQ29yciA9IHtcclxuICAgICAgICBpZDogMSxcclxuICAgICAgICBwcm9qZWN0SWQ6IDEsXHJcbiAgICAgICAgY29ycmVzcG9uZGVuY2VUeXBlSWQ6IDIsXHJcbiAgICAgICAgZGlzY2lwbGluZUlkOiAzLFxyXG4gICAgICAgIG9yaWdpbmF0b3JJZDogMTAsXHJcbiAgICAgICAgY29ycmVzcG9uZGVuY2VOdW1iZXI6ICdPTEQtTlVNJyxcclxuICAgICAgICByZWNpcGllbnRzOiBbeyByZWNpcGllbnRUeXBlOiAnVE8nLCByZWNpcGllbnRPcmdhbml6YXRpb25JZDogOTkgfV0sXHJcbiAgICAgIH07XHJcbiAgICAgIGplc3RcclxuICAgICAgICAuc3B5T24oY29ycmVzcG9uZGVuY2VSZXBvLCAnZmluZE9uZScpXHJcbiAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlKG1vY2tDb3JyIGFzIHVua25vd24gYXMgQ29ycmVzcG9uZGVuY2UpO1xyXG5cclxuICAgICAgY29uc3QgdXBkYXRlRHRvOiBVcGRhdGVDb3JyZXNwb25kZW5jZUR0byA9IHtcclxuICAgICAgICBwcm9qZWN0SWQ6IDIsXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBjb25zdCB1dWlkUmVzb2x2ZXIgPVxyXG4gICAgICAgIHRlc3RpbmdNb2R1bGUuZ2V0PFV1aWRSZXNvbHZlclNlcnZpY2U+KFV1aWRSZXNvbHZlclNlcnZpY2UpO1xyXG4gICAgICAodXVpZFJlc29sdmVyLnJlc29sdmVQcm9qZWN0SWQgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSgyKTtcclxuXHJcbiAgICAgIGF3YWl0IHNlcnZpY2UudXBkYXRlKDEsIHVwZGF0ZUR0bywgbW9ja1VzZXIpO1xyXG5cclxuICAgICAgZXhwZWN0KFxyXG4gICAgICAgIG51bWJlcmluZ1NlcnZpY2UudXBkYXRlTnVtYmVyRm9yRHJhZnQgYXMgamVzdC5Nb2NrXHJcbiAgICAgICkudG9IYXZlQmVlbkNhbGxlZCgpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgaXQoJ3Nob3VsZCByZWdlbmVyYXRlIG51bWJlciBpZiBEb2N1bWVudCBUeXBlIGNoYW5nZXMnLCBhc3luYyAoKSA9PiB7XHJcbiAgICAgIGNvbnN0IG1vY2tVc2VyID0geyBpZDogMSwgcHJpbWFyeU9yZ2FuaXphdGlvbklkOiAxMCB9IGFzIHVua25vd24gYXMgVXNlcjtcclxuICAgICAgY29uc3QgbW9ja1JldmlzaW9uID0ge1xyXG4gICAgICAgIGlkOiAxMDAsXHJcbiAgICAgICAgY29ycmVzcG9uZGVuY2VJZDogMSxcclxuICAgICAgICBpc0N1cnJlbnQ6IHRydWUsXHJcbiAgICAgICAgc3RhdHVzSWQ6IDUsXHJcbiAgICAgIH07XHJcbiAgICAgIGplc3RcclxuICAgICAgICAuc3B5T24ocmV2aXNpb25SZXBvLCAnZmluZE9uZScpXHJcbiAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlKG1vY2tSZXZpc2lvbiBhcyB1bmtub3duIGFzIENvcnJlc3BvbmRlbmNlUmV2aXNpb24pO1xyXG5cclxuICAgICAgY29uc3QgbW9ja0NvcnIgPSB7XHJcbiAgICAgICAgaWQ6IDEsXHJcbiAgICAgICAgcHJvamVjdElkOiAxLFxyXG4gICAgICAgIGNvcnJlc3BvbmRlbmNlVHlwZUlkOiAyLFxyXG4gICAgICAgIGRpc2NpcGxpbmVJZDogMyxcclxuICAgICAgICBvcmlnaW5hdG9ySWQ6IDEwLFxyXG4gICAgICAgIGNvcnJlc3BvbmRlbmNlTnVtYmVyOiAnT0xELU5VTScsXHJcbiAgICAgICAgcmVjaXBpZW50czogW3sgcmVjaXBpZW50VHlwZTogJ1RPJywgcmVjaXBpZW50T3JnYW5pemF0aW9uSWQ6IDk5IH1dLFxyXG4gICAgICB9O1xyXG4gICAgICBqZXN0XHJcbiAgICAgICAgLnNweU9uKGNvcnJlc3BvbmRlbmNlUmVwbywgJ2ZpbmRPbmUnKVxyXG4gICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZShtb2NrQ29yciBhcyB1bmtub3duIGFzIENvcnJlc3BvbmRlbmNlKTtcclxuXHJcbiAgICAgIGNvbnN0IHVwZGF0ZUR0bzogVXBkYXRlQ29ycmVzcG9uZGVuY2VEdG8gPSB7XHJcbiAgICAgICAgdHlwZUlkOiA5OTksXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBjb25zdCB0eXBlUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2VUeXBlPj4oXHJcbiAgICAgICAgZ2V0UmVwb3NpdG9yeVRva2VuKENvcnJlc3BvbmRlbmNlVHlwZSlcclxuICAgICAgKTtcclxuICAgICAgKHR5cGVSZXBvLmZpbmRPbmUgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgaWQ6IDk5OSxcclxuICAgICAgICB0eXBlQ29kZTogJ05FVy1UWVBFJyxcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBhd2FpdCBzZXJ2aWNlLnVwZGF0ZSgxLCB1cGRhdGVEdG8sIG1vY2tVc2VyKTtcclxuXHJcbiAgICAgIGV4cGVjdChcclxuICAgICAgICBudW1iZXJpbmdTZXJ2aWNlLnVwZGF0ZU51bWJlckZvckRyYWZ0IGFzIGplc3QuTW9ja1xyXG4gICAgICApLnRvSGF2ZUJlZW5DYWxsZWQoKTtcclxuICAgIH0pO1xyXG5cclxuICAgIGl0KCdzaG91bGQgcmVnZW5lcmF0ZSBudW1iZXIgaWYgUmVjaXBpZW50IE9yZ2FuaXphdGlvbiBjaGFuZ2VzJywgYXN5bmMgKCkgPT4ge1xyXG4gICAgICBjb25zdCBtb2NrVXNlciA9IHsgaWQ6IDEsIHByaW1hcnlPcmdhbml6YXRpb25JZDogMTAgfSBhcyB1bmtub3duIGFzIFVzZXI7XHJcbiAgICAgIGNvbnN0IG1vY2tSZXZpc2lvbiA9IHtcclxuICAgICAgICBpZDogMTAwLFxyXG4gICAgICAgIGNvcnJlc3BvbmRlbmNlSWQ6IDEsXHJcbiAgICAgICAgaXNDdXJyZW50OiB0cnVlLFxyXG4gICAgICAgIHN0YXR1c0lkOiA1LFxyXG4gICAgICB9O1xyXG4gICAgICBqZXN0XHJcbiAgICAgICAgLnNweU9uKHJldmlzaW9uUmVwbywgJ2ZpbmRPbmUnKVxyXG4gICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZShtb2NrUmV2aXNpb24gYXMgdW5rbm93biBhcyBDb3JyZXNwb25kZW5jZVJldmlzaW9uKTtcclxuXHJcbiAgICAgIGNvbnN0IG1vY2tDb3JyID0ge1xyXG4gICAgICAgIGlkOiAxLFxyXG4gICAgICAgIHByb2plY3RJZDogMSxcclxuICAgICAgICBjb3JyZXNwb25kZW5jZVR5cGVJZDogMixcclxuICAgICAgICBkaXNjaXBsaW5lSWQ6IDMsXHJcbiAgICAgICAgb3JpZ2luYXRvcklkOiAxMCxcclxuICAgICAgICBjb3JyZXNwb25kZW5jZU51bWJlcjogJ09MRC1OVU0nLFxyXG4gICAgICAgIHJlY2lwaWVudHM6IFt7IHJlY2lwaWVudFR5cGU6ICdUTycsIHJlY2lwaWVudE9yZ2FuaXphdGlvbklkOiA5OSB9XSxcclxuICAgICAgfTtcclxuICAgICAgamVzdFxyXG4gICAgICAgIC5zcHlPbihjb3JyZXNwb25kZW5jZVJlcG8sICdmaW5kT25lJylcclxuICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWUobW9ja0NvcnIgYXMgdW5rbm93biBhcyBDb3JyZXNwb25kZW5jZSk7XHJcblxyXG4gICAgICAvLyBBY2Nlc3MgRGF0YVNvdXJjZSBtYW5hZ2VyIGZvciBtb2NraW5nXHJcbiAgICAgIG1vY2tEYXRhU291cmNlLm1hbmFnZXIuZmluZE9uZS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgaWQ6IDg4LFxyXG4gICAgICAgIG9yZ2FuaXphdGlvbkNvZGU6ICdORVctT1JHJyxcclxuICAgICAgfSBhcyB1bmtub3duIGFzIE9yZ2FuaXphdGlvbik7XHJcblxyXG4gICAgICBjb25zdCB1cGRhdGVEdG86IFVwZGF0ZUNvcnJlc3BvbmRlbmNlRHRvID0ge1xyXG4gICAgICAgIHJlY2lwaWVudHM6IFt7IHR5cGU6ICdUTycsIG9yZ2FuaXphdGlvbklkOiA4OCB9XSxcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGF3YWl0IHNlcnZpY2UudXBkYXRlKDEsIHVwZGF0ZUR0bywgbW9ja1VzZXIpO1xyXG5cclxuICAgICAgZXhwZWN0KFxyXG4gICAgICAgIG51bWJlcmluZ1NlcnZpY2UudXBkYXRlTnVtYmVyRm9yRHJhZnQgYXMgamVzdC5Nb2NrXHJcbiAgICAgICkudG9IYXZlQmVlbkNhbGxlZCgpO1xyXG4gICAgfSk7XHJcbiAgfSk7XHJcblxyXG4gIGRlc2NyaWJlKCdjcmVhdGUnLCAoKSA9PiB7XHJcbiAgICBpdCgnc2hvdWxkIGFsbG93IHN5c3RlbS5tYW5hZ2VfYWxsIHVzZXIgd2l0aG91dCBwcmltYXJ5T3JnYW5pemF0aW9uSWQgd2hlbiBvcmlnaW5hdG9ySWQgaXMgcHJvdmlkZWQnLCBhc3luYyAoKSA9PiB7XHJcbiAgICAgIGNvbnN0IG1vY2tVc2VyID0ge1xyXG4gICAgICAgIHVzZXJfaWQ6IDEsXHJcbiAgICAgICAgcHJpbWFyeU9yZ2FuaXphdGlvbklkOiBudWxsLFxyXG4gICAgICB9IGFzIHVua25vd24gYXMgVXNlcjtcclxuXHJcbiAgICAgIGNvbnN0IGNyZWF0ZUR0bzogQ3JlYXRlQ29ycmVzcG9uZGVuY2VEdG8gPSB7XHJcbiAgICAgICAgcHJvamVjdElkOiAncHJvamVjdC11dWlkJyxcclxuICAgICAgICB0eXBlSWQ6IDEsXHJcbiAgICAgICAgc3ViamVjdDogJ1Rlc3QgU3ViamVjdCcsXHJcbiAgICAgICAgb3JpZ2luYXRvcklkOiAnb3JpZ2luYXRvci11dWlkJyxcclxuICAgICAgICByZWNpcGllbnRzOiBbeyBvcmdhbml6YXRpb25JZDogJ3JlY2lwaWVudC11dWlkJywgdHlwZTogJ1RPJyB9XSxcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGNvbnN0IHVzZXJTZXJ2aWNlID0gdGVzdGluZ01vZHVsZS5nZXQ8VXNlclNlcnZpY2U+KFVzZXJTZXJ2aWNlKTtcclxuICAgICAgY29uc3QgdHlwZVJlcG8gPSB0ZXN0aW5nTW9kdWxlLmdldDxSZXBvc2l0b3J5PENvcnJlc3BvbmRlbmNlVHlwZT4+KFxyXG4gICAgICAgIGdldFJlcG9zaXRvcnlUb2tlbihDb3JyZXNwb25kZW5jZVR5cGUpXHJcbiAgICAgICk7XHJcbiAgICAgIGNvbnN0IHN0YXR1c1JlcG8gPSB0ZXN0aW5nTW9kdWxlLmdldDxSZXBvc2l0b3J5PENvcnJlc3BvbmRlbmNlU3RhdHVzPj4oXHJcbiAgICAgICAgZ2V0UmVwb3NpdG9yeVRva2VuKENvcnJlc3BvbmRlbmNlU3RhdHVzKVxyXG4gICAgICApO1xyXG4gICAgICBjb25zdCB1dWlkUmVzb2x2ZXIgPVxyXG4gICAgICAgIHRlc3RpbmdNb2R1bGUuZ2V0PFV1aWRSZXNvbHZlclNlcnZpY2U+KFV1aWRSZXNvbHZlclNlcnZpY2UpO1xyXG5cclxuICAgICAgKHVzZXJTZXJ2aWNlLmZpbmRPbmUgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgdXNlcl9pZDogMSxcclxuICAgICAgICBwcmltYXJ5T3JnYW5pemF0aW9uSWQ6IG51bGwsXHJcbiAgICAgIH0pO1xyXG4gICAgICAodXNlclNlcnZpY2UuZ2V0VXNlclBlcm1pc3Npb25zIGFzIGplc3QuTW9jaykubW9ja1Jlc29sdmVkVmFsdWUoW1xyXG4gICAgICAgICdzeXN0ZW0ubWFuYWdlX2FsbCcsXHJcbiAgICAgIF0pO1xyXG5cclxuICAgICAgKHV1aWRSZXNvbHZlci5yZXNvbHZlUHJvamVjdElkIGFzIGplc3QuTW9jaykubW9ja1Jlc29sdmVkVmFsdWUoMTAwKTtcclxuICAgICAgKHV1aWRSZXNvbHZlci5yZXNvbHZlT3JnYW5pemF0aW9uSWQgYXMgamVzdC5Nb2NrKS5tb2NrSW1wbGVtZW50YXRpb24oXHJcbiAgICAgICAgKHZhbHVlOiBudW1iZXIgfCBzdHJpbmcpID0+IHtcclxuICAgICAgICAgIGlmICh2YWx1ZSA9PT0gJ29yaWdpbmF0b3ItdXVpZCcpIHJldHVybiAxMDtcclxuICAgICAgICAgIGlmICh2YWx1ZSA9PT0gJ3JlY2lwaWVudC11dWlkJykgcmV0dXJuIDIwO1xyXG4gICAgICAgICAgcmV0dXJuIDA7XHJcbiAgICAgICAgfVxyXG4gICAgICApO1xyXG5cclxuICAgICAgKHR5cGVSZXBvLmZpbmRPbmUgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgaWQ6IDEsXHJcbiAgICAgICAgdHlwZUNvZGU6ICdMVFInLFxyXG4gICAgICB9KTtcclxuICAgICAgKHN0YXR1c1JlcG8uZmluZE9uZSBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKHtcclxuICAgICAgICBpZDogMSxcclxuICAgICAgICBzdGF0dXNDb2RlOiAnRFJBRlQnLFxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIChudW1iZXJpbmdTZXJ2aWNlLmdlbmVyYXRlTmV4dE51bWJlciBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKHtcclxuICAgICAgICBudW1iZXI6ICdET0MtMDAxJyxcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBtb2NrRGF0YVNvdXJjZS5tYW5hZ2VyLmZpbmRPbmVcclxuICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKHsgaWQ6IDEwLCBvcmdhbml6YXRpb25Db2RlOiAnT1JHJyB9KVxyXG4gICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoeyBpZDogMjAsIG9yZ2FuaXphdGlvbkNvZGU6ICdSRUMnIH0pO1xyXG5cclxuICAgICAgY29uc3QgcXVlcnlSdW5uZXIgPSB7XHJcbiAgICAgICAgY29ubmVjdDogamVzdC5mbigpLFxyXG4gICAgICAgIHN0YXJ0VHJhbnNhY3Rpb246IGplc3QuZm4oKSxcclxuICAgICAgICBjb21taXRUcmFuc2FjdGlvbjogamVzdC5mbigpLFxyXG4gICAgICAgIHJvbGxiYWNrVHJhbnNhY3Rpb246IGplc3QuZm4oKSxcclxuICAgICAgICByZWxlYXNlOiBqZXN0LmZuKCksXHJcbiAgICAgICAgbWFuYWdlcjoge1xyXG4gICAgICAgICAgY3JlYXRlOiBqZXN0LmZuKFxyXG4gICAgICAgICAgICAoX2VudGl0eTogdW5rbm93biwgcGF5bG9hZDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IHBheWxvYWRcclxuICAgICAgICAgICksXHJcbiAgICAgICAgICBzYXZlOiBqZXN0XHJcbiAgICAgICAgICAgIC5mbigpXHJcbiAgICAgICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoeyBpZDogOTk5LCBwdWJsaWNJZDogJ2NvcnItdXVpZCcgfSlcclxuICAgICAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7IGlkOiAxMDAwIH0pXHJcbiAgICAgICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoW10pLFxyXG4gICAgICAgICAgZmluZE9uZTogamVzdC5mbigpLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH07XHJcblxyXG4gICAgICAobW9ja0RhdGFTb3VyY2UuY3JlYXRlUXVlcnlSdW5uZXIgYXMgamVzdC5Nb2NrKS5tb2NrUmV0dXJuVmFsdWUoXHJcbiAgICAgICAgcXVlcnlSdW5uZXJcclxuICAgICAgKTtcclxuXHJcbiAgICAgIGF3YWl0IHNlcnZpY2UuY3JlYXRlKGNyZWF0ZUR0bywgbW9ja1VzZXIpO1xyXG5cclxuICAgICAgZXhwZWN0KHF1ZXJ5UnVubmVyLm1hbmFnZXIuY3JlYXRlKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcclxuICAgICAgICBDb3JyZXNwb25kZW5jZSxcclxuICAgICAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7IG9yaWdpbmF0b3JJZDogMTAgfSlcclxuICAgICAgKTtcclxuICAgIH0pO1xyXG5cclxuICAgIGl0KCdzaG91bGQgc2V0IHJldmlzaW9uTGFiZWwgdG8gXCJBXCIgZm9yIFJGQSB0eXBlJywgYXN5bmMgKCkgPT4ge1xyXG4gICAgICBjb25zdCBtb2NrVXNlciA9IHtcclxuICAgICAgICB1c2VyX2lkOiAxLFxyXG4gICAgICAgIHByaW1hcnlPcmdhbml6YXRpb25JZDogMTAsXHJcbiAgICAgIH0gYXMgdW5rbm93biBhcyBVc2VyO1xyXG5cclxuICAgICAgY29uc3QgY3JlYXRlRHRvOiBDcmVhdGVDb3JyZXNwb25kZW5jZUR0byA9IHtcclxuICAgICAgICBwcm9qZWN0SWQ6ICdwcm9qZWN0LXV1aWQnLFxyXG4gICAgICAgIHR5cGVJZDogMSxcclxuICAgICAgICBzdWJqZWN0OiAnVGVzdCBTdWJqZWN0JyxcclxuICAgICAgICByZWNpcGllbnRzOiBbeyBvcmdhbml6YXRpb25JZDogJ3JlY2lwaWVudC11dWlkJywgdHlwZTogJ1RPJyB9XSxcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGNvbnN0IHR5cGVSZXBvID0gdGVzdGluZ01vZHVsZS5nZXQ8UmVwb3NpdG9yeTxDb3JyZXNwb25kZW5jZVR5cGU+PihcclxuICAgICAgICBnZXRSZXBvc2l0b3J5VG9rZW4oQ29ycmVzcG9uZGVuY2VUeXBlKVxyXG4gICAgICApO1xyXG4gICAgICBjb25zdCBzdGF0dXNSZXBvID0gdGVzdGluZ01vZHVsZS5nZXQ8UmVwb3NpdG9yeTxDb3JyZXNwb25kZW5jZVN0YXR1cz4+KFxyXG4gICAgICAgIGdldFJlcG9zaXRvcnlUb2tlbihDb3JyZXNwb25kZW5jZVN0YXR1cylcclxuICAgICAgKTtcclxuICAgICAgY29uc3QgdXVpZFJlc29sdmVyID1cclxuICAgICAgICB0ZXN0aW5nTW9kdWxlLmdldDxVdWlkUmVzb2x2ZXJTZXJ2aWNlPihVdWlkUmVzb2x2ZXJTZXJ2aWNlKTtcclxuXHJcbiAgICAgICh1dWlkUmVzb2x2ZXIucmVzb2x2ZVByb2plY3RJZCBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKDEwMCk7XHJcbiAgICAgICh1dWlkUmVzb2x2ZXIucmVzb2x2ZU9yZ2FuaXphdGlvbklkIGFzIGplc3QuTW9jaykubW9ja1Jlc29sdmVkVmFsdWUoMjApO1xyXG5cclxuICAgICAgKHR5cGVSZXBvLmZpbmRPbmUgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgaWQ6IDEsXHJcbiAgICAgICAgdHlwZUNvZGU6ICdSRkEnLFxyXG4gICAgICB9KTtcclxuICAgICAgKHN0YXR1c1JlcG8uZmluZE9uZSBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKHtcclxuICAgICAgICBpZDogMSxcclxuICAgICAgICBzdGF0dXNDb2RlOiAnRFJBRlQnLFxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIChudW1iZXJpbmdTZXJ2aWNlLmdlbmVyYXRlTmV4dE51bWJlciBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKHtcclxuICAgICAgICBudW1iZXI6ICdET0MtMDAxJyxcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBtb2NrRGF0YVNvdXJjZS5tYW5hZ2VyLmZpbmRPbmVcclxuICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKHsgaWQ6IDEwLCBvcmdhbml6YXRpb25Db2RlOiAnT1JHJyB9KVxyXG4gICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoeyBpZDogMjAsIG9yZ2FuaXphdGlvbkNvZGU6ICdSRUMnIH0pO1xyXG5cclxuICAgICAgY29uc3QgcXVlcnlSdW5uZXIgPSB7XHJcbiAgICAgICAgY29ubmVjdDogamVzdC5mbigpLFxyXG4gICAgICAgIHN0YXJ0VHJhbnNhY3Rpb246IGplc3QuZm4oKSxcclxuICAgICAgICBjb21taXRUcmFuc2FjdGlvbjogamVzdC5mbigpLFxyXG4gICAgICAgIHJvbGxiYWNrVHJhbnNhY3Rpb246IGplc3QuZm4oKSxcclxuICAgICAgICByZWxlYXNlOiBqZXN0LmZuKCksXHJcbiAgICAgICAgbWFuYWdlcjoge1xyXG4gICAgICAgICAgY3JlYXRlOiBqZXN0LmZuKFxyXG4gICAgICAgICAgICAoX2VudGl0eTogdW5rbm93biwgcGF5bG9hZDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IHBheWxvYWRcclxuICAgICAgICAgICksXHJcbiAgICAgICAgICBzYXZlOiBqZXN0XHJcbiAgICAgICAgICAgIC5mbigpXHJcbiAgICAgICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoeyBpZDogOTk5LCBwdWJsaWNJZDogJ2NvcnItdXVpZCcgfSlcclxuICAgICAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7IGlkOiAxMDAwIH0pXHJcbiAgICAgICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoW10pLFxyXG4gICAgICAgICAgZmluZE9uZTogamVzdC5mbigpLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH07XHJcblxyXG4gICAgICAobW9ja0RhdGFTb3VyY2UuY3JlYXRlUXVlcnlSdW5uZXIgYXMgamVzdC5Nb2NrKS5tb2NrUmV0dXJuVmFsdWUoXHJcbiAgICAgICAgcXVlcnlSdW5uZXJcclxuICAgICAgKTtcclxuXHJcbiAgICAgIGF3YWl0IHNlcnZpY2UuY3JlYXRlKGNyZWF0ZUR0bywgbW9ja1VzZXIpO1xyXG5cclxuICAgICAgZXhwZWN0KHF1ZXJ5UnVubmVyLm1hbmFnZXIuY3JlYXRlKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChcclxuICAgICAgICBDb3JyZXNwb25kZW5jZVJldmlzaW9uLFxyXG4gICAgICAgIGV4cGVjdC5vYmplY3RDb250YWluaW5nKHsgcmV2aXNpb25MYWJlbDogJ0EnIH0pXHJcbiAgICAgICk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBpdCgnc2hvdWxkIHNldCByZXZpc2lvbkxhYmVsIHRvIFwiQVwiIGZvciBSRkkgdHlwZScsIGFzeW5jICgpID0+IHtcclxuICAgICAgY29uc3QgbW9ja1VzZXIgPSB7XHJcbiAgICAgICAgdXNlcl9pZDogMSxcclxuICAgICAgICBwcmltYXJ5T3JnYW5pemF0aW9uSWQ6IDEwLFxyXG4gICAgICB9IGFzIHVua25vd24gYXMgVXNlcjtcclxuXHJcbiAgICAgIGNvbnN0IGNyZWF0ZUR0bzogQ3JlYXRlQ29ycmVzcG9uZGVuY2VEdG8gPSB7XHJcbiAgICAgICAgcHJvamVjdElkOiAncHJvamVjdC11dWlkJyxcclxuICAgICAgICB0eXBlSWQ6IDEsXHJcbiAgICAgICAgc3ViamVjdDogJ1Rlc3QgU3ViamVjdCcsXHJcbiAgICAgICAgcmVjaXBpZW50czogW3sgb3JnYW5pemF0aW9uSWQ6ICdyZWNpcGllbnQtdXVpZCcsIHR5cGU6ICdUTycgfV0sXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBjb25zdCB0eXBlUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2VUeXBlPj4oXHJcbiAgICAgICAgZ2V0UmVwb3NpdG9yeVRva2VuKENvcnJlc3BvbmRlbmNlVHlwZSlcclxuICAgICAgKTtcclxuICAgICAgY29uc3Qgc3RhdHVzUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2VTdGF0dXM+PihcclxuICAgICAgICBnZXRSZXBvc2l0b3J5VG9rZW4oQ29ycmVzcG9uZGVuY2VTdGF0dXMpXHJcbiAgICAgICk7XHJcbiAgICAgIGNvbnN0IHV1aWRSZXNvbHZlciA9XHJcbiAgICAgICAgdGVzdGluZ01vZHVsZS5nZXQ8VXVpZFJlc29sdmVyU2VydmljZT4oVXVpZFJlc29sdmVyU2VydmljZSk7XHJcblxyXG4gICAgICAodXVpZFJlc29sdmVyLnJlc29sdmVQcm9qZWN0SWQgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSgxMDApO1xyXG4gICAgICAodXVpZFJlc29sdmVyLnJlc29sdmVPcmdhbml6YXRpb25JZCBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKDIwKTtcclxuXHJcbiAgICAgICh0eXBlUmVwby5maW5kT25lIGFzIGplc3QuTW9jaykubW9ja1Jlc29sdmVkVmFsdWUoe1xyXG4gICAgICAgIGlkOiAxLFxyXG4gICAgICAgIHR5cGVDb2RlOiAnUkZJJyxcclxuICAgICAgfSk7XHJcbiAgICAgIChzdGF0dXNSZXBvLmZpbmRPbmUgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgaWQ6IDEsXHJcbiAgICAgICAgc3RhdHVzQ29kZTogJ0RSQUZUJyxcclxuICAgICAgfSk7XHJcblxyXG4gICAgICAobnVtYmVyaW5nU2VydmljZS5nZW5lcmF0ZU5leHROdW1iZXIgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgbnVtYmVyOiAnRE9DLTAwMScsXHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgbW9ja0RhdGFTb3VyY2UubWFuYWdlci5maW5kT25lXHJcbiAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7IGlkOiAxMCwgb3JnYW5pemF0aW9uQ29kZTogJ09SRycgfSlcclxuICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKHsgaWQ6IDIwLCBvcmdhbml6YXRpb25Db2RlOiAnUkVDJyB9KTtcclxuXHJcbiAgICAgIGNvbnN0IHF1ZXJ5UnVubmVyID0ge1xyXG4gICAgICAgIGNvbm5lY3Q6IGplc3QuZm4oKSxcclxuICAgICAgICBzdGFydFRyYW5zYWN0aW9uOiBqZXN0LmZuKCksXHJcbiAgICAgICAgY29tbWl0VHJhbnNhY3Rpb246IGplc3QuZm4oKSxcclxuICAgICAgICByb2xsYmFja1RyYW5zYWN0aW9uOiBqZXN0LmZuKCksXHJcbiAgICAgICAgcmVsZWFzZTogamVzdC5mbigpLFxyXG4gICAgICAgIG1hbmFnZXI6IHtcclxuICAgICAgICAgIGNyZWF0ZTogamVzdC5mbihcclxuICAgICAgICAgICAgKF9lbnRpdHk6IHVua25vd24sIHBheWxvYWQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PiBwYXlsb2FkXHJcbiAgICAgICAgICApLFxyXG4gICAgICAgICAgc2F2ZTogamVzdFxyXG4gICAgICAgICAgICAuZm4oKVxyXG4gICAgICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKHsgaWQ6IDk5OSwgcHVibGljSWQ6ICdjb3JyLXV1aWQnIH0pXHJcbiAgICAgICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoeyBpZDogMTAwMCB9KVxyXG4gICAgICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKFtdKSxcclxuICAgICAgICAgIGZpbmRPbmU6IGplc3QuZm4oKSxcclxuICAgICAgICB9LFxyXG4gICAgICB9O1xyXG5cclxuICAgICAgKG1vY2tEYXRhU291cmNlLmNyZWF0ZVF1ZXJ5UnVubmVyIGFzIGplc3QuTW9jaykubW9ja1JldHVyblZhbHVlKFxyXG4gICAgICAgIHF1ZXJ5UnVubmVyXHJcbiAgICAgICk7XHJcblxyXG4gICAgICBhd2FpdCBzZXJ2aWNlLmNyZWF0ZShjcmVhdGVEdG8sIG1vY2tVc2VyKTtcclxuXHJcbiAgICAgIGV4cGVjdChxdWVyeVJ1bm5lci5tYW5hZ2VyLmNyZWF0ZSkudG9IYXZlQmVlbkNhbGxlZFdpdGgoXHJcbiAgICAgICAgQ29ycmVzcG9uZGVuY2VSZXZpc2lvbixcclxuICAgICAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7IHJldmlzaW9uTGFiZWw6ICdBJyB9KVxyXG4gICAgICApO1xyXG4gICAgfSk7XHJcblxyXG4gICAgaXQoJ3Nob3VsZCBzZXQgcmV2aXNpb25MYWJlbCB0byBudWxsIGZvciBMRVRURVIgdHlwZScsIGFzeW5jICgpID0+IHtcclxuICAgICAgY29uc3QgbW9ja1VzZXIgPSB7XHJcbiAgICAgICAgdXNlcl9pZDogMSxcclxuICAgICAgICBwcmltYXJ5T3JnYW5pemF0aW9uSWQ6IDEwLFxyXG4gICAgICB9IGFzIHVua25vd24gYXMgVXNlcjtcclxuXHJcbiAgICAgIGNvbnN0IGNyZWF0ZUR0bzogQ3JlYXRlQ29ycmVzcG9uZGVuY2VEdG8gPSB7XHJcbiAgICAgICAgcHJvamVjdElkOiAncHJvamVjdC11dWlkJyxcclxuICAgICAgICB0eXBlSWQ6IDEsXHJcbiAgICAgICAgc3ViamVjdDogJ1Rlc3QgU3ViamVjdCcsXHJcbiAgICAgICAgcmVjaXBpZW50czogW3sgb3JnYW5pemF0aW9uSWQ6ICdyZWNpcGllbnQtdXVpZCcsIHR5cGU6ICdUTycgfV0sXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBjb25zdCB0eXBlUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2VUeXBlPj4oXHJcbiAgICAgICAgZ2V0UmVwb3NpdG9yeVRva2VuKENvcnJlc3BvbmRlbmNlVHlwZSlcclxuICAgICAgKTtcclxuICAgICAgY29uc3Qgc3RhdHVzUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2VTdGF0dXM+PihcclxuICAgICAgICBnZXRSZXBvc2l0b3J5VG9rZW4oQ29ycmVzcG9uZGVuY2VTdGF0dXMpXHJcbiAgICAgICk7XHJcbiAgICAgIGNvbnN0IHV1aWRSZXNvbHZlciA9XHJcbiAgICAgICAgdGVzdGluZ01vZHVsZS5nZXQ8VXVpZFJlc29sdmVyU2VydmljZT4oVXVpZFJlc29sdmVyU2VydmljZSk7XHJcblxyXG4gICAgICAodXVpZFJlc29sdmVyLnJlc29sdmVQcm9qZWN0SWQgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSgxMDApO1xyXG4gICAgICAodXVpZFJlc29sdmVyLnJlc29sdmVPcmdhbml6YXRpb25JZCBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKDIwKTtcclxuXHJcbiAgICAgICh0eXBlUmVwby5maW5kT25lIGFzIGplc3QuTW9jaykubW9ja1Jlc29sdmVkVmFsdWUoe1xyXG4gICAgICAgIGlkOiAxLFxyXG4gICAgICAgIHR5cGVDb2RlOiAnTEVUVEVSJyxcclxuICAgICAgfSk7XHJcbiAgICAgIChzdGF0dXNSZXBvLmZpbmRPbmUgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgaWQ6IDEsXHJcbiAgICAgICAgc3RhdHVzQ29kZTogJ0RSQUZUJyxcclxuICAgICAgfSk7XHJcblxyXG4gICAgICAobnVtYmVyaW5nU2VydmljZS5nZW5lcmF0ZU5leHROdW1iZXIgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7XHJcbiAgICAgICAgbnVtYmVyOiAnRE9DLTAwMScsXHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgbW9ja0RhdGFTb3VyY2UubWFuYWdlci5maW5kT25lXHJcbiAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7IGlkOiAxMCwgb3JnYW5pemF0aW9uQ29kZTogJ09SRycgfSlcclxuICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKHsgaWQ6IDIwLCBvcmdhbml6YXRpb25Db2RlOiAnUkVDJyB9KTtcclxuXHJcbiAgICAgIGNvbnN0IHF1ZXJ5UnVubmVyID0ge1xyXG4gICAgICAgIGNvbm5lY3Q6IGplc3QuZm4oKSxcclxuICAgICAgICBzdGFydFRyYW5zYWN0aW9uOiBqZXN0LmZuKCksXHJcbiAgICAgICAgY29tbWl0VHJhbnNhY3Rpb246IGplc3QuZm4oKSxcclxuICAgICAgICByb2xsYmFja1RyYW5zYWN0aW9uOiBqZXN0LmZuKCksXHJcbiAgICAgICAgcmVsZWFzZTogamVzdC5mbigpLFxyXG4gICAgICAgIG1hbmFnZXI6IHtcclxuICAgICAgICAgIGNyZWF0ZTogamVzdC5mbihcclxuICAgICAgICAgICAgKF9lbnRpdHk6IHVua25vd24sIHBheWxvYWQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PiBwYXlsb2FkXHJcbiAgICAgICAgICApLFxyXG4gICAgICAgICAgc2F2ZTogamVzdFxyXG4gICAgICAgICAgICAuZm4oKVxyXG4gICAgICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKHsgaWQ6IDk5OSwgcHVibGljSWQ6ICdjb3JyLXV1aWQnIH0pXHJcbiAgICAgICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoeyBpZDogMTAwMCB9KVxyXG4gICAgICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKFtdKSxcclxuICAgICAgICAgIGZpbmRPbmU6IGplc3QuZm4oKSxcclxuICAgICAgICB9LFxyXG4gICAgICB9O1xyXG5cclxuICAgICAgKG1vY2tEYXRhU291cmNlLmNyZWF0ZVF1ZXJ5UnVubmVyIGFzIGplc3QuTW9jaykubW9ja1JldHVyblZhbHVlKFxyXG4gICAgICAgIHF1ZXJ5UnVubmVyXHJcbiAgICAgICk7XHJcblxyXG4gICAgICBhd2FpdCBzZXJ2aWNlLmNyZWF0ZShjcmVhdGVEdG8sIG1vY2tVc2VyKTtcclxuXHJcbiAgICAgIGV4cGVjdChxdWVyeVJ1bm5lci5tYW5hZ2VyLmNyZWF0ZSkudG9IYXZlQmVlbkNhbGxlZFdpdGgoXHJcbiAgICAgICAgQ29ycmVzcG9uZGVuY2VSZXZpc2lvbixcclxuICAgICAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7IHJldmlzaW9uTGFiZWw6IHVuZGVmaW5lZCB9KVxyXG4gICAgICApO1xyXG4gICAgfSk7XHJcblxyXG4gICAgaXQoJ3Nob3VsZCBzZXQgcmV2aXNpb25MYWJlbCB0byB1bmRlZmluZWQgZm9yIE1FTU8gdHlwZScsIGFzeW5jICgpID0+IHtcclxuICAgICAgY29uc3QgbW9ja1VzZXIgPSB7XHJcbiAgICAgICAgdXNlcl9pZDogMSxcclxuICAgICAgICBwcmltYXJ5T3JnYW5pemF0aW9uSWQ6IDEwLFxyXG4gICAgICB9IGFzIHVua25vd24gYXMgVXNlcjtcclxuXHJcbiAgICAgIGNvbnN0IGNyZWF0ZUR0bzogQ3JlYXRlQ29ycmVzcG9uZGVuY2VEdG8gPSB7XHJcbiAgICAgICAgcHJvamVjdElkOiAncHJvamVjdC11dWlkJyxcclxuICAgICAgICB0eXBlSWQ6IDEsXHJcbiAgICAgICAgc3ViamVjdDogJ1Rlc3QgU3ViamVjdCcsXHJcbiAgICAgICAgcmVjaXBpZW50czogW3sgb3JnYW5pemF0aW9uSWQ6ICdyZWNpcGllbnQtdXVpZCcsIHR5cGU6ICdUTycgfV0sXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBjb25zdCB0eXBlUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2VUeXBlPj4oXHJcbiAgICAgICAgZ2V0UmVwb3NpdG9yeVRva2VuKENvcnJlc3BvbmRlbmNlVHlwZSlcclxuICAgICAgKTtcclxuICAgICAgY29uc3Qgc3RhdHVzUmVwbyA9IHRlc3RpbmdNb2R1bGUuZ2V0PFJlcG9zaXRvcnk8Q29ycmVzcG9uZGVuY2VTdGF0dXM+PihcclxuICAgICAgICBnZXRSZXBvc2l0b3J5VG9rZW4oQ29ycmVzcG9uZGVuY2VTdGF0dXMpXHJcbiAgICAgICk7XHJcbiAgICAgIGNvbnN0IHV1aWRSZXNvbHZlciA9XHJcbiAgICAgICAgdGVzdGluZ01vZHVsZS5nZXQ8VXVpZFJlc29sdmVyU2VydmljZT4oVXVpZFJlc29sdmVyU2VydmljZSk7XHJcblxyXG4gICAgICAodXVpZFJlc29sdmVyLnJlc29sdmVQcm9qZWN0SWQgYXMgamVzdC5Nb2NrKS5tb2NrUmVzb2x2ZWRWYWx1ZSgxMDApO1xyXG4gICAgICAodXVpZFJlc29sdmVyLnJlc29sdmVPcmdhbml6YXRpb25JZCBhcyBqZXN0Lk1vY2spLm1vY2tSZXNvbHZlZFZhbHVlKDIwKTtcclxuXHJcbiAgICAgICh0eXBlUmVwby5maW5kT25lIGFzIGplc3QuTW9jaykubW9ja1Jlc29sdmVkVmFsdWUoe1xyXG4gICAgICAgIGlkOiAxLFxyXG4gICAgICAgIHR5cGVDb2RlOiAnTUVNTycsXHJcbiAgICAgIH0pO1xyXG4gICAgICAoc3RhdHVzUmVwby5maW5kT25lIGFzIGplc3QuTW9jaykubW9ja1Jlc29sdmVkVmFsdWUoe1xyXG4gICAgICAgIGlkOiAxLFxyXG4gICAgICAgIHN0YXR1c0NvZGU6ICdEUkFGVCcsXHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgKG51bWJlcmluZ1NlcnZpY2UuZ2VuZXJhdGVOZXh0TnVtYmVyIGFzIGplc3QuTW9jaykubW9ja1Jlc29sdmVkVmFsdWUoe1xyXG4gICAgICAgIG51bWJlcjogJ0RPQy0wMDEnLFxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIG1vY2tEYXRhU291cmNlLm1hbmFnZXIuZmluZE9uZVxyXG4gICAgICAgIC5tb2NrUmVzb2x2ZWRWYWx1ZU9uY2UoeyBpZDogMTAsIG9yZ2FuaXphdGlvbkNvZGU6ICdPUkcnIH0pXHJcbiAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7IGlkOiAyMCwgb3JnYW5pemF0aW9uQ29kZTogJ1JFQycgfSk7XHJcblxyXG4gICAgICBjb25zdCBxdWVyeVJ1bm5lciA9IHtcclxuICAgICAgICBjb25uZWN0OiBqZXN0LmZuKCksXHJcbiAgICAgICAgc3RhcnRUcmFuc2FjdGlvbjogamVzdC5mbigpLFxyXG4gICAgICAgIGNvbW1pdFRyYW5zYWN0aW9uOiBqZXN0LmZuKCksXHJcbiAgICAgICAgcm9sbGJhY2tUcmFuc2FjdGlvbjogamVzdC5mbigpLFxyXG4gICAgICAgIHJlbGVhc2U6IGplc3QuZm4oKSxcclxuICAgICAgICBtYW5hZ2VyOiB7XHJcbiAgICAgICAgICBjcmVhdGU6IGplc3QuZm4oXHJcbiAgICAgICAgICAgIChfZW50aXR5OiB1bmtub3duLCBwYXlsb2FkOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgPT4gcGF5bG9hZFxyXG4gICAgICAgICAgKSxcclxuICAgICAgICAgIHNhdmU6IGplc3RcclxuICAgICAgICAgICAgLmZuKClcclxuICAgICAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlT25jZSh7IGlkOiA5OTksIHB1YmxpY0lkOiAnY29yci11dWlkJyB9KVxyXG4gICAgICAgICAgICAubW9ja1Jlc29sdmVkVmFsdWVPbmNlKHsgaWQ6IDEwMDAgfSlcclxuICAgICAgICAgICAgLm1vY2tSZXNvbHZlZFZhbHVlT25jZShbXSksXHJcbiAgICAgICAgICBmaW5kT25lOiBqZXN0LmZuKCksXHJcbiAgICAgICAgfSxcclxuICAgICAgfTtcclxuXHJcbiAgICAgIChtb2NrRGF0YVNvdXJjZS5jcmVhdGVRdWVyeVJ1bm5lciBhcyBqZXN0Lk1vY2spLm1vY2tSZXR1cm5WYWx1ZShcclxuICAgICAgICBxdWVyeVJ1bm5lclxyXG4gICAgICApO1xyXG5cclxuICAgICAgYXdhaXQgc2VydmljZS5jcmVhdGUoY3JlYXRlRHRvLCBtb2NrVXNlcik7XHJcblxyXG4gICAgICBleHBlY3QocXVlcnlSdW5uZXIubWFuYWdlci5jcmVhdGUpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKFxyXG4gICAgICAgIENvcnJlc3BvbmRlbmNlUmV2aXNpb24sXHJcbiAgICAgICAgZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoeyByZXZpc2lvbkxhYmVsOiB1bmRlZmluZWQgfSlcclxuICAgICAgKTtcclxuICAgIH0pO1xyXG4gIH0pO1xyXG59KTtcclxuIl0sInZlcnNpb24iOjN9 \ No newline at end of file diff --git a/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/f7/correspondenceservicespec_f7c1f1e06b95bcf8310dffb265941ee4.map b/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/f7/correspondenceservicespec_f7c1f1e06b95bcf8310dffb265941ee4.map new file mode 100644 index 0000000..d714fc1 --- /dev/null +++ b/backend/src/.jest-cache/jest-transform-cache-60cab15b743c6776f41d29bcac696b99-12533232bd0f05f65688e7a7764bf3fb/f7/correspondenceservicespec_f7c1f1e06b95bcf8310dffb265941ee4.map @@ -0,0 +1 @@ +{"file":"E:\\np-dms\\lcbp3\\backend\\src\\modules\\correspondence\\correspondence.service.spec.ts","mappings":"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","names":[],"sources":["E:\\np-dms\\lcbp3\\backend\\src\\modules\\correspondence\\correspondence.service.spec.ts"],"sourcesContent":["import { Test, TestingModule } from '@nestjs/testing';\r\nimport { getRepositoryToken } from '@nestjs/typeorm';\r\nimport { DataSource, Repository } from 'typeorm';\r\nimport { CorrespondenceService } from './correspondence.service';\r\nimport { Correspondence } from './entities/correspondence.entity';\r\nimport { CorrespondenceRevision } from './entities/correspondence-revision.entity';\r\nimport { CorrespondenceType } from './entities/correspondence-type.entity';\r\nimport { CorrespondenceStatus } from './entities/correspondence-status.entity';\r\nimport { CorrespondenceReference } from './entities/correspondence-reference.entity';\r\nimport { CorrespondenceTag } from './entities/correspondence-tag.entity';\r\nimport { Organization } from '../organization/entities/organization.entity';\r\nimport { CorrespondenceRecipient } from './entities/correspondence-recipient.entity';\r\nimport { DocumentNumberingService } from '../document-numbering/services/document-numbering.service';\r\nimport { JsonSchemaService } from '../json-schema/json-schema.service';\r\nimport { WorkflowEngineService } from '../workflow-engine/workflow-engine.service';\r\nimport { UserService } from '../user/user.service';\r\nimport { SearchService } from '../search/search.service';\r\nimport { FileStorageService } from '../../common/file-storage/file-storage.service';\r\nimport { UuidResolverService } from '../../common/services/uuid-resolver.service';\r\nimport { NotificationService } from '../notification/notification.service';\r\nimport { UpdateCorrespondenceDto } from './dto/update-correspondence.dto';\r\nimport { CreateCorrespondenceDto } from './dto/create-correspondence.dto';\r\nimport { User } from '../user/entities/user.entity';\r\n\r\ndescribe('CorrespondenceService', () => {\r\n let service: CorrespondenceService;\r\n let numberingService: DocumentNumberingService;\r\n let correspondenceRepo: Repository;\r\n let revisionRepo: Repository;\r\n let testingModule: TestingModule;\r\n let _dataSource: DataSource;\r\n\r\n const createMockRepository = () => ({\r\n find: jest.fn(),\r\n findOne: jest.fn(),\r\n create: jest.fn(),\r\n save: jest.fn(),\r\n update: jest.fn(),\r\n delete: jest.fn(),\r\n softDelete: jest.fn(),\r\n createQueryBuilder: jest.fn(() => ({\r\n leftJoinAndSelect: jest.fn().mockReturnThis(),\r\n where: jest.fn().mockReturnThis(),\r\n andWhere: jest.fn().mockReturnThis(),\r\n orderBy: jest.fn().mockReturnThis(),\r\n skip: jest.fn().mockReturnThis(),\r\n take: jest.fn().mockReturnThis(),\r\n getOne: jest.fn().mockResolvedValue(null),\r\n getMany: jest.fn().mockResolvedValue([]),\r\n getManyAndCount: jest.fn().mockResolvedValue([[], 0]),\r\n })),\r\n });\r\n\r\n const mockDataSource = {\r\n createQueryRunner: jest.fn(() => ({\r\n connect: jest.fn(),\r\n startTransaction: jest.fn(),\r\n commitTransaction: jest.fn(),\r\n rollbackTransaction: jest.fn(),\r\n release: jest.fn(),\r\n manager: {\r\n create: jest.fn(),\r\n save: jest.fn(),\r\n findOne: jest.fn(),\r\n },\r\n })),\r\n getRepository: jest.fn(() => createMockRepository()),\r\n manager: {\r\n findOne: jest.fn(),\r\n },\r\n };\r\n\r\n beforeEach(async () => {\r\n testingModule = await Test.createTestingModule({\r\n providers: [\r\n CorrespondenceService,\r\n {\r\n provide: getRepositoryToken(Correspondence),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: getRepositoryToken(CorrespondenceRevision),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: getRepositoryToken(CorrespondenceType),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: getRepositoryToken(CorrespondenceStatus),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: getRepositoryToken(CorrespondenceReference),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: getRepositoryToken(CorrespondenceTag),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: getRepositoryToken(Organization),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: getRepositoryToken(CorrespondenceRecipient),\r\n useValue: createMockRepository(),\r\n },\r\n {\r\n provide: DocumentNumberingService,\r\n useValue: {\r\n generateNextNumber: jest.fn(),\r\n updateNumberForDraft: jest.fn(),\r\n previewNextNumber: jest.fn(),\r\n },\r\n },\r\n {\r\n provide: JsonSchemaService,\r\n useValue: { validate: jest.fn() },\r\n },\r\n {\r\n provide: WorkflowEngineService,\r\n useValue: { createInstance: jest.fn() },\r\n },\r\n {\r\n provide: UserService,\r\n useValue: {\r\n findOne: jest.fn(),\r\n getUserPermissions: jest.fn().mockResolvedValue([]),\r\n },\r\n },\r\n {\r\n provide: DataSource,\r\n useValue: mockDataSource,\r\n },\r\n {\r\n provide: SearchService,\r\n useValue: { indexDocument: jest.fn() },\r\n },\r\n {\r\n provide: FileStorageService,\r\n useValue: { commit: jest.fn().mockResolvedValue([]) },\r\n },\r\n {\r\n provide: UuidResolverService,\r\n useValue: {\r\n resolveProjectId: jest.fn().mockResolvedValue(1),\r\n resolveOrganizationId: jest.fn().mockResolvedValue(1),\r\n },\r\n },\r\n {\r\n provide: NotificationService,\r\n useValue: { send: jest.fn().mockResolvedValue(undefined) },\r\n },\r\n ],\r\n }).compile();\r\n\r\n service = testingModule.get(CorrespondenceService);\r\n numberingService = testingModule.get(\r\n DocumentNumberingService\r\n );\r\n correspondenceRepo = testingModule.get>(\r\n getRepositoryToken(Correspondence)\r\n );\r\n revisionRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceRevision)\r\n );\r\n _dataSource = testingModule.get(DataSource);\r\n });\r\n\r\n it('should be defined', () => {\r\n expect(service).toBeDefined();\r\n });\r\n\r\n describe('update', () => {\r\n it('should NOT regenerate number if critical fields unchanged', async () => {\r\n const mockUser = { id: 1, primaryOrganizationId: 10 } as unknown as User;\r\n const mockRevision = {\r\n id: 100,\r\n correspondenceId: 1,\r\n isCurrent: true,\r\n statusId: 5,\r\n };\r\n\r\n jest\r\n .spyOn(revisionRepo, 'findOne')\r\n .mockResolvedValue(mockRevision as unknown as CorrespondenceRevision);\r\n\r\n const mockCorr = {\r\n id: 1,\r\n projectId: 1,\r\n correspondenceTypeId: 2,\r\n disciplineId: 3,\r\n originatorId: 10,\r\n correspondenceNumber: 'OLD-NUM',\r\n recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }],\r\n };\r\n jest\r\n .spyOn(correspondenceRepo, 'findOne')\r\n .mockResolvedValue(mockCorr as unknown as Correspondence);\r\n\r\n const updateDto: UpdateCorrespondenceDto = {\r\n projectId: 1,\r\n disciplineId: 3,\r\n };\r\n\r\n await service.update(1, updateDto, mockUser);\r\n\r\n expect(\r\n numberingService.updateNumberForDraft as jest.Mock\r\n ).not.toHaveBeenCalled();\r\n });\r\n\r\n it('should regenerate number if Project ID changes', async () => {\r\n const mockUser = { id: 1, primaryOrganizationId: 10 } as unknown as User;\r\n const mockRevision = {\r\n id: 100,\r\n correspondenceId: 1,\r\n isCurrent: true,\r\n statusId: 5,\r\n };\r\n jest\r\n .spyOn(revisionRepo, 'findOne')\r\n .mockResolvedValue(mockRevision as unknown as CorrespondenceRevision);\r\n\r\n const mockCorr = {\r\n id: 1,\r\n projectId: 1,\r\n correspondenceTypeId: 2,\r\n disciplineId: 3,\r\n originatorId: 10,\r\n correspondenceNumber: 'OLD-NUM',\r\n recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }],\r\n };\r\n jest\r\n .spyOn(correspondenceRepo, 'findOne')\r\n .mockResolvedValue(mockCorr as unknown as Correspondence);\r\n\r\n const updateDto: UpdateCorrespondenceDto = {\r\n projectId: 2,\r\n };\r\n\r\n const uuidResolver =\r\n testingModule.get(UuidResolverService);\r\n (uuidResolver.resolveProjectId as jest.Mock).mockResolvedValue(2);\r\n\r\n await service.update(1, updateDto, mockUser);\r\n\r\n expect(\r\n numberingService.updateNumberForDraft as jest.Mock\r\n ).toHaveBeenCalled();\r\n });\r\n\r\n it('should regenerate number if Document Type changes', async () => {\r\n const mockUser = { id: 1, primaryOrganizationId: 10 } as unknown as User;\r\n const mockRevision = {\r\n id: 100,\r\n correspondenceId: 1,\r\n isCurrent: true,\r\n statusId: 5,\r\n };\r\n jest\r\n .spyOn(revisionRepo, 'findOne')\r\n .mockResolvedValue(mockRevision as unknown as CorrespondenceRevision);\r\n\r\n const mockCorr = {\r\n id: 1,\r\n projectId: 1,\r\n correspondenceTypeId: 2,\r\n disciplineId: 3,\r\n originatorId: 10,\r\n correspondenceNumber: 'OLD-NUM',\r\n recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }],\r\n };\r\n jest\r\n .spyOn(correspondenceRepo, 'findOne')\r\n .mockResolvedValue(mockCorr as unknown as Correspondence);\r\n\r\n const updateDto: UpdateCorrespondenceDto = {\r\n typeId: 999,\r\n };\r\n\r\n const typeRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceType)\r\n );\r\n (typeRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 999,\r\n typeCode: 'NEW-TYPE',\r\n });\r\n\r\n await service.update(1, updateDto, mockUser);\r\n\r\n expect(\r\n numberingService.updateNumberForDraft as jest.Mock\r\n ).toHaveBeenCalled();\r\n });\r\n\r\n it('should regenerate number if Recipient Organization changes', async () => {\r\n const mockUser = { id: 1, primaryOrganizationId: 10 } as unknown as User;\r\n const mockRevision = {\r\n id: 100,\r\n correspondenceId: 1,\r\n isCurrent: true,\r\n statusId: 5,\r\n };\r\n jest\r\n .spyOn(revisionRepo, 'findOne')\r\n .mockResolvedValue(mockRevision as unknown as CorrespondenceRevision);\r\n\r\n const mockCorr = {\r\n id: 1,\r\n projectId: 1,\r\n correspondenceTypeId: 2,\r\n disciplineId: 3,\r\n originatorId: 10,\r\n correspondenceNumber: 'OLD-NUM',\r\n recipients: [{ recipientType: 'TO', recipientOrganizationId: 99 }],\r\n };\r\n jest\r\n .spyOn(correspondenceRepo, 'findOne')\r\n .mockResolvedValue(mockCorr as unknown as Correspondence);\r\n\r\n // Access DataSource manager for mocking\r\n mockDataSource.manager.findOne.mockResolvedValue({\r\n id: 88,\r\n organizationCode: 'NEW-ORG',\r\n } as unknown as Organization);\r\n\r\n const updateDto: UpdateCorrespondenceDto = {\r\n recipients: [{ type: 'TO', organizationId: 88 }],\r\n };\r\n\r\n await service.update(1, updateDto, mockUser);\r\n\r\n expect(\r\n numberingService.updateNumberForDraft as jest.Mock\r\n ).toHaveBeenCalled();\r\n });\r\n });\r\n\r\n describe('create', () => {\r\n it('should allow system.manage_all user without primaryOrganizationId when originatorId is provided', async () => {\r\n const mockUser = {\r\n user_id: 1,\r\n primaryOrganizationId: null,\r\n } as unknown as User;\r\n\r\n const createDto: CreateCorrespondenceDto = {\r\n projectId: 'project-uuid',\r\n typeId: 1,\r\n subject: 'Test Subject',\r\n originatorId: 'originator-uuid',\r\n recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }],\r\n };\r\n\r\n const userService = testingModule.get(UserService);\r\n const typeRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceType)\r\n );\r\n const statusRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceStatus)\r\n );\r\n const uuidResolver =\r\n testingModule.get(UuidResolverService);\r\n\r\n (userService.findOne as jest.Mock).mockResolvedValue({\r\n user_id: 1,\r\n primaryOrganizationId: null,\r\n });\r\n (userService.getUserPermissions as jest.Mock).mockResolvedValue([\r\n 'system.manage_all',\r\n ]);\r\n\r\n (uuidResolver.resolveProjectId as jest.Mock).mockResolvedValue(100);\r\n (uuidResolver.resolveOrganizationId as jest.Mock).mockImplementation(\r\n (value: number | string) => {\r\n if (value === 'originator-uuid') return 10;\r\n if (value === 'recipient-uuid') return 20;\r\n return 0;\r\n }\r\n );\r\n\r\n (typeRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n typeCode: 'LTR',\r\n });\r\n (statusRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n statusCode: 'DRAFT',\r\n });\r\n\r\n (numberingService.generateNextNumber as jest.Mock).mockResolvedValue({\r\n number: 'DOC-001',\r\n });\r\n\r\n mockDataSource.manager.findOne\r\n .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' })\r\n .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' });\r\n\r\n const queryRunner = {\r\n connect: jest.fn(),\r\n startTransaction: jest.fn(),\r\n commitTransaction: jest.fn(),\r\n rollbackTransaction: jest.fn(),\r\n release: jest.fn(),\r\n manager: {\r\n create: jest.fn(\r\n (_entity: unknown, payload: Record) => payload\r\n ),\r\n save: jest\r\n .fn()\r\n .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' })\r\n .mockResolvedValueOnce({ id: 1000 })\r\n .mockResolvedValueOnce([]),\r\n findOne: jest.fn(),\r\n },\r\n };\r\n\r\n (mockDataSource.createQueryRunner as jest.Mock).mockReturnValue(\r\n queryRunner\r\n );\r\n\r\n await service.create(createDto, mockUser);\r\n\r\n expect(queryRunner.manager.create).toHaveBeenCalledWith(\r\n Correspondence,\r\n expect.objectContaining({ originatorId: 10 })\r\n );\r\n });\r\n\r\n it('should set revisionLabel to \"A\" for RFA type', async () => {\r\n const mockUser = {\r\n user_id: 1,\r\n primaryOrganizationId: 10,\r\n } as unknown as User;\r\n\r\n const createDto: CreateCorrespondenceDto = {\r\n projectId: 'project-uuid',\r\n typeId: 1,\r\n subject: 'Test Subject',\r\n recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }],\r\n };\r\n\r\n const typeRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceType)\r\n );\r\n const statusRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceStatus)\r\n );\r\n const uuidResolver =\r\n testingModule.get(UuidResolverService);\r\n\r\n (uuidResolver.resolveProjectId as jest.Mock).mockResolvedValue(100);\r\n (uuidResolver.resolveOrganizationId as jest.Mock).mockResolvedValue(20);\r\n\r\n (typeRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n typeCode: 'RFA',\r\n });\r\n (statusRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n statusCode: 'DRAFT',\r\n });\r\n\r\n (numberingService.generateNextNumber as jest.Mock).mockResolvedValue({\r\n number: 'DOC-001',\r\n });\r\n\r\n mockDataSource.manager.findOne\r\n .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' })\r\n .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' });\r\n\r\n const queryRunner = {\r\n connect: jest.fn(),\r\n startTransaction: jest.fn(),\r\n commitTransaction: jest.fn(),\r\n rollbackTransaction: jest.fn(),\r\n release: jest.fn(),\r\n manager: {\r\n create: jest.fn(\r\n (_entity: unknown, payload: Record) => payload\r\n ),\r\n save: jest\r\n .fn()\r\n .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' })\r\n .mockResolvedValueOnce({ id: 1000 })\r\n .mockResolvedValueOnce([]),\r\n findOne: jest.fn(),\r\n },\r\n };\r\n\r\n (mockDataSource.createQueryRunner as jest.Mock).mockReturnValue(\r\n queryRunner\r\n );\r\n\r\n await service.create(createDto, mockUser);\r\n\r\n expect(queryRunner.manager.create).toHaveBeenCalledWith(\r\n CorrespondenceRevision,\r\n expect.objectContaining({ revisionLabel: 'A' })\r\n );\r\n });\r\n\r\n it('should set revisionLabel to \"A\" for RFI type', async () => {\r\n const mockUser = {\r\n user_id: 1,\r\n primaryOrganizationId: 10,\r\n } as unknown as User;\r\n\r\n const createDto: CreateCorrespondenceDto = {\r\n projectId: 'project-uuid',\r\n typeId: 1,\r\n subject: 'Test Subject',\r\n recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }],\r\n };\r\n\r\n const typeRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceType)\r\n );\r\n const statusRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceStatus)\r\n );\r\n const uuidResolver =\r\n testingModule.get(UuidResolverService);\r\n\r\n (uuidResolver.resolveProjectId as jest.Mock).mockResolvedValue(100);\r\n (uuidResolver.resolveOrganizationId as jest.Mock).mockResolvedValue(20);\r\n\r\n (typeRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n typeCode: 'RFI',\r\n });\r\n (statusRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n statusCode: 'DRAFT',\r\n });\r\n\r\n (numberingService.generateNextNumber as jest.Mock).mockResolvedValue({\r\n number: 'DOC-001',\r\n });\r\n\r\n mockDataSource.manager.findOne\r\n .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' })\r\n .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' });\r\n\r\n const queryRunner = {\r\n connect: jest.fn(),\r\n startTransaction: jest.fn(),\r\n commitTransaction: jest.fn(),\r\n rollbackTransaction: jest.fn(),\r\n release: jest.fn(),\r\n manager: {\r\n create: jest.fn(\r\n (_entity: unknown, payload: Record) => payload\r\n ),\r\n save: jest\r\n .fn()\r\n .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' })\r\n .mockResolvedValueOnce({ id: 1000 })\r\n .mockResolvedValueOnce([]),\r\n findOne: jest.fn(),\r\n },\r\n };\r\n\r\n (mockDataSource.createQueryRunner as jest.Mock).mockReturnValue(\r\n queryRunner\r\n );\r\n\r\n await service.create(createDto, mockUser);\r\n\r\n expect(queryRunner.manager.create).toHaveBeenCalledWith(\r\n CorrespondenceRevision,\r\n expect.objectContaining({ revisionLabel: 'A' })\r\n );\r\n });\r\n\r\n it('should set revisionLabel to null for LETTER type', async () => {\r\n const mockUser = {\r\n user_id: 1,\r\n primaryOrganizationId: 10,\r\n } as unknown as User;\r\n\r\n const createDto: CreateCorrespondenceDto = {\r\n projectId: 'project-uuid',\r\n typeId: 1,\r\n subject: 'Test Subject',\r\n recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }],\r\n };\r\n\r\n const typeRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceType)\r\n );\r\n const statusRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceStatus)\r\n );\r\n const uuidResolver =\r\n testingModule.get(UuidResolverService);\r\n\r\n (uuidResolver.resolveProjectId as jest.Mock).mockResolvedValue(100);\r\n (uuidResolver.resolveOrganizationId as jest.Mock).mockResolvedValue(20);\r\n\r\n (typeRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n typeCode: 'LETTER',\r\n });\r\n (statusRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n statusCode: 'DRAFT',\r\n });\r\n\r\n (numberingService.generateNextNumber as jest.Mock).mockResolvedValue({\r\n number: 'DOC-001',\r\n });\r\n\r\n mockDataSource.manager.findOne\r\n .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' })\r\n .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' });\r\n\r\n const queryRunner = {\r\n connect: jest.fn(),\r\n startTransaction: jest.fn(),\r\n commitTransaction: jest.fn(),\r\n rollbackTransaction: jest.fn(),\r\n release: jest.fn(),\r\n manager: {\r\n create: jest.fn(\r\n (_entity: unknown, payload: Record) => payload\r\n ),\r\n save: jest\r\n .fn()\r\n .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' })\r\n .mockResolvedValueOnce({ id: 1000 })\r\n .mockResolvedValueOnce([]),\r\n findOne: jest.fn(),\r\n },\r\n };\r\n\r\n (mockDataSource.createQueryRunner as jest.Mock).mockReturnValue(\r\n queryRunner\r\n );\r\n\r\n await service.create(createDto, mockUser);\r\n\r\n expect(queryRunner.manager.create).toHaveBeenCalledWith(\r\n CorrespondenceRevision,\r\n expect.objectContaining({ revisionLabel: undefined })\r\n );\r\n });\r\n\r\n it('should set revisionLabel to undefined for MEMO type', async () => {\r\n const mockUser = {\r\n user_id: 1,\r\n primaryOrganizationId: 10,\r\n } as unknown as User;\r\n\r\n const createDto: CreateCorrespondenceDto = {\r\n projectId: 'project-uuid',\r\n typeId: 1,\r\n subject: 'Test Subject',\r\n recipients: [{ organizationId: 'recipient-uuid', type: 'TO' }],\r\n };\r\n\r\n const typeRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceType)\r\n );\r\n const statusRepo = testingModule.get>(\r\n getRepositoryToken(CorrespondenceStatus)\r\n );\r\n const uuidResolver =\r\n testingModule.get(UuidResolverService);\r\n\r\n (uuidResolver.resolveProjectId as jest.Mock).mockResolvedValue(100);\r\n (uuidResolver.resolveOrganizationId as jest.Mock).mockResolvedValue(20);\r\n\r\n (typeRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n typeCode: 'MEMO',\r\n });\r\n (statusRepo.findOne as jest.Mock).mockResolvedValue({\r\n id: 1,\r\n statusCode: 'DRAFT',\r\n });\r\n\r\n (numberingService.generateNextNumber as jest.Mock).mockResolvedValue({\r\n number: 'DOC-001',\r\n });\r\n\r\n mockDataSource.manager.findOne\r\n .mockResolvedValueOnce({ id: 10, organizationCode: 'ORG' })\r\n .mockResolvedValueOnce({ id: 20, organizationCode: 'REC' });\r\n\r\n const queryRunner = {\r\n connect: jest.fn(),\r\n startTransaction: jest.fn(),\r\n commitTransaction: jest.fn(),\r\n rollbackTransaction: jest.fn(),\r\n release: jest.fn(),\r\n manager: {\r\n create: jest.fn(\r\n (_entity: unknown, payload: Record) => payload\r\n ),\r\n save: jest\r\n .fn()\r\n .mockResolvedValueOnce({ id: 999, publicId: 'corr-uuid' })\r\n .mockResolvedValueOnce({ id: 1000 })\r\n .mockResolvedValueOnce([]),\r\n findOne: jest.fn(),\r\n },\r\n };\r\n\r\n (mockDataSource.createQueryRunner as jest.Mock).mockReturnValue(\r\n queryRunner\r\n );\r\n\r\n await service.create(createDto, mockUser);\r\n\r\n expect(queryRunner.manager.create).toHaveBeenCalledWith(\r\n CorrespondenceRevision,\r\n expect.objectContaining({ revisionLabel: undefined })\r\n );\r\n });\r\n });\r\n});\r\n"],"version":3} \ No newline at end of file diff --git a/backend/src/.jest-cache/perf-cache-60cab15b743c6776f41d29bcac696b99-da39a3ee5e6b4b0d3255bfef95601890 b/backend/src/.jest-cache/perf-cache-60cab15b743c6776f41d29bcac696b99-da39a3ee5e6b4b0d3255bfef95601890 index cde710c..1e9b7d2 100644 --- a/backend/src/.jest-cache/perf-cache-60cab15b743c6776f41d29bcac696b99-da39a3ee5e6b4b0d3255bfef95601890 +++ b/backend/src/.jest-cache/perf-cache-60cab15b743c6776f41d29bcac696b99-da39a3ee5e6b4b0d3255bfef95601890 @@ -1 +1 @@ -{"E:\\np-dms\\lcbp3\\backend\\src\\modules\\correspondence\\due-date-reminder.service.spec.ts":[1,1723],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\correspondence\\correspondence.service.spec.ts":[0,11179],"E:\\np-dms\\lcbp3\\backend\\src\\common\\auth\\auth.service.spec.ts":[1,1538],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\document-numbering\\document-numbering.service.spec.ts":[1,2037],"E:\\np-dms\\lcbp3\\backend\\src\\common\\auth\\casl\\ability.factory.spec.ts":[1,1294],"E:\\np-dms\\lcbp3\\backend\\src\\common\\services\\uuid-resolver.service.spec.ts":[1,5491],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\workflow-engine\\workflow-engine.service.spec.ts":[1,5639],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\workflow-engine\\dsl\\parser.service.spec.ts":[1,5818],"E:\\np-dms\\lcbp3\\backend\\src\\common\\pipes\\parse-uuid.pipe.spec.ts":[1,355],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\user\\user.service.spec.ts":[1,1270],"E:\\np-dms\\lcbp3\\backend\\src\\common\\file-storage\\file-storage.service.spec.ts":[1,1187],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\correspondence\\correspondence.controller.spec.ts":[1,12259],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\migration\\migration.service.spec.ts":[1,1296],"E:\\np-dms\\lcbp3\\backend\\src\\common\\entities\\uuid-base.entity.spec.ts":[1,430],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\project\\project.service.spec.ts":[1,1109],"E:\\np-dms\\lcbp3\\backend\\src\\common\\auth\\auth.controller.spec.ts":[1,2191],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\document-numbering\\services\\manual-override.service.spec.ts":[1,5256],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\project\\project.controller.spec.ts":[1,1827],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\migration\\migration.controller.spec.ts":[1,6380],"E:\\np-dms\\lcbp3\\backend\\src\\common\\file-storage\\file-storage.controller.spec.ts":[1,1482],"E:\\np-dms\\lcbp3\\backend\\src\\app.controller.spec.ts":[1,587],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\json-schema\\json-schema.controller.spec.ts":[1,5062]} \ No newline at end of file +{"E:\\np-dms\\lcbp3\\backend\\src\\modules\\correspondence\\due-date-reminder.service.spec.ts":[1,1598],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\correspondence\\correspondence.service.spec.ts":[1,7578],"E:\\np-dms\\lcbp3\\backend\\src\\common\\auth\\auth.service.spec.ts":[1,1526],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\document-numbering\\document-numbering.service.spec.ts":[1,1474],"E:\\np-dms\\lcbp3\\backend\\src\\common\\auth\\casl\\ability.factory.spec.ts":[1,921],"E:\\np-dms\\lcbp3\\backend\\src\\common\\services\\uuid-resolver.service.spec.ts":[1,1166],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\workflow-engine\\workflow-engine.service.spec.ts":[1,1175],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\workflow-engine\\dsl\\parser.service.spec.ts":[1,4448],"E:\\np-dms\\lcbp3\\backend\\src\\common\\pipes\\parse-uuid.pipe.spec.ts":[1,369],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\user\\user.service.spec.ts":[1,1074],"E:\\np-dms\\lcbp3\\backend\\src\\common\\file-storage\\file-storage.service.spec.ts":[1,1277],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\correspondence\\correspondence.controller.spec.ts":[1,8589],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\migration\\migration.service.spec.ts":[1,1251],"E:\\np-dms\\lcbp3\\backend\\src\\common\\entities\\uuid-base.entity.spec.ts":[1,460],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\project\\project.service.spec.ts":[1,1043],"E:\\np-dms\\lcbp3\\backend\\src\\common\\auth\\auth.controller.spec.ts":[1,2047],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\document-numbering\\services\\manual-override.service.spec.ts":[1,936],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\project\\project.controller.spec.ts":[1,1666],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\migration\\migration.controller.spec.ts":[1,6122],"E:\\np-dms\\lcbp3\\backend\\src\\common\\file-storage\\file-storage.controller.spec.ts":[1,1859],"E:\\np-dms\\lcbp3\\backend\\src\\app.controller.spec.ts":[1,564],"E:\\np-dms\\lcbp3\\backend\\src\\modules\\json-schema\\json-schema.controller.spec.ts":[1,3140]} \ No newline at end of file diff --git a/backend/src/modules/correspondence/correspondence.service.spec.ts b/backend/src/modules/correspondence/correspondence.service.spec.ts index 72ab08e..4393e6c 100644 --- a/backend/src/modules/correspondence/correspondence.service.spec.ts +++ b/backend/src/modules/correspondence/correspondence.service.spec.ts @@ -643,11 +643,11 @@ describe('CorrespondenceService', () => { expect(queryRunner.manager.create).toHaveBeenCalledWith( CorrespondenceRevision, - expect.objectContaining({ revisionLabel: null }) + expect.objectContaining({ revisionLabel: undefined }) ); }); - it('should set revisionLabel to null for MEMO type', async () => { + it('should set revisionLabel to undefined for MEMO type', async () => { const mockUser = { user_id: 1, primaryOrganizationId: 10, @@ -716,7 +716,7 @@ describe('CorrespondenceService', () => { expect(queryRunner.manager.create).toHaveBeenCalledWith( CorrespondenceRevision, - expect.objectContaining({ revisionLabel: null }) + expect.objectContaining({ revisionLabel: undefined }) ); }); });