{"version":3,"file":"js/memorialsPublic~memorialsPrivate.js","mappings":"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","sources":["webpack://eljs/./javascript/commerce/PayableCheckout.js","webpack://eljs/./javascript/commerce/utils.js","webpack://eljs/./javascript/components/CauseOfDeathAutocomplete.js","webpack://eljs/./javascript/components/CityAutocomplete.js","webpack://eljs/./javascript/components/ExpandableCollapse.js","webpack://eljs/./javascript/components/MobileShareButton.js","webpack://eljs/./javascript/components/Participant.js","webpack://eljs/./javascript/components/ProgressRing.js","webpack://eljs/./javascript/components/SocialPhotoImporter.js","webpack://eljs/./javascript/components/UGCTemplates.js","webpack://eljs/./javascript/components/UserMentions.js","webpack://eljs/./javascript/commerce/BelongingEditor.js","webpack://eljs/./javascript/components/AutoSaveTextField.js","webpack://eljs/./javascript/components/BusinessAssociationForm.js","webpack://eljs/./javascript/components/DateTimePicker.js","webpack://eljs/./javascript/components/EditEvents.js","webpack://eljs/./javascript/components/StockPhotoModal.js","webpack://eljs/./javascript/components/DeceasedPhotoUploader.js","webpack://eljs/./javascript/components/DeceasedSearchAutocomplete.js","webpack://eljs/./javascript/components/FundraiserForm.js","webpack://eljs/./javascript/components/MemorialFeatureAutocomplete.js","webpack://eljs/./javascript/components/OrganDonationForm.js","webpack://eljs/./javascript/components/SubscriberNotificationsModal.js","webpack://eljs/./javascript/memorials/private/relationshipForms.js","webpack://eljs/./javascript/components/MemorialSearch.js","webpack://eljs/./javascript/memorials/private/howToHelp.js","webpack://eljs/./javascript/memorials/private/invites.js","webpack://eljs/./javascript/memorials/private/onboarding.js","webpack://eljs/./javascript/memorials/private/onboardingEvents.js","webpack://eljs/./javascript/memorials/private/onboardingFamily.js","webpack://eljs/./javascript/memorials/private/onboardingFinalRestingPlace.js","webpack://eljs/./javascript/memorials/private/onboardingFundraisingGuidance.js","webpack://eljs/./javascript/memorials/private/onboardingPhoto.js","webpack://eljs/./javascript/memorials/private/onboardingShare.js","webpack://eljs/./javascript/components/WordCounter.js","webpack://eljs/./javascript/memorials/private/partnerObituary.js","webpack://eljs/./javascript/memorials/private/privateChooseCause.js","webpack://eljs/./javascript/memorials/private/private.js","webpack://eljs/./javascript/commerce/PaymentMethod.js","webpack://eljs/./javascript/memorials/rsvps.js"],"sourcesContent":["import { loadStripe } from \"@stripe/stripe-js\";\nimport Collapse from \"bootstrap/js/dist/collapse\";\n\nimport { fadeIn, sendBrowserAgnosticEvent, scrollToElement } from \"../core/utils\";\n\nconst toggleSubmitButtonEnabled = (submitButton, enabled) => {\n  if (submitButton) {\n    submitButton.toggleAttribute(\"disabled\", !enabled);\n    submitButton.classList.toggle(\"disabled\", !enabled);\n  }\n};\n\nconst clearError = () => {\n  const errorMessageContainer = document.querySelector(\"#pc-form .payment-error\");\n  if (errorMessageContainer) {\n    errorMessageContainer.classList.add(\"d-none\");\n  }\n};\n\nconst showError = (errorMessage) => {\n  const errorMessageContainer = document.querySelector(\"#pc-form .payment-error\");\n  if (errorMessageContainer) {\n    errorMessageContainer.innerText = errorMessage;\n    fadeIn(errorMessageContainer);\n  }\n};\n\nexport default async function initPayableCheckout(props) {\n  const stripe = await loadStripe(props.stripePublishableKey);\n\n  document.body.addEventListener(\"payableCheckoutStarted\", () => {\n    clearError();\n  });\n\n  document.body.addEventListener(\"payableCheckoutCanceled\", (event) => {\n    if (event && event.payload && event.payload.message) {\n      showError(event.payload.message);\n      toggleSubmitButtonEnabled(\n        document.querySelector(\"#payable-checkout-submit\"),\n        false,\n      );\n    }\n  });\n\n  document.body.addEventListener(\"initPayableCheckout\", (event) => {\n    sendBrowserAgnosticEvent(document.body, \"elep:disable\");\n    scrollToElement(document.body);\n\n    const checkoutForm = document.getElementById(\"pc-form\");\n\n    if (checkoutForm) {\n      const elements = stripe.elements({\n        clientSecret: event.detail.clientSecret,\n        fonts: [{ cssSrc: \"https://fonts.googleapis.com/css?family=Lato:300,400,700\" }],\n        loader: \"always\",\n      });\n\n      const style = {\n        base: {\n          fontFamily: \"Lato\",\n          fontSize: \"18px\",\n          \"::placeholder\": {\n            color: \"#8e8e8e\",\n          },\n        },\n        invalid: {\n          color: \"#c30c30\",\n        },\n      };\n\n      const submitButton = document.querySelector(\"#payable-checkout-submit\");\n\n      const zipInput = document.getElementById(\"zip\");\n      const cardholderInput = document.getElementById(\"cardholder-name\");\n\n      const stripeElementContainerCollapse = Collapse.getOrCreateInstance(\n        \".stripe-element-container\",\n        { toggle: false },\n      );\n\n      // Create instances of the cardNumber, cardExpiry and cardCvc Elements.\n      const cardNumber = elements.create(\"cardNumber\", { showIcon: true, style });\n      const cardExpiry = elements.create(\"cardExpiry\", { style });\n      const cardCvc = elements.create(\"cardCvc\", { style });\n\n      cardNumber.on(\"ready\", () => {\n        submitButton.classList.remove(\"d-none\");\n        toggleSubmitButtonEnabled(submitButton, false);\n      });\n\n      cardNumber.mount(\"#pc-card-element\");\n      cardExpiry.mount(\"#pc-exp-element\");\n      cardCvc.mount(\"#pc-cvc-element\");\n\n      let cardNumberValid = false;\n      let cardExpiryValid = false;\n      let cardCvcValid = false;\n\n      // This uses private/protected variables in the Stripe Elements implementation.\n      // We have no guarantee that they will remain consistent, but there is indication\n      // that Stripe *probably* won't change it:\n      // https://github.com/stripe-archive/react-stripe-elements/issues/283#issuecomment-772659591\n      const allInputsReady = () =>\n        cardNumberValid &&\n        cardExpiryValid &&\n        cardCvcValid &&\n        zipInput.value.length >= 3 &&\n        cardholderInput.value;\n\n      [cardNumber, cardExpiry, cardCvc].forEach((el) =>\n        el.on(\"change\", (changeEvent) => {\n          switch (el) {\n            case cardNumber:\n              cardNumberValid = changeEvent.complete;\n              break;\n            case cardExpiry:\n              cardExpiryValid = changeEvent.complete;\n              break;\n            case cardCvc:\n              cardCvcValid = changeEvent.complete;\n              break;\n            default:\n              break;\n          }\n\n          const isReady =\n            allInputsReady() && changeEvent.complete && !changeEvent.error;\n          toggleSubmitButtonEnabled(submitButton, isReady);\n\n          if (changeEvent.error && changeEvent.error.message) {\n            showError(changeEvent.error.message, submitButton);\n          } else if (!changeEvent.error) {\n            clearError(submitButton);\n          }\n        }),\n      );\n\n      zipInput.addEventListener(\"input\", () => {\n        toggleSubmitButtonEnabled(submitButton, allInputsReady());\n      });\n\n      cardholderInput.addEventListener(\"input\", () => {\n        toggleSubmitButtonEnabled(submitButton, allInputsReady());\n      });\n\n      const paymentMethodSelect = checkoutForm.querySelector(\n        'select[name=\"saved-payment-method\"]',\n      );\n\n      if (paymentMethodSelect) {\n        paymentMethodSelect.addEventListener(\"change\", () => {\n          if (paymentMethodSelect.value) {\n            stripeElementContainerCollapse.hide();\n            toggleSubmitButtonEnabled(submitButton, true);\n          } else {\n            stripeElementContainerCollapse.show();\n            toggleSubmitButtonEnabled(submitButton, false);\n          }\n        });\n      }\n\n      const savePaymentMethod = checkoutForm.querySelector(\"#save-payment-method\");\n\n      const completeCheckout = async (\n        paymentMethodFromPaymentRequest = null,\n        completeCallback = null,\n      ) => {\n        let response;\n\n        if (event.detail.isSetupIntent) {\n          response = await stripe.confirmCardSetup(event.detail.clientSecret, {\n            payment_method: {\n              card: cardNumber,\n              billing_details: {\n                name: cardholderInput.value,\n                address: {\n                  postal_code: zipInput.value,\n                },\n              },\n            },\n          });\n        } else {\n          let paymentData;\n          if (paymentMethodFromPaymentRequest) {\n            paymentData = { payment_method: paymentMethodFromPaymentRequest.id };\n          } else {\n            paymentData = {\n              payment_method: {\n                card: cardNumber,\n                billing_details: {\n                  name: cardholderInput.value,\n                  address: {\n                    postal_code: zipInput.value,\n                  },\n                },\n              },\n            };\n\n            if (savePaymentMethod && savePaymentMethod.checked) {\n              paymentData.setup_future_usage = \"off_session\";\n            }\n          }\n\n          response = await stripe.confirmCardPayment(\n            event.detail.clientSecret,\n            paymentData,\n          );\n        }\n\n        if (response.error) {\n          if (completeCallback) {\n            completeCallback(\"fail\");\n          }\n\n          if (response.error.message) {\n            showError(response.error.message);\n            toggleSubmitButtonEnabled(submitButton, false);\n          } else if (window.Rollbar) {\n            window.Rollbar.error(\n              `Error confirming checkout ${event.detail.isSetupIntent ? \"setup\" : \"payment\"}`,\n              response.error,\n            );\n          }\n\n          sendBrowserAgnosticEvent(\n            checkoutForm,\n            \"payableCheckoutCanceled\",\n            response.error,\n          );\n          sendBrowserAgnosticEvent(checkoutForm, \"cancel-submit-protect\");\n\n          return;\n        }\n\n        if (completeCallback) {\n          completeCallback(\"success\");\n        }\n\n        if (\n          !event.detail.isSetupIntent &&\n          response.paymentIntent.status === \"requires_action\"\n        ) {\n          const actionResponse = await stripe.confirmCardPayment(\n            event.detail.clientSecret,\n          );\n\n          if (actionResponse.error) {\n            if (actionResponse.error.message) {\n              showError(actionResponse.error.message);\n              toggleSubmitButtonEnabled(submitButton, false);\n            } else if (window.Rollbar) {\n              window.Rollbar.error(\n                `Error confirming checkout ${event.detail.isSetupIntent ? \"setup\" : \"payment\"} (inner confirm)`,\n                response.error,\n              );\n            }\n\n            sendBrowserAgnosticEvent(\n              checkoutForm,\n              \"payableCheckoutCanceled\",\n              actionResponse.error,\n            );\n            sendBrowserAgnosticEvent(checkoutForm, \"cancel-submit-protect\");\n\n            return;\n          }\n        }\n\n        sendBrowserAgnosticEvent(checkoutForm, \"payableCheckoutComplete\");\n      };\n\n      const paymentRequest = stripe.paymentRequest(event.detail.paymentRequestParams);\n      const prButton = elements.create(\"paymentRequestButton\", {\n        paymentRequest,\n      });\n\n      (async () => {\n        const result = await paymentRequest.canMakePayment();\n        if (result) {\n          document.getElementById(\"pc-payment-request-container\").classList.add(\"show\");\n          prButton.mount(\"#pc-payment-request-button\");\n        }\n      })();\n\n      paymentRequest.on(\"paymentmethod\", async (paymentMethodEvent) => {\n        await completeCheckout(\n          paymentMethodEvent.paymentMethod,\n          paymentMethodEvent.complete,\n        );\n      });\n\n      checkoutForm.addEventListener(\"submit\", async (submitEvent) => {\n        submitEvent.preventDefault();\n\n        sendBrowserAgnosticEvent(checkoutForm, \"payableCheckoutStarted\");\n\n        const selectedPaymentMethod = paymentMethodSelect && paymentMethodSelect.value;\n        if (selectedPaymentMethod) {\n          sendBrowserAgnosticEvent(checkoutForm, \"savedPaymentMethodSubmit\");\n\n          return;\n        }\n\n        await completeCheckout();\n      });\n    }\n  });\n}\n","import { sendBrowserAgnosticEvent } from \"../core/utils\";\n\nconst supportsBlur = () =>\n  CSS &&\n  (CSS.supports(\"backdrop-filter: blur(20px)\") ||\n    CSS.supports(\"-webkit-backdrop-filter: blur(20px)\"));\n\nexport function initProductPhotoBlur(threshold = 0.2) {\n  const images = document.querySelectorAll(\".product-photo\");\n\n  const processImage = (img) => {\n    const aspect = img.naturalWidth / img.naturalHeight;\n    if (Math.abs(aspect - 1.333) <= threshold) {\n      img.closest(\".product-photo-container\").classList.add(\"fill\");\n    } else {\n      const canvas = document.createElement(\"canvas\");\n      canvas.width = img.naturalWidth;\n      canvas.height = img.naturalHeight;\n\n      const ctx = canvas.getContext(\"2d\");\n      ctx.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight);\n\n      const pixelCoordinates = [\n        [0, 0],\n        [0, canvas.height / 2],\n        [0, canvas.height - 1],\n        [canvas.width / 2, 0],\n        [canvas.width / 2, canvas.height - 1],\n        [canvas.width - 1, 0],\n        [canvas.width - 1, canvas.height / 2],\n        [canvas.width - 1, canvas.height - 1],\n      ];\n\n      const pixelData = pixelCoordinates.map((p) =>\n        ctx.getImageData(p[0], p[1], 1, 1).data.slice(0, 4),\n      );\n\n      const container = img.parentNode;\n\n      if (pixelData.every((d) => d.every((p, i) => p === pixelData[0][i]))) {\n        const bg = pixelData[0];\n        container.style.backgroundColor = `rgb(${bg[0]}, ${bg[1]}, ${bg[2]}, ${bg[3]})`;\n      } else if (\"objectFit\" in document.documentElement.style && supportsBlur()) {\n        container.style.backgroundImage = `url('${img.src}')`;\n        container.style.backgroundSize = \"cover\";\n      } else {\n        const avg = pixelData\n          .reduce((acc, curr) => acc.map((val, idx) => val + curr[idx]), [0, 0, 0, 0])\n          .map((val) => val / pixelData.length);\n        container.style.backgroundColor = `rgb(${avg[0]}, ${avg[1]}, ${avg[2]}, ${avg[3]})`;\n      }\n    }\n  };\n\n  if (images && images.forEach) {\n    images.forEach((image) => {\n      image.addEventListener(\"load\", () => {\n        processImage(image);\n      });\n      if (image.complete) {\n        sendBrowserAgnosticEvent(image, \"load\");\n      }\n    });\n  }\n}\n\nexport function initCheckoutDynamicFormFields(props) {\n  // Delivery instructions display toggle.\n  const toggleTriggers = document.querySelectorAll(\n    '[data-toggle-for=\"delivery-instructions\"]',\n  );\n  toggleTriggers.forEach((trigger) =>\n    trigger.addEventListener(\"click\", () => {\n      const toggleTargets = document.querySelectorAll(\n        '[data-toggle-name=\"delivery-instructions\"]',\n      );\n      toggleTargets.forEach((t) => {\n        t.classList.toggle(\"d-none\");\n      });\n    }),\n  );\n\n  if (!props.skipBillingAndDeliverySync) {\n    let billingNameChanged = false;\n    const deliveryNameInput = document.getElementById(props.formFieldIds.deliveryName);\n    const billingNameInput = document.getElementById(props.formFieldIds.billingName);\n\n    if (deliveryNameInput && billingNameInput) {\n      deliveryNameInput.addEventListener(\"input\", () => {\n        if (!billingNameChanged || !billingNameInput.value) {\n          billingNameInput.value = deliveryNameInput.value;\n          billingNameChanged = false;\n          sendBrowserAgnosticEvent(billingNameInput, \"fill\");\n        }\n      });\n\n      billingNameInput.addEventListener(\"click\", () => {\n        billingNameChanged = true;\n      });\n    }\n  }\n}\n","import TomSelect from \"tom-select/dist/js/tom-select.base\";\n/**\n * Initialize the cause-of-death search/autocomplete behavior.\n *\n * @param {object} props - the page props\n */\nexport default function initCauseOfDeathAutocomplete(props) {\n  const causeOfDeathInput = document.getElementById(props.inputId);\n\n  if (!causeOfDeathInput) {\n    return;\n  }\n\n  const tomSelectConfig = {\n    create: (input) => ({ id: input.trim(), text: input.trim(), created: true }),\n    maxItems: 1,\n    placeholder: \"Ex. Cancer\",\n    valueField: \"id\",\n    sortField: [{ field: \"$order\" }, { field: \"$score\" }],\n  };\n\n  const tomSelect = new TomSelect(causeOfDeathInput, tomSelectConfig);\n\n  // Set the value, creating a new option if necessary\n  if (props.initialAutocompleteData) {\n    const availableOption = tomSelect.options[props.initialAutocompleteData.id];\n    if (!availableOption) {\n      tomSelect.addOption(props.initialAutocompleteData);\n    }\n\n    tomSelect.setValue(props.initialAutocompleteData.id);\n  }\n\n  // We want to disable the search bar when we have one of the association boolean\n  // checkboxes selected\n  let notShared;\n  if (props.notShared) {\n    notShared = document.getElementById(props.notShared);\n  }\n\n  if (props.notShared && props.initialPendingData) {\n    tomSelect.disable();\n  }\n\n  if (props.notShared) {\n    notShared.addEventListener(\"change\", () => {\n      // If the user selected a check box we should disable the search box\n      if (notShared.checked) {\n        tomSelect.clear();\n        tomSelect.disable();\n      } else {\n        tomSelect.enable();\n      }\n    });\n  }\n\n  const strInput = document.getElementById(props.strInputId);\n  if (strInput) {\n    const form = strInput.closest(\"form\");\n    if (form) {\n      form.addEventListener(\"submit\", () => {\n        // When a user is submitting a user-created item (i.e a cause of death\n        // not listed), we need to update the information that is submitted by the form.\n        const selectedOption = tomSelect.options[tomSelect.getValue()];\n        if (selectedOption && selectedOption.created) {\n          strInput.value = selectedOption.text;\n          tomSelect.clear();\n        } else {\n          strInput.value = \"\";\n        }\n\n        // If the user is able to come back to the form and select that they are\n        // not going to sharing a cause of death, we want to trigger a change to the\n        // string that will remove their cause of death if there is one already set.\n        if (notShared && notShared.checked) {\n          strInput.value = \"\";\n          tomSelect.clear();\n        }\n      });\n    }\n  }\n}\n","import TomSelect from \"tom-select/dist/js/tom-select.base\";\nimport TomSelect_virtual_scroll from \"tom-select/dist/js/plugins/virtual_scroll\";\n\nimport { createAutocompleteOption } from \"../places/utils\";\nimport requests, { ResponseError } from \"../core/requests\";\n\nTomSelect.define(\"virtual_scroll\", TomSelect_virtual_scroll);\n\n/**\n * Format the city search result for display in the autocomplete.\n *\n * @param {object} city - an object representing a city in search results\n * @returns {HTMLDivElement} - the rendered element for embedding in the dropdown\n */\nconst formatCity = (city) => createAutocompleteOption(city.text);\n\n/**\n * Initialize the autocomplete behavior for city search.\n *\n * @param {object} props - the page props\n * @returns {HTMLElement|null} - the input to which the autocomplete behavior is bound\n */\nexport default function initCityAutocomplete(props) {\n  const cityIdentifierInput = document.getElementById(props.cityIdentifierInputId);\n  if (!cityIdentifierInput) {\n    return null;\n  }\n\n  let openUrlOnSelect = false;\n  if (\"openUrlOnSelect\" in props) {\n    ({ openUrlOnSelect } = props);\n  }\n\n  /**\n   * Compose the URL combining the search query and the desired page number.\n   *\n   * @param {string} query - a search query\n   * @param {number} page - a page number\n   * @returns {string} - the generated URL.\n   */\n  const buildUrl = (query, page) => {\n    const paramsData = { search: query };\n\n    if (props.businessTypeName) {\n      paramsData[\"for-business-type\"] = props.businessTypeName;\n    }\n\n    paramsData.page = page;\n\n    const params = new URLSearchParams(paramsData);\n\n    return `${props.citySearchUrl}?${params.toString()}`;\n  };\n\n  const tomSelectConfig = {\n    plugins: [\"virtual_scroll\"],\n    valueField: \"id\",\n    sortField: [{ field: \"$order\" }, { field: \"$score\" }],\n    searchField: [],\n    firstUrl(query) {\n      return buildUrl(query, 1);\n    },\n    async load(query, callback) {\n      try {\n        const response = await requests.get(this.getUrl(query));\n\n        if (!response.ok) {\n          throw new ResponseError(response);\n        }\n\n        const data = await response.json();\n\n        if (data.pagination.next) {\n          const nextUrl = buildUrl(query, data.pagination.next);\n          this.setNextUrl(query, nextUrl);\n        }\n\n        callback(data.results);\n      } catch (error) {\n        if (!(error.response && error.response.status === 429)) {\n          window.Rollbar.error(\"TomSelect city search error\", error);\n        }\n\n        callback();\n      }\n    },\n    loadThrottle: 500,\n    placeholder: props.placeholder || \"Please select a city\",\n    render: {\n      option: (item) => formatCity(item),\n      not_loading: (data) => {\n        if (data.input.length === 0) {\n          return null;\n        }\n\n        return '<div class=\"no-results\">Please enter more text.</div>';\n      },\n    },\n    shouldLoad: (query) => query.length >= 3,\n    onChange(value) {\n      if (openUrlOnSelect && value) {\n        const optionSelected = this.options[value];\n        if (openUrlOnSelect) {\n          window.location.href = optionSelected.url;\n        }\n      }\n    },\n    maxItems: 1,\n  };\n\n  new TomSelect(cityIdentifierInput, tomSelectConfig);\n\n  return cityIdentifierInput;\n}\n","import Collapse from \"bootstrap/js/dist/collapse\"; // eslint-disable-line no-unused-vars\n\n/**\n * Initialize the expandable collapse element. Can be called again and again on the same\n * element. This is useful when you have an element whose size isn't settled until it's\n * visible.\n *\n * The given element should have the `expandable-collapse` classes and bet configured as\n * a Bootstrap Collapse.\n *\n * The HTML for the controls is as follows:\n *\n * <div class=\"control\">\n *   <a href=\"javascript:;\" data-bs-toggle=\"collapse\" data-bs-target=\"<collapse-id>\" aria-expanded=\"false\">\n *     <span class=\"more\">Read More</span>\n *     <span class=\"less\">Read Less</span>\n *   </a>\n * </div>\n *\n * @param {HTMLElement} rootElement - the collapse element.\n */\nexport function initExpandableCollapse(rootElement) {\n  let lineCount = 1;\n  if (rootElement.dataset.collapsedLineCount) {\n    lineCount = parseInt(rootElement.dataset.collapsedLineCount, 10);\n  }\n\n  const lineHeightStr = window.getComputedStyle(rootElement).lineHeight;\n  const lineHeight = parseInt(lineHeightStr.replace(\"px\", \"\"), 10);\n  const collapsedHeight = lineHeight * lineCount;\n  const gradientHeight = Math.max(collapsedHeight / 3, lineHeight * 2);\n\n  if (rootElement.scrollHeight > 0 && rootElement.scrollHeight < collapsedHeight + 20) {\n    rootElement.classList.add(\"show\", \"short\");\n  } else {\n    rootElement.style.setProperty(\n      \"--expandable-collapse-gradient-height\",\n      `${gradientHeight}px`,\n    );\n    rootElement.style.setProperty(\n      \"--expandable-collapse-collapsed-height\",\n      `${collapsedHeight}px`,\n    );\n  }\n}\n\n/**\n * Initialize the expandable collapse element.\n */\nexport default function initExpandableCollapses() {\n  document.querySelectorAll(\".expandable-collapse\").forEach((rootElement) => {\n    initExpandableCollapse(rootElement);\n  });\n}\n","import \"share-api-polyfill\";\n\n/**\n * Given a query selector, get the element and initiate `navigator.share` behavior on it\n * Gracefully accepts nonexistent elements and incompatible browsers.\n *\n * @param {string} selector - a query selector of a .btn-native-share element\n */\nexport default function initMobileShareButton(selector) {\n  const shareButton = document.querySelector(selector);\n  if (shareButton) {\n    shareButton.addEventListener(\"click\", () => {\n      if (navigator && navigator.share) {\n        navigator\n          .share({\n            title: shareButton.dataset.shareTitle,\n            url: shareButton.dataset.shareUrl,\n          })\n          .catch(() => {\n            // Do nothing but swallow unhandled promise rejections.\n          });\n      }\n    });\n  }\n}\n","import Modal from \"bootstrap/js/dist/modal\";\nimport TomSelect from \"tom-select/dist/js/tom-select.base\";\nimport TomSelect_remove_button from \"tom-select/dist/js/plugins/remove_button\";\nimport TomSelect_virtual_scroll from \"tom-select/dist/js/plugins/virtual_scroll\";\n\nimport { runInviteFormValidation } from \"./UserMentions\";\nimport { createAutocompleteOption } from \"../places/utils\";\nimport requests, { ResponseError } from \"../core/requests\";\n\nTomSelect.define(\"remove_button\", TomSelect_remove_button);\nTomSelect.define(\"virtual_scroll\", TomSelect_virtual_scroll);\n\nconst NO_CHANGES_CLASS = \"no-changes\";\n\n/**\n * Format a participant for display in autocomplete dropdown.\n *\n * @param {object} participant - the participant data from the server response.\n * @returns {HTMLDivElement|null} - the rendered element (or null)\n */\nconst formatParticipant = (participant) => {\n  if (participant.name && participant.thumbnailUrl) {\n    const img = document.createElement(\"img\");\n    img.setAttribute(\"class\", \"user-profile-photo\");\n    img.setAttribute(\"src\", participant.thumbnailUrl);\n    img.setAttribute(\"alt\", \"User profile photo\");\n\n    return createAutocompleteOption([img, participant.name]);\n  }\n  if (participant.name && !participant.thumbnailUrl) {\n    return createAutocompleteOption(participant.name);\n  }\n\n  return null;\n};\n\n/**\n * Clear the invite modal form.\n *\n * @param {Element} inviteModal - the modal container.\n */\nconst clearInviteForm = (inviteModal) => {\n  const inviteFormInputs = inviteModal.querySelectorAll(\"input\");\n  inviteFormInputs.forEach((inviteInput) => {\n    inviteInput.value = \"\";\n  });\n  inviteModal.removeAttribute(\"data-temporary-participant-identifier\");\n\n  const modalParticipantData = inviteModal.querySelector(\".temporary-participant-data\");\n  modalParticipantData.setAttribute(\"value\", \"\");\n};\n\n/**\n * Initialize participant autocomplete behavior, including invite-participant modal.\n *\n * @param {object} props - the page props\n * @returns {Function} - an anonymous function to flush participant data to the json-\n *     data field.\n */\nexport default function initParticipantAutocomplete(props) {\n  const {\n    participantsInitialAutocompleteData = [],\n    participantsInputIds: { participants, participantsJson },\n    userMention: { memorialSlug, userSearchEndpoint },\n  } = props;\n\n  const participantsField = document.querySelector(`#${participants}`);\n  // Values are added to participantsField by tomselect which causes the dirty form\n  // tracker to think there's been a change. We add the NO_CHANGES_CLASS on initial load\n  // so that the dirty form tracker knows to ignore the field. On field change, the\n  // NO_CHANGES_CLASS is removed.\n  participantsField.classList.add(NO_CHANGES_CLASS);\n  const hiddenParticipantsJsonInput = document.querySelector(`#${participantsJson}`);\n  const form = participantsField.closest(\"form\");\n\n  // this houses the participant data before submission\n  participantsField.temporaryParticipants = participantsInitialAutocompleteData;\n  const currentParticipantsIdentifier = `${participants}-temp`;\n\n  const inviteModal = document.querySelector(\"#modal-user-mention\");\n  const modalParticipantData = inviteModal.querySelector(\".temporary-participant-data\");\n\n  function flushParticipantDataToJsonField() {\n    hiddenParticipantsJsonInput.setAttribute(\n      \"value\",\n      JSON.stringify(participantsField.temporaryParticipants),\n    );\n    clearInviteForm(inviteModal);\n\n    participantsField.tomselect.clear();\n  }\n\n  /**\n   * Compose the URL combining the search query and the desired page number.\n   *\n   * @param {string} query - a search query\n   * @param {number} page - a page number\n   * @returns {string} - the generated URL.\n   */\n  const buildUrl = (query, page) => {\n    const paramsData = {\n      search: query,\n      \"memorial-slug\": memorialSlug,\n    };\n\n    paramsData.page = page;\n\n    const params = new URLSearchParams(paramsData);\n\n    return `${userSearchEndpoint}?${params.toString()}`;\n  };\n\n  const tomSelectConfig = {\n    sortField: [{ field: \"$order\" }, { field: \"$score\" }],\n    searchField: [],\n    create: (input) => {\n      const term = input.trim();\n\n      if (term === \"\") {\n        return null;\n      }\n\n      return {\n        id: term,\n        name: term,\n        created: true,\n        text: term,\n      };\n    },\n    firstUrl(query) {\n      return buildUrl(query, 1);\n    },\n    async load(query, callback) {\n      try {\n        const response = await requests.get(this.getUrl(query));\n\n        if (!response.ok) {\n          throw new ResponseError(response);\n        }\n\n        const data = await response.json();\n\n        if (data.pagination.next) {\n          const nextUrl = buildUrl(query, data.pagination.next);\n          this.setNextUrl(query, nextUrl);\n        }\n\n        callback(\n          data.results.map((user) => ({\n            id: user.userHash,\n            name: user.userMentionName,\n            created: false,\n            text: user.userMentionName,\n            thumbnailUrl: user.thumbnailUrl,\n            userSlug: user.userSlug,\n          })),\n        );\n      } catch (error) {\n        if (!(error.response && error.response.status === 429)) {\n          window.Rollbar.error(\"TomSelect event participant error\", error);\n        }\n\n        callback();\n      }\n    },\n    loadThrottle: 500,\n    render: {\n      option: (item) => formatParticipant(item),\n      not_loading: (data) => {\n        if (data.input.length === 0) {\n          return null;\n        }\n\n        return '<div class=\"no-results\">Please enter more text.</div>';\n      },\n    },\n    shouldLoad: (query) => query.length >= 3,\n    placeholder: \"Example: Laura Adams\",\n    plugins: {\n      virtual_scroll: true,\n      remove_button: {\n        title: \"Remove this item\",\n      },\n    },\n    valueField: \"id\",\n  };\n\n  const participantAutocomplete = new TomSelect(participantsField, tomSelectConfig);\n\n  if (\n    participantsInitialAutocompleteData &&\n    participantsInitialAutocompleteData.length\n  ) {\n    participantAutocomplete.addOptions(participantsInitialAutocompleteData);\n    participantAutocomplete.addItems(\n      participantsInitialAutocompleteData.map((data) => data.id),\n    );\n  }\n\n  participantAutocomplete.on(\"item_remove\", (value) => {\n    participantsField.dataset.unselect = true;\n    participantsField.classList.remove(NO_CHANGES_CLASS);\n\n    const deselectedData = participantAutocomplete.options[value];\n\n    participantsField.temporaryParticipants =\n      participantsField.temporaryParticipants.filter(\n        (participantData) =>\n          !(\n            participantData.id === deselectedData.id &&\n            participantData.name === deselectedData.name &&\n            participantData.created === deselectedData.created &&\n            participantData.userSlug === deselectedData.userSlug\n          ),\n      );\n  });\n\n  // On open, close dropdown immediately if has data-unselect\n  participantAutocomplete.on(\"dropdown_open\", () => {\n    if (participantsField.dataset.unselect) {\n      participantAutocomplete.close();\n      participantsField.removeAttribute(\"data-unselect\");\n    }\n  });\n\n  // On select\n  participantAutocomplete.on(\"item_add\", (value) => {\n    participantsField.classList.remove(NO_CHANGES_CLASS);\n    const selectedOption = participantAutocomplete.options[value];\n\n    if (selectedOption.created) {\n      Modal.getOrCreateInstance(inviteModal).show();\n      modalParticipantData.setAttribute(\"value\", JSON.stringify(selectedOption));\n      inviteModal.dataset.temporaryParticipantIdentifier =\n        currentParticipantsIdentifier;\n    } else {\n      // existing user chosen\n      participantsField.temporaryParticipants.push(selectedOption);\n    }\n  });\n\n  form.addEventListener(\"submit\", () => {\n    flushParticipantDataToJsonField();\n  });\n\n  inviteModal.addEventListener(\"input\", () => {\n    runInviteFormValidation(inviteModal.querySelector(\"form\"));\n  });\n\n  inviteModal\n    .querySelector(\".notify-user-mention-button\")\n    .addEventListener(\"click\", () => {\n      Modal.getOrCreateInstance(inviteModal).hide();\n\n      if (\n        inviteModal.dataset.temporaryParticipantIdentifier ===\n          currentParticipantsIdentifier &&\n        modalParticipantData.value\n      ) {\n        const inviteData = JSON.parse(modalParticipantData.value);\n        const firstNameField = inviteModal.querySelector(\n          \"#user-mention-invite-first-name\",\n        );\n        const lastNameField = inviteModal.querySelector(\n          \"#user-mention-invite-last-name\",\n        );\n        const emailField = inviteModal.querySelector(\"#user-mention-invite-email\");\n\n        inviteData.name = `${firstNameField.value} ${lastNameField.value}`;\n        inviteData.email = emailField.value;\n\n        participantsField.temporaryParticipants.push(inviteData);\n        clearInviteForm(inviteModal);\n      }\n    });\n\n  inviteModal\n    .querySelector(\".cancel-notify-user-mention-button\")\n    .addEventListener(\"click\", () => {\n      if (\n        inviteModal.dataset.temporaryParticipantIdentifier ===\n          currentParticipantsIdentifier &&\n        modalParticipantData.value\n      ) {\n        participantsField.temporaryParticipants.push(\n          JSON.parse(modalParticipantData.value),\n        );\n        clearInviteForm(inviteModal);\n      }\n    });\n\n  return flushParticipantDataToJsonField;\n}\n","export default class ProgressRing {\n  constructor(root, initialPercentage = 0) {\n    this.root = root;\n    this.circle = this.root.querySelector(\".progress-ring__circle\");\n    this.label = this.root.querySelector(\".progress-ring__label\");\n\n    const radius = this.circle.r.baseVal.value;\n    const circumference = radius * 2 * Math.PI;\n\n    this.circle.style.strokeDasharray = `${circumference} ${circumference}`;\n    this.circle.style.strokeDashoffset = `${circumference}`;\n\n    this.setPercentage(parseInt(initialPercentage, 10));\n  }\n\n  setPercentage(newPercentage) {\n    const radius = this.circle.r.baseVal.value;\n    const circumference = radius * 2 * Math.PI;\n    this.circle.style.strokeDashoffset =\n      circumference - (newPercentage / 100) * circumference;\n\n    if (this.label) {\n      this.label.textContent = `${newPercentage}%`;\n    }\n  }\n}\n","import Modal from \"bootstrap/js/dist/modal\";\n\nexport const SocialSource = {\n  FACEBOOK: \"facebook\",\n};\n\nSocialSource.display = (value) => {\n  switch (value) {\n    case SocialSource.FACEBOOK:\n      return \"Facebook\";\n    default:\n      return \"Somewhere\";\n  }\n};\n\nclass FacebookImporter {\n  constructor(mediaImporter) {\n    this.mediaImporter = mediaImporter;\n    this.auth = null;\n\n    this.nextCursor = null;\n    this.nextAlbumCursor = null;\n\n    this.selectedAlbum = null;\n  }\n\n  getAlbumsUrl() {\n    const baseUrl = \"/me/albums?fields=id,images,name,picture\";\n\n    return this.nextAlbumCursor ? `${baseUrl}&after=${this.nextAlbumCursor}` : baseUrl;\n  }\n\n  getMediaUrl() {\n    const baseUrl = this.selectedAlbum\n      ? `/${this.selectedAlbum.id}/photos?fields=id,images,name,picture`\n      : \"/me/photos/uploaded?fields=id,images,name,picture\";\n\n    return this.nextCursor ? `${baseUrl}&after=${this.nextCursor}` : baseUrl;\n  }\n\n  authenticate(next, authType = null) {\n    const options = {\n      return_scopes: true,\n      scope: \"public_profile,user_photos\",\n    };\n\n    if (authType) {\n      options.auth_type = authType;\n    }\n\n    window.FB.login((response) => {\n      if (response.status === \"connected\") {\n        if (response.authResponse.grantedScopes.includes(\"user_photos\")) {\n          this.auth = response.authResponse;\n          if (this.auth) {\n            next();\n          } else {\n            this.mediaImporter.error(\n              \"There was a problem with your login. Please try again.\",\n            );\n          }\n        } else {\n          this.mediaImporter.error(\n            \"You denied permission to your photos. Please try again and be sure to allow photos permissions.\",\n          );\n        }\n      } else {\n        this.mediaImporter.error(\n          \"An error occurred connecting to your Facebook account. Please try again.\",\n        );\n      }\n    }, options);\n  }\n\n  loadAlbums() {\n    this.mediaImporter.loading();\n\n    if (this.auth) {\n      window.FB.api(this.getAlbumsUrl(), (response) => {\n        if (response && !response.error) {\n          this.nextAlbumCursor =\n            response.data.length === 25 &&\n            response.paging &&\n            response.paging.cursors &&\n            response.paging.cursors.after;\n          this.mediaImporter.albumsReceived(\n            response.data.map((node) => ({\n              id: node.id,\n              name: node.name,\n              thumbnail: node.picture.data.url,\n            })),\n          );\n        } else {\n          this.mediaImporter.error(response.error);\n        }\n      });\n    } else {\n      this.authenticate(() => {\n        this.loadAlbums();\n      });\n    }\n  }\n\n  selectAlbum(album) {\n    this.media = [];\n    this.selectedAlbum = album;\n  }\n\n  loadMedia() {\n    this.mediaImporter.loading();\n\n    if (this.auth) {\n      window.FB.api(this.getMediaUrl(), (response) => {\n        if (response && !response.error) {\n          this.nextCursor =\n            response.data.length === 25 &&\n            response.paging &&\n            response.paging.cursors &&\n            response.paging.cursors.after;\n\n          this.mediaImporter.mediaReceived(\n            response.data.map((node) => ({\n              id: node.id,\n              caption: node.name,\n              thumbnail: node.picture,\n              url: node.images[0].source,\n            })),\n          );\n        } else {\n          this.mediaImporter.error(response.error);\n        }\n      });\n    } else {\n      this.authenticate(() => {\n        this.loadMedia();\n      });\n    }\n  }\n\n  reset() {\n    this.nextCursor = null;\n    this.nextAlbumCursor = null;\n    this.selectedAlbum = null;\n  }\n}\n\nexport class SocialPhotoImporter {\n  constructor(root, onPhotosSelected, maxAllowed = 20) {\n    // DOM elements\n    this.root = root;\n    this.modal = Modal.getOrCreateInstance(this.root);\n    this.albumList = this.root.querySelector(\".album-list\");\n    this.mediaGrid = this.root.querySelector(\".media-grid\");\n    this.selectedMediaGrid = this.root.querySelector(\".selected-media-grid\");\n    this.errorContainer = this.root.querySelector(\".overlay.error\");\n    this.loadingContainer = this.root.querySelector(\".overlay.loading\");\n\n    this.loadingMoreContainer = this.mediaGrid.querySelector(\".loading-more\");\n    this.loadMoreMedia = this.mediaGrid.querySelector(\".load-more\");\n\n    this.loadingMoreAlbumsContainer = this.albumList.querySelector(\".loading-more\");\n    this.loadMoreAlbums = this.albumList.querySelector(\".load-more\");\n\n    // Media state\n    this.albums = [];\n    this.selectedAlbum = null;\n\n    this.media = [];\n    this.selectedMedia = [];\n\n    // Importer state\n    this.facebookImporter = new FacebookImporter(this);\n    this.activeImporter = null;\n\n    // Other\n    this.maximum = maxAllowed;\n    this.root.querySelector(\".max-allowed\").innerText = `${this.maximum}`;\n\n    this.root.addEventListener(\"hidden.bs.modal\", () => {\n      this.reset();\n    });\n\n    this.mediaGrid.querySelector(\".album-back\").addEventListener(\"click\", () => {\n      this.selectAlbum(null);\n    });\n\n    this.root.querySelector(\".import-photos-submit\").addEventListener(\"click\", () => {\n      this.hide();\n      onPhotosSelected(this.selectedMedia.map((media) => media.url));\n    });\n\n    this.loadMoreMedia.addEventListener(\"click\", () => {\n      if (this.activeImporter) {\n        this.activeImporter.loadMedia();\n      }\n    });\n\n    this.loadMoreAlbums.addEventListener(\"click\", () => {\n      if (this.activeImporter && this.activeImporter.loadAlbums) {\n        this.activeImporter.loadAlbums();\n      }\n    });\n  }\n\n  show(source) {\n    if (source === SocialSource.FACEBOOK) {\n      this.activeImporter = this.facebookImporter;\n    }\n\n    if (this.activeImporter) {\n      if (this.activeImporter.loadAlbums) {\n        this.activeImporter.loadAlbums();\n      } else {\n        this.activeImporter.loadMedia();\n      }\n\n      this.root.querySelector(\".source-name\").innerText = SocialSource.display(source);\n      this.modal.show();\n    }\n  }\n\n  hide() {\n    this.modal.hide();\n  }\n\n  resetMedia() {\n    this.media = [];\n\n    if (this.activeImporter && this.activeImporter.nextCursor) {\n      this.activeImporter.nextCursor = null;\n    }\n  }\n\n  reset() {\n    this.albums = [];\n    this.selectedAlbum = null;\n    this.selectedMedia = [];\n\n    if (this.activeImporter) {\n      this.activeImporter.reset();\n    }\n\n    this.render();\n  }\n\n  retry() {\n    if (this.activeImporter) {\n      if (this.activeImporter.auth) {\n        if (this.selectedAlbum || !this.activeImporter.loadAlbums) {\n          this.activeImporter.loadMedia();\n        } else {\n          this.activeImporter.loadAlbums();\n        }\n      } else {\n        this.activeImporter.authenticate(() => {\n          if (this.activeImporter.loadAlbums) {\n            this.activeImporter.loadAlbums();\n          } else {\n            this.activeImporter.loadMedia();\n          }\n        }, \"rerequest\");\n      }\n    }\n  }\n\n  mediaReceived(media) {\n    this.media.push(...media);\n    this.render();\n  }\n\n  albumsReceived(albums) {\n    this.albums.push(...albums);\n    this.render();\n  }\n\n  render() {\n    const existingAlbumIds = this.albums.map((a) => `${a.id}`);\n    this.albumList.querySelectorAll(\".album\").forEach((node) => {\n      if (!existingAlbumIds.includes(node.id)) {\n        node.remove();\n      }\n    });\n\n    this.albums.forEach((album) => {\n      const existingAlbumElement = document.getElementById(album.id);\n\n      if (!existingAlbumElement) {\n        const newAlbumElement = document.createElement(\"a\");\n        newAlbumElement.href = \"javascript:;\";\n        newAlbumElement.classList.add(\"album\");\n        const newAlbumThumb = document.createElement(\"img\");\n        newAlbumThumb.classList.add(\"thumbnail\");\n        newAlbumThumb.src = album.thumbnail;\n        const newAlbumTitle = document.createElement(\"div\");\n        newAlbumTitle.classList.add(\"title\");\n        newAlbumTitle.innerText = album.name;\n\n        newAlbumElement.appendChild(newAlbumThumb);\n        newAlbumElement.appendChild(newAlbumTitle);\n\n        newAlbumElement.addEventListener(\"click\", () => {\n          this.selectAlbum(album);\n        });\n\n        this.albumList.insertBefore(newAlbumElement, this.loadingMoreAlbumsContainer);\n      }\n    });\n\n    const existingIds = this.media.map((m) => `${m.id}`);\n    this.mediaGrid.querySelectorAll(\".media\").forEach((node) => {\n      if (!existingIds.includes(node.id)) {\n        node.remove();\n      }\n    });\n\n    this.media.forEach((media) => {\n      const existingMediaElement = document.getElementById(media.id);\n      const isSelected = this.selectedMedia.filter((m) => m.id === media.id).length;\n\n      if (existingMediaElement) {\n        existingMediaElement.classList.toggle(\"selected\", isSelected);\n      } else {\n        const newMediaElement = document.createElement(\"div\");\n        newMediaElement.classList.add(\"media\");\n        newMediaElement.id = media.id;\n        newMediaElement.classList.toggle(\"selected\", isSelected);\n\n        const newMediaImg = document.createElement(\"img\");\n        newMediaImg.classList.add(\"media-img\");\n        newMediaImg.src = media.thumbnail;\n        newMediaImg.alt = media.caption;\n\n        newMediaElement.addEventListener(\"click\", () => {\n          this.toggleSelected(media);\n        });\n        newMediaElement.appendChild(newMediaImg);\n\n        this.mediaGrid.insertBefore(newMediaElement, this.loadingMoreContainer);\n      }\n    });\n\n    const existingSelectedIds = this.selectedMedia.map((m) => `${m.id}-selected`);\n    this.selectedMediaGrid.querySelectorAll(\".selected-media\").forEach((node) => {\n      if (!existingSelectedIds.includes(node.id)) {\n        node.remove();\n      }\n    });\n\n    this.selectedMedia.forEach((selectedMedia) => {\n      const selectedId = `${selectedMedia.id}-selected`;\n\n      const existingSelectedMediaElement = document.getElementById(selectedId);\n      if (!existingSelectedMediaElement) {\n        const newSelected = document.createElement(\"img\");\n        newSelected.src = selectedMedia.thumbnail;\n        newSelected.classList.add(\"selected-media\");\n        newSelected.id = selectedId;\n        newSelected.addEventListener(\"click\", () => {\n          this.toggleSelected(selectedMedia);\n        });\n        this.selectedMediaGrid.appendChild(newSelected);\n      }\n    });\n\n    const shouldChooseAlbum = this.albums.length && !this.selectedAlbum;\n    this.albumList.classList.toggle(\"d-none\", !shouldChooseAlbum);\n    this.mediaGrid.classList.toggle(\"d-none\", shouldChooseAlbum);\n\n    this.root\n      .querySelector(\".selected-media-container\")\n      .classList.toggle(\"d-none\", !this.selectedMedia.length);\n    this.root.querySelector(\".selected-media-header .count\").innerText =\n      `${this.selectedMedia.length} Photo${this.selectedMedia.length === 1 ? \"\" : \"s\"}`;\n    this.mediaGrid.classList.toggle(\n      \"maximum-selected\",\n      this.selectedMedia.length >= this.maximum,\n    );\n\n    this.loadMoreMedia.classList.toggle(\"d-none\", !this.activeImporter.nextCursor);\n    this.loadMoreAlbums.classList.toggle(\n      \"d-none\",\n      !this.activeImporter.nextAlbumCursor,\n    );\n\n    this.loading(false);\n  }\n\n  selectAlbum(album) {\n    this.selectedAlbum = album;\n    this.resetMedia();\n\n    if (this.selectedAlbum && this.selectedAlbum.children) {\n      this.mediaGrid.querySelector(\".album-title\").classList.toggle(\"d-none\", !album);\n      this.mediaGrid.querySelector(\".title-value\").innerText =\n        `${this.selectedAlbum.children.length} photos`;\n      this.media = album.children;\n    } else {\n      this.mediaGrid.querySelector(\".album-title\").classList.toggle(\"d-none\", !album);\n      this.mediaGrid.querySelector(\".title-value\").innerText = album ? album.name : \"\";\n\n      if (this.activeImporter.selectAlbum) {\n        this.activeImporter.selectAlbum(this.selectedAlbum);\n      } else if (!this.albums.length) {\n        this.activeImporter.loadMedia();\n      }\n\n      if (this.selectedAlbum) {\n        this.activeImporter.loadMedia();\n      }\n    }\n\n    this.render();\n  }\n\n  toggleSelected(media) {\n    if (this.selectedMedia.includes(media)) {\n      this.selectedMedia = this.selectedMedia.filter((m) => m.id !== media.id);\n    } else if (this.selectedMedia.length < this.maximum) {\n      this.selectedMedia.push(media);\n    }\n\n    this.render();\n  }\n\n  loading(show = true) {\n    if (!show) {\n      this.loadingMoreContainer.classList.add(\"d-none\");\n      this.loadingMoreAlbumsContainer.classList.add(\"d-none\");\n      this.loadingContainer.classList.add(\"d-none\");\n    } else if ((this.media && this.media.length) || this.selectedAlbum) {\n      this.loadingMoreContainer.classList.remove(\"d-none\");\n    } else if (this.albums && this.albums.length && !this.selectedAlbum) {\n      this.loadingMoreAlbumsContainer.classList.remove(\"d-none\");\n    } else {\n      this.loadingContainer.classList.remove(\"d-none\");\n    }\n  }\n\n  error(message, allowRetry = true) {\n    this.loading(false);\n\n    if (message) {\n      this.errorContainer.querySelector(\".message\").innerText = message;\n      this.errorContainer\n        .querySelector(\".retry\")\n        .classList.toggle(\"d-none\", !allowRetry);\n    }\n\n    this.errorContainer.classList.toggle(\"d-none\", !message);\n  }\n}\n","import Modal from \"bootstrap/js/dist/modal\";\n\nimport { sendBrowserAgnosticEvent } from \"../core/utils\";\n\nconst EMPTY_VALUES = [undefined, null, \"\", \" \", \"<p></p>\", \"<p><br></p>\"];\n\nexport default function initUGCTemplates(\n  container,\n  input,\n  templatesData,\n  shouldShowTemplatesOnInit = null,\n  skipWarningModal = false,\n  onTemplateSelected = null,\n  inputIsHTMLEditor = true,\n  alwaysShowTemplates = false,\n) {\n  // UGC template selection\n  if (container && input) {\n    const form = input.closest(\"form\");\n\n    // Add \"has-warning-modal\" class to the main submit button of any form that is using\n    // initUGCTemplates! This button is clicked in JS to submit form if a user decides\n    // to ignore the warning that they are submitting an unedited template.\n    const submitBtnWithWarning = form.querySelector(\".has-warning-modal\");\n    const templateSelector = container.querySelector(\"select\");\n    const templateDefaultOption = container.querySelector('option[value=\"\"]');\n\n    // optional warning modal elements\n    const editModalButton = document.querySelector(\".unedited-template-modal-close\");\n    const saveModalButton = document.querySelector(\".unedited-template-modal-save\");\n    const warningModal = document.querySelector(\".modal-unedited-template\");\n    let showWarningModalOnSubmit = false;\n\n    if (\n      (EMPTY_VALUES.includes(input.value) &&\n        (!shouldShowTemplatesOnInit || shouldShowTemplatesOnInit())) ||\n      alwaysShowTemplates\n    ) {\n      // Show template selector on init if we should.\n      container.classList.remove(\"d-none\");\n    }\n\n    input.addEventListener(\"input\", () => {\n      if (parseInt(input.dataset.selectedTemplate, 10) === 1) {\n        // Template selected & we fired an \"input\" event so passwordless signup form can show.\n        // We reset selectedTemplate so can process the next \"input\" event.\n        input.dataset.selectedTemplate = 0;\n      } else if (EMPTY_VALUES.includes(input.value)) {\n        // input is empty - show template selector.\n        showWarningModalOnSubmit = false;\n        container.classList.remove(\"d-none\");\n        templateDefaultOption.selected = true;\n      } else {\n        // Wrap template in <p> (if HTML mode) and remove all whitespace to compare.\n        const templateBody = templatesData[templateSelector.value] || \"\";\n\n        let templateIsEdited;\n        if (inputIsHTMLEditor) {\n          const templateBodyInP = `<p>${templateBody.replace(\"\\n\", \"</p><p>\")}</p>`;\n          templateIsEdited = !(\n            input.value.replace(/\\s/g, \"\") === templateBodyInP.replace(/\\s/g, \"\")\n          );\n        } else {\n          templateIsEdited = !(\n            input.value.replace(/\\s/g, \"\") === templateBody.replace(/\\s/g, \"\")\n          );\n        }\n\n        if (templateIsEdited) {\n          // input is not empty & has been edited from original template - hide template selector.\n          if (!alwaysShowTemplates) {\n            container.classList.add(\"d-none\");\n          }\n          showWarningModalOnSubmit = false;\n        }\n      }\n    });\n\n    let previousSelection = templateSelector.value;\n\n    templateSelector.addEventListener(\"change\", () => {\n      const prevValue = input.value;\n\n      if (templateSelector.value) {\n        // changed template selector to a value, insert template into input.\n        const templateBody = templatesData[templateSelector.value];\n        if (inputIsHTMLEditor) {\n          input.value = `<p>${templateBody.replace(\"\\n\", \"</p><p>\")}</p>`;\n        } else {\n          input.value = templateBody;\n        }\n\n        input.dataset.selectedTemplate = 1;\n        showWarningModalOnSubmit = true;\n      } else {\n        // changed template selector to no value, clear input.\n        input.value = \"\";\n        input.dataset.selectedTemplate = 0;\n        showWarningModalOnSubmit = false;\n      }\n\n      // Capture previous to a diff var so we don't have a race.\n      const previous = previousSelection;\n      if (onTemplateSelected) {\n        onTemplateSelected(input.value, () => {\n          input.value = prevValue;\n          templateSelector.value = previous;\n          sendBrowserAgnosticEvent(input, \"input\");\n        });\n      }\n\n      sendBrowserAgnosticEvent(input, \"input\");\n      previousSelection = templateSelector.value;\n    });\n\n    if (saveModalButton) {\n      saveModalButton.addEventListener(\"click\", () => {\n        Modal.getOrCreateInstance(warningModal).hide();\n        saveModalButton.classList.add(\"disabled\");\n\n        // clicking submitBtn in JS to allow reCAPTCHA.js to run checks\n        sendBrowserAgnosticEvent(form, \"cancel-submit-protect\");\n        submitBtnWithWarning.dataset.acknowledgedWarning = true;\n        submitBtnWithWarning.click();\n      });\n    }\n\n    if (warningModal && editModalButton) {\n      editModalButton.addEventListener(\"click\", () => {\n        Modal.getOrCreateInstance(warningModal).hide();\n        sendBrowserAgnosticEvent(form, \"cancel-submit-protect\");\n      });\n    }\n    form.addEventListener(\"submit\", (event) => {\n      if (submitBtnWithWarning) {\n        const hasSeenWarning = submitBtnWithWarning.dataset.acknowledgedWarning;\n        if (\n          !skipWarningModal &&\n          warningModal &&\n          showWarningModalOnSubmit &&\n          !hasSeenWarning\n        ) {\n          event.preventDefault();\n          event.stopImmediatePropagation();\n          Modal.getOrCreateInstance(warningModal).show();\n        }\n      }\n    });\n  }\n}\n","import Modal from \"bootstrap/js/dist/modal\";\nimport debounce from \"lodash.debounce\";\nimport Tribute from \"tributejs\";\n\nimport requests from \"../core/requests\";\nimport { animateCSS, fadeOut } from \"../core/utils\";\n\nconst MENU_ITEM_LIMIT = 8;\n\nexport function runInviteFormValidation(inviteForm) {\n  const submitBtn = inviteForm.querySelector(\".notify-user-mention-button\");\n\n  function isValid(el) {\n    return el.checkValidity();\n  }\n\n  const firstNameField = inviteForm.querySelector(\"#user-mention-invite-first-name\");\n  const lastNameField = inviteForm.querySelector(\"#user-mention-invite-last-name\");\n  const emailField = inviteForm.querySelector(\"#user-mention-invite-email\");\n\n  if ([firstNameField, lastNameField, emailField].every(isValid)) {\n    submitBtn.classList.remove(\"disabled\");\n  } else {\n    submitBtn.classList.add(\"disabled\");\n  }\n}\n\nexport class UserMentionWriteHandler {\n  constructor(mentionableElement, memorialSlug, searchEndpoint) {\n    this.form = mentionableElement.closest(\"form\");\n    this.mentionsInput = this.form.querySelector(\".user-mentions-input\");\n    this.inviteForm = document.querySelector(\"#user-mention-invite-form\");\n    this.memorialSlug = memorialSlug;\n    this.mentionModalElement = document.querySelector(\"#modal-user-mention\");\n    this.mentionModal = new Modal(this.mentionModalElement);\n    this.mentionableElement = mentionableElement;\n    this.processableMentions = new Set();\n    this.searchEndpoint = searchEndpoint;\n    this.currentUserSearch = \"\";\n    this.inviteSuccessModal = document.querySelector(\".mention-invite-success-modal\");\n\n    this.boundSetHiddenUserData = this.setUserQueryValue.bind(null, this);\n    this.boundValidateForm = this.validateInviteForm.bind(this);\n    this.boundAcceptUserData =\n      this.addSubmittedUserDataToProcessableMentions.bind(this);\n  }\n\n  async showSuccessModal() {\n    // TODO: Check this once we fix a bug preventing users from being invited\n    this.inviteSuccessModal.classList.remove(\"d-none\");\n    await animateCSS(this.inviteSuccessModal, \"fadeIn\");\n    fadeOut(this.inviteSuccessModal, 5000);\n  }\n\n  listenForUserMentionTrigger() {\n    const tribute = new Tribute({\n      allowSpaces: false,\n      searchOpts: {\n        skip: true,\n      },\n      // class added in the flyout menu for active item\n      selectClass: \"user-mention-highlight\",\n\n      // class added to the menu container\n      containerClass: \"tribute-container\",\n\n      // class added to each list item\n      itemClass: \"user-mention-option\",\n\n      // function called on select that returns the content to insert\n      selectTemplate: (item) => {\n        if (typeof item === \"undefined\") return null;\n\n        if (item.original.userHash === \"no-match-item\") {\n          this.mentionModal.show();\n          this.setupListenersOnUserMentionInviteForm(item.original.userMentionName);\n        } else if (item.original.userHash === \"rate-limit-item\") {\n          // pass\n        } else if (item.original.userHash === \"match-error-item\") {\n          // pass\n        } else {\n          this.processableMentions.add(item.original);\n        }\n\n        return `@${item.original.userMentionName}`;\n      },\n\n      // template for displaying item in menu\n      menuItemTemplate: (item) => {\n        if (item.original.userHash === \"no-match-item\") {\n          return `<a data-user-query=\"${item.original.userMentionName}\" class=\"user-mention-invite-user\" target=\"_blank\">No match found - Click to notify person</a>`;\n        }\n\n        if (item.original.thumbnailUrl) {\n          return `<span><img class=\"user-profile-photo\" src=\"${item.original.thumbnailUrl}\" alt=\"User profile photo\"></img> ${item.original.userMentionName}</span>`;\n        }\n\n        return item.string;\n      },\n\n      // template for when no match is found (optional),\n      // If no template is provided, menu is hidden.\n      noMatchTemplate: null,\n\n      // column to search against in the object (accepts function or string)\n      lookup: \"userMentionName\",\n\n      // column that contains the content to insert by default\n      fillAttr: \"userHash\",\n\n      // TODO: Figure out how to handle pagination with Tribute.js\n      // REQUIRED: array of objects to match or a function that returns data\n      values: debounce(\n        async (text, cb) => {\n          const noMatchItem = { userMentionName: text, userHash: \"no-match-item\" };\n          const rateLimitItem = {\n            userMentionName:\n              \"An error occurred. Please wait a few minutes and try again.\",\n            userHash: \"rate-limited-item\",\n          };\n          const searchErrorItem = {\n            userMentionName: \"An error occurred. Please try again.\",\n            userHash: \"search-error-item\",\n          };\n          try {\n            const response = await requests.get(this.searchEndpoint, {\n              search: text,\n              \"memorial-slug\": this.memorialSlug,\n            });\n\n            if (!response.ok) {\n              if (response.status === 429) {\n                return cb([rateLimitItem]);\n              }\n\n              throw new Error();\n            }\n\n            const responseData = await response.json();\n            const dropdownData = [...responseData.results];\n            dropdownData.splice(MENU_ITEM_LIMIT - 1, 0, noMatchItem);\n\n            return cb(dropdownData);\n          } catch {\n            return cb([searchErrorItem]);\n          }\n        },\n        100,\n        { maxWait: 250 },\n      ),\n\n      // specify whether a space is required before the trigger string\n      requireLeadingSpace: true,\n\n      // Limits the number of items in the menu\n      menuItemLimit: MENU_ITEM_LIMIT,\n\n      // specify the minimum number of characters that must be typed before menu appears\n      menuShowMinLength: 3,\n    });\n\n    tribute.attach(this.mentionableElement);\n  }\n\n  setUserQueryValue(klass, event) {\n    if (event.target.classList.contains(\"modal-open\")) {\n      const userQueryHiddenInput =\n        klass.inviteForm.querySelector(\".user-mention-query\");\n      userQueryHiddenInput.value = `@${klass.currentUserSearch}`;\n    }\n  }\n\n  validateInviteForm() {\n    runInviteFormValidation(this.inviteForm);\n  }\n\n  addSubmittedUserDataToProcessableMentions() {\n    const userQueryHiddenInput = this.inviteForm.querySelector(\".user-mention-query\");\n\n    const firstNameInput = this.inviteForm.querySelector(\n      \"#user-mention-invite-first-name\",\n    );\n    const lastNameInput = this.inviteForm.querySelector(\n      \"#user-mention-invite-last-name\",\n    );\n    const emailInput = this.inviteForm.querySelector(\"#user-mention-invite-email\");\n\n    const email = emailInput.value;\n    const fullName = `${firstNameInput.value} ${lastNameInput.value}`;\n\n    this.processableMentions.add({ userMentionName: fullName, email, disabled: true });\n    if (\"mediumEditorElement\" in this.mentionableElement.dataset) {\n      window.eljs.editor.replaceContent(\n        this.mentionableElement,\n        userQueryHiddenInput.value,\n        `@${fullName}`,\n      );\n    } else {\n      this.mentionableElement.value = this.mentionableElement.value.replace(\n        userQueryHiddenInput.value,\n        `@${fullName}`,\n      );\n    }\n\n    this.mentionModal.hide();\n    firstNameInput.value = \"\";\n    lastNameInput.value = \"\";\n    emailInput.value = \"\";\n\n    this.showSuccessModal();\n  }\n\n  setupListenersOnUserMentionInviteForm(userQuery) {\n    this.currentUserSearch = userQuery;\n\n    document\n      .querySelector(\"body\")\n      .addEventListener(\"click\", this.boundSetHiddenUserData);\n    this.inviteForm.addEventListener(\"input\", this.boundValidateForm);\n    this.inviteForm\n      .querySelector(\".notify-user-mention-button\")\n      .addEventListener(\"click\", this.boundAcceptUserData);\n  }\n\n  addMentionsToFormOnSubmit() {\n    if (this.mentionsInput) {\n      this.form.addEventListener(\"submit\", () => {\n        if (!this.mentionableElement.offsetParent) {\n          // This listener is not the one that should be listening;\n          return;\n        }\n\n        const mentions = [...this.processableMentions];\n        this.mentionsInput.setAttribute(\"value\", JSON.stringify(mentions));\n      });\n    }\n  }\n\n  clearListenersOnUserMentionInviteModalClose() {\n    this.mentionModalElement.addEventListener(\"hide.bs.modal\", () => {\n      document\n        .querySelector(\"body\")\n        .removeEventListener(\"click\", this.boundSetHiddenUserData);\n      this.inviteForm.removeEventListener(\"input\", this.boundValidateForm);\n      this.inviteForm\n        .querySelector(\".notify-user-mention-button\")\n        .removeEventListener(\"click\", this.boundAcceptUserData);\n    });\n  }\n\n  setUp() {\n    this.listenForUserMentionTrigger();\n    this.addMentionsToFormOnSubmit();\n    this.clearListenersOnUserMentionInviteModalClose();\n  }\n}\n\nexport function initUserMentionsForElement(element, memorialSlug, searchEndpoint) {\n  const handler = new UserMentionWriteHandler(element, memorialSlug, searchEndpoint);\n  handler.setUp();\n}\n\nexport function initUserMentions(props) {\n  const {\n    memorialIsExample,\n    userMention: { memorialSlug, userMentionClass, userSearchEndpoint },\n  } = props;\n\n  // set up write user mentions\n  if (!memorialIsExample) {\n    const mentionableElements = document.querySelectorAll(`.${userMentionClass}`);\n\n    mentionableElements.forEach((element) => {\n      initUserMentionsForElement(element, memorialSlug, userSearchEndpoint);\n    });\n  }\n}\n","import Modal from \"bootstrap/js/dist/modal\";\n\nimport requests from \"../core/requests\";\nimport {\n  handleAjaxFormSubmitProtection,\n  readValidFileFromInput,\n  sendBrowserAgnosticEvent,\n} from \"../core/utils\";\n\nexport default class BelongingEditor {\n  constructor(modalContainer, props) {\n    this.modalContainer = modalContainer;\n    this.createUrl = props.createUrl;\n    this.editUrl = props.editUrl;\n    this.modal = new Modal(this.modalContainer);\n\n    this.titleNameSpan = this.modalContainer.querySelector(\".belonging-editor--name\");\n    this.titleClaimedBadge = this.modalContainer.querySelector(\n      \".belonging-editor--claimed\",\n    );\n    this.titleAvailableBadge = this.modalContainer.querySelector(\n      \".belonging-editor--available\",\n    );\n\n    this.productPhoto = this.modalContainer.querySelector(\".product-photo\");\n    this.productPhotoPlaceholder = this.productPhoto.src;\n\n    const fieldIds = props.belongingFormFieldIds;\n    this.photoInput = document.getElementById(fieldIds.photo);\n    this.nameInput = document.getElementById(fieldIds.name);\n    this.descriptionTextarea = document.getElementById(fieldIds.description);\n    this.isPublishedCheckbox = document.getElementById(fieldIds.isPublished);\n    this.isClaimedCheckbox = document.getElementById(fieldIds.isClaimed);\n\n    this.productPhoto.addEventListener(\"click\", () => {\n      this.photoInput.click();\n    });\n\n    this.nameInput.addEventListener(\"input\", () => {\n      this.renderDependents();\n    });\n\n    this.isClaimedCheckbox.addEventListener(\"change\", () => {\n      this.renderDependents();\n    });\n\n    this.photoInput.addEventListener(\"change\", () => {\n      const file = readValidFileFromInput(this.photoInput);\n      if (file) {\n        const reader = new FileReader();\n        reader.onload = (readerEvent) => {\n          this.productPhoto.src = readerEvent.target.result;\n          this.productPhoto.parentNode.style.backgroundImage = `url('${readerEvent.target.result}');`;\n        };\n\n        reader.readAsDataURL(file);\n      }\n    });\n\n    this.activeBelonging = null;\n\n    this.onBelongingChanged = props.onBelongingChanged;\n\n    this.form = this.modalContainer.querySelector(\"form\");\n    this.form.addEventListener(\"submit\", (e) => {\n      e.preventDefault();\n      e.stopPropagation();\n    });\n\n    this.saveButton = this.modalContainer.querySelector(\".save-belonging-details\");\n    this.saveButton.addEventListener(\"click\", () => {\n      this.save();\n    });\n  }\n\n  renderDependents() {\n    this.titleClaimedBadge.classList.toggle(\"d-none\", !this.isClaimedCheckbox.checked);\n    this.titleAvailableBadge.classList.toggle(\"d-none\", this.isClaimedCheckbox.checked);\n    this.titleNameSpan.innerText = this.nameInput.value;\n    this.productPhoto.setAttribute(\"alt\", this.nameInput.value);\n  }\n\n  reset() {\n    this.photoInput.value = null;\n    this.nameInput.value = \"\";\n    this.descriptionTextarea.value = \"\";\n    this.isPublishedCheckbox.checked = false;\n    this.isClaimedCheckbox.checked = false;\n\n    this.titleNameSpan.innerText = \"\";\n    this.productPhoto.setAttribute(\"alt\", \"\");\n    this.modalContainer.querySelector(\".alert-danger\").classList.add(\"d-none\");\n\n    this.renderDependents();\n  }\n\n  dismiss() {\n    this.reset();\n    this.modal.hide();\n  }\n\n  showForBelonging(belonging) {\n    this.activeBelonging = belonging;\n\n    let invokeFilePicker = false;\n\n    if (this.activeBelonging) {\n      this.nameInput.value = this.activeBelonging.name;\n      this.descriptionTextarea.value = this.activeBelonging.description;\n      this.isPublishedCheckbox.checked = this.activeBelonging.isPublished;\n      this.isClaimedCheckbox.checked = this.activeBelonging.isClaimed;\n      this.productPhoto.src = this.activeBelonging.photo;\n      this.productPhoto.parentNode.style.backgroundImage = `url('${this.activeBelonging.photo}');`;\n    } else {\n      this.nameInput.value = \"\";\n      this.descriptionTextarea.value = \"\";\n      this.isPublishedCheckbox.checked = true;\n      this.isClaimedCheckbox.checked = false;\n      this.productPhoto.src = this.productPhotoPlaceholder;\n      this.productPhoto.parentNode.style.backgroundImage = \"none\";\n\n      invokeFilePicker = true;\n    }\n\n    sendBrowserAgnosticEvent(this.nameInput, \"input\");\n    this.renderDependents();\n\n    this.modal.show();\n\n    if (invokeFilePicker) {\n      this.photoInput.click();\n    }\n  }\n\n  getUrl() {\n    if (this.activeBelonging && this.activeBelonging.id) {\n      return this.editUrl.replace(\"__id__\", this.activeBelonging.id);\n    }\n\n    return this.createUrl;\n  }\n\n  async save() {\n    this.saveButton.dataset.clicked = true;\n    const cancelSubmitProtect = handleAjaxFormSubmitProtection(this.saveButton);\n    this.modalContainer.querySelector(\".alert-danger\").classList.add(\"d-none\");\n    this.modalContainer.querySelectorAll(\".errorlist\").forEach((errList) => {\n      while (errList.hasChildNodes()) {\n        errList.removeChild(errList.lastChild);\n      }\n      errList.classList.add(\"d-none\");\n    });\n\n    const showGenericError = () => {\n      const mainErrorAlert = this.modalContainer.querySelector(\".alert-danger\");\n      mainErrorAlert.classList.remove(\"d-none\");\n      mainErrorAlert.querySelector(\".error-message\").innerText =\n        \"An unknown error occurred.\";\n    };\n\n    const handleFail = (data) => {\n      window.Rollbar.error(\n        \"Error modifying Belonging\",\n        data.responseJSON ? data.responseJSON.errors : data,\n      );\n      cancelSubmitProtect();\n\n      if (data.errors) {\n        const mainErrorAlert = this.modalContainer.querySelector(\".alert-danger\");\n        mainErrorAlert.classList.remove(\"d-none\");\n        mainErrorAlert.querySelector(\".error-message\").innerText =\n          data.errors.main || \"An unknown error occurred.\";\n        Object.keys(data.errors).forEach((errKey) => {\n          if (errKey === \"main\") {\n            return;\n          }\n\n          const errorList = this.modalContainer.querySelector(`.${errKey}-errorlist`);\n          if (errorList) {\n            errorList.classList.remove(\"d-none\");\n            data.errors[errKey].forEach((err) => {\n              const errItem = document.createElement(\"li\");\n              errItem.innerText = err;\n              errorList.appendChild(errItem);\n            });\n          }\n        });\n      } else {\n        showGenericError();\n      }\n    };\n\n    let responseData;\n\n    try {\n      const response = await requests.post(this.getUrl(), this.form);\n\n      if (!response.ok) {\n        showGenericError();\n        return;\n      }\n\n      responseData = await response.json();\n    } catch (error) {\n      showGenericError();\n      throw error;\n    }\n\n    if (responseData.success) {\n      cancelSubmitProtect();\n      this.onBelongingChanged(responseData.data, this);\n      this.dismiss();\n    } else {\n      handleFail(responseData);\n    }\n  }\n}\n","import debounce from \"lodash.debounce\";\nimport { sendBrowserAgnosticEvent, storageAvailable } from \"../core/utils\";\n\nexport default class AutoSaveTextField {\n  constructor(textField) {\n    this.textField = textField;\n    this.storageKey = this.textField.dataset.autosaveKey;\n    this.remoteLastUpdated =\n      parseFloat(this.textField.dataset.autosaveLastUpdated) || 0.0;\n    this.storageAvailable = storageAvailable(\"localStorage\");\n\n    this.textField.addEventListener(\n      \"input\",\n      debounce(\n        () => {\n          this.store();\n        },\n        100,\n        { maxWait: 250 },\n      ),\n    );\n\n    this.initialValue = this.textField.value;\n\n    this.load();\n\n    if (this.textField.value) {\n      // Send a slightly deferred `input` event over the DOM in particular for the\n      // obit template selector management code.\n      setTimeout(() => {\n        sendBrowserAgnosticEvent(this.textField, \"input\");\n      }, 300);\n    }\n\n    this.indicator = document.querySelector(\n      `[data-autosave-indicator-for=\"${this.textField.id}\"]`,\n    );\n    if (this.indicator) {\n      const revertLink = this.indicator.querySelector(\".revert-autosave\");\n      if (revertLink) {\n        revertLink.addEventListener(\"click\", () => {\n          this.clear();\n        });\n      }\n    }\n  }\n\n  load(force = false) {\n    if (this.storageAvailable) {\n      const data = JSON.parse(window.localStorage.getItem(this.storageKey));\n      if (data && data.timestamp && data.text) {\n        const ts = parseFloat(data.timestamp);\n        if (ts > this.remoteLastUpdated || force) {\n          this.textField.value = data.text;\n          sendBrowserAgnosticEvent(this.textField, \"input\");\n          sendBrowserAgnosticEvent(this.textField, \"el-editor-external-input\");\n        }\n      }\n    }\n  }\n\n  store() {\n    if (this.storageAvailable) {\n      if (this.textField.value) {\n        const data = {\n          text: this.textField.value,\n          timestamp: Date.now() / 1000.0,\n        };\n\n        window.localStorage.setItem(this.storageKey, JSON.stringify(data));\n      } else {\n        window.localStorage.removeItem(this.storageKey);\n      }\n    }\n\n    this.updateIndicator();\n  }\n\n  clear() {\n    if (this.storageAvailable) {\n      window.localStorage.removeItem(this.storageKey);\n    }\n\n    this.textField.value = this.initialValue;\n    sendBrowserAgnosticEvent(this.textField, \"input\");\n    sendBrowserAgnosticEvent(this.textField, \"el-editor-external-input\");\n\n    this.updateIndicator();\n  }\n\n  updateIndicator() {\n    if (this.indicator) {\n      // Handle empty rich editor value of <p></p> or <p><br></p>\n      const hasNotChanged =\n        this.textField.value === this.initialValue ||\n        (this.initialValue === \"\" &&\n          (this.textField.value === \"<p></p>\" ||\n            this.textField.value === \"<p><br></p>\"));\n\n      this.indicator.classList.toggle(\"d-none\", hasNotChanged);\n    }\n  }\n}\n","import Collapse from \"bootstrap/js/dist/collapse\";\n\nimport initBusinessAutocomplete from \"./BusinessAutocomplete\";\nimport { handleAjaxFormSubmitProtection, isHidden } from \"../core/utils\";\nimport requests, { ResponseError } from \"../core/requests\";\n\n/**\n * Update a BusinessAutocomplete component with new settings.\n *\n * We're defaulting addSubmitListener to false so we can manually add the submit\n * listener for each autocomplete during initialization to prevent a new listener from\n * being added each time this function is called.\n *\n * @param {object} props - the autocomplete page props\n * @param {boolean} includeInitialValue - whether or not to include the initial value\n * @param {string} businessPlaceholder - the placeholder value for the given business type\n * @param {boolean} [addSubmitListener] - whether or not to add a submit listener\n */\nfunction updateBusinessAutocomplete(\n  props,\n  includeInitialValue,\n  businessPlaceholder,\n  addSubmitListener = false,\n) {\n  if (props && props.businessIdentifierInputId) {\n    let initialAutocompleteData = {};\n    let initialPendingData = false;\n    if (includeInitialValue) {\n      initialAutocompleteData = props.initialAutocompleteData;\n      initialPendingData = props.initialPendingData;\n    }\n\n    const mergedProps = {\n      ...props,\n      businessPlaceholder,\n      initialPendingData,\n      initialAutocompleteData,\n      addSubmitListener,\n    };\n\n    const businessIdentifierInput = document.getElementById(\n      props.businessIdentifierInputId,\n    );\n    if (businessIdentifierInput && businessIdentifierInput.tomselect) {\n      businessIdentifierInput.tomselect.destroy();\n    }\n\n    initBusinessAutocomplete(mergedProps);\n  }\n}\n\n/**\n * Given an array/nodelist of review-input-wrapping container elements, clear all the\n * inputs within.\n *\n * @param {NodeList | Array<Element>} reviewInputWrappers - the containers wrapping\n *     the review inputs.\n */\nfunction clearReviewInputs(reviewInputWrappers) {\n  reviewInputWrappers.forEach((reviewInputWrapper) => {\n    const stars = reviewInputWrapper.querySelectorAll('input[type=\"radio\"]');\n\n    stars.forEach((item) => {\n      item.checked = false;\n    });\n\n    const reviewTextarea = reviewInputWrapper.querySelector(\"textarea\");\n    if (reviewTextarea) {\n      reviewTextarea.value = \"\";\n    }\n    reviewInputWrapper.parentNode.parentNode\n      .querySelectorAll(\":scope .errorlist\")\n      .forEach((errorlist) => errorlist.classList.add(\"d-none\"));\n  });\n}\n\n/**\n * Initialize the business reviews section.\n *\n * @param {object} props - the page props.\n */\nfunction initBusinessReviewSection(props) {\n  const reviewSection = document.querySelector(\".business-association-review-section\");\n  const reviewSectionHeader = document.querySelector(\".review-form-header\");\n  const funeralHomeReviewSection = document.querySelector(\n    \".funeral-home-review-section\",\n  );\n  const funeralHomeSlugInput = document.querySelector(\n    `#${props.funeralHomeSearch.businessIdentifierInputId}`,\n  );\n  const funeralHomePendingCheckbox = document.querySelector(\n    `#${props.funeralHomeSearch.businessPending}`,\n  );\n  const funeralHomeReviewSubmitBtn = funeralHomeReviewSection.querySelector(\"button\");\n  const cemeteryReviewSection = document.querySelector(\".cemetery-review-section\");\n  const cemeterySlugInput = document.querySelector(\n    `#${props.cemeterySearch.businessIdentifierInputId}`,\n  );\n  const cemeteryPendingCheckbox = document.querySelector(\n    `#${props.cemeterySearch.businessPending}`,\n  );\n  const cemeteryReviewSubmitBtn = cemeteryReviewSection.querySelector(\"button\");\n  const hospiceReviewSection = document.querySelector(\".hospice-review-section\");\n  const hospiceSlugInput = document.querySelector(\n    `#${props.hospiceSearch.businessIdentifierInputId}`,\n  );\n  const hospicePendingCheckbox = document.querySelector(\n    `#${props.hospiceSearch.businessPending}`,\n  );\n  const hospiceReviewSubmitBtn = hospiceReviewSection.querySelector(\"button\");\n  const donationOrgReviewSection = document.querySelector(\n    \".donation-org-review-section\",\n  );\n  const donationOrgSlugInput = document.querySelector(\n    `#${props.donationOrgSearch.businessIdentifierInputId}`,\n  );\n  const donationOrgPendingCheckbox = document.querySelector(\n    `#${props.donationOrgSearch.businessPending}`,\n  );\n  const donationOrgReviewSubmitBtn = donationOrgReviewSection.querySelector(\"button\");\n  const deathDoulaReviewSection = document.querySelector(\".death-doula-review-section\");\n  const deathDoulaSlugInput = document.querySelector(\n    `#${props.deathDoulaSearch.businessIdentifierInputId}`,\n  );\n  const deathDoulaPendingCheckbox = document.querySelector(\n    `#${props.deathDoulaSearch.businessPending}`,\n  );\n  const deathDoulaReviewSubmitBtn = deathDoulaReviewSection.querySelector(\"button\");\n\n  /**\n   * Show the business review form.\n   */\n  const showBusinessReviewForm = () => {\n    const selectedFuneralHome =\n      funeralHomeSlugInput.tomselect.options[funeralHomeSlugInput.tomselect.getValue()];\n    const selectedCemetery =\n      cemeterySlugInput.tomselect.options[cemeterySlugInput.tomselect.getValue()];\n    const selectedHospice =\n      hospiceSlugInput.tomselect.options[hospiceSlugInput.tomselect.getValue()];\n    const selectedDonationOrg =\n      donationOrgSlugInput.tomselect.options[donationOrgSlugInput.tomselect.getValue()];\n    const selectedDeathDoula =\n      deathDoulaSlugInput.tomselect.options[deathDoulaSlugInput.tomselect.getValue()];\n    const funeralHomesReviewed = props.businessesUserHasReviewed.funeralHomes;\n    const cemeteriesReviewed = props.businessesUserHasReviewed.cemeteries;\n    const hospicesReviewed = props.businessesUserHasReviewed.hospices;\n    const donationOrgsReviewed = props.businessesUserHasReviewed.donationOrgs;\n    const deathDoulasReviewed = props.businessesUserHasReviewed.deathDoulas;\n    let showFuneralHomeReviewForm = false;\n    let showCemeteryReviewForm = false;\n    let showHospiceReviewForm = false;\n    let showDonationOrgReviewForm = false;\n    let showDeathDoulaReviewForm = false;\n\n    if (\n      selectedFuneralHome &&\n      selectedFuneralHome.id &&\n      !selectedFuneralHome.created &&\n      !funeralHomePendingCheckbox.checked\n    ) {\n      const funeralHomeSlug = selectedFuneralHome.id;\n      const funeralHomeName = selectedFuneralHome.text;\n      // check if user has not yet reviewed business before showing review form\n      showFuneralHomeReviewForm = !funeralHomesReviewed.includes(funeralHomeSlug);\n      if (showFuneralHomeReviewForm) {\n        funeralHomeReviewSection.classList.remove(\"d-none\");\n        const nameSpan = funeralHomeReviewSection.querySelector(\"span\");\n        if (nameSpan) {\n          nameSpan.innerText = funeralHomeName;\n        }\n      } else {\n        funeralHomeReviewSection.classList.add(\"d-none\");\n      }\n    } else {\n      funeralHomeReviewSection.classList.add(\"d-none\");\n    }\n\n    if (\n      selectedCemetery &&\n      selectedCemetery.id &&\n      !selectedCemetery.created &&\n      !cemeteryPendingCheckbox.checked\n    ) {\n      const cemeterySlug = selectedCemetery.id;\n      const cemeteryName = selectedCemetery.text;\n      // check if user has not yet reviewed business before showing review form\n      showCemeteryReviewForm = !cemeteriesReviewed.includes(cemeterySlug);\n      if (showCemeteryReviewForm) {\n        cemeteryReviewSection.classList.remove(\"d-none\");\n        const nameSpan = cemeteryReviewSection.querySelector(\"span\");\n        if (nameSpan) {\n          nameSpan.innerText = cemeteryName;\n        }\n      } else {\n        cemeteryReviewSection.classList.add(\"d-none\");\n      }\n    } else {\n      cemeteryReviewSection.classList.add(\"d-none\");\n    }\n\n    if (\n      selectedHospice &&\n      selectedHospice.id &&\n      !selectedHospice.created &&\n      !hospicePendingCheckbox.checked\n    ) {\n      const hospiceSlug = selectedHospice.id;\n      const hospiceName = selectedHospice.text;\n      // check if user has not yet reviewed business before showing review form\n      showHospiceReviewForm = !hospicesReviewed.includes(hospiceSlug);\n      if (showHospiceReviewForm) {\n        hospiceReviewSection.classList.remove(\"d-none\");\n        const nameSpan = hospiceReviewSection.querySelector(\"span\");\n        if (nameSpan) {\n          nameSpan.innerText = hospiceName;\n        }\n      } else {\n        hospiceReviewSection.classList.add(\"d-none\");\n      }\n    } else {\n      hospiceReviewSection.classList.add(\"d-none\");\n    }\n\n    if (\n      selectedDonationOrg &&\n      selectedDonationOrg.id &&\n      !selectedDonationOrg.created &&\n      !donationOrgPendingCheckbox.checked\n    ) {\n      const donationOrgSlug = selectedDonationOrg.id;\n      const donationOrgName = selectedDonationOrg.text;\n      // check if user has not yet reviewed business before showing review form\n      showDonationOrgReviewForm = !donationOrgsReviewed.includes(donationOrgSlug);\n      if (showDonationOrgReviewForm) {\n        donationOrgReviewSection.classList.remove(\"d-none\");\n        const nameSpan = donationOrgReviewSection.querySelector(\"span\");\n        if (nameSpan) {\n          nameSpan.innerText = donationOrgName;\n        }\n      } else {\n        donationOrgReviewSection.classList.add(\"d-none\");\n      }\n    } else {\n      donationOrgReviewSection.classList.add(\"d-none\");\n    }\n\n    if (\n      selectedDeathDoula &&\n      selectedDeathDoula.id &&\n      !selectedDeathDoula.created &&\n      !deathDoulaPendingCheckbox.checked\n    ) {\n      const deathDoulaSlug = selectedDeathDoula.id;\n      const deathDoulaName = selectedDeathDoula.text;\n      // check if user has not yet reviewed business before showing review form\n      showDeathDoulaReviewForm = !deathDoulasReviewed.includes(deathDoulaSlug);\n      if (showDeathDoulaReviewForm) {\n        deathDoulaReviewSection.classList.remove(\"d-none\");\n        const nameSpan = deathDoulaReviewSection.querySelector(\"span\");\n        if (nameSpan) {\n          nameSpan.innerText = deathDoulaName;\n        }\n      } else {\n        deathDoulaReviewSection.classList.add(\"d-none\");\n      }\n    } else {\n      deathDoulaReviewSection.classList.add(\"d-none\");\n    }\n\n    if (\n      showFuneralHomeReviewForm ||\n      showCemeteryReviewForm ||\n      showHospiceReviewForm ||\n      showDonationOrgReviewForm ||\n      showDeathDoulaReviewForm\n    ) {\n      reviewSection.classList.remove(\"d-none\");\n      reviewSectionHeader.classList.remove(\"d-none\");\n    } else {\n      reviewSection.classList.add(\"d-none\");\n    }\n  };\n\n  /**\n   * Show the business review success message.\n   *\n   * @param {string} businessType - the type of business\n   * @param {string} businessName - the name of the business\n   * @param {string} businessSlug - the business slug\n   */\n  const showBusinessReviewSuccessState = (businessType, businessName, businessSlug) => {\n    const successMessage = document.querySelector(\".review-success-message\");\n\n    if (businessType === props.funeralHomeSearch.businessTypeName) {\n      funeralHomeReviewSection.classList.add(\"d-none\");\n      props.businessesUserHasReviewed.funeralHomes.push(businessSlug);\n    } else if (businessType === props.cemeterySearch.businessTypeName) {\n      cemeteryReviewSection.classList.add(\"d-none\");\n      props.businessesUserHasReviewed.cemeteries.push(businessSlug);\n    } else if (businessType === props.hospiceSearch.businessTypeName) {\n      hospiceReviewSection.classList.add(\"d-none\");\n      props.businessesUserHasReviewed.hospices.push(businessSlug);\n    } else if (businessType === props.donationOrgSearch.businessTypeName) {\n      donationOrgReviewSection.classList.add(\"d-none\");\n      props.businessesUserHasReviewed.donationOrgs.push(businessSlug);\n    } else if (businessType === props.deathDoulaSearch.businessTypeName) {\n      deathDoulaReviewSection.classList.add(\"d-none\");\n      props.businessesUserHasReviewed.deathDoulas.push(businessSlug);\n    }\n\n    reviewSectionHeader.classList.add(\"d-none\");\n\n    const business1 = document.querySelector(\".business-1\");\n    const business2 = document.querySelector(\".business-2\");\n    const business2Wrapper = document.querySelector(\".business-2-wrapper\");\n\n    if (isHidden(successMessage)) {\n      successMessage.classList.remove(\"d-none\");\n      business1.innerText = businessName;\n    } else {\n      business2Wrapper.classList.remove(\"d-none\");\n      business2.innerText = businessName;\n    }\n  };\n\n  /**\n   * Initialize the automatically-showing submit button on the review forms.\n   */\n  const initExpandableSubmitButton = () => {\n    const reviewForms = document.querySelectorAll(\".async-review-form\");\n    reviewForms.forEach((reviewForm) => {\n      const collapse = new Collapse(\n        reviewForm.querySelector(\".collapsed-submit-wrapper\"),\n        { toggle: false },\n      );\n      reviewForm.querySelector(\"textarea\").addEventListener(\"focus\", () => {\n        collapse.show();\n      });\n\n      reviewForm.querySelector(\"textarea\").addEventListener(\"focusout\", (event) => {\n        if (!event.currentTarget.value) {\n          collapse.hide();\n        }\n      });\n    });\n  };\n\n  /**\n   * Submit a business review (async).\n   *\n   * @param {HTMLElement} submitBtn - the triggering button.\n   * @param {string} businessType - the business type\n   * @returns {Promise<void>} - An ignorable void promise\n   */\n  const submitBusinessReview = async (submitBtn, businessType) => {\n    const submitButtonRestore = handleAjaxFormSubmitProtection(submitBtn);\n    const url = submitBtn.dataset.submitUrl;\n    const reviewInputWrapper = submitBtn\n      .closest(\".review-form-container\")\n      .querySelector(\".review-input-wrapper\");\n\n    const text = reviewInputWrapper.querySelector(\"textarea\").value;\n    const rating = reviewInputWrapper.querySelector(\n      'input[type=\"radio\"]:checked',\n    ).value;\n    const searchParams = new URLSearchParams(window.location.search);\n    const flow = searchParams.get(\"association-flow\");\n    let slug = \"\";\n    let name = \"\";\n    if (businessType === props.funeralHomeSearch.businessTypeName) {\n      slug = funeralHomeSlugInput.tomselect.getValue();\n      name =\n        funeralHomeSlugInput.tomselect.options[\n          funeralHomeSlugInput.tomselect.getValue()\n        ].text;\n    } else if (businessType === props.cemeterySearch.businessTypeName) {\n      slug = cemeterySlugInput.tomselect.getValue();\n      name =\n        cemeterySlugInput.tomselect.options[cemeterySlugInput.tomselect.getValue()]\n          .text;\n    } else if (businessType === props.hospiceSearch.businessTypeName) {\n      slug = hospiceSlugInput.tomselect.getValue();\n      name =\n        hospiceSlugInput.tomselect.options[hospiceSlugInput.tomselect.getValue()].text;\n    } else if (businessType === props.donationOrgSearch.businessTypeName) {\n      slug = donationOrgSlugInput.tomselect.getValue();\n      name =\n        donationOrgSlugInput.tomselect.options[\n          donationOrgSlugInput.tomselect.getValue()\n        ].text;\n    } else if (businessType === props.deathDoulaSearch.businessTypeName) {\n      slug = deathDoulaSlugInput.tomselect.getValue();\n      name =\n        deathDoulaSlugInput.tomselect.options[deathDoulaSlugInput.tomselect.getValue()]\n          .text;\n    }\n\n    try {\n      const response = await requests.post(url, {\n        \"review-text\": text,\n        \"review-rating\": rating,\n        slug,\n        flow,\n        businessType,\n      });\n\n      if (!response.ok) {\n        throw new ResponseError(response);\n      }\n\n      clearReviewInputs([reviewInputWrapper]);\n      showBusinessReviewSuccessState(businessType, name, slug);\n      submitButtonRestore();\n    } catch (err) {\n      window.Rollbar.error(\"Error while submitting business review\", err);\n      reviewInputWrapper.parentNode.parentNode\n        .querySelector(\".errorlist\")\n        .classList.remove(\"d-none\");\n      submitButtonRestore();\n    }\n  };\n\n  funeralHomeSlugInput.addEventListener(\"change\", showBusinessReviewForm);\n  funeralHomePendingCheckbox.addEventListener(\"change\", showBusinessReviewForm);\n  cemeterySlugInput.addEventListener(\"change\", showBusinessReviewForm);\n  cemeteryPendingCheckbox.addEventListener(\"change\", showBusinessReviewForm);\n  hospiceSlugInput.addEventListener(\"change\", showBusinessReviewForm);\n  hospicePendingCheckbox.addEventListener(\"change\", showBusinessReviewForm);\n  donationOrgSlugInput.addEventListener(\"change\", showBusinessReviewForm);\n  donationOrgPendingCheckbox.addEventListener(\"change\", showBusinessReviewForm);\n  deathDoulaSlugInput.addEventListener(\"change\", showBusinessReviewForm);\n  deathDoulaPendingCheckbox.addEventListener(\"change\", showBusinessReviewForm);\n\n  funeralHomeReviewSubmitBtn.addEventListener(\"click\", () => {\n    submitBusinessReview(\n      funeralHomeReviewSubmitBtn,\n      props.funeralHomeSearch.businessTypeName,\n    );\n  });\n\n  cemeteryReviewSubmitBtn.addEventListener(\"click\", () => {\n    submitBusinessReview(\n      cemeteryReviewSubmitBtn,\n      props.cemeterySearch.businessTypeName,\n    );\n  });\n\n  hospiceReviewSubmitBtn.addEventListener(\"click\", () => {\n    submitBusinessReview(hospiceReviewSubmitBtn, props.hospiceSearch.businessTypeName);\n  });\n\n  donationOrgReviewSubmitBtn.addEventListener(\"click\", () => {\n    submitBusinessReview(\n      donationOrgReviewSubmitBtn,\n      props.donationOrgSearch.businessTypeName,\n    );\n  });\n\n  deathDoulaReviewSubmitBtn.addEventListener(\"click\", () => {\n    submitBusinessReview(\n      deathDoulaReviewSubmitBtn,\n      props.deathDoulaSearch.businessTypeName,\n    );\n  });\n\n  showBusinessReviewForm();\n  initExpandableSubmitButton();\n}\n\n/**\n * Clear all the inputs for business association.\n *\n * @param {object} props - the page props\n */\nfunction clearAllBusinessAssociationInputs(props) {\n  updateBusinessAutocomplete(\n    props.cemeterySearch,\n    false,\n    props.cemeterySearch.businessPlaceholder,\n  );\n  updateBusinessAutocomplete(\n    props.donationOrgSearch,\n    false,\n    props.donationOrgSearch.businessPlaceholder,\n  );\n  updateBusinessAutocomplete(\n    props.seaBurialProviderSearch,\n    false,\n    props.seaBurialProviderSearch.businessPlaceholder,\n  );\n\n  const businessSelectInputs = [\n    document.getElementById(props.cemeterySearch.businessIdentifierInputId),\n    document.getElementById(props.donationOrgSearch.businessIdentifierInputId),\n    document.getElementById(props.seaBurialProviderSearch.businessIdentifierInputId),\n  ];\n\n  businessSelectInputs.forEach((item) => {\n    if (item && item.tomselect) {\n      item.tomselect.clear();\n      item.tomselect.clearOptions();\n      item.tomselect.enable();\n    }\n  });\n\n  const locationInputs = [\n    document.getElementById(\"id_business_association-remains_location_type\"),\n    document.getElementById(\"id_business_association-remains_location\"),\n  ];\n\n  locationInputs.forEach((item) => {\n    item.removeAttribute(\"disabled\");\n    item.classList.remove(\"disabled\");\n  });\n\n  const stringInputs = [\n    document.getElementById(props.funeralHomeSearch.businessStrInputId),\n    document.getElementById(props.cemeterySearch.businessStrInputId),\n    document.getElementById(props.donationOrgSearch.businessStrInputId),\n    document.getElementById(props.seaBurialProviderSearch.businessStrInputId),\n    document.getElementById(\"id_business_association-remains_location\"),\n  ];\n\n  stringInputs.forEach((item) => {\n    if (item && item.tomselect) {\n      item.tomselect.clear();\n    } else {\n      item.value = \"\";\n    }\n  });\n\n  document.getElementById(\"id_business_association-remains_location\").value = \"\";\n\n  const pendingInputs = [\n    document.getElementById(props.funeralHomeSearch.businessPending),\n    document.getElementById(props.cemeterySearch.businessPending),\n    document.getElementById(props.donationOrgSearch.businessPending),\n    document.getElementById(props.seaBurialProviderSearch.businessPending),\n    document.getElementById(\"id_business_association-remains_location_type_pending\"),\n    document.getElementById(\"id_business_association-remains_location_pending\"),\n  ];\n\n  pendingInputs.forEach((item) => {\n    item.checked = false;\n  });\n\n  const locationMetadataInput = document.getElementById(\n    \"id_business_association-remains_location_metadata\",\n  );\n  locationMetadataInput.value = \"{}\";\n  document.querySelector(\".location-input-group .dark-gray-label\").innerText =\n    \"Location\";\n  document\n    .getElementById(\"id_business_association-remains_location\")\n    .setAttribute(\"placeholder\", \"Ex: 123 Green street, San Francisco, CA\");\n\n  const locationTypeSelect = document.getElementById(\n    \"id_business_association-remains_location_type\",\n  );\n  locationTypeSelect.value = \"\";\n\n  document\n    .querySelector(\".business-association-review-section\")\n    .classList.add(\"d-none\");\n  clearReviewInputs(document.querySelectorAll(\".review-input-wrapper\"));\n}\n\n/**\n * Show or hide the funeral home selection input group.\n *\n * @param {Element} inputGroup - the <div> that is the FH selection input group.\n * @param {boolean} isOnboarding - true if we're in onboarding mode.\n * @param {boolean} shouldShow - true if we're meant to show; false if we're meant to hide.\n */\nfunction toggleFuneralHome(inputGroup, isOnboarding, shouldShow) {\n  inputGroup.classList.toggle(\"d-none\", !isOnboarding && !shouldShow);\n}\n\n/**\n * Initialize the business association form. Lots of autocomplete, lots of conditional\n * show/hide of subforms.\n *\n * @param {object} props - the page props\n */\nexport default function initBusinessAssociationForm(props) {\n  const { isOnboarding } = props;\n\n  const editDispositionMethodBtns = document.querySelectorAll(\n    \".edit-disposition-method\",\n  );\n  const businessAssociationInputGroups = document.querySelectorAll(\n    \".business-association-input-group\",\n  );\n\n  const funeralHomeInputGroup = document.querySelector(\".funeral-home-input-group\");\n  const cemeteryInputGroup = document.querySelector(\".cemetery-input-group\");\n  const donationOrgInputGroup = document.querySelector(\".donation-org-input-group\");\n  const seaBurialProviderInputGroup = document.querySelector(\n    \".sea-burial-provider-input-group\",\n  );\n  const locationTypeInputGroup = document.querySelector(\".location-type-input-group\");\n  const locationInputGroup = document.querySelector(\".location-input-group\");\n\n  const locationTypeSelect = document.querySelector(\n    \"#id_business_association-remains_location_type\",\n  );\n  const remainsLocationField = document.querySelector(\n    \"#id_business_association-remains_location\",\n  );\n\n  const funeralHomeInputLabel = funeralHomeInputGroup.querySelector(\".dark-gray-label\");\n  const funeralHomeInputPending = funeralHomeInputGroup.querySelector(\"label\");\n  const locationTypeNoRemains = locationTypeInputGroup.querySelector(\n    `option[value=\"${props.remainsLocationTypeNoRemains}\"]`,\n  );\n\n  /**\n   * Set the text of the funeral home input group.\n   *\n   * @param {boolean} isFuneralHome - if true, we're specifically a Funeral Home\n   * @param {boolean} isInitialLoad - if true, this is executing on the initial load of\n   *     the page\n   * @param {boolean} isGenericProvider - if true, set the label to copy about a\n   *     \"provider\" rather than a \"funeral home\"\n   */\n  const setTextOfFuneralHomeGroup = (\n    isFuneralHome = true,\n    isInitialLoad = false,\n    isGenericProvider = false,\n  ) => {\n    if (isInitialLoad) {\n      funeralHomeInputLabel.innerText = \"Funeral home or cremation provider\";\n      funeralHomeInputPending.innerText =\n        \"I have not yet chosen a funeral home or cremation provider\";\n    } else if (isFuneralHome) {\n      funeralHomeInputLabel.innerText = \"Funeral home\";\n      funeralHomeInputPending.innerText = \"I have not yet chosen a funeral home\";\n    } else if (isGenericProvider) {\n      funeralHomeInputLabel.innerText = \"Provider\";\n      funeralHomeInputPending.innerText = \"I have not yet chosen a provider\";\n    } else {\n      funeralHomeInputLabel.innerText = \"Cremation provider\";\n      funeralHomeInputPending.innerText = \"I have not yet chosen a cremation provider\";\n    }\n  };\n\n  /**\n   * Update disposition method form field visibilities.\n   */\n  const setDispositionMethodState = () => {\n    const nonSelectedDispositionRadios = document.querySelectorAll(\n      '[name=\"business_association-disposition_method\"]:not(:checked)',\n    );\n    const selectedDispositionRadio = document.querySelector(\n      '[name=\"business_association-disposition_method\"]:checked',\n    );\n\n    if (selectedDispositionRadio) {\n      const selectedDispositionRadioWrapper =\n        selectedDispositionRadio.closest(\".el-radio-btn\");\n      nonSelectedDispositionRadios.forEach((nonSelectedDispositionRadio) => {\n        const nonSelectedDispositionRadioWrapper =\n          nonSelectedDispositionRadio.closest(\".el-radio-btn\");\n        nonSelectedDispositionRadioWrapper.classList.add(\"d-none\");\n      });\n\n      selectedDispositionRadioWrapper.classList.remove(\"d-none\");\n      selectedDispositionRadioWrapper\n        .querySelector(\".edit-disposition-method\")\n        .classList.remove(\"d-none\");\n    } else {\n      nonSelectedDispositionRadios.forEach((nonSelectedDispositionRadio) => {\n        const nonSelectedDispositionRadioWrapper =\n          nonSelectedDispositionRadio.closest(\".el-radio-btn\");\n        nonSelectedDispositionRadioWrapper.classList.remove(\"d-none\");\n      });\n\n      editDispositionMethodBtns.forEach((editDispositionMethodBtn) => {\n        editDispositionMethodBtn.classList.add(\"d-none\");\n      });\n\n      // if there's no disposition method, check if user has data for funeral home or\n      // cemetery associations (the only field groups that existed before disposition\n      // method was added), so we can show it to users who have that data\n      updateBusinessAutocomplete(\n        props.funeralHomeSearch,\n        true,\n        props.funeralHomeSearch.businessPlaceholder,\n      );\n\n      if (\n        document.getElementById(props.funeralHomeSearch.businessIdentifierInputId)\n          .value ||\n        document.getElementById(props.funeralHomeSearch.businessStrInputId).value ||\n        document.getElementById(props.funeralHomeSearch.businessPending).checked\n      ) {\n        toggleFuneralHome(funeralHomeInputGroup, isOnboarding, true);\n      }\n\n      updateBusinessAutocomplete(\n        props.cemeterySearch,\n        true,\n        props.cemeterySearch.businessPlaceholder,\n      );\n\n      if (\n        document.getElementById(props.cemeterySearch.businessIdentifierInputId).value ||\n        document.getElementById(props.cemeterySearch.businessStrInputId).value ||\n        document.getElementById(props.cemeterySearch.businessPending).checked\n      ) {\n        cemeteryInputGroup.classList.remove(\"d-none\");\n      }\n    }\n  };\n\n  /**\n   * Show the burial-disposition-relevant form fields.\n   */\n  const showBurialFields = () => {\n    toggleFuneralHome(funeralHomeInputGroup, isOnboarding, true);\n    cemeteryInputGroup.classList.remove(\"d-none\");\n    setTextOfFuneralHomeGroup();\n  };\n\n  /**\n   * Show the cremation-disposition-relevant form fields.\n   *\n   * @param {boolean} isGenericProvider - if true, the funeral home input group is\n   *     slightly different to \"Provider\" instead of \"Funeral Home\"\n   */\n  const showCremationFields = (isGenericProvider = false) => {\n    toggleFuneralHome(funeralHomeInputGroup, isOnboarding, true);\n    locationTypeInputGroup.classList.remove(\"d-none\");\n    setTextOfFuneralHomeGroup(false, false, isGenericProvider);\n    locationTypeNoRemains.classList.add(\"d-none\");\n  };\n\n  /**\n   * Show the body-donation-disposition-relevant form fields.\n   */\n  const showDonationFields = () => {\n    donationOrgInputGroup.classList.remove(\"d-none\");\n    locationTypeInputGroup.classList.remove(\"d-none\");\n    locationTypeNoRemains.classList.remove(\"d-none\");\n  };\n\n  /**\n   * Show the sea-burial-disposition-relevant form fields.\n   */\n  const showSeaBurialFields = () => {\n    toggleFuneralHome(funeralHomeInputGroup, isOnboarding, true);\n    seaBurialProviderInputGroup.classList.remove(\"d-none\");\n    locationInputGroup.classList.remove(\"d-none\");\n    setTextOfFuneralHomeGroup();\n    locationInputGroup.querySelector(\".dark-gray-label\").innerText = \"Ocean (Location)\";\n    document\n      .getElementById(\"id_business_association-remains_location\")\n      .setAttribute(\"placeholder\", \"Ex: Pacific ocean\");\n  };\n\n  /**\n   * Show the form fields relevant to the \"other\" disposition method.\n   */\n  const showOtherFields = () => {\n    toggleFuneralHome(funeralHomeInputGroup, isOnboarding, true);\n    locationInputGroup.classList.remove(\"d-none\");\n  };\n\n  // show the funeral home field on initial load & update label\n  toggleFuneralHome(funeralHomeInputGroup, isOnboarding, true);\n  setTextOfFuneralHomeGroup(null, true);\n\n  // click handlers for disposition method radio buttons and edit buttons\n  editDispositionMethodBtns.forEach((editDispositionMethodBtn) => {\n    editDispositionMethodBtn.addEventListener(\"click\", () => {\n      document\n        .querySelectorAll(\n          '[name=\"business_association-disposition_method\"]:not(:checked)',\n        )\n        .forEach((nonSelectedDispositionRadio) => {\n          nonSelectedDispositionRadio\n            .closest(\".el-radio-btn\")\n            .classList.remove(\"d-none\");\n        });\n      editDispositionMethodBtns.forEach((innerEditDispositionMethodBtn) => {\n        innerEditDispositionMethodBtn.classList.add(\"d-none\");\n      });\n    });\n  });\n\n  document\n    .querySelectorAll('[name=\"business_association-disposition_method\"]')\n    .forEach((dispositionRadio) => {\n      dispositionRadio.addEventListener(\"change\", () => {\n        if (dispositionRadio.checked) {\n          clearAllBusinessAssociationInputs(props);\n        }\n      });\n    });\n\n  // show next fields depending on radio button selection, hide other fields and clear their inputs\n  const burialRadio = document.getElementById(\n    \"id_business_association-disposition_method_0\",\n  );\n  burialRadio.addEventListener(\"change\", () => {\n    if (burialRadio.checked) {\n      businessAssociationInputGroups.forEach((group) => {\n        if (![funeralHomeInputGroup, cemeteryInputGroup].includes(group)) {\n          group.classList.add(\"d-none\");\n        }\n      });\n\n      showBurialFields();\n      updateBusinessAutocomplete(\n        props.funeralHomeSearch,\n        false,\n        props.funeralHomeSearch.businessPlaceholder,\n      );\n      setDispositionMethodState();\n    }\n  });\n\n  const cremationRadio = document.getElementById(\n    \"id_business_association-disposition_method_1\",\n  );\n  cremationRadio.addEventListener(\"change\", () => {\n    if (cremationRadio.checked) {\n      businessAssociationInputGroups.forEach((group) => {\n        if (![funeralHomeInputGroup, locationTypeInputGroup].includes(group)) {\n          group.classList.add(\"d-none\");\n        }\n      });\n\n      showCremationFields();\n      setDispositionMethodState();\n    }\n  });\n\n  const donationRadio = document.getElementById(\n    \"id_business_association-disposition_method_2\",\n  );\n  donationRadio.addEventListener(\"change\", () => {\n    if (donationRadio.checked) {\n      businessAssociationInputGroups.forEach((group) => {\n        if (![donationOrgInputGroup, locationTypeInputGroup].includes(group)) {\n          group.classList.add(\"d-none\");\n        }\n      });\n\n      showDonationFields();\n      setDispositionMethodState();\n    }\n  });\n\n  const seaBurialRadio = document.getElementById(\n    \"id_business_association-disposition_method_3\",\n  );\n  seaBurialRadio.addEventListener(\"change\", () => {\n    if (seaBurialRadio.checked) {\n      businessAssociationInputGroups.forEach((group) => {\n        if (\n          ![\n            funeralHomeInputGroup,\n            seaBurialProviderInputGroup,\n            locationTypeInputGroup,\n          ].includes(group)\n        ) {\n          group.classList.add(\"d-none\");\n        }\n      });\n\n      showSeaBurialFields();\n      updateBusinessAutocomplete(\n        props.funeralHomeSearch,\n        false,\n        props.funeralHomeSearch.businessPlaceholder,\n      );\n      setDispositionMethodState();\n    }\n  });\n\n  const naturalOrganicReductionRadio = document.getElementById(\n    \"id_business_association-disposition_method_4\",\n  );\n  naturalOrganicReductionRadio.addEventListener(\"change\", () => {\n    if (naturalOrganicReductionRadio.checked) {\n      businessAssociationInputGroups.forEach((group) => {\n        if (![funeralHomeInputGroup, locationTypeInputGroup].includes(group)) {\n          group.classList.add(\"d-none\");\n        }\n      });\n\n      showCremationFields(true);\n      setDispositionMethodState();\n    }\n  });\n\n  const liquidCremationRadio = document.getElementById(\n    \"id_business_association-disposition_method_5\",\n  );\n  liquidCremationRadio.addEventListener(\"change\", () => {\n    if (liquidCremationRadio.checked) {\n      businessAssociationInputGroups.forEach((group) => {\n        if (![funeralHomeInputGroup, locationTypeInputGroup].includes(group)) {\n          group.classList.add(\"d-none\");\n        }\n      });\n\n      showCremationFields();\n      setDispositionMethodState();\n    }\n  });\n\n  const otherRadio = document.getElementById(\n    \"id_business_association-disposition_method_6\",\n  );\n  otherRadio.addEventListener(\"change\", () => {\n    if (otherRadio.checked) {\n      if (isOnboarding) {\n        businessAssociationInputGroups.forEach((group) => {\n          if (![funeralHomeInputGroup, locationTypeInputGroup].includes(group)) {\n            group.classList.add(\"d-none\");\n          }\n        });\n      } else {\n        businessAssociationInputGroups.forEach((group) => {\n          if (group !== locationInputGroup) {\n            group.classList.add(\"d-none\");\n          }\n        });\n      }\n\n      showOtherFields();\n      setDispositionMethodState();\n      setTextOfFuneralHomeGroup();\n    }\n  });\n\n  const pendingRadio = document.getElementById(\n    \"id_business_association-disposition_method_7\",\n  );\n  pendingRadio.addEventListener(\"change\", () => {\n    if (pendingRadio.checked) {\n      businessAssociationInputGroups.forEach((group) => {\n        if (group !== funeralHomeInputGroup) {\n          group.classList.add(\"d-none\");\n        }\n      });\n\n      setDispositionMethodState();\n    }\n  });\n\n  /**\n   * Clear the remains-location-relevant inputs.\n   */\n  const clearLocationInputs = () => {\n    remainsLocationField.removeAttribute(\"disabled\");\n    remainsLocationField.classList.remove(\"disabled\");\n    remainsLocationField.value = \"\";\n\n    const locationMetadataInput = document.getElementById(\n      \"id_business_association-remains_location_metadata\",\n    );\n    locationMetadataInput.value = \"{}\";\n\n    const locationInputGroupLabel = document.querySelector(\n      \".location-input-group .dark-gray-label\",\n    );\n    locationInputGroupLabel.innerText = \"Location\";\n\n    remainsLocationField.setAttribute(\n      \"placeholder\",\n      \"Ex: 123 Green street, San Francisco, CA\",\n    );\n\n    const pendingCheckbox = document.getElementById(\n      \"id_business_association-remains_location_pending\",\n    );\n    pendingCheckbox.checked = false;\n  };\n\n  /**\n   * Clear the cemetery-search-related inputs.\n   */\n  const clearCemeteryInputs = () => {\n    const cemeterySearchInput = document.getElementById(\n      props.cemeterySearch.businessIdentifierInputId,\n    );\n\n    if (cemeterySearchInput.tomselect) {\n      cemeterySearchInput.tomselect.clear();\n      cemeterySearchInput.tomselect.clearOptions();\n      cemeterySearchInput.tomselect.enable();\n    }\n\n    document.getElementById(props.cemeterySearch.businessPending).checked = false;\n  };\n\n  /**\n   * Show next field depending on location type dropdown selection\n   *\n   * @param {boolean} showInitialValue - if true, show the initial value from props.\n   */\n  const showLocationTypeFollowupField = (showInitialValue) => {\n    if (locationTypeSelect.value === props.remainsLocationTypeCemetery.toString()) {\n      cemeteryInputGroup.classList.remove(\"d-none\");\n      locationInputGroup.classList.add(\"d-none\");\n\n      if (showInitialValue) {\n        updateBusinessAutocomplete(\n          props.cemeterySearch,\n          true,\n          props.cemeterySearch.businessPlaceholder,\n        );\n      } else {\n        updateBusinessAutocomplete(\n          props.cemeterySearch,\n          false,\n          props.cemeterySearch.businessPlaceholder,\n        );\n      }\n    } else if (\n      locationTypeSelect.value === props.remainsLocationTypeNoRemains.toString() ||\n      !locationTypeSelect.value\n    ) {\n      locationInputGroup.classList.add(\"d-none\");\n      cemeteryInputGroup.classList.add(\"d-none\");\n    } else if (locationTypeSelect.value) {\n      locationInputGroup.classList.remove(\"d-none\");\n      cemeteryInputGroup.classList.add(\"d-none\");\n    }\n  };\n\n  locationTypeSelect.addEventListener(\"change\", () => {\n    clearLocationInputs();\n    clearCemeteryInputs();\n    showLocationTypeFollowupField(false);\n  });\n\n  const remainsLocationTypeCheckbox = document.getElementById(\n    \"id_business_association-remains_location_type_pending\",\n  );\n  const remainsLocationCheckbox = document.getElementById(\n    \"id_business_association-remains_location_pending\",\n  );\n\n  /**\n   * Update the remains location form fields' visibility based on other form state.\n   */\n  const setRemainsLocationTypeState = () => {\n    const remainsLocationTypeField = document.getElementById(\n      \"id_business_association-remains_location_type\",\n    );\n\n    if (remainsLocationTypeCheckbox.checked) {\n      remainsLocationTypeField.setAttribute(\"disabled\", \"disabled\");\n      remainsLocationTypeField.classList.add(\"disabled\");\n      locationTypeSelect.value = \"\";\n    } else {\n      remainsLocationTypeField.removeAttribute(\"disabled\");\n      remainsLocationTypeField.classList.remove(\"disabled\");\n      showLocationTypeFollowupField(true);\n    }\n  };\n\n  /**\n   * Update the remains location state based on the checkbox state.\n   */\n  const setRemainsLocationState = () => {\n    if (remainsLocationCheckbox.checked) {\n      remainsLocationField.setAttribute(\"disabled\", \"disabled\");\n      remainsLocationField.classList.add(\"disabled\");\n      remainsLocationField.value = \"\";\n    } else {\n      remainsLocationField.removeAttribute(\"disabled\");\n      remainsLocationField.classList.remove(\"disabled\");\n    }\n  };\n\n  remainsLocationTypeCheckbox.addEventListener(\"click\", () => {\n    setRemainsLocationTypeState();\n    clearLocationInputs();\n    clearCemeteryInputs();\n    showLocationTypeFollowupField(false);\n  });\n\n  remainsLocationCheckbox.addEventListener(\"click\", () => {\n    setRemainsLocationState();\n  });\n\n  // initial state for display\n  setDispositionMethodState();\n\n  // Set addSubmitListener to true here as we only want to add the submit event listener\n  // during initialization.\n  updateBusinessAutocomplete(\n    props.funeralHomeSearch,\n    true,\n    props.funeralHomeSearch.businessPlaceholder,\n    true,\n  );\n  updateBusinessAutocomplete(\n    props.cemeterySearch,\n    true,\n    props.cemeterySearch.businessPlaceholder,\n    true,\n  );\n  updateBusinessAutocomplete(\n    props.hospiceSearch,\n    true,\n    props.hospiceSearch.businessPlaceholder,\n    true,\n  );\n  updateBusinessAutocomplete(\n    props.donationOrgSearch,\n    true,\n    props.donationOrgSearch.businessPlaceholder,\n    true,\n  );\n  updateBusinessAutocomplete(\n    props.deathDoulaSearch,\n    true,\n    props.deathDoulaSearch.businessPlaceholder,\n    true,\n  );\n  updateBusinessAutocomplete(\n    props.seaBurialProviderSearch,\n    true,\n    props.seaBurialProviderSearch.businessPlaceholder,\n    true,\n  );\n\n  setRemainsLocationState();\n\n  const selectedDispositionRadio = document.querySelector(\n    '[name=\"business_association-disposition_method\"]:checked',\n  );\n\n  if (selectedDispositionRadio === burialRadio) {\n    showBurialFields();\n  } else if (selectedDispositionRadio === cremationRadio) {\n    showCremationFields();\n    setRemainsLocationTypeState();\n  } else if (selectedDispositionRadio === donationRadio) {\n    showDonationFields();\n    setRemainsLocationTypeState();\n  } else if (selectedDispositionRadio === seaBurialRadio) {\n    showSeaBurialFields();\n  } else if (selectedDispositionRadio === naturalOrganicReductionRadio) {\n    showCremationFields();\n    setRemainsLocationTypeState();\n  } else if (selectedDispositionRadio === liquidCremationRadio) {\n    showCremationFields();\n    setRemainsLocationTypeState();\n  } else if (selectedDispositionRadio === otherRadio) {\n    showOtherFields();\n  }\n\n  if (!props.disableReviews) {\n    initBusinessReviewSection(props);\n  }\n}\n","import flatpickr from \"flatpickr\";\n\nexport default function initDateTimePicker(props) {\n  flatpickr(props.element, {\n    allowInput: true,\n    altFormat: \"l, F j, Y h:i K\",\n    altInput: true,\n    enableTime: true,\n    onChange(selectedDates, dateStr, instance) {\n      instance._previousInput = instance._input.value;\n    },\n    onClose(selectedDates, dateStr, instance) {\n      if (\n        instance.config.allowInput &&\n        instance._input.value &&\n        instance._input.value !== instance._previousInput\n      ) {\n        instance.setDate(instance._input.value, true, instance.config.altFormat);\n      }\n    },\n    onReady(selectedDates, dateStr, instance) {\n      instance._previousInput = instance._input.value;\n    },\n  });\n}\n","import Collapse from \"bootstrap/js/dist/collapse\";\n\nimport initDateTimePicker from \"./DateTimePicker\";\nimport initGoogleAutocomplete from \"./GoogleAutocomplete\";\nimport initParticipantAutocomplete from \"./Participant\";\nimport { initAttendeeFormset } from \"../memorials/rsvps\";\nimport { scrollInMemorialPrivateContentContainer } from \"../memorials/utils\";\nimport { generateElements } from \"../core/utils\";\n\nconst placeholderEventsStatePending =\n  \"Example: We're planning a celebration of life sometime in June in Chicago. I'll add more details as soon as we lock down a date.\";\n\n/**\n * Disable the edit events forms when a non-events-public event_state is selected.\n *\n * @param {boolean} disabled - if the forms should be disabled.\n */\nconst setEventsContainerInputsDisabledState = (disabled) => {\n  const eventInputContainers = document.querySelectorAll(\".edit-events-container\");\n  eventInputContainers.forEach((eventInputContainer) => {\n    eventInputContainer\n      .querySelectorAll(\"input, textarea, select\")\n      .forEach((eventInput) => {\n        if (eventInput.tomselect) {\n          if (disabled) {\n            eventInput.tomselect.disable();\n          } else {\n            eventInput.tomselect.enable();\n          }\n        } else {\n          eventInput.disabled = disabled;\n        }\n      });\n  });\n};\n\n/**\n * Initialize behavior where if the \"other\" title is focused, the \"other\" event type\n * radio gets selected.\n *\n * @param {number} formCount - the number of forms (which is used as the index of the\n *     title input to which to attach the behavior)\n */\nconst addEventTypeOtherFocus = (formCount) => {\n  const title = document.getElementById(`id_form-${formCount}-event_type_other_title`);\n  const otherInput = title.parentElement.querySelector('[value=\"0\"]');\n  title.addEventListener(\"click\", () => {\n    otherInput.checked = true;\n  });\n};\n\n/**\n * Initialize handling event type selection for an event form.\n *\n * @param {HTMLElement} formContainer - the form-containing element.\n */\nconst attachEventTypeListener = (formContainer) => {\n  const eventTypeContainer = formContainer.querySelector(\".event-type\");\n\n  /**\n   * Handle the event selection -- show and hide the name field, etc.\n   */\n  const handleEventSelection = () => {\n    const selectedEventType = eventTypeContainer.querySelector(\n      'input[type=\"radio\"]:checked',\n    );\n    const eventName = formContainer.querySelector(\".event-name\");\n    if (selectedEventType && eventName) {\n      const otherField = document.getElementById(\n        `id_${selectedEventType.getAttribute(\"name\")}_other_title`,\n      );\n      const newTitle =\n        selectedEventType.value === \"0\"\n          ? otherField.value\n          : document.querySelector(\n              `label[for=${selectedEventType.getAttribute(\"id\")}] .radio-label-text`,\n            ).innerText;\n\n      if (newTitle) {\n        eventName.innerText = newTitle;\n        eventName.classList.remove(\"empty\");\n      } else {\n        eventName.innerText = \"New Event\";\n        eventName.classList.add(\"empty\");\n      }\n\n      if (selectedEventType.value === \"0\") {\n        otherField.setAttribute(\"required\", \"required\");\n      } else {\n        otherField.removeAttribute(\"required\");\n      }\n    }\n  };\n\n  eventTypeContainer.querySelectorAll('input[type=\"radio\"]').forEach((radio) => {\n    radio.addEventListener(\"click\", handleEventSelection);\n  });\n\n  eventTypeContainer\n    .querySelector('input[type=\"text\"]')\n    .addEventListener(\"input\", handleEventSelection);\n\n  handleEventSelection();\n};\n\n/**\n * Initialize the Google places autocomplete behavior for an event form.\n *\n * @param {HTMLInputElement} element - the input to which to attach autocomplete.\n * @param {HTMLInputElement} metadataElement - the metadata element into which to place\n *     metadata\n * @param {boolean} alwaysBlockReturnKeySubmit - if true, block return key sending a\n *     submit event to the form\n */\nconst addEventLocationAutocomplete = (\n  element,\n  metadataElement,\n  alwaysBlockReturnKeySubmit,\n) => {\n  initGoogleAutocomplete({\n    element,\n    metadataElement,\n    options: {\n      types: [\"establishment\", \"geocode\"],\n    },\n    alwaysBlockReturnKeySubmit,\n  });\n};\n\n/**\n * Initialize the RSVP limit feature on an event form.\n *\n * @param {HTMLElement} container - the event form container\n */\nconst initRSVPLimitBehavior = (container) => {\n  const rsvpsEnabledCheckbox = container.querySelector(\".event-rsvps-enabled-checkbox\");\n  const rsvpsLimitContainer = container.querySelector(\".rsvps-limit-container\");\n\n  if (!(rsvpsEnabledCheckbox && rsvpsLimitContainer)) {\n    return;\n  }\n\n  const rsvpsLimitContainerCollapse = Collapse.getOrCreateInstance(\n    rsvpsLimitContainer,\n    { toggle: false },\n  );\n  const rsvpsLimitCheckbox = container.querySelector(\".event-rsvps-limit-checkbox\");\n  const rsvpsLimitFieldContainer = container.querySelector(\n    \".rsvps-limit-field-container\",\n  );\n  const rsvpsLimitField = rsvpsLimitFieldContainer.querySelector('[type=\"number\"]');\n  const rsvpsLimitFieldContainerCollapse = Collapse.getOrCreateInstance(\n    rsvpsLimitFieldContainer,\n    { toggle: false },\n  );\n\n  /**\n   * Update the limit display based on RSVP/limit state.\n   */\n  const updateRSVPLimitDisplay = () => {\n    if (rsvpsEnabledCheckbox.checked) {\n      rsvpsLimitContainerCollapse.show();\n    } else {\n      rsvpsLimitContainerCollapse.hide();\n    }\n\n    if (rsvpsLimitCheckbox.checked) {\n      if (!rsvpsLimitField.value) {\n        const minValue = rsvpsLimitField.getAttribute(\"min\");\n        if (minValue) {\n          rsvpsLimitField.value = Number.parseInt(minValue, 10);\n        } else {\n          rsvpsLimitField.value = 10;\n        }\n      }\n\n      rsvpsLimitFieldContainerCollapse.show();\n    } else {\n      rsvpsLimitField.value = null;\n      rsvpsLimitFieldContainerCollapse.hide();\n    }\n  };\n\n  rsvpsEnabledCheckbox.addEventListener(\"change\", updateRSVPLimitDisplay);\n  rsvpsLimitCheckbox.addEventListener(\"change\", updateRSVPLimitDisplay);\n\n  updateRSVPLimitDisplay();\n};\n\n/**\n * Initialize the streaming configuration behavior for an event form.\n *\n * @param {HTMLElement} container - the event form container\n */\nconst initStreamingOptions = (container) => {\n  const eventStreamingCheckbox = container.querySelector(\n    \".event-stream-enabled-checkbox\",\n  );\n  const zoomHostingCheckbox = container.querySelector(\".event-zoom-enabled-checkbox\");\n  const urlContainer = container.querySelector(\".event-streaming-url-container\");\n  const zoomDataContainer = container.querySelector(\".event-zoom-data-container\");\n  const eventLocationLabel = container.querySelector(\".event-location-label\");\n\n  /**\n   * Update the location field label with (optional for streams) as necessary.\n   */\n  const updateLocationLabel = () => {\n    if (eventStreamingCheckbox.checked || zoomHostingCheckbox.checked) {\n      if (eventLocationLabel.textContent.indexOf(\" (optional for streams)\") === -1) {\n        eventLocationLabel.textContent = eventLocationLabel.textContent.concat(\n          \" (optional for streams)\",\n        );\n      }\n    } else {\n      eventLocationLabel.textContent = eventLocationLabel.textContent.replace(\n        \" (optional for streams)\",\n        \"\",\n      );\n    }\n  };\n\n  eventStreamingCheckbox.addEventListener(\"click\", (event) => {\n    updateLocationLabel();\n    if (event.target.checked) {\n      urlContainer.classList.remove(\"d-none\");\n    } else {\n      urlContainer.classList.add(\"d-none\");\n    }\n  });\n\n  zoomHostingCheckbox.addEventListener(\"click\", (event) => {\n    updateLocationLabel();\n    if (event.target.checked) {\n      zoomDataContainer.classList.remove(\"d-none\");\n    } else {\n      zoomDataContainer.classList.add(\"d-none\");\n    }\n  });\n};\n\n/**\n * Initialize \"Extra Data\" fields for an event form -- COVID precautions, attachments.\n *\n * @param {HTMLElement} container - the event form container\n * @param {object} props - the page props\n * @returns {Function} - a function to flush selected participants to the JSON field.\n */\nconst initEventExtraData = (container, props) => {\n  let flushParticipantData;\n  if (container) {\n    const showCovid = container.querySelector(\".toggle-covid-precautions\");\n    const covidInputs = container.querySelector(\".event-covid-precautions\");\n\n    if (showCovid && covidInputs) {\n      showCovid.addEventListener(\"click\", () => {\n        showCovid.classList.add(\"d-none\");\n        covidInputs.classList.remove(\"d-none\");\n      });\n    }\n\n    const covidPrecautionOtherContainer = container.querySelector(\n      \".covid-precaution-other-container\",\n    );\n    if (covidPrecautionOtherContainer) {\n      const checkbox = covidPrecautionOtherContainer.querySelector(\n        'input[type=\"checkbox\"]',\n      );\n      const label = covidPrecautionOtherContainer.querySelector(\n        \".covid-precaution-other-label\",\n      );\n      const field = covidPrecautionOtherContainer.querySelector(\n        \".covid-precaution-other-field-container\",\n      );\n\n      checkbox.addEventListener(\"change\", () => {\n        label.classList.toggle(\"d-none\", checkbox.checked);\n        field.classList.toggle(\"d-none\", !checkbox.checked);\n\n        if (!checkbox.checked) {\n          field.querySelector('input[type=\"text\"]').value = \"\";\n        }\n      });\n    }\n\n    const attachmentInputContainer = container.querySelector(\n      \".program-attachment-field\",\n    );\n    const attachmentInput = container.querySelector('input[type=\"file\"]');\n    const downloadProgramLink = container.querySelector(\".download-program-link\");\n    const removeContainer = container.querySelector(\".program-attachment-remove-field\");\n    const removeField = container.querySelector(\".remove-program-input\");\n    if (attachmentInput) {\n      attachmentInput.addEventListener(\"change\", (event) => {\n        const { files } = event.currentTarget;\n        if (files && files[0]) {\n          removeField.value = null;\n          removeContainer.classList.remove(\"d-none\");\n        }\n      });\n    }\n\n    const programTextCTA = container.querySelector(\".program-text-cta\");\n    const programTextContainer = container.querySelector(\".program-text-container\");\n    if (programTextCTA && programTextContainer) {\n      programTextCTA.addEventListener(\"click\", () => {\n        programTextCTA.classList.add(\"d-none\");\n        programTextContainer.classList.remove(\"d-none\");\n      });\n\n      const programTextarea = programTextContainer.querySelector(\"textarea\");\n\n      // NOTE: We don't want to import editor here because we don't want any chunks\n      // shared between the editor and memorialsPrivate entrypoints. Additionally, we\n      // shouldn't use dependOn either as any editor would then need to be loaded\n      // anywhere we load memorialsPrivate.\n      //\n      // So, instead, we just trust that the editor bundle was loaded and is available\n      // in window.eljs...\n      window.eljs.editor.initEditor({\n        editor: {\n          customButtons: [\"h2\", \"h3\"],\n          inputId: programTextarea.id,\n          inputContainerSelector: \".program-text-container\",\n          templates: null,\n          templatesContainerSelector: null,\n        },\n        userMention: props.userMention,\n      });\n    }\n\n    const speakersContainer = container.querySelector(\".participants-input\");\n    if (speakersContainer) {\n      const participants = speakersContainer.querySelector(\"select\");\n      const participantsJson = speakersContainer.querySelector('input[type=\"hidden\"]');\n\n      const participantAutocompleteProps = {\n        participantsInitialAutocompleteData:\n          props.participantsInitialAutocompleteDataByEvent[container.dataset.uuid],\n        participantsInputIds: {\n          participants: participants.id,\n          participantsJson: participantsJson.id,\n        },\n        userMention: props.userMention,\n      };\n\n      flushParticipantData = initParticipantAutocomplete(participantAutocompleteProps);\n    }\n\n    if (removeContainer) {\n      const removeLink = removeContainer.querySelector(\".remove-program-attachment\");\n      removeLink.addEventListener(\"click\", () => {\n        if (attachmentInput) {\n          attachmentInput.value = null;\n        }\n\n        if (removeField) {\n          removeField.value = true;\n        }\n\n        if (downloadProgramLink) {\n          downloadProgramLink.classList.add(\"d-none\");\n        }\n\n        removeContainer.classList.add(\"d-none\");\n        attachmentInputContainer.classList.remove(\"d-none\");\n      });\n    }\n  }\n\n  return flushParticipantData;\n};\n\n/**\n * Expand the RSVPs container\n *\n * @param {HTMLElement} triggeringElement - the element triggering the showing of RSVPs container.\n * @param {boolean} scrollToDetails - if true, scroll to the RSVP details.\n */\nconst expandRSVPs = (triggeringElement, scrollToDetails = false) => {\n  const rsvpsContainer =\n    triggeringElement.parentElement.parentElement.querySelector(\".rsvps-details\");\n  triggeringElement.classList.add(\"d-none\");\n  rsvpsContainer.classList.remove(\"d-none\");\n\n  if (scrollToDetails) {\n    scrollInMemorialPrivateContentContainer(rsvpsContainer, -340);\n  }\n};\n\n/**\n * Initialize the edit events page. Formset management, initializing copious features\n * on each form, and probably more.\n *\n * @param {object} props - the page props\n * @param {Array<Function>} deleteEventCallbacks - an array of callback functions to\n *     call when an event is deleted\n */\nexport function initEditEvents(props, deleteEventCallbacks) {\n  // Placeholders need to be initialized for event state note fields\n  const placeholderEventsStateNotHappening = `Example: ${props.memorialFirstName} did not want a funeral service, but we appreciate all the love and support and encourage everyone to share their favorite memories of ${props.memorialFirstName} on this memorial website.`;\n  const placeholderEventsStatePrivate = `Example: ${props.memorialFirstName} requested a small service with immediate family only, but we appreciate everyone's love and support and encourage everyone to share their favorite memories of ${props.memorialFirstName} on this memorial website.`;\n  const changeTimezoneContainer = document.querySelector(\".change-timezone-container\");\n  const bottomSubmitRow = document.querySelector(\".bottom-submit-row\");\n  const topSubmitRow = document.querySelector(\".top-submit-row\");\n\n  if (props.eventsState === props.eventsStatePublic) {\n    setEventsContainerInputsDisabledState(false);\n  } else {\n    setEventsContainerInputsDisabledState(true);\n  }\n\n  const nonPublicEventStateReasonField = document.querySelector(\n    \".events-state-non-public .other-reason\",\n  );\n  let eventsNote = \"\";\n  if (nonPublicEventStateReasonField) {\n    if (props.eventsState === props.eventsStatePrivate) {\n      nonPublicEventStateReasonField.setAttribute(\n        \"placeholder\",\n        placeholderEventsStatePrivate,\n      );\n    } else if (props.eventsState === props.eventsStateNotHappening) {\n      nonPublicEventStateReasonField.setAttribute(\n        \"placeholder\",\n        placeholderEventsStateNotHappening,\n      );\n    } else if (props.eventsState === props.eventsStatePending) {\n      nonPublicEventStateReasonField.setAttribute(\n        \"placeholder\",\n        placeholderEventsStatePending,\n      );\n    }\n\n    // we need to preserve the event state note toggles, so let's keep that here\n    eventsNote = nonPublicEventStateReasonField.value;\n  }\n\n  const privateEventStreamCheckbox = document.querySelector(\n    '.private-event-stream input[type=\"checkbox\"]',\n  );\n  const streamEntryField = document.querySelector(\n    \".private-event-stream .stream-entry\",\n  );\n  if (privateEventStreamCheckbox && streamEntryField) {\n    privateEventStreamCheckbox.addEventListener(\"change\", (event) => {\n      streamEntryField.classList.toggle(\"d-none\", !event.target.checked);\n    });\n  }\n\n  const privateEventZoomCheckbox = document.querySelector(\n    '.private-event-zoom input[type=\"checkbox\"]',\n  );\n  const privateEventZoomDataContainer = document.querySelector(\n    \".private-event-zoom .event-zoom-data-container\",\n  );\n\n  if (privateEventZoomCheckbox && privateEventZoomDataContainer) {\n    privateEventZoomCheckbox.addEventListener(\"change\", (event) => {\n      privateEventZoomDataContainer.classList.toggle(\"d-none\", !event.target.checked);\n    });\n  }\n\n  document\n    .querySelectorAll('.event-state-selection-wrapper input[type=\"radio\"]')\n    .forEach((stateRadio) => {\n      stateRadio.addEventListener(\"change\", (event) => {\n        const selectedRadio = event.target;\n\n        // when toggling between radio buttons, we want to display a warning that events\n        // related to this memorial will be deleted if moving from a public event state with\n        // events to a non public or pending state\n        if (\n          props.eventsState === props.eventsStatePublic &&\n          selectedRadio.value !== `${props.eventsStatePublic}`\n        ) {\n          document.querySelector(\".event-delete-warning\").classList.remove(\"d-none\");\n        }\n\n        setEventsContainerInputsDisabledState(\n          selectedRadio.value !== `${props.eventsStatePublic}`,\n        );\n\n        document\n          .querySelectorAll(\n            \".events-state-non-public .private-event-stream, .events-state-non-public .private-event-zoom\",\n          )\n          .forEach((streamOption) => {\n            streamOption.classList.toggle(\n              \"d-none\",\n              selectedRadio.value !== `${props.eventsStatePrivate}`,\n            );\n          });\n\n        const otherReason = document.querySelector(\n          \".events-state-non-public .other-reason\",\n        );\n        if (selectedRadio.value === `${props.eventsStatePublic}`) {\n          // if we are toggling to make the memorial event state public, we should\n          // toggle the appropriate cards on and off and hide the event deletion warning.\n          document\n            .querySelectorAll(\n              \".events-state-non-public, .events-state-pending, .events-state-no-info, .event-delete-warning\",\n            )\n            .forEach((toHide) => {\n              toHide.classList.add(\"d-none\");\n            });\n          document\n            .querySelectorAll(\".edit-events-containers, .add-event-container\")\n            .forEach((toShow) => {\n              toShow.classList.remove(\"d-none\");\n            });\n\n          if (topSubmitRow) {\n            topSubmitRow.classList.add(\"d-none\");\n          }\n\n          if (bottomSubmitRow) {\n            bottomSubmitRow.classList.remove(\"d-none\");\n          }\n\n          const totalFormCount = document.querySelectorAll(\n            \".edit-events-containers .edit-events-container\",\n          ).length;\n          document\n            .querySelectorAll(\".remove-event\")\n            .forEach((removeButton) =>\n              removeButton.classList.toggle(\"d-none\", totalFormCount <= 1),\n            );\n\n          if (!props.hideTimezone) {\n            changeTimezoneContainer.classList.remove(\"d-none\");\n          }\n        } else if (\n          [`${props.eventsStatePrivate}`, `${props.eventsStateNotHappening}`].includes(\n            selectedRadio.value,\n          )\n        ) {\n          if (selectedRadio.value === `${props.eventsStatePrivate}`) {\n            otherReason.setAttribute(\"placeholder\", placeholderEventsStatePrivate);\n            otherReason.value =\n              props.eventsState === props.eventsStatePrivate && eventsNote\n                ? eventsNote\n                : \"\";\n          } else {\n            otherReason.setAttribute(\"placeholder\", placeholderEventsStateNotHappening);\n            otherReason.value =\n              props.eventsState === props.eventsStateNotHappening && eventsNote\n                ? eventsNote\n                : \"\";\n          }\n\n          document\n            .querySelectorAll(\n              \".edit-events-containers, .add-event-container, .events-state-pending, .events-state-no-info\",\n            )\n            .forEach((toHide) => toHide.classList.add(\"d-none\"));\n          document.querySelector(\".events-state-non-public\").classList.remove(\"d-none\");\n\n          if (topSubmitRow) {\n            topSubmitRow.classList.remove(\"d-none\");\n          }\n\n          if (bottomSubmitRow) {\n            bottomSubmitRow.classList.add(\"d-none\");\n          }\n\n          if (!props.hideTimezone) {\n            changeTimezoneContainer.classList.add(\"d-none\");\n          }\n        } else if (selectedRadio.value === `${props.eventsStatePending}`) {\n          otherReason.setAttribute(\"placeholder\", placeholderEventsStatePending);\n          otherReason.value =\n            props.eventsState === props.eventsStatePending && eventsNote\n              ? eventsNote\n              : \"\";\n\n          // toggle the appropriate containers for the pending state when clicking on the pending\n          // radio button\n          document\n            .querySelectorAll(\n              \".edit-events-containers, .add-event-container, .events-state-no-info, .private-event-stream, .private-event-zoom\",\n            )\n            .forEach((toHide) => toHide.classList.add(\"d-none\"));\n          document\n            .querySelectorAll(\".events-state-pending, .events-state-non-public\")\n            .forEach((toShow) => toShow.classList.remove(\"d-none\"));\n\n          if (topSubmitRow) {\n            topSubmitRow.classList.remove(\"d-none\");\n          }\n\n          if (bottomSubmitRow) {\n            bottomSubmitRow.classList.add(\"d-none\");\n          }\n\n          if (!props.hideTimezone) {\n            changeTimezoneContainer.classList.add(\"d-none\");\n          }\n        } else if (selectedRadio.value === `${props.eventsStateNoInfo}`) {\n          // toggle the appropriate containers for the \"no information\" when clicking on the pending\n          // radio button\n          document\n            .querySelectorAll(\n              \".edit-events-containers, .add-event-container, .events-state-non-public, .events-state-pending\",\n            )\n            .forEach((toHide) => toHide.classList.add(\"d-none\"));\n          document.querySelector(\".events-state-no-info\").classList.add(\"d-none\");\n\n          if (topSubmitRow) {\n            topSubmitRow.classList.remove(\"d-none\");\n          }\n\n          if (bottomSubmitRow) {\n            bottomSubmitRow.classList.add(\"d-none\");\n          }\n\n          if (!props.hideTimezone) {\n            changeTimezoneContainer.classList.add(\"d-none\");\n          }\n        }\n      });\n    });\n\n  document.querySelectorAll(\".datetime-input\").forEach((datetimeInputElement) => {\n    initDateTimePicker({ element: datetimeInputElement });\n\n    // Listen for clearing of the input field. If this is the case then we want to make\n    // the hidden DateTimePicker input field have a cleared value in case we want to\n    // edit an event and remove an end date.\n    const pickerInput = datetimeInputElement.nextElementSibling;\n    pickerInput.addEventListener(\"input\", () => {\n      if (!pickerInput.value) {\n        datetimeInputElement.value = \"\";\n      }\n    });\n  });\n\n  const deleteCallbacks = Array.from(\n    document.querySelectorAll(\".edit-events-container\"),\n  )\n    .map((container) => {\n      initStreamingOptions(container);\n      initRSVPLimitBehavior(container);\n      return initEventExtraData(container, props);\n    })\n    .filter((callback) => callback);\n  deleteEventCallbacks = [...deleteEventCallbacks, ...deleteCallbacks];\n\n  document.querySelectorAll(\".remove-event a\").forEach((removeEventAnchor) => {\n    removeEventAnchor.addEventListener(\"click\", (event) => {\n      const idField = removeEventAnchor\n        .closest(\".edit-events-container\")\n        .querySelector('input[type=\"hidden\"]');\n      if (idField && idField.value) {\n        if (window.confirm(\"Are you sure you want to delete this event?\")) {\n          if (deleteEventCallbacks.length >= 1) {\n            deleteEventCallbacks.forEach((cb) => cb());\n          }\n\n          const form = removeEventAnchor.closest(\"form\");\n          const toDelete = event.currentTarget.previousElementSibling;\n          toDelete.checked = true;\n          form.setAttribute(\"data-dirty-track-is-submitting\", \"1\");\n          form.action = \"?dr=1&edit-events=1\";\n          form.submit();\n        }\n      }\n    });\n  });\n\n  const showRSVPs = document.querySelectorAll(\".show-rsvps\");\n  showRSVPs.forEach((element) => {\n    element.addEventListener(\"click\", () => {\n      expandRSVPs(element);\n    });\n  });\n\n  if (props.attendeeFormsetProps) {\n    Object.keys(props.attendeeFormsetProps).forEach((eventUUID) => {\n      const formsetProps = props.attendeeFormsetProps[eventUUID];\n      initAttendeeFormset(eventUUID, formsetProps);\n    });\n  }\n}\n\n// NOTE: This function used to be run from a callback function from the Google Maps API\n// before we switched to async/await; hence the name.\nexport function initEditEventsOnLoad(props, deleteEventCallbacks) {\n  const inputElements = document.getElementsByClassName(\"location-autocomplete\");\n  let { totalFormCount } = props;\n  const totalFormCountInput = document.getElementById(\"id_form-TOTAL_FORMS\");\n  totalFormCountInput.value = totalFormCount;\n  const bottomSubmitRow = document.querySelector(\".bottom-submit-row\");\n\n  for (let i = 0; i < inputElements.length; i += 1) {\n    addEventLocationAutocomplete(\n      inputElements[i],\n      document.getElementById(`id_form-${i}-location_metadata`),\n    );\n    addEventTypeOtherFocus(i);\n  }\n\n  const resequenceForms = (removedIdFormField) => {\n    // Given the ID form field from the form we've removed, iterate over remaining forms\n    // to ensure their index sequence in the formset is coalesced.\n    const formIdRegex = /form-([0-9]+)-[A-Za-z_]+/;\n    const removedIndex = parseInt(\n      removedIdFormField.getAttribute(\"name\").match(formIdRegex)[1],\n      10,\n    );\n    if (removedIndex < parseInt(totalFormCountInput.value, 10)) {\n      document.querySelectorAll(\".edit-events-container\").forEach((_container) => {\n        const containerIndex = parseInt(\n          _container\n            .querySelector('input[type=\"hidden\"]')\n            .getAttribute(\"name\")\n            .match(formIdRegex)[1],\n          10,\n        );\n        if (containerIndex > removedIndex) {\n          _container.querySelectorAll(\"input\").forEach((input) => {\n            if (input.name.includes(`-${containerIndex}-`)) {\n              input.setAttribute(\n                \"name\",\n                input\n                  .getAttribute(\"name\")\n                  .replace(`-${containerIndex}-`, `-${containerIndex - 1}-`),\n              );\n              input.setAttribute(\n                \"id\",\n                input\n                  .getAttribute(\"id\")\n                  .replace(`-${containerIndex}-`, `-${containerIndex - 1}-`),\n              );\n            }\n          });\n\n          _container.querySelectorAll(\"label\").forEach((label) => {\n            if (label.getAttribute(\"for\").includes(`-${containerIndex}-`)) {\n              label.setAttribute(\n                \"for\",\n                label\n                  .getAttribute(\"for\")\n                  .replace(`-${containerIndex}-`, `-${containerIndex - 1}-`),\n              );\n            }\n          });\n        }\n      });\n    }\n\n    document\n      .querySelectorAll(\".remove-event\")\n      .forEach((removeButton) =>\n        removeButton.classList.toggle(\"d-none\", totalFormCount <= 1),\n      );\n  };\n\n  // For every form _currently_ loaded, if there's no instance ID, we need to handle\n  // the remove event appropriately, which includes\n  document.querySelectorAll(\".edit-events-container\").forEach((container) => {\n    const idFormField = container.querySelector('input[type=\"hidden\"]');\n    if (idFormField && !idFormField.value) {\n      container.querySelectorAll(\".remove-event a\").forEach((removeAnchor) =>\n        removeAnchor.addEventListener(\"click\", () => {\n          if (deleteEventCallbacks.length >= 1) {\n            deleteEventCallbacks.forEach((cb) => cb());\n          }\n          removeAnchor.closest(\".edit-events-container\").remove();\n          totalFormCount -= 1;\n          totalFormCountInput.value = totalFormCount;\n          resequenceForms(idFormField);\n        }),\n      );\n    }\n\n    attachEventTypeListener(container);\n  });\n\n  document.querySelectorAll(\".add-event-button\").forEach((addEventButton) =>\n    addEventButton.addEventListener(\"click\", () => {\n      totalFormCount += 1;\n      const newForm = props.emptyForm.replace(/__prefix__/g, totalFormCount - 1);\n      const formElements = [...generateElements(newForm)];\n      const eventFormsContainer = document.querySelector(\".edit-events-containers\");\n\n      eventFormsContainer.append(...formElements);\n\n      const eventForm = formElements[0];\n\n      document\n        .querySelectorAll(\".remove-event\")\n        .forEach((removeButton) =>\n          removeButton.classList.toggle(\"d-none\", totalFormCount <= 1),\n        );\n\n      totalFormCountInput.value = totalFormCount;\n\n      const eventExtraDataCallback = initEventExtraData(\n        eventFormsContainer.querySelector(\".edit-events-container:last-of-type\"),\n        props,\n      );\n      if (typeof eventExtraDataCallback !== \"undefined\") {\n        deleteEventCallbacks.push(eventExtraDataCallback);\n      }\n\n      eventForm.querySelectorAll(\".remove-event a\").forEach((removeButton) =>\n        removeButton.addEventListener(\"click\", () => {\n          if (deleteEventCallbacks.length >= 1) {\n            deleteEventCallbacks.forEach((cb) => cb());\n          }\n\n          const container = removeButton.closest(\".edit-events-container\");\n          attachEventTypeListener(container);\n          const idFormField = container.querySelector('input[type=\"hidden\"]');\n\n          if (idFormField && !idFormField.value) {\n            container.remove();\n            totalFormCount -= 1;\n            totalFormCountInput.value = totalFormCount;\n            resequenceForms(idFormField);\n          }\n        }),\n      );\n\n      const elementMetadataId = document.getElementById(\n        `id_form-${totalFormCount - 1}-location_metadata`,\n      );\n      addEventLocationAutocomplete(\n        inputElements[totalFormCount - 1],\n        elementMetadataId,\n        true,\n      );\n      initDateTimePicker({ element: `#id_form-${totalFormCount - 1}-start` });\n      initDateTimePicker({ element: `#id_form-${totalFormCount - 1}-end` });\n      initRSVPLimitBehavior(eventForm);\n      initStreamingOptions(eventForm);\n      attachEventTypeListener(eventForm);\n      addEventTypeOtherFocus(totalFormCount - 1);\n\n      if (bottomSubmitRow) {\n        bottomSubmitRow.classList.remove(\"d-none\");\n      }\n    }),\n  );\n\n  const searchParams = new URLSearchParams(window.location.search);\n  const expandEventRSVPS = searchParams.get(\"expand-rsvp-details\");\n  if (expandEventRSVPS) {\n    const eventContainer = document.querySelector(\n      `.edit-events-container[data-uuid='${expandEventRSVPS}']`,\n    );\n    const expandElement = eventContainer.querySelector(\".show-rsvps\");\n    if (expandElement) {\n      expandRSVPs(expandElement, true);\n    }\n  }\n}\n","import Modal from \"bootstrap/js/dist/modal\";\nimport { sendBrowserAgnosticEvent } from \"../core/utils\";\n\nexport default class StockPhotoModal {\n  constructor(root, onSelected) {\n    this.root = root;\n    this.rootModal = Modal.getOrCreateInstance(root);\n\n    this.selectedStockPhotos = [];\n    this.desiredCount = null;\n\n    this.confirmSelection = this.root.querySelector(\".confirm-selection\");\n    this.cancelSelection = this.root.querySelector(\".cancel-selection\");\n\n    document.body.addEventListener(\"htmx:afterSettle\", (evt) => {\n      if (evt.detail.elt.classList.contains(\"stock-photo-browser\")) {\n        evt.detail.elt.querySelectorAll(\".stock-photo\").forEach((photo) => {\n          photo.addEventListener(\"click\", () => {\n            this.togglePhoto(photo);\n          });\n        });\n\n        this.updateSelected();\n      }\n    });\n\n    this.confirmSelection.addEventListener(\"click\", () => {\n      onSelected(this.selectedStockPhotos);\n      this.rootModal.hide();\n    });\n\n    this.cancelSelection.addEventListener(\"click\", () => {\n      onSelected([]);\n      this.rootModal.hide();\n    });\n  }\n\n  show(alreadySelectedStockPhotos = null, desiredCount = null) {\n    if (desiredCount) {\n      this.desiredCount = alreadySelectedStockPhotos\n        ? alreadySelectedStockPhotos.length + desiredCount\n        : null;\n    } else {\n      this.desiredCount = null;\n    }\n\n    this.selectedStockPhotos = alreadySelectedStockPhotos || [];\n\n    const browserContainer = this.root.querySelector(\".stock-photo-browser\");\n    if (browserContainer) {\n      sendBrowserAgnosticEvent(browserContainer, \"loadStockPhotos\");\n    }\n\n    this.rootModal.show();\n  }\n\n  togglePhoto(photoElement) {\n    const { hashid, thumbnailUrl } = photoElement.dataset;\n\n    const filteredPhotos = this.selectedStockPhotos.filter(\n      (sp) => sp.hashid !== hashid,\n    );\n\n    if (filteredPhotos.length === this.selectedStockPhotos.length) {\n      this.selectedStockPhotos.push({ hashid, thumbnailUrl });\n    } else {\n      this.selectedStockPhotos = filteredPhotos;\n    }\n\n    this.updateSelected();\n  }\n\n  updateSelected() {\n    const selectedPhotosContainer = this.root.querySelector(\".selected-photos\");\n\n    if (selectedPhotosContainer) {\n      // Clear.\n      while (selectedPhotosContainer.firstChild) {\n        selectedPhotosContainer.removeChild(selectedPhotosContainer.lastChild);\n      }\n\n      selectedPhotosContainer.append(\n        ...this.selectedStockPhotos.map((photoData) => {\n          const photo = document.createElement(\"img\");\n          photo.setAttribute(\"src\", photoData.thumbnailUrl);\n\n          const div = document.createElement(\"div\");\n          div.classList.add(\"ratio\", \"ratio-4x3\");\n          div.dataset.hashid = photoData.hashid;\n          div.dataset.thumbnailUrl = photoData.thumbnailUrl;\n          div.append(photo);\n\n          const remove = document.createElement(\"a\");\n          remove.setAttribute(\"href\", \"javascript:;\");\n          remove.innerText = \"-\";\n          div.append(remove);\n\n          const container = document.createElement(\"div\");\n          container.append(div);\n\n          return container;\n        }),\n      );\n\n      const selectedHashids = this.selectedStockPhotos.map(\n        (photoData) => photoData.hashid,\n      );\n\n      this.root.querySelectorAll(\".stock-photo\").forEach((stockPhoto) => {\n        stockPhoto.classList.toggle(\n          \"selected\",\n          selectedHashids.includes(stockPhoto.dataset.hashid),\n        );\n      });\n\n      const browserContainer = this.root.querySelector(\".stock-photo-browser\");\n      browserContainer.classList.remove(\"full-selection\");\n\n      if (this.selectedStockPhotos.length > 0) {\n        this.confirmSelection.innerText = \"Confirm Selection\";\n        this.confirmSelection.removeAttribute(\"disabled\");\n        this.confirmSelection.classList.remove(\"disabled\");\n      } else {\n        this.confirmSelection.innerText = \"Select Photos\";\n        this.confirmSelection.setAttribute(\"disabled\", \"disabled\");\n        this.confirmSelection.classList.add(\"disabled\");\n      }\n    }\n\n    if (this.desiredCount) {\n      const desiredCountLabel = this.root.querySelector(\".desired-count-label\");\n      if (desiredCountLabel) {\n        const remaining = this.desiredCount - this.selectedStockPhotos.length;\n        desiredCountLabel.classList.toggle(\"d-none\", !remaining);\n        if (remaining > 0) {\n          desiredCountLabel.innerText = `You can select ${remaining} more stock photo${remaining === 1 ? \"\" : \"s\"}.`;\n        } else {\n          desiredCountLabel.innerText = `You have selected ${Math.abs(remaining)} too many stock photos.`;\n        }\n      }\n    }\n  }\n}\n","import Cropper from \"cropperjs\";\nimport Modal from \"bootstrap/js/dist/modal\";\nimport { SocialPhotoImporter, SocialSource } from \"./SocialPhotoImporter\";\nimport StockPhotoModal from \"./StockPhotoModal\";\nimport { sendBrowserAgnosticEvent } from \"../core/utils\";\nimport { postMultipartWithProgress } from \"../memorials/utils\";\n\nconst MAX_PHOTOS = 8;\nconst CROPPER_OPTIONS = {\n  aspectRatio: 4 / 3,\n  autoCrop: true,\n  autoCropArea: 0.8,\n  viewMode: 0,\n  cropBoxMovable: false,\n  cropBoxResizable: false,\n  dragMode: \"move\",\n  minCropBoxWidth: 200,\n  minCropBoxHeight: 150,\n  minCanvasHeight: 150,\n  zoomOnWheel: true,\n};\n\n/**\n * Verify that the type provided matches the accept attribute provided.\n *\n * @param {string} type - the type to test\n * @param {string} accept - the accept attribute value to test against\n * @returns {boolean} - true if the type matches the accept\n */\nconst verifyAccept = (type, accept) => {\n  const allowed = accept.split(\",\").map((x) => x.trim());\n  return allowed.includes(type) || allowed.includes(`${type.split(\"/\")[0]}/*`);\n};\n\nexport default class DeceasedPhotoUploader {\n  constructor(props) {\n    this.isOnboarding = props.isOnboarding;\n    this.container = document.getElementById(\"deceased-photo-modal\");\n\n    this.socialImporter = new SocialPhotoImporter(\n      document.getElementById(\"social-photo-importer\"),\n      (photos) => {\n        this.onSocialPhotosSelected(photos);\n      },\n      MAX_PHOTOS,\n    );\n\n    const stockPhotoRoot = document.getElementById(\"stock-photo-importer\");\n    if (stockPhotoRoot) {\n      this.stockPhotoModal = new StockPhotoModal(stockPhotoRoot, (stockPhotoData) => {\n        this.stockPhotosSelected(stockPhotoData);\n      });\n    }\n\n    this.isSelectingPhotos = true;\n    this.isInExternalPhotoSelection = false;\n\n    this.ingestionOptionsModal = document.getElementById(\"photo-ingestion-modal\");\n    this.fileInput = this.container.querySelector('input[type=\"file\"]');\n    this.fileInput.addEventListener(\"change\", () => {\n      this.filesSelected(this.fileInput.files);\n    });\n\n    this.selectPhotosButton = this.ingestionOptionsModal.querySelector(\n      \".ingestion-option.upload\",\n    );\n    this.selectPhotosButton.addEventListener(\"click\", () => {\n      this.fileInput.click();\n    });\n\n    this.importFromFacebookButton = this.ingestionOptionsModal.querySelector(\n      \".ingestion-option.facebook\",\n    );\n    if (this.importFromFacebookButton) {\n      this.importFromFacebookButton.addEventListener(\"click\", () => {\n        this.isInExternalPhotoSelection = true;\n        this.render();\n\n        this.socialImporter.show(SocialSource.FACEBOOK);\n      });\n    }\n\n    this.importFromEverLovedButton = this.ingestionOptionsModal.querySelector(\n      \".ingestion-option.stock-photos\",\n    );\n    if (this.importFromEverLovedButton) {\n      this.importFromEverLovedButton.addEventListener(\"click\", () => {\n        this.isInExternalPhotoSelection = true;\n        this.render();\n        this.stockPhotoModal.show(\n          this.photos\n            .filter((p) => p.hashid)\n            .map((p) => ({ thumbnailUrl: p.url, hashid: p.hashid })),\n          this.collageSize - this.photos.length,\n        );\n      });\n    }\n\n    this.layoutFrame = this.container.querySelector(\".layout-frame\");\n    this.layoutFrame.addEventListener(\"click\", (e) => {\n      // We are clicking a layout-selector element.\n      const layoutSelector = e.target.closest(\".layout-selector\");\n      if (layoutSelector !== null) {\n        this.collageSize = parseInt(layoutSelector.dataset.layoutSize, 10);\n        this.isSelectingLayout = false;\n        this.isSelectingPhotos = this.photos.length === 0;\n\n        this.render();\n      }\n    });\n\n    this.filterFrame = this.container.querySelector(\".filter-frame\");\n    this.filterFinishedButton = this.filterFrame.querySelector(\".filter-finished\");\n    this.filterFinishedButton.addEventListener(\"click\", () => {\n      // Filtering should be done at this point, so we just need to trigger a render\n      // so that it moves to the preview frame.\n      this.isFiltering = false;\n      this.render();\n    });\n\n    this.previewFrame = this.container.querySelector(\".preview-frame\");\n\n    this.existingPhotos = props.existingPhotos || [];\n    this.photos = this.existingPhotos.slice();\n\n    this.cropperData = {};\n\n    this.isShowing = false;\n\n    this.saveButton = this.previewFrame.querySelector(\".save-photos-btn\");\n    this.saveButton.addEventListener(\"click\", () => {\n      if (!this.saveButton.disabled) {\n        this.uploadPhotos();\n      }\n    });\n    this.onPhotosUpdated = props.onPhotosUpdated;\n\n    this.uploadUrl = props.uploadUrl;\n    this.uploadExtraParams = {\n      is_onboarding: props.isOnboarding,\n      fundraising_purpose: props.fundraisingPurpose,\n    };\n\n    this.uploadOverlay = this.container.querySelector(\".upload-overlay\");\n\n    this.nextUrl = props.nextUrl;\n\n    const cancelButton = this.container.querySelector(\".cancel-photo-selection\");\n    cancelButton.addEventListener(\"click\", () => {\n      this.photos = this.existingPhotos;\n      this.cropperData = {};\n      const previewPhotosContainer = this.previewFrame.querySelector(\".preview-photos\");\n\n      while (previewPhotosContainer.hasChildNodes()) {\n        previewPhotosContainer.removeChild(previewPhotosContainer.lastChild);\n      }\n\n      this.hide();\n    });\n\n    this.collageSize = null;\n\n    this.incompleteWarning = this.previewFrame.querySelector(\".incomplete-warning\");\n    this.incompleteWarning.classList.toggle(\"d-none\", this.isOnboarding);\n\n    this.incompleteWarning\n      .querySelector(\".invoke-stock-photo-selector\")\n      .addEventListener(\"click\", () => {\n        this.isSelectingPhotos = true;\n        this.isInExternalPhotoSelection = true;\n        this.render();\n        this.stockPhotoModal.show(\n          this.photos\n            .filter((p) => p.hashid)\n            .map((p) => ({ thumbnailUrl: p.url, hashid: p.hashid })),\n        );\n      });\n\n    this.previewFrame\n      .querySelector(\".select-different-layout\")\n      .addEventListener(\"click\", () => {\n        this.collageSize = null;\n        this.isSelectingLayout = true;\n        this.isSelectingPhotos = false;\n\n        if (this.socialImporter.activeImporter) {\n          this.socialImporter.reset();\n        }\n\n        this.render();\n      });\n\n    this.previewFrame.querySelector(\".upload-photo\").addEventListener(\"click\", () => {\n      this.startSelectPhotos();\n    });\n  }\n\n  /**\n   * Show the uploader.\n   *\n   * @param {boolean} [overrideSelectingPhotos] - if true, then autoprogress the render\n   *     state to be isSelectingPhotos=true\n   */\n  show(overrideSelectingPhotos = false) {\n    this.isShowing = true;\n    this.isInExternalPhotoSelection = false;\n\n    this.isSelectingLayout = this.collageSize === null;\n    this.isSelectingPhotos =\n      (this.photos.length === 0 || overrideSelectingPhotos) && !this.isSelectingLayout;\n\n    if (this.socialImporter.activeImporter) {\n      this.socialImporter.reset();\n    }\n\n    this.render();\n  }\n\n  /**\n   * Hide the uploader.\n   */\n  hide() {\n    this.isShowing = false;\n    this.isSelectingLayout = false;\n    this.isSelectingPhotos = false;\n    this.isInExternalPhotoSelection = false;\n    this.collageSize = null;\n\n    if (this.socialImporter.activeImporter) {\n      this.socialImporter.reset();\n    }\n\n    this.render();\n  }\n\n  /**\n   * Make a render passed based on our state.\n   */\n  render() {\n    const modal = Modal.getOrCreateInstance(this.container);\n    const socialOptionsModal = Modal.getOrCreateInstance(this.ingestionOptionsModal);\n\n    const previewPhotosContainer = this.previewFrame.querySelector(\".preview-photos\");\n    if (previewPhotosContainer) {\n      previewPhotosContainer.dataset.collageSize = this.collageSize;\n\n      if (this.isOnboarding) {\n        previewPhotosContainer.classList.add(\"onboarding\");\n      }\n    }\n\n    this.container.querySelectorAll(\".layout-size\").forEach((span) => {\n      span.innerText = `${this.collageSize}`;\n    });\n\n    if (this.isShowing) {\n      if (this.isSelectingPhotos) {\n        if (this.isInExternalPhotoSelection) {\n          modal.hide();\n          socialOptionsModal.hide();\n        } else {\n          modal.hide();\n          socialOptionsModal.show();\n        }\n      } else {\n        modal.show();\n        socialOptionsModal.hide();\n\n        if (this.isSelectingLayout) {\n          this.filterFrame.classList.add(\"d-none\");\n          this.previewFrame.classList.add(\"d-none\");\n          this.layoutFrame.classList.remove(\"d-none\");\n          this.renderLayoutFrame();\n        } else if (!this.photos.length && !this.existingPhotos.length) {\n          this.filterFrame.classList.add(\"d-none\");\n          this.previewFrame.classList.add(\"d-none\");\n          this.layoutFrame.classList.add(\"d-none\");\n        } else if (this.collageSize !== null && this.photos.length > this.collageSize) {\n          this.filterFrame.classList.remove(\"d-none\");\n          this.previewFrame.classList.add(\"d-none\");\n          this.layoutFrame.classList.add(\"d-none\");\n          this.isFiltering = true;\n          this.renderFilterFrame();\n        } else {\n          this.filterFrame.classList.add(\"d-none\");\n          this.previewFrame.classList.remove(\"d-none\");\n          this.layoutFrame.classList.add(\"d-none\");\n          this.renderPreviewFrame();\n        }\n      }\n    } else {\n      modal.hide();\n      socialOptionsModal.hide();\n      this.isFiltering = false;\n    }\n  }\n\n  /**\n   * Called when stock photos have been selected.\n   *\n   * @param {Array} stockPhotosData - an array of stock photo data objects\n   */\n  stockPhotosSelected(stockPhotosData) {\n    stockPhotosData.forEach((stockPhoto) => {\n      if (this.photos.filter((f) => f.hashid === stockPhoto.hashid).length === 0) {\n        this.photos.push(stockPhoto);\n      }\n    });\n\n    if (this.photos.length) {\n      this.isSelectingPhotos = false;\n    }\n\n    this.render();\n  }\n\n  /**\n   * Called when uploadable files have been selected.\n   *\n   * @param {FileList} files - the FileList from the HTMLFileInputElement.\n   */\n  filesSelected(files) {\n    // Push onto state but don't allow duplicates.\n    Array.from(files).forEach((file) => {\n      if (\n        this.photos.filter(\n          (v) => (v instanceof File || v.isFromSocial) && v.name === file.name,\n        ).length === 0\n      ) {\n        if (verifyAccept(file.type, this.fileInput.getAttribute(\"accept\"))) {\n          this.photos.push(file);\n        } else {\n          alert(`Photo ${file.name} is an invalid file type.`);\n        }\n      } else {\n        alert(\n          \"This photo has already been selected. Please do not attempt to upload the same photo twice.\",\n        );\n      }\n    });\n\n    if (this.photos.length) {\n      this.isSelectingPhotos = false;\n    }\n\n    this.render();\n\n    this.fileInput.value = null;\n  }\n\n  /**\n   * Render the layout-selector frame of the uploader modal.\n   */\n  renderLayoutFrame() {\n    sendBrowserAgnosticEvent(\n      this.layoutFrame.querySelector(\".deceased-photos-layout-editor\"),\n      \"reloadPhotoLayouts\",\n    );\n  }\n\n  /**\n   * Render the filter-too-many-photos frame of the upload modal.\n   */\n  renderFilterFrame() {\n    const tileContainer = this.filterFrame.querySelector(\".photo-tile-container\");\n\n    // Remove all existing children.\n    while (tileContainer.firstChild) {\n      tileContainer.removeChild(tileContainer.firstChild);\n    }\n\n    this.photos.forEach((photo) => {\n      const newTile = document.createElement(\"div\");\n      newTile.classList.add(\"photo-tile\");\n      newTile.dataset.photoName = photo.name || photo.uuid || photo.hashid;\n\n      const newTilePhoto = document.createElement(\"img\");\n      newTilePhoto.classList.add(\"photo\");\n      newTile.appendChild(newTilePhoto);\n\n      if (this.cropperData[photo.name]) {\n        newTilePhoto.style.objectFit = \"\";\n        newTilePhoto.src = this.cropperData[photo.name].croppedCanvas;\n      } else {\n        newTilePhoto.style.objectFit = \"cover\";\n        newTilePhoto.style.objectPosition = \"center center\";\n\n        if (photo instanceof File) {\n          const fileReader = new FileReader();\n          fileReader.onload = () => {\n            newTilePhoto.src = `${fileReader.result}`;\n          };\n          fileReader.readAsDataURL(photo);\n        } else {\n          newTilePhoto.src = photo.url || photo.thumbnailUrl;\n        }\n      }\n\n      const remove = document.createElement(\"a\");\n      remove.classList.add(\"remove-tile-button\");\n      remove.href = \"javascript:;\";\n      remove.innerHTML = \"&times;\";\n      remove.addEventListener(\"click\", (evt) => {\n        this.removePhoto(photo);\n        evt.stopPropagation();\n      });\n      newTile.appendChild(remove);\n\n      tileContainer.appendChild(newTile);\n    });\n\n    const canProgress = this.photos.length <= this.collageSize;\n\n    this.filterFrame.querySelector(\".alert\").classList.toggle(\"d-none\", canProgress);\n    this.filterFinishedButton.disabled = !canProgress;\n    this.filterFinishedButton.classList.toggle(\"disabled\", !canProgress);\n  }\n\n  /**\n   * Render the upload preview frame of the upload modal (which allows for cropping and\n   * rearrangement).\n   */\n  renderPreviewFrame() {\n    const previewPhotosContainer = this.previewFrame.querySelector(\".preview-photos\");\n\n    previewPhotosContainer\n      .querySelectorAll(\".preview-photo.placeholder\")\n      .forEach((placeholder) => {\n        placeholder.remove();\n      });\n\n    this.photos.forEach((photo) => {\n      const photoName = photo.name || photo.uuid || photo.hashid;\n      let photoContainer = previewPhotosContainer.querySelector(\n        `[data-photo-name=\"${photoName}\"]`,\n      );\n      if (photoContainer) {\n        if (this.cropperData[photo.name]) {\n          const photoImg = photoContainer.querySelector(\"img.photo\");\n          photoImg.style.objectFit = \"contain\";\n          photoImg.style.objectPosition = \"center center\";\n          photoImg.src = this.cropperData[photo.name].croppedCanvas;\n        }\n      } else {\n        photoContainer = document.createElement(\"div\");\n        photoContainer.classList.add(\"preview-photo\", \"memorial-collage-grid-item\");\n        photoContainer.dataset.photoName = photoName;\n\n        const primaryBanner = document.createElement(\"span\");\n        primaryBanner.classList.add(\"primary-banner\");\n        primaryBanner.classList.add(\"badge\");\n        primaryBanner.classList.add(\"rounded-pill\");\n        primaryBanner.classList.add(\"text-bg-secondary\");\n        primaryBanner.innerHTML = \"PRIMARY PHOTO\";\n        photoContainer.appendChild(primaryBanner);\n\n        if (photo instanceof File || photo.isFromSocial) {\n          const cropControlContainer = document.createElement(\"div\");\n          cropControlContainer.classList.add(\"photo-controls\", \"crop\");\n          const cropControl = document.createElement(\"a\");\n          cropControl.href = \"javascript:;\";\n          cropControl.classList.add(\n            \"preview-crop\",\n            \"mt-text-color-secondary\",\n            \"mt-border-color-secondary\",\n            \"border\",\n          );\n          cropControl.innerHTML = \"CROP\";\n          cropControl.addEventListener(\"click\", () => {\n            this.cropPhoto(photo);\n          });\n          cropControlContainer.appendChild(cropControl);\n          photoContainer.appendChild(cropControlContainer);\n        }\n\n        const moveControls = document.createElement(\"div\");\n        moveControls.classList.add(\"photo-controls\", \"move\");\n        photoContainer.appendChild(moveControls);\n\n        const remove = document.createElement(\"a\");\n        remove.href = \"javascript:;\";\n        remove.classList.add(\"preview-remove\");\n        remove.innerHTML = \"REMOVE\";\n        remove.addEventListener(\"click\", (evt) => {\n          this.removePhoto(photo);\n          evt.stopPropagation();\n        });\n        moveControls.appendChild(remove);\n\n        const change = document.createElement(\"a\");\n        change.href = \"javascript:;\";\n        change.classList.add(\"preview-change\");\n        change.innerHTML = \"CHANGE\";\n        change.addEventListener(\"click\", (evt) => {\n          this.removePhoto(photo);\n          this.startSelectPhotos();\n          evt.stopPropagation();\n        });\n        moveControls.appendChild(change);\n\n        const moveUp = document.createElement(\"a\");\n        moveUp.href = \"javascript:;\";\n        moveUp.innerHTML = \"&lt;\";\n        moveUp.addEventListener(\"click\", () => {\n          this.movePhoto(photo, false);\n        });\n        moveControls.appendChild(moveUp);\n\n        const moveDown = document.createElement(\"a\");\n        moveDown.href = \"javascript:;\";\n        moveDown.innerHTML = \"&gt;\";\n        moveDown.addEventListener(\"click\", () => {\n          this.movePhoto(photo, true);\n        });\n        moveControls.appendChild(moveDown);\n\n        const photoImg = document.createElement(\"img\");\n        photoImg.classList.add(\"photo\");\n        photoContainer.appendChild(photoImg);\n\n        previewPhotosContainer.appendChild(photoContainer);\n\n        if (this.cropperData[photo.name]) {\n          photoImg.style.objectFit = \"\";\n          photoImg.src = this.cropperData[photo.name].croppedCanvas;\n        } else {\n          photoImg.style.objectFit = \"cover\";\n          photoImg.style.objectPosition = \"center center\";\n\n          if (photo instanceof File) {\n            const fileReader = new FileReader();\n            fileReader.onload = () => {\n              photoImg.src = `${fileReader.result}`;\n            };\n            fileReader.readAsDataURL(photo);\n          } else {\n            photoImg.src = photo.url || photo.thumbnailUrl;\n          }\n        }\n      }\n\n      if (this.isOnboarding) {\n        photoContainer\n          .querySelector(\".preview-remove\")\n          .classList.toggle(\"d-none\", this.photos.length <= 1);\n      }\n    });\n\n    let placeholderCount = this.collageSize - this.photos.length;\n    if (placeholderCount > 0) {\n      if (this.isOnboarding) {\n        placeholderCount = 1;\n      }\n\n      for (let placeholder = 0; placeholder < placeholderCount; placeholder += 1) {\n        const placeholderElement = document.createElement(\"a\");\n        placeholderElement.setAttribute(\"href\", \"javascript:;\");\n        placeholderElement.classList.add(\n          \"preview-photo\",\n          \"placeholder\",\n          \"memorial-collage-grid-item\",\n        );\n        placeholderElement.addEventListener(\"click\", () => {\n          this.startSelectPhotos();\n        });\n\n        const cameraImg = document.createElement(\"img\");\n        cameraImg.setAttribute(\"src\", this.container.dataset.cameraSvg);\n\n        placeholderElement.append(cameraImg, \"Add Photo(s)\");\n\n        previewPhotosContainer.append(placeholderElement);\n      }\n    }\n\n    this.incompleteWarning.classList.toggle(\n      \"d-none\",\n      this.isOnboarding || placeholderCount <= 0,\n    );\n    if (!this.isOnboarding) {\n      this.saveButton.classList.toggle(\"disabled\", placeholderCount !== 0);\n      if (placeholderCount === 0) {\n        this.saveButton.removeAttribute(\"disabled\");\n        this.saveButton.innerText = \"Save Changes\";\n      } else {\n        this.saveButton.setAttribute(\"disabled\", \"disabled\");\n        this.saveButton.innerText = `${placeholderCount} space${placeholderCount === 1 ? \"\" : \"s\"} left`;\n      }\n    }\n  }\n\n  /**\n   * Invoke the photo selector/importer UX (upload/stock/FB/etc)\n   */\n  startSelectPhotos() {\n    this.isSelectingPhotos = true;\n    this.render();\n  }\n\n  /**\n   * Actually do the upload of the photos. We have to use XMLHttpRequest since fetch\n   * does not support progress events/updates for uploads.\n   *\n   * @returns {Promise<void>} - void Promise of the upload in-progress\n   */\n  async uploadPhotos() {\n    const formData = new FormData();\n\n    Object.keys(this.uploadExtraParams).forEach((k) => {\n      formData.set(k, this.uploadExtraParams[k]);\n    });\n\n    this.photos.forEach((photo, idx) => {\n      if (photo instanceof File) {\n        formData.append(\"photos\", photo);\n\n        let photoMetadata = {\n          is_main_photo: idx === 0,\n          idx,\n        };\n\n        if (this.cropperData[photo.name]) {\n          const cropperData = this.cropperData[photo.name].cropData;\n          photoMetadata = {\n            x: cropperData.x,\n            y: cropperData.y,\n            width: cropperData.width,\n            height: cropperData.height,\n            ...photoMetadata,\n          };\n        }\n\n        formData.set(photo.name, JSON.stringify(photoMetadata));\n      } else if (photo.isFromSocial) {\n        const cropperData = this.cropperData[photo.name];\n\n        let photoMetadata = {\n          is_main_photo: idx === 0,\n          social_url: photo.url,\n          idx,\n        };\n\n        if (cropperData) {\n          photoMetadata = {\n            x: cropperData.x,\n            y: cropperData.y,\n            width: cropperData.width,\n            height: cropperData.height,\n            ...photoMetadata,\n          };\n        }\n\n        formData.set(photo.name, JSON.stringify(photoMetadata));\n      } else {\n        formData.set(\n          photo.uuid || photo.hashid,\n          JSON.stringify({\n            is_main_photo: idx === 0,\n            idx,\n          }),\n        );\n      }\n    });\n\n    const { uploadOverlay } = this;\n    const progressBar = this.uploadOverlay.querySelector(\".el-progress > *\");\n    const uploadCount = this.photos.length;\n    const errorAlert = this.previewFrame.querySelector(\".alert-warning\");\n\n    this.previewFrame.classList.add(\"uploading\");\n    uploadOverlay.classList.remove(\"d-none\");\n    errorAlert.classList.add(\"d-none\");\n\n    const onProgressPercentage = (percent) => {\n      progressBar.value = percent / 2;\n\n      // The second half of the progress is estimating the processing time\n      // on the other end. Interval number here is just kind of a magic\n      // number that makes the rest of the bar go at a reasonable speed.\n      if (percent >= 100) {\n        const loadFinish = setInterval(() => {\n          if (uploadOverlay.classList.contains(\"d-none\") || !progressBar) {\n            clearInterval(loadFinish);\n            return;\n          }\n\n          const currentValue = parseInt(progressBar.value, 10);\n          if (currentValue < 100) {\n            progressBar.value = currentValue + 1;\n          } else {\n            clearInterval(loadFinish);\n          }\n        }, uploadCount * 40);\n      }\n    };\n\n    let response;\n\n    try {\n      response = await postMultipartWithProgress(\n        this.uploadUrl,\n        formData,\n        onProgressPercentage,\n      );\n    } catch (error) {\n      window.Rollbar.error(\"Error uploading multi-DeceasedPhotos\", error);\n\n      this.previewFrame.classList.remove(\"uploading\");\n      uploadOverlay.classList.add(\"d-none\");\n      errorAlert.classList.remove(\"d-none\");\n\n      return;\n    }\n\n    this.previewFrame.classList.remove(\"uploading\");\n\n    progressBar.value = 0;\n    uploadOverlay.classList.add(\"d-none\");\n\n    if (this.nextUrl) {\n      window.location.href = this.nextUrl;\n    } else if (this.onPhotosUpdated) {\n      this.existingPhotos = response.data;\n      this.photos = this.existingPhotos.slice();\n      this.cropperData = {};\n\n      const previewPhotosContainer = this.previewFrame.querySelector(\".preview-photos\");\n      while (previewPhotosContainer.hasChildNodes()) {\n        previewPhotosContainer.removeChild(previewPhotosContainer.lastChild);\n      }\n\n      this.isSelectingPhotos = true;\n      this.onPhotosUpdated(response.data);\n    }\n\n    document\n      .querySelectorAll(\".deceased-photos-layout-editor\")\n      .forEach((photoLayoutSelector) => {\n        sendBrowserAgnosticEvent(photoLayoutSelector, \"reloadPhotoLayouts\");\n      });\n\n    this.hide();\n  }\n\n  /**\n   * Move a photo in the layout order.\n   *\n   * @param {object} photo - the photo data dict from this.photos\n   * @param {boolean} [up] - whether to move forward or back in order.\n   */\n  movePhoto(photo, up = true) {\n    const currentIndex = this.photos.indexOf(photo);\n    let newIndex = currentIndex + (up ? 1 : -1);\n    newIndex = Math.max(Math.min(this.photos.length - 1, newIndex), 0);\n\n    if (currentIndex === newIndex) {\n      return;\n    }\n\n    this.photos.splice(newIndex, 0, this.photos.splice(currentIndex, 1)[0]);\n\n    const previewElementContainer = this.previewFrame.querySelector(\".preview-photos\");\n\n    const photoName = photo.name || photo.uuid || photo.hashid;\n    const previewElement = previewElementContainer.querySelector(\n      `[data-photo-name=\"${photoName}\"]`,\n    );\n\n    if (previewElement) {\n      if (up) {\n        previewElementContainer.insertBefore(\n          previewElement,\n          previewElement.nextSibling ? previewElement.nextSibling.nextSibling : null,\n        );\n      } else if (currentIndex > 0) {\n        previewElementContainer.insertBefore(\n          previewElement,\n          previewElement.previousSibling,\n        );\n      }\n    }\n  }\n\n  /**\n   * Remove a photo from the layout.\n   *\n   * @param {object} photo - the photo data dict from this.photos\n   */\n  removePhoto(photo) {\n    this.photos = this.photos.filter((p) => p !== photo);\n\n    const photoName = photo.name || photo.uuid || photo.hashid;\n\n    const previewElement = this.previewFrame.querySelector(\n      `[data-photo-name=\"${photoName}\"]`,\n    );\n    if (previewElement) {\n      previewElement.remove();\n    }\n\n    if (this.photos.length) {\n      if (this.isFiltering) {\n        this.renderFilterFrame();\n      } else {\n        this.renderPreviewFrame();\n      }\n    } else {\n      this.render();\n    }\n  }\n\n  /**\n   * Initialize and show the crop UX for the given photo\n   *\n   * @param {object} photo - the photo data dict from this.photos\n   */\n  cropPhoto(photo) {\n    let cropper;\n\n    const cropperContainer = document.createElement(\"div\");\n    cropperContainer.classList.add(\n      \"cropper-dvh100\",\n      \"position-fixed\",\n      \"top-0\",\n      \"left-0\",\n      \"w-100\",\n      \"h-100\",\n      \"d-flex\",\n      \"justify-content-stretch\",\n      \"align-items-stretch\",\n      \"flex-column\",\n      \"bg-black\",\n    );\n    cropperContainer.style.zIndex = \"9998\"; // Absolute highest z-index, trumps everything, except zoom buttons\n    const cropperImg = document.createElement(\"img\");\n    cropperImg.classList.add(\"flex-shrink-1\");\n    cropperImg.style.objectFit = \"contain\";\n    cropperImg.style.objectPosition = \"center center\";\n    cropperImg.style.flexBasis = \"calc(100% - 74px)\";\n    cropperImg.style.maxHeight = \"calc(100% - 74px)\";\n\n    const zoomControls = document.createElement(\"div\");\n    zoomControls.classList.add(\n      \"zoom-controls\",\n      \"position-absolute\",\n      \"top-0\",\n      \"right-0\",\n      \"d-flex\",\n      \"m-3\",\n    );\n    zoomControls.style.zIndex = \"9999\";\n\n    const zoomInBtn = document.createElement(\"a\");\n    zoomInBtn.setAttribute(\"href\", \"javascript:;\");\n    zoomInBtn.classList.add(\n      \"zoom-control\",\n      \"zoom-in\",\n      \"rounded-circle\",\n      \"fw-bold\",\n      \"text-black\",\n      \"bg-white\",\n      \"d-flex\",\n      \"align-items-center\",\n      \"justify-content-center\",\n      \"m-1\",\n    );\n    zoomInBtn.style.width = \"40px\";\n    zoomInBtn.style.height = \"40px\";\n    zoomInBtn.style.fontSize = \"36px\";\n    zoomInBtn.style.lineHeight = \"36px\";\n    zoomInBtn.innerText = \"\\uFF0B\";\n    zoomInBtn.addEventListener(\"click\", () => {\n      if (cropper) {\n        cropper.zoom(0.1);\n      }\n    });\n\n    const zoomOutBtn = document.createElement(\"a\");\n    zoomOutBtn.setAttribute(\"href\", \"javascript:;\");\n    zoomOutBtn.classList.add(\n      \"zoom-control\",\n      \"zoom-in\",\n      \"rounded-circle\",\n      \"fw-bold\",\n      \"text-black\",\n      \"bg-white\",\n      \"d-flex\",\n      \"align-items-center\",\n      \"justify-content-center\",\n      \"m-1\",\n    );\n    zoomOutBtn.style.width = \"40px\";\n    zoomOutBtn.style.height = \"40px\";\n    zoomOutBtn.style.fontSize = \"36px\";\n    zoomOutBtn.style.lineHeight = \"36px\";\n    zoomOutBtn.innerText = \"\\uFF0D\";\n    zoomOutBtn.addEventListener(\"click\", () => {\n      if (cropper) {\n        cropper.zoom(-0.1);\n      }\n    });\n\n    zoomControls.append(zoomOutBtn, zoomInBtn);\n\n    cropperContainer.appendChild(zoomControls);\n\n    // Restore prior crop if applicable.\n    let canvasData;\n    if (this.cropperData[photo.name]) {\n      canvasData = this.cropperData[photo.name].canvasData;\n    }\n\n    const cropOptions = {\n      ...CROPPER_OPTIONS,\n      ready() {\n        if (canvasData) {\n          this.cropper.setCanvasData(canvasData);\n        } else {\n          // Get image dimensions and crop-box dimensions, and find the direction we need\n          // to zoom in to \"fill\" the crop box.\n          const imageData = cropper.getImageData();\n          const cropData = cropper.getCropBoxData();\n\n          cropper.zoom(\n            Math.max(\n              cropData.width / imageData.width,\n              cropData.height / imageData.height,\n            ) - 1.0,\n          );\n        }\n      },\n    };\n\n    if (photo instanceof File) {\n      const fileReader = new FileReader();\n      fileReader.onload = () => {\n        cropperImg.src = `${fileReader.result}`;\n        cropper = new Cropper(cropperImg, cropOptions);\n      };\n\n      fileReader.readAsDataURL(photo);\n    } else {\n      cropperImg.src = photo.url || photo.thumbnailUrl;\n      cropper = new Cropper(cropperImg, cropOptions);\n    }\n\n    cropperContainer.appendChild(cropperImg);\n\n    const buttonBar = document.createElement(\"div\");\n    buttonBar.classList.add(\n      \"w-100\",\n      \"flex-grow-1\",\n      \"d-flex\",\n      \"justify-content-between\",\n      \"bg-white\",\n      \"p-2\",\n    );\n\n    const cancelButton = document.createElement(\"a\");\n    cancelButton.href = \"javascript:;\";\n    cancelButton.addEventListener(\"click\", () => {\n      cropperContainer.remove();\n    });\n    cancelButton.classList.add(\"btn\", \"btn-lg\", \"btn-outline-danger\");\n    cancelButton.style.minWidth = \"0\";\n    cancelButton.innerText = \"Cancel\";\n    buttonBar.appendChild(cancelButton);\n\n    const saveButton = document.createElement(\"a\");\n    saveButton.href = \"javascript:;\";\n    saveButton.addEventListener(\"click\", () => {\n      this.cropperData[photo.name] = {\n        canvasData: cropper.getCanvasData(),\n        cropData: cropper.getData(),\n        croppedCanvas: cropper.getCroppedCanvas().toDataURL(\"image/jpeg\"),\n      };\n      cropperContainer.remove();\n      this.render();\n    });\n\n    saveButton.classList.add(\"btn\", \"btn-lg\", \"btn-primary\");\n    saveButton.style.minWidth = \"0\";\n    saveButton.innerText = \"Crop\";\n\n    buttonBar.appendChild(saveButton);\n    cropperContainer.appendChild(buttonBar);\n\n    document.body.appendChild(cropperContainer);\n  }\n\n  /**\n   * Called when social import photos are received.\n   *\n   * @param {Array} photos - an array of photo data from the social provider.\n   */\n  onSocialPhotosSelected(photos) {\n    if (photos.length) {\n      this.isSelectingPhotos = false;\n      this.isInExternalPhotoSelection = false;\n      this.photos.push(\n        ...photos.map((url) => ({ url, name: url, isFromSocial: true })),\n      );\n    } else {\n      this.isSelectingPhotos = true;\n      this.isInExternalPhotoSelection = true;\n    }\n\n    this.render();\n  }\n}\n","import TomSelect from \"tom-select/dist/js/tom-select.base\";\nimport TomSelect_virtual_scroll from \"tom-select/dist/js/plugins/virtual_scroll\";\n\nimport initGoogleAutocomplete from \"./GoogleAutocomplete\";\nimport { createAutocompleteOption } from \"../places/utils\";\nimport requests, { ResponseError } from \"../core/requests\";\n\nTomSelect.define(\"virtual_scroll\", TomSelect_virtual_scroll);\n\n/**\n * Format a Deceased search result for display in the dropdown.\n *\n * @param {object} deceased - an object representing a deceased in search results.\n * @returns {HTMLDivElement} - the rendered autocomplete option\n */\nconst formatDeceased = (deceased) => {\n  if (deceased.dateOfBirth) {\n    return createAutocompleteOption(\n      deceased.text,\n      `${deceased.dateOfBirth} - ${deceased.dateOfDeath}`,\n    );\n  }\n\n  return createAutocompleteOption(deceased.text);\n};\n\n/**\n * Toggle display of the manual family/predeceased person entry.\n *\n * @param {object} props - the page props\n * @param {boolean} showManualEntry - if true, show the manual entry form (if false,\n *     hide it)\n */\nconst toggleManualEntry = (props, showManualEntry) => {\n  let { deceasedFirstName: firstName, deceasedLastName: lastName } = props;\n  const fullNameInput = document.querySelector(`#${props.deceasedNameFieldId}`);\n  const firstNameInput = document.querySelector(`#${props.deceasedFirstNameFieldId}`);\n  const lastNameInput = document.querySelector(`#${props.deceasedLastNameFieldId}`);\n\n  if (showManualEntry) {\n    document\n      .querySelector(`.${props.manualEntryContainerClass}`)\n      .classList.remove(\"d-none\");\n    document\n      .querySelector(`.${props.memorialSearchContainerClass}`)\n      .classList.add(\"d-none\");\n\n    if (!firstName && !lastName) {\n      const fullName = fullNameInput.value;\n      const splitNames = fullName.split(\" \");\n      [firstName] = splitNames;\n      lastName = splitNames.slice(1).join(\" \");\n    }\n\n    fullNameInput.value = \"\";\n    firstNameInput.value = firstName;\n    lastNameInput.value = lastName;\n  } else {\n    document\n      .querySelector(`.${props.manualEntryContainerClass}`)\n      .classList.add(\"d-none\");\n    document\n      .querySelector(`.${props.memorialSearchContainerClass}`)\n      .classList.remove(\"d-none\");\n\n    firstNameInput.value = \"\";\n    lastNameInput.value = \"\";\n  }\n};\n\n/**\n * Initialize the autocomplete search for deceaseds/memorials.\n *\n * @param {object} props - the page props\n * @returns {HTMLElement|null} - the input element, if successfully configured\n */\nconst initDeceasedAutocomplete = (props) => {\n  const deceasedIdentifierInput = document.getElementById(props.deceasedNameFieldId);\n  if (!deceasedIdentifierInput) {\n    return null;\n  }\n\n  /**\n   * Compose the URL combining the search query and the desired page number.\n   *\n   * @param {string} query - a search query\n   * @param {number} page - a page number\n   * @returns {string} - the generated URL.\n   */\n  const buildUrl = (query, page) => {\n    const paramsData = { search: query };\n\n    paramsData.page = page;\n\n    const params = new URLSearchParams(paramsData);\n\n    return `${props.deceasedSearchUrl}?${params.toString()}`;\n  };\n\n  const tomSelectConfig = {\n    plugins: [\"virtual_scroll\"],\n    valueField: \"id\",\n    sortField: [{ field: \"$order\" }, { field: \"$score\" }],\n    searchField: [],\n    firstUrl(query) {\n      return buildUrl(query, 1);\n    },\n    async load(query, callback) {\n      try {\n        const response = await requests.get(this.getUrl(query));\n\n        if (!response.ok) {\n          throw new ResponseError(response);\n        }\n\n        const data = await response.json();\n\n        if (data.pagination.next) {\n          const nextUrl = buildUrl(query, data.pagination.next);\n          this.setNextUrl(query, nextUrl);\n        }\n\n        callback(data.results);\n      } catch (error) {\n        if (!(error.response && error.response.status === 429)) {\n          window.Rollbar.error(\"TomSelect deceased search error\", error);\n        }\n\n        callback();\n      }\n    },\n    loadThrottle: 500,\n    placeholder: props.deceasedPlaceholder,\n    render: {\n      option: (item) => formatDeceased(item),\n      not_loading: (data) => {\n        if (data.input.length === 0) {\n          return null;\n        }\n\n        return '<div class=\"no-results\">Please enter the name.</div>';\n      },\n    },\n    shouldLoad: (query) => query.length >= 3,\n    create: (input) => ({ id: input.trim(), text: input.trim(), created: true }),\n    maxItems: 1,\n  };\n\n  const deceasedSearchAutocomplete = new TomSelect(\n    deceasedIdentifierInput,\n    tomSelectConfig,\n  );\n  deceasedSearchAutocomplete.on(\"change\", (newValue) => {\n    if (newValue) {\n      const newOption = deceasedSearchAutocomplete.options[newValue];\n      const deceasedMemorialSlugInput = document.getElementById(\n        props.deceasedMemorialSlugFieldId,\n      );\n\n      if (newOption.created) {\n        toggleManualEntry(props, true);\n        deceasedMemorialSlugInput.value = \"\";\n      } else {\n        deceasedMemorialSlugInput.value = newOption.id;\n      }\n    }\n  });\n\n  // Set the value, creating a new option if necessary\n  if (props.initialAutocompleteData && props.initialAutocompleteData.id) {\n    const availableOption =\n      deceasedSearchAutocomplete.options[props.initialAutocompleteData.id];\n    if (!availableOption) {\n      deceasedSearchAutocomplete.addOption(props.initialAutocompleteData);\n    }\n\n    deceasedSearchAutocomplete.setValue(props.initialAutocompleteData.id);\n  }\n\n  if (props.deceasedManualEntryErrors) {\n    toggleManualEntry(props, true);\n  }\n\n  const followerForm = document.querySelector(`.${props.deceasedFormClass}`);\n  followerForm.querySelector(\".close-button\").addEventListener(\"click\", () => {\n    toggleManualEntry(props, false);\n    deceasedSearchAutocomplete.clear();\n  });\n\n  const locationContainer = document.querySelector(\n    `.${props.deceasedLocationContainerClass}`,\n  );\n  if (locationContainer) {\n    initGoogleAutocomplete({\n      element: locationContainer.querySelector(\"input\"),\n      options: {\n        types: [\"(cities)\"],\n      },\n    });\n  }\n\n  return deceasedIdentifierInput;\n};\n\n/**\n * Set up behavior to control submit button toggling based on the raw-data form entry\n * states.\n *\n * @param {object} props - the page props\n */\nconst setupFormListeners = (props) => {\n  const nameField = document.querySelector(`#${props.deceasedNameFieldId}`);\n  const firstNameField = document.querySelector(`#${props.deceasedFirstNameFieldId}`);\n  const lastNameField = document.querySelector(`#${props.deceasedLastNameFieldId}`);\n  const relationshipSelect = document.querySelector(\n    `#${props.deceasedRelationshipTypeFieldId}`,\n  );\n\n  function toggleButton() {\n    const submitButton = document.querySelector(`.${props.deceasedSubmitButton}`);\n    if (\n      relationshipSelect.value &&\n      (nameField.value || (firstNameField.value && lastNameField.value))\n    ) {\n      submitButton.disabled = false;\n    } else {\n      submitButton.disabled = true;\n    }\n  }\n\n  if (nameField.tomselect) {\n    nameField.tomselect.on(\"change\", () => toggleButton());\n  }\n\n  relationshipSelect.addEventListener(\"change\", () => {\n    toggleButton();\n  });\n};\n\n/**\n * This function sets up autocomplete and form listeners for the search by name\n * deceased forms. The inner function with a similar name is concerned only with the\n * autocomplete part of this component.\n *\n * @param {object} props - the page props\n */\nexport default function initDeceasedSearchAutocomplete(props) {\n  initDeceasedAutocomplete(props);\n  setupFormListeners(props);\n}\n","import Cleave from \"cleave.js\";\nimport Collapse from \"bootstrap/js/dist/collapse\";\n\nimport initUGCTemplates from \"./UGCTemplates\";\nimport { initPopovers } from \"../core/utils\";\n\nexport default function initFundraiserForm(props, onCleaveInit = null) {\n  // Initialize Cleave and currency selection UX\n  let cleave;\n\n  props.personalFundraiserForms.forEach((personalFundraiserForm) => {\n    let fundraisingGoalContainer = document.querySelector(\n      `#${personalFundraiserForm.fields.fundraisingGoal}`,\n    );\n    if (fundraisingGoalContainer) {\n      fundraisingGoalContainer = fundraisingGoalContainer.closest(\n        \".fundraising-goal-container\",\n      );\n    }\n    const fundraisingGoalDisabled = document.querySelector(\n      `#${personalFundraiserForm.fields.fundraisingGoalDisabled}`,\n    );\n\n    if (fundraisingGoalContainer && fundraisingGoalDisabled) {\n      const goalAmountContainer = fundraisingGoalContainer.querySelector(\n        \".goal-amount-container\",\n      );\n      const currencyWithoutGoalContainer = fundraisingGoalContainer.querySelector(\n        \".currency-no-goal-container\",\n      );\n      const goalContainer = fundraisingGoalContainer.querySelector(\".goal-container\");\n      const goalAmountCollapse = Collapse.getOrCreateInstance(goalAmountContainer, {\n        toggle: false,\n      });\n\n      let currencyWithoutGoalCollapse;\n      if (currencyWithoutGoalContainer) {\n        currencyWithoutGoalCollapse = Collapse.getOrCreateInstance(\n          currencyWithoutGoalContainer,\n          { toggle: false },\n        );\n      }\n\n      fundraisingGoalDisabled.addEventListener(\"change\", () => {\n        // swap goal container with goalless container\n        goalAmountCollapse.toggle();\n        if (currencyWithoutGoalContainer) {\n          currencyWithoutGoalCollapse.toggle();\n        }\n\n        if (fundraisingGoalDisabled.checked) {\n          goalContainer.parentElement.querySelector(\"input\").value = \"\";\n        }\n      });\n    }\n\n    const fundraisingGoalInput = document.getElementById(\n      personalFundraiserForm.fields.fundraisingGoal,\n    );\n    if (fundraisingGoalInput) {\n      cleave = new Cleave(fundraisingGoalInput, {\n        numeral: true,\n        numeralPositiveOnly: true,\n      });\n\n      if (onCleaveInit) {\n        onCleaveInit(cleave);\n      }\n\n      fundraisingGoalInput.closest(\"form\").addEventListener(\"submit\", () => {\n        fundraisingGoalInput.value = cleave.getRawValue();\n      });\n    }\n\n    const currencySelect = document.getElementById(\n      personalFundraiserForm.fields.currencySelect,\n    );\n    const currencyNote = document.querySelector(\".intl-currency-warning\");\n\n    if (currencySelect && currencyNote) {\n      let previousCurrency = currencySelect.selectedOptions[0].value;\n      currencySelect.addEventListener(\"change\", () => {\n        const selectedCurrency = currencySelect.selectedOptions[0].value;\n        currencyNote.classList.toggle(\"d-none\", selectedCurrency === \"usd\");\n\n        if (props.exchangeRates && previousCurrency !== selectedCurrency) {\n          const currentValue = parseFloat(cleave.getRawValue()).toFixed(2);\n          cleave.setRawValue(\n            Math.round(\n              currentValue * props.exchangeRates[previousCurrency][selectedCurrency],\n            ),\n          );\n          previousCurrency = selectedCurrency;\n        }\n      });\n    }\n  });\n\n  // Initialize cause story template UX\n  const causeStoryField = document.querySelector(\n    `#${props.causeStoryForm.fields.causeStory}`,\n  );\n  const causeStoryTemplatesContainer = document.querySelector(\n    \".cause-story-templates-container\",\n  );\n\n  initUGCTemplates(\n    causeStoryTemplatesContainer,\n    causeStoryField,\n    props.causeStoryTemplates,\n    () => props.shouldShowCauseStoryTemplates === true,\n    false,\n    null,\n    false,\n  );\n\n  // NOTE: The naming here is a misdirection. This is used for paste event detection.\n  const previousCauseStoryField = document.querySelector(\n    `#${props.causeStoryForm.fields.previousCauseStory}`,\n  );\n  if (previousCauseStoryField) {\n    causeStoryField.addEventListener(\"paste\", (event) => {\n      previousCauseStoryField.value = (\n        event.clipboardData || window.clipboardData\n      ).getData(\"text\");\n    });\n  }\n\n  props.charityFundraiserForms.forEach((charityFundraiserForm) => {\n    const charityvestDesignationSelector = document.querySelector(\n      `#${charityFundraiserForm.fields.charityvestDesignation}`,\n    );\n    if (charityvestDesignationSelector) {\n      const parentCard = charityvestDesignationSelector.closest(\".body-card\");\n      const otherContainer = parentCard.querySelector(\".charityvest-designation-other\");\n\n      charityvestDesignationSelector.addEventListener(\"change\", () => {\n        otherContainer.classList.toggle(\n          \"d-none\",\n          !(charityvestDesignationSelector.value === \"other_purpose\"),\n        );\n      });\n    }\n  });\n\n  const fundraisingManagerSelect = document.getElementById(\n    \"change-fundraising-manager\",\n  );\n  if (fundraisingManagerSelect) {\n    fundraisingManagerSelect.addEventListener(\"change\", () => {\n      const selected = fundraisingManagerSelect.selectedOptions[0];\n      if (selected && !selected.dataset.isOriginal) {\n        fundraisingManagerSelect.setAttribute(\"name\", \"_change_fundraising_manager\");\n        const form = fundraisingManagerSelect.closest(\"form\");\n        form.dataset.forceSubmit = \"true\";\n        form.submit();\n      }\n    });\n  }\n\n  initPopovers();\n}\n","import Modal from \"bootstrap/js/dist/modal\";\nimport TomSelect from \"tom-select/dist/js/tom-select.base\";\nimport TomSelect_virtual_scroll from \"tom-select/dist/js/plugins/virtual_scroll\";\n\nimport requests, { ResponseError } from \"../core/requests\";\n\nTomSelect.define(\"virtual_scroll\", TomSelect_virtual_scroll);\n\n/**\n * Initialize the feature-search autocomplete component.\n *\n * @param {object} props - the page props\n * @returns {HTMLElement|null} - the input element to which the autocomplete search is\n *     attached.\n */\nexport default function initMemorialFeatureAutocomplete(props) {\n  const modalElement = document.querySelector(\"#memorialFeatureSearchModal\");\n\n  const searchPhraseInput = document.getElementById(props.searchPhraseInputId);\n  if (!searchPhraseInput) {\n    return null;\n  }\n\n  /**\n   * Compose the URL combining the search query and the desired page number.\n   *\n   * @param {string} query - a search query\n   * @param {number} page - a page number\n   * @returns {string} - the generated URL.\n   */\n  const buildUrl = (query, page) => {\n    const paramsData = { search: query };\n\n    paramsData.page = page;\n\n    const params = new URLSearchParams(paramsData);\n\n    if (props.memorialFeatureSearchUrl.includes(\"?\")) {\n      return `${props.memorialFeatureSearchUrl}&${params.toString()}`;\n    }\n\n    return `${props.memorialFeatureSearchUrl}?${params.toString()}`;\n  };\n\n  const tomSelectConfig = {\n    sortField: [{ field: \"$order\" }, { field: \"$score\" }],\n    searchField: [],\n    firstUrl(query) {\n      return buildUrl(query, 1);\n    },\n    async load(query, callback) {\n      try {\n        const response = await requests.get(this.getUrl(query));\n\n        if (!response.ok) {\n          throw new ResponseError(response);\n        }\n\n        const data = await response.json();\n\n        if (data.pagination.next) {\n          const nextUrl = buildUrl(query, data.pagination.next);\n          this.setNextUrl(query, nextUrl);\n        }\n\n        callback(data.results);\n      } catch (error) {\n        if (!(error.response && error.response.status === 429)) {\n          window.Rollbar.error(\"TomSelect memorial feature search error\", error);\n        }\n\n        callback();\n      }\n    },\n    loadThrottle: 500,\n    placeholder: 'Try \"Events\"',\n    plugins: [\"virtual_scroll\"],\n    valueField: \"id\",\n  };\n\n  const featureAutocomplete = new TomSelect(searchPhraseInput, tomSelectConfig);\n\n  featureAutocomplete.on(\"change\", (newValue) => {\n    const selectedOption = featureAutocomplete.options[newValue];\n    Modal.getOrCreateInstance(modalElement).hide();\n    window.location.href = selectedOption.url;\n  });\n\n  modalElement.addEventListener(\"shown.bs.modal\", () => {\n    featureAutocomplete.open();\n  });\n\n  return searchPhraseInput;\n}\n","import TomSelect from \"tom-select/dist/js/tom-select.base\";\nimport TomSelect_remove_button from \"tom-select/dist/js/plugins/remove_button\";\n\nTomSelect.define(\"remove_button\", TomSelect_remove_button);\n\n/**\n * Initialize the organ donation search form.\n *\n * @param {object} organDonationSearchProps - the props for the organ donation\n *     tomselect search widget.\n * @returns {TomSelect} - the TomSelect instance created on the form input.\n */\nexport default function initOrganDonationForm(organDonationSearchProps) {\n  const { checkboxId, initialAutocompleteData, inputId } = organDonationSearchProps;\n  const hasDonatedOrgans = document.querySelector(`#${checkboxId}`);\n  const organChoicesInput = document.querySelector(`#${inputId}`);\n  const organDonationDetailsContainer = organChoicesInput.closest(\n    \".donated-organs-details-container\",\n  );\n\n  const tomSelectConfig = {\n    hidePlaceholder: true,\n    sortField: [{ field: \"$order\" }, { field: \"$score\" }],\n    items: initialAutocompleteData.choices\n      .filter((choice) => choice.selected)\n      .map((choice) => choice.id),\n    options: initialAutocompleteData.choices,\n    placeholder: \"Ex. Heart\",\n    plugins: {\n      remove_button: {\n        title: \"Remove this item\",\n      },\n    },\n    valueField: \"id\",\n  };\n\n  const tomSelect = new TomSelect(organChoicesInput, tomSelectConfig);\n\n  function toggleShowOrganDonationDetails() {\n    if (hasDonatedOrgans.checked) {\n      organDonationDetailsContainer.classList.remove(\"d-none\");\n    } else {\n      organDonationDetailsContainer.classList.add(\"d-none\");\n    }\n  }\n\n  if (hasDonatedOrgans && organDonationDetailsContainer) {\n    hasDonatedOrgans.addEventListener(\"change\", () => {\n      toggleShowOrganDonationDetails();\n    });\n  }\n\n  // determine if donated organs search box should be shown on initial load\n  toggleShowOrganDonationDetails();\n\n  return tomSelect;\n}\n","import Modal from \"bootstrap/js/dist/modal\";\n\nimport requests from \"../core/requests\";\n\nexport default function initSubscriberNotificationsModal(props) {\n  const notificationsModalElement = document.querySelector(\n    \".memorial-notifications-modal\",\n  );\n  const notificationsModal = Modal.getOrCreateInstance(notificationsModalElement);\n  const notifyBtn = notificationsModalElement.querySelector(\".btn-secondary\");\n\n  notificationsModal.show();\n  notifyBtn.addEventListener(\"click\", async () => {\n    notificationsModal.hide();\n\n    try {\n      const response = await requests.post(props.sendNotificationsEndpoint);\n\n      if (!response.ok) {\n        throw new Error();\n      }\n    } catch {\n      window.Rollbar.error(\"Error sending memorial notifications to subscribers.\");\n    }\n  });\n}\n","import initMemorialSearchByUrl from \"../../components/MemorialSearch\";\nimport initGoogleAutocomplete from \"../../components/GoogleAutocomplete\";\n\nexport default function initRelationshipForms(props) {\n  const addPredeceasedLovedOneButton = document.querySelector(\n    \".add-predeceased-button\",\n  );\n  const addPredeceasedLovedOneForm = document.querySelector(\".add-predeceased-form\");\n  const addFollowingLovedOneButton = document.querySelector(\n    \".add-following-in-death-button\",\n  );\n  const addFollowingLovedOneForm = document.querySelector(\n    \".add-following-in-death-form\",\n  );\n  const addSurvivingLovedOneButton = document.querySelector(\".add-survivor-button\");\n  const addSurvivingLovedOneForm = document.querySelector(\".add-survivor-form\");\n\n  if (addPredeceasedLovedOneButton && addPredeceasedLovedOneForm) {\n    addPredeceasedLovedOneButton.addEventListener(\"click\", () => {\n      addPredeceasedLovedOneButton.classList.add(\"d-none\");\n      addPredeceasedLovedOneForm.classList.remove(\"d-none\");\n\n      if (addFollowingLovedOneForm) {\n        addFollowingLovedOneForm.classList.add(\"d-none\");\n      }\n\n      if (addSurvivingLovedOneForm) {\n        addSurvivingLovedOneForm.classList.add(\"d-none\");\n      }\n\n      addPredeceasedLovedOneForm.querySelectorAll(\"input,select\").forEach((field) => {\n        field.disabled = false;\n      });\n\n      if (addFollowingLovedOneForm) {\n        addFollowingLovedOneForm.querySelectorAll(\"input,select\").forEach((field) => {\n          field.disabled = \"disabled\";\n        });\n      }\n\n      if (addSurvivingLovedOneForm) {\n        addSurvivingLovedOneForm.querySelectorAll(\"input,select\").forEach((field) => {\n          field.disabled = \"disabled\";\n        });\n      }\n    });\n\n    addPredeceasedLovedOneForm\n      .querySelector(\".close-button\")\n      .addEventListener(\"click\", () => {\n        addPredeceasedLovedOneButton.classList.remove(\"d-none\");\n        addPredeceasedLovedOneForm.classList.add(\"d-none\");\n        addPredeceasedLovedOneForm.querySelectorAll(\"input,select\").forEach((field) => {\n          field.disabled = \"disabled\";\n        });\n      });\n\n    const predeceasedLocationContainer = document.querySelector(\n      \".predeceased-location-container\",\n    );\n    if (predeceasedLocationContainer) {\n      initGoogleAutocomplete({\n        element: predeceasedLocationContainer.querySelector(\"input\"),\n        options: {\n          types: [\"(cities)\"],\n        },\n      });\n    }\n  }\n\n  if (addFollowingLovedOneButton && addFollowingLovedOneForm) {\n    addFollowingLovedOneButton.addEventListener(\"click\", () => {\n      addFollowingLovedOneButton.classList.add(\"d-none\");\n      addFollowingLovedOneForm.classList.remove(\"d-none\");\n\n      if (addPredeceasedLovedOneForm) {\n        addPredeceasedLovedOneForm.classList.add(\"d-none\");\n      }\n\n      if (addSurvivingLovedOneForm) {\n        addSurvivingLovedOneForm.classList.add(\"d-none\");\n      }\n\n      addFollowingLovedOneForm.querySelectorAll(\"input,select\").forEach((field) => {\n        field.disabled = false;\n      });\n\n      if (addPredeceasedLovedOneForm) {\n        addPredeceasedLovedOneForm.querySelectorAll(\"input,select\").forEach((field) => {\n          field.disabled = \"disabled\";\n        });\n      }\n\n      if (addSurvivingLovedOneForm) {\n        addSurvivingLovedOneForm.querySelectorAll(\"input,select\").forEach((field) => {\n          field.disabled = \"disabled\";\n        });\n      }\n    });\n\n    addFollowingLovedOneForm\n      .querySelector(\".close-button\")\n      .addEventListener(\"click\", () => {\n        addFollowingLovedOneButton.classList.remove(\"d-none\");\n        addFollowingLovedOneForm.classList.add(\"d-none\");\n        addFollowingLovedOneForm.querySelectorAll(\"input,select\").forEach((field) => {\n          field.disabled = \"disabled\";\n        });\n      });\n  }\n\n  if (addSurvivingLovedOneButton && addSurvivingLovedOneForm) {\n    addSurvivingLovedOneButton.addEventListener(\"click\", () => {\n      addSurvivingLovedOneButton.classList.add(\"d-none\");\n      addSurvivingLovedOneForm.classList.remove(\"d-none\");\n\n      if (addFollowingLovedOneForm) {\n        addFollowingLovedOneForm.classList.add(\"d-none\");\n      }\n\n      if (addPredeceasedLovedOneForm) {\n        addPredeceasedLovedOneForm.classList.add(\"d-none\");\n      }\n\n      addSurvivingLovedOneForm.querySelectorAll(\"input,select\").forEach((field) => {\n        field.disabled = false;\n      });\n\n      if (addFollowingLovedOneForm) {\n        addFollowingLovedOneForm.querySelectorAll(\"input,select\").forEach((field) => {\n          field.disabled = \"disabled\";\n        });\n      }\n\n      if (addPredeceasedLovedOneForm) {\n        addPredeceasedLovedOneForm.querySelectorAll(\"input,select\").forEach((field) => {\n          field.disabled = \"disabled\";\n        });\n      }\n    });\n\n    addSurvivingLovedOneForm\n      .querySelector(\".close-button\")\n      .addEventListener(\"click\", () => {\n        addSurvivingLovedOneButton.classList.remove(\"d-none\");\n        addSurvivingLovedOneForm.classList.add(\"d-none\");\n        addSurvivingLovedOneForm.querySelectorAll(\"input,select\").forEach((field) => {\n          field.disabled = \"disabled\";\n        });\n      });\n  }\n\n  const survivorRelationshipTypeSelect = document.getElementById(\n    props.survivorRelationshipTypeFieldId,\n  );\n  const survivorRelationshipTypeStr = document.querySelector(\n    \".survivor-relationship-other\",\n  );\n\n  if (survivorRelationshipTypeSelect && survivorRelationshipTypeStr) {\n    survivorRelationshipTypeSelect.addEventListener(\"change\", (evt) => {\n      const index = evt.target.selectedIndex;\n      const selected = evt.target.options[index];\n      if (selected.value === \"other\") {\n        survivorRelationshipTypeStr.classList.remove(\"d-none\");\n      } else {\n        survivorRelationshipTypeStr.querySelector(\"input\").value = \"\";\n        survivorRelationshipTypeStr.classList.add(\"d-none\");\n      }\n    });\n  }\n\n  const inviteManager = document.querySelector(\n    '.survivor-invite-manager input[type=\"checkbox\"]',\n  );\n  if (inviteManager) {\n    inviteManager.addEventListener(\"change\", () => {\n      const disclaimer = document.querySelector(\".survivor-invite-manager-disclaimer\");\n      disclaimer.classList.toggle(\"d-none\", !inviteManager.checked);\n      const optionalSpan = document.querySelector(\".survivor-email-optional\");\n      optionalSpan.classList.toggle(\"d-none\", inviteManager.checked);\n    });\n  }\n\n  const predeceasedRelationshipTypeSelect = document.getElementById(\n    props.predeceasedRelationshipTypeFieldId,\n  );\n  const predeceasedRelationshipTypeStr = document.querySelector(\n    \".predeceased-relationship-other\",\n  );\n\n  if (predeceasedRelationshipTypeSelect && predeceasedRelationshipTypeStr) {\n    predeceasedRelationshipTypeSelect.addEventListener(\"change\", (evt) => {\n      const index = evt.target.selectedIndex;\n      const selected = evt.target.options[index];\n      if (selected.value === \"other\") {\n        predeceasedRelationshipTypeStr.classList.remove(\"d-none\");\n      } else {\n        predeceasedRelationshipTypeStr.querySelector(\"input\").value = \"\";\n        predeceasedRelationshipTypeStr.classList.add(\"d-none\");\n      }\n    });\n  }\n\n  if (props.followerFormProps) {\n    const followingRelationshipTypeSelect = document.getElementById(\n      props.followerFormProps.deceasedRelationshipTypeFieldId,\n    );\n    const followingRelationshipTypeStr = document.querySelector(\n      \".following-relationship-other\",\n    );\n\n    if (followingRelationshipTypeSelect && followingRelationshipTypeStr) {\n      followingRelationshipTypeSelect.addEventListener(\"change\", (evt) => {\n        const index = evt.target.selectedIndex;\n        const selected = evt.target.options[index];\n        if (selected.value === \"other\") {\n          followingRelationshipTypeStr.classList.remove(\"d-none\");\n        } else {\n          followingRelationshipTypeStr.querySelector(\"input\").value = \"\";\n          followingRelationshipTypeStr.classList.add(\"d-none\");\n        }\n      });\n    }\n  }\n\n  if (!props.isOnboarding) {\n    initMemorialSearchByUrl({\n      baseSearchUrl: props.memorialSearchUrl,\n      container: addPredeceasedLovedOneForm,\n      excludeSlugs: props.relatedMemorialSlugs,\n      slugFieldId: props.predeceasedMemorialSlugFieldId,\n      firstNameFieldId: props.predeceasedMemorialDeceasedFirstNameFieldId,\n      lastNameFieldId: props.predeceasedMemorialDeceasedLastNameFieldId,\n    });\n  }\n\n  // Initialize relationship edit forms.\n\n  const personEditForms = document.querySelectorAll(\".person-edit-form\");\n  if (personEditForms) {\n    personEditForms.forEach((personEditFormContainer) => {\n      const relationshipTypeSelect = personEditFormContainer.querySelector(\"select\");\n      const relationshipTypeStr = personEditFormContainer.querySelector(\n        \".edit-relationship-other\",\n      );\n\n      relationshipTypeSelect.addEventListener(\"change\", (evt) => {\n        const index = evt.target.selectedIndex;\n        const selected = evt.target.options[index];\n        if (selected.value === \"other\") {\n          relationshipTypeStr.classList.remove(\"d-none\");\n          relationshipTypeStr\n            .querySelector(\"input\")\n            .setAttribute(\"required\", \"required\");\n        } else {\n          relationshipTypeStr.querySelector(\"input\").value = \"\";\n          relationshipTypeStr.classList.add(\"d-none\");\n          relationshipTypeStr.querySelector(\"input\").removeAttribute(\"required\");\n        }\n      });\n\n      const listGroupItem = personEditFormContainer.closest(\".list-group-item\");\n      const editForm = listGroupItem.querySelector(\".person-edit-form\");\n      const listItemContent = listGroupItem.querySelector(\".list-item-content\");\n      personEditFormContainer\n        .querySelector(\".cancel-edit-person\")\n        .addEventListener(\"click\", () => {\n          editForm.classList.add(\"d-none\");\n          listItemContent.classList.remove(\"d-none\");\n\n          editForm.querySelectorAll(\"input,select\").forEach((field) => {\n            field.disabled = \"disabled\";\n          });\n        });\n\n      editForm.querySelectorAll(\"input\").forEach((input) => {\n        input.addEventListener(\"keydown\", (evt) => {\n          if (evt.keyCode === 13) {\n            evt.preventDefault();\n            editForm.querySelector(\"button\").click();\n          }\n        });\n      });\n    });\n  }\n\n  const personEditLinks = document.querySelectorAll(\".edit-person-link\");\n  if (personEditLinks) {\n    personEditLinks.forEach((editLink) => {\n      const listGroupItem = editLink.closest(\".list-group-item\");\n      const editForm = listGroupItem.querySelector(\".person-edit-form\");\n      const listItemContent = listGroupItem.querySelector(\".list-item-content\");\n      editLink.addEventListener(\"click\", () => {\n        editForm.classList.remove(\"d-none\");\n        listItemContent.classList.add(\"d-none\");\n\n        editForm.querySelectorAll(\"input,select\").forEach((field) => {\n          field.disabled = null;\n        });\n      });\n    });\n  }\n}\n","import requests, { ResponseError } from \"../core/requests\";\n\n/**\n * Initialize memorial search-by-URL behavior.\n *\n * @param {object} props - the props generated for memorial search.\n */\nexport default function initMemorialSearchByUrl(props) {\n  const {\n    baseSearchUrl,\n    container,\n    slugFieldId,\n    firstNameFieldId,\n    lastNameFieldId,\n    excludeSlugs,\n    predicateFilter,\n  } = props;\n\n  if (!container) {\n    return;\n  }\n\n  const memorialSearchEntry = container.querySelector(\".memorial-search-entry\");\n  const memorialSearchLoading = container.querySelector(\".memorial-search-loading\");\n  const memorialSearchResultContainer = container.querySelector(\n    \".memorial-search-result-container\",\n  );\n  const memorialSearchError = container.querySelector(\".memorial-search-error\");\n  const memorialSearchDuplicate = container.querySelector(\".memorial-search-duplicate\");\n  const memorialSearchIneligible = container.querySelector(\n    \".memorial-search-ineligible\",\n  );\n  const manualEntryContainer = container.querySelector(\".manual-entry\");\n  const memorialSlugField = document.getElementById(slugFieldId);\n  const rawFirstNameField = document.getElementById(firstNameFieldId);\n  const rawLastNameField = document.getElementById(lastNameFieldId);\n\n  const submitButton = container.querySelector('[type=\"submit\"]');\n\n  /**\n   * Given received memorial data from a search, display the result on-screen\n   *\n   * @param {object} memorialData - data about a memorial.\n   */\n  const showSearchResult = (memorialData) => {\n    memorialSearchLoading.classList.add(\"d-none\");\n\n    if (memorialData) {\n      if (predicateFilter && !predicateFilter(memorialData)) {\n        memorialSearchIneligible.classList.remove(\"d-none\");\n        memorialSearchResultContainer.classList.add(\"d-none\");\n        memorialSearchEntry.classList.remove(\"d-none\");\n        if (manualEntryContainer) {\n          manualEntryContainer.classList.remove(\"d-none\");\n        } else if (submitButton) {\n          submitButton.setAttribute(\"disabled\", \"disabled\");\n        }\n        return;\n      }\n\n      if (excludeSlugs && excludeSlugs.includes(memorialData.slug)) {\n        memorialSearchDuplicate.classList.remove(\"d-none\");\n        memorialSearchResultContainer.classList.add(\"d-none\");\n        memorialSearchEntry.classList.remove(\"d-none\");\n        if (manualEntryContainer) {\n          manualEntryContainer.classList.remove(\"d-none\");\n        } else if (submitButton) {\n          submitButton.setAttribute(\"disabled\", \"disabled\");\n        }\n        return;\n      }\n\n      memorialSearchResultContainer.classList.remove(\"d-none\");\n      if (manualEntryContainer) {\n        manualEntryContainer.classList.add(\"d-none\");\n      } else if (submitButton) {\n        submitButton.removeAttribute(\"disabled\");\n      }\n      memorialSearchResultContainer.querySelector(\".memorial-image\").src =\n        memorialData.photo;\n      memorialSearchResultContainer.querySelector(\".name\").innerText =\n        memorialData.name;\n      memorialSearchResultContainer.querySelector(\".location\").innerText =\n        memorialData.location || \"\";\n      if (memorialData.yearOfBirth) {\n        memorialSearchResultContainer.querySelector(\".years\").innerText =\n          `${memorialData.yearOfBirth} - ${memorialData.yearOfDeath}`;\n      } else {\n        memorialSearchResultContainer.querySelector(\".years\").innerText = \"--\";\n      }\n      memorialSlugField.value = memorialData.slug;\n      rawFirstNameField.value = memorialData.firstName;\n      rawLastNameField.value = memorialData.lastName;\n    } else {\n      memorialSearchResultContainer.classList.add(\"d-none\");\n      memorialSearchEntry.classList.remove(\"d-none\");\n      memorialSearchError.classList.remove(\"d-none\");\n      if (manualEntryContainer) {\n        manualEntryContainer.classList.remove(\"d-none\");\n      } else if (submitButton) {\n        submitButton.setAttribute(\"disabled\", \"disabled\");\n      }\n    }\n  };\n\n  /**\n   * Search for a memorial by URL.\n   *\n   * @param {string} memorialUrl - the memorial URL\n   * @returns {Promise<void>} - an ignorable promise\n   */\n  const searchMemorial = async (memorialUrl) => {\n    memorialSearchEntry.classList.add(\"d-none\");\n    memorialSearchLoading.classList.remove(\"d-none\");\n    memorialSearchResultContainer.classList.add(\"d-none\");\n    memorialSearchError.classList.add(\"d-none\");\n    memorialSearchIneligible.classList.add(\"d-none\");\n    memorialSearchDuplicate.classList.add(\"d-none\");\n\n    const searchUrl = `${baseSearchUrl}?url=${encodeURIComponent(memorialUrl)}`;\n\n    try {\n      const response = await requests.get(searchUrl);\n\n      if (!response.ok) {\n        throw new ResponseError(response);\n      }\n\n      const responseData = await response.json();\n\n      showSearchResult(responseData);\n    } catch (error) {\n      window.Rollbar.warn(\"Error searching memorial by URL\", error);\n      showSearchResult(null);\n    }\n  };\n\n  if (memorialSearchEntry) {\n    memorialSearchEntry.querySelector(\"input\").addEventListener(\"paste\", (event) => {\n      const pastedUrl = (event.clipboardData || window.clipboardData).getData(\"text\");\n      searchMemorial(pastedUrl);\n    });\n\n    const clearLink = container.querySelector(\".clear-search-result\");\n    clearLink.addEventListener(\"click\", () => {\n      memorialSlugField.value = \"\";\n      rawFirstNameField.value = \"\";\n      rawLastNameField.value = \"\";\n      memorialSearchResultContainer.classList.add(\"d-none\");\n      memorialSearchEntry.classList.remove(\"d-none\");\n      if (manualEntryContainer) {\n        manualEntryContainer.classList.remove(\"d-none\");\n      } else if (submitButton) {\n        submitButton.setAttribute(\"disabled\", \"disabled\");\n      }\n    });\n  }\n}\n","import initGoogleAutocomplete from \"../../components/GoogleAutocomplete\";\nimport initExpandableCollapses from \"../../components/ExpandableCollapse\";\nimport {\n  initAnimatedPlaceholderFormField,\n  registerSubmitButton,\n} from \"../../core/utils\";\n\nexport default function initMemorialPrivateHowToHelp(props) {\n  let { totalOtherFormCount } = props;\n\n  const initNeedForm = (needFormContainer) => {\n    const checkbox = needFormContainer.querySelector(\n      '.need-title input[type=\"checkbox\"]',\n    );\n    const needTypeOtherInput = checkbox\n      .closest(\".need-title\")\n      .querySelector(\".need-type-other-input\");\n\n    const activate = () => {\n      const detail = checkbox\n        .closest(\".need-form-container\")\n        .querySelector(\".need-details\");\n      if (detail) {\n        detail.classList.toggle(\"show\", checkbox.checked);\n      }\n\n      const needTypeLabel = checkbox\n        .closest(\".need-title\")\n        .querySelector(\".need-title-label\");\n      const deleteInput = checkbox\n        .closest(\".need-title\")\n        .querySelector(`#${checkbox.id.replace(\"need_enabled\", \"DELETE\")}`);\n      const idInput = checkbox\n        .closest(\".need-form-container\")\n        .querySelector(`#${checkbox.id.replace(\"need_enabled\", \"id\")}`);\n      if (needTypeLabel && needTypeOtherInput && deleteInput) {\n        needTypeOtherInput.classList.toggle(\"d-none\", !checkbox.checked);\n        needTypeLabel.classList.toggle(\"d-none\", checkbox.checked);\n\n        if (checkbox.checked) {\n          needTypeOtherInput.focus();\n        }\n\n        if (idInput && idInput.value) {\n          deleteInput.value = !checkbox.checked;\n        } else if (!checkbox.checked) {\n          totalOtherFormCount -= 1;\n          checkbox.closest(\".need-form-container\").remove();\n          document.querySelector(\"#id_need-other-TOTAL_FORMS\").value =\n            totalOtherFormCount;\n        }\n      }\n\n      const titleSubmitButton = checkbox\n        .closest(\".need-title\")\n        .querySelector('button[type=\"submit\"]');\n      if (titleSubmitButton) {\n        titleSubmitButton.classList.add(\"d-md-block\");\n\n        if (idInput && idInput.value && !checkbox.checked) {\n          titleSubmitButton.innerText = \"Remove\";\n        }\n      }\n    };\n\n    checkbox.addEventListener(\"change\", activate);\n\n    if (needTypeOtherInput) {\n      needTypeOtherInput.addEventListener(\"input\", activate);\n    }\n\n    const editNeedDetailsButtons =\n      needFormContainer.querySelectorAll(\".edit-need-details\");\n    editNeedDetailsButtons.forEach((button) => {\n      button.addEventListener(\"click\", () => {\n        const readonlyContainer = needFormContainer.querySelector(\n          \".need-details-readonly\",\n        );\n        const editableContainer = needFormContainer.querySelector(\n          \".need-details-editable\",\n        );\n\n        readonlyContainer.classList.add(\"d-none\");\n        editableContainer.classList.remove(\"d-none\");\n      });\n    });\n\n    const locationField = needFormContainer.querySelector(\".need-location-field\");\n    const locationMetadataField = needFormContainer.querySelector(\n      \".need-location-metadata-field\",\n    );\n\n    if (locationField && locationMetadataField) {\n      initGoogleAutocomplete({\n        element: locationField,\n        metadataElement: locationMetadataField,\n        options: {\n          types: [\"establishment\", \"geocode\"],\n        },\n      });\n    }\n  };\n\n  document.querySelectorAll(\".need-form-container\").forEach(initNeedForm);\n\n  const otherNeedFormsetContainer = document.querySelector(\".other-need-formset\");\n  const addOtherButton = document.querySelector(\".add-other-need\");\n  if (otherNeedFormsetContainer && addOtherButton) {\n    addOtherButton.addEventListener(\"click\", () => {\n      totalOtherFormCount += 1;\n      const formSource = props.emptyOtherForm.replace(\n        /__prefix__/g,\n        totalOtherFormCount - 1,\n      );\n      const wrapper = document.createElement(\"div\");\n      wrapper.innerHTML = formSource;\n      const form = wrapper.firstElementChild;\n      otherNeedFormsetContainer.appendChild(form);\n\n      initNeedForm(form);\n\n      form.querySelectorAll('[type=\"submit\"]').forEach(registerSubmitButton);\n      form.querySelector('input[type=\"checkbox\"]').click();\n      form\n        .querySelectorAll(\".el-animated-placeholder-label-input input\")\n        .forEach(initAnimatedPlaceholderFormField);\n\n      document.querySelector(\"#id_need-other-TOTAL_FORMS\").value = totalOtherFormCount;\n    });\n  }\n\n  initExpandableCollapses();\n}\n","import Modal from \"bootstrap/js/dist/modal\";\n\nimport initSubscriberNotificationsModal from \"../../components/SubscriberNotificationsModal\";\nimport requests, { ResponseError } from \"../../core/requests\";\n\nexport default function initInvites(props) {\n  if (props.showNotificationsPrompt) {\n    initSubscriberNotificationsModal(props);\n  }\n\n  const openImportContactsButton = document.querySelector(\n    \".open-import-contacts-button\",\n  );\n  const loadingOverlay = document.querySelector(\".modal-body-overlay.loading\");\n  const connectPromptOverlay = document.querySelector(\n    \".modal-body-overlay.connect-prompt\",\n  );\n  const errorOverlay = document.querySelector(\".modal-body-overlay.error\");\n  const contactSearch = document.querySelector(\".contact-search\");\n  const contactListGroup = document.querySelector(\".contact-list-group\");\n  const importContactsButton = document.querySelector(\".import-contacts-button\");\n  const recipientsField = document.querySelector(\".invite-recipients-field textarea\");\n  const selectAllContactsButton = document.querySelector(\".select-all-contacts-button\");\n\n  if (contactSearch) {\n    contactSearch.addEventListener(\"input\", () => {\n      const term = contactSearch.value.toLowerCase();\n      document.querySelector(\".clear-contact-search\").classList.toggle(\"d-none\", !term);\n      contactListGroup.querySelectorAll(\".list-group-item\").forEach((element) => {\n        const searchTarget = (\n          element.getAttribute(\"data-name\") + element.getAttribute(\"data-email\")\n        ).toLowerCase();\n        const show = !term || searchTarget.includes(term);\n        element.classList.toggle(\"d-none\", !show);\n      });\n    });\n\n    document.querySelector(\".clear-contact-search\").addEventListener(\"click\", (e) => {\n      e.currentTarget.classList.add(\"d-none\");\n      contactSearch.value = \"\";\n      contactListGroup.querySelectorAll(\".list-group-item\").forEach((element) => {\n        element.classList.remove(\"d-none\");\n      });\n    });\n\n    const loadContacts = async () => {\n      const alreadySelected = (recipientsField.value || \"\")\n        .toLowerCase()\n        .split(\",\")\n        .map((em) => em.trim());\n\n      while (contactListGroup.firstChild) {\n        contactListGroup.removeChild(contactListGroup.firstChild);\n      }\n\n      errorOverlay.classList.add(\"d-none\");\n      loadingOverlay.classList.remove(\"d-none\");\n      importContactsButton.classList.add(\"disabled\");\n\n      let responseData;\n\n      try {\n        const response = await requests.get(props.getContactsUrl);\n\n        if (!response.ok) {\n          throw new ResponseError(response);\n        }\n\n        responseData = await response.json();\n      } catch (error) {\n        window.Rollbar.warn(\"Error getting Google contacts\", error);\n        loadingOverlay.classList.add(\"d-none\");\n        errorOverlay.classList.remove(\"d-none\");\n      }\n\n      if (responseData) {\n        if (responseData.contacts.length === 0) {\n          const element = document.createElement(\"div\");\n          element.setAttribute(\"class\", \"list-group-item list-group-item-disabled\");\n          element.innerText = \"You have no contacts attached to your Google account.\";\n        }\n\n        responseData.contacts.forEach((contact) => {\n          const element = document.createElement(\"a\");\n          element.setAttribute(\"href\", \"javascript:;\");\n          element.setAttribute(\n            \"class\",\n            \"list-group-item list-group-item-action contact-list-group-item\",\n          );\n          element.setAttribute(\"data-email\", contact.email);\n          element.setAttribute(\"data-name\", contact.name);\n          element.innerHTML = `<div class=\"checkbox\"></div><div class=\"contact\"><h5>${contact.name}</h5><span>${contact.email}</span></div>`;\n          element.addEventListener(\"click\", () => {\n            element.classList.toggle(\"active\");\n\n            if (\n              document.querySelectorAll(\".contact-list-group-item\").length ===\n              document.querySelectorAll(\".contact-list-group-item.active\").length\n            ) {\n              selectAllContactsButton.innerText = \"Deselect All\";\n              selectAllContactsButton.setAttribute(\"data-all-selected\", \"true\");\n            } else {\n              selectAllContactsButton.innerText = \"Select All\";\n              selectAllContactsButton.removeAttribute(\"data-all-selected\");\n            }\n          });\n\n          if (alreadySelected.includes(contact.email.toLowerCase())) {\n            element.classList.add(\"active\");\n          }\n\n          contactListGroup.appendChild(element);\n        });\n\n        selectAllContactsButton.classList.remove(\"d-none\");\n        loadingOverlay.classList.add(\"d-none\");\n        importContactsButton.classList.remove(\"disabled\");\n      }\n    };\n\n    errorOverlay.querySelector(\".btn\").addEventListener(\"click\", (evt) => {\n      if (!errorOverlay.getAttribute(\"data-has-retried\")) {\n        errorOverlay.setAttribute(\"data-has-retried\", \"true\");\n        evt.currentTarget.innerText = \"Error! Click to reload and reconnect to Google.\";\n        loadContacts();\n      } else {\n        window.location = `${window.location.pathname}?clear-gauth=1`;\n      }\n    });\n\n    const importGoogleContactsModalElement = document.querySelector(\n      \"#import-google-contacts-modal\",\n    );\n    if (props.hasCredentials) {\n      importGoogleContactsModalElement.addEventListener(\"show.bs.modal\", async () => {\n        await loadContacts();\n      });\n    } else {\n      const initializerButton = document.querySelector(\".oauth-initializer\");\n      initializerButton.addEventListener(\"click\", () => {\n        const alternate = document.querySelector(\n          initializerButton.getAttribute(\"data-alternate\"),\n        );\n        if (alternate && alternate.classList.contains(\"invisible\")) {\n          setTimeout(() => {\n            alternate.classList.remove(\"invisible\");\n          }, 2000);\n        }\n\n        const url = initializerButton.getAttribute(\"data-oauth-url\");\n        const w = 400;\n        const h = 680;\n        const y = window.top.outerHeight / 2 + window.top.screenY - h / 2;\n        const x = window.top.outerWidth / 2 + window.top.screenX - w / 2;\n        window.open(\n          url,\n          \"OAuthWindow\",\n          `toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=${w}, height=${h}, top=${y}, left=${x}`,\n        );\n      });\n      window.oAuthComplete = async () => {\n        if (connectPromptOverlay && loadingOverlay) {\n          connectPromptOverlay.classList.add(\"d-none\");\n          loadingOverlay.classList.remove(\"d-none\");\n        }\n        await loadContacts();\n      };\n    }\n\n    if (importContactsButton) {\n      importContactsButton.addEventListener(\"click\", () => {\n        openImportContactsButton.innerText = \"Add more imported contacts\";\n        if (!importContactsButton.classList.contains(\"disabled\")) {\n          const alreadySelected = (recipientsField.value || \"\")\n            .toLowerCase()\n            .split(\",\")\n            .map((em) => em.trim());\n          const selectedEmails = Array.from(\n            contactListGroup.querySelectorAll(\".list-group-item.active\"),\n          ).map((item) => item.getAttribute(\"data-email\").toLowerCase());\n          const deselectedEmails = Array.from(\n            contactListGroup.querySelectorAll(\".list-group-item\"),\n          )\n            .map((item) => item.getAttribute(\"data-email\").toLowerCase())\n            .filter((email) => !selectedEmails.includes(email));\n          const newSelectedEmails = selectedEmails.filter(\n            (email) => !alreadySelected.includes(email.toLowerCase()),\n          );\n          const newRecipients = alreadySelected\n            .filter((email) => !deselectedEmails.includes(email.toLowerCase()))\n            .concat(newSelectedEmails)\n            .filter((email) => email);\n\n          recipientsField.value = `${newRecipients.join(\", \")}`;\n\n          Modal.getOrCreateInstance(importGoogleContactsModalElement).hide();\n        }\n      });\n    }\n\n    if (selectAllContactsButton) {\n      selectAllContactsButton.addEventListener(\"click\", () => {\n        if (selectAllContactsButton.getAttribute(\"data-all-selected\")) {\n          document.querySelectorAll(\".contact-list-group-item\").forEach((el) => {\n            el.classList.remove(\"active\");\n          });\n        } else {\n          document.querySelectorAll(\".contact-list-group-item\").forEach((el) => {\n            el.classList.add(\"active\");\n          });\n        }\n\n        if (\n          document.querySelectorAll(\".contact-list-group-item\").length ===\n          document.querySelectorAll(\".contact-list-group-item.active\").length\n        ) {\n          selectAllContactsButton.innerText = \"Deselect All\";\n          selectAllContactsButton.setAttribute(\"data-all-selected\", \"true\");\n        } else {\n          selectAllContactsButton.innerText = \"Select All\";\n          selectAllContactsButton.removeAttribute(\"data-all-selected\");\n        }\n      });\n    }\n  }\n\n  const inviteRecordsBodyCard = document.querySelector(\".invite-records-body-card\");\n  if (inviteRecordsBodyCard) {\n    const toggleButton = inviteRecordsBodyCard.querySelector(\n      \".toggle-collapse-invite-records\",\n    );\n    toggleButton.addEventListener(\"click\", () => {\n      inviteRecordsBodyCard.classList.toggle(\"collapsed\");\n\n      if (inviteRecordsBodyCard.classList.contains(\"collapsed\")) {\n        inviteRecordsBodyCard.style.height = null;\n      } else {\n        inviteRecordsBodyCard.style.height = `${inviteRecordsBodyCard.scrollHeight + 40}px`;\n      }\n    });\n  }\n}\n","import initFundraiserForm from \"../../components/FundraiserForm\";\nimport initRelationshipForms from \"./relationshipForms\";\n\nexport function initFundraiserOnboarding(props) {\n  initFundraiserForm(props);\n}\n\nexport function initMemorialOnboardingInviteManager(props) {\n  initRelationshipForms(props);\n  const formContainer = document.querySelector(\".add-survivor-form\");\n  formContainer.querySelectorAll(\"input,select\").forEach((field) => {\n    field.disabled = false;\n  });\n}\n","import { initEditEvents, initEditEventsOnLoad } from \"../../components/EditEvents\";\n\nexport default function initMemorialOnboardingEvents(props) {\n  const deleteEventCallbacks = [];\n  initEditEvents(props, deleteEventCallbacks);\n  initEditEventsOnLoad(props, deleteEventCallbacks);\n}\n","import initRelationshipForms from \"./relationshipForms\";\n\nexport default function initMemorialOnboardingFamily(props) {\n  initRelationshipForms(props);\n}\n","import initBusinessAssociationForm from \"../../components/BusinessAssociationForm\";\nimport initCauseOfDeathAutocomplete from \"../../components/CauseOfDeathAutocomplete\";\nimport initGoogleAutocomplete from \"../../components/GoogleAutocomplete\";\n\nexport default function initMemorialOnboardingFinalRestingPlace(props) {\n  initBusinessAssociationForm(props);\n  initCauseOfDeathAutocomplete(props.causeOfDeathSearch);\n\n  initGoogleAutocomplete({\n    element: document.getElementById(\"id_business_association-remains_location\"),\n    metadataElement: document.getElementById(\n      \"id_business_association-remains_location_metadata\",\n    ),\n    options: {\n      types: [\"establishment\", \"geocode\"],\n    },\n  });\n}\n","export default function initMemorialOnboardingFundraisingGuidance() {\n  const choiceField = document.querySelector('input[name=\"_fundraising_choice\"]');\n  const choices = document.querySelectorAll(\".fundraising-guidance-option\");\n\n  if (choiceField && choices.length) {\n    choices.forEach((choice) => {\n      choice.addEventListener(\"click\", () => {\n        choiceField.value = choice.dataset.fundraisingChoice;\n        choiceField.closest(\"form\").submit();\n      });\n    });\n  }\n}\n","import DeceasedPhotoUploader from \"../../components/DeceasedPhotoUploader\";\nimport config from \"../../core/config\";\n\nexport default function initMemorialOnboardingPhoto(props) {\n  const uploader = new DeceasedPhotoUploader(props.deceasedPhotoUploaderProps);\n  const selectPhotosButton = document.querySelector(\".start-select-photos\");\n  selectPhotosButton.addEventListener(\"click\", () => {\n    uploader.show();\n  });\n\n  window.fbAsyncInit = () => {\n    window.FB.init({\n      appId: config.facebookAppId,\n      autoLogAppEvents: true,\n      xfbml: true,\n      version: config.facebookApiVersion,\n    });\n  };\n}\n","import ClipboardJS from \"clipboard\";\n\nimport config from \"../../core/config\";\nimport requests, { ResponseError } from \"../../core/requests\";\n\nconst updateSharingChecklist = async (props) => {\n  try {\n    const response = await requests.post(props.updateSharingChecklistEndpoint, {\n      \"sharing-checklist-item\": \"share_to_facebook\",\n    });\n    if (!response.ok) {\n      throw new ResponseError(response);\n    }\n  } catch (error) {\n    window.Rollbar.error(\n      \"Error updating the sharing checklist from onboarding\",\n      error.statusText,\n    );\n  }\n};\n\nexport default function initMemorialOnboardingShare(props) {\n  const clipboard = new ClipboardJS(\".btn-copy\");\n  clipboard.on(\"success\", (event) => {\n    const button = event.trigger;\n    button.innerText = \"Copied!\";\n  });\n\n  // NOTE: this is the callback function for when the FaceBook SDK loads\n  window.fbAsyncInit = () => {\n    window.FB.init({\n      appId: config.facebookAppId,\n      autoLogAppEvents: true,\n      xfbml: true,\n      version: config.facebookApiVersion,\n    });\n    document.querySelectorAll(\".btn-facebook-share\").forEach((btnFacebookShare) => {\n      btnFacebookShare.addEventListener(\"click\", () => {\n        if (config.debug) {\n          console.log(\n            `Would share the following link to Facebook: ${props.facebookShare.href}`,\n          );\n        }\n        window.FB.ui(props.facebookShare, (facebookResponse) => {\n          if (\n            facebookResponse &&\n            !facebookResponse.error_code &&\n            typeof facebookResponse !== \"undefined\"\n          ) {\n            if (\n              props.memorialHasPersonalFundraiser &&\n              !props.shareToFacebookChecklistStatus\n            ) {\n              updateSharingChecklist(props);\n              window.location.href = props.shareComplete;\n            } else {\n              window.location.href = props.shareComplete;\n            }\n          }\n        });\n      });\n    });\n  };\n}\n","import { sendBrowserAgnosticEvent } from \"../core/utils\";\n\nexport default class WordCounter {\n  constructor(root) {\n    this.root = root;\n    this.target = document.getElementById(this.root.dataset.wordCountTarget);\n    this.max = parseInt(this.root.dataset.wordCountMax, 10);\n    this.counterSpan = this.root.querySelector(\".word-counter-count\");\n\n    if (!(this.target && this.max)) {\n      return;\n    }\n\n    this.target.addEventListener(\"input\", () => {\n      this.assessCount();\n    });\n  }\n\n  assessCount() {\n    const currentCount = this.getWordCount();\n    const overage = currentCount - this.max;\n\n    if (overage > 0) {\n      this.counterSpan.innerText = `${currentCount}/${this.max}`;\n      sendBrowserAgnosticEvent(this.root, \"elwc:overage\");\n    } else {\n      this.counterSpan.innerText = `${currentCount}/${this.max}`;\n      sendBrowserAgnosticEvent(this.root, \"elwc:compliance\");\n    }\n\n    this.counterSpan.classList.toggle(\"overage\", overage > 0);\n    this.counterSpan.classList.toggle(\"warning\", overage >= -10 && overage <= 0);\n  }\n\n  getWordCount() {\n    return this.target.value.split(/\\s/).filter((token) => token.length > 0).length;\n  }\n}\n","import WordCounter from \"../../components/WordCounter\";\nimport AutoSaveTextField from \"../../components/AutoSaveTextField\";\nimport initPayableCheckout from \"../../commerce/PayableCheckout\";\n\nexport default function initPartnerObituaryOrderCreate(props) {\n  const photoUrlField = document.getElementById(props.form.fields.photoUrl);\n  const selectedPhoto = document.querySelector(\".selected-photo\");\n  const photoSelectorChoices = document.querySelectorAll(\n    \".photo-selector-choices > img\",\n  );\n\n  if (photoUrlField && selectedPhoto && photoSelectorChoices.length) {\n    photoSelectorChoices.forEach((img) => {\n      img.addEventListener(\"click\", () => {\n        photoSelectorChoices.forEach((_img) => {\n          _img.classList.remove(\"selected\");\n        });\n\n        img.classList.add(\"selected\");\n\n        if (img.classList.contains(\"no-photo\")) {\n          photoUrlField.value = \"\";\n          selectedPhoto.src = \"\";\n          selectedPhoto.classList.add(\"d-none\");\n        } else {\n          photoUrlField.value = img.src;\n          selectedPhoto.src = img.src;\n          selectedPhoto.classList.remove(\"d-none\");\n        }\n      });\n    });\n  }\n\n  const form = document.querySelector(\".partner-obituary-order-create-form\");\n  let formDisabled = false;\n  form.addEventListener(\"submit\", (event) => {\n    if (formDisabled) {\n      event.stopPropagation();\n      event.preventDefault();\n    }\n  });\n\n  const toggleFormEnabled = (forceEnabled) => {\n    formDisabled = !forceEnabled;\n    form.querySelectorAll('[type=\"submit\"]').forEach((btn) => {\n      btn.disabled = !forceEnabled;\n      btn.classList.toggle(\"disabled\", !forceEnabled);\n    });\n  };\n\n  const wordCountRoot = document.querySelector(\n    `.word-counter[data-word-count-target=\"${props.form.fields.obituary}\"]`,\n  );\n  if (wordCountRoot) {\n    const wordCounter = new WordCounter(wordCountRoot);\n    wordCounter.assessCount();\n\n    wordCountRoot.addEventListener(\"elwc:overage\", () => {\n      toggleFormEnabled(false);\n    });\n    wordCountRoot.addEventListener(\"elwc:compliance\", () => {\n      toggleFormEnabled(true);\n    });\n  }\n\n  const obitField = document.getElementById(props.form.fields.obituary);\n  if (obitField) {\n    new AutoSaveTextField(obitField);\n  }\n\n  initPayableCheckout(props);\n}\n","import Modal from \"bootstrap/js/dist/modal\";\n\nimport initBusinessAutocomplete from \"../../components/BusinessAutocomplete\";\nimport { scrollToElement } from \"../../core/utils\";\nimport initExpandableCollapses from \"../../components/ExpandableCollapse\";\n\n/**\n * Initialize the Charity Search handling for the page.\n *\n * @param {object} props - the page props, including Autocomplete props for\n *     Charity search\n */\nfunction initCharitySearchListener(props) {\n  initBusinessAutocomplete(props.charitySearch);\n\n  const charityBusinessIdentifierInput = document.getElementById(\n    props.charitySearch.businessIdentifierInputId,\n  );\n  const selectCharityBtn = document.querySelector(\".btn-submit-typed-charity\");\n  const modalElement = document.querySelector(\".charity-search-helper-modal\");\n\n  charityBusinessIdentifierInput.tomselect.on(\"change\", (newValue) => {\n    if (newValue) {\n      const newOption = charityBusinessIdentifierInput.tomselect.options[newValue];\n      if (newOption.created) {\n        const causeNameInput = modalElement.querySelector(\".cause-name-input\");\n        causeNameInput.value = newOption.id;\n\n        Modal.getOrCreateInstance(modalElement).show();\n      }\n\n      selectCharityBtn.classList.remove(\"d-none\");\n    }\n  });\n}\n\n/**\n * Initialize the cause chooser grid.\n */\nfunction initChooseCauseGrid() {\n  const causeCards = document.querySelectorAll(\".cause-card\");\n  const causeExpanders = document.querySelectorAll(\".cause-card .cause-expander\");\n  const rectangles = document.querySelectorAll(\".rectangle\");\n\n  // open and close cause-card when click on cause-card\n  causeExpanders.forEach((causeExpander) => {\n    causeExpander.addEventListener(\"click\", () => {\n      const thisCard = causeExpander.closest(\".cause-card\");\n      const thisCauseCardExpander = thisCard.querySelector(\".cause-card-expander\");\n      const thisRectangle = thisCard.querySelector(\".rectangle\");\n      const isAlreadyExpanded = thisCard.classList.contains(\"is-expanded\");\n\n      rectangles.forEach((rectangle) => {\n        rectangle.classList.toggle(\n          \"d-none\",\n          thisRectangle !== rectangle || isAlreadyExpanded,\n        );\n      });\n\n      causeCards.forEach((card) => {\n        card.classList.toggle(\n          \"is-expanded\",\n          card === thisCard ? !isAlreadyExpanded : false,\n        );\n        card.classList.toggle(\n          \"is-collapsed\",\n          card === thisCard ? isAlreadyExpanded : true,\n        );\n        card.style.marginBottom =\n          card === thisCard && !isAlreadyExpanded\n            ? `${thisCauseCardExpander.offsetHeight + 20}px`\n            : \"20px\";\n      });\n\n      scrollToElement(\n        thisCard,\n        -80,\n        false,\n        window.isOnMobile\n          ? document.scrollingElement\n          : thisCard.closest(\".private-content-container\") || document.scrollingElement,\n      );\n    });\n  });\n}\n\n/**\n * Init the expandable charity overview sections with `initExpandableCollapse`\n */\nfunction initExpandableCharityOverview() {\n  // This initializes the Read More/Read Less functionality of already opened charity\n  // overviews.\n  function adjustCurrentCardBottomMargin(event) {\n    const currentExpander = event.target.closest(\".cause-card-expander\");\n    const currentCard = currentExpander.closest(\".cause-card\");\n\n    currentCard.style.marginBottom = `${currentExpander.offsetHeight + 20}px`;\n  }\n\n  initExpandableCollapses();\n\n  document.querySelectorAll(\".cause-description\").forEach((descriptionExpander) => {\n    descriptionExpander.addEventListener(\n      \"shown.bs.collapse\",\n      adjustCurrentCardBottomMargin,\n    );\n    descriptionExpander.addEventListener(\n      \"hidden.bs.collapse\",\n      adjustCurrentCardBottomMargin,\n    );\n  });\n}\n\n/**\n * Initialize the choose-cause experience page (onboarding and private)\n *\n * @param {object} props - the page props.\n */\nexport default function initMemorialPrivateChooseCause(props) {\n  initCharitySearchListener(props);\n  initChooseCauseGrid();\n  initExpandableCharityOverview();\n}\n","import \"../../../sass/memorials/private/private.scss\";\n\nimport Glide, { Swipe } from \"@glidejs/glide/dist/glide.modular.esm\";\nimport Alert from \"bootstrap/js/dist/alert\";\nimport Carousel from \"bootstrap/js/dist/carousel\";\nimport Collapse from \"bootstrap/js/dist/collapse\";\nimport Dropdown from \"bootstrap/js/dist/dropdown\"; // eslint-disable-line no-unused-vars\nimport Modal from \"bootstrap/js/dist/modal\";\nimport Tab from \"bootstrap/js/dist/tab\"; // eslint-disable-line no-unused-vars\n\nimport BelongingEditor from \"../../commerce/BelongingEditor\";\n\nimport { initProductPhotoBlur } from \"../../commerce/utils\";\nimport AutoSaveTextField from \"../../components/AutoSaveTextField\";\nimport initBusinessAssociationForm from \"../../components/BusinessAssociationForm\";\nimport initCauseOfDeathAutocomplete from \"../../components/CauseOfDeathAutocomplete\";\nimport initCityAutocomplete from \"../../components/CityAutocomplete\";\nimport { initEditEvents, initEditEventsOnLoad } from \"../../components/EditEvents\";\nimport DeceasedPhotoUploader from \"../../components/DeceasedPhotoUploader\";\nimport initDeceasedSearchAutocomplete from \"../../components/DeceasedSearchAutocomplete\";\nimport { initEditDropdowns } from \"../../components/EditMenuDropdowns\";\nimport initFundraiserForm from \"../../components/FundraiserForm\";\nimport initGoogleAutocomplete from \"../../components/GoogleAutocomplete\";\nimport initMemorialFeatureAutocomplete from \"../../components/MemorialFeatureAutocomplete\";\nimport initMobileShareButton from \"../../components/MobileShareButton\";\nimport initOrganDonationForm from \"../../components/OrganDonationForm\";\nimport initPhotoCropper from \"../../components/PhotoCropper\";\nimport ProgressRing from \"../../components/ProgressRing\";\nimport initSubscriberNotificationsModal from \"../../components/SubscriberNotificationsModal\";\nimport initSuccessModal from \"../../components/SuccessModal\";\nimport initUGCTemplates from \"../../components/UGCTemplates\";\nimport { initUserMentions } from \"../../components/UserMentions\";\nimport config from \"../../core/config\";\nimport {\n  generateElements,\n  getNextSiblingMatchingSelector,\n  handleAjaxFormSubmitProtection,\n  initClipboard,\n  initDirtyTracker,\n  initPopovers,\n  initTooltips,\n  isInViewport,\n  isVisible,\n  registerFormSubmitProtection,\n  storageAvailable,\n  trackCustomUserAction,\n} from \"../../core/utils\";\nimport initRelationshipForms from \"./relationshipForms\";\nimport requests, { ResponseError } from \"../../core/requests\";\nimport {\n  initAddFuneralHomeWarning,\n  scrollInMemorialPrivateContentContainer,\n} from \"../utils\";\nimport initPayableCheckout from \"../../commerce/PayableCheckout\";\nimport initAddPaymentMethod from \"../../commerce/PaymentMethod\";\n\nexport { default as initMemorialPrivateHowToHelp } from \"./howToHelp\";\nexport { default as initInvites } from \"./invites\";\nexport {\n  initFundraiserOnboarding,\n  initMemorialOnboardingInviteManager,\n} from \"./onboarding\";\nexport { default as initMemorialOnboardingEvents } from \"./onboardingEvents\";\nexport { default as initMemorialOnboardingFamily } from \"./onboardingFamily\";\nexport { default as initMemorialOnboardingFinalRestingPlace } from \"./onboardingFinalRestingPlace\";\nexport { default as initMemorialOnboardingFundraisingGuidance } from \"./onboardingFundraisingGuidance\";\nexport { default as initMemorialOnboardingPhoto } from \"./onboardingPhoto\";\nexport { default as initMemorialOnboardingShare } from \"./onboardingShare\";\nexport { default as initPartnerObituaryOrderCheckout } from \"./partnerObituary\";\nexport { default as initMemorialPrivateChooseCause } from \"./privateChooseCause\";\n\nconst eventActions = {\n  \"cause-name\": \"cause-name-change-after-launch\",\n  \"cause-url\": \"cause-website-change-after-launch\",\n  \"cause-type\": \"sympathy-gift-type-change-after-launch\",\n};\n\nconst errorMessages = {\n  \"cause-name\":\n    \"The cause name can't be changed if there are outstanding pledges to the cause.\",\n  \"cause-url\":\n    \"The cause website address can't be changed if there are outstanding pledges to the cause.\",\n  \"cause-type\":\n    \"The type of sympathy gift can't be changed if there are outstanding pledges to the cause.\",\n};\n\nconst TOUR_DELAY = 5000;\n\nfunction initTimezoneSelector(timezoneSelectorId) {\n  const timezoneSelector = document.querySelector(`#${timezoneSelectorId}`);\n  if (timezoneSelector) {\n    let browserTimezone;\n    try {\n      browserTimezone = window.Intl.DateTimeFormat().resolvedOptions().timeZone;\n    } catch {\n      browserTimezone = null;\n    }\n\n    if (browserTimezone) {\n      const match = Array.from(timezoneSelector.options).find(\n        (opt) => opt.value === browserTimezone,\n      );\n\n      if (match) {\n        timezoneSelector.insertBefore(\n          match,\n          timezoneSelector.firstElementChild.nextElementSibling,\n        );\n      }\n    }\n  }\n}\n\nasync function completeSharingChecklistItem(checklistItemKey, endpoint) {\n  try {\n    const response = await requests.post(endpoint, {\n      \"sharing-checklist-item\": checklistItemKey,\n      \"sharing-checklist-value\": 1,\n    });\n\n    if (!response.ok) {\n      throw new ResponseError(response);\n    }\n  } catch {\n    return;\n  }\n\n  document.querySelectorAll(`[data-alert-key=\"${checklistItemKey}\"]`).forEach((a) => {\n    a.remove();\n  });\n}\n\nconst SIDEBAR_KEY = \"el-sidebar-hidden\";\n\nclass SidebarManager {\n  constructor(sidebar) {\n    this.sidebar = sidebar;\n    this.storageAvailable = storageAvailable(\"sessionStorage\");\n  }\n\n  isShowing() {\n    return !this.sidebar.classList.contains(\"hidden\");\n  }\n\n  sync() {\n    const hidden = window.sessionStorage.getItem(SIDEBAR_KEY) === \"true\";\n    this.sidebar.classList.toggle(\"hidden\", hidden);\n  }\n\n  show() {\n    if (this.storageAvailable) {\n      window.sessionStorage.setItem(SIDEBAR_KEY, \"false\");\n      this.sync();\n    } else {\n      this.sidebar.classList.remove(\"hidden\");\n    }\n  }\n\n  hide() {\n    if (this.storageAvailable) {\n      window.sessionStorage.setItem(SIDEBAR_KEY, \"true\");\n      this.sync();\n    } else {\n      this.sidebar.classList.add(\"hidden\");\n    }\n  }\n\n  toggle() {\n    if (this.storageAvailable) {\n      if (this.isShowing()) {\n        this.hide();\n      } else {\n        this.show();\n      }\n    } else {\n      this.sidebar.classList.toggle(\"hidden\");\n    }\n  }\n}\n\nfunction initMemorialUpdateEdits() {\n  document.querySelectorAll(\".remove-memorial-update\").forEach((link) => {\n    link.addEventListener(\"click\", async () => {\n      if (\n        window.confirm(\n          \"Are you sure you want to delete this update? Subscribers will not be notified.\",\n        )\n      ) {\n        const deleteUrl = link.getAttribute(\"data-delete-url\");\n\n        link.innerHTML = \"Removing...\";\n        try {\n          const response = await requests.delete(deleteUrl);\n\n          if (!response.ok) {\n            throw new ResponseError(response);\n          }\n        } catch {\n          link.innerHTML = \"Removing failed.\";\n          return;\n        }\n\n        link.closest(\".memorial-update-container\").remove();\n      }\n    });\n  });\n}\n\nfunction initMemorialGiftPremiumControls(props) {\n  if (!props.hasPremium) {\n    return;\n  }\n\n  if (props.disableMemorialGiftsId) {\n    const disableMemorialGiftsContainers = document.querySelectorAll(\n      \".disable-memorial-gifts-container\",\n    );\n    if (disableMemorialGiftsContainers.length > 0) {\n      disableMemorialGiftsContainers.forEach((disableMemorialGiftsContainer) => {\n        const disableMemorialGiftsToggle = disableMemorialGiftsContainer.querySelector(\n          'input[type=\"checkbox\"]',\n        );\n        const handleDisableToggle = () => {\n          const giftTogglesContainer = document.querySelector(\".gift-toggles\");\n          const giftTogglesDoNotSuggestGifts = giftTogglesContainer.querySelector(\n            \".disable-memorial-gifts-container\",\n          );\n          const causeConfigurationContainers = document.querySelectorAll(\n            \".cause-configuration-container\",\n          );\n          const preferencesContainer = document.querySelector(\n            \".memorial-gifts-display-preferences-container\",\n          );\n          const standaloneStoryAndChecklist = document.querySelector(\n            \".standalone-story-and-checklist\",\n          );\n          const addFundraiserBtn = document.querySelector(\n            \".full-width-add-fundraiser-button\",\n          );\n\n          if (giftTogglesContainer && causeConfigurationContainers) {\n            giftTogglesContainer.classList.toggle(\n              \"gifts-hidden\",\n              disableMemorialGiftsToggle.checked,\n            );\n            causeConfigurationContainers.forEach((causeConfigurationContainer) => {\n              causeConfigurationContainer.parentElement.classList.toggle(\n                \"d-none\",\n                disableMemorialGiftsToggle.checked,\n              );\n            });\n            giftTogglesDoNotSuggestGifts.classList.toggle(\n              \"d-none\",\n              !disableMemorialGiftsToggle.checked,\n            );\n            preferencesContainer.classList.toggle(\n              \"d-none\",\n              disableMemorialGiftsToggle.checked,\n            );\n\n            if (standaloneStoryAndChecklist) {\n              standaloneStoryAndChecklist.classList.toggle(\n                \"d-none\",\n                disableMemorialGiftsToggle.checked,\n              );\n            }\n\n            if (addFundraiserBtn) {\n              addFundraiserBtn.classList.toggle(\n                \"d-none\",\n                disableMemorialGiftsToggle.checked,\n              );\n            }\n          }\n\n          disableMemorialGiftsContainers.forEach((container) => {\n            container.querySelector('input[type=\"checkbox\"]').checked =\n              disableMemorialGiftsToggle.checked;\n          });\n        };\n\n        disableMemorialGiftsToggle.addEventListener(\"change\", handleDisableToggle);\n        handleDisableToggle();\n      });\n    }\n  }\n\n  if (props.disableMemorialGiftListDisplayId) {\n    const disableListDisplay = document.getElementById(\n      props.disableMemorialGiftListDisplayId,\n    );\n    const disableContributionsDisplay = document.getElementById(\n      props.disableMemorialGiftContributionsDisplayId,\n    );\n\n    if (disableListDisplay) {\n      const handleListDisplayToggle = () => {\n        if (disableListDisplay.checked) {\n          disableContributionsDisplay.checked = true;\n          disableContributionsDisplay.disabled = true;\n        } else {\n          disableContributionsDisplay.disabled = false;\n        }\n      };\n\n      const undoDisabledCheckboxOnSubmit = (checkboxEl) => {\n        const targetForm = checkboxEl.closest(\"form\");\n        if (targetForm && checkboxEl) {\n          targetForm.addEventListener(\"submit\", () => {\n            if (checkboxEl.disabled) {\n              checkboxEl.disabled = false;\n            }\n          });\n        }\n      };\n\n      disableListDisplay.addEventListener(\"change\", handleListDisplayToggle);\n      handleListDisplayToggle();\n      undoDisabledCheckboxOnSubmit(disableContributionsDisplay);\n    }\n  }\n}\n\nfunction initPremiumUpsell(props) {\n  if (!props.hasPremium) {\n    const disabledPremiumCheckboxContainers = document.querySelectorAll(\n      \".premium-preference-toggle.disabled\",\n    );\n    disabledPremiumCheckboxContainers.forEach((checkboxContainer) => {\n      checkboxContainer\n        .querySelector(\".click-capture-overlay\")\n        .addEventListener(\"click\", () => {\n          Modal.getOrCreateInstance(\".premium-upsell-modal\").show();\n        });\n    });\n  }\n}\n\nfunction initTimezoneModal() {\n  const urlParams = new URLSearchParams(window.location.search);\n  if (\n    urlParams.get(\"timezone-added\") ||\n    urlParams.get(\"timezone-changed\") ||\n    urlParams.get(\"timezone-removed\")\n  ) {\n    const message = document.getElementsByClassName(\"timezone-modal-text\")[0];\n\n    if (urlParams.get(\"timezone-added\")) {\n      message.innerHTML =\n        \"This timezone will now be displayed throughout this memorial website.\";\n    } else if (urlParams.get(\"timezone-changed\")) {\n      message.innerHTML =\n        \"Your memorial website and any event times have been updated to reflect this new timezone. If you have memorial events listed, please check to ensure the times shown are what you intended.\";\n    } else {\n      message.innerHTML =\n        \"The timezone has been removed from this memorial website. If you have memorial events listed, please check to ensure the times shown are what you intended.\";\n    }\n\n    Modal.getOrCreateInstance(\".timezone-selection-modal\").show();\n  }\n}\n\nfunction initThankYouNoteCheckboxes() {\n  document\n    .querySelectorAll(\".sent-thank-you-checkbox\")\n    .forEach((sentThankYouCheckbox) => {\n      sentThankYouCheckbox.addEventListener(\"click\", async (event) => {\n        event.preventDefault();\n\n        const checkbox = event.currentTarget;\n        checkbox.disabled = true;\n\n        let responseData;\n\n        try {\n          const response = await requests.post(sentThankYouCheckbox.dataset.updateUrl, {\n            toggle_thank_you: true,\n          });\n\n          if (!response.ok) {\n            throw new ResponseError(response);\n          }\n\n          responseData = await response.json();\n        } catch {\n          checkbox.disabled = false;\n        }\n\n        if (responseData) {\n          checkbox.disabled = false;\n          checkbox.checked = responseData.sentThankYou;\n        }\n      });\n    });\n}\n\nexport function initMemorialPrivateBase(props) {\n  // Notification-sending prompt\n  if (props.showNotificationsPrompt) {\n    initSubscriberNotificationsModal(props);\n  }\n\n  // Initialize UserMention code\n  if (props.userMention) {\n    initUserMentions(props);\n  }\n\n  // Initialize JS for sidebar hide/show in tablet mode.\n  const sidebar = document.querySelector(\".private-sidebar\");\n  if (sidebar) {\n    const sidebarToggle = sidebar.querySelector(\".sidebar-toggle\");\n    const sidebarManager = new SidebarManager(sidebar);\n    sidebarManager.sync();\n\n    if (sidebarToggle) {\n      sidebarToggle.addEventListener(\"click\", () => {\n        sidebarManager.toggle();\n      });\n    }\n\n    // If there are visible errorlists, hide sidebar.\n    if (\n      Array.from(document.querySelectorAll(\".errorlist\")).some(\n        (el) => el.offset !== null,\n      )\n    ) {\n      sidebarManager.hide();\n    }\n\n    sidebar.querySelectorAll(\".sidebar-nav .nav-link\").forEach((link) => {\n      link.addEventListener(\"click\", (e) => {\n        e.preventDefault();\n        sidebarManager.hide();\n        window.location.href = e.currentTarget.href;\n      });\n    });\n  }\n\n  // Initialize: clipboard management, \"show less\", dirty form tracker, premium upsell,\n  // timezone modal.\n  initClipboard();\n  initDirtyTracker(props);\n  initPremiumUpsell(props);\n  initTimezoneModal();\n  initAddFuneralHomeWarning();\n\n  // Initialize FB share links\n  // NOTE: this is the callback function for when the FaceBook SDK loads\n  window.fbAsyncInit = () => {\n    window.FB.init({\n      appId: config.facebookAppId,\n      autoLogAppEvents: true,\n      xfbml: true,\n      version: config.facebookApiVersion,\n    });\n\n    document.querySelectorAll(\".btn-facebook-share\").forEach((facebookBtn) => {\n      facebookBtn.addEventListener(\"click\", () => {\n        if (config.debug) {\n          console.log(\n            `Would share the following link to Facebook: ${props.sharingUrl}`,\n          );\n        }\n\n        window.FB.ui(\n          {\n            method: \"share\",\n            href: props.sharingUrl,\n          },\n          (response) => {\n            if (response && !response.error_code && typeof response !== \"undefined\") {\n              completeSharingChecklistItem(\n                \"share_to_facebook\",\n                props.updateSharingChecklistEndpoint,\n              );\n            }\n          },\n        );\n      });\n    });\n  };\n\n  // Initialize the share button if supported.\n  initMobileShareButton(\"#sidebar-mobile-actions-share .btn-native-share\");\n\n  const autocompleteSharingChecklistItems = document.querySelectorAll(\n    \".autocomplete-sharing-checklist-item\",\n  );\n  autocompleteSharingChecklistItems.forEach((item) => {\n    item.addEventListener(\"click\", () => {\n      completeSharingChecklistItem(\n        item.dataset.alertKey,\n        props.updateSharingChecklistEndpoint,\n      );\n    });\n  });\n\n  const allAlertsContainer = document.querySelector(\".private-all-alerts\");\n  const showAllAlerts = document.querySelector(\".show-all-alerts\");\n  if (showAllAlerts) {\n    showAllAlerts.addEventListener(\"click\", (event) => {\n      event.preventDefault();\n      event.stopPropagation();\n\n      if (\n        props.isPrivateDashboard &&\n        allAlertsContainer &&\n        allAlertsContainer.offsetParent == null\n      ) {\n        allAlertsContainer.classList.remove(\"d-none\");\n        allAlertsContainer.classList.add(\"full-screen\");\n      } else {\n        scrollInMemorialPrivateContentContainer(allAlertsContainer);\n        allAlertsContainer.classList.add(\"expand-alerts\");\n        sidebar.classList.add(\"hidden\");\n      }\n    });\n  }\n\n  if (\n    props.isPrivateDashboard &&\n    window.location.hash === \"#all-alerts\" &&\n    allAlertsContainer &&\n    allAlertsContainer.offsetParent == null\n  ) {\n    allAlertsContainer.classList.remove(\"d-none\");\n    allAlertsContainer.classList.add(\"full-screen\");\n  }\n\n  const closeAlerts = document.querySelector(\".close-alerts\");\n  if (closeAlerts) {\n    closeAlerts.addEventListener(\"click\", () => {\n      allAlertsContainer.classList.add(\"d-none\");\n      allAlertsContainer.classList.remove(\"full-screen\");\n    });\n  }\n\n  const hideAlertButtons = document.querySelectorAll(\".dismiss-alert-button\");\n  if (hideAlertButtons) {\n    hideAlertButtons.forEach((alertButton) => {\n      if (alertButton.dataset.alertKey) {\n        alertButton.addEventListener(\"click\", async () => {\n          const revert = handleAjaxFormSubmitProtection(alertButton);\n          const listItem = alertButton.closest(\".list-group-item\");\n\n          let responseData;\n\n          try {\n            const response = await requests.post(props.dismissPrivateAlertUrl, {\n              key: alertButton.dataset.alertKey,\n            });\n\n            if (!response.ok) {\n              throw new ResponseError(response);\n            }\n\n            responseData = await response.json();\n          } catch {\n            revert();\n            return;\n          }\n\n          if (responseData) {\n            if (responseData.success) {\n              listItem.remove();\n            } else {\n              alertButton.innerText = \"Error\";\n            }\n          }\n        });\n      }\n    });\n  }\n\n  // Init autoscroll\n  if (props.autoScrollTargets) {\n    const autoScroll = () => {\n      Object.keys(props.autoScrollTargets).forEach((hash) => {\n        if (window.location.hash === hash) {\n          const node = document.querySelector(props.autoScrollTargets[hash]);\n          if (node) {\n            scrollInMemorialPrivateContentContainer(node, -240);\n            sidebar.classList.add(\"hidden\");\n          }\n        }\n      });\n    };\n\n    window.onhashchange = autoScroll;\n    autoScroll();\n  }\n\n  const onboardingReentryBanner = document.querySelector(\".exit-onboarding-wizard\");\n  if (onboardingReentryBanner) {\n    const alert = Alert.getOrCreateInstance(onboardingReentryBanner);\n    const closeBannerBtn = onboardingReentryBanner.querySelector(\".btn-close\");\n    closeBannerBtn.addEventListener(\"htmx:afterRequest\", () => {\n      alert.close();\n    });\n  }\n\n  initMemorialFeatureAutocomplete(props.memorialFeatureSearch);\n  initPopovers();\n  initTooltips();\n}\n\nfunction initMemorialPrivateTour(props) {\n  // Instead of relying on anything else here let's just cut off the tour from being\n  // accessible at narrower than 1000 pixels wide. That's when the layout changes,\n  // more or less.\n  if (window.innerWidth < 1000) {\n    return;\n  }\n\n  const { tourData, containerSelector } = props;\n\n  const container = document.querySelector(containerSelector);\n\n  let [currentTourStep] = tourData;\n\n  if (container) {\n    let tourHasBeenInvoked = false;\n    let advanceTour;\n\n    const closeTour = () => {\n      document.querySelectorAll(\".tour-target\").forEach((target) => {\n        target.classList.remove(\"tour-target\");\n      });\n\n      document.querySelectorAll(\".tour-step\").forEach((step) => {\n        step.classList.add(\"d-none\");\n      });\n\n      container.classList.add(\"d-none\");\n    };\n\n    const renderCurrentTourStep = () => {\n      document.querySelectorAll(\".tour-step\").forEach((step) => {\n        step.classList.add(\"d-none\");\n        const tourStepTarget = document.querySelector(\n          `[data-tour-target-for=\"${step.id}\"]`,\n        );\n        if (tourStepTarget) {\n          tourStepTarget.classList.toggle(\n            \"tour-target\",\n            step.id === currentTourStep.id,\n          );\n        }\n      });\n\n      const currentStep = document.getElementById(currentTourStep.id);\n\n      if (currentStep) {\n        if (currentTourStep.alone) {\n          currentStep.style.position = \"absolute\";\n          currentStep.style.width = \"33%\";\n          currentStep.style.left = \"33%\";\n          currentStep.style.top = \"25%\";\n          currentStep.classList.remove(\"d-none\");\n        } else {\n          const tourStepTarget = document.querySelector(\n            `[data-tour-target-for=\"${currentStep.id}\"]`,\n          );\n          if (tourStepTarget) {\n            if (!isInViewport(tourStepTarget)) {\n              tourStepTarget.scrollIntoView(false);\n            }\n\n            // Do the following in a 100ms timeout because `scrollIntView` doesn't\n            // synchronously update the bounding client rect we need.\n            setTimeout(() => {\n              const targetRect = tourStepTarget.getBoundingClientRect();\n\n              const leftEdge = targetRect.left;\n              const rightEdge = targetRect.left + targetRect.width;\n              const topEdge = targetRect.top;\n              const bottomEdge = targetRect.top + targetRect.height;\n\n              // Reset positioning to null state.\n              currentStep.style.position = \"absolute\";\n              currentStep.style.left = null;\n              currentStep.style.right = null;\n              currentStep.style.top = null;\n              currentStep.style.bottom = null;\n\n              let horizontalSpace;\n              let horizontalAnchor;\n              let verticalSpace;\n              let verticalAnchor;\n\n              // Determine if we're placing above or below target.\n              if (topEdge > window.innerHeight - bottomEdge) {\n                // More space on top.\n                verticalSpace = window.innerHeight - topEdge;\n                verticalAnchor = \"bottom\";\n              } else {\n                // More space on bottom.\n                verticalSpace = bottomEdge;\n                verticalAnchor = \"top\";\n              }\n\n              // Determine if we're placing left or right of target.\n              if (leftEdge > window.innerWidth - rightEdge) {\n                // More space to left.\n                horizontalSpace = window.innerWidth - leftEdge;\n                horizontalAnchor = \"right\";\n              } else {\n                // More space to right.\n                horizontalSpace = rightEdge;\n                horizontalAnchor = \"left\";\n              }\n\n              // Determine if we're placing beside or above/below.\n              if (horizontalSpace > verticalSpace) {\n                // Left/right\n                currentStep.style.setProperty(horizontalAnchor, `${horizontalSpace}px`);\n                currentStep.style.top = `${topEdge}px`;\n              } else {\n                // Top/bottom\n                currentStep.style.setProperty(verticalAnchor, `${verticalSpace}px`);\n                currentStep.style.left = `${leftEdge}px`;\n              }\n\n              currentStep.classList.remove(\"d-none\");\n\n              // Correct flowing over bottom\n              if (\n                window.innerHeight - currentStep.getBoundingClientRect().bottom <\n                60\n              ) {\n                currentStep.style.top = null;\n                currentStep.style.bottom = \"0\";\n              }\n            }, 150);\n          } else {\n            advanceTour();\n          }\n        }\n      }\n    };\n\n    advanceTour = () => {\n      const currentIndex = tourData.indexOf(currentTourStep);\n      if (currentIndex + 1 >= tourData.length) {\n        // We're at the end!\n        [currentTourStep] = tourData;\n        closeTour();\n      } else {\n        currentTourStep = tourData[currentIndex + 1];\n        renderCurrentTourStep();\n      }\n    };\n\n    const beginTour = () => {\n      container.classList.remove(\"d-none\");\n      renderCurrentTourStep();\n      tourHasBeenInvoked = true;\n    };\n\n    document.querySelectorAll(\".tour-next\").forEach((nextBtn) => {\n      nextBtn.addEventListener(\"click\", () => {\n        advanceTour();\n      });\n    });\n\n    document.querySelectorAll(\".tour-exit\").forEach((exitBtn) => {\n      exitBtn.addEventListener(\"click\", () => {\n        closeTour();\n      });\n    });\n\n    // Initial timeout\n    const timerFire = () => {\n      if (!tourHasBeenInvoked) {\n        beginTour();\n      }\n    };\n\n    let timeoutId = setTimeout(timerFire, TOUR_DELAY);\n\n    document.addEventListener(\"mousemove\", () => {\n      if (timeoutId) {\n        clearTimeout(timeoutId);\n        timeoutId = null;\n      }\n\n      if (!tourHasBeenInvoked) {\n        timeoutId = setTimeout(timerFire, TOUR_DELAY);\n      }\n    });\n\n    // Don't let the timer fire while page is backgrounded.\n    // Restart it when we're foregrounded if applicable.\n    document.addEventListener(\"visibilitychange\", () => {\n      if (timeoutId) {\n        clearTimeout(timeoutId);\n        timeoutId = null;\n      }\n\n      if (!document.hidden && !tourHasBeenInvoked) {\n        setTimeout(timerFire, TOUR_DELAY);\n      }\n    });\n  }\n}\n\nexport function initMemorialInvitePeople(props) {\n  const personCountSpan = document.querySelector(\".person-count\");\n  const { emptyForm } = props.invitePeopleFormset;\n  const totalFormsField = document.getElementById(\n    props.invitePeopleFormset.totalFormsFieldId,\n  );\n  let totalForms = props.invitePeopleFormset.total;\n\n  const initManagerRelationshipBehavior = (container) => {\n    const relationshipEntryContainer = container.querySelector(\".relationship-entry\");\n    const managerToggles = container.querySelectorAll('[type=\"radio\"]');\n\n    managerToggles.forEach((toggle) => {\n      toggle.addEventListener(\"change\", () => {\n        const showingManager = toggle.checked && toggle.value === \"True\";\n        relationshipEntryContainer.classList.toggle(\"d-none\", !showingManager);\n      });\n    });\n  };\n\n  const initRelationshipOtherBehavior = (selectField, strField) => {\n    if (selectField && strField) {\n      selectField.addEventListener(\"change\", (evt) => {\n        const index = evt.target.selectedIndex;\n        const selected = evt.target.options[index];\n        if (selected.value === \"other\") {\n          strField.classList.remove(\"d-none\");\n        } else {\n          strField.querySelector(\"input\").value = \"\";\n          strField.classList.add(\"d-none\");\n        }\n      });\n    }\n  };\n\n  const updateSubmitButton = () => {\n    const submitButton = document.querySelector(\"#invite-people-btn\");\n    personCountSpan.innerText = `${totalForms} pe${totalForms === 1 ? \"rson\" : \"ople\"}`;\n    if (totalForms === 1) {\n      const nameFields = document.querySelectorAll(\".name-entry input\");\n      const emailField = document.querySelector(\".email-entry input\");\n      submitButton.disabled = !(\n        Array.from(nameFields).every((field) => field.value) && emailField.value\n      );\n    } else {\n      submitButton.disabled = false;\n    }\n  };\n\n  const updateNumberOfForms = (increment) => {\n    totalForms += increment;\n    totalFormsField.value = totalForms;\n    updateSubmitButton();\n  };\n\n  const removeFormHandler = (event) => {\n    const formContainer = event.currentTarget.closest(\".invite-person-survivor-form\");\n    if (formContainer) {\n      updateNumberOfForms(-1);\n      formContainer.remove();\n    }\n  };\n\n  document\n    .querySelectorAll(\".invite-person-survivor-form.first input\")\n    .forEach((input) => {\n      input.addEventListener(\"input\", () => {\n        updateSubmitButton();\n      });\n    });\n\n  document.querySelectorAll(\".invite-person-survivor-form\").forEach((formContainer) => {\n    const selectField = formContainer.querySelector(\"select\");\n    const strField = formContainer.querySelector(\".survivor-relationship-other\");\n    initRelationshipOtherBehavior(selectField, strField);\n    initManagerRelationshipBehavior(formContainer);\n  });\n\n  document.querySelectorAll(\".remove-invite-person-form\").forEach((removeButton) => {\n    removeButton.addEventListener(\"click\", removeFormHandler);\n  });\n\n  const addInvitePersonFormButton = document.querySelector(\".add-invite-person-btn\");\n  if (addInvitePersonFormButton) {\n    addInvitePersonFormButton.addEventListener(\"click\", () => {\n      const container = addInvitePersonFormButton.parentElement;\n      const newIndex = totalForms;\n\n      // Update count state.\n      updateNumberOfForms(1);\n\n      // Create new form.\n      const newFormContainer = document.createElement(\"div\");\n      newFormContainer.classList.add(\"add-survivor-form\");\n      newFormContainer.classList.add(\"invite-person-survivor-form\");\n\n      // Put in HTML and insert into DOM.\n      newFormContainer.innerHTML = emptyForm.replace(/__prefix__/g, newIndex);\n      container.insertBefore(newFormContainer, addInvitePersonFormButton);\n      newFormContainer\n        .querySelector(\".remove-invite-person-form\")\n        .addEventListener(\"click\", removeFormHandler);\n\n      const selectField = newFormContainer.querySelector(\"select\");\n      const strField = newFormContainer.querySelector(\".survivor-relationship-other\");\n      initRelationshipOtherBehavior(selectField, strField);\n      initManagerRelationshipBehavior(newFormContainer);\n    });\n  }\n}\n\nexport function initMemorialPrivateDashboard(props) {\n  const recommendationsWrapper = document.querySelector(\n    \".creator-recommendations-carousel-wrapper\",\n  );\n  if (recommendationsWrapper) {\n    new Glide(recommendationsWrapper.querySelector(\".glide\"), {\n      animationDuration: 600,\n      peek: { before: 20, after: 20 },\n      type: \"carousel\",\n    }).mount({ Swipe });\n  }\n\n  initCityAutocomplete({\n    initialAutocompleteData: props.initialAutocompleteData,\n    cityIdentifierInputId: \"id_memorial-city_slug\",\n    citySearchUrl: props.citySearchUrl,\n  });\n\n  // Community FAQ stuff\n\n  // when someone is typing an answer to an faq, let's show the submit button\n  document.querySelectorAll(\".answer-text\").forEach((answerText) => {\n    const collapseElement = answerText\n      .closest(\".carousel-item\")\n      .querySelector(\".collapse\");\n    answerText.addEventListener(\"focus\", () => {\n      Collapse.getOrCreateInstance(collapseElement, { toggle: false }).show();\n    });\n  });\n\n  const carouselElement = document.querySelector(\n    \".memorial-community-questions .carousel\",\n  );\n  if (carouselElement) {\n    new Carousel(carouselElement);\n\n    // hide the submit button when navigating the faq carousel\n    carouselElement\n      .querySelectorAll(\".previous-btn, .next-btn, .carousel-indicators\")\n      .forEach((notAnswerText) => {\n        notAnswerText.addEventListener(\"click\", () => {\n          const openCollapseElement = notAnswerText\n            .closest(\".carousel\")\n            .querySelector(\".collapse.show\");\n          if (openCollapseElement) {\n            Collapse.getOrCreateInstance(openCollapseElement, { toggle: false }).hide();\n          }\n        });\n      });\n  }\n\n  initSuccessModal();\n\n  let hasSubmitted = false;\n  const form = document.querySelector(\".memorial-community-questions form\");\n  if (form) {\n    form.addEventListener(\"submit\", (event) => {\n      event.preventDefault();\n\n      const submitBtn = [...form.querySelectorAll(\"button\")].find((element) =>\n        isVisible(element),\n      );\n      if (submitBtn) {\n        document.getElementById(\"id_submitted_question_index\").value = submitBtn.value;\n        if (!hasSubmitted) {\n          hasSubmitted = true;\n          form.submit();\n        }\n      }\n    });\n  }\n\n  initThankYouNoteCheckboxes();\n\n  const ringContainer = document.querySelector(\".checklist-progress-container\");\n  if (ringContainer) {\n    new ProgressRing(ringContainer, props.checklistProgress);\n  }\n\n  if (props.tourProps) {\n    initMemorialPrivateTour(props.tourProps);\n  }\n\n  if (props.invitePeopleFormset) {\n    initMemorialInvitePeople(props);\n  }\n}\n\nfunction setupDeceasedTitleAndSuffix(props) {\n  const { titleInputId, titleOtherStrInputId, suffixInputId, suffixOtherStrInputId } =\n    props;\n\n  if (titleInputId && titleOtherStrInputId && suffixInputId && suffixOtherStrInputId) {\n    // Deceased title, e.g. Honorable\n    const titleInput = document.querySelector(`#${props.titleInputId}`);\n    const titleOtherStrContainer = document.querySelector(\n      `#${props.titleOtherStrInputId}`,\n    ).parentNode;\n    titleInput.addEventListener(\"change\", (event) => {\n      if (event.target.value === \"other\") {\n        titleOtherStrContainer.classList.remove(\"d-none\");\n      } else {\n        titleOtherStrContainer.classList.add(\"d-none\");\n      }\n    });\n\n    // Deceased suffix, e.g. IV\n    const suffixInput = document.querySelector(`#${props.suffixInputId}`);\n    const suffixOtherStrContainer = document.querySelector(\n      `#${props.suffixOtherStrInputId}`,\n    ).parentNode;\n    suffixInput.addEventListener(\"change\", (event) => {\n      if (event.target.value === \"other\") {\n        suffixOtherStrContainer.classList.remove(\"d-none\");\n      } else {\n        suffixOtherStrContainer.classList.add(\"d-none\");\n      }\n    });\n  }\n}\n\nexport function initMemorialDeceasedForm(props) {\n  setupDeceasedTitleAndSuffix(props);\n\n  // Deceased nicknaming\n  const addNickname = document.querySelector(\".add-nickname\");\n  addNickname.addEventListener(\"click\", () => {\n    addNickname.nextElementSibling.classList.remove(\"d-none\");\n    addNickname.classList.add(\"d-none\");\n  });\n\n  // DOB/DOD\n  const dateOfDeathInputs = document.querySelectorAll(\n    \".date-of-death-input-group select\",\n  );\n\n  function disableDateOfDeathPicker() {\n    dateOfDeathInputs.forEach((currentInput) => {\n      currentInput.selectedIndex = null;\n      currentInput.classList.add(\"disabled-input\");\n      currentInput.removeAttribute(\"required\");\n    });\n  }\n\n  function enableDateOfDeathPicker() {\n    dateOfDeathInputs.forEach((currentInput) => {\n      currentInput.classList.remove(\"disabled-input\");\n      currentInput.setAttribute(\"required\", \"\");\n    });\n  }\n\n  const notYetPassed = document.getElementById(props.notYetPassedInputId);\n  notYetPassed.addEventListener(\"change\", () => {\n    if (notYetPassed.checked) {\n      disableDateOfDeathPicker();\n    } else {\n      enableDateOfDeathPicker();\n    }\n  });\n\n  dateOfDeathInputs.forEach((currentInput) => {\n    currentInput.addEventListener(\"click\", () => {\n      if (notYetPassed.checked) {\n        enableDateOfDeathPicker();\n        notYetPassed.checked = false;\n      }\n    });\n  });\n\n  if (notYetPassed.checked) {\n    disableDateOfDeathPicker();\n  }\n\n  // Relationship (where relevant)\n  if (props.relationshipSelectId) {\n    const relationshipSelect = document.getElementById(props.relationshipSelectId);\n    const relationshipOther = document.querySelector(\".relationship-other\");\n\n    if (relationshipSelect && relationshipOther) {\n      relationshipSelect.addEventListener(\"change\", (evt) => {\n        const index = evt.target.selectedIndex;\n        const selected = evt.target.options[index];\n        if (selected.value === \"other\") {\n          relationshipOther.classList.remove(\"d-none\");\n        } else {\n          relationshipOther.querySelector(\"input\").value = \"\";\n          relationshipOther.classList.add(\"d-none\");\n        }\n      });\n    }\n  }\n\n  initGoogleAutocomplete({\n    element: document.getElementById(\"id_deceased-location_str\"),\n    options: {\n      types: [\"(cities)\"],\n    },\n  });\n}\n\nexport function initMemorialPrivateBasicInformation(props) {\n  initMemorialDeceasedForm(props);\n\n  const photosUploadedBanner = document.querySelector(\".photos-uploaded-banner\");\n\n  const onPhotosUpdated = () => {\n    if (photosUploadedBanner) {\n      photosUploadedBanner.classList.remove(\"d-none\");\n    }\n  };\n\n  // Initialize multi-photo uploader.\n  const multiPhotoUploader = new DeceasedPhotoUploader({\n    onPhotosUpdated,\n    ...props.deceasedPhotoUploaderProps,\n  });\n\n  const photosSection = document.querySelector(\".memorial-deceased-form-photos\");\n  if (photosSection) {\n    photosSection.addEventListener(\"click\", (e) => {\n      // We are clicking a layout-selector element.\n      const layoutSelector = e.target.closest(\".layout-selector\");\n      if (layoutSelector !== null) {\n        photosUploadedBanner.classList.add(\"d-none\");\n        multiPhotoUploader.show(false);\n      }\n    });\n  }\n}\n\nexport function initMemorialPrivatePassing(props) {\n  initBusinessAssociationForm(props);\n  initCauseOfDeathAutocomplete(props.causeOfDeathSearch);\n  initOrganDonationForm(props.organDonationSearch);\n\n  initGoogleAutocomplete({\n    element: document.getElementById(\"id_business_association-remains_location\"),\n    metadataElement: document.getElementById(\n      \"id_business_association-remains_location_metadata\",\n    ),\n    options: {\n      types: [\"establishment\", \"geocode\"],\n    },\n  });\n}\n\nfunction addDeliveryLocationAutocomplete(\n  element,\n  metadataElement,\n  alwaysBlockReturnKeySubmit,\n) {\n  initGoogleAutocomplete({\n    element,\n    metadataElement,\n    options: {\n      componentRestrictions: { country: [\"ca\", \"us\"] },\n      types: [\"address\"],\n    },\n    alwaysBlockReturnKeySubmit,\n  });\n}\n\nfunction initDeliveryAddressesOnLoad(props) {\n  const formsetContainer = document.querySelector(\n    \".delivery-addresses-formset-container\",\n  );\n  const inputElements = formsetContainer.getElementsByClassName(\n    \"location-autocomplete\",\n  );\n  const addAddressContainer = formsetContainer.querySelector(\".add-address-container\");\n\n  const deliveryAddressForms = document.querySelector(\".delivery-address-forms\");\n  const totalFormCountInput = document.getElementById(\n    props.deliveryAddressesTotalFormCountInputId,\n  );\n  let totalFormCount = props.deliveryAddressesTotalFormCount;\n\n  function addRemoveAddressHandler(removeAddressButton) {\n    removeAddressButton.addEventListener(\"click\", () => {\n      removeAddressButton.querySelector('input[type=\"checkbox\"]').checked = true;\n      removeAddressButton.parentElement.classList.add(\"d-none\");\n      const formIdField =\n        removeAddressButton.previousElementSibling.querySelector(\n          'input[type=\"hidden\"]',\n        );\n      if (formIdField && !formIdField.value) {\n        totalFormCount -= 1;\n        totalFormCountInput.value = totalFormCount;\n        removeAddressButton.remove();\n      }\n    });\n  }\n\n  const addAddressButton = addAddressContainer.querySelector(\"button\");\n  addAddressButton.addEventListener(\"click\", () => {\n    totalFormCount += 1;\n    totalFormCountInput.value = totalFormCount;\n    deliveryAddressForms.insertAdjacentHTML(\n      \"beforeend\",\n      props.emptyDeliveryAddressForm.replace(/__prefix__/g, totalFormCount - 1),\n    );\n\n    addDeliveryLocationAutocomplete(\n      inputElements[totalFormCount - 1],\n      document.getElementById(\n        `id_delivery_addresses-${totalFormCount - 1}-location_metadata`,\n      ),\n      true,\n    );\n\n    addRemoveAddressHandler(\n      deliveryAddressForms.lastElementChild.querySelector(\".remove-address\"),\n    );\n  });\n\n  const allowFlowersToggle = document.getElementById(\n    props.preferencesFormFieldIds.allowFlowers,\n  );\n  allowFlowersToggle.addEventListener(\"change\", () => {\n    if (allowFlowersToggle.checked) {\n      formsetContainer.classList.remove(\"d-none\");\n    } else {\n      formsetContainer.classList.add(\"d-none\");\n    }\n  });\n\n  for (let i = 0; i < inputElements.length; i += 1) {\n    addDeliveryLocationAutocomplete(\n      inputElements[i],\n      document.getElementById(`id_delivery_addresses-${i}-location_metadata`),\n    );\n  }\n\n  deliveryAddressForms\n    .querySelectorAll(\".remove-address\")\n    .forEach((removeAddressButton) => {\n      addRemoveAddressHandler(removeAddressButton);\n    });\n}\n\nexport function initMemorialPrivateGifts(props) {\n  initFundraiserForm(props, (clv) => {\n    props.fundraisingGoalCleave = clv;\n  });\n\n  const { causeStoryForm } = props;\n\n  if (props.isNewCause) {\n    const causeStoryInput = document.querySelector(\n      `#${causeStoryForm.fields.causeStory}`,\n    );\n    if (causeStoryInput) {\n      const val = causeStoryInput.value;\n      causeStoryInput.defaultValue = \"must-edit-me!\";\n      causeStoryInput.value = val;\n    }\n  }\n\n  const clearFundraisingUser = document.querySelector(\".clear-fundraising-user-link\");\n  if (clearFundraisingUser) {\n    clearFundraisingUser.addEventListener(\"click\", () => {\n      const input = document.getElementById(clearFundraisingUser.dataset.clearInput);\n      input.value = 1;\n\n      const form = input.closest(\"form\");\n      if (form) {\n        form.requestSubmit();\n      }\n    });\n  }\n\n  document\n    .querySelectorAll(\".show-error-on-click\")\n    .forEach((showErrorOnClickElement) => {\n      showErrorOnClickElement.addEventListener(\n        \"click\",\n        () => {\n          const disabledFieldName = showErrorOnClickElement.dataset.disabledName;\n\n          const errorList = getNextSiblingMatchingSelector(\n            showErrorOnClickElement,\n            \".errorlist\",\n          );\n          if (errorList) {\n            const errorMessage = errorMessages[disabledFieldName];\n            showErrorOnClickElement.parentElement.append(\n              ...generateElements(\n                `<ul class=\"errorlist\"><li>${errorMessage}</li></ul>`,\n              ),\n            );\n            errorList.classList.remove(\"d-none\");\n          }\n\n          const eventAction = eventActions[disabledFieldName];\n          trackCustomUserAction(\n            window.location.href,\n            \"memorial edit info\",\n            eventAction,\n          );\n        },\n        { once: true },\n      );\n    });\n\n  initMemorialGiftPremiumControls({\n    disableMemorialGiftsId: props.premiumForm.fields.disableMemorialGifts,\n    disableMemorialGiftListDisplayId:\n      props.premiumForm.fields.disableMemorialGiftListDisplay,\n    disableMemorialGiftContributionsDisplayId:\n      props.premiumForm.fields.disableMemorialGiftContributionsDisplay,\n    ...props,\n  });\n\n  props.charityFundraiserForms.forEach((charityFundraiserForm) => {\n    const selfServeCheckbox = document.querySelector(\n      `#${charityFundraiserForm.fields.selfServeDonations}`,\n    );\n    if (selfServeCheckbox) {\n      const parentBodyCard = selfServeCheckbox.closest(\".body-card\");\n      const customCharityFinePrint = parentBodyCard.querySelector(\n        \".custom-charity-fine-print\",\n      );\n      const selfServeCharityFinePrint = parentBodyCard.querySelector(\n        \".self-serve-charity-fine-print\",\n      );\n      const fundraisingManagerForm = parentBodyCard.querySelector(\n        \".fundraising-user-selection\",\n      );\n      const selfServeChanged = () => {\n        selfServeCharityFinePrint.classList.toggle(\n          \"d-none\",\n          !selfServeCheckbox.checked,\n        );\n        customCharityFinePrint.classList.toggle(\"d-none\", selfServeCheckbox.checked);\n\n        if (fundraisingManagerForm) {\n          fundraisingManagerForm.classList.toggle(\"d-none\", !selfServeCheckbox.checked);\n        }\n      };\n\n      selfServeCheckbox.addEventListener(\"change\", selfServeChanged);\n      selfServeChanged();\n    }\n  });\n\n  initDeliveryAddressesOnLoad(props);\n\n  initMemorialUpdateEdits();\n}\n\nexport function initMemorialPrivateFavorites() {\n  initEditDropdowns();\n}\n\nfunction initUserBlocking(props) {\n  const handleListUpdate = (searchEvent) => {\n    const searchField = searchEvent.target;\n    const container = searchField.closest(\".list-container\");\n    const scrollContainer = container.querySelector(\".user-scroll-container\");\n    const emptyElement = container.querySelector(\".empty\");\n    const noSearch = emptyElement.querySelector(\".no-search\");\n    const emptySearch = emptyElement.querySelector(\".empty-search\");\n\n    let showEmpty = true;\n\n    container.querySelectorAll(\".blockable-user\").forEach((user) => {\n      const searchContent = user.getAttribute(\"data-search-string\").toLowerCase();\n      if (searchContent.includes(searchField.value.toLowerCase())) {\n        showEmpty = false;\n        user.classList.remove(\"d-none\");\n      } else {\n        user.classList.add(\"d-none\");\n      }\n    });\n\n    if (showEmpty) {\n      emptyElement.classList.remove(\"d-none\");\n      scrollContainer.classList.add(\"d-none\");\n\n      if (searchField.value) {\n        emptySearch.classList.remove(\"d-none\");\n        noSearch.classList.add(\"d-none\");\n      } else {\n        emptySearch.classList.add(\"d-none\");\n        noSearch.classList.remove(\"d-none\");\n      }\n    } else {\n      emptyElement.classList.add(\"d-none\");\n      scrollContainer.classList.remove(\"d-none\");\n    }\n  };\n\n  const userSearchingContainers = document.querySelectorAll(\n    \".user-blocking-container > div\",\n  );\n  if (userSearchingContainers) {\n    userSearchingContainers.forEach((container) => {\n      const searchField = container.querySelector(\".search-field\");\n      searchField.addEventListener(\"keyup\", handleListUpdate);\n      searchField.addEventListener(\"paste\", handleListUpdate);\n      handleListUpdate({ target: searchField });\n    });\n  }\n\n  const userBlockButtons = document.querySelectorAll(\".block-user-button\");\n  const blockedUserList = document.querySelector(\n    \".blocked-user-list .user-scroll-container\",\n  );\n  const unblockedUserList = document.querySelector(\n    \".unblocked-user-list .user-scroll-container\",\n  );\n\n  userBlockButtons.forEach((blockBtn) => {\n    blockBtn.addEventListener(\"click\", async () => {\n      const revert = handleAjaxFormSubmitProtection(blockBtn);\n      const isBlocking = blockBtn.getAttribute(\"data-block\") === \"1\";\n      const listItem = blockBtn.closest(\".list-group-item\");\n\n      try {\n        const response = await requests.post(props.blockUrl, {\n          user: blockBtn.getAttribute(\"data-block-user\"),\n          block: isBlocking,\n        });\n\n        if (!response.ok) {\n          throw new ResponseError(response);\n        }\n      } catch {\n        revert();\n        return;\n      }\n\n      blockBtn.innerText = isBlocking ? \"Unblock\" : \"Block\";\n      blockBtn.setAttribute(\"data-block\", isBlocking ? \"0\" : \"1\");\n      const list = isBlocking ? blockedUserList : unblockedUserList;\n      list.appendChild(listItem);\n\n      document.querySelectorAll(\".search-field\").forEach((f) => {\n        handleListUpdate({ target: f });\n      });\n      revert();\n    });\n  });\n}\n\nfunction initRelatedPhotoUpload(props) {\n  const editRelatedPhotoLinks = document.querySelectorAll(\".edit-related-photo-link\");\n  const uploadRelatedPhotoPersonField = document.querySelector(\n    'input[name=\"_upload_related_person_photo\"]',\n  );\n  const uploadForm = uploadRelatedPhotoPersonField.closest(\"form\");\n  const fileInput = uploadForm.querySelector('input[type=\"file\"]');\n\n  editRelatedPhotoLinks.forEach((link) => {\n    link.addEventListener(\"click\", () => {\n      fileInput.dataset.toPerson = link.dataset.toPerson;\n      if (link.dataset.memorial) {\n        fileInput.dataset.memorial = link.dataset.memorial;\n      } else {\n        fileInput.removeAttribute(\"data-memorial\");\n      }\n      fileInput.click();\n    });\n  });\n\n  initPhotoCropper({\n    photoInput: document.querySelector(\n      `#${props.relatedPhotoForm.fields.rawPublicProfilePhoto}`,\n    ),\n    xInput: document.querySelector(`#${props.relatedPhotoForm.fields.x}`),\n    yInput: document.querySelector(`#${props.relatedPhotoForm.fields.y}`),\n    heightInput: document.querySelector(`#${props.relatedPhotoForm.fields.height}`),\n    widthInput: document.querySelector(`#${props.relatedPhotoForm.fields.width}`),\n    cropperOptions: {\n      viewMode: 0,\n      cropBoxMovable: false,\n      cropBoxResizable: false,\n      dragMode: \"move\",\n      minCropBoxWidth: 373,\n      minCropBoxHeight: 280,\n      minCanvasHeight: 280,\n      aspectRatio: 1,\n    },\n    cropButtonSubmits: true,\n    onComplete: () => {\n      uploadRelatedPhotoPersonField.value = fileInput.dataset.toPerson;\n      uploadForm.submit();\n    },\n    onModalShown: (cropperInstance) => {\n      if (fileInput.dataset.memorial) {\n        cropperInstance.setAspectRatio(4 / 3);\n      } else {\n        cropperInstance.setAspectRatio(1.0);\n      }\n    },\n  });\n}\n\nfunction initRelativeAwaitingConfirmationTips() {\n  let firstSection = null;\n  const awaitingConfirmationSectionAlerts = document.querySelectorAll(\n    \"a.awaiting-confirmation-alert\",\n  );\n  const awaitingConfirmationSections = document.querySelectorAll(\".added-by-others\");\n  if (awaitingConfirmationSections.length) {\n    firstSection = awaitingConfirmationSections[0];\n  }\n\n  awaitingConfirmationSectionAlerts.forEach((awaitingConfirmationSectionAlert) => {\n    if (awaitingConfirmationSectionAlert && firstSection) {\n      awaitingConfirmationSectionAlert.href = \"#\";\n      awaitingConfirmationSectionAlert.addEventListener(\"click\", () => {\n        scrollInMemorialPrivateContentContainer(firstSection);\n      });\n    }\n  });\n}\n\nexport function initMemorialPrivateFamily(props) {\n  initRelationshipForms(props);\n  initRelatedPhotoUpload(props);\n  initRelativeAwaitingConfirmationTips();\n  initDeceasedSearchAutocomplete(props.followerFormProps);\n}\n\nexport function initMemorialPrivateEvents(props) {\n  const deleteEventCallbacks = [];\n  initEditEvents(props, deleteEventCallbacks);\n  initEditEventsOnLoad(props, deleteEventCallbacks);\n  initTimezoneSelector(props.forms.timezone.fields.timezone);\n}\n\nexport function initMemorialObituary(props) {\n  if (props && props.placeholderOverride) {\n    const obituaryTextArea = document.querySelector(\".edit-obituary textarea\");\n    if (obituaryTextArea) {\n      obituaryTextArea.setAttribute(\"placeholder\", props.placeholderOverride);\n    }\n  }\n\n  const autoSaves = [];\n  document.querySelectorAll(\".el-autosave\").forEach((el) => {\n    autoSaves.push(new AutoSaveTextField(el));\n  });\n\n  const showTemplateSelectorButton = document.querySelector(\".show-templates\");\n  const templateSelectorContainer = document.querySelector(\n    \".obituary-templates-container-container\",\n  );\n\n  if (showTemplateSelectorButton && templateSelectorContainer) {\n    templateSelectorContainer.classList.add(\"d-none\");\n\n    showTemplateSelectorButton.addEventListener(\"click\", () => {\n      templateSelectorContainer.classList.remove(\"d-none\");\n    });\n  }\n}\n\nexport function initMemorialNote(props) {\n  // Memorial note template selection\n  const noteInput = document.getElementById(props.noteInputId);\n  const noteTemplatesContainer = document.querySelector(\".note-templates-container\");\n  const templatesData = props.noteTemplates;\n  initUGCTemplates(\n    noteTemplatesContainer,\n    noteInput,\n    templatesData,\n    null,\n    true,\n    null,\n    false,\n  );\n}\n\nfunction initPasswordProtect() {\n  const passwordProtectToggle = document.querySelector(\n    \".password-protect-toggle input\",\n  );\n  const passwordProtectFieldContainer = document.querySelector(\n    \".password-field-container\",\n  );\n  if (passwordProtectToggle && passwordProtectFieldContainer) {\n    passwordProtectToggle.addEventListener(\"change\", () => {\n      if (passwordProtectToggle.checked) {\n        passwordProtectFieldContainer.classList.remove(\"d-none\");\n      } else {\n        passwordProtectFieldContainer.classList.add(\"d-none\");\n      }\n    });\n  }\n}\n\nexport async function initMemorialPrivatePremium(props) {\n  initPasswordProtect();\n  initMemorialGiftPremiumControls(props);\n  initUserBlocking(props);\n\n  await initPayableCheckout(props);\n  await initAddPaymentMethod(props);\n\n  document.body.addEventListener(\"htmx:afterSettle\", (evt) => {\n    const premiumForm =\n      evt.detail.elt.id === \"premium-checkout\" ? evt.detail.elt : null;\n    if (premiumForm) {\n      registerFormSubmitProtection(premiumForm);\n    }\n  });\n}\n\nexport function initMemorialPrivateSettings(props) {\n  initPasswordProtect();\n\n  document.querySelectorAll(\".remove-manager-link\").forEach((link) => {\n    link.addEventListener(\"click\", async () => {\n      if (window.confirm(\"Are you sure you want to remove this manager?\")) {\n        const deleteUrl = link.getAttribute(\"data-delete-url\");\n\n        link.innerHTML = \"Removing...\";\n        try {\n          const response = await requests.delete(deleteUrl);\n          if (!response.ok) {\n            throw new ResponseError(response);\n          }\n        } catch {\n          link.innerHTML = \"Removing failed.\";\n          return;\n        }\n\n        link.closest(\".list-group-item\").remove();\n      }\n    });\n  });\n\n  const themeOptions = document.querySelectorAll(\".memorial-theme-option\");\n  const themeNames = Array.from(themeOptions).map(\n    (themeOption) => themeOption.dataset.themeName,\n  );\n  themeOptions.forEach((themeOption) => {\n    const radio = themeOption.querySelector('input[type=\"radio\"]');\n    if (radio) {\n      radio.addEventListener(\"change\", () => {\n        themeNames.forEach((name) => {\n          document.body.classList.toggle(\n            name,\n            name === radio.closest(\".memorial-theme-option\").dataset.themeName &&\n              radio.checked,\n          );\n        });\n        document.body.classList.add(\"theme\");\n      });\n    }\n  });\n\n  initTimezoneSelector(props.forms.timezone.fields.timezone);\n}\n\n/**\n * Initialize the legacy `/memorial/<slug>/edit/` page. The Django view provides a map\n * from \"legacy\" hash points (#edit-family, for example) to the reversed URLs for their\n * new-private-mode view counterparts. This JS simply takes the `hash` from the current\n * location (if it exists) and issues a client-side redirect to that URL, falling back\n * to a default URL `/memorial/<slug>/` if nothing exists in that map.\n * This has to be done in JS/client-side because not all browsers send #hash fragments\n * to the server on request, and as such we can't issue the redirect logic from inside\n * of Django.\n *\n * @param {object} props - Props from Django\n */\nexport function initLegacyEdit(props) {\n  window.location.href = props.urls[window.location.hash] || props.defaultUrl;\n}\n\nexport function initFeedbackForm(props) {\n  const feedbackReasonField = document.getElementById(props.reasonCommentFieldId);\n  const feedbackReasonChoices = document.querySelectorAll(\n    `input[name=\"${props.reasonInputName}\"]`,\n  );\n\n  feedbackReasonChoices.forEach((choice) => {\n    choice.addEventListener(\"change\", () => {\n      feedbackReasonField.setAttribute(\n        \"placeholder\",\n        props.reasonCommentFormPrompts[choice.value],\n      );\n      feedbackReasonField.classList.remove(\"d-none\");\n    });\n  });\n}\n\nexport function initMemorialPrivateNoteAndUpdates(props) {\n  const noteInput = document.getElementById(props.noteInputId);\n  const noteTemplatesContainer = document.querySelector(\".note-templates-container\");\n  const templatesData = props.noteTemplates;\n  initUGCTemplates(\n    noteTemplatesContainer,\n    noteInput,\n    templatesData,\n    null,\n    true,\n    null,\n    false,\n  );\n\n  initMemorialUpdateEdits();\n}\n\nexport function initMemorialPrivateBelongings(props) {\n  initProductPhotoBlur();\n\n  const editorContainer = document.querySelector(\".modal-belonging-editor\");\n  if (editorContainer) {\n    const invokeEditor = (editor) => (event) => {\n      if (event.currentTarget.classList.contains(\"add-belonging\")) {\n        editor.showForBelonging(null);\n      } else {\n        const { name, description, isPublished, isClaimed, belonging, photo } =\n          event.currentTarget.dataset;\n\n        editor.showForBelonging({\n          name,\n          description,\n          photo,\n          isPublished: isPublished === \"true\",\n          isClaimed: isClaimed === \"true\",\n          id: belonging,\n        });\n      }\n    };\n\n    const onBelongingChanged = (newBelonging, editor) => {\n      const listedBelongings = document.querySelector(\n        \".listed-belongings .belongings-list\",\n      );\n      const unlistedBelongings = document.querySelector(\n        \".unlisted-belongings .belongings-list\",\n      );\n\n      const existing = document.querySelector(\n        `.belonging[data-belonging=\"${newBelonging.id}\"]`,\n      );\n\n      const belongingsList = newBelonging.is_published\n        ? listedBelongings\n        : unlistedBelongings;\n\n      let insertBeforeTarget = belongingsList.querySelector(\".belonging.add-belonging\");\n\n      if (existing) {\n        if (existing.parentElement === belongingsList) {\n          insertBeforeTarget = existing.nextSibling;\n        }\n        existing.remove();\n      }\n\n      const newItemWrapper = document.createElement(\"div\");\n      const truncatedDescription = `${newBelonging.description.slice(0, 30)}${newBelonging.description.length > 30 ? \"...\" : \"\"}`;\n      newItemWrapper.innerHTML = props.emptyListItem\n        .replace(/__name__/g, newBelonging.name)\n        .replace(/__description__/g, truncatedDescription)\n        .replace(/__photo__/g, newBelonging.photo);\n      const listItem = newItemWrapper.firstChild;\n      listItem.classList.toggle(\"claimed\", newBelonging.is_claimed);\n      listItem.dataset.belonging = newBelonging.id;\n      listItem.dataset.name = newBelonging.name;\n      listItem.dataset.description = newBelonging.description;\n      listItem.dataset.isPublished = newBelonging.is_published ? \"true\" : \"false\";\n      listItem.dataset.isClaimed = newBelonging.is_claimed ? \"true\" : \"false\";\n\n      const claimedBadge = listItem.querySelector(\".claimed-badge\");\n      if (claimedBadge) {\n        claimedBadge.classList.toggle(\"d-none\", !newBelonging.is_claimed);\n      }\n\n      belongingsList.insertBefore(listItem, insertBeforeTarget);\n\n      listItem.addEventListener(\"click\", invokeEditor(editor));\n    };\n\n    const belongingEditor = new BelongingEditor(editorContainer, {\n      ...props.editorProps,\n      onBelongingChanged,\n    });\n\n    document.querySelectorAll(\".belonging\").forEach((belongingItem) => {\n      belongingItem.addEventListener(\"click\", invokeEditor(belongingEditor));\n    });\n  }\n\n  const notifyCheckboxContainerForm = document.querySelector(\n    \".notify-subscribers-toggle\",\n  );\n  if (notifyCheckboxContainerForm) {\n    const notifyCheckbox = notifyCheckboxContainerForm.querySelector(\n      'input[type=\"checkbox\"]',\n    );\n    notifyCheckbox.addEventListener(\"click\", () => {\n      notifyCheckbox.parentElement.classList.add(\"d-none\");\n\n      const spinnerContainer =\n        notifyCheckboxContainerForm.querySelector(\".spinner-container\");\n      spinnerContainer.classList.remove(\"d-none\");\n\n      notifyCheckboxContainerForm.submit();\n    });\n  }\n}\n\nexport function initPhotoArchiveRequest() {\n  const photoArchiveRequestError = document.querySelector(\n    \".photo-archive-request-error\",\n  );\n  if (photoArchiveRequestError) {\n    document.body.addEventListener(\"htmx:responseError\", () => {\n      photoArchiveRequestError.classList.remove(\"d-none\");\n    });\n  }\n}\n\nexport function initMemorialPrivateCommunityContent(props) {\n  initUserBlocking(props);\n  initPhotoArchiveRequest();\n}\n\nexport function initAIObituaryComposerForm() {\n  const composerForm = document.querySelector(\".obituary-composer-form\");\n\n  const scrollFix = () => {\n    if (composerForm) {\n      const editContent = document.querySelector(\".edit-memorial-content\");\n      if (editContent) {\n        setTimeout(() => {\n          editContent.parentNode.parentNode.scrollIntoView(true);\n        }, 100);\n      } else {\n        document.body.scrollIntoView(true);\n      }\n    }\n  };\n\n  document.body.addEventListener(\"htmx:beforeRequest\", () => {\n    scrollFix();\n  });\n\n  scrollFix();\n\n  if (composerForm) {\n    const locationAutocompleteFields = composerForm.querySelectorAll(\n      '[data-google-autocomplete=\"location\"]',\n    );\n    const placeAutocompleteFields = composerForm.querySelectorAll(\n      '[data-google-autocomplete=\"place\"]',\n    );\n\n    if (typeof window.google === \"object\" && typeof window.google.maps === \"object\") {\n      locationAutocompleteFields.forEach((field) => {\n        initGoogleAutocomplete({ element: field, options: { types: [\"(cities)\"] } });\n      });\n\n      placeAutocompleteFields.forEach((field) => {\n        initGoogleAutocomplete({\n          element: field,\n          options: {\n            types: [\"establishment\", \"geocode\"],\n          },\n        });\n      });\n    }\n\n    const handleSchoolNameInput = (event) => {\n      const existingNameInputs = Array.from(\n        document.querySelectorAll(\".school-name-input\"),\n      );\n\n      if (event.currentTarget === existingNameInputs.slice(-1)[0]) {\n        if (event.currentTarget.value) {\n          const container = event.currentTarget.closest(\".d-flex\");\n          const cloned = container.cloneNode(true);\n          const nameInput = cloned.querySelector(\".school-name-input\");\n          nameInput.value = \"\";\n          nameInput.setAttribute(\"id\", `id_school_name_${existingNameInputs.length}`);\n          nameInput.setAttribute(\"name\", `school_name_${existingNameInputs.length}`);\n          nameInput.addEventListener(\"change\", handleSchoolNameInput);\n\n          initGoogleAutocomplete({\n            element: nameInput,\n            options: {\n              types: [\"establishment\", \"geocode\"],\n            },\n          });\n\n          const yearInput = cloned.querySelector(\".school-year-input\");\n          yearInput.value = \"\";\n          yearInput.setAttribute(\"id\", `id_school_year_${existingNameInputs.length}`);\n          yearInput.setAttribute(\"name\", `school_year_${existingNameInputs.length}`);\n\n          container.parentNode.appendChild(cloned);\n        }\n      } else {\n        const container = event.currentTarget.closest(\".d-flex\");\n        const parent = container.parentNode;\n        container.remove();\n\n        // Renumber the inputs.\n        parent.querySelectorAll(\":scope > .d-flex\").forEach((childNode, idx) => {\n          const nameInput = childNode.querySelector(\".school-name-input\");\n          nameInput.setAttribute(\"id\", `id_school_name_${idx}`);\n          nameInput.setAttribute(\"name\", `school_name_${idx}`);\n\n          const yearInput = childNode.querySelector(\".school-year-input\");\n          yearInput.setAttribute(\"id\", `id_school_year_${idx}`);\n          yearInput.setAttribute(\"name\", `school_year_${idx}`);\n        });\n      }\n    };\n\n    const schoolNameInputs = document.querySelectorAll(\".school-name-input\");\n\n    schoolNameInputs.forEach((input) => {\n      input.addEventListener(\"change\", handleSchoolNameInput);\n    });\n  }\n}\n","import { loadStripe } from \"@stripe/stripe-js\";\n\nimport {\n  handleAjaxFormSubmitProtection,\n  sendBrowserAgnosticEvent,\n} from \"../core/utils\";\n\nexport default async function initAddPaymentMethod(props) {\n  const stripe = await loadStripe(props.stripePublishableKey);\n\n  document.body.addEventListener(\"initAddPaymentMethod\", (event) => {\n    const paymentMethodForm = document.getElementById(\"manage-payment-method\");\n    if (!paymentMethodForm) {\n      return;\n    }\n\n    document\n      .querySelectorAll('input[name=\"payment_method\"][type=\"radio\"]')\n      .forEach((radio) => {\n        radio.addEventListener(\"change\", () => {\n          if (radio.checked) {\n            document\n              .querySelectorAll(\".payment-method-select-listener\")\n              .forEach((listener) => {\n                window.htmx.trigger(listener, \"paymentMethodSelected\");\n              });\n          }\n        });\n\n        if (radio.checked) {\n          document\n            .querySelectorAll(\".payment-method-select-listener\")\n            .forEach((listener) => {\n              window.htmx.trigger(listener, \"paymentMethodSelected\");\n            });\n        }\n      });\n\n    const elements = stripe.elements({\n      appearance: {\n        theme: \"stripe\",\n        variables: {\n          colorPrimary:\n            getComputedStyle(document.body).getPropertyValue(\"--primary-brand-color\") ||\n            \"#7f465c\",\n          fontFamily: \"Lato\",\n        },\n        labels: \"floating\",\n      },\n      clientSecret: event.detail.clientSecret,\n      fonts: [{ cssSrc: \"https://fonts.googleapis.com/css?family=Lato:300,400,700\" }],\n      loader: \"always\",\n    });\n\n    const style = {\n      base: {\n        fontFamily: \"Lato\",\n        fontSize: \"18px\",\n        \"::placeholder\": {\n          color: \"#8e8e8e\",\n        },\n      },\n      invalid: {\n        color: \"#c30c30\",\n      },\n    };\n\n    // Create instances of the cardNumber, cardExpiry and cardCvc Elements.\n    const cardNumber = elements.create(\"cardNumber\", { style });\n    const cardExpiry = elements.create(\"cardExpiry\", { style });\n    const cardCvc = elements.create(\"cardCvc\", { style });\n\n    // Mount them.\n    cardNumber.mount(\"#stripe-card-element\");\n    cardExpiry.mount(\"#stripe-exp-element\");\n    cardCvc.mount(\"#stripe-cvc-element\");\n\n    cardNumber.addEventListener(\"change\", (evt) => {\n      const displayError = document.getElementById(\"stripe-card-errors\");\n      if (evt.error) {\n        displayError.textContent = evt.error.message;\n        displayError.classList.remove(\"d-none\");\n      } else {\n        displayError.textContent = \"\";\n        displayError.classList.add(\"d-none\");\n      }\n    });\n\n    cardExpiry.addEventListener(\"change\", (evt) => {\n      const displayError = document.getElementById(\"stripe-exp-errors\");\n      if (evt.error) {\n        displayError.textContent = evt.error.message;\n        displayError.classList.remove(\"d-none\");\n      } else {\n        displayError.textContent = \"\";\n        displayError.classList.add(\"d-none\");\n      }\n    });\n\n    cardCvc.addEventListener(\"change\", (evt) => {\n      const displayError = document.getElementById(\"stripe-cvc-errors\");\n      if (evt.error) {\n        displayError.textContent = evt.error.message;\n        displayError.classList.remove(\"d-none\");\n      } else {\n        displayError.textContent = \"\";\n        displayError.classList.add(\"d-none\");\n      }\n    });\n\n    const cardholderNameInput = document.getElementById(\"cardholder-name\");\n    const zipCodeInput = document.getElementById(\"zip\");\n    const submitButton = document.getElementById(\"save-card\");\n\n    submitButton.addEventListener(\"click\", async (clickEvent) => {\n      clickEvent.preventDefault();\n      clickEvent.stopPropagation();\n\n      const reverseSubmitProtection = handleAjaxFormSubmitProtection(submitButton);\n\n      const paymentMethodDetails = {\n        billing_details: {\n          address: {\n            postal_code: zipCodeInput.value,\n          },\n          name: cardholderNameInput.value,\n        },\n        card: cardNumber,\n      };\n\n      const response = await stripe.confirmCardSetup(event.detail.clientSecret, {\n        payment_method: paymentMethodDetails,\n      });\n\n      if (response.error) {\n        if (response.error.message) {\n          const displayError = document.getElementById(\"payment-method-errors\");\n          displayError.innerText = response.error.message;\n          displayError.classList.remove(\"d-none\");\n        } else if (window.Rollbar) {\n          window.Rollbar.error(\"Error confirming PaymentMethod setup\", response.error);\n        }\n\n        reverseSubmitProtection();\n\n        return;\n      }\n\n      paymentMethodForm.setAttribute(\n        \"hx-vals\",\n        JSON.stringify({ setup_intent: response.setupIntent.id }),\n      );\n      sendBrowserAgnosticEvent(paymentMethodForm, \"paymentMethodAdded\");\n    });\n  });\n}\n","export function initAttendeeFormset(eventUUID, formsetProps) {\n  if (formsetProps) {\n    const totalFormsInput = document.getElementById(\n      formsetProps.managementForm.fields.TOTALFORMS,\n    );\n    const numberOfAttendeesInput = document.getElementById(\n      formsetProps.numberOfAttendeesInput,\n    );\n\n    if (!numberOfAttendeesInput) {\n      return;\n    }\n\n    const attendeesListGroup = numberOfAttendeesInput\n      .closest(\".add-rsvp-form,.rsvp-form\")\n      .querySelector(\".rsvp-attendees\");\n    let { totalFormCount } = formsetProps;\n    const { emptyForm } = formsetProps;\n\n    const removeForm = (specificForm = null) => {\n      let child;\n\n      if (!specificForm) {\n        child = [\n          ...attendeesListGroup.querySelectorAll(\n            \".rsvp-attendee-formset-form:not(.hidden)\",\n          ),\n        ].pop();\n      } else {\n        child = specificForm;\n      }\n\n      if (child) {\n        const deleteField = child.querySelector('input[type=\"hidden\"]');\n        deleteField.value = \"1\";\n\n        child.classList.add(\"hidden\");\n\n        const visibleFormCount = attendeesListGroup.querySelectorAll(\n          \".rsvp-attendee-formset-form:not(.hidden)\",\n        ).length;\n        if (visibleFormCount === 0) {\n          attendeesListGroup.classList.add(\"d-none\");\n        }\n      }\n    };\n\n    const addForm = () => {\n      const formWrapper = document.createElement(\"div\");\n      formWrapper.innerHTML = emptyForm.replace(/__prefix__/g, totalFormCount);\n      const newForm = formWrapper.querySelector(\".rsvp-attendee-formset-form\");\n\n      const removeButton = newForm.querySelector(\".remove-attendee\");\n\n      if (removeButton) {\n        removeButton.addEventListener(\"click\", () => {\n          numberOfAttendeesInput.value = parseInt(numberOfAttendeesInput.value, 10) - 1;\n          removeForm(newForm);\n        });\n      }\n\n      attendeesListGroup.appendChild(newForm);\n      totalFormCount += 1;\n      totalFormsInput.value = totalFormCount;\n\n      attendeesListGroup.classList.remove(\"d-none\");\n    };\n\n    attendeesListGroup.querySelectorAll(\".remove-attendee\").forEach((removeButton) => {\n      removeButton.addEventListener(\"click\", () => {\n        numberOfAttendeesInput.value = parseInt(numberOfAttendeesInput.value, 10) - 1;\n        removeForm(removeButton.closest(\".rsvp-attendee-formset-form\"));\n      });\n    });\n\n    numberOfAttendeesInput.addEventListener(\"change\", () => {\n      const desiredNumberOfForms = parseInt(numberOfAttendeesInput.value, 10) - 1;\n      const visibleFormCount = attendeesListGroup.querySelectorAll(\n        \".rsvp-attendee-formset-form:not(.hidden)\",\n      ).length;\n\n      if (desiredNumberOfForms > visibleFormCount) {\n        for (let i = 0; i < desiredNumberOfForms - visibleFormCount; i++) {\n          addForm();\n        }\n      } else if (desiredNumberOfForms < visibleFormCount) {\n        for (let i = 0; i < visibleFormCount - desiredNumberOfForms; i++) {\n          // No adjustment of numberOfAttendeesInput here (it has already changed by\n          // user interaction)\n          removeForm();\n        }\n      }\n    });\n  }\n}\n"],"names":["toggleSubmitButtonEnabled","submitButton","enabled","toggleAttribute","classList","toggle","clearError","errorMessageContainer","document","querySelector","add","showError","errorMessage","innerText","fadeIn","async","initPayableCheckout","props","stripe","loadStripe","stripePublishableKey","body","addEventListener","event","payload","message","sendBrowserAgnosticEvent","scrollToElement","checkoutForm","getElementById","elements","clientSecret","detail","fonts","cssSrc","loader","style","base","fontFamily","fontSize","color","invalid","zipInput","cardholderInput","stripeElementContainerCollapse","Collapse","cardNumber","create","showIcon","cardExpiry","cardCvc","on","remove","mount","cardNumberValid","cardExpiryValid","cardCvcValid","allInputsReady","value","length","forEach","el","changeEvent","complete","isReady","error","paymentMethodSelect","hide","show","savePaymentMethod","completeCheckout","paymentMethodFromPaymentRequest","completeCallback","response","isSetupIntent","confirmCardSetup","payment_method","card","billing_details","name","address","postal_code","paymentData","id","checked","setup_future_usage","confirmCardPayment","window","Rollbar","paymentIntent","status","actionResponse","paymentRequest","paymentRequestParams","prButton","canMakePayment","paymentMethodEvent","paymentMethod","submitEvent","preventDefault","supportsBlur","CSS","supports","initProductPhotoBlur","threshold","images","querySelectorAll","image","img","aspect","naturalWidth","naturalHeight","Math","abs","closest","canvas","createElement","width","height","ctx","getContext","drawImage","pixelData","map","p","getImageData","data","slice","container","parentNode","every","d","i","bg","backgroundColor","documentElement","backgroundImage","src","backgroundSize","avg","reduce","acc","curr","val","idx","processImage","initCheckoutDynamicFormFields","trigger","t","skipBillingAndDeliverySync","billingNameChanged","deliveryNameInput","formFieldIds","deliveryName","billingNameInput","billingName","initCauseOfDeathAutocomplete","causeOfDeathInput","inputId","tomSelect","TomSelect","input","trim","text","created","maxItems","placeholder","valueField","sortField","field","notShared","initialAutocompleteData","options","addOption","setValue","initialPendingData","disable","clear","enable","strInput","strInputId","form","selectedOption","getValue","TomSelect_virtual_scroll","formatCity","city","createAutocompleteOption","initCityAutocomplete","cityIdentifierInput","cityIdentifierInputId","openUrlOnSelect","buildUrl","query","page","paramsData","search","businessTypeName","params","URLSearchParams","citySearchUrl","toString","tomSelectConfig","plugins","searchField","firstUrl","load","callback","requests","get","this","getUrl","ok","ResponseError","json","pagination","next","nextUrl","setNextUrl","results","loadThrottle","render","option","item","not_loading","shouldLoad","onChange","optionSelected","location","href","url","initExpandableCollapse","rootElement","lineCount","dataset","collapsedLineCount","parseInt","lineHeightStr","getComputedStyle","lineHeight","replace","collapsedHeight","gradientHeight","max","scrollHeight","setProperty","initExpandableCollapses","initMobileShareButton","selector","shareButton","navigator","share","title","shareTitle","shareUrl","catch","TomSelect_remove_button","NO_CHANGES_CLASS","formatParticipant","participant","thumbnailUrl","setAttribute","clearInviteForm","inviteModal","inviteInput","removeAttribute","initParticipantAutocomplete","participantsInitialAutocompleteData","participantsInputIds","participants","participantsJson","userMention","memorialSlug","userSearchEndpoint","participantsField","hiddenParticipantsJsonInput","temporaryParticipants","currentParticipantsIdentifier","modalParticipantData","flushParticipantDataToJsonField","JSON","stringify","tomselect","term","user","userHash","userMentionName","userSlug","virtual_scroll","remove_button","participantAutocomplete","addOptions","addItems","unselect","deselectedData","filter","participantData","close","Modal","temporaryParticipantIdentifier","push","runInviteFormValidation","inviteData","parse","firstNameField","lastNameField","emailField","email","ProgressRing","constructor","root","initialPercentage","circle","label","circumference","r","baseVal","PI","strokeDasharray","strokeDashoffset","setPercentage","newPercentage","textContent","SocialSource","FACEBOOK","FacebookImporter","mediaImporter","auth","nextCursor","nextAlbumCursor","selectedAlbum","getAlbumsUrl","baseUrl","getMediaUrl","authenticate","authType","return_scopes","scope","auth_type","FB","login","authResponse","grantedScopes","includes","loadAlbums","loading","api","paging","cursors","after","albumsReceived","node","thumbnail","picture","selectAlbum","album","media","loadMedia","mediaReceived","caption","source","reset","SocialPhotoImporter","onPhotosSelected","maxAllowed","modal","albumList","mediaGrid","selectedMediaGrid","errorContainer","loadingContainer","loadingMoreContainer","loadMoreMedia","loadingMoreAlbumsContainer","loadMoreAlbums","albums","selectedMedia","facebookImporter","activeImporter","maximum","display","resetMedia","retry","existingAlbumIds","a","newAlbumElement","newAlbumThumb","newAlbumTitle","appendChild","insertBefore","existingIds","m","existingMediaElement","isSelected","newMediaElement","newMediaImg","alt","toggleSelected","existingSelectedIds","selectedId","newSelected","shouldChooseAlbum","children","allowRetry","EMPTY_VALUES","undefined","initUGCTemplates","templatesData","shouldShowTemplatesOnInit","skipWarningModal","onTemplateSelected","inputIsHTMLEditor","alwaysShowTemplates","submitBtnWithWarning","templateSelector","templateDefaultOption","editModalButton","saveModalButton","warningModal","showWarningModalOnSubmit","selectedTemplate","selected","templateBody","templateIsEdited","templateBodyInP","previousSelection","prevValue","previous","acknowledgedWarning","click","hasSeenWarning","stopImmediatePropagation","inviteForm","submitBtn","checkValidity","UserMentionWriteHandler","mentionableElement","searchEndpoint","mentionsInput","mentionModalElement","mentionModal","processableMentions","Set","currentUserSearch","inviteSuccessModal","boundSetHiddenUserData","setUserQueryValue","bind","boundValidateForm","validateInviteForm","boundAcceptUserData","addSubmittedUserDataToProcessableMentions","showSuccessModal","animateCSS","fadeOut","listenForUserMentionTrigger","Tribute","allowSpaces","searchOpts","skip","selectClass","containerClass","itemClass","selectTemplate","original","setupListenersOnUserMentionInviteForm","menuItemTemplate","string","noMatchTemplate","lookup","fillAttr","values","debounce","cb","noMatchItem","rateLimitItem","searchErrorItem","Error","dropdownData","splice","MENU_ITEM_LIMIT","maxWait","requireLeadingSpace","menuItemLimit","menuShowMinLength","attach","klass","target","contains","userQueryHiddenInput","firstNameInput","lastNameInput","emailInput","fullName","disabled","eljs","editor","replaceContent","userQuery","addMentionsToFormOnSubmit","offsetParent","mentions","clearListenersOnUserMentionInviteModalClose","removeEventListener","setUp","initUserMentionsForElement","element","initUserMentions","memorialIsExample","userMentionClass","BelongingEditor","modalContainer","createUrl","editUrl","titleNameSpan","titleClaimedBadge","titleAvailableBadge","productPhoto","productPhotoPlaceholder","fieldIds","belongingFormFieldIds","photoInput","photo","nameInput","descriptionTextarea","description","isPublishedCheckbox","isPublished","isClaimedCheckbox","isClaimed","renderDependents","file","readValidFileFromInput","reader","FileReader","onload","readerEvent","result","readAsDataURL","activeBelonging","onBelongingChanged","e","stopPropagation","saveButton","save","dismiss","showForBelonging","belonging","invokeFilePicker","clicked","cancelSubmitProtect","handleAjaxFormSubmitProtection","errList","hasChildNodes","removeChild","lastChild","showGenericError","mainErrorAlert","responseData","post","success","responseJSON","errors","main","Object","keys","errKey","errorList","err","errItem","handleFail","AutoSaveTextField","textField","storageKey","autosaveKey","remoteLastUpdated","parseFloat","autosaveLastUpdated","storageAvailable","store","initialValue","setTimeout","indicator","revertLink","force","localStorage","getItem","timestamp","Date","now","setItem","removeItem","updateIndicator","hasNotChanged","updateBusinessAutocomplete","includeInitialValue","businessPlaceholder","addSubmitListener","businessIdentifierInputId","mergedProps","businessIdentifierInput","destroy","initBusinessAutocomplete","clearReviewInputs","reviewInputWrappers","reviewInputWrapper","reviewTextarea","errorlist","toggleFuneralHome","inputGroup","isOnboarding","shouldShow","initBusinessAssociationForm","editDispositionMethodBtns","businessAssociationInputGroups","funeralHomeInputGroup","cemeteryInputGroup","donationOrgInputGroup","seaBurialProviderInputGroup","locationTypeInputGroup","locationInputGroup","locationTypeSelect","remainsLocationField","funeralHomeInputLabel","funeralHomeInputPending","locationTypeNoRemains","remainsLocationTypeNoRemains","setTextOfFuneralHomeGroup","isFuneralHome","isInitialLoad","isGenericProvider","setDispositionMethodState","nonSelectedDispositionRadios","selectedDispositionRadio","selectedDispositionRadioWrapper","nonSelectedDispositionRadio","editDispositionMethodBtn","funeralHomeSearch","businessStrInputId","businessPending","cemeterySearch","showBurialFields","showCremationFields","showDonationFields","showSeaBurialFields","showOtherFields","innerEditDispositionMethodBtn","dispositionRadio","donationOrgSearch","seaBurialProviderSearch","clearOptions","clearAllBusinessAssociationInputs","burialRadio","group","cremationRadio","donationRadio","seaBurialRadio","naturalOrganicReductionRadio","liquidCremationRadio","otherRadio","pendingRadio","clearLocationInputs","clearCemeteryInputs","cemeterySearchInput","showLocationTypeFollowupField","showInitialValue","remainsLocationTypeCemetery","remainsLocationTypeCheckbox","remainsLocationCheckbox","setRemainsLocationTypeState","remainsLocationTypeField","setRemainsLocationState","hospiceSearch","deathDoulaSearch","disableReviews","reviewSection","reviewSectionHeader","funeralHomeReviewSection","funeralHomeSlugInput","funeralHomePendingCheckbox","funeralHomeReviewSubmitBtn","cemeteryReviewSection","cemeterySlugInput","cemeteryPendingCheckbox","cemeteryReviewSubmitBtn","hospiceReviewSection","hospiceSlugInput","hospicePendingCheckbox","hospiceReviewSubmitBtn","donationOrgReviewSection","donationOrgSlugInput","donationOrgPendingCheckbox","donationOrgReviewSubmitBtn","deathDoulaReviewSection","deathDoulaSlugInput","deathDoulaPendingCheckbox","deathDoulaReviewSubmitBtn","showBusinessReviewForm","selectedFuneralHome","selectedCemetery","selectedHospice","selectedDonationOrg","selectedDeathDoula","funeralHomesReviewed","businessesUserHasReviewed","funeralHomes","cemeteriesReviewed","cemeteries","hospicesReviewed","hospices","donationOrgsReviewed","donationOrgs","deathDoulasReviewed","deathDoulas","showFuneralHomeReviewForm","showCemeteryReviewForm","showHospiceReviewForm","showDonationOrgReviewForm","showDeathDoulaReviewForm","funeralHomeSlug","funeralHomeName","nameSpan","cemeterySlug","cemeteryName","hospiceSlug","hospiceName","donationOrgSlug","donationOrgName","deathDoulaSlug","deathDoulaName","submitBusinessReview","businessType","submitButtonRestore","submitUrl","rating","flow","slug","showBusinessReviewSuccessState","businessName","businessSlug","successMessage","business1","business2","business2Wrapper","isHidden","reviewForm","collapse","currentTarget","initBusinessReviewSection","initDateTimePicker","flatpickr","allowInput","altFormat","altInput","enableTime","selectedDates","dateStr","instance","_previousInput","_input","onClose","config","setDate","onReady","placeholderEventsStatePending","setEventsContainerInputsDisabledState","eventInputContainer","eventInput","addEventTypeOtherFocus","formCount","otherInput","parentElement","attachEventTypeListener","formContainer","eventTypeContainer","handleEventSelection","selectedEventType","eventName","otherField","getAttribute","newTitle","radio","addEventLocationAutocomplete","metadataElement","alwaysBlockReturnKeySubmit","initGoogleAutocomplete","types","initRSVPLimitBehavior","rsvpsEnabledCheckbox","rsvpsLimitContainer","rsvpsLimitContainerCollapse","rsvpsLimitCheckbox","rsvpsLimitFieldContainer","rsvpsLimitField","rsvpsLimitFieldContainerCollapse","updateRSVPLimitDisplay","minValue","Number","initStreamingOptions","eventStreamingCheckbox","zoomHostingCheckbox","urlContainer","zoomDataContainer","eventLocationLabel","updateLocationLabel","indexOf","concat","initEventExtraData","flushParticipantData","showCovid","covidInputs","covidPrecautionOtherContainer","checkbox","attachmentInputContainer","attachmentInput","downloadProgramLink","removeContainer","removeField","files","programTextCTA","programTextContainer","programTextarea","initEditor","customButtons","inputContainerSelector","templates","templatesContainerSelector","speakersContainer","participantAutocompleteProps","participantsInitialAutocompleteDataByEvent","uuid","expandRSVPs","triggeringElement","scrollToDetails","rsvpsContainer","scrollInMemorialPrivateContentContainer","initEditEvents","deleteEventCallbacks","placeholderEventsStateNotHappening","memorialFirstName","placeholderEventsStatePrivate","changeTimezoneContainer","bottomSubmitRow","topSubmitRow","eventsState","eventsStatePublic","nonPublicEventStateReasonField","eventsNote","eventsStatePrivate","eventsStateNotHappening","eventsStatePending","privateEventStreamCheckbox","streamEntryField","privateEventZoomCheckbox","privateEventZoomDataContainer","stateRadio","selectedRadio","streamOption","otherReason","toHide","toShow","totalFormCount","removeButton","hideTimezone","eventsStateNoInfo","datetimeInputElement","pickerInput","nextElementSibling","deleteCallbacks","Array","from","removeEventAnchor","idField","confirm","previousElementSibling","action","submit","attendeeFormsetProps","eventUUID","formsetProps","initAttendeeFormset","initEditEventsOnLoad","inputElements","getElementsByClassName","totalFormCountInput","resequenceForms","removedIdFormField","formIdRegex","removedIndex","match","_container","containerIndex","idFormField","removeAnchor","addEventButton","newForm","emptyForm","formElements","generateElements","eventFormsContainer","append","eventForm","eventExtraDataCallback","elementMetadataId","expandEventRSVPS","expandElement","StockPhotoModal","onSelected","rootModal","selectedStockPhotos","desiredCount","confirmSelection","cancelSelection","evt","elt","togglePhoto","updateSelected","alreadySelectedStockPhotos","browserContainer","photoElement","hashid","filteredPhotos","sp","selectedPhotosContainer","firstChild","photoData","div","selectedHashids","stockPhoto","desiredCountLabel","remaining","CROPPER_OPTIONS","aspectRatio","autoCrop","autoCropArea","viewMode","cropBoxMovable","cropBoxResizable","dragMode","minCropBoxWidth","minCropBoxHeight","minCanvasHeight","zoomOnWheel","DeceasedPhotoUploader","socialImporter","photos","onSocialPhotosSelected","stockPhotoRoot","stockPhotoModal","stockPhotoData","stockPhotosSelected","isSelectingPhotos","isInExternalPhotoSelection","ingestionOptionsModal","fileInput","filesSelected","selectPhotosButton","importFromFacebookButton","importFromEverLovedButton","collageSize","layoutFrame","layoutSelector","layoutSize","isSelectingLayout","filterFrame","filterFinishedButton","isFiltering","previewFrame","existingPhotos","cropperData","isShowing","uploadPhotos","onPhotosUpdated","uploadUrl","uploadExtraParams","is_onboarding","fundraising_purpose","fundraisingPurpose","uploadOverlay","previewPhotosContainer","incompleteWarning","startSelectPhotos","overrideSelectingPhotos","socialOptionsModal","span","renderLayoutFrame","renderFilterFrame","renderPreviewFrame","stockPhotosData","f","v","File","isFromSocial","verifyAccept","type","allowed","split","x","alert","tileContainer","newTile","photoName","newTilePhoto","objectFit","croppedCanvas","objectPosition","fileReader","innerHTML","removePhoto","canProgress","photoContainer","photoImg","primaryBanner","cropControlContainer","cropControl","cropPhoto","moveControls","change","moveUp","movePhoto","moveDown","placeholderCount","placeholderElement","cameraImg","cameraSvg","formData","FormData","k","set","photoMetadata","is_main_photo","cropData","y","social_url","progressBar","uploadCount","errorAlert","onProgressPercentage","percent","loadFinish","setInterval","clearInterval","currentValue","postMultipartWithProgress","photoLayoutSelector","up","currentIndex","newIndex","min","previewElementContainer","previewElement","nextSibling","previousSibling","cropper","cropperContainer","zIndex","cropperImg","flexBasis","maxHeight","zoomControls","zoomInBtn","zoom","zoomOutBtn","canvasData","cropOptions","ready","setCanvasData","imageData","getCropBoxData","Cropper","buttonBar","cancelButton","minWidth","getCanvasData","getData","getCroppedCanvas","toDataURL","toggleManualEntry","showManualEntry","deceasedFirstName","firstName","deceasedLastName","lastName","fullNameInput","deceasedNameFieldId","deceasedFirstNameFieldId","deceasedLastNameFieldId","manualEntryContainerClass","memorialSearchContainerClass","splitNames","join","initDeceasedAutocomplete","deceasedIdentifierInput","deceasedSearchUrl","deceasedPlaceholder","formatDeceased","deceased","dateOfBirth","dateOfDeath","deceasedSearchAutocomplete","newValue","newOption","deceasedMemorialSlugInput","deceasedMemorialSlugFieldId","deceasedManualEntryErrors","deceasedFormClass","locationContainer","deceasedLocationContainerClass","setupFormListeners","nameField","relationshipSelect","deceasedRelationshipTypeFieldId","toggleButton","deceasedSubmitButton","initFundraiserForm","onCleaveInit","cleave","personalFundraiserForms","personalFundraiserForm","fundraisingGoalContainer","fields","fundraisingGoal","fundraisingGoalDisabled","goalAmountContainer","currencyWithoutGoalContainer","goalContainer","goalAmountCollapse","currencyWithoutGoalCollapse","fundraisingGoalInput","Cleave","numeral","numeralPositiveOnly","getRawValue","currencySelect","currencyNote","previousCurrency","selectedOptions","selectedCurrency","exchangeRates","toFixed","setRawValue","round","causeStoryField","causeStoryForm","causeStory","causeStoryTemplatesContainer","causeStoryTemplates","shouldShowCauseStoryTemplates","previousCauseStoryField","previousCauseStory","clipboardData","charityFundraiserForms","charityFundraiserForm","charityvestDesignationSelector","charityvestDesignation","otherContainer","fundraisingManagerSelect","isOriginal","forceSubmit","initPopovers","initSubscriberNotificationsModal","notificationsModalElement","notificationsModal","notifyBtn","sendNotificationsEndpoint","initRelationshipForms","addPredeceasedLovedOneButton","addPredeceasedLovedOneForm","addFollowingLovedOneButton","addFollowingLovedOneForm","addSurvivingLovedOneButton","addSurvivingLovedOneForm","predeceasedLocationContainer","survivorRelationshipTypeSelect","survivorRelationshipTypeFieldId","survivorRelationshipTypeStr","index","selectedIndex","inviteManager","predeceasedRelationshipTypeSelect","predeceasedRelationshipTypeFieldId","predeceasedRelationshipTypeStr","followerFormProps","followingRelationshipTypeSelect","followingRelationshipTypeStr","baseSearchUrl","slugFieldId","firstNameFieldId","lastNameFieldId","excludeSlugs","predicateFilter","memorialSearchEntry","memorialSearchLoading","memorialSearchResultContainer","memorialSearchError","memorialSearchDuplicate","memorialSearchIneligible","manualEntryContainer","memorialSlugField","rawFirstNameField","rawLastNameField","showSearchResult","memorialData","yearOfBirth","yearOfDeath","searchUrl","encodeURIComponent","memorialUrl","warn","searchMemorial","initMemorialSearchByUrl","memorialSearchUrl","relatedMemorialSlugs","predeceasedMemorialSlugFieldId","predeceasedMemorialDeceasedFirstNameFieldId","predeceasedMemorialDeceasedLastNameFieldId","personEditForms","personEditFormContainer","relationshipTypeSelect","relationshipTypeStr","listGroupItem","editForm","listItemContent","keyCode","personEditLinks","editLink","initMemorialPrivateHowToHelp","totalOtherFormCount","initNeedForm","needFormContainer","needTypeOtherInput","activate","needTypeLabel","deleteInput","idInput","focus","titleSubmitButton","button","readonlyContainer","editableContainer","locationField","locationMetadataField","otherNeedFormsetContainer","addOtherButton","formSource","emptyOtherForm","wrapper","firstElementChild","registerSubmitButton","initAnimatedPlaceholderFormField","initInvites","showNotificationsPrompt","openImportContactsButton","loadingOverlay","connectPromptOverlay","errorOverlay","contactSearch","contactListGroup","importContactsButton","recipientsField","selectAllContactsButton","toLowerCase","searchTarget","loadContacts","alreadySelected","em","getContactsUrl","contacts","contact","pathname","importGoogleContactsModalElement","hasCredentials","initializerButton","alternate","top","outerHeight","screenY","h","outerWidth","screenX","w","open","oAuthComplete","selectedEmails","deselectedEmails","newSelectedEmails","newRecipients","inviteRecordsBodyCard","initFundraiserOnboarding","initMemorialOnboardingInviteManager","initMemorialOnboardingEvents","initMemorialOnboardingFamily","initMemorialOnboardingFinalRestingPlace","causeOfDeathSearch","initMemorialOnboardingFundraisingGuidance","choiceField","choices","choice","fundraisingChoice","initMemorialOnboardingPhoto","uploader","deceasedPhotoUploaderProps","fbAsyncInit","init","appId","facebookAppId","autoLogAppEvents","xfbml","version","facebookApiVersion","updateSharingChecklist","updateSharingChecklistEndpoint","statusText","initMemorialOnboardingShare","ClipboardJS","btnFacebookShare","debug","console","log","facebookShare","ui","facebookResponse","error_code","memorialHasPersonalFundraiser","shareToFacebookChecklistStatus","shareComplete","WordCounter","wordCountTarget","wordCountMax","counterSpan","assessCount","currentCount","getWordCount","overage","token","initPartnerObituaryOrderCreate","photoUrlField","photoUrl","selectedPhoto","photoSelectorChoices","_img","formDisabled","toggleFormEnabled","forceEnabled","btn","wordCountRoot","obituary","obitField","initMemorialPrivateChooseCause","charitySearch","charityBusinessIdentifierInput","selectCharityBtn","modalElement","initCharitySearchListener","causeCards","causeExpanders","rectangles","causeExpander","thisCard","thisCauseCardExpander","thisRectangle","isAlreadyExpanded","rectangle","marginBottom","offsetHeight","isOnMobile","scrollingElement","initChooseCauseGrid","adjustCurrentCardBottomMargin","currentExpander","descriptionExpander","initExpandableCharityOverview","eventActions","errorMessages","TOUR_DELAY","initTimezoneSelector","timezoneSelectorId","timezoneSelector","browserTimezone","Intl","DateTimeFormat","resolvedOptions","timeZone","find","opt","completeSharingChecklistItem","checklistItemKey","endpoint","SIDEBAR_KEY","SidebarManager","sidebar","sync","hidden","sessionStorage","initMemorialUpdateEdits","link","deleteUrl","delete","initMemorialGiftPremiumControls","hasPremium","disableMemorialGiftsId","disableMemorialGiftsContainers","disableMemorialGiftsContainer","disableMemorialGiftsToggle","handleDisableToggle","giftTogglesContainer","giftTogglesDoNotSuggestGifts","causeConfigurationContainers","preferencesContainer","standaloneStoryAndChecklist","addFundraiserBtn","causeConfigurationContainer","disableMemorialGiftListDisplayId","disableListDisplay","disableContributionsDisplay","disableMemorialGiftContributionsDisplayId","handleListDisplayToggle","undoDisabledCheckboxOnSubmit","checkboxEl","targetForm","initMemorialPrivateBase","sidebarToggle","sidebarManager","some","offset","initClipboard","initDirtyTracker","checkboxContainer","initPremiumUpsell","urlParams","initTimezoneModal","initAddFuneralHomeWarning","facebookBtn","sharingUrl","method","alertKey","allAlertsContainer","showAllAlerts","isPrivateDashboard","hash","closeAlerts","hideAlertButtons","alertButton","revert","listItem","dismissPrivateAlertUrl","key","autoScrollTargets","autoScroll","onhashchange","onboardingReentryBanner","Alert","searchPhraseInput","searchPhraseInputId","memorialFeatureSearchUrl","featureAutocomplete","initMemorialFeatureAutocomplete","memorialFeatureSearch","initTooltips","initMemorialInvitePeople","personCountSpan","invitePeopleFormset","totalFormsField","totalFormsFieldId","totalForms","total","initManagerRelationshipBehavior","relationshipEntryContainer","showingManager","initRelationshipOtherBehavior","selectField","strField","updateSubmitButton","nameFields","updateNumberOfForms","increment","removeFormHandler","addInvitePersonFormButton","newFormContainer","initMemorialPrivateDashboard","recommendationsWrapper","Glide","animationDuration","peek","before","Swipe","answerText","collapseElement","carouselElement","Carousel","notAnswerText","openCollapseElement","initSuccessModal","hasSubmitted","isVisible","sentThankYouCheckbox","updateUrl","toggle_thank_you","sentThankYou","ringContainer","checklistProgress","tourProps","innerWidth","tourData","containerSelector","currentTourStep","advanceTour","tourHasBeenInvoked","closeTour","step","renderCurrentTourStep","tourStepTarget","currentStep","alone","position","left","isInViewport","scrollIntoView","targetRect","getBoundingClientRect","leftEdge","rightEdge","topEdge","bottomEdge","horizontalSpace","horizontalAnchor","verticalSpace","verticalAnchor","right","bottom","innerHeight","beginTour","nextBtn","exitBtn","timerFire","timeoutId","clearTimeout","initMemorialPrivateTour","initMemorialDeceasedForm","titleInputId","titleOtherStrInputId","suffixInputId","suffixOtherStrInputId","titleInput","titleOtherStrContainer","suffixInput","suffixOtherStrContainer","setupDeceasedTitleAndSuffix","addNickname","dateOfDeathInputs","disableDateOfDeathPicker","currentInput","enableDateOfDeathPicker","notYetPassed","notYetPassedInputId","relationshipSelectId","relationshipOther","initMemorialPrivateBasicInformation","photosUploadedBanner","multiPhotoUploader","photosSection","initMemorialPrivatePassing","organDonationSearchProps","checkboxId","hasDonatedOrgans","organChoicesInput","organDonationDetailsContainer","hidePlaceholder","items","toggleShowOrganDonationDetails","initOrganDonationForm","organDonationSearch","addDeliveryLocationAutocomplete","componentRestrictions","country","initMemorialPrivateGifts","clv","fundraisingGoalCleave","isNewCause","causeStoryInput","defaultValue","clearFundraisingUser","clearInput","requestSubmit","showErrorOnClickElement","disabledFieldName","disabledName","getNextSiblingMatchingSelector","eventAction","trackCustomUserAction","once","premiumForm","disableMemorialGifts","disableMemorialGiftListDisplay","disableMemorialGiftContributionsDisplay","selfServeCheckbox","selfServeDonations","parentBodyCard","customCharityFinePrint","selfServeCharityFinePrint","fundraisingManagerForm","selfServeChanged","formsetContainer","addAddressContainer","deliveryAddressForms","deliveryAddressesTotalFormCountInputId","deliveryAddressesTotalFormCount","addRemoveAddressHandler","removeAddressButton","formIdField","insertAdjacentHTML","emptyDeliveryAddressForm","lastElementChild","allowFlowersToggle","preferencesFormFieldIds","allowFlowers","initDeliveryAddressesOnLoad","initMemorialPrivateFavorites","initEditDropdowns","initUserBlocking","handleListUpdate","searchEvent","scrollContainer","emptyElement","noSearch","emptySearch","showEmpty","userSearchingContainers","userBlockButtons","blockedUserList","unblockedUserList","blockBtn","isBlocking","blockUrl","block","initMemorialPrivateFamily","editRelatedPhotoLinks","uploadRelatedPhotoPersonField","uploadForm","toPerson","memorial","initPhotoCropper","relatedPhotoForm","rawPublicProfilePhoto","xInput","yInput","heightInput","widthInput","cropperOptions","cropButtonSubmits","onComplete","onModalShown","cropperInstance","setAspectRatio","initRelatedPhotoUpload","firstSection","awaitingConfirmationSectionAlerts","awaitingConfirmationSections","awaitingConfirmationSectionAlert","initRelativeAwaitingConfirmationTips","initDeceasedSearchAutocomplete","initMemorialPrivateEvents","forms","timezone","initMemorialObituary","placeholderOverride","obituaryTextArea","autoSaves","showTemplateSelectorButton","templateSelectorContainer","initMemorialNote","noteInput","noteInputId","noteTemplatesContainer","noteTemplates","initPasswordProtect","passwordProtectToggle","passwordProtectFieldContainer","initMemorialPrivatePremium","paymentMethodForm","listener","htmx","appearance","theme","variables","colorPrimary","getPropertyValue","labels","displayError","cardholderNameInput","zipCodeInput","clickEvent","reverseSubmitProtection","paymentMethodDetails","setup_intent","setupIntent","initAddPaymentMethod","registerFormSubmitProtection","initMemorialPrivateSettings","themeOptions","themeNames","themeOption","themeName","initLegacyEdit","urls","defaultUrl","initFeedbackForm","feedbackReasonField","reasonCommentFieldId","reasonInputName","reasonCommentFormPrompts","initMemorialPrivateNoteAndUpdates","initMemorialPrivateBelongings","editorContainer","invokeEditor","newBelonging","listedBelongings","unlistedBelongings","existing","belongingsList","is_published","insertBeforeTarget","newItemWrapper","truncatedDescription","emptyListItem","is_claimed","claimedBadge","belongingEditor","editorProps","belongingItem","notifyCheckboxContainerForm","notifyCheckbox","initPhotoArchiveRequest","photoArchiveRequestError","initMemorialPrivateCommunityContent","initAIObituaryComposerForm","composerForm","scrollFix","editContent","locationAutocompleteFields","placeAutocompleteFields","google","maps","handleSchoolNameInput","existingNameInputs","cloned","cloneNode","yearInput","parent","childNode","totalFormsInput","managementForm","TOTALFORMS","numberOfAttendeesInput","attendeesListGroup","removeForm","specificForm","child","pop","addForm","formWrapper","desiredNumberOfForms","visibleFormCount"],"sourceRoot":""}