{"version":3,"file":"application-aSXr6pKi.js","sources":["../../../app/javascript/channels/consumer.js","../../../app/javascript/controllers/accounts_controller.js","../../../app/javascript/controllers/application_controller.js","../../../app/javascript/controllers/autogrow_controller.js","../../../app/javascript/controllers/braintree_controller.js","../../../app/javascript/controllers/bulk_controller.js","../../../app/javascript/controllers/cleave_controller.js","../../../app/javascript/controllers/clipboard_controller.js","../../../app/javascript/controllers/cmd_enter_controller.js","../../../app/javascript/controllers/command_palette_controller.js","../../../app/javascript/controllers/cropper_controller.js","../../../app/javascript/controllers/datepicker_controller.js","../../../app/javascript/controllers/disable_submission_controller.js","../../../app/javascript/controllers/drag_drop_student_room_controller.js","../../../app/javascript/controllers/dropdown_controller.js","../../../app/javascript/controllers/enrollment_guardians_search_controller.js","../../../app/javascript/controllers/example_controller.js","../../../app/javascript/controllers/fix_dropdown_position_controller.js","../../../app/javascript/controllers/form_validation_controller.js","../../../app/javascript/controllers/infinite_scroll_controller.js","../../../app/javascript/controllers/instant_upload_controller.js","../../../app/javascript/controllers/link_element_controller.js","../../../app/javascript/controllers/mentions_controller.js","../../../app/javascript/controllers/notification_toast_controller.js","../../../app/javascript/controllers/notifications_controller.js","../../../app/javascript/controllers/pricing_controller.js","../../../app/javascript/controllers/program_room_selects_controller.js","../../../app/javascript/controllers/remote_tom_select_controller.js","../../../app/javascript/controllers/reset_form_controller.js","../../../app/javascript/controllers/room_schedule_controller.js","../../../app/javascript/controllers/select_filter_controller.js","../../../app/javascript/controllers/select_redirect_controller.js","../../../app/javascript/controllers/signature_controller.js","../../../app/javascript/controllers/start_end_date_filter_controller.js","../../../app/javascript/controllers/student_list_actions_controller.js","../../../app/javascript/controllers/submit_on_change_controller.js","../../../app/javascript/controllers/tagify_controller.js","../../../app/javascript/controllers/test_controller.js","../../../app/javascript/controllers/toggle_button_controller.js","../../../app/javascript/controllers/toggler_controller.js","../../../app/javascript/controllers/tom_select_assign_controller.js","../../../app/javascript/controllers/tooltip_controller.js","../../../app/javascript/controllers/turbo_native/sign_out_controller.js","../../../app/javascript/controllers/zui/accent_controller.js","../../../app/javascript/controllers/zui/collapsible_controller.js","../../../app/javascript/controllers/zui/dropdown_controller.js","../../../app/javascript/controllers/zui/message_controller.js","../../../app/javascript/controllers/zui/modal_controller.js","../../../app/javascript/controllers/zui/proxy_controller.js","../../../app/javascript/controllers/zui/swipe_controller.js","../../../app/javascript/controllers/zui/switch_controller.js","../../../app/javascript/controllers/zui/tab_panel_controller.js","../../../app/javascript/controllers/zui/theme_controller.js","../../../app/javascript/controllers/zui/toast_controller.js","../../../app/javascript/controllers/zui/tooltip_controller.js","../../../app/components/global/search/controller.js","../../../app/components/layouts/header/controller.js","../../../app/components/layouts/sidebar/controller.js","../../../app/components/time_machine/controller.js","../../../app/javascript/controllers/application.js","../../../app/javascript/controllers/index.js","../../../app/javascript/config/cable_ready.js","../../../app/javascript/config/stimulus_reflex.js","../../../app/javascript/src/textarea_auto_grow.js","../../../app/javascript/entrypoints/application.js"],"sourcesContent":["// Action Cable provides the framework to deal with WebSockets in Rails.\n// You can generate new channels where WebSocket features live using the `rails generate channel` command.\n\nimport { createConsumer } from \"@rails/actioncable\"\n\nexport default createConsumer()\n","// Reconnect ActionCable after switching accounts\n\nimport { Controller } from \"@hotwired/stimulus\"\nimport consumer from \"../channels/consumer\"\n\nexport default class extends Controller {\n reconnect(event) {\n if (consumer.connection.isActive()) {\n consumer.connection.reopen()\n }\n }\n}\n","import { Controller } from '@hotwired/stimulus'\nimport StimulusReflex from 'stimulus_reflex'\n\n// This is the Stimulus ApplicationController.\n// All StimulusReflex controllers should inherit from this class.\n//\n// Example:\n//\n// import ApplicationController from './application_controller'\n//\n// export default class extends ApplicationController { ... }\n//\n// Learn more at: https://docs.stimulusreflex.com\n//\n\nexport default class extends Controller {\n connect () {\n StimulusReflex.register(this)\n }\n\n // Application-wide lifecycle methods\n //\n // Use these methods to handle lifecycle callbacks for all controllers.\n // Using lifecycle methods is optional, so feel free to delete these if you don't need them.\n //\n // Arguments:\n //\n // element - the element that triggered the reflex\n // may be different than the Stimulus controller's this.element\n //\n // reflex - the name of the reflex e.g. \"Example#demo\"\n //\n // error/noop - the error message (for reflexError), otherwise null\n //\n // id - a UUID4 or developer-provided unique identifier for each Reflex\n //\n\n beforeReflex (element, reflex, noop, id) {\n // document.body.classList.add('wait')\n }\n\n reflexQueued (element, reflex, noop, id) {\n // Reflex will be delivered to server upon reconnection\n }\n\n reflexDelivered (element, reflex, noop, id) {\n // Reflex has been delivered to the server\n }\n\n reflexSuccess (element, reflex, noop, id) {\n // show success message\n }\n\n reflexError (element, reflex, error, id) {\n // show error message\n }\n\n reflexForbidden (element, reflex, noop, id) {\n // Reflex action did not have permission to run\n // window.location = '/'\n }\n\n reflexHalted (element, reflex, noop, id) {\n // handle aborted Reflex action\n }\n\n afterReflex (element, reflex, noop, id) {\n // document.body.classList.remove('wait')\n }\n\n finalizeReflex (element, reflex, noop, id) {\n // all operations have completed, animation etc is now safe\n }\n}\n","// Autogrows textareas based on content\n//\n// Example Usage:\n// <%= form.text_area :value, data: {controller: \"autogrow\", action: \"input->autogrow#autogrow\"} %>\n\nimport { Controller } from \"@hotwired/stimulus\"\n\nexport default class extends Controller {\n connect() {\n this.autogrow()\n }\n\n autogrow() {\n this.element.style.height = 'auto';\n this.element.style.height = `${this.element.scrollHeight}px`;\n }\n}\n","import { Controller } from \"@hotwired/stimulus\"\n\nexport default class extends Controller {\n static targets = [ \"dropin\", \"form\" ]\n\n connect() {\n braintree.dropin.create({\n authorization: this.data.get(\"clientToken\"),\n container: this.dropinTarget,\n //threeDSecure: true,\n paypal: {\n flow: \"vault\"\n },\n // Uncomment this to only display PayPal in the Drop-in UI\n //paymentOptionPriority: ['paypal']\n },\n this.clientCreated.bind(this)\n )\n }\n\n clientCreated(error, instance) {\n if (error) {\n console.error(\"Error setting up Braintree dropin:\", error)\n return\n }\n\n this.instance = instance\n }\n\n submit(event) {\n event.preventDefault()\n\n this.instance.requestPaymentMethod(this.paymentMethod.bind(this))\n }\n\n paymentMethod(error, payload) {\n if (error) {\n console.error(\"Error with payment method:\", error)\n return\n }\n\n this.addHiddenField(\"processor\", \"braintree\")\n this.addHiddenField(\"payment_method_token\", payload.nonce)\n\n Rails.fire(this.formTarget, \"submit\")\n }\n\n addHiddenField(name, value) {\n let hiddenInput = document.createElement(\"input\")\n hiddenInput.setAttribute(\"type\", \"hidden\")\n hiddenInput.setAttribute(\"name\", name)\n hiddenInput.setAttribute(\"value\", value)\n this.formTarget.appendChild(hiddenInput)\n }\n}\n","// The BulkController can be used for adding bulk operations to your index views.\n// You can add a Select All checkbox and checkboxes for each record and easily grab\n// the selected records.\n//\n// Usage:\n//\n// import BulkController from \"controllers/bulk_controller\"\n//\n// export default class extends BulkController {\n// }\n\nimport { Controller } from \"@hotwired/stimulus\"\n\nexport default class extends Controller {\n\tstatic targets = [ \"checkbox\", \"selectAll\" ]\n\n // Toggles all checkboxes based upon what is currently checked\n toggleSelectAll(event) {\n (!this.allCheckboxesSelected) ? this.selectAll() : this.unselectAll()\n }\n\n // Selects all checkboxes\n selectAll() {\n this.selectAllTarget.checked = true\n this.selectAllTarget.indeterminate = false\n this.unselected.forEach(target => target.checked = true)\n }\n\n // Unselects all checkboxes\n unselectAll() {\n this.selectAllTarget.checked = false\n this.selectAllTarget.indeterminate = false\n this.selected.forEach(target => target.checked = false)\n }\n\n // Keep track of SelectAll state based upon how many checkboxes are selected\n change(event) {\n if (this.noCheckboxesSelected) {\n this.selectAllTarget.checked = false\n this.selectAllTarget.indeterminate = false\n\n } else if (this.allCheckboxesSelected) {\n this.selectAllTarget.checked = true\n this.selectAllTarget.indeterminate = false\n\n } else {\n this.selectAllTarget.indeterminate = true\n }\n }\n\n // Returns true if Select All checkbox is checked\n get selectedAll() {\n return this.selectAllTarget.checked\n }\n\n // Returns all selected checkboxes\n get selected() {\n return this.checkboxTargets.filter(target => target.checked)\n }\n\n // Returns all unselected checkboxes\n get unselected() {\n return this.checkboxTargets.filter(target => !target.checked)\n }\n\n // Returns data-id attributes for all selected checkboxes\n get selectedIds() {\n return this.selected.map(target => target.dataset.id)\n }\n\n // Returns true if all checkboxes are checked\n get allCheckboxesSelected() {\n return this.checkboxTargets.every(target => target.checked)\n }\n\n // Returns true if no checkboxes are checked\n get noCheckboxesSelected() {\n return this.checkboxTargets.every(target => !target.checked)\n }\n}\n","// Format your content when you are typing with Cleave.js\n//\n// Example Usage:\n// <%= form.text_field :phone, data: {\n// controller: \"cleave\",\n// cleave_options_value: {\n// numeral: true,\n// numeralIntegerScale: 4,\n// numeralDecimalScale: 0,\n// numeralPositiveOnly: true}.to_json\n// } %>\n\nimport { Controller } from \"@hotwired/stimulus\"\nimport Cleave from 'cleave.js'\nimport 'cleave.js/dist/addons/cleave-phone.us'\n\nexport default class extends Controller {\n static values = { options: Object, digits: Number }\n\n connect() {\n console.log(this.optionsValue)\n this.cleave = new Cleave(this.element, this.optionsValue)\n if (this.hasDigitsValue) {\n this.element.addEventListener('beforeinput', this.inputHandler)\n this.element.addEventListener('paste', this.pasteHandler)\n }\n }\n\n disconnect() {\n this.cleave.destroy()\n if (this.hasDigitsValue) {\n this.element.removeEventListener('beforeinput', this.inputHandler)\n this.element.removeEventListener('paste', this.pasteHandler)\n }\n }\n\n inputHandler = event => {\n if (\n String(this.element.value).length >= this.digitsValue &&\n event.inputType === 'insertText'\n )\n event.preventDefault()\n }\n\n pasteHandler = event => {\n if (\n String(event.clipboardData.getData('text')).length >= this.digitsValue\n ) {\n event.preventDefault()\n }\n }\n}\n","// Copy text to clipboard with tippy.js\n//\n// Example Usage:\n// <%= button_tag \"Copy\", data: {controller: \"clipboard\", clipboard_text: \"Hello, world!\"} %>\n// or\n// <%= button_tag \"Copy\", data: {controller: \"clipboard\", clipboard_target: \"#dom_id\"} %>\n\nimport { Controller } from \"@hotwired/stimulus\"\nimport ClipboardJS from \"clipboard\"\nimport tippy from \"tippy.js\";\n\nexport default class extends Controller {\n static values = {\n successMessage: String,\n errorMessage: String\n }\n\n connect() {\n this.clipboard = new ClipboardJS(this.element)\n this.clipboard.on(\"success\", (e) => this.tooltip(this.successMessage))\n this.clipboard.on(\"error\", (e) => this.tooltip(this.errorMessage))\n }\n\n tooltip(message) {\n tippy(this.element, {\n content: message,\n showOnCreate: true,\n onHidden: (instance) => {\n instance.destroy()\n }\n })\n }\n\n get successMessage() {\n return this.successMessageValue || \"Copied!\"\n }\n\n get errorMessage() {\n return this.errorMessageValue || \"Failed!\"\n }\n}\n","// Submit form when the user presses CMD+Enter\n//\n// Example Usage:\n// <%= form_with url: \"/\", data: {controller: \"cmd-enter\"} do %>\n// <%= text_field_tag :search, nil, data: { cmd_enter_target: \"input\" } %>\n// <%= submit_tag \"Search\", data: { cmd_enter_target: \"submit\" } %>\n// <% end %>\n\nimport { Controller } from \"@hotwired/stimulus\";\n\nexport default class extends Controller {\n static targets = [\"input\", \"submit\"];\n\n submit(event) {\n if (!((event.metaKey || event.ctrlKey || event.keyCode == 91 || event.keyCode == 93) && event.keyCode == 13))\n return;\n\n this.submitTarget.click()\n }\n}\n","// Customizable command palette for advanced users\n// Opens with cmd+k or ctrl+k by default\n// https://github.com/excid3/ninja-keys\n\nimport { Controller } from \"@hotwired/stimulus\"\nimport \"@gorails/ninja-keys\"\n\nexport default class extends Controller {\n connect() {\n this.element.data = [\n {\n id: \"Home\",\n title: \"Home\",\n hotkey: \"ctrl+H\",\n icon: '',\n handler: () => {\n Turbo.visit(\"/\")\n }\n },\n {\n id: \"Accounts\",\n title: \"Accounts\",\n hotkey: \"ctrl+A\",\n icon: '',\n handler: () => {\n Turbo.visit(\"/accounts\")\n }\n },\n {\n id: \"Profile\",\n title: \"Profile\",\n hotkey: \"ctrl+P\",\n icon: '',\n handler: () => {\n Turbo.visit(\"/users/edit\")\n }\n },\n {\n id: \"Notifications\",\n title: \"Notifications\",\n hotkey: \"ctrl+N\",\n icon: '',\n handler: () => {\n Turbo.visit(\"/notifications\")\n }\n },\n ];\n }\n}\n","// Crop images with cropperjs\n//\n// Example Usage:\n// Example Usage:\n//\n// <%= tag.div data: {\n// controller: \"cropper\",\n// cropper_circle_value: true,\n// cropper_aspect_ratio_value: 1\n// } do %>\n// <%= image_tag \"path/to/image.jpg\", data: { cropper_target: \"image\" } %>\n// <% end %>\n\nimport { Controller } from \"@hotwired/stimulus\"\nimport Cropper from \"cropperjs\"\n\nexport default class extends Controller {\n static targets = [\"image\"]\n static values = { model: String }\n\n static values = {\n model: String,\n viewMode: { type: Number, default: 1 },\n dragMode: { type: String, default: 'crop' },\n circle: { type: Boolean, default: false },\n aspectRatio: { type: String, default: \"\" }\n }\n\n connect() {\n if (this.circleValue) {\n let style = document.createElement('style')\n style.innerHTML = '.cropper-view-box, .cropper-face { border-radius: 50% !important; }'\n style.innerHTML += '.cropper-view-box { outline: 0; box-shadow: 0 0 0 1px #39f; }'\n document.head.appendChild(style)\n }\n\n let style = document.createElement('style')\n style.innerHTML = '.cropper-bg { background-image: none !important; } .cropper-modal { background-color: rgba(0,0,0,0) !important; }'\n document.head.appendChild(style)\n\n this.data.set(\"has-image\", this.imageTarget.src != \"\")\n }\n\n changed() {\n let _this = this\n const cropper = new Cropper(this.imageTarget, {\n crop(event) {\n _this.crop_x().value = event.detail.x\n _this.crop_y().value = event.detail.y\n _this.crop_width().value = event.detail.width\n _this.crop_height().value = event.detail.height\n },\n aspectRatio: _this.aspectRatioValue,\n viewMode: _this.viewModeValue,\n dragMode: _this.dragModeValue,\n responsive: true\n })\n\n this.data.set(\"has-image\", this.imageTarget.src != \"\")\n\n // Set initial values\n this.crop_x().value = cropper.x\n this.crop_y().value = cropper.y\n this.crop_width().value = cropper.width\n this.crop_height().value = cropper.height\n }\n\n crop_x() {\n if (this._crop_x == undefined) {\n this._crop_x = document.createElement(\"input\")\n this._crop_x.name = `${this.modelValue}[crop_x]`\n this._crop_x.type = \"hidden\"\n this.imageTarget.parentNode.insertBefore(this._crop_x, this.imageTarget.nextSibling)\n }\n return this._crop_x\n }\n\n crop_y() {\n if (this._crop_y == undefined) {\n this._crop_y = document.createElement(\"input\")\n this._crop_y.name = `${this.modelValue}[crop_y]`\n this._crop_y.type = \"hidden\"\n this.imageTarget.parentNode.insertBefore(this._crop_y, this.imageTarget.nextSibling)\n }\n return this._crop_y\n }\n\n crop_width() {\n if (this._crop_width == undefined) {\n this._crop_width = document.createElement(\"input\")\n this._crop_width.name = `${this.modelValue}[crop_width]`\n this._crop_width.type = \"hidden\"\n this.imageTarget.parentNode.insertBefore(this._crop_width, this.imageTarget.nextSibling)\n }\n return this._crop_width\n }\n\n crop_height() {\n if (this._crop_height == undefined) {\n this._crop_height = document.createElement(\"input\")\n this._crop_height.name = `${this.modelValue}[crop_height]`\n this._crop_height.type = \"hidden\"\n this.imageTarget.parentNode.insertBefore(this._crop_height, this.imageTarget.nextSibling)\n }\n return this._crop_height\n }\n\n}\n","// Improved Flatpickr supporting arbitrary date parsing\n//\n// Example Usage:\n// <%= text_field_tag \"date\", nil, data: { controller: \"datepicker\" } %>\n\nimport Flatpickr from \"stimulus-flatpickr\";\nimport dayjs from \"dayjs\";\n\nexport default class extends Flatpickr {\n static values = {\n submitOnChange: { type: Boolean, default: false },\n selectOnFocus: { type: Boolean, default: true },\n swallowPaste: { type: Boolean, default: true }\n }\n\n initialize() {\n this.config = {\n parseDate: (dateString) => {\n if (dateString && dateString.length > 0) {\n let parsed = dayjs(dateString);\n if (parsed.isValid()) return parsed.toDate();\n }\n }\n }\n\n if (!this.element.hasAttribute(\"autocomplete\"))\n this.element.setAttribute(\"autocomplete\", \"off\");\n }\n\n connect() {\n super.connect();\n const _this = this;\n\n setTimeout(() => {\n _this.visibleInput = _this.fp.input.nextElementSibling;\n if (!_this.visibleInput || _this.visibleInput.type !== 'text') {\n _this.visibleInput = null;\n return\n }\n\n if (_this.selectOnFocusValue) {\n _this.visibleInput.addEventListener(\"focus\", () => {\n _this.visibleInput.select();\n });\n }\n\n if (_this.swallowPasteValue) {\n _this.visibleInput.addEventListener(\"paste\", (e) => {\n e.preventDefault();\n let text = e.clipboardData.getData(\"text/plain\");\n _this.fp.setDate(text, false);\n });\n }\n }, 300);\n }\n\n change(selectedDates, dateStr, instance) {\n if (dateStr && this.submitOnChangeValue) this.element.form.requestSubmit();\n }\n}\n","// Disable form after submission to prevent double submit\n//\n// Example Usage:\n// <%= form_with url: \"/\", data: { controller: \"disable-submission\", disable_submission_with_value: \"Submitting...\" } %>\n\nimport { Controller } from \"@hotwired/stimulus\";\n\nexport default class extends Controller {\n static values = { with: String };\n\n connect() {\n this.element.dataset[\"action\"] ||= \"\";\n this.element.dataset[\"action\"] += \" submit->disable-submission#disableForm\";\n this.element.dataset[\"action\"].trim();\n }\n\n disableForm() {\n this.submitButtons().forEach((button) => {\n button.disabled = true;\n if (this.hasWithValue) button.value = this.withValue;\n });\n }\n\n submitButtons() {\n return this.element.querySelectorAll(\"input[type='submit'], button[type='submit']\");\n }\n}\n","\n// This controller is used to drag and drop students between rooms\nimport Sortable from '@stimulus-components/sortable';\n\nexport default class extends Sortable {\n connect() {\n super.connect();\n\n this.modalFrame = document.querySelector('turbo-frame[id=\"modal\"]');\n this.modalFrame.addEventListener('modal:closed', this.loadListener);\n }\n\n disconnect() {\n super.disconnect();\n }\n\n get options() {\n let options = super.options\n options[\"group\"] = \"drag-drop-student-room\"\n options[\"sort\"] = false\n options[\"onMove\"] = this.onMove\n options[\"onEnd\"] = this.onEnd.bind(this)\n return options\n }\n\n get defaultOptions() {\n return {\n animation: 200,\n }\n }\n\n // always add item to end of list\n onMove(event) {\n if (event.to !== event.from) {\n event.to.appendChild(event.dragged);\n return false;\n }\n }\n\n // show modal when dropped in new container\n onEnd(event) {\n if (event.to === event.from) {\n return\n }\n\n // dim the item while awaiting confirmation from modal\n event.item.querySelector('img')?.classList?.add(...this.dimmedClasses())\n\n // Show modal\n const url = this.modalUrl(event.item, event.to.dataset.roomId, event.to.dataset.contextDate)\n\n if (url) Turbo.visit(url.href, { frame: \"modal\" })\n }\n\n modalUrl(item, toRoomId, date) {\n if (item.dataset.transitionModalUrl) {\n let url = new URL(item.dataset.transitionModalUrl)\n url.searchParams.append(\"program_enrollment[room_id]\", toRoomId)\n url.searchParams.append(\"program_enrollment[start_date]\", date)\n url.searchParams.append(\"origin_url\", window.location.href)\n return url\n }\n }\n\n dimmedClasses() {\n return [\"opacity-90\", \"h-8\", \"w-8\", \"border-2\", \"border-dotted\", \"border-gray-300\", \"p-1\"]\n }\n}\n\n","// Dropdown menu with click outside\n//\n// Example Usage:\n//\n//
... | \n//
Load More | \n//