diff --git a/app/controllers/resources_controller.rb b/app/controllers/resources_controller.rb index 3586b3ce1..6bba8048b 100644 --- a/app/controllers/resources_controller.rb +++ b/app/controllers/resources_controller.rb @@ -35,6 +35,12 @@ def show render :show end + def rhino_text + @resource = Resource.find(resource_id_param).decorate + load_forms + render :show_test + end + def create @resource = current_user.resources.build(resource_params) if @resource.save @@ -118,12 +124,12 @@ def resource_id_param def resource_params params.require(:resource).permit( - :text, :kind, :male, :female, :title, :featured, :inactive, :url, + :text, :rhino_text, :kind, :male, :female, :title, :featured, :inactive, :url, :agency, :author, :filemaker_code, :windows_type_id, :ordering, main_image_attributes: [:id, :file, :_destroy], gallery_images_attributes: [:id, :file, :_destroy], categorizable_items_attributes: [:id, :category_id, :_destroy], category_ids: [], - sectorable_items_attributes: [:id, :sector_id, :is_leader, :_destroy], sector_ids: [], + sectorable_items_attributes: [:id, :sector_id, :is_leader, :_destroy], sector_ids: [] ) end diff --git a/app/frontend/javascript/application.js b/app/frontend/javascript/application.js index 562d92c85..dfd48449c 100644 --- a/app/frontend/javascript/application.js +++ b/app/frontend/javascript/application.js @@ -1,3 +1,7 @@ import "@hotwired/turbo-rails"; +import "@rails/actiontext"; +import "rhino-editor"; +import "rhino-editor/exports/styles/trix.css"; import "./controllers"; +import "./rhino/extend-editor.js"; diff --git a/app/frontend/javascript/controllers/index.js b/app/frontend/javascript/controllers/index.js index af3655451..93119ebff 100644 --- a/app/frontend/javascript/controllers/index.js +++ b/app/frontend/javascript/controllers/index.js @@ -29,3 +29,6 @@ application.register("tabs", TabsController) import TimeframeController from "./timeframe_controller" application.register("timeframe", TimeframeController) + +import RhinoSourceController from "./rhino_source_controller" +application.register("rhino-source", RhinoSourceController) diff --git a/app/frontend/javascript/controllers/rhino_source_controller.js b/app/frontend/javascript/controllers/rhino_source_controller.js new file mode 100644 index 000000000..88679e718 --- /dev/null +++ b/app/frontend/javascript/controllers/rhino_source_controller.js @@ -0,0 +1,35 @@ +import { Controller } from "@hotwired/stimulus" + +// Connects to data-controller="rhino-source" + +export default class extends Controller { + static targets = ["modal", "textarea"] + + connect() { + this.modalTarget.classList.add("hidden") + this._editor = null + } + + registerEditor(editor) { + this._editor = editor + } + + show(event) { + event?.preventDefault() + if (!this._editor) return + this.textareaTarget.value = this._editor.getHTML() + this.modalTarget.classList.remove("hidden") + } + + hide(event) { + event?.preventDefault() + this.modalTarget.classList.add("hidden") + } + + save(event) { + event.preventDefault() + if (!this._editor) return + this._editor.chain().focus().setContent(this.textareaTarget.value).run() + this.hide() + } +} diff --git a/app/frontend/javascript/rhino/custom-editor.js b/app/frontend/javascript/rhino/custom-editor.js new file mode 100644 index 000000000..b5e03d6cd --- /dev/null +++ b/app/frontend/javascript/rhino/custom-editor.js @@ -0,0 +1,439 @@ +// This custom editor +// extends the default tiptap editor to have a toolbar +// with table editing buttons in it. + +import { html } from "lit" +import "rhino-editor/exports/styles/trix.css" +import { TipTapEditor } from "rhino-editor/exports/elements/tip-tap-editor.js" +import * as table_icons from "./table-icons.js" +import * as table_translations from "./table-translations.js" +import { application } from "../controllers/application" + +class CustomEditor extends TipTapEditor { + + renderToolbar() { + + if (this.readonly) return html``; + + return html` + + + ${this.renderToolbarStart()} + + + + ${this.renderBoldButton()} + + + + + ${this.renderItalicButton()} + + + + + ${this.renderStrikeButton()} + + + + + ${this.renderLinkButton()} + + + + ${this.renderAlignmentButtons()} + + + + ${this.renderHeadingButton()} + + + + + ${this.renderBlockquoteButton()} + + + + + ${this.renderCodeBlockButton()} + + + + + ${this.renderBulletListButton()} + + + + + + ${this.renderOrderedListButton()} + + + + + ${this.renderDecreaseIndentation()} + + + + ${this.renderIncreaseIndentation()} + + + + + ${this.renderTableButton()} + + + + ${this.renderAttachmentButton()} + + + + + + + + + + + ${this.renderUndoButton()} + + + + + ${this.renderRedoButton()} + + + ${this.renderToolbarEnd()} + + + ${this.renderTableMenu()} + + `; + } + + renderTableButton() { + const tableEnabled = true; // Boolean(this.editor?.commands.setAttachment); + + if (!tableEnabled) return html``; + + const isDisabled = this.editor == null; + return html` + + `; + } + renderTableMenu() { + if (!this.editor || !this.editor.isActive('table')) { + return html``; + } + return html` + + + + + + + + + + + + + `; + } + + renderAlignmentButtons() { + if (!this.editor) return html``; + + const alignmentOptions = [ + { name: 'left', icon: '⬅️' }, + { name: 'center', icon: '↔️' }, + { name: 'right', icon: '➡️' }, + { name: 'justify', icon: '⏹', style: 'margin-inline-end:1rem;' }, + ]; + + const canAlign = ['paragraph', 'heading'].some(type => this.editor.isActive(type)); + if (!canAlign) return html``; + + return html` + ${alignmentOptions.map( + align => html` + + ` + )} + `; + } +} + +CustomEditor.define("custom-rhino-editor") diff --git a/app/frontend/javascript/rhino/extend-editor.js b/app/frontend/javascript/rhino/extend-editor.js new file mode 100644 index 000000000..3fd6a6b53 --- /dev/null +++ b/app/frontend/javascript/rhino/extend-editor.js @@ -0,0 +1,26 @@ +import "./custom-editor.js" +import { Table } from '@tiptap/extension-table' +import { TableCell } from '@tiptap/extension-table-cell' +import { TableHeader } from '@tiptap/extension-table-header' +import { TableRow } from '@tiptap/extension-table-row' +import Youtube from '@tiptap/extension-youtube' +import TextAlign from '@tiptap/extension-text-align' + +function extendRhinoEditor(event) { + const rhinoEditor = event.target + if (!rhinoEditor) return + + rhinoEditor.addExtensions( + Table, + TableRow, + TableHeader, + TableCell, + Youtube.configure({ nocookie: true }), + TextAlign.configure({ + types: ['heading', 'paragraph'], + }) + ) +} + +document.addEventListener("rhino-before-initialize", extendRhinoEditor) + diff --git a/app/frontend/javascript/rhino/table-icons.js b/app/frontend/javascript/rhino/table-icons.js new file mode 100644 index 000000000..8355ffa79 --- /dev/null +++ b/app/frontend/javascript/rhino/table-icons.js @@ -0,0 +1,88 @@ +import { html, svg } from "lit"; + +function toSvg(path, size = 24) { + return html` + + ` +} + +export const insertTable = toSvg( + svg`` +); + +export const deleteTable = toSvg( + svg`` +); + +export const addColumnBefore = toSvg( + svg`` +); + +export const addColumnAfter = toSvg( + svg`` +); + +export const deleteColumn = toSvg( + svg`` +); + +export const addRowBefore = toSvg( + svg`` +); + +export const addRowAfter = toSvg( + svg`` +); + +export const deleteRow = toSvg( + svg`` +); + +export const mergeCells = toSvg( + svg`` +); + +export const splitCells = toSvg( + svg`` +); + +export const toggleHeaderColumn = toSvg( + svg`` +); + +export const toggleHeaderRow = toSvg( + svg`` +); + +export const toggleHeaderCell = toSvg( + svg`` +); + +export const mergeOrSplit = toSvg( + svg`` +); + +export const setCellAttribute = toSvg( + svg`` +); + +export const fixTables = toSvg( + svg`` +); + +export const goToNextCell = toSvg( + svg`` +); +export const goToPreviousCell = toSvg( + svg`` +); diff --git a/app/frontend/javascript/rhino/table-translations.js b/app/frontend/javascript/rhino/table-translations.js new file mode 100644 index 000000000..5b52c45c4 --- /dev/null +++ b/app/frontend/javascript/rhino/table-translations.js @@ -0,0 +1,18 @@ +export const insertTable = "Insert a Table"; +export const deleteTable = "Delete a Table"; +export const addColumnBefore = "Add A Column Before"; +export const addColumnAfter = "Add a Column After"; +export const deleteColumn = "Delete a Column"; +export const addRowBefore = "Add a Row Before"; +export const addRowAfter = "Add a Row After"; +export const deleteRow = "Delete a Row"; +export const mergeCells = "Merge Cells"; +export const splitCells = "Split Cells"; +export const toggleHeaderColumn = "Toggle Header Column"; +export const toggleHeaderRow = "Toggle Header Row"; +export const toggleHeaderCell = "Toggle Header Cell"; +export const mergeOrSplit = "Merge or Split Cells"; +export const setCellAttribute = "Set Cell Attribute"; +export const fixTables = "Fix Tables"; +export const goToNextCell = "Go To Next Cell"; +export const goToPreviousCell = "Go To Previous Cell"; diff --git a/app/frontend/stylesheets/application.tailwind.css b/app/frontend/stylesheets/application.tailwind.css index dfdeb639b..0e5f6fd00 100644 --- a/app/frontend/stylesheets/application.tailwind.css +++ b/app/frontend/stylesheets/application.tailwind.css @@ -82,3 +82,59 @@ .is-active { @apply text-primary border-b-2 border-primary font-bold bg-gray-100; } + + +custom-rhino-editor table { + border-collapse: collapse; + margin: 0; + overflow: hidden; + table-layout: fixed; + width: 100%; +} +custom-rhino-editor table td, custom-rhino-editor table th { + border: 2px solid #ced4da; + box-sizing: border-box; + min-width: 1em; + padding: 3px 5px; + position: relative; + vertical-align: top; +} +custom-rhino-editor table td > *, custom-rhino-editor table th > * { + margin-bottom: 0; +} +custom-rhino-editor table th { + background-color: #f1f3f5; + font-weight: bold; + text-align: left; +} +custom-rhino-editor table .selectedCell:after { + background: rgba(200, 200, 255, 0.4); + content: ""; + left: 0; + right: 0; + top: 0; + bottom: 0; + pointer-events: none; + position: absolute; + z-index: 2; +} +custom-rhino-editor table .column-resize-handle { + background-color: #adf; + bottom: -2px; + position: absolute; + right: -2px; + pointer-events: none; + top: 0; + width: 4px; +} +custom-rhino-editor table p { + margin: 0; +} +custom-rhino-editor a { + @apply underline text-blue-600 hover:text-blue-800; +} +.tableWrapper { + padding: 1rem 0; + overflow-x: auto; + +} diff --git a/app/helpers/rhino_editor_helper.rb b/app/helpers/rhino_editor_helper.rb new file mode 100644 index 000000000..10428ff62 --- /dev/null +++ b/app/helpers/rhino_editor_helper.rb @@ -0,0 +1,43 @@ +module RhinoEditorHelper + # custom rhino editor with stimulus controller attached to edit raw source html + def rhino_editor(form, base_attribute_name) + rhino_attr = :"rhino_#{base_attribute_name}" + field_id = form.field_id(rhino_attr) + value = form.object.public_send(rhino_attr) + + hidden = form.hidden_field( + rhino_attr, + id: field_id, + value: value.respond_to?(:to_trix_html) ? value.to_trix_html : value + ) + + modal = content_tag(:div, data: {rhino_source_target: "modal"}, class: "hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50") do + content_tag(:div, class: "bg-white p-4 rounded shadow-lg w-3/4 max-w-2xl") do + safe_join([ + content_tag(:h2, "Edit HTML", class: "text-lg font-bold mb-2"), + content_tag(:textarea, nil, data: {rhino_source_target: "textarea"}, class: "w-full h-64 p-2 border rounded prose"), + content_tag(:div, class: "mt-2 text-right") do + safe_join([ + content_tag(:button, "Cancel", data: {action: "click->rhino-source#hide"}, class: "mr-2 px-4 py-2 bg-gray-200 rounded"), + content_tag(:button, "Save", data: {action: "click->rhino-source#save"}, class: "px-4 py-2 bg-blue-600 text-white rounded") + ]) + end + ]) + end + end + + editor = content_tag( + :"custom-rhino-editor", + nil, + input: field_id, + data: { + blob_url_template: rails_service_blob_url(":signed_id", ":filename"), + direct_upload_url: rails_direct_uploads_url + } + ) + + content_tag(:div, data: {controller: "rhino-source"}) do + safe_join([modal, hidden, editor]) + end + end +end diff --git a/app/models/resource.rb b/app/models/resource.rb index 5802d20e6..886d77bbf 100644 --- a/app/models/resource.rb +++ b/app/models/resource.rb @@ -4,6 +4,8 @@ class Resource < ApplicationRecord PUBLISHED_KINDS = ["Handout", "Scholarship", "Template", "Toolkit", "Form"] KINDS = PUBLISHED_KINDS + ["Resource", "Story"] + has_rich_text :rhino_text + belongs_to :user belongs_to :workshop, optional: true belongs_to :windows_type, optional: true diff --git a/app/services/rich_text_migrator.rb b/app/services/rich_text_migrator.rb new file mode 100644 index 000000000..ec8ad4a73 --- /dev/null +++ b/app/services/rich_text_migrator.rb @@ -0,0 +1,90 @@ +class RichTextMigrator + include ActionText::ContentHelper + + PLACEHOLDER_TEXT = "image not found" + + def initialize(record, old_column) + @record = record + @old_column = old_column.to_s + @new_column = "rhino_#{@old_column}" + @blobs_by_key = index_resource_blobs + end + + def migrate! + html = @record.public_send(@old_column) + return if html.blank? + + sanitized_html = sanitize_html(html) + + @record.assign_attributes(@new_column => ActionText::Content.new(sanitized_html)) + + @record.save(validate: false) + end + + private + + def sanitize_html(html) + sanitized = ActionController::Base.helpers.sanitize( + html, + tags: allowed_tags, + attributes: allowed_attributes + ) + + convert_images_to_attachments(sanitized) + end + + def allowed_tags + ActionText::ContentHelper.allowed_tags + end + + def allowed_attributes + ActionText::ContentHelper.allowed_attributes + end + + def convert_images_to_attachments(html) + fragment = Nokogiri::HTML::DocumentFragment.parse(html) + + fragment.css("img").each do |img| + aws_key = extract_aws_key(img["src"]) + blob = @blobs_by_key[aws_key] + + if blob + attachment = ActionText::Attachment.from_attachable(blob) + img.replace(attachment.to_html) + else + img.replace(placeholder_node(img["src"])) + end + end + + fragment.to_html + end + + def index_resource_blobs + @record.images + .includes(file_attachment: :blob) + .map(&:file) # get ActiveStorage::Attached::One + .map(&:blob) + .compact # remove nil blobs + .index_by(&:aws_key) + end + + def extract_aws_key(src) + return if src.blank? + + uri = URI.parse(src) + uri.path + .sub(%r{^/}, "") # remove leading slash + .split("?") + .first + rescue URI::InvalidURIError + nil + end + + def placeholder_node(src = nil) + text = %([#{PLACEHOLDER_TEXT}#{": #{src}" if src.present?}]) + + Nokogiri::HTML::DocumentFragment.parse( + "#{ERB::Util.html_escape(text)}" + ) + end +end diff --git a/app/views/active_storage/blobs/_blob.html.erb b/app/views/active_storage/blobs/_blob.html.erb new file mode 100644 index 000000000..49ba357dd --- /dev/null +++ b/app/views/active_storage/blobs/_blob.html.erb @@ -0,0 +1,14 @@ +
attachment--<%= blob.filename.extension %>"> + <% if blob.representable? %> + <%= image_tag blob.representation(resize_to_limit: local_assigns[:in_gallery] ? [ 800, 600 ] : [ 1024, 768 ]) %> + <% end %> + +
+ <% if caption = blob.try(:caption) %> + <%= caption %> + <% else %> + <%= blob.filename %> + <%= number_to_human_size blob.byte_size %> + <% end %> +
+
diff --git a/app/views/layouts/action_text/contents/_content.html.erb b/app/views/layouts/action_text/contents/_content.html.erb new file mode 100644 index 000000000..9fa0cc4c4 --- /dev/null +++ b/app/views/layouts/action_text/contents/_content.html.erb @@ -0,0 +1 @@ +
<%= yield -%>
diff --git a/app/views/resources/_form.html.erb b/app/views/resources/_form.html.erb index 97d8d6e7a..4b7ec53e9 100644 --- a/app/views/resources/_form.html.erb +++ b/app/views/resources/_form.html.erb @@ -13,9 +13,7 @@
-
- <%= f.input :featured, as: :boolean, wrapper: false, label_html: { class: "inline" } %> -
+
<%= f.input :featured, as: :boolean, wrapper: false, label_html: { class: "inline" } %>
<%= f.input :inactive, as: :boolean, label: "Hidden?", @@ -24,6 +22,7 @@
+
<%= f.input :kind, @@ -32,6 +31,7 @@ selected: f.object.kind, input_html: { class: "w-full rounded border-gray-300" } %>
+
<%= f.input :windows_type_id, as: :select, @@ -41,6 +41,7 @@ input_html: { value: f.object.windows_type_id, class: "w-full rounded border-gray-300" } %>
+
<%= f.input :user_id, as: :select, @@ -62,6 +63,8 @@
+ <%= rhino_editor(f, :text) %> +
@@ -96,10 +99,12 @@
  • <%= attachment.file_file_name %> <%# if attachment&.persisted? %> - <%#= link_to attachment.file_file_name, - url_for(attachment.file), class: "hover:underline" %> + <%# + = link_to attachment.file_file_name, + url_for(attachment.file), class: "hover:underline" + %> <%# else %> - <%#= attachment.file_file_name %> + <%# = attachment.file_file_name %> <%# end %>
  • <% end %> @@ -107,8 +112,6 @@
    <% end %> - -
    <%= link_to "Delete", @resource, class: "btn btn-danger-outline", method: :delete, data: { confirm: "Are you sure?" } %> diff --git a/app/views/resources/show_test.html.erb b/app/views/resources/show_test.html.erb new file mode 100644 index 000000000..5493fe36c --- /dev/null +++ b/app/views/resources/show_test.html.erb @@ -0,0 +1,101 @@ +
    +
    +
    + +
    + + <%= render "bookmarks/editable_bookmark_button", resource: @resource.object %> + + + <% if current_user.super_user? %> + <%= link_to("Edit", edit_resource_path(@resource), + class: "admin-only bg-blue-100 btn btn-primary-outline") %> + <% end %> + + <%= link_to ("" + + " Download ").html_safe, + resource_download_path(@resource), + class: "btn btn-utility" if @resource.download_attachment&.file&.attached? %> +
    + + +
    + +
    <%= title_with_badges(@resource, font_size: "text-3xl") %>
    + + +
    + <% unless @resource.toolkit_and_form? %> +
    + <%= @resource.author %> + <% unless @resource.story? %> + "> + <%= @resource.display_date %> + + <% end %> +
    + <% end %> +
    + +
    + + <% if @resource.main_image&.file&.attached? %> +
    + <%= image_tag @resource.main_image.file, + class: "w-full rounded-lg shadow-sm border border-gray-200", + alt: @resource.title %> +
    + <% end %> + + + <% if @resource.gallery_images.any? { |img| img.persisted? && img.file.attached? } %> + + <% end %> +
    + + + <% if @resource.url.present? %> +
    + <%= link_to @resource.url, @resource.url, target: "_blank", + rel: "noopener noreferrer", + class: "text-blue-600 hover:underline break-words" %> +
    + <% end %> + + + <%= @resource.rhino_text %> + + + <% if @resource.attachments.any? %> +
    +

    Attachment:

    +
      + <% @resource.attachments.each do |attachment| %> + <% if attachment.file&.attached? %> +
    • + <%= link_to ("" + + " #{ attachment.file_file_name } ").html_safe, + resource_download_path(@resource, + attachment_id: attachment.id), + class: "btn btn-utility" if attachment&.file&.attached? %> +
    • + <% end %> + <% end %> +
    +
    + <% end %> +
    +
    +
    +
    diff --git a/config/initializers/action_text.rb b/config/initializers/action_text.rb new file mode 100644 index 000000000..5ded161b0 --- /dev/null +++ b/config/initializers/action_text.rb @@ -0,0 +1,5 @@ +default_allowed_tags = Class.new.include(ActionText::ContentHelper).new.sanitizer_allowed_tags +ActionText::ContentHelper.allowed_tags = default_allowed_tags.merge(%w[iframe table colgroup col thead tbody tfoot tr th td]) + +default_allowed_attributes = Class.new.include(ActionText::ContentHelper).new.sanitizer_allowed_attributes +ActionText::ContentHelper.allowed_attributes = default_allowed_attributes.merge(%w[style colspan rowspan cellpadding cellspacing width height align valign]) diff --git a/config/routes.rb b/config/routes.rb index 86e3917e6..7a3b3ead6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -67,6 +67,9 @@ resources :reports resources :resources do get :download + member do + get :rhino_text + end collection do post :search end diff --git a/db/migrate/20251217163623_create_action_text_tables.action_text.rb b/db/migrate/20251217163623_create_action_text_tables.action_text.rb new file mode 100644 index 000000000..c1c0a9d8c --- /dev/null +++ b/db/migrate/20251217163623_create_action_text_tables.action_text.rb @@ -0,0 +1,26 @@ +# This migration comes from action_text (originally 20180528164100) +class CreateActionTextTables < ActiveRecord::Migration[6.0] + def change + # Use Active Record's configured type for primary and foreign keys + primary_key_type, foreign_key_type = primary_and_foreign_key_types + + create_table :action_text_rich_texts, id: primary_key_type do |t| + t.string :name, null: false + t.text :body, size: :long + t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type + + t.timestamps + + t.index [ :record_type, :record_id, :name ], name: "index_action_text_rich_texts_uniqueness", unique: true + end + end + + private + def primary_and_foreign_key_types + config = Rails.configuration.generators + setting = config.options[config.orm][:primary_key_type] + primary_key_type = setting || :primary_key + foreign_key_type = setting || :bigint + [ primary_key_type, foreign_key_type ] + end +end diff --git a/db/schema.rb b/db/schema.rb index 99d3cf784..66369a750 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,17 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.1].define(version: 2025_12_04_024120) do +ActiveRecord::Schema[8.1].define(version: 2025_12_17_163623) do + create_table "action_text_rich_texts", charset: "utf8mb3", force: :cascade do |t| + t.text "body", size: :long + t.datetime "created_at", null: false + t.string "name", null: false + t.bigint "record_id", null: false + t.string "record_type", null: false + t.datetime "updated_at", null: false + t.index ["record_type", "record_id", "name"], name: "index_action_text_rich_texts_uniqueness", unique: true + end + create_table "active_storage_attachments", charset: "utf8mb4", collation: "utf8mb4_unicode_ci", force: :cascade do |t| t.bigint "blob_id", null: false t.datetime "created_at", precision: nil, null: false diff --git a/package-lock.json b/package-lock.json index 82ce43410..7b1282793 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,11 +8,21 @@ "@fortawesome/fontawesome-free": "^7.0.1", "@hotwired/stimulus": "^3.2.2", "@hotwired/turbo-rails": "^8.0.18", + "@rails/actiontext": "^8.1.100", "@rails/request.js": "^0.0.12", "@tailwindcss/vite": "^4.1.13", + "@tiptap/extension-table": "^3.13.0", + "@tiptap/extension-table-cell": "^3.13.0", + "@tiptap/extension-table-header": "^3.13.0", + "@tiptap/extension-table-row": "^3.13.0", + "@tiptap/extension-text-align": "^3.13.0", + "@tiptap/extension-youtube": "^3.13.0", + "from": "^0.1.7", + "rhino-editor": "^0.18.0", "sortablejs": "^1.15.6", "swiper": "^12.0.3", "tailwindcss": "^4.1.13", + "trix": "^2.1.15", "vite-plugin-rails": "^0.5.0" }, "devDependencies": { @@ -366,6 +376,31 @@ "node": ">=12" } }, + "node_modules/@floating-ui/core": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz", + "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz", + "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.3", + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", + "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", + "license": "MIT" + }, "node_modules/@fortawesome/fontawesome-free": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-7.0.1.tgz", @@ -457,6 +492,21 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@lit-labs/ssr-dom-shim": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.4.0.tgz", + "integrity": "sha512-ficsEARKnmmW5njugNYKipTm4SFnbik7CXtoencDZzmzo/dQ+2Q0bgkzJuoJP20Aj0F+izzJjOqsnkd6F/o1bw==", + "license": "BSD-3-Clause" + }, + "node_modules/@lit/reactive-element": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.1.1.tgz", + "integrity": "sha512-N+dm5PAYdQ8e6UlywyyrgI2t++wFGXfHx+dSJ1oBrg6FAxUj40jId++EaRm80MKX5JnlH1sBsyZ5h0bcZKemCg==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.4.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -489,18 +539,51 @@ "node": ">= 8" } }, + "node_modules/@open-wc/dedupe-mixin": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@open-wc/dedupe-mixin/-/dedupe-mixin-1.4.0.tgz", + "integrity": "sha512-Sj7gKl1TLcDbF7B6KUhtvr+1UCxdhMbNY5KxdU5IfMFWqL8oy1ZeAcCANjoB1TL0AJTcPmcCFsCbHf8X2jGDUA==", + "license": "MIT" + }, "node_modules/@rails/actioncable": { "version": "8.0.300", "resolved": "https://registry.npmjs.org/@rails/actioncable/-/actioncable-8.0.300.tgz", "integrity": "sha512-X+jxLnyYciTciEeM9crFFsR6DCodCsnoQIzv4hEST6Lx1rEBEjNQbBopnyDT4gr7lBeHJNfb6fEcvZuWFxUSQg==", "license": "MIT" }, + "node_modules/@rails/actiontext": { + "version": "8.1.100", + "resolved": "https://registry.npmjs.org/@rails/actiontext/-/actiontext-8.1.100.tgz", + "integrity": "sha512-gnLK1HgGCmmVGY40hCiAJ4RwGALwRmiRzqyht6fiM/hrQnul278CqCg9jwV2IQOo7+jMbktGx2O9luGUzayQIA==", + "license": "MIT", + "dependencies": { + "@rails/activestorage": ">= 8.1.0-alpha" + }, + "peerDependencies": { + "trix": "^2.0.0" + } + }, + "node_modules/@rails/activestorage": { + "version": "8.1.100", + "resolved": "https://registry.npmjs.org/@rails/activestorage/-/activestorage-8.1.100.tgz", + "integrity": "sha512-rlZg23KYT7JFYXl1tj1WD9nm/yvtUvZT6pzNMVX+HaOjPyGq8xpEv1ADrrhawkbMktKxRj3xDVZ3d/qy0akHvw==", + "license": "MIT", + "dependencies": { + "spark-md5": "^3.0.1" + } + }, "node_modules/@rails/request.js": { "version": "0.0.12", "resolved": "https://registry.npmjs.org/@rails/request.js/-/request.js-0.0.12.tgz", "integrity": "sha512-g3//JBja1s04Zflj7IoMLQuXza9i4ZvtLmm0r0dMwh1QQUs6rL2iKUOGGyERfLsd81SnXC5ucfVV//rtsDlEEA==", "license": "MIT" }, + "node_modules/@remirror/core-constants": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-3.0.0.tgz", + "integrity": "sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==", + "license": "MIT" + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.50.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.50.1.tgz", @@ -1028,11 +1111,536 @@ "vite": "^5.2.0 || ^6 || ^7" } }, + "node_modules/@tiptap/core": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.13.0.tgz", + "integrity": "sha512-iUelgiTMgPVMpY5ZqASUpk8mC8HuR9FWKaDzK27w9oWip9tuB54Z8mePTxNcQaSPb6ErzEaC8x8egrRt7OsdGQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/pm": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-blockquote": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-3.13.0.tgz", + "integrity": "sha512-K1z/PAIIwEmiWbzrP//4cC7iG1TZknDlF1yb42G7qkx2S2X4P0NiqX7sKOej3yqrPjKjGwPujLMSuDnCF87QkQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-bold": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-3.13.0.tgz", + "integrity": "sha512-VYiDN9EEwR6ShaDLclG8mphkb/wlIzqfk7hxaKboq1G+NSDj8PcaSI9hldKKtTCLeaSNu6UR5nkdu/YHdzYWTw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-bullet-list": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-3.13.0.tgz", + "integrity": "sha512-fFQmmEUoPzRGiQJ/KKutG35ZX21GE+1UCDo8Q6PoWH7Al9lex47nvyeU1BiDYOhcTKgIaJRtEH5lInsOsRJcSA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extension-list": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-code": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-3.13.0.tgz", + "integrity": "sha512-sF5raBni6iSVpXWvwJCAcOXw5/kZ+djDHx1YSGWhopm4+fsj0xW7GvVO+VTwiFjZGKSw+K5NeAxzcQTJZd3Vhw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-code-block": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-3.13.0.tgz", + "integrity": "sha512-kIwfQ4iqootsWg9e74iYJK54/YMIj6ahUxEltjZRML5z/h4gTDcQt2eTpnEC8yjDjHeUVOR94zH9auCySyk9CQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.13.0", + "@tiptap/pm": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-document": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-3.13.0.tgz", + "integrity": "sha512-RjU7hTJwjKXIdY57o/Pc+Yr8swLkrwT7PBQ/m+LCX5oO/V2wYoWCjoBYnK5KSHrWlNy/aLzC33BvLeqZZ9nzlQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-dropcursor": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-3.13.0.tgz", + "integrity": "sha512-m7GPT3c/83ni+bbU8c+3dpNa8ug+aQ4phNB1Q52VQG3oTonDJnZS7WCtn3lB/Hi1LqoqMtEHwhepU2eD+JeXqQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extensions": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-focus": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-focus/-/extension-focus-3.13.0.tgz", + "integrity": "sha512-UXeJcreVqXRLz1f4MX/KmeKCicwOWilCAc1I81s0GVV6kgdqgUodnqRSvQZBpbSZ+vicG+gmYWXOa0S3CurEGg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extensions": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-gapcursor": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-3.13.0.tgz", + "integrity": "sha512-KVxjQKkd964nin+1IdM2Dvej/Jy4JTMcMgq5seusUhJ9T9P8F9s2D5Iefwgkps3OCzub/aF+eAsZe+1P5KSIgA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extensions": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-hard-break": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-3.13.0.tgz", + "integrity": "sha512-nH1OBaO+/pakhu+P1jF208mPgB70IKlrR/9d46RMYoYbqJTNf4KVLx5lHAOHytIhjcNg+MjyTfJWfkK+dyCCyg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-heading": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-3.13.0.tgz", + "integrity": "sha512-8VKWX8waYPtUWN97J89em9fOtxNteh6pvUEd0htcOAtoxjt2uZjbW5N4lKyWhNKifZBrVhH2Cc2NUPuftCVgxw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-horizontal-rule": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-3.13.0.tgz", + "integrity": "sha512-ZUFyORtjj22ib8ykbxRhWFQOTZjNKqOsMQjaAGof30cuD2DN5J5pMz7Haj2fFRtLpugWYH+f0Mi+WumQXC3hCw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.13.0", + "@tiptap/pm": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-image": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-image/-/extension-image-3.13.0.tgz", + "integrity": "sha512-223uzLUkIa1rkK7aQK3AcIXe6LbCtmnpVb7sY5OEp+LpSaSPyXwyrZ4A0EO1o98qXG68/0B2OqMntFtA9c5Fbw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-italic": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-3.13.0.tgz", + "integrity": "sha512-XbVTgmzk1kgUMTirA6AGdLTcKHUvEJoh3R4qMdPtwwygEOe7sBuvKuLtF6AwUtpnOM+Y3tfWUTNEDWv9AcEdww==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-link": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-3.13.0.tgz", + "integrity": "sha512-LuFPJ5GoL12GHW4A+USsj60O90pLcwUPdvEUSWewl9USyG6gnLnY/j5ZOXPYH7LiwYW8+lhq7ABwrDF2PKyBbA==", + "license": "MIT", + "dependencies": { + "linkifyjs": "^4.3.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.13.0", + "@tiptap/pm": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-list": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list/-/extension-list-3.13.0.tgz", + "integrity": "sha512-MMFH0jQ4LeCPkJJFyZ77kt6eM/vcKujvTbMzW1xSHCIEA6s4lEcx9QdZMPpfmnOvTzeoVKR4nsu2t2qT9ZXzAw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.13.0", + "@tiptap/pm": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-list-item": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-3.13.0.tgz", + "integrity": "sha512-63NbcS/XeQP2jcdDEnEAE3rjJICDj8y1SN1h/MsJmSt1LusnEo8WQ2ub86QELO6XnD3M04V03cY6Knf6I5mTkw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extension-list": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-list-keymap": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-keymap/-/extension-list-keymap-3.13.0.tgz", + "integrity": "sha512-P+HtIa1iwosb1feFc8B/9MN5EAwzS+/dZ0UH0CTF2E4wnp5Z9OMxKl1IYjfiCwHzZrU5Let+S/maOvJR/EmV0g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extension-list": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-ordered-list": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-3.13.0.tgz", + "integrity": "sha512-QuDyLzuK/3vCvx9GeKhgvHWrGECBzmJyAx6gli2HY+Iil7XicbfltV4nvhIxgxzpx3LDHLKzJN9pBi+2MzX60g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extension-list": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-paragraph": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-3.13.0.tgz", + "integrity": "sha512-9csQde1i0yeZI5oQQ9e1GYNtGL2JcC2d8Fwtw9FsGC8yz2W0h+Fmk+3bc2kobbtO5LGqupSc1fKM8fAg5rSRDg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-placeholder": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-3.13.0.tgz", + "integrity": "sha512-Au4ktRBraQktX9gjSzGWyJV6kPof7+kOhzE8ej+rOMjIrHbx3DCHy1CJWftSO9BbqIyonjsFmm4nE+vjzZ3Z5Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extensions": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-strike": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-3.13.0.tgz", + "integrity": "sha512-VHhWNqTAMOfrC48m2FcPIZB0nhl6XHQviAV16SBc+EFznKNv9tQUsqQrnuQ2y6ZVfqq5UxvZ3hKF/JlN/Ff7xw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-table": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table/-/extension-table-3.13.0.tgz", + "integrity": "sha512-LcH9KE4QBUJ6IPwt1Uo5iU7zatFjUUvXbctIu2fKQ9nqJ7nNSFxRhkNyporVFkTWYH7/rb0qMoF1VxSUGefG5w==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.13.0", + "@tiptap/pm": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-table-cell": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table-cell/-/extension-table-cell-3.13.0.tgz", + "integrity": "sha512-dBOPeLe2NqymZI8reS2yZRIcgfIYHudCq4lDWZBJ5NiMvoy0b/fVe1qYSP4EcfBQMpfgAP0E05bMB3C7p1kmkw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extension-table": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-table-header": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table-header/-/extension-table-header-3.13.0.tgz", + "integrity": "sha512-ZA5lhcek0VlKupqj3WFgE6bj5vNRmxcpDqjYc6RWaxuva4dYfEQSqdlG+3a53Sr53le0grfBpolM8zJFCVYrcw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extension-table": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-table-row": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table-row/-/extension-table-row-3.13.0.tgz", + "integrity": "sha512-FdsMTIBNleZtWJEhXE/PBxkB8L9YJtnKs7YZNesLKqLn6/sWZl+X5e5SAAN/N3DLOEAwNCa/m0C3A1DWGNz/tw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extension-table": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-text": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-3.13.0.tgz", + "integrity": "sha512-VcZIna93rixw7hRkHGCxDbL3kvJWi80vIT25a2pXg0WP1e7Pi3nBYvZIL4SQtkbBCji9EHrbZx3p8nNPzfazYw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-text-align": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text-align/-/extension-text-align-3.13.0.tgz", + "integrity": "sha512-hebIus9tdXWb+AmhO+LTeUxZLdb0tqwdeaL/0wYxJQR5DeCTlJe6huXacMD/BkmnlEpRhxzQH0FrmXAd0d4Wgg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-underline": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-3.13.0.tgz", + "integrity": "sha512-VDQi+UYw0tFnfghpthJTFmtJ3yx90kXeDwFvhmT8G+O+si5VmP05xYDBYBmYCix5jqKigJxEASiBL0gYOgMDEg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.13.0" + } + }, + "node_modules/@tiptap/extension-youtube": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-youtube/-/extension-youtube-3.13.0.tgz", + "integrity": "sha512-KG6NtdpK9VheacN4imjhDJ8G1V2tJZd/LRr+QID8dYEMQe9vKbqIXgA0kO91t+f+iH8NwgNPmi3a/BQogvoqJg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.13.0" + } + }, + "node_modules/@tiptap/extensions": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/extensions/-/extensions-3.13.0.tgz", + "integrity": "sha512-i7O0ptSibEtTy+2PIPsNKEvhTvMaFJg1W4Oxfnbuxvaigs7cJV9Q0lwDUcc7CPsNw2T1+44wcxg431CzTvdYoA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.13.0", + "@tiptap/pm": "^3.13.0" + } + }, + "node_modules/@tiptap/pm": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.13.0.tgz", + "integrity": "sha512-WKR4ucALq+lwx0WJZW17CspeTpXorbIOpvKv5mulZica6QxqfMhn8n1IXCkDws/mCoLRx4Drk5d377tIjFNsvQ==", + "license": "MIT", + "dependencies": { + "prosemirror-changeset": "^2.3.0", + "prosemirror-collab": "^1.3.1", + "prosemirror-commands": "^1.6.2", + "prosemirror-dropcursor": "^1.8.1", + "prosemirror-gapcursor": "^1.3.2", + "prosemirror-history": "^1.4.1", + "prosemirror-inputrules": "^1.4.0", + "prosemirror-keymap": "^1.2.2", + "prosemirror-markdown": "^1.13.1", + "prosemirror-menu": "^1.2.4", + "prosemirror-model": "^1.24.1", + "prosemirror-schema-basic": "^1.2.3", + "prosemirror-schema-list": "^1.5.0", + "prosemirror-state": "^1.4.3", + "prosemirror-tables": "^1.6.4", + "prosemirror-trailing-node": "^3.0.0", + "prosemirror-transform": "^1.10.2", + "prosemirror-view": "^1.38.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + } + }, + "node_modules/@tiptap/starter-kit": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-3.13.0.tgz", + "integrity": "sha512-Ojn6sRub04CRuyQ+9wqN62JUOMv+rG1vXhc2s6DCBCpu28lkCMMW+vTe7kXJcEdbot82+5swPbERw9vohswFzg==", + "license": "MIT", + "dependencies": { + "@tiptap/core": "^3.13.0", + "@tiptap/extension-blockquote": "^3.13.0", + "@tiptap/extension-bold": "^3.13.0", + "@tiptap/extension-bullet-list": "^3.13.0", + "@tiptap/extension-code": "^3.13.0", + "@tiptap/extension-code-block": "^3.13.0", + "@tiptap/extension-document": "^3.13.0", + "@tiptap/extension-dropcursor": "^3.13.0", + "@tiptap/extension-gapcursor": "^3.13.0", + "@tiptap/extension-hard-break": "^3.13.0", + "@tiptap/extension-heading": "^3.13.0", + "@tiptap/extension-horizontal-rule": "^3.13.0", + "@tiptap/extension-italic": "^3.13.0", + "@tiptap/extension-link": "^3.13.0", + "@tiptap/extension-list": "^3.13.0", + "@tiptap/extension-list-item": "^3.13.0", + "@tiptap/extension-list-keymap": "^3.13.0", + "@tiptap/extension-ordered-list": "^3.13.0", + "@tiptap/extension-paragraph": "^3.13.0", + "@tiptap/extension-strike": "^3.13.0", + "@tiptap/extension-text": "^3.13.0", + "@tiptap/extension-underline": "^3.13.0", + "@tiptap/extensions": "^3.13.0", + "@tiptap/pm": "^3.13.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + } + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==" }, + "node_modules/@types/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", + "license": "MIT" + }, + "node_modules/@types/markdown-it": { + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", + "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", + "license": "MIT", + "dependencies": { + "@types/linkify-it": "^5", + "@types/mdurl": "^2" + } + }, + "node_modules/@types/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", + "license": "MIT" + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, "node_modules/braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", @@ -1053,6 +1661,12 @@ "node": ">=18" } }, + "node_modules/crelt": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", + "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==", + "license": "MIT" + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -1091,6 +1705,15 @@ "node": ">=8" } }, + "node_modules/dompurify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.1.tgz", + "integrity": "sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, "node_modules/enhanced-resolve": { "version": "5.18.3", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", @@ -1104,6 +1727,18 @@ "node": ">=10.13.0" } }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/esbuild": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", @@ -1141,6 +1776,18 @@ "@esbuild/win32-x64": "0.21.5" } }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/fast-glob": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", @@ -1175,6 +1822,18 @@ "node": ">=8" } }, + "node_modules/form-associated-helpers": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/form-associated-helpers/-/form-associated-helpers-0.0.10.tgz", + "integrity": "sha512-ClR8Y8muq6EPsmUZsPf+iWUWvRpRzSRGm/ESb5pbhf1PsRSph5cWjpvBlHrNeaBwTGPC1R0kFjAb5kR96ZQe+Q==", + "license": "MIT" + }, + "node_modules/from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", + "license": "MIT" + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -1469,6 +2128,52 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, + "node_modules/linkifyjs": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.3.2.tgz", + "integrity": "sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==", + "license": "MIT" + }, + "node_modules/lit": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/lit/-/lit-3.3.1.tgz", + "integrity": "sha512-Ksr/8L3PTapbdXJCk+EJVB78jDodUMaP54gD24W186zGRARvwrsPfS60wae/SSCTCNZVPd1chXqio1qHQmu4NA==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit/reactive-element": "^2.1.0", + "lit-element": "^4.2.0", + "lit-html": "^3.3.0" + } + }, + "node_modules/lit-element": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.2.1.tgz", + "integrity": "sha512-WGAWRGzirAgyphK2urmYOV72tlvnxw7YfyLDgQ+OZnM9vQQBQnumQ7jUJe6unEzwGU3ahFOjuz1iz1jjrpCPuw==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.4.0", + "@lit/reactive-element": "^2.1.0", + "lit-html": "^3.3.0" + } + }, + "node_modules/lit-html": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.3.1.tgz", + "integrity": "sha512-S9hbyDu/vs1qNrithiNyeyv64c9yqiW9l+DBgI18fL+MTvOtWoFR0FWiyq1TxaYef5wNlpEmzlXoBlZEO+WjoA==", + "license": "BSD-3-Clause", + "dependencies": { + "@types/trusted-types": "^2.0.2" + } + }, "node_modules/magic-string": { "version": "0.30.19", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz", @@ -1478,6 +2183,29 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "license": "MIT" + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -1541,6 +2269,12 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/orderedmap": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz", + "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==", + "license": "MIT" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -1598,6 +2332,232 @@ "node": ">=4" } }, + "node_modules/prosemirror-changeset": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.3.1.tgz", + "integrity": "sha512-j0kORIBm8ayJNl3zQvD1TTPHJX3g042et6y/KQhZhnPrruO8exkTgG8X+NRpj7kIyMMEx74Xb3DyMIBtO0IKkQ==", + "license": "MIT", + "dependencies": { + "prosemirror-transform": "^1.0.0" + } + }, + "node_modules/prosemirror-codemark": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/prosemirror-codemark/-/prosemirror-codemark-0.4.2.tgz", + "integrity": "sha512-4n+PnGQToa/vTjn0OiivUvE8/moLtguUAfry8UA4Q8p47MhqT2Qpf2zBLustX5Upi4mSp3z1ZYBqLLovZC6abA==", + "license": "MIT", + "peerDependencies": { + "prosemirror-inputrules": "^1.2.0", + "prosemirror-model": "^1.18.1", + "prosemirror-state": "^1.4.1", + "prosemirror-view": "^1.26.2" + } + }, + "node_modules/prosemirror-collab": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz", + "integrity": "sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.0.0" + } + }, + "node_modules/prosemirror-commands": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.7.1.tgz", + "integrity": "sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.10.2" + } + }, + "node_modules/prosemirror-dropcursor": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.2.tgz", + "integrity": "sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.1.0", + "prosemirror-view": "^1.1.0" + } + }, + "node_modules/prosemirror-gapcursor": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.4.0.tgz", + "integrity": "sha512-z00qvurSdCEWUIulij/isHaqu4uLS8r/Fi61IbjdIPJEonQgggbJsLnstW7Lgdk4zQ68/yr6B6bf7sJXowIgdQ==", + "license": "MIT", + "dependencies": { + "prosemirror-keymap": "^1.0.0", + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-view": "^1.0.0" + } + }, + "node_modules/prosemirror-history": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.5.0.tgz", + "integrity": "sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.2.2", + "prosemirror-transform": "^1.0.0", + "prosemirror-view": "^1.31.0", + "rope-sequence": "^1.3.0" + } + }, + "node_modules/prosemirror-inputrules": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.5.1.tgz", + "integrity": "sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.0.0" + } + }, + "node_modules/prosemirror-keymap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.3.tgz", + "integrity": "sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.0.0", + "w3c-keyname": "^2.2.0" + } + }, + "node_modules/prosemirror-markdown": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.2.tgz", + "integrity": "sha512-FPD9rHPdA9fqzNmIIDhhnYQ6WgNoSWX9StUZ8LEKapaXU9i6XgykaHKhp6XMyXlOWetmaFgGDS/nu/w9/vUc5g==", + "license": "MIT", + "dependencies": { + "@types/markdown-it": "^14.0.0", + "markdown-it": "^14.0.0", + "prosemirror-model": "^1.25.0" + } + }, + "node_modules/prosemirror-menu": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.2.5.tgz", + "integrity": "sha512-qwXzynnpBIeg1D7BAtjOusR+81xCp53j7iWu/IargiRZqRjGIlQuu1f3jFi+ehrHhWMLoyOQTSRx/IWZJqOYtQ==", + "license": "MIT", + "dependencies": { + "crelt": "^1.0.0", + "prosemirror-commands": "^1.0.0", + "prosemirror-history": "^1.0.0", + "prosemirror-state": "^1.0.0" + } + }, + "node_modules/prosemirror-model": { + "version": "1.25.4", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.4.tgz", + "integrity": "sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==", + "license": "MIT", + "dependencies": { + "orderedmap": "^2.0.0" + } + }, + "node_modules/prosemirror-schema-basic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.4.tgz", + "integrity": "sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.25.0" + } + }, + "node_modules/prosemirror-schema-list": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.5.1.tgz", + "integrity": "sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.7.3" + } + }, + "node_modules/prosemirror-state": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.4.tgz", + "integrity": "sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-transform": "^1.0.0", + "prosemirror-view": "^1.27.0" + } + }, + "node_modules/prosemirror-tables": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.8.3.tgz", + "integrity": "sha512-wbqCR/RlRPRe41a4LFtmhKElzBEfBTdtAYWNIGHM6X2e24NN/MTNUKyXjjphfAfdQce37Kh/5yf765mLPYDe7Q==", + "license": "MIT", + "dependencies": { + "prosemirror-keymap": "^1.2.3", + "prosemirror-model": "^1.25.4", + "prosemirror-state": "^1.4.4", + "prosemirror-transform": "^1.10.5", + "prosemirror-view": "^1.41.4" + } + }, + "node_modules/prosemirror-trailing-node": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-3.0.0.tgz", + "integrity": "sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==", + "license": "MIT", + "dependencies": { + "@remirror/core-constants": "3.0.0", + "escape-string-regexp": "^4.0.0" + }, + "peerDependencies": { + "prosemirror-model": "^1.22.1", + "prosemirror-state": "^1.4.2", + "prosemirror-view": "^1.33.8" + } + }, + "node_modules/prosemirror-transform": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.5.tgz", + "integrity": "sha512-RPDQCxIDhIBb1o36xxwsaeAvivO8VLJcgBtzmOwQ64bMtsVFh5SSuJ6dWSxO1UsHTiTXPCgQm3PDJt7p6IOLbw==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.21.0" + } + }, + "node_modules/prosemirror-utils": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/prosemirror-utils/-/prosemirror-utils-1.2.2.tgz", + "integrity": "sha512-7a2MPf99oCW8/587rQYI1/snX71Ban40+apr1hLkY8TmU9YXd7JeR6QsmktcTisJURO3WRjxIia4lTMsYgZVOw==", + "license": "Apache-2.0", + "peerDependencies": { + "prosemirror-model": "^1.19.2", + "prosemirror-state": "^1.4.3" + } + }, + "node_modules/prosemirror-view": { + "version": "1.41.4", + "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.41.4.tgz", + "integrity": "sha512-WkKgnyjNncri03Gjaz3IFWvCAE94XoiEgvtr0/r2Xw7R8/IjK3sKLSiDoCHWcsXSAinVaKlGRZDvMCsF1kbzjA==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.20.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.1.0" + } + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -1626,6 +2586,44 @@ "node": ">=0.10.0" } }, + "node_modules/rhino-editor": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/rhino-editor/-/rhino-editor-0.18.0.tgz", + "integrity": "sha512-5n9VHb7dfeSIDuc7aJUWc+7EmRNCMvha32yV/hvL89vjXliIDvENSy+C4808HsvRrHsbJpMBXs+36MTDL2fBTQ==", + "license": "MIT", + "dependencies": { + "@rails/activestorage": "^8.0.201", + "@tiptap/core": "^3.4.0", + "@tiptap/extension-code": "^3.4.0", + "@tiptap/extension-code-block": "^3.4.0", + "@tiptap/extension-focus": "^3.4.0", + "@tiptap/extension-image": "^3.4.0", + "@tiptap/extension-link": "^3.4.0", + "@tiptap/extension-placeholder": "^3.4.0", + "@tiptap/extension-strike": "^3.4.0", + "@tiptap/pm": "^3.4.0", + "@tiptap/starter-kit": "^3.4.0", + "linkifyjs": "^4.1.3", + "lit": "^3.3.1", + "prosemirror-codemark": "^0.4.2", + "prosemirror-utils": "^1.2.2", + "prosemirror-view": "^1.40.1", + "role-components": "^3.1.0", + "tslib": "^2.8.1" + } + }, + "node_modules/role-components": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/role-components/-/role-components-3.1.0.tgz", + "integrity": "sha512-d0vq9H4Hqe24fGzd79s+e/X/GzNz+OI5dsThsn1cNaix+VKfr/I+UbkErZ8G8lWEqWe+ULOTa25/t5oRng2xkQ==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.6.5", + "form-associated-helpers": "^0.0.10", + "lit": "^3", + "web-component-define": "^2.0.11" + } + }, "node_modules/rollup": { "version": "4.50.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.50.1.tgz", @@ -1676,6 +2674,12 @@ "rollup": ">=2.0.0" } }, + "node_modules/rope-sequence": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz", + "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==", + "license": "MIT" + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -1712,6 +2716,12 @@ "node": ">=0.10.0" } }, + "node_modules/spark-md5": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz", + "integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw==", + "license": "(WTFPL OR MIT)" + }, "node_modules/stimulus-vite-helpers": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/stimulus-vite-helpers/-/stimulus-vite-helpers-3.1.0.tgz", @@ -1782,6 +2792,27 @@ "node": ">=8.0" } }, + "node_modules/trix": { + "version": "2.1.15", + "resolved": "https://registry.npmjs.org/trix/-/trix-2.1.15.tgz", + "integrity": "sha512-LoaXWczdTUV8+3Box92B9b1iaDVbxD14dYemZRxi3PwY+AuDm97BUJV2aHLBUFPuDABhxp0wzcbf0CxHCVmXiw==", + "license": "MIT", + "dependencies": { + "dompurify": "^3.2.5" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "license": "MIT" + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -1908,6 +2939,31 @@ "stimulus-vite-helpers": "^3.0.0" } }, + "node_modules/w3c-keyname": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", + "license": "MIT" + }, + "node_modules/web-component-define": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/web-component-define/-/web-component-define-2.0.11.tgz", + "integrity": "sha512-oMOngNGL5k55NyaQNnPz0UnV5QtPuESvSuxpBgmHHfNjb8sgVm4akAFq7HO4I5bhGHX8Of+0XnUZ3whBo0chgw==", + "license": "MIT", + "dependencies": { + "@lit/reactive-element": "^1.6.1", + "@open-wc/dedupe-mixin": "^1.3.1" + } + }, + "node_modules/web-component-define/node_modules/@lit/reactive-element": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz", + "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.0.0" + } + }, "node_modules/yallist": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", diff --git a/package.json b/package.json index fdeedf59f..6217ab8a1 100644 --- a/package.json +++ b/package.json @@ -8,11 +8,21 @@ "@fortawesome/fontawesome-free": "^7.0.1", "@hotwired/stimulus": "^3.2.2", "@hotwired/turbo-rails": "^8.0.18", + "@rails/actiontext": "^8.1.100", "@rails/request.js": "^0.0.12", "@tailwindcss/vite": "^4.1.13", + "@tiptap/extension-table": "^3.13.0", + "@tiptap/extension-table-cell": "^3.13.0", + "@tiptap/extension-table-header": "^3.13.0", + "@tiptap/extension-table-row": "^3.13.0", + "@tiptap/extension-text-align": "^3.13.0", + "@tiptap/extension-youtube": "^3.13.0", + "from": "^0.1.7", + "rhino-editor": "^0.18.0", "sortablejs": "^1.15.6", "swiper": "^12.0.3", "tailwindcss": "^4.1.13", + "trix": "^2.1.15", "vite-plugin-rails": "^0.5.0" } }