From 42921527f8874ea20f0d1fad9c4c8f2f41dec5f1 Mon Sep 17 00:00:00 2001 From: null31 Date: Mon, 13 Oct 2025 00:23:31 -0300 Subject: [PATCH] Initial commit --- README.md | 1 + backend/.editorconfig | 9 + backend/.env.example | 36 + backend/.eslintignore | 3 + backend/.eslintrc.json | 49 + backend/.gitignore | 16 + backend/.sequelizerc | 8 + backend/certs/coloque_seus_certificado_aqui | 1 + backend/jest.config.js | 186 + backend/package.json | 99 + backend/prettier.config.js | 5 + backend/src/@types/express.d.ts | 5 + backend/src/@types/qrcode-terminal.d.ts | 1 + backend/src/app.ts | 53 + backend/src/bootstrap.ts | 5 + backend/src/config/Gn.ts | 13 + backend/src/config/auth.ts | 6 + backend/src/config/database.ts | 16 + backend/src/config/redis.ts | 3 + backend/src/config/upload.ts | 39 + .../src/controllers/AnnouncementController.ts | 205 + backend/src/controllers/CampaignController.ts | 287 + .../controllers/CampaignSettingController.ts | 34 + backend/src/controllers/ChatController.ts | 205 + backend/src/controllers/CompanyController.ts | 180 + backend/src/controllers/ContactController.ts | 193 + .../src/controllers/ContactListController.ts | 159 + .../controllers/ContactListItemController.ts | 145 + backend/src/controllers/DashbardController.ts | 42 + backend/src/controllers/FilesController.ts | 155 + backend/src/controllers/ForgotController.ts | 25 + backend/src/controllers/HelpController.ts | 131 + .../ImportPhoneContactsController.ts | 10 + backend/src/controllers/InvoicesController.ts | 172 + backend/src/controllers/MessageController.ts | 192 + backend/src/controllers/PlanController.ts | 136 + backend/src/controllers/PromptController.ts | 114 + backend/src/controllers/QueueController.ts | 107 + .../controllers/QueueIntegrationController.ts | 99 + .../src/controllers/QueueOptionController.ts | 60 + .../src/controllers/QuickMessageController.ts | 197 + .../controllers/QuickMessageController_OLD.ts | 146 + backend/src/controllers/ScheduleController.ts | 154 + backend/src/controllers/SessionController.ts | 80 + backend/src/controllers/SettingController.ts | 45 + .../src/controllers/SubscriptionController.ts | 198 + backend/src/controllers/TagController.ts | 128 + backend/src/controllers/TicketController.ts | 223 + .../src/controllers/TicketNoteController.ts | 138 + .../src/controllers/TicketTagController.ts | 57 + backend/src/controllers/UserController.ts | 158 + backend/src/controllers/VersionController.ts | 7 + backend/src/controllers/WhatsAppController.ts | 166 + .../controllers/WhatsAppSessionController.ts | 46 + backend/src/database/index.ts | 90 + .../20200717133431-add-uuid-ossp.ts | 10 + .../migrations/20200717133438-create-users.ts | 39 + .../20200717144403-create-contacts.ts | 37 + .../20200717145643-create-tickets.ts | 46 + .../20200717151645-create-messages.ts | 58 + .../20200717170223-create-whatsapps.ts | 41 + ...723200315-create-contacts-custom-fields.ts | 41 + ...00723202116-add-email-field-to-contacts.ts | 15 + ...7-remove-user-association-from-messages.ts | 16 + .../20200730153545-add-fromMe-to-messages.ts | 15 + ...6-change-ticket-lastMessage-column-type.ts | 15 + ...00901235509-add-profile-column-to-users.ts | 15 + .../20200903215941-create-settings.ts | 29 + .../20200904220257-add-name-to-whatsapp.ts | 15 + ...2228-add-name-default-field-to-whatsapp.ts | 15 + ...906155658-add-whatsapp-field-to-tickets.ts | 16 + ...update-default-column-name-on-whatsappp.ts | 11 + ...220708-add-isDeleted-column-to-messages.ts | 15 + ...0929145451-add-user-tokenVersion-column.ts | 15 + ...930162323-add-isGroup-column-to-tickets.ts | 15 + ...30194808-add-isGroup-column-to-contacts.ts | 15 + ...150008-add-contactId-column-to-messages.ts | 16 + ...9-add-vcardContactId-column-to-messages.ts | 16 + ...emove-vcardContactId-column-to-messages.ts | 16 + ...20201026215410-add-retries-to-whatsapps.ts | 15 + ...201028124427-add-quoted-msg-to-messages.ts | 16 + ...108001431-add-unreadMessages-to-tickets.ts | 13 + .../20210108164404-create-queues.ts | 39 + .../20210108164504-add-queueId-to-tickets.ts | 16 + ...20210108174594-associate-whatsapp-queue.ts | 28 + .../20210108204708-associate-users-queue.ts | 28 + ...9192513-add-greetingMessage-to-whatsapp.ts | 13 + .../20210109192514-create-companies-table.ts | 39 + ...-add-column-companyId-to-Settings-table.ts | 16 + ...516-add-column-companyId-to-Users-table.ts | 16 + ...-add-column-companyId-to-Contacts-table.ts | 16 + ...-add-column-companyId-to-Messages-table.ts | 16 + ...19-add-column-companyId-to-Queues-table.ts | 16 + ...add-column-companyId-to-Whatsapps-table.ts | 16 + ...1-add-column-companyId-to-Tickets-table.ts | 16 + .../20210109192522-create-plans-table.ts | 47 + ...09192523-add-column-planId-to-Companies.ts | 16 + ...olumn-status-and-schedules-to-Companies.ts | 23 + .../20210109192523-create-ticket-notes.ts | 49 + .../20210109192524-create-quick-messages.ts | 40 + ...dd-column-complationMessage-to-whatsapp.ts | 13 + ...d-column-outOfHoursMessage-to-whatsapp .ts | 13 + ...9192527-add-column-super-to-Users-table.ts | 14 + ...-column-message-to-quick-messages-table.ts | 14 + .../migrations/20210109192529-create-helps.ts | 42 + ...add-unique-constraint-to-Contacts-table.ts | 17 + ...10109192531-create-TicketTracking-table.ts | 60 + ...192532-add-column-online-to-Users-table.ts | 14 + ...20210109192533-create-UserRatings-table.ts | 46 + ...210109192534-add-rated-to-TicketTraking.ts | 24 + ...35-add-column-ratingMessage-to-whatsapp.ts | 13 + ...-add-unique-constraint-to-Tickets-table.ts | 17 + .../20210818102606-add-uuid-to-tickets.ts | 17 + ...7-remove-unique-indexes-to-Queues-table.ts | 25 + ...2608-add-unique-indexes-to-Queues-table.ts | 23 + .../20210818102609-add-token-to-Whatsapps.ts | 14 + .../20211205164404-create-queue-options.ts | 51 + .../20211212125704-add-chatbot-to-tickets.ts | 24 + .../20211227010200-create-schedules.ts | 66 + ...dd-column-userId-to-QuickMessages-table.ts | 16 + .../migrations/20220117130000-create-tags.ts | 41 + .../20220117134400-associate-tickets-tags.ts | 34 + .../20220122160900-add-status-to-schedules.ts | 14 + ...0014719-add-farewellMessage-to-whatsapp.ts | 13 + .../20220221014717-add-provider-whatsapp.ts | 14 + .../20220221014718-add-remoteJid-messages.ts | 13 + ...20220221014719-add-jsonMessage-messages.ts | 13 + ...20220221014720-add-participant-messages.ts | 13 + .../20220221014721-create-baileys.ts | 38 + ...0220315110000-create-ContactLists-table.ts | 37 + ...315110001-create-ContactListItems-table.ts | 56 + .../20220315110002-create-Campaigns-table.ts | 126 + ...315110004-create-CampaignSettings-table.ts | 41 + ...315110005-remove-constraint-to-Settings.ts | 27 + .../20220321130000-create-CampaignShipping.ts | 72 + ...00-add-column-queueId-to-Messages-table.ts | 16 + ...6000000-add-column-dueDate-to-Companies.ts | 14 + ...0001-add-column-recurrence-to-Companies.ts | 15 + ...-column-startTime-and-endTime-to-Queues.ts | 28 + ...-column-startTime-and-endTime-to-Queues.ts | 28 + ...hedules-and-outOfHoursMessage-to-Queues.ts | 23 + ...220411000003-create-table-Announcements.ts | 57 + .../20220425000000-create-table-Chats.ts | 54 + .../20220425000001-create-table-ChatUsers.ts | 44 + ...0220425000002-create-table-ChatMessages.ts | 53 + .../20220512000001-create-Indexes.ts | 37 + .../20220512000002-create-subscriptions.ts | 58 + .../20220512000003-create-invoices.ts | 44 + ...23000001-add-mediaPath-to-quickmessages.ts | 15 + ...3000002-add-mediaName-to-quickemessages.ts | 15 + .../20222016014720-create-baileys-chats.ts | 44 + ...016014721-create-baileys-chats Messages.ts | 42 + .../20230106164900-add-useCampaigns-Plans.ts | 14 + ...20230106164900-add-useExternalApi-Plans.ts | 14 + ...0230106164900-add-useInternalChat-Plans.ts | 14 + .../20230106164900-add-useSchedules-Plans.ts | 14 + ...3001-add-amountUsedBotQueues-to-tickets.ts | 13 + .../20230417203900-add-allTickets-user.ts | 15 + ...20230603212335-create-QueueIntegrations.ts | 48 + ...0603212337-add-urlN8N-QueueIntegrations.ts | 15 + .../20230623095932-add-whatsapp-to-user.ts | 17 + ...623133903-add-chatbotAt-ticket-tracking.ts | 14 + .../20230628134807-add-orderQueue-Queue.ts | 13 + ...mn-companyId-to-QueueIntegrations-table.ts | 16 + ...30711111701-add-sendIdQueue-to-whatsapp.ts | 13 + .../migrations/20230714113901-create-Files.ts | 41 + .../20230714113902-create-fileOptions.ts | 41 + .../20230723301001-add-kanban-to-Tags.ts | 14 + .../20230801081907-add-collumns-Ticket.ts | 17 + ...6-change-ticket-lastMessage-column-type.ts | 17 + ...230824082607-add-mediaType-FilesOptions.ts | 15 + ...30828143411-add-Integrations-to-tickets.ts | 26 + .../20230828144000-create-prompts.ts | 103 + ...4100-add-column-promptid-into-whatsapps.ts | 26 + .../20230831093000-add-useKanban-Plans.ts | 14 + ...20230922212337-add-integrationId-Queues.ts | 23 + ...20230924212337-add-fileListId-Campaigns.ts | 16 + ...0231111185822-add_reset_password_column.ts | 1 + ...231117000001-add-mediaName-to-schedules.ts | 15 + ...231117000001-add-mediaPath-to-schedules.ts | 15 + .../20231127113000-add-columns-Plans.ts | 19 + ...128123537-add-typebot-QueueIntegrations.ts | 33 + ...2143411-add-typebotSessionId-to-tickets.ts | 16 + ...d-typebotDelayMessage-QueueIntegrations.ts | 15 + ...1207085011-add-typebotStatus-to-tickets.ts | 16 + .../20231214092337-add-promptId-Queues.ts | 16 + ...20231214143411-add-columns-to-whatsapps.ts | 30 + .../20231214143411-add-promptId-to-tickets.ts | 16 + ...218160937-add-columns-QueueIntegrations.ts | 21 + ...9153800-add-isEdited-column-to-messages.ts | 15 + ...-add-unique-constraint-to-Tickets-table.ts | 18 + ...23517-add-column-whatsappId-to-Contacts.ts | 16 + ...19-add-transferTime-and-queueIdTransfer.ts | 27 + .../20200904070005-create-default-company.ts | 45 + .../20200904070006-create-default-user.ts | 32 + .../20200904070007-create-default-settings.ts | 123 + ...230130004700-create-alltickets-settings.ts | 22 + backend/src/errors/AppError.ts | 12 + backend/src/errors/toastError.js | 42 + .../src/helpers/CheckContactOpenTickets.ts | 31 + backend/src/helpers/CheckContactSomeTicket.ts | 18 + backend/src/helpers/CheckSettings.ts | 16 + backend/src/helpers/CreateTokens.ts | 32 + backend/src/helpers/Debounce.ts | 41 + backend/src/helpers/GetDefaultWhatsApp.ts | 43 + .../src/helpers/GetDefaultWhatsAppByUser.ts | 18 + backend/src/helpers/GetTicketWbot.ts | 23 + backend/src/helpers/GetWbotMessage.ts | 42 + backend/src/helpers/GetWhatsappWbot.ts | 9 + backend/src/helpers/Mustache.ts | 57 + backend/src/helpers/SendMessage.ts | 45 + backend/src/helpers/SendRefreshToken.ts | 5 + backend/src/helpers/SerializeUser.ts | 30 + backend/src/helpers/SerializeWbotMsgId.ts | 12 + .../src/helpers/SetTicketMessagesAsRead.ts | 62 + .../UpdateDeletedUserOpenTicketsStatus.ts | 19 + backend/src/helpers/authState.ts | 77 + backend/src/libs/cache.ts | 82 + backend/src/libs/counter.ts | 33 + backend/src/libs/socket.ts | 177 + backend/src/libs/store.d.ts | 116 + backend/src/libs/wbot.ts | 263 + backend/src/middleware/envTokenAuth.ts | 32 + backend/src/middleware/isAuth.ts | 40 + backend/src/middleware/isSuper.ts | 17 + backend/src/middleware/tokenAuth.ts | 31 + backend/src/models/Announcement.ts | 54 + backend/src/models/Baileys.ts | 40 + backend/src/models/BaileysChats.ts | 45 + backend/src/models/Campaign.ts | 115 + backend/src/models/CampaignSetting.ts | 41 + backend/src/models/CampaignShipping.ts | 67 + backend/src/models/Chat.ts | 72 + backend/src/models/ChatMessage.ts | 52 + backend/src/models/ChatUser.ts | 46 + backend/src/models/Company.ts | 133 + backend/src/models/Contact.ts | 84 + backend/src/models/ContactCustomField.ts | 41 + backend/src/models/ContactList.ts | 47 + backend/src/models/ContactListItem.ts | 61 + backend/src/models/Files.ts | 44 + backend/src/models/FilesOptions.ts | 46 + backend/src/models/Help.ts | 39 + backend/src/models/Invoices.ts | 44 + backend/src/models/Message.ts | 113 + backend/src/models/Plan.ts | 65 + backend/src/models/Prompt.ts | 87 + backend/src/models/Queue.ts | 103 + backend/src/models/QueueIntegrations.ts | 82 + backend/src/models/QueueOption.ts | 54 + backend/src/models/QuickMessage.ts | 63 + backend/src/models/Schedule.ts | 78 + backend/src/models/Setting.ts | 42 + backend/src/models/Subscriptions.ts | 56 + backend/src/models/Tag.ts | 54 + backend/src/models/Ticket.ts | 154 + backend/src/models/TicketNote.ts | 55 + backend/src/models/TicketTag.ts | 38 + backend/src/models/TicketTraking.ts | 80 + backend/src/models/User.ts | 108 + backend/src/models/UserQueue.ts | 29 + backend/src/models/UserRating.ts | 58 + backend/src/models/Whatsapp.ts | 148 + backend/src/models/WhatsappQueue.ts | 33 + backend/src/queues.ts | 930 + backend/src/routes/announcementRoutes.ts | 38 + backend/src/routes/authRoutes.ts | 15 + backend/src/routes/campaignRoutes.ts | 41 + backend/src/routes/campaignSettingRoutes.ts | 16 + backend/src/routes/chatRoutes.ts | 24 + backend/src/routes/companyRoutes.ts | 22 + backend/src/routes/contactListItemRoutes.ts | 28 + backend/src/routes/contactListRoutes.ts | 31 + backend/src/routes/contactRoutes.ts | 27 + backend/src/routes/dashboardRoutes.ts | 12 + backend/src/routes/filesRoutes.ts | 20 + backend/src/routes/forgotPasswordRoutes.ts | 10 + backend/src/routes/helpRoutes.ts | 21 + backend/src/routes/index.ts | 71 + backend/src/routes/invoicesRoutes.ts | 14 + backend/src/routes/messageRoutes.ts | 18 + backend/src/routes/planRoutes.ts | 23 + backend/src/routes/promptRouter.ts | 18 + backend/src/routes/queueIntegrationRoutes.ts | 18 + backend/src/routes/queueOptionRoutes.ts | 18 + backend/src/routes/queueRoutes.ts | 18 + backend/src/routes/quickMessageRoutes.ts | 37 + backend/src/routes/scheduleRoutes.ts | 26 + backend/src/routes/settingRoutes.ts | 15 + backend/src/routes/subScriptionRoutes.ts | 11 + backend/src/routes/tagRoutes.ts | 25 + backend/src/routes/ticketNoteRoutes.ts | 28 + backend/src/routes/ticketRoutes.ts | 22 + backend/src/routes/ticketTagRoutes.ts | 11 + backend/src/routes/userRoutes.ts | 20 + backend/src/routes/versionRoutes.ts | 9 + backend/src/routes/whatsappRoutes.ts | 22 + backend/src/routes/whatsappSessionRoutes.ts | 26 + backend/src/server.ts | 40 + .../AnnouncementService/CreateService.ts | 32 + .../AnnouncementService/DeleteService.ts | 16 + .../AnnouncementService/FindAllService.ts | 10 + .../AnnouncementService/FindService.ts | 20 + .../AnnouncementService/ListService.ts | 58 + .../AnnouncementService/ShowService.ts | 14 + .../AnnouncementService/UpdateService.ts | 27 + .../AuthServices/FindUserFromToken.ts | 18 + .../AuthServices/RefreshTokenService.ts | 48 + .../CreateOrUpdateBaileysChatService.ts | 39 + .../DeleteBaileysChatServices.ts | 13 + .../ShowBaileysChatService.ts | 19 + .../UpdateBaileysChatServices.ts | 30 + .../CreateOrUpdateBaileysService.ts | 57 + .../BaileysServices/DeleteBaileysService.ts | 15 + .../BaileysServices/ShowBaileysService.ts | 18 + .../services/CampaignService/CancelService.ts | 26 + .../services/CampaignService/CreateService.ts | 58 + .../services/CampaignService/DeleteService.ts | 20 + .../CampaignService/FindAllService.ts | 10 + .../services/CampaignService/FindService.ts | 20 + .../services/CampaignService/ListService.ts | 66 + .../CampaignService/RestartService.ts | 12 + .../services/CampaignService/ShowService.ts | 24 + .../services/CampaignService/UpdateService.ts | 63 + .../CampaignSettingServices/CreateService.ts | 36 + .../CampaignSettingServices/ListService.ts | 34 + .../ChatService/CreateMessageService.ts | 52 + .../src/services/ChatService/CreateService.ts | 38 + .../src/services/ChatService/DeleteService.ts | 16 + .../services/ChatService/FindAllService.ts | 10 + .../src/services/ChatService/FindMessages.ts | 58 + .../src/services/ChatService/FindService.ts | 26 + .../src/services/ChatService/ListService.ts | 54 + .../ChatService/ShowFromUuidService.ts | 14 + .../src/services/ChatService/ShowService.ts | 14 + .../src/services/ChatService/UpdateService.ts | 38 + .../CompanyService/CreateCompanyService.ts | 305 + .../CompanyService/DeleteCompanyService.ts | 16 + .../CompanyService/FindAllCompaniesService.ts | 16 + .../ListCompaniesPlanService.ts | 32 + .../CompanyService/ListCompaniesService.ts | 50 + .../CompanyService/ShowCompanyService.ts | 14 + .../CompanyService/ShowPlanCompanyService.ts | 34 + .../CompanyService/UpdateCompanyService.ts | 66 + .../CompanyService/UpdateSchedulesService.ts | 26 + .../CompanyService/VerifyCurrentSchedule.ts | 45 + .../ContactListItemService/CreateService.ts | 52 + .../ContactListItemService/DeleteService.ts | 16 + .../ContactListItemService/FindAllService.ts | 10 + .../ContactListItemService/FindService.ts | 33 + .../ContactListItemService/ListService.ts | 57 + .../ContactListItemService/ShowService.ts | 14 + .../ContactListItemService/UpdateService.ts | 41 + .../ContactListService/CreateService.ts | 30 + .../ContactListService/DeleteService.ts | 16 + .../ContactListService/FindAllService.ts | 10 + .../ContactListService/FindService.ts | 20 + .../ContactListService/ImportContacts.ts | 79 + .../ContactListService/ListService.ts | 76 + .../ContactListService/ShowService.ts | 14 + .../ContactListService/UpdateService.ts | 25 + .../ContactServices/CreateContactService.ts | 50 + .../CreateOrUpdateContactService.ts | 76 + .../ContactServices/DeleteContactService.ts | 16 + .../ContactServices/GetContactService.ts | 43 + .../ContactServices/ListContactsService.ts | 55 + .../ContactServices/ShowContactService.ts | 21 + .../ContactServices/SimpleListService.ts | 39 + .../ContactServices/UpdateContactService.ts | 76 + .../services/FileServices/CreateService.ts | 68 + .../services/FileServices/DeleteAllService.ts | 16 + .../services/FileServices/DeleteService.ts | 16 + .../src/services/FileServices/ListService.ts | 46 + .../src/services/FileServices/ShowService.ts | 25 + .../FileServices/SimpleListService.ts | 30 + .../services/FileServices/UpdateService.ts | 82 + .../ForgotPassWordServices/SendMail.ts | 248 + .../services/HelpServices/CreateService.ts | 33 + .../services/HelpServices/DeleteService.ts | 16 + .../services/HelpServices/FindAllService.ts | 10 + .../src/services/HelpServices/FindService.ts | 11 + .../src/services/HelpServices/ListService.ts | 49 + .../src/services/HelpServices/ShowService.ts | 14 + .../services/HelpServices/UpdateService.ts | 26 + .../InvoicesService/FindAllInvoiceService.ts | 17 + .../InvoicesService/ListInvoicesServices.ts | 49 + .../InvoicesService/ShowInvoiceService.ts | 14 + .../InvoicesService/UpdateInvoiceService.ts | 25 + .../MessageServices/CreateMessageService.ts | 77 + .../MessageServices/GetMessagesService.ts | 20 + .../MessageServices/ListMessagesService.ts | 84 + .../services/PlanService/CreatePlanService.ts | 54 + .../services/PlanService/DeletePlanService.ts | 16 + .../PlanService/FindAllPlanService.ts | 10 + .../services/PlanService/ListPlansService.ts | 49 + .../services/PlanService/ShowPlanService.ts | 14 + .../services/PlanService/UpdatePlanService.ts | 34 + .../PromptServices/CreatePromptService.ts | 47 + .../PromptServices/DeletePromptService.ts | 9 + .../PromptServices/ListPromptsService.ts | 56 + .../PromptServices/ShowPromptService.ts | 30 + .../PromptServices/UpdatePromptService.ts | 58 + .../CreateQueueIntegrationService.ts | 86 + .../DeleteQueueIntegrationService.ts | 16 + .../ListQueueIntegrationService.ts | 57 + .../ShowQueueIntegrationService.ts | 19 + .../UpdateQueueIntegrationService.ts | 83 + .../QueueOptionService/CreateService.ts | 16 + .../QueueOptionService/DeleteService.ts | 9 + .../QueueOptionService/ListService.ts | 38 + .../QueueOptionService/ShowService.ts | 26 + .../QueueOptionService/UpdateService.ts | 24 + .../QueueService/CreateQueueService.ts | 94 + .../QueueService/DeleteQueueService.ts | 12 + .../QueueService/ListQueuesService.ts | 18 + .../services/QueueService/ShowQueueService.ts | 21 + .../QueueService/UpdateQueueService.ts | 83 + .../QuickMessageService/CreateService.ts | 35 + .../QuickMessageService/DeleteService.ts | 16 + .../QuickMessageService/FindAllService.ts | 10 + .../QuickMessageService/FindService.ts | 23 + .../QuickMessageService/ListService.ts | 67 + .../QuickMessageService/ShowService.ts | 14 + .../QuickMessageService/UpdateService.ts | 29 + .../ReportService/DashbardDataService.ts | 144 + .../ReportService/TicketsAttendance.ts | 60 + .../ReportService/TicketsDayService.ts | 70 + .../ResetPasswordService/ResetPassword.ts | 51 + .../ResetPasswordService/ResetPassword.ts.bak | 48 + .../ScheduleServices/CreateService.ts | 48 + .../ScheduleServices/DeleteService.ts | 16 + .../services/ScheduleServices/ListService.ts | 93 + .../services/ScheduleServices/ShowService.ts | 25 + .../ScheduleServices/UpdateService.ts | 67 + .../SettingServices/ListSettingsService.ts | 19 + .../SettingServices/ListSettingsServiceOne.ts | 22 + .../SettingServices/UpdateSettingService.ts | 40 + .../src/services/TagServices/CreateService.ts | 39 + .../src/services/TagServices/DeleteService.ts | 16 + .../services/TagServices/KanbanListService.ts | 24 + .../src/services/TagServices/ListService.ts | 66 + .../src/services/TagServices/ShowService.ts | 14 + .../services/TagServices/SimpleListService.ts | 34 + .../services/TagServices/SyncTagsService.ts | 26 + .../src/services/TagServices/UpdateService.ts | 47 + .../CreateTicketNoteService.ts | 34 + .../DeleteTicketNoteService.ts | 16 + .../FindAllTicketNotesService.ts | 8 + .../FindNotesByContactIdAndTicketId.ts | 31 + .../ListTicketNotesService.ts | 49 + .../ShowTicketNoteService.ts | 16 + .../UpdateTicketNoteService.ts | 27 + .../TicketServices/CreateTicketService.ts | 82 + .../TicketServices/DeleteTicketService.ts | 18 + .../FindOrCreateATicketTrakingService.ts | 40 + .../FindOrCreateTicketService.ts | 128 + .../TicketServices/ListTicketsService.ts | 237 + .../ListTicketsServiceKanban.ts | 234 + .../ShowTicketFromUUIDService.ts | 51 + .../TicketServices/ShowTicketService.ts | 57 + .../TicketServices/UpdateTicketService.ts | 297 + .../TypebotServices/typebotListener.ts | 413 + .../services/UserServices/AuthUserService.ts | 61 + .../UserServices/CreateUserService.ts | 107 + .../UserServices/DeleteUserService.ts | 29 + .../services/UserServices/ListUsersService.ts | 64 + .../services/UserServices/ShowUserService.ts | 32 + .../UserServices/SimpleListService.ts | 28 + .../UserServices/UpdateUserService.ts | 91 + .../WbotServices/CheckIsValidContact.ts | 26 + .../src/services/WbotServices/CheckNumber.ts | 29 + .../WbotServices/DeleteWhatsAppMessage.ts | 51 + .../services/WbotServices/GetProfilePicUrl.ts | 22 + .../WbotServices/ImportContactsService.ts | 82 + .../WbotServices/SendWhatsAppMedia.ts | 191 + .../WbotServices/SendWhatsAppMessage.ts | 66 + .../WbotServices/StartAllWhatsAppsSessions.ts | 18 + .../WbotServices/StartWhatsAppSession.ts | 29 + .../src/services/WbotServices/providers.ts | 1527 + .../WbotServices/wbotClosedTickets.ts | 118 + .../WbotServices/wbotMessageListener.ts | 2312 ++ .../src/services/WbotServices/wbotMonitor.ts | 117 + .../WhatsappService/AssociateWhatsappQueue.ts | 12 + .../WhatsappService/CreateWhatsAppService.ts | 178 + .../WhatsappService/DeleteWhatsAppService.ts | 16 + .../WhatsappService/ListWhatsAppsService.ts | 36 + .../WhatsappService/ShowWhatsAppService.ts | 46 + .../WhatsappService/UpdateWhatsAppService.ts | 130 + backend/src/utils/logger.ts | 14 + backend/src/wbotTransferTicketQueue.ts | 82 + backend/tsconfig.json | 14 + frontend/.DS_Store | Bin 0 -> 6148 bytes frontend/.env.exemple | 2 + frontend/package-lock.json | 26964 ++++++++++++++++ frontend/package.json | 90 + frontend/public/android-chrome-192x192.jpg | Bin 0 -> 112803 bytes frontend/public/apple-touch-icon.jpg | Bin 0 -> 112803 bytes frontend/public/favicon-16x16.jpg | Bin 0 -> 112803 bytes frontend/public/favicon-32x32.jpg | Bin 0 -> 112803 bytes frontend/public/favicon.ico | Bin 0 -> 268286 bytes frontend/public/index.html | 28 + frontend/public/manifest.json | 20 + frontend/public/mstile-150x150.jpg | Bin 0 -> 112803 bytes frontend/server.js | 10 + frontend/src/App.js | 116 + frontend/src/assets/chat_notify.mp3 | Bin 0 -> 19326 bytes frontend/src/assets/dialogflow.png | Bin 0 -> 3931 bytes frontend/src/assets/logo.png | Bin 0 -> 32826 bytes frontend/src/assets/n8n.png | Bin 0 -> 251556 bytes frontend/src/assets/planilha.xlsx | Bin 0 -> 5340 bytes frontend/src/assets/sound.mp3 | Bin 0 -> 52244 bytes frontend/src/assets/sound.ogg | Bin 0 -> 26509 bytes frontend/src/assets/typebot.jpg | Bin 0 -> 9342 bytes frontend/src/assets/wa-background-dark.png | Bin 0 -> 62401 bytes frontend/src/assets/wa-background.png | Bin 0 -> 151439 bytes frontend/src/assets/webhook.png | Bin 0 -> 20328 bytes .../src/components/AnnouncementModal/index.js | 338 + .../components/AnnouncementsPopover/index.js | 329 + .../src/components/BackdropLoading/index.js | 23 + .../src/components/ButtonWithSpinner/index.js | 35 + .../src/components/CampaignModal/index.js | 771 + frontend/src/components/Can/index.js | 39 + .../components/CheckoutPage/CheckoutPage.js | 174 + .../CheckoutSuccess/CheckoutSuccess.js | 76 + .../CheckoutPage/CheckoutSuccess/index.js | 2 + .../CheckoutPage/CheckoutSuccess/style.js | 117 + .../FormModel/checkoutFormModel.js | 73 + .../FormModel/formInitialValues.js | 32 + .../FormModel/validationSchema.js | 29 + .../CheckoutPage/Forms/AddressForm.js | 134 + .../CheckoutPage/Forms/PaymentForm.js | 237 + .../ReviewOrder/PaymentDetails.js | 61 + .../ReviewOrder/ProductDetails.js | 33 + .../CheckoutPage/ReviewOrder/ReviewOrder.js | 19 + .../ReviewOrder/ShippingDetails.js | 25 + .../CheckoutPage/ReviewOrder/index.js | 2 + .../CheckoutPage/ReviewOrder/styles.js | 12 + frontend/src/components/CheckoutPage/index.js | 2 + .../src/components/CheckoutPage/styles.js | 23 + frontend/src/components/ColorPicker/index.js | 85 + .../src/components/CompaniesManager/index.js | 627 + .../src/components/ConfirmationModal/index.js | 45 + .../src/components/ContactDrawer/index.js | 199 + .../components/ContactDrawerSkeleton/index.js | 50 + frontend/src/components/ContactForm/index.js | 187 + .../src/components/ContactListDialog/index.js | 181 + .../components/ContactListItemModal/index.js | 242 + .../src/components/ContactListTable/index.js | 103 + frontend/src/components/ContactModal/index.js | 284 + frontend/src/components/ContactNotes/index.js | 204 + .../components/ContactNotesDialog/index.js | 206 + .../ContactNotesDialogListItem/index.js | 64 + frontend/src/components/ContactTag/index.js | 26 + .../src/components/CurrencyInput/index.js | 50 + frontend/src/components/DarkMode/index.js | 70 + .../src/components/Dashboard/CardCounter.js | 53 + .../Dashboard/TableAttendantsStatus.js | 104 + frontend/src/components/Dialog/index.js | 34 + frontend/src/components/FileModal/index.js | 350 + .../components/FormFields/CheckboxField.js | 38 + .../components/FormFields/DatePickerField.js | 54 + .../src/components/FormFields/InputField.js | 26 + .../src/components/FormFields/SelectField.js | 48 + frontend/src/components/FormFields/index.js | 5 + frontend/src/components/HelpsManager/index.js | 290 + .../src/components/LocationPreview/index.js | 50 + .../src/components/MainContainer/index.js | 31 + frontend/src/components/MainHeader/index.js | 19 + .../MainHeaderButtonsWrapper/index.js | 21 + .../src/components/MarkdownWrapper/index.js | 186 + .../components/MessageInput/RecordingTimer.js | 48 + frontend/src/components/MessageInput/index.js | 513 + .../MessageInputCustom/RecordingTimer.js | 48 + .../components/MessageInputCustom/index.js | 773 + .../components/MessageOptionsMenu/index.js | 71 + .../MessageVariablesPicker/index.js | 66 + frontend/src/components/MessagesList/index.js | 830 + .../src/components/ModalImageCors/index.js | 50 + frontend/src/components/ModalUsers/index.js | 263 + .../src/components/NewTicketModal/index.js | 415 + .../components/NotificationsPopOver/index.js | 270 + .../NotificationsPopOver/index_Antigo.js | 275 + .../components/NotificationsVolume/index.js | 110 + .../src/components/OnlyForSuperUser/index.js | 9 + frontend/src/components/OutlinedDiv/index.js | 30 + frontend/src/components/PlansManager/index.js | 559 + frontend/src/components/PromptModal/index.js | 366 + frontend/src/components/QrcodeModal/index.js | 84 + .../components/QueueIntegrationModal/index.js | 505 + frontend/src/components/QueueModal/index.js | 470 + frontend/src/components/QueueOptions/index.js | 345 + .../src/components/QueueSelect/index copy.js | 90 + frontend/src/components/QueueSelect/index.js | 112 + .../src/components/QueueSelect/index_erro.js | 90 + .../src/components/QueueSelectCustom/index.js | 92 + .../src/components/QueueSelectSingle/index.js | 66 + .../components/QuickMessageDialog/index.js | 332 + .../components/QuickMessagesTable/index.js | 93 + .../src/components/ScheduleModal/index.js | 382 + .../src/components/SchedulesForm/index.js | 140 + frontend/src/components/Settings/Options.js | 720 + .../src/components/SubscriptionModal/index.js | 70 + .../components/SubscriptionStepper/index.js | 9 + frontend/src/components/TabPanel/index.js | 18 + .../src/components/TableRowSkeleton/index.js | 52 + frontend/src/components/TagModal/index.js | 269 + .../src/components/TagModal/index.js_Backup | 239 + .../src/components/TagsContainer/index.js | 120 + frontend/src/components/TagsFilter/index.js | 66 + frontend/src/components/Ticket/index.js | 197 + .../components/TicketActionButtons/index.js | 121 + .../TicketActionButtonsCustom/index.js | 149 + .../components/TicketAdvancedLayout/index.js | 10 + frontend/src/components/TicketHeader/index.js | 36 + .../components/TicketHeaderSkeleton/index.js | 36 + frontend/src/components/TicketInfo/index.js | 46 + .../src/components/TicketListItem/index.js | 246 + .../components/TicketListItemCustom/index.js | 551 + .../components/TicketMessagesDialog/index.js | 185 + .../src/components/TicketOptionsMenu/index.js | 127 + frontend/src/components/TicketsList/index.js | 374 + .../src/components/TicketsListCustom/index.js | 333 + .../components/TicketsListSkeleton/index.js | 46 + .../src/components/TicketsManager/index.js | 309 + .../components/TicketsManagerTabs/index.js | 387 + .../components/TicketsQueueSelect/index.js | 60 + frontend/src/components/Title/index.js | 10 + .../components/TransferTicketModal/index.js | 146 + .../TransferTicketModalCustom/index.js | 294 + .../components/UserLanguageSelector/index.js | 71 + frontend/src/components/UserModal/index.js | 329 + frontend/src/components/UsersFilter/index.js | 85 + .../src/components/WhatsAppModal/index.js | 455 + frontend/src/context/Auth/AuthContext.js | 19 + .../ReplyingMessage/ReplyingMessageContext.js | 17 + frontend/src/context/Socket/SocketContext.js | 173 + .../src/context/Tickets/TicketsContext.js | 26 + .../src/context/WhatsApp/WhatsAppsContext.js | 17 + frontend/src/errors/toastError.js | 58 + frontend/src/helpers/contrastColor.js | 36 + frontend/src/hooks/useAuth.js/index.js | 190 + frontend/src/hooks/useCompanies/index.js | 85 + .../src/hooks/useContactListItems/index.js | 57 + frontend/src/hooks/useContactLists/index.js | 56 + frontend/src/hooks/useContacts/index.js | 45 + frontend/src/hooks/useDashboard/index.js | 19 + frontend/src/hooks/useDate/index.js | 30 + frontend/src/hooks/useHelps/index.js | 58 + frontend/src/hooks/useInvoices/index.js | 67 + frontend/src/hooks/useLocalStorage/index.js | 29 + frontend/src/hooks/useMessages/index.js | 38 + frontend/src/hooks/usePlans/index.js | 77 + frontend/src/hooks/useQueues/index.js | 12 + frontend/src/hooks/useQuickMessages/index.js | 48 + .../src/hooks/useQuickMessages_OLD/index.js | 48 + frontend/src/hooks/useSettings/index.js | 29 + frontend/src/hooks/useTicketNotes/index.js | 38 + frontend/src/hooks/useTickets/index.js | 68 + frontend/src/hooks/useUsers/index.js | 38 + frontend/src/hooks/useVersion/index.js | 21 + frontend/src/hooks/useWhatsApps/index.js | 107 + frontend/src/index.js | 22 + frontend/src/layout/MainListItems.js | 522 + frontend/src/layout/index.js | 470 + frontend/src/layout/themeContext.js | 5 + frontend/src/pages/.DS_Store | Bin 0 -> 8196 bytes frontend/src/pages/Annoucements/index.js | 358 + frontend/src/pages/CampaignReport/index.js | 246 + frontend/src/pages/Campaigns/index.js | 425 + frontend/src/pages/CampaignsConfig/index.js | 323 + frontend/src/pages/Chat/ChatList.js | 179 + frontend/src/pages/Chat/ChatMessages.js | 184 + frontend/src/pages/Chat/ChatPopover.js | 294 + frontend/src/pages/Chat/index.js | 455 + frontend/src/pages/Companies/index.js | 182 + frontend/src/pages/Connections/index.js | 435 + frontend/src/pages/ContactListItems/index.js | 437 + frontend/src/pages/ContactLists/index.js | 326 + frontend/src/pages/Contacts/index.js | 381 + frontend/src/pages/Dashboard/Chart.js | 119 + frontend/src/pages/Dashboard/ChartsDate.js | 128 + frontend/src/pages/Dashboard/ChartsUser.js | 141 + frontend/src/pages/Dashboard/Filters.js | 110 + frontend/src/pages/Dashboard/Title.js | 12 + frontend/src/pages/Dashboard/button.css | 9 + frontend/src/pages/Dashboard/index.js | 736 + frontend/src/pages/Dashboard/index_old.js | 351 + frontend/src/pages/Files/index.js | 290 + frontend/src/pages/Financeiro/index.js | 244 + frontend/src/pages/ForgetPassWord/index.js | 356 + frontend/src/pages/Helps/index.js | 172 + frontend/src/pages/Kanban/index.js | 189 + frontend/src/pages/Kanban/responsive.css | 13 + frontend/src/pages/Login/index.js | 167 + frontend/src/pages/Login/style.css | 222 + frontend/src/pages/MessagesAPI/index.js | 341 + frontend/src/pages/Prompts/index.js | 277 + frontend/src/pages/QueueIntegration/index.js | 331 + frontend/src/pages/Queues/index.js | 288 + frontend/src/pages/QuickMessages/index.js | 327 + frontend/src/pages/Schedules.bkp | Bin 0 -> 2917 bytes frontend/src/pages/Schedules/Schedules.css | 22 + frontend/src/pages/Schedules/index.js | 324 + frontend/src/pages/Settings/index.js | 129 + frontend/src/pages/SettingsCustom/index.js | 235 + frontend/src/pages/Signup/index.js | 259 + frontend/src/pages/Signup/style.css | 126 + frontend/src/pages/Subscription/index.js | 139 + frontend/src/pages/Tags/index.js | 304 + .../pages/TicketResponsiveContainer/index.js | 14 + frontend/src/pages/Tickets/index.js | 83 + frontend/src/pages/TicketsAdvanced/index.js | 110 + frontend/src/pages/TicketsCustom/index.js | 81 + frontend/src/pages/ToDoList/index.js | 131 + frontend/src/pages/Users/index.js | 294 + frontend/src/routes/Route.js | 36 + frontend/src/routes/index.js | 183 + frontend/src/rules.js | 22 + frontend/src/services/api.js | 12 + frontend/src/services/socket.js | 3 + frontend/src/translate/i18n.js | 14 + frontend/src/translate/languages/en.js | 412 + frontend/src/translate/languages/es.js | 972 + frontend/src/translate/languages/index.js | 11 + frontend/src/translate/languages/pt.js | 974 + 725 files changed, 91395 insertions(+) create mode 100644 README.md create mode 100644 backend/.editorconfig create mode 100644 backend/.env.example create mode 100644 backend/.eslintignore create mode 100644 backend/.eslintrc.json create mode 100644 backend/.gitignore create mode 100644 backend/.sequelizerc create mode 100644 backend/certs/coloque_seus_certificado_aqui create mode 100644 backend/jest.config.js create mode 100644 backend/package.json create mode 100644 backend/prettier.config.js create mode 100644 backend/src/@types/express.d.ts create mode 100644 backend/src/@types/qrcode-terminal.d.ts create mode 100644 backend/src/app.ts create mode 100644 backend/src/bootstrap.ts create mode 100644 backend/src/config/Gn.ts create mode 100644 backend/src/config/auth.ts create mode 100644 backend/src/config/database.ts create mode 100644 backend/src/config/redis.ts create mode 100644 backend/src/config/upload.ts create mode 100644 backend/src/controllers/AnnouncementController.ts create mode 100644 backend/src/controllers/CampaignController.ts create mode 100644 backend/src/controllers/CampaignSettingController.ts create mode 100644 backend/src/controllers/ChatController.ts create mode 100644 backend/src/controllers/CompanyController.ts create mode 100644 backend/src/controllers/ContactController.ts create mode 100644 backend/src/controllers/ContactListController.ts create mode 100644 backend/src/controllers/ContactListItemController.ts create mode 100644 backend/src/controllers/DashbardController.ts create mode 100644 backend/src/controllers/FilesController.ts create mode 100644 backend/src/controllers/ForgotController.ts create mode 100644 backend/src/controllers/HelpController.ts create mode 100644 backend/src/controllers/ImportPhoneContactsController.ts create mode 100644 backend/src/controllers/InvoicesController.ts create mode 100644 backend/src/controllers/MessageController.ts create mode 100644 backend/src/controllers/PlanController.ts create mode 100644 backend/src/controllers/PromptController.ts create mode 100644 backend/src/controllers/QueueController.ts create mode 100644 backend/src/controllers/QueueIntegrationController.ts create mode 100644 backend/src/controllers/QueueOptionController.ts create mode 100644 backend/src/controllers/QuickMessageController.ts create mode 100644 backend/src/controllers/QuickMessageController_OLD.ts create mode 100644 backend/src/controllers/ScheduleController.ts create mode 100644 backend/src/controllers/SessionController.ts create mode 100644 backend/src/controllers/SettingController.ts create mode 100644 backend/src/controllers/SubscriptionController.ts create mode 100644 backend/src/controllers/TagController.ts create mode 100644 backend/src/controllers/TicketController.ts create mode 100644 backend/src/controllers/TicketNoteController.ts create mode 100644 backend/src/controllers/TicketTagController.ts create mode 100644 backend/src/controllers/UserController.ts create mode 100644 backend/src/controllers/VersionController.ts create mode 100644 backend/src/controllers/WhatsAppController.ts create mode 100644 backend/src/controllers/WhatsAppSessionController.ts create mode 100644 backend/src/database/index.ts create mode 100644 backend/src/database/migrations/20200717133431-add-uuid-ossp.ts create mode 100644 backend/src/database/migrations/20200717133438-create-users.ts create mode 100644 backend/src/database/migrations/20200717144403-create-contacts.ts create mode 100644 backend/src/database/migrations/20200717145643-create-tickets.ts create mode 100644 backend/src/database/migrations/20200717151645-create-messages.ts create mode 100644 backend/src/database/migrations/20200717170223-create-whatsapps.ts create mode 100644 backend/src/database/migrations/20200723200315-create-contacts-custom-fields.ts create mode 100644 backend/src/database/migrations/20200723202116-add-email-field-to-contacts.ts create mode 100644 backend/src/database/migrations/20200730153237-remove-user-association-from-messages.ts create mode 100644 backend/src/database/migrations/20200730153545-add-fromMe-to-messages.ts create mode 100644 backend/src/database/migrations/20200813114236-change-ticket-lastMessage-column-type.ts create mode 100644 backend/src/database/migrations/20200901235509-add-profile-column-to-users.ts create mode 100644 backend/src/database/migrations/20200903215941-create-settings.ts create mode 100644 backend/src/database/migrations/20200904220257-add-name-to-whatsapp.ts create mode 100644 backend/src/database/migrations/20200906122228-add-name-default-field-to-whatsapp.ts create mode 100644 backend/src/database/migrations/20200906155658-add-whatsapp-field-to-tickets.ts create mode 100644 backend/src/database/migrations/20200919124112-update-default-column-name-on-whatsappp.ts create mode 100644 backend/src/database/migrations/20200927220708-add-isDeleted-column-to-messages.ts create mode 100644 backend/src/database/migrations/20200929145451-add-user-tokenVersion-column.ts create mode 100644 backend/src/database/migrations/20200930162323-add-isGroup-column-to-tickets.ts create mode 100644 backend/src/database/migrations/20200930194808-add-isGroup-column-to-contacts.ts create mode 100644 backend/src/database/migrations/20201004150008-add-contactId-column-to-messages.ts create mode 100644 backend/src/database/migrations/20201004155719-add-vcardContactId-column-to-messages.ts create mode 100644 backend/src/database/migrations/20201004955719-remove-vcardContactId-column-to-messages.ts create mode 100644 backend/src/database/migrations/20201026215410-add-retries-to-whatsapps.ts create mode 100644 backend/src/database/migrations/20201028124427-add-quoted-msg-to-messages.ts create mode 100644 backend/src/database/migrations/20210108001431-add-unreadMessages-to-tickets.ts create mode 100644 backend/src/database/migrations/20210108164404-create-queues.ts create mode 100644 backend/src/database/migrations/20210108164504-add-queueId-to-tickets.ts create mode 100644 backend/src/database/migrations/20210108174594-associate-whatsapp-queue.ts create mode 100644 backend/src/database/migrations/20210108204708-associate-users-queue.ts create mode 100644 backend/src/database/migrations/20210109192513-add-greetingMessage-to-whatsapp.ts create mode 100644 backend/src/database/migrations/20210109192514-create-companies-table.ts create mode 100644 backend/src/database/migrations/20210109192515-add-column-companyId-to-Settings-table.ts create mode 100644 backend/src/database/migrations/20210109192516-add-column-companyId-to-Users-table.ts create mode 100644 backend/src/database/migrations/20210109192517-add-column-companyId-to-Contacts-table.ts create mode 100644 backend/src/database/migrations/20210109192518-add-column-companyId-to-Messages-table.ts create mode 100644 backend/src/database/migrations/20210109192519-add-column-companyId-to-Queues-table.ts create mode 100644 backend/src/database/migrations/20210109192520-add-column-companyId-to-Whatsapps-table.ts create mode 100644 backend/src/database/migrations/20210109192521-add-column-companyId-to-Tickets-table.ts create mode 100644 backend/src/database/migrations/20210109192522-create-plans-table.ts create mode 100644 backend/src/database/migrations/20210109192523-add-column-planId-to-Companies.ts create mode 100644 backend/src/database/migrations/20210109192523-add-column-status-and-schedules-to-Companies.ts create mode 100644 backend/src/database/migrations/20210109192523-create-ticket-notes.ts create mode 100644 backend/src/database/migrations/20210109192524-create-quick-messages.ts create mode 100644 backend/src/database/migrations/20210109192525-add-column-complationMessage-to-whatsapp.ts create mode 100644 backend/src/database/migrations/20210109192526-add-column-outOfHoursMessage-to-whatsapp .ts create mode 100644 backend/src/database/migrations/20210109192527-add-column-super-to-Users-table.ts create mode 100644 backend/src/database/migrations/20210109192528-change-column-message-to-quick-messages-table.ts create mode 100644 backend/src/database/migrations/20210109192529-create-helps.ts create mode 100644 backend/src/database/migrations/20210109192530-add-unique-constraint-to-Contacts-table.ts create mode 100644 backend/src/database/migrations/20210109192531-create-TicketTracking-table.ts create mode 100644 backend/src/database/migrations/20210109192532-add-column-online-to-Users-table.ts create mode 100644 backend/src/database/migrations/20210109192533-create-UserRatings-table.ts create mode 100644 backend/src/database/migrations/20210109192534-add-rated-to-TicketTraking.ts create mode 100644 backend/src/database/migrations/20210109192535-add-column-ratingMessage-to-whatsapp.ts create mode 100644 backend/src/database/migrations/20210109192536-add-unique-constraint-to-Tickets-table.ts create mode 100644 backend/src/database/migrations/20210818102606-add-uuid-to-tickets.ts create mode 100644 backend/src/database/migrations/20210818102607-remove-unique-indexes-to-Queues-table.ts create mode 100644 backend/src/database/migrations/20210818102608-add-unique-indexes-to-Queues-table.ts create mode 100644 backend/src/database/migrations/20210818102609-add-token-to-Whatsapps.ts create mode 100644 backend/src/database/migrations/20211205164404-create-queue-options.ts create mode 100644 backend/src/database/migrations/20211212125704-add-chatbot-to-tickets.ts create mode 100644 backend/src/database/migrations/20211227010200-create-schedules.ts create mode 100644 backend/src/database/migrations/20220115114088-add-column-userId-to-QuickMessages-table.ts create mode 100644 backend/src/database/migrations/20220117130000-create-tags.ts create mode 100644 backend/src/database/migrations/20220117134400-associate-tickets-tags.ts create mode 100644 backend/src/database/migrations/20220122160900-add-status-to-schedules.ts create mode 100644 backend/src/database/migrations/20220220014719-add-farewellMessage-to-whatsapp.ts create mode 100644 backend/src/database/migrations/20220221014717-add-provider-whatsapp.ts create mode 100644 backend/src/database/migrations/20220221014718-add-remoteJid-messages.ts create mode 100644 backend/src/database/migrations/20220221014719-add-jsonMessage-messages.ts create mode 100644 backend/src/database/migrations/20220221014720-add-participant-messages.ts create mode 100644 backend/src/database/migrations/20220221014721-create-baileys.ts create mode 100644 backend/src/database/migrations/20220315110000-create-ContactLists-table.ts create mode 100644 backend/src/database/migrations/20220315110001-create-ContactListItems-table.ts create mode 100644 backend/src/database/migrations/20220315110002-create-Campaigns-table.ts create mode 100644 backend/src/database/migrations/20220315110004-create-CampaignSettings-table.ts create mode 100644 backend/src/database/migrations/20220315110005-remove-constraint-to-Settings.ts create mode 100644 backend/src/database/migrations/20220321130000-create-CampaignShipping.ts create mode 100644 backend/src/database/migrations/20220404000000-add-column-queueId-to-Messages-table.ts create mode 100644 backend/src/database/migrations/20220406000000-add-column-dueDate-to-Companies.ts create mode 100644 backend/src/database/migrations/20220406000001-add-column-recurrence-to-Companies.ts create mode 100644 backend/src/database/migrations/20220411000000-add-column-startTime-and-endTime-to-Queues.ts create mode 100644 backend/src/database/migrations/20220411000001-remove-column-startTime-and-endTime-to-Queues.ts create mode 100644 backend/src/database/migrations/20220411000002-add-column-schedules-and-outOfHoursMessage-to-Queues.ts create mode 100644 backend/src/database/migrations/20220411000003-create-table-Announcements.ts create mode 100644 backend/src/database/migrations/20220425000000-create-table-Chats.ts create mode 100644 backend/src/database/migrations/20220425000001-create-table-ChatUsers.ts create mode 100644 backend/src/database/migrations/20220425000002-create-table-ChatMessages.ts create mode 100644 backend/src/database/migrations/20220512000001-create-Indexes.ts create mode 100644 backend/src/database/migrations/20220512000002-create-subscriptions.ts create mode 100644 backend/src/database/migrations/20220512000003-create-invoices.ts create mode 100644 backend/src/database/migrations/20220723000001-add-mediaPath-to-quickmessages.ts create mode 100644 backend/src/database/migrations/20220723000002-add-mediaName-to-quickemessages.ts create mode 100644 backend/src/database/migrations/20222016014720-create-baileys-chats.ts create mode 100644 backend/src/database/migrations/20222016014721-create-baileys-chats Messages.ts create mode 100644 backend/src/database/migrations/20230106164900-add-useCampaigns-Plans.ts create mode 100644 backend/src/database/migrations/20230106164900-add-useExternalApi-Plans.ts create mode 100644 backend/src/database/migrations/20230106164900-add-useInternalChat-Plans.ts create mode 100644 backend/src/database/migrations/20230106164900-add-useSchedules-Plans.ts create mode 100644 backend/src/database/migrations/20230303223001-add-amountUsedBotQueues-to-tickets.ts create mode 100644 backend/src/database/migrations/20230417203900-add-allTickets-user.ts create mode 100644 backend/src/database/migrations/20230603212335-create-QueueIntegrations.ts create mode 100644 backend/src/database/migrations/20230603212337-add-urlN8N-QueueIntegrations.ts create mode 100644 backend/src/database/migrations/20230623095932-add-whatsapp-to-user.ts create mode 100644 backend/src/database/migrations/20230623133903-add-chatbotAt-ticket-tracking.ts create mode 100644 backend/src/database/migrations/20230628134807-add-orderQueue-Queue.ts create mode 100644 backend/src/database/migrations/20230711094417-add-column-companyId-to-QueueIntegrations-table.ts create mode 100644 backend/src/database/migrations/20230711111701-add-sendIdQueue-to-whatsapp.ts create mode 100644 backend/src/database/migrations/20230714113901-create-Files.ts create mode 100644 backend/src/database/migrations/20230714113902-create-fileOptions.ts create mode 100644 backend/src/database/migrations/20230723301001-add-kanban-to-Tags.ts create mode 100644 backend/src/database/migrations/20230801081907-add-collumns-Ticket.ts create mode 100644 backend/src/database/migrations/20230813114236-change-ticket-lastMessage-column-type.ts create mode 100644 backend/src/database/migrations/20230824082607-add-mediaType-FilesOptions.ts create mode 100644 backend/src/database/migrations/20230828143411-add-Integrations-to-tickets.ts create mode 100644 backend/src/database/migrations/20230828144000-create-prompts.ts create mode 100644 backend/src/database/migrations/20230828144100-add-column-promptid-into-whatsapps.ts create mode 100644 backend/src/database/migrations/20230831093000-add-useKanban-Plans.ts create mode 100644 backend/src/database/migrations/20230922212337-add-integrationId-Queues.ts create mode 100644 backend/src/database/migrations/20230924212337-add-fileListId-Campaigns.ts create mode 100644 backend/src/database/migrations/20231111185822-add_reset_password_column.ts create mode 100644 backend/src/database/migrations/20231117000001-add-mediaName-to-schedules.ts create mode 100644 backend/src/database/migrations/20231117000001-add-mediaPath-to-schedules.ts create mode 100644 backend/src/database/migrations/20231127113000-add-columns-Plans.ts create mode 100644 backend/src/database/migrations/20231128123537-add-typebot-QueueIntegrations.ts create mode 100644 backend/src/database/migrations/20231202143411-add-typebotSessionId-to-tickets.ts create mode 100644 backend/src/database/migrations/20231207080337-add-typebotDelayMessage-QueueIntegrations.ts create mode 100644 backend/src/database/migrations/20231207085011-add-typebotStatus-to-tickets.ts create mode 100644 backend/src/database/migrations/20231214092337-add-promptId-Queues.ts create mode 100644 backend/src/database/migrations/20231214143411-add-columns-to-whatsapps.ts create mode 100644 backend/src/database/migrations/20231214143411-add-promptId-to-tickets.ts create mode 100644 backend/src/database/migrations/20231218160937-add-columns-QueueIntegrations.ts create mode 100644 backend/src/database/migrations/20231219153800-add-isEdited-column-to-messages.ts create mode 100644 backend/src/database/migrations/20231220192536-add-unique-constraint-to-Tickets-table.ts create mode 100644 backend/src/database/migrations/20231220223517-add-column-whatsappId-to-Contacts.ts create mode 100644 backend/src/database/migrations/20232016014719-add-transferTime-and-queueIdTransfer.ts create mode 100644 backend/src/database/seeds/20200904070005-create-default-company.ts create mode 100644 backend/src/database/seeds/20200904070006-create-default-user.ts create mode 100644 backend/src/database/seeds/20200904070007-create-default-settings.ts create mode 100644 backend/src/database/seeds/20230130004700-create-alltickets-settings.ts create mode 100644 backend/src/errors/AppError.ts create mode 100644 backend/src/errors/toastError.js create mode 100644 backend/src/helpers/CheckContactOpenTickets.ts create mode 100644 backend/src/helpers/CheckContactSomeTicket.ts create mode 100644 backend/src/helpers/CheckSettings.ts create mode 100644 backend/src/helpers/CreateTokens.ts create mode 100644 backend/src/helpers/Debounce.ts create mode 100644 backend/src/helpers/GetDefaultWhatsApp.ts create mode 100644 backend/src/helpers/GetDefaultWhatsAppByUser.ts create mode 100644 backend/src/helpers/GetTicketWbot.ts create mode 100644 backend/src/helpers/GetWbotMessage.ts create mode 100644 backend/src/helpers/GetWhatsappWbot.ts create mode 100644 backend/src/helpers/Mustache.ts create mode 100644 backend/src/helpers/SendMessage.ts create mode 100644 backend/src/helpers/SendRefreshToken.ts create mode 100644 backend/src/helpers/SerializeUser.ts create mode 100644 backend/src/helpers/SerializeWbotMsgId.ts create mode 100644 backend/src/helpers/SetTicketMessagesAsRead.ts create mode 100644 backend/src/helpers/UpdateDeletedUserOpenTicketsStatus.ts create mode 100644 backend/src/helpers/authState.ts create mode 100644 backend/src/libs/cache.ts create mode 100644 backend/src/libs/counter.ts create mode 100644 backend/src/libs/socket.ts create mode 100644 backend/src/libs/store.d.ts create mode 100644 backend/src/libs/wbot.ts create mode 100644 backend/src/middleware/envTokenAuth.ts create mode 100644 backend/src/middleware/isAuth.ts create mode 100644 backend/src/middleware/isSuper.ts create mode 100644 backend/src/middleware/tokenAuth.ts create mode 100644 backend/src/models/Announcement.ts create mode 100644 backend/src/models/Baileys.ts create mode 100644 backend/src/models/BaileysChats.ts create mode 100644 backend/src/models/Campaign.ts create mode 100644 backend/src/models/CampaignSetting.ts create mode 100644 backend/src/models/CampaignShipping.ts create mode 100644 backend/src/models/Chat.ts create mode 100644 backend/src/models/ChatMessage.ts create mode 100644 backend/src/models/ChatUser.ts create mode 100644 backend/src/models/Company.ts create mode 100644 backend/src/models/Contact.ts create mode 100644 backend/src/models/ContactCustomField.ts create mode 100644 backend/src/models/ContactList.ts create mode 100644 backend/src/models/ContactListItem.ts create mode 100644 backend/src/models/Files.ts create mode 100644 backend/src/models/FilesOptions.ts create mode 100644 backend/src/models/Help.ts create mode 100644 backend/src/models/Invoices.ts create mode 100644 backend/src/models/Message.ts create mode 100644 backend/src/models/Plan.ts create mode 100644 backend/src/models/Prompt.ts create mode 100644 backend/src/models/Queue.ts create mode 100644 backend/src/models/QueueIntegrations.ts create mode 100644 backend/src/models/QueueOption.ts create mode 100644 backend/src/models/QuickMessage.ts create mode 100644 backend/src/models/Schedule.ts create mode 100644 backend/src/models/Setting.ts create mode 100644 backend/src/models/Subscriptions.ts create mode 100644 backend/src/models/Tag.ts create mode 100644 backend/src/models/Ticket.ts create mode 100644 backend/src/models/TicketNote.ts create mode 100644 backend/src/models/TicketTag.ts create mode 100644 backend/src/models/TicketTraking.ts create mode 100644 backend/src/models/User.ts create mode 100644 backend/src/models/UserQueue.ts create mode 100644 backend/src/models/UserRating.ts create mode 100644 backend/src/models/Whatsapp.ts create mode 100644 backend/src/models/WhatsappQueue.ts create mode 100644 backend/src/queues.ts create mode 100644 backend/src/routes/announcementRoutes.ts create mode 100644 backend/src/routes/authRoutes.ts create mode 100644 backend/src/routes/campaignRoutes.ts create mode 100644 backend/src/routes/campaignSettingRoutes.ts create mode 100644 backend/src/routes/chatRoutes.ts create mode 100644 backend/src/routes/companyRoutes.ts create mode 100644 backend/src/routes/contactListItemRoutes.ts create mode 100644 backend/src/routes/contactListRoutes.ts create mode 100644 backend/src/routes/contactRoutes.ts create mode 100644 backend/src/routes/dashboardRoutes.ts create mode 100644 backend/src/routes/filesRoutes.ts create mode 100644 backend/src/routes/forgotPasswordRoutes.ts create mode 100644 backend/src/routes/helpRoutes.ts create mode 100644 backend/src/routes/index.ts create mode 100644 backend/src/routes/invoicesRoutes.ts create mode 100644 backend/src/routes/messageRoutes.ts create mode 100644 backend/src/routes/planRoutes.ts create mode 100644 backend/src/routes/promptRouter.ts create mode 100644 backend/src/routes/queueIntegrationRoutes.ts create mode 100644 backend/src/routes/queueOptionRoutes.ts create mode 100644 backend/src/routes/queueRoutes.ts create mode 100644 backend/src/routes/quickMessageRoutes.ts create mode 100644 backend/src/routes/scheduleRoutes.ts create mode 100644 backend/src/routes/settingRoutes.ts create mode 100644 backend/src/routes/subScriptionRoutes.ts create mode 100644 backend/src/routes/tagRoutes.ts create mode 100644 backend/src/routes/ticketNoteRoutes.ts create mode 100644 backend/src/routes/ticketRoutes.ts create mode 100644 backend/src/routes/ticketTagRoutes.ts create mode 100644 backend/src/routes/userRoutes.ts create mode 100644 backend/src/routes/versionRoutes.ts create mode 100644 backend/src/routes/whatsappRoutes.ts create mode 100644 backend/src/routes/whatsappSessionRoutes.ts create mode 100644 backend/src/server.ts create mode 100644 backend/src/services/AnnouncementService/CreateService.ts create mode 100644 backend/src/services/AnnouncementService/DeleteService.ts create mode 100644 backend/src/services/AnnouncementService/FindAllService.ts create mode 100644 backend/src/services/AnnouncementService/FindService.ts create mode 100644 backend/src/services/AnnouncementService/ListService.ts create mode 100644 backend/src/services/AnnouncementService/ShowService.ts create mode 100644 backend/src/services/AnnouncementService/UpdateService.ts create mode 100644 backend/src/services/AuthServices/FindUserFromToken.ts create mode 100644 backend/src/services/AuthServices/RefreshTokenService.ts create mode 100644 backend/src/services/BaileysChatServices/CreateOrUpdateBaileysChatService.ts create mode 100644 backend/src/services/BaileysChatServices/DeleteBaileysChatServices.ts create mode 100644 backend/src/services/BaileysChatServices/ShowBaileysChatService.ts create mode 100644 backend/src/services/BaileysChatServices/UpdateBaileysChatServices.ts create mode 100644 backend/src/services/BaileysServices/CreateOrUpdateBaileysService.ts create mode 100644 backend/src/services/BaileysServices/DeleteBaileysService.ts create mode 100644 backend/src/services/BaileysServices/ShowBaileysService.ts create mode 100644 backend/src/services/CampaignService/CancelService.ts create mode 100644 backend/src/services/CampaignService/CreateService.ts create mode 100644 backend/src/services/CampaignService/DeleteService.ts create mode 100644 backend/src/services/CampaignService/FindAllService.ts create mode 100644 backend/src/services/CampaignService/FindService.ts create mode 100644 backend/src/services/CampaignService/ListService.ts create mode 100644 backend/src/services/CampaignService/RestartService.ts create mode 100644 backend/src/services/CampaignService/ShowService.ts create mode 100644 backend/src/services/CampaignService/UpdateService.ts create mode 100644 backend/src/services/CampaignSettingServices/CreateService.ts create mode 100644 backend/src/services/CampaignSettingServices/ListService.ts create mode 100644 backend/src/services/ChatService/CreateMessageService.ts create mode 100644 backend/src/services/ChatService/CreateService.ts create mode 100644 backend/src/services/ChatService/DeleteService.ts create mode 100644 backend/src/services/ChatService/FindAllService.ts create mode 100644 backend/src/services/ChatService/FindMessages.ts create mode 100644 backend/src/services/ChatService/FindService.ts create mode 100644 backend/src/services/ChatService/ListService.ts create mode 100644 backend/src/services/ChatService/ShowFromUuidService.ts create mode 100644 backend/src/services/ChatService/ShowService.ts create mode 100644 backend/src/services/ChatService/UpdateService.ts create mode 100644 backend/src/services/CompanyService/CreateCompanyService.ts create mode 100644 backend/src/services/CompanyService/DeleteCompanyService.ts create mode 100644 backend/src/services/CompanyService/FindAllCompaniesService.ts create mode 100644 backend/src/services/CompanyService/ListCompaniesPlanService.ts create mode 100644 backend/src/services/CompanyService/ListCompaniesService.ts create mode 100644 backend/src/services/CompanyService/ShowCompanyService.ts create mode 100644 backend/src/services/CompanyService/ShowPlanCompanyService.ts create mode 100644 backend/src/services/CompanyService/UpdateCompanyService.ts create mode 100644 backend/src/services/CompanyService/UpdateSchedulesService.ts create mode 100644 backend/src/services/CompanyService/VerifyCurrentSchedule.ts create mode 100644 backend/src/services/ContactListItemService/CreateService.ts create mode 100644 backend/src/services/ContactListItemService/DeleteService.ts create mode 100644 backend/src/services/ContactListItemService/FindAllService.ts create mode 100644 backend/src/services/ContactListItemService/FindService.ts create mode 100644 backend/src/services/ContactListItemService/ListService.ts create mode 100644 backend/src/services/ContactListItemService/ShowService.ts create mode 100644 backend/src/services/ContactListItemService/UpdateService.ts create mode 100644 backend/src/services/ContactListService/CreateService.ts create mode 100644 backend/src/services/ContactListService/DeleteService.ts create mode 100644 backend/src/services/ContactListService/FindAllService.ts create mode 100644 backend/src/services/ContactListService/FindService.ts create mode 100644 backend/src/services/ContactListService/ImportContacts.ts create mode 100644 backend/src/services/ContactListService/ListService.ts create mode 100644 backend/src/services/ContactListService/ShowService.ts create mode 100644 backend/src/services/ContactListService/UpdateService.ts create mode 100644 backend/src/services/ContactServices/CreateContactService.ts create mode 100644 backend/src/services/ContactServices/CreateOrUpdateContactService.ts create mode 100644 backend/src/services/ContactServices/DeleteContactService.ts create mode 100644 backend/src/services/ContactServices/GetContactService.ts create mode 100644 backend/src/services/ContactServices/ListContactsService.ts create mode 100644 backend/src/services/ContactServices/ShowContactService.ts create mode 100644 backend/src/services/ContactServices/SimpleListService.ts create mode 100644 backend/src/services/ContactServices/UpdateContactService.ts create mode 100644 backend/src/services/FileServices/CreateService.ts create mode 100644 backend/src/services/FileServices/DeleteAllService.ts create mode 100644 backend/src/services/FileServices/DeleteService.ts create mode 100644 backend/src/services/FileServices/ListService.ts create mode 100644 backend/src/services/FileServices/ShowService.ts create mode 100644 backend/src/services/FileServices/SimpleListService.ts create mode 100644 backend/src/services/FileServices/UpdateService.ts create mode 100644 backend/src/services/ForgotPassWordServices/SendMail.ts create mode 100644 backend/src/services/HelpServices/CreateService.ts create mode 100644 backend/src/services/HelpServices/DeleteService.ts create mode 100644 backend/src/services/HelpServices/FindAllService.ts create mode 100644 backend/src/services/HelpServices/FindService.ts create mode 100644 backend/src/services/HelpServices/ListService.ts create mode 100644 backend/src/services/HelpServices/ShowService.ts create mode 100644 backend/src/services/HelpServices/UpdateService.ts create mode 100644 backend/src/services/InvoicesService/FindAllInvoiceService.ts create mode 100644 backend/src/services/InvoicesService/ListInvoicesServices.ts create mode 100644 backend/src/services/InvoicesService/ShowInvoiceService.ts create mode 100644 backend/src/services/InvoicesService/UpdateInvoiceService.ts create mode 100644 backend/src/services/MessageServices/CreateMessageService.ts create mode 100644 backend/src/services/MessageServices/GetMessagesService.ts create mode 100644 backend/src/services/MessageServices/ListMessagesService.ts create mode 100644 backend/src/services/PlanService/CreatePlanService.ts create mode 100644 backend/src/services/PlanService/DeletePlanService.ts create mode 100644 backend/src/services/PlanService/FindAllPlanService.ts create mode 100644 backend/src/services/PlanService/ListPlansService.ts create mode 100644 backend/src/services/PlanService/ShowPlanService.ts create mode 100644 backend/src/services/PlanService/UpdatePlanService.ts create mode 100644 backend/src/services/PromptServices/CreatePromptService.ts create mode 100644 backend/src/services/PromptServices/DeletePromptService.ts create mode 100644 backend/src/services/PromptServices/ListPromptsService.ts create mode 100644 backend/src/services/PromptServices/ShowPromptService.ts create mode 100644 backend/src/services/PromptServices/UpdatePromptService.ts create mode 100644 backend/src/services/QueueIntegrationServices/CreateQueueIntegrationService.ts create mode 100644 backend/src/services/QueueIntegrationServices/DeleteQueueIntegrationService.ts create mode 100644 backend/src/services/QueueIntegrationServices/ListQueueIntegrationService.ts create mode 100644 backend/src/services/QueueIntegrationServices/ShowQueueIntegrationService.ts create mode 100644 backend/src/services/QueueIntegrationServices/UpdateQueueIntegrationService.ts create mode 100644 backend/src/services/QueueOptionService/CreateService.ts create mode 100644 backend/src/services/QueueOptionService/DeleteService.ts create mode 100644 backend/src/services/QueueOptionService/ListService.ts create mode 100644 backend/src/services/QueueOptionService/ShowService.ts create mode 100644 backend/src/services/QueueOptionService/UpdateService.ts create mode 100644 backend/src/services/QueueService/CreateQueueService.ts create mode 100644 backend/src/services/QueueService/DeleteQueueService.ts create mode 100644 backend/src/services/QueueService/ListQueuesService.ts create mode 100644 backend/src/services/QueueService/ShowQueueService.ts create mode 100644 backend/src/services/QueueService/UpdateQueueService.ts create mode 100644 backend/src/services/QuickMessageService/CreateService.ts create mode 100644 backend/src/services/QuickMessageService/DeleteService.ts create mode 100644 backend/src/services/QuickMessageService/FindAllService.ts create mode 100644 backend/src/services/QuickMessageService/FindService.ts create mode 100644 backend/src/services/QuickMessageService/ListService.ts create mode 100644 backend/src/services/QuickMessageService/ShowService.ts create mode 100644 backend/src/services/QuickMessageService/UpdateService.ts create mode 100644 backend/src/services/ReportService/DashbardDataService.ts create mode 100644 backend/src/services/ReportService/TicketsAttendance.ts create mode 100644 backend/src/services/ReportService/TicketsDayService.ts create mode 100644 backend/src/services/ResetPasswordService/ResetPassword.ts create mode 100644 backend/src/services/ResetPasswordService/ResetPassword.ts.bak create mode 100644 backend/src/services/ScheduleServices/CreateService.ts create mode 100644 backend/src/services/ScheduleServices/DeleteService.ts create mode 100644 backend/src/services/ScheduleServices/ListService.ts create mode 100644 backend/src/services/ScheduleServices/ShowService.ts create mode 100644 backend/src/services/ScheduleServices/UpdateService.ts create mode 100644 backend/src/services/SettingServices/ListSettingsService.ts create mode 100644 backend/src/services/SettingServices/ListSettingsServiceOne.ts create mode 100644 backend/src/services/SettingServices/UpdateSettingService.ts create mode 100644 backend/src/services/TagServices/CreateService.ts create mode 100644 backend/src/services/TagServices/DeleteService.ts create mode 100644 backend/src/services/TagServices/KanbanListService.ts create mode 100644 backend/src/services/TagServices/ListService.ts create mode 100644 backend/src/services/TagServices/ShowService.ts create mode 100644 backend/src/services/TagServices/SimpleListService.ts create mode 100644 backend/src/services/TagServices/SyncTagsService.ts create mode 100644 backend/src/services/TagServices/UpdateService.ts create mode 100644 backend/src/services/TicketNoteService/CreateTicketNoteService.ts create mode 100644 backend/src/services/TicketNoteService/DeleteTicketNoteService.ts create mode 100644 backend/src/services/TicketNoteService/FindAllTicketNotesService.ts create mode 100644 backend/src/services/TicketNoteService/FindNotesByContactIdAndTicketId.ts create mode 100644 backend/src/services/TicketNoteService/ListTicketNotesService.ts create mode 100644 backend/src/services/TicketNoteService/ShowTicketNoteService.ts create mode 100644 backend/src/services/TicketNoteService/UpdateTicketNoteService.ts create mode 100644 backend/src/services/TicketServices/CreateTicketService.ts create mode 100644 backend/src/services/TicketServices/DeleteTicketService.ts create mode 100644 backend/src/services/TicketServices/FindOrCreateATicketTrakingService.ts create mode 100644 backend/src/services/TicketServices/FindOrCreateTicketService.ts create mode 100644 backend/src/services/TicketServices/ListTicketsService.ts create mode 100644 backend/src/services/TicketServices/ListTicketsServiceKanban.ts create mode 100644 backend/src/services/TicketServices/ShowTicketFromUUIDService.ts create mode 100644 backend/src/services/TicketServices/ShowTicketService.ts create mode 100644 backend/src/services/TicketServices/UpdateTicketService.ts create mode 100644 backend/src/services/TypebotServices/typebotListener.ts create mode 100644 backend/src/services/UserServices/AuthUserService.ts create mode 100644 backend/src/services/UserServices/CreateUserService.ts create mode 100644 backend/src/services/UserServices/DeleteUserService.ts create mode 100644 backend/src/services/UserServices/ListUsersService.ts create mode 100644 backend/src/services/UserServices/ShowUserService.ts create mode 100644 backend/src/services/UserServices/SimpleListService.ts create mode 100644 backend/src/services/UserServices/UpdateUserService.ts create mode 100644 backend/src/services/WbotServices/CheckIsValidContact.ts create mode 100644 backend/src/services/WbotServices/CheckNumber.ts create mode 100644 backend/src/services/WbotServices/DeleteWhatsAppMessage.ts create mode 100644 backend/src/services/WbotServices/GetProfilePicUrl.ts create mode 100644 backend/src/services/WbotServices/ImportContactsService.ts create mode 100644 backend/src/services/WbotServices/SendWhatsAppMedia.ts create mode 100644 backend/src/services/WbotServices/SendWhatsAppMessage.ts create mode 100644 backend/src/services/WbotServices/StartAllWhatsAppsSessions.ts create mode 100644 backend/src/services/WbotServices/StartWhatsAppSession.ts create mode 100644 backend/src/services/WbotServices/providers.ts create mode 100644 backend/src/services/WbotServices/wbotClosedTickets.ts create mode 100644 backend/src/services/WbotServices/wbotMessageListener.ts create mode 100644 backend/src/services/WbotServices/wbotMonitor.ts create mode 100644 backend/src/services/WhatsappService/AssociateWhatsappQueue.ts create mode 100644 backend/src/services/WhatsappService/CreateWhatsAppService.ts create mode 100644 backend/src/services/WhatsappService/DeleteWhatsAppService.ts create mode 100644 backend/src/services/WhatsappService/ListWhatsAppsService.ts create mode 100644 backend/src/services/WhatsappService/ShowWhatsAppService.ts create mode 100644 backend/src/services/WhatsappService/UpdateWhatsAppService.ts create mode 100644 backend/src/utils/logger.ts create mode 100644 backend/src/wbotTransferTicketQueue.ts create mode 100644 backend/tsconfig.json create mode 100644 frontend/.DS_Store create mode 100644 frontend/.env.exemple create mode 100644 frontend/package-lock.json create mode 100644 frontend/package.json create mode 100644 frontend/public/android-chrome-192x192.jpg create mode 100644 frontend/public/apple-touch-icon.jpg create mode 100644 frontend/public/favicon-16x16.jpg create mode 100644 frontend/public/favicon-32x32.jpg create mode 100644 frontend/public/favicon.ico create mode 100644 frontend/public/index.html create mode 100644 frontend/public/manifest.json create mode 100644 frontend/public/mstile-150x150.jpg create mode 100644 frontend/server.js create mode 100644 frontend/src/App.js create mode 100644 frontend/src/assets/chat_notify.mp3 create mode 100644 frontend/src/assets/dialogflow.png create mode 100644 frontend/src/assets/logo.png create mode 100644 frontend/src/assets/n8n.png create mode 100644 frontend/src/assets/planilha.xlsx create mode 100644 frontend/src/assets/sound.mp3 create mode 100644 frontend/src/assets/sound.ogg create mode 100644 frontend/src/assets/typebot.jpg create mode 100644 frontend/src/assets/wa-background-dark.png create mode 100644 frontend/src/assets/wa-background.png create mode 100644 frontend/src/assets/webhook.png create mode 100644 frontend/src/components/AnnouncementModal/index.js create mode 100644 frontend/src/components/AnnouncementsPopover/index.js create mode 100644 frontend/src/components/BackdropLoading/index.js create mode 100644 frontend/src/components/ButtonWithSpinner/index.js create mode 100644 frontend/src/components/CampaignModal/index.js create mode 100644 frontend/src/components/Can/index.js create mode 100644 frontend/src/components/CheckoutPage/CheckoutPage.js create mode 100644 frontend/src/components/CheckoutPage/CheckoutSuccess/CheckoutSuccess.js create mode 100644 frontend/src/components/CheckoutPage/CheckoutSuccess/index.js create mode 100644 frontend/src/components/CheckoutPage/CheckoutSuccess/style.js create mode 100644 frontend/src/components/CheckoutPage/FormModel/checkoutFormModel.js create mode 100644 frontend/src/components/CheckoutPage/FormModel/formInitialValues.js create mode 100644 frontend/src/components/CheckoutPage/FormModel/validationSchema.js create mode 100644 frontend/src/components/CheckoutPage/Forms/AddressForm.js create mode 100644 frontend/src/components/CheckoutPage/Forms/PaymentForm.js create mode 100644 frontend/src/components/CheckoutPage/ReviewOrder/PaymentDetails.js create mode 100644 frontend/src/components/CheckoutPage/ReviewOrder/ProductDetails.js create mode 100644 frontend/src/components/CheckoutPage/ReviewOrder/ReviewOrder.js create mode 100644 frontend/src/components/CheckoutPage/ReviewOrder/ShippingDetails.js create mode 100644 frontend/src/components/CheckoutPage/ReviewOrder/index.js create mode 100644 frontend/src/components/CheckoutPage/ReviewOrder/styles.js create mode 100644 frontend/src/components/CheckoutPage/index.js create mode 100644 frontend/src/components/CheckoutPage/styles.js create mode 100644 frontend/src/components/ColorPicker/index.js create mode 100644 frontend/src/components/CompaniesManager/index.js create mode 100644 frontend/src/components/ConfirmationModal/index.js create mode 100644 frontend/src/components/ContactDrawer/index.js create mode 100644 frontend/src/components/ContactDrawerSkeleton/index.js create mode 100644 frontend/src/components/ContactForm/index.js create mode 100644 frontend/src/components/ContactListDialog/index.js create mode 100644 frontend/src/components/ContactListItemModal/index.js create mode 100644 frontend/src/components/ContactListTable/index.js create mode 100644 frontend/src/components/ContactModal/index.js create mode 100644 frontend/src/components/ContactNotes/index.js create mode 100644 frontend/src/components/ContactNotesDialog/index.js create mode 100644 frontend/src/components/ContactNotesDialogListItem/index.js create mode 100644 frontend/src/components/ContactTag/index.js create mode 100644 frontend/src/components/CurrencyInput/index.js create mode 100644 frontend/src/components/DarkMode/index.js create mode 100644 frontend/src/components/Dashboard/CardCounter.js create mode 100644 frontend/src/components/Dashboard/TableAttendantsStatus.js create mode 100644 frontend/src/components/Dialog/index.js create mode 100644 frontend/src/components/FileModal/index.js create mode 100644 frontend/src/components/FormFields/CheckboxField.js create mode 100644 frontend/src/components/FormFields/DatePickerField.js create mode 100644 frontend/src/components/FormFields/InputField.js create mode 100644 frontend/src/components/FormFields/SelectField.js create mode 100644 frontend/src/components/FormFields/index.js create mode 100644 frontend/src/components/HelpsManager/index.js create mode 100644 frontend/src/components/LocationPreview/index.js create mode 100644 frontend/src/components/MainContainer/index.js create mode 100644 frontend/src/components/MainHeader/index.js create mode 100644 frontend/src/components/MainHeaderButtonsWrapper/index.js create mode 100644 frontend/src/components/MarkdownWrapper/index.js create mode 100644 frontend/src/components/MessageInput/RecordingTimer.js create mode 100644 frontend/src/components/MessageInput/index.js create mode 100644 frontend/src/components/MessageInputCustom/RecordingTimer.js create mode 100644 frontend/src/components/MessageInputCustom/index.js create mode 100644 frontend/src/components/MessageOptionsMenu/index.js create mode 100644 frontend/src/components/MessageVariablesPicker/index.js create mode 100644 frontend/src/components/MessagesList/index.js create mode 100644 frontend/src/components/ModalImageCors/index.js create mode 100644 frontend/src/components/ModalUsers/index.js create mode 100644 frontend/src/components/NewTicketModal/index.js create mode 100644 frontend/src/components/NotificationsPopOver/index.js create mode 100644 frontend/src/components/NotificationsPopOver/index_Antigo.js create mode 100644 frontend/src/components/NotificationsVolume/index.js create mode 100644 frontend/src/components/OnlyForSuperUser/index.js create mode 100644 frontend/src/components/OutlinedDiv/index.js create mode 100644 frontend/src/components/PlansManager/index.js create mode 100644 frontend/src/components/PromptModal/index.js create mode 100644 frontend/src/components/QrcodeModal/index.js create mode 100644 frontend/src/components/QueueIntegrationModal/index.js create mode 100644 frontend/src/components/QueueModal/index.js create mode 100644 frontend/src/components/QueueOptions/index.js create mode 100644 frontend/src/components/QueueSelect/index copy.js create mode 100644 frontend/src/components/QueueSelect/index.js create mode 100644 frontend/src/components/QueueSelect/index_erro.js create mode 100644 frontend/src/components/QueueSelectCustom/index.js create mode 100644 frontend/src/components/QueueSelectSingle/index.js create mode 100644 frontend/src/components/QuickMessageDialog/index.js create mode 100644 frontend/src/components/QuickMessagesTable/index.js create mode 100644 frontend/src/components/ScheduleModal/index.js create mode 100644 frontend/src/components/SchedulesForm/index.js create mode 100644 frontend/src/components/Settings/Options.js create mode 100644 frontend/src/components/SubscriptionModal/index.js create mode 100644 frontend/src/components/SubscriptionStepper/index.js create mode 100644 frontend/src/components/TabPanel/index.js create mode 100644 frontend/src/components/TableRowSkeleton/index.js create mode 100644 frontend/src/components/TagModal/index.js create mode 100644 frontend/src/components/TagModal/index.js_Backup create mode 100644 frontend/src/components/TagsContainer/index.js create mode 100644 frontend/src/components/TagsFilter/index.js create mode 100644 frontend/src/components/Ticket/index.js create mode 100644 frontend/src/components/TicketActionButtons/index.js create mode 100644 frontend/src/components/TicketActionButtonsCustom/index.js create mode 100644 frontend/src/components/TicketAdvancedLayout/index.js create mode 100644 frontend/src/components/TicketHeader/index.js create mode 100644 frontend/src/components/TicketHeaderSkeleton/index.js create mode 100644 frontend/src/components/TicketInfo/index.js create mode 100644 frontend/src/components/TicketListItem/index.js create mode 100644 frontend/src/components/TicketListItemCustom/index.js create mode 100644 frontend/src/components/TicketMessagesDialog/index.js create mode 100644 frontend/src/components/TicketOptionsMenu/index.js create mode 100644 frontend/src/components/TicketsList/index.js create mode 100644 frontend/src/components/TicketsListCustom/index.js create mode 100644 frontend/src/components/TicketsListSkeleton/index.js create mode 100644 frontend/src/components/TicketsManager/index.js create mode 100644 frontend/src/components/TicketsManagerTabs/index.js create mode 100644 frontend/src/components/TicketsQueueSelect/index.js create mode 100644 frontend/src/components/Title/index.js create mode 100644 frontend/src/components/TransferTicketModal/index.js create mode 100644 frontend/src/components/TransferTicketModalCustom/index.js create mode 100644 frontend/src/components/UserLanguageSelector/index.js create mode 100644 frontend/src/components/UserModal/index.js create mode 100644 frontend/src/components/UsersFilter/index.js create mode 100644 frontend/src/components/WhatsAppModal/index.js create mode 100644 frontend/src/context/Auth/AuthContext.js create mode 100644 frontend/src/context/ReplyingMessage/ReplyingMessageContext.js create mode 100644 frontend/src/context/Socket/SocketContext.js create mode 100644 frontend/src/context/Tickets/TicketsContext.js create mode 100644 frontend/src/context/WhatsApp/WhatsAppsContext.js create mode 100644 frontend/src/errors/toastError.js create mode 100644 frontend/src/helpers/contrastColor.js create mode 100644 frontend/src/hooks/useAuth.js/index.js create mode 100644 frontend/src/hooks/useCompanies/index.js create mode 100644 frontend/src/hooks/useContactListItems/index.js create mode 100644 frontend/src/hooks/useContactLists/index.js create mode 100644 frontend/src/hooks/useContacts/index.js create mode 100644 frontend/src/hooks/useDashboard/index.js create mode 100644 frontend/src/hooks/useDate/index.js create mode 100644 frontend/src/hooks/useHelps/index.js create mode 100644 frontend/src/hooks/useInvoices/index.js create mode 100644 frontend/src/hooks/useLocalStorage/index.js create mode 100644 frontend/src/hooks/useMessages/index.js create mode 100644 frontend/src/hooks/usePlans/index.js create mode 100644 frontend/src/hooks/useQueues/index.js create mode 100644 frontend/src/hooks/useQuickMessages/index.js create mode 100644 frontend/src/hooks/useQuickMessages_OLD/index.js create mode 100644 frontend/src/hooks/useSettings/index.js create mode 100644 frontend/src/hooks/useTicketNotes/index.js create mode 100644 frontend/src/hooks/useTickets/index.js create mode 100644 frontend/src/hooks/useUsers/index.js create mode 100644 frontend/src/hooks/useVersion/index.js create mode 100644 frontend/src/hooks/useWhatsApps/index.js create mode 100644 frontend/src/index.js create mode 100644 frontend/src/layout/MainListItems.js create mode 100644 frontend/src/layout/index.js create mode 100644 frontend/src/layout/themeContext.js create mode 100644 frontend/src/pages/.DS_Store create mode 100644 frontend/src/pages/Annoucements/index.js create mode 100644 frontend/src/pages/CampaignReport/index.js create mode 100644 frontend/src/pages/Campaigns/index.js create mode 100644 frontend/src/pages/CampaignsConfig/index.js create mode 100644 frontend/src/pages/Chat/ChatList.js create mode 100644 frontend/src/pages/Chat/ChatMessages.js create mode 100644 frontend/src/pages/Chat/ChatPopover.js create mode 100644 frontend/src/pages/Chat/index.js create mode 100644 frontend/src/pages/Companies/index.js create mode 100644 frontend/src/pages/Connections/index.js create mode 100644 frontend/src/pages/ContactListItems/index.js create mode 100644 frontend/src/pages/ContactLists/index.js create mode 100644 frontend/src/pages/Contacts/index.js create mode 100644 frontend/src/pages/Dashboard/Chart.js create mode 100644 frontend/src/pages/Dashboard/ChartsDate.js create mode 100644 frontend/src/pages/Dashboard/ChartsUser.js create mode 100644 frontend/src/pages/Dashboard/Filters.js create mode 100644 frontend/src/pages/Dashboard/Title.js create mode 100644 frontend/src/pages/Dashboard/button.css create mode 100644 frontend/src/pages/Dashboard/index.js create mode 100644 frontend/src/pages/Dashboard/index_old.js create mode 100644 frontend/src/pages/Files/index.js create mode 100644 frontend/src/pages/Financeiro/index.js create mode 100644 frontend/src/pages/ForgetPassWord/index.js create mode 100644 frontend/src/pages/Helps/index.js create mode 100644 frontend/src/pages/Kanban/index.js create mode 100644 frontend/src/pages/Kanban/responsive.css create mode 100644 frontend/src/pages/Login/index.js create mode 100644 frontend/src/pages/Login/style.css create mode 100644 frontend/src/pages/MessagesAPI/index.js create mode 100644 frontend/src/pages/Prompts/index.js create mode 100644 frontend/src/pages/QueueIntegration/index.js create mode 100644 frontend/src/pages/Queues/index.js create mode 100644 frontend/src/pages/QuickMessages/index.js create mode 100644 frontend/src/pages/Schedules.bkp create mode 100644 frontend/src/pages/Schedules/Schedules.css create mode 100644 frontend/src/pages/Schedules/index.js create mode 100644 frontend/src/pages/Settings/index.js create mode 100644 frontend/src/pages/SettingsCustom/index.js create mode 100644 frontend/src/pages/Signup/index.js create mode 100644 frontend/src/pages/Signup/style.css create mode 100644 frontend/src/pages/Subscription/index.js create mode 100644 frontend/src/pages/Tags/index.js create mode 100644 frontend/src/pages/TicketResponsiveContainer/index.js create mode 100644 frontend/src/pages/Tickets/index.js create mode 100644 frontend/src/pages/TicketsAdvanced/index.js create mode 100644 frontend/src/pages/TicketsCustom/index.js create mode 100644 frontend/src/pages/ToDoList/index.js create mode 100644 frontend/src/pages/Users/index.js create mode 100644 frontend/src/routes/Route.js create mode 100644 frontend/src/routes/index.js create mode 100644 frontend/src/rules.js create mode 100644 frontend/src/services/api.js create mode 100644 frontend/src/services/socket.js create mode 100644 frontend/src/translate/i18n.js create mode 100644 frontend/src/translate/languages/en.js create mode 100644 frontend/src/translate/languages/es.js create mode 100644 frontend/src/translate/languages/index.js create mode 100644 frontend/src/translate/languages/pt.js diff --git a/README.md b/README.md new file mode 100644 index 0000000..0166584 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +Todos os direitos reservados a https://atendechat.com diff --git a/backend/.editorconfig b/backend/.editorconfig new file mode 100644 index 0000000..11695db --- /dev/null +++ b/backend/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +end_of_line = lf +indent_style = space +indent_size = 2 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/backend/.env.example b/backend/.env.example new file mode 100644 index 0000000..035daca --- /dev/null +++ b/backend/.env.example @@ -0,0 +1,36 @@ +NODE_ENV= +BACKEND_URL=http://localhost +FRONTEND_URL=http://localhost:3000 +PROXY_PORT=8080 +PORT=8080 + +DB_DIALECT=postgres +DB_HOST=localhost +DB_PORT=5432 +DB_USER=user +DB_PASS=senha +DB_NAME=db_name + +JWT_SECRET=kZaOTd+YZpjRUyyuQUpigJaEMk4vcW4YOymKPZX0Ts8= +JWT_REFRESH_SECRET=dBSXqFg9TaNUEDXVp6fhMTRLBysP+j2DSqf7+raxD3A= + +REDIS_URI=redis://:123456@127.0.0.1:6379 +REDIS_OPT_LIMITER_MAX=1 +REDIS_OPT_LIMITER_DURATION=3000 + +USER_LIMIT=10000 +CONNECTIONS_LIMIT=100000 +CLOSED_SEND_BY_ME=true + +GERENCIANET_SANDBOX=false +GERENCIANET_CLIENT_ID=Client_Id_Gerencianet +GERENCIANET_CLIENT_SECRET=Client_Secret_Gerencianet +GERENCIANET_PIX_CERT=certificado-Gerencianet +GERENCIANET_PIX_KEY=chave pix gerencianet + +# EMAIL + MAIL_HOST="smtp.gmail.com" + MAIL_USER="seu@gmail.com" + MAIL_PASS="SuaSenha" + MAIL_FROM="seu@gmail.com" + MAIL_PORT="465" diff --git a/backend/.eslintignore b/backend/.eslintignore new file mode 100644 index 0000000..77b9a34 --- /dev/null +++ b/backend/.eslintignore @@ -0,0 +1,3 @@ +/*.js +node_modules +dist diff --git a/backend/.eslintrc.json b/backend/.eslintrc.json new file mode 100644 index 0000000..aa015fa --- /dev/null +++ b/backend/.eslintrc.json @@ -0,0 +1,49 @@ +{ + "env": { + "es2021": true, + "node": true, + "jest": true + }, + "extends": [ + "airbnb-base", + "plugin:@typescript-eslint/recommended", + "prettier/@typescript-eslint", + "plugin:prettier/recommended" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 12, + "sourceType": "module" + }, + "plugins": ["@typescript-eslint", "prettier"], + "rules": { + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-unused-vars": [ + "error", + { "argsIgnorePattern": "_" } + ], + "import/prefer-default-export": "off", + "no-console": "off", + "no-param-reassign": "off", + "prettier/prettier": "error", + "import/extensions": [ + "error", + "ignorePackages", + { + "ts": "never" + } + ], + "quotes": [ + 1, + "double", + { + "avoidEscape": true + } + ] + }, + "settings": { + "import/resolver": { + "typescript": {} + } + } +} diff --git a/backend/.gitignore b/backend/.gitignore new file mode 100644 index 0000000..1c092bc --- /dev/null +++ b/backend/.gitignore @@ -0,0 +1,16 @@ +node_modules +public/* +dist +!public/.gitkeep +.env +.env.test + +package-lock.json +yarn.lock +yarn-error.log + +/src/config/sentry.js + +# Ignore test-related files +/coverage.data +/coverage/ diff --git a/backend/.sequelizerc b/backend/.sequelizerc new file mode 100644 index 0000000..264f851 --- /dev/null +++ b/backend/.sequelizerc @@ -0,0 +1,8 @@ +const { resolve } = require("path"); + +module.exports = { + "config": resolve(__dirname, "dist", "config", "database.js"), + "modules-path": resolve(__dirname, "dist", "models"), + "migrations-path": resolve(__dirname, "dist", "database", "migrations"), + "seeders-path": resolve(__dirname, "dist", "database", "seeds") +}; diff --git a/backend/certs/coloque_seus_certificado_aqui b/backend/certs/coloque_seus_certificado_aqui new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/backend/certs/coloque_seus_certificado_aqui @@ -0,0 +1 @@ + diff --git a/backend/jest.config.js b/backend/jest.config.js new file mode 100644 index 0000000..76c1b57 --- /dev/null +++ b/backend/jest.config.js @@ -0,0 +1,186 @@ +/* + * For a detailed explanation regarding each configuration property, visit: + * https://jestjs.io/docs/en/configuration.html + */ + +module.exports = { + // All imported modules in your tests should be mocked automatically + // automock: false, + + // Stop running tests after `n` failures + bail: 1, + + // The directory where Jest should store its cached dependency information + // cacheDirectory: "/tmp/jest_rs", + + // Automatically clear mock calls and instances between every test + clearMocks: true, + + // Indicates whether the coverage information should be collected while executing the test + collectCoverage: true, + + // An array of glob patterns indicating a set of files for which coverage information should be collected + collectCoverageFrom: ["/src/services/**/*.ts"], + + // The directory where Jest should output its coverage files + coverageDirectory: "coverage", + + // An array of regexp pattern strings used to skip coverage collection + // coveragePathIgnorePatterns: [ + // "/node_modules/" + // ], + + // Indicates which provider should be used to instrument code for coverage + coverageProvider: "v8", + + // A list of reporter names that Jest uses when writing coverage reports + coverageReporters: ["text", "lcov"], + + // An object that configures minimum threshold enforcement for coverage results + // coverageThreshold: undefined, + + // A path to a custom dependency extractor + // dependencyExtractor: undefined, + + // Make calling deprecated APIs throw helpful error messages + // errorOnDeprecated: false, + + // Force coverage collection from ignored files using an array of glob patterns + // forceCoverageMatch: [], + + // A path to a module which exports an async function that is triggered once before all test suites + // globalSetup: undefined, + + // A path to a module which exports an async function that is triggered once after all test suites + // globalTeardown: undefined, + + // A set of global variables that need to be available in all test environments + // globals: {}, + + // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. + // maxWorkers: "50%", + + // An array of directory names to be searched recursively up from the requiring module's location + // moduleDirectories: [ + // "node_modules" + // ], + + // An array of file extensions your modules use + // moduleFileExtensions: [ + // "js", + // "json", + // "jsx", + // "ts", + // "tsx", + // "node" + // ], + + // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module + // moduleNameMapper: {}, + + // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader + // modulePathIgnorePatterns: [], + + // Activates notifications for test results + // notify: false, + + // An enum that specifies notification mode. Requires { notify: true } + // notifyMode: "failure-change", + + // A preset that is used as a base for Jest's configuration + preset: "ts-jest", + + // Run tests from one or more projects + // projects: undefined, + + // Use this configuration option to add custom reporters to Jest + // reporters: undefined, + + // Automatically reset mock state between every test + // resetMocks: false, + + // Reset the module registry before running each individual test + // resetModules: false, + + // A path to a custom resolver + // resolver: undefined, + + // Automatically restore mock state between every test + // restoreMocks: false, + + // The root directory that Jest should scan for tests and modules within + // rootDir: undefined, + + // A list of paths to directories that Jest should use to search for files in + // roots: [ + // "" + // ], + + // Allows you to use a custom runner instead of Jest's default test runner + // runner: "jest-runner", + + // The paths to modules that run some code to configure or set up the testing environment before each test + // setupFiles: [], + + // A list of paths to modules that run some code to configure or set up the testing framework before each test + // setupFilesAfterEnv: [], + + // The number of seconds after which a test is considered as slow and reported as such in the results. + // slowTestThreshold: 5, + + // A list of paths to snapshot serializer modules Jest should use for snapshot testing + // snapshotSerializers: [], + + // The test environment that will be used for testing + testEnvironment: "node", + + // Options that will be passed to the testEnvironment + // testEnvironmentOptions: {}, + + // Adds a location field to test results + // testLocationInResults: false, + + // The glob patterns Jest uses to detect test files + testMatch: ["**/__tests__/**/*.spec.ts"] + + // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped + // testPathIgnorePatterns: [ + // "/node_modules/" + // ], + + // The regexp pattern or array of patterns that Jest uses to detect test files + // testRegex: [], + + // This option allows the use of a custom results processor + // testResultsProcessor: undefined, + + // This option allows use of a custom test runner + // testRunner: "jasmine2", + + // This option sets the URL for the jsdom environment. It is reflected in properties such as location.href + // testURL: "http://localhost", + + // Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout" + // timers: "real", + + // A map from regular expressions to paths to transformers + // transform: undefined, + + // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation + // transformIgnorePatterns: [ + // "/node_modules/", + // "\\.pnp\\.[^\\/]+$" + // ], + + // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them + // unmockedModulePathPatterns: undefined, + + // Indicates whether each individual test should be reported during the run + // verbose: undefined, + + // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode + // watchPathIgnorePatterns: [], + + // Whether to use watchman for file crawling + // watchman: true, +}; diff --git a/backend/package.json b/backend/package.json new file mode 100644 index 0000000..cd4d620 --- /dev/null +++ b/backend/package.json @@ -0,0 +1,99 @@ +{ + "name": "backend", + "version": "6.0.0", + "description": "", + "main": "index.js", + "scripts": { + "build": "tsc", + "watch": "tsc -w", + "start": "nodemon dist/server.js", + "dev:server": "ts-node-dev --respawn --transpile-only --ignore node_modules src/server.ts", + "db:migrate": "npx sequelize db:migrate", + "db:seed": "sequelize db:seed:all", + "pretest": "NODE_ENV=test sequelize db:migrate && NODE_ENV=test sequelize db:seed:all", + "test": "NODE_ENV=test jest", + "posttest": "NODE_ENV=test sequelize db:migrate:undo:all", + "lint": "eslint src/**/*.ts" + }, + "author": "", + "license": "MIT", + "dependencies": { + "@adiwajshing/keyed-db": "^0.2.4", + "@ffmpeg-installer/ffmpeg": "^1.1.0", + "@hapi/boom": "^9.1.4", + "@sentry/node": "^6.18.1", + "@types/fs-extra": "^11.0.4", + "@whiskeysockets/baileys": "github:WhiskeySockets/Baileys", + "bcryptjs": "^2.4.3", + "bull": "^4.8.2", + "cookie-parser": "^1.4.6", + "cors": "^2.8.5", + "cron": "^2.1.0", + "body-parser":"^1.20.2", + "date-fns": "^2.28.0", + "dotenv": "^16.0.0", + "express": "^4.17.3", + "express-async-errors": "^3.1.1", + "fluent-ffmpeg": "^2.1.2", + "gn-api-sdk-typescript": "^1.0.7", + "http-graceful-shutdown": "^3.1.6", + "jsonwebtoken": "^8.5.1", + "microsoft-cognitiveservices-speech-sdk": "1.31.0", + "multer": "^1.4.4", + "mustache": "^4.2.0", + "mysql2": "^2.2.5", + "node-cache": "^5.1.2", + "node-cron": "^3.0.2", + "nodemailer": "^6.8.0", + "openai": "3.3.0", + "pg": "^8.7.3", + "pino": "^7.8.0", + "pino-pretty": "^10.0.0", + "puppeteer": "^19.4.0", + "qrcode-terminal": "^0.12.0", + "reflect-metadata": "^0.1.13", + "request": "2.88.2", + "sequelize": "^5.22.3", + "sequelize-cli": "^5.5.1", + "sequelize-typescript": "^1.1.0", + "socket.io": "^4.7.4", + "uuid": "^8.3.2", + "xlsx": "^0.18.3", + "yup": "^0.32.11" + }, + "devDependencies": { + "@types/bcryptjs": "^2.4.2", + "@types/bluebird": "^3.5.36", + "@types/chance": "^1.1.3", + "@types/cookie-parser": "^1.4.2", + "@types/cors": "^2.8.12", + "@types/express": "^4.17.13", + "@types/factory-girl": "^5.0.8", + "@types/jest": "^27.4.1", + "@types/jsonwebtoken": "^8.5.8", + "@types/multer": "^1.4.7", + "@types/mustache": "^4.1.2", + "@types/node": "^17.0.21", + "@types/supertest": "^2.0.11", + "@types/uuid": "^8.3.4", + "@types/validator": "^13.7.1", + "@types/yup": "^0.29.13", + "@typescript-eslint/eslint-plugin": "^5.13.0", + "@typescript-eslint/parser": "^5.13.0", + "chance": "^1.1.8", + "eslint": "^8.10.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-prettier": "^8.5.0", + "eslint-import-resolver-typescript": "^2.5.0", + "eslint-plugin-import": "^2.25.4", + "eslint-plugin-prettier": "^4.0.0", + "factory-girl": "^5.0.4", + "jest": "^27.5.1", + "nodemon": "^2.0.15", + "prettier": "^2.5.1", + "supertest": "^6.2.2", + "ts-jest": "^27.1.3", + "ts-node-dev": "^1.1.8", + "typescript": "^4.6.3" + } +} diff --git a/backend/prettier.config.js b/backend/prettier.config.js new file mode 100644 index 0000000..2821955 --- /dev/null +++ b/backend/prettier.config.js @@ -0,0 +1,5 @@ +module.exports = { + singleQuote: false, + trailingComma: "none", + arrowParens: "avoid" +}; diff --git a/backend/src/@types/express.d.ts b/backend/src/@types/express.d.ts new file mode 100644 index 0000000..113a3e7 --- /dev/null +++ b/backend/src/@types/express.d.ts @@ -0,0 +1,5 @@ +declare namespace Express { + export interface Request { + user: { id: string; profile: string; companyId: number }; + } +} diff --git a/backend/src/@types/qrcode-terminal.d.ts b/backend/src/@types/qrcode-terminal.d.ts new file mode 100644 index 0000000..3b59fed --- /dev/null +++ b/backend/src/@types/qrcode-terminal.d.ts @@ -0,0 +1 @@ +declare module "qrcode-terminal"; diff --git a/backend/src/app.ts b/backend/src/app.ts new file mode 100644 index 0000000..1eed665 --- /dev/null +++ b/backend/src/app.ts @@ -0,0 +1,53 @@ +import "./bootstrap"; +import "reflect-metadata"; +import "express-async-errors"; +import express, { Request, Response, NextFunction } from "express"; +import cors from "cors"; +import cookieParser from "cookie-parser"; +import * as Sentry from "@sentry/node"; + +import "./database"; +import uploadConfig from "./config/upload"; +import AppError from "./errors/AppError"; +import routes from "./routes"; +import { logger } from "./utils/logger"; +import { messageQueue, sendScheduledMessages } from "./queues"; +import bodyParser from 'body-parser'; + +Sentry.init({ dsn: process.env.SENTRY_DSN }); + +const app = express(); + +app.set("queues", { + messageQueue, + sendScheduledMessages +}); + +const bodyparser = require('body-parser'); +app.use(bodyParser.json({ limit: '10mb' })); + +app.use( + cors({ + credentials: true, + origin: process.env.FRONTEND_URL + }) +); +app.use(cookieParser()); +app.use(express.json()); +app.use(Sentry.Handlers.requestHandler()); +app.use("/public", express.static(uploadConfig.directory)); +app.use(routes); + +app.use(Sentry.Handlers.errorHandler()); + +app.use(async (err: Error, req: Request, res: Response, _: NextFunction) => { + if (err instanceof AppError) { + logger.warn(err); + return res.status(err.statusCode).json({ error: err.message }); + } + + logger.error(err); + return res.status(500).json({ error: "Internal server error" }); +}); + +export default app; diff --git a/backend/src/bootstrap.ts b/backend/src/bootstrap.ts new file mode 100644 index 0000000..03fffb5 --- /dev/null +++ b/backend/src/bootstrap.ts @@ -0,0 +1,5 @@ +import dotenv from "dotenv"; + +dotenv.config({ + path: process.env.NODE_ENV === "test" ? ".env.test" : ".env" +}); diff --git a/backend/src/config/Gn.ts b/backend/src/config/Gn.ts new file mode 100644 index 0000000..d4cbb91 --- /dev/null +++ b/backend/src/config/Gn.ts @@ -0,0 +1,13 @@ +import path from "path"; + +const cert = path.join( + __dirname, + `../../certs/${process.env.GERENCIANET_PIX_CERT}.p12` +); + +export = { + sandbox: false, + client_id: process.env.GERENCIANET_CLIENT_ID as string, + client_secret: process.env.GERENCIANET_CLIENT_SECRET as string, + pix_cert: cert +}; diff --git a/backend/src/config/auth.ts b/backend/src/config/auth.ts new file mode 100644 index 0000000..6f8c5fd --- /dev/null +++ b/backend/src/config/auth.ts @@ -0,0 +1,6 @@ +export default { + secret: process.env.JWT_SECRET || "mysecret", + expiresIn: "15m", + refreshSecret: process.env.JWT_REFRESH_SECRET || "myanothersecret", + refreshExpiresIn: "7d" +}; diff --git a/backend/src/config/database.ts b/backend/src/config/database.ts new file mode 100644 index 0000000..d5e452b --- /dev/null +++ b/backend/src/config/database.ts @@ -0,0 +1,16 @@ +import "../bootstrap"; + +module.exports = { + define: { + charset: "utf8mb4", + collate: "utf8mb4_bin" + }, + dialect: process.env.DB_DIALECT || "mysql", + timezone: "-03:00", + host: process.env.DB_HOST, + port: process.env.DB_PORT || 3306, + database: process.env.DB_NAME, + username: process.env.DB_USER, + password: process.env.DB_PASS, + logging: process.env.DB_DEBUG === "true" +}; diff --git a/backend/src/config/redis.ts b/backend/src/config/redis.ts new file mode 100644 index 0000000..43118e2 --- /dev/null +++ b/backend/src/config/redis.ts @@ -0,0 +1,3 @@ +export const REDIS_URI_CONNECTION = process.env.REDIS_URI || ""; +export const REDIS_OPT_LIMITER_MAX = process.env.REDIS_OPT_LIMITER_MAX || 1; +export const REDIS_OPT_LIMITER_DURATION = process.env.REDIS_OPT_LIMITER_DURATION || 3000; diff --git a/backend/src/config/upload.ts b/backend/src/config/upload.ts new file mode 100644 index 0000000..5a06e12 --- /dev/null +++ b/backend/src/config/upload.ts @@ -0,0 +1,39 @@ +import path from "path"; +import multer from "multer"; +import fs from "fs"; + +const publicFolder = path.resolve(__dirname, "..", "..", "public"); + +export default { + directory: publicFolder, + storage: multer.diskStorage({ + destination: async function (req, file, cb) { + + const { typeArch, fileId } = req.body; + + let folder; + + if (typeArch && typeArch !== "announcements") { + folder = path.resolve(publicFolder , typeArch, fileId ? fileId : "") + } else if (typeArch && typeArch === "announcements") { + folder = path.resolve(publicFolder , typeArch) + } + else + { + folder = path.resolve(publicFolder) + } + + if (!fs.existsSync(folder)) { + fs.mkdirSync(folder, { recursive: true }) + fs.chmodSync(folder, 0o777) + } + return cb(null, folder); + }, + filename(req, file, cb) { + const { typeArch } = req.body; + + const fileName = typeArch && typeArch !== "announcements" ? file.originalname.replace('/','-').replace(/ /g, "_") : new Date().getTime() + '_' + file.originalname.replace('/','-').replace(/ /g, "_"); + return cb(null, fileName); + } + }) +}; diff --git a/backend/src/controllers/AnnouncementController.ts b/backend/src/controllers/AnnouncementController.ts new file mode 100644 index 0000000..3d3a3a4 --- /dev/null +++ b/backend/src/controllers/AnnouncementController.ts @@ -0,0 +1,205 @@ +import * as Yup from "yup"; +import { Request, Response } from "express"; +import { getIO } from "../libs/socket"; +import { head } from "lodash"; +import fs from "fs"; +import path from "path"; + +import ListService from "../services/AnnouncementService/ListService"; +import CreateService from "../services/AnnouncementService/CreateService"; +import ShowService from "../services/AnnouncementService/ShowService"; +import UpdateService from "../services/AnnouncementService/UpdateService"; +import DeleteService from "../services/AnnouncementService/DeleteService"; +import FindService from "../services/AnnouncementService/FindService"; + +import Announcement from "../models/Announcement"; + +import AppError from "../errors/AppError"; + +type IndexQuery = { + searchParam: string; + pageNumber: string; + companyId: string | number; +}; + +type StoreData = { + priority: string; + title: string; + text: string; + status: string; + companyId: number; + mediaPath?: string; + mediaName?: string; +}; + +type FindParams = { + companyId: string; +}; + +export const index = async (req: Request, res: Response): Promise => { + const { searchParam, pageNumber } = req.query as IndexQuery; + + const { records, count, hasMore } = await ListService({ + searchParam, + pageNumber + }); + + return res.json({ records, count, hasMore }); +}; + +export const store = async (req: Request, res: Response): Promise => { + const { companyId } = req.user; + const data = req.body as StoreData; + + const schema = Yup.object().shape({ + title: Yup.string().required() + }); + + try { + await schema.validate(data); + } catch (err: any) { + throw new AppError(err.message); + } + + const record = await CreateService({ + ...data, + companyId + }); + + const io = getIO(); + io.emit(`company-announcement`, { + action: "create", + record + }); + + return res.status(200).json(record); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { id } = req.params; + + const record = await ShowService(id); + + return res.status(200).json(record); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + const data = req.body as StoreData; + + const schema = Yup.object().shape({ + title: Yup.string().required() + }); + + try { + await schema.validate(data); + } catch (err: any) { + throw new AppError(err.message); + } + + const { id } = req.params; + + const record = await UpdateService({ + ...data, + id + }); + + const io = getIO(); + io.emit(`company-announcement`, { + action: "update", + record + }); + + return res.status(200).json(record); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { id } = req.params; + const { companyId } = req.user; + + await DeleteService(id); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-announcement`, { + action: "delete", + id + }); + + return res.status(200).json({ message: "Announcement deleted" }); +}; + +export const findList = async ( + req: Request, + res: Response +): Promise => { + const params = req.query as FindParams; + const records: Announcement[] = await FindService(params); + + return res.status(200).json(records); +}; + +export const mediaUpload = async ( + req: Request, + res: Response +): Promise => { + const { id } = req.params; + const files = req.files as Express.Multer.File[]; + const file = head(files); + + try { + const announcement = await Announcement.findByPk(id); + + await announcement.update({ + mediaPath: file.filename, + mediaName: file.originalname + }); + await announcement.reload(); + + const io = getIO(); + io.emit(`company-announcement`, { + action: "update", + record: announcement + }); + + return res.send({ mensagem: "Mensagem enviada" }); + } catch (err: any) { + throw new AppError(err.message); + } +}; + +export const deleteMedia = async ( + req: Request, + res: Response +): Promise => { + const { id } = req.params; + + try { + const announcement = await Announcement.findByPk(id); + const filePath = path.resolve("public", announcement.mediaPath); + const fileExists = fs.existsSync(filePath); + if (fileExists) { + fs.unlinkSync(filePath); + } + + await announcement.update({ + mediaPath: null, + mediaName: null + }); + await announcement.reload(); + + const io = getIO(); + io.emit(`company-announcement`, { + action: "update", + record: announcement + }); + + return res.send({ mensagem: "Arquivo excluído" }); + } catch (err: any) { + throw new AppError(err.message); + } +}; diff --git a/backend/src/controllers/CampaignController.ts b/backend/src/controllers/CampaignController.ts new file mode 100644 index 0000000..30e83d9 --- /dev/null +++ b/backend/src/controllers/CampaignController.ts @@ -0,0 +1,287 @@ +import * as Yup from "yup"; +import { Request, Response } from "express"; +import { getIO } from "../libs/socket"; +import { head } from "lodash"; +import fs from "fs"; +import path from "path"; + +import ListService from "../services/CampaignService/ListService"; +import CreateService from "../services/CampaignService/CreateService"; +import ShowService from "../services/CampaignService/ShowService"; +import UpdateService from "../services/CampaignService/UpdateService"; +import DeleteService from "../services/CampaignService/DeleteService"; +import FindService from "../services/CampaignService/FindService"; + +import Campaign from "../models/Campaign"; + +import AppError from "../errors/AppError"; +import { CancelService } from "../services/CampaignService/CancelService"; +import { RestartService } from "../services/CampaignService/RestartService"; +import TicketTag from "../models/TicketTag"; +import Ticket from "../models/Ticket"; +import Contact from "../models/Contact"; +import ContactList from "../models/ContactList"; +import ContactListItem from "../models/ContactListItem"; + +type IndexQuery = { + searchParam: string; + pageNumber: string; + companyId: string | number; +}; + +type StoreData = { + name: string; + status: string; + confirmation: boolean; + scheduledAt: string; + companyId: number; + contactListId: number; + tagListId: number | string; + fileListId: number; +}; + +type FindParams = { + companyId: string; +}; + +export const index = async (req: Request, res: Response): Promise => { + const { searchParam, pageNumber } = req.query as IndexQuery; + const { companyId } = req.user; + + const { records, count, hasMore } = await ListService({ + searchParam, + pageNumber, + companyId + }); + + return res.json({ records, count, hasMore }); +}; + +export const store = async (req: Request, res: Response): Promise => { + const { companyId } = req.user; + const data = req.body as StoreData; + + const schema = Yup.object().shape({ + name: Yup.string().required() + }); + + try { + await schema.validate(data); + } catch (err: any) { + throw new AppError(err.message); + } + + if (typeof data.tagListId === 'number') { + + const tagId = data.tagListId; + const campanhaNome = data.name; + + async function createContactListFromTag(tagId) { + + const currentDate = new Date(); + const formattedDate = currentDate.toISOString(); + + try { + const ticketTags = await TicketTag.findAll({ where: { tagId } }); + const ticketIds = ticketTags.map((ticketTag) => ticketTag.ticketId); + + const tickets = await Ticket.findAll({ where: { id: ticketIds } }); + const contactIds = tickets.map((ticket) => ticket.contactId); + + const contacts = await Contact.findAll({ where: { id: contactIds } }); + + const randomName = `${campanhaNome} | TAG: ${tagId} - ${formattedDate}` // Implement your own function to generate a random name + const contactList = await ContactList.create({ name: randomName, companyId: companyId }); + + const { id: contactListId } = contactList; + + const contactListItems = contacts.map((contact) => ({ + name: contact.name, + number: contact.number, + email: contact.email, + contactListId, + companyId, + isWhatsappValid: true, + + })); + + await ContactListItem.bulkCreate(contactListItems); + + // Return the ContactList ID + return contactListId; + } catch (error) { + console.error('Error creating contact list:', error); + throw error; + } + } + + + createContactListFromTag(tagId) + .then(async (contactListId) => { + const record = await CreateService({ + ...data, + companyId, + contactListId: contactListId, + }); + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-campaign`, { + action: "create", + record + }); + return res.status(200).json(record); + }) + .catch((error) => { + console.error('Error:', error); + return res.status(500).json({ error: 'Error creating contact list' }); + }); + + } else { // SAI DO CHECK DE TAG + + + const record = await CreateService({ + ...data, + companyId + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-campaign`, { + action: "create", + record + }); + + return res.status(200).json(record); + } +}; + +export const show = async (req: Request, res: Response): Promise => { + const { id } = req.params; + + const record = await ShowService(id); + + return res.status(200).json(record); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + const data = req.body as StoreData; + const { companyId } = req.user; + + const schema = Yup.object().shape({ + name: Yup.string().required() + }); + + try { + await schema.validate(data); + } catch (err: any) { + throw new AppError(err.message); + } + + const { id } = req.params; + + const record = await UpdateService({ + ...data, + id + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-campaign`, { + action: "update", + record + }); + + return res.status(200).json(record); +}; + +export const cancel = async ( + req: Request, + res: Response +): Promise => { + const { id } = req.params; + + await CancelService(+id); + + return res.status(204).json({ message: "Cancelamento realizado" }); +}; + +export const restart = async ( + req: Request, + res: Response +): Promise => { + const { id } = req.params; + + await RestartService(+id); + + return res.status(204).json({ message: "Reinício dos disparos" }); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { id } = req.params; + const { companyId } = req.user; + + await DeleteService(id); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-campaign`, { + action: "delete", + id + }); + + return res.status(200).json({ message: "Campaign deleted" }); +}; + +export const findList = async ( + req: Request, + res: Response +): Promise => { + const params = req.query as FindParams; + const records: Campaign[] = await FindService(params); + + return res.status(200).json(records); +}; + +export const mediaUpload = async ( + req: Request, + res: Response +): Promise => { + const { id } = req.params; + const files = req.files as Express.Multer.File[]; + const file = head(files); + + try { + const campaign = await Campaign.findByPk(id); + campaign.mediaPath = file.filename; + campaign.mediaName = file.originalname; + await campaign.save(); + return res.send({ mensagem: "Mensagem enviada" }); + } catch (err: any) { + throw new AppError(err.message); + } +}; + +export const deleteMedia = async ( + req: Request, + res: Response +): Promise => { + const { id } = req.params; + + try { + const campaign = await Campaign.findByPk(id); + const filePath = path.resolve("public", campaign.mediaPath); + const fileExists = fs.existsSync(filePath); + if (fileExists) { + fs.unlinkSync(filePath); + } + + campaign.mediaPath = null; + campaign.mediaName = null; + await campaign.save(); + return res.send({ mensagem: "Arquivo excluído" }); + } catch (err: any) { + throw new AppError(err.message); + } +}; diff --git a/backend/src/controllers/CampaignSettingController.ts b/backend/src/controllers/CampaignSettingController.ts new file mode 100644 index 0000000..860dfaf --- /dev/null +++ b/backend/src/controllers/CampaignSettingController.ts @@ -0,0 +1,34 @@ +import { Request, Response } from "express"; +import { getIO } from "../libs/socket"; + +import ListService from "../services/CampaignSettingServices/ListService"; +import CreateService from "../services/CampaignSettingServices/CreateService"; + +interface StoreData { + settings: any; +} + +export const index = async (req: Request, res: Response): Promise => { + const { companyId } = req.user; + + const records = await ListService({ + companyId + }); + + return res.json(records); +}; + +export const store = async (req: Request, res: Response): Promise => { + const { companyId } = req.user; + const data = req.body as StoreData; + + const record = await CreateService(data, companyId); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-campaignSettings`, { + action: "create", + record + }); + + return res.status(200).json(record); +}; diff --git a/backend/src/controllers/ChatController.ts b/backend/src/controllers/ChatController.ts new file mode 100644 index 0000000..6165181 --- /dev/null +++ b/backend/src/controllers/ChatController.ts @@ -0,0 +1,205 @@ +import * as Yup from "yup"; +import { Request, Response } from "express"; +import { getIO } from "../libs/socket"; + +import CreateService from "../services/ChatService/CreateService"; +import ListService from "../services/ChatService/ListService"; +import ShowFromUuidService from "../services/ChatService/ShowFromUuidService"; +import DeleteService from "../services/ChatService/DeleteService"; +import FindMessages from "../services/ChatService/FindMessages"; +import UpdateService from "../services/ChatService/UpdateService"; + +import Chat from "../models/Chat"; +import CreateMessageService from "../services/ChatService/CreateMessageService"; +import User from "../models/User"; +import ChatUser from "../models/ChatUser"; + +type IndexQuery = { + pageNumber: string; + companyId: string | number; + ownerId?: number; +}; + +type StoreData = { + users: any[]; + title: string; +}; + +type FindParams = { + companyId: number; + ownerId?: number; +}; + +export const index = async (req: Request, res: Response): Promise => { + const { pageNumber } = req.query as unknown as IndexQuery; + const ownerId = +req.user.id; + + const { records, count, hasMore } = await ListService({ + ownerId, + pageNumber + }); + + return res.json({ records, count, hasMore }); +}; + +export const store = async (req: Request, res: Response): Promise => { + const { companyId } = req.user; + const ownerId = +req.user.id; + const data = req.body as StoreData; + + const record = await CreateService({ + ...data, + ownerId, + companyId + }); + + const io = getIO(); + + record.users.forEach(user => { + io.to(`user-${user.userId}`).emit(`company-${companyId}-chat-user-${user.userId}`, { + action: "create", + record + }); + }); + + return res.status(200).json(record); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + const { companyId } = req.user; + const data = req.body; + const { id } = req.params; + + const record = await UpdateService({ + ...data, + id: +id + }); + + const io = getIO(); + + record.users.forEach(user => { + io.to(`user-${user.userId}`).emit(`company-${companyId}-chat-user-${user.userId}`, { + action: "update", + record + }); + }); + + return res.status(200).json(record); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { id } = req.params; + + const record = await ShowFromUuidService(id); + + return res.status(200).json(record); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { id } = req.params; + const { companyId } = req.user; + + await DeleteService(id); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-chat`, { + action: "delete", + id + }); + + return res.status(200).json({ message: "Chat deleted" }); +}; + +export const saveMessage = async ( + req: Request, + res: Response +): Promise => { + const { companyId } = req.user; + const { message } = req.body; + const { id } = req.params; + const senderId = +req.user.id; + const chatId = +id; + + const newMessage = await CreateMessageService({ + chatId, + senderId, + message + }); + + const chat = await Chat.findByPk(chatId, { + include: [ + { model: User, as: "owner" }, + { model: ChatUser, as: "users" } + ] + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-chat-${chatId}`, { + action: "new-message", + newMessage, + chat + }); + + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-chat`, { + action: "new-message", + newMessage, + chat + }); + + return res.json(newMessage); +}; + +export const checkAsRead = async ( + req: Request, + res: Response +): Promise => { + const { companyId } = req.user; + const { userId } = req.body; + const { id } = req.params; + + const chatUser = await ChatUser.findOne({ where: { chatId: id, userId } }); + await chatUser.update({ unreads: 0 }); + + const chat = await Chat.findByPk(id, { + include: [ + { model: User, as: "owner" }, + { model: ChatUser, as: "users" } + ] + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-chat-${id}`, { + action: "update", + chat + }); + + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-chat`, { + action: "update", + chat + }); + + return res.json(chat); +}; + +export const messages = async ( + req: Request, + res: Response +): Promise => { + const { pageNumber } = req.query as unknown as IndexQuery; + const { id: chatId } = req.params; + const ownerId = +req.user.id; + + const { records, count, hasMore } = await FindMessages({ + chatId, + ownerId, + pageNumber + }); + + return res.json({ records, count, hasMore }); +}; diff --git a/backend/src/controllers/CompanyController.ts b/backend/src/controllers/CompanyController.ts new file mode 100644 index 0000000..7bdcc68 --- /dev/null +++ b/backend/src/controllers/CompanyController.ts @@ -0,0 +1,180 @@ +import * as Yup from "yup"; +import { Request, Response } from "express"; +// import { getIO } from "../libs/socket"; +import AppError from "../errors/AppError"; +import Company from "../models/Company"; +import authConfig from "../config/auth"; + +import ListCompaniesService from "../services/CompanyService/ListCompaniesService"; +import CreateCompanyService from "../services/CompanyService/CreateCompanyService"; +import UpdateCompanyService from "../services/CompanyService/UpdateCompanyService"; +import ShowCompanyService from "../services/CompanyService/ShowCompanyService"; +import UpdateSchedulesService from "../services/CompanyService/UpdateSchedulesService"; +import DeleteCompanyService from "../services/CompanyService/DeleteCompanyService"; +import FindAllCompaniesService from "../services/CompanyService/FindAllCompaniesService"; +import { verify } from "jsonwebtoken"; +import User from "../models/User"; +import ShowPlanCompanyService from "../services/CompanyService/ShowPlanCompanyService"; +import ListCompaniesPlanService from "../services/CompanyService/ListCompaniesPlanService"; + +type IndexQuery = { + searchParam: string; + pageNumber: string; +}; + +interface TokenPayload { + id: string; + username: string; + profile: string; + companyId: number; + iat: number; + exp: number; +} + +type CompanyData = { + name: string; + id?: number; + phone?: string; + email?: string; + status?: boolean; + planId?: number; + campaignsEnabled?: boolean; + dueDate?: string; + recurrence?: string; +}; + +type SchedulesData = { + schedules: []; +}; + +export const index = async (req: Request, res: Response): Promise => { + const { searchParam, pageNumber } = req.query as IndexQuery; + + const { companies, count, hasMore } = await ListCompaniesService({ + searchParam, + pageNumber + }); + + return res.json({ companies, count, hasMore }); +}; + +export const store = async (req: Request, res: Response): Promise => { + const newCompany: CompanyData = req.body; + + const schema = Yup.object().shape({ + name: Yup.string().required() + }); + + try { + await schema.validate(newCompany); + } catch (err: any) { + throw new AppError(err.message); + } + + const company = await CreateCompanyService(newCompany); + + return res.status(200).json(company); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { id } = req.params; + + const company = await ShowCompanyService(id); + + return res.status(200).json(company); +}; + +export const list = async (req: Request, res: Response): Promise => { + const companies: Company[] = await FindAllCompaniesService(); + + return res.status(200).json(companies); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + const companyData: CompanyData = req.body; + + const schema = Yup.object().shape({ + name: Yup.string() + }); + + try { + await schema.validate(companyData); + } catch (err: any) { + throw new AppError(err.message); + } + + const { id } = req.params; + + const company = await UpdateCompanyService({ id, ...companyData }); + + return res.status(200).json(company); +}; + +export const updateSchedules = async ( + req: Request, + res: Response +): Promise => { + const { schedules }: SchedulesData = req.body; + const { id } = req.params; + + const company = await UpdateSchedulesService({ + id, + schedules + }); + + return res.status(200).json(company); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { id } = req.params; + + const company = await DeleteCompanyService(id); + + return res.status(200).json(company); +}; + +export const listPlan = async (req: Request, res: Response): Promise => { + const { id } = req.params; + + const authHeader = req.headers.authorization; + const [, token] = authHeader.split(" "); + const decoded = verify(token, authConfig.secret); + const { id: requestUserId, profile, companyId } = decoded as TokenPayload; + const requestUser = await User.findByPk(requestUserId); + + if (requestUser.super === true) { + const company = await ShowPlanCompanyService(id); + return res.status(200).json(company); + } else if (companyId.toString() !== id) { + return res.status(400).json({ error: "Você não possui permissão para acessar este recurso!" }); + } else { + const company = await ShowPlanCompanyService(id); + return res.status(200).json(company); + } + +}; + +export const indexPlan = async (req: Request, res: Response): Promise => { + const { searchParam, pageNumber } = req.query as IndexQuery; + + const authHeader = req.headers.authorization; + const [, token] = authHeader.split(" "); + const decoded = verify(token, authConfig.secret); + const { id, profile, companyId } = decoded as TokenPayload; + // const company = await Company.findByPk(companyId); + const requestUser = await User.findByPk(id); + + if (requestUser.super === true) { + const companies = await ListCompaniesPlanService(); + return res.json({ companies }); + } else { + return res.status(400).json({ error: "Você não possui permissão para acessar este recurso!" }); + } + +}; \ No newline at end of file diff --git a/backend/src/controllers/ContactController.ts b/backend/src/controllers/ContactController.ts new file mode 100644 index 0000000..08ae136 --- /dev/null +++ b/backend/src/controllers/ContactController.ts @@ -0,0 +1,193 @@ +import * as Yup from "yup"; +import { Request, Response } from "express"; +import { getIO } from "../libs/socket"; + +import ListContactsService from "../services/ContactServices/ListContactsService"; +import CreateContactService from "../services/ContactServices/CreateContactService"; +import ShowContactService from "../services/ContactServices/ShowContactService"; +import UpdateContactService from "../services/ContactServices/UpdateContactService"; +import DeleteContactService from "../services/ContactServices/DeleteContactService"; +import GetContactService from "../services/ContactServices/GetContactService"; + +import CheckContactNumber from "../services/WbotServices/CheckNumber"; +import CheckIsValidContact from "../services/WbotServices/CheckIsValidContact"; +import GetProfilePicUrl from "../services/WbotServices/GetProfilePicUrl"; +import AppError from "../errors/AppError"; +import SimpleListService, { + SearchContactParams +} from "../services/ContactServices/SimpleListService"; +import ContactCustomField from "../models/ContactCustomField"; + +type IndexQuery = { + searchParam: string; + pageNumber: string; +}; + +type IndexGetContactQuery = { + name: string; + number: string; +}; + +interface ExtraInfo extends ContactCustomField { + name: string; + value: string; +} +interface ContactData { + name: string; + number: string; + email?: string; + extraInfo?: ExtraInfo[]; +} + +export const index = async (req: Request, res: Response): Promise => { + const { searchParam, pageNumber } = req.query as IndexQuery; + const { companyId } = req.user; + + const { contacts, count, hasMore } = await ListContactsService({ + searchParam, + pageNumber, + companyId + }); + + return res.json({ contacts, count, hasMore }); +}; + +export const getContact = async ( + req: Request, + res: Response +): Promise => { + const { name, number } = req.body as IndexGetContactQuery; + const { companyId } = req.user; + + const contact = await GetContactService({ + name, + number, + companyId + }); + + return res.status(200).json(contact); +}; + +export const store = async (req: Request, res: Response): Promise => { + const { companyId } = req.user; + const newContact: ContactData = req.body; + newContact.number = newContact.number.replace("-", "").replace(" ", ""); + + const schema = Yup.object().shape({ + name: Yup.string().required(), + number: Yup.string() + .required() + .matches(/^\d+$/, "Invalid number format. Only numbers is allowed.") + }); + + try { + await schema.validate(newContact); + } catch (err: any) { + throw new AppError(err.message); + } + + await CheckIsValidContact(newContact.number, companyId); + const validNumber = await CheckContactNumber(newContact.number, companyId); + const number = validNumber.jid.replace(/\D/g, ""); + newContact.number = number; + + /** + * Código desabilitado por demora no retorno + */ + // const profilePicUrl = await GetProfilePicUrl(validNumber.jid, companyId); + + const contact = await CreateContactService({ + ...newContact, + // profilePicUrl, + companyId + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-contact`, { + action: "create", + contact + }); + + return res.status(200).json(contact); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { contactId } = req.params; + const { companyId } = req.user; + + const contact = await ShowContactService(contactId, companyId); + + return res.status(200).json(contact); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + const contactData: ContactData = req.body; + const { companyId } = req.user; + + const schema = Yup.object().shape({ + name: Yup.string(), + number: Yup.string().matches( + /^\d+$/, + "Invalid number format. Only numbers is allowed." + ) + }); + + try { + await schema.validate(contactData); + } catch (err: any) { + throw new AppError(err.message); + } + + await CheckIsValidContact(contactData.number, companyId); + const validNumber = await CheckContactNumber(contactData.number, companyId); + const number = validNumber.jid.replace(/\D/g, ""); + contactData.number = number; + + const { contactId } = req.params; + + const contact = await UpdateContactService({ + contactData, + contactId, + companyId + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-contact`, { + action: "update", + contact + }); + + return res.status(200).json(contact); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { contactId } = req.params; + const { companyId } = req.user; + + await ShowContactService(contactId, companyId); + + await DeleteContactService(contactId); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-contact`, { + action: "delete", + contactId + }); + + return res.status(200).json({ message: "Contact deleted" }); +}; + +export const list = async (req: Request, res: Response): Promise => { + const { name } = req.query as unknown as SearchContactParams; + const { companyId } = req.user; + + const contacts = await SimpleListService({ name, companyId }); + + return res.json(contacts); +}; diff --git a/backend/src/controllers/ContactListController.ts b/backend/src/controllers/ContactListController.ts new file mode 100644 index 0000000..ba1b422 --- /dev/null +++ b/backend/src/controllers/ContactListController.ts @@ -0,0 +1,159 @@ +import * as Yup from "yup"; +import { Request, Response } from "express"; +import { getIO } from "../libs/socket"; + +import ListService from "../services/ContactListService/ListService"; +import CreateService from "../services/ContactListService/CreateService"; +import ShowService from "../services/ContactListService/ShowService"; +import UpdateService from "../services/ContactListService/UpdateService"; +import DeleteService from "../services/ContactListService/DeleteService"; +import FindService from "../services/ContactListService/FindService"; +import { head } from "lodash"; + +import ContactList from "../models/ContactList"; + +import AppError from "../errors/AppError"; +import { ImportContacts } from "../services/ContactListService/ImportContacts"; + +type IndexQuery = { + searchParam: string; + pageNumber: string; + companyId: string | number; +}; + +type StoreData = { + name: string; + companyId: string; +}; + +type FindParams = { + companyId: string; +}; + +export const index = async (req: Request, res: Response): Promise => { + const { searchParam, pageNumber } = req.query as IndexQuery; + const { companyId } = req.user; + + const { records, count, hasMore } = await ListService({ + searchParam, + pageNumber, + companyId + }); + + return res.json({ records, count, hasMore }); +}; + +export const store = async (req: Request, res: Response): Promise => { + const { companyId } = req.user; + const data = req.body as StoreData; + + const schema = Yup.object().shape({ + name: Yup.string().required() + }); + + try { + await schema.validate(data); + } catch (err: any) { + throw new AppError(err.message); + } + + const record = await CreateService({ + ...data, + companyId + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-ContactList`, { + action: "create", + record + }); + + return res.status(200).json(record); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { id } = req.params; + + const record = await ShowService(id); + + return res.status(200).json(record); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + const data = req.body as StoreData; + const { companyId } = req.user; + + const schema = Yup.object().shape({ + name: Yup.string().required() + }); + + try { + await schema.validate(data); + } catch (err: any) { + throw new AppError(err.message); + } + + const { id } = req.params; + + const record = await UpdateService({ + ...data, + id + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-ContactList`, { + action: "update", + record + }); + + return res.status(200).json(record); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { id } = req.params; + const { companyId } = req.user; + + await DeleteService(id); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-ContactList`, { + action: "delete", + id + }); + + return res.status(200).json({ message: "Contact list deleted" }); +}; + +export const findList = async ( + req: Request, + res: Response +): Promise => { + const params = req.query as FindParams; + const records: ContactList[] = await FindService(params); + + return res.status(200).json(records); +}; + +export const upload = async (req: Request, res: Response) => { + const files = req.files as Express.Multer.File[]; + const file: Express.Multer.File = head(files) as Express.Multer.File; + const { id } = req.params; + const { companyId } = req.user; + + const response = await ImportContacts(+id, companyId, file); + + const io = getIO(); + + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-ContactListItem-${+id}`, { + action: "reload", + records: response + }); + + return res.status(200).json(response); +}; diff --git a/backend/src/controllers/ContactListItemController.ts b/backend/src/controllers/ContactListItemController.ts new file mode 100644 index 0000000..56295be --- /dev/null +++ b/backend/src/controllers/ContactListItemController.ts @@ -0,0 +1,145 @@ +import * as Yup from "yup"; +import { Request, Response } from "express"; +import { getIO } from "../libs/socket"; + +import ListService from "../services/ContactListItemService/ListService"; +import CreateService from "../services/ContactListItemService/CreateService"; +import ShowService from "../services/ContactListItemService/ShowService"; +import UpdateService from "../services/ContactListItemService/UpdateService"; +import DeleteService from "../services/ContactListItemService/DeleteService"; +import FindService from "../services/ContactListItemService/FindService"; + +import ContactListItem from "../models/ContactListItem"; + +import AppError from "../errors/AppError"; + +type IndexQuery = { + searchParam: string; + pageNumber: string; + companyId: string | number; + contactListId: string | number; +}; + +type StoreData = { + name: string; + number: string; + contactListId: number; + companyId?: string; + email?: string; +}; + +type FindParams = { + companyId: number; + contactListId: number; +}; + +export const index = async (req: Request, res: Response): Promise => { + const { searchParam, pageNumber, contactListId } = req.query as IndexQuery; + const { companyId } = req.user; + + const { contacts, count, hasMore } = await ListService({ + searchParam, + pageNumber, + companyId, + contactListId + }); + + return res.json({ contacts, count, hasMore }); +}; + +export const store = async (req: Request, res: Response): Promise => { + const { companyId } = req.user; + const data = req.body as StoreData; + + const schema = Yup.object().shape({ + name: Yup.string().required() + }); + + try { + await schema.validate(data); + } catch (err: any) { + throw new AppError(err.message); + } + + const record = await CreateService({ + ...data, + companyId + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-ContactListItem`, { + action: "create", + record + }); + + return res.status(200).json(record); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { id } = req.params; + + const record = await ShowService(id); + + return res.status(200).json(record); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + const data = req.body as StoreData; + const { companyId } = req.user; + + const schema = Yup.object().shape({ + name: Yup.string().required() + }); + + try { + await schema.validate(data); + } catch (err: any) { + throw new AppError(err.message); + } + + const { id } = req.params; + + const record = await UpdateService({ + ...data, + id + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-ContactListItem`, { + action: "update", + record + }); + + return res.status(200).json(record); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { id } = req.params; + const { companyId } = req.user; + + await DeleteService(id); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-ContactListItem`, { + action: "delete", + id + }); + + return res.status(200).json({ message: "Contact deleted" }); +}; + +export const findList = async ( + req: Request, + res: Response +): Promise => { + const params = req.query as unknown as FindParams; + const records: ContactListItem[] = await FindService(params); + + return res.status(200).json(records); +}; diff --git a/backend/src/controllers/DashbardController.ts b/backend/src/controllers/DashbardController.ts new file mode 100644 index 0000000..e0527f5 --- /dev/null +++ b/backend/src/controllers/DashbardController.ts @@ -0,0 +1,42 @@ +import { Request, Response } from "express"; +import DashboardDataService, { DashboardData, Params } from "../services/ReportService/DashbardDataService"; +import { TicketsAttendance } from "../services/ReportService/TicketsAttendance"; +import { TicketsDayService } from "../services/ReportService/TicketsDayService"; + +type IndexQuery = { + initialDate: string; + finalDate: string; + companyId: number | any; +}; + +export const index = async (req: Request, res: Response): Promise => { + const params: Params = req.query; + const { companyId } = req.user; + let daysInterval = 3; + + const dashboardData: DashboardData = await DashboardDataService( + companyId, + params + ); + return res.status(200).json(dashboardData); +}; + +export const reportsUsers = async (req: Request, res: Response): Promise => { + + const { initialDate, finalDate, companyId } = req.query as IndexQuery + + const { data } = await TicketsAttendance({ initialDate, finalDate, companyId }); + + return res.json({ data }); + +} + +export const reportsDay = async (req: Request, res: Response): Promise => { + + const { initialDate, finalDate, companyId } = req.query as IndexQuery + + const { count, data } = await TicketsDayService({ initialDate, finalDate, companyId }); + + return res.json({ count, data }); + +} diff --git a/backend/src/controllers/FilesController.ts b/backend/src/controllers/FilesController.ts new file mode 100644 index 0000000..ee54e26 --- /dev/null +++ b/backend/src/controllers/FilesController.ts @@ -0,0 +1,155 @@ +import { Request, Response } from "express"; +import { getIO } from "../libs/socket"; + +import AppError from "../errors/AppError"; +import { head } from "lodash"; + +import CreateService from "../services/FileServices/CreateService"; +import ListService from "../services/FileServices/ListService"; +import UpdateService from "../services/FileServices/UpdateService"; +import ShowService from "../services/FileServices/ShowService"; +import DeleteService from "../services/FileServices/DeleteService"; +import SimpleListService from "../services/FileServices/SimpleListService"; +import DeleteAllService from "../services/FileServices/DeleteAllService"; +import ShowTicketService from "../services/TicketServices/ShowTicketService"; +import UpdateTicketService from "../services/TicketServices/UpdateTicketService"; +import FilesOptions from "../models/FilesOptions"; + +type IndexQuery = { + searchParam?: string; + pageNumber?: string | number; +}; + +export const index = async (req: Request, res: Response): Promise => { + const { pageNumber, searchParam } = req.query as IndexQuery; + const { companyId } = req.user; + + const { files, count, hasMore } = await ListService({ + searchParam, + pageNumber, + companyId + }); + + return res.json({ files, count, hasMore }); +}; + +export const store = async (req: Request, res: Response): Promise => { + const { name, message, options } = req.body; + const { companyId } = req.user; + + const fileList = await CreateService({ + name, + message, + options, + companyId + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company${companyId}-file`, { + action: "create", + fileList + }); + + return res.status(200).json(fileList); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { fileId } = req.params; + const { companyId } = req.user; + + const file = await ShowService(fileId, companyId); + + return res.status(200).json(file); +}; + +export const uploadMedias = async (req: Request, res: Response): Promise => { + const { fileId, id, mediaType } = req.body; + const files = req.files as Express.Multer.File[]; + const file = head(files); + + try { + + let fileOpt + if (files.length > 0) { + + for (const [index, file] of files.entries()) { + fileOpt = await FilesOptions.findOne({ + where: { + fileId, + id: Array.isArray(id)? id[index] : id + } + }); + + fileOpt.update({ + path: file.filename.replace('/','-'), + mediaType: Array.isArray(mediaType)? mediaType[index] : mediaType + }) ; + } + } + + return res.send({ mensagem: "Arquivos atualizados" }); + } catch (err: any) { + throw new AppError(err.message); + } +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + if (req.user.profile !== "admin") { + throw new AppError("ERR_NO_PERMISSION", 403); + } + + const { fileId } = req.params; + const fileData = req.body; + const { companyId } = req.user; + + const fileList = await UpdateService({ fileData, id: fileId, companyId }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company${companyId}-file`, { + action: "update", + fileList + }); + + return res.status(200).json(fileList); +}; + + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { fileId } = req.params; + const { companyId } = req.user; + + await DeleteService(fileId, companyId); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company${companyId}-file`, { + action: "delete", + fileId + }); + + return res.status(200).json({ message: "File List deleted" }); +}; + +export const removeAll = async ( + req: Request, + res: Response +): Promise => { + const { companyId } = req.user; + await DeleteAllService(companyId); + + return res.send(); +}; + +export const list = async (req: Request, res: Response): Promise => { + const { searchParam } = req.query as IndexQuery; + const { companyId } = req.user; + + const ratings = await SimpleListService({ searchParam, companyId }); + + return res.json(ratings); +}; diff --git a/backend/src/controllers/ForgotController.ts b/backend/src/controllers/ForgotController.ts new file mode 100644 index 0000000..121efb2 --- /dev/null +++ b/backend/src/controllers/ForgotController.ts @@ -0,0 +1,25 @@ +import { v4 as uuid } from "uuid"; +import { Request, Response } from "express"; +import SendMail from "../services/ForgotPassWordServices/SendMail"; +import ResetPassword from "../services/ResetPasswordService/ResetPassword"; +type IndexQuery = { email?: string; token?: string; password?: string }; +export const store = async (req: Request, res: Response): Promise => { + const { email } = req.params as IndexQuery; + const TokenSenha = uuid(); + const forgotPassword = await SendMail(email, TokenSenha); + if (!forgotPassword) { + return res.status(200).json({ message: "E-mail enviado com sucesso" }); + } + return res.status(404).json({ error: "E-mail enviado com sucesso" }); +}; +export const resetPasswords = async ( + req: Request, + res: Response +): Promise => { + const { email, token, password } = req.params as IndexQuery; + const resetPassword = await ResetPassword(email, token, password); + if (!resetPassword) { + return res.status(200).json({ message: "Senha redefinida com sucesso" }); + } + return res.status(404).json({ error: "Verifique o Token informado" }); +}; diff --git a/backend/src/controllers/HelpController.ts b/backend/src/controllers/HelpController.ts new file mode 100644 index 0000000..e6bb521 --- /dev/null +++ b/backend/src/controllers/HelpController.ts @@ -0,0 +1,131 @@ +import * as Yup from "yup"; +import { Request, Response } from "express"; +import { getIO } from "../libs/socket"; + +import ListService from "../services/HelpServices/ListService"; +import CreateService from "../services/HelpServices/CreateService"; +import ShowService from "../services/HelpServices/ShowService"; +import UpdateService from "../services/HelpServices/UpdateService"; +import DeleteService from "../services/HelpServices/DeleteService"; +import FindService from "../services/HelpServices/FindService"; + +import Help from "../models/Help"; + +import AppError from "../errors/AppError"; + +type IndexQuery = { + searchParam: string; + pageNumber: string; +}; + +type StoreData = { + title: string; + description: string; + video?: string; + link?: string; +}; + +export const index = async (req: Request, res: Response): Promise => { + const { searchParam, pageNumber } = req.query as IndexQuery; + + const { records, count, hasMore } = await ListService({ + searchParam, + pageNumber + }); + return res.json({ records, count, hasMore }); +}; + +export const store = async (req: Request, res: Response): Promise => { + const { companyId } = req.user; + const data = req.body as StoreData; + + const schema = Yup.object().shape({ + title: Yup.string().required() + }); + + try { + await schema.validate(data); + } catch (err) { + throw new AppError(err.message); + } + + const record = await CreateService({ + ...data + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-help`, { + action: "create", + record + }); + + return res.status(200).json(record); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { id } = req.params; + + const record = await ShowService(id); + + return res.status(200).json(record); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + const data = req.body as StoreData; + const { companyId } = req.user; + + const schema = Yup.object().shape({ + title: Yup.string().required() + }); + + try { + await schema.validate(data); + } catch (err) { + throw new AppError(err.message); + } + + const { id } = req.params; + + const record = await UpdateService({ + ...data, + id + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-help`, { + action: "update", + record + }); + + return res.status(200).json(record); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { id } = req.params; + const { companyId } = req.user; + + await DeleteService(id); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-help`, { + action: "delete", + id + }); + + return res.status(200).json({ message: "Help deleted" }); +}; + +export const findList = async ( + req: Request, + res: Response +): Promise => { + const records: Help[] = await FindService(); + + return res.status(200).json(records); +}; diff --git a/backend/src/controllers/ImportPhoneContactsController.ts b/backend/src/controllers/ImportPhoneContactsController.ts new file mode 100644 index 0000000..a1084f6 --- /dev/null +++ b/backend/src/controllers/ImportPhoneContactsController.ts @@ -0,0 +1,10 @@ +import { Request, Response } from "express"; +import ImportContactsService from "../services/WbotServices/ImportContactsService"; + +export const store = async (req: Request, res: Response): Promise => { + const { companyId } = req.user; + + await ImportContactsService(companyId); + + return res.status(200).json({ message: "contacts imported" }); +}; diff --git a/backend/src/controllers/InvoicesController.ts b/backend/src/controllers/InvoicesController.ts new file mode 100644 index 0000000..44180c8 --- /dev/null +++ b/backend/src/controllers/InvoicesController.ts @@ -0,0 +1,172 @@ +import * as Yup from "yup"; +import { Request, Response } from "express"; +// import { getIO } from "../libs/socket"; +import AppError from "../errors/AppError"; +import Invoices from "../models/Invoices"; + +import CreatePlanService from "../services/PlanService/CreatePlanService"; +import UpdatePlanService from "../services/PlanService/UpdatePlanService"; +import ShowPlanService from "../services/PlanService/ShowPlanService"; +import DeletePlanService from "../services/PlanService/DeletePlanService"; + +import FindAllInvoiceService from "../services/InvoicesService/FindAllInvoiceService"; +import ListInvoicesServices from "../services/InvoicesService/ListInvoicesServices"; +import ShowInvoceService from "../services/InvoicesService/ShowInvoiceService"; +import UpdateInvoiceService from "../services/InvoicesService/UpdateInvoiceService"; + +type IndexQuery = { + searchParam: string; + pageNumber: string; +}; + +type StorePlanData = { + name: string; + id?: number | string; + users: number | 0; + connections: number | 0; + queues: number | 0; + value: number; +}; + +type UpdateInvoiceData = { + status: string; + id?: string; +}; + +export const index = async (req: Request, res: Response): Promise => { + const { searchParam, pageNumber } = req.query as IndexQuery; + + const { invoices, count, hasMore } = await ListInvoicesServices({ + searchParam, + pageNumber + }); + + return res.json({ invoices, count, hasMore }); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { Invoiceid } = req.params; + + const invoice = await ShowInvoceService(Invoiceid); + + return res.status(200).json(invoice); +}; + + +export const list = async (req: Request, res: Response): Promise => { + const { companyId } = req.user; + const invoice: Invoices[] = await FindAllInvoiceService(companyId); + + return res.status(200).json(invoice); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + const InvoiceData: UpdateInvoiceData = req.body; + + const schema = Yup.object().shape({ + name: Yup.string() + }); + + try { + await schema.validate(InvoiceData); + } catch (err) { + throw new AppError(err.message); + } + + const { id, status } = InvoiceData; + + const plan = await UpdateInvoiceService({ + id, + status, + + }); + + // const io = getIO(); + // io.emit("plan", { + // action: "update", + // plan + // }); + + return res.status(200).json(plan); +}; +/* export const store = async (req: Request, res: Response): Promise => { + const newPlan: StorePlanData = req.body; + + const schema = Yup.object().shape({ + name: Yup.string().required() + }); + + try { + await schema.validate(newPlan); + } catch (err) { + throw new AppError(err.message); + } + + const plan = await CreatePlanService(newPlan); + + // const io = getIO(); + // io.emit("plan", { + // action: "create", + // plan + // }); + + return res.status(200).json(plan); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { id } = req.params; + + const plan = await ShowPlanService(id); + + return res.status(200).json(plan); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + const planData: UpdateInvoiceData = req.body; + + const schema = Yup.object().shape({ + name: Yup.string() + }); + + try { + await schema.validate(planData); + } catch (err) { + throw new AppError(err.message); + } + + const { id, name, users, connections, queues, value } = planData; + + const plan = await UpdatePlanService({ + id, + name, + users, + connections, + queues, + value + }); + + // const io = getIO(); + // io.emit("plan", { + // action: "update", + // plan + // }); + + return res.status(200).json(plan); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { id } = req.params; + + const plan = await DeletePlanService(id); + + return res.status(200).json(plan); +}; */ diff --git a/backend/src/controllers/MessageController.ts b/backend/src/controllers/MessageController.ts new file mode 100644 index 0000000..f6f132a --- /dev/null +++ b/backend/src/controllers/MessageController.ts @@ -0,0 +1,192 @@ +import { Request, Response } from "express"; +import AppError from "../errors/AppError"; + +import SetTicketMessagesAsRead from "../helpers/SetTicketMessagesAsRead"; +import { getIO } from "../libs/socket"; +import Message from "../models/Message"; +import Queue from "../models/Queue"; +import User from "../models/User"; +import Whatsapp from "../models/Whatsapp"; +import formatBody from "../helpers/Mustache"; + +import ListMessagesService from "../services/MessageServices/ListMessagesService"; +import ShowTicketService from "../services/TicketServices/ShowTicketService"; +import FindOrCreateTicketService from "../services/TicketServices/FindOrCreateTicketService"; +import UpdateTicketService from "../services/TicketServices/UpdateTicketService"; +import DeleteWhatsAppMessage from "../services/WbotServices/DeleteWhatsAppMessage"; +import SendWhatsAppMedia from "../services/WbotServices/SendWhatsAppMedia"; +import SendWhatsAppMessage from "../services/WbotServices/SendWhatsAppMessage"; +import CheckContactNumber from "../services/WbotServices/CheckNumber"; +import CheckIsValidContact from "../services/WbotServices/CheckIsValidContact"; +import GetProfilePicUrl from "../services/WbotServices/GetProfilePicUrl"; +import CreateOrUpdateContactService from "../services/ContactServices/CreateOrUpdateContactService"; +type IndexQuery = { + pageNumber: string; +}; + +type MessageData = { + body: string; + fromMe: boolean; + read: boolean; + quotedMsg?: Message; + number?: string; + closeTicket?: true; +}; + +export const index = async (req: Request, res: Response): Promise => { + const { ticketId } = req.params; + const { pageNumber } = req.query as IndexQuery; + const { companyId, profile } = req.user; + const queues: number[] = []; + + if (profile !== "admin") { + const user = await User.findByPk(req.user.id, { + include: [{ model: Queue, as: "queues" }] + }); + user.queues.forEach(queue => { + queues.push(queue.id); + }); + } + + const { count, messages, ticket, hasMore } = await ListMessagesService({ + pageNumber, + ticketId, + companyId, + queues + }); + + SetTicketMessagesAsRead(ticket); + + return res.json({ count, messages, ticket, hasMore }); +}; + +export const store = async (req: Request, res: Response): Promise => { + const { ticketId } = req.params; + const { body, quotedMsg }: MessageData = req.body; + const medias = req.files as Express.Multer.File[]; + const { companyId } = req.user; + + const ticket = await ShowTicketService(ticketId, companyId); + + SetTicketMessagesAsRead(ticket); + + if (medias) { + await Promise.all( + medias.map(async (media: Express.Multer.File, index) => { + await SendWhatsAppMedia({ media, ticket, body: Array.isArray(body) ? body[index] : body }); + }) + ); + } else { + const send = await SendWhatsAppMessage({ body, ticket, quotedMsg }); + } + + return res.send(); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { messageId } = req.params; + const { companyId } = req.user; + + const message = await DeleteWhatsAppMessage(messageId); + + const io = getIO(); + io.to(message.ticketId.toString()).emit(`company-${companyId}-appMessage`, { + action: "update", + message + }); + + return res.send(); +}; + +export const send = async (req: Request, res: Response): Promise => { + const { whatsappId } = req.params as unknown as { whatsappId: number }; + const messageData: MessageData = req.body; + const medias = req.files as Express.Multer.File[]; + + try { + const whatsapp = await Whatsapp.findByPk(whatsappId); + + if (!whatsapp) { + throw new Error("Não foi possível realizar a operação"); + } + + if (messageData.number === undefined) { + throw new Error("O número é obrigatório"); + } + + const numberToTest = messageData.number; + const body = messageData.body; + + const companyId = whatsapp.companyId; + + const CheckValidNumber = await CheckContactNumber(numberToTest, companyId); + const number = CheckValidNumber.jid.replace(/\D/g, ""); + const profilePicUrl = await GetProfilePicUrl( + number, + companyId + ); + const contactData = { + name: `${number}`, + number, + profilePicUrl, + isGroup: false, + companyId + }; + + const contact = await CreateOrUpdateContactService(contactData); + + const ticket = await FindOrCreateTicketService(contact, whatsapp.id!, 0, companyId); + + if (medias) { + await Promise.all( + medias.map(async (media: Express.Multer.File) => { + await req.app.get("queues").messageQueue.add( + "SendMessage", + { + whatsappId, + data: { + number, + body: body ? formatBody(body, contact) : media.originalname, + mediaPath: media.path, + fileName: media.originalname + } + }, + { removeOnComplete: true, attempts: 3 } + ); + }) + ); + } else { + await SendWhatsAppMessage({ body: formatBody(body, contact), ticket }); + + await ticket.update({ + lastMessage: body, + }); + + } + + if (messageData.closeTicket) { + setTimeout(async () => { + await UpdateTicketService({ + ticketId: ticket.id, + ticketData: { status: "closed" }, + companyId + }); + }, 1000); + } + + SetTicketMessagesAsRead(ticket); + + return res.send({ mensagem: "Mensagem enviada" }); + } catch (err: any) { + if (Object.keys(err).length === 0) { + throw new AppError( + "Não foi possível enviar a mensagem, tente novamente em alguns instantes" + ); + } else { + throw new AppError(err.message); + } + } +}; diff --git a/backend/src/controllers/PlanController.ts b/backend/src/controllers/PlanController.ts new file mode 100644 index 0000000..85e071f --- /dev/null +++ b/backend/src/controllers/PlanController.ts @@ -0,0 +1,136 @@ +import * as Yup from "yup"; +import { Request, Response } from "express"; +// import { getIO } from "../libs/socket"; +import AppError from "../errors/AppError"; +import Plan from "../models/Plan"; + +import ListPlansService from "../services/PlanService/ListPlansService"; +import CreatePlanService from "../services/PlanService/CreatePlanService"; +import UpdatePlanService from "../services/PlanService/UpdatePlanService"; +import ShowPlanService from "../services/PlanService/ShowPlanService"; +import FindAllPlanService from "../services/PlanService/FindAllPlanService"; +import DeletePlanService from "../services/PlanService/DeletePlanService"; + +type IndexQuery = { + searchParam: string; + pageNumber: string; +}; + +type StorePlanData = { + name: string; + id?: number | string; + users: number | 0; + connections: number | 0; + queues: number | 0; + value: number; + useCampaigns?: boolean; + useSchedules?: boolean; + useInternalChat?: boolean; + useExternalApi?: boolean; + useKanban?: boolean; + useOpenAi?: boolean; + useIntegrations?: boolean; +}; + +type UpdatePlanData = { + name: string; + id?: number | string; + users?: number; + connections?: number; + queues?: number; + value?: number; + useCampaigns?: boolean; + useSchedules?: boolean; + useInternalChat?: boolean; + useExternalApi?: boolean; + useKanban?: boolean; + useOpenAi?: boolean; + useIntegrations?: boolean; +}; + +export const index = async (req: Request, res: Response): Promise => { + const { searchParam, pageNumber } = req.query as IndexQuery; + + const { plans, count, hasMore } = await ListPlansService({ + searchParam, + pageNumber + }); + + return res.json({ plans, count, hasMore }); +}; + +export const list = async (req: Request, res: Response): Promise => { + const plans: Plan[] = await FindAllPlanService(); + + return res.status(200).json(plans); +}; + +export const store = async (req: Request, res: Response): Promise => { + const newPlan: StorePlanData = req.body; + + const schema = Yup.object().shape({ + name: Yup.string().required() + }); + + try { + await schema.validate(newPlan); + } catch (err) { + throw new AppError(err.message); + } + + const plan = await CreatePlanService(newPlan); + + // const io = getIO(); + // io.emit("plan", { + // action: "create", + // plan + // }); + + return res.status(200).json(plan); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { id } = req.params; + + const plan = await ShowPlanService(id); + + return res.status(200).json(plan); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + const planData: UpdatePlanData = req.body; + + const schema = Yup.object().shape({ + name: Yup.string() + }); + + try { + await schema.validate(planData); + } catch (err) { + throw new AppError(err.message); + } + + const plan = await UpdatePlanService(planData); + + // const io = getIO(); + // io.emit("plan", { + // action: "update", + // plan + // }); + + return res.status(200).json(plan); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { id } = req.params; + + const plan = await DeletePlanService(id); + + return res.status(200).json(plan); +}; diff --git a/backend/src/controllers/PromptController.ts b/backend/src/controllers/PromptController.ts new file mode 100644 index 0000000..d6969ba --- /dev/null +++ b/backend/src/controllers/PromptController.ts @@ -0,0 +1,114 @@ +import { Request, Response } from "express"; +import { getIO } from "../libs/socket"; +import CreatePromptService from "../services/PromptServices/CreatePromptService"; +import DeletePromptService from "../services/PromptServices/DeletePromptService"; +import ListPromptsService from "../services/PromptServices/ListPromptsService"; +import ShowPromptService from "../services/PromptServices/ShowPromptService"; +import UpdatePromptService from "../services/PromptServices/UpdatePromptService"; +import Whatsapp from "../models/Whatsapp"; +import { verify } from "jsonwebtoken"; +import authConfig from "../config/auth"; + +interface TokenPayload { + id: string; + username: string; + profile: string; + companyId: number; + iat: number; + exp: number; +} + +type IndexQuery = { + searchParam?: string; + pageNumber?: string | number; +}; + +export const index = async (req: Request, res: Response): Promise => { + const { pageNumber, searchParam } = req.query as IndexQuery; + const authHeader = req.headers.authorization; + const [, token] = authHeader.split(" "); + const decoded = verify(token, authConfig.secret); + const { companyId } = decoded as TokenPayload; + const { prompts, count, hasMore } = await ListPromptsService({ searchParam, pageNumber, companyId }); + + return res.status(200).json({ prompts, count, hasMore }); +}; + +export const store = async (req: Request, res: Response): Promise => { + const authHeader = req.headers.authorization; + const [, token] = authHeader.split(" "); + const decoded = verify(token, authConfig.secret); + const { companyId } = decoded as TokenPayload; + const { name, apiKey, prompt, maxTokens, temperature, promptTokens, completionTokens, totalTokens, queueId, maxMessages,voice,voiceKey,voiceRegion } = req.body; + const promptTable = await CreatePromptService({ name, apiKey, prompt, maxTokens, temperature, promptTokens, completionTokens, totalTokens, queueId, maxMessages, companyId,voice,voiceKey,voiceRegion }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit("prompt", { + action: "update", + prompt: promptTable + }); + + return res.status(200).json(promptTable); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { promptId } = req.params; + const authHeader = req.headers.authorization; + const [, token] = authHeader.split(" "); + const decoded = verify(token, authConfig.secret); + const { companyId } = decoded as TokenPayload; + const prompt = await ShowPromptService({ promptId, companyId }); + + return res.status(200).json(prompt); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + const { promptId } = req.params; + const promptData = req.body; + const authHeader = req.headers.authorization; + const [, token] = authHeader.split(" "); + const decoded = verify(token, authConfig.secret); + const { companyId } = decoded as TokenPayload; + + const prompt = await UpdatePromptService({ promptData, promptId: promptId, companyId }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit("prompt", { + action: "update", + prompt + }); + + return res.status(200).json(prompt); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { promptId } = req.params; + const authHeader = req.headers.authorization; + const [, token] = authHeader.split(" "); + const decoded = verify(token, authConfig.secret); + const { companyId } = decoded as TokenPayload; + try { + const { count } = await Whatsapp.findAndCountAll({ where: { promptId: +promptId, companyId } }); + + if (count > 0) return res.status(200).json({ message: "Não foi possível excluir! Verifique se este prompt está sendo usado nas conexões Whatsapp!" }); + + await DeletePromptService(promptId, companyId); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit("prompt", { + action: "delete", + intelligenceId: +promptId + }); + + return res.status(200).json({ message: "Prompt deleted" }); + } catch (err) { + return res.status(500).json({ message: "Não foi possível excluir! Verifique se este prompt está sendo usado!" }); + } +}; + diff --git a/backend/src/controllers/QueueController.ts b/backend/src/controllers/QueueController.ts new file mode 100644 index 0000000..7a0ebd2 --- /dev/null +++ b/backend/src/controllers/QueueController.ts @@ -0,0 +1,107 @@ +import { Request, Response } from "express"; +import { getIO } from "../libs/socket"; +import CreateQueueService from "../services/QueueService/CreateQueueService"; +import DeleteQueueService from "../services/QueueService/DeleteQueueService"; +import ListQueuesService from "../services/QueueService/ListQueuesService"; +import ShowQueueService from "../services/QueueService/ShowQueueService"; +import UpdateQueueService from "../services/QueueService/UpdateQueueService"; +import { isNil } from "lodash"; + +type QueueFilter = { + companyId: number; +}; + +export const index = async (req: Request, res: Response): Promise => { + const { companyId: userCompanyId } = req.user; + const { companyId: queryCompanyId } = req.query as unknown as QueueFilter; + let companyId = userCompanyId; + + if (!isNil(queryCompanyId)) { + companyId = +queryCompanyId; + } + + const queues = await ListQueuesService({ companyId }); + + return res.status(200).json(queues); +}; + +export const store = async (req: Request, res: Response): Promise => { + const { name, color, greetingMessage, outOfHoursMessage, schedules, orderQueue, integrationId, promptId } = + req.body; + const { companyId } = req.user; + console.log("queue", integrationId, promptId) + const queue = await CreateQueueService({ + name, + color, + greetingMessage, + companyId, + outOfHoursMessage, + schedules, + orderQueue: orderQueue === "" ? null : orderQueue, + integrationId: integrationId === "" ? null : integrationId, + promptId: promptId === "" ? null : promptId + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-queue`, { + action: "update", + queue + }); + + return res.status(200).json(queue); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { queueId } = req.params; + const { companyId } = req.user; + + const queue = await ShowQueueService(queueId, companyId); + + return res.status(200).json(queue); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + const { queueId } = req.params; + const { companyId } = req.user; + const { name, color, greetingMessage, outOfHoursMessage, schedules, orderQueue, integrationId, promptId } = + req.body; + const queue = await UpdateQueueService(queueId, { + name, + color, + greetingMessage, + outOfHoursMessage, + schedules, + orderQueue: orderQueue === "" ? null : orderQueue, + integrationId: integrationId === "" ? null : integrationId, + promptId: promptId === "" ? null : promptId + }, companyId); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-queue`, { + action: "update", + queue + }); + + return res.status(201).json(queue); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { queueId } = req.params; + const { companyId } = req.user; + + await DeleteQueueService(queueId, companyId); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-queue`, { + action: "delete", + queueId: +queueId + }); + + return res.status(200).send(); +}; diff --git a/backend/src/controllers/QueueIntegrationController.ts b/backend/src/controllers/QueueIntegrationController.ts new file mode 100644 index 0000000..7fbb095 --- /dev/null +++ b/backend/src/controllers/QueueIntegrationController.ts @@ -0,0 +1,99 @@ +import { Request, Response } from "express"; +import { getIO } from "../libs/socket"; +import CreateQueueIntegrationService from "../services/QueueIntegrationServices/CreateQueueIntegrationService"; +import DeleteQueueIntegrationService from "../services/QueueIntegrationServices/DeleteQueueIntegrationService"; +import ListQueueIntegrationService from "../services/QueueIntegrationServices/ListQueueIntegrationService"; +import ShowQueueIntegrationService from "../services/QueueIntegrationServices/ShowQueueIntegrationService"; +import UpdateQueueIntegrationService from "../services/QueueIntegrationServices/UpdateQueueIntegrationService"; + +type IndexQuery = { + searchParam: string; + pageNumber: string; +}; + +export const index = async (req: Request, res: Response): Promise => { + const { searchParam, pageNumber } = req.query as IndexQuery; + const { companyId } = req.user; + + const { queueIntegrations, count, hasMore } = await ListQueueIntegrationService({ + searchParam, + pageNumber, + companyId + }); + + return res.status(200).json({ queueIntegrations, count, hasMore }); +}; + +export const store = async (req: Request, res: Response): Promise => { + const { type, name, projectName, jsonContent, language, urlN8N, + typebotExpires, + typebotKeywordFinish, + typebotSlug, + typebotUnknownMessage, + typebotKeywordRestart, + typebotRestartMessage } = req.body; + const { companyId } = req.user; + const queueIntegration = await CreateQueueIntegrationService({ + type, name, projectName, jsonContent, language, urlN8N, companyId, + typebotExpires, + typebotKeywordFinish, + typebotSlug, + typebotUnknownMessage, + typebotKeywordRestart, + typebotRestartMessage + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-queueIntegration`, { + action: "create", + queueIntegration + }); + + return res.status(200).json(queueIntegration); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { integrationId } = req.params; + const { companyId } = req.user; + + const queueIntegration = await ShowQueueIntegrationService(integrationId, companyId); + + return res.status(200).json(queueIntegration); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + const { integrationId } = req.params; + const integrationData = req.body; + const { companyId } = req.user; + + const queueIntegration = await UpdateQueueIntegrationService({ integrationData, integrationId, companyId }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-queueIntegration`, { + action: "update", + queueIntegration + }); + + return res.status(201).json(queueIntegration); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { integrationId } = req.params; + const { companyId } = req.user; + + await DeleteQueueIntegrationService(integrationId); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-queueIntegration`, { + action: "delete", + integrationId: +integrationId + }); + + return res.status(200).send(); +}; \ No newline at end of file diff --git a/backend/src/controllers/QueueOptionController.ts b/backend/src/controllers/QueueOptionController.ts new file mode 100644 index 0000000..e3cbcae --- /dev/null +++ b/backend/src/controllers/QueueOptionController.ts @@ -0,0 +1,60 @@ +import { Request, Response } from "express"; + +import CreateService from "../services/QueueOptionService/CreateService"; +import ListService from "../services/QueueOptionService/ListService"; +import UpdateService from "../services/QueueOptionService/UpdateService"; +import ShowService from "../services/QueueOptionService/ShowService"; +import DeleteService from "../services/QueueOptionService/DeleteService"; + +type FilterList = { + queueId: string | number; + queueOptionId: string | number; + parentId: string | number | boolean; +}; + +export const index = async (req: Request, res: Response): Promise => { + const { queueId, queueOptionId, parentId } = req.query as FilterList; + + const queueOptions = await ListService({ queueId, queueOptionId, parentId }); + + return res.json(queueOptions); +}; + +export const store = async (req: Request, res: Response): Promise => { + const queueOptionData = req.body; + + const queueOption = await CreateService(queueOptionData); + + return res.status(200).json(queueOption); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { queueOptionId } = req.params; + + const queueOption = await ShowService(queueOptionId); + + return res.status(200).json(queueOption); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + const { queueOptionId } = req.params + const queueOptionData = req.body; + + const queueOption = await UpdateService(queueOptionId, queueOptionData); + + return res.status(200).json(queueOption); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { queueOptionId } = req.params + + await DeleteService(queueOptionId); + + return res.status(200).json({ message: "Option Delected" }); +}; diff --git a/backend/src/controllers/QuickMessageController.ts b/backend/src/controllers/QuickMessageController.ts new file mode 100644 index 0000000..353ebf5 --- /dev/null +++ b/backend/src/controllers/QuickMessageController.ts @@ -0,0 +1,197 @@ +import * as Yup from "yup"; +import { Request, Response } from "express"; +import { getIO } from "../libs/socket"; + +import ListService from "../services/QuickMessageService/ListService"; +import CreateService from "../services/QuickMessageService/CreateService"; +import ShowService from "../services/QuickMessageService/ShowService"; +import UpdateService from "../services/QuickMessageService/UpdateService"; +import DeleteService from "../services/QuickMessageService/DeleteService"; +import FindService from "../services/QuickMessageService/FindService"; + +import QuickMessage from "../models/QuickMessage"; + +import { head } from "lodash"; +import fs from "fs"; +import path from "path"; + +import AppError from "../errors/AppError"; + +type IndexQuery = { + searchParam: string; + pageNumber: string; + userId: string | number; +}; + +type StoreData = { + shortcode: string; + message: string; + userId: number | number; +}; + +type FindParams = { + companyId: string; + userId: string; +}; + +export const index = async (req: Request, res: Response): Promise => { + const { searchParam, pageNumber, userId } = req.query as IndexQuery; + const { companyId } = req.user; + + const { records, count, hasMore } = await ListService({ + searchParam, + pageNumber, + companyId, + userId + }); + + return res.json({ records, count, hasMore }); +}; + +export const store = async (req: Request, res: Response): Promise => { + const { companyId } = req.user; + const data = req.body as StoreData; + + const schema = Yup.object().shape({ + shortcode: Yup.string().required(), + message: Yup.string().required() + }); + + try { + await schema.validate(data); + } catch (err: any) { + throw new AppError(err.message); + } + + const record = await CreateService({ + ...data, + companyId, + userId: req.user.id + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-quickmessage`, { + action: "create", + record + }); + + return res.status(200).json(record); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { id } = req.params; + + const record = await ShowService(id); + + return res.status(200).json(record); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + const data = req.body as StoreData; + const { companyId } = req.user; + + const schema = Yup.object().shape({ + shortcode: Yup.string().required(), + message: Yup.string().required() + }); + + try { + await schema.validate(data); + } catch (err: any) { + throw new AppError(err.message); + } + + const { id } = req.params; + + const record = await UpdateService({ + ...data, + userId: req.user.id, + id, + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-quickmessage`, { + action: "update", + record + }); + + return res.status(200).json(record); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { id } = req.params; + const { companyId } = req.user; + + await DeleteService(id); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-quickmessage`, { + action: "delete", + id + }); + + return res.status(200).json({ message: "Contact deleted" }); +}; + +export const findList = async ( + req: Request, + res: Response +): Promise => { + const params = req.query as FindParams; + const records: QuickMessage[] = await FindService(params); + + return res.status(200).json(records); +}; + +export const mediaUpload = async ( + req: Request, + res: Response +): Promise => { + const { id } = req.params; + const files = req.files as Express.Multer.File[]; + const file = head(files); + + try { + const quickmessage = await QuickMessage.findByPk(id); + + quickmessage.update ({ + mediaPath: file.filename, + mediaName: file.originalname + }); + + return res.send({ mensagem: "Arquivo Anexado" }); + } catch (err: any) { + throw new AppError(err.message); + } +}; + +export const deleteMedia = async ( + req: Request, + res: Response +): Promise => { + const { id } = req.params; + const { companyId } = req.user + + try { + const quickmessage = await QuickMessage.findByPk(id); + const filePath = path.resolve("public","quickMessage",quickmessage.mediaName); + const fileExists = fs.existsSync(filePath); + if (fileExists) { + fs.unlinkSync(filePath); + } + quickmessage.update ({ + mediaPath: null, + mediaName: null + }); + + return res.send({ mensagem: "Arquivo Excluído" }); + } catch (err: any) { + throw new AppError(err.message); + } +}; \ No newline at end of file diff --git a/backend/src/controllers/QuickMessageController_OLD.ts b/backend/src/controllers/QuickMessageController_OLD.ts new file mode 100644 index 0000000..257d728 --- /dev/null +++ b/backend/src/controllers/QuickMessageController_OLD.ts @@ -0,0 +1,146 @@ +import * as Yup from "yup"; +import { Request, Response } from "express"; +import { getIO } from "../libs/socket"; + +import ListService from "../services/QuickMessageService/ListService"; +import CreateService from "../services/QuickMessageService/CreateService"; +import ShowService from "../services/QuickMessageService/ShowService"; +import UpdateService from "../services/QuickMessageService/UpdateService"; +import DeleteService from "../services/QuickMessageService/DeleteService"; +import FindService from "../services/QuickMessageService/FindService"; + +import QuickMessage from "../models/QuickMessage"; + +import AppError from "../errors/AppError"; + +type IndexQuery = { + searchParam: string; + pageNumber: string; + userId: string | number; +}; + +type StoreData = { + shortcode: string; + message: string; + userId: number | number; +}; + +type FindParams = { + companyId: string; + userId: string; +}; + +export const index = async (req: Request, res: Response): Promise => { + const { searchParam, pageNumber, userId } = req.query as IndexQuery; + const { companyId } = req.user; + + const { records, count, hasMore } = await ListService({ + searchParam, + pageNumber, + companyId, + userId + }); + + return res.json({ records, count, hasMore }); +}; + +export const store = async (req: Request, res: Response): Promise => { + const { companyId } = req.user; + const data = req.body as StoreData; + + const schema = Yup.object().shape({ + shortcode: Yup.string().required(), + message: Yup.string().required() + }); + + try { + await schema.validate(data); + } catch (err: any) { + throw new AppError(err.message); + } + + const record = await CreateService({ + ...data, + companyId, + userId: req.user.id + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-quickmessage`, { + action: "create", + record + }); + + return res.status(200).json(record); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { id } = req.params; + + const record = await ShowService(id); + + return res.status(200).json(record); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + const data = req.body as StoreData; + const { companyId } = req.user; + + const schema = Yup.object().shape({ + shortcode: Yup.string().required(), + message: Yup.string().required() + }); + + try { + await schema.validate(data); + } catch (err: any) { + throw new AppError(err.message); + } + + const { id } = req.params; + + const record = await UpdateService({ + ...data, + userId: req.user.id, + id, + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-quickmessage`, { + action: "update", + record + }); + + return res.status(200).json(record); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { id } = req.params; + const { companyId } = req.user; + + await DeleteService(id); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-quickmessage`, { + action: "delete", + id + }); + + return res.status(200).json({ message: "Contact deleted" }); +}; + +export const findList = async ( + req: Request, + res: Response +): Promise => { + const params = req.query as FindParams; + const records: QuickMessage[] = await FindService(params); + + return res.status(200).json(records); +}; diff --git a/backend/src/controllers/ScheduleController.ts b/backend/src/controllers/ScheduleController.ts new file mode 100644 index 0000000..51df02f --- /dev/null +++ b/backend/src/controllers/ScheduleController.ts @@ -0,0 +1,154 @@ +import { Request, Response } from "express"; +import { getIO } from "../libs/socket"; + +import AppError from "../errors/AppError"; + +import CreateService from "../services/ScheduleServices/CreateService"; +import ListService from "../services/ScheduleServices/ListService"; +import UpdateService from "../services/ScheduleServices/UpdateService"; +import ShowService from "../services/ScheduleServices/ShowService"; +import DeleteService from "../services/ScheduleServices/DeleteService"; +import Schedule from "../models/Schedule"; +import path from "path"; +import fs from "fs"; +import { head } from "lodash"; + +type IndexQuery = { + searchParam?: string; + contactId?: number | string; + userId?: number | string; + pageNumber?: string | number; +}; + +export const index = async (req: Request, res: Response): Promise => { + const { contactId, userId, pageNumber, searchParam } = req.query as IndexQuery; + const { companyId } = req.user; + + const { schedules, count, hasMore } = await ListService({ + searchParam, + contactId, + userId, + pageNumber, + companyId + }); + + return res.json({ schedules, count, hasMore }); +}; + +export const store = async (req: Request, res: Response): Promise => { + const { + body, + sendAt, + contactId, + userId + } = req.body; + const { companyId } = req.user; + + const schedule = await CreateService({ + body, + sendAt, + contactId, + companyId, + userId + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit("schedule", { + action: "create", + schedule + }); + + return res.status(200).json(schedule); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { scheduleId } = req.params; + const { companyId } = req.user; + + const schedule = await ShowService(scheduleId, companyId); + + return res.status(200).json(schedule); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + if (req.user.profile !== "admin") { + throw new AppError("ERR_NO_PERMISSION", 403); + } + + const { scheduleId } = req.params; + const scheduleData = req.body; + const { companyId } = req.user; + + const schedule = await UpdateService({ scheduleData, id: scheduleId, companyId }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit("schedule", { + action: "update", + schedule + }); + + return res.status(200).json(schedule); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { scheduleId } = req.params; + const { companyId } = req.user; + + await DeleteService(scheduleId, companyId); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit("schedule", { + action: "delete", + scheduleId + }); + + return res.status(200).json({ message: "Schedule deleted" }); +}; + +export const mediaUpload = async ( + req: Request, + res: Response +): Promise => { + const { id } = req.params; + const files = req.files as Express.Multer.File[]; + const file = head(files); + + try { + const schedule = await Schedule.findByPk(id); + schedule.mediaPath = file.filename; + schedule.mediaName = file.originalname; + + await schedule.save(); + return res.send({ mensagem: "Arquivo Anexado" }); + } catch (err: any) { + throw new AppError(err.message); + } +}; + +export const deleteMedia = async ( + req: Request, + res: Response +): Promise => { + const { id } = req.params; + + try { + const schedule = await Schedule.findByPk(id); + const filePath = path.resolve("public", schedule.mediaPath); + const fileExists = fs.existsSync(filePath); + if (fileExists) { + fs.unlinkSync(filePath); + } + schedule.mediaPath = null; + schedule.mediaName = null; + await schedule.save(); + return res.send({ mensagem: "Arquivo Excluído" }); + } catch (err: any) { + throw new AppError(err.message); + } +}; \ No newline at end of file diff --git a/backend/src/controllers/SessionController.ts b/backend/src/controllers/SessionController.ts new file mode 100644 index 0000000..9dabe76 --- /dev/null +++ b/backend/src/controllers/SessionController.ts @@ -0,0 +1,80 @@ +import { Request, Response } from "express"; +import AppError from "../errors/AppError"; +import { getIO } from "../libs/socket"; + +import AuthUserService from "../services/UserServices/AuthUserService"; +import { SendRefreshToken } from "../helpers/SendRefreshToken"; +import { RefreshTokenService } from "../services/AuthServices/RefreshTokenService"; +import FindUserFromToken from "../services/AuthServices/FindUserFromToken"; +import User from "../models/User"; + +export const store = async (req: Request, res: Response): Promise => { + const { email, password } = req.body; + + const { token, serializedUser, refreshToken } = await AuthUserService({ + email, + password + }); + + SendRefreshToken(res, refreshToken); + + const io = getIO(); + io.to(`user-${serializedUser.id}`).emit(`company-${serializedUser.companyId}-auth`, { + action: "update", + user: { + id: serializedUser.id, + email: serializedUser.email, + companyId: serializedUser.companyId + } + }); + + return res.status(200).json({ + token, + user: serializedUser + }); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + const token: string = req.cookies.jrt; + + if (!token) { + throw new AppError("ERR_SESSION_EXPIRED", 401); + } + + const { user, newToken, refreshToken } = await RefreshTokenService( + res, + token + ); + + SendRefreshToken(res, refreshToken); + + return res.json({ token: newToken, user }); +}; + +export const me = async (req: Request, res: Response): Promise => { + const token: string = req.cookies.jrt; + const user = await FindUserFromToken(token); + const { id, profile, super: superAdmin } = user; + + if (!token) { + throw new AppError("ERR_SESSION_EXPIRED", 401); + } + + return res.json({ id, profile, super: superAdmin }); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { id } = req.user; + const user = await User.findByPk(id); + await user.update({ online: false }); + + res.clearCookie("jrt"); + + return res.send(); +}; diff --git a/backend/src/controllers/SettingController.ts b/backend/src/controllers/SettingController.ts new file mode 100644 index 0000000..a5f43ae --- /dev/null +++ b/backend/src/controllers/SettingController.ts @@ -0,0 +1,45 @@ +import { Request, Response } from "express"; + +import { getIO } from "../libs/socket"; +import AppError from "../errors/AppError"; + +import UpdateSettingService from "../services/SettingServices/UpdateSettingService"; +import ListSettingsService from "../services/SettingServices/ListSettingsService"; + +export const index = async (req: Request, res: Response): Promise => { + const { companyId } = req.user; + + // if (req.user.profile !== "admin") { + // throw new AppError("ERR_NO_PERMISSION", 403); + // } + + const settings = await ListSettingsService({ companyId }); + + return res.status(200).json(settings); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + if (req.user.profile !== "admin") { + throw new AppError("ERR_NO_PERMISSION", 403); + } + const { settingKey: key } = req.params; + const { value } = req.body; + const { companyId } = req.user; + + const setting = await UpdateSettingService({ + key, + value, + companyId + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-settings`, { + action: "update", + setting + }); + + return res.status(200).json(setting); +}; diff --git a/backend/src/controllers/SubscriptionController.ts b/backend/src/controllers/SubscriptionController.ts new file mode 100644 index 0000000..c408733 --- /dev/null +++ b/backend/src/controllers/SubscriptionController.ts @@ -0,0 +1,198 @@ +import { Request, Response } from "express"; +import express from "express"; +import * as Yup from "yup"; +import Gerencianet from "gn-api-sdk-typescript"; +import AppError from "../errors/AppError"; + +import options from "../config/Gn"; +import Company from "../models/Company"; +import Invoices from "../models/Invoices"; +import Subscriptions from "../models/Subscriptions"; +import { getIO } from "../libs/socket"; +import UpdateUserService from "../services/UserServices/UpdateUserService"; + +const app = express(); + + +export const index = async (req: Request, res: Response): Promise => { + const gerencianet = Gerencianet(options); + return res.json(gerencianet.getSubscriptions()); +}; + +export const createSubscription = async ( + req: Request, + res: Response + ): Promise => { + const gerencianet = Gerencianet(options); + const { companyId } = req.user; + + const schema = Yup.object().shape({ + price: Yup.string().required(), + users: Yup.string().required(), + connections: Yup.string().required() + }); + + if (!(await schema.isValid(req.body))) { + throw new AppError("Validation fails", 400); + } + + const { + firstName, + price, + users, + connections, + address2, + city, + state, + zipcode, + country, + plan, + invoiceId + } = req.body; + + const body = { + calendario: { + expiracao: 3600 + }, + valor: { + original: price.toLocaleString("pt-br", { minimumFractionDigits: 2 }).replace(",", ".") + }, + chave: process.env.GERENCIANET_PIX_KEY, + solicitacaoPagador: `#Fatura:${invoiceId}` + }; + try { + const pix = await gerencianet.pixCreateImmediateCharge(null, body); + + const qrcode = await gerencianet.pixGenerateQRCode({ + id: pix.loc.id + }); + + const updateCompany = await Company.findOne(); + + if (!updateCompany) { + throw new AppError("Company not found", 404); + } + + +/* await Subscriptions.create({ + companyId, + isActive: false, + userPriceCents: users, + whatsPriceCents: connections, + lastInvoiceUrl: pix.location, + lastPlanChange: new Date(), + providerSubscriptionId: pix.loc.id, + expiresAt: new Date() + }); */ + +/* const { id } = req.user; + const userData = {}; + const userId = id; + const requestUserId = parseInt(id); + const user = await UpdateUserService({ userData, userId, companyId, requestUserId }); */ + + /* const io = getIO(); + io.emit("user", { + action: "update", + user + }); */ + + + return res.json({ + ...pix, + qrcode, + + }); + } catch (error) { + throw new AppError("Validation fails", 400); + } +}; + +export const createWebhook = async ( + req: Request, + res: Response +): Promise => { + const schema = Yup.object().shape({ + chave: Yup.string().required(), + url: Yup.string().required() + }); + + if (!(await schema.isValid(req.body))) { + throw new AppError("Validation fails", 400); + } + + const { chave, url } = req.body; + + const body = { + webhookUrl: url + }; + + const params = { + chave + }; + + try { + const gerencianet = Gerencianet(options); + const create = await gerencianet.pixConfigWebhook(params, body); + return res.json(create); + } catch (error) { + console.log(error); + } +}; + +export const webhook = async ( + req: Request, + res: Response + ): Promise => { + const { type } = req.params; + const { evento } = req.body; + if (evento === "teste_webhook") { + return res.json({ ok: true }); + } + if (req.body.pix) { + const gerencianet = Gerencianet(options); + req.body.pix.forEach(async (pix: any) => { + const detahe = await gerencianet.pixDetailCharge({ + txid: pix.txid + }); + + if (detahe.status === "CONCLUIDA") { + const { solicitacaoPagador } = detahe; + const invoiceID = solicitacaoPagador.replace("#Fatura:", ""); + const invoices = await Invoices.findByPk(invoiceID); + const companyId =invoices.companyId; + const company = await Company.findByPk(companyId); + + const expiresAt = new Date(company.dueDate); + expiresAt.setDate(expiresAt.getDate() + 30); + const date = expiresAt.toISOString().split("T")[0]; + + if (company) { + await company.update({ + dueDate: date + }); + const invoi = await invoices.update({ + id: invoiceID, + status: 'paid' + }); + await company.reload(); + const io = getIO(); + const companyUpdate = await Company.findOne({ + where: { + id: companyId + } + }); + + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-payment`, { + action: detahe.status, + company: companyUpdate + }); + } + + } + }); + + } + + return res.json({ ok: true }); +}; diff --git a/backend/src/controllers/TagController.ts b/backend/src/controllers/TagController.ts new file mode 100644 index 0000000..4de55cd --- /dev/null +++ b/backend/src/controllers/TagController.ts @@ -0,0 +1,128 @@ +import { Request, Response } from "express"; +import { getIO } from "../libs/socket"; + +import AppError from "../errors/AppError"; + +import CreateService from "../services/TagServices/CreateService"; +import ListService from "../services/TagServices/ListService"; +import UpdateService from "../services/TagServices/UpdateService"; +import ShowService from "../services/TagServices/ShowService"; +import DeleteService from "../services/TagServices/DeleteService"; +import SimpleListService from "../services/TagServices/SimpleListService"; +import SyncTagService from "../services/TagServices/SyncTagsService"; +import KanbanListService from "../services/TagServices/KanbanListService"; + +type IndexQuery = { + searchParam?: string; + pageNumber?: string | number; + kanban?: number; +}; + +export const index = async (req: Request, res: Response): Promise => { + const { pageNumber, searchParam } = req.query as IndexQuery; + const { companyId } = req.user; + + const { tags, count, hasMore } = await ListService({ + searchParam, + pageNumber, + companyId + }); + + return res.json({ tags, count, hasMore }); +}; + +export const store = async (req: Request, res: Response): Promise => { + const { name, color, kanban } = req.body; + const { companyId } = req.user; + + const tag = await CreateService({ + name, + color, + companyId, + kanban + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit("tag", { + action: "create", + tag + }); + + return res.status(200).json(tag); +}; + +export const kanban = async (req: Request, res: Response): Promise => { + const { companyId } = req.user; + + const tags = await KanbanListService({ companyId }); + + return res.json({lista:tags}); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { tagId } = req.params; + + const tag = await ShowService(tagId); + + return res.status(200).json(tag); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + if (req.user.profile !== "admin") { + throw new AppError("ERR_NO_PERMISSION", 403); + } + + const { tagId } = req.params; + const tagData = req.body; + + const tag = await UpdateService({ tagData, id: tagId }); + + const io = getIO(); + io.to(`company-${req.user.companyId}-mainchannel`).emit("tag", { + action: "update", + tag + }); + + return res.status(200).json(tag); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { tagId } = req.params; + + await DeleteService(tagId); + + const io = getIO(); + io.to(`company-${req.user.companyId}-mainchannel`).emit("tag", { + action: "delete", + tagId + }); + + return res.status(200).json({ message: "Tag deleted" }); +}; + +export const list = async (req: Request, res: Response): Promise => { + const { searchParam } = req.query as IndexQuery; + const { companyId } = req.user; + + const tags = await SimpleListService({ searchParam, companyId }); + + return res.json(tags); +}; + +export const syncTags = async ( + req: Request, + res: Response +): Promise => { + const data = req.body; + const { companyId } = req.user; + + const tags = await SyncTagService({ ...data, companyId }); + + return res.json(tags); +}; diff --git a/backend/src/controllers/TicketController.ts b/backend/src/controllers/TicketController.ts new file mode 100644 index 0000000..c1d4542 --- /dev/null +++ b/backend/src/controllers/TicketController.ts @@ -0,0 +1,223 @@ +import { Request, Response } from "express"; +import { getIO } from "../libs/socket"; +import Ticket from "../models/Ticket"; + +import CreateTicketService from "../services/TicketServices/CreateTicketService"; +import DeleteTicketService from "../services/TicketServices/DeleteTicketService"; +import ListTicketsService from "../services/TicketServices/ListTicketsService"; +import ShowTicketUUIDService from "../services/TicketServices/ShowTicketFromUUIDService"; +import ShowTicketService from "../services/TicketServices/ShowTicketService"; +import UpdateTicketService from "../services/TicketServices/UpdateTicketService"; +import ListTicketsServiceKanban from "../services/TicketServices/ListTicketsServiceKanban"; + +type IndexQuery = { + searchParam: string; + pageNumber: string; + status: string; + date: string; + updatedAt?: string; + showAll: string; + withUnreadMessages: string; + queueIds: string; + tags: string; + users: string; +}; + +interface TicketData { + contactId: number; + status: string; + queueId: number; + userId: number; + whatsappId: string; + useIntegration: boolean; + promptId: number; + integrationId: number; +} + +export const index = async (req: Request, res: Response): Promise => { + const { + pageNumber, + status, + date, + updatedAt, + searchParam, + showAll, + queueIds: queueIdsStringified, + tags: tagIdsStringified, + users: userIdsStringified, + withUnreadMessages + } = req.query as IndexQuery; + + const userId = req.user.id; + const { companyId } = req.user; + + let queueIds: number[] = []; + let tagsIds: number[] = []; + let usersIds: number[] = []; + + if (queueIdsStringified) { + queueIds = JSON.parse(queueIdsStringified); + } + + if (tagIdsStringified) { + tagsIds = JSON.parse(tagIdsStringified); + } + + if (userIdsStringified) { + usersIds = JSON.parse(userIdsStringified); + } + + const { tickets, count, hasMore } = await ListTicketsService({ + searchParam, + tags: tagsIds, + users: usersIds, + pageNumber, + status, + date, + updatedAt, + showAll, + userId, + queueIds, + withUnreadMessages, + companyId, + + + }); + return res.status(200).json({ tickets, count, hasMore }); +}; + +export const store = async (req: Request, res: Response): Promise => { + const { contactId, status, userId, queueId, whatsappId }: TicketData = req.body; + const { companyId } = req.user; + + const ticket = await CreateTicketService({ + contactId, + status, + userId, + companyId, + queueId, + whatsappId + }); + + const io = getIO(); + io.to(ticket.status).emit(`company-${companyId}-ticket`, { + action: "update", + ticket + }); + return res.status(200).json(ticket); +}; + +export const kanban = async (req: Request, res: Response): Promise => { + const { + pageNumber, + status, + date, + updatedAt, + searchParam, + showAll, + queueIds: queueIdsStringified, + tags: tagIdsStringified, + users: userIdsStringified, + withUnreadMessages + } = req.query as IndexQuery; + + + const userId = req.user.id; + const { companyId } = req.user; + + let queueIds: number[] = []; + let tagsIds: number[] = []; + let usersIds: number[] = []; + + if (queueIdsStringified) { + queueIds = JSON.parse(queueIdsStringified); + } + + if (tagIdsStringified) { + tagsIds = JSON.parse(tagIdsStringified); + } + + if (userIdsStringified) { + usersIds = JSON.parse(userIdsStringified); + } + + const { tickets, count, hasMore } = await ListTicketsServiceKanban({ + searchParam, + tags: tagsIds, + users: usersIds, + pageNumber, + status, + date, + updatedAt, + showAll, + userId, + queueIds, + withUnreadMessages, + companyId + + }); + + return res.status(200).json({ tickets, count, hasMore }); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { ticketId } = req.params; + const { companyId } = req.user; + + const contact = await ShowTicketService(ticketId, companyId); + return res.status(200).json(contact); +}; + +export const showFromUUID = async ( + req: Request, + res: Response +): Promise => { + const { uuid } = req.params; + + const ticket: Ticket = await ShowTicketUUIDService(uuid); + + return res.status(200).json(ticket); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + const { ticketId } = req.params; + const ticketData: TicketData = req.body; + const { companyId } = req.user; + + const { ticket } = await UpdateTicketService({ + ticketData, + ticketId, + companyId + }); + + + return res.status(200).json(ticket); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { ticketId } = req.params; + const { companyId } = req.user; + + await ShowTicketService(ticketId, companyId); + + const ticket = await DeleteTicketService(ticketId); + + const io = getIO(); + io.to(ticketId) + .to(`company-${companyId}-${ticket.status}`) + .to(`company-${companyId}-notification`) + .to(`queue-${ticket.queueId}-${ticket.status}`) + .to(`queue-${ticket.queueId}-notification`) + .emit(`company-${companyId}-ticket`, { + action: "delete", + ticketId: +ticketId + }); + + return res.status(200).json({ message: "ticket deleted" }); +}; diff --git a/backend/src/controllers/TicketNoteController.ts b/backend/src/controllers/TicketNoteController.ts new file mode 100644 index 0000000..42a4379 --- /dev/null +++ b/backend/src/controllers/TicketNoteController.ts @@ -0,0 +1,138 @@ +import * as Yup from "yup"; +import { Request, Response } from "express"; +import AppError from "../errors/AppError"; +import TicketNote from "../models/TicketNote"; + +import ListTicketNotesService from "../services/TicketNoteService/ListTicketNotesService"; +import CreateTicketNoteService from "../services/TicketNoteService/CreateTicketNoteService"; +import UpdateTicketNoteService from "../services/TicketNoteService/UpdateTicketNoteService"; +import ShowTicketNoteService from "../services/TicketNoteService/ShowTicketNoteService"; +import FindAllTicketNotesService from "../services/TicketNoteService/FindAllTicketNotesService"; +import DeleteTicketNoteService from "../services/TicketNoteService/DeleteTicketNoteService"; +import FindNotesByContactIdAndTicketId from "../services/TicketNoteService/FindNotesByContactIdAndTicketId"; + +type IndexQuery = { + searchParam: string; + pageNumber: string; +}; + +type StoreTicketNoteData = { + note: string; + userId: number; + contactId: number | 0; + ticketId: number | 0; + id?: number | string; +}; + +type UpdateTicketNoteData = { + note: string; + id?: number | string; + userId?: number | 0; + contactId?: number | 0; + ticketId?: number | 0; +}; + +type QueryFilteredNotes = { + contactId: number | string; + ticketId: number | string; +}; + +export const index = async (req: Request, res: Response): Promise => { + const { searchParam, pageNumber } = req.query as IndexQuery; + + const { ticketNotes, count, hasMore } = await ListTicketNotesService({ + searchParam, + pageNumber + }); + + return res.json({ ticketNotes, count, hasMore }); +}; + +export const list = async (req: Request, res: Response): Promise => { + const ticketNotes: TicketNote[] = await FindAllTicketNotesService(); + + return res.status(200).json(ticketNotes); +}; + +export const store = async (req: Request, res: Response): Promise => { + const newTicketNote: StoreTicketNoteData = req.body; + const { id: userId } = req.user; + + const schema = Yup.object().shape({ + note: Yup.string().required() + }); + + try { + await schema.validate(newTicketNote); + } catch (err) { + throw new AppError(err.message); + } + + const ticketNote = await CreateTicketNoteService({ + ...newTicketNote, + userId + }); + + return res.status(200).json(ticketNote); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { id } = req.params; + + const ticketNote = await ShowTicketNoteService(id); + + return res.status(200).json(ticketNote); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + const ticketNote: UpdateTicketNoteData = req.body; + + const schema = Yup.object().shape({ + note: Yup.string() + }); + + try { + await schema.validate(ticketNote); + } catch (err) { + throw new AppError(err.message); + } + + const recordUpdated = await UpdateTicketNoteService(ticketNote); + + return res.status(200).json(recordUpdated); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { id } = req.params; + + if (req.user.profile !== "admin") { + throw new AppError("ERR_NO_PERMISSION", 403); + } + + await DeleteTicketNoteService(id); + + return res.status(200).json({ message: "Observação removida" }); +}; + +export const findFilteredList = async ( + req: Request, + res: Response +): Promise => { + try { + const { contactId, ticketId } = req.query as QueryFilteredNotes; + const notes: TicketNote[] = await FindNotesByContactIdAndTicketId({ + contactId, + ticketId + }); + + return res.status(200).json(notes); + } catch (e) { + return res.status(500).json({ message: e }); + } +}; diff --git a/backend/src/controllers/TicketTagController.ts b/backend/src/controllers/TicketTagController.ts new file mode 100644 index 0000000..c240c8b --- /dev/null +++ b/backend/src/controllers/TicketTagController.ts @@ -0,0 +1,57 @@ +import { Request, Response } from "express"; +import AppError from "../errors/AppError"; +import TicketTag from '../models/TicketTag'; +import Tag from '../models/Tag' + +export const store = async (req: Request, res: Response): Promise => { + const { ticketId, tagId } = req.params; + + try { + const ticketTag = await TicketTag.create({ ticketId, tagId }); + return res.status(201).json(ticketTag); + } catch (error) { + return res.status(500).json({ error: 'Failed to store ticket tag.' }); + } +}; + +/* +export const remove = async (req: Request, res: Response): Promise => { + const { ticketId } = req.params; + + + + try { + await TicketTag.destroy({ where: { ticketId } }); + return res.status(200).json({ message: 'Ticket tags removed successfully.' }); + } catch (error) { + return res.status(500).json({ error: 'Failed to remove ticket tags.' }); + } +}; +*/ +export const remove = async (req: Request, res: Response): Promise => { + const { ticketId } = req.params; + + + try { + // Retrieve tagIds associated with the provided ticketId from TicketTags + const ticketTags = await TicketTag.findAll({ where: { ticketId } }); + const tagIds = ticketTags.map((ticketTag) => ticketTag.tagId); + + // Find the tagIds with kanban = 1 in the Tags table + const tagsWithKanbanOne = await Tag.findAll({ + where: { + id: tagIds, + kanban: 1, + }, + }); + + // Remove the tagIds with kanban = 1 from TicketTags + const tagIdsWithKanbanOne = tagsWithKanbanOne.map((tag) => tag.id); + if (tagIdsWithKanbanOne) + await TicketTag.destroy({ where: { ticketId, tagId: tagIdsWithKanbanOne } }); + + return res.status(200).json({ message: 'Ticket tags removed successfully.' }); + } catch (error) { + return res.status(500).json({ error: 'Failed to remove ticket tags.' }); + } +}; diff --git a/backend/src/controllers/UserController.ts b/backend/src/controllers/UserController.ts new file mode 100644 index 0000000..2865b20 --- /dev/null +++ b/backend/src/controllers/UserController.ts @@ -0,0 +1,158 @@ +import { Request, Response } from "express"; +import { getIO } from "../libs/socket"; + +import CheckSettingsHelper from "../helpers/CheckSettings"; +import AppError from "../errors/AppError"; + +import CreateUserService from "../services/UserServices/CreateUserService"; +import ListUsersService from "../services/UserServices/ListUsersService"; +import UpdateUserService from "../services/UserServices/UpdateUserService"; +import ShowUserService from "../services/UserServices/ShowUserService"; +import DeleteUserService from "../services/UserServices/DeleteUserService"; +import SimpleListService from "../services/UserServices/SimpleListService"; +import User from "../models/User"; + +type IndexQuery = { + searchParam: string; + pageNumber: string; +}; + +type ListQueryParams = { + companyId: string; +}; + +export const index = async (req: Request, res: Response): Promise => { + const { searchParam, pageNumber } = req.query as IndexQuery; + const { companyId, profile } = req.user; + + const { users, count, hasMore } = await ListUsersService({ + searchParam, + pageNumber, + companyId, + profile + }); + + return res.json({ users, count, hasMore }); +}; + +export const store = async (req: Request, res: Response): Promise => { + const { + email, + password, + name, + profile, + companyId: bodyCompanyId, + queueIds, + whatsappId, + allTicket + } = req.body; + let userCompanyId: number | null = null; + + let requestUser: User = null; + + if (req.user !== undefined) { + const { companyId: cId } = req.user; + userCompanyId = cId; + requestUser = await User.findByPk(req.user.id); + } + + const newUserCompanyId = bodyCompanyId || userCompanyId; + + if (req.url === "/signup") { + if (await CheckSettingsHelper("userCreation") === "disabled") { + throw new AppError("ERR_USER_CREATION_DISABLED", 403); + } + } else if (req.user?.profile !== "admin") { + throw new AppError("ERR_NO_PERMISSION", 403); + } else if (newUserCompanyId !== req.user?.companyId && !requestUser?.super) { + throw new AppError("ERR_NO_SUPER", 403); + } + + const user = await CreateUserService({ + email, + password, + name, + profile, + companyId: newUserCompanyId, + queueIds, + whatsappId, + allTicket + }); + + const io = getIO(); + io.to(`company-${userCompanyId}-mainchannel`).emit(`company-${userCompanyId}-user`, { + action: "create", + user + }); + + return res.status(200).json(user); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { userId } = req.params; + + const user = await ShowUserService(userId); + + return res.status(200).json(user); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + if (req.user.profile !== "admin") { + throw new AppError("ERR_NO_PERMISSION", 403); + } + + const { id: requestUserId, companyId } = req.user; + const { userId } = req.params; + const userData = req.body; + + const user = await UpdateUserService({ + userData, + userId, + companyId, + requestUserId: +requestUserId + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-user`, { + action: "update", + user + }); + + return res.status(200).json(user); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { userId } = req.params; + const { companyId } = req.user; + + if (req.user.profile !== "admin") { + throw new AppError("ERR_NO_PERMISSION", 403); + } + + await DeleteUserService(userId, companyId); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-user`, { + action: "delete", + userId + }); + + return res.status(200).json({ message: "User deleted" }); +}; + +export const list = async (req: Request, res: Response): Promise => { + const { companyId } = req.query; + const { companyId: userCompanyId } = req.user; + + const users = await SimpleListService({ + companyId: companyId ? +companyId : userCompanyId + }); + + return res.status(200).json(users); +}; diff --git a/backend/src/controllers/VersionController.ts b/backend/src/controllers/VersionController.ts new file mode 100644 index 0000000..bb1cfa3 --- /dev/null +++ b/backend/src/controllers/VersionController.ts @@ -0,0 +1,7 @@ +import { Request, Response } from "express"; + +export const index = async (req: Request, res: Response): Promise => { + return res.status(200).json({ + version: "4.6.5" + }); +}; diff --git a/backend/src/controllers/WhatsAppController.ts b/backend/src/controllers/WhatsAppController.ts new file mode 100644 index 0000000..79b7e89 --- /dev/null +++ b/backend/src/controllers/WhatsAppController.ts @@ -0,0 +1,166 @@ +import { Request, Response } from "express"; +import { getIO } from "../libs/socket"; +import { removeWbot } from "../libs/wbot"; +import { StartWhatsAppSession } from "../services/WbotServices/StartWhatsAppSession"; + +import CreateWhatsAppService from "../services/WhatsappService/CreateWhatsAppService"; +import DeleteWhatsAppService from "../services/WhatsappService/DeleteWhatsAppService"; +import ListWhatsAppsService from "../services/WhatsappService/ListWhatsAppsService"; +import ShowWhatsAppService from "../services/WhatsappService/ShowWhatsAppService"; +import UpdateWhatsAppService from "../services/WhatsappService/UpdateWhatsAppService"; + +interface WhatsappData { + name: string; + queueIds: number[]; + companyId: number; + greetingMessage?: string; + complationMessage?: string; + outOfHoursMessage?: string; + ratingMessage?: string; + status?: string; + isDefault?: boolean; + token?: string; + //sendIdQueue?: number; + //timeSendQueue?: number; + transferQueueId?: number; + timeToTransfer?: number; + promptId?: number; + maxUseBotQueues?: number; + timeUseBotQueues?: number; + expiresTicket?: number; + expiresInactiveMessage?: string; +} + +interface QueryParams { + session?: number | string; +} + +export const index = async (req: Request, res: Response): Promise => { + const { companyId } = req.user; + const { session } = req.query as QueryParams; + const whatsapps = await ListWhatsAppsService({ companyId, session }); + + return res.status(200).json(whatsapps); +}; + +export const store = async (req: Request, res: Response): Promise => { + const { + name, + status, + isDefault, + greetingMessage, + complationMessage, + outOfHoursMessage, + queueIds, + token, + //timeSendQueue, + //sendIdQueue, + transferQueueId, + timeToTransfer, + promptId, + maxUseBotQueues, + timeUseBotQueues, + expiresTicket, + expiresInactiveMessage + }: WhatsappData = req.body; + const { companyId } = req.user; + + const { whatsapp, oldDefaultWhatsapp } = await CreateWhatsAppService({ + name, + status, + isDefault, + greetingMessage, + complationMessage, + outOfHoursMessage, + queueIds, + companyId, + token, + //timeSendQueue, + //sendIdQueue, + transferQueueId, + timeToTransfer, + promptId, + maxUseBotQueues, + timeUseBotQueues, + expiresTicket, + expiresInactiveMessage + }); + + StartWhatsAppSession(whatsapp, companyId); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-whatsapp`, { + action: "update", + whatsapp + }); + + if (oldDefaultWhatsapp) { + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-whatsapp`, { + action: "update", + whatsapp: oldDefaultWhatsapp + }); + } + + return res.status(200).json(whatsapp); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { whatsappId } = req.params; + const { companyId } = req.user; + const { session } = req.query; + + const whatsapp = await ShowWhatsAppService(whatsappId, companyId, session); + + return res.status(200).json(whatsapp); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + const { whatsappId } = req.params; + const whatsappData = req.body; + const { companyId } = req.user; + + const { whatsapp, oldDefaultWhatsapp } = await UpdateWhatsAppService({ + whatsappData, + whatsappId, + companyId + }); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-whatsapp`, { + action: "update", + whatsapp + }); + + if (oldDefaultWhatsapp) { + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-whatsapp`, { + action: "update", + whatsapp: oldDefaultWhatsapp + }); + } + + return res.status(200).json(whatsapp); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { whatsappId } = req.params; + const { companyId } = req.user; + + await ShowWhatsAppService(whatsappId, companyId); + + await DeleteWhatsAppService(whatsappId); + removeWbot(+whatsappId); + + const io = getIO(); + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-whatsapp`, { + action: "delete", + whatsappId: +whatsappId + }); + + return res.status(200).json({ message: "Whatsapp deleted." }); +}; diff --git a/backend/src/controllers/WhatsAppSessionController.ts b/backend/src/controllers/WhatsAppSessionController.ts new file mode 100644 index 0000000..dffcd4a --- /dev/null +++ b/backend/src/controllers/WhatsAppSessionController.ts @@ -0,0 +1,46 @@ +import { Request, Response } from "express"; +import { getWbot } from "../libs/wbot"; +import ShowWhatsAppService from "../services/WhatsappService/ShowWhatsAppService"; +import { StartWhatsAppSession } from "../services/WbotServices/StartWhatsAppSession"; +import UpdateWhatsAppService from "../services/WhatsappService/UpdateWhatsAppService"; + +const store = async (req: Request, res: Response): Promise => { + const { whatsappId } = req.params; + const { companyId } = req.user; + + const whatsapp = await ShowWhatsAppService(whatsappId, companyId); + await StartWhatsAppSession(whatsapp, companyId); + + return res.status(200).json({ message: "Starting session." }); +}; + +const update = async (req: Request, res: Response): Promise => { + const { whatsappId } = req.params; + const { companyId } = req.user; + + const { whatsapp } = await UpdateWhatsAppService({ + whatsappId, + companyId, + whatsappData: { session: "" } + }); + + await StartWhatsAppSession(whatsapp, companyId); + + return res.status(200).json({ message: "Starting session." }); +}; + +const remove = async (req: Request, res: Response): Promise => { + const { whatsappId } = req.params; + const { companyId } = req.user; + const whatsapp = await ShowWhatsAppService(whatsappId, companyId); + + if (whatsapp.session) { + await whatsapp.update({ status: "DISCONNECTED", session: "" }); + const wbot = getWbot(whatsapp.id); + await wbot.logout(); + } + + return res.status(200).json({ message: "Session disconnected." }); +}; + +export default { store, remove, update }; diff --git a/backend/src/database/index.ts b/backend/src/database/index.ts new file mode 100644 index 0000000..d9b871d --- /dev/null +++ b/backend/src/database/index.ts @@ -0,0 +1,90 @@ +import { Sequelize } from "sequelize-typescript"; +import User from "../models/User"; +import Setting from "../models/Setting"; +import Contact from "../models/Contact"; +import Ticket from "../models/Ticket"; +import Whatsapp from "../models/Whatsapp"; +import ContactCustomField from "../models/ContactCustomField"; +import Message from "../models/Message"; +import Queue from "../models/Queue"; +import WhatsappQueue from "../models/WhatsappQueue"; +import UserQueue from "../models/UserQueue"; +import Company from "../models/Company"; +import Plan from "../models/Plan"; +import TicketNote from "../models/TicketNote"; +import QuickMessage from "../models/QuickMessage"; +import Help from "../models/Help"; +import TicketTraking from "../models/TicketTraking"; +import UserRating from "../models/UserRating"; +import QueueOption from "../models/QueueOption"; +import Schedule from "../models/Schedule"; +import Tag from "../models/Tag"; +import TicketTag from "../models/TicketTag"; +import ContactList from "../models/ContactList"; +import ContactListItem from "../models/ContactListItem"; +import Campaign from "../models/Campaign"; +import CampaignSetting from "../models/CampaignSetting"; +import Baileys from "../models/Baileys"; +import CampaignShipping from "../models/CampaignShipping"; +import Announcement from "../models/Announcement"; +import Chat from "../models/Chat"; +import ChatUser from "../models/ChatUser"; +import ChatMessage from "../models/ChatMessage"; +import Invoices from "../models/Invoices"; +import Subscriptions from "../models/Subscriptions"; +import BaileysChats from "../models/BaileysChats"; +import Files from "../models/Files"; +import FilesOptions from "../models/FilesOptions"; +import Prompt from "../models/Prompt"; +import QueueIntegrations from "../models/QueueIntegrations"; + +// eslint-disable-next-line +const dbConfig = require("../config/database"); +// import dbConfig from "../config/database"; + +const sequelize = new Sequelize(dbConfig); + +const models = [ + Company, + User, + Contact, + Ticket, + Message, + Whatsapp, + ContactCustomField, + Setting, + Queue, + WhatsappQueue, + UserQueue, + Plan, + TicketNote, + QuickMessage, + Help, + TicketTraking, + UserRating, + QueueOption, + Schedule, + Tag, + TicketTag, + ContactList, + ContactListItem, + Campaign, + CampaignSetting, + Baileys, + CampaignShipping, + Announcement, + Chat, + ChatUser, + ChatMessage, + Invoices, + Subscriptions, + BaileysChats, + Files, + FilesOptions, + Prompt, + QueueIntegrations, +]; + +sequelize.addModels(models); + +export default sequelize; diff --git a/backend/src/database/migrations/20200717133431-add-uuid-ossp.ts b/backend/src/database/migrations/20200717133431-add-uuid-ossp.ts new file mode 100644 index 0000000..671b11e --- /dev/null +++ b/backend/src/database/migrations/20200717133431-add-uuid-ossp.ts @@ -0,0 +1,10 @@ +import { QueryInterface, DataTypes, Sequelize } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.sequelize.query('CREATE EXTENSION IF NOT EXISTS "uuid-ossp"'), + ]); + }, + +}; diff --git a/backend/src/database/migrations/20200717133438-create-users.ts b/backend/src/database/migrations/20200717133438-create-users.ts new file mode 100644 index 0000000..17e9ee9 --- /dev/null +++ b/backend/src/database/migrations/20200717133438-create-users.ts @@ -0,0 +1,39 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("Users", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + name: { + type: DataTypes.STRING, + allowNull: false + }, + email: { + type: DataTypes.STRING, + allowNull: false, + unique: true + }, + passwordHash: { + type: DataTypes.STRING, + allowNull: false + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("Users"); + } +}; diff --git a/backend/src/database/migrations/20200717144403-create-contacts.ts b/backend/src/database/migrations/20200717144403-create-contacts.ts new file mode 100644 index 0000000..f3fa92a --- /dev/null +++ b/backend/src/database/migrations/20200717144403-create-contacts.ts @@ -0,0 +1,37 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("Contacts", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + name: { + type: DataTypes.STRING, + allowNull: false + }, + number: { + type: DataTypes.STRING, + allowNull: false + }, + profilePicUrl: { + type: DataTypes.STRING + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("Contacts"); + } +}; diff --git a/backend/src/database/migrations/20200717145643-create-tickets.ts b/backend/src/database/migrations/20200717145643-create-tickets.ts new file mode 100644 index 0000000..d5016ee --- /dev/null +++ b/backend/src/database/migrations/20200717145643-create-tickets.ts @@ -0,0 +1,46 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("Tickets", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + status: { + type: DataTypes.STRING, + defaultValue: "pending", + allowNull: false + }, + lastMessage: { + type: DataTypes.STRING + }, + contactId: { + type: DataTypes.INTEGER, + references: { model: "Contacts", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE" + }, + userId: { + type: DataTypes.INTEGER, + references: { model: "Users", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL" + }, + createdAt: { + type: DataTypes.DATE(6), + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE(6), + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("Tickets"); + } +}; diff --git a/backend/src/database/migrations/20200717151645-create-messages.ts b/backend/src/database/migrations/20200717151645-create-messages.ts new file mode 100644 index 0000000..052dfc1 --- /dev/null +++ b/backend/src/database/migrations/20200717151645-create-messages.ts @@ -0,0 +1,58 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("Messages", { + id: { + type: DataTypes.STRING, + primaryKey: true, + allowNull: false + }, + body: { + type: DataTypes.TEXT, + allowNull: false + }, + ack: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 0 + }, + read: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false + }, + mediaType: { + type: DataTypes.STRING + }, + mediaUrl: { + type: DataTypes.STRING + }, + userId: { + type: DataTypes.INTEGER, + references: { model: "Users", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL" + }, + ticketId: { + type: DataTypes.INTEGER, + references: { model: "Tickets", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: false + }, + createdAt: { + type: DataTypes.DATE(6), + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE(6), + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("Messages"); + } +}; diff --git a/backend/src/database/migrations/20200717170223-create-whatsapps.ts b/backend/src/database/migrations/20200717170223-create-whatsapps.ts new file mode 100644 index 0000000..0686bc1 --- /dev/null +++ b/backend/src/database/migrations/20200717170223-create-whatsapps.ts @@ -0,0 +1,41 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("Whatsapps", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + session: { + type: DataTypes.TEXT + }, + qrcode: { + type: DataTypes.TEXT + }, + status: { + type: DataTypes.STRING + }, + battery: { + type: DataTypes.STRING + }, + plugged: { + type: DataTypes.BOOLEAN + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("Whatsapps"); + } +}; diff --git a/backend/src/database/migrations/20200723200315-create-contacts-custom-fields.ts b/backend/src/database/migrations/20200723200315-create-contacts-custom-fields.ts new file mode 100644 index 0000000..c6cc7f7 --- /dev/null +++ b/backend/src/database/migrations/20200723200315-create-contacts-custom-fields.ts @@ -0,0 +1,41 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("ContactCustomFields", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + name: { + type: DataTypes.STRING, + allowNull: false + }, + value: { + type: DataTypes.STRING, + allowNull: false + }, + contactId: { + type: DataTypes.INTEGER, + references: { model: "Contacts", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: false + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("ContactCustomFields"); + } +}; diff --git a/backend/src/database/migrations/20200723202116-add-email-field-to-contacts.ts b/backend/src/database/migrations/20200723202116-add-email-field-to-contacts.ts new file mode 100644 index 0000000..cbf086d --- /dev/null +++ b/backend/src/database/migrations/20200723202116-add-email-field-to-contacts.ts @@ -0,0 +1,15 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Contacts", "email", { + type: DataTypes.STRING, + allowNull: false, + defaultValue: "" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Contacts", "email"); + } +}; diff --git a/backend/src/database/migrations/20200730153237-remove-user-association-from-messages.ts b/backend/src/database/migrations/20200730153237-remove-user-association-from-messages.ts new file mode 100644 index 0000000..765619f --- /dev/null +++ b/backend/src/database/migrations/20200730153237-remove-user-association-from-messages.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Messages", "userId"); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Messages", "userId", { + type: DataTypes.INTEGER, + references: { model: "Users", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL" + }); + } +}; diff --git a/backend/src/database/migrations/20200730153545-add-fromMe-to-messages.ts b/backend/src/database/migrations/20200730153545-add-fromMe-to-messages.ts new file mode 100644 index 0000000..4bdcebe --- /dev/null +++ b/backend/src/database/migrations/20200730153545-add-fromMe-to-messages.ts @@ -0,0 +1,15 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Messages", "fromMe", { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Messages", "fromMe"); + } +}; diff --git a/backend/src/database/migrations/20200813114236-change-ticket-lastMessage-column-type.ts b/backend/src/database/migrations/20200813114236-change-ticket-lastMessage-column-type.ts new file mode 100644 index 0000000..e4248e8 --- /dev/null +++ b/backend/src/database/migrations/20200813114236-change-ticket-lastMessage-column-type.ts @@ -0,0 +1,15 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.changeColumn("Tickets", "lastMessage", { + type: DataTypes.TEXT + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.changeColumn("Tickets", "lastMessage", { + type: DataTypes.STRING + }); + } +}; diff --git a/backend/src/database/migrations/20200901235509-add-profile-column-to-users.ts b/backend/src/database/migrations/20200901235509-add-profile-column-to-users.ts new file mode 100644 index 0000000..b1d866d --- /dev/null +++ b/backend/src/database/migrations/20200901235509-add-profile-column-to-users.ts @@ -0,0 +1,15 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Users", "profile", { + type: DataTypes.STRING, + allowNull: false, + defaultValue: "admin" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Users", "profile"); + } +}; diff --git a/backend/src/database/migrations/20200903215941-create-settings.ts b/backend/src/database/migrations/20200903215941-create-settings.ts new file mode 100644 index 0000000..b8724fc --- /dev/null +++ b/backend/src/database/migrations/20200903215941-create-settings.ts @@ -0,0 +1,29 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("Settings", { + key: { + type: DataTypes.STRING, + primaryKey: true, + allowNull: false + }, + value: { + type: DataTypes.TEXT, + allowNull: false + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("Settings"); + } +}; diff --git a/backend/src/database/migrations/20200904220257-add-name-to-whatsapp.ts b/backend/src/database/migrations/20200904220257-add-name-to-whatsapp.ts new file mode 100644 index 0000000..3d15507 --- /dev/null +++ b/backend/src/database/migrations/20200904220257-add-name-to-whatsapp.ts @@ -0,0 +1,15 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Whatsapps", "name", { + type: DataTypes.STRING, + allowNull: false, + unique: true + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Whatsapps", "name"); + } +}; diff --git a/backend/src/database/migrations/20200906122228-add-name-default-field-to-whatsapp.ts b/backend/src/database/migrations/20200906122228-add-name-default-field-to-whatsapp.ts new file mode 100644 index 0000000..7ec4a50 --- /dev/null +++ b/backend/src/database/migrations/20200906122228-add-name-default-field-to-whatsapp.ts @@ -0,0 +1,15 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Whatsapps", "default", { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Whatsapps", "default"); + } +}; diff --git a/backend/src/database/migrations/20200906155658-add-whatsapp-field-to-tickets.ts b/backend/src/database/migrations/20200906155658-add-whatsapp-field-to-tickets.ts new file mode 100644 index 0000000..5ed102d --- /dev/null +++ b/backend/src/database/migrations/20200906155658-add-whatsapp-field-to-tickets.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Tickets", "whatsappId", { + type: DataTypes.INTEGER, + references: { model: "Whatsapps", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Tickets", "whatsappId"); + } +}; diff --git a/backend/src/database/migrations/20200919124112-update-default-column-name-on-whatsappp.ts b/backend/src/database/migrations/20200919124112-update-default-column-name-on-whatsappp.ts new file mode 100644 index 0000000..4821129 --- /dev/null +++ b/backend/src/database/migrations/20200919124112-update-default-column-name-on-whatsappp.ts @@ -0,0 +1,11 @@ +import { QueryInterface } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.renameColumn("Whatsapps", "default", "isDefault"); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.renameColumn("Whatsapps", "isDefault", "default"); + } +}; diff --git a/backend/src/database/migrations/20200927220708-add-isDeleted-column-to-messages.ts b/backend/src/database/migrations/20200927220708-add-isDeleted-column-to-messages.ts new file mode 100644 index 0000000..a3ffa86 --- /dev/null +++ b/backend/src/database/migrations/20200927220708-add-isDeleted-column-to-messages.ts @@ -0,0 +1,15 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Messages", "isDeleted", { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Messages", "isDeleted"); + } +}; diff --git a/backend/src/database/migrations/20200929145451-add-user-tokenVersion-column.ts b/backend/src/database/migrations/20200929145451-add-user-tokenVersion-column.ts new file mode 100644 index 0000000..ceb5c21 --- /dev/null +++ b/backend/src/database/migrations/20200929145451-add-user-tokenVersion-column.ts @@ -0,0 +1,15 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Users", "tokenVersion", { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 0 + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Users", "tokenVersion"); + } +}; diff --git a/backend/src/database/migrations/20200930162323-add-isGroup-column-to-tickets.ts b/backend/src/database/migrations/20200930162323-add-isGroup-column-to-tickets.ts new file mode 100644 index 0000000..3e7ba47 --- /dev/null +++ b/backend/src/database/migrations/20200930162323-add-isGroup-column-to-tickets.ts @@ -0,0 +1,15 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Tickets", "isGroup", { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Tickets", "isGroup"); + } +}; diff --git a/backend/src/database/migrations/20200930194808-add-isGroup-column-to-contacts.ts b/backend/src/database/migrations/20200930194808-add-isGroup-column-to-contacts.ts new file mode 100644 index 0000000..d2037ec --- /dev/null +++ b/backend/src/database/migrations/20200930194808-add-isGroup-column-to-contacts.ts @@ -0,0 +1,15 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Contacts", "isGroup", { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Contacts", "isGroup"); + } +}; diff --git a/backend/src/database/migrations/20201004150008-add-contactId-column-to-messages.ts b/backend/src/database/migrations/20201004150008-add-contactId-column-to-messages.ts new file mode 100644 index 0000000..4b8f111 --- /dev/null +++ b/backend/src/database/migrations/20201004150008-add-contactId-column-to-messages.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Messages", "contactId", { + type: DataTypes.INTEGER, + references: { model: "Contacts", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Messages", "contactId"); + } +}; diff --git a/backend/src/database/migrations/20201004155719-add-vcardContactId-column-to-messages.ts b/backend/src/database/migrations/20201004155719-add-vcardContactId-column-to-messages.ts new file mode 100644 index 0000000..d897363 --- /dev/null +++ b/backend/src/database/migrations/20201004155719-add-vcardContactId-column-to-messages.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Messages", "vcardContactId", { + type: DataTypes.INTEGER, + references: { model: "Contacts", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Messages", "vcardContactId"); + } +}; diff --git a/backend/src/database/migrations/20201004955719-remove-vcardContactId-column-to-messages.ts b/backend/src/database/migrations/20201004955719-remove-vcardContactId-column-to-messages.ts new file mode 100644 index 0000000..dac0046 --- /dev/null +++ b/backend/src/database/migrations/20201004955719-remove-vcardContactId-column-to-messages.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Messages", "vcardContactId"); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Messages", "vcardContactId", { + type: DataTypes.INTEGER, + references: { model: "Contacts", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE" + }); + } +}; diff --git a/backend/src/database/migrations/20201026215410-add-retries-to-whatsapps.ts b/backend/src/database/migrations/20201026215410-add-retries-to-whatsapps.ts new file mode 100644 index 0000000..57b1450 --- /dev/null +++ b/backend/src/database/migrations/20201026215410-add-retries-to-whatsapps.ts @@ -0,0 +1,15 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Whatsapps", "retries", { + type: DataTypes.INTEGER, + defaultValue: 0, + allowNull: false + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Whatsapps", "retries"); + } +}; diff --git a/backend/src/database/migrations/20201028124427-add-quoted-msg-to-messages.ts b/backend/src/database/migrations/20201028124427-add-quoted-msg-to-messages.ts new file mode 100644 index 0000000..8bfd56f --- /dev/null +++ b/backend/src/database/migrations/20201028124427-add-quoted-msg-to-messages.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Messages", "quotedMsgId", { + type: DataTypes.STRING, + references: { model: "Messages", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Messages", "quotedMsgId"); + } +}; diff --git a/backend/src/database/migrations/20210108001431-add-unreadMessages-to-tickets.ts b/backend/src/database/migrations/20210108001431-add-unreadMessages-to-tickets.ts new file mode 100644 index 0000000..ca5b47f --- /dev/null +++ b/backend/src/database/migrations/20210108001431-add-unreadMessages-to-tickets.ts @@ -0,0 +1,13 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Tickets", "unreadMessages", { + type: DataTypes.INTEGER + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Tickets", "unreadMessages"); + } +}; diff --git a/backend/src/database/migrations/20210108164404-create-queues.ts b/backend/src/database/migrations/20210108164404-create-queues.ts new file mode 100644 index 0000000..4a404d6 --- /dev/null +++ b/backend/src/database/migrations/20210108164404-create-queues.ts @@ -0,0 +1,39 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("Queues", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + name: { + type: DataTypes.STRING, + allowNull: false, + unique: true + }, + color: { + type: DataTypes.STRING, + allowNull: false, + unique: true + }, + greetingMessage: { + type: DataTypes.TEXT + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("Queues"); + } +}; diff --git a/backend/src/database/migrations/20210108164504-add-queueId-to-tickets.ts b/backend/src/database/migrations/20210108164504-add-queueId-to-tickets.ts new file mode 100644 index 0000000..6122b32 --- /dev/null +++ b/backend/src/database/migrations/20210108164504-add-queueId-to-tickets.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Tickets", "queueId", { + type: DataTypes.INTEGER, + references: { model: "Queues", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Tickets", "queueId"); + } +}; diff --git a/backend/src/database/migrations/20210108174594-associate-whatsapp-queue.ts b/backend/src/database/migrations/20210108174594-associate-whatsapp-queue.ts new file mode 100644 index 0000000..0e08f71 --- /dev/null +++ b/backend/src/database/migrations/20210108174594-associate-whatsapp-queue.ts @@ -0,0 +1,28 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("WhatsappQueues", { + whatsappId: { + type: DataTypes.INTEGER, + primaryKey: true + }, + queueId: { + type: DataTypes.INTEGER, + primaryKey: true + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("WhatsappQueues"); + } +}; diff --git a/backend/src/database/migrations/20210108204708-associate-users-queue.ts b/backend/src/database/migrations/20210108204708-associate-users-queue.ts new file mode 100644 index 0000000..d92496a --- /dev/null +++ b/backend/src/database/migrations/20210108204708-associate-users-queue.ts @@ -0,0 +1,28 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("UserQueues", { + userId: { + type: DataTypes.INTEGER, + primaryKey: true + }, + queueId: { + type: DataTypes.INTEGER, + primaryKey: true + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("UserQueues"); + } +}; diff --git a/backend/src/database/migrations/20210109192513-add-greetingMessage-to-whatsapp.ts b/backend/src/database/migrations/20210109192513-add-greetingMessage-to-whatsapp.ts new file mode 100644 index 0000000..6d3c3be --- /dev/null +++ b/backend/src/database/migrations/20210109192513-add-greetingMessage-to-whatsapp.ts @@ -0,0 +1,13 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Whatsapps", "greetingMessage", { + type: DataTypes.TEXT + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Whatsapps", "greetingMessage"); + } +}; diff --git a/backend/src/database/migrations/20210109192514-create-companies-table.ts b/backend/src/database/migrations/20210109192514-create-companies-table.ts new file mode 100644 index 0000000..773c786 --- /dev/null +++ b/backend/src/database/migrations/20210109192514-create-companies-table.ts @@ -0,0 +1,39 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("Companies", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + name: { + type: DataTypes.STRING, + allowNull: false, + unique: true + }, + phone: { + type: DataTypes.STRING, + allowNull: true + }, + email: { + type: DataTypes.STRING, + allowNull: true + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("Companies"); + } +}; diff --git a/backend/src/database/migrations/20210109192515-add-column-companyId-to-Settings-table.ts b/backend/src/database/migrations/20210109192515-add-column-companyId-to-Settings-table.ts new file mode 100644 index 0000000..7ae9017 --- /dev/null +++ b/backend/src/database/migrations/20210109192515-add-column-companyId-to-Settings-table.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Settings", "companyId", { + type: DataTypes.INTEGER, + references: { model: "Companies", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Settings", "companyId"); + } +}; diff --git a/backend/src/database/migrations/20210109192516-add-column-companyId-to-Users-table.ts b/backend/src/database/migrations/20210109192516-add-column-companyId-to-Users-table.ts new file mode 100644 index 0000000..885dc8a --- /dev/null +++ b/backend/src/database/migrations/20210109192516-add-column-companyId-to-Users-table.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Users", "companyId", { + type: DataTypes.INTEGER, + references: { model: "Companies", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Users", "companyId"); + } +}; diff --git a/backend/src/database/migrations/20210109192517-add-column-companyId-to-Contacts-table.ts b/backend/src/database/migrations/20210109192517-add-column-companyId-to-Contacts-table.ts new file mode 100644 index 0000000..d348602 --- /dev/null +++ b/backend/src/database/migrations/20210109192517-add-column-companyId-to-Contacts-table.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Contacts", "companyId", { + type: DataTypes.INTEGER, + references: { model: "Companies", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Contacts", "companyId"); + } +}; diff --git a/backend/src/database/migrations/20210109192518-add-column-companyId-to-Messages-table.ts b/backend/src/database/migrations/20210109192518-add-column-companyId-to-Messages-table.ts new file mode 100644 index 0000000..fb1d711 --- /dev/null +++ b/backend/src/database/migrations/20210109192518-add-column-companyId-to-Messages-table.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Messages", "companyId", { + type: DataTypes.INTEGER, + references: { model: "Companies", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Messages", "companyId"); + } +}; diff --git a/backend/src/database/migrations/20210109192519-add-column-companyId-to-Queues-table.ts b/backend/src/database/migrations/20210109192519-add-column-companyId-to-Queues-table.ts new file mode 100644 index 0000000..02dee46 --- /dev/null +++ b/backend/src/database/migrations/20210109192519-add-column-companyId-to-Queues-table.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Queues", "companyId", { + type: DataTypes.INTEGER, + references: { model: "Companies", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Queues", "companyId"); + } +}; diff --git a/backend/src/database/migrations/20210109192520-add-column-companyId-to-Whatsapps-table.ts b/backend/src/database/migrations/20210109192520-add-column-companyId-to-Whatsapps-table.ts new file mode 100644 index 0000000..8628328 --- /dev/null +++ b/backend/src/database/migrations/20210109192520-add-column-companyId-to-Whatsapps-table.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Whatsapps", "companyId", { + type: DataTypes.INTEGER, + references: { model: "Companies", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Whatsapps", "companyId"); + } +}; diff --git a/backend/src/database/migrations/20210109192521-add-column-companyId-to-Tickets-table.ts b/backend/src/database/migrations/20210109192521-add-column-companyId-to-Tickets-table.ts new file mode 100644 index 0000000..d7ac711 --- /dev/null +++ b/backend/src/database/migrations/20210109192521-add-column-companyId-to-Tickets-table.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Tickets", "companyId", { + type: DataTypes.INTEGER, + references: { model: "Companies", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Tickets", "companyId"); + } +}; diff --git a/backend/src/database/migrations/20210109192522-create-plans-table.ts b/backend/src/database/migrations/20210109192522-create-plans-table.ts new file mode 100644 index 0000000..96c3e5f --- /dev/null +++ b/backend/src/database/migrations/20210109192522-create-plans-table.ts @@ -0,0 +1,47 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("Plans", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + name: { + type: DataTypes.STRING, + allowNull: false, + unique: true + }, + users: { + type: DataTypes.INTEGER, + defaultValue: 0 + }, + connections: { + type: DataTypes.INTEGER, + defaultValue: 0 + }, + queues: { + type: DataTypes.INTEGER, + defaultValue: 0 + }, + value: { + type: DataTypes.FLOAT, + defaultValue: 0 + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("Plans"); + } +}; diff --git a/backend/src/database/migrations/20210109192523-add-column-planId-to-Companies.ts b/backend/src/database/migrations/20210109192523-add-column-planId-to-Companies.ts new file mode 100644 index 0000000..020ffe8 --- /dev/null +++ b/backend/src/database/migrations/20210109192523-add-column-planId-to-Companies.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Companies", "planId", { + type: DataTypes.INTEGER, + references: { model: "Plans", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Companies", "planId"); + } +}; diff --git a/backend/src/database/migrations/20210109192523-add-column-status-and-schedules-to-Companies.ts b/backend/src/database/migrations/20210109192523-add-column-status-and-schedules-to-Companies.ts new file mode 100644 index 0000000..c9bbe71 --- /dev/null +++ b/backend/src/database/migrations/20210109192523-add-column-status-and-schedules-to-Companies.ts @@ -0,0 +1,23 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.addColumn("Companies", "status", { + type: DataTypes.BOOLEAN, + defaultValue: true + }), + queryInterface.addColumn("Companies", "schedules", { + type: DataTypes.JSONB, + defaultValue: [] + }) + ]); + }, + + down: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.removeColumn("Companies", "schedules"), + queryInterface.removeColumn("Companies", "status") + ]); + } +}; diff --git a/backend/src/database/migrations/20210109192523-create-ticket-notes.ts b/backend/src/database/migrations/20210109192523-create-ticket-notes.ts new file mode 100644 index 0000000..2163d5e --- /dev/null +++ b/backend/src/database/migrations/20210109192523-create-ticket-notes.ts @@ -0,0 +1,49 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("TicketNotes", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + note: { + type: DataTypes.STRING, + allowNull: false + }, + userId: { + type: DataTypes.INTEGER, + references: { model: "Users", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL" + }, + contactId: { + type: DataTypes.INTEGER, + references: { model: "Contacts", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: false + }, + ticketId: { + type: DataTypes.INTEGER, + references: { model: "Tickets", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL" + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("Plans"); + } +}; diff --git a/backend/src/database/migrations/20210109192524-create-quick-messages.ts b/backend/src/database/migrations/20210109192524-create-quick-messages.ts new file mode 100644 index 0000000..c390b6d --- /dev/null +++ b/backend/src/database/migrations/20210109192524-create-quick-messages.ts @@ -0,0 +1,40 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("QuickMessages", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + shortcode: { + type: DataTypes.STRING, + allowNull: false + }, + message: { + type: DataTypes.STRING, + allowNull: false + }, + companyId: { + type: DataTypes.INTEGER, + references: { model: "Companies", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE" + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("QuickMessages"); + } +}; diff --git a/backend/src/database/migrations/20210109192525-add-column-complationMessage-to-whatsapp.ts b/backend/src/database/migrations/20210109192525-add-column-complationMessage-to-whatsapp.ts new file mode 100644 index 0000000..a3bfb4f --- /dev/null +++ b/backend/src/database/migrations/20210109192525-add-column-complationMessage-to-whatsapp.ts @@ -0,0 +1,13 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Whatsapps", "complationMessage", { + type: DataTypes.TEXT + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Whatsapps", "complationMessage"); + } +}; diff --git a/backend/src/database/migrations/20210109192526-add-column-outOfHoursMessage-to-whatsapp .ts b/backend/src/database/migrations/20210109192526-add-column-outOfHoursMessage-to-whatsapp .ts new file mode 100644 index 0000000..c9f4589 --- /dev/null +++ b/backend/src/database/migrations/20210109192526-add-column-outOfHoursMessage-to-whatsapp .ts @@ -0,0 +1,13 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Whatsapps", "outOfHoursMessage", { + type: DataTypes.TEXT + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Whatsapps", "outOfHoursMessage"); + } +}; diff --git a/backend/src/database/migrations/20210109192527-add-column-super-to-Users-table.ts b/backend/src/database/migrations/20210109192527-add-column-super-to-Users-table.ts new file mode 100644 index 0000000..5a5a3b3 --- /dev/null +++ b/backend/src/database/migrations/20210109192527-add-column-super-to-Users-table.ts @@ -0,0 +1,14 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Users", "super", { + type: DataTypes.BOOLEAN, + defaultValue: false + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Users", "super"); + } +}; diff --git a/backend/src/database/migrations/20210109192528-change-column-message-to-quick-messages-table.ts b/backend/src/database/migrations/20210109192528-change-column-message-to-quick-messages-table.ts new file mode 100644 index 0000000..852cc57 --- /dev/null +++ b/backend/src/database/migrations/20210109192528-change-column-message-to-quick-messages-table.ts @@ -0,0 +1,14 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.changeColumn("QuickMessages", "message", { + type: DataTypes.TEXT + }); + }, + down: (queryInterface: QueryInterface) => { + return queryInterface.changeColumn("QuickMessages", "message", { + type: DataTypes.STRING + }); + } +}; diff --git a/backend/src/database/migrations/20210109192529-create-helps.ts b/backend/src/database/migrations/20210109192529-create-helps.ts new file mode 100644 index 0000000..ebec49b --- /dev/null +++ b/backend/src/database/migrations/20210109192529-create-helps.ts @@ -0,0 +1,42 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("Helps", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + title: { + type: DataTypes.STRING, + allowNull: false + }, + description: { + type: DataTypes.TEXT, + allowNull: true + }, + video: { + type: DataTypes.STRING, + allowNull: true + }, + link: { + type: DataTypes.TEXT, + allowNull: true + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("Helps"); + } +}; diff --git a/backend/src/database/migrations/20210109192530-add-unique-constraint-to-Contacts-table.ts b/backend/src/database/migrations/20210109192530-add-unique-constraint-to-Contacts-table.ts new file mode 100644 index 0000000..32c9fcf --- /dev/null +++ b/backend/src/database/migrations/20210109192530-add-unique-constraint-to-Contacts-table.ts @@ -0,0 +1,17 @@ +import { QueryInterface } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addConstraint("Contacts", ["number", "companyId"], { + type: "unique", + name: "number_companyid_unique" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeConstraint( + "Contacts", + "number_companyid_unique" + ); + } +}; diff --git a/backend/src/database/migrations/20210109192531-create-TicketTracking-table.ts b/backend/src/database/migrations/20210109192531-create-TicketTracking-table.ts new file mode 100644 index 0000000..e0f12c1 --- /dev/null +++ b/backend/src/database/migrations/20210109192531-create-TicketTracking-table.ts @@ -0,0 +1,60 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("TicketTraking", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + ticketId: { + type: DataTypes.INTEGER, + references: { model: "Tickets", key: "id" }, + onDelete: "SET NULL" + }, + companyId: { + type: DataTypes.INTEGER, + references: { model: "Companies", key: "id" }, + onDelete: "SET NULL" + }, + whatsappId: { + type: DataTypes.INTEGER, + references: { model: "Whatsapps", key: "id" }, + onDelete: "SET NULL", + allowNull: true + }, + userId: { + type: DataTypes.INTEGER, + references: { model: "Users", key: "id" }, + onDelete: "SET NULL", + allowNull: true + }, + createdAt: { + type: DataTypes.DATE, + allowNull: true + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: true + }, + queuedAt: { + type: DataTypes.DATE, + allowNull: true + }, + startedAt: { + type: DataTypes.DATE, + allowNull: true + }, + finishedAt: { + type: DataTypes.DATE, + allowNull: true + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("TicketTraking"); + } +}; diff --git a/backend/src/database/migrations/20210109192532-add-column-online-to-Users-table.ts b/backend/src/database/migrations/20210109192532-add-column-online-to-Users-table.ts new file mode 100644 index 0000000..c7aafca --- /dev/null +++ b/backend/src/database/migrations/20210109192532-add-column-online-to-Users-table.ts @@ -0,0 +1,14 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Users", "online", { + type: DataTypes.BOOLEAN, + defaultValue: false + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Users", "online"); + } +}; diff --git a/backend/src/database/migrations/20210109192533-create-UserRatings-table.ts b/backend/src/database/migrations/20210109192533-create-UserRatings-table.ts new file mode 100644 index 0000000..91cd5f2 --- /dev/null +++ b/backend/src/database/migrations/20210109192533-create-UserRatings-table.ts @@ -0,0 +1,46 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("UserRatings", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + ticketId: { + type: DataTypes.INTEGER, + references: { model: "Tickets", key: "id" }, + onDelete: "SET NULL" + }, + companyId: { + type: DataTypes.INTEGER, + references: { model: "Companies", key: "id" }, + onDelete: "SET NULL" + }, + userId: { + type: DataTypes.INTEGER, + references: { model: "Users", key: "id" }, + onDelete: "SET NULL", + allowNull: true + }, + rate: { + type: DataTypes.INTEGER, + defaultValue: 0 + }, + createdAt: { + type: DataTypes.DATE, + allowNull: true + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: true + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("UserRatings"); + } +}; diff --git a/backend/src/database/migrations/20210109192534-add-rated-to-TicketTraking.ts b/backend/src/database/migrations/20210109192534-add-rated-to-TicketTraking.ts new file mode 100644 index 0000000..bc007b1 --- /dev/null +++ b/backend/src/database/migrations/20210109192534-add-rated-to-TicketTraking.ts @@ -0,0 +1,24 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.addColumn("TicketTraking", "ratingAt", { + type: DataTypes.DATE, + allowNull: true, + defaultValue: null + }), + queryInterface.addColumn("TicketTraking", "rated", { + type: DataTypes.BOOLEAN, + defaultValue: false + }) + ]); + }, + + down: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.removeColumn("TicketTraking", "ratingAt"), + queryInterface.removeColumn("TicketTraking", "rated") + ]); + } +}; diff --git a/backend/src/database/migrations/20210109192535-add-column-ratingMessage-to-whatsapp.ts b/backend/src/database/migrations/20210109192535-add-column-ratingMessage-to-whatsapp.ts new file mode 100644 index 0000000..7cfbb4a --- /dev/null +++ b/backend/src/database/migrations/20210109192535-add-column-ratingMessage-to-whatsapp.ts @@ -0,0 +1,13 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Whatsapps", "ratingMessage", { + type: DataTypes.TEXT + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Whatsapps", "ratingMessage"); + } +}; diff --git a/backend/src/database/migrations/20210109192536-add-unique-constraint-to-Tickets-table.ts b/backend/src/database/migrations/20210109192536-add-unique-constraint-to-Tickets-table.ts new file mode 100644 index 0000000..217426b --- /dev/null +++ b/backend/src/database/migrations/20210109192536-add-unique-constraint-to-Tickets-table.ts @@ -0,0 +1,17 @@ +import { QueryInterface } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addConstraint("Tickets", ["contactId", "companyId"], { + type: "unique", + name: "contactid_companyid_unique" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeConstraint( + "Tickets", + "contactid_companyid_unique" + ); + } +}; diff --git a/backend/src/database/migrations/20210818102606-add-uuid-to-tickets.ts b/backend/src/database/migrations/20210818102606-add-uuid-to-tickets.ts new file mode 100644 index 0000000..90669b9 --- /dev/null +++ b/backend/src/database/migrations/20210818102606-add-uuid-to-tickets.ts @@ -0,0 +1,17 @@ +import { QueryInterface, DataTypes, Sequelize } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.addColumn("Tickets", "uuid", { + type: DataTypes.UUID, + allowNull: true, + defaultValue: Sequelize.literal('uuid_generate_v4()') + }) + ]); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Tickets", "uuid"); + } +}; diff --git a/backend/src/database/migrations/20210818102607-remove-unique-indexes-to-Queues-table.ts b/backend/src/database/migrations/20210818102607-remove-unique-indexes-to-Queues-table.ts new file mode 100644 index 0000000..c6087c8 --- /dev/null +++ b/backend/src/database/migrations/20210818102607-remove-unique-indexes-to-Queues-table.ts @@ -0,0 +1,25 @@ +import { QueryInterface } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.removeConstraint("Queues", "Queues_color_key"), + queryInterface.removeConstraint("Queues", "Queues_name_key"), + queryInterface.removeIndex("Queues", "Queues_color_key"), + queryInterface.removeIndex("Queues", "Queues_name_key"), + ]); + }, + + down: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.addConstraint("Queues", ["color"], { + name: "Queues_color_key", + type: 'unique' + }), + queryInterface.addConstraint("Queues", ["name"], { + name: "Queues_name_key", + type: 'unique' + }), + ]); + } +}; diff --git a/backend/src/database/migrations/20210818102608-add-unique-indexes-to-Queues-table.ts b/backend/src/database/migrations/20210818102608-add-unique-indexes-to-Queues-table.ts new file mode 100644 index 0000000..9a68704 --- /dev/null +++ b/backend/src/database/migrations/20210818102608-add-unique-indexes-to-Queues-table.ts @@ -0,0 +1,23 @@ +import { QueryInterface } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.addConstraint("Queues", ["color", "companyId"], { + name: "Queues_color_key", + type: 'unique' + }), + queryInterface.addConstraint("Queues", ["name", "companyId"], { + name: "Queues_name_key", + type: 'unique' + }), + ]); + }, + + down: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.removeConstraint("Queues", "Queues_color_key"), + queryInterface.removeConstraint("Queues", "Queues_name_key"), + ]); + } +}; diff --git a/backend/src/database/migrations/20210818102609-add-token-to-Whatsapps.ts b/backend/src/database/migrations/20210818102609-add-token-to-Whatsapps.ts new file mode 100644 index 0000000..b17c96f --- /dev/null +++ b/backend/src/database/migrations/20210818102609-add-token-to-Whatsapps.ts @@ -0,0 +1,14 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Whatsapps", "token", { + type: DataTypes.TEXT, + allowNull: true + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Whatsapps", "token"); + } +}; diff --git a/backend/src/database/migrations/20211205164404-create-queue-options.ts b/backend/src/database/migrations/20211205164404-create-queue-options.ts new file mode 100644 index 0000000..2009ca9 --- /dev/null +++ b/backend/src/database/migrations/20211205164404-create-queue-options.ts @@ -0,0 +1,51 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("QueueOptions", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + title: { + type: DataTypes.STRING, + allowNull: false, + }, + message: { + type: DataTypes.TEXT, + allowNull: true, + }, + option: { + type: DataTypes.TEXT, + allowNull: true, + }, + queueId: { + type: DataTypes.INTEGER, + references: { model: "Queues", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE" + }, + parentId: { + type: DataTypes.INTEGER, + references: { model: "QueueOptions", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: true + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("QueueOptions"); + } +}; diff --git a/backend/src/database/migrations/20211212125704-add-chatbot-to-tickets.ts b/backend/src/database/migrations/20211212125704-add-chatbot-to-tickets.ts new file mode 100644 index 0000000..a1cdc94 --- /dev/null +++ b/backend/src/database/migrations/20211212125704-add-chatbot-to-tickets.ts @@ -0,0 +1,24 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.addColumn("Tickets", "chatbot", { + type: DataTypes.BOOLEAN, + allowNull: true, + defaultValue: false + }), + queryInterface.addColumn("Tickets", "queueOptionId", { + type: DataTypes.INTEGER, + references: { model: "QueueOptions", key: "id" }, + onUpdate: "SET null", + onDelete: "SET null", + allowNull: true + }) + ]); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Tickets", "chatbot"); + } +}; diff --git a/backend/src/database/migrations/20211227010200-create-schedules.ts b/backend/src/database/migrations/20211227010200-create-schedules.ts new file mode 100644 index 0000000..9ae2731 --- /dev/null +++ b/backend/src/database/migrations/20211227010200-create-schedules.ts @@ -0,0 +1,66 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("Schedules", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + body: { + type: DataTypes.TEXT, + allowNull: false + }, + sendAt: { + type: DataTypes.DATE, + allowNull: true + }, + sentAt: { + type: DataTypes.DATE, + allowNull: true + }, + contactId: { + type: DataTypes.INTEGER, + references: { model: "Contacts", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: true + }, + ticketId: { + type: DataTypes.INTEGER, + references: { model: "Tickets", key: "id" }, + onUpdate: "SET NULL", + onDelete: "SET NULL", + allowNull: true + }, + userId: { + type: DataTypes.INTEGER, + references: { model: "Users", key: "id" }, + onUpdate: "SET NULL", + onDelete: "SET NULL", + allowNull: true + }, + companyId: { + type: DataTypes.INTEGER, + references: { model: "Companies", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: true + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("Schedules"); + } +}; diff --git a/backend/src/database/migrations/20220115114088-add-column-userId-to-QuickMessages-table.ts b/backend/src/database/migrations/20220115114088-add-column-userId-to-QuickMessages-table.ts new file mode 100644 index 0000000..22f33ed --- /dev/null +++ b/backend/src/database/migrations/20220115114088-add-column-userId-to-QuickMessages-table.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("QuickMessages", "userId", { + type: DataTypes.INTEGER, + references: { model: "Users", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("QuickMessages", "userId"); + } +}; diff --git a/backend/src/database/migrations/20220117130000-create-tags.ts b/backend/src/database/migrations/20220117130000-create-tags.ts new file mode 100644 index 0000000..37870ff --- /dev/null +++ b/backend/src/database/migrations/20220117130000-create-tags.ts @@ -0,0 +1,41 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("Tags", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + name: { + type: DataTypes.STRING, + allowNull: false + }, + color: { + type: DataTypes.STRING, + allowNull: true + }, + companyId: { + type: DataTypes.INTEGER, + references: { model: "Companies", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: false + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("Tags"); + } +}; diff --git a/backend/src/database/migrations/20220117134400-associate-tickets-tags.ts b/backend/src/database/migrations/20220117134400-associate-tickets-tags.ts new file mode 100644 index 0000000..6df85cb --- /dev/null +++ b/backend/src/database/migrations/20220117134400-associate-tickets-tags.ts @@ -0,0 +1,34 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("TicketTags", { + ticketId: { + type: DataTypes.INTEGER, + references: { model: "Tickets", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: false + }, + tagId: { + type: DataTypes.INTEGER, + references: { model: "Tags", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: false + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("TicketTags"); + } +}; diff --git a/backend/src/database/migrations/20220122160900-add-status-to-schedules.ts b/backend/src/database/migrations/20220122160900-add-status-to-schedules.ts new file mode 100644 index 0000000..15639d7 --- /dev/null +++ b/backend/src/database/migrations/20220122160900-add-status-to-schedules.ts @@ -0,0 +1,14 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Schedules", "status", { + type: DataTypes.STRING, + allowNull: true + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Schedules", "status"); + } +}; diff --git a/backend/src/database/migrations/20220220014719-add-farewellMessage-to-whatsapp.ts b/backend/src/database/migrations/20220220014719-add-farewellMessage-to-whatsapp.ts new file mode 100644 index 0000000..40120bf --- /dev/null +++ b/backend/src/database/migrations/20220220014719-add-farewellMessage-to-whatsapp.ts @@ -0,0 +1,13 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Whatsapps", "farewellMessage", { + type: DataTypes.TEXT + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Whatsapps", "farewellMessage"); + } +}; diff --git a/backend/src/database/migrations/20220221014717-add-provider-whatsapp.ts b/backend/src/database/migrations/20220221014717-add-provider-whatsapp.ts new file mode 100644 index 0000000..263a1a3 --- /dev/null +++ b/backend/src/database/migrations/20220221014717-add-provider-whatsapp.ts @@ -0,0 +1,14 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Whatsapps", "provider", { + type: DataTypes.TEXT, + defaultValue: "stable" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Whatsapps", "provider"); + } +}; diff --git a/backend/src/database/migrations/20220221014718-add-remoteJid-messages.ts b/backend/src/database/migrations/20220221014718-add-remoteJid-messages.ts new file mode 100644 index 0000000..fd911ad --- /dev/null +++ b/backend/src/database/migrations/20220221014718-add-remoteJid-messages.ts @@ -0,0 +1,13 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Messages", "remoteJid", { + type: DataTypes.TEXT + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Messages", "remoteJid"); + } +}; diff --git a/backend/src/database/migrations/20220221014719-add-jsonMessage-messages.ts b/backend/src/database/migrations/20220221014719-add-jsonMessage-messages.ts new file mode 100644 index 0000000..72f23a6 --- /dev/null +++ b/backend/src/database/migrations/20220221014719-add-jsonMessage-messages.ts @@ -0,0 +1,13 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Messages", "dataJson", { + type: DataTypes.TEXT + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Messages", "dataJson"); + } +}; diff --git a/backend/src/database/migrations/20220221014720-add-participant-messages.ts b/backend/src/database/migrations/20220221014720-add-participant-messages.ts new file mode 100644 index 0000000..65fe5a1 --- /dev/null +++ b/backend/src/database/migrations/20220221014720-add-participant-messages.ts @@ -0,0 +1,13 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Messages", "participant", { + type: DataTypes.TEXT + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Messages", "participant"); + } +}; diff --git a/backend/src/database/migrations/20220221014721-create-baileys.ts b/backend/src/database/migrations/20220221014721-create-baileys.ts new file mode 100644 index 0000000..4544385 --- /dev/null +++ b/backend/src/database/migrations/20220221014721-create-baileys.ts @@ -0,0 +1,38 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("Baileys", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + whatsappId: { + type: DataTypes.INTEGER, + primaryKey: true + }, + contacts: { + type: DataTypes.TEXT, + allowNull: true + }, + chats: { + type: DataTypes.TEXT, + allowNull: true + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("Baileys"); + } +}; diff --git a/backend/src/database/migrations/20220315110000-create-ContactLists-table.ts b/backend/src/database/migrations/20220315110000-create-ContactLists-table.ts new file mode 100644 index 0000000..7406ef2 --- /dev/null +++ b/backend/src/database/migrations/20220315110000-create-ContactLists-table.ts @@ -0,0 +1,37 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("ContactLists", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + name: { + type: DataTypes.STRING, + allowNull: false + }, + companyId: { + type: DataTypes.INTEGER, + references: { model: "Companies", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: true + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("ContactLists"); + } +}; diff --git a/backend/src/database/migrations/20220315110001-create-ContactListItems-table.ts b/backend/src/database/migrations/20220315110001-create-ContactListItems-table.ts new file mode 100644 index 0000000..009f7a9 --- /dev/null +++ b/backend/src/database/migrations/20220315110001-create-ContactListItems-table.ts @@ -0,0 +1,56 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("ContactListItems", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + name: { + type: DataTypes.STRING, + allowNull: false + }, + number: { + type: DataTypes.STRING, + allowNull: false + }, + email: { + type: DataTypes.STRING, + allowNull: true + }, + contactListId: { + type: DataTypes.INTEGER, + references: { model: "ContactLists", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: false + }, + isWhatsappValid: { + type: DataTypes.BOOLEAN, + defaultValue: false + }, + companyId: { + type: DataTypes.INTEGER, + references: { model: "Companies", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: true + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("ContactListItems"); + } +}; diff --git a/backend/src/database/migrations/20220315110002-create-Campaigns-table.ts b/backend/src/database/migrations/20220315110002-create-Campaigns-table.ts new file mode 100644 index 0000000..2d1f568 --- /dev/null +++ b/backend/src/database/migrations/20220315110002-create-Campaigns-table.ts @@ -0,0 +1,126 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("Campaigns", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + name: { + type: DataTypes.STRING, + allowNull: false + }, + message1: { + type: DataTypes.TEXT, + allowNull: true, + defaultValue: "" + }, + message2: { + type: DataTypes.TEXT, + allowNull: true, + defaultValue: "" + }, + message3: { + type: DataTypes.TEXT, + allowNull: true, + defaultValue: "" + }, + message4: { + type: DataTypes.TEXT, + allowNull: true, + defaultValue: "" + }, + message5: { + type: DataTypes.TEXT, + allowNull: true, + defaultValue: "" + }, + confirmationMessage1: { + type: DataTypes.TEXT, + allowNull: true, + defaultValue: "" + }, + confirmationMessage2: { + type: DataTypes.TEXT, + allowNull: true, + defaultValue: "" + }, + confirmationMessage3: { + type: DataTypes.TEXT, + allowNull: true, + defaultValue: "" + }, + confirmationMessage4: { + type: DataTypes.TEXT, + allowNull: true, + defaultValue: "" + }, + confirmationMessage5: { + type: DataTypes.TEXT, + allowNull: true, + defaultValue: "" + }, + status: { + type: DataTypes.STRING, + allowNull: true + }, + confirmation: { + type: DataTypes.BOOLEAN, + allowNull: true, + defaultValue: false + }, + mediaPath: { + type: DataTypes.TEXT, + allowNull: true + }, + mediaName: { + type: DataTypes.TEXT, + allowNull: true + }, + companyId: { + type: DataTypes.INTEGER, + references: { model: "Companies", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: false + }, + contactListId: { + type: DataTypes.INTEGER, + references: { model: "ContactLists", key: "id" }, + onUpdate: "SET NULL", + onDelete: "SET NULL", + allowNull: true + }, + whatsappId: { + type: DataTypes.INTEGER, + references: { model: "Whatsapps", key: "id" }, + onUpdate: "SET NULL", + onDelete: "SET NULL", + allowNull: true + }, + scheduledAt: { + type: DataTypes.DATE, + allowNull: true + }, + completedAt: { + type: DataTypes.DATE, + allowNull: true + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("Campaigns"); + } +}; diff --git a/backend/src/database/migrations/20220315110004-create-CampaignSettings-table.ts b/backend/src/database/migrations/20220315110004-create-CampaignSettings-table.ts new file mode 100644 index 0000000..4d796a9 --- /dev/null +++ b/backend/src/database/migrations/20220315110004-create-CampaignSettings-table.ts @@ -0,0 +1,41 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("CampaignSettings", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + key: { + type: DataTypes.STRING, + allowNull: false + }, + value: { + type: DataTypes.TEXT, + allowNull: true + }, + companyId: { + type: DataTypes.INTEGER, + references: { model: "Companies", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: true + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("CampaignSettings"); + } +}; diff --git a/backend/src/database/migrations/20220315110005-remove-constraint-to-Settings.ts b/backend/src/database/migrations/20220315110005-remove-constraint-to-Settings.ts new file mode 100644 index 0000000..f794a99 --- /dev/null +++ b/backend/src/database/migrations/20220315110005-remove-constraint-to-Settings.ts @@ -0,0 +1,27 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.sequelize.query('DELETE FROM "Settings"'), + queryInterface.removeConstraint("Settings", "Settings_pkey"), + queryInterface.addColumn("Settings", "id", { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }) + ]); + }, + + down: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.sequelize.query('DELETE FROM "Settings"'), + queryInterface.removeColumn("Settings", "id"), + queryInterface.addConstraint("Settings", ["key"], { + type: "primary key", + name: "Settings_pkey" + }) + ]); + } +}; diff --git a/backend/src/database/migrations/20220321130000-create-CampaignShipping.ts b/backend/src/database/migrations/20220321130000-create-CampaignShipping.ts new file mode 100644 index 0000000..6570474 --- /dev/null +++ b/backend/src/database/migrations/20220321130000-create-CampaignShipping.ts @@ -0,0 +1,72 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("CampaignShipping", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + jobId: { + type: DataTypes.STRING, + allowNull: true + }, + number: { + type: DataTypes.STRING, + allowNull: false + }, + message: { + type: DataTypes.TEXT, + allowNull: false + }, + confirmationMessage: { + type: DataTypes.TEXT, + allowNull: true + }, + confirmation: { + type: DataTypes.BOOLEAN, + allowNull: true + }, + contactId: { + type: DataTypes.INTEGER, + references: { model: "ContactListItems", key: "id" }, + onUpdate: "SET NULL", + onDelete: "SET NULL", + allowNull: true + }, + campaignId: { + type: DataTypes.INTEGER, + references: { model: "Campaigns", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: false + }, + confirmationRequestedAt: { + type: DataTypes.DATE, + allowNull: true + }, + confirmedAt: { + type: DataTypes.DATE, + allowNull: true + }, + deliveredAt: { + type: DataTypes.DATE, + allowNull: true + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("CampaignShipping"); + } +}; diff --git a/backend/src/database/migrations/20220404000000-add-column-queueId-to-Messages-table.ts b/backend/src/database/migrations/20220404000000-add-column-queueId-to-Messages-table.ts new file mode 100644 index 0000000..fc663a1 --- /dev/null +++ b/backend/src/database/migrations/20220404000000-add-column-queueId-to-Messages-table.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Messages", "queueId", { + type: DataTypes.INTEGER, + references: { model: "Queues", key: "id" }, + onUpdate: "SET NULL", + onDelete: "SET NULL" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Messages", "queueId"); + } +}; diff --git a/backend/src/database/migrations/20220406000000-add-column-dueDate-to-Companies.ts b/backend/src/database/migrations/20220406000000-add-column-dueDate-to-Companies.ts new file mode 100644 index 0000000..e5083c7 --- /dev/null +++ b/backend/src/database/migrations/20220406000000-add-column-dueDate-to-Companies.ts @@ -0,0 +1,14 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Companies", "dueDate", { + type: DataTypes.DATE, + allowNull: true + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Companies", "dueDate"); + } +}; diff --git a/backend/src/database/migrations/20220406000001-add-column-recurrence-to-Companies.ts b/backend/src/database/migrations/20220406000001-add-column-recurrence-to-Companies.ts new file mode 100644 index 0000000..09d8760 --- /dev/null +++ b/backend/src/database/migrations/20220406000001-add-column-recurrence-to-Companies.ts @@ -0,0 +1,15 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Companies", "recurrence", { + type: DataTypes.STRING, + allowNull: true, + defaultValue: "" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Companies", "recurrence"); + } +}; diff --git a/backend/src/database/migrations/20220411000000-add-column-startTime-and-endTime-to-Queues.ts b/backend/src/database/migrations/20220411000000-add-column-startTime-and-endTime-to-Queues.ts new file mode 100644 index 0000000..a90dba1 --- /dev/null +++ b/backend/src/database/migrations/20220411000000-add-column-startTime-and-endTime-to-Queues.ts @@ -0,0 +1,28 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.addColumn("Queues", "startTime", { + type: DataTypes.STRING, + defaultValue: null + }), + queryInterface.addColumn("Queues", "endTime", { + type: DataTypes.STRING, + defaultValue: null + }), + queryInterface.addColumn("Queues", "outOfHoursMessage", { + type: DataTypes.TEXT, + defaultValue: null + }) + ]); + }, + + down: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.removeColumn("Queues", "startTime"), + queryInterface.removeColumn("Queues", "endTime"), + queryInterface.removeColumn("Queues", "outOfHoursMessage") + ]); + } +}; diff --git a/backend/src/database/migrations/20220411000001-remove-column-startTime-and-endTime-to-Queues.ts b/backend/src/database/migrations/20220411000001-remove-column-startTime-and-endTime-to-Queues.ts new file mode 100644 index 0000000..7f005b7 --- /dev/null +++ b/backend/src/database/migrations/20220411000001-remove-column-startTime-and-endTime-to-Queues.ts @@ -0,0 +1,28 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.removeColumn("Queues", "startTime"), + queryInterface.removeColumn("Queues", "endTime"), + queryInterface.removeColumn("Queues", "outOfHoursMessage") + ]); + }, + + down: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.addColumn("Queues", "startTime", { + type: DataTypes.STRING, + defaultValue: null + }), + queryInterface.addColumn("Queues", "endTime", { + type: DataTypes.STRING, + defaultValue: null + }), + queryInterface.addColumn("Queues", "outOfHoursMessage", { + type: DataTypes.TEXT, + defaultValue: null + }) + ]); + } +}; diff --git a/backend/src/database/migrations/20220411000002-add-column-schedules-and-outOfHoursMessage-to-Queues.ts b/backend/src/database/migrations/20220411000002-add-column-schedules-and-outOfHoursMessage-to-Queues.ts new file mode 100644 index 0000000..72023d0 --- /dev/null +++ b/backend/src/database/migrations/20220411000002-add-column-schedules-and-outOfHoursMessage-to-Queues.ts @@ -0,0 +1,23 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.addColumn("Queues", "schedules", { + type: DataTypes.JSONB, + defaultValue: [] + }), + queryInterface.addColumn("Queues", "outOfHoursMessage", { + type: DataTypes.TEXT, + allowNull: true + }) + ]); + }, + + down: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.removeColumn("Queues", "schedules"), + queryInterface.removeColumn("Queues", "outOfHoursMessage") + ]); + } +}; diff --git a/backend/src/database/migrations/20220411000003-create-table-Announcements.ts b/backend/src/database/migrations/20220411000003-create-table-Announcements.ts new file mode 100644 index 0000000..9123242 --- /dev/null +++ b/backend/src/database/migrations/20220411000003-create-table-Announcements.ts @@ -0,0 +1,57 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("Announcements", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + priority: { + type: DataTypes.INTEGER, + allowNull: true + }, + title: { + type: DataTypes.STRING, + allowNull: false + }, + text: { + type: DataTypes.TEXT, + allowNull: false + }, + mediaPath: { + type: DataTypes.TEXT, + allowNull: true + }, + mediaName: { + type: DataTypes.TEXT, + allowNull: true + }, + companyId: { + type: DataTypes.INTEGER, + references: { model: "Companies", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: false + }, + status: { + type: DataTypes.BOOLEAN, + allowNull: true + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("Announcements"); + } +}; diff --git a/backend/src/database/migrations/20220425000000-create-table-Chats.ts b/backend/src/database/migrations/20220425000000-create-table-Chats.ts new file mode 100644 index 0000000..5659c5e --- /dev/null +++ b/backend/src/database/migrations/20220425000000-create-table-Chats.ts @@ -0,0 +1,54 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("Chats", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + title: { + type: DataTypes.TEXT, + defaultValue: "", + allowNull: true + }, + uuid: { + type: DataTypes.STRING, + defaultValue: "", + allowNull: true + }, + ownerId: { + type: DataTypes.INTEGER, + references: { model: "Users", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: false + }, + lastMessage: { + type: DataTypes.TEXT, + allowNull: true + }, + companyId: { + type: DataTypes.INTEGER, + references: { model: "Companies", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: false + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("Chats"); + } +}; diff --git a/backend/src/database/migrations/20220425000001-create-table-ChatUsers.ts b/backend/src/database/migrations/20220425000001-create-table-ChatUsers.ts new file mode 100644 index 0000000..67adc5a --- /dev/null +++ b/backend/src/database/migrations/20220425000001-create-table-ChatUsers.ts @@ -0,0 +1,44 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("ChatUsers", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + chatId: { + type: DataTypes.INTEGER, + references: { model: "Chats", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: false + }, + userId: { + type: DataTypes.INTEGER, + references: { model: "Users", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: false + }, + unreads: { + type: DataTypes.INTEGER, + defaultValue: 0 + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("ChatUsers"); + } +}; diff --git a/backend/src/database/migrations/20220425000002-create-table-ChatMessages.ts b/backend/src/database/migrations/20220425000002-create-table-ChatMessages.ts new file mode 100644 index 0000000..1dfbbd3 --- /dev/null +++ b/backend/src/database/migrations/20220425000002-create-table-ChatMessages.ts @@ -0,0 +1,53 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("ChatMessages", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + chatId: { + type: DataTypes.INTEGER, + references: { model: "Chats", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: false + }, + senderId: { + type: DataTypes.INTEGER, + references: { model: "Users", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: false + }, + message: { + type: DataTypes.TEXT, + allowNull: true, + defaultValue: "" + }, + mediaPath: { + type: DataTypes.TEXT, + allowNull: true + }, + mediaName: { + type: DataTypes.TEXT, + allowNull: true + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("ChatMessages"); + } +}; diff --git a/backend/src/database/migrations/20220512000001-create-Indexes.ts b/backend/src/database/migrations/20220512000001-create-Indexes.ts new file mode 100644 index 0000000..ae67b3b --- /dev/null +++ b/backend/src/database/migrations/20220512000001-create-Indexes.ts @@ -0,0 +1,37 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.addIndex("Schedules", ["companyId"], { + name: "idx_sched_company_id" + }), + queryInterface.addIndex("Contacts", ["companyId"], { + name: "idx_cont_company_id" + }), + queryInterface.addIndex("Tags", ["companyId"], { + name: "idx_tg_company_id" + }), + queryInterface.addIndex("Messages", ["companyId", "ticketId"], { + name: "idx_ms_company_id_ticket_id" + }), + queryInterface.addIndex("CampaignShipping", ["campaignId"], { + name: "idx_cpsh_campaign_id" + }), + queryInterface.addIndex("ContactListItems", ["contactListId"], { + name: "idx_ctli_contact_list_id" + }) + ]); + }, + + down: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.removeIndex("Schedules", "idx_sched_company_id"), + queryInterface.removeIndex("Contacts", "idx_cont_company_id"), + queryInterface.removeIndex("Tags", "idx_tg_company_id"), + queryInterface.removeIndex("Messages", "idx_ms_company_id_ticket_id"), + queryInterface.removeIndex("CampaignShipping", "idx_cpsh_campaign_id"), + queryInterface.removeIndex("ContactListItems", "idx_ctli_contact_list_id") + ]); + } +}; diff --git a/backend/src/database/migrations/20220512000002-create-subscriptions.ts b/backend/src/database/migrations/20220512000002-create-subscriptions.ts new file mode 100644 index 0000000..2c25559 --- /dev/null +++ b/backend/src/database/migrations/20220512000002-create-subscriptions.ts @@ -0,0 +1,58 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("Subscriptions", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + isActive: { + type: DataTypes.BOOLEAN, + defaultValue: false + }, + expiresAt: { + type: DataTypes.DATE, + allowNull: false + }, + userPriceCents: { + type: DataTypes.INTEGER + }, + whatsPriceCents: { + type: DataTypes.INTEGER + }, + lastInvoiceUrl: { + type: DataTypes.STRING, + allowNull: true + }, + lastPlanChange: { + type: DataTypes.DATE, + allowNull: true + }, + companyId: { + type: DataTypes.INTEGER, + references: { model: "Companies", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE" + }, + providerSubscriptionId: { + type: DataTypes.STRING, + allowNull: false + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("Subscriptions"); + } +}; diff --git a/backend/src/database/migrations/20220512000003-create-invoices.ts b/backend/src/database/migrations/20220512000003-create-invoices.ts new file mode 100644 index 0000000..108e24f --- /dev/null +++ b/backend/src/database/migrations/20220512000003-create-invoices.ts @@ -0,0 +1,44 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("Invoices", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + detail: { + type: DataTypes.STRING, + }, + status: { + type: DataTypes.STRING, + }, + value: { + type: DataTypes.FLOAT + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + }, + dueDate: { + type: DataTypes.STRING, + }, + companyId: { + type: DataTypes.INTEGER, + references: { model: "Companies", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE" + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("Invoices"); + } +}; diff --git a/backend/src/database/migrations/20220723000001-add-mediaPath-to-quickmessages.ts b/backend/src/database/migrations/20220723000001-add-mediaPath-to-quickmessages.ts new file mode 100644 index 0000000..89dba5f --- /dev/null +++ b/backend/src/database/migrations/20220723000001-add-mediaPath-to-quickmessages.ts @@ -0,0 +1,15 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("QuickMessages", "mediaPath", { + type: DataTypes.STRING, + allowNull: true, + defaultValue: null + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("QuickMessages", "mediaPath"); + } +}; diff --git a/backend/src/database/migrations/20220723000002-add-mediaName-to-quickemessages.ts b/backend/src/database/migrations/20220723000002-add-mediaName-to-quickemessages.ts new file mode 100644 index 0000000..968d98a --- /dev/null +++ b/backend/src/database/migrations/20220723000002-add-mediaName-to-quickemessages.ts @@ -0,0 +1,15 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("QuickMessages", "mediaName", { + type: DataTypes.STRING, + allowNull: true, + defaultValue: null + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("QuickMessages", "mediaName"); + } +}; diff --git a/backend/src/database/migrations/20222016014720-create-baileys-chats.ts b/backend/src/database/migrations/20222016014720-create-baileys-chats.ts new file mode 100644 index 0000000..e11e660 --- /dev/null +++ b/backend/src/database/migrations/20222016014720-create-baileys-chats.ts @@ -0,0 +1,44 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("BaileysChats", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + whatsappId: { + type: DataTypes.INTEGER, + references: { model: "Whatsapps", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE" + }, + jid: { + type: DataTypes.STRING, + allowNull: false + }, + conversationTimestamp: { + type: DataTypes.STRING, + allowNull: false + }, + unreadCount: { + type: DataTypes.INTEGER, + defaultValue: 0 + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("BaileysChats"); + } +}; diff --git a/backend/src/database/migrations/20222016014721-create-baileys-chats Messages.ts b/backend/src/database/migrations/20222016014721-create-baileys-chats Messages.ts new file mode 100644 index 0000000..993f52b --- /dev/null +++ b/backend/src/database/migrations/20222016014721-create-baileys-chats Messages.ts @@ -0,0 +1,42 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("BaileysMessages", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + whatsappId: { + type: DataTypes.INTEGER, + references: { model: "Whatsapps", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE" + }, + baileysChatId: { + type: DataTypes.INTEGER, + references: { model: "BaileysChats", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE" + }, + jsonMessage: { + type: DataTypes.JSON, + allowNull: false + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("BaileysMessages"); + } +}; diff --git a/backend/src/database/migrations/20230106164900-add-useCampaigns-Plans.ts b/backend/src/database/migrations/20230106164900-add-useCampaigns-Plans.ts new file mode 100644 index 0000000..d88e967 --- /dev/null +++ b/backend/src/database/migrations/20230106164900-add-useCampaigns-Plans.ts @@ -0,0 +1,14 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Plans", "useCampaigns", { + type: DataTypes.BOOLEAN, + defaultValue: true + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Plans", "useCampaigns"); + } +}; diff --git a/backend/src/database/migrations/20230106164900-add-useExternalApi-Plans.ts b/backend/src/database/migrations/20230106164900-add-useExternalApi-Plans.ts new file mode 100644 index 0000000..ebdfa22 --- /dev/null +++ b/backend/src/database/migrations/20230106164900-add-useExternalApi-Plans.ts @@ -0,0 +1,14 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Plans", "useExternalApi", { + type: DataTypes.BOOLEAN, + defaultValue: true + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Plans", "useExternalApi"); + } +}; diff --git a/backend/src/database/migrations/20230106164900-add-useInternalChat-Plans.ts b/backend/src/database/migrations/20230106164900-add-useInternalChat-Plans.ts new file mode 100644 index 0000000..950ff20 --- /dev/null +++ b/backend/src/database/migrations/20230106164900-add-useInternalChat-Plans.ts @@ -0,0 +1,14 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Plans", "useInternalChat", { + type: DataTypes.BOOLEAN, + defaultValue: true + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Plans", "useInternalChat"); + } +}; diff --git a/backend/src/database/migrations/20230106164900-add-useSchedules-Plans.ts b/backend/src/database/migrations/20230106164900-add-useSchedules-Plans.ts new file mode 100644 index 0000000..76a3e9e --- /dev/null +++ b/backend/src/database/migrations/20230106164900-add-useSchedules-Plans.ts @@ -0,0 +1,14 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Plans", "useSchedules", { + type: DataTypes.BOOLEAN, + defaultValue: true + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Plans", "useSchedules"); + } +}; diff --git a/backend/src/database/migrations/20230303223001-add-amountUsedBotQueues-to-tickets.ts b/backend/src/database/migrations/20230303223001-add-amountUsedBotQueues-to-tickets.ts new file mode 100644 index 0000000..0fa8ed9 --- /dev/null +++ b/backend/src/database/migrations/20230303223001-add-amountUsedBotQueues-to-tickets.ts @@ -0,0 +1,13 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Tickets", "amountUsedBotQueues", { + type: DataTypes.INTEGER + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Tickets", "amountUsedBotQueues"); + } +}; diff --git a/backend/src/database/migrations/20230417203900-add-allTickets-user.ts b/backend/src/database/migrations/20230417203900-add-allTickets-user.ts new file mode 100644 index 0000000..6275f42 --- /dev/null +++ b/backend/src/database/migrations/20230417203900-add-allTickets-user.ts @@ -0,0 +1,15 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Users", "allTicket", { + type: DataTypes.STRING, + allowNull: false, + defaultValue: "desabled" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Users", "allTicket"); + } +}; diff --git a/backend/src/database/migrations/20230603212335-create-QueueIntegrations.ts b/backend/src/database/migrations/20230603212335-create-QueueIntegrations.ts new file mode 100644 index 0000000..e7fac19 --- /dev/null +++ b/backend/src/database/migrations/20230603212335-create-QueueIntegrations.ts @@ -0,0 +1,48 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("QueueIntegrations", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + type: { + type: DataTypes.STRING, + allowNull: false + }, + name: { + type: DataTypes.STRING, + allowNull: false, + unique: true + }, + projectName: { + type: DataTypes.STRING, + allowNull: false, + unique: true + }, + jsonContent: { + type: DataTypes.TEXT, + allowNull: false, + }, + language: { + type: DataTypes.STRING, + allowNull: false, + }, + createdAt: { + type: DataTypes.DATE, + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE, + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("QueueIntegrations"); + } +}; \ No newline at end of file diff --git a/backend/src/database/migrations/20230603212337-add-urlN8N-QueueIntegrations.ts b/backend/src/database/migrations/20230603212337-add-urlN8N-QueueIntegrations.ts new file mode 100644 index 0000000..1348c62 --- /dev/null +++ b/backend/src/database/migrations/20230603212337-add-urlN8N-QueueIntegrations.ts @@ -0,0 +1,15 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("QueueIntegrations", "urlN8N", { + type: DataTypes.STRING, + allowNull: false, + defaultValue: true + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("QueueIntegrations", "urlN8N"); + } +}; \ No newline at end of file diff --git a/backend/src/database/migrations/20230623095932-add-whatsapp-to-user.ts b/backend/src/database/migrations/20230623095932-add-whatsapp-to-user.ts new file mode 100644 index 0000000..b09393b --- /dev/null +++ b/backend/src/database/migrations/20230623095932-add-whatsapp-to-user.ts @@ -0,0 +1,17 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Users", "whatsappId", { + type: DataTypes.INTEGER, + references: { model: "Whatsapps", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL", + allowNull: true + },); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Users", "whatsappId"); + } +}; \ No newline at end of file diff --git a/backend/src/database/migrations/20230623133903-add-chatbotAt-ticket-tracking.ts b/backend/src/database/migrations/20230623133903-add-chatbotAt-ticket-tracking.ts new file mode 100644 index 0000000..cbedb37 --- /dev/null +++ b/backend/src/database/migrations/20230623133903-add-chatbotAt-ticket-tracking.ts @@ -0,0 +1,14 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("TicketTraking", "chatbotAt", { + type: DataTypes.DATE, + allowNull: true + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("TicketTraking", "chatbotAt"); + } +}; diff --git a/backend/src/database/migrations/20230628134807-add-orderQueue-Queue.ts b/backend/src/database/migrations/20230628134807-add-orderQueue-Queue.ts new file mode 100644 index 0000000..4ab7aad --- /dev/null +++ b/backend/src/database/migrations/20230628134807-add-orderQueue-Queue.ts @@ -0,0 +1,13 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Queues", "orderQueue", { + type: DataTypes.INTEGER + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Queues", "orderQueue"); + } +}; \ No newline at end of file diff --git a/backend/src/database/migrations/20230711094417-add-column-companyId-to-QueueIntegrations-table.ts b/backend/src/database/migrations/20230711094417-add-column-companyId-to-QueueIntegrations-table.ts new file mode 100644 index 0000000..94a1855 --- /dev/null +++ b/backend/src/database/migrations/20230711094417-add-column-companyId-to-QueueIntegrations-table.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("QueueIntegrations", "companyId", { + type: DataTypes.INTEGER, + references: { model: "Companies", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("QueueIntegrations", "companyId"); + } +}; diff --git a/backend/src/database/migrations/20230711111701-add-sendIdQueue-to-whatsapp.ts b/backend/src/database/migrations/20230711111701-add-sendIdQueue-to-whatsapp.ts new file mode 100644 index 0000000..1d3174f --- /dev/null +++ b/backend/src/database/migrations/20230711111701-add-sendIdQueue-to-whatsapp.ts @@ -0,0 +1,13 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Whatsapps", "sendIdQueue", { + type: DataTypes.INTEGER + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Whatsapps", "sendIdQueue"); + } +}; diff --git a/backend/src/database/migrations/20230714113901-create-Files.ts b/backend/src/database/migrations/20230714113901-create-Files.ts new file mode 100644 index 0000000..51afb6e --- /dev/null +++ b/backend/src/database/migrations/20230714113901-create-Files.ts @@ -0,0 +1,41 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("Files", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + companyId: { + type: DataTypes.INTEGER, + references: { model: "Companies", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: false + }, + name: { + type: DataTypes.STRING, + allowNull: false + }, + message: { + type: DataTypes.TEXT, + allowNull: false + }, + createdAt: { + type: DataTypes.DATE(6), + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE(6), + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("Files"); + } +}; diff --git a/backend/src/database/migrations/20230714113902-create-fileOptions.ts b/backend/src/database/migrations/20230714113902-create-fileOptions.ts new file mode 100644 index 0000000..84c66c1 --- /dev/null +++ b/backend/src/database/migrations/20230714113902-create-fileOptions.ts @@ -0,0 +1,41 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.createTable("FilesOptions", { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + name: { + type: DataTypes.STRING, + allowNull: false + }, + path: { + type: DataTypes.STRING, + allowNull: false + }, + fileId: { + type: DataTypes.INTEGER, + references: { model: "Files", key: "id" }, + onUpdate: "CASCADE", + onDelete: "CASCADE", + allowNull: false + }, + createdAt: { + type: DataTypes.DATE(6), + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE(6), + allowNull: false + } + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("FilesOptions"); + } +}; diff --git a/backend/src/database/migrations/20230723301001-add-kanban-to-Tags.ts b/backend/src/database/migrations/20230723301001-add-kanban-to-Tags.ts new file mode 100644 index 0000000..421c588 --- /dev/null +++ b/backend/src/database/migrations/20230723301001-add-kanban-to-Tags.ts @@ -0,0 +1,14 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Tags", "kanban", { + type: DataTypes.INTEGER, + allowNull: true + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Tags", "kanban"); + } +}; diff --git a/backend/src/database/migrations/20230801081907-add-collumns-Ticket.ts b/backend/src/database/migrations/20230801081907-add-collumns-Ticket.ts new file mode 100644 index 0000000..89f56f6 --- /dev/null +++ b/backend/src/database/migrations/20230801081907-add-collumns-Ticket.ts @@ -0,0 +1,17 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Tickets", "fromMe", { + type: DataTypes.BOOLEAN, + defaultValue: false, + allowNull: false + }); + }, + + down: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.removeColumn("Tickets", "fromMe"), + ]) + } +}; \ No newline at end of file diff --git a/backend/src/database/migrations/20230813114236-change-ticket-lastMessage-column-type.ts b/backend/src/database/migrations/20230813114236-change-ticket-lastMessage-column-type.ts new file mode 100644 index 0000000..f85f44b --- /dev/null +++ b/backend/src/database/migrations/20230813114236-change-ticket-lastMessage-column-type.ts @@ -0,0 +1,17 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.changeColumn("Tickets", "lastMessage", { + defaultValue: "", + type: DataTypes.TEXT + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.changeColumn("Tickets", "lastMessage", { + defaultValue: "", + type: DataTypes.TEXT + }); + } +}; \ No newline at end of file diff --git a/backend/src/database/migrations/20230824082607-add-mediaType-FilesOptions.ts b/backend/src/database/migrations/20230824082607-add-mediaType-FilesOptions.ts new file mode 100644 index 0000000..b2a385e --- /dev/null +++ b/backend/src/database/migrations/20230824082607-add-mediaType-FilesOptions.ts @@ -0,0 +1,15 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("FilesOptions", "mediaType", { + type: DataTypes.STRING, + defaultValue: "", + allowNull: true + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("FilesOptions", "mediaType"); + } +}; \ No newline at end of file diff --git a/backend/src/database/migrations/20230828143411-add-Integrations-to-tickets.ts b/backend/src/database/migrations/20230828143411-add-Integrations-to-tickets.ts new file mode 100644 index 0000000..41da7b7 --- /dev/null +++ b/backend/src/database/migrations/20230828143411-add-Integrations-to-tickets.ts @@ -0,0 +1,26 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Tickets", "useIntegration", { + type: DataTypes.BOOLEAN, + defaultValue: false, + allowNull: true, + + }), + queryInterface.addColumn("Tickets", "integrationId", { + references: { model: "QueueIntegrations", key: "id" }, + type: DataTypes.INTEGER, + defaultValue: null, + allowNull: true, + + }); + }, + + down: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.removeColumn("Tickets", "useIntegration"), + queryInterface.removeColumn("Tickets", "integrationId"), + ]) + } +}; diff --git a/backend/src/database/migrations/20230828144000-create-prompts.ts b/backend/src/database/migrations/20230828144000-create-prompts.ts new file mode 100644 index 0000000..aad49fb --- /dev/null +++ b/backend/src/database/migrations/20230828144000-create-prompts.ts @@ -0,0 +1,103 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +interface ExistingTables { + [key: string]: any; +} + +module.exports = { + up: async (queryInterface: QueryInterface) => { + const table = "Prompts"; + + const existingTables: ExistingTables = await queryInterface.showAllTables(); + + if (!existingTables.includes(table)) { + return queryInterface.createTable(table, { + id: { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + allowNull: false + }, + name: { + type: DataTypes.TEXT, + allowNull: false + }, + apiKey: { + type: DataTypes.TEXT, + allowNull: false + }, + prompt: { + type: DataTypes.TEXT, + allowNull: false + }, + maxTokens: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 100 + }, + maxMessages: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 10 + }, + temperature: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 1 + }, + promptTokens: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 0 + }, + completionTokens: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 0 + }, + totalTokens: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 0 + }, + voice: { + type: DataTypes.TEXT, + allowNull: true + }, + voiceKey: { + type: DataTypes.TEXT, + allowNull: true + }, + voiceRegion: { + type: DataTypes.TEXT, + allowNull: true + }, + queueId: { + type: DataTypes.INTEGER, + references: { model: "Queues", key: "id" }, + onUpdate: "NO ACTION", + onDelete: "NO ACTION", + allowNull: false + }, + companyId: { + type: DataTypes.INTEGER, + references: { model: "Companies", key: "id" }, + onUpdate: "NO ACTION", + onDelete: "NO ACTION", + allowNull: false + }, + createdAt: { + type: DataTypes.DATE(6), + allowNull: false + }, + updatedAt: { + type: DataTypes.DATE(6), + allowNull: false + } + }); + } + }, + down: (queryInterface: QueryInterface) => { + return queryInterface.dropTable("Prompts"); + } +}; diff --git a/backend/src/database/migrations/20230828144100-add-column-promptid-into-whatsapps.ts b/backend/src/database/migrations/20230828144100-add-column-promptid-into-whatsapps.ts new file mode 100644 index 0000000..0fcfba1 --- /dev/null +++ b/backend/src/database/migrations/20230828144100-add-column-promptid-into-whatsapps.ts @@ -0,0 +1,26 @@ +import { QueryInterface, DataTypes } from "sequelize"; +interface ExistingColumns { + }; + +module.exports = { + up: async (queryInterface: QueryInterface) => { + const table = "Whatsapps"; + const column = "promptId"; + + const tableInfo: ExistingColumns = await queryInterface.describeTable(table); + if (tableInfo[column]) { + return Promise.resolve(); + } + + return queryInterface.addColumn(table, column, { + type: DataTypes.INTEGER, + references: { model: "Prompts", key: "id" }, + onUpdate: "RESTRICT", + onDelete: "RESTRICT" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Whatsapps", "promptId"); + } +}; diff --git a/backend/src/database/migrations/20230831093000-add-useKanban-Plans.ts b/backend/src/database/migrations/20230831093000-add-useKanban-Plans.ts new file mode 100644 index 0000000..0dece8e --- /dev/null +++ b/backend/src/database/migrations/20230831093000-add-useKanban-Plans.ts @@ -0,0 +1,14 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Plans", "useKanban", { + type: DataTypes.BOOLEAN, + defaultValue: true + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Plans", "useKanban"); + } +}; diff --git a/backend/src/database/migrations/20230922212337-add-integrationId-Queues.ts b/backend/src/database/migrations/20230922212337-add-integrationId-Queues.ts new file mode 100644 index 0000000..7f370ef --- /dev/null +++ b/backend/src/database/migrations/20230922212337-add-integrationId-Queues.ts @@ -0,0 +1,23 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Queues", "integrationId", { + type: DataTypes.INTEGER, + references: { model: "QueueIntegrations", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL" + }), + queryInterface.addColumn("Whatsapps", "integrationId", { + type: DataTypes.INTEGER, + references: { model: "QueueIntegrations", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL" + }) + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Queues", "integrationId"), + queryInterface.removeColumn("Whatsapps", "integrationId"); + } +}; \ No newline at end of file diff --git a/backend/src/database/migrations/20230924212337-add-fileListId-Campaigns.ts b/backend/src/database/migrations/20230924212337-add-fileListId-Campaigns.ts new file mode 100644 index 0000000..ebb213b --- /dev/null +++ b/backend/src/database/migrations/20230924212337-add-fileListId-Campaigns.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Campaigns", "fileListId", { + type: DataTypes.INTEGER, + references: { model: "Files", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL" + }) + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Campaigns", "fileListId") + } +}; \ No newline at end of file diff --git a/backend/src/database/migrations/20231111185822-add_reset_password_column.ts b/backend/src/database/migrations/20231111185822-add_reset_password_column.ts new file mode 100644 index 0000000..8154356 --- /dev/null +++ b/backend/src/database/migrations/20231111185822-add_reset_password_column.ts @@ -0,0 +1 @@ +'use strict';module.exports={up:async(queryInterface,Sequelize)=>{await queryInterface.addColumn('Users','resetPassword',{type:Sequelize.STRING,allowNull:true,});},down:async(queryInterface,Sequelize)=>{await queryInterface.removeColumn('Users','resetPassword');},}; \ No newline at end of file diff --git a/backend/src/database/migrations/20231117000001-add-mediaName-to-schedules.ts b/backend/src/database/migrations/20231117000001-add-mediaName-to-schedules.ts new file mode 100644 index 0000000..c8395a2 --- /dev/null +++ b/backend/src/database/migrations/20231117000001-add-mediaName-to-schedules.ts @@ -0,0 +1,15 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Schedules", "mediaName", { + type: DataTypes.STRING, + allowNull: true, + defaultValue: null + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Schedules", "mediaName"); + } +}; diff --git a/backend/src/database/migrations/20231117000001-add-mediaPath-to-schedules.ts b/backend/src/database/migrations/20231117000001-add-mediaPath-to-schedules.ts new file mode 100644 index 0000000..257b24d --- /dev/null +++ b/backend/src/database/migrations/20231117000001-add-mediaPath-to-schedules.ts @@ -0,0 +1,15 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Schedules", "mediaPath", { + type: DataTypes.STRING, + allowNull: true, + defaultValue: null + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Schedules", "mediaPath"); + } +}; diff --git a/backend/src/database/migrations/20231127113000-add-columns-Plans.ts b/backend/src/database/migrations/20231127113000-add-columns-Plans.ts new file mode 100644 index 0000000..0bd3c98 --- /dev/null +++ b/backend/src/database/migrations/20231127113000-add-columns-Plans.ts @@ -0,0 +1,19 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Plans", "useOpenAi", { + type: DataTypes.BOOLEAN, + defaultValue: true + }), + queryInterface.addColumn("Plans", "useIntegrations", { + type: DataTypes.BOOLEAN, + defaultValue: true + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Plans", "useOpenAi"), + queryInterface.removeColumn("Plans", "useIntegrations"); + } +}; diff --git a/backend/src/database/migrations/20231128123537-add-typebot-QueueIntegrations.ts b/backend/src/database/migrations/20231128123537-add-typebot-QueueIntegrations.ts new file mode 100644 index 0000000..6cee910 --- /dev/null +++ b/backend/src/database/migrations/20231128123537-add-typebot-QueueIntegrations.ts @@ -0,0 +1,33 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("QueueIntegrations", "typebotSlug", { + type: DataTypes.STRING, + allowNull: false, + defaultValue: "" + }), + queryInterface.addColumn("QueueIntegrations", "typebotExpires", { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 0 + }), + queryInterface.addColumn("QueueIntegrations", "typebotKeywordFinish", { + type: DataTypes.STRING, + allowNull: false, + defaultValue: "" + }), + queryInterface.addColumn("QueueIntegrations", "typebotUnknownMessage", { + type: DataTypes.STRING, + allowNull: false, + defaultValue: "" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("QueueIntegrations", "typebotSlug"), + queryInterface.removeColumn("QueueIntegrations", "typebotExpires"), + queryInterface.removeColumn("QueueIntegrations", "typebotKeywordFinish"), + queryInterface.removeColumn("QueueIntegrations", "typebotUnknownMessage"); + } +}; \ No newline at end of file diff --git a/backend/src/database/migrations/20231202143411-add-typebotSessionId-to-tickets.ts b/backend/src/database/migrations/20231202143411-add-typebotSessionId-to-tickets.ts new file mode 100644 index 0000000..9805d93 --- /dev/null +++ b/backend/src/database/migrations/20231202143411-add-typebotSessionId-to-tickets.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Tickets", "typebotSessionId", { + type: DataTypes.STRING, + defaultValue: null, + allowNull: true, + + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Tickets", "typebotSessionId"); + } +}; diff --git a/backend/src/database/migrations/20231207080337-add-typebotDelayMessage-QueueIntegrations.ts b/backend/src/database/migrations/20231207080337-add-typebotDelayMessage-QueueIntegrations.ts new file mode 100644 index 0000000..0985f6c --- /dev/null +++ b/backend/src/database/migrations/20231207080337-add-typebotDelayMessage-QueueIntegrations.ts @@ -0,0 +1,15 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("QueueIntegrations", "typebotDelayMessage", { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 1000 + }) + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("QueueIntegrations", "typebotDelayMessage") + } +}; \ No newline at end of file diff --git a/backend/src/database/migrations/20231207085011-add-typebotStatus-to-tickets.ts b/backend/src/database/migrations/20231207085011-add-typebotStatus-to-tickets.ts new file mode 100644 index 0000000..5679dfc --- /dev/null +++ b/backend/src/database/migrations/20231207085011-add-typebotStatus-to-tickets.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Tickets", "typebotStatus", { + type: DataTypes.BOOLEAN, + defaultValue: false, + allowNull: false, + + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Tickets", "typebotStatus"); + } +}; diff --git a/backend/src/database/migrations/20231214092337-add-promptId-Queues.ts b/backend/src/database/migrations/20231214092337-add-promptId-Queues.ts new file mode 100644 index 0000000..5fbbaf1 --- /dev/null +++ b/backend/src/database/migrations/20231214092337-add-promptId-Queues.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Queues", "promptId", { + type: DataTypes.INTEGER, + references: { model: "Prompts", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL" + }) + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Queues", "promptId"); + } +}; \ No newline at end of file diff --git a/backend/src/database/migrations/20231214143411-add-columns-to-whatsapps.ts b/backend/src/database/migrations/20231214143411-add-columns-to-whatsapps.ts new file mode 100644 index 0000000..048e490 --- /dev/null +++ b/backend/src/database/migrations/20231214143411-add-columns-to-whatsapps.ts @@ -0,0 +1,30 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Whatsapps", "maxUseBotQueues", { + type: DataTypes.INTEGER, + defaultValue: 3, + allowNull: true + }), + queryInterface.addColumn("Whatsapps", "expiresTicket", { + type: DataTypes.INTEGER, + defaultValue: 0, + allowNull: true + }), + queryInterface.addColumn("Whatsapps", "expiresInactiveMessage", { + type: DataTypes.STRING, + defaultValue: "", + allowNull: true + }), + queryInterface.addColumn("Whatsapps", "timeUseBotQueues", { + type: DataTypes.INTEGER, + defaultValue: 0, + allowNull: true + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Whatsapps", "companyId"); + } +}; \ No newline at end of file diff --git a/backend/src/database/migrations/20231214143411-add-promptId-to-tickets.ts b/backend/src/database/migrations/20231214143411-add-promptId-to-tickets.ts new file mode 100644 index 0000000..e59f30e --- /dev/null +++ b/backend/src/database/migrations/20231214143411-add-promptId-to-tickets.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Tickets", "promptId", { + type: DataTypes.STRING, + defaultValue: null, + allowNull: true, + + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Tickets", "promptId"); + } +}; diff --git a/backend/src/database/migrations/20231218160937-add-columns-QueueIntegrations.ts b/backend/src/database/migrations/20231218160937-add-columns-QueueIntegrations.ts new file mode 100644 index 0000000..cfc6ec4 --- /dev/null +++ b/backend/src/database/migrations/20231218160937-add-columns-QueueIntegrations.ts @@ -0,0 +1,21 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("QueueIntegrations", "typebotKeywordRestart", { + type: DataTypes.STRING, + allowNull: true, + defaultValue: "" + }), + queryInterface.addColumn("QueueIntegrations", "typebotRestartMessage", { + type: DataTypes.STRING, + allowNull: true, + defaultValue: "" + }) + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("QueueIntegrations", "typebotKeywordRestart"), + queryInterface.removeColumn("QueueIntegrations", "typebotRestartMessage") + } +}; \ No newline at end of file diff --git a/backend/src/database/migrations/20231219153800-add-isEdited-column-to-messages.ts b/backend/src/database/migrations/20231219153800-add-isEdited-column-to-messages.ts new file mode 100644 index 0000000..ad53d35 --- /dev/null +++ b/backend/src/database/migrations/20231219153800-add-isEdited-column-to-messages.ts @@ -0,0 +1,15 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Messages", "isEdited", { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Messages", "isEdited"); + } +}; \ No newline at end of file diff --git a/backend/src/database/migrations/20231220192536-add-unique-constraint-to-Tickets-table.ts b/backend/src/database/migrations/20231220192536-add-unique-constraint-to-Tickets-table.ts new file mode 100644 index 0000000..4cebd29 --- /dev/null +++ b/backend/src/database/migrations/20231220192536-add-unique-constraint-to-Tickets-table.ts @@ -0,0 +1,18 @@ +import { QueryInterface } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.removeConstraint("Tickets", "contactid_companyid_unique"), + queryInterface.addConstraint("Tickets", ["contactId", "companyId", "whatsappId"], { + type: "unique", + name: "contactid_companyid_unique" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeConstraint( + "Tickets", + "contactid_companyid_unique" + ); + } +}; diff --git a/backend/src/database/migrations/20231220223517-add-column-whatsappId-to-Contacts.ts b/backend/src/database/migrations/20231220223517-add-column-whatsappId-to-Contacts.ts new file mode 100644 index 0000000..e2154cc --- /dev/null +++ b/backend/src/database/migrations/20231220223517-add-column-whatsappId-to-Contacts.ts @@ -0,0 +1,16 @@ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.addColumn("Contacts", "whatsappId", { + type: DataTypes.INTEGER, + references: { model: "Whatsapps", key: "id" }, + onUpdate: "CASCADE", + onDelete: "SET NULL" + }); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.removeColumn("Contacts", "whatsappId"); + } +}; diff --git a/backend/src/database/migrations/20232016014719-add-transferTime-and-queueIdTransfer.ts b/backend/src/database/migrations/20232016014719-add-transferTime-and-queueIdTransfer.ts new file mode 100644 index 0000000..0504915 --- /dev/null +++ b/backend/src/database/migrations/20232016014719-add-transferTime-and-queueIdTransfer.ts @@ -0,0 +1,27 @@ +import { QueryInterface, DataTypes } from "sequelize"; +// +module.exports = { + + up: (queryInterface: QueryInterface) => { + return Promise.all([ + + queryInterface.addColumn("Whatsapps", "transferQueueId", { + type: DataTypes.INTEGER, + allowNull: true, + }), + + queryInterface.addColumn("Whatsapps", "timeToTransfer", { + type: DataTypes.INTEGER, + allowNull: true, + }) + ]); + }, + + down: (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.removeColumn("Whatsapps", "timeToTransfer"), + queryInterface.removeColumn("Whatsapps", "transferQueueId") + ]); + } + +}; diff --git a/backend/src/database/seeds/20200904070005-create-default-company.ts b/backend/src/database/seeds/20200904070005-create-default-company.ts new file mode 100644 index 0000000..caea0e5 --- /dev/null +++ b/backend/src/database/seeds/20200904070005-create-default-company.ts @@ -0,0 +1,45 @@ +import { QueryInterface } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.sequelize.transaction(t => { + return Promise.all([ + queryInterface.bulkInsert( + "Plans", + [ + { + name: "Plano 1", + users: 10, + connections: 10, + queues: 10, + value: 30, + createdAt: new Date(), + updatedAt: new Date() + } + ], + { transaction: t } + ), + queryInterface.bulkInsert( + "Companies", + [ + { + name: "Empresa 1", + planId: 1, + dueDate: "2093-03-14 04:00:00+01", + createdAt: new Date(), + updatedAt: new Date() + } + ], + { transaction: t } + ) + ]); + }); + }, + + down: async (queryInterface: QueryInterface) => { + return Promise.all([ + queryInterface.bulkDelete("Companies", {}), + queryInterface.bulkDelete("Plans", {}) + ]); + } +}; diff --git a/backend/src/database/seeds/20200904070006-create-default-user.ts b/backend/src/database/seeds/20200904070006-create-default-user.ts new file mode 100644 index 0000000..c670393 --- /dev/null +++ b/backend/src/database/seeds/20200904070006-create-default-user.ts @@ -0,0 +1,32 @@ +import { QueryInterface } from "sequelize"; +import { hash } from "bcryptjs"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.sequelize.transaction(async t => { + const passwordHash = await hash("123456", 8); + return Promise.all([ + queryInterface.bulkInsert( + "Users", + [ + { + name: "Admin", + email: "admin@admin.com", + profile: "admin", + passwordHash, + companyId: 1, + createdAt: new Date(), + updatedAt: new Date(), + super: true + } + ], + { transaction: t } + ) + ]); + }); + }, + + down: async (queryInterface: QueryInterface) => { + return queryInterface.bulkDelete("Users", {}); + } +}; diff --git a/backend/src/database/seeds/20200904070007-create-default-settings.ts b/backend/src/database/seeds/20200904070007-create-default-settings.ts new file mode 100644 index 0000000..742584f --- /dev/null +++ b/backend/src/database/seeds/20200904070007-create-default-settings.ts @@ -0,0 +1,123 @@ +import { QueryInterface } from "sequelize"; +import { hash } from "bcryptjs"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.sequelize.transaction(async t => { + return Promise.all([ + queryInterface.bulkInsert( + "Settings", + [ + { + key: "chatBotType", + value: "text", + companyId: 1, + createdAt: new Date(), + updatedAt: new Date() + }, + { + key: "sendGreetingAccepted", + value: "disabled", + companyId: 1, + createdAt: new Date(), + updatedAt: new Date(), + + }, + { + key: "sendMsgTransfTicket", + value: "disabled", + companyId: 1, + createdAt: new Date(), + updatedAt: new Date(), + + }, + { + key: "sendGreetingMessageOneQueues", + value: "disabled", + companyId: 1, + createdAt: new Date(), + updatedAt: new Date(), + + }, + { + key: "userRating", + value: "disabled", + companyId: 1, + createdAt: new Date(), + updatedAt: new Date() + }, + { + key: "scheduleType", + value: "queue", + companyId: 1, + createdAt: new Date(), + updatedAt: new Date() + }, + { + key: "CheckMsgIsGroup", + value: "enabled", + companyId: 1, + createdAt: new Date(), + updatedAt: new Date() + }, + { + key:"call", + value: "disabled", + companyId: 1, + createdAt: new Date(), + updatedAt: new Date() + }, + { + key: "ipixc", + value: "", + companyId: 1, + createdAt: new Date(), + updatedAt: new Date() + }, + { + key: "tokenixc", + value: "", + companyId: 1, + createdAt: new Date(), + updatedAt: new Date() + }, + { + key: "ipmkauth", + value: "", + companyId: 1, + createdAt: new Date(), + updatedAt: new Date() + }, + { + key: "clientidmkauth", + value: "", + companyId: 1, + createdAt: new Date(), + updatedAt: new Date() + }, + { + key: "clientsecretmkauth", + value: "", + companyId: 1, + createdAt: new Date(), + updatedAt: new Date() + }, + { + key: "asaas", + value: "", + companyId: 1, + createdAt: new Date(), + updatedAt: new Date() + }, + + ], + { transaction: t } + ) + ]); + }); + }, + + down: async (queryInterface: QueryInterface) => { + return queryInterface.bulkDelete("Settings", {}); + } +}; diff --git a/backend/src/database/seeds/20230130004700-create-alltickets-settings.ts b/backend/src/database/seeds/20230130004700-create-alltickets-settings.ts new file mode 100644 index 0000000..ffbbee8 --- /dev/null +++ b/backend/src/database/seeds/20230130004700-create-alltickets-settings.ts @@ -0,0 +1,22 @@ +import { QueryInterface } from "sequelize"; + +module.exports = { + up: (queryInterface: QueryInterface) => { + return queryInterface.bulkInsert( + "Settings", + [ + { + key: "allTicket", + value: "disabled", + createdAt: new Date(), + updatedAt: new Date() + } + ], + {} + ); + }, + + down: (queryInterface: QueryInterface) => { + return queryInterface.bulkDelete("Settings", {}); + } +}; diff --git a/backend/src/errors/AppError.ts b/backend/src/errors/AppError.ts new file mode 100644 index 0000000..a8b1209 --- /dev/null +++ b/backend/src/errors/AppError.ts @@ -0,0 +1,12 @@ +class AppError { + public readonly message: string; + + public readonly statusCode: number; + + constructor(message: string, statusCode = 400) { + this.message = message; + this.statusCode = statusCode; + } +} + +export default AppError; diff --git a/backend/src/errors/toastError.js b/backend/src/errors/toastError.js new file mode 100644 index 0000000..8b1cb9b --- /dev/null +++ b/backend/src/errors/toastError.js @@ -0,0 +1,42 @@ +import { toast } from "react-toastify"; +import { i18n } from "../translate/i18n"; +import { isString } from 'lodash'; + +const toastError = err => { + const errorMsg = err?.response?.data?.message || err?.response?.data?.error; + if (errorMsg) { + if (i18n.exists(`backendErrors.${errorMsg}`)) { + toast.error(i18n.t(`backendErrors.${errorMsg}`), { + toastId: errorMsg, + autoClose: 2000, + hideProgressBar: false, + closeOnClick: true, + pauseOnHover: false, + draggable: true, + progress: undefined, + theme: "light", + }); + return + } else { + toast.error(errorMsg, { + toastId: errorMsg, + autoClose: 2000, + hideProgressBar: false, + closeOnClick: true, + pauseOnHover: false, + draggable: true, + progress: undefined, + theme: "light", + }); + return + } + } if (isString(err)) { + toast.error(err); + return + } else { + toast.error("An error occurred!"); + return + } +}; + +export default toastError; diff --git a/backend/src/helpers/CheckContactOpenTickets.ts b/backend/src/helpers/CheckContactOpenTickets.ts new file mode 100644 index 0000000..960aa9c --- /dev/null +++ b/backend/src/helpers/CheckContactOpenTickets.ts @@ -0,0 +1,31 @@ +import { Op } from "sequelize"; +import AppError from "../errors/AppError"; +import Ticket from "../models/Ticket"; + +const CheckContactOpenTickets = async (contactId: number, whatsappId?: string): Promise => { + let ticket + + if (!whatsappId) { + ticket = await Ticket.findOne({ + where: { + contactId, + status: { [Op.or]: ["open", "pending"] }, + + } + }); + } else { + ticket = await Ticket.findOne({ + where: { + contactId, + status: { [Op.or]: ["open", "pending"] }, + whatsappId + } + }); + } + console.log(ticket) + if (ticket) { + throw new AppError("ERR_OTHER_OPEN_TICKET"); + } +}; + +export default CheckContactOpenTickets; diff --git a/backend/src/helpers/CheckContactSomeTicket.ts b/backend/src/helpers/CheckContactSomeTicket.ts new file mode 100644 index 0000000..11a4042 --- /dev/null +++ b/backend/src/helpers/CheckContactSomeTicket.ts @@ -0,0 +1,18 @@ +import { Op } from "sequelize"; +import AppError from "../errors/AppError"; +import Ticket from "../models/Ticket"; + +const CheckContactSomeTickets = async ( + contactId: number, + companyId: number +): Promise => { + const ticket = await Ticket.findOne({ + where: { contactId, companyId } + }); + + if (ticket) { + throw new AppError("ERR_OTHER_OPEN_TICKET"); + } +}; + +export default CheckContactSomeTickets; diff --git a/backend/src/helpers/CheckSettings.ts b/backend/src/helpers/CheckSettings.ts new file mode 100644 index 0000000..d19122b --- /dev/null +++ b/backend/src/helpers/CheckSettings.ts @@ -0,0 +1,16 @@ +import Setting from "../models/Setting"; +import AppError from "../errors/AppError"; + +const CheckSettings = async (key: string): Promise => { + const setting = await Setting.findOne({ + where: { key } + }); + + if (!setting) { + throw new AppError("ERR_NO_SETTING_FOUND", 404); + } + + return setting.value; +}; + +export default CheckSettings; diff --git a/backend/src/helpers/CreateTokens.ts b/backend/src/helpers/CreateTokens.ts new file mode 100644 index 0000000..3f814c0 --- /dev/null +++ b/backend/src/helpers/CreateTokens.ts @@ -0,0 +1,32 @@ +import { sign } from "jsonwebtoken"; +import authConfig from "../config/auth"; +import User from "../models/User"; + +export const createAccessToken = (user: User): string => { + const { secret, expiresIn } = authConfig; + + return sign( + { + usarname: user.name, + profile: user.profile, + id: user.id, + companyId: user.companyId + }, + secret, + { + expiresIn + } + ); +}; + +export const createRefreshToken = (user: User): string => { + const { refreshSecret, refreshExpiresIn } = authConfig; + + return sign( + { id: user.id, tokenVersion: user.tokenVersion, companyId: user.companyId }, + refreshSecret, + { + expiresIn: refreshExpiresIn + } + ); +}; diff --git a/backend/src/helpers/Debounce.ts b/backend/src/helpers/Debounce.ts new file mode 100644 index 0000000..80665d9 --- /dev/null +++ b/backend/src/helpers/Debounce.ts @@ -0,0 +1,41 @@ +interface Timeout { + id: number; + timeout: NodeJS.Timeout; +} + +const timeouts: Timeout[] = []; + +const findAndClearTimeout = (ticketId: number) => { + if (timeouts.length > 0) { + const timeoutIndex = timeouts.findIndex(timeout => timeout.id === ticketId); + + if (timeoutIndex !== -1) { + clearTimeout(timeouts[timeoutIndex].timeout); + timeouts.splice(timeoutIndex, 1); + } + } +}; + +const debounce = ( + func: { (): Promise; (...args: never[]): void }, + wait: number, + ticketId: number +) => { + return function executedFunction(...args: never[]): void { + const later = () => { + findAndClearTimeout(ticketId); + func(...args); + }; + + findAndClearTimeout(ticketId); + + const newTimeout = { + id: ticketId, + timeout: setTimeout(later, wait) + }; + + timeouts.push(newTimeout); + }; +}; + +export { debounce }; diff --git a/backend/src/helpers/GetDefaultWhatsApp.ts b/backend/src/helpers/GetDefaultWhatsApp.ts new file mode 100644 index 0000000..8370575 --- /dev/null +++ b/backend/src/helpers/GetDefaultWhatsApp.ts @@ -0,0 +1,43 @@ +import AppError from "../errors/AppError"; +import Whatsapp from "../models/Whatsapp"; +import GetDefaultWhatsAppByUser from "./GetDefaultWhatsAppByUser"; + +const GetDefaultWhatsApp = async ( + companyId: number, + userId?: number +): Promise => { + let connection: Whatsapp; + + const defaultWhatsapp = await Whatsapp.findOne({ + where: { isDefault: true, companyId } + }); + + if (defaultWhatsapp?.status === 'CONNECTED') { + connection = defaultWhatsapp; + } else { + const whatsapp = await Whatsapp.findOne({ + where: { status: "CONNECTED", companyId } + }); + connection = whatsapp; + } + + if (userId) { + const whatsappByUser = await GetDefaultWhatsAppByUser(userId); + if (whatsappByUser?.status === 'CONNECTED') { + connection = whatsappByUser; + } else { + const whatsapp = await Whatsapp.findOne({ + where: { status: "CONNECTED", companyId } + }); + connection = whatsapp; + } + } + + if (!connection) { + throw new AppError(`ERR_NO_DEF_WAPP_FOUND in COMPANY ${companyId}`); + } + + return connection; +}; + +export default GetDefaultWhatsApp; \ No newline at end of file diff --git a/backend/src/helpers/GetDefaultWhatsAppByUser.ts b/backend/src/helpers/GetDefaultWhatsAppByUser.ts new file mode 100644 index 0000000..335129a --- /dev/null +++ b/backend/src/helpers/GetDefaultWhatsAppByUser.ts @@ -0,0 +1,18 @@ +import User from "../models/User"; +import Whatsapp from "../models/Whatsapp"; +import { logger } from "../utils/logger"; + +const GetDefaultWhatsAppByUser = async ( + userId: number +): Promise => { + const user = await User.findByPk(userId, {include: ["whatsapp"]}); + if( user === null || !user.whatsapp) { + return null; + } + + logger.info(`Found whatsapp linked to user '${user.name}' is '${user.whatsapp.name}'.`); + + return user.whatsapp; +}; + +export default GetDefaultWhatsAppByUser; diff --git a/backend/src/helpers/GetTicketWbot.ts b/backend/src/helpers/GetTicketWbot.ts new file mode 100644 index 0000000..5debbb6 --- /dev/null +++ b/backend/src/helpers/GetTicketWbot.ts @@ -0,0 +1,23 @@ +import { WASocket } from "@whiskeysockets/baileys"; +import { getWbot } from "../libs/wbot"; +import GetDefaultWhatsApp from "./GetDefaultWhatsApp"; +import Ticket from "../models/Ticket"; +import { Store } from "../libs/store"; + +type Session = WASocket & { + id?: number; + store?: Store; +}; + +const GetTicketWbot = async (ticket: Ticket): Promise => { + if (!ticket.whatsappId) { + const defaultWhatsapp = await GetDefaultWhatsApp(ticket.user.id); + + await ticket.$set("whatsapp", defaultWhatsapp); + } + + const wbot = getWbot(ticket.whatsappId); + return wbot; +}; + +export default GetTicketWbot; diff --git a/backend/src/helpers/GetWbotMessage.ts b/backend/src/helpers/GetWbotMessage.ts new file mode 100644 index 0000000..9b71f8f --- /dev/null +++ b/backend/src/helpers/GetWbotMessage.ts @@ -0,0 +1,42 @@ +import { proto } from "@whiskeysockets/baileys"; +import WALegacySocket from "@whiskeysockets/baileys" +import Ticket from "../models/Ticket"; +import GetTicketWbot from "./GetTicketWbot"; +import AppError from "../errors/AppError"; +import GetMessageService from "../services/MessageServices/GetMessagesService"; +import Message from "../models/Message"; + +export const GetWbotMessage = async ( + ticket: Ticket, + messageId: string +): Promise => { + const getSock = await GetTicketWbot(ticket); + + let limit = 20; + + const fetchWbotMessagesGradually = async (): Promise< + proto.WebMessageInfo | Message | null | undefined + > => { + const msgFound = await GetMessageService({ + id: messageId + }); + + return msgFound; + + + }; + + try { + const msgFound = await fetchWbotMessagesGradually(); + + if (!msgFound) { + throw new Error("Cannot found message within 100 last messages"); + } + + return msgFound; + } catch (err) { + throw new AppError("ERR_FETCH_WAPP_MSG"); + } +}; + +export default GetWbotMessage; diff --git a/backend/src/helpers/GetWhatsappWbot.ts b/backend/src/helpers/GetWhatsappWbot.ts new file mode 100644 index 0000000..24e63ba --- /dev/null +++ b/backend/src/helpers/GetWhatsappWbot.ts @@ -0,0 +1,9 @@ +import { getWbot } from "../libs/wbot"; +import Whatsapp from "../models/Whatsapp"; + +const GetWhatsappWbot = async (whatsapp: Whatsapp) => { + const wbot = await getWbot(whatsapp.id); + return wbot; +}; + +export default GetWhatsappWbot; diff --git a/backend/src/helpers/Mustache.ts b/backend/src/helpers/Mustache.ts new file mode 100644 index 0000000..2b0ad26 --- /dev/null +++ b/backend/src/helpers/Mustache.ts @@ -0,0 +1,57 @@ +import Mustache from "mustache"; +import Contact from "../models/Contact"; + +export const greeting = (): string => { + const greetings = ["Boa madrugada", "Bom dia", "Boa tarde", "Boa noite"]; + const h = new Date().getHours(); + // eslint-disable-next-line no-bitwise + return greetings[(h / 6) >> 0]; +}; + +export const firstName = (contact?: Contact): string => { + if (contact && contact?.name) { + const nameArr = contact?.name.split(' '); + return nameArr[0]; + } + return ''; +}; + +export default (body: string, contact: Contact): string => { + let ms = ""; + + const Hr = new Date(); + + const dd: string = `0${Hr.getDate()}`.slice(-2); + const mm: string = `0${Hr.getMonth() + 1}`.slice(-2); + const yy: string = Hr.getFullYear().toString(); + const hh: number = Hr.getHours(); + const min: string = `0${Hr.getMinutes()}`.slice(-2); + const ss: string = `0${Hr.getSeconds()}`.slice(-2); + + if (hh >= 6) { + ms = "Bom dia"; + } + if (hh > 11) { + ms = "Boa tarde"; + } + if (hh > 17) { + ms = "Boa noite"; + } + if (hh > 23 || hh < 6) { + ms = "Boa madrugada"; + } + + const protocol = yy + mm + dd + String(hh) + min + ss; + + const hora = `${hh}:${min}:${ss}`; + + const view = { + firstName: firstName(contact), + name: contact ? contact.name : "", + gretting: greeting(), + ms, + protocol, + hora + }; + return Mustache.render(body, view); +}; \ No newline at end of file diff --git a/backend/src/helpers/SendMessage.ts b/backend/src/helpers/SendMessage.ts new file mode 100644 index 0000000..84ce74e --- /dev/null +++ b/backend/src/helpers/SendMessage.ts @@ -0,0 +1,45 @@ +import Whatsapp from "../models/Whatsapp"; +import GetWhatsappWbot from "./GetWhatsappWbot"; +import fs from "fs"; + +import { getMessageOptions } from "../services/WbotServices/SendWhatsAppMedia"; + +export type MessageData = { + number: number | string; + body: string; + mediaPath?: string; + fileName?: string; +}; + +export const SendMessage = async ( + whatsapp: Whatsapp, + messageData: MessageData +): Promise => { + try { + const wbot = await GetWhatsappWbot(whatsapp); + const chatId = `${messageData.number}@s.whatsapp.net`; + + let message; + + if (messageData.mediaPath) { + const options = await getMessageOptions( + messageData.fileName, + messageData.mediaPath, + messageData.body + ); + if (options) { + const body = fs.readFileSync(messageData.mediaPath); + message = await wbot.sendMessage(chatId, { + ...options + }); + } + } else { + const body = `\u200e ${messageData.body}`; + message = await wbot.sendMessage(chatId, { text: body }); + } + + return message; + } catch (err: any) { + throw new Error(err); + } +}; diff --git a/backend/src/helpers/SendRefreshToken.ts b/backend/src/helpers/SendRefreshToken.ts new file mode 100644 index 0000000..4e4459a --- /dev/null +++ b/backend/src/helpers/SendRefreshToken.ts @@ -0,0 +1,5 @@ +import { Response } from "express"; + +export const SendRefreshToken = (res: Response, token: string): void => { + res.cookie("jrt", token, { httpOnly: true }); +}; diff --git a/backend/src/helpers/SerializeUser.ts b/backend/src/helpers/SerializeUser.ts new file mode 100644 index 0000000..7e50103 --- /dev/null +++ b/backend/src/helpers/SerializeUser.ts @@ -0,0 +1,30 @@ +import Queue from "../models/Queue"; +import Company from "../models/Company"; +import User from "../models/User"; +import Setting from "../models/Setting"; + +interface SerializedUser { + id: number; + name: string; + email: string; + profile: string; + companyId: number; + company: Company | null; + super: boolean; + queues: Queue[]; + allTicket: string, +} + +export const SerializeUser = async (user: User): Promise => { + return { + id: user.id, + name: user.name, + email: user.email, + profile: user.profile, + companyId: user.companyId, + company: user.company, + super: user.super, + queues: user.queues, + allTicket: user.allTicket, + }; +}; diff --git a/backend/src/helpers/SerializeWbotMsgId.ts b/backend/src/helpers/SerializeWbotMsgId.ts new file mode 100644 index 0000000..4b5886e --- /dev/null +++ b/backend/src/helpers/SerializeWbotMsgId.ts @@ -0,0 +1,12 @@ +import Message from "../models/Message"; +import Ticket from "../models/Ticket"; + +const SerializeWbotMsgId = (ticket: Ticket, message: Message): string => { + const serializedMsgId = `${message.fromMe}_${ticket.contact.number}@${ + ticket.isGroup ? "g" : "c" + }.us_${message.id}`; + + return serializedMsgId; +}; + +export default SerializeWbotMsgId; diff --git a/backend/src/helpers/SetTicketMessagesAsRead.ts b/backend/src/helpers/SetTicketMessagesAsRead.ts new file mode 100644 index 0000000..32c5f9a --- /dev/null +++ b/backend/src/helpers/SetTicketMessagesAsRead.ts @@ -0,0 +1,62 @@ +import { proto, WASocket } from "@whiskeysockets/baileys"; +// import cacheLayer from "../libs/cache"; +import { getIO } from "../libs/socket"; +import Message from "../models/Message"; +import Ticket from "../models/Ticket"; +import { logger } from "../utils/logger"; +import GetTicketWbot from "./GetTicketWbot"; + +const SetTicketMessagesAsRead = async (ticket: Ticket): Promise => { + await ticket.update({ unreadMessages: 0 }); + // await cacheLayer.set(`contacts:${ticket.contactId}:unreads`, "0"); + + try { + const wbot = await GetTicketWbot(ticket); + + const getJsonMessage = await Message.findAll({ + where: { + ticketId: ticket.id, + fromMe: false, + read: false + }, + order: [["createdAt", "DESC"]] + }); + + if (getJsonMessage.length > 0) { + const lastMessages: proto.IWebMessageInfo = JSON.parse( + JSON.stringify(getJsonMessage[0].dataJson) + ); + + if (lastMessages.key && lastMessages.key.fromMe === false) { + await (wbot as WASocket).chatModify( + { markRead: true, lastMessages: [lastMessages] }, + `${ticket.contact.number}@${ + ticket.isGroup ? "g.us" : "s.whatsapp.net" + }` + ); + } + } + + await Message.update( + { read: true }, + { + where: { + ticketId: ticket.id, + read: false + } + } + ); + } catch (err) { + logger.warn( + `Could not mark messages as read. Maybe whatsapp session disconnected? Err: ${err}` + ); + } + + const io = getIO(); + io.to(`company-${ticket.companyId}-mainchannel`).emit(`company-${ticket.companyId}-ticket`, { + action: "updateUnread", + ticketId: ticket.id + }); +}; + +export default SetTicketMessagesAsRead; diff --git a/backend/src/helpers/UpdateDeletedUserOpenTicketsStatus.ts b/backend/src/helpers/UpdateDeletedUserOpenTicketsStatus.ts new file mode 100644 index 0000000..1204974 --- /dev/null +++ b/backend/src/helpers/UpdateDeletedUserOpenTicketsStatus.ts @@ -0,0 +1,19 @@ +import Ticket from "../models/Ticket"; +import UpdateTicketService from "../services/TicketServices/UpdateTicketService"; + +const UpdateDeletedUserOpenTicketsStatus = async ( + tickets: Ticket[], + companyId: number +): Promise => { + tickets.forEach(async t => { + const ticketId = t.id.toString(); + + await UpdateTicketService({ + ticketData: { status: "pending" }, + ticketId, + companyId + }); + }); +}; + +export default UpdateDeletedUserOpenTicketsStatus; diff --git a/backend/src/helpers/authState.ts b/backend/src/helpers/authState.ts new file mode 100644 index 0000000..db8304b --- /dev/null +++ b/backend/src/helpers/authState.ts @@ -0,0 +1,77 @@ +import type { + AuthenticationCreds, + AuthenticationState, + SignalDataTypeMap +} from "@whiskeysockets/baileys"; +import { BufferJSON, initAuthCreds, proto } from "@whiskeysockets/baileys"; +import Whatsapp from "../models/Whatsapp"; + +const KEY_MAP: { [T in keyof SignalDataTypeMap]: string } = { + "pre-key": "preKeys", + session: "sessions", + "sender-key": "senderKeys", + "app-state-sync-key": "appStateSyncKeys", + "app-state-sync-version": "appStateVersions", + "sender-key-memory": "senderKeyMemory" +}; + +const authState = async ( + whatsapp: Whatsapp +): Promise<{ state: AuthenticationState; saveState: () => void }> => { + let creds: AuthenticationCreds; + let keys: any = {}; + + const saveState = async () => { + try { + await whatsapp.update({ + session: JSON.stringify({ creds, keys }, BufferJSON.replacer, 0) + }); + } catch (error) { + console.log(error); + } + }; + + // const getSessionDatabase = await whatsappById(whatsapp.id); + + if (whatsapp.session && whatsapp.session !== null) { + const result = JSON.parse(whatsapp.session, BufferJSON.reviver); + creds = result.creds; + keys = result.keys; + } else { + creds = initAuthCreds(); + keys = {}; + } + + return { + state: { + creds, + keys: { + get: (type, ids) => { + const key = KEY_MAP[type]; + return ids.reduce((dict: any, id) => { + let value = keys[key]?.[id]; + if (value) { + if (type === "app-state-sync-key") { + value = proto.Message.AppStateSyncKeyData.fromObject(value); + } + dict[id] = value; + } + return dict; + }, {}); + }, + set: (data: any) => { + // eslint-disable-next-line no-restricted-syntax, guard-for-in + for (const i in data) { + const key = KEY_MAP[i as keyof SignalDataTypeMap]; + keys[key] = keys[key] || {}; + Object.assign(keys[key], data[i]); + } + saveState(); + } + } + }, + saveState + }; +}; + +export default authState; diff --git a/backend/src/libs/cache.ts b/backend/src/libs/cache.ts new file mode 100644 index 0000000..ce38792 --- /dev/null +++ b/backend/src/libs/cache.ts @@ -0,0 +1,82 @@ +import Redis from "ioredis"; +import { REDIS_URI_CONNECTION } from "../config/redis"; +import util from "util"; +import * as crypto from "crypto"; + +const redis = new Redis(REDIS_URI_CONNECTION); + +function encryptParams(params: any) { + const str = JSON.stringify(params); + return crypto.createHash("sha256").update(str).digest("base64"); +} + +export function setFromParams( + key: string, + params: any, + value: string, + option?: string, + optionValue?: string | number +) { + const finalKey = `${key}:${encryptParams(params)}`; + if (option !== undefined && optionValue !== undefined) { + return set(finalKey, value, option, optionValue); + } + return set(finalKey, value); +} + +export function getFromParams(key: string, params: any) { + const finalKey = `${key}:${encryptParams(params)}`; + return get(finalKey); +} + +export function delFromParams(key: string, params: any) { + const finalKey = `${key}:${encryptParams(params)}`; + return del(finalKey); +} + +export function set( + key: string, + value: string, + option?: string, + optionValue?: string | number +) { + const setPromisefy = util.promisify(redis.set).bind(redis); + if (option !== undefined && optionValue !== undefined) { + return setPromisefy(key, value, option, optionValue); + } + + return setPromisefy(key, value); +} + +export function get(key: string) { + const getPromisefy = util.promisify(redis.get).bind(redis); + return getPromisefy(key); +} + +export function getKeys(pattern: string) { + const getKeysPromisefy = util.promisify(redis.keys).bind(redis); + return getKeysPromisefy(pattern); +} + +export function del(key: string) { + const delPromisefy = util.promisify(redis.del).bind(redis); + return delPromisefy(key); +} + +export async function delFromPattern(pattern: string) { + const all = await getKeys(pattern); + for (let item of all) { + del(item); + } +} + +export const cacheLayer = { + set, + setFromParams, + get, + getFromParams, + getKeys, + del, + delFromParams, + delFromPattern +}; diff --git a/backend/src/libs/counter.ts b/backend/src/libs/counter.ts new file mode 100644 index 0000000..77a7971 --- /dev/null +++ b/backend/src/libs/counter.ts @@ -0,0 +1,33 @@ +// I ❤️ Chat GPT + +export type Counter = { + name: string; + value: number; +}; + +export type CounterMap = Record; + +export class CounterManager { + private counters: CounterMap = {}; + + // Function to increment the value of a counter and return the current value + incrementCounter(name: string, amount: number = 1): number { + if (!this.counters[name]) { + this.counters[name] = { name, value: 0 }; + } + this.counters[name].value += amount; + return this.counters[name].value; + } + + // Function to decrement the value of a counter and return the current value + decrementCounter(name: string, amount: number = 1): number { + if (this.counters[name]) { + this.counters[name].value -= amount; + if (this.counters[name].value < 0) { + this.counters[name].value = 0; // Ensure the counter doesn't go below zero + } + return this.counters[name].value; + } + return 0; // Counter doesn't exist, return 0 + } +} diff --git a/backend/src/libs/socket.ts b/backend/src/libs/socket.ts new file mode 100644 index 0000000..9fb04ea --- /dev/null +++ b/backend/src/libs/socket.ts @@ -0,0 +1,177 @@ +import { Server as SocketIO } from "socket.io"; +import { Server } from "http"; +import AppError from "../errors/AppError"; +import { logger } from "../utils/logger"; +import User from "../models/User"; +import Queue from "../models/Queue"; +import Ticket from "../models/Ticket"; +import { verify } from "jsonwebtoken"; +import authConfig from "../config/auth"; +import { CounterManager } from "./counter"; + +let io: SocketIO; + +export const initIO = (httpServer: Server): SocketIO => { + io = new SocketIO(httpServer, { + cors: { + origin: process.env.FRONTEND_URL + } + }); + + io.on("connection", async socket => { + logger.info("Client Connected"); + const { token } = socket.handshake.query; + let tokenData = null; + try { + tokenData = verify(token as string, authConfig.secret); + logger.debug(tokenData, "io-onConnection: tokenData"); + } catch (error) { + logger.warn(`[libs/socket.ts] Error decoding token: ${error?.message}`); + socket.disconnect(); + return io; + } + const counters = new CounterManager(); + + let user: User = null; + let userId = tokenData.id; + + if (userId && userId !== "undefined" && userId !== "null") { + user = await User.findByPk(userId, { include: [ Queue ] }); + if (user) { + user.online = true; + await user.save(); + } else { + logger.info(`onConnect: User ${userId} not found`); + socket.disconnect(); + return io; + } + } else { + logger.info("onConnect: Missing userId"); + socket.disconnect(); + return io; + } + + socket.join(`company-${user.companyId}-mainchannel`); + socket.join(`user-${user.id}`); + + socket.on("joinChatBox", async (ticketId: string) => { + if (!ticketId || ticketId === "undefined") { + return; + } + Ticket.findByPk(ticketId).then( + (ticket) => { + if (ticket && ticket.companyId === user.companyId + && (ticket.userId === user.id || user.profile === "admin")) { + let c: number; + if ((c = counters.incrementCounter(`ticket-${ticketId}`)) === 1) { + socket.join(ticketId); + } + logger.debug(`joinChatbox[${c}]: Channel: ${ticketId} by user ${user.id}`) + } else { + logger.info(`Invalid attempt to join channel of ticket ${ticketId} by user ${user.id}`) + } + }, + (error) => { + logger.error(error, `Error fetching ticket ${ticketId}`); + } + ); + }); + + socket.on("leaveChatBox", async (ticketId: string) => { + if (!ticketId || ticketId === "undefined") { + return; + } + + let c: number; + // o último que sair apaga a luz + + if ((c = counters.decrementCounter(`ticket-${ticketId}`)) === 0) { + socket.leave(ticketId); + } + logger.debug(`leaveChatbox[${c}]: Channel: ${ticketId} by user ${user.id}`) + }); + + socket.on("joinNotification", async () => { + let c: number; + if ((c = counters.incrementCounter("notification")) === 1) { + if (user.profile === "admin") { + socket.join(`company-${user.companyId}-notification`); + } else { + user.queues.forEach((queue) => { + logger.debug(`User ${user.id} of company ${user.companyId} joined queue ${queue.id} channel.`); + socket.join(`queue-${queue.id}-notification`); + }); + if (user.allTicket === "enabled") { + socket.join("queue-null-notification"); + } + + } + } + logger.debug(`joinNotification[${c}]: User: ${user.id}`); + }); + + socket.on("leaveNotification", async () => { + let c: number; + if ((c = counters.decrementCounter("notification")) === 0) { + if (user.profile === "admin") { + socket.leave(`company-${user.companyId}-notification`); + } else { + user.queues.forEach((queue) => { + logger.debug(`User ${user.id} of company ${user.companyId} leaved queue ${queue.id} channel.`); + socket.leave(`queue-${queue.id}-notification`); + }); + if (user.allTicket === "enabled") { + socket.leave("queue-null-notification"); + } + } + } + logger.debug(`leaveNotification[${c}]: User: ${user.id}`); + }); + + socket.on("joinTickets", (status: string) => { + if (counters.incrementCounter(`status-${status}`) === 1) { + if (user.profile === "admin") { + logger.debug(`Admin ${user.id} of company ${user.companyId} joined ${status} tickets channel.`); + socket.join(`company-${user.companyId}-${status}`); + } else if (status === "pending") { + user.queues.forEach((queue) => { + logger.debug(`User ${user.id} of company ${user.companyId} joined queue ${queue.id} pending tickets channel.`); + socket.join(`queue-${queue.id}-pending`); + }); + if (user.allTicket === "enabled") { + socket.join("queue-null-pending"); + } + } else { + logger.debug(`User ${user.id} cannot subscribe to ${status}`); + } + } + }); + + socket.on("leaveTickets", (status: string) => { + if (counters.decrementCounter(`status-${status}`) === 0) { + if (user.profile === "admin") { + logger.debug(`Admin ${user.id} of company ${user.companyId} leaved ${status} tickets channel.`); + socket.leave(`company-${user.companyId}-${status}`); + } else if (status === "pending") { + user.queues.forEach((queue) => { + logger.debug(`User ${user.id} of company ${user.companyId} leaved queue ${queue.id} pending tickets channel.`); + socket.leave(`queue-${queue.id}-pending`); + }); + if (user.allTicket === "enabled") { + socket.leave("queue-null-pending"); + } + } + } + }); + + socket.emit("ready"); + }); + return io; +}; + +export const getIO = (): SocketIO => { + if (!io) { + throw new AppError("Socket IO not initialized"); + } + return io; +}; diff --git a/backend/src/libs/store.d.ts b/backend/src/libs/store.d.ts new file mode 100644 index 0000000..1599036 --- /dev/null +++ b/backend/src/libs/store.d.ts @@ -0,0 +1,116 @@ +import { + AnyWASocket, + BaileysEventEmitter, + Chat, + ConnectionState, + Contact, + GroupMetadata, + PresenceData, + proto, + WAMessageCursor, + WAMessageKey, + WALegacySocket +} from "@adiwajshing/baileys"; +import KeyedDB from "@adiwajshing/keyed-db"; + +export interface Store { + chats: KeyedDB; + contacts: { + [_: string]: Contact; + }; + messages: { + [_: string]: { + array: proto.IWebMessageInfo[]; + get: (id: string) => proto.IWebMessageInfo; + upsert: (item: proto.IWebMessageInfo, mode: "append" | "prepend") => void; + update: (item: proto.IWebMessageInfo) => boolean; + remove: (item: proto.IWebMessageInfo) => boolean; + updateAssign: ( + id: string, + update: Partial + ) => boolean; + clear: () => void; + filter: (contain: (item: proto.IWebMessageInfo) => boolean) => void; + toJSON: () => proto.IWebMessageInfo[]; + fromJSON: (newItems: proto.IWebMessageInfo[]) => void; + }; + }; + groupMetadata: { + [_: string]: GroupMetadata; + }; + state: ConnectionState; + presences: { + [id: string]: { + [participant: string]: PresenceData; + }; + }; + bind: (ev: BaileysEventEmitter) => void; + loadMessages: ( + jid: string, + count: number, + cursor: WAMessageCursor, + sock: WALegacySocket | undefined + ) => Promise; + loadMessage: ( + jid: string, + id: string, + sock: WALegacySocket | undefined + ) => Promise; + mostRecentMessage: ( + jid: string, + sock: WALegacySocket | undefined + ) => Promise; + fetchImageUrl: ( + jid: string, + sock: AnyWASocket | undefined + ) => Promise; + fetchGroupMetadata: ( + jid: string, + sock: AnyWASocket | undefined + ) => Promise; + fetchBroadcastListInfo: ( + jid: string, + sock: WALegacySocket | undefined + ) => Promise; + fetchMessageReceipts: ( + { remoteJid, id }: WAMessageKey, + sock: WALegacySocket | undefined + ) => Promise; + toJSON: () => { + chats: KeyedDB; + contacts: { + [_: string]: Contact; + }; + messages: { + [_: string]: { + array: proto.IWebMessageInfo[]; + get: (id: string) => proto.IWebMessageInfo; + upsert: ( + item: proto.IWebMessageInfo, + mode: "append" | "prepend" + ) => void; + update: (item: proto.IWebMessageInfo) => boolean; + remove: (item: proto.IWebMessageInfo) => boolean; + updateAssign: ( + id: string, + update: Partial + ) => boolean; + clear: () => void; + filter: (contain: (item: proto.IWebMessageInfo) => boolean) => void; + toJSON: () => proto.IWebMessageInfo[]; + fromJSON: (newItems: proto.IWebMessageInfo[]) => void; + }; + }; + }; + fromJSON: (json: { + chats: Chat[]; + contacts: { + [id: string]: Contact; + }; + messages: { + [id: string]: proto.IWebMessageInfo[]; + }; + }) => void; + writeToFile: (path: string) => void; + readFromFile: (path: string) => void; +} diff --git a/backend/src/libs/wbot.ts b/backend/src/libs/wbot.ts new file mode 100644 index 0000000..d152267 --- /dev/null +++ b/backend/src/libs/wbot.ts @@ -0,0 +1,263 @@ +import * as Sentry from "@sentry/node"; +import makeWASocket, { + WASocket, + Browsers, + DisconnectReason, + fetchLatestBaileysVersion, + makeCacheableSignalKeyStore, + makeInMemoryStore, + isJidBroadcast, + CacheStore +} from "@whiskeysockets/baileys"; +import makeWALegacySocket from "@whiskeysockets/baileys"; +import P from "pino"; + +import Whatsapp from "../models/Whatsapp"; +import { logger } from "../utils/logger"; +import MAIN_LOGGER from "@whiskeysockets/baileys/lib/Utils/logger"; +import authState from "../helpers/authState"; +import { Boom } from "@hapi/boom"; +import AppError from "../errors/AppError"; +import { getIO } from "./socket"; +import { Store } from "./store"; +import { StartWhatsAppSession } from "../services/WbotServices/StartWhatsAppSession"; +import DeleteBaileysService from "../services/BaileysServices/DeleteBaileysService"; +import NodeCache from 'node-cache'; + +const loggerBaileys = MAIN_LOGGER.child({}); +loggerBaileys.level = "error"; + +type Session = WASocket & { + id?: number; + store?: Store; +}; + +const sessions: Session[] = []; + +const retriesQrCodeMap = new Map(); + +export const getWbot = (whatsappId: number): Session => { + const sessionIndex = sessions.findIndex(s => s.id === whatsappId); + + if (sessionIndex === -1) { + throw new AppError("ERR_WAPP_NOT_INITIALIZED"); + } + return sessions[sessionIndex]; +}; + +export const removeWbot = async ( + whatsappId: number, + isLogout = true +): Promise => { + try { + const sessionIndex = sessions.findIndex(s => s.id === whatsappId); + if (sessionIndex !== -1) { + if (isLogout) { + sessions[sessionIndex].logout(); + sessions[sessionIndex].ws.close(); + } + + sessions.splice(sessionIndex, 1); + } + } catch (err) { + logger.error(err); + } +}; + +export const initWASocket = async (whatsapp: Whatsapp): Promise => { + return new Promise(async (resolve, reject) => { + try { + (async () => { + const io = getIO(); + + const whatsappUpdate = await Whatsapp.findOne({ + where: { id: whatsapp.id } + }); + + if (!whatsappUpdate) return; + + const { id, name, provider } = whatsappUpdate; + + const { version, isLatest } = await fetchLatestBaileysVersion(); + const isLegacy = provider === "stable" ? true : false; + + logger.info(`using WA v${version.join(".")}, isLatest: ${isLatest}`); + logger.info(`isLegacy: ${isLegacy}`); + logger.info(`Starting session ${name}`); + let retriesQrCode = 0; + + let wsocket: Session = null; + const store = makeInMemoryStore({ + logger: loggerBaileys + }); + + const { state, saveState } = await authState(whatsapp); + + const msgRetryCounterCache = new NodeCache(); + const userDevicesCache: CacheStore = new NodeCache(); + + wsocket = makeWASocket({ + logger: loggerBaileys, + printQRInTerminal: false, + browser: Browsers.appropriate("Desktop"), + auth: { + creds: state.creds, + keys: makeCacheableSignalKeyStore(state.keys, logger), + }, + version, + // defaultQueryTimeoutMs: 60000, + // retryRequestDelayMs: 250, + // keepAliveIntervalMs: 1000 * 60 * 10 * 3, + msgRetryCounterCache, + shouldIgnoreJid: jid => isJidBroadcast(jid), + }); + + // wsocket = makeWASocket({ + // version, + // logger: loggerBaileys, + // printQRInTerminal: false, + // auth: state as AuthenticationState, + // generateHighQualityLinkPreview: false, + // shouldIgnoreJid: jid => isJidBroadcast(jid), + // browser: ["Chat", "Chrome", "10.15.7"], + // patchMessageBeforeSending: (message) => { + // const requiresPatch = !!( + // message.buttonsMessage || + // // || message.templateMessage + // message.listMessage + // ); + // if (requiresPatch) { + // message = { + // viewOnceMessage: { + // message: { + // messageContextInfo: { + // deviceListMetadataVersion: 2, + // deviceListMetadata: {}, + // }, + // ...message, + // }, + // }, + // }; + // } + + // return message; + // }, + // }) + + wsocket.ev.on( + "connection.update", + async ({ connection, lastDisconnect, qr }) => { + logger.info( + `Socket ${name} Connection Update ${connection || ""} ${lastDisconnect || "" + }` + ); + + if (connection === "close") { + if ((lastDisconnect?.error as Boom)?.output?.statusCode === 403) { + await whatsapp.update({ status: "PENDING", session: "" }); + await DeleteBaileysService(whatsapp.id); + io.to(`company-${whatsapp.companyId}-mainchannel`).emit(`company-${whatsapp.companyId}-whatsappSession`, { + action: "update", + session: whatsapp + }); + removeWbot(id, false); + } + if ( + (lastDisconnect?.error as Boom)?.output?.statusCode !== + DisconnectReason.loggedOut + ) { + removeWbot(id, false); + setTimeout( + () => StartWhatsAppSession(whatsapp, whatsapp.companyId), + 2000 + ); + } else { + await whatsapp.update({ status: "PENDING", session: "" }); + await DeleteBaileysService(whatsapp.id); + io.to(`company-${whatsapp.companyId}-mainchannel`).emit(`company-${whatsapp.companyId}-whatsappSession`, { + action: "update", + session: whatsapp + }); + removeWbot(id, false); + setTimeout( + () => StartWhatsAppSession(whatsapp, whatsapp.companyId), + 2000 + ); + } + } + + if (connection === "open") { + await whatsapp.update({ + status: "CONNECTED", + qrcode: "", + retries: 0 + }); + + io.to(`company-${whatsapp.companyId}-mainchannel`).emit(`company-${whatsapp.companyId}-whatsappSession`, { + action: "update", + session: whatsapp + }); + + const sessionIndex = sessions.findIndex( + s => s.id === whatsapp.id + ); + if (sessionIndex === -1) { + wsocket.id = whatsapp.id; + sessions.push(wsocket); + } + + resolve(wsocket); + } + + if (qr !== undefined) { + if (retriesQrCodeMap.get(id) && retriesQrCodeMap.get(id) >= 3) { + await whatsappUpdate.update({ + status: "DISCONNECTED", + qrcode: "" + }); + await DeleteBaileysService(whatsappUpdate.id); + io.to(`company-${whatsapp.companyId}-mainchannel`).emit("whatsappSession", { + action: "update", + session: whatsappUpdate + }); + wsocket.ev.removeAllListeners("connection.update"); + wsocket.ws.close(); + wsocket = null; + retriesQrCodeMap.delete(id); + } else { + logger.info(`Session QRCode Generate ${name}`); + retriesQrCodeMap.set(id, (retriesQrCode += 1)); + + await whatsapp.update({ + qrcode: qr, + status: "qrcode", + retries: 0 + }); + const sessionIndex = sessions.findIndex( + s => s.id === whatsapp.id + ); + + if (sessionIndex === -1) { + wsocket.id = whatsapp.id; + sessions.push(wsocket); + } + + io.to(`company-${whatsapp.companyId}-mainchannel`).emit(`company-${whatsapp.companyId}-whatsappSession`, { + action: "update", + session: whatsapp + }); + } + } + } + ); + wsocket.ev.on("creds.update", saveState); + + store.bind(wsocket.ev); + })(); + } catch (error) { + Sentry.captureException(error); + console.log(error); + reject(error); + } + }); +}; diff --git a/backend/src/middleware/envTokenAuth.ts b/backend/src/middleware/envTokenAuth.ts new file mode 100644 index 0000000..99e7617 --- /dev/null +++ b/backend/src/middleware/envTokenAuth.ts @@ -0,0 +1,32 @@ +import { Request, Response, NextFunction } from "express"; + +import AppError from "../errors/AppError"; + +type TokenPayload = { + token: string | undefined; +}; + +const envTokenAuth = ( + req: Request, + res: Response, + next: NextFunction +): void => { + try { + const { token: bodyToken } = req.body as TokenPayload; + const { token: queryToken } = req.query as TokenPayload; + + if (queryToken === process.env.ENV_TOKEN) { + return next(); + } + + if (bodyToken === process.env.ENV_TOKEN) { + return next(); + } + } catch (e) { + console.log(e); + } + + throw new AppError("Token inválido", 403); +}; + +export default envTokenAuth; diff --git a/backend/src/middleware/isAuth.ts b/backend/src/middleware/isAuth.ts new file mode 100644 index 0000000..1898f35 --- /dev/null +++ b/backend/src/middleware/isAuth.ts @@ -0,0 +1,40 @@ +import { verify } from "jsonwebtoken"; +import { Request, Response, NextFunction } from "express"; +import { logger } from "../utils/logger"; +import AppError from "../errors/AppError"; +import authConfig from "../config/auth"; + +interface TokenPayload { + id: string; + username: string; + profile: string; + companyId: number; + iat: number; + exp: number; +} + +const isAuth = (req: Request, res: Response, next: NextFunction): void => { + const authHeader = req.headers.authorization; + + if (!authHeader) { + throw new AppError("ERR_SESSION_EXPIRED", 401); + } + + const [, token] = authHeader.split(" "); + + try { + const decoded = verify(token, authConfig.secret); + const { id, profile, companyId } = decoded as TokenPayload; + req.user = { + id, + profile, + companyId + }; + } catch (err) { + throw new AppError("Invalid token. We'll try to assign a new one on next request", 403 ); + } + + return next(); +}; + +export default isAuth; diff --git a/backend/src/middleware/isSuper.ts b/backend/src/middleware/isSuper.ts new file mode 100644 index 0000000..f30dd17 --- /dev/null +++ b/backend/src/middleware/isSuper.ts @@ -0,0 +1,17 @@ +import { Request, Response, NextFunction } from "express"; +import AppError from "../errors/AppError"; +import User from "../models/User"; + +const isSuper = async (req: Request, res: Response, next: NextFunction): Promise => { + const { super:isSuper } = await User.findByPk(req.user.id); + if(!isSuper){ + throw new AppError( + "Acesso não permitido", + 401 + ); + } + + return next(); +} + +export default isSuper; diff --git a/backend/src/middleware/tokenAuth.ts b/backend/src/middleware/tokenAuth.ts new file mode 100644 index 0000000..ac883a6 --- /dev/null +++ b/backend/src/middleware/tokenAuth.ts @@ -0,0 +1,31 @@ +import { Request, Response, NextFunction } from "express"; + +import AppError from "../errors/AppError"; +import Whatsapp from "../models/Whatsapp"; + +type HeaderParams = { + Bearer: string; +}; + +const tokenAuth = async (req: Request, res: Response, next: NextFunction): Promise => { + try { + const token = req.headers.authorization.replace('Bearer ', ''); + const whatsapp = await Whatsapp.findOne({ where: { token } }); + if (whatsapp) { + req.params = { + whatsappId: whatsapp.id.toString() + } + } else { + throw new Error(); + } + } catch (err) { + throw new AppError( + "Acesso não permitido", + 401 + ); + } + + return next(); +}; + +export default tokenAuth; diff --git a/backend/src/models/Announcement.ts b/backend/src/models/Announcement.ts new file mode 100644 index 0000000..94cc873 --- /dev/null +++ b/backend/src/models/Announcement.ts @@ -0,0 +1,54 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + AutoIncrement, + DataType, + BelongsTo, + ForeignKey +} from "sequelize-typescript"; +import Company from "./Company"; + +@Table +class Announcement extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column + priority: number; //1 - alta, 2 - média, 3 - baixa + + @Column + title: string; + + @Column(DataType.TEXT) + text: string; + + @Column + mediaPath: string; + + @Column + mediaName: string; + + @ForeignKey(() => Company) + @Column + companyId: number; + + @Column + status: boolean; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @BelongsTo(() => Company) + company: Company; +} + +export default Announcement; diff --git a/backend/src/models/Baileys.ts b/backend/src/models/Baileys.ts new file mode 100644 index 0000000..b64c2d9 --- /dev/null +++ b/backend/src/models/Baileys.ts @@ -0,0 +1,40 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + AutoIncrement, + Default, + ForeignKey +} from "sequelize-typescript"; +import Whatsapp from "./Whatsapp"; + +@Table +class Baileys extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Default(null) + @Column + contacts: string; + + @Default(null) + @Column + chats: string; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @ForeignKey(() => Whatsapp) + @Column + whatsappId: number; +} + +export default Baileys; diff --git a/backend/src/models/BaileysChats.ts b/backend/src/models/BaileysChats.ts new file mode 100644 index 0000000..a1d63e8 --- /dev/null +++ b/backend/src/models/BaileysChats.ts @@ -0,0 +1,45 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + Default, + ForeignKey, + DataType, + AllowNull, + AutoIncrement +} from "sequelize-typescript"; +import Company from "./Company"; +import Whatsapp from "./Whatsapp"; + +@Table +class BaileysChats extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column + jid: string; + + @Column + conversationTimestamp: number; + + @Default(0) + @Column + unreadCount: number; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @ForeignKey(() => Whatsapp) + @Column(DataType.INTEGER) + whatsappId: string; +} + +export default BaileysChats; diff --git a/backend/src/models/Campaign.ts b/backend/src/models/Campaign.ts new file mode 100644 index 0000000..91b5a96 --- /dev/null +++ b/backend/src/models/Campaign.ts @@ -0,0 +1,115 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + AutoIncrement, + ForeignKey, + BelongsTo, + HasMany +} from "sequelize-typescript"; +import CampaignShipping from "./CampaignShipping"; +import Company from "./Company"; +import ContactList from "./ContactList"; +import Whatsapp from "./Whatsapp"; +import Files from "./Files"; + +@Table({ tableName: "Campaigns" }) +class Campaign extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column + name: string; + + @Column({ defaultValue: "" }) + message1: string; + + @Column({ defaultValue: "" }) + message2: string; + + @Column({ defaultValue: "" }) + message3: string; + + @Column({ defaultValue: "" }) + message4: string; + + @Column({ defaultValue: "" }) + message5: string; + + @Column({ defaultValue: "" }) + confirmationMessage1: string; + + @Column({ defaultValue: "" }) + confirmationMessage2: string; + + @Column({ defaultValue: "" }) + confirmationMessage3: string; + + @Column({ defaultValue: "" }) + confirmationMessage4: string; + + @Column({ defaultValue: "" }) + confirmationMessage5: string; + + @Column({ defaultValue: "INATIVA" }) + status: string; // INATIVA, PROGRAMADA, EM_ANDAMENTO, CANCELADA, FINALIZADA + + @Column + confirmation: boolean; + + @Column + mediaPath: string; + + @Column + mediaName: string; + + @Column + scheduledAt: Date; + + @Column + completedAt: Date; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @ForeignKey(() => Company) + @Column + companyId: number; + + @BelongsTo(() => Company) + company: Company; + + @ForeignKey(() => ContactList) + @Column + contactListId: number; + + @BelongsTo(() => ContactList) + contactList: ContactList; + + @ForeignKey(() => Whatsapp) + @Column + whatsappId: number; + + @BelongsTo(() => Whatsapp) + whatsapp: Whatsapp; + + @ForeignKey(() => Files) + @Column + fileListId: number; + + @BelongsTo(() => Files) + fileList: Files; + + @HasMany(() => CampaignShipping) + shipping: CampaignShipping[]; +} + +export default Campaign; diff --git a/backend/src/models/CampaignSetting.ts b/backend/src/models/CampaignSetting.ts new file mode 100644 index 0000000..ce9cc61 --- /dev/null +++ b/backend/src/models/CampaignSetting.ts @@ -0,0 +1,41 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + AutoIncrement, + ForeignKey, + BelongsTo +} from "sequelize-typescript"; +import Company from "./Company"; + +@Table({ tableName: "CampaignSettings" }) +class CampaignSetting extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column + key: string; + + @Column + value: string; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @ForeignKey(() => Company) + @Column + companyId: number; + + @BelongsTo(() => Company) + company: Company; +} + +export default CampaignSetting; diff --git a/backend/src/models/CampaignShipping.ts b/backend/src/models/CampaignShipping.ts new file mode 100644 index 0000000..f7849db --- /dev/null +++ b/backend/src/models/CampaignShipping.ts @@ -0,0 +1,67 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + AutoIncrement, + ForeignKey, + BelongsTo +} from "sequelize-typescript"; +import Campaign from "./Campaign"; +import ContactListItem from "./ContactListItem"; + +@Table({ tableName: "CampaignShipping" }) +class CampaignShipping extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column + jobId: string; + + @Column + number: string; + + @Column + message: string; + + @Column + confirmationMessage: string; + + @Column + confirmation: boolean; + + @ForeignKey(() => ContactListItem) + @Column + contactId: number; + + @ForeignKey(() => Campaign) + @Column + campaignId: number; + + @Column + confirmationRequestedAt: Date; + + @Column + confirmedAt: Date; + + @Column + deliveredAt: Date; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @BelongsTo(() => ContactListItem) + contact: ContactListItem; + + @BelongsTo(() => Campaign) + campaign: Campaign; +} + +export default CampaignShipping; diff --git a/backend/src/models/Chat.ts b/backend/src/models/Chat.ts new file mode 100644 index 0000000..a84dd4f --- /dev/null +++ b/backend/src/models/Chat.ts @@ -0,0 +1,72 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + AutoIncrement, + HasMany, + BelongsTo, + ForeignKey, + BeforeCreate, + Default +} from "sequelize-typescript"; + +import { v4 as uuidv4 } from "uuid"; + +import ChatMessage from "./ChatMessage"; +import ChatUser from "./ChatUser"; +import Company from "./Company"; +import User from "./User"; + +@Table({ tableName: "Chats" }) +class Chat extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Default(uuidv4()) + @Column + uuid: string; + + @Column({ defaultValue: "" }) + title: string; + + @ForeignKey(() => User) + @Column + ownerId: number; + + @Column({ defaultValue: "" }) + lastMessage: string; + + @ForeignKey(() => Company) + @Column + companyId: number; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @BelongsTo(() => Company) + company: Company; + + @BelongsTo(() => User) + owner: User; + + @HasMany(() => ChatUser) + users: ChatUser[]; + + @HasMany(() => ChatMessage) + messages: ChatMessage[]; + + @BeforeCreate + static setUUID(chat: Chat) { + chat.uuid = uuidv4(); + } +} + +export default Chat; diff --git a/backend/src/models/ChatMessage.ts b/backend/src/models/ChatMessage.ts new file mode 100644 index 0000000..9cf9e33 --- /dev/null +++ b/backend/src/models/ChatMessage.ts @@ -0,0 +1,52 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + AutoIncrement, + BelongsTo, + ForeignKey +} from "sequelize-typescript"; +import User from "./User"; +import Chat from "./Chat"; + +@Table({ tableName: "ChatMessages" }) +class ChatMessage extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @ForeignKey(() => Chat) + @Column + chatId: number; + + @ForeignKey(() => User) + @Column + senderId: number; + + @Column({ defaultValue: "" }) + message: string; + + @Column + mediaPath: string; + + @Column + mediaName: string; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @BelongsTo(() => Chat) + chat: Chat; + + @BelongsTo(() => User) + sender: User; +} + +export default ChatMessage; diff --git a/backend/src/models/ChatUser.ts b/backend/src/models/ChatUser.ts new file mode 100644 index 0000000..ecddcaa --- /dev/null +++ b/backend/src/models/ChatUser.ts @@ -0,0 +1,46 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + AutoIncrement, + BelongsTo, + ForeignKey +} from "sequelize-typescript"; +import User from "./User"; +import Chat from "./Chat"; + +@Table({ tableName: "ChatUsers" }) +class ChatUser extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @ForeignKey(() => Chat) + @Column + chatId: number; + + @ForeignKey(() => User) + @Column + userId: number; + + @Column + unreads: number; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @BelongsTo(() => Chat) + chat: Chat; + + @BelongsTo(() => User) + user: User; +} + +export default ChatUser; diff --git a/backend/src/models/Company.ts b/backend/src/models/Company.ts new file mode 100644 index 0000000..a4e75f5 --- /dev/null +++ b/backend/src/models/Company.ts @@ -0,0 +1,133 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + AutoIncrement, + ForeignKey, + BelongsTo, + DataType, + HasMany +} from "sequelize-typescript"; +import Contact from "./Contact"; +import Message from "./Message"; + +import Plan from "./Plan"; +import Queue from "./Queue"; +import Setting from "./Setting"; +import Ticket from "./Ticket"; +import TicketTraking from "./TicketTraking"; +import User from "./User"; +import UserRating from "./UserRating"; +import Whatsapp from "./Whatsapp"; + +@Table +class Company extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column + name: string; + + @Column + phone: string; + + @Column + email: string; + + @Column + status: boolean; + + @Column + dueDate: string; + + @Column + recurrence: string; + + @Column({ + type: DataType.JSONB + }) + schedules: []; + + @ForeignKey(() => Plan) + @Column + planId: number; + + @BelongsTo(() => Plan) + plan: Plan; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @HasMany(() => User, { + onUpdate: "CASCADE", + onDelete: "CASCADE", + hooks: true + }) + users: User[]; + + @HasMany(() => UserRating, { + onUpdate: "CASCADE", + onDelete: "CASCADE", + hooks: true + }) + userRatings: UserRating[]; + + @HasMany(() => Queue, { + onUpdate: "CASCADE", + onDelete: "CASCADE", + hooks: true + }) + queues: Queue[]; + + @HasMany(() => Whatsapp, { + onUpdate: "CASCADE", + onDelete: "CASCADE", + hooks: true + }) + whatsapps: Whatsapp[]; + + @HasMany(() => Message, { + onUpdate: "CASCADE", + onDelete: "CASCADE", + hooks: true + }) + messages: Message[]; + + @HasMany(() => Contact, { + onUpdate: "CASCADE", + onDelete: "CASCADE", + hooks: true + }) + contacts: Contact[]; + + @HasMany(() => Setting, { + onUpdate: "CASCADE", + onDelete: "CASCADE", + hooks: true + }) + settings: Setting[]; + + @HasMany(() => Ticket, { + onUpdate: "CASCADE", + onDelete: "CASCADE", + hooks: true + }) + tickets: Ticket[]; + + @HasMany(() => TicketTraking, { + onUpdate: "CASCADE", + onDelete: "CASCADE", + hooks: true + }) + ticketTrankins: TicketTraking[]; +} + +export default Company; diff --git a/backend/src/models/Contact.ts b/backend/src/models/Contact.ts new file mode 100644 index 0000000..9ef41d9 --- /dev/null +++ b/backend/src/models/Contact.ts @@ -0,0 +1,84 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + AutoIncrement, + AllowNull, + Unique, + Default, + HasMany, + ForeignKey, + BelongsTo +} from "sequelize-typescript"; +import ContactCustomField from "./ContactCustomField"; +import Ticket from "./Ticket"; +import Company from "./Company"; +import Schedule from "./Schedule"; +import Whatsapp from "./Whatsapp"; + +@Table +class Contact extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column + name: string; + + @AllowNull(false) + @Unique + @Column + number: string; + + @AllowNull(false) + @Default("") + @Column + email: string; + + @Default("") + @Column + profilePicUrl: string; + + @Default(false) + @Column + isGroup: boolean; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @HasMany(() => Ticket) + tickets: Ticket[]; + + @HasMany(() => ContactCustomField) + extraInfo: ContactCustomField[]; + + @ForeignKey(() => Company) + @Column + companyId: number; + + @BelongsTo(() => Company) + company: Company; + + @HasMany(() => Schedule, { + onUpdate: "CASCADE", + onDelete: "CASCADE", + hooks: true + }) + schedules: Schedule[]; + + @ForeignKey(() => Whatsapp) + @Column + whatsappId: number; + + @BelongsTo(() => Whatsapp) + whatsapp: Whatsapp; +} + +export default Contact; diff --git a/backend/src/models/ContactCustomField.ts b/backend/src/models/ContactCustomField.ts new file mode 100644 index 0000000..f4a9ebe --- /dev/null +++ b/backend/src/models/ContactCustomField.ts @@ -0,0 +1,41 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + AutoIncrement, + ForeignKey, + BelongsTo +} from "sequelize-typescript"; +import Contact from "./Contact"; + +@Table +class ContactCustomField extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column + name: string; + + @Column + value: string; + + @ForeignKey(() => Contact) + @Column + contactId: number; + + @BelongsTo(() => Contact) + contact: Contact; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; +} + +export default ContactCustomField; diff --git a/backend/src/models/ContactList.ts b/backend/src/models/ContactList.ts new file mode 100644 index 0000000..c1b500c --- /dev/null +++ b/backend/src/models/ContactList.ts @@ -0,0 +1,47 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + AutoIncrement, + ForeignKey, + BelongsTo, + HasMany +} from "sequelize-typescript"; +import Company from "./Company"; +import ContactListItem from "./ContactListItem"; + +@Table({ tableName: "ContactLists" }) +class ContactList extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column + name: string; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @ForeignKey(() => Company) + @Column + companyId: number; + + @BelongsTo(() => Company) + company: Company; + + @HasMany(() => ContactListItem, { + onUpdate: "CASCADE", + onDelete: "CASCADE", + hooks: true + }) + contacts: ContactListItem[]; +} + +export default ContactList; diff --git a/backend/src/models/ContactListItem.ts b/backend/src/models/ContactListItem.ts new file mode 100644 index 0000000..7eecc98 --- /dev/null +++ b/backend/src/models/ContactListItem.ts @@ -0,0 +1,61 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + AutoIncrement, + AllowNull, + Default, + ForeignKey, + BelongsTo +} from "sequelize-typescript"; +import Company from "./Company"; +import ContactList from "./ContactList"; + +@Table({ tableName: "ContactListItems" }) +class ContactListItem extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @AllowNull(false) + @Column + name: string; + + @AllowNull(false) + @Column + number: string; + + @AllowNull(false) + @Default("") + @Column + email: string; + + @Column + isWhatsappValid: boolean; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @ForeignKey(() => Company) + @Column + companyId: number; + + @BelongsTo(() => Company) + company: Company; + + @ForeignKey(() => ContactList) + @Column + contactListId: number; + + @BelongsTo(() => ContactList) + contactList: ContactList; +} + +export default ContactListItem; diff --git a/backend/src/models/Files.ts b/backend/src/models/Files.ts new file mode 100644 index 0000000..2693b79 --- /dev/null +++ b/backend/src/models/Files.ts @@ -0,0 +1,44 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + AutoIncrement, + HasMany, + ForeignKey +} from "sequelize-typescript"; +import Company from "./Company"; +import FilesOptions from "./FilesOptions"; + +@Table({ + tableName: "Files" +}) +class Files extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @ForeignKey(() => Company) + @Column + companyId: number; + + @Column + name: string; + + @Column + message: string; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @HasMany(() => FilesOptions) + options: FilesOptions[]; +} + +export default Files; diff --git a/backend/src/models/FilesOptions.ts b/backend/src/models/FilesOptions.ts new file mode 100644 index 0000000..d4ce956 --- /dev/null +++ b/backend/src/models/FilesOptions.ts @@ -0,0 +1,46 @@ +import { + Table, + Column, + Model, + ForeignKey, + PrimaryKey, + AutoIncrement, + CreatedAt, + UpdatedAt, + BelongsTo +} from "sequelize-typescript"; +import Files from "./Files"; + +@Table({ + tableName: "FilesOptions" +}) +class FilesOptions extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @ForeignKey(() => Files) + @Column + fileId: number; + + @Column + name: string; + + @Column + path: string; + + @Column + mediaType: string; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @BelongsTo(() => Files) + file: Files; +} + +export default FilesOptions; diff --git a/backend/src/models/Help.ts b/backend/src/models/Help.ts new file mode 100644 index 0000000..cbbf17e --- /dev/null +++ b/backend/src/models/Help.ts @@ -0,0 +1,39 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + AutoIncrement +} from "sequelize-typescript"; + +@Table({ + tableName: "Helps" +}) +class Help extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column + title: string; + + @Column + description: string; + + @Column + video: string; + + @Column + link: string; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; +} + +export default Help; diff --git a/backend/src/models/Invoices.ts b/backend/src/models/Invoices.ts new file mode 100644 index 0000000..8a855a5 --- /dev/null +++ b/backend/src/models/Invoices.ts @@ -0,0 +1,44 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + AutoIncrement, + AllowNull, + HasMany, + Unique +} from "sequelize-typescript"; + +@Table({ tableName: "Invoices" }) +class Invoices extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column + detail: string; + + @Column + status: string; + + @Column + value: number; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @Column + dueDate: string; + + @Column + companyId: number; + +} + +export default Invoices; diff --git a/backend/src/models/Message.ts b/backend/src/models/Message.ts new file mode 100644 index 0000000..b354fec --- /dev/null +++ b/backend/src/models/Message.ts @@ -0,0 +1,113 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + DataType, + PrimaryKey, + Default, + BelongsTo, + ForeignKey +} from "sequelize-typescript"; +import Contact from "./Contact"; +import Ticket from "./Ticket"; +import Company from "./Company"; +import Queue from "./Queue"; + +@Table +class Message extends Model { + @PrimaryKey + @Column + id: string; + + @Column(DataType.STRING) + remoteJid: string; + + @Column(DataType.STRING) + participant: string; + + @Column(DataType.STRING) + dataJson: string; + + @Default(0) + @Column + ack: number; + + @Default(false) + @Column + read: boolean; + + @Default(false) + @Column + fromMe: boolean; + + @Column(DataType.TEXT) + body: string; + + @Column(DataType.STRING) + get mediaUrl(): string | null { + if (this.getDataValue("mediaUrl")) { + return `${process.env.BACKEND_URL}/public/${this.getDataValue( + "mediaUrl" + )}`; + } + return null; + } + + @Column + mediaType: string; + + @Default(false) + @Column + isDeleted: boolean; + + @CreatedAt + @Column(DataType.DATE(6)) + createdAt: Date; + + @UpdatedAt + @Column(DataType.DATE(6)) + updatedAt: Date; + + @ForeignKey(() => Message) + @Column + quotedMsgId: string; + + @BelongsTo(() => Message, "quotedMsgId") + quotedMsg: Message; + + @ForeignKey(() => Ticket) + @Column + ticketId: number; + + @BelongsTo(() => Ticket) + ticket: Ticket; + + @ForeignKey(() => Contact) + @Column + contactId: number; + + @BelongsTo(() => Contact, "contactId") + contact: Contact; + + @ForeignKey(() => Company) + @Column + companyId: number; + + @BelongsTo(() => Company) + company: Company; + + @ForeignKey(() => Queue) + @Column + queueId: number; + + @BelongsTo(() => Queue) + queue: Queue; + + @Default(false) + @Column + isEdited: boolean; +} + +export default Message; diff --git a/backend/src/models/Plan.ts b/backend/src/models/Plan.ts new file mode 100644 index 0000000..d6ece13 --- /dev/null +++ b/backend/src/models/Plan.ts @@ -0,0 +1,65 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + AutoIncrement, + AllowNull, + Unique +} from "sequelize-typescript"; + +@Table +class Plan extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @AllowNull(false) + @Unique + @Column + name: string; + + @Column + users: number; + + @Column + connections: number; + + @Column + queues: number; + + @Column + value: number; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @Column + useSchedules: boolean; + + @Column + useCampaigns: boolean; + + @Column + useInternalChat: boolean; + + @Column + useExternalApi: boolean; + + @Column + useKanban: boolean; + + @Column + useOpenAi: boolean; + + @Column + useIntegrations: boolean; +} + +export default Plan; diff --git a/backend/src/models/Prompt.ts b/backend/src/models/Prompt.ts new file mode 100644 index 0000000..88a9375 --- /dev/null +++ b/backend/src/models/Prompt.ts @@ -0,0 +1,87 @@ +import { + AllowNull, + AutoIncrement, + BelongsTo, + Column, + CreatedAt, + ForeignKey, + Model, + PrimaryKey, + Table, + UpdatedAt +} from "sequelize-typescript"; +import Queue from "./Queue"; +import Company from "./Company"; + +@Table +class Prompt extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @AllowNull(false) + @Column + name: string; + + @AllowNull(false) + @Column + prompt: string; + + @AllowNull(false) + @Column + apiKey: string; + + @Column({ defaultValue: 10 }) + maxMessages: number; + + @Column({ defaultValue: 100 }) + maxTokens: number; + + @Column({ defaultValue: 1 }) + temperature: number; + + @Column({ defaultValue: 0 }) + promptTokens: number; + + @Column({ defaultValue: 0 }) + completionTokens: number; + + @Column({ defaultValue: 0 }) + totalTokens: number; + + @AllowNull(false) + @Column + voice: string; + + @AllowNull(true) + @Column + voiceKey:string; + + @AllowNull(true) + @Column + voiceRegion:string; + + @AllowNull + @ForeignKey(() => Queue) + @Column + queueId: number; + + @BelongsTo(() => Queue) + queue: Queue; + + @ForeignKey(() => Company) + @Column + companyId: number; + + @BelongsTo(() => Company) + company: Company; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; +} + +export default Prompt; diff --git a/backend/src/models/Queue.ts b/backend/src/models/Queue.ts new file mode 100644 index 0000000..c32a16b --- /dev/null +++ b/backend/src/models/Queue.ts @@ -0,0 +1,103 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + AutoIncrement, + AllowNull, + Unique, + BelongsToMany, + BelongsTo, + ForeignKey, + HasMany, + DataType, + Default +} from "sequelize-typescript"; +import User from "./User"; +import UserQueue from "./UserQueue"; +import Company from "./Company"; + +import Whatsapp from "./Whatsapp"; +import WhatsappQueue from "./WhatsappQueue"; +import QueueOption from "./QueueOption"; +import Prompt from "./Prompt"; +import QueueIntegrations from "./QueueIntegrations"; + +@Table +class Queue extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @AllowNull(false) + @Unique + @Column + name: string; + + @AllowNull(false) + @Unique + @Column + color: string; + + @Default("") + @Column + greetingMessage: string; + + @Default("") + @Column + outOfHoursMessage: string; + + @Column({ + type: DataType.JSONB + }) + schedules: []; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @ForeignKey(() => Company) + @Column + companyId: number; + + @BelongsTo(() => Company) + company: Company; + + @BelongsToMany(() => Whatsapp, () => WhatsappQueue) + whatsapps: Array; + + @BelongsToMany(() => User, () => UserQueue) + users: Array; + + @HasMany(() => QueueOption, { + onDelete: "DELETE", + onUpdate: "DELETE", + hooks: true + }) + options: QueueOption[]; + + @Column + orderQueue: number; + + + @ForeignKey(() => QueueIntegrations) + @Column + integrationId: number; + + @BelongsTo(() => QueueIntegrations) + queueIntegrations: QueueIntegrations; + + @ForeignKey(() => Prompt) + @Column + promptId: number; + + @BelongsTo(() => Prompt) + prompt: Prompt; +} + +export default Queue; diff --git a/backend/src/models/QueueIntegrations.ts b/backend/src/models/QueueIntegrations.ts new file mode 100644 index 0000000..9412094 --- /dev/null +++ b/backend/src/models/QueueIntegrations.ts @@ -0,0 +1,82 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + DataType, + PrimaryKey, + HasMany, + AutoIncrement, + BelongsTo, + ForeignKey, + Default +} from "sequelize-typescript"; +import Queue from "./Queue"; +import Company from "./Company"; + +@Table +class QueueIntegrations extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column(DataType.TEXT) + type: string; + + @Column(DataType.TEXT) + name: string; + + @Column(DataType.TEXT) + projectName: string; + + @Column(DataType.TEXT) + jsonContent: string; + + @Column(DataType.TEXT) + urlN8N: string; + + @Column(DataType.TEXT) + language: string; + + @CreatedAt + @Column(DataType.DATE(6)) + createdAt: Date; + + @UpdatedAt + @Column(DataType.DATE(6)) + updatedAt: Date; + + @ForeignKey(() => Company) + @Column + companyId: number; + + @BelongsTo(() => Company) + company: Company; + + @Column + typebotSlug: string; + + @Default(0) + @Column + typebotExpires: number; + + @Column + typebotKeywordFinish: string; + + @Column + typebotUnknownMessage: string; + + @Default(1000) + @Column + typebotDelayMessage: number + + @Column + typebotKeywordRestart: string; + + @Column + typebotRestartMessage: string; +} + +export default QueueIntegrations; \ No newline at end of file diff --git a/backend/src/models/QueueOption.ts b/backend/src/models/QueueOption.ts new file mode 100644 index 0000000..c8f0cce --- /dev/null +++ b/backend/src/models/QueueOption.ts @@ -0,0 +1,54 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + AutoIncrement, + ForeignKey, + BelongsTo, + AllowNull +} from "sequelize-typescript"; +import Queue from "./Queue"; + +@Table +class QueueOption extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column + title: string; + + @AllowNull + @Column + message: string; + + @AllowNull + @Column + option: string; + + @ForeignKey(() => Queue) + @Column + queueId: number; + + @ForeignKey(() => QueueOption) + @Column + parentId: number; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @BelongsTo(() => Queue) + queue: Queue; + + @BelongsTo(() => QueueOption, { foreignKey: 'parentId' }) + parent: QueueOption; +} + +export default QueueOption; diff --git a/backend/src/models/QuickMessage.ts b/backend/src/models/QuickMessage.ts new file mode 100644 index 0000000..3aebb3b --- /dev/null +++ b/backend/src/models/QuickMessage.ts @@ -0,0 +1,63 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + ForeignKey, + BelongsTo, + AutoIncrement +} from "sequelize-typescript"; + +import Company from "./Company"; +import User from "./User"; + +@Table +class QuickMessage extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column + shortcode: string; + + @Column + message: string; + + @ForeignKey(() => Company) + @Column + companyId: number; + + @ForeignKey(() => User) + @Column + userId: number; + + @BelongsTo(() => Company) + company: Company; + + @BelongsTo(() => User) + user: User; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @Column + get mediaPath(): string | null { + if (this.getDataValue("mediaPath")) { + + return `${process.env.BACKEND_URL}${process.env.PROXY_PORT ?`:${process.env.PROXY_PORT}`:""}/public/quickMessage/${this.getDataValue("mediaPath")}`; + + } + return null; + } + + @Column + mediaName: string; +} + +export default QuickMessage; diff --git a/backend/src/models/Schedule.ts b/backend/src/models/Schedule.ts new file mode 100644 index 0000000..3dca703 --- /dev/null +++ b/backend/src/models/Schedule.ts @@ -0,0 +1,78 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + AutoIncrement, + DataType, + BelongsTo, + ForeignKey +} from "sequelize-typescript"; +import Company from "./Company"; +import Contact from "./Contact"; +import Ticket from "./Ticket"; +import User from "./User"; + +@Table +class Schedule extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column(DataType.TEXT) + body: string; + + @Column + sendAt: Date; + + @Column + sentAt: Date; + + @ForeignKey(() => Contact) + @Column + contactId: number; + + @ForeignKey(() => Ticket) + @Column + ticketId: number; + + @ForeignKey(() => User) + @Column + userId: number; + + @ForeignKey(() => Company) + @Column + companyId: number; + + @Column(DataType.STRING) + status: string; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @BelongsTo(() => Contact, "contactId") + contact: Contact; + + @BelongsTo(() => Ticket) + ticket: Ticket; + + @BelongsTo(() => User) + user: User; + + @BelongsTo(() => Company) + company: Company; + + @Column + mediaPath: string; + + @Column + mediaName: string; +} + +export default Schedule; diff --git a/backend/src/models/Setting.ts b/backend/src/models/Setting.ts new file mode 100644 index 0000000..9b74978 --- /dev/null +++ b/backend/src/models/Setting.ts @@ -0,0 +1,42 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + ForeignKey, + BelongsTo, + AutoIncrement +} from "sequelize-typescript"; + +import Company from "./Company"; + +@Table +class Setting extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column + key: string; + + @Column + value: string; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @ForeignKey(() => Company) + @Column + companyId: number; + + @BelongsTo(() => Company) + company: Company; +} + +export default Setting; diff --git a/backend/src/models/Subscriptions.ts b/backend/src/models/Subscriptions.ts new file mode 100644 index 0000000..e099d03 --- /dev/null +++ b/backend/src/models/Subscriptions.ts @@ -0,0 +1,56 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + AutoIncrement, + AllowNull +} from "sequelize-typescript"; + +@Table +class Subscriptions extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column + isActive: boolean; + + @AllowNull(true) + @Column + userPriceCents: number; + + @AllowNull(true) + @Column + whatsPriceCents: number; + + @AllowNull(true) + @Column + lastInvoiceUrl: string; + + @AllowNull(true) + @Column + lastPlanChange: Date; + + @AllowNull(true) + @Column + expiresAt: Date; + + @AllowNull(true) + @Column + providerSubscriptionId: string; + + @Column + companyId: number; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; +} + +export default Subscriptions; diff --git a/backend/src/models/Tag.ts b/backend/src/models/Tag.ts new file mode 100644 index 0000000..793f231 --- /dev/null +++ b/backend/src/models/Tag.ts @@ -0,0 +1,54 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + AutoIncrement, + BelongsToMany, + ForeignKey, + BelongsTo, + HasMany +} from "sequelize-typescript"; +import Company from "./Company"; +import Ticket from "./Ticket"; +import TicketTag from "./TicketTag"; + +@Table +class Tag extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column + name: string; + + @Column + color: string; + + @HasMany(() => TicketTag) + ticketTags: TicketTag[]; + + @BelongsToMany(() => Ticket, () => TicketTag) + tickets: Ticket[]; + + @ForeignKey(() => Company) + @Column + companyId: number; + + @BelongsTo(() => Company) + company: Company; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @Column + kanban: number; +} + +export default Tag; diff --git a/backend/src/models/Ticket.ts b/backend/src/models/Ticket.ts new file mode 100644 index 0000000..2e350eb --- /dev/null +++ b/backend/src/models/Ticket.ts @@ -0,0 +1,154 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + ForeignKey, + BelongsTo, + HasMany, + AutoIncrement, + Default, + BeforeCreate, + BelongsToMany, + AllowNull +} from "sequelize-typescript"; +import { v4 as uuidv4 } from "uuid"; + +import Contact from "./Contact"; +import Message from "./Message"; +import Queue from "./Queue"; +import User from "./User"; +import Whatsapp from "./Whatsapp"; +import Company from "./Company"; +import QueueOption from "./QueueOption"; +import Tag from "./Tag"; +import TicketTag from "./TicketTag"; +import QueueIntegrations from "./QueueIntegrations"; +import Prompt from "./Prompt"; + +@Table +class Ticket extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column({ defaultValue: "pending" }) + status: string; + + @Column + unreadMessages: number; + + @Column + lastMessage: string; + + @Default(false) + @Column + isGroup: boolean; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @ForeignKey(() => User) + @Column + userId: number; + + @BelongsTo(() => User) + user: User; + + @ForeignKey(() => Contact) + @Column + contactId: number; + + @BelongsTo(() => Contact) + contact: Contact; + + @ForeignKey(() => Whatsapp) + @Column + whatsappId: number; + + @BelongsTo(() => Whatsapp) + whatsapp: Whatsapp; + + @ForeignKey(() => Queue) + @Column + queueId: number; + + @BelongsTo(() => Queue) + queue: Queue; + + @Column + chatbot: boolean; + + @ForeignKey(() => QueueOption) + @Column + queueOptionId: number; + + @BelongsTo(() => QueueOption) + queueOption: QueueOption; + + @HasMany(() => Message) + messages: Message[]; + + @HasMany(() => TicketTag) + ticketTags: TicketTag[]; + + @BelongsToMany(() => Tag, () => TicketTag) + tags: Tag[]; + + @ForeignKey(() => Company) + @Column + companyId: number; + + @BelongsTo(() => Company) + company: Company; + + @Default(uuidv4()) + @Column + uuid: string; + + @BeforeCreate + static setUUID(ticket: Ticket) { + ticket.uuid = uuidv4(); + } + + @Default(false) + @Column + useIntegration: boolean; + + @ForeignKey(() => QueueIntegrations) + @Column + integrationId: number; + + @BelongsTo(() => QueueIntegrations) + queueIntegration: QueueIntegrations; + + @Column + typebotSessionId: string; + + @Default(false) + @Column + typebotStatus: boolean + + @ForeignKey(() => Prompt) + @Column + promptId: number; + + @BelongsTo(() => Prompt) + prompt: Prompt; + + @Column + fromMe: boolean; + + @AllowNull(false) + @Default(0) + @Column + amountUsedBotQueues: number; +} + +export default Ticket; diff --git a/backend/src/models/TicketNote.ts b/backend/src/models/TicketNote.ts new file mode 100644 index 0000000..621a15b --- /dev/null +++ b/backend/src/models/TicketNote.ts @@ -0,0 +1,55 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + ForeignKey, + BelongsTo, + AutoIncrement +} from "sequelize-typescript"; + +import Contact from "./Contact"; +import User from "./User"; +import Ticket from "./Ticket"; + +@Table +class TicketNote extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column + note: string; + + @ForeignKey(() => User) + @Column + userId: number; + + @BelongsTo(() => User) + user: User; + + @ForeignKey(() => Contact) + @Column + contactId: number; + + @BelongsTo(() => Contact) + contact: Contact; + + @ForeignKey(() => Ticket) + @Column + ticketId: number; + + @BelongsTo(() => Ticket) + ticket: Ticket; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; +} + +export default TicketNote; diff --git a/backend/src/models/TicketTag.ts b/backend/src/models/TicketTag.ts new file mode 100644 index 0000000..55b4bb0 --- /dev/null +++ b/backend/src/models/TicketTag.ts @@ -0,0 +1,38 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + ForeignKey, + BelongsTo +} from "sequelize-typescript"; +import Tag from "./Tag"; +import Ticket from "./Ticket"; + +@Table({ + tableName: 'TicketTags' +}) +class TicketTag extends Model { + @ForeignKey(() => Ticket) + @Column + ticketId: number; + + @ForeignKey(() => Tag) + @Column + tagId: number; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @BelongsTo(() => Ticket) + ticket: Ticket; + + @BelongsTo(() => Tag) + tag: Tag; +} + +export default TicketTag; diff --git a/backend/src/models/TicketTraking.ts b/backend/src/models/TicketTraking.ts new file mode 100644 index 0000000..d523102 --- /dev/null +++ b/backend/src/models/TicketTraking.ts @@ -0,0 +1,80 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + ForeignKey, + BelongsTo, + AutoIncrement +} from "sequelize-typescript"; + +import Company from "./Company"; +import User from "./User"; +import Ticket from "./Ticket"; +import Whatsapp from "./Whatsapp"; + +@Table({ + tableName: "TicketTraking" +}) +class TicketTraking extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @ForeignKey(() => Ticket) + @Column + ticketId: number; + + @BelongsTo(() => Ticket) + ticket: Ticket; + + @ForeignKey(() => Company) + @Column + companyId: number; + + @BelongsTo(() => Company) + company: Company; + + @ForeignKey(() => Whatsapp) + @Column + whatsappId: number; + + @BelongsTo(() => Whatsapp) + whatsapp: Whatsapp; + + @ForeignKey(() => User) + @Column + userId: number; + + @Column + rated: boolean; + + @BelongsTo(() => User) + user: User; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @Column + startedAt: Date; + + @Column + queuedAt: Date; + + @Column + finishedAt: Date; + + @Column + ratingAt: Date; + + @Column + chatbotAt: Date; +} + +export default TicketTraking; diff --git a/backend/src/models/User.ts b/backend/src/models/User.ts new file mode 100644 index 0000000..8da2ae3 --- /dev/null +++ b/backend/src/models/User.ts @@ -0,0 +1,108 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + DataType, + BeforeCreate, + BeforeUpdate, + PrimaryKey, + AutoIncrement, + Default, + HasMany, + BelongsToMany, + ForeignKey, + BelongsTo +} from "sequelize-typescript"; +import { hash, compare } from "bcryptjs"; +import Ticket from "./Ticket"; +import Queue from "./Queue"; +import UserQueue from "./UserQueue"; +import Company from "./Company"; +import QuickMessage from "./QuickMessage"; +import Whatsapp from "./Whatsapp"; + +@Table +class User extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column + name: string; + + @Column + email: string; + + @Column + allTicket: string; + + @Column(DataType.VIRTUAL) + password: string; + + @Column + passwordHash: string; + + @Default(0) + @Column + tokenVersion: number; + + @Default("admin") + @Column + profile: string; + + @Column + super: boolean; + + @Column + online: boolean; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @ForeignKey(() => Company) + @Column + companyId: number; + + @BelongsTo(() => Company) + company: Company; + + @HasMany(() => Ticket) + tickets: Ticket[]; + + @BelongsToMany(() => Queue, () => UserQueue) + queues: Queue[]; + + @HasMany(() => QuickMessage, { + onUpdate: "CASCADE", + onDelete: "CASCADE", + hooks: true + }) + quickMessages: QuickMessage[]; + + @ForeignKey(() => Whatsapp) + @Column + whatsappId: number; + + @BelongsTo(() => Whatsapp) + whatsapp: Whatsapp; + + @BeforeUpdate + @BeforeCreate + static hashPassword = async (instance: User): Promise => { + if (instance.password) { + instance.passwordHash = await hash(instance.password, 8); + } + }; + + public checkPassword = async (password: string): Promise => { + return compare(password, this.getDataValue("passwordHash")); + }; +} + +export default User; diff --git a/backend/src/models/UserQueue.ts b/backend/src/models/UserQueue.ts new file mode 100644 index 0000000..17528c2 --- /dev/null +++ b/backend/src/models/UserQueue.ts @@ -0,0 +1,29 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + ForeignKey +} from "sequelize-typescript"; +import Queue from "./Queue"; +import User from "./User"; + +@Table +class UserQueue extends Model { + @ForeignKey(() => User) + @Column + userId: number; + + @ForeignKey(() => Queue) + @Column + queueId: number; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; +} + +export default UserQueue; diff --git a/backend/src/models/UserRating.ts b/backend/src/models/UserRating.ts new file mode 100644 index 0000000..9f033e4 --- /dev/null +++ b/backend/src/models/UserRating.ts @@ -0,0 +1,58 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + PrimaryKey, + ForeignKey, + BelongsTo, + AutoIncrement + } from "sequelize-typescript"; + + import Company from "./Company"; + import User from "./User"; + import Ticket from "./Ticket"; + + @Table({ + tableName: "UserRatings" + }) + class UserRating extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @ForeignKey(() => Ticket) + @Column + ticketId: number; + + @BelongsTo(() => Ticket) + ticket: Ticket; + + @ForeignKey(() => Company) + @Column + companyId: number; + + @BelongsTo(() => Company) + company: Company; + + @ForeignKey(() => User) + @Column + userId: number; + + @BelongsTo(() => User) + user: User; + + @Column + rate: number; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + } + + export default UserRating; + \ No newline at end of file diff --git a/backend/src/models/Whatsapp.ts b/backend/src/models/Whatsapp.ts new file mode 100644 index 0000000..8f0d076 --- /dev/null +++ b/backend/src/models/Whatsapp.ts @@ -0,0 +1,148 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + DataType, + PrimaryKey, + AutoIncrement, + Default, + AllowNull, + HasMany, + Unique, + BelongsToMany, + ForeignKey, + BelongsTo +} from "sequelize-typescript"; +import Queue from "./Queue"; +import Ticket from "./Ticket"; +import WhatsappQueue from "./WhatsappQueue"; +import Company from "./Company"; +import Prompt from "./Prompt"; +import QueueIntegrations from "./QueueIntegrations"; + +@Table +class Whatsapp extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @AllowNull + @Unique + @Column(DataType.TEXT) + name: string; + + @Column(DataType.TEXT) + session: string; + + @Column(DataType.TEXT) + qrcode: string; + + @Column + status: string; + + @Column + battery: string; + + @Column + plugged: boolean; + + @Column + retries: number; + + @Default("") + @Column(DataType.TEXT) + greetingMessage: string; + + @Default("") + @Column(DataType.TEXT) + farewellMessage: string; + + @Default("") + @Column(DataType.TEXT) + complationMessage: string; + + @Default("") + @Column(DataType.TEXT) + outOfHoursMessage: string; + + @Default("") + @Column(DataType.TEXT) + ratingMessage: string; + + @Column({ defaultValue: "stable" }) + provider: string; + + @Default(false) + @AllowNull + @Column + isDefault: boolean; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @HasMany(() => Ticket) + tickets: Ticket[]; + + @BelongsToMany(() => Queue, () => WhatsappQueue) + queues: Array; + + @HasMany(() => WhatsappQueue) + whatsappQueues: WhatsappQueue[]; + + @ForeignKey(() => Company) + @Column + companyId: number; + + @BelongsTo(() => Company) + company: Company; + + @Column + token: string; + + //@Default(0) + //@Column + //timeSendQueue: number; + + //@Column + //sendIdQueue: number; + + @Column + transferQueueId: number; + + @Column + timeToTransfer: number; + + @ForeignKey(() => Prompt) + @Column + promptId: number; + + @BelongsTo(() => Prompt) + prompt: Prompt; + + @ForeignKey(() => QueueIntegrations) + @Column + integrationId: number; + + @BelongsTo(() => QueueIntegrations) + queueIntegrations: QueueIntegrations; + + @Column + maxUseBotQueues: number; + + @Column + timeUseBotQueues: string; + + @Column + expiresTicket: number; + + @Column + expiresInactiveMessage: string; +} + +export default Whatsapp; diff --git a/backend/src/models/WhatsappQueue.ts b/backend/src/models/WhatsappQueue.ts new file mode 100644 index 0000000..b68aaa0 --- /dev/null +++ b/backend/src/models/WhatsappQueue.ts @@ -0,0 +1,33 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + ForeignKey, + BelongsTo +} from "sequelize-typescript"; +import Queue from "./Queue"; +import Whatsapp from "./Whatsapp"; + +@Table +class WhatsappQueue extends Model { + @ForeignKey(() => Whatsapp) + @Column + whatsappId: number; + + @ForeignKey(() => Queue) + @Column + queueId: number; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; + + @BelongsTo(() => Queue) + queue: Queue; +} + +export default WhatsappQueue; diff --git a/backend/src/queues.ts b/backend/src/queues.ts new file mode 100644 index 0000000..b2d9fe9 --- /dev/null +++ b/backend/src/queues.ts @@ -0,0 +1,930 @@ +import * as Sentry from "@sentry/node"; +import BullQueue from "bull"; +import { MessageData, SendMessage } from "./helpers/SendMessage"; +import Whatsapp from "./models/Whatsapp"; +import { logger } from "./utils/logger"; +import moment from "moment"; +import Schedule from "./models/Schedule"; +import Contact from "./models/Contact"; +import { Op, QueryTypes, Sequelize } from "sequelize"; +import GetDefaultWhatsApp from "./helpers/GetDefaultWhatsApp"; +import Campaign from "./models/Campaign"; +import ContactList from "./models/ContactList"; +import ContactListItem from "./models/ContactListItem"; +import { isEmpty, isNil, isArray } from "lodash"; +import CampaignSetting from "./models/CampaignSetting"; +import CampaignShipping from "./models/CampaignShipping"; +import GetWhatsappWbot from "./helpers/GetWhatsappWbot"; +import sequelize from "./database"; +import { getMessageOptions } from "./services/WbotServices/SendWhatsAppMedia"; +import { getIO } from "./libs/socket"; +import path from "path"; +import User from "./models/User"; +import Company from "./models/Company"; +import Plan from "./models/Plan"; +import Ticket from "./models/Ticket"; +import ShowFileService from "./services/FileServices/ShowService"; +import FilesOptions from './models/FilesOptions'; +import { addSeconds, differenceInSeconds } from "date-fns"; +import formatBody from "./helpers/Mustache"; +import { ClosedAllOpenTickets } from "./services/WbotServices/wbotClosedTickets"; + + +const nodemailer = require('nodemailer'); +const CronJob = require('cron').CronJob; + +const connection = process.env.REDIS_URI || ""; +const limiterMax = process.env.REDIS_OPT_LIMITER_MAX || 1; +const limiterDuration = process.env.REDIS_OPT_LIMITER_DURATION || 3000; + +interface ProcessCampaignData { + id: number; + delay: number; +} + +interface PrepareContactData { + contactId: number; + campaignId: number; + delay: number; + variables: any[]; +} + +interface DispatchCampaignData { + campaignId: number; + campaignShippingId: number; + contactListItemId: number; +} + +export const userMonitor = new BullQueue("UserMonitor", connection); + +export const queueMonitor = new BullQueue("QueueMonitor", connection); + +export const messageQueue = new BullQueue("MessageQueue", connection, { + limiter: { + max: limiterMax as number, + duration: limiterDuration as number + } +}); + +export const scheduleMonitor = new BullQueue("ScheduleMonitor", connection); +export const sendScheduledMessages = new BullQueue( + "SendSacheduledMessages", + connection +); + +export const campaignQueue = new BullQueue("CampaignQueue", connection); + +async function handleSendMessage(job) { + try { + const { data } = job; + + const whatsapp = await Whatsapp.findByPk(data.whatsappId); + + if (whatsapp == null) { + throw Error("Whatsapp não identificado"); + } + + const messageData: MessageData = data.data; + + await SendMessage(whatsapp, messageData); + } catch (e: any) { + Sentry.captureException(e); + logger.error("MessageQueue -> SendMessage: error", e.message); + throw e; + } +} + +{/*async function handleVerifyQueue(job) { + logger.info("Buscando atendimentos perdidos nas filas"); + try { + const companies = await Company.findAll({ + attributes: ['id', 'name'], + where: { + status: true, + dueDate: { + [Op.gt]: Sequelize.literal('CURRENT_DATE') + } + }, + include: [ + { + model: Whatsapp, attributes: ["id", "name", "status", "timeSendQueue", "sendIdQueue"], where: { + timeSendQueue: { + [Op.gt]: 0 + } + } + }, + ] + }); */} + +{/* companies.map(async c => { + c.whatsapps.map(async w => { + + if (w.status === "CONNECTED") { + + var companyId = c.id; + + const moveQueue = w.timeSendQueue ? w.timeSendQueue : 0; + const moveQueueId = w.sendIdQueue; + const moveQueueTime = moveQueue; + const idQueue = moveQueueId; + const timeQueue = moveQueueTime; + + if (moveQueue > 0) { + + if (!isNaN(idQueue) && Number.isInteger(idQueue) && !isNaN(timeQueue) && Number.isInteger(timeQueue)) { + + const tempoPassado = moment().subtract(timeQueue, "minutes").utc().format(); + // const tempoAgora = moment().utc().format(); + + const { count, rows: tickets } = await Ticket.findAndCountAll({ + where: { + status: "pending", + queueId: null, + companyId: companyId, + whatsappId: w.id, + updatedAt: { + [Op.lt]: tempoPassado + } + }, + include: [ + { + model: Contact, + as: "contact", + attributes: ["id", "name", "number", "email", "profilePicUrl"], + include: ["extraInfo"] + } + ] + }); + + if (count > 0) { + tickets.map(async ticket => { + await ticket.update({ + queueId: idQueue + }); + + await ticket.reload(); + + const io = getIO(); + io.to(ticket.status) + .to("notification") + .to(ticket.id.toString()) + .emit(`company-${companyId}-ticket`, { + action: "update", + ticket, + ticketId: ticket.id + }); + + // io.to("pending").emit(`company-${companyId}-ticket`, { + // action: "update", + // ticket, + // }); + + logger.info(`Atendimento Perdido: ${ticket.id} - Empresa: ${companyId}`); + }); + } else { + logger.info(`Nenhum atendimento perdido encontrado - Empresa: ${companyId}`); + } + } else { + logger.info(`Condição não respeitada - Empresa: ${companyId}`); + } + } + } + }); + }); + } catch (e: any) { + Sentry.captureException(e); + logger.error("SearchForQueue -> VerifyQueue: error", e.message); + throw e; + } +}; */} + +async function handleCloseTicketsAutomatic() { + const job = new CronJob('*/1 * * * *', async () => { + const companies = await Company.findAll(); + companies.map(async c => { + + try { + const companyId = c.id; + await ClosedAllOpenTickets(companyId); + } catch (e: any) { + Sentry.captureException(e); + logger.error("ClosedAllOpenTickets -> Verify: error", e.message); + throw e; + } + + }); + }); + job.start() +} + +async function handleVerifySchedules(job) { + try { + const { count, rows: schedules } = await Schedule.findAndCountAll({ + where: { + status: "PENDENTE", + sentAt: null, + sendAt: { + [Op.gte]: moment().format("YYYY-MM-DD HH:mm:ss"), + [Op.lte]: moment().add("30", "seconds").format("YYYY-MM-DD HH:mm:ss") + } + }, + include: [{ model: Contact, as: "contact" }] + }); + if (count > 0) { + schedules.map(async schedule => { + await schedule.update({ + status: "AGENDADA" + }); + sendScheduledMessages.add( + "SendMessage", + { schedule }, + { delay: 40000 } + ); + logger.info(`Disparo agendado para: ${schedule.contact.name}`); + }); + } + } catch (e: any) { + Sentry.captureException(e); + logger.error("SendScheduledMessage -> Verify: error", e.message); + throw e; + } +} + +async function handleSendScheduledMessage(job) { + const { + data: { schedule } + } = job; + let scheduleRecord: Schedule | null = null; + + try { + scheduleRecord = await Schedule.findByPk(schedule.id); + } catch (e) { + Sentry.captureException(e); + logger.info(`Erro ao tentar consultar agendamento: ${schedule.id}`); + } + + try { + const whatsapp = await GetDefaultWhatsApp(schedule.companyId); + + let filePath = null; + if (schedule.mediaPath) { + filePath = path.resolve("public", schedule.mediaPath); + } + + await SendMessage(whatsapp, { + number: schedule.contact.number, + body: formatBody(schedule.body, schedule.contact), + mediaPath: filePath + }); + + await scheduleRecord?.update({ + sentAt: moment().format("YYYY-MM-DD HH:mm"), + status: "ENVIADA" + }); + + logger.info(`Mensagem agendada enviada para: ${schedule.contact.name}`); + sendScheduledMessages.clean(15000, "completed"); + } catch (e: any) { + Sentry.captureException(e); + await scheduleRecord?.update({ + status: "ERRO" + }); + logger.error("SendScheduledMessage -> SendMessage: error", e.message); + throw e; + } +} + +async function handleVerifyCampaigns(job) { + /** + * @todo + * Implementar filtro de campanhas + */ + const campaigns: { id: number; scheduledAt: string }[] = + await sequelize.query( + `select id, "scheduledAt" from "Campaigns" c + where "scheduledAt" between now() and now() + '1 hour'::interval and status = 'PROGRAMADA'`, + { type: QueryTypes.SELECT } + ); + + if (campaigns.length > 0) + logger.info(`Campanhas encontradas: ${campaigns.length}`); + + for (let campaign of campaigns) { + try { + const now = moment(); + const scheduledAt = moment(campaign.scheduledAt); + const delay = scheduledAt.diff(now, "milliseconds"); + logger.info( + `Campanha enviada para a fila de processamento: Campanha=${campaign.id}, Delay Inicial=${delay}` + ); + campaignQueue.add( + "ProcessCampaign", + { + id: campaign.id, + delay + }, + { + removeOnComplete: true + } + ); + } catch (err: any) { + Sentry.captureException(err); + } + } +} + +async function getCampaign(id) { + return await Campaign.findByPk(id, { + include: [ + { + model: ContactList, + as: "contactList", + attributes: ["id", "name"], + include: [ + { + model: ContactListItem, + as: "contacts", + attributes: ["id", "name", "number", "email", "isWhatsappValid"], + where: { isWhatsappValid: true } + } + ] + }, + { + model: Whatsapp, + as: "whatsapp", + attributes: ["id", "name"] + }, + { + model: CampaignShipping, + as: "shipping", + include: [{ model: ContactListItem, as: "contact" }] + } + ] + }); +} + +async function getContact(id) { + return await ContactListItem.findByPk(id, { + attributes: ["id", "name", "number", "email"] + }); +} + +async function getSettings(campaign) { + const settings = await CampaignSetting.findAll({ + where: { companyId: campaign.companyId }, + attributes: ["key", "value"] + }); + + let messageInterval: number = 20; + let longerIntervalAfter: number = 20; + let greaterInterval: number = 60; + let variables: any[] = []; + + settings.forEach(setting => { + if (setting.key === "messageInterval") { + messageInterval = JSON.parse(setting.value); + } + if (setting.key === "longerIntervalAfter") { + longerIntervalAfter = JSON.parse(setting.value); + } + if (setting.key === "greaterInterval") { + greaterInterval = JSON.parse(setting.value); + } + if (setting.key === "variables") { + variables = JSON.parse(setting.value); + } + }); + + return { + messageInterval, + longerIntervalAfter, + greaterInterval, + variables + }; +} + +export function parseToMilliseconds(seconds) { + return seconds * 1000; +} + +async function sleep(seconds) { + logger.info( + `Sleep de ${seconds} segundos iniciado: ${moment().format("HH:mm:ss")}` + ); + return new Promise(resolve => { + setTimeout(() => { + logger.info( + `Sleep de ${seconds} segundos finalizado: ${moment().format( + "HH:mm:ss" + )}` + ); + resolve(true); + }, parseToMilliseconds(seconds)); + }); +} + +function getCampaignValidMessages(campaign) { + const messages = []; + + if (!isEmpty(campaign.message1) && !isNil(campaign.message1)) { + messages.push(campaign.message1); + } + + if (!isEmpty(campaign.message2) && !isNil(campaign.message2)) { + messages.push(campaign.message2); + } + + if (!isEmpty(campaign.message3) && !isNil(campaign.message3)) { + messages.push(campaign.message3); + } + + if (!isEmpty(campaign.message4) && !isNil(campaign.message4)) { + messages.push(campaign.message4); + } + + if (!isEmpty(campaign.message5) && !isNil(campaign.message5)) { + messages.push(campaign.message5); + } + + return messages; +} + +function getCampaignValidConfirmationMessages(campaign) { + const messages = []; + + if ( + !isEmpty(campaign.confirmationMessage1) && + !isNil(campaign.confirmationMessage1) + ) { + messages.push(campaign.confirmationMessage1); + } + + if ( + !isEmpty(campaign.confirmationMessage2) && + !isNil(campaign.confirmationMessage2) + ) { + messages.push(campaign.confirmationMessage2); + } + + if ( + !isEmpty(campaign.confirmationMessage3) && + !isNil(campaign.confirmationMessage3) + ) { + messages.push(campaign.confirmationMessage3); + } + + if ( + !isEmpty(campaign.confirmationMessage4) && + !isNil(campaign.confirmationMessage4) + ) { + messages.push(campaign.confirmationMessage4); + } + + if ( + !isEmpty(campaign.confirmationMessage5) && + !isNil(campaign.confirmationMessage5) + ) { + messages.push(campaign.confirmationMessage5); + } + + return messages; +} + +function getProcessedMessage(msg: string, variables: any[], contact: any) { + let finalMessage = msg; + + if (finalMessage.includes("{nome}")) { + finalMessage = finalMessage.replace(/{nome}/g, contact.name); + } + + if (finalMessage.includes("{email}")) { + finalMessage = finalMessage.replace(/{email}/g, contact.email); + } + + if (finalMessage.includes("{numero}")) { + finalMessage = finalMessage.replace(/{numero}/g, contact.number); + } + + variables.forEach(variable => { + if (finalMessage.includes(`{${variable.key}}`)) { + const regex = new RegExp(`{${variable.key}}`, "g"); + finalMessage = finalMessage.replace(regex, variable.value); + } + }); + + return finalMessage; +} + +export function randomValue(min, max) { + return Math.floor(Math.random() * max) + min; +} + +async function verifyAndFinalizeCampaign(campaign) { + const { contacts } = campaign.contactList; + + const count1 = contacts.length; + const count2 = await CampaignShipping.count({ + where: { + campaignId: campaign.id, + deliveredAt: { + [Op.not]: null + } + } + }); + + if (count1 === count2) { + await campaign.update({ status: "FINALIZADA", completedAt: moment() }); + } + + const io = getIO(); + io.to(`company-${campaign.companyId}-mainchannel`).emit(`company-${campaign.companyId}-campaign`, { + action: "update", + record: campaign + }); +} + +function calculateDelay(index, baseDelay, longerIntervalAfter, greaterInterval, messageInterval) { + const diffSeconds = differenceInSeconds(baseDelay, new Date()); + if (index > longerIntervalAfter) { + return diffSeconds * 1000 + greaterInterval + } else { + return diffSeconds * 1000 + messageInterval + } +} + +async function handleProcessCampaign(job) { + try { + const { id }: ProcessCampaignData = job.data; + const campaign = await getCampaign(id); + const settings = await getSettings(campaign); + if (campaign) { + const { contacts } = campaign.contactList; + if (isArray(contacts)) { + const contactData = contacts.map(contact => ({ + contactId: contact.id, + campaignId: campaign.id, + variables: settings.variables, + })); + + // const baseDelay = job.data.delay || 0; + const longerIntervalAfter = parseToMilliseconds(settings.longerIntervalAfter); + const greaterInterval = parseToMilliseconds(settings.greaterInterval); + const messageInterval = settings.messageInterval; + + let baseDelay = campaign.scheduledAt; + + const queuePromises = []; + for (let i = 0; i < contactData.length; i++) { + baseDelay = addSeconds(baseDelay, i > longerIntervalAfter ? greaterInterval : messageInterval); + + const { contactId, campaignId, variables } = contactData[i]; + const delay = calculateDelay(i, baseDelay, longerIntervalAfter, greaterInterval, messageInterval); + const queuePromise = campaignQueue.add( + "PrepareContact", + { contactId, campaignId, variables, delay }, + { removeOnComplete: true } + ); + queuePromises.push(queuePromise); + logger.info(`Registro enviado pra fila de disparo: Campanha=${campaign.id};Contato=${contacts[i].name};delay=${delay}`); + } + await Promise.all(queuePromises); + await campaign.update({ status: "EM_ANDAMENTO" }); + } + } + } catch (err: any) { + Sentry.captureException(err); + } +} + +async function handlePrepareContact(job) { + try { + const { contactId, campaignId, delay, variables }: PrepareContactData = + job.data; + const campaign = await getCampaign(campaignId); + const contact = await getContact(contactId); + + const campaignShipping: any = {}; + campaignShipping.number = contact.number; + campaignShipping.contactId = contactId; + campaignShipping.campaignId = campaignId; + + const messages = getCampaignValidMessages(campaign); + if (messages.length) { + const radomIndex = randomValue(0, messages.length); + const message = getProcessedMessage( + messages[radomIndex], + variables, + contact + ); + campaignShipping.message = `\u200c ${message}`; + } + + if (campaign.confirmation) { + const confirmationMessages = + getCampaignValidConfirmationMessages(campaign); + if (confirmationMessages.length) { + const radomIndex = randomValue(0, confirmationMessages.length); + const message = getProcessedMessage( + confirmationMessages[radomIndex], + variables, + contact + ); + campaignShipping.confirmationMessage = `\u200c ${message}`; + } + } + + const [record, created] = await CampaignShipping.findOrCreate({ + where: { + campaignId: campaignShipping.campaignId, + contactId: campaignShipping.contactId + }, + defaults: campaignShipping + }); + + if ( + !created && + record.deliveredAt === null && + record.confirmationRequestedAt === null + ) { + record.set(campaignShipping); + await record.save(); + } + + if ( + record.deliveredAt === null && + record.confirmationRequestedAt === null + ) { + const nextJob = await campaignQueue.add( + "DispatchCampaign", + { + campaignId: campaign.id, + campaignShippingId: record.id, + contactListItemId: contactId + }, + { + delay + } + ); + + await record.update({ jobId: nextJob.id }); + } + + await verifyAndFinalizeCampaign(campaign); + } catch (err: any) { + Sentry.captureException(err); + logger.error(`campaignQueue -> PrepareContact -> error: ${err.message}`); + } +} + +async function handleDispatchCampaign(job) { + try { + const { data } = job; + const { campaignShippingId, campaignId }: DispatchCampaignData = data; + const campaign = await getCampaign(campaignId); + const wbot = await GetWhatsappWbot(campaign.whatsapp); + + if (!wbot) { + logger.error(`campaignQueue -> DispatchCampaign -> error: wbot not found`); + return; + } + + if (!campaign.whatsapp) { + logger.error(`campaignQueue -> DispatchCampaign -> error: whatsapp not found`); + return; + } + + if (!wbot?.user?.id) { + logger.error(`campaignQueue -> DispatchCampaign -> error: wbot user not found`); + return; + } + + logger.info( + `Disparo de campanha solicitado: Campanha=${campaignId};Registro=${campaignShippingId}` + ); + + const campaignShipping = await CampaignShipping.findByPk( + campaignShippingId, + { + include: [{ model: ContactListItem, as: "contact" }] + } + ); + + const chatId = `${campaignShipping.number}@s.whatsapp.net`; + + let body = campaignShipping.message; + + if (campaign.confirmation && campaignShipping.confirmation === null) { + body = campaignShipping.confirmationMessage + } + + if (!isNil(campaign.fileListId)) { + try { + const publicFolder = path.resolve(__dirname, "..", "public"); + const files = await ShowFileService(campaign.fileListId, campaign.companyId) + const folder = path.resolve(publicFolder, "fileList", String(files.id)) + for (const [index, file] of files.options.entries()) { + const options = await getMessageOptions(file.path, path.resolve(folder, file.path), file.name); + await wbot.sendMessage(chatId, { ...options }); + }; + } catch (error) { + logger.info(error); + } + } + + if (campaign.mediaPath) { + const publicFolder = path.resolve(__dirname, "..", "public"); + const filePath = path.join(publicFolder, campaign.mediaPath); + + const options = await getMessageOptions(campaign.mediaName, filePath, body); + if (Object.keys(options).length) { + await wbot.sendMessage(chatId, { ...options }); + } + } + else { + if (campaign.confirmation && campaignShipping.confirmation === null) { + await wbot.sendMessage(chatId, { + text: body + }); + await campaignShipping.update({ confirmationRequestedAt: moment() }); + } else { + + await wbot.sendMessage(chatId, { + text: body + }); + } + } + await campaignShipping.update({ deliveredAt: moment() }); + + await verifyAndFinalizeCampaign(campaign); + + const io = getIO(); + io.to(`company-${campaign.companyId}-mainchannel`).emit(`company-${campaign.companyId}-campaign`, { + action: "update", + record: campaign + }); + + logger.info( + `Campanha enviada para: Campanha=${campaignId};Contato=${campaignShipping.contact.name}` + ); + } catch (err: any) { + Sentry.captureException(err); + logger.error(err.message); + console.log(err.stack); + } +} + +async function handleLoginStatus(job) { + const users: { id: number }[] = await sequelize.query( + `select id from "Users" where "updatedAt" < now() - '5 minutes'::interval and online = true`, + { type: QueryTypes.SELECT } + ); + for (let item of users) { + try { + const user = await User.findByPk(item.id); + await user.update({ online: false }); + logger.info(`Usuário passado para offline: ${item.id}`); + } catch (e: any) { + Sentry.captureException(e); + } + } +} + + +async function handleInvoiceCreate() { + logger.info("Iniciando geração de boletos"); + const job = new CronJob('*/5 * * * * *', async () => { + + + const companies = await Company.findAll(); + companies.map(async c => { + var dueDate = c.dueDate; + const date = moment(dueDate).format(); + const timestamp = moment().format(); + const hoje = moment(moment()).format("DD/MM/yyyy"); + var vencimento = moment(dueDate).format("DD/MM/yyyy"); + + var diff = moment(vencimento, "DD/MM/yyyy").diff(moment(hoje, "DD/MM/yyyy")); + var dias = moment.duration(diff).asDays(); + + if (dias < 20) { + const plan = await Plan.findByPk(c.planId); + + const sql = `SELECT COUNT(*) mycount FROM "Invoices" WHERE "companyId" = ${c.id} AND "dueDate"::text LIKE '${moment(dueDate).format("yyyy-MM-DD")}%';` + const invoice = await sequelize.query(sql, + { type: QueryTypes.SELECT } + ); + if (invoice[0]['mycount'] > 0) { + + } else { + const sql = `INSERT INTO "Invoices" (detail, status, value, "updatedAt", "createdAt", "dueDate", "companyId") + VALUES ('${plan.name}', 'open', '${plan.value}', '${timestamp}', '${timestamp}', '${date}', ${c.id});` + + const invoiceInsert = await sequelize.query(sql, + { type: QueryTypes.INSERT } + ); + + /* let transporter = nodemailer.createTransport({ + service: 'gmail', + auth: { + user: 'email@gmail.com', + pass: 'senha' + } + }); + + const mailOptions = { + from: 'heenriquega@gmail.com', // sender address + to: `${c.email}`, // receiver (use array of string for a list) + subject: 'Fatura gerada - Sistema', // Subject line + html: `Olá ${c.name} esté é um email sobre sua fatura!
+
+ Vencimento: ${vencimento}
+ Valor: ${plan.value}
+ Link: ${process.env.FRONTEND_URL}/financeiro
+
+ Qualquer duvida estamos a disposição! + `// plain text body + }; + + transporter.sendMail(mailOptions, (err, info) => { + if (err) + console.log(err) + else + console.log(info); + }); */ + + } + + + + + + } + + }); + }); + job.start() +} + +handleCloseTicketsAutomatic() + +handleInvoiceCreate() + +export async function startQueueProcess() { + logger.info("Iniciando processamento de filas"); + + messageQueue.process("SendMessage", handleSendMessage); + + scheduleMonitor.process("Verify", handleVerifySchedules); + + sendScheduledMessages.process("SendMessage", handleSendScheduledMessage); + + campaignQueue.process("VerifyCampaigns", handleVerifyCampaigns); + + campaignQueue.process("ProcessCampaign", handleProcessCampaign); + + campaignQueue.process("PrepareContact", handlePrepareContact); + + campaignQueue.process("DispatchCampaign", handleDispatchCampaign); + + userMonitor.process("VerifyLoginStatus", handleLoginStatus); + + //queueMonitor.process("VerifyQueueStatus", handleVerifyQueue); + + + + scheduleMonitor.add( + "Verify", + {}, + { + repeat: { cron: "*/5 * * * * *", key: "verify" }, + removeOnComplete: true + } + ); + + campaignQueue.add( + "VerifyCampaigns", + {}, + { + repeat: { cron: "*/20 * * * * *", key: "verify-campaing" }, + removeOnComplete: true + } + ); + + userMonitor.add( + "VerifyLoginStatus", + {}, + { + repeat: { cron: "* * * * *", key: "verify-login" }, + removeOnComplete: true + } + ); + + queueMonitor.add( + "VerifyQueueStatus", + {}, + { + repeat: { cron: "*/20 * * * * *" }, + removeOnComplete: true + } + ); +} diff --git a/backend/src/routes/announcementRoutes.ts b/backend/src/routes/announcementRoutes.ts new file mode 100644 index 0000000..3b64f0d --- /dev/null +++ b/backend/src/routes/announcementRoutes.ts @@ -0,0 +1,38 @@ +import express from "express"; +import isAuth from "../middleware/isAuth"; +import isSuper from "../middleware/isSuper"; + +import * as AnnouncementController from "../controllers/AnnouncementController"; +import multer from "multer"; +import uploadConfig from "../config/upload"; + +const upload = multer(uploadConfig); + +const routes = express.Router(); + +routes.get("/announcements/list", isAuth, AnnouncementController.findList); + +routes.get("/announcements", isAuth, AnnouncementController.index); + +routes.get("/announcements/:id", isAuth, AnnouncementController.show); + +routes.post("/announcements", isAuth, isSuper, AnnouncementController.store); + +routes.put("/announcements/:id", isAuth, isSuper, AnnouncementController.update); + +routes.delete("/announcements/:id", isAuth, isSuper, AnnouncementController.remove); + +routes.post( + "/announcements/:id/media-upload", + isAuth, isSuper, + upload.array("file"), + AnnouncementController.mediaUpload +); + +routes.delete( + "/announcements/:id/media-upload", + isAuth, isSuper, + AnnouncementController.deleteMedia +); + +export default routes; diff --git a/backend/src/routes/authRoutes.ts b/backend/src/routes/authRoutes.ts new file mode 100644 index 0000000..8a5c3b0 --- /dev/null +++ b/backend/src/routes/authRoutes.ts @@ -0,0 +1,15 @@ +import { Router } from "express"; +import * as SessionController from "../controllers/SessionController"; +import * as UserController from "../controllers/UserController"; +import isAuth from "../middleware/isAuth"; +import envTokenAuth from "../middleware/envTokenAuth"; + +const authRoutes = Router(); + +authRoutes.post("/signup", envTokenAuth, UserController.store); +authRoutes.post("/login", SessionController.store); +authRoutes.post("/refresh_token", SessionController.update); +authRoutes.delete("/logout", isAuth, SessionController.remove); +authRoutes.get("/me", isAuth, SessionController.me); + +export default authRoutes; diff --git a/backend/src/routes/campaignRoutes.ts b/backend/src/routes/campaignRoutes.ts new file mode 100644 index 0000000..2a794fd --- /dev/null +++ b/backend/src/routes/campaignRoutes.ts @@ -0,0 +1,41 @@ +import express from "express"; +import isAuth from "../middleware/isAuth"; + +import * as CampaignController from "../controllers/CampaignController"; +import multer from "multer"; +import uploadConfig from "../config/upload"; + +const upload = multer(uploadConfig); + +const routes = express.Router(); + +routes.get("/campaigns/list", isAuth, CampaignController.findList); + +routes.get("/campaigns", isAuth, CampaignController.index); + +routes.get("/campaigns/:id", isAuth, CampaignController.show); + +routes.post("/campaigns", isAuth, CampaignController.store); + +routes.put("/campaigns/:id", isAuth, CampaignController.update); + +routes.delete("/campaigns/:id", isAuth, CampaignController.remove); + +routes.post("/campaigns/:id/cancel", isAuth, CampaignController.cancel); + +routes.post("/campaigns/:id/restart", isAuth, CampaignController.restart); + +routes.post( + "/campaigns/:id/media-upload", + isAuth, + upload.array("file"), + CampaignController.mediaUpload +); + +routes.delete( + "/campaigns/:id/media-upload", + isAuth, + CampaignController.deleteMedia +); + +export default routes; diff --git a/backend/src/routes/campaignSettingRoutes.ts b/backend/src/routes/campaignSettingRoutes.ts new file mode 100644 index 0000000..572ea57 --- /dev/null +++ b/backend/src/routes/campaignSettingRoutes.ts @@ -0,0 +1,16 @@ +import express from "express"; +import isAuth from "../middleware/isAuth"; + +import * as CampaignSettingController from "../controllers/CampaignSettingController"; +import multer from "multer"; +import uploadConfig from "../config/upload"; + +const upload = multer(uploadConfig); + +const routes = express.Router(); + +routes.get("/campaign-settings", isAuth, CampaignSettingController.index); + +routes.post("/campaign-settings", isAuth, CampaignSettingController.store); + +export default routes; diff --git a/backend/src/routes/chatRoutes.ts b/backend/src/routes/chatRoutes.ts new file mode 100644 index 0000000..1d27994 --- /dev/null +++ b/backend/src/routes/chatRoutes.ts @@ -0,0 +1,24 @@ +import express from "express"; +import isAuth from "../middleware/isAuth"; + +import * as ChatController from "../controllers/ChatController"; + +const routes = express.Router(); + +routes.get("/chats", isAuth, ChatController.index); + +routes.get("/chats/:id", isAuth, ChatController.show); + +routes.get("/chats/:id/messages", isAuth, ChatController.messages); + +routes.post("/chats/:id/messages", isAuth, ChatController.saveMessage); + +routes.post("/chats/:id/read", isAuth, ChatController.checkAsRead); + +routes.post("/chats", isAuth, ChatController.store); + +routes.put("/chats/:id", isAuth, ChatController.update); + +routes.delete("/chats/:id", isAuth, ChatController.remove); + +export default routes; diff --git a/backend/src/routes/companyRoutes.ts b/backend/src/routes/companyRoutes.ts new file mode 100644 index 0000000..99aa631 --- /dev/null +++ b/backend/src/routes/companyRoutes.ts @@ -0,0 +1,22 @@ +import express from "express"; +import isAuth from "../middleware/isAuth"; +import isSuper from "../middleware/isSuper"; + +import * as CompanyController from "../controllers/CompanyController"; + +const companyRoutes = express.Router(); + +companyRoutes.get("/companies/list", isAuth, isSuper, CompanyController.list); +companyRoutes.get("/companies", isAuth, isSuper, CompanyController.index); +companyRoutes.get("/companies/:id", isAuth, CompanyController.show); +companyRoutes.post("/companies", isAuth, isSuper, CompanyController.store); +companyRoutes.put("/companies/:id", isAuth, isSuper, CompanyController.update); +companyRoutes.put("/companies/:id/schedules",isAuth,CompanyController.updateSchedules); +companyRoutes.delete("/companies/:id", isAuth, isSuper, CompanyController.remove); +companyRoutes.post("/companies/cadastro", CompanyController.store); + +// Rota para listar o plano da empresa +companyRoutes.get("/companies/listPlan/:id", isAuth, CompanyController.listPlan); +companyRoutes.get("/companiesPlan", isAuth, CompanyController.indexPlan); + +export default companyRoutes; diff --git a/backend/src/routes/contactListItemRoutes.ts b/backend/src/routes/contactListItemRoutes.ts new file mode 100644 index 0000000..7f91592 --- /dev/null +++ b/backend/src/routes/contactListItemRoutes.ts @@ -0,0 +1,28 @@ +import express from "express"; +import isAuth from "../middleware/isAuth"; + +import * as ContactListItemController from "../controllers/ContactListItemController"; + +const routes = express.Router(); + +routes.get( + "/contact-list-items/list", + isAuth, + ContactListItemController.findList +); + +routes.get("/contact-list-items", isAuth, ContactListItemController.index); + +routes.get("/contact-list-items/:id", isAuth, ContactListItemController.show); + +routes.post("/contact-list-items", isAuth, ContactListItemController.store); + +routes.put("/contact-list-items/:id", isAuth, ContactListItemController.update); + +routes.delete( + "/contact-list-items/:id", + isAuth, + ContactListItemController.remove +); + +export default routes; diff --git a/backend/src/routes/contactListRoutes.ts b/backend/src/routes/contactListRoutes.ts new file mode 100644 index 0000000..574e567 --- /dev/null +++ b/backend/src/routes/contactListRoutes.ts @@ -0,0 +1,31 @@ +import express from "express"; +import isAuth from "../middleware/isAuth"; +import uploadConfig from "../config/upload"; + +import * as ContactListController from "../controllers/ContactListController"; +import multer from "multer"; + +const routes = express.Router(); + +const upload = multer(uploadConfig); + +routes.get("/contact-lists/list", isAuth, ContactListController.findList); + +routes.get("/contact-lists", isAuth, ContactListController.index); + +routes.get("/contact-lists/:id", isAuth, ContactListController.show); + +routes.post("/contact-lists", isAuth, ContactListController.store); + +routes.post( + "/contact-lists/:id/upload", + isAuth, + upload.array("file"), + ContactListController.upload +); + +routes.put("/contact-lists/:id", isAuth, ContactListController.update); + +routes.delete("/contact-lists/:id", isAuth, ContactListController.remove); + +export default routes; diff --git a/backend/src/routes/contactRoutes.ts b/backend/src/routes/contactRoutes.ts new file mode 100644 index 0000000..fbacf80 --- /dev/null +++ b/backend/src/routes/contactRoutes.ts @@ -0,0 +1,27 @@ +import express from "express"; +import isAuth from "../middleware/isAuth"; + +import * as ContactController from "../controllers/ContactController"; +import * as ImportPhoneContactsController from "../controllers/ImportPhoneContactsController"; + +const contactRoutes = express.Router(); + +contactRoutes.post( + "/contacts/import", + isAuth, + ImportPhoneContactsController.store +); + +contactRoutes.get("/contacts", isAuth, ContactController.index); + +contactRoutes.get("/contacts/list", isAuth, ContactController.list); + +contactRoutes.get("/contacts/:contactId", isAuth, ContactController.show); + +contactRoutes.post("/contacts", isAuth, ContactController.store); + +contactRoutes.put("/contacts/:contactId", isAuth, ContactController.update); + +contactRoutes.delete("/contacts/:contactId", isAuth, ContactController.remove); + +export default contactRoutes; diff --git a/backend/src/routes/dashboardRoutes.ts b/backend/src/routes/dashboardRoutes.ts new file mode 100644 index 0000000..aeec79a --- /dev/null +++ b/backend/src/routes/dashboardRoutes.ts @@ -0,0 +1,12 @@ +import express from "express"; +import isAuth from "../middleware/isAuth"; + +import * as DashboardController from "../controllers/DashbardController"; + +const routes = express.Router(); + +routes.get("/dashboard", isAuth, DashboardController.index); +routes.get("/dashboard/ticketsUsers", DashboardController.reportsUsers); +routes.get("/dashboard/ticketsDay", DashboardController.reportsDay); + +export default routes; diff --git a/backend/src/routes/filesRoutes.ts b/backend/src/routes/filesRoutes.ts new file mode 100644 index 0000000..1b2814c --- /dev/null +++ b/backend/src/routes/filesRoutes.ts @@ -0,0 +1,20 @@ +import express from "express"; +import isAuth from "../middleware/isAuth"; +import uploadConfig from "../config/upload"; +import multer from "multer"; + +import * as FilesController from "../controllers/FilesController"; + +const upload = multer(uploadConfig); + +const filesRoutes = express.Router(); + +filesRoutes.get("/files/list", isAuth, FilesController.list); +filesRoutes.get("/files", isAuth, FilesController.index); +filesRoutes.post("/files", isAuth, FilesController.store); +filesRoutes.put("/files/:fileId", isAuth, FilesController.update); +filesRoutes.get("/files/:fileId", isAuth, FilesController.show); +filesRoutes.delete("/files/:fileId", isAuth, FilesController.remove); +filesRoutes.delete("/files", isAuth, FilesController.removeAll); +filesRoutes.post("/files/uploadList/:fileListId", isAuth, upload.array("files"), FilesController.uploadMedias); +export default filesRoutes; diff --git a/backend/src/routes/forgotPasswordRoutes.ts b/backend/src/routes/forgotPasswordRoutes.ts new file mode 100644 index 0000000..5fae897 --- /dev/null +++ b/backend/src/routes/forgotPasswordRoutes.ts @@ -0,0 +1,10 @@ +import express from "express"; +import isAuth from "../middleware/isAuth"; +import * as ForgotController from "../controllers/ForgotController"; +const forgotsRoutes = express.Router(); +forgotsRoutes.post("/forgetpassword/:email", ForgotController.store); +forgotsRoutes.post( + "/resetpasswords/:email/:token/:password", + ForgotController.resetPasswords +); +export default forgotsRoutes; diff --git a/backend/src/routes/helpRoutes.ts b/backend/src/routes/helpRoutes.ts new file mode 100644 index 0000000..c3c4512 --- /dev/null +++ b/backend/src/routes/helpRoutes.ts @@ -0,0 +1,21 @@ +import express from "express"; +import isAuth from "../middleware/isAuth"; +import isSuper from "../middleware/isSuper"; + +import * as HelpController from "../controllers/HelpController"; + +const routes = express.Router(); + +routes.get("/helps/list", isAuth, HelpController.findList); + +routes.get("/helps", isAuth, HelpController.index); + +routes.get("/helps/:id", isAuth, HelpController.show); + +routes.post("/helps", isAuth, isSuper, HelpController.store); + +routes.put("/helps/:id", isAuth, isSuper, HelpController.update); + +routes.delete("/helps/:id", isAuth, isSuper, HelpController.remove); + +export default routes; diff --git a/backend/src/routes/index.ts b/backend/src/routes/index.ts new file mode 100644 index 0000000..147100c --- /dev/null +++ b/backend/src/routes/index.ts @@ -0,0 +1,71 @@ +import { Router } from "express"; + +import userRoutes from "./userRoutes"; +import authRoutes from "./authRoutes"; +import settingRoutes from "./settingRoutes"; +import contactRoutes from "./contactRoutes"; +import ticketRoutes from "./ticketRoutes"; +import whatsappRoutes from "./whatsappRoutes"; +import messageRoutes from "./messageRoutes"; +import whatsappSessionRoutes from "./whatsappSessionRoutes"; +import queueRoutes from "./queueRoutes"; +import companyRoutes from "./companyRoutes"; +import planRoutes from "./planRoutes"; +import ticketNoteRoutes from "./ticketNoteRoutes"; +import quickMessageRoutes from "./quickMessageRoutes"; +import helpRoutes from "./helpRoutes"; +import dashboardRoutes from "./dashboardRoutes"; +import queueOptionRoutes from "./queueOptionRoutes"; +import scheduleRoutes from "./scheduleRoutes"; +import tagRoutes from "./tagRoutes"; +import contactListRoutes from "./contactListRoutes"; +import contactListItemRoutes from "./contactListItemRoutes"; +import campaignRoutes from "./campaignRoutes"; +import campaignSettingRoutes from "./campaignSettingRoutes"; +import announcementRoutes from "./announcementRoutes"; +import chatRoutes from "./chatRoutes"; +import invoiceRoutes from "./invoicesRoutes"; +import subscriptionRoutes from "./subScriptionRoutes"; +import ticketTagRoutes from "./ticketTagRoutes"; +import filesRoutes from "./filesRoutes"; +import promptRoutes from "./promptRouter"; +import queueIntegrationRoutes from "./queueIntegrationRoutes"; +import forgotsRoutes from "./forgotPasswordRoutes"; +import versionRouter from "./versionRoutes"; +const routes = Router(); + +routes.use(userRoutes); +routes.use("/auth", authRoutes); +routes.use(settingRoutes); +routes.use(contactRoutes); +routes.use(ticketRoutes); +routes.use(whatsappRoutes); +routes.use(messageRoutes); +routes.use(messageRoutes); +routes.use(whatsappSessionRoutes); +routes.use(queueRoutes); +routes.use(companyRoutes); +routes.use(planRoutes); +routes.use(ticketNoteRoutes); +routes.use(quickMessageRoutes); +routes.use(helpRoutes); +routes.use(dashboardRoutes); +routes.use(queueOptionRoutes); +routes.use(scheduleRoutes); +routes.use(tagRoutes); +routes.use(contactListRoutes); +routes.use(contactListItemRoutes); +routes.use(campaignRoutes); +routes.use(campaignSettingRoutes); +routes.use(announcementRoutes); +routes.use(chatRoutes); +routes.use(subscriptionRoutes); +routes.use(invoiceRoutes); +routes.use(ticketTagRoutes); +routes.use(filesRoutes); +routes.use(promptRoutes); +routes.use(queueIntegrationRoutes); +routes.use(forgotsRoutes); +routes.use(versionRouter); + +export default routes; diff --git a/backend/src/routes/invoicesRoutes.ts b/backend/src/routes/invoicesRoutes.ts new file mode 100644 index 0000000..e1ffef0 --- /dev/null +++ b/backend/src/routes/invoicesRoutes.ts @@ -0,0 +1,14 @@ +import express from "express"; +import isAuth from "../middleware/isAuth"; +import * as QueueOptionController from "../controllers/QueueOptionController"; +import * as InvoicesController from "../controllers/InvoicesController" + +const invoiceRoutes = express.Router(); + +invoiceRoutes.get("/invoices", isAuth, InvoicesController.index); +invoiceRoutes.get("/invoices/list", InvoicesController.list); +invoiceRoutes.get("/invoices/all", isAuth, InvoicesController.list); +invoiceRoutes.get("/invoices/:Invoiceid", isAuth, InvoicesController.show); +invoiceRoutes.put("/invoices/:id", isAuth, InvoicesController.update); + +export default invoiceRoutes; diff --git a/backend/src/routes/messageRoutes.ts b/backend/src/routes/messageRoutes.ts new file mode 100644 index 0000000..8e10279 --- /dev/null +++ b/backend/src/routes/messageRoutes.ts @@ -0,0 +1,18 @@ +import { Router } from "express"; +import multer from "multer"; +import isAuth from "../middleware/isAuth"; +import uploadConfig from "../config/upload"; +import tokenAuth from "../middleware/tokenAuth"; + +import * as MessageController from "../controllers/MessageController"; + +const messageRoutes = Router(); + +const upload = multer(uploadConfig); + +messageRoutes.get("/messages/:ticketId", isAuth, MessageController.index); +messageRoutes.post("/messages/:ticketId", isAuth, upload.array("medias"), MessageController.store); +messageRoutes.delete("/messages/:messageId", isAuth, MessageController.remove); +messageRoutes.post("/api/messages/send", tokenAuth, upload.array("medias"), MessageController.send); + +export default messageRoutes; diff --git a/backend/src/routes/planRoutes.ts b/backend/src/routes/planRoutes.ts new file mode 100644 index 0000000..b522f41 --- /dev/null +++ b/backend/src/routes/planRoutes.ts @@ -0,0 +1,23 @@ +import express from "express"; +import isAuth from "../middleware/isAuth"; +import isSuper from "../middleware/isSuper"; + +import * as PlanController from "../controllers/PlanController"; + +const planRoutes = express.Router(); + +planRoutes.get("/plans", isAuth, PlanController.index); + +planRoutes.get("/plans/list", PlanController.list); + +planRoutes.get("/plans/all", PlanController.list); + +planRoutes.get("/plans/:id", isAuth, PlanController.show); + +planRoutes.post("/plans", isAuth, isSuper, PlanController.store); + +planRoutes.put("/plans/:id", isAuth, isSuper, PlanController.update); + +planRoutes.delete("/plans/:id", isAuth, isSuper, PlanController.remove); + +export default planRoutes; diff --git a/backend/src/routes/promptRouter.ts b/backend/src/routes/promptRouter.ts new file mode 100644 index 0000000..1b140a6 --- /dev/null +++ b/backend/src/routes/promptRouter.ts @@ -0,0 +1,18 @@ +import { Router } from "express"; +import * as PromptController from "../controllers/PromptController"; +import isAuth from "../middleware/isAuth"; + + +const promptRoutes = Router(); + +promptRoutes.get("/prompt", isAuth, PromptController.index); + +promptRoutes.post("/prompt", isAuth, PromptController.store); + +promptRoutes.get("/prompt/:promptId", isAuth, PromptController.show); + +promptRoutes.put("/prompt/:promptId", isAuth, PromptController.update); + +promptRoutes.delete("/prompt/:promptId", isAuth, PromptController.remove); + +export default promptRoutes; diff --git a/backend/src/routes/queueIntegrationRoutes.ts b/backend/src/routes/queueIntegrationRoutes.ts new file mode 100644 index 0000000..3be2ef6 --- /dev/null +++ b/backend/src/routes/queueIntegrationRoutes.ts @@ -0,0 +1,18 @@ +import { Router } from "express"; +import isAuth from "../middleware/isAuth"; + +import * as QueueIntegrationController from "../controllers/QueueIntegrationController"; + +const queueIntegrationRoutes = Router(); + +queueIntegrationRoutes.get("/queueIntegration", isAuth, QueueIntegrationController.index); + +queueIntegrationRoutes.post("/queueIntegration", isAuth, QueueIntegrationController.store); + +queueIntegrationRoutes.get("/queueIntegration/:integrationId", isAuth, QueueIntegrationController.show); + +queueIntegrationRoutes.put("/queueIntegration/:integrationId", isAuth, QueueIntegrationController.update); + +queueIntegrationRoutes.delete("/queueIntegration/:integrationId", isAuth, QueueIntegrationController.remove); + +export default queueIntegrationRoutes; \ No newline at end of file diff --git a/backend/src/routes/queueOptionRoutes.ts b/backend/src/routes/queueOptionRoutes.ts new file mode 100644 index 0000000..711828d --- /dev/null +++ b/backend/src/routes/queueOptionRoutes.ts @@ -0,0 +1,18 @@ +import { Router } from "express"; +import isAuth from "../middleware/isAuth"; + +import * as QueueOptionController from "../controllers/QueueOptionController"; + +const queueOptionRoutes = Router(); + +queueOptionRoutes.get("/queue-options", isAuth, QueueOptionController.index); + +queueOptionRoutes.post("/queue-options", isAuth, QueueOptionController.store); + +queueOptionRoutes.get("/queue-options/:queueOptionId", isAuth, QueueOptionController.show); + +queueOptionRoutes.put("/queue-options/:queueOptionId", isAuth, QueueOptionController.update); + +queueOptionRoutes.delete("/queue-options/:queueOptionId", isAuth, QueueOptionController.remove); + +export default queueOptionRoutes; diff --git a/backend/src/routes/queueRoutes.ts b/backend/src/routes/queueRoutes.ts new file mode 100644 index 0000000..a85f5e3 --- /dev/null +++ b/backend/src/routes/queueRoutes.ts @@ -0,0 +1,18 @@ +import { Router } from "express"; +import isAuth from "../middleware/isAuth"; + +import * as QueueController from "../controllers/QueueController"; + +const queueRoutes = Router(); + +queueRoutes.get("/queue", isAuth, QueueController.index); + +queueRoutes.post("/queue", isAuth, QueueController.store); + +queueRoutes.get("/queue/:queueId", isAuth, QueueController.show); + +queueRoutes.put("/queue/:queueId", isAuth, QueueController.update); + +queueRoutes.delete("/queue/:queueId", isAuth, QueueController.remove); + +export default queueRoutes; diff --git a/backend/src/routes/quickMessageRoutes.ts b/backend/src/routes/quickMessageRoutes.ts new file mode 100644 index 0000000..412ef1b --- /dev/null +++ b/backend/src/routes/quickMessageRoutes.ts @@ -0,0 +1,37 @@ +import express from "express"; +import isAuth from "../middleware/isAuth"; + +import * as QuickMessageController from "../controllers/QuickMessageController"; +import multer from "multer"; +import uploadConfig from "../config/upload"; + +const upload = multer(uploadConfig); + +const routes = express.Router(); + +routes.get("/quick-messages/list", isAuth, QuickMessageController.findList); + +routes.get("/quick-messages", isAuth, QuickMessageController.index); + +routes.get("/quick-messages/:id", isAuth, QuickMessageController.show); + +routes.post("/quick-messages", isAuth, QuickMessageController.store); + +routes.put("/quick-messages/:id", isAuth, QuickMessageController.update); + +routes.delete("/quick-messages/:id", isAuth, QuickMessageController.remove); + +routes.post( + "/quick-messages/:id/media-upload", + isAuth, + upload.array("file"), + QuickMessageController.mediaUpload + ); + + routes.delete( + "/quick-messages/:id/media-upload", + isAuth, + QuickMessageController.deleteMedia + ); + +export default routes; diff --git a/backend/src/routes/scheduleRoutes.ts b/backend/src/routes/scheduleRoutes.ts new file mode 100644 index 0000000..1f9e6a6 --- /dev/null +++ b/backend/src/routes/scheduleRoutes.ts @@ -0,0 +1,26 @@ +import express from "express"; +import isAuth from "../middleware/isAuth"; + +import * as ScheduleController from "../controllers/ScheduleController"; +import multer from "multer"; +import uploadConfig from "../config/upload"; + +const upload = multer(uploadConfig); + +const scheduleRoutes = express.Router(); + +scheduleRoutes.get("/schedules", isAuth, ScheduleController.index); + +scheduleRoutes.post("/schedules", isAuth, ScheduleController.store); + +scheduleRoutes.put("/schedules/:scheduleId", isAuth, ScheduleController.update); + +scheduleRoutes.get("/schedules/:scheduleId", isAuth, ScheduleController.show); + +scheduleRoutes.delete("/schedules/:scheduleId", isAuth, ScheduleController.remove); + +scheduleRoutes.post("/schedules/:id/media-upload", isAuth, upload.array("file"), ScheduleController.mediaUpload); + +scheduleRoutes.delete("/schedules/:id/media-upload", isAuth, ScheduleController.deleteMedia); + +export default scheduleRoutes; diff --git a/backend/src/routes/settingRoutes.ts b/backend/src/routes/settingRoutes.ts new file mode 100644 index 0000000..625864a --- /dev/null +++ b/backend/src/routes/settingRoutes.ts @@ -0,0 +1,15 @@ +import { Router } from "express"; +import isAuth from "../middleware/isAuth"; + +import * as SettingController from "../controllers/SettingController"; + +const settingRoutes = Router(); + +settingRoutes.get("/settings", isAuth, SettingController.index); + +// routes.get("/settings/:settingKey", isAuth, SettingsController.show); + +// change setting key to key in future +settingRoutes.put("/settings/:settingKey", isAuth, SettingController.update); + +export default settingRoutes; diff --git a/backend/src/routes/subScriptionRoutes.ts b/backend/src/routes/subScriptionRoutes.ts new file mode 100644 index 0000000..8817b6d --- /dev/null +++ b/backend/src/routes/subScriptionRoutes.ts @@ -0,0 +1,11 @@ +import express from "express"; +import isAuth from "../middleware/isAuth"; + +import * as SubscriptionController from "../controllers/SubscriptionController"; + +const subscriptionRoutes = express.Router(); +subscriptionRoutes.post("/subscription", isAuth, SubscriptionController.createSubscription); +subscriptionRoutes.post("/subscription/create/webhook", SubscriptionController.createWebhook); +subscriptionRoutes.post("/subscription/webhook/:type?", SubscriptionController.webhook); + +export default subscriptionRoutes; diff --git a/backend/src/routes/tagRoutes.ts b/backend/src/routes/tagRoutes.ts new file mode 100644 index 0000000..6889ceb --- /dev/null +++ b/backend/src/routes/tagRoutes.ts @@ -0,0 +1,25 @@ +import express from "express"; +import isAuth from "../middleware/isAuth"; + +import * as TagController from "../controllers/TagController"; + +const tagRoutes = express.Router(); + +tagRoutes.get("/tags/list", isAuth, TagController.list); + +tagRoutes.get("/tags", isAuth, TagController.index); + +tagRoutes.get("/tags/kanban", isAuth, TagController.kanban); + +tagRoutes.post("/tags", isAuth, TagController.store); + +tagRoutes.put("/tags/:tagId", isAuth, TagController.update); + +tagRoutes.get("/tags/:tagId", isAuth, TagController.show); + +tagRoutes.delete("/tags/:tagId", isAuth, TagController.remove); + +tagRoutes.post("/tags/sync", isAuth, TagController.syncTags); + + +export default tagRoutes; diff --git a/backend/src/routes/ticketNoteRoutes.ts b/backend/src/routes/ticketNoteRoutes.ts new file mode 100644 index 0000000..88462bb --- /dev/null +++ b/backend/src/routes/ticketNoteRoutes.ts @@ -0,0 +1,28 @@ +import express from "express"; +import isAuth from "../middleware/isAuth"; + +import * as TicketNoteController from "../controllers/TicketNoteController"; + +const ticketNoteRoutes = express.Router(); + +ticketNoteRoutes.get( + "/ticket-notes/list", + isAuth, + TicketNoteController.findFilteredList +); + +ticketNoteRoutes.get("/ticket-notes", isAuth, TicketNoteController.index); + +ticketNoteRoutes.get("/ticket-notes/:id", isAuth, TicketNoteController.show); + +ticketNoteRoutes.post("/ticket-notes", isAuth, TicketNoteController.store); + +ticketNoteRoutes.put("/ticket-notes/:id", isAuth, TicketNoteController.update); + +ticketNoteRoutes.delete( + "/ticket-notes/:id", + isAuth, + TicketNoteController.remove +); + +export default ticketNoteRoutes; diff --git a/backend/src/routes/ticketRoutes.ts b/backend/src/routes/ticketRoutes.ts new file mode 100644 index 0000000..0ee02e7 --- /dev/null +++ b/backend/src/routes/ticketRoutes.ts @@ -0,0 +1,22 @@ +import express from "express"; +import isAuth from "../middleware/isAuth"; + +import * as TicketController from "../controllers/TicketController"; + +const ticketRoutes = express.Router(); + +ticketRoutes.get("/tickets", isAuth, TicketController.index); + +ticketRoutes.get("/tickets/:ticketId", isAuth, TicketController.show); + +ticketRoutes.get("/ticket/kanban", isAuth, TicketController.kanban); + +ticketRoutes.get("/tickets/u/:uuid", isAuth, TicketController.showFromUUID); + +ticketRoutes.post("/tickets", isAuth, TicketController.store); + +ticketRoutes.put("/tickets/:ticketId", isAuth, TicketController.update); + +ticketRoutes.delete("/tickets/:ticketId", isAuth, TicketController.remove); + +export default ticketRoutes; diff --git a/backend/src/routes/ticketTagRoutes.ts b/backend/src/routes/ticketTagRoutes.ts new file mode 100644 index 0000000..759f203 --- /dev/null +++ b/backend/src/routes/ticketTagRoutes.ts @@ -0,0 +1,11 @@ +import express from "express"; +import isAuth from "../middleware/isAuth"; + +import * as TicketTagController from "../controllers/TicketTagController"; + +const ticketTagRoutes = express.Router(); + +ticketTagRoutes.put("/ticket-tags/:ticketId/:tagId", isAuth, TicketTagController.store); +ticketTagRoutes.delete("/ticket-tags/:ticketId", isAuth, TicketTagController.remove); + +export default ticketTagRoutes; diff --git a/backend/src/routes/userRoutes.ts b/backend/src/routes/userRoutes.ts new file mode 100644 index 0000000..4fbf2c1 --- /dev/null +++ b/backend/src/routes/userRoutes.ts @@ -0,0 +1,20 @@ +import { Router } from "express"; + +import isAuth from "../middleware/isAuth"; +import * as UserController from "../controllers/UserController"; + +const userRoutes = Router(); + +userRoutes.get("/users", isAuth, UserController.index); + +userRoutes.get("/users/list", isAuth, UserController.list); + +userRoutes.post("/users", isAuth, UserController.store); + +userRoutes.put("/users/:userId", isAuth, UserController.update); + +userRoutes.get("/users/:userId", isAuth, UserController.show); + +userRoutes.delete("/users/:userId", isAuth, UserController.remove); + +export default userRoutes; diff --git a/backend/src/routes/versionRoutes.ts b/backend/src/routes/versionRoutes.ts new file mode 100644 index 0000000..9ff2cbe --- /dev/null +++ b/backend/src/routes/versionRoutes.ts @@ -0,0 +1,9 @@ +import { Router } from "express"; + +import * as VerssionController from "../controllers/VersionController"; + +const versionRouter = Router(); + +versionRouter.get("/version", VerssionController.index); + +export default versionRouter; diff --git a/backend/src/routes/whatsappRoutes.ts b/backend/src/routes/whatsappRoutes.ts new file mode 100644 index 0000000..dc187a7 --- /dev/null +++ b/backend/src/routes/whatsappRoutes.ts @@ -0,0 +1,22 @@ +import express from "express"; +import isAuth from "../middleware/isAuth"; + +import * as WhatsAppController from "../controllers/WhatsAppController"; + +const whatsappRoutes = express.Router(); + +whatsappRoutes.get("/whatsapp/", isAuth, WhatsAppController.index); + +whatsappRoutes.post("/whatsapp/", isAuth, WhatsAppController.store); + +whatsappRoutes.get("/whatsapp/:whatsappId", isAuth, WhatsAppController.show); + +whatsappRoutes.put("/whatsapp/:whatsappId", isAuth, WhatsAppController.update); + +whatsappRoutes.delete( + "/whatsapp/:whatsappId", + isAuth, + WhatsAppController.remove +); + +export default whatsappRoutes; diff --git a/backend/src/routes/whatsappSessionRoutes.ts b/backend/src/routes/whatsappSessionRoutes.ts new file mode 100644 index 0000000..731d847 --- /dev/null +++ b/backend/src/routes/whatsappSessionRoutes.ts @@ -0,0 +1,26 @@ +import { Router } from "express"; +import isAuth from "../middleware/isAuth"; + +import WhatsAppSessionController from "../controllers/WhatsAppSessionController"; + +const whatsappSessionRoutes = Router(); + +whatsappSessionRoutes.post( + "/whatsappsession/:whatsappId", + isAuth, + WhatsAppSessionController.store +); + +whatsappSessionRoutes.put( + "/whatsappsession/:whatsappId", + isAuth, + WhatsAppSessionController.update +); + +whatsappSessionRoutes.delete( + "/whatsappsession/:whatsappId", + isAuth, + WhatsAppSessionController.remove +); + +export default whatsappSessionRoutes; diff --git a/backend/src/server.ts b/backend/src/server.ts new file mode 100644 index 0000000..5f386b2 --- /dev/null +++ b/backend/src/server.ts @@ -0,0 +1,40 @@ +import gracefulShutdown from "http-graceful-shutdown"; +import app from "./app"; +import { initIO } from "./libs/socket"; +import { logger } from "./utils/logger"; +import { StartAllWhatsAppsSessions } from "./services/WbotServices/StartAllWhatsAppsSessions"; +import Company from "./models/Company"; +import { startQueueProcess } from "./queues"; +import { TransferTicketQueue } from "./wbotTransferTicketQueue"; +import cron from "node-cron"; + +const server = app.listen(process.env.PORT, async () => { + const companies = await Company.findAll(); + const allPromises: any[] = []; + companies.map(async c => { + const promise = StartAllWhatsAppsSessions(c.id); + allPromises.push(promise); + }); + + Promise.all(allPromises).then(() => { + startQueueProcess(); + }); + logger.info(`Server started on port: ${process.env.PORT}`); +}); + +cron.schedule("* * * * *", async () => { + + try { + // console.log("Running a job at 01:00 at America/Sao_Paulo timezone") + logger.info(`Serviço de transferencia de tickets iniciado`); + + await TransferTicketQueue(); + } + catch (error) { + logger.error(error); + } + +}); + +initIO(server); +gracefulShutdown(server); diff --git a/backend/src/services/AnnouncementService/CreateService.ts b/backend/src/services/AnnouncementService/CreateService.ts new file mode 100644 index 0000000..0a81193 --- /dev/null +++ b/backend/src/services/AnnouncementService/CreateService.ts @@ -0,0 +1,32 @@ +import * as Yup from "yup"; +import AppError from "../../errors/AppError"; +import Announcement from "../../models/Announcement"; + +interface Data { + priority: string; + title: string; + text: string; + status: string; + companyId: number; +} + +const CreateService = async (data: Data): Promise => { + const { title, text } = data; + + const ticketnoteSchema = Yup.object().shape({ + title: Yup.string().required("ERR_ANNOUNCEMENT_REQUIRED"), + text: Yup.string().required("ERR_ANNOUNCEMENT_REQUIRED") + }); + + try { + await ticketnoteSchema.validate({ title, text }); + } catch (err: any) { + throw new AppError(err.message); + } + + const record = await Announcement.create(data); + + return record; +}; + +export default CreateService; diff --git a/backend/src/services/AnnouncementService/DeleteService.ts b/backend/src/services/AnnouncementService/DeleteService.ts new file mode 100644 index 0000000..c3aee30 --- /dev/null +++ b/backend/src/services/AnnouncementService/DeleteService.ts @@ -0,0 +1,16 @@ +import Announcement from "../../models/Announcement"; +import AppError from "../../errors/AppError"; + +const DeleteService = async (id: string): Promise => { + const record = await Announcement.findOne({ + where: { id } + }); + + if (!record) { + throw new AppError("ERR_NO_ANNOUNCEMENT_FOUND", 404); + } + + await record.destroy(); +}; + +export default DeleteService; diff --git a/backend/src/services/AnnouncementService/FindAllService.ts b/backend/src/services/AnnouncementService/FindAllService.ts new file mode 100644 index 0000000..13209f7 --- /dev/null +++ b/backend/src/services/AnnouncementService/FindAllService.ts @@ -0,0 +1,10 @@ +import Announcement from "../../models/Announcement"; + +const FindAllService = async (): Promise => { + const records: Announcement[] = await Announcement.findAll({ + order: [["createdAt", "DESC"]] + }); + return records; +}; + +export default FindAllService; diff --git a/backend/src/services/AnnouncementService/FindService.ts b/backend/src/services/AnnouncementService/FindService.ts new file mode 100644 index 0000000..5125672 --- /dev/null +++ b/backend/src/services/AnnouncementService/FindService.ts @@ -0,0 +1,20 @@ +import Announcement from "../../models/Announcement"; +import Company from "../../models/Company"; + +type Params = { + companyId: string; +}; + +const FindService = async ({ companyId }: Params): Promise => { + const notes: Announcement[] = await Announcement.findAll({ + where: { + companyId + }, + include: [{ model: Company, as: "company", attributes: ["id", "name"] }], + order: [["createdAt", "DESC"]] + }); + + return notes; +}; + +export default FindService; diff --git a/backend/src/services/AnnouncementService/ListService.ts b/backend/src/services/AnnouncementService/ListService.ts new file mode 100644 index 0000000..474a761 --- /dev/null +++ b/backend/src/services/AnnouncementService/ListService.ts @@ -0,0 +1,58 @@ +import { Op, fn, col, where } from "sequelize"; +import { isEmpty } from "lodash"; +import Announcement from "../../models/Announcement"; + +interface Request { + searchParam?: string; + pageNumber?: string; +} + +interface Response { + records: Announcement[]; + count: number; + hasMore: boolean; +} + +const ListService = async ({ + searchParam = "", + pageNumber = "1" +}: Request): Promise => { + let whereCondition: any = { + status: true + }; + + if (!isEmpty(searchParam)) { + whereCondition = { + ...whereCondition, + [Op.or]: [ + { + title: where( + fn("LOWER", col("Announcement.title")), + "LIKE", + `%${searchParam.toLowerCase().trim()}%` + ) + } + ] + }; + } + + const limit = 20; + const offset = limit * (+pageNumber - 1); + + const { count, rows: records } = await Announcement.findAndCountAll({ + where: whereCondition, + limit, + offset, + order: [["createdAt", "DESC"]] + }); + + const hasMore = count > offset + records.length; + + return { + records, + count, + hasMore + }; +}; + +export default ListService; diff --git a/backend/src/services/AnnouncementService/ShowService.ts b/backend/src/services/AnnouncementService/ShowService.ts new file mode 100644 index 0000000..d00e28f --- /dev/null +++ b/backend/src/services/AnnouncementService/ShowService.ts @@ -0,0 +1,14 @@ +import Announcement from "../../models/Announcement"; +import AppError from "../../errors/AppError"; + +const ShowService = async (id: string | number): Promise => { + const record = await Announcement.findByPk(id); + + if (!record) { + throw new AppError("ERR_NO_ANNOUNCEMENT_FOUND", 404); + } + + return record; +}; + +export default ShowService; diff --git a/backend/src/services/AnnouncementService/UpdateService.ts b/backend/src/services/AnnouncementService/UpdateService.ts new file mode 100644 index 0000000..7389cee --- /dev/null +++ b/backend/src/services/AnnouncementService/UpdateService.ts @@ -0,0 +1,27 @@ +import AppError from "../../errors/AppError"; +import Announcement from "../../models/Announcement"; + +interface Data { + id: number | string; + priority: string; + title: string; + text: string; + status: string; + companyId: number; +} + +const UpdateService = async (data: Data): Promise => { + const { id } = data; + + const record = await Announcement.findByPk(id); + + if (!record) { + throw new AppError("ERR_NO_ANNOUNCEMENT_FOUND", 404); + } + + await record.update(data); + + return record; +}; + +export default UpdateService; diff --git a/backend/src/services/AuthServices/FindUserFromToken.ts b/backend/src/services/AuthServices/FindUserFromToken.ts new file mode 100644 index 0000000..20d57f4 --- /dev/null +++ b/backend/src/services/AuthServices/FindUserFromToken.ts @@ -0,0 +1,18 @@ +import { verify } from "jsonwebtoken"; +import ShowUserService from "../UserServices/ShowUserService"; +import authConfig from "../../config/auth"; +import User from "../../models/User"; + +interface RefreshTokenPayload { + id: string; + tokenVersion: number; + companyId: number; +} + +export default async function FindUserFromToken(token: string): Promise { + const decoded = verify(token, authConfig.refreshSecret); + const { id } = decoded as RefreshTokenPayload; + + const user = await ShowUserService(id); + return user; +} diff --git a/backend/src/services/AuthServices/RefreshTokenService.ts b/backend/src/services/AuthServices/RefreshTokenService.ts new file mode 100644 index 0000000..fb19102 --- /dev/null +++ b/backend/src/services/AuthServices/RefreshTokenService.ts @@ -0,0 +1,48 @@ +import { verify } from "jsonwebtoken"; +import { Response as Res } from "express"; + +import User from "../../models/User"; +import AppError from "../../errors/AppError"; +import ShowUserService from "../UserServices/ShowUserService"; +import authConfig from "../../config/auth"; +import { + createAccessToken, + createRefreshToken +} from "../../helpers/CreateTokens"; + +interface RefreshTokenPayload { + id: string; + tokenVersion: number; + companyId: number; +} + +interface Response { + user: User; + newToken: string; + refreshToken: string; +} + +export const RefreshTokenService = async ( + res: Res, + token: string +): Promise => { + try { + const decoded = verify(token, authConfig.refreshSecret); + const { id, tokenVersion, companyId } = decoded as RefreshTokenPayload; + + const user = await ShowUserService(id); + + if (user.tokenVersion !== tokenVersion) { + res.clearCookie("jrt"); + throw new AppError("ERR_SESSION_EXPIRED", 401); + } + + const newToken = createAccessToken(user); + const refreshToken = createRefreshToken(user); + + return { user, newToken, refreshToken }; + } catch (err) { + res.clearCookie("jrt"); + throw new AppError("ERR_SESSION_EXPIRED", 401); + } +}; diff --git a/backend/src/services/BaileysChatServices/CreateOrUpdateBaileysChatService.ts b/backend/src/services/BaileysChatServices/CreateOrUpdateBaileysChatService.ts new file mode 100644 index 0000000..37e5818 --- /dev/null +++ b/backend/src/services/BaileysChatServices/CreateOrUpdateBaileysChatService.ts @@ -0,0 +1,39 @@ +import { Chat } from "@whiskeysockets/baileys"; +import BaileysChats from "../../models/BaileysChats"; + +export const CreateOrUpdateBaileysChatService = async ( + whatsappId: number, + chat: Partial, +): Promise => { + const { id, conversationTimestamp, unreadCount } = chat; + const baileysChat = await BaileysChats.findOne({ + where: { + whatsappId, + jid: id, + } + }); + + if (baileysChat) { + const baileysChats = await baileysChat.update({ + conversationTimestamp, + unreadCount: unreadCount ? baileysChat.unreadCount + unreadCount : 0 + }); + + return baileysChats; + } + // timestamp now + + const timestamp = new Date().getTime(); + + // convert timestamp to number + const conversationTimestampNumber = Number(timestamp); + + const baileysChats = await BaileysChats.create({ + whatsappId, + jid: id, + conversationTimestamp: conversationTimestamp || conversationTimestampNumber, + unreadCount: unreadCount || 1, + }); + + return baileysChats; +}; diff --git a/backend/src/services/BaileysChatServices/DeleteBaileysChatServices.ts b/backend/src/services/BaileysChatServices/DeleteBaileysChatServices.ts new file mode 100644 index 0000000..57313ff --- /dev/null +++ b/backend/src/services/BaileysChatServices/DeleteBaileysChatServices.ts @@ -0,0 +1,13 @@ +import { ShowBaileysChatService } from "./ShowBaileysChatService"; + +export const DeleteBaileysChatServices = async ( + whatsappId: number, + jid: string, +): Promise => { + const showBaileysChatService = await ShowBaileysChatService( + whatsappId, + jid, + ); + + showBaileysChatService.destroy(); +}; diff --git a/backend/src/services/BaileysChatServices/ShowBaileysChatService.ts b/backend/src/services/BaileysChatServices/ShowBaileysChatService.ts new file mode 100644 index 0000000..a93ca2d --- /dev/null +++ b/backend/src/services/BaileysChatServices/ShowBaileysChatService.ts @@ -0,0 +1,19 @@ +import AppError from "../../errors/AppError"; +import BaileysChats from "../../models/BaileysChats"; + +export const ShowBaileysChatService = async ( + whatsappId: number, + jid: string, +): Promise => { + const baileysChat = await BaileysChats.findOne({ + where: { + whatsappId, + jid, + } + }); + + if (baileysChat) { + return baileysChat; + } + +}; diff --git a/backend/src/services/BaileysChatServices/UpdateBaileysChatServices.ts b/backend/src/services/BaileysChatServices/UpdateBaileysChatServices.ts new file mode 100644 index 0000000..dd4a304 --- /dev/null +++ b/backend/src/services/BaileysChatServices/UpdateBaileysChatServices.ts @@ -0,0 +1,30 @@ +import AppError from "../../errors/AppError"; +import BaileysChats from "../../models/BaileysChats"; + +interface Data { + id?: string; + conversationTimestamp?: number; + unreadCount?: number; +} + +export const UpdateBaileysChatServices = async ( + whatsappId: number, + jid: string, + data: Data +): Promise => { + const baileysChat = await BaileysChats.findOne({ + where: { + whatsappId, + jid + } + }); + + if (baileysChat) { + await baileysChat.update({ + conversationTimestamp: data.conversationTimestamp, + unreadCount: data.unreadCount + }); + + return baileysChat; + } +}; diff --git a/backend/src/services/BaileysServices/CreateOrUpdateBaileysService.ts b/backend/src/services/BaileysServices/CreateOrUpdateBaileysService.ts new file mode 100644 index 0000000..5a91d45 --- /dev/null +++ b/backend/src/services/BaileysServices/CreateOrUpdateBaileysService.ts @@ -0,0 +1,57 @@ +import { Chat, Contact } from "@whiskeysockets/baileys"; +import Baileys from "../../models/Baileys"; +import { isArray } from "lodash"; + +interface Request { + whatsappId: number; + contacts?: Contact[]; + chats?: Chat[]; +} + +const createOrUpdateBaileysService = async ({ + whatsappId, + contacts, + chats +}: Request): Promise => { + const baileysExists = await Baileys.findOne({ + where: { whatsappId } + }); + + if (baileysExists) { + const getChats = baileysExists.chats + ? JSON.parse(JSON.stringify(baileysExists.chats)) + : []; + const getContacts = baileysExists.contacts + ? JSON.parse(JSON.stringify(baileysExists.contacts)) + : []; + + if (chats && isArray(getChats)) { + getChats.push(...chats); + getChats.sort(); + getChats.filter((v, i, a) => a.indexOf(v) === i); + } + + if (contacts && isArray(getContacts)) { + getContacts.push(...contacts); + getContacts.sort(); + getContacts.filter((v, i, a) => a.indexOf(v) === i); + } + + const newBaileys = await baileysExists.update({ + chats: JSON.stringify(getChats), + contacts: JSON.stringify(getContacts) + }); + + return newBaileys; + } + + const baileys = await Baileys.create({ + whatsappId, + contacts: JSON.stringify(contacts), + chats: JSON.stringify(chats) + }); + + return baileys; +}; + +export default createOrUpdateBaileysService; diff --git a/backend/src/services/BaileysServices/DeleteBaileysService.ts b/backend/src/services/BaileysServices/DeleteBaileysService.ts new file mode 100644 index 0000000..12396ba --- /dev/null +++ b/backend/src/services/BaileysServices/DeleteBaileysService.ts @@ -0,0 +1,15 @@ +import Baileys from "../../models/Baileys"; + +const DeleteBaileysService = async (id: string | number): Promise => { + const baileysData = await Baileys.findOne({ + where: { + whatsappId: id + } + }); + + if (baileysData) { + await baileysData.destroy(); + } +}; + +export default DeleteBaileysService; diff --git a/backend/src/services/BaileysServices/ShowBaileysService.ts b/backend/src/services/BaileysServices/ShowBaileysService.ts new file mode 100644 index 0000000..5c3d5fb --- /dev/null +++ b/backend/src/services/BaileysServices/ShowBaileysService.ts @@ -0,0 +1,18 @@ +import Baileys from "../../models/Baileys"; +import AppError from "../../errors/AppError"; + +const ShowBaileysService = async (id: string | number): Promise => { + const baileysData = await Baileys.findOne({ + where: { + whatsappId: id + } + }); + + if (!baileysData) { + throw new AppError("ERR_NO_BAILEYS_DATA_FOUND", 404); + } + + return baileysData; +}; + +export default ShowBaileysService; diff --git a/backend/src/services/CampaignService/CancelService.ts b/backend/src/services/CampaignService/CancelService.ts new file mode 100644 index 0000000..2c83668 --- /dev/null +++ b/backend/src/services/CampaignService/CancelService.ts @@ -0,0 +1,26 @@ +import { Op } from "sequelize"; +import Campaign from "../../models/Campaign"; +import CampaignShipping from "../../models/CampaignShipping"; +import { campaignQueue } from "../../queues"; + +export async function CancelService(id: number) { + const campaign = await Campaign.findByPk(id); + await campaign.update({ status: "CANCELADA" }); + + const recordsToCancel = await CampaignShipping.findAll({ + where: { + campaignId: campaign.id, + jobId: { [Op.not]: null }, + deliveredAt: null + } + }); + + const promises = []; + + for (let record of recordsToCancel) { + const job = await campaignQueue.getJob(+record.jobId); + promises.push(job.remove()); + } + + await Promise.all(promises); +} diff --git a/backend/src/services/CampaignService/CreateService.ts b/backend/src/services/CampaignService/CreateService.ts new file mode 100644 index 0000000..a50db6d --- /dev/null +++ b/backend/src/services/CampaignService/CreateService.ts @@ -0,0 +1,58 @@ +import * as Yup from "yup"; +import AppError from "../../errors/AppError"; +import Campaign from "../../models/Campaign"; +import ContactList from "../../models/ContactList"; +import Whatsapp from "../../models/Whatsapp"; + +interface Data { + name: string; + status: string; + confirmation: boolean; + scheduledAt: string; + companyId: number; + contactListId: number; + message1?: string; + message2?: string; + message3?: string; + message4?: string; + message5?: string; + confirmationMessage1?: string; + confirmationMessage2?: string; + confirmationMessage3?: string; + confirmationMessage4?: string; + confirmationMessage5?: string; + fileListId: number; +} + +const CreateService = async (data: Data): Promise => { + const { name } = data; + + const ticketnoteSchema = Yup.object().shape({ + name: Yup.string() + .min(3, "ERR_CAMPAIGN_INVALID_NAME") + .required("ERR_CAMPAIGN_REQUIRED") + }); + + try { + await ticketnoteSchema.validate({ name }); + } catch (err: any) { + throw new AppError(err.message); + } + + if (data.scheduledAt != null && data.scheduledAt != "") { + data.status = "PROGRAMADA"; + } + + const record = await Campaign.create(data); + + await record.reload({ + include: [ + { model: ContactList }, + { model: Whatsapp, attributes: ["id", "name"] } + ] + }); + + return record; +}; + +export default CreateService; diff --git a/backend/src/services/CampaignService/DeleteService.ts b/backend/src/services/CampaignService/DeleteService.ts new file mode 100644 index 0000000..4038555 --- /dev/null +++ b/backend/src/services/CampaignService/DeleteService.ts @@ -0,0 +1,20 @@ +import Campaign from "../../models/Campaign"; +import AppError from "../../errors/AppError"; + +const DeleteService = async (id: string): Promise => { + const record = await Campaign.findOne({ + where: { id } + }); + + if (!record) { + throw new AppError("ERR_NO_CAMPAIGN_FOUND", 404); + } + + if (record.status === "EM_ANDAMENTO") { + throw new AppError("Não é permitido excluir campanha em andamento", 400); + } + + await record.destroy(); +}; + +export default DeleteService; diff --git a/backend/src/services/CampaignService/FindAllService.ts b/backend/src/services/CampaignService/FindAllService.ts new file mode 100644 index 0000000..cff8b37 --- /dev/null +++ b/backend/src/services/CampaignService/FindAllService.ts @@ -0,0 +1,10 @@ +import Campaign from "../../models/Campaign"; + +const FindAllService = async (): Promise => { + const records: Campaign[] = await Campaign.findAll({ + order: [["name", "ASC"]] + }); + return records; +}; + +export default FindAllService; diff --git a/backend/src/services/CampaignService/FindService.ts b/backend/src/services/CampaignService/FindService.ts new file mode 100644 index 0000000..128e4c1 --- /dev/null +++ b/backend/src/services/CampaignService/FindService.ts @@ -0,0 +1,20 @@ +import Campaign from "../../models/Campaign"; +import Company from "../../models/Company"; + +type Params = { + companyId: string; +}; + +const FindService = async ({ companyId }: Params): Promise => { + const notes: Campaign[] = await Campaign.findAll({ + where: { + companyId + }, + include: [{ model: Company, as: "company", attributes: ["id", "name"] }], + order: [["name", "ASC"]] + }); + + return notes; +}; + +export default FindService; diff --git a/backend/src/services/CampaignService/ListService.ts b/backend/src/services/CampaignService/ListService.ts new file mode 100644 index 0000000..234504e --- /dev/null +++ b/backend/src/services/CampaignService/ListService.ts @@ -0,0 +1,66 @@ +import { Op, fn, col, where } from "sequelize"; +import Campaign from "../../models/Campaign"; +import { isEmpty } from "lodash"; +import ContactList from "../../models/ContactList"; +import Whatsapp from "../../models/Whatsapp"; + +interface Request { + companyId: number | string; + searchParam?: string; + pageNumber?: string; +} + +interface Response { + records: Campaign[]; + count: number; + hasMore: boolean; +} + +const ListService = async ({ + searchParam = "", + pageNumber = "1", + companyId +}: Request): Promise => { + let whereCondition: any = { + companyId + }; + + if (!isEmpty(searchParam)) { + whereCondition = { + ...whereCondition, + [Op.or]: [ + { + name: where( + fn("LOWER", col("Campaign.name")), + "LIKE", + `%${searchParam.toLowerCase().trim()}%` + ) + } + ] + }; + } + + const limit = 20; + const offset = limit * (+pageNumber - 1); + + const { count, rows: records } = await Campaign.findAndCountAll({ + where: whereCondition, + limit, + offset, + order: [["name", "ASC"]], + include: [ + { model: ContactList }, + { model: Whatsapp, attributes: ["id", "name"] } + ] + }); + + const hasMore = count > offset + records.length; + + return { + records, + count, + hasMore + }; +}; + +export default ListService; diff --git a/backend/src/services/CampaignService/RestartService.ts b/backend/src/services/CampaignService/RestartService.ts new file mode 100644 index 0000000..3ec214d --- /dev/null +++ b/backend/src/services/CampaignService/RestartService.ts @@ -0,0 +1,12 @@ +import Campaign from "../../models/Campaign"; +import { campaignQueue } from "../../queues"; + +export async function RestartService(id: number) { + const campaign = await Campaign.findByPk(id); + await campaign.update({ status: "EM_ANDAMENTO" }); + + await campaignQueue.add("ProcessCampaign", { + id: campaign.id, + delay: 3000 + }); +} diff --git a/backend/src/services/CampaignService/ShowService.ts b/backend/src/services/CampaignService/ShowService.ts new file mode 100644 index 0000000..16974a5 --- /dev/null +++ b/backend/src/services/CampaignService/ShowService.ts @@ -0,0 +1,24 @@ +import Campaign from "../../models/Campaign"; +import AppError from "../../errors/AppError"; +import CampaignShipping from "../../models/CampaignShipping"; +import ContactList from "../../models/ContactList"; +import ContactListItem from "../../models/ContactListItem"; +import Whatsapp from "../../models/Whatsapp"; + +const ShowService = async (id: string | number): Promise => { + const record = await Campaign.findByPk(id, { + include: [ + { model: CampaignShipping }, + { model: ContactList, include: [{ model: ContactListItem }] }, + { model: Whatsapp, attributes: ["id", "name"] } + ] + }); + + if (!record) { + throw new AppError("ERR_NO_TICKETNOTE_FOUND", 404); + } + + return record; +}; + +export default ShowService; diff --git a/backend/src/services/CampaignService/UpdateService.ts b/backend/src/services/CampaignService/UpdateService.ts new file mode 100644 index 0000000..fa33ed4 --- /dev/null +++ b/backend/src/services/CampaignService/UpdateService.ts @@ -0,0 +1,63 @@ +import AppError from "../../errors/AppError"; +import Campaign from "../../models/Campaign"; +import ContactList from "../../models/ContactList"; +import Whatsapp from "../../models/Whatsapp"; + +interface Data { + id: number | string; + name: string; + status: string; + confirmation: boolean; + scheduledAt: string; + companyId: number; + contactListId: number; + message1?: string; + message2?: string; + message3?: string; + message4?: string; + message5?: string; + confirmationMessage1?: string; + confirmationMessage2?: string; + confirmationMessage3?: string; + confirmationMessage4?: string; + confirmationMessage5?: string; + fileListId: number; +} + +const UpdateService = async (data: Data): Promise => { + const { id } = data; + + const record = await Campaign.findByPk(id); + + if (!record) { + throw new AppError("ERR_NO_CAMPAIGN_FOUND", 404); + } + + if (["INATIVA", "PROGRAMADA", "CANCELADA"].indexOf(data.status) === -1) { + throw new AppError( + "Só é permitido alterar campanha Inativa e Programada", + 400 + ); + } + + if ( + data.scheduledAt != null && + data.scheduledAt != "" && + data.status === "INATIVA" + ) { + data.status = "PROGRAMADA"; + } + + await record.update(data); + + await record.reload({ + include: [ + { model: ContactList }, + { model: Whatsapp, attributes: ["id", "name"] } + ] + }); + + return record; +}; + +export default UpdateService; diff --git a/backend/src/services/CampaignSettingServices/CreateService.ts b/backend/src/services/CampaignSettingServices/CreateService.ts new file mode 100644 index 0000000..7afeee4 --- /dev/null +++ b/backend/src/services/CampaignSettingServices/CreateService.ts @@ -0,0 +1,36 @@ +import CampaignSetting from "../../models/CampaignSetting"; +import { isArray, isObject } from "lodash"; + +interface Data { + settings: any; +} + +const CreateService = async ( + data: Data, + companyId: number +): Promise => { + const settings = []; + for (let settingKey of Object.keys(data.settings)) { + const value = + isArray(data.settings[settingKey]) || isObject(data.settings[settingKey]) + ? JSON.stringify(data.settings[settingKey]) + : data.settings[settingKey]; + const [record, created] = await CampaignSetting.findOrCreate({ + where: { + key: settingKey, + companyId + }, + defaults: { key: settingKey, value, companyId } + }); + + if (!created) { + await record.update({ value }); + } + + settings.push(record); + } + + return settings; +}; + +export default CreateService; diff --git a/backend/src/services/CampaignSettingServices/ListService.ts b/backend/src/services/CampaignSettingServices/ListService.ts new file mode 100644 index 0000000..009df3a --- /dev/null +++ b/backend/src/services/CampaignSettingServices/ListService.ts @@ -0,0 +1,34 @@ +import { Op, fn, col, where } from "sequelize"; +import Campaign from "../../models/Campaign"; +import { isEmpty } from "lodash"; +import ContactList from "../../models/ContactList"; +import Whatsapp from "../../models/Whatsapp"; +import CampaignSetting from "../../models/CampaignSetting"; + +interface Request { + companyId: number | string; + searchParam?: string; + pageNumber?: string; +} + +interface Response { + records: Campaign[]; + count: number; + hasMore: boolean; +} + +const ListService = async ({ + companyId +}: Request): Promise => { + let whereCondition: any = { + companyId + }; + + const records = await CampaignSetting.findAll({ + where: whereCondition + }); + + return records; +}; + +export default ListService; diff --git a/backend/src/services/ChatService/CreateMessageService.ts b/backend/src/services/ChatService/CreateMessageService.ts new file mode 100644 index 0000000..946e615 --- /dev/null +++ b/backend/src/services/ChatService/CreateMessageService.ts @@ -0,0 +1,52 @@ +import { Op } from "sequelize"; +import Chat from "../../models/Chat"; +import ChatMessage from "../../models/ChatMessage"; +import ChatUser from "../../models/ChatUser"; +import User from "../../models/User"; + +export interface ChatMessageData { + senderId: number; + chatId: number; + message: string; +} + +export default async function CreateMessageService({ + senderId, + chatId, + message +}: ChatMessageData) { + const newMessage = await ChatMessage.create({ + senderId, + chatId, + message + }); + + await newMessage.reload({ + include: [ + { model: User, as: "sender", attributes: ["id", "name"] }, + { + model: Chat, + as: "chat", + include: [{ model: ChatUser, as: "users" }] + } + ] + }); + + const sender = await User.findByPk(senderId); + + await newMessage.chat.update({ lastMessage: `${sender.name}: ${message}` }); + + const chatUsers = await ChatUser.findAll({ + where: { chatId } + }); + + for (let chatUser of chatUsers) { + if (chatUser.userId === senderId) { + await chatUser.update({ unreads: 0 }); + } else { + await chatUser.update({ unreads: chatUser.unreads + 1 }); + } + } + + return newMessage; +} diff --git a/backend/src/services/ChatService/CreateService.ts b/backend/src/services/ChatService/CreateService.ts new file mode 100644 index 0000000..6b1ff9e --- /dev/null +++ b/backend/src/services/ChatService/CreateService.ts @@ -0,0 +1,38 @@ +import Chat from "../../models/Chat"; +import ChatUser from "../../models/ChatUser"; +import User from "../../models/User"; + +interface Data { + ownerId: number; + companyId: number; + users: any[]; + title: string; +} + +const CreateService = async (data: Data): Promise => { + const { ownerId, companyId, users, title } = data; + + const record = await Chat.create({ + ownerId, + companyId, + title + }); + + if (Array.isArray(users) && users.length > 0) { + await ChatUser.create({ chatId: record.id, userId: ownerId }); + for (let user of users) { + await ChatUser.create({ chatId: record.id, userId: user.id }); + } + } + + await record.reload({ + include: [ + { model: ChatUser, as: "users", include: [{ model: User, as: "user" }] }, + { model: User, as: "owner" } + ] + }); + + return record; +}; + +export default CreateService; diff --git a/backend/src/services/ChatService/DeleteService.ts b/backend/src/services/ChatService/DeleteService.ts new file mode 100644 index 0000000..e560f24 --- /dev/null +++ b/backend/src/services/ChatService/DeleteService.ts @@ -0,0 +1,16 @@ +import Chat from "../../models/Chat"; +import AppError from "../../errors/AppError"; + +const DeleteService = async (id: string): Promise => { + const record = await Chat.findOne({ + where: { id } + }); + + if (!record) { + throw new AppError("ERR_NO_CHAT_FOUND", 404); + } + + await record.destroy(); +}; + +export default DeleteService; diff --git a/backend/src/services/ChatService/FindAllService.ts b/backend/src/services/ChatService/FindAllService.ts new file mode 100644 index 0000000..afbc09a --- /dev/null +++ b/backend/src/services/ChatService/FindAllService.ts @@ -0,0 +1,10 @@ +import Chat from "../../models/Chat"; + +const FindAllService = async (): Promise => { + const records: Chat[] = await Chat.findAll({ + order: [["createdAt", "DESC"]] + }); + return records; +}; + +export default FindAllService; diff --git a/backend/src/services/ChatService/FindMessages.ts b/backend/src/services/ChatService/FindMessages.ts new file mode 100644 index 0000000..f2dd5f4 --- /dev/null +++ b/backend/src/services/ChatService/FindMessages.ts @@ -0,0 +1,58 @@ +import AppError from "../../errors/AppError"; +import ChatMessage from "../../models/ChatMessage"; +import ChatUser from "../../models/ChatUser"; +import User from "../../models/User"; + +import { sortBy } from "lodash"; + +interface Request { + chatId: string; + ownerId: number; + pageNumber?: string; +} + +interface Response { + records: ChatMessage[]; + count: number; + hasMore: boolean; +} + +const FindMessages = async ({ + chatId, + ownerId, + pageNumber = "1" +}: Request): Promise => { + const userInChat = await ChatUser.count({ + where: { chatId, userId: ownerId } + }); + + if (userInChat === 0) { + throw new AppError("UNAUTHORIZED", 400); + } + + const limit = 20; + const offset = limit * (+pageNumber - 1); + + const { count, rows: records } = await ChatMessage.findAndCountAll({ + where: { + chatId + }, + include: [{ model: User, as: "sender", attributes: ["id", "name"] }], + limit, + offset, + + order: [["createdAt", "DESC"]] + }); + + const hasMore = count > offset + records.length; + + const sorted = sortBy(records, ["id", "ASC"]); + + return { + records: sorted, + count, + hasMore + }; +}; + +export default FindMessages; diff --git a/backend/src/services/ChatService/FindService.ts b/backend/src/services/ChatService/FindService.ts new file mode 100644 index 0000000..c849990 --- /dev/null +++ b/backend/src/services/ChatService/FindService.ts @@ -0,0 +1,26 @@ +import Chat from "../../models/Chat"; +import Company from "../../models/Company"; +import User from "../../models/User"; + +type Params = { + companyId: number; + ownerId?: number; +}; + +const FindService = async ({ ownerId, companyId }: Params): Promise => { + const chats: Chat[] = await Chat.findAll({ + where: { + ownerId, + companyId + }, + include: [ + { model: Company, as: "company", attributes: ["id", "name"] }, + { model: User, as: "owner", attributes: ["id", "name"] } + ], + order: [["createdAt", "DESC"]] + }); + + return chats; +}; + +export default FindService; diff --git a/backend/src/services/ChatService/ListService.ts b/backend/src/services/ChatService/ListService.ts new file mode 100644 index 0000000..38246d0 --- /dev/null +++ b/backend/src/services/ChatService/ListService.ts @@ -0,0 +1,54 @@ +import { Op } from "sequelize"; +import Chat from "../../models/Chat"; +import ChatUser from "../../models/ChatUser"; +import User from "../../models/User"; + +interface Request { + ownerId: number; + pageNumber?: string; +} + +interface Response { + records: Chat[]; + count: number; + hasMore: boolean; +} + +const ListService = async ({ + ownerId, + pageNumber = "1" +}: Request): Promise => { + const chatUsers = await ChatUser.findAll({ + where: { userId: ownerId } + }); + + const chatIds = chatUsers.map(chat => chat.chatId); + + const limit = 20; + const offset = limit * (+pageNumber - 1); + + const { count, rows: records } = await Chat.findAndCountAll({ + where: { + id: { + [Op.in]: chatIds + } + }, + include: [ + { model: User, as: "owner" }, + { model: ChatUser, as: "users", include: [{ model: User, as: "user" }] } + ], + limit, + offset, + order: [["createdAt", "DESC"]] + }); + + const hasMore = count > offset + records.length; + + return { + records, + count, + hasMore + }; +}; + +export default ListService; diff --git a/backend/src/services/ChatService/ShowFromUuidService.ts b/backend/src/services/ChatService/ShowFromUuidService.ts new file mode 100644 index 0000000..dd5f950 --- /dev/null +++ b/backend/src/services/ChatService/ShowFromUuidService.ts @@ -0,0 +1,14 @@ +import Chat from "../../models/Chat"; +import AppError from "../../errors/AppError"; + +const ShowFromUuidService = async (uuid: string): Promise => { + const record = await Chat.findOne({ where: { uuid } }); + + if (!record) { + throw new AppError("ERR_NO_CHAT_FOUND", 404); + } + + return record; +}; + +export default ShowFromUuidService; diff --git a/backend/src/services/ChatService/ShowService.ts b/backend/src/services/ChatService/ShowService.ts new file mode 100644 index 0000000..55be2d2 --- /dev/null +++ b/backend/src/services/ChatService/ShowService.ts @@ -0,0 +1,14 @@ +import Chat from "../../models/Chat"; +import AppError from "../../errors/AppError"; + +const ShowService = async (id: string | number): Promise => { + const record = await Chat.findByPk(id); + + if (!record) { + throw new AppError("ERR_NO_CHAT_FOUND", 404); + } + + return record; +}; + +export default ShowService; diff --git a/backend/src/services/ChatService/UpdateService.ts b/backend/src/services/ChatService/UpdateService.ts new file mode 100644 index 0000000..8ebdad8 --- /dev/null +++ b/backend/src/services/ChatService/UpdateService.ts @@ -0,0 +1,38 @@ +import Chat from "../../models/Chat"; +import ChatUser from "../../models/ChatUser"; +import User from "../../models/User"; + +interface ChatData { + id: number; + title?: string; + users?: any[]; +} + +export default async function UpdateService(data: ChatData) { + const { users } = data; + const record = await Chat.findByPk(data.id, { + include: [{ model: ChatUser, as: "users" }] + }); + const { ownerId } = record; + + await record.update({ title: data.title }); + + if (Array.isArray(users)) { + await ChatUser.destroy({ where: { chatId: record.id } }); + await ChatUser.create({ chatId: record.id, userId: ownerId }); + for (let user of users) { + if (user.id !== ownerId) { + await ChatUser.create({ chatId: record.id, userId: user.id }); + } + } + } + + await record.reload({ + include: [ + { model: ChatUser, as: "users", include: [{ model: User, as: "user" }] }, + { model: User, as: "owner" } + ] + }); + + return record; +} diff --git a/backend/src/services/CompanyService/CreateCompanyService.ts b/backend/src/services/CompanyService/CreateCompanyService.ts new file mode 100644 index 0000000..c50ff50 --- /dev/null +++ b/backend/src/services/CompanyService/CreateCompanyService.ts @@ -0,0 +1,305 @@ +import * as Yup from "yup"; +import AppError from "../../errors/AppError"; +import Company from "../../models/Company"; +import User from "../../models/User"; +import Setting from "../../models/Setting"; + +interface CompanyData { + name: string; + phone?: string; + email?: string; + password?: string; + status?: boolean; + planId?: number; + campaignsEnabled?: boolean; + dueDate?: string; + recurrence?: string; +} + +const CreateCompanyService = async ( + companyData: CompanyData +): Promise => { + const { + name, + phone, + email, + status, + planId, + password, + campaignsEnabled, + dueDate, + recurrence + } = companyData; + + const companySchema = Yup.object().shape({ + name: Yup.string() + .min(2, "ERR_COMPANY_INVALID_NAME") + .required("ERR_COMPANY_INVALID_NAME") + .test( + "Check-unique-name", + "ERR_COMPANY_NAME_ALREADY_EXISTS", + async value => { + if (value) { + const companyWithSameName = await Company.findOne({ + where: { name: value } + }); + + return !companyWithSameName; + } + return false; + } + ) + }); + + try { + await companySchema.validate({ name }); + } catch (err: any) { + throw new AppError(err.message); + } + + const company = await Company.create({ + name, + phone, + email, + status, + planId, + dueDate, + recurrence + }); + + const user = await User.create({ + name: company.name, + email: company.email, + password: companyData.password, + profile: "admin", + companyId: company.id + }); + + await Setting.findOrCreate({ + where: { + companyId: company.id, + key: "asaas" + }, + defaults: { + companyId: company.id, + key: "asaas", + value: "" + }, + }); + + //tokenixc + await Setting.findOrCreate({ + where: { + companyId: company.id, + key: "tokenixc" + }, + defaults: { + companyId: company.id, + key: "tokenixc", + value: "" + }, + }); + + //ipixc + await Setting.findOrCreate({ + where: { + companyId: company.id, + key: "ipixc" + }, + defaults: { + companyId: company.id, + key: "ipixc", + value: "" + }, + }); + + //ipmkauth + await Setting.findOrCreate({ + where: { + companyId: company.id, + key: "ipmkauth" + }, + defaults: { + companyId: company.id, + key: "ipmkauth", + value: "" + }, + }); + + //clientsecretmkauth + await Setting.findOrCreate({ + where: { + companyId: company.id, + key: "clientsecretmkauth" + }, + defaults: { + companyId: company.id, + key: "clientsecretmkauth", + value: "" + }, + }); + + //clientidmkauth + await Setting.findOrCreate({ + where: { + companyId: company.id, + key: "clientidmkauth" + }, + defaults: { + companyId: company.id, + key: "clientidmkauth", + value: "" + }, + }); + + //CheckMsgIsGroup + await Setting.findOrCreate({ + where: { + companyId: company.id, + key: "CheckMsgIsGroup" + }, + defaults: { + companyId: company.id, + key: "enabled", + value: "" + }, + }); + + //CheckMsgIsGroup + await Setting.findOrCreate({ + where: { + companyId: company.id, + key: "" + }, + defaults: { + companyId: company.id, + key: "call", + value: "disabled" + }, + }); + + //scheduleType + await Setting.findOrCreate({ + where: { + companyId: company.id, + key: "scheduleType" + }, + defaults: { + companyId: company.id, + key: "scheduleType", + value: "disabled" + }, + }); + + + // Enviar mensagem ao aceitar ticket + await Setting.findOrCreate({ + where:{ + companyId: company.id, + key: "sendGreetingAccepted", + }, + defaults: { + companyId: company.id, + key: "sendGreetingAccepted", + value: "disabled" + }, + }); + + // Enviar mensagem de transferencia + await Setting.findOrCreate({ + where:{ + companyId: company.id, + key: "sendMsgTransfTicket", + }, + defaults: { + companyId: company.id, + key: "sendMsgTransfTicket", + value: "disabled" + }, + }); + + //userRating + await Setting.findOrCreate({ + where: { + companyId: company.id, + key: "userRating" + }, + defaults: { + companyId: company.id, + key: "userRating", + value: "disabled" + }, + }); + + //userRating + await Setting.findOrCreate({ + where: { + companyId: company.id, + key: "chatBotType" + }, + defaults: { + companyId: company.id, + key: "chatBotType", + value: "text" + }, + + }); + + await Setting.findOrCreate({ + where: { + companyId: company.id, + key: "tokensgp" + }, + defaults: { + companyId: company.id, + key: "tokensgp", + value: "" + }, + }); + + await Setting.findOrCreate({ + where: { + companyId: company.id, + key: "ipsgp" + }, + defaults: { + companyId: company.id, + key: "ipsgp", + value: "" + }, + }); + + await Setting.findOrCreate({ + where: { + companyId: company.id, + key: "appsgp" + }, + defaults: { + companyId: company.id, + key: "appsgp", + value: "" + }, + }); + + if (companyData.campaignsEnabled !== undefined) { + const [setting, created] = await Setting.findOrCreate({ + where: { + companyId: company.id, + key: "campaignsEnabled" + }, + defaults: { + companyId: company.id, + key: "campaignsEnabled", + value: `${campaignsEnabled}` + }, + + }); + if (!created) { + await setting.update({ value: `${campaignsEnabled}` }); + } + } + + return company; +}; + +export default CreateCompanyService; \ No newline at end of file diff --git a/backend/src/services/CompanyService/DeleteCompanyService.ts b/backend/src/services/CompanyService/DeleteCompanyService.ts new file mode 100644 index 0000000..c4c9651 --- /dev/null +++ b/backend/src/services/CompanyService/DeleteCompanyService.ts @@ -0,0 +1,16 @@ +import Company from "../../models/Company"; +import AppError from "../../errors/AppError"; + +const DeleteCompanyService = async (id: string): Promise => { + const company = await Company.findOne({ + where: { id } + }); + + if (!company) { + throw new AppError("ERR_NO_COMPANY_FOUND", 404); + } + + await company.destroy(); +}; + +export default DeleteCompanyService; diff --git a/backend/src/services/CompanyService/FindAllCompaniesService.ts b/backend/src/services/CompanyService/FindAllCompaniesService.ts new file mode 100644 index 0000000..e593345 --- /dev/null +++ b/backend/src/services/CompanyService/FindAllCompaniesService.ts @@ -0,0 +1,16 @@ +import Company from "../../models/Company"; +import Plan from "../../models/Plan"; +import Setting from "../../models/Setting"; + +const FindAllCompanyService = async (): Promise => { + const companies = await Company.findAll({ + order: [["name", "ASC"]], + include: [ + { model: Plan, as: "plan", attributes: ["id", "name", "value"] }, + { model: Setting, as: "settings" } + ] + }); + return companies; +}; + +export default FindAllCompanyService; diff --git a/backend/src/services/CompanyService/ListCompaniesPlanService.ts b/backend/src/services/CompanyService/ListCompaniesPlanService.ts new file mode 100644 index 0000000..cf76d87 --- /dev/null +++ b/backend/src/services/CompanyService/ListCompaniesPlanService.ts @@ -0,0 +1,32 @@ +import Company from "../../models/Company"; +import Plan from "../../models/Plan"; + +const ListCompaniesPlanService = async (): Promise => { + const companies = await Company.findAll({ + attributes: ["id", "name", "email", "status", "dueDate", "createdAt", "phone"], + order: [["name", "ASC"]], + include: [ + { + model: Plan, as: "plan", + attributes: [ + "id", + "name", + "users", + "connections", + "queues", + "value", + "useCampaigns", + "useSchedules", + "useInternalChat", + "useExternalApi", + "useKanban", + "useOpenAi", + "useIntegrations" + ] + }, + ] + }); + return companies; +}; + +export default ListCompaniesPlanService; diff --git a/backend/src/services/CompanyService/ListCompaniesService.ts b/backend/src/services/CompanyService/ListCompaniesService.ts new file mode 100644 index 0000000..69b813f --- /dev/null +++ b/backend/src/services/CompanyService/ListCompaniesService.ts @@ -0,0 +1,50 @@ +import { Sequelize, Op } from "sequelize"; +import Company from "../../models/Company"; + +interface Request { + searchParam?: string; + pageNumber?: string; +} + +interface Response { + companies: Company[]; + count: number; + hasMore: boolean; +} + +const ListCompaniesService = async ({ + searchParam = "", + pageNumber = "1", +}: Request): Promise => { + const whereCondition = { + [Op.or]: [ + { + name: Sequelize.where( + Sequelize.fn("LOWER", Sequelize.col("name")), + "LIKE", + `%${searchParam.toLowerCase().trim()}%` + ) + } + ] + }; + const limit = 20; + const offset = limit * (+pageNumber - 1); + + + const { count, rows: companies } = await Company.findAndCountAll({ + where: whereCondition, + limit, + offset, + order: [["name", "ASC"]] + }); + + const hasMore = count > offset + companies.length; + + return { + companies, + count, + hasMore, + }; +}; + +export default ListCompaniesService; diff --git a/backend/src/services/CompanyService/ShowCompanyService.ts b/backend/src/services/CompanyService/ShowCompanyService.ts new file mode 100644 index 0000000..bede133 --- /dev/null +++ b/backend/src/services/CompanyService/ShowCompanyService.ts @@ -0,0 +1,14 @@ +import Company from "../../models/Company"; +import AppError from "../../errors/AppError"; + +const ShowCompanyService = async (id: string | number): Promise => { + const company = await Company.findByPk(id); + + if (!company) { + throw new AppError("ERR_NO_COMPANY_FOUND", 404); + } + + return company; +}; + +export default ShowCompanyService; diff --git a/backend/src/services/CompanyService/ShowPlanCompanyService.ts b/backend/src/services/CompanyService/ShowPlanCompanyService.ts new file mode 100644 index 0000000..6b01aa1 --- /dev/null +++ b/backend/src/services/CompanyService/ShowPlanCompanyService.ts @@ -0,0 +1,34 @@ +import Company from "../../models/Company"; +import Plan from "../../models/Plan"; + +const ShowPlanCompanyService = async (id: string | number): Promise => { + const companies = await Company.findOne({ + where: { id }, + attributes: ["id", "name", "email", "status", "dueDate", "createdAt", "phone"], + order: [["name", "ASC"]], + include: [ + { + model: Plan, as: "plan", + attributes: [ + "id", + "name", + "users", + "connections", + "queues", + "value", + "useCampaigns", + "useSchedules", + "useInternalChat", + "useExternalApi", + "useKanban", + "useOpenAi", + "useIntegrations" + ] + }, + ] + }); + + return companies; +}; + +export default ShowPlanCompanyService; diff --git a/backend/src/services/CompanyService/UpdateCompanyService.ts b/backend/src/services/CompanyService/UpdateCompanyService.ts new file mode 100644 index 0000000..92351d8 --- /dev/null +++ b/backend/src/services/CompanyService/UpdateCompanyService.ts @@ -0,0 +1,66 @@ +import AppError from "../../errors/AppError"; +import Company from "../../models/Company"; +import Setting from "../../models/Setting"; + +interface CompanyData { + name: string; + id?: number | string; + phone?: string; + email?: string; + status?: boolean; + planId?: number; + campaignsEnabled?: boolean; + dueDate?: string; + recurrence?: string; +} + +const UpdateCompanyService = async ( + companyData: CompanyData +): Promise => { + const company = await Company.findByPk(companyData.id); + const { + name, + phone, + email, + status, + planId, + campaignsEnabled, + dueDate, + recurrence + } = companyData; + + if (!company) { + throw new AppError("ERR_NO_COMPANY_FOUND", 404); + } + + await company.update({ + name, + phone, + email, + status, + planId, + dueDate, + recurrence + }); + + if (companyData.campaignsEnabled !== undefined) { + const [setting, created] = await Setting.findOrCreate({ + where: { + companyId: company.id, + key: "campaignsEnabled" + }, + defaults: { + companyId: company.id, + key: "campaignsEnabled", + value: `${campaignsEnabled}` + } + }); + if (!created) { + await setting.update({ value: `${campaignsEnabled}` }); + } + } + + return company; +}; + +export default UpdateCompanyService; diff --git a/backend/src/services/CompanyService/UpdateSchedulesService.ts b/backend/src/services/CompanyService/UpdateSchedulesService.ts new file mode 100644 index 0000000..afaef18 --- /dev/null +++ b/backend/src/services/CompanyService/UpdateSchedulesService.ts @@ -0,0 +1,26 @@ +import AppError from "../../errors/AppError"; +import Company from "../../models/Company"; + +type ScheduleData = { + id: number | string; + schedules: []; +}; + +const UpdateSchedulesService = async ({ + id, + schedules +}: ScheduleData): Promise => { + const company = await Company.findByPk(id); + + if (!company) { + throw new AppError("ERR_NO_COMPANY_FOUND", 404); + } + + await company.update({ + schedules + }); + + return company; +}; + +export default UpdateSchedulesService; diff --git a/backend/src/services/CompanyService/VerifyCurrentSchedule.ts b/backend/src/services/CompanyService/VerifyCurrentSchedule.ts new file mode 100644 index 0000000..4b0bd6f --- /dev/null +++ b/backend/src/services/CompanyService/VerifyCurrentSchedule.ts @@ -0,0 +1,45 @@ +import { QueryTypes } from "sequelize"; +import sequelize from "../../database"; + +type Result = { + id: number; + currentSchedule: []; + startTime: string; + endTime: string; + inActivity: boolean; +}; + +const VerifyCurrentSchedule = async (id: string | number): Promise => { + const sql = ` + select + s.id, + s.currentWeekday, + s.currentSchedule, + (s.currentSchedule->>'startTime')::time "startTime", + (s.currentSchedule->>'endTime')::time "endTime", + ( + now()::time >= (s.currentSchedule->>'startTime')::time and + now()::time <= (s.currentSchedule->>'endTime')::time + ) "inActivity" + from ( + SELECT + c.id, + to_char(current_date, 'day') currentWeekday, + (array_to_json(array_agg(s))->>0)::jsonb currentSchedule + FROM "Companies" c, jsonb_array_elements(c.schedules) s + WHERE s->>'weekdayEn' like trim(to_char(current_date, 'day')) and c.id = :id + GROUP BY 1, 2 + ) s + where s.currentSchedule->>'startTime' not like '' and s.currentSchedule->>'endTime' not like ''; + `; + + const result: Result = await sequelize.query(sql, { + replacements: { id }, + type: QueryTypes.SELECT, + plain: true + }); + + return result; +}; + +export default VerifyCurrentSchedule; diff --git a/backend/src/services/ContactListItemService/CreateService.ts b/backend/src/services/ContactListItemService/CreateService.ts new file mode 100644 index 0000000..8b69715 --- /dev/null +++ b/backend/src/services/ContactListItemService/CreateService.ts @@ -0,0 +1,52 @@ +import * as Yup from "yup"; +import AppError from "../../errors/AppError"; +import ContactListItem from "../../models/ContactListItem"; +import { logger } from "../../utils/logger"; +import CheckContactNumber from "../WbotServices/CheckNumber"; + +interface Data { + name: string; + number: string; + contactListId: number; + companyId: number; + email?: string; +} + +const CreateService = async (data: Data): Promise => { + const { name } = data; + + const contactListItemSchema = Yup.object().shape({ + name: Yup.string() + .min(3, "ERR_CONTACTLISTITEM_INVALID_NAME") + .required("ERR_CONTACTLISTITEM_REQUIRED") + }); + + try { + await contactListItemSchema.validate({ name }); + } catch (err: any) { + throw new AppError(err.message); + } + + const [record] = await ContactListItem.findOrCreate({ + where: { + number: data.number, + companyId: data.companyId, + contactListId: data.contactListId + }, + defaults: data + }); + + try { + const response = await CheckContactNumber(record.number, record.companyId); + record.isWhatsappValid = response.exists; + const number = response.jid.replace(/\D/g, ""); + record.number = number; + await record.save(); + } catch (e) { + logger.error(`Número de contato inválido: ${record.number}`); + } + + return record; +}; + +export default CreateService; diff --git a/backend/src/services/ContactListItemService/DeleteService.ts b/backend/src/services/ContactListItemService/DeleteService.ts new file mode 100644 index 0000000..2824a96 --- /dev/null +++ b/backend/src/services/ContactListItemService/DeleteService.ts @@ -0,0 +1,16 @@ +import ContactListItem from "../../models/ContactListItem"; +import AppError from "../../errors/AppError"; + +const DeleteService = async (id: string): Promise => { + const record = await ContactListItem.findOne({ + where: { id } + }); + + if (!record) { + throw new AppError("ERR_NO_CONTACTLISTITEM_FOUND", 404); + } + + await record.destroy(); +}; + +export default DeleteService; diff --git a/backend/src/services/ContactListItemService/FindAllService.ts b/backend/src/services/ContactListItemService/FindAllService.ts new file mode 100644 index 0000000..2e4f158 --- /dev/null +++ b/backend/src/services/ContactListItemService/FindAllService.ts @@ -0,0 +1,10 @@ +import ContactListItem from "../../models/ContactListItem"; + +const FindAllService = async (): Promise => { + const records: ContactListItem[] = await ContactListItem.findAll({ + order: [["name", "ASC"]] + }); + return records; +}; + +export default FindAllService; diff --git a/backend/src/services/ContactListItemService/FindService.ts b/backend/src/services/ContactListItemService/FindService.ts new file mode 100644 index 0000000..e574f38 --- /dev/null +++ b/backend/src/services/ContactListItemService/FindService.ts @@ -0,0 +1,33 @@ +import ContactListItem from "../../models/ContactListItem"; +import Company from "../../models/Company"; + +type Params = { + companyId: number; + contactListId: number; +}; + +const FindService = async ({ + companyId, + contactListId +}: Params): Promise => { + let where: any = { + companyId + }; + + if (contactListId) { + where = { + ...where, + contactListId + }; + } + + const notes: ContactListItem[] = await ContactListItem.findAll({ + where, + include: [{ model: Company, as: "company", attributes: ["id", "name"] }], + order: [["name", "ASC"]] + }); + + return notes; +}; + +export default FindService; diff --git a/backend/src/services/ContactListItemService/ListService.ts b/backend/src/services/ContactListItemService/ListService.ts new file mode 100644 index 0000000..ab1f53f --- /dev/null +++ b/backend/src/services/ContactListItemService/ListService.ts @@ -0,0 +1,57 @@ +import { Sequelize, Op } from "sequelize"; +import ContactListItem from "../../models/ContactListItem"; + +interface Request { + searchParam?: string; + pageNumber?: string; + companyId: number | string; + contactListId: number | string; +} + +interface Response { + contacts: ContactListItem[]; + count: number; + hasMore: boolean; +} + +const ListService = async ({ + searchParam = "", + pageNumber = "1", + companyId, + contactListId +}: Request): Promise => { + const whereCondition = { + [Op.or]: [ + { + name: Sequelize.where( + Sequelize.fn("LOWER", Sequelize.col("name")), + "LIKE", + `%${searchParam.toLowerCase().trim()}%` + ) + }, + { number: { [Op.like]: `%${searchParam.toLowerCase().trim()}%` } } + ], + companyId, + contactListId + }; + + const limit = 20; + const offset = limit * (+pageNumber - 1); + + const { count, rows: contacts } = await ContactListItem.findAndCountAll({ + where: whereCondition, + limit, + offset, + order: [["name", "ASC"]] + }); + + const hasMore = count > offset + contacts.length; + + return { + contacts, + count, + hasMore + }; +}; + +export default ListService; diff --git a/backend/src/services/ContactListItemService/ShowService.ts b/backend/src/services/ContactListItemService/ShowService.ts new file mode 100644 index 0000000..1b09384 --- /dev/null +++ b/backend/src/services/ContactListItemService/ShowService.ts @@ -0,0 +1,14 @@ +import ContactListItem from "../../models/ContactListItem"; +import AppError from "../../errors/AppError"; + +const ShowService = async (id: string | number): Promise => { + const record = await ContactListItem.findByPk(id); + + if (!record) { + throw new AppError("ERR_NO_CONTACTLISTITEM_FOUND", 404); + } + + return record; +}; + +export default ShowService; diff --git a/backend/src/services/ContactListItemService/UpdateService.ts b/backend/src/services/ContactListItemService/UpdateService.ts new file mode 100644 index 0000000..b254eb8 --- /dev/null +++ b/backend/src/services/ContactListItemService/UpdateService.ts @@ -0,0 +1,41 @@ +import AppError from "../../errors/AppError"; +import ContactListItem from "../../models/ContactListItem"; +import { logger } from "../../utils/logger"; +import CheckContactNumber from "../WbotServices/CheckNumber"; + +interface Data { + id: number | string; + name: string; + number: string; + email?: string; +} + +const UpdateService = async (data: Data): Promise => { + const { id, name, number, email } = data; + + const record = await ContactListItem.findByPk(id); + + if (!record) { + throw new AppError("ERR_NO_CONTACTLISTITEM_FOUND", 404); + } + + await record.update({ + name, + number, + email + }); + + try { + const response = await CheckContactNumber(record.number, record.companyId); + record.isWhatsappValid = response.exists; + const number = response.jid.replace(/\D/g, ""); + record.number = number; + await record.save(); + } catch (e) { + logger.error(`Número de contato inválido: ${record.number}`); + } + + return record; +}; + +export default UpdateService; diff --git a/backend/src/services/ContactListService/CreateService.ts b/backend/src/services/ContactListService/CreateService.ts new file mode 100644 index 0000000..fcf7d03 --- /dev/null +++ b/backend/src/services/ContactListService/CreateService.ts @@ -0,0 +1,30 @@ +import * as Yup from "yup"; +import AppError from "../../errors/AppError"; +import ContactList from "../../models/ContactList"; + +interface Data { + name: string; + companyId: number | string; +} + +const CreateService = async (data: Data): Promise => { + const { name, companyId } = data; + + const ticketnoteSchema = Yup.object().shape({ + name: Yup.string() + .min(3, "ERR_CONTACTLIST_INVALID_NAME") + .required("ERR_CONTACTLIST_REQUIRED") + }); + + try { + await ticketnoteSchema.validate({ name }); + } catch (err: any) { + throw new AppError(err.message); + } + + const record = await ContactList.create(data); + + return record; +}; + +export default CreateService; diff --git a/backend/src/services/ContactListService/DeleteService.ts b/backend/src/services/ContactListService/DeleteService.ts new file mode 100644 index 0000000..3550ff3 --- /dev/null +++ b/backend/src/services/ContactListService/DeleteService.ts @@ -0,0 +1,16 @@ +import ContactList from "../../models/ContactList"; +import AppError from "../../errors/AppError"; + +const DeleteService = async (id: string): Promise => { + const record = await ContactList.findOne({ + where: { id } + }); + + if (!record) { + throw new AppError("ERR_NO_CONTACTLIST_FOUND", 404); + } + + await record.destroy(); +}; + +export default DeleteService; diff --git a/backend/src/services/ContactListService/FindAllService.ts b/backend/src/services/ContactListService/FindAllService.ts new file mode 100644 index 0000000..44efebe --- /dev/null +++ b/backend/src/services/ContactListService/FindAllService.ts @@ -0,0 +1,10 @@ +import ContactList from "../../models/ContactList"; + +const FindAllService = async (): Promise => { + const records: ContactList[] = await ContactList.findAll({ + order: [["name", "ASC"]] + }); + return records; +}; + +export default FindAllService; diff --git a/backend/src/services/ContactListService/FindService.ts b/backend/src/services/ContactListService/FindService.ts new file mode 100644 index 0000000..daf7ffd --- /dev/null +++ b/backend/src/services/ContactListService/FindService.ts @@ -0,0 +1,20 @@ +import ContactList from "../../models/ContactList"; +import Company from "../../models/Company"; + +type Params = { + companyId: string; +}; + +const FindService = async ({ companyId }: Params): Promise => { + const notes: ContactList[] = await ContactList.findAll({ + where: { + companyId + }, + include: [{ model: Company, as: "company", attributes: ["id", "name"] }], + order: [["name", "ASC"]] + }); + + return notes; +}; + +export default FindService; diff --git a/backend/src/services/ContactListService/ImportContacts.ts b/backend/src/services/ContactListService/ImportContacts.ts new file mode 100644 index 0000000..a5d2c9b --- /dev/null +++ b/backend/src/services/ContactListService/ImportContacts.ts @@ -0,0 +1,79 @@ +import { head } from "lodash"; +import XLSX from "xlsx"; +import { has } from "lodash"; +import ContactListItem from "../../models/ContactListItem"; +import CheckContactNumber from "../WbotServices/CheckNumber"; +import { logger } from "../../utils/logger"; +// import CheckContactNumber from "../WbotServices/CheckNumber"; + +export async function ImportContacts( + contactListId: number, + companyId: number, + file: Express.Multer.File | undefined +) { + const workbook = XLSX.readFile(file?.path as string); + const worksheet = head(Object.values(workbook.Sheets)) as any; + const rows: any[] = XLSX.utils.sheet_to_json(worksheet, { header: 0 }); + const contacts = rows.map(row => { + let name = ""; + let number = ""; + let email = ""; + + if (has(row, "nome") || has(row, "Nome")) { + name = row["nome"] || row["Nome"]; + } + + if ( + has(row, "numero") || + has(row, "número") || + has(row, "Numero") || + has(row, "Número") + ) { + number = row["numero"] || row["número"] || row["Numero"] || row["Número"]; + number = `${number}`.replace(/\D/g, ""); + } + + if ( + has(row, "email") || + has(row, "e-mail") || + has(row, "Email") || + has(row, "E-mail") + ) { + email = row["email"] || row["e-mail"] || row["Email"] || row["E-mail"]; + } + + return { name, number, email, contactListId, companyId }; + }); + + const contactList: ContactListItem[] = []; + + for (const contact of contacts) { + const [newContact, created] = await ContactListItem.findOrCreate({ + where: { + number: `${contact.number}`, + contactListId: contact.contactListId, + companyId: contact.companyId + }, + defaults: contact + }); + if (created) { + contactList.push(newContact); + } + } + + if (contactList) { + for (let newContact of contactList) { + try { + const response = await CheckContactNumber(newContact.number, companyId); + newContact.isWhatsappValid = response.exists; + const number = response.jid.replace(/\D/g, ""); + newContact.number = number; + await newContact.save(); + } catch (e) { + logger.error(`Número de contato inválido: ${newContact.number}`); + } + } + } + + return contactList; +} diff --git a/backend/src/services/ContactListService/ListService.ts b/backend/src/services/ContactListService/ListService.ts new file mode 100644 index 0000000..f77af09 --- /dev/null +++ b/backend/src/services/ContactListService/ListService.ts @@ -0,0 +1,76 @@ +import { Op, fn, col, where } from "sequelize"; +import ContactList from "../../models/ContactList"; +import ContactListItem from "../../models/ContactListItem"; +import { isEmpty } from "lodash"; + +interface Request { + companyId: number | string; + searchParam?: string; + pageNumber?: string; +} + +interface Response { + records: ContactList[]; + count: number; + hasMore: boolean; +} + +const ListService = async ({ + searchParam = "", + pageNumber = "1", + companyId +}: Request): Promise => { + let whereCondition: any = { + companyId + }; + + if (!isEmpty(searchParam)) { + whereCondition = { + ...whereCondition, + [Op.or]: [ + { + name: where( + fn("LOWER", col("ContactList.name")), + "LIKE", + `%${searchParam.toLowerCase().trim()}%` + ) + } + ] + }; + } + + const limit = 20; + const offset = limit * (+pageNumber - 1); + + const { count, rows: records } = await ContactList.findAndCountAll({ + where: whereCondition, + limit, + offset, + order: [["name", "ASC"]], + subQuery: false, + include: [ + { + model: ContactListItem, + as: "contacts", + attributes: [], + required: false + } + ], + attributes: [ + "id", + "name", + [fn("count", col("contacts.id")), "contactsCount"] + ], + group: ["ContactList.id"] + }); + + const hasMore = count > offset + records.length; + + return { + records, + count, + hasMore + }; +}; + +export default ListService; diff --git a/backend/src/services/ContactListService/ShowService.ts b/backend/src/services/ContactListService/ShowService.ts new file mode 100644 index 0000000..13b11e3 --- /dev/null +++ b/backend/src/services/ContactListService/ShowService.ts @@ -0,0 +1,14 @@ +import ContactList from "../../models/ContactList"; +import AppError from "../../errors/AppError"; + +const ShowService = async (id: string | number): Promise => { + const record = await ContactList.findByPk(id); + + if (!record) { + throw new AppError("ERR_NO_TICKETNOTE_FOUND", 404); + } + + return record; +}; + +export default ShowService; diff --git a/backend/src/services/ContactListService/UpdateService.ts b/backend/src/services/ContactListService/UpdateService.ts new file mode 100644 index 0000000..6c58753 --- /dev/null +++ b/backend/src/services/ContactListService/UpdateService.ts @@ -0,0 +1,25 @@ +import AppError from "../../errors/AppError"; +import ContactList from "../../models/ContactList"; + +interface Data { + id: number | string; + name: string; +} + +const UpdateService = async (data: Data): Promise => { + const { id, name } = data; + + const record = await ContactList.findByPk(id); + + if (!record) { + throw new AppError("ERR_NO_CONTACTLIST_FOUND", 404); + } + + await record.update({ + name + }); + + return record; +}; + +export default UpdateService; diff --git a/backend/src/services/ContactServices/CreateContactService.ts b/backend/src/services/ContactServices/CreateContactService.ts new file mode 100644 index 0000000..fbc4295 --- /dev/null +++ b/backend/src/services/ContactServices/CreateContactService.ts @@ -0,0 +1,50 @@ +import AppError from "../../errors/AppError"; +import Contact from "../../models/Contact"; +import ContactCustomField from "../../models/ContactCustomField"; + +interface ExtraInfo extends ContactCustomField { + name: string; + value: string; +} + +interface Request { + name: string; + number: string; + email?: string; + profilePicUrl?: string; + companyId: number; + extraInfo?: ExtraInfo[]; +} + +const CreateContactService = async ({ + name, + number, + email = "", + companyId, + extraInfo = [] +}: Request): Promise => { + const numberExists = await Contact.findOne({ + where: { number, companyId } + }); + + if (numberExists) { + throw new AppError("ERR_DUPLICATED_CONTACT"); + } + + const contact = await Contact.create( + { + name, + number, + email, + extraInfo, + companyId + }, + { + include: ["extraInfo"] + } + ); + + return contact; +}; + +export default CreateContactService; diff --git a/backend/src/services/ContactServices/CreateOrUpdateContactService.ts b/backend/src/services/ContactServices/CreateOrUpdateContactService.ts new file mode 100644 index 0000000..c25edd0 --- /dev/null +++ b/backend/src/services/ContactServices/CreateOrUpdateContactService.ts @@ -0,0 +1,76 @@ +import { getIO } from "../../libs/socket"; +import Contact from "../../models/Contact"; +import ContactCustomField from "../../models/ContactCustomField"; +import { isNil } from "lodash"; +interface ExtraInfo extends ContactCustomField { + name: string; + value: string; +} + +interface Request { + name: string; + number: string; + isGroup: boolean; + email?: string; + profilePicUrl?: string; + companyId: number; + extraInfo?: ExtraInfo[]; + whatsappId?: number; +} + +const CreateOrUpdateContactService = async ({ + name, + number: rawNumber, + profilePicUrl, + isGroup, + email = "", + companyId, + extraInfo = [], + whatsappId +}: Request): Promise => { + const number = isGroup ? rawNumber : rawNumber.replace(/[^0-9]/g, ""); + + const io = getIO(); + let contact: Contact | null; + + contact = await Contact.findOne({ + where: { + number, + companyId + } + }); + + if (contact) { + contact.update({ profilePicUrl }); + console.log(contact.whatsappId) + if (isNil(contact.whatsappId === null)) { + contact.update({ + whatsappId + }); + } + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-contact`, { + action: "update", + contact + }); + } else { + contact = await Contact.create({ + name, + number, + profilePicUrl, + email, + isGroup, + extraInfo, + companyId, + whatsappId + }); + + io.to(`company-${companyId}-mainchannel`).emit(`company-${companyId}-contact`, { + action: "create", + contact + }); + } + + return contact; +}; + +export default CreateOrUpdateContactService; diff --git a/backend/src/services/ContactServices/DeleteContactService.ts b/backend/src/services/ContactServices/DeleteContactService.ts new file mode 100644 index 0000000..caaf86a --- /dev/null +++ b/backend/src/services/ContactServices/DeleteContactService.ts @@ -0,0 +1,16 @@ +import Contact from "../../models/Contact"; +import AppError from "../../errors/AppError"; + +const DeleteContactService = async (id: string): Promise => { + const contact = await Contact.findOne({ + where: { id } + }); + + if (!contact) { + throw new AppError("ERR_NO_CONTACT_FOUND", 404); + } + + await contact.destroy(); +}; + +export default DeleteContactService; diff --git a/backend/src/services/ContactServices/GetContactService.ts b/backend/src/services/ContactServices/GetContactService.ts new file mode 100644 index 0000000..7466c54 --- /dev/null +++ b/backend/src/services/ContactServices/GetContactService.ts @@ -0,0 +1,43 @@ +import AppError from "../../errors/AppError"; +import Contact from "../../models/Contact"; +import ContactCustomField from "../../models/ContactCustomField"; +import CreateContactService from "./CreateContactService"; + +interface ExtraInfo extends ContactCustomField { + name: string; + value: string; +} + +interface Request { + name: string; + number: string; + companyId: number; + email?: string; + profilePicUrl?: string; + extraInfo?: ExtraInfo[]; +} + +const GetContactService = async ({ + name, + number, + companyId +}: Request): Promise => { + const numberExists = await Contact.findOne({ + where: { number, companyId } + }); + + if (!numberExists) { + const contact = await CreateContactService({ + name, + number, + companyId + }); + + if (contact == null) throw new AppError("CONTACT_NOT_FIND"); + else return contact; + } + + return numberExists; +}; + +export default GetContactService; diff --git a/backend/src/services/ContactServices/ListContactsService.ts b/backend/src/services/ContactServices/ListContactsService.ts new file mode 100644 index 0000000..0443c7b --- /dev/null +++ b/backend/src/services/ContactServices/ListContactsService.ts @@ -0,0 +1,55 @@ +import { Sequelize, Op } from "sequelize"; +import Contact from "../../models/Contact"; + +interface Request { + searchParam?: string; + pageNumber?: string; + companyId: number; +} + +interface Response { + contacts: Contact[]; + count: number; + hasMore: boolean; +} + +const ListContactsService = async ({ + searchParam = "", + pageNumber = "1", + companyId +}: Request): Promise => { + const whereCondition = { + [Op.or]: [ + { + name: Sequelize.where( + Sequelize.fn("LOWER", Sequelize.col("name")), + "LIKE", + `%${searchParam.toLowerCase().trim()}%` + ) + }, + { number: { [Op.like]: `%${searchParam.toLowerCase().trim()}%` } } + ], + companyId: { + [Op.eq]: companyId + } + }; + const limit = 30; + const offset = limit * (+pageNumber - 1); + + const { count, rows: contacts } = await Contact.findAndCountAll({ + where: whereCondition, + limit, + offset, + order: [["name", "ASC"]] + }); + + const hasMore = count > offset + contacts.length; + + return { + contacts, + count, + hasMore + }; +}; + +export default ListContactsService; diff --git a/backend/src/services/ContactServices/ShowContactService.ts b/backend/src/services/ContactServices/ShowContactService.ts new file mode 100644 index 0000000..4c23ef4 --- /dev/null +++ b/backend/src/services/ContactServices/ShowContactService.ts @@ -0,0 +1,21 @@ +import Contact from "../../models/Contact"; +import AppError from "../../errors/AppError"; + +const ShowContactService = async ( + id: string | number, + companyId: number +): Promise => { + const contact = await Contact.findByPk(id, { include: ["extraInfo", "whatsapp"] }); + + if (contact?.companyId !== companyId) { + throw new AppError("Não é possível excluir registro de outra empresa"); + } + + if (!contact) { + throw new AppError("ERR_NO_CONTACT_FOUND", 404); + } + + return contact; +}; + +export default ShowContactService; diff --git a/backend/src/services/ContactServices/SimpleListService.ts b/backend/src/services/ContactServices/SimpleListService.ts new file mode 100644 index 0000000..12608ed --- /dev/null +++ b/backend/src/services/ContactServices/SimpleListService.ts @@ -0,0 +1,39 @@ +import Contact from "../../models/Contact"; +import AppError from "../../errors/AppError"; +import { FindOptions, Op } from "sequelize"; + +export interface SearchContactParams { + companyId: string | number; + name?: string; +} + +const SimpleListService = async ({ name, companyId }: SearchContactParams): Promise => { + let options: FindOptions = { + order: [ + ['name', 'ASC'] + ] + } + + if (name) { + options.where = { + name: { + [Op.like]: `%${name}%` + } + } + } + + options.where = { + ...options.where, + companyId + } + + const contacts = await Contact.findAll(options); + + if (!contacts) { + throw new AppError("ERR_NO_CONTACT_FOUND", 404); + } + + return contacts; +}; + +export default SimpleListService; diff --git a/backend/src/services/ContactServices/UpdateContactService.ts b/backend/src/services/ContactServices/UpdateContactService.ts new file mode 100644 index 0000000..638c195 --- /dev/null +++ b/backend/src/services/ContactServices/UpdateContactService.ts @@ -0,0 +1,76 @@ +import AppError from "../../errors/AppError"; +import Contact from "../../models/Contact"; +import ContactCustomField from "../../models/ContactCustomField"; + +interface ExtraInfo { + id?: number; + name: string; + value: string; +} +interface ContactData { + email?: string; + number?: string; + name?: string; + extraInfo?: ExtraInfo[]; +} + +interface Request { + contactData: ContactData; + contactId: string; + companyId: number; +} + +const UpdateContactService = async ({ + contactData, + contactId, + companyId +}: Request): Promise => { + const { email, name, number, extraInfo } = contactData; + + const contact = await Contact.findOne({ + where: { id: contactId }, + attributes: ["id", "name", "number", "email", "companyId", "profilePicUrl"], + include: ["extraInfo"] + }); + + if (contact?.companyId !== companyId) { + throw new AppError("Não é possível alterar registros de outra empresa"); + } + + if (!contact) { + throw new AppError("ERR_NO_CONTACT_FOUND", 404); + } + + if (extraInfo) { + await Promise.all( + extraInfo.map(async (info: any) => { + await ContactCustomField.upsert({ ...info, contactId: contact.id }); + }) + ); + + await Promise.all( + contact.extraInfo.map(async oldInfo => { + const stillExists = extraInfo.findIndex(info => info.id === oldInfo.id); + + if (stillExists === -1) { + await ContactCustomField.destroy({ where: { id: oldInfo.id } }); + } + }) + ); + } + + await contact.update({ + name, + number, + email + }); + + await contact.reload({ + attributes: ["id", "name", "number", "email", "profilePicUrl"], + include: ["extraInfo"] + }); + + return contact; +}; + +export default UpdateContactService; diff --git a/backend/src/services/FileServices/CreateService.ts b/backend/src/services/FileServices/CreateService.ts new file mode 100644 index 0000000..2e7356e --- /dev/null +++ b/backend/src/services/FileServices/CreateService.ts @@ -0,0 +1,68 @@ +import * as Yup from "yup"; + +import AppError from "../../errors/AppError"; +import Files from "../../models/Files"; +import FilesOptions from "../../models/FilesOptions"; +import ShowService from "./ShowService"; + +interface Request { + name: string; + companyId: number; + message: string; + options?: FilesOptions[]; +} + +const CreateService = async ({ + name, + message, + companyId, + options +}: Request): Promise => { + const schema = Yup.object().shape({ + name: Yup.string() + .required() + .min(3) + .test( + "Check-unique-name", + "ERR_RATING_NAME_ALREADY_EXISTS", + async value => { + if (value) { + const tagWithSameName = await Files.findOne({ + where: { name: value, companyId } + }); + + return !tagWithSameName; + } + return false; + } + ) + }); + + try { + await schema.validate({ name }); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } catch (err: any) { + throw new AppError(err.message); + } + let fileList = await Files.create({ + name, + message, + companyId + }); + + if(options && options.length > 0) { + await Promise.all( + options.map(async info => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + await FilesOptions.upsert({ ...info, fileId: fileList.id }); + }) + ); + } + + fileList = await ShowService(fileList.id, companyId) + + return fileList; +}; + +export default CreateService; \ No newline at end of file diff --git a/backend/src/services/FileServices/DeleteAllService.ts b/backend/src/services/FileServices/DeleteAllService.ts new file mode 100644 index 0000000..46736b4 --- /dev/null +++ b/backend/src/services/FileServices/DeleteAllService.ts @@ -0,0 +1,16 @@ +import Files from "../../models/Files"; +import AppError from "../../errors/AppError"; + +const DeleteAllService = async (companyId: number): Promise => { + await Files.findAll({ + where: { companyId } + }); + + if (!Files) { + throw new AppError("ERR_NO_RATING_FOUND", 404); + } + + await Files.destroy({ where: {} }); +}; + +export default DeleteAllService; diff --git a/backend/src/services/FileServices/DeleteService.ts b/backend/src/services/FileServices/DeleteService.ts new file mode 100644 index 0000000..55078f3 --- /dev/null +++ b/backend/src/services/FileServices/DeleteService.ts @@ -0,0 +1,16 @@ +import Files from "../../models/Files"; +import AppError from "../../errors/AppError"; + +const DeleteService = async (id: string | number, companyId: number): Promise => { + const file = await Files.findOne({ + where: { id, companyId } + }); + + if (!file) { + throw new AppError("ERR_NO_RATING_FOUND", 404); + } + + await file.destroy(); +}; + +export default DeleteService; diff --git a/backend/src/services/FileServices/ListService.ts b/backend/src/services/FileServices/ListService.ts new file mode 100644 index 0000000..062e49b --- /dev/null +++ b/backend/src/services/FileServices/ListService.ts @@ -0,0 +1,46 @@ +import { Op } from "sequelize"; +import Files from "../../models/Files"; + +interface Request { + companyId: number; + searchParam?: string; + pageNumber?: string | number; +} + +interface Response { + files: Files[]; + count: number; + hasMore: boolean; +} + +const ListService = async ({ + searchParam, + pageNumber = "1", + companyId +}: Request): Promise => { + let whereCondition = {}; + const limit = 20; + const offset = limit * (+pageNumber - 1); + + if (searchParam) { + whereCondition = { + [Op.or]: [{ name: { [Op.like]: `%${searchParam}%` } }] + }; + } + const { count, rows: files } = await Files.findAndCountAll({ + where: {companyId, ...whereCondition}, + limit, + offset, + order: [["name", "ASC"]] + }); + + const hasMore = count > offset + files.length; + + return { + files, + count, + hasMore + }; +}; + +export default ListService; diff --git a/backend/src/services/FileServices/ShowService.ts b/backend/src/services/FileServices/ShowService.ts new file mode 100644 index 0000000..6684c0b --- /dev/null +++ b/backend/src/services/FileServices/ShowService.ts @@ -0,0 +1,25 @@ +import Files from "../../models/Files"; +import AppError from "../../errors/AppError"; +import FilesOptions from "../../models/FilesOptions"; + +const ShowFileService = async (id: string | number, companyId: number): Promise => { + const fileList = await Files.findOne({ + where: { id, companyId }, + include: [ + "options", + { + model: FilesOptions, + as: "options", + order: [["id","ASC"]] + } + ] + }); + + if (!fileList) { + throw new AppError("ERR_NO_FILE_FOUND", 404); + } + + return fileList; +}; + +export default ShowFileService; diff --git a/backend/src/services/FileServices/SimpleListService.ts b/backend/src/services/FileServices/SimpleListService.ts new file mode 100644 index 0000000..fb027f7 --- /dev/null +++ b/backend/src/services/FileServices/SimpleListService.ts @@ -0,0 +1,30 @@ +import { Op } from "sequelize"; +import Rating from "../../models/Files"; + +interface Request { + companyId: number + searchParam?: string; +} + +const ListService = async ({ searchParam, companyId }: Request): Promise => { + let whereCondition = {}; + + if (searchParam) { + whereCondition = { + [Op.or]: [{ name: { [Op.like]: `%${searchParam}%` } }] + }; + } + + const ratings = await Rating.findAll({ + where: {companyId, ...whereCondition}, + order: [["name", "ASC"]], + attributes: { + exclude: ["createdAt", "updatedAt"] + }, + group: ["Rating.id"] + }); + + return ratings; +}; + +export default ListService; diff --git a/backend/src/services/FileServices/UpdateService.ts b/backend/src/services/FileServices/UpdateService.ts new file mode 100644 index 0000000..7946cd7 --- /dev/null +++ b/backend/src/services/FileServices/UpdateService.ts @@ -0,0 +1,82 @@ +import * as Yup from "yup"; + +import AppError from "../../errors/AppError"; +import Files from "../../models/Files"; +import FilesOptions from "../../models/FilesOptions"; +import ShowService from "./ShowService"; + +interface Options { + id?: number; + name: string; + path: string; +} + +interface FileData { + id?: number; + name: string; + message: string; + options?: Options[]; +} + +interface Request { + fileData: FileData; + id: string | number; + companyId: number; +} + +const UpdateService = async ({ + fileData, + id, + companyId +}: Request): Promise => { + const file = await ShowService(id, companyId); + + const schema = Yup.object().shape({ + name: Yup.string().min(3) + }); + + const { name, message, options } = fileData; + + try { + await schema.validate({ name }); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } catch (err: any) { + throw new AppError(err.message); + } + + if (options) { + await Promise.all( + options.map(async info => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + await FilesOptions.upsert({ ...info, fileId: file.id }); + }) + ); + + await Promise.all( + file.options.map(async oldInfo => { + const stillExists = options.findIndex(info => info.id === oldInfo.id); + + if (stillExists === -1) { + await FilesOptions.destroy({ where: { id: oldInfo.id } }); + } + }) + ); + } + + + + + await file.update({ + name, + message + }); + + await file.reload({ + attributes: ["id", "name", "message","companyId"], + include: ["options"] + }); + return file; +}; + +export default UpdateService; diff --git a/backend/src/services/ForgotPassWordServices/SendMail.ts b/backend/src/services/ForgotPassWordServices/SendMail.ts new file mode 100644 index 0000000..cef87d0 --- /dev/null +++ b/backend/src/services/ForgotPassWordServices/SendMail.ts @@ -0,0 +1,248 @@ +import nodemailer from "nodemailer"; +import sequelize from "sequelize"; +import database from "../../database"; +import Setting from "../../models/Setting"; +import { config } from "dotenv"; +config(); +interface UserData { + companyId: number; +} +const SendMail = async (email: string, tokenSenha: string) => { + const { hasResult, data } = await filterEmail(email); + if (!hasResult) { + return { status: 404, message: "Email não encontrado" }; + } + const userData = data[0][0] as UserData; + if (!userData || userData.companyId === undefined) { + return { status: 404, message: "Dados do usuário não encontrados" }; + } + const companyId = userData.companyId; + const urlSmtp = process.env.MAIL_HOST; + const userSmtp = process.env.MAIL_USER; + const passwordSmpt = process.env.MAIL_PASS; + const fromEmail = process.env.MAIL_FROM; + const transporter = nodemailer.createTransport({ + host: urlSmtp, + port: Number(process.env.MAIL_PORT), + secure: true, + auth: { user: userSmtp, pass: passwordSmpt } + }); + if (hasResult === true) { + const { hasResults, datas } = await insertToken(email, tokenSenha); + async function sendEmail() { + try { + const mailOptions = { + from: fromEmail, + to: email, + subject: "Redefinição de Senha - S-WhiteLabel", + html: ` + + + + + + + + Novo modelo + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + + + +
+ + + + +
+ + + + + + + +

Bem-vindo à Scripts WhiteLabel

Você solicitou recuperação de senha do Whaticket!

+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + + + + + + +

Código de Verificação:

${tokenSenha}

+ + + + +
+ + + + +
+ + + + +
+ + + + + + + +

Está com dúvidas?

Entre em contato agora mesmo conosco.

+
+ +` + }; + const info = await transporter.sendMail(mailOptions); + console.log("E-mail enviado: " + info.response); + } catch (error) { + console.log(error); + } + } + sendEmail(); + } +}; +const filterEmail = async (email: string) => { + const sql = `SELECT * FROM "Users" WHERE email ='${email}'`; + const result = await database.query(sql, { + type: sequelize.QueryTypes.SELECT + }); + return { hasResult: result.length > 0, data: [result] }; +}; +const insertToken = async (email: string, tokenSenha: string) => { + const sqls = `UPDATE "Users" SET "resetPassword"= '${tokenSenha}' WHERE email ='${email}'`; + const results = await database.query(sqls, { + type: sequelize.QueryTypes.UPDATE + }); + return { hasResults: results.length > 0, datas: results }; +}; +export default SendMail; diff --git a/backend/src/services/HelpServices/CreateService.ts b/backend/src/services/HelpServices/CreateService.ts new file mode 100644 index 0000000..a444df4 --- /dev/null +++ b/backend/src/services/HelpServices/CreateService.ts @@ -0,0 +1,33 @@ +import * as Yup from "yup"; +import AppError from "../../errors/AppError"; +import Help from "../../models/Help"; + +interface Data { + title: string; + description?: string; + video?: string; + link?: string; +} + +const CreateService = async (data: Data): Promise => { + const { title, description } = data; + + const helpSchema = Yup.object().shape({ + title: Yup.string() + .min(3, "ERR_HELP_INVALID_NAME") + .required("ERR_HELP_REQUIRED"), + description: Yup.string().min(3, "ERR_HELP_INVALID_NAME") + }); + + try { + await helpSchema.validate({ title, description }); + } catch (err) { + throw new AppError(err.message); + } + + const record = await Help.create(data); + + return record; +}; + +export default CreateService; diff --git a/backend/src/services/HelpServices/DeleteService.ts b/backend/src/services/HelpServices/DeleteService.ts new file mode 100644 index 0000000..e922ea5 --- /dev/null +++ b/backend/src/services/HelpServices/DeleteService.ts @@ -0,0 +1,16 @@ +import Help from "../../models/Help"; +import AppError from "../../errors/AppError"; + +const DeleteService = async (id: string): Promise => { + const record = await Help.findOne({ + where: { id } + }); + + if (!record) { + throw new AppError("ERR_NO_HELP_FOUND", 404); + } + + await record.destroy(); +}; + +export default DeleteService; diff --git a/backend/src/services/HelpServices/FindAllService.ts b/backend/src/services/HelpServices/FindAllService.ts new file mode 100644 index 0000000..ea6262d --- /dev/null +++ b/backend/src/services/HelpServices/FindAllService.ts @@ -0,0 +1,10 @@ +import Help from "../../models/Help"; + +const FindAllService = async (): Promise => { + const records: Help[] = await Help.findAll({ + order: [["title", "ASC"]] + }); + return records; +}; + +export default FindAllService; diff --git a/backend/src/services/HelpServices/FindService.ts b/backend/src/services/HelpServices/FindService.ts new file mode 100644 index 0000000..b3d3401 --- /dev/null +++ b/backend/src/services/HelpServices/FindService.ts @@ -0,0 +1,11 @@ +import Help from "../../models/Help"; + +const FindService = async (): Promise => { + const notes: Help[] = await Help.findAll({ + order: [["title", "ASC"]] + }); + + return notes; +}; + +export default FindService; diff --git a/backend/src/services/HelpServices/ListService.ts b/backend/src/services/HelpServices/ListService.ts new file mode 100644 index 0000000..5ab1dd5 --- /dev/null +++ b/backend/src/services/HelpServices/ListService.ts @@ -0,0 +1,49 @@ +import { Sequelize, Op } from "sequelize"; +import Help from "../../models/Help"; + +interface Request { + searchParam?: string; + pageNumber?: string; +} + +interface Response { + records: Help[]; + count: number; + hasMore: boolean; +} + +const ListService = async ({ + searchParam = "", + pageNumber = "1" +}: Request): Promise => { + const whereCondition = { + [Op.or]: [ + { + title: Sequelize.where( + Sequelize.fn("LOWER", Sequelize.col("title")), + "LIKE", + `%${searchParam.toLowerCase().trim()}%` + ) + } + ] + }; + const limit = 20; + const offset = limit * (+pageNumber - 1); + + const { count, rows: records } = await Help.findAndCountAll({ + where: whereCondition, + limit, + offset, + order: [["title", "ASC"]] + }); + + const hasMore = count > offset + records.length; + + return { + records, + count, + hasMore + }; +}; + +export default ListService; diff --git a/backend/src/services/HelpServices/ShowService.ts b/backend/src/services/HelpServices/ShowService.ts new file mode 100644 index 0000000..8e38638 --- /dev/null +++ b/backend/src/services/HelpServices/ShowService.ts @@ -0,0 +1,14 @@ +import Help from "../../models/Help"; +import AppError from "../../errors/AppError"; + +const ShowService = async (id: string | number): Promise => { + const record = await Help.findByPk(id); + + if (!record) { + throw new AppError("ERR_NO_HELP_FOUND", 404); + } + + return record; +}; + +export default ShowService; diff --git a/backend/src/services/HelpServices/UpdateService.ts b/backend/src/services/HelpServices/UpdateService.ts new file mode 100644 index 0000000..d4bc4b2 --- /dev/null +++ b/backend/src/services/HelpServices/UpdateService.ts @@ -0,0 +1,26 @@ +import AppError from "../../errors/AppError"; +import Help from "../../models/Help"; + +interface Data { + id: number | string; + title: string; + description?: string; + video?: string; + link?: string; +} + +const UpdateService = async (data: Data): Promise => { + const { id } = data; + + const record = await Help.findByPk(id); + + if (!record) { + throw new AppError("ERR_NO_HELP_FOUND", 404); + } + + await record.update(data); + + return record; +}; + +export default UpdateService; diff --git a/backend/src/services/InvoicesService/FindAllInvoiceService.ts b/backend/src/services/InvoicesService/FindAllInvoiceService.ts new file mode 100644 index 0000000..47d73cb --- /dev/null +++ b/backend/src/services/InvoicesService/FindAllInvoiceService.ts @@ -0,0 +1,17 @@ +import Invoices from "../../models/Invoices"; + +interface Request { + companyId: number; +} + +const FindAllPlanService = async (companyId: number): Promise => { + const invoice = await Invoices.findAll({ + where: { + companyId + }, + order: [["id", "ASC"]] + }); + return invoice; +}; + +export default FindAllPlanService; diff --git a/backend/src/services/InvoicesService/ListInvoicesServices.ts b/backend/src/services/InvoicesService/ListInvoicesServices.ts new file mode 100644 index 0000000..5b9faff --- /dev/null +++ b/backend/src/services/InvoicesService/ListInvoicesServices.ts @@ -0,0 +1,49 @@ +import { Sequelize, Op } from "sequelize"; +import Invoices from "../../models/Invoices"; + +interface Request { + searchParam?: string; + pageNumber?: string; +} + +interface Response { + invoices: Invoices[]; + count: number; + hasMore: boolean; +} + +const ListInvoicesServices = async ({ + searchParam = "", + pageNumber = "1" +}: Request): Promise => { + const whereCondition = { + [Op.or]: [ + { + name: Sequelize.where( + Sequelize.fn("LOWER", Sequelize.col("detail")), + "LIKE", + `%${searchParam.toLowerCase().trim()}%` + ) + } + ] + }; + const limit = 20; + const offset = limit * (+pageNumber - 1); + + const { count, rows: invoices } = await Invoices.findAndCountAll({ + where: whereCondition, + limit, + offset, + order: [["id", "ASC"]] + }); + + const hasMore = count > offset + invoices.length; + + return { + invoices, + count, + hasMore + }; +}; + +export default ListInvoicesServices; diff --git a/backend/src/services/InvoicesService/ShowInvoiceService.ts b/backend/src/services/InvoicesService/ShowInvoiceService.ts new file mode 100644 index 0000000..a0409c7 --- /dev/null +++ b/backend/src/services/InvoicesService/ShowInvoiceService.ts @@ -0,0 +1,14 @@ +import Invoice from "../../models/Invoices"; +import AppError from "../../errors/AppError"; + +const ShowInvoceService = async (Invoiceid: string | number): Promise => { + const invoice = await Invoice.findByPk(Invoiceid); + + if (!invoice) { + throw new AppError("ERR_NO_PLAN_FOUND", 404); + } + + return invoice; +}; + +export default ShowInvoceService; diff --git a/backend/src/services/InvoicesService/UpdateInvoiceService.ts b/backend/src/services/InvoicesService/UpdateInvoiceService.ts new file mode 100644 index 0000000..6ac45e8 --- /dev/null +++ b/backend/src/services/InvoicesService/UpdateInvoiceService.ts @@ -0,0 +1,25 @@ +import AppError from "../../errors/AppError"; +import Invoice from "../../models/Invoices"; + +interface InvoiceData { + status: string; + id?: number | string; +} + +const UpdateInvoiceService = async (InvoiceData: InvoiceData): Promise => { + const { id, status } = InvoiceData; + + const invoice = await Invoice.findByPk(id); + + if (!invoice) { + throw new AppError("ERR_NO_PLAN_FOUND", 404); + } + + await invoice.update({ + status, + }); + + return invoice; +}; + +export default UpdateInvoiceService; diff --git a/backend/src/services/MessageServices/CreateMessageService.ts b/backend/src/services/MessageServices/CreateMessageService.ts new file mode 100644 index 0000000..43236fc --- /dev/null +++ b/backend/src/services/MessageServices/CreateMessageService.ts @@ -0,0 +1,77 @@ +import { getIO } from "../../libs/socket"; +import Message from "../../models/Message"; +import Ticket from "../../models/Ticket"; +import Whatsapp from "../../models/Whatsapp"; + +interface MessageData { + id: string; + ticketId: number; + body: string; + contactId?: number; + fromMe?: boolean; + read?: boolean; + mediaType?: string; + mediaUrl?: string; + ack?: number; + queueId?: number; +} +interface Request { + messageData: MessageData; + companyId: number; +} + +const CreateMessageService = async ({ + messageData, + companyId +}: Request): Promise => { + await Message.upsert({ ...messageData, companyId }); + + const message = await Message.findByPk(messageData.id, { + include: [ + "contact", + { + model: Ticket, + as: "ticket", + include: [ + "contact", + "queue", + { + model: Whatsapp, + as: "whatsapp", + attributes: ["name"] + } + ] + }, + { + model: Message, + as: "quotedMsg", + include: ["contact"] + } + ] + }); + + if (message.ticket.queueId !== null && message.queueId === null) { + await message.update({ queueId: message.ticket.queueId }); + } + + if (!message) { + throw new Error("ERR_CREATING_MESSAGE"); + } + + const io = getIO(); + io.to(message.ticketId.toString()) + .to(`company-${companyId}-${message.ticket.status}`) + .to(`company-${companyId}-notification`) + .to(`queue-${message.ticket.queueId}-${message.ticket.status}`) + .to(`queue-${message.ticket.queueId}-notification`) + .emit(`company-${companyId}-appMessage`, { + action: "create", + message, + ticket: message.ticket, + contact: message.ticket.contact + }); + + return message; +}; + +export default CreateMessageService; diff --git a/backend/src/services/MessageServices/GetMessagesService.ts b/backend/src/services/MessageServices/GetMessagesService.ts new file mode 100644 index 0000000..b33c014 --- /dev/null +++ b/backend/src/services/MessageServices/GetMessagesService.ts @@ -0,0 +1,20 @@ +import AppError from "../../errors/AppError"; +import Message from "../../models/Message"; + +interface Request { + id: string; +} + +const GetMessageService = async ({ id }: Request): Promise => { + const messageExists = await Message.findOne({ + where: { id } + }); + + if (!messageExists) { + throw new AppError("MESSAGE_NOT_FIND"); + } + + return messageExists; +}; + +export default GetMessageService; diff --git a/backend/src/services/MessageServices/ListMessagesService.ts b/backend/src/services/MessageServices/ListMessagesService.ts new file mode 100644 index 0000000..8cec516 --- /dev/null +++ b/backend/src/services/MessageServices/ListMessagesService.ts @@ -0,0 +1,84 @@ +import { FindOptions } from "sequelize/types"; +import { Op } from "sequelize"; +import AppError from "../../errors/AppError"; +import Message from "../../models/Message"; +import Ticket from "../../models/Ticket"; +import ShowTicketService from "../TicketServices/ShowTicketService"; +import Queue from "../../models/Queue"; + +interface Request { + ticketId: string; + companyId: number; + pageNumber?: string; + queues?: number[]; +} + +interface Response { + messages: Message[]; + ticket: Ticket; + count: number; + hasMore: boolean; +} + +const ListMessagesService = async ({ + pageNumber = "1", + ticketId, + companyId, + queues = [] +}: Request): Promise => { + const ticket = await ShowTicketService(ticketId, companyId); + + if (!ticket) { + throw new AppError("ERR_NO_TICKET_FOUND", 404); + } + + // await setMessagesAsRead(ticket); + const limit = 20; + const offset = limit * (+pageNumber - 1); + + const options: FindOptions = { + where: { + ticketId, + companyId + } + }; + + if (queues.length > 0) { + options.where["queueId"] = { + [Op.or]: { + [Op.in]: queues, + [Op.eq]: null + } + }; + } + + const { count, rows: messages } = await Message.findAndCountAll({ + ...options, + limit, + include: [ + "contact", + { + model: Message, + as: "quotedMsg", + include: ["contact"] + }, + { + model: Queue, + as: "queue" + } + ], + offset, + order: [["createdAt", "DESC"]] + }); + + const hasMore = count > offset + messages.length; + + return { + messages: messages.reverse(), + ticket, + count, + hasMore + }; +}; + +export default ListMessagesService; diff --git a/backend/src/services/PlanService/CreatePlanService.ts b/backend/src/services/PlanService/CreatePlanService.ts new file mode 100644 index 0000000..704b339 --- /dev/null +++ b/backend/src/services/PlanService/CreatePlanService.ts @@ -0,0 +1,54 @@ +import * as Yup from "yup"; +import AppError from "../../errors/AppError"; +import Plan from "../../models/Plan"; + +interface PlanData { + name: string; + users: number; + connections: number; + queues: number; + value: number; + useCampaigns?: boolean; + useSchedules?: boolean; + useInternalChat?: boolean; + useExternalApi?: boolean; + useKanban?: boolean; + useOpenAi?: boolean; + useIntegrations?: boolean; +} + +const CreatePlanService = async (planData: PlanData): Promise => { + const { name } = planData; + + const planSchema = Yup.object().shape({ + name: Yup.string() + .min(2, "ERR_PLAN_INVALID_NAME") + .required("ERR_PLAN_INVALID_NAME") + .test( + "Check-unique-name", + "ERR_PLAN_NAME_ALREADY_EXISTS", + async value => { + if (value) { + const planWithSameName = await Plan.findOne({ + where: { name: value } + }); + + return !planWithSameName; + } + return false; + } + ) + }); + + try { + await planSchema.validate({ name }); + } catch (err) { + throw new AppError(err.message); + } + + const plan = await Plan.create(planData); + + return plan; +}; + +export default CreatePlanService; diff --git a/backend/src/services/PlanService/DeletePlanService.ts b/backend/src/services/PlanService/DeletePlanService.ts new file mode 100644 index 0000000..47764b9 --- /dev/null +++ b/backend/src/services/PlanService/DeletePlanService.ts @@ -0,0 +1,16 @@ +import Plan from "../../models/Plan"; +import AppError from "../../errors/AppError"; + +const DeletePlanService = async (id: string): Promise => { + const plan = await Plan.findOne({ + where: { id } + }); + + if (!plan) { + throw new AppError("ERR_NO_PLAN_FOUND", 404); + } + + await plan.destroy(); +}; + +export default DeletePlanService; diff --git a/backend/src/services/PlanService/FindAllPlanService.ts b/backend/src/services/PlanService/FindAllPlanService.ts new file mode 100644 index 0000000..1aa20e4 --- /dev/null +++ b/backend/src/services/PlanService/FindAllPlanService.ts @@ -0,0 +1,10 @@ +import Plan from "../../models/Plan"; + +const FindAllPlanService = async (): Promise => { + const plan = await Plan.findAll({ + order: [["name", "ASC"]] + }); + return plan; +}; + +export default FindAllPlanService; diff --git a/backend/src/services/PlanService/ListPlansService.ts b/backend/src/services/PlanService/ListPlansService.ts new file mode 100644 index 0000000..e244c91 --- /dev/null +++ b/backend/src/services/PlanService/ListPlansService.ts @@ -0,0 +1,49 @@ +import { Sequelize, Op } from "sequelize"; +import Plan from "../../models/Plan"; + +interface Request { + searchParam?: string; + pageNumber?: string; +} + +interface Response { + plans: Plan[]; + count: number; + hasMore: boolean; +} + +const ListPlansService = async ({ + searchParam = "", + pageNumber = "1" +}: Request): Promise => { + const whereCondition = { + [Op.or]: [ + { + name: Sequelize.where( + Sequelize.fn("LOWER", Sequelize.col("name")), + "LIKE", + `%${searchParam.toLowerCase().trim()}%` + ) + } + ] + }; + const limit = 20; + const offset = limit * (+pageNumber - 1); + + const { count, rows: plans } = await Plan.findAndCountAll({ + where: whereCondition, + limit, + offset, + order: [["name", "ASC"]] + }); + + const hasMore = count > offset + plans.length; + + return { + plans, + count, + hasMore + }; +}; + +export default ListPlansService; diff --git a/backend/src/services/PlanService/ShowPlanService.ts b/backend/src/services/PlanService/ShowPlanService.ts new file mode 100644 index 0000000..96f9388 --- /dev/null +++ b/backend/src/services/PlanService/ShowPlanService.ts @@ -0,0 +1,14 @@ +import Plan from "../../models/Plan"; +import AppError from "../../errors/AppError"; + +const ShowPlanService = async (id: string | number): Promise => { + const plan = await Plan.findByPk(id); + + if (!plan) { + throw new AppError("ERR_NO_PLAN_FOUND", 404); + } + + return plan; +}; + +export default ShowPlanService; diff --git a/backend/src/services/PlanService/UpdatePlanService.ts b/backend/src/services/PlanService/UpdatePlanService.ts new file mode 100644 index 0000000..7cfeb35 --- /dev/null +++ b/backend/src/services/PlanService/UpdatePlanService.ts @@ -0,0 +1,34 @@ +import AppError from "../../errors/AppError"; +import Plan from "../../models/Plan"; + +interface PlanData { + name: string; + id?: number | string; + users?: number; + connections?: number; + queues?: number; + value?: number; + useCampaigns?: boolean; + useSchedules?: boolean; + useInternalChat?: boolean; + useExternalApi?: boolean; + useKanban?: boolean; + useOpenAi?: boolean; + useIntegrations?: boolean; +} + +const UpdatePlanService = async (planData: PlanData): Promise => { + const { id, name, users, connections, queues, value } = planData; + + const plan = await Plan.findByPk(id); + + if (!plan) { + throw new AppError("ERR_NO_PLAN_FOUND", 404); + } + + await plan.update(planData); + + return plan; +}; + +export default UpdatePlanService; diff --git a/backend/src/services/PromptServices/CreatePromptService.ts b/backend/src/services/PromptServices/CreatePromptService.ts new file mode 100644 index 0000000..ccf8029 --- /dev/null +++ b/backend/src/services/PromptServices/CreatePromptService.ts @@ -0,0 +1,47 @@ +import * as Yup from "yup"; +import AppError from "../../errors/AppError"; +import Prompt from "../../models/Prompt"; +import ShowPromptService from "./ShowPromptService"; + +interface PromptData { + name: string; + apiKey: string; + prompt: string; + maxTokens?: number; + temperature?: number; + promptTokens?: number; + completionTokens?: number; + totalTokens?: number; + queueId?: number; + maxMessages?: number; + companyId: string | number; + voice?: string; + voiceKey?: string; + voiceRegion?: string; +} + +const CreatePromptService = async (promptData: PromptData): Promise => { + const { name, apiKey, prompt, queueId,maxMessages,companyId } = promptData; + + const promptSchema = Yup.object().shape({ + name: Yup.string().required("ERR_PROMPT_NAME_INVALID"), + prompt: Yup.string().required("ERR_PROMPT_INTELLIGENCE_INVALID"), + apiKey: Yup.string().required("ERR_PROMPT_APIKEY_INVALID"), + queueId: Yup.number().required("ERR_PROMPT_QUEUEID_INVALID"), + maxMessages: Yup.number().required("ERR_PROMPT_MAX_MESSAGES_INVALID"), + companyId: Yup.number().required("ERR_PROMPT_companyId_INVALID") + }); + + try { + await promptSchema.validate({ name, apiKey, prompt, queueId,maxMessages,companyId }); + } catch (err) { + throw new AppError(`${JSON.stringify(err, undefined, 2)}`); + } + + let promptTable = await Prompt.create(promptData); + promptTable = await ShowPromptService({ promptId: promptTable.id, companyId }); + + return promptTable; +}; + +export default CreatePromptService; diff --git a/backend/src/services/PromptServices/DeletePromptService.ts b/backend/src/services/PromptServices/DeletePromptService.ts new file mode 100644 index 0000000..9fc04d6 --- /dev/null +++ b/backend/src/services/PromptServices/DeletePromptService.ts @@ -0,0 +1,9 @@ +import ShowPromptService from "./ShowPromptService"; + +const DeletePromptService = async (promptId: number | string, companyId: number | string): Promise => { + const prompt = await ShowPromptService({ promptId, companyId }); + + await prompt.destroy(); +}; + +export default DeletePromptService; diff --git a/backend/src/services/PromptServices/ListPromptsService.ts b/backend/src/services/PromptServices/ListPromptsService.ts new file mode 100644 index 0000000..8b0540c --- /dev/null +++ b/backend/src/services/PromptServices/ListPromptsService.ts @@ -0,0 +1,56 @@ +import { Op } from "sequelize"; +import Prompt from "../../models/Prompt"; +import Queue from "../../models/Queue"; + +interface Request { + searchParam?: string; + pageNumber?: string | number; + companyId: string | number; +} + +interface Response { + prompts: Prompt[]; + count: number; + hasMore: boolean; +} + +const ListPromptsService = async ({ + searchParam = "", + pageNumber = "1", + companyId +}: Request): Promise => { + let whereCondition = {}; + const limit = 20; + const offset = limit * (+pageNumber - 1); + + if (searchParam) { + whereCondition = { + [Op.or]: [ + { name: { [Op.like]: `%${searchParam}%` } } + ] + } + } + + const { count, rows: prompts } = await Prompt.findAndCountAll({ + where: { ...whereCondition, companyId }, + include: [ + { + model: Queue, + as: "queue", + attributes: ["id", "name"] + } + ], + limit, + offset, + order: [["name", "ASC"]], + }); + const hasMore = count > offset + prompts.length; + + return { + prompts, + count, + hasMore + }; +}; + +export default ListPromptsService; diff --git a/backend/src/services/PromptServices/ShowPromptService.ts b/backend/src/services/PromptServices/ShowPromptService.ts new file mode 100644 index 0000000..13424d1 --- /dev/null +++ b/backend/src/services/PromptServices/ShowPromptService.ts @@ -0,0 +1,30 @@ +import AppError from "../../errors/AppError"; +import Prompt from "../../models/Prompt"; +import Queue from "../../models/Queue"; + +interface Data { + promptId: string | number; + companyId: string | number; +} +const ShowPromptService = async ({ promptId, companyId }: Data): Promise => { + + const prompt = await Prompt.findOne({ + where: { + id: promptId, + companyId + }, + include: [ + { + model: Queue, + as: "queue" + } + ] + }); + + if (!prompt) { + throw new AppError("ERR_NO_PROMPT_FOUND", 404); + } + + return prompt; +}; +export default ShowPromptService; diff --git a/backend/src/services/PromptServices/UpdatePromptService.ts b/backend/src/services/PromptServices/UpdatePromptService.ts new file mode 100644 index 0000000..ed70999 --- /dev/null +++ b/backend/src/services/PromptServices/UpdatePromptService.ts @@ -0,0 +1,58 @@ +import * as Yup from "yup"; +import AppError from "../../errors/AppError"; +import Prompt from "../../models/Prompt"; +import ShowPromptService from "./ShowPromptService"; + +interface PromptData { + id?: number; + name: string; + apiKey: string; + prompt: string; + maxTokens?: number; + temperature?: number; + promptTokens?: number; + completionTokens?: number; + totalTokens?: number; + queueId?: number; + maxMessages?: number; + companyId: string | number; + voice?: string; + voiceKey?: string; + voiceRegion?: string; +} + +interface Request { + promptData: PromptData; + promptId: string | number; + companyId: string | number; +} + +const UpdatePromptService = async ({ + promptId, + promptData, + companyId +}: Request): Promise => { + const promptTable = await ShowPromptService({ promptId: promptId, companyId }); + + const promptSchema = Yup.object().shape({ + name: Yup.string().required("ERR_PROMPT_NAME_INVALID"), + prompt: Yup.string().required("ERR_PROMPT_PROMPT_INVALID"), + apiKey: Yup.string().required("ERR_PROMPT_APIKEY_INVALID"), + queueId: Yup.number().required("ERR_PROMPT_QUEUEID_INVALID"), + maxMessages: Yup.number().required("ERR_PROMPT_MAX_MESSAGES_INVALID") + }); + + const { name, apiKey, prompt, maxTokens, temperature, promptTokens, completionTokens, totalTokens, queueId, maxMessages, voice, voiceKey, voiceRegion } = promptData; + + try { + await promptSchema.validate({ name, apiKey, prompt, maxTokens, temperature, promptTokens, completionTokens, totalTokens, queueId, maxMessages }); + } catch (err) { + throw new AppError(`${JSON.stringify(err, undefined, 2)}`); + } + + await promptTable.update({ name, apiKey, prompt, maxTokens, temperature, promptTokens, completionTokens, totalTokens, queueId, maxMessages, voice, voiceKey, voiceRegion }); + await promptTable.reload(); + return promptTable; +}; + +export default UpdatePromptService; diff --git a/backend/src/services/QueueIntegrationServices/CreateQueueIntegrationService.ts b/backend/src/services/QueueIntegrationServices/CreateQueueIntegrationService.ts new file mode 100644 index 0000000..c0f4529 --- /dev/null +++ b/backend/src/services/QueueIntegrationServices/CreateQueueIntegrationService.ts @@ -0,0 +1,86 @@ +import * as Yup from "yup"; + +import AppError from "../../errors/AppError"; +import QueueIntegrations from "../../models/QueueIntegrations"; + + +interface Request { + type: string; + name: string; + projectName: string; + jsonContent: string; + language: string; + urlN8N?: string; + companyId: number; + typebotSlug?: string; + typebotExpires?: number; + typebotKeywordFinish?: string; + typebotUnknownMessage?: string; + typebotDelayMessage?: number; + typebotKeywordRestart?: string; + typebotRestartMessage?: string; +} + +const CreateQueueIntegrationService = async ({ + type, + name, + projectName, + jsonContent, + language, + urlN8N, + companyId, + typebotExpires, + typebotKeywordFinish, + typebotSlug, + typebotUnknownMessage, + typebotDelayMessage, + typebotKeywordRestart, + typebotRestartMessage +}: Request): Promise => { + const schema = Yup.object().shape({ + name: Yup.string() + .required() + .min(2) + .test( + "Check-name", + "This integration name is already used.", + async value => { + if (!value) return false; + const nameExists = await QueueIntegrations.findOne({ + where: { name: value, companyId } + }); + return !nameExists; + } + ) + }); + + try { + await schema.validate({ type, name, projectName, jsonContent, language, urlN8N, companyId }); + } catch (err) { + throw new AppError(err.message); + } + + + const queueIntegration = await QueueIntegrations.create( + { + type, + name, + projectName, + jsonContent, + language, + urlN8N, + companyId, + typebotExpires, + typebotKeywordFinish, + typebotSlug, + typebotUnknownMessage, + typebotDelayMessage, + typebotKeywordRestart, + typebotRestartMessage + } + ); + + return queueIntegration; +}; + +export default CreateQueueIntegrationService; \ No newline at end of file diff --git a/backend/src/services/QueueIntegrationServices/DeleteQueueIntegrationService.ts b/backend/src/services/QueueIntegrationServices/DeleteQueueIntegrationService.ts new file mode 100644 index 0000000..5f9d3ef --- /dev/null +++ b/backend/src/services/QueueIntegrationServices/DeleteQueueIntegrationService.ts @@ -0,0 +1,16 @@ +import QueueIntegrations from "../../models/QueueIntegrations"; +import AppError from "../../errors/AppError"; + +const DeleteQueueIntegrationService = async (id: string): Promise => { + const dialogflow = await QueueIntegrations.findOne({ + where: { id } + }); + + if (!dialogflow) { + throw new AppError("ERR_NO_DIALOG_FOUND", 404); + } + + await dialogflow.destroy(); +}; + +export default DeleteQueueIntegrationService; \ No newline at end of file diff --git a/backend/src/services/QueueIntegrationServices/ListQueueIntegrationService.ts b/backend/src/services/QueueIntegrationServices/ListQueueIntegrationService.ts new file mode 100644 index 0000000..18247a6 --- /dev/null +++ b/backend/src/services/QueueIntegrationServices/ListQueueIntegrationService.ts @@ -0,0 +1,57 @@ +import { Sequelize, Op, Filterable } from "sequelize"; +import QueueIntegrations from "../../models/QueueIntegrations"; + +interface Request { + searchParam?: string; + pageNumber?: string | number; + companyId: number; +} + +interface Response { + queueIntegrations: QueueIntegrations[]; + count: number; + hasMore: boolean; +} + +const ListQueueIntegrationService = async ({ + searchParam = "", + pageNumber = "1", + companyId +}: Request): Promise => { + let whereCondition: Filterable["where"] = { + [Op.or]: [ + { + "$QueueIntegrations.name$": Sequelize.where( + Sequelize.fn("LOWER", Sequelize.col("QueueIntegrations.name")), + "LIKE", + `%${searchParam.toLowerCase()}%` + ) + } + ] + }; + + whereCondition = { + ...whereCondition, + companyId + }; + + const limit = 20; + const offset = limit * (+pageNumber - 1); + + const { count, rows: queueIntegrations } = await QueueIntegrations.findAndCountAll({ + where: whereCondition, + limit, + offset, + order: [["createdAt", "DESC"]], + }); + + const hasMore = count > offset + queueIntegrations.length; + + return { + queueIntegrations, + count, + hasMore + }; +}; + +export default ListQueueIntegrationService; \ No newline at end of file diff --git a/backend/src/services/QueueIntegrationServices/ShowQueueIntegrationService.ts b/backend/src/services/QueueIntegrationServices/ShowQueueIntegrationService.ts new file mode 100644 index 0000000..11d37b1 --- /dev/null +++ b/backend/src/services/QueueIntegrationServices/ShowQueueIntegrationService.ts @@ -0,0 +1,19 @@ +import QueueIntegrations from "../../models/QueueIntegrations"; +import AppError from "../../errors/AppError"; + + +const ShowQueueIntegrationService = async (id: string | number, companyId: number): Promise => { + const integration = await QueueIntegrations.findByPk(id); + + // if (Number(integration?.companyId) !== Number(companyId)) { + // throw new AppError("Não é possível excluir registro de outra empresa"); + // } + + if (!integration) { + throw new AppError("ERR_NO_DIALOG_FOUND", 404); + } + + return integration; +}; + +export default ShowQueueIntegrationService; \ No newline at end of file diff --git a/backend/src/services/QueueIntegrationServices/UpdateQueueIntegrationService.ts b/backend/src/services/QueueIntegrationServices/UpdateQueueIntegrationService.ts new file mode 100644 index 0000000..b973fc8 --- /dev/null +++ b/backend/src/services/QueueIntegrationServices/UpdateQueueIntegrationService.ts @@ -0,0 +1,83 @@ +import * as Yup from "yup"; + +import AppError from "../../errors/AppError"; +import QueueIntegrations from "../../models/QueueIntegrations"; +import ShowIntegrationService from "./ShowQueueIntegrationService"; + +interface IntegrationData { + type?: string; + name?: string; + projectName?: string; + jsonContent?: string; + language?: string; + urlN8N?: string; + typebotSlug?: string; + typebotExpires?: number; + typebotKeywordFinish?: string; + typebotUnknownMessage?: string; + typebotDelayMessage?: number; + typebotKeywordRestart?: string; + typebotRestartMessage?: string; +} + +interface Request { + integrationData: IntegrationData; + integrationId: string; + companyId: number; +} + +const UpdateQueueIntegrationService = async ({ + integrationData, + integrationId, + companyId +}: Request): Promise => { + const schema = Yup.object().shape({ + type: Yup.string().min(2), + name: Yup.string().min(2) + }); + + const { + type, + name, + projectName, + jsonContent, + language, + urlN8N, + typebotExpires, + typebotKeywordFinish, + typebotSlug, + typebotUnknownMessage, + typebotDelayMessage, + typebotKeywordRestart, + typebotRestartMessage + } = integrationData; + + try { + await schema.validate({ type, name, projectName, jsonContent, language, urlN8N }); + } catch (err) { + throw new AppError(err.message); + } + + const integration = await ShowIntegrationService(integrationId, companyId); + + await integration.update({ + type, + name, + projectName, + jsonContent, + language, + urlN8N, + companyId, + typebotExpires, + typebotKeywordFinish, + typebotSlug, + typebotUnknownMessage, + typebotDelayMessage, + typebotKeywordRestart, + typebotRestartMessage + }); + + return integration; +}; + +export default UpdateQueueIntegrationService; \ No newline at end of file diff --git a/backend/src/services/QueueOptionService/CreateService.ts b/backend/src/services/QueueOptionService/CreateService.ts new file mode 100644 index 0000000..6027841 --- /dev/null +++ b/backend/src/services/QueueOptionService/CreateService.ts @@ -0,0 +1,16 @@ +import QueueOption from "../../models/QueueOption"; + +interface QueueOptionData { + queueId: string; + title: string; + option: string; + message?: string; + parentId?: string; +} + +const CreateService = async (queueOptionData: QueueOptionData): Promise => { + const queueOption = await QueueOption.create(queueOptionData); + return queueOption; +}; + +export default CreateService; diff --git a/backend/src/services/QueueOptionService/DeleteService.ts b/backend/src/services/QueueOptionService/DeleteService.ts new file mode 100644 index 0000000..07a506e --- /dev/null +++ b/backend/src/services/QueueOptionService/DeleteService.ts @@ -0,0 +1,9 @@ +import ShowService from "./ShowService"; + +const DeleteService = async (queueOptionId: number | string): Promise => { + const queueOption = await ShowService(queueOptionId); + + await queueOption.destroy(); +}; + +export default DeleteService; diff --git a/backend/src/services/QueueOptionService/ListService.ts b/backend/src/services/QueueOptionService/ListService.ts new file mode 100644 index 0000000..a2cc9b1 --- /dev/null +++ b/backend/src/services/QueueOptionService/ListService.ts @@ -0,0 +1,38 @@ +import { WhereOptions } from "sequelize/types"; +import QueueOption from "../../models/QueueOption"; + +type QueueOptionFilter = { + queueId: string | number; + queueOptionId: string | number; + parentId: string | number | boolean; +}; + +const ListService = async ({ queueId, queueOptionId, parentId }: QueueOptionFilter): Promise => { + + const whereOptions: WhereOptions = {}; + + if (queueId) { + whereOptions.queueId = queueId; + } + + if (queueOptionId) { + whereOptions.id = queueOptionId; + } + + if (parentId == -1) { + whereOptions.parentId = null; + } + + if (parentId > 0) { + whereOptions.parentId = parentId; + } + + const queueOptions = await QueueOption.findAll({ + where: whereOptions, + order: [["id", "ASC"]] + }); + + return queueOptions; +}; + +export default ListService; diff --git a/backend/src/services/QueueOptionService/ShowService.ts b/backend/src/services/QueueOptionService/ShowService.ts new file mode 100644 index 0000000..bbb24a0 --- /dev/null +++ b/backend/src/services/QueueOptionService/ShowService.ts @@ -0,0 +1,26 @@ +import AppError from "../../errors/AppError"; +import QueueOption from "../../models/QueueOption"; + +const ShowService = async (queueOptionId: number | string): Promise => { + const queue = await QueueOption.findOne({ + where: { + id: queueOptionId + }, + include: [ + { + model: QueueOption, + as: 'parent', + where: { parentId: queueOptionId }, + required: false + }, + ] + }); + + if (!queue) { + throw new AppError("ERR_QUEUE_NOT_FOUND"); + } + + return queue; +}; + +export default ShowService; diff --git a/backend/src/services/QueueOptionService/UpdateService.ts b/backend/src/services/QueueOptionService/UpdateService.ts new file mode 100644 index 0000000..f288f80 --- /dev/null +++ b/backend/src/services/QueueOptionService/UpdateService.ts @@ -0,0 +1,24 @@ +import QueueOption from "../../models/QueueOption"; +import ShowService from "./ShowService"; + +interface QueueData { + queueId?: string; + title?: string; + option?: string; + message?: string; + parentId?: string; +} + +const UpdateService = async ( + queueOptionId: number | string, + queueOptionData: QueueData +): Promise => { + + const queueOption = await ShowService(queueOptionId); + + await queueOption.update(queueOptionData); + + return queueOption; +}; + +export default UpdateService; diff --git a/backend/src/services/QueueService/CreateQueueService.ts b/backend/src/services/QueueService/CreateQueueService.ts new file mode 100644 index 0000000..b428c83 --- /dev/null +++ b/backend/src/services/QueueService/CreateQueueService.ts @@ -0,0 +1,94 @@ +import * as Yup from "yup"; +import AppError from "../../errors/AppError"; +import Queue from "../../models/Queue"; +import Company from "../../models/Company"; +import Plan from "../../models/Plan"; + +interface QueueData { + name: string; + color: string; + companyId: number; + greetingMessage?: string; + outOfHoursMessage?: string; + schedules?: any[]; + orderQueue?: number; + integrationId?: number; + promptId?: number; +} + +const CreateQueueService = async (queueData: QueueData): Promise => { + const { color, name, companyId } = queueData; + + const company = await Company.findOne({ + where: { + id: companyId + }, + include: [{ model: Plan, as: "plan" }] + }); + + if (company !== null) { + const queuesCount = await Queue.count({ + where: { + companyId + } + }); + + if (queuesCount >= company.plan.queues) { + throw new AppError(`Número máximo de filas já alcançado: ${queuesCount}`); + } + } + + const queueSchema = Yup.object().shape({ + name: Yup.string() + .min(2, "ERR_QUEUE_INVALID_NAME") + .required("ERR_QUEUE_INVALID_NAME") + .test( + "Check-unique-name", + "ERR_QUEUE_NAME_ALREADY_EXISTS", + async value => { + if (value) { + const queueWithSameName = await Queue.findOne({ + where: { name: value, companyId } + }); + + return !queueWithSameName; + } + return false; + } + ), + color: Yup.string() + .required("ERR_QUEUE_INVALID_COLOR") + .test("Check-color", "ERR_QUEUE_INVALID_COLOR", async value => { + if (value) { + const colorTestRegex = /^#[0-9a-f]{3,6}$/i; + return colorTestRegex.test(value); + } + return false; + }) + .test( + "Check-color-exists", + "ERR_QUEUE_COLOR_ALREADY_EXISTS", + async value => { + if (value) { + const queueWithSameColor = await Queue.findOne({ + where: { color: value, companyId } + }); + return !queueWithSameColor; + } + return false; + } + ) + }); + + try { + await queueSchema.validate({ color, name }); + } catch (err: any) { + throw new AppError(err.message); + } + + const queue = await Queue.create(queueData); + + return queue; +}; + +export default CreateQueueService; diff --git a/backend/src/services/QueueService/DeleteQueueService.ts b/backend/src/services/QueueService/DeleteQueueService.ts new file mode 100644 index 0000000..3a04c3e --- /dev/null +++ b/backend/src/services/QueueService/DeleteQueueService.ts @@ -0,0 +1,12 @@ +import ShowQueueService from "./ShowQueueService"; + +const DeleteQueueService = async ( + queueId: number | string, + companyId: number +): Promise => { + const queue = await ShowQueueService(queueId, companyId); + + await queue.destroy(); +}; + +export default DeleteQueueService; diff --git a/backend/src/services/QueueService/ListQueuesService.ts b/backend/src/services/QueueService/ListQueuesService.ts new file mode 100644 index 0000000..b092209 --- /dev/null +++ b/backend/src/services/QueueService/ListQueuesService.ts @@ -0,0 +1,18 @@ +import Queue from "../../models/Queue"; + +interface Request { + companyId: number; +} + +const ListQueuesService = async ({ companyId }: Request): Promise => { + const queues = await Queue.findAll({ + where: { + companyId + }, + order: [["orderQueue", "ASC"]] + }); + + return queues; +}; + +export default ListQueuesService; diff --git a/backend/src/services/QueueService/ShowQueueService.ts b/backend/src/services/QueueService/ShowQueueService.ts new file mode 100644 index 0000000..3c3329d --- /dev/null +++ b/backend/src/services/QueueService/ShowQueueService.ts @@ -0,0 +1,21 @@ +import AppError from "../../errors/AppError"; +import Queue from "../../models/Queue"; + +const ShowQueueService = async ( + queueId: number | string, + companyId: number +): Promise => { + const queue = await Queue.findByPk(queueId); + + if (queue?.companyId !== companyId) { + throw new AppError("Não é possível consultar registros de outra empresa"); + } + + if (!queue) { + throw new AppError("ERR_QUEUE_NOT_FOUND"); + } + + return queue; +}; + +export default ShowQueueService; diff --git a/backend/src/services/QueueService/UpdateQueueService.ts b/backend/src/services/QueueService/UpdateQueueService.ts new file mode 100644 index 0000000..50028e8 --- /dev/null +++ b/backend/src/services/QueueService/UpdateQueueService.ts @@ -0,0 +1,83 @@ +import { Op } from "sequelize"; +import * as Yup from "yup"; +import AppError from "../../errors/AppError"; +import Queue from "../../models/Queue"; +import ShowQueueService from "./ShowQueueService"; + +interface QueueData { + name?: string; + color?: string; + greetingMessage?: string; + outOfHoursMessage?: string; + schedules?: any[]; + orderQueue?: number; + integrationId?: number; + promptId?: number; +} + +const UpdateQueueService = async ( + queueId: number | string, + queueData: QueueData, + companyId: number +): Promise => { + const { color, name } = queueData; + + const queueSchema = Yup.object().shape({ + name: Yup.string() + .min(2, "ERR_QUEUE_INVALID_NAME") + .test( + "Check-unique-name", + "ERR_QUEUE_NAME_ALREADY_EXISTS", + async value => { + if (value) { + const queueWithSameName = await Queue.findOne({ + where: { name: value, id: { [Op.ne]: queueId }, companyId } + }); + + return !queueWithSameName; + } + return true; + } + ), + color: Yup.string() + .required("ERR_QUEUE_INVALID_COLOR") + .test("Check-color", "ERR_QUEUE_INVALID_COLOR", async value => { + if (value) { + const colorTestRegex = /^#[0-9a-f]{3,6}$/i; + return colorTestRegex.test(value); + } + return true; + }) + .test( + "Check-color-exists", + "ERR_QUEUE_COLOR_ALREADY_EXISTS", + async value => { + if (value) { + const queueWithSameColor = await Queue.findOne({ + where: { color: value, id: { [Op.ne]: queueId }, companyId } + }); + return !queueWithSameColor; + } + return true; + } + ) + }); + + try { + await queueSchema.validate({ color, name }); + } catch (err: any) { + throw new AppError(err.message); + } + + const queue = await ShowQueueService(queueId, companyId); + + if (queue.companyId !== companyId) { + throw new AppError("Não é permitido alterar registros de outra empresa"); + } + + await queue.update(queueData); + + return queue; +}; + +export default UpdateQueueService; diff --git a/backend/src/services/QuickMessageService/CreateService.ts b/backend/src/services/QuickMessageService/CreateService.ts new file mode 100644 index 0000000..94eb198 --- /dev/null +++ b/backend/src/services/QuickMessageService/CreateService.ts @@ -0,0 +1,35 @@ +import * as Yup from "yup"; +import AppError from "../../errors/AppError"; +import QuickMessage from "../../models/QuickMessage"; + +interface Data { + shortcode: string; + message: string; + companyId: number | string; + userId: number | string; +} + +const CreateService = async (data: Data): Promise => { + const { shortcode, message } = data; + + const ticketnoteSchema = Yup.object().shape({ + shortcode: Yup.string() + .min(3, "ERR_QUICKMESSAGE_INVALID_NAME") + .required("ERR_QUICKMESSAGE_REQUIRED"), + message: Yup.string() + .min(3, "ERR_QUICKMESSAGE_INVALID_NAME") + .required("ERR_QUICKMESSAGE_REQUIRED") + }); + + try { + await ticketnoteSchema.validate({ shortcode, message }); + } catch (err: any) { + throw new AppError(err.message); + } + + const record = await QuickMessage.create(data); + + return record; +}; + +export default CreateService; diff --git a/backend/src/services/QuickMessageService/DeleteService.ts b/backend/src/services/QuickMessageService/DeleteService.ts new file mode 100644 index 0000000..e2d09bf --- /dev/null +++ b/backend/src/services/QuickMessageService/DeleteService.ts @@ -0,0 +1,16 @@ +import QuickMessage from "../../models/QuickMessage"; +import AppError from "../../errors/AppError"; + +const DeleteService = async (id: string): Promise => { + const record = await QuickMessage.findOne({ + where: { id } + }); + + if (!record) { + throw new AppError("ERR_NO_QUICKMESSAGE_FOUND", 404); + } + + await record.destroy(); +}; + +export default DeleteService; diff --git a/backend/src/services/QuickMessageService/FindAllService.ts b/backend/src/services/QuickMessageService/FindAllService.ts new file mode 100644 index 0000000..e461f72 --- /dev/null +++ b/backend/src/services/QuickMessageService/FindAllService.ts @@ -0,0 +1,10 @@ +import QuickMessage from "../../models/QuickMessage"; + +const FindAllService = async (): Promise => { + const records: QuickMessage[] = await QuickMessage.findAll({ + order: [["shortcode", "ASC"]] + }); + return records; +}; + +export default FindAllService; diff --git a/backend/src/services/QuickMessageService/FindService.ts b/backend/src/services/QuickMessageService/FindService.ts new file mode 100644 index 0000000..4866ac1 --- /dev/null +++ b/backend/src/services/QuickMessageService/FindService.ts @@ -0,0 +1,23 @@ +import { Op } from "sequelize"; +import QuickMessage from "../../models/QuickMessage"; +import Company from "../../models/Company"; + +type Params = { + companyId: string; + userId: string; +}; + +const FindService = async ({ companyId, userId }: Params): Promise => { + const notes: QuickMessage[] = await QuickMessage.findAll({ + where: { + companyId, + userId, + }, + include: [{ model: Company, as: "company", attributes: ["id", "name"] }], + order: [["shortcode", "ASC"]] + }); + + return notes; +}; + +export default FindService; diff --git a/backend/src/services/QuickMessageService/ListService.ts b/backend/src/services/QuickMessageService/ListService.ts new file mode 100644 index 0000000..89fb973 --- /dev/null +++ b/backend/src/services/QuickMessageService/ListService.ts @@ -0,0 +1,67 @@ +import { Sequelize, Op, Filterable } from "sequelize"; +import QuickMessage from "../../models/QuickMessage"; + +interface Request { + searchParam?: string; + pageNumber?: string; + companyId: number | string; + userId?: number | string; +} + +interface Response { + records: QuickMessage[]; + count: number; + hasMore: boolean; +} + +const ListService = async ({ + searchParam = "", + pageNumber = "1", + companyId, + userId +}: Request): Promise => { + const sanitizedSearchParam = searchParam.toLocaleLowerCase().trim(); + + let whereCondition: Filterable["where"] = { + // [Op.or]: [ + // { + shortcode: Sequelize.where( + Sequelize.fn("LOWER", Sequelize.col("shortcode")), + "LIKE", + `%${sanitizedSearchParam}%` + ) + // }, + // { + // message: Sequelize.where( + // Sequelize.fn("LOWER", Sequelize.col("message")), + // "LIKE", + // `%${sanitizedSearchParam}%` + // ) + // } + // ] + }; + whereCondition = { + ...whereCondition, + companyId, + userId: userId + } + const limit = 20; + const offset = limit * (+pageNumber - 1); + + const { count, rows: records } = await QuickMessage.findAndCountAll({ + where: whereCondition, + limit, + offset, + order: [["shortcode", "ASC"]] + }); + + const hasMore = count > offset + records.length; + + return { + records, + count, + hasMore + }; +}; + +export default ListService; \ No newline at end of file diff --git a/backend/src/services/QuickMessageService/ShowService.ts b/backend/src/services/QuickMessageService/ShowService.ts new file mode 100644 index 0000000..a12282c --- /dev/null +++ b/backend/src/services/QuickMessageService/ShowService.ts @@ -0,0 +1,14 @@ +import QuickMessage from "../../models/QuickMessage"; +import AppError from "../../errors/AppError"; + +const ShowService = async (id: string | number): Promise => { + const record = await QuickMessage.findByPk(id); + + if (!record) { + throw new AppError("ERR_NO_TICKETNOTE_FOUND", 404); + } + + return record; +}; + +export default ShowService; diff --git a/backend/src/services/QuickMessageService/UpdateService.ts b/backend/src/services/QuickMessageService/UpdateService.ts new file mode 100644 index 0000000..e8a4e8f --- /dev/null +++ b/backend/src/services/QuickMessageService/UpdateService.ts @@ -0,0 +1,29 @@ +import AppError from "../../errors/AppError"; +import QuickMessage from "../../models/QuickMessage"; + +interface Data { + shortcode: string; + message: string; + userId: number | string; + id?: number | string; +} + +const UpdateService = async (data: Data): Promise => { + const { id, shortcode, message, userId } = data; + + const record = await QuickMessage.findByPk(id); + + if (!record) { + throw new AppError("ERR_NO_TICKETNOTE_FOUND", 404); + } + + await record.update({ + shortcode, + message, + userId + }); + + return record; +}; + +export default UpdateService; diff --git a/backend/src/services/ReportService/DashbardDataService.ts b/backend/src/services/ReportService/DashbardDataService.ts new file mode 100644 index 0000000..378ee00 --- /dev/null +++ b/backend/src/services/ReportService/DashbardDataService.ts @@ -0,0 +1,144 @@ +/* eslint-disable import/no-extraneous-dependencies */ +/* eslint-disable camelcase */ +import { QueryTypes } from "sequelize"; +import * as _ from "lodash"; +import sequelize from "../../database"; + +export interface DashboardData { + counters: any; + attendants: []; +} + +export interface Params { + days?: number; + date_from?: string; + date_to?: string; +} + +export default async function DashboardDataService( + companyId: string | number, + params: Params +): Promise { + const query = ` + with + traking as ( + select + c.name "companyName", + u.name "userName", + u.online "userOnline", + w.name "whatsappName", + ct.name "contactName", + ct.number "contactNumber", + (tt."finishedAt" is not null) "finished", + (tt."userId" is null and tt."finishedAt" is null) "pending", + coalesce(( + (date_part('day', age(coalesce(tt."ratingAt", tt."finishedAt") , tt."startedAt")) * 24 * 60) + + (date_part('hour', age(coalesce(tt."ratingAt", tt."finishedAt"), tt."startedAt")) * 60) + + (date_part('minutes', age(coalesce(tt."ratingAt", tt."finishedAt"), tt."startedAt"))) + ), 0) "supportTime", + coalesce(( + (date_part('day', age(tt."startedAt", tt."queuedAt")) * 24 * 60) + + (date_part('hour', age(tt."startedAt", tt."queuedAt")) * 60) + + (date_part('minutes', age(tt."startedAt", tt."queuedAt"))) + ), 0) "waitTime", + t.status, + tt.*, + ct."id" "contactId" + from "TicketTraking" tt + left join "Companies" c on c.id = tt."companyId" + left join "Users" u on u.id = tt."userId" + left join "Whatsapps" w on w.id = tt."whatsappId" + left join "Tickets" t on t.id = tt."ticketId" + left join "Contacts" ct on ct.id = t."contactId" + -- filterPeriod + ), + counters as ( + select + (select avg("supportTime") from traking where "supportTime" > 0) "avgSupportTime", + (select avg("waitTime") from traking where "waitTime" > 0) "avgWaitTime", + ( + select count(distinct "id") + from "Tickets" + where status like 'open' and "companyId" = ? + ) "supportHappening", + ( + select count(distinct "id") + from "Tickets" + where status like 'pending' and "companyId" = ? + ) "supportPending", + (select count(id) from traking where finished) "supportFinished", + ( + select count(leads.id) from ( + select + ct1.id, + count(tt1.id) total + from traking tt1 + left join "Tickets" t1 on t1.id = tt1."ticketId" + left join "Contacts" ct1 on ct1.id = t1."contactId" + group by 1 + having count(tt1.id) = 1 + ) leads + ) "leads" + ), + attedants as ( + select + u.id, + u.name, + coalesce(att."avgSupportTime", 0) "avgSupportTime", + att.tickets, + att.rating, + att.online + from "Users" u + left join ( + select + u1.id, + u1."name", + u1."online", + avg(t."supportTime") "avgSupportTime", + count(t."id") tickets, + coalesce(avg(ur.rate), 0) rating + from "Users" u1 + left join traking t on t."userId" = u1.id + left join "UserRatings" ur on ur."userId" = t."userId" and ur."createdAt"::date = t."finishedAt"::date + group by 1, 2 + ) att on att.id = u.id + where u."companyId" = ? + order by att.name + ) + select + (select coalesce(jsonb_build_object('counters', c.*)->>'counters', '{}')::jsonb from counters c) counters, + (select coalesce(json_agg(a.*), '[]')::jsonb from attedants a) attendants; + `; + + let where = 'where tt."companyId" = ?'; + const replacements: any[] = [companyId]; + + if (_.has(params, "days")) { + where += ` and tt."queuedAt" >= (now() - '? days'::interval)`; + replacements.push(parseInt(`${params.days}`.replace(/\D/g, ""), 10)); + } + + if (_.has(params, "date_from")) { + where += ` and tt."queuedAt" >= ?`; + replacements.push(`${params.date_from} 00:00:00`); + } + + if (_.has(params, "date_to")) { + where += ` and tt."finishedAt" <= ?`; + replacements.push(`${params.date_to} 23:59:59`); + } + + replacements.push(companyId); + replacements.push(companyId); + replacements.push(companyId); + + const finalQuery = query.replace("-- filterPeriod", where); + + const responseData: DashboardData = await sequelize.query(finalQuery, { + replacements, + type: QueryTypes.SELECT, + plain: true + }); + + return responseData; +} diff --git a/backend/src/services/ReportService/TicketsAttendance.ts b/backend/src/services/ReportService/TicketsAttendance.ts new file mode 100644 index 0000000..ecafcaa --- /dev/null +++ b/backend/src/services/ReportService/TicketsAttendance.ts @@ -0,0 +1,60 @@ +import sequelize from "../../database/index"; +import { QueryTypes } from "sequelize"; + +interface Return { + data: {}; +} + +interface Request { + initialDate: string; + finalDate: string; + companyId: number; +} + +interface DataReturn { + quantidade: number; + data?: number; + nome?: string; +} + +interface dataUser { + name: string; +} + +export const TicketsAttendance = async ({ initialDate, finalDate, companyId }: Request): Promise => { + + const sqlUsers = `select u.name from "Users" u where u."companyId" = ${companyId}` + + const users: dataUser[] = await sequelize.query(sqlUsers, { type: QueryTypes.SELECT }); + + const sql = ` + select + COUNT(*) AS quantidade, + u.name AS nome + from + "TicketTraking" tt + left join "Users" u on u.id = tt."userId" + where + tt."companyId" = ${companyId} + and "ticketId" is not null + and tt."userId" is not null + and tt."finishedAt" >= '${initialDate} 00:00:00' + and tt."finishedAt" <= '${finalDate} 23:59:59' + group by + nome + ORDER BY + nome asc` + + const data: DataReturn[] = await sequelize.query(sql, { type: QueryTypes.SELECT }); + + users.map(user => { + let indexCreated = data.findIndex((item) => item.nome === user.name); + + if (indexCreated === -1) { + data.push({ quantidade: 0, nome: user.name }) + } + + }) + + return { data }; +} diff --git a/backend/src/services/ReportService/TicketsDayService.ts b/backend/src/services/ReportService/TicketsDayService.ts new file mode 100644 index 0000000..d501e87 --- /dev/null +++ b/backend/src/services/ReportService/TicketsDayService.ts @@ -0,0 +1,70 @@ +import sequelize from "../../database/index"; +import { QueryTypes } from "sequelize"; + +interface Return { + data: {}; + count: number; +} + +interface Request { + initialDate: string; + finalDate: string; + companyId: number; +} + +interface DataReturn { + total: number; + data?: number; + horario?: string; +} + +export const TicketsDayService = async ({ initialDate, finalDate, companyId }: Request): Promise => { + + let sql = ''; + let count = 0; + + if (initialDate && initialDate.trim() === finalDate && finalDate.trim()) { + sql = ` + SELECT + COUNT(*) AS total, + extract(hour from tick."createdAt") AS horario + --to_char(DATE(tick."createdAt"), 'dd-mm-YYYY') as horario + FROM + "TicketTraking" tick + WHERE + tick."companyId" = ${companyId} + and DATE(tick."createdAt") >= '${initialDate} 00:00:00' + AND DATE(tick."createdAt") <= '${finalDate} 23:59:59' + GROUP BY + extract(hour from tick."createdAt") + --to_char(DATE(tick."createdAt"), 'dd-mm-YYYY') + ORDER BY + horario asc; + ` + } else { + sql = ` + SELECT + COUNT(*) AS total, + to_char(DATE(tick."createdAt"), 'dd/mm/YYYY') as data + FROM + "TicketTraking" tick + WHERE + tick."companyId" = ${companyId} + and DATE(tick."createdAt") >= '${initialDate}' + AND DATE(tick."createdAt") <= '${finalDate}' + GROUP BY + to_char(DATE(tick."createdAt"), 'dd/mm/YYYY') + ORDER BY + data asc; + ` + } + + const data: DataReturn[] = await sequelize.query(sql, { type: QueryTypes.SELECT }); + + data.forEach((register) => { + count += Number(register.total); + }) + + return { data, count }; + +} diff --git a/backend/src/services/ResetPasswordService/ResetPassword.ts b/backend/src/services/ResetPasswordService/ResetPassword.ts new file mode 100644 index 0000000..071db69 --- /dev/null +++ b/backend/src/services/ResetPasswordService/ResetPassword.ts @@ -0,0 +1,51 @@ +import sequelize from "sequelize"; +import database from "../../database"; +import { hash } from "bcryptjs"; +const ResetPassword = async ( + email: string, + token: string, + password: string +) => { + const { hasResult, data } = await filterUser(email, token); + if (!hasResult) { + return { status: 404, message: "Email não encontrado" }; + } + if (hasResult === true) { + try { + const convertPassword: string = await hash(password, 8); + const { hasResults, datas } = await insertHasPassword( + email, + token, + convertPassword + ); + if (datas.length === 0) { + return { status: 404, message: "Token não encontrado" }; + } + } catch (err) { + console.log(err); + } + } +}; +export default ResetPassword; +const filterUser = async (email: string, token: string) => { + const sql = `SELECT * FROM "Users" WHERE email = '${email}' AND "resetPassword" != ''`; + const result = await database.query(sql, { + type: sequelize.QueryTypes.SELECT + }); + return { hasResult: result.length > 0, data: result }; +}; +const insertHasPassword = async ( + email: string, + token: string, + convertPassword: string +) => { + const sqlValida = `SELECT * FROM "Users" WHERE email = '${email}' AND "resetPassword" = '${token}'`; + const resultado = await database.query(sqlValida, { + type: sequelize.QueryTypes.SELECT + }); + const sqls = `UPDATE "Users" SET "passwordHash"= '${convertPassword}' , "resetPassword" = '' WHERE email= '${email}' AND "resetPassword" = '${token}'`; + const results = await database.query(sqls, { + type: sequelize.QueryTypes.UPDATE + }); + return { hasResults: results.length > 0, datas: resultado }; +}; diff --git a/backend/src/services/ResetPasswordService/ResetPassword.ts.bak b/backend/src/services/ResetPasswordService/ResetPassword.ts.bak new file mode 100644 index 0000000..411f45e --- /dev/null +++ b/backend/src/services/ResetPasswordService/ResetPassword.ts.bak @@ -0,0 +1,48 @@ +import sequelize from "sequelize"; +import database from "../../database"; +import { hash } from "bcryptjs"; + +const ResetPassword = async (email: string ,token: string, password: string) => { + + const {hasResult , data} = await filterUser(email, token); + + if (!hasResult) { + return { status: 404, message: "Email não encontrado" }; + } + + if(hasResult === true){ + try{ + const convertPassword: string= await hash(password,8) + + const {hasResults , datas} = await insertHasPassword(email, token ,convertPassword); + + if (datas.length === 0){ + return { status: 404, message: "Token não encontrado" }; + } + + }catch(err){ + console.log(err) + } + } + +} +export default ResetPassword; + +const filterUser = async (email : string , token: string)=>{ + const sql = `SELECT * FROM "Users" WHERE email = '${email}' AND "resetPassword" != ''`; + const result = await database.query(sql, { type: sequelize.QueryTypes.SELECT }); + return { hasResult: result.length > 0, data: result }; +} +const insertHasPassword = async (email : string , token: string, convertPassword: string)=>{ + + + const sqlValida = `SELECT * FROM "Users" WHERE email = '${email}' AND "resetPassword" = '${token}'`; + const resultado = await database.query(sqlValida, { type: sequelize.QueryTypes.SELECT }); + + + const sqls = `UPDATE "Users" SET "passwordHash"= '${convertPassword}' , "resetPassword" = '' WHERE email= '${email}' AND "resetPassword" = '${token}'`; + const results = await database.query(sqls, { type: sequelize.QueryTypes.UPDATE }); + + + return { hasResults: results.length > 0, datas: resultado}; +} \ No newline at end of file diff --git a/backend/src/services/ScheduleServices/CreateService.ts b/backend/src/services/ScheduleServices/CreateService.ts new file mode 100644 index 0000000..0454976 --- /dev/null +++ b/backend/src/services/ScheduleServices/CreateService.ts @@ -0,0 +1,48 @@ +import * as Yup from "yup"; + +import AppError from "../../errors/AppError"; +import Schedule from "../../models/Schedule"; + +interface Request { + body: string; + sendAt: string; + contactId: number | string; + companyId: number | string; + userId?: number | string; +} + +const CreateService = async ({ + body, + sendAt, + contactId, + companyId, + userId +}: Request): Promise => { + const schema = Yup.object().shape({ + body: Yup.string().required().min(5), + sendAt: Yup.string().required() + }); + + try { + await schema.validate({ body, sendAt }); + } catch (err: any) { + throw new AppError(err.message); + } + + const schedule = await Schedule.create( + { + body, + sendAt, + contactId, + companyId, + userId, + status: 'PENDENTE' + } + ); + + await schedule.reload(); + + return schedule; +}; + +export default CreateService; diff --git a/backend/src/services/ScheduleServices/DeleteService.ts b/backend/src/services/ScheduleServices/DeleteService.ts new file mode 100644 index 0000000..bdda0c2 --- /dev/null +++ b/backend/src/services/ScheduleServices/DeleteService.ts @@ -0,0 +1,16 @@ +import Schedule from "../../models/Schedule"; +import AppError from "../../errors/AppError"; + +const DeleteService = async (id: string | number, companyId: number): Promise => { + const schedule = await Schedule.findOne({ + where: { id, companyId } + }); + + if (!schedule) { + throw new AppError("ERR_NO_SCHEDULE_FOUND", 404); + } + + await schedule.destroy(); +}; + +export default DeleteService; diff --git a/backend/src/services/ScheduleServices/ListService.ts b/backend/src/services/ScheduleServices/ListService.ts new file mode 100644 index 0000000..14b193b --- /dev/null +++ b/backend/src/services/ScheduleServices/ListService.ts @@ -0,0 +1,93 @@ +import { Op, Sequelize } from "sequelize"; +import Contact from "../../models/Contact"; +import Schedule from "../../models/Schedule"; +import User from "../../models/User"; + +interface Request { + searchParam?: string; + contactId?: number | string; + userId?: number | string; + companyId?: number; + pageNumber?: string | number; +} + +interface Response { + schedules: Schedule[]; + count: number; + hasMore: boolean; +} + +const ListService = async ({ + searchParam, + contactId = "", + userId = "", + pageNumber = "1", + companyId +}: Request): Promise => { + let whereCondition = {}; + const limit = 20; + const offset = limit * (+pageNumber - 1); + + if (searchParam) { + whereCondition = { + [Op.or]: [ + { + "$Schedule.body$": Sequelize.where( + Sequelize.fn("LOWER", Sequelize.col("Schedule.body")), + "LIKE", + `%${searchParam.toLowerCase()}%` + ) + }, + { + "$Contact.name$": Sequelize.where( + Sequelize.fn("LOWER", Sequelize.col("contact.name")), + "LIKE", + `%${searchParam.toLowerCase()}%` + ) + }, + ], + } + } + + if (contactId !== "") { + whereCondition = { + ...whereCondition, + contactId + } + } + + if (userId !== "") { + whereCondition = { + ...whereCondition, + userId + } + } + + whereCondition = { + ...whereCondition, + companyId: { + [Op.eq]: companyId + } + } + + const { count, rows: schedules } = await Schedule.findAndCountAll({ + where: whereCondition, + limit, + offset, + order: [["createdAt", "DESC"]], + include: [ + { model: Contact, as: "contact", attributes: ["id", "name"] }, + { model: User, as: "user", attributes: ["id", "name"] }, + ] + }); + + const hasMore = count > offset + schedules.length; + + return { + schedules, + count, + hasMore + }; +}; + +export default ListService; diff --git a/backend/src/services/ScheduleServices/ShowService.ts b/backend/src/services/ScheduleServices/ShowService.ts new file mode 100644 index 0000000..6237703 --- /dev/null +++ b/backend/src/services/ScheduleServices/ShowService.ts @@ -0,0 +1,25 @@ +import Schedule from "../../models/Schedule"; +import AppError from "../../errors/AppError"; +import Contact from "../../models/Contact"; +import User from "../../models/User"; + +const ScheduleService = async (id: string | number, companyId: number): Promise => { + const schedule = await Schedule.findByPk(id, { + include: [ + { model: Contact, as: "contact", attributes: ["id", "name"] }, + { model: User, as: "user", attributes: ["id", "name"] }, + ] + }); + + if (schedule?.companyId !== companyId) { + throw new AppError("Não é possível excluir registro de outra empresa"); + } + + if (!schedule) { + throw new AppError("ERR_NO_SCHEDULE_FOUND", 404); + } + + return schedule; +}; + +export default ScheduleService; diff --git a/backend/src/services/ScheduleServices/UpdateService.ts b/backend/src/services/ScheduleServices/UpdateService.ts new file mode 100644 index 0000000..649ca5c --- /dev/null +++ b/backend/src/services/ScheduleServices/UpdateService.ts @@ -0,0 +1,67 @@ +import * as Yup from "yup"; + +import AppError from "../../errors/AppError"; +import Schedule from "../../models/Schedule"; +import ShowService from "./ShowService"; + +interface ScheduleData { + id?: number; + body?: string; + sendAt?: string; + sentAt?: string; + contactId?: number; + companyId?: number; + ticketId?: number; + userId?: number; +} + +interface Request { + scheduleData: ScheduleData; + id: string | number; + companyId: number; +} + +const UpdateUserService = async ({ + scheduleData, + id, + companyId +}: Request): Promise => { + const schedule = await ShowService(id, companyId); + + if (schedule?.companyId !== companyId) { + throw new AppError("Não é possível alterar registros de outra empresa"); + } + + const schema = Yup.object().shape({ + body: Yup.string().min(5) + }); + + const { + body, + sendAt, + sentAt, + contactId, + ticketId, + userId, + } = scheduleData; + + try { + await schema.validate({ body }); + } catch (err: any) { + throw new AppError(err.message); + } + + await schedule.update({ + body, + sendAt, + sentAt, + contactId, + ticketId, + userId, + }); + + await schedule.reload(); + return schedule; +}; + +export default UpdateUserService; diff --git a/backend/src/services/SettingServices/ListSettingsService.ts b/backend/src/services/SettingServices/ListSettingsService.ts new file mode 100644 index 0000000..19853e3 --- /dev/null +++ b/backend/src/services/SettingServices/ListSettingsService.ts @@ -0,0 +1,19 @@ +import Setting from "../../models/Setting"; + +interface Request { + companyId: number; +} + +const ListSettingsService = async ({ + companyId +}: Request): Promise => { + const settings = await Setting.findAll({ + where: { + companyId + } + }); + + return settings; +}; + +export default ListSettingsService; diff --git a/backend/src/services/SettingServices/ListSettingsServiceOne.ts b/backend/src/services/SettingServices/ListSettingsServiceOne.ts new file mode 100644 index 0000000..4d64221 --- /dev/null +++ b/backend/src/services/SettingServices/ListSettingsServiceOne.ts @@ -0,0 +1,22 @@ +import Setting from "../../models/Setting"; + +interface Request { + companyId: number; + key?: string; +} + +const ListSettingsServiceOne = async ({ + companyId, + key +}: Request): Promise => { + const setting = await Setting.findOne({ + where: { + companyId, + ...(key && { key }) + } + }); + + return setting; +}; + +export default ListSettingsServiceOne; \ No newline at end of file diff --git a/backend/src/services/SettingServices/UpdateSettingService.ts b/backend/src/services/SettingServices/UpdateSettingService.ts new file mode 100644 index 0000000..af05567 --- /dev/null +++ b/backend/src/services/SettingServices/UpdateSettingService.ts @@ -0,0 +1,40 @@ +import AppError from "../../errors/AppError"; +import Setting from "../../models/Setting"; + +interface Request { + key: string; + value: string; + companyId: number; +} + +const UpdateSettingService = async ({ + key, + value, + companyId +}: Request): Promise => { + const [setting] = await Setting.findOrCreate({ + where: { + key, + companyId + }, + defaults: { + key, + value, + companyId + } + }); + + if (setting != null && setting?.companyId !== companyId) { + throw new AppError("Não é possível consultar registros de outra empresa"); + } + + if (!setting) { + throw new AppError("ERR_NO_SETTING_FOUND", 404); + } + + await setting.update({ value }); + + return setting; +}; + +export default UpdateSettingService; diff --git a/backend/src/services/TagServices/CreateService.ts b/backend/src/services/TagServices/CreateService.ts new file mode 100644 index 0000000..45527a4 --- /dev/null +++ b/backend/src/services/TagServices/CreateService.ts @@ -0,0 +1,39 @@ +import * as Yup from "yup"; + +import AppError from "../../errors/AppError"; +import Tag from "../../models/Tag"; + +interface Request { + name: string; + color: string; + kanban: number; + companyId: number; +} + +const CreateService = async ({ + name, + color = "#A4CCCC", + kanban = 0, + companyId +}: Request): Promise => { + const schema = Yup.object().shape({ + name: Yup.string().required().min(3) + }); + + try { + await schema.validate({ name }); + } catch (err: any) { + throw new AppError(err.message); + } + + const [tag] = await Tag.findOrCreate({ + where: { name, color, companyId, kanban }, + defaults: { name, color, companyId, kanban } + }); + + await tag.reload(); + + return tag; +}; + +export default CreateService; diff --git a/backend/src/services/TagServices/DeleteService.ts b/backend/src/services/TagServices/DeleteService.ts new file mode 100644 index 0000000..9d81b7b --- /dev/null +++ b/backend/src/services/TagServices/DeleteService.ts @@ -0,0 +1,16 @@ +import Tag from "../../models/Tag"; +import AppError from "../../errors/AppError"; + +const DeleteService = async (id: string | number): Promise => { + const tag = await Tag.findOne({ + where: { id } + }); + + if (!tag) { + throw new AppError("ERR_NO_TAG_FOUND", 404); + } + + await tag.destroy(); +}; + +export default DeleteService; diff --git a/backend/src/services/TagServices/KanbanListService.ts b/backend/src/services/TagServices/KanbanListService.ts new file mode 100644 index 0000000..f999a41 --- /dev/null +++ b/backend/src/services/TagServices/KanbanListService.ts @@ -0,0 +1,24 @@ +import { Op } from "sequelize"; +import Tag from "../../models/Tag"; +import Ticket from "../../models/Ticket"; +import TicketTag from "../../models/TicketTag"; + +interface Request { + companyId: number; +} + +const KanbanListService = async ({ + companyId +}: Request): Promise => { + const tags = await Tag.findAll({ + where: { + kanban: 1, + companyId: companyId, + }, + order: [["id", "ASC"]], + raw: true, + }); + return tags; +}; + +export default KanbanListService; diff --git a/backend/src/services/TagServices/ListService.ts b/backend/src/services/TagServices/ListService.ts new file mode 100644 index 0000000..b07787d --- /dev/null +++ b/backend/src/services/TagServices/ListService.ts @@ -0,0 +1,66 @@ +import { Op, literal, fn, col } from "sequelize"; +import Tag from "../../models/Tag"; +import Ticket from "../../models/Ticket"; +import TicketTag from "../../models/TicketTag"; + +interface Request { + companyId: number; + searchParam?: string; + pageNumber?: string | number; +} + +interface Response { + tags: Tag[]; + count: number; + hasMore: boolean; +} + +const ListService = async ({ + companyId, + searchParam, + pageNumber = "1" +}: Request): Promise => { + let whereCondition = {}; + const limit = 5000; + const offset = limit * (+pageNumber - 1); + + if (searchParam) { + whereCondition = { + [Op.or]: [ + { name: { [Op.like]: `%${searchParam}%` } }, + { color: { [Op.like]: `%${searchParam}%` } } + ] + }; + } + + const { count, rows: tags } = await Tag.findAndCountAll({ + where: { ...whereCondition, companyId }, + limit, + offset, + order: [["name", "ASC"]], + subQuery: false, + include: [{ + model: TicketTag, + as: 'ticketTags', + attributes: [], + required: false + }], + attributes: [ + 'id', + 'name', + 'color', + [fn('count', col('ticketTags.tagId')), 'ticketsCount'] + ], + group: ['Tag.id'] + }); + + const hasMore = count > offset + tags.length; + + return { + tags, + count, + hasMore + }; +}; + +export default ListService; diff --git a/backend/src/services/TagServices/ShowService.ts b/backend/src/services/TagServices/ShowService.ts new file mode 100644 index 0000000..fec4ade --- /dev/null +++ b/backend/src/services/TagServices/ShowService.ts @@ -0,0 +1,14 @@ +import Tag from "../../models/Tag"; +import AppError from "../../errors/AppError"; + +const TagService = async (id: string | number): Promise => { + const tag = await Tag.findByPk(id); + + if (!tag) { + throw new AppError("ERR_NO_TAG_FOUND", 404); + } + + return tag; +}; + +export default TagService; diff --git a/backend/src/services/TagServices/SimpleListService.ts b/backend/src/services/TagServices/SimpleListService.ts new file mode 100644 index 0000000..451cb93 --- /dev/null +++ b/backend/src/services/TagServices/SimpleListService.ts @@ -0,0 +1,34 @@ +import { Op, Sequelize } from "sequelize"; +import Tag from "../../models/Tag"; +import Ticket from "../../models/Ticket"; +import TicketTag from "../../models/TicketTag"; + +interface Request { + companyId: number; + searchParam?: string; +} + +const ListService = async ({ + companyId, + searchParam +}: Request): Promise => { + let whereCondition = {}; + + if (searchParam) { + whereCondition = { + [Op.or]: [ + { name: { [Op.like]: `%${searchParam}%` } }, + { color: { [Op.like]: `%${searchParam}%` } } + ] + }; + } + + const tags = await Tag.findAll({ + where: { ...whereCondition, companyId }, + order: [["name", "ASC"]] + }); + + return tags; +}; + +export default ListService; diff --git a/backend/src/services/TagServices/SyncTagsService.ts b/backend/src/services/TagServices/SyncTagsService.ts new file mode 100644 index 0000000..18ef7c0 --- /dev/null +++ b/backend/src/services/TagServices/SyncTagsService.ts @@ -0,0 +1,26 @@ +import Tag from "../../models/Tag"; +import Ticket from "../../models/Ticket"; +import TicketTag from "../../models/TicketTag"; + +interface Request { + tags: Tag[]; + ticketId: number; +} + +const SyncTags = async ({ + tags, + ticketId +}: Request): Promise => { + const ticket = await Ticket.findByPk(ticketId, { include: [Tag] }); + + const tagList = tags.map(t => ({ tagId: t.id, ticketId })); + + await TicketTag.destroy({ where: { ticketId } }); + await TicketTag.bulkCreate(tagList); + + ticket?.reload(); + + return ticket; +}; + +export default SyncTags; diff --git a/backend/src/services/TagServices/UpdateService.ts b/backend/src/services/TagServices/UpdateService.ts new file mode 100644 index 0000000..06889ad --- /dev/null +++ b/backend/src/services/TagServices/UpdateService.ts @@ -0,0 +1,47 @@ +import * as Yup from "yup"; + +import AppError from "../../errors/AppError"; +import Tag from "../../models/Tag"; +import ShowService from "./ShowService"; + +interface TagData { + id?: number; + name?: string; + color?: string; + kanban?: number; +} + +interface Request { + tagData: TagData; + id: string | number; +} + +const UpdateUserService = async ({ + tagData, + id +}: Request): Promise => { + const tag = await ShowService(id); + + const schema = Yup.object().shape({ + name: Yup.string().min(3) + }); + + const { name, color, kanban } = tagData; + + try { + await schema.validate({ name }); + } catch (err: any) { + throw new AppError(err.message); + } + + await tag.update({ + name, + color, + kanban + }); + + await tag.reload(); + return tag; +}; + +export default UpdateUserService; diff --git a/backend/src/services/TicketNoteService/CreateTicketNoteService.ts b/backend/src/services/TicketNoteService/CreateTicketNoteService.ts new file mode 100644 index 0000000..08b6518 --- /dev/null +++ b/backend/src/services/TicketNoteService/CreateTicketNoteService.ts @@ -0,0 +1,34 @@ +import * as Yup from "yup"; +import AppError from "../../errors/AppError"; +import TicketNote from "../../models/TicketNote"; + +interface TicketNoteData { + note: string; + userId: number | string; + contactId: number | string; + ticketId: number | string; +} + +const CreateTicketNoteService = async ( + ticketNoteData: TicketNoteData +): Promise => { + const { note } = ticketNoteData; + + const ticketnoteSchema = Yup.object().shape({ + note: Yup.string() + .min(3, "ERR_TICKETNOTE_INVALID_NAME") + .required("ERR_TICKETNOTE_INVALID_NAME") + }); + + try { + await ticketnoteSchema.validate({ note }); + } catch (err) { + throw new AppError(err.message); + } + + const ticketNote = await TicketNote.create(ticketNoteData); + + return ticketNote; +}; + +export default CreateTicketNoteService; diff --git a/backend/src/services/TicketNoteService/DeleteTicketNoteService.ts b/backend/src/services/TicketNoteService/DeleteTicketNoteService.ts new file mode 100644 index 0000000..5d8f9fe --- /dev/null +++ b/backend/src/services/TicketNoteService/DeleteTicketNoteService.ts @@ -0,0 +1,16 @@ +import TicketNote from "../../models/TicketNote"; +import AppError from "../../errors/AppError"; + +const DeleteTicketNoteService = async (id: string): Promise => { + const ticketnote = await TicketNote.findOne({ + where: { id } + }); + + if (!ticketnote) { + throw new AppError("ERR_NO_TICKETNOTE_FOUND", 404); + } + + await ticketnote.destroy(); +}; + +export default DeleteTicketNoteService; diff --git a/backend/src/services/TicketNoteService/FindAllTicketNotesService.ts b/backend/src/services/TicketNoteService/FindAllTicketNotesService.ts new file mode 100644 index 0000000..57fc19e --- /dev/null +++ b/backend/src/services/TicketNoteService/FindAllTicketNotesService.ts @@ -0,0 +1,8 @@ +import TicketNote from "../../models/TicketNote"; + +const FindAllTicketNotesService = async (): Promise => { + const ticketNote = await TicketNote.findAll(); + return ticketNote; +}; + +export default FindAllTicketNotesService; diff --git a/backend/src/services/TicketNoteService/FindNotesByContactIdAndTicketId.ts b/backend/src/services/TicketNoteService/FindNotesByContactIdAndTicketId.ts new file mode 100644 index 0000000..bd01d0e --- /dev/null +++ b/backend/src/services/TicketNoteService/FindNotesByContactIdAndTicketId.ts @@ -0,0 +1,31 @@ +import TicketNote from "../../models/TicketNote"; +import User from "../../models/User"; +import Contact from "../../models/Contact"; +import Ticket from "../../models/Ticket"; + +interface Params { + contactId: number | string; + ticketId: number | string; +} + +const FindNotesByContactIdAndTicketId = async ({ + contactId, + ticketId +}: Params): Promise => { + const notes: TicketNote[] = await TicketNote.findAll({ + where: { + contactId, + ticketId + }, + include: [ + { model: User, as: "user", attributes: ["id", "name", "email"] }, + { model: Contact, as: "contact", attributes: ["id", "name"] }, + { model: Ticket, as: "ticket", attributes: ["id", "status", "createdAt"] } + ], + order: [["createdAt", "DESC"]] + }); + + return notes; +}; + +export default FindNotesByContactIdAndTicketId; diff --git a/backend/src/services/TicketNoteService/ListTicketNotesService.ts b/backend/src/services/TicketNoteService/ListTicketNotesService.ts new file mode 100644 index 0000000..900061e --- /dev/null +++ b/backend/src/services/TicketNoteService/ListTicketNotesService.ts @@ -0,0 +1,49 @@ +import { Sequelize, Op } from "sequelize"; +import TicketNote from "../../models/TicketNote"; + +interface Request { + searchParam?: string; + pageNumber?: string; +} + +interface Response { + ticketNotes: TicketNote[]; + count: number; + hasMore: boolean; +} + +const ListTicketNotesService = async ({ + searchParam = "", + pageNumber = "1" +}: Request): Promise => { + const whereCondition = { + [Op.or]: [ + { + note: Sequelize.where( + Sequelize.fn("LOWER", Sequelize.col("note")), + "LIKE", + `%${searchParam.toLowerCase().trim()}%` + ) + } + ] + }; + const limit = 20; + const offset = limit * (+pageNumber - 1); + + const { count, rows: ticketNotes } = await TicketNote.findAndCountAll({ + where: whereCondition, + limit, + offset, + order: [["createdAt", "DESC"]] + }); + + const hasMore = count > offset + ticketNotes.length; + + return { + ticketNotes, + count, + hasMore + }; +}; + +export default ListTicketNotesService; diff --git a/backend/src/services/TicketNoteService/ShowTicketNoteService.ts b/backend/src/services/TicketNoteService/ShowTicketNoteService.ts new file mode 100644 index 0000000..ead2ae6 --- /dev/null +++ b/backend/src/services/TicketNoteService/ShowTicketNoteService.ts @@ -0,0 +1,16 @@ +import TicketNote from "../../models/TicketNote"; +import AppError from "../../errors/AppError"; + +const ShowTicketNoteService = async ( + id: string | number +): Promise => { + const ticketNote = await TicketNote.findByPk(id); + + if (!ticketNote) { + throw new AppError("ERR_NO_TICKETNOTE_FOUND", 404); + } + + return ticketNote; +}; + +export default ShowTicketNoteService; diff --git a/backend/src/services/TicketNoteService/UpdateTicketNoteService.ts b/backend/src/services/TicketNoteService/UpdateTicketNoteService.ts new file mode 100644 index 0000000..a656260 --- /dev/null +++ b/backend/src/services/TicketNoteService/UpdateTicketNoteService.ts @@ -0,0 +1,27 @@ +import AppError from "../../errors/AppError"; +import TicketNote from "../../models/TicketNote"; + +interface TicketNoteData { + note: string; + id?: number | string; +} + +const UpdateTicketNoteService = async ( + ticketNoteData: TicketNoteData +): Promise => { + const { id, note } = ticketNoteData; + + const ticketNote = await TicketNote.findByPk(id); + + if (!ticketNote) { + throw new AppError("ERR_NO_TICKETNOTE_FOUND", 404); + } + + await ticketNote.update({ + note + }); + + return ticketNote; +}; + +export default UpdateTicketNoteService; diff --git a/backend/src/services/TicketServices/CreateTicketService.ts b/backend/src/services/TicketServices/CreateTicketService.ts new file mode 100644 index 0000000..528e912 --- /dev/null +++ b/backend/src/services/TicketServices/CreateTicketService.ts @@ -0,0 +1,82 @@ +import AppError from "../../errors/AppError"; +import CheckContactOpenTickets from "../../helpers/CheckContactOpenTickets"; +import GetDefaultWhatsApp from "../../helpers/GetDefaultWhatsApp"; +import Ticket from "../../models/Ticket"; +import ShowContactService from "../ContactServices/ShowContactService"; +import { getIO } from "../../libs/socket"; +import GetDefaultWhatsAppByUser from "../../helpers/GetDefaultWhatsAppByUser"; +import ShowWhatsAppService from "../WhatsappService/ShowWhatsAppService"; + +interface Request { + contactId: number; + status: string; + userId: number; + companyId: number; + queueId?: number; + whatsappId?: string; +} + +const CreateTicketService = async ({ + contactId, + status, + userId, + queueId, + companyId, + whatsappId +}: Request): Promise => { + let whatsapp; + + if (whatsappId !== undefined && whatsappId !== null && whatsappId !== "") { + whatsapp = await ShowWhatsAppService(whatsappId, companyId) + } + + let defaultWhatsapp = await GetDefaultWhatsAppByUser(userId); + + if (whatsapp) { + defaultWhatsapp = whatsapp; + } + if (!defaultWhatsapp) + defaultWhatsapp = await GetDefaultWhatsApp(companyId); + + await CheckContactOpenTickets(contactId, whatsappId); + + const { isGroup } = await ShowContactService(contactId, companyId); + + const [{ id }] = await Ticket.findOrCreate({ + where: { + contactId, + companyId, + whatsappId + }, + defaults: { + contactId, + companyId, + whatsappId: defaultWhatsapp.id, + status, + isGroup, + userId + } + }); + + await Ticket.update( + { companyId, queueId, userId, whatsappId: defaultWhatsapp.id, status: "open" }, + { where: { id } } + ); + + const ticket = await Ticket.findByPk(id, { include: ["contact", "queue"] }); + + if (!ticket) { + throw new AppError("ERR_CREATING_TICKET"); + } + + const io = getIO(); + + io.to(ticket.id.toString()).emit("ticket", { + action: "update", + ticket + }); + + return ticket; +}; + +export default CreateTicketService; diff --git a/backend/src/services/TicketServices/DeleteTicketService.ts b/backend/src/services/TicketServices/DeleteTicketService.ts new file mode 100644 index 0000000..279a913 --- /dev/null +++ b/backend/src/services/TicketServices/DeleteTicketService.ts @@ -0,0 +1,18 @@ +import Ticket from "../../models/Ticket"; +import AppError from "../../errors/AppError"; + +const DeleteTicketService = async (id: string): Promise => { + const ticket = await Ticket.findOne({ + where: { id } + }); + + if (!ticket) { + throw new AppError("ERR_NO_TICKET_FOUND", 404); + } + + await ticket.destroy(); + + return ticket; +}; + +export default DeleteTicketService; diff --git a/backend/src/services/TicketServices/FindOrCreateATicketTrakingService.ts b/backend/src/services/TicketServices/FindOrCreateATicketTrakingService.ts new file mode 100644 index 0000000..80d0df3 --- /dev/null +++ b/backend/src/services/TicketServices/FindOrCreateATicketTrakingService.ts @@ -0,0 +1,40 @@ +import { Op } from "sequelize"; +import TicketTraking from "../../models/TicketTraking"; + +interface Params { + ticketId: string | number; + companyId: string | number; + whatsappId?: string | number; + userId?: string | number; +} + +const FindOrCreateATicketTrakingService = async ({ + ticketId, + companyId, + whatsappId, + userId +}: Params): Promise => { + const ticketTraking = await TicketTraking.findOne({ + where: { + ticketId, + finishedAt: { + [Op.is]: null + } + } + }); + + if (ticketTraking) { + return ticketTraking; + } + + const newRecord = await TicketTraking.create({ + ticketId, + companyId, + whatsappId, + userId + }); + + return newRecord; +}; + +export default FindOrCreateATicketTrakingService; diff --git a/backend/src/services/TicketServices/FindOrCreateTicketService.ts b/backend/src/services/TicketServices/FindOrCreateTicketService.ts new file mode 100644 index 0000000..ca1cf9b --- /dev/null +++ b/backend/src/services/TicketServices/FindOrCreateTicketService.ts @@ -0,0 +1,128 @@ +import { subHours } from "date-fns"; +import { Op } from "sequelize"; +import Contact from "../../models/Contact"; +import Ticket from "../../models/Ticket"; +import ShowTicketService from "./ShowTicketService"; +import FindOrCreateATicketTrakingService from "./FindOrCreateATicketTrakingService"; +import Setting from "../../models/Setting"; +import Whatsapp from "../../models/Whatsapp"; + +interface TicketData { + status?: string; + companyId?: number; + unreadMessages?: number; +} + +const FindOrCreateTicketService = async ( + contact: Contact, + whatsappId: number, + unreadMessages: number, + companyId: number, + groupContact?: Contact +): Promise => { + let ticket = await Ticket.findOne({ + where: { + status: { + [Op.or]: ["open", "pending", "closed"] + }, + contactId: groupContact ? groupContact.id : contact.id, + companyId, + whatsappId + }, + order: [["id", "DESC"]] + }); + + if (ticket) { + await ticket.update({ unreadMessages, whatsappId }); + } + + if (ticket?.status === "closed") { + await ticket.update({ queueId: null, userId: null }); + } + + if (!ticket && groupContact) { + ticket = await Ticket.findOne({ + where: { + contactId: groupContact.id + }, + order: [["updatedAt", "DESC"]] + }); + + if (ticket) { + await ticket.update({ + status: "pending", + userId: null, + unreadMessages, + queueId: null, + companyId + }); + await FindOrCreateATicketTrakingService({ + ticketId: ticket.id, + companyId, + whatsappId: ticket.whatsappId, + userId: ticket.userId + }); + } + const msgIsGroupBlock = await Setting.findOne({ + where: { key: "timeCreateNewTicket" } + }); + + const value = msgIsGroupBlock ? parseInt(msgIsGroupBlock.value, 10) : 7200; + } + + if (!ticket && !groupContact) { + ticket = await Ticket.findOne({ + where: { + updatedAt: { + [Op.between]: [+subHours(new Date(), 2), +new Date()] + }, + contactId: contact.id + }, + order: [["updatedAt", "DESC"]] + }); + + if (ticket) { + await ticket.update({ + status: "pending", + userId: null, + unreadMessages, + queueId: null, + companyId + }); + await FindOrCreateATicketTrakingService({ + ticketId: ticket.id, + companyId, + whatsappId: ticket.whatsappId, + userId: ticket.userId + }); + } + } + + const whatsapp = await Whatsapp.findOne({ + where: { id: whatsappId } + }); + + if (!ticket) { + ticket = await Ticket.create({ + contactId: groupContact ? groupContact.id : contact.id, + status: "pending", + isGroup: !!groupContact, + unreadMessages, + whatsappId, + whatsapp, + companyId + }); + await FindOrCreateATicketTrakingService({ + ticketId: ticket.id, + companyId, + whatsappId, + userId: ticket.userId + }); + } + + ticket = await ShowTicketService(ticket.id, companyId); + + return ticket; +}; + +export default FindOrCreateTicketService; diff --git a/backend/src/services/TicketServices/ListTicketsService.ts b/backend/src/services/TicketServices/ListTicketsService.ts new file mode 100644 index 0000000..8fff0c4 --- /dev/null +++ b/backend/src/services/TicketServices/ListTicketsService.ts @@ -0,0 +1,237 @@ +import { Op, fn, where, col, Filterable, Includeable } from "sequelize"; +import { startOfDay, endOfDay, parseISO } from "date-fns"; + +import Ticket from "../../models/Ticket"; +import Contact from "../../models/Contact"; +import Message from "../../models/Message"; +import Queue from "../../models/Queue"; +import User from "../../models/User"; +import ShowUserService from "../UserServices/ShowUserService"; +import Tag from "../../models/Tag"; +import TicketTag from "../../models/TicketTag"; +import { intersection } from "lodash"; +import Whatsapp from "../../models/Whatsapp"; + +interface Request { + searchParam?: string; + pageNumber?: string; + status?: string; + date?: string; + updatedAt?: string; + showAll?: string; + userId: string; + withUnreadMessages?: string; + queueIds: number[]; + tags: number[]; + users: number[]; + companyId: number; +} + +interface Response { + tickets: Ticket[]; + count: number; + hasMore: boolean; +} + +const ListTicketsService = async ({ + searchParam = "", + pageNumber = "1", + queueIds, + tags, + users, + status, + date, + updatedAt, + showAll, + userId, + withUnreadMessages, + companyId +}: Request): Promise => { + let whereCondition: Filterable["where"] = { + [Op.or]: [{ userId }, { status: "pending" }], + queueId: { [Op.or]: [queueIds, null] } + }; + let includeCondition: Includeable[]; + + includeCondition = [ + { + model: Contact, + as: "contact", + attributes: ["id", "name", "number", "email", "profilePicUrl"] + }, + { + model: Queue, + as: "queue", + attributes: ["id", "name", "color"] + }, + { + model: User, + as: "user", + attributes: ["id", "name"] + }, + { + model: Tag, + as: "tags", + attributes: ["id", "name", "color"] + }, + { + model: Whatsapp, + as: "whatsapp", + attributes: ["name"] + }, + ]; + + if (showAll === "true") { + whereCondition = { queueId: { [Op.or]: [queueIds, null] } }; + } + + if (status) { + whereCondition = { + ...whereCondition, + status + }; + } + + if (searchParam) { + const sanitizedSearchParam = searchParam.toLocaleLowerCase().trim(); + + includeCondition = [ + ...includeCondition, + { + model: Message, + as: "messages", + attributes: ["id", "body"], + where: { + body: where( + fn("LOWER", col("body")), + "LIKE", + `%${sanitizedSearchParam}%` + ) + }, + required: false, + duplicating: false + } + ]; + + whereCondition = { + ...whereCondition, + [Op.or]: [ + { + "$contact.name$": where( + fn("LOWER", col("contact.name")), + "LIKE", + `%${sanitizedSearchParam}%` + ) + }, + { "$contact.number$": { [Op.like]: `%${sanitizedSearchParam}%` } }, + { + "$message.body$": where( + fn("LOWER", col("body")), + "LIKE", + `%${sanitizedSearchParam}%` + ) + } + ] + }; + } + + if (date) { + whereCondition = { + createdAt: { + [Op.between]: [+startOfDay(parseISO(date)), +endOfDay(parseISO(date))] + } + }; + } + + if (updatedAt) { + whereCondition = { + updatedAt: { + [Op.between]: [ + +startOfDay(parseISO(updatedAt)), + +endOfDay(parseISO(updatedAt)) + ] + } + }; + } + + if (withUnreadMessages === "true") { + const user = await ShowUserService(userId); + const userQueueIds = user.queues.map(queue => queue.id); + + whereCondition = { + [Op.or]: [{ userId }, { status: "pending" }], + queueId: { [Op.or]: [userQueueIds, null] }, + unreadMessages: { [Op.gt]: 0 } + }; + } + + if (Array.isArray(tags) && tags.length > 0) { + const ticketsTagFilter: any[] | null = []; + for (let tag of tags) { + const ticketTags = await TicketTag.findAll({ + where: { tagId: tag } + }); + if (ticketTags) { + ticketsTagFilter.push(ticketTags.map(t => t.ticketId)); + } + } + + const ticketsIntersection: number[] = intersection(...ticketsTagFilter); + + whereCondition = { + ...whereCondition, + id: { + [Op.in]: ticketsIntersection + } + }; + } + + if (Array.isArray(users) && users.length > 0) { + const ticketsUserFilter: any[] | null = []; + for (let user of users) { + const ticketUsers = await Ticket.findAll({ + where: { userId: user } + }); + if (ticketUsers) { + ticketsUserFilter.push(ticketUsers.map(t => t.id)); + } + } + + const ticketsIntersection: number[] = intersection(...ticketsUserFilter); + + whereCondition = { + ...whereCondition, + id: { + [Op.in]: ticketsIntersection + } + }; + } + + const limit = 40; + const offset = limit * (+pageNumber - 1); + + whereCondition = { + ...whereCondition, + companyId + }; + + const { count, rows: tickets } = await Ticket.findAndCountAll({ + where: whereCondition, + include: includeCondition, + distinct: true, + limit, + offset, + order: [["updatedAt", "DESC"]], + subQuery: false + }); + + const hasMore = count > offset + tickets.length; + + return { + tickets, + count, + hasMore + }; +}; + +export default ListTicketsService; \ No newline at end of file diff --git a/backend/src/services/TicketServices/ListTicketsServiceKanban.ts b/backend/src/services/TicketServices/ListTicketsServiceKanban.ts new file mode 100644 index 0000000..b96b51c --- /dev/null +++ b/backend/src/services/TicketServices/ListTicketsServiceKanban.ts @@ -0,0 +1,234 @@ +import { Op, fn, where, col, Filterable, Includeable } from "sequelize"; +import { startOfDay, endOfDay, parseISO } from "date-fns"; + +import Ticket from "../../models/Ticket"; +import Contact from "../../models/Contact"; +import Message from "../../models/Message"; +import Queue from "../../models/Queue"; +import User from "../../models/User"; +import ShowUserService from "../UserServices/ShowUserService"; +import Tag from "../../models/Tag"; +import TicketTag from "../../models/TicketTag"; +import { intersection } from "lodash"; +import Whatsapp from "../../models/Whatsapp"; + +interface Request { + searchParam?: string; + pageNumber?: string; + status?: string; + date?: string; + updatedAt?: string; + showAll?: string; + userId: string; + withUnreadMessages?: string; + queueIds: number[]; + tags: number[]; + users: number[]; + companyId: number; +} + +interface Response { + tickets: Ticket[]; + count: number; + hasMore: boolean; +} + +const ListTicketsServiceKanban = async ({ + searchParam = "", + pageNumber = "1", + queueIds, + tags, + users, + status, + date, + updatedAt, + showAll, + userId, + withUnreadMessages, + companyId +}: Request): Promise => { + let whereCondition: Filterable["where"] = { + [Op.or]: [{ userId }, { status: "pending" }], + queueId: { [Op.or]: [queueIds, null] } + }; + let includeCondition: Includeable[]; + + includeCondition = [ + { + model: Contact, + as: "contact", + attributes: ["id", "name", "number", "email"] + }, + { + model: Queue, + as: "queue", + attributes: ["id", "name", "color"] + }, + { + model: User, + as: "user", + attributes: ["id", "name"] + }, + { + model: Tag, + as: "tags", + attributes: ["id", "name", "color"] + }, + { + model: Whatsapp, + as: "whatsapp", + attributes: ["name"] + }, + ]; + + if (showAll === "true") { + whereCondition = { queueId: { [Op.or]: [queueIds, null] } }; + } + + whereCondition = { + ...whereCondition, + status: { [Op.or]: ["pending", "open"] } + }; + + if (searchParam) { + const sanitizedSearchParam = searchParam.toLocaleLowerCase().trim(); + + includeCondition = [ + ...includeCondition, + { + model: Message, + as: "messages", + attributes: ["id", "body"], + where: { + body: where( + fn("LOWER", col("body")), + "LIKE", + `%${sanitizedSearchParam}%` + ) + }, + required: false, + duplicating: false + } + ]; + + whereCondition = { + ...whereCondition, + [Op.or]: [ + { + "$contact.name$": where( + fn("LOWER", col("contact.name")), + "LIKE", + `%${sanitizedSearchParam}%` + ) + }, + { "$contact.number$": { [Op.like]: `%${sanitizedSearchParam}%` } }, + { + "$message.body$": where( + fn("LOWER", col("body")), + "LIKE", + `%${sanitizedSearchParam}%` + ) + } + ] + }; + } + + if (date) { + whereCondition = { + createdAt: { + [Op.between]: [+startOfDay(parseISO(date)), +endOfDay(parseISO(date))] + } + }; + } + + if (updatedAt) { + whereCondition = { + updatedAt: { + [Op.between]: [ + +startOfDay(parseISO(updatedAt)), + +endOfDay(parseISO(updatedAt)) + ] + } + }; + } + + if (withUnreadMessages === "true") { + const user = await ShowUserService(userId); + const userQueueIds = user.queues.map(queue => queue.id); + + whereCondition = { + [Op.or]: [{ userId }, { status: "pending" }], + queueId: { [Op.or]: [userQueueIds, null] }, + unreadMessages: { [Op.gt]: 0 } + }; + } + + if (Array.isArray(tags) && tags.length > 0) { + const ticketsTagFilter: any[] | null = []; + for (let tag of tags) { + const ticketTags = await TicketTag.findAll({ + where: { tagId: tag } + }); + if (ticketTags) { + ticketsTagFilter.push(ticketTags.map(t => t.ticketId)); + } + } + + const ticketsIntersection: number[] = intersection(...ticketsTagFilter); + + whereCondition = { + ...whereCondition, + id: { + [Op.in]: ticketsIntersection + } + }; + } + + if (Array.isArray(users) && users.length > 0) { + const ticketsUserFilter: any[] | null = []; + for (let user of users) { + const ticketUsers = await Ticket.findAll({ + where: { userId: user } + }); + if (ticketUsers) { + ticketsUserFilter.push(ticketUsers.map(t => t.id)); + } + } + + const ticketsIntersection: number[] = intersection(...ticketsUserFilter); + + whereCondition = { + ...whereCondition, + id: { + [Op.in]: ticketsIntersection + } + }; + } + + const limit = 40; + const offset = limit * (+pageNumber - 1); + + whereCondition = { + ...whereCondition, + companyId + }; + + const { count, rows: tickets } = await Ticket.findAndCountAll({ + where: whereCondition, + include: includeCondition, + distinct: true, + limit, + offset, + order: [["updatedAt", "DESC"]], + subQuery: false + }); + const hasMore = count > offset + tickets.length; + + return { + tickets, + count, + hasMore + }; +}; + +export default ListTicketsServiceKanban; \ No newline at end of file diff --git a/backend/src/services/TicketServices/ShowTicketFromUUIDService.ts b/backend/src/services/TicketServices/ShowTicketFromUUIDService.ts new file mode 100644 index 0000000..61afebf --- /dev/null +++ b/backend/src/services/TicketServices/ShowTicketFromUUIDService.ts @@ -0,0 +1,51 @@ +import Ticket from "../../models/Ticket"; +import AppError from "../../errors/AppError"; +import Contact from "../../models/Contact"; +import User from "../../models/User"; +import Queue from "../../models/Queue"; +import Tag from "../../models/Tag"; +import Whatsapp from "../../models/Whatsapp"; + +const ShowTicketUUIDService = async (uuid: string): Promise => { + const ticket = await Ticket.findOne({ + where: { + uuid + }, + include: [ + { + model: Contact, + as: "contact", + attributes: ["id", "name", "number", "email", "profilePicUrl"], + include: ["extraInfo"] + }, + { + model: User, + as: "user", + attributes: ["id", "name"] + }, + { + model: Queue, + as: "queue", + attributes: ["id", "name", "color"] + }, + { + model: Whatsapp, + as: "whatsapp", + attributes: ["name"] + }, + { + model: Tag, + as: "tags", + attributes: ["id", "name", "color"] + } + ] + }); + + if (!ticket) { + throw new AppError("ERR_NO_TICKET_FOUND", 404); + } + + return ticket; +}; + +export default ShowTicketUUIDService; diff --git a/backend/src/services/TicketServices/ShowTicketService.ts b/backend/src/services/TicketServices/ShowTicketService.ts new file mode 100644 index 0000000..2d9b516 --- /dev/null +++ b/backend/src/services/TicketServices/ShowTicketService.ts @@ -0,0 +1,57 @@ +import Ticket from "../../models/Ticket"; +import AppError from "../../errors/AppError"; +import Contact from "../../models/Contact"; +import User from "../../models/User"; +import Queue from "../../models/Queue"; +import Tag from "../../models/Tag"; +import Whatsapp from "../../models/Whatsapp"; +import Prompt from "../../models/Prompt"; + +const ShowTicketService = async ( + id: string | number, + companyId: number +): Promise => { + const ticket = await Ticket.findByPk(id, { + include: [ + { + model: Contact, + as: "contact", + attributes: ["id", "name", "number", "email", "profilePicUrl"], + include: ["extraInfo"] + }, + { + model: User, + as: "user", + attributes: ["id", "name"] + }, + { + model: Queue, + as: "queue", + attributes: ["id", "name", "color"], + include: ["prompt", "queueIntegrations"] + }, + { + model: Whatsapp, + as: "whatsapp", + attributes: ["name"] + }, + { + model: Tag, + as: "tags", + attributes: ["id", "name", "color"] + } + ] + }); + + if (ticket?.companyId !== companyId) { + throw new AppError("Não é possível consultar registros de outra empresa"); + } + + if (!ticket) { + throw new AppError("ERR_NO_TICKET_FOUND", 404); + } + + return ticket; +}; + +export default ShowTicketService; diff --git a/backend/src/services/TicketServices/UpdateTicketService.ts b/backend/src/services/TicketServices/UpdateTicketService.ts new file mode 100644 index 0000000..4292605 --- /dev/null +++ b/backend/src/services/TicketServices/UpdateTicketService.ts @@ -0,0 +1,297 @@ +import moment from "moment"; +import * as Sentry from "@sentry/node"; +import CheckContactOpenTickets from "../../helpers/CheckContactOpenTickets"; +import SetTicketMessagesAsRead from "../../helpers/SetTicketMessagesAsRead"; +import { getIO } from "../../libs/socket"; +import Ticket from "../../models/Ticket"; +import Setting from "../../models/Setting"; +import Queue from "../../models/Queue"; +import ShowTicketService from "./ShowTicketService"; +import ShowWhatsAppService from "../WhatsappService/ShowWhatsAppService"; +import SendWhatsAppMessage from "../WbotServices/SendWhatsAppMessage"; +import FindOrCreateATicketTrakingService from "./FindOrCreateATicketTrakingService"; +import GetTicketWbot from "../../helpers/GetTicketWbot"; +import { verifyMessage } from "../WbotServices/wbotMessageListener"; +import ListSettingsServiceOne from "../SettingServices/ListSettingsServiceOne"; //NOVO PLW DESIGN// +import ShowUserService from "../UserServices/ShowUserService"; //NOVO PLW DESIGN// +import { isNil } from "lodash"; +import Whatsapp from "../../models/Whatsapp"; +import { Op } from "sequelize"; +import AppError from "../../errors/AppError"; + +interface TicketData { + status?: string; + userId?: number | null; + queueId?: number | null; + chatbot?: boolean; + queueOptionId?: number; + whatsappId?: string; + useIntegration?: boolean; + integrationId?: number | null; + promptId?: number | null; +} + +interface Request { + ticketData: TicketData; + ticketId: string | number; + companyId: number; +} + +interface Response { + ticket: Ticket; + oldStatus: string; + oldUserId: number | undefined; +} + +const UpdateTicketService = async ({ + ticketData, + ticketId, + companyId +}: Request): Promise => { + + try { + const { status } = ticketData; + let { queueId, userId, whatsappId } = ticketData; + let chatbot: boolean | null = ticketData.chatbot || false; + let queueOptionId: number | null = ticketData.queueOptionId || null; + let promptId: number | null = ticketData.promptId || null; + let useIntegration: boolean | null = ticketData.useIntegration || false; + let integrationId: number | null = ticketData.integrationId || null; + + const io = getIO(); + + const key = "userRating"; + const setting = await Setting.findOne({ + where: { + companyId, + key + } + }); + + + + const ticket = await ShowTicketService(ticketId, companyId); + const ticketTraking = await FindOrCreateATicketTrakingService({ + ticketId, + companyId, + whatsappId: ticket.whatsappId + }); + + if (isNil(whatsappId)) { + whatsappId = ticket.whatsappId.toString(); + } + + await SetTicketMessagesAsRead(ticket); + + const oldStatus = ticket.status; + const oldUserId = ticket.user?.id; + const oldQueueId = ticket.queueId; + + if (oldStatus === "closed" || Number(whatsappId) !== ticket.whatsappId) { + // let otherTicket = await Ticket.findOne({ + // where: { + // contactId: ticket.contactId, + // status: { [Op.or]: ["open", "pending", "group"] }, + // whatsappId + // } + // }); + // if (otherTicket) { + // otherTicket = await ShowTicketService(otherTicket.id, companyId) + + // await ticket.update({status: "closed"}) + + // io.to(oldStatus).emit(`company-${companyId}-ticket`, { + // action: "delete", + // ticketId: ticket.id + // }); + + // return { ticket: otherTicket, oldStatus, oldUserId } + // } + await CheckContactOpenTickets(ticket.contact.id, whatsappId); + chatbot = null; + queueOptionId = null; + } + + if (status !== undefined && ["closed"].indexOf(status) > -1) { + const { complationMessage, ratingMessage } = await ShowWhatsAppService( + ticket.whatsappId, + companyId + ); + + if (setting?.value === "enabled") { + if (ticketTraking.ratingAt == null) { + const ratingTxt = ratingMessage || ""; + let bodyRatingMessage = `\u200e${ratingTxt}\n\n`; + bodyRatingMessage += + "Digite de 1 à 3 para qualificar nosso atendimento:\n*1* - _Insatisfeito_\n*2* - _Satisfeito_\n*3* - _Muito Satisfeito_\n\n"; + await SendWhatsAppMessage({ body: bodyRatingMessage, ticket }); + + await ticketTraking.update({ + ratingAt: moment().toDate() + }); + + io.to(`company-${ticket.companyId}-open`) + .to(`queue-${ticket.queueId}-open`) + .to(ticketId.toString()) + .emit(`company-${ticket.companyId}-ticket`, { + action: "delete", + ticketId: ticket.id + }); + + return { ticket, oldStatus, oldUserId }; + } + ticketTraking.ratingAt = moment().toDate(); + ticketTraking.rated = false; + } + + if (!isNil(complationMessage) && complationMessage !== "") { + const body = `\u200e${complationMessage}`; + await SendWhatsAppMessage({ body, ticket }); + } + await ticket.update({ + promptId: null, + integrationId: null, + useIntegration: false, + typebotStatus: false, + typebotSessionId: null + }) + + ticketTraking.finishedAt = moment().toDate(); + ticketTraking.whatsappId = ticket.whatsappId; + ticketTraking.userId = ticket.userId; + + /* queueId = null; + userId = null; */ + } + + if (queueId !== undefined && queueId !== null) { + ticketTraking.queuedAt = moment().toDate(); + } + + const settingsTransfTicket = await ListSettingsServiceOne({ companyId: companyId, key: "sendMsgTransfTicket" }); + + if (settingsTransfTicket?.value === "enabled") { + // Mensagem de transferencia da FILA + if (oldQueueId !== queueId && oldUserId === userId && !isNil(oldQueueId) && !isNil(queueId)) { + + const queue = await Queue.findByPk(queueId); + const wbot = await GetTicketWbot(ticket); + const msgtxt = "*Mensagem automática*:\nVocê foi transferido para o departamento *" + queue?.name + "*\naguarde, já vamos te atender!"; + + const queueChangedMessage = await wbot.sendMessage( + `${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, + { + text: msgtxt + } + ); + await verifyMessage(queueChangedMessage, ticket, ticket.contact); + } + else + // Mensagem de transferencia do ATENDENTE + if (oldUserId !== userId && oldQueueId === queueId && !isNil(oldUserId) && !isNil(userId)) { + const wbot = await GetTicketWbot(ticket); + const nome = await ShowUserService(ticketData.userId); + const msgtxt = "*Mensagem automática*:\nFoi transferido para o atendente *" + nome.name + "*\naguarde, já vamos te atender!"; + + const queueChangedMessage = await wbot.sendMessage( + `${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, + { + text: msgtxt + } + ); + await verifyMessage(queueChangedMessage, ticket, ticket.contact); + } + else + // Mensagem de transferencia do ATENDENTE e da FILA + if (oldUserId !== userId && !isNil(oldUserId) && !isNil(userId) && oldQueueId !== queueId && !isNil(oldQueueId) && !isNil(queueId)) { + const wbot = await GetTicketWbot(ticket); + const queue = await Queue.findByPk(queueId); + const nome = await ShowUserService(ticketData.userId); + const msgtxt = "*Mensagem automática*:\nVocê foi transferido para o departamento *" + queue?.name + "* e contará com a presença de *" + nome.name + "*\naguarde, já vamos te atender!"; + + const queueChangedMessage = await wbot.sendMessage( + `${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, + { + text: msgtxt + } + ); + await verifyMessage(queueChangedMessage, ticket, ticket.contact); + } else + if (oldUserId !== undefined && isNil(userId) && oldQueueId !== queueId && !isNil(queueId)) { + + const queue = await Queue.findByPk(queueId); + const wbot = await GetTicketWbot(ticket); + const msgtxt = "*Mensagem automática*:\nVocê foi transferido para o departamento *" + queue?.name + "*\naguarde, já vamos te atender!"; + + const queueChangedMessage = await wbot.sendMessage( + `${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, + { + text: msgtxt + } + ); + await verifyMessage(queueChangedMessage, ticket, ticket.contact); + } + } + + await ticket.update({ + status, + queueId, + userId, + whatsappId, + chatbot, + queueOptionId + }); + + await ticket.reload(); + + if (status !== undefined && ["pending"].indexOf(status) > -1) { + ticketTraking.update({ + whatsappId, + queuedAt: moment().toDate(), + startedAt: null, + userId: null + }); + } + + if (status !== undefined && ["open"].indexOf(status) > -1) { + ticketTraking.update({ + startedAt: moment().toDate(), + ratingAt: null, + rated: false, + whatsappId, + userId: ticket.userId + }); + } + + await ticketTraking.save(); + + if (ticket.status !== oldStatus || ticket.user?.id !== oldUserId) { + + io.to(`company-${companyId}-${oldStatus}`) + .to(`queue-${ticket.queueId}-${oldStatus}`) + .to(`user-${oldUserId}`) + .emit(`company-${companyId}-ticket`, { + action: "delete", + ticketId: ticket.id + }); + } + + io.to(`company-${companyId}-${ticket.status}`) + .to(`company-${companyId}-notification`) + .to(`queue-${ticket.queueId}-${ticket.status}`) + .to(`queue-${ticket.queueId}-notification`) + .to(ticketId.toString()) + .to(`user-${ticket?.userId}`) + .to(`user-${oldUserId}`) + .emit(`company-${companyId}-ticket`, { + action: "update", + ticket + }); + + return { ticket, oldStatus, oldUserId }; + } catch (err) { + Sentry.captureException(err); + } +}; + +export default UpdateTicketService; diff --git a/backend/src/services/TypebotServices/typebotListener.ts b/backend/src/services/TypebotServices/typebotListener.ts new file mode 100644 index 0000000..30147f3 --- /dev/null +++ b/backend/src/services/TypebotServices/typebotListener.ts @@ -0,0 +1,413 @@ +import axios from "axios"; +import Ticket from "../../models/Ticket"; +import QueueIntegrations from "../../models/QueueIntegrations"; +import { WASocket, delay, proto } from "@whiskeysockets/baileys"; +import { getBodyMessage } from "../WbotServices/wbotMessageListener"; +import { logger } from "../../utils/logger"; +import { isNil } from "lodash"; +import UpdateTicketService from "../TicketServices/UpdateTicketService"; + + +type Session = WASocket & { + id?: number; +}; + +interface Request { + wbot: Session; + msg: proto.IWebMessageInfo; + ticket: Ticket; + typebot: QueueIntegrations; +} + + +const typebotListener = async ({ + wbot, + msg, + ticket, + typebot +}: Request): Promise => { + + if (msg.key.remoteJid === 'status@broadcast') return; + + const { urlN8N: url, + typebotExpires, + typebotKeywordFinish, + typebotKeywordRestart, + typebotUnknownMessage, + typebotSlug, + typebotDelayMessage, + typebotRestartMessage + } = typebot; + + const number = msg.key.remoteJid.replace(/\D/g, ''); + + let body = getBodyMessage(msg); + + async function createSession(msg, typebot, number) { + try { + const id = Math.floor(Math.random() * 10000000000).toString(); + + const reqData = JSON.stringify({ + "isStreamEnabled": true, + "message": "string", + "resultId": "string", + "isOnlyRegistering": false, + "prefilledVariables": { + "number": number, + "pushName": msg.pushName || "" + }, + }); + + const config = { + method: 'post', + maxBodyLength: Infinity, + url: `${url}/api/v1/typebots/${typebotSlug}/startChat`, + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }, + data: reqData + }; + + const request = await axios.request(config); + + return request.data; + + } catch (err) { + logger.info("Erro ao criar sessão do typebot: ", err) + throw err; + } + } + + + let sessionId + let dataStart + let status = false; + try { + const dataLimite = new Date() + dataLimite.setMinutes(dataLimite.getMinutes() - Number(typebotExpires)); + + + if (typebotExpires > 0 && ticket.updatedAt < dataLimite) { + await ticket.update({ + typebotSessionId: null, + isBot: true + }); + + await ticket.reload(); + } + + if (isNil(ticket.typebotSessionId)) { + dataStart = await createSession(msg, typebot, number); + sessionId = dataStart.sessionId + status = true; + await ticket.update({ + typebotSessionId: sessionId, + typebotStatus: true, + useIntegration: true, + integrationId: typebot.id + }) + } else { + sessionId = ticket.typebotSessionId; + status = ticket.typebotStatus; + } + + if (!status) return; + + //let body = getConversationMessage(msg); + + + if (body !== typebotKeywordFinish && body !== typebotKeywordRestart) { + let requestContinue + let messages + let input + if (dataStart?.messages.length === 0 || dataStart === undefined) { + const reqData = JSON.stringify({ + "message": body + }); + + let config = { + method: 'post', + maxBodyLength: Infinity, + url: `${url}/api/v1/sessions/${sessionId}/continueChat`, + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }, + data: reqData + }; + requestContinue = await axios.request(config); + messages = requestContinue.data?.messages; + input = requestContinue.data?.input; + } else { + messages = dataStart?.messages; + input = dataStart?.input; + } + + if (messages?.length === 0) { + await wbot.sendMessage(`${number}@c.us`, { text: typebotUnknownMessage }); + } else { + for (const message of messages) { + if (message.type === 'text') { + let formattedText = ''; + let linkPreview = false; + for (const richText of message.content.richText) { + for (const element of richText.children) { + let text = ''; + + if (element.text) { + text = element.text; + } + if (element.type && element.children) { + for (const subelement of element.children) { + let text = ''; + + if (subelement.text) { + text = subelement.text; + } + + if (subelement.type && subelement.children) { + for (const subelement2 of subelement.children) { + let text = ''; + + if (subelement2.text) { + text = subelement2.text; + } + + if (subelement2.bold) { + text = `*${text}*`; + } + if (subelement2.italic) { + text = `_${text}_`; + } + if (subelement2.underline) { + text = `~${text}~`; + } + if (subelement2.url) { + const linkText = subelement2.children[0].text; + text = `[${linkText}](${subelement2.url})`; + linkPreview = true; + } + formattedText += text; + } + } + if (subelement.bold) { + text = `*${text}*`; + } + if (subelement.italic) { + text = `_${text}_`; + } + if (subelement.underline) { + text = `~${text}~`; + } + if (subelement.url) { + const linkText = subelement.children[0].text; + text = `[${linkText}](${subelement.url})`; + linkPreview = true; + } + formattedText += text; + } + } + + if (element.bold) { + text = `*${text}*` + } + if (element.italic) { + text = `_${text}_`; + } + if (element.underline) { + text = `~${text}~`; + } + + if (element.url) { + const linkText = element.children[0].text; + text = `[${linkText}](${element.url})`; + linkPreview = true; + } + + formattedText += text; + } + formattedText += '\n'; + } + formattedText = formattedText.replace('**', '').replace(/\n$/, ''); + + if (formattedText === "Invalid message. Please, try again.") { + formattedText = typebotUnknownMessage; + } + + if (formattedText.startsWith("#")) { + let gatilho = formattedText.replace("#", ""); + + try { + let jsonGatilho = JSON.parse(gatilho); + + if (jsonGatilho.stopBot && isNil(jsonGatilho.userId) && isNil(jsonGatilho.queueId)) { + await ticket.update({ + useIntegration: false, + isBot: false + }) + + return; + } + if (!isNil(jsonGatilho.queueId) && jsonGatilho.queueId > 0 && isNil(jsonGatilho.userId)) { + await UpdateTicketService({ + ticketData: { + queueId: jsonGatilho.queueId, + chatbot: false, + useIntegration: false, + integrationId: null + }, + ticketId: ticket.id, + companyId: ticket.companyId + }) + + return; + } + + if (!isNil(jsonGatilho.queueId) && jsonGatilho.queueId > 0 && !isNil(jsonGatilho.userId) && jsonGatilho.userId > 0) { + await UpdateTicketService({ + ticketData: { + queueId: jsonGatilho.queueId, + userId: jsonGatilho.userId, + chatbot: false, + useIntegration: false, + integrationId: null + }, + ticketId: ticket.id, + companyId: ticket.companyId + }) + + return; + } + } catch (err) { + throw err + } + } + + await wbot.presenceSubscribe(msg.key.remoteJid) + //await delay(2000) + await wbot.sendPresenceUpdate('composing', msg.key.remoteJid) + await delay(typebotDelayMessage) + await wbot.sendPresenceUpdate('paused', msg.key.remoteJid) + + + await wbot.sendMessage(msg.key.remoteJid, { text: formattedText }); + } + + if (message.type === 'audio') { + await wbot.presenceSubscribe(msg.key.remoteJid) + //await delay(2000) + await wbot.sendPresenceUpdate('composing', msg.key.remoteJid) + await delay(typebotDelayMessage) + await wbot.sendPresenceUpdate('paused', msg.key.remoteJid) + const media = { + audio: { + url: message.content.url, + mimetype: 'audio/mp4', + ptt: true + }, + } + await wbot.sendMessage(msg.key.remoteJid, media); + + } + + // if (message.type === 'embed') { + // await wbot.presenceSubscribe(msg.key.remoteJid) + // //await delay(2000) + // await wbot.sendPresenceUpdate('composing', msg.key.remoteJid) + // await delay(typebotDelayMessage) + // await wbot.sendPresenceUpdate('paused', msg.key.remoteJid) + // const media = { + + // document: { url: message.content.url }, + // mimetype: 'application/pdf', + // caption: "" + + // } + // await wbot.sendMessage(msg.key.remoteJid, media); + // } + + if (message.type === 'image') { + await wbot.presenceSubscribe(msg.key.remoteJid) + //await delay(2000) + await wbot.sendPresenceUpdate('composing', msg.key.remoteJid) + await delay(typebotDelayMessage) + await wbot.sendPresenceUpdate('paused', msg.key.remoteJid) + const media = { + image: { + url: message.content.url, + }, + + } + await wbot.sendMessage(msg.key.remoteJid, media); + } + + // if (message.type === 'video' ) { + // await wbot.presenceSubscribe(msg.key.remoteJid) + // //await delay(2000) + // await wbot.sendPresenceUpdate('composing', msg.key.remoteJid) + // await delay(typebotDelayMessage) + // await wbot.sendPresenceUpdate('paused', msg.key.remoteJid) + // const media = { + // video: { + // url: message.content.url, + // }, + + // } + // await wbot.sendMessage(msg.key.remoteJid, media); + // } + } + if (input) { + if (input.type === 'choice input') { + let formattedText = ''; + const items = input.items; + for (const item of items) { + formattedText += `▶️ ${item.content}\n`; + } + formattedText = formattedText.replace(/\n$/, ''); + await wbot.presenceSubscribe(msg.key.remoteJid) + //await delay(2000) + await wbot.sendPresenceUpdate('composing', msg.key.remoteJid) + await delay(typebotDelayMessage) + await wbot.sendPresenceUpdate('paused', msg.key.remoteJid) + await wbot.sendMessage(msg.key.remoteJid, { text: formattedText }); + + } + } + } + } + if (body === typebotKeywordRestart) { + await ticket.update({ + isBot: true, + typebotSessionId: null + + }) + + await ticket.reload(); + + await wbot.sendMessage(`${number}@c.us`, { text: typebotRestartMessage }) + + } + if (body === typebotKeywordFinish) { + await UpdateTicketService({ + ticketData: { + status: "closed", + useIntegration: false, + integrationId: null + }, + ticketId: ticket.id, + companyId: ticket.companyId + }) + + return; + } + } catch (error) { + logger.info("Error on typebotListener: ", error); + await ticket.update({ + typebotSessionId: null + }) + throw error; + } +} + +export default typebotListener; diff --git a/backend/src/services/UserServices/AuthUserService.ts b/backend/src/services/UserServices/AuthUserService.ts new file mode 100644 index 0000000..463adb4 --- /dev/null +++ b/backend/src/services/UserServices/AuthUserService.ts @@ -0,0 +1,61 @@ +import User from "../../models/User"; +import AppError from "../../errors/AppError"; +import { + createAccessToken, + createRefreshToken +} from "../../helpers/CreateTokens"; +import { SerializeUser } from "../../helpers/SerializeUser"; +import Queue from "../../models/Queue"; +import Company from "../../models/Company"; +import Setting from "../../models/Setting"; + +interface SerializedUser { + id: number; + name: string; + email: string; + profile: string; + queues: Queue[]; + companyId: number; +} + +interface Request { + email: string; + password: string; +} + +interface Response { + serializedUser: SerializedUser; + token: string; + refreshToken: string; +} + +const AuthUserService = async ({ + email, + password +}: Request): Promise => { + const user = await User.findOne({ + where: { email }, + include: ["queues", { model: Company, include: [{ model: Setting }] }] + }); + + if (!user) { + throw new AppError("ERR_INVALID_CREDENTIALS", 401); + } + + if (!(await user.checkPassword(password))) { + throw new AppError("ERR_INVALID_CREDENTIALS", 401); + } + + const token = createAccessToken(user); + const refreshToken = createRefreshToken(user); + + const serializedUser = await SerializeUser(user); + + return { + serializedUser, + token, + refreshToken + }; +}; + +export default AuthUserService; diff --git a/backend/src/services/UserServices/CreateUserService.ts b/backend/src/services/UserServices/CreateUserService.ts new file mode 100644 index 0000000..273cd23 --- /dev/null +++ b/backend/src/services/UserServices/CreateUserService.ts @@ -0,0 +1,107 @@ +import * as Yup from "yup"; + +import AppError from "../../errors/AppError"; +import { SerializeUser } from "../../helpers/SerializeUser"; +import User from "../../models/User"; +import Plan from "../../models/Plan"; +import Company from "../../models/Company"; + +interface Request { + email: string; + password: string; + name: string; + queueIds?: number[]; + companyId?: number; + profile?: string; + whatsappId?: number; + allTicket?:string; +} + +interface Response { + email: string; + name: string; + id: number; + profile: string; +} + +const CreateUserService = async ({ + email, + password, + name, + queueIds = [], + companyId, + profile = "admin", + whatsappId, + allTicket +}: Request): Promise => { + if (companyId !== undefined) { + const company = await Company.findOne({ + where: { + id: companyId + }, + include: [{ model: Plan, as: "plan" }] + }); + + if (company !== null) { + const usersCount = await User.count({ + where: { + companyId + } + }); + + if (usersCount >= company.plan.users) { + throw new AppError( + `Número máximo de usuários já alcançado: ${usersCount}` + ); + } + } + } + + const schema = Yup.object().shape({ + name: Yup.string().required().min(2), + email: Yup.string() + .email() + .required() + .test( + "Check-email", + "An user with this email already exists.", + async value => { + if (!value) return false; + const emailExists = await User.findOne({ + where: { email: value } + }); + return !emailExists; + } + ), + password: Yup.string().required().min(5) + }); + + try { + await schema.validate({ email, password, name }); + } catch (err) { + throw new AppError(err.message); + } + + const user = await User.create( + { + email, + password, + name, + companyId, + profile, + whatsappId: whatsappId || null, + allTicket + }, + { include: ["queues", "company"] } + ); + + await user.$set("queues", queueIds); + + await user.reload(); + + const serializedUser = SerializeUser(user); + + return serializedUser; +}; + +export default CreateUserService; diff --git a/backend/src/services/UserServices/DeleteUserService.ts b/backend/src/services/UserServices/DeleteUserService.ts new file mode 100644 index 0000000..96a9a79 --- /dev/null +++ b/backend/src/services/UserServices/DeleteUserService.ts @@ -0,0 +1,29 @@ +import User from "../../models/User"; +import AppError from "../../errors/AppError"; +import Ticket from "../../models/Ticket"; +import UpdateDeletedUserOpenTicketsStatus from "../../helpers/UpdateDeletedUserOpenTicketsStatus"; + +const DeleteUserService = async ( + id: string | number, + companyId: number +): Promise => { + const user = await User.findOne({ + where: { id } + }); + + if (!user) { + throw new AppError("ERR_NO_USER_FOUND", 404); + } + + const userOpenTickets: Ticket[] = await user.$get("tickets", { + where: { status: "open" } + }); + + if (userOpenTickets.length > 0) { + UpdateDeletedUserOpenTicketsStatus(userOpenTickets, companyId); + } + + await user.destroy(); +}; + +export default DeleteUserService; diff --git a/backend/src/services/UserServices/ListUsersService.ts b/backend/src/services/UserServices/ListUsersService.ts new file mode 100644 index 0000000..51b43f7 --- /dev/null +++ b/backend/src/services/UserServices/ListUsersService.ts @@ -0,0 +1,64 @@ +import { Sequelize, Op } from "sequelize"; +import Queue from "../../models/Queue"; +import Company from "../../models/Company"; +import User from "../../models/User"; + +interface Request { + searchParam?: string; + pageNumber?: string | number; + profile?: string; + companyId?: number; +} + +interface Response { + users: User[]; + count: number; + hasMore: boolean; +} + +const ListUsersService = async ({ + searchParam = "", + pageNumber = "1", + companyId +}: Request): Promise => { + const whereCondition = { + [Op.or]: [ + { + "$User.name$": Sequelize.where( + Sequelize.fn("LOWER", Sequelize.col("User.name")), + "LIKE", + `%${searchParam.toLowerCase()}%` + ) + }, + { email: { [Op.like]: `%${searchParam.toLowerCase()}%` } } + ], + companyId: { + [Op.eq]: companyId + } + }; + + const limit = 20; + const offset = limit * (+pageNumber - 1); + + const { count, rows: users } = await User.findAndCountAll({ + where: whereCondition, + attributes: ["name", "id", "email", "companyId", "profile", "createdAt"], + limit, + offset, + order: [["createdAt", "DESC"]], + include: [ + { model: Queue, as: "queues", attributes: ["id", "name", "color"] }, + { model: Company, as: "company", attributes: ["id", "name"] } + ] + }); + + const hasMore = count > offset + users.length; + + return { + users, + count, + hasMore + }; +}; + +export default ListUsersService; diff --git a/backend/src/services/UserServices/ShowUserService.ts b/backend/src/services/UserServices/ShowUserService.ts new file mode 100644 index 0000000..0634491 --- /dev/null +++ b/backend/src/services/UserServices/ShowUserService.ts @@ -0,0 +1,32 @@ +import User from "../../models/User"; +import AppError from "../../errors/AppError"; +import Queue from "../../models/Queue"; +import Company from "../../models/Company"; + +const ShowUserService = async (id: string | number): Promise => { + const user = await User.findByPk(id, { + attributes: [ + "name", + "id", + "email", + "companyId", + "profile", + "super", + "tokenVersion", + "whatsappId", + "allTicket" + ], + include: [ + { model: Queue, as: "queues", attributes: ["id", "name", "color"] }, + { model: Company, as: "company", attributes: ["id", "name"] } + ] + }); + + if (!user) { + throw new AppError("ERR_NO_USER_FOUND", 404); + } + + return user; +}; + +export default ShowUserService; diff --git a/backend/src/services/UserServices/SimpleListService.ts b/backend/src/services/UserServices/SimpleListService.ts new file mode 100644 index 0000000..a484d4f --- /dev/null +++ b/backend/src/services/UserServices/SimpleListService.ts @@ -0,0 +1,28 @@ +import User from "../../models/User"; +import AppError from "../../errors/AppError"; +import Queue from "../../models/Queue"; + +interface Params { + companyId: string | number; +} + +const SimpleListService = async ({ companyId }: Params): Promise => { + const users = await User.findAll({ + where: { + companyId + }, + attributes: ["name", "id", "email"], + include: [ + { model: Queue, as: 'queues' } + ], + order: [["id", "ASC"]] + }); + + if (!users) { + throw new AppError("ERR_NO_USER_FOUND", 404); + } + + return users; +}; + +export default SimpleListService; diff --git a/backend/src/services/UserServices/UpdateUserService.ts b/backend/src/services/UserServices/UpdateUserService.ts new file mode 100644 index 0000000..9f05829 --- /dev/null +++ b/backend/src/services/UserServices/UpdateUserService.ts @@ -0,0 +1,91 @@ +import * as Yup from "yup"; + +import AppError from "../../errors/AppError"; +import ShowUserService from "./ShowUserService"; +import Company from "../../models/Company"; +import User from "../../models/User"; + +interface UserData { + email?: string; + password?: string; + name?: string; + profile?: string; + companyId?: number; + queueIds?: number[]; + whatsappId?: number; + allTicket?: string; +} + +interface Request { + userData: UserData; + userId: string | number; + companyId: number; + requestUserId: number; +} + +interface Response { + id: number; + name: string; + email: string; + profile: string; +} + +const UpdateUserService = async ({ + userData, + userId, + companyId, + requestUserId +}: Request): Promise => { + const user = await ShowUserService(userId); + + const requestUser = await User.findByPk(requestUserId); + + if (requestUser.super === false && userData.companyId !== companyId) { + throw new AppError("O usuário não pertence à esta empresa"); + } + + const schema = Yup.object().shape({ + name: Yup.string().min(2), + email: Yup.string().email(), + profile: Yup.string(), + password: Yup.string(), + allTicket: Yup.string() + }); + + const { email, password, profile, name, queueIds = [], whatsappId, allTicket } = userData; + + try { + await schema.validate({ email, password, profile, name, allTicket }); + } catch (err: any) { + throw new AppError(err.message); + } + + await user.update({ + email, + password, + profile, + name, + whatsappId: whatsappId || null, + allTicket + }); + + await user.$set("queues", queueIds); + + await user.reload(); + + const company = await Company.findByPk(user.companyId); + + const serializedUser = { + id: user.id, + name: user.name, + email: user.email, + profile: user.profile, + companyId: user.companyId, + company, + queues: user.queues + }; + + return serializedUser; +}; + +export default UpdateUserService; diff --git a/backend/src/services/WbotServices/CheckIsValidContact.ts b/backend/src/services/WbotServices/CheckIsValidContact.ts new file mode 100644 index 0000000..1b567b0 --- /dev/null +++ b/backend/src/services/WbotServices/CheckIsValidContact.ts @@ -0,0 +1,26 @@ +import AppError from "../../errors/AppError"; +import GetDefaultWhatsApp from "../../helpers/GetDefaultWhatsApp"; +import { getWbot } from "../../libs/wbot"; + +const CheckIsValidContact = async ( + number: string, + companyId: number +): Promise => { + const defaultWhatsapp = await GetDefaultWhatsApp(companyId); + + const wbot = getWbot(defaultWhatsapp.id); + + try { + const isValidNumber = await wbot.onWhatsApp(`${number}`); + if (!isValidNumber) { + throw new AppError("invalidNumber"); + } + } catch (err: any) { + if (err.message === "invalidNumber") { + throw new AppError("ERR_WAPP_INVALID_CONTACT"); + } + throw new AppError("ERR_WAPP_CHECK_CONTACT"); + } +}; + +export default CheckIsValidContact; diff --git a/backend/src/services/WbotServices/CheckNumber.ts b/backend/src/services/WbotServices/CheckNumber.ts new file mode 100644 index 0000000..be4ecef --- /dev/null +++ b/backend/src/services/WbotServices/CheckNumber.ts @@ -0,0 +1,29 @@ +import GetDefaultWhatsApp from "../../helpers/GetDefaultWhatsApp"; +import { getWbot } from "../../libs/wbot"; + +interface IOnWhatsapp { + jid: string; + exists: boolean; +} + +const checker = async (number: string, wbot: any) => { + const [validNumber] = await wbot.onWhatsApp(`${number}@s.whatsapp.net`); + return validNumber; +}; + +const CheckContactNumber = async ( + number: string, + companyId: number +): Promise => { + const defaultWhatsapp = await GetDefaultWhatsApp(companyId); + + const wbot = getWbot(defaultWhatsapp.id); + const isNumberExit = await checker(number, wbot); + + if (!isNumberExit.exists) { + throw new Error("ERR_CHECK_NUMBER"); + } + return isNumberExit; +}; + +export default CheckContactNumber; diff --git a/backend/src/services/WbotServices/DeleteWhatsAppMessage.ts b/backend/src/services/WbotServices/DeleteWhatsAppMessage.ts new file mode 100644 index 0000000..6c9497a --- /dev/null +++ b/backend/src/services/WbotServices/DeleteWhatsAppMessage.ts @@ -0,0 +1,51 @@ +import { proto, WASocket } from "@whiskeysockets/baileys"; +import WALegacySocket from "@whiskeysockets/baileys" +import AppError from "../../errors/AppError"; +import GetTicketWbot from "../../helpers/GetTicketWbot"; +import GetWbotMessage from "../../helpers/GetWbotMessage"; +import Message from "../../models/Message"; +import Ticket from "../../models/Ticket"; + +const DeleteWhatsAppMessage = async (messageId: string): Promise => { + const message = await Message.findByPk(messageId, { + include: [ + { + model: Ticket, + as: "ticket", + include: ["contact"] + } + ] + }); + + if (!message) { + throw new AppError("No message found with this ID."); + } + + const { ticket } = message; + + const messageToDelete = await GetWbotMessage(ticket, messageId); + + try { + const wbot = await GetTicketWbot(ticket); + const messageDelete = messageToDelete as proto.WebMessageInfo; + + const menssageDelete = messageToDelete as Message; + + await (wbot as WASocket).sendMessage(menssageDelete.remoteJid, { + delete: { + id: menssageDelete.id, + remoteJid: menssageDelete.remoteJid, + participant: menssageDelete.participant, + fromMe: menssageDelete.fromMe + } + }); + + } catch (err) { + throw new AppError("ERR_DELETE_WAPP_MSG"); + } + await message.update({ isDeleted: true }); + + return message; +}; + +export default DeleteWhatsAppMessage; diff --git a/backend/src/services/WbotServices/GetProfilePicUrl.ts b/backend/src/services/WbotServices/GetProfilePicUrl.ts new file mode 100644 index 0000000..4ae0fa9 --- /dev/null +++ b/backend/src/services/WbotServices/GetProfilePicUrl.ts @@ -0,0 +1,22 @@ +import GetDefaultWhatsApp from "../../helpers/GetDefaultWhatsApp"; +import { getWbot } from "../../libs/wbot"; + +const GetProfilePicUrl = async ( + number: string, + companyId: number +): Promise => { + const defaultWhatsapp = await GetDefaultWhatsApp(companyId); + + const wbot = getWbot(defaultWhatsapp.id); + + let profilePicUrl: string; + try { + profilePicUrl = await wbot.profilePictureUrl(`${number}@s.whatsapp.net`); + } catch (error) { + profilePicUrl = `${process.env.FRONTEND_URL}/nopicture.png`; + } + + return profilePicUrl; +}; + +export default GetProfilePicUrl; diff --git a/backend/src/services/WbotServices/ImportContactsService.ts b/backend/src/services/WbotServices/ImportContactsService.ts new file mode 100644 index 0000000..eb9f168 --- /dev/null +++ b/backend/src/services/WbotServices/ImportContactsService.ts @@ -0,0 +1,82 @@ +import * as Sentry from "@sentry/node"; +import GetDefaultWhatsApp from "../../helpers/GetDefaultWhatsApp"; +import { getWbot } from "../../libs/wbot"; +import Contact from "../../models/Contact"; +import { logger } from "../../utils/logger"; +import ShowBaileysService from "../BaileysServices/ShowBaileysService"; +import CreateContactService from "../ContactServices/CreateContactService"; +import { isString, isArray } from "lodash"; +import path from "path"; +import fs from 'fs'; + +const ImportContactsService = async (companyId: number): Promise => { + const defaultWhatsapp = await GetDefaultWhatsApp(companyId); + const wbot = getWbot(defaultWhatsapp.id); + + let phoneContacts; + + try { + const contactsString = await ShowBaileysService(wbot.id); + phoneContacts = JSON.parse(JSON.stringify(contactsString.contacts)); + + const publicFolder = path.resolve(__dirname, "..", "..", "..", "public"); + const beforeFilePath = path.join(publicFolder, 'contatos_antes.txt'); + fs.writeFile(beforeFilePath, JSON.stringify(phoneContacts, null, 2), (err) => { + if (err) { + logger.error(`Failed to write contacts to file: ${err}`); + throw err; + } + console.log('O arquivo contatos_antes.txt foi criado!'); + }); + + } catch (err) { + Sentry.captureException(err); + logger.error(`Could not get whatsapp contacts from phone. Err: ${err}`); + } + + const publicFolder = path.resolve(__dirname, "..", "..", "..", "public"); + const afterFilePath = path.join(publicFolder, 'contatos_depois.txt'); + fs.writeFile(afterFilePath, JSON.stringify(phoneContacts, null, 2), (err) => { + if (err) { + logger.error(`Failed to write contacts to file: ${err}`); + throw err; + } + }); + + const phoneContactsList = isString(phoneContacts) + ? JSON.parse(phoneContacts) + : phoneContacts; + + if (isArray(phoneContactsList)) { + phoneContactsList.forEach(async ({ id, name, notify }) => { + if (id === "status@broadcast" || id.includes("g.us")) return; + const number = id.replace(/\D/g, ""); + + const existingContact = await Contact.findOne({ + where: { number, companyId } + }); + + if (existingContact) { + // Atualiza o nome do contato existente + existingContact.name = name || notify; + await existingContact.save(); + } else { + // Criar um novo contato + try { + await CreateContactService({ + number, + name: name || notify, + companyId + }); + } catch (error) { + Sentry.captureException(error); + logger.warn( + `Could not get whatsapp contacts from phone. Err: ${error}` + ); + } + } + }); + } +}; + +export default ImportContactsService; diff --git a/backend/src/services/WbotServices/SendWhatsAppMedia.ts b/backend/src/services/WbotServices/SendWhatsAppMedia.ts new file mode 100644 index 0000000..ff6f28b --- /dev/null +++ b/backend/src/services/WbotServices/SendWhatsAppMedia.ts @@ -0,0 +1,191 @@ +import { WAMessage, AnyMessageContent } from "@whiskeysockets/baileys"; +import * as Sentry from "@sentry/node"; +import fs from "fs"; +import { exec } from "child_process"; +import path from "path"; +import ffmpegPath from "@ffmpeg-installer/ffmpeg"; +import AppError from "../../errors/AppError"; +import GetTicketWbot from "../../helpers/GetTicketWbot"; +import Ticket from "../../models/Ticket"; +import mime from "mime-types"; +import formatBody from "../../helpers/Mustache"; + +interface Request { + media: Express.Multer.File; + ticket: Ticket; + body?: string; +} + +const publicFolder = path.resolve(__dirname, "..", "..", "..", "public"); + +const processAudio = async (audio: string): Promise => { + const outputAudio = `${publicFolder}/${new Date().getTime()}.mp3`; + return new Promise((resolve, reject) => { + exec( + `${ffmpegPath.path} -i ${audio} -vn -ab 128k -ar 44100 -f ipod ${outputAudio} -y`, + (error, _stdout, _stderr) => { + if (error) reject(error); + fs.unlinkSync(audio); + resolve(outputAudio); + } + ); + }); +}; + +const processAudioFile = async (audio: string): Promise => { + const outputAudio = `${publicFolder}/${new Date().getTime()}.mp3`; + return new Promise((resolve, reject) => { + exec( + `${ffmpegPath.path} -i ${audio} -vn -ar 44100 -ac 2 -b:a 192k ${outputAudio}`, + (error, _stdout, _stderr) => { + if (error) reject(error); + fs.unlinkSync(audio); + resolve(outputAudio); + } + ); + }); +}; + +export const getMessageOptions = async ( + fileName: string, + pathMedia: string, + body?: string +): Promise => { + const mimeType = mime.lookup(pathMedia); + const typeMessage = mimeType.split("/")[0]; + + try { + if (!mimeType) { + throw new Error("Invalid mimetype"); + } + let options: AnyMessageContent; + + if (typeMessage === "video") { + options = { + video: fs.readFileSync(pathMedia), + caption: body ? body : '', + fileName: fileName + // gifPlayback: true + }; + } else if (typeMessage === "audio") { + const typeAudio = true; //fileName.includes("audio-record-site"); + const convert = await processAudio(pathMedia); + if (typeAudio) { + options = { + audio: fs.readFileSync(convert), + mimetype: typeAudio ? "audio/mp4" : mimeType, + caption: body ? body : null, + ptt: true + }; + } else { + options = { + audio: fs.readFileSync(convert), + mimetype: typeAudio ? "audio/mp4" : mimeType, + caption: body ? body : null, + ptt: true + }; + } + } else if (typeMessage === "document") { + options = { + document: fs.readFileSync(pathMedia), + caption: body ? body : null, + fileName: fileName, + mimetype: mimeType + }; + } else if (typeMessage === "application") { + options = { + document: fs.readFileSync(pathMedia), + caption: body ? body : null, + fileName: fileName, + mimetype: mimeType + }; + } else { + options = { + image: fs.readFileSync(pathMedia), + caption: body ? body : null + }; + } + + return options; + } catch (e) { + Sentry.captureException(e); + console.log(e); + return null; + } +}; + +const SendWhatsAppMedia = async ({ + media, + ticket, + body +}: Request): Promise => { + try { + const wbot = await GetTicketWbot(ticket); + + const pathMedia = media.path; + const typeMessage = media.mimetype.split("/")[0]; + let options: AnyMessageContent; + const bodyMessage = formatBody(body, ticket.contact) + + if (typeMessage === "video") { + options = { + video: fs.readFileSync(pathMedia), + caption: bodyMessage, + fileName: media.originalname + // gifPlayback: true + }; + } else if (typeMessage === "audio") { + const typeAudio = media.originalname.includes("audio-record-site"); + if (typeAudio) { + const convert = await processAudio(media.path); + options = { + audio: fs.readFileSync(convert), + mimetype: typeAudio ? "audio/mp4" : media.mimetype, + ptt: true + }; + } else { + const convert = await processAudioFile(media.path); + options = { + audio: fs.readFileSync(convert), + mimetype: typeAudio ? "audio/mp4" : media.mimetype + }; + } + } else if (typeMessage === "document" || typeMessage === "text") { + options = { + document: fs.readFileSync(pathMedia), + caption: bodyMessage, + fileName: media.originalname, + mimetype: media.mimetype + }; + } else if (typeMessage === "application") { + options = { + document: fs.readFileSync(pathMedia), + caption: bodyMessage, + fileName: media.originalname, + mimetype: media.mimetype + }; + } else { + options = { + image: fs.readFileSync(pathMedia), + caption: bodyMessage, + }; + } + + const sentMessage = await wbot.sendMessage( + `${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, + { + ...options + } + ); + + await ticket.update({ lastMessage: bodyMessage }); + + return sentMessage; + } catch (err) { + Sentry.captureException(err); + console.log(err); + throw new AppError("ERR_SENDING_WAPP_MSG"); + } +}; + +export default SendWhatsAppMedia; diff --git a/backend/src/services/WbotServices/SendWhatsAppMessage.ts b/backend/src/services/WbotServices/SendWhatsAppMessage.ts new file mode 100644 index 0000000..c770c42 --- /dev/null +++ b/backend/src/services/WbotServices/SendWhatsAppMessage.ts @@ -0,0 +1,66 @@ +import { WAMessage } from "@whiskeysockets/baileys"; +import WALegacySocket from "@whiskeysockets/baileys" +import * as Sentry from "@sentry/node"; +import AppError from "../../errors/AppError"; +import GetTicketWbot from "../../helpers/GetTicketWbot"; +import Message from "../../models/Message"; +import Ticket from "../../models/Ticket"; + +import formatBody from "../../helpers/Mustache"; + +interface Request { + body: string; + ticket: Ticket; + quotedMsg?: Message; +} + +const SendWhatsAppMessage = async ({ + body, + ticket, + quotedMsg +}: Request): Promise => { + let options = {}; + const wbot = await GetTicketWbot(ticket); + const number = `${ticket.contact.number}@${ + ticket.isGroup ? "g.us" : "s.whatsapp.net" + }`; + if (quotedMsg) { + const chatMessages = await Message.findOne({ + where: { + id: quotedMsg.id + } + }); + + if (chatMessages) { + const msgFound = JSON.parse(chatMessages.dataJson); + + options = { + quoted: { + key: msgFound.key, + message: { + extendedTextMessage: msgFound.message.extendedTextMessage + } + } + }; + } + + } + + try { + const sentMessage = await wbot.sendMessage(number,{ + text: formatBody(body, ticket.contact) + }, + { + ...options + } + ); + await ticket.update({ lastMessage: formatBody(body, ticket.contact) }); + return sentMessage; + } catch (err) { + Sentry.captureException(err); + console.log(err); + throw new AppError("ERR_SENDING_WAPP_MSG"); + } +}; + +export default SendWhatsAppMessage; diff --git a/backend/src/services/WbotServices/StartAllWhatsAppsSessions.ts b/backend/src/services/WbotServices/StartAllWhatsAppsSessions.ts new file mode 100644 index 0000000..913509f --- /dev/null +++ b/backend/src/services/WbotServices/StartAllWhatsAppsSessions.ts @@ -0,0 +1,18 @@ +import ListWhatsAppsService from "../WhatsappService/ListWhatsAppsService"; +import { StartWhatsAppSession } from "./StartWhatsAppSession"; +import * as Sentry from "@sentry/node"; + +export const StartAllWhatsAppsSessions = async ( + companyId: number +): Promise => { + try { + const whatsapps = await ListWhatsAppsService({ companyId }); + if (whatsapps.length > 0) { + whatsapps.forEach(whatsapp => { + StartWhatsAppSession(whatsapp, companyId); + }); + } + } catch (e) { + Sentry.captureException(e); + } +}; diff --git a/backend/src/services/WbotServices/StartWhatsAppSession.ts b/backend/src/services/WbotServices/StartWhatsAppSession.ts new file mode 100644 index 0000000..ad08cb0 --- /dev/null +++ b/backend/src/services/WbotServices/StartWhatsAppSession.ts @@ -0,0 +1,29 @@ +import { initWASocket } from "../../libs/wbot"; +import Whatsapp from "../../models/Whatsapp"; +import { wbotMessageListener } from "./wbotMessageListener"; +import { getIO } from "../../libs/socket"; +import wbotMonitor from "./wbotMonitor"; +import { logger } from "../../utils/logger"; +import * as Sentry from "@sentry/node"; + +export const StartWhatsAppSession = async ( + whatsapp: Whatsapp, + companyId: number +): Promise => { + await whatsapp.update({ status: "OPENING" }); + + const io = getIO(); + io.to(`company-${whatsapp.companyId}-mainchannel`).emit("whatsappSession", { + action: "update", + session: whatsapp + }); + + try { + const wbot = await initWASocket(whatsapp); + wbotMessageListener(wbot, companyId); + wbotMonitor(wbot, whatsapp, companyId); + } catch (err) { + Sentry.captureException(err); + logger.error(err); + } +}; diff --git a/backend/src/services/WbotServices/providers.ts b/backend/src/services/WbotServices/providers.ts new file mode 100644 index 0000000..b8ee4c0 --- /dev/null +++ b/backend/src/services/WbotServices/providers.ts @@ -0,0 +1,1527 @@ +import { proto, WASocket } from "@whiskeysockets/baileys"; +import Contact from "../../models/Contact"; +import Setting from "../../models/Setting"; +import Ticket from "../../models/Ticket"; +import { getBodyMessage, isNumeric, sleep, validaCpfCnpj, sendMessageImage, sendMessageLink, makeid } from "./wbotMessageListener"; +import formatBody from "../../helpers/Mustache"; + +import puppeteer from "puppeteer"; + +import axios from 'axios'; +import UpdateTicketService from "../TicketServices/UpdateTicketService"; +import fs from 'fs'; + +export const provider = async (ticket: Ticket, msg: proto.IWebMessageInfo, companyId: number, contact: Contact, wbot: WASocket) => { + const filaescolhida = ticket.queue?.name + if (filaescolhida === "2ª Via de Boleto" || filaescolhida === "2 Via de Boleto") { + let cpfcnpj + cpfcnpj = getBodyMessage(msg); + cpfcnpj = cpfcnpj.replace(/\./g, ''); + cpfcnpj = cpfcnpj.replace('-', '') + cpfcnpj = cpfcnpj.replace('/', '') + cpfcnpj = cpfcnpj.replace(' ', '') + cpfcnpj = cpfcnpj.replace(',', '') + + const asaastoken = await Setting.findOne({ + where: { + key: "asaas", + companyId + } + }); + const ixcapikey = await Setting.findOne({ + where: { + key: "tokenixc", + companyId + } + }); + const urlixcdb = await Setting.findOne({ + where: { + key: "ipixc", + companyId + } + }); + const ipmkauth = await Setting.findOne({ + where: { + key: "ipmkauth", + companyId + } + }); + const clientidmkauth = await Setting.findOne({ + where: { + key: "clientidmkauth", + companyId + } + }); + const clientesecretmkauth = await Setting.findOne({ + where: { + key: "clientsecretmkauth", + companyId + } + }); + + let urlmkauth = ipmkauth.value + if (urlmkauth.substr(-1) === '/') { + urlmkauth = urlmkauth.slice(0, -1); + } + + //VARS + let url = `${urlmkauth}/api/`; + const Client_Id = clientidmkauth.value + const Client_Secret = clientesecretmkauth.value + const ixckeybase64 = btoa(ixcapikey.value); + const urlixc = urlixcdb.value + const asaastk = asaastoken.value + + const cnpj_cpf = getBodyMessage(msg); + let numberCPFCNPJ = cpfcnpj; + + if (urlmkauth != "" && Client_Id != "" && Client_Secret != "") { + if (isNumeric(numberCPFCNPJ) === true) { + if (cpfcnpj.length > 2) { + const isCPFCNPJ = validaCpfCnpj(numberCPFCNPJ) + if (isCPFCNPJ) { + const textMessage = { + text: formatBody(`Aguarde! Estamos consultando na base de dados!`, contact), + }; + try { + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, textMessage); + } catch (error) { + + } + + + axios({ + rejectUnauthorized: true, + method: 'get', + url, + auth: { + username: Client_Id, + password: Client_Secret + } + } as any) + .then(function (response) { + const jtw = response.data + var config = { + method: 'GET', + url: `${urlmkauth}/api/cliente/show/${numberCPFCNPJ}`, + headers: { + Authorization: `Bearer ${jtw}` + } + }; + axios.request(config as any) + .then(async function (response) { + if (response.data == 'NULL') { + const textMessage = { + text: formatBody(`Cadastro não localizado! *CPF/CNPJ* incorreto ou inválido. Tenta novamente!`, contact), + }; + try { + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, textMessage); + } catch (error) { + console.log('Não consegui enviar a mensagem!') + } + } else { + let nome + let cpf_cnpj + let qrcode + let valor + let bloqueado + let linhadig + let uuid_cliente + let referencia + let status + let datavenc + let descricao + let titulo + let statusCorrigido + let valorCorrigido + + nome = response.data.dados_cliente.titulos.nome + cpf_cnpj = response.data.dados_cliente.titulos.cpf_cnpj + valor = response.data.dados_cliente.titulos.valor + bloqueado = response.data.dados_cliente.titulos.bloqueado + uuid_cliente = response.data.dados_cliente.titulos.uuid_cliente + qrcode = response.data.dados_cliente.titulos.qrcode + linhadig = response.data.dados_cliente.titulos.linhadig + referencia = response.data.dados_cliente.titulos.referencia + status = response.data.dados_cliente.titulos.status + datavenc = response.data.dados_cliente.titulos.datavenc + descricao = response.data.dados_cliente.titulos.descricao + titulo = response.data.dados_cliente.titulos.titulo + statusCorrigido = status[0].toUpperCase() + status.substr(1); + valorCorrigido = valor.replace(".", ","); + + var curdate = new Date(datavenc) + const mesCorreto = curdate.getMonth() + 1 + const ano = ('0' + curdate.getFullYear()).slice(-4) + const mes = ('0' + mesCorreto).slice(-2) + const dia = ('0' + curdate.getDate()).slice(-2) + const anoMesDia = `${dia}/${mes}/${ano}` + + try { + const textMessage = { text: formatBody(`Localizei seu Cadastro! *${nome}* só mais um instante por favor!`, contact) }; + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, textMessage); + const bodyBoleto = { text: formatBody(`Segue a segunda-via da sua Fatura!\n\n*Nome:* ${nome}\n*Valor:* R$ ${valorCorrigido}\n*Data Vencimento:* ${anoMesDia}\n*Link:* ${urlmkauth}/boleto/21boleto.php?titulo=${titulo}\n\nVou mandar o *código de barras* na próxima mensagem para ficar mais fácil para você copiar!`, contact) }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyBoleto); + const bodyLinha = { text: formatBody(`${linhadig}`, contact) }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyLinha); + if (qrcode !== null) { + const bodyPdf = { text: formatBody(`Este é o *PIX COPIA E COLA*`, contact) }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyPdf); + const bodyqrcode = { text: formatBody(`${qrcode}`, contact) }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyqrcode); + let linkBoleto = `https://chart.googleapis.com/chart?cht=qr&chs=500x500&chld=L|0&chl=${qrcode}` + await sleep(2000) + await sendMessageImage(wbot, contact, ticket, linkBoleto, "") + } + const bodyPdf = { text: formatBody(`Agora vou te enviar o boleto em *PDF* caso você precise.`, contact) }; + await sleep(2000) + const bodyPdfQr = { text: formatBody(`${bodyPdf}`, contact) }; + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyPdfQr); + await sleep(2000) + + //GERA O PDF + const nomePDF = `Boleto-${nome}-${dia}-${mes}-${ano}.pdf`; + (async () => { + const browser = await puppeteer.launch({ args: ['--no-sandbox'] }); + const page = await browser.newPage(); + const website_url = `${urlmkauth}/boleto/21boleto.php?titulo=${titulo}`; + await page.goto(website_url, { waitUntil: 'networkidle0' }); + await page.emulateMediaType('screen'); + // Downlaod the PDF + const pdf = await page.pdf({ + path: nomePDF, + printBackground: true, + format: 'A4', + }); + + await browser.close(); + await sendMessageLink(wbot, contact, ticket, nomePDF, nomePDF); + }); + + + if (bloqueado === 'sim') { + const bodyBloqueio = { text: formatBody(`${nome} vi tambem que a sua conexão esta bloqueada! Vou desbloquear para você por *48 horas*.`, contact) }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyBloqueio); + const bodyqrcode = { text: formatBody(`Estou liberando seu acesso. Por favor aguarde!`, contact) }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyqrcode); + var optionsdesbloq = { + method: 'GET', + url: `${urlmkauth}/api/cliente/desbloqueio/${uuid_cliente}`, + headers: { + Authorization: `Bearer ${jtw}` + } + }; + axios.request(optionsdesbloq as any).then(async function (response) { + const bodyLiberado = { text: formatBody(`Pronto liberei! Vou precisar que você *retire* seu equipamento da tomada.\n\n*OBS: Somente retire da tomada.* \nAguarde 1 minuto e ligue novamente!`, contact) }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyLiberado); + const bodyqrcode = { text: formatBody(`Veja se seu acesso voltou! Caso nao tenha voltado retorne o contato e fale com um atendente!`, contact) }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyqrcode); + }).catch(async function (error) { + const bodyfinaliza = { text: formatBody(`Opss! Algo de errado aconteceu! Digite *#* para voltar ao menu anterior e fale com um atendente!`, contact) }; + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyfinaliza); + }); + } + + + const bodyfinaliza = { text: formatBody(`Estamos finalizando esta conversa! Caso precise entre em contato conosco!`, contact) }; + await sleep(12000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyfinaliza); + + await sleep(2000) + fs.unlink(nomePDF, function (err) { + if (err) throw err; + console.log(err); + }) + + await UpdateTicketService({ + ticketData: { status: "closed" }, + ticketId: ticket.id, + companyId: ticket.companyId, + }); + + } catch (error) { + console.log('11 Não consegui enviar a mensagem!') + } + } + }) + .catch(async function (error) { + try { + const bodyBoleto = { text: formatBody(`Não consegui encontrar seu cadastro.\n\nPor favor tente novamente!\nOu digite *#* para voltar ao *Menu Anterior*`, contact) }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyBoleto); + } catch (error) { + console.log('111 Não consegui enviar a mensagem!') + } + + }); + }) + .catch(async function (error) { + const bodyfinaliza = { text: formatBody(`Opss! Algo de errado aconteceu! Digite *#* para voltar ao menu anterior e fale com um atendente!`, contact) }; + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyfinaliza); + }); + } else { + const body = { text: formatBody(`Este CPF/CNPJ não é válido!\n\nPor favor tente novamente!\nOu digite *#* para voltar ao *Menu Anterior*`, contact) }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body); + } + } + } + } + + if (asaastoken.value !== "") { + if (isNumeric(numberCPFCNPJ) === true) { + if (cpfcnpj.length > 2) { + const isCPFCNPJ = validaCpfCnpj(numberCPFCNPJ) + if (isCPFCNPJ) { + const body = { + text: formatBody(`Aguarde! Estamos consultando na base de dados!`, contact), + }; + try { + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body); + } catch (error) { + } + var optionsc = { + method: 'GET', + url: 'https://www.asaas.com/api/v3/customers', + params: { cpfCnpj: numberCPFCNPJ }, + headers: { + 'Content-Type': 'application/json', + access_token: asaastk + } + }; + + axios.request(optionsc as any).then(async function (response) { + let nome; + let id_cliente; + let totalCount; + + nome = response?.data?.data[0]?.name; + id_cliente = response?.data?.data[0]?.id; + totalCount = response?.data?.totalCount; + + if (totalCount === 0) { + const body = { + text: formatBody(`Cadastro não localizado! *CPF/CNPJ* incorreto ou inválido. Tenta novamente!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body); + } else { + + const body = { + text: formatBody(`Localizei seu Cadastro! \n*${nome}* só mais um instante por favor!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body); + var optionsListpaymentOVERDUE = { + method: 'GET', + url: 'https://www.asaas.com/api/v3/payments', + params: { customer: id_cliente, status: 'OVERDUE' }, + headers: { + 'Content-Type': 'application/json', + access_token: asaastk + } + }; + + axios.request(optionsListpaymentOVERDUE as any).then(async function (response) { + let totalCount_overdue; + totalCount_overdue = response?.data?.totalCount; + + if (totalCount_overdue === 0) { + const body = { + text: formatBody(`Você não tem nenhuma fatura vencidada! \nVou te enviar a proxima fatura. Por favor aguarde!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body); + var optionsPENDING = { + method: 'GET', + url: 'https://www.asaas.com/api/v3/payments', + params: { customer: id_cliente, status: 'PENDING' }, + headers: { + 'Content-Type': 'application/json', + access_token: asaastk + } + }; + + axios.request(optionsPENDING as any).then(async function (response) { + function sortfunction(a, b) { + return a.dueDate.localeCompare(b.dueDate); + } + const ordenado = response?.data?.data.sort(sortfunction); + let id_payment_pending; + let value_pending; + let description_pending; + let invoiceUrl_pending; + let dueDate_pending; + let invoiceNumber_pending; + let totalCount_pending; + let value_pending_corrigida; + let dueDate_pending_corrigida; + + id_payment_pending = ordenado[0]?.id; + value_pending = ordenado[0]?.value; + description_pending = ordenado[0]?.description; + invoiceUrl_pending = ordenado[0]?.invoiceUrl; + dueDate_pending = ordenado[0]?.dueDate; + invoiceNumber_pending = ordenado[0]?.invoiceNumber; + totalCount_pending = response?.data?.totalCount; + + dueDate_pending_corrigida = dueDate_pending?.split('-')?.reverse()?.join('/'); + value_pending_corrigida = value_pending.toLocaleString('pt-br', { style: 'currency', currency: 'BRL' }); + + const bodyBoleto = { + text: formatBody(`Segue a segunda-via da sua Fatura!\n\n*Fatura:* ${invoiceNumber_pending}\n*Nome:* ${nome}\n*Valor:* R$ ${value_pending_corrigida}\n*Data Vencimento:* ${dueDate_pending_corrigida}\n*Descrição:*\n${description_pending}\n*Link:* ${invoiceUrl_pending}`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyBoleto); + //GET DADOS PIX + var optionsGetPIX = { + method: 'GET', + url: `https://www.asaas.com/api/v3/payments/${id_payment_pending}/pixQrCode`, + headers: { + 'Content-Type': 'application/json', + access_token: asaastk + } + }; + + axios.request(optionsGetPIX as any).then(async function (response) { + let success; + let payload; + + success = response?.data?.success; + payload = response?.data?.payload; + + if (success === true) { + const bodyPixCP = { + text: formatBody(`Este é o *PIX Copia e Cola*`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyPixCP); + const bodyPix = { + text: formatBody(`${payload}`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyPix); + let linkBoleto = `https://chart.googleapis.com/chart?cht=qr&chs=500x500&chld=L|0&chl=${payload}` + await sleep(2000) + await sendMessageImage(wbot, contact, ticket, linkBoleto, '') + var optionsBoletopend = { + method: 'GET', + url: `https://www.asaas.com/api/v3/payments/${id_payment_pending}/identificationField`, + headers: { + 'Content-Type': 'application/json', + access_token: asaastk + } + }; + + axios.request(optionsBoletopend as any).then(async function (response) { + let codigo_barras + codigo_barras = response.data.identificationField; + const bodycodigoBarras = { + text: formatBody(`${codigo_barras}`, contact), + }; + if (response.data?.errors?.code !== 'invalid_action') { + const bodycodigo = { + text: formatBody(`Este é o *Código de Barras*!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodycodigo); + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodycodigoBarras); + const bodyfinaliza = { + text: formatBody(`Estamos finalizando esta conversa! Caso precise entre em contato conosco!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyfinaliza); + await sleep(2000) + await UpdateTicketService({ + ticketData: { status: "closed" }, + ticketId: ticket.id, + companyId: ticket.companyId, + }); + } else { + const bodyfinaliza = { + text: formatBody(`Estamos finalizando esta conversa! Caso precise entre em contato conosco!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyfinaliza); + await UpdateTicketService({ + ticketData: { status: "closed" }, + ticketId: ticket.id, + companyId: ticket.companyId, + }); + } + + }).catch(async function (error) { + const bodyfinaliza = { + text: formatBody(`Estamos finalizando esta conversa! Caso precise entre em contato conosco!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyfinaliza); + await UpdateTicketService({ + ticketData: { status: "closed" }, + ticketId: ticket.id, + companyId: ticket.companyId, + }); + }); + } + + }).catch(async function (error) { + const body = { + text: formatBody(`*Opss!!!!*\nOcorreu um erro! Digite *#* e fale com um *Atendente*!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body); + }); + + }).catch(async function (error) { + const body = { + text: formatBody(`*Opss!!!!*\nOcorreu um erro! Digite *#* e fale com um *Atendente*!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body); + }); + } else { + let id_payment_overdue; + let value_overdue; + let description_overdue; + let invoiceUrl_overdue; + let dueDate_overdue; + let invoiceNumber_overdue; + + let value_overdue_corrigida; + let dueDate_overdue_corrigida; + + id_payment_overdue = response?.data?.data[0]?.id; + value_overdue = response?.data?.data[0]?.value; + description_overdue = response?.data?.data[0]?.description; + invoiceUrl_overdue = response?.data?.data[0]?.invoiceUrl; + dueDate_overdue = response?.data?.data[0]?.dueDate; + invoiceNumber_overdue = response?.data?.data[0]?.invoiceNumber; + + + dueDate_overdue_corrigida = dueDate_overdue?.split('-')?.reverse()?.join('/'); + value_overdue_corrigida = value_overdue.toLocaleString('pt-br', { style: 'currency', currency: 'BRL' }); + const body = { + text: formatBody(`Você tem *${totalCount_overdue}* fatura(s) vencidada(s)! \nVou te enviar. Por favor aguarde!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body); + const bodyBoleto = { + text: formatBody(`Segue a segunda-via da sua Fatura!\n\n*Fatura:* ${invoiceNumber_overdue}\n*Nome:* ${nome}\n*Valor:* R$ ${value_overdue_corrigida}\n*Data Vencimento:* ${dueDate_overdue_corrigida}\n*Descrição:*\n${description_overdue}\n*Link:* ${invoiceUrl_overdue}`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyBoleto); + //GET DADOS PIX + var optionsGetPIX = { + method: 'GET', + url: `https://www.asaas.com/api/v3/payments/${id_payment_overdue}/pixQrCode`, + headers: { + 'Content-Type': 'application/json', + access_token: asaastk + } + }; + + axios.request(optionsGetPIX as any).then(async function (response) { + let success; + let payload; + + success = response?.data?.success; + payload = response?.data?.payload; + if (success === true) { + + const bodyPixCP = { + text: formatBody(`Este é o *PIX Copia e Cola*`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyPixCP); + const bodyPix = { + text: formatBody(`${payload}`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyPix); + let linkBoleto = `https://chart.googleapis.com/chart?cht=qr&chs=500x500&chld=L|0&chl=${payload}` + await sleep(2000) + await sendMessageImage(wbot, contact, ticket, linkBoleto, '') + var optionsBoleto = { + method: 'GET', + url: `https://www.asaas.com/api/v3/payments/${id_payment_overdue}/identificationField`, + headers: { + 'Content-Type': 'application/json', + access_token: asaastk + } + }; + + axios.request(optionsBoleto as any).then(async function (response) { + + let codigo_barras + codigo_barras = response.data.identificationField; + const bodycodigoBarras = { + text: formatBody(`${codigo_barras}`, contact), + }; + if (response.data?.errors?.code !== 'invalid_action') { + const bodycodigo = { + text: formatBody(`Este é o *Código de Barras*!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodycodigo); + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodycodigoBarras); + const bodyfinaliza = { + text: formatBody(`Estamos finalizando esta conversa! Caso precise entre em contato conosco!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyfinaliza); + await UpdateTicketService({ + ticketData: { status: "closed" }, + ticketId: ticket.id, + companyId: ticket.companyId, + }); + } else { + const bodyfinaliza = { + text: formatBody(`Estamos finalizando esta conversa! Caso precise entre em contato conosco!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyfinaliza); + await UpdateTicketService({ + ticketData: { status: "closed" }, + ticketId: ticket.id, + companyId: ticket.companyId, + }); + } + + }).catch(function (error) { + //console.error(error); + }); + + } + }).catch(function (error) { + + }); + + } + + }).catch(async function (error) { + const body = { + text: formatBody(`*Opss!!!!*\nOcorreu um erro! Digite *#* e fale com um *Atendente*!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body); + }); + } + }).catch(async function (error) { + const body = { + text: formatBody(`*Opss!!!!*\nOcorreu um erro! Digite *#* e fale com um *Atendente*!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body); + }); + } + } + } + } + + if (ixcapikey.value != "" && urlixcdb.value != "") { + if (isNumeric(numberCPFCNPJ) === true) { + if (cpfcnpj.length > 2) { + const isCPFCNPJ = validaCpfCnpj(numberCPFCNPJ) + if (isCPFCNPJ) { + if (numberCPFCNPJ.length <= 11) { + numberCPFCNPJ = numberCPFCNPJ.replace(/(\d{3})(\d)/, "$1.$2") + numberCPFCNPJ = numberCPFCNPJ.replace(/(\d{3})(\d)/, "$1.$2") + numberCPFCNPJ = numberCPFCNPJ.replace(/(\d{3})(\d{1,2})$/, "$1-$2") + } else { + numberCPFCNPJ = numberCPFCNPJ.replace(/^(\d{2})(\d)/, "$1.$2") + numberCPFCNPJ = numberCPFCNPJ.replace(/^(\d{2})\.(\d{3})(\d)/, "$1.$2.$3") + numberCPFCNPJ = numberCPFCNPJ.replace(/\.(\d{3})(\d)/, ".$1/$2") + numberCPFCNPJ = numberCPFCNPJ.replace(/(\d{4})(\d)/, "$1-$2") + } + //const token = await CheckSettingsHelper("OBTEM O TOKEN DO BANCO (dei insert na tabela settings)") + const body = { + text: formatBody(`Aguarde! Estamos consultando na base de dados!`, contact), + }; + try { + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body); + } catch (error) { + } + var options = { + method: 'GET', + url: `${urlixc}/webservice/v1/cliente`, + headers: { + ixcsoft: 'listar', + Authorization: `Basic ${ixckeybase64}` + }, + data: { + qtype: 'cliente.cnpj_cpf', + query: numberCPFCNPJ, + oper: '=', + page: '1', + rp: '1', + sortname: 'cliente.cnpj_cpf', + sortorder: 'asc' + } + }; + + axios.request(options as any).then(async function (response) { + if (response.data.type === 'error') { + console.log("Error response", response.data.message); + const body = { + text: formatBody(`*Opss!!!!*\nOcorreu um erro! Digite *#* e fale com um *Atendente*!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body); + } if (response.data.total === 0) { + const body = { + text: formatBody(`Cadastro não localizado! *CPF/CNPJ* incorreto ou inválido. Tenta novamente!`, contact), + }; + try { + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body); + } catch (error) { + } + } else { + + let nome; + let id; + let type; + + nome = response.data?.registros[0]?.razao + id = response.data?.registros[0]?.id + type = response.data?.type + + + const body = { + text: formatBody(`Localizei seu Cadastro! \n*${nome}* só mais um instante por favor!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body); + var boleto = { + method: 'GET', + url: `${urlixc}/webservice/v1/fn_areceber`, + headers: { + ixcsoft: 'listar', + Authorization: `Basic ${ixckeybase64}` + }, + data: { + qtype: 'fn_areceber.id_cliente', + query: id, + oper: '=', + page: '1', + rp: '1', + sortname: 'fn_areceber.data_vencimento', + sortorder: 'asc', + grid_param: '[{"TB":"fn_areceber.status", "OP" : "=", "P" : "A"}]' + } + }; + axios.request(boleto as any).then(async function (response) { + + + + let gateway_link; + let valor; + let datavenc; + let datavencCorrigida; + let valorCorrigido; + let linha_digitavel; + let impresso; + let idboleto; + + idboleto = response.data?.registros[0]?.id + gateway_link = response.data?.registros[0]?.gateway_link + valor = response.data?.registros[0]?.valor + datavenc = response.data?.registros[0]?.data_vencimento + linha_digitavel = response.data?.registros[0]?.linha_digitavel + impresso = response.data?.registros[0]?.impresso + valorCorrigido = valor.replace(".", ","); + datavencCorrigida = datavenc.split('-').reverse().join('/') + + + //INFORMAÇÕES BOLETO + const bodyBoleto = { + text: formatBody(`Segue a segunda-via da sua Fatura!\n\n*Fatura:* ${idboleto}\n*Nome:* ${nome}\n*Valor:* R$ ${valorCorrigido}\n*Data Vencimento:* ${datavencCorrigida}\n\nVou mandar o *código de barras* na próxima mensagem para ficar mais fácil para você copiar!`, contact), + }; + //await sleep(2000) + //await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyBoleto); + //LINHA DIGITAVEL + if (impresso !== "S") { + //IMPRIME BOLETO PARA GERAR CODIGO BARRAS + var boletopdf = { + method: 'GET', + url: `${urlixc}/webservice/v1/get_boleto`, + headers: { + ixcsoft: 'listar', + Authorization: `Basic ${ixckeybase64}` + }, + data: { + boletos: idboleto, + juro: 'N', + multa: 'N', + atualiza_boleto: 'N', + tipo_boleto: 'arquivo', + base64: 'S' + } + }; + + axios.request(boletopdf as any).then(function (response) { + }).catch(function (error) { + console.error(error); + }); + } + + //SE TIVER PIX ENVIA O PIX + var optionsPix = { + method: 'GET', + url: `${urlixc}/webservice/v1/get_pix`, + headers: { + ixcsoft: 'listar', + Authorization: `Basic ${ixckeybase64}` + }, + data: { id_areceber: idboleto } + }; + + axios.request(optionsPix as any).then(async function (response) { + let tipo; + let pix; + + tipo = response.data?.type; + pix = response.data?.pix?.qrCode?.qrcode; + if (tipo === 'success') { + const bodyBoletoPix = { + text: formatBody(`Segue a segunda-via da sua Fatura!\n\n*Fatura:* ${idboleto}\n*Nome:* ${nome}\n*Valor:* R$ ${valorCorrigido}\n*Data Vencimento:* ${datavencCorrigida}\n\nVou te enviar o *Código de Barras* e o *PIX* basta clicar em qual você quer utlizar que já vai copiar! Depois basta realizar o pagamento no seu banco`, contact), + }; + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyBoletoPix); + const body_linhadigitavel = { + text: formatBody("Este é o *Código de Barras*", contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body_linhadigitavel); + await sleep(2000) + const body_linha_digitavel = { + text: formatBody(`${linha_digitavel}`, contact), + }; + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body_linha_digitavel); + const body_pix = { + text: formatBody("Este é o *PIX Copia e Cola*", contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body_pix); + await sleep(2000) + const body_pix_dig = { + text: formatBody(`${pix}`, contact), + }; + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body_pix_dig); + const body_pixqr = { + text: formatBody("QR CODE do *PIX*", contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body_pixqr); + let linkBoleto = `https://chart.googleapis.com/chart?cht=qr&chs=500x500&chld=L|0&chl=${pix}` + await sleep(2000) + await sendMessageImage(wbot, contact, ticket, linkBoleto, '') + ///VE SE ESTA BLOQUEADO PARA LIBERAR! + var optionscontrato = { + method: 'POST', + url: `${urlixc}/webservice/v1/cliente_contrato`, + headers: { + ixcsoft: 'listar', + Authorization: `Basic ${ixckeybase64}` + }, + data: { + qtype: 'cliente_contrato.id_cliente', + query: id, + oper: '=', + page: '1', + rp: '1', + sortname: 'cliente_contrato.id', + sortorder: 'asc' + } + }; + axios.request(optionscontrato as any).then(async function (response) { + let status_internet; + let id_contrato; + status_internet = response.data?.registros[0]?.status_internet; + id_contrato = response.data?.registros[0]?.id; + if (status_internet !== 'A') { + const bodyPdf = { + text: formatBody(`*${nome}* vi tambem que a sua conexão esta bloqueada! Vou desbloquear para você.`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyPdf); + const bodyqrcode = { + text: formatBody(`Estou liberando seu acesso. Por favor aguarde!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyqrcode); + //REALIZANDO O DESBLOQUEIO + var optionsdesbloqeuio = { + method: 'POST', + url: `${urlixc}/webservice/v1/desbloqueio_confianca`, + headers: { + Authorization: `Basic ${ixckeybase64}` + }, + data: { id: id_contrato } + }; + + axios.request(optionsdesbloqeuio as any).then(async function (response) { + let tipo; + let mensagem; + tipo = response.data?.tipo; + mensagem = response.data?.mensagem; + if (tipo === 'sucesso') { + //DESCONECTANDO O CLIENTE PARA VOLTAR O ACESSO + var optionsRadius = { + method: 'GET', + url: `${urlixc}/webservice/v1/radusuarios`, + headers: { + ixcsoft: 'listar', + Authorization: `Basic ${ixckeybase64}` + }, + data: { + qtype: 'radusuarios.id_cliente', + query: id, + oper: '=', + page: '1', + rp: '1', + sortname: 'radusuarios.id', + sortorder: 'asc' + } + }; + + axios.request(optionsRadius as any).then(async function (response) { + let tipo; + tipo = response.data?.type; + if (tipo === 'success') { + const body_mensagem = { + text: formatBody(`${mensagem}`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body_mensagem); + const bodyPdf = { + text: formatBody(`Fiz os procedimentos de liberação! Agora aguarde até 5 minutos e veja se sua conexão irá retornar! .\n\nCaso não tenha voltado, retorne o contato e fale com um atendente!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyPdf); + const bodyfinaliza = { + text: formatBody(`Estamos finalizando esta conversa! Caso precise entre em contato conosco!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyfinaliza); + await UpdateTicketService({ + ticketData: { status: "closed" }, + ticketId: ticket.id, + companyId: ticket.companyId, + }); + } + }).catch(function (error) { + console.error(error); + }); + //FIM DA DESCONEXÃO + } else { + var msgerrolbieracao = response.data.mensagem + const bodyerro = { + text: formatBody(`Ops! Ocorreu um erro e nao consegui desbloquear`, contact), + }; + const msg_errolbieracao = { + text: formatBody(`${msgerrolbieracao}`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyerro); + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, msg_errolbieracao); + const bodyerroatendent = { + text: formatBody(`Digite *#* para voltar o menu e fale com um atendente!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyerroatendent); + } + + }).catch(async function (error) { + const bodyerro = { + text: formatBody(`Ops! Ocorreu um erro digite *#* e fale com um atendente!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyerro); + }); + } else { + const bodyfinaliza = { + text: formatBody(`Estamos finalizando esta conversa! Caso precise entre em contato conosco!`, contact), + }; + await sleep(8000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyfinaliza); + await UpdateTicketService({ + ticketData: { status: "closed" }, + ticketId: ticket.id, + companyId: ticket.companyId, + }); + } + + // + }).catch(async function (error) { + + const bodyerro = { + text: formatBody(`Ops! Ocorreu um erro digite *#* e fale com um atendente!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyerro); + }); + ///VE SE ESTA BLOQUEADO PARA LIBERAR! + } else { + const bodyBoleto = { + text: formatBody(`Segue a segunda-via da sua Fatura!\n\n*Fatura:* ${idboleto}\n*Nome:* ${nome}\n*Valor:* R$ ${valorCorrigido}\n*Data Vencimento:* ${datavencCorrigida}\n\nBasta clicar aqui em baixo em código de barras para copiar, apos isto basta realizar o pagamento em seu banco!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyBoleto); + const body = { + text: formatBody(`Este é o *Codigo de Barras*`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body); + await sleep(2000) + const body_linha_digitavel = { + text: formatBody(`${linha_digitavel}`, contact), + }; + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body_linha_digitavel); + ///VE SE ESTA BLOQUEADO PARA LIBERAR! + var optionscontrato = { + method: 'POST', + url: `${urlixc}/webservice/v1/cliente_contrato`, + headers: { + ixcsoft: 'listar', + Authorization: `Basic ${ixckeybase64}` + }, + data: { + qtype: 'cliente_contrato.id_cliente', + query: id, + oper: '=', + page: '1', + rp: '1', + sortname: 'cliente_contrato.id', + sortorder: 'asc' + } + }; + axios.request(optionscontrato as any).then(async function (response) { + let status_internet; + let id_contrato; + status_internet = response.data?.registros[0]?.status_internet; + id_contrato = response.data?.registros[0]?.id; + if (status_internet !== 'A') { + const bodyPdf = { + text: formatBody(`*${nome}* vi tambem que a sua conexão esta bloqueada! Vou desbloquear para você.`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyPdf); + const bodyqrcode = { + text: formatBody(`Estou liberando seu acesso. Por favor aguarde!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyqrcode); + //REALIZANDO O DESBLOQUEIO + var optionsdesbloqeuio = { + method: 'POST', + url: `${urlixc}/webservice/v1/desbloqueio_confianca`, + headers: { + Authorization: `Basic ${ixckeybase64}` + }, + data: { id: id_contrato } + }; + + axios.request(optionsdesbloqeuio as any).then(async function (response) { + let tipo; + let mensagem; + tipo = response.data?.tipo; + mensagem = response.data?.mensagem; + if (tipo === 'sucesso') { + //DESCONECTANDO O CLIENTE PARA VOLTAR O ACESSO + var optionsRadius = { + method: 'GET', + url: `${urlixc}/webservice/v1/radusuarios`, + headers: { + ixcsoft: 'listar', + Authorization: `Basic ${ixckeybase64}` + }, + data: { + qtype: 'radusuarios.id_cliente', + query: id, + oper: '=', + page: '1', + rp: '1', + sortname: 'radusuarios.id', + sortorder: 'asc' + } + }; + + axios.request(optionsRadius as any).then(async function (response) { + let tipo; + tipo = response.data?.type; + const body_mensagem = { + text: formatBody(`${mensagem}`, contact), + }; + if (tipo === 'success') { + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body_mensagem); + const bodyPdf = { + text: formatBody(`Fiz os procedimentos de liberação! Agora aguarde até 5 minutos e veja se sua conexão irá retornar! .\n\nCaso não tenha voltado, retorne o contato e fale com um atendente!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyPdf); + const bodyfinaliza = { + text: formatBody(`Estamos finalizando esta conversa! Caso precise entre em contato conosco!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyfinaliza); + await UpdateTicketService({ + ticketData: { status: "closed" }, + ticketId: ticket.id, + companyId: ticket.companyId, + }); + } else { + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body_mensagem); + const bodyPdf = { + text: formatBody(`Vou precisar que você *retire* seu equipamento da tomada.\n\n*OBS: Somente retire da tomada.* \nAguarde 1 minuto e ligue novamente!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyPdf); + const bodyqrcode = { + text: formatBody(`Veja se seu acesso voltou! Caso não tenha voltado retorne o contato e fale com um atendente!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyqrcode); + const bodyfinaliza = { + text: formatBody(`Estamos finalizando esta conversa! Caso precise entre em contato conosco!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyfinaliza); + await UpdateTicketService({ + ticketData: { status: "closed" }, + ticketId: ticket.id, + companyId: ticket.companyId, + }); + } + }).catch(function (error) { + console.error(error); + }); + //FIM DA DESCONEXÃO + } else { + const bodyerro = { + text: formatBody(`Ops! Ocorreu um erro e nao consegui desbloquear! Digite *#* e fale com um atendente!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyerro); + } + + }).catch(async function (error) { + const bodyerro = { + text: formatBody(`Ops! Ocorreu um erro digite *#* e fale com um atendente!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyerro); + }); + } else { + const bodyfinaliza = { + text: formatBody(`Estamos finalizando esta conversa! Caso precise entre em contato conosco!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyfinaliza); + await UpdateTicketService({ + ticketData: { status: "closed" }, + ticketId: ticket.id, + companyId: ticket.companyId, + }); + } + + // + }).catch(async function (error) { + const bodyerro = { + text: formatBody(`Ops! Ocorreu um erro digite *#* e fale com um atendente!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyerro); + }); + ///VE SE ESTA BLOQUEADO PARA LIBERAR! + } + }).catch(function (error) { + console.error(error); + }); + //FIM DO PÌX + + + + }).catch(function (error) { + console.error(error); + }); + + } + + }).catch(async function (error) { + const body = { + text: formatBody(`*Opss!!!!*\nOcorreu um erro! Digite *#* e fale com um *Atendente*!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body); + }); + } else { + const body = { + text: formatBody(`Este CPF/CNPJ não é válido!\n\nPor favor tente novamente!\nOu digite *#* para voltar ao *Menu Anterior*`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body); + } + } + } + + + } + } + + if (filaescolhida === "Religue de Confiança" || filaescolhida === "Liberação em Confiança") { + let cpfcnpj + cpfcnpj = getBodyMessage(msg); + cpfcnpj = cpfcnpj.replace(/\./g, ''); + cpfcnpj = cpfcnpj.replace('-', '') + cpfcnpj = cpfcnpj.replace('/', '') + cpfcnpj = cpfcnpj.replace(' ', '') + cpfcnpj = cpfcnpj.replace(',', '') + + const asaastoken = await Setting.findOne({ + where: { + key: "asaas", + companyId + } + }); + const ixcapikey = await Setting.findOne({ + where: { + key: "tokenixc", + companyId + } + }); + const urlixcdb = await Setting.findOne({ + where: { + key: "ipixc", + companyId + } + }); + const ipmkauth = await Setting.findOne({ + where: { + key: "ipmkauth", + companyId + } + }); + const clientidmkauth = await Setting.findOne({ + where: { + key: "clientidmkauth", + companyId + } + }); + const clientesecretmkauth = await Setting.findOne({ + where: { + key: "clientsecretmkauth", + companyId + } + }); + + let urlmkauth = ipmkauth.value + if (urlmkauth.substr(-1) === '/') { + urlmkauth = urlmkauth.slice(0, -1); + } + + //VARS + let url = `${urlmkauth}/api/`; + const Client_Id = clientidmkauth.value + const Client_Secret = clientesecretmkauth.value + const ixckeybase64 = btoa(ixcapikey.value); + const urlixc = urlixcdb.value + const asaastk = asaastoken.value + + const cnpj_cpf = getBodyMessage(msg); + let numberCPFCNPJ = cpfcnpj; + + if (ixcapikey.value != "" && urlixcdb.value != "") { + if (isNumeric(numberCPFCNPJ) === true) { + if (cpfcnpj.length > 2) { + const isCPFCNPJ = validaCpfCnpj(numberCPFCNPJ) + if (isCPFCNPJ) { + if (numberCPFCNPJ.length <= 11) { + numberCPFCNPJ = numberCPFCNPJ.replace(/(\d{3})(\d)/, "$1.$2") + numberCPFCNPJ = numberCPFCNPJ.replace(/(\d{3})(\d)/, "$1.$2") + numberCPFCNPJ = numberCPFCNPJ.replace(/(\d{3})(\d{1,2})$/, "$1-$2") + } else { + numberCPFCNPJ = numberCPFCNPJ.replace(/^(\d{2})(\d)/, "$1.$2") + numberCPFCNPJ = numberCPFCNPJ.replace(/^(\d{2})\.(\d{3})(\d)/, "$1.$2.$3") + numberCPFCNPJ = numberCPFCNPJ.replace(/\.(\d{3})(\d)/, ".$1/$2") + numberCPFCNPJ = numberCPFCNPJ.replace(/(\d{4})(\d)/, "$1-$2") + } + //const token = await CheckSettingsHelper("OBTEM O TOKEN DO BANCO (dei insert na tabela settings)") + const body = { + text: formatBody(`Aguarde! Estamos consultando na base de dados!`, contact), + }; + try { + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body); + } catch (error) { + + } + var options = { + method: 'GET', + url: `${urlixc}/webservice/v1/cliente`, + headers: { + ixcsoft: 'listar', + Authorization: `Basic ${ixckeybase64}` + }, + data: { + qtype: 'cliente.cnpj_cpf', + query: numberCPFCNPJ, + oper: '=', + page: '1', + rp: '1', + sortname: 'cliente.cnpj_cpf', + sortorder: 'asc' + } + }; + + axios.request(options as any).then(async function (response) { + + if (response.data.type === 'error') { + const body = { + text: formatBody(`*Opss!!!!*\nOcorreu um erro! Digite *#* e fale com um *Atendente*!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body); + } if (response.data.total === 0) { + const body = { + text: formatBody(`Cadastro não localizado! *CPF/CNPJ* incorreto ou inválido. Tenta novamente!`, contact), + }; + try { + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body); + } catch (error) { + + } + } else { + + let nome; + let id; + let type; + + nome = response.data?.registros[0]?.razao + id = response.data?.registros[0]?.id + type = response.data?.type + + + const body = { + text: formatBody(`Localizei seu Cadastro! \n*${nome}* só mais um instante por favor!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body); + ///VE SE ESTA BLOQUEADO PARA LIBERAR! + var optionscontrato = { + method: 'POST', + url: `${urlixc}/webservice/v1/cliente_contrato`, + headers: { + ixcsoft: 'listar', + Authorization: `Basic ${ixckeybase64}` + }, + data: { + qtype: 'cliente_contrato.id_cliente', + query: id, + oper: '=', + page: '1', + rp: '1', + sortname: 'cliente_contrato.id', + sortorder: 'asc' + } + }; + axios.request(optionscontrato as any).then(async function (response) { + let status_internet; + let id_contrato; + status_internet = response.data?.registros[0]?.status_internet; + id_contrato = response.data?.registros[0]?.id; + if (status_internet !== 'A') { + const bodyPdf = { + text: formatBody(`*${nome}* a sua conexão esta bloqueada! Vou desbloquear para você.`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyPdf); + const bodyqrcode = { + text: formatBody(`Estou liberando seu acesso. Por favor aguarde!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyqrcode); + //REALIZANDO O DESBLOQUEIO + var optionsdesbloqeuio = { + method: 'POST', + url: `${urlixc}/webservice/v1/desbloqueio_confianca`, + headers: { + Authorization: `Basic ${ixckeybase64}` + }, + data: { id: id_contrato } + }; + + axios.request(optionsdesbloqeuio as any).then(async function (response) { + let tipo; + let mensagem; + tipo = response.data?.tipo; + mensagem = response.data?.mensagem; + const body_mensagem = { + text: formatBody(`${mensagem}`, contact), + }; + if (tipo === 'sucesso') { + //DESCONECTANDO O CLIENTE PARA VOLTAR O ACESSO + var optionsRadius = { + method: 'GET', + url: `${urlixc}/webservice/v1/radusuarios`, + headers: { + ixcsoft: 'listar', + Authorization: `Basic ${ixckeybase64}` + }, + data: { + qtype: 'radusuarios.id_cliente', + query: id, + oper: '=', + page: '1', + rp: '1', + sortname: 'radusuarios.id', + sortorder: 'asc' + } + }; + + axios.request(optionsRadius as any).then(async function (response) { + let tipo; + tipo = response.data?.type; + + if (tipo === 'success') { + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body_mensagem); + const bodyPdf = { + text: formatBody(`Fiz os procedimentos de liberação! Agora aguarde até 5 minutos e veja se sua conexão irá retornar! .\n\nCaso não tenha voltado, retorne o contato e fale com um atendente!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyPdf); + const bodyfinaliza = { + text: formatBody(`Estamos finalizando esta conversa! Caso precise entre em contato conosco!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyfinaliza); + await UpdateTicketService({ + ticketData: { status: "closed" }, + ticketId: ticket.id, + companyId: ticket.companyId, + }); + } else { + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body_mensagem); + const bodyPdf = { + text: formatBody(`Vou precisar que você *retire* seu equipamento da tomada.\n\n*OBS: Somente retire da tomada.* \nAguarde 1 minuto e ligue novamente!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyPdf); + const bodyqrcode = { + text: formatBody(`Veja se seu acesso voltou! Caso não tenha voltado retorne o contato e fale com um atendente!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyqrcode); + const bodyfinaliza = { + text: formatBody(`Estamos finalizando esta conversa! Caso precise entre em contato conosco!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyfinaliza); + await UpdateTicketService({ + ticketData: { status: "closed" }, + ticketId: ticket.id, + companyId: ticket.companyId, + }); + } + }).catch(function (error) { + console.error(error); + }); + //FIM DA DESCONEXÃO + + } else { + const bodyerro = { + text: formatBody(`Ops! Ocorreu um erro e nao consegui desbloquear!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyerro); + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body_mensagem); + const bodyerroatendente = { + text: formatBody(`Digite *#* e fale com um atendente!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyerroatendente); + } /* else { + const bodyerro = { + text: formatBody(`Ops! Ocorreu um erro e nao consegui desbloquear! Digite *#* e fale com um atendente!` + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`,bodyerro); + } */ + + }).catch(async function (error) { + + const bodyerro = { + text: formatBody(`Ops! Ocorreu um erro digite *#* e fale com um atendente!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyerro); + }); + } else { + const bodysembloqueio = { + text: formatBody(`Sua Conexão não está bloqueada! Caso esteja com dificuldades de navegação, retorne o contato e fale com um atendente!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodysembloqueio); + const bodyfinaliza = { + text: formatBody(`Estamos finalizando esta conversa! Caso precise entre em contato conosco!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyfinaliza); + await UpdateTicketService({ + ticketData: { status: "closed" }, + ticketId: ticket.id, + companyId: ticket.companyId, + }); + } + + // + }).catch(async function (error) { + + const bodyerro = { + text: formatBody(`Ops! Ocorreu um erro digite *#* e fale com um atendente!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, bodyerro); + }); + + } + + }).catch(async function (error) { + const body = { + text: formatBody(`*Opss!!!!*\nOcorreu um erro! Digite *#* e fale com um *Atendente*!`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body); + }); + } else { + const body = { + text: formatBody(`Este CPF/CNPJ não é válido!\n\nPor favor tente novamente!\nOu digite *#* para voltar ao *Menu Anterior*`, contact), + }; + await sleep(2000) + await wbot.sendMessage(`${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, body); + } + } + } + } + } + +} diff --git a/backend/src/services/WbotServices/wbotClosedTickets.ts b/backend/src/services/WbotServices/wbotClosedTickets.ts new file mode 100644 index 0000000..b29d41a --- /dev/null +++ b/backend/src/services/WbotServices/wbotClosedTickets.ts @@ -0,0 +1,118 @@ +import { Op } from "sequelize"; +import Ticket from "../../models/Ticket" +import Whatsapp from "../../models/Whatsapp" +import { getIO } from "../../libs/socket" +import formatBody from "../../helpers/Mustache"; +import SendWhatsAppMessage from "./SendWhatsAppMessage"; +import moment from "moment"; +import ShowTicketService from "../TicketServices/ShowTicketService"; +import { verifyMessage } from "./wbotMessageListener"; +import TicketTraking from "../../models/TicketTraking"; + +export const ClosedAllOpenTickets = async (companyId: number): Promise => { + + // @ts-ignore: Unreachable code error + const closeTicket = async (ticket: any, currentStatus: any, body: any) => { + if (currentStatus === 'nps') { + + await ticket.update({ + status: "closed", + //userId: ticket.userId || null, + lastMessage: body, + unreadMessages: 0, + amountUseBotQueues: 0 + }); + + } else if (currentStatus === 'open') { + + await ticket.update({ + status: "closed", + // userId: ticket.userId || null, + lastMessage: body, + unreadMessages: 0, + amountUseBotQueues: 0 + }); + + } else { + + await ticket.update({ + status: "closed", + //userId: ticket.userId || null, + unreadMessages: 0 + }); + } + }; + + const io = getIO(); + try { + + const { rows: tickets } = await Ticket.findAndCountAll({ + where: { status: { [Op.in]: ["open"] }, companyId }, + order: [["updatedAt", "DESC"]] + }); + + tickets.forEach(async ticket => { + const showTicket = await ShowTicketService(ticket.id, companyId); + const whatsapp = await Whatsapp.findByPk(showTicket?.whatsappId); + const ticketTraking = await TicketTraking.findOne({ + where: { + ticketId: ticket.id, + finishedAt: null, + } + }) + + if (!whatsapp) return; + + let { + expiresInactiveMessage, //mensage de encerramento por inatividade + expiresTicket //tempo em horas para fechar ticket automaticamente + } = whatsapp + + + // @ts-ignore: Unreachable code error + if (expiresTicket && expiresTicket !== "" && + // @ts-ignore: Unreachable code error + expiresTicket !== "0" && Number(expiresTicket) > 0) { + + //mensagem de encerramento por inatividade + const bodyExpiresMessageInactive = formatBody(`\u200e ${expiresInactiveMessage}`, showTicket.contact); + + const dataLimite = new Date() + dataLimite.setMinutes(dataLimite.getMinutes() - Number(expiresTicket)); + + if (showTicket.status === "open" && !showTicket.isGroup) { + + const dataUltimaInteracaoChamado = new Date(showTicket.updatedAt) + + if (dataUltimaInteracaoChamado < dataLimite && showTicket.fromMe) { + + closeTicket(showTicket, showTicket.status, bodyExpiresMessageInactive); + + if (expiresInactiveMessage !== "" && expiresInactiveMessage !== undefined) { + const sentMessage = await SendWhatsAppMessage({ body: bodyExpiresMessageInactive, ticket: showTicket }); + + await verifyMessage(sentMessage, showTicket, showTicket.contact); + } + + await ticketTraking.update({ + finishedAt: moment().toDate(), + closedAt: moment().toDate(), + whatsappId: ticket.whatsappId, + userId: ticket.userId, + }) + + io.to("open").emit(`company-${companyId}-ticket`, { + action: "delete", + ticketId: showTicket.id + }); + + } + } + } + }); + + } catch (e: any) { + console.log('e', e) + } + +} diff --git a/backend/src/services/WbotServices/wbotMessageListener.ts b/backend/src/services/WbotServices/wbotMessageListener.ts new file mode 100644 index 0000000..813697f --- /dev/null +++ b/backend/src/services/WbotServices/wbotMessageListener.ts @@ -0,0 +1,2312 @@ +import path, { join } from "path"; +import { promisify } from "util"; +import { readFile, writeFile } from "fs"; +import * as Sentry from "@sentry/node"; +import { isNil, isNull, head } from "lodash"; + +import { + downloadMediaMessage, + extractMessageContent, + getContentType, + jidNormalizedUser, + MessageUpsertType, + proto, + WAMessage, + WAMessageStubType, + WAMessageUpdate, + WASocket, +} from "@whiskeysockets/baileys"; +import Contact from "../../models/Contact"; +import Ticket from "../../models/Ticket"; +import Message from "../../models/Message"; + +import { getIO } from "../../libs/socket"; +import CreateMessageService from "../MessageServices/CreateMessageService"; +import { logger } from "../../utils/logger"; +import CreateOrUpdateContactService from "../ContactServices/CreateOrUpdateContactService"; +import FindOrCreateTicketService from "../TicketServices/FindOrCreateTicketService"; +import ShowWhatsAppService from "../WhatsappService/ShowWhatsAppService"; +import UpdateTicketService from "../TicketServices/UpdateTicketService"; +import formatBody from "../../helpers/Mustache"; +import { Store } from "../../libs/store"; +import TicketTraking from "../../models/TicketTraking"; +import UserRating from "../../models/UserRating"; +import SendWhatsAppMessage from "./SendWhatsAppMessage"; +import moment from "moment"; +import Queue from "../../models/Queue"; +import QueueOption from "../../models/QueueOption"; +import FindOrCreateATicketTrakingService from "../TicketServices/FindOrCreateATicketTrakingService"; +import VerifyCurrentSchedule from "../CompanyService/VerifyCurrentSchedule"; +import Campaign from "../../models/Campaign"; +import CampaignShipping from "../../models/CampaignShipping"; +import { Op } from "sequelize"; +import { campaignQueue, parseToMilliseconds, randomValue } from "../../queues"; +import User from "../../models/User"; +import Setting from "../../models/Setting"; +import { cacheLayer } from "../../libs/cache"; +import { provider } from "./providers"; +import { debounce } from "../../helpers/Debounce"; +import { ChatCompletionRequestMessage, Configuration, OpenAIApi } from "openai"; +import ffmpeg from "fluent-ffmpeg"; +import { + SpeechConfig, + SpeechSynthesizer, + AudioConfig +} from "microsoft-cognitiveservices-speech-sdk"; +import typebotListener from "../TypebotServices/typebotListener"; +import QueueIntegrations from "../../models/QueueIntegrations"; +import ShowQueueIntegrationService from "../QueueIntegrationServices/ShowQueueIntegrationService"; + +const request = require("request"); + +const fs = require('fs') + +type Session = WASocket & { + id?: number; + store?: Store; +}; + +interface SessionOpenAi extends OpenAIApi { + id?: number; +} +const sessionsOpenAi: SessionOpenAi[] = []; + +interface ImessageUpsert { + messages: proto.IWebMessageInfo[]; + type: MessageUpsertType; +} + +interface IMe { + name: string; + id: string; +} + +interface IMessage { + messages: WAMessage[]; + isLatest: boolean; +} + +export const isNumeric = (value: string) => /^-?\d+$/.test(value); + +const writeFileAsync = promisify(writeFile); + +const getTypeMessage = (msg: proto.IWebMessageInfo): string => { + return getContentType(msg.message); +}; + +export function validaCpfCnpj(val) { + if (val.length == 11) { + var cpf = val.trim(); + + cpf = cpf.replace(/\./g, ''); + cpf = cpf.replace('-', ''); + cpf = cpf.split(''); + + var v1 = 0; + var v2 = 0; + var aux = false; + + for (var i = 1; cpf.length > i; i++) { + if (cpf[i - 1] != cpf[i]) { + aux = true; + } + } + + if (aux == false) { + return false; + } + + for (var i = 0, p = 10; (cpf.length - 2) > i; i++, p--) { + v1 += cpf[i] * p; + } + + v1 = ((v1 * 10) % 11); + + if (v1 == 10) { + v1 = 0; + } + + if (v1 != cpf[9]) { + return false; + } + + for (var i = 0, p = 11; (cpf.length - 1) > i; i++, p--) { + v2 += cpf[i] * p; + } + + v2 = ((v2 * 10) % 11); + + if (v2 == 10) { + v2 = 0; + } + + if (v2 != cpf[10]) { + return false; + } else { + return true; + } + } else if (val.length == 14) { + var cnpj = val.trim(); + + cnpj = cnpj.replace(/\./g, ''); + cnpj = cnpj.replace('-', ''); + cnpj = cnpj.replace('/', ''); + cnpj = cnpj.split(''); + + var v1 = 0; + var v2 = 0; + var aux = false; + + for (var i = 1; cnpj.length > i; i++) { + if (cnpj[i - 1] != cnpj[i]) { + aux = true; + } + } + + if (aux == false) { + return false; + } + + for (var i = 0, p1 = 5, p2 = 13; (cnpj.length - 2) > i; i++, p1--, p2--) { + if (p1 >= 2) { + v1 += cnpj[i] * p1; + } else { + v1 += cnpj[i] * p2; + } + } + + v1 = (v1 % 11); + + if (v1 < 2) { + v1 = 0; + } else { + v1 = (11 - v1); + } + + if (v1 != cnpj[12]) { + return false; + } + + for (var i = 0, p1 = 6, p2 = 14; (cnpj.length - 1) > i; i++, p1--, p2--) { + if (p1 >= 2) { + v2 += cnpj[i] * p1; + } else { + v2 += cnpj[i] * p2; + } + } + + v2 = (v2 % 11); + + if (v2 < 2) { + v2 = 0; + } else { + v2 = (11 - v2); + } + + if (v2 != cnpj[13]) { + return false; + } else { + return true; + } + } else { + return false; + } +} + +function timeout(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +export async function sleep(time) { + await timeout(time); +} +export const sendMessageImage = async ( + wbot: Session, + contact, + ticket: Ticket, + url: string, + caption: string +) => { + + let sentMessage + try { + sentMessage = await wbot.sendMessage( + `${contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, + { + image: url ? { url } : fs.readFileSync(`public/temp/${caption}-${makeid(10)}`), + fileName: caption, + caption: caption, + mimetype: 'image/jpeg' + } + ); + } catch (error) { + sentMessage = await wbot.sendMessage( + `${contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, + { + text: formatBody('Não consegui enviar o PDF, tente novamente!', contact) + } + ); + } + verifyMessage(sentMessage, ticket, contact); +}; + +export const sendMessageLink = async ( + wbot: Session, + contact: Contact, + ticket: Ticket, + url: string, + caption: string +) => { + + let sentMessage + try { + sentMessage = await wbot.sendMessage( + `${contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, { + document: url ? { url } : fs.readFileSync(`public/temp/${caption}-${makeid(10)}`), + fileName: caption, + caption: caption, + mimetype: 'application/pdf' + } + ); + } catch (error) { + sentMessage = await wbot.sendMessage( + `${contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, { + text: formatBody('Não consegui enviar o PDF, tente novamente!', contact) + } + ); + } + verifyMessage(sentMessage, ticket, contact); +}; + +export function makeid(length) { + var result = ''; + var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + var charactersLength = characters.length; + for (var i = 0; i < length; i++) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)); + } + return result; +} + + +const getBodyButton = (msg: proto.IWebMessageInfo): string => { + if (msg.key.fromMe && msg?.message?.viewOnceMessage?.message?.buttonsMessage?.contentText) { + let bodyMessage = `*${msg?.message?.viewOnceMessage?.message?.buttonsMessage?.contentText}*`; + + for (const buton of msg.message?.viewOnceMessage?.message?.buttonsMessage?.buttons) { + bodyMessage += `\n\n${buton.buttonText?.displayText}`; + } + return bodyMessage; + } + + if (msg.key.fromMe && msg?.message?.viewOnceMessage?.message?.listMessage) { + let bodyMessage = `*${msg?.message?.viewOnceMessage?.message?.listMessage?.description}*`; + for (const buton of msg.message?.viewOnceMessage?.message?.listMessage?.sections) { + for (const rows of buton.rows) { + bodyMessage += `\n\n${rows.title}`; + } + } + + return bodyMessage; + } +}; + +const msgLocation = (image, latitude, longitude) => { + if (image) { + var b64 = Buffer.from(image).toString("base64"); + + let data = `data:image/png;base64, ${b64} | https://maps.google.com/maps?q=${latitude}%2C${longitude}&z=17&hl=pt-BR|${latitude}, ${longitude} `; + return data; + } +}; + +export const getBodyMessage = (msg: proto.IWebMessageInfo): string | null => { + + try { + let type = getTypeMessage(msg); + + const types = { + conversation: msg?.message?.conversation, + editedMessage: msg?.message?.editedMessage?.message?.protocolMessage?.editedMessage?.conversation, + imageMessage: msg.message?.imageMessage?.caption, + videoMessage: msg.message?.videoMessage?.caption, + extendedTextMessage: msg.message?.extendedTextMessage?.text, + buttonsResponseMessage: msg.message?.buttonsResponseMessage?.selectedButtonId, + templateButtonReplyMessage: msg.message?.templateButtonReplyMessage?.selectedId, + messageContextInfo: msg.message?.buttonsResponseMessage?.selectedButtonId || msg.message?.listResponseMessage?.title, + buttonsMessage: getBodyButton(msg) || msg.message?.listResponseMessage?.singleSelectReply?.selectedRowId, + viewOnceMessage: getBodyButton(msg) || msg.message?.listResponseMessage?.singleSelectReply?.selectedRowId, + stickerMessage: "sticker", + contactMessage: msg.message?.contactMessage?.vcard, + contactsArrayMessage: "varios contatos", + //locationMessage: `Latitude: ${msg.message.locationMessage?.degreesLatitude} - Longitude: ${msg.message.locationMessage?.degreesLongitude}`, + locationMessage: msgLocation( + msg.message?.locationMessage?.jpegThumbnail, + msg.message?.locationMessage?.degreesLatitude, + msg.message?.locationMessage?.degreesLongitude + ), + liveLocationMessage: `Latitude: ${msg.message?.liveLocationMessage?.degreesLatitude} - Longitude: ${msg.message?.liveLocationMessage?.degreesLongitude}`, + documentMessage: msg.message?.documentMessage?.title, + documentWithCaptionMessage: msg.message?.documentWithCaptionMessage?.message?.documentMessage?.caption, + audioMessage: "Áudio", + listMessage: getBodyButton(msg) || msg.message?.listResponseMessage?.title, + listResponseMessage: msg.message?.listResponseMessage?.singleSelectReply?.selectedRowId, + reactionMessage: msg.message?.reactionMessage?.text || "reaction", + }; + + const objKey = Object.keys(types).find(key => key === type); + + if (!objKey) { + logger.warn(`#### Nao achou o type 152: ${type} +${JSON.stringify(msg)}`); + Sentry.setExtra("Mensagem", { BodyMsg: msg.message, msg, type }); + Sentry.captureException( + new Error("Novo Tipo de Mensagem em getTypeMessage") + ); + } + return types[type]; + } catch (error) { + Sentry.setExtra("Error getTypeMessage", { msg, BodyMsg: msg.message }); + Sentry.captureException(error); + console.log(error); + } +}; + + +export const getQuotedMessage = (msg: proto.IWebMessageInfo): any => { + const body = + msg.message.imageMessage.contextInfo || + msg.message.videoMessage.contextInfo || + msg.message?.documentMessage || + msg.message.extendedTextMessage.contextInfo || + msg.message.buttonsResponseMessage.contextInfo || + msg.message.listResponseMessage.contextInfo || + msg.message.templateButtonReplyMessage.contextInfo || + msg.message.buttonsResponseMessage?.contextInfo || + msg?.message?.buttonsResponseMessage?.selectedButtonId || + msg.message.listResponseMessage?.singleSelectReply?.selectedRowId || + msg?.message?.listResponseMessage?.singleSelectReply.selectedRowId || + msg.message.listResponseMessage?.contextInfo; + msg.message.senderKeyDistributionMessage; + + // testar isso + + return extractMessageContent(body[Object.keys(body).values().next().value]); +}; +export const getQuotedMessageId = (msg: proto.IWebMessageInfo) => { + const body = extractMessageContent(msg.message)[ + Object.keys(msg?.message).values().next().value + ]; + + return body?.contextInfo?.stanzaId; +}; + +const getMeSocket = (wbot: Session): IMe => { + return { + id: jidNormalizedUser((wbot as WASocket).user.id), + name: (wbot as WASocket).user.name + } +}; + +const getSenderMessage = ( + msg: proto.IWebMessageInfo, + wbot: Session +): string => { + const me = getMeSocket(wbot); + if (msg.key.fromMe) return me.id; + + const senderId = msg.participant || msg.key.participant || msg.key.remoteJid || undefined; + + return senderId && jidNormalizedUser(senderId); +}; + +const getContactMessage = async (msg: proto.IWebMessageInfo, wbot: Session) => { + const isGroup = msg.key.remoteJid.includes("g.us"); + const rawNumber = msg.key.remoteJid.replace(/\D/g, ""); + return isGroup + ? { + id: getSenderMessage(msg, wbot), + name: msg.pushName + } + : { + id: msg.key.remoteJid, + name: msg.key.fromMe ? rawNumber : msg.pushName + }; +}; + +const downloadMedia = async (msg: proto.IWebMessageInfo) => { + + let buffer + try { + buffer = await downloadMediaMessage( + msg, + 'buffer', + {} + ) + } catch (err) { + + + console.error('Erro ao baixar mídia:', err); + + // Trate o erro de acordo com as suas necessidades + } + + let filename = msg.message?.documentMessage?.fileName || ""; + + const mineType = + msg.message?.imageMessage || + msg.message?.audioMessage || + msg.message?.videoMessage || + msg.message?.stickerMessage || + msg.message?.documentMessage || + msg.message?.documentWithCaptionMessage?.message?.documentMessage || + msg.message?.extendedTextMessage?.contextInfo?.quotedMessage?.imageMessage || + msg.message?.extendedTextMessage?.contextInfo?.quotedMessage?.videoMessage; + + if (!mineType) + console.log(msg) + + if (!filename) { + const ext = mineType.mimetype.split("/")[1].split(";")[0]; + filename = `${new Date().getTime()}.${ext}`; + } else { + filename = `${new Date().getTime()}_${filename}`; + } + + const media = { + data: buffer, + mimetype: mineType.mimetype, + filename + }; + + return media; +} + + +const verifyContact = async ( + msgContact: IMe, + wbot: Session, + companyId: number +): Promise => { + let profilePicUrl: string; + try { + profilePicUrl = await wbot.profilePictureUrl(msgContact.id); + } catch (e) { + Sentry.captureException(e); + profilePicUrl = `${process.env.FRONTEND_URL}/nopicture.png`; + } + + const contactData = { + name: msgContact?.name || msgContact.id.replace(/\D/g, ""), + number: msgContact.id.replace(/\D/g, ""), + profilePicUrl, + isGroup: msgContact.id.includes("g.us"), + companyId, + whatsappId: wbot.id + }; + + + + const contact = CreateOrUpdateContactService(contactData); + + return contact; +}; + +const verifyQuotedMessage = async ( + msg: proto.IWebMessageInfo +): Promise => { + if (!msg) return null; + const quoted = getQuotedMessageId(msg); + + if (!quoted) return null; + + const quotedMsg = await Message.findOne({ + where: { id: quoted }, + }); + + if (!quotedMsg) return null; + + return quotedMsg; +}; + +const sanitizeName = (name: string): string => { + let sanitized = name.split(" ")[0]; + sanitized = sanitized.replace(/[^a-zA-Z0-9]/g, ""); + return sanitized.substring(0, 60); +}; +const convertTextToSpeechAndSaveToFile = ( + text: string, + filename: string, + subscriptionKey: string, + serviceRegion: string, + voice: string = "pt-BR-FabioNeural", + audioToFormat: string = "mp3" +): Promise => { + return new Promise((resolve, reject) => { + const speechConfig = SpeechConfig.fromSubscription( + subscriptionKey, + serviceRegion + ); + speechConfig.speechSynthesisVoiceName = voice; + const audioConfig = AudioConfig.fromAudioFileOutput(`${filename}.wav`); + const synthesizer = new SpeechSynthesizer(speechConfig, audioConfig); + synthesizer.speakTextAsync( + text, + result => { + if (result) { + convertWavToAnotherFormat( + `${filename}.wav`, + `${filename}.${audioToFormat}`, + audioToFormat + ) + .then(output => { + resolve(); + }) + .catch(error => { + console.error(error); + reject(error); + }); + } else { + reject(new Error("No result from synthesizer")); + } + synthesizer.close(); + }, + error => { + console.error(`Error: ${error}`); + synthesizer.close(); + reject(error); + } + ); + }); +}; + +const convertWavToAnotherFormat = ( + inputPath: string, + outputPath: string, + toFormat: string +) => { + return new Promise((resolve, reject) => { + ffmpeg() + .input(inputPath) + .toFormat(toFormat) + .on("end", () => resolve(outputPath)) + .on("error", (err: { message: any }) => + reject(new Error(`Error converting file: ${err.message}`)) + ) + .save(outputPath); + }); +}; + +const deleteFileSync = (path: string): void => { + try { + fs.unlinkSync(path); + } catch (error) { + console.error("Erro ao deletar o arquivo:", error); + } +}; + +const keepOnlySpecifiedChars = (str: string) => { + return str.replace(/[^a-zA-Z0-9áéíóúÁÉÍÓÚâêîôûÂÊÎÔÛãõÃÕçÇ!?.,;:\s]/g, ""); +}; +const handleOpenAi = async ( + msg: proto.IWebMessageInfo, + wbot: Session, + ticket: Ticket, + contact: Contact, + mediaSent: Message | undefined +): Promise => { + const bodyMessage = getBodyMessage(msg); + + if (!bodyMessage) return; + + + let { prompt } = await ShowWhatsAppService(wbot.id, ticket.companyId); + + + if (!prompt && !isNil(ticket?.queue?.prompt)) { + prompt = ticket.queue.prompt; + } + + if (!prompt) return; + + if (msg.messageStubType) return; + + const publicFolder: string = path.resolve( + __dirname, + "..", + "..", + "..", + "public" + ); + + let openai: SessionOpenAi; + const openAiIndex = sessionsOpenAi.findIndex(s => s.id === wbot.id); + + + if (openAiIndex === -1) { + const configuration = new Configuration({ + apiKey: prompt.apiKey + }); + openai = new OpenAIApi(configuration); + openai.id = wbot.id; + sessionsOpenAi.push(openai); + } else { + openai = sessionsOpenAi[openAiIndex]; + } + + const messages = await Message.findAll({ + where: { ticketId: ticket.id }, + order: [["createdAt", "ASC"]], + limit: prompt.maxMessages + }); + + const promptSystem = `Nas respostas utilize o nome ${sanitizeName( + contact.name || "Amigo(a)" + )} para identificar o cliente.\nSua resposta deve usar no máximo ${prompt.maxTokens + } tokens e cuide para não truncar o final.\nSempre que possível, mencione o nome dele para ser mais personalizado o atendimento e mais educado. Quando a resposta requer uma transferência para o setor de atendimento, comece sua resposta com 'Ação: Transferir para o setor de atendimento'.\n + ${prompt.prompt}\n`; + + let messagesOpenAi: ChatCompletionRequestMessage[] = []; + + if (msg.message?.conversation || msg.message?.extendedTextMessage?.text) { + messagesOpenAi = []; + messagesOpenAi.push({ role: "system", content: promptSystem }); + for ( + let i = 0; + i < Math.min(prompt.maxMessages, messages.length); + i++ + ) { + const message = messages[i]; + if (message.mediaType === "chat") { + if (message.fromMe) { + messagesOpenAi.push({ role: "assistant", content: message.body }); + } else { + messagesOpenAi.push({ role: "user", content: message.body }); + } + } + } + messagesOpenAi.push({ role: "user", content: bodyMessage! }); + + const chat = await openai.createChatCompletion({ + model: "gpt-3.5-turbo-1106", + messages: messagesOpenAi, + max_tokens: prompt.maxTokens, + temperature: prompt.temperature + }); + + let response = chat.data.choices[0].message?.content; + + if (response?.includes("Ação: Transferir para o setor de atendimento")) { + await transferQueue(prompt.queueId, ticket, contact); + response = response + .replace("Ação: Transferir para o setor de atendimento", "") + .trim(); + } + + if (prompt.voice === "texto") { + const sentMessage = await wbot.sendMessage(msg.key.remoteJid!, { + text: response! + }); + await verifyMessage(sentMessage!, ticket, contact); + } else { + const fileNameWithOutExtension = `${ticket.id}_${Date.now()}`; + convertTextToSpeechAndSaveToFile( + keepOnlySpecifiedChars(response!), + `${publicFolder}/${fileNameWithOutExtension}`, + prompt.voiceKey, + prompt.voiceRegion, + prompt.voice, + "mp3" + ).then(async () => { + try { + const sendMessage = await wbot.sendMessage(msg.key.remoteJid!, { + audio: { url: `${publicFolder}/${fileNameWithOutExtension}.mp3` }, + mimetype: "audio/mpeg", + ptt: true + }); + await verifyMediaMessage(sendMessage!, ticket, contact); + deleteFileSync(`${publicFolder}/${fileNameWithOutExtension}.mp3`); + deleteFileSync(`${publicFolder}/${fileNameWithOutExtension}.wav`); + } catch (error) { + console.log(`Erro para responder com audio: ${error}`); + } + }); + } + } else if (msg.message?.audioMessage) { + const mediaUrl = mediaSent!.mediaUrl!.split("/").pop(); + const file = fs.createReadStream(`${publicFolder}/${mediaUrl}`) as any; + const transcription = await openai.createTranscription(file, "whisper-1"); + + messagesOpenAi = []; + messagesOpenAi.push({ role: "system", content: promptSystem }); + for ( + let i = 0; + i < Math.min(prompt.maxMessages, messages.length); + i++ + ) { + const message = messages[i]; + if (message.mediaType === "chat") { + if (message.fromMe) { + messagesOpenAi.push({ role: "assistant", content: message.body }); + } else { + messagesOpenAi.push({ role: "user", content: message.body }); + } + } + } + messagesOpenAi.push({ role: "user", content: transcription.data.text }); + const chat = await openai.createChatCompletion({ + model: "gpt-3.5-turbo-1106", + messages: messagesOpenAi, + max_tokens: prompt.maxTokens, + temperature: prompt.temperature + }); + let response = chat.data.choices[0].message?.content; + + if (response?.includes("Ação: Transferir para o setor de atendimento")) { + await transferQueue(prompt.queueId, ticket, contact); + response = response + .replace("Ação: Transferir para o setor de atendimento", "") + .trim(); + } + if (prompt.voice === "texto") { + const sentMessage = await wbot.sendMessage(msg.key.remoteJid!, { + text: response! + }); + await verifyMessage(sentMessage!, ticket, contact); + } else { + const fileNameWithOutExtension = `${ticket.id}_${Date.now()}`; + convertTextToSpeechAndSaveToFile( + keepOnlySpecifiedChars(response!), + `${publicFolder}/${fileNameWithOutExtension}`, + prompt.voiceKey, + prompt.voiceRegion, + prompt.voice, + "mp3" + ).then(async () => { + try { + const sendMessage = await wbot.sendMessage(msg.key.remoteJid!, { + audio: { url: `${publicFolder}/${fileNameWithOutExtension}.mp3` }, + mimetype: "audio/mpeg", + ptt: true + }); + await verifyMediaMessage(sendMessage!, ticket, contact); + deleteFileSync(`${publicFolder}/${fileNameWithOutExtension}.mp3`); + deleteFileSync(`${publicFolder}/${fileNameWithOutExtension}.wav`); + } catch (error) { + console.log(`Erro para responder com audio: ${error}`); + } + }); + } + } + messagesOpenAi = []; +}; + +const transferQueue = async ( + queueId: number, + ticket: Ticket, + contact: Contact +): Promise => { + await UpdateTicketService({ + ticketData: { queueId: queueId, useIntegration: false, promptId: null }, + ticketId: ticket.id, + companyId: ticket.companyId + }); +}; + +const verifyMediaMessage = async ( + msg: proto.IWebMessageInfo, + ticket: Ticket, + contact: Contact +): Promise => { + const io = getIO(); + const quotedMsg = await verifyQuotedMessage(msg); + const media = await downloadMedia(msg); + + if (!media) { + throw new Error("ERR_WAPP_DOWNLOAD_MEDIA"); + } + + if (!media.filename) { + const ext = media.mimetype.split("/")[1].split(";")[0]; + media.filename = `${new Date().getTime()}.${ext}`; + } + + try { + await writeFileAsync( + join(__dirname, "..", "..", "..", "public", media.filename), + media.data, + "base64" + ); + } catch (err) { + Sentry.captureException(err); + logger.error(err); + } + + const body = getBodyMessage(msg); + + + const messageData = { + id: msg.key.id, + ticketId: ticket.id, + contactId: msg.key.fromMe ? undefined : contact.id, + body: body ? formatBody(body, ticket.contact) : media.filename, + fromMe: msg.key.fromMe, + read: msg.key.fromMe, + mediaUrl: media.filename, + mediaType: media.mimetype.split("/")[0], + quotedMsgId: quotedMsg?.id, + ack: msg.status, + remoteJid: msg.key.remoteJid, + participant: msg.key.participant, + dataJson: JSON.stringify(msg), + }; + + await ticket.update({ + lastMessage: body || media.filename, + }); + + const newMessage = await CreateMessageService({ + messageData, + companyId: ticket.companyId, + }); + + if (!msg.key.fromMe && ticket.status === "closed") { + await ticket.update({ status: "pending" }); + await ticket.reload({ + include: [ + { model: Queue, as: "queue" }, + { model: User, as: "user" }, + { model: Contact, as: "contact" }, + ], + }); + + io.to(`company-${ticket.companyId}-closed`) + .to(`queue-${ticket.queueId}-closed`) + .emit(`company-${ticket.companyId}-ticket`, { + action: "delete", + ticket, + ticketId: ticket.id, + }); + + io.to(`company-${ticket.companyId}-${ticket.status}`) + .to(`queue-${ticket.queueId}-${ticket.status}`) + .to(ticket.id.toString()) + .emit(`company-${ticket.companyId}-ticket`, { + action: "update", + ticket, + ticketId: ticket.id, + }); + } + + return newMessage; +}; + +export const verifyMessage = async ( + msg: proto.IWebMessageInfo, + ticket: Ticket, + contact: Contact +) => { + const io = getIO(); + const quotedMsg = await verifyQuotedMessage(msg); + const body = getBodyMessage(msg); + const isEdited = getTypeMessage(msg) == 'editedMessage'; + + const messageData = { + id: isEdited ? msg?.message?.editedMessage?.message?.protocolMessage?.key?.id : msg.key.id, + ticketId: ticket.id, + contactId: msg.key.fromMe ? undefined : contact.id, + body, + fromMe: msg.key.fromMe, + mediaType: getTypeMessage(msg), + read: msg.key.fromMe, + quotedMsgId: quotedMsg?.id, + ack: msg.status, + remoteJid: msg.key.remoteJid, + participant: msg.key.participant, + dataJson: JSON.stringify(msg), + isEdited: isEdited, + }; + + await ticket.update({ + lastMessage: body + }); + + await CreateMessageService({ messageData, companyId: ticket.companyId }); + + if (!msg.key.fromMe && ticket.status === "closed") { + await ticket.update({ status: "pending" }); + await ticket.reload({ + include: [ + { model: Queue, as: "queue" }, + { model: User, as: "user" }, + { model: Contact, as: "contact" } + ] + }); + + io.to(`company-${ticket.companyId}-closed`) + .to(`queue-${ticket.queueId}-closed`) + .emit(`company-${ticket.companyId}-ticket`, { + action: "delete", + ticket, + ticketId: ticket.id + }); + + io.to(`company-${ticket.companyId}-${ticket.status}`) + .to(`queue-${ticket.queueId}-${ticket.status}`) + .emit(`company-${ticket.companyId}-ticket`, { + action: "update", + ticket, + ticketId: ticket.id + }); + } +}; + +const isValidMsg = (msg: proto.IWebMessageInfo): boolean => { + if (msg.key.remoteJid === "status@broadcast") return false; + try { + const msgType = getTypeMessage(msg); + if (!msgType) { + return; + } + + const ifType = + msgType === "conversation" || + msgType === "extendedTextMessage" || + msgType === "editedMessage" || + msgType === "audioMessage" || + msgType === "videoMessage" || + msgType === "imageMessage" || + msgType === "documentMessage" || + msgType === "documentWithCaptionMessage" || + msgType === "stickerMessage" || + msgType === "buttonsResponseMessage" || + msgType === "buttonsMessage" || + msgType === "messageContextInfo" || + msgType === "locationMessage" || + msgType === "liveLocationMessage" || + msgType === "contactMessage" || + msgType === "voiceMessage" || + msgType === "mediaMessage" || + msgType === "contactsArrayMessage" || + msgType === "reactionMessage" || + msgType === "ephemeralMessage" || + msgType === "protocolMessage" || + msgType === "listResponseMessage" || + msgType === "listMessage" || + msgType === "viewOnceMessage"; + + if (!ifType) { + logger.warn(`#### Nao achou o type em isValidMsg: ${msgType} +${JSON.stringify(msg?.message)}`); + Sentry.setExtra("Mensagem", { BodyMsg: msg.message, msg, msgType }); + Sentry.captureException(new Error("Novo Tipo de Mensagem em isValidMsg")); + } + + return !!ifType; + } catch (error) { + Sentry.setExtra("Error isValidMsg", { msg }); + Sentry.captureException(error); + } +}; + + +const Push = (msg: proto.IWebMessageInfo) => { + return msg.pushName; +} + +const verifyQueue = async ( + wbot: Session, + msg: proto.IWebMessageInfo, + ticket: Ticket, + contact: Contact, + mediaSent?: Message | undefined +) => { + const companyId = ticket.companyId; + + const { queues, greetingMessage, maxUseBotQueues, timeUseBotQueues } = await ShowWhatsAppService( + wbot.id!, + ticket.companyId + ) + + + + if (queues.length === 1) { + + const sendGreetingMessageOneQueues = await Setting.findOne({ + where: { + key: "sendGreetingMessageOneQueues", + companyId: ticket.companyId + } + }); + + if (greetingMessage.length > 1 && sendGreetingMessageOneQueues?.value === "enabled") { + const body = formatBody(`${greetingMessage}`, contact); + + await wbot.sendMessage( + `${contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, + { + text: body + } + ); + } + + const firstQueue = head(queues); + let chatbot = false; + if (firstQueue?.options) { + chatbot = firstQueue.options.length > 0; + } + + //inicia integração dialogflow/n8n + if ( + !msg.key.fromMe && + !ticket.isGroup && + !isNil(queues[0]?.integrationId) + ) { + const integrations = await ShowQueueIntegrationService(queues[0].integrationId, companyId); + + await handleMessageIntegration(msg, wbot, integrations, ticket) + + await ticket.update({ + useIntegration: true, + integrationId: integrations.id + }) + // return; + } + //inicia integração openai + if ( + !msg.key.fromMe && + !ticket.isGroup && + !isNil(queues[0]?.promptId) + ) { + + + + await handleOpenAi(msg, wbot, ticket, contact, mediaSent); + + + await ticket.update({ + useIntegration: true, + promptId: queues[0]?.promptId + }) + // return; + } + + await UpdateTicketService({ + ticketData: { queueId: firstQueue.id, chatbot, status: "pending" }, + ticketId: ticket.id, + companyId: ticket.companyId, + }); + + return; + } + + const selectedOption = getBodyMessage(msg); + const choosenQueue = queues[+selectedOption - 1]; + + const buttonActive = await Setting.findOne({ + where: { + key: "chatBotType", + companyId + } + }); + + + + const botText = async () => { + let options = ""; + + queues.forEach((queue, index) => { + options += `*[ ${index + 1} ]* - ${queue.name}\n`; + }); + + + const textMessage = { + text: formatBody(`\u200e${greetingMessage}\n\n${options}`, contact), + }; + + const sendMsg = await wbot.sendMessage( + `${contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, + textMessage + ); + + await verifyMessage(sendMsg, ticket, ticket.contact); + }; + + if (choosenQueue) { + let chatbot = false; + if (choosenQueue?.options) { + chatbot = choosenQueue.options.length > 0; + } + + await UpdateTicketService({ + ticketData: { queueId: choosenQueue.id, chatbot }, + ticketId: ticket.id, + companyId: ticket.companyId, + }); + + + /* Tratamento para envio de mensagem quando a fila está fora do expediente */ + if (choosenQueue.options.length === 0) { + const queue = await Queue.findByPk(choosenQueue.id); + const { schedules }: any = queue; + const now = moment(); + const weekday = now.format("dddd").toLowerCase(); + let schedule; + if (Array.isArray(schedules) && schedules.length > 0) { + schedule = schedules.find((s) => s.weekdayEn === weekday && s.startTime !== "" && s.startTime !== null && s.endTime !== "" && s.endTime !== null); + } + + if (queue.outOfHoursMessage !== null && queue.outOfHoursMessage !== "" && !isNil(schedule)) { + const startTime = moment(schedule.startTime, "HH:mm"); + const endTime = moment(schedule.endTime, "HH:mm"); + + if (now.isBefore(startTime) || now.isAfter(endTime)) { + const body = formatBody(`\u200e ${queue.outOfHoursMessage}\n\n*[ # ]* - Voltar ao Menu Principal`, ticket.contact); + const sentMessage = await wbot.sendMessage( + `${contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, { + text: body, + } + ); + await verifyMessage(sentMessage, ticket, contact); + await UpdateTicketService({ + ticketData: { queueId: null, chatbot }, + ticketId: ticket.id, + companyId: ticket.companyId, + }); + return; + } + } + + //inicia integração dialogflow/n8n + if ( + !msg.key.fromMe && + !ticket.isGroup && + choosenQueue.integrationId + ) { + const integrations = await ShowQueueIntegrationService(choosenQueue.integrationId, companyId); + + await handleMessageIntegration(msg, wbot, integrations, ticket) + + await ticket.update({ + useIntegration: true, + integrationId: integrations.id + }) + // return; + } + + //inicia integração openai + if ( + !msg.key.fromMe && + !ticket.isGroup && + !isNil(choosenQueue?.promptId) + ) { + await handleOpenAi(msg, wbot, ticket, contact, mediaSent); + + + await ticket.update({ + useIntegration: true, + promptId: choosenQueue?.promptId + }) + // return; + } + + const body = formatBody(`\u200e${choosenQueue.greetingMessage}`, ticket.contact + ); + if (choosenQueue.greetingMessage) { + const sentMessage = await wbot.sendMessage( + `${contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, { + text: body, + } + ); + await verifyMessage(sentMessage, ticket, contact); + } + } + + } else { + + if (maxUseBotQueues && maxUseBotQueues !== 0 && ticket.amountUsedBotQueues >= maxUseBotQueues) { + // await UpdateTicketService({ + // ticketData: { queueId: queues[0].id }, + // ticketId: ticket.id + // }); + + return; + } + + //Regra para desabilitar o chatbot por x minutos/horas após o primeiro envio + const ticketTraking = await FindOrCreateATicketTrakingService({ ticketId: ticket.id, companyId }); + let dataLimite = new Date(); + let Agora = new Date(); + + + if (ticketTraking.chatbotAt !== null) { + dataLimite.setMinutes(ticketTraking.chatbotAt.getMinutes() + (Number(timeUseBotQueues))); + + if (ticketTraking.chatbotAt !== null && Agora < dataLimite && timeUseBotQueues !== "0" && ticket.amountUsedBotQueues !== 0) { + return + } + } + await ticketTraking.update({ + chatbotAt: null + }) + + if (buttonActive.value === "text") { + return botText(); + } + + } + +}; + + +export const verifyRating = (ticketTraking: TicketTraking) => { + if ( + ticketTraking && + ticketTraking.finishedAt === null && + ticketTraking.userId !== null && + ticketTraking.ratingAt !== null + ) { + return true; + } + return false; +}; + +export const handleRating = async ( + rate: number, + ticket: Ticket, + ticketTraking: TicketTraking +) => { + const io = getIO(); + + const { complationMessage } = await ShowWhatsAppService( + ticket.whatsappId, + ticket.companyId + ); + + let finalRate = rate; + + if (rate < 1) { + finalRate = 1; + } + if (rate > 5) { + finalRate = 5; + } + + await UserRating.create({ + ticketId: ticketTraking.ticketId, + companyId: ticketTraking.companyId, + userId: ticketTraking.userId, + rate: finalRate, + }); + + if (complationMessage) { + const body = formatBody(`\u200e${complationMessage}`, ticket.contact); + await SendWhatsAppMessage({ body, ticket }); + } + + await ticketTraking.update({ + finishedAt: moment().toDate(), + rated: true, + }); + + await ticket.update({ + queueId: null, + chatbot: null, + queueOptionId: null, + userId: null, + status: "closed", + }); + + io.to(`company-${ticket.companyId}-open`) + .to(`queue-${ticket.queueId}-open`) + .emit(`company-${ticket.companyId}-ticket`, { + action: "delete", + ticket, + ticketId: ticket.id, + }); + + io.to(`company-${ticket.companyId}-${ticket.status}`) + .to(`queue-${ticket.queueId}-${ticket.status}`) + .to(ticket.id.toString()) + .emit(`company-${ticket.companyId}-ticket`, { + action: "update", + ticket, + ticketId: ticket.id, + }); +}; + +const handleChartbot = async (ticket: Ticket, msg: WAMessage, wbot: Session, dontReadTheFirstQuestion: boolean = false) => { + + + + const queue = await Queue.findByPk(ticket.queueId, { + include: [ + { + model: QueueOption, + as: "options", + where: { parentId: null }, + order: [ + ["option", "ASC"], + ["createdAt", "ASC"], + ], + }, + ], + }); + + + + + const messageBody = getBodyMessage(msg); + + if (messageBody == "#") { + // voltar para o menu inicial + await ticket.update({ queueOptionId: null, chatbot: false, queueId: null }); + await verifyQueue(wbot, msg, ticket, ticket.contact); + return; + } + + // voltar para o menu anterior + if (!isNil(queue) && !isNil(ticket.queueOptionId) && messageBody == "0") { + const option = await QueueOption.findByPk(ticket.queueOptionId); + await ticket.update({ queueOptionId: option?.parentId }); + + // escolheu uma opção + } else if (!isNil(queue) && !isNil(ticket.queueOptionId)) { + const count = await QueueOption.count({ + where: { parentId: ticket.queueOptionId }, + }); + let option: any = {}; + if (count == 1) { + option = await QueueOption.findOne({ + where: { parentId: ticket.queueOptionId }, + }); + } else { + option = await QueueOption.findOne({ + where: { + option: messageBody || "", + parentId: ticket.queueOptionId, + }, + }); + } + if (option) { + await ticket.update({ queueOptionId: option?.id }); + } + + // não linha a primeira pergunta + } else if (!isNil(queue) && isNil(ticket.queueOptionId) && !dontReadTheFirstQuestion) { + const option = queue?.options.find((o) => o.option == messageBody); + if (option) { + await ticket.update({ queueOptionId: option?.id }); + } + } + + await ticket.reload(); + + if (!isNil(queue) && isNil(ticket.queueOptionId)) { + + const queueOptions = await QueueOption.findAll({ + where: { queueId: ticket.queueId, parentId: null }, + order: [ + ["option", "ASC"], + ["createdAt", "ASC"], + ], + }); + + const companyId = ticket.companyId; + + const buttonActive = await Setting.findOne({ + where: { + key: "chatBotType", + companyId + } + }); + + // const botList = async () => { + // const sectionsRows = []; + + // queues.forEach((queue, index) => { + // sectionsRows.push({ + // title: queue.name, + // rowId: `${index + 1}` + // }); + // }); + + // const sections = [ + // { + // rows: sectionsRows + // } + // ]; + + + // const listMessage = { + // text: formatBody(`\u200e${queue.greetingMessage}`, ticket.contact), + // buttonText: "Escolha uma opção", + // sections + // }; + + // const sendMsg = await wbot.sendMessage( + // `${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, + // listMessage + // ); + + // await verifyMessage(sendMsg, ticket, ticket.contact); + // } + + const botButton = async () => { + const buttons = []; + queueOptions.forEach((option, i) => { + buttons.push({ + buttonId: `${option.option}`, + buttonText: { displayText: option.title }, + type: 4 + }); + }); + buttons.push({ + buttonId: `#`, + buttonText: { displayText: "Menu inicial *[ 0 ]* Menu anterior" }, + type: 4 + }); + + const buttonMessage = { + text: formatBody(`\u200e${queue.greetingMessage}`, ticket.contact), + buttons, + headerType: 4 + }; + + const sendMsg = await wbot.sendMessage( + `${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, + buttonMessage + ); + + await verifyMessage(sendMsg, ticket, ticket.contact); + } + + const botText = async () => { + let options = ""; + + queueOptions.forEach((option, i) => { + options += `*[ ${option.option} ]* - ${option.title}\n`; + }); + //options += `\n*[ 0 ]* - Menu anterior`; + options += `\n*[ # ]* - Menu inicial`; + + const textMessage = { + text: formatBody(`\u200e${queue.greetingMessage}\n\n${options}`, ticket.contact), + }; + + const sendMsg = await wbot.sendMessage( + `${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, + textMessage + ); + + await verifyMessage(sendMsg, ticket, ticket.contact); + }; + + // if (buttonActive.value === "list") { + // return botList(); + // }; + + if (buttonActive.value === "button" && QueueOption.length <= 4) { + return botButton(); + } + + if (buttonActive.value === "text") { + return botText(); + } + + if (buttonActive.value === "button" && QueueOption.length > 4) { + return botText(); + } + } else if (!isNil(queue) && !isNil(ticket.queueOptionId)) { + const currentOption = await QueueOption.findByPk(ticket.queueOptionId); + const queueOptions = await QueueOption.findAll({ + where: { parentId: ticket.queueOptionId }, + order: [ + ["option", "ASC"], + ["createdAt", "ASC"], + ], + }); + + if (queueOptions.length > -1) { + + const companyId = ticket.companyId; + const buttonActive = await Setting.findOne({ + where: { + key: "chatBotType", + companyId + } + }); + + const botList = async () => { + const sectionsRows = []; + + queueOptions.forEach((option, i) => { + sectionsRows.push({ + title: option.title, + rowId: `${option.option}` + }); + }); + sectionsRows.push({ + title: "Menu inicial *[ 0 ]* Menu anterior", + rowId: `#` + }); + const sections = [ + { + rows: sectionsRows + } + ]; + + const listMessage = { + text: formatBody(`\u200e${currentOption.message}`, ticket.contact), + buttonText: "Escolha uma opção", + sections + }; + + const sendMsg = await wbot.sendMessage( + `${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, + listMessage + ); + + await verifyMessage(sendMsg, ticket, ticket.contact); + } + + const botButton = async () => { + const buttons = []; + queueOptions.forEach((option, i) => { + buttons.push({ + buttonId: `${option.option}`, + buttonText: { displayText: option.title }, + type: 4 + }); + }); + buttons.push({ + buttonId: `#`, + buttonText: { displayText: "Menu inicial *[ 0 ]* Menu anterior" }, + type: 4 + }); + + const buttonMessage = { + text: formatBody(`\u200e${currentOption.message}`, ticket.contact), + buttons, + headerType: 4 + }; + + const sendMsg = await wbot.sendMessage( + `${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, + buttonMessage + ); + + await verifyMessage(sendMsg, ticket, ticket.contact); + } + + const botText = async () => { + + let options = ""; + + queueOptions.forEach((option, i) => { + options += `*[ ${option.option} ]* - ${option.title}\n`; + }); + options += `\n*[ 0 ]* - Menu anterior`; + options += `\n*[ # ]* - Menu inicial`; + const textMessage = { + text: formatBody(`\u200e${currentOption.message}\n\n${options}`, ticket.contact), + }; + + const sendMsg = await wbot.sendMessage( + `${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net"}`, + textMessage + ); + + await verifyMessage(sendMsg, ticket, ticket.contact); + }; + + if (buttonActive.value === "list") { + return botList(); + }; + + if (buttonActive.value === "button" && QueueOption.length <= 4) { + return botButton(); + } + + if (buttonActive.value === "text") { + return botText(); + } + + if (buttonActive.value === "button" && QueueOption.length > 4) { + return botText(); + } + } + } +} + +export const handleMessageIntegration = async ( + msg: proto.IWebMessageInfo, + wbot: Session, + queueIntegration: QueueIntegrations, + ticket: Ticket +): Promise => { + const msgType = getTypeMessage(msg); + + if (queueIntegration.type === "n8n" || queueIntegration.type === "webhook") { + if (queueIntegration?.urlN8N) { + const options = { + method: "POST", + url: queueIntegration?.urlN8N, + headers: { + "Content-Type": "application/json" + }, + json: msg + }; + try { + request(options, function (error, response) { + if (error) { + throw new Error(error); + } + else { + console.log(response.body); + } + }); + } catch (error) { + throw new Error(error); + } + } + + } else if (queueIntegration.type === "typebot") { + console.log("entrou no typebot") + // await typebots(ticket, msg, wbot, queueIntegration); + await typebotListener({ ticket, msg, wbot, typebot: queueIntegration }); + + } +} + +const handleMessage = async ( + msg: proto.IWebMessageInfo, + wbot: Session, + companyId: number +): Promise => { + + let mediaSent: Message | undefined; + + if (!isValidMsg(msg)) return; + try { + let msgContact: IMe; + let groupContact: Contact | undefined; + + const isGroup = msg.key.remoteJid?.endsWith("@g.us"); + + const msgIsGroupBlock = await Setting.findOne({ + where: { + companyId, + key: "CheckMsgIsGroup", + }, + }); + + const bodyMessage = getBodyMessage(msg); + const msgType = getTypeMessage(msg); + + const hasMedia = + msg.message?.audioMessage || + msg.message?.imageMessage || + msg.message?.videoMessage || + msg.message?.documentMessage || + msg.message?.documentWithCaptionMessage || + msg.message.stickerMessage; + if (msg.key.fromMe) { + if (/\u200e/.test(bodyMessage)) return; + + if ( + !hasMedia && + msgType !== "conversation" && + msgType !== "extendedTextMessage" && + msgType !== "vcard" + ) + return; + msgContact = await getContactMessage(msg, wbot); + } else { + msgContact = await getContactMessage(msg, wbot); + } + + if (msgIsGroupBlock?.value === "enabled" && isGroup) return; + + if (isGroup) { + const grupoMeta = await wbot.groupMetadata(msg.key.remoteJid); + const msgGroupContact = { + id: grupoMeta.id, + name: grupoMeta.subject + }; + groupContact = await verifyContact(msgGroupContact, wbot, companyId); + } + + const whatsapp = await ShowWhatsAppService(wbot.id!, companyId); + const contact = await verifyContact(msgContact, wbot, companyId); + + let unreadMessages = 0; + + + if (msg.key.fromMe) { + await cacheLayer.set(`contacts:${contact.id}:unreads`, "0"); + } else { + const unreads = await cacheLayer.get(`contacts:${contact.id}:unreads`); + unreadMessages = +unreads + 1; + await cacheLayer.set( + `contacts:${contact.id}:unreads`, + `${unreadMessages}` + ); + } + + const lastMessage = await Message.findOne({ + where: { + contactId: contact.id, + companyId, + }, + order: [["createdAt", "DESC"]], + }); + + if (unreadMessages === 0 && whatsapp.complationMessage && formatBody(whatsapp.complationMessage, contact).trim().toLowerCase() === lastMessage?.body.trim().toLowerCase()) { + return; + } + + const ticket = await FindOrCreateTicketService(contact, wbot.id!, unreadMessages, companyId, groupContact); + + + + await provider(ticket, msg, companyId, contact, wbot as WASocket); + + // voltar para o menu inicial + + if (bodyMessage == "#") { + await ticket.update({ + queueOptionId: null, + chatbot: false, + queueId: null, + }); + await verifyQueue(wbot, msg, ticket, ticket.contact); + return; + } + + + const ticketTraking = await FindOrCreateATicketTrakingService({ + ticketId: ticket.id, + companyId, + whatsappId: whatsapp?.id + }); + + try { + if (!msg.key.fromMe) { + /** + * Tratamento para avaliação do atendente + */ + + // // dev Ricardo: insistir a responder avaliação + // const rate_ = Number(bodyMessage); + + // if ((ticket?.lastMessage.includes('_Insatisfeito_') || ticket?.lastMessage.includes('Por favor avalie nosso atendimento.')) && (!isFinite(rate_))) { + // const debouncedSentMessage = debounce( + // async () => { + // await wbot.sendMessage( + // `${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net" + // }`, + // { + // text: 'Por favor avalie nosso atendimento.' + // } + // ); + // }, + // 1000, + // ticket.id + // ); + // debouncedSentMessage(); + // return; + // } + // // dev Ricardo + + if (ticketTraking !== null && verifyRating(ticketTraking)) { + + handleRating(parseFloat(bodyMessage), ticket, ticketTraking); + return; + } + } + } catch (e) { + Sentry.captureException(e); + console.log(e); + } + + // Atualiza o ticket se a ultima mensagem foi enviada por mim, para que possa ser finalizado. + try { + await ticket.update({ + fromMe: msg.key.fromMe, + }); + } catch (e) { + Sentry.captureException(e); + console.log(e); + } + + if (hasMedia) { + mediaSent = await verifyMediaMessage(msg, ticket, contact); + } else { + await verifyMessage(msg, ticket, contact); + } + + const currentSchedule = await VerifyCurrentSchedule(companyId); + const scheduleType = await Setting.findOne({ + where: { + companyId, + key: "scheduleType" + } + }); + + + try { + if (!msg.key.fromMe && scheduleType) { + /** + * Tratamento para envio de mensagem quando a empresa está fora do expediente + */ + if ( + scheduleType.value === "company" && + !isNil(currentSchedule) && + (!currentSchedule || currentSchedule.inActivity === false) + ) { + const body = `\u200e ${whatsapp.outOfHoursMessage}`; + + const debouncedSentMessage = debounce( + async () => { + await wbot.sendMessage( + `${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net" + }`, + { + text: body + } + ); + }, + 3000, + ticket.id + ); + debouncedSentMessage(); + return; + } + + + if (scheduleType.value === "queue" && ticket.queueId !== null) { + + /** + * Tratamento para envio de mensagem quando a fila está fora do expediente + */ + const queue = await Queue.findByPk(ticket.queueId); + + const { schedules }: any = queue; + const now = moment(); + const weekday = now.format("dddd").toLowerCase(); + let schedule = null; + + if (Array.isArray(schedules) && schedules.length > 0) { + schedule = schedules.find( + s => + s.weekdayEn === weekday && + s.startTime !== "" && + s.startTime !== null && + s.endTime !== "" && + s.endTime !== null + ); + } + + if ( + scheduleType.value === "queue" && + queue.outOfHoursMessage !== null && + queue.outOfHoursMessage !== "" && + !isNil(schedule) + ) { + const startTime = moment(schedule.startTime, "HH:mm"); + const endTime = moment(schedule.endTime, "HH:mm"); + + if (now.isBefore(startTime) || now.isAfter(endTime)) { + const body = `${queue.outOfHoursMessage}`; + const debouncedSentMessage = debounce( + async () => { + await wbot.sendMessage( + `${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net" + }`, + { + text: body + } + ); + }, + 3000, + ticket.id + ); + debouncedSentMessage(); + return; + } + } + } + + } + } catch (e) { + Sentry.captureException(e); + console.log(e); + } + + try { + if (!msg.key.fromMe) { + if (ticketTraking !== null && verifyRating(ticketTraking)) { + handleRating(parseFloat(bodyMessage), ticket, ticketTraking); + return; + } + } + } catch (e) { + Sentry.captureException(e); + console.log(e); + } + + //openai na conexao + if ( + !ticket.queue && + !isGroup && + !msg.key.fromMe && + !ticket.userId && + !isNil(whatsapp.promptId) + ) { + await handleOpenAi(msg, wbot, ticket, contact, mediaSent); + } + + //integraçao na conexao + if ( + !msg.key.fromMe && + !ticket.isGroup && + !ticket.queue && + !ticket.user && + ticket.chatbot && + !isNil(whatsapp.integrationId) && + !ticket.useIntegration + ) { + + const integrations = await ShowQueueIntegrationService(whatsapp.integrationId, companyId); + + await handleMessageIntegration(msg, wbot, integrations, ticket) + + return + } + + //openai na fila + if ( + !isGroup && + !msg.key.fromMe && + !ticket.userId && + !isNil(ticket.promptId) && + ticket.useIntegration && + ticket.queueId + + ) { + await handleOpenAi(msg, wbot, ticket, contact, mediaSent); + } + + if ( + !msg.key.fromMe && + !ticket.isGroup && + !ticket.userId && + ticket.integrationId && + ticket.useIntegration && + ticket.queue + ) { + + console.log("entrou no type 1974") + const integrations = await ShowQueueIntegrationService(ticket.integrationId, companyId); + + await handleMessageIntegration(msg, wbot, integrations, ticket) + + } + + if ( + !ticket.queue && + !ticket.isGroup && + !msg.key.fromMe && + !ticket.userId && + whatsapp.queues.length >= 1 && + !ticket.useIntegration + ) { + + await verifyQueue(wbot, msg, ticket, contact); + + if (ticketTraking.chatbotAt === null) { + await ticketTraking.update({ + chatbotAt: moment().toDate(), + }) + } + } + + const dontReadTheFirstQuestion = ticket.queue === null; + + await ticket.reload(); + + try { + //Fluxo fora do expediente + if (!msg.key.fromMe && scheduleType && ticket.queueId !== null) { + /** + * Tratamento para envio de mensagem quando a fila está fora do expediente + */ + const queue = await Queue.findByPk(ticket.queueId); + + const { schedules }: any = queue; + const now = moment(); + const weekday = now.format("dddd").toLowerCase(); + let schedule = null; + + if (Array.isArray(schedules) && schedules.length > 0) { + schedule = schedules.find( + s => + s.weekdayEn === weekday && + s.startTime !== "" && + s.startTime !== null && + s.endTime !== "" && + s.endTime !== null + ); + } + + if ( + scheduleType.value === "queue" && + queue.outOfHoursMessage !== null && + queue.outOfHoursMessage !== "" && + !isNil(schedule) + ) { + const startTime = moment(schedule.startTime, "HH:mm"); + const endTime = moment(schedule.endTime, "HH:mm"); + + if (now.isBefore(startTime) || now.isAfter(endTime)) { + const body = queue.outOfHoursMessage; + const debouncedSentMessage = debounce( + async () => { + await wbot.sendMessage( + `${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net" + }`, + { + text: body + } + ); + }, + 3000, + ticket.id + ); + debouncedSentMessage(); + return; + } + } + } + } catch (e) { + Sentry.captureException(e); + console.log(e); + } + + + + if (!whatsapp?.queues?.length && !ticket.userId && !isGroup && !msg.key.fromMe) { + + const lastMessage = await Message.findOne({ + where: { + ticketId: ticket.id, + fromMe: true + }, + order: [["createdAt", "DESC"]] + }); + + if (lastMessage && lastMessage.body.includes(whatsapp.greetingMessage)) { + return; + } + + if (whatsapp.greetingMessage) { + + const debouncedSentMessage = debounce( + async () => { + await wbot.sendMessage( + `${ticket.contact.number}@${ticket.isGroup ? "g.us" : "s.whatsapp.net" + }`, + { + text: whatsapp.greetingMessage + } + ); + }, + 1000, + ticket.id + ); + debouncedSentMessage(); + return; + } + + } + + + if (whatsapp.queues.length == 1 && ticket.queue) { + if (ticket.chatbot && !msg.key.fromMe) { + await handleChartbot(ticket, msg, wbot); + } + } + if (whatsapp.queues.length > 1 && ticket.queue) { + if (ticket.chatbot && !msg.key.fromMe) { + await handleChartbot(ticket, msg, wbot, dontReadTheFirstQuestion); + } + } + + } catch (err) { + console.log(err) + Sentry.captureException(err); + logger.error(`Error handling whatsapp message: Err: ${err}`); + } +}; + +const handleMsgAck = async ( + msg: WAMessage, + chat: number | null | undefined +) => { + await new Promise((r) => setTimeout(r, 500)); + const io = getIO(); + + try { + const messageToUpdate = await Message.findByPk(msg.key.id, { + include: [ + "contact", + { + model: Message, + as: "quotedMsg", + include: ["contact"], + }, + ], + }); + + if (!messageToUpdate) return; + await messageToUpdate.update({ ack: chat }); + io.to(messageToUpdate.ticketId.toString()).emit( + `company-${messageToUpdate.companyId}-appMessage`, + { + action: "update", + message: messageToUpdate, + } + ); + } catch (err) { + Sentry.captureException(err); + logger.error(`Error handling message ack. Err: ${err}`); + } +}; + +const verifyRecentCampaign = async ( + message: proto.IWebMessageInfo, + companyId: number +) => { + if (!message.key.fromMe) { + const number = message.key.remoteJid.replace(/\D/g, ""); + const campaigns = await Campaign.findAll({ + where: { companyId, status: "EM_ANDAMENTO", confirmation: true }, + }); + if (campaigns) { + const ids = campaigns.map((c) => c.id); + const campaignShipping = await CampaignShipping.findOne({ + where: { campaignId: { [Op.in]: ids }, number, confirmation: null }, + }); + + if (campaignShipping) { + await campaignShipping.update({ + confirmedAt: moment(), + confirmation: true, + }); + await campaignQueue.add( + "DispatchCampaign", + { + campaignShippingId: campaignShipping.id, + campaignId: campaignShipping.campaignId, + }, + { + delay: parseToMilliseconds(randomValue(0, 10)), + } + ); + } + } + } +}; + +const verifyCampaignMessageAndCloseTicket = async ( + message: proto.IWebMessageInfo, + companyId: number +) => { + const io = getIO(); + const body = getBodyMessage(message); + const isCampaign = /\u200c/.test(body); + if (message.key.fromMe && isCampaign) { + const messageRecord = await Message.findOne({ + where: { id: message.key.id!, companyId }, + }); + const ticket = await Ticket.findByPk(messageRecord.ticketId); + await ticket.update({ status: "closed" }); + + io.to(`company-${ticket.companyId}-open`) + .to(`queue-${ticket.queueId}-open`) + .emit(`company-${ticket.companyId}-ticket`, { + action: "delete", + ticket, + ticketId: ticket.id, + }); + + io.to(`company-${ticket.companyId}-${ticket.status}`) + .to(`queue-${ticket.queueId}-${ticket.status}`) + .to(ticket.id.toString()) + .emit(`company-${ticket.companyId}-ticket`, { + action: "update", + ticket, + ticketId: ticket.id, + }); + } +}; + +const filterMessages = (msg: WAMessage): boolean => { + if (msg.message?.protocolMessage) return false; + + if ( + [ + WAMessageStubType.REVOKE, + WAMessageStubType.E2E_DEVICE_CHANGED, + WAMessageStubType.E2E_IDENTITY_CHANGED, + WAMessageStubType.CIPHERTEXT + ].includes(msg.messageStubType as WAMessageStubType) + ) + return false; + + return true; +}; + +const wbotMessageListener = async (wbot: Session, companyId: number): Promise => { + try { + wbot.ev.on("messages.upsert", async (messageUpsert: ImessageUpsert) => { + const messages = messageUpsert.messages + .filter(filterMessages) + .map(msg => msg); + + if (!messages) return; + + messages.forEach(async (message: proto.IWebMessageInfo) => { + + const messageExists = await Message.count({ + where: { id: message.key.id!, companyId } + }); + + if (!messageExists) { + await handleMessage(message, wbot, companyId); + await verifyRecentCampaign(message, companyId); + await verifyCampaignMessageAndCloseTicket(message, companyId); + } + }); + }); + + wbot.ev.on("messages.update", (messageUpdate: WAMessageUpdate[]) => { + if (messageUpdate.length === 0) return; + messageUpdate.forEach(async (message: WAMessageUpdate) => { + (wbot as WASocket)!.readMessages([message.key]) + + handleMsgAck(message, message.update.status); + }); + }); + + // wbot.ev.on("messages.set", async (messageSet: IMessage) => { + // messageSet.messages.filter(filterMessages).map(msg => msg); + // }); + } catch (error) { + Sentry.captureException(error); + logger.error(`Error handling wbot message listener. Err: ${error}`); + } +}; + +export { wbotMessageListener, handleMessage }; diff --git a/backend/src/services/WbotServices/wbotMonitor.ts b/backend/src/services/WbotServices/wbotMonitor.ts new file mode 100644 index 0000000..cb2115c --- /dev/null +++ b/backend/src/services/WbotServices/wbotMonitor.ts @@ -0,0 +1,117 @@ +import { + WASocket, + BinaryNode, + Contact as BContact, +} from "@whiskeysockets/baileys"; +import * as Sentry from "@sentry/node"; + +import { Op } from "sequelize"; +// import { getIO } from "../../libs/socket"; +import { Store } from "../../libs/store"; +import Contact from "../../models/Contact"; +import Setting from "../../models/Setting"; +import Ticket from "../../models/Ticket"; +import Whatsapp from "../../models/Whatsapp"; +import { logger } from "../../utils/logger"; +import createOrUpdateBaileysService from "../BaileysServices/CreateOrUpdateBaileysService"; +import CreateMessageService from "../MessageServices/CreateMessageService"; + +type Session = WASocket & { + id?: number; + store?: Store; +}; + +interface IContact { + contacts: BContact[]; +} + +const wbotMonitor = async ( + wbot: Session, + whatsapp: Whatsapp, + companyId: number +): Promise => { + try { + wbot.ws.on("CB:call", async (node: BinaryNode) => { + const content = node.content[0] as any; + + if (content.tag === "offer") { + const { from, id } = node.attrs; + + } + + if (content.tag === "terminate") { + const sendMsgCall = await Setting.findOne({ + where: { key: "call", companyId }, + }); + + if (sendMsgCall.value === "disabled") { + await wbot.sendMessage(node.attrs.from, { + text: + "*Mensagem Automática:*\n\nAs chamadas de voz e vídeo estão desabilitas para esse WhatsApp, favor enviar uma mensagem de texto. Obrigado", + }); + + const number = node.attrs.from.replace(/\D/g, ""); + + const contact = await Contact.findOne({ + where: { companyId, number }, + }); + + const ticket = await Ticket.findOne({ + where: { + contactId: contact.id, + whatsappId: wbot.id, + //status: { [Op.or]: ["close"] }, + companyId + }, + }); + // se não existir o ticket não faz nada. + if (!ticket) return; + + const date = new Date(); + const hours = date.getHours(); + const minutes = date.getMinutes(); + + const body = `Chamada de voz/vídeo perdida às ${hours}:${minutes}`; + const messageData = { + id: content.attrs["call-id"], + ticketId: ticket.id, + contactId: contact.id, + body, + fromMe: false, + mediaType: "call_log", + read: true, + quotedMsgId: null, + ack: 1, + }; + + await ticket.update({ + lastMessage: body, + }); + + + if(ticket.status === "closed") { + await ticket.update({ + status: "pending", + }); + } + + return CreateMessageService({ messageData, companyId: companyId }); + } + } + }); + + wbot.ev.on("contacts.upsert", async (contacts: BContact[]) => { + + await createOrUpdateBaileysService({ + whatsappId: whatsapp.id, + contacts, + }); + }); + + } catch (err) { + Sentry.captureException(err); + logger.error(err); + } +}; + +export default wbotMonitor; diff --git a/backend/src/services/WhatsappService/AssociateWhatsappQueue.ts b/backend/src/services/WhatsappService/AssociateWhatsappQueue.ts new file mode 100644 index 0000000..5f840f7 --- /dev/null +++ b/backend/src/services/WhatsappService/AssociateWhatsappQueue.ts @@ -0,0 +1,12 @@ +import Whatsapp from "../../models/Whatsapp"; + +const AssociateWhatsappQueue = async ( + whatsapp: Whatsapp, + queueIds: number[] +): Promise => { + await whatsapp.$set("queues", queueIds); + + await whatsapp.reload(); +}; + +export default AssociateWhatsappQueue; diff --git a/backend/src/services/WhatsappService/CreateWhatsAppService.ts b/backend/src/services/WhatsappService/CreateWhatsAppService.ts new file mode 100644 index 0000000..3073a25 --- /dev/null +++ b/backend/src/services/WhatsappService/CreateWhatsAppService.ts @@ -0,0 +1,178 @@ +import * as Yup from "yup"; + +import AppError from "../../errors/AppError"; +import Whatsapp from "../../models/Whatsapp"; +import Company from "../../models/Company"; +import Plan from "../../models/Plan"; +import AssociateWhatsappQueue from "./AssociateWhatsappQueue"; + +interface Request { + name: string; + companyId: number; + queueIds?: number[]; + greetingMessage?: string; + complationMessage?: string; + outOfHoursMessage?: string; + ratingMessage?: string; + status?: string; + isDefault?: boolean; + token?: string; + provider?: string; + //sendIdQueue?: number; + //timeSendQueue?: number; + transferQueueId?: number; + timeToTransfer?: number; + promptId?: number; + maxUseBotQueues?: number; + timeUseBotQueues?: number; + expiresTicket?: number; + expiresInactiveMessage?: string; +} + +interface Response { + whatsapp: Whatsapp; + oldDefaultWhatsapp: Whatsapp | null; +} + +const CreateWhatsAppService = async ({ + name, + status = "OPENING", + queueIds = [], + greetingMessage, + complationMessage, + outOfHoursMessage, + ratingMessage, + isDefault = false, + companyId, + token = "", + provider = "beta", + //timeSendQueue, + //sendIdQueue, + transferQueueId, + timeToTransfer, + promptId, + maxUseBotQueues = 3, + timeUseBotQueues = 0, + expiresTicket = 0, + expiresInactiveMessage = "" +}: Request): Promise => { + const company = await Company.findOne({ + where: { + id: companyId + }, + include: [{ model: Plan, as: "plan" }] + }); + + if (company !== null) { + const whatsappCount = await Whatsapp.count({ + where: { + companyId + } + }); + + if (whatsappCount >= company.plan.connections) { + throw new AppError( + `Número máximo de conexões já alcançado: ${whatsappCount}` + ); + } + } + + const schema = Yup.object().shape({ + name: Yup.string() + .required() + .min(2) + .test( + "Check-name", + "Esse nome já está sendo utilizado por outra conexão", + async value => { + if (!value) return false; + const nameExists = await Whatsapp.findOne({ + where: { name: value } + }); + return !nameExists; + } + ), + isDefault: Yup.boolean().required() + }); + + try { + await schema.validate({ name, status, isDefault }); + } catch (err: any) { + throw new AppError(err.message); + } + + const whatsappFound = await Whatsapp.findOne({ where: { companyId } }); + + isDefault = !whatsappFound; + + let oldDefaultWhatsapp: Whatsapp | null = null; + + if (isDefault) { + oldDefaultWhatsapp = await Whatsapp.findOne({ + where: { isDefault: true, companyId } + }); + if (oldDefaultWhatsapp) { + await oldDefaultWhatsapp.update({ isDefault: false, companyId }); + } + } + + if (queueIds.length > 1 && !greetingMessage) { + throw new AppError("ERR_WAPP_GREETING_REQUIRED"); + } + + if (token !== null && token !== "") { + const tokenSchema = Yup.object().shape({ + token: Yup.string() + .required() + .min(2) + .test( + "Check-token", + "This whatsapp token is already used.", + async value => { + if (!value) return false; + const tokenExists = await Whatsapp.findOne({ + where: { token: value } + }); + return !tokenExists; + } + ) + }); + + try { + await tokenSchema.validate({ token }); + } catch (err: any) { + throw new AppError(err.message); + } + } + + const whatsapp = await Whatsapp.create( + { + name, + status, + greetingMessage, + complationMessage, + outOfHoursMessage, + ratingMessage, + isDefault, + companyId, + token, + provider, + //timeSendQueue, + //sendIdQueue, + transferQueueId, + timeToTransfer, + promptId, + maxUseBotQueues, + timeUseBotQueues, + expiresTicket, + expiresInactiveMessage + }, + { include: ["queues"] } + ); + + await AssociateWhatsappQueue(whatsapp, queueIds); + + return { whatsapp, oldDefaultWhatsapp }; +}; + +export default CreateWhatsAppService; diff --git a/backend/src/services/WhatsappService/DeleteWhatsAppService.ts b/backend/src/services/WhatsappService/DeleteWhatsAppService.ts new file mode 100644 index 0000000..ff516b8 --- /dev/null +++ b/backend/src/services/WhatsappService/DeleteWhatsAppService.ts @@ -0,0 +1,16 @@ +import Whatsapp from "../../models/Whatsapp"; +import AppError from "../../errors/AppError"; + +const DeleteWhatsAppService = async (id: string): Promise => { + const whatsapp = await Whatsapp.findOne({ + where: { id } + }); + + if (!whatsapp) { + throw new AppError("ERR_NO_WAPP_FOUND", 404); + } + + await whatsapp.destroy(); +}; + +export default DeleteWhatsAppService; diff --git a/backend/src/services/WhatsappService/ListWhatsAppsService.ts b/backend/src/services/WhatsappService/ListWhatsAppsService.ts new file mode 100644 index 0000000..e1e51a7 --- /dev/null +++ b/backend/src/services/WhatsappService/ListWhatsAppsService.ts @@ -0,0 +1,36 @@ +import { FindOptions } from "sequelize/types"; +import Queue from "../../models/Queue"; +import Whatsapp from "../../models/Whatsapp"; + +interface Request { + companyId: number; + session?: number | string; +} + +const ListWhatsAppsService = async ({ + session, + companyId +}: Request): Promise => { + const options: FindOptions = { + where: { + companyId + }, + include: [ + { + model: Queue, + as: "queues", + attributes: ["id", "name", "color", "greetingMessage"] + } + ] + }; + + if (session !== undefined && session == 0) { + options.attributes = { exclude: ["session"] }; + } + + const whatsapps = await Whatsapp.findAll(options); + + return whatsapps; +}; + +export default ListWhatsAppsService; diff --git a/backend/src/services/WhatsappService/ShowWhatsAppService.ts b/backend/src/services/WhatsappService/ShowWhatsAppService.ts new file mode 100644 index 0000000..7a1751d --- /dev/null +++ b/backend/src/services/WhatsappService/ShowWhatsAppService.ts @@ -0,0 +1,46 @@ +import Whatsapp from "../../models/Whatsapp"; +import AppError from "../../errors/AppError"; +import Queue from "../../models/Queue"; +import QueueOption from "../../models/QueueOption"; +import { FindOptions } from "sequelize/types"; +import Prompt from "../../models/Prompt"; + +const ShowWhatsAppService = async ( + id: string | number, + companyId: number, + session?: any +): Promise => { + const findOptions: FindOptions = { + include: [ + { + model: Queue, + as: "queues", + attributes: ["id", "name", "color", "greetingMessage", "integrationId", "promptId"], + include: [{ model: QueueOption, as: "options" }] + }, + { + model: Prompt, + as: "prompt", + } + ], + order: [["queues", "orderQueue", "ASC"]] + }; + + if (session !== undefined && session == 0) { + findOptions.attributes = { exclude: ["session"] }; + } + + const whatsapp = await Whatsapp.findByPk(id, findOptions); + + if (whatsapp?.companyId !== companyId) { + throw new AppError("Não é possível acessar registros de outra empresa"); + } + + if (!whatsapp) { + throw new AppError("ERR_NO_WAPP_FOUND", 404); + } + + return whatsapp; +}; + +export default ShowWhatsAppService; diff --git a/backend/src/services/WhatsappService/UpdateWhatsAppService.ts b/backend/src/services/WhatsappService/UpdateWhatsAppService.ts new file mode 100644 index 0000000..f42fd80 --- /dev/null +++ b/backend/src/services/WhatsappService/UpdateWhatsAppService.ts @@ -0,0 +1,130 @@ +import * as Yup from "yup"; +import { Op } from "sequelize"; + +import AppError from "../../errors/AppError"; +import Whatsapp from "../../models/Whatsapp"; +import ShowWhatsAppService from "./ShowWhatsAppService"; +import AssociateWhatsappQueue from "./AssociateWhatsappQueue"; + +interface WhatsappData { + name?: string; + status?: string; + session?: string; + isDefault?: boolean; + greetingMessage?: string; + complationMessage?: string; + outOfHoursMessage?: string; + ratingMessage?: string; + queueIds?: number[]; + token?: string; + //sendIdQueue?: number; + //timeSendQueue?: number; + transferQueueId?: number; + timeToTransfer?: number; + promptId?: number; + maxUseBotQueues?: number; + timeUseBotQueues?: number; + expiresTicket?: number; + expiresInactiveMessage?: string; + +} + +interface Request { + whatsappData: WhatsappData; + whatsappId: string; + companyId: number; +} + +interface Response { + whatsapp: Whatsapp; + oldDefaultWhatsapp: Whatsapp | null; +} + +const UpdateWhatsAppService = async ({ + whatsappData, + whatsappId, + companyId +}: Request): Promise => { + const schema = Yup.object().shape({ + name: Yup.string().min(2), + status: Yup.string(), + isDefault: Yup.boolean() + }); + + const { + name, + status, + isDefault, + session, + greetingMessage, + complationMessage, + outOfHoursMessage, + ratingMessage, + queueIds = [], + token, + //timeSendQueue, + //sendIdQueue = null, + transferQueueId, + timeToTransfer, + promptId, + maxUseBotQueues, + timeUseBotQueues, + expiresTicket, + expiresInactiveMessage + } = whatsappData; + + try { + await schema.validate({ name, status, isDefault }); + } catch (err: any) { + throw new AppError(err.message); + } + + if (queueIds.length > 1 && !greetingMessage) { + throw new AppError("ERR_WAPP_GREETING_REQUIRED"); + } + + let oldDefaultWhatsapp: Whatsapp | null = null; + + if (isDefault) { + oldDefaultWhatsapp = await Whatsapp.findOne({ + where: { + isDefault: true, + id: { [Op.not]: whatsappId }, + companyId + } + }); + if (oldDefaultWhatsapp) { + await oldDefaultWhatsapp.update({ isDefault: false }); + } + } + + const whatsapp = await ShowWhatsAppService(whatsappId, companyId); + + await whatsapp.update({ + name, + status, + session, + greetingMessage, + complationMessage, + outOfHoursMessage, + ratingMessage, + isDefault, + companyId, + token, + //timeSendQueue, + //sendIdQueue, + transferQueueId, + timeToTransfer, + promptId, + maxUseBotQueues, + timeUseBotQueues, + expiresTicket, + expiresInactiveMessage + }); + + await AssociateWhatsappQueue(whatsapp, queueIds); + + return { whatsapp, oldDefaultWhatsapp }; +}; + +export default UpdateWhatsAppService; diff --git a/backend/src/utils/logger.ts b/backend/src/utils/logger.ts new file mode 100644 index 0000000..0a499eb --- /dev/null +++ b/backend/src/utils/logger.ts @@ -0,0 +1,14 @@ +import pino from "pino"; + +const logger = pino({ + transport: { + target: 'pino-pretty', + options: { + levelFirst: true, + translateTime: true, + colorize: true, + } + } +}); + +export { logger }; diff --git a/backend/src/wbotTransferTicketQueue.ts b/backend/src/wbotTransferTicketQueue.ts new file mode 100644 index 0000000..1bd32ba --- /dev/null +++ b/backend/src/wbotTransferTicketQueue.ts @@ -0,0 +1,82 @@ +import { Op } from "sequelize"; +import TicketTraking from "./models/TicketTraking"; +import { format } from "date-fns"; +import moment from "moment"; +import Ticket from "./models/Ticket"; +import Whatsapp from "./models/Whatsapp"; +import { getIO } from "./libs/socket"; +import { logger } from "./utils/logger"; +import ShowTicketService from "./services/TicketServices/ShowTicketService"; + + +export const TransferTicketQueue = async (): Promise => { + + const io = getIO(); + + //buscar os tickets que em pendentes e sem fila + const tickets = await Ticket.findAll({ + where: { + status: "pending", + queueId: { + [Op.is]: null + }, + }, + + }); + + // varrer os tickets e verificar se algum deles está com o tempo estourado + tickets.forEach(async ticket => { + + + + const wpp = await Whatsapp.findOne({ + where: { + id: ticket.whatsappId + } + }); + + if (!wpp || !wpp.timeToTransfer || !wpp.transferQueueId || wpp.timeToTransfer == 0) return; + + let dataLimite = new Date(ticket.updatedAt); + dataLimite.setMinutes(dataLimite.getMinutes() + wpp.timeToTransfer); + + if (new Date() > dataLimite) { + + await ticket.update({ + + queueId: wpp.transferQueueId, + + }); + + const ticketTraking = await TicketTraking.findOne({ + where: { + ticketId: ticket.id + }, + order: [["createdAt", "DESC"]] + }); + + await ticketTraking.update({ + queuedAt: moment().toDate(), + queueId: wpp.transferQueueId, + }); + + const currentTicket = await ShowTicketService(ticket.id, ticket.companyId); + + io.to(ticket.status) + .to("notification") + .to(ticket.id.toString()) + .emit(`company-${ticket.companyId}-ticket`, { + action: "update", + ticket: currentTicket, + traking: "created ticket 33" + }); + + logger.info(`Transferencia de ticket automatica ticket id ${ticket.id} para a fila ${wpp.transferQueueId}`); + + } + + + }); + + +} diff --git a/backend/tsconfig.json b/backend/tsconfig.json new file mode 100644 index 0000000..4a869e4 --- /dev/null +++ b/backend/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "es2020", + "module": "commonjs", + "outDir": "./dist", + "strict": false, + "strictPropertyInitialization": false, + "esModuleInterop": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true + } +} diff --git a/frontend/.DS_Store b/frontend/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..6d5c9df656579074ab60dc3779e2706be7577707 GIT binary patch literal 6148 zcmeHKO>fgc5S>lZ)}}=Y5*1vKEO8AbrBc<3iwWhx6(cwR3U+K2Q`Z~WadU_w`C9l7 z`~{Bu6aEV)cssk15{F(Zigu*gH@iD;KVIbBED?!874H*uiO7K~?A$`}7gPPp*Q{k) zT%h1F;+L5mMVXA&a&3cEz$)MRQzM?c0)SCM%kjV{3jYyLX?SW z#`id#gs;(-RspNPsse3Y?W+6##ntcsRg$e)1*`)9l>(x35}XXMC3Cl~ZBE^_9{eL* pnaZm*G6jXXjyX_Q@qIWO`aBf?eS@_|w7~2i0hYlQR)K3(;1AbLs2~6U literal 0 HcmV?d00001 diff --git a/frontend/.env.exemple b/frontend/.env.exemple new file mode 100644 index 0000000..4d65288 --- /dev/null +++ b/frontend/.env.exemple @@ -0,0 +1,2 @@ +REACT_APP_BACKEND_URL=https://url front +REACT_APP_HOURS_CLOSE_TICKETS_AUTO = 24 diff --git a/frontend/package-lock.json b/frontend/package-lock.json new file mode 100644 index 0000000..b8c74ae --- /dev/null +++ b/frontend/package-lock.json @@ -0,0 +1,26964 @@ +{ + "name": "frontend", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "frontend", + "version": "0.1.0", + "dependencies": { + "@date-io/date-fns": "^2.14.0", + "@emotion/styled": "^11.10.6", + "@material-ui/core": "4.12.3", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "^4.0.0-alpha.56", + "@material-ui/pickers": "^3.3.10", + "@material-ui/styles": "^4.11.5", + "@mui/material": "^5.10.13", + "@mui/x-date-pickers": "^6.0.1", + "@testing-library/jest-dom": "^5.11.4", + "@testing-library/react": "^11.0.4", + "@testing-library/user-event": "^12.1.7", + "axios": "^0.21.1", + "bootstrap": "^5.2.3", + "chart.js": "^3.9.1", + "chartjs-plugin-datalabels": "^2.1.0", + "context": "^4.0.0", + "date-fns": "^2.16.1", + "emoji-mart": "^3.0.0", + "formik": "^2.2.0", + "formik-material-ui": "^3.0.1", + "gn-api-sdk-node": "^3.0.2", + "i18next": "^19.8.2", + "i18next-browser-languagedetector": "^6.0.1", + "jsonwebtoken": "^9.0.2", + "markdown-to-jsx": "^7.1.0", + "material-ui-color": "^1.2.0", + "mic-recorder-to-mp3": "^2.2.2", + "moment": "^2.29.1", + "qrcode.react": "^1.0.0", + "query-string": "^7.0.0", + "react": "^17.0.2", + "react-big-calendar": "^1.8.7", + "react-bootstrap": "^2.7.0", + "react-chartjs-2": "^4.3.1", + "react-color": "^2.19.3", + "react-copy-to-clipboard": "^5.1.0", + "react-csv": "^2.2.2", + "react-currency-format": "^1.1.0", + "react-dom": "^17.0.2", + "react-icons": "^4.4.0", + "react-input-mask": "^2.0.4", + "react-modal-image": "^2.5.0", + "react-number-format": "^4.6.4", + "react-qr-code": "^2.0.7", + "react-query": "^3.39.3", + "react-router-dom": "^5.2.0", + "react-scripts": "3.4.3", + "react-text-mask": "^5.5.0", + "react-toastify": "9.0.0", + "react-trello": "^2.2.11", + "recharts": "^2.0.2", + "socket.io-client": "^4.7.5", + "styled-components": "^5.3.5", + "text-mask-addons": "^3.8.0", + "use-debounce": "^7.0.0", + "use-sound": "^2.0.1", + "uuid": "^8.3.2", + "yup": "^0.32.8" + } + }, + "node_modules/@adobe/css-tools": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.3.tgz", + "integrity": "sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ==" + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", + "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", + "dependencies": { + "@babel/highlight": "^7.24.2", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.4.tgz", + "integrity": "sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.4.tgz", + "integrity": "sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg==", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.2", + "@babel/generator": "^7.24.4", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.24.4", + "@babel/parser": "^7.24.4", + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.1", + "@babel/types": "^7.24.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.4.tgz", + "integrity": "sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==", + "dependencies": { + "@babel/types": "^7.24.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", + "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.4.tgz", + "integrity": "sha512-lG75yeuUSVu0pIcbhiYMXBXANHrpUPaOfu7ryAzskCgKUHuAxRQI5ssrtmF0X9UXldPlvT0XM/A4F44OXRt6iQ==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.24.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", + "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "dependencies": { + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", + "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", + "dependencies": { + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", + "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz", + "integrity": "sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", + "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "dependencies": { + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.4.tgz", + "integrity": "sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw==", + "dependencies": { + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.1", + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", + "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz", + "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.4.tgz", + "integrity": "sha512-qpl6vOOEEzTLLcsuqYYo8yDtrTocmu2xkGvgNebvPjT9DTtfFYGmgDqY+rBYXNlqL4s9qLDn6xkrJv4RxAPiTA==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.1.tgz", + "integrity": "sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.1.tgz", + "integrity": "sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.24.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.1.tgz", + "integrity": "sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-async-generator-functions": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz", + "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-async-generator-functions instead.", + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-remap-async-to-generator": "^7.18.9", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.8.3.tgz", + "integrity": "sha512-EqFhbo7IosdgPgZggHaNObkmO1kNUe3slaKu54d5OWvy+p9QIKOzK1GAEpAIsZtWVtPXUHSMcT4smvDrCfY4AA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-decorators": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.8.3.tgz", + "integrity": "sha512-e3RvdvS4qPJVTe288DlXjwKflpfy1hr0j5dz5WpIYYeP7vQZg2WfAEIp8k5/Lwis/m5REXEteIz6rrcDtXXG7w==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-decorators": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-dynamic-import": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", + "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-dynamic-import instead.", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-json-strings": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", + "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-json-strings instead.", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-numeric-separator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.8.3.tgz", + "integrity": "sha512-jWioO1s6R/R+wEHizfaScNsAx+xKgwTLNXSh7tTC4Usj3ItsPEhYkEpU4h+lpnBwq7NBVOJXfO6cRFYcX69JUQ==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-object-rest-spread": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", + "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.", + "dependencies": { + "@babel/compat-data": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-catch-binding": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", + "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-catch-binding instead.", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-chaining": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz", + "integrity": "sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-unicode-property-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", + "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-unicode-property-regex instead.", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-decorators": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.24.1.tgz", + "integrity": "sha512-05RJdO/cCrtVWuAaSn1tS3bH8jbsJa/Y1uD186u6J4C/1mnHFxseeuWpsqr9anvo7TUulev7tm7GDwRV+VuhDw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-flow": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.24.1.tgz", + "integrity": "sha512-sxi2kLTI5DeW5vDtMUsk4mTPwvlUDbjOnoWayhynCwrw4QXRld4QEYwqzY8JmQXaJUtgUuCIurtSRH5sn4c7mA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.1.tgz", + "integrity": "sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.1.tgz", + "integrity": "sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.1.tgz", + "integrity": "sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.1.tgz", + "integrity": "sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz", + "integrity": "sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.24.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.3.tgz", + "integrity": "sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-remap-async-to-generator": "^7.22.20", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.1.tgz", + "integrity": "sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==", + "dependencies": { + "@babel/helper-module-imports": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-remap-async-to-generator": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.1.tgz", + "integrity": "sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.4.tgz", + "integrity": "sha512-nIFUZIpGKDf9O9ttyRXpHFpKC+X3Y5mtshZONuEUYBomAKoM4y029Jr+uB1bHGPhNmK8YXHevDtKDOLmtRrp6g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.1.tgz", + "integrity": "sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.4.tgz", + "integrity": "sha512-B8q7Pz870Hz/q9UgP8InNpY01CSLDSCyqX7zcRuv3FcPl87A2G17lASroHWaCtbdIcbYzOZ7kWmXFKbijMSmFg==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.4", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.1.tgz", + "integrity": "sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-replace-supers": "^7.24.1", + "@babel/helper-split-export-declaration": "^7.22.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.1.tgz", + "integrity": "sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/template": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.1.tgz", + "integrity": "sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.1.tgz", + "integrity": "sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.1.tgz", + "integrity": "sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.1.tgz", + "integrity": "sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.1.tgz", + "integrity": "sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==", + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.1.tgz", + "integrity": "sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-flow-strip-types": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.9.0.tgz", + "integrity": "sha512-7Qfg0lKQhEHs93FChxVLAvhBshOPQDtJUTVHr/ZwQNRccCm4O9D79r9tVSoV8iNwjP1YgfD+e/fgHcPkN1qEQg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-flow": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz", + "integrity": "sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.1.tgz", + "integrity": "sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.1.tgz", + "integrity": "sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.1.tgz", + "integrity": "sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.1.tgz", + "integrity": "sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.1.tgz", + "integrity": "sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.1.tgz", + "integrity": "sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==", + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz", + "integrity": "sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==", + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-simple-access": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.1.tgz", + "integrity": "sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==", + "dependencies": { + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.1.tgz", + "integrity": "sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==", + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.1.tgz", + "integrity": "sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz", + "integrity": "sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.1.tgz", + "integrity": "sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.1.tgz", + "integrity": "sha512-XjD5f0YqOtebto4HGISLNfiNMTTs6tbkFf2TOqJlYKYmbo+mN9Dnpl4SRoofiziuOWMIyq3sZEUqLo3hLITFEA==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.24.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz", + "integrity": "sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-replace-supers": "^7.24.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.1.tgz", + "integrity": "sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.1.tgz", + "integrity": "sha512-n03wmDt+987qXwAgcBlnUUivrZBPZ8z1plL0YvgQalLm+ZE5BMhGm94jhxXtA1wzv1Cu2aaOv1BM9vbVttrzSg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.1.tgz", + "integrity": "sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz", + "integrity": "sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.1.tgz", + "integrity": "sha512-pTHxDVa0BpUbvAgX3Gat+7cSciXqUcY9j2VZKTbSB6+VQGpNgNO9ailxTGHSXlqOnX1Hcx1Enme2+yv7VqP9bg==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.24.1", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz", + "integrity": "sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-constant-elements": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.24.1.tgz", + "integrity": "sha512-QXp1U9x0R7tkiGB0FOk8o74jhnap0FlZ5gNkRIWdG3eP+SvMFg118e1zaWewDzgABb106QSKpVsD3Wgd8t6ifA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.1.tgz", + "integrity": "sha512-mvoQg2f9p2qlpDQRBC7M3c3XTr0k7cp/0+kFKKO/7Gtu0LSw16eKB+Fabe2bDT/UpsyasTBBkAnbdsLrkD5XMw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz", + "integrity": "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/types": "^7.23.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", + "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.1.tgz", + "integrity": "sha512-kDJgnPujTmAZ/9q2CN4m2/lRsUUPDvsG3+tSHWUJIzMGTt5U/b/fwWd3RO3n+5mjLrsBrVa5eKFRVSQbi3dF1w==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.1.tgz", + "integrity": "sha512-1v202n7aUq4uXAieRTKcwPzNyphlCuqHHDcdSNc+vdhoTEZcFMh+L5yZuCmGaIO7bs1nJUNfHB89TZyoL48xNA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.1.tgz", + "integrity": "sha512-+pWEAaDJvSm9aFvJNpLiM2+ktl2Sn2U5DdyiWdZBxmLc6+xGt88dvFqsHiAiDS+8WqUwbDfkKz9jRxK3M0k+kA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.1.tgz", + "integrity": "sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.1.tgz", + "integrity": "sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.9.0.tgz", + "integrity": "sha512-pUu9VSf3kI1OqbWINQ7MaugnitRss1z533436waNXp+0N3ur3zfut37sXiQMxkuCF4VUjwZucen/quskCh7NHw==", + "dependencies": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "resolve": "^1.8.1", + "semver": "^5.5.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz", + "integrity": "sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.1.tgz", + "integrity": "sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.1.tgz", + "integrity": "sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz", + "integrity": "sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.1.tgz", + "integrity": "sha512-CBfU4l/A+KruSUoW+vTQthwcAdwuqbpRNB8HQKlZABwHRhsdHZ9fezp4Sn18PeAlYxTNiLMlx4xUBV3AWfg1BA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.4.tgz", + "integrity": "sha512-79t3CQ8+oBGk/80SQ8MN3Bs3obf83zJ0YZjDmDaEZN8MqhMI760apl5z6a20kFeMXBwJX99VpKT8CKxEBp5H1g==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.24.4", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-typescript": "^7.24.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.1.tgz", + "integrity": "sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.1.tgz", + "integrity": "sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.1.tgz", + "integrity": "sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.1.tgz", + "integrity": "sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.4.tgz", + "integrity": "sha512-7Kl6cSmYkak0FK/FXjSEnLJ1N9T/WA2RkMhu17gZ/dsxKJUuTYNIylahPTzqpLyJN4WhDif8X0XK1R8Wsguo/A==", + "dependencies": { + "@babel/compat-data": "^7.24.4", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-validator-option": "^7.23.5", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.4", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.1", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.24.1", + "@babel/plugin-syntax-import-attributes": "^7.24.1", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.24.1", + "@babel/plugin-transform-async-generator-functions": "^7.24.3", + "@babel/plugin-transform-async-to-generator": "^7.24.1", + "@babel/plugin-transform-block-scoped-functions": "^7.24.1", + "@babel/plugin-transform-block-scoping": "^7.24.4", + "@babel/plugin-transform-class-properties": "^7.24.1", + "@babel/plugin-transform-class-static-block": "^7.24.4", + "@babel/plugin-transform-classes": "^7.24.1", + "@babel/plugin-transform-computed-properties": "^7.24.1", + "@babel/plugin-transform-destructuring": "^7.24.1", + "@babel/plugin-transform-dotall-regex": "^7.24.1", + "@babel/plugin-transform-duplicate-keys": "^7.24.1", + "@babel/plugin-transform-dynamic-import": "^7.24.1", + "@babel/plugin-transform-exponentiation-operator": "^7.24.1", + "@babel/plugin-transform-export-namespace-from": "^7.24.1", + "@babel/plugin-transform-for-of": "^7.24.1", + "@babel/plugin-transform-function-name": "^7.24.1", + "@babel/plugin-transform-json-strings": "^7.24.1", + "@babel/plugin-transform-literals": "^7.24.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.1", + "@babel/plugin-transform-member-expression-literals": "^7.24.1", + "@babel/plugin-transform-modules-amd": "^7.24.1", + "@babel/plugin-transform-modules-commonjs": "^7.24.1", + "@babel/plugin-transform-modules-systemjs": "^7.24.1", + "@babel/plugin-transform-modules-umd": "^7.24.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.24.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.1", + "@babel/plugin-transform-numeric-separator": "^7.24.1", + "@babel/plugin-transform-object-rest-spread": "^7.24.1", + "@babel/plugin-transform-object-super": "^7.24.1", + "@babel/plugin-transform-optional-catch-binding": "^7.24.1", + "@babel/plugin-transform-optional-chaining": "^7.24.1", + "@babel/plugin-transform-parameters": "^7.24.1", + "@babel/plugin-transform-private-methods": "^7.24.1", + "@babel/plugin-transform-private-property-in-object": "^7.24.1", + "@babel/plugin-transform-property-literals": "^7.24.1", + "@babel/plugin-transform-regenerator": "^7.24.1", + "@babel/plugin-transform-reserved-words": "^7.24.1", + "@babel/plugin-transform-shorthand-properties": "^7.24.1", + "@babel/plugin-transform-spread": "^7.24.1", + "@babel/plugin-transform-sticky-regex": "^7.24.1", + "@babel/plugin-transform-template-literals": "^7.24.1", + "@babel/plugin-transform-typeof-symbol": "^7.24.1", + "@babel/plugin-transform-unicode-escapes": "^7.24.1", + "@babel/plugin-transform-unicode-property-regex": "^7.24.1", + "@babel/plugin-transform-unicode-regex": "^7.24.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.24.1", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.4", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.24.1.tgz", + "integrity": "sha512-eFa8up2/8cZXLIpkafhaADTXSnl7IsUFCYenRWrARBz0/qZwcT0RBXpys0LJU4+WfPoF2ZG6ew6s2V6izMCwRA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-validator-option": "^7.23.5", + "@babel/plugin-transform-react-display-name": "^7.24.1", + "@babel/plugin-transform-react-jsx": "^7.23.4", + "@babel/plugin-transform-react-jsx-development": "^7.22.5", + "@babel/plugin-transform-react-pure-annotations": "^7.24.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.9.0.tgz", + "integrity": "sha512-S4cueFnGrIbvYJgwsVFKdvOmpiL0XGw9MFW9D0vgRys5g36PBhZRL8NX8Gr2akz8XRtzq6HuDXPD/1nniagNUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-transform-typescript": "^7.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" + }, + "node_modules/@babel/runtime": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz", + "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.24.4.tgz", + "integrity": "sha512-VOQOexSilscN24VEY810G/PqtpFvx/z6UqDIjIWbDe2368HhDLkYN5TYwaEz/+eRCUkhJ2WaNLLmQAlxzfWj4w==", + "dependencies": { + "core-js-pure": "^3.30.2", + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", + "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", + "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", + "dependencies": { + "@babel/code-frame": "^7.24.1", + "@babel/generator": "^7.24.1", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.24.1", + "@babel/types": "^7.24.0", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "dependencies": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + }, + "bin": { + "watch": "cli.js" + }, + "engines": { + "node": ">=0.1.95" + } + }, + "node_modules/@csstools/convert-colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz", + "integrity": "sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/@csstools/normalize.css": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-10.1.0.tgz", + "integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==" + }, + "node_modules/@date-io/core": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@date-io/core/-/core-2.17.0.tgz", + "integrity": "sha512-+EQE8xZhRM/hsY0CDTVyayMDDY5ihc4MqXCrPxooKw19yAzUIC6uUqsZeaOFNL9YKTNxYKrJP5DFgE8o5xRCOw==" + }, + "node_modules/@date-io/date-fns": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@date-io/date-fns/-/date-fns-2.17.0.tgz", + "integrity": "sha512-L0hWZ/mTpy3Gx/xXJ5tq5CzHo0L7ry6KEO9/w/JWiFWFLZgiNVo3ex92gOl3zmzjHqY/3Ev+5sehAr8UnGLEng==", + "dependencies": { + "@date-io/core": "^2.17.0" + }, + "peerDependencies": { + "date-fns": "^2.0.0" + }, + "peerDependenciesMeta": { + "date-fns": { + "optional": true + } + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "dependencies": { + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/@emotion/react": { + "version": "11.11.4", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", + "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.4.tgz", + "integrity": "sha512-RIN04MBT8g+FnDwgvIUi8czvr1LU1alUMI05LekWB5DGyTm8cCBMCRpq3GqaiyEDRptEXOyXnvZ58GZYu4kBxQ==", + "dependencies": { + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + }, + "node_modules/@emotion/styled": { + "version": "11.11.5", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.5.tgz", + "integrity": "sha512-/ZjjnaNKvuMPxcIiUkf/9SHoG4Q196DRl1w82hQ3WCsjo1IUR8uaGWrC6a87CrYAW0Kb/pK7hk8BnLgLRi9KoQ==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.2", + "@emotion/serialize": "^1.1.4", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/stylis": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", + "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + }, + "node_modules/@floating-ui/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", + "dependencies": { + "@floating-ui/utils": "^0.2.1" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", + "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", + "dependencies": { + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", + "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", + "dependencies": { + "@floating-ui/dom": "^1.6.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" + }, + "node_modules/@hapi/address": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", + "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==", + "deprecated": "Moved to 'npm install @sideway/address'" + }, + "node_modules/@hapi/bourne": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", + "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==", + "deprecated": "This version has been deprecated and is no longer supported or maintained" + }, + "node_modules/@hapi/hoek": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz", + "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==", + "deprecated": "This version has been deprecated and is no longer supported or maintained" + }, + "node_modules/@hapi/joi": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz", + "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==", + "deprecated": "Switch to 'npm install joi'", + "dependencies": { + "@hapi/address": "2.x.x", + "@hapi/bourne": "1.x.x", + "@hapi/hoek": "8.x.x", + "@hapi/topo": "3.x.x" + } + }, + "node_modules/@hapi/topo": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz", + "integrity": "sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==", + "deprecated": "This version has been deprecated and is no longer supported or maintained", + "dependencies": { + "@hapi/hoek": "^8.3.0" + } + }, + "node_modules/@icons/material": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@icons/material/-/material-0.2.4.tgz", + "integrity": "sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw==", + "peerDependencies": { + "react": "*" + } + }, + "node_modules/@jest/console": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz", + "integrity": "sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==", + "dependencies": { + "@jest/source-map": "^24.9.0", + "chalk": "^2.0.1", + "slash": "^2.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@jest/console/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@jest/console/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@jest/console/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@jest/console/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@jest/console/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@jest/console/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@jest/console/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@jest/console/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@jest/core": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-24.9.0.tgz", + "integrity": "sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A==", + "dependencies": { + "@jest/console": "^24.7.1", + "@jest/reporters": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "graceful-fs": "^4.1.15", + "jest-changed-files": "^24.9.0", + "jest-config": "^24.9.0", + "jest-haste-map": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.9.0", + "jest-resolve-dependencies": "^24.9.0", + "jest-runner": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-snapshot": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "jest-watcher": "^24.9.0", + "micromatch": "^3.1.10", + "p-each-series": "^1.0.0", + "realpath-native": "^1.1.0", + "rimraf": "^2.5.4", + "slash": "^2.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@jest/core/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@jest/core/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@jest/core/node_modules/@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==" + }, + "node_modules/@jest/core/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/core/node_modules/ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@jest/core/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/core/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/core/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@jest/core/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@jest/core/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@jest/core/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@jest/core/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/core/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/core/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@jest/core/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/core/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/core/node_modules/jest-message-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz", + "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@jest/core/node_modules/jest-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", + "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", + "dependencies": { + "@jest/console": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/source-map": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@jest/core/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/core/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/core/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/@jest/core/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@jest/core/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/core/node_modules/stack-utils": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", + "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@jest/core/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/environment": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.9.0.tgz", + "integrity": "sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ==", + "dependencies": { + "@jest/fake-timers": "^24.9.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@jest/environment/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@jest/environment/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@jest/environment/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.9.0.tgz", + "integrity": "sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==", + "dependencies": { + "@jest/types": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-mock": "^24.9.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@jest/fake-timers/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@jest/fake-timers/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@jest/fake-timers/node_modules/@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==" + }, + "node_modules/@jest/fake-timers/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/fake-timers/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@jest/fake-timers/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@jest/fake-timers/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@jest/fake-timers/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@jest/fake-timers/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@jest/fake-timers/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/jest-message-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz", + "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@jest/fake-timers/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@jest/fake-timers/node_modules/stack-utils": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", + "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/fake-timers/node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/fake-timers/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@jest/fake-timers/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/reporters": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.9.0.tgz", + "integrity": "sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw==", + "dependencies": { + "@jest/environment": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "glob": "^7.1.2", + "istanbul-lib-coverage": "^2.0.2", + "istanbul-lib-instrument": "^3.0.1", + "istanbul-lib-report": "^2.0.4", + "istanbul-lib-source-maps": "^3.0.1", + "istanbul-reports": "^2.2.6", + "jest-haste-map": "^24.9.0", + "jest-resolve": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-util": "^24.9.0", + "jest-worker": "^24.6.0", + "node-notifier": "^5.4.2", + "slash": "^2.0.0", + "source-map": "^0.6.0", + "string-length": "^2.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@jest/reporters/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@jest/reporters/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@jest/reporters/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/reporters/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@jest/reporters/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@jest/reporters/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@jest/reporters/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@jest/reporters/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@jest/reporters/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@jest/reporters/node_modules/jest-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", + "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", + "dependencies": { + "@jest/console": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/source-map": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@jest/reporters/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@jest/reporters/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/reporters/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.9.0.tgz", + "integrity": "sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==", + "dependencies": { + "callsites": "^3.0.0", + "graceful-fs": "^4.1.15", + "source-map": "^0.6.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@jest/source-map/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/test-result": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.9.0.tgz", + "integrity": "sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==", + "dependencies": { + "@jest/console": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/istanbul-lib-coverage": "^2.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@jest/test-result/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@jest/test-result/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@jest/test-result/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz", + "integrity": "sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A==", + "dependencies": { + "@jest/test-result": "^24.9.0", + "jest-haste-map": "^24.9.0", + "jest-runner": "^24.9.0", + "jest-runtime": "^24.9.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@jest/transform": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.9.0.tgz", + "integrity": "sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==", + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/types": "^24.9.0", + "babel-plugin-istanbul": "^5.1.0", + "chalk": "^2.0.1", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.1.15", + "jest-haste-map": "^24.9.0", + "jest-regex-util": "^24.9.0", + "jest-util": "^24.9.0", + "micromatch": "^3.1.10", + "pirates": "^4.0.1", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "2.4.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@jest/transform/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@jest/transform/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@jest/transform/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@jest/transform/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@jest/transform/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/transform/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/transform/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@jest/transform/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@jest/transform/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@jest/transform/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@jest/transform/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/transform/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/transform/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@jest/transform/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/transform/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/transform/node_modules/jest-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", + "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", + "dependencies": { + "@jest/console": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/source-map": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@jest/transform/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/transform/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/transform/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@jest/transform/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/transform/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@jest/transform/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@material-ui/core": { + "version": "4.12.3", + "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.12.3.tgz", + "integrity": "sha512-sdpgI/PL56QVsEJldwEe4FFaFTLUqN+rd7sSZiRCdx2E/C7z5yK0y/khAWVBH24tXwto7I1hCzNWfJGZIYJKnw==", + "deprecated": "Material UI v4 doesn't receive active development since September 2021. See the guide https://mui.com/material-ui/migration/migration-v4/ to upgrade to v5.", + "dependencies": { + "@babel/runtime": "^7.4.4", + "@material-ui/styles": "^4.11.4", + "@material-ui/system": "^4.12.1", + "@material-ui/types": "5.1.0", + "@material-ui/utils": "^4.11.2", + "@types/react-transition-group": "^4.2.0", + "clsx": "^1.0.4", + "hoist-non-react-statics": "^3.3.2", + "popper.js": "1.16.1-lts", + "prop-types": "^15.7.2", + "react-is": "^16.8.0 || ^17.0.0", + "react-transition-group": "^4.4.0" + }, + "engines": { + "node": ">=8.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/material-ui" + }, + "peerDependencies": { + "@types/react": "^16.8.6 || ^17.0.0", + "react": "^16.8.0 || ^17.0.0", + "react-dom": "^16.8.0 || ^17.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@material-ui/core/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + }, + "node_modules/@material-ui/icons": { + "version": "4.11.3", + "resolved": "https://registry.npmjs.org/@material-ui/icons/-/icons-4.11.3.tgz", + "integrity": "sha512-IKHlyx6LDh8n19vzwH5RtHIOHl9Tu90aAAxcbWME6kp4dmvODM3UvOHJeMIDzUbd4muuJKHmlNoBN+mDY4XkBA==", + "dependencies": { + "@babel/runtime": "^7.4.4" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "@material-ui/core": "^4.0.0", + "@types/react": "^16.8.6 || ^17.0.0", + "react": "^16.8.0 || ^17.0.0", + "react-dom": "^16.8.0 || ^17.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@material-ui/lab": { + "version": "4.0.0-alpha.61", + "resolved": "https://registry.npmjs.org/@material-ui/lab/-/lab-4.0.0-alpha.61.tgz", + "integrity": "sha512-rSzm+XKiNUjKegj8bzt5+pygZeckNLOr+IjykH8sYdVk7dE9y2ZuUSofiMV2bJk3qU+JHwexmw+q0RyNZB9ugg==", + "deprecated": "Material UI v4 doesn't receive active development since September 2021. See the guide https://mui.com/material-ui/migration/migration-v4/ to upgrade to v5.", + "dependencies": { + "@babel/runtime": "^7.4.4", + "@material-ui/utils": "^4.11.3", + "clsx": "^1.0.4", + "prop-types": "^15.7.2", + "react-is": "^16.8.0 || ^17.0.0" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "@material-ui/core": "^4.12.1", + "@types/react": "^16.8.6 || ^17.0.0", + "react": "^16.8.0 || ^17.0.0", + "react-dom": "^16.8.0 || ^17.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@material-ui/lab/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + }, + "node_modules/@material-ui/pickers": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@material-ui/pickers/-/pickers-3.3.11.tgz", + "integrity": "sha512-pDYjbjUeabapijS2FpSwK/ruJdk7IGeAshpLbKDa3PRRKRy7Nv6sXxAvUg2F+lID/NwUKgBmCYS5bzrl7Xxqzw==", + "deprecated": "This package no longer supported. It has been relaced by @mui/x-date-pickers", + "dependencies": { + "@babel/runtime": "^7.6.0", + "@date-io/core": "1.x", + "@types/styled-jsx": "^2.2.8", + "clsx": "^1.0.2", + "react-transition-group": "^4.0.0", + "rifm": "^0.7.0" + }, + "peerDependencies": { + "@date-io/core": "^1.3.6", + "@material-ui/core": "^4.0.0", + "prop-types": "^15.6.0", + "react": "^16.8.0 || ^17.0.0", + "react-dom": "^16.8.0 || ^17.0.0" + } + }, + "node_modules/@material-ui/pickers/node_modules/@date-io/core": { + "version": "1.3.13", + "resolved": "https://registry.npmjs.org/@date-io/core/-/core-1.3.13.tgz", + "integrity": "sha512-AlEKV7TxjeK+jxWVKcCFrfYAk8spX9aCyiToFIiLPtfQbsjmRGLIhb5VZgptQcJdHtLXo7+m0DuurwFgUToQuA==" + }, + "node_modules/@material-ui/styles": { + "version": "4.11.5", + "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.5.tgz", + "integrity": "sha512-o/41ot5JJiUsIETME9wVLAJrmIWL3j0R0Bj2kCOLbSfqEkKf0fmaPt+5vtblUh5eXr2S+J/8J3DaCb10+CzPGA==", + "deprecated": "Material UI v4 doesn't receive active development since September 2021. See the guide https://mui.com/material-ui/migration/migration-v4/ to upgrade to v5.", + "dependencies": { + "@babel/runtime": "^7.4.4", + "@emotion/hash": "^0.8.0", + "@material-ui/types": "5.1.0", + "@material-ui/utils": "^4.11.3", + "clsx": "^1.0.4", + "csstype": "^2.5.2", + "hoist-non-react-statics": "^3.3.2", + "jss": "^10.5.1", + "jss-plugin-camel-case": "^10.5.1", + "jss-plugin-default-unit": "^10.5.1", + "jss-plugin-global": "^10.5.1", + "jss-plugin-nested": "^10.5.1", + "jss-plugin-props-sort": "^10.5.1", + "jss-plugin-rule-value-function": "^10.5.1", + "jss-plugin-vendor-prefixer": "^10.5.1", + "prop-types": "^15.7.2" + }, + "engines": { + "node": ">=8.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/material-ui" + }, + "peerDependencies": { + "@types/react": "^16.8.6 || ^17.0.0", + "react": "^16.8.0 || ^17.0.0", + "react-dom": "^16.8.0 || ^17.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@material-ui/styles/node_modules/@emotion/hash": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", + "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" + }, + "node_modules/@material-ui/styles/node_modules/csstype": { + "version": "2.6.21", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz", + "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==" + }, + "node_modules/@material-ui/system": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.12.2.tgz", + "integrity": "sha512-6CSKu2MtmiJgcCGf6nBQpM8fLkuB9F55EKfbdTC80NND5wpTmKzwdhLYLH3zL4cLlK0gVaaltW7/wMuyTnN0Lw==", + "dependencies": { + "@babel/runtime": "^7.4.4", + "@material-ui/utils": "^4.11.3", + "csstype": "^2.5.2", + "prop-types": "^15.7.2" + }, + "engines": { + "node": ">=8.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/material-ui" + }, + "peerDependencies": { + "@types/react": "^16.8.6 || ^17.0.0", + "react": "^16.8.0 || ^17.0.0", + "react-dom": "^16.8.0 || ^17.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@material-ui/system/node_modules/csstype": { + "version": "2.6.21", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz", + "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==" + }, + "node_modules/@material-ui/types": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz", + "integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==", + "peerDependencies": { + "@types/react": "*" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@material-ui/utils": { + "version": "4.11.3", + "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.11.3.tgz", + "integrity": "sha512-ZuQPV4rBK/V1j2dIkSSEcH5uT6AaHuKWFfotADHsC0wVL1NLd2WkFCm4ZZbX33iO4ydl6V0GPngKm8HZQ2oujg==", + "dependencies": { + "@babel/runtime": "^7.4.4", + "prop-types": "^15.7.2", + "react-is": "^16.8.0 || ^17.0.0" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0", + "react-dom": "^16.8.0 || ^17.0.0" + } + }, + "node_modules/@material-ui/utils/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + }, + "node_modules/@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dependencies": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@mui/base": { + "version": "5.0.0-beta.40", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz", + "integrity": "sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@floating-ui/react-dom": "^2.0.8", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.14", + "@popperjs/core": "^2.11.8", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/base/node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.15.15", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.15.tgz", + "integrity": "sha512-aXnw29OWQ6I5A47iuWEI6qSSUfH6G/aCsW9KmW3LiFqr7uXZBK4Ks+z8G+qeIub8k0T5CMqlT2q0L+ZJTMrqpg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/material": { + "version": "5.15.15", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.15.tgz", + "integrity": "sha512-3zvWayJ+E1kzoIsvwyEvkTUKVKt1AjchFFns+JtluHCuvxgKcLSRJTADw37k0doaRtVAsyh8bz9Afqzv+KYrIA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/base": "5.0.0-beta.40", + "@mui/core-downloads-tracker": "^5.15.15", + "@mui/system": "^5.15.15", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.14", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material/node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@mui/private-theming": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.14.tgz", + "integrity": "sha512-UH0EiZckOWcxiXLX3Jbb0K7rC8mxTr9L9l6QhOZxYc4r8FHUkefltV9VDGLrzCaWh30SQiJvAEd7djX3XXY6Xw==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.15.14", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.14.tgz", + "integrity": "sha512-RILkuVD8gY6PvjZjqnWhz8fu68dVkqhM5+jYWfB5yhlSQKg+2rHkmEwm75XIeAqI3qwOndK6zELK5H6Zxn4NHw==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "5.15.15", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.15.tgz", + "integrity": "sha512-aulox6N1dnu5PABsfxVGOZffDVmlxPOVgj56HrUnJE8MCSh8lOvvkd47cebIVQQYAjpwieXQXiDPj5pwM40jTQ==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.15.14", + "@mui/styled-engine": "^5.15.14", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.14", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/system/node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@mui/types": { + "version": "7.2.14", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.14.tgz", + "integrity": "sha512-MZsBZ4q4HfzBsywtXgM1Ksj6HDThtiwmOKUXH1pKYISI9gAVXCNHNpo7TlGoGrBaYWZTdNoirIN7JsQcQUjmQQ==", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.14.tgz", + "integrity": "sha512-0lF/7Hh/ezDv5X7Pry6enMsbYyGKjADzvHyo3Qrc/SSlTsQ1VkbDMbH0m2t3OR5iIVLwMoxwM7yGd+6FCMtTFA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@types/prop-types": "^15.7.11", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/x-date-pickers": { + "version": "6.19.9", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-6.19.9.tgz", + "integrity": "sha512-B2m4Fv/fOme5qmV6zuE3QnWQSvj3zKtI2OvikPz5prpiCcIxqpeytkQ7VfrWH3/Aqd5yhG1Yr4IgbqG0ymIXGg==", + "dependencies": { + "@babel/runtime": "^7.23.2", + "@mui/base": "^5.0.0-beta.22", + "@mui/utils": "^5.14.16", + "@types/react-transition-group": "^4.4.8", + "clsx": "^2.0.0", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.8.6", + "@mui/system": "^5.8.0", + "date-fns": "^2.25.0 || ^3.2.0", + "date-fns-jalali": "^2.13.0-0", + "dayjs": "^1.10.7", + "luxon": "^3.0.2", + "moment": "^2.29.4", + "moment-hijri": "^2.1.2", + "moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "date-fns": { + "optional": true + }, + "date-fns-jalali": { + "optional": true + }, + "dayjs": { + "optional": true + }, + "luxon": { + "optional": true + }, + "moment": { + "optional": true + }, + "moment-hijri": { + "optional": true + }, + "moment-jalaali": { + "optional": true + } + } + }, + "node_modules/@mui/x-date-pickers/node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@react-aria/ssr": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.2.tgz", + "integrity": "sha512-0gKkgDYdnq1w+ey8KzG9l+H5Z821qh9vVjztk55rUg71vTk/Eaebeir+WtzcLLwTjw3m/asIjx8Y59y1lJZhBw==", + "dependencies": { + "@swc/helpers": "^0.5.0" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + } + }, + "node_modules/@restart/hooks": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.16.tgz", + "integrity": "sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==", + "dependencies": { + "dequal": "^2.0.3" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@restart/ui": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.8.tgz", + "integrity": "sha512-6ndCv3oZ7r9vuP1Ok9KH55TM1/UkdBnP/fSraW0DFDMbPMzWKhVKeFAIEUCRCSdzayjZDcFYK6xbMlipN9dmMA==", + "dependencies": { + "@babel/runtime": "^7.21.0", + "@popperjs/core": "^2.11.6", + "@react-aria/ssr": "^3.5.0", + "@restart/hooks": "^0.4.9", + "@types/warning": "^3.0.0", + "dequal": "^2.0.3", + "dom-helpers": "^5.2.0", + "uncontrollable": "^8.0.1", + "warning": "^4.0.3" + }, + "peerDependencies": { + "react": ">=16.14.0", + "react-dom": ">=16.14.0" + } + }, + "node_modules/@restart/ui/node_modules/uncontrollable": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", + "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==", + "peerDependencies": { + "react": ">=16.14.0" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.1.tgz", + "integrity": "sha512-dzJtaDAAoXx4GCOJpbB2eG/Qj8VDpdwkLsWGzGm+0L7E8/434RyMbAHmk9ubXWVAb9nXmc44jUf8GKqVDiKezg==" + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz", + "integrity": "sha512-j7KnilGyZzYr/jhcrSYS3FGWMZVaqyCG0vzMCwzvei0coIkczuYMcniK07nI0aHJINciujjH11T72ICW5eL5Ig==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-4.2.0.tgz", + "integrity": "sha512-3XHLtJ+HbRCH4n28S7y/yZoEQnRpl0tvTZQsHqvaeNXPra+6vE5tbRliH3ox1yZYPCxrlqaJT/Mg+75GpDKlvQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-4.2.0.tgz", + "integrity": "sha512-yTr2iLdf6oEuUE9MsRdvt0NmdpMBAkgK8Bjhl6epb+eQWk6abBaX3d65UZ3E3FWaOwePyUgNyNCMVG61gGCQ7w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-4.2.0.tgz", + "integrity": "sha512-U9m870Kqm0ko8beHawRXLGLvSi/ZMrl89gJ5BNcT452fAjtF2p4uRzXkdzvGJJJYBgx7BmqlDjBN/eCp5AAX2w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-4.3.3.tgz", + "integrity": "sha512-w3Be6xUNdwgParsvxkkeZb545VhXEwjGMwExMVBIdPQJeyMQHqm9Msnb2a1teHBqUYL66qtwfhNkbj1iarCG7w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-4.2.0.tgz", + "integrity": "sha512-C0Uy+BHolCHGOZ8Dnr1zXy/KgpBOkEUYY9kI/HseHVPeMbluaX3CijJr7D4C5uR8zrc1T64nnq/k63ydQuGt4w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-4.2.0.tgz", + "integrity": "sha512-7YvynOpZDpCOUoIVlaaOUU87J4Z6RdD6spYN4eUb5tfPoKGSF9OG2NuhgYnq4jSkAxcpMaXWPf1cePkzmqTPNw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-4.2.0.tgz", + "integrity": "sha512-hYfYuZhQPCBVotABsXKSCfel2slf/yvJY8heTVX1PCTaq/IgASq1IyxPPKJ0chWREEKewIU/JMSsIGBtK1KKxw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-4.3.3.tgz", + "integrity": "sha512-6PG80tdz4eAlYUN3g5GZiUjg2FMcp+Wn6rtnz5WJG9ITGEF1pmFdzq02597Hn0OmnQuCVaBYQE1OVFAnwOl+0A==", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "^4.2.0", + "@svgr/babel-plugin-remove-jsx-attribute": "^4.2.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "^4.2.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "^4.2.0", + "@svgr/babel-plugin-svg-dynamic-title": "^4.3.3", + "@svgr/babel-plugin-svg-em-dimensions": "^4.2.0", + "@svgr/babel-plugin-transform-react-native-svg": "^4.2.0", + "@svgr/babel-plugin-transform-svg-component": "^4.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@svgr/core": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-4.3.3.tgz", + "integrity": "sha512-qNuGF1QON1626UCaZamWt5yedpgOytvLj5BQZe2j1k1B8DUG4OyugZyfEwBeXozCUwhLEpsrgPrE+eCu4fY17w==", + "dependencies": { + "@svgr/plugin-jsx": "^4.3.3", + "camelcase": "^5.3.1", + "cosmiconfig": "^5.2.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@svgr/core/node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@svgr/core/node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@svgr/core/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@svgr/core/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-4.3.2.tgz", + "integrity": "sha512-JioXclZGhFIDL3ddn4Kiq8qEqYM2PyDKV0aYno8+IXTLuYt6TOgHUbUAAFvqtb0Xn37NwP0BTHglejFoYr8RZg==", + "dependencies": { + "@babel/types": "^7.4.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-4.3.3.tgz", + "integrity": "sha512-cLOCSpNWQnDB1/v+SUENHH7a0XY09bfuMKdq9+gYvtuwzC2rU4I0wKGFEp1i24holdQdwodCtDQdFtJiTCWc+w==", + "dependencies": { + "@babel/core": "^7.4.5", + "@svgr/babel-preset": "^4.3.3", + "@svgr/hast-util-to-babel-ast": "^4.3.2", + "svg-parser": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-4.3.1.tgz", + "integrity": "sha512-PrMtEDUWjX3Ea65JsVCwTIXuSqa3CG9px+DluF1/eo9mlDrgrtFE7NE/DjdhjJgSM9wenlVBzkzneSIUgfUI/w==", + "dependencies": { + "cosmiconfig": "^5.2.1", + "merge-deep": "^3.0.2", + "svgo": "^1.2.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@svgr/plugin-svgo/node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@svgr/plugin-svgo/node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@svgr/plugin-svgo/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@svgr/plugin-svgo/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@svgr/webpack": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-4.3.3.tgz", + "integrity": "sha512-bjnWolZ6KVsHhgyCoYRFmbd26p8XVbulCzSG53BDQqAr+JOAderYK7CuYrB3bDjHJuF6LJ7Wrr42+goLRV9qIg==", + "dependencies": { + "@babel/core": "^7.4.5", + "@babel/plugin-transform-react-constant-elements": "^7.0.0", + "@babel/preset-env": "^7.4.5", + "@babel/preset-react": "^7.0.0", + "@svgr/core": "^4.3.3", + "@svgr/plugin-jsx": "^4.3.3", + "@svgr/plugin-svgo": "^4.3.1", + "loader-utils": "^1.2.3" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.10.tgz", + "integrity": "sha512-CU+RF9FySljn7HVSkkjiB84hWkvTaI3rtLvF433+jRSBL2hMu3zX5bGhHS8C80SM++h4xy8hBSnUHFQHmRXSBw==", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@testing-library/dom": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.0.0.tgz", + "integrity": "sha512-PmJPnogldqoVFf+EwbHvbBJ98MmqASV8kLrBYgsDNxQcFMeIS7JFL48sfyXvuMtgmWO/wMhh25odr+8VhDmn4g==", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz", + "integrity": "sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==", + "dependencies": { + "@adobe/css-tools": "^4.0.1", + "@babel/runtime": "^7.9.2", + "@types/testing-library__jest-dom": "^5.9.1", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.5.6", + "lodash": "^4.17.15", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=8", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/react": { + "version": "11.2.7", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-11.2.7.tgz", + "integrity": "sha512-tzRNp7pzd5QmbtXNG/mhdcl7Awfu/Iz1RaVHY75zTdOkmHCuzMhRL83gWHSgOAcjS3CCbyfwUHMZgRJb4kAfpA==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@testing-library/dom": "^7.28.1" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/@testing-library/react/node_modules/@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@testing-library/react/node_modules/@testing-library/dom": { + "version": "7.31.2", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-7.31.2.tgz", + "integrity": "sha512-3UqjCpey6HiTZT92vODYLPxTBWlM8ZOOjr3LX5F37/VRipW2M1kX6I/Cm4VXzteZqfGfagg8yXywpcOgQBlNsQ==", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^4.2.0", + "aria-query": "^4.2.2", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.6", + "lz-string": "^1.4.4", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@testing-library/react/node_modules/@types/aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==" + }, + "node_modules/@testing-library/react/node_modules/@types/yargs": { + "version": "15.0.19", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.19.tgz", + "integrity": "sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@testing-library/react/node_modules/aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "dependencies": { + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/@testing-library/react/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@testing-library/react/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + }, + "node_modules/@testing-library/user-event": { + "version": "12.8.3", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-12.8.3.tgz", + "integrity": "sha512-IR0iWbFkgd56Bu5ZI/ej8yQwrkCv8Qydx6RzwbKz9faXazR/+5tvYKsZQgyXJiwgpcva127YO6JcWy7YlCfofQ==", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "peer": true + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", + "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", + "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", + "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", + "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==" + }, + "node_modules/@types/eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==" + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", + "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.12", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", + "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/jest/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@types/jest/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + }, + "node_modules/@types/lodash": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz", + "integrity": "sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==" + }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==" + }, + "node_modules/@types/node": { + "version": "20.12.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", + "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" + }, + "node_modules/@types/q": { + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.8.tgz", + "integrity": "sha512-hroOstUScF6zhIi+5+x0dzqrHA1EJi+Irri6b1fxolMTqqHIV/Cg77EtnQcZqZCu8hR3mX2BzIxN4/GzI68Kfw==" + }, + "node_modules/@types/react": { + "version": "17.0.80", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.80.tgz", + "integrity": "sha512-LrgHIu2lEtIo8M7d1FcI3BdwXWoRQwMoXOZ7+dPTW0lYREjmlHl3P0U1VD0i/9tppOuv8/sam7sOjx34TxSFbA==", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "^0.16", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==" + }, + "node_modules/@types/styled-jsx": { + "version": "2.2.9", + "resolved": "https://registry.npmjs.org/@types/styled-jsx/-/styled-jsx-2.2.9.tgz", + "integrity": "sha512-W/iTlIkGEyTBGTEvZCey8EgQlQ5l0DwMqi3iOXlLs2kyBwYTXHKEiU6IZ5EwoRwngL8/dGYuzezSup89ttVHLw==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/testing-library__jest-dom": { + "version": "5.14.9", + "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz", + "integrity": "sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw==", + "dependencies": { + "@types/jest": "*" + } + }, + "node_modules/@types/warning": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz", + "integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==" + }, + "node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz", + "integrity": "sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ==", + "dependencies": { + "@typescript-eslint/experimental-utils": "2.34.0", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "tsutils": "^3.17.1" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^2.0.0", + "eslint": "^5.0.0 || ^6.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz", + "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==", + "dependencies": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.34.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.34.0.tgz", + "integrity": "sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA==", + "dependencies": { + "@types/eslint-visitor-keys": "^1.0.0", + "@typescript-eslint/experimental-utils": "2.34.0", + "@typescript-eslint/typescript-estree": "2.34.0", + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", + "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", + "dependencies": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", + "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==", + "dependencies": { + "@webassemblyjs/helper-module-context": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/wast-parser": "1.8.5" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz", + "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz", + "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz", + "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==" + }, + "node_modules/@webassemblyjs/helper-code-frame": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz", + "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==", + "dependencies": { + "@webassemblyjs/wast-printer": "1.8.5" + } + }, + "node_modules/@webassemblyjs/helper-fsm": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz", + "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==" + }, + "node_modules/@webassemblyjs/helper-module-context": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz", + "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==", + "dependencies": { + "@webassemblyjs/ast": "1.8.5", + "mamacro": "^0.0.3" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz", + "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz", + "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==", + "dependencies": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz", + "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz", + "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz", + "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz", + "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==", + "dependencies": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/helper-wasm-section": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5", + "@webassemblyjs/wasm-opt": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5", + "@webassemblyjs/wast-printer": "1.8.5" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz", + "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==", + "dependencies": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/ieee754": "1.8.5", + "@webassemblyjs/leb128": "1.8.5", + "@webassemblyjs/utf8": "1.8.5" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz", + "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==", + "dependencies": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz", + "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==", + "dependencies": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-api-error": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/ieee754": "1.8.5", + "@webassemblyjs/leb128": "1.8.5", + "@webassemblyjs/utf8": "1.8.5" + } + }, + "node_modules/@webassemblyjs/wast-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz", + "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==", + "dependencies": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/floating-point-hex-parser": "1.8.5", + "@webassemblyjs/helper-api-error": "1.8.5", + "@webassemblyjs/helper-code-frame": "1.8.5", + "@webassemblyjs/helper-fsm": "1.8.5", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz", + "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==", + "dependencies": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/wast-parser": "1.8.5", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "deprecated": "Use your platform's native atob() and btoa() methods instead" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "dependencies": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + } + }, + "node_modules/acorn-globals/node_modules/acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", + "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/adjust-sourcemap-loader": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-2.0.0.tgz", + "integrity": "sha512-4hFsTsn58+YjrU9qKzML2JSSDqKvN8mUGQ0nNIrfPi8hmIONT4L3uUaT6MKdMsZ9AjsU6D2xDkZxCkbQPxChrA==", + "dependencies": { + "assert": "1.4.1", + "camelcase": "5.0.0", + "loader-utils": "1.2.3", + "object-path": "0.11.4", + "regex-parser": "2.2.10" + } + }, + "node_modules/adjust-sourcemap-loader/node_modules/camelcase": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", + "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/adjust-sourcemap-loader/node_modules/emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha512-knHEZMgs8BB+MInokmNTg/OyPlAddghe1YBgNwJBc5zsJi/uyIcXoSDsL/W9ymOsBoBGdPIHXYJ9+qKFwRwDng==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/adjust-sourcemap-loader/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/adjust-sourcemap-loader/node_modules/loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "peerDependencies": { + "ajv": ">=5.0.0" + } + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha512-0FcBfdcmaumGPQ0qPn7Q5qTgz/ooXgIyp1rf8ik5bGX8mpE2YHjC0P/eyQvxu1GURYQgq9ozf2mteQ5ZD9YiyQ==" + }, + "node_modules/ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha512-JoAxEa1DfP9m2xfB/y2r/aKcwXNlltr4+0QSBC4TrLfcxyvepX2Pv0t/xpgGV5bGsDzCYV8SzjWgyCW0T9yYbA==", + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/anymatch/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/arity-n": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arity-n/-/arity-n-1.0.4.tgz", + "integrity": "sha512-fExL2kFDC1Q2DUOx3whE/9KoN66IzkY4b4zUHUBFM1ojEYjZZYDcUW3bek/ufGionX9giIKDC5redH2IlGqcQQ==" + }, + "node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-equal": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.2.tgz", + "integrity": "sha512-gUHx76KtnhEgB3HOuFYiCm3FIdEs6ocM2asHvNTkfu/Y09qQVrrVVaOKENmS2KkSaGoxgXNqC+ZVtR/n0MOkSA==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.reduce": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.7.tgz", + "integrity": "sha512-mzmiUCVwtiD4lgxYP8g7IYy8El8p2CSMePvIbTS7gchKir/L1fgJrk0yDKmAX6mnRQFKNADYIk8nNlTris5H1Q==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-array-method-boxes-properly": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/asn1.js/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha512-N+aAxov+CKVS3JuhDIQFr24XvZvwE96Wlhk9dytTg/GmwWoghdOvR8dspx8MVz71O+Y0pA3UPqHF68D6iy8UvQ==", + "dependencies": { + "util": "0.10.3" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==" + }, + "node_modules/astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/async-each": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.6.tgz", + "integrity": "sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/autoprefixer": { + "version": "9.8.8", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz", + "integrity": "sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==", + "dependencies": { + "browserslist": "^4.12.0", + "caniuse-lite": "^1.0.30001109", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "picocolors": "^0.2.1", + "postcss": "^7.0.32", + "postcss-value-parser": "^4.1.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + }, + "node_modules/autoprefixer/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" + }, + "node_modules/autosize": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/autosize/-/autosize-4.0.4.tgz", + "integrity": "sha512-5yxLQ22O0fCRGoxGfeLSNt3J8LB1v+umtpMnPW6XjkTWXKoN0AmXAIhelJcDtFT/Y/wYWmfE+oqU10Q0b8FhaQ==" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" + }, + "node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, + "node_modules/axobject-query": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", + "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==" + }, + "node_modules/babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", + "dependencies": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "node_modules/babel-code-frame/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/babel-code-frame/node_modules/js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==" + }, + "node_modules/babel-code-frame/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/babel-eslint": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", + "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", + "deprecated": "babel-eslint is now @babel/eslint-parser. This package will no longer receive updates.", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0", + "eslint-visitor-keys": "^1.0.0", + "resolve": "^1.12.0" + }, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "eslint": ">= 4.12.1" + } + }, + "node_modules/babel-extract-comments": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz", + "integrity": "sha512-qWWzi4TlddohA91bFwgt6zO/J0X+io7Qp184Fw0m2JYRSTZnJbFR8+07KmzudHCZgOiKRCrjhylwv9Xd8gfhVQ==", + "dependencies": { + "babylon": "^6.18.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/babel-jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz", + "integrity": "sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==", + "dependencies": { + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/babel__core": "^7.1.0", + "babel-plugin-istanbul": "^5.1.0", + "babel-preset-jest": "^24.9.0", + "chalk": "^2.4.2", + "slash": "^2.0.0" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-jest/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/babel-jest/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/babel-jest/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/babel-jest/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/babel-jest/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/babel-jest/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/babel-jest/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/babel-jest/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/babel-jest/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/babel-jest/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/babel-jest/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/babel-loader": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", + "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==", + "dependencies": { + "find-cache-dir": "^2.1.0", + "loader-utils": "^1.4.0", + "mkdirp": "^0.5.3", + "pify": "^4.0.1", + "schema-utils": "^2.6.5" + }, + "engines": { + "node": ">= 6.9" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "webpack": ">=2" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz", + "integrity": "sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "find-up": "^3.0.0", + "istanbul-lib-instrument": "^3.3.0", + "test-exclude": "^5.2.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz", + "integrity": "sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==", + "dependencies": { + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-plugin-named-asset-import": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz", + "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==", + "peerDependencies": { + "@babel/core": "^7.1.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.2", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", + "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.1", + "core-js-compat": "^3.36.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-styled-components": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.4.tgz", + "integrity": "sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", + "lodash": "^4.17.21", + "picomatch": "^2.3.1" + }, + "peerDependencies": { + "styled-components": ">= 2" + } + }, + "node_modules/babel-plugin-syntax-object-rest-spread": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "integrity": "sha512-C4Aq+GaAj83pRQ0EFgTvw5YO6T3Qz2KGrNRwIj9mSoNHVvdZY4KO2uA6HNtNXCw993iSZnckY1aLW8nOi8i4+w==" + }, + "node_modules/babel-plugin-transform-object-rest-spread": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", + "integrity": "sha512-ocgA9VJvyxwt+qJB0ncxV8kb/CjfTcECUY4tQ5VT7nP6Aohzobm8CDFaQ5FHdvZQzLmf0sgDxB8iRXZXxwZcyA==", + "dependencies": { + "babel-plugin-syntax-object-rest-spread": "^6.8.0", + "babel-runtime": "^6.26.0" + } + }, + "node_modules/babel-plugin-transform-react-remove-prop-types": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", + "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==" + }, + "node_modules/babel-preset-jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz", + "integrity": "sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==", + "dependencies": { + "@babel/plugin-syntax-object-rest-spread": "^7.0.0", + "babel-plugin-jest-hoist": "^24.9.0" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-react-app": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-9.1.2.tgz", + "integrity": "sha512-k58RtQOKH21NyKtzptoAvtAODuAJJs3ZhqBMl456/GnXEQ/0La92pNmwgWoMn5pBTrsvk3YYXdY7zpY4e3UIxA==", + "dependencies": { + "@babel/core": "7.9.0", + "@babel/plugin-proposal-class-properties": "7.8.3", + "@babel/plugin-proposal-decorators": "7.8.3", + "@babel/plugin-proposal-nullish-coalescing-operator": "7.8.3", + "@babel/plugin-proposal-numeric-separator": "7.8.3", + "@babel/plugin-proposal-optional-chaining": "7.9.0", + "@babel/plugin-transform-flow-strip-types": "7.9.0", + "@babel/plugin-transform-react-display-name": "7.8.3", + "@babel/plugin-transform-runtime": "7.9.0", + "@babel/preset-env": "7.9.0", + "@babel/preset-react": "7.9.1", + "@babel/preset-typescript": "7.9.0", + "@babel/runtime": "7.9.0", + "babel-plugin-macros": "2.8.0", + "babel-plugin-transform-react-remove-prop-types": "0.4.24" + } + }, + "node_modules/babel-preset-react-app/node_modules/@babel/core": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", + "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.0", + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helpers": "^7.9.0", + "@babel/parser": "^7.9.0", + "@babel/template": "^7.8.6", + "@babel/traverse": "^7.9.0", + "@babel/types": "^7.9.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/babel-preset-react-app/node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.8.3.tgz", + "integrity": "sha512-3Jy/PCw8Fe6uBKtEgz3M82ljt+lTg+xJaM4og+eyu83qLT87ZUSckn0wy7r31jflURWLO83TW6Ylf7lyXj3m5A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-preset-react-app/node_modules/@babel/preset-env": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.9.0.tgz", + "integrity": "sha512-712DeRXT6dyKAM/FMbQTV/FvRCms2hPCx+3weRjZ8iQVQWZejWWk1wwG6ViWMyqb/ouBbGOl5b6aCk0+j1NmsQ==", + "dependencies": { + "@babel/compat-data": "^7.9.0", + "@babel/helper-compilation-targets": "^7.8.7", + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-proposal-async-generator-functions": "^7.8.3", + "@babel/plugin-proposal-dynamic-import": "^7.8.3", + "@babel/plugin-proposal-json-strings": "^7.8.3", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-proposal-numeric-separator": "^7.8.3", + "@babel/plugin-proposal-object-rest-spread": "^7.9.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.8.3", + "@babel/plugin-proposal-optional-chaining": "^7.9.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.8.3", + "@babel/plugin-syntax-async-generators": "^7.8.0", + "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "@babel/plugin-syntax-json-strings": "^7.8.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", + "@babel/plugin-syntax-numeric-separator": "^7.8.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.0", + "@babel/plugin-syntax-top-level-await": "^7.8.3", + "@babel/plugin-transform-arrow-functions": "^7.8.3", + "@babel/plugin-transform-async-to-generator": "^7.8.3", + "@babel/plugin-transform-block-scoped-functions": "^7.8.3", + "@babel/plugin-transform-block-scoping": "^7.8.3", + "@babel/plugin-transform-classes": "^7.9.0", + "@babel/plugin-transform-computed-properties": "^7.8.3", + "@babel/plugin-transform-destructuring": "^7.8.3", + "@babel/plugin-transform-dotall-regex": "^7.8.3", + "@babel/plugin-transform-duplicate-keys": "^7.8.3", + "@babel/plugin-transform-exponentiation-operator": "^7.8.3", + "@babel/plugin-transform-for-of": "^7.9.0", + "@babel/plugin-transform-function-name": "^7.8.3", + "@babel/plugin-transform-literals": "^7.8.3", + "@babel/plugin-transform-member-expression-literals": "^7.8.3", + "@babel/plugin-transform-modules-amd": "^7.9.0", + "@babel/plugin-transform-modules-commonjs": "^7.9.0", + "@babel/plugin-transform-modules-systemjs": "^7.9.0", + "@babel/plugin-transform-modules-umd": "^7.9.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3", + "@babel/plugin-transform-new-target": "^7.8.3", + "@babel/plugin-transform-object-super": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.8.7", + "@babel/plugin-transform-property-literals": "^7.8.3", + "@babel/plugin-transform-regenerator": "^7.8.7", + "@babel/plugin-transform-reserved-words": "^7.8.3", + "@babel/plugin-transform-shorthand-properties": "^7.8.3", + "@babel/plugin-transform-spread": "^7.8.3", + "@babel/plugin-transform-sticky-regex": "^7.8.3", + "@babel/plugin-transform-template-literals": "^7.8.3", + "@babel/plugin-transform-typeof-symbol": "^7.8.4", + "@babel/plugin-transform-unicode-regex": "^7.8.3", + "@babel/preset-modules": "^0.1.3", + "@babel/types": "^7.9.0", + "browserslist": "^4.9.1", + "core-js-compat": "^3.6.2", + "invariant": "^2.2.2", + "levenary": "^1.1.1", + "semver": "^5.5.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-preset-react-app/node_modules/@babel/preset-modules": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6.tgz", + "integrity": "sha512-ID2yj6K/4lKfhuU3+EX4UvNbIt7eACFbHmNUjzA+ep+B5971CknnA/9DEWKbRokfbbtblxxxXFJJrH47UEAMVg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-preset-react-app/node_modules/@babel/preset-react": { + "version": "7.9.1", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.9.1.tgz", + "integrity": "sha512-aJBYF23MPj0RNdp/4bHnAP0NVqqZRr9kl0NAOP4nJCex6OYVio59+dnQzsAWFuogdLyeaKA1hmfUIVZkY5J+TQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-transform-react-display-name": "^7.8.3", + "@babel/plugin-transform-react-jsx": "^7.9.1", + "@babel/plugin-transform-react-jsx-development": "^7.9.0", + "@babel/plugin-transform-react-jsx-self": "^7.9.0", + "@babel/plugin-transform-react-jsx-source": "^7.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-preset-react-app/node_modules/@babel/runtime": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.0.tgz", + "integrity": "sha512-cTIudHnzuWLS56ik4DnRnqqNf8MkdUzV4iFFI1h7Jo9xvrpQROYaAnaSd2mHLQAzzZAPfATynX5ord6YlNYNMA==", + "dependencies": { + "regenerator-runtime": "^0.13.4" + } + }, + "node_modules/babel-preset-react-app/node_modules/babel-plugin-macros": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz", + "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "cosmiconfig": "^6.0.0", + "resolve": "^1.12.0" + } + }, + "node_modules/babel-preset-react-app/node_modules/cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-preset-react-app/node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, + "node_modules/babel-preset-react-app/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", + "dependencies": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "node_modules/babel-runtime/node_modules/core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", + "hasInstallScript": true + }, + "node_modules/babel-runtime/node_modules/regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + }, + "node_modules/babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "bin": { + "babylon": "bin/babylon.js" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha512-RaVTblr+OnEli0r/ud8InrU7D+G0y6aJhlxaLa6Pwty4+xoxboF1BsUI45tujvRpbj9dQVoglChqonGAsjEBYg==", + "dependencies": { + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, + "node_modules/bootstrap": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz", + "integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "peerDependencies": { + "@popperjs/core": "^2.11.8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/broadcast-channel": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-3.7.0.tgz", + "integrity": "sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "detect-node": "^2.1.0", + "js-sha3": "0.8.0", + "microseconds": "0.2.0", + "nano-time": "1.0.0", + "oblivious-set": "1.0.0", + "rimraf": "3.0.2", + "unload": "2.2.0" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" + }, + "node_modules/browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dependencies": { + "resolve": "1.1.7" + } + }, + "node_modules/browser-resolve/node_modules/resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==" + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dependencies": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/browserify-sign": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz", + "integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==", + "dependencies": { + "bn.js": "^5.2.1", + "browserify-rsa": "^4.1.0", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.5", + "hash-base": "~3.0", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.7", + "readable-stream": "^2.3.8", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dependencies": { + "pako": "~1.0.5" + } + }, + "node_modules/browserslist": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==" + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" + }, + "node_modules/buffer/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==" + }, + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz", + "integrity": "sha512-5ZvAxd05HDDU+y9BVvcqYu2LLXmPnQ0hW62h32g4xBTgL/MppR4/04NHfj/ycM2y6lmTnbw6HVi+1eN0Psba6w==", + "dependencies": { + "chownr": "^1.1.2", + "figgy-pudding": "^3.5.1", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.2", + "infer-owner": "^1.0.4", + "lru-cache": "^5.1.1", + "minipass": "^3.0.0", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "p-map": "^3.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^2.7.1", + "ssri": "^7.0.0", + "unique-filename": "^1.1.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cacache/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==" + }, + "node_modules/caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", + "dependencies": { + "callsites": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/caller-callsite/node_modules/callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", + "dependencies": { + "caller-callsite": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001612", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz", + "integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "dependencies": { + "rsvp": "^4.8.4" + }, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/case-sensitive-paths-webpack-plugin": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz", + "integrity": "sha512-/4YgnZS8y1UXXmC02xD5rRrBEu6T5ub+mQHLNRj0fzTRbgdBYhsNo2V5EqwgqrExjxsjtF/OpAKAMkKsxbD5XQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, + "node_modules/chart.js": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.9.1.tgz", + "integrity": "sha512-Ro2JbLmvg83gXF5F4sniaQ+lTbSv18E+TIf2cOeiH1Iqd2PGFOtem+DUufMZsCJwFE7ywPOpfXFBwRTGq7dh6w==" + }, + "node_modules/chartjs-plugin-datalabels": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/chartjs-plugin-datalabels/-/chartjs-plugin-datalabels-2.2.0.tgz", + "integrity": "sha512-14ZU30lH7n89oq+A4bWaJPnAG8a7ZTk7dKf48YAzMvJjQtjrgg5Dpk9f+LbjCF6bpx3RAGTeL13IXpKQYyRvlw==", + "peerDependencies": { + "chart.js": ">=3.0.0" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/chokidar/node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" + }, + "node_modules/clean-css": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", + "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/clean-css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "engines": { + "node": ">=4" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-deep": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-0.2.4.tgz", + "integrity": "sha512-we+NuQo2DHhSl+DP6jlUiAhyAjBQrYnpOk15rN6c6JSPScjiCLh8IbSU+VTcph6YS3o7mASE8a0+gbZ7ChLpgg==", + "dependencies": { + "for-own": "^0.1.3", + "is-plain-object": "^2.0.1", + "kind-of": "^3.0.2", + "lazy-cache": "^1.0.3", + "shallow-clone": "^0.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "dependencies": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/coa/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/coa/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/coa/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/coa/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/color/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" + }, + "node_modules/component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/compose-function": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz", + "integrity": "sha512-xzhzTJ5eC+gmIzvZq+C3kCJHsp9os6tJkrigDRZclyGtOKINbZtE8n1Tzmeh32jW+BUDPbvZpibwvJHBLGMVwg==", + "dependencies": { + "arity-n": "^1.0.4" + } + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==" + }, + "node_modules/connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" + }, + "node_modules/constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==" + }, + "node_modules/contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha512-OKZnPGeMQy2RPaUIBPFFd71iNf4791H12MCRuVQDnzGRwCYNYmTDy5pdafo2SLAcEMKzTOQnLWG4QdcjeJUMEg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/context": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/context/-/context-4.0.0.tgz", + "integrity": "sha512-B5XTstvpRXt79RkiLR+/XqSCDPrtAsdIZAhZuBCj1bXzuHy7HVbhee+aJ/pHP/+pYrP7YAHdqDH91vfuwqD9/w==", + "dependencies": { + "vest-utils": "^0.0.5" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dependencies": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "node_modules/copy-concurrently/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/copy-to-clipboard": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", + "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", + "dependencies": { + "toggle-selection": "^1.0.6" + } + }, + "node_modules/core-js": { + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.0.tgz", + "integrity": "sha512-fu5vHevQ8ZG4og+LXug8ulUtVxjOcEYvifJr7L5Bfq9GOztVqsKd9/59hUk2ZSbCrS3BqUr3EpaYGIYzq7g3Ug==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat": { + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.0.tgz", + "integrity": "sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA==", + "dependencies": { + "browserslist": "^4.23.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-pure": { + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.37.0.tgz", + "integrity": "sha512-d3BrpyFr5eD4KcbRvQ3FTUx/KWmaDesr7+a3+1+P46IUnNoEt+oiLijPINZMEon7w9oGkIINWxrBAU9DEciwFQ==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/create-ecdh/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/cross-spawn/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "dependencies": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + } + }, + "node_modules/css-blank-pseudo": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz", + "integrity": "sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w==", + "dependencies": { + "postcss": "^7.0.5" + }, + "bin": { + "css-blank-pseudo": "cli.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha512-zj5D7X1U2h2zsXOAM8EyUREBnnts6H+Jm+d1M2DbiQQcUtnqgQsMrdo8JW9R80YFUmIdBZeMu5wvYM7hcgWP/Q==", + "engines": { + "node": "*" + } + }, + "node_modules/css-declaration-sorter": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", + "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", + "dependencies": { + "postcss": "^7.0.1", + "timsort": "^0.3.0" + }, + "engines": { + "node": ">4" + } + }, + "node_modules/css-has-pseudo": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz", + "integrity": "sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ==", + "dependencies": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^5.0.0-rc.4" + }, + "bin": { + "css-has-pseudo": "cli.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/css-has-pseudo/node_modules/cssesc": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", + "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/css-has-pseudo/node_modules/postcss-selector-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", + "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", + "dependencies": { + "cssesc": "^2.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/css-loader": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.4.2.tgz", + "integrity": "sha512-jYq4zdZT0oS0Iykt+fqnzVLRIeiPWhka+7BqPn+oSIpWJAHak5tmB/WZrJ2a21JhCeFyNnnlroSl8c+MtVndzA==", + "dependencies": { + "camelcase": "^5.3.1", + "cssesc": "^3.0.0", + "icss-utils": "^4.1.1", + "loader-utils": "^1.2.3", + "normalize-path": "^3.0.0", + "postcss": "^7.0.23", + "postcss-modules-extract-imports": "^2.0.0", + "postcss-modules-local-by-default": "^3.0.2", + "postcss-modules-scope": "^2.1.1", + "postcss-modules-values": "^3.0.0", + "postcss-value-parser": "^4.0.2", + "schema-utils": "^2.6.0" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/css-prefers-color-scheme": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz", + "integrity": "sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg==", + "dependencies": { + "postcss": "^7.0.5" + }, + "bin": { + "css-prefers-color-scheme": "cli.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" + }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, + "node_modules/css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "dependencies": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/css-tree/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-vendor": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz", + "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==", + "dependencies": { + "@babel/runtime": "^7.8.3", + "is-in-browser": "^1.0.2" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==" + }, + "node_modules/css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cssdb": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-4.4.0.tgz", + "integrity": "sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ==" + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz", + "integrity": "sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==", + "dependencies": { + "cosmiconfig": "^5.0.0", + "cssnano-preset-default": "^4.0.8", + "is-resolvable": "^1.0.0", + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-preset-default": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz", + "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==", + "dependencies": { + "css-declaration-sorter": "^4.0.1", + "cssnano-util-raw-cache": "^4.0.1", + "postcss": "^7.0.0", + "postcss-calc": "^7.0.1", + "postcss-colormin": "^4.0.3", + "postcss-convert-values": "^4.0.1", + "postcss-discard-comments": "^4.0.2", + "postcss-discard-duplicates": "^4.0.2", + "postcss-discard-empty": "^4.0.1", + "postcss-discard-overridden": "^4.0.1", + "postcss-merge-longhand": "^4.0.11", + "postcss-merge-rules": "^4.0.3", + "postcss-minify-font-values": "^4.0.2", + "postcss-minify-gradients": "^4.0.2", + "postcss-minify-params": "^4.0.2", + "postcss-minify-selectors": "^4.0.2", + "postcss-normalize-charset": "^4.0.1", + "postcss-normalize-display-values": "^4.0.2", + "postcss-normalize-positions": "^4.0.2", + "postcss-normalize-repeat-style": "^4.0.2", + "postcss-normalize-string": "^4.0.2", + "postcss-normalize-timing-functions": "^4.0.2", + "postcss-normalize-unicode": "^4.0.1", + "postcss-normalize-url": "^4.0.1", + "postcss-normalize-whitespace": "^4.0.2", + "postcss-ordered-values": "^4.1.2", + "postcss-reduce-initial": "^4.0.3", + "postcss-reduce-transforms": "^4.0.2", + "postcss-svgo": "^4.0.3", + "postcss-unique-selectors": "^4.0.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-get-arguments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", + "integrity": "sha512-6RIcwmV3/cBMG8Aj5gucQRsJb4vv4I4rn6YjPbVWd5+Pn/fuG+YseGvXGk00XLkoZkaj31QOD7vMUpNPC4FIuw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-get-match": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", + "integrity": "sha512-JPMZ1TSMRUPVIqEalIBNoBtAYbi8okvcFns4O0YIhcdGebeYZK7dMyHJiQ6GqNBA9kE0Hym4Aqym5rPdsV/4Cw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-raw-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", + "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-same-parent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", + "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano/node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano/node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dependencies": { + "css-tree": "^1.1.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + }, + "node_modules/csso/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + }, + "node_modules/cssstyle": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", + "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", + "dependencies": { + "cssom": "0.3.x" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/cyclist": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.2.tgz", + "integrity": "sha512-0sVXIohTfLqVIW3kb/0n6IiWF3Ifj5nm2XaSrLq2DI6fKIGa2fYAZdk917rUneaeLVpYfFcyXE2ft0fe3remsA==" + }, + "node_modules/d": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", + "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", + "dependencies": { + "es5-ext": "^0.10.64", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "dependencies": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + } + }, + "node_modules/data-urls/node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/date-arithmetic": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/date-arithmetic/-/date-arithmetic-4.1.0.tgz", + "integrity": "sha512-QWxYLR5P/6GStZcdem+V1xoto6DMadYWpMXU82ES3/RfR3Wdwr3D0+be7mgOJ+Ov0G9D5Dmb9T17sNLQYj9XOg==" + }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/dayjs": { + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" + }, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/deep-diff": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/deep-diff/-/deep-diff-0.3.8.tgz", + "integrity": "sha512-yVn6RZmHiGnxRKR9sJb3iVV2XTF1Ghh2DiWRZ3dMnGc43yUdWWF/kX6lQyk3+P84iprfWKU/8zFTrlkvtFm1ug==" + }, + "node_modules/deep-equal": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.2.tgz", + "integrity": "sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==", + "dependencies": { + "is-arguments": "^1.1.1", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.5.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + }, + "node_modules/deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-gateway": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", + "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + "dependencies": { + "execa": "^1.0.0", + "ip-regex": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "dependencies": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/del/node_modules/globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", + "dependencies": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del/node_modules/globby/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del/node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/del/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/des.js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", + "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-newline": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", + "integrity": "sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + }, + "node_modules/detect-port-alt": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", + "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", + "dependencies": { + "address": "^1.0.1", + "debug": "^2.6.0" + }, + "bin": { + "detect": "bin/detect-port", + "detect-port": "bin/detect-port" + }, + "engines": { + "node": ">= 4.2.1" + } + }, + "node_modules/detect-port-alt/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/detect-port-alt/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/diffie-hellman/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/dir-glob": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz", + "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==", + "dependencies": { + "arrify": "^1.0.1", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/dir-glob/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/dir-glob/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==" + }, + "node_modules/dns-packet": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz", + "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==", + "dependencies": { + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha512-Ix5PrWjphuSoUXV/Zv5gaFHjnaJtb02F2+Si3Ht9dyJ87+Z/lMmy+dpNHtTGraNK958ndXq2i+GLkWsWHcKaBQ==", + "dependencies": { + "buffer-indexof": "^1.0.0" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==" + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "engines": { + "node": ">=0.4", + "npm": ">=1.2" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "deprecated": "Use your platform's native DOMException instead", + "dependencies": { + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dot-prop/node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", + "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv-expand": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, + "node_modules/duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dependencies": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.747", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.747.tgz", + "integrity": "sha512-+FnSWZIAvFHbsNVmUxhEqWiaOiPMcfum1GQzlWCg/wLigVtshOsjXHyEFfmt6cFK6+HkS3QOJBv6/3OPumbBfw==" + }, + "node_modules/elliptic": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.5.tgz", + "integrity": "sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/emoji-mart": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/emoji-mart/-/emoji-mart-3.0.1.tgz", + "integrity": "sha512-sxpmMKxqLvcscu6mFn9ITHeZNkGzIvD0BSNFE/LJESPbCA8s1jM6bCDPjWbV31xHq7JXaxgpHxLB54RCbBZSlg==", + "dependencies": { + "@babel/runtime": "^7.0.0", + "prop-types": "^15.6.0" + }, + "peerDependencies": { + "react": "^0.14.0 || ^15.0.0-0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/engine.io-client": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz", + "integrity": "sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.11.0", + "xmlhttprequest-ssl": "~2.0.0" + } + }, + "node_modules/engine.io-client/node_modules/ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", + "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", + "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", + "dependencies": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/enhanced-resolve/node_modules/memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dependencies": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + }, + "engines": { + "node": ">=4.3.0 <5.0.0 || >=5.10" + } + }, + "node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==" + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es5-ext": { + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", + "hasInstallScript": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", + "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", + "dependencies": { + "d": "^1.0.2", + "ext": "^1.7.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", + "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.3", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.2", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^7.0.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.3", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-react-app": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-5.2.1.tgz", + "integrity": "sha512-pGIZ8t0mFLcV+6ZirRgYK6RVqUIKRIi9MmgzUEmrIknsn3AdO0I32asO86dJgloHq+9ZPl8UIg8mYrvgP5u2wQ==", + "dependencies": { + "confusing-browser-globals": "^1.0.9" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "2.x", + "@typescript-eslint/parser": "2.x", + "babel-eslint": "10.x", + "eslint": "6.x", + "eslint-plugin-flowtype": "3.x || 4.x", + "eslint-plugin-import": "2.x", + "eslint-plugin-jsx-a11y": "6.x", + "eslint-plugin-react": "7.x", + "eslint-plugin-react-hooks": "1.x || 2.x" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-loader": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-3.0.3.tgz", + "integrity": "sha512-+YRqB95PnNvxNp1HEjQmvf9KNvCin5HXYYseOXVC2U0KEcw4IkQ2IQEBG46j7+gW39bMzeu0GsUhVbBY3Votpw==", + "deprecated": "This loader has been deprecated. Please use eslint-webpack-plugin", + "dependencies": { + "fs-extra": "^8.1.0", + "loader-fs-cache": "^1.0.2", + "loader-utils": "^1.2.3", + "object-hash": "^2.0.1", + "schema-utils": "^2.6.1" + }, + "engines": { + "node": ">= 8.9.0" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0", + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-flowtype": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-4.6.0.tgz", + "integrity": "sha512-W5hLjpFfZyZsXfo5anlu7HM970JBDqbEshAJUkeczP6BFCIfJXuiIBQXyberLRtOStT0OGPF8efeTbxlHk4LpQ==", + "dependencies": { + "lodash": "^4.17.15" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": ">=6.1.0" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz", + "integrity": "sha512-qQHgFOTjguR+LnYRoToeZWT62XM55MBVXObHM6SKFd1VzDcX/vqT1kAz8ssqigh5eMj8qXcRoXXGZpPP6RfdCw==", + "dependencies": { + "array-includes": "^3.0.3", + "array.prototype.flat": "^1.2.1", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.1", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.0", + "read-pkg-up": "^2.0.0", + "resolve": "^1.12.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "2.x - 6.x" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha512-lsGyRuYr4/PIB0txi+Fy2xOMI2dGaTguCaotzFGkVZuKR5usKfcRWIFKNM3QNrU7hh/+w2bwTW+ZeXPK5l8uVg==", + "dependencies": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz", + "integrity": "sha512-CawzfGt9w83tyuVekn0GDPU9ytYtxyxyFZ3aSWROmnRRFQFT2BiPJd7jvRdzNDi6oLWaS2asMeYSNMjWTV4eNg==", + "dependencies": { + "@babel/runtime": "^7.4.5", + "aria-query": "^3.0.0", + "array-includes": "^3.0.3", + "ast-types-flow": "^0.0.7", + "axobject-query": "^2.0.2", + "damerau-levenshtein": "^1.0.4", + "emoji-regex": "^7.0.2", + "has": "^1.0.3", + "jsx-ast-utils": "^2.2.1" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/aria-query": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", + "integrity": "sha512-majUxHgLehQTeSA+hClx+DY09OVUqG3GtezWkF1krgLGNdlDu9l9V8DaqNMWbq4Eddc8wsyDA0hpDUtnYxQEXw==", + "dependencies": { + "ast-types-flow": "0.0.7", + "commander": "^2.11.0" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/eslint-plugin-react": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.19.0.tgz", + "integrity": "sha512-SPT8j72CGuAP+JFbT0sJHOB80TX/pu44gQ4vXH/cq+hQTiY2PuZ6IHkqXJV6x1b28GDdo1lbInjKUrrdUf0LOQ==", + "dependencies": { + "array-includes": "^3.1.1", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.2.3", + "object.entries": "^1.1.1", + "object.fromentries": "^2.0.2", + "object.values": "^1.1.1", + "prop-types": "^15.7.2", + "resolve": "^1.15.1", + "semver": "^6.3.0", + "string.prototype.matchall": "^4.0.2", + "xregexp": "^4.3.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz", + "integrity": "sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA==", + "engines": { + "node": ">=7" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint/node_modules/eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dependencies": { + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "engines": { + "node": ">=6.5.0" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/espree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", + "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "dependencies": { + "acorn": "^7.1.1", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/eventsource": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.2.tgz", + "integrity": "sha512-xAH3zWhgO2/3KIniEKYPr8plNSzlGINOUqYj0m0u7AB81iRw8b/3E73W6AuU+6klLbaSFmZnaETQ2lXPfAydrA==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/exec-sh": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz", + "integrity": "sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==" + }, + "node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/expand-brackets/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/express": { + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/express/node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/express/node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extend-shallow/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-equals": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz", + "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/fast-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "dependencies": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/fast-glob/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-glob/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "node_modules/faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha512-Xhj93RXbMSq8urNCUq4p9l0P6hnySJ/7YNRhYNug0bLOuii7pKO7xQFb5mx9xZXWCar88pLPb805PvUkwrLZpQ==", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", + "deprecated": "This module is no longer supported." + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dependencies": { + "flat-cache": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/file-loader": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-4.3.0.tgz", + "integrity": "sha512-aKrYPYjF1yG3oX0kWRrqrSMfgftm7oJW5M+m4owoldH5C51C0RkIwB++JbRvEW3IU6/ZG5n8UvEcdgwOt2UOWA==", + "dependencies": { + "loader-utils": "^1.2.3", + "schema-utils": "^2.5.0" + }, + "engines": { + "node": ">= 8.9.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "optional": true + }, + "node_modules/filesize": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.0.1.tgz", + "integrity": "sha512-u4AYWPgbI5GBhs6id1KdImZWn5yfyFrrQ8OWZdN7ZMfA8Bf4HcO0BGo9bmUIEV8yrp8I1xVfJ/dn90GtFNNJcg==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/filter-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", + "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, + "node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dependencies": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==" + }, + "node_modules/flatten": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", + "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==", + "deprecated": "flatten is deprecated in favor of utility frameworks such as lodash." + }, + "node_modules/flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha512-SKmowqGTJoPzLO1T0BBJpkfp3EMacCMOuH40hOUbrbzElVktk4DioXVM99QkLCyKoiuOmyjgcWMpVz2xjE7LZw==", + "dependencies": { + "for-in": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "engines": { + "node": "*" + } + }, + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-3.1.1.tgz", + "integrity": "sha512-DuVkPNrM12jR41KM2e+N+styka0EgLkTnXmNcXdgOM37vtGeY+oCBK/Jx0hzSeEU6memFCtWb4htrHPMDfwwUQ==", + "dependencies": { + "babel-code-frame": "^6.22.0", + "chalk": "^2.4.1", + "chokidar": "^3.3.0", + "micromatch": "^3.1.10", + "minimatch": "^3.0.4", + "semver": "^5.6.0", + "tapable": "^1.0.0", + "worker-rpc": "^0.1.0" + }, + "engines": { + "node": ">=6.11.5", + "yarn": ">=1.0.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/formik": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.5.tgz", + "integrity": "sha512-Gxlht0TD3vVdzMDHwkiNZqJ7Mvg77xQNfmBRrNtvzcHZs72TJppSTDKHpImCMJZwcWPBJ8jSQQ95GJzXFf1nAQ==", + "funding": [ + { + "type": "individual", + "url": "https://opencollective.com/formik" + } + ], + "dependencies": { + "@types/hoist-non-react-statics": "^3.3.1", + "deepmerge": "^2.1.1", + "hoist-non-react-statics": "^3.3.0", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "react-fast-compare": "^2.0.1", + "tiny-warning": "^1.0.2", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/formik-material-ui": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/formik-material-ui/-/formik-material-ui-3.0.1.tgz", + "integrity": "sha512-N8oxZIdhY70npRv86IfF6Zaaps9RL3a37XRdq02WDroB3XZC1mXs6lA/zQ09ZYFWYJp/UjI80SKVpVa/xJOJJA==", + "peerDependencies": { + "@material-ui/core": ">=4.0.0", + "formik": ">=2.0.0", + "react": ">=16.8.0", + "tiny-warning": ">=1.0.2" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==", + "dependencies": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", + "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "deprecated": "\"Please update to latest v2.3 or v2.2\"", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==" + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" + }, + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==" + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/globalize": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/globalize/-/globalize-0.1.1.tgz", + "integrity": "sha512-5e01v8eLGfuQSOvx2MsDMOWS0GFtCx1wPzQSmcHw4hkxFzrQDBO3Xwg/m8Hr/7qXMrHeOIE29qWVzyv06u1TZA==" + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.2.tgz", + "integrity": "sha512-yTzMmKygLp8RUpG1Ymu2VXPSJQZjNAZPD4ywgYEaG7e4tBJeUQBO8OpXrf1RCNcEs5alsoJYPAMiIHP0cmeC7w==", + "dependencies": { + "array-union": "^1.0.1", + "dir-glob": "2.0.0", + "fast-glob": "^2.0.2", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/globby/node_modules/ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==" + }, + "node_modules/globby/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/globby/node_modules/slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gn-api-sdk-node": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/gn-api-sdk-node/-/gn-api-sdk-node-3.0.4.tgz", + "integrity": "sha512-DZKeTj9bw+Ybe2ZZG9oeWlOEPUm3wsSpLnr/ZAEhxR2Q+b4xZ9juo0tblvc2qi6Q+hnEs03LOR+ULr+kt8mYkQ==", + "dependencies": { + "axios": "^1.2.1", + "randomstring": "^1.2.2" + } + }, + "node_modules/gn-api-sdk-node/node_modules/axios": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", + "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/gn-api-sdk-node/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==" + }, + "node_modules/gzip-size": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", + "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", + "dependencies": { + "duplexer": "^0.1.1", + "pify": "^4.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/harmony-reflect": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", + "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==" + }, + "node_modules/has": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hex-color-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", + "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" + }, + "node_modules/history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "dependencies": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" + }, + "node_modules/howler": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/howler/-/howler-2.2.4.tgz", + "integrity": "sha512-iARIBPgcQrwtEr+tALF+rapJ8qSc+Set2GJQl7xT1MQzWaVkFebdJhR3alVlSiUf5U7nAANKuj3aWpwerocD5w==" + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hsl-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", + "integrity": "sha512-M5ezZw4LzXbBKMruP+BNANf0k+19hDQMgpzBIYnya//Al+fjNct9Wf3b1WedLqdEs2hKBvxq/jh+DsHJLj0F9A==" + }, + "node_modules/hsla-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", + "integrity": "sha512-7Wn5GMLuHBjZCb2bTmnDOycho0p/7UVaAeqXZGbHrBCl6Yd/xDhQJAXe6Ga9AXJH2I5zY1dEdYw2u1UptnSBJA==" + }, + "node_modules/html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dependencies": { + "whatwg-encoding": "^1.0.1" + } + }, + "node_modules/html-entities": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz", + "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==" + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + }, + "node_modules/html-minifier-terser": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", + "integrity": "sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg==", + "dependencies": { + "camel-case": "^4.1.1", + "clean-css": "^4.2.3", + "commander": "^4.1.1", + "he": "^1.2.0", + "param-case": "^3.0.3", + "relateurl": "^0.2.7", + "terser": "^4.6.3" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/html-webpack-plugin": { + "version": "4.0.0-beta.11", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.0.0-beta.11.tgz", + "integrity": "sha512-4Xzepf0qWxf8CGg7/WQM5qBB2Lc/NFI7MhU59eUDTkuQp3skZczH4UA1d6oQyDEIoMDgERVhRyTdtUPZ5s5HBg==", + "deprecated": "please switch to a stable version", + "dependencies": { + "html-minifier-terser": "^5.0.1", + "loader-utils": "^1.2.3", + "lodash": "^4.17.15", + "pretty-error": "^2.1.1", + "tapable": "^1.1.3", + "util.promisify": "1.0.0" + }, + "engines": { + "node": ">=6.9" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", + "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", + "dependencies": { + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.11", + "micromatch": "^3.1.10" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==" + }, + "node_modules/hyphenate-style-name": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", + "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==" + }, + "node_modules/i18next": { + "version": "19.9.2", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-19.9.2.tgz", + "integrity": "sha512-0i6cuo6ER6usEOtKajUUDj92zlG+KArFia0857xxiEHAQcUwh/RtOQocui1LPJwunSYT574Pk64aNva1kwtxZg==", + "dependencies": { + "@babel/runtime": "^7.12.0" + } + }, + "node_modules/i18next-browser-languagedetector": { + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-6.1.8.tgz", + "integrity": "sha512-Svm+MduCElO0Meqpj1kJAriTC6OhI41VhlT/A0UPjGoPZBhAHIaGE5EfsHlTpgdH09UVX7rcc72pSDDBeKSQQA==", + "dependencies": { + "@babel/runtime": "^7.19.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", + "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", + "dependencies": { + "postcss": "^7.0.14" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/identity-obj-proxy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", + "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==", + "dependencies": { + "harmony-reflect": "^1.4.6" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==" + }, + "node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immer": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/immer/-/immer-1.10.0.tgz", + "integrity": "sha512-O3sR1/opvCDGLEVcvrGTMtLac8GJ5IwZC4puPrLuRj3l7ICKvkmA0vGuU9OW8mV9WIBRnaxp5GJh9IEAaNOoYg==" + }, + "node_modules/immutability-helper": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/immutability-helper/-/immutability-helper-2.9.1.tgz", + "integrity": "sha512-r/RmRG8xO06s/k+PIaif2r5rGc3j4Yhc01jSBfwPCXDLYZwp/yxralI37Df1mwmuzcCsen/E/ITKcTEvc1PQmQ==", + "dependencies": { + "invariant": "^2.2.0" + } + }, + "node_modules/import-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", + "integrity": "sha512-Ew5AZzJQFqrOV5BTW3EIoHAnoie1LojZLXKcCQ/yTRyVZosBhK1x1ViYjHGf5pAFOq8ZyChZp6m/fSN7pJyZtg==", + "dependencies": { + "import-from": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-from": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", + "integrity": "sha512-0vdnLL2wSGnhlRmzHJAg5JHjt1l2vYhzJ7tNLGbeVg0fse56tpGaH0uzH+r9Slej+BSXXEHvBKDEnVSLLE9/+w==", + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-from/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dependencies": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==" + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/inquirer": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", + "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.19", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.6.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/inquirer/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/internal-ip": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", + "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", + "dependencies": { + "default-gateway": "^4.2.0", + "ipaddr.js": "^1.9.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/ip": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", + "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==" + }, + "node_modules/ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha512-vOx7VprsKyllwjSkLV79NIhpyLfr3jAp7VaTCMXOJHu4m0Ew1CZ2fcjASwmV1jI3BWuWHB013M48eyeldk9gYg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", + "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==", + "dependencies": { + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-ci/node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + }, + "node_modules/is-color-stop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", + "integrity": "sha512-H1U8Vz0cfXNujrJzEcvvwMDW9Ra+biSYA3ThdQvAnMLJkEHQXn6bWzLkxHtVYJ+Sdbx0b6finn3jZiaVe7MAHA==", + "dependencies": { + "css-color-names": "^0.0.4", + "hex-color-regex": "^1.1.0", + "hsl-regex": "^1.0.0", + "hsla-regex": "^1.0.0", + "rgb-regex": "^1.0.1", + "rgba-regex": "^1.0.0" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-descriptor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz", + "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==", + "dependencies": { + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-in-browser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", + "integrity": "sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g==" + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "dependencies": { + "is-path-inside": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "dependencies": { + "path-is-inside": "^1.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==" + }, + "node_modules/is-root": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", + "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" + }, + "node_modules/istanbul-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", + "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", + "dependencies": { + "@babel/generator": "^7.4.0", + "@babel/parser": "^7.4.3", + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.3", + "@babel/types": "^7.4.0", + "istanbul-lib-coverage": "^2.0.5", + "semver": "^6.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/istanbul-lib-report": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", + "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", + "dependencies": { + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "supports-color": "^6.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", + "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "rimraf": "^2.6.3", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", + "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", + "dependencies": { + "html-escaper": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jest": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-24.9.0.tgz", + "integrity": "sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw==", + "dependencies": { + "import-local": "^2.0.0", + "jest-cli": "^24.9.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-changed-files": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.9.0.tgz", + "integrity": "sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg==", + "dependencies": { + "@jest/types": "^24.9.0", + "execa": "^1.0.0", + "throat": "^4.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-changed-files/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-changed-files/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-changed-files/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-cli": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.9.0.tgz", + "integrity": "sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg==", + "dependencies": { + "@jest/core": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "import-local": "^2.0.0", + "is-ci": "^2.0.0", + "jest-config": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "prompts": "^2.0.1", + "realpath-native": "^1.1.0", + "yargs": "^13.3.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-cli/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-cli/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-cli/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-cli/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-cli/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-cli/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/jest-cli/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/jest-cli/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/jest-cli/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-cli/node_modules/jest-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", + "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", + "dependencies": { + "@jest/console": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/source-map": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-cli/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-cli/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-cli/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-config": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.9.0.tgz", + "integrity": "sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ==", + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^24.9.0", + "@jest/types": "^24.9.0", + "babel-jest": "^24.9.0", + "chalk": "^2.0.1", + "glob": "^7.1.1", + "jest-environment-jsdom": "^24.9.0", + "jest-environment-node": "^24.9.0", + "jest-get-type": "^24.9.0", + "jest-jasmine2": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "micromatch": "^3.1.10", + "pretty-format": "^24.9.0", + "realpath-native": "^1.1.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-config/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-config/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-config/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-config/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-config/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-config/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-config/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-config/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/jest-config/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/jest-config/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/jest-config/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-config/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-config/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-config/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-config/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-config/node_modules/jest-get-type": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", + "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-config/node_modules/jest-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", + "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", + "dependencies": { + "@jest/console": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/source-map": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-config/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-config/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-config/node_modules/pretty-format": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", + "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", + "dependencies": { + "@jest/types": "^24.9.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-config/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/jest-config/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-config/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-config/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-config/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.9.0.tgz", + "integrity": "sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==", + "dependencies": { + "detect-newline": "^2.1.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-each": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.9.0.tgz", + "integrity": "sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog==", + "dependencies": { + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "jest-get-type": "^24.9.0", + "jest-util": "^24.9.0", + "pretty-format": "^24.9.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-each/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-each/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-each/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-each/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-each/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-each/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/jest-each/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/jest-each/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/jest-each/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-each/node_modules/jest-get-type": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", + "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-each/node_modules/jest-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", + "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", + "dependencies": { + "@jest/console": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/source-map": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-each/node_modules/pretty-format": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", + "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", + "dependencies": { + "@jest/types": "^24.9.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-each/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/jest-each/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-each/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-each/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-environment-jsdom": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz", + "integrity": "sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA==", + "dependencies": { + "@jest/environment": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-util": "^24.9.0", + "jsdom": "^11.5.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-environment-jsdom-fourteen": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom-fourteen/-/jest-environment-jsdom-fourteen-1.0.1.tgz", + "integrity": "sha512-DojMX1sY+at5Ep+O9yME34CdidZnO3/zfPh8UW+918C5fIZET5vCjfkegixmsi7AtdYfkr4bPlIzmWnlvQkP7Q==", + "dependencies": { + "@jest/environment": "^24.3.0", + "@jest/fake-timers": "^24.3.0", + "@jest/types": "^24.3.0", + "jest-mock": "^24.0.0", + "jest-util": "^24.0.0", + "jsdom": "^14.1.0" + } + }, + "node_modules/jest-environment-jsdom-fourteen/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-environment-jsdom-fourteen/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-environment-jsdom-fourteen/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-environment-jsdom-fourteen/node_modules/acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jest-environment-jsdom-fourteen/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-environment-jsdom-fourteen/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-environment-jsdom-fourteen/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/jest-environment-jsdom-fourteen/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/jest-environment-jsdom-fourteen/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/jest-environment-jsdom-fourteen/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-environment-jsdom-fourteen/node_modules/jest-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", + "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", + "dependencies": { + "@jest/console": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/source-map": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-environment-jsdom-fourteen/node_modules/jsdom": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-14.1.0.tgz", + "integrity": "sha512-O901mfJSuTdwU2w3Sn+74T+RnDVP+FuV5fH8tcPWyqrseRAb0s5xOtPgCFiPOtLcyK7CLIJwPyD83ZqQWvA5ng==", + "dependencies": { + "abab": "^2.0.0", + "acorn": "^6.0.4", + "acorn-globals": "^4.3.0", + "array-equal": "^1.0.0", + "cssom": "^0.3.4", + "cssstyle": "^1.1.1", + "data-urls": "^1.1.0", + "domexception": "^1.0.1", + "escodegen": "^1.11.0", + "html-encoding-sniffer": "^1.0.2", + "nwsapi": "^2.1.3", + "parse5": "5.1.0", + "pn": "^1.1.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.5", + "saxes": "^3.1.9", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.5.0", + "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^1.1.2", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^7.0.0", + "ws": "^6.1.2", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom-fourteen/node_modules/parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==" + }, + "node_modules/jest-environment-jsdom-fourteen/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-environment-jsdom-fourteen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-environment-jsdom-fourteen/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-environment-jsdom-fourteen/node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/jest-environment-jsdom-fourteen/node_modules/ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-environment-jsdom/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-environment-jsdom/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-environment-jsdom/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/jest-environment-jsdom/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/jest-environment-jsdom/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jest-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", + "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", + "dependencies": { + "@jest/console": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/source-map": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-environment-jsdom/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-environment-jsdom/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-environment-node": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.9.0.tgz", + "integrity": "sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA==", + "dependencies": { + "@jest/environment": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-util": "^24.9.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-environment-node/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-environment-node/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-environment-node/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-environment-node/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-environment-node/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-environment-node/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/jest-environment-node/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/jest-environment-node/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/jest-environment-node/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-environment-node/node_modules/jest-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", + "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", + "dependencies": { + "@jest/console": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/source-map": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-environment-node/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-environment-node/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-environment-node/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.9.0.tgz", + "integrity": "sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ==", + "dependencies": { + "@jest/types": "^24.9.0", + "anymatch": "^2.0.0", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.1.15", + "invariant": "^2.2.4", + "jest-serializer": "^24.9.0", + "jest-util": "^24.9.0", + "jest-worker": "^24.9.0", + "micromatch": "^3.1.10", + "sane": "^4.0.3", + "walker": "^1.0.7" + }, + "engines": { + "node": ">= 6" + }, + "optionalDependencies": { + "fsevents": "^1.2.7" + } + }, + "node_modules/jest-haste-map/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-haste-map/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-haste-map/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-haste-map/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-haste-map/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-haste-map/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-haste-map/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-haste-map/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/jest-haste-map/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/jest-haste-map/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/jest-haste-map/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-haste-map/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-haste-map/node_modules/fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "deprecated": "The v1 package contains DANGEROUS / INSECURE binaries. Upgrade to safe fsevents v2", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/jest-haste-map/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-haste-map/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-haste-map/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-haste-map/node_modules/jest-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", + "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", + "dependencies": { + "@jest/console": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/source-map": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-haste-map/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-haste-map/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-haste-map/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-haste-map/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-haste-map/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-haste-map/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-jasmine2": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz", + "integrity": "sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw==", + "dependencies": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "co": "^4.6.0", + "expect": "^24.9.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^24.9.0", + "jest-matcher-utils": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-snapshot": "^24.9.0", + "jest-util": "^24.9.0", + "pretty-format": "^24.9.0", + "throat": "^4.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-jasmine2/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-jasmine2/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-jasmine2/node_modules/@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==" + }, + "node_modules/jest-jasmine2/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-jasmine2/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-jasmine2/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-jasmine2/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-jasmine2/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-jasmine2/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-jasmine2/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/jest-jasmine2/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/jest-jasmine2/node_modules/diff-sequences": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz", + "integrity": "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-jasmine2/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/jest-jasmine2/node_modules/expect": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-24.9.0.tgz", + "integrity": "sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q==", + "dependencies": { + "@jest/types": "^24.9.0", + "ansi-styles": "^3.2.0", + "jest-get-type": "^24.9.0", + "jest-matcher-utils": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-regex-util": "^24.9.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-jasmine2/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-jasmine2/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-jasmine2/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-jasmine2/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-jasmine2/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-diff": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.9.0.tgz", + "integrity": "sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==", + "dependencies": { + "chalk": "^2.0.1", + "diff-sequences": "^24.9.0", + "jest-get-type": "^24.9.0", + "pretty-format": "^24.9.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-get-type": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", + "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-matcher-utils": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz", + "integrity": "sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA==", + "dependencies": { + "chalk": "^2.0.1", + "jest-diff": "^24.9.0", + "jest-get-type": "^24.9.0", + "pretty-format": "^24.9.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-message-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz", + "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", + "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", + "dependencies": { + "@jest/console": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/source-map": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-jasmine2/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-jasmine2/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-jasmine2/node_modules/pretty-format": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", + "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", + "dependencies": { + "@jest/types": "^24.9.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-jasmine2/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/jest-jasmine2/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-jasmine2/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-jasmine2/node_modules/stack-utils": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", + "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-jasmine2/node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-jasmine2/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-jasmine2/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-leak-detector": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz", + "integrity": "sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA==", + "dependencies": { + "jest-get-type": "^24.9.0", + "pretty-format": "^24.9.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-leak-detector/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-leak-detector/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-leak-detector/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-leak-detector/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-leak-detector/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-leak-detector/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/jest-leak-detector/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/jest-leak-detector/node_modules/jest-get-type": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", + "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-leak-detector/node_modules/pretty-format": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", + "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", + "dependencies": { + "@jest/types": "^24.9.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-leak-detector/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.9.0.tgz", + "integrity": "sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==", + "dependencies": { + "@jest/types": "^24.9.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-mock/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-mock/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-mock/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.9.0.tgz", + "integrity": "sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-resolve": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz", + "integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==", + "dependencies": { + "@jest/types": "^24.9.0", + "browser-resolve": "^1.11.3", + "chalk": "^2.0.1", + "jest-pnp-resolver": "^1.2.1", + "realpath-native": "^1.1.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz", + "integrity": "sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g==", + "dependencies": { + "@jest/types": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-snapshot": "^24.9.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-resolve/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-resolve/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-resolve/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-resolve/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-resolve/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-resolve/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/jest-resolve/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/jest-resolve/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/jest-resolve/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-resolve/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-runner": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.9.0.tgz", + "integrity": "sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg==", + "dependencies": { + "@jest/console": "^24.7.1", + "@jest/environment": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "chalk": "^2.4.2", + "exit": "^0.1.2", + "graceful-fs": "^4.1.15", + "jest-config": "^24.9.0", + "jest-docblock": "^24.3.0", + "jest-haste-map": "^24.9.0", + "jest-jasmine2": "^24.9.0", + "jest-leak-detector": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-resolve": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-util": "^24.9.0", + "jest-worker": "^24.6.0", + "source-map-support": "^0.5.6", + "throat": "^4.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-runner/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-runner/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-runner/node_modules/@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==" + }, + "node_modules/jest-runner/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-runner/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-runner/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-runner/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-runner/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-runner/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/jest-runner/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/jest-runner/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/jest-runner/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-runner/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-runner/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-runner/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-runner/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-runner/node_modules/jest-message-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz", + "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-runner/node_modules/jest-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", + "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", + "dependencies": { + "@jest/console": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/source-map": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-runner/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-runner/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-runner/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-runner/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-runner/node_modules/stack-utils": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", + "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-runner/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-runtime": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.9.0.tgz", + "integrity": "sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw==", + "dependencies": { + "@jest/console": "^24.7.1", + "@jest/environment": "^24.9.0", + "@jest/source-map": "^24.3.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/yargs": "^13.0.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.1.15", + "jest-config": "^24.9.0", + "jest-haste-map": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.9.0", + "jest-snapshot": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "strip-bom": "^3.0.0", + "yargs": "^13.3.0" + }, + "bin": { + "jest-runtime": "bin/jest-runtime.js" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-runtime/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-runtime/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-runtime/node_modules/@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==" + }, + "node_modules/jest-runtime/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-runtime/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-runtime/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-runtime/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-runtime/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-runtime/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/jest-runtime/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/jest-runtime/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/jest-runtime/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-runtime/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-runtime/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-runtime/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-runtime/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-runtime/node_modules/jest-message-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz", + "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-runtime/node_modules/jest-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", + "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", + "dependencies": { + "@jest/console": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/source-map": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-runtime/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-runtime/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-runtime/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-runtime/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-runtime/node_modules/stack-utils": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", + "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-runtime/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-serializer": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.9.0.tgz", + "integrity": "sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-snapshot": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.9.0.tgz", + "integrity": "sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew==", + "dependencies": { + "@babel/types": "^7.0.0", + "@jest/types": "^24.9.0", + "chalk": "^2.0.1", + "expect": "^24.9.0", + "jest-diff": "^24.9.0", + "jest-get-type": "^24.9.0", + "jest-matcher-utils": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-resolve": "^24.9.0", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^24.9.0", + "semver": "^6.2.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-snapshot/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-snapshot/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-snapshot/node_modules/@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==" + }, + "node_modules/jest-snapshot/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-snapshot/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-snapshot/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-snapshot/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-snapshot/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/jest-snapshot/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/jest-snapshot/node_modules/diff-sequences": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz", + "integrity": "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-snapshot/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/jest-snapshot/node_modules/expect": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-24.9.0.tgz", + "integrity": "sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q==", + "dependencies": { + "@jest/types": "^24.9.0", + "ansi-styles": "^3.2.0", + "jest-get-type": "^24.9.0", + "jest-matcher-utils": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-regex-util": "^24.9.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-snapshot/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-snapshot/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-snapshot/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-snapshot/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-snapshot/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-snapshot/node_modules/jest-diff": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.9.0.tgz", + "integrity": "sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==", + "dependencies": { + "chalk": "^2.0.1", + "diff-sequences": "^24.9.0", + "jest-get-type": "^24.9.0", + "pretty-format": "^24.9.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-snapshot/node_modules/jest-get-type": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", + "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-snapshot/node_modules/jest-matcher-utils": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz", + "integrity": "sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA==", + "dependencies": { + "chalk": "^2.0.1", + "jest-diff": "^24.9.0", + "jest-get-type": "^24.9.0", + "pretty-format": "^24.9.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-snapshot/node_modules/jest-message-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz", + "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-snapshot/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-snapshot/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-snapshot/node_modules/pretty-format": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", + "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", + "dependencies": { + "@jest/types": "^24.9.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-snapshot/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/jest-snapshot/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-snapshot/node_modules/stack-utils": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", + "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot/node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-snapshot/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz", + "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==", + "dependencies": { + "@jest/types": "^24.9.0", + "camelcase": "^5.3.1", + "chalk": "^2.0.1", + "jest-get-type": "^24.9.0", + "leven": "^3.1.0", + "pretty-format": "^24.9.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-validate/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-validate/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-validate/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-validate/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-validate/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-validate/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/jest-validate/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/jest-validate/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/jest-validate/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-validate/node_modules/jest-get-type": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", + "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-validate/node_modules/pretty-format": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", + "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", + "dependencies": { + "@jest/types": "^24.9.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-validate/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/jest-validate/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-watch-typeahead": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-0.4.2.tgz", + "integrity": "sha512-f7VpLebTdaXs81rg/oj4Vg/ObZy2QtGzAmGLNsqUS5G5KtSN68tFcIsbvNODfNyQxU78g7D8x77o3bgfBTR+2Q==", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^2.4.1", + "jest-regex-util": "^24.9.0", + "jest-watcher": "^24.3.0", + "slash": "^3.0.0", + "string-length": "^3.1.0", + "strip-ansi": "^5.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-watch-typeahead/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-watch-typeahead/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/jest-watch-typeahead/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/jest-watch-typeahead/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-watch-typeahead/node_modules/string-length": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz", + "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==", + "dependencies": { + "astral-regex": "^1.0.0", + "strip-ansi": "^5.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-watcher": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.9.0.tgz", + "integrity": "sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw==", + "dependencies": { + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/yargs": "^13.0.0", + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.1", + "jest-util": "^24.9.0", + "string-length": "^2.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-watcher/node_modules/@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-watcher/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-watcher/node_modules/@types/yargs": { + "version": "13.0.12", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.12.tgz", + "integrity": "sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-watcher/node_modules/ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-watcher/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-watcher/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-watcher/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/jest-watcher/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/jest-watcher/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/jest-watcher/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-watcher/node_modules/jest-util": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", + "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", + "dependencies": { + "@jest/console": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/source-map": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-watcher/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-watcher/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-watcher/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-worker": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", + "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", + "dependencies": { + "merge-stream": "^2.0.0", + "supports-color": "^6.1.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" + }, + "node_modules/jsdom": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", + "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", + "dependencies": { + "abab": "^2.0.0", + "acorn": "^5.5.3", + "acorn-globals": "^4.1.0", + "array-equal": "^1.0.0", + "cssom": ">= 0.3.2 < 0.4.0", + "cssstyle": "^1.0.0", + "data-urls": "^1.0.0", + "domexception": "^1.0.1", + "escodegen": "^1.9.1", + "html-encoding-sniffer": "^1.0.2", + "left-pad": "^1.3.0", + "nwsapi": "^2.0.7", + "parse5": "4.0.0", + "pn": "^1.1.0", + "request": "^2.87.0", + "request-promise-native": "^1.0.5", + "sax": "^1.2.4", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.3.4", + "w3c-hr-time": "^1.0.1", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.3", + "whatwg-mimetype": "^2.1.0", + "whatwg-url": "^6.4.1", + "ws": "^5.2.0", + "xml-name-validator": "^3.0.0" + } + }, + "node_modules/jsdom/node_modules/acorn": { + "version": "5.7.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", + "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/json-stable-stringify": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.1.1.tgz", + "integrity": "sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg==", + "dependencies": { + "call-bind": "^1.0.5", + "isarray": "^2.0.5", + "jsonify": "^0.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" + }, + "node_modules/json-stable-stringify/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + }, + "node_modules/json3": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", + "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", + "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsonwebtoken/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsonwebtoken/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/jss": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss/-/jss-10.10.0.tgz", + "integrity": "sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "csstype": "^3.0.2", + "is-in-browser": "^1.1.3", + "tiny-warning": "^1.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/jss" + } + }, + "node_modules/jss-plugin-camel-case": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.10.0.tgz", + "integrity": "sha512-z+HETfj5IYgFxh1wJnUAU8jByI48ED+v0fuTuhKrPR+pRBYS2EDwbusU8aFOpCdYhtRc9zhN+PJ7iNE8pAWyPw==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "hyphenate-style-name": "^1.0.3", + "jss": "10.10.0" + } + }, + "node_modules/jss-plugin-default-unit": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.10.0.tgz", + "integrity": "sha512-SvpajxIECi4JDUbGLefvNckmI+c2VWmP43qnEy/0eiwzRUsafg5DVSIWSzZe4d2vFX1u9nRDP46WCFV/PXVBGQ==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0" + } + }, + "node_modules/jss-plugin-global": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.10.0.tgz", + "integrity": "sha512-icXEYbMufiNuWfuazLeN+BNJO16Ge88OcXU5ZDC2vLqElmMybA31Wi7lZ3lf+vgufRocvPj8443irhYRgWxP+A==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0" + } + }, + "node_modules/jss-plugin-nested": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.10.0.tgz", + "integrity": "sha512-9R4JHxxGgiZhurDo3q7LdIiDEgtA1bTGzAbhSPyIOWb7ZubrjQe8acwhEQ6OEKydzpl8XHMtTnEwHXCARLYqYA==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "node_modules/jss-plugin-props-sort": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.10.0.tgz", + "integrity": "sha512-5VNJvQJbnq/vRfje6uZLe/FyaOpzP/IH1LP+0fr88QamVrGJa0hpRRyAa0ea4U/3LcorJfBFVyC4yN2QC73lJg==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0" + } + }, + "node_modules/jss-plugin-rule-value-function": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.10.0.tgz", + "integrity": "sha512-uEFJFgaCtkXeIPgki8ICw3Y7VMkL9GEan6SqmT9tqpwM+/t+hxfMUdU4wQ0MtOiMNWhwnckBV0IebrKcZM9C0g==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "jss": "10.10.0", + "tiny-warning": "^1.0.2" + } + }, + "node_modules/jss-plugin-vendor-prefixer": { + "version": "10.10.0", + "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.10.0.tgz", + "integrity": "sha512-UY/41WumgjW8r1qMCO8l1ARg7NHnfRVWRhZ2E2m0DMYsr2DD91qIXLyNhiX83hHswR7Wm4D+oDYNC1zWCJWtqg==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "css-vendor": "^2.0.8", + "jss": "10.10.0" + } + }, + "node_modules/jsx-ast-utils": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz", + "integrity": "sha512-z1xSldJ6imESSzOjd3NNkieVJKRlKYSOtMG8SFyCj2FIrvSaSuli/WjpBkEzCBoR9bYYYFgqJw61Xhu7Lcgk+w==", + "dependencies": { + "array-includes": "^3.1.1", + "object.assign": "^4.1.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/just-curry-it": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/just-curry-it/-/just-curry-it-3.2.1.tgz", + "integrity": "sha512-Q8206k8pTY7krW32cdmPsP+DqqLgWx/hYPSj9/+7SYqSqz7UuwPbfSe07lQtvuuaVyiSJveXk0E5RydOuWwsEg==" + }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/killable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", + "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==" + }, + "node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/lamejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/lamejs/-/lamejs-1.2.1.tgz", + "integrity": "sha512-s7bxvjvYthw6oPLCm5pFxvA84wUROODB8jEO2+CE1adhKgrIvVOlmMgY8zyugxGrvRaDHNJanOiS21/emty6dQ==", + "dependencies": { + "use-strict": "1.0.1" + } + }, + "node_modules/last-call-webpack-plugin": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz", + "integrity": "sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w==", + "dependencies": { + "lodash": "^4.17.5", + "webpack-sources": "^1.1.0" + } + }, + "node_modules/lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha512-RE2g0b5VGZsOCFOCgP7omTRYFqydmZkBwl5oNnQ1lDYC57uyO9KqNnNVxT7COSHTxrRCWVcAVOcbjk+tvh/rgQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/left-pad": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", + "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==", + "deprecated": "use String.prototype.padStart()" + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/levenary": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", + "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", + "dependencies": { + "leven": "^3.1.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loader-fs-cache": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz", + "integrity": "sha512-ldcgZpjNJj71n+2Mf6yetz+c9bM4xpKtNds4LbqXzU/PTdeAX0g3ytnU1AJMEcTk2Lex4Smpe3Q/eCTsvUBxbA==", + "dependencies": { + "find-cache-dir": "^0.1.1", + "mkdirp": "^0.5.1" + } + }, + "node_modules/loader-fs-cache/node_modules/find-cache-dir": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", + "integrity": "sha512-Z9XSBoNE7xQiV6MSgPuCfyMokH2K7JdpRkOYE1+mu3d4BFJtx3GW+f6Bo4q8IX6rlf5MYbLBKW0pjl2cWdkm2A==", + "dependencies": { + "commondir": "^1.0.1", + "mkdirp": "^0.5.1", + "pkg-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loader-fs-cache/node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loader-fs-cache/node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loader-fs-cache/node_modules/pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha512-c6pv3OE78mcZ92ckebVDqg0aWSoKhOTbwCV6qbCWMk546mAL9pZln0+QsN/yQ7fkucd4+yJPLrCBXNt8Ruk+Eg==", + "dependencies": { + "find-up": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "engines": { + "node": ">=4.3.0 <5.0.0 || >=5.10" + } + }, + "node_modules/loader-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/loader-utils/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, + "node_modules/lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" + }, + "node_modules/lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dependencies": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "node_modules/lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dependencies": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + }, + "node_modules/loglevel": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.1.tgz", + "integrity": "sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==", + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/luxon": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.4.tgz", + "integrity": "sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/mamacro": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", + "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==" + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/markdown-to-jsx": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.4.7.tgz", + "integrity": "sha512-0+ls1IQZdU6cwM1yu0ZjjiVWYtkbExSyUIFU2ZeDIFuZM1W42Mh4OlJ4nb4apX4H8smxDHRdFaoIVJGwfv5hkg==", + "engines": { + "node": ">= 10" + }, + "peerDependencies": { + "react": ">= 0.14.0" + } + }, + "node_modules/match-sorter": { + "version": "6.3.4", + "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.4.tgz", + "integrity": "sha512-jfZW7cWS5y/1xswZo8VBOdudUiSd9nifYRWphc9M5D/ee4w4AoXLgBEdRbgVaxbMuagBPeUC5y2Hi8DO6o9aDg==", + "dependencies": { + "@babel/runtime": "^7.23.8", + "remove-accents": "0.5.0" + } + }, + "node_modules/material-colors": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz", + "integrity": "sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg==" + }, + "node_modules/material-ui-color": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/material-ui-color/-/material-ui-color-1.2.0.tgz", + "integrity": "sha512-bD2Rww+hakJxD2/19uxc280Vh292DnRStLke2LDFavVtGd5fzOz09zIrHO3ZHlMkJFsvwx6IwiB4/932ftv0sQ==", + "peerDependencies": { + "@material-ui/core": "^4.9.5", + "material-ui-popup-state": "^1.5.3", + "prop-types": "^15.7.2", + "react": "^16.0.0 || ^17.0.0", + "react-dom": "^16.0.0 || ^17.0.0" + } + }, + "node_modules/material-ui-popup-state": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/material-ui-popup-state/-/material-ui-popup-state-1.9.3.tgz", + "integrity": "sha512-+Ete5Tzw5rXlYfmqptOS8kBUH8vnK5OJsd6IQ7SHtLjU0PsvsmM73M/k8ot0xkX4RmPGuNRsFbK3mlCe/ClQuw==", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.12.5", + "@material-ui/types": "^6.0.1", + "classnames": "^2.2.6", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "@material-ui/core": "^4.0.0 || ^5.0.0-beta", + "react": "^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/material-ui-popup-state/node_modules/@material-ui/types": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-6.0.2.tgz", + "integrity": "sha512-/XUca4wUb9pWimLLdM1PE8KS8rTbDEGohSGkGtk3WST7lm23m+8RYv9uOmrvOg/VSsl4bMiOv4t2/LCb+RLbTg==", + "peer": true, + "peerDependencies": { + "@types/react": "*" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" + }, + "node_modules/memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ==", + "dependencies": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "node_modules/merge-deep": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/merge-deep/-/merge-deep-3.0.3.tgz", + "integrity": "sha512-qtmzAS6t6grwEkNrunqTBdn0qKwFgNWvlxUbAV8es9M7Ot1EbyApytCnvE0jALPa46ZpKDUo527kKiaWplmlFA==", + "dependencies": { + "arr-union": "^3.1.0", + "clone-deep": "^0.2.4", + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mic-recorder-to-mp3": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/mic-recorder-to-mp3/-/mic-recorder-to-mp3-2.2.2.tgz", + "integrity": "sha512-xDkOaHbojW3bdKOGn9CI5dT+Mc0RrfczsX/Y1zGJp3FUB4zei5ZKFnNm7Nguc9v910wkd7T3csnCTq5EtCF3Zw==", + "dependencies": { + "lamejs": "^1.2.0" + }, + "peerDependencies": { + "webrtc-adapter": ">=4.1.1" + } + }, + "node_modules/microevent.ts": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/microevent.ts/-/microevent.ts-0.1.1.tgz", + "integrity": "sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g==" + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/microseconds": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz", + "integrity": "sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA==" + }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/miller-rabin/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz", + "integrity": "sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A==", + "dependencies": { + "loader-utils": "^1.1.0", + "normalize-url": "1.9.1", + "schema-utils": "^1.0.0", + "webpack-sources": "^1.1.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^4.4.0" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dependencies": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-object": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz", + "integrity": "sha512-ALGF1Jt9ouehcaXaHhn6t1yGWRqGaHkPFndtFVHfZXOvkIZ/yoGaSi0AHVTafb3ZBGg4dr/bDwnaEKqCXzchMA==", + "dependencies": { + "for-in": "^0.1.3", + "is-extendable": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-object/node_modules/for-in": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz", + "integrity": "sha512-F0to7vbBSHP8E3l6dCjxNOLuSFAACIxFy3UehTUlG7svlXi37HHsDkyVcHo0Pq8QwrE+pXvWSVX3ZT1T9wAZ9g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "engines": { + "node": "*" + } + }, + "node_modules/moment-timezone": { + "version": "0.5.45", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz", + "integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==", + "dependencies": { + "moment": "^2.29.4" + }, + "engines": { + "node": "*" + } + }, + "node_modules/move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==", + "dependencies": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "node_modules/move-concurrently/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/multicast-dns": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", + "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "dependencies": { + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha512-cnAsSVxIDsYt0v7HmC0hWZFwwXSh+E6PgCrREDuN/EsjgLwA5XRmlMHhSiDPrt6HxY1gTivEa/Zh7GtODoLevQ==" + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, + "node_modules/nan": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.19.0.tgz", + "integrity": "sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==", + "optional": true + }, + "node_modules/nano-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz", + "integrity": "sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA==", + "dependencies": { + "big-integer": "^1.6.16" + } + }, + "node_modules/nanoclone": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz", + "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==" + }, + "node_modules/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-forge": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" + }, + "node_modules/node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dependencies": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + } + }, + "node_modules/node-libs-browser/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + }, + "node_modules/node-libs-browser/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" + }, + "node_modules/node-libs-browser/node_modules/util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dependencies": { + "inherits": "2.0.3" + } + }, + "node_modules/node-notifier": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.5.tgz", + "integrity": "sha512-tVbHs7DyTLtzOiN78izLA85zRqB9NvEXkAf014Vx3jtSvn/xBl6bR8ZYifj+dFcFrKI21huSQgJZ6ZtL3B4HfQ==", + "dependencies": { + "growly": "^1.3.0", + "is-wsl": "^1.1.0", + "semver": "^5.5.0", + "shellwords": "^0.1.1", + "which": "^1.3.0" + } + }, + "node_modules/node-notifier/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha512-A48My/mtCklowHBlI8Fq2jFWK4tX4lJ5E6ytFsSOq1fzpvT0SQSgKhSg7lN5c2uYFOrUAOQp6zhhJnpp1eMloQ==", + "dependencies": { + "object-assign": "^4.0.1", + "prepend-http": "^1.0.0", + "query-string": "^4.1.0", + "sort-keys": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/normalize-url/node_modules/query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha512-O2XLNDBIg1DnTOa+2XrIwSiXEV8h2KImXUnjhhn2+UsvZ+Es2uyd5CCRTNQlDGbzUQOW3aYCBx9rVA6dzsiY7Q==", + "dependencies": { + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url/node_modules/strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==" + }, + "node_modules/nwsapi": { + "version": "2.2.9", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.9.tgz", + "integrity": "sha512-2f3F0SEEer8bBu0dsNCFF50N0cTThV1nWFYcEYFZttdW0lDAoybv9cQoK7X7/68Z89S7FoRrVjP1LPX4XRf9vg==" + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-hash": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", + "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-path": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.4.tgz", + "integrity": "sha512-ICbQN+aw/eAASDtaC7+SJXSAruz7fvvNjxMFfS3mTdvZaaiuuw81XXYu+9CSJeUVrS3YpRhTr862YGywMQUOWg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.8.tgz", + "integrity": "sha512-qkHIGe4q0lSYMv0XI4SsBTJz3WaURhLvd0lKSgtVuOsJ2krg4SgMw3PIRQFMp07yi++UR3se2mkcLqsBNpBb/A==", + "dependencies": { + "array.prototype.reduce": "^1.0.6", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "gopd": "^1.0.1", + "safe-array-concat": "^1.1.2" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.values": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/oblivious-set": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.0.0.tgz", + "integrity": "sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw==" + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "dependencies": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open/node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "dependencies": { + "is-wsl": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/optimize-css-assets-webpack-plugin": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.3.tgz", + "integrity": "sha512-q9fbvCRS6EYtUKKSwI87qm2IxlyJK5b4dygW1rKUBT6mMDhdG5e5bZT63v6tnJR9F9FB/H5a0HTmtw+laUBxKA==", + "dependencies": { + "cssnano": "^4.1.10", + "last-call-webpack-plugin": "^3.0.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==" + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-each-series": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz", + "integrity": "sha512-J/e9xiZZQNrt+958FFzJ+auItsBGq+UrQ7nE89AUP7UOTtjHnkISANXLdayhVzh538UnLMCSlf13lFfRIAKQOA==", + "dependencies": { + "p-reduce": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-reduce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", + "integrity": "sha512-3Tx1T3oM1xO/Y8Gj0sWyE78EIJZ+t+aEmXUdvQgvGmSMri7aPTHoovbXEreWKkL5j21Er60XAWLTzKbAKYOujQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-retry": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", + "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", + "dependencies": { + "retry": "^0.12.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, + "node_modules/parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dependencies": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-asn1": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz", + "integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==", + "dependencies": { + "asn1.js": "^4.10.1", + "browserify-aes": "^1.2.0", + "evp_bytestokey": "^1.0.3", + "hash-base": "~3.0", + "pbkdf2": "^3.1.2", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==" + }, + "node_modules/path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==" + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==" + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" + }, + "node_modules/pnp-webpack-plugin": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz", + "integrity": "sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==", + "dependencies": { + "ts-pnp": "^1.1.6" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/popper.js": { + "version": "1.16.1-lts", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz", + "integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA==" + }, + "node_modules/portfinder": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", + "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", + "dependencies": { + "async": "^2.6.4", + "debug": "^3.2.7", + "mkdirp": "^0.5.6" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/portfinder/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-attribute-case-insensitive": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz", + "integrity": "sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA==", + "dependencies": { + "postcss": "^7.0.2", + "postcss-selector-parser": "^6.0.2" + } + }, + "node_modules/postcss-browser-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-3.0.0.tgz", + "integrity": "sha512-qfVjLfq7HFd2e0HW4s1dvU8X080OZdG46fFbIBFjW7US7YPDcWfRvdElvwMJr2LI6hMmD+7LnH2HcmXTs+uOig==", + "dependencies": { + "postcss": "^7" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "browserslist": "^4" + } + }, + "node_modules/postcss-calc": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz", + "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==", + "dependencies": { + "postcss": "^7.0.27", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.0.2" + } + }, + "node_modules/postcss-color-functional-notation": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz", + "integrity": "sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g==", + "dependencies": { + "postcss": "^7.0.2", + "postcss-values-parser": "^2.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-color-gray": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz", + "integrity": "sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw==", + "dependencies": { + "@csstools/convert-colors": "^1.4.0", + "postcss": "^7.0.5", + "postcss-values-parser": "^2.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-color-hex-alpha": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz", + "integrity": "sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw==", + "dependencies": { + "postcss": "^7.0.14", + "postcss-values-parser": "^2.0.1" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-color-mod-function": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz", + "integrity": "sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ==", + "dependencies": { + "@csstools/convert-colors": "^1.4.0", + "postcss": "^7.0.2", + "postcss-values-parser": "^2.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-color-rebeccapurple": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz", + "integrity": "sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g==", + "dependencies": { + "postcss": "^7.0.2", + "postcss-values-parser": "^2.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-colormin": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", + "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", + "dependencies": { + "browserslist": "^4.0.0", + "color": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-colormin/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-convert-values": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", + "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", + "dependencies": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-convert-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-custom-media": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz", + "integrity": "sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg==", + "dependencies": { + "postcss": "^7.0.14" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-custom-properties": { + "version": "8.0.11", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz", + "integrity": "sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA==", + "dependencies": { + "postcss": "^7.0.17", + "postcss-values-parser": "^2.0.1" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-custom-selectors": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz", + "integrity": "sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w==", + "dependencies": { + "postcss": "^7.0.2", + "postcss-selector-parser": "^5.0.0-rc.3" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-custom-selectors/node_modules/cssesc": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", + "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-custom-selectors/node_modules/postcss-selector-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", + "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", + "dependencies": { + "cssesc": "^2.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-dir-pseudo-class": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz", + "integrity": "sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw==", + "dependencies": { + "postcss": "^7.0.2", + "postcss-selector-parser": "^5.0.0-rc.3" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/postcss-dir-pseudo-class/node_modules/cssesc": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", + "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-dir-pseudo-class/node_modules/postcss-selector-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", + "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", + "dependencies": { + "cssesc": "^2.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-discard-comments": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", + "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", + "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-discard-empty": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", + "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", + "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-double-position-gradients": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz", + "integrity": "sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA==", + "dependencies": { + "postcss": "^7.0.5", + "postcss-values-parser": "^2.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-env-function": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-2.0.2.tgz", + "integrity": "sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw==", + "dependencies": { + "postcss": "^7.0.2", + "postcss-values-parser": "^2.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-flexbugs-fixes": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.1.0.tgz", + "integrity": "sha512-jr1LHxQvStNNAHlgco6PzY308zvLklh7SJVYuWUwyUQncofaAlD2l+P/gxKHOdqWKe7xJSkVLFF/2Tp+JqMSZA==", + "dependencies": { + "postcss": "^7.0.0" + } + }, + "node_modules/postcss-focus-visible": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz", + "integrity": "sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g==", + "dependencies": { + "postcss": "^7.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-focus-within": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz", + "integrity": "sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w==", + "dependencies": { + "postcss": "^7.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-font-variant": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-4.0.1.tgz", + "integrity": "sha512-I3ADQSTNtLTTd8uxZhtSOrTCQ9G4qUVKPjHiDk0bV75QSxXjVWiJVJ2VLdspGUi9fbW9BcjKJoRvxAH1pckqmA==", + "dependencies": { + "postcss": "^7.0.2" + } + }, + "node_modules/postcss-gap-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz", + "integrity": "sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg==", + "dependencies": { + "postcss": "^7.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-image-set-function": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz", + "integrity": "sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw==", + "dependencies": { + "postcss": "^7.0.2", + "postcss-values-parser": "^2.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-initial": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.4.tgz", + "integrity": "sha512-3RLn6DIpMsK1l5UUy9jxQvoDeUN4gP939tDcKUHD/kM8SGSKbFAnvkpFpj3Bhtz3HGk1jWY5ZNWX6mPta5M9fg==", + "dependencies": { + "postcss": "^7.0.2" + } + }, + "node_modules/postcss-lab-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz", + "integrity": "sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg==", + "dependencies": { + "@csstools/convert-colors": "^1.4.0", + "postcss": "^7.0.2", + "postcss-values-parser": "^2.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-load-config": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.2.tgz", + "integrity": "sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==", + "dependencies": { + "cosmiconfig": "^5.0.0", + "import-cwd": "^2.0.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-load-config/node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-load-config/node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-load-config/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-load-config/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", + "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", + "dependencies": { + "loader-utils": "^1.1.0", + "postcss": "^7.0.0", + "postcss-load-config": "^2.0.0", + "schema-utils": "^1.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-loader/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/postcss-logical": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-3.0.0.tgz", + "integrity": "sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA==", + "dependencies": { + "postcss": "^7.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-media-minmax": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz", + "integrity": "sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw==", + "dependencies": { + "postcss": "^7.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", + "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", + "dependencies": { + "css-color-names": "0.0.4", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "stylehacks": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-merge-longhand/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-merge-rules": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", + "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "cssnano-util-same-parent": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0", + "vendors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-merge-rules/node_modules/postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dependencies": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", + "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", + "dependencies": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-font-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-minify-gradients": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", + "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "is-color-stop": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-gradients/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-minify-params": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", + "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", + "dependencies": { + "alphanum-sort": "^1.0.0", + "browserslist": "^4.0.0", + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "uniqs": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-params/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-minify-selectors": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", + "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", + "dependencies": { + "alphanum-sort": "^1.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-selectors/node_modules/postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dependencies": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", + "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", + "dependencies": { + "postcss": "^7.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz", + "integrity": "sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==", + "dependencies": { + "icss-utils": "^4.1.1", + "postcss": "^7.0.32", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-modules-scope": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", + "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", + "dependencies": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-modules-values": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", + "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", + "dependencies": { + "icss-utils": "^4.0.0", + "postcss": "^7.0.6" + } + }, + "node_modules/postcss-nesting": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-7.0.1.tgz", + "integrity": "sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg==", + "dependencies": { + "postcss": "^7.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-normalize": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-8.0.1.tgz", + "integrity": "sha512-rt9JMS/m9FHIRroDDBGSMsyW1c0fkvOJPy62ggxSHUldJO7B195TqFMqIf+lY5ezpDcYOV4j86aUp3/XbxzCCQ==", + "dependencies": { + "@csstools/normalize.css": "^10.1.0", + "browserslist": "^4.6.2", + "postcss": "^7.0.17", + "postcss-browser-comments": "^3.0.0", + "sanitize.css": "^10.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", + "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", + "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", + "dependencies": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-display-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-normalize-positions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", + "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-positions/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", + "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-repeat-style/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-normalize-string": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", + "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", + "dependencies": { + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-string/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", + "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", + "dependencies": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-timing-functions/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-normalize-unicode": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", + "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", + "dependencies": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-unicode/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-normalize-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", + "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", + "dependencies": { + "is-absolute-url": "^2.0.0", + "normalize-url": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-url/node_modules/normalize-url": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/postcss-normalize-url/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-normalize-whitespace": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", + "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", + "dependencies": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-whitespace/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-ordered-values": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", + "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-ordered-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-overflow-shorthand": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz", + "integrity": "sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g==", + "dependencies": { + "postcss": "^7.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-page-break": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-2.0.0.tgz", + "integrity": "sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ==", + "dependencies": { + "postcss": "^7.0.2" + } + }, + "node_modules/postcss-place": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-4.0.1.tgz", + "integrity": "sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg==", + "dependencies": { + "postcss": "^7.0.2", + "postcss-values-parser": "^2.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-preset-env": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz", + "integrity": "sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg==", + "dependencies": { + "autoprefixer": "^9.6.1", + "browserslist": "^4.6.4", + "caniuse-lite": "^1.0.30000981", + "css-blank-pseudo": "^0.1.4", + "css-has-pseudo": "^0.10.0", + "css-prefers-color-scheme": "^3.1.1", + "cssdb": "^4.4.0", + "postcss": "^7.0.17", + "postcss-attribute-case-insensitive": "^4.0.1", + "postcss-color-functional-notation": "^2.0.1", + "postcss-color-gray": "^5.0.0", + "postcss-color-hex-alpha": "^5.0.3", + "postcss-color-mod-function": "^3.0.3", + "postcss-color-rebeccapurple": "^4.0.1", + "postcss-custom-media": "^7.0.8", + "postcss-custom-properties": "^8.0.11", + "postcss-custom-selectors": "^5.1.2", + "postcss-dir-pseudo-class": "^5.0.0", + "postcss-double-position-gradients": "^1.0.0", + "postcss-env-function": "^2.0.2", + "postcss-focus-visible": "^4.0.0", + "postcss-focus-within": "^3.0.0", + "postcss-font-variant": "^4.0.0", + "postcss-gap-properties": "^2.0.0", + "postcss-image-set-function": "^3.0.1", + "postcss-initial": "^3.0.0", + "postcss-lab-function": "^2.0.1", + "postcss-logical": "^3.0.0", + "postcss-media-minmax": "^4.0.0", + "postcss-nesting": "^7.0.0", + "postcss-overflow-shorthand": "^2.0.0", + "postcss-page-break": "^2.0.0", + "postcss-place": "^4.0.1", + "postcss-pseudo-class-any-link": "^6.0.0", + "postcss-replace-overflow-wrap": "^3.0.0", + "postcss-selector-matches": "^4.0.0", + "postcss-selector-not": "^4.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-pseudo-class-any-link": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz", + "integrity": "sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew==", + "dependencies": { + "postcss": "^7.0.2", + "postcss-selector-parser": "^5.0.0-rc.3" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-pseudo-class-any-link/node_modules/cssesc": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", + "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-pseudo-class-any-link/node_modules/postcss-selector-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", + "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", + "dependencies": { + "cssesc": "^2.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", + "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", + "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", + "dependencies": { + "cssnano-util-get-match": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-reduce-transforms/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-replace-overflow-wrap": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz", + "integrity": "sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw==", + "dependencies": { + "postcss": "^7.0.2" + } + }, + "node_modules/postcss-safe-parser": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.1.tgz", + "integrity": "sha512-xZsFA3uX8MO3yAda03QrG3/Eg1LN3EPfjjf07vke/46HERLZyHrTsQ9E1r1w1W//fWEhtYNndo2hQplN2cVpCQ==", + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-selector-matches": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz", + "integrity": "sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww==", + "dependencies": { + "balanced-match": "^1.0.0", + "postcss": "^7.0.2" + } + }, + "node_modules/postcss-selector-not": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-4.0.1.tgz", + "integrity": "sha512-YolvBgInEK5/79C+bdFMyzqTg6pkYqDbzZIST/PDMqa/o3qtXenD05apBG2jLgT0/BQ77d4U2UK12jWpilqMAQ==", + "dependencies": { + "balanced-match": "^1.0.0", + "postcss": "^7.0.2" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.16", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", + "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-svgo": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz", + "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==", + "dependencies": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "svgo": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-svgo/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-unique-selectors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", + "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", + "dependencies": { + "alphanum-sort": "^1.0.0", + "postcss": "^7.0.0", + "uniqs": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "node_modules/postcss-values-parser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz", + "integrity": "sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==", + "dependencies": { + "flatten": "^1.0.2", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=6.14.4" + } + }, + "node_modules/postcss/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" + }, + "node_modules/postcss/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pretty-error": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", + "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==", + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^2.0.4" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pretty-format/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "peer": true + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "dependencies": { + "asap": "~2.0.6" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==" + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types-extra": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", + "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", + "dependencies": { + "react-is": "^16.3.2", + "warning": "^4.0.0" + }, + "peerDependencies": { + "react": ">=0.14.0" + } + }, + "node_modules/prop-types-extra/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/property-expr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz", + "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==" + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + }, + "node_modules/public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/public-encrypt/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dependencies": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } + }, + "node_modules/pumpify/node_modules/pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qr.js": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/qr.js/-/qr.js-0.0.0.tgz", + "integrity": "sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ==" + }, + "node_modules/qrcode.react": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-1.0.1.tgz", + "integrity": "sha512-8d3Tackk8IRLXTo67Y+c1rpaiXjoz/Dd2HpcMdW//62/x8J1Nbho14Kh8x974t9prsLHN6XqVgcnRiBGFptQmg==", + "dependencies": { + "loose-envify": "^1.4.0", + "prop-types": "^15.6.0", + "qr.js": "0.0.0" + }, + "peerDependencies": { + "react": "^15.5.3 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/query-string": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", + "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==", + "dependencies": { + "decode-uri-component": "^0.2.2", + "filter-obj": "^1.1.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, + "node_modules/raf": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "dependencies": { + "performance-now": "^2.1.0" + } + }, + "node_modules/randombytes": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.3.tgz", + "integrity": "sha512-lDVjxQQFoCG1jcrP06LNo2lbWp4QTShEXnhActFBwYuHprllQV6VUpwreApsYqCgD+N1mHoqJ/BI/4eV4R2GYg==" + }, + "node_modules/randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "node_modules/randomfill/node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/randomstring": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/randomstring/-/randomstring-1.3.0.tgz", + "integrity": "sha512-gY7aQ4i1BgwZ8I1Op4YseITAyiDiajeZOPQUbIq9TPGPhUm5FX59izIaOpmKbME1nmnEiABf28d9K2VSii6BBg==", + "dependencies": { + "randombytes": "2.0.3" + }, + "bin": { + "randomstring": "bin/randomstring" + }, + "engines": { + "node": "*" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/react": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-app-polyfill": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-1.0.6.tgz", + "integrity": "sha512-OfBnObtnGgLGfweORmdZbyEz+3dgVePQBb3zipiaDsMHV1NpWm0rDFYIVXFV/AK+x4VIIfWHhrdMIeoTLyRr2g==", + "dependencies": { + "core-js": "^3.5.0", + "object-assign": "^4.1.1", + "promise": "^8.0.3", + "raf": "^3.4.1", + "regenerator-runtime": "^0.13.3", + "whatwg-fetch": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/react-app-polyfill/node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, + "node_modules/react-big-calendar": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/react-big-calendar/-/react-big-calendar-1.11.6.tgz", + "integrity": "sha512-F8TpYul2pVc6a1TmFGFufwCpRlY55YJgx+JCDjhHnZwD2lwpKiAaDlnOjBPsm3OiijVQBHWUKrZwbli3V4lVyw==", + "dependencies": { + "@babel/runtime": "^7.20.7", + "clsx": "^1.2.1", + "date-arithmetic": "^4.1.0", + "dayjs": "^1.11.7", + "dom-helpers": "^5.2.1", + "globalize": "^0.1.1", + "invariant": "^2.2.4", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "luxon": "^3.2.1", + "memoize-one": "^6.0.0", + "moment": "^2.29.4", + "moment-timezone": "^0.5.40", + "prop-types": "^15.8.1", + "react-overlays": "^5.2.1", + "uncontrollable": "^7.2.1" + }, + "peerDependencies": { + "react": "^16.14.0 || ^17 || ^18", + "react-dom": "^16.14.0 || ^17 || ^18" + } + }, + "node_modules/react-bootstrap": { + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.10.2.tgz", + "integrity": "sha512-UvB7mRqQjivdZNxJNEA2yOQRB7L9N43nBnKc33K47+cH90/ujmnMwatTCwQLu83gLhrzAl8fsa6Lqig/KLghaA==", + "dependencies": { + "@babel/runtime": "^7.22.5", + "@restart/hooks": "^0.4.9", + "@restart/ui": "^1.6.8", + "@types/react-transition-group": "^4.4.6", + "classnames": "^2.3.2", + "dom-helpers": "^5.2.1", + "invariant": "^2.2.4", + "prop-types": "^15.8.1", + "prop-types-extra": "^1.1.0", + "react-transition-group": "^4.4.5", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + }, + "peerDependencies": { + "@types/react": ">=16.14.8", + "react": ">=16.14.0", + "react-dom": ">=16.14.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-chartjs-2": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-4.3.1.tgz", + "integrity": "sha512-5i3mjP6tU7QSn0jvb8I4hudTzHJqS8l00ORJnVwI2sYu0ihpj83Lv2YzfxunfxTZkscKvZu2F2w9LkwNBhj6xA==", + "peerDependencies": { + "chart.js": "^3.5.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-color": { + "version": "2.19.3", + "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.19.3.tgz", + "integrity": "sha512-LEeGE/ZzNLIsFWa1TMe8y5VYqr7bibneWmvJwm1pCn/eNmrabWDh659JSPn9BuaMpEfU83WTOJfnCcjDZwNQTA==", + "dependencies": { + "@icons/material": "^0.2.4", + "lodash": "^4.17.15", + "lodash-es": "^4.17.15", + "material-colors": "^1.2.1", + "prop-types": "^15.5.10", + "reactcss": "^1.2.0", + "tinycolor2": "^1.4.1" + }, + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-copy-to-clipboard": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.1.0.tgz", + "integrity": "sha512-k61RsNgAayIJNoy9yDsYzDe/yAZAzEbEgcz3DZMhF686LEyukcE1hzurxe85JandPUG+yTfGVFzuEw3xt8WP/A==", + "dependencies": { + "copy-to-clipboard": "^3.3.1", + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "react": "^15.3.0 || 16 || 17 || 18" + } + }, + "node_modules/react-csv": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/react-csv/-/react-csv-2.2.2.tgz", + "integrity": "sha512-RG5hOcZKZFigIGE8LxIEV/OgS1vigFQT4EkaHeKgyuCbUAu9Nbd/1RYq++bJcJJ9VOqO/n9TZRADsXNDR4VEpw==" + }, + "node_modules/react-currency-format": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/react-currency-format/-/react-currency-format-1.1.0.tgz", + "integrity": "sha512-WWrEOIp/3GbDSk1wlhFXaBc7IHGT3IwL306DHbGP3GVr4YFa0iS5hHPbKjHa0haruGL4Ly+WG4/5jBHpUtgqZg==", + "dependencies": { + "prop-types": "^15.6.0" + }, + "peerDependencies": { + "react": "^0.14 || ^15.0.0-rc || ^15.0.0 || ^16.0.0-rc || ^16.0.0 || ^17.0.0", + "react-dom": "^0.14 || ^15.0.0-rc || ^15.0.0 || ^16.0.0-rc || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/react-dev-utils": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-10.2.1.tgz", + "integrity": "sha512-XxTbgJnYZmxuPtY3y/UV0D8/65NKkmaia4rXzViknVnZeVlklSh8u6TnaEYPfAi/Gh1TP4mEOXHI6jQOPbeakQ==", + "dependencies": { + "@babel/code-frame": "7.8.3", + "address": "1.1.2", + "browserslist": "4.10.0", + "chalk": "2.4.2", + "cross-spawn": "7.0.1", + "detect-port-alt": "1.1.6", + "escape-string-regexp": "2.0.0", + "filesize": "6.0.1", + "find-up": "4.1.0", + "fork-ts-checker-webpack-plugin": "3.1.1", + "global-modules": "2.0.0", + "globby": "8.0.2", + "gzip-size": "5.1.1", + "immer": "1.10.0", + "inquirer": "7.0.4", + "is-root": "2.1.0", + "loader-utils": "1.2.3", + "open": "^7.0.2", + "pkg-up": "3.1.0", + "react-error-overlay": "^6.0.7", + "recursive-readdir": "2.2.2", + "shell-quote": "1.7.2", + "strip-ansi": "6.0.0", + "text-table": "0.2.0" + }, + "engines": { + "node": ">=8.10" + } + }, + "node_modules/react-dev-utils/node_modules/@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dependencies": { + "@babel/highlight": "^7.8.3" + } + }, + "node_modules/react-dev-utils/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/react-dev-utils/node_modules/browserslist": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.10.0.tgz", + "integrity": "sha512-TpfK0TDgv71dzuTsEAlQiHeWQ/tiPqgNZVdv046fvNtBZrjbv2O3TsWCDU0AWGJJKCF/KsjNdLzR9hXOsh/CfA==", + "dependencies": { + "caniuse-lite": "^1.0.30001035", + "electron-to-chromium": "^1.3.378", + "node-releases": "^1.1.52", + "pkg-up": "^3.1.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + }, + "node_modules/react-dev-utils/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/react-dev-utils/node_modules/chalk/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/react-dev-utils/node_modules/cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==" + }, + "node_modules/react-dev-utils/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/react-dev-utils/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/react-dev-utils/node_modules/cross-spawn": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", + "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/react-dev-utils/node_modules/emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha512-knHEZMgs8BB+MInokmNTg/OyPlAddghe1YBgNwJBc5zsJi/uyIcXoSDsL/W9ymOsBoBGdPIHXYJ9+qKFwRwDng==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/react-dev-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dev-utils/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dev-utils/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/react-dev-utils/node_modules/inquirer": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.4.tgz", + "integrity": "sha512-Bu5Td5+j11sCkqfqmUTiwv+tWisMtP0L7Q8WrqA2C/BbBhy1YTdFrvjjlrKq8oagA/tLQBski2Gcx/Sqyi2qSQ==", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^2.4.2", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.2.0", + "rxjs": "^6.5.3", + "string-width": "^4.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/react-dev-utils/node_modules/inquirer/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/react-dev-utils/node_modules/inquirer/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/react-dev-utils/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/react-dev-utils/node_modules/loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/react-dev-utils/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dev-utils/node_modules/node-releases": { + "version": "1.1.77", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.77.tgz", + "integrity": "sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ==" + }, + "node_modules/react-dev-utils/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dev-utils/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dev-utils/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dev-utils/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dev-utils/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dev-utils/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dev-utils/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/react-dev-utils/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/react-dom": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", + "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "scheduler": "^0.20.2" + }, + "peerDependencies": { + "react": "17.0.2" + } + }, + "node_modules/react-error-overlay": { + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", + "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" + }, + "node_modules/react-fast-compare": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", + "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==" + }, + "node_modules/react-icons": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.12.0.tgz", + "integrity": "sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw==", + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-input-mask": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/react-input-mask/-/react-input-mask-2.0.4.tgz", + "integrity": "sha512-1hwzMr/aO9tXfiroiVCx5EtKohKwLk/NT8QlJXHQ4N+yJJFyUuMT+zfTpLBwX/lK3PkuMlievIffncpMZ3HGRQ==", + "dependencies": { + "invariant": "^2.2.4", + "warning": "^4.0.2" + }, + "peerDependencies": { + "react": ">=0.14.0", + "react-dom": ">=0.14.0" + } + }, + "node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, + "node_modules/react-modal-image": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/react-modal-image/-/react-modal-image-2.6.0.tgz", + "integrity": "sha512-NNc1xPKzFAn0VsNMdJ8NXt6c54aL/z0fcoYmw9qn4SBUONdGl+8LOQ0sTfo0wtdzcjLiby/ncloHcAL+UI+wIA==" + }, + "node_modules/react-number-format": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/react-number-format/-/react-number-format-4.9.4.tgz", + "integrity": "sha512-Gq20Z3ugqPLFgeaidnx5on9cNpbQZntPN3QgNAL/WJrNNlQnNznY0LCx7g8xtssmRBw0/hw+SCqw6zAcajooiA==", + "dependencies": { + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-overlays": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-5.2.1.tgz", + "integrity": "sha512-GLLSOLWr21CqtJn8geSwQfoJufdt3mfdsnIiQswouuQ2MMPns+ihZklxvsTDKD3cR2tF8ELbi5xUsvqVhR6WvA==", + "dependencies": { + "@babel/runtime": "^7.13.8", + "@popperjs/core": "^2.11.6", + "@restart/hooks": "^0.4.7", + "@types/warning": "^3.0.0", + "dom-helpers": "^5.2.0", + "prop-types": "^15.7.2", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + }, + "peerDependencies": { + "react": ">=16.3.0", + "react-dom": ">=16.3.0" + } + }, + "node_modules/react-popopo": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/react-popopo/-/react-popopo-2.1.9.tgz", + "integrity": "sha512-zXOpcLSpaLZmBxhdtenJzQPLjY81XknVS/tXH4Kv5BBrnYIUPHvVdGmS7+o9s7DjCzzdK7AdVwtG+FVSO0cZ8g==", + "dependencies": { + "classnames": ">= 2.0", + "prop-types": "^15.7.2", + "react": ">= 16.3", + "react-dom": ">= 16.3", + "styled-components": ">= 4.0" + }, + "peerDependencies": { + "classnames": ">= 2.0", + "react": ">= 16.3", + "react-dom": ">= 16.3", + "styled-components": ">= 4.0" + } + }, + "node_modules/react-qr-code": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/react-qr-code/-/react-qr-code-2.0.12.tgz", + "integrity": "sha512-k+pzP5CKLEGBRwZsDPp98/CAJeXlsYRHM2iZn1Sd5Th/HnKhIZCSg27PXO58zk8z02RaEryg+60xa4vyywMJwg==", + "dependencies": { + "prop-types": "^15.8.1", + "qr.js": "0.0.0" + }, + "peerDependencies": { + "react": "^16.x || ^17.x || ^18.x", + "react-native-svg": "*" + }, + "peerDependenciesMeta": { + "react-native-svg": { + "optional": true + } + } + }, + "node_modules/react-query": { + "version": "3.39.3", + "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz", + "integrity": "sha512-nLfLz7GiohKTJDuT4us4X3h/8unOh+00MLb2yJoGTPjxKs2bc1iDhkNx2bd5MKklXnOD3NrVZ+J2UXujA5In4g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "broadcast-channel": "^3.4.1", + "match-sorter": "^6.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/react-router": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", + "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/react-router-dom": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", + "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.3.4", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/react-router/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react-scripts": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.4.3.tgz", + "integrity": "sha512-oSnoWmii/iKdeQiwaO6map1lUaZLmG0xIUyb/HwCVFLT7gNbj8JZ9RmpvMCZ4fB98ZUMRfNmp/ft8uy/xD1RLA==", + "dependencies": { + "@babel/core": "7.9.0", + "@svgr/webpack": "4.3.3", + "@typescript-eslint/eslint-plugin": "^2.10.0", + "@typescript-eslint/parser": "^2.10.0", + "babel-eslint": "10.1.0", + "babel-jest": "^24.9.0", + "babel-loader": "8.1.0", + "babel-plugin-named-asset-import": "^0.3.6", + "babel-preset-react-app": "^9.1.2", + "camelcase": "^5.3.1", + "case-sensitive-paths-webpack-plugin": "2.3.0", + "css-loader": "3.4.2", + "dotenv": "8.2.0", + "dotenv-expand": "5.1.0", + "eslint": "^6.6.0", + "eslint-config-react-app": "^5.2.1", + "eslint-loader": "3.0.3", + "eslint-plugin-flowtype": "4.6.0", + "eslint-plugin-import": "2.20.1", + "eslint-plugin-jsx-a11y": "6.2.3", + "eslint-plugin-react": "7.19.0", + "eslint-plugin-react-hooks": "^1.6.1", + "file-loader": "4.3.0", + "fs-extra": "^8.1.0", + "html-webpack-plugin": "4.0.0-beta.11", + "identity-obj-proxy": "3.0.0", + "jest": "24.9.0", + "jest-environment-jsdom-fourteen": "1.0.1", + "jest-resolve": "24.9.0", + "jest-watch-typeahead": "0.4.2", + "mini-css-extract-plugin": "0.9.0", + "optimize-css-assets-webpack-plugin": "5.0.3", + "pnp-webpack-plugin": "1.6.4", + "postcss-flexbugs-fixes": "4.1.0", + "postcss-loader": "3.0.0", + "postcss-normalize": "8.0.1", + "postcss-preset-env": "6.7.0", + "postcss-safe-parser": "4.0.1", + "react-app-polyfill": "^1.0.6", + "react-dev-utils": "^10.2.1", + "resolve": "1.15.0", + "resolve-url-loader": "3.1.1", + "sass-loader": "8.0.2", + "semver": "6.3.0", + "style-loader": "0.23.1", + "terser-webpack-plugin": "2.3.8", + "ts-pnp": "1.1.6", + "url-loader": "2.3.0", + "webpack": "4.42.0", + "webpack-dev-server": "3.11.0", + "webpack-manifest-plugin": "2.2.0", + "workbox-webpack-plugin": "4.3.1" + }, + "bin": { + "react-scripts": "bin/react-scripts.js" + }, + "engines": { + "node": ">=8.10" + }, + "optionalDependencies": { + "fsevents": "2.1.2" + }, + "peerDependencies": { + "typescript": "^3.2.1" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/react-scripts/node_modules/@babel/core": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", + "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.0", + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helpers": "^7.9.0", + "@babel/parser": "^7.9.0", + "@babel/template": "^7.8.6", + "@babel/traverse": "^7.9.0", + "@babel/types": "^7.9.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/react-scripts/node_modules/@babel/core/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/react-scripts/node_modules/resolve": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.0.tgz", + "integrity": "sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw==", + "dependencies": { + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/react-smooth": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.1.tgz", + "integrity": "sha512-OE4hm7XqR0jNOq3Qmk9mFLyd6p2+j6bvbPJ7qlB7+oo0eNcL2l7WQzG6MBnT3EXY6xzkLMUBec3AfewJdA0J8w==", + "dependencies": { + "fast-equals": "^5.0.1", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-text-mask": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/react-text-mask/-/react-text-mask-5.5.0.tgz", + "integrity": "sha512-SLJlJQxa0uonMXsnXRpv5abIepGmHz77ylQcra0GNd7Jtk4Wj2Mtp85uGQHv1avba2uI8ZvRpIEQPpJKsqRGYw==", + "dependencies": { + "prop-types": "^15.5.6" + }, + "peerDependencies": { + "react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-toastify": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.0.0.tgz", + "integrity": "sha512-gmxAFTKV0VVN7s5UEcZdC+bBR1EQtsqXgHJWQgB0G5J8m3Mdxz1Pacm7BJ1nTHkMMNfupruKCu7wUwAq46Z1jg==", + "dependencies": { + "clsx": "^1.1.1" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/react-trello": { + "version": "2.2.11", + "resolved": "https://registry.npmjs.org/react-trello/-/react-trello-2.2.11.tgz", + "integrity": "sha512-Zm7qrPAcFTysUXK6wpa1KhTt7fTadIZgNGYj+blDWGnppFYW7GMi1p+S6J8P9quhzKnIJTSZXVzHA1f4sREIVQ==", + "dependencies": { + "autosize": "^4.0.2", + "classnames": "^2.2.6", + "immutability-helper": "^2.8.1", + "lodash": "^4.17.11", + "prop-types": "^15.7.2", + "react-popopo": "^2.1.9", + "react-redux": "^5.0.7", + "redux": "^4.0.0", + "redux-actions": "^2.6.1", + "redux-logger": "^3.0.6", + "trello-smooth-dnd": "1.0.0", + "uuid": "^3.3.2" + }, + "peerDependencies": { + "lodash": ">= 4.17.11", + "react": "*", + "react-dom": "*", + "react-redux": ">= 5.0.7", + "redux": ">= 4.0.0", + "redux-actions": ">= 2.6.1", + "redux-logger": ">= 3.0.6", + "styled-components": ">= 4.0.3" + } + }, + "node_modules/react-trello/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react-trello/node_modules/react-redux": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.1.2.tgz", + "integrity": "sha512-Ns1G0XXc8hDyH/OcBHOxNgQx9ayH3SPxBnFCOidGKSle8pKihysQw2rG/PmciUQRoclhVBO8HMhiRmGXnDja9Q==", + "dependencies": { + "@babel/runtime": "^7.1.2", + "hoist-non-react-statics": "^3.3.0", + "invariant": "^2.2.4", + "loose-envify": "^1.1.0", + "prop-types": "^15.6.1", + "react-is": "^16.6.0", + "react-lifecycles-compat": "^3.0.0" + }, + "peerDependencies": { + "react": "^0.14.0 || ^15.0.0-0 || ^16.0.0-0", + "redux": "^2.0.0 || ^3.0.0 || ^4.0.0-0" + } + }, + "node_modules/react-trello/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/reactcss": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz", + "integrity": "sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==", + "dependencies": { + "lodash": "^4.0.1" + } + }, + "node_modules/read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==", + "dependencies": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==", + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==", + "dependencies": { + "pify": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/realpath-native": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz", + "integrity": "sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA==", + "dependencies": { + "util.promisify": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/recharts": { + "version": "2.12.6", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.12.6.tgz", + "integrity": "sha512-D+7j9WI+D0NHauah3fKHuNNcRK8bOypPW7os1DERinogGBGaHI7i6tQKJ0aUF3JXyBZ63dyfKIW2WTOPJDxJ8w==", + "dependencies": { + "clsx": "^2.0.0", + "eventemitter3": "^4.0.1", + "lodash": "^4.17.21", + "react-is": "^16.10.2", + "react-smooth": "^4.0.0", + "recharts-scale": "^0.4.4", + "tiny-invariant": "^1.3.1", + "victory-vendor": "^36.6.8" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/recharts-scale": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", + "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", + "dependencies": { + "decimal.js-light": "^2.4.1" + } + }, + "node_modules/recharts/node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/recharts/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/recursive-readdir": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz", + "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==", + "dependencies": { + "minimatch": "3.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/recursive-readdir/node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/reduce-reducers": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/reduce-reducers/-/reduce-reducers-0.4.3.tgz", + "integrity": "sha512-+CNMnI8QhgVMtAt54uQs3kUxC3Sybpa7Y63HR14uGLgI9/QR5ggHvpxwhGGe3wmx5V91YwqQIblN9k5lspAmGw==" + }, + "node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, + "node_modules/redux-actions": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/redux-actions/-/redux-actions-2.6.5.tgz", + "integrity": "sha512-pFhEcWFTYNk7DhQgxMGnbsB1H2glqhQJRQrtPb96kD3hWiZRzXHwwmFPswg6V2MjraXRXWNmuP9P84tvdLAJmw==", + "dependencies": { + "invariant": "^2.2.4", + "just-curry-it": "^3.1.0", + "loose-envify": "^1.4.0", + "reduce-reducers": "^0.4.3", + "to-camel-case": "^1.0.0" + } + }, + "node_modules/redux-logger": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/redux-logger/-/redux-logger-3.0.6.tgz", + "integrity": "sha512-JoCIok7bg/XpqA1JqCqXFypuqBbQzGQySrhFzewB7ThcnysTO30l4VCst86AuB9T9tuT03MAA56Jw2PNhRSNCg==", + "dependencies": { + "deep-diff": "^0.3.5" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regex-parser": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.10.tgz", + "integrity": "sha512-8t6074A68gHfU8Neftl0Le6KTDwfGAj7IyjPIMSfikI2wJUTHDMaIq42bUsfVnj8mhx0R+45rdUXHGpN164avA==" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/remove-accents": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz", + "integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==" + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==" + }, + "node_modules/renderkid": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.7.tgz", + "integrity": "sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ==", + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^3.0.1" + } + }, + "node_modules/renderkid/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/renderkid/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request-promise-core": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", + "dependencies": { + "lodash": "^4.17.19" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "node_modules/request-promise-native": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", + "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", + "dependencies": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "engines": { + "node": ">=0.12.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha512-ccu8zQTrzVr954472aUVPLEcB3YpKSYR3cg/3lo1okzobPBM+1INXBbBZlDbnI/hbEocnf8j0QVo43hQKrbchg==", + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", + "deprecated": "https://github.com/lydell/resolve-url#deprecated" + }, + "node_modules/resolve-url-loader": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.1.tgz", + "integrity": "sha512-K1N5xUjj7v0l2j/3Sgs5b8CjrrgtC70SmdCuZiJ8tSyb5J+uk3FoeZ4b7yTnH6j7ngI+Bc5bldHJIa8hYdu2gQ==", + "dependencies": { + "adjust-sourcemap-loader": "2.0.0", + "camelcase": "5.3.1", + "compose-function": "3.0.3", + "convert-source-map": "1.7.0", + "es6-iterator": "2.0.3", + "loader-utils": "1.2.3", + "postcss": "7.0.21", + "rework": "1.0.1", + "rework-visit": "1.0.0", + "source-map": "0.6.1" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/resolve-url-loader/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-url-loader/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-url-loader/node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-url-loader/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/resolve-url-loader/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/resolve-url-loader/node_modules/convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/resolve-url-loader/node_modules/emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha512-knHEZMgs8BB+MInokmNTg/OyPlAddghe1YBgNwJBc5zsJi/uyIcXoSDsL/W9ymOsBoBGdPIHXYJ9+qKFwRwDng==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/resolve-url-loader/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/resolve-url-loader/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-url-loader/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/resolve-url-loader/node_modules/loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/resolve-url-loader/node_modules/postcss": { + "version": "7.0.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.21.tgz", + "integrity": "sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ==", + "dependencies": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/resolve-url-loader/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/resolve-url-loader/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-url-loader/node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "engines": { + "node": ">=0.12" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/rework": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz", + "integrity": "sha512-eEjL8FdkdsxApd0yWVZgBGzfCQiT8yqSc2H1p4jpZpQdtz7ohETiDMoje5PlM8I9WgkqkreVxFUKYOiJdVWDXw==", + "dependencies": { + "convert-source-map": "^0.3.3", + "css": "^2.0.0" + } + }, + "node_modules/rework-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rework-visit/-/rework-visit-1.0.0.tgz", + "integrity": "sha512-W6V2fix7nCLUYX1v6eGPrBOZlc03/faqzP4sUxMAJMBMOPYhfV/RyLegTufn5gJKaOITyi+gvf0LXDZ9NzkHnQ==" + }, + "node_modules/rework/node_modules/convert-source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz", + "integrity": "sha512-+4nRk0k3oEpwUB7/CalD7xE2z4VmtEnnq0GO2IPTkrooTrAhEsWvuLF5iWP1dXrwluki/azwXV1ve7gtYuPldg==" + }, + "node_modules/rgb-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", + "integrity": "sha512-gDK5mkALDFER2YLqH6imYvK6g02gpNGM4ILDZ472EwWfXZnC2ZEpoB2ECXTyOVUKuk/bPJZMzwQPBYICzP+D3w==" + }, + "node_modules/rgba-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", + "integrity": "sha512-zgn5OjNQXLUTdq8m17KdaicF6w89TZs8ZU8y0AYENIU6wG8GG6LLm0yLSiPY8DmaYmHdgRW8rnApjoT0fQRfMg==" + }, + "node_modules/rifm": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/rifm/-/rifm-0.7.0.tgz", + "integrity": "sha512-DSOJTWHD67860I5ojetXdEQRIBvF6YcpNe53j0vn1vp9EUb9N80EiZTxgP+FkDKorWC8PZw052kTF4C1GOivCQ==", + "dependencies": { + "@babel/runtime": "^7.3.1" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "engines": { + "node": "6.* || >= 7.*" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==", + "dependencies": { + "aproba": "^1.1.1" + } + }, + "node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/rxjs/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-array-concat/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "deprecated": "some dependency vulnerabilities fixed, support for node < 10 dropped, and newer ECMAScript syntax/features added", + "dependencies": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + }, + "bin": { + "sane": "src/cli.js" + }, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/sane/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sanitize.css": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-10.0.0.tgz", + "integrity": "sha512-vTxrZz4dX5W86M6oVWVdOVe72ZiPs41Oi7Z6Km4W5Turyz28mrXSJhhEBZoRtzJWIv3833WKVwLSDWWkEfupMg==" + }, + "node_modules/sass-loader": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz", + "integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==", + "dependencies": { + "clone-deep": "^4.0.1", + "loader-utils": "^1.2.3", + "neo-async": "^2.6.1", + "schema-utils": "^2.6.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "fibers": ">= 3.1.0", + "node-sass": "^4.0.0", + "sass": "^1.3.0", + "webpack": "^4.36.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "fibers": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/sass-loader/node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-loader/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sass-loader/node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sax": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", + "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" + }, + "node_modules/saxes": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", + "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", + "dependencies": { + "xmlchars": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "node_modules/schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dependencies": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/sdp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/sdp/-/sdp-3.2.0.tgz", + "integrity": "sha512-d7wDPgDV3DDiqulJjKiV2865wKsJ34YI+NDREbm+FySq6WuKOikwyNQcm+doLAZ1O6ltdO0SeKle2xMpN3Brgw==", + "peer": true + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" + }, + "node_modules/selfsigned": { + "version": "1.10.14", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.14.tgz", + "integrity": "sha512-lkjaiAye+wBZDCBsu5BGi0XiLRxeUlsGod5ZP924CRSEoGuZAw/f7y9RKu28rwTfiHVhdavhB0qH0INV6P1lEA==", + "dependencies": { + "node-forge": "^0.10.0" + } + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serialize-javascript/node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/shallow-clone": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-0.1.2.tgz", + "integrity": "sha512-J1zdXCky5GmNnuauESROVu31MQSnLoYvlyEn6j2Ztk6Q5EHFIhxkMhYcv6vuDzl2XEzoRr856QwzMgWM/TmZgw==", + "dependencies": { + "is-extendable": "^0.1.1", + "kind-of": "^2.0.1", + "lazy-cache": "^0.2.3", + "mixin-object": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shallow-clone/node_modules/kind-of": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-2.0.1.tgz", + "integrity": "sha512-0u8i1NZ/mg0b+W3MGGw5I7+6Eib2nx72S/QvXa0hYjEkjTknYmEYQJwGu3mLC0BrhtJjtQafTkyRUQ75Kx0LVg==", + "dependencies": { + "is-buffer": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shallow-clone/node_modules/lazy-cache": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz", + "integrity": "sha512-gkX52wvU/R8DVMMt78ATVPFMJqfW8FPz1GZ1sVHBVQHmu/WvhIWE4cE1GBzhJNFicDeYhnwp6Rl35BcAIM3YOQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shell-quote": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", + "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==" + }, + "node_modules/shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==" + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dependencies": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "engines": { + "node": ">=4" + } + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/snapdragon/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/socket.io-client": { + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.5.tgz", + "integrity": "sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/sockjs": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz", + "integrity": "sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==", + "dependencies": { + "faye-websocket": "^0.10.0", + "uuid": "^3.4.0", + "websocket-driver": "0.6.5" + } + }, + "node_modules/sockjs-client": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", + "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", + "dependencies": { + "debug": "^3.2.5", + "eventsource": "^1.0.7", + "faye-websocket": "~0.11.1", + "inherits": "^2.0.3", + "json3": "^3.3.2", + "url-parse": "^1.4.3" + } + }, + "node_modules/sockjs-client/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/sockjs-client/node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/sockjs/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==", + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "deprecated": "See https://github.com/lydell/source-map-url#deprecated" + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", + "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==" + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/spdy-transport/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/split-on-first": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", + "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ssri": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-7.1.1.tgz", + "integrity": "sha512-w+daCzXN89PseTL99MkA+fxJEcU3wfaE/ah0i0lnOlpG1CYLJ2ZjzEry68YBKfLs4JfoTShrTEsJkAZuNZ/stw==", + "dependencies": { + "figgy-pudding": "^3.5.1", + "minipass": "^3.1.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dependencies": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "node_modules/stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dependencies": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dependencies": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/stream-shift": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==" + }, + "node_modules/strict-uri-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/string-length": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", + "integrity": "sha512-Qka42GGrS8Mm3SZ+7cH8UXiIWI867/b/Z/feQSpQx/rbfB8UGknGEZVaUQMOUVj+soY6NpWAxily63HI1OckVQ==", + "dependencies": { + "astral-regex": "^1.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/string-length/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/string-length/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", + "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "regexp.prototype.flags": "^1.5.2", + "set-function-name": "^2.0.2", + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-comments": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-1.0.2.tgz", + "integrity": "sha512-kL97alc47hoyIQSV165tTt9rG5dn4w1dNnBhOQ3bOU1Nc1hel09jnXANaHJ7vzHLd4Ju8kseDGzlev96pghLFw==", + "dependencies": { + "babel-extract-comments": "^1.0.0", + "babel-plugin-transform-object-rest-spread": "^6.26.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-loader": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz", + "integrity": "sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg==", + "dependencies": { + "loader-utils": "^1.1.0", + "schema-utils": "^1.0.0" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/style-loader/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/styled-components": { + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.11.tgz", + "integrity": "sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==", + "dependencies": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/traverse": "^7.4.5", + "@emotion/is-prop-valid": "^1.1.0", + "@emotion/stylis": "^0.8.4", + "@emotion/unitless": "^0.7.4", + "babel-plugin-styled-components": ">= 1.12.0", + "css-to-react-native": "^3.0.0", + "hoist-non-react-statics": "^3.0.0", + "shallowequal": "^1.1.0", + "supports-color": "^5.5.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0", + "react-is": ">= 16.8.0" + } + }, + "node_modules/styled-components/node_modules/@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + }, + "node_modules/styled-components/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/styled-components/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylehacks": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", + "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", + "dependencies": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/stylehacks/node_modules/postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dependencies": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" + }, + "node_modules/svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.", + "dependencies": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/svgo/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/svgo/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/svgo/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/svgo/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/svgo/node_modules/css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "node_modules/svgo/node_modules/css-what": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/svgo/node_modules/dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dependencies": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "node_modules/svgo/node_modules/domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/svgo/node_modules/domutils/node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "node_modules/svgo/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/svgo/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/svgo/node_modules/nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dependencies": { + "boolbase": "~1.0.0" + } + }, + "node_modules/svgo/node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "node_modules/svgo/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, + "node_modules/table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dependencies": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/table/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz", + "integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==", + "dependencies": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.8.tgz", + "integrity": "sha512-/fKw3R+hWyHfYx7Bv6oPqmk4HGQcrWLtV3X6ggvPuwPNHSnzvVV51z6OaaCOus4YLjutYGOz3pEpbhe6Up2s1w==", + "dependencies": { + "cacache": "^13.0.1", + "find-cache-dir": "^3.3.1", + "jest-worker": "^25.4.0", + "p-limit": "^2.3.0", + "schema-utils": "^2.6.6", + "serialize-javascript": "^4.0.0", + "source-map": "^0.6.1", + "terser": "^4.6.12", + "webpack-sources": "^1.4.3" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/terser-webpack-plugin/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/terser-webpack-plugin/node_modules/jest-worker": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", + "dependencies": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/terser-webpack-plugin/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/terser-webpack-plugin/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terser-webpack-plugin/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/terser-webpack-plugin/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/terser-webpack-plugin/node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/terser-webpack-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/terser/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/test-exclude": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", + "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", + "dependencies": { + "glob": "^7.1.3", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/test-exclude/node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/test-exclude/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/test-exclude/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/test-exclude/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/test-exclude/node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/test-exclude/node_modules/read-pkg-up": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", + "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "dependencies": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/text-mask-addons": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/text-mask-addons/-/text-mask-addons-3.8.0.tgz", + "integrity": "sha512-VSZSdc/tKn4zGxgpJ+uNBzoW1t472AoAFIlbw1K7hSNXz0DfSBYDJNRxLqgxOfWw1BY2z6DQpm7g0sYZn5qLpg==" + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + }, + "node_modules/throat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", + "integrity": "sha512-wCVxLDcFxw7ujDxaeJC6nfl2XfHJNYs8yUYJnvMgtPEFlttP9tHSfRUv2vBe6C4hkVFPWoP1P6ZccbYjmSEkKA==" + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" + }, + "node_modules/timers-browserify": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", + "dependencies": { + "setimmediate": "^1.0.4" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==" + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, + "node_modules/tinycolor2": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==" + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" + }, + "node_modules/to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==" + }, + "node_modules/to-camel-case": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-camel-case/-/to-camel-case-1.0.0.tgz", + "integrity": "sha512-nD8pQi5H34kyu1QDMFjzEIYqk0xa9Alt6ZfrdEMuHCFOfTLhDG5pgTu/aAM9Wt9lXILwlXmWP43b8sav0GNE8Q==", + "dependencies": { + "to-space-case": "^1.0.0" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-no-case": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz", + "integrity": "sha512-Z3g735FxuZY8rodxV4gH7LxClE4H0hTIyHNIHdk+vpQxjLm0cwnKXq/OFVZ76SOQmto7txVcwSCwkU5kqp+FKg==" + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/to-space-case": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz", + "integrity": "sha512-rLdvwXZ39VOn1IxGL3V6ZstoTbwLRckQmn/U8ZDLuWwIXNpuZDhQ3AiRUlhTbOXFVE9C+dR51wM0CBDhk31VcA==", + "dependencies": { + "to-no-case": "^1.0.0" + } + }, + "node_modules/toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==" + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/trello-smooth-dnd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trello-smooth-dnd/-/trello-smooth-dnd-1.0.0.tgz", + "integrity": "sha512-KgYEwmxX08Dl4OmioEv24LSnlNp9jNv8lwTQlUMbMm6B+VuwyQuuuoyu4wlsRweiMCCC6sZXpCCGkmAni/vCaQ==" + }, + "node_modules/ts-pnp": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.1.6.tgz", + "integrity": "sha512-CrG5GqAAzMT7144Cl+UIFP7mz/iIhiy+xQ6GGcnjTezhALT02uPMRw7tgDSESgB5MsfKt55+GPWw4ir1kVtMIQ==", + "engines": { + "node": ">=6" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" + }, + "node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" + }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, + "node_modules/typescript": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/uncontrollable": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", + "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", + "dependencies": { + "@babel/runtime": "^7.6.3", + "@types/react": ">=16.9.11", + "invariant": "^2.2.4", + "react-lifecycles-compat": "^3.0.4" + }, + "peerDependencies": { + "react": ">=15.0.0" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "engines": { + "node": ">=4" + } + }, + "node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==" + }, + "node_modules/uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha512-mZdDpf3vBV5Efh29kMw5tXoup/buMgxLzOt/XKFKcVmi+15ManNQWr6HfZ2aiZTYlYixbdNJ0KFmIZIv52tHSQ==" + }, + "node_modules/unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dependencies": { + "unique-slug": "^2.0.0" + } + }, + "node_modules/unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dependencies": { + "imurmurhash": "^0.1.4" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unload": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unload/-/unload-2.2.0.tgz", + "integrity": "sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==", + "dependencies": { + "@babel/runtime": "^7.6.2", + "detect-node": "^2.0.4" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==" + }, + "node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", + "deprecated": "Please see https://github.com/lydell/urix#deprecated" + }, + "node_modules/url": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", + "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", + "dependencies": { + "punycode": "^1.4.1", + "qs": "^6.11.2" + } + }, + "node_modules/url-loader": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-2.3.0.tgz", + "integrity": "sha512-goSdg8VY+7nPZKUEChZSEtW5gjbS66USIGCeSJ1OVOJ7Yfuh/36YxCwMi5HVEJh6mqUYOoy3NJ0vlOMrWsSHog==", + "dependencies": { + "loader-utils": "^1.2.3", + "mime": "^2.4.4", + "schema-utils": "^2.5.0" + }, + "engines": { + "node": ">= 8.9.0" + }, + "peerDependencies": { + "file-loader": "*", + "webpack": "^4.0.0" + }, + "peerDependenciesMeta": { + "file-loader": { + "optional": true + } + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" + }, + "node_modules/url/node_modules/qs": { + "version": "6.12.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz", + "integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/use-debounce": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/use-debounce/-/use-debounce-7.0.1.tgz", + "integrity": "sha512-fOrzIw2wstbAJuv8PC9Vg4XgwyTLEOdq4y/Z3IhVl8DAE4svRcgyEUvrEXu+BMNgMoc3YND6qLT61kkgEKXh7Q==", + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/use-sound": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/use-sound/-/use-sound-2.2.0.tgz", + "integrity": "sha512-Sa524UuX1piuCHomP/STSjRVhZK6FaXC9qOjfwms2uWp9EErUl+g5ioju/ECfThtexNgcceNunuUtrEr7707Uw==", + "dependencies": { + "howler": "^2.1.3" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/use-strict": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/use-strict/-/use-strict-1.0.1.tgz", + "integrity": "sha512-IeiWvvEXfW5ltKVMkxq6FvNf2LojMKvB2OCeja6+ct24S1XOmQw2dGr2JyndwACWAGJva9B7yPHwAmeA9QCqAQ==" + }, + "node_modules/util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==", + "dependencies": { + "inherits": "2.0.1" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "dependencies": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "node_modules/util/node_modules/inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==" + }, + "node_modules/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", + "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==" + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vendors": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", + "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + }, + "node_modules/vest-utils": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/vest-utils/-/vest-utils-0.0.5.tgz", + "integrity": "sha512-uA5NW62n/EdmIOiEHZUQesUSzRnzJgh4R36hZ1omdil0wwYgv7Qobb5omnl1Z03ymopadDtbGXNRxnNFIlwTjQ==" + }, + "node_modules/victory-vendor": { + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz", + "integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, + "node_modules/vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==" + }, + "node_modules/w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.", + "dependencies": { + "browser-process-hrtime": "^1.0.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", + "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", + "dependencies": { + "domexception": "^1.0.1", + "webidl-conversions": "^4.0.2", + "xml-name-validator": "^3.0.0" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/watchpack": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", + "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", + "dependencies": { + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + }, + "optionalDependencies": { + "chokidar": "^3.4.1", + "watchpack-chokidar2": "^2.0.1" + } + }, + "node_modules/watchpack-chokidar2": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", + "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", + "optional": true, + "dependencies": { + "chokidar": "^2.1.8" + } + }, + "node_modules/watchpack-chokidar2/node_modules/binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "optional": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", + "optional": true, + "dependencies": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "optionalDependencies": { + "fsevents": "^1.2.7" + } + }, + "node_modules/watchpack-chokidar2/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "optional": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "optional": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "deprecated": "The v1 package contains DANGEROUS / INSECURE binaries. Upgrade to safe fsevents v2", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "optional": true, + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "optional": true, + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", + "optional": true, + "dependencies": { + "binary-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "optional": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "optional": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/micromatch/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "optional": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/micromatch/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "optional": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/micromatch/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "optional": true, + "dependencies": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/watchpack-chokidar2/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "optional": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "node_modules/webpack": { + "version": "4.42.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.42.0.tgz", + "integrity": "sha512-EzJRHvwQyBiYrYqhyjW9AqM90dE4+s1/XtCfn7uWg6cS72zH+2VPFAlsnW0+W0cDi0XRjNKUMoJtpSi50+Ph6w==", + "dependencies": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-module-context": "1.8.5", + "@webassemblyjs/wasm-edit": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5", + "acorn": "^6.2.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.1.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.1", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.6.0", + "webpack-sources": "^1.4.1" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-dev-middleware": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz", + "integrity": "sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==", + "dependencies": { + "memory-fs": "^0.4.1", + "mime": "^2.4.4", + "mkdirp": "^0.5.1", + "range-parser": "^1.2.1", + "webpack-log": "^2.0.0" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/webpack-dev-server": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz", + "integrity": "sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==", + "dependencies": { + "ansi-html": "0.0.7", + "bonjour": "^3.5.0", + "chokidar": "^2.1.8", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", + "debug": "^4.1.1", + "del": "^4.1.1", + "express": "^4.17.1", + "html-entities": "^1.3.1", + "http-proxy-middleware": "0.19.1", + "import-local": "^2.0.0", + "internal-ip": "^4.3.0", + "ip": "^1.1.5", + "is-absolute-url": "^3.0.3", + "killable": "^1.0.1", + "loglevel": "^1.6.8", + "opn": "^5.5.0", + "p-retry": "^3.0.1", + "portfinder": "^1.0.26", + "schema-utils": "^1.0.0", + "selfsigned": "^1.10.7", + "semver": "^6.3.0", + "serve-index": "^1.9.1", + "sockjs": "0.3.20", + "sockjs-client": "1.4.0", + "spdy": "^4.0.2", + "strip-ansi": "^3.0.1", + "supports-color": "^6.1.0", + "url": "^0.11.0", + "webpack-dev-middleware": "^3.7.2", + "webpack-log": "^2.0.0", + "ws": "^6.2.1", + "yargs": "^13.3.2" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 6.11.5" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", + "dependencies": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "optionalDependencies": { + "fsevents": "^1.2.7" + } + }, + "node_modules/webpack-dev-server/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "deprecated": "The v1 package contains DANGEROUS / INSECURE binaries. Upgrade to safe fsevents v2", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/webpack-dev-server/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/webpack-dev-server/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack-dev-server/node_modules/is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/webpack-dev-server/node_modules/is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", + "dependencies": { + "binary-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/micromatch/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/micromatch/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/micromatch/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dependencies": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/webpack-dev-server/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/webpack-dev-server/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/webpack-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "dependencies": { + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/webpack-log/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/webpack-manifest-plugin": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-2.2.0.tgz", + "integrity": "sha512-9S6YyKKKh/Oz/eryM1RyLVDVmy3NSPV0JXMRhZ18fJsq+AwGxUY34X54VNwkzYcEmEkDwNxuEOboCZEebJXBAQ==", + "dependencies": { + "fs-extra": "^7.0.0", + "lodash": ">=3.5 <5", + "object.entries": "^1.1.0", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=6.11.5" + }, + "peerDependencies": { + "webpack": "2 || 3 || 4" + } + }, + "node_modules/webpack-manifest-plugin/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dependencies": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "node_modules/webpack-sources/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/webpack/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dependencies": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dependencies": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/webpack/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/webpack/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/ssri": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", + "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", + "dependencies": { + "figgy-pudding": "^3.5.1" + } + }, + "node_modules/webpack/node_modules/terser-webpack-plugin": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", + "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", + "dependencies": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^4.0.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/webpack/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webrtc-adapter": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-9.0.1.tgz", + "integrity": "sha512-1AQO+d4ElfVSXyzNVTOewgGT/tAomwwztX/6e3totvyyzXPvXIIuUUjAmyZGbKBKbZOXauuJooZm3g6IuFuiNQ==", + "peer": true, + "dependencies": { + "sdp": "^3.2.0" + }, + "engines": { + "node": ">=6.0.0", + "npm": ">=3.10.0" + } + }, + "node_modules/websocket-driver": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz", + "integrity": "sha512-oBx6ZM1Gs5q2jwZuSN/Qxyy/fbgomV8+vqsmipaPKB/74hjHlKuM07jNmRhn4qa2AdUwsgxrltq+gaPsHgcl0Q==", + "dependencies": { + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==" + }, + "node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + }, + "node_modules/whatwg-url": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", + "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==" + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workbox-background-sync": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-4.3.1.tgz", + "integrity": "sha512-1uFkvU8JXi7L7fCHVBEEnc3asPpiAL33kO495UMcD5+arew9IbKW2rV5lpzhoWcm/qhGB89YfO4PmB/0hQwPRg==", + "dependencies": { + "workbox-core": "^4.3.1" + } + }, + "node_modules/workbox-broadcast-update": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-4.3.1.tgz", + "integrity": "sha512-MTSfgzIljpKLTBPROo4IpKjESD86pPFlZwlvVG32Kb70hW+aob4Jxpblud8EhNb1/L5m43DUM4q7C+W6eQMMbA==", + "dependencies": { + "workbox-core": "^4.3.1" + } + }, + "node_modules/workbox-build": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-4.3.1.tgz", + "integrity": "sha512-UHdwrN3FrDvicM3AqJS/J07X0KXj67R8Cg0waq1MKEOqzo89ap6zh6LmaLnRAjpB+bDIz+7OlPye9iii9KBnxw==", + "dependencies": { + "@babel/runtime": "^7.3.4", + "@hapi/joi": "^15.0.0", + "common-tags": "^1.8.0", + "fs-extra": "^4.0.2", + "glob": "^7.1.3", + "lodash.template": "^4.4.0", + "pretty-bytes": "^5.1.0", + "stringify-object": "^3.3.0", + "strip-comments": "^1.0.2", + "workbox-background-sync": "^4.3.1", + "workbox-broadcast-update": "^4.3.1", + "workbox-cacheable-response": "^4.3.1", + "workbox-core": "^4.3.1", + "workbox-expiration": "^4.3.1", + "workbox-google-analytics": "^4.3.1", + "workbox-navigation-preload": "^4.3.1", + "workbox-precaching": "^4.3.1", + "workbox-range-requests": "^4.3.1", + "workbox-routing": "^4.3.1", + "workbox-strategies": "^4.3.1", + "workbox-streams": "^4.3.1", + "workbox-sw": "^4.3.1", + "workbox-window": "^4.3.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/workbox-build/node_modules/fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "node_modules/workbox-cacheable-response": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-4.3.1.tgz", + "integrity": "sha512-Rp5qlzm6z8IOvnQNkCdO9qrDgDpoPNguovs0H8C+wswLuPgSzSp9p2afb5maUt9R1uTIwOXrVQMmPfPypv+npw==", + "dependencies": { + "workbox-core": "^4.3.1" + } + }, + "node_modules/workbox-core": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-4.3.1.tgz", + "integrity": "sha512-I3C9jlLmMKPxAC1t0ExCq+QoAMd0vAAHULEgRZ7kieCdUd919n53WC0AfvokHNwqRhGn+tIIj7vcb5duCjs2Kg==" + }, + "node_modules/workbox-expiration": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-4.3.1.tgz", + "integrity": "sha512-vsJLhgQsQouv9m0rpbXubT5jw0jMQdjpkum0uT+d9tTwhXcEZks7qLfQ9dGSaufTD2eimxbUOJfWLbNQpIDMPw==", + "dependencies": { + "workbox-core": "^4.3.1" + } + }, + "node_modules/workbox-google-analytics": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-4.3.1.tgz", + "integrity": "sha512-xzCjAoKuOb55CBSwQrbyWBKqp35yg1vw9ohIlU2wTy06ZrYfJ8rKochb1MSGlnoBfXGWss3UPzxR5QL5guIFdg==", + "deprecated": "It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained", + "dependencies": { + "workbox-background-sync": "^4.3.1", + "workbox-core": "^4.3.1", + "workbox-routing": "^4.3.1", + "workbox-strategies": "^4.3.1" + } + }, + "node_modules/workbox-navigation-preload": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-4.3.1.tgz", + "integrity": "sha512-K076n3oFHYp16/C+F8CwrRqD25GitA6Rkd6+qAmLmMv1QHPI2jfDwYqrytOfKfYq42bYtW8Pr21ejZX7GvALOw==", + "dependencies": { + "workbox-core": "^4.3.1" + } + }, + "node_modules/workbox-precaching": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-4.3.1.tgz", + "integrity": "sha512-piSg/2csPoIi/vPpp48t1q5JLYjMkmg5gsXBQkh/QYapCdVwwmKlU9mHdmy52KsDGIjVaqEUMFvEzn2LRaigqQ==", + "dependencies": { + "workbox-core": "^4.3.1" + } + }, + "node_modules/workbox-range-requests": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-4.3.1.tgz", + "integrity": "sha512-S+HhL9+iTFypJZ/yQSl/x2Bf5pWnbXdd3j57xnb0V60FW1LVn9LRZkPtneODklzYuFZv7qK6riZ5BNyc0R0jZA==", + "dependencies": { + "workbox-core": "^4.3.1" + } + }, + "node_modules/workbox-routing": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-4.3.1.tgz", + "integrity": "sha512-FkbtrODA4Imsi0p7TW9u9MXuQ5P4pVs1sWHK4dJMMChVROsbEltuE79fBoIk/BCztvOJ7yUpErMKa4z3uQLX+g==", + "dependencies": { + "workbox-core": "^4.3.1" + } + }, + "node_modules/workbox-strategies": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-4.3.1.tgz", + "integrity": "sha512-F/+E57BmVG8dX6dCCopBlkDvvhg/zj6VDs0PigYwSN23L8hseSRwljrceU2WzTvk/+BSYICsWmRq5qHS2UYzhw==", + "dependencies": { + "workbox-core": "^4.3.1" + } + }, + "node_modules/workbox-streams": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-4.3.1.tgz", + "integrity": "sha512-4Kisis1f/y0ihf4l3u/+ndMkJkIT4/6UOacU3A4BwZSAC9pQ9vSvJpIi/WFGQRH/uPXvuVjF5c2RfIPQFSS2uA==", + "dependencies": { + "workbox-core": "^4.3.1" + } + }, + "node_modules/workbox-sw": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-4.3.1.tgz", + "integrity": "sha512-0jXdusCL2uC5gM3yYFT6QMBzKfBr2XTk0g5TPAV4y8IZDyVNDyj1a8uSXy3/XrvkVTmQvLN4O5k3JawGReXr9w==" + }, + "node_modules/workbox-webpack-plugin": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-4.3.1.tgz", + "integrity": "sha512-gJ9jd8Mb8wHLbRz9ZvGN57IAmknOipD3W4XNE/Lk/4lqs5Htw4WOQgakQy/o/4CoXQlMCYldaqUg+EJ35l9MEQ==", + "dependencies": { + "@babel/runtime": "^7.0.0", + "json-stable-stringify": "^1.0.1", + "workbox-build": "^4.3.1" + }, + "engines": { + "node": ">=4.0.0" + }, + "peerDependencies": { + "webpack": "^2.0.0 || ^3.0.0 || ^4.0.0" + } + }, + "node_modules/workbox-window": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-4.3.1.tgz", + "integrity": "sha512-C5gWKh6I58w3GeSc0wp2Ne+rqVw8qwcmZnQGpjiek8A2wpbxSJb1FdCoQVO+jDJs35bFgo/WETgl1fqgsxN0Hg==", + "dependencies": { + "workbox-core": "^4.3.1" + } + }, + "node_modules/worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dependencies": { + "errno": "~0.1.7" + } + }, + "node_modules/worker-rpc": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/worker-rpc/-/worker-rpc-0.1.1.tgz", + "integrity": "sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg==", + "dependencies": { + "microevent.ts": "~0.1.1" + } + }, + "node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "engines": { + "node": ">=4" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dependencies": { + "mkdirp": "^0.5.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/write-file-atomic": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.1.tgz", + "integrity": "sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==", + "dependencies": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "node_modules/ws": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.3.tgz", + "integrity": "sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA==", + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/xregexp": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.4.1.tgz", + "integrity": "sha512-2u9HwfadaJaY9zHtRRnH6BY6CQVNQKkYm3oLtC9gJXXzfsbACg5X5e4EZZGVAH+YIfa+QA9lsFQTTe3HURF3ag==", + "dependencies": { + "@babel/runtime-corejs3": "^7.12.1" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "engines": { + "node": ">=4" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yup": { + "version": "0.32.11", + "resolved": "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz", + "integrity": "sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==", + "dependencies": { + "@babel/runtime": "^7.15.4", + "@types/lodash": "^4.14.175", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "nanoclone": "^0.2.1", + "property-expr": "^2.0.4", + "toposort": "^2.0.2" + }, + "engines": { + "node": ">=10" + } + } + } +} diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 0000000..1f56d7f --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,90 @@ +{ + "name": "frontend", + "version": "6.0.0", + "versionSystem": "6.0.0", + "nomeEmpresa": "Atendechat", + "private": true, + "dependencies": { + "@date-io/date-fns": "^2.14.0", + "@emotion/styled": "^11.10.6", + "@material-ui/core": "4.12.3", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "^4.0.0-alpha.56", + "@material-ui/pickers": "^3.3.10", + "@material-ui/styles": "^4.11.5", + "@mui/material": "^5.10.13", + "@mui/x-date-pickers": "^6.0.1", + "@testing-library/jest-dom": "^5.11.4", + "@testing-library/react": "^11.0.4", + "@testing-library/user-event": "^12.1.7", + "axios": "^0.21.1", + "bootstrap": "^5.2.3", + "chart.js": "^3.9.1", + "chartjs-plugin-datalabels": "^2.1.0", + "context": "^4.0.0", + "date-fns": "^2.16.1", + "emoji-mart": "^3.0.0", + "formik": "^2.2.0", + "formik-material-ui": "^3.0.1", + "gn-api-sdk-node": "^3.0.2", + "i18next": "^19.8.2", + "i18next-browser-languagedetector": "^6.0.1", + "jsonwebtoken": "^9.0.2", + "markdown-to-jsx": "^7.1.0", + "material-ui-color": "^1.2.0", + "mic-recorder-to-mp3": "^2.2.2", + "moment": "^2.29.1", + "qrcode.react": "^1.0.0", + "query-string": "^7.0.0", + "react": "^17.0.2", + "react-big-calendar": "^1.8.7", + "react-bootstrap": "^2.7.0", + "react-chartjs-2": "^4.3.1", + "react-color": "^2.19.3", + "react-copy-to-clipboard": "^5.1.0", + "react-csv": "^2.2.2", + "react-currency-format": "^1.1.0", + "react-dom": "^17.0.2", + "react-icons": "^4.4.0", + "react-input-mask": "^2.0.4", + "react-modal-image": "^2.5.0", + "react-number-format": "^4.6.4", + "react-qr-code": "^2.0.7", + "react-query": "^3.39.3", + "react-router-dom": "^5.2.0", + "react-scripts": "3.4.3", + "react-text-mask": "^5.5.0", + "react-toastify": "9.0.0", + "react-trello": "^2.2.11", + "recharts": "^2.0.2", + "socket.io-client": "^4.7.5", + "styled-components": "^5.3.5", + "text-mask-addons": "^3.8.0", + "use-debounce": "^7.0.0", + "use-sound": "^2.0.1", + "uuid": "^8.3.2", + "yup": "^0.32.8" + }, + "scripts": { + "start": "NODE_OPTIONS=--openssl-legacy-provider react-scripts start", + "build": "NODE_OPTIONS=--openssl-legacy-provider GENERATE_SOURCEMAP=false react-scripts build", + "builddev": "react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject" + }, + "eslintConfig": { + "extends": "react-app" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + } +} diff --git a/frontend/public/android-chrome-192x192.jpg b/frontend/public/android-chrome-192x192.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3b81d05a419022188fd12c3bf8b74d5c9e2375f9 GIT binary patch literal 112803 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 lu#8%wihQd-%yXMAI?VNNZ%G2-nm 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 lu#8%wihQd-%yXMAI?VNNZ%G2-nm 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 lu#8%wihQd-%yXMAI?VNNZ%G2-nm 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 lu#8%wihQd-%yXMAI?VNNZ%G2-nm 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 E4=0M*lK=n! literal 0 HcmV?d00001 diff --git a/frontend/public/index.html b/frontend/public/index.html new file mode 100644 index 0000000..ad3fa17 --- /dev/null +++ b/frontend/public/index.html @@ -0,0 +1,28 @@ + + + + Atendechat + + + + + + + + + + + + +
+ + diff --git a/frontend/public/manifest.json b/frontend/public/manifest.json new file mode 100644 index 0000000..fa8141d --- /dev/null +++ b/frontend/public/manifest.json @@ -0,0 +1,20 @@ +{ + "short_name": "Atendechat", + "name": "Atendechat", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/frontend/public/mstile-150x150.jpg b/frontend/public/mstile-150x150.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3b81d05a419022188fd12c3bf8b74d5c9e2375f9 GIT binary patch literal 112803 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 lu#8%wihQd-%yXMAI?VNNZ%G2-nm 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
H$>%0SCHV>$4^pfsY`_igOs?BNz$q%F&8c94CY z%W3zA3%5^8P9ab3fgWN*7?PU;y{nfAm78vJwy2k33C|B zKG}Ka1EEoAQPOhrV)(8b9=yUly?!jgs!O1dsGqpO$;nARy)8KJJX24FcbfAPLQ1Eo z)7H7RTxIG&?DiJ^>iRF#$Y|y7nBHq=1`r8Qoc$Fa1ftxnSdtGGoWQQr124Aub5tJ9 zI-e;V_Fl&8X43d3&Q?`D+cgvS(Lzo()iR3OUN&ge){Vdu!`H@NjF`Na6g8$wFa-9B`AcNwTE45qewWRSB~d${i zX?Gcn;{2jaEvK(<<<-cU&K8G4r%=HY>=b8fk~7PKl<|GB%8D4iga>Yg;_1aJs@t(Y9yqDz$M31T4axwk8BY z6Mb&skdePE(h_g)LCssEN&+>pr+EPT8ESB$;Zi^dQ$#^zRVznn+K4%s2B}{RxtuP8 zj%0{X?C}`T*y##I99>bxVHNDgBm@lcV`33@zkMQR)Gtd=^rN@ag=lZnhiR`Bp+GOB z4;bjhe1r&|xUtELWU0#-htVn)`A4rQl*4BPmOf$cR#Rd%45DR%%w4=_kev^&8$}CI zt#;5=EYMC+bK{XVe-#_i0!tS5@OIg0gY1D=&5uos4ny(r&%G*}g4ZOWj~87sSY5$Y z{X0$gRP3!97XwXHeukOAi1{*28Xw{nS}U7{p*qdEagcT+FY%es^OYeqDv1=9rqQkFF`{-U3D zTq#M2s)5;a?;JTCEfkv8#b}2yALUpH&}zg9T5*@0Xy&j+P{iAab~J;bV6u&Q*5n=b zwyWaFw>ZGaKgBd5s%PJdvjPSKQaxD^T916`$ZgBZQN`KWTwbABP>0g$v3vqR)g`y! z&tOyUh2T>Id!ON@hI2F2H`*-)HFbY@7+~&X*P>Gx$wH_ z>Q7_w+MAiAOR*-9+ukmR-?QZB?IvUP;t6Kl`ezZ~` z@?`^FESB^xJleUv*riqH?a$~uSLe=OI5C8#HKx|3m6gng~&foS#=g*jnwNOU8G++`0LMq_4{xaET->~fC9qskhoPsvcjHrAxeL^%T zsW$%Xi(@^GVgvJD-CFUq0WACqboJZ&fcFo#zD{fVq9bD}gP2xJ!*IA}L=C;?-f2@BCviS_)c~Su&*`}J~GKk zUYTusAi1@VHlrI4pi577qQUH#JB5!IdZl$Dh7+~`Pv#@QJN{n=A>Lxwd8%o*PzVlT zK#2yuX%u^dzWy@Fj5jf&bBCa3ix#y_`>j$d#)I8UZni?l{H3W}G$SJCfWkR5aZbSF zDhvMMGQITiEkGz{-$#=GVm2J{;K0COg-PbniR`zW>rVm`EYPi0&KwO!Qf#X4-j&R* z2g1eT>|DmtJUxR8^T7b)5g^rgV(U5P>-f^hO3*rg!AlF+b5I>)7vO}$u51z}YpC36 z1kX73FtSzRKDo4o4JYS;Dm4zgl!?YNSVI@dkLAWz*BUkp7s0MnND$T=c*Q-;j@6AM z=fp-0yv1BZW$k-L8T>}kB%Psr!K+7kWEw4;EK#t^a4&5FHoBXn^YF!b17daf>&Cp) z$b;HX4=PkibK#{P8Z5J@UNiTKrE^WWww)0mqye?P!+=GV-Wu{$!8>z~jq~OlO4wh^ zTudHEQ)l4C6d36)#b|0A#T=Zo%?-TU+mSTM7J)(gm^8xv%9wCUwl(YA(DGMGm`T1T z!Zoj5X!}yR(9mLWqFI^A@Tj8w{^M7*J}MzT@(8sHb8JSH$`-I*u}OXPKMv9FY!_qM z0XQ(~EP?m{c1K9Goex0_=__oLV^xPJg4iG*BdgK6Qya-)loF-D$|Xoa zXPvs{Wh9f$O?hMJ;b~anGt-F_Dv$q#zWhf7f3aA=kcnhQ?165(m}kIFJrQSII)YJy zZCp2O_Jj!uVtVb@hhR9R0skCXEdUpiE4}6du*5iJAHz}voa;*SANE%$It6gfoq`!+ zb9}E6!GiJipQ;c9HN!INc_j`qeUQc$RNILzpkx_DFv^tK_CV*MLd%RJ7>i*lEIOBO zYxDXna`t@g0&zlFc&TU)Xi?X z{gi>0CaS?z7|G3yb=oxC1ilAqdCXAUZ5Nqud;=d62UOwY?kUVi6gKXGd;t|=J3het zO%vhH?27`7VHE~P=I-q4Jy6#jDtZUJ%#MAxb0U0q0XU0hGTCrenNAd?=ngWD)ZwE6 zxwg=rGk~X^YXqSm5G~yUy$Z01--KMyMp!5T7o8+BA+w1g@3CtmrHs_vpMM(e8|Af* zcGRVh%cB^59N;MNOM4(ONYEbW0&uDueiypBjHFynnd&4mF_?H`>G%6Hoq_X4dboIz zQO^9py*%$>+oK+e+-y!OvH}o`!^l@v1!|=P4~|{1{m(ZcSXizq@DEl$cB z)7S=a8O3s=mA=c2vhhZVJ&=DRG&=D7qwemTFsc`A7-o_l=-iF?%nAE8SPQ-HQ^wLh zPxtH-fb1SSx=^?W8kWXMC83}-o}#FowH`Hq&M`0dXfoey9_5NUy=|Ls`PE9GrtWlz z%6op7g7POExA_NGE`K0s;ux_()>D;-4ngV@9b~ccrMan1ioJzJqt*`{?JC8Ns|Iax z%=QsQ(6q8z?ECnIm)`x|kmxe!I>>2zLn?EyN7nebLT6?xFo5=X-9T*O9KJiJ&^eWJ zM-CwM>{dh4Pq!hm%h}zvuGlx_;P1*HYEw9t06Kd<>8SW$0&Q#|-(U^uYPR2lRC_iD zSK*~ibgDt_y5i5JyzIrTftiMK!}JRZeE?zAM+|-PCqc}K5?*VMsxzN=l>$q|y~`qZ zpung-ck>n>w6{yXIN&_wVJP=mk8#kDQM8ZX*_HsQm5PKzpg6xw=m}4ozCaak*xWrVcx&)`}}N$u>gkX g){$^AH6_qxV8{Q { + const [locale, setLocale] = useState(); + + const prefersDarkMode = useMediaQuery("(prefers-color-scheme: dark)"); + const preferredTheme = window.localStorage.getItem("preferredTheme"); + const [mode, setMode] = useState(preferredTheme ? preferredTheme : prefersDarkMode ? "dark" : "light"); + + const colorMode = React.useMemo( + () => ({ + toggleColorMode: () => { + setMode((prevMode) => (prevMode === "light" ? "dark" : "light")); + }, + }), + [] + ); + + const theme = createTheme( + { + scrollbarStyles: { + "&::-webkit-scrollbar": { + width: '8px', + height: '8px', + }, + "&::-webkit-scrollbar-thumb": { + boxShadow: 'inset 0 0 6px rgba(0, 0, 0, 0.3)', + backgroundColor: "#682EE3", + }, + }, + scrollbarStylesSoft: { + "&::-webkit-scrollbar": { + width: "8px", + }, + "&::-webkit-scrollbar-thumb": { + backgroundColor: mode === "light" ? "#F3F3F3" : "#333333", + }, + }, + palette: { + type: mode, + primary: { main: mode === "light" ? "#682EE3" : "#FFFFFF" }, + textPrimary: mode === "light" ? "#682EE3" : "#FFFFFF", + borderPrimary: mode === "light" ? "#682EE3" : "#FFFFFF", + dark: { main: mode === "light" ? "#333333" : "#F3F3F3" }, + light: { main: mode === "light" ? "#F3F3F3" : "#333333" }, + tabHeaderBackground: mode === "light" ? "#EEE" : "#666", + optionsBackground: mode === "light" ? "#fafafa" : "#333", + options: mode === "light" ? "#fafafa" : "#666", + fontecor: mode === "light" ? "#128c7e" : "#fff", + fancyBackground: mode === "light" ? "#fafafa" : "#333", + bordabox: mode === "light" ? "#eee" : "#333", + newmessagebox: mode === "light" ? "#eee" : "#333", + inputdigita: mode === "light" ? "#fff" : "#666", + contactdrawer: mode === "light" ? "#fff" : "#666", + announcements: mode === "light" ? "#ededed" : "#333", + login: mode === "light" ? "#fff" : "#1C1C1C", + announcementspopover: mode === "light" ? "#fff" : "#666", + chatlist: mode === "light" ? "#eee" : "#666", + boxlist: mode === "light" ? "#ededed" : "#666", + boxchatlist: mode === "light" ? "#ededed" : "#333", + total: mode === "light" ? "#fff" : "#222", + messageIcons: mode === "light" ? "grey" : "#F3F3F3", + inputBackground: mode === "light" ? "#FFFFFF" : "#333", + barraSuperior: mode === "light" ? "linear-gradient(to right, #682EE3, #682EE3 , #682EE3)" : "#666", + boxticket: mode === "light" ? "#EEE" : "#666", + campaigntab: mode === "light" ? "#ededed" : "#666", + mediainput: mode === "light" ? "#ededed" : "#1c1c1c", + }, + mode, + }, + locale + ); + + useEffect(() => { + const i18nlocale = localStorage.getItem("i18nextLng"); + const browserLocale = + i18nlocale.substring(0, 2) + i18nlocale.substring(3, 5); + + if (browserLocale === "ptBR") { + setLocale(ptBR); + } + }, []); + + useEffect(() => { + window.localStorage.setItem("preferredTheme", mode); + }, [mode]); + + + + return ( + + + + + + + + + + ); +}; + +export default App; diff --git a/frontend/src/assets/chat_notify.mp3 b/frontend/src/assets/chat_notify.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..1e5ab73b88617a5f24475f9055a13c1b9c0735c6 GIT binary patch literal 19326 zcmeI2byyYM+wTY1zy>z3>F$v35(GERrn|cvL_$GfBV9_Tba%I;G%Ae(f{2KO0@CR| z@Vw{up7YP^zmL~B-q*}EYv!K#&i$FS=3X-kE++^AZp}nf8?Jw|Rmw+4%vTYGy)M;8}J>c-l@0Jop zhEkid?TT(hro3b7ys90LK`u{R>@r|)T6E@`eMGqrL!sT>-My0QMu0;1vp+5)K#X9n zjs2I9!85rvC$lqkkN%k>sQLw~x@Y#M^Grt8NWI>{T*Jp65TCh9DAsy_9Zp!V;92%` zyhatjrVTHCUb}kZ{*Y`0@*Fm7vRn8$B*QP+D+HqqK^R@O;#tMc@nF9|NSteZFNDt4 zhz&>Ig0+Y!1!jfM?o$TQZNwI|9cWK{*33L5qg;$0X82*4ibN#@5QWI$9mt@evug%Q zW6)fUOgwy})bi#2%c2&~(+)e04O91+d&P`KhjkzK8U&5~a>kBFCiF7oK6we0R0QbK zXmqosxg9gdh>JX*`OxBeRLB**-Tuj2k+QY6y9_>`%?M{s44SU{RLNzL_w0<7qM$ax zFGHO~-i2Sfr=X-kXgjDRR;SP851ct?AJ_=}E+--YmKbkJc?LDE}z&TX+@-`o&b)MTN~lx!TGv(KK(9rZeCP-NvWYTHY@qbbB^IS?5yEnN{+4N#|CN&N&r|ID7?%(Onh^HPU8d5yUMN9W>`fb0@*^O$1v0&zPJI~q_q z>3E9o)+GPxwd}KeWyz3}6{wi}f`IhsE0##eEBO50f`otgy`3(u>Q=rk&fK67cOH_c z!Ey4;w8msRU!GQVLxY-bNVb@&ZS2M9RT36+_VqTSkwTwbMj`|G-Nu@+O>K|`qm~_4 zb3BjKEunj1sIS@jEu|^EwAaNPK&G8C!gXMNxw>S?zW=zq{W##LQn-=RNU{LB=~IG#B!3 z8cct_Wv%UMrFy%66=Yzo#v1TIV%w3}Qd-+y359&Eh>wV=ZA7VRDINocA+q5Zi$t@^ z=(!xFJ2>z?5jj4Q5N>jGtHo_uoG1|HsSp6`6T~Hb6~lOKi}I#j-PSg$q*$LqovC`Q zd-t(MNk!=#+iI*#wqHY|<|4Zj`+?H#x(h>G!(+(0gRPH1HLEp0URRl;@g@5&>b;TZ zUHit-*6B(CR2od`2u55TF)8YNJG&|tiYDf8aZMWel4#EcO)(PCwJCFGJd(B^qAMvh z`B_Ltu_`S-B)*LyYA}W_EO@DR6=f0)fr8*841tODOQEzud&AM%p#2I?C5lyIy(YkS zG_To3x-|u?<1Xo?M@hkPLUV#PBW1=3;QK@5$mc8P&5ABsYr!2nABeU;n7vBL_I2^| z6THT;yd|WHz({rM=eAk}=usb8=79n7K}r7hWdtx%%7})o3AprB!OiM838PQF6P-Np zdp-AxGLUq%y<9vK+g9dc}|OS585iPGMMdk_=mNA z0-C)7oTT@y7+twsSC&ogJ$aqA(s2Kr#IH-UX=QsW7jzdEULSkBR*^T;%DtN^itPBh za=S=u?CC;kAmQp|Ck4tR#`zv@_d5cPvzA3X+_Qrk{QU#FvT8>emv$U}EWV*YUZVvT zMIb8&=QNPpH}w$!P*6qyP%z9=oQB|;zOh!Kl2eMrfh##Dg0(O5lz)E+D>@-^lpdMirf}jVSfDruPI5Bjkv~R19P{aY?sPpiQ zoQB^0JIXjchSvz5I7A|`&nrR%Lk}?d@Qg7W4Hf7xeMfsh%eu-(k4_D<0!8MIe$mMR6?ubwFO%W7Gp)Cym|~{@PlSyJL*yPwL*oVI_qs8 zz2Q@Lr*#Q0-B0$pgywNik$$^K#q8}**P}Nv+VliaU_&~1eQIpIAXErJ?^&NWWh_~5 zdhe?{u@XbjQN3W?WVmUbr~>!5e;SU?oM^m~!dRz;V|)1A5TXU(fhZP=mn)@rVRN^mIYgsd#o*n(f@+s1bs64&di4AtJ<) zztOPZf~+QAFW3?+;|@KmCF43PA8C(aKmd_#7mu)HiM_tnDXkP*#J+c4sdP9`qoOD% zD0rDON4we5G{WR^+B_MHBHe+e>lpRis(B-cXmA7viy~B_G#aYslD{ZQ>Rjv6?CMGtjLx`^6%l-oQ>h?Eonm=OTa=NzI{)Yp$FM@XE?A0xz!$+?Q! zQx^)!SwZFW#OMg>3IHB>-ApN^^Rcve*y8P;n`HD@a{v3dP_ z8w5U+WAGZ(;75V@FED;+j-aZ~e30s((wUXSe2xoq<~gP)Opt72$Q!2KGu%4OW8Iq% zNK%MZB{V*Q1m#{d8aR_%I=4S7A$$um&7~G~YCTpn(^;>8c#~64cC#WT7rq9`jSM$;E;ngerggi4V-gkNT*CT_T9NU|W9{vd zN=G*1Q)|odt+LUCs)K?`tw)O@j;RHrhigC#pe_$!o^K2Pj&8IesB1f&Awy)Qv;IG#bKl^j(GfjUbJMFfG$@-X3@ z)VjK!@I38t1s5)Xuy9&Ka;s=fT^1|_oEoL|lk1BFhw9l#8;%{!VeAxQJ-PddN^A_*;`1Lc0gN&?b)`t*hBxe$0=W-_GwL^ObUv)ox%r>U*VHdUf4mFSsz}QIbjNFbp4VmiJe(+7oJb;0 z<0O=oP-3yZ(2IlE^FcV)m<$0)jR0$ey&Q8*ltlh!MIS|U5VxbT&@@MTzAzYcONbtU zmgevp-8B#Oww22V10)Ng^6ec60=<|u15`esp*>@|^)AP@o~-t6n3~!5veL(;28?O; zZvE+vDKrO@)nc3+?`+yfVpTHY2c8jf8}k-ETr5xKeUdaY4{i2l9_lK*dYx7^8||o2 zTDfc20iKl$Y_)O6j(zwtjF{k!Ju)h!q>zMG)HDsAn5CB4k01*=Pk66&tL-> zdjgY93BCEUF;-$CNlK)|=qbVPsbO}jL?2~Bf}sLRO}LXIXu34j@!q2e6KF6j#BlyT zIa)Zq2kkKIJFSA_Qvg8^K?MewpaOS!I$VQ66sTDpfYl^9dAbk=9x4VH-!!VyufrpN zp51c^eMA7Y6>6%DJPG2P6W7znn@(Of~PxfzD<*nP8(PEJ_VRt?N6c6|yxWdsf4EllNn<*+{>ZP&8PNKZx2 z-8~P)-yezSO$G?yXq;W00MLS9kPW2=Ft+(i%0MVk)nzWtUh4!)M-;<{GEi_X!imQO zN}j>4@X>*Vpk!kyzqpX+c*;ENhRVBFpmRQCpG< zX#&j|+rDChVb&aa**w|EIg?7m+7vCN7y|pF`-k>t0mn# ziiU}y*$CAT9c|1Tm)P)>N<2ioJ3B#x=A}~u2uF-a$6{G#ymUJS%NNqF&*v^Xz$KYn z;$d%SpdeIDW;8`-HrD8AoA6NknEU#!^KP=xFrNdKRkC(;vDCi z6wCvA-ed}RT8{}K=T(Th|7ztT=~XFuJ$rlcRRU2_^*9Mpi0mR)y<;bkJr@CSX_w;r z1i&O+lJYRzSwqB)%EYcAYV*`|)@fFpFRyQER9~;Pf%staMMa~~tiN(qMN5H8VzLeQ z!l}u})0;;VIeh#ht~`~9AFo2!2aeaVV{FDDkGEx+iE*qy>sqU0>in~2#~0OJQO91x z+$c0gytJfgs953gC*xNx!Jq=#HHL!=mcE|RSEk|lR&d*RleOyaXD+ya!S1BaaH=5o|)^cMQg)+7LgBW zqk!6p@yUGc<&u8~Y3;>WtHo2}`}Tp8KbrVuB&n=uQ6 zfI&}vnz07E2GJ{?JF}T;7S}PVeoJ9t+DizDcir?+cy=d#{gx0b3K|ESJii$wjMtJ} z^CnY(-18#@jz)o1faxVPiZ4ec@sVUuO?e9c-5uvyO+Jolk&;TfiuZ#T+Lj6=NEuN^IE@H-`e#eF ze$SUr8SIxS-;7{ z4x@fdXmxfx!JjztR7no2+Hgp-Bi=gsh55If2VQqDpw#s%>#T$tnw@M$+}yK7)^sr| z&C0$k;6Y`P1IO;-e9;e?I+PbyrR6`M9Gx$?YliCHe&;GSZwf31$g!9KH05T!E_kwx z1)CusrtGU#e&v(M$=OET4ASN=E~B8l1Pp61)W@tR@w2O2PeBm_`si0}J-@kR{}!az z6`CLSy#Mn3(v=zHlNscmWX_D@na7*euZK$;b{i|@8%DXdrDg_2XvS5kmaDpQwvPvJ zv4TCEjJ3mM*EQ;$oG+%4kJ~*SYY z%@Un@trz};-#T!EsG}+3bozemNIcC~tIFTzl63PvD9<6Y$#|$Uv4+v@glfC?!v2?( zJdmX7x}huKWU#_cQw@|r!!KhSQ{0raPbv{a3TDGjF9POExa0@-6AWhs>EX$dw0sF^ zW7@3*zU0jwJ>3^LEr`@HOyZ z<0Q#wMf4Y;Bz^-Qo?hoPzl?FoyD&nbY=_D4rIfOpw6#{_{&*VL>E!%@M}W@9Gs}h9 zbudo-)lhCex_&5w<5;aA5Sm+`6K;ZG^Bw~gf{9A)5)@I-6X-JV zIdziM#4jr0Mf=q*7@BSVE7VpXGrE!%cosHK{cCIOj>CW=g z9Q0YW(fnSm&VR%8yT(6Ho!Mvi@DJ!qAIyb&)b8urJkJQQP)NSA9E)y}dKVX2QX4Ed z%HbHEStl}1jb3Tx`ZHBUQYG{m+_D$l6OU|K)+7{;mW@9kp+VWG+{V04T|YgS+D(#m zM;_#<4Ui!AsG#<*3<=7K2*W;Lg=mJQLcc8AY&b$og1FpFob$Ld*DQqqK9-yVsaG_Q zzrG=jUD6#99WkzEo%Y6S8xC{QdnX#u7ghC%Xdo(`zfeI47pH>cfk>wwSE}elHKp(s zm{9J8p7`Nhy2!lwz??I13 z@z3(uDiA=(r=D=a_9pIPR*I6rqS5x@{uylwf495MRIP0J>M{-Ps;^yq*YdxlWy-yh z$FI?E^>Q8-)ye8$@JkJusPK#Q4|^k5jJ4iWa7!o&fl(83KU{JZHCZ$A?rU;@l3mo` z{1pO9iD1UONn7ToGcsMdcWlex{}$f#!9hvJ6NB*~8^iiZr`KIeZ1ErDn&s^mk-@5Bp#unrq1ZbmwXw*) zus5pvb$Hmkd}}sb*nH=*%90Q_BK&i;rZ*UJOceufR1RYW)7QSE1ZVmcjM?{x0B(fb zM3ZzJ&Z3ZEUCZ+DfD!vH`Ap}93*5?OT9C5cjprTj4Y>^~)~EfS5_IlEXR)Wh4) z&UAG?loO3ZaAvu8b!A<)FjQF<2&bMsL;q0XUv+@%X`EBo4_tU-I z;a@?ulO_a1;nPl-BE8~~8hz?>*HkZ9w>r-huuMRSSC8Po z6NRQf$)yP83Uy57b@eKyXn^bd^2XrnYk>P!6FW(ivv6LpB{CXcEVD=o7j!wc`Wq(- z(DX0d@iQ^LFmGn}VO>nTCB%<7jMJUodyt1AvI_QG1p~Ou&73^j>aYa_1MH?hB%lVD z8nfg6wdj4ZBiE_;AwiE{6${ts0~QA{h0(@GQzNyitvg+A`Mqd*!aFq*Em2w9-5F=` zm}^(QoswE;g9a5&KOUoa0{{dSxwLUEGD-V&y~2@C3@b7`gwpIGo|G)gkS4vSY7_Ox zBPu+ll!Kri@o{0r^ltCZUyA!wP-xM?S65pZ#S+;%zd`50gJ zeoTR)<1d?D>vpIR-O+;L#nu!w1jsUMFIVkB2S?_GMltLj9y5$ZKZuHTdyLXL9#;Wu zX^kPTL}7>U8^XHcBajNoWEW&S(9kv`HX?dGX_41G;cLeN_s5cSh6imXhr-EI`8W0M z%xWj1>V<~i(Qc=QHyM3$XhkY+rQXAWN z#)m#JW5AZ*%sIhH&rU+{O|^Zg+4$`DWUu9lywDN-axJepKbLc_tcQBy+(F38pfAI8 z=$ObWx-UU=RPzEu;%`fE+lN}X-X|&R_PI&DKBCC45RK{RSY2)0e7xFRN7u~ zpO3_zXg3p(G!-N&Qm>)|LD%-%)49{hA7=%iZ2la__j>lz_QoHFz3l4FEp6PZ2udL{ zsg|Tk=un7vhF;sf&76G;+9*57OOl_7@Ac#w1R(1XTmwKGHCbv^Gpe+AEHv0v7bopJH$c4Yf$XQf_YrrV;AM%LEi@QdBG)R9oDjdE@zl zk%ReGcl4_7tb^aN`KRUVYit|1+;uT5TW}2;H${;zeu)Jkk-MT_g06#pky*Z@s0J## zU>1#Y?!#p|Q0;8HTS75lG?k#67u~qV6fDwRnWkA))>k)5otU`e}zQsX?vMCjD z(cK^)P>s)=q^{H#q*W@xTGRp$o2#9=arlg*K8(Gy9aq$M0p>Efso{XP6b8$XRE&-d zOK5g42$4r03>#EPgbcl=SaC=RoqD9?>~2qyiS&)ia=hNIj84yLgD@jC9D3eeyEKZF zMN}1Dwj!k(U-qp`eRB9PCv{hRxuQBDW*O#DrsZZnznMRcBa7QfTQbi<2xWa;F!!p_ z&P~l|fM&4DRIgx(^3*&fW;b=Me_SScpsUjFRUIYE+$Dqiwr8A|_Q-0N% zD~&}iQr&FUh^S~znb&G_UQ?1>s$6~y)z-^S^8}Y`;-w}F`mwYv1GJZuPjk|~SDJ_H zm&m&6E$! zk}6DG!7Ll%R`uMAGk?lo_xi+**RN+c^s97`Z)4SGpZm2WK8Znb<=;H+57sCWvC8a@ z&DP6KMJ()wV&G7cbmVou?NahEjm&@hEa8RuAZ5t2A|XN*7kF%nD$}ENdE&EXm;qV7 zupVV5o9*|_gu>L0^UQ9FmnhP%Vqw~TEB?E3QOisSlK3i>#UVN%J4Jw*ixSe7;>_jG zM$8e-@Ti!uk)c3Qn!aE{GRD*|NU(&NHIuGV>L%qY-Fcu=MiZPL+OD0-+ zMg(@7+j7>7F1Lgx!w$)WUnBUn5ALqsq(U+PHk$=>0G+3g7O?ES=?}pZCRyrznbXU& zJ|wJowi;2A?l3(5rsp`2Yv8El-9lK>BhfQZ)Igy>5_L5pk?>|TKldeQ(vf`fZRBNt z;^*{yX5uLt?ui&`inus<4rWHUC6&dK=qOuRb~5l*nK+?Y|Erz|!>zpD`p0CtA(^JD zQ-K@W!1aKkOp6Q>;db!@oShCIg){mc%^b zEa;4uu3TRQOgvSfB0cslS}$mzNTA9?Ry?6ij!d{*Mh5lk02w9PaU}7h6G?@$pqP>- z#+SBJ(%>Wvmjm3H$JUP3+wL2!#g$fYwF&aNM^Mf6?IZ3P4pnJ2dBNM!Hx(5`RF_zg z%cZB-AI8ob1&+no?*Gs}jC%;P$?^0n{r(n%P*6rBeVwNm8>2F1%zTD?&W0knxcVjY z5r2suEJk@8+cVzDI9y-TAkz$@I~98-UvtQAB9pH<@tIhH(=%ZNVtkL$L`<$a1-O%f zyxPCoU*Qq^r^kAPKwYGkQDPAAGIe7kA!h1V-bX{DkA-2`0+zNY5ER`$#~BQyt_f|w z*d21SP*E};Q#(82Wz>pa!sXSDebkCfjWVnL757Ge6~$?~LBNLl@nr zjZaKkrTFzqoVPo{eA4eoOSWI2Mb2qMnh%02$a{_}L?1bUTre^grx0ie0c{Dc6(Bz6 z*>W&r;^P0bGPUfyZ&>(1|3ccz(og{_1O1tGK>@!OJuwA_OvF!JSiD$JsM}{cmgfHI z$+$Kqk3Bf=nZgP|E68oG+2R8EnaWdP`Q#$^SU;M9mrZeW`(_M8@&4_O;H7?%b(5Q8 zZ}&j{B4`bD`}K;+{aQWkpW}Ow$bWXjTH5}<09E`ec3X$eBSXxcJApo)X9m5PqhM=O zIIQelFUYO$g%C6nm_z(4!v5upiVfQ?67rFO^!}TW-oIqGgyiw}NdW}f&9`CHUMO($ zV;K-b1;96-i9rY$5D$RHGe}wBVp+5q{Z$$hh^qb)P5w5?4{s;`e5%HJMZ-Vnj Oxc(CQBQX5QBK{ZOzUQU@ literal 0 HcmV?d00001 diff --git a/frontend/src/assets/dialogflow.png b/frontend/src/assets/dialogflow.png new file mode 100644 index 0000000000000000000000000000000000000000..2b765c5ad23866785484e85b77f511ab0b7a0103 GIT binary patch literal 3931 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 F`ahJ9f=&Pc literal 0 HcmV?d00001 diff --git a/frontend/src/assets/logo.png b/frontend/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..254ef9a961e74b97d4f4fda15009dc4c5e981e0a GIT binary patch literal 32826 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 literal 0 HcmV?d00001 diff --git a/frontend/src/assets/n8n.png b/frontend/src/assets/n8n.png new file mode 100644 index 0000000000000000000000000000000000000000..3acc57819eba3a98cb14daeab07023fedcf6fadc GIT binary patch literal 251556 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

NuG6`vcnUIwq0c77}be3ke} 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 literal 0 HcmV?d00001 diff --git a/frontend/src/assets/sound.mp3 b/frontend/src/assets/sound.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..bd770d8c56b1ad93480e16c89ee32c3d134ef8b9 GIT binary patch literal 52244 zcmW*RWmr^A8wc>ES-Lxyr8}ivI$S!WC6?|M73uB;mPTrUC6q2f=?3ZUZY32Jczxcv z&d2lN%=NqOd;Vu;p8llv12E=n@h&hU`xTKruR>F^dnj1Kw{jYuCCcVR60m5Gq;urS z6_aMcW@Q0kkqkd*Ov9W9nPH2OBCO~m6|ehAWD7gIX?Nt(S!s7bY_<#q3O_%rxMx+A zPm|!1C`bm2irsvNvStN$W0Jhpc`HE7q4j)Q;$alPvov6;EEQ{cm)NxIpzKQ$D<_#a z1wli9154LtKC|koPphX|wkP4x@wy6hz*_!89I#01PFzmD35jGSP!i({i=_vPX?-i6 zHOpXGLymf;x+DlB`RT(YN?!0~XuCy#Udd;u5-)3id$}01+`_-VUw(U=z)~m+ekbf8 zbzpOtPvm7f+3^m28R|_QT^3b49P!D~_Jy0y5lbhxf-5X}_(vd{kav@pEZ+>aP5Qj6 zh6t|4U|C|kgKwN{q@EZ!vp!A=gLDDfM1G+`3C}QK=bX=)AC(Mn>edOF(Ik=2{veHG3QR8A^sw|^t6?K90-harf_*Q7lxu$b$ zxQh9?fkqUVih0Ln?oWT<{mc z673b8k^)N7TAjG6yEQ~FH6w;7_mY;`<_7X64E*{@xO(G2k%|g9+TSxE;exzF||xnXRiO>!=9Dg*h2CsWsYn}nBqQrulwN{DFZr$<@BSnt+@ z_QD{ldfpcjBm%@Cf>5pZq6W01VkMYMidyPfVa!{NO|2lNM%Gs5?JerV`i_WIUthY{ z!F?%m78jAr^;wKtq?89l#lR=O_fe;*=WCg& z*_bOW;vxPrELOEt#AuayQ_x!9l@Q*___MHQn1k^Tt^!FU%Rrc7wAl6E76+y1om_NH z(Gq}nuU{fs1@yTBMXF9tdro#n_7X0p-`ESowa@JLukb$O)0%XprG}-`(8LbYB*ORx zhZR_q5!LqjBA-cJ-qrY4gfx0OTWaV z!7H!E=AY8_mP&mOz&tt_&2Jd5fJ!E7e>T@!utgBM$2RuA_hu?`qSsR}6Bz)ZXoKXcJcDQW2e6>YFOS#SYI`~p z>m)_-_&rZgo+x~F=BIm?A^`Jsr=D@Rb(xI81U^lfJ)zY-%JqE&tP&F-Q0~S(Q;yN-eE#GZA@0Cm(!{mLcKhu2Ibfi>d z2<0s*j)I@Gzfhv^C()yU+L8=k9QizXHG*D&zC4*#XWSOhlA0t|idC0aeeg+3 zs_R3q!@~gN7AlEiY`w>04~k*orXdcE3nf9vN7K(r4W%&wn3uZklve2(hHN@xu7wAg z&NcJSirxHw9l|heufQdC^B!ZC+8S6-4(bOiLaa%I5-ip2sW`MlwzKIR*hHCX9_5HO zs*WFmcN&&qxdcArEa0LEd3$m%^U*(=&G}VpAV1q-NHFWW^>d}F5OYW zl;|}?MqGwZm@OPZze(@?uUu!xD}|+U?$gO((%&T|jI%!FrakJR;L-YgVb8D}Z|)DH z`tu%e-G+D!?*5{U{m5NBCL&xj5h4W;(b>|(Ct{RAnHo=FecuBj6Eqa+on@3G62L2{} z!U>c`vEO=5c{Z(1c0Sfjyh2gA0RdO_`* zSHcTRcArFlEt$P-3+km^HVtVKpE#UwSmz}X=sK_e&~E-H^Z3Kp_WSs#6>V_F9 z{Bf^y9DU-Goaa3%n7+C=yB!^A6P8m;TCXb-hIl}69$CT%(1RJo+Jq~Ni#Y*C=?;8jb z7{rBPhSu&H;F)Kp17)Rgxp^pcX3<KbkFp! zulvh&6O=gbrmV3|8hS>(ZcB2vS0>4alCJy+4FI6lG?8G4%^cb#3~%`U5JGfXC$tM$ zRYmiCl1(cv2@@)^%R!4oN6&`zM*ht=;Ls?XKEqfj|Az;BW>-`lAEu~{8&)cp z2*6EOoM!6hzqAmtqstH`7dI}YU>-l^7$?Dm=DbkKE7AJiIu3y;_KYKE)&WV|E8*4LEv>)7bJ(RglFX4qPoIMo2927Yh za=?WXeR!6+zEuAB{)ujLyzX#^huihx3NNK z+4iTJuY$Sr^3=7i_-6OPDPyyWAz#g#y+<#kzyFD`yZSE~t=G1ZJvurY-0NPFz*HTg zV`KN+h3L%IYq}|oxdku7AqUcAbnuuW;Vraq3|tJwFUYCaJ+FOJ7PVT?Sf~~FtExb` zCS_biN_)+s`c+eMJgm><6G6RJ1GTs+4J8wl++W#T{Ru^D@(C~fN!$2q)3P{J18*x8 zx6ogwGP0FjsbV89>Yr$)zCKlxUM{fp&mYIS89zPUgnfH@;7yIvbQ@NrJQ=NgYI$V! z+<88E`LsD`ltOs}XCSb`bWD@GO`2tX`m*M&xcT2?da7u<0f3N&;DXmmRxx$axx)Vf zD?JOt|Ao-9<37t5jE16jKI0T$kALm96x*3Cd?KixmM0n ziPTPuqzTVsu>>Jm&u}6YHM!Et-ZHF8x0B0v5%Ve-8yI z7!rlK=Y)$97K_8;uz$qtl}Kf#)JGN(OrXh^j&5-o=PoWRZJRjaz;0kOip~NMS_(x^ zE=H(2=_^m)X{0%*$hSz{==z7;GCxM~od289g9cY_$kUT@&2N=V0N}&#JeUCf?@3<| ztqE%M;v7U8Dx&D5iin1L z#`v_+hc2xTGJ)8`n|26U)GLPLa(iNW6D1)wg`DFsWjJJ5As(=we*fyCJ^wtXv)W?q ztRqB5J1!I%qdIcY>Ri3DQ59&^I_;PrX~Z}cbFL}#h_5M}Nt5%Fjl#?6V$9HL=o(u| zI{5jo-&J`3AOHa7r{e%VM{K4Lv(Zcp069j#k`hXZqh~8r#X7WjN{I)I*)sXvyVisE zKOyR{EVOpflbsaG=cLykhZ-V7NNDST}7&G-rn<5<7xx_DZ|fpZFby)ofIttlq{@n zKBgEpZ>2jgp05+x#(vgyVcpS2PrxTV7yjS^esQl3wjoQV;;Ux^g7ghTe%dz5czQmi zurNPW&~XxoN&?df0U!m_c!>86M}0G3JI0ze0-_LAdYs%}ISe>!ds#cKq?b+g(#4}Q zy70E}8a|vSMN5VRatZL>4-!zZ(4m{x>*!2A8qTe=qbt^I$B2x{Jp25DSdt571C~07 zC{>w*K{HfBP(jt%f5o)`vjJVGk5g+|pK)J^kgrWzXVk!O?-m?|51;)y&m=ITIML^s zq2Svl)sBU2niWg&-HFzN+cv7<(259Td+L!?Ik z69R|LV^MMyy|p6?=h?SePkw#>JJ9N&)${)Em`vsYElp@;Po{}dswJm%LMuDjgn3b6 zP(yiN(Co^4(Ts*&CL%U$7gEfJXrBdU9gn-GABRs~eIK5puX~YdX4C@AvjR5}-$`gS zlgXc!zP&|>9^c^LJpCEc2OU4JL0X4*bBFDOmC%MEic_r>YaIX>sti#R?04~Z58^?T zNk4zApWOViU!NEx=Sd?HM&-yB;i6Zb1)494oVgOLh(*`F6aM?`>1~@?zJZ+*jp_G4 z%g;Bi91t%1*)4Kig7LblzV&9i@}!FBxkx!bhvSb=LPNRiQKN#aEF3OcG@8CL#NrQx zf@hDUx0p&_gAyJGL!Mr0?yZX5NsUIXlxqVdJPw_#MR{Lo~RsP zp;0MAAcRwO;YlZPW;TqpFj-s_lYmCZ?^3z1UtD>to)#V~YlQGKhLe$Y&F9?f0+8zFAMa&vXm<^XKt<_Q|}*bzpKXSt1o4 z5z&7_s$p~6#9%<69l94I%$nHAx+-k6a@pq8$1NUiP&kJgm1m1s|H7@;o7I51p zIabE3emc6m=X&+syCy?8Vxb0G*PE&Zz{_a}vVA1`Kg}@+9y|15wU`s5X#+a%0O9k>%^qFbo#^Ct)FE^N0LqxqMV= zs7Fj%VaIqiUBbp^JJumU4FxN z#oX$#*%wqF@$}?Sa1y!-Kd~!=)C>I%h?PeFh}IhfA$g+l!BAxrrS@*s!Wn#OZuq)Z zzj&zepO9;q;nXHe(OV_FOvc^$`R{tIZ}`g!EP}h_jj<@ueG&Ho>8__H-BIU<84_PE zJWNyw=mKV*uhQ#4Q``5~r5-C!rzC{RxLs`$$k)1lZU31pef3=@1J6I__EQ#cw?bj^ zH`xaWM=MW#;!@dxSJ4eIssBRo(IR3wnjTGEZ29gketKU#Z?C;7EHh?<_P(UD498O9tg0Pv z*3bZ*N*c9TipeORK#q=>*P$PgV3ec|c(^{m!Og=0v}MB-<^+SZNsp{(87;nx*RNo9 z&lX=`9D&YO9JDjNdO&1X^Y=~Q)+45Vz<&jO;<~SMFYw)5%`5A;17}{p$1w}S#CdvX zf9JpyXyWn;3t)h$virO_LO?0P%jk0$cchK+IknyFbg;?BGjX#oAvbg6H*?=LH#f%= ziH!089-23DCsFGYomI5Np3rM*m+4y_O_2JE8E87Zi4#LZM|19PdY9YPxuc{ALzif7 z^n;lQ{U?-&W&|{4CYpLPYM!?{zou8eY57xhx*p(PBjO^}nojfas}Xn8?FYN(U0erW zAMfZdKmA(h|M+Hfo(u5rYx!<`5QY;ul~dSIa6+856GTV`(u0d0DjDes%o+P0`PVM@ zE8>+W-M#&bNd1o)%>nCZe^KGVUsQcHad*we_;=wyMwg8fDJ?I>M(*VgC1cQsgS{>bgTjHloWP06( z$#v6`1pL!Hfze&sjRlfuJR)if1+rb-IS9Q5s}C z8qm?bNjP>8CtX+w&!v?&8+Z)-lp~7I$eJ z?#`GswvcWZP$J`-v887=Q$>P{^YoWe!+|Nrk zZ=U2J*?&R}5wp`MhL2N0cyBsO!&Zn*t6sDPCq9?upKCPBO^~jAk?DZGHGA**dBhM= zILvonm8mdiuTTTWmpwz8@+6FzHdGkGn#)~iDw$%|ir|QNBKJi$S4#a@rS_mvb*uL; zImSzZ^VIiy=P5;9^9yrmr$u9kvp7guab?0n1agdGeE8yOBHyXpy7O}SkuZPToLr6B zbfPU{C%FXtvFWB}5z_uZadHRwy_Qpd1IL|sc=>QxBeL&m(w*s3^lGjd$wKmmZ)KrM z8ed#_e`cCH2Q-oo=^mf=C;$%7PL_w`W~D2JYwE#yL^u=(dtAy&gsxmvz)svoV8hbs zr67g`5sHjuZYehT2`#paN*FjA`ZK#qvF|EHLpgsWF09~=43{yJl`gJIvfI1=FkgFOn9J+^}k%U`7@}VmwGv-5V+9QnxpPsP3>aHdM8mabh(Z-3%5|8QpOIh0SA^gNJ$k zx;Xp2G5IsM+0BZx{_5Je15{-}5`U{s_fAsc(+ip@SjcnK5V@)Twlxr{5 zXhh8a-{pQ{EXzGm679{dQgrWxtP_!U3jfVmVROLJ?K1 zUc080JopWXpig79v(C*|?>`N~`(Kzs!>GhFmZ`OToy7-H#YpzbvoYu2O9it#Dgja% z{vQ}83|t}{0vA^jjq0PnD+J4F?`%GSF8<^M{Yj8^^1_aGa8fxSi#!TlTPTHkZs+m@ z;ml0V-Tzr+mymfGqV?ub#(O9ID!0<=^rhwZwPfFbnxEendcQQDi|2blI*`w(cj8^`c2c2Rm4jB-Ro6RLmq#iu$vx9^N)eF{vq+?fe&f4zr)DZ=g4jy> zz{(F|`^y@#C&~w>D-NBRZ?u34*or?%0_M)b?X9?{dCe_3J84uBdq3Hq%o)^v)q%fJ z>4)+(Z}pq3C|e5s!+F>~8>Dk+BIU{Iw${&TpaB)!58aXJ{@;T~X31o{k6S^S#uf+C)tg5%w{I9;D%dv{i zq`6zp{6EXxp)JJ|QWD9o^bz)eGXDt`>OVs4IqKtuAC6mEJE=7b8yna5vGek6xJkDW zZv|Z$vgTB)_{cUSj90JyrOie)U9Qptr{9&oOz^Fl|6p|yOF5A~=Q6LlR?fy5<+vKI z)z0>iWM(kgHIPNZ{&-t};wqaSZQvGsx;bvlp5;v!KWq+(!6vFQ#?rt}U^<{okhTbCq@$)i|@qprzrPUY%!%*$g zS~*Gl^RLTu41)OKbFo%eB;v6PXzszx-wmKnsV;&^@})qLOG013s;;XbV_o)LvQblgzsil78m@SEN#l3c|Ve1f4aPY#mU&2@Y}OG z8;h+d2eKHRqdVUN9jKkgqB1L@pqNO{+DAMTfb;YBy17P9qV=%240?%ys`EG#wXy2K zrFQp^0cU@{mS~x0?g@F)A(T%cc%p7{_0pNmTUdPt0!4D;ueB*d5;r#(1JU`KQshMC zh3Osy`Ut!B{aL9?er2C)>wrE3nrXQI1JJoxR3zdrwVDZ9Ziv)LqWF3Y)+Ogm6u!7j^~0 z)9!RA5@kL;R5|CRix;kBosAoe?$e!pY$`#hT>>k=t;QxsS(w5Gus8Z**kl)*xw{s? zxH93rS4_pWZ&X@ZYs@5W*%>xAF!4XXUdFQ^Wa!$LIGmH8!Oe~s zydp?AS|k@Z(qi&3Z4u%ZbI7QR?7 z?P|eVH(yrD&G>96ZB@z_jnlQLh0wbx51&?bP1aV?5He(2LN*U|m~Matn2JH6BT{EL zmBt9_dDFeq{9-y6pZt!pSMf?Z>1zDFzx5R!eAot>rc2K^_rSLrlf85y0u5u5)yTGU2up}u?mWfn_gGFRj! z%AYns!2QG3)g6z;ZC^qfZ+PKq-N&`OMh9y7+gHxNR!Ti(=tli_%m!u!--GsloJVE! zMSTsRU+dT1WcFF7I86`u{d;DX+$6=$V)i!3%}Z$4V{Qd2N%H`^`O{y! zi~fSKfHe-)bzH>*;}4+?bk$f5xs1~X*e8LpNQX^X$#R&%|kLGJ!OyVW^Qouqu4iZeMy?k`Xxepn>Sh5XQKN=y~qgd!#Z@edeN)Pr_sH8|AeBI$&u=*jECpKQDi0irr zao9hldtXMp&t8?WP@38f-FIvJ{N}y6C%0v1?e-XXCf6ZF`*`!1Y%OyMh3oPnZ5%!+ z*PC09r2p@nUPi3+0*MH_k`nN~mZ0_LnfhZ&%(q0n2_U&VSQeBrZ&>xY5yVTWn*At+ zC)3y5nDvXT%)^|1pFMXzmc^3nDJfvwHnj|r2)5xEwNr`R(*+5XeR=msm^`)+(IHy| zk*S)qrf9(O)W8(PC8(wHDyj7|^XvbVu9KQU(ALZzj$8lBgF}wpIN#hsDq4vEfa`jn z-otNe2nWK7uU%s%QvC*FRPHwKm3SNogQ6f zkiXR``W?TnE?r6MFt)%gFwsjmVZJEfZ<#v=p6|+Wl8xf!%n9N!_DZjx>}(2p?8U^uohQmfq_jd)VcL@&Adb9X5`5F>m_tQIcZyHC@0s0{pvb)uis1`%2i4-Dn zX{W$LG~4~TxY*$FojrB)GK%v9Q4C*!9Tg2;5QO2tmqcYv+Ugy(FB;h9;@*ANSr}>I za!cbKpIQE|hE7A5E`TJ2b*p$w-8(jAd8P#89bXPrW->Q|7S4@Jq@?(YyKkj_XPmry z7ulLqotybbz~0s<+3dywj&JfP%APTRkJ_BU*~J4^zQ4cehm%5ES}Z z^RB@37X?n_{(_Hqji_T*K0N~&io85lkIF44)A6+EXg6SrOFTh&mkTnpc#w#i#&!q8V-r?v#@1aoEKuCA@j)A$TeJ?Gw?iJT2H({g6cKUni|=Iiv%J#84INzvJ* zcwB$h&@QeaH1P5*N#1&no;MZ>lbrExrQ?|8gW`$byF=Pp9z{afdAl9KOUn>nq>;cH zeAK*)ep5e#rv;Zf*U3P&H@W|X=37k{ug40<6KJ4{qr_%ard0=^2>Z!Aixi_Oun-5) z+M?^VWfYl>lgE-Jr^Uld$@sp~Meca*Rm*XjmA~Tqg)jGW{)+yZ!yRwLV_|C3LMR*l z=0k3EnQz@!zW)hb11zeD@rdM-!dDbPMit1q6rN?3Qsv~A{55=nJcZq-W9p!{sF}7g zc8-sxw_s+Yrsqu5`64s=qiJ!8<)j7b$h$0eYys$L~2v@*B_QXkJXf!!V*7J z+u~-)zkmBl=oD|?)wO9q_*KIKtqXynuQAECsJs>Z(B%0K#ls@#F9~esS@ss_w%Db+90?wyvo=?!xn|Hm!u?+#pmHr z;gFv2+cRfXhM(S2%ej1#tR`8T(wZLm;BgsYij*_CP%P3SV3Z(rIOK# z4}!|bndOC3h6lqC8u;3J+VQZsm1w=_1CL(WS2?b#P-6hN@@ zlJ2IAa7gf`B;AhkS$qCh$F*7)w=b<@sJuWQO`&H_zKL`&02UNXj0i z-oFFFK5>ztP(27%Lu`Ij3;DI`jDW_&#ujvt3uwFiKv==OWIQ2J5kR!z=L?L~RjwGXVV!ID#7O42r~KMGqD;m=jrXCV zMP+_)U`<9mJ{_P(H{z$R;6sL26U!~@K zJsi4qMx&bee9&ng$snnnG6GlkUe|3tqMf4;tD1yCQt!XJa5VpY_W7e>{Z;^*h^7=; z?~E98a#1Y8%SeQi!{mKCZdq}UG|sOf(#P&{@z0iW-_EdFK0Q_n_hsm z6h%3u#N&6>HHH5xq2q|9czhzjG208m9-AHndp+jlv)o3|5fBv#G#Jsm-H=fGn?i@w z%$tMDuWB;qQhF8bm;{$#jItwd&N4Yw%1y(sjEp-;T;t*=xbH|Q)Rn~Cnl`z`WyeHQ z3AQyF%W`uE9WnZmJE7A$RJoKahN=AJPNI~w{@M6&HKM#1^nz4gno%VCrDnK%&5(7OlD#Ii8#VBLT?VKG&1%Dv4dVtrbuU(;=zZdigv}t)EL=uf)WM z=b1jF#(g^X#9iSNcfdi%>%7=53lye}x;q_*QJ#Bo2If8C)51o~d{}Rx=`jVvF?~&I z>I~6gpj%sb56QVL-S9Ww#rF99eVJ!m7hM|8FG64CMN?&`gx0$0PUAC{8$%*y)HcbC z2Dnx|*i+I}T}%HHIzwMB0TK|@^N(ID*vuo?kCo~zHIUEXF5{E@yVD?3#l+^ywW{=R zB4)FKdX@|v;43U<^|&nSbUJ&Wy@gXjllq!XQkrv$9aX9>qm`^4HNYN*+YAC^nDU7UiMZON|~4RfU7 zY2O`XGS)4io9C`_&+wM-K~;cN5XQVk&}0E=RU3aqq^{VE;;p&31a|FeV6N`f%q{AiCQ1?i%jKH5G$RU1mYCK=QDTdn^__rdO zRf}Yst_JBefY6*&F_4*LwQoxmS(s=LH%k!Uscnnb%RO6fexbeJ%CsQnWj;Z{5cM}U zV}vLrIj4wDnWZ{SWL8^tja>F-C4+=dhY%y_c8Xlc+lf5;)q`HdQt&WoT|FroCl~Vq zLOs(B)iX==|Bci0h@}}U0s>+F1QtkfC?%YnzdAD zIwIPLQq0kuGm(_p6fPwPi_SHvRw+vQjjHj~thDIU!0H>7DASS5kNRdssEOkrN!a*I zKs%jZJ@oe~S2LLy>=7(fDb3%TM=2^DLF!D3UCqe~9pkR7nnWlxag|Sg>Wp9xVwmlC zeC{^O4Ml|ZtB@9;DDyKsHiL%}*}y{YW+XXm`O;`#Tbsl-hj)n!^r?03w_b4kocz+(Ly_3wJa_bOJ~g!(H$JV-#^iVWE-% zWoNGD06r8{mKZJmfC+r#;`v45-v}qsLE*~7nMa-*xn<9Yr~B#Cb;HUA zg~j^WBMI5Wm{l8wB7a2A>2{kMvoSUkA{JW+6$^T(aV|wnk2izq{5FU88KhuYbqtib!;=If-S5Dkwg+kt9R4I$!vrhXGd4FT?BC4*&mu~a<*dl@gO-HmuE<4vD6Vy{X~P2$nbSN-`TX1=IIOV_Tm zPlN>`cz6|C9jKy}Y4C#CE$Nf>=Q!SUhvGp5v%Poe3lAODcg?~ws>S+xs9s#s38zZ+ zWy7WLao+U*gibJ)cJK)RHmolgdTjm)IhDDzlz23}YzS6yhN|u>UyppW(KB^0v{A+$ zF_VK1%Q0w*z8RV^=JhY16*wyrXowfO$%4$JSeA@bd9nN~aUWM}qRS^b#T12DGLfgV zmyu`-#bZ(6duQhGSk#8)kdjcIQOwOd6_x3@@5P)XC|u}(y=E1zyh^Y(kUb6Rf{K3y z37gsut$loSF@Ry#x-8n5>0vHHyTY@+V%#7np`k&MBT^O=|{>nwXs zz1jQn8^ZeVZ)WafD`Go8 zAluPBinry*l*)0=bKYo`BYU`MR0Nyq zxe9L%a9C6c+pV(UTxh+uVv5eL%_W9Yt#117f7r}Gyd7?}+C}w)>GFl}?0;NA=quhZ zp>P@o;3oj@{9R^ikRr1~`3;Jj+CqCu|@ce(Cu#sCTSdE&b? zfxY~rYA1S-3Yj7FnfhlAqV$>)EUwrnWu8*pLaP_;P0$f#&*!o+9MNTi{gy%dAX8fD zol+Rdz#Eclh4Nf(xm$Lzdo?yy!&NfFT-fvsjDr>5VKqOMS8JlL(o7Ff0rdFMxf6!O z2N~NZ@l;Fi%~^{$mu2<4KnFgTT9IE_j~{DrS+I9`J<5Ujg<%MH=D zmR;S+CjC$76n#k^NKjEWn;_i14WTY`mToI99TNZ&B#7Pi!MX5e$tO8-(-d4Z9L+$w zDg>0wbk=c3V!_v8y>&nstZ!VB<84d+zN88j5Oc2Zq6ZqOzSlApg(Z1)rSsgLq@-p@ zPmLVJvYMWdC>JO_qh?w?Cc4Pv_aKvo zK3-CxWcN<_oLf$tjBiwY#d#2O*rl-0eL1@#0<`Iqq>V{iXG-_Xx{BSR{jXJ8L7LBV zoqEMHGjUph9kSu63~K$MJFU!@s#FfHa`d@i;sK2lEIy^M*qKg%P0P@g z2lxM<6i(0=4~PkI%BCYk6j&iRW!#4xNZ>)Ogq}wdotJJ-GhwA$1T0S_f{be}mUMU& z%j`WIamB{!6U$Odlsq0;JykL{Ew)P}(HkddkzGn20Np0o*fi1X{e3e{N@0UcY@~1& zSqACY(9#kxNP&QYBgv`njOg)WLC()P;&PY!p<_-t{=@h=)n;I{1K9ny$Jn4~4oxxynU3e#$@w5%$!T@h%Ma_>%gAyF#yYxJa@(4np%1 zSW=wBc=8+=>q{QStcD(HI%ru#(ya9{V6mWB$R{>zP?uR>Bb~2lu>>n!;xB8tL)3I4 zwHS?Nv&stPJ^3k)Lm1w0>Cle)GCg4r8XlRG_%2-Kkfv1N>jwNpwBsMo z{(l_`TaG8j19Y)PuqfCVQkU7t-<>4|=1b;Jv4Vu&2s)Mi=ozF@RqPmJ_cb!ni_$=- z#8NEm`GpTtnKog^+Cg?;NBs4`-|}A@F!-pWHF#9x^Q6b%$X%2vXT+Qsila1Fl1f;t zL{WFmRJWdcBGq0qi0%yR66fFK!4+f>UAdI1yA1Xqam&=bgNE5VWgenFWgwfzS8{Pt z+%!V2DBvTU9<3p4U}l%6^1gmn5V2IvFVgra7b&YCF3e3N=_xQ`@#qdQzsL;|0vMjUS1L&SM0zMr`s(r7S@!L zoD;Xqo8~UI)CLLzSJ_kG(QOYm*zL3T0+-pyWfY+yIJPs-JIi#9vi%KD3pmWpS>mya zhE3It9Ozm!p%?C3TNlK`wN%hMRH@idxZyBHk!`GrJL=QI8VMq!Y9{ zFHb=}rSXTBHvzDa@Y`QCUwS#LUsqvca3MiI#N0YmR;+|sM7G=wVF{7LWDXWKiskfQmBqI%AV0kk5M=`~U_CblFI09r$SS(!o%AW!z%Lxwc1?pDC z&q7r{IKd^~r&boDDXjcpl;|HXk_RjC$-HDR9(e=4fNn1@)5buMY=cYr2F}5f3SgeJ zl^rwdxqYvTvT=oXh@Gd5_T+cb)zQzY)ZyxVA7Qm6p$K;N~V(jU zM`}{R2QEq*%gS69iJh{RF;mS}m%1~Cmyf9t+mOYU#f)^!rDmu5T22JAmaZG0CgHGs z)Z;$z#VX1~cxA8Zt5e2hs2Us@PA?J6i4>TaOp0B;Q%Hz5lxI+tz}5hwzp2Tj%;3;s zAnD*zk3ugov}qE7tO8l|J*6mY^~cF_)7{Is)s15dGGQ{<_(h?=lUk@%CE8F%{|OyM ztO(%a;?#4;4=NOgQqef^DExu&O62Y}YDH=m!S0*Ae{pGX*Mn=~{J?T82@*VM+;o-w zY&zi@%E~kCNn(l(6kIwKl*+NatPSYqY>Jdz4QCvzU`uI=5>`g?8r63laMi&|w;6Q3 zyW}!;qxbBx+9qE}*uo>@GNniMKy5!R8LPC1J1{0~QlKKEHIUI-@C>)YPv2a|MAceF z5poR0V_f3gIRc^#$}rfsIcS`EtemzM?dxogqB5=ce!khIoFxr227>N^6}jeu*eZ;7#-k0SHFEVdLT>+ggvBROKN-VB4z6~SF%24w^q4V&S zM|@mB7ibjOV>3sQ?QP>foo#$FG@Q8|7S?mwGhN^j9bjUwEFqx4Q@MRoLGNvQ$^FhL zWr6+mgWlS-veqAeDSg9|zWo?`7>8~$HUI5==T7A5P`O^#_@qH$${mX5*hJc*elamd z3vGO#{6RVFnobj>o8n_iKrPYsd_hekNl zrKgJxiN`M7*uvB6eow$|b|(w1XemPhm;g~=rM9g@0Ea>NPW@DVBsa)9BTF-jA}TJA zT|qId_i{nciaeE-D}lz$km61o-s;aenmx>A`^ffT=`E@oL+EoM9%89rlTqBrRKDqqgE4okWRi^}@isc$yWpQboGzu>$E|Hp{$0 zAQnda)yFaG8^28Z1c8}Rcs&MrI;aVACXzm}nVgTyEOSwufD=7HEr0LtvWT|tEgvEo zA!bGib=eo;*3T!;WpPS1#chi(?D!q4owmvXq9e|ch?3I%V+Z3+D%{100V*f9L}#;U zMd8lTQq(Aiz8_hpg#P#fB4onE;!+2K?C)mS_XZ24okDFgX?WRR6laV8b;2E0qnxrq zs@6vtDxN&Nc%&**?h-ZGIeS-DZYQkb!>Q_2Z`AbY#IgGD@X1;Z6>(QttW{x2-~l3K z9$TZuegczV`t0O%n#vkJX#r(*z5V8>4aadYJw8M2(Iiz7XdQBx6_=}F6vQ)Ulz-0< z77?Sz_Fhd%{ewH&A_33Gj0&qky-!t!lV8S;vfghPZ^pZS#_(zr^k%LC{3mo4x~xx# z|F4E3-YRT$KP!8kXFP7IRz*<4dhS#(;e$I8gBfjlxKIEYCQ0NK>cw3~)0G3))rF7K zVA^0z8(h$)MyB`29Y1bSY1l}P5)|r{6;PB}`wp|%aD=u~m`TN_&zgHfC$zAOoHL7` zts2;f`TZoVs4)56e{SzTl_wypyJ!5~Z82QSFPQ~pUK{jPpBvT}ny~($J6xjZl%9|w z0isA_%;sUjA_6A!iNx#jd=OCSVB$i67v5Q!%EsB;d zQ-lhtwzg=eQ%VP2rd929o8R}R^B=s=bDneWea}7jeCC=2EnYkA!L$3K4Sx^%OC&el zJ%1YajqK%4-#%f&62usI;)`6_W6Tmz@tz9_sXM+ZB5!TAwE}nRMhTDF@);>kx9Y0RT9f)o!Gu%2U_0 zb!%tOi`SJ@Q(5fH)~D^g%F)sPt%sh=K5qF}MM3Y7`~UW)?XntsLAFl|x2XPtA1kd| zqkc{_DZDW}GC~Ut(zuz54=`&8F5vhpJzC~>4%<+&ucwhdPIm=WE4w3@+BFWLF#fM8 zFyb8U2xWqV+AJ)i>x2qnTC6xg^`dsj|N4RZf}50D9+=u|+yVEVV4%#SCE_@5OjEj>+Dmo_o`kdmX#cD|Id;Mfc7w8jEp{|T}U5%lbVo*A317*k75A8%w=#Nx==RnzKY zie3r|N`J^})!>4|KePxtHatO{o>&{?ZjWij^x7nw!Bn#Hq_o-ShFby}v$}eto{*;E z`5SbAFy`oGuTWAnVtA|nX@D930RDNktp?X0#(s;K#C$Nf#Ob4)W-MNfMAh*w`b+Xn zVOH28BQG~miiwA_U)VWoZ*Q%9?-&<{_X;kGj*yC`wCJxhmeN};Z@f`%A>v7RR_nRF zVmEfvSPB$|xMra~yqN&sxzgiNsXDpWZvIi?swve$Fe zF^P3%muyu*P59v9Z>N58Xj^u9UKyZZiJX$!Luj{pkP;Y2Oy_(B&gi4ebO%|S8hGk9 zx8i-Vxn{$WLm6L<%D!bky46nh{1ck8kzF3qUSLbPNjW=tawzhvdBxJ7`WBMRAH+i` zZ>yWWrwx=(|C<~%`LBDzVDRCWjgRM2sL=)q!{L88^j7*84>-K6F1PwOvQU|P+6gHj z{jj@G^mt#_0U`6kTW4M0KU9`i94}HD*qveT{NBFTCLVhoJ1Xbr8`!AtgS{y-l&Of^ z!D@k^-c*a=TcKFD`$+sRev4~m39Vh&EZwpSwlVuT(m3T{Qn(Cy}f zc4OLgKCi&hmopk6;`8xZg&yDs7bMY?V%t0BHhYUr>T${KM~2H*1xW0_KYA=aq>Zva0L+L8+7tM2uo(#+n&tA4uzdtC~1CAPBfNDqJCAG*#Nr4*h4 z&Tp=@I;8j2tNmd*5I|Lamv2VjEPgG8y!KcV1~;y)aw+IoQP%BukIs~p6nULnEHQBS z(koH%%z|T|;c|#Db~3L0DoT)plp4-X7 z3)Oob_&>O_rHSd;yowU!h@w%kCI;1C@u?;@N8`;9x2*bGr0o8M&H#ZXE{ zCp@>-ngdc6aVb7$Q=^`yeEn*{@j?3qf7sL_UQ7hH4O9eY9YDkT`fhc6&M333QM_@i z03QhBBr-EwEOWUKcx+K%l8NLU6AKZAUyrFG%)>N24Lp64$TOc1m|(q+^96VJ{oqm} za=TVE+aDkKoOlHMkEwYFj?8JU-L=US8<@I$Y(2_suTfCPa4uZ*2q70bOUp<}*)IF4 zScvC@>lA-L_a&jRG2z~^F}w%r(;VO2qt_7B-6Cpiioo?=8I(N++5Az)=fI)Hej}^l zObRpfou6}<#ZQD@ORuN_z90lR_kV{^_*f$neVK6jK!&m9Wj-T7eq!468U+|v-0PHm zj(W%S_^O{!MC{BrKpvuMe)j1ib$kd+h#<9MHr8@LOO5Ye30SVA9*aM?Jd-I+AxEkA z;sV2f%zj*39Y*hz9i+_Mh_m!mZc2F?>^p6*lq%C|Q2W?AO+fE?@jb;Cv!DAI9$evS zhTypRN6SP@FDPTtA16>R>1^&iq#I_SY?YIuavTx0eZ2eSBcd`1r_BH$1Tss_^z?(S z+zsYz!rL`Z`%C|VOP%D39Y0W(-&alLHE8BVgBllMA;*wSG8s|(()sIPI){9zm!iDyR=t=nEh5C~|45NXk zH(G@v_cU9rWRj0Z%OU7<5Bg_0dv>>BdrXfb>#`oM!Y<2CUd@W=*rZ4I0lU@{WP zj|8Mha83VlD1CVw_*G8e4D5B;pB`Ez#c3vA>_5SHVE5EF8V!es$y`a+LDo6c>1L?j zsaUmwP@!o ziNp~{<(8kU)C|T7R3F!dd*0kG_1CYsG(s`3jY^Y=V#Rd0tJ)yOq3DZJ{`yDSrf*V~ zKrfs&7(<1vCcL8$)u^w*sE}yfjjsHvoh<9O!e`c$gspQ3RPmpmb?UZnUV8fR(Zp*0 zr_}qU-vm_vfCPE7QXM#L@nJExKu+%R{fRPiOFy>GtL-pCtrP8Mo!!g3 zg+IPk7^B4jSCMRy&z9%IRnC5hPSTT@=P8b?%Ffa!3Uo{l*|OWxPzA<^W6K0#eC9{i zc399V|Jf~y<50gbKr=3AR$H&Jo4Ua>oX8faRp}Cn&jrEGzDl8T+%s}Qn(R7!WRTB~ z=+12aL}*7!Z${yp_>OH>qf31{yW39L6wuB!4Ox41(O0*^a?W?~jH|cld{NScu;>xJ z{(`Orz*D=XH-+V4E5|3>bgdTG_WmCSK5c6$K&D>ag8ccRzw~3vls8(xYtq=AU4VYg z>|nhO$21i*<%G-6rx*3dU)JO#Wq2Ra!}6^o%E3a1Q@jpPz4kh*%EG3#|KQ{lip8{s z)v#cxH%AVtFTRbx^ZNk)SHA#j;^2ayH7=?|)88jS<8Ju6***|1;W=JhBzeo8(vfVP zC2U*EYP7gLZj2Fj+Nvna=UJ9Fp49{qNEdQ+YdO9vF7fzW1=IbI1?xwG=NG2xFAMB5 zn_K)q?nvN{WDw@EX)#wmKDS~ISmR5Niet97=Jf6B=sVL*K`VLdL;}r4C0Hg>IhG@8 zY7<0wc$VvO{TAE==i&)8nIdeC?$_jT4#0h2YFcvy>CrtRO-zW*i8k=ea={nv;5`2_ zR>r!U{ng624YJeATaCeuxC%u3WV`bIYLZDCfeS? z{zT{xSziUf4>)3Z!D_fcssb5O$iv&W=$x6knDZk4+d<~xdf7$gKci9K-pBf0iH%|x zm%3HG_J^q0LilfX)|6=v?5z}6ip&ZMWmZkQdfNbcR0FtHr2A1)n-?LqK+TYk_rWn% zgvB=BPB)i-*kejZtzs;sct6-ZwsgUYS#r-zq-+#|?t~l-D$FOo=-$G#PgYv^y|^_` zZLq%x7KU;W&EM43*Einfv%Pi3LpEjGjDnm~(#v{$Jb2%b{}R`lDJvR!MzI!zI#B0G zM+r?q4t_h@;+K+d~t!s7|W<> z^Z~m>%Yol49?{Ng!R<`(o~Ya@7tIyg!fm_RCnyqaf-21%grDqPYA*w~O;Bd_$!r@~dllX|O`sT7exRlJONl6M!|Uc2yXfysKY)A)-7 zftXUcHl?|ex#9L|>SzYwiXr2w@xdiTl6XF*@rN0*GGg#GGGZ1|)EB_Sd@U`}u=PqW z5cjF8Tbvbu#GRzK*ISC37$-4JNsd(3bJqAQzE|O;T)Y=L7ty7HE0FH*n&$Ij(P{00(+%;u z7e(&9&A?|n@=p?%u5G31F5w;$QuRKyW3EhdTNkMJb?RDV+In1>)Q7~bQWT6`Q0b54 zbL~8YXT{2tdWBD#k)Pe0iT+A;q4S`?6?GTY+BgX0>cZ?5M~7u@w2W}Rpq7K$kM!|| z`SV|;ULxa)l*Fgy%_H@*i&4BgmWGh7bl0Gqao-*ql+W6nH-?jBtZWxjrsU`jL|DGD zJE>6OI3}yTP@tYw)=a75Z$EoBlrQPufNHMGDK4JVR=J`TN^8`2`N^S8DSrjEFVX^N zmYU0nkZ{D=Q^~IwHPjR=EV??>cx8OzFZ9hFvFi$t@P9Xp5awNR1}lfrS5pR4D(KTy zCL~cHmer2WUSp_24k1rkUHj%L57>Upp0s`5WwU>N)WJAla+miKm8s#v00((|@JsN@ zuVS1GjBSD?%oEf`YZu57HXc^7g|s3(>4xO91vV#SHnc05Ht{l7Vb%zm#&T-@3216GO`q zBb4W+izAL1LzsMWDHliVMQ`%uOZ^r2RK#Y5r?~OdW*>BUud;`Q0tq>p_tbH5JFF;7 za^k>&qu~Cw=o&+hE1G)Q6Zz1n5A9ZSM(72JVT4Fk+nXBs(=NA}bRUB zm6~vhQp|>d`NBUjuL4no76q-*&kLpE#Pg>PQ!JyqpZPft>k#0V{K*wo9GSoE+-qy= z@}8ZI;59xG4mt=)!gh_duILT5JNqCeC|24G*8Q}Wy=v_f$HCIc)rkXop8Ih^P8-Ih z9hj)yd>!%m_WFvne*SR3_ zeiawSvou5=0{?Q-ETy3};)02nx$>oAAeH*ETIqpI^F;SYj5+>s(v}x}qf+zbv}S1J zEH$;iOyx{`?qk9uEk?%;$SIxYw*Y?GNvU7T%awM||_wQw9tjh!G0nhQ?=c zau#x;wskE8qWVqW8DXJ^UnUVw40P|9RdHlW$Xra{!+HAyP^Ht*eR@20GPNF*EecS? zrWhOg-6$(Ej~Ju5WXoojqw_xspL&Ap*;{z?u#=ROpA`BlL+4k(H(5Q?(L*i`eif)H z_iB&kT7QD44uW(BLhQU^u8e37$nl5-s_QKYxcOpCiTJl_yNolpeQ!}F5e#hES(Rr2 zKyfhN!OibCxlKT}Zfa(9Rl94Jz7mm-xYw9JZ{vgI=-nN&ktC*= zX*77*CaD{mg4rA4n=%tMzO*K|494O&=^Yq4aQ}uPf2wh&g3RZwb+$#93o{R9q zx1>o6Pcx3`|4O@f4u!beY2FYmt@7;SN0`3|Oe%RdRbOTi9}V}QN}H`t-t@bbCP;cy z<%&Q|XvUvwiMZ0oT_(NoY&Lp!nBs->fk5Zi(cj_OFPB_(Yj)v z3O~a}7b)VjYNm>I{IgP0))7zR0MNc5-^DQH|B76ezrM;Ig{(&Y`Hw=&1aAduYZYz| zmcL9@GW>7}8hk}M=%uwEd8q{$S&F2}Y7i%IJfQ}~!Eeq!u6DWN>h<`?zWepb+|X4$ zWzt%YOkvHy@|c)w%|q)E)+zbrhunpP83_D1XntMGh(lV7{U-H;o&H^+5@AO_^W8$^ zjvMky3J1DMTdjF8l`msF`?Vnw)qga#2x}h>KH>Q*!T4^1(eZFd- zMY;`zWSZy|4#k2=bFY^it4=p^fZFP@u{WQskk3USc9of0x~!JDYQFaK-OwF84pWrI z$uX6<(*)~t7=isE6WyiUqlScw>g8pEu`nu)O0nBE?c&2Hp!TQ~A9f4eIn{uuAes!e zKPZzJFa_U-=SWF;T22TV)~(*W6~8Pxvq^Ra7%+WRA5)@*GY-F=#}N8N5p_sU&G_vV zV|_8r3ZU4D@eS_(P{Z5C3E-lkExfAA`h8rTf5X)PF*Jym_D@Pa{d2lw`8sW@4H?$$(!&ZF$w zs=WtQ^>?o28gv%_eO;d4D{Hx_Eg!{yE$5r*Ufk51G)KkD@1?4m zqiwV6pPiXBfKBwEK7pfjNMd$@5^%md^psymgy`eUzkln%_}6gJDe{zB)(|2ffe+wL zebD?mnwGvg)OxhUe%q?oZv9iz`oL55vtM11vPzfzF75iXQK!}!wLu?bX5$~n=otFV z54t&H^rLg-;dy>&H$>Fhmz#1cDne{~pGEWy%lF@XKZF4R*!Gaf`-DrEcM3IL#&(4j zc>--`wM16bYMC-)0zB$^|Hh!J2cfoZYUM6Hak1OOUad8kHkeaJaC?GXl#iW976zIr zbhvs#tchjh2udLCqa~4e>q24F%TrEd+fQ|w>?Qg7V2_Bt`r%H&YEz2=9Qy+(|-Vj$wk*ml(=Aw4|8r< z2EX0qa5(W>g(l`KoAo=!>9A>K!||+?5`?|$FNrNB)eRazj~e=E(t1qo(6<$inR=M1 znta4H$MHQM#%7J*uPH$`#R`QwowJSamj;;he~;LIpmc-by(jrb}P|-B)5KF_yK_`90~yH-r7jM zuRu8OhbW*VnlUnn_2NR^1~osVy)GOOsBwdM$CDX6cpqomX z(S;Pcd&vC8e<`P18G+8g&vGrLlY_%2%GlMbh%sM_U5+58V&6?~j)MBs>|4zUi!=UC zd)3mdpgD@R*I#xg%Ke(V6V{bNdMKx2@);IOtENmuRF$)pGwno2+FcF(+A$_^1a{Ci zp`yx0q{@?6|AQrj0rZc=E3e4w70eqGGSHxMyB>`%#`-7wwR~(eXq`PU=@bYnm(h=m z94b=ov@04SOCwE-lL}D0DB(J<3aL2XG38q;;EbS(znpj0eZYdbK8tdG;iR~;58~Qj z`|v8~lS(huah9qJ6Lr0P!8~v5ki0P6HR_(^OUc-9E4*=VW+*1D-0IV+JSFntOTQcZ zH@A6x4gAF{G^%Zk><;$@ZNgfjp@id@i|ogDrB}< z)qd`_fb?q^0bMK!xz#4`l+G@gNa!R;hBYC&8? zTfIbUjEzvI1(&hz?jJW-Or|DhJh3qy*6jJ~50_gWEZ!qfj$kNX?&wLIoqPrMGS|$@ z7=N#7{*yzm(*rWqzKDD5WCSiJme@5?MXB@8yhsUOPu*<46H-=^5Y4rHE0KZvtZ}_4 zKn)%3x`Zu5va**>*%R$F@p{Ysa654LA%}>rLqieoulOuK-8gB$zvxnkbX%k6Cgpm$ z$z2Q1HO*Upuk_~jIj$DxQXK{tEk0IQVf*p&k~N-~cE3~C@g>W5$x8t--@#r#94zOq zHdE+r4Oa3t6vA=LYUp)0%d1Rw`OtJC8@$hn`gd=BZ~ z(nCg%(jSNPlnyJzNDNL^ifq9yF!yvRS;X6JcD9(Ji+>tRVLG}r7e1TC!tJ3RmjOOx zAD=>Q%fb`JjUnQx5}V6j=qsXQc}CU0?xxLXf`Ku+yBhc4&ptocr|3{I zTNUsEZK%6u*G7I;uwe%D1OpLnTdTEC9OPHXricR|S*I__l1velZ1v{uz#(h9cm z9LtTCXeh&}Jrc}}a@X{@H@FUeDkUT3FQp~J02wXHkynBtyXnR5I{e-2fXZqPzRP}H zVXdqkVPOtRj)^)`7jT)c)ugUya%8#Wi@$-HqtRmlE9o(%{rwB>?6eG-khP%^nO# zP%*j3Sy!Vn{J`SAWpq8nejZokno$D{Bz5r3r6jTnO6t@hpFar9GBuW`iI#tTDKlxJ z5{(w**ZxRfPIK>x9>?Y;(VY6`*)K^WN$bg4gHTyp(xB2Ix{sHSd-^x=sC4%FUyIwK zk^9G);hUE zym9Zp?d!_iJFgh`*Ff3BReQX8m1XY#qp$1!n z@`^dB9q@|bqbq@uRbF!z1rl&jBkLh6V@#Oy_Uiuo)XqP3+iZ+JlWDEFJyYaXrRP$V0^0xt&)SVEey(_xzs-y-N?+TRtFq zY^Okb>!DJVUYxCvmU5!F?X@p9b@}2))_t?4lwu)A<>-SieVy`(lP_ZIB%tLgBjkY! zug5@llwl9E0^b#Y@|~!>urFu&k}z}(S&X%KigaL87m#t@jXd%&Deu78c^I)TgbAd;g9m=98Qr^s^^rmrEBfkPx7p| z{R#%J5RXce-gh0h9CEdA)uql%L`C@d2+t~WQR$^}junO9Q*52)08{QE3u$Hk53GiJ zz|V=r2-52(H8)Byb$4S_E;ioCi?$K(nXedisqziM0dCj7p6+k9T#So$50s3J@}eAO zZ*>rTiVB3B*?!XGvWoMJ#J4^NYE%Lv7BwS&1(cC8ZOw3~F@VI+-^H{XAfA|-b}rL5 zf}2pwfA)iWGo+6&F$3eOQx~C7 zb04Gq^!(gW`8ms~4yBNlUG!Y!vxqR;BF#IPP~F|dHv^@9XEN>pB!Q2WkTM z67Ll;{?T?wxPBny&0Ocbxr|212gVmC%K&5mmtdDmn1i@`8CGaI=sjbCO8!W#PSsD8 zStJPV-J56(l-x(${`|3!JY=FaT8dx8Mw^+tnj)nCvu*z^yPOO7BCCgxjokYmDn+K7 zVSv~t7vHQqB=t6tZY4Mo_|06vX=4HdaM%`yYs&hBhpf#cBbHh6#?zF(I7|iUdj4Im z`ANui744!N{$eFaPm}AvBY;>=7$1c!xtH!e2w|3}=wVp*#UXK~7D6uOQ!9Ol>Ic*_ zU;aA6=Ipbg#+>!BmzkMw!u43^Ten9O6>`1PFJ>L}y84Sn`cU>?Ocn5Kk8UKajQ#R{ zvCJ%?q-5^nCP8S+x0c9dzgS+!2`U~L|K)Wfx{;MVrc~6Z+Fm4`yqP&w6|ffi;j97x zpzX6dmThT0V{}l6C&A9XUL*!w5?t3fHB14w^0%5|u=-8CHp{F&G|xc?&`XK%J`bi$ zxz%3z)2KjjAg@Cv-*4Ur@8(B5cq}qNp^-EvmJ5jI+AEoksO3JV;6vhSbZ*9U8E!tc zk^ndxsig>91;#co(BJCx?F+P!?si|+8$m>8Y>rIFgOAQNrz(B6xuYJIC_3=jQ}JpQ zH2E}MdS^nZ)gy|sQB4lj61vJ#ylsyk*nB09{mG%VOjfVV4>(|2*~#Suge@AT!vjQ^ z{pe*)!7)ZjSB|t9+SQF8483W5zP85fW_QNK3eim$8^Ka-cOHf`_JI1PQ1n&y;1}q5 zWjzEEdQN8C8yl{oX%r01rPgz5xONSUl<;;XZCZLSprrlY)ezBA;{Jrj^bY-ngvpAH zBYzAi8RS5bQ9=b>{ff$jOzxdIg(`A4@94=c{QAjxkkjbzEQ;AJq*9|DrjJ}0 zn&jgh*DIE8m+J%GU*L~N>Sk@Ro-*{R8dJ3oAwaJWhXw13M4_8`xiK;>(o#hq!*{4J zyISj!WiOnZev7{oRz1?#?O_ujJ{Fo}s}Iz*>6utdDOuMKAt{6I1w{Rs*?qQhY$(pj zc?dS<3i}u`?ay|N%B8$G!E?6@O-#{T|E~{iX9a-OzR2akWUjlM$S$k4r*KUW>Xoii zjdc^WUV`Z>=n0vF?p-i;e`vWoqtz<^$A=rKdFA!mce^^`$~{V6T%NfavSGexbUEIiqkG=ghtHW?i)GvbU!ct+EkST3+rmS5spa zD&@y4(O+GbkqCFa!zp)*j{2u09W^ts2zv13+$k|9^0@C5+5<4=ckNDu2GTn)B`1KM zoxPd=yaRBv7X7loN!Rwi??{d|vFckXxkebo;~dQ14cEV&MHg0O%)ruot7&;JHgbLh zw|9LkBM)^=rZVY^)a!F7$`DHz#2mdQV!XQDa%S7;qsD*ErHkBBE!dSW!R zH7$L96lzY59GU)Zmqd2W9L$|oM(8>&-j(FHZk=kH%bGCE`iSp#jv;xcV|{V$bng3V z1G@p*pL*Pstz(BaAnB8_Zh`>5d{-at;|-s{k~qgClVQ_f>7kQ_k>th*(BjD7@q+=! zJYxvx&fb#;EHM^z^s+IR@=_w=NV+mE;pO71Pw(ZOlSUr{}xH z_ueRzbzCKvs(QhX1gH1L0^FChq;n~$$<{f%ESW_ezvDO~1e~OG9^D%Svbe02S61~w zP^7MK49&kTNHx{OX7aH9WjyeICwOl%0*V1&#`T=tJO9%ZIL@I*7+Q8cauWu?W-ON@ z@2Z=hq4eU}EFg!_9YyvBq2{a?HXdKW(Z7ajh{-$y^OyH>o>IC%SSzH3!&%Trk8BnS zsoXT%$3!v=azc9EkVs^ievYW|+xk4gX9w|~K_;z5hJ+?}=9HTnPqe)0JIDT; zCJKS#b}vQZdaQhvr4=lUu~ArD53w=zX%%d(Ak^e>FJ7PXP}!Vr@?qVuZ@;|yJKeYj z9JMpkpA_wiSGlAA%OISUtE08y63qW&X4`xYbGwyl?lYL{-0d&SsVsnmRurRi{POA} z;IHw2iRO~$PkGctO!el$vMVkGo-DTDaD2F@&MbAz`^z8DiTN0U%`bcQro!Vb1iQOit-vN7O_=H z-r*sD(qI>Fu?)@bCx<>}1okR?Znm_VQW82sxIp_qtJV}jn1?0EX z972ZnuVfzO4MwZ=tQVm)XeHktG9~a6{WXb_u+30XM4F23dtU4Deo60>m#QHP3$#&n zhVrX;`QS@NqC9pON zfhbDgPmp8*)S%gD+*2b<0x9SRE36m0@ecdFq9v(&T0@~in~8u&Qc@WprF(uxFa$1^ z5(i^;TjWlF2|3r(JUqJiuWHiIj?}Ue#a;Sv_oEVv1pk1*GJky$#u(IujaM;7I|}qX z%LGZt0Fs$1sPiX6Tj{#CfPdkZwz8VTe};^jMEUj5uTRi#X4vwUmt9{&!@$Qm#kzjk z7jj5SfqJ}Y@)z3LKzg(j!Rt(eQHp0v*nVlbW-N+NgSQ}>0aSsfe1EGSL< z5aiOKM_jSJ1ZXNmExou`HgN^c@bk7_`psR}p){iJD_H!dy;HBaK5orUWE91Lyp;C$ zl-c5_W4B~gmneq{Kw! z78Qnw-j542#oqQNbIy3SXo6e-yrTJq{s*n`Zj?Up1&O(p@6`ma^r@Le1xg;x3Ya~(apkWiLQh4{Yb8VIfH*%nvK zP>#9;!cT(^BleBVfD5M_9r%0I*bwW_&)1h;F6X(wm6` zdM3ukq-uN=sDZqe-BJ_%3GQRkQ7K?Y>pPPzLcf&o=Eeng6zFV1UTm&5tjg@>y9%{ed8ZZxZvP$4d%flo5=-%ybrFGKX zzC?cf9d$$_Oij4@67yX7wzwuT*Q!<}GAv9JC>Ibe6T4{V@Rp`mi~mdQuuD7eM5TnluF3p-?vyH!)%N(PzFAx@HgyW z>_~w>_QJ^{gX`$YzXyC1dK1o&j@wski)uxDSxvE-07alHtu~zF`K3S8wFCu}%zy`BFWOT+HBO!Jzt zXwet}imb~gW+&reMh%%OAL%zeL+&n1=-oSu$JUr-pRL&K-e&tM&}L=_tc=u-UCQn& zRzfE6iIe)3-Rp0D?EdC@&B4s_OqT#??QPX-GgY=z&DEso+8mIXXa zo?r~yMlV{s%+RWp^M6a}@$pQ6lMOKG~*% zS8exuvDQIrl{j=nzea#x@HwE%g{8(?Q>B}**xEWaV68}*qm$M<7a0QrNcWLeYm(o5)!PSF37j=T z82MZ08!(8z63O$_%?SXgD@RY)U$+x5@wg2Qt3JdTTh0QLm5XW}T;%tWKlsope z4Z{1UIDRKhxmX73E`NHAeRQ?=0yzkqixvd4bYWqDuSR{<8jD*%vt!Ztvbf^x21f05 zkq0(*`#X~I{_}xYZGqodPnqKUx(WjzX?>RAa=!|K#*@qWJ;*%wfq6%}Iny;1EkY|Y zsp^k!*+y)e4jZFew@oKqvv(T}>zm_=Z@fy!j6Rr(HIF9+n-5;epG7^l*%zI48tEB| z=w>dTtbKx7sXK$YrNr=)R7bb`mR4nqte(q!)9diut#|U++d}SJ^MS60ha09nEM#qG zcdDt{91z73kZzVweAs(lYEIPN-&eFlRe(iOV#rHh;~Cfkm6Ug3(rBH09%GnX)s8=k zNNoO^k@U)mq^D1K$)MFc%*Dt6q_ZBN*CHDMp_=zyLPj>|ehIysxM7t%I%;lqS(pPd z1ZYClEA?ABJiry9@Xyt)+B!FGRLL)pS)vTHJQ-|-sLcdOX76FEx2JNiEn+LZR6 z`N<(i;Jx97basuMl|sROf9r}#OQn>l@;<~A)!?ZAnP^4}AaQ_{ed;zdB)bSNM`E8E z)}(Tnp?#Ch_|j7YO@w>&7ez^`!8I)JgFU}=BI&IMYbV7iJcFa)+X0j(doJeJO`|^w z<9*9r8TN+Sw6Y6>0|AbO4JT)XJEa<4q@znUB#e1Aao$S%#!;FtRa?dOCB>KE*tuoZ z-;guLblJO<;TuJ3NH6TP03aQnns{+xUx_bFYb^tECe-zKcZWrXOlFy}E(N1xpi$iD zgoqxv9X&C zN8!UieG2IZ{Ym3mmnD}Jz<+S1umgle8KNurUQ>WI$dyz^?a*JuY?-Wacp zM+3D|3<{Zv;WCZ8nXfw&Bi8Ao?qtFgL!;riT9#WL%{D)eYUTRSmbLDiSGWUOrpk-;Foj4tjB z<21+R)05B)AQ1I(fdQ&&oV*pU7P`vSR*IuaUe0>t8j76C6;2{xOI>{K+kf#iB2fYb zLc++U$J1i->Fg%#7|4&PAGfrvYjJf_fuyW4P%Pnb9@STO%$Z+mCV!M?FNe9BR1Du} zl$<}ii-D4J%WUy!W(?C2Ye1Rifx?L)#FK~veJIEQ`r;DJ`PGZH$Z77Zt1RhCi*1w5 z-VymJaHF=vjZCrP*E9uKRoIxvbp0=Fnr7~GDBrsg)B_Fl&aL{lsL<9|dOno}Ze^2K zolN_O(|2P*heFcN9Nu^=flh=EgUDb<6%s3jQn0AE>gY%bAX%hyRo- zH37U8+t{c5*{WlFU$PW4&AWf7ur5=-NmoQa@-=l-E7=|y7-D_(hn32vdY;=ee{V@+ zMfGB0AvBw5o>5Y|rC#g%9bD8(K9>84t7$4ol}OVQ<=dl9?sy{9?rF#r%Dj+>#^6$o zK@sI;!5#*-+OkRdww|&Bh0*}BQV%DX3qLhzxQf1bq?kJ{kSoZ zlC11y3sWeTjqssp29bu9oRQ^;q71=6i3MMQ-kBshT@FbhQk zi3FO8qylTL1fdO|oaEUzuT+rCKVU=OY7Wa*sr&xZ(72us_J6Gi*FEhqKU`0!Fu}Df zoHVLKPdeCKH5M(h)ZE&a$Gp@RJd?f=oc+>{z-o|wA8VHNT?(50EH0b(lAa2PeI*8G zGo#yGac8Q{b)dMaIo zRnC)$sMi|MXivdbUD8OW~3QKGg71E0qyriX+Z+J#L>kXuQx|9sIP$ zt^~yW6IQ$q#;a=0#;+Zu(;Lrx2BTsT4;MTaUgHc06DL}G-#-$TD?EFK^i7Ig$|<3h zn5A^$Y9z(JywQ1lmk~srv_6Zk#_gbXz>Y|I{^H<)+qqT4v0dYIss*D>hg^R2jaAz4 zIbQ!sAf@>{!i^6Nk;od+BrSkStCE<%O8sRb+9B2HIpx{cmg`e&4f`fdUFFr}#3D>r z{<5BNU|zX>`2Rf$nP^(ykVk-%U?>L3o&AB(dk7ybO-b0VYt-OqVd~;wm2hwOCd*7| zb@;=#mk8Fy3#tP1RMobB^DixG*LWobbfW(oVT6t7=LDqe~<16p=*e$hYowP?wYN!2(lbk$Qbx{KJKf%}T;%Fw@l9g=gKf{nLY1tZfXrAoa}5)LN|vt)f#0i& zh*jM@&v3@Qw<<G~MTQmty|3r5~txy|7E={^rjd7o^d>OvT^&49-< zWagFF3)lhW@QH7nJ3ib{#9NceHhX+;Z{|Md%i%d;z4!x#vH$$u9&I{Y-&G!QlaI@S zpgfb-vs)CWE+hZe;5Cl+Xt_?0Wo2Wz3s4w!&4<0EX9D_EriH#-M*Gs(X8)PAQfb^w_@!%I5NC9D3qEc3?gFlho!~?Me8Ve z<%*#4Hl3&(I2IP>#ZE1scMhGrx8)2iqqm3wC9 zzkiRS_>oYwBi+O~hx;V+=tz^;^_B6r8m71sV`-&Bvcf2*RNWF>t#md0D8>KYrDTM! z_%VeWy@t+_(-BD=^2pR48!(AFgsmX_LkrQ@V2POxs+3G^NG5fb4g=4 zBkv#Y9@yWpU$L2J=&s#OHQZg?@Xn%6e%!V@mYQzmWt_j>X4q`~gW zz{{#Zn6+`{s+2*GR7uF;*=73$6+=l`ii5x)N^K z(zv*A(BXc~dFv%nv8dv~zpAdg8I-dK4CQu~DmGF&SGZXq18_7{EKDliS2S1p{vzAz z;mCzGK=dp7*M?!KZRFU_>d8L(D(!TbNzs;maMr(ab329WA@h{!Kx7~c(V+)zJs9I2 z3i&g(bdo5r(e4i$(S1+C(#d~=oH9>+FMzh_G)G(5}vm5Yu9m9;Qg z*{DE5bz(`m5z%wIZ=~lqR8fi=z3&%OB69znxqOi*@AeSoB#L`4RAl?~7t<}@1B?g0 z%1v%Y?xiC3+!&K!N+Z{qo#?^A8UX^J@RgTIb#KUZM!*;2=U$0lmxThudF0w>d$B^NTB8S+jug0%Kh@LH;x5ZG zbL@H{vtRq|uyn#y;uGq&C$bogL>Hj=_=l}^d^dXkF}c6ZP4I_q#8d0_h!dFn43BS=7lk<*1kE9&Ws)ub`FOtf2-E3gI zu=orDaT;x4c(&0uy_ZTn+!lqTPx^NJ3u;dav}wON6xK9Sl{RWTCL_;N<|9hjiU*s2c6%;(po}6%?^=n1(bD(1U2YvB;uuLhD6jw4SoaPvN4NEPxH8v4!V;l74 zbPr}EGNGer*-et_f4BNC(vO`3{%GEZlDW2L^~o04AAzldoLO9TrX9woSs8Q?k&h9g z*%XWq!vmX-?-~B*G@2omDT9c)T1=M9l+T>((6+fAChE)Rs36ez=Pux_ur3OEI)Y4k z7f_NN4GT+>er!af4CMe^PlkKk!?|DV_q7daVxsi)?4m~YvXKq;Qehr|nti47w`|u~S}jLH;7M$zo)nBZe;h*lr|r2gYcg{h zdgfOPES(|GMl@#B1$z-4bpl1j=Z-?K0aZtHU%>)JcfeeUVmZ~4{F$}AMYPy1jMcs` z4j?XH>o`<*@fjp$8R5sfW}ZcDivDg`vXT9p@dG}1=^FS@%^Bc|urSm<|A(dK^vAQN?PuNFo^IRB7r~>dp^ojeK^5U%)(yl$TMqmg;`aE2<%# zr;DW0pjvh09jUcMzG%7O49MCa_TX>Qtd?Km-^G9Ytk4@#_+{zueE!<_&gd`I^jeEe zeBe=vp)9$NC{Lyts9ah`@*^gI+?p`wo+ce-QTtEzOIlIQo~xkAZwh1OIeRSE7AfmB zONF;NWVJE%Ho$N&j6wARg%k8Rd7;h_AmUi!3+gHM^MLg&8}Mz%r0lriQT_E9Z_ z&V^l8z1pQ^K`7wgH%*}Mi+FFu<3t!laD%-uGHbU?bweFH^U@f0vS4`Y*l+PzrDz*| z*jqU=X^T8XQ1_8u5s2UCXDC=n*pWz0M@}f*+^z2C^B1+16b3ouzOL(*aTv!k?-q~a zM!N&6hzVUL;;Eex&ubB+p;s%h*!?bAg@9wJnNi&awzo`&%UAsVA%5(+1vw@i0v$*T zT_Nat-~S-=xGzD+Kp*V1vFwM_YR}=y+7x2J%%y_zKoNbUk9`?XN^t#iq3(Er8zL*8 z(lG97dN2S)tA?eFUt>W2^1k@%MN1D%XXW|vsqy*sm&Dt2Rmx!EVzh{+NCI> z82Z!~SyAOm*%7#Ng2+$+bJ7#=5nL35Q;9$HsJ7<3^zeurr*!@6aDP@koy}%6euTZa zS+C&%bvJgQfVXWJU~>iL=NyBcHyT01&n?;5*jPtBsGIOIYjM0@9$b?wh`L#+(D7Wt zIw?E%iDaobToIb)4$Y=sK;+FRVlT`b5#tN$K2$)$(@Qi_aXivc1X3Q^NNt{%$_g!H zDpV-QMK#s*_PyFvRHQi-yn!t}sSfUlQUGaM7t5oIXF%ww*sO@pQd+%!Tgh-#S>Wwx zq3zU`JcYyJ8U_NnNA=xoCEg*vf2jV#EDno$e=IPW-Z0usA%U46a(G*<;+9K$P}n3! zfs&Z@ptLxD+NqBBa;Jox!}4uX)z~JCb*FfY^6(CDKq+YxvGwOEiv?r3k7gl1sj0&;8Ky| zQp#H%N#9%MRBraZh6q;WKcw(l%-aX>w;1}lQ~FrLBnRWynV!lmtF@ofXLaaV#N7q* zXOy{~RGA(fYsV2aj(%%iT9XA?rG)IoG{|E*ohiAQIecRmrkBE|-n*K85(@f|OSwp1-Bbb@3`?M=Wc13RODp<9 zNU7t%00=N$B&$T1RfhEKIh>T{|~^gPquVJ~Rw;SirYkoJmqer;nZ>fLpQ ziC1SsrJn!$edN}~UP)|7JlZc{m(Z7D$&N#4X{PUy_gv>9?OV0=YT}zS;ewBtLf`n9 z&6vr$JHma-hlq-ct_mQUX24Afs;VrX*wy}IF{tMHxmsqy^-7_sS{+UM*|Y4;vgt1ubqZ^%e%)5-Y;t_6I&UWHQf|Ac z0=mkQN;%HIA?Ib<#obNu4B13xcU-G-;VV(<{wMEuaElsF)#P|EgA zD6;W`zo)Mz_dkKxr!2Jw=`UC#^YOCLD`g>EWifkd4PFz9bW3Msd&)FiKwYabB=?Ci z#Gg$?7PwYYUr4)TRK|`2B&YA&WCXC(Ss4(S&~vX8dCE-h`A#c|asOBQrsD!Z^Lq7F z%GbGkB@O@0gbQXJo9Zuv|D>?XA(|Ri1{veD;Ey2%I_R(B8$eON{i_Z<&r+@ zpvpj*brOkz5nW8_({HrG^Mc)ld4g0LI?aE~=+sh%)E-n`4BVPcQPryEz@TZN(NL+j z9CB7pnu(T&&@usyVf^L0rko;~ZY53g>gie@EVZt{q#B6wHz#9|x~7u=K9V%gYA=}G zb!mX@vC5pRiZXqTGcy&W`NiukUgz{S}qwazisn~dV+^y*~C>IAw(kRzD&6uk?^%Lu(|*xdKBTo)beh43uV z7b4_}QS)WgvRk@hdc?I&91K27M0D%Gp4Jv3J){8=4uoJWwDoIP`ywJSdHPB}2rM>U z<6HJahDt+#s-TVFGH4#4pxhQ?8|8%7gi1?0g1IU6=m+{b`EuvV3UM>k1Yl`jJ=`H} zU_>cKzHnhg!R3i-Psr<9_FH+yn(h)C9nG76FH4|K7?&&DsWi-;Yzudk4PE3?I+OIlS8Tb*;be^BIlh9{3M-?tz>Yaq+UU?c8VWV?$ z3qdD$9xGwYi+e&^roi~33MAm&CudI9D3y2?RuTAOCH$C>< zXZayA|iwL{r>@T(?Z|JTic5+vIpHa{T7#yOpZS8a)-weal@4fBz-q0G zq0LJ2>MEb1sH^SG`?a;$_)gnd^FdU<$Anj{0e|$k$9jpQf@8!9(U%E+{l2<-_zZSY z=uAr$c4kVk+s00c*j0`<@)9_7d|pEP-~G+z%tFA4X0slvPphkgtd*nseN|xvx85qb z`KWXuUV6oG4m(de0Uz?Dl|6Aj!&jvM;Zn08K>kopPV*v24bB&^S*^Ql)QymM8{DAk zQ+8p1!T2>$cip;Vt(r%x?`O5+uVXuxw>{u|7jF7{sWp|3?noV7>FQs?-c-jQcmGd< zw=K4o0QxE>bZBf9y86&-$0VwLS^i@nb@-1n9_4zjO~;$k7A`ny`(1Ff9X;%L^jj#@ z#Luam!Z30x3aoS}i~6{T&B*L83fBCx-SjIVs^~PLH&e$*cL?RS&jO+IJTiw~C#4ibjgeO6Lv)>4(~UayshC zwK&X>c5uyfRn0%D@sz0CIA+|Y_WIQ)XpascK)lE6PMdDFAs9a{UWR2LO)uW0I#k5x zwa&sqDj1KMC#JaK`K|=Iz8=EcGzduyOpZv10BJ_Ryi& z8B?JIuh(Su-?2Z)!Xr48s0Sk!XWEE9%7;-ZVaZ0itFv3V!G0!>ObY+vJywYKl%hnH z*80BGg%g6`%2-JM05_qiw1NsrgjS&rvsZ2iup2c_-_;*cAqf7Ge1dn^f{Js3D+sB5 zL%FJgP~=NAK$_U(MFY19vubXGWHiI2YmMlM3bOhM^sEPFFXivATXWuoLGE_M7MJU1 zg{MEPEmwcqq(Vw({<+l}Q~xd^`joXVbp zb>{nv&T{C2?cH(`e&*9bgu}Wxk^Y%Ssxb9yF?+(y?2>Q5Y@J1wr@f zi~KC4@A-T0>gR#4!1}r^R-&FRIkz~o+T}7|H?p#3Soa6|FLcm77?oVcs|c=lk{y3- z&+)Yj09}lPFF+Mts!k5G>g*+ME3a}D3ylQsq30RWI+1cp2{=)E#TIJmkiD{1P29i) z3K^}RGc{yy^O^BWP86gpuS|l2QOE)c@=sN_ULt28HchQEK%)6rE`+@ZRXkE5Bfk7W z9wT%%6l06DN%7diY#7q3(oh2K)ua^n%!r8;{g(W1k^udvN3GUNH4z9cJ>EQ?Ljh}A z&RkHg?36YVyo6^EnpD&1)9s<&K_?)8tJD-s2L;xIg5<;*j|=+buUXamczB;LQxfVN znaKgU=WsqG4Mx1|fQptgSodwIbCMhLSs@Z?cFyfxib z#?eO1djidpaP9>h&Y}m=E_|?a1|CJ?ScqeR4fXRnf{Rsb=CiAl;yxkoBTUt+u#f6m z=d*4YqObGc?<{=01x-qf7W2T3_`7X!o?M)-Bo91irxjiHMtyqyI$R_H5z>3}k6Lyq zY3OrFvQ>NxN;g>wowLSy`Pzx0Y-UoeN_029 zR|@jLVxwSe-espFX>&yqMwvi|32|A5!4$SAlc4Y-_$&SV?dYji$30VEzp9|Cwn3KzLsbiCSwL5PdyjKdZTU_#odKKv2lR+J|OqLK@=7XAcR97~3L8CeTm7VPisZigt$G z+8|i5JpT5}?5y&8lhl~*6elgKb%7&J0}AEfHIutp9Ia13M|9d#jiP=>o%k?b8ENrpTJ$!e{~MwzZ8fDWp8TqAwd$=zhn)pgzZz3vJJ)-A ze1-5yLE3!5?~Sc;YKFMnHtrxC!SunLHuUFqsS|dM{b|}4)iTbBE*o9R&vGIw4@^E( zEGnz0>wND!FRwN2s9kMTCN4{!JtaNwcLtw0;Ce|ET2^U!2rQqin(E4UCd?fKJivyy zHEqSh3vy;XwIEoQ+>so~ai}jdH{`>9s3h5uGGvILhEKi*%8ATD`KXpLky*mHGWQn` zQ$VAOjj2oW{Dhlnqo7@`HIqzgN9)~*ONe6ptkABAU#o=hmBTys+6Zr~HKS^HDno3> zedq%2xuXF8waJ#2@TVb8-_cZ=Y)=8j-VuON0FkMbDGmKS)j&DoZv_l#A_djt_i;;) zUz8Fst-qGNZcT2-WxP*k!WGoyhce<-pe=8nCXI8O^!HtGnQwksxLfZTS$>JLw^?C7 zbGzxCm8;`7V$CPh6HR?pvJ6!CEWAC%4NsY~zNXg@)}xXOXQD|kn$2NyIZwQb^Z-1{ znyxAUKy|g9vfaH~#l?z9?DTL+fuZ%s0B%@lxwD2Pmx-E`qkf!vnEdBCD7m<*yS#2L z{IN5U5|kTj$7$o|+OfEHbNKW%$<9*8E7S8c@3L|-KeT@`FfOuqTi!=4rFov49!?UG zNUZ)%%wEFL>*z1U#;|AyKy}`@;`y9j(PW)eY7{zIkv6I&V(BU(;=kWO`)Y^GU=(Ia z0Ih*y;c_>QI47wnxNiE)9G9AFi`~qPf+rNY2KG_pN0P+dhHsTBmE4_?wZ+Gw*eF% z`=-3~LvpRAb;DbpPMrrK*#FA9O+3^W?vY&T-8yszw@7~HCXFdvG?aBKZ$y^-dVtl- z@t_J+A~O0=l5!Eq*IbN$Sm5szdvU$=uT&SOHeJ zQ#Ku`j(qpSoc$MmFIroSgm|&_=B1Kb@Ts0JXXNcOhDT7MQr|7g3QL+rY~yz; zR#T;CkZ_CE_P`#UP-uWp=HP*e>nFDp3J*aJlT=?A>8nRUuDF!Quu+?0G_X4QjVqEv zEkIsuB@TNlo9kV~&RE}+WXNrIi0*N&ioaY&^cmEWJ?bIy zhNQ$)z%&-EKZ5W1Q0K+8Z_&qZHG??7vgW~A2G***xm^n{E^cS3sGwVPuq=5LzicXi zNlZUrO82>q>_|<(!AZ`LF1fO^grM6%lTRr1FtT=5B`?)&+&HedZhGXreU zqoW_(d^81UANFrnbIAWg3VxMGg*{|G;U#?K!qA9F8^s?H%ZqQK-u51a~Mn zt-nAlMAG_Uw0doyKB<`(q?Fp{y6DHMud1p4IuAM_E*9$Uyg2vDlU}jcg60n%HLrn$ zAu3ib`;oiqZqB={a^eHSs+=uWo8yM>zA;f`-|hIdctF68@l4WpE{%fKd1Q=Pt!M8X z2^J4`BhR46Im@RU>LVW;N~)1OS$&s!EX)EjpL`==q)%DUi&&<*wNp`Ki5w9ML_`*; zFh9A5?_d1doF@?u#kMFZ*AN_@BYlUn;|u%J(Wl&4&FJc3sJI+;RAXp*$E|Z-f#Yt( z(uylD$O$}Z*PlL}#7Fb2Q-k!#<1O8D>=pCJ4!iiG2hde@^^u%Ot=BauSW0|tdpbFEjJYLUu z8mazn(KgC~=md|8i$Axs_^npY*j#Tyn1L56F>Hr6iJl*>kb*f7QY71r7xXQ&Y@;VB zQIDiMnv&Sc&9?bvL&Iv*<#anol)LDDoPcoJF3FHvg-fXDa)%~pK@2@*5UE=Dw)D1} zc$xY-yrGO0N4=`JUgrll2LH8fvXfwpJr)0Zu^ ze88r~5Q+W;<&a6rTZVd7dt1)rk7O#P#@YKb;tZtoY2#KRB^G8uac}RijB{?=YSlsC z5^tb$#KGDx+^RnpkE z8dBzvpj=@|aJ*#+RWf~2!7sDAZF$RaDi?IT2z^Of2}{y{GB6T8|0BTSCf)S#nq+dyLDpL&+H}Rfmz?&0C4hxaQE# znrm&hpv-Nf2gyx%er|;Ni`v9nzZ8Th>8?w$LgZvAOQKpA?%i#V#~Ll7ER6u-EcciW zonOk&eHyU(_(UxkXsHcW5fiR8`NDuOtKpn5U-}Qx7Ka)Cf4*P7Bs*CEJgQra60)(% zg!9lk=;zjl2$mVswB~3#JpZFjjXe_L#XW~^E3OyMGMMueqRPZRbtl0vjGjdOJ*C_bTLAdCOx)z9@^`O%-lW^#`IYa1u4LztgNYIO$Z@iZY3l|VIC@P z=t>Q8zXStqoy~r|mMKC7bJ?Le+kwA&*&g#9%?KcMRD*u43sIrJLdzqW%kUbW#JA@A zf^KbJw{_v0_oqKD(27w^ruedr}IbDoY!Nzc1w&Z$}T z_Ef%Z5)Lz%AH*%l~~boBp;FPO3gdS~l<6qO4T9A^gkM_aZE zfs@QFfmKhtw0?#Ysp7-6C^wWLgQ!Iq-A_#GH+J)&lwIVWemW zp>t15Az=-$SauSp@%!dss8uHf8Sm3dUwaf2;fJ+#1RfDv(=Rt{FFu{(QAT7Tk}|<1+>jn9?;d)h$KShukb#Vs+m_`_G>|i~mW_8ow~*vE!ly4JhmVYh z6<0N)FIo(ui<}EA{T#Dh6=L09S=#x&KsUX0E<|2?sW2^sJe2Z8QY?JzflBa$M)4Y} z_*jU+9eC6s7Vi6M+h#$wuHHuM*#!x4m3C_uNDLAkF1Q=p9<5{Q9UDQ^^|+zxEM-g1 z0bs)H*I-xhjQvV_a8-1SEwoCi^16WG5EJN zgxh@FZ72PjqaNJihTzOvxsG$o%+YHXtea!ZhEX!*g(`WqI@%(iXXM5;TnjEB|Hi$! zcAN4XpBIF|=w6VB)aqX*uL$m5u66gA3^}ABmP1L>k|y+5$LpDSzj2*kmQMY7X7RN~ z-RHR85^x#lo)c8wcvU-;goNer0P?;K)&=8O?Z|amgtECZ$}*>pmE|Ftq$MS%KU4){$qVV!3Z(AdOZ*UI7O$=}AtW zO1ZL>>Lkyvi6JR{J}B6I<4=*$3MsOAu><+0v$aRd`(o+Vv5S4XPOl6mz5F{}Pw1+1 zE{=DRPAlU(PsH6lRejs4w(oZpW4rlKA?finbTtZtqDgcXqq|J-npJKh8L;&@owgh& z{Xmn?_s@hAWgK5@{DIqi=eW5M4e6O~FEYJUDo@>Hm(d)=t0JO`j-3P9d6=8hJM^UR zS?jJXNH66m7C&c65$ad&Nr!z8j`i+4o1$8WQsNoE=X3Xkuw1p@nT2TUUj64up7W-{ zi<#d7!G(h!+;IBC^Kzt3L6i-@Ai0D-r=wA7;3WVZTs70%a4xs|cE790kkJvo?_;yN z+!`I(rRJaZ$#nM^Y1u}vx3Ea%gt6mgedMUPOHn9C&q9Ltk@WL4HqX5;dON!1&B?e!WQSQ2>EeK_ zE;%G8nG$H;&0j<0+RY3c5rGk2S<k0ZCwJGR!D6>ZKY54a@a+I4Xj6(OT?E2mz+wR_^O#lwcL28js%3 zNteMft6BwNRrZdbcnNr zQk;P3m`G4TD2Xx9_%Ww&50!`aD%xfO{_COLOh4?;Be?FInvGCrjD@f?Ij^a#w)Asf zv(7ps*+h5r88NPfOIBt%vj&LE1gQLS!Q@g&6L);c%!G%GbHJ7@<1g#+*LIq3lo=Vv zXJ25C^f}0NZzRT)uq9Qn$BQ@RMUidjjQ#JH4!6g#l}TY8nv{zAx&n@!G>FsFj>L2g zRzo4+muUkokj{uHM(-!b#f21^{xKik}1Q)WeVKR=^fV|G~Mty^L$Z_d`TS< z>FJG>-j7(gV1IMu{^glNC1$Se`$2ThKi8j}DAPK=PFb)IY4XsGZ5omXt%0jf8Ph%W}}ewi3=9G%&w< z`dH9Z{{08}eY4lpNnHtiOAox|@4klPEAYIe={ZBq8*T0Z13<3*(v87>K*Y%}HG~?6R!v9HbI7ob%VLS&m!g53k;h=PGhaTa^<+yoljTl# zxrOk9yBQza1JrQzS+q}sis&eQoGFnxnq{~D{7yA{;EQ;YHtw36;)R_?q&HfeNOtO>*W(wQ`T`6iip2>?qP6~GNph8n;ELrYn=7={~s?I zK!~c_#7LEqN#$Hq8ktEHrT-lBP7 zC>=9>g_h>+ZZwHo%J^BK1F;S0Plv{;Im!S0F5Jf?%%^JbD*2~9*t~&0x^7fJwhk^; z<_Q(QNiH*$E3sN%3`aK}=nA zU(m3kb-EzD%7qsLzdlRBSTlOhU5kHCB%6FdeF%jblGA}n_!m2mVocqM1(_yOH$Tyo zDsLM0;>~wK32)*J%shI?I(Md)>HK}NMxMcKs3vrW+;h(yJdvdUS&G= z=E+EW1Bov%D^W`6Y|1v;9TSEk4c!M{6PxW4orWl<{g9ASaE270mu2zlWSTHr+v5W? zxcMX#AtD}<$i!M)?K`q(f@G)wZU;v;o4gOKOtK>M)*9`qV|C)z88Sg)NIOlH9s$Ss z9M&nV?PrDd#2$YE{d75<`_(3Bv{G9zS+A_kOyx^~jrO{WRj5$etDH5(tuw zTbt(fVr%zi4lkTUG$P`(3VGou$122>GUla}4d8&BC5>B&-wFBB;H&e}PK7hMK%nsY zUS!dy(RKasdi9Gnki@36AXT!D7bPpYK-%cSZxx2VtC6h{EZh`C1?iaLP4>#Sk0_`> zhYmTnWtymlY~Jh`Wl772B7+Jxc8ztR`o%_41Q%4VZ-9JUMuFEMQ$!}G0-@I`e$#UE z*9vO*?y-HuHFy(n7T58KNMSCSTc1oa%87@1xBFK&_HTw8S} zB};5YQ{0pdK7GBk?~Uo0;}bd_%UwuQ!mlx1Px9%DXVkolFa7ze;LM#B`5lmhA~7a) z?BjKQ(2vqvAocw>A54ns+k%dTG;bE>UPJX82s3sTo5IyBVuv;zBX8gREPX^|l$hE$ z_ek4aM>m4(^PU&M&qBFY*-31WzG3)zPe{YdhZy>k;i_P9W{$SQ_&qpJ%t5!B`0F{~ zu$RWq3cbu!*!zj)o`T)RuE5Is%pbfcv~Hmul`{{3^xv-pOlbg#$}8d1%^pNx)RUYN zp?3h0r%M5y7=0@D_M_kQu!t9zG*TLo?6RCd;>*jnB47LJW=biwVrTU|rDNW_)QRWz z@?&Xh+wWAS&rn7_uoZ%a_S%sTpPZIz>e?_k+dAWJM3`2J_EwmbCk=Ac{dV;=PKsI| zzsEBzvvS{soR~o}ps_oF*IUg+B@tgEQS(5+>rxaZnWzHqVD)B2* zySRZ`37U0A8yDDSAW=&hmXflF&%&0Obj_WPNilCV85uSivv)ooE))`|7&?+x_zqqu zO1w*Y^D=TQIq6`dIehL4TTmiRoIlMwG#``G@mM6B4h^Pxd;dla4oDn~QREPkG#Wvw zzbIzoeyrND5@y`WXF%^nUWbx%p$f00Krq#yCI%{6!p3V!r$fRMsFS_r9H4Ax?F}o_}|1D0p zMc@}CehBGub1Gwhc%jf~lko;e%bFK#_#oPJH~H&LmP&zwMxP9|>6@mXw@}#ISj@>O zMwo^?Fx(mZ`;qyBi|n-r-%F26V)^jmd+I z`ex5^HXNlXY}_%I!dMuS`g-Um9E|20clU|mV(GEY} zcV684E3Wf@y)v)Q?#ZRUmTV1A)o}4Q^0JPdmDRSQWi_@W{VQl{HaLNedeo_p)m2yL z>0xO;8hTS3rCTQV9TDfp$N5A+)Pn~uvS&-s$J7&MX4&6uNyB&t3rPMM-w%s0Oy2u0 zlPFavBICQg0|L5QaigXqbS9?Ff9GkqF5eFL$OQuFyEE!FJz@+c`LETHFlpZJ#Gz0W^n{B5fMnlEgYHqo*3UdMm$n0L2l{ZDyH-(kJJFV|Cd zAvMN#S*-{;9(8}c#`_HRmjkaSYhMMEKX3&H^vCN7GQ?X40Hye%g!ca;rw@h0JV;2F zE1msf^NV#@i%0;+EyTytgg0`%wRNPO>&~?SY(G`&SdFVJ|I56G{mpb`%W@spQrYp| zroe%>9NQhh-^~QUq%T~l52Y`l@;r%3UePu>T+oOW|4U)$ou>m(A3{8#MhE`ZZ#xrP zB=GL;)SYZ)A&U*55hHX)N>%V1PCyFU3L=@6_kOVunlXI>V(%=nWH^2B`F^9+pb29^ z(L)Fi+Er!DmqW#)2Lz^6b}YI-u5Vt@wv>{>EqBnOQL%a-`3xVVyz^yaxg3v z!&PzQ1>emQIQiyM0$|42GcLzbt1#5#Ug%{}zJu~BngQJq7JA+ZS8h;qX;~7`_{Gaj% ztN!A-A|8=9wqoNuz0W5$d!VE>SV;Mp9>HVT1{AU2W&=iJ=4TJR%JPAN{s!(Pus0W=`fw^nZAle)7p){UbA#@YgS{=zsP- z(J14StQU@I%hGI9#kD5D$pJoMZlY{$D+_1*DObycA6m6Auf_(AW%}#w{@pv%&7sG_ z)28fB+bj2!_^ zuZNv-PV=3P0=WL z>fW+$+V}h0X|vD?oU>(!&P?Kua_iui%i#_x+CxP!`IyZzMlt{e&~M3~mmif6GH;ww zCgsfyF=yMT`7k6QKYI@5%Yg8h2wlM|T^=_>cmCxOXDd*vJlR9~=E$|46JMRWnzTPhvzWJWYfw|TkPXS>GS(1N80Z9 zh118E$2k7IuL0u|v(Xo#+w9Tq=e0S>-IDX5%_J29jQ-_kg*G#Nbb){Kxu?J(LJ!SK z?a}xwj*!LSL3Imt!v@hBlypZ3C%q2$CnB9U=yuorORp)u<;E^vx+}S>md(rj^Xzh~ z-LHkAOZhAR)3`K0si%d0T@?6+ZUnC9A8o3-3Ll-?>$w+)PhDLWp?JHTw-IHK%aXs> zeQLb9zP*ON4qu7@*Dyrj8F_kj{@UU%Ow%&i=xRTDlIzK7V{7EN8hvMtMsSU9LD}A4DtPZB^MdOIMdzM=BYW)13y&W%3b>qC^x!i< z#DqvFDr5*`X)54hy-0^`UWt>mAv;A@iFCu@ntqyTj#rbHq6sQGwF z)cC4_O`WEx?OO;mA z!FLm{|7l`|4<7}ao3lK-Q7hf7J=M+#XZ(!iagxuw zJ*M6f+|LNWO|UyVGi&x;J^MJu{54a18b|26XUvfQk8-*tqQDgWcS5+^ju4{l^1g4e zdt1@BPhXwiuo-4`RG-4kKny9%=zKtURIY;l2o1qf*$%Z$aVLaBJL{(u<#8vMwT0Q# z3x?6d&wz^~l7lE*<8l$g#o75tvCpy~XEpS=bk^MR>t>j5$9EY0iDaT$DKbenGW6UAS-YuJkwsn&RC zpUeqP9BFr$#TIz3lTfnOfh~^qyMn|n3etgx>W}S`b=;BdQR~i~^FjtB$w-f2>9EZvaq_%vd zGs@9Gp+u}hO|7n)0h@@!RgYRym$k+QYTwmeM=VYC87352aQxDku-ZGXuIQrcIsDta zmj_lQ*>_76M5jT6JKY=0xm*zKK3N6|;Og!i};4@O6 zZCbK+$oyh?Y-VrnLN&QviVSM5dA&j5wN9aX_{XdRkFL}XG2|(e)M|?RX`ulL#wBhw zph*Re%&fXyNsgR3?J>Po{T(&MfvJ-_r2w~y?qWbia!8c^SW08tXZ?&KHDX|B+U@d( zqir!pHe}L21>Wp;ZOeeAu*cf*oer0R29tfJ4dpDe=1bsw>&PIciRdC( zt@%C>o+Q>;`nW6?ogT?ryTOs+6|Adp3trm0xpZ>mP2NyNnaddu6D4AqJ8HM73)Mu1 zhHFvljE%e2@C{(!Tv?+PsYv=k6#LRNm zH7O`9UuK*f=c<~Sfy@-qXL%Y)qbfU7a+uO`#T?*cGL3wXMfV^ws~8NtFk+nFe2k*) zy3p8%qIdBOqX+S9If~11nm_Tv49L`t&JGn)0GX3W=L2YCBny;* z5vcz@99QG`?R?TYohN5-l>H_f>SHj~G_~pux_b2g$ww`b0Q8eUwEXzJo@8WJ&MAw_8YG}7)Q#Cx`j6Ek6tV zkzU-X(1pEXs)D0i%zJh<*tX98ZV z%eM1>Y(do2ZV$R9)v-~`tLd*=ZEkP-jL_` zeMQ7*rV_4O9fhzoa4N+%l95Xl5V)aCrb@A@56+H!DT%Pw0hM1dVCO#W85xJ3vc(rw zX;2Ehs*A?{@0Ihb0SW!k^=7+;V*N1eH``EcEpm=Rd1D_Xt96Q$T|A(x8>4f(+Fc|o zb%Ml}EE_@%3i=LDqn?F`NygQ^daN=0-T@;Ex8Dc+lTD2nTsI|aJ8Q3I4y{;cTeqvG zmbO`w$W6<~4RmQyrE7UY{wi8l$W|lb5r>p9=tayG2l*kJc#m87PdUqtV^0DE6!N~E zvc8>e9c$&1STsKU#@cz0+Fsuf|G6doX+my)GP`D-Co@0c+!z_ z<09XQknN<=4s9{d;sW|1{1461gl^lFSc^;xoJ+=O{>YjI#(9`$Xvr@Gf{hF-oyl(TEx_xW z65n}$wW6~f6!Hubvg9t1SG{x5f3DZfwXF5n-k%)cQExlo^pDWK&~lOP^IWxA*Z3*@ z{9*Uh#Z5LaRE0nf%X#xp%;7mF1*8={+A-AW3_Y&>tEOr5(KBa4 z#Z|r)9JM zkEW`<+6z*%Z|vDA)Av$=M>`h_F5x{aQnpW(xW=oVcq4~{P#9Zn9a(SqtfkeThy;@FdURm^Nft3Dt z3($=8kafT=N>EDh0$T0>pR;YU#B0VkN3p3Bf zJJPv#m#A_i9b0y9=Z8Qcm81oWjD_r+E+(Z^&GvlBBroUWbTde)L{RaHrLNPOi5Ctk z3vTOp$n;SqB5dA{E`7buxxltQb8B$6hlktgbqzl*v3Q)A=@7}|c81%?`-zZa*si6H z6Lw6Vq~P)MiZ^g-CW^H?FtxOm^D@wP%M(pG%{eb@YdE3e<*?8tK+E;XrHPjoP4i#% z$V9j?O|<{8Zt$%RPz=3c5dXyU=d7f{;UGtO(Jf0DZyr&}vAm>XIU(levhBPVwUm@X z&P<*pxA;`f+ZU=mr%Eo=a(#Qc%fd^4w$&xxxQh;trl#=9CI{zUYTM`eY)0zU8{JPi z56aAZbD7&!!*z1W>;;ETZ_}J+_Vx11ze%42x~)0Stb^AsYo4yybT-IqQ6&~sKm3VPvIqUQ6 zWF4K78!KX8h?tr9m|S96V4$t{;U_1vqgvwuE;pN9p)Qw9CNjI|$GR&nN{G-}gdYX6tTpa5T~qVV&12r>4R7b7DX-hqj`T%M^#qmpoJc%kF7J%#*aD zre}@YDnEy=4E8XkXCc77``2WG+yXD3IcTv}I=w$Sz`2` z$!NkPwbu(w94^gx)FWnW_^75rVey=Xl{t0AGQ@iCG6;**98=pN(xTrqXmCcjZOjzrfy1~p_^EJn}L%J?2lT6xLPPBVY3tc0=EvQ@!cua+$?n&3U z&Fgj?`lh)=D>}C1--9h&N}pYCSx?zH19+0L-{#hP^E00ZL>qa%>`uzaU3p;7DXkT6 zw}E2lIdg;<&o7;siia%^-e;V$gu$5E>u65mwv^CzxARG#(jrq#E~a*Fm0Gi4!=X!x z$%0d34n+nQj$WH4#{mK7eC*pEC}cJNMSp>yeK!%Fi__8O;mJpQnV?aEDoMG7vt zvp)6;aybfm8}{kAXo^hQv|`Eh)%p@gxwRH%-8>a3uu@3knBgQPg$+wog(q3Ch1CB1^b6ks}_y0^t+5S|_rAyZ%;K?+XuAm(YPgYh(%={O$MQMt!l8Y8ESLftO zCnn}3djszYRp>~WW~y=gn4#18$Q7&3dc{q&o9O*t;`p+bmZ=j~fsSuB*0Z$KGhIa; z09w%ajPZIC&oB0w%1yr<nc z|N8cC&fas@%&b|nX4TA|t!Zbc10VqZUeO)#Mh{uFci5p2YKXUsyOo2-0{|jd{_p?* zm?-4$vk{{C(DJ|6L(7Mf=5me-Y{UEibp;^)gN73tuie? zFP{)EAFmKC>t>*C~O2zLn%2sfR>#EQCcY`2t|5;G+03zqyR;%kuZ2jx|lqeT?~yTm{!o52#5iI>|EA}TviNR z@)`_a003~MvRsM z*Wk4DzmiFk4cXu3AP;dT9c)Wb!gvwMQ2x#XNCpfqg0~0uA11>{Rj_l>E5z2)x3Z0} z;VRW)ROw3fzHw<0O=3Ig9;1WX>3pMLE;ro>6AsqfN$<%v!uTi0QtdkqXMcdXjsCDq z$Lj-g%oV;d@DKH14!Oc18m?Lm=9HRzp=qiQFpmdRe{XxeKPb})9{v`$H6^8u_kuai zz8|aUxc{y4x87eSgX5LL4gK(JnGJ1n$DURJ&x)M?hxFwxFFJWpy3F3hu6=%jI2u!; z8&rkmABH0UQfPD`gixjb+^oXrLP_1fvK3_qs<4+7=SJ}lan=t1y@?-`*J3}$Np9_8af_{?ZAWT^o<=W>Y*xZ1qo1$zx<;Gc`t)PW*wvbfY~aHttj0cgT444 zcG5mf4FG8VqMX2^`k(ZZatx128y`$uQ~W|xI`Vp6Hgic{MxXsn=0nUb{a3(r<@L-k z$;Rmaq<@AEDnBhK?Eeget&h}WSZtRu0rx+{1Sb@5B~<(?Z^|`{s*{W(lbo8Tf|>*p z+Jy2`f_f7~X4)c7+QK$dLS{O`W_tQg21!mP4PHyhHcOZOYyT^mq5d5rJ^+ZvF|fta zv&C(RMl&i)*$=P-QYa4^8L`P4y(JpQs2s=S5NGF`RGbR`k($X~`nL*z`%vZKiYR;) zQSvIH_*L|7Se$)oQgI2K<7?qTbLIa3FFpDz;EVv^$*Abgs0d}0hk}{E+=XF2aF?>1 zk5S&8b7)fVpD|7lNPrAA@chSU{5t^vfH_!2I5a`2j?Xj$<;I*=wAuMigyv!19)(mWnE^W;EXT8=g)utNM=VrX7^t{$)y}qY9EnR`ly!4Vn zEWmnmAsfEVDpPZgAN!EN~z*KCn;xtKR=4gG6jx_^*-b&0T^l51mQMcy{Su zaP%lquOS4aU?;`N%<%2j?rl52r(@71f;JSsAwK z5UBCXiW#_Zq)_mrF>67+mP%wv0lA5zkV2I7Kze+f7)wFI--2N=_KYCVgo1|7n3Jv7 zP>h8sC|U)Tt{_fDjj4cCmc2SL!3r#xH-6dFo8rM*&>N@nlBvMZL`|%L)Fb+#bC$oI z7t}+cj)@*n5S0zK3Ok5OMTHNf3Pgo1qXMGRQ30v4;$WLGRC!SiqEh9X)q+NX1*$51 zAS&nT@3YeOT>1FVS(*BXpI27YlgqOG)AbiM{`~^N4y7m1Fe4sAY^Z<{h0%D+RK5C?t8K`{#Q1_Q8kr5yV8L|agA!JBjNRBl2L)GVsM5K#M^hW>$gd9D1dqvvI2 zb}6SV1PU-H;1Xaf5Mp%UKc)K@(hy=HsAm8|l5Ext%^vDBc$tvu&pbe!OhiIW=Db!e zL!OC=e|Fw)KEC<#^Km}_oFJhB*$5Q+ilS`fk2wEQ1qN>5+)69a1>u6Ov;Y^X0@_AW zS1>H$&A}ujufYexKv_kL1zqHaga<$QkSj>Q|8H#eKT+EM$sq$*nxeqf)A?++YEh{i zIt~a7MA}JOkm8Ohj?N|&C5DodkN|S(Sri{yLH@L{YN7|OigHQ)yj6L6kQP*>qL=(R zC{we><<+zB$DrI2JC=*hQ>r*{^%;7Mwq3?R9rw1} zlMS{7VNjL7ZP6ZbKmH42dx&iRma;MZH&+mhtHSzF59BSb40!vO%m0DJ{TBv>{s#t5 z)xY%;pvqtfN+}A8DycLJnI7@8JaiIj*kAdT0sz7ueVy0v&*5;`=#;u0AZwopFV zue611Iv8{zbRH3O2syp_s=c6N$3+6rKo;;yY4IWgnAo_IsM0J_u61B^D`Oq1B*=;M z9yJlb<0AqXnOVOfNQLyuFZLpPlC1}FABp42;0EIMYyuccon7c6Pkx57EUzPFPYI)=Y9g&f)dU}SUEn;_lU37gzTYstA%Ik&M z*HVn8lcwjw;^RK>g23m<-g`z>(?T}KfBwiEE(@2Y6g;mGIbK|jKE&ionG_7?!!85hbR3uh7TuSIqB6<>OS?&4+P{;FiV zP>j>p_TQ_=7?gALgc8l4C*Nq$?JjsIw7D^8GhG-J^bM2Tw@{@FKsV(zURb4RBhsaH zR0qAsGYbptMM~&vz)h{H)JF&aI^9%^65+$lVejS2XRp??o7@r7`-HVZ&V6T)&>+AK z#o#1I>jqIQ70Hz2%McwCpu8_Sd-(d66M#Tq&$oLf{+N)w?)N%go-z8=G5adLvsX)} zu*j1Vfr8Oi&0EroapSP%UNP^gKDSob*%=-jK1!jPHk;C;(t|JzWi?_jw=6mwpyhug zmDK*t@jD^S=d!2CCpzpBr#6XGc2tu6Wo5sYEc=LhW-Yu$+qyqJXXtV@OfeGOl@kE~ zc+-aUA7wF$E;Cg&ZYFXf2;+pehmI8R+F&HQ>>cl+*xkpEFW=Ufe%W;B{B!-=>}l#S zXjGAbaqIEnT9H5`1fcV6CHJ@pIxJ*{4S0+S1A<;uF!l3n#E%KTBmwZ~D;&@dKTuqc zv^ShS+Ml4P1R4=^9XW9C_o<1bAV9G3-mP&wE4eq6%RRky$c;5dqdMc8YU~}lPEwPX zPD@!?R)~3Yw_y2Wz&D9S88YlrQXdFvocLo);A&g!-c-w00mBfO#9TkydvYsz4K8Qj zU{%#!KmbEVfErb3NgD~Z=NtU3rXK~~joR^s2I4_JF93`q0FplAC)G$WB;Z61AF%XD zB*O#%;-;NRKO_?f5IdVK1Tj<%PxV-0QHP;`DwqhG9{_Np@yGc{50M6r{o`I*k0?-o z>3#_y2F|LaZI-ed>hsuD=ab>v`&cU>G=3@IUcer=iur;4lgaL_%ZpKROAx_oo;2H) zuMtE6(;v%5CArle>WZ!gNG823x_ms2;~zd!^S$Ko;dv+ z6p+@ccqAaZmJtPjk>~Zsp=?7sNgzELC`?SR6moLby$7X`PV6C+g1WOP;}7JL;(<3b zI(O`(xE>@dR~M(X+s#T_qnL4bD<^#n7}o9m6|D!&L+St)ql*F>EDX`MTR917X9 zKIlu1@sj>qc|MN-y0s+g%malQ$)x4WJ(^Z#)yUZoB^0J_?|Kw7P_De;;AY1o;MGh_ zr#M84(F_5|M#sRz1db$f*OAAOVUa4FY}(msu6kyDbU<<316h_YTzF)WNaXZ8?_o%p zBO7XB0I)s+kY?Wr{5BqP82{DrP^+_J91oV|EIas(k8azzw*@&iBeK7DIrt)y(kxnb zr=s^olgX0RS?|;5Th1G#te>U?ZM^V-i^M0%gFL$`*Z8DUXQvmh{eN{!Q+8Z9TR;&m zU50@=0JahP!x{jBtrP%Ui6q&iZ|JMZ9v6&o=V^v7AB^$qjq^&X43|K*TP^{xWL3m` zypU!=t*?Aue+t9T*O&3DbpxpH2N*4lnKlAYfT~8?*JAOUJEwF*XTz?^V&cD<6$T6O zTZq3kWG(N@JKOD1%zBedu92@<#1x`F<(PVtE;#G}3GT~vZb)PrM+2f*=~xS-2xV9F zhp}zfL&|fEY7v6_+&mK1%8Y~L081e^CMHY8p+@a2X5JW0r(=qiaQjD5eS=al!Ct<= z2LN{IFx|{e9-X$=(<3Zr(KCWH+JIjt33dLNtw^P)$d6n_MP7Ng-LaKJ-SM*Xvd?9$ zV~W)oe`V&+7z+35D-~cFI!RZUgw-%ttt`ANS^zkwz4}G$F)h02bYpsf4W5i)YsFgP6c5=tza{>X)EyUn;1^}p$YNZ6J}OXzup28ZInq3Z5mFfP@}hHc zU@P)Pr5_C#UcRA&%+uln<1b^|NOp>6fzo2{2n%fhsR;qBSdw4`xZJBP+@sR+uJ0gG zm;yjf!H}G}><)(k?M|004r*((sBvI&3?nD>EXCBMb?-21 z+4OpDWhSw!+~mNsY(_f~xLuVusu1NATAn~|_IGh#&;w93-yUyK@;@2$xJJG)dEb2N zL6up)=XrlGh>3`~Q?gH(7QS#eqWK6L_81`9Ljuf~V=V7dO6<6NIOxV%5a1M!lb_fZ zpDQFMt{sp(uVob4C?y=c3W+P=xgaUB5gBM0*_I)C~fhkothDXoHW` zn&bM%ZJ$##_}7fvE>|I;e-5ql_#^#CX|Gg|?rOK_d==ZcF&4+-`2{mE47$4`!u3za@+g^-ty z3>1K+n*q=X(Mne8#99YnTmUcy`UR9u4G4@BFNzS5`gQ%&Pw8#vDxiP_!0;&?WTXkK z;4lhc=dDJRlu&*>LUvaz0@wx6*$)OomXR{_yR;kd^JTzQmwEQEkA{mH5s;d{Di-+& z^O?GpV)mp>f0l16;$r+-FOg)fQFckyBYwvD<)if=0H_C}dLVPa%-N`;JM#V{e(7yN z`M{CE$1ZWKaj`{j1i&yI3k=ar!;xAMD1j*(%%*B?Ej{a!;M*CPXE7t0C& zszeb1Xd0{p;skDhU;zdQ`~b+g&H->!%#{@Wk8CbGFU`3EnRLSdZcCyuYt&?7dzAv^^yyQm&0N&wZ|JR&TB2XWj>(lD9G zxnKqvhW!bg;XkG}wGhX7>YLV!gXUI12RIMR*KfM`h$GR)~C zM(5x63c5B1YHYCe$0b0gFdA>^9dxve*Lt8``30#KY;GGr1@Z&|j(q_7)y}c^5Z#vD z=ArA@w*s!i?{69^Nm2x4UN@D!>C4AzDscTlW89!(n?>4AhylD6IV9=5uln=xc=t|I zeA^6aB#1Ts1zbm1@_}&y(uEz20Sm|g_xG3p+&EH9ppkJum6;h~o2Zir(8|Wl1%gQ+ z05TAhmI5*>Oge{Hs`D#BJFrgFRU=(b_?SkK3w;Gg{u3GPPO|*d;Yez#4c}XP+CMMW zn|`ERwYG|w?%dJpF=W|gxp?0ueOI6LiiFM+YK~-`*OzDmSdyqts61b~{ydNR{Kw@J zv?aJy9LsV(0RmXop`XzJc6bn6etc2@*Ky@i1-DZWKmisfLB;K)_D>K7o*;R`aHS(Z z(oL;1mW^XuRR01z9 z{3cwGlLp+yIT0or_iO91w6A8%O$_24lrLg#P#2YFJ(1<+5n<`5W>&;kP0 zeIFNn;h+kq`<%W~s26%8CxLt`uks;T1m}V|-0d`6QE$Rg?tY`752^TZRR6usS#J1g z-Pd^n?b1sl4R3)J>ZUUlR=lY?iYWJ|e4G2hQ5D8I?~3)1H?azP=aDQSnT2W@xYE4k zHxeDc)44BnWQ3?R5w+Ilk%3M}NFj2H5&{6hjbr2mIzNfE(Z~X?A(#Lo3F-q|Sa1R5 zlY|^iAW}JFwNIq=ks3?TdPW3V024n(C(9JC^Lq>L+fO?3u}ONfCeh*c1yEn}4_F$H zIuSQA?y?u889EO`Nxcd3G$99R5qqs!pkg1|E?2={>SU|~U@06oQ8&t9cq)t+!^J^rg zA<%dP7!eRn2xu{tl2Q<&&FvkQ(_pTV1xwfpl1gSa^bP!`vw*Q1mXLU8o&OMhUR_`x zq_AAuyfgd1Ju5?kub}U{Z zm@@%Bz!MxnAVG>u*%Bc9qpE*0BMkgf(qbh9esd!L7@!(s%+egs=~8`lVKvuWk8kMx zsPg=J(}xVf#k*Nt>*|);pxIt~+a5*A!vk6jAMxe02!_w$xEwvdM$0&q#qj6m1c2H+}QNFqotv~w&in6X;XcTq<4BQ0bW&p-;Hgz zLng{ey};j177kc)HiT9R7KelawDvkrHob&#TV}&<)_`nN4Er#Kz=TR`NSyfz0B!~9 z1?OZ=pz1aXyL}Io2}b5pU;du>R`a?>)24k*FGL;g%Wx{)_kF6ZZMKc?N2ZzMh(&v* zyzgdq^&!i^)Hr8Bd}QW+n_!cROvIMw-GGAA2j*`zk~a>m4MYu=YX_^Ey(gsAd5nel zj&>Gtvv@5Uhn5b+)ZXO<*Qi$WzN>w<-ex%S$-DLBC#`x?`T#S;T#Zcy0TDLI0Dr|S zJi3mINdzd4m*$!P%{{_*DL)|Q=t@M58=~IM;?BA+&*BvqD*Ba2>#g_75#Av^eC`cx0@dx>{H>^W*ze|BS2o1*CT8 zy>8wkFJ+G{Tdprp7KoAl5-kl=JLq7*!uQT7f_QWA%YvQ4U|I2-g&ogD^+5lE@lr!oh3SnnOQ#xb2BdXtA!7 zq_^pdxL4>DF0_{0h~D&?vef!tP6ay4fN4OdKcN`3K$e5gR|e;dO=qb$3h^xSWQFuO zwz$*3y@i?%O3InY1u}8zg+9)q&L!zfj~!D@?4{XoeBUb`)u`RKk9B%Pxi$G%gX7V! zr`nShD)btaF3hg8R*L4OQsqw8L)-i|bXuXJ#N+;SO}3}p$)-QP{>W%Pldig=8Cr0m zx2x1l+bPfC?pwB-UtS6}-7^{dvJj&94F_ICV0(}L4Pzc#()&qn>@@ne-#YgIrh^`R~uavcx-E3a9Il+zJE6c&cE;)j>MHzw zlN)u}%@TsWF-*l1>*)GxC~fJae6*vyh+XMH#&zHHMS7Ir96mRh*U;EuyrO;&&D*kp zFK;TJTO`D_t=hP!uTLJK7#YPttsGV5P~_3hv^g>aUSJY$iHBAisY#%`6t!hY_H?|O z?fsILiL^C*oL}0$d1=RG<(PxA9>!#n;)J3(6d*B+s4sh@aamw9-G1QFNELlr3jyWE zIL_5^enFZI>EH=Xb|phtQ$QQmfK{9V1L$aJOo{8H1|xFm6(1dsTTJ6Or##A1 z$G)9kjGWgfO^_J>Elkvw7#-l=*?M&5JE>|q#WTYTEGSia3ch{uD1G6$uXdf}Y0c5p zh9?Rbs&m>T-AjfHuJK&!r73&5I{qqhd>z0MlR%*2LcRrUOBVJ=4@uq-eH#JCiQS$^ zmu}PX^3t&n;@a%aE~QzT5DZcuOJXDdIsQD3w`&m#Y4{E7vU$f+{);Jc3z1M=(@KRhzf1%+>Y^V7&Yfw<%XLLk~5?LkNpYVs)Ux=mQb1?Ojhq-=L7cfJ*|2Vrj z6#eweV2k>lJ@N0ep>6EPQ{=S#C@QnDi8YrVP}|a$cja50M_3#964yWSbIwa}aui94 zncQuE9dRe%Q0+ghmRRD=+>&jv2p3Yvge=m?uplq`06zIr zJ|+>kT+nOwk8D@uWSdM7E|^o`@6D9@+CEj!h_6*_liu3=>FKQG37O-O37RnEBbyxw zUH7xwO#?UINF%m^!_>uBc~ky_P0={R~?8BHX1k zrBB_IPtz1ck{ZvNL%(yzwcD4(K?UBss>prd796CcTHrCKu76^5^O|0@%le?38Q>v1_j8cT{9 z4K*u9CM;L9C)M2$z>H}%O5-soi^+o3T8&227oumNkrf`b;t5_md^E_T0*M?+GbU_j zUtNc^Y;SDm9X4OJ!?%a!it2s@rLtAKwYBA76}s$ZoRVse%#PTaro5Tw-lA#Yj^J+C z5p<@FS)@zmdzovBM}ICB1VIO#s&Oo?0RgX-sO66TGYTY?m^jRZwck)X=ckc@_?QaP5qO!?UD}*n4~h%(*Ms>s z8~5@&7dIc{14f~AR!cdmrRmn2a@XWBpi&mfLjW?U#~NiC*z9mJhAyqW^-&gx}eewgKr?@&RUDKUjSQ3DDpIrL?uB`g&I}9l2#wPMO8^% zw8mxrr8&8-F%$X1X(_qT0+r%ZpRlVB(ELO@xw3LS0?$>!OZN{?YDb83Dk8E>yjh-Z ztR~>6%J(O4H9EX7`E!KMt7`LL!~5t5X$65($R5>3RZbV?fKrKK9w#~`@QPVXZzSyQ zI0fHAP0Gu=zm2yxgQ91pdPlAlZ-k{t6pLPB^9-`h)vWbu@%&#F$MhdK z8(0j)-YJDovs8*SJ=N{1nZ)HUFBK7!;g>)TwOmC#>rgxL{b{sN22h8Z_Mai2BEb+} z?_<>=3geAWktX+rf#D%kphEu0z{(0f?@*pwFLzi*CeEa1>mL5>x|&Ca7NbU5%$G8j zy1*ZU!B~u*QM>hRn$45>$SK<9OAR}jM)Q?K22RabQ_b?iq|ZsNz0%+JS(dmmM#BTN z7p<}4woE(*mKWFQ+~C5^CuSy|srC}Y<}Po-Hi>bff>E6Hb~a>mLxugP-uTBXX*0f6 zsxcHC;#`|_L^^9CxEb?^OpvWXmb6_iIz#jZNU?dho%t~tChYSE1^e=}F;Re?Sm&hh zyFpC@@DK(M{7rI;aubcY-FdGo+Wrl~y@7>UQ^oWf-5+9xnggrFp88sa2l7T*F$W_lJ($@oaq>sah}dKqNq^4OXwSaMr|P z4MxIQ5XjwpYfv$SEq+NqFZz*n4U-YB;XhoH_oQp6^G3S7AXcBAPoC-;SKSXs($+Nj z7h*#!Yy;NzW12#-au_gnd_7#O#1sILO3T6;v&*s_JaKd>y-;i4W7%%+Y8uiTWz+AL zHETSXRU$gxKgo2Tv&>asBqNM2&1192ofe^_sb7!g7JY(%0IG z?dBy=CaYJ4xchUqiQvw8!_L1RW$sz(5i0M+_PoYX8s1ICO#aCJ@`mHs4(t1R|5*uv zH~P$s9ikFN9aII|^hH;_LvEX|vt#qh-_X?3vu%y(Y?R&Aj=TBZq4@f&PL75n`E$uxBv{2CI;Bsz`0KQMWYk7H zUQ=r2mCNllZzRauBGmgCTX@F&Lf@wE_!(=O?)a$vLXjKF3Mbz; zDW5z}sL4G{)Gj~^v?r*X;5Y-fUQ7#r$MUZza@=bEiU^3O&BXdY}f4OSRNH#B`QG%%7SQlv`77)hC|7Y&EDMpl#?Us6ZXBq z;6G8*&n@aCxt#6_)a%E@>CC?xddKe1xaBrpRzwRO$XN=IB$GF!CwvKBHIfW9y=12& z1zcg?<X4~{+eRJil5Cs-ZL64WR2=Rqs01HfpqmYNb_%a%n)FAJ@g~!n1q=yT_nM4%c;?&M^y% z?!O37N;`Xr-{Rm7VL%<&4V8pied;MpwikB-Ht+Yiingzq-Ub~UVtMnYYQwCxw?*+^ z^Zzogy8AHc=AAcGdIjI}F{XK?3%;Cg%{q5M7e=;3jNdhOSJesUB4!PsOxoZuagZdKx*ehDUD2dO8a*6a4lskly;yQalX6dm#NW6IJr@e>mCuK5~?l-c4 zlv2MSRzvV&JNN#na3t576_peP6>O?60^@|>yqt7H4FWj^+#Qh?t3Ayd=h}7;ghknno_k=xz4A94O zIwqzwecjg>rJLON_|zW>r`T0sGwYp-(HJUOL7f%W2lnmfaug{kgtiFONpD6@eX4LLh2trJ7f>&9vgKIW%Dh_eq;Mm7yqe%%fWXZ-Nx2b zN62hDraCd@9oAg_i>vQ>NA!yaQ=ed6Yuuu1lh0O4_CK(C!QOTx{yFH;eVlgggpKD% zy;HN)M#Cx8ZC@!(s$YJ-&@!pI^aW1jr>alkoQ)RM{)$97dwzw?#B zD;juT^2r>vyfUkV-b#@ChuNm zg&cY+GW2Xza*b2QLhOycF_dT8)@lOg$Wj|L>|A(2P4$;qEqDOTV$#|Zp8)~*RwTsx zvgI?`o!*93WjZYnNm;!Yl|OFd^H^&vB=XIAvHVD1s{Zg&BFY9C-qv^bIP_=XD^9soI7P4#hVRyLi5cJl# z>22wG%McT3dfGHXMiVPvC$3{ns`o9y)j2Tt83M?y#_&PGNcnODZh>g?E9qZ&}b?-6ZJ_jCcx==ww_+BLZpHv1z*y^_{>IWbY`lTDXJ@+F2MxUlG;6^j*3{8MDIRU1Dwb&KH!96~7}0 z(~DtF_4k?FdEnFXg$phKD-nnnXOTlfeBnX)dV|wX>{f6J)8(jJ*!BHnqCeN0v9FW+ z>pddFrjhdm{=XpIH#9-ik1=8^(5aVn@DF<`R12vE@|dAy8Y0uRB?I(g`^$&7_eG!P z`D6?j;+A_%cB zd2bIrs$z)>Jy-POGdT}gQmrLXs;+I&`&T~0F5v|I)|*j@E{#pcCKOGspZ!-I&%JCq z{JF?!V!uzDvD>=7F;cRS7LfS_=ehV}=QkqrR$Akeepun14027~<@}cj@u{B{DkbhZ zw;wsKVPCA+k*SkzpDeYwf-fr72p9z9kO2F;7y2eM(y|6y&N#`ZKOwa^<}bM}cnwT3 zT&3{1n=_hXuaWhVpCv4QP1zaG1;XVvceXeR{gpUPDeO3_F@7ox{Gdq-VRIKG(Zlj2 zwwB>D*nHiAEaog^>9vh#8{>He?7$iC5JCJ~aYRa=Ac=@W?61Oqqal(;n9 z5f7&U5uDKW1fD(!U}dYuf*69i(AaYQwb_Me)rQbd4*m{KI^OshBaeWyU1f)#;#q)n>J>C+a4e-l9w+t>G9WxsHSFQ#EqMwuz4tL@I$$h1P{jb2SfI zcK3H75~e1DRI~JG=byE+R+?*^g6}JOwPO%J_BuuLRhJ5>_fMKyr-b$4Jpu`9taFLS z##g9}8jj+Qpra=RXbnAlB}T78&@bMaeA+iRH0ca zkw;5A{rnW!g!1ySQx(nYzZt&oYzm`so5XKMUIYDKi|FW@T&yM-u^#lYdG@a_N)^n< zr$+!vrVnw(d|o$qCGD+EIR^YrL$A@*oPCNhI-lI_MLn*&wY_2aL0v0cGsxg_i;VRT zt2_slB~|?J^_L`*45dUumYbEJq5W1o{gS$1{rLE-f!zKwLKGJ}SFT!{A)dx7lcnTQ zU1jX=J6YntFIq%2MW}7*|Il1j3lij2X|Q($T|oYkFHvAzAnJz?u^P|FXox2|uZB>2;Np$FLly*6mUgi_5}rNhvG_OZ-maZ53+Fq_4*p~a&@ zZBqV?!S31j^zRl}?Vc8Cp}&E%8jiHS{udF-5mMLdqv~5VRFg53l+!9Q8TOHd}ii`x(UH?_aICeb&Uni)LtsH1_M21g49y7P#m~Ga8z2j}_W^qhx<8E=vR@OLHP#+ zxsY&|b=)F$qGr&3w)iC~68S_Nl>Rqs*Qgt`mRQWsqr3?P=sQQ_O4*m)tgqXAjk?{3 zhI>cBa~x09+_EhI1)m{%Yhj4-%lo-$JE>4<68XW#LC-5f(8lZ>Kb60vL|N3R zxWdS9hx1)sxI?>Pe#xP*Y~ADQNEYieMm9_}c56MmZfZK+fV%fuHwy9X=p-wi(IjdO zRIOJLSA??1HmgXsP8!&T;~a`t#EpBS-vr9m9nfSrWKC#is}^vrp3YF*&6d1ikWP_i zHhPn1%1kO289hF(j`fdn4hBG2C8AO_WaPl}g;@(ON3}<((?#kLKmF4tfA9Ts*?j-C zV*)a!e#LXO^7s&Vr}$z|FE5vi68)*YOD{Tm@X1?GhSPWM-*2xV8flBqNHFXBx^mxK zvk-dwo&$euZkG!m_d(Wq`9EZ6M}=8}pB$d>H__;ccs_xjoS3p%|Ku6S;jA|!7OF*Q zK;pV$cxignhX*g_*c$Lne0qE#D~7||(J-c2jx5zAob|p7ThYTc;qjP81f#Q}j!2siy~utFD#}%8y19n9 zj_kUrN4-}GBw7gf@h=;T6NU`4_!+#OC5% zyyW)(i?Y5byc%3QAi`yH?5nw0<#Dxh;syKRAYPj{@w{Dj@*$;uy2oIQLQfrWX``KV z#D`}ZSqTdw;i0>{Y$5ZMWZ~ZkN{JC}r$U7K>vc~q zUyC;>SynvR)B;5$)#bh)&4#`(P>B5qIqpIv3S{2bBKKql{@r-^_&*yD;Ab*`%&&Ad z3h>*w)a>Nsj5K&091c%O$;rrw%ZkfSPKIZK<{6C1!L^HoR`uD| zMM7OcyjO{7{cFx=>KT}W)+F*gm@e%csL(yfclIjcC?6~vDG7LY+2i+;nSD*H<;c!l zS2NtE`ydW`FVrK{EDz^Ko%kT0^CiV)NQK;mtT&~#CGW%do;&e-7W0sL+|e11h*?c= z9yZyHLg-ci8rvGQ0%L`0mdnprM>>?HI9_xsOM- z4_D&1Fdr^?vDY=c<@<)qvKWaWroWJg88A=SFSDIc*e^_5((C!N_IG;M6&=ClPx4fx z-Ppqhomj%?AkjT(W-RyWVL7yZBPO~}bEbQm#yDt(3j}&wFCFNuxAIq8Zf8mD7(5c( zL-k7wbct*VDLxknO0c!uOs$2mWrGPpsAp?R`yYq1ar4V*kxHtN!zXV#~_uP%t zZp9naUl<}&A-_LqDBag|7AW>cRe;C(@PP_Nofm57DU4`7XQoEljlKT#d7lRx~9 zDL|$#foy0Z`mB69{@{DE$9hq~VU6wE#qqrc$8@zYZ@##8r^x;+yCvcM>`w=~ZG3JU zF{8HzD9V~ICmYxUv_zvpOSF4Co9dwKVn+@1x-PZ3Li(zVaHd^Za%8=1E$k%WWm0&1q-b%f*5OJ z0SXU<{qtcFDOq<^EHYjf_!a2nZ)NqQcXjQ7Rd_EseDd@RwjvbP+a@)tmd|=TXCSxo zps$3N*frnpfAm+M(D~yM9%E+_?;GbEd6R0^z-XQ?QsQV zW&1t&{rM!9b-?vR(N^3W7Y{OT`n6R^bal{h*2|-5#p~3t=7MobM|t0kufAx|SfZ_g zXZBbw=4O3S-n`B>N{mk(Lv_BzT*%pO9H(7?S}WFl)$q$+wT?R5TxiOXVKKWd-(~4J z$Lf88vpaeb9kV`afmG3Q19hG#!J*u4EkpO`_`^#y>8BCLPboYL`|GK#6TnZ4L9*Uh z?1{JnqA>#gX(}<`dCi)`3v-sohZS#gkQLjQw07TLedENH$O~RDJga_V;r2Eru9il# zD50-=o>4SsDa*t6v!VdGC7dc+fAfD%6pZ|B=Vpq!X zu#L7?Z#;(lQivam%UQ#>V=pBUiD-u)-MHpnFkO^#n!XCzXbGZ*6s^;jkjIQ)sBSp?(8W7JR6MxLzG5e@hl=cy*Lr$i=|kRxZ{)LUrA7_Tn`oi=W4r;XXz&W>%{w$nIiY?}=mGbKMPeD68WFL88w;Yc%ku$6!a1)=C2v-Ho#9($9(lb{&z2HEn?sV7yVHL zS(EQ!02_hQuHiquymGA7hMBk1c!nHHN``6uG>NVlFcd|7-7$GH z?6fmUCZD#e%)OgtaD)XLnbH$GiG>C}Y}!zdm!KL?vlUHG;e*+jZ~6n^%No$Ivv@ykXe(+gvvlArBXY$z!VO9%p0X#$Bg>2>xCz57x^-J|E{ z&}gri-vqcu>!pKvrxv$#SM*3?h8*;*8#Fo!?v;GJ?WJt76;L9HK(eqFwj>W2_tuTk z8HvD`fjJKC_Oz=Z_770}S}s`VXhbz&?|-)y91N6!iJ6k-JEjBxyE;0SXw-)gn}o(CM+pM}kI@l`OW!F< zV$gRv5x?M0wBY>7%KX;MJoUeEX*v)EU5f+Z&w{*e&tOCx)H;8?_ARAuiD;g|+Xz#N zsuG*rqq;77DeOt&Yo?y*4dMh9UM|5D<^UxGThNO=GrXEwy*+w4FA30Oy{B()-eYWR z(Z<4#A#T^&@tL&8Vj;Kt0Gn|mj8jEY?mY5qRKyf2$wNdkWqqtgOzi`W8Z;T>hCQoY z^ej)(x}-4#6vTgUIG983AGIKZMeWW5>1xs2Bk6z$JEJl^cz9u=1zw4F;i zE{71+0YjI{3q5QTB0pay#W(NM+KW3T3~h@NGl%*UdU0M0)`B$rT-3u3YzrFsTy|q3 z?`pW1+T5AXJjNPvL(oB|HG^9j)#SrA%6@JR;R{^PLK?vnQ}PVwK<0y0GJ|1niUI(5 zyYBy&a03%oCNU;(^9~pq{_*f#|4e@Vrn6e%5{v&fnuZj+QV+;({Jl#Hh)*AGx^8^PnMf&@-_yKYeYPZ$1USW^LPEJw6O$zO`qmRZIb@% z&oMPPo-@>PscOSBq(uD;hvHPRVSz3-!yQCOquggPp0}X1uD!}Y$ zZhCs-XO=(+v`)1$a*Upv{c(*8)~Z&OfsU9% zlTuFY5GDbSztFVpXG3|pLCNty!)N#U8-h~4*I=WnLcpWKaV4f`5$7HHSkrwqQTNto zbH5{PYd4+a)siGl*vm}tMCNztQkIxbRIhB$T(}3{mYeYW}*bafy~bzt7d0<9Ki$p z*_vOf``eS|H0?HzsD=Cu0`-lkaw@|p@WRPKZ^NH=-V`@d6nw8@B2-qGgdNosmPbX_ z=tN7C_g?6>lXFDIG6`>A91(? z2)YS;uGa^r+Ehy; z?k^-CP`nu^Qssok_vnaOWUWZ)_`{K(-O@6IqyAdT6rMtM4|Xn8zA8}+JF&TA z*%kg?!rHu7ZQu)nKfvd96(McdqCAFIJ~E&;ZGUfG{zE7;^atbihrvQSJWi3nk?V2h z7~-E^iXEQvemdTv7n!aKH-}SJsLz$-1&#UCeU<8yJekK3(Vt1f{ku5Jih-?^cI8w9 zWFfC^-EHt`{nKIeCxxH!IjC&5TQAwfR3Ao>HMeCJYloya)b)1tFrLA zCFWfP#=@(FAMeME%VoXvVqk@s`P`F!Gm~%A(Aw*BjX$CFMpT28mg$QmC_E3e2#xlj>#6vAJ1nOB@c1Bp|1l5qZAze}3+aEb| zYPjVE1!TLB@_d>sumZ~VRFcdc;<5N6y~jZ3{6E@zrXOdCi4&r@~GjA1PMtow!IMZPR_2Fu*OcdAPoQ^@CfUYkJ6H`}pAPXqK-T;z^9rns6EA zI&*Datz`#4O5Bg0iZ@^&(tE-MwZTFHUhFIofN~wE1lQ(1yYYV<^?n-(s~yrmafHRAQFtbirKk@c``YouQ;J3is-|S)tN z-J-?=gLD_eZtrij+k02Yl_i+S=`h^RBb@gvWO}#)3w9pb2$oFB=fg&*YB}1_Pp35n zJ_B~XB1Q608XY27h5=Y|#}gdBpEpT1#GtNJizR13X-$8K3xzqR&c+>lQR+T8v$u~2 zu}svzDSj0x(7?zuV0!wo3KGz%PJ7}q_bJbS^;BM*LY*gn%N#szEenFzk^md;-+n>0AAy_SiZJ@9Hpat0g)K?CUz#>c^{rA4wCp%M@{)&es%d|w$#aWTUel0RDWuu zR_Zcpzc8WYG}y$&H+ahwGluO5^UJ3K8SgOBhCTH~k(_J!Y&>#BxE*@uD*K#y z!_inRzgbRvjQx?lo_54B$_O-j#>7(@C8=E6i+sO7_yPP9#vIa$2(*<)RGGse-bu-4 zGb)P9+cw8#iM&oOLOR&Z(Y*w6$EcI?RiB^LpnovAru3=42LYbH| zrI%_*cr2UiEXMxmh;bH0U5Ct|iulj|4=4r~++6DNJbLhe`Rh=%DYtr1&-k=!ZRC

7eLUsG*kr!g;`bK8XqGug7US$#)>U$v&O4$YS6FmN||`qCKe)3&NJhhSQAS!Oa9% z9I{x7{V-uZgV(T5_uTBcEb5RJtlwaW$E3@e)ciZEZvXX1A)F6aKEC!%5YnN$80x+v zVcjw-BP|gBFw!22O4#x?EKWpZ>+Oc0*+Va+xtjH^RB&4K9&$apAMHzpEuu>~2(e~lZo@kT3bgna6MULLtBh;ou++>mw!(Rw;W1~uG zCm!sxj0wOv)^3}RWW@Jp1ySH_1=z*q@(@qS^ZoGduaEig<5wcwzyG>>|F7hK@@g}v8pB$O2O)Y#`|l%U9+lWboTOSg-%1p*ljh0AG30`Y=d zRV>K`Yq>TuES=*2IMpnOFGPr}P!~+F5wovKN;_HesGNp9DGGc{&mpKh3~sZ){K{NZ z=8^u;5&P8n*<)_oTUtTgI_(?kO9_d^XV z@JJcJVykNZRe93Q{x0UepuynmZUZh8t8U!Y%ugpc^)PE;Zru!e`Z)h%u7)aB0A18k zKMV_nU&IK7lJyGnM&3d7`cGmG4jq(*oO~l<(QWa#3=xwSe1~NipK}pvD+illomm9o zsbVfAt87*`mbqm*iH_;y)Po8&Lx-I3{5`AUG7bx=3l?gP|8aR(fWOX&sIjy#PdYA{#kyw`U6AX6>TRLa8U{-F$c(%T#ipLAw z90K;GN36DNnIg}aOdCS)tC{t-a#DQ;O5NU>WSrZG5C|Ky7RsD}T zJRQ~3z#a!mfz>X+4F{})j3Zh8&e$5szHBAi_1^JnQX9Ei_`*!_{7qmM zyyuYbvt~XbU%A+DWpXJ7lH*`*J;Ief{|5qt#R7~*6EZYZB8&jR!|iIF40kOksT#Fe z(@ksgk-?8sT6l0WZTedS2l&w)_^8!~F3o+?`&9UNKCfR{n~0Fc%ZmRT9TUcw-3d+B z5DLHoD~tramvAw1T-2V2eU?qrZWI`%o@uQj@ZTU#P!X( zS+!3Z`}-$@R}0{5dm_UXi-8W3L4x3uU|_5L(=sqJvjAz##K5PAMs*a6C&Y3M$e+0` z5OaJp5Q&mhi?QxkX(nWJDT7IV-MH;cR?rVR;tf}f^?DfobU8Kn`7m_B_|+JZPQtYH zWl6DvFS@VyN<5fHlQdwcdDm9uFY{fT^?0f76}~ncArt9q(Xj1AZNAq&OoLhypH$|o7sSp*WJ#Yzw!I%+{7u%Ht(?oP+=gQA|k(>s7TUKO@t(a`c zpR2NGtUJHO!w^M&Q+o^eMM^pR`Oc#1TCBZM45QnzO=yp;c#2K{w>dJ~vDI*7*Q-NC zTv1W$F5Zf`F|~$$G8Y5q3bXZIc2l)34L!Xi%a(o?21}W=XXroJ9NVb%=)v=!6+c!+aP`;fCR z9Vtglr*ohDAIQJl8h>y~rtG_jS8;DA#5$reLRX*9?Xd83t4(gRTaGS{3_G!ib|Ps5 z1kJyoxJ>nO!dL8li}z_>bV>!)o+1J(zuXlsI&(9PUW_Kq(km)Eaa}0zwVR(Nef}uZA;#{FaWIYEMtR~K z2Qfm;9ZmEN-9`N<&<+twPtQ~$TkD$UYcE=;Xxv{TQEKfqrm&G%r*07PnZh?;=ACQV zws(vuTCRJhNCoJ=I_y^U%`f3=CrhxU(?E}%oFKB2bfHi%p|RNwec0Y;PglsdJl|1I z_-_@RoasxW!vaeO1YQ3Q*RX4?`8RBmr*;vh@W{w-zOk}xW*+r}_=_j? zzm#073F^S96kS(UHKd-M&>Y55EoH)3`emFcos`#{=tCT{bJ%&sVcYK5w}es^CWn1{ zkgkyr(ZPfN5u?&NEKf=!=j78sSUcBPletZ!=P$R*tF%PIO$7n=vVRI;Fz?2cO(q8T zEGO04oObLL*OF~h?Y2IFeBM@(fC)0zvkrBrnUDA|S3Gd_u&zEhAKrsoBhctK4}DG< zZn;ru8vyKR8(mL;T!U0WU-f#cE4Lrpa6+&VnlFzRRo^#T=aQCMo&_;G&RPj{%7N&< zAvK--uxeuX$$3k=z-+245M9r#9&S=00zc+t|Kw9{GR$y&I&8>pFbn+H$wh*iGq-W`kk$$h1FOYa%$MZ>H?t z3^gP~Q51QObF3d)HOS`b_%j>|;sPg&HoJvZ9(nS*@Xxi^rYIT-_pbSI?;xsj=52P& za({@#*3uMfJu=?AQ_^seM&euYgh$sjd>HHF?stjFoP6d(QJGACj|gxfK>ch4@V#d) zwEaRF7(ih`?+ibzOL{-wAdW99iOt$sy@u0Fqq|B5B=9--A{wZBc*vUndB0RjBff#7 zVmu=Pt4XAK9kFr)p&B=7>a0_+y*drf26N?p)4)a!aI?|xX4w@`MR%PeF-(?{7m|(!SDAAam&_#!i$JDiU zcD5gim=w!EviAS^gojtOG>&tR(NOvt{SqiX}_N%S;w5R`X^S?sNIqh8A#_5KLNi{ebf0#*?ll zVfN!yA63M|Wcc7d4A&FRapjHSc6-B2H=P?U9; z`2~4;;ld0L=vFe+;VS=g{2#J~8qC#$zxSgM@7GrRnI44@%F_}H5>txuveMFh-y`|G z#S#Q)05r`<2ho_*kQOF?QtKiu^yQlemO}#7ZXF9kXL`TIaDZYk(B=^98}wRr#La4h z;kNm%PIciW9hiqT;wj=~?g~s#r4+Ire4*#>-h!W0-*S{si3llkQJVr8^nzOsB$)nQ z-MNz}*;ZG#-#x$RMj)tFwrSZSM3oZLswk`{sC(z5I|AHc#vOj5%^&gN%$BR&}h#4=j%^%o0X zU1TT}|JC<{(QNiqu&2csyT9hua~QJfGQFm60H!xc{%luVu3OUnc*AG)feV8F-*B)r z2tea&Hce#)*0md4Mb^P4>uNQnA78UlTK^az4fP@jUsk9-HDK#gryL3Ef7F#PYn<{; zfg3&`9YEx1+DGYr5O?zUj1 zE*@_qCg8;tXxK#U-m7X$5$Hfu0za{vIAlcU|GNnopi9k-bfOOTF=B;iTzg~aHTx=J zqpEVjuSEL!cSzza%g!1eFJ~OH++B~d+i;ZX(Y@soiT*aR_*BKcz-C*0(_n$xwZ)HY z*3nj3%NQ@-_HFhs{;BKQq$^%2QbbMvcPZ#U3gq{JrqOr0FM)iE)xai)06TO2pw8ux zXD9cSBiCmSpW6_p08n@`XK)J7?gQG_%dYl=_?uGDciw_xrmnx8*(ahJ4qtn9M7ls@UYr7)uuJ`w5Ad8 zc@bv}k|GdGKt^?NhuWtIiVo^YdHtzq9@B_282IGi0UGZmhFSGA+Fa(+1|v&z2HUMjpWRkn zp2Vz7$@W*RS`7Wplqw|3*+(|#=#C4}D8CSfD8xTi&HQ^s!{M_mPE13Eg)m6zanQgA zcCr0&OCC)=1!Z7X*m4~k4gDyz*Q}r{ry^#L-Ey7Ay)M~tE{|RsqIl)L8ttDI2RicJ z6czE16R8}gq+`r|1LcTb`WoW&;=*oe9p3UjUB{p!wg7=)X5|SQ0y7jJY8p_01^7+s z38Fe#ggS_IeR=V{DUHkQX*39J zcH3HyC-gf4LYy^{+n39#t1}(BP>u-PGWQXVL$5@BJ>sI&k@fY2wCj9@UAG0-y3*`9 zM5a&DSf>O$GNV|Svo6`Vyi>U|Gvzz-k5pzUtc6>&Vs`QRnLNoSnzLx967bq}^T?)H zqw^=#r+S@utp;4%>GdN|iI#=Q%9XP0(<)(WZa6Kx)7R z7Bj~|fZF0RR-^P9G4y88hCULdth|)kE1(b-`3K_|n}F4gzpvvbWi00AcAo72S{89X z8uLgGO@tPI8!9ias2GA=W+o0ivU)D?RQ%L4I?^h@FH-7DO(rPW={K7)hHUPs=?Q}a u^|lQJ{CzL#*tqhYqoEvaxggO;GJHC&%Hx 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

6SCGutf-go$Mg%}AHBmNNOCAjATycr{A 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%0A#`2^w#*fWF-f1Sx$4TIIm;MKZ$A~mfuC@a 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

F5;5R?Do}?qZqY_WZcq%OquWP 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 z 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 literal 0 HcmV?d00001 diff --git a/frontend/src/components/AnnouncementModal/index.js b/frontend/src/components/AnnouncementModal/index.js new file mode 100644 index 0000000..49162cb --- /dev/null +++ b/frontend/src/components/AnnouncementModal/index.js @@ -0,0 +1,338 @@ +import React, { useState, useEffect, useRef } from "react"; + +import * as Yup from "yup"; +import { Formik, Form, Field } from "formik"; +import { toast } from "react-toastify"; + +import { makeStyles } from "@material-ui/core/styles"; +import { green } from "@material-ui/core/colors"; +import Button from "@material-ui/core/Button"; +import TextField from "@material-ui/core/TextField"; +import Dialog from "@material-ui/core/Dialog"; +import DialogActions from "@material-ui/core/DialogActions"; +import DialogContent from "@material-ui/core/DialogContent"; +import DialogTitle from "@material-ui/core/DialogTitle"; +import CircularProgress from "@material-ui/core/CircularProgress"; +import AttachFileIcon from "@material-ui/icons/AttachFile"; +import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline"; +import IconButton from "@material-ui/core/IconButton"; + +import { i18n } from "../../translate/i18n"; +import { head } from "lodash"; + +import api from "../../services/api"; +import toastError from "../../errors/toastError"; +import { + FormControl, + Grid, + InputLabel, + MenuItem, + Select, +} from "@material-ui/core"; +import ConfirmationModal from "../ConfirmationModal"; + +const useStyles = makeStyles((theme) => ({ + root: { + display: "flex", + flexWrap: "wrap", + }, + multFieldLine: { + display: "flex", + "& > *:not(:last-child)": { + marginRight: theme.spacing(1), + }, + }, + + btnWrapper: { + position: "relative", + }, + + buttonProgress: { + color: green[500], + position: "absolute", + top: "50%", + left: "50%", + marginTop: -12, + marginLeft: -12, + }, + formControl: { + margin: theme.spacing(1), + minWidth: 120, + }, + colorAdorment: { + width: 20, + height: 20, + }, +})); + +const AnnouncementSchema = Yup.object().shape({ + title: Yup.string().required("Obrigatório"), + text: Yup.string().required("Obrigatório"), +}); + +const AnnouncementModal = ({ open, onClose, announcementId, reload }) => { + const classes = useStyles(); + + const initialState = { + title: "", + text: "", + priority: 3, + status: true, + }; + + const [confirmationOpen, setConfirmationOpen] = useState(false); + const [announcement, setAnnouncement] = useState(initialState); + const [attachment, setAttachment] = useState(null); + const attachmentFile = useRef(null); + + useEffect(() => { + try { + (async () => { + if (!announcementId) return; + + const { data } = await api.get(`/announcements/${announcementId}`); + setAnnouncement((prevState) => { + return { ...prevState, ...data }; + }); + })(); + } catch (err) { + toastError(err); + } + }, [announcementId, open]); + + const handleClose = () => { + setAnnouncement(initialState); + setAttachment(null); + onClose(); + }; + + const handleAttachmentFile = (e) => { + const file = head(e.target.files); + if (file) { + setAttachment(file); + } + }; + + const handleSaveAnnouncement = async (values) => { + const announcementData = { ...values }; + try { + if (announcementId) { + await api.put(`/announcements/${announcementId}`, announcementData); + if (attachment != null) { + const formData = new FormData(); + formData.append("file", attachment); + await api.post( + `/announcements/${announcementId}/media-upload`, + formData + ); + } + } else { + const { data } = await api.post("/announcements", announcementData); + if (attachment != null) { + const formData = new FormData(); + formData.append("file", attachment); + await api.post(`/announcements/${data.id}/media-upload`, formData); + } + } + toast.success(i18n.t("announcements.toasts.success")); + if (typeof reload == "function") { + reload(); + } + } catch (err) { + toastError(err); + } + handleClose(); + }; + + const deleteMedia = async () => { + if (attachment) { + setAttachment(null); + attachmentFile.current.value = null; + } + + if (announcement.mediaPath) { + await api.delete(`/announcements/${announcement.id}/media-upload`); + setAnnouncement((prev) => ({ + ...prev, + mediaPath: null, + })); + toast.success(i18n.t("announcements.toasts.deleted")); + if (typeof reload == "function") { + reload(); + } + } + }; + + return ( +

+ setConfirmationOpen(false)} + onConfirm={deleteMedia} + > + {i18n.t("announcements.confirmationModal.deleteMessage")} + + + + {announcementId + ? `${i18n.t("announcements.dialog.edit")}` + : `${i18n.t("announcements.dialog.add")}`} + +
+ handleAttachmentFile(e)} + /> +
+ { + setTimeout(() => { + handleSaveAnnouncement(values); + actions.setSubmitting(false); + }, 400); + }} + > + {({ touched, errors, isSubmitting, values }) => ( +
+ + + + + + + + + + + + {i18n.t("announcements.dialog.form.status")} + + + Ativo + Inativo + + + + + + + {i18n.t("announcements.dialog.form.priority")} + + + Alta + Média + Baixa + + + + {(announcement.mediaPath || attachment) && ( + + + setConfirmationOpen(true)} + color="secondary" + > + + + + )} + + + + {!attachment && !announcement.mediaPath && ( + + )} + + + +
+ )} +
+
+
+ ); +}; + +export default AnnouncementModal; diff --git a/frontend/src/components/AnnouncementsPopover/index.js b/frontend/src/components/AnnouncementsPopover/index.js new file mode 100644 index 0000000..b4af33d --- /dev/null +++ b/frontend/src/components/AnnouncementsPopover/index.js @@ -0,0 +1,329 @@ +import React, { useEffect, useReducer, useState, useContext } from "react"; +import { makeStyles } from "@material-ui/core/styles"; +import toastError from "../../errors/toastError"; +import Popover from "@material-ui/core/Popover"; +import AnnouncementIcon from "@material-ui/icons/Announcement"; +import Notifications from "@material-ui/icons/Notifications" + +import { + Avatar, + Badge, + IconButton, + List, + ListItem, + ListItemAvatar, + ListItemText, + Dialog, + Paper, + Typography, + DialogTitle, + DialogContent, + DialogActions, + Button, + DialogContentText, +} from "@material-ui/core"; +import api from "../../services/api"; +import { isArray } from "lodash"; +import moment from "moment"; +import { SocketContext } from "../../context/Socket/SocketContext"; + +const useStyles = makeStyles((theme) => ({ + mainPaper: { + flex: 1, + maxHeight: 3000, + maxWidth: 5000, + padding: theme.spacing(1), + overflowY: "scroll", + ...theme.scrollbarStyles, + }, +})); + +function AnnouncementDialog({ announcement, open, handleClose }) { + const getMediaPath = (filename) => { + return `${process.env.REACT_APP_BACKEND_URL}/public/${filename}`; + }; + return ( + handleClose()} + aria-labelledby="alert-dialog-title" + aria-describedby="alert-dialog-description" + > + {announcement.title} + + {announcement.mediaPath && ( +
+ )} + + {announcement.text} + +
+ + + +
+ ); +} + +const reducer = (state, action) => { + if (action.type === "LOAD_ANNOUNCEMENTS") { + const announcements = action.payload; + const newAnnouncements = []; + + if (isArray(announcements)) { + announcements.forEach((announcement) => { + const announcementIndex = state.findIndex( + (u) => u.id === announcement.id + ); + if (announcementIndex !== -1) { + state[announcementIndex] = announcement; + } else { + newAnnouncements.push(announcement); + } + }); + } + + return [...state, ...newAnnouncements]; + } + + if (action.type === "UPDATE_ANNOUNCEMENTS") { + const announcement = action.payload; + const announcementIndex = state.findIndex((u) => u.id === announcement.id); + + if (announcementIndex !== -1) { + state[announcementIndex] = announcement; + return [...state]; + } else { + return [announcement, ...state]; + } + } + + if (action.type === "DELETE_ANNOUNCEMENT") { + const announcementId = action.payload; + + const announcementIndex = state.findIndex((u) => u.id === announcementId); + if (announcementIndex !== -1) { + state.splice(announcementIndex, 1); + } + return [...state]; + } + + if (action.type === "RESET") { + return []; + } +}; + +export default function AnnouncementsPopover() { + const classes = useStyles(); + + const [loading, setLoading] = useState(false); + const [anchorEl, setAnchorEl] = useState(null); + const [pageNumber, setPageNumber] = useState(1); + const [hasMore, setHasMore] = useState(false); + const [searchParam] = useState(""); + const [announcements, dispatch] = useReducer(reducer, []); + const [invisible, setInvisible] = useState(false); + const [announcement, setAnnouncement] = useState({}); + const [showAnnouncementDialog, setShowAnnouncementDialog] = useState(false); + + const socketManager = useContext(SocketContext); + + useEffect(() => { + dispatch({ type: "RESET" }); + setPageNumber(1); + }, [searchParam]); + + useEffect(() => { + setLoading(true); + const delayDebounceFn = setTimeout(() => { + fetchAnnouncements(); + }, 500); + return () => clearTimeout(delayDebounceFn); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [searchParam, pageNumber]); + + useEffect(() => { + const companyId = localStorage.getItem("companyId"); + const socket = socketManager.getSocket(companyId); + + if (!socket) { + return () => {}; + } + + socket.on(`company-announcement`, (data) => { + if (data.action === "update" || data.action === "create") { + dispatch({ type: "UPDATE_ANNOUNCEMENTS", payload: data.record }); + setInvisible(false); + } + if (data.action === "delete") { + dispatch({ type: "DELETE_ANNOUNCEMENT", payload: +data.id }); + } + }); + return () => { + socket.disconnect(); + }; + }, [socketManager]); + + const fetchAnnouncements = async () => { + try { + const { data } = await api.get("/announcements/", { + params: { searchParam, pageNumber }, + }); + dispatch({ type: "LOAD_ANNOUNCEMENTS", payload: data.records }); + setHasMore(data.hasMore); + setLoading(false); + } catch (err) { + toastError(err); + } + }; + + const loadMore = () => { + setPageNumber((prevState) => prevState + 1); + }; + + const handleScroll = (e) => { + if (!hasMore || loading) return; + const { scrollTop, scrollHeight, clientHeight } = e.currentTarget; + if (scrollHeight - (scrollTop + 100) < clientHeight) { + loadMore(); + } + }; + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + setInvisible(true); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const borderPriority = (priority) => { + if (priority === 1) { + return "4px solid #b81111"; + } + if (priority === 2) { + return "4px solid orange"; + } + if (priority === 3) { + return "4px solid grey"; + } + }; + + const getMediaPath = (filename) => { + return `${process.env.REACT_APP_BACKEND_URL}/public/${filename}`; + }; + + const handleShowAnnouncementDialog = (record) => { + setAnnouncement(record); + setShowAnnouncementDialog(true); + setAnchorEl(null); + }; + + const open = Boolean(anchorEl); + const id = open ? "simple-popover" : undefined; + + return ( +
+ setShowAnnouncementDialog(false)} + /> + + + + + + + + + {isArray(announcements) && + announcements.map((item, key) => ( + handleShowAnnouncementDialog(item)} + > + {item.mediaPath && ( + + + + )} + + + {moment(item.createdAt).format("DD/MM/YYYY")} + + + + {item.text} + + + } + /> + + ))} + {isArray(announcements) && announcements.length === 0 && ( + + )} + + + +
+ ); +} diff --git a/frontend/src/components/BackdropLoading/index.js b/frontend/src/components/BackdropLoading/index.js new file mode 100644 index 0000000..183b02b --- /dev/null +++ b/frontend/src/components/BackdropLoading/index.js @@ -0,0 +1,23 @@ +import React from "react"; + +import Backdrop from "@material-ui/core/Backdrop"; +import CircularProgress from "@material-ui/core/CircularProgress"; +import { makeStyles } from "@material-ui/core/styles"; + +const useStyles = makeStyles(theme => ({ + backdrop: { + zIndex: theme.zIndex.drawer + 1, + color: "#fff", + }, +})); + +const BackdropLoading = () => { + const classes = useStyles(); + return ( + + + + ); +}; + +export default BackdropLoading; diff --git a/frontend/src/components/ButtonWithSpinner/index.js b/frontend/src/components/ButtonWithSpinner/index.js new file mode 100644 index 0000000..542c39c --- /dev/null +++ b/frontend/src/components/ButtonWithSpinner/index.js @@ -0,0 +1,35 @@ +import React from "react"; + +import { makeStyles } from "@material-ui/core/styles"; +import { green } from "@material-ui/core/colors"; +import { CircularProgress, Button } from "@material-ui/core"; + +const useStyles = makeStyles(theme => ({ + button: { + position: "relative", + }, + + buttonProgress: { + color: green[500], + position: "absolute", + top: "50%", + left: "50%", + marginTop: -12, + marginLeft: -12, + }, +})); + +const ButtonWithSpinner = ({ loading, children, ...rest }) => { + const classes = useStyles(); + + return ( + + ); +}; + +export default ButtonWithSpinner; diff --git a/frontend/src/components/CampaignModal/index.js b/frontend/src/components/CampaignModal/index.js new file mode 100644 index 0000000..afbc7d6 --- /dev/null +++ b/frontend/src/components/CampaignModal/index.js @@ -0,0 +1,771 @@ +import React, { useState, useEffect, useRef, useContext } from "react"; + +import * as Yup from "yup"; +import { Formik, Form, Field } from "formik"; +import { toast } from "react-toastify"; +import { head } from "lodash"; + +import { makeStyles } from "@material-ui/core/styles"; +import { green } from "@material-ui/core/colors"; +import Button from "@material-ui/core/Button"; +import IconButton from "@material-ui/core/IconButton"; +import TextField from "@material-ui/core/TextField"; +import Dialog from "@material-ui/core/Dialog"; +import DialogActions from "@material-ui/core/DialogActions"; +import DialogContent from "@material-ui/core/DialogContent"; +import DialogTitle from "@material-ui/core/DialogTitle"; +import CircularProgress from "@material-ui/core/CircularProgress"; +import AttachFileIcon from "@material-ui/icons/AttachFile"; +import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline"; + +import { i18n } from "../../translate/i18n"; +import moment from "moment"; + +import api from "../../services/api"; +import toastError from "../../errors/toastError"; +import { + Box, + FormControl, + Grid, + InputLabel, + MenuItem, + Select, + Tab, + Tabs, +} from "@material-ui/core"; +import { AuthContext } from "../../context/Auth/AuthContext"; +import ConfirmationModal from "../ConfirmationModal"; + +const useStyles = makeStyles((theme) => ({ + root: { + display: "flex", + flexWrap: "wrap", + backgroundColor: "#fff" + }, + + tabmsg: { + backgroundColor: theme.palette.campaigntab, + }, + + textField: { + marginRight: theme.spacing(1), + flex: 1, + }, + + extraAttr: { + display: "flex", + justifyContent: "center", + alignItems: "center", + }, + + btnWrapper: { + position: "relative", + }, + + buttonProgress: { + color: green[500], + position: "absolute", + top: "50%", + left: "50%", + marginTop: -12, + marginLeft: -12, + }, +})); + +const CampaignSchema = Yup.object().shape({ + name: Yup.string() + .min(2, "Too Short!") + .max(50, "Too Long!") + .required("Required"), +}); + +const CampaignModal = ({ + open, + onClose, + campaignId, + initialValues, + onSave, + resetPagination, +}) => { + const classes = useStyles(); + const isMounted = useRef(true); + const { user } = useContext(AuthContext); + const { companyId } = user; + const [file, setFile] = useState(null); + + const initialState = { + name: "", + message1: "", + message2: "", + message3: "", + message4: "", + message5: "", + confirmationMessage1: "", + confirmationMessage2: "", + confirmationMessage3: "", + confirmationMessage4: "", + confirmationMessage5: "", + status: "INATIVA", // INATIVA, PROGRAMADA, EM_ANDAMENTO, CANCELADA, FINALIZADA, + confirmation: false, + scheduledAt: "", + whatsappId: "", + contactListId: "", + tagListId: "Nenhuma", + companyId, + }; + + const [campaign, setCampaign] = useState(initialState); + const [whatsapps, setWhatsapps] = useState([]); + const [contactLists, setContactLists] = useState([]); + const [messageTab, setMessageTab] = useState(0); + const [attachment, setAttachment] = useState(null); + const [confirmationOpen, setConfirmationOpen] = useState(false); + const [campaignEditable, setCampaignEditable] = useState(true); + const attachmentFile = useRef(null); + const [tagLists, setTagLists] = useState([]); + + useEffect(() => { + return () => { + isMounted.current = false; + }; + }, []); + + useEffect(() => { + (async () => { + try { + const { data } = await api.get("/files/", { + params: { companyId } + }); + + setFile(data.files); + } catch (err) { + toastError(err); + } + })(); + }, []); + + useEffect(() => { + if (isMounted.current) { + if (initialValues) { + setCampaign((prevState) => { + return { ...prevState, ...initialValues }; + }); + } + + api + .get(`/contact-lists/list`, { params: { companyId } }) + .then(({ data }) => setContactLists(data)); + + api + .get(`/whatsapp`, { params: { companyId, session: 0 } }) + .then(({ data }) => setWhatsapps(data)); + + api.get(`/tags`, { params: { companyId } }) + .then(({ data }) => { + const fetchedTags = data.tags; + // Perform any necessary data transformation here + const formattedTagLists = fetchedTags.map((tag) => ({ + id: tag.id, + name: tag.name, + })); + setTagLists(formattedTagLists); + }) + .catch((error) => { + console.error("Error retrieving tags:", error); + }); + + if (!campaignId) return; + + api.get(`/campaigns/${campaignId}`).then(({ data }) => { + setCampaign((prev) => { + let prevCampaignData = Object.assign({}, prev); + + Object.entries(data).forEach(([key, value]) => { + if (key === "scheduledAt" && value !== "" && value !== null) { + prevCampaignData[key] = moment(value).format("YYYY-MM-DDTHH:mm"); + } else { + prevCampaignData[key] = value === null ? "" : value; + } + }); + + return prevCampaignData; + }); + }); + } + }, [campaignId, open, initialValues, companyId]); + + useEffect(() => { + const now = moment(); + const scheduledAt = moment(campaign.scheduledAt); + const moreThenAnHour = + !Number.isNaN(scheduledAt.diff(now)) && scheduledAt.diff(now, "hour") > 1; + const isEditable = + campaign.status === "INATIVA" || + (campaign.status === "PROGRAMADA" && moreThenAnHour); + + setCampaignEditable(isEditable); + }, [campaign.status, campaign.scheduledAt]); + + const handleClose = () => { + onClose(); + setCampaign(initialState); + }; + + const handleAttachmentFile = (e) => { + const file = head(e.target.files); + if (file) { + setAttachment(file); + } + }; + + const handleSaveCampaign = async (values) => { + try { + const dataValues = {}; + Object.entries(values).forEach(([key, value]) => { + if (key === "scheduledAt" && value !== "" && value !== null) { + dataValues[key] = moment(value).format("YYYY-MM-DD HH:mm:ss"); + } else { + dataValues[key] = value === "" ? null : value; + } + }); + + if (campaignId) { + await api.put(`/campaigns/${campaignId}`, dataValues); + + if (attachment != null) { + const formData = new FormData(); + formData.append("file", attachment); + await api.post(`/campaigns/${campaignId}/media-upload`, formData); + } + handleClose(); + } else { + const { data } = await api.post("/campaigns", dataValues); + + if (attachment != null) { + const formData = new FormData(); + formData.append("file", attachment); + await api.post(`/campaigns/${data.id}/media-upload`, formData); + } + if (onSave) { + onSave(data); + } + handleClose(); + } + toast.success(i18n.t("campaigns.toasts.success")); + } catch (err) { + console.log(err); + toastError(err); + } + }; + + const deleteMedia = async () => { + if (attachment) { + setAttachment(null); + attachmentFile.current.value = null; + } + + if (campaign.mediaPath) { + await api.delete(`/campaigns/${campaign.id}/media-upload`); + setCampaign((prev) => ({ ...prev, mediaPath: null, mediaName: null })); + toast.success(i18n.t("campaigns.toasts.deleted")); + } + }; + + const renderMessageField = (identifier) => { + return ( + + ); + }; + + const renderConfirmationMessageField = (identifier) => { + return ( + + ); + }; + + const cancelCampaign = async () => { + try { + await api.post(`/campaigns/${campaign.id}/cancel`); + toast.success(i18n.t("campaigns.toasts.cancel")); + setCampaign((prev) => ({ ...prev, status: "CANCELADA" })); + resetPagination(); + } catch (err) { + toast.error(err.message); + } + }; + + const restartCampaign = async () => { + try { + await api.post(`/campaigns/${campaign.id}/restart`); + toast.success(i18n.t("campaigns.toasts.restart")); + setCampaign((prev) => ({ ...prev, status: "EM_ANDAMENTO" })); + resetPagination(); + } catch (err) { + toast.error(err.message); + } + }; + + return ( +
+ setConfirmationOpen(false)} + onConfirm={deleteMedia} + > + {i18n.t("campaigns.confirmationModal.deleteMessage")} + + + + {campaignEditable ? ( + <> + {campaignId + ? `${i18n.t("campaigns.dialog.update")}` + : `${i18n.t("campaigns.dialog.new")}`} + + ) : ( + <>{`${i18n.t("campaigns.dialog.readonly")}`} + )} + +
+ handleAttachmentFile(e)} + /> +
+ { + setTimeout(() => { + handleSaveCampaign(values); + actions.setSubmitting(false); + }, 400); + }} + > + {({ values, errors, touched, isSubmitting }) => ( +
+ + + + + + + + + {i18n.t("campaigns.dialog.form.confirmation")} + + + Desabilitada + Habilitada + + + + + + + {i18n.t("campaigns.dialog.form.contactList")} + + + Nenhuma + {contactLists && + contactLists.map((contactList) => ( + + {contactList.name} + + ))} + + + + + + + {i18n.t("campaigns.dialog.form.tagList")} + + + Nenhuma + {Array.isArray(tagLists) && + tagLists.map((tagList) => ( + + {tagList.name} + + ))} + + + + + + + {i18n.t("campaigns.dialog.form.whatsapp")} + + + Nenhuma + {whatsapps && + whatsapps.map((whatsapp) => ( + + {whatsapp.name} + + ))} + + + + + + + + + {i18n.t("campaigns.dialog.form.fileList")} + + {"Nenhum"} + {file.map(f => ( + + {f.name} + + ))} + + + + + setMessageTab(v)} + variant="fullWidth" + centered + style={{ + borderRadius: 2, + }} + > + + + + + + + + {messageTab === 0 && ( + <> + {values.confirmation ? ( + + + <>{renderMessageField("message1")} + + + <> + {renderConfirmationMessageField( + "confirmationMessage1" + )} + + + + ) : ( + <>{renderMessageField("message1")} + )} + + )} + {messageTab === 1 && ( + <> + {values.confirmation ? ( + + + <>{renderMessageField("message2")} + + + <> + {renderConfirmationMessageField( + "confirmationMessage2" + )} + + + + ) : ( + <>{renderMessageField("message2")} + )} + + )} + {messageTab === 2 && ( + <> + {values.confirmation ? ( + + + <>{renderMessageField("message3")} + + + <> + {renderConfirmationMessageField( + "confirmationMessage3" + )} + + + + ) : ( + <>{renderMessageField("message3")} + )} + + )} + {messageTab === 3 && ( + <> + {values.confirmation ? ( + + + <>{renderMessageField("message4")} + + + <> + {renderConfirmationMessageField( + "confirmationMessage4" + )} + + + + ) : ( + <>{renderMessageField("message4")} + )} + + )} + {messageTab === 4 && ( + <> + {values.confirmation ? ( + + + <>{renderMessageField("message5")} + + + <> + {renderConfirmationMessageField( + "confirmationMessage5" + )} + + + + ) : ( + <>{renderMessageField("message5")} + )} + + )} + + + {(campaign.mediaPath || attachment) && ( + + + {campaignEditable && ( + setConfirmationOpen(true)} + color="secondary" + > + + + )} + + )} + + + + {campaign.status === "CANCELADA" && ( + + )} + {campaign.status === "EM_ANDAMENTO" && ( + + )} + {!attachment && !campaign.mediaPath && campaignEditable && ( + + )} + + {(campaignEditable || campaign.status === "CANCELADA") && ( + + )} + +
+ )} +
+
+
+ ); +}; + +export default CampaignModal; diff --git a/frontend/src/components/Can/index.js b/frontend/src/components/Can/index.js new file mode 100644 index 0000000..3d80215 --- /dev/null +++ b/frontend/src/components/Can/index.js @@ -0,0 +1,39 @@ +import rules from "../../rules"; + +const check = (role, action, data) => { + const permissions = rules[role]; + if (!permissions) { + // role is not present in the rules + return false; + } + + const staticPermissions = permissions.static; + + if (staticPermissions && staticPermissions.includes(action)) { + // static rule not provided for action + return true; + } + + const dynamicPermissions = permissions.dynamic; + + if (dynamicPermissions) { + const permissionCondition = dynamicPermissions[action]; + if (!permissionCondition) { + // dynamic rule not provided for action + return false; + } + + return permissionCondition(data); + } + return false; +}; + +const Can = ({ role, perform, data, yes, no }) => + check(role, perform, data) ? yes() : no(); + +Can.defaultProps = { + yes: () => null, + no: () => null, +}; + +export { Can }; diff --git a/frontend/src/components/CheckoutPage/CheckoutPage.js b/frontend/src/components/CheckoutPage/CheckoutPage.js new file mode 100644 index 0000000..7e94b2c --- /dev/null +++ b/frontend/src/components/CheckoutPage/CheckoutPage.js @@ -0,0 +1,174 @@ +import React, { useContext, useState } from "react"; +import { + Stepper, + Step, + StepLabel, + Button, + Typography, + CircularProgress, +} from "@material-ui/core"; +import { Formik, Form } from "formik"; + +import AddressForm from "./Forms/AddressForm"; +import PaymentForm from "./Forms/PaymentForm"; +import ReviewOrder from "./ReviewOrder"; +import CheckoutSuccess from "./CheckoutSuccess"; + +import api from "../../services/api"; +import toastError from "../../errors/toastError"; +import { toast } from "react-toastify"; +import { AuthContext } from "../../context/Auth/AuthContext"; + + +import validationSchema from "./FormModel/validationSchema"; +import checkoutFormModel from "./FormModel/checkoutFormModel"; +import formInitialValues from "./FormModel/formInitialValues"; + +import useStyles from "./styles"; +import Invoices from "../../pages/Financeiro"; + + +export default function CheckoutPage(props) { + const steps = ["Dados", "Personalizar", "Revisar"]; + const { formId, formField } = checkoutFormModel; + + + + const classes = useStyles(); + const [activeStep, setActiveStep] = useState(1); + const [datePayment, setDatePayment] = useState(null); + const [invoiceId, setinvoiceId] = useState(props.Invoice.id); + const currentValidationSchema = validationSchema[activeStep]; + const isLastStep = activeStep === steps.length - 1; + const { user } = useContext(AuthContext); + +function _renderStepContent(step, setFieldValue, setActiveStep, values ) { + + switch (step) { + case 0: + return ; + case 1: + return ; + case 2: + return ; + default: + return
Not Found
; + } +} + + + async function _submitForm(values, actions) { + try { + const plan = JSON.parse(values.plan); + const newValues = { + firstName: values.firstName, + lastName: values.lastName, + address2: values.address2, + city: values.city, + state: values.state, + zipcode: values.zipcode, + country: values.country, + useAddressForPaymentDetails: values.useAddressForPaymentDetails, + nameOnCard: values.nameOnCard, + cardNumber: values.cardNumber, + cvv: values.cvv, + plan: values.plan, + price: plan.price, + users: plan.users, + connections: plan.connections, + invoiceId: invoiceId + } + + const { data } = await api.post("/subscription", newValues); + setDatePayment(data) + actions.setSubmitting(false); + setActiveStep(activeStep + 1); + toast.success("Assinatura realizada com sucesso!, aguardando a realização do pagamento"); + } catch (err) { + toastError(err); + } + } + + function _handleSubmit(values, actions) { + if (isLastStep) { + _submitForm(values, actions); + } else { + setActiveStep(activeStep + 1); + actions.setTouched({}); + actions.setSubmitting(false); + } + } + + function _handleBack() { + setActiveStep(activeStep - 1); + } + + return ( + + + Falta pouco! + + + {steps.map((label) => ( + + {label} + + ))} + + + {activeStep === steps.length ? ( + + ) : ( + + {({ isSubmitting, setFieldValue, values }) => ( +
+ {_renderStepContent(activeStep, setFieldValue, setActiveStep, values)} + +
+ {activeStep !== 1 && ( + + )} +
+ {activeStep !== 1 && ( + + )} + {isSubmitting && ( + + )} +
+
+
+ )} +
+ )} +
+
+ ); +} diff --git a/frontend/src/components/CheckoutPage/CheckoutSuccess/CheckoutSuccess.js b/frontend/src/components/CheckoutPage/CheckoutSuccess/CheckoutSuccess.js new file mode 100644 index 0000000..a2b9094 --- /dev/null +++ b/frontend/src/components/CheckoutPage/CheckoutSuccess/CheckoutSuccess.js @@ -0,0 +1,76 @@ +import React, { useState, useEffect, useContext } from 'react'; +import { useHistory } from "react-router-dom"; +import QRCode from 'react-qr-code'; +import { SuccessContent, Total } from './style'; +import { CopyToClipboard } from 'react-copy-to-clipboard'; +import { FaCopy, FaCheckCircle } from 'react-icons/fa'; +import { SocketContext } from "../../../context/Socket/SocketContext"; +import { useDate } from "../../../hooks/useDate"; +import { toast } from "react-toastify"; + +function CheckoutSuccess(props) { + + const { pix } = props; + const [pixString,] = useState(pix.qrcode.qrcode); + const [copied, setCopied] = useState(false); + const history = useHistory(); + + const { dateToClient } = useDate(); + + const socketManager = useContext(SocketContext); + + useEffect(() => { + const companyId = localStorage.getItem("companyId"); + const socket = socketManager.getSocket(companyId); + + socket.on(`company-${companyId}-payment`, (data) => { + + if (data.action === "CONCLUIDA") { + toast.success(`Sua licença foi renovada até ${dateToClient(data.company.dueDate)}!`); + setTimeout(() => { + history.push("/"); + }, 4000); + } + }); + }, [history, socketManager]); + + const handleCopyQR = () => { + setTimeout(() => { + setCopied(false); + }, 1 * 1000); + setCopied(true); + }; + + return ( + + + TOTAL + R${pix.valor.original.toLocaleString('pt-br', { minimumFractionDigits: 2 })} + + + + + + + + Para finalizar, basta realizar o pagamento escaneando ou colando o + código Pix acima :) + + + + ); +} + +export default CheckoutSuccess; diff --git a/frontend/src/components/CheckoutPage/CheckoutSuccess/index.js b/frontend/src/components/CheckoutPage/CheckoutSuccess/index.js new file mode 100644 index 0000000..32bd128 --- /dev/null +++ b/frontend/src/components/CheckoutPage/CheckoutSuccess/index.js @@ -0,0 +1,2 @@ +import CheckoutSuccess from './CheckoutSuccess'; +export default CheckoutSuccess; diff --git a/frontend/src/components/CheckoutPage/CheckoutSuccess/style.js b/frontend/src/components/CheckoutPage/CheckoutSuccess/style.js new file mode 100644 index 0000000..f0bbdee --- /dev/null +++ b/frontend/src/components/CheckoutPage/CheckoutSuccess/style.js @@ -0,0 +1,117 @@ +import styled from 'styled-components'; + +export const Container = styled.div` + footer { + margin-top: 30px; + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + + @media (max-width: 768px) { + flex-direction: column; + .checkout-buttons { + display: flex; + flex-direction: column-reverse; + width: 100%; + + button { + width: 100%; + margin-top: 16px; + margin-left: 0; + } + } + } + + button { + margin-left: 16px; + } + } +`; +export const Total = styled.div` + display: flex; + align-items: baseline; + + span { + color: #333; + font-weight: bold; + } + + strong { + color: #333; + font-size: 28px; + margin-left: 5px; + } + + @media (max-width: 768px) { + min-width: 100%; + justify-content: space-between; + } +`; + +export const SuccessContent = styled.div` + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + > h2 { + text-align: center; + } + + > svg { + margin-top: 16px; + } + + > span { + margin-top: 24px; + text-align: center; + } + + > p, + strong { + margin-top: 8px; + font-size: 9px; + color: #999; + } + + .copy-button { + font-size: 14px; + cursor: pointer; + text-align: center; + user-select: none; + min-height: 56px; + display: inline-flex; + -webkit-box-pack: center; + justify-content: center; + -webkit-box-align: center; + align-items: center; + background-color: #f9f9f9; + color: #000; + -webkit-appearance: none !important; + outline: none; + margin-top: 16px; + width: 256px; + font-weight: 600; + text-transform: uppercase; + border: none; + + > span { + margin-right: 8px; + } + } +`; + +export const CheckoutWrapper = styled.div` + width: 100%; + margin: 0 auto 0; + max-width: 1110px; + display: flex; + flex-direction: column; + -webkit-box-align: center; + align-items: center; + padding: 50px 95px; + background: #fff; + @media (max-width: 768px) { + padding: 16px 24px; +`; \ No newline at end of file diff --git a/frontend/src/components/CheckoutPage/FormModel/checkoutFormModel.js b/frontend/src/components/CheckoutPage/FormModel/checkoutFormModel.js new file mode 100644 index 0000000..f77ff4e --- /dev/null +++ b/frontend/src/components/CheckoutPage/FormModel/checkoutFormModel.js @@ -0,0 +1,73 @@ +export default { + formId: 'checkoutForm', + formField: { + firstName: { + name: 'firstName', + label: 'Nome completo*', + requiredErrorMsg: 'O nome completo é obrigatório' + }, + lastName: { + name: 'lastName', + label: 'Last name*', + requiredErrorMsg: 'Last name is required' + }, + address1: { + name: 'address2', + label: 'Endereço*', + requiredErrorMsg: 'O Endereço é obrigatório' + }, + + city: { + name: 'city', + label: 'Cidade*', + requiredErrorMsg: 'Cidade é obrigatória' + }, + state: { + name: 'state', + label: 'Estado*', + requiredErrorMsg: 'Cidade é obrigatória' + }, + zipcode: { + name: 'zipcode', + label: 'CEP*', + requiredErrorMsg: 'CEP é obrigatório', + invalidErrorMsg: 'Formato de CEP inválido' + }, + country: { + name: 'country', + label: 'País*', + requiredErrorMsg: 'País é obrigatório' + }, + useAddressForPaymentDetails: { + name: 'useAddressForPaymentDetails', + label: 'Use this address for payment details' + }, + invoiceId: { + name: 'invoiceId', + label: 'Use this invoiceId' + }, + nameOnCard: { + name: 'nameOnCard', + label: 'Name on card*', + requiredErrorMsg: 'Name on card is required' + }, + cardNumber: { + name: 'cardNumber', + label: 'Card number*', + requiredErrorMsg: 'Card number is required', + invalidErrorMsg: 'Card number is not valid (e.g. 4111111111111)' + }, + expiryDate: { + name: 'expiryDate', + label: 'Expiry date*', + requiredErrorMsg: 'Expiry date is required', + invalidErrorMsg: 'Expiry date is not valid' + }, + cvv: { + name: 'cvv', + label: 'CVV*', + requiredErrorMsg: 'CVV is required', + invalidErrorMsg: 'CVV is invalid (e.g. 357)' + } + } +}; diff --git a/frontend/src/components/CheckoutPage/FormModel/formInitialValues.js b/frontend/src/components/CheckoutPage/FormModel/formInitialValues.js new file mode 100644 index 0000000..a4d22e1 --- /dev/null +++ b/frontend/src/components/CheckoutPage/FormModel/formInitialValues.js @@ -0,0 +1,32 @@ +import checkoutFormModel from './checkoutFormModel'; +const { + formField: { + firstName, + lastName, + address1, + city, + state, + zipcode, + country, + useAddressForPaymentDetails, + nameOnCard, + cardNumber, + invoiceId, + cvv + } +} = checkoutFormModel; + +export default { + [firstName.name]: '', + [lastName.name]: '', + [address1.name]: '', + [city.name]: '', + [state.name]: '', + [zipcode.name]: '', + [country.name]: '', + [useAddressForPaymentDetails.name]: false, + [nameOnCard.name]: '', + [cardNumber.name]: '', + [invoiceId.name]: '', + [cvv.name]: '' +}; diff --git a/frontend/src/components/CheckoutPage/FormModel/validationSchema.js b/frontend/src/components/CheckoutPage/FormModel/validationSchema.js new file mode 100644 index 0000000..9c01534 --- /dev/null +++ b/frontend/src/components/CheckoutPage/FormModel/validationSchema.js @@ -0,0 +1,29 @@ +import * as Yup from 'yup'; +import checkoutFormModel from './checkoutFormModel'; +const { + formField: { + firstName, + address1, + city, + zipcode, + country, + } +} = checkoutFormModel; + + +export default [ + Yup.object().shape({ + [firstName.name]: Yup.string().required(`${firstName.requiredErrorMsg}`), + [address1.name]: Yup.string().required(`${address1.requiredErrorMsg}`), + [city.name]: Yup.string() + .nullable() + .required(`${city.requiredErrorMsg}`), + [zipcode.name]: Yup.string() + .required(`${zipcode.requiredErrorMsg}`), + + [country.name]: Yup.string() + .nullable() + .required(`${country.requiredErrorMsg}`) + }), + +]; diff --git a/frontend/src/components/CheckoutPage/Forms/AddressForm.js b/frontend/src/components/CheckoutPage/Forms/AddressForm.js new file mode 100644 index 0000000..a5afc16 --- /dev/null +++ b/frontend/src/components/CheckoutPage/Forms/AddressForm.js @@ -0,0 +1,134 @@ +import React, { useContext, useEffect, useState } from "react"; +import { Grid, Typography } from "@material-ui/core"; +import { InputField, SelectField } from "../../FormFields"; +import { AuthContext } from "../../../context/Auth/AuthContext"; + +const countries = [ + { + value: "BR", + label: "Brasil", + }, + { + value: "usa", + label: "United States", + }, +]; + +export default function AddressForm(props) { + + const { user } = useContext(AuthContext); + const [billingName, setBillingName] = useState(user.company.billingName); + const [addressZipCode, setAddressZipCode] = useState(user.company.addressZipCode); + const [addressStreet, setAddressStreet] = useState(user.company.addressStreet); + const [addressState, setAddressState] = useState(user.company.addressState); + const [addressCity, setAddressCity] = useState(user.company.addressCity); + const [addressDistrict, setAddressDistrict] = useState(user.company.addressDistrict); + + const { + formField: { + firstName, + address1, + city, + state, + zipcode, + country, + }, + setFieldValue + } = props; + useEffect(() => { + setFieldValue("firstName", billingName) + setFieldValue("zipcode", addressZipCode) + setFieldValue("address2", addressStreet) + setFieldValue("state", addressState) + setFieldValue("city", addressCity) + setFieldValue("country", addressDistrict) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + + return ( + + + Vamos precisar de algumas informações + + + + + { + setBillingName(e.target.value) + setFieldValue("firstName", e.target.value) + }} + /> + + + { + setAddressDistrict(e.target.value) + setFieldValue("country", e.target.value) + } + } + /> + + + + { + setAddressZipCode(e.target.value) + setFieldValue("zipcode", e.target.value) + }} + /> + + + { + setAddressStreet(e.target.value) + setFieldValue("address2", e.target.value) + + }} + /> + + + + { + setAddressState(e.target.value) + setFieldValue("state", e.target.value) + + }} + /> + + + { + setAddressCity(e.target.value) + setFieldValue("city", e.target.value) + }} + /> + + + + + ); +} diff --git a/frontend/src/components/CheckoutPage/Forms/PaymentForm.js b/frontend/src/components/CheckoutPage/Forms/PaymentForm.js new file mode 100644 index 0000000..4a8a6f3 --- /dev/null +++ b/frontend/src/components/CheckoutPage/Forms/PaymentForm.js @@ -0,0 +1,237 @@ +import React, { useState, useEffect, useReducer } from 'react'; +import Button from '@material-ui/core/Button'; +import Card from '@material-ui/core/Card'; +import CardActions from '@material-ui/core/CardActions'; +import CardContent from '@material-ui/core/CardContent'; +import CardHeader from '@material-ui/core/CardHeader'; +import Grid from '@material-ui/core/Grid'; +import StarIcon from '@material-ui/icons/StarBorder'; +import Typography from '@material-ui/core/Typography'; +import { makeStyles } from '@material-ui/core/styles'; + +import IconButton from '@material-ui/core/IconButton'; +import MinimizeIcon from '@material-ui/icons/Minimize'; +import AddIcon from '@material-ui/icons/Add'; + +import usePlans from "../../../hooks/usePlans"; +import useCompanies from "../../../hooks/useCompanies"; + +const useStyles = makeStyles((theme) => ({ + '@global': { + ul: { + margin: 0, + padding: 0, + listStyle: 'none', + }, + }, + margin: { + margin: theme.spacing(1), + }, + + + cardHeader: { + backgroundColor: + theme.palette.type === 'light' ? theme.palette.grey[200] : theme.palette.grey[700], + }, + cardPricing: { + display: 'flex', + justifyContent: 'center', + alignItems: 'baseline', + marginBottom: theme.spacing(2), + }, + footer: { + borderTop: `1px solid ${theme.palette.divider}`, + marginTop: theme.spacing(8), + paddingTop: theme.spacing(3), + paddingBottom: theme.spacing(3), + [theme.breakpoints.up('sm')]: { + paddingTop: theme.spacing(6), + paddingBottom: theme.spacing(6), + }, + }, + + customCard: { + display: "flex", + marginTop: "16px", + alignItems: "center", + flexDirection: "column", + }, + custom: { + display: "flex", + alignItems: "center", + justifyContent: "space-between", + } +})); + + +export default function Pricing(props) { + const { + setFieldValue, + setActiveStep, + activeStep, + } = props; + + const handleChangeAdd = (event, newValue) => { + if (newValue < 3) return + + const newPrice = 11.00; + + setUsersPlans(newValue); + setCustomValuePlans(customValuePlans + newPrice); + } + + const handleChangeMin = (event, newValue) => { + if (newValue < 3) return + + const newPrice = 11; + + setUsersPlans(newValue); + setCustomValuePlans(customValuePlans - newPrice); + } + + const handleChangeConnectionsAdd = (event, newValue) => { + if (newValue < 3) return + const newPrice = 20.00; + setConnectionsPlans(newValue); + setCustomValuePlans(customValuePlans + newPrice); + } + + const handleChangeConnectionsMin = (event, newValue) => { + if (newValue < 3) return + const newPrice = 20; + setConnectionsPlans(newValue); + setCustomValuePlans(customValuePlans - newPrice); + } + + const { list, finder } = usePlans(); + const { find } = useCompanies(); + + const classes = useStyles(); + const [usersPlans, setUsersPlans] = React.useState(3); + const [companiesPlans, setCompaniesPlans] = useState(0); + const [connectionsPlans, setConnectionsPlans] = React.useState(3); + const [storagePlans, setStoragePlans] = React.useState([]); + const [customValuePlans, setCustomValuePlans] = React.useState(49.00); + const [loading, setLoading] = React.useState(false); + const companyId = localStorage.getItem("companyId"); + + useEffect(() => { + async function fetchData() { + await loadCompanies(); + } + fetchData(); + }, []) + + const loadCompanies = async () => { + setLoading(true); + try { + const companiesList = await find(companyId); + setCompaniesPlans(companiesList.planId); + await loadPlans(companiesList.planId); + } catch (e) { + console.log(e); + // toast.error("Não foi possível carregar a lista de registros"); + } + setLoading(false); + }; + const loadPlans = async (companiesPlans) => { + setLoading(true); + try { + const plansCompanies = await finder(companiesPlans); + const plans = [] + + //plansCompanies.forEach((plan) => { + plans.push({ + title: plansCompanies.name, + planId: plansCompanies.id, + price: plansCompanies.value, + description: [ + `${plansCompanies.users} Usuários`, + `${plansCompanies.connections} Conexão`, + `${plansCompanies.queues} Filas` + ], + users: plansCompanies.users, + connections: plansCompanies.connections, + queues: plansCompanies.queues, + buttonText: 'SELECIONAR', + buttonVariant: 'outlined', + }) + + // setStoragePlans(data); + //}); + setStoragePlans(plans); + } catch (e) { + console.log(e); + // toast.error("Não foi possível carregar a lista de registros"); + } + setLoading(false); + }; + + + const tiers = storagePlans + return ( + + + {tiers.map((tier) => ( + // Enterprise card is full width at sm breakpoint + + + : null} + className={classes.cardHeader} + /> + +
+ + { + + + R${tier.price.toLocaleString('pt-br', { minimumFractionDigits: 2 })} + + } + + + /mês + +
+
    + {tier.description.map((line) => ( + + {line} + + ))} +
+
+ + + +
+
+ ))} +
+
+ ); +} \ No newline at end of file diff --git a/frontend/src/components/CheckoutPage/ReviewOrder/PaymentDetails.js b/frontend/src/components/CheckoutPage/ReviewOrder/PaymentDetails.js new file mode 100644 index 0000000..8f7fa76 --- /dev/null +++ b/frontend/src/components/CheckoutPage/ReviewOrder/PaymentDetails.js @@ -0,0 +1,61 @@ +import React, {useContext} from 'react'; +import { Typography, Grid } from '@material-ui/core'; +import useStyles from './styles'; +import { AuthContext } from "../../../context/Auth/AuthContext"; + +function PaymentDetails(props) { + const { formValues } = props; + const classes = useStyles(); + const { firstName, address2, city, zipcode, state, country, plan } = formValues; + const { user } = useContext(AuthContext); + + + const newPlan = JSON.parse(plan); + const { price } = newPlan; + + return ( + + + Informação de pagamento + + + + + Email: + + + {user.company.email} + + + + + Nome: + + + {firstName} + + + + + Endereço: + + + + {address2}, {city} - {state} {zipcode} {country} + + + + + + Total: + + + R${price.toLocaleString('pt-br', {minimumFractionDigits: 2})} + + + + + ); +} + +export default PaymentDetails; diff --git a/frontend/src/components/CheckoutPage/ReviewOrder/ProductDetails.js b/frontend/src/components/CheckoutPage/ReviewOrder/ProductDetails.js new file mode 100644 index 0000000..6d9da8d --- /dev/null +++ b/frontend/src/components/CheckoutPage/ReviewOrder/ProductDetails.js @@ -0,0 +1,33 @@ +import React from 'react'; +import { Typography, List, ListItem, ListItemText } from '@material-ui/core'; +import useStyles from './styles'; + +const products = [ + { name: 'Product 1', desc: 'A nice thing', price: '$9.99' }, + { name: 'Product 2', desc: 'Another thing', price: '$3.45' }, + { name: 'Product 3', desc: 'Something else', price: '$6.51' }, + { name: 'Product 4', desc: 'Best thing of all', price: '$14.11' }, + { name: 'Shipping', desc: '', price: 'Free' } +]; + +function ProductDetails() { + const classes = useStyles(); + return ( + + {products.map(product => ( + + + {product.price} + + ))} + + + + $34.06 + + + + ); +} + +export default ProductDetails; diff --git a/frontend/src/components/CheckoutPage/ReviewOrder/ReviewOrder.js b/frontend/src/components/CheckoutPage/ReviewOrder/ReviewOrder.js new file mode 100644 index 0000000..4ffb132 --- /dev/null +++ b/frontend/src/components/CheckoutPage/ReviewOrder/ReviewOrder.js @@ -0,0 +1,19 @@ +import React from 'react'; +import { useFormikContext } from 'formik'; +import { Typography, Grid } from '@material-ui/core'; +import ShippingDetails from './ShippingDetails'; +import PaymentDetails from './PaymentDetails'; + +export default function ReviewOrder() { + const { values: formValues } = useFormikContext(); + return ( + + + Resumo da assinatura + + + + + + ); +} diff --git a/frontend/src/components/CheckoutPage/ReviewOrder/ShippingDetails.js b/frontend/src/components/CheckoutPage/ReviewOrder/ShippingDetails.js new file mode 100644 index 0000000..78c9de0 --- /dev/null +++ b/frontend/src/components/CheckoutPage/ReviewOrder/ShippingDetails.js @@ -0,0 +1,25 @@ +import React from 'react'; +import { Typography, Grid } from '@material-ui/core'; +import useStyles from './styles'; + +function PaymentDetails(props) { + const { formValues } = props; + const classes = useStyles(); + const { plan } = formValues; + + const newPlan = JSON.parse(plan); + const { users, connections, price } = newPlan; + return ( + + + Detalhes do plano + + Usuários: {users} + Whatsapps: {connections} + Cobrança: Mensal + Total: R${price.toLocaleString('pt-br', {minimumFractionDigits: 2})} + + ); +} + +export default PaymentDetails; diff --git a/frontend/src/components/CheckoutPage/ReviewOrder/index.js b/frontend/src/components/CheckoutPage/ReviewOrder/index.js new file mode 100644 index 0000000..4a3afc8 --- /dev/null +++ b/frontend/src/components/CheckoutPage/ReviewOrder/index.js @@ -0,0 +1,2 @@ +import ReviewOrder from './ReviewOrder'; +export default ReviewOrder; diff --git a/frontend/src/components/CheckoutPage/ReviewOrder/styles.js b/frontend/src/components/CheckoutPage/ReviewOrder/styles.js new file mode 100644 index 0000000..626176a --- /dev/null +++ b/frontend/src/components/CheckoutPage/ReviewOrder/styles.js @@ -0,0 +1,12 @@ +import { makeStyles } from '@material-ui/core/styles'; +export default makeStyles(theme => ({ + listItem: { + padding: theme.spacing(1, 0) + }, + total: { + fontWeight: '700' + }, + title: { + marginTop: theme.spacing(2) + } +})); diff --git a/frontend/src/components/CheckoutPage/index.js b/frontend/src/components/CheckoutPage/index.js new file mode 100644 index 0000000..8728a02 --- /dev/null +++ b/frontend/src/components/CheckoutPage/index.js @@ -0,0 +1,2 @@ +import CheckoutPage from './CheckoutPage'; +export default CheckoutPage; diff --git a/frontend/src/components/CheckoutPage/styles.js b/frontend/src/components/CheckoutPage/styles.js new file mode 100644 index 0000000..963c4d2 --- /dev/null +++ b/frontend/src/components/CheckoutPage/styles.js @@ -0,0 +1,23 @@ +import { makeStyles } from '@material-ui/core/styles'; +export default makeStyles(theme => ({ + stepper: { + padding: theme.spacing(3, 0, 5) + }, + buttons: { + display: 'flex', + justifyContent: 'flex-end' + }, + button: { + marginTop: theme.spacing(3), + marginLeft: theme.spacing(1) + }, + wrapper: { + margin: theme.spacing(1), + position: 'relative' + }, + buttonProgress: { + position: 'absolute', + top: '50%', + left: '50%' + } +})); diff --git a/frontend/src/components/ColorPicker/index.js b/frontend/src/components/ColorPicker/index.js new file mode 100644 index 0000000..7eb9d0a --- /dev/null +++ b/frontend/src/components/ColorPicker/index.js @@ -0,0 +1,85 @@ +import { Dialog } from "@material-ui/core"; +import React, { useState } from "react"; + +import { BlockPicker } from "react-color"; + +const ColorPicker = ({ onChange, currentColor, handleClose, open }) => { + const [selectedColor, setSelectedColor] = useState(currentColor); + + const handleChange = color => { + setSelectedColor(color.hex); + handleClose(); + }; + + const colors = [ + "#B80000", + "#DB3E00", + "#FCCB00", + "#008B02", + "#006B76", + "#1273DE", + "#004DCF", + "#5300EB", + "#EB9694", + "#FAD0C3", + "#FEF3BD", + "#C1E1C5", + "#BEDADC", + "#C4DEF6", + "#BED3F3", + "#D4C4FB", + "#4D4D4D", + "#999999", + "#F44E3B", + "#FE9200", + "#FCDC00", + "#DBDF00", + "#A4DD00", + "#68CCCA", + "#73D8FF", + "#AEA1FF", + "#FDA1FF", + "#333333", + "#808080", + "#cccccc", + "#D33115", + "#E27300", + "#FCC400", + "#B0BC00", + "#68BC00", + "#16A5A5", + "#009CE0", + "#7B64FF", + "#FA28FF", + "#666666", + "#B3B3B3", + "#9F0500", + "#C45100", + "#FB9E00", + "#808900", + "#194D33", + "#0C797D", + "#0062B1", + "#653294", + "#AB149E", + ]; + + return ( + + onChange(color.hex)} + /> + + ); +}; + +export default ColorPicker; diff --git a/frontend/src/components/CompaniesManager/index.js b/frontend/src/components/CompaniesManager/index.js new file mode 100644 index 0000000..f8866e3 --- /dev/null +++ b/frontend/src/components/CompaniesManager/index.js @@ -0,0 +1,627 @@ +import React, { useState, useEffect } from "react"; +import { + makeStyles, + Paper, + Grid, + FormControl, + InputLabel, + MenuItem, + TextField, + Table, + TableHead, + TableBody, + TableCell, + TableRow, + IconButton, + Select, +} from "@material-ui/core"; +import { Formik, Form, Field } from "formik"; +import ButtonWithSpinner from "../ButtonWithSpinner"; +import ConfirmationModal from "../ConfirmationModal"; + +import { Edit as EditIcon } from "@material-ui/icons"; + +import { toast } from "react-toastify"; +import useCompanies from "../../hooks/useCompanies"; +import usePlans from "../../hooks/usePlans"; +import ModalUsers from "../ModalUsers"; +import api from "../../services/api"; +import { head, isArray, has } from "lodash"; +import { useDate } from "../../hooks/useDate"; + +import moment from "moment"; + +const useStyles = makeStyles((theme) => ({ + root: { + width: "100%", + }, + mainPaper: { + width: "100%", + flex: 1, + padding: theme.spacing(2), + }, + fullWidth: { + width: "100%", + }, + tableContainer: { + width: "100%", + overflowX: "scroll", + ...theme.scrollbarStyles, + }, + textfield: { + width: "100%", + }, + textRight: { + textAlign: "right", + }, + row: { + paddingTop: theme.spacing(2), + paddingBottom: theme.spacing(2), + }, + control: { + paddingRight: theme.spacing(1), + paddingLeft: theme.spacing(1), + }, + buttonContainer: { + textAlign: "right", + padding: theme.spacing(1), + }, +})); + +export function CompanyForm(props) { + const { onSubmit, onDelete, onCancel, initialValue, loading } = props; + const classes = useStyles(); + const [plans, setPlans] = useState([]); + const [modalUser, setModalUser] = useState(false); + const [firstUser, setFirstUser] = useState({}); + + const [record, setRecord] = useState({ + name: "", + email: "", + phone: "", + planId: "", + status: true, + campaignsEnabled: false, + dueDate: "", + recurrence: "", + ...initialValue, + }); + + const { list: listPlans } = usePlans(); + + useEffect(() => { + async function fetchData() { + const list = await listPlans(); + setPlans(list); + } + fetchData(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + useEffect(() => { + setRecord((prev) => { + if (moment(initialValue).isValid()) { + initialValue.dueDate = moment(initialValue.dueDate).format( + "YYYY-MM-DD" + ); + } + return { + ...prev, + ...initialValue, + }; + }); + }, [initialValue]); + + const handleSubmit = async (data) => { + if (data.dueDate === "" || moment(data.dueDate).isValid() === false) { + data.dueDate = null; + } + onSubmit(data); + setRecord({ ...initialValue, dueDate: "" }); + }; + + const handleOpenModalUsers = async () => { + try { + const { data } = await api.get("/users/list", { + params: { + companyId: initialValue.id, + }, + }); + if (isArray(data) && data.length) { + setFirstUser(head(data)); + } + setModalUser(true); + } catch (e) { + toast.error(e); + } + }; + + const handleCloseModalUsers = () => { + setFirstUser({}); + setModalUser(false); + }; + + const incrementDueDate = () => { + const data = { ...record }; + if (data.dueDate !== "" && data.dueDate !== null) { + switch (data.recurrence) { + case "MENSAL": + data.dueDate = moment(data.dueDate) + .add(1, "month") + .format("YYYY-MM-DD"); + break; + case "BIMESTRAL": + data.dueDate = moment(data.dueDate) + .add(2, "month") + .format("YYYY-MM-DD"); + break; + case "TRIMESTRAL": + data.dueDate = moment(data.dueDate) + .add(3, "month") + .format("YYYY-MM-DD"); + break; + case "SEMESTRAL": + data.dueDate = moment(data.dueDate) + .add(6, "month") + .format("YYYY-MM-DD"); + break; + case "ANUAL": + data.dueDate = moment(data.dueDate) + .add(12, "month") + .format("YYYY-MM-DD"); + break; + default: + break; + } + } + setRecord(data); + }; + + return ( + <> + + + setTimeout(() => { + handleSubmit(values); + resetForm(); + }, 500) + } + > + {(values, setValues) => ( +
+ + + + + + + + + + + + + Plano + + {plans.map((plan, key) => ( + + {plan.name} + + ))} + + + + + + Status + + Sim + Não + + + + + + Campanhas + + Habilitadas + Desabilitadas + + + + + + + + + + + + Recorrência + + + Mensal + {/*Bimestral*/} + {/*Trimestral*/} + {/*Semestral*/} + {/*Anual*/} + + + + + + + onCancel()} + variant="contained" + > + Limpar + + + {record.id !== undefined ? ( + <> + + onDelete(record)} + variant="contained" + color="secondary" + > + Excluir + + + + incrementDueDate()} + variant="contained" + color="primary" + > + + Vencimento + + + + handleOpenModalUsers()} + variant="contained" + color="primary" + > + Usuário + + + + ) : null} + + + Salvar + + + + + +
+ )} +
+ + ); +} + +export function CompaniesManagerGrid(props) { + const { records, onSelect } = props; + const classes = useStyles(); + const { dateToClient } = useDate(); + + const renderStatus = (row) => { + return row.status === false ? "Não" : "Sim"; + }; + + const renderPlan = (row) => { + return row.planId !== null ? row.plan.name : "-"; + }; + + const renderCampaignsStatus = (row) => { + if ( + has(row, "settings") && + isArray(row.settings) && + row.settings.length > 0 + ) { + const setting = row.settings.find((s) => s.key === "campaignsEnabled"); + if (setting) { + return setting.value === "true" ? "Habilitadas" : "Desabilitadas"; + } + } + return "Desabilitadas"; + }; + + const rowStyle = (record) => { + if (moment(record.dueDate).isValid()) { + const now = moment(); + const dueDate = moment(record.dueDate); + const diff = dueDate.diff(now, "days"); + if (diff === 5) { + return { backgroundColor: "#fffead" }; + } + if (diff >= -3 && diff <= 4) { + return { backgroundColor: "#f7cc8f" }; + } + if (diff === -4) { + return { backgroundColor: "#fa8c8c" }; + } + } + return {}; + }; + + return ( + + + + + + # + + Nome + E-mail + Telefone + Plano + Campanhas + Status + Criada Em + Vencimento + + + + {records.map((row, key) => ( + + + onSelect(row)} aria-label="delete"> + + + + {row.name || "-"} + {row.email || "-"} + {row.phone || "-"} + {renderPlan(row)} + {renderCampaignsStatus(row)} + {renderStatus(row)} + {dateToClient(row.createdAt)} + + {dateToClient(row.dueDate)} +
+ {row.recurrence} +
+
+ ))} +
+
+
+ ); +} + +export default function CompaniesManager() { + const classes = useStyles(); + const { list, save, update, remove } = useCompanies(); + + const [showConfirmDialog, setShowConfirmDialog] = useState(false); + const [loading, setLoading] = useState(false); + const [records, setRecords] = useState([]); + const [record, setRecord] = useState({ + name: "", + email: "", + phone: "", + planId: "", + status: true, + campaignsEnabled: false, + dueDate: "", + recurrence: "", + }); + + useEffect(() => { + loadPlans(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const loadPlans = async () => { + setLoading(true); + try { + const companyList = await list(); + setRecords(companyList); + } catch (e) { + toast.error("Não foi possível carregar a lista de registros"); + } + setLoading(false); + }; + + const handleSubmit = async (data) => { + setLoading(true); + try { + if (data.id !== undefined) { + await update(data); + } else { + await save(data); + } + await loadPlans(); + handleCancel(); + toast.success("Operação realizada com sucesso!"); + } catch (e) { + toast.error( + "Não foi possível realizar a operação. Verifique se já existe uma empresa com o mesmo nome ou se os campos foram preenchidos corretamente" + ); + } + setLoading(false); + }; + + const handleDelete = async () => { + setLoading(true); + try { + await remove(record.id); + await loadPlans(); + handleCancel(); + toast.success("Operação realizada com sucesso!"); + } catch (e) { + toast.error("Não foi possível realizar a operação"); + } + setLoading(false); + }; + + const handleOpenDeleteDialog = () => { + setShowConfirmDialog(true); + }; + + const handleCancel = () => { + setRecord((prev) => ({ + ...prev, + name: "", + email: "", + phone: "", + planId: "", + status: true, + campaignsEnabled: false, + dueDate: "", + recurrence: "", + })); + }; + + const handleSelect = (data) => { + let campaignsEnabled = false; + + const setting = data.settings.find( + (s) => s.key.indexOf("campaignsEnabled") > -1 + ); + if (setting) { + campaignsEnabled = + setting.value === "true" || setting.value === "enabled"; + } + + setRecord((prev) => ({ + ...prev, + id: data.id, + name: data.name || "", + phone: data.phone || "", + email: data.email || "", + planId: data.planId || "", + status: data.status === false ? false : true, + campaignsEnabled, + dueDate: data.dueDate || "", + recurrence: data.recurrence || "", + })); + }; + + return ( + + + + + + + + + + setShowConfirmDialog(false)} + onConfirm={() => handleDelete()} + > + Deseja realmente excluir esse registro? + + + ); +} diff --git a/frontend/src/components/ConfirmationModal/index.js b/frontend/src/components/ConfirmationModal/index.js new file mode 100644 index 0000000..ce340f2 --- /dev/null +++ b/frontend/src/components/ConfirmationModal/index.js @@ -0,0 +1,45 @@ +import React from "react"; +import Button from "@material-ui/core/Button"; +import Dialog from "@material-ui/core/Dialog"; +import DialogActions from "@material-ui/core/DialogActions"; +import DialogContent from "@material-ui/core/DialogContent"; +import DialogTitle from "@material-ui/core/DialogTitle"; +import Typography from "@material-ui/core/Typography"; + +import { i18n } from "../../translate/i18n"; + +const ConfirmationModal = ({ title, children, open, onClose, onConfirm }) => { + return ( + onClose(false)} + aria-labelledby="confirm-dialog" + > + {title} + + {children} + + + + + + + ); +}; + +export default ConfirmationModal; diff --git a/frontend/src/components/ContactDrawer/index.js b/frontend/src/components/ContactDrawer/index.js new file mode 100644 index 0000000..912035e --- /dev/null +++ b/frontend/src/components/ContactDrawer/index.js @@ -0,0 +1,199 @@ +import React, { useEffect, useState } from "react"; + +import { makeStyles } from "@material-ui/core/styles"; +import Typography from "@material-ui/core/Typography"; +import IconButton from "@material-ui/core/IconButton"; +import CloseIcon from "@material-ui/icons/Close"; +import Drawer from "@material-ui/core/Drawer"; +import Link from "@material-ui/core/Link"; +import InputLabel from "@material-ui/core/InputLabel"; +import Avatar from "@material-ui/core/Avatar"; +import Button from "@material-ui/core/Button"; +import Paper from "@material-ui/core/Paper"; +import CreateIcon from '@material-ui/icons/Create'; + +import { i18n } from "../../translate/i18n"; + +import ContactDrawerSkeleton from "../ContactDrawerSkeleton"; +import MarkdownWrapper from "../MarkdownWrapper"; +import { CardHeader } from "@material-ui/core"; +import { ContactForm } from "../ContactForm"; +import ContactModal from "../ContactModal"; +import { ContactNotes } from "../ContactNotes"; + +const drawerWidth = 320; + +const useStyles = makeStyles(theme => ({ + drawer: { + width: drawerWidth, + flexShrink: 0, + }, + drawerPaper: { + width: drawerWidth, + display: "flex", + borderTop: "1px solid rgba(0, 0, 0, 0.12)", + borderRight: "1px solid rgba(0, 0, 0, 0.12)", + borderBottom: "1px solid rgba(0, 0, 0, 0.12)", + borderTopRightRadius: 4, + borderBottomRightRadius: 4, + }, + header: { + display: "flex", + borderBottom: "1px solid rgba(0, 0, 0, 0.12)", + backgroundColor: theme.palette.contactdrawer, //DARK MODE PLW DESIGN// + alignItems: "center", + padding: theme.spacing(0, 1), + minHeight: "73px", + justifyContent: "flex-start", + }, + content: { + display: "flex", + backgroundColor: theme.palette.contactdrawer, //DARK MODE PLW DESIGN// + flexDirection: "column", + padding: "8px 0px 8px 8px", + height: "100%", + overflowY: "scroll", + ...theme.scrollbarStyles, + }, + + contactAvatar: { + margin: 15, + width: 100, + height: 100, + }, + + contactHeader: { + display: "flex", + padding: 8, + flexDirection: "column", + alignItems: "center", + justifyContent: "center", + "& > *": { + margin: 4, + }, + }, + + contactDetails: { + marginTop: 8, + padding: 8, + display: "flex", + flexDirection: "column", + }, + contactExtraInfo: { + marginTop: 4, + padding: 6, + }, +})); + +const ContactDrawer = ({ open, handleDrawerClose, contact, ticket, loading }) => { + const classes = useStyles(); + + const [modalOpen, setModalOpen] = useState(false); + const [openForm, setOpenForm] = useState(false); + + useEffect(() => { + setOpenForm(false); + }, [open, contact]); + + return ( + <> + +
+ + + + + {i18n.t("contactDrawer.header")} + +
+ {loading ? ( + + ) : ( +
+ + {}} + style={{ cursor: "pointer", width: '100%' }} + titleTypographyProps={{ noWrap: true }} + subheaderTypographyProps={{ noWrap: true }} + avatar={} + title={ + <> + setOpenForm(true)}> + {contact.name} + + + + } + subheader={ + <> + + {contact.number} + + + {contact.email} + + + } + /> + + {(contact.id && openForm) && setOpenForm(false)} />} + + + + {i18n.t("ticketOptionsMenu.appointmentsModal.title")} + + + + + setModalOpen(false)} + contactId={contact.id} + > + + {i18n.t("contactDrawer.extraInfo")} + + {contact?.extraInfo?.map(info => ( + + {info.name} + + {info.value} + + + ))} + +
+ )} +
+ + ); +}; + +export default ContactDrawer; diff --git a/frontend/src/components/ContactDrawerSkeleton/index.js b/frontend/src/components/ContactDrawerSkeleton/index.js new file mode 100644 index 0000000..14b9027 --- /dev/null +++ b/frontend/src/components/ContactDrawerSkeleton/index.js @@ -0,0 +1,50 @@ +import React from "react"; +import Skeleton from "@material-ui/lab/Skeleton"; +import Typography from "@material-ui/core/Typography"; +import Paper from "@material-ui/core/Paper"; +import { i18n } from "../../translate/i18n"; +import { Grid } from "@material-ui/core"; + +const ContactDrawerSkeleton = ({ classes }) => { + return ( +
+ + + + + + + + + + + + + + + {i18n.t("contactDrawer.extraInfo")} + + + + + + + + + + + + + + +
+ ); +}; + +export default ContactDrawerSkeleton; diff --git a/frontend/src/components/ContactForm/index.js b/frontend/src/components/ContactForm/index.js new file mode 100644 index 0000000..efdc98a --- /dev/null +++ b/frontend/src/components/ContactForm/index.js @@ -0,0 +1,187 @@ +import React, { useState, useEffect } from "react"; + +import * as Yup from "yup"; +import { Formik, Form, Field } from "formik"; +import { toast } from "react-toastify"; + +import { makeStyles } from "@material-ui/core/styles"; +import { green } from "@material-ui/core/colors"; +import Button from "@material-ui/core/Button"; +import TextField from "@material-ui/core/TextField"; +import CircularProgress from "@material-ui/core/CircularProgress"; + +import { i18n } from "../../translate/i18n"; + +import api from "../../services/api"; +import toastError from "../../errors/toastError"; +import { Grid } from "@material-ui/core"; + +const useStyles = makeStyles(theme => ({ + root: { + display: "flex", + flexWrap: "wrap", + }, + textField: { + marginRight: theme.spacing(1), + flex: 1, + }, + + extraAttr: { + display: "flex", + justifyContent: "center", + alignItems: "center", + }, + + btnWrapper: { + position: "relative", + }, + + buttonProgress: { + color: green[500], + position: "absolute", + top: "50%", + left: "50%", + marginTop: -12, + marginLeft: -12, + }, + + textCenter: { + backgroundColor: 'red' + } +})); + +const ContactSchema = Yup.object().shape({ + name: Yup.string() + .min(2, "Too Short!") + .max(50, "Too Long!") + .required("Required"), + number: Yup.string().min(8, "Too Short!").max(50, "Too Long!"), + email: Yup.string().email("Invalid email"), +}); + +export function ContactForm ({ initialContact, onSave, onCancel }) { + const classes = useStyles(); + + const [contact, setContact] = useState(initialContact); + + useEffect(() => { + setContact(initialContact); + }, [initialContact]); + + const handleSaveContact = async values => { + try { + if (contact.id) { + await api.put(`/contacts/${contact.id}`, values); + } else { + const { data } = await api.post("/contacts", values); + if (onSave) { + onSave(data); + } + } + toast.success(i18n.t("contactModal.success")); + } catch (err) { + toastError(err); + } + }; + + return ( + { + setTimeout(() => { + handleSaveContact(values); + actions.setSubmitting(false); + }, 400); + }} + > + {({ values, errors, touched, isSubmitting }) => ( +
+ + {/* + + {i18n.t("contactModal.form.mainInfo")} + + */} + + + + + + + + + + + + + + + + + + + + +
+ )} +
+ ) +} diff --git a/frontend/src/components/ContactListDialog/index.js b/frontend/src/components/ContactListDialog/index.js new file mode 100644 index 0000000..de6ac3b --- /dev/null +++ b/frontend/src/components/ContactListDialog/index.js @@ -0,0 +1,181 @@ +import React, { useState, useEffect } from "react"; + +import * as Yup from "yup"; +import { Formik, Form, Field } from "formik"; +import { toast } from "react-toastify"; + +import { makeStyles } from "@material-ui/core/styles"; +import { green } from "@material-ui/core/colors"; +import Button from "@material-ui/core/Button"; +import TextField from "@material-ui/core/TextField"; +import Dialog from "@material-ui/core/Dialog"; +import DialogActions from "@material-ui/core/DialogActions"; +import DialogContent from "@material-ui/core/DialogContent"; +import DialogTitle from "@material-ui/core/DialogTitle"; +import CircularProgress from "@material-ui/core/CircularProgress"; + +import { i18n } from "../../translate/i18n"; + +import api from "../../services/api"; +import toastError from "../../errors/toastError"; + +const useStyles = makeStyles((theme) => ({ + root: { + display: "flex", + flexWrap: "wrap", + }, + multFieldLine: { + display: "flex", + "& > *:not(:last-child)": { + marginRight: theme.spacing(1), + }, + }, + + btnWrapper: { + position: "relative", + }, + + buttonProgress: { + color: green[500], + position: "absolute", + top: "50%", + left: "50%", + marginTop: -12, + marginLeft: -12, + }, + formControl: { + margin: theme.spacing(1), + minWidth: 120, + }, +})); + +const ContactListSchema = Yup.object().shape({ + name: Yup.string() + .min(2, "Too Short!") + .max(50, "Too Long!") + .required("Required"), +}); + +const ContactListModal = ({ open, onClose, contactListId }) => { + const classes = useStyles(); + + const initialState = { + name: "", + }; + + const [contactList, setContactList] = useState(initialState); + + useEffect(() => { + const fetchContactList = async () => { + if (!contactListId) return; + try { + const { data } = await api.get(`/contact-lists/${contactListId}`); + setContactList((prevState) => { + return { ...prevState, ...data }; + }); + } catch (err) { + toastError(err); + } + }; + + fetchContactList(); + }, [contactListId, open]); + + const handleClose = () => { + onClose(); + setContactList(initialState); + }; + + const handleSaveContactList = async (values) => { + const contactListData = { ...values }; + try { + if (contactListId) { + await api.put(`/contact-lists/${contactListId}`, contactListData); + } else { + await api.post("/contact-lists", contactListData); + } + toast.success(i18n.t("contactList.dialog")); + } catch (err) { + toastError(err); + } + handleClose(); + }; + + return ( +
+ + + {contactListId + ? `${i18n.t("contactLists.dialog.edit")}` + : `${i18n.t("contactLists.dialog.add")}`} + + { + setTimeout(() => { + handleSaveContactList(values); + actions.setSubmitting(false); + }, 400); + }} + > + {({ touched, errors, isSubmitting }) => ( +
+ +
+ +
+
+ + + + +
+ )} +
+
+
+ ); +}; + +export default ContactListModal; diff --git a/frontend/src/components/ContactListItemModal/index.js b/frontend/src/components/ContactListItemModal/index.js new file mode 100644 index 0000000..52d3881 --- /dev/null +++ b/frontend/src/components/ContactListItemModal/index.js @@ -0,0 +1,242 @@ +import React, { useState, useEffect, useRef, useContext } from "react"; + +import * as Yup from "yup"; +import { Formik, Form, Field } from "formik"; +import { toast } from "react-toastify"; + +import { makeStyles } from "@material-ui/core/styles"; +import { green } from "@material-ui/core/colors"; +import Button from "@material-ui/core/Button"; +import TextField from "@material-ui/core/TextField"; +import Dialog from "@material-ui/core/Dialog"; +import DialogActions from "@material-ui/core/DialogActions"; +import DialogContent from "@material-ui/core/DialogContent"; +import DialogTitle from "@material-ui/core/DialogTitle"; +import Typography from "@material-ui/core/Typography"; +import CircularProgress from "@material-ui/core/CircularProgress"; + +import { i18n } from "../../translate/i18n"; + +import api from "../../services/api"; +import toastError from "../../errors/toastError"; +import { useParams } from "react-router-dom"; +import { AuthContext } from "../../context/Auth/AuthContext"; + +const useStyles = makeStyles((theme) => ({ + root: { + display: "flex", + flexWrap: "wrap", + }, + textField: { + marginRight: theme.spacing(1), + flex: 1, + }, + + extraAttr: { + display: "flex", + justifyContent: "center", + alignItems: "center", + }, + + btnWrapper: { + position: "relative", + }, + + buttonProgress: { + color: green[500], + position: "absolute", + top: "50%", + left: "50%", + marginTop: -12, + marginLeft: -12, + }, +})); + +const ContactSchema = Yup.object().shape({ + name: Yup.string() + .min(2, "Too Short!") + .max(50, "Too Long!") + .required("Required"), + number: Yup.string().min(8, "Too Short!").max(50, "Too Long!"), + email: Yup.string().email("Invalid email"), +}); + +const ContactListItemModal = ({ + open, + onClose, + contactId, + initialValues, + onSave, +}) => { + const classes = useStyles(); + const isMounted = useRef(true); + + const { + user: { companyId }, + } = useContext(AuthContext); + const { contactListId } = useParams(); + + const initialState = { + name: "", + number: "", + email: "", + }; + + const [contact, setContact] = useState(initialState); + + useEffect(() => { + return () => { + isMounted.current = false; + }; + }, []); + + useEffect(() => { + const fetchContact = async () => { + if (initialValues) { + setContact((prevState) => { + return { ...prevState, ...initialValues }; + }); + } + + if (!contactId) return; + + try { + const { data } = await api.get(`/contact-list-items/${contactId}`); + if (isMounted.current) { + setContact(data); + } + } catch (err) { + toastError(err); + } + }; + + fetchContact(); + }, [contactId, open, initialValues]); + + const handleClose = () => { + onClose(); + setContact(initialState); + }; + + const handleSaveContact = async (values) => { + try { + if (contactId) { + await api.put(`/contact-list-items/${contactId}`, { + ...values, + companyId, + contactListId, + }); + handleClose(); + } else { + const { data } = await api.post("/contact-list-items", { + ...values, + companyId, + contactListId, + }); + if (onSave) { + onSave(data); + } + handleClose(); + } + toast.success(i18n.t("contactModal.success")); + } catch (err) { + toastError(err); + } + }; + + return ( +
+ + + {contactId + ? `${i18n.t("contactModal.title.edit")}` + : `${i18n.t("contactModal.title.add")}`} + + { + setTimeout(() => { + handleSaveContact(values); + actions.setSubmitting(false); + }, 400); + }} + > + {({ values, errors, touched, isSubmitting }) => ( +
+ + + {i18n.t("contactModal.form.mainInfo")} + + + +
+ +
+
+ + + + +
+ )} +
+
+
+ ); +}; + +export default ContactListItemModal; diff --git a/frontend/src/components/ContactListTable/index.js b/frontend/src/components/ContactListTable/index.js new file mode 100644 index 0000000..24f354d --- /dev/null +++ b/frontend/src/components/ContactListTable/index.js @@ -0,0 +1,103 @@ +import React, { useState, useEffect } from "react"; +import PropTypes from "prop-types"; +import { + Table, + TableHead, + TableBody, + TableCell, + TableRow, + IconButton, +} from "@material-ui/core"; +import { + Edit as EditIcon, + DeleteOutline as DeleteOutlineIcon, + People as PeopleIcon, +} from "@material-ui/icons"; + +import TableRowSkeleton from "../../components/TableRowSkeleton"; + +function ContactListsTable(props) { + const { + contactLists, + showLoading, + editContactList, + deleteContactList, + readOnly, + } = props; + const [loading, setLoading] = useState(true); + const [rows, setRows] = useState([]); + + useEffect(() => { + if (Array.isArray(contactLists)) { + setRows(contactLists); + } + if (showLoading !== undefined) { + setLoading(showLoading); + } + }, [contactLists, showLoading]); + + const handleEdit = (contactList) => { + editContactList(contactList); + }; + + const handleDelete = (contactList) => { + deleteContactList(contactList); + }; + + const renderRows = () => { + return rows.map((contactList) => { + return ( + + {contactList.name} + + {!readOnly ? ( + + + + + + handleEdit(contactList)}> + + + + handleDelete(contactList)} + > + + + + ) : null} + + ); + }); + }; + + return ( + + + + Nome + Contatos + {!readOnly ? Ações : null} + + + + {loading ? ( + + ) : ( + renderRows() + )} + +
+ ); +} + +ContactListsTable.propTypes = { + contactLists: PropTypes.array.isRequired, + showLoading: PropTypes.bool, + editContactList: PropTypes.func.isRequired, + deleteContactList: PropTypes.func.isRequired, +}; + +export default ContactListsTable; diff --git a/frontend/src/components/ContactModal/index.js b/frontend/src/components/ContactModal/index.js new file mode 100644 index 0000000..3b9c40b --- /dev/null +++ b/frontend/src/components/ContactModal/index.js @@ -0,0 +1,284 @@ +import React, { useState, useEffect, useRef } from "react"; + +import * as Yup from "yup"; +import { Formik, FieldArray, Form, Field } from "formik"; +import { toast } from "react-toastify"; + +import { makeStyles } from "@material-ui/core/styles"; +import { green } from "@material-ui/core/colors"; +import Button from "@material-ui/core/Button"; +import TextField from "@material-ui/core/TextField"; +import Dialog from "@material-ui/core/Dialog"; +import DialogActions from "@material-ui/core/DialogActions"; +import DialogContent from "@material-ui/core/DialogContent"; +import DialogTitle from "@material-ui/core/DialogTitle"; +import Typography from "@material-ui/core/Typography"; +import IconButton from "@material-ui/core/IconButton"; +import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline"; +import CircularProgress from "@material-ui/core/CircularProgress"; + +import { i18n } from "../../translate/i18n"; + +import api from "../../services/api"; +import toastError from "../../errors/toastError"; + +const useStyles = makeStyles(theme => ({ + root: { + display: "flex", + flexWrap: "wrap", + }, + textField: { + marginRight: theme.spacing(1), + flex: 1, + }, + + extraAttr: { + display: "flex", + justifyContent: "center", + alignItems: "center", + }, + + btnWrapper: { + position: "relative", + }, + + buttonProgress: { + color: green[500], + position: "absolute", + top: "50%", + left: "50%", + marginTop: -12, + marginLeft: -12, + }, +})); + +const ContactSchema = Yup.object().shape({ + name: Yup.string() + .min(2, "Too Short!") + .max(50, "Too Long!") + .required("Required"), + number: Yup.string().min(8, "Too Short!").max(50, "Too Long!"), + email: Yup.string().email("Invalid email"), +}); + +const ContactModal = ({ open, onClose, contactId, initialValues, onSave }) => { + const classes = useStyles(); + const isMounted = useRef(true); + + const initialState = { + name: "", + number: "", + email: "", + }; + + const [contact, setContact] = useState(initialState); + + useEffect(() => { + return () => { + isMounted.current = false; + }; + }, []); + + useEffect(() => { + const fetchContact = async () => { + if (initialValues) { + setContact(prevState => { + return { ...prevState, ...initialValues }; + }); + } + + if (!contactId) return; + + try { + const { data } = await api.get(`/contacts/${contactId}`); + if (isMounted.current) { + console.log(data) + setContact(data); + } + } catch (err) { + toastError(err); + } + }; + + fetchContact(); + }, [contactId, open, initialValues]); + + const handleClose = () => { + onClose(); + setContact(initialState); + }; + + const handleSaveContact = async values => { + try { + if (contactId) { + await api.put(`/contacts/${contactId}`, values); + handleClose(); + } else { + const { data } = await api.post("/contacts", values); + if (onSave) { + onSave(data); + } + handleClose(); + } + toast.success(i18n.t("contactModal.success")); + } catch (err) { + toastError(err); + } + }; + + return ( +
+ + + {contactId + ? `${i18n.t("contactModal.title.edit")}` + : `${i18n.t("contactModal.title.add")}`} + + { + setTimeout(() => { + handleSaveContact(values); + actions.setSubmitting(false); + }, 400); + }} + > + {({ values, errors, touched, isSubmitting }) => ( +
+ + + {i18n.t("contactModal.form.mainInfo")} + + + +
+ +
+ + {i18n.t("contactModal.form.whatsapp")} {contact?.whatsapp ? contact?.whatsapp.name : ""} + + + {i18n.t("contactModal.form.extraInfo")} + + + + {({ push, remove }) => ( + <> + {values.extraInfo && + values.extraInfo.length > 0 && + values.extraInfo.map((info, index) => ( +
+ + + remove(index)} + > + + +
+ ))} +
+ +
+ + )} +
+
+ + + + +
+ )} +
+
+
+ ); +}; + +export default ContactModal; diff --git a/frontend/src/components/ContactNotes/index.js b/frontend/src/components/ContactNotes/index.js new file mode 100644 index 0000000..a7db83c --- /dev/null +++ b/frontend/src/components/ContactNotes/index.js @@ -0,0 +1,204 @@ +import React, { useState, useEffect } from 'react'; +import Button from '@material-ui/core/Button'; +import TextField from '@material-ui/core/TextField'; +import List from '@material-ui/core/List'; +import { makeStyles } from '@material-ui/core/styles'; +import * as Yup from "yup"; +import { Formik, Form, Field } from "formik"; + +import ContactNotesDialogListItem from '../ContactNotesDialogListItem'; +import ConfirmationModal from '../ConfirmationModal'; + +import { toast } from "react-toastify"; + +import { i18n } from "../../translate/i18n"; + +import ButtonWithSpinner from '../ButtonWithSpinner'; + +import useTicketNotes from '../../hooks/useTicketNotes'; +import { Grid } from '@material-ui/core'; + +const useStyles = makeStyles((theme) => ({ + root: { + '& .MuiTextField-root': { + margin: theme.spacing(1), + width: '350px', + }, + }, + list: { + width: '100%', + maxWidth: '350px', + maxHeight: '200px', + backgroundColor: theme.palette.background.paper, + overflow: 'auto' + }, + inline: { + width: '100%' + } +})); + +const NoteSchema = Yup.object().shape({ + note: Yup.string() + .min(2, "Too Short!") + .required("Required") +}); +export function ContactNotes ({ ticket }) { + const { id: ticketId, contactId } = ticket + const classes = useStyles() + const [newNote, setNewNote] = useState({ note: "" }); + const [loading, setLoading] = useState(false) + const [showOnDeleteDialog, setShowOnDeleteDialog] = useState(false) + const [selectedNote, setSelectedNote] = useState({}) + const [notes, setNotes] = useState([]) + const { saveNote, deleteNote, listNotes } = useTicketNotes() + + useEffect(() => { + async function openAndFetchData () { + handleResetState() + await loadNotes() + } + openAndFetchData() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + + const handleResetState = () => { + setNewNote({ note: "" }) + setLoading(false) + } + + const handleChangeComment = (e) => { + setNewNote({ note: e.target.value }) + } + + const handleSave = async values => { + setLoading(true) + try { + await saveNote({ + ...values, + ticketId, + contactId + }) + await loadNotes() + setNewNote({ note: '' }) + toast.success('Observação adicionada com sucesso!') + } catch (e) { + toast.error(e) + } + setLoading(false) + } + + const handleOpenDialogDelete = (item) => { + setSelectedNote(item) + setShowOnDeleteDialog(true) + } + + const handleDelete = async () => { + setLoading(true) + try { + await deleteNote(selectedNote.id) + await loadNotes() + setSelectedNote({}) + toast.success('Observação excluída com sucesso!') + } catch (e) { + toast.error(e) + } + setLoading(false) + } + + const loadNotes = async () => { + setLoading(true) + try { + const notes = await listNotes({ ticketId, contactId }) + setNotes(notes) + } catch (e) { + toast.error(e) + } + setLoading(false) + } + + const renderNoteList = () => { + return notes.map((note) => { + return + }) + } + + return ( + <> + + Deseja realmente excluir este registro? + + { + setTimeout(() => { + handleSave(values); + actions.setSubmitting(false); + }, 400); + }} + > + + {({ touched, errors, setErrors }) => ( +
+ + + + + { notes.length > 0 && ( + + + { renderNoteList() } + + + ) } + + + + + + + + Salvar + + + + + +
+ )} +
+ + ); +} \ No newline at end of file diff --git a/frontend/src/components/ContactNotesDialog/index.js b/frontend/src/components/ContactNotesDialog/index.js new file mode 100644 index 0000000..d511256 --- /dev/null +++ b/frontend/src/components/ContactNotesDialog/index.js @@ -0,0 +1,206 @@ +import React, { useState, useEffect } from 'react'; +import Button from '@material-ui/core/Button'; +import Dialog from '@material-ui/core/Dialog'; +import DialogActions from '@material-ui/core/DialogActions'; +import DialogContent from '@material-ui/core/DialogContent'; +import DialogTitle from '@material-ui/core/DialogTitle'; +import TextField from '@material-ui/core/TextField'; +import List from '@material-ui/core/List'; +import { makeStyles } from '@material-ui/core/styles'; +import * as Yup from "yup"; +import { Formik, Form, Field } from "formik"; + +import ContactNotesDialogListItem from '../ContactNotesDialogListItem'; +import ConfirmationModal from '../ConfirmationModal'; + +import { toast } from "react-toastify"; + +import { i18n } from "../../translate/i18n"; + +import ButtonWithSpinner from '../ButtonWithSpinner'; + +import useTicketNotes from '../../hooks/useTicketNotes'; + +const useStyles = makeStyles((theme) => ({ + root: { + '& .MuiTextField-root': { + margin: theme.spacing(1), + width: '350px', + }, + }, + list: { + width: '100%', + maxWidth: '350px', + maxHeight: '200px', + backgroundColor: theme.palette.background.paper, + }, + inline: { + width: '100%' + } +})); + +const NoteSchema = Yup.object().shape({ + note: Yup.string() + .min(2, "Too Short!") + .required("Required") +}); + +export default function ContactNotesDialog ({ modalOpen, onClose, ticket }) { + const { id: ticketId, contactId } = ticket + const classes = useStyles() + const [open, setOpen] = useState(false); + const [newNote, setNewNote] = useState({ note: "" }); + const [loading, setLoading] = useState(false) + const [showOnDeleteDialog, setShowOnDeleteDialog] = useState(false) + const [selectedNote, setSelectedNote] = useState({}) + const [notes, setNotes] = useState([]) + const { saveNote, deleteNote, listNotes } = useTicketNotes() + + useEffect(() => { + async function openAndFetchData () { + if (modalOpen) { + setOpen(true) + handleResetState() + await loadNotes() + } + } + openAndFetchData() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [modalOpen]) + + const handleResetState = () => { + setNewNote({ note: "" }) + setLoading(false) + } + + const handleChangeComment = (e) => { + setNewNote({ note: e.target.value }) + } + + const handleClose = () => { + setOpen(false); + onClose() + }; + + const handleSave = async values => { + setLoading(true) + try { + await saveNote({ + ...values, + ticketId, + contactId + }) + await loadNotes() + setNewNote({ note: '' }) + toast.success('Observação adicionada com sucesso!') + } catch (e) { + toast.error(e) + } + setLoading(false) + } + + const handleOpenDialogDelete = (item) => { + setSelectedNote(item) + setShowOnDeleteDialog(true) + } + + const handleDelete = async () => { + setLoading(true) + try { + await deleteNote(selectedNote.id) + await loadNotes() + setSelectedNote({}) + toast.success('Observação excluída com sucesso!') + } catch (e) { + toast.error(e) + } + setLoading(false) + } + + const loadNotes = async () => { + setLoading(true) + try { + const notes = await listNotes({ ticketId, contactId }) + setNotes(notes) + } catch (e) { + toast.error(e) + } + setLoading(false) + } + + const renderNoteList = () => { + return notes.map((note) => { + return + }) + } + + return ( + <> + + Deseja realmente excluir este registro? + + + + { i18n.t("ticketOptionsMenu.appointmentsModal.title") } + + { + setTimeout(() => { + handleSave(values); + actions.setSubmitting(false); + }, 400); + }} + > + + {({ touched, errors }) => ( +
+ + + + + { renderNoteList() } + + + + + + Salvar + + +
+ )} +
+
+ + ); +} \ No newline at end of file diff --git a/frontend/src/components/ContactNotesDialogListItem/index.js b/frontend/src/components/ContactNotesDialogListItem/index.js new file mode 100644 index 0000000..2b45f71 --- /dev/null +++ b/frontend/src/components/ContactNotesDialogListItem/index.js @@ -0,0 +1,64 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import IconButton from '@material-ui/core/IconButton'; +import ListItem from '@material-ui/core/ListItem'; +import ListItemText from '@material-ui/core/ListItemText'; +import ListItemAvatar from '@material-ui/core/ListItemAvatar'; +import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction'; +import Avatar from '@material-ui/core/Avatar'; +import Typography from '@material-ui/core/Typography'; +import { makeStyles } from '@material-ui/core/styles'; +import DeleteIcon from '@material-ui/icons/Delete'; +import moment from 'moment'; + +const useStyles = makeStyles((theme) => ({ + inline: { + width: '100%' + } +})); + +export default function ContactNotesDialogListItem (props) { + const { note, deleteItem } = props; + const classes = useStyles(); + + const handleDelete = (item) => { + deleteItem(item); + } + + return ( + + + + + + + {note.note} + + + } + secondary={ + <> + {note.user.name}, {moment(note.createdAt).format('DD/MM/YY HH:mm')} + + } + /> + + handleDelete(note)} edge="end" aria-label="delete"> + + + + + ) +} + +ContactNotesDialogListItem.propTypes = { + note: PropTypes.object.isRequired, + deleteItem: PropTypes.func.isRequired +} \ No newline at end of file diff --git a/frontend/src/components/ContactTag/index.js b/frontend/src/components/ContactTag/index.js new file mode 100644 index 0000000..b6c838d --- /dev/null +++ b/frontend/src/components/ContactTag/index.js @@ -0,0 +1,26 @@ +import { makeStyles } from "@material-ui/styles"; +import React from "react"; + +const useStyles = makeStyles(theme => ({ + tag: { + padding: "1px 5px", + borderRadius: "3px", + fontSize: "0.8em", + fontWeight: "bold", + color: "#FFF", + marginRight: "5px", + whiteSpace: "nowrap" + } +})); + +const ContactTag = ({ tag }) => { + const classes = useStyles(); + + return ( +
+ {tag.name.toUpperCase()} +
+ ) +} + +export default ContactTag; \ No newline at end of file diff --git a/frontend/src/components/CurrencyInput/index.js b/frontend/src/components/CurrencyInput/index.js new file mode 100644 index 0000000..4cdddc9 --- /dev/null +++ b/frontend/src/components/CurrencyInput/index.js @@ -0,0 +1,50 @@ +import React from 'react' +import PropTypes from 'prop-types' +import MaskedInput from 'react-text-mask' +import createNumberMask from 'text-mask-addons/dist/createNumberMask' + +const defaultMaskOptions = { + prefix: 'R$', + suffix: '', + includeThousandsSeparator: true, + thousandsSeparatorSymbol: '.', + allowDecimal: true, + decimalSymbol: ',', + decimalLimit: 2, // how many digits allowed after the decimal + integerLimit: 7, // limit length of integer numbers + allowNegative: false, + allowLeadingZeroes: false, +} + +const CurrencyInput = ({ maskOptions, ...inputProps }) => { + const currencyMask = createNumberMask({ + ...defaultMaskOptions, + ...maskOptions, + }) + + return +} + +CurrencyInput.defaultProps = { + inputMode: 'numeric', + maskOptions: {}, +} + +CurrencyInput.propTypes = { + inputmode: PropTypes.string, + maskOptions: PropTypes.shape({ + prefix: PropTypes.string, + suffix: PropTypes.string, + includeThousandsSeparator: PropTypes.bool, + thousandsSeparatorSymbol: PropTypes.string, + allowDecimal: PropTypes.bool, + decimalSymbol: PropTypes.string, + decimalLimit: PropTypes.string, + requireDecimal: PropTypes.bool, + allowNegative: PropTypes.bool, + allowLeadingZeroes: PropTypes.bool, + integerLimit: PropTypes.number, + }), +} + +export default CurrencyInput diff --git a/frontend/src/components/DarkMode/index.js b/frontend/src/components/DarkMode/index.js new file mode 100644 index 0000000..014be13 --- /dev/null +++ b/frontend/src/components/DarkMode/index.js @@ -0,0 +1,70 @@ +import React, { useState } from "react"; + +import { makeStyles } from "@material-ui/core/styles"; +import { CssBaseline, IconButton } from "@material-ui/core"; +import Brightness4Icon from "@material-ui/icons/Brightness4"; +import Brightness7Icon from "@material-ui/icons/Brightness7"; + +const useStyles = makeStyles((theme) => ({ + icons: { + color: "#fff", + }, + switch: { + color: "#fff", + }, + visible: { + display: "none", + }, + btnHeader: { + color: "#fff", + }, +})); + +const DarkMode = (props) => { + const classes = useStyles(); + + const [theme, setTheme] = useState("light"); + + const themeToggle = () => { + theme === "light" ? setTheme("dark") : setTheme("light"); + }; + + const handleClick = () => { + props.themeToggle(); + themeToggle(); + }; + + return ( + <> + {theme === "light" ? ( + <> + + + + + + ) : ( + <> + + + + + + )} + + ); +}; + +export default DarkMode; diff --git a/frontend/src/components/Dashboard/CardCounter.js b/frontend/src/components/Dashboard/CardCounter.js new file mode 100644 index 0000000..c8978a6 --- /dev/null +++ b/frontend/src/components/Dashboard/CardCounter.js @@ -0,0 +1,53 @@ +import React from "react"; + +import { Avatar, Card, CardHeader, Typography } from "@material-ui/core"; +import Skeleton from "@material-ui/lab/Skeleton"; + +import { makeStyles } from "@material-ui/core/styles"; +import { grey } from '@material-ui/core/colors'; + +const useStyles = makeStyles(theme => ({ + cardAvatar: { + fontSize: '55px', + color: grey[500], + backgroundColor: '#ffffff', + width: theme.spacing(7), + height: theme.spacing(7) + }, + cardTitle: { + fontSize: '18px', + color: theme.palette.text.primary + }, + cardSubtitle: { + color: grey[600], + fontSize: '14px' + } +})); + +export default function CardCounter(props) { + const { icon, title, value, loading } = props + const classes = useStyles(); + return ( !loading ? + + + {icon} + + } + title={ + + { title } + + } + subheader={ + + { value } + + } + /> + + : + ) + +} \ No newline at end of file diff --git a/frontend/src/components/Dashboard/TableAttendantsStatus.js b/frontend/src/components/Dashboard/TableAttendantsStatus.js new file mode 100644 index 0000000..ed748e4 --- /dev/null +++ b/frontend/src/components/Dashboard/TableAttendantsStatus.js @@ -0,0 +1,104 @@ +import React from "react"; + +import Paper from "@material-ui/core/Paper"; +import Table from '@material-ui/core/Table'; +import TableBody from '@material-ui/core/TableBody'; +import TableCell from '@material-ui/core/TableCell'; +import TableContainer from '@material-ui/core/TableContainer'; +import TableHead from '@material-ui/core/TableHead'; +import TableRow from '@material-ui/core/TableRow'; +import Skeleton from "@material-ui/lab/Skeleton"; + +import { makeStyles } from "@material-ui/core/styles"; +import { green, red } from '@material-ui/core/colors'; + +import CheckCircleIcon from '@material-ui/icons/CheckCircle'; +import ErrorIcon from '@material-ui/icons/Error'; +import moment from 'moment'; + +import Rating from '@material-ui/lab/Rating'; + +const useStyles = makeStyles(theme => ({ + on: { + color: green[600], + fontSize: '20px' + }, + off: { + color: red[600], + fontSize: '20px' + }, + pointer: { + cursor: "pointer" + } +})); + +export function RatingBox ({ rating }) { + const ratingTrunc = rating === null ? 0 : Math.trunc(rating); + return +} + +export default function TableAttendantsStatus(props) { + const { loading, attendants } = props + const classes = useStyles(); + + function renderList () { + return attendants.map((a, k) => ( + + {a.name} + + + + {formatTime(a.avgSupportTime, 2)} + + { a.online ? + + : + } + + + )) + } + + function formatTime(minutes){ + return moment().startOf('day').add(minutes, 'minutes').format('HH[h] mm[m]'); + } + + return ( !loading ? + + + + + Nome + Avaliações + T.M. de Atendimento + Status (Atual) + + + + { renderList() } + {/* + Nome 4 + 10 + 10 minutos + + + + + + Nome 5 + 10 + 10 minutos + + + + */} + +
+
+ : + ) +} \ No newline at end of file diff --git a/frontend/src/components/Dialog/index.js b/frontend/src/components/Dialog/index.js new file mode 100644 index 0000000..23bcb28 --- /dev/null +++ b/frontend/src/components/Dialog/index.js @@ -0,0 +1,34 @@ +import React, { useState, useEffect } from 'react'; +import CoreDialog from '@material-ui/core/Dialog'; +import DialogTitle from '@material-ui/core/DialogTitle'; + +function Dialog ({ title, modalOpen, onClose, children }) { + const [open, setOpen] = useState(false); + + useEffect(() => { + setOpen(modalOpen) + }, [modalOpen]) + + const handleClose = () => { + setOpen(false); + onClose() + }; + + return ( + <> + + + {title} + + {children} + + + ); +} + +export default Dialog; \ No newline at end of file diff --git a/frontend/src/components/FileModal/index.js b/frontend/src/components/FileModal/index.js new file mode 100644 index 0000000..87b7404 --- /dev/null +++ b/frontend/src/components/FileModal/index.js @@ -0,0 +1,350 @@ +import React, { useState, useEffect, useContext } from "react"; + +import * as Yup from "yup"; +import { + Formik, + Form, + Field, + FieldArray +} from "formik"; +import { toast } from "react-toastify"; + +import { + Box, + Button, + CircularProgress, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + Divider, + Grid, + makeStyles, + TextField +} from "@material-ui/core"; +import IconButton from "@material-ui/core/IconButton"; +import Typography from "@material-ui/core/Typography"; +import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline"; +import AttachFileIcon from "@material-ui/icons/AttachFile"; + +import { green } from "@material-ui/core/colors"; + +import { i18n } from "../../translate/i18n"; + +import api from "../../services/api"; +import toastError from "../../errors/toastError"; +import { AuthContext } from "../../context/Auth/AuthContext"; + +const useStyles = makeStyles(theme => ({ + root: { + display: "flex", + flexWrap: "wrap", + gap: 4 + }, + multFieldLine: { + display: "flex", + "& > *:not(:last-child)": { + marginRight: theme.spacing(1), + }, + }, + textField: { + marginRight: theme.spacing(1), + flex: 1, + }, + + extraAttr: { + display: "flex", + justifyContent: "center", + alignItems: "center", + }, + + btnWrapper: { + position: "relative", + }, + + buttonProgress: { + color: green[500], + position: "absolute", + top: "50%", + left: "50%", + marginTop: -12, + marginLeft: -12, + }, + formControl: { + margin: theme.spacing(1), + minWidth: 2000, + }, + colorAdorment: { + width: 20, + height: 20, + }, +})); + +const FileListSchema = Yup.object().shape({ + name: Yup.string() + .min(3, "nome muito curto") + .required("Obrigatório"), + message: Yup.string() + .required("Obrigatório") +}); + +const FilesModal = ({ open, onClose, fileListId, reload }) => { + const classes = useStyles(); + const { user } = useContext(AuthContext); + const [ files, setFiles ] = useState([]); + const [selectedFileNames, setSelectedFileNames] = useState([]); + + + const initialState = { + name: "", + message: "", + options: [{ name: "", path:"", mediaType:"" }], + }; + + const [fileList, setFileList] = useState(initialState); + + useEffect(() => { + try { + (async () => { + if (!fileListId) return; + + const { data } = await api.get(`/files/${fileListId}`); + setFileList(data); + })() + } catch (err) { + toastError(err); + } + }, [fileListId, open]); + + const handleClose = () => { + setFileList(initialState); + setFiles([]); + onClose(); + }; + + const handleSaveFileList = async (values) => { + + const uploadFiles = async (options, filesOptions, id) => { + const formData = new FormData(); + formData.append("fileId", id); + formData.append("typeArch", "fileList") + filesOptions.forEach((fileOption, index) => { + if (fileOption.file) { + formData.append("files", fileOption.file); + formData.append("mediaType", fileOption.file.type) + formData.append("name", options[index].name); + formData.append("id", options[index].id); + } + }); + + try { + const { data } = await api.post(`/files/uploadList/${id}`, formData); + setFiles([]); + return data; + } catch (err) { + toastError(err); + } + return null; + } + + const fileData = { ...values, userId: user.id }; + + try { + if (fileListId) { + const { data } = await api.put(`/files/${fileListId}`, fileData) + if (data.options.length > 0) + + uploadFiles(data.options, values.options, fileListId) + } else { + const { data } = await api.post("/files", fileData); + if (data.options.length > 0) + uploadFiles(data.options, values.options, data.id) + } + toast.success(i18n.t("fileModal.success")); + if (typeof reload == 'function') { + reload(); + } + } catch (err) { + toastError(err); + } + handleClose(); + }; + + return ( +
+ + + {(fileListId ? `${i18n.t("fileModal.title.edit")}` : `${i18n.t("fileModal.title.add")}`)} + + { + setTimeout(() => { + handleSaveFileList(values); + actions.setSubmitting(false); + }, 400); + }} + > + {({ touched, errors, isSubmitting, values }) => ( +
+ +
+ +
+
+
+ +
+ + {i18n.t("fileModal.form.fileOptions")} + + + + {({ push, remove }) => ( + <> + {values.options && + values.options.length > 0 && + values.options.map((info, index) => ( +
+ + + + + + { + const selectedFile = e.target.files[0]; + const updatedOptions = [...values.options]; + updatedOptions[index].file = selectedFile; + + setFiles('options', updatedOptions); + + // Atualize a lista selectedFileNames para o campo específico + const updatedFileNames = [...selectedFileNames]; + updatedFileNames[index] = selectedFile ? selectedFile.name : ''; + setSelectedFileNames(updatedFileNames); + }} + style={{ display: 'none' }} + name={`options[${index}].file`} + id={`file-upload-${index}`} + /> + + remove(index)} + > + + + + + {info.path? info.path : selectedFileNames[index]} + + +
+ + ))} +
+ +
+ + )} +
+
+ + + + +
+ )} +
+
+
+ ); +}; + +export default FilesModal; \ No newline at end of file diff --git a/frontend/src/components/FormFields/CheckboxField.js b/frontend/src/components/FormFields/CheckboxField.js new file mode 100644 index 0000000..c7688ff --- /dev/null +++ b/frontend/src/components/FormFields/CheckboxField.js @@ -0,0 +1,38 @@ +import React from 'react'; +import { at } from 'lodash'; +import { useField } from 'formik'; +import { + Checkbox, + FormControl, + FormControlLabel, + FormHelperText +} from '@material-ui/core'; + +export default function CheckboxField(props) { + const { label, ...rest } = props; + const [field, meta, helper] = useField(props); + const { setValue } = helper; + + function _renderHelperText() { + const [touched, error] = at(meta, 'touched', 'error'); + if (touched && error) { + return {error}; + } + } + + function _onChange(e) { + setValue(e.target.checked); + } + + return ( + + } + label={label} + /> + {_renderHelperText()} + + ); +} diff --git a/frontend/src/components/FormFields/DatePickerField.js b/frontend/src/components/FormFields/DatePickerField.js new file mode 100644 index 0000000..503396e --- /dev/null +++ b/frontend/src/components/FormFields/DatePickerField.js @@ -0,0 +1,54 @@ +import React, { useState, useEffect } from 'react'; +import { useField } from 'formik'; +import Grid from '@material-ui/core/Grid'; +import { + MuiPickersUtilsProvider, + KeyboardDatePicker +} from '@material-ui/pickers'; +import DateFnsUtils from '@date-io/date-fns'; + +export default function DatePickerField(props) { + const [field, meta, helper] = useField(props); + const { touched, error } = meta; + const { setValue } = helper; + const isError = touched && error && true; + const { value } = field; + const [selectedDate, setSelectedDate] = useState(null); + + useEffect(() => { + if (value) { + const date = new Date(value); + setSelectedDate(date); + } + }, [value]); + + function _onChange(date) { + if (date) { + setSelectedDate(date); + try { + const ISODateString = date.toISOString(); + setValue(ISODateString); + } catch (error) { + setValue(date); + } + } else { + setValue(date); + } + } + + return ( + + + + + + ); +} diff --git a/frontend/src/components/FormFields/InputField.js b/frontend/src/components/FormFields/InputField.js new file mode 100644 index 0000000..ecc68b2 --- /dev/null +++ b/frontend/src/components/FormFields/InputField.js @@ -0,0 +1,26 @@ +import React from 'react'; +import { at } from 'lodash'; +import { useField } from 'formik'; +import { TextField } from '@material-ui/core'; + +export default function InputField(props) { + const { errorText, ...rest } = props; + const [field, meta] = useField(props); + + function _renderHelperText() { + const [touched, error] = at(meta, 'touched', 'error'); + if (touched && error) { + return error; + } + } + + return ( + + ); +} diff --git a/frontend/src/components/FormFields/SelectField.js b/frontend/src/components/FormFields/SelectField.js new file mode 100644 index 0000000..35ca7e2 --- /dev/null +++ b/frontend/src/components/FormFields/SelectField.js @@ -0,0 +1,48 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { at } from 'lodash'; +import { useField } from 'formik'; +import { + InputLabel, + FormControl, + Select, + MenuItem, + FormHelperText +} from '@material-ui/core'; + +function SelectField(props) { + const { label, data, ...rest } = props; + const [field, meta] = useField(props); + const { value: selectedValue } = field; + const [touched, error] = at(meta, 'touched', 'error'); + const isError = touched && error && true; + function _renderHelperText() { + if (isError) { + return {error}; + } + } + + return ( + + {label} + + {_renderHelperText()} + + ); +} + +SelectField.defaultProps = { + data: [] +}; + +SelectField.propTypes = { + data: PropTypes.array.isRequired +}; + +export default SelectField; diff --git a/frontend/src/components/FormFields/index.js b/frontend/src/components/FormFields/index.js new file mode 100644 index 0000000..9fa1775 --- /dev/null +++ b/frontend/src/components/FormFields/index.js @@ -0,0 +1,5 @@ +import InputField from './InputField'; +import CheckboxField from './CheckboxField'; +import SelectField from './SelectField'; +import DatePickerField from './DatePickerField'; +export { InputField, CheckboxField, SelectField, DatePickerField }; diff --git a/frontend/src/components/HelpsManager/index.js b/frontend/src/components/HelpsManager/index.js new file mode 100644 index 0000000..5e7c2ac --- /dev/null +++ b/frontend/src/components/HelpsManager/index.js @@ -0,0 +1,290 @@ +import React, { useState, useEffect } from "react"; +import { + makeStyles, + Paper, + Grid, + TextField, + Table, + TableHead, + TableBody, + TableCell, + TableRow, + IconButton +} from "@material-ui/core"; +import { Formik, Form, Field } from 'formik'; +import ButtonWithSpinner from "../ButtonWithSpinner"; +import ConfirmationModal from "../ConfirmationModal"; + +import { Edit as EditIcon } from "@material-ui/icons"; + +import { toast } from "react-toastify"; +import useHelps from "../../hooks/useHelps"; + + +const useStyles = makeStyles(theme => ({ + root: { + width: '100%' + }, + mainPaper: { + width: '100%', + flex: 1, + padding: theme.spacing(2) + }, + fullWidth: { + width: '100%' + }, + tableContainer: { + width: '100%', + overflowX: "scroll", + ...theme.scrollbarStyles + }, + textfield: { + width: '100%' + }, + textRight: { + textAlign: 'right' + }, + row: { + paddingTop: theme.spacing(2), + paddingBottom: theme.spacing(2) + }, + control: { + paddingRight: theme.spacing(1), + paddingLeft: theme.spacing(1) + }, + buttonContainer: { + textAlign: 'right', + padding: theme.spacing(1) + } +})); + +export function HelpManagerForm (props) { + const { onSubmit, onDelete, onCancel, initialValue, loading } = props; + const classes = useStyles() + + const [record, setRecord] = useState(initialValue); + + useEffect(() => { + setRecord(initialValue) + }, [initialValue]) + + const handleSubmit = async(data) => { + onSubmit(data) + } + + return ( + + setTimeout(() => { + handleSubmit(values) + resetForm() + }, 500) + } + > + {(values) => ( +
+ + + + + + + + + + + + onCancel()} variant="contained"> + Limpar + + + { record.id !== undefined ? ( + + onDelete(record)} variant="contained" color="secondary"> + Excluir + + + ) : null} + + + Salvar + + + +
+ )} +
+ ) +} + +export function HelpsManagerGrid (props) { + const { records, onSelect } = props + const classes = useStyles() + + return ( + + + + + # + Título + Descrição + Vídeo + + + + {records.map((row) => ( + + + onSelect(row)} aria-label="delete"> + + + + {row.title || '-'} + {row.description || '-'} + {row.video || '-'} + + ))} + +
+
+ ) +} + +export default function HelpsManager () { + const classes = useStyles() + const { list, save, update, remove } = useHelps() + + const [showConfirmDialog, setShowConfirmDialog] = useState(false) + const [loading, setLoading] = useState(false) + const [records, setRecords] = useState([]) + const [record, setRecord] = useState({ + title: '', + description: '', + video: '' + }) + + useEffect(() => { + async function fetchData () { + await loadHelps() + } + fetchData() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + + const loadHelps = async () => { + setLoading(true) + try { + const helpList = await list() + setRecords(helpList) + } catch (e) { + toast.error('Não foi possível carregar a lista de registros') + } + setLoading(false) + } + + const handleSubmit = async (data) => { + setLoading(true) + try { + if (data.id !== undefined) { + await update(data) + } else { + await save(data) + } + await loadHelps() + handleCancel() + toast.success('Operação realizada com sucesso!') + } catch (e) { + toast.error('Não foi possível realizar a operação. Verifique se já existe uma helpo com o mesmo nome ou se os campos foram preenchidos corretamente') + } + setLoading(false) + } + + const handleDelete = async () => { + setLoading(true) + try { + await remove(record.id) + await loadHelps() + handleCancel() + toast.success('Operação realizada com sucesso!') + } catch (e) { + toast.error('Não foi possível realizar a operação') + } + setLoading(false) + } + + const handleOpenDeleteDialog = () => { + setShowConfirmDialog(true) + } + + const handleCancel = () => { + setRecord({ + title: '', + description: '', + video: '' + }) + } + + const handleSelect = (data) => { + setRecord({ + id: data.id, + title: data.title || '', + description: data.description || '', + video: data.video || '' + }) + } + + return ( + + + + + + + + + + setShowConfirmDialog(false)} + onConfirm={() => handleDelete()} + > + Deseja realmente excluir esse registro? + + + ) +} \ No newline at end of file diff --git a/frontend/src/components/LocationPreview/index.js b/frontend/src/components/LocationPreview/index.js new file mode 100644 index 0000000..c7f7b5e --- /dev/null +++ b/frontend/src/components/LocationPreview/index.js @@ -0,0 +1,50 @@ +import React, { useEffect } from 'react'; +import toastError from "../../errors/toastError"; + +import { Button, Divider, Typography} from "@material-ui/core"; + +const LocationPreview = ({ image, link, description }) => { + useEffect(() => {}, [image, link, description]); + + const handleLocation = async() => { + try { + window.open(link); + } catch (err) { + toastError(err); + } + } + + return ( + <> +
+
+
+ loc +
+ { description && ( +
+ +
') }}>
+
+
+ )} +
+
+ + +
+
+
+ + ); + +}; + +export default LocationPreview; \ No newline at end of file diff --git a/frontend/src/components/MainContainer/index.js b/frontend/src/components/MainContainer/index.js new file mode 100644 index 0000000..24b7b9a --- /dev/null +++ b/frontend/src/components/MainContainer/index.js @@ -0,0 +1,31 @@ +import React from "react"; + +import { makeStyles } from "@material-ui/core/styles"; +import Container from "@material-ui/core/Container"; + +const useStyles = makeStyles(theme => ({ + mainContainer: { + flex: 1, + padding: theme.spacing(2), + height: `calc(100% - 48px)`, + }, + + contentWrapper: { + height: "100%", + overflowY: "hidden", + display: "flex", + flexDirection: "column", + }, +})); + +const MainContainer = ({ children }) => { + const classes = useStyles(); + + return ( + +
{children}
+
+ ); +}; + +export default MainContainer; diff --git a/frontend/src/components/MainHeader/index.js b/frontend/src/components/MainHeader/index.js new file mode 100644 index 0000000..46fa8ab --- /dev/null +++ b/frontend/src/components/MainHeader/index.js @@ -0,0 +1,19 @@ +import React from "react"; + +import { makeStyles } from "@material-ui/core/styles"; + +const useStyles = makeStyles(theme => ({ + contactsHeader: { + display: "flex", + alignItems: "center", + padding: "0px 6px 6px 6px", + }, +})); + +const MainHeader = ({ children }) => { + const classes = useStyles(); + + return
{children}
; +}; + +export default MainHeader; diff --git a/frontend/src/components/MainHeaderButtonsWrapper/index.js b/frontend/src/components/MainHeaderButtonsWrapper/index.js new file mode 100644 index 0000000..ed5887c --- /dev/null +++ b/frontend/src/components/MainHeaderButtonsWrapper/index.js @@ -0,0 +1,21 @@ +import React from "react"; + +import { makeStyles } from "@material-ui/core/styles"; + +const useStyles = makeStyles(theme => ({ + MainHeaderButtonsWrapper: { + flex: "none", + marginLeft: "auto", + "& > *": { + margin: theme.spacing(1), + }, + }, +})); + +const MainHeaderButtonsWrapper = ({ children }) => { + const classes = useStyles(); + + return
{children}
; +}; + +export default MainHeaderButtonsWrapper; diff --git a/frontend/src/components/MarkdownWrapper/index.js b/frontend/src/components/MarkdownWrapper/index.js new file mode 100644 index 0000000..64764b2 --- /dev/null +++ b/frontend/src/components/MarkdownWrapper/index.js @@ -0,0 +1,186 @@ +import React from "react"; +import Markdown from "markdown-to-jsx"; + +const elements = [ + "a", + "abbr", + "address", + "area", + "article", + "aside", + "audio", + "b", + "base", + "bdi", + "bdo", + "big", + "blockquote", + "body", + "br", + "button", + "canvas", + "caption", + "cite", + "code", + "col", + "colgroup", + "data", + "datalist", + "dd", + "del", + "details", + "dfn", + "dialog", + "div", + "dl", + "dt", + "em", + "embed", + "fieldset", + "figcaption", + "figure", + "footer", + "form", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "head", + "header", + "hgroup", + "hr", + "html", + "i", + "iframe", + "img", + "input", + "ins", + "kbd", + "keygen", + "label", + "legend", + "li", + "link", + "main", + "map", + "mark", + "marquee", + "menu", + "menuitem", + "meta", + "meter", + "nav", + "noscript", + "object", + "ol", + "optgroup", + "option", + "output", + "p", + "param", + "picture", + "pre", + "progress", + "q", + "rp", + "rt", + "ruby", + "s", + "samp", + "script", + "section", + "select", + "small", + "source", + "span", + "strong", + "style", + "sub", + "summary", + "sup", + "table", + "tbody", + "td", + "textarea", + "tfoot", + "th", + "thead", + "time", + "title", + "tr", + "track", + "u", + "ul", + "var", + "video", + "wbr", + + // SVG + "circle", + "clipPath", + "defs", + "ellipse", + "foreignObject", + "g", + "image", + "line", + "linearGradient", + "marker", + "mask", + "path", + "pattern", + "polygon", + "polyline", + "radialGradient", + "rect", + "stop", + "svg", + "text", + "tspan", +]; + +const allowedElements = ["a", "b", "strong", "em", "u", "code", "del"]; + +const CustomLink = ({ children, ...props }) => ( +
+ {children} + +); + +const MarkdownWrapper = ({ children }) => { + const boldRegex = /\*(.*?)\*/g; + const tildaRegex = /~(.*?)~/g; + + if (children && boldRegex.test(children)) { + children = children.replace(boldRegex, "**$1**"); + } + if (children && tildaRegex.test(children)) { + children = children.replace(tildaRegex, "~~$1~~"); + } + + const options = React.useMemo(() => { + const markdownOptions = { + disableParsingRawHTML: true, + forceInline: true, + overrides: { + a: { component: CustomLink }, + }, + }; + + elements.forEach(element => { + if (!allowedElements.includes(element)) { + markdownOptions.overrides[element] = el => el.children || null; + } + }); + + return markdownOptions; + }, []); + + if (!children) return null; + + return {children}; +}; + +export default MarkdownWrapper; diff --git a/frontend/src/components/MessageInput/RecordingTimer.js b/frontend/src/components/MessageInput/RecordingTimer.js new file mode 100644 index 0000000..108cf50 --- /dev/null +++ b/frontend/src/components/MessageInput/RecordingTimer.js @@ -0,0 +1,48 @@ +import React, { useState, useEffect } from "react"; +import { makeStyles } from "@material-ui/core/styles"; + +const useStyles = makeStyles(theme => ({ + timerBox: { + display: "flex", + marginLeft: 10, + marginRight: 10, + alignItems: "center", + }, +})); + +const RecordingTimer = () => { + const classes = useStyles(); + const initialState = { + minutes: 0, + seconds: 0, + }; + const [timer, setTimer] = useState(initialState); + + useEffect(() => { + const interval = setInterval( + () => + setTimer(prevState => { + if (prevState.seconds === 59) { + return { ...prevState, minutes: prevState.minutes + 1, seconds: 0 }; + } + return { ...prevState, seconds: prevState.seconds + 1 }; + }), + 1000 + ); + return () => { + clearInterval(interval); + }; + }, []); + + const addZero = n => { + return n < 10 ? "0" + n : n; + }; + + return ( +
+ {`${addZero(timer.minutes)}:${addZero(timer.seconds)}`} +
+ ); +}; + +export default RecordingTimer; diff --git a/frontend/src/components/MessageInput/index.js b/frontend/src/components/MessageInput/index.js new file mode 100644 index 0000000..874b332 --- /dev/null +++ b/frontend/src/components/MessageInput/index.js @@ -0,0 +1,513 @@ +import React, { useState, useEffect, useContext, useRef } from "react"; +import "emoji-mart/css/emoji-mart.css"; +import { useParams } from "react-router-dom"; +import { Picker } from "emoji-mart"; +import MicRecorder from "mic-recorder-to-mp3"; +import clsx from "clsx"; + +import { makeStyles } from "@material-ui/core/styles"; +import Paper from "@material-ui/core/Paper"; +import InputBase from "@material-ui/core/InputBase"; +import CircularProgress from "@material-ui/core/CircularProgress"; +import { green } from "@material-ui/core/colors"; +import AttachFileIcon from "@material-ui/icons/AttachFile"; +import IconButton from "@material-ui/core/IconButton"; +import MoodIcon from "@material-ui/icons/Mood"; +import SendIcon from "@material-ui/icons/Send"; +import CancelIcon from "@material-ui/icons/Cancel"; +import ClearIcon from "@material-ui/icons/Clear"; +import MicIcon from "@material-ui/icons/Mic"; +import CheckCircleOutlineIcon from "@material-ui/icons/CheckCircleOutline"; +import HighlightOffIcon from "@material-ui/icons/HighlightOff"; +import { FormControlLabel, Switch } from "@material-ui/core"; + +import { i18n } from "../../translate/i18n"; +import api from "../../services/api"; +import RecordingTimer from "./RecordingTimer"; +import { ReplyMessageContext } from "../../context/ReplyingMessage/ReplyingMessageContext"; +import { AuthContext } from "../../context/Auth/AuthContext"; +import { useLocalStorage } from "../../hooks/useLocalStorage"; +import toastError from "../../errors/toastError"; + +const Mp3Recorder = new MicRecorder({ bitRate: 128 }); + +const useStyles = makeStyles(theme => ({ + mainWrapper: { + backgroundColor: theme.palette.bordabox, //DARK MODE PLW DESIGN// + display: "flex", + flexDirection: "column", + alignItems: "center", + borderTop: "1px solid rgba(0, 0, 0, 0.12)", + }, + + newMessageBox: { + background: "#eee", + width: "100%", + display: "flex", + padding: "7px", + alignItems: "center", + }, + + messageInputWrapper: { + padding: 6, + marginRight: 7, + background: "#fff", + display: "flex", + borderRadius: 20, + flex: 1, + }, + + messageInput: { + paddingLeft: 10, + flex: 1, + border: "none", + }, + + sendMessageIcons: { + color: "grey", + }, + + uploadInput: { + display: "none", + }, + + viewMediaInputWrapper: { + display: "flex", + padding: "10px 13px", + position: "relative", + justifyContent: "space-between", + alignItems: "center", + backgroundColor: "#eee", + borderTop: "1px solid rgba(0, 0, 0, 0.12)", + }, + + emojiBox: { + position: "absolute", + bottom: 63, + width: 40, + borderTop: "1px solid #e8e8e8", + }, + + circleLoading: { + color: green[500], + opacity: "70%", + position: "absolute", + top: "20%", + left: "50%", + marginLeft: -12, + }, + + audioLoading: { + color: green[500], + opacity: "70%", + }, + + recorderWrapper: { + display: "flex", + alignItems: "center", + alignContent: "middle", + }, + + cancelAudioIcon: { + color: "red", + }, + + sendAudioIcon: { + color: "green", + }, + + replyginMsgWrapper: { + display: "flex", + width: "100%", + alignItems: "center", + justifyContent: "center", + paddingTop: 8, + paddingLeft: 73, + paddingRight: 7, + }, + + replyginMsgContainer: { + flex: 1, + marginRight: 5, + overflowY: "hidden", + backgroundColor: "rgba(0, 0, 0, 0.05)", + borderRadius: "7.5px", + display: "flex", + position: "relative", + }, + + replyginMsgBody: { + padding: 10, + height: "auto", + display: "block", + whiteSpace: "pre-wrap", + overflow: "hidden", + }, + + replyginContactMsgSideColor: { + flex: "none", + width: "4px", + backgroundColor: "#35cd96", + }, + + replyginSelfMsgSideColor: { + flex: "none", + width: "4px", + backgroundColor: "#6bcbef", + }, + + messageContactName: { + display: "flex", + color: "#6bcbef", + fontWeight: 500, + }, +})); + +const MessageInput = ({ ticketStatus }) => { + const classes = useStyles(); + const { ticketId } = useParams(); + + const [medias, setMedias] = useState([]); + const [inputMessage, setInputMessage] = useState(""); + const [showEmoji, setShowEmoji] = useState(false); + const [loading, setLoading] = useState(false); + const [recording, setRecording] = useState(false); + const inputRef = useRef(); + const { setReplyingMessage, replyingMessage } = useContext( + ReplyMessageContext + ); + const { user } = useContext(AuthContext); + + const [signMessage, setSignMessage] = useLocalStorage("signOption", true); + + useEffect(() => { + inputRef.current.focus(); + }, [replyingMessage]); + + useEffect(() => { + inputRef.current.focus(); + return () => { + setInputMessage(""); + setShowEmoji(false); + setMedias([]); + setReplyingMessage(null); + }; + }, [ticketId, setReplyingMessage]); + + const handleChangeInput = e => { + setInputMessage(e.target.value); + }; + + const handleAddEmoji = e => { + let emoji = e.native; + setInputMessage(prevState => prevState + emoji); + }; + + const handleChangeMedias = e => { + if (!e.target.files) { + return; + } + + const selectedMedias = Array.from(e.target.files); + setMedias(selectedMedias); + }; + + const handleInputPaste = e => { + if (e.clipboardData.files[0]) { + setMedias([e.clipboardData.files[0]]); + } + }; + + const handleUploadMedia = async e => { + setLoading(true); + e.preventDefault(); + + const formData = new FormData(); + formData.append("fromMe", true); + medias.forEach(media => { + formData.append("medias", media); + formData.append("body", media.name); + }); + + try { + await api.post(`/messages/${ticketId}`, formData); + } catch (err) { + toastError(err); + } + + setLoading(false); + setMedias([]); + }; + + const handleSendMessage = async () => { + if (inputMessage.trim() === "") return; + setLoading(true); + + const message = { + read: 1, + fromMe: true, + mediaUrl: "", + body: signMessage + ? `*${user?.name}:*\n${inputMessage.trim()}` + : inputMessage.trim(), + quotedMsg: replyingMessage, + }; + try { + await api.post(`/messages/${ticketId}`, message); + } catch (err) { + toastError(err); + } + + setInputMessage(""); + setShowEmoji(false); + setLoading(false); + setReplyingMessage(null); + }; + + const handleStartRecording = async () => { + setLoading(true); + try { + await navigator.mediaDevices.getUserMedia({ audio: true }); + await Mp3Recorder.start(); + setRecording(true); + setLoading(false); + } catch (err) { + toastError(err); + setLoading(false); + } + }; + + const handleUploadAudio = async () => { + setLoading(true); + try { + const [, blob] = await Mp3Recorder.stop().getMp3(); + if (blob.size < 10000) { + setLoading(false); + setRecording(false); + return; + } + + const formData = new FormData(); + const filename = `${new Date().getTime()}.mp3`; + formData.append("medias", blob, filename); + formData.append("body", filename); + formData.append("fromMe", true); + + await api.post(`/messages/${ticketId}`, formData); + } catch (err) { + toastError(err); + } + + setRecording(false); + setLoading(false); + }; + + const handleCancelAudio = async () => { + try { + await Mp3Recorder.stop().getMp3(); + setRecording(false); + } catch (err) { + toastError(err); + } + }; + + const renderReplyingMessage = message => { + return ( +
+
+ +
+ {!message.fromMe && ( + + {message.contact?.name} + + )} + {message.body} +
+
+ setReplyingMessage(null)} + > + + +
+ ); + }; + + if (medias.length > 0) + return ( + + setMedias([])} + > + + + + {loading ? ( +
+ +
+ ) : ( + + {medias[0]?.name} + {/* */} + + )} + + + +
+ ); + else { + return ( + + {replyingMessage && renderReplyingMessage(replyingMessage)} +
+ setShowEmoji(prevState => !prevState)} + > + + + {showEmoji ? ( +
+ +
+ ) : null} + + + + { + setSignMessage(e.target.checked); + }} + name="showAllTickets" + color="primary" + /> + } + /> +
+ { + input && input.focus(); + input && (inputRef.current = input); + }} + className={classes.messageInput} + placeholder={ + ticketStatus === "open" + ? i18n.t("messagesInput.placeholderOpen") + : i18n.t("messagesInput.placeholderClosed") + } + multiline + maxRows={5} + value={inputMessage} + onChange={handleChangeInput} + disabled={recording || loading || ticketStatus !== "open"} + onPaste={e => { + ticketStatus === "open" && handleInputPaste(e); + }} + onKeyPress={e => { + if (loading || e.shiftKey) return; + else if (e.key === "Enter") { + handleSendMessage(); + } + }} + /> +
+ {inputMessage ? ( + + + + ) : recording ? ( +
+ + + + {loading ? ( +
+ +
+ ) : ( + + )} + + + + +
+ ) : ( + + + + )} +
+
+ ); + } +}; + +export default MessageInput; \ No newline at end of file diff --git a/frontend/src/components/MessageInputCustom/RecordingTimer.js b/frontend/src/components/MessageInputCustom/RecordingTimer.js new file mode 100644 index 0000000..108cf50 --- /dev/null +++ b/frontend/src/components/MessageInputCustom/RecordingTimer.js @@ -0,0 +1,48 @@ +import React, { useState, useEffect } from "react"; +import { makeStyles } from "@material-ui/core/styles"; + +const useStyles = makeStyles(theme => ({ + timerBox: { + display: "flex", + marginLeft: 10, + marginRight: 10, + alignItems: "center", + }, +})); + +const RecordingTimer = () => { + const classes = useStyles(); + const initialState = { + minutes: 0, + seconds: 0, + }; + const [timer, setTimer] = useState(initialState); + + useEffect(() => { + const interval = setInterval( + () => + setTimer(prevState => { + if (prevState.seconds === 59) { + return { ...prevState, minutes: prevState.minutes + 1, seconds: 0 }; + } + return { ...prevState, seconds: prevState.seconds + 1 }; + }), + 1000 + ); + return () => { + clearInterval(interval); + }; + }, []); + + const addZero = n => { + return n < 10 ? "0" + n : n; + }; + + return ( +
+ {`${addZero(timer.minutes)}:${addZero(timer.seconds)}`} +
+ ); +}; + +export default RecordingTimer; diff --git a/frontend/src/components/MessageInputCustom/index.js b/frontend/src/components/MessageInputCustom/index.js new file mode 100644 index 0000000..deb144f --- /dev/null +++ b/frontend/src/components/MessageInputCustom/index.js @@ -0,0 +1,773 @@ +import React, { useState, useEffect, useContext, useRef } from "react"; +import withWidth, { isWidthUp } from "@material-ui/core/withWidth"; +import "emoji-mart/css/emoji-mart.css"; +import { Picker } from "emoji-mart"; +import MicRecorder from "mic-recorder-to-mp3"; +import clsx from "clsx"; +import { isNil } from "lodash"; + +import { makeStyles } from "@material-ui/core/styles"; +import Paper from "@material-ui/core/Paper"; +import InputBase from "@material-ui/core/InputBase"; +import CircularProgress from "@material-ui/core/CircularProgress"; +import { green } from "@material-ui/core/colors"; +import AttachFileIcon from "@material-ui/icons/AttachFile"; +import IconButton from "@material-ui/core/IconButton"; +import MoodIcon from "@material-ui/icons/Mood"; +import SendIcon from "@material-ui/icons/Send"; +import CancelIcon from "@material-ui/icons/Cancel"; +import ClearIcon from "@material-ui/icons/Clear"; +import MicIcon from "@material-ui/icons/Mic"; +import CheckCircleOutlineIcon from "@material-ui/icons/CheckCircleOutline"; +import HighlightOffIcon from "@material-ui/icons/HighlightOff"; +import { FormControlLabel, Switch } from "@material-ui/core"; +import Autocomplete from "@material-ui/lab/Autocomplete"; +import { isString, isEmpty, isObject, has } from "lodash"; + +import { i18n } from "../../translate/i18n"; +import api from "../../services/api"; +import axios from "axios"; + +import RecordingTimer from "./RecordingTimer"; +import { ReplyMessageContext } from "../../context/ReplyingMessage/ReplyingMessageContext"; +import { AuthContext } from "../../context/Auth/AuthContext"; +import { useLocalStorage } from "../../hooks/useLocalStorage"; +import toastError from "../../errors/toastError"; + +import useQuickMessages from "../../hooks/useQuickMessages"; + +const Mp3Recorder = new MicRecorder({ bitRate: 128 }); + +const useStyles = makeStyles((theme) => ({ + mainWrapper: { + backgroundColor: theme.palette.bordabox, //DARK MODE PLW DESIGN// + display: "flex", + flexDirection: "column", + alignItems: "center", + borderTop: "1px solid rgba(0, 0, 0, 0.12)", + }, + + newMessageBox: { + backgroundColor: theme.palette.newmessagebox, //DARK MODE PLW DESIGN// + width: "100%", + display: "flex", + padding: "7px", + alignItems: "center", + }, + + messageInputWrapper: { + padding: 6, + marginRight: 7, + backgroundColor: theme.palette.inputdigita, //DARK MODE PLW DESIGN// + display: "flex", + borderRadius: 20, + flex: 1, + }, + + messageInput: { + paddingLeft: 10, + flex: 1, + border: "none", + }, + + sendMessageIcons: { + color: "grey", + }, + + uploadInput: { + display: "none", + }, + + viewMediaInputWrapper: { + display: "flex", + padding: "10px 13px", + position: "relative", + justifyContent: "space-between", + alignItems: "center", + backgroundColor: "#eee", + borderTop: "1px solid rgba(0, 0, 0, 0.12)", + }, + + emojiBox: { + position: "absolute", + bottom: 63, + width: 40, + borderTop: "1px solid #e8e8e8", + }, + + circleLoading: { + color: green[500], + opacity: "70%", + position: "absolute", + top: "20%", + left: "50%", + marginLeft: -12, + }, + + audioLoading: { + color: green[500], + opacity: "70%", + }, + + recorderWrapper: { + display: "flex", + alignItems: "center", + alignContent: "middle", + }, + + cancelAudioIcon: { + color: "red", + }, + + sendAudioIcon: { + color: "green", + }, + + replyginMsgWrapper: { + display: "flex", + width: "100%", + alignItems: "center", + justifyContent: "center", + paddingTop: 8, + paddingLeft: 73, + paddingRight: 7, + }, + + replyginMsgContainer: { + flex: 1, + marginRight: 5, + overflowY: "hidden", + backgroundColor: "rgba(0, 0, 0, 0.05)", + borderRadius: "7.5px", + display: "flex", + position: "relative", + }, + + replyginMsgBody: { + padding: 10, + height: "auto", + display: "block", + whiteSpace: "pre-wrap", + overflow: "hidden", + }, + + replyginContactMsgSideColor: { + flex: "none", + width: "4px", + backgroundColor: "#35cd96", + }, + + replyginSelfMsgSideColor: { + flex: "none", + width: "4px", + backgroundColor: "#6bcbef", + }, + + messageContactName: { + display: "flex", + color: "#6bcbef", + fontWeight: 500, + }, +})); + +const EmojiOptions = (props) => { + const { disabled, showEmoji, setShowEmoji, handleAddEmoji } = props; + const classes = useStyles(); + return ( + <> + setShowEmoji((prevState) => !prevState)} + > + + + {showEmoji ? ( +
+ +
+ ) : null} + + ); +}; + +const SignSwitch = (props) => { + const { width, setSignMessage, signMessage } = props; + if (isWidthUp("md", width)) { + return ( + { + setSignMessage(e.target.checked); + }} + name="showAllTickets" + color="primary" + /> + } + /> + ); + } + return null; +}; + +const FileInput = (props) => { + const { handleChangeMedias, disableOption } = props; + const classes = useStyles(); + return ( + <> + + + + ); +}; + +const ActionButtons = (props) => { + const { + inputMessage, + loading, + recording, + ticketStatus, + handleSendMessage, + handleCancelAudio, + handleUploadAudio, + handleStartRecording, + } = props; + const classes = useStyles(); + if (inputMessage) { + return ( + + + + ); + } else if (recording) { + return ( +
+ + + + {loading ? ( +
+ +
+ ) : ( + + )} + + + + +
+ ); + } else { + return ( + + + + ); + } +}; + +const CustomInput = (props) => { + const { + loading, + inputRef, + ticketStatus, + inputMessage, + setInputMessage, + handleSendMessage, + handleInputPaste, + disableOption, + handleQuickAnswersClick, + } = props; + const classes = useStyles(); + const [quickMessages, setQuickMessages] = useState([]); + const [options, setOptions] = useState([]); + const [popupOpen, setPopupOpen] = useState(false); + + const { user } = useContext(AuthContext); + + const { list: listQuickMessages } = useQuickMessages(); + + useEffect(() => { + async function fetchData() { + const companyId = localStorage.getItem("companyId"); + const messages = await listQuickMessages({ companyId, userId: user.id }); + const options = messages.map((m) => { + let truncatedMessage = m.message; + if (isString(truncatedMessage) && truncatedMessage.length > 35) { + truncatedMessage = m.message.substring(0, 35) + "..."; + } + return { + value: m.message, + label: `/${m.shortcode} - ${truncatedMessage}`, + mediaPath: m.mediaPath, + }; + }); + setQuickMessages(options); + } + fetchData(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + useEffect(() => { + if ( + isString(inputMessage) && + !isEmpty(inputMessage) && + inputMessage.length > 1 + ) { + const firstWord = inputMessage.charAt(0); + setPopupOpen(firstWord.indexOf("/") > -1); + + const filteredOptions = quickMessages.filter( + (m) => m.label.indexOf(inputMessage) > -1 + ); + setOptions(filteredOptions); + } else { + setPopupOpen(false); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [inputMessage]); + + const onKeyPress = (e) => { + if (loading || e.shiftKey) return; + else if (e.key === "Enter") { + handleSendMessage(); + } + }; + + const onPaste = (e) => { + if (ticketStatus === "open") { + handleInputPaste(e); + } + }; + + const renderPlaceholder = () => { + if (ticketStatus === "open") { + return i18n.t("messagesInput.placeholderOpen"); + } + return i18n.t("messagesInput.placeholderClosed"); + }; + + + const setInputRef = (input) => { + if (input) { + input.focus(); + inputRef.current = input; + } + }; + + return ( +
+ { + if (isObject(option)) { + return option.label; + } else { + return option; + } + }} + onChange={(event, opt) => { + + if (isObject(opt) && has(opt, "value") && isNil(opt.mediaPath)) { + setInputMessage(opt.value); + setTimeout(() => { + inputRef.current.scrollTop = inputRef.current.scrollHeight; + }, 200); + } else if (isObject(opt) && has(opt, "value") && !isNil(opt.mediaPath)) { + handleQuickAnswersClick(opt); + + setTimeout(() => { + inputRef.current.scrollTop = inputRef.current.scrollHeight; + }, 200); + } + }} + onInputChange={(event, opt, reason) => { + if (reason === "input") { + setInputMessage(event.target.value); + } + }} + onPaste={onPaste} + onKeyPress={onKeyPress} + style={{ width: "100%" }} + renderInput={(params) => { + const { InputLabelProps, InputProps, ...rest } = params; + return ( + + ); + }} + /> +
+ ); +}; + +const MessageInputCustom = (props) => { + const { ticketStatus, ticketId } = props; + const classes = useStyles(); + + const [medias, setMedias] = useState([]); + const [inputMessage, setInputMessage] = useState(""); + const [showEmoji, setShowEmoji] = useState(false); + const [loading, setLoading] = useState(false); + const [recording, setRecording] = useState(false); + const inputRef = useRef(); + const { setReplyingMessage, replyingMessage } = + useContext(ReplyMessageContext); + const { user } = useContext(AuthContext); + + const [signMessage, setSignMessage] = useLocalStorage("signOption", true); + + useEffect(() => { + inputRef.current.focus(); + }, [replyingMessage]); + + useEffect(() => { + inputRef.current.focus(); + return () => { + setInputMessage(""); + setShowEmoji(false); + setMedias([]); + setReplyingMessage(null); + }; + }, [ticketId, setReplyingMessage]); + + // const handleChangeInput = e => { + // if (isObject(e) && has(e, 'value')) { + // setInputMessage(e.value); + // } else { + // setInputMessage(e.target.value) + // } + // }; + + const handleAddEmoji = (e) => { + let emoji = e.native; + setInputMessage((prevState) => prevState + emoji); + }; + + const handleChangeMedias = (e) => { + if (!e.target.files) { + return; + } + + const selectedMedias = Array.from(e.target.files); + setMedias(selectedMedias); + }; + + const handleInputPaste = (e) => { + if (e.clipboardData.files[0]) { + setMedias([e.clipboardData.files[0]]); + } + }; + + const handleUploadQuickMessageMedia = async (blob, message) => { + setLoading(true); + try { + const extension = blob.type.split("/")[1]; + + const formData = new FormData(); + const filename = `${new Date().getTime()}.${extension}`; + formData.append("medias", blob, filename); + formData.append("body", message); + formData.append("fromMe", true); + + await api.post(`/messages/${ticketId}`, formData); + } catch (err) { + toastError(err); + setLoading(false); + } + setLoading(false); + }; + + const handleQuickAnswersClick = async (value) => { + if (value.mediaPath) { + try { + const { data } = await axios.get(value.mediaPath, { + responseType: "blob", + }); + + handleUploadQuickMessageMedia(data, value.value); + setInputMessage(""); + return; + // handleChangeMedias(response) + } catch (err) { + toastError(err); + } + } + + setInputMessage(""); + setInputMessage(value.value); + }; + + const handleUploadMedia = async (e) => { + setLoading(true); + e.preventDefault(); + + const formData = new FormData(); + formData.append("fromMe", true); + medias.forEach((media) => { + formData.append("medias", media); + formData.append("body", media.name); + }); + + try { + await api.post(`/messages/${ticketId}`, formData); + } catch (err) { + toastError(err); + } + + setLoading(false); + setMedias([]); + }; + + const handleSendMessage = async () => { + if (inputMessage.trim() === "") return; + setLoading(true); + + const message = { + read: 1, + fromMe: true, + mediaUrl: "", + body: signMessage + ? `*${user?.name}:*\n${inputMessage.trim()}` + : inputMessage.trim(), + quotedMsg: replyingMessage, + }; + try { + await api.post(`/messages/${ticketId}`, message); + } catch (err) { + toastError(err); + } + + setInputMessage(""); + setShowEmoji(false); + setLoading(false); + setReplyingMessage(null); + }; + + const handleStartRecording = async () => { + setLoading(true); + try { + await navigator.mediaDevices.getUserMedia({ audio: true }); + await Mp3Recorder.start(); + setRecording(true); + setLoading(false); + } catch (err) { + toastError(err); + setLoading(false); + } + }; + + const handleUploadAudio = async () => { + setLoading(true); + try { + const [, blob] = await Mp3Recorder.stop().getMp3(); + if (blob.size < 10000) { + setLoading(false); + setRecording(false); + return; + } + + const formData = new FormData(); + const filename = `audio-record-site-${new Date().getTime()}.mp3`; + formData.append("medias", blob, filename); + formData.append("body", filename); + formData.append("fromMe", true); + + await api.post(`/messages/${ticketId}`, formData); + } catch (err) { + toastError(err); + } + + setRecording(false); + setLoading(false); + }; + + const handleCancelAudio = async () => { + try { + await Mp3Recorder.stop().getMp3(); + setRecording(false); + } catch (err) { + toastError(err); + } + }; + + const disableOption = () => { + return loading || recording || ticketStatus !== "open"; + }; + + const renderReplyingMessage = (message) => { + return ( +
+
+ +
+ {!message.fromMe && ( + + {message.contact?.name} + + )} + {message.body} +
+
+ setReplyingMessage(null)} + > + + +
+ ); + }; + + if (medias.length > 0) + return ( + + setMedias([])} + > + + + + {loading ? ( +
+ +
+ ) : ( + + {medias[0]?.name} + {/* */} + + )} + + + +
+ ); + else { + return ( + + {replyingMessage && renderReplyingMessage(replyingMessage)} +
+ + + + + + + + + +
+
+ ); + } +}; + +export default withWidth()(MessageInputCustom); diff --git a/frontend/src/components/MessageOptionsMenu/index.js b/frontend/src/components/MessageOptionsMenu/index.js new file mode 100644 index 0000000..83a0b6e --- /dev/null +++ b/frontend/src/components/MessageOptionsMenu/index.js @@ -0,0 +1,71 @@ +import React, { useState, useContext } from "react"; + +import MenuItem from "@material-ui/core/MenuItem"; + +import { i18n } from "../../translate/i18n"; +import api from "../../services/api"; +import ConfirmationModal from "../ConfirmationModal"; +import { Menu } from "@material-ui/core"; +import { ReplyMessageContext } from "../../context/ReplyingMessage/ReplyingMessageContext"; +import toastError from "../../errors/toastError"; + +const MessageOptionsMenu = ({ message, menuOpen, handleClose, anchorEl }) => { + const { setReplyingMessage } = useContext(ReplyMessageContext); + const [confirmationOpen, setConfirmationOpen] = useState(false); + + const handleDeleteMessage = async () => { + try { + await api.delete(`/messages/${message.id}`); + } catch (err) { + toastError(err); + } + }; + + const hanldeReplyMessage = () => { + setReplyingMessage(message); + handleClose(); + }; + + const handleOpenConfirmationModal = e => { + setConfirmationOpen(true); + handleClose(); + }; + + return ( + <> + + {i18n.t("messageOptionsMenu.confirmationModal.message")} + + + {message.fromMe && ( + + {i18n.t("messageOptionsMenu.delete")} + + )} + + {i18n.t("messageOptionsMenu.reply")} + + + + ); +}; + +export default MessageOptionsMenu; diff --git a/frontend/src/components/MessageVariablesPicker/index.js b/frontend/src/components/MessageVariablesPicker/index.js new file mode 100644 index 0000000..6d6ece2 --- /dev/null +++ b/frontend/src/components/MessageVariablesPicker/index.js @@ -0,0 +1,66 @@ +import React from "react"; +import { Chip, makeStyles } from "@material-ui/core"; +import { i18n } from "../../translate/i18n"; +import OutlinedDiv from "../OutlinedDiv"; + +const useStyles = makeStyles(theme => ({ + chip: { + margin: theme.spacing(0.5), + cursor: "pointer" + } +})); + +const MessageVariablesPicker = ({ onClick, disabled }) => { + const classes = useStyles(); + + const handleClick = (e, value) => { + e.preventDefault(); + if (disabled) return; + onClick(value); + }; + + const msgVars = [ + { + name: i18n.t("messageVariablesPicker.vars.contactFirstName"), + value: "{{firstName}}" + }, + { + name: i18n.t("messageVariablesPicker.vars.contactName"), + value: "{{name}} " + }, + { + name: i18n.t("messageVariablesPicker.vars.greeting"), + value: "{{ms}} " + }, + { + name: i18n.t("messageVariablesPicker.vars.protocolNumber"), + value: "{{protocol}} " + }, + { + name: i18n.t("messageVariablesPicker.vars.hour"), + value: "{{hora}} " + }, + ]; + + return ( + + {msgVars.map(msgVar => ( + handleClick(e, msgVar.value)} + label={msgVar.name} + size="small" + className={classes.chip} + color="primary" + /> + ))} + + ); +}; + +export default MessageVariablesPicker; \ No newline at end of file diff --git a/frontend/src/components/MessagesList/index.js b/frontend/src/components/MessagesList/index.js new file mode 100644 index 0000000..3431a25 --- /dev/null +++ b/frontend/src/components/MessagesList/index.js @@ -0,0 +1,830 @@ +import React, { useState, useEffect, useReducer, useRef, useContext } from "react"; + +import { isSameDay, parseISO, format } from "date-fns"; +import clsx from "clsx"; + +import { green } from "@material-ui/core/colors"; +import { + Button, + CircularProgress, + Divider, + IconButton, + makeStyles, +} from "@material-ui/core"; + +import { + AccessTime, + Block, + Done, + DoneAll, + ExpandMore, + GetApp, +} from "@material-ui/icons"; + +import MarkdownWrapper from "../MarkdownWrapper"; +import ModalImageCors from "../ModalImageCors"; +import MessageOptionsMenu from "../MessageOptionsMenu"; +import whatsBackground from "../../assets/wa-background.png"; +import LocationPreview from "../LocationPreview"; + +import whatsBackgroundDark from "../../assets/wa-background-dark.png"; //DARK MODE PLW DESIGN// + +import api from "../../services/api"; +import toastError from "../../errors/toastError"; +import { SocketContext } from "../../context/Socket/SocketContext"; + +const useStyles = makeStyles((theme) => ({ + messagesListWrapper: { + overflow: "hidden", + position: "relative", + display: "flex", + flexDirection: "column", + flexGrow: 1, + width: "100%", + minWidth: 300, + minHeight: 200, + }, + + messagesList: { + backgroundImage: theme.mode === 'light' ? `url(${whatsBackground})` : `url(${whatsBackgroundDark})`, //DARK MODE PLW DESIGN// + display: "flex", + flexDirection: "column", + flexGrow: 1, + padding: "20px 20px 20px 20px", + overflowY: "scroll", + ...theme.scrollbarStyles, + }, + + circleLoading: { + color: green[500], + position: "absolute", + opacity: "70%", + top: 0, + left: "50%", + marginTop: 12, + }, + + messageLeft: { + marginRight: 20, + marginTop: 2, + minWidth: 100, + maxWidth: 600, + height: "auto", + display: "block", + position: "relative", + "&:hover #messageActionsButton": { + display: "flex", + position: "absolute", + top: 0, + right: 0, + }, + + whiteSpace: "pre-wrap", + backgroundColor: "#ffffff", + color: "#303030", + alignSelf: "flex-start", + borderTopLeftRadius: 0, + borderTopRightRadius: 8, + borderBottomLeftRadius: 8, + borderBottomRightRadius: 8, + paddingLeft: 5, + paddingRight: 5, + paddingTop: 5, + paddingBottom: 0, + boxShadow: "0 1px 1px #b3b3b3", + }, + + quotedContainerLeft: { + margin: "-3px -80px 6px -6px", + overflow: "hidden", + backgroundColor: "#f0f0f0", + borderRadius: "7.5px", + display: "flex", + position: "relative", + }, + + quotedMsg: { + padding: 10, + maxWidth: 300, + height: "auto", + display: "block", + whiteSpace: "pre-wrap", + overflow: "hidden", + }, + + quotedSideColorLeft: { + flex: "none", + width: "4px", + backgroundColor: "#6bcbef", + }, + + messageRight: { + marginLeft: 20, + marginTop: 2, + minWidth: 100, + maxWidth: 600, + height: "auto", + display: "block", + position: "relative", + "&:hover #messageActionsButton": { + display: "flex", + position: "absolute", + top: 0, + right: 0, + }, + + whiteSpace: "pre-wrap", + backgroundColor: "#dcf8c6", + color: "#303030", + alignSelf: "flex-end", + borderTopLeftRadius: 8, + borderTopRightRadius: 8, + borderBottomLeftRadius: 8, + borderBottomRightRadius: 0, + paddingLeft: 5, + paddingRight: 5, + paddingTop: 5, + paddingBottom: 0, + boxShadow: "0 1px 1px #b3b3b3", + }, + + quotedContainerRight: { + margin: "-3px -80px 6px -6px", + overflowY: "hidden", + backgroundColor: "#cfe9ba", + borderRadius: "7.5px", + display: "flex", + position: "relative", + }, + + quotedMsgRight: { + padding: 10, + maxWidth: 300, + height: "auto", + whiteSpace: "pre-wrap", + }, + + quotedSideColorRight: { + flex: "none", + width: "4px", + backgroundColor: "#35cd96", + }, + + messageActionsButton: { + display: "none", + position: "relative", + color: "#999", + zIndex: 1, + backgroundColor: "inherit", + opacity: "90%", + "&:hover, &.Mui-focusVisible": { backgroundColor: "inherit" }, + }, + + messageContactName: { + display: "flex", + color: "#6bcbef", + fontWeight: 500, + }, + + textContentItem: { + overflowWrap: "break-word", + padding: "3px 80px 6px 6px", + }, + + textContentItemEdited: { + overflowWrap: "break-word", + padding: "3px 120px 6px 6px", + }, + + textContentItemDeleted: { + fontStyle: "italic", + color: "rgba(0, 0, 0, 0.36)", + overflowWrap: "break-word", + padding: "3px 80px 6px 6px", + }, + + messageMedia: { + objectFit: "cover", + width: 250, + height: 200, + borderTopLeftRadius: 8, + borderTopRightRadius: 8, + borderBottomLeftRadius: 8, + borderBottomRightRadius: 8, + }, + + timestamp: { + fontSize: 11, + position: "absolute", + bottom: 0, + right: 5, + color: "#999", + }, + + dailyTimestamp: { + alignItems: "center", + textAlign: "center", + alignSelf: "center", + width: "110px", + backgroundColor: "#e1f3fb", + margin: "10px", + borderRadius: "10px", + boxShadow: "0 1px 1px #b3b3b3", + }, + + dailyTimestampText: { + color: "#808888", + padding: 8, + alignSelf: "center", + marginLeft: "0px", + }, + + ackIcons: { + fontSize: 18, + verticalAlign: "middle", + marginLeft: 4, + }, + + deletedIcon: { + fontSize: 18, + verticalAlign: "middle", + marginRight: 4, + }, + + ackDoneAllIcon: { + color: green[500], + fontSize: 18, + verticalAlign: "middle", + marginLeft: 4, + }, + + downloadMedia: { + display: "flex", + alignItems: "center", + justifyContent: "center", + backgroundColor: "inherit", + padding: 10, + }, +})); + +const reducer = (state, action) => { + if (action.type === "LOAD_MESSAGES") { + const messages = action.payload; + const newMessages = []; + + messages.forEach((message) => { + const messageIndex = state.findIndex((m) => m.id === message.id); + if (messageIndex !== -1) { + state[messageIndex] = message; + } else { + newMessages.push(message); + } + }); + + return [...newMessages, ...state]; + } + + if (action.type === "ADD_MESSAGE") { + const newMessage = action.payload; + const messageIndex = state.findIndex((m) => m.id === newMessage.id); + + if (messageIndex !== -1) { + state[messageIndex] = newMessage; + } else { + state.push(newMessage); + } + + return [...state]; + } + + if (action.type === "UPDATE_MESSAGE") { + const messageToUpdate = action.payload; + const messageIndex = state.findIndex((m) => m.id === messageToUpdate.id); + + if (messageIndex !== -1) { + state[messageIndex] = messageToUpdate; + } + + return [...state]; + } + + if (action.type === "RESET") { + return []; + } +}; + +const MessagesList = ({ ticket, ticketId, isGroup }) => { + const classes = useStyles(); + + const [messagesList, dispatch] = useReducer(reducer, []); + const [pageNumber, setPageNumber] = useState(1); + const [hasMore, setHasMore] = useState(false); + const [loading, setLoading] = useState(false); + const lastMessageRef = useRef(); + + const [selectedMessage, setSelectedMessage] = useState({}); + const [anchorEl, setAnchorEl] = useState(null); + const messageOptionsMenuOpen = Boolean(anchorEl); + const currentTicketId = useRef(ticketId); + + const socketManager = useContext(SocketContext); + + useEffect(() => { + dispatch({ type: "RESET" }); + setPageNumber(1); + + currentTicketId.current = ticketId; + }, [ticketId]); + + useEffect(() => { + setLoading(true); + const delayDebounceFn = setTimeout(() => { + const fetchMessages = async () => { + if (ticketId === undefined) return; + try { + const { data } = await api.get("/messages/" + ticketId, { + params: { pageNumber }, + }); + + if (currentTicketId.current === ticketId) { + dispatch({ type: "LOAD_MESSAGES", payload: data.messages }); + setHasMore(data.hasMore); + setLoading(false); + } + + if (pageNumber === 1 && data.messages.length > 1) { + scrollToBottom(); + } + } catch (err) { + setLoading(false); + toastError(err); + } + }; + fetchMessages(); + }, 500); + return () => { + clearTimeout(delayDebounceFn); + }; + }, [pageNumber, ticketId]); + + useEffect(() => { + const companyId = localStorage.getItem("companyId"); + const socket = socketManager.getSocket(companyId); + + socket.on("ready", () => socket.emit("joinChatBox", `${ticket.id}`)); + + socket.on(`company-${companyId}-appMessage`, (data) => { + if (data.action === "create" && data.message.ticketId === currentTicketId.current) { + dispatch({ type: "ADD_MESSAGE", payload: data.message }); + scrollToBottom(); + } + + if (data.action === "update" && data.message.ticketId === currentTicketId.current) { + dispatch({ type: "UPDATE_MESSAGE", payload: data.message }); + } + }); + + return () => { + socket.disconnect(); + }; + }, [ticketId, ticket, socketManager]); + + const loadMore = () => { + setPageNumber((prevPageNumber) => prevPageNumber + 1); + }; + + const scrollToBottom = () => { + if (lastMessageRef.current) { + lastMessageRef.current.scrollIntoView({}); + } + }; + + const handleScroll = (e) => { + if (!hasMore) return; + const { scrollTop } = e.currentTarget; + + if (scrollTop === 0) { + document.getElementById("messagesList").scrollTop = 1; + } + + if (loading) { + return; + } + + if (scrollTop < 50) { + loadMore(); + } + }; + + const handleOpenMessageOptionsMenu = (e, message) => { + setAnchorEl(e.currentTarget); + setSelectedMessage(message); + }; + + const handleCloseMessageOptionsMenu = (e) => { + setAnchorEl(null); + }; + + const checkMessageMedia = (message) => { + if (message.mediaType === "locationMessage" && message.body.split('|').length >= 2) { + let locationParts = message.body.split('|') + let imageLocation = locationParts[0] + let linkLocation = locationParts[1] + + let descriptionLocation = null + + if (locationParts.length > 2) + descriptionLocation = message.body.split('|')[2] + + return + } + /* else if (message.mediaType === "vcard") { + let array = message.body.split("\n"); + let obj = []; + let contact = ""; + for (let index = 0; index < array.length; index++) { + const v = array[index]; + let values = v.split(":"); + for (let ind = 0; ind < values.length; ind++) { + if (values[ind].indexOf("+") !== -1) { + obj.push({ number: values[ind] }); + } + if (values[ind].indexOf("FN") !== -1) { + contact = values[ind + 1]; + } + } + } + return + } */ + /*else if (message.mediaType === "multi_vcard") { + console.log("multi_vcard") + console.log(message) + + if(message.body !== null && message.body !== "") { + let newBody = JSON.parse(message.body) + return ( + <> + { + newBody.map(v => ( + + )) + } + + ) + } else return (<>) + }*/ + else if (message.mediaType === "image") { + return ; + } else if (message.mediaType === "audio") { + return ( + + ); + } else if (message.mediaType === "video") { + return ( +