@planningcenter/core-automations 1.15.0 → 1.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"core-automations.modern.mjs","sources":["../../src/assets/svg_automations.tsx","../../src/contexts/organization_context.tsx","../../src/utils/alerts.ts","../../src/utils/utils.ts","../../src/history.tsx","../../src/history_modal.tsx","../../src/utils/logos.ts","../../src/utils/response-labelers/people-form.ts","../../src/utils/resolve-response-details.ts","../../src/automation.tsx","../../src/utils/fetch-automations.ts","../../src/incoming_automations.tsx","../../src/definition.tsx","../../src/field.tsx","../../src/fields.tsx","../../src/new_automation.tsx","../../src/new_automation_modal.tsx","../../src/utils/theme.ts","../../src/automations.tsx"],"sourcesContent":["import React from \"react\"\n\nconst SvgAutomations = () => (\n <svg\n id=\"automations_blank\"\n data-name=\"Automations Blank\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 111.112 84.832\"\n className=\"symbol\"\n >\n <title>Automations</title>\n <g opacity=\"0.6\">\n <path\n d=\"M107.784,46.051A57.416,57.416,0,0,1,85.26,75.058c-9.7,6.247-20.045,7.792-31.912,5.185-11.74-2.638-23.339-8-32.92-13.088-9.51-5.342-17-10.236-18.863-17.925C-.26,41.753,3.737,31.4,13.347,21.194,22.85,11.162,37.968,1.853,55.948.321,73.8-1.476,90.2,4.478,99.608,13.164,109.257,21.9,111.921,33.784,107.784,46.051Z\"\n fill=\"#e1f0f9\"\n className=\"svg-background-blob\"\n />\n </g>\n <path\n d=\"M81,27.269v31.8a2.685,2.685,0,0,1-2.685,2.685H44.564a2.685,2.685,0,0,1-2.685-2.685V15.425a2.685,2.685,0,0,1,2.685-2.685h21.91a2.681,2.681,0,0,1,1.9.786L80.217,25.371A2.685,2.685,0,0,1,81,27.269Z\"\n fill=\"#fff\"\n />\n <path\n d=\"M68.479,13.633v9.8a2.035,2.035,0,0,0,2.035,2.034h9.877Z\"\n fill=\"#c9d8e2\"\n />\n <rect\n x=\"51.214\"\n y=\"41.285\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"51.214\"\n y=\"48.434\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"51.214\"\n y=\"34.136\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"11.771\"\n y=\"44.005\"\n width=\"50.915\"\n height=\"6.664\"\n transform=\"translate(-22.93 44.557) rotate(-49.171)\"\n fill=\"#454942\"\n />\n <path\n d=\"M56.283,30.38l-7.557,8.745a5.968,5.968,0,0,0-2.005-2.734,6.292,6.292,0,0,0-3.036-1.624l7.555-8.743a6.275,6.275,0,0,1,3.038,1.624A5.959,5.959,0,0,1,56.283,30.38Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M58.088,28.29l-7.556,8.745a5.968,5.968,0,0,0-2-2.734,6.3,6.3,0,0,0-3.036-1.624l7.555-8.743a6.274,6.274,0,0,1,3.037,1.624A5.959,5.959,0,0,1,58.088,28.29Z\"\n fill=\"#48a5e5\"\n />\n <path\n d=\"M58.724,10.432l1.17,2.7a2.129,2.129,0,0,0,1.4,1.207l2.843.765a.73.73,0,0,1,.1,1.375l-2.7,1.17a2.125,2.125,0,0,0-1.207,1.4L59.56,21.89a.73.73,0,0,1-1.374.1l-1.17-2.7a2.125,2.125,0,0,0-1.4-1.206l-2.843-.766a.73.73,0,0,1-.1-1.374l2.7-1.17a2.121,2.121,0,0,0,1.206-1.4l.766-2.844A.73.73,0,0,1,58.724,10.432Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M44.544,19.294l1.024.868a.968.968,0,0,0,.814.21l1.316-.261a.333.333,0,0,1,.319.541l-.868,1.024a.968.968,0,0,0-.21.814l.261,1.316a.333.333,0,0,1-.541.319l-1.024-.868a.968.968,0,0,0-.814-.21l-1.316.261a.333.333,0,0,1-.319-.541l.868-1.024a.967.967,0,0,0,.21-.814L44,19.613A.333.333,0,0,1,44.544,19.294Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M64.223,25.729l.869,2.005a1.575,1.575,0,0,0,1.036.895l2.109.568a.542.542,0,0,1,.075,1.02l-2,.868a1.576,1.576,0,0,0-.9,1.036l-.568,2.11a.541.541,0,0,1-1.019.074L62.955,32.3a1.572,1.572,0,0,0-1.036-.895l-2.109-.568a.542.542,0,0,1-.075-1.02l2.005-.868a1.572,1.572,0,0,0,.895-1.036L63.2,25.8A.541.541,0,0,1,64.223,25.729Z\"\n fill=\"#fcc846\"\n />\n </svg>\n)\n\nexport default SvgAutomations\n","import { createContext } from \"react\"\n\nexport const OrganizationContext = createContext({\n dateFormat: null,\n olsonTimeZone: null,\n twentyFourHourTime: null,\n})\n","import {\n createConfirmOptions,\n destroyConfirmOptions,\n errorAlertOptions,\n standardAlertOptions,\n standardConfirmOptions,\n successAlertOptions,\n} from \"@planningcenter/sweetalert2\"\nimport Swal from \"sweetalert2/dist/sweetalert2\"\n\nexport const alert = Swal.mixin(standardAlertOptions)\nexport const alertSuccess = Swal.mixin(successAlertOptions)\nexport const alertError = Swal.mixin(errorAlertOptions)\nexport const confirm = Swal.mixin(standardConfirmOptions)\nexport const confirmDestroy = Swal.mixin(destroyConfirmOptions)\nexport const confirmCreate = Swal.mixin(createConfirmOptions)\n","import { Client } from \"@planningcenter/api-client\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { cloneDeep, isBoolean, set } from \"lodash\"\nimport moment from \"moment\"\n\nexport async function deobfuscateDescriptions(\n subscriptions: AutomationInstance[]\n) {\n return Promise.all(\n subscriptions.map(async (subscription) => {\n if (isDeobfuscatable(subscription)) {\n subscription.description = await deobfuscatedDescription(subscription)\n }\n return subscription\n })\n )\n}\n\nfunction isDeobfuscatable(subscription: AutomationInstance) {\n const DEOBFUSCATABLE_OPERATION_DEFINITION_CLASS_NAMES = [\n \"AddToWorkflowOperationDefinition\",\n \"CustomFieldBooleanOperationDefinition\",\n \"CustomFieldCheckboxesOperationDefinition\",\n \"CustomFieldDateOperationDefinition\",\n \"CustomFieldNumberOperationDefinition\",\n \"CustomFieldSelectOperationDefinition\",\n \"CustomFieldStringOperationDefinition\",\n \"CustomFieldTextOperationDefinition\",\n ]\n\n return DEOBFUSCATABLE_OPERATION_DEFINITION_CLASS_NAMES.includes(\n subscription.operationDefinitionClassName\n )\n}\n\nasync function deobfuscatedDescription(subscription: AutomationInstance) {\n let description = \"\"\n if (\n subscription.operationDefinitionClassName ===\n \"AddToWorkflowOperationDefinition\"\n ) {\n const data = await fetchWorkflow(subscription.operationParams.workflowId!)\n const workflow = data[0]\n\n if (workflow?.name) {\n let workflowName\n\n if (workflow.archivedAt) {\n workflowName = `[archived] ${workflow.name}`\n } else {\n workflowName = workflow.name\n }\n\n description = subscription.description.replace(\n \"[Hidden Workflow]\",\n workflowName\n )\n }\n } else {\n // custom field\n const fieldDefinitionId =\n subscription.operationParams.definitionIdentifier.match(\n /(\\d+)_field_definition/\n )![1]\n const fieldDefinition = await fetchFieldDefinition(fieldDefinitionId)\n if (fieldDefinition.name) {\n description = subscription.description.replace(\n \"[Hidden Custom Field]\",\n fieldDefinition.name\n )\n description +=\n subscription.operationParams.values ||\n fieldDefinition.dataType !== \"checkboxes\"\n ? ` (${customFieldOptionDescription(subscription, fieldDefinition)})`\n : \"\"\n }\n }\n return description || subscription.description\n}\n\nfunction customFieldOptionDescription(\n subscription: AutomationInstance,\n fieldDefinition: {\n dataType: string\n fieldOptions: { id: number; value: string }[]\n }\n) {\n switch (fieldDefinition.dataType) {\n case \"checkboxes\":\n return Object.entries(subscription.operationParams.values ?? {})\n .map(([id, action]) => {\n const value =\n fieldDefinition.fieldOptions.find(\n (fieldOption) => fieldOption.id === parseInt(id, 10)\n )?.value || \"[Hidden value]\"\n return `${capitalize(action)} ${value}`\n })\n .join(\", \")\n case \"select\": {\n const value = subscription.operationParams.value\n return value\n ? fieldDefinition.fieldOptions.find(\n (fieldOption) => fieldOption.id === parseInt(value, 10)\n )?.value || \"[Hidden value]\"\n : \"Unanswered\"\n }\n case \"boolean\":\n switch (subscription.operationParams.value) {\n case \"true\":\n return \"Yes\"\n case \"false\":\n return \"No\"\n default:\n return \"Unanswered\"\n }\n default:\n return subscription.operationParams.value ?? \"Unanswered\"\n }\n}\n\nfunction capitalize(string: string) {\n return string.charAt(0).toUpperCase() + string.slice(1)\n}\n\nconst peopleClient = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n version: \"2025-03-20\",\n})\n\nasync function fetchWorkflow(workflowId: number) {\n const { data } = await peopleClient\n .get({\n data: {\n fields: { Workflow: \"name,archived_at\" },\n where: { id: workflowId },\n },\n url: `workflows`,\n })\n .catch(() => [{ data: { name: \"\" } }])\n\n return data\n}\n\nasync function fetchFieldDefinition(fieldDefinitionId: string) {\n const { data } = await peopleClient\n .get({\n data: {\n fields: {\n FieldDefinition: \"name,data_type,field_options\",\n FieldOption: \"value\",\n },\n include: \"field_options\",\n },\n url: `field_definitions/${fieldDefinitionId}`,\n })\n .catch(() => ({ data: { name: \"\" } }))\n\n return data\n}\n\nexport function fieldListIdentifier(field: DefinitionField) {\n if (field.listClass) {\n return `${field.id}_${field.listClass}`\n } else if (field.kind === \"PersonSearch\") {\n return `${field.id}_PersonSearch`\n } else {\n return null\n }\n}\n\nexport function buildDescription({\n selectedDefinition,\n selectedFieldOptions,\n loadedLists,\n}: {\n loadedLists: { [k: string]: LoadedList[] }\n selectedDefinition: OperationDefinition\n selectedFieldOptions: SelectedFieldOptions\n}) {\n return {\n description: describeSelectedFields({\n loadedLists: loadedLists || {},\n selectedDefinition,\n selectedFieldOptions,\n }),\n name: buildDescriptionName(selectedDefinition),\n }\n}\n\nfunction obfuscateDescriptionName(definition: OperationDefinition) {\n if (definition.definitionClass.match(/^CustomField\\w+OperationDefinition$/)) {\n return \"Update [Hidden Custom Field]\"\n }\n}\n\nfunction buildDescriptionName(definition: OperationDefinition) {\n return obfuscateDescriptionName(definition) || definition.description\n}\n\nfunction hasOwnProperty(object: object, key: PropertyKey) {\n return Object.prototype.hasOwnProperty.call(object, key)\n}\n\nfunction getListForField({\n field,\n loadedLists,\n}: {\n field: DefinitionField\n loadedLists: { [k: string]: LoadedList[] }\n}) {\n if (field.list) {\n return field.list\n } else if (fieldListIdentifier(field)) {\n const identifier = fieldListIdentifier(field) as string\n const list = loadedLists[identifier]\n\n return list\n } else {\n throw new Error(`Don't know how to get list for ${JSON.stringify(field)}`)\n }\n}\n\nexport function buildTriggerConditions({\n baseConditions,\n dynamicConditions,\n dynamicTriggerConditions,\n}: {\n baseConditions: object\n dynamicConditions: DefinitionField[] | undefined\n dynamicTriggerConditions: SelectedFieldOptions\n}) {\n const triggerConditions = cloneDeep(baseConditions)\n const fields = dynamicConditions ?? []\n const writableFields = fields.filter((field) => {\n if (field.renderOnly) return false\n return renderIfChainSatisfied(field, fields, dynamicTriggerConditions)\n })\n\n for (const field of writableFields) {\n if (\n Object.prototype.hasOwnProperty.call(dynamicTriggerConditions, field.id)\n ) {\n set(triggerConditions, field.id, dynamicTriggerConditions[field.id])\n }\n }\n\n return triggerConditions\n}\n\nfunction shouldRender(\n field: DefinitionField,\n selectedFieldOptions: SelectedFieldOptions\n) {\n if (!Object.prototype.hasOwnProperty.call(field, \"renderIf\")) return true\n\n const renderIf = field.renderIf!\n if (isBoolean(renderIf)) return renderIf\n\n const conditionKey = Object.keys(renderIf)[0]\n return renderIf[conditionKey] === selectedFieldOptions[conditionKey]\n}\n\nfunction renderIfChainSatisfied(\n field: DefinitionField,\n allFields: DefinitionField[],\n selectedFieldOptions: SelectedFieldOptions\n): boolean {\n if (!shouldRender(field, selectedFieldOptions)) return false\n\n const renderIf = field.renderIf\n if (renderIf == null || renderIf === true) return true\n\n const upstreamId = Object.keys(renderIf)[0]\n const upstream = allFields.find((f) => f.id === upstreamId)\n if (!upstream) return true\n return renderIfChainSatisfied(upstream, allFields, selectedFieldOptions)\n}\n\nexport function getRenderedFields(\n definitionFields: DefinitionField[],\n selectedFieldOptions: SelectedFieldOptions\n) {\n return definitionFields.filter(\n (field) =>\n field.kind !== \"Hidden\" &&\n renderIfChainSatisfied(field, definitionFields, selectedFieldOptions)\n )\n}\n\nfunction describeSelectedFields({\n selectedDefinition,\n selectedFieldOptions,\n loadedLists,\n}: {\n loadedLists: { [k: string]: LoadedList[] }\n selectedDefinition: OperationDefinition\n selectedFieldOptions: SelectedFieldOptions\n}) {\n const description = selectedDefinition.definitionFields\n .map((field) => {\n if (!hasOwnProperty(selectedFieldOptions, field.id)) return null\n\n const value = selectedFieldOptions[field.id]\n let list\n\n switch (field.kind) {\n case \"Select\":\n case \"SelectSearch\":\n case \"PersonSearch\":\n case \"RadioButtons\":\n list = getListForField({ field, loadedLists })\n\n return (\n list && list.find((o) => o.value.toString() === value)?.description\n )\n case \"Checkbox\":\n return value && field.label\n case \"Checkboxes\":\n list = getListForField({ field, loadedLists })\n\n return list\n .filter((e) => hasOwnProperty(value as object, e.value))\n .map(\n (e) =>\n `${capitalize((value as Record<string, string>)[e.value])} ${\n e.description\n }`\n )\n .join(\", \")\n case \"NumberField\":\n case \"TextField\":\n case \"TextArea\":\n case \"DateField\":\n return value\n default:\n throw new Error(\n `Don't know how to build value for field with kind ${field.kind}`\n )\n }\n })\n .filter((x) => x)\n .join(\", \")\n\n return obfuscateSelectedFieldDescriptions({\n description,\n loadedLists,\n selectedDefinition,\n selectedFieldOptions,\n })\n}\n\nfunction obfuscateSelectedFieldDescriptions({\n selectedDefinition,\n selectedFieldOptions,\n loadedLists,\n description,\n}: {\n description: string\n loadedLists: { [k: string]: LoadedList[] }\n selectedDefinition: OperationDefinition\n selectedFieldOptions: SelectedFieldOptions\n}) {\n if (\n selectedDefinition.definitionClass === \"AddToWorkflowOperationDefinition\"\n ) {\n const list = loadedLists.workflow_id_WorkflowsList\n const sensitiveString =\n list &&\n list.find((o) => o.value.toString() === selectedFieldOptions.workflow_id)\n ?.description\n\n return sensitiveString\n ? description.replace(sensitiveString, \"[Hidden Workflow]\")\n : description\n } else if (\n selectedDefinition.definitionClass.match(\n /^CustomField\\w+OperationDefinition$/\n )\n ) {\n return \"\"\n } else {\n return description\n }\n}\n\nexport function dateFNSFormat(format: string) {\n return format\n .replace(/%m/, \"M\")\n .replace(/%d/, \"d\")\n .replace(/%Y/, \"y\")\n .replace(/%y/, \"yy\")\n}\n\nexport function momentDateFormat(format: string) {\n return format\n .replace(/%m/, \"MM\")\n .replace(/%d/, \"DD\")\n .replace(/%Y/, \"YYYY\")\n .replace(/%y/, \"YY\")\n}\n\nexport function momentDateTimeFormat({\n dateFormat,\n twentyFourHourTime,\n}: {\n dateFormat: string\n twentyFourHourTime: boolean\n}) {\n return `${momentDateFormat(dateFormat)} ${\n twentyFourHourTime ? \"HH:mm\" : \"h:mm A\"\n }`\n}\n\nexport function dateLocalized(date: string, dateFormat: string) {\n const momentDate = moment(date, \"YYYY-MM-DD\")\n if (!momentDate.isValid()) {\n return \"\"\n }\n\n const format = momentDateFormat(dateFormat)\n return momentDate.format(format)\n}\n\nexport function numDaysSince(date: string) {\n const momentDate = moment(date, \"YYYY-MM-DD\")\n return moment().diff(momentDate, \"days\")\n}\n\nexport function pluralize(count: number, word: string) {\n if (count === 1) {\n return `1 ${word}`\n } else {\n return `${count} ${word}s`\n }\n}\n\nexport function singularize(string: string) {\n return string.replace(/s$/, \"\")\n}\n\nexport function upperFirst(string: string) {\n return string.charAt(0).toUpperCase() + string.slice(1)\n}\n\nexport function triggerResourceParts(triggerResource: string) {\n const triggerParts = triggerResource.split(\"/\")\n\n return {\n appName: triggerParts[0],\n resourceId: triggerParts[triggerParts.length - 1],\n resourcePath: triggerParts.slice(2, -1).join(\"/\"),\n resourceType: triggerParts[triggerParts.length - 2],\n }\n}\n\nexport function forbiddenText(error: any, action?: string) {\n if (error.errors?.[0]?.status === \"403\") {\n return `You don't have permission to ${action || \"modify\"} this automation.`\n }\n return null\n}\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Alert,\n Badge,\n Box,\n Button,\n DataTable,\n Heading,\n Icon,\n Input,\n Link,\n Select,\n StackView,\n Text,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport moment from \"moment\"\nimport React, { useCallback, useContext, useEffect, useState } from \"react\"\n\nimport SvgAutomations from \"./assets/svg_automations\"\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport * as alerts from \"./utils/alerts\"\nimport {\n dateLocalized,\n momentDateTimeFormat,\n numDaysSince,\n} from \"./utils/utils\"\n\ndeclare global {\n interface Window {\n openHelpdesk: () => void\n }\n}\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"2022-10-20\",\n})\nconst peopleClient = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n version: \"2022-07-14\",\n})\n\n// values should match the webhooks Event `status` enum entries\nconst STATUS = {\n delivered: {\n label: \"Success\",\n value: [\"delivered\"],\n },\n failed: {\n label: \"Failed\",\n value: [\"failed\", \"duplicated\"],\n },\n ignored: {\n label: \"Ignored\",\n value: [\"ignored_duplicated\", \"ignored_failed\", \"ignored_skipped\"],\n },\n pending: {\n label: \"Pending\",\n value: [\"pending\"],\n },\n skipped: {\n label: \"Paused\",\n value: [\"skipped\"],\n },\n}\n\nasync function fetchEvents(\n triggerResource: EncryptedTriggerResource,\n automationId: number,\n params: {\n offset: number\n per_page: number\n where?: { status: string } | null\n }\n) {\n const response = await webhooksClient.get({\n data: {\n _e: triggerResource,\n fields: {\n Delivery: \"status,response_body,created_at\",\n Event: \"id,created_at,last_delivery,payload,status,uuid,person\",\n },\n include: \"last_delivery\",\n order: \"-created_at\",\n ...params,\n },\n url: `automation_subscriptions/${automationId}/events`,\n })\n\n return response\n}\n\nasync function fetchPeople(personIds) {\n const { data } = await peopleClient.get({\n data: {\n fields: {\n Person: \"id,name\",\n },\n where: { id: personIds.join(\",\") },\n },\n url: `people`,\n })\n\n return data\n}\n\nasync function fetchPeopleWhoTriggeredEvents(events) {\n const personIds = events.data.map((e) => eventPersonId(e))\n try {\n const people = await fetchPeople(personIds)\n return { events, people }\n } catch (error) {\n return { events, people: [] }\n }\n}\n\nfunction mergePeopleAndEvents({ events, people }) {\n const mergedData = events.data.reduce((result, e) => {\n const personId = eventPersonId(e)\n const foundPerson = people.find(\n (p) => personId.toString() === p.id.toString()\n )\n if (foundPerson) {\n result.push({\n ...e,\n person: { id: foundPerson.id, name: foundPerson.name },\n })\n } else {\n result.push({\n ...e,\n person: { id: personId, name: \"[Hidden]\" },\n })\n }\n return result\n }, [])\n\n return { ...events, data: mergedData }\n}\n\nfunction eventPersonId(event) {\n return event.personId\n}\n\nfunction useEvents(\n automationId: number,\n triggerResource: EncryptedTriggerResource,\n filterWhere?: string\n) {\n const perPage = 50\n const [_, setError] = useState()\n const [loading, setLoading] = useState(false)\n const [eventPages, setEventPages] = useState<{ [k: number]: EventPage[] }>({})\n const [params, setParams] = useState<{ where?: { status: string } | null }>(\n filterWhere ? { where: { status: filterWhere } } : {}\n )\n const [meta, setMeta] = useState<{ totalCount: number | any }>()\n const { offset, paginationProps, resetOffset } = usePagination(\n perPage,\n meta?.totalCount\n )\n useEffect(() => {\n if (loading || eventPages[offset]) return\n\n setLoading(true)\n\n fetchEvents(triggerResource, automationId, {\n offset,\n per_page: perPage,\n ...params,\n })\n .then(fetchPeopleWhoTriggeredEvents)\n .then(mergePeopleAndEvents)\n .then((events) => {\n setEventPages((pages) => ({ ...pages, [offset]: events.data }))\n setMeta(events.meta)\n setLoading(false)\n })\n .catch(bubbleErrorToBoundary)\n }, [automationId, triggerResource, loading, params, offset, eventPages])\n\n const refresh = useCallback(() => {\n setEventPages({})\n setMeta(undefined)\n resetOffset()\n }, [resetOffset])\n\n useEffect(() => {\n refresh()\n }, [refresh, params])\n\n function bubbleErrorToBoundary(error) {\n setError(() => {\n throw error\n })\n }\n\n return {\n events: eventPages[offset] || [],\n loading,\n paginationProps,\n params,\n refresh,\n setParams,\n }\n}\n\nfunction usePagination(perPage: number, totalCount: number) {\n const [offset, setOffset] = useState(0)\n\n const currentPage = Math.floor(offset / perPage) + 1\n const totalPages = Math.ceil(totalCount / perPage)\n const paginationProps = { currentPage, onPageChange, totalPages }\n\n function onPageChange(pageNum: number) {\n setOffset((pageNum - 1) * perPage)\n }\n\n const resetOffset = useCallback(() => {\n setOffset(0)\n }, [])\n\n return { offset, paginationProps, resetOffset }\n}\n\ntype HistoryProps = {\n automation: AutomationInstance\n filterWhere?: string\n onEventsStatusChange: Function\n onRequestClose?: () => void\n triggerResource: EncryptedTriggerResource\n}\n\nfunction History({\n automation,\n triggerResource,\n filterWhere,\n onEventsStatusChange,\n}: HistoryProps) {\n const { events, loading, paginationProps, refresh, params, setParams } =\n useEvents(automation.id, triggerResource, filterWhere)\n const { dateFormat, olsonTimeZone, twentyFourHourTime } = useContext<{\n dateFormat: any\n olsonTimeZone: any\n twentyFourHourTime: any\n }>(OrganizationContext)\n\n const filteringEvents = params.where && Object.keys(params.where).length > 0\n const automationCreatedRecently = numDaysSince(automation.createdAt) <= 32\n const automationBeganOn = dateLocalized(automation.createdAt, dateFormat)\n const historyPreservationAlert = automationCreatedRecently\n ? `Automation history started on ${automationBeganOn}`\n : \"Automation history is saved for 32 days\"\n\n const columns = [\n {\n cell: (event: EventPage) => <EventStatusBadge status={event.status} />,\n css: {\n padding: \"8px 12px\",\n },\n header: \"Status\",\n },\n {\n cell: (event: EventPage) =>\n moment(event.createdAt)\n .utcOffset(olsonTimeZone)\n .format(momentDateTimeFormat({ dateFormat, twentyFourHourTime })),\n header: \"Date and time\",\n },\n {\n cell: (event: EventPage) => (\n <Link to={`/people/AC${event.person.id}`}>{event.person.name}</Link>\n ),\n css: {\n maxWidth: \"33%\",\n },\n header: \"Profile\",\n },\n {\n cell: (event: EventPage) => <EventStatusMessage event={event} />,\n css: {\n flex: 1,\n },\n header: \"Message\",\n },\n {\n cell: (event: EventPage) =>\n ![...STATUS.delivered.value, ...STATUS.pending.value].includes(\n event.status\n ) && (\n <>\n <RetryEventButton\n automationId={automation.id}\n event={event}\n triggerResource={triggerResource}\n onEventsStatusChange={onEventsStatusChange}\n />\n {![...STATUS.ignored.value].includes(event.status) && (\n <IgnoreEventButton\n automationId={automation.id}\n event={event}\n triggerResource={triggerResource}\n refreshHistory={refresh}\n onEventsStatusChange={onEventsStatusChange}\n />\n )}\n </>\n ),\n css: {\n textAlign: \"right\",\n },\n header: \"\",\n minWidth: \"84px\",\n },\n ]\n\n return (\n <StackView spacing={token(\"--t-spacing-4\")}>\n <StackView spacing={token(\"--t-spacing-half\")}>\n <Heading\n level={3}\n size=\"16px\"\n color={token(\"--t-text-color-secondary\")}\n weight={token(\"--t-font-weight-medium\")}\n >\n {automation.description}\n </Heading>\n <Text\n color={token(\"--t-text-color-secondary\")}\n size={token(\"--t-font-size-xs\")}\n italic\n >\n {historyPreservationAlert}\n </Text>\n </StackView>\n <StackView spacing={token(\"--t-spacing-2\")}>\n <Box minHeight={7}>\n {!loading && (events.length || filteringEvents) && (\n <StackView\n alignItems=\"end\"\n axis=\"horizontal\"\n distribution=\"space-between\"\n spacing={token(\"--t-spacing-1\")}\n >\n <StackView width=\"max-content\">\n <Input.InputLabel\n fontWeight={token(\"--t-font-weight-medium\")}\n color={token(\"--t-text-color\")}\n controls=\"select-status\"\n >\n Filter by status\n </Input.InputLabel>\n <Select\n id=\"select-status\"\n emptyValue={null}\n onChange={({ selectedValue }) => {\n const newWhere = selectedValue\n ? { status: selectedValue }\n : null\n setParams({ where: newWhere })\n }}\n title=\"Status\"\n value={params.where?.status}\n >\n <Select.Option value={null}>All</Select.Option>\n {Object.values(STATUS).map((status) => (\n <Select.Option\n key={status.value}\n value={status.value.join(\",\")}\n >\n {status.label}\n </Select.Option>\n ))}\n </Select>\n </StackView>\n <Button\n iconLeft={{ name: \"general.refresh\" }}\n onClick={refresh}\n theme=\"primary\"\n variant=\"outline\"\n width={12}\n >\n Refresh\n </Button>\n </StackView>\n )}\n </Box>\n <Box maxHeight=\"70vh\" minHeight={36} overflow=\"auto\">\n <DataTable\n columns={columns}\n data={events}\n empty={\n <StackView\n alignment=\"center\"\n distribution=\"center\"\n minHeight={20}\n maxWidth={45}\n spacing={token(\"--t-spacing-1\")}\n marginTop={!filteringEvents ? -8 : -4}\n marginBottom={!filteringEvents ? undefined : 4}\n >\n <Box\n css={{\n svg: {\n height: 15,\n width: 20,\n },\n }}\n >\n <SvgAutomations />\n </Box>\n <Heading\n color={token(\"--t-text-color-headline\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n level={4}\n size={token(\"--t-font-size-lg\")}\n >\n No history found\n </Heading>\n <Text fontSize={token(\"--t-font-size-md\")} textAlign=\"center\">\n No events {filteringEvents && \"matching your filters\"} were\n triggered for this automation{\" \"}\n {automationCreatedRecently\n ? `since ${automationBeganOn}.`\n : \"in the last 32 days.\"}\n </Text>\n {filteringEvents && (\n <Button\n marginTop={token(\"--t-spacing-1\")}\n onClick={() => setParams({})}\n theme=\"primary\"\n title=\"Clear filters\"\n variant=\"outline\"\n />\n )}\n </StackView>\n }\n loading={loading}\n loadingTitle=\"Loading automation history...\"\n variant={{\n bodyCell: {\n alignItems: \"start\",\n fontSize: token(\"--t-font-size-sm\"),\n lineHeight: \"20px\",\n padding: \"10px 12px\",\n },\n bodyRow: ({ rowData }) => {\n return {\n backgroundColor: [...STATUS.ignored.value].includes(\n rowData.status\n )\n ? token(\"--t-fill-color-neutral-090\")\n : undefined,\n minHeight: \"36px\",\n }\n },\n headerCell: {\n padding: \"8px 12px\",\n },\n headerRow: {\n minHeight: \"36px\",\n },\n }}\n {...paginationProps}\n />\n </Box>\n </StackView>\n </StackView>\n )\n}\n\nfunction RetryEventButton({\n automationId,\n event,\n triggerResource,\n onEventsStatusChange,\n}: {\n automationId: number\n event: EventPage\n onEventsStatusChange: Function\n triggerResource: EncryptedTriggerResource\n}) {\n const [status, setStatus] = useState(event.status)\n\n function handleRetry() {\n setStatus(STATUS.pending.value.join(\",\"))\n webhooksClient\n .post({\n data: {\n _e: triggerResource,\n data: { attributes: {} },\n },\n url: `/automation_subscriptions/${automationId}/events/${event.id}/redeliver`,\n })\n .then((response) => {\n setStatus(STATUS.delivered.value.join(\",\"))\n onEventsStatusChange(response.meta.eventsStatus)\n })\n .catch(() => {\n setStatus(STATUS.failed.value.join(\",\"))\n alerts.alertError.fire({\n text: \"There was a problem retrying this automation. Please try again in a few moments.\",\n title: \"Uh oh!\",\n })\n })\n }\n\n const retryTitleFromStatus = STATUS.pending.value.includes(status)\n ? \"Sending\"\n : STATUS.delivered.value.includes(status)\n ? \"Sent\"\n : STATUS.skipped.value.includes(status)\n ? \"Run now\"\n : \"Retry\"\n\n const statusIcon = STATUS.delivered.value.includes(status)\n ? { color: token(\"--t-text-color-status-success\"), name: \"general.check\" }\n : undefined\n\n return (\n <Button\n title={retryTitleFromStatus}\n onClick={handleRetry}\n iconLeft={statusIcon}\n disabled={status !== event.status}\n variant=\"naked\"\n color={\n STATUS.delivered.value.includes(status)\n ? token(\"--t-text-color-status-success\")\n : STATUS.pending.value.includes(status)\n ? token(\"--t-text-color-placeholder\")\n : token(\"--t-text-color-interaction\")\n }\n theme=\"primary\"\n size=\"xs\"\n />\n )\n}\n\nfunction IgnoreEventButton({\n automationId,\n event,\n triggerResource,\n refreshHistory,\n onEventsStatusChange,\n}: {\n automationId: number\n event: EventPage\n onEventsStatusChange: Function\n refreshHistory: Function\n triggerResource: EncryptedTriggerResource\n}) {\n function handleIgnore() {\n webhooksClient\n .post({\n data: {\n _e: triggerResource,\n data: { attributes: {} },\n },\n url: `/automation_subscriptions/${automationId}/events/${event.id}/ignore`,\n })\n .then((response) => {\n onEventsStatusChange(response.meta.eventsStatus)\n })\n .then(() => refreshHistory())\n .catch(() => {\n alerts.alertError.fire({\n text: \"There was a problem ignoring this event. Please try again in a few moments.\",\n title: \"Uh oh!\",\n })\n })\n }\n\n return (\n <Button\n title={\"Ignore\"}\n onClick={handleIgnore}\n variant=\"naked\"\n color={\"linkForeground\"}\n theme=\"primary\"\n size=\"xs\"\n />\n )\n}\n\nfunction EventStatusBadge({ status }: { status: string }) {\n const badgeColors = STATUS.pending.value.includes(status)\n ? {\n border: token(\"--t-border-color-dark\"),\n text: token(\"--t-text-color\"),\n }\n : STATUS.delivered.value.includes(status)\n ? {\n border: token(\"--t-border-color-status-success\"),\n text: token(\"--t-text-color-status-success\"),\n }\n : STATUS.skipped.value.includes(status)\n ? {\n border: token(\"--t-border-color-status-warning\"),\n text: token(\"--t-text-color-status-warning\"),\n }\n : STATUS.ignored.value.includes(status)\n ? {\n border: token(\"--t-border-color-dark\"),\n text: token(\"--t-text-color-secondary\"),\n }\n : {\n border: token(\"--t-border-color-status-error\"),\n text: token(\"--t-text-color-status-error\"),\n }\n\n const badgeIcon = STATUS.pending.value.includes(status)\n ? \"general.clock\"\n : STATUS.skipped.value.includes(status)\n ? \"services.pause\"\n : STATUS.delivered.value.includes(status)\n ? \"general.checkCircle\"\n : STATUS.ignored.value.includes(status)\n ? \"general.inactive\"\n : \"general.exclamationTriangle\"\n\n const badgeTitle = STATUS.failed.value.includes(status)\n ? STATUS.failed.label\n : STATUS.ignored.value.includes(status)\n ? STATUS.ignored.label\n : STATUS[status].label\n\n return (\n <Badge\n color={{ background: \"transparent\", foreground: badgeColors.text }}\n css={{ paddingLeft: 3.5, paddingRight: 1.5 }}\n fontSize={token(\"--t-font-size-xs\")}\n radius=\"pill\"\n renderLeft={\n <Icon\n name={badgeIcon}\n color={badgeColors.border}\n marginLeft={token(\"--t-spacing-1\")}\n />\n }\n size=\"sm\"\n stroke={badgeColors.border}\n strokeAlign=\"inside\"\n strokeWeight={1}\n title={badgeTitle}\n />\n )\n}\n\nfunction EventStatusMessage({ event }: { event: EventPage }) {\n const { status, lastDelivery } = event\n\n function statusMessage(status: string, lastDelivery: Delivery) {\n let message: string | JSX.Element | null = null\n\n switch (status) {\n case \"skipped\":\n case \"ignored_skipped\":\n message = \"Automation was paused and did not run on this profile\"\n break\n case \"failed\":\n case \"duplicated\":\n case \"ignored_failed\":\n case \"ignored_duplicated\":\n message = deliveryFailureReason(lastDelivery, status)\n }\n\n return message\n }\n\n function deliveryFailureReason(delivery: Delivery, status: string) {\n const ERRORS = {\n 403: \"Owner doesn't have permission to perform this action.\",\n 404: \"Owner lacks access to target product or resource doesn't exist.\",\n 422: \"The automation action failed to run\",\n default: \"An error occurred\",\n duplicated_event:\n \"Didn't run because the same action had already been performed less than 60 seconds ago\",\n failed_without_deliveries:\n \"Didn't run because the owner doesn't have permissions in this product.\",\n }\n\n function responseErrors(delivery: Delivery) {\n if (!delivery?.responseBody) return null\n let response\n\n try {\n response = JSON.parse(delivery.responseBody)\n } catch {\n response = { errors: [\"Server Error\"] }\n }\n\n return parsedErrors(response).join(\", \") || response?.message\n }\n\n function parsedErrors(response) {\n if (response?.errors) {\n return response.errors.map((error) =>\n typeof error === \"string\" && error.match(/Archived profiles/)\n ? error.replace(/Archived profiles/, \"Archived profiles.\")\n : error\n )\n } else {\n return []\n }\n }\n\n return (\n <StackView flex={1} whiteSpace=\"normal\">\n {!delivery ? (\n [\"duplicated\", \"ignored_duplicated\"].includes(status) ? (\n ERRORS.duplicated_event\n ) : (\n ERRORS.failed_without_deliveries\n )\n ) : (\n <ToggleableDetails\n details={responseErrors(delivery)}\n status={delivery.status}\n >\n {ERRORS[delivery.status] || ERRORS.default}\n </ToggleableDetails>\n )}\n </StackView>\n )\n }\n\n const message = statusMessage(status, lastDelivery)\n\n return message ? (\n <Box\n fontSize={token(\"--t-font-size-sm\")}\n fontStyle=\"italic\"\n lineHeight=\"16px\"\n maxWidth=\"100%\"\n paddingTop=\"1px\"\n whiteSpace=\"normal\"\n >\n {message}\n </Box>\n ) : null\n}\n\nfunction ToggleableDetails({\n children,\n details,\n status,\n}: {\n children: React.ReactNode\n details: string\n status: string\n}) {\n const [open, setOpen] = useState(false)\n\n function toggleOpen() {\n setOpen((was) => !was)\n }\n\n return (\n <StackView spacing={token(\"--t-spacing-1\")}>\n <Box>\n {children}{\" \"}\n {details && (\n <Button\n inline\n onClick={toggleOpen}\n size=\"xs\"\n theme=\"primary\"\n variant=\"naked\"\n fontStyle=\"normal\"\n >\n Details\n </Button>\n )}\n </Box>\n {open ? (\n <Box padding={1} background={token(\"--t-fill-color-neutral-090\")}>\n <Text\n fontFamily=\"monospace\"\n fontSize={token(\"--t-font-size-xs\")}\n lineHeight=\"1.2\"\n >\n {status && `${status}: `}\n {details}\n </Text>\n </Box>\n ) : null}\n </StackView>\n )\n}\n\ntype ErrorBoundaryProps = {\n children: React.ReactNode\n onRequestClose?: () => void\n}\n\ntype ErrorBoundaryState = {\n hasError: boolean\n}\n\nclass ErrorBoundary extends React.Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n constructor(props) {\n super(props)\n this.state = { hasError: false }\n }\n\n static getDerivedStateFromError() {\n return { hasError: true }\n }\n\n handleContactSupport = () => {\n if (this.props.onRequestClose) {\n this.props.onRequestClose()\n }\n window.openHelpdesk()\n }\n\n render() {\n if (this.state.hasError) {\n return (\n <Alert\n type=\"error\"\n marginVertical={1}\n padding={1.5}\n css={{ boxShadow: \"none\" }}\n >\n <Text lineHeight=\"1.35\">\n The application hit an unexpected error. If this persists after a\n few minutes, please let us know so we can get it fixed for you.{\" \"}\n <button\n style={{\n color: token(\"--t-text-color-interaction\"),\n whiteSpace: \"nowrap\",\n }}\n onClick={this.handleContactSupport}\n >\n Contact support\n </button>\n .\n </Text>\n </Alert>\n )\n }\n\n return this.props.children\n }\n}\n\n// eslint-disable-next-line react/display-name\nexport default (props: HistoryProps) => (\n <ErrorBoundary onRequestClose={props.onRequestClose}>\n <History {...props}></History>\n </ErrorBoundary>\n)\n","import { token } from \"@planningcenter/tapestry\"\nimport {\n Button,\n Heading,\n Modal,\n StackView,\n ThemeProvider,\n} from \"@planningcenter/tapestry-react\"\nimport React from \"react\"\nimport { createPortal } from \"react-dom\"\n\nfunction CloseModalIcon({ onClick }: { onClick: React.MouseEventHandler }) {\n return (\n <Button\n as=\"button\"\n height={token(\"--t-element-size-md\")}\n icon={{\n color: token(\"--t-icon-color-dim\"),\n name: \"general.x\",\n }}\n onClick={onClick}\n size=\"sm\"\n title=\"Close\"\n variant=\"naked\"\n />\n )\n}\n\nfunction HistoryModal({\n children,\n onRequestClose,\n open,\n theme,\n}: {\n children: React.ReactNode\n onRequestClose: () => void\n open: boolean\n theme: object\n}): React.ReactPortal | JSX.Element {\n return createPortal(\n <ThemeProvider theme={theme}>\n <Modal\n open={open}\n onRequestClose={onRequestClose}\n maxWidth={120}\n boxShadow=\"0 0 20px rgba(0, 0, 0, 0.15)\"\n padding={token(\"--t-spacing-4\")}\n paddingBottom={token(\"--t-spacing-3\")}\n radius={token(\"--t-border-radius-lg\")}\n >\n <StackView\n axis=\"horizontal\"\n distribution=\"space-between\"\n alignment=\"center\"\n >\n <Heading\n level={2}\n color={token(\"--t-text-color-headline\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n fontSize={token(\"--t-font-size-2xl\")}\n lineHeight=\"1.4\"\n >\n Automation history\n </Heading>\n <CloseModalIcon onClick={onRequestClose} />\n </StackView>\n {children}\n </Modal>\n </ThemeProvider>,\n document.body\n )\n}\n\nexport default HistoryModal\n","import { Logo } from \"@planningcenter/tapestry-react\"\nimport { kebabCase } from \"lodash\"\nimport type { ComponentProps } from \"react\"\n\n// Extract valid logo names from the Logo component's props\ntype ValidLogoName = NonNullable<ComponentProps<typeof Logo>[\"name\"]>\n\n// List of valid logo names from @planningcenter/tapestry-react Logo component\n// Update this list when support for new products are added to tapestry-react\nconst VALID_LOGO_NAMES: ValidLogoName[] = [\n \"api\",\n \"calendar\",\n \"check-ins\",\n \"church-center\",\n \"giving\",\n \"groups\",\n \"headcounts\",\n \"home\",\n \"login\",\n \"music-stand\",\n \"people\",\n \"planning-center\",\n \"publishing\",\n \"registrations\",\n \"services\",\n]\n\nexport const isValidLogoName = (name: string): name is ValidLogoName => {\n return VALID_LOGO_NAMES.includes(name as ValidLogoName)\n}\n\nexport const getValidLogoName = (name: string): ValidLogoName => {\n const kebabName = kebabCase(name)\n return isValidLogoName(kebabName) ? kebabName : \"planning-center\"\n}\n","import { Client } from \"@planningcenter/api-client\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { uniq } from \"lodash\"\n\nimport type { ResponseLabeler } from \"./types\"\n\nconst HIDDEN_FIELD = \"[Hidden Field]\"\nconst HIDDEN_RESPONSE = \"[Hidden Response]\"\nconst FIELD_KEY_RE = /^field_(\\d+)$/\nconst SENTINEL_VALUES = new Set([\"no-option\"])\n\nconst peopleClient = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n version: \"2025-03-20\",\n})\n\ntype FormFieldRecord = {\n fieldType: string\n fieldableId: number | null\n fieldableType: string | null\n id: number\n label: string | null\n options?: { id: number; label: string | null }[]\n}\n\ntype FieldDefinitionRecord = {\n dataType: string\n fieldOptions?: { id: number; value: string | null }[]\n id: number\n name: string | null\n}\n\ntype CampusRecord = {\n id: number\n name: string | null\n}\n\ntype ExtractedIds = {\n fieldId: string\n formId: string\n optionId: string | null\n}\n\nasync function resolve(\n subscriptions: AutomationInstance[]\n): Promise<AutomationInstance[]> {\n const extracted = subscriptions.map((sub) => ({\n ids: extractIds(sub),\n sub,\n }))\n const targets = extracted.filter(\n (entry): entry is { ids: ExtractedIds; sub: AutomationInstance } =>\n entry.ids !== null\n )\n if (targets.length === 0) return subscriptions\n\n const fieldsByForm = await fetchFormFields(\n uniq(targets.map((t) => t.ids.formId))\n )\n\n const fieldDefIds = new Set<string>()\n const campusIds = new Set<string>()\n for (const { ids } of targets) {\n const field = fieldsByForm.get(ids.formId)?.get(ids.fieldId)\n if (field?.fieldType === \"custom_field\" && field.fieldableId != null) {\n fieldDefIds.add(String(field.fieldableId))\n } else if (field?.fieldType === \"primary_campus\" && ids.optionId != null) {\n campusIds.add(ids.optionId)\n }\n }\n const [fieldDefs, campuses] = await Promise.all([\n fetchFieldDefinitions([...fieldDefIds]),\n fetchCampuses([...campusIds]),\n ])\n\n return extracted.map(({ ids, sub }) => {\n if (!ids) return sub\n return {\n ...sub,\n responseDetails: buildResponseDetails(\n ids,\n fieldsByForm,\n fieldDefs,\n campuses\n ),\n }\n })\n}\n\nfunction extractIds(subscription: AutomationInstance): ExtractedIds | null {\n const conds = subscription.triggerConditions\n const formId = conds?.data?.relationships?.form?.data?.id\n const selectedOptionsByField = conds?.data?.attributes?.selectedOptionsByField\n if (\n formId == null ||\n !selectedOptionsByField ||\n typeof selectedOptionsByField !== \"object\"\n ) {\n return null\n }\n\n for (const [key, value] of Object.entries(selectedOptionsByField)) {\n const match = FIELD_KEY_RE.exec(key)\n if (!match) continue\n const raw = (value as { $in?: unknown })?.$in\n const optionIds = (Array.isArray(raw) ? raw : raw == null ? [] : [raw])\n .map((id) => (id == null ? null : String(id)))\n .filter((id): id is string => id != null && !SENTINEL_VALUES.has(id))\n return {\n fieldId: match[1],\n formId: String(formId),\n optionId: optionIds[0] ?? null,\n }\n }\n return null\n}\n\nasync function fetchFormFields(\n formIds: string[]\n): Promise<Map<string, Map<string, FormFieldRecord>>> {\n const result = new Map<string, Map<string, FormFieldRecord>>()\n await Promise.all(\n formIds.map(async (formId) => {\n try {\n const { data } = await peopleClient.get<{ data: FormFieldRecord[] }>({\n data: {\n fields: {\n FormField: \"label,field_type,fieldable,options\",\n FormFieldOption: \"label\",\n },\n include: \"options\",\n walk: true,\n },\n url: `forms/${formId}/fields`,\n })\n const byId = new Map<string, FormFieldRecord>()\n for (const field of data) {\n byId.set(String(field.id), field)\n }\n result.set(formId, byId)\n } catch {\n result.set(formId, new Map())\n }\n })\n )\n return result\n}\n\nasync function fetchFieldDefinitions(\n ids: string[]\n): Promise<Map<string, FieldDefinitionRecord>> {\n const result = new Map<string, FieldDefinitionRecord>()\n if (ids.length === 0) return result\n\n try {\n const { data } = await peopleClient.get<{ data: FieldDefinitionRecord[] }>({\n data: {\n fields: {\n FieldDefinition: \"name,data_type,field_options\",\n FieldOption: \"value\",\n },\n include: \"field_options\",\n walk: true,\n where: { id: ids.join(\",\") },\n },\n url: \"field_definitions\",\n })\n for (const fd of data) {\n result.set(String(fd.id), fd)\n }\n } catch {\n // permission-denied or other failure: leave entries absent so the\n // resolver falls back to [Hidden response].\n }\n return result\n}\n\nasync function fetchCampuses(\n ids: string[]\n): Promise<Map<string, CampusRecord>> {\n const result = new Map<string, CampusRecord>()\n if (ids.length === 0) return result\n\n try {\n const { data } = await peopleClient.get<{ data: CampusRecord[] }>({\n data: {\n fields: { Campus: \"name\" },\n walk: true,\n where: { id: ids.join(\",\") },\n },\n url: \"campuses\",\n })\n for (const campus of data) {\n result.set(String(campus.id), campus)\n }\n } catch {\n // permission-denied or other failure: leave entries absent so the\n // resolver falls back to [Hidden response].\n }\n return result\n}\n\nfunction buildResponseDetails(\n ids: ExtractedIds,\n fieldsByForm: Map<string, Map<string, FormFieldRecord>>,\n fieldDefs: Map<string, FieldDefinitionRecord>,\n campuses: Map<string, CampusRecord>\n): ResponseDetails {\n const field = fieldsByForm.get(ids.formId)?.get(ids.fieldId)\n if (!field) return { fieldLabel: HIDDEN_FIELD, valueLabel: HIDDEN_RESPONSE }\n\n const fieldLabel = field.label || HIDDEN_FIELD\n\n if (field.fieldType === \"boolean\") {\n return { fieldLabel, valueLabel: null }\n }\n\n if (field.fieldType === \"custom_field\" && field.fieldableId != null) {\n const fd = fieldDefs.get(String(field.fieldableId))\n if (!fd) return { fieldLabel, valueLabel: HIDDEN_RESPONSE }\n if (fd.dataType === \"boolean\") return { fieldLabel, valueLabel: null }\n if (ids.optionId == null) return { fieldLabel, valueLabel: HIDDEN_RESPONSE }\n const match = (fd.fieldOptions || []).find(\n (o) => String(o.id) === ids.optionId\n )\n return { fieldLabel, valueLabel: match?.value || HIDDEN_RESPONSE }\n }\n\n if (field.fieldType === \"primary_campus\") {\n if (ids.optionId == null) return { fieldLabel, valueLabel: HIDDEN_RESPONSE }\n const campus = campuses.get(ids.optionId)\n return { fieldLabel, valueLabel: campus?.name || HIDDEN_RESPONSE }\n }\n\n if (ids.optionId == null) {\n return { fieldLabel, valueLabel: HIDDEN_RESPONSE }\n }\n const match = (field.options || []).find((o) => String(o.id) === ids.optionId)\n return { fieldLabel, valueLabel: match?.label || HIDDEN_RESPONSE }\n}\n\nconst peopleFormLabeler: ResponseLabeler = { resolve }\n\nexport { peopleFormLabeler }\n","import { peopleFormLabeler } from \"./response-labelers/people-form\"\nimport type { ResponseLabeler } from \"./response-labelers/types\"\n\nconst labelers: Record<string, ResponseLabeler> = {\n \"people.v2.events.form_submission.created\": peopleFormLabeler,\n}\n\nasync function resolveResponseDetails(\n subscriptions: AutomationInstance[]\n): Promise<AutomationInstance[]> {\n const groups = new Map<string, AutomationInstance[]>()\n for (const sub of subscriptions) {\n if (!labelers[sub.name]) continue\n const group = groups.get(sub.name) ?? []\n group.push(sub)\n groups.set(sub.name, group)\n }\n if (groups.size === 0) return subscriptions\n\n const resolvedById = new Map<number, AutomationInstance>()\n await Promise.all(\n [...groups.entries()].map(async ([name, subs]) => {\n const resolved = await labelers[name].resolve(subs)\n for (const sub of resolved) resolvedById.set(sub.id, sub)\n })\n )\n\n return subscriptions.map((sub) => resolvedById.get(sub.id) ?? sub)\n}\n\nfunction formatResponseDetails(\n responseDetails: ResponseDetails | null | undefined\n): string {\n if (!responseDetails) return \"\"\n const { fieldLabel, valueLabel } = responseDetails\n if (valueLabel == null) return ` with \"${fieldLabel}\" selected`\n return ` with \"${fieldLabel}\" selected as \"${valueLabel}\"`\n}\n\nexport { formatResponseDetails, resolveResponseDetails }\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Avatar,\n Box,\n Button,\n Card,\n Divider,\n Dropdown,\n Heading,\n Icon,\n Logo,\n StackView,\n Text,\n ToggleSwitch,\n Tooltip,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { lowerFirst, truncate } from \"lodash\"\nimport React, { createContext, useContext, useState } from \"react\"\n\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport History from \"./history\"\nimport HistoryModal from \"./history_modal\"\nimport * as alerts from \"./utils/alerts\"\nimport { getValidLogoName } from \"./utils/logos\"\nimport { formatResponseDetails } from \"./utils/resolve-response-details\"\nimport { dateLocalized, forbiddenText } from \"./utils/utils\"\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"2022-10-20\",\n})\nconst peopleClient = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n})\n\ntype AutomationProps = {\n automation: AutomationInstance\n currentPersonCanCreate: boolean\n currentPersonId: number\n disabled?: boolean\n disabledReason?: string\n trigger: {\n event: AutomationTriggerEvent\n resource: EncryptedTriggerResource\n }\n updateAutomation: React.Dispatch<React.SetStateAction<AutomationInstance>>\n}\n\ntype IncomingAutomationProps = {\n automation: IncomingAutomationInstance\n}\n\ntype EditableAutomationContextType = {\n automation: AutomationInstance\n currentPersonCanCreate?: boolean\n currentPersonId?: number\n theme: object\n trigger?: {\n event: AutomationTriggerEvent\n resource: EncryptedTriggerResource\n }\n updateAutomation?: React.Dispatch<React.SetStateAction<AutomationInstance>>\n}\n\ntype IncomingAutomationContextType = {\n automation: IncomingAutomationInstance\n}\n\nconst AutomationContext = createContext<\n EditableAutomationContextType | IncomingAutomationContextType\n>(null)\n\nfunction EditableAutomation({\n updateAutomation,\n onDelete,\n theme,\n openHistoryNow = false,\n disabled,\n disabledReason,\n ...props\n}: AutomationProps & {\n disabled: boolean\n disabledReason: string\n onDelete: (id: number) => void\n openHistoryNow: boolean\n theme?: object\n}) {\n return (\n <AutomationWrapper\n theme={theme}\n updateAutomation={updateAutomation}\n {...props}\n >\n <Header>\n <Icons />\n <Manage\n onDelete={onDelete}\n openHistoryNow={openHistoryNow}\n disabled={disabled}\n disabledReason={disabledReason}\n />\n </Header>\n <Description />\n <EditableFooter />\n </AutomationWrapper>\n )\n}\n\nfunction IncomingAutomation(props: IncomingAutomationProps) {\n return (\n <AutomationWrapper automation={props.automation}>\n <Header>\n <Icons />\n <LinkToAutomation />\n </Header>\n <IncomingDescription />\n <Footer />\n </AutomationWrapper>\n )\n}\n\nfunction IncomingDescription() {\n const { automation } = useContext(\n AutomationContext\n ) as IncomingAutomationContextType\n\n const triggerEventDescription = automation.triggerEventDescription\n const { name, description } = parseDescription(automation.description)\n const cardOpacity = !automation.active ? 0.5 : undefined\n\n return (\n <StackView\n paddingVertical={token(\"--t-spacing-2\")}\n flex={1}\n opacity={cardOpacity}\n >\n <Heading\n level={3}\n size={token(\"--t-font-size-xl\")}\n weight={token(\"--t-font-weight-medium\")}\n marginBottom={token(\"--t-spacing-half\")}\n truncate\n >\n {name}\n </Heading>\n <StackView spacing={0.75}>\n <Text\n size={token(\"--t-font-size-sm\")}\n color={token(\"--t-text-color\")}\n lineHeight=\"1.2\"\n >\n {triggerEventDescription}\n {formatResponseDetails(automation.responseDetails)}, then{\" \"}\n {lowerFirst(name)} {conditionalSuffix(automation)}\n </Text>\n <Text\n size={token(\"--t-font-size-xs\")}\n color={token(\"--t-text-color-secondary\")}\n lineHeight=\"1.2\"\n >\n {truncate(optionallyPrettifyArchivedPrefix(description), {\n length: 160,\n separator: \" \",\n })}\n </Text>\n </StackView>\n </StackView>\n )\n}\n\nfunction LinkToAutomation() {\n const { automation } = useContext(\n AutomationContext\n ) as IncomingAutomationContextType\n\n return (\n <Button\n external\n iconLeft={{ name: \"general.newWindow\" }}\n variant=\"naked\"\n size=\"sm\"\n to={automation.triggerAdminUrl}\n disabled={!automation.canManage}\n tooltip={\n !automation.canManage\n ? \"You do not have access to this resource\"\n : undefined\n }\n color={token(\"--t-text-color-secondary\")}\n hover={{\n backgroundColor: \"highlight\",\n color: token(\"--t-text-color-secondary\"),\n }}\n >\n Manage\n </Button>\n )\n}\n\nfunction AutomationWrapper({\n automation,\n updateAutomation,\n children,\n theme,\n ...rest\n}: (AutomationProps | IncomingAutomationProps) & {\n children: React.ReactNode\n theme?: object\n updateAutomation?: (automation: AutomationInstance) => void\n}) {\n return (\n <AutomationContext.Provider\n value={{\n automation,\n theme,\n updateAutomation,\n ...rest,\n }}\n >\n <Card radius={4} padding={2}>\n {children}\n </Card>\n </AutomationContext.Provider>\n )\n}\n\nfunction Header({ children }: { children: React.ReactNode }) {\n const { automation } = useContext(AutomationContext)\n\n const cardOpacity = !automation.active ? 0.5 : undefined\n\n return (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n padding={0}\n distribution=\"space-between\"\n opacity={cardOpacity}\n >\n {children}\n </StackView>\n )\n}\n\nfunction Manage({\n onDelete,\n openHistoryNow = false,\n disabled,\n disabledReason,\n}: {\n disabled: boolean\n disabledReason: string\n onDelete: (id: number) => void\n openHistoryNow: boolean\n}) {\n const {\n automation,\n currentPersonCanCreate,\n currentPersonId,\n trigger,\n theme,\n updateAutomation,\n } = useContext(AutomationContext) as EditableAutomationContextType\n const [historyVisible, setHistoryVisible] = useState(openHistoryNow)\n const isActive = automation.active\n const { name } = parseDescription(automation.description)\n\n function showHistory() {\n setHistoryVisible(true)\n }\n\n function updateEventsStatus(newStatus: AutomationInstance[\"eventsStatus\"]) {\n updateAutomation((prev) => ({ ...prev, eventsStatus: newStatus }))\n }\n\n function handleToggleActive() {\n webhooksClient\n .patch({\n data: {\n _e: trigger.resource,\n data: {\n attributes: {\n active: !isActive,\n },\n },\n },\n url: `/automation_subscriptions/${automation.id}`,\n })\n .then((data: { data: { active: boolean } }) => {\n updateAutomation((prev) => ({ ...prev, active: data.data.active }))\n })\n .catch((error) => {\n const text =\n forbiddenText(error, \"pause\") ||\n `There was a problem ${\n isActive ? \"pausing\" : \"unpausing\"\n } this automation. Please try again in a few moments.`\n alerts.alertError.fire({\n text,\n title: \"Uh oh!\",\n })\n })\n }\n\n function handleReassign() {\n alerts.confirm\n .fire({\n text: \"This automation will run with your permission levels. Other administrators who can see this automation can grant it their permissions by reassigning it to themselves.\",\n title: \"Reassign automation?\",\n })\n .then(({ isConfirmed }) => {\n if (isConfirmed) {\n webhooksClient\n .post({\n data: {\n _e: trigger.resource,\n data: { attributes: {} },\n },\n url: `/automation_subscriptions/${automation.id}/self_assign`,\n })\n .then(({ data }) => fetchCurrentPersonAvatar(data))\n .then(({ subscription, avatar }) => {\n updateAutomation((prev) => ({\n ...prev,\n createdBy: { ...prev.createdBy, avatarUrl: avatar },\n createdById: subscription.createdById,\n createdByName: subscription.createdByName,\n }))\n })\n .catch((error) => {\n const text =\n forbiddenText(error, \"update\") ||\n \"There was a problem updating this automation. Please try again in a few moments.\"\n alerts.alertError.fire({\n text,\n title: \"Uh oh!\",\n })\n })\n }\n })\n }\n\n function handleDelete() {\n alerts.confirmDestroy\n .fire({\n confirmButtonText: \"Yes, delete automation\",\n text: `Are you sure you want to delete the \"${name}\" automation? This cannot be undone.`,\n title: \"Delete this automation?\",\n })\n .then(({ isConfirmed }) => {\n if (isConfirmed) onDelete(automation.id)\n })\n }\n\n return (\n <>\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={0.75}>\n <Dropdown\n icon={{\n color: token(\"--t-icon-color\"),\n name: \"churchCenter.threeDots\",\n }}\n iconRight={false}\n title=\"Actions\"\n variant=\"naked\"\n size=\"md\"\n disabled={disabled}\n >\n <Dropdown.Item onSelect={() => showHistory()}>History</Dropdown.Item>\n {currentPersonCanCreate &&\n (automation.createdById === currentPersonId ? (\n <Dropdown.Item disabled={true}>\n <Tooltip\n placement=\"left\"\n openDelay={250}\n title=\"This automation is already assigned to you.\"\n >\n <Text>Reassign to me...</Text>\n </Tooltip>\n </Dropdown.Item>\n ) : (\n <Dropdown.Item onSelect={handleReassign}>\n Reassign to me...\n </Dropdown.Item>\n ))}\n <Dropdown.Item onSelect={handleDelete}>Delete...</Dropdown.Item>\n </Dropdown>\n <ToggleSwitch\n isChecked={isActive}\n size=\"sm\"\n onClick={handleToggleActive}\n tooltip={\n disabled\n ? disabledReason\n : isActive\n ? \"Pause automation\"\n : \"Enable automation\"\n }\n disabled={disabled}\n />\n </StackView>\n\n <HistoryModal\n open={historyVisible}\n onRequestClose={() => setHistoryVisible(false)}\n theme={theme}\n >\n <History\n automation={automation}\n triggerResource={trigger.resource}\n onEventsStatusChange={updateEventsStatus}\n onRequestClose={() => setHistoryVisible(false)}\n />\n </HistoryModal>\n </>\n )\n}\n\nfunction Icons() {\n const { automation } = useContext(AutomationContext)\n const triggerProductName = automation.name.split(\".\")[0]\n\n return (\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={0.5}>\n <Logo\n markOnly={true}\n name={getValidLogoName(triggerProductName)}\n size=\"sm\"\n theme=\"color\"\n />\n <Icon name=\"general.rightArrow\" size={1.5} />\n <Logo\n markOnly={true}\n name={getValidLogoName(automation.operationAppName)}\n size=\"sm\"\n theme=\"color\"\n />\n </StackView>\n )\n}\nfunction Footer() {\n const { automation } = useContext(AutomationContext)\n const { dateFormat } = useContext(OrganizationContext)\n const createdBySuffix = !automation.createdBy?.id ? \"(deleted profile)\" : \"\"\n const createdByName = `${automation.createdByName} ${createdBySuffix}`\n\n const cardOpacity = !automation.active ? 0.5 : undefined\n\n return (\n <>\n <Divider marginHorizontal={-2} />\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n distribution=\"space-between\"\n paddingTop={1.75}\n spacing={token(\"--t-spacing-1\")}\n opacity={cardOpacity}\n >\n <Text\n size={token(\"--t-font-size-xs\")}\n color={token(\"--t-text-color-placeholder\")}\n whiteSpace=\"nowrap\"\n >\n Updated {dateLocalized(automation.createdAt, dateFormat)}\n </Text>\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-half\")}\n maxWidth=\"calc(100% - 136px)\"\n >\n {automation.createdBy?.avatarUrl && (\n <Avatar\n width={2}\n height={2}\n basis={2}\n key={createdByName}\n source={automation.createdBy.avatarUrl}\n />\n )}\n <Text size={5} truncate>\n {createdByName}\n </Text>\n </StackView>\n </StackView>\n </>\n )\n}\n\nfunction EditableFooter() {\n const { dateFormat } = useContext(OrganizationContext)\n const { automation, trigger, theme, updateAutomation } = useContext(\n AutomationContext\n ) as EditableAutomationContextType\n\n const createdBySuffix = !automation.createdBy?.id ? \"(deleted profile)\" : \"\"\n const createdByName = `${automation.createdByName} ${createdBySuffix}`\n\n const cardOpacity = !automation.active ? 0.5 : undefined\n const buttonProps = {\n color: token(\"--t-text-color-secondary\"),\n fontSize: token(\"--t-font-size-xs\"),\n fontWeight: token(\"--t-font-weight-normal\"),\n paddingHorizontal: token(\"--t-spacing-1\"),\n radius: \"pill\",\n size: \"xs\",\n variant: \"naked\",\n }\n const [historyProps, setHistoryProps] = useState({\n filter: null,\n historyVisible: false,\n })\n\n function renderSkippedHistory() {\n setHistoryProps({ filter: \"skipped\", historyVisible: true })\n }\n\n function renderFailedOrDuplicatedHistory() {\n setHistoryProps({ filter: \"failed,duplicated\", historyVisible: true })\n }\n\n function handleEventsStatusChange(\n newStatus: AutomationInstance[\"eventsStatus\"]\n ) {\n updateAutomation((prev) => ({ ...prev, eventsStatus: newStatus }))\n }\n\n return (\n <>\n <Divider marginHorizontal={-2} />\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n distribution=\"space-between\"\n paddingTop={1.75}\n spacing={token(\"--t-spacing-1\")}\n opacity={cardOpacity}\n >\n <Text\n size={token(\"--t-font-size-xs\")}\n color={token(\"--t-text-color-placeholder\")}\n whiteSpace=\"nowrap\"\n >\n Updated {dateLocalized(automation.createdAt, dateFormat)}\n </Text>\n\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-fourth\")}\n >\n {!!automation.eventsStatus?.skipped && (\n <Button\n {...buttonProps}\n aria-label={`${automation.eventsStatus.skipped} skipped`}\n onClick={renderSkippedHistory}\n tooltip={`${automation.eventsStatus.skipped?.toLocaleString()} skipped events`}\n >\n <Box\n backgroundColor={token(\"--t-fill-color-status-warning\")}\n marginRight={token(\"--t-spacing-half\")}\n radius=\"circle\"\n height=\"10px\"\n width=\"10px\"\n padding={token(\"--t-spacing-fourth\")}\n >\n <Icon\n name={\"services.pause\"}\n size={\"6px\"}\n title={\"Skipped\"}\n color=\"white\"\n />\n </Box>\n {`${automation.eventsStatus.skipped?.toLocaleString()}`}\n </Button>\n )}\n {!!automation.eventsStatus?.failed && (\n <Button\n {...buttonProps}\n aria-label={`${automation.eventsStatus.failed} failed`}\n iconLeft={{\n color: token(\"--t-icon-color-status-error\"),\n marginRight: token(\"--t-spacing-half\"),\n name: \"general.exclamationTriangle\",\n size: \"10px\",\n title: \"Failed\",\n }}\n onClick={renderFailedOrDuplicatedHistory}\n title={`${automation.eventsStatus.failed?.toLocaleString()}`}\n tooltip={`${automation.eventsStatus.failed?.toLocaleString()} failed events`}\n />\n )}\n </StackView>\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n distribution=\"end\"\n flex={1}\n spacing={token(\"--t-spacing-half\")}\n marginLeft=\"auto\"\n >\n {automation.createdBy?.avatarUrl && (\n <Avatar\n width={token(\"--t-element-size-md\")}\n height={token(\"--t-element-size-md\")}\n basis={token(\"--t-element-size-md\")}\n key={createdByName}\n source={automation.createdBy.avatarUrl}\n />\n )}\n <Text size={token(\"--t-font-size-sm\")} truncate>\n {createdByName}\n </Text>\n </StackView>\n </StackView>\n\n <HistoryModal\n open={historyProps.historyVisible}\n onRequestClose={() =>\n setHistoryProps({ filter: null, historyVisible: false })\n }\n theme={theme}\n >\n <History\n automation={automation}\n triggerResource={trigger.resource}\n filterWhere={historyProps.filter}\n onEventsStatusChange={handleEventsStatusChange}\n onRequestClose={() =>\n setHistoryProps({ filter: null, historyVisible: false })\n }\n />\n </HistoryModal>\n </>\n )\n}\n\nfunction Description() {\n const { automation, trigger } = useContext(\n AutomationContext\n ) as EditableAutomationContextType\n\n const { name, description } = parseDescription(automation.description)\n const cardOpacity = !automation.active ? 0.5 : undefined\n\n const triggerEventDescription = [\n \"When a person\",\n lowerFirst(trigger.event.description) +\n formatResponseDetails(automation.responseDetails) +\n \",\",\n \"then\",\n lowerFirst(name),\n conditionalSuffix(automation),\n ].join(\" \")\n\n return (\n <StackView\n paddingVertical={token(\"--t-spacing-2\")}\n flex={1}\n opacity={cardOpacity}\n >\n <Heading\n level={3}\n size={token(\"--t-font-size-xl\")}\n weight={token(\"--t-font-weight-bold\")}\n marginBottom={token(\"--t-spacing-half\")}\n truncate\n >\n {name}\n </Heading>\n <StackView spacing={0.75}>\n <Text\n size={token(\"--t-font-size-sm\")}\n color={token(\"--t-text-color\")}\n lineHeight=\"1.2\"\n >\n {triggerEventDescription}\n </Text>\n <Text\n size={token(\"--t-font-size-xs\")}\n color={token(\"--t-text-color-secondary\")}\n lineHeight=\"1.2\"\n >\n {truncate(optionallyPrettifyArchivedPrefix(description), {\n length: 160,\n separator: \" \",\n })}\n </Text>\n </StackView>\n </StackView>\n )\n}\n\nfunction conditionalSuffix(automation: AutomationInstance) {\n return automation?.triggerParams?.useTriggerPersonOverride\n ? \"(also applies to joint donor)\"\n : \"\"\n}\n\nfunction parseDescription(description: string) {\n const match = /^(.+?)\\(([^()]*?)\\)$/.exec(description)\n\n if (match) {\n return { description: match[\"2\"], name: match[\"1\"].trim() }\n } else {\n return { name: description }\n }\n}\n\nfunction optionallyPrettifyArchivedPrefix(description: string) {\n if (description?.startsWith(\"[archived]\")) {\n return description.replace(\"[archived]\", \"[Archived]\")\n } else {\n return description\n }\n}\n\nasync function fetchCurrentPersonAvatar(subscription: AutomationInstance) {\n const {\n data: { avatar },\n } = await peopleClient.get({\n data: {\n fields: { Person: \"avatar\" },\n },\n url: \"me\",\n })\n\n return { avatar, subscription }\n}\n\nexport { EditableAutomation, IncomingAutomation }\n","import { Client } from \"@planningcenter/api-client\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { compact, uniq } from \"lodash\"\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"2022-10-20\",\n})\nconst peopleClient = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n})\n\nasync function fetchAutomations(triggerResource: EncryptedTriggerResource) {\n const { data } = await webhooksClient.get({\n data: {\n _e: triggerResource,\n fields: {\n AutomationSubscription:\n \"id,description,created_at,created_by,operation_app_name,operation_definition_class_name,operation_params,active,created_by_name,name,trigger_admin_url,events_status,trigger_conditions,trigger_params\",\n Person: \"name\",\n },\n include: \"created_by\",\n },\n url: \"automation_subscriptions\",\n })\n\n return data\n}\n\nasync function fetchCreatorProfiles(subscriptions: AutomationInstance[]) {\n const personIds = compact(\n uniq(subscriptions.map((subscription) => subscription.createdById))\n )\n\n try {\n const { data: profiles } = await peopleClient.get({\n data: {\n fields: { Person: \"avatar\" },\n where: { id: personIds.join(\",\") },\n },\n url: \"people\",\n })\n return { profiles, subscriptions }\n } catch (error) {\n return { profiles: [], subscriptions }\n }\n}\n\nfunction mergeProfilesAndSubscriptions({\n profiles,\n subscriptions,\n}: {\n profiles: { avatar: string; id: number }[]\n subscriptions: AutomationInstance[]\n}) {\n const subscriptionsWithAvatars = subscriptions.map((subscription) => {\n const avatar = profiles.find(\n (profile) => profile.id === subscription.createdById\n )\n return {\n ...subscription,\n createdBy: { ...subscription.createdBy, avatarUrl: avatar?.avatar },\n }\n })\n\n return subscriptionsWithAvatars\n}\n\nasync function fetchPersonApps() {\n return peopleClient\n .get({\n data: {\n fields: { App: [\"name\"], PersonApp: [\"app\", \"allow_pco_login\"] },\n include: [\"app\"],\n },\n url: `/me/person_apps`,\n })\n .then(({ data }) => {\n return data\n .filter((personApp: PersonApp) => personApp.allowPcoLogin)\n .map((personApp: PersonApp) => personApp.app.name.toLowerCase())\n })\n}\n\nexport {\n fetchAutomations,\n fetchCreatorProfiles,\n fetchPersonApps,\n mergeProfilesAndSubscriptions,\n}\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Box,\n Heading,\n Spinner,\n Summary,\n Text,\n TileView,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { truncate, upperFirst } from \"lodash\"\nimport React, { useEffect, useState } from \"react\"\n\nimport { IncomingAutomation } from \"./automation\"\nimport {\n fetchCreatorProfiles,\n fetchPersonApps,\n mergeProfilesAndSubscriptions,\n} from \"./utils/fetch-automations\"\nimport { resolveResponseDetails } from \"./utils/resolve-response-details\"\nimport {\n deobfuscateDescriptions,\n pluralize,\n singularize,\n triggerResourceParts,\n} from \"./utils/utils\"\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"2022-10-20\",\n})\n\nasync function fetchIncomingAutomations(encryptedParam) {\n const { data } = await webhooksClient.get({\n data: {\n _e: encryptedParam,\n fields: {\n AutomationSubscription:\n \"id,description,created_at,created_by,operation_app_name,operation_definition_class_name,operation_params,active,created_by_name,name,trigger_admin_url,trigger_conditions,trigger_resource,trigger_params\",\n Person: \"name\",\n },\n include: \"created_by\",\n },\n url: \"incoming_automation_subscriptions\",\n })\n\n return data\n}\n\nasync function fetchTriggerResources(automations) {\n // We can optimize the query by fetching all the resources at once if we know\n // that the endpoint supports querying by multiple ids. Otherwise, we'll have\n // to fetch each resource individually.\n const QUERYABLE_BY_MULTIPLE_IDS = {\n people: [\"forms\", \"lists\"],\n registrations: [\"events\"],\n services: [\"teams\"],\n }\n const NOT_QUERYABLE = [\"giving\"]\n\n const automationsByModel = automations.reduce((accumulator, automation) => {\n // registrations has a weird case of signup vs event\n const automationTriggerResource = automation.triggerResource.replace(\n /signup/,\n \"event\"\n )\n const { appName, resourceType, resourcePath, resourceId } =\n triggerResourceParts(automationTriggerResource)\n\n if (!accumulator[appName]) accumulator[appName] = {}\n if (!accumulator[appName][resourceType])\n accumulator[appName][resourceType] = {}\n if (!accumulator[appName][resourceType][\"resoucePath\"])\n accumulator[appName][resourceType][\"resourcePath\"] = resourcePath\n\n if (!accumulator[appName][resourceType][\"ids\"])\n accumulator[appName][resourceType][\"ids\"] = []\n\n accumulator[appName][resourceType][\"ids\"].push(resourceId)\n\n return accumulator\n }, {})\n\n const promises = Object.keys(automationsByModel).flatMap((appName) => {\n const automationsByResourceType = automationsByModel[appName]\n\n return Object.entries(automationsByResourceType).flatMap(\n ([resourceType, resourceParts]) => {\n const fetchFn = NOT_QUERYABLE.includes(appName)\n ? fetchNothing\n : QUERYABLE_BY_MULTIPLE_IDS[appName]?.includes(resourceType)\n ? fetchAllAtOnce\n : fetchOneAtATime\n\n return fetchFn({\n appName,\n ids: resourceParts[\"ids\"],\n resourcePath: resourceParts[\"resourcePath\"],\n resourceType,\n })\n }\n )\n })\n\n const results = await Promise.allSettled(promises)\n\n return {\n automations,\n triggerResources: collectSuccessfulResults(results),\n }\n}\n\nfunction collectSuccessfulResults(settledPromises) {\n return settledPromises\n .reduce((acc, result) => {\n if (result.status === \"fulfilled\") acc = acc.concat(result.value)\n\n return acc\n }, [])\n .flatMap((d) => d.data)\n}\n\nfunction fetchAllAtOnce({ appName, resourcePath, resourceType, ids }) {\n return fetchResourceName({\n appName,\n params: {\n where: { id: ids.join(\",\") },\n },\n path: resourcePath,\n resourceType,\n })\n}\n\nfunction fetchOneAtATime({ appName, resourcePath, resourceType, ids }) {\n return ids.map((id) =>\n fetchResourceName({\n appName,\n path: `${resourcePath}/${id}`,\n resourceType,\n })\n )\n}\n\nfunction fetchNothing(_props: object) {\n return new Promise((_, reject) => {\n reject()\n })\n}\n\n// TODO (maybe): move these to webhooks, return the verb in the API response,\n// so new events don't need a code change in both places\nfunction mapNameToVerb(messageName) {\n // e.g. \"groups.v2.events.membership.created\" => \"groups.membership.created\"\n const appResourceAction = messageName.replace(\"v2.events.\", \"\")\n\n switch (appResourceAction) {\n case \"groups.membership.created\":\n return \"joins\"\n case \"groups.membership.destroyed\":\n return \"leaves\"\n case \"people.list_result.created\":\n case \"services.team_person.created\":\n return \"is added to\"\n case \"people.list_result.destroyed\":\n case \"services.team_person.destroyed\":\n return \"is removed from\"\n case \"people.form_submission.created\":\n return \"submits\"\n case \"registrations.attendee.created\":\n return \"is registered as a new attendee for\"\n case \"registrations.attendee.cancelled\":\n return \"is canceled as an attendee for\"\n case \"registrations.registration.created\":\n return \"is the registration contact on a new registration for\"\n case \"registrations.registration.cancelled\":\n return \"is the registration contact on a canceled registration for\"\n default:\n return null\n }\n}\n\nfunction buildGivingDescription(automation: AutomationInstance) {\n const action = automation.name.replace(\"giving.v2.events.\", \"\")\n\n switch (action) {\n case \"donation.payment_successful\":\n return \"When a person gives\"\n case \"profile.first_donated_automation\":\n return \"When a person gives for the first time\"\n case \"recurring_donation.setup_successful\":\n return \"When a person sets up a recurring donation\"\n default:\n return null\n }\n}\n\nfunction buildDescription(automation, triggerResourceName) {\n const verb = mapNameToVerb(automation.name)\n\n const { resourceType } = triggerResourceParts(automation.triggerResource)\n\n if (!verb) {\n // No verb mapping for this message name, so just show something generic\n const resourceName = truncate(triggerResourceName, {\n length: 160,\n separator: \" \",\n })\n\n return `When the automation is triggered from ${singularize(\n resourceType\n )} \"${resourceName}\"`\n }\n\n return `When a person ${verb} ${singularize(\n resourceType\n )} \"${triggerResourceName}\"`\n}\n\nfunction fetchResourceName({\n appName,\n path,\n resourceType,\n params = {},\n}): Promise<any> {\n const client = new Client({ root: pcoApiUrl(appName, { squiggly: false }) })\n const model = upperFirst(singularize(resourceType))\n\n return client.get({\n data: {\n fields: {\n [model]: [\"name\", \"name_or_description\"],\n },\n ...params,\n },\n url: path,\n })\n}\n\nfunction mergeTriggerResourceEventDescriptions({\n automations,\n triggerResources,\n operationApps,\n}) {\n return automations.map((automation) => {\n const { appName, resourceType, resourceId } = triggerResourceParts(\n automation.triggerResource\n )\n\n if (appName === \"giving\") {\n automation.triggerEventDescription = buildGivingDescription(automation)\n automation.canManage = operationApps.find((app) => app === \"giving\")\n\n return automation\n }\n\n // find the result that matches this automation\n const result = triggerResources.find(\n (tr) => tr.id.toString() == resourceId.toString()\n )\n\n const resourceName = result\n ? result.name || result.nameOrDescription\n : `[Hidden ${upperFirst(singularize(resourceType))}]`\n\n automation.triggerEventDescription = buildDescription(\n automation,\n resourceName\n )\n\n automation.canManage = !!result\n\n return automation\n })\n}\n\nfunction IncomingAutomations({\n encryptedParam,\n trigger,\n}: {\n encryptedParam: string\n trigger?: AutomationTrigger\n}) {\n const [loading, setLoading] = useState(true)\n const [automations, setAutomations] = useState<IncomingAutomationInstance[]>()\n\n useEffect(() => {\n fetchPersonApps().then((operationApps) => {\n fetchIncomingAutomations(encryptedParam)\n .then(fetchCreatorProfiles)\n .then(mergeProfilesAndSubscriptions)\n .then(deobfuscateDescriptions)\n .then(resolveResponseDetails)\n .then(fetchTriggerResources)\n .then(({ automations, triggerResources }) =>\n mergeTriggerResourceEventDescriptions({\n automations,\n operationApps,\n triggerResources,\n })\n )\n .then(setAutomations)\n .then(() => setLoading(false))\n })\n }, [encryptedParam])\n\n const noResults = !loading && automations.length === 0\n\n return (\n <>\n <Box\n borderBottom={`1px solid ${token(\"--t-border-color\")}`}\n marginBottom={token(\"--t-spacing-2\")}\n marginHorizontal={-3}\n marginTop={trigger ? 12 : 0}\n paddingHorizontal={token(\"--t-spacing-3\")}\n paddingVertical={token(\"--t-spacing-2\")}\n >\n <Heading\n color={token(\"--t-text-color-headline\")}\n level={2}\n size={token(\"--t-font-size-lg\")}\n >\n {loading\n ? \"Incoming automations\"\n : pluralize(automations.length, \"incoming automation\")}\n </Heading>\n </Box>\n {noResults ? (\n <Text\n color={token(\"--t-text-color-secondary\")}\n marginVertical={token(\"--t-spacing-3\")}\n >\n Automations that perform actions on this resource will be listed here.\n </Text>\n ) : loading ? (\n <Summary\n image={<Spinner size=\"xl\" />}\n paddingVertical={10}\n title={\"Loading incoming automations...\"}\n />\n ) : (\n <TileView\n spacing={token(\"--t-spacing-3\")}\n marginVertical={token(\"--t-spacing-3\")}\n minCellWidth={45}\n >\n {automations.map((automation) => (\n <IncomingAutomation key={automation.id} automation={automation} />\n ))}\n </TileView>\n )}\n </>\n )\n}\n\nexport default IncomingAutomations\n","import { token } from \"@planningcenter/tapestry\"\nimport { Select, StackView } from \"@planningcenter/tapestry-react\"\nimport { groupBy, uniqBy } from \"lodash\"\nimport React from \"react\"\n\nfunction operationDefinitionId(od: OperationDefinition) {\n return `OPERATION_${od.definitionClass}${od.definitionIdentifier || \"\"}`\n}\n\nfunction sectionId(section: string) {\n return `SECTION_${section}`\n}\n\nfunction idType(value: string) {\n if (value.startsWith(\"SECTION\")) {\n return \"section\"\n } else if (value.startsWith(\"OPERATION\")) {\n return \"operation\"\n } else if (!value) {\n return null\n } else {\n throw new Error(`Unexpected value: ${value}`)\n }\n}\n\nfunction renderOptionsWithoutConsideringGroup(\n options: { label: string; value: string | number }[]\n) {\n return options.map(({ label, value }) => (\n <Select.Option key={value} value={value}>\n {label}\n </Select.Option>\n ))\n}\n\nfunction renderOptions(\n options: { group?: string | null; label: string; value: string | number }[]\n) {\n const groupedOptions = groupBy(options, \"group\")\n const groupTypes = Object.keys(groupedOptions).sort()\n return groupTypes.map((gt) =>\n gt === \"null\" ? (\n renderOptionsWithoutConsideringGroup(groupedOptions[gt])\n ) : (\n <Select.OptionGroup key={gt} title={gt}>\n {renderOptionsWithoutConsideringGroup(groupedOptions[gt])}\n </Select.OptionGroup>\n )\n )\n}\n\nconst Definition = ({\n selectedOperation,\n onOperationDefinitionChange,\n operationDefinitions,\n}: {\n onOperationDefinitionChange: Function\n operationDefinitions: OperationDefinition[]\n selectedOperation: OperationDefinition\n}) => {\n const selectedSection = selectedOperation?.section\n\n const operationDefinitionsWithUniqueIds = operationDefinitions.map((od) => ({\n ...od,\n id: operationDefinitionId(od),\n }))\n\n const primaryOperations = operationDefinitionsWithUniqueIds.filter(\n (od) => od.section === null\n )\n\n const primarySectionOptions = uniqBy(operationDefinitions, \"section\")\n .filter((od) => !!od.section)\n .map((od) => ({\n group: od.sectionGroup,\n label: od.section,\n value: sectionId(od.section),\n }))\n\n const secondaryOperations = selectedSection\n ? operationDefinitionsWithUniqueIds.filter(\n (od) => od.section === selectedSection\n )\n : []\n\n function handleAnySelectChange({ selectedValue }) {\n switch (idType(selectedValue)) {\n case \"section\":\n onOperationDefinitionChange(\n operationDefinitions.find(\n (od) => sectionId(od.section) === selectedValue\n )\n )\n break\n case \"operation\":\n onOperationDefinitionChange(\n operationDefinitions.find(\n (od) => operationDefinitionId(od) === selectedValue\n )\n )\n break\n case null:\n onOperationDefinitionChange(null)\n break\n }\n }\n\n function renderOperations(operations: OperationDefinition[]) {\n const operationsAsOptions = operations.map((o) => ({\n group: o.group,\n label: o.description,\n value: o.id,\n }))\n\n return renderOptions(operationsAsOptions)\n }\n\n return (\n <StackView spacing={token(\"--t-spacing-1\")}>\n <Select\n emptyValue=\"Select an action\"\n id=\"select-action\"\n onChange={handleAnySelectChange}\n size=\"lg\"\n data-testid=\"operation-select\"\n >\n {renderOperations(primaryOperations)}\n {renderOptions(primarySectionOptions)}\n </Select>\n {secondaryOperations.length > 0 && (\n <Select\n defaultValue={secondaryOperations[0].id}\n onChange={handleAnySelectChange}\n size=\"lg\"\n >\n {renderOperations(secondaryOperations)}\n </Select>\n )}\n </StackView>\n )\n}\n\nexport default Definition\n","import { token } from \"@planningcenter/tapestry\"\nimport {\n Alert,\n Avatar,\n Badge,\n Box,\n Checkbox as TapestryCheckbox,\n Combobox as TapestryCombobox,\n DateField as TapestryDateField,\n HelperDrawer,\n Highlight,\n Icon,\n Input,\n Menu,\n NumberField as TapestryNumberField,\n Radio,\n Select as TapestrySelect,\n Spinner,\n StackView,\n Text,\n TextArea as TapestryTextArea,\n} from \"@planningcenter/tapestry-react\"\nimport { camelCase, debounce, groupBy, isEqual, sortBy, uniqBy } from \"lodash\"\nimport moment from \"moment\"\nimport React, {\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from \"react\"\n\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport {\n dateFNSFormat,\n dateLocalized,\n fieldListIdentifier,\n} from \"./utils/utils\"\n\nfunction fieldDependencies({\n field,\n selectedFieldOptions,\n}: {\n field: DefinitionField\n selectedFieldOptions: { [k: string]: any }\n}) {\n const dependsOn = field.dependsOn || []\n return dependsOn.reduce((acc, depKey) => {\n if (Object.prototype.hasOwnProperty.call(selectedFieldOptions, depKey)) {\n acc[camelCase(depKey)] = selectedFieldOptions[depKey]\n }\n return acc\n }, {})\n}\n\nfunction useMemoizedObject(generator) {\n const [memoizedObject, setMemoizedObject] = useState(generator)\n\n useEffect(() => {\n const newObject = generator()\n\n if (!isEqual(newObject, memoizedObject)) {\n setMemoizedObject(newObject)\n }\n }, [generator, memoizedObject])\n\n return memoizedObject\n}\n\nconst Field = ({\n canAccessPeople,\n field,\n onChange,\n value,\n selectedFieldOptions,\n loadListForField,\n loadedLists,\n loadingLists,\n}: {\n canAccessPeople: boolean\n field: DefinitionField\n loadListForField: LoadListForField\n loadedLists: { [k: string]: LoadedList[] }\n loadingLists: { [k: string]: boolean }\n onChange: Function\n selectedFieldOptions: { [k: string]: any }\n value: any\n}) => {\n const dependencies = useMemoizedObject(() =>\n fieldDependencies({ field, selectedFieldOptions })\n )\n\n useEffect(() => {\n if (field.listClass) {\n loadListForField({ dependencies, field })\n }\n }, [field, dependencies, loadListForField])\n\n if (field.kind === \"Hidden\") return null\n\n const listOptions =\n field.list || loadedLists[fieldListIdentifier(field)] || []\n\n const actionAllowedOptions = listOptions.filter(\n (op) => !op.automationNotAllowed\n )\n\n const loading = field.listClass && loadingLists[fieldListIdentifier(field)]\n\n function renderField() {\n switch (field.kind) {\n case \"Select\":\n return (\n <Select\n fieldId={field.id}\n listOptions={actionAllowedOptions}\n onChange={onChange}\n value={value}\n description={field.description}\n disabled={field.disabled}\n />\n )\n case \"SelectSearch\":\n return (\n <SelectSearch\n fieldId={field.id}\n listOptions={actionAllowedOptions}\n onChange={onChange}\n value={value}\n />\n )\n case \"Checkbox\":\n return <Checkbox field={field} value={value} onChange={onChange} />\n case \"TextArea\":\n return <TextArea field={field} onChange={onChange} value={value} />\n\n case \"DateField\":\n return <DateField field={field} onChange={onChange} value={value} />\n case \"Checkboxes\":\n return (\n <Checkboxes\n fieldId={field.id}\n options={actionAllowedOptions}\n onChange={onChange}\n />\n )\n case \"NumberField\":\n return <NumberField field={field} onChange={onChange} value={value} />\n case \"PersonSearch\":\n return (\n <PersonSearch\n canAccessPeople={canAccessPeople}\n field={field}\n onChange={onChange}\n listOptions={listOptions}\n isLoading={loadingLists[fieldListIdentifier(field)]}\n loadListForField={loadListForField}\n value={value}\n />\n )\n case \"TextField\":\n return <TextField field={field} onChange={onChange} value={value} />\n case \"RadioButtons\":\n return (\n <RadioButtons\n field={field}\n options={listOptions}\n onChange={onChange}\n value={value}\n />\n )\n case \"StaticText\":\n return <Text dangerouslySetInnerHTML={{ __html: field.content }} />\n default:\n console.warn(`Unknown field kind \"${field.kind}\"`)\n return null\n }\n }\n\n return (\n <StackView marginBottom={2} spacing={0.5}>\n <Input.InputLabel\n color={token(\"--t-text-color-headline\")}\n fontSize={token(\"--t-font-size-sm\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n controls={field.id}\n >\n {field.description}\n {field.info && (\n <HelperDrawer.Toggle drawerId={`${field.id}_help`} marginLeft={1} />\n )}\n </Input.InputLabel>\n <Box>{loading ? <Loading /> : renderField()}</Box>\n {field.info && (\n <HelperDrawer\n id={`${field.id}_help`}\n marginTop={token(\"--t-spacing-half\")}\n >\n <Box dangerouslySetInnerHTML={{ __html: field.info }} />\n </HelperDrawer>\n )}\n </StackView>\n )\n}\n\nconst Select = ({\n fieldId,\n listOptions,\n onChange,\n value,\n description,\n disabled,\n}: {\n description?: string\n disabled?: boolean\n fieldId: string\n listOptions: LoadedList[]\n onChange: Function\n value: any\n}) => {\n const overridenEmptyValue = listOptions?.find(\n (option) => option.value === \"no-option\"\n )\n const groupedOptions = groupBy(listOptions, \"group\")\n const groupTypes = Object.keys(groupedOptions).sort()\n const renderOptions = () => {\n return groupTypes.map((gt) =>\n gt === \"null\" || gt === \"undefined\" ? (\n renderOptionsWithoutConsideringGroup(groupedOptions[gt])\n ) : (\n <TapestrySelect.OptionGroup key={gt} title={gt}>\n {renderOptionsWithoutConsideringGroup(groupedOptions[gt])}\n </TapestrySelect.OptionGroup>\n )\n )\n }\n\n const renderOptionsWithoutConsideringGroup = (\n items: { description: string; disabled?: boolean; value: string | number }[]\n ) => {\n return items.map((item) => (\n <TapestrySelect.Option\n key={item.value}\n value={item.value.toString()}\n disabled={item.disabled}\n >\n {item.description}\n </TapestrySelect.Option>\n ))\n }\n\n const handleSelectedValueChange = ({ selectedValue }) => {\n onChange({ fieldId, value: selectedValue })\n }\n\n const generatePrompt = (word: string) => {\n let prompt = `Select `\n if (!word) {\n prompt += \"a value\"\n } else if ([\"a\", \"e\", \"i\", \"o\", \"u\"].includes(word.charAt(0))) {\n prompt += `an ${word}`\n } else {\n prompt += `a ${word}`\n }\n return prompt\n }\n\n const renderEmptyValue = () => {\n if (renderOptions().length === 0) return \"No options available\"\n return (\n overridenEmptyValue?.description ||\n generatePrompt(description?.toLowerCase())\n )\n }\n\n return (\n <TapestrySelect\n id={fieldId}\n onChange={handleSelectedValueChange}\n disabled={renderOptions().length < 1 || !!disabled}\n emptyValue={renderEmptyValue()}\n size=\"lg\"\n value={value || overridenEmptyValue?.value || null}\n placement=\"bottom-start\"\n >\n {renderOptions()}\n </TapestrySelect>\n )\n}\n\nconst SelectSearch = ({\n fieldId,\n listOptions,\n onChange,\n value,\n}: {\n fieldId: string\n listOptions: LoadedList[]\n onChange: Function\n value?: string\n}) => {\n const selectedOption: LoadedList = listOptions.find(\n (option) => option.value?.toString() === value\n )\n const selectedLabel = selectedOption?.description || \"\"\n const [prevSelectedLabel, setPrevSelectedLabel] = useState(\"\")\n const [query, setQuery] = useState(selectedLabel)\n const [showFilteredOptions, setShowFilteredOptions] = useState(false)\n const [showClearButton, setShowClearButton] = useState(false)\n\n if (selectedLabel !== prevSelectedLabel) {\n setPrevSelectedLabel(selectedLabel)\n setQuery(selectedLabel)\n setShowFilteredOptions(false)\n }\n\n let filteredOptions = sortBy(uniqBy(listOptions, \"value\"), \"group\")\n\n if (showFilteredOptions) {\n const formattedQuery = query.toLowerCase()\n filteredOptions = filteredOptions.filter((option) => {\n const optionText = `${option.description} ${option.group}`.toLowerCase()\n return optionText.includes(formattedQuery)\n })\n }\n\n const handleValueChange = (value: string) => {\n onChange({ fieldId, value })\n }\n\n return (\n <TapestryCombobox.Popover\n closeOnSelect\n closeButton={{ icon: { size: \"md\" } }}\n css={{\n \"[role='combobox']\": {\n cursor: listOptions.length > 0 ? \"pointer\" : \"not-allowed\",\n },\n }}\n cursor=\"pointer\"\n disabled={listOptions.length === 0}\n onBlur={() => {\n setShowClearButton(false)\n setQuery(selectedLabel)\n }}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\n setQuery(e.target.value)\n setShowFilteredOptions(true)\n setShowClearButton(true)\n }}\n onClear={\n showClearButton\n ? () => {\n setQuery(\"\")\n setShowFilteredOptions(false)\n }\n : undefined\n }\n onFocus={(e: React.ChangeEvent<HTMLInputElement>) => e.target.select()} // select all text on focus\n onSelect={(option: { description: string; value: string }) => {\n handleValueChange(option.value)\n setQuery(option.description)\n setShowFilteredOptions(false)\n setShowClearButton(false)\n }}\n openOnFocus\n paddingLeft={4.5}\n placeholder={\n listOptions.length > 0 ? \"Select an option\" : \"No options available\"\n }\n placement=\"bottom-start\"\n popoverProps={{\n matchWidths: \"minimum\",\n }}\n renderLeft={<Icon name=\"general.search\" size=\"md\" />}\n renderRight={<Icon name=\"general.downCaret\" />}\n size=\"lg\"\n value={query}\n >\n {listOptions.length > 0 && (\n <>\n {filteredOptions.length > 0 ? (\n filteredOptions.map((option: LoadedList, index: number) => {\n const isCurrent = option.value.toString() === value\n return (\n <TapestryCombobox.Item\n aria-label={option.description}\n disabled={option.disabled}\n index={index}\n key={option.value}\n paddingLeft={4.25}\n renderLeft={\n <Icon\n marginLeft={-0.5}\n name={isCurrent ? \"general.check\" : \"\"}\n size=\"sm\"\n />\n }\n role=\"option\"\n spacing={token(\"--t-spacing-1\")}\n value={{\n description: option.description,\n value: option.value.toString(),\n }}\n >\n <Text truncate>\n <Highlight text={option.description} query={query} />\n </Text>\n {option.group && (\n <Badge\n title={<Highlight text={option.group} query={query} />}\n size=\"sm\"\n marginLeft=\"auto\"\n />\n )}\n </TapestryCombobox.Item>\n )\n })\n ) : (\n <Menu.Item>\n <Text>No results for &quot;{query}&quot;</Text>\n </Menu.Item>\n )}\n </>\n )}\n </TapestryCombobox.Popover>\n )\n}\n\nconst PersonSearch = ({\n canAccessPeople,\n field,\n isLoading,\n listOptions,\n loadListForField,\n onChange,\n value,\n}: {\n canAccessPeople: boolean\n field: DefinitionField\n isLoading: boolean\n listOptions: LoadedList[]\n loadListForField: LoadListForField\n onChange: Function\n value?: string\n}) => {\n const immediateSearch = useCallback(\n (query: string) => {\n loadListForField({ dependencies: { query }, field })\n },\n [loadListForField]\n )\n\n const debouncedSearch = useMemo(\n () => debounce(immediateSearch, 300),\n [immediateSearch]\n )\n\n const search = useCallback(\n (query: string) => {\n if (!canAccessPeople) {\n return\n } else if (query.trim().length > 0) {\n debouncedSearch(query)\n } else {\n debouncedSearch.cancel()\n }\n },\n [debouncedSearch]\n )\n\n const myself: LoadedList = useMemo(\n () => ({ description: \"Myself\", value: \"self\" }),\n []\n )\n const allListOptions = useMemo(() => {\n if (!canAccessPeople) {\n return [myself]\n } else {\n return listOptions\n }\n }, [myself, listOptions])\n\n const selectedOption = allListOptions.find((option) => option.value === value)\n const selectedLabel = selectedOption?.description || \"\"\n const [query, _setQuery] = useState(selectedLabel)\n const [showClearButton, setShowClearButton] = useState(false)\n\n function setQuery(value: string) {\n _setQuery(value)\n search(value)\n if (value.trim().length === 0) {\n handleValueChange(null)\n }\n }\n\n const handleValueChange = (value: string) => {\n onChange({ fieldId: field.id, value })\n }\n\n return (\n <TapestryCombobox.Popover\n closeOnSelect\n closeButton={{ icon: { size: \"md\" } }}\n cursor=\"pointer\"\n onBlur={() => {\n setShowClearButton(false)\n setQuery(selectedLabel)\n }}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\n setQuery(e.target.value)\n setShowClearButton(true)\n }}\n onClear={\n showClearButton\n ? () => {\n setQuery(\"\")\n }\n : undefined\n }\n onFocus={(e: React.FocusEvent<HTMLInputElement>) => e.target.select()} // select all text on focus\n onSelect={(option: { description: string; value: string }) => {\n handleValueChange(option.value)\n setQuery(option.description)\n setShowClearButton(false)\n }}\n openOnFocus\n paddingLeft={4.5}\n placeholder=\"Search\"\n placement=\"bottom-start\"\n popoverProps={{\n matchWidths: \"minimum\",\n }}\n renderLeft={\n selectedOption && selectedOption.meta?.avatar ? (\n <Avatar size=\"sm\" source={selectedOption.meta.avatar} />\n ) : (\n <Icon name=\"general.search\" size=\"md\" />\n )\n }\n renderRight={<Icon name=\"general.downCaret\" />}\n size=\"lg\"\n value={query}\n >\n {canAccessPeople ? (\n query.trim().length > 0 ? (\n listOptions.length > 0 ? (\n listOptions.map((option, index) => {\n return (\n <TapestryCombobox.Item\n aria-label={option.description}\n index={index}\n key={option.value}\n paddingLeft={4.25}\n renderLeft={\n <Avatar\n marginLeft={-0.5}\n source={option.meta.avatar}\n size=\"sm\"\n />\n }\n role=\"option\"\n spacing={token(\"--t-spacing-1\")}\n value={option}\n >\n <Text truncate>\n <Highlight text={option.description} query={query} />\n </Text>\n </TapestryCombobox.Item>\n )\n })\n ) : isLoading ? (\n <TapestryCombobox.Item>\n <Text>Loading...</Text>\n </TapestryCombobox.Item>\n ) : (\n <TapestryCombobox.Item>\n <Text>No results</Text>\n </TapestryCombobox.Item>\n )\n ) : (\n <TapestryCombobox.Item>\n <Text>Type to search</Text>\n </TapestryCombobox.Item>\n )\n ) : (\n <TapestryCombobox.Item value={myself} index={0} role=\"option\">\n <Text>{myself.description}</Text>\n </TapestryCombobox.Item>\n )}\n </TapestryCombobox.Popover>\n )\n}\n\nconst Checkbox = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleCheckedValueChange = (e) => {\n const value = e.target.checked\n onChange({ fieldId: field.id, value })\n }\n\n return (\n <TapestryCheckbox\n disabled={field.disabled}\n label={field.label}\n checked={value || false}\n onChange={handleCheckedValueChange}\n />\n )\n}\n\nconst TextArea = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleTextChange = (e) => {\n const val = e.target.value\n onChange({ fieldId: field.id, value: val })\n }\n return (\n <Box>\n <TapestryTextArea\n value={value}\n placeholder={field.placeholder}\n onChange={handleTextChange}\n size=\"lg\"\n />\n </Box>\n )\n}\n\nconst DateField = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const { dateFormat } = useContext(OrganizationContext)\n const [specificDate, setSpecificDate] = useState(false)\n const todaysValue = field.customValue || \"Day automation runs\"\n const dateBeforeValue = \"Day before automation runs\"\n const orgFormat = dateFNSFormat(dateFormat)\n const [dateFieldValue, setDateFieldValue] = useState(moment(value).toDate())\n const allowUnansweredOption = field.allowUnansweredOption ?? false\n\n const handleSelectChange = ({ selectedValue }) => {\n if (selectedValue === todaysValue || selectedValue === dateBeforeValue) {\n setSpecificDate(false)\n onChange({ fieldId: field.id, value: selectedValue })\n } else if (selectedValue === \"specific-date\") {\n onChange({ fieldId: field.id, value: null })\n setSpecificDate(true)\n } else {\n setSpecificDate(false)\n onChange({ fieldId: field.id, value: null })\n }\n }\n\n const handleValueChanged = (date: Date) => {\n onChange({ fieldId: field.id, value: dateLocalized(date, dateFormat) })\n setDateFieldValue(date)\n }\n\n return (\n <StackView axis=\"horizontal\">\n <TapestrySelect\n onChange={handleSelectChange}\n size=\"lg\"\n placement=\"bottom-start\"\n >\n <TapestrySelect.Option value={todaysValue}>\n {todaysValue}\n </TapestrySelect.Option>\n {!field.customValue && (\n <TapestrySelect.Option value={dateBeforeValue}>\n {dateBeforeValue}\n </TapestrySelect.Option>\n )}\n <TapestrySelect.Option value=\"specific-date\">\n A specific date\n </TapestrySelect.Option>\n {allowUnansweredOption && (\n <TapestrySelect.Option value=\"unanswered\">\n Unanswered\n </TapestrySelect.Option>\n )}\n </TapestrySelect>\n {specificDate && (\n <Box>\n <TapestryDateField\n defaultOpen\n formatValue={orgFormat}\n marginLeft={1}\n onChange={handleValueChanged}\n size=\"lg\"\n value={dateFieldValue}\n />\n </Box>\n )}\n </StackView>\n )\n}\n\nconst Checkboxes = ({\n fieldId,\n options,\n onChange,\n}: {\n fieldId: string\n onChange: Function\n options: { description: string; value: string | number }[]\n}) => {\n const [selectedValues, setSelectedValues] = useState({})\n\n const handleCheckboxesChange = (selectedValue, value) => {\n const newSelectedValues = { ...selectedValues }\n newSelectedValues[value] = selectedValue\n setSelectedValues(newSelectedValues)\n onChange({ fieldId, value: newSelectedValues })\n }\n\n return (\n <StackView spacing={1}>\n {options.map((item) => (\n <Box key={item.value}>\n <Input.InputLabel controls={`checkboxes_${fieldId}_${item.value}`}>\n {item.description || item.value}\n </Input.InputLabel>\n <TapestrySelect\n id={`checkboxes_${fieldId}_${item.value}`}\n onChange={({ selectedValue }) =>\n handleCheckboxesChange(selectedValue, item.value)\n }\n size=\"lg\"\n emptyValue={\"Don't change\"}\n >\n <TapestrySelect.Option value=\"check\">Check</TapestrySelect.Option>\n <TapestrySelect.Option value=\"uncheck\">\n Uncheck\n </TapestrySelect.Option>\n </TapestrySelect>\n </Box>\n ))}\n </StackView>\n )\n}\n\nconst NumberField = ({\n field,\n onChange,\n value,\n}: {\n field: DefinitionField\n onChange: Function\n value: string\n}) => {\n const minimumValue = field.minValue >= 0 ? field.minValue : 1\n const maximumValue =\n field.maxValue >= 1 && field.maxValue <= 365 ? field.maxValue : 365\n\n const [inputValue, setInputValue] = useState(Number(field.defaultValue) || 1)\n\n useEffect(() => {\n onChange({ fieldId: field.id, value: field.defaultValue || 1 })\n }, [field])\n\n return (\n <StackView>\n <Input.InputBox>\n <TapestryNumberField\n onChange={(value: string) => {\n const newNumberValue = Number(value) || 0\n setInputValue(newNumberValue)\n\n onChange({\n fieldId: field.id,\n value: Math.min(\n Math.max(newNumberValue, minimumValue),\n maximumValue\n ),\n })\n }}\n placeholder={field.placeholder}\n size=\"lg\"\n value={value}\n min={minimumValue}\n max={maximumValue}\n hasControls={true}\n />\n </Input.InputBox>\n {inputValue > maximumValue && (\n <Alert\n type=\"error\"\n paddingHorizontal={token(\"--t-spacing-1\")}\n paddingVertical={token(\"--t-spacing-half\")}\n display=\"inline-block\"\n marginTop={1.5}\n >\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={0.75}>\n <Icon\n name=\"general.exclamationTriangle\"\n size=\"sm\"\n color=\"delete45\"\n />\n <Text size={token(\"--t-font-size-md\")}>\n Value cannot exceed {maximumValue}.\n </Text>\n </StackView>\n </Alert>\n )}\n </StackView>\n )\n}\n\nconst TextField = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleTextChange = (e) => {\n const val = e.target.value\n onChange({ fieldId: field.id, value: val })\n }\n return (\n <Box>\n <Input\n size=\"lg\"\n value={value ?? \"\"}\n id={field.id}\n placeholder={field.placeholder}\n onChange={handleTextChange}\n />\n </Box>\n )\n}\n\nconst RadioButtons = ({\n field,\n options,\n onChange,\n value,\n}: {\n field: DefinitionField\n onChange: Function\n options: LoadedList[]\n value: any\n}) => {\n const handleCheckedChange = (e) => {\n onChange({ fieldId: field.id, value: e.target.value })\n }\n\n return (\n <StackView marginTop={1} spacing={0.5}>\n {options.map((option) => (\n <Radio\n checked={value === option.value}\n key={option.value}\n label={option.description || option.value}\n onChange={handleCheckedChange}\n size=\"md\"\n value={option.value}\n />\n ))}\n </StackView>\n )\n}\n\nconst Loading = () => (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n paddingHorizontal={1.75}\n paddingVertical={token(\"--t-spacing-1\")}\n radius={token(\"--t-border-radius-md\")}\n border={`1px solid ${token(\"--t-border-color\")}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={token(\"--t-font-size-md\")} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n)\n\nexport default Field\n","import React, { useEffect } from \"react\"\n\nimport Field from \"./field\"\nimport { getRenderedFields } from \"./utils/utils\"\n\ninterface FieldsProps {\n canAccessPeople: boolean\n definitionFields: DefinitionField[]\n loadListForField: LoadListForField\n loadedLists: { [k: string]: LoadedList[] }\n loadingLists: { [k: string]: boolean }\n onChange: Function\n selectedFieldOptions: SelectedFieldOptions\n}\n\nconst Fields = ({\n canAccessPeople,\n definitionFields,\n onChange,\n selectedFieldOptions,\n loadListForField,\n loadedLists,\n loadingLists,\n}: FieldsProps): JSX.Element => {\n useEffect(() => {\n const newSelections = definitionFields.reduce((acc, field) => {\n if (Object.prototype.hasOwnProperty.call(field, \"defaultValue\")) {\n acc[field.id] = field.defaultValue\n } else if (field.kind === \"DateField\") {\n acc[field.id] = field.customValue || \"Date automation runs\"\n }\n\n return acc\n }, {})\n onChange(newSelections)\n }, [definitionFields, onChange])\n\n const renderableFields = getRenderedFields(\n definitionFields,\n selectedFieldOptions\n )\n\n const handleSelectedFieldOptionsChange = ({ fieldId, value }) => {\n const newSelections = { ...selectedFieldOptions }\n const dependents = definitionFields.filter((field) => field.dependsOn)\n dependents.map((dependent) => {\n if (dependent.dependsOn.includes(fieldId)) {\n const deeper = dependents.find((d) =>\n d.dependsOn.includes(dependent.id)\n )\n if (deeper) {\n delete newSelections[deeper.id]\n }\n delete newSelections[dependent.id]\n\n if (\n dependent.defaultValue !== undefined &&\n newSelections[dependent.id] === undefined\n ) {\n newSelections[dependent.id] = dependent.defaultValue\n }\n }\n })\n\n if (value === \"no-option\") {\n delete newSelections[fieldId]\n } else {\n newSelections[fieldId] = value\n }\n\n onChange({ ...newSelections })\n }\n\n if (definitionFields.length) {\n return (\n <div>\n {renderableFields.map((field) => {\n return (\n <Field\n canAccessPeople={canAccessPeople}\n field={field}\n key={field.id}\n onChange={handleSelectedFieldOptionsChange}\n value={selectedFieldOptions[field.id]}\n selectedFieldOptions={selectedFieldOptions}\n loadListForField={loadListForField}\n loadedLists={loadedLists}\n loadingLists={loadingLists}\n />\n )\n })}\n </div>\n )\n } else {\n return null\n }\n}\n\nexport default Fields\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Alert,\n Box,\n Button,\n Checkbox,\n Icon,\n Input,\n Link,\n Select,\n Spinner,\n StackView,\n Text,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\n\nimport Definition from \"./definition\"\nimport Fields from \"./fields\"\nimport * as alerts from \"./utils/alerts\"\nimport {\n buildDescription,\n buildTriggerConditions,\n fieldListIdentifier,\n getRenderedFields,\n} from \"./utils/utils\"\n\nconst client = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n version: \"LATEST\",\n})\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"LATEST\",\n})\nconst errorAlertProps = {\n css: { borderRadius: token(\"--t-border-radius-md\") },\n paddingHorizontal: 1.75,\n paddingVertical: 1.25,\n type: \"error\",\n}\n\ntype TopbarResponse = {\n data: {\n apps: Array<{ name: string }>\n type: \"Topbar\"\n }\n}\n\nasync function getVisibleApps() {\n return client\n .get<TopbarResponse>({\n data: {\n fields: { Topbar: \"apps\" },\n },\n url: \"/me/topbar\",\n })\n .then(({ data }) => data.apps.map((a) => a.name))\n}\n\nasync function getWebhooksApps() {\n return webhooksClient\n .get<{ data: Array<{ name: string; type: \"OperationApp\" }> }>({\n data: { fields: { OperationApp: \"name\" } },\n url: \"/operation_apps\",\n })\n .then(({ data }) => data.map((a) => a.name))\n}\n\nasync function getOperationApps() {\n const [visibleApps, webhooksApps] = await Promise.all([\n getVisibleApps(),\n getWebhooksApps(),\n ])\n\n return visibleApps\n .filter((app) => webhooksApps.includes(app))\n .sort()\n .map((app: string) => ({ id: app.toLowerCase(), name: app }))\n}\n\nasync function getOperationDefinitions(app: string) {\n return webhooksClient\n .get({\n data: {\n fields: {\n OperationDefinition:\n \"definition_class,definition_fields,definition_identifier,description,group,section,section_group,footer_message\",\n },\n filter: \"automation_allowed\",\n walk: true,\n },\n url: `/operation_apps/${app}/operation_definitions`,\n })\n .then(({ data }) => data)\n}\n\nasync function getListOptions({\n app,\n field,\n definitionIdentifier,\n dependencies,\n}: {\n app: string\n definitionIdentifier: string\n dependencies: { [k: string]: string }\n field: DefinitionField\n}): Promise<LoadedList[]> {\n if (field.kind === \"PersonSearch\") {\n const { data: people } = await client.get<{\n data: { avatar: string; id: number; name: string }[]\n }>({\n data: {\n fields: { Person: \"avatar,name\" },\n where: { search_name_or_email: dependencies.query, status: \"active\" },\n },\n url: \"/people\",\n })\n\n return people.map((p) => ({\n description: p.name,\n meta: { avatar: p.avatar },\n value: p.id.toString(),\n }))\n } else {\n const { data } = await webhooksClient.get({\n data: {\n ...dependencies,\n definitionIdentifier,\n fields: {\n OperationDefinitionList: \"values\",\n },\n },\n url: `/operation_apps/${app}/operation_definition_lists/${field.listClass}`,\n })\n return data.values\n }\n}\n\nconst NewAutomation = ({\n afterCreateOptions,\n blankStateLink,\n debugMode = false,\n defaultApp,\n description,\n onRequestClose,\n trigger,\n}: {\n afterCreateOptions?: AfterCreateOptions\n blankStateLink: string\n debugMode?: boolean\n defaultApp: string\n description: string\n onRequestClose: () => void\n trigger: AutomationTrigger\n}) => {\n const [selectedTriggerEvent, setSelectedTriggerEvent] = useState(\n trigger.events[0]\n )\n const [dynamicTriggerConditions, setDynamicTriggerConditions] =\n useState<SelectedFieldOptions>({})\n const [selectedApp, setSelectedApp] = useState(defaultApp)\n const [operationApps, setOperationApps] = useState<\n { id: string; name: string }[]\n >([])\n const [operationDefinitions, setOperationDefinitions] = useState<\n OperationDefinition[]\n >([])\n const [loadingOperationDefinitions, setLoadingOperationDefinitions] =\n useState(true)\n const [selectedDefinition, setSelectedDefinition] =\n useState<OperationDefinition>()\n const [selectedFieldOptions, setSelectedFieldOptions] =\n useState<SelectedFieldOptions>({})\n const [loadedLists, setLoadedLists] = useState<{ [k: string]: LoadedList[] }>(\n {}\n )\n const [loadingLists, setLoadingLists] = useState<{ [k: string]: boolean }>({})\n const [submitting, setSubmitting] = useState(false)\n const [error, setError] = useState<{\n automation?: string | string[]\n definitions?: string | string[]\n selected_definition?: string | string[]\n }>({})\n const [callAfterCreate, setCallAfterCreate] = useState(false)\n const [triggerParams, setTriggerParams] = useState<{ [k: string]: string }>(\n {}\n )\n const activeAppRef = useRef(null)\n\n const canAccessPeople = useMemo(\n () => operationApps.map((a) => a.id).includes(\"people\"),\n [operationApps]\n )\n\n const definitionIdentifier = selectedDefinition?.definitionIdentifier\n const dangerAlertPresent =\n selectedDefinition?.footerMessage?.kind === \"danger\"\n\n const loadListForField = useCallback<LoadListForField>(\n ({ field, dependencies }) => {\n setLoadingLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: true,\n }))\n getListOptions({\n app: selectedApp,\n definitionIdentifier,\n dependencies,\n field,\n })\n .then((ret) => {\n setLoadedLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: ret,\n }))\n setLoadingLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: false,\n }))\n })\n .catch((error) => setError({ selected_definition: error }))\n },\n [selectedApp, definitionIdentifier]\n )\n\n const handleChangeSelectedApp = (app: string) => {\n setSelectedApp(app)\n setLoadingOperationDefinitions(true)\n setOperationDefinitions([])\n activeAppRef.current = app\n setSelectedDefinition(null)\n setSelectedFieldOptions({})\n setError({})\n getOperationDefinitions(app)\n .then(setOperationDefinitions)\n .then(() => setLoadingOperationDefinitions(false))\n .catch((error) => setError({ definitions: error }))\n }\n\n const handleChangeTriggerEvent = (\n selectedValue: typeof selectedTriggerEvent\n ) => {\n setSelectedTriggerEvent(selectedValue)\n setDynamicTriggerConditions({})\n }\n\n useEffect(() => {\n setError({})\n getOperationApps().then((apps) => {\n setOperationApps(apps)\n const defaultSelection = apps.find((app) => app.id === defaultApp)\n ? defaultApp\n : apps[0].id\n setSelectedApp(defaultSelection)\n getOperationDefinitions(defaultSelection)\n .then((definitions) => {\n if (!activeAppRef.current) {\n setOperationDefinitions(definitions)\n setLoadingOperationDefinitions(false)\n }\n })\n .catch((error) => setError({ definitions: error }))\n })\n }, [defaultApp])\n\n useEffect(() => {\n setError({})\n }, [selectedFieldOptions])\n\n const dynamicConditions =\n \"dynamicConditions\" in selectedTriggerEvent\n ? selectedTriggerEvent.dynamicConditions\n : trigger.dynamicConditions\n const triggerConditions = buildTriggerConditions({\n baseConditions:\n \"conditions\" in selectedTriggerEvent\n ? selectedTriggerEvent.conditions\n : trigger.conditions,\n dynamicConditions,\n dynamicTriggerConditions,\n })\n\n const handleSelectedDefinitionChange = (\n newDefinition: OperationDefinition\n ) => {\n setSelectedDefinition(newDefinition)\n setError({})\n setSelectedFieldOptions({})\n }\n\n function getDescription(): string {\n const descriptionParts = buildDescription({\n loadedLists,\n selectedDefinition,\n selectedFieldOptions,\n })\n\n let description = descriptionParts.name\n\n if (descriptionParts.description) {\n description += ` (${descriptionParts.description})`\n }\n\n return description\n }\n\n function handleSubmit() {\n if (submitting) {\n return\n }\n const operation_params = { ...selectedFieldOptions }\n\n if (selectedDefinition.definitionIdentifier) {\n operation_params.definition_identifier =\n selectedDefinition.definitionIdentifier\n }\n\n const data = {\n _e: trigger.resource,\n data: {\n attributes: {\n description: getDescription(),\n name: selectedTriggerEvent.name,\n operation_app_name: selectedApp,\n operation_definition_class_name: selectedDefinition.definitionClass,\n operation_params,\n trigger_conditions: triggerConditions,\n trigger_params: triggerParams,\n },\n type: \"AutomationSubscription\",\n },\n }\n if (callAfterCreate) {\n alerts.confirmCreate\n .fire({\n cancelButtonText: \"Cancel\",\n confirmButtonText: \"Yes, perform action\",\n text: \"This will happen immediately after creating your new automation. Are you sure?\",\n title: `${afterCreateOptions.label}?`,\n })\n .then((result: { value: any }) => {\n if (result.value) {\n submitCreate(data)\n } else {\n setSubmitting(false)\n setCallAfterCreate(false)\n }\n })\n } else {\n submitCreate(data)\n }\n }\n\n function submitCreate(data) {\n setSubmitting(true)\n webhooksClient\n .post({\n data,\n url: \"/me/automation_subscriptions\",\n })\n .then(() => {\n if (afterCreateOptions?.onConfirm && callAfterCreate) {\n onRequestClose()\n afterCreateOptions.onConfirm({ ...data })\n } else {\n window.location.reload()\n }\n })\n .catch((error) => {\n setSubmitting(false)\n if (error.errors) {\n setError({ automation: error.errors })\n } else {\n alert(\"something even worse happened!\")\n }\n })\n }\n\n return (\n <StackView paddingTop={4} spacing={2}>\n {description && (\n <Box>\n <Text\n style={{\n color: token(\"--t-text-color\"),\n fontSize: token(\"--t-font-size-md\"),\n lineHeight: 1.65,\n marginBottom: token(\"--t-spacing-2\"),\n }}\n >\n {description}{\" \"}\n <Link external to={blankStateLink}>\n Learn more\n </Link>\n </Text>\n </Box>\n )}\n {error.automation && (\n <Alert {...errorAlertProps}>\n <Text>\n There was an error creating your automation. Please change your\n selections and try again or contact support if the problem persists.\n </Text>\n </Alert>\n )}\n <StackView spacing={1}>\n <Input.InputLabel\n color={token(\"--t-text-color\")}\n controls=\"select-trigger-event\"\n fontSize={token(\"--t-font-size-md\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n >\n When a person...\n </Input.InputLabel>\n <Select\n id=\"select-trigger-event\"\n onChange={({ selectedValue }) =>\n handleChangeTriggerEvent(selectedValue)\n }\n size=\"lg\"\n value={selectedTriggerEvent}\n >\n {trigger.events.map((triggerEvent, idx) => (\n <Select.Option\n key={`${triggerEvent.name}_${idx}`}\n value={triggerEvent}\n >\n {triggerEvent.description}\n </Select.Option>\n ))}\n </Select>\n\n {dynamicConditions?.length > 0 && (\n <Fields\n canAccessPeople={canAccessPeople}\n definitionFields={dynamicConditions}\n selectedFieldOptions={dynamicTriggerConditions}\n onChange={setDynamicTriggerConditions}\n loadedLists={{}}\n loadingLists={{}}\n loadListForField={() => null}\n />\n )}\n </StackView>\n\n <StackView spacing={1}>\n {operationApps.length > 0 ? (\n <Application\n selectedApp={selectedApp}\n operationApps={operationApps}\n onOperationAppChange={handleChangeSelectedApp}\n />\n ) : (\n <StackView spacing={1}>\n <Text\n color={token(\"--t-text-color-headline\")}\n fontSize={token(\"--t-font-size-md\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n >\n Then perform an action in...\n </Text>\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n paddingHorizontal={1.75}\n paddingVertical={token(\"--t-spacing-1\")}\n radius={4}\n border={`1px solid ${token(\"--t-border-color\")}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={token(\"--t-font-size-md\")} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n </StackView>\n )}\n {error.definitions ? (\n <Alert marginTop={token(\"--t-spacing-1\")} {...errorAlertProps}>\n <Text>\n There was a problem looking up automations. Please contact support\n if the problem persists.\n </Text>\n </Alert>\n ) : loadingOperationDefinitions ? (\n <LoadingOperationDefinitions />\n ) : (\n <Definition\n selectedOperation={selectedDefinition}\n operationDefinitions={operationDefinitions}\n onOperationDefinitionChange={handleSelectedDefinitionChange}\n />\n )}\n </StackView>\n\n {selectedDefinition &&\n (error.selected_definition ? (\n <Alert {...errorAlertProps}>\n <Text>\n There was a problem looking up automation options. Please contact\n support if the problem persists.\n </Text>\n </Alert>\n ) : (\n <>\n <Fields\n canAccessPeople={canAccessPeople}\n definitionFields={selectedDefinition.definitionFields || []}\n onChange={setSelectedFieldOptions}\n selectedFieldOptions={selectedFieldOptions}\n loadedLists={loadedLists}\n loadListForField={loadListForField}\n loadingLists={loadingLists}\n />\n {afterCreateOptions?.label && (\n <Checkbox\n disabled={\n submitting ||\n disableSubmit(selectedDefinition, selectedFieldOptions)\n }\n label={afterCreateOptions.label}\n checked={callAfterCreate}\n onChange={() => setCallAfterCreate(!callAfterCreate)}\n />\n )}\n {selectedTriggerEvent?.triggerParams?.map((param, idx) => (\n <Checkbox\n key={`${param.key}_${idx}`}\n label={param.description}\n checked={\n (triggerParams && triggerParams[param.key]) ||\n param.defaultValue\n }\n onChange={(e) => {\n setTriggerParams((prev) => ({\n ...prev,\n [`${param.key}`]: e.target.checked,\n }))\n }}\n />\n ))}\n {dangerAlertPresent && (\n <Alert {...errorAlertProps}>\n <StackView axis=\"horizontal\" spacing={1.5}>\n <Icon\n size={token(\"--t-element-size-lg\")}\n name=\"general.exclamationTriangle\"\n color={token(\"--t-icon-color-status-error\")}\n />\n <Text\n dangerouslySetInnerHTML={{\n __html: selectedDefinition.footerMessage?.html,\n }}\n />\n </StackView>\n </Alert>\n )}\n </>\n ))}\n\n {debugMode && (\n <pre>\n {JSON.stringify(\n {\n description: selectedDefinition && getDescription(),\n loadedLists,\n selectedDefinition,\n selectedFieldOptions,\n triggerConditions,\n },\n null,\n 4\n )}\n </pre>\n )}\n\n <StackView\n alignment=\"center\"\n axis=\"horizontal\"\n borderTop={`1px solid ${token(\"--t-border-color\")}`}\n distribution=\"end\"\n marginTop={2}\n marginHorizontal={-4}\n paddingHorizontal={4}\n paddingTop={3}\n spacing={2}\n >\n <Button\n color={token(\"--t-text-color-headline\")}\n // for temporary backwards compatibility\n data-modal-close\n fontWeight={token(\"--t-font-weight-normal\")}\n onClick={onRequestClose}\n size=\"md\"\n title=\"Cancel\"\n variant=\"naked\"\n />\n <Button\n disabled={\n submitting ||\n dangerAlertPresent ||\n disableSubmit(\n selectedDefinition,\n selectedFieldOptions,\n dynamicConditions,\n dynamicTriggerConditions\n )\n }\n onClick={handleSubmit}\n size=\"md\"\n theme=\"primary\"\n title={getButtonText(selectedDefinition, selectedFieldOptions)}\n variant=\"fill\"\n data-testid=\"create-automation\"\n />\n </StackView>\n </StackView>\n )\n}\n\nfunction disableSubmit(\n selectedDefinition: OperationDefinition,\n selectedFieldOptions: SelectedFieldOptions,\n dynamicConditions?: DefinitionField[],\n dynamicTriggerConditions?: SelectedFieldOptions\n) {\n if (!selectedDefinition) return true\n\n const operationFields = getRenderedFields(\n selectedDefinition.definitionFields,\n selectedFieldOptions\n )\n if (\n !operationFields\n .filter((field) => field.required)\n .every((field) => fieldIsFilled(field, selectedFieldOptions))\n )\n return true\n if (\n !operationFields\n .filter((field) => fieldIsSelect(field))\n .every((field) => fieldIsFilled(field, selectedFieldOptions))\n )\n return true\n\n const triggerFields = getRenderedFields(\n dynamicConditions ?? [],\n dynamicTriggerConditions ?? {}\n )\n if (\n !triggerFields\n .filter((field) => field.required)\n .every((field) => fieldIsFilled(field, dynamicTriggerConditions ?? {}))\n )\n return true\n\n return false\n}\n\nfunction fieldIsSelect(field: DefinitionField) {\n return field.kind === \"Select\" || field.kind === \"SelectSearch\"\n}\n\nfunction fieldIsFilled(\n field: DefinitionField,\n selectedFieldOptions: SelectedFieldOptions\n) {\n if (fieldIsSelect(field)) {\n return selectedFieldOptions.hasOwnProperty(field.id)\n } else {\n return (\n selectedFieldOptions.hasOwnProperty(field.id) &&\n selectedFieldOptions[field.id] &&\n selectedFieldOptions[field.id].toString().trim() !== \"\"\n )\n }\n}\n\nfunction getNextRequiredDescription(\n selectedDefinition: OperationDefinition,\n selectedFieldOptions: SelectedFieldOptions\n) {\n if (!selectedDefinition?.definitionFields) return\n\n const renderedFields = getRenderedFields(\n selectedDefinition.definitionFields,\n selectedFieldOptions\n )\n\n for (const field of renderedFields) {\n if (field.required && !fieldIsFilled(field, selectedFieldOptions))\n return field.description\n }\n}\n\nfunction getButtonText(\n selectedDefinition: OperationDefinition,\n selectedFieldOptions: SelectedFieldOptions\n) {\n const nextRequiredDescription = getNextRequiredDescription(\n selectedDefinition,\n selectedFieldOptions\n )\n\n if (!selectedDefinition) {\n return \"Select an action\"\n } else if (nextRequiredDescription) {\n return `Select a${\n nextRequiredDescription.charAt(0).match(/[aeiou]/i) ? \"n\" : \"\"\n } ${nextRequiredDescription.toLowerCase()}`\n } else {\n return \"Create automation\"\n }\n}\n\nconst Application = ({\n onOperationAppChange,\n operationApps,\n selectedApp,\n}: {\n onOperationAppChange: (selectedValue: string) => void\n operationApps: Array<{ id: string; name: string }>\n selectedApp: string\n}) => {\n const handleChange = ({ selectedValue }) => {\n onOperationAppChange(selectedValue)\n }\n\n return (\n <StackView spacing={1}>\n <Input.InputLabel\n color={token(\"--t-text-color-headline\")}\n controls=\"select-product\"\n fontSize={token(\"--t-font-size-md\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n >\n Then perform an action in...\n </Input.InputLabel>\n <Select\n autoFocus\n id=\"select-product\"\n onChange={handleChange}\n size=\"lg\"\n value={selectedApp}\n >\n {operationApps.map((app) => (\n <Select.Option key={app.id} value={app.id}>\n {app.name}\n </Select.Option>\n ))}\n </Select>\n </StackView>\n )\n}\n\nconst LoadingOperationDefinitions = () => (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n paddingHorizontal={1.75}\n paddingVertical={token(\"--t-spacing-1\")}\n radius={token(\"--t-border-radius-md\")}\n border={`1px solid ${token(\"--t-border-color\")}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={token(\"--t-font-size-md\")} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n)\n\nexport default NewAutomation\n","import { token } from \"@planningcenter/tapestry\"\nimport {\n Button,\n Heading,\n Modal,\n StackView,\n ThemeProvider,\n} from \"@planningcenter/tapestry-react\"\nimport React from \"react\"\nimport { createPortal } from \"react-dom\"\n\nfunction CloseModalIcon({\n onClick,\n}: {\n onClick: React.MouseEventHandler\n}): JSX.Element {\n return (\n <Button\n as=\"button\"\n height={token(\"--t-element-size-md\")}\n icon={{ color: token(\"--t-icon-color-dim\"), name: \"general.x\" }}\n onClick={onClick}\n size={\"sm\"}\n title=\"Close\"\n variant=\"naked\"\n />\n )\n}\n\nfunction NewAutomationModal({\n children,\n onRequestClose,\n open,\n theme,\n}: {\n children: React.ReactNode\n onRequestClose: () => void\n open: boolean\n theme: object\n}): React.ReactPortal | JSX.Element {\n return createPortal(\n <ThemeProvider theme={theme}>\n <Modal\n open={open}\n onRequestClose={onRequestClose}\n maxWidth={75}\n boxShadow=\"0 0 20px rgba(0, 0, 0, 0.15)\"\n padding={token(\"--t-spacing-4\")}\n paddingBottom={token(\"--t-spacing-3\")}\n radius={token(\"--t-border-radius-lg\")}\n zIndex={10009}\n >\n <StackView\n axis=\"horizontal\"\n distribution=\"space-between\"\n alignment=\"center\"\n >\n <Heading\n level={2}\n color={token(\"--t-text-color-headline\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n fontSize={token(\"--t-font-size-2xl\")}\n lineHeight=\"1.4\"\n >\n Create automation\n </Heading>\n <CloseModalIcon onClick={onRequestClose} />\n </StackView>\n {children}\n </Modal>\n <style>{`\n .swal2-container.swal2-backdrop-show { z-index: 10001 }\n `}</style>\n </ThemeProvider>,\n document.body\n )\n}\n\nexport default NewAutomationModal\n","import * as churchCenter from \"@planningcenter/icons/paths/church-center\"\nimport * as logomark from \"@planningcenter/icons/paths/logomark\"\nimport * as services from \"@planningcenter/icons/paths/services\"\n\nexport const icons = {\n churchCenter,\n logomark,\n services,\n}\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Box,\n Button,\n Heading,\n Icon,\n Spinner,\n StackView,\n Summary,\n Text,\n ThemeProvider,\n TileView,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport sortBy from \"lodash/sortBy\"\nimport React, { useEffect, useState } from \"react\"\n\nimport SvgAutomations from \"./assets/svg_automations\"\nimport { EditableAutomation } from \"./automation\"\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport IncomingAutomations from \"./incoming_automations\"\nimport NewAutomation from \"./new_automation\"\nimport NewAutomationModal from \"./new_automation_modal\"\nimport styles from \"./styles.scss\"\nimport * as alerts from \"./utils/alerts\"\nimport {\n fetchAutomations,\n fetchCreatorProfiles,\n mergeProfilesAndSubscriptions,\n} from \"./utils/fetch-automations\"\nimport { resolveResponseDetails } from \"./utils/resolve-response-details\"\nimport { icons } from \"./utils/theme\"\nimport {\n deobfuscateDescriptions,\n forbiddenText,\n pluralize,\n} from \"./utils/utils\"\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"2022-10-20\",\n})\n\nfunction Header({\n afterCreateOptions,\n automations,\n blankStateLink,\n canCreate,\n defaultApp,\n description,\n hasActiveAutomations,\n loading,\n onPauseAutomations,\n theme,\n trigger,\n}: {\n afterCreateOptions?: AfterCreateOptions\n automations: AutomationInstance[]\n blankStateLink: string\n canCreate: boolean\n defaultApp: string\n description: string\n hasActiveAutomations: boolean\n loading: boolean\n onPauseAutomations: Function\n theme: object\n trigger: AutomationTrigger\n}) {\n const [newModalVisible, setNewModalVisible] = useState(false)\n const isPaused = canCreate && !hasActiveAutomations\n\n const activeCount = automations.filter(\n (automation) => automation.active\n ).length\n const pausedCount = automations.filter(\n (automation) => !automation.active\n ).length\n\n return (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n backgroundColor={\n isPaused ? token(\"--t-fill-color-status-warning-ghost\") : undefined\n }\n borderBottom={\n isPaused ? undefined : `1px solid ${token(\"--t-border-color\")}`\n }\n data-testid=\"automations-header\"\n distribution=\"space-between\"\n marginHorizontal={-3}\n marginBottom={token(\"--t-spacing-2\")}\n marginTop={-3}\n paddingHorizontal={token(\"--t-spacing-3\")}\n paddingVertical={token(\"--t-spacing-2\")}\n spacing={token(\"--t-spacing-2\")}\n wrap\n zIndex={2}\n >\n {canCreate && !hasActiveAutomations ? (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n marginHorizontal={1}\n spacing={1}\n >\n <Icon\n size={2}\n color={token(\"--t-icon-color-status-warning\")}\n name=\"general.exclamationTriangle\"\n />\n <Heading\n color={token(\"--t-text-color-headline\")}\n level={2}\n size={token(\"--t-font-size-lg\")}\n >\n Automations are currently paused\n </Heading>\n </StackView>\n ) : (\n <Heading\n color={token(\"--t-text-color-headline\")}\n level={2}\n size={token(\"--t-font-size-lg\")}\n >\n {loading\n ? \"Active automations\"\n : pluralize(activeCount, \"active automation\")}\n {pausedCount > 0 ? ` (${pausedCount} paused)` : \"\"}\n </Heading>\n )}\n {canCreate &&\n (hasActiveAutomations ? (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n >\n {automations.length > 0 && (\n <Button onClick={onPauseAutomations} variant=\"outline\">\n Pause automations\n </Button>\n )}\n <Button\n theme=\"primary\"\n variant=\"fill\"\n onClick={() => setNewModalVisible(true)}\n >\n Create automation\n </Button>\n <NewAutomationModal\n open={newModalVisible}\n onRequestClose={() => setNewModalVisible(false)}\n theme={theme}\n >\n <NewAutomation\n description={description}\n blankStateLink={blankStateLink}\n defaultApp={defaultApp}\n trigger={trigger}\n onRequestClose={() => setNewModalVisible(false)}\n afterCreateOptions={afterCreateOptions}\n />\n </NewAutomationModal>\n </StackView>\n ) : (\n <Box>\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={1}>\n <Button\n onClick={onPauseAutomations}\n theme=\"primary\"\n variant=\"outline\"\n >\n Enable automations\n </Button>\n <Button\n theme=\"primary\"\n disabled\n tooltip={{\n title: \"Automations must be enabled to create new ones\",\n }}\n >\n Create automation\n </Button>\n </StackView>\n </Box>\n ))}\n </StackView>\n )\n}\n\nexport default function Automations({\n afterCreateOptions,\n blankStateDescription,\n blankStateLink = \"https://pcopeople.zendesk.com/hc/en-us/articles/217582148-Automations\",\n currentPersonId,\n currentPersonCanCreate,\n defaultApp,\n incomingAutomationsParam,\n theme,\n trigger,\n currentOrganization,\n permissionDeniedReason = \"You need permissions of Editor or above to add an automation.\",\n disabled = false,\n disabledReason = \"Not allowed\",\n}: {\n afterCreateOptions?: AfterCreateOptions\n blankStateDescription: string\n blankStateLink?: string\n currentOrganization: {\n dateFormat: string\n olsonTimeZone: string\n twentyFourHourTime: boolean\n }\n currentPersonCanCreate: boolean\n currentPersonId: number\n defaultApp: string\n disabled?: boolean\n disabledReason?: string\n incomingAutomationsParam?: string\n permissionDeniedReason?: string\n theme?: object\n trigger?: AutomationTrigger\n}) {\n useEffect(() => {\n if (!trigger) return setLoading(false)\n fetchAutomations(trigger.resource)\n .then(fetchCreatorProfiles)\n .then(mergeProfilesAndSubscriptions)\n .then(deobfuscateDescriptions)\n .then(resolveResponseDetails)\n .then(setAutomations)\n .then(() => setLoading(false))\n }, [trigger?.resource])\n\n const [automations, setAutomations] = useState([])\n const [loading, setLoading] = useState(true)\n const [newModalVisible, setNewModalVisible] = useState(false)\n\n const { dateFormat, twentyFourHourTime, olsonTimeZone } = currentOrganization\n\n const params = new URLSearchParams(window.location.search)\n\n const automationId = params.get(\"automation_id\")\n\n // make sure necessary icons are added to theme\n const customTheme = { ...theme, ...{ icons: { ...icons } } }\n\n useEffect(() => {\n document.body.toggleAttribute(\"data-loading-automations\", loading)\n }, [loading])\n\n const hasActiveAutomations = automations.length\n ? automations.some((a) => a.active)\n : true\n\n function handleDelete(id: number) {\n webhooksClient\n .delete({\n data: { _e: trigger.resource },\n url: `/automation_subscriptions/${id}`,\n })\n .then(() =>\n setAutomations(automations.filter((automation) => automation.id !== id))\n )\n .catch((error) => {\n const text =\n forbiddenText(error, \"delete\") ||\n \"There was a problem deleting this automation. Please try again in a few moments.\"\n alerts.alertError.fire({\n text,\n title: \"Uh oh!\",\n })\n })\n }\n\n function handlePauseAutomations() {\n webhooksClient\n .post({\n data: {\n data: {\n attributes: {\n _e: trigger.resource,\n active: !hasActiveAutomations,\n },\n },\n },\n url: \"/pause_automations\",\n })\n .then(() => {\n window.location.reload()\n })\n }\n\n const BlankStateHeadingProps = {\n color: token(\"--t-text-color\"),\n level: 2,\n size: token(\"--t-font-size-2xl\"),\n weight: token(\"--t-font-weight-bold\"),\n }\n\n const BlankStateTextProps = {\n color: token(\"--t-text-color-secondary\"),\n lineHeight: 3,\n size: token(\"--t-font-size-md\"),\n }\n\n function automationTriggerEvent(automation: AutomationInstance) {\n return trigger.events.find((event) => event.name === automation.name)\n }\n\n const handleUpdateAutomation =\n (originalAutomation: AutomationInstance) =>\n (newState: React.SetStateAction<AutomationInstance>) => {\n const updated =\n typeof newState == \"function\" ? newState(originalAutomation) : newState\n const newAutomations = [\n ...automations.filter((automation) => automation.id !== updated.id),\n updated,\n ]\n\n setAutomations(newAutomations)\n }\n\n return (\n <ThemeProvider theme={customTheme}>\n <OrganizationContext.Provider\n value={{ dateFormat, olsonTimeZone, twentyFourHourTime }}\n >\n {trigger && (\n <Header\n automations={automations}\n blankStateLink={blankStateLink}\n canCreate={currentPersonCanCreate && !disabled}\n loading={loading}\n defaultApp={defaultApp}\n description={blankStateDescription}\n theme={customTheme}\n trigger={trigger}\n hasActiveAutomations={hasActiveAutomations}\n onPauseAutomations={handlePauseAutomations}\n afterCreateOptions={afterCreateOptions}\n />\n )}\n {loading ? (\n <Summary\n image={<Spinner size=\"xl\" />}\n paddingVertical={10}\n title={\"Loading automations...\"}\n />\n ) : !trigger ? (\n <></>\n ) : (\n <Box data-testid=\"automations-section\">\n {automations?.length > 0 ? (\n <TileView spacing={3} marginVertical={3} minCellWidth={45}>\n {sortBy(automations, \"id\").map((a) => (\n <EditableAutomation\n key={a.id}\n automation={a}\n updateAutomation={handleUpdateAutomation(a)}\n onDelete={handleDelete}\n theme={customTheme}\n openHistoryNow={a.id === Number(automationId)}\n trigger={{\n event: automationTriggerEvent(a),\n resource: trigger.resource,\n }}\n currentPersonId={currentPersonId}\n currentPersonCanCreate={currentPersonCanCreate}\n disabled={disabled}\n disabledReason={disabledReason}\n />\n ))}\n </TileView>\n ) : (\n <StackView\n margin={token(\"--t-spacing-6\")}\n spacing={token(\"--t-spacing-2\")}\n alignment=\"center\"\n mediaQueries={{\n lg: {\n axis: \"horizontal\",\n distribution: \"center\",\n spacing: token(\"--t-spacing-6\"),\n },\n }}\n >\n <Box\n css={{\n \".symbol\": {\n height: \"100%\",\n width: \"100%\",\n },\n }}\n maxWidth={24}\n mediaQueries={{\n lg: {\n maxWidth: 40,\n },\n }}\n >\n <SvgAutomations />\n </Box>\n <StackView\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n maxWidth={45}\n mediaQueries={{\n lg: {\n alignment: \"start\",\n textAlign: \"left\",\n },\n }}\n textAlign=\"center\"\n >\n {currentPersonCanCreate ? (\n <>\n <Heading {...BlankStateHeadingProps}>\n Add an automation\n </Heading>\n <StackView\n alignment=\"center\"\n marginBottom={token(\"--t-spacing-1\")}\n mediaQueries={{\n lg: {\n alignment: \"start\",\n },\n }}\n spacing={1}\n >\n <Text {...BlankStateTextProps}>\n {blankStateDescription}\n </Text>\n </StackView>\n <StackView\n axis=\"horizontal\"\n spacing={token(\"--t-spacing-1\")}\n >\n <Button\n variant=\"outline\"\n to={blankStateLink}\n color={`${token(\n \"--t-text-color-status-neutral\"\n )} !important`}\n >\n Learn more\n </Button>\n <Button\n as=\"button\"\n theme=\"primary\"\n variant=\"fill\"\n onClick={() => setNewModalVisible(true)}\n >\n Create automation\n </Button>\n </StackView>\n <NewAutomationModal\n open={newModalVisible}\n onRequestClose={() => setNewModalVisible(false)}\n theme={customTheme}\n >\n <NewAutomation\n defaultApp={defaultApp}\n description={blankStateDescription}\n blankStateLink={blankStateLink}\n onRequestClose={() => setNewModalVisible(false)}\n trigger={trigger}\n afterCreateOptions={afterCreateOptions}\n />\n </NewAutomationModal>\n </>\n ) : (\n <>\n <Heading {...BlankStateHeadingProps}>Automations</Heading>\n <Text {...BlankStateTextProps}>\n {permissionDeniedReason}\n </Text>\n </>\n )}\n </StackView>\n </StackView>\n )}\n </Box>\n )}\n {incomingAutomationsParam && (\n <IncomingAutomations\n encryptedParam={incomingAutomationsParam}\n trigger={trigger}\n />\n )}\n </OrganizationContext.Provider>\n <style>{styles}</style>\n </ThemeProvider>\n )\n}\n"],"names":["SvgAutomations","React","createElement","id","xmlns","viewBox","className","opacity","d","fill","x","y","width","height","rx","ry","transform","OrganizationContext","createContext","dateFormat","olsonTimeZone","twentyFourHourTime","Swal","mixin","standardAlertOptions","successAlertOptions","alertError","errorAlertOptions","confirm","standardConfirmOptions","confirmDestroy","destroyConfirmOptions","confirmCreate","createConfirmOptions","async","deobfuscateDescriptions","subscriptions","Promise","all","map","subscription","includes","operationDefinitionClassName","isDeobfuscatable","description","workflow","workflowId","data","peopleClient","get","fields","Workflow","where","url","catch","name","fetchWorkflow","operationParams","workflowName","archivedAt","replace","fieldDefinitionId","definitionIdentifier","match","fieldDefinition","FieldDefinition","FieldOption","include","fetchFieldDefinition","values","dataType","_subscription$operati","_subscription$operati2","Object","entries","action","_fieldDefinition$fiel","value","fieldOptions","find","fieldOption","parseInt","capitalize","join","_fieldDefinition$fiel2","customFieldOptionDescription","deobfuscatedDescription","string","charAt","toUpperCase","slice","Client","root","pcoApiUrl","squiggly","version","fieldListIdentifier","field","listClass","kind","obfuscateDescriptionName","definition","definitionClass","hasOwnProperty","object","key","prototype","call","getListForField","loadedLists","list","Error","JSON","stringify","renderIfChainSatisfied","allFields","selectedFieldOptions","renderIf","isBoolean","conditionKey","keys","shouldRender","upstreamId","upstream","f","getRenderedFields","definitionFields","filter","describeSelectedFields","selectedDefinition","_list$find2","workflow_id_WorkflowsList","sensitiveString","o","toString","workflow_id","obfuscateSelectedFieldDescriptions","_list$find","label","e","momentDateFormat","format","dateLocalized","date","momentDate","moment","isValid","pluralize","count","word","singularize","triggerResourceParts","triggerResource","triggerParts","split","appName","resourceId","length","resourcePath","resourceType","forbiddenText","error","_error$errors","errors","status","webhooksClient","STATUS","delivered","failed","ignored","pending","skipped","fetchPeopleWhoTriggeredEvents","events","personIds","eventPersonId","people","Person","fetchPeople","mergePeopleAndEvents","mergedData","reduce","result","personId","foundPerson","p","push","_extends","person","event","History","automation","filterWhere","onEventsStatusChange","_params$where","loading","paginationProps","refresh","params","setParams","automationId","_","setError","useState","setLoading","eventPages","setEventPages","meta","setMeta","offset","resetOffset","perPage","totalCount","setOffset","currentPage","Math","floor","onPageChange","pageNum","totalPages","ceil","useCallback","usePagination","useEffect","_e","Delivery","Event","order","fetchEvents","per_page","then","pages","bubbleErrorToBoundary","undefined","useEvents","useContext","filteringEvents","automationCreatedRecently","diff","numDaysSince","createdAt","automationBeganOn","historyPreservationAlert","columns","cell","EventStatusBadge","css","padding","header","utcOffset","momentDateTimeFormat","Link","to","maxWidth","EventStatusMessage","flex","Fragment","RetryEventButton","IgnoreEventButton","refreshHistory","textAlign","minWidth","StackView","spacing","token","Heading","level","size","color","weight","Text","italic","Box","minHeight","alignItems","axis","distribution","Input","InputLabel","fontWeight","controls","Select","emptyValue","onChange","selectedValue","title","Option","Button","iconLeft","onClick","theme","variant","maxHeight","overflow","DataTable","empty","alignment","marginTop","marginBottom","svg","fontSize","loadingTitle","bodyCell","lineHeight","bodyRow","rowData","backgroundColor","headerCell","headerRow","setStatus","retryTitleFromStatus","statusIcon","post","attributes","response","eventsStatus","alerts","fire","text","disabled","badgeColors","border","badgeIcon","badgeTitle","Badge","background","foreground","paddingLeft","paddingRight","radius","renderLeft","Icon","marginLeft","stroke","strokeAlign","strokeWeight","lastDelivery","message","delivery","ERRORS","default","duplicated_event","failed_without_deliveries","whiteSpace","ToggleableDetails","details","_response","responseBody","parse","_unused","parsedErrors","responseErrors","deliveryFailureReason","statusMessage","fontStyle","paddingTop","children","open","setOpen","inline","was","fontFamily","ErrorBoundary","Component","constructor","props","super","handleContactSupport","this","onRequestClose","window","openHelpdesk","state","hasError","static","render","Alert","type","marginVertical","boxShadow","style","History$1","CloseModalIcon","as","icon","HistoryModal","createPortal","ThemeProvider","Modal","paddingBottom","document","body","VALID_LOGO_NAMES","getValidLogoName","kebabName","kebabCase","isValidLogoName","HIDDEN_FIELD","HIDDEN_RESPONSE","FIELD_KEY_RE","SENTINEL_VALUES","Set","extractIds","_conds$data","_conds$data2","conds","triggerConditions","formId","relationships","form","selectedOptionsByField","_optionIds$","exec","raw","$in","optionIds","Array","isArray","String","has","fieldId","optionId","fetchFieldDefinitions","ids","Map","walk","fd","set","_unused2","fetchCampuses","Campus","campus","_unused3","buildResponseDetails","fieldsByForm","fieldDefs","campuses","_fieldsByForm$get2","fieldLabel","valueLabel","fieldType","fieldableId","options","labelers","resolve","extracted","sub","targets","entry","formIds","FormField","FormFieldOption","byId","fetchFormFields","uniq","t","fieldDefIds","campusIds","_fieldsByForm$get","add","responseDetails","resolveResponseDetails","groups","_groups$get","group","resolvedById","subs","resolved","_resolvedById$get","formatResponseDetails","_excluded","_excluded2","AutomationContext","EditableAutomation","_ref","updateAutomation","onDelete","openHistoryNow","disabledReason","_objectWithoutPropertiesLoose","AutomationWrapper","Header","Icons","Manage","Description","EditableFooter","IncomingAutomation","LinkToAutomation","IncomingDescription","Footer","triggerEventDescription","parseDescription","cardOpacity","active","paddingVertical","truncate","lowerFirst","conditionalSuffix","optionallyPrettifyArchivedPrefix","separator","external","triggerAdminUrl","canManage","tooltip","hover","_ref2","rest","Provider","Card","currentPersonCanCreate","currentPersonId","trigger","historyVisible","setHistoryVisible","isActive","Dropdown","iconRight","Item","onSelect","createdById","Tooltip","placement","openDelay","isConfirmed","resource","avatar","fetchCurrentPersonAvatar","prev","createdBy","avatarUrl","createdByName","confirmButtonText","ToggleSwitch","isChecked","patch","newStatus","triggerProductName","Logo","markOnly","operationAppName","_automation$createdBy","_automation$createdBy2","createdBySuffix","Divider","marginHorizontal","Avatar","basis","source","_automation$createdBy3","_automation$eventsSta","_automation$eventsSta2","_automation$eventsSta3","_automation$eventsSta4","_automation$eventsSta5","_automation$eventsSta6","_automation$createdBy4","buttonProps","paddingHorizontal","historyProps","setHistoryProps","toLocaleString","marginRight","_automation$triggerPa","triggerParams","useTriggerPersonOverride","trim","startsWith","fetchCreatorProfiles","compact","profiles","mergeProfilesAndSubscriptions","profile","fetchTriggerResources","automations","QUERYABLE_BY_MULTIPLE_IDS","registrations","services","NOT_QUERYABLE","automationsByModel","accumulator","automationTriggerResource","promises","flatMap","resourceParts","_QUERYABLE_BY_MULTIPL","fetchNothing","fetchAllAtOnce","fetchOneAtATime","triggerResources","settledPromises","allSettled","acc","concat","fetchResourceName","path","_props","reject","client","model","upperFirst","IncomingAutomations","encryptedParam","setAutomations","App","PersonApp","personApp","allowPcoLogin","app","toLowerCase","fetchPersonApps","operationApps","AutomationSubscription","fetchIncomingAutomations","buildGivingDescription","tr","resourceName","nameOrDescription","triggerResourceName","verb","messageName","mapNameToVerb","buildDescription","mergeTriggerResourceEventDescriptions","noResults","borderBottom","Summary","image","Spinner","TileView","minCellWidth","operationDefinitionId","od","sectionId","section","renderOptionsWithoutConsideringGroup","renderOptions","groupedOptions","groupBy","sort","gt","OptionGroup","Definition","selectedOperation","onOperationDefinitionChange","operationDefinitions","selectedSection","operationDefinitionsWithUniqueIds","primaryOperations","primarySectionOptions","uniqBy","sectionGroup","secondaryOperations","handleAnySelectChange","idType","renderOperations","operations","defaultValue","Field","canAccessPeople","loadListForField","loadingLists","dependencies","generator","memoizedObject","setMemoizedObject","newObject","isEqual","useMemoizedObject","dependsOn","depKey","camelCase","fieldDependencies","listOptions","actionAllowedOptions","op","automationNotAllowed","info","HelperDrawer","Toggle","drawerId","Loading","SelectSearch","Checkbox","TextArea","DateField","Checkboxes","NumberField","PersonSearch","isLoading","TextField","RadioButtons","dangerouslySetInnerHTML","__html","content","console","warn","renderField","overridenEmptyValue","option","groupTypes","TapestrySelect","items","item","handleSelectedValueChange","prompt","generatePrompt","selectedOption","_option$value","selectedLabel","prevSelectedLabel","setPrevSelectedLabel","query","setQuery","showFilteredOptions","setShowFilteredOptions","showClearButton","setShowClearButton","filteredOptions","sortBy","formattedQuery","TapestryCombobox","Popover","closeOnSelect","closeButton","cursor","onBlur","target","onClear","onFocus","select","handleValueChange","openOnFocus","placeholder","popoverProps","matchWidths","renderRight","index","isCurrent","role","Highlight","Menu","_selectedOption$meta","immediateSearch","debouncedSearch","useMemo","debounce","search","cancel","myself","_setQuery","TapestryCheckbox","checked","TapestryTextArea","_field$allowUnanswere","specificDate","setSpecificDate","todaysValue","customValue","dateBeforeValue","orgFormat","dateFieldValue","setDateFieldValue","toDate","allowUnansweredOption","handleSelectChange","TapestryDateField","defaultOpen","formatValue","selectedValues","setSelectedValues","handleCheckboxesChange","newSelectedValues","minimumValue","minValue","maximumValue","maxValue","inputValue","setInputValue","Number","InputBox","TapestryNumberField","newNumberValue","min","max","hasControls","display","handleCheckedChange","Radio","Fields","newSelections","renderableFields","handleSelectedFieldOptionsChange","dependents","dependent","deeper","errorAlertProps","borderRadius","getVisibleApps","Topbar","apps","a","getWebhooksApps","OperationApp","getOperationDefinitions","OperationDefinition","NewAutomation","afterCreateOptions","blankStateLink","debugMode","defaultApp","_selectedDefinition$f","_selectedTriggerEvent","_selectedDefinition$f2","selectedTriggerEvent","setSelectedTriggerEvent","dynamicTriggerConditions","setDynamicTriggerConditions","selectedApp","setSelectedApp","setOperationApps","setOperationDefinitions","loadingOperationDefinitions","setLoadingOperationDefinitions","setSelectedDefinition","setSelectedFieldOptions","setLoadedLists","setLoadingLists","submitting","setSubmitting","callAfterCreate","setCallAfterCreate","setTriggerParams","activeAppRef","useRef","dangerAlertPresent","footerMessage","search_name_or_email","OperationDefinitionList","getListOptions","ret","selected_definition","visibleApps","webhooksApps","getOperationApps","defaultSelection","definitions","current","dynamicConditions","baseConditions","cloneDeep","writableFields","renderOnly","buildTriggerConditions","conditions","getDescription","descriptionParts","submitCreate","onConfirm","location","reload","alert","handleChangeTriggerEvent","triggerEvent","idx","Application","onOperationAppChange","LoadingOperationDefinitions","newDefinition","disableSubmit","param","html","borderTop","operation_params","definition_identifier","operation_app_name","operation_definition_class_name","trigger_conditions","trigger_params","cancelButtonText","getButtonText","operationFields","required","every","fieldIsFilled","fieldIsSelect","nextRequiredDescription","renderedFields","getNextRequiredDescription","autoFocus","handleChange","NewAutomationModal","zIndex","icons","churchCenter","logomark","canCreate","hasActiveAutomations","onPauseAutomations","newModalVisible","setNewModalVisible","isPaused","activeCount","pausedCount","wrap","Automations","blankStateDescription","incomingAutomationsParam","currentOrganization","permissionDeniedReason","fetchAutomations","URLSearchParams","customTheme","toggleAttribute","some","handleDelete","delete","BlankStateHeadingProps","BlankStateTextProps","originalAutomation","newState","updated","newAutomations","margin","mediaQueries","lg","styles"],"mappings":"2zDAEA,MAAMA,GAAiBA,iBACrBC,EAAAC,qBACEC,GAAG,oBACH,YAAU,oBACVC,MAAM,6BACNC,QAAQ,qBACRC,UAAU,uBAEVL,EAAAC,cAAA,QAAA,KAAO,4BACPD,EAAAC,cAAA,IAAA,CAAGK,QAAQ,oBACTN,EAAAC,sBACEM,EAAE,uTACFC,KAAK,UACLH,UAAU,sCAGdL,EAAAC,sBACEM,EAAE,qMACFC,KAAK,sBAEPR,EAAAC,sBACEM,EAAE,0DACFC,KAAK,yBAEPR,EAAAC,sBACEQ,EAAE,SACFC,EAAE,SACFC,MAAM,SACNC,OAAO,QACPC,GAAG,QACHC,GAAG,QACHN,KAAK,yBAEPR,EAAAC,cACEQ,OAAAA,CAAAA,EAAE,SACFC,EAAE,SACFC,MAAM,SACNC,OAAO,QACPC,GAAG,QACHC,GAAG,QACHN,KAAK,yBAEPR,EAAAC,cACEQ,OAAAA,CAAAA,EAAE,SACFC,EAAE,SACFC,MAAM,SACNC,OAAO,QACPC,GAAG,QACHC,GAAG,QACHN,KAAK,yBAEPR,EAAAC,cAAA,OAAA,CACEQ,EAAE,SACFC,EAAE,SACFC,MAAM,SACNC,OAAO,QACPG,UAAU,2CACVP,KAAK,yBAEPR,EAAAC,cAAA,OAAA,CACEM,EAAE,mKACFC,KAAK,yBAEPR,EAAAC,cACEM,OAAAA,CAAAA,EAAE,2JACFC,KAAK,yBAEPR,EAAAC,cACEM,OAAAA,CAAAA,EAAE,iTACFC,KAAK,yBAEPR,EAAAC,cACEM,OAAAA,CAAAA,EAAE,8SACFC,KAAK,yBAEPR,EAAAC,cAAA,OAAA,CACEM,EAAE,gUACFC,KAAK,aC7EEQ,gBAAsBC,EAAc,CAC/CC,WAAY,KACZC,cAAe,KACfC,mBAAoB,OCKDC,GAAKC,MAAMC,IACJF,GAAKC,MAAME,IAC1B,MAAAC,GAAaJ,GAAKC,MAAMI,IACxBC,GAAUN,GAAKC,MAAMM,IACrBC,GAAiBR,GAAKC,MAAMQ,IAC5BC,GAAgBV,GAAKC,MAAMU,ICVjCC,eAAeC,GACpBC,GAEA,OAAOC,QAAQC,IACbF,EAAcG,IAAIL,UAStB,SAA0BM,GAYxB,MAXwD,CACtD,mCACA,wCACA,2CACA,qCACA,uCACA,uCACA,uCACA,sCAGqDC,SACrDD,EAAaE,6BAEjB,CAvBUC,CAAiBH,KACnBA,EAAaI,kBAwBrBV,eAAuCM,GACrC,IAAII,EAAc,GAClB,GAEE,qCADAJ,EAAaE,6BAEb,CACA,MACMG,SAuFVX,eAA6BY,GAC3B,MAAMC,KAAEA,SAAeC,GACpBC,IAAI,CACHF,KAAM,CACJG,OAAQ,CAAEC,SAAU,oBACpBC,MAAO,CAAEjD,GAAI2C,IAEfO,IAAM,cAEPC,MAAM,IAAM,CAAC,CAAEP,KAAM,CAAEQ,KAAM,OAEhC,OAAOR,CACT,CApGuBS,CAAchB,EAAaiB,gBAAgBX,aACxC,GAEtB,GAAID,MAAAA,GAAAA,EAAUU,KAAM,CAClB,IAAIG,EAGFA,EADEb,EAASc,WACK,cAAad,EAASU,OAEvBV,EAASU,KAG1BX,EAAcJ,EAAaI,YAAYgB,QACrC,oBACAF,EAEJ,CACF,KAAO,CAEL,MAAMG,EACJrB,EAAaiB,gBAAgBK,qBAAqBC,MAChD,0BACC,GACCC,QA+EV9B,eAAoC2B,GAClC,MAAMd,KAAEA,SAAeC,GACpBC,IAAI,CACHF,KAAM,CACJG,OAAQ,CACNe,gBAAiB,+BACjBC,YAAa,SAEfC,QAAS,iBAEXd,IAAM,qBAAoBQ,MAE3BP,MAAM,KAAA,CAASP,KAAM,CAAEQ,KAAM,OAEhC,OAAOR,CACT,CA9FkCqB,CAAqBP,GAC/CG,EAAgBT,OAClBX,EAAcJ,EAAaI,YAAYgB,QACrC,wBACAI,EAAgBT,MAElBX,GACEJ,EAAaiB,gBAAgBY,QACA,eAA7BL,EAAgBM,SACX,KAOb,SACE9B,EACAwB,GAIAO,IAAAA,EAAAC,EACA,OAAQR,EAAgBM,UACtB,IAAK,aACH,OAAOG,OAAOC,QAA2C,OAApCH,EAAC/B,EAAaiB,gBAAgBY,QAAME,EAAI,CAAE,GAC5DhC,IAAI,EAAEpC,EAAIwE,MAAYC,IAAAA,EACrB,MAAMC,GAGH,OAFDD,EAAAZ,EAAgBc,aAAaC,KAC1BC,GAAgBA,EAAY7E,KAAO8E,SAAS9E,EAAI,WAClD,EAFDyE,EAEGC,QAAS,iBACd,MAAQ,GAAEK,GAAWP,MAAWE,GAAM,GAEvCM,KAAK,MACV,IAAK,SAAU,CAAAC,IAAAA,EACb,MAAMP,EAAQrC,EAAaiB,gBAAgBoB,MAC3C,OAAOA,GACHO,OAAAA,EAAApB,EAAgBc,aAAaC,KAC1BC,GAAgBA,EAAY7E,KAAO8E,SAASJ,EAAO,WADtDO,EAAAA,EAEGP,QAAS,iBACZ,YACN,CACA,IAAK,UACH,OAAQrC,EAAaiB,gBAAgBoB,OACnC,IAAK,OACH,MAAO,MACT,IAAK,QACH,MAAO,KACT,QACE,MAAO,aAEb,QACE,OAAyCL,OAAzCA,EAAOhC,EAAaiB,gBAAgBoB,OAAKL,EAAI,aAEnD,CA7CiBa,CAA6B7C,EAAcwB,MAChD,GAEV,CACA,OAAOpB,GAAeJ,EAAaI,WACrC,CAnEyC0C,CAAwB9C,IAEpDA,IAGb,CAwGA,SAAS0C,GAAWK,GAClB,OAAOA,EAAOC,OAAO,GAAGC,cAAgBF,EAAOG,MAAM,EACvD,CAEA,MAAM1C,GAAe,IAAI2C,EAAO,CAC9BC,KAAMC,EAAU,SAAU,CAAEC,UAAU,IACtCC,QAAS,eAkCJ,SAASC,GAAoBC,GAClC,OAAIA,EAAMC,UACA,GAAED,EAAM9F,MAAM8F,EAAMC,YACJ,iBAAfD,EAAME,KACP,GAAEF,EAAM9F,kBAGlB,IACF,CAqBA,SAASiG,GAAyBC,GAChC,GAAIA,EAAWC,gBAAgBvC,MAAM,uCACnC,MAAO,8BAEX,CAMA,SAASwC,GAAeC,EAAgBC,GACtC,OAAOhC,OAAOiC,UAAUH,eAAeI,KAAKH,EAAQC,EACtD,CAEA,SAASG,IAAgBX,MACvBA,EAAKY,YACLA,IAKA,GAAIZ,EAAMa,KACR,OAAOb,EAAMa,KACJd,GAAAA,GAAoBC,GAI7B,OAFaY,EADMb,GAAoBC,IAKvC,MAAU,IAAAc,MAAO,kCAAiCC,KAAKC,UAAUhB,KAErE,CA0CA,SAASiB,GACPjB,EACAkB,EACAC,GAEA,IAlBF,SACEnB,EACAmB,GAEA,IAAK3C,OAAOiC,UAAUH,eAAeI,KAAKV,EAAO,YAAa,OAAO,EAErE,MAAMoB,EAAWpB,EAAMoB,SACvB,GAAIC,EAAUD,GAAW,OAAOA,EAEhC,MAAME,EAAe9C,OAAO+C,KAAKH,GAAU,GAC3C,OAAOA,EAASE,KAAkBH,EAAqBG,EACzD,CAOOE,CAAaxB,EAAOmB,GAAuB,OAAO,EAEvD,MAAMC,EAAWpB,EAAMoB,SACvB,GAAgB,MAAZA,IAAiC,IAAbA,EAAmB,OAAW,EAEtD,MAAMK,EAAajD,OAAO+C,KAAKH,GAAU,GACnCM,EAAWR,EAAUpC,KAAM6C,GAAMA,EAAEzH,KAAOuH,GAChD,OAAKC,GACET,GAAuBS,EAAUR,EAAWC,EACrD,CAEgB,SAAAS,GACdC,EACAV,GAEA,OAAOU,EAAiBC,OACrB9B,GACgB,WAAfA,EAAME,MACNe,GAAuBjB,EAAO6B,EAAkBV,GAEtD,CAEA,SAASY,IAAuBC,mBAC9BA,EAAkBb,qBAClBA,EAAoBP,YACpBA,IAmDA,OAQF,UAA4CoB,mBAC1CA,EAAkBb,qBAClBA,EAAoBP,YACpBA,EAAWjE,YACXA,IAOA,GACyC,qCAAvCqF,EAAmB3B,gBACnB,CAAA4B,IAAAA,EACA,MAAMpB,EAAOD,EAAYsB,0BACnBC,EACJtB,IACAoB,OADIA,EACJpB,EAAK/B,KAAMsD,GAAMA,EAAExD,MAAMyD,aAAelB,EAAqBmB,mBAA7DL,EAAAA,EACItF,aAEN,OAAOwF,EACHxF,EAAYgB,QAAQwE,EAAiB,qBACrCxF,CACN,CACEqF,OAAAA,EAAmB3B,gBAAgBvC,MACjC,uCAGK,GAEAnB,CAEX,CAxCS4F,CAAmC,CACxC5F,YA9CkBqF,EAAmBH,iBACpCvF,IAAK0D,IAAUwC,IAAAA,EACd,IAAKlC,GAAea,EAAsBnB,EAAM9F,IAAK,OAAW,KAEhE,MAAM0E,EAAQuC,EAAqBnB,EAAM9F,IACzC,IAAI2G,EAEJ,OAAQb,EAAME,MACZ,IAAK,SACL,IAAK,eACL,IAAK,eACL,IAAK,eAGH,OAFAW,EAAOF,GAAgB,CAAEX,QAAOY,gBAG9BC,IAAQ2B,OAAJA,EAAI3B,EAAK/B,KAAMsD,GAAMA,EAAExD,MAAMyD,aAAezD,SAAxC4D,EAAAA,EAAgD7F,aAE5D,IAAK,WACH,OAAOiC,GAASoB,EAAMyC,MACxB,IAAK,aAGH,OAFA5B,EAAOF,GAAgB,CAAEX,QAAOY,gBAEzBC,EACJiB,OAAQY,GAAMpC,GAAe1B,EAAiB8D,EAAE9D,QAChDtC,IACEoG,GACE,GAAEzD,GAAYL,EAAiC8D,EAAE9D,WAChD8D,EAAE/F,eAGPuC,KAAK,MACV,IAAK,cACL,IAAK,YACL,IAAK,WACL,IAAK,YACH,OAAON,EACT,QACE,MAAU,IAAAkC,MACP,qDAAoDd,EAAME,QAEjE,GAED4B,OAAQrH,GAAMA,GACdyE,KAAK,MAIN0B,cACAoB,qBACAb,wBAEJ,CA4CgB,SAAAwB,GAAiBC,GAC/B,OAAOA,EACJjF,QAAQ,KAAM,MACdA,QAAQ,KAAM,MACdA,QAAQ,KAAM,QACdA,QAAQ,KAAM,KACnB,UAcgBkF,GAAcC,EAAc5H,GAC1C,MAAM6H,EAAaC,GAAOF,EAAM,cAChC,IAAKC,EAAWE,UACd,MAAO,GAGT,MAAML,EAASD,GAAiBzH,GAChC,OAAO6H,EAAWH,OAAOA,EAC3B,CAOgB,SAAAM,GAAUC,EAAeC,GACvC,OAAc,IAAVD,EACM,KAAIC,IAEJ,GAAED,KAASC,IAEvB,CAEO,SAASC,GAAY/D,GAC1B,OAAOA,EAAO3B,QAAQ,KAAM,GAC9B,CAMO,SAAS2F,GAAqBC,GACnC,MAAMC,EAAeD,EAAgBE,MAAM,KAE3C,MAAO,CACLC,QAASF,EAAa,GACtBG,WAAYH,EAAaA,EAAaI,OAAS,GAC/CC,aAAcL,EAAa/D,MAAM,GAAI,GAAGP,KAAK,KAC7C4E,aAAcN,EAAaA,EAAaI,OAAS,GAErD,CAEgB,SAAAG,GAAcC,EAAYtF,GAAiBuF,IAAAA,EACzD,MAAkC,SAAlB,OAAZA,EAAAD,EAAME,SAAND,OAAYA,EAAZA,EAAe,SAAfA,EAAAA,EAAmBE,QACb,gCAA+BzF,GAAU,4BAGrD,IAAA,CCzaA,MAAM0F,GAAiB,IAAI1E,EAAO,CAChCC,KAAMC,EAAU,WAAY,CAAEC,UAAU,IACxCC,QAAS,eAEL/C,GAAe,IAAI2C,EAAO,CAC9BC,KAAMC,EAAU,SAAU,CAAEC,UAAU,IACtCC,QAAS,eAILuE,GAAS,CACbC,UAAW,CACT7B,MAAO,UACP7D,MAAO,CAAC,cAEV2F,OAAQ,CACN9B,MAAO,SACP7D,MAAO,CAAC,SAAU,eAEpB4F,QAAS,CACP/B,MAAO,UACP7D,MAAO,CAAC,qBAAsB,iBAAkB,oBAElD6F,QAAS,CACPhC,MAAO,UACP7D,MAAO,CAAC,YAEV8F,QAAS,CACPjC,MAAO,SACP7D,MAAO,CAAC,aA4CZ3C,eAAe0I,GAA8BC,GAC3C,MAAMC,EAAYD,EAAO9H,KAAKR,IAAKoG,GAAMoC,GAAcpC,IACvD,IACE,MAAMqC,QAjBV9I,eAA2B4I,GACzB,MAAM/H,KAAEA,SAAeC,GAAaC,IAAI,CACtCF,KAAM,CACJG,OAAQ,CACN+H,OAAQ,WAEV7H,MAAO,CAAEjD,GAAI2K,EAAU3F,KAAK,OAE9B9B,IAAM,WAGR,OAAON,CACT,CAKyBmI,CAAYJ,GACjC,MAAO,CAAED,SAAQG,SACnB,CAAE,MAAOf,GACP,MAAO,CAAEY,SAAQG,OAAQ,GAC3B,CACF,CAEA,SAASG,IAAqBN,OAAEA,EAAMG,OAAEA,IACtC,MAAMI,EAAaP,EAAO9H,KAAKsI,OAAO,CAACC,EAAQ3C,KAC7C,MAAM4C,EAAWR,GAAcpC,GACzB6C,EAAcR,EAAOjG,KACxB0G,GAAMF,EAASjD,aAAemD,EAAEtL,GAAGmI,YAatC,OAVEgD,EAAOI,KAAIC,GAAA,CAAA,EACNhD,EAFH6C,EAEI,CACJI,OAAQ,CAAEzL,GAAIqL,EAAYrL,GAAIoD,KAAMiI,EAAYjI,OAKhDqI,CAAAA,OAAQ,CAAEzL,GAAIoL,EAAUhI,KAAM,eAG3B+H,GACN,IAEH,OAAAK,GAAYd,CAAAA,EAAAA,EAAQ9H,CAAAA,KAAMqI,GAC5B,CAEA,SAASL,GAAcc,GACrB,OAAOA,EAAMN,QACf,CA2FA,SAASO,IAAQC,WACfA,EAAUvC,gBACVA,EAAewC,YACfA,EAAWC,qBACXA,IACeC,IAAAA,EACf,MAAMrB,OAAEA,EAAMsB,QAAEA,EAAOC,gBAAEA,EAAeC,QAAEA,EAAOC,OAAEA,EAAMC,UAAEA,GA/F7D,SACEC,EACAhD,EACAwC,GAEA,MACOS,EAAGC,GAAYC,KACfR,EAASS,GAAcD,GAAS,IAChCE,EAAYC,GAAiBH,EAAuC,CAAA,IACpEL,EAAQC,GAAaI,EAC1BX,EAAc,CAAE5I,MAAO,CAAEgH,OAAQ4B,IAAkB,CACrD,IACOe,EAAMC,GAAWL,KAClBM,OAAEA,EAAMb,gBAAEA,EAAec,YAAEA,GAkDnC,SAAuBC,EAAiBC,GACtC,MAAOH,EAAQI,GAAaV,EAAS,GAcrC,MAAO,CAAEM,SAAQb,gBAVO,CAAEkB,YAFNC,KAAKC,MAAMP,EA7Df,IA6DmC,EAEZQ,aAEvC,SAAsBC,GACpBL,EAlEc,IAkEHK,EAAU,GACvB,EAJqDC,WADlCJ,KAAKK,KAAKR,EA9Db,KAyEkBF,YAJdW,EAAY,KAC9BR,EAAU,IACT,IAGL,CAlEmDS,CARjC,EAUdf,MAAAA,OAAAA,EAAAA,EAAMK,YAERW,EAAU,KACJ5B,GAAWU,EAAWI,KAE1BL,GAAW,GAjGf1K,eACEsH,EACAgD,EACAF,GAoBA,aAduBjC,GAAepH,IAAI,CACxCF,KAAI4I,GACFqC,CAAAA,GAAIxE,EACJtG,OAAQ,CACN+K,SAAU,kCACVC,MAAO,0DAET/J,QAAS,gBACTgK,MAAO,eACJ7B,GAELjJ,IAAM,4BAA2BmJ,YAIrC,CA2EI4B,CAAY5E,EAAiBgD,EAAYb,GAAA,CACvCsB,SACAoB,SAnBY,IAoBT/B,IAEFgC,KAAK1D,IACL0D,KAAKnD,IACLmD,KAAMzD,IACLiC,EAAeyB,GAAK5C,GAAA,CAAA,EAAW4C,EAAO,CAAAtB,CAACA,GAASpC,EAAO9H,QACvDiK,EAAQnC,EAAOkC,MACfH,GAAW,KAEZtJ,MAAMkL,GAAqB,EAC7B,CAAChC,EAAchD,EAAiB2C,EAASG,EAAQW,EAAQJ,IAE5D,MAAMR,EAAUwB,EAAY,KAC1Bf,EAAc,CAAA,GACdE,OAAQyB,GACRvB,GAAW,EACV,CAACA,IAMJ,SAASsB,EAAsBvE,GAC7ByC,EAAS,KACP,MAAMzC,GAEV,CAEA,OAVA8D,EAAU,KACR1B,GAAO,EACN,CAACA,EAASC,IAQN,CACLzB,OAAQgC,EAAWI,IAAW,GAC9Bd,UACAC,kBACAE,SACAD,UACAE,YAEJ,CAmCImC,CAAU3C,EAAW5L,GAAIqJ,EAAiBwC,IACtC7K,WAAEA,EAAUC,cAAEA,EAAaC,mBAAEA,GAAuBsN,EAIvD1N,IAEG2N,EAAkBtC,EAAOlJ,OAASqB,OAAO+C,KAAK8E,EAAOlJ,OAAOyG,OAAS,EACrEgF,ED8KQ,SAAa9F,GAC3B,MAAMC,EAAaC,GAAOF,EAAM,cAChC,OAAOE,KAAS6F,KAAK9F,EAAY,OACnC,CCjLoC+F,CAAahD,EAAWiD,YAAc,GAClEC,EAAoBnG,GAAciD,EAAWiD,UAAW7N,GACxD+N,EAA2BL,EAC5B,iCAAgCI,IACjC,0CAEEE,EAAU,CACd,CACEC,KAAOvD,gBAAqB5L,EAAAC,cAACmP,GAAgB,CAACjF,OAAQyB,EAAMzB,SAC5DkF,IAAK,CACHC,QAAS,YAEXC,OAAQ,UAEV,CACEJ,KAAOvD,GACL5C,GAAO4C,EAAMmD,WACVS,UAAUrO,GACVyH,ODsIJ,UAA8B1H,WACnCA,EAAUE,mBACVA,IAKA,MAAQ,GAAEuH,GAAiBzH,MACzBE,EAAqB,QAAU,UAEnC,CChJkBqO,CAAqB,CAAEvO,aAAYE,wBAC/CmO,OAAQ,iBAEV,CACEJ,KAAOvD,gBACL5L,EAAAC,cAACyP,EAAKC,CAAAA,GAAK,aAAY/D,EAAMD,OAAOzL,MAAO0L,EAAMD,OAAOrI,MAE1D+L,IAAK,CACHO,SAAU,OAEZL,OAAQ,WAEV,CACEJ,KAAOvD,gBAAqB5L,EAAAC,cAAC4P,GAAmBjE,CAAAA,MAAOA,IACvDyD,IAAK,CACHS,KAAM,GAERP,OAAQ,WAEV,CACEJ,KAAOvD,IACJ,IAAIvB,GAAOC,UAAU1F,SAAUyF,GAAOI,QAAQ7F,OAAOpC,SACpDoJ,EAAMzB,sBAENnK,EAAAC,cAAAD,EAAA+P,SACE/P,kBAAAA,EAAAC,cAAC+P,GACCzD,CAAAA,aAAcT,EAAW5L,GACzB0L,MAAOA,EACPrC,gBAAiBA,EACjByC,qBAAsBA,KAEtB,IAAI3B,GAAOG,QAAQ5F,OAAOpC,SAASoJ,EAAMzB,sBACzCnK,EAAAC,cAACgQ,GAAiB,CAChB1D,aAAcT,EAAW5L,GACzB0L,MAAOA,EACPrC,gBAAiBA,EACjB2G,eAAgB9D,EAChBJ,qBAAsBA,KAKhCqD,IAAK,CACHc,UAAW,SAEbZ,OAAQ,GACRa,SAAU,sBAId,OACEpQ,EAAAC,cAACoQ,EAAS,CAACC,QAASC,EAAM,+BACxBvQ,EAAAC,cAACoQ,EAAUC,CAAAA,QAASC,EAAM,kCACxBvQ,EAAAC,cAACuQ,EACCC,CAAAA,MAAO,EACPC,KAAK,OACLC,MAAOJ,EAAM,4BACbK,OAAQL,EAAM,2BAEbzE,EAAWnJ,0BAEd3C,EAAAC,cAAC4Q,GACCF,MAAOJ,EAAM,4BACbG,KAAMH,EAAM,oBACZO,QAEC7B,GAAAA,iBAGLjP,EAAAC,cAACoQ,EAAS,CAACC,QAASC,EAAM,+BACxBvQ,EAAAC,cAAC8Q,EAAG,CAACC,UAAW,IACZ9E,IAAYtB,EAAOhB,QAAU+E,iBAC7B3O,EAAAC,cAACoQ,EACCY,CAAAA,WAAW,MACXC,KAAK,aACLC,aAAa,gBACbb,QAASC,EAAM,+BAEfvQ,EAAAC,cAACoQ,EAAU1P,CAAAA,MAAM,4BACfX,EAAAC,cAACmR,EAAMC,WACLC,CAAAA,WAAYf,EAAM,0BAClBI,MAAOJ,EAAM,kBACbgB,SAAS,iBACV,iCAGDvR,EAAAC,cAACuR,EACCtR,CAAAA,GAAG,gBACHuR,WAAY,KACZC,SAAUA,EAAGC,oBAIXrF,EAAU,CAAEnJ,MAHKwO,EACb,CAAExH,OAAQwH,GACV,MAEN,EACAC,MAAM,SACNhN,MAAmB,OAAdqH,EAAEI,EAAOlJ,YAAK,EAAZ8I,EAAc9B,qBAErBnK,EAAAC,cAACuR,EAAOK,OAAM,CAACjN,MAAO,MAAM,OAC3BJ,OAAOJ,OAAOiG,IAAQ/H,IAAK6H,gBAC1BnK,EAAAC,cAACuR,EAAOK,OAAM,CACZrL,IAAK2D,EAAOvF,MACZA,MAAOuF,EAAOvF,MAAMM,KAAK,MAExBiF,EAAO1B,uBAKhBzI,EAAAC,cAAC6R,EAAM,CACLC,SAAU,CAAEzO,KAAM,mBAClB0O,QAAS5F,EACT6F,MAAM,UACNC,QAAQ,UACRvR,MAAO,IACR,0BAMPX,EAAAC,cAAC8Q,GAAIoB,UAAU,OAAOnB,UAAW,GAAIoB,SAAS,qBAC5CpS,EAAAC,cAACoS,EAAS3G,IACRwD,QAASA,EACTpM,KAAM8H,EACN0H,mBACEtS,EAAAC,cAACoQ,EAAS,CACRkC,UAAU,SACVpB,aAAa,SACbH,UAAW,GACXpB,SAAU,GACVU,QAASC,EAAM,iBACfiC,UAAY7D,GAAwB,GAAL,EAC/B8D,aAAe9D,EAA8B,OAAZH,gBAEjCxO,EAAAC,cAAC8Q,GACC1B,IAAK,CACHqD,IAAK,CACH9R,OAAQ,GACRD,MAAO,mBAIXX,EAAAC,cAACF,GAAgB,oBAEnBC,EAAAC,cAACuQ,EACCG,CAAAA,MAAOJ,EAAM,2BACbe,WAAYf,EAAM,0BAClBE,MAAO,EACPC,KAAMH,EAAM,qBACb,iCAGDvQ,EAAAC,cAAC4Q,EAAK8B,CAAAA,SAAUpC,EAAM,oBAAqBJ,UAAU,UAAS,aACjDxB,GAAmB,wBAAwB,sCACxB,IAC7BC,EACI,SAAQI,KACT,wBAELL,gBACC3O,EAAAC,cAAC6R,EACCU,CAAAA,UAAWjC,EAAM,iBACjByB,QAASA,IAAM1F,EAAU,CAAA,GACzB2F,MAAM,UACNL,MAAM,gBACNM,QAAQ,aAKhBhG,QAASA,EACT0G,aAAa,gCACbV,QAAS,CACPW,SAAU,CACR5B,WAAY,QACZ0B,SAAUpC,EAAM,oBAChBuC,WAAY,OACZxD,QAAS,aAEXyD,QAASA,EAAGC,cACH,CACLC,gBAAiB,IAAI5I,GAAOG,QAAQ5F,OAAOpC,SACzCwQ,EAAQ7I,QAENoG,EAAM,mCACN/B,EACJwC,UAAW,SAGfkC,WAAY,CACV5D,QAAS,YAEX6D,UAAW,CACTnC,UAAW,UAGX7E,MAMhB,CAEA,SAAS6D,IAAiBzD,aACxBA,EAAYX,MACZA,EAAKrC,gBACLA,EAAeyC,qBACfA,IAOA,MAAO7B,EAAQiJ,GAAa1G,EAASd,EAAMzB,QAyBrCkJ,EAAuBhJ,GAAOI,QAAQ7F,MAAMpC,SAAS2H,GACvD,UACAE,GAAOC,UAAU1F,MAAMpC,SAAS2H,GAChC,OACAE,GAAOK,QAAQ9F,MAAMpC,SAAS2H,GAC9B,UACA,QAEEmJ,EAAajJ,GAAOC,UAAU1F,MAAMpC,SAAS2H,GAC/C,CAAEwG,MAAOJ,EAAM,iCAAkCjN,KAAM,sBACvDkL,eAEJ,OACExO,EAAAC,cAAC6R,EAAM,CACLF,MAAOyB,EACPrB,QAtCJ,WACEoB,EAAU/I,GAAOI,QAAQ7F,MAAMM,KAAK,MACpCkF,GACGmJ,KAAK,CACJzQ,KAAM,CACJiL,GAAIxE,EACJzG,KAAM,CAAE0Q,WAAY,KAEtBpQ,IAAM,6BAA4BmJ,YAAuBX,EAAM1L,iBAEhEmO,KAAMoF,IACLL,EAAU/I,GAAOC,UAAU1F,MAAMM,KAAK,MACtC8G,EAAqByH,EAAS3G,KAAK4G,aACrC,GACCrQ,MAAM,KACL+P,EAAU/I,GAAOE,OAAO3F,MAAMM,KAAK,MACnCyO,GAAkBC,KAAK,CACrBC,KAAM,mFACNjC,MAAO,UACR,EAEP,EAkBIG,SAAUuB,EACVQ,SAAU3J,IAAWyB,EAAMzB,OAC3B+H,QAAQ,QACRvB,MACEtG,GAAOC,UAAU1F,MAAMpC,SAAS2H,GAC5BoG,EAAM,iCACNlG,GAAOI,QAAQ7F,MAAMpC,SAAS2H,GAC9BoG,EAAM,8BACNA,EAAM,8BAEZ0B,MAAM,UACNvB,KAAK,MAGX,CAEA,SAAST,IAAkB1D,aACzBA,EAAYX,MACZA,EAAKrC,gBACLA,EAAe2G,eACfA,EAAclE,qBACdA,iBA6BA,OACEhM,EAAAC,cAAC6R,EAAM,CACLF,MAAO,SACPI,QAxBJ,WACE5H,GACGmJ,KAAK,CACJzQ,KAAM,CACJiL,GAAIxE,EACJzG,KAAM,CAAE0Q,WAAY,CAAA,IAEtBpQ,IAAM,6BAA4BmJ,YAAuBX,EAAM1L,cAEhEmO,KAAMoF,IACLzH,EAAqByH,EAAS3G,KAAK4G,aAAY,GAEhDrF,KAAK,IAAM6B,KACX7M,MAAM,KACLsQ,GAAkBC,KAAK,CACrBC,KAAM,8EACNjC,MAAO,UAEX,EACJ,EAMIM,QAAQ,QACRvB,MAAO,iBACPsB,MAAM,UACNvB,KAAK,MAGX,CAEA,SAAStB,IAAiBjF,OAAEA,IAC1B,MAAM4J,EAAc1J,GAAOI,QAAQ7F,MAAMpC,SAAS2H,GAC9C,CACE6J,OAAQzD,EAAM,yBACdsD,KAAMtD,EAAM,mBAEdlG,GAAOC,UAAU1F,MAAMpC,SAAS2H,GAChC,CACE6J,OAAQzD,EAAM,mCACdsD,KAAMtD,EAAM,kCAEdlG,GAAOK,QAAQ9F,MAAMpC,SAAS2H,GAC9B,CACE6J,OAAQzD,EAAM,mCACdsD,KAAMtD,EAAM,kCAEdlG,GAAOG,QAAQ5F,MAAMpC,SAAS2H,GAC9B,CACE6J,OAAQzD,EAAM,yBACdsD,KAAMtD,EAAM,6BAEd,CACEyD,OAAQzD,EAAM,iCACdsD,KAAMtD,EAAM,gCAGZ0D,EAAY5J,GAAOI,QAAQ7F,MAAMpC,SAAS2H,GAC5C,gBACAE,GAAOK,QAAQ9F,MAAMpC,SAAS2H,GAC9B,iBACAE,GAAOC,UAAU1F,MAAMpC,SAAS2H,GAChC,sBACAE,GAAOG,QAAQ5F,MAAMpC,SAAS2H,GAC9B,mBACA,8BAEE+J,EAAa7J,GAAOE,OAAO3F,MAAMpC,SAAS2H,GAC5CE,GAAOE,OAAO9B,MACd4B,GAAOG,QAAQ5F,MAAMpC,SAAS2H,GAC9BE,GAAOG,QAAQ/B,MACf4B,GAAOF,GAAQ1B,mBAEnB,OACEzI,EAAAC,cAACkU,GACCxD,MAAO,CAAEyD,WAAY,cAAeC,WAAYN,EAAYF,MAC5DxE,IAAK,CAAEiF,YAAa,IAAKC,aAAc,KACvC5B,SAAUpC,EAAM,oBAChBiE,OAAO,OACPC,wBACEzU,EAAAC,cAACyU,EACCpR,CAAAA,KAAM2Q,EACNtD,MAAOoD,EAAYC,OACnBW,WAAYpE,EAAM,mBAGtBG,KAAK,KACLkE,OAAQb,EAAYC,OACpBa,YAAY,SACZC,aAAc,EACdlD,MAAOsC,GAGb,CAEA,SAASrE,IAAmBjE,MAAEA,IAC5B,MAAMzB,OAAEA,EAAM4K,aAAEA,GAAiBnJ,EA6E3BoJ,EA3EN,SAAuB7K,EAAgB4K,GACrC,IAAIC,EAAuC,KAE3C,OAAQ7K,GACN,IAAK,UACL,IAAK,kBACH6K,EAAU,wDACV,MACF,IAAK,SACL,IAAK,aACL,IAAK,iBACL,IAAK,qBACHA,EAMN,SAA+BC,EAAoB9K,GACjD,MAAM+K,EAAS,CACb,IAAK,wDACL,IAAK,kEACL,IAAK,sCACLC,QAAS,oBACTC,iBACE,yFACFC,0BACE,uFA4BJ,OACErV,EAAAC,cAACoQ,EAAS,CAACP,KAAM,EAAGwF,WAAW,UAC3BL,eAOAjV,EAAAC,cAACsV,GAAiB,CAChBC,QAnCR,SAAwBP,GAAoB,IAAAQ,EAC1C,GAAKR,MAAAA,IAAAA,EAAUS,aAAc,OAAO,KACpC,IAAIjC,EAEJ,IACEA,EAAW1M,KAAK4O,MAAMV,EAASS,aACjC,CAAE,MAAAE,GACAnC,EAAW,CAAEvJ,OAAQ,CAAC,gBACxB,CAEA,OAGF,SAAsBuJ,GACpB,OAAY,MAARA,GAAAA,EAAUvJ,OACLuJ,EAASvJ,OAAO5H,IAAK0H,GACT,iBAAVA,GAAsBA,EAAMlG,MAAM,qBACrCkG,EAAMrG,QAAQ,oBAAqB,sBACnCqG,GAGC,EAEX,CAbS6L,CAAapC,GAAUvO,KAAK,QAAiB,OAAZuQ,EAAIhC,QAAQ,EAARgC,EAAUT,QACxD,CAwBiBc,CAAeb,GACxB9K,OAAQ8K,EAAS9K,QAEhB+K,EAAOD,EAAS9K,SAAW+K,EAAOC,SAVrC,CAAC,aAAc,sBAAsB3S,SAAS2H,GAC5C+K,EAAOE,iBAEPF,EAAOG,0BAYjB,CA7DgBU,CAAsBhB,EAAc5K,GAGlD,OAAO6K,CACT,CA2DgBgB,CAAc7L,EAAQ4K,GAEtC,OAAOC,eACLhV,EAAAC,cAAC8Q,EAAG,CACF4B,SAAUpC,EAAM,oBAChB0F,UAAU,SACVnD,WAAW,OACXlD,SAAS,OACTsG,WAAW,MACXZ,WAAW,UAEVN,GAED,IACN,CAEA,SAASO,IAAkBY,SACzBA,EAAQX,QACRA,EAAOrL,OACPA,IAMA,MAAOiM,EAAMC,GAAW3J,GAAS,gBAMjC,OACE1M,EAAAC,cAACoQ,EAAUC,CAAAA,QAASC,EAAM,+BACxBvQ,EAAAC,cAAC8Q,EAAG,KACDoF,EAAU,IACVX,gBACCxV,EAAAC,cAAC6R,EACCwE,CAAAA,QACAtE,EAAAA,QAXV,WACEqE,EAASE,IAASA,EACpB,EAUU7F,KAAK,KACLuB,MAAM,UACNC,QAAQ,QACR+D,UAAU,UACX,YAKJG,eACCpW,EAAAC,cAAC8Q,GAAIzB,QAAS,EAAG8E,WAAY7D,EAAM,4CACjCvQ,EAAAC,cAAC4Q,GACC2F,WAAW,YACX7D,SAAUpC,EAAM,oBAChBuC,WAAW,OAEV3I,GAAW,GAAEA,MACbqL,IAGH,KAGV,CAWA,MAAMiB,WAAsBzW,EAAM0W,UAIhCC,YAAYC,GACVC,MAAMD,GAQRE,KAAAA,qBAAuB,KACjBC,KAAKH,MAAMI,gBACbD,KAAKH,MAAMI,iBAEbC,OAAOC,cAAY,EAXnBH,KAAKI,MAAQ,CAAEC,UAAU,EAC3B,CAEAC,kCACE,MAAO,CAAED,UAAU,EACrB,CASAE,SACE,OAAIP,KAAKI,MAAMC,sBAEXpX,EAAAC,cAACsX,EAAK,CACJC,KAAK,QACLC,eAAgB,EAChBnI,QAAS,IACTD,IAAK,CAAEqI,UAAW,sBAElB1X,EAAAC,cAAC4Q,EAAKiC,CAAAA,WAAW,QAAO,oIAE0C,iBAChE9S,EAAAC,cACE0X,SAAAA,CAAAA,MAAO,CACLhH,MAAOJ,EAAM,8BACb+E,WAAY,UAEdtD,QAAS+E,KAAKD,sBACf,mBAIG,MAKDC,KAACH,MAAMT,QACpB,EAIF,IAAAyB,GAAgBhB,gBACd5W,EAAAC,cAACwW,GAAa,CAACO,eAAgBJ,EAAMI,6BACnChX,EAAAC,cAAC4L,GAAY+K,IC50BjB,SAASiB,IAAe7F,QAAEA,iBACxB,OACEhS,EAAAC,cAAC6R,GACCgG,GAAG,SACHlX,OAAQ2P,EAAM,uBACdwH,KAAM,CACJpH,MAAOJ,EAAM,sBACbjN,KAAM,aAER0O,QAASA,EACTtB,KAAK,KACLkB,MAAM,QACNM,QAAQ,SAGd,CAEA,SAAS8F,IAAa7B,SACpBA,EAAQa,eACRA,EAAcZ,KACdA,EAAInE,MACJA,iBAOA,OAAOgG,gBACLjY,EAAAC,cAACiY,EAAcjG,CAAAA,MAAOA,gBACpBjS,EAAAC,cAACkY,EAAK,CACJ/B,KAAMA,EACNY,eAAgBA,EAChBpH,SAAU,IACV8H,UAAU,+BACVpI,QAASiB,EAAM,iBACf6H,cAAe7H,EAAM,iBACrBiE,OAAQjE,EAAM,sCAEdvQ,EAAAC,cAACoQ,EACCa,CAAAA,KAAK,aACLC,aAAa,gBACboB,UAAU,uBAEVvS,EAAAC,cAACuQ,EAAO,CACNC,MAAO,EACPE,MAAOJ,EAAM,2BACbe,WAAYf,EAAM,0BAClBoC,SAAUpC,EAAM,qBAChBuC,WAAW,OACZ,mCAGD9S,EAAAC,cAAC4X,GAAc,CAAC7F,QAASgF,KAE1Bb,IAGLkC,SAASC,KAEb,CC9DA,MAAMC,GAAoC,CACxC,MACA,WACA,YACA,gBACA,SACA,SACA,aACA,OACA,QACA,cACA,SACA,kBACA,aACA,gBACA,YAOWC,GAAoBlV,IAC/B,MAAMmV,EAAYC,EAAUpV,GAC5B,MAN8BA,IACvBiV,GAAiB/V,SAASc,GAK1BqV,CAAgBF,GAAaA,EAAY,mBC3B5CG,GAAe,iBACfC,GAAkB,oBAClBC,GAAe,gBACfC,GAAkB,IAAIC,IAAI,CAAC,cAE3BjW,GAAe,IAAI2C,EAAO,CAC9BC,KAAMC,EAAU,SAAU,CAAEC,UAAU,IACtCC,QAAS,eA4EX,SAASmT,GAAW1W,GAAuD2W,IAAAA,EAAAC,EACzE,MAAMC,EAAQ7W,EAAa8W,kBACrBC,EAAc,MAALF,GAAWF,OAANA,EAALE,EAAOtW,OAAmB,OAAfoW,EAAXA,EAAaK,uBAAaL,EAA1BA,EAA4BM,OAA5BN,OAAgCA,EAAhCA,EAAkCpW,WAAlCoW,EAAAA,EAAwChZ,GACjDuZ,EAA8B,MAALL,GAAWD,OAANA,EAALC,EAAOtW,OAAgB,OAAZqW,EAAXA,EAAa3F,iBAAU,EAAvB2F,EAAyBM,uBACxD,GACY,MAAVH,IACCG,GACiC,iBAA3BA,EAEP,YAGF,IAAK,MAAOjT,EAAK5B,KAAUJ,OAAOC,QAAQgV,GAAyB,CAAAC,IAAAA,EACjE,MAAM5V,EAAQgV,GAAaa,KAAKnT,GAChC,IAAK1C,EAAO,SACZ,MAAM8V,EAAOhV,MAAAA,OAAAA,EAAAA,EAA6BiV,IACpCC,GAAaC,MAAMC,QAAQJ,GAAOA,EAAa,MAAPA,EAAc,GAAK,CAACA,IAC/DtX,IAAKpC,GAAc,MAANA,EAAa,KAAO+Z,OAAO/Z,IACxC4H,OAAQ5H,GAA2B,MAANA,IAAe6Y,GAAgBmB,IAAIha,IACnE,MAAO,CACLia,QAASrW,EAAM,GACfwV,OAAQW,OAAOX,GACfc,SAAsBV,OAAdA,EAAEI,EAAU,IAAEJ,EAAI,KAE9B,CACA,OACF,IAAA,CAiCAzX,eAAeoY,GACbC,GAEA,MAAMjP,EAAS,IAAIkP,IACnB,GAAmB,IAAfD,EAAI1Q,OAAc,OAAOyB,EAE7B,IACE,MAAMvI,KAAEA,SAAeC,GAAaC,IAAuC,CACzEF,KAAM,CACJG,OAAQ,CACNe,gBAAiB,+BACjBC,YAAa,SAEfC,QAAS,gBACTsW,MAAM,EACNrX,MAAO,CAAEjD,GAAIoa,EAAIpV,KAAK,OAExB9B,IAAK,sBAEP,IAAK,MAAMqX,KAAM3X,EACfuI,EAAOqP,IAAIT,OAAOQ,EAAGva,IAAKua,EAE9B,CAAE,MAAAE,GAIF,CAAA,OAAOtP,CACT,CAEApJ,eAAe2Y,GACbN,GAEA,MAAMjP,EAAS,IAAIkP,IACnB,GAAmB,IAAfD,EAAI1Q,OAAc,OAAOyB,EAE7B,IACE,MAAMvI,KAAEA,SAAeC,GAAaC,IAA8B,CAChEF,KAAM,CACJG,OAAQ,CAAE4X,OAAQ,QAClBL,MAAM,EACNrX,MAAO,CAAEjD,GAAIoa,EAAIpV,KAAK,OAExB9B,IAAK,aAEP,IAAK,MAAM0X,KAAUhY,EACnBuI,EAAOqP,IAAIT,OAAOa,EAAO5a,IAAK4a,EAElC,CAAE,MAAAC,GAAM,CAIR,OAAO1P,CACT,CAEA,SAAS2P,GACPV,EACAW,EACAC,EACAC,GACiB,IAAAC,EACjB,MAAMpV,EAAoC,OAA/BoV,EAAGH,EAAajY,IAAIsX,EAAIhB,cAAO,EAA5B8B,EAA8BpY,IAAIsX,EAAIH,SACpD,IAAKnU,EAAO,MAAO,CAAEqV,WAAYzC,GAAc0C,WAAYzC,IAE3D,MAAMwC,EAAarV,EAAMyC,OAASmQ,GAElC,GAAwB,YAApB5S,EAAMuV,UACR,MAAO,CAAEF,aAAYC,WAAY,MAGnC,GAAwB,iBAApBtV,EAAMuV,WAAqD,MAArBvV,EAAMwV,YAAqB,CACnE,MAAMf,EAAKS,EAAUlY,IAAIiX,OAAOjU,EAAMwV,cACtC,IAAKf,EAAI,MAAO,CAAEY,aAAYC,WAAYzC,IAC1C,GAAoB,YAAhB4B,EAAGpW,SAAwB,MAAO,CAAEgX,aAAYC,WAAY,MAChE,GAAoB,MAAhBhB,EAAIF,SAAkB,MAAO,CAAEiB,aAAYC,WAAYzC,IAC3D,MAAM/U,GAAS2W,EAAG5V,cAAgB,IAAIC,KACnCsD,GAAM6R,OAAO7R,EAAElI,MAAQoa,EAAIF,UAE9B,MAAO,CAAEiB,aAAYC,YAAiB,MAALxX,OAAK,EAALA,EAAOc,QAASiU,GACnD,CAEA,GAAwB,mBAApB7S,EAAMuV,UAAgC,CACxC,GAAoB,MAAhBjB,EAAIF,SAAkB,MAAO,CAAEiB,aAAYC,WAAYzC,IAC3D,MAAMiC,EAASK,EAASnY,IAAIsX,EAAIF,UAChC,MAAO,CAAEiB,aAAYC,YAAYR,MAAAA,OAAAA,EAAAA,EAAQxX,OAAQuV,GACnD,CAEA,GAAoB,MAAhByB,EAAIF,SACN,MAAO,CAAEiB,aAAYC,WAAYzC,IAEnC,MAAM/U,GAASkC,EAAMyV,SAAW,IAAI3W,KAAMsD,GAAM6R,OAAO7R,EAAElI,MAAQoa,EAAIF,UACrE,MAAO,CAAEiB,aAAYC,YAAiB,MAALxX,OAAK,EAALA,EAAO2E,QAASoQ,GACnD,CAEA,MC9OM6C,GAA4C,CAChD,2CD6OyC,CAAEC,QAtM7C1Z,eACEE,GAEA,MAAMyZ,EAAYzZ,EAAcG,IAAKuZ,IAAG,CACtCvB,IAAKrB,GAAW4C,GAChBA,SAEIC,EAAUF,EAAU9T,OACvBiU,GACe,OAAdA,EAAMzB,KAEV,GAAuB,IAAnBwB,EAAQlS,OAAc,OAAOzH,EAEjC,MAAM8Y,QA6DRhZ,eACE+Z,GAEA,MAAM3Q,EAAS,IAAIkP,IAyBnB,aAxBMnY,QAAQC,IACZ2Z,EAAQ1Z,IAAIL,UACV,IACE,MAAMa,KAAEA,SAAeC,GAAaC,IAAiC,CACnEF,KAAM,CACJG,OAAQ,CACNgZ,UAAW,qCACXC,gBAAiB,SAEnBhY,QAAS,UACTsW,MAAM,GAERpX,IAAM,SAAQkW,aAEV6C,EAAO,IAAI5B,IACjB,IAAK,MAAMvU,KAASlD,EAClBqZ,EAAKzB,IAAIT,OAAOjU,EAAM9F,IAAK8F,GAE7BqF,EAAOqP,IAAIpB,EAAQ6C,EACrB,CAAE,MAAAvG,GACAvK,EAAOqP,IAAIpB,EAAQ,IAAIiB,IACzB,KAGGlP,CACT,CA1F6B+Q,CACzBC,EAAKP,EAAQxZ,IAAKga,GAAMA,EAAEhC,IAAIhB,UAG1BiD,EAAc,IAAIvD,IAClBwD,EAAY,IAAIxD,IACtB,IAAK,MAAMsB,IAAEA,KAASwB,EAAS,KAAAW,EAC7B,MAAMzW,EAAQyW,OAAHA,EAAGxB,EAAajY,IAAIsX,EAAIhB,cAArBmD,EAAAA,EAA8BzZ,IAAIsX,EAAIH,SAC3B,kBAArBnU,MAAAA,OAAAA,EAAAA,EAAOuV,YAAqD,MAArBvV,EAAMwV,YAC/Ce,EAAYG,IAAIzC,OAAOjU,EAAMwV,cACC,oBAAhB,MAALxV,OAAK,EAALA,EAAOuV,YAAkD,MAAhBjB,EAAIF,UACtDoC,EAAUE,IAAIpC,EAAIF,SAEtB,CACA,MAAOc,EAAWC,SAAkB/Y,QAAQC,IAAI,CAC9CgY,GAAsB,IAAIkC,IAC1B3B,GAAc,IAAI4B,MAGpB,OAAOZ,EAAUtZ,IAAI,EAAGgY,MAAKuB,SACtBvB,EACL5O,GACKmQ,CAAAA,EAAAA,GACHc,gBAAiB3B,GACfV,EACAW,EACAC,EACAC,KAPaU,EAWrB,IChFA5Z,eAAe2a,GACbza,GAEA,MAAM0a,EAAS,IAAItC,IACnB,IAAK,MAAMsB,KAAO1Z,EAAe,CAAA2a,IAAAA,EAC/B,IAAKpB,GAASG,EAAIvY,MAAO,SACzB,MAAMyZ,EAA4B,OAAvBD,EAAGD,EAAO7Z,IAAI6Y,EAAIvY,OAAKwZ,EAAI,GACtCC,EAAMtR,KAAKoQ,GACXgB,EAAOnC,IAAImB,EAAIvY,KAAMyZ,EACvB,CACA,GAAoB,IAAhBF,EAAOnM,KAAY,OAAOvO,EAE9B,MAAM6a,EAAe,IAAIzC,IAQzB,aAPMnY,QAAQC,IACZ,IAAIwa,EAAOpY,WAAWnC,IAAIL,OAAQqB,EAAM2Z,MACtC,MAAMC,QAAiBxB,GAASpY,GAAMqY,QAAQsB,GAC9C,IAAK,MAAMpB,KAAOqB,EAAUF,EAAatC,IAAImB,EAAI3b,GAAI2b,EACvD,IAGK1Z,EAAcG,IAAKuZ,IAAG,IAAAsB,EAAA,OAA6B,OAA7BA,EAAKH,EAAaha,IAAI6Y,EAAI3b,KAAGid,EAAItB,GAChE,CAEA,SAASuB,GACPT,GAEA,IAAKA,EAAiB,MAAO,GAC7B,MAAMtB,WAAEA,EAAUC,WAAEA,GAAeqB,EACnC,OAAkB,MAAdrB,EAA4B,UAASD,cACjC,UAASA,mBAA4BC,IAC/C,CCrCA,MAAA+B,GAAA,CAAA,mBAAA,WAAA,QAAA,iBAAA,WAAA,kBAAAC,GAAA,CAAA,aAAA,mBAAA,WAAA,SA6BMlT,GAAiB,IAAI1E,EAAO,CAChCC,KAAMC,EAAU,WAAY,CAAEC,UAAU,IACxCC,QAAS,eAEL/C,GAAe,IAAI2C,EAAO,CAC9BC,KAAMC,EAAU,SAAU,CAAEC,UAAU,MAoClC0X,gBAAoBtc,EAExB,MAEF,SAASuc,GAAkBC,GAAC,IAAAC,iBAC1BA,EAAgBC,SAChBA,EAAQ1L,MACRA,EAAK2L,eACLA,GAAiB,EAAK9J,SACtBA,EAAQ+J,eACRA,GAQDJ,EAPI7G,EAAKkH,GAAAL,EAAAJ,iBAQR,OACErd,EAAAC,cAAC8d,GAAiBrS,GAChBuG,CAAAA,MAAOA,EACPyL,iBAAkBA,GACd9G,gBAEJ5W,EAAAC,cAAC+d,qBACChe,EAAAC,cAACge,sBACDje,EAAAC,cAACie,IACCP,SAAUA,EACVC,eAAgBA,EAChB9J,SAAUA,EACV+J,eAAgBA,kBAGpB7d,EAAAC,cAACke,GAAa,mBACdne,EAAAC,cAACme,SAGP,CAEA,SAASC,GAAmBzH,gBAC1B,OACE5W,EAAAC,cAAC8d,IAAkBjS,WAAY8K,EAAM9K,yBACnC9L,EAAAC,cAAC+d,qBACChe,EAAAC,cAACge,GAAO,mBACRje,EAAAC,cAACqe,uBAEHte,EAAAC,cAACse,sBACDve,EAAAC,cAACue,SAGP,CAEA,SAASD,KACP,MAAMzS,WAAEA,GAAe4C,EACrB6O,IAGIkB,EAA0B3S,EAAW2S,yBACrCnb,KAAEA,EAAIX,YAAEA,GAAgB+b,GAAiB5S,EAAWnJ,aACpDgc,EAAe7S,EAAW8S,YAAepQ,EAAN,gBAEzC,OACExO,EAAAC,cAACoQ,EAAS,CACRwO,gBAAiBtO,EAAM,iBACvBT,KAAM,EACNxP,QAASqe,gBAET3e,EAAAC,cAACuQ,GACCC,MAAO,EACPC,KAAMH,EAAM,oBACZK,OAAQL,EAAM,0BACdkC,aAAclC,EAAM,oBACpBuO,UAECxb,GAAAA,gBAEHtD,EAAAC,cAACoQ,EAAUC,CAAAA,QAAS,kBAClBtQ,EAAAC,cAAC4Q,EAAI,CACHH,KAAMH,EAAM,oBACZI,MAAOJ,EAAM,kBACbuC,WAAW,OAEV2L,EACArB,GAAsBtR,EAAW6Q,iBAAiB,SAAO,IACzDoC,EAAWzb,GAAM,IAAE0b,GAAkBlT,iBAExC9L,EAAAC,cAAC4Q,GACCH,KAAMH,EAAM,oBACZI,MAAOJ,EAAM,4BACbuC,WAAW,OAEVgM,EAASG,GAAiCtc,GAAc,CACvDiH,OAAQ,IACRsV,UAAW,QAMvB,CAEA,SAASZ,KACP,MAAMxS,WAAEA,GAAe4C,EACrB6O,iBAGF,OACEvd,EAAAC,cAAC6R,EACCqN,CAAAA,YACApN,SAAU,CAAEzO,KAAM,qBAClB4O,QAAQ,QACRxB,KAAK,KACLf,GAAI7D,EAAWsT,gBACftL,UAAWhI,EAAWuT,UACtBC,QACGxT,EAAWuT,eAER7Q,EADA,0CAGNmC,MAAOJ,EAAM,4BACbgP,MAAO,CACLtM,gBAAiB,YACjBtC,MAAOJ,EAAM,8BAEhB,SAIL,CAEA,SAASwN,GAAiByB,GAUvB,IAVwB1T,WACzBA,EAAU4R,iBACVA,EAAgBvH,SAChBA,EAAQlE,MACRA,GAMDuN,EALIC,EAAI3B,GAAA0B,EAAAlC,iBAMP,OACEtd,EAAAC,cAACsd,GAAkBmC,SAAQ,CACzB9a,MAAK8G,GACHI,CAAAA,aACAmG,QACAyL,oBACG+B,iBAGLzf,EAAAC,cAAC0f,EAAKnL,CAAAA,OAAQ,EAAGlF,QAAS,GACvB6G,GAIT,CAEA,SAAS6H,IAAO7H,SAAEA,IAChB,MAAMrK,WAAEA,GAAe4C,EAAW6O,iBAIlC,OACEvd,EAAAC,cAACoQ,EAAS,CACRa,KAAK,aACLqB,UAAU,SACVjD,QAAS,EACT6B,aAAa,gBACb7Q,QARiBwL,EAAW8S,YAAepQ,EAAN,IAUpC2H,EAGP,CAEA,SAAS+H,IAAOP,SACdA,EAAQC,eACRA,GAAiB,EAAK9J,SACtBA,EAAQ+J,eACRA,IAOA,MAAM/R,WACJA,EAAU8T,uBACVA,EAAsBC,gBACtBA,EAAeC,QACfA,EAAO7N,MACPA,EAAKyL,iBACLA,GACEhP,EAAW6O,KACRwC,EAAgBC,GAAqBtT,EAASkR,GAC/CqC,EAAWnU,EAAW8S,QACtBtb,KAAEA,GAASob,GAAiB5S,EAAWnJ,0BAyF7C,OACE3C,EAAAC,cAAAD,EAAA+P,SAAA,kBACE/P,EAAAC,cAACoQ,EAAS,CAACa,KAAK,aAAaqB,UAAU,SAASjC,QAAS,kBACvDtQ,EAAAC,cAACigB,GACCnI,KAAM,CACJpH,MAAOJ,EAAM,kBACbjN,KAAM,0BAER6c,WAAW,EACXvO,MAAM,UACNM,QAAQ,QACRxB,KAAK,KACLoD,SAAUA,gBAEV9T,EAAAC,cAACigB,EAASE,MAAKC,SAAUA,KApG/BL,GAAkB,EAoGiC,GAAC,WAC7CJ,IACE9T,EAAWwU,cAAgBT,eAC1B7f,EAAAC,cAACigB,EAASE,MAAKtM,UAAU,gBACvB9T,EAAAC,cAACsgB,EAAO,CACNC,UAAU,OACVC,UAAW,IACX7O,MAAM,4DAEN5R,EAAAC,cAAC4Q,EAAI,KAAC,oCAIV7Q,EAAAC,cAACigB,EAASE,KAAKC,CAAAA,SA7E3B,WACE1M,GACGC,KAAK,CACJC,KAAM,yKACNjC,MAAO,yBAERvD,KAAK,EAAGqS,kBACHA,GACFtW,GACGmJ,KAAK,CACJzQ,KAAM,CACJiL,GAAI+R,EAAQa,SACZ7d,KAAM,CAAE0Q,WAAY,CAAG,IAEzBpQ,IAAM,6BAA4B0I,EAAW5L,mBAE9CmO,KAAK,EAAGvL,UA8YrBb,eAAwCM,GACtC,MACEO,MAAM8d,OAAEA,UACA7d,GAAaC,IAAI,CACzBF,KAAM,CACJG,OAAQ,CAAE+H,OAAQ,WAEpB5H,IAAK,OAGP,MAAO,CAAEwd,SAAQre,eACnB,CAzZgCse,CAAyB/d,IAC5CuL,KAAK,EAAG9L,eAAcqe,aACrBlD,EAAkBoD,GAAIpV,GACjBoV,GAAAA,GACHC,UAASrV,GAAOoV,GAAAA,EAAKC,UAAS,CAAEC,UAAWJ,IAC3CN,YAAa/d,EAAa+d,YAC1BW,cAAe1e,EAAa0e,gBAC5B,GAEH5d,MAAO2G,IACN,MAAM6J,EACJ9J,GAAcC,EAAO,WACrB,mFACF2J,GAAkBC,KAAK,CACrBC,OACAjC,MAAO,UAEX,EACJ,EAEN,GAyCqD,mCAI7C5R,EAAAC,cAACigB,EAASE,MAAKC,SA3CvB,WACE1M,GACGC,KAAK,CACJsN,kBAAmB,yBACnBrN,KAAO,wCAAuCvQ,wCAC9CsO,MAAO,4BAERvD,KAAK,EAAGqS,kBACHA,GAAa/C,EAAS7R,EAAW5L,GAAE,EAE7C,GAiC+C,2BAEzCF,EAAAC,cAACkhB,EAAY,CACXC,UAAWnB,EACXvP,KAAK,KACLsB,QAnHR,WACE5H,GACGiX,MAAM,CACLve,KAAM,CACJiL,GAAI+R,EAAQa,SACZ7d,KAAM,CACJ0Q,WAAY,CACVoL,QAASqB,KAIf7c,IAAM,6BAA4B0I,EAAW5L,OAE9CmO,KAAMvL,IACL4a,EAAkBoD,GAAIpV,GAAWoV,CAAAA,EAAAA,GAAMlC,OAAQ9b,EAAKA,KAAK8b,SAC3D,GACCvb,MAAO2G,IACN,MAAM6J,EACJ9J,GAAcC,EAAO,UACpB,uBACCiW,EAAW,UAAY,kEAE3BtM,GAAkBC,KAAK,CACrBC,OACAjC,MAAO,UAEX,EACJ,EAyFQ0N,QACExL,EACI+J,EACAoC,EACA,mBACA,oBAENnM,SAAUA,kBAId9T,EAAAC,cAAC+X,GACC5B,CAAAA,KAAM2J,EACN/I,eAAgBA,IAAMgJ,GAAkB,GACxC/N,MAAOA,gBAEPjS,EAAAC,cAAC4L,IACCC,WAAYA,EACZvC,gBAAiBuW,EAAQa,SACzB3U,qBA3IR,SAA4BsV,GAC1B5D,EAAkBoD,GAAIpV,GAAA,GAAWoV,EAAI,CAAEpN,aAAc4N,IACvD,EA0IQtK,eAAgBA,IAAMgJ,GAAkB,MAKlD,CAEA,SAAS/B,KACP,MAAMnS,WAAEA,GAAe4C,EAAW6O,IAC5BgE,EAAqBzV,EAAWxI,KAAKmG,MAAM,KAAK,gBAEtD,OACEzJ,EAAAC,cAACoQ,EAAS,CAACa,KAAK,aAAaqB,UAAU,SAASjC,QAAS,iBACvDtQ,EAAAC,cAACuhB,EAAI,CACHC,UAAU,EACVne,KAAMkV,GAAiB+I,GACvB7Q,KAAK,KACLuB,MAAM,uBAERjS,EAAAC,cAACyU,EAAKpR,CAAAA,KAAK,qBAAqBoN,KAAM,mBACtC1Q,EAAAC,cAACuhB,EAAI,CACHC,UAAU,EACVne,KAAMkV,GAAiB1M,EAAW4V,kBAClChR,KAAK,KACLuB,MAAM,UAId,CACA,SAASuM,SAASmD,EAAAC,EAChB,MAAM9V,WAAEA,GAAe4C,EAAW6O,KAC5Brc,WAAEA,GAAewN,EAAW1N,IAC5B6gB,SAAkBF,EAAC7V,EAAWiV,YAAXY,EAAsBzhB,GAA2B,GAAtB,oBAC9C+gB,EAAiB,GAAEnV,EAAWmV,iBAAiBY,IAE/ClD,EAAe7S,EAAW8S,YAAepQ,EAAN,gBAEzC,OACExO,EAAAC,cAAAD,EAAA+P,SACE/P,kBAAAA,EAAAC,cAAC6hB,EAAQC,CAAAA,kBAAmB,iBAC5B/hB,EAAAC,cAACoQ,GACCa,KAAK,aACLqB,UAAU,SACVpB,aAAa,gBACb+E,WAAY,KACZ5F,QAASC,EAAM,iBACfjQ,QAASqe,gBAET3e,EAAAC,cAAC4Q,EACCH,CAAAA,KAAMH,EAAM,oBACZI,MAAOJ,EAAM,8BACb+E,WAAW,UACZ,WACUzM,GAAciD,EAAWiD,UAAW7N,iBAE/ClB,EAAAC,cAACoQ,EAAS,CACRa,KAAK,aACLqB,UAAU,SACVjC,QAASC,EAAM,oBACfX,SAAS,uBAEY,OAApBgS,EAAA9V,EAAWiV,gBAAS,EAApBa,EAAsBZ,yBACrBhhB,EAAAC,cAAC+hB,GACCrhB,MAAO,EACPC,OAAQ,EACRqhB,MAAO,EACPzb,IAAKya,EACLiB,OAAQpW,EAAWiV,UAAUC,yBAGjChhB,EAAAC,cAAC4Q,EAAKH,CAAAA,KAAM,EAAGoO,UACZmC,GAAAA,KAMb,CAEA,SAAS7C,KAAiB+D,IAAAA,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EACxB,MAAMxhB,WAAEA,GAAewN,EAAW1N,KAC5B8K,WAAEA,EAAUgU,QAAEA,EAAO7N,MAAEA,EAAKyL,iBAAEA,GAAqBhP,EACvD6O,IAGIsE,EAAuC,OAArBM,EAACrW,EAAWiV,YAAXoB,EAAsBjiB,GAA2B,GAAtB,oBAC9C+gB,EAAiB,GAAEnV,EAAWmV,iBAAiBY,IAE/ClD,EAAe7S,EAAW8S,YAAepQ,EAAN,GACnCmU,EAAc,CAClBhS,MAAOJ,EAAM,4BACboC,SAAUpC,EAAM,oBAChBe,WAAYf,EAAM,0BAClBqS,kBAAmBrS,EAAM,iBACzBiE,OAAQ,OACR9D,KAAM,KACNwB,QAAS,UAEJ2Q,EAAcC,GAAmBpW,EAAS,CAC/C5E,OAAQ,KACRiY,gBAAgB,iBAiBlB,OACE/f,EAAAC,cAAAD,EAAA+P,2BACE/P,EAAAC,cAAC6hB,GAAQC,kBAAmB,iBAC5B/hB,EAAAC,cAACoQ,EAAS,CACRa,KAAK,aACLqB,UAAU,SACVpB,aAAa,gBACb+E,WAAY,KACZ5F,QAASC,EAAM,iBACfjQ,QAASqe,gBAET3e,EAAAC,cAAC4Q,GACCH,KAAMH,EAAM,oBACZI,MAAOJ,EAAM,8BACb+E,WAAW,UACZ,WACUzM,GAAciD,EAAWiD,UAAW7N,iBAG/ClB,EAAAC,cAACoQ,EACCa,CAAAA,KAAK,aACLqB,UAAU,SACVjC,QAASC,EAAM,gCAEb6R,EAACtW,EAAW4H,gBAAX0O,EAAyB1X,uBAC1B1K,EAAAC,cAAC6R,EAAMpG,MACDiX,EAAW,CACf,aAAa,GAAE7W,EAAW4H,aAAahJ,kBACvCsH,QA1CZ,WACE8Q,EAAgB,CAAEhb,OAAQ,UAAWiY,gBAAgB,GACvD,EAyCYT,QAAU,UAAA+C,EAAEvW,EAAW4H,aAAahJ,gBAAxB2X,EAAiCU,iDAE7C/iB,EAAAC,cAAC8Q,EACCkC,CAAAA,gBAAiB1C,EAAM,iCACvByS,YAAazS,EAAM,oBACnBiE,OAAO,SACP5T,OAAO,OACPD,MAAM,OACN2O,QAASiB,EAAM,oCAEfvQ,EAAAC,cAACyU,EAAI,CACHpR,KAAM,iBACNoN,KAAM,MACNkB,MAAO,UACPjB,MAAM,WAGR,GAAiC,OAAjC2R,EAAExW,EAAW4H,aAAahJ,cAAO,EAA/B4X,EAAiCS,6BAGvCR,EAACzW,EAAW4H,gBAAX6O,EAAyBhY,sBAC1BvK,EAAAC,cAAC6R,EAAMpG,MACDiX,EAAW,CACf,aAAa,GAAE7W,EAAW4H,aAAanJ,gBACvCwH,SAAU,CACRpB,MAAOJ,EAAM,+BACbyS,YAAazS,EAAM,oBACnBjN,KAAM,8BACNoN,KAAM,OACNkB,MAAO,UAETI,QAtEZ,WACE8Q,EAAgB,CAAEhb,OAAQ,oBAAqBiY,gBAAgB,GACjE,EAqEYnO,MAAQ,GAAE4Q,OAAFA,EAAE1W,EAAW4H,aAAanJ,aAAxBiY,EAAAA,EAAgCO,mBAC1CzD,QAAU,GAAgC,OAAhCmD,EAAE3W,EAAW4H,aAAanJ,aAAM,EAA9BkY,EAAgCM,kDAIlD/iB,EAAAC,cAACoQ,GACCa,KAAK,aACLqB,UAAU,SACVpB,aAAa,MACbrB,KAAM,EACNQ,QAASC,EAAM,oBACfoE,WAAW,SAEU,OAApB+N,EAAA5W,EAAWiV,gBAAS,EAApB2B,EAAsB1B,yBACrBhhB,EAAAC,cAAC+hB,EACCrhB,CAAAA,MAAO4P,EAAM,uBACb3P,OAAQ2P,EAAM,uBACd0R,MAAO1R,EAAM,uBACb/J,IAAKya,EACLiB,OAAQpW,EAAWiV,UAAUC,yBAGjChhB,EAAAC,cAAC4Q,EAAKH,CAAAA,KAAMH,EAAM,oBAAqBuO,UACpCmC,GAAAA,kBAKPjhB,EAAAC,cAAC+X,IACC5B,KAAMyM,EAAa9C,eACnB/I,eAAgBA,IACd8L,EAAgB,CAAEhb,OAAQ,KAAMiY,gBAAgB,IAElD9N,MAAOA,gBAEPjS,EAAAC,cAAC4L,GAAO,CACNC,WAAYA,EACZvC,gBAAiBuW,EAAQa,SACzB5U,YAAa8W,EAAa/a,OAC1BkE,qBA1GR,SACEsV,GAEA5D,EAAkBoD,GAAIpV,MAAWoV,EAAI,CAAEpN,aAAc4N,IACvD,EAuGQtK,eAAgBA,IACd8L,EAAgB,CAAEhb,OAAQ,KAAMiY,gBAAgB,OAM5D,CAEA,SAAS5B,KACP,MAAMrS,WAAEA,EAAUgU,QAAEA,GAAYpR,EAC9B6O,KAGIja,KAAEA,EAAIX,YAAEA,GAAgB+b,GAAiB5S,EAAWnJ,aACpDgc,EAAe7S,EAAW8S,YAAepQ,EAAN,GAEnCiQ,EAA0B,CAC9B,gBACAM,EAAWe,EAAQlU,MAAMjJ,aACvBya,GAAsBtR,EAAW6Q,iBACjC,IACF,OACAoC,EAAWzb,GACX0b,GAAkBlT,IAClB5G,KAAK,kBAEP,OACElF,EAAAC,cAACoQ,EACCwO,CAAAA,gBAAiBtO,EAAM,iBACvBT,KAAM,EACNxP,QAASqe,gBAET3e,EAAAC,cAACuQ,EACCC,CAAAA,MAAO,EACPC,KAAMH,EAAM,oBACZK,OAAQL,EAAM,wBACdkC,aAAclC,EAAM,oBACpBuO,aAECxb,gBAEHtD,EAAAC,cAACoQ,GAAUC,QAAS,kBAClBtQ,EAAAC,cAAC4Q,EACCH,CAAAA,KAAMH,EAAM,oBACZI,MAAOJ,EAAM,kBACbuC,WAAW,OAEV2L,gBAEHze,EAAAC,cAAC4Q,EAAI,CACHH,KAAMH,EAAM,oBACZI,MAAOJ,EAAM,4BACbuC,WAAW,OAEVgM,EAASG,GAAiCtc,GAAc,CACvDiH,OAAQ,IACRsV,UAAW,QAMvB,CAEA,SAASF,GAAkBlT,GAAgC,IAAAmX,EACzD,OAAiB,MAAVnX,GAAyB,OAAfmX,EAAVnX,EAAYoX,gBAAZD,EAA2BE,yBAC9B,gCACA,EACN,CAEA,SAASzE,GAAiB/b,GACxB,MAAMmB,EAAQ,uBAAuB6V,KAAKhX,GAE1C,OAAImB,EACK,CAAEnB,YAAamB,EAAM,GAAMR,KAAMQ,EAAM,GAAKsf,QAE5C,CAAE9f,KAAMX,EAEnB,CAEA,SAASsc,GAAiCtc,GACxC,aAAIA,GAAAA,EAAa0gB,WAAW,cACnB1gB,EAAYgB,QAAQ,aAAc,cAElChB,CAEX,CC1sBA,MAAMyH,GAAiB,IAAI1E,EAAO,CAChCC,KAAMC,EAAU,WAAY,CAAEC,UAAU,IACxCC,QAAS,eAEL/C,GAAe,IAAI2C,EAAO,CAC9BC,KAAMC,EAAU,SAAU,CAAEC,UAAU,MAoBxC5D,eAAeqhB,GAAqBnhB,GAClC,MAAM0I,EAAY0Y,EAChBlH,EAAKla,EAAcG,IAAKC,GAAiBA,EAAa+d,eAGxD,IACE,MAAQxd,KAAM0gB,SAAmBzgB,GAAaC,IAAI,CAChDF,KAAM,CACJG,OAAQ,CAAE+H,OAAQ,UAClB7H,MAAO,CAAEjD,GAAI2K,EAAU3F,KAAK,OAE9B9B,IAAK,WAEP,MAAO,CAAEogB,WAAUrhB,gBACrB,CAAE,MAAO6H,GACP,MAAO,CAAEwZ,SAAU,GAAIrhB,gBACzB,CACF,CAEA,SAASshB,IAA8BD,SACrCA,EAAQrhB,cACRA,IAeA,OAViCA,EAAcG,IAAKC,IAClD,MAAMqe,EAAS4C,EAAS1e,KACrB4e,GAAYA,EAAQxjB,KAAOqC,EAAa+d,aAE3C,OAAA5U,GAAA,GACKnJ,EACHwe,CAAAA,UAASrV,GAAA,CAAA,EAAOnJ,EAAawe,WAAWC,UAAWJ,MAAAA,OAAAA,EAAAA,EAAQA,YAKjE,CCtCA,MAAMxW,GAAiB,IAAI1E,EAAO,CAChCC,KAAMC,EAAU,WAAY,CAAEC,UAAU,IACxCC,QAAS,eAoBX7D,eAAe0hB,GAAsBC,GAInC,MAAMC,EAA4B,CAChC9Y,OAAQ,CAAC,QAAS,SAClB+Y,cAAe,CAAC,UAChBC,SAAU,CAAC,UAEPC,EAAgB,CAAC,UAEjBC,EAAqBL,EAAYxY,OAAO,CAAC8Y,EAAapY,KAE1D,MAAMqY,EAA4BrY,EAAWvC,gBAAgB5F,QAC3D,SACA,UAEI+F,QAAEA,EAAOI,aAAEA,EAAYD,aAAEA,EAAYF,WAAEA,GAC3CL,GAAqB6a,GAavB,OAXKD,EAAYxa,KAAUwa,EAAYxa,GAAW,IAC7Cwa,EAAYxa,GAASI,KACxBoa,EAAYxa,GAASI,GAAgB,CAAA,GAClCoa,EAAYxa,GAASI,GAA2B,cACnDoa,EAAYxa,GAASI,GAA4B,aAAID,GAElDqa,EAAYxa,GAASI,GAAmB,MAC3Coa,EAAYxa,GAASI,GAAmB,IAAI,IAE9Coa,EAAYxa,GAASI,GAAmB,IAAE2B,KAAK9B,GAExCua,GACN,IAEGE,EAAW5f,OAAO+C,KAAK0c,GAAoBI,QAAS3a,GAGjDlF,OAAOC,QAFoBwf,EAAmBva,IAEJ2a,QAC/C,EAAEva,EAAcwa,MAAmBC,IAAAA,EAOjC,OANgBP,EAAcxhB,SAASkH,GACnC8a,GACkC,OAAlCD,EAAAV,EAA0Bna,KAA1B6a,EAAoC/hB,SAASsH,GAC7C2a,GACAC,IAEW,CACbhb,UACA4Q,IAAKgK,EAAmB,IACxBza,aAAcya,EAA4B,aAC1Cxa,gBACD,IAOP,MAAO,CACL8Z,cACAe,kBAI8BC,QARVxiB,QAAQyiB,WAAWT,GASlCQ,EACJxZ,OAAO,CAAC0Z,EAAKzZ,KACU,cAAlBA,EAAOlB,SAAwB2a,EAAMA,EAAIC,OAAO1Z,EAAOzG,QAEpDkgB,GACN,IACFT,QAAS9jB,GAAMA,EAAEuC,QAPtB,IAAkC8hB,CAFlC,CAYA,SAASH,IAAe/a,QAAEA,EAAOG,aAAEA,EAAYC,aAAEA,EAAYwQ,IAAEA,IAC7D,OAAO0K,GAAkB,CACvBtb,UACA2C,OAAQ,CACNlJ,MAAO,CAAEjD,GAAIoa,EAAIpV,KAAK,OAExB+f,KAAMpb,EACNC,gBAEJ,CAEA,SAAS4a,IAAgBhb,QAAEA,EAAOG,aAAEA,EAAYC,aAAEA,EAAYwQ,IAAEA,IAC9D,OAAOA,EAAIhY,IAAKpC,GACd8kB,GAAkB,CAChBtb,UACAub,KAAO,GAAEpb,KAAgB3J,IACzB4J,iBAGN,CAEA,SAAS0a,GAAaU,GACpB,OAAW,IAAA9iB,QAAQ,CAACoK,EAAG2Y,KACrBA,GACF,EACF,CAuEA,SAASH,IAAkBtb,QACzBA,EAAOub,KACPA,EAAInb,aACJA,EAAYuC,OACZA,EAAS,CACX,IACE,MAAM+Y,EAAS,IAAI1f,EAAO,CAAEC,KAAMC,EAAU8D,EAAS,CAAE7D,UAAU,MAC3Dwf,EAAQC,EAAWjc,GAAYS,IAErC,OAAOsb,EAAOpiB,IAAI,CAChBF,KAAI4I,GAAA,CACFzI,OAAQ,CACNoiB,CAACA,GAAQ,CAAC,OAAQ,yBAEjBhZ,GAELjJ,IAAK6hB,GAET,CAuCA,SAASM,IAAoBC,eAC3BA,EAAc1F,QACdA,IAKA,MAAO5T,EAASS,GAAcD,GAAS,IAChCkX,EAAa6B,GAAkB/Y,IAEtCoB,EAAU,MD1NZ7L,iBACE,OAAOc,GACJC,IAAI,CACHF,KAAM,CACJG,OAAQ,CAAEyiB,IAAK,CAAC,QAASC,UAAW,CAAC,MAAO,oBAC5CzhB,QAAS,CAAC,QAEZd,IAAM,oBAEPiL,KAAK,EAAGvL,UACAA,EACJgF,OAAQ8d,GAAyBA,EAAUC,eAC3CvjB,IAAKsjB,GAAyBA,EAAUE,IAAIxiB,KAAKyiB,eAE1D,EC6MIC,GAAkB3X,KAAM4X,KA9P5BhkB,eAAwCujB,GACtC,MAAM1iB,KAAEA,SAAesH,GAAepH,IAAI,CACxCF,KAAM,CACJiL,GAAIyX,EACJviB,OAAQ,CACNijB,uBACE,4MACFlb,OAAQ,QAEV9G,QAAS,cAEXd,IAAK,sCAGP,OAAON,CACT,EAgPMqjB,CAAyBX,GACtBnX,KAAKiV,IACLjV,KAAKoV,IACLpV,KAAKnM,IACLmM,KAAKuO,IACLvO,KAAKsV,IACLtV,KAAK,EAAGuV,cAAae,sBAvD9B,UAA+Cf,YAC7CA,EAAWe,iBACXA,EAAgBsB,cAChBA,IAEA,OAAOrC,EAAYthB,IAAKwJ,IACtB,MAAMpC,QAAEA,EAAOI,aAAEA,EAAYH,WAAEA,GAAeL,GAC5CwC,EAAWvC,iBAGb,GAAgB,WAAZG,EAIF,OAHAoC,EAAW2S,wBApEjB,SAAgC3S,GAG9B,OAFeA,EAAWxI,KAAKK,QAAQ,oBAAqB,KAG1D,IAAK,8BACH,MAAO,sBACT,IAAK,mCACH,MAAO,yCACT,IAAK,sCACH,MAAO,6CACT,QACE,OACJ,KACF,CAuD2CyiB,CAAuBta,GAC5DA,EAAWuT,UAAY4G,EAAcnhB,KAAMghB,GAAgB,WAARA,GAE5Cha,EAIT,MAAMT,EAASsZ,EAAiB7f,KAC7BuhB,GAAOA,EAAGnmB,GAAGmI,YAAcsB,EAAWtB,YAGnCie,EAAejb,EACjBA,EAAO/H,MAAQ+H,EAAOkb,kBACrB,WAAUjB,EAAWjc,GAAYS,OAStC,OAPAgC,EAAW2S,wBApEf,SAA0B3S,EAAY0a,GACpC,MAAMC,EA9CR,SAAuBC,GAIrB,OAF0BA,EAAY/iB,QAAQ,aAAc,KAG1D,IAAK,4BACH,MAAO,QACT,IAAK,8BACH,MAAO,SACT,IAAK,6BACL,IAAK,+BACH,MAAO,cACT,IAAK,+BACL,IAAK,iCACH,MAAO,kBACT,IAAK,iCACH,MAAO,UACT,IAAK,iCACH,MAAO,sCACT,IAAK,mCACH,MAAO,iCACT,IAAK,qCACH,MAAO,wDACT,IAAK,uCACH,MAAO,6DACT,QACE,YAEN,CAkBegjB,CAAc7a,EAAWxI,OAEhCwG,aAAEA,GAAiBR,GAAqBwC,EAAWvC,iBAEzD,IAAKkd,EAAM,CAET,MAAMH,EAAexH,EAAS0H,EAAqB,CACjD5c,OAAQ,IACRsV,UAAW,MAGb,MAAQ,yCAAwC7V,GAC9CS,OACIwc,IACR,CAEA,MAAQ,iBAAgBG,KAAQpd,GAC9BS,OACI0c,IACR,CAgDyCI,CACnC9a,EACAwa,GAGFxa,EAAWuT,YAAchU,EAElBS,GAEX,CAqBU+a,CAAsC,CACpCjD,cACAqC,gBACAtB,sBAGHtW,KAAKoX,GACLpX,KAAK,IAAM1B,GAAW,GAAM,EAEnC,EAAG,CAAC6Y,IAEJ,MAAMsB,GAAa5a,GAAkC,IAAvB0X,EAAYha,oBAE1C,OACE5J,EAAAC,cAAAD,EAAA+P,SACE/P,kBAAAA,EAAAC,cAAC8Q,EACCgW,CAAAA,aAAe,aAAYxW,EAAM,sBACjCkC,aAAclC,EAAM,iBACpBwR,kBAAmB,EACnBvP,UAAWsN,EAAU,GAAK,EAC1B8C,kBAAmBrS,EAAM,iBACzBsO,gBAAiBtO,EAAM,+BAEvBvQ,EAAAC,cAACuQ,EAAO,CACNG,MAAOJ,EAAM,2BACbE,MAAO,EACPC,KAAMH,EAAM,qBAEXrE,EACG,uBACAhD,GAAU0a,EAAYha,OAAQ,yBAGrCkd,eACC9mB,EAAAC,cAAC4Q,EACCF,CAAAA,MAAOJ,EAAM,4BACbkH,eAAgBlH,EAAM,kBACvB,0EAGCrE,eACFlM,EAAAC,cAAC+mB,EACCC,CAAAA,mBAAOjnB,EAAAC,cAACinB,GAAQxW,KAAK,OACrBmO,gBAAiB,GACjBjN,MAAO,iDAGT5R,EAAAC,cAACknB,EAAQ,CACP7W,QAASC,EAAM,iBACfkH,eAAgBlH,EAAM,iBACtB6W,aAAc,IAEbxD,EAAYthB,IAAKwJ,gBAChB9L,EAAAC,cAACoe,GAAmB7X,CAAAA,IAAKsF,EAAW5L,GAAI4L,WAAYA,MAMhE,CC7VA,SAASub,GAAsBC,GAC7B,MAAQ,aAAYA,EAAGjhB,kBAAkBihB,EAAGzjB,sBAAwB,IACtE,CAEA,SAAS0jB,GAAUC,GACjB,MAAQ,WAAUA,GACpB,CAcA,SAASC,GACPhM,GAEA,OAAOA,EAAQnZ,IAAI,EAAGmG,QAAO7D,wBAC3B5E,EAAAC,cAACuR,EAAOK,OAAM,CAACrL,IAAK5B,EAAOA,MAAOA,GAC/B6D,GAGP,CAEA,SAASif,GACPjM,GAEA,MAAMkM,EAAiBC,GAAQnM,EAAS,SAExC,OADmBjX,OAAO+C,KAAKogB,GAAgBE,OAC7BvlB,IAAKwlB,GACd,SAAPA,EACEL,GAAqCE,EAAeG,iBAEpD9nB,EAAAC,cAACuR,EAAOuW,aAAYvhB,IAAKshB,EAAIlW,MAAOkW,GACjCL,GAAqCE,EAAeG,KAI7D,CAEA,MAAME,GAAaA,EACjBC,oBACAC,8BACAC,2BAMA,MAAMC,EAAmC,MAAjBH,OAAiB,EAAjBA,EAAmBT,QAErCa,EAAoCF,EAAqB7lB,IAAKglB,GAAE5b,MACjE4b,EAAE,CACLpnB,GAAImnB,GAAsBC,MAGtBgB,EAAoBD,EAAkCvgB,OACzDwf,GAAsB,OAAfA,EAAGE,SAGPe,EAAwBC,GAAOL,EAAsB,WACxDrgB,OAAQwf,KAASA,EAAGE,SACpBllB,IAAKglB,IAAQ,CACZvK,MAAOuK,EAAGmB,aACVhgB,MAAO6e,EAAGE,QACV5iB,MAAO2iB,GAAUD,EAAGE,YAGlBkB,EAAsBN,EACxBC,EAAkCvgB,OAC/Bwf,GAAOA,EAAGE,UAAYY,GAEzB,GAEJ,SAASO,GAAsBhX,cAAEA,IAC/B,OAzEJ,SAAgB/M,GACd,GAAIA,EAAMye,WAAW,WACnB,MAAO,UACEze,GAAAA,EAAMye,WAAW,aAC1B,MAAO,YACE,GAACze,EAGV,MAAU,IAAAkC,MAAO,qBAAoBlC,KAFrC,OAAO,IAIX,CA+DYgkB,CAAOjX,IACb,IAAK,UACHuW,EACEC,EAAqBrjB,KAClBwiB,GAAOC,GAAUD,EAAGE,WAAa7V,IAGtC,MACF,IAAK,YACHuW,EACEC,EAAqBrjB,KAClBwiB,GAAOD,GAAsBC,KAAQ3V,IAG1C,MACF,UACEuW,EAA4B,MAGlC,CAEA,SAASW,EAAiBC,GAOxB,OAAOpB,GANqBoB,EAAWxmB,IAAK8F,IAAC,CAC3C2U,MAAO3U,EAAE2U,MACTtU,MAAOL,EAAEzF,YACTiC,MAAOwD,EAAElI,MAIb,cAEA,OACEF,EAAAC,cAACoQ,EAAS,CAACC,QAASC,EAAM,+BACxBvQ,EAAAC,cAACuR,EACCC,CAAAA,WAAW,mBACXvR,GAAG,gBACHwR,SAAUiX,EACVjY,KAAK,KACL,cAAY,oBAEXmY,EAAiBP,GACjBZ,GAAca,IAEhBG,EAAoB9e,OAAS,gBAC5B5J,EAAAC,cAACuR,GACCuX,aAAcL,EAAoB,GAAGxoB,GACrCwR,SAAUiX,EACVjY,KAAK,MAEJmY,EAAiBH,IAGb,ECrETM,GAAQA,EACZC,kBACAjjB,QACA0L,WACA9M,QACAuC,uBACA+hB,mBACAtiB,cACAuiB,mBAWA,MAAMC,EAjCR,SAA2BC,GACzB,MAAOC,EAAgBC,GAAqB7c,EAAS2c,GAUrD,OARAvb,EAAU,KACR,MAAM0b,EAAYH,IAEbI,GAAQD,EAAWF,IACtBC,EAAkBC,EACpB,EACC,CAACH,EAAWC,IAERA,CACT,CAqBuBI,CAAkB,IAjDzC,UAA2B1jB,MACzBA,EAAKmB,qBACLA,IAMA,OADkBnB,EAAM2jB,WAAa,IACpBve,OAAO,CAAC0Z,EAAK8E,KACxBplB,OAAOiC,UAAUH,eAAeI,KAAKS,EAAsByiB,KAC7D9E,EAAI+E,GAAUD,IAAWziB,EAAqByiB,IAEzC9E,GACN,CAAA,EACL,CAoCIgF,CAAkB,CAAE9jB,QAAOmB,0BAS7B,GANA2G,EAAU,KACJ9H,EAAMC,WACRijB,EAAiB,CAAEE,eAAcpjB,SACnC,EACC,CAACA,EAAOojB,EAAcF,IAEN,WAAfljB,EAAME,KAAmB,OAAW,KAExC,MAAM6jB,EACJ/jB,EAAMa,MAAQD,EAAYb,GAAoBC,KAAW,GAErDgkB,EAAuBD,EAAYjiB,OACtCmiB,IAAQA,EAAGC,sBAGRhe,EAAUlG,EAAMC,WAAakjB,EAAapjB,GAAoBC,iBAwEpE,OACEhG,EAAAC,cAACoQ,EAAUoC,CAAAA,aAAc,EAAGnC,QAAS,iBACnCtQ,EAAAC,cAACmR,EAAMC,WAAU,CACfV,MAAOJ,EAAM,2BACboC,SAAUpC,EAAM,oBAChBe,WAAYf,EAAM,0BAClBgB,SAAUvL,EAAM9F,IAEf8F,EAAMrD,YACNqD,EAAMmkB,mBACLnqB,EAAAC,cAACmqB,EAAaC,OAAOC,CAAAA,SAAW,GAAEtkB,EAAM9F,UAAWyU,WAAY,kBAGnE3U,EAAAC,cAAC8Q,EAAK7E,KAAAA,eAAUlM,EAAAC,cAACsqB,SAnFrB,WACE,OAAQvkB,EAAME,MACZ,IAAK,sBACH,OACElG,EAAAC,cAACuR,GAAM,CACL2I,QAASnU,EAAM9F,GACf6pB,YAAaC,EACbtY,SAAUA,EACV9M,MAAOA,EACPjC,YAAaqD,EAAMrD,YACnBmR,SAAU9N,EAAM8N,WAGtB,IAAK,4BACH,OACE9T,EAAAC,cAACuqB,GAAY,CACXrQ,QAASnU,EAAM9F,GACf6pB,YAAaC,EACbtY,SAAUA,EACV9M,MAAOA,IAGb,IAAK,wBACH,OAAO5E,EAAAC,cAACwqB,GAASzkB,CAAAA,MAAOA,EAAOpB,MAAOA,EAAO8M,SAAUA,IACzD,IAAK,wBACH,OAAO1R,EAAAC,cAACyqB,GAAQ,CAAC1kB,MAAOA,EAAO0L,SAAUA,EAAU9M,MAAOA,IAE5D,IAAK,yBACH,OAAO5E,EAAAC,cAAC0qB,GAAU3kB,CAAAA,MAAOA,EAAO0L,SAAUA,EAAU9M,MAAOA,IAC7D,IAAK,0BACH,OACE5E,EAAAC,cAAC2qB,GAAU,CACTzQ,QAASnU,EAAM9F,GACfub,QAASuO,EACTtY,SAAUA,IAGhB,IAAK,2BACH,OAAO1R,EAAAC,cAAC4qB,IAAY7kB,MAAOA,EAAO0L,SAAUA,EAAU9M,MAAOA,IAC/D,IAAK,4BACH,OACE5E,EAAAC,cAAC6qB,GACC7B,CAAAA,gBAAiBA,EACjBjjB,MAAOA,EACP0L,SAAUA,EACVqY,YAAaA,EACbgB,UAAW5B,EAAapjB,GAAoBC,IAC5CkjB,iBAAkBA,EAClBtkB,MAAOA,IAGb,IAAK,yBACH,OAAO5E,EAAAC,cAAC+qB,GAAUhlB,CAAAA,MAAOA,EAAO0L,SAAUA,EAAU9M,MAAOA,IAC7D,IAAK,4BACH,OACE5E,EAAAC,cAACgrB,GAAY,CACXjlB,MAAOA,EACPyV,QAASsO,EACTrY,SAAUA,EACV9M,MAAOA,IAGb,IAAK,0BACH,OAAO5E,EAAAC,cAAC4Q,EAAKqa,CAAAA,wBAAyB,CAAEC,OAAQnlB,EAAMolB,WACxD,QAEE,OADAC,QAAQC,KAAM,uBAAsBtlB,EAAME,SACnC,KAEb,CAekCqlB,IAC7BvlB,EAAMmkB,mBACLnqB,EAAAC,cAACmqB,EAAY,CACXlqB,GAAK,GAAE8F,EAAM9F,UACbsS,UAAWjC,EAAM,kCAEjBvQ,EAAAC,cAAC8Q,EAAIma,CAAAA,wBAAyB,CAAEC,OAAQnlB,EAAMmkB,SAGzC,EAIT3Y,GAASA,EACb2I,UACA4P,cACArY,WACA9M,QACAjC,cACAmR,eASA,MAAM0X,EAAsBzB,MAAAA,OAAAA,EAAAA,EAAajlB,KACtC2mB,GAA4B,cAAjBA,EAAO7mB,OAEf+iB,EAAiBC,GAAQmC,EAAa,SACtC2B,EAAalnB,OAAO+C,KAAKogB,GAAgBE,OACzCH,EAAgBA,IACbgE,EAAWppB,IAAKwlB,GACd,SAAPA,GAAwB,cAAPA,EACfL,EAAqCE,EAAeG,iBAEpD9nB,EAAAC,cAAC0rB,EAAe5D,YAAYvhB,CAAAA,IAAKshB,EAAIlW,MAAOkW,GACzCL,EAAqCE,EAAeG,MAMvDL,EACJmE,GAEOA,EAAMtpB,IAAKupB,gBAChB7rB,EAAAC,cAAC0rB,EAAe9Z,QACdrL,IAAKqlB,EAAKjnB,MACVA,MAAOinB,EAAKjnB,MAAMyD,WAClByL,SAAU+X,EAAK/X,UAEd+X,EAAKlpB,2BA6BZ,OACE3C,EAAAC,cAAC0rB,EAAc,CACbzrB,GAAIia,EACJzI,SA3B8Boa,EAAGna,oBACnCD,EAAS,CAAEyI,UAASvV,MAAO+M,GAC7B,EA0BImC,SAAU4T,IAAgB9d,OAAS,KAAOkK,EAC1CrC,WAZ6B,IAA3BiW,IAAgB9d,OAAqB,wBAEpB,MAAnB4hB,OAAmB,EAAnBA,EAAqB7oB,cAfDyG,KACtB,IAAI2iB,EAAU,UAQd,OAPK3iB,EAEM,CAAC,IAAK,IAAK,IAAK,IAAK,KAAK5G,SAAS4G,EAAK7D,OAAO,IACxDwmB,GAAW,MAAK3iB,IAEhB2iB,GAAW,KAAI3iB,IAJf2iB,GAAU,UAMLA,GAOLC,CAA0B,MAAXrpB,OAAW,EAAXA,EAAaojB,eAU5BrV,KAAK,KACL9L,MAAOA,IAAS4mB,MAAAA,OAAAA,EAAAA,EAAqB5mB,QAAS,KAC9C4b,UAAU,gBAETkH,IACa,EAId8C,GAAeA,EACnBrQ,UACA4P,cACArY,WACA9M,YAOA,MAAMqnB,EAA6BlC,EAAYjlB,KAC5C2mB,IAAMS,IAAAA,SAAKA,OAAAA,EAAAT,EAAO7mB,YAAPsnB,EAAAA,EAAc7jB,cAAezD,IAErCunB,GAA8B,MAAdF,OAAc,EAAdA,EAAgBtpB,cAAe,IAC9CypB,EAAmBC,GAAwB3f,EAAS,KACpD4f,EAAOC,GAAY7f,EAASyf,IAC5BK,EAAqBC,GAA0B/f,GAAS,IACxDggB,EAAiBC,GAAsBjgB,GAAS,GAEnDyf,IAAkBC,IACpBC,EAAqBF,GACrBI,EAASJ,GACTM,GAAuB,IAGzB,IAAIG,EAAkBC,GAAOrE,GAAOuB,EAAa,SAAU,SAE3D,GAAIyC,EAAqB,CACvB,MAAMM,EAAiBR,EAAMvG,cAC7B6G,EAAkBA,EAAgB9kB,OAAQ2jB,GACpB,GAAEA,EAAO9oB,eAAe8oB,EAAO1O,QAAQgJ,cACzCvjB,SAASsqB,GAE/B,cAMA,OACE9sB,EAAAC,cAAC8sB,EAAiBC,QAChBC,CAAAA,eACAC,EAAAA,YAAa,CAAEnV,KAAM,CAAErH,KAAM,OAC7BrB,IAAK,CACH,oBAAqB,CACnB8d,OAAQpD,EAAYngB,OAAS,EAAI,UAAY,gBAGjDujB,OAAO,UACPrZ,SAAiC,IAAvBiW,EAAYngB,OACtBwjB,OAAQA,KACNT,GAAmB,GACnBJ,EAASJ,EACX,EACAza,SAAWhJ,IACT6jB,EAAS7jB,EAAE2kB,OAAOzoB,OAClB6nB,GAAuB,GACvBE,GAAmB,EACrB,EACAW,QACEZ,EACI,KACEH,EAAS,IACTE,GAAuB,EAAK,OAE9Bje,EAEN+e,QAAU7kB,GAA2CA,EAAE2kB,OAAOG,SAC9DnN,SAAWoL,IAjCY7mB,KACzB8M,EAAS,CAAEyI,UAASvV,SACtB,EAgCM6oB,CAAkBhC,EAAO7mB,OACzB2nB,EAASd,EAAO9oB,aAChB8pB,GAAuB,GACvBE,GAAmB,EAAK,EAE1Be,aAAW,EACXpZ,YAAa,IACbqZ,YACE5D,EAAYngB,OAAS,EAAI,mBAAqB,uBAEhD4W,UAAU,eACVoN,aAAc,CACZC,YAAa,WAEfpZ,wBAAYzU,EAAAC,cAACyU,EAAI,CAACpR,KAAK,iBAAiBoN,KAAK,OAC7Cod,yBAAa9tB,EAAAC,cAACyU,EAAI,CAACpR,KAAK,sBACxBoN,KAAK,KACL9L,MAAO0nB,GAENvC,EAAYngB,OAAS,gBACpB5J,EAAAC,cAAAD,EAAA+P,SACG6c,KAAAA,EAAgBhjB,OAAS,EACxBgjB,EAAgBtqB,IAAI,CAACmpB,EAAoBsC,KACvC,MAAMC,EAAYvC,EAAO7mB,MAAMyD,aAAezD,eAC9C,OACE5E,EAAAC,cAAC8sB,EAAiB3M,KAAI,CACpB,aAAYqL,EAAO9oB,YACnBmR,SAAU2X,EAAO3X,SACjBia,MAAOA,EACPvnB,IAAKilB,EAAO7mB,MACZ0P,YAAa,KACbG,wBACEzU,EAAAC,cAACyU,EACCC,CAAAA,YAAa,GACbrR,KAAM0qB,EAAY,gBAAkB,GACpCtd,KAAK,OAGTud,KAAK,SACL3d,QAASC,EAAM,iBACf3L,MAAO,CACLjC,YAAa8oB,EAAO9oB,YACpBiC,MAAO6mB,EAAO7mB,MAAMyD,0BAGtBrI,EAAAC,cAAC4Q,EAAI,CAACiO,UAAQ,gBACZ9e,EAAAC,cAACiuB,EAAS,CAACra,KAAM4X,EAAO9oB,YAAa2pB,MAAOA,KAE7Cb,EAAO1O,oBACN/c,EAAAC,cAACkU,EAAK,CACJvC,mBAAO5R,EAAAC,cAACiuB,EAAS,CAACra,KAAM4X,EAAO1O,MAAOuP,MAAOA,IAC7C5b,KAAK,KACLiE,WAAW,SAGM,gBAI3B3U,EAAAC,cAACkuB,EAAK/N,KACJpgB,kBAAAA,EAAAC,cAAC4Q,EAAK,KAAA,mBAAsByb,EAAM,OAKlB,EAIxBxB,GAAeA,EACnB7B,kBACAjjB,QACA+kB,YACAhB,cACAb,mBACAxX,WACA9M,YASIwpB,IAAAA,EACJ,MAAMC,EAAkBzgB,EACrB0e,IACCpD,EAAiB,CAAEE,aAAc,CAAEkD,SAAStmB,SAC9C,EACA,CAACkjB,IAGGoF,EAAkBC,EACtB,IAAMC,GAASH,EAAiB,KAChC,CAACA,IAGGI,EAAS7gB,EACZ0e,IACMrD,IAEMqD,EAAMlJ,OAAOxZ,OAAS,EAC/B0kB,EAAgBhC,GAEhBgC,EAAgBI,SAClB,EAEF,CAACJ,IAGGK,EAAqBJ,EACzB,KAAA,CAAS5rB,YAAa,SAAUiC,MAAO,SACvC,IAUIqnB,EARiBsC,EAAQ,IACxBtF,EAGIc,EAFA,CAAC4E,GAIT,CAACA,EAAQ5E,IAE0BjlB,KAAM2mB,GAAWA,EAAO7mB,QAAUA,GAClEunB,GAAgBF,MAAAA,OAAAA,EAAAA,EAAgBtpB,cAAe,IAC9C2pB,EAAOsC,GAAaliB,EAASyf,IAC7BO,EAAiBC,GAAsBjgB,GAAS,GAEvD,SAAS6f,EAAS3nB,GAChBgqB,EAAUhqB,GACV6pB,EAAO7pB,GACqB,IAAxBA,EAAMwe,OAAOxZ,QACf6jB,EAAkB,KAEtB,CAEA,MAAMA,EAAqB7oB,IACzB8M,EAAS,CAAEyI,QAASnU,EAAM9F,GAAI0E,SAChC,eAEA,OACE5E,EAAAC,cAAC8sB,EAAiBC,QAAO,CACvBC,eAAa,EACbC,YAAa,CAAEnV,KAAM,CAAErH,KAAM,OAC7Byc,OAAO,UACPC,OAAQA,KACNT,GAAmB,GACnBJ,EAASJ,EAAa,EAExBza,SAAWhJ,IACT6jB,EAAS7jB,EAAE2kB,OAAOzoB,OAClB+nB,GAAmB,EAAI,EAEzBW,QACEZ,EACI,KACEH,EAAS,GACX,OACA/d,EAEN+e,QAAU7kB,GAA0CA,EAAE2kB,OAAOG,SAC7DnN,SAAWoL,IACTgC,EAAkBhC,EAAO7mB,OACzB2nB,EAASd,EAAO9oB,aAChBgqB,GAAmB,EACrB,EACAe,aACApZ,EAAAA,YAAa,IACbqZ,YAAY,SACZnN,UAAU,eACVoN,aAAc,CACZC,YAAa,WAEfpZ,WACEwX,UAAcmC,EAAInC,EAAenf,OAAfshB,EAAqBxN,oBACrC5gB,EAAAC,cAAC+hB,EAAM,CAACtR,KAAK,KAAKwR,OAAQ+J,EAAenf,KAAK8T,sBAE9C5gB,EAAAC,cAACyU,GAAKpR,KAAK,iBAAiBoN,KAAK,OAGrCod,yBAAa9tB,EAAAC,cAACyU,EAAI,CAACpR,KAAK,sBACxBoN,KAAK,KACL9L,MAAO0nB,GAENrD,EACCqD,EAAMlJ,OAAOxZ,OAAS,EACpBmgB,EAAYngB,OAAS,EACnBmgB,EAAYznB,IAAI,CAACmpB,EAAQsC,iBAErB/tB,EAAAC,cAAC8sB,EAAiB3M,KAChB,CAAA,aAAYqL,EAAO9oB,YACnBorB,MAAOA,EACPvnB,IAAKilB,EAAO7mB,MACZ0P,YAAa,KACbG,wBACEzU,EAAAC,cAAC+hB,EACCrN,CAAAA,YAAa,GACbuN,OAAQuJ,EAAO3e,KAAK8T,OACpBlQ,KAAK,OAGTud,KAAK,SACL3d,QAASC,EAAM,iBACf3L,MAAO6mB,gBAEPzrB,EAAAC,cAAC4Q,EAAKiO,CAAAA,UACJ9e,gBAAAA,EAAAC,cAACiuB,EAAUra,CAAAA,KAAM4X,EAAO9oB,YAAa2pB,MAAOA,oBAMpDtsB,EAAAC,cAAC8sB,EAAiB3M,KAChBpgB,kBAAAA,EAAAC,cAAC4Q,EAAK,KAFNka,EAEM,aAIA,4BAIV/qB,EAAAC,cAAC8sB,EAAiB3M,KAAI,kBACpBpgB,EAAAC,cAAC4Q,EAAI,KAAC,gCAIV7Q,EAAAC,cAAC8sB,EAAiB3M,KAAKxb,CAAAA,MAAO+pB,EAAQZ,MAAO,EAAGE,KAAK,uBACnDjuB,EAAAC,cAAC4Q,EAAI,KAAE8d,EAAOhsB,cAGM,EAIxB8nB,GAAWA,EACfzkB,QACApB,QACA8M,2BAYE1R,EAAAC,cAAC4uB,EAAgB,CACf/a,SAAU9N,EAAM8N,SAChBrL,MAAOzC,EAAMyC,MACbqmB,QAASlqB,IAAS,EAClB8M,SAV8BhJ,IAEhCgJ,EAAS,CAAEyI,QAASnU,EAAM9F,GAAI0E,MADhB8D,EAAE2kB,OAAOyB,SACc,IAanCpE,GAAWA,EACf1kB,QACApB,QACA8M,2BAWE1R,EAAAC,cAAC8Q,EACC/Q,kBAAAA,EAAAC,cAAC8uB,EACCnqB,CAAAA,MAAOA,EACP+oB,YAAa3nB,EAAM2nB,YACnBjc,SAToBhJ,IAExBgJ,EAAS,CAAEyI,QAASnU,EAAM9F,GAAI0E,MADlB8D,EAAE2kB,OAAOzoB,OAEvB,EAOM8L,KAAK,QAMPia,GAAYA,EAChB3kB,QACApB,QACA8M,eAKIsd,IAAAA,EACJ,MAAM9tB,WAAEA,GAAewN,EAAW1N,KAC3BiuB,EAAcC,GAAmBxiB,GAAS,GAC3CyiB,EAAcnpB,EAAMopB,aAAe,sBACnCC,EAAkB,6BAClBC,EAA0BpuB,EV7Q7ByC,QAAQ,KAAM,KACdA,QAAQ,KAAM,KACdA,QAAQ,KAAM,KACdA,QAAQ,KAAM,OU2QV4rB,EAAgBC,GAAqB9iB,EAAS1D,GAAOpE,GAAO6qB,UAC7DC,EAAmDV,OAA9BA,EAAGhpB,EAAM0pB,wBAAqBV,eAoBzD,OACEhvB,EAAAC,cAACoQ,EAAUa,CAAAA,KAAK,2BACdlR,EAAAC,cAAC0rB,EAAc,CACbja,SArBqBie,EAAGhe,oBACxBA,IAAkBwd,GAAexd,IAAkB0d,GACrDH,GAAgB,GAChBxd,EAAS,CAAEyI,QAASnU,EAAM9F,GAAI0E,MAAO+M,KACV,kBAAlBA,GACTD,EAAS,CAAEyI,QAASnU,EAAM9F,GAAI0E,MAAO,OACrCsqB,GAAgB,KAEhBA,GAAgB,GAChBxd,EAAS,CAAEyI,QAASnU,EAAM9F,GAAI0E,MAAO,OACvC,EAYI8L,KAAK,KACL8P,UAAU,6BAEVxgB,EAAAC,cAAC0rB,EAAe9Z,OAAOjN,CAAAA,MAAOuqB,GAC3BA,IAEDnpB,EAAMopB,0BACNpvB,EAAAC,cAAC0rB,EAAe9Z,OAAM,CAACjN,MAAOyqB,GAC3BA,gBAGLrvB,EAAAC,cAAC0rB,EAAe9Z,OAAOjN,CAAAA,MAAM,iBAAgB,mBAG5C8qB,gBACC1vB,EAAAC,cAAC0rB,EAAe9Z,OAAOjN,CAAAA,MAAM,cAAa,eAK7CqqB,gBACCjvB,EAAAC,cAAC8Q,EAAG,kBACF/Q,EAAAC,cAAC2vB,EACCC,CAAAA,aACAC,EAAAA,YAAaR,EACb3a,WAAY,EACZjD,SAnCkB5I,IAC1B4I,EAAS,CAAEyI,QAASnU,EAAM9F,GAAI0E,MAAOiE,GAAcC,EAAM5H,KACzDsuB,EAAkB1mB,EACpB,EAiCU4H,KAAK,KACL9L,MAAO2qB,KAIJ,EAIT3E,GAAaA,EACjBzQ,UACAsB,UACA/J,eAMA,MAAOqe,EAAgBC,GAAqBtjB,EAAS,CAAA,gBASrD,OACE1M,EAAAC,cAACoQ,EAAUC,CAAAA,QAAS,GACjBmL,EAAQnZ,IAAKupB,gBACZ7rB,EAAAC,cAAC8Q,EAAG,CAACvK,IAAKqlB,EAAKjnB,oBACb5E,EAAAC,cAACmR,EAAMC,WAAU,CAACE,SAAW,cAAa4I,KAAW0R,EAAKjnB,SACvDinB,EAAKlpB,aAAekpB,EAAKjnB,oBAE5B5E,EAAAC,cAAC0rB,EAAc,CACbzrB,GAAK,cAAaia,KAAW0R,EAAKjnB,QAClC8M,SAAUA,EAAGC,mBAhBQse,EAACte,EAAe/M,KAC7C,MAAMsrB,EAAiBxkB,GAAQqkB,CAAAA,EAAAA,GAC/BG,EAAkBtrB,GAAS+M,EAC3Bqe,EAAkBE,GAClBxe,EAAS,CAAEyI,UAASvV,MAAOsrB,GAC7B,EAYYD,CAAuBte,EAAeka,EAAKjnB,OAE7C8L,KAAK,KACLe,WAAY,6BAEZzR,EAAAC,cAAC0rB,EAAe9Z,OAAM,CAACjN,MAAM,SAAQ,sBACrC5E,EAAAC,cAAC0rB,EAAe9Z,OAAM,CAACjN,MAAM,WAAU,cAMpC,EAITimB,GAAcA,EAClB7kB,QACA0L,WACA9M,YAMA,MAAMurB,EAAenqB,EAAMoqB,UAAY,EAAIpqB,EAAMoqB,SAAW,EACtDC,EACJrqB,EAAMsqB,UAAY,GAAKtqB,EAAMsqB,UAAY,IAAMtqB,EAAMsqB,SAAW,KAE3DC,EAAYC,GAAiB9jB,EAAS+jB,OAAOzqB,EAAM+iB,eAAiB,GAM3E,OAJAjb,EAAU,KACR4D,EAAS,CAAEyI,QAASnU,EAAM9F,GAAI0E,MAAOoB,EAAM+iB,cAAgB,GAAG,EAC7D,CAAC/iB,iBAGFhG,EAAAC,cAACoQ,EAAS,kBACRrQ,EAAAC,cAACmR,EAAMsf,SAAQ,kBACb1wB,EAAAC,cAAC0wB,EACCjf,CAAAA,SAAW9M,IACT,MAAMgsB,EAAiBH,OAAO7rB,IAAU,EACxC4rB,EAAcI,GAEdlf,EAAS,CACPyI,QAASnU,EAAM9F,GACf0E,MAAO0I,KAAKujB,IACVvjB,KAAKwjB,IAAIF,EAAgBT,GACzBE,IAEH,EAEH1C,YAAa3nB,EAAM2nB,YACnBjd,KAAK,KACL9L,MAAOA,EACPisB,IAAKV,EACLW,IAAKT,EACLU,aAAa,KAGhBR,EAAaF,gBACZrwB,EAAAC,cAACsX,EACCC,CAAAA,KAAK,QACLoL,kBAAmBrS,EAAM,iBACzBsO,gBAAiBtO,EAAM,oBACvBygB,QAAQ,eACRxe,UAAW,kBAEXxS,EAAAC,cAACoQ,EAAUa,CAAAA,KAAK,aAAaqB,UAAU,SAASjC,QAAS,kBACvDtQ,EAAAC,cAACyU,EAAI,CACHpR,KAAK,8BACLoN,KAAK,KACLC,MAAM,0BAER3Q,EAAAC,cAAC4Q,EAAI,CAACH,KAAMH,EAAM,qBAAqB,uBAChB8f,EAAa,OAKjC,EAITrF,GAAYA,EAChBhlB,QACApB,QACA8M,2BAWE1R,EAAAC,cAAC8Q,EACC/Q,kBAAAA,EAAAC,cAACmR,EACCV,CAAAA,KAAK,KACL9L,MAAY,MAALA,EAAAA,EAAS,GAChB1E,GAAI8F,EAAM9F,GACVytB,YAAa3nB,EAAM2nB,YACnBjc,SAXoBhJ,IAExBgJ,EAAS,CAAEyI,QAASnU,EAAM9F,GAAI0E,MADlB8D,EAAE2kB,OAAOzoB,OAEvB,KAcIqmB,GAAeA,EACnBjlB,QACAyV,UACA/J,WACA9M,YAOA,MAAMqsB,EAAuBvoB,IAC3BgJ,EAAS,CAAEyI,QAASnU,EAAM9F,GAAI0E,MAAO8D,EAAE2kB,OAAOzoB,OAAO,eAGvD,OACE5E,EAAAC,cAACoQ,EAAS,CAACmC,UAAW,EAAGlC,QAAS,IAC/BmL,EAAQnZ,IAAKmpB,gBACZzrB,EAAAC,cAACixB,EACCpC,CAAAA,QAASlqB,IAAU6mB,EAAO7mB,MAC1B4B,IAAKilB,EAAO7mB,MACZ6D,MAAOgjB,EAAO9oB,aAAe8oB,EAAO7mB,MACpC8M,SAAUuf,EACVvgB,KAAK,KACL9L,MAAO6mB,EAAO7mB,SAGT,EAIT2lB,GAAUA,iBACdvqB,EAAAC,cAACoQ,EACCa,CAAAA,KAAK,aACLqB,UAAU,SACVjC,QAASC,EAAM,iBACfqS,kBAAmB,KACnB/D,gBAAiBtO,EAAM,iBACvBiE,OAAQjE,EAAM,wBACdyD,OAAS,aAAYzD,EAAM,oCAE3BvQ,EAAAC,cAACinB,EAAO,CAACxW,KAAK,oBACd1Q,EAAAC,cAAC4Q,EAAK8B,CAAAA,SAAUpC,EAAM,oBAAqBuC,WAAY,MAAM,YCl3B3Dqe,GAASA,EACblI,kBACAphB,mBACA6J,WACAvK,uBACA+hB,mBACAtiB,cACAuiB,mBAEArb,EAAU,KACR,MAAMsjB,EAAgBvpB,EAAiBuD,OAAO,CAAC0Z,EAAK9e,KAC9CxB,OAAOiC,UAAUH,eAAeI,KAAKV,EAAO,gBAC9C8e,EAAI9e,EAAM9F,IAAM8F,EAAM+iB,aACE,cAAf/iB,EAAME,OACf4e,EAAI9e,EAAM9F,IAAM8F,EAAMopB,aAAe,wBAGhCtK,GACN,CAAA,GACHpT,EAAS0f,EAAa,EACrB,CAACvpB,EAAkB6J,IAEtB,MAAM2f,EAAmBzpB,GACvBC,EACAV,GAGImqB,EAAmCA,EAAGnX,UAASvV,YACnD,MAAMwsB,EAAa1lB,GAAA,CAAA,EAAQvE,GACrBoqB,EAAa1pB,EAAiBC,OAAQ9B,GAAUA,EAAM2jB,WAC5D4H,EAAWjvB,IAAKkvB,IACd,GAAIA,EAAU7H,UAAUnnB,SAAS2X,GAAU,CACzC,MAAMsX,EAASF,EAAWzsB,KAAMvE,GAC9BA,EAAEopB,UAAUnnB,SAASgvB,EAAUtxB,KAE7BuxB,UACKL,EAAcK,EAAOvxB,WAEvBkxB,EAAcI,EAAUtxB,SAGFsO,IAA3BgjB,EAAUzI,mBACsBva,IAAhC4iB,EAAcI,EAAUtxB,MAExBkxB,EAAcI,EAAUtxB,IAAMsxB,EAAUzI,aAE5C,IAGY,cAAVnkB,SACKwsB,EAAcjX,GAErBiX,EAAcjX,GAAWvV,EAG3B8M,EAAQhG,GAAM0lB,CAAAA,EAAAA,KAGhB,OAAIvpB,EAAiB+B,oBAEjB5J,EAAAC,cAAA,MAAA,KACGoxB,EAAiB/uB,IAAK0D,gBAEnBhG,EAAAC,cAAC+oB,GACCC,CAAAA,gBAAiBA,EACjBjjB,MAAOA,EACPQ,IAAKR,EAAM9F,GACXwR,SAAU4f,EACV1sB,MAAOuC,EAAqBnB,EAAM9F,IAClCiH,qBAAsBA,EACtB+hB,iBAAkBA,EAClBtiB,YAAaA,EACbuiB,aAAcA,MAOjB,IACT,ECnEI/D,GAAS,IAAI1f,EAAO,CACxBC,KAAMC,EAAU,SAAU,CAAEC,UAAU,IACtCC,QAAS,WAELsE,GAAiB,IAAI1E,EAAO,CAChCC,KAAMC,EAAU,WAAY,CAAEC,UAAU,IACxCC,QAAS,WAEL4rB,GAAkB,CACtBriB,IAAK,CAAEsiB,aAAcphB,EAAM,yBAC3BqS,kBAAmB,KACnB/D,gBAAiB,KACjBrH,KAAM,SAURvV,eAAe2vB,KACb,OAAOxM,GACJpiB,IAAoB,CACnBF,KAAM,CACJG,OAAQ,CAAE4uB,OAAQ,SAEpBzuB,IAAK,eAENiL,KAAK,EAAGvL,UAAWA,EAAKgvB,KAAKxvB,IAAKyvB,GAAMA,EAAEzuB,MAC/C,CAEArB,eAAe+vB,KACb,OAAO5nB,GACJpH,IAA6D,CAC5DF,KAAM,CAAEG,OAAQ,CAAEgvB,aAAc,SAChC7uB,IAAK,oBAENiL,KAAK,EAAGvL,UAAWA,EAAKR,IAAKyvB,GAAMA,EAAEzuB,MAC1C,CAcArB,eAAeiwB,GAAwBpM,GACrC,OAAO1b,GACJpH,IAAI,CACHF,KAAM,CACJG,OAAQ,CACNkvB,oBACE,mHAEJrqB,OAAQ,qBACR0S,MAAM,GAERpX,IAAM,mBAAkB0iB,4BAEzBzX,KAAK,EAAGvL,UAAWA,EACxB,CA4CA,MAAMsvB,GAAgBA,EACpBC,qBACAC,iBACAC,UAAAA,GAAY,EACZC,aACA7vB,cACAqU,iBACA8I,cASI,IAAA2S,EAAAC,EAAAC,EACJ,MAAOC,EAAsBC,GAA2BnmB,EACtDoT,EAAQlV,OAAO,KAEVkoB,EAA0BC,GAC/BrmB,EAA+B,CAAE,IAC5BsmB,EAAaC,GAAkBvmB,EAAS8lB,IACxCvM,EAAeiN,GAAoBxmB,EAExC,KACKyb,EAAsBgL,GAA2BzmB,EAEtD,KACK0mB,EAA6BC,GAClC3mB,GAAS,IACJ1E,EAAoBsrB,GACzB5mB,KACKvF,EAAsBosB,GAC3B7mB,EAA+B,CAAA,IAC1B9F,EAAa4sB,GAAkB9mB,EACpC,CAAA,IAEKyc,EAAcsK,GAAmB/mB,EAAmC,CAAA,IACpEgnB,EAAYC,GAAiBjnB,GAAS,IACtC1C,EAAOyC,GAAYC,EAIvB,CAAA,IACIknB,GAAiBC,IAAsBnnB,GAAS,IAChDwW,GAAe4Q,IAAoBpnB,EACxC,CAAA,GAEIqnB,GAAeC,EAAO,MAEtB/K,GAAkBsF,EACtB,IAAMtI,EAAc3jB,IAAKyvB,GAAMA,EAAE7xB,IAAIsC,SAAS,UAC9C,CAACyjB,IAGGpiB,GAAuBmE,MAAAA,OAAAA,EAAAA,EAAoBnE,qBAC3CowB,GACwC,kBAA5CjsB,UAAkByqB,EAAlBzqB,EAAoBksB,sBAApBzB,EAAmCvsB,MAE/BgjB,GAAmBtb,EACvB,EAAG5H,QAAOojB,mBACRqK,EAAiB3S,GAAIpV,GAAA,GAChBoV,EACH,CAAA,CAAC/a,GAAoBC,KAAS,KA1GtC/D,gBAA8B6jB,IAC5BA,EAAG9f,MACHA,EAAKnC,qBACLA,EAAoBulB,aACpBA,IAOA,GAAmB,iBAAfpjB,EAAME,KAAyB,CACjC,MAAQpD,KAAMiI,SAAiBqa,GAAOpiB,IAEnC,CACDF,KAAM,CACJG,OAAQ,CAAE+H,OAAQ,eAClB7H,MAAO,CAAEgxB,qBAAsB/K,EAAakD,MAAOniB,OAAQ,WAE7D/G,IAAK,YAGP,OAAO2H,EAAOzI,IAAKkJ,KACjB7I,YAAa6I,EAAElI,KACfwJ,KAAM,CAAE8T,OAAQpV,EAAEoV,QAClBhc,MAAO4G,EAAEtL,GAAGmI,aAEhB,CAAO,CACL,MAAMvF,KAAEA,SAAesH,GAAepH,IAAI,CACxCF,KAAI4I,GACC0d,CAAAA,EAAAA,GACHvlB,uBACAZ,OAAQ,CACNmxB,wBAAyB,YAG7BhxB,IAAM,mBAAkB0iB,gCAAkC9f,EAAMC,cAElE,OAAOnD,EAAKsB,MACd,CACF,CAoEMiwB,CAAe,CACbvO,IAAKkN,EACLnvB,wBACAulB,eACApjB,UAECqI,KAAMimB,IACLd,EAAgB1S,GAAIpV,GACfoV,GAAAA,GACH,CAAC/a,GAAoBC,IAASsuB,KAEhCb,EAAiB3S,GAAIpV,GAChBoV,CAAAA,EAAAA,GACH,CAAC/a,GAAoBC,KAAS,OAGjC3C,MAAO2G,GAAUyC,EAAS,CAAE8nB,oBAAqBvqB,IACtD,EACA,CAACgpB,EAAanvB,KAwBhBiK,EAAU,KACRrB,EAAS,CAAA,GAnLbxK,iBACE,MAAOuyB,EAAaC,SAAsBryB,QAAQC,IAAI,CACpDuvB,KACAI,OAGF,OAAOwC,EACJ1sB,OAAQge,GAAQ2O,EAAajyB,SAASsjB,IACtC+B,OACAvlB,IAAKwjB,IAAiB,CAAE5lB,GAAI4lB,EAAIC,cAAeziB,KAAMwiB,IAC1D,CA0KI4O,GAAmBrmB,KAAMyjB,IACvBoB,EAAiBpB,GACjB,MAAM6C,EAAmB7C,EAAKhtB,KAAMghB,GAAQA,EAAI5lB,KAAOsyB,GACnDA,EACAV,EAAK,GAAG5xB,GACZ+yB,EAAe0B,GACfzC,GAAwByC,GACrBtmB,KAAMumB,IACAb,GAAac,UAChB1B,EAAwByB,GACxBvB,GAA+B,GACjC,GAEDhwB,MAAO2G,GAAUyC,EAAS,CAAEmoB,YAAa5qB,MAC7C,EACA,CAACwoB,IAEJ1kB,EAAU,KACRrB,EAAS,CAAE,EAAA,EACV,CAACtF,IAEJ,MAAM2tB,GACJ,sBAAuBlC,EACnBA,EAAqBkC,kBACrBhV,EAAQgV,kBACRzb,GZrDD,UAAgC0b,eACrCA,EAAcD,kBACdA,EAAiBhC,yBACjBA,IAMA,MAAMzZ,EAAoB2b,EAAUD,GAC9B9xB,EAAS6xB,MAAAA,EAAAA,EAAqB,GAC9BG,EAAiBhyB,EAAO6E,OAAQ9B,IAChCA,EAAMkvB,YACHjuB,GAAuBjB,EAAO/C,EAAQ6vB,IAG/C,IAAK,MAAM9sB,KAASivB,EAEhBzwB,OAAOiC,UAAUH,eAAeI,KAAKosB,EAA0B9sB,EAAM9F,KAErEwa,EAAIrB,EAAmBrT,EAAM9F,GAAI4yB,EAAyB9sB,EAAM9F,KAIpE,OAAOmZ,CACT,CY4B4B8b,CAAuB,CAC/CJ,eACE,eAAgBnC,EACZA,EAAqBwC,WACrBtV,EAAQsV,WACdN,qBACAhC,6BAWF,SAASuC,KACP,MAAMC,YZ3HuBttB,mBAC/BA,EAAkBb,qBAClBA,EAAoBP,YACpBA,IAMA,MAAO,CACLjE,YAAaoF,GAAuB,CAClCnB,YAAaA,GAAe,CAAE,EAC9BoB,qBACAb,yBAEF7D,MAU0B8C,EAVC4B,EAWtB7B,GAAyBC,IAAeA,EAAWzD,cAD5D,IAA8ByD,CAR9B,CY0G6BwgB,CAAiB,CACxChgB,cACAoB,qBACAb,yBAGF,IAAIxE,EAAc2yB,EAAiBhyB,KAMnC,OAJIgyB,EAAiB3yB,cACnBA,GAAgB,KAAI2yB,EAAiB3yB,gBAGhCA,CACT,CAiDA,SAAS4yB,GAAazyB,GACpB6wB,GAAc,GACdvpB,GACGmJ,KAAK,CACJzQ,OACAM,IAAK,iCAENiL,KAAK,WACAgkB,GAAAA,EAAoBmD,WAAa5B,IACnC5c,IACAqb,EAAmBmD,UAAS9pB,GAAA,CAAA,EAAM5I,KAElCmU,OAAOwe,SAASC,QAClB,GAEDryB,MAAO2G,IACN2pB,GAAc,GACV3pB,EAAME,OACRuC,EAAS,CAAEX,WAAY9B,EAAME,SAE7ByrB,MAAM,iCACR,EAEN,cAEA,OACE31B,EAAAC,cAACoQ,GAAU6F,WAAY,EAAG5F,QAAS,GAChC3N,gBACC3C,EAAAC,cAAC8Q,EACC/Q,kBAAAA,EAAAC,cAAC4Q,EACC8G,CAAAA,MAAO,CACLhH,MAAOJ,EAAM,kBACboC,SAAUpC,EAAM,oBAChBuC,WAAY,KACZL,aAAclC,EAAM,mBAGrB5N,EAAa,iBACd3C,EAAAC,cAACyP,EAAKyP,CAAAA,YAASxP,GAAI2iB,GAAgB,gBAMxCtoB,EAAM8B,yBACL9L,EAAAC,cAACsX,EAAUma,gBACT1xB,EAAAC,cAAC4Q,OAAK,sJAMV7Q,EAAAC,cAACoQ,EAAUC,CAAAA,QAAS,gBAClBtQ,EAAAC,cAACmR,EAAMC,WACLV,CAAAA,MAAOJ,EAAM,kBACbgB,SAAS,uBACToB,SAAUpC,EAAM,oBAChBe,WAAYf,EAAM,2BACnB,iCAGDvQ,EAAAC,cAACuR,EAAM,CACLtR,GAAG,uBACHwR,SAAUA,EAAGC,mBAhLnBA,KAEAkhB,EAAwBlhB,GACxBohB,EAA4B,CAAE,EAAA,EA8KtB6C,CAAyBjkB,GAE3BjB,KAAK,KACL9L,MAAOguB,GAEN9S,EAAQlV,OAAOtI,IAAI,CAACuzB,EAAcC,iBACjC91B,EAAAC,cAACuR,EAAOK,QACNrL,IAAM,GAAEqvB,EAAavyB,QAAQwyB,IAC7BlxB,MAAOixB,GAENA,EAAalzB,sBAKnBmyB,UAAAA,GAAmBlrB,QAAS,gBAC3B5J,EAAAC,cAACkxB,IACClI,gBAAiBA,GACjBphB,iBAAkBitB,GAClB3tB,qBAAsB2rB,EACtBphB,SAAUqhB,EACVnsB,YAAa,CAAG,EAChBuiB,aAAc,CAAA,EACdD,iBAAkBA,IAAM,qBAK9BlpB,EAAAC,cAACoQ,EAAS,CAACC,QAAS,GACjB2V,EAAcrc,OAAS,eACtB5J,EAAAC,cAAC81B,IACC/C,YAAaA,EACb/M,cAAeA,EACf+P,qBAjOuBlQ,IAC/BmN,EAAenN,GACfuN,GAA+B,GAC/BF,EAAwB,IACxBY,GAAac,QAAU/O,EACvBwN,EAAsB,MACtBC,EAAwB,IACxB9mB,EAAS,CAAA,GACTylB,GAAwBpM,GACrBzX,KAAK8kB,GACL9kB,KAAK,IAAMglB,GAA+B,IAC1ChwB,MAAO2G,GAAUyC,EAAS,CAAEmoB,YAAa5qB,qBAyNtChK,EAAAC,cAACoQ,EAAS,CAACC,QAAS,gBAClBtQ,EAAAC,cAAC4Q,GACCF,MAAOJ,EAAM,2BACboC,SAAUpC,EAAM,oBAChBe,WAAYf,EAAM,2BACnB,6CAGDvQ,EAAAC,cAACoQ,GACCa,KAAK,aACLqB,UAAU,SACVjC,QAASC,EAAM,iBACfqS,kBAAmB,KACnB/D,gBAAiBtO,EAAM,iBACvBiE,OAAQ,EACRR,OAAS,aAAYzD,EAAM,oCAE3BvQ,EAAAC,cAACinB,GAAQxW,KAAK,oBACd1Q,EAAAC,cAAC4Q,GAAK8B,SAAUpC,EAAM,oBAAqBuC,WAAY,MAAM,aAMlE9I,EAAM4qB,yBACL50B,EAAAC,cAACsX,EAAK7L,GAAC8G,CAAAA,UAAWjC,EAAM,kBAAsBmhB,iBAC5C1xB,EAAAC,cAAC4Q,EAAK,KAAA,gGAKNuiB,eACFpzB,EAAAC,cAACg2B,GAA6B,mBAE9Bj2B,EAAAC,cAAC+nB,IACCC,kBAAmBjgB,EACnBmgB,qBAAsBA,EACtBD,4BA/MRgO,IAEA5C,EAAsB4C,GACtBzpB,EAAS,CAAE,GACX8mB,EAAwB,GAC1B,KA+MKvrB,IACEgC,EAAMuqB,iCACLv0B,EAAAC,cAACsX,EAAUma,gBACT1xB,EAAAC,cAAC4Q,EAAI,KAAC,oHAMR7Q,EAAAC,cAAAD,EAAA+P,SAAA,kBACE/P,EAAAC,cAACkxB,GAAM,CACLlI,gBAAiBA,GACjBphB,iBAAkBG,EAAmBH,kBAAoB,GACzD6J,SAAU6hB,EACVpsB,qBAAsBA,EACtBP,YAAaA,EACbsiB,iBAAkBA,GAClBC,aAAcA,WAEfkJ,SAAAA,EAAoB5pB,qBACnBzI,EAAAC,cAACwqB,EACC3W,CAAAA,SACE4f,GACAyC,GAAcnuB,EAAoBb,GAEpCsB,MAAO4pB,EAAmB5pB,MAC1BqmB,QAAS8E,GACTliB,SAAUA,IAAMmiB,IAAoBD,YAGvChB,UAAoBF,EAApBE,EAAsB1P,sBAAtBwP,EAAqCpwB,IAAI,CAAC8zB,EAAON,iBAChD91B,EAAAC,cAACwqB,GACCjkB,IAAM,GAAE4vB,EAAM5vB,OAAOsvB,IACrBrtB,MAAO2tB,EAAMzzB,YACbmsB,QACG5L,IAAiBA,GAAckT,EAAM5vB,MACtC4vB,EAAMrN,aAERrX,SAAWhJ,IACTorB,GAAkBhT,GAAIpV,MACjBoV,EAAI,CACP,CAAE,GAAEsV,EAAM5vB,OAAQkC,EAAE2kB,OAAOyB,UAE/B,KAGHmF,iBACCj0B,EAAAC,cAACsX,EAAUma,gBACT1xB,EAAAC,cAACoQ,EAAUa,CAAAA,KAAK,aAAaZ,QAAS,kBACpCtQ,EAAAC,cAACyU,GACChE,KAAMH,EAAM,uBACZjN,KAAK,8BACLqN,MAAOJ,EAAM,8CAEfvQ,EAAAC,cAAC4Q,EAAI,CACHqa,wBAAyB,CACvBC,OAAQwH,OAAFA,EAAE3qB,EAAmBksB,oBAAnBvB,EAAAA,EAAkC0D,YASzD9D,gBACCvyB,EAAAC,yBACG8G,KAAKC,UACJ,CACErE,YAAaqF,GAAsBqtB,KACnCzuB,cACAoB,qBACAb,uBACAkS,sBAEF,KACA,iBAKNrZ,EAAAC,cAACoQ,EACCkC,CAAAA,UAAU,SACVrB,KAAK,aACLolB,UAAY,aAAY/lB,EAAM,sBAC9BY,aAAa,MACbqB,UAAW,EACXuP,kBAAmB,EACnBa,kBAAmB,EACnB1M,WAAY,EACZ5F,QAAS,gBAETtQ,EAAAC,cAAC6R,EACCnB,CAAAA,MAAOJ,EAAM,2BAEb,sBACAe,WAAYf,EAAM,0BAClByB,QAASgF,EACTtG,KAAK,KACLkB,MAAM,SACNM,QAAQ,uBAEVlS,EAAAC,cAAC6R,EAAM,CACLgC,SACE4f,GACAO,IACAkC,GACEnuB,EACAb,EACA2tB,GACAhC,GAGJ9gB,QA9SR,WACE,GAAI0hB,EACF,OAEF,MAAM6C,EAAgB7qB,MAAQvE,GAE1Ba,EAAmBnE,uBACrB0yB,EAAiBC,sBACfxuB,EAAmBnE,sBAGvB,MAAMf,EAAO,CACXiL,GAAI+R,EAAQa,SACZ7d,KAAM,CACJ0Q,WAAY,CACV7Q,YAAa0yB,KACb/xB,KAAMsvB,EAAqBtvB,KAC3BmzB,mBAAoBzD,EACpB0D,gCAAiC1uB,EAAmB3B,gBACpDkwB,mBACAI,mBAAoBtd,GACpBud,eAAgB1T,IAElB1L,KAAM,2BAGNoc,GACFjgB,GACGC,KAAK,CACJijB,iBAAkB,SAClB3V,kBAAmB,sBACnBrN,KAAM,iFACNjC,MAAQ,GAAEygB,EAAmB5pB,WAE9B4F,KAAMhD,IACDA,EAAOzG,MACT2wB,GAAazyB,IAEb6wB,GAAc,GACdE,IAAmB,GACrB,GAGJ0B,GAAazyB,EAEjB,EAkQQ4N,KAAK,KACLuB,MAAM,UACNL,MAAOklB,GAAc9uB,EAAoBb,GACzC+K,QAAQ,OACR,cAAY,uBAGP,EAIf,SAASikB,GACPnuB,EACAb,EACA2tB,EACAhC,GAEA,IAAK9qB,EAAoB,OAAO,EAEhC,MAAM+uB,EAAkBnvB,GACtBI,EAAmBH,iBACnBV,GAEF,OACG4vB,EACEjvB,OAAQ9B,GAAUA,EAAMgxB,UACxBC,MAAOjxB,GAAUkxB,GAAclxB,EAAOmB,MAIxC4vB,EACEjvB,OAAQ9B,GAAUmxB,GAAcnxB,IAChCixB,MAAOjxB,GAAUkxB,GAAclxB,EAAOmB,MAIrBS,SACpBktB,EAAAA,EAAqB,SACrBhC,EAAAA,EAA4B,IAIzBhrB,OAAQ9B,GAAUA,EAAMgxB,UACxBC,MAAOjxB,GAAUkxB,GAAclxB,EAA+B,MAAxB8sB,EAAAA,EAA4B,IAKzE,CAEA,SAASqE,GAAcnxB,GACrB,MAAsB,WAAfA,EAAME,MAAoC,iBAAfF,EAAME,IAC1C,CAEA,SAASgxB,GACPlxB,EACAmB,GAEA,OAAIgwB,GAAcnxB,GACTmB,EAAqBb,eAAeN,EAAM9F,IAG/CiH,EAAqBb,eAAeN,EAAM9F,KAC1CiH,EAAqBnB,EAAM9F,KAC0B,KAArDiH,EAAqBnB,EAAM9F,IAAImI,WAAW+a,MAGhD,CAmBA,SAAS0T,GACP9uB,EACAb,GAEA,MAAMiwB,EArBR,SACEpvB,EACAb,GAEA,SAAKa,IAAAA,EAAoBH,iBAAkB,OAE3C,MAAMwvB,EAAiBzvB,GACrBI,EAAmBH,iBACnBV,GAGF,IAAK,MAAMnB,KAASqxB,EAClB,GAAIrxB,EAAMgxB,WAAaE,GAAclxB,EAAOmB,GAC1C,OAAOnB,EAAMrD,WAEnB,CAMkC20B,CAC9BtvB,EACAb,GAGF,OAAKa,EAEMovB,EACD,WACNA,EAAwB7xB,OAAO,GAAGzB,MAAM,YAAc,IAAM,MAC1DszB,EAAwBrR,gBAErB,oBANA,kBAQX,CAEA,MAAMgQ,GAAcA,EAClBC,uBACA/P,gBACA+M,8BAWEhzB,EAAAC,cAACoQ,EAAUC,CAAAA,QAAS,gBAClBtQ,EAAAC,cAACmR,EAAMC,WACLV,CAAAA,MAAOJ,EAAM,2BACbgB,SAAS,iBACToB,SAAUpC,EAAM,oBAChBe,WAAYf,EAAM,2BACnB,6CAGDvQ,EAAAC,cAACuR,EAAM,CACL+lB,WACAr3B,EAAAA,GAAG,iBACHwR,SAjBe8lB,EAAG7lB,oBACtBqkB,EAAqBrkB,EACvB,EAgBMjB,KAAK,KACL9L,MAAOouB,GAEN/M,EAAc3jB,IAAKwjB,gBAClB9lB,EAAAC,cAACuR,EAAOK,OAAOrL,CAAAA,IAAKsf,EAAI5lB,GAAI0E,MAAOkhB,EAAI5lB,IACpC4lB,EAAIxiB,SAQX2yB,GAA8BA,iBAClCj2B,EAAAC,cAACoQ,EACCa,CAAAA,KAAK,aACLqB,UAAU,SACVjC,QAASC,EAAM,iBACfqS,kBAAmB,KACnB/D,gBAAiBtO,EAAM,iBACvBiE,OAAQjE,EAAM,wBACdyD,OAAS,aAAYzD,EAAM,oCAE3BvQ,EAAAC,cAACinB,EAAQxW,CAAAA,KAAK,oBACd1Q,EAAAC,cAAC4Q,EAAK8B,CAAAA,SAAUpC,EAAM,oBAAqBuC,WAAY,MAAM,YCrvBjE,SAAS+E,IAAe7F,QACtBA,iBAIA,OACEhS,EAAAC,cAAC6R,GACCgG,GAAG,SACHlX,OAAQ2P,EAAM,uBACdwH,KAAM,CAAEpH,MAAOJ,EAAM,sBAAuBjN,KAAM,aAClD0O,QAASA,EACTtB,KAAM,KACNkB,MAAM,QACNM,QAAQ,SAGd,CAEA,SAASulB,IAAmBthB,SAC1BA,EAAQa,eACRA,EAAcZ,KACdA,EAAInE,MACJA,iBAOA,OAAOgG,gBACLjY,EAAAC,cAACiY,EAAcjG,CAAAA,MAAOA,gBACpBjS,EAAAC,cAACkY,EAAK,CACJ/B,KAAMA,EACNY,eAAgBA,EAChBpH,SAAU,GACV8H,UAAU,+BACVpI,QAASiB,EAAM,iBACf6H,cAAe7H,EAAM,iBACrBiE,OAAQjE,EAAM,wBACdmnB,OAAQ,oBAER13B,EAAAC,cAACoQ,EAAS,CACRa,KAAK,aACLC,aAAa,gBACboB,UAAU,uBAEVvS,EAAAC,cAACuQ,EACCC,CAAAA,MAAO,EACPE,MAAOJ,EAAM,2BACbe,WAAYf,EAAM,0BAClBoC,SAAUpC,EAAM,qBAChBuC,WAAW,OACZ,kCAGD9S,EAAAC,cAAC4X,GAAe7F,CAAAA,QAASgF,KAE1Bb,gBAEHnW,EAAAC,cAAS,QAAA,KAAA,8EAIXoY,SAASC,KAEb,w/lBCxEaqf,GAAQ,CACnBC,gBACAC,YACA9T,aCgCI3Z,GAAiB,IAAI1E,EAAO,CAChCC,KAAMC,EAAU,WAAY,CAAEC,UAAU,IACxCC,QAAS,eAGX,SAASkY,IAAOqU,mBACdA,EAAkBzO,YAClBA,EAAW0O,eACXA,EAAcwF,UACdA,EAAStF,WACTA,EAAU7vB,YACVA,EAAWo1B,qBACXA,EAAoB7rB,QACpBA,EAAO8rB,mBACPA,EAAkB/lB,MAClBA,EAAK6N,QACLA,IAcA,MAAOmY,EAAiBC,GAAsBxrB,GAAS,GACjDyrB,EAAWL,IAAcC,EAEzBK,EAAcxU,EAAY9b,OAC7BgE,GAAeA,EAAW8S,QAC3BhV,OACIyuB,EAAczU,EAAY9b,OAC7BgE,IAAgBA,EAAW8S,QAC5BhV,oBAEF,OACE5J,EAAAC,cAACoQ,EAAS,CACRa,KAAK,aACLqB,UAAU,SACVU,gBACEklB,EAAW5nB,EAAM,4CAAyC/B,EAE5DuY,aACEoR,OAAW3pB,EAAa,aAAY+B,EAAM,sBAE5C,cAAY,qBACZY,aAAa,gBACb4Q,kBAAmB,EACnBtP,aAAclC,EAAM,iBACpBiC,WAAY,EACZoQ,kBAAmBrS,EAAM,iBACzBsO,gBAAiBtO,EAAM,iBACvBD,QAASC,EAAM,iBACf+nB,MAAI,EACJZ,OAAQ,GAEPI,IAAcC,eACb/3B,EAAAC,cAACoQ,EAAS,CACRa,KAAK,aACLqB,UAAU,SACVwP,iBAAkB,EAClBzR,QAAS,gBAETtQ,EAAAC,cAACyU,GACChE,KAAM,EACNC,MAAOJ,EAAM,iCACbjN,KAAK,6CAEPtD,EAAAC,cAACuQ,EAAO,CACNG,MAAOJ,EAAM,2BACbE,MAAO,EACPC,KAAMH,EAAM,qBACb,kDAKHvQ,EAAAC,cAACuQ,EACCG,CAAAA,MAAOJ,EAAM,2BACbE,MAAO,EACPC,KAAMH,EAAM,qBAEXrE,EACG,qBACAhD,GAAUkvB,EAAa,qBAC1BC,EAAc,EAAK,KAAIA,YAAwB,IAGnDP,IACEC,eACC/3B,EAAAC,cAACoQ,GACCa,KAAK,aACLqB,UAAU,SACVjC,QAASC,EAAM,kBAEdqT,EAAYha,OAAS,gBACpB5J,EAAAC,cAAC6R,EAAM,CAACE,QAASgmB,EAAoB9lB,QAAQ,WAAU,kCAIzDlS,EAAAC,cAAC6R,EACCG,CAAAA,MAAM,UACNC,QAAQ,OACRF,QAASA,IAAMkmB,GAAmB,IACnC,kCAGDl4B,EAAAC,cAACw3B,GAAkB,CACjBrhB,KAAM6hB,EACNjhB,eAAgBA,IAAMkhB,GAAmB,GACzCjmB,MAAOA,gBAEPjS,EAAAC,cAACmyB,GACCzvB,CAAAA,YAAaA,EACb2vB,eAAgBA,EAChBE,WAAYA,EACZ1S,QAASA,EACT9I,eAAgBA,IAAMkhB,GAAmB,GACzC7F,mBAAoBA,mBAK1BryB,EAAAC,cAAC8Q,EAAG,kBACF/Q,EAAAC,cAACoQ,EAAUa,CAAAA,KAAK,aAAaqB,UAAU,SAASjC,QAAS,gBACvDtQ,EAAAC,cAAC6R,EACCE,CAAAA,QAASgmB,EACT/lB,MAAM,UACNC,QAAQ,WACT,mCAGDlS,EAAAC,cAAC6R,EAAM,CACLG,MAAM,UACN6B,UACAwL,EAAAA,QAAS,CACP1N,MAAO,mDAEV,wBAQf,UAEwB2mB,IAAYlG,mBAClCA,EAAkBmG,sBAClBA,EAAqBlG,eACrBA,EAAiB,wEAAuEzS,gBACxFA,EAAeD,uBACfA,EAAsB4S,WACtBA,EAAUiG,yBACVA,EAAwBxmB,MACxBA,EAAK6N,QACLA,EAAO4Y,oBACPA,EAAmBC,uBACnBA,EAAyB,gEAA+D7kB,SACxFA,GAAW,EAAK+J,eAChBA,EAAiB,gBAoBjB/P,EAAU,KACR,IAAKgS,EAAS,OAAOnT,GAAW,IRtNpC1K,eAAgCsH,GAC9B,MAAMzG,KAAEA,SAAesH,GAAepH,IAAI,CACxCF,KAAM,CACJiL,GAAIxE,EACJtG,OAAQ,CACNijB,uBACE,yMACFlb,OAAQ,QAEV9G,QAAS,cAEXd,IAAK,6BAGP,OAAON,CACT,EQwMI81B,CAAiB9Y,EAAQa,UACtBtS,KAAKiV,IACLjV,KAAKoV,IACLpV,KAAKnM,IACLmM,KAAKuO,IACLvO,KAAKoX,GACLpX,KAAK,IAAM1B,GAAW,GAC3B,EAAG,CAACmT,MAAAA,OAAAA,EAAAA,EAASa,WAEb,MAAOiD,EAAa6B,GAAkB/Y,EAAS,KACxCR,EAASS,GAAcD,GAAS,IAChCurB,EAAiBC,GAAsBxrB,GAAS,IAEjDxL,WAAEA,EAAUE,mBAAEA,EAAkBD,cAAEA,GAAkBu3B,EAIpDnsB,EAFS,IAAIssB,gBAAgB5hB,OAAOwe,SAAShH,QAEvBzrB,IAAI,iBAG1B81B,EAAWptB,GAAA,CAAA,EAAQuG,EAAU,CAAE0lB,MAAKjsB,GAAOisB,CAAAA,EAAAA,MAEjD7pB,EAAU,KACRuK,SAASC,KAAKygB,gBAAgB,2BAA4B7sB,EAC5D,EAAG,CAACA,IAEJ,MAAM6rB,GAAuBnU,EAAYha,QACrCga,EAAYoV,KAAMjH,GAAMA,EAAEnT,QAG9B,SAASqa,EAAa/4B,GACpBkK,GACG8uB,OAAO,CACNp2B,KAAM,CAAEiL,GAAI+R,EAAQa,UACpBvd,IAAM,6BAA4BlD,MAEnCmO,KAAK,IACJoX,EAAe7B,EAAY9b,OAAQgE,GAAeA,EAAW5L,KAAOA,KAErEmD,MAAO2G,IACN,MAAM6J,EACJ9J,GAAcC,EAAO,WACrB,mFACF2J,GAAkBC,KAAK,CACrBC,OACAjC,MAAO,UAEX,EACJ,CAoBA,MAAMunB,EAAyB,CAC7BxoB,MAAOJ,EAAM,kBACbE,MAAO,EACPC,KAAMH,EAAM,qBACZK,OAAQL,EAAM,yBAGV6oB,EAAsB,CAC1BzoB,MAAOJ,EAAM,4BACbuC,WAAY,EACZpC,KAAMH,EAAM,kCAoBd,OACEvQ,EAAAC,cAACiY,EAAa,CAACjG,MAAO6mB,gBACpB94B,EAAAC,cAACe,GAAoB0e,SACnB9a,CAAAA,MAAO,CAAE1D,aAAYC,gBAAeC,uBAEnC0e,gBACC9f,EAAAC,cAAC+d,IACC4F,YAAaA,EACb0O,eAAgBA,EAChBwF,UAAWlY,IAA2B9L,EACtC5H,QAASA,EACTsmB,WAAYA,EACZ7vB,YAAa61B,EACbvmB,MAAO6mB,EACPhZ,QAASA,EACTiY,qBAAsBA,EACtBC,mBAhEV,WACE5tB,GACGmJ,KAAK,CACJzQ,KAAM,CACJA,KAAM,CACJ0Q,WAAY,CACVzF,GAAI+R,EAAQa,SACZ/B,QAASmZ,KAIf30B,IAAK,uBAENiL,KAAK,KACJ4I,OAAOwe,SAASC,QAAM,EAE5B,EAiDUrD,mBAAoBA,IAGvBnmB,eACClM,EAAAC,cAAC+mB,EAAO,CACNC,mBAAOjnB,EAAAC,cAACinB,GAAQxW,KAAK,OACrBmO,gBAAiB,GACjBjN,MAAO,2BAENkO,eAGH9f,EAAAC,cAAC8Q,EAAG,CAAC,cAAY,wBACd6S,MAAAA,OAAAA,EAAAA,EAAaha,QAAS,eACrB5J,EAAAC,cAACknB,EAAS7W,CAAAA,QAAS,EAAGmH,eAAgB,EAAG2P,aAAc,IACpDyF,EAAOjJ,EAAa,MAAMthB,IAAKyvB,iBAC9B/xB,SAAAC,cAACud,GACChX,CAAAA,IAAKurB,EAAE7xB,GACP4L,WAAYimB,EACZrU,kBAhDf2b,EAgDwDtH,EA/CxDuH,IACC,MAAMC,EACe,mBAAZD,EAAyBA,EAASD,GAAsBC,EAC3DE,EAAiB,IAClB5V,EAAY9b,OAAQgE,GAAeA,EAAW5L,KAAOq5B,EAAQr5B,IAChEq5B,GAGF9T,EAAe+T,EACjB,GAuCgB7b,SAAUsb,EACVhnB,MAAO6mB,EACPlb,eAAgBmU,EAAE7xB,KAAOuwB,OAAOlkB,GAChCuT,QAAS,CACPlU,OA1DYE,EA0DkBimB,EAzDzCjS,EAAQlV,OAAO9F,KAAM8G,GAAUA,EAAMtI,OAASwI,EAAWxI,OA0D9Cqd,SAAUb,EAAQa,UAEpBd,gBAAiBA,EACjBD,uBAAwBA,EACxB9L,SAAUA,EACV+J,eAAgBA,IAhElC,IAAgC/R,EAK7ButB,CA6DY,iBAGHr5B,EAAAC,cAACoQ,EACCopB,CAAAA,OAAQlpB,EAAM,iBACdD,QAASC,EAAM,iBACfgC,UAAU,SACVmnB,aAAc,CACZC,GAAI,CACFzoB,KAAM,aACNC,aAAc,SACdb,QAASC,EAAM,iCAInBvQ,EAAAC,cAAC8Q,EAAG,CACF1B,IAAK,CACH,UAAW,CACTzO,OAAQ,OACRD,MAAO,SAGXiP,SAAU,GACV8pB,aAAc,CACZC,GAAI,CACF/pB,SAAU,mBAId5P,EAAAC,cAACF,GAAc,oBAEjBC,EAAAC,cAACoQ,EAAS,CACRkC,UAAU,SACVjC,QAASC,EAAM,iBACfX,SAAU,GACV8pB,aAAc,CACZC,GAAI,CACFpnB,UAAW,QACXpC,UAAW,SAGfA,UAAU,UAETyP,eACC5f,EAAAC,cAAAD,EAAA+P,SACE/P,kBAAAA,EAAAC,cAACuQ,EAAY2oB,EAAwB,kCAGrCn5B,EAAAC,cAACoQ,EAAS,CACRkC,UAAU,SACVE,aAAclC,EAAM,iBACpBmpB,aAAc,CACZC,GAAI,CACFpnB,UAAW,UAGfjC,QAAS,gBAETtQ,EAAAC,cAAC4Q,EAASuoB,EACPZ,iBAGLx4B,EAAAC,cAACoQ,EACCa,CAAAA,KAAK,aACLZ,QAASC,EAAM,+BAEfvQ,EAAAC,cAAC6R,EACCI,CAAAA,QAAQ,UACRvC,GAAI2iB,EACJ3hB,MAAQ,GAAEJ,EACR,+CAEH,2BAGDvQ,EAAAC,cAAC6R,EAAM,CACLgG,GAAG,SACH7F,MAAM,UACNC,QAAQ,OACRF,QAASA,IAAMkmB,GAAmB,IACnC,mCAIHl4B,EAAAC,cAACw3B,GAAkB,CACjBrhB,KAAM6hB,EACNjhB,eAAgBA,IAAMkhB,GAAmB,GACzCjmB,MAAO6mB,gBAEP94B,EAAAC,cAACmyB,GAAa,CACZI,WAAYA,EACZ7vB,YAAa61B,EACblG,eAAgBA,EAChBtb,eAAgBA,IAAMkhB,GAAmB,GACzCpY,QAASA,EACTuS,mBAAoBA,mBAK1BryB,EAAAC,cAAAD,EAAA+P,SAAA,kBACE/P,EAAAC,cAACuQ,EAAY2oB,EAAwB,4BACrCn5B,EAAAC,cAAC4Q,EAASuoB,EACPT,oBA7Hf34B,EAAAC,cAAAD,EAAA+P,SAAA,MAsID0oB,gBACCz4B,EAAAC,cAACslB,GAAmB,CAClBC,eAAgBiT,EAChB3Y,QAASA,kBAIf9f,EAAAC,cAAA,QAAA,KAAQ25B,IAGd"}
1
+ {"version":3,"file":"core-automations.modern.mjs","sources":["../../src/assets/svg_automations.tsx","../../src/contexts/organization_context.tsx","../../src/utils/alerts.ts","../../src/utils/utils.ts","../../src/history.tsx","../../src/history_modal.tsx","../../src/utils/logos.ts","../../src/utils/response-labelers/people-form.ts","../../src/utils/resolve-response-details.ts","../../src/automation.tsx","../../src/utils/fetch-automations.ts","../../src/incoming_automations.tsx","../../src/definition.tsx","../../src/field.tsx","../../src/fields.tsx","../../src/new_automation.tsx","../../src/new_automation_modal.tsx","../../src/utils/theme.ts","../../src/automations.tsx"],"sourcesContent":["import React from \"react\"\n\nconst SvgAutomations = () => (\n <svg\n id=\"automations_blank\"\n data-name=\"Automations Blank\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 111.112 84.832\"\n className=\"symbol\"\n >\n <title>Automations</title>\n <g opacity=\"0.6\">\n <path\n d=\"M107.784,46.051A57.416,57.416,0,0,1,85.26,75.058c-9.7,6.247-20.045,7.792-31.912,5.185-11.74-2.638-23.339-8-32.92-13.088-9.51-5.342-17-10.236-18.863-17.925C-.26,41.753,3.737,31.4,13.347,21.194,22.85,11.162,37.968,1.853,55.948.321,73.8-1.476,90.2,4.478,99.608,13.164,109.257,21.9,111.921,33.784,107.784,46.051Z\"\n fill=\"#e1f0f9\"\n className=\"svg-background-blob\"\n />\n </g>\n <path\n d=\"M81,27.269v31.8a2.685,2.685,0,0,1-2.685,2.685H44.564a2.685,2.685,0,0,1-2.685-2.685V15.425a2.685,2.685,0,0,1,2.685-2.685h21.91a2.681,2.681,0,0,1,1.9.786L80.217,25.371A2.685,2.685,0,0,1,81,27.269Z\"\n fill=\"#fff\"\n />\n <path\n d=\"M68.479,13.633v9.8a2.035,2.035,0,0,0,2.035,2.034h9.877Z\"\n fill=\"#c9d8e2\"\n />\n <rect\n x=\"51.214\"\n y=\"41.285\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"51.214\"\n y=\"48.434\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"51.214\"\n y=\"34.136\"\n width=\"20.221\"\n height=\"2.791\"\n rx=\"1.395\"\n ry=\"1.395\"\n fill=\"#dae5ed\"\n />\n <rect\n x=\"11.771\"\n y=\"44.005\"\n width=\"50.915\"\n height=\"6.664\"\n transform=\"translate(-22.93 44.557) rotate(-49.171)\"\n fill=\"#454942\"\n />\n <path\n d=\"M56.283,30.38l-7.557,8.745a5.968,5.968,0,0,0-2.005-2.734,6.292,6.292,0,0,0-3.036-1.624l7.555-8.743a6.275,6.275,0,0,1,3.038,1.624A5.959,5.959,0,0,1,56.283,30.38Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M58.088,28.29l-7.556,8.745a5.968,5.968,0,0,0-2-2.734,6.3,6.3,0,0,0-3.036-1.624l7.555-8.743a6.274,6.274,0,0,1,3.037,1.624A5.959,5.959,0,0,1,58.088,28.29Z\"\n fill=\"#48a5e5\"\n />\n <path\n d=\"M58.724,10.432l1.17,2.7a2.129,2.129,0,0,0,1.4,1.207l2.843.765a.73.73,0,0,1,.1,1.375l-2.7,1.17a2.125,2.125,0,0,0-1.207,1.4L59.56,21.89a.73.73,0,0,1-1.374.1l-1.17-2.7a2.125,2.125,0,0,0-1.4-1.206l-2.843-.766a.73.73,0,0,1-.1-1.374l2.7-1.17a2.121,2.121,0,0,0,1.206-1.4l.766-2.844A.73.73,0,0,1,58.724,10.432Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M44.544,19.294l1.024.868a.968.968,0,0,0,.814.21l1.316-.261a.333.333,0,0,1,.319.541l-.868,1.024a.968.968,0,0,0-.21.814l.261,1.316a.333.333,0,0,1-.541.319l-1.024-.868a.968.968,0,0,0-.814-.21l-1.316.261a.333.333,0,0,1-.319-.541l.868-1.024a.967.967,0,0,0,.21-.814L44,19.613A.333.333,0,0,1,44.544,19.294Z\"\n fill=\"#fcc846\"\n />\n <path\n d=\"M64.223,25.729l.869,2.005a1.575,1.575,0,0,0,1.036.895l2.109.568a.542.542,0,0,1,.075,1.02l-2,.868a1.576,1.576,0,0,0-.9,1.036l-.568,2.11a.541.541,0,0,1-1.019.074L62.955,32.3a1.572,1.572,0,0,0-1.036-.895l-2.109-.568a.542.542,0,0,1-.075-1.02l2.005-.868a1.572,1.572,0,0,0,.895-1.036L63.2,25.8A.541.541,0,0,1,64.223,25.729Z\"\n fill=\"#fcc846\"\n />\n </svg>\n)\n\nexport default SvgAutomations\n","import { createContext } from \"react\"\n\nexport const OrganizationContext = createContext({\n dateFormat: null,\n olsonTimeZone: null,\n twentyFourHourTime: null,\n})\n","import {\n createConfirmOptions,\n destroyConfirmOptions,\n errorAlertOptions,\n standardAlertOptions,\n standardConfirmOptions,\n successAlertOptions,\n} from \"@planningcenter/sweetalert2\"\nimport Swal from \"sweetalert2/dist/sweetalert2\"\n\nexport const alert = Swal.mixin(standardAlertOptions)\nexport const alertSuccess = Swal.mixin(successAlertOptions)\nexport const alertError = Swal.mixin(errorAlertOptions)\nexport const confirm = Swal.mixin(standardConfirmOptions)\nexport const confirmDestroy = Swal.mixin(destroyConfirmOptions)\nexport const confirmCreate = Swal.mixin(createConfirmOptions)\n","import { Client } from \"@planningcenter/api-client\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { cloneDeep, isBoolean, set } from \"lodash\"\nimport moment from \"moment\"\n\nexport async function deobfuscateDescriptions(\n subscriptions: AutomationInstance[]\n) {\n return Promise.all(\n subscriptions.map(async (subscription) => {\n if (isDeobfuscatable(subscription)) {\n subscription.description = await deobfuscatedDescription(subscription)\n }\n return subscription\n })\n )\n}\n\nfunction isDeobfuscatable(subscription: AutomationInstance) {\n const DEOBFUSCATABLE_OPERATION_DEFINITION_CLASS_NAMES = [\n \"AddToWorkflowOperationDefinition\",\n \"CustomFieldBooleanOperationDefinition\",\n \"CustomFieldCheckboxesOperationDefinition\",\n \"CustomFieldDateOperationDefinition\",\n \"CustomFieldNumberOperationDefinition\",\n \"CustomFieldSelectOperationDefinition\",\n \"CustomFieldStringOperationDefinition\",\n \"CustomFieldTextOperationDefinition\",\n ]\n\n return DEOBFUSCATABLE_OPERATION_DEFINITION_CLASS_NAMES.includes(\n subscription.operationDefinitionClassName\n )\n}\n\nasync function deobfuscatedDescription(subscription: AutomationInstance) {\n let description = \"\"\n if (\n subscription.operationDefinitionClassName ===\n \"AddToWorkflowOperationDefinition\"\n ) {\n const data = await fetchWorkflow(subscription.operationParams.workflowId!)\n const workflow = data[0]\n\n if (workflow?.name) {\n let workflowName\n\n if (workflow.archivedAt) {\n workflowName = `[archived] ${workflow.name}`\n } else {\n workflowName = workflow.name\n }\n\n description = subscription.description.replace(\n \"[Hidden Workflow]\",\n workflowName\n )\n }\n } else {\n // custom field\n const fieldDefinitionId =\n subscription.operationParams.definitionIdentifier.match(\n /(\\d+)_field_definition/\n )![1]\n const fieldDefinition = await fetchFieldDefinition(fieldDefinitionId)\n if (fieldDefinition.name) {\n description = subscription.description.replace(\n \"[Hidden Custom Field]\",\n fieldDefinition.name\n )\n description +=\n subscription.operationParams.values ||\n fieldDefinition.dataType !== \"checkboxes\"\n ? ` (${customFieldOptionDescription(subscription, fieldDefinition)})`\n : \"\"\n }\n }\n return description || subscription.description\n}\n\nfunction customFieldOptionDescription(\n subscription: AutomationInstance,\n fieldDefinition: {\n dataType: string\n fieldOptions: { id: number; value: string }[]\n }\n) {\n switch (fieldDefinition.dataType) {\n case \"checkboxes\":\n return Object.entries(subscription.operationParams.values ?? {})\n .map(([id, action]) => {\n const value =\n fieldDefinition.fieldOptions.find(\n (fieldOption) => fieldOption.id === parseInt(id, 10)\n )?.value || \"[Hidden value]\"\n return `${capitalize(action)} ${value}`\n })\n .join(\", \")\n case \"select\": {\n const value = subscription.operationParams.value\n return value\n ? fieldDefinition.fieldOptions.find(\n (fieldOption) => fieldOption.id === parseInt(value, 10)\n )?.value || \"[Hidden value]\"\n : \"Unanswered\"\n }\n case \"boolean\":\n switch (subscription.operationParams.value) {\n case \"true\":\n return \"Yes\"\n case \"false\":\n return \"No\"\n default:\n return \"Unanswered\"\n }\n default:\n return subscription.operationParams.value ?? \"Unanswered\"\n }\n}\n\nfunction capitalize(string: string) {\n return string.charAt(0).toUpperCase() + string.slice(1)\n}\n\nconst peopleClient = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n version: \"2025-03-20\",\n})\n\nasync function fetchWorkflow(workflowId: number) {\n const { data } = await peopleClient\n .get({\n data: {\n fields: { Workflow: \"name,archived_at\" },\n where: { id: workflowId },\n },\n url: `workflows`,\n })\n .catch(() => [{ data: { name: \"\" } }])\n\n return data\n}\n\nasync function fetchFieldDefinition(fieldDefinitionId: string) {\n const { data } = await peopleClient\n .get({\n data: {\n fields: {\n FieldDefinition: \"name,data_type,field_options\",\n FieldOption: \"value\",\n },\n include: \"field_options\",\n },\n url: `field_definitions/${fieldDefinitionId}`,\n })\n .catch(() => ({ data: { name: \"\" } }))\n\n return data\n}\n\nexport function fieldListIdentifier(field: DefinitionField) {\n if (field.listClass) {\n return `${field.id}_${field.listClass}`\n } else if (field.kind === \"PersonSearch\") {\n return `${field.id}_PersonSearch`\n } else {\n return null\n }\n}\n\nexport function buildDescription({\n selectedDefinition,\n selectedFieldOptions,\n loadedLists,\n}: {\n loadedLists: { [k: string]: LoadedList[] }\n selectedDefinition: OperationDefinition\n selectedFieldOptions: SelectedFieldOptions\n}) {\n return {\n description: describeSelectedFields({\n loadedLists: loadedLists || {},\n selectedDefinition,\n selectedFieldOptions,\n }),\n name: buildDescriptionName(selectedDefinition),\n }\n}\n\nfunction obfuscateDescriptionName(definition: OperationDefinition) {\n if (definition.definitionClass.match(/^CustomField\\w+OperationDefinition$/)) {\n return \"Update [Hidden Custom Field]\"\n }\n}\n\nfunction buildDescriptionName(definition: OperationDefinition) {\n return obfuscateDescriptionName(definition) || definition.description\n}\n\nfunction hasOwnProperty(object: object, key: PropertyKey) {\n return Object.prototype.hasOwnProperty.call(object, key)\n}\n\nfunction getListForField({\n field,\n loadedLists,\n}: {\n field: DefinitionField\n loadedLists: { [k: string]: LoadedList[] }\n}) {\n if (field.list) {\n return field.list\n } else if (fieldListIdentifier(field)) {\n const identifier = fieldListIdentifier(field) as string\n const list = loadedLists[identifier]\n\n return list\n } else {\n throw new Error(`Don't know how to get list for ${JSON.stringify(field)}`)\n }\n}\n\nexport function buildTriggerConditions({\n baseConditions,\n dynamicConditions,\n dynamicTriggerConditions,\n}: {\n baseConditions: object\n dynamicConditions: DefinitionField[] | undefined\n dynamicTriggerConditions: SelectedFieldOptions\n}) {\n const triggerConditions = cloneDeep(baseConditions)\n const fields = dynamicConditions ?? []\n const writableFields = fields.filter((field) => {\n if (field.renderOnly) return false\n return renderIfChainSatisfied(field, fields, dynamicTriggerConditions)\n })\n\n for (const field of writableFields) {\n if (\n Object.prototype.hasOwnProperty.call(dynamicTriggerConditions, field.id)\n ) {\n set(triggerConditions, field.id, dynamicTriggerConditions[field.id])\n }\n }\n\n return triggerConditions\n}\n\nfunction shouldRender(\n field: DefinitionField,\n selectedFieldOptions: SelectedFieldOptions\n) {\n if (!Object.prototype.hasOwnProperty.call(field, \"renderIf\")) return true\n\n const renderIf = field.renderIf!\n if (isBoolean(renderIf)) return renderIf\n\n const conditionKey = Object.keys(renderIf)[0]\n return renderIf[conditionKey] === selectedFieldOptions[conditionKey]\n}\n\nfunction renderIfChainSatisfied(\n field: DefinitionField,\n allFields: DefinitionField[],\n selectedFieldOptions: SelectedFieldOptions\n): boolean {\n if (!shouldRender(field, selectedFieldOptions)) return false\n\n const renderIf = field.renderIf\n if (renderIf == null || renderIf === true) return true\n\n const upstreamId = Object.keys(renderIf)[0]\n const upstream = allFields.find((f) => f.id === upstreamId)\n if (!upstream) return true\n return renderIfChainSatisfied(upstream, allFields, selectedFieldOptions)\n}\n\nexport function getRenderedFields(\n definitionFields: DefinitionField[],\n selectedFieldOptions: SelectedFieldOptions\n) {\n return definitionFields.filter(\n (field) =>\n field.kind !== \"Hidden\" &&\n renderIfChainSatisfied(field, definitionFields, selectedFieldOptions)\n )\n}\n\nfunction describeSelectedFields({\n selectedDefinition,\n selectedFieldOptions,\n loadedLists,\n}: {\n loadedLists: { [k: string]: LoadedList[] }\n selectedDefinition: OperationDefinition\n selectedFieldOptions: SelectedFieldOptions\n}) {\n const description = selectedDefinition.definitionFields\n .map((field) => {\n if (!hasOwnProperty(selectedFieldOptions, field.id)) return null\n\n const value = selectedFieldOptions[field.id]\n let list\n\n switch (field.kind) {\n case \"Select\":\n case \"SelectSearch\":\n case \"PersonSearch\":\n case \"RadioButtons\":\n list = getListForField({ field, loadedLists })\n\n return (\n list && list.find((o) => o.value.toString() === value)?.description\n )\n case \"Checkbox\":\n return value && field.label\n case \"Checkboxes\":\n list = getListForField({ field, loadedLists })\n\n return list\n .filter((e) => hasOwnProperty(value as object, e.value))\n .map(\n (e) =>\n `${capitalize((value as Record<string, string>)[e.value])} ${\n e.description\n }`\n )\n .join(\", \")\n case \"NumberField\":\n case \"TextField\":\n case \"TextArea\":\n case \"DateField\":\n return value\n default:\n throw new Error(\n `Don't know how to build value for field with kind ${field.kind}`\n )\n }\n })\n .filter((x) => x)\n .join(\", \")\n\n return obfuscateSelectedFieldDescriptions({\n description,\n loadedLists,\n selectedDefinition,\n selectedFieldOptions,\n })\n}\n\nfunction obfuscateSelectedFieldDescriptions({\n selectedDefinition,\n selectedFieldOptions,\n loadedLists,\n description,\n}: {\n description: string\n loadedLists: { [k: string]: LoadedList[] }\n selectedDefinition: OperationDefinition\n selectedFieldOptions: SelectedFieldOptions\n}) {\n if (\n selectedDefinition.definitionClass === \"AddToWorkflowOperationDefinition\"\n ) {\n const list = loadedLists.workflow_id_WorkflowsList\n const sensitiveString =\n list &&\n list.find((o) => o.value.toString() === selectedFieldOptions.workflow_id)\n ?.description\n\n return sensitiveString\n ? description.replace(sensitiveString, \"[Hidden Workflow]\")\n : description\n } else if (\n selectedDefinition.definitionClass.match(\n /^CustomField\\w+OperationDefinition$/\n )\n ) {\n return \"\"\n } else {\n return description\n }\n}\n\nexport function dateFNSFormat(format: string) {\n return format\n .replace(/%m/, \"M\")\n .replace(/%d/, \"d\")\n .replace(/%Y/, \"y\")\n .replace(/%y/, \"yy\")\n}\n\nexport function momentDateFormat(format: string) {\n return format\n .replace(/%m/, \"MM\")\n .replace(/%d/, \"DD\")\n .replace(/%Y/, \"YYYY\")\n .replace(/%y/, \"YY\")\n}\n\nexport function momentDateTimeFormat({\n dateFormat,\n twentyFourHourTime,\n}: {\n dateFormat: string\n twentyFourHourTime: boolean\n}) {\n return `${momentDateFormat(dateFormat)} ${\n twentyFourHourTime ? \"HH:mm\" : \"h:mm A\"\n }`\n}\n\nexport function dateLocalized(date: string, dateFormat: string) {\n const momentDate = moment(date, \"YYYY-MM-DD\")\n if (!momentDate.isValid()) {\n return \"\"\n }\n\n const format = momentDateFormat(dateFormat)\n return momentDate.format(format)\n}\n\nexport function numDaysSince(date: string) {\n const momentDate = moment(date, \"YYYY-MM-DD\")\n return moment().diff(momentDate, \"days\")\n}\n\nexport function pluralize(count: number, word: string) {\n if (count === 1) {\n return `1 ${word}`\n } else {\n return `${count} ${word}s`\n }\n}\n\nexport function singularize(string: string) {\n return string.replace(/s$/, \"\")\n}\n\nexport function upperFirst(string: string) {\n return string.charAt(0).toUpperCase() + string.slice(1)\n}\n\nexport function triggerResourceParts(triggerResource: string) {\n const triggerParts = triggerResource.split(\"/\")\n\n return {\n appName: triggerParts[0],\n resourceId: triggerParts[triggerParts.length - 1],\n resourcePath: triggerParts.slice(2, -1).join(\"/\"),\n resourceType: triggerParts[triggerParts.length - 2],\n }\n}\n\nexport function forbiddenText(error: any, action?: string) {\n if (error.errors?.[0]?.status === \"403\") {\n return `You don't have permission to ${action || \"modify\"} this automation.`\n }\n return null\n}\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Alert,\n Badge,\n Box,\n Button,\n DataTable,\n Heading,\n Icon,\n Input,\n Link,\n Select,\n StackView,\n Text,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport moment from \"moment-timezone\"\nimport React, { useCallback, useContext, useEffect, useState } from \"react\"\n\nimport SvgAutomations from \"./assets/svg_automations\"\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport * as alerts from \"./utils/alerts\"\nimport {\n dateLocalized,\n momentDateTimeFormat,\n numDaysSince,\n} from \"./utils/utils\"\n\ndeclare global {\n interface Window {\n openHelpdesk: () => void\n }\n}\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"2022-10-20\",\n})\nconst peopleClient = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n version: \"2022-07-14\",\n})\n\n// values should match the webhooks Event `status` enum entries\nconst STATUS = {\n delivered: {\n label: \"Success\",\n value: [\"delivered\"],\n },\n failed: {\n label: \"Failed\",\n value: [\"failed\", \"duplicated\"],\n },\n ignored: {\n label: \"Ignored\",\n value: [\"ignored_duplicated\", \"ignored_failed\", \"ignored_skipped\"],\n },\n pending: {\n label: \"Pending\",\n value: [\"pending\"],\n },\n skipped: {\n label: \"Paused\",\n value: [\"skipped\"],\n },\n}\n\nasync function fetchEvents(\n triggerResource: EncryptedTriggerResource,\n automationId: number,\n params: {\n offset: number\n per_page: number\n where?: { status: string } | null\n }\n) {\n const response = await webhooksClient.get({\n data: {\n _e: triggerResource,\n fields: {\n Delivery: \"status,response_body,created_at\",\n Event: \"id,created_at,last_delivery,payload,status,uuid,person\",\n },\n include: \"last_delivery\",\n order: \"-created_at\",\n ...params,\n },\n url: `automation_subscriptions/${automationId}/events`,\n })\n\n return response\n}\n\nasync function fetchPeople(personIds) {\n const { data } = await peopleClient.get({\n data: {\n fields: {\n Person: \"id,name\",\n },\n where: { id: personIds.join(\",\") },\n },\n url: `people`,\n })\n\n return data\n}\n\nasync function fetchPeopleWhoTriggeredEvents(events) {\n const personIds = events.data.map((e) => eventPersonId(e))\n try {\n const people = await fetchPeople(personIds)\n return { events, people }\n } catch (error) {\n return { events, people: [] }\n }\n}\n\nfunction mergePeopleAndEvents({ events, people }) {\n const mergedData = events.data.reduce((result, e) => {\n const personId = eventPersonId(e)\n const foundPerson = people.find(\n (p) => personId.toString() === p.id.toString()\n )\n if (foundPerson) {\n result.push({\n ...e,\n person: { id: foundPerson.id, name: foundPerson.name },\n })\n } else {\n result.push({\n ...e,\n person: { id: personId, name: \"[Hidden]\" },\n })\n }\n return result\n }, [])\n\n return { ...events, data: mergedData }\n}\n\nfunction eventPersonId(event) {\n return event.personId\n}\n\nfunction useEvents(\n automationId: number,\n triggerResource: EncryptedTriggerResource,\n filterWhere?: string\n) {\n const perPage = 50\n const [_, setError] = useState()\n const [loading, setLoading] = useState(false)\n const [eventPages, setEventPages] = useState<{ [k: number]: EventPage[] }>({})\n const [params, setParams] = useState<{ where?: { status: string } | null }>(\n filterWhere ? { where: { status: filterWhere } } : {}\n )\n const [meta, setMeta] = useState<{ totalCount: number | any }>()\n const { offset, paginationProps, resetOffset } = usePagination(\n perPage,\n meta?.totalCount\n )\n useEffect(() => {\n if (loading || eventPages[offset]) return\n\n setLoading(true)\n\n fetchEvents(triggerResource, automationId, {\n offset,\n per_page: perPage,\n ...params,\n })\n .then(fetchPeopleWhoTriggeredEvents)\n .then(mergePeopleAndEvents)\n .then((events) => {\n setEventPages((pages) => ({ ...pages, [offset]: events.data }))\n setMeta(events.meta)\n setLoading(false)\n })\n .catch(bubbleErrorToBoundary)\n }, [automationId, triggerResource, loading, params, offset, eventPages])\n\n const refresh = useCallback(() => {\n setEventPages({})\n setMeta(undefined)\n resetOffset()\n }, [resetOffset])\n\n useEffect(() => {\n refresh()\n }, [refresh, params])\n\n function bubbleErrorToBoundary(error) {\n setError(() => {\n throw error\n })\n }\n\n return {\n events: eventPages[offset] || [],\n loading,\n paginationProps,\n params,\n refresh,\n setParams,\n }\n}\n\nfunction usePagination(perPage: number, totalCount: number) {\n const [offset, setOffset] = useState(0)\n\n const currentPage = Math.floor(offset / perPage) + 1\n const totalPages = Math.ceil(totalCount / perPage)\n const paginationProps = { currentPage, onPageChange, totalPages }\n\n function onPageChange(pageNum: number) {\n setOffset((pageNum - 1) * perPage)\n }\n\n const resetOffset = useCallback(() => {\n setOffset(0)\n }, [])\n\n return { offset, paginationProps, resetOffset }\n}\n\ntype HistoryProps = {\n automation: AutomationInstance\n filterWhere?: string\n onEventsStatusChange: Function\n onRequestClose?: () => void\n triggerResource: EncryptedTriggerResource\n}\n\nfunction History({\n automation,\n triggerResource,\n filterWhere,\n onEventsStatusChange,\n}: HistoryProps) {\n const { events, loading, paginationProps, refresh, params, setParams } =\n useEvents(automation.id, triggerResource, filterWhere)\n const { dateFormat, olsonTimeZone, twentyFourHourTime } = useContext<{\n dateFormat: any\n olsonTimeZone: any\n twentyFourHourTime: any\n }>(OrganizationContext)\n\n const filteringEvents = params.where && Object.keys(params.where).length > 0\n const automationCreatedRecently = numDaysSince(automation.createdAt) <= 32\n const automationBeganOn = dateLocalized(automation.createdAt, dateFormat)\n const historyPreservationAlert = automationCreatedRecently\n ? `Automation history started on ${automationBeganOn}`\n : \"Automation history is saved for 32 days\"\n\n const showTzLabel =\n Intl.DateTimeFormat().resolvedOptions().timeZone !== olsonTimeZone\n\n const columns = [\n {\n cell: (event: EventPage) => <EventStatusBadge status={event.status} />,\n css: {\n padding: \"8px 12px\",\n },\n header: \"Status\",\n },\n {\n cell: (event: EventPage) => {\n const baseFormat = momentDateTimeFormat({ dateFormat, twentyFourHourTime })\n const format = showTzLabel ? `${baseFormat} z` : baseFormat\n return moment.tz(event.createdAt, olsonTimeZone).format(format)\n },\n header: \"Date and time\",\n },\n {\n cell: (event: EventPage) => (\n <Link to={`/people/AC${event.person.id}`}>{event.person.name}</Link>\n ),\n css: {\n maxWidth: \"33%\",\n },\n header: \"Profile\",\n },\n {\n cell: (event: EventPage) => <EventStatusMessage event={event} />,\n css: {\n flex: 1,\n },\n header: \"Message\",\n },\n {\n cell: (event: EventPage) =>\n ![...STATUS.delivered.value, ...STATUS.pending.value].includes(\n event.status\n ) && (\n <>\n <RetryEventButton\n automationId={automation.id}\n event={event}\n triggerResource={triggerResource}\n onEventsStatusChange={onEventsStatusChange}\n />\n {![...STATUS.ignored.value].includes(event.status) && (\n <IgnoreEventButton\n automationId={automation.id}\n event={event}\n triggerResource={triggerResource}\n refreshHistory={refresh}\n onEventsStatusChange={onEventsStatusChange}\n />\n )}\n </>\n ),\n css: {\n textAlign: \"right\",\n },\n header: \"\",\n minWidth: \"84px\",\n },\n ]\n\n return (\n <StackView spacing={token(\"--t-spacing-4\")}>\n <StackView spacing={token(\"--t-spacing-half\")}>\n <Heading\n level={3}\n size=\"16px\"\n color={token(\"--t-text-color-secondary\")}\n weight={token(\"--t-font-weight-medium\")}\n >\n {automation.description}\n </Heading>\n <Text\n color={token(\"--t-text-color-secondary\")}\n size={token(\"--t-font-size-xs\")}\n italic\n >\n {historyPreservationAlert}\n </Text>\n </StackView>\n <StackView spacing={token(\"--t-spacing-2\")}>\n <Box minHeight={7}>\n {!loading && (events.length || filteringEvents) && (\n <StackView\n alignItems=\"end\"\n axis=\"horizontal\"\n distribution=\"space-between\"\n spacing={token(\"--t-spacing-1\")}\n >\n <StackView width=\"max-content\">\n <Input.InputLabel\n fontWeight={token(\"--t-font-weight-medium\")}\n color={token(\"--t-text-color\")}\n controls=\"select-status\"\n >\n Filter by status\n </Input.InputLabel>\n <Select\n id=\"select-status\"\n emptyValue={null}\n onChange={({ selectedValue }) => {\n const newWhere = selectedValue\n ? { status: selectedValue }\n : null\n setParams({ where: newWhere })\n }}\n title=\"Status\"\n value={params.where?.status}\n >\n <Select.Option value={null}>All</Select.Option>\n {Object.values(STATUS).map((status) => (\n <Select.Option\n key={status.value}\n value={status.value.join(\",\")}\n >\n {status.label}\n </Select.Option>\n ))}\n </Select>\n </StackView>\n <Button\n iconLeft={{ name: \"general.refresh\" }}\n onClick={refresh}\n theme=\"primary\"\n variant=\"outline\"\n width={12}\n >\n Refresh\n </Button>\n </StackView>\n )}\n </Box>\n <Box maxHeight=\"70vh\" minHeight={36} overflow=\"auto\">\n <DataTable\n columns={columns}\n data={events}\n empty={\n <StackView\n alignment=\"center\"\n distribution=\"center\"\n minHeight={20}\n maxWidth={45}\n spacing={token(\"--t-spacing-1\")}\n marginTop={!filteringEvents ? -8 : -4}\n marginBottom={!filteringEvents ? undefined : 4}\n >\n <Box\n css={{\n svg: {\n height: 15,\n width: 20,\n },\n }}\n >\n <SvgAutomations />\n </Box>\n <Heading\n color={token(\"--t-text-color-headline\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n level={4}\n size={token(\"--t-font-size-lg\")}\n >\n No history found\n </Heading>\n <Text fontSize={token(\"--t-font-size-md\")} textAlign=\"center\">\n No events {filteringEvents && \"matching your filters\"} were\n triggered for this automation{\" \"}\n {automationCreatedRecently\n ? `since ${automationBeganOn}.`\n : \"in the last 32 days.\"}\n </Text>\n {filteringEvents && (\n <Button\n marginTop={token(\"--t-spacing-1\")}\n onClick={() => setParams({})}\n theme=\"primary\"\n title=\"Clear filters\"\n variant=\"outline\"\n />\n )}\n </StackView>\n }\n loading={loading}\n loadingTitle=\"Loading automation history...\"\n variant={{\n bodyCell: {\n alignItems: \"start\",\n fontSize: token(\"--t-font-size-sm\"),\n lineHeight: \"20px\",\n padding: \"10px 12px\",\n },\n bodyRow: ({ rowData }) => {\n return {\n backgroundColor: [...STATUS.ignored.value].includes(\n rowData.status\n )\n ? token(\"--t-fill-color-neutral-090\")\n : undefined,\n minHeight: \"36px\",\n }\n },\n headerCell: {\n padding: \"8px 12px\",\n },\n headerRow: {\n minHeight: \"36px\",\n },\n }}\n {...paginationProps}\n />\n </Box>\n </StackView>\n </StackView>\n )\n}\n\nfunction RetryEventButton({\n automationId,\n event,\n triggerResource,\n onEventsStatusChange,\n}: {\n automationId: number\n event: EventPage\n onEventsStatusChange: Function\n triggerResource: EncryptedTriggerResource\n}) {\n const [status, setStatus] = useState(event.status)\n\n function handleRetry() {\n setStatus(STATUS.pending.value.join(\",\"))\n webhooksClient\n .post({\n data: {\n _e: triggerResource,\n data: { attributes: {} },\n },\n url: `/automation_subscriptions/${automationId}/events/${event.id}/redeliver`,\n })\n .then((response) => {\n setStatus(STATUS.delivered.value.join(\",\"))\n onEventsStatusChange(response.meta.eventsStatus)\n })\n .catch(() => {\n setStatus(STATUS.failed.value.join(\",\"))\n alerts.alertError.fire({\n text: \"There was a problem retrying this automation. Please try again in a few moments.\",\n title: \"Uh oh!\",\n })\n })\n }\n\n const retryTitleFromStatus = STATUS.pending.value.includes(status)\n ? \"Sending\"\n : STATUS.delivered.value.includes(status)\n ? \"Sent\"\n : STATUS.skipped.value.includes(status)\n ? \"Run now\"\n : \"Retry\"\n\n const statusIcon = STATUS.delivered.value.includes(status)\n ? { color: token(\"--t-text-color-status-success\"), name: \"general.check\" }\n : undefined\n\n return (\n <Button\n title={retryTitleFromStatus}\n onClick={handleRetry}\n iconLeft={statusIcon}\n disabled={status !== event.status}\n variant=\"naked\"\n color={\n STATUS.delivered.value.includes(status)\n ? token(\"--t-text-color-status-success\")\n : STATUS.pending.value.includes(status)\n ? token(\"--t-text-color-placeholder\")\n : token(\"--t-text-color-interaction\")\n }\n theme=\"primary\"\n size=\"xs\"\n />\n )\n}\n\nfunction IgnoreEventButton({\n automationId,\n event,\n triggerResource,\n refreshHistory,\n onEventsStatusChange,\n}: {\n automationId: number\n event: EventPage\n onEventsStatusChange: Function\n refreshHistory: Function\n triggerResource: EncryptedTriggerResource\n}) {\n function handleIgnore() {\n webhooksClient\n .post({\n data: {\n _e: triggerResource,\n data: { attributes: {} },\n },\n url: `/automation_subscriptions/${automationId}/events/${event.id}/ignore`,\n })\n .then((response) => {\n onEventsStatusChange(response.meta.eventsStatus)\n })\n .then(() => refreshHistory())\n .catch(() => {\n alerts.alertError.fire({\n text: \"There was a problem ignoring this event. Please try again in a few moments.\",\n title: \"Uh oh!\",\n })\n })\n }\n\n return (\n <Button\n title={\"Ignore\"}\n onClick={handleIgnore}\n variant=\"naked\"\n color={\"linkForeground\"}\n theme=\"primary\"\n size=\"xs\"\n />\n )\n}\n\nfunction EventStatusBadge({ status }: { status: string }) {\n const badgeColors = STATUS.pending.value.includes(status)\n ? {\n border: token(\"--t-border-color-dark\"),\n text: token(\"--t-text-color\"),\n }\n : STATUS.delivered.value.includes(status)\n ? {\n border: token(\"--t-border-color-status-success\"),\n text: token(\"--t-text-color-status-success\"),\n }\n : STATUS.skipped.value.includes(status)\n ? {\n border: token(\"--t-border-color-status-warning\"),\n text: token(\"--t-text-color-status-warning\"),\n }\n : STATUS.ignored.value.includes(status)\n ? {\n border: token(\"--t-border-color-dark\"),\n text: token(\"--t-text-color-secondary\"),\n }\n : {\n border: token(\"--t-border-color-status-error\"),\n text: token(\"--t-text-color-status-error\"),\n }\n\n const badgeIcon = STATUS.pending.value.includes(status)\n ? \"general.clock\"\n : STATUS.skipped.value.includes(status)\n ? \"services.pause\"\n : STATUS.delivered.value.includes(status)\n ? \"general.checkCircle\"\n : STATUS.ignored.value.includes(status)\n ? \"general.inactive\"\n : \"general.exclamationTriangle\"\n\n const badgeTitle = STATUS.failed.value.includes(status)\n ? STATUS.failed.label\n : STATUS.ignored.value.includes(status)\n ? STATUS.ignored.label\n : STATUS[status].label\n\n return (\n <Badge\n color={{ background: \"transparent\", foreground: badgeColors.text }}\n css={{ paddingLeft: 3.5, paddingRight: 1.5 }}\n fontSize={token(\"--t-font-size-xs\")}\n radius=\"pill\"\n renderLeft={\n <Icon\n name={badgeIcon}\n color={badgeColors.border}\n marginLeft={token(\"--t-spacing-1\")}\n />\n }\n size=\"sm\"\n stroke={badgeColors.border}\n strokeAlign=\"inside\"\n strokeWeight={1}\n title={badgeTitle}\n />\n )\n}\n\nfunction EventStatusMessage({ event }: { event: EventPage }) {\n const { status, lastDelivery } = event\n\n function statusMessage(status: string, lastDelivery: Delivery) {\n let message: string | JSX.Element | null = null\n\n switch (status) {\n case \"skipped\":\n case \"ignored_skipped\":\n message = \"Automation was paused and did not run on this profile\"\n break\n case \"failed\":\n case \"duplicated\":\n case \"ignored_failed\":\n case \"ignored_duplicated\":\n message = deliveryFailureReason(lastDelivery, status)\n }\n\n return message\n }\n\n function deliveryFailureReason(delivery: Delivery, status: string) {\n const ERRORS = {\n 403: \"Owner doesn't have permission to perform this action.\",\n 404: \"Owner lacks access to target product or resource doesn't exist.\",\n 422: \"The automation action failed to run\",\n default: \"An error occurred\",\n duplicated_event:\n \"Didn't run because the same action had already been performed less than 60 seconds ago\",\n failed_without_deliveries:\n \"Didn't run because the owner doesn't have permissions in this product.\",\n }\n\n function responseErrors(delivery: Delivery) {\n if (!delivery?.responseBody) return null\n let response\n\n try {\n response = JSON.parse(delivery.responseBody)\n } catch {\n response = { errors: [\"Server Error\"] }\n }\n\n return parsedErrors(response).join(\", \") || response?.message\n }\n\n function parsedErrors(response) {\n if (response?.errors) {\n return response.errors.map((error) =>\n typeof error === \"string\" && error.match(/Archived profiles/)\n ? error.replace(/Archived profiles/, \"Archived profiles.\")\n : error\n )\n } else {\n return []\n }\n }\n\n return (\n <StackView flex={1} whiteSpace=\"normal\">\n {!delivery ? (\n [\"duplicated\", \"ignored_duplicated\"].includes(status) ? (\n ERRORS.duplicated_event\n ) : (\n ERRORS.failed_without_deliveries\n )\n ) : (\n <ToggleableDetails\n details={responseErrors(delivery)}\n status={delivery.status}\n >\n {ERRORS[delivery.status] || ERRORS.default}\n </ToggleableDetails>\n )}\n </StackView>\n )\n }\n\n const message = statusMessage(status, lastDelivery)\n\n return message ? (\n <Box\n fontSize={token(\"--t-font-size-sm\")}\n fontStyle=\"italic\"\n lineHeight=\"16px\"\n maxWidth=\"100%\"\n paddingTop=\"1px\"\n whiteSpace=\"normal\"\n >\n {message}\n </Box>\n ) : null\n}\n\nfunction ToggleableDetails({\n children,\n details,\n status,\n}: {\n children: React.ReactNode\n details: string\n status: string\n}) {\n const [open, setOpen] = useState(false)\n\n function toggleOpen() {\n setOpen((was) => !was)\n }\n\n return (\n <StackView spacing={token(\"--t-spacing-1\")}>\n <Box>\n {children}{\" \"}\n {details && (\n <Button\n inline\n onClick={toggleOpen}\n size=\"xs\"\n theme=\"primary\"\n variant=\"naked\"\n fontStyle=\"normal\"\n >\n Details\n </Button>\n )}\n </Box>\n {open ? (\n <Box padding={1} background={token(\"--t-fill-color-neutral-090\")}>\n <Text\n fontFamily=\"monospace\"\n fontSize={token(\"--t-font-size-xs\")}\n lineHeight=\"1.2\"\n >\n {status && `${status}: `}\n {details}\n </Text>\n </Box>\n ) : null}\n </StackView>\n )\n}\n\ntype ErrorBoundaryProps = {\n children: React.ReactNode\n onRequestClose?: () => void\n}\n\ntype ErrorBoundaryState = {\n hasError: boolean\n}\n\nclass ErrorBoundary extends React.Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n constructor(props) {\n super(props)\n this.state = { hasError: false }\n }\n\n static getDerivedStateFromError() {\n return { hasError: true }\n }\n\n handleContactSupport = () => {\n if (this.props.onRequestClose) {\n this.props.onRequestClose()\n }\n window.openHelpdesk()\n }\n\n render() {\n if (this.state.hasError) {\n return (\n <Alert\n type=\"error\"\n marginVertical={1}\n padding={1.5}\n css={{ boxShadow: \"none\" }}\n >\n <Text lineHeight=\"1.35\">\n The application hit an unexpected error. If this persists after a\n few minutes, please let us know so we can get it fixed for you.{\" \"}\n <button\n style={{\n color: token(\"--t-text-color-interaction\"),\n whiteSpace: \"nowrap\",\n }}\n onClick={this.handleContactSupport}\n >\n Contact support\n </button>\n .\n </Text>\n </Alert>\n )\n }\n\n return this.props.children\n }\n}\n\n// eslint-disable-next-line react/display-name\nexport default (props: HistoryProps) => (\n <ErrorBoundary onRequestClose={props.onRequestClose}>\n <History {...props}></History>\n </ErrorBoundary>\n)\n","import { token } from \"@planningcenter/tapestry\"\nimport {\n Button,\n Heading,\n Modal,\n StackView,\n ThemeProvider,\n} from \"@planningcenter/tapestry-react\"\nimport React from \"react\"\nimport { createPortal } from \"react-dom\"\n\nfunction CloseModalIcon({ onClick }: { onClick: React.MouseEventHandler }) {\n return (\n <Button\n as=\"button\"\n height={token(\"--t-element-size-md\")}\n icon={{\n color: token(\"--t-icon-color-dim\"),\n name: \"general.x\",\n }}\n onClick={onClick}\n size=\"sm\"\n title=\"Close\"\n variant=\"naked\"\n />\n )\n}\n\nfunction HistoryModal({\n children,\n onRequestClose,\n open,\n theme,\n}: {\n children: React.ReactNode\n onRequestClose: () => void\n open: boolean\n theme: object\n}): React.ReactPortal | JSX.Element {\n return createPortal(\n <ThemeProvider theme={theme}>\n <Modal\n open={open}\n onRequestClose={onRequestClose}\n maxWidth={120}\n boxShadow=\"0 0 20px rgba(0, 0, 0, 0.15)\"\n padding={token(\"--t-spacing-4\")}\n paddingBottom={token(\"--t-spacing-3\")}\n radius={token(\"--t-border-radius-lg\")}\n >\n <StackView\n axis=\"horizontal\"\n distribution=\"space-between\"\n alignment=\"center\"\n >\n <Heading\n level={2}\n color={token(\"--t-text-color-headline\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n fontSize={token(\"--t-font-size-2xl\")}\n lineHeight=\"1.4\"\n >\n Automation history\n </Heading>\n <CloseModalIcon onClick={onRequestClose} />\n </StackView>\n {children}\n </Modal>\n </ThemeProvider>,\n document.body\n )\n}\n\nexport default HistoryModal\n","import { Logo } from \"@planningcenter/tapestry-react\"\nimport { kebabCase } from \"lodash\"\nimport type { ComponentProps } from \"react\"\n\n// Extract valid logo names from the Logo component's props\ntype ValidLogoName = NonNullable<ComponentProps<typeof Logo>[\"name\"]>\n\n// List of valid logo names from @planningcenter/tapestry-react Logo component\n// Update this list when support for new products are added to tapestry-react\nconst VALID_LOGO_NAMES: ValidLogoName[] = [\n \"api\",\n \"calendar\",\n \"check-ins\",\n \"church-center\",\n \"giving\",\n \"groups\",\n \"headcounts\",\n \"home\",\n \"login\",\n \"music-stand\",\n \"people\",\n \"planning-center\",\n \"publishing\",\n \"registrations\",\n \"services\",\n]\n\nexport const isValidLogoName = (name: string): name is ValidLogoName => {\n return VALID_LOGO_NAMES.includes(name as ValidLogoName)\n}\n\nexport const getValidLogoName = (name: string): ValidLogoName => {\n const kebabName = kebabCase(name)\n return isValidLogoName(kebabName) ? kebabName : \"planning-center\"\n}\n","import { Client } from \"@planningcenter/api-client\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { uniq } from \"lodash\"\n\nimport type { ResponseLabeler } from \"./types\"\n\nconst HIDDEN_FIELD = \"[Hidden Field]\"\nconst HIDDEN_RESPONSE = \"[Hidden Response]\"\nconst FIELD_KEY_RE = /^field_(\\d+)$/\nconst SENTINEL_VALUES = new Set([\"no-option\"])\n\nconst peopleClient = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n version: \"2025-03-20\",\n})\n\ntype FormFieldRecord = {\n fieldType: string\n fieldableId: number | null\n fieldableType: string | null\n id: number\n label: string | null\n options?: { id: number; label: string | null }[]\n}\n\ntype FieldDefinitionRecord = {\n dataType: string\n fieldOptions?: { id: number; value: string | null }[]\n id: number\n name: string | null\n}\n\ntype CampusRecord = {\n id: number\n name: string | null\n}\n\ntype ExtractedIds = {\n fieldId: string\n formId: string\n optionId: string | null\n}\n\nasync function resolve(\n subscriptions: AutomationInstance[]\n): Promise<AutomationInstance[]> {\n const extracted = subscriptions.map((sub) => ({\n ids: extractIds(sub),\n sub,\n }))\n const targets = extracted.filter(\n (entry): entry is { ids: ExtractedIds; sub: AutomationInstance } =>\n entry.ids !== null\n )\n if (targets.length === 0) return subscriptions\n\n const fieldsByForm = await fetchFormFields(\n uniq(targets.map((t) => t.ids.formId))\n )\n\n const fieldDefIds = new Set<string>()\n const campusIds = new Set<string>()\n for (const { ids } of targets) {\n const field = fieldsByForm.get(ids.formId)?.get(ids.fieldId)\n if (field?.fieldType === \"custom_field\" && field.fieldableId != null) {\n fieldDefIds.add(String(field.fieldableId))\n } else if (field?.fieldType === \"primary_campus\" && ids.optionId != null) {\n campusIds.add(ids.optionId)\n }\n }\n const [fieldDefs, campuses] = await Promise.all([\n fetchFieldDefinitions([...fieldDefIds]),\n fetchCampuses([...campusIds]),\n ])\n\n return extracted.map(({ ids, sub }) => {\n if (!ids) return sub\n return {\n ...sub,\n responseDetails: buildResponseDetails(\n ids,\n fieldsByForm,\n fieldDefs,\n campuses\n ),\n }\n })\n}\n\nfunction extractIds(subscription: AutomationInstance): ExtractedIds | null {\n const conds = subscription.triggerConditions\n const formId = conds?.data?.relationships?.form?.data?.id\n const selectedOptionsByField = conds?.data?.attributes?.selectedOptionsByField\n if (\n formId == null ||\n !selectedOptionsByField ||\n typeof selectedOptionsByField !== \"object\"\n ) {\n return null\n }\n\n for (const [key, value] of Object.entries(selectedOptionsByField)) {\n const match = FIELD_KEY_RE.exec(key)\n if (!match) continue\n const raw = (value as { $in?: unknown })?.$in\n const optionIds = (Array.isArray(raw) ? raw : raw == null ? [] : [raw])\n .map((id) => (id == null ? null : String(id)))\n .filter((id): id is string => id != null && !SENTINEL_VALUES.has(id))\n return {\n fieldId: match[1],\n formId: String(formId),\n optionId: optionIds[0] ?? null,\n }\n }\n return null\n}\n\nasync function fetchFormFields(\n formIds: string[]\n): Promise<Map<string, Map<string, FormFieldRecord>>> {\n const result = new Map<string, Map<string, FormFieldRecord>>()\n await Promise.all(\n formIds.map(async (formId) => {\n try {\n const { data } = await peopleClient.get<{ data: FormFieldRecord[] }>({\n data: {\n fields: {\n FormField: \"label,field_type,fieldable,options\",\n FormFieldOption: \"label\",\n },\n include: \"options\",\n walk: true,\n },\n url: `forms/${formId}/fields`,\n })\n const byId = new Map<string, FormFieldRecord>()\n for (const field of data) {\n byId.set(String(field.id), field)\n }\n result.set(formId, byId)\n } catch {\n result.set(formId, new Map())\n }\n })\n )\n return result\n}\n\nasync function fetchFieldDefinitions(\n ids: string[]\n): Promise<Map<string, FieldDefinitionRecord>> {\n const result = new Map<string, FieldDefinitionRecord>()\n if (ids.length === 0) return result\n\n try {\n const { data } = await peopleClient.get<{ data: FieldDefinitionRecord[] }>({\n data: {\n fields: {\n FieldDefinition: \"name,data_type,field_options\",\n FieldOption: \"value\",\n },\n include: \"field_options\",\n walk: true,\n where: { id: ids.join(\",\") },\n },\n url: \"field_definitions\",\n })\n for (const fd of data) {\n result.set(String(fd.id), fd)\n }\n } catch {\n // permission-denied or other failure: leave entries absent so the\n // resolver falls back to [Hidden response].\n }\n return result\n}\n\nasync function fetchCampuses(\n ids: string[]\n): Promise<Map<string, CampusRecord>> {\n const result = new Map<string, CampusRecord>()\n if (ids.length === 0) return result\n\n try {\n const { data } = await peopleClient.get<{ data: CampusRecord[] }>({\n data: {\n fields: { Campus: \"name\" },\n walk: true,\n where: { id: ids.join(\",\") },\n },\n url: \"campuses\",\n })\n for (const campus of data) {\n result.set(String(campus.id), campus)\n }\n } catch {\n // permission-denied or other failure: leave entries absent so the\n // resolver falls back to [Hidden response].\n }\n return result\n}\n\nfunction buildResponseDetails(\n ids: ExtractedIds,\n fieldsByForm: Map<string, Map<string, FormFieldRecord>>,\n fieldDefs: Map<string, FieldDefinitionRecord>,\n campuses: Map<string, CampusRecord>\n): ResponseDetails {\n const field = fieldsByForm.get(ids.formId)?.get(ids.fieldId)\n if (!field) return { fieldLabel: HIDDEN_FIELD, valueLabel: HIDDEN_RESPONSE }\n\n const fieldLabel = field.label || HIDDEN_FIELD\n\n if (field.fieldType === \"boolean\") {\n return { fieldLabel, valueLabel: null }\n }\n\n if (field.fieldType === \"custom_field\" && field.fieldableId != null) {\n const fd = fieldDefs.get(String(field.fieldableId))\n if (!fd) return { fieldLabel, valueLabel: HIDDEN_RESPONSE }\n if (fd.dataType === \"boolean\") return { fieldLabel, valueLabel: null }\n if (ids.optionId == null) return { fieldLabel, valueLabel: HIDDEN_RESPONSE }\n const match = (fd.fieldOptions || []).find(\n (o) => String(o.id) === ids.optionId\n )\n return { fieldLabel, valueLabel: match?.value || HIDDEN_RESPONSE }\n }\n\n if (field.fieldType === \"primary_campus\") {\n if (ids.optionId == null) return { fieldLabel, valueLabel: HIDDEN_RESPONSE }\n const campus = campuses.get(ids.optionId)\n return { fieldLabel, valueLabel: campus?.name || HIDDEN_RESPONSE }\n }\n\n if (ids.optionId == null) {\n return { fieldLabel, valueLabel: HIDDEN_RESPONSE }\n }\n const match = (field.options || []).find((o) => String(o.id) === ids.optionId)\n return { fieldLabel, valueLabel: match?.label || HIDDEN_RESPONSE }\n}\n\nconst peopleFormLabeler: ResponseLabeler = { resolve }\n\nexport { peopleFormLabeler }\n","import { peopleFormLabeler } from \"./response-labelers/people-form\"\nimport type { ResponseLabeler } from \"./response-labelers/types\"\n\nconst labelers: Record<string, ResponseLabeler> = {\n \"people.v2.events.form_submission.created\": peopleFormLabeler,\n}\n\nasync function resolveResponseDetails(\n subscriptions: AutomationInstance[]\n): Promise<AutomationInstance[]> {\n const groups = new Map<string, AutomationInstance[]>()\n for (const sub of subscriptions) {\n if (!labelers[sub.name]) continue\n const group = groups.get(sub.name) ?? []\n group.push(sub)\n groups.set(sub.name, group)\n }\n if (groups.size === 0) return subscriptions\n\n const resolvedById = new Map<number, AutomationInstance>()\n await Promise.all(\n [...groups.entries()].map(async ([name, subs]) => {\n const resolved = await labelers[name].resolve(subs)\n for (const sub of resolved) resolvedById.set(sub.id, sub)\n })\n )\n\n return subscriptions.map((sub) => resolvedById.get(sub.id) ?? sub)\n}\n\nfunction formatResponseDetails(\n responseDetails: ResponseDetails | null | undefined\n): string {\n if (!responseDetails) return \"\"\n const { fieldLabel, valueLabel } = responseDetails\n if (valueLabel == null) return ` with \"${fieldLabel}\" selected`\n return ` with \"${fieldLabel}\" selected as \"${valueLabel}\"`\n}\n\nexport { formatResponseDetails, resolveResponseDetails }\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Avatar,\n Box,\n Button,\n Card,\n Divider,\n Dropdown,\n Heading,\n Icon,\n Logo,\n StackView,\n Text,\n ToggleSwitch,\n Tooltip,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { lowerFirst, truncate } from \"lodash\"\nimport React, { createContext, useContext, useState } from \"react\"\n\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport History from \"./history\"\nimport HistoryModal from \"./history_modal\"\nimport * as alerts from \"./utils/alerts\"\nimport { getValidLogoName } from \"./utils/logos\"\nimport { formatResponseDetails } from \"./utils/resolve-response-details\"\nimport { dateLocalized, forbiddenText } from \"./utils/utils\"\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"2022-10-20\",\n})\nconst peopleClient = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n})\n\ntype AutomationProps = {\n automation: AutomationInstance\n currentPersonCanCreate: boolean\n currentPersonId: number\n disabled?: boolean\n disabledReason?: string\n trigger: {\n event: AutomationTriggerEvent\n resource: EncryptedTriggerResource\n }\n updateAutomation: React.Dispatch<React.SetStateAction<AutomationInstance>>\n}\n\ntype IncomingAutomationProps = {\n automation: IncomingAutomationInstance\n}\n\ntype EditableAutomationContextType = {\n automation: AutomationInstance\n currentPersonCanCreate?: boolean\n currentPersonId?: number\n theme: object\n trigger?: {\n event: AutomationTriggerEvent\n resource: EncryptedTriggerResource\n }\n updateAutomation?: React.Dispatch<React.SetStateAction<AutomationInstance>>\n}\n\ntype IncomingAutomationContextType = {\n automation: IncomingAutomationInstance\n}\n\nconst AutomationContext = createContext<\n EditableAutomationContextType | IncomingAutomationContextType\n>(null)\n\nfunction EditableAutomation({\n updateAutomation,\n onDelete,\n theme,\n openHistoryNow = false,\n disabled,\n disabledReason,\n ...props\n}: AutomationProps & {\n disabled: boolean\n disabledReason: string\n onDelete: (id: number) => void\n openHistoryNow: boolean\n theme?: object\n}) {\n return (\n <AutomationWrapper\n theme={theme}\n updateAutomation={updateAutomation}\n {...props}\n >\n <Header>\n <Icons />\n <Manage\n onDelete={onDelete}\n openHistoryNow={openHistoryNow}\n disabled={disabled}\n disabledReason={disabledReason}\n />\n </Header>\n <Description />\n <EditableFooter />\n </AutomationWrapper>\n )\n}\n\nfunction IncomingAutomation(props: IncomingAutomationProps) {\n return (\n <AutomationWrapper automation={props.automation}>\n <Header>\n <Icons />\n <LinkToAutomation />\n </Header>\n <IncomingDescription />\n <Footer />\n </AutomationWrapper>\n )\n}\n\nfunction IncomingDescription() {\n const { automation } = useContext(\n AutomationContext\n ) as IncomingAutomationContextType\n\n const triggerEventDescription = automation.triggerEventDescription\n const { name, description } = parseDescription(automation.description)\n const cardOpacity = !automation.active ? 0.5 : undefined\n\n return (\n <StackView\n paddingVertical={token(\"--t-spacing-2\")}\n flex={1}\n opacity={cardOpacity}\n >\n <Heading\n level={3}\n size={token(\"--t-font-size-xl\")}\n weight={token(\"--t-font-weight-medium\")}\n marginBottom={token(\"--t-spacing-half\")}\n truncate\n >\n {name}\n </Heading>\n <StackView spacing={0.75}>\n <Text\n size={token(\"--t-font-size-sm\")}\n color={token(\"--t-text-color\")}\n lineHeight=\"1.2\"\n >\n {triggerEventDescription}\n {formatResponseDetails(automation.responseDetails)}, then{\" \"}\n {lowerFirst(name)} {conditionalSuffix(automation)}\n </Text>\n <Text\n size={token(\"--t-font-size-xs\")}\n color={token(\"--t-text-color-secondary\")}\n lineHeight=\"1.2\"\n >\n {truncate(optionallyPrettifyArchivedPrefix(description), {\n length: 160,\n separator: \" \",\n })}\n </Text>\n </StackView>\n </StackView>\n )\n}\n\nfunction LinkToAutomation() {\n const { automation } = useContext(\n AutomationContext\n ) as IncomingAutomationContextType\n\n return (\n <Button\n external\n iconLeft={{ name: \"general.newWindow\" }}\n variant=\"naked\"\n size=\"sm\"\n to={automation.triggerAdminUrl}\n disabled={!automation.canManage}\n tooltip={\n !automation.canManage\n ? \"You do not have access to this resource\"\n : undefined\n }\n color={token(\"--t-text-color-secondary\")}\n hover={{\n backgroundColor: \"highlight\",\n color: token(\"--t-text-color-secondary\"),\n }}\n >\n Manage\n </Button>\n )\n}\n\nfunction AutomationWrapper({\n automation,\n updateAutomation,\n children,\n theme,\n ...rest\n}: (AutomationProps | IncomingAutomationProps) & {\n children: React.ReactNode\n theme?: object\n updateAutomation?: (automation: AutomationInstance) => void\n}) {\n return (\n <AutomationContext.Provider\n value={{\n automation,\n theme,\n updateAutomation,\n ...rest,\n }}\n >\n <Card radius={4} padding={2}>\n {children}\n </Card>\n </AutomationContext.Provider>\n )\n}\n\nfunction Header({ children }: { children: React.ReactNode }) {\n const { automation } = useContext(AutomationContext)\n\n const cardOpacity = !automation.active ? 0.5 : undefined\n\n return (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n padding={0}\n distribution=\"space-between\"\n opacity={cardOpacity}\n >\n {children}\n </StackView>\n )\n}\n\nfunction Manage({\n onDelete,\n openHistoryNow = false,\n disabled,\n disabledReason,\n}: {\n disabled: boolean\n disabledReason: string\n onDelete: (id: number) => void\n openHistoryNow: boolean\n}) {\n const {\n automation,\n currentPersonCanCreate,\n currentPersonId,\n trigger,\n theme,\n updateAutomation,\n } = useContext(AutomationContext) as EditableAutomationContextType\n const [historyVisible, setHistoryVisible] = useState(openHistoryNow)\n const isActive = automation.active\n const { name } = parseDescription(automation.description)\n\n function showHistory() {\n setHistoryVisible(true)\n }\n\n function updateEventsStatus(newStatus: AutomationInstance[\"eventsStatus\"]) {\n updateAutomation((prev) => ({ ...prev, eventsStatus: newStatus }))\n }\n\n function handleToggleActive() {\n webhooksClient\n .patch({\n data: {\n _e: trigger.resource,\n data: {\n attributes: {\n active: !isActive,\n },\n },\n },\n url: `/automation_subscriptions/${automation.id}`,\n })\n .then((data: { data: { active: boolean } }) => {\n updateAutomation((prev) => ({ ...prev, active: data.data.active }))\n })\n .catch((error) => {\n const text =\n forbiddenText(error, \"pause\") ||\n `There was a problem ${\n isActive ? \"pausing\" : \"unpausing\"\n } this automation. Please try again in a few moments.`\n alerts.alertError.fire({\n text,\n title: \"Uh oh!\",\n })\n })\n }\n\n function handleReassign() {\n alerts.confirm\n .fire({\n text: \"This automation will run with your permission levels. Other administrators who can see this automation can grant it their permissions by reassigning it to themselves.\",\n title: \"Reassign automation?\",\n })\n .then(({ isConfirmed }) => {\n if (isConfirmed) {\n webhooksClient\n .post({\n data: {\n _e: trigger.resource,\n data: { attributes: {} },\n },\n url: `/automation_subscriptions/${automation.id}/self_assign`,\n })\n .then(({ data }) => fetchCurrentPersonAvatar(data))\n .then(({ subscription, avatar }) => {\n updateAutomation((prev) => ({\n ...prev,\n createdBy: { ...prev.createdBy, avatarUrl: avatar },\n createdById: subscription.createdById,\n createdByName: subscription.createdByName,\n }))\n })\n .catch((error) => {\n const text =\n forbiddenText(error, \"update\") ||\n \"There was a problem updating this automation. Please try again in a few moments.\"\n alerts.alertError.fire({\n text,\n title: \"Uh oh!\",\n })\n })\n }\n })\n }\n\n function handleDelete() {\n alerts.confirmDestroy\n .fire({\n confirmButtonText: \"Yes, delete automation\",\n text: `Are you sure you want to delete the \"${name}\" automation? This cannot be undone.`,\n title: \"Delete this automation?\",\n })\n .then(({ isConfirmed }) => {\n if (isConfirmed) onDelete(automation.id)\n })\n }\n\n return (\n <>\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={0.75}>\n <Dropdown\n icon={{\n color: token(\"--t-icon-color\"),\n name: \"churchCenter.threeDots\",\n }}\n iconRight={false}\n title=\"Actions\"\n variant=\"naked\"\n size=\"md\"\n disabled={disabled}\n >\n <Dropdown.Item onSelect={() => showHistory()}>History</Dropdown.Item>\n {currentPersonCanCreate &&\n (automation.createdById === currentPersonId ? (\n <Dropdown.Item disabled={true}>\n <Tooltip\n placement=\"left\"\n openDelay={250}\n title=\"This automation is already assigned to you.\"\n >\n <Text>Reassign to me...</Text>\n </Tooltip>\n </Dropdown.Item>\n ) : (\n <Dropdown.Item onSelect={handleReassign}>\n Reassign to me...\n </Dropdown.Item>\n ))}\n <Dropdown.Item onSelect={handleDelete}>Delete...</Dropdown.Item>\n </Dropdown>\n <ToggleSwitch\n isChecked={isActive}\n size=\"sm\"\n onClick={handleToggleActive}\n tooltip={\n disabled\n ? disabledReason\n : isActive\n ? \"Pause automation\"\n : \"Enable automation\"\n }\n disabled={disabled}\n />\n </StackView>\n\n <HistoryModal\n open={historyVisible}\n onRequestClose={() => setHistoryVisible(false)}\n theme={theme}\n >\n <History\n automation={automation}\n triggerResource={trigger.resource}\n onEventsStatusChange={updateEventsStatus}\n onRequestClose={() => setHistoryVisible(false)}\n />\n </HistoryModal>\n </>\n )\n}\n\nfunction Icons() {\n const { automation } = useContext(AutomationContext)\n const triggerProductName = automation.name.split(\".\")[0]\n\n return (\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={0.5}>\n <Logo\n markOnly={true}\n name={getValidLogoName(triggerProductName)}\n size=\"sm\"\n theme=\"color\"\n />\n <Icon name=\"general.rightArrow\" size={1.5} />\n <Logo\n markOnly={true}\n name={getValidLogoName(automation.operationAppName)}\n size=\"sm\"\n theme=\"color\"\n />\n </StackView>\n )\n}\nfunction Footer() {\n const { automation } = useContext(AutomationContext)\n const { dateFormat } = useContext(OrganizationContext)\n const createdBySuffix = !automation.createdBy?.id ? \"(deleted profile)\" : \"\"\n const createdByName = `${automation.createdByName} ${createdBySuffix}`\n\n const cardOpacity = !automation.active ? 0.5 : undefined\n\n return (\n <>\n <Divider marginHorizontal={-2} />\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n distribution=\"space-between\"\n paddingTop={1.75}\n spacing={token(\"--t-spacing-1\")}\n opacity={cardOpacity}\n >\n <Text\n size={token(\"--t-font-size-xs\")}\n color={token(\"--t-text-color-placeholder\")}\n whiteSpace=\"nowrap\"\n >\n Updated {dateLocalized(automation.createdAt, dateFormat)}\n </Text>\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-half\")}\n maxWidth=\"calc(100% - 136px)\"\n >\n {automation.createdBy?.avatarUrl && (\n <Avatar\n width={2}\n height={2}\n basis={2}\n key={createdByName}\n source={automation.createdBy.avatarUrl}\n />\n )}\n <Text size={5} truncate>\n {createdByName}\n </Text>\n </StackView>\n </StackView>\n </>\n )\n}\n\nfunction EditableFooter() {\n const { dateFormat } = useContext(OrganizationContext)\n const { automation, trigger, theme, updateAutomation } = useContext(\n AutomationContext\n ) as EditableAutomationContextType\n\n const createdBySuffix = !automation.createdBy?.id ? \"(deleted profile)\" : \"\"\n const createdByName = `${automation.createdByName} ${createdBySuffix}`\n\n const cardOpacity = !automation.active ? 0.5 : undefined\n const buttonProps = {\n color: token(\"--t-text-color-secondary\"),\n fontSize: token(\"--t-font-size-xs\"),\n fontWeight: token(\"--t-font-weight-normal\"),\n paddingHorizontal: token(\"--t-spacing-1\"),\n radius: \"pill\",\n size: \"xs\",\n variant: \"naked\",\n }\n const [historyProps, setHistoryProps] = useState({\n filter: null,\n historyVisible: false,\n })\n\n function renderSkippedHistory() {\n setHistoryProps({ filter: \"skipped\", historyVisible: true })\n }\n\n function renderFailedOrDuplicatedHistory() {\n setHistoryProps({ filter: \"failed,duplicated\", historyVisible: true })\n }\n\n function handleEventsStatusChange(\n newStatus: AutomationInstance[\"eventsStatus\"]\n ) {\n updateAutomation((prev) => ({ ...prev, eventsStatus: newStatus }))\n }\n\n return (\n <>\n <Divider marginHorizontal={-2} />\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n distribution=\"space-between\"\n paddingTop={1.75}\n spacing={token(\"--t-spacing-1\")}\n opacity={cardOpacity}\n >\n <Text\n size={token(\"--t-font-size-xs\")}\n color={token(\"--t-text-color-placeholder\")}\n whiteSpace=\"nowrap\"\n >\n Updated {dateLocalized(automation.createdAt, dateFormat)}\n </Text>\n\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-fourth\")}\n >\n {!!automation.eventsStatus?.skipped && (\n <Button\n {...buttonProps}\n aria-label={`${automation.eventsStatus.skipped} skipped`}\n onClick={renderSkippedHistory}\n tooltip={`${automation.eventsStatus.skipped?.toLocaleString()} skipped events`}\n >\n <Box\n backgroundColor={token(\"--t-fill-color-status-warning\")}\n marginRight={token(\"--t-spacing-half\")}\n radius=\"circle\"\n height=\"10px\"\n width=\"10px\"\n padding={token(\"--t-spacing-fourth\")}\n >\n <Icon\n name={\"services.pause\"}\n size={\"6px\"}\n title={\"Skipped\"}\n color=\"white\"\n />\n </Box>\n {`${automation.eventsStatus.skipped?.toLocaleString()}`}\n </Button>\n )}\n {!!automation.eventsStatus?.failed && (\n <Button\n {...buttonProps}\n aria-label={`${automation.eventsStatus.failed} failed`}\n iconLeft={{\n color: token(\"--t-icon-color-status-error\"),\n marginRight: token(\"--t-spacing-half\"),\n name: \"general.exclamationTriangle\",\n size: \"10px\",\n title: \"Failed\",\n }}\n onClick={renderFailedOrDuplicatedHistory}\n title={`${automation.eventsStatus.failed?.toLocaleString()}`}\n tooltip={`${automation.eventsStatus.failed?.toLocaleString()} failed events`}\n />\n )}\n </StackView>\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n distribution=\"end\"\n flex={1}\n spacing={token(\"--t-spacing-half\")}\n marginLeft=\"auto\"\n >\n {automation.createdBy?.avatarUrl && (\n <Avatar\n width={token(\"--t-element-size-md\")}\n height={token(\"--t-element-size-md\")}\n basis={token(\"--t-element-size-md\")}\n key={createdByName}\n source={automation.createdBy.avatarUrl}\n />\n )}\n <Text size={token(\"--t-font-size-sm\")} truncate>\n {createdByName}\n </Text>\n </StackView>\n </StackView>\n\n <HistoryModal\n open={historyProps.historyVisible}\n onRequestClose={() =>\n setHistoryProps({ filter: null, historyVisible: false })\n }\n theme={theme}\n >\n <History\n automation={automation}\n triggerResource={trigger.resource}\n filterWhere={historyProps.filter}\n onEventsStatusChange={handleEventsStatusChange}\n onRequestClose={() =>\n setHistoryProps({ filter: null, historyVisible: false })\n }\n />\n </HistoryModal>\n </>\n )\n}\n\nfunction Description() {\n const { automation, trigger } = useContext(\n AutomationContext\n ) as EditableAutomationContextType\n\n const { name, description } = parseDescription(automation.description)\n const cardOpacity = !automation.active ? 0.5 : undefined\n\n const triggerEventDescription = [\n \"When a person\",\n lowerFirst(trigger.event.description) +\n formatResponseDetails(automation.responseDetails) +\n \",\",\n \"then\",\n lowerFirst(name),\n conditionalSuffix(automation),\n ].join(\" \")\n\n return (\n <StackView\n paddingVertical={token(\"--t-spacing-2\")}\n flex={1}\n opacity={cardOpacity}\n >\n <Heading\n level={3}\n size={token(\"--t-font-size-xl\")}\n weight={token(\"--t-font-weight-bold\")}\n marginBottom={token(\"--t-spacing-half\")}\n truncate\n >\n {name}\n </Heading>\n <StackView spacing={0.75}>\n <Text\n size={token(\"--t-font-size-sm\")}\n color={token(\"--t-text-color\")}\n lineHeight=\"1.2\"\n >\n {triggerEventDescription}\n </Text>\n <Text\n size={token(\"--t-font-size-xs\")}\n color={token(\"--t-text-color-secondary\")}\n lineHeight=\"1.2\"\n >\n {truncate(optionallyPrettifyArchivedPrefix(description), {\n length: 160,\n separator: \" \",\n })}\n </Text>\n </StackView>\n </StackView>\n )\n}\n\nfunction conditionalSuffix(automation: AutomationInstance) {\n return automation?.triggerParams?.useTriggerPersonOverride\n ? \"(also applies to joint donor)\"\n : \"\"\n}\n\nfunction parseDescription(description: string) {\n const match = /^(.+?)\\(([^()]*?)\\)$/.exec(description)\n\n if (match) {\n return { description: match[\"2\"], name: match[\"1\"].trim() }\n } else {\n return { name: description }\n }\n}\n\nfunction optionallyPrettifyArchivedPrefix(description: string) {\n if (description?.startsWith(\"[archived]\")) {\n return description.replace(\"[archived]\", \"[Archived]\")\n } else {\n return description\n }\n}\n\nasync function fetchCurrentPersonAvatar(subscription: AutomationInstance) {\n const {\n data: { avatar },\n } = await peopleClient.get({\n data: {\n fields: { Person: \"avatar\" },\n },\n url: \"me\",\n })\n\n return { avatar, subscription }\n}\n\nexport { EditableAutomation, IncomingAutomation }\n","import { Client } from \"@planningcenter/api-client\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { compact, uniq } from \"lodash\"\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"2022-10-20\",\n})\nconst peopleClient = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n})\n\nasync function fetchAutomations(triggerResource: EncryptedTriggerResource) {\n const { data } = await webhooksClient.get({\n data: {\n _e: triggerResource,\n fields: {\n AutomationSubscription:\n \"id,description,created_at,created_by,operation_app_name,operation_definition_class_name,operation_params,active,created_by_name,name,trigger_admin_url,events_status,trigger_conditions,trigger_params\",\n Person: \"name\",\n },\n include: \"created_by\",\n },\n url: \"automation_subscriptions\",\n })\n\n return data\n}\n\nasync function fetchCreatorProfiles(subscriptions: AutomationInstance[]) {\n const personIds = compact(\n uniq(subscriptions.map((subscription) => subscription.createdById))\n )\n\n try {\n const { data: profiles } = await peopleClient.get({\n data: {\n fields: { Person: \"avatar\" },\n where: { id: personIds.join(\",\") },\n },\n url: \"people\",\n })\n return { profiles, subscriptions }\n } catch (error) {\n return { profiles: [], subscriptions }\n }\n}\n\nfunction mergeProfilesAndSubscriptions({\n profiles,\n subscriptions,\n}: {\n profiles: { avatar: string; id: number }[]\n subscriptions: AutomationInstance[]\n}) {\n const subscriptionsWithAvatars = subscriptions.map((subscription) => {\n const avatar = profiles.find(\n (profile) => profile.id === subscription.createdById\n )\n return {\n ...subscription,\n createdBy: { ...subscription.createdBy, avatarUrl: avatar?.avatar },\n }\n })\n\n return subscriptionsWithAvatars\n}\n\nasync function fetchPersonApps() {\n return peopleClient\n .get({\n data: {\n fields: { App: [\"name\"], PersonApp: [\"app\", \"allow_pco_login\"] },\n include: [\"app\"],\n },\n url: `/me/person_apps`,\n })\n .then(({ data }) => {\n return data\n .filter((personApp: PersonApp) => personApp.allowPcoLogin)\n .map((personApp: PersonApp) => personApp.app.name.toLowerCase())\n })\n}\n\nexport {\n fetchAutomations,\n fetchCreatorProfiles,\n fetchPersonApps,\n mergeProfilesAndSubscriptions,\n}\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Box,\n Heading,\n Spinner,\n Summary,\n Text,\n TileView,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport { truncate, upperFirst } from \"lodash\"\nimport React, { useEffect, useState } from \"react\"\n\nimport { IncomingAutomation } from \"./automation\"\nimport {\n fetchCreatorProfiles,\n fetchPersonApps,\n mergeProfilesAndSubscriptions,\n} from \"./utils/fetch-automations\"\nimport { resolveResponseDetails } from \"./utils/resolve-response-details\"\nimport {\n deobfuscateDescriptions,\n pluralize,\n singularize,\n triggerResourceParts,\n} from \"./utils/utils\"\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"2022-10-20\",\n})\n\nasync function fetchIncomingAutomations(encryptedParam) {\n const { data } = await webhooksClient.get({\n data: {\n _e: encryptedParam,\n fields: {\n AutomationSubscription:\n \"id,description,created_at,created_by,operation_app_name,operation_definition_class_name,operation_params,active,created_by_name,name,trigger_admin_url,trigger_conditions,trigger_resource,trigger_params\",\n Person: \"name\",\n },\n include: \"created_by\",\n },\n url: \"incoming_automation_subscriptions\",\n })\n\n return data\n}\n\nasync function fetchTriggerResources(automations) {\n // We can optimize the query by fetching all the resources at once if we know\n // that the endpoint supports querying by multiple ids. Otherwise, we'll have\n // to fetch each resource individually.\n const QUERYABLE_BY_MULTIPLE_IDS = {\n people: [\"forms\", \"lists\"],\n registrations: [\"events\"],\n services: [\"teams\"],\n }\n const NOT_QUERYABLE = [\"giving\"]\n\n const automationsByModel = automations.reduce((accumulator, automation) => {\n // registrations has a weird case of signup vs event\n const automationTriggerResource = automation.triggerResource.replace(\n /signup/,\n \"event\"\n )\n const { appName, resourceType, resourcePath, resourceId } =\n triggerResourceParts(automationTriggerResource)\n\n if (!accumulator[appName]) accumulator[appName] = {}\n if (!accumulator[appName][resourceType])\n accumulator[appName][resourceType] = {}\n if (!accumulator[appName][resourceType][\"resoucePath\"])\n accumulator[appName][resourceType][\"resourcePath\"] = resourcePath\n\n if (!accumulator[appName][resourceType][\"ids\"])\n accumulator[appName][resourceType][\"ids\"] = []\n\n accumulator[appName][resourceType][\"ids\"].push(resourceId)\n\n return accumulator\n }, {})\n\n const promises = Object.keys(automationsByModel).flatMap((appName) => {\n const automationsByResourceType = automationsByModel[appName]\n\n return Object.entries(automationsByResourceType).flatMap(\n ([resourceType, resourceParts]) => {\n const fetchFn = NOT_QUERYABLE.includes(appName)\n ? fetchNothing\n : QUERYABLE_BY_MULTIPLE_IDS[appName]?.includes(resourceType)\n ? fetchAllAtOnce\n : fetchOneAtATime\n\n return fetchFn({\n appName,\n ids: resourceParts[\"ids\"],\n resourcePath: resourceParts[\"resourcePath\"],\n resourceType,\n })\n }\n )\n })\n\n const results = await Promise.allSettled(promises)\n\n return {\n automations,\n triggerResources: collectSuccessfulResults(results),\n }\n}\n\nfunction collectSuccessfulResults(settledPromises) {\n return settledPromises\n .reduce((acc, result) => {\n if (result.status === \"fulfilled\") acc = acc.concat(result.value)\n\n return acc\n }, [])\n .flatMap((d) => d.data)\n}\n\nfunction fetchAllAtOnce({ appName, resourcePath, resourceType, ids }) {\n return fetchResourceName({\n appName,\n params: {\n where: { id: ids.join(\",\") },\n },\n path: resourcePath,\n resourceType,\n })\n}\n\nfunction fetchOneAtATime({ appName, resourcePath, resourceType, ids }) {\n return ids.map((id) =>\n fetchResourceName({\n appName,\n path: `${resourcePath}/${id}`,\n resourceType,\n })\n )\n}\n\nfunction fetchNothing(_props: object) {\n return new Promise((_, reject) => {\n reject()\n })\n}\n\n// TODO (maybe): move these to webhooks, return the verb in the API response,\n// so new events don't need a code change in both places\nfunction mapNameToVerb(messageName) {\n // e.g. \"groups.v2.events.membership.created\" => \"groups.membership.created\"\n const appResourceAction = messageName.replace(\"v2.events.\", \"\")\n\n switch (appResourceAction) {\n case \"groups.membership.created\":\n return \"joins\"\n case \"groups.membership.destroyed\":\n return \"leaves\"\n case \"people.list_result.created\":\n case \"services.team_person.created\":\n return \"is added to\"\n case \"people.list_result.destroyed\":\n case \"services.team_person.destroyed\":\n return \"is removed from\"\n case \"people.form_submission.created\":\n return \"submits\"\n case \"registrations.attendee.created\":\n return \"is registered as a new attendee for\"\n case \"registrations.attendee.cancelled\":\n return \"is canceled as an attendee for\"\n case \"registrations.registration.created\":\n return \"is the registration contact on a new registration for\"\n case \"registrations.registration.cancelled\":\n return \"is the registration contact on a canceled registration for\"\n default:\n return null\n }\n}\n\nfunction buildGivingDescription(automation: AutomationInstance) {\n const action = automation.name.replace(\"giving.v2.events.\", \"\")\n\n switch (action) {\n case \"donation.payment_successful\":\n return \"When a person gives\"\n case \"profile.first_donated_automation\":\n return \"When a person gives for the first time\"\n case \"recurring_donation.setup_successful\":\n return \"When a person sets up a recurring donation\"\n default:\n return null\n }\n}\n\nfunction buildDescription(automation, triggerResourceName) {\n const verb = mapNameToVerb(automation.name)\n\n const { resourceType } = triggerResourceParts(automation.triggerResource)\n\n if (!verb) {\n // No verb mapping for this message name, so just show something generic\n const resourceName = truncate(triggerResourceName, {\n length: 160,\n separator: \" \",\n })\n\n return `When the automation is triggered from ${singularize(\n resourceType\n )} \"${resourceName}\"`\n }\n\n return `When a person ${verb} ${singularize(\n resourceType\n )} \"${triggerResourceName}\"`\n}\n\nfunction fetchResourceName({\n appName,\n path,\n resourceType,\n params = {},\n}): Promise<any> {\n const client = new Client({ root: pcoApiUrl(appName, { squiggly: false }) })\n const model = upperFirst(singularize(resourceType))\n\n return client.get({\n data: {\n fields: {\n [model]: [\"name\", \"name_or_description\"],\n },\n ...params,\n },\n url: path,\n })\n}\n\nfunction mergeTriggerResourceEventDescriptions({\n automations,\n triggerResources,\n operationApps,\n}) {\n return automations.map((automation) => {\n const { appName, resourceType, resourceId } = triggerResourceParts(\n automation.triggerResource\n )\n\n if (appName === \"giving\") {\n automation.triggerEventDescription = buildGivingDescription(automation)\n automation.canManage = operationApps.find((app) => app === \"giving\")\n\n return automation\n }\n\n // find the result that matches this automation\n const result = triggerResources.find(\n (tr) => tr.id.toString() == resourceId.toString()\n )\n\n const resourceName = result\n ? result.name || result.nameOrDescription\n : `[Hidden ${upperFirst(singularize(resourceType))}]`\n\n automation.triggerEventDescription = buildDescription(\n automation,\n resourceName\n )\n\n automation.canManage = !!result\n\n return automation\n })\n}\n\nfunction IncomingAutomations({\n encryptedParam,\n trigger,\n}: {\n encryptedParam: string\n trigger?: AutomationTrigger\n}) {\n const [loading, setLoading] = useState(true)\n const [automations, setAutomations] = useState<IncomingAutomationInstance[]>()\n\n useEffect(() => {\n fetchPersonApps().then((operationApps) => {\n fetchIncomingAutomations(encryptedParam)\n .then(fetchCreatorProfiles)\n .then(mergeProfilesAndSubscriptions)\n .then(deobfuscateDescriptions)\n .then(resolveResponseDetails)\n .then(fetchTriggerResources)\n .then(({ automations, triggerResources }) =>\n mergeTriggerResourceEventDescriptions({\n automations,\n operationApps,\n triggerResources,\n })\n )\n .then(setAutomations)\n .then(() => setLoading(false))\n })\n }, [encryptedParam])\n\n const noResults = !loading && automations.length === 0\n\n return (\n <>\n <Box\n borderBottom={`1px solid ${token(\"--t-border-color\")}`}\n marginBottom={token(\"--t-spacing-2\")}\n marginHorizontal={-3}\n marginTop={trigger ? 12 : 0}\n paddingHorizontal={token(\"--t-spacing-3\")}\n paddingVertical={token(\"--t-spacing-2\")}\n >\n <Heading\n color={token(\"--t-text-color-headline\")}\n level={2}\n size={token(\"--t-font-size-lg\")}\n >\n {loading\n ? \"Incoming automations\"\n : pluralize(automations.length, \"incoming automation\")}\n </Heading>\n </Box>\n {noResults ? (\n <Text\n color={token(\"--t-text-color-secondary\")}\n marginVertical={token(\"--t-spacing-3\")}\n >\n Automations that perform actions on this resource will be listed here.\n </Text>\n ) : loading ? (\n <Summary\n image={<Spinner size=\"xl\" />}\n paddingVertical={10}\n title={\"Loading incoming automations...\"}\n />\n ) : (\n <TileView\n spacing={token(\"--t-spacing-3\")}\n marginVertical={token(\"--t-spacing-3\")}\n minCellWidth={45}\n >\n {automations.map((automation) => (\n <IncomingAutomation key={automation.id} automation={automation} />\n ))}\n </TileView>\n )}\n </>\n )\n}\n\nexport default IncomingAutomations\n","import { token } from \"@planningcenter/tapestry\"\nimport { Select, StackView } from \"@planningcenter/tapestry-react\"\nimport { groupBy, uniqBy } from \"lodash\"\nimport React from \"react\"\n\nfunction operationDefinitionId(od: OperationDefinition) {\n return `OPERATION_${od.definitionClass}${od.definitionIdentifier || \"\"}`\n}\n\nfunction sectionId(section: string) {\n return `SECTION_${section}`\n}\n\nfunction idType(value: string) {\n if (value.startsWith(\"SECTION\")) {\n return \"section\"\n } else if (value.startsWith(\"OPERATION\")) {\n return \"operation\"\n } else if (!value) {\n return null\n } else {\n throw new Error(`Unexpected value: ${value}`)\n }\n}\n\nfunction renderOptionsWithoutConsideringGroup(\n options: { label: string; value: string | number }[]\n) {\n return options.map(({ label, value }) => (\n <Select.Option key={value} value={value}>\n {label}\n </Select.Option>\n ))\n}\n\nfunction renderOptions(\n options: { group?: string | null; label: string; value: string | number }[]\n) {\n const groupedOptions = groupBy(options, \"group\")\n const groupTypes = Object.keys(groupedOptions).sort()\n return groupTypes.map((gt) =>\n gt === \"null\" ? (\n renderOptionsWithoutConsideringGroup(groupedOptions[gt])\n ) : (\n <Select.OptionGroup key={gt} title={gt}>\n {renderOptionsWithoutConsideringGroup(groupedOptions[gt])}\n </Select.OptionGroup>\n )\n )\n}\n\nconst Definition = ({\n selectedOperation,\n onOperationDefinitionChange,\n operationDefinitions,\n}: {\n onOperationDefinitionChange: Function\n operationDefinitions: OperationDefinition[]\n selectedOperation: OperationDefinition\n}) => {\n const selectedSection = selectedOperation?.section\n\n const operationDefinitionsWithUniqueIds = operationDefinitions.map((od) => ({\n ...od,\n id: operationDefinitionId(od),\n }))\n\n const primaryOperations = operationDefinitionsWithUniqueIds.filter(\n (od) => od.section === null\n )\n\n const primarySectionOptions = uniqBy(operationDefinitions, \"section\")\n .filter((od) => !!od.section)\n .map((od) => ({\n group: od.sectionGroup,\n label: od.section,\n value: sectionId(od.section),\n }))\n\n const secondaryOperations = selectedSection\n ? operationDefinitionsWithUniqueIds.filter(\n (od) => od.section === selectedSection\n )\n : []\n\n function handleAnySelectChange({ selectedValue }) {\n switch (idType(selectedValue)) {\n case \"section\":\n onOperationDefinitionChange(\n operationDefinitions.find(\n (od) => sectionId(od.section) === selectedValue\n )\n )\n break\n case \"operation\":\n onOperationDefinitionChange(\n operationDefinitions.find(\n (od) => operationDefinitionId(od) === selectedValue\n )\n )\n break\n case null:\n onOperationDefinitionChange(null)\n break\n }\n }\n\n function renderOperations(operations: OperationDefinition[]) {\n const operationsAsOptions = operations.map((o) => ({\n group: o.group,\n label: o.description,\n value: o.id,\n }))\n\n return renderOptions(operationsAsOptions)\n }\n\n return (\n <StackView spacing={token(\"--t-spacing-1\")}>\n <Select\n emptyValue=\"Select an action\"\n id=\"select-action\"\n onChange={handleAnySelectChange}\n size=\"lg\"\n data-testid=\"operation-select\"\n >\n {renderOperations(primaryOperations)}\n {renderOptions(primarySectionOptions)}\n </Select>\n {secondaryOperations.length > 0 && (\n <Select\n defaultValue={secondaryOperations[0].id}\n onChange={handleAnySelectChange}\n size=\"lg\"\n >\n {renderOperations(secondaryOperations)}\n </Select>\n )}\n </StackView>\n )\n}\n\nexport default Definition\n","import { token } from \"@planningcenter/tapestry\"\nimport {\n Alert,\n Avatar,\n Badge,\n Box,\n Checkbox as TapestryCheckbox,\n Combobox as TapestryCombobox,\n DateField as TapestryDateField,\n HelperDrawer,\n Highlight,\n Icon,\n Input,\n Menu,\n NumberField as TapestryNumberField,\n Radio,\n Select as TapestrySelect,\n Spinner,\n StackView,\n Text,\n TextArea as TapestryTextArea,\n} from \"@planningcenter/tapestry-react\"\nimport { camelCase, debounce, groupBy, isEqual, sortBy, uniqBy } from \"lodash\"\nimport moment from \"moment\"\nimport React, {\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from \"react\"\n\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport {\n dateFNSFormat,\n dateLocalized,\n fieldListIdentifier,\n} from \"./utils/utils\"\n\nfunction fieldDependencies({\n field,\n selectedFieldOptions,\n}: {\n field: DefinitionField\n selectedFieldOptions: { [k: string]: any }\n}) {\n const dependsOn = field.dependsOn || []\n return dependsOn.reduce((acc, depKey) => {\n if (Object.prototype.hasOwnProperty.call(selectedFieldOptions, depKey)) {\n acc[camelCase(depKey)] = selectedFieldOptions[depKey]\n }\n return acc\n }, {})\n}\n\nfunction useMemoizedObject(generator) {\n const [memoizedObject, setMemoizedObject] = useState(generator)\n\n useEffect(() => {\n const newObject = generator()\n\n if (!isEqual(newObject, memoizedObject)) {\n setMemoizedObject(newObject)\n }\n }, [generator, memoizedObject])\n\n return memoizedObject\n}\n\nconst Field = ({\n canAccessPeople,\n field,\n onChange,\n value,\n selectedFieldOptions,\n loadListForField,\n loadedLists,\n loadingLists,\n}: {\n canAccessPeople: boolean\n field: DefinitionField\n loadListForField: LoadListForField\n loadedLists: { [k: string]: LoadedList[] }\n loadingLists: { [k: string]: boolean }\n onChange: Function\n selectedFieldOptions: { [k: string]: any }\n value: any\n}) => {\n const dependencies = useMemoizedObject(() =>\n fieldDependencies({ field, selectedFieldOptions })\n )\n\n useEffect(() => {\n if (field.listClass) {\n loadListForField({ dependencies, field })\n }\n }, [field, dependencies, loadListForField])\n\n if (field.kind === \"Hidden\") return null\n\n const listOptions =\n field.list || loadedLists[fieldListIdentifier(field)] || []\n\n const actionAllowedOptions = listOptions.filter(\n (op) => !op.automationNotAllowed\n )\n\n const loading = field.listClass && loadingLists[fieldListIdentifier(field)]\n\n function renderField() {\n switch (field.kind) {\n case \"Select\":\n return (\n <Select\n fieldId={field.id}\n listOptions={actionAllowedOptions}\n onChange={onChange}\n value={value}\n description={field.description}\n disabled={field.disabled}\n />\n )\n case \"SelectSearch\":\n return (\n <SelectSearch\n fieldId={field.id}\n listOptions={actionAllowedOptions}\n onChange={onChange}\n value={value}\n />\n )\n case \"Checkbox\":\n return <Checkbox field={field} value={value} onChange={onChange} />\n case \"TextArea\":\n return <TextArea field={field} onChange={onChange} value={value} />\n\n case \"DateField\":\n return <DateField field={field} onChange={onChange} value={value} />\n case \"Checkboxes\":\n return (\n <Checkboxes\n fieldId={field.id}\n options={actionAllowedOptions}\n onChange={onChange}\n />\n )\n case \"NumberField\":\n return <NumberField field={field} onChange={onChange} value={value} />\n case \"PersonSearch\":\n return (\n <PersonSearch\n canAccessPeople={canAccessPeople}\n field={field}\n onChange={onChange}\n listOptions={listOptions}\n isLoading={loadingLists[fieldListIdentifier(field)]}\n loadListForField={loadListForField}\n value={value}\n />\n )\n case \"TextField\":\n return <TextField field={field} onChange={onChange} value={value} />\n case \"RadioButtons\":\n return (\n <RadioButtons\n field={field}\n options={listOptions}\n onChange={onChange}\n value={value}\n />\n )\n case \"StaticText\":\n return <Text dangerouslySetInnerHTML={{ __html: field.content }} />\n default:\n console.warn(`Unknown field kind \"${field.kind}\"`)\n return null\n }\n }\n\n return (\n <StackView marginBottom={2} spacing={0.5}>\n <Input.InputLabel\n color={token(\"--t-text-color-headline\")}\n fontSize={token(\"--t-font-size-sm\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n controls={field.id}\n >\n {field.description}\n {field.info && (\n <HelperDrawer.Toggle drawerId={`${field.id}_help`} marginLeft={1} />\n )}\n </Input.InputLabel>\n <Box>{loading ? <Loading /> : renderField()}</Box>\n {field.info && (\n <HelperDrawer\n id={`${field.id}_help`}\n marginTop={token(\"--t-spacing-half\")}\n >\n <Box dangerouslySetInnerHTML={{ __html: field.info }} />\n </HelperDrawer>\n )}\n </StackView>\n )\n}\n\nconst Select = ({\n fieldId,\n listOptions,\n onChange,\n value,\n description,\n disabled,\n}: {\n description?: string\n disabled?: boolean\n fieldId: string\n listOptions: LoadedList[]\n onChange: Function\n value: any\n}) => {\n const overridenEmptyValue = listOptions?.find(\n (option) => option.value === \"no-option\"\n )\n const groupedOptions = groupBy(listOptions, \"group\")\n const groupTypes = Object.keys(groupedOptions).sort()\n const renderOptions = () => {\n return groupTypes.map((gt) =>\n gt === \"null\" || gt === \"undefined\" ? (\n renderOptionsWithoutConsideringGroup(groupedOptions[gt])\n ) : (\n <TapestrySelect.OptionGroup key={gt} title={gt}>\n {renderOptionsWithoutConsideringGroup(groupedOptions[gt])}\n </TapestrySelect.OptionGroup>\n )\n )\n }\n\n const renderOptionsWithoutConsideringGroup = (\n items: { description: string; disabled?: boolean; value: string | number }[]\n ) => {\n return items.map((item) => (\n <TapestrySelect.Option\n key={item.value}\n value={item.value.toString()}\n disabled={item.disabled}\n >\n {item.description}\n </TapestrySelect.Option>\n ))\n }\n\n const handleSelectedValueChange = ({ selectedValue }) => {\n onChange({ fieldId, value: selectedValue })\n }\n\n const generatePrompt = (word: string) => {\n let prompt = `Select `\n if (!word) {\n prompt += \"a value\"\n } else if ([\"a\", \"e\", \"i\", \"o\", \"u\"].includes(word.charAt(0))) {\n prompt += `an ${word}`\n } else {\n prompt += `a ${word}`\n }\n return prompt\n }\n\n const renderEmptyValue = () => {\n if (renderOptions().length === 0) return \"No options available\"\n return (\n overridenEmptyValue?.description ||\n generatePrompt(description?.toLowerCase())\n )\n }\n\n return (\n <TapestrySelect\n id={fieldId}\n onChange={handleSelectedValueChange}\n disabled={renderOptions().length < 1 || !!disabled}\n emptyValue={renderEmptyValue()}\n size=\"lg\"\n value={value || overridenEmptyValue?.value || null}\n placement=\"bottom-start\"\n >\n {renderOptions()}\n </TapestrySelect>\n )\n}\n\nconst SelectSearch = ({\n fieldId,\n listOptions,\n onChange,\n value,\n}: {\n fieldId: string\n listOptions: LoadedList[]\n onChange: Function\n value?: string\n}) => {\n const selectedOption: LoadedList = listOptions.find(\n (option) => option.value?.toString() === value\n )\n const selectedLabel = selectedOption?.description || \"\"\n const [prevSelectedLabel, setPrevSelectedLabel] = useState(\"\")\n const [query, setQuery] = useState(selectedLabel)\n const [showFilteredOptions, setShowFilteredOptions] = useState(false)\n const [showClearButton, setShowClearButton] = useState(false)\n\n if (selectedLabel !== prevSelectedLabel) {\n setPrevSelectedLabel(selectedLabel)\n setQuery(selectedLabel)\n setShowFilteredOptions(false)\n }\n\n let filteredOptions = sortBy(uniqBy(listOptions, \"value\"), \"group\")\n\n if (showFilteredOptions) {\n const formattedQuery = query.toLowerCase()\n filteredOptions = filteredOptions.filter((option) => {\n const optionText = `${option.description} ${option.group}`.toLowerCase()\n return optionText.includes(formattedQuery)\n })\n }\n\n const handleValueChange = (value: string) => {\n onChange({ fieldId, value })\n }\n\n return (\n <TapestryCombobox.Popover\n closeOnSelect\n closeButton={{ icon: { size: \"md\" } }}\n css={{\n \"[role='combobox']\": {\n cursor: listOptions.length > 0 ? \"pointer\" : \"not-allowed\",\n },\n }}\n cursor=\"pointer\"\n disabled={listOptions.length === 0}\n onBlur={() => {\n setShowClearButton(false)\n setQuery(selectedLabel)\n }}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\n setQuery(e.target.value)\n setShowFilteredOptions(true)\n setShowClearButton(true)\n }}\n onClear={\n showClearButton\n ? () => {\n setQuery(\"\")\n setShowFilteredOptions(false)\n }\n : undefined\n }\n onFocus={(e: React.ChangeEvent<HTMLInputElement>) => e.target.select()} // select all text on focus\n onSelect={(option: { description: string; value: string }) => {\n handleValueChange(option.value)\n setQuery(option.description)\n setShowFilteredOptions(false)\n setShowClearButton(false)\n }}\n openOnFocus\n paddingLeft={4.5}\n placeholder={\n listOptions.length > 0 ? \"Select an option\" : \"No options available\"\n }\n placement=\"bottom-start\"\n popoverProps={{\n matchWidths: \"minimum\",\n }}\n renderLeft={<Icon name=\"general.search\" size=\"md\" />}\n renderRight={<Icon name=\"general.downCaret\" />}\n size=\"lg\"\n value={query}\n >\n {listOptions.length > 0 && (\n <>\n {filteredOptions.length > 0 ? (\n filteredOptions.map((option: LoadedList, index: number) => {\n const isCurrent = option.value.toString() === value\n return (\n <TapestryCombobox.Item\n aria-label={option.description}\n disabled={option.disabled}\n index={index}\n key={option.value}\n paddingLeft={4.25}\n renderLeft={\n <Icon\n marginLeft={-0.5}\n name={isCurrent ? \"general.check\" : \"\"}\n size=\"sm\"\n />\n }\n role=\"option\"\n spacing={token(\"--t-spacing-1\")}\n value={{\n description: option.description,\n value: option.value.toString(),\n }}\n >\n <Text truncate>\n <Highlight text={option.description} query={query} />\n </Text>\n {option.group && (\n <Badge\n title={<Highlight text={option.group} query={query} />}\n size=\"sm\"\n marginLeft=\"auto\"\n />\n )}\n </TapestryCombobox.Item>\n )\n })\n ) : (\n <Menu.Item>\n <Text>No results for &quot;{query}&quot;</Text>\n </Menu.Item>\n )}\n </>\n )}\n </TapestryCombobox.Popover>\n )\n}\n\nconst PersonSearch = ({\n canAccessPeople,\n field,\n isLoading,\n listOptions,\n loadListForField,\n onChange,\n value,\n}: {\n canAccessPeople: boolean\n field: DefinitionField\n isLoading: boolean\n listOptions: LoadedList[]\n loadListForField: LoadListForField\n onChange: Function\n value?: string\n}) => {\n const immediateSearch = useCallback(\n (query: string) => {\n loadListForField({ dependencies: { query }, field })\n },\n [loadListForField]\n )\n\n const debouncedSearch = useMemo(\n () => debounce(immediateSearch, 300),\n [immediateSearch]\n )\n\n const search = useCallback(\n (query: string) => {\n if (!canAccessPeople) {\n return\n } else if (query.trim().length > 0) {\n debouncedSearch(query)\n } else {\n debouncedSearch.cancel()\n }\n },\n [debouncedSearch]\n )\n\n const myself: LoadedList = useMemo(\n () => ({ description: \"Myself\", value: \"self\" }),\n []\n )\n const allListOptions = useMemo(() => {\n if (!canAccessPeople) {\n return [myself]\n } else {\n return listOptions\n }\n }, [myself, listOptions])\n\n const selectedOption = allListOptions.find((option) => option.value === value)\n const selectedLabel = selectedOption?.description || \"\"\n const [query, _setQuery] = useState(selectedLabel)\n const [showClearButton, setShowClearButton] = useState(false)\n\n function setQuery(value: string) {\n _setQuery(value)\n search(value)\n if (value.trim().length === 0) {\n handleValueChange(null)\n }\n }\n\n const handleValueChange = (value: string) => {\n onChange({ fieldId: field.id, value })\n }\n\n return (\n <TapestryCombobox.Popover\n closeOnSelect\n closeButton={{ icon: { size: \"md\" } }}\n cursor=\"pointer\"\n onBlur={() => {\n setShowClearButton(false)\n setQuery(selectedLabel)\n }}\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\n setQuery(e.target.value)\n setShowClearButton(true)\n }}\n onClear={\n showClearButton\n ? () => {\n setQuery(\"\")\n }\n : undefined\n }\n onFocus={(e: React.FocusEvent<HTMLInputElement>) => e.target.select()} // select all text on focus\n onSelect={(option: { description: string; value: string }) => {\n handleValueChange(option.value)\n setQuery(option.description)\n setShowClearButton(false)\n }}\n openOnFocus\n paddingLeft={4.5}\n placeholder=\"Search\"\n placement=\"bottom-start\"\n popoverProps={{\n matchWidths: \"minimum\",\n }}\n renderLeft={\n selectedOption && selectedOption.meta?.avatar ? (\n <Avatar size=\"sm\" source={selectedOption.meta.avatar} />\n ) : (\n <Icon name=\"general.search\" size=\"md\" />\n )\n }\n renderRight={<Icon name=\"general.downCaret\" />}\n size=\"lg\"\n value={query}\n >\n {canAccessPeople ? (\n query.trim().length > 0 ? (\n listOptions.length > 0 ? (\n listOptions.map((option, index) => {\n return (\n <TapestryCombobox.Item\n aria-label={option.description}\n index={index}\n key={option.value}\n paddingLeft={4.25}\n renderLeft={\n <Avatar\n marginLeft={-0.5}\n source={option.meta.avatar}\n size=\"sm\"\n />\n }\n role=\"option\"\n spacing={token(\"--t-spacing-1\")}\n value={option}\n >\n <Text truncate>\n <Highlight text={option.description} query={query} />\n </Text>\n </TapestryCombobox.Item>\n )\n })\n ) : isLoading ? (\n <TapestryCombobox.Item>\n <Text>Loading...</Text>\n </TapestryCombobox.Item>\n ) : (\n <TapestryCombobox.Item>\n <Text>No results</Text>\n </TapestryCombobox.Item>\n )\n ) : (\n <TapestryCombobox.Item>\n <Text>Type to search</Text>\n </TapestryCombobox.Item>\n )\n ) : (\n <TapestryCombobox.Item value={myself} index={0} role=\"option\">\n <Text>{myself.description}</Text>\n </TapestryCombobox.Item>\n )}\n </TapestryCombobox.Popover>\n )\n}\n\nconst Checkbox = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleCheckedValueChange = (e) => {\n const value = e.target.checked\n onChange({ fieldId: field.id, value })\n }\n\n return (\n <TapestryCheckbox\n disabled={field.disabled}\n label={field.label}\n checked={value || false}\n onChange={handleCheckedValueChange}\n />\n )\n}\n\nconst TextArea = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleTextChange = (e) => {\n const val = e.target.value\n onChange({ fieldId: field.id, value: val })\n }\n return (\n <Box>\n <TapestryTextArea\n value={value}\n placeholder={field.placeholder}\n onChange={handleTextChange}\n size=\"lg\"\n />\n </Box>\n )\n}\n\nconst DateField = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const { dateFormat } = useContext(OrganizationContext)\n const [specificDate, setSpecificDate] = useState(false)\n const todaysValue = field.customValue || \"Day automation runs\"\n const dateBeforeValue = \"Day before automation runs\"\n const orgFormat = dateFNSFormat(dateFormat)\n const [dateFieldValue, setDateFieldValue] = useState(moment(value).toDate())\n const allowUnansweredOption = field.allowUnansweredOption ?? false\n\n const handleSelectChange = ({ selectedValue }) => {\n if (selectedValue === todaysValue || selectedValue === dateBeforeValue) {\n setSpecificDate(false)\n onChange({ fieldId: field.id, value: selectedValue })\n } else if (selectedValue === \"specific-date\") {\n onChange({ fieldId: field.id, value: null })\n setSpecificDate(true)\n } else {\n setSpecificDate(false)\n onChange({ fieldId: field.id, value: null })\n }\n }\n\n const handleValueChanged = (date: Date) => {\n onChange({ fieldId: field.id, value: dateLocalized(date, dateFormat) })\n setDateFieldValue(date)\n }\n\n return (\n <StackView axis=\"horizontal\">\n <TapestrySelect\n onChange={handleSelectChange}\n size=\"lg\"\n placement=\"bottom-start\"\n >\n <TapestrySelect.Option value={todaysValue}>\n {todaysValue}\n </TapestrySelect.Option>\n {!field.customValue && (\n <TapestrySelect.Option value={dateBeforeValue}>\n {dateBeforeValue}\n </TapestrySelect.Option>\n )}\n <TapestrySelect.Option value=\"specific-date\">\n A specific date\n </TapestrySelect.Option>\n {allowUnansweredOption && (\n <TapestrySelect.Option value=\"unanswered\">\n Unanswered\n </TapestrySelect.Option>\n )}\n </TapestrySelect>\n {specificDate && (\n <Box>\n <TapestryDateField\n defaultOpen\n formatValue={orgFormat}\n marginLeft={1}\n onChange={handleValueChanged}\n size=\"lg\"\n value={dateFieldValue}\n />\n </Box>\n )}\n </StackView>\n )\n}\n\nconst Checkboxes = ({\n fieldId,\n options,\n onChange,\n}: {\n fieldId: string\n onChange: Function\n options: { description: string; value: string | number }[]\n}) => {\n const [selectedValues, setSelectedValues] = useState({})\n\n const handleCheckboxesChange = (selectedValue, value) => {\n const newSelectedValues = { ...selectedValues }\n newSelectedValues[value] = selectedValue\n setSelectedValues(newSelectedValues)\n onChange({ fieldId, value: newSelectedValues })\n }\n\n return (\n <StackView spacing={1}>\n {options.map((item) => (\n <Box key={item.value}>\n <Input.InputLabel controls={`checkboxes_${fieldId}_${item.value}`}>\n {item.description || item.value}\n </Input.InputLabel>\n <TapestrySelect\n id={`checkboxes_${fieldId}_${item.value}`}\n onChange={({ selectedValue }) =>\n handleCheckboxesChange(selectedValue, item.value)\n }\n size=\"lg\"\n emptyValue={\"Don't change\"}\n >\n <TapestrySelect.Option value=\"check\">Check</TapestrySelect.Option>\n <TapestrySelect.Option value=\"uncheck\">\n Uncheck\n </TapestrySelect.Option>\n </TapestrySelect>\n </Box>\n ))}\n </StackView>\n )\n}\n\nconst NumberField = ({\n field,\n onChange,\n value,\n}: {\n field: DefinitionField\n onChange: Function\n value: string\n}) => {\n const minimumValue = field.minValue >= 0 ? field.minValue : 1\n const maximumValue =\n field.maxValue >= 1 && field.maxValue <= 365 ? field.maxValue : 365\n\n const [inputValue, setInputValue] = useState(Number(field.defaultValue) || 1)\n\n useEffect(() => {\n onChange({ fieldId: field.id, value: field.defaultValue || 1 })\n }, [field])\n\n return (\n <StackView>\n <Input.InputBox>\n <TapestryNumberField\n onChange={(value: string) => {\n const newNumberValue = Number(value) || 0\n setInputValue(newNumberValue)\n\n onChange({\n fieldId: field.id,\n value: Math.min(\n Math.max(newNumberValue, minimumValue),\n maximumValue\n ),\n })\n }}\n placeholder={field.placeholder}\n size=\"lg\"\n value={value}\n min={minimumValue}\n max={maximumValue}\n hasControls={true}\n />\n </Input.InputBox>\n {inputValue > maximumValue && (\n <Alert\n type=\"error\"\n paddingHorizontal={token(\"--t-spacing-1\")}\n paddingVertical={token(\"--t-spacing-half\")}\n display=\"inline-block\"\n marginTop={1.5}\n >\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={0.75}>\n <Icon\n name=\"general.exclamationTriangle\"\n size=\"sm\"\n color=\"delete45\"\n />\n <Text size={token(\"--t-font-size-md\")}>\n Value cannot exceed {maximumValue}.\n </Text>\n </StackView>\n </Alert>\n )}\n </StackView>\n )\n}\n\nconst TextField = ({\n field,\n value,\n onChange,\n}: {\n field: DefinitionField\n onChange: Function\n value: any\n}) => {\n const handleTextChange = (e) => {\n const val = e.target.value\n onChange({ fieldId: field.id, value: val })\n }\n return (\n <Box>\n <Input\n size=\"lg\"\n value={value ?? \"\"}\n id={field.id}\n placeholder={field.placeholder}\n onChange={handleTextChange}\n />\n </Box>\n )\n}\n\nconst RadioButtons = ({\n field,\n options,\n onChange,\n value,\n}: {\n field: DefinitionField\n onChange: Function\n options: LoadedList[]\n value: any\n}) => {\n const handleCheckedChange = (e) => {\n onChange({ fieldId: field.id, value: e.target.value })\n }\n\n return (\n <StackView marginTop={1} spacing={0.5}>\n {options.map((option) => (\n <Radio\n checked={value === option.value}\n key={option.value}\n label={option.description || option.value}\n onChange={handleCheckedChange}\n size=\"md\"\n value={option.value}\n />\n ))}\n </StackView>\n )\n}\n\nconst Loading = () => (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n paddingHorizontal={1.75}\n paddingVertical={token(\"--t-spacing-1\")}\n radius={token(\"--t-border-radius-md\")}\n border={`1px solid ${token(\"--t-border-color\")}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={token(\"--t-font-size-md\")} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n)\n\nexport default Field\n","import React, { useEffect } from \"react\"\n\nimport Field from \"./field\"\nimport { getRenderedFields } from \"./utils/utils\"\n\ninterface FieldsProps {\n canAccessPeople: boolean\n definitionFields: DefinitionField[]\n loadListForField: LoadListForField\n loadedLists: { [k: string]: LoadedList[] }\n loadingLists: { [k: string]: boolean }\n onChange: Function\n selectedFieldOptions: SelectedFieldOptions\n}\n\nconst Fields = ({\n canAccessPeople,\n definitionFields,\n onChange,\n selectedFieldOptions,\n loadListForField,\n loadedLists,\n loadingLists,\n}: FieldsProps): JSX.Element => {\n useEffect(() => {\n const newSelections = definitionFields.reduce((acc, field) => {\n if (Object.prototype.hasOwnProperty.call(field, \"defaultValue\")) {\n acc[field.id] = field.defaultValue\n } else if (field.kind === \"DateField\") {\n acc[field.id] = field.customValue || \"Date automation runs\"\n }\n\n return acc\n }, {})\n onChange(newSelections)\n }, [definitionFields, onChange])\n\n const renderableFields = getRenderedFields(\n definitionFields,\n selectedFieldOptions\n )\n\n const handleSelectedFieldOptionsChange = ({ fieldId, value }) => {\n const newSelections = { ...selectedFieldOptions }\n const dependents = definitionFields.filter((field) => field.dependsOn)\n dependents.map((dependent) => {\n if (dependent.dependsOn.includes(fieldId)) {\n const deeper = dependents.find((d) =>\n d.dependsOn.includes(dependent.id)\n )\n if (deeper) {\n delete newSelections[deeper.id]\n }\n delete newSelections[dependent.id]\n\n if (\n dependent.defaultValue !== undefined &&\n newSelections[dependent.id] === undefined\n ) {\n newSelections[dependent.id] = dependent.defaultValue\n }\n }\n })\n\n if (value === \"no-option\") {\n delete newSelections[fieldId]\n } else {\n newSelections[fieldId] = value\n }\n\n onChange({ ...newSelections })\n }\n\n if (definitionFields.length) {\n return (\n <div>\n {renderableFields.map((field) => {\n return (\n <Field\n canAccessPeople={canAccessPeople}\n field={field}\n key={field.id}\n onChange={handleSelectedFieldOptionsChange}\n value={selectedFieldOptions[field.id]}\n selectedFieldOptions={selectedFieldOptions}\n loadListForField={loadListForField}\n loadedLists={loadedLists}\n loadingLists={loadingLists}\n />\n )\n })}\n </div>\n )\n } else {\n return null\n }\n}\n\nexport default Fields\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Alert,\n Box,\n Button,\n Checkbox,\n Icon,\n Input,\n Link,\n Select,\n Spinner,\n StackView,\n Text,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\n\nimport Definition from \"./definition\"\nimport Fields from \"./fields\"\nimport * as alerts from \"./utils/alerts\"\nimport {\n buildDescription,\n buildTriggerConditions,\n fieldListIdentifier,\n getRenderedFields,\n} from \"./utils/utils\"\n\nconst client = new Client({\n root: pcoApiUrl(\"people\", { squiggly: false }),\n version: \"LATEST\",\n})\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"LATEST\",\n})\nconst errorAlertProps = {\n css: { borderRadius: token(\"--t-border-radius-md\") },\n paddingHorizontal: 1.75,\n paddingVertical: 1.25,\n type: \"error\",\n}\n\ntype TopbarResponse = {\n data: {\n apps: Array<{ name: string }>\n type: \"Topbar\"\n }\n}\n\nasync function getVisibleApps() {\n return client\n .get<TopbarResponse>({\n data: {\n fields: { Topbar: \"apps\" },\n },\n url: \"/me/topbar\",\n })\n .then(({ data }) => data.apps.map((a) => a.name))\n}\n\nasync function getWebhooksApps() {\n return webhooksClient\n .get<{ data: Array<{ name: string; type: \"OperationApp\" }> }>({\n data: { fields: { OperationApp: \"name\" } },\n url: \"/operation_apps\",\n })\n .then(({ data }) => data.map((a) => a.name))\n}\n\nasync function getOperationApps() {\n const [visibleApps, webhooksApps] = await Promise.all([\n getVisibleApps(),\n getWebhooksApps(),\n ])\n\n return visibleApps\n .filter((app) => webhooksApps.includes(app))\n .sort()\n .map((app: string) => ({ id: app.toLowerCase(), name: app }))\n}\n\nasync function getOperationDefinitions(app: string) {\n return webhooksClient\n .get({\n data: {\n fields: {\n OperationDefinition:\n \"definition_class,definition_fields,definition_identifier,description,group,section,section_group,footer_message\",\n },\n filter: \"automation_allowed\",\n walk: true,\n },\n url: `/operation_apps/${app}/operation_definitions`,\n })\n .then(({ data }) => data)\n}\n\nasync function getListOptions({\n app,\n field,\n definitionIdentifier,\n dependencies,\n}: {\n app: string\n definitionIdentifier: string\n dependencies: { [k: string]: string }\n field: DefinitionField\n}): Promise<LoadedList[]> {\n if (field.kind === \"PersonSearch\") {\n const { data: people } = await client.get<{\n data: { avatar: string; id: number; name: string }[]\n }>({\n data: {\n fields: { Person: \"avatar,name\" },\n where: { search_name_or_email: dependencies.query, status: \"active\" },\n },\n url: \"/people\",\n })\n\n return people.map((p) => ({\n description: p.name,\n meta: { avatar: p.avatar },\n value: p.id.toString(),\n }))\n } else {\n const { data } = await webhooksClient.get({\n data: {\n ...dependencies,\n definitionIdentifier,\n fields: {\n OperationDefinitionList: \"values\",\n },\n },\n url: `/operation_apps/${app}/operation_definition_lists/${field.listClass}`,\n })\n return data.values\n }\n}\n\nconst NewAutomation = ({\n afterCreateOptions,\n blankStateLink,\n debugMode = false,\n defaultApp,\n description,\n onRequestClose,\n trigger,\n}: {\n afterCreateOptions?: AfterCreateOptions\n blankStateLink: string\n debugMode?: boolean\n defaultApp: string\n description: string\n onRequestClose: () => void\n trigger: AutomationTrigger\n}) => {\n const [selectedTriggerEvent, setSelectedTriggerEvent] = useState(\n trigger.events[0]\n )\n const [dynamicTriggerConditions, setDynamicTriggerConditions] =\n useState<SelectedFieldOptions>({})\n const [selectedApp, setSelectedApp] = useState(defaultApp)\n const [operationApps, setOperationApps] = useState<\n { id: string; name: string }[]\n >([])\n const [operationDefinitions, setOperationDefinitions] = useState<\n OperationDefinition[]\n >([])\n const [loadingOperationDefinitions, setLoadingOperationDefinitions] =\n useState(true)\n const [selectedDefinition, setSelectedDefinition] =\n useState<OperationDefinition>()\n const [selectedFieldOptions, setSelectedFieldOptions] =\n useState<SelectedFieldOptions>({})\n const [loadedLists, setLoadedLists] = useState<{ [k: string]: LoadedList[] }>(\n {}\n )\n const [loadingLists, setLoadingLists] = useState<{ [k: string]: boolean }>({})\n const [submitting, setSubmitting] = useState(false)\n const [error, setError] = useState<{\n automation?: string | string[]\n definitions?: string | string[]\n selected_definition?: string | string[]\n }>({})\n const [callAfterCreate, setCallAfterCreate] = useState(false)\n const [triggerParams, setTriggerParams] = useState<{ [k: string]: string }>(\n {}\n )\n const activeAppRef = useRef(null)\n\n const canAccessPeople = useMemo(\n () => operationApps.map((a) => a.id).includes(\"people\"),\n [operationApps]\n )\n\n const definitionIdentifier = selectedDefinition?.definitionIdentifier\n const dangerAlertPresent =\n selectedDefinition?.footerMessage?.kind === \"danger\"\n\n const loadListForField = useCallback<LoadListForField>(\n ({ field, dependencies }) => {\n setLoadingLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: true,\n }))\n getListOptions({\n app: selectedApp,\n definitionIdentifier,\n dependencies,\n field,\n })\n .then((ret) => {\n setLoadedLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: ret,\n }))\n setLoadingLists((prev) => ({\n ...prev,\n [fieldListIdentifier(field)]: false,\n }))\n })\n .catch((error) => setError({ selected_definition: error }))\n },\n [selectedApp, definitionIdentifier]\n )\n\n const handleChangeSelectedApp = (app: string) => {\n setSelectedApp(app)\n setLoadingOperationDefinitions(true)\n setOperationDefinitions([])\n activeAppRef.current = app\n setSelectedDefinition(null)\n setSelectedFieldOptions({})\n setError({})\n getOperationDefinitions(app)\n .then(setOperationDefinitions)\n .then(() => setLoadingOperationDefinitions(false))\n .catch((error) => setError({ definitions: error }))\n }\n\n const handleChangeTriggerEvent = (\n selectedValue: typeof selectedTriggerEvent\n ) => {\n setSelectedTriggerEvent(selectedValue)\n setDynamicTriggerConditions({})\n }\n\n useEffect(() => {\n setError({})\n getOperationApps().then((apps) => {\n setOperationApps(apps)\n const defaultSelection = apps.find((app) => app.id === defaultApp)\n ? defaultApp\n : apps[0].id\n setSelectedApp(defaultSelection)\n getOperationDefinitions(defaultSelection)\n .then((definitions) => {\n if (!activeAppRef.current) {\n setOperationDefinitions(definitions)\n setLoadingOperationDefinitions(false)\n }\n })\n .catch((error) => setError({ definitions: error }))\n })\n }, [defaultApp])\n\n useEffect(() => {\n setError({})\n }, [selectedFieldOptions])\n\n const dynamicConditions =\n \"dynamicConditions\" in selectedTriggerEvent\n ? selectedTriggerEvent.dynamicConditions\n : trigger.dynamicConditions\n const triggerConditions = buildTriggerConditions({\n baseConditions:\n \"conditions\" in selectedTriggerEvent\n ? selectedTriggerEvent.conditions\n : trigger.conditions,\n dynamicConditions,\n dynamicTriggerConditions,\n })\n\n const handleSelectedDefinitionChange = (\n newDefinition: OperationDefinition\n ) => {\n setSelectedDefinition(newDefinition)\n setError({})\n setSelectedFieldOptions({})\n }\n\n function getDescription(): string {\n const descriptionParts = buildDescription({\n loadedLists,\n selectedDefinition,\n selectedFieldOptions,\n })\n\n let description = descriptionParts.name\n\n if (descriptionParts.description) {\n description += ` (${descriptionParts.description})`\n }\n\n return description\n }\n\n function handleSubmit() {\n if (submitting) {\n return\n }\n const operation_params = { ...selectedFieldOptions }\n\n if (selectedDefinition.definitionIdentifier) {\n operation_params.definition_identifier =\n selectedDefinition.definitionIdentifier\n }\n\n const data = {\n _e: trigger.resource,\n data: {\n attributes: {\n description: getDescription(),\n name: selectedTriggerEvent.name,\n operation_app_name: selectedApp,\n operation_definition_class_name: selectedDefinition.definitionClass,\n operation_params,\n trigger_conditions: triggerConditions,\n trigger_params: triggerParams,\n },\n type: \"AutomationSubscription\",\n },\n }\n if (callAfterCreate) {\n alerts.confirmCreate\n .fire({\n cancelButtonText: \"Cancel\",\n confirmButtonText: \"Yes, perform action\",\n text: \"This will happen immediately after creating your new automation. Are you sure?\",\n title: `${afterCreateOptions.label}?`,\n })\n .then((result: { value: any }) => {\n if (result.value) {\n submitCreate(data)\n } else {\n setSubmitting(false)\n setCallAfterCreate(false)\n }\n })\n } else {\n submitCreate(data)\n }\n }\n\n function submitCreate(data) {\n setSubmitting(true)\n webhooksClient\n .post({\n data,\n url: \"/me/automation_subscriptions\",\n })\n .then(() => {\n if (afterCreateOptions?.onConfirm && callAfterCreate) {\n onRequestClose()\n afterCreateOptions.onConfirm({ ...data })\n } else {\n window.location.reload()\n }\n })\n .catch((error) => {\n setSubmitting(false)\n if (error.errors) {\n setError({ automation: error.errors })\n } else {\n alert(\"something even worse happened!\")\n }\n })\n }\n\n return (\n <StackView paddingTop={4} spacing={2}>\n {description && (\n <Box>\n <Text\n style={{\n color: token(\"--t-text-color\"),\n fontSize: token(\"--t-font-size-md\"),\n lineHeight: 1.65,\n marginBottom: token(\"--t-spacing-2\"),\n }}\n >\n {description}{\" \"}\n <Link external to={blankStateLink}>\n Learn more\n </Link>\n </Text>\n </Box>\n )}\n {error.automation && (\n <Alert {...errorAlertProps}>\n <Text>\n There was an error creating your automation. Please change your\n selections and try again or contact support if the problem persists.\n </Text>\n </Alert>\n )}\n <StackView spacing={1}>\n <Input.InputLabel\n color={token(\"--t-text-color\")}\n controls=\"select-trigger-event\"\n fontSize={token(\"--t-font-size-md\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n >\n When a person...\n </Input.InputLabel>\n <Select\n id=\"select-trigger-event\"\n onChange={({ selectedValue }) =>\n handleChangeTriggerEvent(selectedValue)\n }\n size=\"lg\"\n value={selectedTriggerEvent}\n >\n {trigger.events.map((triggerEvent, idx) => (\n <Select.Option\n key={`${triggerEvent.name}_${idx}`}\n value={triggerEvent}\n >\n {triggerEvent.description}\n </Select.Option>\n ))}\n </Select>\n\n {dynamicConditions?.length > 0 && (\n <Fields\n canAccessPeople={canAccessPeople}\n definitionFields={dynamicConditions}\n selectedFieldOptions={dynamicTriggerConditions}\n onChange={setDynamicTriggerConditions}\n loadedLists={{}}\n loadingLists={{}}\n loadListForField={() => null}\n />\n )}\n </StackView>\n\n <StackView spacing={1}>\n {operationApps.length > 0 ? (\n <Application\n selectedApp={selectedApp}\n operationApps={operationApps}\n onOperationAppChange={handleChangeSelectedApp}\n />\n ) : (\n <StackView spacing={1}>\n <Text\n color={token(\"--t-text-color-headline\")}\n fontSize={token(\"--t-font-size-md\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n >\n Then perform an action in...\n </Text>\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n paddingHorizontal={1.75}\n paddingVertical={token(\"--t-spacing-1\")}\n radius={4}\n border={`1px solid ${token(\"--t-border-color\")}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={token(\"--t-font-size-md\")} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n </StackView>\n )}\n {error.definitions ? (\n <Alert marginTop={token(\"--t-spacing-1\")} {...errorAlertProps}>\n <Text>\n There was a problem looking up automations. Please contact support\n if the problem persists.\n </Text>\n </Alert>\n ) : loadingOperationDefinitions ? (\n <LoadingOperationDefinitions />\n ) : (\n <Definition\n selectedOperation={selectedDefinition}\n operationDefinitions={operationDefinitions}\n onOperationDefinitionChange={handleSelectedDefinitionChange}\n />\n )}\n </StackView>\n\n {selectedDefinition &&\n (error.selected_definition ? (\n <Alert {...errorAlertProps}>\n <Text>\n There was a problem looking up automation options. Please contact\n support if the problem persists.\n </Text>\n </Alert>\n ) : (\n <>\n <Fields\n canAccessPeople={canAccessPeople}\n definitionFields={selectedDefinition.definitionFields || []}\n onChange={setSelectedFieldOptions}\n selectedFieldOptions={selectedFieldOptions}\n loadedLists={loadedLists}\n loadListForField={loadListForField}\n loadingLists={loadingLists}\n />\n {afterCreateOptions?.label && (\n <Checkbox\n disabled={\n submitting ||\n disableSubmit(selectedDefinition, selectedFieldOptions)\n }\n label={afterCreateOptions.label}\n checked={callAfterCreate}\n onChange={() => setCallAfterCreate(!callAfterCreate)}\n />\n )}\n {selectedTriggerEvent?.triggerParams?.map((param, idx) => (\n <Checkbox\n key={`${param.key}_${idx}`}\n label={param.description}\n checked={\n (triggerParams && triggerParams[param.key]) ||\n param.defaultValue\n }\n onChange={(e) => {\n setTriggerParams((prev) => ({\n ...prev,\n [`${param.key}`]: e.target.checked,\n }))\n }}\n />\n ))}\n {dangerAlertPresent && (\n <Alert {...errorAlertProps}>\n <StackView axis=\"horizontal\" spacing={1.5}>\n <Icon\n size={token(\"--t-element-size-lg\")}\n name=\"general.exclamationTriangle\"\n color={token(\"--t-icon-color-status-error\")}\n />\n <Text\n dangerouslySetInnerHTML={{\n __html: selectedDefinition.footerMessage?.html,\n }}\n />\n </StackView>\n </Alert>\n )}\n </>\n ))}\n\n {debugMode && (\n <pre>\n {JSON.stringify(\n {\n description: selectedDefinition && getDescription(),\n loadedLists,\n selectedDefinition,\n selectedFieldOptions,\n triggerConditions,\n },\n null,\n 4\n )}\n </pre>\n )}\n\n <StackView\n alignment=\"center\"\n axis=\"horizontal\"\n borderTop={`1px solid ${token(\"--t-border-color\")}`}\n distribution=\"end\"\n marginTop={2}\n marginHorizontal={-4}\n paddingHorizontal={4}\n paddingTop={3}\n spacing={2}\n >\n <Button\n color={token(\"--t-text-color-headline\")}\n // for temporary backwards compatibility\n data-modal-close\n fontWeight={token(\"--t-font-weight-normal\")}\n onClick={onRequestClose}\n size=\"md\"\n title=\"Cancel\"\n variant=\"naked\"\n />\n <Button\n disabled={\n submitting ||\n dangerAlertPresent ||\n disableSubmit(\n selectedDefinition,\n selectedFieldOptions,\n dynamicConditions,\n dynamicTriggerConditions\n )\n }\n onClick={handleSubmit}\n size=\"md\"\n theme=\"primary\"\n title={getButtonText(selectedDefinition, selectedFieldOptions)}\n variant=\"fill\"\n data-testid=\"create-automation\"\n />\n </StackView>\n </StackView>\n )\n}\n\nfunction disableSubmit(\n selectedDefinition: OperationDefinition,\n selectedFieldOptions: SelectedFieldOptions,\n dynamicConditions?: DefinitionField[],\n dynamicTriggerConditions?: SelectedFieldOptions\n) {\n if (!selectedDefinition) return true\n\n const operationFields = getRenderedFields(\n selectedDefinition.definitionFields,\n selectedFieldOptions\n )\n if (\n !operationFields\n .filter((field) => field.required)\n .every((field) => fieldIsFilled(field, selectedFieldOptions))\n )\n return true\n if (\n !operationFields\n .filter((field) => fieldIsSelect(field))\n .every((field) => fieldIsFilled(field, selectedFieldOptions))\n )\n return true\n\n const triggerFields = getRenderedFields(\n dynamicConditions ?? [],\n dynamicTriggerConditions ?? {}\n )\n if (\n !triggerFields\n .filter((field) => field.required)\n .every((field) => fieldIsFilled(field, dynamicTriggerConditions ?? {}))\n )\n return true\n\n return false\n}\n\nfunction fieldIsSelect(field: DefinitionField) {\n return field.kind === \"Select\" || field.kind === \"SelectSearch\"\n}\n\nfunction fieldIsFilled(\n field: DefinitionField,\n selectedFieldOptions: SelectedFieldOptions\n) {\n if (fieldIsSelect(field)) {\n return selectedFieldOptions.hasOwnProperty(field.id)\n } else {\n return (\n selectedFieldOptions.hasOwnProperty(field.id) &&\n selectedFieldOptions[field.id] &&\n selectedFieldOptions[field.id].toString().trim() !== \"\"\n )\n }\n}\n\nfunction getNextRequiredDescription(\n selectedDefinition: OperationDefinition,\n selectedFieldOptions: SelectedFieldOptions\n) {\n if (!selectedDefinition?.definitionFields) return\n\n const renderedFields = getRenderedFields(\n selectedDefinition.definitionFields,\n selectedFieldOptions\n )\n\n for (const field of renderedFields) {\n if (field.required && !fieldIsFilled(field, selectedFieldOptions))\n return field.description\n }\n}\n\nfunction getButtonText(\n selectedDefinition: OperationDefinition,\n selectedFieldOptions: SelectedFieldOptions\n) {\n const nextRequiredDescription = getNextRequiredDescription(\n selectedDefinition,\n selectedFieldOptions\n )\n\n if (!selectedDefinition) {\n return \"Select an action\"\n } else if (nextRequiredDescription) {\n return `Select a${\n nextRequiredDescription.charAt(0).match(/[aeiou]/i) ? \"n\" : \"\"\n } ${nextRequiredDescription.toLowerCase()}`\n } else {\n return \"Create automation\"\n }\n}\n\nconst Application = ({\n onOperationAppChange,\n operationApps,\n selectedApp,\n}: {\n onOperationAppChange: (selectedValue: string) => void\n operationApps: Array<{ id: string; name: string }>\n selectedApp: string\n}) => {\n const handleChange = ({ selectedValue }) => {\n onOperationAppChange(selectedValue)\n }\n\n return (\n <StackView spacing={1}>\n <Input.InputLabel\n color={token(\"--t-text-color-headline\")}\n controls=\"select-product\"\n fontSize={token(\"--t-font-size-md\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n >\n Then perform an action in...\n </Input.InputLabel>\n <Select\n autoFocus\n id=\"select-product\"\n onChange={handleChange}\n size=\"lg\"\n value={selectedApp}\n >\n {operationApps.map((app) => (\n <Select.Option key={app.id} value={app.id}>\n {app.name}\n </Select.Option>\n ))}\n </Select>\n </StackView>\n )\n}\n\nconst LoadingOperationDefinitions = () => (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n paddingHorizontal={1.75}\n paddingVertical={token(\"--t-spacing-1\")}\n radius={token(\"--t-border-radius-md\")}\n border={`1px solid ${token(\"--t-border-color\")}`}\n >\n <Spinner size=\"xs\" />\n <Text fontSize={token(\"--t-font-size-md\")} lineHeight={2.75}>\n Loading\n </Text>\n </StackView>\n)\n\nexport default NewAutomation\n","import { token } from \"@planningcenter/tapestry\"\nimport {\n Button,\n Heading,\n Modal,\n StackView,\n ThemeProvider,\n} from \"@planningcenter/tapestry-react\"\nimport React from \"react\"\nimport { createPortal } from \"react-dom\"\n\nfunction CloseModalIcon({\n onClick,\n}: {\n onClick: React.MouseEventHandler\n}): JSX.Element {\n return (\n <Button\n as=\"button\"\n height={token(\"--t-element-size-md\")}\n icon={{ color: token(\"--t-icon-color-dim\"), name: \"general.x\" }}\n onClick={onClick}\n size={\"sm\"}\n title=\"Close\"\n variant=\"naked\"\n />\n )\n}\n\nfunction NewAutomationModal({\n children,\n onRequestClose,\n open,\n theme,\n}: {\n children: React.ReactNode\n onRequestClose: () => void\n open: boolean\n theme: object\n}): React.ReactPortal | JSX.Element {\n return createPortal(\n <ThemeProvider theme={theme}>\n <Modal\n open={open}\n onRequestClose={onRequestClose}\n maxWidth={75}\n boxShadow=\"0 0 20px rgba(0, 0, 0, 0.15)\"\n padding={token(\"--t-spacing-4\")}\n paddingBottom={token(\"--t-spacing-3\")}\n radius={token(\"--t-border-radius-lg\")}\n zIndex={10009}\n >\n <StackView\n axis=\"horizontal\"\n distribution=\"space-between\"\n alignment=\"center\"\n >\n <Heading\n level={2}\n color={token(\"--t-text-color-headline\")}\n fontWeight={token(\"--t-font-weight-medium\")}\n fontSize={token(\"--t-font-size-2xl\")}\n lineHeight=\"1.4\"\n >\n Create automation\n </Heading>\n <CloseModalIcon onClick={onRequestClose} />\n </StackView>\n {children}\n </Modal>\n <style>{`\n .swal2-container.swal2-backdrop-show { z-index: 10001 }\n `}</style>\n </ThemeProvider>,\n document.body\n )\n}\n\nexport default NewAutomationModal\n","import * as churchCenter from \"@planningcenter/icons/paths/church-center\"\nimport * as logomark from \"@planningcenter/icons/paths/logomark\"\nimport * as services from \"@planningcenter/icons/paths/services\"\n\nexport const icons = {\n churchCenter,\n logomark,\n services,\n}\n","import { Client } from \"@planningcenter/api-client\"\nimport { token } from \"@planningcenter/tapestry\"\nimport {\n Box,\n Button,\n Heading,\n Icon,\n Spinner,\n StackView,\n Summary,\n Text,\n ThemeProvider,\n TileView,\n} from \"@planningcenter/tapestry-react\"\nimport { pcoApiUrl } from \"@planningcenter/url\"\nimport sortBy from \"lodash/sortBy\"\nimport React, { useEffect, useState } from \"react\"\n\nimport SvgAutomations from \"./assets/svg_automations\"\nimport { EditableAutomation } from \"./automation\"\nimport { OrganizationContext } from \"./contexts/organization_context\"\nimport IncomingAutomations from \"./incoming_automations\"\nimport NewAutomation from \"./new_automation\"\nimport NewAutomationModal from \"./new_automation_modal\"\nimport styles from \"./styles.scss\"\nimport * as alerts from \"./utils/alerts\"\nimport {\n fetchAutomations,\n fetchCreatorProfiles,\n mergeProfilesAndSubscriptions,\n} from \"./utils/fetch-automations\"\nimport { resolveResponseDetails } from \"./utils/resolve-response-details\"\nimport { icons } from \"./utils/theme\"\nimport {\n deobfuscateDescriptions,\n forbiddenText,\n pluralize,\n} from \"./utils/utils\"\n\nconst webhooksClient = new Client({\n root: pcoApiUrl(\"webhooks\", { squiggly: false }),\n version: \"2022-10-20\",\n})\n\nfunction Header({\n afterCreateOptions,\n automations,\n blankStateLink,\n canCreate,\n defaultApp,\n description,\n hasActiveAutomations,\n loading,\n onPauseAutomations,\n theme,\n trigger,\n}: {\n afterCreateOptions?: AfterCreateOptions\n automations: AutomationInstance[]\n blankStateLink: string\n canCreate: boolean\n defaultApp: string\n description: string\n hasActiveAutomations: boolean\n loading: boolean\n onPauseAutomations: Function\n theme: object\n trigger: AutomationTrigger\n}) {\n const [newModalVisible, setNewModalVisible] = useState(false)\n const isPaused = canCreate && !hasActiveAutomations\n\n const activeCount = automations.filter(\n (automation) => automation.active\n ).length\n const pausedCount = automations.filter(\n (automation) => !automation.active\n ).length\n\n return (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n backgroundColor={\n isPaused ? token(\"--t-fill-color-status-warning-ghost\") : undefined\n }\n borderBottom={\n isPaused ? undefined : `1px solid ${token(\"--t-border-color\")}`\n }\n data-testid=\"automations-header\"\n distribution=\"space-between\"\n marginHorizontal={-3}\n marginBottom={token(\"--t-spacing-2\")}\n marginTop={-3}\n paddingHorizontal={token(\"--t-spacing-3\")}\n paddingVertical={token(\"--t-spacing-2\")}\n spacing={token(\"--t-spacing-2\")}\n wrap\n zIndex={2}\n >\n {canCreate && !hasActiveAutomations ? (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n marginHorizontal={1}\n spacing={1}\n >\n <Icon\n size={2}\n color={token(\"--t-icon-color-status-warning\")}\n name=\"general.exclamationTriangle\"\n />\n <Heading\n color={token(\"--t-text-color-headline\")}\n level={2}\n size={token(\"--t-font-size-lg\")}\n >\n Automations are currently paused\n </Heading>\n </StackView>\n ) : (\n <Heading\n color={token(\"--t-text-color-headline\")}\n level={2}\n size={token(\"--t-font-size-lg\")}\n >\n {loading\n ? \"Active automations\"\n : pluralize(activeCount, \"active automation\")}\n {pausedCount > 0 ? ` (${pausedCount} paused)` : \"\"}\n </Heading>\n )}\n {canCreate &&\n (hasActiveAutomations ? (\n <StackView\n axis=\"horizontal\"\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n >\n {automations.length > 0 && (\n <Button onClick={onPauseAutomations} variant=\"outline\">\n Pause automations\n </Button>\n )}\n <Button\n theme=\"primary\"\n variant=\"fill\"\n onClick={() => setNewModalVisible(true)}\n >\n Create automation\n </Button>\n <NewAutomationModal\n open={newModalVisible}\n onRequestClose={() => setNewModalVisible(false)}\n theme={theme}\n >\n <NewAutomation\n description={description}\n blankStateLink={blankStateLink}\n defaultApp={defaultApp}\n trigger={trigger}\n onRequestClose={() => setNewModalVisible(false)}\n afterCreateOptions={afterCreateOptions}\n />\n </NewAutomationModal>\n </StackView>\n ) : (\n <Box>\n <StackView axis=\"horizontal\" alignment=\"center\" spacing={1}>\n <Button\n onClick={onPauseAutomations}\n theme=\"primary\"\n variant=\"outline\"\n >\n Enable automations\n </Button>\n <Button\n theme=\"primary\"\n disabled\n tooltip={{\n title: \"Automations must be enabled to create new ones\",\n }}\n >\n Create automation\n </Button>\n </StackView>\n </Box>\n ))}\n </StackView>\n )\n}\n\nexport default function Automations({\n afterCreateOptions,\n blankStateDescription,\n blankStateLink = \"https://pcopeople.zendesk.com/hc/en-us/articles/217582148-Automations\",\n currentPersonId,\n currentPersonCanCreate,\n defaultApp,\n incomingAutomationsParam,\n theme,\n trigger,\n currentOrganization,\n permissionDeniedReason = \"You need permissions of Editor or above to add an automation.\",\n disabled = false,\n disabledReason = \"Not allowed\",\n}: {\n afterCreateOptions?: AfterCreateOptions\n blankStateDescription: string\n blankStateLink?: string\n currentOrganization: {\n dateFormat: string\n olsonTimeZone: string\n twentyFourHourTime: boolean\n }\n currentPersonCanCreate: boolean\n currentPersonId: number\n defaultApp: string\n disabled?: boolean\n disabledReason?: string\n incomingAutomationsParam?: string\n permissionDeniedReason?: string\n theme?: object\n trigger?: AutomationTrigger\n}) {\n useEffect(() => {\n if (!trigger) return setLoading(false)\n fetchAutomations(trigger.resource)\n .then(fetchCreatorProfiles)\n .then(mergeProfilesAndSubscriptions)\n .then(deobfuscateDescriptions)\n .then(resolveResponseDetails)\n .then(setAutomations)\n .then(() => setLoading(false))\n }, [trigger?.resource])\n\n const [automations, setAutomations] = useState([])\n const [loading, setLoading] = useState(true)\n const [newModalVisible, setNewModalVisible] = useState(false)\n\n const { dateFormat, twentyFourHourTime, olsonTimeZone } = currentOrganization\n\n const params = new URLSearchParams(window.location.search)\n\n const automationId = params.get(\"automation_id\")\n\n // make sure necessary icons are added to theme\n const customTheme = { ...theme, ...{ icons: { ...icons } } }\n\n useEffect(() => {\n document.body.toggleAttribute(\"data-loading-automations\", loading)\n }, [loading])\n\n const hasActiveAutomations = automations.length\n ? automations.some((a) => a.active)\n : true\n\n function handleDelete(id: number) {\n webhooksClient\n .delete({\n data: { _e: trigger.resource },\n url: `/automation_subscriptions/${id}`,\n })\n .then(() =>\n setAutomations(automations.filter((automation) => automation.id !== id))\n )\n .catch((error) => {\n const text =\n forbiddenText(error, \"delete\") ||\n \"There was a problem deleting this automation. Please try again in a few moments.\"\n alerts.alertError.fire({\n text,\n title: \"Uh oh!\",\n })\n })\n }\n\n function handlePauseAutomations() {\n webhooksClient\n .post({\n data: {\n data: {\n attributes: {\n _e: trigger.resource,\n active: !hasActiveAutomations,\n },\n },\n },\n url: \"/pause_automations\",\n })\n .then(() => {\n window.location.reload()\n })\n }\n\n const BlankStateHeadingProps = {\n color: token(\"--t-text-color\"),\n level: 2,\n size: token(\"--t-font-size-2xl\"),\n weight: token(\"--t-font-weight-bold\"),\n }\n\n const BlankStateTextProps = {\n color: token(\"--t-text-color-secondary\"),\n lineHeight: 3,\n size: token(\"--t-font-size-md\"),\n }\n\n function automationTriggerEvent(automation: AutomationInstance) {\n return trigger.events.find((event) => event.name === automation.name)\n }\n\n const handleUpdateAutomation =\n (originalAutomation: AutomationInstance) =>\n (newState: React.SetStateAction<AutomationInstance>) => {\n const updated =\n typeof newState == \"function\" ? newState(originalAutomation) : newState\n const newAutomations = [\n ...automations.filter((automation) => automation.id !== updated.id),\n updated,\n ]\n\n setAutomations(newAutomations)\n }\n\n return (\n <ThemeProvider theme={customTheme}>\n <OrganizationContext.Provider\n value={{ dateFormat, olsonTimeZone, twentyFourHourTime }}\n >\n {trigger && (\n <Header\n automations={automations}\n blankStateLink={blankStateLink}\n canCreate={currentPersonCanCreate && !disabled}\n loading={loading}\n defaultApp={defaultApp}\n description={blankStateDescription}\n theme={customTheme}\n trigger={trigger}\n hasActiveAutomations={hasActiveAutomations}\n onPauseAutomations={handlePauseAutomations}\n afterCreateOptions={afterCreateOptions}\n />\n )}\n {loading ? (\n <Summary\n image={<Spinner size=\"xl\" />}\n paddingVertical={10}\n title={\"Loading automations...\"}\n />\n ) : !trigger ? (\n <></>\n ) : (\n <Box data-testid=\"automations-section\">\n {automations?.length > 0 ? (\n <TileView spacing={3} marginVertical={3} minCellWidth={45}>\n {sortBy(automations, \"id\").map((a) => (\n <EditableAutomation\n key={a.id}\n automation={a}\n updateAutomation={handleUpdateAutomation(a)}\n onDelete={handleDelete}\n theme={customTheme}\n openHistoryNow={a.id === Number(automationId)}\n trigger={{\n event: automationTriggerEvent(a),\n resource: trigger.resource,\n }}\n currentPersonId={currentPersonId}\n currentPersonCanCreate={currentPersonCanCreate}\n disabled={disabled}\n disabledReason={disabledReason}\n />\n ))}\n </TileView>\n ) : (\n <StackView\n margin={token(\"--t-spacing-6\")}\n spacing={token(\"--t-spacing-2\")}\n alignment=\"center\"\n mediaQueries={{\n lg: {\n axis: \"horizontal\",\n distribution: \"center\",\n spacing: token(\"--t-spacing-6\"),\n },\n }}\n >\n <Box\n css={{\n \".symbol\": {\n height: \"100%\",\n width: \"100%\",\n },\n }}\n maxWidth={24}\n mediaQueries={{\n lg: {\n maxWidth: 40,\n },\n }}\n >\n <SvgAutomations />\n </Box>\n <StackView\n alignment=\"center\"\n spacing={token(\"--t-spacing-1\")}\n maxWidth={45}\n mediaQueries={{\n lg: {\n alignment: \"start\",\n textAlign: \"left\",\n },\n }}\n textAlign=\"center\"\n >\n {currentPersonCanCreate ? (\n <>\n <Heading {...BlankStateHeadingProps}>\n Add an automation\n </Heading>\n <StackView\n alignment=\"center\"\n marginBottom={token(\"--t-spacing-1\")}\n mediaQueries={{\n lg: {\n alignment: \"start\",\n },\n }}\n spacing={1}\n >\n <Text {...BlankStateTextProps}>\n {blankStateDescription}\n </Text>\n </StackView>\n <StackView\n axis=\"horizontal\"\n spacing={token(\"--t-spacing-1\")}\n >\n <Button\n variant=\"outline\"\n to={blankStateLink}\n color={`${token(\n \"--t-text-color-status-neutral\"\n )} !important`}\n >\n Learn more\n </Button>\n <Button\n as=\"button\"\n theme=\"primary\"\n variant=\"fill\"\n onClick={() => setNewModalVisible(true)}\n >\n Create automation\n </Button>\n </StackView>\n <NewAutomationModal\n open={newModalVisible}\n onRequestClose={() => setNewModalVisible(false)}\n theme={customTheme}\n >\n <NewAutomation\n defaultApp={defaultApp}\n description={blankStateDescription}\n blankStateLink={blankStateLink}\n onRequestClose={() => setNewModalVisible(false)}\n trigger={trigger}\n afterCreateOptions={afterCreateOptions}\n />\n </NewAutomationModal>\n </>\n ) : (\n <>\n <Heading {...BlankStateHeadingProps}>Automations</Heading>\n <Text {...BlankStateTextProps}>\n {permissionDeniedReason}\n </Text>\n </>\n )}\n </StackView>\n </StackView>\n )}\n </Box>\n )}\n {incomingAutomationsParam && (\n <IncomingAutomations\n encryptedParam={incomingAutomationsParam}\n trigger={trigger}\n />\n )}\n </OrganizationContext.Provider>\n <style>{styles}</style>\n </ThemeProvider>\n )\n}\n"],"names":["SvgAutomations","React","createElement","id","xmlns","viewBox","className","opacity","d","fill","x","y","width","height","rx","ry","transform","OrganizationContext","createContext","dateFormat","olsonTimeZone","twentyFourHourTime","Swal","mixin","standardAlertOptions","successAlertOptions","alertError","errorAlertOptions","confirm","standardConfirmOptions","confirmDestroy","destroyConfirmOptions","confirmCreate","createConfirmOptions","async","deobfuscateDescriptions","subscriptions","Promise","all","map","subscription","includes","operationDefinitionClassName","isDeobfuscatable","description","workflow","workflowId","data","peopleClient","get","fields","Workflow","where","url","catch","name","fetchWorkflow","operationParams","workflowName","archivedAt","replace","fieldDefinitionId","definitionIdentifier","match","fieldDefinition","FieldDefinition","FieldOption","include","fetchFieldDefinition","values","dataType","_subscription$operati","_subscription$operati2","Object","entries","action","_fieldDefinition$fiel","value","fieldOptions","find","fieldOption","parseInt","capitalize","join","_fieldDefinition$fiel2","customFieldOptionDescription","deobfuscatedDescription","string","charAt","toUpperCase","slice","Client","root","pcoApiUrl","squiggly","version","fieldListIdentifier","field","listClass","kind","obfuscateDescriptionName","definition","definitionClass","hasOwnProperty","object","key","prototype","call","getListForField","loadedLists","list","Error","JSON","stringify","renderIfChainSatisfied","allFields","selectedFieldOptions","renderIf","isBoolean","conditionKey","keys","shouldRender","upstreamId","upstream","f","getRenderedFields","definitionFields","filter","describeSelectedFields","selectedDefinition","_list$find2","workflow_id_WorkflowsList","sensitiveString","o","toString","workflow_id","obfuscateSelectedFieldDescriptions","_list$find","label","e","momentDateFormat","format","dateLocalized","date","momentDate","moment","isValid","pluralize","count","word","singularize","triggerResourceParts","triggerResource","triggerParts","split","appName","resourceId","length","resourcePath","resourceType","forbiddenText","error","_error$errors","errors","status","webhooksClient","STATUS","delivered","failed","ignored","pending","skipped","fetchPeopleWhoTriggeredEvents","events","personIds","eventPersonId","people","Person","fetchPeople","mergePeopleAndEvents","mergedData","reduce","result","personId","foundPerson","p","push","_extends","person","event","History","automation","filterWhere","onEventsStatusChange","_params$where","loading","paginationProps","refresh","params","setParams","automationId","_","setError","useState","setLoading","eventPages","setEventPages","meta","setMeta","offset","resetOffset","perPage","totalCount","setOffset","currentPage","Math","floor","onPageChange","pageNum","totalPages","ceil","useCallback","usePagination","useEffect","_e","Delivery","Event","order","fetchEvents","per_page","then","pages","bubbleErrorToBoundary","undefined","useEvents","useContext","filteringEvents","automationCreatedRecently","diff","numDaysSince","createdAt","automationBeganOn","historyPreservationAlert","showTzLabel","Intl","DateTimeFormat","resolvedOptions","timeZone","columns","cell","EventStatusBadge","css","padding","header","baseFormat","momentDateTimeFormat","tz","Link","to","maxWidth","EventStatusMessage","flex","Fragment","RetryEventButton","IgnoreEventButton","refreshHistory","textAlign","minWidth","StackView","spacing","token","Heading","level","size","color","weight","Text","italic","Box","minHeight","alignItems","axis","distribution","Input","InputLabel","fontWeight","controls","Select","emptyValue","onChange","selectedValue","title","Option","Button","iconLeft","onClick","theme","variant","maxHeight","overflow","DataTable","empty","alignment","marginTop","marginBottom","svg","fontSize","loadingTitle","bodyCell","lineHeight","bodyRow","rowData","backgroundColor","headerCell","headerRow","setStatus","retryTitleFromStatus","statusIcon","post","attributes","response","eventsStatus","alerts","fire","text","disabled","badgeColors","border","badgeIcon","badgeTitle","Badge","background","foreground","paddingLeft","paddingRight","radius","renderLeft","Icon","marginLeft","stroke","strokeAlign","strokeWeight","lastDelivery","message","delivery","ERRORS","default","duplicated_event","failed_without_deliveries","whiteSpace","ToggleableDetails","details","_response","responseBody","parse","_unused","parsedErrors","responseErrors","deliveryFailureReason","statusMessage","fontStyle","paddingTop","children","open","setOpen","inline","was","fontFamily","ErrorBoundary","Component","constructor","props","super","this","handleContactSupport","onRequestClose","window","openHelpdesk","state","hasError","static","render","Alert","type","marginVertical","boxShadow","style","CloseModalIcon","as","icon","HistoryModal","createPortal","ThemeProvider","Modal","paddingBottom","document","body","VALID_LOGO_NAMES","getValidLogoName","kebabName","kebabCase","isValidLogoName","HIDDEN_FIELD","HIDDEN_RESPONSE","FIELD_KEY_RE","SENTINEL_VALUES","Set","extractIds","_conds$data","_conds$data2","conds","triggerConditions","formId","relationships","form","selectedOptionsByField","_optionIds$","exec","raw","$in","optionIds","Array","isArray","String","has","fieldId","optionId","fetchFieldDefinitions","ids","Map","walk","fd","set","_unused2","fetchCampuses","Campus","campus","_unused3","buildResponseDetails","fieldsByForm","fieldDefs","campuses","_fieldsByForm$get2","fieldLabel","valueLabel","fieldType","fieldableId","options","labelers","resolve","extracted","sub","targets","entry","formIds","FormField","FormFieldOption","byId","fetchFormFields","uniq","t","fieldDefIds","campusIds","_fieldsByForm$get","add","responseDetails","resolveResponseDetails","groups","_groups$get","group","resolvedById","subs","resolved","_resolvedById$get","formatResponseDetails","_excluded","_excluded2","AutomationContext","EditableAutomation","_ref","updateAutomation","onDelete","openHistoryNow","disabledReason","_objectWithoutPropertiesLoose","AutomationWrapper","Header","Icons","Manage","Description","EditableFooter","IncomingAutomation","LinkToAutomation","IncomingDescription","Footer","triggerEventDescription","parseDescription","cardOpacity","active","paddingVertical","truncate","lowerFirst","conditionalSuffix","optionallyPrettifyArchivedPrefix","separator","external","triggerAdminUrl","canManage","tooltip","hover","_ref2","rest","Provider","Card","currentPersonCanCreate","currentPersonId","trigger","historyVisible","setHistoryVisible","isActive","Dropdown","iconRight","Item","onSelect","createdById","Tooltip","placement","openDelay","isConfirmed","resource","avatar","fetchCurrentPersonAvatar","prev","createdBy","avatarUrl","createdByName","confirmButtonText","ToggleSwitch","isChecked","patch","newStatus","triggerProductName","Logo","markOnly","operationAppName","_automation$createdBy","_automation$createdBy2","createdBySuffix","Divider","marginHorizontal","Avatar","basis","source","_automation$createdBy3","_automation$eventsSta","_automation$eventsSta2","_automation$eventsSta3","_automation$eventsSta4","_automation$eventsSta5","_automation$eventsSta6","_automation$createdBy4","buttonProps","paddingHorizontal","historyProps","setHistoryProps","toLocaleString","marginRight","_automation$triggerPa","triggerParams","useTriggerPersonOverride","trim","startsWith","fetchCreatorProfiles","compact","profiles","mergeProfilesAndSubscriptions","profile","fetchTriggerResources","automations","QUERYABLE_BY_MULTIPLE_IDS","registrations","services","NOT_QUERYABLE","automationsByModel","accumulator","automationTriggerResource","promises","flatMap","resourceParts","_QUERYABLE_BY_MULTIPL","fetchNothing","fetchAllAtOnce","fetchOneAtATime","triggerResources","settledPromises","allSettled","acc","concat","fetchResourceName","path","_props","reject","client","model","upperFirst","IncomingAutomations","encryptedParam","setAutomations","App","PersonApp","personApp","allowPcoLogin","app","toLowerCase","fetchPersonApps","operationApps","AutomationSubscription","fetchIncomingAutomations","buildGivingDescription","tr","resourceName","nameOrDescription","triggerResourceName","verb","messageName","mapNameToVerb","buildDescription","mergeTriggerResourceEventDescriptions","noResults","borderBottom","Summary","image","Spinner","TileView","minCellWidth","operationDefinitionId","od","sectionId","section","renderOptionsWithoutConsideringGroup","renderOptions","groupedOptions","groupBy","sort","gt","OptionGroup","Definition","selectedOperation","onOperationDefinitionChange","operationDefinitions","selectedSection","operationDefinitionsWithUniqueIds","primaryOperations","primarySectionOptions","uniqBy","sectionGroup","secondaryOperations","handleAnySelectChange","idType","renderOperations","operations","defaultValue","Field","canAccessPeople","loadListForField","loadingLists","dependencies","generator","memoizedObject","setMemoizedObject","newObject","isEqual","useMemoizedObject","dependsOn","depKey","camelCase","fieldDependencies","listOptions","actionAllowedOptions","op","automationNotAllowed","info","HelperDrawer","Toggle","drawerId","Loading","SelectSearch","Checkbox","TextArea","DateField","Checkboxes","NumberField","PersonSearch","isLoading","TextField","RadioButtons","dangerouslySetInnerHTML","__html","content","console","warn","renderField","overridenEmptyValue","option","groupTypes","TapestrySelect","items","item","handleSelectedValueChange","prompt","generatePrompt","selectedOption","_option$value","selectedLabel","prevSelectedLabel","setPrevSelectedLabel","query","setQuery","showFilteredOptions","setShowFilteredOptions","showClearButton","setShowClearButton","filteredOptions","sortBy","formattedQuery","TapestryCombobox","Popover","closeOnSelect","closeButton","cursor","onBlur","target","onClear","onFocus","select","handleValueChange","openOnFocus","placeholder","popoverProps","matchWidths","renderRight","index","isCurrent","role","Highlight","Menu","_selectedOption$meta","immediateSearch","debouncedSearch","useMemo","debounce","search","cancel","myself","_setQuery","TapestryCheckbox","checked","TapestryTextArea","_field$allowUnanswere","specificDate","setSpecificDate","todaysValue","customValue","dateBeforeValue","orgFormat","dateFieldValue","setDateFieldValue","toDate","allowUnansweredOption","handleSelectChange","TapestryDateField","defaultOpen","formatValue","selectedValues","setSelectedValues","handleCheckboxesChange","newSelectedValues","minimumValue","minValue","maximumValue","maxValue","inputValue","setInputValue","Number","InputBox","TapestryNumberField","newNumberValue","min","max","hasControls","display","handleCheckedChange","Radio","Fields","newSelections","renderableFields","handleSelectedFieldOptionsChange","dependents","dependent","deeper","errorAlertProps","borderRadius","getVisibleApps","Topbar","apps","a","getWebhooksApps","OperationApp","getOperationDefinitions","OperationDefinition","NewAutomation","afterCreateOptions","blankStateLink","debugMode","defaultApp","_selectedDefinition$f","_selectedTriggerEvent","_selectedDefinition$f2","selectedTriggerEvent","setSelectedTriggerEvent","dynamicTriggerConditions","setDynamicTriggerConditions","selectedApp","setSelectedApp","setOperationApps","setOperationDefinitions","loadingOperationDefinitions","setLoadingOperationDefinitions","setSelectedDefinition","setSelectedFieldOptions","setLoadedLists","setLoadingLists","submitting","setSubmitting","callAfterCreate","setCallAfterCreate","setTriggerParams","activeAppRef","useRef","dangerAlertPresent","footerMessage","search_name_or_email","OperationDefinitionList","getListOptions","ret","selected_definition","visibleApps","webhooksApps","getOperationApps","defaultSelection","definitions","current","dynamicConditions","baseConditions","cloneDeep","writableFields","renderOnly","buildTriggerConditions","conditions","getDescription","descriptionParts","submitCreate","onConfirm","location","reload","alert","handleChangeTriggerEvent","triggerEvent","idx","Application","onOperationAppChange","LoadingOperationDefinitions","newDefinition","disableSubmit","param","html","borderTop","operation_params","definition_identifier","operation_app_name","operation_definition_class_name","trigger_conditions","trigger_params","cancelButtonText","getButtonText","operationFields","required","every","fieldIsFilled","fieldIsSelect","nextRequiredDescription","renderedFields","getNextRequiredDescription","autoFocus","handleChange","NewAutomationModal","zIndex","icons","churchCenter","logomark","canCreate","hasActiveAutomations","onPauseAutomations","newModalVisible","setNewModalVisible","isPaused","activeCount","pausedCount","wrap","Automations","blankStateDescription","incomingAutomationsParam","currentOrganization","permissionDeniedReason","fetchAutomations","URLSearchParams","customTheme","toggleAttribute","some","handleDelete","delete","BlankStateHeadingProps","BlankStateTextProps","originalAutomation","newState","updated","newAutomations","margin","mediaQueries","lg","styles"],"mappings":"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"}