diff --git a/src/api/Gemfile b/src/api/Gemfile index 41a7e209ab8..a75d2506cae 100644 --- a/src/api/Gemfile +++ b/src/api/Gemfile @@ -123,6 +123,9 @@ gem 'stringio', '3.1.2' # OpenStruct implementation (no longer a default gem from ruby > 3.4.0) gem 'ostruct' +# For markdown editor +gem 'marksmith' + group :development, :production do # to have the delayed job daemon gem 'daemons' diff --git a/src/api/Gemfile.lock b/src/api/Gemfile.lock index 67fe4590a71..2aa15959046 100644 --- a/src/api/Gemfile.lock +++ b/src/api/Gemfile.lock @@ -285,6 +285,8 @@ GEM net-pop net-smtp marcel (1.0.4) + marksmith (0.4.7) + activesupport matrix (0.4.3) method_source (1.1.0) middleware (0.1.0) @@ -643,6 +645,7 @@ DEPENDENCIES kaminari launchy lograge + marksmith minitest minitest-ci minitest-fail-fast diff --git a/src/api/app/assets/javascripts/webui/canned_responses.js b/src/api/app/assets/javascripts/webui/canned_responses.js index 81c252a434b..33854e80e3c 100644 --- a/src/api/app/assets/javascripts/webui/canned_responses.js +++ b/src/api/app/assets/javascripts/webui/canned_responses.js @@ -12,5 +12,6 @@ function setupCannedResponses() { // jshint ignore:line } // we have to enable the submit button for the comments form $(e.target).closest('[class*="-comment-form"]').find('input[type="submit"]').prop('disabled', false); + $('.decision-add-comment').prop('disabled', false); }); } diff --git a/src/api/app/assets/javascripts/webui/color_themes.js b/src/api/app/assets/javascripts/webui/color_themes.js index 5f446115412..84e14cd016e 100644 --- a/src/api/app/assets/javascripts/webui/color_themes.js +++ b/src/api/app/assets/javascripts/webui/color_themes.js @@ -3,6 +3,12 @@ const setTheme = theme => { document.documentElement.dataset.bsTheme = theme; + + if (theme === 'dark') { + document.documentElement.classList.add('dark'); + } else { + document.documentElement.classList.remove('dark'); + } }; const getTheme = () => { diff --git a/src/api/app/assets/javascripts/webui/comment.js b/src/api/app/assets/javascripts/webui/comment.js index 0d70de8ea6e..a32f6a91621 100644 --- a/src/api/app/assets/javascripts/webui/comment.js +++ b/src/api/app/assets/javascripts/webui/comment.js @@ -32,6 +32,7 @@ function handlingCommentEvents() { // Disable submit button if textarea is empty and enable otherwise $(document).on('input', '.write-and-preview textarea', function(e) { validateForm(e); + $('.decision-add-comment').prop('disabled', false); resizeTextarea(this); }); diff --git a/src/api/app/components/request_decision_component.html.haml b/src/api/app/components/request_decision_component.html.haml index bd946ac58ea..1c1fc7e4420 100644 --- a/src/api/app/components/request_decision_component.html.haml +++ b/src/api/app/components/request_decision_component.html.haml @@ -1,5 +1,5 @@ .request-decision.mt-n1 - = form_with(url: request_changerequest_path, html: { id: 'request_handle_form' }, local: true) do |form| + = form_with(model: @bs_request.reviews.new, url: request_changerequest_path, html: { id: 'request_handle_form' }, local: true) do |form| = hidden_field_tag(:number, @bs_request.number) .pb-2{ 'data-canned-controller': '' } - if policy(Comment.new(commentable: @bs_request)).locked? @@ -10,12 +10,13 @@ - decision_placeholder = "Write your comment or decision...(markdown is only supported for comments, not for decisions)" = render WriteAndPreviewComponent.new(form: form, preview_message_url: preview_comments_path, canned_responses_enabled: true, message_body_param: 'comment[body]', - text_area_attributes: { object_name: 'reason', id_suffix: 'new_comment', + text_area_attributes: { object_name: 'reason', id_suffix: 'new_comment', required: true, placeholder: decision_placeholder}) .mt-2#decision-buttons-row %div - if policy(Comment.new(commentable:@bs_request)).create? - = submit_tag 'Add comment', class: 'btn btn-outline-primary me-2', data: { disable_with: 'Creating comment...' }, name: 'commented' + = submit_tag 'Add comment', class: 'btn btn-outline-primary me-2 decision-add-comment', data: { disable_with: 'Creating comment...' }, + name: 'commented', disabled: true %div - if policy(@bs_request).revoke_request? = submit_tag('Revoke request', name: 'revoked', class: 'btn btn-danger me-2', diff --git a/src/api/app/components/request_decision_component.rb b/src/api/app/components/request_decision_component.rb index 4fbfcde7560..98d06cae161 100644 --- a/src/api/app/components/request_decision_component.rb +++ b/src/api/app/components/request_decision_component.rb @@ -1,4 +1,7 @@ class RequestDecisionComponent < ApplicationComponent + # This is required to help marksmith render the markdown editor + delegate :main_app, to: :helpers + def initialize(bs_request:, package_maintainers:, show_project_maintainer_hint:) super diff --git a/src/api/app/components/write_and_preview_component.html.haml b/src/api/app/components/write_and_preview_component.html.haml index 0e9c888630e..85a8a53eba5 100644 --- a/src/api/app/components/write_and_preview_component.html.haml +++ b/src/api/app/components/write_and_preview_component.html.haml @@ -1,23 +1,20 @@ -.card.write-and-preview{ data: { preview_message_url: preview_message_url, message_body_param: message_body_param } } - %ul.card-header.nav.nav-tabs.px-3.pt-2.pb-0.disable-link-generation{ role: 'tablist' } - %li.nav-item - = link_to('Write', "#write_#{text_area_attributes[:id_suffix]}", class: 'nav-link active', data: { 'bs-toggle': 'tab' }, role: 'tab', - aria: { controls: 'write-message-tab', selected: 'true' }) - %li.nav-item - = link_to('Preview', "#preview_#{text_area_attributes[:id_suffix]}", class: 'nav-link preview-message-tab', - data: { 'bs-toggle': 'tab', preview_message_url: preview_message_url }, - role: 'tab', aria: { controls: 'preview-message-tab', selected: 'false' }) - .tab-content.px-3 - .tab-pane.fade.show.active.my-3{ id: "write_#{text_area_attributes[:id_suffix]}", - role: 'tabpanel', 'aria-labelledby': 'write-message-tab', 'data-canned-controller': '' } - - if Flipper.enabled?(:canned_responses, User.session) && canned_responses_enabled - .d-flex.justify-content-end - = render CannedResponsesDropdownComponent.new(User.session.canned_responses.where(decision_type: nil).order(:title)) - ~ form.text_area(text_area_attributes[:object_name], id: "#{text_area_attributes[:id_suffix]}_body", - rows: text_area_attributes[:rows], required: text_area_attributes[:required], - placeholder: text_area_attributes[:placeholder], class: 'w-100 form-control message-field') - .tab-pane.fade{ id: "preview_#{text_area_attributes[:id_suffix]}", role: 'tabpanel', 'aria-labelledby': 'preview-message-tab' } - .message-preview.my-3 +%markdown-toolbar.write-and-preview{ id: "write_#{text_area_attributes[:id_suffix]}", + role: 'tabpanel', 'aria-labelledby': 'write-message-tab', + 'data-canned-controller': '' } + - if Flipper.enabled?(:canned_responses, User.session) && canned_responses_enabled + .d-flex.justify-content-end + = render CannedResponsesDropdownComponent.new(User.session.canned_responses.where(decision_type: nil).order(:title)) + = form.marksmith(text_area_attributes[:object_name], + id: "#{text_area_attributes[:id_suffix]}_body", + rows: text_area_attributes[:rows], + required: text_area_attributes[:required], + placeholder: text_area_attributes[:placeholder], + enable_file_uploads: false, + upload_url: nil, + maxlength: text_area_attributes[:maxlength], + class: "w-100 form-control message-field") + .tab-pane.fade{ id: "preview_#{text_area_attributes[:id_suffix]}", role: 'tabpanel', 'aria-labelledby': 'preview-message-tab' } + .message-preview.my-3 :javascript attachPreviewMessageOnCommentBoxes(); diff --git a/src/api/app/controllers/webui/request_controller.rb b/src/api/app/controllers/webui/request_controller.rb index fb57805d051..7b9cc8d8d44 100644 --- a/src/api/app/controllers/webui/request_controller.rb +++ b/src/api/app/controllers/webui/request_controller.rb @@ -214,7 +214,7 @@ def changerequest if changestate == 'commented' - build_new_comment(@bs_request, body: params[:reason]) + build_new_comment(@bs_request, body: params.dig(:review, :reason)) elsif change_state(changestate, params) # TODO: Make this work for each submit action individually @@ -440,7 +440,7 @@ def change_state(newstate, params) newstate: newstate, force: true, user: User.session.login, - comment: params[:reason] + comment: params.dig(:review, :reason) } begin request.change_state(opts) diff --git a/src/api/app/javascript/application.js b/src/api/app/javascript/application.js index d4544d38710..e63f20d9063 100644 --- a/src/api/app/javascript/application.js +++ b/src/api/app/javascript/application.js @@ -2,5 +2,12 @@ import "@hotwired/turbo-rails" import "src/turbo_error" -// We can't use session drive, since our existing js doesn't expect it +import { Application } from "@hotwired/stimulus" +import { MarksmithController, ListContinuationController } from "@avo-hq/marksmith" + +// Start Stimulus application +const application = Application.start() +application.register("marksmith", MarksmithController) +application.register("list-continuation", ListContinuationController) + Turbo.session.drive = false diff --git a/src/api/app/views/layouts/webui/webui.html.haml b/src/api/app/views/layouts/webui/webui.html.haml index 88faa41df90..a8ab732bad5 100644 --- a/src/api/app/views/layouts/webui/webui.html.haml +++ b/src/api/app/views/layouts/webui/webui.html.haml @@ -22,6 +22,7 @@ %meta{ property: 'errbit:host', content: CONFIG['errbit_javascript_host'] } = stylesheet_link_tag 'webui/application' + = stylesheet_link_tag "marksmith" = javascript_include_tag 'webui/application' = javascript_importmap_tags diff --git a/src/api/app/views/webui/package/new.html.haml b/src/api/app/views/webui/package/new.html.haml index 24dbf1f98b4..2cedeed4285 100644 --- a/src/api/app/views/webui/package/new.html.haml +++ b/src/api/app/views/webui/package/new.html.haml @@ -10,7 +10,7 @@ .col-12 %h3= @pagetitle .col-12.col-md-9.col-lg-6 - = form_for(:package, url: packages_url(@project)) do |f| + = form_for(@project.packages.new, url: packages_url(@project)) do |f| .mb-3 = f.label(:name) = render partial: 'webui/shared/required_label_mark' diff --git a/src/api/app/views/webui/user/_edit_account_form.html.haml b/src/api/app/views/webui/user/_edit_account_form.html.haml index 6b3b8988995..dd7ca550de7 100644 --- a/src/api/app/views/webui/user/_edit_account_form.html.haml +++ b/src/api/app/views/webui/user/_edit_account_form.html.haml @@ -13,7 +13,11 @@ %span.badge.text-bg-secondary = title.upcase .mb-3 - = f.text_area(:biography, rows: 6, placeholder: 'Biography', maxlength: User::MAX_BIOGRAPHY_LENGTH_ALLOWED, class: 'form-control') + = render WriteAndPreviewComponent.new(form: f, preview_message_url: nil, message_body_param: nil, + text_area_attributes: { rows: 6, placeholder: 'Biography', + required: false, object_name: :biography, + maxlength: User::MAX_BIOGRAPHY_LENGTH_ALLOWED}) + = f.label(:biography, class: 'd-block text-end') do %small.form-text#bio-chars-counter .mb-3 diff --git a/src/api/config/importmap.rb b/src/api/config/importmap.rb index fc115abb01d..5f8c57f33d3 100644 --- a/src/api/config/importmap.rb +++ b/src/api/config/importmap.rb @@ -3,3 +3,5 @@ pin "application" pin_all_from 'app/javascript/src', under: 'src', to: 'src' pin "@hotwired/turbo-rails", to: "turbo.min.js" +pin "@hotwired/stimulus", to: "https://ga.jspm.io/npm:@hotwired/stimulus@3.2.1/dist/stimulus.js" +pin "@avo-hq/marksmith", to: "@avo-hq--marksmith.js" # 0.4.7 diff --git a/src/api/config/initializers/assets.rb b/src/api/config/initializers/assets.rb index 4be85d8e6f3..6b75a9564a6 100644 --- a/src/api/config/initializers/assets.rb +++ b/src/api/config/initializers/assets.rb @@ -10,3 +10,7 @@ # application.js, application.css, and all non-JS/CSS in the app/assets # folder are already added. Rails.application.config.assets.precompile += ['webui.js'] + +# Don't compress css because we use sassc-rails compressor to compress +# css which does not support tailwind functions +Rails.application.config.assets.css_compressor = nil diff --git a/src/api/config/initializers/marksmith.rb b/src/api/config/initializers/marksmith.rb new file mode 100644 index 00000000000..c636b1313fe --- /dev/null +++ b/src/api/config/initializers/marksmith.rb @@ -0,0 +1,5 @@ +Marksmith.configure do |config| + config.automatically_mount_engine = true + config.mount_path = "/marksmith" + config.parser = "redcarpet" +end diff --git a/src/api/spec/features/beta/webui/maintenance_workflow_spec.rb b/src/api/spec/features/beta/webui/maintenance_workflow_spec.rb index 1c44019e9d1..bb56c477482 100644 --- a/src/api/spec/features/beta/webui/maintenance_workflow_spec.rb +++ b/src/api/spec/features/beta/webui/maintenance_workflow_spec.rb @@ -51,7 +51,7 @@ login(maintenance_coord_user) visit request_show_path(bs_request) - fill_in('reason', with: 'really? ok') + fill_in('review[reason]', with: 'really? ok') accept_alert do click_button('Accept') @@ -96,7 +96,7 @@ login(maintenance_coord_user) visit request_show_path(bs_request) - fill_in('reason', with: 'really? ok') + fill_in('review[reason]', with: 'really? ok') accept_alert do click_button('Accept') diff --git a/src/api/spec/features/webui/requests/diff_comments_spec.rb b/src/api/spec/features/webui/requests/diff_comments_spec.rb index 71e610bfead..920d84cb57d 100644 --- a/src/api/spec/features/webui/requests/diff_comments_spec.rb +++ b/src/api/spec/features/webui/requests/diff_comments_spec.rb @@ -32,7 +32,7 @@ click_on "reply_button_of_#{comment.id}" within("#reply_for_#{comment.id}_form") do - fill_in "reply_for_#{comment.id}_body", with: 'This is a new reply' + fill_in "reply_for_#{comment.id}_body-textarea", with: 'This is a new reply' click_on 'Add comment' end end @@ -61,7 +61,7 @@ find('a', class: 'line-new-comment').click # Wait for comment box to appear find_by_id('new_comment_diff_0_n2_form').visible? - fill_in 'new_comment_diff_0_n2_body', with: 'My test diff comment' + fill_in 'new_comment_diff_0_n2_body-textarea', with: 'My test diff comment' find('input[type="submit"]').click end # Wait for the comment to be created and appear back diff --git a/src/api/vendor/cache/marksmith-0.4.7.gem b/src/api/vendor/cache/marksmith-0.4.7.gem new file mode 100644 index 00000000000..9ffda901e74 Binary files /dev/null and b/src/api/vendor/cache/marksmith-0.4.7.gem differ diff --git a/src/api/vendor/javascript/@avo-hq--marksmith.js b/src/api/vendor/javascript/@avo-hq--marksmith.js new file mode 100644 index 00000000000..5846987d104 --- /dev/null +++ b/src/api/vendor/javascript/@avo-hq--marksmith.js @@ -0,0 +1,4 @@ +// @avo-hq/marksmith@0.4.7 downloaded from https://ga.jspm.io/npm:@avo-hq/marksmith@0.4.7/dist/marksmith.esm.js + +var t=(void 0,function(t,e,n,r){if(n==="a"&&!r)throw new TypeError("Private accessor was defined without a getter");if(typeof e==="function"?t!==e||!r:!e.has(t))throw new TypeError("Cannot read private member from an object whose class did not declare it");return n==="m"?r:n==="a"?r.call(t):r?r.value:e.get(t)});var e,n;const r=["[data-md-button]","md-header","md-bold","md-italic","md-quote","md-code","md-link","md-image","md-unordered-list","md-ordered-list","md-task-list","md-mention","md-ref","md-strikethrough"];function i(t){const e=[];for(const n of t.querySelectorAll(r.join(", ")))n.hidden||n.offsetWidth<=0&&n.offsetHeight<=0||n.closest("markdown-toolbar")===t&&e.push(n);return e}function s(t){return function(e){e.key!==" "&&e.key!=="Enter"||t(e)}}const o=new WeakMap;const a={"header-1":{prefix:"# "},"header-2":{prefix:"## "},"header-3":{prefix:"### "},"header-4":{prefix:"#### "},"header-5":{prefix:"##### "},"header-6":{prefix:"###### "},bold:{prefix:"**",suffix:"**",trimFirst:true},italic:{prefix:"_",suffix:"_",trimFirst:true},quote:{prefix:"> ",multiline:true,surroundWithNewlines:true},code:{prefix:"`",suffix:"`",blockPrefix:"```",blockSuffix:"```"},link:{prefix:"[",suffix:"](url)",replaceNext:"url",scanFor:"https?://"},image:{prefix:"![",suffix:"](url)",replaceNext:"url",scanFor:"https?://"},"unordered-list":{prefix:"- ",multiline:true,unorderedList:true},"ordered-list":{prefix:"1. ",multiline:true,orderedList:true},"task-list":{prefix:"- [ ] ",multiline:true,surroundWithNewlines:true},mention:{prefix:"@",prefixSpace:true},ref:{prefix:"#",prefixSpace:true},strikethrough:{prefix:"~~",suffix:"~~",trimFirst:true}};class MarkdownButtonElement extends HTMLElement{constructor(){super();const t=t=>{const e=o.get(this);if(e){t.preventDefault();B(this,e)}};this.addEventListener("keydown",s(t));this.addEventListener("click",t)}connectedCallback(){this.hasAttribute("role")||this.setAttribute("role","button")}click(){const t=o.get(this);t&&B(this,t)}}class MarkdownHeaderButtonElement extends MarkdownButtonElement{constructor(){super(...arguments);e.add(this)}connectedCallback(){const r=parseInt(this.getAttribute("level")||"3",10);t(this,e,"m",n).call(this,r)}static get observedAttributes(){return["level"]}attributeChangedCallback(r,i,s){if(r!=="level")return;const o=parseInt(s||"3",10);t(this,e,"m",n).call(this,o)}}e=new WeakSet,n=function(t){if(t<1||t>6)return;const e=`${"#".repeat(t)} `;o.set(this,{prefix:e})};if(!window.customElements.get("md-header")){window.MarkdownHeaderButtonElement=MarkdownHeaderButtonElement;window.customElements.define("md-header",MarkdownHeaderButtonElement)}class MarkdownBoldButtonElement extends MarkdownButtonElement{connectedCallback(){o.set(this,{prefix:"**",suffix:"**",trimFirst:true})}}if(!window.customElements.get("md-bold")){window.MarkdownBoldButtonElement=MarkdownBoldButtonElement;window.customElements.define("md-bold",MarkdownBoldButtonElement)}class MarkdownItalicButtonElement extends MarkdownButtonElement{connectedCallback(){o.set(this,{prefix:"_",suffix:"_",trimFirst:true})}}if(!window.customElements.get("md-italic")){window.MarkdownItalicButtonElement=MarkdownItalicButtonElement;window.customElements.define("md-italic",MarkdownItalicButtonElement)}class MarkdownQuoteButtonElement extends MarkdownButtonElement{connectedCallback(){o.set(this,{prefix:"> ",multiline:true,surroundWithNewlines:true})}}if(!window.customElements.get("md-quote")){window.MarkdownQuoteButtonElement=MarkdownQuoteButtonElement;window.customElements.define("md-quote",MarkdownQuoteButtonElement)}class MarkdownCodeButtonElement extends MarkdownButtonElement{connectedCallback(){o.set(this,{prefix:"`",suffix:"`",blockPrefix:"```",blockSuffix:"```"})}}if(!window.customElements.get("md-code")){window.MarkdownCodeButtonElement=MarkdownCodeButtonElement;window.customElements.define("md-code",MarkdownCodeButtonElement)}class MarkdownLinkButtonElement extends MarkdownButtonElement{connectedCallback(){o.set(this,{prefix:"[",suffix:"](url)",replaceNext:"url",scanFor:"https?://"})}}if(!window.customElements.get("md-link")){window.MarkdownLinkButtonElement=MarkdownLinkButtonElement;window.customElements.define("md-link",MarkdownLinkButtonElement)}class MarkdownImageButtonElement extends MarkdownButtonElement{connectedCallback(){o.set(this,{prefix:"![",suffix:"](url)",replaceNext:"url",scanFor:"https?://"})}}if(!window.customElements.get("md-image")){window.MarkdownImageButtonElement=MarkdownImageButtonElement;window.customElements.define("md-image",MarkdownImageButtonElement)}class MarkdownUnorderedListButtonElement extends MarkdownButtonElement{connectedCallback(){o.set(this,{prefix:"- ",multiline:true,unorderedList:true})}}if(!window.customElements.get("md-unordered-list")){window.MarkdownUnorderedListButtonElement=MarkdownUnorderedListButtonElement;window.customElements.define("md-unordered-list",MarkdownUnorderedListButtonElement)}class MarkdownOrderedListButtonElement extends MarkdownButtonElement{connectedCallback(){o.set(this,{prefix:"1. ",multiline:true,orderedList:true})}}if(!window.customElements.get("md-ordered-list")){window.MarkdownOrderedListButtonElement=MarkdownOrderedListButtonElement;window.customElements.define("md-ordered-list",MarkdownOrderedListButtonElement)}class MarkdownTaskListButtonElement extends MarkdownButtonElement{connectedCallback(){o.set(this,{prefix:"- [ ] ",multiline:true,surroundWithNewlines:true})}}if(!window.customElements.get("md-task-list")){window.MarkdownTaskListButtonElement=MarkdownTaskListButtonElement;window.customElements.define("md-task-list",MarkdownTaskListButtonElement)}class MarkdownMentionButtonElement extends MarkdownButtonElement{connectedCallback(){o.set(this,{prefix:"@",prefixSpace:true})}}if(!window.customElements.get("md-mention")){window.MarkdownMentionButtonElement=MarkdownMentionButtonElement;window.customElements.define("md-mention",MarkdownMentionButtonElement)}class MarkdownRefButtonElement extends MarkdownButtonElement{connectedCallback(){o.set(this,{prefix:"#",prefixSpace:true})}}if(!window.customElements.get("md-ref")){window.MarkdownRefButtonElement=MarkdownRefButtonElement;window.customElements.define("md-ref",MarkdownRefButtonElement)}class MarkdownStrikethroughButtonElement extends MarkdownButtonElement{connectedCallback(){o.set(this,{prefix:"~~",suffix:"~~",trimFirst:true})}}if(!window.customElements.get("md-strikethrough")){window.MarkdownStrikethroughButtonElement=MarkdownStrikethroughButtonElement;window.customElements.define("md-strikethrough",MarkdownStrikethroughButtonElement)}function c(t){const{target:e,currentTarget:n}=t;if(!(e instanceof Element))return;const r=e.closest("[data-md-button]");if(!r||r.closest("markdown-toolbar")!==n)return;const i=r.getAttribute("data-md-button");const s=a[i];if(s){t.preventDefault();B(e,s)}}function l(t){t.addEventListener("keydown",h);t.setAttribute("tabindex","0");t.addEventListener("focus",d,{once:true})}function u(t){t.removeEventListener("keydown",h);t.removeAttribute("tabindex");t.removeEventListener("focus",d)}class MarkdownToolbarElement extends HTMLElement{connectedCallback(){this.hasAttribute("role")||this.setAttribute("role","toolbar");this.hasAttribute("data-no-focus")||l(this);this.addEventListener("keydown",s(c));this.addEventListener("click",c)}attributeChangedCallback(t,e,n){t==="data-no-focus"&&(n===null?l(this):u(this))}disconnectedCallback(){u(this)}get field(){const t=this.getAttribute("for");if(!t)return null;const e="getRootNode"in this?this.getRootNode():document;let n;(e instanceof Document||e instanceof ShadowRoot)&&(n=e.getElementById(t));return n instanceof HTMLTextAreaElement?n:null}}MarkdownToolbarElement.observedAttributes=["data-no-focus"];function d({target:t}){if(!(t instanceof Element))return;t.removeAttribute("tabindex");let e="0";for(const n of i(t)){n.setAttribute("tabindex",e);if(e==="0"){n.focus();e="-1"}}}function h(t){const e=t.key;if(e!=="ArrowRight"&&e!=="ArrowLeft"&&e!=="Home"&&e!=="End")return;const n=t.currentTarget;if(!(n instanceof HTMLElement))return;const r=i(n);const s=r.indexOf(t.target);const o=r.length;if(s===-1)return;let a=0;e==="ArrowLeft"&&(a=s-1);e==="ArrowRight"&&(a=s+1);e==="End"&&(a=o-1);a<0&&(a=o-1);a>o-1&&(a=0);for(let t=0;t1}function p(t,e){return Array(e+1).join(t)}function m(t,e){let n=e;while(t[n]&&t[n-1]!=null&&!t[n-1].match(/\s/))n--;return n}function g(t,e,n){let r=e;const i=n?/\n/:/\s/;while(t[r]&&!t[r].match(i))r++;return r}let w=null;function b(t,{text:e,selectionStart:n,selectionEnd:r}){const i=t.selectionStart;const s=t.value.slice(0,i);const o=t.value.slice(t.selectionEnd);if(w===null||w===true){t.contentEditable="true";try{w=document.execCommand("insertText",false,e)}catch(t){w=false}t.contentEditable="false"}w&&!t.value.slice(0,t.selectionStart).endsWith(e)&&(w=false);if(!w){try{document.execCommand("ms-beginUndoUnit")}catch(t){}t.value=s+e+o;try{document.execCommand("ms-endUndoUnit")}catch(t){}t.dispatchEvent(new CustomEvent("input",{bubbles:true,cancelable:true}))}n!=null&&r!=null?t.setSelectionRange(n,r):t.setSelectionRange(i,t.selectionEnd)}function y(t,e){const n=t.value.slice(t.selectionStart,t.selectionEnd);let r;r=e.orderedList||e.unorderedList?M(t,e):e.multiline&&f(n)?T(t,e):k(t,e);b(t,r)}function E(t){const e=t.value.split("\n");let n=0;for(let r=0;r=n&&t.selectionStart=n&&t.selectionEnd0?`${o}\n`:i;let w=f(m)&&a.length>0?`\n${a}`:s;if(l){const e=t.value[t.selectionStart-1];t.selectionStart===0||e==null||e.match(/\s/)||(g=` ${g}`)}m=v(t,g,w,e.multiline);let b=t.selectionStart;let y=t.selectionEnd;const E=c.length>0&&w.indexOf(c)>-1&&m.length>0;if(d){const e=x(t);n=e.newlinesToAppend;r=e.newlinesToPrepend;g=n+i;w+=r}if(m.startsWith(g)&&m.endsWith(w)){const t=m.slice(g.length,m.length-w.length);if(h===p){let e=h-g.length;e=Math.max(e,b);e=Math.min(e,b+t.length);b=y=e}else y=b+t.length;return{text:t,selectionStart:b,selectionEnd:y}}if(E){if(u.length>0&&m.match(u)){w=w.replace(c,m);const t=g+w;b=y=b+g.length;return{text:t,selectionStart:b,selectionEnd:y}}{const t=g+m+w;b=b+g.length+m.length+w.indexOf(c);y=b+c.length;return{text:t,selectionStart:b,selectionEnd:y}}}{let t=g+m+w;b=h+g.length;y=p+g.length;const n=m.match(/^\s*|\s*$/g);if(e.trimFirst&&n){const e=n[0]||"";const r=n[1]||"";t=e+g+m.trim()+w+r;b+=e.length;y-=r.length}return{text:t,selectionStart:b,selectionEnd:y}}}function T(t,e){const{prefix:n,suffix:r,surroundWithNewlines:i}=e;let s=t.value.slice(t.selectionStart,t.selectionEnd);let o=t.selectionStart;let a=t.selectionEnd;const c=s.split("\n");const l=c.every((t=>t.startsWith(n)&&t.endsWith(r)));if(l){s=c.map((t=>t.slice(n.length,t.length-r.length))).join("\n");a=o+s.length}else{s=c.map((t=>n+t+r)).join("\n");if(i){const{newlinesToAppend:e,newlinesToPrepend:n}=x(t);o+=e.length;a=o+s.length;s=e+s+n}}return{text:s,selectionStart:o,selectionEnd:a}}function S(t){const e=t.split("\n");const n=/^\d+\.\s+/;const r=e.every((t=>n.test(t)));let i=e;r&&(i=e.map((t=>t.replace(n,""))));return{text:i.join("\n"),processed:r}}function L(t){const e=t.split("\n");const n="- ";const r=e.every((t=>t.startsWith(n)));let i=e;r&&(i=e.map((t=>t.slice(n.length,t.length))));return{text:i.join("\n"),processed:r}}function A(t,e){return e?"- ":`${t+1}. `}function C(t,e){let n;let r;let i;if(t.orderedList){r=S(e);n=L(r.text);i=n.text}else{r=L(e);n=S(r.text);i=n.text}return[r,n,i]}function M(t,e){const n=t.selectionStart===t.selectionEnd;let r=t.selectionStart;let i=t.selectionEnd;E(t);const s=t.value.slice(t.selectionStart,t.selectionEnd);const[o,a,c]=C(e,s);const l=c.split("\n").map(((t,n)=>`${A(n,e.unorderedList)}${t}`));const u=l.reduce(((t,n,r)=>t+A(r,e.unorderedList).length),0);const d=l.reduce(((t,n,r)=>t+A(r,!e.unorderedList).length),0);if(o.processed){if(n){r=Math.max(r-A(0,e.unorderedList).length,0);i=r}else{r=t.selectionStart;i=t.selectionEnd-u}return{text:c,selectionStart:r,selectionEnd:i}}const{newlinesToAppend:h,newlinesToPrepend:f}=x(t);const p=h+l.join("\n")+f;if(n){r=Math.max(r+A(0,e.unorderedList).length+h.length,0);i=r}else if(a.processed){r=Math.max(t.selectionStart+h.length,0);i=t.selectionEnd+h.length+u-d}else{r=Math.max(t.selectionStart+h.length,0);i=t.selectionEnd+h.length+u}return{text:p,selectionStart:r,selectionEnd:i}}function B(t,e){const n=t.closest("markdown-toolbar");if(!(n instanceof MarkdownToolbarElement))return;const r={prefix:"",suffix:"",blockPrefix:"",blockSuffix:"",multiline:false,replaceNext:"",prefixSpace:false,scanFor:"",surroundWithNewlines:false,orderedList:false,unorderedList:false,trimFirst:false};const i=Object.assign(Object.assign({},r),e);const s=n.field;if(s){s.focus();y(s,i)}}function $(t){return t.replace(/(?:[_-])([a-z0-9])/g,((t,e)=>e.toUpperCase()))}function j(t){return $(t.replace(/--/g,"-").replace(/__/g,"_"))}function U(t){return t.charAt(0).toUpperCase()+t.slice(1)}function R(t){return t.replace(/([A-Z])/g,((t,e)=>`-${e.toLowerCase()}`))}function _(t){return t!==null&&t!==void 0}function D(t,e){return Object.prototype.hasOwnProperty.call(t,e)}function O(t,e){const n=P(t);return Array.from(n.reduce(((t,n)=>{q(n,e).forEach((e=>t.add(e)));return t}),new Set))}function F(t,e){const n=P(t);return n.reduce(((t,n)=>{t.push(...N(n,e));return t}),[])}function P(t){const e=[];while(t){e.push(t);t=Object.getPrototypeOf(t)}return e.reverse()}function q(t,e){const n=t[e];return Array.isArray(n)?n:[]}function N(t,e){const n=t[e];return n?Object.keys(n).map((t=>[t,n[t]])):[]}(()=>{function t(t){function e(){return Reflect.construct(t,arguments,new.target)}e.prototype=Object.create(t.prototype,{constructor:{value:e}});Reflect.setPrototypeOf(e,t);return e}function e(){const e=function(){this.a.call(this)};const n=t(e);n.prototype.a=function(){};return new n}try{e();return t}catch(t){return t=>class extended extends t{}}})();({controllerAttribute:"data-controller",actionAttribute:"data-action",targetAttribute:"data-target",targetAttributeForScope:t=>`data-${t}-target`,outletAttributeForScope:(t,e)=>`data-${t}-${e}-outlet`,keyMappings:Object.assign(Object.assign({enter:"Enter",tab:"Tab",esc:"Escape",space:" ",up:"ArrowUp",down:"ArrowDown",left:"ArrowLeft",right:"ArrowRight",home:"Home",end:"End",page_up:"PageUp",page_down:"PageDown"},H("abcdefghijklmnopqrstuvwxyz".split("").map((t=>[t,t])))),H("0123456789".split("").map((t=>[t,t]))))});function H(t){return t.reduce(((t,[e,n])=>Object.assign(Object.assign({},t),{[e]:n})),{})}function I(t){const e=O(t,"classes");return e.reduce(((t,e)=>Object.assign(t,W(e))),{})}function W(t){return{[`${t}Class`]:{get(){const{classes:e}=this;if(e.has(t))return e.get(t);{const n=e.getAttributeName(t);throw new Error(`Missing attribute "${n}"`)}}},[`${t}Classes`]:{get(){return this.classes.getAll(t)}},[`has${U(t)}Class`]:{get(){return this.classes.has(t)}}}}function K(t){const e=O(t,"outlets");return e.reduce(((t,e)=>Object.assign(t,X(e))),{})}function z(t,e,n){return t.application.getControllerForElementAndIdentifier(e,n)}function J(t,e,n){let r=z(t,e,n);if(r)return r;t.application.router.proposeToConnectScopeForElementAndIdentifier(e,n);r=z(t,e,n);return r||void 0}function X(t){const e=j(t);return{[`${e}Outlet`]:{get(){const e=this.outlets.find(t);const n=this.outlets.getSelectorForOutletName(t);if(e){const n=J(this,e,t);if(n)return n;throw new Error(`The provided outlet element is missing an outlet controller "${t}" instance for host controller "${this.identifier}"`)}throw new Error(`Missing outlet element "${t}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${n}".`)}},[`${e}Outlets`]:{get(){const e=this.outlets.findAll(t);return e.length>0?e.map((e=>{const n=J(this,e,t);if(n)return n;console.warn(`The provided outlet element is missing an outlet controller "${t}" instance for host controller "${this.identifier}"`,e)})).filter((t=>t)):[]}},[`${e}OutletElement`]:{get(){const e=this.outlets.find(t);const n=this.outlets.getSelectorForOutletName(t);if(e)return e;throw new Error(`Missing outlet element "${t}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${n}".`)}},[`${e}OutletElements`]:{get(){return this.outlets.findAll(t)}},[`has${U(e)}Outlet`]:{get(){return this.outlets.has(t)}}}}function V(t){const e=O(t,"targets");return e.reduce(((t,e)=>Object.assign(t,Q(e))),{})}function Q(t){return{[`${t}Target`]:{get(){const e=this.targets.find(t);if(e)return e;throw new Error(`Missing target element "${t}" for "${this.identifier}" controller`)}},[`${t}Targets`]:{get(){return this.targets.findAll(t)}},[`has${U(t)}Target`]:{get(){return this.targets.has(t)}}}}function Y(t){const e=F(t,"values");const n={valueDescriptorMap:{get(){return e.reduce(((t,e)=>{const n=G(e,this.identifier);const r=this.data.getAttributeNameForKey(n.key);return Object.assign(t,{[r]:n})}),{})}}};return e.reduce(((t,e)=>Object.assign(t,Z(e))),n)}function Z(t,e){const n=G(t,e);const{key:r,name:i,reader:s,writer:o}=n;return{[i]:{get(){const t=this.data.get(r);return t!==null?s(t):n.defaultValue},set(t){t===void 0?this.data.delete(r):this.data.set(r,o(t))}},[`has${U(i)}`]:{get(){return this.data.has(r)||n.hasCustomDefaultValue}}}}function G([t,e],n){return st({controller:n,token:t,typeDefinition:e})}function tt(t){switch(t){case Array:return"array";case Boolean:return"boolean";case Number:return"number";case Object:return"object";case String:return"string"}}function et(t){switch(typeof t){case"boolean":return"boolean";case"number":return"number";case"string":return"string"}return Array.isArray(t)?"array":Object.prototype.toString.call(t)==="[object Object]"?"object":void 0}function nt(t){const{controller:e,token:n,typeObject:r}=t;const i=_(r.type);const s=_(r.default);const o=i&&s;const a=i&&!s;const c=!i&&s;const l=tt(r.type);const u=et(t.typeObject.default);if(a)return l;if(c)return u;if(l!==u){const t=e?`${e}.${n}`:n;throw new Error(`The specified default value for the Stimulus Value "${t}" must match the defined type "${l}". The provided default value of "${r.default}" is of type "${u}".`)}return o?l:void 0}function rt(t){const{controller:e,token:n,typeDefinition:r}=t;const i={controller:e,token:n,typeObject:r};const s=nt(i);const o=et(r);const a=tt(r);const c=s||o||a;if(c)return c;const l=e?`${e}.${r}`:n;throw new Error(`Unknown value type "${l}" for "${n}" value`)}function it(t){const e=tt(t);if(e)return ot[e];const n=D(t,"default");const r=D(t,"type");const i=t;if(n)return i.default;if(r){const{type:t}=i;const e=tt(t);if(e)return ot[e]}return t}function st(t){const{token:e,typeDefinition:n}=t;const r=`${R(e)}-value`;const i=rt(t);return{type:i,key:r,name:$(r),get defaultValue(){return it(n)},get hasCustomDefaultValue(){return et(n)!==void 0},reader:at[i],writer:ct[i]||ct.default}}const ot={get array(){return[]},boolean:false,number:0,get object(){return{}},string:""};const at={array(t){const e=JSON.parse(t);if(!Array.isArray(e))throw new TypeError(`expected value of type "array" but instead got value "${t}" of type "${et(e)}"`);return e},boolean(t){return!(t=="0"||String(t).toLowerCase()=="false")},number(t){return Number(t.replace(/_/g,""))},object(t){const e=JSON.parse(t);if(e===null||typeof e!="object"||Array.isArray(e))throw new TypeError(`expected value of type "object" but instead got value "${t}" of type "${et(e)}"`);return e},string(t){return t}};const ct={default:ut,array:lt,object:lt};function lt(t){return JSON.stringify(t)}function ut(t){return`${t}`}class Controller{constructor(t){this.context=t}static get shouldLoad(){return true}static afterLoad(t,e){}get application(){return this.context.application}get scope(){return this.context.scope}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get targets(){return this.scope.targets}get outlets(){return this.scope.outlets}get classes(){return this.scope.classes}get data(){return this.scope.data}initialize(){}connect(){}disconnect(){}dispatch(t,{target:e=this.element,detail:n={},prefix:r=this.identifier,bubbles:i=true,cancelable:s=true}={}){const o=r?`${r}:${t}`:t;const a=new CustomEvent(o,{detail:n,bubbles:i,cancelable:s});e.dispatchEvent(a);return a}}Controller.blessings=[I,V,Y,K];Controller.targets=[];Controller.outlets=[];Controller.values={};var dt={exports:{}};(function(t){(function(e){t.exports=e()})((function(t){var e=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];function n(t,e){var n=t[0],r=t[1],i=t[2],s=t[3];n+=(r&i|~r&s)+e[0]-680876936|0;n=(n<<7|n>>>25)+r|0;s+=(n&r|~n&i)+e[1]-389564586|0;s=(s<<12|s>>>20)+n|0;i+=(s&n|~s&r)+e[2]+606105819|0;i=(i<<17|i>>>15)+s|0;r+=(i&s|~i&n)+e[3]-1044525330|0;r=(r<<22|r>>>10)+i|0;n+=(r&i|~r&s)+e[4]-176418897|0;n=(n<<7|n>>>25)+r|0;s+=(n&r|~n&i)+e[5]+1200080426|0;s=(s<<12|s>>>20)+n|0;i+=(s&n|~s&r)+e[6]-1473231341|0;i=(i<<17|i>>>15)+s|0;r+=(i&s|~i&n)+e[7]-45705983|0;r=(r<<22|r>>>10)+i|0;n+=(r&i|~r&s)+e[8]+1770035416|0;n=(n<<7|n>>>25)+r|0;s+=(n&r|~n&i)+e[9]-1958414417|0;s=(s<<12|s>>>20)+n|0;i+=(s&n|~s&r)+e[10]-42063|0;i=(i<<17|i>>>15)+s|0;r+=(i&s|~i&n)+e[11]-1990404162|0;r=(r<<22|r>>>10)+i|0;n+=(r&i|~r&s)+e[12]+1804603682|0;n=(n<<7|n>>>25)+r|0;s+=(n&r|~n&i)+e[13]-40341101|0;s=(s<<12|s>>>20)+n|0;i+=(s&n|~s&r)+e[14]-1502002290|0;i=(i<<17|i>>>15)+s|0;r+=(i&s|~i&n)+e[15]+1236535329|0;r=(r<<22|r>>>10)+i|0;n+=(r&s|i&~s)+e[1]-165796510|0;n=(n<<5|n>>>27)+r|0;s+=(n&i|r&~i)+e[6]-1069501632|0;s=(s<<9|s>>>23)+n|0;i+=(s&r|n&~r)+e[11]+643717713|0;i=(i<<14|i>>>18)+s|0;r+=(i&n|s&~n)+e[0]-373897302|0;r=(r<<20|r>>>12)+i|0;n+=(r&s|i&~s)+e[5]-701558691|0;n=(n<<5|n>>>27)+r|0;s+=(n&i|r&~i)+e[10]+38016083|0;s=(s<<9|s>>>23)+n|0;i+=(s&r|n&~r)+e[15]-660478335|0;i=(i<<14|i>>>18)+s|0;r+=(i&n|s&~n)+e[4]-405537848|0;r=(r<<20|r>>>12)+i|0;n+=(r&s|i&~s)+e[9]+568446438|0;n=(n<<5|n>>>27)+r|0;s+=(n&i|r&~i)+e[14]-1019803690|0;s=(s<<9|s>>>23)+n|0;i+=(s&r|n&~r)+e[3]-187363961|0;i=(i<<14|i>>>18)+s|0;r+=(i&n|s&~n)+e[8]+1163531501|0;r=(r<<20|r>>>12)+i|0;n+=(r&s|i&~s)+e[13]-1444681467|0;n=(n<<5|n>>>27)+r|0;s+=(n&i|r&~i)+e[2]-51403784|0;s=(s<<9|s>>>23)+n|0;i+=(s&r|n&~r)+e[7]+1735328473|0;i=(i<<14|i>>>18)+s|0;r+=(i&n|s&~n)+e[12]-1926607734|0;r=(r<<20|r>>>12)+i|0;n+=(r^i^s)+e[5]-378558|0;n=(n<<4|n>>>28)+r|0;s+=(n^r^i)+e[8]-2022574463|0;s=(s<<11|s>>>21)+n|0;i+=(s^n^r)+e[11]+1839030562|0;i=(i<<16|i>>>16)+s|0;r+=(i^s^n)+e[14]-35309556|0;r=(r<<23|r>>>9)+i|0;n+=(r^i^s)+e[1]-1530992060|0;n=(n<<4|n>>>28)+r|0;s+=(n^r^i)+e[4]+1272893353|0;s=(s<<11|s>>>21)+n|0;i+=(s^n^r)+e[7]-155497632|0;i=(i<<16|i>>>16)+s|0;r+=(i^s^n)+e[10]-1094730640|0;r=(r<<23|r>>>9)+i|0;n+=(r^i^s)+e[13]+681279174|0;n=(n<<4|n>>>28)+r|0;s+=(n^r^i)+e[0]-358537222|0;s=(s<<11|s>>>21)+n|0;i+=(s^n^r)+e[3]-722521979|0;i=(i<<16|i>>>16)+s|0;r+=(i^s^n)+e[6]+76029189|0;r=(r<<23|r>>>9)+i|0;n+=(r^i^s)+e[9]-640364487|0;n=(n<<4|n>>>28)+r|0;s+=(n^r^i)+e[12]-421815835|0;s=(s<<11|s>>>21)+n|0;i+=(s^n^r)+e[15]+530742520|0;i=(i<<16|i>>>16)+s|0;r+=(i^s^n)+e[2]-995338651|0;r=(r<<23|r>>>9)+i|0;n+=(i^(r|~s))+e[0]-198630844|0;n=(n<<6|n>>>26)+r|0;s+=(r^(n|~i))+e[7]+1126891415|0;s=(s<<10|s>>>22)+n|0;i+=(n^(s|~r))+e[14]-1416354905|0;i=(i<<15|i>>>17)+s|0;r+=(s^(i|~n))+e[5]-57434055|0;r=(r<<21|r>>>11)+i|0;n+=(i^(r|~s))+e[12]+1700485571|0;n=(n<<6|n>>>26)+r|0;s+=(r^(n|~i))+e[3]-1894986606|0;s=(s<<10|s>>>22)+n|0;i+=(n^(s|~r))+e[10]-1051523|0;i=(i<<15|i>>>17)+s|0;r+=(s^(i|~n))+e[1]-2054922799|0;r=(r<<21|r>>>11)+i|0;n+=(i^(r|~s))+e[8]+1873313359|0;n=(n<<6|n>>>26)+r|0;s+=(r^(n|~i))+e[15]-30611744|0;s=(s<<10|s>>>22)+n|0;i+=(n^(s|~r))+e[6]-1560198380|0;i=(i<<15|i>>>17)+s|0;r+=(s^(i|~n))+e[13]+1309151649|0;r=(r<<21|r>>>11)+i|0;n+=(i^(r|~s))+e[4]-145523070|0;n=(n<<6|n>>>26)+r|0;s+=(r^(n|~i))+e[11]-1120210379|0;s=(s<<10|s>>>22)+n|0;i+=(n^(s|~r))+e[2]+718787259|0;i=(i<<15|i>>>17)+s|0;r+=(s^(i|~n))+e[9]-343485551|0;r=(r<<21|r>>>11)+i|0;t[0]=n+t[0]|0;t[1]=r+t[1]|0;t[2]=i+t[2]|0;t[3]=s+t[3]|0}function r(t){var e,n=[];for(e=0;e<64;e+=4)n[e>>2]=t.charCodeAt(e)+(t.charCodeAt(e+1)<<8)+(t.charCodeAt(e+2)<<16)+(t.charCodeAt(e+3)<<24);return n}function i(t){var e,n=[];for(e=0;e<64;e+=4)n[e>>2]=t[e]+(t[e+1]<<8)+(t[e+2]<<16)+(t[e+3]<<24);return n}function s(t){var e,i,s,o,a,c,l=t.length,u=[1732584193,-271733879,-1732584194,271733878];for(e=64;e<=l;e+=64)n(u,r(t.substring(e-64,e)));t=t.substring(e-64);i=t.length;s=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(e=0;e>2]|=t.charCodeAt(e)<<(e%4<<3);s[e>>2]|=128<<(e%4<<3);if(e>55){n(u,s);for(e=0;e<16;e+=1)s[e]=0}o=l*8;o=o.toString(16).match(/(.*?)(.{0,8})$/);a=parseInt(o[2],16);c=parseInt(o[1],16)||0;s[14]=a;s[15]=c;n(u,s);return u}function o(t){var e,r,s,o,a,c,l=t.length,u=[1732584193,-271733879,-1732584194,271733878];for(e=64;e<=l;e+=64)n(u,i(t.subarray(e-64,e)));t=e-64>2]|=t[e]<<(e%4<<3);s[e>>2]|=128<<(e%4<<3);if(e>55){n(u,s);for(e=0;e<16;e+=1)s[e]=0}o=l*8;o=o.toString(16).match(/(.*?)(.{0,8})$/);a=parseInt(o[2],16);c=parseInt(o[1],16)||0;s[14]=a;s[15]=c;n(u,s);return u}function a(t){var n,r="";for(n=0;n<4;n+=1)r+=e[t>>n*8+4&15]+e[t>>n*8&15];return r}function c(t){var e;for(e=0;eu)return new ArrayBuffer(0);i=u-l;s=new ArrayBuffer(i);o=new Uint8Array(s);a=new Uint8Array(this,l,i);o.set(a);return s}}();function l(t){/[\u0080-\uFFFF]/.test(t)&&(t=unescape(encodeURIComponent(t)));return t}function u(t,e){var n,r=t.length,i=new ArrayBuffer(r),s=new Uint8Array(i);for(n=0;n>2]|=r.charCodeAt(e)<<(e%4<<3);this._finish(s,i);n=c(this._hash);t&&(n=f(n));this.reset();return n};p.prototype.reset=function(){this._buff="";this._length=0;this._hash=[1732584193,-271733879,-1732584194,271733878];return this};p.prototype.getState=function(){return{buff:this._buff,length:this._length,hash:this._hash.slice()}};p.prototype.setState=function(t){this._buff=t.buff;this._length=t.length;this._hash=t.hash;return this};p.prototype.destroy=function(){delete this._hash;delete this._buff;delete this._length};p.prototype._finish=function(t,e){var r,i,s,o=e;t[o>>2]|=128<<(o%4<<3);if(o>55){n(this._hash,t);for(o=0;o<16;o+=1)t[o]=0}r=this._length*8;r=r.toString(16).match(/(.*?)(.{0,8})$/);i=parseInt(r[2],16);s=parseInt(r[1],16)||0;t[14]=i;t[15]=s;n(this._hash,t)};p.hash=function(t,e){return p.hashBinary(l(t),e)};p.hashBinary=function(t,e){var n=s(t),r=c(n);return e?f(r):r};p.ArrayBuffer=function(){this.reset()};p.ArrayBuffer.prototype.append=function(t){var e,r=h(this._buff.buffer,t),s=r.length;this._length+=t.byteLength;for(e=64;e<=s;e+=64)n(this._hash,i(r.subarray(e-64,e)));this._buff=e-64>2]|=r[e]<<(e%4<<3);this._finish(s,i);n=c(this._hash);t&&(n=f(n));this.reset();return n};p.ArrayBuffer.prototype.reset=function(){this._buff=new Uint8Array(0);this._length=0;this._hash=[1732584193,-271733879,-1732584194,271733878];return this};p.ArrayBuffer.prototype.getState=function(){var t=p.prototype.getState.call(this);t.buff=d(t.buff);return t};p.ArrayBuffer.prototype.setState=function(t){t.buff=u(t.buff,true);return p.prototype.setState.call(this,t)};p.ArrayBuffer.prototype.destroy=p.prototype.destroy;p.ArrayBuffer.prototype._finish=p.prototype._finish;p.ArrayBuffer.hash=function(t,e){var n=o(new Uint8Array(t)),r=c(n);return e?f(r):r};return p}))})(dt);var ht=dt.exports;const ft=File.prototype.slice||File.prototype.mozSlice||File.prototype.webkitSlice;class FileChecksum{static create(t,e){const n=new FileChecksum(t);n.create(e)}constructor(t){this.file=t;this.chunkSize=2097152;this.chunkCount=Math.ceil(this.file.size/this.chunkSize);this.chunkIndex=0}create(t){this.callback=t;this.md5Buffer=new ht.ArrayBuffer;this.fileReader=new FileReader;this.fileReader.addEventListener("load",(t=>this.fileReaderDidLoad(t)));this.fileReader.addEventListener("error",(t=>this.fileReaderDidError(t)));this.readNextChunk()}fileReaderDidLoad(t){this.md5Buffer.append(t.target.result);if(!this.readNextChunk()){const t=this.md5Buffer.end(true);const e=btoa(t);this.callback(null,e)}}fileReaderDidError(t){this.callback(`Error reading ${this.file.name}`)}readNextChunk(){if(this.chunkIndex{this.xhr.setRequestHeader(t,r[t])}));const i=pt("csrf-token");i!=void 0&&this.xhr.setRequestHeader("X-CSRF-Token",i);this.xhr.addEventListener("load",(t=>this.requestDidLoad(t)));this.xhr.addEventListener("error",(t=>this.requestDidError(t)))}get status(){return this.xhr.status}get response(){const{responseType:t,response:e}=this.xhr;return t=="json"?e:JSON.parse(e)}create(t){this.callback=t;this.xhr.send(JSON.stringify({blob:this.attributes}))}requestDidLoad(t){if(this.status>=200&&this.status<300){const{response:t}=this;const{direct_upload:e}=t;delete t.direct_upload;this.attributes=t;this.directUploadData=e;this.callback(null,this.toJSON())}else this.requestDidError(t)}requestDidError(t){this.callback(`Error creating Blob for "${this.file.name}". Status: ${this.status}`)}toJSON(){const t={};for(const e in this.attributes)t[e]=this.attributes[e];return t}}class BlobUpload{constructor(t){this.blob=t;this.file=t.file;const{url:e,headers:n}=t.directUploadData;this.xhr=new XMLHttpRequest;this.xhr.open("PUT",e,true);this.xhr.responseType="text";for(const t in n)this.xhr.setRequestHeader(t,n[t]);this.xhr.addEventListener("load",(t=>this.requestDidLoad(t)));this.xhr.addEventListener("error",(t=>this.requestDidError(t)))}create(t){this.callback=t;this.xhr.send(this.file.slice())}requestDidLoad(t){const{status:e,response:n}=this.xhr;e>=200&&e<300?this.callback(null,n):this.requestDidError(t)}requestDidError(t){this.callback(`Error storing "${this.file.name}". Status: ${this.xhr.status}`)}}let yt=0;class DirectUpload{constructor(t,e,n,r={}){this.id=++yt;this.file=t;this.url=e;this.delegate=n;this.customHeaders=r}create(t){FileChecksum.create(this.file,((e,n)=>{if(e){t(e);return}const r=new BlobRecord(this.file,n,this.url,this.customHeaders);Et(this.delegate,"directUploadWillCreateBlobWithXHR",r.xhr);r.create((e=>{if(e)t(e);else{const e=new BlobUpload(r);Et(this.delegate,"directUploadWillStoreFileWithXHR",e.xhr);e.create((e=>{e?t(e):t(null,r.toJSON())}))}}))}))}}function Et(t,e,...n){if(t&&typeof t[e]=="function")return t[e](...n)}class DirectUploadController{constructor(t,e){this.input=t;this.file=e;this.directUpload=new DirectUpload(this.file,this.url,this);this.dispatch("initialize")}start(t){const e=document.createElement("input");e.type="hidden";e.name=this.input.name;this.input.insertAdjacentElement("beforebegin",e);this.dispatch("start");this.directUpload.create(((n,r)=>{if(n){e.parentNode.removeChild(e);this.dispatchError(n)}else e.value=r.signed_id;this.dispatch("end");t(n)}))}uploadRequestDidProgress(t){const e=t.loaded/t.total*100;e&&this.dispatch("progress",{progress:e})}get url(){return this.input.getAttribute("data-direct-upload-url")}dispatch(t,e={}){e.file=this.file;e.id=this.directUpload.id;return wt(this.input,`direct-upload:${t}`,{detail:e})}dispatchError(t){const e=this.dispatch("error",{error:t});e.defaultPrevented||alert(t)}directUploadWillCreateBlobWithXHR(t){this.dispatch("before-blob-request",{xhr:t})}directUploadWillStoreFileWithXHR(t){this.dispatch("before-storage-request",{xhr:t});t.upload.addEventListener("progress",(t=>this.uploadRequestDidProgress(t)))}}const vt="input[type=file][data-direct-upload-url]:not([disabled])";class DirectUploadsController{constructor(t){this.form=t;this.inputs=mt(t,vt).filter((t=>t.files.length))}start(t){const e=this.createDirectUploadControllers();const n=()=>{const r=e.shift();if(r)r.start((e=>{if(e){t(e);this.dispatch("end")}else n()}));else{t();this.dispatch("end")}};this.dispatch("start");n()}createDirectUploadControllers(){const t=[];this.inputs.forEach((e=>{bt(e.files).forEach((n=>{const r=new DirectUploadController(e,n);t.push(r)}))}));return t}dispatch(t,e={}){return wt(this.form,`direct-uploads:${t}`,{detail:e})}}const xt="data-direct-uploads-processing";const kt=new WeakMap;let Tt=false;function St(){if(!Tt){Tt=true;document.addEventListener("click",Lt,true);document.addEventListener("submit",At,true);document.addEventListener("ajax:before",Ct)}}function Lt(t){const e=t.target.closest("button, input");e&&e.type==="submit"&&e.form&&kt.set(e.form,e)}function At(t){Mt(t)}function Ct(t){t.target.tagName=="FORM"&&Mt(t)}function Mt(t){const e=t.target;if(e.hasAttribute(xt)){t.preventDefault();return}const n=new DirectUploadsController(e);const{inputs:r}=n;if(r.length){t.preventDefault();e.setAttribute(xt,"");r.forEach($t);n.start((t=>{e.removeAttribute(xt);t?r.forEach(jt):Bt(e)}))}}function Bt(t){let e=kt.get(t)||gt(t,"input[type=submit], button[type=submit]");if(e){const{disabled:t}=e;e.disabled=false;e.focus();e.click();e.disabled=t}else{e=document.createElement("input");e.type="submit";e.style.display="none";t.appendChild(e);e.click();t.removeChild(e)}kt.delete(t)}function $t(t){t.disabled=true}function jt(t){t.disabled=false}function Ut(){window.ActiveStorage&&St()}setTimeout(Ut,1);class FetchResponse{constructor(t){this.response=t}get statusCode(){return this.response.status}get redirected(){return this.response.redirected}get ok(){return this.response.ok}get unauthenticated(){return this.statusCode===401}get unprocessableEntity(){return this.statusCode===422}get authenticationURL(){return this.response.headers.get("WWW-Authenticate")}get contentType(){const t=this.response.headers.get("Content-Type")||"";return t.replace(/;.*$/,"")}get headers(){return this.response.headers}get html(){return this.contentType.match(/^(application|text)\/(html|xhtml\+xml)$/)?this.text:Promise.reject(new Error(`Expected an HTML response but got "${this.contentType}" instead`))}get json(){return this.contentType.match(/^application\/.*json$/)?this.responseJson||(this.responseJson=this.response.json()):Promise.reject(new Error(`Expected a JSON response but got "${this.contentType}" instead`))}get text(){return this.responseText||(this.responseText=this.response.text())}get isTurboStream(){return this.contentType.match(/^text\/vnd\.turbo-stream\.html/)}get isScript(){return this.contentType.match(/\b(?:java|ecma)script\b/)}async renderTurboStream(){if(!this.isTurboStream)return Promise.reject(new Error(`Expected a Turbo Stream response but got "${this.contentType}" instead`));window.Turbo?await window.Turbo.renderStreamMessage(await this.text):console.warn("You must set `window.Turbo = Turbo` to automatically process Turbo Stream events with request.js")}async activeScript(){if(!this.isScript)return Promise.reject(new Error(`Expected a Script response but got "${this.contentType}" instead`));{const t=document.createElement("script");const e=document.querySelector("meta[name=csp-nonce]");const n=e&&e.content;n&&t.setAttribute("nonce",n);t.innerHTML=await this.text;document.body.appendChild(t)}}}class RequestInterceptor{static register(t){this.interceptor=t}static get(){return this.interceptor}static reset(){this.interceptor=void 0}}function Rt(t){const e=document.cookie?document.cookie.split("; "):[];const n=`${encodeURIComponent(t)}=`;const r=e.find((t=>t.startsWith(n)));if(r){const t=r.split("=").slice(1).join("=");if(t)return decodeURIComponent(t)}}function _t(t){const e={};for(const n in t){const r=t[n];r!==void 0&&(e[n]=r)}return e}function Dt(t){const e=document.head.querySelector(`meta[name="${t}"]`);return e&&e.content}function Ot(t){return[...t].reduce(((t,[e,n])=>t.concat(typeof n==="string"?[[e,n]]:[])),[])}function Ft(t,e){for(const[n,r]of e)if(!(r instanceof window.File))if(t.has(n)&&!n.includes("[]")){t.delete(n);t.set(n,r)}else t.append(n,r)}class FetchRequest{constructor(t,e,n={}){this.method=t;this.options=n;this.originalUrl=e.toString()}async perform(){try{const t=RequestInterceptor.get();t&&await t(this)}catch(t){console.error(t)}const t=this.responseKind==="turbo-stream"&&window.Turbo?window.Turbo.fetch:window.fetch;const e=new FetchResponse(await t(this.url,this.fetchOptions));if(e.unauthenticated&&e.authenticationURL)return Promise.reject(window.location.href=e.authenticationURL);e.isScript&&await e.activeScript();const n=e.ok||e.unprocessableEntity;n&&e.isTurboStream&&await e.renderTurboStream();return e}addHeader(t,e){const n=this.additionalHeaders;n[t]=e;this.options.headers=n}sameHostname(){if(!this.originalUrl.startsWith("http:"))return true;try{return new URL(this.originalUrl).hostname===window.location.hostname}catch(t){return true}}get fetchOptions(){return{method:this.method.toUpperCase(),headers:this.headers,body:this.formattedBody,signal:this.signal,credentials:this.credentials,redirect:this.redirect}}get headers(){const t={"X-Requested-With":"XMLHttpRequest","Content-Type":this.contentType,Accept:this.accept};this.sameHostname()&&(t["X-CSRF-Token"]=this.csrfToken);return _t(Object.assign(t,this.additionalHeaders))}get csrfToken(){return Rt(Dt("csrf-param"))||Dt("csrf-token")}get contentType(){return this.options.contentType?this.options.contentType:this.body==null||this.body instanceof window.FormData?void 0:this.body instanceof window.File?this.body.type:"application/json"}get accept(){switch(this.responseKind){case"html":return"text/html, application/xhtml+xml";case"turbo-stream":return"text/vnd.turbo-stream.html, text/html, application/xhtml+xml";case"json":return"application/json, application/vnd.api+json";case"script":return"text/javascript, application/javascript";default:return"*/*"}}get body(){return this.options.body}get query(){const t=(this.originalUrl.split("?")[1]||"").split("#")[0];const e=new URLSearchParams(t);let n=this.options.query;n=n instanceof window.FormData?Ot(n):n instanceof window.URLSearchParams?n.entries():Object.entries(n||{});Ft(e,n);const r=e.toString();return r.length>0?`?${r}`:""}get url(){return this.originalUrl.split("?")[0].split("#")[0]+this.query}get responseKind(){return this.options.responseKind||"html"}get signal(){return this.options.signal}get redirect(){return this.options.redirect||"follow"}get credentials(){return this.options.credentials||"same-origin"}get additionalHeaders(){return this.options.headers||{}}get formattedBody(){const t=Object.prototype.toString.call(this.body)==="[object String]";const e=this.headers["Content-Type"]==="application/json";return e&&!t?JSON.stringify(this.body):this.body}}async function Pt(t,e){const n=new FetchRequest("post",t,e);return n.perform()}function qt(t,e){var n,r,i;const s=t.value.slice(0,(n=t.selectionStart)!==null&&n!==void 0?n:void 0);const o=t.value.slice((r=t.selectionEnd)!==null&&r!==void 0?r:void 0);let a=true;t.contentEditable="true";try{a=document.execCommand("insertText",false,e)}catch(t){a=false}t.contentEditable="false";a&&!t.value.slice(0,(i=t.selectionStart)!==null&&i!==void 0?i:void 0).endsWith(e)&&(a=false);if(!a){try{document.execCommand("ms-beginUndoUnit")}catch(t){}t.value=s+e+o;try{document.execCommand("ms-endUndoUnit")}catch(t){}t.dispatchEvent(new CustomEvent("change",{bubbles:true,cancelable:true}))}}const Nt=new WeakMap;function Ht(t){const{currentTarget:e}=t;const n=t.code==="KeyV"&&(t.ctrlKey||t.metaKey)&&t.shiftKey;(n||n&&t.altKey)&&Nt.set(e,true)}function It(t){const{currentTarget:e}=t;Nt.delete(e)}function Wt(t){var e;const n=(e=Nt.get(t))!==null&&e!==void 0&&e;return n}function Kt(t,e,n){t.addEventListener("keydown",Ht);for(const r of e)r(t,n);t.addEventListener("paste",It)}function zt(t){t.removeEventListener("keydown",Ht);t.removeEventListener("paste",It)}function Jt(t){t.addEventListener("paste",Vt)}function Xt(t){t.removeEventListener("paste",Vt)}function Vt(t){const e=t.clipboardData;const{currentTarget:n}=t;if(Wt(n))return;if(!e||!te(e))return;const r=t.currentTarget;if(!(r instanceof HTMLTextAreaElement))return;if(Yt(r))return;let i=e.getData("text/plain");const s=e.getData("text/html");const o=s.replace(/\u00A0/g," ").replace(/\uC2A0/g," ");if(!s)return;i=i.trim();if(!i)return;const a=new DOMParser;const c=a.parseFromString(o,"text/html");const l=c.createTreeWalker(c.body,NodeFilter.SHOW_ALL,(t=>t.parentNode&&Gt(t.parentNode)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT));const u=Qt(i,l);if(u!==i){t.stopPropagation();t.preventDefault();qt(r,u)}}function Qt(t,e){let n=e.firstChild();let r=t;let i=0;let s=0;const o=1e4;while(n&&s=0){const e=ee(n,t);r=r.slice(0,o)+e+r.slice(o+t.length);i=o+e.length}n=e.nextNode()}return s===o?t:r}function Yt(t){const e=t.selectionStart||0;if(e===0)return false;const n=t.value.substring(e-1,e);return n==="@"}function Zt(t){return!t||(t===null||t===void 0?void 0:t.trim().length)===0}function Gt(t){var e;return((e=t.tagName)===null||e===void 0?void 0:e.toLowerCase())==="a"&&t.hasAttribute("href")}function te(t){return t.types.includes("text/html")}function ee(t,e){const n=t.href||"";let r="";r=ie(t)||se(t)?e:ne(t)||re(n,e)?n:`[${e}](${n})`;return r}function ne(t){return t.className.indexOf("commit-link")>=0||!!t.getAttribute("data-hovercard-type")&&t.getAttribute("data-hovercard-type")!=="user"}function re(t,e){t=t.slice(-1)==="/"?t.slice(0,-1):t;e=e.slice(-1)==="/"?e.slice(0,-1):e;return t.toLowerCase()===e.toLowerCase()}function ie(t){var e;return((e=t.textContent)===null||e===void 0?void 0:e.slice(0,1))==="@"&&t.getAttribute("data-hovercard-type")==="user"}function se(t){var e;return((e=t.textContent)===null||e===void 0?void 0:e.slice(0,1))==="@"&&t.getAttribute("data-hovercard-type")==="team"}function oe(t){t.addEventListener("dragover",le);t.addEventListener("drop",ce);t.addEventListener("paste",ue)}function ae(t){t.removeEventListener("dragover",le);t.removeEventListener("drop",ce);t.removeEventListener("paste",ue)}function ce(t){const e=t.dataTransfer;if(!e)return;if(he(e))return;if(!fe(e))return;const n=pe(e);if(!n.some(ge))return;t.stopPropagation();t.preventDefault();const r=t.currentTarget;r instanceof HTMLTextAreaElement&&qt(r,n.map(de).join(""))}function le(t){const e=t.dataTransfer;e&&(e.dropEffect="link")}function ue(t){const{currentTarget:e}=t;if(Wt(e))return;const n=t.clipboardData;if(!n||!fe(n))return;const r=pe(n);if(!r.some(ge))return;t.stopPropagation();t.preventDefault();const i=t.currentTarget;i instanceof HTMLTextAreaElement&&qt(i,r.map(de).join(""))}function de(t){return ge(t)?`\n![](${t})\n`:t}function he(t){return Array.from(t.types).indexOf("Files")>=0}function fe(t){return Array.from(t.types).indexOf("text/uri-list")>=0}function pe(t){return(t.getData("text/uri-list")||"").split("\r\n")}const me=/\.(gif|png|jpe?g)$/i;function ge(t){return me.test(t)}const we=new WeakMap;function be(t,e){var n;we.set(t,((n=e===null||e===void 0?void 0:e.defaultPlainTextPaste)===null||n===void 0?void 0:n.urlLinks)===true);t.addEventListener("paste",Ee)}function ye(t){t.removeEventListener("paste",Ee)}function Ee(t){var e;const{currentTarget:n}=t;const r=n;const i=(e=we.get(r))!==null&&e!==void 0&&e;const s=Wt(r);if(!i&&s||i&&!s)return;const o=t.clipboardData;if(!o||!ve(o))return;const a=t.currentTarget;if(!(a instanceof HTMLTextAreaElement))return;const c=o.getData("text/plain");if(!c)return;if(!Te(c))return;if(xe(a))return;const l=a.value.substring(a.selectionStart,a.selectionEnd);if(l.length&&!Te(l.trim())){t.stopPropagation();t.preventDefault();qt(a,ke(l,c.trim()))}}function ve(t){return Array.from(t.types).includes("text/plain")}function xe(t){const e=t.selectionStart||0;if(e>1){const n=t.value.substring(e-2,e);return n==="]("}return false}function ke(t,e){return`[${t}](${e})`}function Te(t){try{const e=new URL(t);return Se(e.href).trim()===Se(t).trim()}catch(t){return false}}function Se(t){return t.endsWith("/")?t.slice(0,t.length-1):t}function Le(t){t.addEventListener("dragover",Me);t.addEventListener("drop",Ce);t.addEventListener("paste",Be)}function Ae(t){t.removeEventListener("dragover",Me);t.removeEventListener("drop",Ce);t.removeEventListener("paste",Be)}function Ce(t){const e=t.dataTransfer;if(!e)return;if($e(e))return;const n=_e(e);if(!n)return;t.stopPropagation();t.preventDefault();const r=t.currentTarget;r instanceof HTMLTextAreaElement&&qt(r,n)}function Me(t){const e=t.dataTransfer;e&&(e.dropEffect="copy")}function Be(t){const{currentTarget:e}=t;if(Wt(e))return;if(!t.clipboardData)return;const n=_e(t.clipboardData);if(!n)return;t.stopPropagation();t.preventDefault();const r=t.currentTarget;r instanceof HTMLTextAreaElement&&qt(r,n)}function $e(t){return Array.from(t.types).indexOf("Files")>=0}function je(t){const e=" ";const n=(t.textContent||"").trim().replace(/\|/g,"\\|").replace(/\n/g," ");return n||e}function Ue(t){return Array.from(t.querySelectorAll("td, th")).map(je)}function Re(t){const e=Array.from(t.querySelectorAll("tr"));const n=e.shift();if(!n)return"";const r=Ue(n);const i=r.map((()=>"--"));const s=`${r.join(" | ")}\n${i.join(" | ")}\n`;const o=e.map((t=>Array.from(t.querySelectorAll("td")).map(je).join(" | "))).join("\n");return`\n${s}${o}\n\n`}function _e(t){if(Array.from(t.types).indexOf("text/html")===-1)return;const e=t.getData("text/html");if(!/");if(!n||!r)return;const i=e.substring(r+8);const s=new DOMParser;const o=s.parseFromString(e,"text/html");let a=o.querySelector("table");a=!a||a.closest("[data-paste-markdown-skip]")?null:a;if(!a)return;const c=Re(a);return c?[n,c,i].join("").replace(//,""):void 0}function De(t){t.addEventListener("paste",Fe)}function Oe(t){t.removeEventListener("paste",Fe)}function Fe(t){const{currentTarget:e}=t;if(Wt(e))return;const n=t.clipboardData;if(!n||!Pe(n))return;const r=t.currentTarget;if(!(r instanceof HTMLTextAreaElement))return;const i=n.getData("text/x-gfm");if(i){t.stopPropagation();t.preventDefault();qt(r,i)}}function Pe(t){return Array.from(t.types).indexOf("text/x-gfm")>=0}function qe(t,e){Kt(t,[Le,oe,be,De,Jt],e);return{unsubscribe:()=>{zt(t);Ae(t);Xt(t);ae(t);ye(t);Oe(t)}}}class Leaf{constructor(t){this.children=[];this.parent=t}delete(t){const e=this.children.indexOf(t);if(e===-1)return false;this.children=this.children.slice(0,e).concat(this.children.slice(e+1));this.children.length===0&&this.parent.delete(this);return true}add(t){this.children.push(t);return this}}class RadixTrie{constructor(t){this.parent=null;this.children={};this.parent=t||null}get(t){return this.children[t]}insert(t){let e=this;for(let n=0;n","¿":"?"};const He={"`":"~",1:"!",2:"@",3:"#",4:"$",5:"%",6:"^",7:"&",8:"*",9:"(",0:")","-":"_","=":"+","[":"{","]":"}","\\":"|",";":":","'":'"',",":"<",".":">","/":"?",q:"Q",w:"W",e:"E",r:"R",t:"T",y:"Y",u:"U",i:"I",o:"O",p:"P",a:"A",s:"S",d:"D",f:"F",g:"G",h:"H",j:"J",k:"K",l:"L",z:"Z",x:"X",c:"C",v:"V",b:"B",n:"N",m:"M"};const Ie={" ":"Space","+":"Plus"};function We(t,e=navigator.platform){var n,r,i;const{ctrlKey:s,altKey:o,metaKey:a,shiftKey:c,key:l}=t;const u=[];const d=[s,o,a,c];for(const[t,e]of d.entries())e&&u.push(Ke[t]);if(!Ke.includes(l)){const t=u.includes("Alt")&&Je.test(e)&&(n=Ne[l])!==null&&n!==void 0?n:l;const s=u.includes("Shift")&&Je.test(e)&&(r=He[t])!==null&&r!==void 0?r:t;const o=(i=Ie[s])!==null&&i!==void 0?i:s;u.push(o)}return u.join("+")}const Ke=["Control","Alt","Meta","Shift"];function ze(t,e){let n;n=Xe(t);n=Ve(n);return n}const Je=/Mac|iPod|iPhone|iPad/i;function Xe(t,e){var n;const r=typeof window==="undefined"?void 0:window;const i=(n=r===null||r===void 0?void 0:r.navigator.platform)!==null&&n!==void 0?n:"";const s=Je.test(i)?"Meta":"Control";return t.replace("Mod",s)}function Ve(t){const e=t.split("+").pop();const n=[];for(const e of["Control","Alt","Meta","Shift"])t.includes(e)&&n.push(e);e&&n.push(e);return n.join("+")}const Qe=" ";class SequenceTracker{constructor({onReset:t}={}){this._path=[];this.timer=null;this.onReset=t}get path(){return this._path}get sequence(){return this._path.join(Qe)}registerKeypress(t){this._path=[...this._path,We(t)];this.startTimer()}reset(){var t;this.killTimer();this._path=[];(t=this.onReset)===null||t===void 0?void 0:t.call(this)}killTimer(){this.timer!=null&&window.clearTimeout(this.timer);this.timer=null}startTimer(){this.killTimer();this.timer=window.setTimeout((()=>this.reset()),SequenceTracker.CHORD_TIMEOUT)}}SequenceTracker.CHORD_TIMEOUT=1500;function Ye(t){if(!(t instanceof HTMLElement))return false;const e=t.nodeName.toLowerCase();const n=(t.getAttribute("type")||"").toLowerCase();return e==="select"||e==="textarea"||e==="input"&&n!=="submit"&&n!=="reset"&&n!=="checkbox"&&n!=="radio"&&n!=="file"||t.isContentEditable}function Ze(t,e){const n=new CustomEvent("hotkey-fire",{cancelable:true,detail:{path:e}});const r=!t.dispatchEvent(n);r||(Ye(t)?t.focus():t.click())}function Ge(t){const e=[];let n=[""];let r=false;for(let i=0;it.map((t=>ze(t))).filter((t=>t!=="")))).filter((t=>t.length>0))}const tn=new RadixTrie;const en=new WeakMap;let nn=tn;const rn=new SequenceTracker({onReset(){nn=tn}});function sn(t){if(t.defaultPrevented)return;if(!(t.target instanceof Node))return;if(Ye(t.target)){const e=t.target;if(!e.id)return;if(!e.ownerDocument.querySelector(`[data-hotkey-scope="${e.id}"]`))return}const e=nn.get(We(t));if(e){rn.registerKeypress(t);nn=e;if(e instanceof Leaf){const n=t.target;let r=false;let i;const s=Ye(n);for(let t=e.children.length-1;t>=0;t-=1){i=e.children[t];const o=i.getAttribute("data-hotkey-scope");if(!s&&!o||s&&n.id===o){r=true;break}}if(i&&r){Ze(i,rn.path);t.preventDefault()}rn.reset()}}else rn.reset()}function on(t,e){Object.keys(tn.children).length===0&&document.addEventListener("keydown",sn);const n=Ge(t.getAttribute("data-hotkey")||"");const r=n.map((e=>tn.insert(e).add(t)));en.set(t,r)}function an(t){const e=en.get(t);if(e&&e.length)for(const n of e)n&&n.delete(t);Object.keys(tn.children).length===0&&document.removeEventListener("keydown",sn)}class marksmith_controller extends Controller{static values={attachUrl:String,previewUrl:String,extraPreviewParams:{type:Object,default:{}},fieldId:String,galleryEnabled:{type:Boolean,default:false},galleryOpenPath:String,fileUploadsEnabled:{type:Boolean,default:true}};static targets=["fieldContainer","fieldElement","previewPane","writeTabButton","previewTabButton","toolbar"];activeTabClass="active";get#t(){return!this.fileUploadsEnabledValue}connect(){qe(this.fieldElementTarget);for(const t of document.querySelectorAll("[data-hotkey]"))on(t)}disconnect(){for(const t of document.querySelectorAll("[data-hotkey]"))an(t)}switchToWrite(t){t.preventDefault();this.writeTabButtonTarget.classList.add(this.activeTabClass);this.previewTabButtonTarget.classList.remove(this.activeTabClass);this.fieldContainerTarget.classList.remove("ms:hidden");this.previewPaneTarget.classList.add("ms:hidden");this.toolbarTarget.classList.remove("ms:opacity-0","ms:pointer-events-none")}switchToPreview(t){t.preventDefault();this.element.focus();this.element.blur();document.activeElement.blur();Pt(this.previewUrlValue,{body:{body:this.fieldElementTarget.value,element_id:this.previewPaneTarget.id,extra_params:this.extraPreviewParamsValue},responseKind:"turbo-stream"});this.previewPaneTarget.style.minHeight=`${this.fieldElementTarget.offsetHeight}px`;this.writeTabButtonTarget.classList.remove(this.activeTabClass);this.previewTabButtonTarget.classList.add(this.activeTabClass);this.fieldContainerTarget.classList.add("ms:hidden");this.previewPaneTarget.classList.remove("ms:hidden");this.toolbarTarget.classList.add("ms:opacity-0","ms:pointer-events-none")}dropUpload(t){if(!this.#t){t.preventDefault();this.#e(t.dataTransfer.files)}}pasteUpload(t){if(!this.#t&&t.clipboardData.files.length){t.preventDefault();this.#e(t.clipboardData.files)}}buttonUpload(t){t.preventDefault();const e=document.createElement("input");e.type="file";e.multiple=true;e.accept="image/*,.pdf,.doc,.docx,.txt";e.addEventListener("change",(t=>{this.#e(t.target.files)}));e.click()}insertAttachments(t,e){const n=t.map((t=>{const{blob:e,path:n,url:r}=t;const i=this.#n(e.filename,n,e.content_type);this.#r(i)}));this.editor?.chain().focus().setAttachment(n).run()}indent(t){t.preventDefault();const e=this.fieldElementTarget.selectionStart;const n=this.fieldElementTarget.selectionEnd;const r=this.fieldElementTarget.value;const i=r.slice(0,e)+"\t"+r.slice(e,n)+r.slice(n);this.fieldElementTarget.value=i;this.fieldElementTarget.selectionStart=e+1;this.fieldElementTarget.selectionEnd=n+1}#e(t){Array.from(t).forEach((t=>this.#i(t)))}#i(t){const e=new DirectUpload(t,this.attachUrlValue);e.create(((t,e)=>{if(t)console.log("Error",t);else{const t=this.#n(e.filename,this.#s(e),e.content_type);this.#r(t)}}))}#r(t){const e=this.fieldElementTarget.selectionStart;const n=this.fieldElementTarget.selectionEnd;this.fieldElementTarget.setRangeText(t,e,n)}#s(t){return`/rails/active_storage/blobs/redirect/${t.signed_id}/${encodeURIComponent(t.filename)}`}#n(t,e,n){const r=this.#o(n)?"!":"";return`${r}[${t}](${e})\n`}#o(t){return["image/jpeg","image/gif","image/png"].includes(t)}}class list_continuation_controller extends Controller{connect(){this.isInsertLineBreak=false;this.isProcessing=false;this.SPACE_PATTERN=/^(\s*)?/;this.LIST_PATTERN=/^(\s*)([*-]|(\d+)\.)\s(\[[\sx]\]\s)?/}handleBeforeInput(t){this.isProcessing||(this.isInsertLineBreak=t.inputType==="insertLineBreak")}handleInput(t){if(!this.isProcessing&&(this.isInsertLineBreak||t.inputType==="insertLineBreak")){this.handleListContinuation(t.target);this.isInsertLineBreak=false}}handleListContinuation(t){if(this.isProcessing)return;const e=this.analyzeCurrentLine(t.value,[t.selectionStart,t.selectionEnd]);if(e!==void 0){this.isProcessing=true;try{this.applyTextChange(t,e)}finally{setTimeout((()=>{this.isProcessing=false}),0)}}}analyzeCurrentLine(t,[e]){if(!e||!t)return;const n=t.substring(0,e).split("\n");const r=n[n.length-2];const i=r?.match(this.LIST_PATTERN);if(!i)return;const[s,o,a,c,l]=i;const u=r.replace(s,"").trim();if(u.length===0){const n=e-`\n${s}`.length;return{text:t.substring(0,n)+t.substring(e),selection:[n,n],operation:"delete"}}const d=c?`${parseInt(c,10)+1}.`:a;const h=`${o}${d} ${l?"[ ] ":""}`;return{text:t.substring(0,e)+h+t.substring(e),selection:[e+h.length,e+h.length],operation:"insert"}}applyTextChange(t,{text:e,selection:n}){t.value=e;const[r,i]=n;t.selectionStart=r;t.selectionEnd=i}}export{list_continuation_controller as ListContinuationController,marksmith_controller as MarksmithController}; +